implemented capture dialog 3rd (+x) proposal
[obnox/wireshark/wip.git] / gtk / capture_dlg.c
1 /* capture_dlg.c
2  * Routines for packet capture windows
3  *
4  * $Id: capture_dlg.c,v 1.115 2004/03/02 22:07:23 ulfl Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@ethereal.com>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #ifdef HAVE_LIBPCAP
30
31 #include <pcap.h>
32 #include <string.h>
33 #include <gtk/gtk.h>
34
35 #include <epan/packet.h>
36 #include "capture.h"
37 #include "globals.h"
38 #include <epan/resolv.h>
39 #include "main.h"
40 #include "ui_util.h"
41 #include "capture_dlg.h"
42 #include "filter_prefs.h"
43 #include "simple_dialog.h"
44 #include "dlg_utils.h"
45 #include "pcap-util.h"
46 #include "capture_combo_utils.h"
47 #include "prefs.h"
48 #include "ringbuffer.h"
49 #include <epan/filesystem.h>
50 #include "compat_macros.h"
51 #include "file_dlg.h"
52 #include "help_dlg.h"
53
54 #ifdef _WIN32
55 #include "capture-wpcap.h"
56 #endif
57
58 /* Capture callback data keys */
59 #define E_CAP_IFACE_KEY       "cap_iface"
60 #define E_CAP_SNAP_CB_KEY     "cap_snap_cb"
61 #define E_CAP_LT_OM_KEY       "cap_lt_om"
62 #define E_CAP_LT_OM_LABEL_KEY "cap_lt_om_label"
63 #define E_CAP_SNAP_SB_KEY     "cap_snap_sb"
64 #define E_CAP_PROMISC_KEY     "cap_promisc"
65 #define E_CAP_FILT_KEY        "cap_filter_te"
66 #define E_CAP_FILE_TE_KEY     "cap_file_te"
67 #define E_CAP_RING_ON_TB_KEY  "cap_ringbuffer_on_tb"
68 #define E_CAP_RING_NBF_CB_KEY "cap_ringbuffer_nbf_cb"
69 #define E_CAP_RING_NBF_SB_KEY "cap_ringbuffer_nbf_sb"
70 #define E_CAP_RING_NBF_LB_KEY "cap_ringbuffer_nbf_lb"
71 #define E_CAP_RING_FILESIZE_CB_KEY "cap_ringbuffer_filesize_cb"
72 #define E_CAP_RING_FILESIZE_SB_KEY "cap_ringbuffer_filesize_sb"
73 #define E_CAP_RING_FILESIZE_LB_KEY "cap_ringbuffer_filesize_lb"
74 #define E_CAP_RING_DURATION_CB_KEY "cap_ringbuffer_duration_cb"
75 #define E_CAP_RING_DURATION_SB_KEY "cap_ringbuffer_duration_sb"
76 #define E_CAP_RING_DURATION_LB_KEY "cap_ringbuffer_duration_lb"
77 #define E_CAP_SYNC_KEY        "cap_sync"
78 #define E_CAP_AUTO_SCROLL_KEY "cap_auto_scroll"
79 #define E_CAP_COUNT_CB_KEY    "cap_count_cb"
80 #define E_CAP_COUNT_SB_KEY    "cap_count_sb"
81 #define E_CAP_FILESIZE_CB_KEY "cap_filesize_cb"
82 #define E_CAP_FILESIZE_SB_KEY "cap_filesize_sb"
83 #define E_CAP_FILESIZE_LB_KEY "cap_filesize_lb"
84 #define E_CAP_DURATION_CB_KEY "cap_duration_cb"
85 #define E_CAP_DURATION_SB_KEY "cap_duration_sb"
86 #define E_CAP_FILES_CB_KEY    "cap_files_cb"
87 #define E_CAP_FILES_SB_KEY    "cap_files_sb"
88 #define E_CAP_FILES_LB_KEY    "cap_files_lb"
89 #define E_CAP_M_RESOLVE_KEY   "cap_m_resolve"
90 #define E_CAP_N_RESOLVE_KEY   "cap_n_resolve"
91 #define E_CAP_T_RESOLVE_KEY   "cap_t_resolve"
92
93 #define E_CAP_OM_LT_VALUE_KEY "cap_om_lt_value"
94
95 #define E_FS_CALLER_PTR_KEY       "fs_caller_ptr"
96 #define E_FILE_SEL_DIALOG_PTR_KEY "file_sel_dialog_ptr"
97
98 static void
99 capture_prep_file_cb(GtkWidget *w, gpointer te);
100
101 static void
102 select_link_type_cb(GtkWidget *w, gpointer data);
103
104 static void
105 cap_prep_fs_ok_cb(GtkWidget *w, gpointer data);
106
107 static void
108 cap_prep_fs_cancel_cb(GtkWidget *w, gpointer data);
109
110 static void
111 cap_prep_fs_destroy_cb(GtkWidget *win, GtkWidget* file_te);
112
113 static void
114 capture_prep_adjust_sensitivity(GtkWidget *tb, gpointer parent_w);
115
116 static void
117 capture_prep_ok_cb(GtkWidget *ok_bt, gpointer parent_w);
118
119 static void
120 capture_prep_close_cb(GtkWidget *close_bt, gpointer parent_w);
121
122 static void
123 capture_prep_destroy_cb(GtkWidget *win, gpointer user_data);
124
125 static void
126 capture_prep_interface_changed_cb(GtkWidget *entry, gpointer parent_w);
127
128 void
129 capture_stop_cb(GtkWidget *w _U_, gpointer d _U_)
130 {
131     capture_stop();
132 }
133
134 /*
135  * Given text that contains an interface name possibly prefixed by an
136  * interface description, extract the interface name.
137  */
138 static char *
139 get_if_name(char *if_text)
140 {
141   char *if_name;
142
143 #ifdef WIN32
144   /*
145    * We cannot assume that the interface name doesn't contain a space;
146    * some names on Windows OT do.
147    *
148    * We also can't assume it begins with "\Device\", either, as, on
149    * Windows OT, WinPcap doesn't put "\Device\" in front of the name.
150    *
151    * As I remember, we can't assume that the interface description
152    * doesn't contain a colon, either; I think some do.
153    *
154    * We can probably assume that the interface *name* doesn't contain
155    * a colon, however; if any interface name does contain a colon on
156    * Windows, it'll be time to just get rid of the damn interface
157    * descriptions in the drop-down list, have just the names in the
158    * drop-down list, and have a "Browse..." button to browse for interfaces,
159    * with names, descriptions, IP addresses, blah blah blah available when
160    * possible.
161    *
162    * So we search backwards for a colon.  If we don't find it, just
163    * return the entire string; otherwise, skip the colon and any blanks
164    * after it, and return that string.
165    */
166    if_name = strrchr(if_text, ':');
167    if (if_name == NULL) {
168      if_name = if_text;
169    } else {
170      if_name++;
171      while (*if_name == ' ')
172        if_name++;
173    }
174 #else
175   /*
176    * There's a space between the interface description and name, and
177    * the interface name shouldn't have a space in it (it doesn't, on
178    * UNIX systems); look backwards in the string for a space.
179    *
180    * (An interface name might, however, contain a colon in it, which
181    * is why we don't use the colon search on UNIX.)
182    */
183   if_name = strrchr(if_text, ' ');
184   if (if_name == NULL) {
185     if_name = if_text;
186   } else {
187     if_name++;
188   }
189 #endif
190   return if_name;
191 }
192
193 /*
194  * Keep a static pointer to the current "Capture Options" window, if
195  * any, so that if somebody tries to do "Capture:Start" while there's
196  * already a "Capture Options" window up, we just pop up the existing
197  * one, rather than creating a new one.
198  */
199 static GtkWidget *cap_open_w;
200
201 static void
202 set_link_type_list(GtkWidget *linktype_om, GtkWidget *entry)
203 {
204   gchar *entry_text;
205   gchar *if_text;
206   gchar *if_name;
207   GList *if_list;
208   GList *if_entry;
209   if_info_t *if_info;
210   GList *lt_list;
211   int err;
212   char err_buf[PCAP_ERRBUF_SIZE];
213   GtkWidget *lt_menu, *lt_menu_item;
214   GList *lt_entry;
215   data_link_info_t *data_link_info;
216   gchar *linktype_menu_label;
217   guint num_supported_link_types;
218   GtkWidget *linktype_lb = OBJECT_GET_DATA(linktype_om, E_CAP_LT_OM_LABEL_KEY);
219
220   lt_menu = gtk_menu_new();
221   entry_text = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
222   if_text = g_strstrip(entry_text);
223   if_name = get_if_name(if_text);
224
225   /*
226    * If the interface name is in the list of known interfaces, get
227    * its list of link-layer types and set the option menu to display it.
228    *
229    * If it's not, don't bother - the user might be in the middle of
230    * editing the list, or it might be a remote device in which case
231    * getting the list could take an arbitrarily-long period of time.
232    * The list currently won't contain any remote devices (as
233    * "pcap_findalldevs()" doesn't know about remote devices, and neither
234    * does the code we use if "pcap_findalldevs()" isn't available), but
235    * should contain all the local devices on which you can capture.
236    */
237   lt_list = NULL;
238   if (*if_name != '\0') {
239     /*
240      * Try to get the list of known interfaces.
241      */
242     if_list = get_interface_list(&err, err_buf);
243     if (if_list != NULL) {
244       /*
245        * We have the list - check it.
246        */
247       for (if_entry = if_list; if_entry != NULL;
248            if_entry = g_list_next(if_entry)) {
249         if_info = if_entry->data;
250         if (strcmp(if_info->name, if_name) == 0) {
251           /*
252            * It's in the list.
253            * Get the list of link-layer types for it.
254            */
255           lt_list = get_pcap_linktype_list(if_name, err_buf);
256         }
257       }
258       free_interface_list(if_list);
259     }
260   }
261   g_free(entry_text);
262   num_supported_link_types = 0;
263   for (lt_entry = lt_list; lt_entry != NULL; lt_entry = g_list_next(lt_entry)) {
264     data_link_info = lt_entry->data;
265     if (data_link_info->description != NULL) {
266       lt_menu_item = gtk_menu_item_new_with_label(data_link_info->description);
267       OBJECT_SET_DATA(lt_menu_item, E_CAP_LT_OM_KEY, linktype_om);
268       SIGNAL_CONNECT(lt_menu_item, "activate", select_link_type_cb,
269                      GINT_TO_POINTER(data_link_info->dlt));
270       num_supported_link_types++;
271     } else {
272       /* Not supported - tell them about it but don't let them select it. */
273       linktype_menu_label = g_strdup_printf("%s (not supported)",
274                                             data_link_info->name);
275       lt_menu_item = gtk_menu_item_new_with_label(linktype_menu_label);
276       g_free(linktype_menu_label);
277       gtk_widget_set_sensitive(lt_menu_item, FALSE);
278     }
279     gtk_menu_append(GTK_MENU(lt_menu), lt_menu_item);
280   }
281   if (lt_list != NULL)
282     free_pcap_linktype_list(lt_list);
283   gtk_option_menu_set_menu(GTK_OPTION_MENU(linktype_om), lt_menu);
284   gtk_widget_set_sensitive(linktype_lb, num_supported_link_types >= 2);
285   gtk_widget_set_sensitive(linktype_om, num_supported_link_types >= 2);
286 }
287
288 void
289 capture_prep(void)
290 {
291   GtkWidget     *main_vb,
292                 *main_hb, *left_vb, *right_vb,
293
294                 *capture_fr, *capture_vb,
295                 *if_hb, *if_cb, *if_lb,
296                 *linktype_hb, *linktype_lb, *linktype_om,
297                 *snap_hb, *snap_cb, *snap_sb, *snap_lb,
298                 *promisc_cb,
299                 *filter_hb, *filter_bt, *filter_te,
300
301                 *file_fr, *file_vb,
302                 *file_hb, *file_bt, *file_lb, *file_te,
303                 *ringbuffer_hb, *ringbuffer_on_tb, 
304                 *ring_filesize_hb, *ring_filesize_cb, *ring_filesize_sb, *ring_filesize_lb,
305                 *ring_duration_hb, *ring_duration_cb, *ring_duration_sb, *ring_duration_lb,
306                 *ringbuffer_nbf_hb, *ringbuffer_nbf_cb, *ringbuffer_nbf_sb, *ringbuffer_nbf_lb, 
307
308                 *limit_fr, *limit_vb,
309                 *count_hb, *count_cb, *count_sb, *count_lb,
310                 *filesize_hb, *filesize_cb, *filesize_sb, *filesize_lb,
311                 *duration_hb, *duration_cb, *duration_sb, *duration_lb,
312                 *files_hb, *files_cb, *files_sb, *files_lb,
313
314                 *display_fr, *display_vb,
315                 *sync_cb, *auto_scroll_cb,
316
317                 *resolv_fr, *resolv_vb,
318                 *m_resolv_cb, *n_resolv_cb, *t_resolv_cb,
319                 *bbox, *ok_bt, *cancel_bt,
320                 *help_bt;
321 #if GTK_MAJOR_VERSION < 2
322   GtkAccelGroup *accel_group;
323 #endif
324   GtkAdjustment *snap_adj, *ringbuffer_nbf_adj,
325                 *count_adj, *filesize_adj, *duration_adj, *files_adj, *ring_filesize_adj, *ring_duration_adj;
326   GList         *if_list, *combo_list;
327   int           err;
328   char          err_str[PCAP_ERRBUF_SIZE];
329
330   if (cap_open_w != NULL) {
331     /* There's already a "Capture Options" dialog box; reactivate it. */
332     reactivate_window(cap_open_w);
333     return;
334   }
335
336 #ifdef _WIN32
337   /* Is WPcap loaded? */
338   if (!has_wpcap) {
339           simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
340                   "Unable to load WinPcap (wpcap.dll); Ethereal will not be able\n"
341                   "to capture packets.\n\n"
342                   "In order to capture packets, WinPcap must be installed; see\n"
343                   "\n"
344                   "        http://winpcap.polito.it/\n"
345                   "\n"
346                   "or the mirror at\n"
347                   "\n"
348                   "        http://winpcap.mirror.ethereal.com/\n"
349                   "\n"
350                   "or the mirror at\n"
351                   "\n"
352                   "        http://www.mirrors.wiretapped.net/security/packet-capture/winpcap/\n"
353                   "\n"
354                   "for a downloadable version of WinPcap and for instructions\n"
355                   "on how to install WinPcap.");
356           return;
357   }
358 #endif
359
360   if_list = get_interface_list(&err, err_str);
361   if (if_list == NULL && err == CANT_GET_INTERFACE_LIST) {
362     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK, "Can't get list of interfaces: %s",
363                         err_str);
364   }
365
366   cap_open_w = dlg_window_new("Ethereal: Capture Options");
367   SIGNAL_CONNECT(cap_open_w, "destroy", capture_prep_destroy_cb, NULL);
368
369 #if GTK_MAJOR_VERSION < 2
370   /* Accelerator group for the accelerators (or, as they're called in
371      Windows and, I think, in Motif, "mnemonics"; Alt+<key> is a mnemonic,
372      Ctrl+<key> is an accelerator). */
373   accel_group = gtk_accel_group_new();
374   gtk_window_add_accel_group(GTK_WINDOW(cap_open_w), accel_group);
375 #endif
376
377   main_vb = gtk_vbox_new(FALSE, 0);
378   gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
379   gtk_container_add(GTK_CONTAINER(cap_open_w), main_vb);
380
381   /* Capture-related options frame */
382   capture_fr = gtk_frame_new("Capture");
383   gtk_container_add(GTK_CONTAINER(main_vb), capture_fr);
384
385   capture_vb = gtk_vbox_new(FALSE, 3);
386   gtk_container_border_width(GTK_CONTAINER(capture_vb), 5);
387   gtk_container_add(GTK_CONTAINER(capture_fr), capture_vb);
388
389   /* Interface row */
390   if_hb = gtk_hbox_new(FALSE, 3);
391   gtk_container_add(GTK_CONTAINER(capture_vb), if_hb);
392
393   if_lb = gtk_label_new("Interface:");
394   gtk_box_pack_start(GTK_BOX(if_hb), if_lb, FALSE, FALSE, 6);
395
396   if_cb = gtk_combo_new();
397   combo_list = build_capture_combo_list(if_list, TRUE);
398   if (combo_list != NULL)
399     gtk_combo_set_popdown_strings(GTK_COMBO(if_cb), combo_list);
400   if (cfile.iface == NULL && prefs.capture_device != NULL) {
401     /* No interface was specified on the command line or in a previous
402        capture, but there is one specified in the preferences file;
403        make the one from the preferences file the default */
404     cfile.iface = g_strdup(prefs.capture_device);
405   }
406   if (cfile.iface != NULL)
407     gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry), cfile.iface);
408   else if (combo_list != NULL) {
409     gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry),
410                        (char *)combo_list->data);
411   }
412   free_capture_combo_list(combo_list);
413   free_interface_list(if_list);
414   gtk_box_pack_start(GTK_BOX(if_hb), if_cb, TRUE, TRUE, 6);
415
416   /* Linktype row */
417   linktype_hb = gtk_hbox_new(FALSE, 3);
418   gtk_box_pack_start(GTK_BOX(capture_vb), linktype_hb, FALSE, FALSE, 0);
419
420   linktype_lb = gtk_label_new("Link-layer header type:");
421   gtk_box_pack_start(GTK_BOX(linktype_hb), linktype_lb, FALSE, FALSE, 6);
422
423   linktype_om = gtk_option_menu_new();
424   OBJECT_SET_DATA(linktype_om, E_CAP_LT_OM_LABEL_KEY, linktype_lb);
425   /* Default to "use the default" */
426   OBJECT_SET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY, GINT_TO_POINTER(-1));
427   set_link_type_list(linktype_om, GTK_COMBO(if_cb)->entry);
428   gtk_box_pack_start (GTK_BOX(linktype_hb), linktype_om, FALSE, FALSE, 0);
429   SIGNAL_CONNECT(GTK_ENTRY(GTK_COMBO(if_cb)->entry), "changed",
430                  capture_prep_interface_changed_cb, linktype_om);
431
432   /* Promiscuous mode row */
433   promisc_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
434       "Capture packets in _promiscuous mode", accel_group);
435   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(promisc_cb),
436                 capture_opts.promisc_mode);
437   gtk_container_add(GTK_CONTAINER(capture_vb), promisc_cb);
438
439   /* Capture length row */
440   snap_hb = gtk_hbox_new(FALSE, 3);
441   gtk_container_add(GTK_CONTAINER(capture_vb), snap_hb);
442
443   snap_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC("_Limit each packet to", accel_group);
444   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(snap_cb),
445                 capture_opts.has_snaplen);
446   SIGNAL_CONNECT(snap_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
447   gtk_box_pack_start(GTK_BOX(snap_hb), snap_cb, FALSE, FALSE, 0);
448
449   snap_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) capture_opts.snaplen,
450     MIN_PACKET_SIZE, WTAP_MAX_PACKET_SIZE, 1.0, 10.0, 0.0);
451   snap_sb = gtk_spin_button_new (snap_adj, 0, 0);
452   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (snap_sb), TRUE);
453   WIDGET_SET_SIZE(snap_sb, 80, -1);
454   gtk_box_pack_start (GTK_BOX(snap_hb), snap_sb, FALSE, FALSE, 0);
455
456   snap_lb = gtk_label_new("bytes");
457   gtk_misc_set_alignment(GTK_MISC(snap_lb), 0, 0.5);
458   gtk_box_pack_start(GTK_BOX(snap_hb), snap_lb, FALSE, FALSE, 0);
459
460   /* Filter row */
461   filter_hb = gtk_hbox_new(FALSE, 3);
462   gtk_box_pack_start(GTK_BOX(capture_vb), filter_hb, FALSE, FALSE, 0);
463
464   filter_bt = BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_CAPTURE_FILTER_ENTRY);
465   SIGNAL_CONNECT(filter_bt, "clicked", capture_filter_construct_cb, NULL);
466   SIGNAL_CONNECT(filter_bt, "destroy", filter_button_destroy_cb, NULL);
467   gtk_box_pack_start(GTK_BOX(filter_hb), filter_bt, FALSE, FALSE, 3);
468
469   filter_te = gtk_entry_new();
470   if (cfile.cfilter) gtk_entry_set_text(GTK_ENTRY(filter_te), cfile.cfilter);
471   OBJECT_SET_DATA(filter_bt, E_FILT_TE_PTR_KEY, filter_te);
472   gtk_box_pack_start(GTK_BOX(filter_hb), filter_te, TRUE, TRUE, 3);
473
474   main_hb = gtk_hbox_new(FALSE, 5);
475   gtk_container_border_width(GTK_CONTAINER(main_hb), 0);
476   gtk_container_add(GTK_CONTAINER(main_vb), main_hb);
477
478   left_vb = gtk_vbox_new(FALSE, 0);
479   gtk_container_border_width(GTK_CONTAINER(left_vb), 0);
480   gtk_box_pack_start(GTK_BOX(main_hb), left_vb, TRUE, TRUE, 0);
481
482   right_vb = gtk_vbox_new(FALSE, 0);
483   gtk_container_border_width(GTK_CONTAINER(right_vb), 0);
484   gtk_box_pack_start(GTK_BOX(main_hb), right_vb, FALSE, FALSE, 0);
485
486
487   /* Capture file-related options frame */
488   file_fr = gtk_frame_new("Capture File(s)");
489   gtk_container_add(GTK_CONTAINER(left_vb), file_fr);
490
491   file_vb = gtk_vbox_new(FALSE, 3);
492   gtk_container_border_width(GTK_CONTAINER(file_vb), 5);
493   gtk_container_add(GTK_CONTAINER(file_fr), file_vb);
494
495   /* File row */
496   file_hb = gtk_hbox_new(FALSE, 3);
497   gtk_box_pack_start(GTK_BOX(file_vb), file_hb, FALSE, FALSE, 0);
498
499   file_lb = gtk_label_new("File:");
500   gtk_box_pack_start(GTK_BOX(file_hb), file_lb, FALSE, FALSE, 3);
501
502   file_te = gtk_entry_new();
503   gtk_box_pack_start(GTK_BOX(file_hb), file_te, TRUE, TRUE, 3);
504
505   file_bt = BUTTON_NEW_FROM_STOCK(ETHEREAL_STOCK_BROWSE);
506   gtk_box_pack_start(GTK_BOX(file_hb), file_bt, FALSE, FALSE, 3);
507
508   SIGNAL_CONNECT(file_bt, "clicked", capture_prep_file_cb, file_te);
509
510   /* Ring buffer row */
511   ringbuffer_hb = gtk_hbox_new(FALSE, 3);
512   gtk_container_add(GTK_CONTAINER(file_vb), ringbuffer_hb);
513
514   ringbuffer_on_tb = CHECK_BUTTON_NEW_WITH_MNEMONIC("Use _multiple files", accel_group);
515   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ringbuffer_on_tb),
516                 capture_opts.multi_files_on);
517   SIGNAL_CONNECT(ringbuffer_on_tb, "toggled", capture_prep_adjust_sensitivity,
518                  cap_open_w);
519   gtk_box_pack_start(GTK_BOX(ringbuffer_hb), ringbuffer_on_tb, FALSE, FALSE, 0);
520
521   /* Ring buffer filesize row */
522   ring_filesize_hb = gtk_hbox_new(FALSE, 3);
523   gtk_container_add(GTK_CONTAINER(file_vb), ring_filesize_hb);
524
525   ring_filesize_cb = gtk_check_button_new_with_label("Next file every");
526   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ring_filesize_cb),
527                 capture_opts.has_autostop_filesize);
528   SIGNAL_CONNECT(ring_filesize_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
529   gtk_box_pack_start(GTK_BOX(ring_filesize_hb), ring_filesize_cb, FALSE, FALSE, 0);
530
531   ring_filesize_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts.autostop_filesize,
532     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
533   ring_filesize_sb = gtk_spin_button_new (ring_filesize_adj, 0, 0);
534   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ring_filesize_sb), TRUE);
535   WIDGET_SET_SIZE(ring_filesize_sb, 80, -1);
536   gtk_box_pack_start (GTK_BOX(ring_filesize_hb), ring_filesize_sb, FALSE, FALSE, 0);
537
538   ring_filesize_lb = gtk_label_new("kilobyte(s)");
539   gtk_misc_set_alignment(GTK_MISC(ring_filesize_lb), 0, 0.5);
540   gtk_box_pack_start(GTK_BOX(ring_filesize_hb), ring_filesize_lb, FALSE, FALSE, 0);
541
542   /* Ring buffer duration row */
543   ring_duration_hb = gtk_hbox_new(FALSE, 3);
544   gtk_container_add(GTK_CONTAINER(file_vb), ring_duration_hb);
545
546   ring_duration_cb = gtk_check_button_new_with_label("Next file every");
547   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ring_duration_cb),
548                               capture_opts.has_ring_duration);
549   SIGNAL_CONNECT(ring_duration_cb, "toggled", 
550                  capture_prep_adjust_sensitivity, cap_open_w);
551   gtk_box_pack_start(GTK_BOX(ring_duration_hb), ring_duration_cb, FALSE, FALSE, 0);
552
553   ring_duration_adj = (GtkAdjustment *)gtk_adjustment_new((gfloat)capture_opts.ringbuffer_duration,
554     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
555   ring_duration_sb = gtk_spin_button_new (ring_duration_adj, 0, 0);
556   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ring_duration_sb), TRUE);
557   WIDGET_SET_SIZE(ring_duration_sb, 80, -1);
558   gtk_box_pack_start (GTK_BOX(ring_duration_hb), ring_duration_sb, FALSE, FALSE, 0);
559
560   ring_duration_lb = gtk_label_new("second(s)");
561   gtk_misc_set_alignment(GTK_MISC(ring_duration_lb), 0, 0.5);
562   gtk_box_pack_start(GTK_BOX(ring_duration_hb), ring_duration_lb, 
563                      FALSE, FALSE, 0);
564
565   /* Ring buffer files row */
566   ringbuffer_nbf_hb = gtk_hbox_new(FALSE, 3);
567   gtk_container_add(GTK_CONTAINER(file_vb), ringbuffer_nbf_hb);
568
569   ringbuffer_nbf_cb = gtk_check_button_new_with_label("Ring buffer with");
570   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb),
571                 capture_opts.has_ring_num_files);
572   SIGNAL_CONNECT(ringbuffer_nbf_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
573   gtk_box_pack_start(GTK_BOX(ringbuffer_nbf_hb), ringbuffer_nbf_cb, FALSE, FALSE, 0);
574
575   ringbuffer_nbf_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat) capture_opts.num_files,
576     2/*RINGBUFFER_MIN_NUM_FILES*/, RINGBUFFER_MAX_NUM_FILES, 1.0, 10.0, 0.0);
577   ringbuffer_nbf_sb = gtk_spin_button_new (ringbuffer_nbf_adj, 0, 0);
578   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ringbuffer_nbf_sb), TRUE);
579   WIDGET_SET_SIZE(ringbuffer_nbf_sb, 80, -1);
580   SIGNAL_CONNECT(ringbuffer_nbf_sb, "changed", capture_prep_adjust_sensitivity, cap_open_w);
581   gtk_box_pack_start (GTK_BOX(ringbuffer_nbf_hb), ringbuffer_nbf_sb, FALSE, FALSE, 0);
582
583   ringbuffer_nbf_lb = gtk_label_new("files");
584   gtk_misc_set_alignment(GTK_MISC(ringbuffer_nbf_lb), 1, 0.5);
585   gtk_box_pack_start(GTK_BOX(ringbuffer_nbf_hb), ringbuffer_nbf_lb, FALSE, FALSE, 3);
586
587   /* Files row */
588   files_hb = gtk_hbox_new(FALSE, 3);
589   gtk_container_add(GTK_CONTAINER(file_vb), files_hb);
590
591   files_cb = gtk_check_button_new_with_label("Stop capture after");
592   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(files_cb),
593                 capture_opts.has_autostop_files);
594   SIGNAL_CONNECT(files_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
595   gtk_box_pack_start(GTK_BOX(files_hb), files_cb, FALSE, FALSE, 0);
596
597   files_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts.autostop_files,
598     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
599   files_sb = gtk_spin_button_new (files_adj, 0, 0);
600   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (files_sb), TRUE);
601   WIDGET_SET_SIZE(files_sb, 80, -1);
602   gtk_box_pack_start (GTK_BOX(files_hb), files_sb, FALSE, FALSE, 0);
603
604   files_lb = gtk_label_new("file(s)");
605   gtk_misc_set_alignment(GTK_MISC(files_lb), 0, 0.5);
606   gtk_box_pack_start(GTK_BOX(files_hb), files_lb, FALSE, FALSE, 0);
607
608   /* Capture limits frame */
609   limit_fr = gtk_frame_new("Stop Capture ...");
610   gtk_container_add(GTK_CONTAINER(left_vb), limit_fr);
611
612   limit_vb = gtk_vbox_new(FALSE, 3);
613   gtk_container_border_width(GTK_CONTAINER(limit_vb), 5);
614   gtk_container_add(GTK_CONTAINER(limit_fr), limit_vb);
615
616   /* Packet count row */
617   count_hb = gtk_hbox_new(FALSE, 3);
618   gtk_container_add(GTK_CONTAINER(limit_vb), count_hb);
619
620   count_cb = gtk_check_button_new_with_label("... after");
621   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(count_cb),
622                 capture_opts.has_autostop_count);
623   SIGNAL_CONNECT(count_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
624   gtk_box_pack_start(GTK_BOX(count_hb), count_cb, FALSE, FALSE, 0);
625
626   count_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts.autostop_count,
627     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
628   count_sb = gtk_spin_button_new (count_adj, 0, 0);
629   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (count_sb), TRUE);
630   WIDGET_SET_SIZE(count_sb, 80, -1);
631   gtk_box_pack_start (GTK_BOX(count_hb), count_sb, FALSE, FALSE, 0);
632
633   count_lb = gtk_label_new("packet(s)");
634   gtk_misc_set_alignment(GTK_MISC(count_lb), 0, 0.5);
635   gtk_box_pack_start(GTK_BOX(count_hb), count_lb, FALSE, FALSE, 0);
636
637   /* Filesize row */
638   filesize_hb = gtk_hbox_new(FALSE, 3);
639   gtk_container_add(GTK_CONTAINER(limit_vb), filesize_hb);
640
641   filesize_cb = gtk_check_button_new_with_label("... after");
642   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(filesize_cb),
643                 capture_opts.has_autostop_filesize);
644   SIGNAL_CONNECT(filesize_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
645   gtk_box_pack_start(GTK_BOX(filesize_hb), filesize_cb, FALSE, FALSE, 0);
646
647   filesize_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts.autostop_filesize,
648     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
649   filesize_sb = gtk_spin_button_new (filesize_adj, 0, 0);
650   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (filesize_sb), TRUE);
651   WIDGET_SET_SIZE(filesize_sb, 80, -1);
652   gtk_box_pack_start (GTK_BOX(filesize_hb), filesize_sb, FALSE, FALSE, 0);
653
654   filesize_lb = gtk_label_new("kilobyte(s)");
655   gtk_misc_set_alignment(GTK_MISC(filesize_lb), 0, 0.5);
656   gtk_box_pack_start(GTK_BOX(filesize_hb), filesize_lb, FALSE, FALSE, 0);
657
658   /* Duration row */
659   duration_hb = gtk_hbox_new(FALSE, 3);
660   gtk_container_add(GTK_CONTAINER(limit_vb), duration_hb);
661
662   duration_cb = gtk_check_button_new_with_label("... after");
663   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(duration_cb),
664                 capture_opts.has_autostop_duration);
665   SIGNAL_CONNECT(duration_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
666   gtk_box_pack_start(GTK_BOX(duration_hb), duration_cb, FALSE, FALSE, 0);
667
668   duration_adj = (GtkAdjustment *) gtk_adjustment_new((gfloat)capture_opts.autostop_duration,
669     1, (gfloat)INT_MAX, 1.0, 10.0, 0.0);
670   duration_sb = gtk_spin_button_new (duration_adj, 0, 0);
671   gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (duration_sb), TRUE);
672   WIDGET_SET_SIZE(duration_sb, 80, -1);
673   gtk_box_pack_start (GTK_BOX(duration_hb), duration_sb, FALSE, FALSE, 0);
674
675   duration_lb = gtk_label_new("second(s)");
676   gtk_misc_set_alignment(GTK_MISC(duration_lb), 0, 0.5);
677   gtk_box_pack_start(GTK_BOX(duration_hb), duration_lb, FALSE, FALSE, 0);
678
679   /* Display-related options frame */
680   display_fr = gtk_frame_new("Display Options");
681   gtk_container_add(GTK_CONTAINER(right_vb), display_fr);
682
683   display_vb = gtk_vbox_new(FALSE, 0);
684   gtk_container_border_width(GTK_CONTAINER(display_vb), 5);
685   gtk_container_add(GTK_CONTAINER(display_fr), display_vb);
686
687   /* "Update display in real time" row */
688   sync_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
689       "_Update list of packets in real time", accel_group);
690   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(sync_cb),
691                 capture_opts.sync_mode);
692   SIGNAL_CONNECT(sync_cb, "toggled", capture_prep_adjust_sensitivity, cap_open_w);
693   gtk_container_add(GTK_CONTAINER(display_vb), sync_cb);
694
695   /* "Auto-scroll live update" row */
696   auto_scroll_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
697                 "_Automatic scrolling in live capture", accel_group);
698   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(auto_scroll_cb), auto_scroll_live);
699   gtk_container_add(GTK_CONTAINER(display_vb), auto_scroll_cb);
700
701   /* Name Resolution frame */
702   resolv_fr = gtk_frame_new("Name Resolution");
703   gtk_container_add(GTK_CONTAINER(right_vb), resolv_fr);
704
705   resolv_vb = gtk_vbox_new(FALSE, 0);
706   gtk_container_border_width(GTK_CONTAINER(resolv_vb), 5);
707   gtk_container_add(GTK_CONTAINER(resolv_fr), resolv_vb);
708
709   m_resolv_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
710                 "Enable _MAC name resolution", accel_group);
711   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(m_resolv_cb),
712                 g_resolv_flags & RESOLV_MAC);
713   gtk_container_add(GTK_CONTAINER(resolv_vb), m_resolv_cb);
714
715   n_resolv_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
716                 "Enable _network name resolution", accel_group);
717   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(n_resolv_cb),
718                 g_resolv_flags & RESOLV_NETWORK);
719   gtk_container_add(GTK_CONTAINER(resolv_vb), n_resolv_cb);
720
721   t_resolv_cb = CHECK_BUTTON_NEW_WITH_MNEMONIC(
722                 "Enable _transport name resolution", accel_group);
723   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(t_resolv_cb),
724                 g_resolv_flags & RESOLV_TRANSPORT);
725   gtk_container_add(GTK_CONTAINER(resolv_vb), t_resolv_cb);
726
727   /* Button row: OK and cancel buttons */
728   bbox = dlg_button_row_new(GTK_STOCK_OK, GTK_STOCK_CANCEL, GTK_STOCK_HELP, NULL);
729   gtk_box_pack_start(GTK_BOX(main_vb), bbox, FALSE, FALSE, 5);
730
731   ok_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_OK);
732   SIGNAL_CONNECT(ok_bt, "clicked", capture_prep_ok_cb, cap_open_w);
733   gtk_widget_grab_default(ok_bt);
734
735   cancel_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_CANCEL);
736   SIGNAL_CONNECT(cancel_bt, "clicked", capture_prep_close_cb, cap_open_w);
737
738   help_bt = OBJECT_GET_DATA(bbox, GTK_STOCK_HELP);
739   SIGNAL_CONNECT(help_bt, "clicked", help_topic_cb, "Capturing");
740
741   /* Attach pointers to needed widgets to the capture prefs window/object */
742   OBJECT_SET_DATA(cap_open_w, E_CAP_IFACE_KEY, if_cb);
743   OBJECT_SET_DATA(cap_open_w, E_CAP_SNAP_CB_KEY, snap_cb);
744   OBJECT_SET_DATA(cap_open_w, E_CAP_SNAP_SB_KEY, snap_sb);
745   OBJECT_SET_DATA(cap_open_w, E_CAP_LT_OM_KEY, linktype_om);
746   OBJECT_SET_DATA(cap_open_w, E_CAP_PROMISC_KEY, promisc_cb);
747   OBJECT_SET_DATA(cap_open_w, E_CAP_FILT_KEY,  filter_te);
748   OBJECT_SET_DATA(cap_open_w, E_CAP_FILE_TE_KEY,  file_te);
749   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_ON_TB_KEY,  ringbuffer_on_tb);
750   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_NBF_CB_KEY,  ringbuffer_nbf_cb);
751   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_NBF_SB_KEY,  ringbuffer_nbf_sb);
752   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_NBF_LB_KEY,  ringbuffer_nbf_lb);
753   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_FILESIZE_CB_KEY,  ring_filesize_cb);
754   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_FILESIZE_SB_KEY,  ring_filesize_sb);
755   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_FILESIZE_LB_KEY,  ring_filesize_lb);
756   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_DURATION_CB_KEY,  ring_duration_cb);
757   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_DURATION_SB_KEY,  ring_duration_sb);
758   OBJECT_SET_DATA(cap_open_w, E_CAP_RING_DURATION_LB_KEY,  ring_duration_lb);
759   OBJECT_SET_DATA(cap_open_w, E_CAP_SYNC_KEY,  sync_cb);
760   OBJECT_SET_DATA(cap_open_w, E_CAP_AUTO_SCROLL_KEY, auto_scroll_cb);
761   OBJECT_SET_DATA(cap_open_w, E_CAP_COUNT_CB_KEY, count_cb);
762   OBJECT_SET_DATA(cap_open_w, E_CAP_COUNT_SB_KEY, count_sb);
763   OBJECT_SET_DATA(cap_open_w, E_CAP_FILESIZE_CB_KEY, filesize_cb);
764   OBJECT_SET_DATA(cap_open_w, E_CAP_FILESIZE_SB_KEY, filesize_sb);
765   OBJECT_SET_DATA(cap_open_w, E_CAP_FILESIZE_LB_KEY, filesize_lb);
766   OBJECT_SET_DATA(cap_open_w, E_CAP_DURATION_CB_KEY,  duration_cb);
767   OBJECT_SET_DATA(cap_open_w, E_CAP_DURATION_SB_KEY,  duration_sb);
768   OBJECT_SET_DATA(cap_open_w, E_CAP_FILES_CB_KEY, files_cb);
769   OBJECT_SET_DATA(cap_open_w, E_CAP_FILES_SB_KEY, files_sb);
770   OBJECT_SET_DATA(cap_open_w, E_CAP_FILES_LB_KEY, files_lb);
771   OBJECT_SET_DATA(cap_open_w, E_CAP_M_RESOLVE_KEY,  m_resolv_cb);
772   OBJECT_SET_DATA(cap_open_w, E_CAP_N_RESOLVE_KEY,  n_resolv_cb);
773   OBJECT_SET_DATA(cap_open_w, E_CAP_T_RESOLVE_KEY,  t_resolv_cb);
774
775   /* Set the sensitivity of various widgets as per the settings of other
776      widgets. */
777   capture_prep_adjust_sensitivity(NULL, cap_open_w);
778
779   /* Catch the "activate" signal on the filter and file name text
780      entries, so that if the user types Return there, we act as if the
781      "OK" button had been selected, as happens if Return is typed if some
782      widget that *doesn't* handle the Return key has the input focus. */
783   dlg_set_activate(filter_te, ok_bt);
784   dlg_set_activate(file_te, ok_bt);
785
786   /* Catch the "key_press_event" signal in the window, so that we can catch
787      the ESC key being pressed and act as if the "Cancel" button had
788      been selected. */
789   dlg_set_cancel(cap_open_w, cancel_bt);
790
791   /* XXX - why does not
792
793      gtk_widget_grab_focus(if_cb);
794
795     give the initial focus to the "Interface" combo box?
796
797     Or should I phrase that as "why does GTK+ continually frustrate
798     attempts to make GUIs driveable from the keyboard?"  We have to
799     go catch the activate signal on every single GtkEntry widget
800     (rather than having widgets whose activate signal is *not*
801     caught not catch the Return keystroke, so that it passes on,
802     ultimately, to the window, which can activate the default
803     widget, i.e. the "OK" button); we have to catch the "key_press_event"
804     signal and have the handler check for ESC, so that we can have ESC
805     activate the "Cancel" button; in order to support Alt+<key> mnemonics
806     for buttons and the like, we may have to construct an accelerator
807     group by hand and set up the accelerators by hand (if that even
808     works - I've not tried it yet); we have to do a "gtk_widget_grab_focus()"
809     to keep some container widget from getting the initial focus, so that
810     you don't have to tab into the first widget in order to start typing
811     in it; and it now appears that you simply *can't* make a combo box
812     get the initial focus, at least not in the obvious fashion. Sigh.... */
813
814   gtk_widget_show_all(cap_open_w);
815 }
816
817 static void 
818 capture_prep_answered_cb(gpointer dialog _U_, gint btn, gpointer data)
819 {
820     switch(btn) {
821     case(ESD_BTN_YES):
822         /* save file first */
823         file_save_as_cmd(after_save_capture_dialog, data);
824         break;
825     case(ESD_BTN_NO):
826         capture_prep();
827         break;
828     case(ESD_BTN_CANCEL):
829         break;
830     default:
831         g_assert_not_reached();
832     }
833 }
834
835 void
836 capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
837 {
838   gpointer  dialog;
839
840   if((cfile.state != FILE_CLOSED) && !cfile.user_saved) {
841     /* user didn't saved his current file, ask him */
842     dialog = simple_dialog(ESD_TYPE_CONFIRMATION, ESD_BTNS_YES_NO_CANCEL,
843                 PRIMARY_TEXT_START "Save capture file before starting a new capture?" PRIMARY_TEXT_END "\n\n"
844                 "If you start a new capture without saving, your current capture data will be discarded.");
845     simple_dialog_set_cb(dialog, capture_prep_answered_cb, NULL);
846   } else {
847     /* unchanged file, just capture a new one */
848     capture_prep();
849   }
850 }
851
852 static void
853 select_link_type_cb(GtkWidget *w, gpointer data)
854 {
855   int new_linktype = GPOINTER_TO_INT(data);
856   GtkWidget *linktype_om = OBJECT_GET_DATA(w, E_CAP_LT_OM_KEY);
857   int old_linktype = GPOINTER_TO_INT(OBJECT_GET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY));
858
859   if (old_linktype != new_linktype)
860     OBJECT_SET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY, GINT_TO_POINTER(new_linktype));
861 }
862
863 static void
864 capture_prep_file_cb(GtkWidget *w, gpointer file_te)
865 {
866   GtkWidget *caller = gtk_widget_get_toplevel(w);
867   GtkWidget *fs;
868
869   /* Has a file selection dialog box already been opened for that top-level
870      widget? */
871   fs = OBJECT_GET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY);
872
873   if (fs != NULL) {
874     /* Yes.  Just re-activate that dialog box. */
875     reactivate_window(fs);
876     return;
877   }
878
879   fs = file_selection_new ("Ethereal: Capture File");
880
881   /* If we've opened a file, start out by showing the files in the directory
882      in which that file resided. */
883   if (last_open_dir)
884     gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), last_open_dir);
885
886   OBJECT_SET_DATA(fs, E_CAP_FILE_TE_KEY, file_te);
887
888   /* Set the E_FS_CALLER_PTR_KEY for the new dialog to point to our caller. */
889   OBJECT_SET_DATA(fs, E_FS_CALLER_PTR_KEY, caller);
890
891   /* Set the E_FILE_SEL_DIALOG_PTR_KEY for the caller to point to us */
892   OBJECT_SET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY, fs);
893
894   /* Call a handler when the file selection box is destroyed, so we can inform
895      our caller, if any, that it's been destroyed. */
896   SIGNAL_CONNECT(fs, "destroy", cap_prep_fs_destroy_cb, file_te);
897
898   SIGNAL_CONNECT(GTK_FILE_SELECTION(fs)->ok_button, "clicked", cap_prep_fs_ok_cb, fs);
899
900   /* Connect the cancel_button to destroy the widget */
901   SIGNAL_CONNECT(GTK_FILE_SELECTION(fs)->cancel_button, "clicked", cap_prep_fs_cancel_cb,
902                  fs);
903
904   /* Catch the "key_press_event" signal in the window, so that we can catch
905      the ESC key being pressed and act as if the "Cancel" button had
906      been selected. */
907   dlg_set_cancel(fs, GTK_FILE_SELECTION(fs)->cancel_button);
908
909   gtk_widget_show_all(fs);
910 }
911
912 static void
913 cap_prep_fs_ok_cb(GtkWidget *w _U_, gpointer data)
914 {
915   gchar     *cf_name;
916
917   cf_name = g_strdup(gtk_file_selection_get_filename(
918     GTK_FILE_SELECTION (data)));
919
920   /* Perhaps the user specified a directory instead of a file.
921      Check whether they did. */
922   if (test_for_directory(cf_name) == EISDIR) {
923         /* It's a directory - set the file selection box to display it. */
924         set_last_open_dir(cf_name);
925         g_free(cf_name);
926         gtk_file_selection_set_filename(GTK_FILE_SELECTION(data),
927           last_open_dir);
928         return;
929   }
930
931   gtk_entry_set_text(GTK_ENTRY(OBJECT_GET_DATA(data, E_CAP_FILE_TE_KEY)), cf_name);
932
933   gtk_widget_destroy(GTK_WIDGET(data));
934   g_free(cf_name);
935 }
936
937 static void
938 cap_prep_fs_cancel_cb(GtkWidget *w _U_, gpointer data)
939 {
940   gtk_widget_destroy(GTK_WIDGET(data));
941 }
942
943 static void
944 cap_prep_fs_destroy_cb(GtkWidget *win, GtkWidget* file_te)
945 {
946   GtkWidget *caller;
947
948   /* Get the widget that requested that we be popped up.
949      (It should arrange to destroy us if it's destroyed, so
950      that we don't get a pointer to a non-existent window here.) */
951   caller = OBJECT_GET_DATA(win, E_FS_CALLER_PTR_KEY);
952
953   /* Tell it we no longer exist. */
954   OBJECT_SET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY, NULL);
955
956   /* Now nuke this window. */
957   gtk_grab_remove(GTK_WIDGET(win));
958   gtk_widget_destroy(GTK_WIDGET(win));
959
960   /* Give the focus to the file text entry widget so the user can just press
961      Return to start the capture. */
962   gtk_widget_grab_focus(file_te);
963 }
964
965 static void
966 capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
967   GtkWidget *if_cb, *snap_cb, *snap_sb, *promisc_cb, *filter_te,
968             *file_te, *ringbuffer_on_tb, *ringbuffer_nbf_sb, *ringbuffer_nbf_cb,
969             *linktype_om, *sync_cb, *auto_scroll_cb,
970             *count_cb, *count_sb,
971             *filesize_cb, *filesize_sb,
972             *duration_cb, *duration_sb,
973             *ring_filesize_cb, *ring_filesize_sb,
974             *ring_duration_cb, *ring_duration_sb,
975             *m_resolv_cb, *n_resolv_cb, *t_resolv_cb;
976   gchar *entry_text;
977   gchar *if_text;
978   gchar *if_name;
979   const gchar *filter_text;
980   gchar *save_file;
981   const gchar *g_save_file;
982   gchar *cf_name;
983   gchar *dirname;
984
985   if_cb     = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_IFACE_KEY);
986   snap_cb   = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_CB_KEY);
987   snap_sb   = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_SB_KEY);
988   linktype_om = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_LT_OM_KEY);
989   promisc_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_PROMISC_KEY);
990   filter_te = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILT_KEY);
991   file_te   = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILE_TE_KEY);
992   ringbuffer_on_tb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_ON_TB_KEY);
993   ringbuffer_nbf_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_CB_KEY);
994   ringbuffer_nbf_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_SB_KEY);
995   ring_filesize_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_CB_KEY);
996   ring_filesize_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_SB_KEY);
997   ring_duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_DURATION_CB_KEY);
998   ring_duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_DURATION_SB_KEY);
999   sync_cb   = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SYNC_KEY);
1000   auto_scroll_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_AUTO_SCROLL_KEY);
1001   count_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_COUNT_CB_KEY);
1002   count_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_COUNT_SB_KEY);
1003   filesize_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILESIZE_CB_KEY);
1004   filesize_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILESIZE_SB_KEY);
1005   duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_DURATION_CB_KEY);
1006   duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_DURATION_SB_KEY);
1007   m_resolv_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_M_RESOLVE_KEY);
1008   n_resolv_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_N_RESOLVE_KEY);
1009   t_resolv_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_T_RESOLVE_KEY);
1010
1011   entry_text =
1012     g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry)));
1013   if_text = g_strstrip(entry_text);
1014   if_name = get_if_name(if_text);
1015   if (*if_name == '\0') {
1016     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1017       "You didn't specify an interface on which to capture packets.");
1018     g_free(entry_text);
1019     return;
1020   }
1021   if (cfile.iface)
1022     g_free(cfile.iface);
1023   cfile.iface = g_strdup(if_name);
1024   g_free(entry_text);
1025
1026   capture_opts.linktype =
1027       GPOINTER_TO_INT(OBJECT_GET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY));
1028
1029   capture_opts.has_snaplen =
1030     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb));
1031   if (capture_opts.has_snaplen) {
1032     capture_opts.snaplen =
1033       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb));
1034     if (capture_opts.snaplen < 1)
1035       capture_opts.snaplen = WTAP_MAX_PACKET_SIZE;
1036     else if (capture_opts.snaplen < MIN_PACKET_SIZE)
1037       capture_opts.snaplen = MIN_PACKET_SIZE;
1038   }
1039
1040   capture_opts.promisc_mode =
1041     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(promisc_cb));
1042
1043   /* XXX - don't try to get clever and set "cfile.filter" to NULL if the
1044      filter string is empty, as an indication that we don't have a filter
1045      and thus don't have to set a filter when capturing - the version of
1046      libpcap in Red Hat Linux 6.1, and versions based on later patches
1047      in that series, don't bind the AF_PACKET socket to an interface
1048      until a filter is set, which means they aren't bound at all if
1049      no filter is set, which means no packets arrive as input on that
1050      socket, which means Ethereal never sees any packets. */
1051   filter_text = gtk_entry_get_text(GTK_ENTRY(filter_te));
1052   if (cfile.cfilter)
1053     g_free(cfile.cfilter);
1054   g_assert(filter_text != NULL);
1055   cfile.cfilter = g_strdup(filter_text);
1056
1057   g_save_file = gtk_entry_get_text(GTK_ENTRY(file_te));
1058   if (g_save_file && g_save_file[0]) {
1059     /* User specified a file to which the capture should be written. */
1060     save_file = g_strdup(g_save_file);
1061     /* Save the directory name for future file dialogs. */
1062     cf_name = g_strdup(g_save_file);
1063     dirname = get_dirname(cf_name);  /* Overwrites cf_name */
1064     set_last_open_dir(dirname);
1065     g_free(cf_name);
1066   } else {
1067     /* User didn't specify a file; save to a temporary file. */
1068     save_file = NULL;
1069   }
1070
1071   capture_opts.has_autostop_count =
1072     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(count_cb));
1073   if (capture_opts.has_autostop_count)
1074     capture_opts.autostop_count =
1075       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(count_sb));
1076
1077   capture_opts.has_autostop_duration =
1078     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(duration_cb));
1079   if (capture_opts.has_autostop_duration)
1080     capture_opts.autostop_duration =
1081       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(duration_sb));
1082
1083   capture_opts.sync_mode =
1084     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb));
1085
1086   auto_scroll_live =
1087       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auto_scroll_cb));
1088
1089   g_resolv_flags |= g_resolv_flags & RESOLV_CONCURRENT;
1090   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_resolv_cb)))
1091     g_resolv_flags |= RESOLV_MAC;
1092   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(n_resolv_cb)))
1093     g_resolv_flags |= RESOLV_NETWORK;
1094   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(t_resolv_cb)))
1095     g_resolv_flags |= RESOLV_TRANSPORT;
1096
1097   capture_opts.has_ring_num_files =
1098     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb));  
1099
1100   capture_opts.num_files =
1101     gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ringbuffer_nbf_sb));
1102   if (capture_opts.num_files > RINGBUFFER_MAX_NUM_FILES)
1103     capture_opts.num_files = RINGBUFFER_MAX_NUM_FILES;
1104 #if RINGBUFFER_MIN_NUM_FILES > 0
1105   else if (capture_opts.num_files < RINGBUFFER_MIN_NUM_FILES)
1106     capture_opts.num_files = RINGBUFFER_MIN_NUM_FILES;
1107 #endif
1108
1109   capture_opts.multi_files_on =
1110     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb));
1111
1112   if(capture_opts.sync_mode)
1113     capture_opts.multi_files_on = FALSE;
1114
1115   if (capture_opts.multi_files_on) {
1116     capture_opts.has_autostop_filesize =
1117       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb));
1118     if (capture_opts.has_autostop_filesize)
1119       capture_opts.autostop_filesize =
1120         gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ring_filesize_sb));
1121
1122     /* test if the settings are ok for a ringbuffer */
1123     if (save_file == NULL) {
1124       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1125         PRIMARY_TEXT_START "Multiple files: No capture file name given!\n\n" PRIMARY_TEXT_END
1126         "You must specify a filename if you want to use multiple files.");
1127       return;
1128     } else if (!capture_opts.has_autostop_filesize) {
1129       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1130         PRIMARY_TEXT_START "Multiple files: No file limit given!\n\n" PRIMARY_TEXT_END
1131         "You must specify a file size at which is switched to the next capture file\n"
1132         "if you want to use multiple files.");
1133       g_free(save_file);
1134       return;
1135     }
1136   } else {
1137     capture_opts.has_autostop_filesize =
1138       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(filesize_cb));
1139     if (capture_opts.has_autostop_filesize)
1140       capture_opts.autostop_filesize =
1141         gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(filesize_sb));
1142   }
1143
1144   capture_opts.has_ring_duration =
1145     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_duration_cb));
1146   if (capture_opts.has_ring_duration)
1147     capture_opts.ringbuffer_duration =
1148       gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ring_duration_sb));
1149
1150   gtk_widget_destroy(GTK_WIDGET(parent_w));
1151
1152   do_capture(save_file);
1153   if (save_file != NULL)
1154     g_free(save_file);
1155 }
1156
1157 static void
1158 capture_prep_close_cb(GtkWidget *close_bt _U_, gpointer parent_w)
1159 {
1160   gtk_grab_remove(GTK_WIDGET(parent_w));
1161   gtk_widget_destroy(GTK_WIDGET(parent_w));
1162 }
1163
1164 static void
1165 capture_prep_destroy_cb(GtkWidget *win, gpointer user_data _U_)
1166 {
1167   GtkWidget *fs;
1168
1169   /* Is there a file selection dialog associated with this
1170      Capture Options dialog? */
1171   fs = OBJECT_GET_DATA(win, E_FILE_SEL_DIALOG_PTR_KEY);
1172
1173   if (fs != NULL) {
1174     /* Yes.  Destroy it. */
1175     gtk_widget_destroy(fs);
1176   }
1177
1178   /* Note that we no longer have a "Capture Options" dialog box. */
1179   cap_open_w = NULL;
1180 }
1181
1182 static void
1183 capture_prep_interface_changed_cb(GtkWidget *entry, gpointer argp)
1184 {
1185   GtkWidget *linktype_om = argp;
1186
1187   set_link_type_list(linktype_om, entry);
1188 }
1189
1190 /*
1191  * Adjust the sensitivity of various widgets as per the current setting
1192  * of other widgets.
1193  */
1194 static void
1195 capture_prep_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w)
1196 {
1197   GtkWidget *if_cb,
1198             *snap_cb, *snap_sb,
1199             *ringbuffer_on_tb, *ringbuffer_nbf_cb, *ringbuffer_nbf_sb, *ringbuffer_nbf_lb,
1200             *ring_filesize_cb, *ring_filesize_sb, *ring_filesize_lb,
1201             *sync_cb, *auto_scroll_cb,
1202             *count_cb, *count_sb,
1203             *filesize_cb, *filesize_sb, *filesize_lb,
1204             *duration_cb, *duration_sb,
1205             *files_cb, *files_sb, *files_lb,
1206             *ring_duration_cb, *ring_duration_sb, *ring_duration_lb;
1207
1208
1209   if_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_IFACE_KEY);
1210   snap_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_CB_KEY);
1211   snap_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SNAP_SB_KEY);
1212   ringbuffer_on_tb  = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_ON_TB_KEY);
1213   ringbuffer_nbf_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_CB_KEY);
1214   ringbuffer_nbf_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_SB_KEY);
1215   ringbuffer_nbf_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_LB_KEY);
1216   ring_filesize_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_CB_KEY);
1217   ring_filesize_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_SB_KEY);
1218   ring_filesize_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_FILESIZE_LB_KEY);
1219   ring_duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_DURATION_CB_KEY);
1220   ring_duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_DURATION_SB_KEY);
1221   ring_duration_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_DURATION_LB_KEY);
1222   sync_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_SYNC_KEY);
1223   auto_scroll_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_AUTO_SCROLL_KEY);
1224   count_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_COUNT_CB_KEY);
1225   count_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_COUNT_SB_KEY);
1226   filesize_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILESIZE_CB_KEY);
1227   filesize_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILESIZE_SB_KEY);
1228   filesize_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILESIZE_LB_KEY);
1229   duration_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_DURATION_CB_KEY);
1230   duration_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_DURATION_SB_KEY);
1231   files_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILES_CB_KEY);
1232   files_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILES_SB_KEY);
1233   files_lb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILES_LB_KEY);
1234
1235   /* The snapshot length spinbox is sensitive if the "Limit each packet
1236      to" checkbox is on. */
1237   gtk_widget_set_sensitive(GTK_WIDGET(snap_sb),
1238       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb)));
1239
1240
1241   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb))) {
1242     /* "Update list of packets in real time" captures enabled; we don't
1243        support ring buffer mode for those captures, so turn ring buffer
1244        mode off if it's on, and make its toggle button, and the spin
1245        button for the number of ring buffer files (and the spin button's
1246        label), insensitive. */
1247     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb), FALSE);
1248     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_on_tb), FALSE);
1249
1250     /* Auto-scroll mode is meaningful only in "Update list of packets
1251        in real time" captures, so make its toggle button sensitive. */
1252     gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), TRUE);
1253   } else {
1254     /* "Update list of packets in real time" captures disabled; that
1255        means ring buffer mode is OK, so make its toggle button
1256        sensitive. */
1257     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_on_tb), TRUE);
1258
1259     /* Auto-scroll mode is meaningful only in "Update list of packets
1260        in real time" captures, so make its toggle button insensitive. */
1261     gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), FALSE);
1262   }
1263
1264   if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb))) {
1265     /* Ring buffer mode enabled. */
1266     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ring_filesize_cb), TRUE);
1267
1268     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_cb), TRUE);
1269     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb),
1270           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_nbf_cb)));
1271     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb), TRUE);
1272
1273     /* The ring filesize spinbox is sensitive if the "Next capture file
1274          after N kilobytes" checkbox is on. */
1275     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_cb), TRUE);
1276     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_sb),
1277           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_filesize_cb)));
1278     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_lb), TRUE);
1279
1280     /* The ring duration spinbox is sensitive if the "Next capture file
1281          after N seconds" checkbox is on. */
1282     gtk_widget_set_sensitive(GTK_WIDGET(ring_duration_cb), TRUE);
1283     gtk_widget_set_sensitive(GTK_WIDGET(ring_duration_sb),
1284           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ring_duration_cb)));
1285     gtk_widget_set_sensitive(GTK_WIDGET(ring_duration_lb), TRUE);
1286
1287     gtk_widget_set_sensitive(GTK_WIDGET(filesize_cb), FALSE);
1288     gtk_widget_set_sensitive(GTK_WIDGET(filesize_sb), FALSE);
1289     gtk_widget_set_sensitive(GTK_WIDGET(filesize_lb), FALSE);
1290
1291     gtk_widget_set_sensitive(GTK_WIDGET(files_cb), TRUE);
1292     gtk_widget_set_sensitive(GTK_WIDGET(files_sb), 
1293           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(files_cb)));
1294     gtk_widget_set_sensitive(GTK_WIDGET(files_lb), TRUE);
1295   } else {
1296     /* Ring buffer mode disabled. */
1297     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_cb), FALSE);
1298     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb), FALSE);
1299     gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb), FALSE);
1300
1301     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_cb), FALSE);
1302     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_sb),FALSE);
1303     gtk_widget_set_sensitive(GTK_WIDGET(ring_filesize_lb),FALSE);
1304
1305     gtk_widget_set_sensitive(GTK_WIDGET(ring_duration_cb), FALSE);
1306     gtk_widget_set_sensitive(GTK_WIDGET(ring_duration_sb),FALSE);
1307     gtk_widget_set_sensitive(GTK_WIDGET(ring_duration_lb),FALSE);
1308
1309     /* The maximum file size spinbox is sensitive if the "Stop capture
1310          after N kilobytes" checkbox is on. */
1311     gtk_widget_set_sensitive(GTK_WIDGET(filesize_cb), TRUE);
1312     gtk_widget_set_sensitive(GTK_WIDGET(filesize_sb),
1313           gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(filesize_cb)));
1314     gtk_widget_set_sensitive(GTK_WIDGET(filesize_lb), TRUE);
1315
1316     gtk_widget_set_sensitive(GTK_WIDGET(files_cb), FALSE);
1317     gtk_widget_set_sensitive(GTK_WIDGET(files_sb), FALSE);
1318     gtk_widget_set_sensitive(GTK_WIDGET(files_lb), FALSE);
1319   }
1320
1321   /* The maximum packet count spinbox is sensitive if the "Stop capture
1322      after N packets" checkbox is on. */
1323   gtk_widget_set_sensitive(GTK_WIDGET(count_sb),
1324       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(count_cb)));
1325
1326   /* The capture duration spinbox is sensitive if the "Stop capture
1327      after N seconds" checkbox is on. */
1328   gtk_widget_set_sensitive(GTK_WIDGET(duration_sb),
1329       gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(duration_cb)));
1330 }
1331
1332 #endif /* HAVE_LIBPCAP */