913812094d81b20f7e9c66bd212608ab1ac4a596
[obnox/wireshark/wip.git] / gtk / recent.c
1 /* recent.c
2  * Recent "preference" handling routines
3  * Copyright 2004, Ulf Lamping <ulf.lamping@web.de>
4  *
5  * $Id$
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <gtk/gtk.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <ctype.h>
34
35 #include "recent.h"
36 #include <epan/epan.h>
37 #include <epan/filesystem.h>
38 #include "menu.h"
39 #include "main.h"
40 #include <epan/prefs.h>
41 #include <epan/prefs-int.h>
42 #include "gui_utils.h"
43 #if 0
44 #include "dlg_utils.h"
45 #endif
46 #include "file_dlg.h"
47 #include "cfilter_combo_utils.h"
48 #include "simple_dialog.h"
49 #include "file_util.h"
50 #include "u3.h"
51
52 #ifdef NEED_G_ASCII_STRCASECMP_H
53 #include "../epan/g_ascii_strcasecmp.h"
54 #endif
55
56 #define RECENT_KEY_MAIN_TOOLBAR_SHOW        "gui.toolbar_main_show"
57 #define RECENT_KEY_FILTER_TOOLBAR_SHOW      "gui.filter_toolbar_show"
58 #define RECENT_KEY_AIRPCAP_TOOLBAR_SHOW     "gui.airpcap_toolbar_show"
59 #define RECENT_KEY_DRIVER_CHECK_SHOW        "gui.airpcap_driver_check_show"
60 #define RECENT_KEY_PACKET_LIST_SHOW         "gui.packet_list_show"
61 #define RECENT_KEY_TREE_VIEW_SHOW           "gui.tree_view_show"
62 #define RECENT_KEY_BYTE_VIEW_SHOW           "gui.byte_view_show"
63 #define RECENT_KEY_STATUSBAR_SHOW           "gui.statusbar_show"
64 #define RECENT_KEY_PACKET_LIST_COLORIZE     "gui.packet_list_colorize"
65 #define RECENT_GUI_TIME_FORMAT              "gui.time_format"
66 #define RECENT_GUI_TIME_PRECISION           "gui.time_precision"
67 #define RECENT_GUI_ZOOM_LEVEL               "gui.zoom_level"
68 #define RECENT_GUI_GEOMETRY_MAIN_X          "gui.geometry_main_x"
69 #define RECENT_GUI_GEOMETRY_MAIN_Y          "gui.geometry_main_y"
70 #define RECENT_GUI_GEOMETRY_MAIN_WIDTH      "gui.geometry_main_width"
71 #define RECENT_GUI_GEOMETRY_MAIN_HEIGHT     "gui.geometry_main_height"
72 #define RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED  "gui.geometry_main_maximized"
73 #define RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE "gui.geometry_main_upper_pane"
74 #define RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE "gui.geometry_main_lower_pane"
75 #define RECENT_GUI_GEOMETRY_STATUS_PANE     "gui.geometry_status_pane"
76 #define RECENT_GUI_FILEOPEN_REMEMBERED_DIR  "gui.fileopen_remembered_dir"
77 #define RECENT_GUI_GEOMETRY                 "gui.geom."
78 #define RECENT_KEY_PRIVS_WARN_IF_ELEVATED   "privs.warn_if_elevated"
79 #define RECENT_KEY_PRIVS_WARN_IF_NO_NPF     "privs.warn_if_no_npf"
80
81 #define RECENT_FILE_NAME "recent"
82
83 recent_settings_t recent;
84
85 static const char *ts_type_text[] =
86         { "RELATIVE", "ABSOLUTE", "ABSOLUTE_WITH_DATE", "DELTA", "EPOCH", NULL };
87
88 static const char *ts_precision_text[] =
89         { "AUTO", "SEC", "DSEC", "CSEC", "MSEC", "USEC", "NSEC", NULL };
90
91 /* Takes an string and a pointer to an array of strings, and a default int value.
92  * The array must be terminated by a NULL string. If the string is found in the array
93  * of strings, the index of that string in the array is returned. Otherwise, the
94  * default value that was passed as the third argument is returned.
95  */
96 static int
97 find_index_from_string_array(const char *needle, const char **haystack, int default_value)
98 {
99         int i = 0;
100
101         while (haystack[i] != NULL) {
102                 if (strcmp(needle, haystack[i]) == 0) {
103                         return i;
104                 }
105                 i++;
106         }
107         return default_value;
108 }
109
110 /* Attempt to Write out "recent" to the user's recent file.
111    If we got an error report it with a dialog box and return FALSE,
112    otherwise return TRUE. */
113 gboolean
114 write_recent(void)
115 {
116   char        *pf_dir_path;
117   char        *rf_path;
118   FILE        *rf;
119
120   /* To do:
121    * - Split output lines longer than MAX_VAL_LEN
122    * - Create a function for the preference directory check/creation
123    *   so that duplication can be avoided with filter.c
124    */
125
126   /* Create the directory that holds personal configuration files, if
127      necessary.  */
128   if (create_persconffile_dir(&pf_dir_path) == -1) {
129      simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
130       "Can't create directory\n\"%s\"\nfor recent file: %s.", pf_dir_path,
131       strerror(errno));
132      g_free(pf_dir_path);
133      return FALSE;
134   }
135
136   rf_path = get_persconffile_path(RECENT_FILE_NAME, TRUE);
137   if ((rf = eth_fopen(rf_path, "w")) == NULL) {
138      simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
139       "Can't open recent file\n\"%s\": %s.", rf_path,
140       strerror(errno));
141     g_free(rf_path);
142     return FALSE;
143   }
144
145   fputs("# Recent settings file for Wireshark " VERSION ".\n"
146     "#\n"
147     "# This file is regenerated each time Wireshark is quit.\n"
148     "# So be careful, if you want to make manual changes here.\n"
149     "\n"
150     "######## Recent capture files (latest last), cannot be altered through command line ########\n"
151     "\n", rf);
152
153   menu_recent_file_write_all(rf);
154
155   fputs("\n"
156     "######## Recent capture filters (latest last), cannot be altered through command line ########\n"
157     "\n", rf);
158
159   cfilter_combo_recent_write_all(rf);
160
161   fputs("\n"
162     "######## Recent display filters (latest last), cannot be altered through command line ########\n"
163     "\n", rf);
164
165   dfilter_recent_combo_write_all(rf);
166
167   fprintf(rf, "\n# Main Toolbar show (hide).\n");
168   fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
169   fprintf(rf, RECENT_KEY_MAIN_TOOLBAR_SHOW ": %s\n",
170                   recent.main_toolbar_show == TRUE ? "TRUE" : "FALSE");
171
172   fprintf(rf, "\n# Filter Toolbar show (hide).\n");
173   fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
174   fprintf(rf, RECENT_KEY_FILTER_TOOLBAR_SHOW ": %s\n",
175                   recent.filter_toolbar_show == TRUE ? "TRUE" : "FALSE");
176
177 #ifdef HAVE_AIRPCAP
178   fprintf(rf, "\n# Wireless Settings Toolbar show (hide).\n");
179   fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
180   fprintf(rf, RECENT_KEY_AIRPCAP_TOOLBAR_SHOW ": %s\n",
181                   recent.airpcap_toolbar_show == TRUE ? "TRUE" : "FALSE");
182 #endif
183
184 #ifdef HAVE_AIRPCAP
185   fprintf(rf, "\n# Show (hide) old AirPcap driver warning dialog box.\n");
186   fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
187   fprintf(rf, RECENT_KEY_DRIVER_CHECK_SHOW ": %s\n",
188                   recent.airpcap_driver_check_show == TRUE ? "TRUE" : "FALSE");
189 #endif
190
191   fprintf(rf, "\n# Packet list show (hide).\n");
192   fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
193   fprintf(rf, RECENT_KEY_PACKET_LIST_SHOW ": %s\n",
194                   recent.packet_list_show == TRUE ? "TRUE" : "FALSE");
195
196   fprintf(rf, "\n# Tree view show (hide).\n");
197   fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
198   fprintf(rf, RECENT_KEY_TREE_VIEW_SHOW ": %s\n",
199                   recent.tree_view_show == TRUE ? "TRUE" : "FALSE");
200
201   fprintf(rf, "\n# Byte view show (hide).\n");
202   fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
203   fprintf(rf, RECENT_KEY_BYTE_VIEW_SHOW ": %s\n",
204                   recent.byte_view_show == TRUE ? "TRUE" : "FALSE");
205
206   fprintf(rf, "\n# Statusbar show (hide).\n");
207   fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
208   fprintf(rf, RECENT_KEY_STATUSBAR_SHOW ": %s\n",
209                   recent.statusbar_show == TRUE ? "TRUE" : "FALSE");
210
211   fprintf(rf, "\n# Packet list colorize (hide).\n");
212   fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
213   fprintf(rf, RECENT_KEY_PACKET_LIST_COLORIZE ": %s\n",
214                   recent.packet_list_colorize == TRUE ? "TRUE" : "FALSE");
215
216   fprintf(rf, "\n# Timestamp display format.\n");
217   fprintf(rf, "# One of: RELATIVE, ABSOLUTE, ABSOLUTE_WITH_DATE, DELTA, EPOCH\n");
218   fprintf(rf, RECENT_GUI_TIME_FORMAT ": %s\n",
219           ts_type_text[recent.gui_time_format]);
220
221   fprintf(rf, "\n# Timestamp display precision.\n");
222   fprintf(rf, "# One of: AUTO, SEC, DSEC, CSEC, MSEC, USEC, NSEC\n");
223   fprintf(rf, RECENT_GUI_TIME_PRECISION ": %s\n",
224           ts_precision_text[recent.gui_time_precision]);
225
226   fprintf(rf, "\n# Zoom level.\n");
227   fprintf(rf, "# A decimal number.\n");
228   fprintf(rf, RECENT_GUI_ZOOM_LEVEL ": %d\n",
229                   recent.gui_zoom_level);
230
231   fprintf(rf, "\n# Main window geometry.\n");
232   fprintf(rf, "# Decimal numbers.\n");
233   fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_X ": %d\n", recent.gui_geometry_main_x);
234   fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_Y ": %d\n", recent.gui_geometry_main_y);
235   fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_WIDTH ": %d\n",
236                   recent.gui_geometry_main_width);
237   fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_HEIGHT ": %d\n",
238                   recent.gui_geometry_main_height);
239
240   fprintf(rf, "\n# Main window maximized (GTK2 only!).\n");
241   fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
242   fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED ": %s\n",
243                   recent.gui_geometry_main_maximized == TRUE ? "TRUE" : "FALSE");
244
245   fprintf(rf, "\n# Main window upper (or leftmost) pane size.\n");
246   fprintf(rf, "# (GTK1: has no effect here, command line -o usage only).\n");
247   fprintf(rf, "# Decimal number.\n");
248   if (recent.gui_geometry_main_upper_pane != 0) {
249     fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE ": %d\n",
250                   recent.gui_geometry_main_upper_pane);
251   }
252   fprintf(rf, "\n# Main window middle pane size.\n");
253   fprintf(rf, "# (GTK1: has no effect here, command line -o usage only).\n");
254   fprintf(rf, "# Decimal number.\n");
255   if (recent.gui_geometry_main_lower_pane != 0) {
256     fprintf(rf, RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE ": %d\n",
257                   recent.gui_geometry_main_lower_pane);
258   }
259   fprintf(rf, "\n# Statusbar left pane size.\n");
260   fprintf(rf, "# (GTK1: has no effect here, command line -o usage only).\n");
261   fprintf(rf, "# Decimal number.\n");
262   if (recent.gui_geometry_status_pane != 0) {
263     fprintf(rf, RECENT_GUI_GEOMETRY_STATUS_PANE ": %d\n",
264                   recent.gui_geometry_status_pane);
265   }
266
267   fprintf(rf, "\n# Warn if running with elevated permissions (e.g. as root).\n");
268   fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
269   fprintf(rf, RECENT_KEY_PRIVS_WARN_IF_ELEVATED ": %s\n",
270                   recent.privs_warn_if_elevated == TRUE ? "TRUE" : "FALSE");
271
272   fprintf(rf, "\n# Warn if npf.sys isn't loaded on Windows >= 6.0.\n");
273   fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
274   fprintf(rf, RECENT_KEY_PRIVS_WARN_IF_NO_NPF ": %s\n",
275                   recent.privs_warn_if_no_npf == TRUE ? "TRUE" : "FALSE");
276
277   if (get_last_open_dir() != NULL) {
278     fprintf(rf, "\n# Last directory navigated to in File Open dialog.\n");
279
280     if(u3_active())
281       fprintf(rf, RECENT_GUI_FILEOPEN_REMEMBERED_DIR ": %s\n", u3_contract_device_path(get_last_open_dir()));
282     else
283       fprintf(rf, RECENT_GUI_FILEOPEN_REMEMBERED_DIR ": %s\n", get_last_open_dir());
284   }
285
286   window_geom_recent_write_all(rf);
287
288   fclose(rf);
289
290   /* XXX - catch I/O errors (e.g. "ran out of disk space") and return
291      an error indication, or maybe write to a new recent file and
292      rename that file on top of the old one only if there are not I/O
293      errors. */
294   return TRUE;
295 }
296
297
298 /* write the geometry values of a window to recent file */
299 void
300 write_recent_geom(gpointer key _U_, gpointer value, gpointer rf)
301 {
302     window_geometry_t *geom = value;
303
304     fprintf(rf, "\n# Geometry and maximized state (GTK2 only) of %s window.\n", geom->key);
305     fprintf(rf, "# Decimal integers.\n");
306     fprintf(rf, RECENT_GUI_GEOMETRY "%s.x: %d\n", geom->key, geom->x);
307     fprintf(rf, RECENT_GUI_GEOMETRY "%s.y: %d\n", geom->key, geom->y);
308     fprintf(rf, RECENT_GUI_GEOMETRY "%s.width: %d\n", geom->key,
309               geom->width);
310     fprintf(rf, RECENT_GUI_GEOMETRY "%s.height: %d\n", geom->key,
311               geom->height);
312
313     fprintf(rf, "# TRUE or FALSE (case-insensitive).\n");
314     fprintf(rf, RECENT_GUI_GEOMETRY "%s.maximized: %s\n", geom->key,
315               geom->maximized == TRUE ? "TRUE" : "FALSE");
316
317 }
318
319
320 /* set one user's recent file key/value pair */
321 static prefs_set_pref_e
322 read_set_recent_pair_static(gchar *key, gchar *value, void *private_data _U_)
323 {
324   long num;
325   char *p;
326
327   if (strcmp(key, RECENT_KEY_MAIN_TOOLBAR_SHOW) == 0) {
328     if (g_ascii_strcasecmp(value, "true") == 0) {
329         recent.main_toolbar_show = TRUE;
330     }
331     else {
332         recent.main_toolbar_show = FALSE;
333     }
334   } else if (strcmp(key, RECENT_KEY_FILTER_TOOLBAR_SHOW) == 0) {
335     if (g_ascii_strcasecmp(value, "true") == 0) {
336         recent.filter_toolbar_show = TRUE;
337     }
338     else {
339         recent.filter_toolbar_show = FALSE;
340     }
341   } else if (strcmp(key, RECENT_KEY_AIRPCAP_TOOLBAR_SHOW) == 0) {
342     if (g_ascii_strcasecmp(value, "true") == 0) {
343         recent.airpcap_toolbar_show = TRUE;
344     }
345     else {
346         recent.airpcap_toolbar_show = FALSE;
347     }
348   } else if (strcmp(key, RECENT_KEY_DRIVER_CHECK_SHOW) == 0) {
349     if (g_ascii_strcasecmp(value, "true") == 0) {
350         recent.airpcap_driver_check_show = TRUE;
351     }
352     else {
353         recent.airpcap_driver_check_show = FALSE;
354     }
355   }else if (strcmp(key, RECENT_KEY_PACKET_LIST_SHOW) == 0) {
356     if (g_ascii_strcasecmp(value, "true") == 0) {
357         recent.packet_list_show = TRUE;
358     }
359     else {
360         recent.packet_list_show = FALSE;
361     }
362   } else if (strcmp(key, RECENT_KEY_TREE_VIEW_SHOW) == 0) {
363     if (g_ascii_strcasecmp(value, "true") == 0) {
364         recent.tree_view_show = TRUE;
365     }
366     else {
367         recent.tree_view_show = FALSE;
368     }
369   } else if (strcmp(key, RECENT_KEY_BYTE_VIEW_SHOW) == 0) {
370     if (g_ascii_strcasecmp(value, "true") == 0) {
371         recent.byte_view_show = TRUE;
372     }
373     else {
374         recent.byte_view_show = FALSE;
375     }
376   } else if (strcmp(key, RECENT_KEY_STATUSBAR_SHOW) == 0) {
377     if (g_ascii_strcasecmp(value, "true") == 0) {
378         recent.statusbar_show = TRUE;
379     }
380     else {
381         recent.statusbar_show = FALSE;
382     }
383   } else if (strcmp(key, RECENT_KEY_PACKET_LIST_COLORIZE) == 0) {
384     if (g_ascii_strcasecmp(value, "true") == 0) {
385         recent.packet_list_colorize = TRUE;
386     }
387     else {
388         recent.packet_list_colorize = FALSE;
389     }
390   } else if (strcmp(key, RECENT_GUI_TIME_FORMAT) == 0) {
391     recent.gui_time_format =
392         find_index_from_string_array(value, ts_type_text, TS_RELATIVE);
393   } else if (strcmp(key, RECENT_GUI_TIME_PRECISION) == 0) {
394     recent.gui_time_precision =
395         find_index_from_string_array(value, ts_precision_text, TS_PREC_AUTO);
396   } else if (strcmp(key, RECENT_GUI_ZOOM_LEVEL) == 0) {
397     num = strtol(value, &p, 0);
398     if (p == value || *p != '\0')
399       return PREFS_SET_SYNTAX_ERR;      /* number was bad */
400     recent.gui_zoom_level = num;
401   } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_MAXIMIZED) == 0) {
402     if (g_ascii_strcasecmp(value, "true") == 0) {
403         recent.gui_geometry_main_maximized = TRUE;
404     }
405     else {
406         recent.gui_geometry_main_maximized = FALSE;
407     }
408
409   } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_X) == 0) {
410     num = strtol(value, &p, 0);
411     if (p == value || *p != '\0')
412       return PREFS_SET_SYNTAX_ERR;      /* number was bad */
413     recent.gui_geometry_main_x = num;
414   } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_Y) == 0) {
415     num = strtol(value, &p, 0);
416     if (p == value || *p != '\0')
417       return PREFS_SET_SYNTAX_ERR;      /* number was bad */
418     recent.gui_geometry_main_y = num;
419   } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_WIDTH) == 0) {
420     num = strtol(value, &p, 0);
421     if (p == value || *p != '\0')
422       return PREFS_SET_SYNTAX_ERR;      /* number was bad */
423     if (num <= 0)
424       return PREFS_SET_SYNTAX_ERR;      /* number must be positive */
425     recent.gui_geometry_main_width = num;
426   } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_HEIGHT) == 0) {
427     num = strtol(value, &p, 0);
428     if (p == value || *p != '\0')
429       return PREFS_SET_SYNTAX_ERR;      /* number was bad */
430     if (num <= 0)
431       return PREFS_SET_SYNTAX_ERR;      /* number must be positive */
432     recent.gui_geometry_main_height = num;
433   } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_UPPER_PANE) == 0) {
434     num = strtol(value, &p, 0);
435     if (p == value || *p != '\0')
436       return PREFS_SET_SYNTAX_ERR;      /* number was bad */
437     if (num <= 0)
438       return PREFS_SET_SYNTAX_ERR;      /* number must be positive */
439     recent.gui_geometry_main_upper_pane = num;
440     recent.has_gui_geometry_main_upper_pane = TRUE;
441   } else if (strcmp(key, RECENT_GUI_GEOMETRY_MAIN_LOWER_PANE) == 0) {
442     num = strtol(value, &p, 0);
443     if (p == value || *p != '\0')
444       return PREFS_SET_SYNTAX_ERR;      /* number was bad */
445     if (num <= 0)
446       return PREFS_SET_SYNTAX_ERR;      /* number must be positive */
447     recent.gui_geometry_main_lower_pane = num;
448     recent.has_gui_geometry_main_lower_pane = TRUE;
449   } else if (strcmp(key, RECENT_GUI_GEOMETRY_STATUS_PANE) == 0) {
450     num = strtol(value, &p, 0);
451     if (p == value || *p != '\0')
452       return PREFS_SET_SYNTAX_ERR;      /* number was bad */
453     if (num <= 0)
454       return PREFS_SET_SYNTAX_ERR;      /* number must be positive */
455     recent.gui_geometry_status_pane = num;
456     recent.has_gui_geometry_status_pane = TRUE;
457   } else if (strcmp(key, RECENT_GUI_FILEOPEN_REMEMBERED_DIR) == 0) {
458     if(u3_active())
459       set_last_open_dir(u3_expand_device_path(value));
460     else
461       set_last_open_dir(value);
462   } else if (strncmp(key, RECENT_GUI_GEOMETRY, sizeof(RECENT_GUI_GEOMETRY)-1) == 0) {
463     /* now have something like "gui.geom.main.x", split it into win and sub_key */
464     char *win = &key[sizeof(RECENT_GUI_GEOMETRY)-1];
465     char *sub_key = strchr(win, '.');
466     if(sub_key) {
467       *sub_key = '\0';
468       sub_key++;
469       window_geom_recent_read_pair(win, sub_key, value);
470     }
471   } else if (strcmp(key, RECENT_KEY_PRIVS_WARN_IF_ELEVATED) == 0) {
472     if (g_ascii_strcasecmp(value, "true") == 0) {
473         recent.privs_warn_if_elevated = TRUE;
474     }
475     else {
476         recent.privs_warn_if_elevated = FALSE;
477     }
478   } else if (strcmp(key, RECENT_KEY_PRIVS_WARN_IF_NO_NPF) == 0) {
479     if (g_ascii_strcasecmp(value, "true") == 0) {
480         recent.privs_warn_if_no_npf = TRUE;
481     }
482     else {
483         recent.privs_warn_if_no_npf = FALSE;
484     }
485   }
486
487   return PREFS_SET_OK;
488 }
489
490
491 /* set one user's recent file key/value pair */
492 static prefs_set_pref_e
493 read_set_recent_pair_dynamic(gchar *key, gchar *value, void *private_data _U_)
494 {
495   if (strcmp(key, RECENT_KEY_CAPTURE_FILE) == 0) {
496     if(u3_active())
497       add_menu_recent_capture_file(u3_expand_device_path(value));
498     else
499       add_menu_recent_capture_file(value);
500   } else if (strcmp(key, RECENT_KEY_DISPLAY_FILTER) == 0) {
501         dfilter_combo_add_recent(value);
502   } else if (strcmp(key, RECENT_KEY_CAPTURE_FILTER) == 0) {
503         cfilter_combo_add_recent(value);
504   }
505
506   return PREFS_SET_OK;
507 }
508
509
510 /*
511  * Given a string of the form "<recent name>:<recent value>", as might appear
512  * as an argument to a "-o" option, parse it and set the recent value in
513  * question.  Return an indication of whether it succeeded or failed
514  * in some fashion.
515  */
516 int
517 recent_set_arg(char *prefarg)
518 {
519         gchar *p, *colonp;
520         int ret;
521
522         colonp = strchr(prefarg, ':');
523         if (colonp == NULL)
524                 return PREFS_SET_SYNTAX_ERR;
525
526         p = colonp;
527         *p++ = '\0';
528
529         /*
530          * Skip over any white space (there probably won't be any, but
531          * as we allow it in the preferences file, we might as well
532          * allow it here).
533          */
534         while (isspace(*p))
535                 p++;
536         if (*p == '\0') {
537                 /*
538                  * Put the colon back, so if our caller uses, in an
539                  * error message, the string they passed us, the message
540                  * looks correct.
541                  */
542                 *colonp = ':';
543                 return PREFS_SET_SYNTAX_ERR;
544         }
545
546         ret = read_set_recent_pair_static(prefarg, p, NULL);
547         *colonp = ':';  /* put the colon back */
548         return ret;
549 }
550
551
552 /* opens the user's recent file and read the first part */
553 void
554 recent_read_static(char **rf_path_return, int *rf_errno_return)
555 {
556   char       *rf_path;
557   FILE       *rf;
558
559
560   /* set defaults */
561   recent.main_toolbar_show      = TRUE;
562   recent.filter_toolbar_show    = TRUE;
563   recent.airpcap_toolbar_show   = FALSE;
564   recent.airpcap_driver_check_show   = TRUE;
565   recent.packet_list_show       = TRUE;
566   recent.tree_view_show         = TRUE;
567   recent.byte_view_show         = TRUE;
568   recent.statusbar_show         = TRUE;
569   recent.packet_list_colorize   = TRUE;
570   recent.gui_time_format        = TS_RELATIVE;
571   recent.gui_time_precision     = TS_PREC_AUTO;
572   recent.gui_zoom_level         = 0;
573
574   recent.gui_geometry_main_x        =        20;
575   recent.gui_geometry_main_y        =        20;
576   recent.gui_geometry_main_width    = DEF_WIDTH;
577   recent.gui_geometry_main_height   = DEF_HEIGHT;
578   recent.gui_geometry_main_maximized=     FALSE;
579
580   /* pane size of zero will autodetect */
581   recent.gui_geometry_main_upper_pane   = 0;
582   recent.gui_geometry_main_lower_pane   = 0;
583   recent.gui_geometry_status_pane       = 0;
584
585   /* the following are only used if GTK2 is used (as GTK1 cannot read these geometry values) */
586   /* or if set through command line */
587 #if GTK_MAJOR_VERSION >= 2
588   recent.has_gui_geometry_main_upper_pane = TRUE;
589   recent.has_gui_geometry_main_lower_pane = TRUE;
590   recent.has_gui_geometry_status_pane = TRUE;
591 #else
592   recent.has_gui_geometry_main_upper_pane = FALSE;
593   recent.has_gui_geometry_main_lower_pane = FALSE;
594   recent.has_gui_geometry_status_pane = FALSE;
595 #endif
596
597   recent.privs_warn_if_elevated = TRUE;
598   recent.privs_warn_if_no_npf = TRUE;
599
600   /* Construct the pathname of the user's recent file. */
601   rf_path = get_persconffile_path(RECENT_FILE_NAME, FALSE);
602
603   /* Read the user's recent file, if it exists. */
604   *rf_path_return = NULL;
605   if ((rf = eth_fopen(rf_path, "r")) != NULL) {
606     /* We succeeded in opening it; read it. */
607     read_prefs_file(rf_path, rf, read_set_recent_pair_static, NULL);
608     fclose(rf);
609     g_free(rf_path);
610     rf_path = NULL;
611   } else {
612     /* We failed to open it.  If we failed for some reason other than
613        "it doesn't exist", return the errno and the pathname, so our
614        caller can report the error. */
615     if (errno != ENOENT) {
616       *rf_errno_return = errno;
617       *rf_path_return = rf_path;
618     }
619   }
620 }
621
622
623
624 /* opens the user's recent file and read it out */
625 void
626 recent_read_dynamic(char **rf_path_return, int *rf_errno_return)
627 {
628   char       *rf_path;
629   FILE       *rf;
630
631
632   /* Construct the pathname of the user's recent file. */
633   rf_path = get_persconffile_path(RECENT_FILE_NAME, FALSE);
634
635   /* Read the user's recent file, if it exists. */
636   *rf_path_return = NULL;
637   if ((rf = eth_fopen(rf_path, "r")) != NULL) {
638     /* We succeeded in opening it; read it. */
639     read_prefs_file(rf_path, rf, read_set_recent_pair_dynamic, NULL);
640         /* set dfilter combobox to have an empty line */
641     dfilter_combo_add_empty();
642     fclose(rf);
643     g_free(rf_path);
644     rf_path = NULL;
645   } else {
646     /* We failed to open it.  If we failed for some reason other than
647        "it doesn't exist", return the errno and the pathname, so our
648        caller can report the error. */
649     if (errno != ENOENT) {
650       *rf_errno_return = errno;
651       *rf_path_return = rf_path;
652     }
653   }
654 }
655
656