nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* export_object.c |
2 | * Common routines for tracking & saving objects found in streams of data |
||
3 | * Copyright 2007, Stephen Fisher (see AUTHORS file) |
||
4 | * |
||
5 | * Wireshark - Network traffic analyzer |
||
6 | * By Gerald Combs <gerald@wireshark.org> |
||
7 | * Copyright 1998 Gerald Combs |
||
8 | * |
||
9 | * This program is free software; you can redistribute it and/or |
||
10 | * modify it under the terms of the GNU General Public License |
||
11 | * as published by the Free Software Foundation; either version 2 |
||
12 | * of the License, or (at your option) any later version. |
||
13 | * |
||
14 | * This program is distributed in the hope that it will be useful, |
||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
17 | * GNU General Public License for more details. |
||
18 | * |
||
19 | * You should have received a copy of the GNU General Public License |
||
20 | * along with this program; if not, write to the Free Software |
||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, |
||
22 | * USA. |
||
23 | */ |
||
24 | |||
25 | #include "config.h" |
||
26 | |||
27 | #include <string.h> |
||
28 | |||
29 | #include <errno.h> |
||
30 | |||
31 | #include <glib.h> |
||
32 | |||
33 | #include <epan/packet_info.h> |
||
34 | #include <epan/tap.h> |
||
35 | |||
36 | #include <wiretap/wtap.h> |
||
37 | |||
38 | #include <wsutil/file_util.h> |
||
39 | |||
40 | #include <ui/alert_box.h> |
||
41 | |||
42 | #include "export_object.h" |
||
43 | |||
44 | gboolean |
||
45 | eo_save_entry(const gchar *save_as_filename, export_object_entry_t *entry, gboolean show_err) |
||
46 | { |
||
47 | int to_fd; |
||
48 | gint64 bytes_left; |
||
49 | int bytes_to_write; |
||
50 | ssize_t bytes_written; |
||
51 | guint8 *ptr; |
||
52 | int err; |
||
53 | |||
54 | to_fd = ws_open(save_as_filename, O_WRONLY | O_CREAT | O_EXCL | |
||
55 | O_BINARY, 0644); |
||
56 | if(to_fd == -1) { /* An error occurred */ |
||
57 | if (show_err) |
||
58 | open_failure_alert_box(save_as_filename, errno, TRUE); |
||
59 | return FALSE; |
||
60 | } |
||
61 | |||
62 | /* |
||
63 | * The third argument to _write() on Windows is an unsigned int, |
||
64 | * so, on Windows, that's the size of the third argument to |
||
65 | * ws_write(). |
||
66 | * |
||
67 | * The third argument to write() on UN*X is a size_t, although |
||
68 | * the return value is an ssize_t, so one probably shouldn't |
||
69 | * write more than the max value of an ssize_t. |
||
70 | * |
||
71 | * In either case, there's no guarantee that a gint64 such as |
||
72 | * payload_len can be passed to ws_write(), so we write in |
||
73 | * chunks of, at most 2^31 bytes. |
||
74 | */ |
||
75 | ptr = entry->payload_data; |
||
76 | bytes_left = entry->payload_len; |
||
77 | while (bytes_left != 0) { |
||
78 | if (bytes_left > 0x40000000) |
||
79 | bytes_to_write = 0x40000000; |
||
80 | else |
||
81 | bytes_to_write = (int)bytes_left; |
||
82 | bytes_written = ws_write(to_fd, ptr, bytes_to_write); |
||
83 | if(bytes_written <= 0) { |
||
84 | if (bytes_written < 0) |
||
85 | err = errno; |
||
86 | else |
||
87 | err = WTAP_ERR_SHORT_WRITE; |
||
88 | if (show_err) |
||
89 | write_failure_alert_box(save_as_filename, err); |
||
90 | ws_close(to_fd); |
||
91 | return FALSE; |
||
92 | } |
||
93 | bytes_left -= bytes_written; |
||
94 | ptr += bytes_written; |
||
95 | } |
||
96 | if (ws_close(to_fd) < 0) { |
||
97 | if (show_err) |
||
98 | write_failure_alert_box(save_as_filename, errno); |
||
99 | return FALSE; |
||
100 | } |
||
101 | |||
102 | return TRUE; |
||
103 | } |
||
104 | |||
105 | |||
106 | #define HINIBBLE(x) (((x) >> 4) & 0xf) |
||
107 | #define LONIBBLE(x) ((x) & 0xf) |
||
108 | #define HEXTOASCII(x) (((x) < 10) ? ((x) + '0') : ((x) - 10 + 'a')) |
||
109 | #define MAXFILELEN 255 |
||
110 | |||
111 | static GString *eo_rename(GString *gstr, int dupn) |
||
112 | { |
||
113 | GString *gstr_tmp; |
||
114 | gchar *tmp_ptr; |
||
115 | GString *ext_str; |
||
116 | |||
117 | gstr_tmp = g_string_new("("); |
||
118 | g_string_append_printf (gstr_tmp, "%d)", dupn); |
||
119 | if ( (tmp_ptr = strrchr(gstr->str, '.')) != NULL ) { |
||
120 | /* Retain the extension */ |
||
121 | ext_str = g_string_new(tmp_ptr); |
||
122 | gstr = g_string_truncate(gstr, gstr->len - ext_str->len); |
||
123 | if ( gstr->len >= (MAXFILELEN - (strlen(gstr_tmp->str) + ext_str->len)) ) |
||
124 | gstr = g_string_truncate(gstr, MAXFILELEN - (strlen(gstr_tmp->str) + ext_str->len)); |
||
125 | gstr = g_string_append(gstr, gstr_tmp->str); |
||
126 | gstr = g_string_append(gstr, ext_str->str); |
||
127 | g_string_free(ext_str, TRUE); |
||
128 | } |
||
129 | else { |
||
130 | if ( gstr->len >= (MAXFILELEN - strlen(gstr_tmp->str)) ) |
||
131 | gstr = g_string_truncate(gstr, MAXFILELEN - strlen(gstr_tmp->str)); |
||
132 | gstr = g_string_append(gstr, gstr_tmp->str); |
||
133 | } |
||
134 | g_string_free(gstr_tmp, TRUE); |
||
135 | return gstr; |
||
136 | } |
||
137 | |||
138 | GString * |
||
139 | eo_massage_str(const gchar *in_str, gsize maxlen, int dupn) |
||
140 | { |
||
141 | gchar *tmp_ptr; |
||
142 | /* The characters in "reject" come from: |
||
143 | * http://msdn.microsoft.com/en-us/library/aa365247%28VS.85%29.aspx. |
||
144 | * Add to the list as necessary for other OS's. |
||
145 | */ |
||
146 | const gchar *reject = "<>:\"/\\|?*" |
||
147 | "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a" |
||
148 | "\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14" |
||
149 | "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"; |
||
150 | GString *out_str; |
||
151 | GString *ext_str; |
||
152 | |||
153 | out_str = g_string_new(""); |
||
154 | |||
155 | /* Find all disallowed characters/bytes and replace them with %xx */ |
||
156 | while ( (tmp_ptr = strpbrk(in_str, reject)) != NULL ) { |
||
157 | out_str = g_string_append_len(out_str, in_str, tmp_ptr - in_str); |
||
158 | out_str = g_string_append_c(out_str, '%'); |
||
159 | out_str = g_string_append_c(out_str, HEXTOASCII(HINIBBLE(*tmp_ptr))); |
||
160 | out_str = g_string_append_c(out_str, HEXTOASCII(LONIBBLE(*tmp_ptr))); |
||
161 | in_str = tmp_ptr + 1; |
||
162 | } |
||
163 | out_str = g_string_append(out_str, in_str); |
||
164 | if ( out_str->len > maxlen ) { |
||
165 | if ( (tmp_ptr = strrchr(out_str->str, '.')) != NULL ) { |
||
166 | /* Retain the extension */ |
||
167 | ext_str = g_string_new(tmp_ptr); |
||
168 | out_str = g_string_truncate(out_str, maxlen - ext_str->len); |
||
169 | out_str = g_string_append(out_str, ext_str->str); |
||
170 | g_string_free(ext_str, TRUE); |
||
171 | } |
||
172 | else |
||
173 | out_str = g_string_truncate(out_str, maxlen); |
||
174 | } |
||
175 | if ( dupn != 0 ) |
||
176 | out_str = eo_rename(out_str, dupn); |
||
177 | return out_str; |
||
178 | } |
||
179 | |||
180 | const char * |
||
181 | ct2ext(const char *content_type) |
||
182 | { |
||
183 | /* TODO: Map the content type string to an extension string. If no match, |
||
184 | * return NULL. */ |
||
185 | return content_type; |
||
186 | } |
||
187 | |||
188 | void eo_free_entry(export_object_entry_t *entry) |
||
189 | { |
||
190 | g_free(entry->hostname); |
||
191 | g_free(entry->content_type); |
||
192 | g_free(entry->filename); |
||
193 | g_free(entry->payload_data); |
||
194 | |||
195 | g_free(entry); |
||
196 | } |
||
197 | |||
198 | /* |
||
199 | * Editor modelines |
||
200 | * |
||
201 | * Local Variables: |
||
202 | * c-basic-offset: 4 |
||
203 | * tab-width: 8 |
||
204 | * indent-tabs-mode: nil |
||
205 | * End: |
||
206 | * |
||
207 | * ex: set shiftwidth=4 tabstop=8 expandtab: |
||
208 | * :indentSize=4:tabSize=8:noTabs=true: |
||
209 | */ |