nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* recent.c |
2 | * Recent "preference" handling routines |
||
3 | * Copyright 2004, Ulf Lamping <ulf.lamping@web.de> |
||
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 USA. |
||
22 | */ |
||
23 | |||
24 | #include "config.h" |
||
25 | |||
26 | #include <stdlib.h> |
||
27 | #include <string.h> |
||
28 | #include <errno.h> |
||
29 | |||
30 | #include "capture_opts.h" |
||
31 | #include <wsutil/filesystem.h> |
||
32 | #include <epan/prefs.h> |
||
33 | #include <epan/prefs-int.h> |
||
34 | #include <epan/column.h> |
||
35 | #include <epan/value_string.h> |
||
36 | |||
37 | #include "ui/last_open_dir.h" |
||
38 | #include "ui/recent.h" |
||
39 | #include "ui/recent_utils.h" |
||
40 | #include "ui/simple_dialog.h" |
||
41 | |||
42 | #include <wsutil/file_util.h> |
||
43 | |||
44 | #define RECENT_KEY_MAIN_TOOLBAR_SHOW "gui.toolbar_main_show" |
||
45 | #define RECENT_KEY_FILTER_TOOLBAR_SHOW "gui.filter_toolbar_show" |
||
46 | #define RECENT_KEY_WIRELESS_TOOLBAR_SHOW "gui.wireless_toolbar_show" |
||
47 | #define RECENT_KEY_DRIVER_CHECK_SHOW "gui.airpcap_driver_check_show" |
||
48 | #define RECENT_KEY_PACKET_LIST_SHOW "gui.packet_list_show" |
||
49 | #define RECENT_KEY_TREE_VIEW_SHOW "gui.tree_view_show" |
||
50 | #define RECENT_KEY_BYTE_VIEW_SHOW "gui.byte_view_show" |
||
51 | #define RECENT_KEY_STATUSBAR_SHOW "gui.statusbar_show" |
||
52 | #define RECENT_KEY_PACKET_LIST_COLORIZE "gui.packet_list_colorize" |
||
53 | #define RECENT_GUI_TIME_FORMAT "gui.time_format" |
||
54 | #define RECENT_GUI_TIME_PRECISION "gui.time_precision" |
||
55 | #define RECENT_GUI_SECONDS_FORMAT "gui.seconds_format" |
||
56 | #define RECENT_GUI_ZOOM_LEVEL "gui.zoom_level" |
||
57 | #define RECENT_GUI_BYTES_VIEW "gui.bytes_view" |
||
58 | #define RECENT_GUI_GEOMETRY_MAIN_X "gui.geometry_main_x" |
||
59 | #define RECENT_GUI_GEOMETRY_MAIN_Y "gui.geometry_main_y" |
||
60 | #define RECENT_GUI_GTK_GEOMETRY_MAIN_X "gui.gtk.geometry_main_x" |
||
61 | #define RECENT_GUI_GTK_GEOMETRY_MAIN_Y "gui.gtk.geometry_main_y" |
||
62 | #define RECENT_GUI_GEOMETRY_MAIN_WIDTH "gui.geometry_main_width" |
||
63 | #define RECENT_GUI_GEOMETRY_MAIN_HEIGHT "gui.geometry_main_height" |
||
64 | #define RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED "gui.geometry_main_maximized" |
||
65 | #define RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE "gui.geometry_main_upper_pane" |
||
66 | #define RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE "gui.geometry_main_lower_pane" |
||
67 | #define RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT "gui.geometry_status_pane" |
||
68 | #define RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT "gui.geometry_status_pane_right" |
||
69 | #define RECENT_GUI_GEOMETRY_WLAN_STATS_PANE "gui.geometry_status_wlan_stats_pane" |
||
70 | #define RECENT_LAST_USED_PROFILE "gui.last_used_profile" |
||
71 | #define RECENT_GUI_FILEOPEN_REMEMBERED_DIR "gui.fileopen_remembered_dir" |
||
72 | #define RECENT_GUI_CONVERSATION_TABS "gui.conversation_tabs" |
||
73 | #define RECENT_GUI_ENDPOINT_TABS "gui.endpoint_tabs" |
||
74 | #define RECENT_GUI_RLC_PDUS_FROM_MAC_FRAMES "gui.rlc_pdus_from_mac_frames" |
||
75 | #define RECENT_GUI_CUSTOM_COLORS "gui.custom_colors" |
||
76 | |||
77 | #define RECENT_GUI_GEOMETRY "gui.geom." |
||
78 | |||
79 | #define RECENT_KEY_PRIVS_WARN_IF_ELEVATED "privs.warn_if_elevated" |
||
80 | #define RECENT_KEY_PRIVS_WARN_IF_NO_NPF "privs.warn_if_no_npf" |
||
81 | |||
82 | #define RECENT_FILE_NAME "recent" |
||
83 | #define RECENT_COMMON_FILE_NAME "recent_common" |
||
84 | |||
85 | recent_settings_t recent; |
||
86 | |||
87 | static const value_string ts_type_values[] = { |
||
88 | { TS_RELATIVE, "RELATIVE" }, |
||
89 | { TS_ABSOLUTE, "ABSOLUTE" }, |
||
90 | { TS_ABSOLUTE_WITH_YMD, "ABSOLUTE_WITH_YMD" }, |
||
91 | { TS_ABSOLUTE_WITH_YDOY, "ABSOLUTE_WITH_YDOY" }, |
||
92 | { TS_ABSOLUTE_WITH_YMD, "ABSOLUTE_WITH_DATE" }, /* Backward compability */ |
||
93 | { TS_DELTA, "DELTA" }, |
||
94 | { TS_DELTA_DIS, "DELTA_DIS" }, |
||
95 | { TS_EPOCH, "EPOCH" }, |
||
96 | { TS_UTC, "UTC" }, |
||
97 | { TS_UTC_WITH_YMD, "UTC_WITH_YMD" }, |
||
98 | { TS_UTC_WITH_YDOY, "UTC_WITH_YDOY" }, |
||
99 | { TS_UTC_WITH_YMD, "UTC_WITH_DATE" }, /* Backward compability */ |
||
100 | { 0, NULL } |
||
101 | }; |
||
102 | |||
103 | static const value_string ts_precision_values[] = { |
||
104 | { TS_PREC_AUTO, "AUTO" }, |
||
105 | { TS_PREC_FIXED_SEC, "SEC" }, |
||
106 | { TS_PREC_FIXED_DSEC, "DSEC" }, |
||
107 | { TS_PREC_FIXED_CSEC, "CSEC" }, |
||
108 | { TS_PREC_FIXED_MSEC, "MSEC" }, |
||
109 | { TS_PREC_FIXED_USEC, "USEC" }, |
||
110 | { TS_PREC_FIXED_NSEC, "NSEC" }, |
||
111 | { 0, NULL } |
||
112 | }; |
||
113 | |||
114 | static const value_string ts_seconds_values[] = { |
||
115 | { TS_SECONDS_DEFAULT, "SECONDS" }, |
||
116 | { TS_SECONDS_HOUR_MIN_SEC, "HOUR_MIN_SEC" }, |
||
117 | { 0, NULL } |
||
118 | }; |
||
119 | |||
120 | static void |
||
121 | free_col_width_info(recent_settings_t *rs) |
||
122 | { |
||
123 | col_width_data *cfmt; |
||
124 | |||
125 | while (rs->col_width_list != NULL) { |
||
126 | cfmt = (col_width_data *)rs->col_width_list->data; |
||
127 | g_free(cfmt->cfield); |
||
128 | g_free(cfmt); |
||
129 | rs->col_width_list = g_list_remove_link(rs->col_width_list, rs->col_width_list); |
||
130 | } |
||
131 | g_list_free(rs->col_width_list); |
||
132 | rs->col_width_list = NULL; |
||
133 | } |
||
134 | |||
135 | /** Write the geometry values of a single window to the recent file. |
||
136 | * |
||
137 | * @param key unused |
||
138 | * @param value the geometry values |
||
139 | * @param rfh recent file handle (FILE) |
||
140 | */ |
||
141 | static void |
||
142 | write_recent_geom(gpointer key _U_, gpointer value, gpointer rfh) |
||
143 | { |
||
144 | window_geometry_t *geom = (window_geometry_t *)value; |
||
145 | FILE *rf = (FILE *)rfh; |
||
146 | |||
147 | fprintf(rf, "\n# Geometry and maximized state of %s window.\n", geom->key); |
||
148 | fprintf(rf, "# Decimal integers.\n"); |
||
149 | fprintf(rf, RECENT_GUI_GEOMETRY "%s.x: %d\n", geom->key, geom->x); |
||
150 | fprintf(rf, RECENT_GUI_GEOMETRY "%s.y: %d\n", geom->key, geom->y); |
||
151 | fprintf(rf, RECENT_GUI_GEOMETRY "%s.width: %d\n", geom->key, |
||
152 | geom->width); |
||
153 | fprintf(rf, RECENT_GUI_GEOMETRY "%s.height: %d\n", geom->key, |
||
154 | geom->height); |
||
155 | |||
156 | fprintf(rf, "# TRUE or FALSE (case-insensitive).\n"); |
||
157 | fprintf(rf, RECENT_GUI_GEOMETRY "%s.maximized: %s\n", geom->key, |
||
158 | geom->maximized == TRUE ? "TRUE" : "FALSE"); |
||
159 | |||
160 | } |
||
161 | |||
162 | /* the geometry hashtable for all known window classes, |
||
163 | * the window name is the key, and the geometry struct is the value */ |
||
164 | static GHashTable *window_geom_hash = NULL; |
||
165 | |||
166 | /* save the window and its current geometry into the geometry hashtable */ |
||
167 | void |
||
168 | window_geom_save(const gchar *name, window_geometry_t *geom) |
||
169 | { |
||
170 | gchar *key; |
||
171 | window_geometry_t *work; |
||
172 | |||
173 | /* init hashtable, if not already done */ |
||
174 | if (!window_geom_hash) { |
||
175 | window_geom_hash = g_hash_table_new(g_str_hash, g_str_equal); |
||
176 | } |
||
177 | /* if we have an old one, remove and free it first */ |
||
178 | work = (window_geometry_t *)g_hash_table_lookup(window_geom_hash, name); |
||
179 | if (work) { |
||
180 | g_hash_table_remove(window_geom_hash, name); |
||
181 | g_free(work->key); |
||
182 | g_free(work); |
||
183 | } |
||
184 | |||
185 | /* g_malloc and insert the new one */ |
||
186 | work = (window_geometry_t *)g_malloc(sizeof(window_geometry_t)); |
||
187 | *work = *geom; |
||
188 | key = g_strdup(name); |
||
189 | work->key = key; |
||
190 | g_hash_table_insert(window_geom_hash, key, work); |
||
191 | } |
||
192 | |||
193 | /* load the desired geometry for this window from the geometry hashtable */ |
||
194 | gboolean |
||
195 | window_geom_load(const gchar *name, |
||
196 | window_geometry_t *geom) |
||
197 | { |
||
198 | window_geometry_t *p; |
||
199 | |||
200 | /* init hashtable, if not already done */ |
||
201 | if (!window_geom_hash) { |
||
202 | window_geom_hash = g_hash_table_new(g_str_hash, g_str_equal); |
||
203 | } |
||
204 | |||
205 | p = (window_geometry_t *)g_hash_table_lookup(window_geom_hash, name); |
||
206 | if (p) { |
||
207 | *geom = *p; |
||
208 | return TRUE; |
||
209 | } else { |
||
210 | return FALSE; |
||
211 | } |
||
212 | } |
||
213 | |||
214 | /* parse values of particular types */ |
||
215 | static void |
||
216 | parse_recent_boolean(const gchar *val_str, gboolean *valuep) |
||
217 | { |
||
218 | if (g_ascii_strcasecmp(val_str, "true") == 0) { |
||
219 | *valuep = TRUE; |
||
220 | } |
||
221 | else { |
||
222 | *valuep = FALSE; |
||
223 | } |
||
224 | } |
||
225 | |||
226 | /** Read in a single geometry key value pair from the recent file. |
||
227 | * |
||
228 | * @param name the geom_name of the window |
||
229 | * @param key the subkey of this pair (e.g. "x") |
||
230 | * @param value the new value (e.g. "123") |
||
231 | */ |
||
232 | static void |
||
233 | window_geom_recent_read_pair(const char *name, |
||
234 | const char *key, |
||
235 | const char *value) |
||
236 | { |
||
237 | window_geometry_t geom; |
||
238 | |||
239 | /* find window geometry maybe already in hashtable */ |
||
240 | if (!window_geom_load(name, &geom)) { |
||
241 | /* not in table, init geom with "basic" values */ |
||
242 | geom.key = NULL; /* Will be set in window_geom_save() */ |
||
243 | geom.set_pos = FALSE; |
||
244 | geom.x = -1; |
||
245 | geom.y = -1; |
||
246 | geom.set_size = FALSE; |
||
247 | geom.width = -1; |
||
248 | geom.height = -1; |
||
249 | |||
250 | geom.set_maximized = FALSE;/* this is valid in GTK2 only */ |
||
251 | geom.maximized = FALSE; /* this is valid in GTK2 only */ |
||
252 | } |
||
253 | |||
254 | if (strcmp(key, "x") == 0) { |
||
255 | geom.x = (gint)strtol(value, NULL, 10); |
||
256 | geom.set_pos = TRUE; |
||
257 | } else if (strcmp(key, "y") == 0) { |
||
258 | geom.y = (gint)strtol(value, NULL, 10); |
||
259 | geom.set_pos = TRUE; |
||
260 | } else if (strcmp(key, "width") == 0) { |
||
261 | geom.width = (gint)strtol(value, NULL, 10); |
||
262 | geom.set_size = TRUE; |
||
263 | } else if (strcmp(key, "height") == 0) { |
||
264 | geom.height = (gint)strtol(value, NULL, 10); |
||
265 | geom.set_size = TRUE; |
||
266 | } else if (strcmp(key, "maximized") == 0) { |
||
267 | parse_recent_boolean(value, &geom.maximized); |
||
268 | geom.set_maximized = TRUE; |
||
269 | } else { |
||
270 | /* |
||
271 | * Silently ignore the bogus key. We shouldn't abort here, |
||
272 | * as this could be due to a corrupt recent file. |
||
273 | * |
||
274 | * XXX - should we print a message about this? |
||
275 | */ |
||
276 | return; |
||
277 | } |
||
278 | |||
279 | /* save / replace geometry in hashtable */ |
||
280 | window_geom_save(name, &geom); |
||
281 | } |
||
282 | |||
283 | /** Write all geometry values of all windows to the recent file. |
||
284 | * Will call write_recent_geom() for every existing window type. |
||
285 | * |
||
286 | * @param rf recent file handle from caller |
||
287 | */ |
||
288 | static void |
||
289 | window_geom_recent_write_all(FILE *rf) |
||
290 | { |
||
291 | /* init hashtable, if not already done */ |
||
292 | if (!window_geom_hash) { |
||
293 | window_geom_hash = g_hash_table_new(g_str_hash, g_str_equal); |
||
294 | } |
||
295 | |||
296 | g_hash_table_foreach(window_geom_hash, write_recent_geom, rf); |
||
297 | } |
||
298 | |||
299 | /* Global list of recent capture filters. */ |
||
300 | static GList *recent_cfilter_list; |
||
301 | |||
302 | /* |
||
303 | * Per-interface lists of recent capture filters; stored in a hash |
||
304 | * table indexed by interface name. |
||
305 | */ |
||
306 | static GHashTable *per_interface_cfilter_lists_hash; |
||
307 | |||
308 | /* XXX: use a preference for this setting! */ |
||
309 | static guint cfilter_combo_max_recent = 20; |
||
310 | |||
311 | /** |
||
312 | * Returns a list of recent capture filters. |
||
313 | * |
||
314 | * @param ifname interface name; NULL refers to the global list. |
||
315 | */ |
||
316 | GList * |
||
317 | recent_get_cfilter_list(const gchar *ifname) |
||
318 | { |
||
319 | if (ifname == NULL) |
||
320 | return recent_cfilter_list; |
||
321 | if (per_interface_cfilter_lists_hash == NULL) { |
||
322 | /* No such lists exist. */ |
||
323 | return NULL; |
||
324 | } |
||
325 | return (GList *)g_hash_table_lookup(per_interface_cfilter_lists_hash, ifname); |
||
326 | } |
||
327 | |||
328 | /** |
||
329 | * Add a capture filter to the global recent capture filter list or |
||
330 | * the recent capture filter list for an interface. |
||
331 | * |
||
332 | * @param ifname interface name; NULL refers to the global list. |
||
333 | * @param s text of capture filter |
||
334 | */ |
||
335 | void |
||
336 | recent_add_cfilter(const gchar *ifname, const gchar *s) |
||
337 | { |
||
338 | GList *cfilter_list; |
||
339 | GList *li; |
||
340 | gchar *li_filter, *newfilter = NULL; |
||
341 | |||
342 | /* Don't add empty filters to the list. */ |
||
343 | if (s[0] == '\0') |
||
344 | return; |
||
345 | |||
346 | if (ifname == NULL) |
||
347 | cfilter_list = recent_cfilter_list; |
||
348 | else { |
||
349 | /* If we don't yet have a hash table for per-interface recent |
||
350 | capture filter lists, create one. Have it free the new key |
||
351 | if we're updating an entry rather than creating it below. */ |
||
352 | if (per_interface_cfilter_lists_hash == NULL) |
||
353 | per_interface_cfilter_lists_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); |
||
354 | cfilter_list = (GList *)g_hash_table_lookup(per_interface_cfilter_lists_hash, ifname); |
||
355 | } |
||
356 | |||
357 | li = g_list_first(cfilter_list); |
||
358 | while (li) { |
||
359 | /* If the filter is already in the list, remove the old one and |
||
360 | * append the new one at the latest position (at g_list_append() below) */ |
||
361 | li_filter = (char *)li->data; |
||
362 | if (strcmp(s, li_filter) == 0) { |
||
363 | /* No need to copy the string, we're just moving it. */ |
||
364 | newfilter = li_filter; |
||
365 | cfilter_list = g_list_remove(cfilter_list, li->data); |
||
366 | break; |
||
367 | } |
||
368 | li = li->next; |
||
369 | } |
||
370 | if (newfilter == NULL) { |
||
371 | /* The filter wasn't already in the list; make a copy to add. */ |
||
372 | newfilter = g_strdup(s); |
||
373 | } |
||
374 | cfilter_list = g_list_append(cfilter_list, newfilter); |
||
375 | |||
376 | if (ifname == NULL) |
||
377 | recent_cfilter_list = cfilter_list; |
||
378 | else |
||
379 | g_hash_table_insert(per_interface_cfilter_lists_hash, g_strdup(ifname), cfilter_list); |
||
380 | } |
||
381 | |||
382 | #ifdef HAVE_PCAP_REMOTE |
||
383 | static GHashTable *remote_host_list=NULL; |
||
384 | |||
385 | int recent_get_remote_host_list_size(void) |
||
386 | { |
||
387 | return g_hash_table_size (remote_host_list); |
||
388 | } |
||
389 | |||
390 | void recent_add_remote_host(gchar *host, struct remote_host *rh) |
||
391 | { |
||
392 | if (remote_host_list == NULL) { |
||
393 | remote_host_list = g_hash_table_new (g_str_hash, g_str_equal); |
||
394 | } |
||
395 | g_hash_table_insert (remote_host_list, g_strdup(host), rh); |
||
396 | } |
||
397 | |||
398 | static gboolean |
||
399 | free_remote_host (gpointer key _U_, gpointer value, gpointer user _U_) |
||
400 | { |
||
401 | struct remote_host *rh = value; |
||
402 | |||
403 | g_free (rh->r_host); |
||
404 | g_free (rh->remote_port); |
||
405 | g_free (rh->auth_username); |
||
406 | g_free (rh->auth_password); |
||
407 | |||
408 | return TRUE; |
||
409 | } |
||
410 | |||
411 | GHashTable *get_remote_host_list(void) |
||
412 | { |
||
413 | return remote_host_list; |
||
414 | } |
||
415 | |||
416 | static void |
||
417 | recent_print_remote_host (gpointer key _U_, gpointer value, gpointer user) |
||
418 | { |
||
419 | FILE *rf = user; |
||
420 | struct remote_host_info *ri = value; |
||
421 | |||
422 | fprintf (rf, RECENT_KEY_REMOTE_HOST ": %s,%s,%d\n", ri->remote_host, ri->remote_port, ri->auth_type); |
||
423 | } |
||
424 | |||
425 | void |
||
426 | capture_remote_combo_recent_write_all(FILE *rf) |
||
427 | { |
||
428 | if (remote_host_list && g_hash_table_size (remote_host_list) > 0) { |
||
429 | /* Write all remote interfaces to the recent file */ |
||
430 | g_hash_table_foreach (remote_host_list, recent_print_remote_host, rf); |
||
431 | } |
||
432 | } |
||
433 | |||
434 | |||
435 | void free_remote_host_list(void) |
||
436 | { |
||
437 | g_hash_table_foreach_remove(remote_host_list, free_remote_host, NULL); |
||
438 | } |
||
439 | |||
440 | struct remote_host * |
||
441 | recent_get_remote_host(const gchar *host) |
||
442 | { |
||
443 | if (host == NULL) |
||
444 | return NULL; |
||
445 | if (remote_host_list == NULL) { |
||
446 | /* No such host exist. */ |
||
447 | return NULL; |
||
448 | } |
||
449 | return (struct remote_host *)g_hash_table_lookup(remote_host_list, host); |
||
450 | } |
||
451 | |||
452 | gboolean |
||
453 | capture_remote_combo_add_recent(const gchar *s) |
||
454 | { |
||
455 | GList *vals = prefs_get_string_list (s); |
||
456 | GList *valp = vals; |
||
457 | gint auth_type; |
||
458 | char *p; |
||
459 | struct remote_host *rh; |
||
460 | |||
461 | if (valp == NULL) |
||
462 | return FALSE; |
||
463 | |||
464 | if (remote_host_list == NULL) { |
||
465 | remote_host_list = g_hash_table_new (g_str_hash, g_str_equal); |
||
466 | } |
||
467 | |||
468 | rh = g_malloc (sizeof (*rh)); |
||
469 | |||
470 | /* First value is the host */ |
||
471 | rh->r_host = g_strdup (valp->data); |
||
472 | if (strlen(rh->r_host) == 0) { |
||
473 | /* Empty remote host */ |
||
474 | g_free(rh->r_host); |
||
475 | g_free(rh); |
||
476 | return FALSE; |
||
477 | } |
||
478 | rh->auth_type = CAPTURE_AUTH_NULL; |
||
479 | valp = valp->next; |
||
480 | |||
481 | if (valp) { |
||
482 | /* Found value 2, this is the port number */ |
||
483 | rh->remote_port = g_strdup (valp->data); |
||
484 | valp = valp->next; |
||
485 | } else { |
||
486 | /* Did not find a port number */ |
||
487 | rh->remote_port = g_strdup (""); |
||
488 | } |
||
489 | |||
490 | if (valp) { |
||
491 | /* Found value 3, this is the authentication type */ |
||
492 | auth_type = strtol(valp->data, &p, 0); |
||
493 | if (p != valp->data && *p == '\0') { |
||
494 | rh->auth_type = auth_type; |
||
495 | } |
||
496 | } |
||
497 | |||
498 | /* Do not store username and password */ |
||
499 | rh->auth_username = g_strdup (""); |
||
500 | rh->auth_password = g_strdup (""); |
||
501 | |||
502 | prefs_clear_string_list(vals); |
||
503 | |||
504 | g_hash_table_insert (remote_host_list, g_strdup(rh->r_host), rh); |
||
505 | |||
506 | return TRUE; |
||
507 | } |
||
508 | #endif |
||
509 | |||
510 | static void |
||
511 | cfilter_recent_write_all_list(FILE *rf, const gchar *ifname, GList *cfilter_list) |
||
512 | { |
||
513 | guint max_count = 0; |
||
514 | GList *li; |
||
515 | |||
516 | /* write all non empty capture filter strings to the recent file (until max count) */ |
||
517 | li = g_list_first(cfilter_list); |
||
518 | while (li && (max_count++ <= cfilter_combo_max_recent) ) { |
||
519 | if (li->data && strlen((const char *)li->data)) { |
||
520 | if (ifname == NULL) |
||
521 | fprintf (rf, RECENT_KEY_CAPTURE_FILTER ": %s\n", (char *)li->data); |
||
522 | else |
||
523 | fprintf (rf, RECENT_KEY_CAPTURE_FILTER ".%s: %s\n", ifname, (char *)li->data); |
||
524 | } |
||
525 | li = li->next; |
||
526 | } |
||
527 | } |
||
528 | |||
529 | static void |
||
530 | cfilter_recent_write_all_hash_callback(gpointer key, gpointer value, gpointer user_data) |
||
531 | { |
||
532 | cfilter_recent_write_all_list((FILE *)user_data, (const gchar *)key, (GList *)value); |
||
533 | } |
||
534 | |||
535 | /** Write all capture filter values to the recent file. |
||
536 | * |
||
537 | * @param rf recent file handle from caller |
||
538 | */ |
||
539 | static void |
||
540 | cfilter_recent_write_all(FILE *rf) |
||
541 | { |
||
542 | /* Write out the global list. */ |
||
543 | cfilter_recent_write_all_list(rf, NULL, recent_cfilter_list); |
||
544 | |||
545 | /* Write out all the per-interface lists. */ |
||
546 | if (per_interface_cfilter_lists_hash != NULL) { |
||
547 | g_hash_table_foreach(per_interface_cfilter_lists_hash, cfilter_recent_write_all_hash_callback, (gpointer)rf); |
||
548 | } |
||
549 | } |
||
550 | |||
551 | /* Write out recent settings of particular types. */ |
||
552 | static void |
||
553 | write_recent_boolean(FILE *rf, const char *description, const char *name, |
||
554 | gboolean value) |
||
555 | { |
||
556 | fprintf(rf, "\n# %s.\n", description); |
||
557 | fprintf(rf, "# TRUE or FALSE (case-insensitive).\n"); |
||
558 | fprintf(rf, "%s: %s\n", name, value == TRUE ? "TRUE" : "FALSE"); |
||
559 | } |
||
560 | |||
561 | static void |
||
562 | write_recent_enum(FILE *rf, const char *description, const char *name, |
||
563 | const value_string *values, guint value) |
||
564 | { |
||
565 | const char *if_invalid = NULL; |
||
566 | const value_string *valp; |
||
567 | |||
568 | fprintf(rf, "\n# %s.\n", description); |
||
569 | fprintf(rf, "# One of: "); |
||
570 | valp = values; |
||
571 | while (valp->strptr != NULL) { |
||
572 | if (if_invalid == NULL) |
||
573 | if_invalid = valp->strptr; |
||
574 | fprintf(rf, "%s", valp->strptr); |
||
575 | valp++; |
||
576 | if (valp->strptr != NULL) |
||
577 | fprintf(rf, ", "); |
||
578 | } |
||
579 | fprintf(rf, "\n"); |
||
580 | fprintf(rf, "%s: %s\n", name, |
||
581 | val_to_str(value, values, if_invalid != NULL ? if_invalid : "Unknown")); |
||
582 | } |
||
583 | |||
584 | /* Attempt to write out "recent common" to the user's recent common file. |
||
585 | If we got an error report it with a dialog box and return FALSE, |
||
586 | otherwise return TRUE. */ |
||
587 | gboolean |
||
588 | write_recent(void) |
||
589 | { |
||
590 | char *pf_dir_path; |
||
591 | char *rf_path; |
||
592 | FILE *rf; |
||
593 | char *string_list; |
||
594 | |||
595 | /* To do: |
||
596 | * - Split output lines longer than MAX_VAL_LEN |
||
597 | * - Create a function for the preference directory check/creation |
||
598 | * so that duplication can be avoided with filter.c |
||
599 | */ |
||
600 | |||
601 | /* Create the directory that holds personal configuration files, if |
||
602 | necessary. */ |
||
603 | if (create_persconffile_dir(&pf_dir_path) == -1) { |
||
604 | simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, |
||
605 | "Can't create directory\n\"%s\"\nfor recent file: %s.", pf_dir_path, |
||
606 | g_strerror(errno)); |
||
607 | g_free(pf_dir_path); |
||
608 | return FALSE; |
||
609 | } |
||
610 | |||
611 | rf_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE); |
||
612 | if ((rf = ws_fopen(rf_path, "w")) == NULL) { |
||
613 | simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, |
||
614 | "Can't open recent file\n\"%s\": %s.", rf_path, |
||
615 | g_strerror(errno)); |
||
616 | g_free(rf_path); |
||
617 | return FALSE; |
||
618 | } |
||
619 | g_free(rf_path); |
||
620 | |||
621 | fputs("# Recent settings file for Wireshark " VERSION ".\n" |
||
622 | "#\n" |
||
623 | "# This file is regenerated each time Wireshark is quit.\n" |
||
624 | "# So be careful, if you want to make manual changes here.\n" |
||
625 | "\n" |
||
626 | "######## Recent capture files (latest last), cannot be altered through command line ########\n" |
||
627 | "\n", rf); |
||
628 | |||
629 | menu_recent_file_write_all(rf); |
||
630 | |||
631 | fputs("\n" |
||
632 | "######## Recent capture filters (latest last), cannot be altered through command line ########\n" |
||
633 | "\n", rf); |
||
634 | |||
635 | cfilter_recent_write_all(rf); |
||
636 | |||
637 | fputs("\n" |
||
638 | "######## Recent display filters (latest last), cannot be altered through command line ########\n" |
||
639 | "\n", rf); |
||
640 | |||
641 | dfilter_recent_combo_write_all(rf); |
||
642 | |||
643 | #ifdef HAVE_PCAP_REMOTE |
||
644 | fputs("\n" |
||
645 | "######## Recent remote hosts, cannot be altered through command line ########\n" |
||
646 | "\n", rf); |
||
647 | |||
648 | capture_remote_combo_recent_write_all(rf); |
||
649 | #endif |
||
650 | |||
651 | fprintf(rf, "\n# Main window geometry.\n"); |
||
652 | fprintf(rf, "# Decimal numbers.\n"); |
||
653 | fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_X ": %d\n", recent.gui_geometry_main_x); |
||
654 | fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_Y ": %d\n", recent.gui_geometry_main_y); |
||
655 | fprintf(rf, RECENT_GUI_GTK_GEOMETRY_MAIN_X ": %d\n", recent.gui_gtk_geometry_main_x); |
||
656 | fprintf(rf, RECENT_GUI_GTK_GEOMETRY_MAIN_Y ": %d\n", recent.gui_gtk_geometry_main_y); |
||
657 | fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_WIDTH ": %d\n", |
||
658 | recent.gui_geometry_main_width); |
||
659 | fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_HEIGHT ": %d\n", |
||
660 | recent.gui_geometry_main_height); |
||
661 | |||
662 | write_recent_boolean(rf, "Main window maximized", |
||
663 | RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED, |
||
664 | recent.gui_geometry_main_maximized); |
||
665 | |||
666 | fprintf(rf, "\n# Statusbar left pane size.\n"); |
||
667 | fprintf(rf, "# Decimal number.\n"); |
||
668 | if (recent.gui_geometry_status_pane_left != 0) { |
||
669 | fprintf(rf, RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT ": %d\n", |
||
670 | recent.gui_geometry_status_pane_left); |
||
671 | } |
||
672 | fprintf(rf, "\n# Statusbar middle pane size.\n"); |
||
673 | fprintf(rf, "# Decimal number.\n"); |
||
674 | if (recent.gui_geometry_status_pane_right != 0) { |
||
675 | fprintf(rf, RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT ": %d\n", |
||
676 | recent.gui_geometry_status_pane_right); |
||
677 | } |
||
678 | |||
679 | fprintf(rf, "\n# Last used Configuration Profile.\n"); |
||
680 | fprintf(rf, RECENT_LAST_USED_PROFILE ": %s\n", get_profile_name()); |
||
681 | |||
682 | fprintf(rf, "\n# WLAN statistics upper pane size.\n"); |
||
683 | fprintf(rf, "# Decimal number.\n"); |
||
684 | fprintf(rf, RECENT_GUI_GEOMETRY_WLAN_STATS_PANE ": %d\n", |
||
685 | recent.gui_geometry_wlan_stats_pane); |
||
686 | |||
687 | write_recent_boolean(rf, "Warn if running with elevated permissions (e.g. as root)", |
||
688 | RECENT_KEY_PRIVS_WARN_IF_ELEVATED, |
||
689 | recent.privs_warn_if_elevated); |
||
690 | |||
691 | write_recent_boolean(rf, "Warn if npf.sys isn't loaded on Windows >= 6.0", |
||
692 | RECENT_KEY_PRIVS_WARN_IF_NO_NPF, |
||
693 | recent.privs_warn_if_no_npf); |
||
694 | |||
695 | window_geom_recent_write_all(rf); |
||
696 | |||
697 | fprintf(rf, "\n# Custom colors.\n"); |
||
698 | fprintf(rf, "# List of custom colors selected in Qt color picker.\n"); |
||
699 | string_list = join_string_list(recent.custom_colors); |
||
700 | fprintf(rf, RECENT_GUI_CUSTOM_COLORS ": %s\n", string_list); |
||
701 | g_free(string_list); |
||
702 | |||
703 | fclose(rf); |
||
704 | |||
705 | /* XXX - catch I/O errors (e.g. "ran out of disk space") and return |
||
706 | an error indication, or maybe write to a new recent file and |
||
707 | rename that file on top of the old one only if there are not I/O |
||
708 | errors. */ |
||
709 | return TRUE; |
||
710 | } |
||
711 | |||
712 | |||
713 | /* Attempt to Write out profile "recent" to the user's profile recent file. |
||
714 | If we got an error report it with a dialog box and return FALSE, |
||
715 | otherwise return TRUE. */ |
||
716 | gboolean |
||
717 | write_profile_recent(void) |
||
718 | { |
||
719 | char *pf_dir_path; |
||
720 | char *rf_path; |
||
721 | char *string_list; |
||
722 | FILE *rf; |
||
723 | |||
724 | /* To do: |
||
725 | * - Split output lines longer than MAX_VAL_LEN |
||
726 | * - Create a function for the preference directory check/creation |
||
727 | * so that duplication can be avoided with filter.c |
||
728 | */ |
||
729 | |||
730 | /* Create the directory that holds personal configuration files, if |
||
731 | necessary. */ |
||
732 | if (create_persconffile_dir(&pf_dir_path) == -1) { |
||
733 | simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, |
||
734 | "Can't create directory\n\"%s\"\nfor recent file: %s.", pf_dir_path, |
||
735 | g_strerror(errno)); |
||
736 | g_free(pf_dir_path); |
||
737 | return FALSE; |
||
738 | } |
||
739 | |||
740 | rf_path = get_persconffile_path(RECENT_FILE_NAME, TRUE); |
||
741 | if ((rf = ws_fopen(rf_path, "w")) == NULL) { |
||
742 | simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, |
||
743 | "Can't open recent file\n\"%s\": %s.", rf_path, |
||
744 | g_strerror(errno)); |
||
745 | g_free(rf_path); |
||
746 | return FALSE; |
||
747 | } |
||
748 | g_free(rf_path); |
||
749 | |||
750 | fputs("# Recent settings file for Wireshark " VERSION ".\n" |
||
751 | "#\n" |
||
752 | "# This file is regenerated each time Wireshark is quit\n" |
||
753 | "# and when changing configuration profile.\n" |
||
754 | "# So be careful, if you want to make manual changes here.\n" |
||
755 | "\n", rf); |
||
756 | |||
757 | write_recent_boolean(rf, "Main Toolbar show (hide)", |
||
758 | RECENT_KEY_MAIN_TOOLBAR_SHOW, |
||
759 | recent.main_toolbar_show); |
||
760 | |||
761 | write_recent_boolean(rf, "Filter Toolbar show (hide)", |
||
762 | RECENT_KEY_FILTER_TOOLBAR_SHOW, |
||
763 | recent.filter_toolbar_show); |
||
764 | |||
765 | write_recent_boolean(rf, "Wireless Settings Toolbar show (hide)", |
||
766 | RECENT_KEY_WIRELESS_TOOLBAR_SHOW, |
||
767 | recent.wireless_toolbar_show); |
||
768 | |||
769 | #ifdef HAVE_AIRPCAP |
||
770 | write_recent_boolean(rf, "Show (hide) old AirPcap driver warning dialog box", |
||
771 | RECENT_KEY_DRIVER_CHECK_SHOW, |
||
772 | recent.airpcap_driver_check_show); |
||
773 | #endif |
||
774 | |||
775 | write_recent_boolean(rf, "Packet list show (hide)", |
||
776 | RECENT_KEY_PACKET_LIST_SHOW, |
||
777 | recent.packet_list_show); |
||
778 | |||
779 | write_recent_boolean(rf, "Tree view show (hide)", |
||
780 | RECENT_KEY_TREE_VIEW_SHOW, |
||
781 | recent.tree_view_show); |
||
782 | |||
783 | write_recent_boolean(rf, "Byte view show (hide)", |
||
784 | RECENT_KEY_BYTE_VIEW_SHOW, |
||
785 | recent.byte_view_show); |
||
786 | |||
787 | write_recent_boolean(rf, "Statusbar show (hide)", |
||
788 | RECENT_KEY_STATUSBAR_SHOW, |
||
789 | recent.statusbar_show); |
||
790 | |||
791 | write_recent_boolean(rf, "Packet list colorize (hide)", |
||
792 | RECENT_KEY_PACKET_LIST_COLORIZE, |
||
793 | recent.packet_list_colorize); |
||
794 | |||
795 | write_recent_enum(rf, "Timestamp display format", |
||
796 | RECENT_GUI_TIME_FORMAT, ts_type_values, |
||
797 | recent.gui_time_format); |
||
798 | |||
799 | write_recent_enum(rf, "Timestamp display precision", |
||
800 | RECENT_GUI_TIME_PRECISION, ts_precision_values, |
||
801 | recent.gui_time_precision); |
||
802 | |||
803 | write_recent_enum(rf, "Seconds display format", |
||
804 | RECENT_GUI_SECONDS_FORMAT, ts_seconds_values, |
||
805 | recent.gui_seconds_format); |
||
806 | |||
807 | fprintf(rf, "\n# Zoom level.\n"); |
||
808 | fprintf(rf, "# A decimal number.\n"); |
||
809 | fprintf(rf, RECENT_GUI_ZOOM_LEVEL ": %d\n", |
||
810 | recent.gui_zoom_level); |
||
811 | |||
812 | fprintf(rf, "\n# Bytes view.\n"); |
||
813 | fprintf(rf, "# A decimal number.\n"); |
||
814 | fprintf(rf, RECENT_GUI_BYTES_VIEW ": %d\n", |
||
815 | recent.gui_bytes_view); |
||
816 | |||
817 | fprintf(rf, "\n# Main window upper (or leftmost) pane size.\n"); |
||
818 | fprintf(rf, "# Decimal number.\n"); |
||
819 | if (recent.gui_geometry_main_upper_pane != 0) { |
||
820 | fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE ": %d\n", |
||
821 | recent.gui_geometry_main_upper_pane); |
||
822 | } |
||
823 | fprintf(rf, "\n# Main window middle pane size.\n"); |
||
824 | fprintf(rf, "# Decimal number.\n"); |
||
825 | if (recent.gui_geometry_main_lower_pane != 0) { |
||
826 | fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE ": %d\n", |
||
827 | recent.gui_geometry_main_lower_pane); |
||
828 | } |
||
829 | |||
830 | fprintf(rf, "\n# Packet list column pixel widths.\n"); |
||
831 | fprintf(rf, "# Each pair of strings consists of a column format and its pixel width.\n"); |
||
832 | packet_list_recent_write_all(rf); |
||
833 | |||
834 | fprintf(rf, "\n# Open conversation dialog tabs.\n"); |
||
835 | fprintf(rf, "# List of conversation names, e.g. \"TCP\", \"IPv6\".\n"); |
||
836 | string_list = join_string_list(recent.conversation_tabs); |
||
837 | fprintf(rf, RECENT_GUI_CONVERSATION_TABS ": %s\n", string_list); |
||
838 | g_free(string_list); |
||
839 | |||
840 | fprintf(rf, "\n# Open endpoint dialog tabs.\n"); |
||
841 | fprintf(rf, "# List of endpoint names, e.g. \"TCP\", \"IPv6\".\n"); |
||
842 | string_list = join_string_list(recent.endpoint_tabs); |
||
843 | fprintf(rf, RECENT_GUI_ENDPOINT_TABS ": %s\n", string_list); |
||
844 | g_free(string_list); |
||
845 | |||
846 | write_recent_boolean(rf, "For RLC stats, whether to use RLC PDUs found inside MAC frames", |
||
847 | RECENT_GUI_RLC_PDUS_FROM_MAC_FRAMES, |
||
848 | recent.gui_rlc_use_pdus_from_mac); |
||
849 | |||
850 | if (get_last_open_dir() != NULL) { |
||
851 | fprintf(rf, "\n# Last directory navigated to in File Open dialog.\n"); |
||
852 | fprintf(rf, RECENT_GUI_FILEOPEN_REMEMBERED_DIR ": %s\n", get_last_open_dir()); |
||
853 | } |
||
854 | |||
855 | fclose(rf); |
||
856 | |||
857 | /* XXX - catch I/O errors (e.g. "ran out of disk space") and return |
||
858 | an error indication, or maybe write to a new recent file and |
||
859 | rename that file on top of the old one only if there are not I/O |
||
860 | errors. */ |
||
861 | return TRUE; |
||
862 | } |
||
863 | |||
864 | /* set one user's recent common file key/value pair */ |
||
865 | static prefs_set_pref_e |
||
866 | read_set_recent_common_pair_static(gchar *key, const gchar *value, |
||
867 | void *private_data _U_, |
||
868 | gboolean return_range_errors _U_) |
||
869 | { |
||
870 | long num; |
||
871 | char *p; |
||
872 | |||
873 | if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED) == 0) { |
||
874 | parse_recent_boolean(value, &recent.gui_geometry_main_maximized); |
||
875 | } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_X) == 0) { |
||
876 | num = strtol(value, &p, 0); |
||
877 | if (p == value || *p != '\0') |
||
878 | return PREFS_SET_SYNTAX_ERR; /* number was bad */ |
||
879 | recent.gui_geometry_main_x = (gint)num; |
||
880 | } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_Y) == 0) { |
||
881 | num = strtol(value, &p, 0); |
||
882 | if (p == value || *p != '\0') |
||
883 | return PREFS_SET_SYNTAX_ERR; /* number was bad */ |
||
884 | recent.gui_geometry_main_y = (gint)num; |
||
885 | } else if (strcmp(key, RECENT_GUI_GTK_GEOMETRY_MAIN_X) == 0) { |
||
886 | num = strtol(value, &p, 0); |
||
887 | if (p == value || *p != '\0') |
||
888 | return PREFS_SET_SYNTAX_ERR; /* number was bad */ |
||
889 | recent.gui_gtk_geometry_main_x = (gint)num; |
||
890 | } else if (strcmp(key, RECENT_GUI_GTK_GEOMETRY_MAIN_Y) == 0) { |
||
891 | num = strtol(value, &p, 0); |
||
892 | if (p == value || *p != '\0') |
||
893 | return PREFS_SET_SYNTAX_ERR; /* number was bad */ |
||
894 | recent.gui_gtk_geometry_main_y = (gint)num; |
||
895 | } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_WIDTH) == 0) { |
||
896 | num = strtol(value, &p, 0); |
||
897 | if (p == value || *p != '\0') |
||
898 | return PREFS_SET_SYNTAX_ERR; /* number was bad */ |
||
899 | if (num <= 0) |
||
900 | return PREFS_SET_SYNTAX_ERR; /* number must be positive */ |
||
901 | recent.gui_geometry_main_width = (gint)num; |
||
902 | } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_HEIGHT) == 0) { |
||
903 | num = strtol(value, &p, 0); |
||
904 | if (p == value || *p != '\0') |
||
905 | return PREFS_SET_SYNTAX_ERR; /* number was bad */ |
||
906 | if (num <= 0) |
||
907 | return PREFS_SET_SYNTAX_ERR; /* number must be positive */ |
||
908 | recent.gui_geometry_main_height = (gint)num; |
||
909 | } else if (strcmp(key, RECENT_GUI_GEOMETRY_STATUS_PANE_RIGHT) == 0) { |
||
910 | num = strtol(value, &p, 0); |
||
911 | if (p == value || *p != '\0') |
||
912 | return PREFS_SET_SYNTAX_ERR; /* number was bad */ |
||
913 | if (num <= 0) |
||
914 | return PREFS_SET_SYNTAX_ERR; /* number must be positive */ |
||
915 | recent.gui_geometry_status_pane_right = (gint)num; |
||
916 | recent.has_gui_geometry_status_pane = TRUE; |
||
917 | } else if (strcmp(key, RECENT_GUI_GEOMETRY_STATUS_PANE_LEFT) == 0) { |
||
918 | num = strtol(value, &p, 0); |
||
919 | if (p == value || *p != '\0') |
||
920 | return PREFS_SET_SYNTAX_ERR; /* number was bad */ |
||
921 | if (num <= 0) |
||
922 | return PREFS_SET_SYNTAX_ERR; /* number must be positive */ |
||
923 | recent.gui_geometry_status_pane_left = (gint)num; |
||
924 | recent.has_gui_geometry_status_pane = TRUE; |
||
925 | } else if (strcmp(key, RECENT_LAST_USED_PROFILE) == 0) { |
||
926 | if ((strcmp(value, DEFAULT_PROFILE) != 0) && profile_exists (value, FALSE)) { |
||
927 | set_profile_name (value); |
||
928 | } |
||
929 | } else if (strcmp(key, RECENT_GUI_GEOMETRY_WLAN_STATS_PANE) == 0) { |
||
930 | num = strtol(value, &p, 0); |
||
931 | if (p == value || *p != '\0') |
||
932 | return PREFS_SET_SYNTAX_ERR; /* number was bad */ |
||
933 | if (num <= 0) |
||
934 | return PREFS_SET_SYNTAX_ERR; /* number must be positive */ |
||
935 | recent.gui_geometry_wlan_stats_pane = (gint)num; |
||
936 | } else if (strncmp(key, RECENT_GUI_GEOMETRY, sizeof(RECENT_GUI_GEOMETRY)-1) == 0) { |
||
937 | /* now have something like "gui.geom.main.x", split it into win and sub_key */ |
||
938 | char *win = &key[sizeof(RECENT_GUI_GEOMETRY)-1]; |
||
939 | char *sub_key = strchr(win, '.'); |
||
940 | if (sub_key) { |
||
941 | *sub_key = '\0'; |
||
942 | sub_key++; |
||
943 | window_geom_recent_read_pair(win, sub_key, value); |
||
944 | } |
||
945 | } else if (strcmp(key, RECENT_KEY_PRIVS_WARN_IF_ELEVATED) == 0) { |
||
946 | parse_recent_boolean(value, &recent.privs_warn_if_elevated); |
||
947 | } else if (strcmp(key, RECENT_KEY_PRIVS_WARN_IF_NO_NPF) == 0) { |
||
948 | parse_recent_boolean(value, &recent.privs_warn_if_no_npf); |
||
949 | } else if (strcmp(key, RECENT_GUI_CUSTOM_COLORS) == 0) { |
||
950 | recent.custom_colors = prefs_get_string_list(value); |
||
951 | } |
||
952 | |||
953 | return PREFS_SET_OK; |
||
954 | } |
||
955 | |||
956 | /* set one user's recent file key/value pair */ |
||
957 | static prefs_set_pref_e |
||
958 | read_set_recent_pair_static(gchar *key, const gchar *value, |
||
959 | void *private_data _U_, |
||
960 | gboolean return_range_errors _U_) |
||
961 | { |
||
962 | long num; |
||
963 | char *p; |
||
964 | GList *col_l, *col_l_elt; |
||
965 | col_width_data *cfmt; |
||
966 | const gchar *cust_format = col_format_to_string(COL_CUSTOM); |
||
967 | int cust_format_len = (int) strlen(cust_format); |
||
968 | |||
969 | if (strcmp(key, RECENT_KEY_MAIN_TOOLBAR_SHOW) == 0) { |
||
970 | parse_recent_boolean(value, &recent.main_toolbar_show); |
||
971 | } else if (strcmp(key, RECENT_KEY_FILTER_TOOLBAR_SHOW) == 0) { |
||
972 | parse_recent_boolean(value, &recent.filter_toolbar_show); |
||
973 | /* check both the old and the new keyword */ |
||
974 | } else if (strcmp(key, RECENT_KEY_WIRELESS_TOOLBAR_SHOW) == 0 || (strcmp(key, "gui.airpcap_toolbar_show") == 0)) { |
||
975 | parse_recent_boolean(value, &recent.wireless_toolbar_show); |
||
976 | } else if (strcmp(key, RECENT_KEY_DRIVER_CHECK_SHOW) == 0) { |
||
977 | parse_recent_boolean(value, &recent.airpcap_driver_check_show); |
||
978 | } else if (strcmp(key, RECENT_KEY_PACKET_LIST_SHOW) == 0) { |
||
979 | parse_recent_boolean(value, &recent.packet_list_show); |
||
980 | } else if (strcmp(key, RECENT_KEY_TREE_VIEW_SHOW) == 0) { |
||
981 | parse_recent_boolean(value, &recent.tree_view_show); |
||
982 | } else if (strcmp(key, RECENT_KEY_BYTE_VIEW_SHOW) == 0) { |
||
983 | parse_recent_boolean(value, &recent.byte_view_show); |
||
984 | } else if (strcmp(key, RECENT_KEY_STATUSBAR_SHOW) == 0) { |
||
985 | parse_recent_boolean(value, &recent.statusbar_show); |
||
986 | } else if (strcmp(key, RECENT_KEY_PACKET_LIST_COLORIZE) == 0) { |
||
987 | parse_recent_boolean(value, &recent.packet_list_colorize); |
||
988 | } else if (strcmp(key, RECENT_GUI_TIME_FORMAT) == 0) { |
||
989 | recent.gui_time_format = |
||
990 | (ts_type)str_to_val(value, ts_type_values, TS_RELATIVE); |
||
991 | } else if (strcmp(key, RECENT_GUI_TIME_PRECISION) == 0) { |
||
992 | recent.gui_time_precision = |
||
993 | (ts_precision)str_to_val(value, ts_precision_values, TS_PREC_AUTO); |
||
994 | } else if (strcmp(key, RECENT_GUI_SECONDS_FORMAT) == 0) { |
||
995 | recent.gui_seconds_format = |
||
996 | (ts_seconds_type)str_to_val(value, ts_seconds_values, TS_SECONDS_DEFAULT); |
||
997 | } else if (strcmp(key, RECENT_GUI_ZOOM_LEVEL) == 0) { |
||
998 | num = strtol(value, &p, 0); |
||
999 | if (p == value || *p != '\0') |
||
1000 | return PREFS_SET_SYNTAX_ERR; /* number was bad */ |
||
1001 | recent.gui_zoom_level = (gint)num; |
||
1002 | } else if (strcmp(key, RECENT_GUI_BYTES_VIEW) == 0) { |
||
1003 | num = strtol(value, &p, 0); |
||
1004 | if (p == value || *p != '\0') |
||
1005 | return PREFS_SET_SYNTAX_ERR; /* number was bad */ |
||
1006 | recent.gui_bytes_view = (bytes_view_type)num; |
||
1007 | } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED) == 0) { |
||
1008 | parse_recent_boolean(value, &recent.gui_geometry_main_maximized); |
||
1009 | } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE) == 0) { |
||
1010 | num = strtol(value, &p, 0); |
||
1011 | if (p == value || *p != '\0') |
||
1012 | return PREFS_SET_SYNTAX_ERR; /* number was bad */ |
||
1013 | if (num <= 0) |
||
1014 | return PREFS_SET_SYNTAX_ERR; /* number must be positive */ |
||
1015 | recent.gui_geometry_main_upper_pane = (gint)num; |
||
1016 | recent.has_gui_geometry_main_upper_pane = TRUE; |
||
1017 | } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE) == 0) { |
||
1018 | num = strtol(value, &p, 0); |
||
1019 | if (p == value || *p != '\0') |
||
1020 | return PREFS_SET_SYNTAX_ERR; /* number was bad */ |
||
1021 | if (num <= 0) |
||
1022 | return PREFS_SET_SYNTAX_ERR; /* number must be positive */ |
||
1023 | recent.gui_geometry_main_lower_pane = (gint)num; |
||
1024 | recent.has_gui_geometry_main_lower_pane = TRUE; |
||
1025 | } else if (strcmp(key, RECENT_GUI_CONVERSATION_TABS) == 0) { |
||
1026 | recent.conversation_tabs = prefs_get_string_list(value); |
||
1027 | } else if (strcmp(key, RECENT_GUI_ENDPOINT_TABS) == 0) { |
||
1028 | recent.endpoint_tabs = prefs_get_string_list(value); |
||
1029 | } else if (strcmp(key, RECENT_GUI_RLC_PDUS_FROM_MAC_FRAMES) == 0) { |
||
1030 | parse_recent_boolean(value, &recent.gui_rlc_use_pdus_from_mac); |
||
1031 | } else if (strcmp(key, RECENT_KEY_COL_WIDTH) == 0) { |
||
1032 | col_l = prefs_get_string_list(value); |
||
1033 | if (col_l == NULL) |
||
1034 | return PREFS_SET_SYNTAX_ERR; |
||
1035 | if ((g_list_length(col_l) % 2) != 0) { |
||
1036 | /* A title didn't have a matching width. */ |
||
1037 | prefs_clear_string_list(col_l); |
||
1038 | return PREFS_SET_SYNTAX_ERR; |
||
1039 | } |
||
1040 | /* Check to make sure all column formats are valid. */ |
||
1041 | col_l_elt = g_list_first(col_l); |
||
1042 | while (col_l_elt) { |
||
1043 | /* Make sure the format isn't empty. */ |
||
1044 | if (strcmp((const char *)col_l_elt->data, "") == 0) { |
||
1045 | /* It is. */ |
||
1046 | prefs_clear_string_list(col_l); |
||
1047 | return PREFS_SET_SYNTAX_ERR; |
||
1048 | } |
||
1049 | |||
1050 | /* Check the format. */ |
||
1051 | if (strncmp((const char *)col_l_elt->data, cust_format, cust_format_len) != 0) { |
||
1052 | if (get_column_format_from_str((const gchar *)col_l_elt->data) == -1) { |
||
1053 | /* It's not a valid column format. */ |
||
1054 | prefs_clear_string_list(col_l); |
||
1055 | return PREFS_SET_SYNTAX_ERR; |
||
1056 | } |
||
1057 | } |
||
1058 | |||
1059 | /* Go past the format. */ |
||
1060 | col_l_elt = col_l_elt->next; |
||
1061 | |||
1062 | /* Go past the width. */ |
||
1063 | col_l_elt = col_l_elt->next; |
||
1064 | } |
||
1065 | free_col_width_info(&recent); |
||
1066 | recent.col_width_list = NULL; |
||
1067 | col_l_elt = g_list_first(col_l); |
||
1068 | while (col_l_elt) { |
||
1069 | gchar *fmt = g_strdup((const gchar *)col_l_elt->data); |
||
1070 | cfmt = (col_width_data *) g_malloc(sizeof(col_width_data)); |
||
1071 | if (strncmp(fmt, cust_format, cust_format_len) != 0) { |
||
1072 | cfmt->cfmt = get_column_format_from_str(fmt); |
||
1073 | cfmt->cfield = NULL; |
||
1074 | } else { |
||
1075 | cfmt->cfmt = COL_CUSTOM; |
||
1076 | cfmt->cfield = g_strdup(&fmt[cust_format_len+1]); /* add 1 for ':' */ |
||
1077 | } |
||
1078 | g_free (fmt); |
||
1079 | if (cfmt->cfmt == -1) { |
||
1080 | g_free(cfmt->cfield); |
||
1081 | g_free(cfmt); |
||
1082 | return PREFS_SET_SYNTAX_ERR; /* string was bad */ |
||
1083 | } |
||
1084 | |||
1085 | col_l_elt = col_l_elt->next; |
||
1086 | cfmt->width = (gint)strtol((const char *)col_l_elt->data, &p, 0); |
||
1087 | if (p == col_l_elt->data || (*p != '\0' && *p != ':')) { |
||
1088 | g_free(cfmt->cfield); |
||
1089 | g_free(cfmt); |
||
1090 | return PREFS_SET_SYNTAX_ERR; /* number was bad */ |
||
1091 | } |
||
1092 | |||
1093 | if (*p == ':') { |
||
1094 | cfmt->xalign = *(++p); |
||
1095 | } else { |
||
1096 | cfmt->xalign = COLUMN_XALIGN_DEFAULT; |
||
1097 | } |
||
1098 | |||
1099 | col_l_elt = col_l_elt->next; |
||
1100 | recent.col_width_list = g_list_append(recent.col_width_list, cfmt); |
||
1101 | } |
||
1102 | prefs_clear_string_list(col_l); |
||
1103 | } else if (strcmp(key, RECENT_GUI_FILEOPEN_REMEMBERED_DIR) == 0) { |
||
1104 | if (recent.gui_fileopen_remembered_dir) { |
||
1105 | g_free (recent.gui_fileopen_remembered_dir); |
||
1106 | } |
||
1107 | recent.gui_fileopen_remembered_dir = g_strdup(value); |
||
1108 | } |
||
1109 | |||
1110 | return PREFS_SET_OK; |
||
1111 | } |
||
1112 | |||
1113 | |||
1114 | /* set one user's recent file key/value pair */ |
||
1115 | static prefs_set_pref_e |
||
1116 | read_set_recent_pair_dynamic(gchar *key, const gchar *value, |
||
1117 | void *private_data _U_, |
||
1118 | gboolean return_range_errors _U_) |
||
1119 | { |
||
1120 | if (!g_utf8_validate(value, -1, NULL)) { |
||
1121 | return PREFS_SET_SYNTAX_ERR; |
||
1122 | } |
||
1123 | if (strcmp(key, RECENT_KEY_CAPTURE_FILE) == 0) { |
||
1124 | add_menu_recent_capture_file(value); |
||
1125 | } else if (strcmp(key, RECENT_KEY_DISPLAY_FILTER) == 0) { |
||
1126 | dfilter_combo_add_recent(value); |
||
1127 | } else if (strcmp(key, RECENT_KEY_CAPTURE_FILTER) == 0) { |
||
1128 | recent_add_cfilter(NULL, value); |
||
1129 | } else if (g_str_has_prefix(key, RECENT_KEY_CAPTURE_FILTER ".")) { |
||
1130 | /* strrchr() can't fail - string has a prefix that ends with a "." */ |
||
1131 | recent_add_cfilter(strrchr(key, '.') + 1, value); |
||
1132 | #ifdef HAVE_PCAP_REMOTE |
||
1133 | } else if (strcmp(key, RECENT_KEY_REMOTE_HOST) == 0) { |
||
1134 | capture_remote_combo_add_recent(value); |
||
1135 | #endif |
||
1136 | } |
||
1137 | |||
1138 | return PREFS_SET_OK; |
||
1139 | } |
||
1140 | |||
1141 | |||
1142 | /* |
||
1143 | * Given a string of the form "<recent name>:<recent value>", as might appear |
||
1144 | * as an argument to a "-o" option, parse it and set the recent value in |
||
1145 | * question. Return an indication of whether it succeeded or failed |
||
1146 | * in some fashion. |
||
1147 | */ |
||
1148 | int |
||
1149 | recent_set_arg(char *prefarg) |
||
1150 | { |
||
1151 | gchar *p, *colonp; |
||
1152 | int ret; |
||
1153 | |||
1154 | colonp = strchr(prefarg, ':'); |
||
1155 | if (colonp == NULL) |
||
1156 | return PREFS_SET_SYNTAX_ERR; |
||
1157 | |||
1158 | p = colonp; |
||
1159 | *p++ = '\0'; |
||
1160 | |||
1161 | /* |
||
1162 | * Skip over any white space (there probably won't be any, but |
||
1163 | * as we allow it in the preferences file, we might as well |
||
1164 | * allow it here). |
||
1165 | */ |
||
1166 | while (g_ascii_isspace(*p)) |
||
1167 | p++; |
||
1168 | if (*p == '\0') { |
||
1169 | /* |
||
1170 | * Put the colon back, so if our caller uses, in an |
||
1171 | * error message, the string they passed us, the message |
||
1172 | * looks correct. |
||
1173 | */ |
||
1174 | *colonp = ':'; |
||
1175 | return PREFS_SET_SYNTAX_ERR; |
||
1176 | } |
||
1177 | |||
1178 | ret = read_set_recent_pair_static(prefarg, p, NULL, TRUE); |
||
1179 | *colonp = ':'; /* put the colon back */ |
||
1180 | return ret; |
||
1181 | } |
||
1182 | |||
1183 | |||
1184 | /* opens the user's recent common file and read the first part */ |
||
1185 | gboolean |
||
1186 | recent_read_static(char **rf_path_return, int *rf_errno_return) |
||
1187 | { |
||
1188 | char *rf_path; |
||
1189 | FILE *rf; |
||
1190 | |||
1191 | /* set defaults */ |
||
1192 | recent.gui_geometry_main_x = 20; |
||
1193 | recent.gui_geometry_main_y = 20; |
||
1194 | recent.gui_gtk_geometry_main_x = 20; |
||
1195 | recent.gui_gtk_geometry_main_y = 20; |
||
1196 | recent.gui_geometry_main_width = DEF_WIDTH; |
||
1197 | recent.gui_geometry_main_height = DEF_HEIGHT; |
||
1198 | recent.gui_geometry_main_maximized= FALSE; |
||
1199 | |||
1200 | recent.gui_geometry_status_pane_left = (DEF_WIDTH/3); |
||
1201 | recent.gui_geometry_status_pane_right = (DEF_WIDTH/3); |
||
1202 | recent.gui_geometry_wlan_stats_pane = 200; |
||
1203 | |||
1204 | recent.privs_warn_if_elevated = TRUE; |
||
1205 | recent.privs_warn_if_no_npf = TRUE; |
||
1206 | |||
1207 | recent.col_width_list = NULL; |
||
1208 | recent.gui_fileopen_remembered_dir = NULL; |
||
1209 | |||
1210 | /* Construct the pathname of the user's recent common file. */ |
||
1211 | rf_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE); |
||
1212 | |||
1213 | /* Read the user's recent common file, if it exists. */ |
||
1214 | *rf_path_return = NULL; |
||
1215 | if ((rf = ws_fopen(rf_path, "r")) != NULL) { |
||
1216 | /* We succeeded in opening it; read it. */ |
||
1217 | read_prefs_file(rf_path, rf, read_set_recent_common_pair_static, NULL); |
||
1218 | |||
1219 | fclose(rf); |
||
1220 | } else { |
||
1221 | /* We failed to open it. If we failed for some reason other than |
||
1222 | "it doesn't exist", return the errno and the pathname, so our |
||
1223 | caller can report the error. */ |
||
1224 | if (errno != ENOENT) { |
||
1225 | *rf_errno_return = errno; |
||
1226 | *rf_path_return = rf_path; |
||
1227 | return FALSE; |
||
1228 | } |
||
1229 | } |
||
1230 | g_free(rf_path); |
||
1231 | return TRUE; |
||
1232 | } |
||
1233 | |||
1234 | |||
1235 | |||
1236 | /* opens the user's recent file and read the first part */ |
||
1237 | gboolean |
||
1238 | recent_read_profile_static(char **rf_path_return, int *rf_errno_return) |
||
1239 | { |
||
1240 | char *rf_path, *rf_common_path; |
||
1241 | FILE *rf; |
||
1242 | |||
1243 | /* set defaults */ |
||
1244 | recent.main_toolbar_show = TRUE; |
||
1245 | recent.filter_toolbar_show = TRUE; |
||
1246 | recent.wireless_toolbar_show = FALSE; |
||
1247 | recent.airpcap_driver_check_show = TRUE; |
||
1248 | recent.packet_list_show = TRUE; |
||
1249 | recent.tree_view_show = TRUE; |
||
1250 | recent.byte_view_show = TRUE; |
||
1251 | recent.statusbar_show = TRUE; |
||
1252 | recent.packet_list_colorize = TRUE; |
||
1253 | recent.gui_time_format = TS_RELATIVE; |
||
1254 | recent.gui_time_precision = TS_PREC_AUTO; |
||
1255 | recent.gui_seconds_format = TS_SECONDS_DEFAULT; |
||
1256 | recent.gui_zoom_level = 0; |
||
1257 | recent.gui_bytes_view = BYTES_HEX; |
||
1258 | |||
1259 | /* pane size of zero will autodetect */ |
||
1260 | recent.gui_geometry_main_upper_pane = 0; |
||
1261 | recent.gui_geometry_main_lower_pane = 0; |
||
1262 | |||
1263 | recent.has_gui_geometry_main_upper_pane = TRUE; |
||
1264 | recent.has_gui_geometry_main_lower_pane = TRUE; |
||
1265 | recent.has_gui_geometry_status_pane = TRUE; |
||
1266 | |||
1267 | if (recent.col_width_list) { |
||
1268 | free_col_width_info(&recent); |
||
1269 | } |
||
1270 | |||
1271 | if (recent.gui_fileopen_remembered_dir) { |
||
1272 | g_free (recent.gui_fileopen_remembered_dir); |
||
1273 | recent.gui_fileopen_remembered_dir = NULL; |
||
1274 | } |
||
1275 | |||
1276 | /* Construct the pathname of the user's profile recent file. */ |
||
1277 | rf_path = get_persconffile_path(RECENT_FILE_NAME, TRUE); |
||
1278 | |||
1279 | /* Read the user's recent file, if it exists. */ |
||
1280 | *rf_path_return = NULL; |
||
1281 | if ((rf = ws_fopen(rf_path, "r")) != NULL) { |
||
1282 | /* We succeeded in opening it; read it. */ |
||
1283 | read_prefs_file(rf_path, rf, read_set_recent_pair_static, NULL); |
||
1284 | fclose(rf); |
||
1285 | |||
1286 | /* XXX: The following code doesn't actually do anything since |
||
1287 | * the "recent common file" always exists. Presumably the |
||
1288 | * "if (!file_exists())" should actually be "if (file_exists())". |
||
1289 | * However, I've left the code as is because this |
||
1290 | * behaviour has existed for quite some time and I don't |
||
1291 | * know what's supposed to happen at this point. |
||
1292 | * ToDo: Determine if the "recent common file" should be read at this point |
||
1293 | */ |
||
1294 | rf_common_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE); |
||
1295 | if (!file_exists(rf_common_path)) { |
||
1296 | /* Read older common settings from recent file */ |
||
1297 | rf = ws_fopen(rf_path, "r"); |
||
1298 | read_prefs_file(rf_path, rf, read_set_recent_common_pair_static, NULL); |
||
1299 | fclose(rf); |
||
1300 | } |
||
1301 | g_free(rf_common_path); |
||
1302 | } else { |
||
1303 | /* We failed to open it. If we failed for some reason other than |
||
1304 | "it doesn't exist", return the errno and the pathname, so our |
||
1305 | caller can report the error. */ |
||
1306 | if (errno != ENOENT) { |
||
1307 | *rf_errno_return = errno; |
||
1308 | *rf_path_return = rf_path; |
||
1309 | return FALSE; |
||
1310 | } |
||
1311 | } |
||
1312 | g_free(rf_path); |
||
1313 | return TRUE; |
||
1314 | } |
||
1315 | |||
1316 | /* opens the user's recent file and read it out */ |
||
1317 | gboolean |
||
1318 | recent_read_dynamic(char **rf_path_return, int *rf_errno_return) |
||
1319 | { |
||
1320 | char *rf_path; |
||
1321 | FILE *rf; |
||
1322 | |||
1323 | |||
1324 | /* Construct the pathname of the user's recent common file. */ |
||
1325 | rf_path = get_persconffile_path(RECENT_COMMON_FILE_NAME, FALSE); |
||
1326 | if (!file_exists (rf_path)) { |
||
1327 | /* Recent common file does not exist, read from default recent */ |
||
1328 | g_free (rf_path); |
||
1329 | rf_path = get_persconffile_path(RECENT_FILE_NAME, FALSE); |
||
1330 | } |
||
1331 | |||
1332 | /* Read the user's recent file, if it exists. */ |
||
1333 | *rf_path_return = NULL; |
||
1334 | if ((rf = ws_fopen(rf_path, "r")) != NULL) { |
||
1335 | /* We succeeded in opening it; read it. */ |
||
1336 | read_prefs_file(rf_path, rf, read_set_recent_pair_dynamic, NULL); |
||
1337 | #if 0 |
||
1338 | /* set dfilter combobox to have an empty line */ |
||
1339 | dfilter_combo_add_empty(); |
||
1340 | #endif |
||
1341 | fclose(rf); |
||
1342 | } else { |
||
1343 | /* We failed to open it. If we failed for some reason other than |
||
1344 | "it doesn't exist", return the errno and the pathname, so our |
||
1345 | caller can report the error. */ |
||
1346 | if (errno != ENOENT) { |
||
1347 | *rf_errno_return = errno; |
||
1348 | *rf_path_return = rf_path; |
||
1349 | return FALSE; |
||
1350 | } |
||
1351 | } |
||
1352 | g_free(rf_path); |
||
1353 | return TRUE; |
||
1354 | } |
||
1355 | |||
1356 | gint |
||
1357 | recent_get_column_width(gint col) |
||
1358 | { |
||
1359 | GList *col_l; |
||
1360 | col_width_data *col_w; |
||
1361 | gint cfmt; |
||
1362 | const gchar *cfield = NULL; |
||
1363 | |||
1364 | cfmt = get_column_format(col); |
||
1365 | if (cfmt == COL_CUSTOM) { |
||
1366 | cfield = get_column_custom_fields(col); |
||
1367 | } |
||
1368 | |||
1369 | col_l = g_list_first(recent.col_width_list); |
||
1370 | while (col_l) { |
||
1371 | col_w = (col_width_data *) col_l->data; |
||
1372 | if (col_w->cfmt == cfmt) { |
||
1373 | if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) { |
||
1374 | return col_w->width; |
||
1375 | } |
||
1376 | } |
||
1377 | col_l = col_l->next; |
||
1378 | } |
||
1379 | |||
1380 | return -1; |
||
1381 | } |
||
1382 | |||
1383 | void |
||
1384 | recent_set_column_width(gint col, gint width) |
||
1385 | { |
||
1386 | GList *col_l; |
||
1387 | col_width_data *col_w; |
||
1388 | gint cfmt; |
||
1389 | const gchar *cfield = NULL; |
||
1390 | gboolean found = FALSE; |
||
1391 | |||
1392 | cfmt = get_column_format(col); |
||
1393 | if (cfmt == COL_CUSTOM) { |
||
1394 | cfield = get_column_custom_fields(col); |
||
1395 | } |
||
1396 | |||
1397 | col_l = g_list_first(recent.col_width_list); |
||
1398 | while (col_l) { |
||
1399 | col_w = (col_width_data *) col_l->data; |
||
1400 | if (col_w->cfmt == cfmt) { |
||
1401 | if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) { |
||
1402 | col_w->width = width; |
||
1403 | found = TRUE; |
||
1404 | break; |
||
1405 | } |
||
1406 | } |
||
1407 | col_l = col_l->next; |
||
1408 | } |
||
1409 | |||
1410 | if (!found) { |
||
1411 | col_w = (col_width_data *) g_malloc(sizeof(col_width_data)); |
||
1412 | col_w->cfmt = cfmt; |
||
1413 | if (cfield) { |
||
1414 | col_w->cfield = g_strdup(cfield); |
||
1415 | } else { |
||
1416 | col_w->cfield = NULL; |
||
1417 | } |
||
1418 | col_w->width = width; |
||
1419 | col_w->xalign = COLUMN_XALIGN_DEFAULT; |
||
1420 | recent.col_width_list = g_list_append(recent.col_width_list, col_w); |
||
1421 | } |
||
1422 | } |
||
1423 | |||
1424 | gchar |
||
1425 | recent_get_column_xalign(gint col) |
||
1426 | { |
||
1427 | GList *col_l; |
||
1428 | col_width_data *col_w; |
||
1429 | gint cfmt; |
||
1430 | const gchar *cfield = NULL; |
||
1431 | |||
1432 | cfmt = get_column_format(col); |
||
1433 | if (cfmt == COL_CUSTOM) { |
||
1434 | cfield = get_column_custom_fields(col); |
||
1435 | } |
||
1436 | |||
1437 | col_l = g_list_first(recent.col_width_list); |
||
1438 | while (col_l) { |
||
1439 | col_w = (col_width_data *) col_l->data; |
||
1440 | if (col_w->cfmt == cfmt) { |
||
1441 | if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) { |
||
1442 | return col_w->xalign; |
||
1443 | } |
||
1444 | } |
||
1445 | col_l = col_l->next; |
||
1446 | } |
||
1447 | |||
1448 | return 0; |
||
1449 | } |
||
1450 | |||
1451 | void |
||
1452 | recent_set_column_xalign(gint col, gchar xalign) |
||
1453 | { |
||
1454 | GList *col_l; |
||
1455 | col_width_data *col_w; |
||
1456 | gint cfmt; |
||
1457 | const gchar *cfield = NULL; |
||
1458 | gboolean found = FALSE; |
||
1459 | |||
1460 | cfmt = get_column_format(col); |
||
1461 | if (cfmt == COL_CUSTOM) { |
||
1462 | cfield = get_column_custom_fields(col); |
||
1463 | } |
||
1464 | |||
1465 | col_l = g_list_first(recent.col_width_list); |
||
1466 | while (col_l) { |
||
1467 | col_w = (col_width_data *) col_l->data; |
||
1468 | if (col_w->cfmt == cfmt) { |
||
1469 | if (cfmt != COL_CUSTOM || strcmp (cfield, col_w->cfield) == 0) { |
||
1470 | col_w->xalign = xalign; |
||
1471 | found = TRUE; |
||
1472 | break; |
||
1473 | } |
||
1474 | } |
||
1475 | col_l = col_l->next; |
||
1476 | } |
||
1477 | |||
1478 | if (!found) { |
||
1479 | col_w = (col_width_data *) g_malloc(sizeof(col_width_data)); |
||
1480 | col_w->cfmt = cfmt; |
||
1481 | if (cfield) { |
||
1482 | col_w->cfield = g_strdup(cfield); |
||
1483 | } else { |
||
1484 | col_w->cfield = NULL; |
||
1485 | } |
||
1486 | col_w->width = 40; |
||
1487 | col_w->xalign = xalign; |
||
1488 | recent.col_width_list = g_list_append(recent.col_width_list, col_w); |
||
1489 | } |
||
1490 | } |
||
1491 | |||
1492 | /* |
||
1493 | * Editor modelines - http://www.wireshark.org/tools/modelines.html |
||
1494 | * |
||
1495 | * Local Variables: |
||
1496 | * c-basic-offset: 2 |
||
1497 | * tab-width: 8 |
||
1498 | * indent-tabs-mode: nil |
||
1499 | * End: |
||
1500 | * |
||
1501 | * ex: set shiftwidth=2 tabstop=8 expandtab: |
||
1502 | * :indentSize=2:tabSize=8:noTabs=true: |
||
1503 | */ |