Ethereal-dev: Re: [Ethereal-dev] Unhandled exception...

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: "Gautham Thavva" <gautham.thavva@xxxxxxxxx>
Date: Sat, 12 Oct 2002 10:15:58 -0400
Hi Ashok,

I have used diff version for windows and have enclosed the diffs
as html. Please tell me if you need any other information.

Thanks,
Gautham


On Fri, 11 Oct 2002 16:15:34  
 Ashok Narayanan wrote:
>
>You probably need to send out more information:
>
>1) A diff of your changes
>
>2) If you got a core dump, the backtrace of that core dump
>
>-Ashok
>
>> 
>> Please can someone who knows about the GUI help me. I had to include a text field for entering an IP address which would call a routine
>> for bringing HDLC traffic from a remote terminal.
>> 
>> These were the changes I made.
>> 
>> I modified the capture file structure in file.h to add
>> the IP address field. (gchar *ipaddr)
>> I initialized the capture file variable in main.c 
>> (cfile.ipaddr = NULL)
>> I added the GUI text entry construct in the capture_dlg.c 
>> When an IP address is entered, I trigger the remote
>> capture by calling a routine.
>> 
>> What happened was that initially, ethereal just quit.
>> Then I commented out the portion of calling of the routine and recompiled. I then encountered Unhandled exception:0xC0000005:Access Violation. It was at the instruction do_capture(save_file) in capture_dlg.c
>> 
>> I then commented out all the extra additions and having brought
>> to the original state, no longer faced the unhandled exception.
>> That however doesn't solve my problem. I don't understand why the
>> GUI additions caused the error.
>> 
>> Did I miss updating somewhere else? 
>> Please can someone help in resolving this issue.
>> 
>> with regards,
>> Gautham Thavva
>> 
>> 
>> ____________________________________________________________
>> Watch a championship game with Elway or McGwire.
>> Enter Now at http://champions.lycos.com 
>> _______________________________________________
>> Ethereal-dev mailing list
>> Ethereal-dev@xxxxxxxxxxxx
>> http://www.ethereal.com/mailman/listinfo/ethereal-dev
>
>
>
>--- Asok the Intern ----------------------------------------
>Ashok Narayanan
>IOS Network Protocols, Cisco Systems
>250 Apollo Drive, Chelmsford, MA 01824
>Ph: 978-497-8387.  Fax: 978-497-8513 (Attn: Ashok Narayanan)
>
>


____________________________________________________________
Watch a championship game with Elway or McGwire.
Enter Now at http://champions.lycos.com 
Title: Differences Analysis

Base file: C:\ws\ethereal-0.9.5\gtk\capture_dlg.c

Compared file: C:\ethereal-0.9.5\gtk\capture_dlg.c

Difference Analysis Generated by HtmlDiff on 10/11/2002 5:51 PM  

1:  /* capture_dlg.c
2:   * Routines for packet capture windows
3:   *
4:   * $Id: capture_dlg.c,v 1.69 2002/06/24 20:56:15 guy Exp $
5:   *
6:   * Ethereal - Network traffic analyzer
7:   * By Gerald Combs <gerald@xxxxxxxxxxxx>
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 <stdlib.h>
32: #include <stdio.h>
33: #include <string.h>
34: #include <gtk/gtk.h>
35: 
36: #ifdef HAVE_UNISTD_H
37: #include <unistd.h>
38: #endif
39: 
40: #include <time.h>
41: 
42: #include <pcap.h>
43: 
44: #ifdef NEED_SNPRINTF_H
45: # include "snprintf.h"
46: #endif
47: 
48: #include "capture.h"
49: #include "capture_remote.h"
49: #include "globals.h"
50: #include <epan/resolv.h>
51: #include "main.h"
52: #include "ui_util.h"
53: #include "capture_dlg.h"
54: #include "filter_prefs.h"
55: #include "simple_dialog.h"
56: #include "dlg_utils.h"
57: #include "pcap-util.h"
58: #include "prefs.h"
59: #include "ringbuffer.h"
60: 
61: #ifdef _WIN32
62: #include "capture-wpcap.h"
63: #endif
64: 
65: /* Capture callback data keys */
66: #define E_CAP_IFACE_KEY       "cap_iface"
67: #define E_CAP_SNAP_CB_KEY     "cap_snap_cb"
68: #define E_CAP_SNAP_SB_KEY     "cap_snap_sb"
69: #define E_CAP_PROMISC_KEY     "cap_promisc"
70: #define E_CAP_FILT_KEY        "cap_filter_te"
72: #define E_CAP_IPADDR_TE_KEY   "cap_ipaddr_te"
73: #define E_CAP_V5_IF_TE_KEY    "cap_v5_if_te"
71: #define E_CAP_FILE_TE_KEY     "cap_file_te"
72: #define E_CAP_RING_ON_TB_KEY  "cap_ringbuffer_on_tb"
73: #define E_CAP_RING_NBF_LB_KEY "cap_ringbuffer_nbf_lb"
74: #define E_CAP_RING_NBF_SB_KEY "cap_ringbuffer_nbf_sb"
75: #define E_CAP_SYNC_KEY        "cap_sync"
76: #define E_CAP_AUTO_SCROLL_KEY "cap_auto_scroll"
77: #define E_CAP_COUNT_CB_KEY    "cap_count_cb"
78: #define E_CAP_COUNT_SB_KEY    "cap_count_sb"
79: #define E_CAP_FILESIZE_CB_KEY "cap_filesize_cb"
80: #define E_CAP_FILESIZE_SB_KEY "cap_filesize_sb"
81: #define E_CAP_FILESIZE_LB_KEY "cap_filesize_lb"
82: #define E_CAP_DURATION_CB_KEY "cap_duration_cb"
83: #define E_CAP_DURATION_SB_KEY "cap_duration_sb"
84: #define E_CAP_M_RESOLVE_KEY   "cap_m_resolve"
85: #define E_CAP_N_RESOLVE_KEY   "cap_n_resolve"
86: #define E_CAP_T_RESOLVE_KEY   "cap_t_resolve"
87: 
88: #define E_FS_CALLER_PTR_KEY       "fs_caller_ptr"
89: #define E_FILE_SEL_DIALOG_PTR_KEY "file_sel_dialog_ptr"
90: 
91: static void
92: capture_prep_file_cb(GtkWidget *w, gpointer te);
93: 
94: static void
95: cap_prep_fs_ok_cb(GtkWidget *w, gpointer data);
96: 
97: static void
98: cap_prep_fs_cancel_cb(GtkWidget *w, gpointer data);
99: 
100:    static void
101:    cap_prep_fs_destroy_cb(GtkWidget *win, gpointer data);
102:    
103:    static void
104:    capture_prep_adjust_sensitivity(GtkWidget *tb, gpointer parent_w);
105:    
106:    static void
107:    capture_prep_ok_cb(GtkWidget *ok_bt, gpointer parent_w);
108:    
109:    static void
110:    capture_prep_close_cb(GtkWidget *close_bt, gpointer parent_w);
111:    
112:    static void
113:    capture_prep_destroy_cb(GtkWidget *win, gpointer user_data);
114:    
115:    void
116:    capture_stop_cb(GtkWidget *w _U_, gpointer d _U_)
117:    {
118:        capture_stop();
119:    }
120:    
121:    /*
122:     * Keep a static pointer to the current "Capture Options" window, if
123:     * any, so that if somebody tries to do "Capture:Start" while there's
124:     * already a "Capture Options" window up, we just pop up the existing
125:     * one, rather than creating a new one.
126:     */
127:    static GtkWidget *cap_open_w;
128:    
129:    void
130:    capture_prep_cb(GtkWidget *w _U_, gpointer d _U_)
131:    {
132:      GtkWidget     *main_vb,
133:                    *capture_fr, *capture_vb,
134:                    *if_hb, *if_cb, *if_lb,
135:                    *snap_hb, *snap_cb, *snap_sb, *snap_lb,
136:                    *promisc_cb,
137:                    *filter_hb, *filter_bt, *filter_te,
141:                    *remote_snoop_fr, *remote_snoop_vb,
142:                    *ipaddr_hb, *ipaddr_lb, *ipaddr_te,
143:                    *v5_if_hb, *v5_if_lb, *v5_if_te,
138:                    *file_fr, *file_vb,
139:                    *file_hb, *file_bt, *file_te,
140:                    *ringbuffer_hb, *ringbuffer_on_tb, *ringbuffer_nbf_lb, *ringbuffer_nbf_sb,
141:                    *display_fr, *display_vb,
142:                    *sync_cb, *auto_scroll_cb,
143:                    *limit_fr, *limit_vb,
144:                    *count_hb, *count_cb, *count_sb, *count_lb,
145:                    *filesize_hb, *filesize_cb, *filesize_sb, *filesize_lb,
146:                    *duration_hb, *duration_cb, *duration_sb, *duration_lb,
147:                    *resolv_fr, *resolv_vb,
148:                    *m_resolv_cb, *n_resolv_cb, *t_resolv_cb,
149:                    *bbox, *ok_bt, *cancel_bt;
150:      GtkAccelGroup *accel_group;
151:      GtkAdjustment *snap_adj, *ringbuffer_nbf_adj,
152:                    *count_adj, *filesize_adj, *duration_adj;
153:      GList         *if_list;
154:      int           err;
155:      char          err_str[PCAP_ERRBUF_SIZE];
156:    
157:      if (cap_open_w != NULL) {
158:        /* There's already a "Capture Options" dialog box; reactivate it. */
159:        reactivate_window(cap_open_w);
160:        return;
161:      }
162:    
163:    #ifdef _WIN32
164:      /* Is WPcap loaded? */
165:      if (!has_wpcap) {
166:          simple_dialog(ESD_TYPE_CRIT, NULL,
167:              "Unable to load WinPcap (wpcap.dll); Ethereal will not be able\n"
168:              "to capture packets.\n\n"
169:              "In order to capture packets, WinPcap must be installed; see\n"
170:              "\n"
171:              "        http://winpcap.polito.it/\n"
172:              "\n"
173:              "or the mirror at\n"
174:              "\n"
175:              "        http://winpcap.mirror.ethereal.com/\n"
176:              "\n"
177:              "or the mirror at\n"
178:              "\n"
179:              "        http://www.mirrors.wiretapped.net/security/packet-capture/winpcap/\n"
180:              "\n"
181:              "for a downloadable version of WinPcap and for instructions\n"
182:              "on how to install WinPcap.");
183:          return;
184:      }
185:    #endif
186:    
187:      if_list = get_interface_list(&err, err_str);
188:      if (if_list == NULL && err == CANT_GET_INTERFACE_LIST) {
189:        simple_dialog(ESD_TYPE_WARN, NULL, "Can't get list of interfaces: %s",
190:                err_str);
191:      }
192:      
193:      cap_open_w = dlg_window_new("Ethereal: Capture Options");
194:      gtk_signal_connect(GTK_OBJECT(cap_open_w), "destroy",
195:        GTK_SIGNAL_FUNC(capture_prep_destroy_cb), NULL);
196:    
197:      /* Accelerator group for the accelerators (or, as they're called in
198:         Windows and, I think, in Motif, "mnemonics"; Alt+<key> is a mnemonic,
199:         Ctrl+<key> is an accelerator). */
200:      accel_group = gtk_accel_group_new();
201:      gtk_window_add_accel_group(GTK_WINDOW(cap_open_w), accel_group);
202:      
203:      main_vb = gtk_vbox_new(FALSE, 0);
204:      gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
205:      gtk_container_add(GTK_CONTAINER(cap_open_w), main_vb);
206:      gtk_widget_show(main_vb);
207:      
208:      /* Capture-related options frame */
209:      capture_fr = gtk_frame_new("Capture");
210:      gtk_container_add(GTK_CONTAINER(main_vb), capture_fr);
211:      gtk_widget_show(capture_fr);
212:    
213:      capture_vb = gtk_vbox_new(FALSE, 0);
214:      gtk_container_add(GTK_CONTAINER(capture_fr), capture_vb);
215:      gtk_widget_show(capture_vb);
216:    
217:      /* Interface row */
218:      if_hb = gtk_hbox_new(FALSE, 3);
219:      gtk_container_add(GTK_CONTAINER(capture_vb), if_hb);
220:      gtk_widget_show(if_hb);
221:    
222:      if_lb = gtk_label_new("Interface:");
223:      gtk_box_pack_start(GTK_BOX(if_hb), if_lb, FALSE, FALSE, 6);
224:      gtk_widget_show(if_lb);
225:      
226:      if_cb = gtk_combo_new();
227:      if (if_list != NULL)
228:        gtk_combo_set_popdown_strings(GTK_COMBO(if_cb), if_list);
229:      if (cfile.iface == NULL && prefs.capture_device != NULL) {
230:        /* No interface was specified on the command line or in a previous
231:           capture, but there is one specified in the preferences file;
232:           make the one from the preferences file the default */
233:        cfile.iface = g_strdup(prefs.capture_device);
234:      }
235:      if (cfile.iface != NULL)
236:        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry), cfile.iface);
237:      else if (if_list != NULL)
238:        gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry), if_list->data);
239:      gtk_box_pack_start(GTK_BOX(if_hb), if_cb, TRUE, TRUE, 6);
240:      gtk_widget_show(if_cb);
241:      
242:      free_interface_list(if_list);
243:    
244:      /* Capture length row */
245:      snap_hb = gtk_hbox_new(FALSE, 3);
246:      gtk_container_add(GTK_CONTAINER(capture_vb), snap_hb);
247:      gtk_widget_show(snap_hb);
248:    
249:      snap_cb = dlg_check_button_new_with_label_with_mnemonic(
250:            "_Limit each packet to", accel_group);
251:      gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(snap_cb),
252:            capture_opts.has_snaplen);
253:      gtk_signal_connect(GTK_OBJECT(snap_cb), "toggled",
254:        GTK_SIGNAL_FUNC(capture_prep_adjust_sensitivity), GTK_OBJECT(cap_open_w));
255:      gtk_box_pack_start(GTK_BOX(snap_hb), snap_cb, FALSE, FALSE, 0);
256:      gtk_widget_show(snap_cb);
257:    
258:      snap_adj = (GtkAdjustment *) gtk_adjustment_new((float) capture_opts.snaplen,
259:        MIN_PACKET_SIZE, WTAP_MAX_PACKET_SIZE, 1.0, 10.0, 0.0);
260:      snap_sb = gtk_spin_button_new (snap_adj, 0, 0);
261:      gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (snap_sb), TRUE);
262:      gtk_widget_set_usize (snap_sb, 80, 0);
263:      gtk_box_pack_start (GTK_BOX(snap_hb), snap_sb, FALSE, FALSE, 0); 
264:      gtk_widget_show(snap_sb);
265:      
266:      snap_lb = gtk_label_new("bytes");
267:      gtk_misc_set_alignment(GTK_MISC(snap_lb), 0, 0.5);
268:      gtk_box_pack_start(GTK_BOX(snap_hb), snap_lb, FALSE, FALSE, 0);
269:      gtk_widget_show(snap_lb);
270:    
271:      /* Promiscuous mode row */
272:      promisc_cb = dlg_check_button_new_with_label_with_mnemonic(
273:            "Capture packets in _promiscuous mode", accel_group);
274:      gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(promisc_cb),
275:            capture_opts.promisc_mode);
276:      gtk_container_add(GTK_CONTAINER(capture_vb), promisc_cb);
277:      gtk_widget_show(promisc_cb);
278:    
279:      /* Filter row */
280:      filter_hb = gtk_hbox_new(FALSE, 3);
281:      gtk_container_add(GTK_CONTAINER(capture_vb), filter_hb);
282:      gtk_widget_show(filter_hb);
283:    
284:      filter_bt = gtk_button_new_with_label("Filter:");
285:      gtk_signal_connect(GTK_OBJECT(filter_bt), "clicked",
286:        GTK_SIGNAL_FUNC(capture_filter_construct_cb), NULL);
287:      gtk_box_pack_start(GTK_BOX(filter_hb), filter_bt, FALSE, FALSE, 3); 
288:      gtk_widget_show(filter_bt);
289:      
290:      filter_te = gtk_entry_new();
291:      if (cfile.cfilter) gtk_entry_set_text(GTK_ENTRY(filter_te), cfile.cfilter);
292:      gtk_object_set_data(GTK_OBJECT(filter_bt), E_FILT_TE_PTR_KEY, filter_te);
293:      gtk_box_pack_start(GTK_BOX(filter_hb), filter_te, TRUE, TRUE, 3); 
294:      gtk_widget_show(filter_te);
295:      
302:      /* Remote Snoop frame */
303:    
304:      remote_snoop_fr = gtk_frame_new("Remote Snoop");
305:      gtk_container_add(GTK_CONTAINER(main_vb), remote_snoop_fr);
306:      gtk_widget_show(remote_snoop_fr);
307:    
308:      remote_snoop_vb = gtk_vbox_new(FALSE, 0);
309:      gtk_container_add(GTK_CONTAINER(remote_snoop_fr), remote_snoop_vb);
310:      gtk_widget_show(remote_snoop_vb);
311:    
312:      /* IP address row */
313:    
314:      ipaddr_hb = gtk_hbox_new(FALSE, 3);
315:      gtk_container_add(GTK_CONTAINER(remote_snoop_vb), ipaddr_hb);
316:      gtk_widget_show(ipaddr_hb);
317:    
318:      ipaddr_lb = gtk_label_new("IP address:");
319:      gtk_box_pack_start(GTK_BOX(ipaddr_hb), ipaddr_lb, FALSE, FALSE, 6);
320:      gtk_widget_show(ipaddr_lb);
321:      
322:      ipaddr_te = gtk_entry_new();
323:      gtk_box_pack_start(GTK_BOX(ipaddr_hb), ipaddr_te, TRUE, TRUE, 3); 
324:      gtk_widget_show(ipaddr_te);
325:    
326:      /* V5 Interface row*/
327:    
328:      v5_if_hb = gtk_hbox_new(FALSE, 3);
329:      gtk_container_add(GTK_CONTAINER(remote_snoop_vb), v5_if_hb);
330:      gtk_widget_show(v5_if_hb);
331:    
332:      v5_if_lb = gtk_label_new("V5 Interface:");
333:      gtk_box_pack_start(GTK_BOX(v5_if_hb), v5_if_lb, FALSE, FALSE, 6);
334:      gtk_widget_show(v5_if_lb);
335:      
336:      v5_if_te = gtk_entry_new();
337:      gtk_box_pack_start(GTK_BOX(v5_if_hb), v5_if_te, TRUE, TRUE, 3); 
338:      gtk_widget_show(v5_if_te);
339:      
340:      
296:      /* Capture file-related options frame */
297:      file_fr = gtk_frame_new("Capture file(s)");
298:      gtk_container_add(GTK_CONTAINER(main_vb), file_fr);
299:      gtk_widget_show(file_fr);
300:    
301:      file_vb = gtk_vbox_new(FALSE, 3);
302:      gtk_container_add(GTK_CONTAINER(file_fr), file_vb);
303:      gtk_widget_show(file_vb);
304:    
305:      /* File row */
306:      file_hb = gtk_hbox_new(FALSE, 3);
307:      gtk_container_add(GTK_CONTAINER(file_vb), file_hb);
308:      gtk_widget_show(file_hb);
309:    
310:      file_bt = gtk_button_new_with_label("File:");
311:      gtk_box_pack_start(GTK_BOX(file_hb), file_bt, FALSE, FALSE, 3); 
312:      gtk_widget_show(file_bt);
313:      
314:      file_te = gtk_entry_new();
315:      gtk_box_pack_start(GTK_BOX(file_hb), file_te, TRUE, TRUE, 3); 
316:      gtk_widget_show(file_te);
317:    
318:      gtk_signal_connect(GTK_OBJECT(file_bt), "clicked",
319:        GTK_SIGNAL_FUNC(capture_prep_file_cb), GTK_OBJECT(file_te));
320:    
321:      /* Ring buffer row */
322:      ringbuffer_hb = gtk_hbox_new(FALSE, 3);
323:      gtk_container_add(GTK_CONTAINER(file_vb), ringbuffer_hb);
324:      gtk_widget_show(ringbuffer_hb);
325:    
326:      ringbuffer_on_tb = dlg_check_button_new_with_label_with_mnemonic(
327:        "Use _ring buffer", accel_group);
328:      /* Ring buffer mode is allowed only if we're not doing an "Update list of
329:         packets in real time" capture, so force it off if we're doing such
330:         a capture. */
331:      if (capture_opts.sync_mode)
332:        capture_opts.ringbuffer_on = FALSE;
333:      gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(ringbuffer_on_tb),
334:            capture_opts.ringbuffer_on);
335:      gtk_signal_connect(GTK_OBJECT(ringbuffer_on_tb), "toggled",
336:        GTK_SIGNAL_FUNC(capture_prep_adjust_sensitivity), GTK_OBJECT(cap_open_w));
337:      gtk_box_pack_start(GTK_BOX(ringbuffer_hb), ringbuffer_on_tb, FALSE, FALSE, 0);
338:      gtk_widget_show(ringbuffer_on_tb);
339:      
340:      ringbuffer_nbf_lb = gtk_label_new("Number of files");
341:      gtk_misc_set_alignment(GTK_MISC(ringbuffer_nbf_lb), 1, 0.5);
342:      gtk_box_pack_start(GTK_BOX(ringbuffer_hb), ringbuffer_nbf_lb, FALSE, FALSE, 6);
343:      gtk_widget_show(ringbuffer_nbf_lb);
344:    
345:      ringbuffer_nbf_adj = (GtkAdjustment *) gtk_adjustment_new((float) capture_opts.ringbuffer_num_files,
346:        RINGBUFFER_MIN_NUM_FILES, RINGBUFFER_MAX_NUM_FILES, 1.0, 10.0, 0.0);
347:      ringbuffer_nbf_sb = gtk_spin_button_new (ringbuffer_nbf_adj, 0, 0);
348:      gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (ringbuffer_nbf_sb), TRUE);
349:      gtk_widget_set_usize (ringbuffer_nbf_sb, 40, 0);
350:      gtk_box_pack_start (GTK_BOX(ringbuffer_hb), ringbuffer_nbf_sb, TRUE, TRUE, 0); 
351:      gtk_widget_show(ringbuffer_nbf_sb);
352:      
353:      /* Display-related options frame */
354:      display_fr = gtk_frame_new("Display options");
355:      gtk_container_add(GTK_CONTAINER(main_vb), display_fr);
356:      gtk_widget_show(display_fr);
357:    
358:      display_vb = gtk_vbox_new(FALSE, 0);
359:      gtk_container_add(GTK_CONTAINER(display_fr), display_vb);
360:      gtk_widget_show(display_vb);
361:    
362:      /* "Update display in real time" row */
363:      sync_cb = dlg_check_button_new_with_label_with_mnemonic(
364:            "_Update list of packets in real time", accel_group);
365:      gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(sync_cb),
366:            capture_opts.sync_mode);
367:      gtk_signal_connect(GTK_OBJECT(sync_cb), "toggled",
368:        GTK_SIGNAL_FUNC(capture_prep_adjust_sensitivity), GTK_OBJECT(cap_open_w));
369:      gtk_container_add(GTK_CONTAINER(display_vb), sync_cb);
370:      gtk_widget_show(sync_cb);
371:    
372:      /* "Auto-scroll live update" row */
373:      auto_scroll_cb = dlg_check_button_new_with_label_with_mnemonic(
374:            "_Automatic scrolling in live capture", accel_group);
375:      gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(auto_scroll_cb), auto_scroll_live);
376:      gtk_container_add(GTK_CONTAINER(display_vb), auto_scroll_cb);
377:      gtk_widget_show(auto_scroll_cb);
378:    
379:      /* Capture limits frame */
380:      limit_fr = gtk_frame_new("Capture limits");
381:      gtk_container_add(GTK_CONTAINER(main_vb), limit_fr);
382:      gtk_widget_show(limit_fr);
383:    
384:      limit_vb = gtk_vbox_new(FALSE, 0);
385:      gtk_container_add(GTK_CONTAINER(limit_fr), limit_vb);
386:      gtk_widget_show(limit_vb);
387:    
388:      /* Count row */
389:      count_hb = gtk_hbox_new(FALSE, 3);
390:      gtk_container_add(GTK_CONTAINER(limit_vb), count_hb);
391:      gtk_widget_show(count_hb);
392:    
393:      count_cb = gtk_check_button_new_with_label("Stop capture after");
394:      gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(count_cb),
395:            capture_opts.has_autostop_count);
396:      gtk_signal_connect(GTK_OBJECT(count_cb), "toggled",
397:        GTK_SIGNAL_FUNC(capture_prep_adjust_sensitivity), GTK_OBJECT(cap_open_w));
398:      gtk_box_pack_start(GTK_BOX(count_hb), count_cb, FALSE, FALSE, 0);
399:      gtk_widget_show(count_cb);
400:    
401:      count_adj = (GtkAdjustment *) gtk_adjustment_new(capture_opts.autostop_count,
402:        1, INT_MAX, 1.0, 10.0, 0.0);
403:      count_sb = gtk_spin_button_new (count_adj, 0, 0);
404:      gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (count_sb), TRUE);
405:      gtk_widget_set_usize (count_sb, 80, 0);
406:      gtk_box_pack_start (GTK_BOX(count_hb), count_sb, FALSE, FALSE, 0); 
407:      gtk_widget_show(count_sb);
408:      
409:      count_lb = gtk_label_new("packet(s) captured");
410:      gtk_misc_set_alignment(GTK_MISC(count_lb), 0, 0.5);
411:      gtk_box_pack_start(GTK_BOX(count_hb), count_lb, FALSE, FALSE, 0);
412:      gtk_widget_show(count_lb);
413:      
414:      /* Filesize row */
415:      filesize_hb = gtk_hbox_new(FALSE, 3);
416:      gtk_container_add(GTK_CONTAINER(limit_vb), filesize_hb);
417:      gtk_widget_show(filesize_hb);
418:    
419:      filesize_cb = gtk_check_button_new_with_label("");
420:      gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(filesize_cb),
421:            capture_opts.has_autostop_filesize);
422:      gtk_signal_connect(GTK_OBJECT(filesize_cb), "toggled",
423:        GTK_SIGNAL_FUNC(capture_prep_adjust_sensitivity), GTK_OBJECT(cap_open_w));
424:      gtk_box_pack_start(GTK_BOX(filesize_hb), filesize_cb, FALSE, FALSE, 0);
425:      gtk_widget_show(filesize_cb);
426:    
427:      filesize_adj = (GtkAdjustment *) gtk_adjustment_new(capture_opts.autostop_filesize,
428:        1, INT_MAX, 1.0, 10.0, 0.0);
429:      filesize_sb = gtk_spin_button_new (filesize_adj, 0, 0);
430:      gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (filesize_sb), TRUE);
431:      gtk_widget_set_usize (filesize_sb, 80, 0);
432:      gtk_box_pack_start (GTK_BOX(filesize_hb), filesize_sb, FALSE, FALSE, 0); 
433:      gtk_widget_show(filesize_sb);
434:      
435:      filesize_lb = gtk_label_new("");
436:      gtk_misc_set_alignment(GTK_MISC(filesize_lb), 0, 0.5);
437:      gtk_box_pack_start(GTK_BOX(filesize_hb), filesize_lb, FALSE, FALSE, 0);
438:      gtk_widget_show(filesize_lb);
439:      
440:      /* Duration row */
441:      duration_hb = gtk_hbox_new(FALSE, 3);
442:      gtk_container_add(GTK_CONTAINER(limit_vb), duration_hb);
443:      gtk_widget_show(duration_hb);
444:    
445:      duration_cb = gtk_check_button_new_with_label("Stop capture after");
446:      gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(duration_cb),
447:            capture_opts.has_autostop_duration);
448:      gtk_signal_connect(GTK_OBJECT(duration_cb), "toggled",
449:        GTK_SIGNAL_FUNC(capture_prep_adjust_sensitivity), GTK_OBJECT(cap_open_w));
450:      gtk_box_pack_start(GTK_BOX(duration_hb), duration_cb, FALSE, FALSE, 0);
451:      gtk_widget_show(duration_cb);
452:    
453:      duration_adj = (GtkAdjustment *) gtk_adjustment_new(capture_opts.autostop_duration,
454:        1, INT_MAX, 1.0, 10.0, 0.0);
455:      duration_sb = gtk_spin_button_new (duration_adj, 0, 0);
456:      gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (duration_sb), TRUE);
457:      gtk_widget_set_usize (duration_sb, 80, 0);
458:      gtk_box_pack_start (GTK_BOX(duration_hb), duration_sb, FALSE, FALSE, 0); 
459:      gtk_widget_show(duration_sb);
460:      
461:      duration_lb = gtk_label_new("second(s)");
462:      gtk_misc_set_alignment(GTK_MISC(duration_lb), 0, 0.5);
463:      gtk_box_pack_start(GTK_BOX(duration_hb), duration_lb, FALSE, FALSE, 0);
464:      gtk_widget_show(duration_lb);
465:      
466:      /* Resolution options frame */
467:      resolv_fr = gtk_frame_new("Name resolution");
468:      gtk_container_add(GTK_CONTAINER(main_vb), resolv_fr);
469:      gtk_widget_show(resolv_fr);
470:    
471:      resolv_vb = gtk_vbox_new(FALSE, 0);
472:      gtk_container_add(GTK_CONTAINER(resolv_fr), resolv_vb);
473:      gtk_widget_show(resolv_vb);
474:    
475:      m_resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
476:            "Enable _MAC name resolution", accel_group);
477:      gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(m_resolv_cb),
478:            g_resolv_flags & RESOLV_MAC);
479:      gtk_container_add(GTK_CONTAINER(resolv_vb), m_resolv_cb);
480:      gtk_widget_show(m_resolv_cb);
481:    
482:      n_resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
483:            "Enable _network name resolution", accel_group);
484:      gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(n_resolv_cb),
485:            g_resolv_flags & RESOLV_NETWORK);
486:      gtk_container_add(GTK_CONTAINER(resolv_vb), n_resolv_cb);
487:      gtk_widget_show(n_resolv_cb);
488:    
489:      t_resolv_cb = dlg_check_button_new_with_label_with_mnemonic(
490:            "Enable _transport name resolution", accel_group);
491:      gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(t_resolv_cb),
492:            g_resolv_flags & RESOLV_TRANSPORT);
493:      gtk_container_add(GTK_CONTAINER(resolv_vb), t_resolv_cb);
494:      gtk_widget_show(t_resolv_cb);
495:      
496:      /* Button row: OK and cancel buttons */
497:      bbox = gtk_hbutton_box_new();
498:      gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
499:      gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
500:      gtk_container_add(GTK_CONTAINER(main_vb), bbox);
501:      gtk_widget_show(bbox);
502:    
503:      ok_bt = gtk_button_new_with_label ("OK");
504:      gtk_signal_connect(GTK_OBJECT(ok_bt), "clicked",
505:        GTK_SIGNAL_FUNC(capture_prep_ok_cb), GTK_OBJECT(cap_open_w));
506:      GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT);
507:      gtk_box_pack_start (GTK_BOX (bbox), ok_bt, TRUE, TRUE, 0);
508:      gtk_widget_grab_default(ok_bt);
509:      gtk_widget_show(ok_bt);
510:    
511:      cancel_bt = gtk_button_new_with_label ("Cancel");
512:      gtk_signal_connect(GTK_OBJECT(cancel_bt), "clicked",
513:        GTK_SIGNAL_FUNC(capture_prep_close_cb), GTK_OBJECT(cap_open_w));
514:      GTK_WIDGET_SET_FLAGS(cancel_bt, GTK_CAN_DEFAULT);
515:      gtk_box_pack_start (GTK_BOX (bbox), cancel_bt, TRUE, TRUE, 0);
516:      gtk_widget_show(cancel_bt);
517:    
518:      /* Attach pointers to needed widgets to the capture prefs window/object */
519:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_IFACE_KEY, if_cb);
520:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_SNAP_CB_KEY, snap_cb);
521:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_SNAP_SB_KEY, snap_sb);
522:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_PROMISC_KEY, promisc_cb);
523:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILT_KEY,  filter_te);
569:    
570:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_IPADDR_TE_KEY,  ipaddr_te);
571:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_V5_IF_TE_KEY,  v5_if_te);
572:    
524:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILE_TE_KEY,  file_te);
525:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_RING_ON_TB_KEY,  ringbuffer_on_tb);
526:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_RING_NBF_LB_KEY,  ringbuffer_nbf_lb);
527:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_RING_NBF_SB_KEY,  ringbuffer_nbf_sb);
528:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_SYNC_KEY,  sync_cb);
529:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_AUTO_SCROLL_KEY, auto_scroll_cb);
530:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_COUNT_CB_KEY, count_cb);
531:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_COUNT_SB_KEY, count_sb);
532:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILESIZE_CB_KEY, filesize_cb);
533:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILESIZE_SB_KEY, filesize_sb);
534:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_FILESIZE_LB_KEY, filesize_lb);
535:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_DURATION_CB_KEY,  duration_cb);
536:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_DURATION_SB_KEY,  duration_sb);
537:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_M_RESOLVE_KEY,  m_resolv_cb);
538:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_N_RESOLVE_KEY,  n_resolv_cb);
539:      gtk_object_set_data(GTK_OBJECT(cap_open_w), E_CAP_T_RESOLVE_KEY,  t_resolv_cb);
540:    
541:      /* Set the sensitivity of various widgets as per the settings of other
542:         widgets. */
543:      capture_prep_adjust_sensitivity(NULL, cap_open_w);
544:    
545:      /* Catch the "activate" signal on the frame number and file name text
546:         entries, so that if the user types Return there, we act as if the
547:         "OK" button had been selected, as happens if Return is typed if some
548:         widget that *doesn't* handle the Return key has the input focus. */
549:      dlg_set_activate(filter_te, ok_bt);
550:      dlg_set_activate(file_te, ok_bt);
551:    
601:      dlg_set_activate(ipaddr_te, ok_bt);
602:      dlg_set_activate(v5_if_te, ok_bt);
603:    
604:    
552:      /* Catch the "key_press_event" signal in the window, so that we can catch
553:         the ESC key being pressed and act as if the "Cancel" button had
554:         been selected. */
555:      dlg_set_cancel(cap_open_w, cancel_bt);
556:    
557:      /* XXX - why does not
558:    
559:         gtk_widget_grab_focus(if_cb);
560:    
561:        give the initial focus to the "Interface" combo box?
562:    
563:        Or should I phrase that as "why does GTK+ continually frustrate
564:        attempts to make GUIs driveable from the keyboard?"  We have to
565:        go catch the activate signal on every single GtkEntry widget
566:        (rather than having widgets whose activate signal is *not*
567:        caught not catch the Return keystroke, so that it passes on,
568:        ultimately, to the window, which can activate the default
569:        widget, i.e. the "OK" button); we have to catch the "key_press_event"
570:        signal and have the handler check for ESC, so that we can have ESC
571:        activate the "Cancel" button; in order to support Alt+<key> mnemonics
572:        for buttons and the like, we may have to construct an accelerator
573:        group by hand and set up the accelerators by hand (if that even
574:        works - I've not tried it yet); we have to do a "gtk_widget_grab_focus()"
575:        to keep some container widget from getting the initial focus, so that
576:        you don't have to tab into the first widget in order to start typing
577:        in it; and it now appears that you simply *can't* make a combo box
578:        get the initial focus, at least not in the obvious fashion. Sigh.... */
579:    
580:      gtk_widget_show(cap_open_w);
581:    }
582:    
583:    static void
584:    capture_prep_file_cb(GtkWidget *w, gpointer file_te)
585:    {
586:      GtkWidget *caller = gtk_widget_get_toplevel(w);
587:      GtkWidget *fs;
588:    
589:      /* Has a file selection dialog box already been opened for that top-level
590:         widget? */
591:      fs = gtk_object_get_data(GTK_OBJECT(caller), E_FILE_SEL_DIALOG_PTR_KEY);
592:    
593:      if (fs != NULL) {
594:        /* Yes.  Just re-activate that dialog box. */
595:        reactivate_window(fs);
596:        return;
597:      }
598:    
599:      fs = gtk_file_selection_new ("Ethereal: Capture File");
600:    
601:      gtk_object_set_data(GTK_OBJECT(fs), E_CAP_FILE_TE_KEY, file_te);
602:    
603:      /* Set the E_FS_CALLER_PTR_KEY for the new dialog to point to our caller. */
604:      gtk_object_set_data(GTK_OBJECT(fs), E_FS_CALLER_PTR_KEY, caller);
605:    
606:      /* Set the E_FILE_SEL_DIALOG_PTR_KEY for the caller to point to us */
607:      gtk_object_set_data(GTK_OBJECT(caller), E_FILE_SEL_DIALOG_PTR_KEY, fs);
608:    
609:      /* Call a handler when the file selection box is destroyed, so we can inform
610:         our caller, if any, that it's been destroyed. */
611:      gtk_signal_connect(GTK_OBJECT(fs), "destroy",
612:            GTK_SIGNAL_FUNC(cap_prep_fs_destroy_cb), NULL);
613:    
614:      gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(fs)->ok_button),
615:        "clicked", (GtkSignalFunc) cap_prep_fs_ok_cb, fs);
616:    
617:      /* Connect the cancel_button to destroy the widget */
618:      gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(fs)->cancel_button),
619:        "clicked", (GtkSignalFunc) cap_prep_fs_cancel_cb, fs);
620:    
621:      /* Catch the "key_press_event" signal in the window, so that we can catch
622:         the ESC key being pressed and act as if the "Cancel" button had
623:         been selected. */
624:      dlg_set_cancel(fs, GTK_FILE_SELECTION(fs)->cancel_button);
625:      
626:      gtk_widget_show(fs);
627:    }
628:    
629:    static void
630:    cap_prep_fs_ok_cb(GtkWidget *w _U_, gpointer data)
631:    {
632:      gtk_entry_set_text(GTK_ENTRY(gtk_object_get_data(GTK_OBJECT(data),
633:          E_CAP_FILE_TE_KEY)),
634:          gtk_file_selection_get_filename (GTK_FILE_SELECTION(data)));
635:      gtk_widget_destroy(GTK_WIDGET(data));
636:    }
637:    
638:    static void
639:    cap_prep_fs_cancel_cb(GtkWidget *w _U_, gpointer data)
640:    {
641:      gtk_widget_destroy(GTK_WIDGET(data));
642:    }  
643:    
644:    static void
645:    cap_prep_fs_destroy_cb(GtkWidget *win, gpointer data _U_)
646:    {
647:      GtkWidget *caller;
648:    
649:      /* Get the widget that requested that we be popped up.
650:         (It should arrange to destroy us if it's destroyed, so
651:         that we don't get a pointer to a non-existent window here.) */
652:      caller = gtk_object_get_data(GTK_OBJECT(win), E_FS_CALLER_PTR_KEY);
653:    
654:      /* Tell it we no longer exist. */
655:      gtk_object_set_data(GTK_OBJECT(caller), E_FILE_SEL_DIALOG_PTR_KEY, NULL);
656:    
657:      /* Now nuke this window. */
658:      gtk_grab_remove(GTK_WIDGET(win));
659:      gtk_widget_destroy(GTK_WIDGET(win));
660:    }
661:    
662:    static void
663:    capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
664:      GtkWidget *if_cb, *snap_cb, *snap_sb, *promisc_cb, *filter_te,
665:                *file_te, *ringbuffer_on_tb, *ringbuffer_nbf_sb,
719:                *ipaddr_te, *v5_if_te, *file_te, *ringbuffer_on_tb, 
720:                *ringbuffer_nbf_sb,
666:                *sync_cb, *auto_scroll_cb,
667:                *count_cb, *count_sb,
668:                *filesize_cb, *filesize_sb,
669:                *duration_cb, *duration_sb,
670:                *m_resolv_cb, *n_resolv_cb, *t_resolv_cb;
671:      gchar *if_text;
672:      gchar *if_name;
673:      gchar *filter_text;
729:      gchar *ipaddr_text;
730:      gchar *v5_if_text;
674:      gchar *save_file;
675:    
676:      if_cb     = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_IFACE_KEY);
677:      snap_cb   = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SNAP_CB_KEY);
678:      snap_sb   = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SNAP_SB_KEY);
679:      promisc_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_PROMISC_KEY);
680:      filter_te = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILT_KEY);
739:      
740:      ipaddr_te = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_IPADDR_TE_KEY);
741:      v5_if_te   = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_V5_IF_TE_KEY);
742:      
681:      file_te   = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILE_TE_KEY);
682:      ringbuffer_on_tb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_RING_ON_TB_KEY);
683:      ringbuffer_nbf_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_RING_NBF_SB_KEY);
684:      sync_cb   = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SYNC_KEY);
685:      auto_scroll_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_AUTO_SCROLL_KEY);
686:      count_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_COUNT_CB_KEY);
687:      count_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_COUNT_SB_KEY);
688:      filesize_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILESIZE_CB_KEY);
689:      filesize_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILESIZE_SB_KEY);
690:      duration_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_DURATION_CB_KEY);
691:      duration_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_DURATION_SB_KEY);
692:      m_resolv_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_M_RESOLVE_KEY);
693:      n_resolv_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_N_RESOLVE_KEY);
694:      t_resolv_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_T_RESOLVE_KEY);
695:    
696:      if_text =
697:        g_strdup(gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(if_cb)->entry)));
698:      /* Windows combo entries have a description followed by the interface name */
699:      if_name = strrchr(if_text, ' ');
700:      if (if_name == NULL) {
701:        if_name = if_text;
702:      } else {
703:        if_name++;
704:      }
705:      if (if_name == NULL) {
706:        simple_dialog(ESD_TYPE_CRIT, NULL,
707:          "You didn't specify an interface on which to capture packets.");
708:        g_free(if_text);
709:        return;
710:      }
711:      if (cfile.iface)
712:        g_free(cfile.iface);
713:      cfile.iface = g_strdup(if_name);
714:      g_free(if_text);
715:    
716:      capture_opts.has_snaplen =
717:        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb));
718:      if (capture_opts.has_snaplen) {
719:        capture_opts.snaplen =
720:          gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(snap_sb));
721:        if (capture_opts.snaplen < 1)
722:          capture_opts.snaplen = WTAP_MAX_PACKET_SIZE;
723:        else if (capture_opts.snaplen < MIN_PACKET_SIZE)
724:          capture_opts.snaplen = MIN_PACKET_SIZE;
725:      }
726:    
727:      capture_opts.promisc_mode =
728:        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(promisc_cb));
729:    
730:      /* XXX - don't try to get clever and set "cfile.filter" to NULL if the
731:         filter string is empty, as an indication that we don't have a filter
732:         and thus don't have to set a filter when capturing - the version of
733:         libpcap in Red Hat Linux 6.1, and versions based on later patches
734:         in that series, don't bind the AF_PACKET socket to an interface
735:         until a filter is set, which means they aren't bound at all if
736:         no filter is set, which means no packets arrive as input on that
737:         socket, which means Ethereal never sees any packets. */
738:      filter_text = gtk_entry_get_text(GTK_ENTRY(filter_te));
739:      if (cfile.cfilter)
740:        g_free(cfile.cfilter);
741:      g_assert(filter_text != NULL);
742:      cfile.cfilter = g_strdup(filter_text); 
743:    
806:      /* IP Address and V5 Interface */
807:    
808:      ipaddr_text = gtk_entry_get_text(GTK_ENTRY(ipaddr_te)); 
809:      if (cfile.ipaddr)
810:          g_free(cfile.ipaddr);
811:      g_assert(ipaddr_text != NULL);
812:      cfile.ipaddr = g_strdup(ipaddr_text);
813:      cfile.has_ipaddr = TRUE;
814:    
815:      v5_if_text = gtk_entry_get_text(GTK_ENTRY(v5_if_te));
816:      if (cfile.v5iface)
817:          g_free(cfile.v5iface);
818:      g_assert(v5_if_text != NULL);
819:      cfile.v5iface = g_strdup(v5_if_text);
820:      cfile.has_v5iface = TRUE;
821:    
744:      save_file = gtk_entry_get_text(GTK_ENTRY(file_te));
745:      if (save_file && save_file[0]) {
746:        /* User specified a file to which the capture should be written. */
747:        save_file = g_strdup(save_file);
748:      } else {
749:        /* User didn't specify a file; save to a temporary file. */
750:        save_file = NULL;
751:      }
752:    
753:      capture_opts.has_autostop_count =
754:        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(count_cb));
755:      if (capture_opts.has_autostop_count)
756:        capture_opts.autostop_count =
757:          gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(count_sb));
758:    
759:      capture_opts.has_autostop_filesize =
760:        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(filesize_cb));
761:      if (capture_opts.has_autostop_filesize)
762:        capture_opts.autostop_filesize =
763:          gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(filesize_sb));
764:    
765:      capture_opts.has_autostop_duration =
766:        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(duration_cb));
767:      if (capture_opts.has_autostop_duration)
768:        capture_opts.autostop_duration =
769:          gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(duration_sb));
770:    
771:      capture_opts.sync_mode =
772:        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb));
773:    
774:      auto_scroll_live =
775:          gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auto_scroll_cb));
776:    
777:      g_resolv_flags = RESOLV_NONE;
778:      if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_resolv_cb)))
779:        g_resolv_flags |= RESOLV_MAC;
780:      if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(n_resolv_cb)))
781:        g_resolv_flags |= RESOLV_NETWORK;
782:      if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(t_resolv_cb)))
783:        g_resolv_flags |= RESOLV_TRANSPORT;
784:    
785:      capture_opts.ringbuffer_on =
786:        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb)) &&
787:        !(capture_opts.sync_mode);
788:      if (capture_opts.ringbuffer_on) {
789:        if (save_file == NULL) {
790:          simple_dialog(ESD_TYPE_CRIT, NULL,
791:            "You must specify a save file if you want to use the ring buffer.");
792:          return;
793:        } else if (!capture_opts.has_autostop_filesize) {
794:          simple_dialog(ESD_TYPE_CRIT, NULL,
795:            "You must specify a file size at which to rotate the capture files\n"
796:            "if you want to use the ring buffer.");
797:          return;
798:        }
799:      }
800:    
801:      capture_opts.ringbuffer_num_files =
802:        gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ringbuffer_nbf_sb));
803:      if (capture_opts.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES)
804:        capture_opts.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
805:      else if (capture_opts.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES)
806:        capture_opts.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES;
807:    
808:      gtk_widget_destroy(GTK_WIDGET(parent_w));
809:    
887:    /*
888:      if(cfile.has_ipaddr)
889:          do_snooping();
890:    */
810:      do_capture(save_file);
811:    }
812:    
813:    static void
814:    capture_prep_close_cb(GtkWidget *close_bt _U_, gpointer parent_w)
815:    {
816:      gtk_grab_remove(GTK_WIDGET(parent_w));
817:      gtk_widget_destroy(GTK_WIDGET(parent_w));
818:    }
819:    
820:    static void
821:    capture_prep_destroy_cb(GtkWidget *win, gpointer user_data _U_)
822:    {
823:      GtkWidget *capture_prep_filter_w;
824:      GtkWidget *fs;
825:    
826:      /* Is there a filter edit/selection dialog associated with this
827:         Capture Options dialog? */
828:      capture_prep_filter_w = gtk_object_get_data(GTK_OBJECT(win), E_FILT_DIALOG_PTR_KEY);
829:    
830:      if (capture_prep_filter_w != NULL) {
831:        /* Yes.  Destroy it. */
832:        gtk_widget_destroy(capture_prep_filter_w);
833:      }
834:    
835:      /* Is there a file selection dialog associated with this
836:         Print File dialog? */
837:      fs = gtk_object_get_data(GTK_OBJECT(win), E_FILE_SEL_DIALOG_PTR_KEY);
838:    
839:      if (fs != NULL) {
840:        /* Yes.  Destroy it. */
841:        gtk_widget_destroy(fs);
842:      }
843:    
844:      /* Note that we no longer have a "Capture Options" dialog box. */
845:      cap_open_w = NULL;
846:    }
847:    
848:    /*
849:     * Adjust the sensitivity of various widgets as per the current setting
850:     * of other widgets.
851:     */
852:    static void
853:    capture_prep_adjust_sensitivity(GtkWidget *tb _U_, gpointer parent_w)
854:    {
855:      GtkWidget *snap_cb, *snap_sb,
856:                *ringbuffer_on_tb, *ringbuffer_nbf_lb, *ringbuffer_nbf_sb,
857:                *sync_cb, *auto_scroll_cb,
858:                *count_cb, *count_sb,
859:                *filesize_cb, *filesize_sb, *filesize_lb,
860:                *duration_cb, *duration_sb;
861:    
862:      snap_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SNAP_CB_KEY);
863:      snap_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SNAP_SB_KEY);
864:      ringbuffer_on_tb  = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_RING_ON_TB_KEY);
865:      ringbuffer_nbf_lb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_RING_NBF_LB_KEY);
866:      ringbuffer_nbf_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_RING_NBF_SB_KEY);
867:      sync_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_SYNC_KEY);
868:      auto_scroll_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_AUTO_SCROLL_KEY);
869:      count_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_COUNT_CB_KEY);
870:      count_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_COUNT_SB_KEY);
871:      filesize_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILESIZE_CB_KEY);
872:      filesize_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILESIZE_SB_KEY);
873:      filesize_lb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_FILESIZE_LB_KEY);
874:      duration_cb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_DURATION_CB_KEY);
875:      duration_sb = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w), E_CAP_DURATION_SB_KEY);
876:    
877:      /* The snapshot length spinbox is sensitive iff the "Limit each packet
878:         to" checkbox is on. */
879:      gtk_widget_set_sensitive(GTK_WIDGET(snap_sb),
880:          gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(snap_cb)));
881:    
882:      if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sync_cb))) {
883:        /* "Update list of packets in real time" captures enabled; we don't
884:           support ring buffer mode for those captures, so turn ring buffer
885:           mode off if it's on, and make its toggle button, and the spin
886:           button for the number of ring buffer files (and the spin button's
887:           label), insensitive. */
888:        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb))) {
889:          gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb), FALSE);
890:        }
891:        gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_on_tb), FALSE);
892:    
893:        /* Auto-scroll mode is meaningful only in "Update list of packets
894:           in real time" captures, so make its toggle button sensitive. */
895:        gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), TRUE);
896:      } else {
897:        /* "Update list of packets in real time" captures disabled; that
898:           means ring buffer mode is OK, so make its toggle button
899:           sensitive. */
900:        gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_on_tb), TRUE);
901:    
902:        /* Auto-scroll mode is meaningful only in "Update list of packets
903:           in real time" captures, so make its toggle button insensitive. */
904:        gtk_widget_set_sensitive(GTK_WIDGET(auto_scroll_cb), FALSE);
905:      }
906:      
907:      if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ringbuffer_on_tb))) {
908:        /* Ring buffer mode enabled.  Make the spin button for the number
909:           of ring buffer files, and its label, sensitive. */
910:        gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb), TRUE);
911:        gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb), TRUE);
912:    
913:        /* Also, indicate that the file size is a size at which to switch
914:           ring buffer files, not a size at which to stop the capture,
915:           turn its button on. */
916:        gtk_label_set_text(GTK_LABEL(GTK_BIN(filesize_cb)->child),
917:            "Rotate capture file every");
918:        gtk_label_set_text(GTK_LABEL(filesize_lb), "kilobyte(s)");
919:        gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(filesize_cb), TRUE);
920:      } else {
921:        /* Ring buffer mode disabled.  Make the spin button for the number
922:           of ring buffer files, and its label insensitive. */
923:        gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_lb), FALSE);
924:        gtk_widget_set_sensitive(GTK_WIDGET(ringbuffer_nbf_sb), FALSE);
925:    
926:        /* Also, indicate that the file size is a size at which to stop the
927:           capture, not a size at which to switch ring buffer files. */
928:        gtk_label_set_text(GTK_LABEL(GTK_BIN(filesize_cb)->child),
929:            "Stop capture after");
930:        gtk_label_set_text(GTK_LABEL(filesize_lb), "kilobyte(s) captured");
931:      }
932:    
933:      /* The maximum packet count spinbox is sensitive iff the "Stop capture
934:         after N packets captured" checkbox is on. */
935:      gtk_widget_set_sensitive(GTK_WIDGET(count_sb),
936:          gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(count_cb)));
937:    
938:      /* The maximum file size spinbox is sensitive iff the "Stop capture
939:         after N kilobytes captured" checkbox is on. */
940:      gtk_widget_set_sensitive(GTK_WIDGET(filesize_sb),
941:          gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(filesize_cb)));
942:    
943:      /* The capture duration spinbox is sensitive iff the "Stop capture
944:         after N seconds" checkbox is on. */
945:      gtk_widget_set_sensitive(GTK_WIDGET(duration_sb),
946:          gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(duration_cb)));
947:    }
948:    
949:    #endif /* HAVE_LIBPCAP */
950:    
Title: Differences Analysis

Base file: C:\ws\ethereal-0.9.5\file.h

Compared file: C:\ethereal-0.9.5\file.h

Difference Analysis Generated by HtmlDiff on 10/11/2002 5:53 PM  

1:  /* file.h
2:   * Definitions for file structures and routines
3:   *
4:   * $Id: file.h,v 1.94 2002/05/27 22:00:35 guy Exp $
5:   *
6:   * Ethereal - Network traffic analyzer
7:   * By Gerald Combs <gerald@xxxxxxxxxxxx>
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: #ifndef __FILE_H__
26: #define __FILE_H__
27: 
28: #ifdef HAVE_SYS_TYPES_H
29: #include <sys/types.h>
30: #endif
31: 
32: #include "wiretap/wtap.h"
33: #include <epan/dfilter/dfilter.h>
34: #include "print.h"
35: #include <errno.h>
36: #include <epan/epan.h>
37: 
38: /* Current state of file. */
39: typedef enum {
40:     FILE_CLOSED,        /* No file open */
41:     FILE_READ_IN_PROGRESS,  /* Reading a file we've opened */
42:     FILE_READ_ABORTED,  /* Read aborted by user */
43:     FILE_READ_DONE      /* Read completed */
44: } file_state;
45: 
46: typedef struct _capture_file {
47:   file_state   state;     /* Current state of capture file */
48:   int          filed;     /* File descriptor of capture file */
49:   gchar       *filename;  /* Name of capture file */
50:   gboolean     is_tempfile; /* Is capture file a temporary file? */
51:   gboolean     user_saved;/* If capture file is temporary, has it been saved by user yet? */
52:   long         f_len;     /* Length of capture file */
53:   guint16      cd_t;      /* File type of capture file */
54:   int          lnk_t;     /* Link-layer type with which to save capture */
55:   guint32      vers;      /* Version.  For tcpdump minor is appended to major */
56:   int          count;     /* Total number of frames */
57:   int          marked_count; /* Number of marked frames */
58:   gboolean     drops_known; /* TRUE if we know how many packets were dropped */
59:   guint32      drops;     /* Dropped packets */
60:   guint32      esec;      /* Elapsed seconds */
61:   guint32      eusec;     /* Elapsed microseconds */
62:   gboolean     has_snap;  /* TRUE if maximum capture packet length is known */
63:   int          snap;      /* Maximum captured packet length */
64:   long         progbar_quantum; /* Number of bytes read per progress bar update */
65:   long         progbar_nextstep; /* Next point at which to update progress bar */
66:   gchar       *iface;     /* Interface */
67:   gchar       *save_file; /* File that user saved capture to */
68:   int          save_file_fd; /* File descriptor for saved file */
69:   wtap        *wth;       /* Wiretap session */
70:   dfilter_t   *rfcode;    /* Compiled read filter program */ 
71:   gchar       *dfilter;   /* Display filter string */
72:   dfilter_t   *dfcode;    /* Compiled display filter program */ 
73:   gchar       *ipaddr;    /* IP address */
74:   gboolean    has_ipaddr; /* TRUE if IP address has been entered */
75:   gchar       *v5iface;   /* V5 Interface */
76:   gboolean    has_v5iface; /* TRUE if V5 interface has been entered */
73: #ifdef HAVE_LIBPCAP
74:   gchar       *cfilter;   /* Capture filter string */
75: #endif
76:   gchar       *sfilter;   /* Search filter string */
77:   gboolean     sbackward;  /* TRUE if search is backward, FALSE if forward */
78:   union wtap_pseudo_header pseudo_header;      /* Packet pseudo_header */
79:   guint8       pd[WTAP_MAX_PACKET_SIZE];  /* Packet data */
80:   GMemChunk   *plist_chunk; /* Memory chunk for frame_data structures */
81:   frame_data  *plist;     /* Packet list */
82:   frame_data  *plist_end; /* Last packet in list */
83:   frame_data  *first_displayed; /* First frame displayed */
84:   frame_data  *last_displayed;  /* Last frame displayed */
85:   column_info  cinfo;    /* Column formatting information */
86:   frame_data  *current_frame;  /* Frame data for current frame */
87:   epan_dissect_t *edt; /* Protocol dissection fo rcurrently selected packet */
88:   FILE        *print_fh;  /* File we're printing to */
89: } capture_file;
90: 
91: /* Return values from "read_cap_file()", "continue_tail_cap_file()",
92:    and "finish_tail_cap_file()". */
93: typedef enum {
94:     READ_SUCCESS,   /* read succeeded */
95:     READ_ERROR, /* read got an error */
96:     READ_ABORTED    /* read aborted by user */
97: } read_status_t;
98: 
99: int  open_cap_file(char *, gboolean, capture_file *);
100:    void close_cap_file(capture_file *);
101:    read_status_t read_cap_file(capture_file *, int *);
102:    int  start_tail_cap_file(char *, gboolean, capture_file *);
103:    read_status_t continue_tail_cap_file(capture_file *, int, int *);
104:    read_status_t finish_tail_cap_file(capture_file *, int *);
105:    /* size_t read_frame_header(capture_file *); */
106:    gboolean save_cap_file(char *, capture_file *, gboolean, gboolean, guint);
107:    
108:    int filter_packets(capture_file *cf, gchar *dfilter);
109:    void colorize_packets(capture_file *);
110:    void redissect_packets(capture_file *cf);
111:    int print_packets(capture_file *cf, print_args_t *print_args);
112:    void change_time_formats(capture_file *);
113:    gboolean find_packet(capture_file *cf, dfilter_t *sfcode);
114:    
115:    typedef enum {
116:      FOUND_FRAME,      /* found the frame */
117:      NO_SUCH_FRAME,    /* no frame with that number */
118:      FRAME_NOT_DISPLAYED   /* frame with that number isn't displayed */
119:    } goto_result_t;
120:    goto_result_t goto_frame(capture_file *cf, guint fnumber);
121:    
122:    void select_packet(capture_file *, int);
123:    void unselect_packet(capture_file *);
124:    
125:    void unselect_field(void);
126:    
127:    /*
128:     * Mark a particular frame in a particular capture.
129:     */
130:    void mark_frame(capture_file *, frame_data *);
131:    
132:    /*
133:     * Unmark a particular frame in a particular capture.
134:     */
135:    void unmark_frame(capture_file *, frame_data *);
136:    
137:    /* Moves or copies a file. Returns 0 on failure, 1 on success */
138:    int file_mv(char *from, char *to);
139:    
140:    /* Copies a file. Returns 0 on failure, 1 on success */
141:    int file_cp(char *from, char *to);
142:    
143:    char *file_open_error_message(int, gboolean);
144:    char *file_read_error_message(int);
145:    char *file_write_error_message(int);
146:    
147:    #endif /* file.h */
148:    
Title: Differences Analysis

Base file: C:\ws\ethereal-0.9.5\gtk\main.c

Compared file: C:\ethereal-0.9.5\gtk\main.c

Difference Analysis Generated by HtmlDiff on 10/11/2002 5:52 PM  

1:  /* main.c
2:   *
3:   * $Id: main.c,v 1.252 2002/05/30 00:44:50 guy Exp $
4:   *
5:   * Ethereal - Network traffic analyzer
6:   * By Gerald Combs <gerald@xxxxxxxxxxxx>
7:   * Copyright 1998 Gerald Combs
8:   *
9:   * Richard Sharpe, 13-Feb-1999, added support for initializing structures
10:  *                              needed by dissect routines
11:  * Jeff Foster,    2001/03/12,  added support tabbed hex display windowss
12:  * 
13:  * 
14:  * This program is free software; you can redistribute it and/or
15:  * modify it under the terms of the GNU General Public License
16:  * as published by the Free Software Foundation; either version 2
17:  * of the License, or (at your option) any later version.
18:  * 
19:  * This program is distributed in the hope that it will be useful,
20:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22:  * GNU General Public License for more details.
23:  * 
24:  * You should have received a copy of the GNU General Public License
25:  * along with this program; if not, write to the Free Software
26:  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27:  *
28:  *
29:  * To do:
30:  * - Graphs
31:  * - Playback window
32:  * - Multiple window support
33:  * - Add cut/copy/paste
34:  * - Create header parsing routines
35:  * - Make byte view selections more fancy?
36:  */
37: 
38: #ifdef HAVE_CONFIG_H
39: # include "config.h"
40: #endif
41: 
42: #include <gtk/gtk.h>
43: 
44: #include <stdlib.h>
45: #include <stdio.h>
46: #include <string.h>
47: #include <ctype.h>
48: 
49: #ifdef HAVE_UNISTD_H
50: #include <unistd.h>
51: #endif
52: 
53: #include <errno.h>
54: 
55: #ifdef HAVE_SYS_TYPES_H
56: #include <sys/types.h>
57: #endif
58: 
59: #ifdef HAVE_SYS_STAT_H
60: #include <sys/stat.h>
61: #endif
62: 
63: #ifdef HAVE_IO_H
64: #include <io.h> /* open/close on win32 */
65: #endif
66: 
67: #ifdef HAVE_DIRECT_H
68: #include <direct.h>
69: #endif
70: 
71: #ifdef HAVE_NETINET_IN_H
72: #include <netinet/in.h>
73: #endif
74: 
75: #include <signal.h>
76: 
77: #ifdef HAVE_LIBPCAP
78: #include <pcap.h>
79: #endif
80: 
81: #ifdef HAVE_LIBZ
82: #include <zlib.h>   /* to get the libz version number */
83: #endif
84: 
85: #ifdef NEED_SNPRINTF_H
86: # include "snprintf.h"
87: #endif
88: 
89: #ifdef HAVE_UCD_SNMP_VERSION_H
90: #include <ucd-snmp/version.h>
91: #endif /* HAVE_UCD_SNMP_VERSION_H */
92: 
93: #ifdef NEED_STRERROR_H
94: #include "strerror.h"
95: #endif
96: 
97: #ifdef NEED_GETOPT_H
98: #include "getopt.h"
99: #endif
100:    
101:    #ifdef WIN32 /* Needed for console I/O */
102:    #include <fcntl.h>
103:    #include <conio.h>
104:    #endif
105:    
106:    #include <epan/epan.h>
107:    #include <epan/filesystem.h>
108:    #include <epan/epan_dissect.h>
109:    
110:    #include "main.h"
111:    #include <epan/timestamp.h>
112:    #include <epan/packet.h>
113:    #include "capture.h"
114:    #include "summary.h"
115:    #include "file.h"
116:    #include "filters.h"
117:    #include "prefs.h"
118:    #include "menu.h"
119:    #include "../menu.h"
120:    #include "color.h"
121:    #include "color_utils.h"
122:    #include "filter_prefs.h"
123:    #include "file_dlg.h"
124:    #include "column.h"
125:    #include "print.h"
126:    #include <epan/resolv.h>
127:    #ifdef HAVE_LIBPCAP
128:    #include "pcap-util.h"
129:    #endif
130:    #include "statusbar.h"
131:    #include "simple_dialog.h"
132:    #include "proto_draw.h"
133:    #include <epan/dfilter/dfilter.h>
134:    #include "keys.h"
135:    #include "packet_win.h"
136:    #include "gtkglobals.h"
137:    #include <epan/plugins.h>
138:    #include "colors.h"
139:    #include <epan/strutil.h>
140:    #include "register.h"
141:    #include "ringbuffer.h"
142:    #include "ui_util.h"
143:    #include "image/clist_ascend.xpm"
144:    #include "image/clist_descend.xpm"
145:    
146:    #ifdef WIN32
147:    #include "capture-wpcap.h"
148:    #endif
149:    
150:    typedef struct column_arrows {
151:      GtkWidget *table;
152:      GtkWidget *ascend_pm;
153:      GtkWidget *descend_pm;
154:    } column_arrows;
155:    
156:    capture_file cfile;
157:    GtkWidget   *top_level, *packet_list, *tree_view, *byte_nb_ptr,
158:                *tv_scrollw, *pkt_scrollw;
159:    static GtkWidget    *info_bar;
160:    GdkFont     *m_r_font, *m_b_font;
161:    guint       m_font_height, m_font_width;
162:    static guint    main_ctx, file_ctx, help_ctx;
163:    static GString *comp_info_str;
164:    gchar       *ethereal_path = NULL;
165:    gchar       *last_open_dir = NULL;
166:    gint   root_x = G_MAXINT, root_y = G_MAXINT, top_width, top_height;
167:    
168:    ts_type timestamp_type = RELATIVE;
169:    
170:    GtkStyle *item_style;
171:    
172:    /* Specifies the field currently selected in the GUI protocol tree */
173:    field_info *finfo_selected = NULL;
174:    
175:    #ifdef WIN32
176:    static gboolean has_no_console; /* TRUE if app has no console */
177:    static gboolean console_was_created; /* TRUE if console was created */
178:    static void create_console(void);
179:    static void destroy_console(void);
180:    static void console_log_handler(const char *log_domain,
181:        GLogLevelFlags log_level, const char *message, gpointer user_data);
182:    #endif
183:    
184:    static void create_main_window(gint, gint, gint, e_prefs*);
185:    
186:    #define E_DFILTER_CM_KEY          "display_filter_combo"
187:    #define E_DFILTER_FL_KEY          "display_filter_list"
188:    
189:    /* About Ethereal window */
190:    void
191:    about_ethereal( GtkWidget *w _U_, gpointer data _U_ ) {
192:      simple_dialog(ESD_TYPE_INFO, NULL,
193:            "Ethereal - Network Protocol Analyzer\n"
194:            "Version " VERSION " (C) 1998-2000 Gerald Combs <gerald@xxxxxxxxxxxx>\n"
195:                    "Compiled %s\n\n"
196:    
197:            "Check the man page for complete documentation and\n"
198:            "for the list of contributors.\n"
199:    
200:            "\nSee http://www.ethereal.com/ for more information.",
201:                     comp_info_str->str);
202:    }
203:    
204:    void
205:    set_fonts(GdkFont *regular, GdkFont *bold)
206:    {
207:        /* Yes, assert. The code that loads the font should check
208:         * for NULL and provide its own error message. */
209:        g_assert(m_r_font && m_b_font);
210:        m_r_font = regular;
211:        m_b_font = bold;
212:    
213:        m_font_height = m_r_font->ascent + m_r_font->descent;
214:        m_font_width = gdk_string_width(m_r_font, "0");
215:    }
216:    
217:    
218:    /* Match selected byte pattern */
219:    static void
220:    match_selected_cb_do(gpointer data, int action, gchar *text)
221:    {
222:        GtkWidget       *filter_te;
223:        char        *cur_filter, *new_filter;
224:    
225:        if (!text)
226:        return;
227:        g_assert(data);
228:        filter_te = gtk_object_get_data(GTK_OBJECT(data), E_DFILTER_TE_KEY);
229:        g_assert(filter_te);
230:    
231:        cur_filter = gtk_editable_get_chars(GTK_EDITABLE(filter_te), 0, -1);
232:    
233:        switch (action&MATCH_SELECTED_MASK) {
234:    
235:        case MATCH_SELECTED_REPLACE:
236:        new_filter = g_strdup(text);
237:        break;
238:    
239:        case MATCH_SELECTED_AND:
240:        if ((!cur_filter) || (0 == strlen(cur_filter)))
241:            new_filter = g_strdup(text);
242:        else
243:            new_filter = g_strconcat("(", cur_filter, ") && (", text, ")", NULL);
244:        break;
245:    
246:        case MATCH_SELECTED_OR:
247:        if ((!cur_filter) || (0 == strlen(cur_filter)))
248:            new_filter = g_strdup(text);
249:        else
250:            new_filter = g_strconcat("(", cur_filter, ") || (", text, ")", NULL);
251:        break;
252:    
253:        case MATCH_SELECTED_NOT:
254:        new_filter = g_strconcat("!(", text, ")", NULL);
255:        break;
256:    
257:        case MATCH_SELECTED_AND_NOT:
258:        if ((!cur_filter) || (0 == strlen(cur_filter)))
259:            new_filter = g_strconcat("!(", text, ")", NULL);
260:        else
261:            new_filter = g_strconcat("(", cur_filter, ") && !(", text, ")", NULL);
262:        break;
263:    
264:        case MATCH_SELECTED_OR_NOT:
265:        if ((!cur_filter) || (0 == strlen(cur_filter)))
266:            new_filter = g_strconcat("!(", text, ")", NULL);
267:        else
268:            new_filter = g_strconcat("(", cur_filter, ") || !(", text, ")", NULL);
269:        break;
270:    
271:        default:
272:        g_assert_not_reached();
273:        new_filter = NULL;
274:        break;
275:        }
276:    
277:        /* Free up the copy we got of the old filter text. */
278:        g_free(cur_filter);
279:    
280:        /* create a new one and set the display filter entry accordingly */
281:        gtk_entry_set_text(GTK_ENTRY(filter_te), new_filter);
282:    
283:        /* Run the display filter so it goes in effect. */
284:        if (action&MATCH_SELECTED_APPLY_NOW)
285:        filter_packets(&cfile, new_filter);
286:    
287:        /* Free up the new filter text. */
288:        g_free(new_filter);
289:    
290:        /* Free up the generated text we were handed. */
291:        g_free(text);
292:    }
293:    
294:    void
295:    match_selected_cb_replace(GtkWidget *w, gpointer data)
296:    {
297:        if (finfo_selected)
298:        match_selected_cb_do((data ? data : w),
299:            MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW,
300:            proto_alloc_dfilter_string(finfo_selected, cfile.pd));
301:    }
302:    
303:    void
304:    match_selected_cb_and(GtkWidget *w, gpointer data)
305:    {
306:        if (finfo_selected)
307:        match_selected_cb_do((data ? data : w),
308:            MATCH_SELECTED_AND|MATCH_SELECTED_APPLY_NOW,
309:            proto_alloc_dfilter_string(finfo_selected, cfile.pd));
310:    }
311:    
312:    void
313:    match_selected_cb_or(GtkWidget *w, gpointer data)
314:    {
315:        if (finfo_selected)
316:        match_selected_cb_do((data ? data : w),
317:            MATCH_SELECTED_OR|MATCH_SELECTED_APPLY_NOW,
318:            proto_alloc_dfilter_string(finfo_selected, cfile.pd));
319:    }
320:    
321:    void
322:    match_selected_cb_not(GtkWidget *w, gpointer data)
323:    {
324:        if (finfo_selected)
325:        match_selected_cb_do((data ? data : w),
326:            MATCH_SELECTED_NOT|MATCH_SELECTED_APPLY_NOW,
327:            proto_alloc_dfilter_string(finfo_selected, cfile.pd));
328:    }
329:    
330:    void
331:    match_selected_cb_and_not(GtkWidget *w, gpointer data)
332:    {
333:        if (finfo_selected)
334:        match_selected_cb_do((data ? data : w),
335:            MATCH_SELECTED_AND_NOT|MATCH_SELECTED_APPLY_NOW,
336:            proto_alloc_dfilter_string(finfo_selected, cfile.pd));
337:    }
338:    
339:    void
340:    match_selected_cb_or_not(GtkWidget *w, gpointer data)
341:    {
342:        if (finfo_selected)
343:        match_selected_cb_do((data ? data : w),
344:            MATCH_SELECTED_OR_NOT,
345:            proto_alloc_dfilter_string(finfo_selected, cfile.pd));
346:    }
347:    
348:    void
349:    prepare_selected_cb_replace(GtkWidget *w, gpointer data)
350:    {
351:        if (finfo_selected)
352:        match_selected_cb_do((data ? data : w),
353:            MATCH_SELECTED_REPLACE,
354:            proto_alloc_dfilter_string(finfo_selected, cfile.pd));
355:    }
356:    
357:    void
358:    prepare_selected_cb_and(GtkWidget *w, gpointer data)
359:    {
360:        if (finfo_selected)
361:        match_selected_cb_do((data ? data : w),
362:            MATCH_SELECTED_AND,
363:            proto_alloc_dfilter_string(finfo_selected, cfile.pd));
364:    }
365:    
366:    void
367:    prepare_selected_cb_or(GtkWidget *w, gpointer data)
368:    {
369:        if (finfo_selected)
370:        match_selected_cb_do((data ? data : w),
371:            MATCH_SELECTED_OR,
372:            proto_alloc_dfilter_string(finfo_selected, cfile.pd));
373:    }
374:    
375:    void
376:    prepare_selected_cb_not(GtkWidget *w, gpointer data)
377:    {
378:        if (finfo_selected)
379:        match_selected_cb_do((data ? data : w),
380:            MATCH_SELECTED_NOT,
381:            proto_alloc_dfilter_string(finfo_selected, cfile.pd));
382:    }
383:    
384:    void
385:    prepare_selected_cb_and_not(GtkWidget *w, gpointer data)
386:    {
387:        if (finfo_selected)
388:        match_selected_cb_do((data ? data : w),
389:            MATCH_SELECTED_AND_NOT,
390:            proto_alloc_dfilter_string(finfo_selected, cfile.pd));
391:    }
392:    
393:    void
394:    prepare_selected_cb_or_not(GtkWidget *w, gpointer data)
395:    {
396:        if (finfo_selected)
397:        match_selected_cb_do((data ? data : w),
398:            MATCH_SELECTED_OR_NOT,
399:            proto_alloc_dfilter_string(finfo_selected, cfile.pd));
400:    }
401:    
402:    static gchar *
403:    get_text_from_packet_list(gpointer data)
404:    {
405:        gint    row = (gint)gtk_object_get_data(GTK_OBJECT(data), E_MPACKET_LIST_ROW_KEY);
406:        gint    column = (gint)gtk_object_get_data(GTK_OBJECT(data), E_MPACKET_LIST_COL_KEY);
407:        frame_data *fdata = (frame_data *)gtk_clist_get_row_data(GTK_CLIST(packet_list), row);
408:        epan_dissect_t *edt;
409:        gchar      *buf=NULL;
410:        int         len;
411:        int         err;
412:    
413:        if (fdata != NULL) {
414:        /* XXX - do something with "err" */
415:        wtap_seek_read(cfile.wth, fdata->file_off, &cfile.pseudo_header,
416:                   cfile.pd, fdata->cap_len, &err);
417:    
418:        edt = epan_dissect_new(FALSE, FALSE);
419:        epan_dissect_run(edt, &cfile.pseudo_header, cfile.pd, fdata,
420:                 &cfile.cinfo);
421:        epan_dissect_fill_in_columns(edt);
422:    
423:        if (strlen(cfile.cinfo.col_expr[column]) != 0 &&
424:            strlen(cfile.cinfo.col_expr_val[column]) != 0) {
425:            len = strlen(cfile.cinfo.col_expr[column]) +
426:              strlen(cfile.cinfo.col_expr_val[column]) + 5;
427:            buf = g_malloc0(len);
428:            snprintf(buf, len, "%s == %s", cfile.cinfo.col_expr[column],
429:                 cfile.cinfo.col_expr_val[column]);
430:            }
431:    
432:        epan_dissect_free(edt);
433:        }
434:            
435:        return buf;
436:    }
437:    
438:    void
439:    match_selected_cb_replace2(GtkWidget *w _U_, gpointer data)
440:    {
441:        match_selected_cb_do(data,
442:            MATCH_SELECTED_REPLACE|MATCH_SELECTED_APPLY_NOW,
443:            get_text_from_packet_list(data));
444:    }
445:    
446:    void
447:    match_selected_cb_and2(GtkWidget *w _U_, gpointer data)
448:    {
449:        match_selected_cb_do(data,
450:            MATCH_SELECTED_AND|MATCH_SELECTED_APPLY_NOW,
451:            get_text_from_packet_list(data));
452:    }
453:    
454:    void
455:    match_selected_cb_or2(GtkWidget *w _U_, gpointer data)
456:    {
457:        match_selected_cb_do(data,
458:            MATCH_SELECTED_OR|MATCH_SELECTED_APPLY_NOW,
459:            get_text_from_packet_list(data));
460:    }
461:    
462:    void
463:    match_selected_cb_not2(GtkWidget *w _U_, gpointer data)
464:    {
465:        match_selected_cb_do(data,
466:            MATCH_SELECTED_NOT|MATCH_SELECTED_APPLY_NOW,
467:            get_text_from_packet_list(data));
468:    }
469:    
470:    void
471:    match_selected_cb_and_not2(GtkWidget *w _U_, gpointer data)
472:    {
473:        match_selected_cb_do(data,
474:            MATCH_SELECTED_AND_NOT|MATCH_SELECTED_APPLY_NOW,
475:            get_text_from_packet_list(data));
476:    }
477:    
478:    void
479:    match_selected_cb_or_not2(GtkWidget *w _U_, gpointer data)
480:    {
481:        match_selected_cb_do(data,
482:            MATCH_SELECTED_OR_NOT|MATCH_SELECTED_APPLY_NOW,
483:            get_text_from_packet_list(data));
484:    }
485:    
486:    void
487:    prepare_selected_cb_replace2(GtkWidget *w _U_, gpointer data)
488:    {
489:        match_selected_cb_do(data,
490:            MATCH_SELECTED_REPLACE,
491:            get_text_from_packet_list(data));
492:    }
493:    
494:    void
495:    prepare_selected_cb_and2(GtkWidget *w _U_, gpointer data)
496:    {
497:        match_selected_cb_do(data,
498:            MATCH_SELECTED_AND,
499:            get_text_from_packet_list(data));
500:    }
501:    
502:    void
503:    prepare_selected_cb_or2(GtkWidget *w _U_, gpointer data)
504:    {
505:        match_selected_cb_do(data,
506:            MATCH_SELECTED_OR,
507:            get_text_from_packet_list(data));
508:    }
509:    
510:    void
511:    prepare_selected_cb_not2(GtkWidget *w _U_, gpointer data)
512:    {
513:        match_selected_cb_do(data,
514:            MATCH_SELECTED_NOT,
515:            get_text_from_packet_list(data));
516:    }
517:    
518:    void
519:    prepare_selected_cb_and_not2(GtkWidget *w _U_, gpointer data)
520:    {
521:        match_selected_cb_do(data,
522:            MATCH_SELECTED_AND_NOT,
523:            get_text_from_packet_list(data));
524:    }
525:    
526:    void
527:    prepare_selected_cb_or_not2(GtkWidget *w _U_, gpointer data)
528:    {
529:        match_selected_cb_do(data,
530:            MATCH_SELECTED_OR_NOT,
531:            get_text_from_packet_list(data));
532:    }
533:    
534:    /* Run the current display filter on the current packet set, and
535:       redisplay. */
536:    static void
537:    filter_activate_cb(GtkWidget *w, gpointer data)
538:    {
539:      GtkCombo  *filter_cm = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_CM_KEY);
540:      GList     *filter_list = gtk_object_get_data(GTK_OBJECT(filter_cm), E_DFILTER_FL_KEY);
541:      GList     *li;
542:      gboolean   add_filter = TRUE;
543:      gboolean   free_filter = TRUE;
544:      char      *s;
545:      
546:      g_assert(data);
547:      s = g_strdup(gtk_entry_get_text(GTK_ENTRY(data)));
548:      
549:      /* GtkCombos don't let us get at their list contents easily, so we maintain
550:         our own filter list, and feed it to gtk_combo_set_popdown_strings when
551:         a new filter is added. */
552:      if (filter_packets(&cfile, s)) {
553:        li = g_list_first(filter_list);
554:        while (li) {
555:          if (li->data && strcmp(s, li->data) == 0)
556:            add_filter = FALSE;
557:          li = li->next;
558:        }
559:    
560:        if (add_filter) {
561:          free_filter = FALSE;
562:          filter_list = g_list_append(filter_list, s);
563:          gtk_object_set_data(GTK_OBJECT(filter_cm), E_DFILTER_FL_KEY, filter_list);
564:          gtk_combo_set_popdown_strings(filter_cm, filter_list);
565:          gtk_entry_set_text(GTK_ENTRY(filter_cm->entry), g_list_last(filter_list)->data);
566:        }
567:      }
568:      if (free_filter)
569:        g_free(s);
570:    }
571:    
572:    /* redisplay with no display filter */
573:    static void
574:    filter_reset_cb(GtkWidget *w, gpointer data _U_)
575:    {
576:      GtkWidget *filter_te = NULL;
577:    
578:      if ((filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY))) {
579:        gtk_entry_set_text(GTK_ENTRY(filter_te), "");
580:      }
581:      filter_packets(&cfile, NULL);
582:    }
583:    
584:    /* GTKClist compare routine, overrides default to allow numeric comparison */
585:    static gint
586:    packet_list_compare(GtkCList *clist, gconstpointer  ptr1, gconstpointer  ptr2)
587:    {
588:      /* Get row text strings */
589:      char *text1 = GTK_CELL_TEXT (((GtkCListRow *)ptr1)->cell[clist->sort_column])->text;
590:      char *text2 = GTK_CELL_TEXT (((GtkCListRow *)ptr2)->cell[clist->sort_column])->text;
591:    
592:      /* Attempt to convert to numbers */
593:      double  num1 = atof(text1);
594:      double  num2 = atof(text2);
595:      
596:      gint  col_fmt = cfile.cinfo.col_fmt[clist->sort_column];
597:      
598:      if ((col_fmt == COL_NUMBER) || (col_fmt == COL_REL_TIME) || (col_fmt == COL_DELTA_TIME) ||
599:          ((col_fmt == COL_CLS_TIME) && (timestamp_type == RELATIVE)) ||
600:          ((col_fmt == COL_CLS_TIME) && (timestamp_type == DELTA))    ||
601:          (col_fmt == COL_UNRES_SRC_PORT) || (col_fmt == COL_UNRES_DST_PORT) ||
602:          ((num1 != 0) && (num2 != 0) && ((col_fmt == COL_DEF_SRC_PORT) || (col_fmt == COL_RES_SRC_PORT) ||
603:                                          (col_fmt == COL_DEF_DST_PORT) || (col_fmt == COL_RES_DST_PORT))) ||
604:          (col_fmt == COL_PACKET_LENGTH)) {
605:    
606:        /* Compare numeric column */
607:    
608:        if (num1 < num2)
609:          return -1;
610:        else if (num1 > num2)
611:          return 1;
612:        else
613:          return 0;
614:      }
615:      
616:      else {
617:        
618:        /* Compare text column */
619:        if (!text2)
620:          return (text1 != NULL);
621:    
622:        if (!text1)
623:          return -1;
624:    
625:        return strcmp(text1, text2);
626:      }
627:    }
628:    
629:    /* What to do when a column is clicked */
630:    static void 
631:    packet_list_click_column_cb(GtkCList *clist, gint column, gpointer data)
632:    {
633:      column_arrows *col_arrows = (column_arrows *) data;
634:      int i;
635:      
636:      gtk_clist_freeze(clist);
637:      
638:      for (i = 0; i < cfile.cinfo.num_cols; i++) {
639:        gtk_widget_hide(col_arrows[i].ascend_pm);
640:        gtk_widget_hide(col_arrows[i].descend_pm);
641:      }
642:      
643:      if (column == clist->sort_column) {
644:        if (clist->sort_type == GTK_SORT_ASCENDING) {
645:          clist->sort_type = GTK_SORT_DESCENDING;
646:          gtk_widget_show(col_arrows[column].descend_pm);
647:        } else {
648:          clist->sort_type = GTK_SORT_ASCENDING;
649:          gtk_widget_show(col_arrows[column].ascend_pm);
650:        }
651:      }
652:      else {
653:        clist->sort_type = GTK_SORT_ASCENDING;
654:        gtk_widget_show(col_arrows[column].ascend_pm);
655:        gtk_clist_set_sort_column(clist, column);
656:      }
657:      gtk_clist_thaw(clist);
658:    
659:      gtk_clist_sort(clist);
660:    }
661:    
662:    /* mark packets */
663:    static void 
664:    set_frame_mark(gboolean set, frame_data *frame, gint row) {
665:      GdkColor fg, bg;
666:    
667:      if (row == -1)
668:        return;
669:      if (set) {
670:        mark_frame(&cfile, frame);
671:        color_t_to_gdkcolor(&fg, &prefs.gui_marked_fg);
672:        color_t_to_gdkcolor(&bg, &prefs.gui_marked_bg);
673:      } else {
674:        unmark_frame(&cfile, frame);
675:        fg = BLACK;
676:        bg = WHITE;
677:      }
678:      file_set_save_marked_sensitive();
679:      gtk_clist_set_background(GTK_CLIST(packet_list), row, &bg);
680:      gtk_clist_set_foreground(GTK_CLIST(packet_list), row, &fg);
681:    }
682:    
683:    static void
684:    packet_list_button_pressed_cb(GtkWidget *w, GdkEvent *event, gpointer data _U_) {
685:      
686:      GdkEventButton *event_button = (GdkEventButton *)event;
687:      gint row, column;
688:    
689:      if (w == NULL || event == NULL)
690:        return;
691:    
692:      if (event->type == GDK_BUTTON_PRESS && event_button->button == 2 &&
693:          gtk_clist_get_selection_info(GTK_CLIST(w), event_button->x, event_button->y,
694:                       &row, &column)) {
695:        frame_data *fdata = (frame_data *) gtk_clist_get_row_data(GTK_CLIST(w), row);
696:        set_frame_mark(!fdata->flags.marked, fdata, row);
697:      }
698:    }
699:    
700:    void mark_frame_cb(GtkWidget *w _U_, gpointer data _U_) {
701:      if (cfile.current_frame) {
702:        /* XXX hum, should better have a "cfile->current_row" here ... */
703:        set_frame_mark(!cfile.current_frame->flags.marked,
704:               cfile.current_frame, 
705:               gtk_clist_find_row_from_data(GTK_CLIST(packet_list), 
706:                            cfile.current_frame));
707:      }
708:    }
709:    
710:    static void mark_all_frames(gboolean set) {
711:      frame_data *fdata;
712:      for (fdata = cfile.plist; fdata != NULL; fdata = fdata->next) {
713:        set_frame_mark(set,
714:               fdata,
715:               gtk_clist_find_row_from_data(GTK_CLIST(packet_list), fdata));    
716:      }
717:    }
718:    
719:    void update_marked_frames(void) {
720:      frame_data *fdata;
721:      if (cfile.plist == NULL) return;
722:      for (fdata = cfile.plist; fdata != NULL; fdata = fdata->next) {
723:        if (fdata->flags.marked)
724:          set_frame_mark(TRUE,
725:                 fdata,
726:                 gtk_clist_find_row_from_data(GTK_CLIST(packet_list),
727:                              fdata));
728:      }
729:    }
730:    
731:    void mark_all_frames_cb(GtkWidget *w _U_, gpointer data _U_) {
732:      mark_all_frames(TRUE);
733:    }
734:    
735:    void unmark_all_frames_cb(GtkWidget *w _U_, gpointer data _U_) {
736:      mark_all_frames(FALSE);
737:    }
738:    
739:    /* What to do when a list item is selected/unselected */
740:    static void
741:    packet_list_select_cb(GtkWidget *w _U_, gint row, gint col _U_, gpointer evt _U_) {
742:    
743:    /* Remove the hex display tabbed pages */
744:      while( (gtk_notebook_get_nth_page( GTK_NOTEBOOK(byte_nb_ptr), 0)))
745:        gtk_notebook_remove_page( GTK_NOTEBOOK(byte_nb_ptr), 0);
746:    
747:      select_packet(&cfile, row);
748:    }
749:    
750:    
751:    static void
752:    packet_list_unselect_cb(GtkWidget *w _U_, gint row _U_, gint col _U_, gpointer evt _U_) {
753:    
754:      unselect_packet(&cfile);
755:    }
756:    
757:    
758:    static void
759:    tree_view_select_row_cb(GtkCTree *ctree, GList *node, gint column _U_, gpointer user_data _U_)
760:    {
761:        field_info  *finfo;
762:        gchar       *help_str = NULL;
763:        gboolean        has_blurb = FALSE;
764:        guint           length = 0, byte_len;
765:        GtkWidget   *byte_view;
766:        const guint8    *byte_data;
767:    
768:        g_assert(node);
769:        finfo = gtk_ctree_node_get_row_data( ctree, GTK_CTREE_NODE(node) );
770:        if (!finfo) return;
771:    
772:        set_notebook_page(byte_nb_ptr, finfo->ds_tvb);
773:    
774:        byte_view = get_notebook_bv_ptr(byte_nb_ptr);
775:        byte_data = get_byte_view_data_and_length(byte_view, &byte_len);
776:        g_assert(byte_data != NULL);
777:    
778:        finfo_selected = finfo;
779:        set_menus_for_selected_tree_row(TRUE);
780:    
781:        if (finfo->hfinfo) {
782:          if (finfo->hfinfo->blurb != NULL && 
783:              finfo->hfinfo->blurb[0] != '\0') {
784:            has_blurb = TRUE;
785:            length = strlen(finfo->hfinfo->blurb);
786:          } else {
787:            length = strlen(finfo->hfinfo->name);
788:          }
789:          statusbar_pop_field_msg();    /* get rid of current help msg */
790:              if (length) {
791:            length += strlen(finfo->hfinfo->abbrev) + 10;
792:            help_str = g_malloc(sizeof(gchar) * length);
793:            sprintf(help_str, "%s (%s)", 
794:               (has_blurb) ? finfo->hfinfo->blurb : finfo->hfinfo->name,
795:               finfo->hfinfo->abbrev);
796:            statusbar_push_field_msg(help_str);
797:            g_free(help_str);
798:              } else {
799:                /*
800:             * Don't show anything if the field name is zero-length;
801:             * the pseudo-field for "proto_tree_add_text()" is such
802:             * a field, and we don't want "Text (text)" showing up
803:             * on the status line if you've selected such a field.
804:             *
805:             * XXX - there are zero-length fields for which we *do*
806:             * want to show the field name.
807:             *
808:             * XXX - perhaps the name and abbrev field should be null
809:             * pointers rather than null strings for that pseudo-field,
810:             * but we'd have to add checks for null pointers in some
811:             * places if we did that.
812:             *
813:             * Or perhaps protocol tree items added with
814:             * "proto_tree_add_text()" should have -1 as the field index,
815:             * with no pseudo-field being used, but that might also
816:             * require special checks for -1 to be added.
817:             */
818:            statusbar_push_field_msg("");
819:              }
820:        }
821:    
822:        packet_hex_print(GTK_TEXT(byte_view), byte_data, cfile.current_frame,
823:            finfo, byte_len);
824:    }
825:    
826:    static void
827:    tree_view_unselect_row_cb(GtkCTree *ctree _U_, GList *node _U_, gint column _U_, gpointer user_data _U_)
828:    {
829:        GtkWidget   *byte_view;
830:        const guint8    *data;
831:        guint       len;    
832:    
833:        /*
834:         * Which byte view is displaying the current protocol tree
835:         * row's data?
836:         */
837:        byte_view = get_notebook_bv_ptr(byte_nb_ptr);
838:        if (byte_view == NULL)
839:            return; /* none */
840:    
841:        data = "" &len);
842:        if (data == NULL)
843:            return; /* none */
844:    
845:        unselect_field();
846:        packet_hex_print(GTK_TEXT(byte_view), data, cfile.current_frame,
847:            NULL, len);
848:    }
849:    
850:    void collapse_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
851:      if (cfile.edt->tree)
852:        collapse_all_tree(cfile.edt->tree, tree_view);
853:    }
854:    
855:    void expand_all_cb(GtkWidget *widget _U_, gpointer data _U_) {
856:      if (cfile.edt->tree)
857:        expand_all_tree(cfile.edt->tree, tree_view);
858:    }
859:    
860:    void resolve_name_cb(GtkWidget *widget _U_, gpointer data _U_) {
861:      if (cfile.edt->tree) {
862:        guint32 tmp = g_resolv_flags;
863:        g_resolv_flags = RESOLV_ALL;
864:        proto_tree_draw(cfile.edt->tree, tree_view);
865:        g_resolv_flags = tmp;
866:      }
867:    }
868:    
869:    /* Set the selection mode of the packet list window. */
870:    void
871:    set_plist_sel_browse(gboolean val)
872:    {
873:        gboolean old_val;
874:    
875:        old_val =
876:            (GTK_CLIST(packet_list)->selection_mode == GTK_SELECTION_SINGLE);
877:    
878:        if (val == old_val) {
879:            /*
880:             * The mode isn't changing, so don't do anything.
881:             * In particular, don't gratuitiously unselect the
882:             * current packet.
883:             *
884:             * XXX - why do we have to unselect the current packet
885:             * ourselves?  The documentation for the GtkCList at
886:             *
887:             *  http://developer.gnome.org/doc/API/gtk/gtkclist.html
888:             *
889:             * says "Note that setting the widget's selection mode to
890:             * one of GTK_SELECTION_BROWSE or GTK_SELECTION_SINGLE will
891:             * cause all the items in the GtkCList to become deselected."
892:             */
893:            return;
894:        }
895:    
896:        if (finfo_selected)
897:            unselect_packet(&cfile);
898:    
899:        /* Yeah, GTK uses "browse" in the case where we do not, but oh well. I think
900:         * "browse" in Ethereal makes more sense than "SINGLE" in GTK+ */
901:        if (val) {
902:            gtk_clist_set_selection_mode(GTK_CLIST(packet_list), GTK_SELECTION_SINGLE);
903:        }
904:        else {
905:            gtk_clist_set_selection_mode(GTK_CLIST(packet_list), GTK_SELECTION_BROWSE);
906:        }
907:    }
908:        
909:    /* Set the font of the packet list window. */
910:    void
911:    set_plist_font(GdkFont *font)
912:    {
913:        GtkStyle *style;
914:        int i;
915:    
916:        style = gtk_style_new();
917:        gdk_font_unref(style->font);
918:        style->font = font;
919:        gdk_font_ref(font);
920:    
921:        gtk_widget_set_style(packet_list, style);
922:    
923:        /* Compute static column sizes to use during a "-S" capture, so that
924:           the columns don't resize during a live capture. */
925:        for (i = 0; i < cfile.cinfo.num_cols; i++) {
926:            cfile.cinfo.col_width[i] = gdk_string_width(font,
927:                get_column_longest_string(get_column_format(i)));
928:        }
929:    }
930:    
931:    /*
932:     * Push a message referring to file access onto the statusbar.
933:     */
934:    void
935:    statusbar_push_file_msg(gchar *msg)
936:    {
937:        gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, msg);
938:    }
939:    
940:    /*
941:     * Pop a message referring to file access off the statusbar.
942:     */
943:    void
944:    statusbar_pop_file_msg(void)
945:    {
946:        gtk_statusbar_pop(GTK_STATUSBAR(info_bar), file_ctx);
947:    }
948:    
949:    /*
950:     * XXX - do we need multiple statusbar contexts?
951:     */
952:    
953:    /*
954:     * Push a message referring to the currently-selected field onto the statusbar.
955:     */
956:    void
957:    statusbar_push_field_msg(gchar *msg)
958:    {
959:        gtk_statusbar_push(GTK_STATUSBAR(info_bar), help_ctx, msg);
960:    }
961:    
962:    /*
963:     * Pop a message referring to the currently-selected field off the statusbar.
964:     */
965:    void
966:    statusbar_pop_field_msg(void)
967:    {
968:        gtk_statusbar_pop(GTK_STATUSBAR(info_bar), help_ctx);
969:    }
970:    
971:    static gboolean
972:    do_quit(void)
973:    {
974:        /* XXX - should we check whether the capture file is an
975:           unsaved temporary file for a live capture and, if so,
976:           pop up a "do you want to exit without saving the capture
977:           file?" dialog, and then just return, leaving said dialog
978:           box to forcibly quit if the user clicks "OK"?
979:    
980:           If so, note that this should be done in a subroutine that
981:           returns TRUE if we do so, and FALSE otherwise, and if it
982:           returns TRUE we should return TRUE without nuking anything.
983:    
984:           Note that, if we do that, we might also want to check if
985:           an "Update list of packets in real time" capture is in
986:           progress and, if so, ask whether they want to terminate
987:           the capture and discard it, and return TRUE, before nuking
988:           any child capture, if they say they don't want to do so. */
989:    
990:    #ifdef HAVE_LIBPCAP
991:        /* Nuke any child capture in progress. */
992:        kill_capture_child();
993:    #endif
994:    
995:        /* Are we in the middle of reading a capture? */
996:        if (cfile.state == FILE_READ_IN_PROGRESS) {
997:            /* Yes, so we can't just close the file and quit, as
998:               that may yank the rug out from under the read in
999:               progress; instead, just set the state to
1000:              "FILE_READ_ABORTED" and return - the code doing the read
1001:              will check for that and, if it sees that, will clean
1002:              up and quit. */
1003:           cfile.state = FILE_READ_ABORTED;
1004:   
1005:           /* Say that the window should *not* be deleted;
1006:              that'll be done by the code that cleans up. */
1007:           return TRUE;
1008:       } else {
1009:           /* Close any capture file we have open; on some OSes, you
1010:              can't unlink a temporary capture file if you have it
1011:              open.
1012:              "close_cap_file()" will unlink it after closing it if
1013:              it's a temporary file.
1014:   
1015:              We do this here, rather than after the main loop returns,
1016:              as, after the main loop returns, the main window may have
1017:              been destroyed (if this is called due to a "destroy"
1018:              even on the main window rather than due to the user
1019:              selecting a menu item), and there may be a crash
1020:              or other problem when "close_cap_file()" tries to
1021:              clean up stuff in the main window.
1022:   
1023:              XXX - is there a better place to put this?
1024:              Or should we have a routine that *just* closes the
1025:              capture file, and doesn't do anything with the UI,
1026:              which we'd call here, and another routine that
1027:              calls that routine and also cleans up the UI, which
1028:              we'd call elsewhere? */
1029:           close_cap_file(&cfile);
1030:   
1031:           /* Exit by leaving the main loop, so that any quit functions
1032:              we registered get called. */
1033:           gtk_main_quit();
1034:   
1035:           /* Say that the window should be deleted. */
1036:           return FALSE;
1037:       }
1038:   }
1039:   
1040:   static gboolean
1041:   main_window_delete_event_cb(GtkWidget *widget _U_, GdkEvent *event _U_, gpointer data _U_)
1042:   {
1043:       gint desk_x, desk_y;
1044:   
1045:       /* Try to grab our geometry */
1046:       gdk_window_get_root_origin(top_level->window, &root_x, &root_y);
1047:       if (gdk_window_get_deskrelative_origin(top_level->window,
1048:                   &desk_x, &desk_y)) {
1049:           if (desk_x <= root_x && desk_y <= root_y) {
1050:               root_x = desk_x;
1051:               root_y = desk_y;
1052:           }
1053:       }
1054:   
1055:       /* XXX - Is this the "approved" method? */
1056:       gdk_window_get_size(top_level->window, &top_width, &top_height);
1057:   
1058:       /* "do_quit()" indicates whether the main window should be deleted. */
1059:       return do_quit();
1060:   }
1061:   
1062:   void
1063:   file_quit_cmd_cb (GtkWidget *widget _U_, gpointer data _U_)
1064:   {
1065:       do_quit();
1066:   }
1067:   
1068:   static void 
1069:   print_usage(gboolean print_ver) {
1070:   
1071:     if (print_ver) {
1072:       fprintf(stderr, "This is GNU " PACKAGE " " VERSION ", compiled %s\n",
1073:         comp_info_str->str);
1074:     }  
1075:   #ifdef HAVE_LIBPCAP
1076:     fprintf(stderr, "\n%s [ -vh ] [ -klpQS ] [ -a <capture autostop condition> ] ...\n",
1077:         PACKAGE);
1078:     fprintf(stderr, "\t[ -b <number of ringbuffer files> ] [ -B <byte view height> ]\n");
1079:     fprintf(stderr, "\t[ -c <count> ] [ -f <capture filter> ] [ -i <interface> ]\n");
1080:     fprintf(stderr, "\t[ -m <medium font> ] [ -n ] [ -N <resolving> ]\n");
1081:     fprintf(stderr, "\t[ -o <preference setting> ] ... [ -P <packet list height> ]\n");
1082:     fprintf(stderr, "\t[ -r <infile> ] [ -R <read filter> ] [ -s <snaplen> ] \n");
1083:     fprintf(stderr, "\t[ -t <time stamp format> ] [ -T <tree view height> ]\n");
1084:     fprintf(stderr, "\t[ -w <savefile> ] [ <infile> ]\n");
1085:   #else
1086:     fprintf(stderr, "\n%s [ -vh ] [ -B <byte view height> ] [ -m <medium font> ]\n",
1087:         PACKAGE);
1088:     fprintf(stderr, "\t[ -n ] [ -N <resolving> ]\n");
1089:     fprintf(stderr, "\t[ -o <preference setting> ... [ -P <packet list height> ]\n");
1090:     fprintf(stderr, "\t[ -r <infile> ] [ -R <read filter> ] [ -t <time stamp format> ]\n");
1091:     fprintf(stderr, "\t[ -T <tree view height> ] [ <infile> ]\n");
1092:   #endif
1093:   }
1094:   
1095:   static void 
1096:   show_version(void)
1097:   {
1098:   #ifdef WIN32
1099:     create_console();
1100:   #endif
1101:   
1102:     printf("%s %s, %s\n", PACKAGE, VERSION, comp_info_str->str);
1103:   }
1104:   
1105:   static int
1106:   get_positive_int(const char *string, const char *name)
1107:   {
1108:     long number;
1109:     char *p;
1110:   
1111:     number = strtol(string, &p, 10);
1112:     if (p == string || *p != '\0') {
1113:       fprintf(stderr, "ethereal: The specified %s \"%s\" is not a decimal number\n",
1114:           name, string);
1115:       exit(1);
1116:     }
1117:     if (number < 0) {
1118:       fprintf(stderr, "ethereal: The specified %s \"%s\" is a negative number\n",
1119:           name, string);
1120:       exit(1);
1121:     }
1122:     if (number == 0) {
1123:       fprintf(stderr, "ethereal: The specified %s \"%s\" is zero\n",
1124:               name, string);
1125:       exit(1);
1126:     }
1127:     if (number > INT_MAX) {
1128:       fprintf(stderr, "ethereal: The specified %s \"%s\" is too large (greater than %d)\n",
1129:           name, string, INT_MAX);
1130:       exit(1);
1131:     }
1132:     return number;
1133:   }
1134:   
1135:   #ifdef HAVE_LIBPCAP
1136:   /*
1137:    * Given a string of the form "<autostop criterion>:<value>", as might appear
1138:    * as an argument to a "-a" option, parse it and set the criterion in
1139:    * question.  Return an indication of whether it succeeded or failed
1140:    * in some fashion.
1141:    */
1142:   static gboolean
1143:   set_autostop_criterion(const char *autostoparg)
1144:   {
1145:     u_char *p, *colonp;
1146:   
1147:     colonp = strchr(autostoparg, ':');
1148:     if (colonp == NULL)
1149:       return FALSE;
1150:   
1151:     p = colonp;
1152:     *p++ = '\0';
1153:   
1154:     /*
1155:      * Skip over any white space (there probably won't be any, but
1156:      * as we allow it in the preferences file, we might as well
1157:      * allow it here).
1158:      */
1159:     while (isspace(*p))
1160:       p++;
1161:     if (*p == '\0') {
1162:       /*
1163:        * Put the colon back, so if our caller uses, in an
1164:        * error message, the string they passed us, the message
1165:        * looks correct.
1166:        */
1167:       *colonp = ':';
1168:       return FALSE;
1169:     }
1170:     if (strcmp(autostoparg,"duration") == 0) {
1171:       capture_opts.has_autostop_duration = TRUE;
1172:       capture_opts.autostop_duration = get_positive_int(p,"autostop duration");
1173:     } else if (strcmp(autostoparg,"filesize") == 0) {
1174:       capture_opts.has_autostop_filesize = TRUE;
1175:       capture_opts.autostop_filesize = get_positive_int(p,"autostop filesize");
1176:     } else {
1177:       return FALSE;
1178:     }
1179:     *colonp = ':'; /* put the colon back */
1180:     return TRUE;
1181:   }
1182:   #endif
1183:   
1184:   /* And now our feature presentation... [ fade to music ] */
1185:   int
1186:   main(int argc, char *argv[])
1187:   {
1188:   #ifdef HAVE_LIBPCAP
1189:     char                *command_name;
1190:   #endif
1191:     char                *s;
1192:     int                  i;
1193:     int                  opt;
1194:     extern char         *optarg;
1195:     gboolean             arg_error = FALSE;
1196:   #ifdef HAVE_LIBPCAP
1197:   #ifdef HAVE_PCAP_VERSION
1198:     extern char          pcap_version[];
1199:   #endif /* HAVE_PCAP_VERSION */
1200:   #endif /* HAVE_LIBPCAP */
1201:     
1202:   #ifdef WIN32
1203:     WSADATA          wsaData; 
1204:   #endif
1205:   
1206:     char                *gpf_path, *cf_path, *df_path;
1207:     const char          *pf_path;
1208:     int                  gpf_open_errno, pf_open_errno, cf_open_errno, df_open_errno;
1209:     int                  err;
1210:   #ifdef HAVE_LIBPCAP
1211:     gboolean             start_capture = FALSE;
1212:     gchar               *save_file = NULL;
1213:     GList               *if_list;
1214:     gchar                err_str[PCAP_ERRBUF_SIZE];
1215:     gboolean             stats_known;
1216:     struct pcap_stat     stats;
1217:   #else
1218:     gboolean             capture_option_specified = FALSE;
1219:   #endif
1220:     gint                 pl_size = 280, tv_size = 95, bv_size = 75;
1221:     gchar               *rc_file, *cf_name = NULL, *rfilter = NULL;
1222:     dfilter_t           *rfcode = NULL;
1223:     gboolean             rfilter_parse_failed = FALSE;
1224:     e_prefs             *prefs;
1225:     char                 badopt;
1226:     char                *bold_font_name;
1227:     gint                 desk_x, desk_y;
1228:     gboolean             prefs_write_needed = FALSE;
1229:   
1230:   #define OPTSTRING_INIT "a:b:B:c:f:hi:klm:nN:o:pP:Qr:R:Ss:t:T:w:v"
1231:   
1232:   #ifdef HAVE_LIBPCAP
1233:   #ifdef WIN32
1234:   #define OPTSTRING_CHILD "W:Z:"
1235:   #else
1236:   #define OPTSTRING_CHILD "W:"
1237:   #endif  /* WIN32 */
1238:   #else
1239:   #define OPTSTRING_CHILD ""
1240:   #endif  /* HAVE_LIBPCAP */
1241:   
1242:     char optstring[sizeof(OPTSTRING_INIT) + sizeof(OPTSTRING_CHILD) - 1] =
1243:       OPTSTRING_INIT;
1244:   
1245:     ethereal_path = argv[0];
1246:   
1247:   #ifdef WIN32
1248:     /* Arrange that if we have no console window, and a GLib message logging
1249:        routine is called to log a message, we pop up a console window.
1250:   
1251:        We do that by inserting our own handler for all messages logged
1252:        to the default domain; that handler pops up a console if necessary,
1253:        and then calls the default handler. */
1254:     g_log_set_handler(NULL,
1255:               G_LOG_LEVEL_ERROR|
1256:               G_LOG_LEVEL_CRITICAL|
1257:               G_LOG_LEVEL_WARNING|
1258:               G_LOG_LEVEL_MESSAGE|
1259:               G_LOG_LEVEL_INFO|
1260:               G_LOG_LEVEL_DEBUG|
1261:               G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION,
1262:               console_log_handler, NULL);
1263:   #endif
1264:   
1265:   #ifdef HAVE_LIBPCAP
1266:     command_name = get_basename(ethereal_path);
1267:     /* Set "capture_child" to indicate whether this is going to be a child
1268:        process for a "-S" capture. */
1269:     capture_child = (strcmp(command_name, CHILD_NAME) == 0);
1270:     if (capture_child)
1271:       strcat(optstring, OPTSTRING_CHILD);
1272:   #endif
1273:   
1274:     /* Register all dissectors; we must do this before checking for the
1275:        "-G" flag, as the "-G" flag dumps information registered by the
1276:        dissectors, and we must do it before we read the preferences, in
1277:        case any dissectors register preferences. */
1278:     epan_init(PLUGIN_DIR,register_all_protocols,register_all_protocol_handoffs);
1279:   
1280:     /* Now register the preferences for any non-dissector modules.
1281:        We must do that before we read the preferences as well. */
1282:     prefs_register_modules();
1283:   
1284:     /* If invoked with the "-G" flag, we dump out information based on
1285:        the argument to the "-G" flag; if no argument is specified,
1286:        for backwards compatibility we dump out a glossary of display
1287:        filter symbols.
1288:   
1289:        We must do this before calling "gtk_init()", because "gtk_init()"
1290:        tries to open an X display, and we don't want to have to do any X
1291:        stuff just to do a build.
1292:   
1293:        Given that we call "gtk_init()" before doing the regular argument
1294:        list processing, so that it can handle X and GTK+ arguments and
1295:        remove them from the list at which we look, this means we must do
1296:        this before doing the regular argument list processing, as well.
1297:   
1298:        This means that:
1299:   
1300:       you must give the "-G" flag as the first flag on the command line;
1301:   
1302:       you must give it as "-G", nothing more, nothing less;
1303:   
1304:       the first argument after the "-G" flag, if present, will be used
1305:       to specify the information to dump;
1306:   
1307:       arguments after that will not be used. */
1308:     if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
1309:       if (argc == 2)
1310:         proto_registrar_dump_fields();
1311:       else {
1312:         if (strcmp(argv[2], "fields") == 0)
1313:           proto_registrar_dump_fields();
1314:         else if (strcmp(argv[2], "protocols") == 0)
1315:           proto_registrar_dump_protocols();
1316:         else {
1317:           fprintf(stderr, "tethereal: Invalid \"%s\" option for -G flag\n",
1318:                   argv[2]);
1319:           exit(1);
1320:         }
1321:       }
1322:       exit(0);
1323:     }
1324:   
1325:     /* Set the current locale according to the program environment. 
1326:      * We haven't localized anything, but some GTK widgets are localized
1327:      * (the file selection dialogue, for example).
1328:      * This also sets the C-language locale to the native environment. */
1329:     gtk_set_locale();
1330:   
1331:     /* Let GTK get its args */
1332:     gtk_init (&argc, &argv);
1333:     
1334:     /* Read the preference files. */
1335:     prefs = read_prefs(&gpf_open_errno, &gpf_path, &pf_open_errno, &pf_path);
1336:   
1337:   #ifdef HAVE_LIBPCAP
1338:     capture_opts.has_snaplen = FALSE;
1339:     capture_opts.snaplen = MIN_PACKET_SIZE;
1340:     capture_opts.has_autostop_count = FALSE;
1341:     capture_opts.autostop_count = 1;
1342:     capture_opts.has_autostop_duration = FALSE;
1343:     capture_opts.autostop_duration = 1;
1344:     capture_opts.has_autostop_filesize = FALSE;
1345:     capture_opts.autostop_filesize = 1;
1346:     capture_opts.ringbuffer_on = FALSE;
1347:     capture_opts.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
1348:   
1349:     /* If this is a capture child process, it should pay no attention
1350:        to the "prefs.capture_prom_mode" setting in the preferences file;
1351:        it should do what the parent process tells it to do, and if
1352:        the parent process wants it not to run in promiscuous mode, it'll
1353:        tell it so with a "-p" flag.
1354:   
1355:        Otherwise, set promiscuous mode from the preferences setting. */
1356:     if (capture_child)
1357:       capture_opts.promisc_mode = TRUE;
1358:     else
1359:       capture_opts.promisc_mode = prefs->capture_prom_mode;
1360:   
1361:     /* Set "Update list of packets in real time" mode from the preferences
1362:        setting. */
1363:     capture_opts.sync_mode = prefs->capture_real_time;
1364:   
1365:     /* And do the same for "Automatic scrolling in live capture" mode. */
1366:     auto_scroll_live = prefs->capture_auto_scroll;
1367:   #endif
1368:   
1369:     /* Set the name resolution code's flags from the preferences. */
1370:     g_resolv_flags = prefs->name_resolve;
1371:   
1372:     /* Read the capture filter file. */
1373:     read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
1374:   
1375:     /* Read the display filter file. */
1376:     read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
1377:   
1378:     /* Initialize the capture file struct */
1379:     cfile.plist       = NULL;
1380:     cfile.plist_end   = NULL;
1381:     cfile.wth     = NULL;
1382:     cfile.filename    = NULL;
1383:     cfile.user_saved  = FALSE;
1384:     cfile.is_tempfile = FALSE;
1385:     cfile.rfcode      = NULL;
1386:     cfile.dfilter     = NULL;
1387:     cfile.dfcode      = NULL;
1388:   #ifdef HAVE_LIBPCAP
1389:     cfile.cfilter     = g_strdup(EMPTY_FILTER);
1390:   #endif
1391:     cfile.iface       = NULL;
1392:     cfile.save_file   = NULL;
1393:     cfile.save_file_fd    = -1;
1394:   
1395:     cfile.ipaddr      = NULL;
1396:     cfile.has_ipaddr  = FALSE;
1397:     cfile.v5iface     = NULL;
1398:     cfile.has_v5iface = FALSE;
1399:   
1394:     cfile.has_snap    = FALSE;
1395:     cfile.snap        = WTAP_MAX_PACKET_SIZE;
1396:     cfile.count       = 0;
1397:     col_init(&cfile.cinfo, prefs->num_cols);
1398:   
1399:     /* Assemble the compile-time options */
1400:     comp_info_str = g_string_new("");
1401:   
1402:     g_string_append(comp_info_str, "with ");
1403:     g_string_sprintfa(comp_info_str,
1404:   #ifdef GTK_MAJOR_VERSION
1405:       "GTK+ %d.%d.%d", GTK_MAJOR_VERSION, GTK_MINOR_VERSION,
1406:       GTK_MICRO_VERSION);
1407:   #else
1408:       "GTK+ (version unknown)");
1409:   #endif
1410:   
1411:     g_string_append(comp_info_str, ", with ");
1412:     g_string_sprintfa(comp_info_str,
1413:   #ifdef GLIB_MAJOR_VERSION
1414:       "GLib %d.%d.%d", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION,
1415:       GLIB_MICRO_VERSION);
1416:   #else
1417:       "GLib (version unknown)");
1418:   #endif
1419:   
1420:   #ifdef HAVE_LIBPCAP
1421:     g_string_append(comp_info_str, ", with libpcap ");
1422:   #ifdef HAVE_PCAP_VERSION
1423:     g_string_append(comp_info_str, pcap_version);
1424:   #else /* HAVE_PCAP_VERSION */
1425:     g_string_append(comp_info_str, "(version unknown)");
1426:   #endif /* HAVE_PCAP_VERSION */
1427:   #else /* HAVE_LIBPCAP */
1428:     g_string_append(comp_info_str, ", without libpcap");
1429:   #endif /* HAVE_LIBPCAP */
1430:   
1431:   #ifdef HAVE_LIBZ
1432:     g_string_append(comp_info_str, ", with libz ");
1433:   #ifdef ZLIB_VERSION
1434:     g_string_append(comp_info_str, ZLIB_VERSION);
1435:   #else /* ZLIB_VERSION */
1436:     g_string_append(comp_info_str, "(version unknown)");
1437:   #endif /* ZLIB_VERSION */
1438:   #else /* HAVE_LIBZ */
1439:     g_string_append(comp_info_str, ", without libz");
1440:   #endif /* HAVE_LIBZ */
1441:   
1442:   /* Oh, this is pretty */
1443:   #ifdef HAVE_UCD_SNMP
1444:     g_string_append(comp_info_str, ", with UCD SNMP ");
1445:   #ifdef HAVE_UCD_SNMP_VERSION_H
1446:     g_string_append(comp_info_str, VersionInfo);
1447:   #else /* HAVE_UCD_SNMP_VERSION_H */
1448:     g_string_append(comp_info_str, "(version unknown)");
1449:   #endif /* HAVE_UCD_SNMP_VERSION_H */
1450:   #else /* no SNMP library */
1451:     g_string_append(comp_info_str, ", without UCD SNMP");
1452:   #endif
1453:   
1454:     /* Now get our args */
1455:     while ((opt = getopt(argc, argv, optstring)) != -1) {
1456:       switch (opt) {
1457:         case 'a':        /* autostop criteria */
1458:   #ifdef HAVE_LIBPCAP
1459:           if (set_autostop_criterion(optarg) == FALSE) {
1460:             fprintf(stderr, "ethereal: Invalid or unknown -a flag \"%s\"\n", optarg);
1461:             exit(1);          
1462:           }
1463:   #else
1464:           capture_option_specified = TRUE;
1465:           arg_error = TRUE;
1466:   #endif
1467:           break;
1468:         case 'b':        /* Ringbuffer option */
1469:   #ifdef HAVE_LIBPCAP
1470:           capture_opts.ringbuffer_on = TRUE;
1471:           capture_opts.ringbuffer_num_files =
1472:             get_positive_int(optarg, "number of ring buffer files");
1473:   #else
1474:           capture_option_specified = TRUE;
1475:           arg_error = TRUE;
1476:   #endif
1477:           break;
1478:         case 'B':        /* Byte view pane height */
1479:           bv_size = get_positive_int(optarg, "byte view pane height");
1480:           break;
1481:         case 'c':        /* Capture xxx packets */
1482:   #ifdef HAVE_LIBPCAP
1483:           capture_opts.has_autostop_count = TRUE;
1484:           capture_opts.autostop_count = get_positive_int(optarg, "packet count");
1485:   #else
1486:           capture_option_specified = TRUE;
1487:           arg_error = TRUE;
1488:   #endif
1489:           break;
1490:         case 'f':
1491:   #ifdef HAVE_LIBPCAP
1492:       if (cfile.cfilter)
1493:           g_free(cfile.cfilter);
1494:       cfile.cfilter = g_strdup(optarg);
1495:   #else
1496:           capture_option_specified = TRUE;
1497:           arg_error = TRUE;
1498:   #endif
1499:       break;
1500:         case 'h':        /* Print help and exit */
1501:       print_usage(TRUE);
1502:       exit(0);
1503:           break;
1504:         case 'i':        /* Use interface xxx */
1505:   #ifdef HAVE_LIBPCAP
1506:           cfile.iface = g_strdup(optarg);
1507:   #else
1508:           capture_option_specified = TRUE;
1509:           arg_error = TRUE;
1510:   #endif
1511:           break;
1512:         case 'k':        /* Start capture immediately */
1513:   #ifdef HAVE_LIBPCAP
1514:           start_capture = TRUE;
1515:   #else
1516:           capture_option_specified = TRUE;
1517:           arg_error = TRUE;
1518:   #endif
1519:           break;
1520:         case 'l':        /* Automatic scrolling in live capture mode */
1521:   #ifdef HAVE_LIBPCAP
1522:           auto_scroll_live = TRUE;
1523:   #else
1524:           capture_option_specified = TRUE;
1525:           arg_error = TRUE;
1526:   #endif
1527:           break;
1528:         case 'm':        /* Fixed-width font for the display */
1529:           if (prefs->gui_font_name != NULL)
1530:             g_free(prefs->gui_font_name);
1531:           prefs->gui_font_name = g_strdup(optarg);
1532:           break;
1533:         case 'n':        /* No name resolution */
1534:           g_resolv_flags = RESOLV_NONE;
1535:           break;
1536:         case 'N':        /* Select what types of addresses/port #s to resolve */
1537:           if (g_resolv_flags == RESOLV_ALL)
1538:             g_resolv_flags = RESOLV_NONE;
1539:           badopt = string_to_name_resolve(optarg, &g_resolv_flags);
1540:           if (badopt != '\0') {
1541:             fprintf(stderr, "ethereal: -N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'\n",
1542:               badopt);
1543:             exit(1);
1544:           }
1545:           break;
1546:         case 'o':        /* Override preference from command line */
1547:           switch (prefs_set_pref(optarg)) {
1548:   
1549:       case PREFS_SET_SYNTAX_ERR:
1550:             fprintf(stderr, "ethereal: Invalid -o flag \"%s\"\n", optarg);
1551:             exit(1);
1552:             break;
1553:   
1554:           case PREFS_SET_NO_SUCH_PREF:
1555:           case PREFS_SET_OBSOLETE:
1556:             fprintf(stderr, "ethereal: -o flag \"%s\" specifies unknown preference\n",
1557:               optarg);
1558:             exit(1);
1559:             break;
1560:           }
1561:           break;
1562:         case 'p':        /* Don't capture in promiscuous mode */
1563:   #ifdef HAVE_LIBPCAP
1564:       capture_opts.promisc_mode = FALSE;
1565:   #else
1566:           capture_option_specified = TRUE;
1567:           arg_error = TRUE;
1568:   #endif
1569:       break;
1570:         case 'P':        /* Packet list pane height */
1571:           pl_size = get_positive_int(optarg, "packet list pane height");
1572:           break;
1573:         case 'Q':        /* Quit after capture (just capture to file) */
1574:   #ifdef HAVE_LIBPCAP
1575:           quit_after_cap = 1;
1576:           start_capture = TRUE;  /*** -Q implies -k !! ***/
1577:   #else
1578:           capture_option_specified = TRUE;
1579:           arg_error = TRUE;
1580:   #endif
1581:           break;
1582:         case 'r':        /* Read capture file xxx */
1583:       /* We may set "last_open_dir" to "cf_name", and if we change
1584:          "last_open_dir" later, we free the old value, so we have to
1585:          set "cf_name" to something that's been allocated. */
1586:           cf_name = g_strdup(optarg);
1587:           break;
1588:         case 'R':        /* Read file filter */
1589:           rfilter = optarg;
1590:           break;
1591:         case 's':        /* Set the snapshot (capture) length */
1592:   #ifdef HAVE_LIBPCAP
1593:           capture_opts.has_snaplen = TRUE;
1594:           capture_opts.snaplen = get_positive_int(optarg, "snapshot length");
1595:   #else
1596:           capture_option_specified = TRUE;
1597:           arg_error = TRUE;
1598:   #endif
1599:           break;
1600:         case 'S':        /* "Sync" mode: used for following file ala tail -f */
1601:   #ifdef HAVE_LIBPCAP
1602:           capture_opts.sync_mode = TRUE;
1603:   #else
1604:           capture_option_specified = TRUE;
1605:           arg_error = TRUE;
1606:   #endif
1607:           break;
1608:         case 't':        /* Time stamp type */
1609:           if (strcmp(optarg, "r") == 0)
1610:             timestamp_type = RELATIVE;
1611:           else if (strcmp(optarg, "a") == 0)
1612:             timestamp_type = ABSOLUTE;
1613:           else if (strcmp(optarg, "ad") == 0)
1614:             timestamp_type = ABSOLUTE_WITH_DATE;
1615:           else if (strcmp(optarg, "d") == 0)
1616:             timestamp_type = DELTA;
1617:           else {
1618:             fprintf(stderr, "ethereal: Invalid time stamp type \"%s\"\n",
1619:               optarg);
1620:             fprintf(stderr, "It must be \"r\" for relative, \"a\" for absolute,\n");
1621:             fprintf(stderr, "\"ad\" for absolute with date, or \"d\" for delta.\n");
1622:             exit(1);
1623:           }
1624:           break;
1625:         case 'T':        /* Tree view pane height */
1626:           tv_size = get_positive_int(optarg, "tree view pane height");
1627:           break;
1628:         case 'v':        /* Show version and exit */
1629:           show_version();
1630:   #ifdef WIN32
1631:           if (console_was_created)
1632:             destroy_console();
1633:   #endif
1634:           exit(0);
1635:           break;
1636:         case 'w':        /* Write to capture file xxx */
1637:   #ifdef HAVE_LIBPCAP
1638:           save_file = g_strdup(optarg);
1639:   #else
1640:           capture_option_specified = TRUE;
1641:           arg_error = TRUE;
1642:   #endif
1643:       break;
1644:   #ifdef HAVE_LIBPCAP
1645:         /* This is a hidden option supporting Sync mode, so we don't set
1646:          * the error flags for the user in the non-libpcap case.
1647:          */
1648:         case 'W':        /* Write to capture file FD xxx */
1649:           cfile.save_file_fd = atoi(optarg);
1650:       break;
1651:   #endif
1652:   
1653:   #ifdef _WIN32
1654:   #ifdef HAVE_LIBPCAP
1655:         /* Hidden option supporting Sync mode */
1656:         case 'Z':        /* Write to pipe FD XXX */
1657:           /* associate stdout with pipe */
1658:           i = atoi(optarg);
1659:           if (dup2(i, 1) < 0) {
1660:             fprintf(stderr, "Unable to dup pipe handle\n");
1661:             exit(1);
1662:           }
1663:           break;
1664:   #endif /* HAVE_LIBPCAP */
1665:   #endif /* _WIN32 */
1666:   
1667:         default:
1668:         case '?':        /* Bad flag - print usage message */
1669:           arg_error = TRUE;
1670:           break;
1671:       }
1672:     }
1673:     argc -= optind;
1674:     argv += optind;
1675:     if (argc >= 1) {
1676:       if (cf_name != NULL) {
1677:         /*
1678:          * Input file name specified with "-r" *and* specified as a regular
1679:          * command-line argument.
1680:          */
1681:         arg_error = TRUE;
1682:       } else {
1683:         /*
1684:          * Input file name not specified with "-r", and a command-line argument
1685:          * was specified; treat it as the input file name.
1686:          *
1687:          * Yes, this is different from tethereal, where non-flag command-line
1688:          * arguments are a filter, but this works better on GUI desktops
1689:          * where a command can be specified to be run to open a particular
1690:          * file - yes, you could have "-r" as the last part of the command,
1691:          * but that's a bit ugly.
1692:          */
1693:         cf_name = g_strdup(argv[0]);
1694:       }
1695:       argc--;
1696:       argv++;
1697:     }
1698:   
1699:     if (argc != 0) {
1700:       /*
1701:        * Extra command line arguments were specified; complain.
1702:        */
1703:       fprintf(stderr, "Invalid argument: %s\n", argv[0]);
1704:       arg_error = TRUE;
1705:     }
1706:     if (arg_error) {
1707:       print_usage(FALSE);
1708:       exit(1);
1709:     }
1710:   
1711:   #ifdef HAVE_LIBPCAP
1712:     if (capture_opts.ringbuffer_on) {
1713:       /* Ring buffer works only under certain conditions:
1714:          a) ring buffer does not work with temporary files;
1715:          b) sync_mode and capture_opts.ringbuffer_on are mutually exclusive -
1716:             sync_mode takes precedence;
1717:          c) it makes no sense to enable the ring buffer if the maximum
1718:             file size is set to "infinite". */
1719:       if (cfile.save_file == NULL) {
1720:         fprintf(stderr, "ethereal: Ring buffer requested, but capture isn't being saved to a permanent file.\n");
1721:         capture_opts.ringbuffer_on = FALSE;
1722:       }
1723:       if (capture_opts.sync_mode) {
1724:         fprintf(stderr, "ethereal: Ring buffer requested, but an \"Update list of packets in real time\" capture is being done.\n");
1725:         capture_opts.ringbuffer_on = FALSE;
1726:       }
1727:       if (!capture_opts.has_autostop_filesize) {
1728:         fprintf(stderr, "ethereal: Ring buffer requested, but no maximum capture file size was specified.\n");
1729:         capture_opts.ringbuffer_on = FALSE;
1730:       }
1731:     }
1732:   #endif
1733:   
1734:   #ifdef WIN32
1735:     /* Load wpcap if possible */
1736:     load_wpcap();
1737:   
1738:     /* Start windows sockets */
1739:     WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
1740:   #endif
1741:   
1742:     /* Notify all registered modules that have had any of their preferences
1743:        changed either from one of the preferences file or from the command
1744:        line that its preferences have changed. */
1745:     prefs_apply_all();
1746:   
1747:   #ifndef HAVE_LIBPCAP
1748:     if (capture_option_specified)
1749:       fprintf(stderr, "This version of Ethereal was not built with support for capturing packets.\n");
1750:   #endif
1751:   #ifdef HAVE_LIBPCAP
1752:     if (start_capture) {
1753:       /* We're supposed to do a live capture; did the user specify an interface
1754:          to use? */
1755:       if (cfile.iface == NULL) {
1756:         /* No - is a default specified in the preferences file? */
1757:         if (prefs->capture_device != NULL) {
1758:             /* Yes - use it. */
1759:             cfile.iface = g_strdup(prefs->capture_device);
1760:         } else {
1761:           /* No - pick the first one from the list of interfaces. */
1762:           if_list = get_interface_list(&err, err_str);
1763:           if (if_list == NULL) {
1764:             switch (err) {
1765:     
1766:             case CANT_GET_INTERFACE_LIST:
1767:                 fprintf(stderr, "ethereal: Can't get list of interfaces: %s\n",
1768:               err_str);
1769:                 break;
1770:     
1771:             case NO_INTERFACES_FOUND:
1772:                 fprintf(stderr, "ethereal: There are no interfaces on which a capture can be done\n");
1773:                 break;
1774:             }
1775:             exit(2);
1776:           }
1777:           cfile.iface = g_strdup(if_list->data);  /* first interface */
1778:           free_interface_list(if_list);
1779:         }
1780:       }
1781:     }
1782:     if (capture_child) {
1783:       if (cfile.save_file_fd == -1) {
1784:         /* XXX - send this to the standard output as something our parent
1785:            should put in an error message box? */
1786:         fprintf(stderr, "%s: \"-W\" flag not specified\n", CHILD_NAME);
1787:         exit(1);
1788:       }
1789:     }
1790:   #endif
1791:   
1792:     /* Build the column format array */  
1793:     for (i = 0; i < cfile.cinfo.num_cols; i++) {
1794:       cfile.cinfo.col_fmt[i] = get_column_format(i);
1795:       cfile.cinfo.col_title[i] = g_strdup(get_column_title(i));
1796:       cfile.cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
1797:         NUM_COL_FMTS);
1798:       get_column_format_matches(cfile.cinfo.fmt_matx[i], cfile.cinfo.col_fmt[i]);
1799:       cfile.cinfo.col_data[i] = NULL;
1800:       if (cfile.cinfo.col_fmt[i] == COL_INFO)
1801:         cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
1802:       else
1803:         cfile.cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
1804:       cfile.cinfo.col_expr[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
1805:       cfile.cinfo.col_expr_val[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
1806:     }
1807:   
1808:   #ifdef HAVE_LIBPCAP
1809:     if (capture_opts.has_snaplen) {
1810:       if (capture_opts.snaplen < 1)
1811:         capture_opts.snaplen = WTAP_MAX_PACKET_SIZE;
1812:       else if (capture_opts.snaplen < MIN_PACKET_SIZE)
1813:         capture_opts.snaplen = MIN_PACKET_SIZE;
1814:     }
1815:     
1816:     /* Check the value range of the ringbuffer_num_files parameter */
1817:     if (capture_opts.ringbuffer_num_files < RINGBUFFER_MIN_NUM_FILES)
1818:       capture_opts.ringbuffer_num_files = RINGBUFFER_MIN_NUM_FILES;
1819:     else if (capture_opts.ringbuffer_num_files > RINGBUFFER_MAX_NUM_FILES)
1820:       capture_opts.ringbuffer_num_files = RINGBUFFER_MAX_NUM_FILES;
1821:   #endif
1822:     
1823:     rc_file = get_persconffile_path(RC_FILE, FALSE);
1824:     gtk_rc_parse(rc_file);
1825:   
1826:     /* Try to load the regular and boldface fixed-width fonts */
1827:     bold_font_name = boldify(prefs->gui_font_name);
1828:     m_r_font = gdk_font_load(prefs->gui_font_name);
1829:     m_b_font = gdk_font_load(bold_font_name);
1830:     if (m_r_font == NULL || m_b_font == NULL) {
1831:       /* XXX - pop this up as a dialog box? no */
1832:       if (m_r_font == NULL) {
1833:   #ifdef HAVE_LIBPCAP
1834:         if (!capture_child)
1835:   #endif
1836:       fprintf(stderr, "ethereal: Warning: font %s not found - defaulting to 6x13 and 6x13bold\n",
1837:           prefs->gui_font_name);
1838:       } else {
1839:         gdk_font_unref(m_r_font);
1840:       }
1841:       if (m_b_font == NULL) {
1842:   #ifdef HAVE_LIBPCAP
1843:         if (!capture_child)
1844:   #endif
1845:       fprintf(stderr, "ethereal: Warning: font %s not found - defaulting to 6x13 and 6x13bold\n",
1846:           bold_font_name);
1847:       } else {
1848:         gdk_font_unref(m_b_font);
1849:       }
1850:       g_free(bold_font_name);
1851:       if ((m_r_font = gdk_font_load("6x13")) == NULL) {
1852:         fprintf(stderr, "ethereal: Error: font 6x13 not found\n");
1853:         exit(1);
1854:       }
1855:       if ((m_b_font = gdk_font_load("6x13bold")) == NULL) {
1856:         fprintf(stderr, "ethereal: Error: font 6x13bold not found\n");
1857:         exit(1);
1858:       }
1859:       g_free(prefs->gui_font_name);
1860:       prefs->gui_font_name = g_strdup("6x13");
1861:     }
1862:   
1863:     /* Call this for the side-effects that set_fonts() produces */
1864:     set_fonts(m_r_font, m_b_font);
1865:   
1866:   
1867:   #ifdef HAVE_LIBPCAP
1868:     /* Is this a "child" ethereal, which is only supposed to pop up a
1869:        capture box to let us stop the capture, and run a capture
1870:        to a file that our parent will read? */
1871:     if (!capture_child) {
1872:   #endif
1873:       /* No.  Pop up the main window, and read in a capture file if
1874:          we were told to. */
1875:   
1876:       create_main_window(pl_size, tv_size, bv_size, prefs);
1877:       set_menus_for_capture_file(FALSE);
1878:   
1879:       colfilter_init();
1880:   
1881:       /* If we were given the name of a capture file, read it in now;
1882:          we defer it until now, so that, if we can't open it, and pop
1883:          up an alert box, the alert box is more likely to come up on
1884:          top of the main window - but before the preference-file-error
1885:          alert box, so, if we get one of those, it's more likely to come
1886:          up on top of us. */
1887:       if (cf_name) {
1888:         if (rfilter != NULL) {
1889:           if (!dfilter_compile(rfilter, &rfcode)) {
1890:             simple_dialog(ESD_TYPE_CRIT, NULL, dfilter_error_msg);
1891:             rfilter_parse_failed = TRUE;
1892:           }
1893:         }
1894:         if (!rfilter_parse_failed) {
1895:           if ((err = open_cap_file(cf_name, FALSE, &cfile)) == 0) {
1896:             /* "open_cap_file()" succeeded, so it closed the previous
1897:            capture file, and thus destroyed any previous read filter
1898:            attached to "cf". */
1899:             cfile.rfcode = rfcode;
1900:             switch (read_cap_file(&cfile, &err)) {
1901:   
1902:             case READ_SUCCESS:
1903:             case READ_ERROR:
1904:               /* Just because we got an error, that doesn't mean we were unable
1905:                  to read any of the file; we handle what we could get from the
1906:                  file. */
1907:               break;
1908:   
1909:             case READ_ABORTED:
1910:               /* Exit now. */
1911:               gtk_exit(0);
1912:               break;
1913:             }
1914:             /* Save the name of the containing directory specified in the
1915:            path name, if any; we can write over cf_name, which is a
1916:                good thing, given that "get_dirname()" does write over its
1917:                argument. */
1918:             s = get_dirname(cf_name);
1919:         set_last_open_dir(s);
1920:           } else {
1921:             if (rfcode != NULL)
1922:               dfilter_free(rfcode);
1923:             cfile.rfcode = NULL;
1924:           }
1925:         }
1926:       }
1927:   #ifdef HAVE_LIBPCAP
1928:     }
1929:   #endif
1930:   
1931:     /* If the global preferences file exists but we failed to open it,
1932:        pop up an alert box; we defer that until now, so that the alert
1933:        box is more likely to come up on top of the main window. */
1934:     if (gpf_path != NULL) {
1935:         simple_dialog(ESD_TYPE_WARN, NULL,
1936:           "Could not open global preferences file\n\"%s\": %s.", gpf_path,
1937:           strerror(gpf_open_errno));
1938:     }
1939:   
1940:     /* If the user's preferences file exists but we failed to open it,
1941:        pop up an alert box; we defer that until now, so that the alert
1942:        box is more likely to come up on top of the main window. */
1943:     if (pf_path != NULL) {
1944:         simple_dialog(ESD_TYPE_WARN, NULL,
1945:           "Could not open your preferences file\n\"%s\": %s.", pf_path,
1946:           strerror(pf_open_errno));
1947:     }
1948:   
1949:     /* If the user's capture filter file exists but we failed to open it,
1950:        pop up an alert box; we defer that until now, so that the alert
1951:        box is more likely to come up on top of the main window. */
1952:     if (cf_path != NULL) {
1953:         simple_dialog(ESD_TYPE_WARN, NULL,
1954:           "Could not open your capture filter file\n\"%s\": %s.", cf_path,
1955:           strerror(cf_open_errno));
1956:         g_free(cf_path);
1957:     }
1958:   
1959:     /* If the user's display filter file exists but we failed to open it,
1960:        pop up an alert box; we defer that until now, so that the alert
1961:        box is more likely to come up on top of the main window. */
1962:     if (df_path != NULL) {
1963:         simple_dialog(ESD_TYPE_WARN, NULL,
1964:           "Could not open your display filter file\n\"%s\": %s.", df_path,
1965:           strerror(df_open_errno));
1966:         g_free(df_path);
1967:     }
1968:   
1969:   #ifdef HAVE_LIBPCAP
1970:     if (capture_child) {
1971:       /* This is the child process for a sync mode or fork mode capture,
1972:          so just do the low-level work of a capture - don't create
1973:          a temporary file and fork off *another* child process (so don't
1974:          call "do_capture()"). */
1975:   
1976:          /* XXX - hand these stats to the parent process */
1977:          capture(&stats_known, &stats);
1978:   
1979:          /* The capture is done; there's nothing more for us to do. */
1980:          gtk_exit(0);
1981:     } else {
1982:       if (start_capture) {
1983:         /* "-k" was specified; start a capture. */
1984:         do_capture(save_file);
1985:       }
1986:       else {
1987:         set_menus_for_capture_in_progress(FALSE);
1988:       }
1989:     }
1990:   #else
1991:     set_menus_for_capture_in_progress(FALSE);
1992:   #endif
1993:   
1994:     gtk_main();
1995:   
1996:       /* Try to save our geometry.  GTK+ provides two routines to get a
1997:            window's position relative to the X root window.  If I understand the
1998:            documentation correctly, gdk_window_get_deskrelative_origin applies
1999:            mainly to Enlightenment and gdk_window_get_root_origin applies for
2000:            all other WMs.
2001:          
2002:          The code below tries both routines, and picks the one that returns
2003:          the upper-left-most coordinates.
2004:          
2005:          More info at:
2006:   
2007:          http://mail.gnome.org/archives/gtk-devel-list/2001-March/msg00289.html
2008:          http://www.gtk.org/faq/#AEN600 */
2009:   
2010:       /* Re-read our saved preferences. */
2011:       /* XXX - Move all of this into a separate function? */
2012:       prefs = read_prefs(&gpf_open_errno, &gpf_path, &pf_open_errno, &pf_path);
2013:   
2014:       if (pf_path == NULL) {
2015:           if (prefs->gui_geometry_save_position) {
2016:               if (top_level->window != NULL) {
2017:                   gdk_window_get_root_origin(top_level->window, &root_x, &root_y);
2018:                   if (gdk_window_get_deskrelative_origin(top_level->window,
2019:                               &desk_x, &desk_y)) {
2020:                       if (desk_x <= root_x && desk_y <= root_y) {
2021:                           root_x = desk_x;
2022:                           root_y = desk_y;
2023:                       }
2024:                   }
2025:               }
2026:               if (prefs->gui_geometry_main_x != root_x) {
2027:                   prefs->gui_geometry_main_x = root_x;
2028:                   prefs_write_needed = TRUE;
2029:               }
2030:               if (prefs->gui_geometry_main_y != root_y) {
2031:                   prefs->gui_geometry_main_y = root_y;
2032:                   prefs_write_needed = TRUE;
2033:               }
2034:           }
2035:           
2036:           if (prefs->gui_geometry_save_size) {
2037:               if (top_level->window != NULL) {
2038:                   /* XXX - Is this the "approved" method? */
2039:                   gdk_window_get_size(top_level->window, &top_width, &top_height);
2040:               }
2041:               if (prefs->gui_geometry_main_width != top_width) {
2042:                   prefs->gui_geometry_main_width = top_width;
2043:                   prefs_write_needed = TRUE;
2044:               }
2045:               if (prefs->gui_geometry_main_height != top_height) {
2046:                   prefs->gui_geometry_main_height = top_height;
2047:                   prefs_write_needed = TRUE;
2048:               }
2049:           }
2050:           
2051:           if (prefs_write_needed) {
2052:               write_prefs(&pf_path);
2053:           }
2054:       }
2055:       
2056:     epan_cleanup();
2057:     g_free(rc_file);
2058:   
2059:   #ifdef WIN32
2060:     /* Shutdown windows sockets */
2061:     WSACleanup();
2062:   
2063:     /* For some unknown reason, the "atexit()" call in "create_console()"
2064:        doesn't arrange that "destroy_console()" be called when we exit,
2065:        so we call it here if a console was created. */
2066:     if (console_was_created)
2067:       destroy_console();
2068:   #endif
2069:   
2070:     gtk_exit(0);
2071:   
2072:     /* This isn't reached, but we need it to keep GCC from complaining
2073:        that "main()" returns without returning a value - it knows that
2074:        "exit()" never returns, but it doesn't know that "gtk_exit()"
2075:        doesn't, as GTK+ doesn't declare it with the attribute
2076:        "noreturn". */
2077:     return 0; /* not reached */
2078:   }
2079:   
2080:   #ifdef WIN32
2081:   
2082:   /* We build this as a GUI subsystem application on Win32, so
2083:      "WinMain()", not "main()", gets called.
2084:   
2085:      Hack shamelessly stolen from the Win32 port of the GIMP. */
2086:   #ifdef __GNUC__
2087:   #define _stdcall  __attribute__((stdcall))
2088:   #endif
2089:   
2090:   int _stdcall
2091:   WinMain (struct HINSTANCE__ *hInstance,
2092:        struct HINSTANCE__ *hPrevInstance,
2093:        char               *lpszCmdLine,
2094:        int                 nCmdShow)
2095:   {
2096:     has_no_console = TRUE;
2097:     return main (__argc, __argv);
2098:   }
2099:   
2100:   /*
2101:    * If this application has no console window to which its standard output
2102:    * would go, create one.
2103:    */
2104:   static void
2105:   create_console(void)
2106:   {
2107:     if (has_no_console) {
2108:       /* We have no console to which to print the version string, so
2109:          create one and make it the standard input, output, and error. */
2110:       if (!AllocConsole())
2111:         return;   /* couldn't create console */
2112:       freopen("CONIN$", "r", stdin);
2113:       freopen("CONOUT$", "w", stdout);
2114:       freopen("CONOUT$", "w", stderr);
2115:   
2116:       /* Well, we have a console now. */
2117:       has_no_console = FALSE;
2118:       console_was_created = TRUE;
2119:   
2120:       /* Now register "destroy_console()" as a routine to be called just
2121:          before the application exits, so that we can destroy the console
2122:          after the user has typed a key (so that the console doesn't just
2123:          disappear out from under them, giving the user no chance to see
2124:          the message(s) we put in there). */
2125:       atexit(destroy_console);
2126:     }
2127:   }
2128:   
2129:   static void
2130:   destroy_console(void)
2131:   {
2132:     printf("\n\nPress any key to exit\n");
2133:     _getch();
2134:     FreeConsole();
2135:   }
2136:   
2137:   /* This routine should not be necessary, at least as I read the GLib
2138:      source code, as it looks as if GLib is, on Win32, *supposed* to
2139:      create a console window into which to display its output.
2140:   
2141:      That doesn't happen, however.  I suspect there's something completely
2142:      broken about that code in GLib-for-Win32, and that it may be related
2143:      to the breakage that forces us to just call "printf()" on the message
2144:      rather than passing the message on to "g_log_default_handler()"
2145:      (which is the routine that does the aforementioned non-functional
2146:      console window creation). */
2147:   static void
2148:   console_log_handler(const char *log_domain, GLogLevelFlags log_level,
2149:               const char *message, gpointer user_data)
2150:   {
2151:     create_console();
2152:     if (console_was_created) {
2153:       /* For some unknown reason, the above doesn't appear to actually cause
2154:          anything to be sent to the standard output, so we'll just splat the
2155:          message out directly, just to make sure it gets out. */
2156:       printf("%s\n", message);
2157:     } else
2158:       g_log_default_handler(log_domain, log_level, message, user_data);
2159:   }
2160:   #endif
2161:   
2162:   /* Given a font name, construct the name of the next heavier version of
2163:      that font. */
2164:   
2165:   #define XLFD_WEIGHT 3   /* index of the "weight" field */
2166:   
2167:   /* Map from a given weight to the appropriate weight for the "bold"
2168:      version of a font.
2169:      XXX - the XLFD says these strings shouldn't be used for font matching;
2170:      can we get the weight, as a number, from GDK, and ask GDK to find us
2171:      a font just like the given font, but with the appropriate higher
2172:      weight? */
2173:   static const struct {
2174:       char    *light;
2175:       char    *heavier;
2176:   } weight_map[] = {
2177:       { "ultralight", "light" },
2178:       { "extralight", "semilight" },
2179:       { "light",      "medium" },
2180:       { "semilight",  "semibold" },
2181:       { "medium",     "bold" },
2182:       { "normal",     "bold" },
2183:       { "semibold",   "extrabold" },
2184:       { "bold",       "ultrabold" }
2185:   };
2186:   #define N_WEIGHTS   (sizeof weight_map / sizeof weight_map[0])
2187:       
2188:   char *
2189:   boldify(const char *font_name)
2190:   {
2191:       char *bold_font_name;
2192:       gchar **xlfd_tokens;
2193:       unsigned int i;
2194:   
2195:       /* Is this an XLFD font?  If it begins with "-", yes, otherwise no. */
2196:       if (font_name[0] == '-') {
2197:           xlfd_tokens = g_strsplit(font_name, "-", XLFD_WEIGHT+1);
2198:   
2199:           /*
2200:            * Make sure we *have* a weight (this might not be a valid
2201:            * XLFD font name).
2202:            */
2203:           for (i = 0; i < XLFD_WEIGHT+1; i++) {
2204:               if (xlfd_tokens[i] == NULL) {
2205:                   /*
2206:                    * We don't, so treat this as a non-XLFD
2207:                    * font name.
2208:                    */
2209:                   goto not_xlfd;
2210:               }
2211:           }
2212:           for (i = 0; i < N_WEIGHTS; i++) {
2213:               if (strcmp(xlfd_tokens[XLFD_WEIGHT],
2214:                   weight_map[i].light) == 0) {
2215:                   g_free(xlfd_tokens[XLFD_WEIGHT]);
2216:                   xlfd_tokens[XLFD_WEIGHT] =
2217:                       g_strdup(weight_map[i].heavier);
2218:                   break;
2219:               }
2220:           }
2221:           bold_font_name = g_strjoinv("-", xlfd_tokens);
2222:           g_strfreev(xlfd_tokens);
2223:           return bold_font_name;
2224:       }
2225:   
2226:   not_xlfd:
2227:       /*
2228:        * This isn't an XLFD font name; just append "bold" to the name
2229:        * of the font.
2230:        */
2231:       bold_font_name = g_strconcat(font_name, "bold", NULL);
2232:       return bold_font_name;
2233:   }
2234:   
2235:   
2236:   static void
2237:   create_main_window (gint pl_size, gint tv_size, gint bv_size, e_prefs *prefs)
2238:   {
2239:     GtkWidget           *main_vbox, *menubar, *u_pane, *l_pane,
2240:                         *stat_hbox, *column_lb,
2241:                         *filter_bt, *filter_cm, *filter_te,
2242:                         *filter_apply,
2243:                         *filter_reset;
2244:     GList               *filter_list = NULL;
2245:     GtkAccelGroup       *accel;
2246:     GtkStyle            *win_style;
2247:     GdkBitmap           *ascend_bm, *descend_bm;
2248:     GdkPixmap           *ascend_pm, *descend_pm;
2249:     column_arrows       *col_arrows;
2250:     int           i;
2251:     /* Display filter construct dialog has an Apply button, and "OK" not
2252:        only sets our text widget, it activates it (i.e., it causes us to
2253:        filter the capture). */
2254:     static construct_args_t args = {
2255:       "Ethereal: Display Filter",
2256:       TRUE,
2257:       TRUE
2258:     };
2259:     
2260:     /* Main window */  
2261:     top_level = gtk_window_new(GTK_WINDOW_TOPLEVEL);
2262:     gtk_widget_set_name(top_level, "main window");
2263:     gtk_signal_connect(GTK_OBJECT(top_level), "delete_event", 
2264:       GTK_SIGNAL_FUNC(main_window_delete_event_cb), NULL);
2265:     gtk_signal_connect (GTK_OBJECT (top_level), "realize",
2266:       GTK_SIGNAL_FUNC (window_icon_realize_cb), NULL);
2267:     gtk_window_set_title(GTK_WINDOW(top_level), "The Ethereal Network Analyzer");
2268:     if (prefs->gui_geometry_save_position) {
2269:       gtk_widget_set_uposition(GTK_WIDGET(top_level),
2270:         prefs->gui_geometry_main_x, prefs->gui_geometry_main_y);
2271:     }
2272:     if (prefs->gui_geometry_save_size) {
2273:       gtk_widget_set_usize(GTK_WIDGET(top_level),
2274:         prefs->gui_geometry_main_width, prefs->gui_geometry_main_height);
2275:     } else {
2276:       gtk_widget_set_usize(GTK_WIDGET(top_level), DEF_WIDTH, -1);
2277:     }
2278:     gtk_window_set_policy(GTK_WINDOW(top_level), TRUE, TRUE, FALSE);
2279:   
2280:     /* Container for menu bar, paned windows and progress/info box */
2281:     main_vbox = gtk_vbox_new(FALSE, 1);
2282:     gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
2283:     gtk_container_add(GTK_CONTAINER(top_level), main_vbox);
2284:     gtk_widget_show(main_vbox);
2285:   
2286:     /* Menu bar */
2287:     get_main_menu(&menubar, &accel);
2288:     gtk_window_add_accel_group(GTK_WINDOW(top_level), accel);
2289:     gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
2290:     gtk_widget_show(menubar);
2291:   
2292:     /* Panes for the packet list, tree, and byte view */
2293:     u_pane = gtk_vpaned_new();
2294:     gtk_paned_gutter_size(GTK_PANED(u_pane), (GTK_PANED(u_pane))->handle_size);
2295:     l_pane = gtk_vpaned_new();
2296:     gtk_paned_gutter_size(GTK_PANED(l_pane), (GTK_PANED(l_pane))->handle_size);
2297:     gtk_container_add(GTK_CONTAINER(main_vbox), u_pane);
2298:     gtk_widget_show(l_pane);
2299:     gtk_paned_add2(GTK_PANED(u_pane), l_pane);
2300:     gtk_widget_show(u_pane);
2301:   
2302:     /* Packet list */
2303:     pkt_scrollw = scrolled_window_new(NULL, NULL);
2304:     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(pkt_scrollw),
2305:       GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
2306:     gtk_widget_show(pkt_scrollw);
2307:     gtk_paned_add1(GTK_PANED(u_pane), pkt_scrollw);
2308:   
2309:     packet_list = gtk_clist_new(cfile.cinfo.num_cols);
2310:     /* Column titles are filled in below */
2311:     gtk_container_add(GTK_CONTAINER(pkt_scrollw), packet_list);
2312:   
2313:     col_arrows = (column_arrows *) g_malloc(sizeof(column_arrows) * cfile.cinfo.num_cols);
2314:     
2315:     set_plist_sel_browse(prefs->gui_plist_sel_browse);
2316:     set_plist_font(m_r_font);
2317:     gtk_widget_set_name(packet_list, "packet list");
2318:     gtk_signal_connect (GTK_OBJECT (packet_list), "click_column",
2319:       GTK_SIGNAL_FUNC(packet_list_click_column_cb), col_arrows);
2320:     gtk_signal_connect(GTK_OBJECT(packet_list), "select_row",
2321:       GTK_SIGNAL_FUNC(packet_list_select_cb), NULL);
2322:     gtk_signal_connect(GTK_OBJECT(packet_list), "unselect_row",
2323:       GTK_SIGNAL_FUNC(packet_list_unselect_cb), NULL);
2324:     for (i = 0; i < cfile.cinfo.num_cols; i++) {
2325:       if (get_column_resize_type(cfile.cinfo.col_fmt[i]) != RESIZE_MANUAL)
2326:         gtk_clist_set_column_auto_resize(GTK_CLIST(packet_list), i, TRUE);
2327:   
2328:       /* Right-justify the packet number column. */
2329:       if (cfile.cinfo.col_fmt[i] == COL_NUMBER)
2330:         gtk_clist_set_column_justification(GTK_CLIST(packet_list), i, 
2331:           GTK_JUSTIFY_RIGHT);
2332:     }
2333:     gtk_widget_set_usize(packet_list, -1, pl_size);
2334:     gtk_signal_connect(GTK_OBJECT(packet_list), "button_press_event",
2335:                GTK_SIGNAL_FUNC(popup_menu_handler), 
2336:                gtk_object_get_data(GTK_OBJECT(popup_menu_object), PM_PACKET_LIST_KEY));
2337:     gtk_signal_connect(GTK_OBJECT(packet_list), "button_press_event",
2338:                GTK_SIGNAL_FUNC(packet_list_button_pressed_cb), NULL);
2339:     gtk_clist_set_compare_func(GTK_CLIST(packet_list), packet_list_compare);
2340:     gtk_widget_show(packet_list);
2341:   
2342:     /* Tree view */
2343:     item_style = gtk_style_new();
2344:     gdk_font_unref(item_style->font);
2345:     item_style->font = m_r_font;
2346:     create_tree_view(tv_size, prefs, l_pane, &tv_scrollw, &tree_view);
2347:     gtk_signal_connect(GTK_OBJECT(tree_view), "tree-select-row",
2348:       GTK_SIGNAL_FUNC(tree_view_select_row_cb), NULL);
2349:     gtk_signal_connect(GTK_OBJECT(tree_view), "tree-unselect-row",
2350:       GTK_SIGNAL_FUNC(tree_view_unselect_row_cb), NULL);
2351:     gtk_signal_connect(GTK_OBJECT(tree_view), "button_press_event",
2352:                GTK_SIGNAL_FUNC(popup_menu_handler),
2353:                gtk_object_get_data(GTK_OBJECT(popup_menu_object), PM_TREE_VIEW_KEY));
2354:     gtk_widget_show(tree_view);
2355:   
2356:     /* Byte view. */
2357:     byte_nb_ptr = create_byte_view(bv_size, l_pane);
2358:   
2359:     gtk_signal_connect(GTK_OBJECT(byte_nb_ptr), "button_press_event",
2360:                GTK_SIGNAL_FUNC(popup_menu_handler),
2361:                gtk_object_get_data(GTK_OBJECT(popup_menu_object), PM_HEXDUMP_KEY));
2362:   
2363:     /* Filter/info box */
2364:     stat_hbox = gtk_hbox_new(FALSE, 1);
2365:     gtk_container_border_width(GTK_CONTAINER(stat_hbox), 0);
2366:     gtk_box_pack_start(GTK_BOX(main_vbox), stat_hbox, FALSE, TRUE, 0);
2367:     gtk_widget_show(stat_hbox);
2368:   
2369:     filter_bt = gtk_button_new_with_label("Filter:");
2370:     gtk_signal_connect(GTK_OBJECT(filter_bt), "clicked",
2371:       GTK_SIGNAL_FUNC(display_filter_construct_cb), &args);
2372:     gtk_box_pack_start(GTK_BOX(stat_hbox), filter_bt, FALSE, TRUE, 0);
2373:     gtk_widget_show(filter_bt);
2374:     
2375:     filter_cm = gtk_combo_new();
2376:     filter_list = g_list_append (filter_list, "");
2377:     gtk_combo_set_popdown_strings(GTK_COMBO(filter_cm), filter_list);
2378:     gtk_combo_disable_activate(GTK_COMBO(filter_cm));
2379:     gtk_combo_set_case_sensitive(GTK_COMBO(filter_cm), TRUE);
2380:     gtk_object_set_data(GTK_OBJECT(filter_cm), E_DFILTER_FL_KEY, filter_list);
2381:     filter_te = GTK_COMBO(filter_cm)->entry;
2382:     gtk_object_set_data(GTK_OBJECT(filter_bt), E_FILT_TE_PTR_KEY, filter_te);
2383:     gtk_object_set_data(GTK_OBJECT(filter_te), E_DFILTER_CM_KEY, filter_cm);
2384:     gtk_box_pack_start(GTK_BOX(stat_hbox), filter_cm, TRUE, TRUE, 3);
2385:     gtk_signal_connect(GTK_OBJECT(filter_te), "activate",
2386:       GTK_SIGNAL_FUNC(filter_activate_cb), filter_te);
2387:     gtk_widget_show(filter_cm);
2388:   
2389:     filter_reset = gtk_button_new_with_label("Reset");
2390:     gtk_object_set_data(GTK_OBJECT(filter_reset), E_DFILTER_TE_KEY, filter_te);
2391:     gtk_signal_connect(GTK_OBJECT(filter_reset), "clicked",
2392:                GTK_SIGNAL_FUNC(filter_reset_cb), NULL);
2393:     gtk_box_pack_start(GTK_BOX(stat_hbox), filter_reset, FALSE, TRUE, 1);
2394:     gtk_widget_show(filter_reset);
2395:   
2396:     filter_apply = gtk_button_new_with_label("Apply");
2397:     gtk_object_set_data(GTK_OBJECT(filter_apply), E_DFILTER_CM_KEY, filter_cm);
2398:     gtk_signal_connect(GTK_OBJECT(filter_apply), "clicked",
2399:                        GTK_SIGNAL_FUNC(filter_activate_cb), filter_te);
2400:     gtk_box_pack_start(GTK_BOX(stat_hbox), filter_apply, FALSE, TRUE, 1);
2401:     gtk_widget_show(filter_apply);
2402:   
2403:     /* Sets the text entry widget pointer as the E_DILTER_TE_KEY data
2404:      * of any widget that ends up calling a callback which needs
2405:      * that text entry pointer */
2406:     set_menu_object_data("/File/Open...", E_DFILTER_TE_KEY, filter_te);
2407:     set_menu_object_data("/File/Reload", E_DFILTER_TE_KEY, filter_te);
2408:     set_menu_object_data("/Edit/Filters...", E_FILT_TE_PTR_KEY, filter_te);
2409:     set_menu_object_data("/Tools/Follow TCP Stream", E_DFILTER_TE_KEY, filter_te);
2410:     set_menu_object_data("/Display/Match/Selected", E_DFILTER_TE_KEY, filter_te);
2411:     set_menu_object_data("/Display/Match/Not Selected", E_DFILTER_TE_KEY, filter_te);
2412:     set_menu_object_data("/Display/Match/And Selected", E_DFILTER_TE_KEY, filter_te);
2413:     set_menu_object_data("/Display/Match/Or Selected", E_DFILTER_TE_KEY, filter_te);
2414:     set_menu_object_data("/Display/Match/And Not Selected", E_DFILTER_TE_KEY, filter_te);
2415:     set_menu_object_data("/Display/Match/Or Not Selected", E_DFILTER_TE_KEY, filter_te);
2416:     set_menu_object_data("/Display/Prepare/Selected", E_DFILTER_TE_KEY, filter_te);
2417:     set_menu_object_data("/Display/Prepare/Not Selected", E_DFILTER_TE_KEY, filter_te);
2418:     set_menu_object_data("/Display/Prepare/And Selected", E_DFILTER_TE_KEY, filter_te);
2419:     set_menu_object_data("/Display/Prepare/Or Selected", E_DFILTER_TE_KEY, filter_te);
2420:     set_menu_object_data("/Display/Prepare/And Not Selected", E_DFILTER_TE_KEY, filter_te);
2421:     set_menu_object_data("/Display/Prepare/Or Not Selected", E_DFILTER_TE_KEY, filter_te);
2422:     gtk_object_set_data(GTK_OBJECT(popup_menu_object), E_DFILTER_TE_KEY, filter_te);
2423:     gtk_object_set_data(GTK_OBJECT(popup_menu_object), E_MPACKET_LIST_KEY, packet_list);
2424:   
2425:     info_bar = gtk_statusbar_new();
2426:     main_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "main");
2427:     file_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "file");
2428:     help_ctx = gtk_statusbar_get_context_id(GTK_STATUSBAR(info_bar), "help");
2429:     gtk_statusbar_push(GTK_STATUSBAR(info_bar), main_ctx, DEF_READY_MESSAGE);
2430:     gtk_box_pack_start(GTK_BOX(stat_hbox), info_bar, TRUE, TRUE, 0);
2431:     gtk_widget_show(info_bar);
2432:   
2433:     gtk_widget_show(top_level);
2434:   
2435:     /* Fill in column titles.  This must be done after the top level window
2436:        is displayed. */
2437:     win_style = gtk_widget_get_style(top_level);
2438:     ascend_pm = gdk_pixmap_create_from_xpm_d(top_level->window, &ascend_bm,
2439:       &win_style->bg[GTK_STATE_NORMAL], (gchar **)clist_ascend_xpm);
2440:     descend_pm = gdk_pixmap_create_from_xpm_d(top_level->window, &descend_bm,
2441:       &win_style->bg[GTK_STATE_NORMAL], (gchar **)clist_descend_xpm);
2442:     for (i = 0; i < cfile.cinfo.num_cols; i++) {
2443:       col_arrows[i].table = gtk_table_new(2, 2, FALSE);
2444:       gtk_table_set_col_spacings(GTK_TABLE(col_arrows[i].table), 5);
2445:       column_lb = gtk_label_new(cfile.cinfo.col_title[i]);
2446:       gtk_table_attach(GTK_TABLE(col_arrows[i].table), column_lb, 0, 1, 0, 2,
2447:           GTK_SHRINK, GTK_SHRINK, 0, 0);
2448:       gtk_widget_show(column_lb);
2449:       col_arrows[i].ascend_pm = gtk_pixmap_new(ascend_pm, ascend_bm);
2450:       gtk_table_attach(GTK_TABLE(col_arrows[i].table), col_arrows[i].ascend_pm, 
2451:           1, 2, 1, 2, GTK_SHRINK, GTK_SHRINK, 0, 0);
2452:       if (i == 0) {
2453:         gtk_widget_show(col_arrows[i].ascend_pm);
2454:       }
2455:       col_arrows[i].descend_pm = gtk_pixmap_new(descend_pm, descend_bm);
2456:       gtk_table_attach(GTK_TABLE(col_arrows[i].table), col_arrows[i].descend_pm,
2457:           1, 2, 0, 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
2458:       gtk_clist_set_column_widget(GTK_CLIST(packet_list), i, col_arrows[i].table);
2459:       gtk_widget_show(col_arrows[i].table);
2460:     }
2461:     gtk_clist_column_titles_show(GTK_CLIST(packet_list));
2462:   }
2463:   
2464:   
2465:   void
2466:   set_last_open_dir(char *dirname)
2467:   {
2468:       int len;
2469:   
2470:       if (last_open_dir) {
2471:           g_free(last_open_dir);
2472:       }
2473:   
2474:       if (dirname) {
2475:           len = strlen(dirname);
2476:           if (dirname[len-1] != G_DIR_SEPARATOR) {
2477:               last_open_dir = g_strconcat(dirname, G_DIR_SEPARATOR_S,
2478:                   NULL);
2479:           }
2480:       }
2481:       else {
2482:           last_open_dir = NULL;
2483:       }
2484:   }
2485: