Do defragment inits via registered init routine
[metze/wireshark/wip.git] / file.c
1 /* file.c
2  * File I/O routines
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
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_UNISTD_H
30 #include <unistd.h>
31 #endif
32
33 #include <time.h>
34
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <ctype.h>
39 #include <errno.h>
40 #include <signal.h>
41
42 #ifdef HAVE_FCNTL_H
43 #include <fcntl.h>
44 #endif
45
46 #include <epan/epan.h>
47 #include <epan/filesystem.h>
48
49 #include "color.h"
50 #include "color_filters.h"
51 #include "cfile.h"
52 #include <epan/column.h>
53 #include <epan/packet.h>
54 #include <epan/column-utils.h>
55 #include "packet-range.h"
56 #include "print.h"
57 #include "file.h"
58 #include "fileset.h"
59 #include "tempfile.h"
60 #include "merge.h"
61 #include "alert_box.h"
62 #include "simple_dialog.h"
63 #include "progress_dlg.h"
64 #include "ui_util.h"
65 #include <epan/prefs.h>
66 #include <epan/dfilter/dfilter.h>
67 #include <epan/epan_dissect.h>
68 #include <epan/tap.h>
69 #include <epan/dissectors/packet-data.h>
70 #include <epan/dissectors/packet-ber.h>
71 #include <epan/timestamp.h>
72 #include <epan/dfilter/dfilter-macro.h>
73 #include <wsutil/file_util.h>
74 #include <epan/strutil.h>
75
76
77 #ifdef HAVE_LIBPCAP
78 gboolean auto_scroll_live;
79 #endif
80
81 static nstime_t first_ts;
82 static nstime_t prev_dis_ts;
83 static guint32 cum_bytes = 0;
84
85 static void cf_reset_state(capture_file *cf);
86
87 static int read_packet(capture_file *cf, dfilter_t *dfcode,
88     gboolean filtering_tap_listeners, guint tap_flags, gint64 offset);
89
90 static void rescan_packets(capture_file *cf, const char *action, const char *action_item,
91         gboolean refilter, gboolean redissect);
92
93 static gboolean match_protocol_tree(capture_file *cf, frame_data *fdata,
94         void *criterion);
95 static void match_subtree_text(proto_node *node, gpointer data);
96 static gboolean match_summary_line(capture_file *cf, frame_data *fdata,
97         void *criterion);
98 static gboolean match_ascii_and_unicode(capture_file *cf, frame_data *fdata,
99         void *criterion);
100 static gboolean match_ascii(capture_file *cf, frame_data *fdata,
101         void *criterion);
102 static gboolean match_unicode(capture_file *cf, frame_data *fdata,
103         void *criterion);
104 static gboolean match_binary(capture_file *cf, frame_data *fdata,
105         void *criterion);
106 static gboolean match_dfilter(capture_file *cf, frame_data *fdata,
107         void *criterion);
108 static gboolean find_packet(capture_file *cf,
109         gboolean (*match_function)(capture_file *, frame_data *, void *),
110         void *criterion);
111
112 static void cf_open_failure_alert_box(const char *filename, int err,
113                                       gchar *err_info, gboolean for_writing,
114                                       int file_type);
115 static const char *file_rename_error_message(int err);
116 static void cf_write_failure_alert_box(const char *filename, int err);
117 static void cf_close_failure_alert_box(const char *filename, int err);
118
119 /* Update the progress bar this many times when reading a file. */
120 #define N_PROGBAR_UPDATES       100
121
122 /* Number of "frame_data" structures per memory chunk.
123    XXX - is this the right number? */
124 #define FRAME_DATA_CHUNK_SIZE   1024
125
126
127 /* this callback mechanism should possibly be replaced by the g_signal_...() stuff (if I only would know how :-) */
128 typedef struct {
129     cf_callback_t cb_fct;
130     gpointer user_data;
131 } cf_callback_data_t;
132
133 static GList *cf_callbacks = NULL;
134
135 static void
136 cf_callback_invoke(int event, gpointer data)
137 {
138     cf_callback_data_t *cb;
139     GList *cb_item = cf_callbacks;
140
141     /* there should be at least one interested */
142     g_assert(cb_item != NULL);
143
144     while(cb_item != NULL) {
145         cb = cb_item->data;
146         cb->cb_fct(event, data, cb->user_data);
147         cb_item = g_list_next(cb_item);
148     }
149 }
150
151
152 void
153 cf_callback_add(cf_callback_t func, gpointer user_data)
154 {
155     cf_callback_data_t *cb;
156
157     cb = g_malloc(sizeof(cf_callback_data_t));
158     cb->cb_fct = func;
159     cb->user_data = user_data;
160
161     cf_callbacks = g_list_append(cf_callbacks, cb);
162 }
163
164 void
165 cf_callback_remove(cf_callback_t func)
166 {
167     cf_callback_data_t *cb;
168     GList *cb_item = cf_callbacks;
169
170     while(cb_item != NULL) {
171         cb = cb_item->data;
172         if(cb->cb_fct == func) {
173             cf_callbacks = g_list_remove(cf_callbacks, cb);
174             g_free(cb);
175             return;
176         }
177         cb_item = g_list_next(cb_item);
178     }
179
180     g_assert_not_reached();
181 }
182
183 void
184 cf_timestamp_auto_precision(capture_file *cf)
185 {
186         int prec = timestamp_get_precision();
187
188
189         /* don't try to get the file's precision if none is opened */
190         if(cf->state == FILE_CLOSED) {
191                 return;
192         }
193
194         /* if we are in auto mode, set precision of current file */
195         if(prec == TS_PREC_AUTO ||
196           prec == TS_PREC_AUTO_SEC ||
197           prec == TS_PREC_AUTO_DSEC ||
198           prec == TS_PREC_AUTO_CSEC ||
199           prec == TS_PREC_AUTO_MSEC ||
200           prec == TS_PREC_AUTO_USEC ||
201           prec == TS_PREC_AUTO_NSEC)
202         {
203                 switch(wtap_file_tsprecision(cf->wth)) {
204                 case(WTAP_FILE_TSPREC_SEC):
205                         timestamp_set_precision(TS_PREC_AUTO_SEC);
206                         break;
207                 case(WTAP_FILE_TSPREC_DSEC):
208                         timestamp_set_precision(TS_PREC_AUTO_DSEC);
209                         break;
210                 case(WTAP_FILE_TSPREC_CSEC):
211                         timestamp_set_precision(TS_PREC_AUTO_CSEC);
212                         break;
213                 case(WTAP_FILE_TSPREC_MSEC):
214                         timestamp_set_precision(TS_PREC_AUTO_MSEC);
215                         break;
216                 case(WTAP_FILE_TSPREC_USEC):
217                         timestamp_set_precision(TS_PREC_AUTO_USEC);
218                         break;
219                 case(WTAP_FILE_TSPREC_NSEC):
220                         timestamp_set_precision(TS_PREC_AUTO_NSEC);
221                         break;
222                 default:
223                         g_assert_not_reached();
224                 }
225         }
226 }
227
228
229 cf_status_t
230 cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
231 {
232   wtap       *wth;
233   gchar       *err_info;
234
235   wth = wtap_open_offline(fname, err, &err_info, TRUE);
236   if (wth == NULL)
237     goto fail;
238
239   /* The open succeeded.  Close whatever capture file we had open,
240      and fill in the information for this file. */
241   cf_reset_state(cf);
242
243   /* Initialize all data structures used for dissection. */
244   init_dissection();
245
246   /* We're about to start reading the file. */
247   cf->state = FILE_READ_IN_PROGRESS;
248
249   cf->wth = wth;
250   cf->f_datalen = 0;
251
252   /* Set the file name because we need it to set the follow stream filter.
253      XXX - is that still true?  We need it for other reasons, though,
254      in any case. */
255   cf->filename = g_strdup(fname);
256
257   /* Indicate whether it's a permanent or temporary file. */
258   cf->is_tempfile = is_tempfile;
259
260   /* If it's a temporary capture buffer file, mark it as not saved. */
261   cf->user_saved = !is_tempfile;
262
263   cf->cd_t        = wtap_file_type(cf->wth);
264   cf->count     = 0;
265   cf->displayed_count = 0;
266   cf->marked_count = 0;
267   cf->drops_known = FALSE;
268   cf->drops     = 0;
269   cf->snap      = wtap_snapshot_length(cf->wth);
270   if (cf->snap == 0) {
271     /* Snapshot length not known. */
272     cf->has_snap = FALSE;
273     cf->snap = WTAP_MAX_PACKET_SIZE;
274   } else
275     cf->has_snap = TRUE;
276   nstime_set_zero(&cf->elapsed_time);
277   nstime_set_unset(&first_ts);
278   nstime_set_unset(&prev_dis_ts);
279
280   cf->plist_chunk = g_mem_chunk_new("frame_data_chunk",
281         sizeof(frame_data),
282         FRAME_DATA_CHUNK_SIZE * sizeof(frame_data),
283         G_ALLOC_AND_FREE);
284   g_assert(cf->plist_chunk);
285
286   /* change the time formats now, as we might have a new precision */
287   cf_change_time_formats(cf);
288
289   fileset_file_opened(fname);
290
291   if(cf->cd_t == WTAP_FILE_BER) {
292     /* tell the BER dissector the file name */
293     ber_set_filename(cf->filename);
294   }
295
296   return CF_OK;
297
298 fail:
299   cf_open_failure_alert_box(fname, *err, err_info, FALSE, 0);
300   return CF_ERROR;
301 }
302
303
304 /*
305  * Reset the state for the currently closed file, but don't do the
306  * UI callbacks; this is for use in "cf_open()", where we don't
307  * want the UI to go from "file open" to "file closed" back to
308  * "file open", we want it to go from "old file open" to "new file
309  * open and being read".
310  */
311 static void
312 cf_reset_state(capture_file *cf)
313 {
314   /* Die if we're in the middle of reading a file. */
315   g_assert(cf->state != FILE_READ_IN_PROGRESS);
316
317   if (cf->wth) {
318     wtap_close(cf->wth);
319     cf->wth = NULL;
320   }
321   /* We have no file open... */
322   if (cf->filename != NULL) {
323     /* If it's a temporary file, remove it. */
324     if (cf->is_tempfile)
325       ws_unlink(cf->filename);
326     g_free(cf->filename);
327     cf->filename = NULL;
328   }
329   /* ...which means we have nothing to save. */
330   cf->user_saved = FALSE;
331
332   if (cf->plist_chunk != NULL) {
333     frame_data *fdata = cf->plist;
334     while (fdata) {
335       g_strfreev(fdata->col_expr.col_expr);
336       g_strfreev(fdata->col_expr.col_expr_val);
337       fdata = fdata->next;
338     }
339     g_mem_chunk_destroy(cf->plist_chunk);
340     cf->plist_chunk = NULL;
341   }
342   if (cf->rfcode != NULL) {
343     dfilter_free(cf->rfcode);
344     cf->rfcode = NULL;
345   }
346   cf->plist = NULL;
347   cf->plist_end = NULL;
348   cf_unselect_packet(cf);       /* nothing to select */
349   cf->first_displayed = NULL;
350   cf->last_displayed = NULL;
351
352   /* No frame selected, no field in that frame selected. */
353   cf->current_frame = NULL;
354   cf->current_row = 0;
355   cf->finfo_selected = NULL;
356
357   /* Clear the packet list. */
358 #ifdef NEW_PACKET_LIST
359   new_packet_list_freeze();
360   new_packet_list_thaw();
361 #else
362   packet_list_freeze();
363   packet_list_clear();
364   packet_list_thaw();
365 #endif
366
367   cf->f_datalen = 0;
368   cf->count = 0;
369   nstime_set_zero(&cf->elapsed_time);
370
371   reset_tap_listeners();
372
373   /* We have no file open. */
374   cf->state = FILE_CLOSED;
375
376   fileset_file_closed();
377 }
378
379 /* Reset everything to a pristine state */
380 void
381 cf_close(capture_file *cf)
382 {
383   /* do GUI things even if file is already closed,
384    * e.g. to cleanup things if a capture couldn't be started */
385   cf_callback_invoke(cf_cb_file_closing, cf);
386
387   /* close things, if not already closed before */
388   if(cf->state != FILE_CLOSED) {
389     color_filters_cleanup();
390     cf_reset_state(cf);
391     cleanup_dissection();
392   }
393
394   cf_callback_invoke(cf_cb_file_closed, cf);
395 }
396
397 /* an out of memory exception occured, wait for a user button press to exit */
398 void outofmemory_cb(gpointer dialog _U_, gint btn _U_, gpointer data _U_)
399 {
400     main_window_exit();
401 }
402
403 cf_read_status_t
404 cf_read(capture_file *cf)
405 {
406   int         err;
407   gchar       *err_info;
408   const gchar *name_ptr;
409   const char  *errmsg;
410   char         errmsg_errno[1024+1];
411   gint64       data_offset;
412   progdlg_t *volatile progbar = NULL;
413   gboolean     stop_flag;
414   volatile gint64 size;
415   gint64       file_pos;
416   volatile float progbar_val;
417   GTimeVal     start_time;
418   gchar        status_str[100];
419   volatile gint64 progbar_nextstep;
420   volatile gint64 progbar_quantum;
421   dfilter_t   *dfcode;
422   gboolean    filtering_tap_listeners;
423   guint       tap_flags;
424 #ifdef HAVE_LIBPCAP
425   volatile int displayed_once = 0;
426 #endif
427
428   /* Compile the current display filter.
429    * We assume this will not fail since cf->dfilter is only set in
430    * cf_filter IFF the filter was valid.
431    */
432   dfcode=NULL;
433   if(cf->dfilter){
434     dfilter_compile(cf->dfilter, &dfcode);
435   }
436
437   /* Do we have any tap listeners with filters? */
438   filtering_tap_listeners = have_filtering_tap_listeners();
439
440   /* Get the union of the flags for all tap listeners. */
441   tap_flags = union_of_tap_listener_flags();
442
443   cum_bytes=0;
444
445   reset_tap_listeners();
446
447   cf_callback_invoke(cf_cb_file_read_start, cf);
448
449   name_ptr = get_basename(cf->filename);
450
451   /* Find the size of the file. */
452   size = wtap_file_size(cf->wth, NULL);
453
454   /* Update the progress bar when it gets to this value. */
455   progbar_nextstep = 0;
456   /* When we reach the value that triggers a progress bar update,
457      bump that value by this amount. */
458   if (size >= 0)
459     progbar_quantum = size/N_PROGBAR_UPDATES;
460   else
461     progbar_quantum = 0;
462   /* Progress so far. */
463   progbar_val = 0.0f;
464
465 #ifdef NEW_PACKET_LIST
466   new_packet_list_freeze();
467 #else
468   packet_list_freeze();
469 #endif
470
471   stop_flag = FALSE;
472   g_get_current_time(&start_time);
473
474   while ((wtap_read(cf->wth, &err, &err_info, &data_offset))) {
475     if (size >= 0) {
476       /* Create the progress bar if necessary.
477          We check on every iteration of the loop, so that it takes no
478          longer than the standard time to create it (otherwise, for a
479          large file, we might take considerably longer than that standard
480          time in order to get to the next progress bar step). */
481       if (progbar == NULL) {
482         progbar = delayed_create_progress_dlg("Loading", name_ptr,
483           TRUE, &stop_flag, &start_time, progbar_val);
484       }
485
486       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
487          when we update it, we have to run the GTK+ main loop to get it
488          to repaint what's pending, and doing so may involve an "ioctl()"
489          to see if there's any pending input from an X server, and doing
490          that for every packet can be costly, especially on a big file. */
491       if (data_offset >= progbar_nextstep) {
492           file_pos = wtap_read_so_far(cf->wth, NULL);
493           progbar_val = (gfloat) file_pos / (gfloat) size;
494           if (progbar_val > 1.0) {
495             /* The file probably grew while we were reading it.
496                Update file size, and try again. */
497             size = wtap_file_size(cf->wth, NULL);
498             if (size >= 0)
499               progbar_val = (gfloat) file_pos / (gfloat) size;
500             /* If it's still > 1, either "wtap_file_size()" failed (in which
501                case there's not much we can do about it), or the file
502                *shrank* (in which case there's not much we can do about
503                it); just clip the progress value at 1.0. */
504             if (progbar_val > 1.0f)
505               progbar_val = 1.0f;
506           }
507           if (progbar != NULL) {
508               /* update the packet lists content on the first run or frequently on very large files */
509               /* (on smaller files the display update takes longer than reading the file) */
510 #ifdef HAVE_LIBPCAP
511               if (progbar_quantum > 500000 || displayed_once == 0) {
512                   if ((auto_scroll_live || displayed_once == 0 || cf->displayed_count < 1000) && cf->plist_end != NULL) {
513                       displayed_once = 1;
514 #ifdef NEW_PACKET_LIST
515                       /* XXX - Add move to end function call.  Freeze/thaw if
516                       * necessary. */
517 #else
518                       packet_list_thaw();
519                       if (auto_scroll_live)
520                           packet_list_moveto_end();
521                       packet_list_freeze();
522 #endif /* NEW_PACKET_LIST */
523                   }
524               }
525 #endif /* HAVE_LIBPCAP */
526             g_snprintf(status_str, sizeof(status_str),
527                        "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
528                        file_pos / 1024, size / 1024);
529             update_progress_dlg(progbar, progbar_val, status_str);
530           }
531          progbar_nextstep += progbar_quantum;
532       }
533     }
534
535     if (stop_flag) {
536       /* Well, the user decided to abort the read. He/She will be warned and
537          it might be enough for him/her to work with the already loaded
538          packets.
539          This is especially true for very large capture files, where you don't
540          want to wait loading the whole file (which may last minutes or even
541          hours even on fast machines) just to see that it was the wrong file. */
542       break;
543     }
544     TRY {
545         read_packet(cf, dfcode, filtering_tap_listeners, tap_flags, data_offset);
546     }
547     CATCH(OutOfMemoryError) {
548         gpointer dialog;
549
550         dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
551               "%sOut Of Memory!%s\n"
552               "\n"
553               "Sorry, but Wireshark has to terminate now!\n"
554               "\n"
555               "Some infos / workarounds can be found at:\n"
556               "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
557               simple_dialog_primary_start(), simple_dialog_primary_end());
558         /* we have to terminate, as we cannot recover from the memory error */
559         simple_dialog_set_cb(dialog, outofmemory_cb, NULL);
560         while(1) {
561             main_window_update();
562             /* XXX - how to avoid a busy wait? */
563             /* Sleep(100); */
564         };
565         break;
566     }
567     ENDTRY;
568   }
569
570   /* Cleanup and release all dfilter resources */
571   if (dfcode != NULL){
572     dfilter_free(dfcode);
573   }
574
575   /* We're done reading the file; destroy the progress bar if it was created. */
576   if (progbar != NULL)
577     destroy_progress_dlg(progbar);
578
579   /* We're done reading sequentially through the file. */
580   cf->state = FILE_READ_DONE;
581
582   /* Close the sequential I/O side, to free up memory it requires. */
583   wtap_sequential_close(cf->wth);
584
585   /* Allow the protocol dissectors to free up memory that they
586    * don't need after the sequential run-through of the packets. */
587   postseq_cleanup_all_protocols();
588
589   /* Set the file encapsulation type now; we don't know what it is until
590      we've looked at all the packets, as we don't know until then whether
591      there's more than one type (and thus whether it's
592      WTAP_ENCAP_PER_PACKET). */
593   cf->lnk_t = wtap_file_encap(cf->wth);
594
595   cf->current_frame = cf->first_displayed;
596   cf->current_row = 0;
597
598 #ifdef NEW_PACKET_LIST
599   new_packet_list_thaw();
600 #else
601   packet_list_thaw();
602 #endif
603
604   cf_callback_invoke(cf_cb_file_read_finished, cf);
605
606 #ifndef NEW_PACKET_LIST
607   /* If we have any displayed packets to select, select the first of those
608      packets by making the first row the selected row. */
609   if (cf->first_displayed != NULL)
610     packet_list_select_row(0);
611 #endif /* NEW_PACKET_LIST */
612
613   if(stop_flag) {
614     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
615           "%sFile loading was cancelled!%s\n"
616           "\n"
617                   "The remaining packets in the file were discarded.\n"
618           "\n"
619           "As a lot of packets from the original file will be missing,\n"
620                   "remember to be careful when saving the current content to a file.\n",
621           simple_dialog_primary_start(), simple_dialog_primary_end());
622     return CF_READ_ERROR;
623   }
624
625   if (err != 0) {
626     /* Put up a message box noting that the read failed somewhere along
627        the line.  Don't throw out the stuff we managed to read, though,
628        if any. */
629     switch (err) {
630
631     case WTAP_ERR_UNSUPPORTED_ENCAP:
632       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
633                "The capture file has a packet with a network type that Wireshark doesn't support.\n(%s)",
634                err_info);
635       g_free(err_info);
636       errmsg = errmsg_errno;
637       break;
638
639     case WTAP_ERR_CANT_READ:
640       errmsg = "An attempt to read from the capture file failed for"
641                " some unknown reason.";
642       break;
643
644     case WTAP_ERR_SHORT_READ:
645       errmsg = "The capture file appears to have been cut short"
646                " in the middle of a packet.";
647       break;
648
649     case WTAP_ERR_BAD_RECORD:
650       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
651                "The capture file appears to be damaged or corrupt.\n(%s)",
652                err_info);
653       g_free(err_info);
654       errmsg = errmsg_errno;
655       break;
656
657     default:
658       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
659                "An error occurred while reading the"
660                " capture file: %s.", wtap_strerror(err));
661       errmsg = errmsg_errno;
662       break;
663     }
664     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", errmsg);
665     return CF_READ_ERROR;
666   } else
667     return CF_READ_OK;
668 }
669
670 #ifdef HAVE_LIBPCAP
671 cf_status_t
672 cf_start_tail(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
673 {
674   cf_status_t cf_status;
675
676   cf_status = cf_open(cf, fname, is_tempfile, err);
677   return cf_status;
678 }
679
680 cf_read_status_t
681 cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
682 {
683   gint64 data_offset = 0;
684   gchar *err_info;
685   volatile int newly_displayed_packets = 0;
686   dfilter_t   *dfcode;
687   gboolean filtering_tap_listeners;
688   guint tap_flags;
689
690   /* Compile the current display filter.
691    * We assume this will not fail since cf->dfilter is only set in
692    * cf_filter IFF the filter was valid.
693    */
694   dfcode=NULL;
695   if(cf->dfilter){
696     dfilter_compile(cf->dfilter, &dfcode);
697   }
698
699   /* Do we have any tap listeners with filters? */
700   filtering_tap_listeners = have_filtering_tap_listeners();
701
702   /* Get the union of the flags for all tap listeners. */
703   tap_flags = union_of_tap_listener_flags();
704
705   *err = 0;
706
707 #ifdef NEW_PACKET_LIST
708   new_packet_list_freeze();
709 #else
710   packet_list_check_end();
711   packet_list_freeze();
712 #endif
713
714   /*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: %u new: %u", cf->count, to_read);*/
715
716   while (to_read != 0 && (wtap_read(cf->wth, err, &err_info, &data_offset))) {
717     if (cf->state == FILE_READ_ABORTED) {
718       /* Well, the user decided to exit Wireshark.  Break out of the
719          loop, and let the code below (which is called even if there
720          aren't any packets left to read) exit. */
721       break;
722     }
723     TRY{
724         if (read_packet(cf, dfcode, filtering_tap_listeners, tap_flags,
725                         data_offset) != -1) {
726             newly_displayed_packets++;
727         }
728     }
729     CATCH(OutOfMemoryError) {
730         gpointer dialog;
731
732         dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
733               "%sOut Of Memory!%s\n"
734               "\n"
735               "Sorry, but Wireshark has to terminate now!\n"
736               "\n"
737               "The capture file is not lost, it can be found at:\n"
738               "%s\n"
739               "\n"
740               "Some infos / workarounds can be found at:\n"
741               "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
742               simple_dialog_primary_start(), simple_dialog_primary_end(), cf->filename);
743         /* we have to terminate, as we cannot recover from the memory error */
744         simple_dialog_set_cb(dialog, outofmemory_cb, NULL);
745         while(1) {
746             main_window_update();
747             /* XXX - how to avoid a busy wait? */
748             /* Sleep(100); */
749         };
750 #ifdef NEW_PACKET_LIST
751         new_packet_list_thaw();
752 #else
753         packet_list_thaw();
754 #endif
755         return CF_READ_ABORTED;
756     }
757     ENDTRY;
758     to_read--;
759   }
760
761   /* Cleanup and release all dfilter resources */
762   if (dfcode != NULL){
763     dfilter_free(dfcode);
764   }
765
766   /*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: count %u state: %u err: %u",
767           cf->count, cf->state, *err);*/
768
769 #ifdef NEW_PACKET_LIST
770   new_packet_list_thaw();
771 #else
772   /* XXX - this causes "flickering" of the list */
773   packet_list_thaw();
774 #endif
775
776 #ifndef NEW_PACKET_LIST
777   /* moving to the end of the packet list - if the user requested so and
778      we have some new packets.
779      this doesn't seem to work well with a frozen GTK_Clist, so do this after
780      packet_list_thaw() is done, see bugzilla 1188 */
781   /* XXX - this cheats and looks inside the packet list to find the final
782      row number. */
783   if (newly_displayed_packets && auto_scroll_live && cf->plist_end != NULL)
784     packet_list_moveto_end();
785 #endif /* NEW_PACKET_LIST */
786
787   if (cf->state == FILE_READ_ABORTED) {
788     /* Well, the user decided to exit Wireshark.  Return CF_READ_ABORTED
789        so that our caller can kill off the capture child process;
790        this will cause an EOF on the pipe from the child, so
791        "cf_finish_tail()" will be called, and it will clean up
792        and exit. */
793     return CF_READ_ABORTED;
794   } else if (*err != 0) {
795     /* We got an error reading the capture file.
796        XXX - pop up a dialog box instead? */
797         g_warning("Error \"%s\" while reading: \"%s\"\n",
798                 wtap_strerror(*err), cf->filename);
799
800     return CF_READ_ERROR;
801   } else
802     return CF_READ_OK;
803 }
804
805 cf_read_status_t
806 cf_finish_tail(capture_file *cf, int *err)
807 {
808   gchar *err_info;
809   gint64 data_offset;
810   dfilter_t   *dfcode;
811   gboolean filtering_tap_listeners;
812   guint tap_flags;
813
814   /* Compile the current display filter.
815    * We assume this will not fail since cf->dfilter is only set in
816    * cf_filter IFF the filter was valid.
817    */
818   dfcode=NULL;
819   if(cf->dfilter){
820     dfilter_compile(cf->dfilter, &dfcode);
821   }
822
823   /* Do we have any tap listeners with filters? */
824   filtering_tap_listeners = have_filtering_tap_listeners();
825
826   /* Get the union of the flags for all tap listeners. */
827   tap_flags = union_of_tap_listener_flags();
828
829   if(cf->wth == NULL) {
830     cf_close(cf);
831     return CF_READ_ERROR;
832   }
833
834 #ifdef NEW_PACKET_LIST
835   new_packet_list_freeze();
836 #else
837   packet_list_check_end();
838   packet_list_freeze();
839 #endif
840
841   while ((wtap_read(cf->wth, err, &err_info, &data_offset))) {
842     if (cf->state == FILE_READ_ABORTED) {
843       /* Well, the user decided to abort the read.  Break out of the
844          loop, and let the code below (which is called even if there
845          aren't any packets left to read) exit. */
846       break;
847     }
848     read_packet(cf, dfcode, filtering_tap_listeners, tap_flags, data_offset);
849   }
850
851   /* Cleanup and release all dfilter resources */
852   if (dfcode != NULL){
853     dfilter_free(dfcode);
854   }
855
856 #ifdef NEW_PACKET_LIST
857   new_packet_list_thaw();
858 #else
859   packet_list_thaw();
860 #endif
861
862   if (cf->state == FILE_READ_ABORTED) {
863     /* Well, the user decided to abort the read.  We're only called
864        when the child capture process closes the pipe to us (meaning
865        it's probably exited), so we can just close the capture
866        file; we return CF_READ_ABORTED so our caller can do whatever
867        is appropriate when that happens. */
868     cf_close(cf);
869     return CF_READ_ABORTED;
870   }
871
872 #ifndef NEW_PACKET_LIST
873   if (auto_scroll_live && cf->plist_end != NULL)
874     /* XXX - this cheats and looks inside the packet list to find the final
875        row number. */
876     packet_list_moveto_end();
877 #endif
878
879   /* We're done reading sequentially through the file. */
880   cf->state = FILE_READ_DONE;
881
882   /* We're done reading sequentially through the file; close the
883      sequential I/O side, to free up memory it requires. */
884   wtap_sequential_close(cf->wth);
885
886   /* Allow the protocol dissectors to free up memory that they
887    * don't need after the sequential run-through of the packets. */
888   postseq_cleanup_all_protocols();
889
890   /* Set the file encapsulation type now; we don't know what it is until
891      we've looked at all the packets, as we don't know until then whether
892      there's more than one type (and thus whether it's
893      WTAP_ENCAP_PER_PACKET). */
894   cf->lnk_t = wtap_file_encap(cf->wth);
895
896   if (*err != 0) {
897     /* We got an error reading the capture file.
898        XXX - pop up a dialog box? */
899     return CF_READ_ERROR;
900   } else {
901     return CF_READ_OK;
902   }
903 }
904 #endif /* HAVE_LIBPCAP */
905
906 const gchar *
907 cf_get_display_name(capture_file *cf)
908 {
909   const gchar *displayname;
910
911   /* Return a name to use in displays */
912   if (!cf->is_tempfile) {
913     /* Get the last component of the file name, and use that. */
914     if (cf->filename){
915       displayname = get_basename(cf->filename);
916     } else {
917       displayname="(No file)";
918     }
919   } else {
920     /* The file we read is a temporary file from a live capture;
921        we don't mention its name. */
922     displayname = "(Untitled)";
923   }
924   return displayname;
925 }
926
927 /* XXX - use a macro instead? */
928 int
929 cf_get_packet_count(capture_file *cf)
930 {
931     return cf->count;
932 }
933
934 /* XXX - use a macro instead? */
935 void
936 cf_set_packet_count(capture_file *cf, int packet_count)
937 {
938     cf->count = packet_count;
939 }
940
941 /* XXX - use a macro instead? */
942 gboolean
943 cf_is_tempfile(capture_file *cf)
944 {
945     return cf->is_tempfile;
946 }
947
948 void cf_set_tempfile(capture_file *cf, gboolean is_tempfile)
949 {
950     cf->is_tempfile = is_tempfile;
951 }
952
953
954 /* XXX - use a macro instead? */
955 void cf_set_drops_known(capture_file *cf, gboolean drops_known)
956 {
957     cf->drops_known = drops_known;
958 }
959
960 /* XXX - use a macro instead? */
961 void cf_set_drops(capture_file *cf, guint32 drops)
962 {
963     cf->drops = drops;
964 }
965
966 /* XXX - use a macro instead? */
967 gboolean cf_get_drops_known(capture_file *cf)
968 {
969     return cf->drops_known;
970 }
971
972 /* XXX - use a macro instead? */
973 guint32 cf_get_drops(capture_file *cf)
974 {
975     return cf->drops;
976 }
977
978 void cf_set_rfcode(capture_file *cf, dfilter_t *rfcode)
979 {
980     cf->rfcode = rfcode;
981 }
982
983 static int
984 add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
985         dfilter_t *dfcode, gboolean filtering_tap_listeners,
986         guint tap_flags,
987         union wtap_pseudo_header *pseudo_header, const guchar *buf,
988         gboolean refilter)
989 {
990   gint          row;
991   gboolean      create_proto_tree = FALSE;
992   epan_dissect_t *edt;
993
994   /* just add some value here until we know if it is being displayed or not */
995   fdata->cum_bytes  = cum_bytes + fdata->pkt_len;
996
997   /* If we don't have the time stamp of the first packet in the
998      capture, it's because this is the first packet.  Save the time
999      stamp of this packet as the time stamp of the first packet. */
1000   if (nstime_is_unset(&first_ts)) {
1001     first_ts  = fdata->abs_ts;
1002   }
1003   /* if this frames is marked as a reference time frame, reset
1004      firstsec and firstusec to this frame */
1005   if(fdata->flags.ref_time){
1006     first_ts = fdata->abs_ts;
1007   }
1008
1009   /* If we don't have the time stamp of the previous displayed packet,
1010      it's because this is the first displayed packet.  Save the time
1011      stamp of this packet as the time stamp of the previous displayed
1012      packet. */
1013   if (nstime_is_unset(&prev_dis_ts)) {
1014     prev_dis_ts = fdata->abs_ts;
1015   }
1016
1017   /* Get the time elapsed between the first packet and this packet. */
1018   nstime_delta(&fdata->rel_ts, &fdata->abs_ts, &first_ts);
1019
1020   /* If it's greater than the current elapsed time, set the elapsed time
1021      to it (we check for "greater than" so as not to be confused by
1022      time moving backwards). */
1023   if ((gint32)cf->elapsed_time.secs < fdata->rel_ts.secs
1024   || ((gint32)cf->elapsed_time.secs == fdata->rel_ts.secs && (gint32)cf->elapsed_time.nsecs < fdata->rel_ts.nsecs)) {
1025     cf->elapsed_time = fdata->rel_ts;
1026   }
1027
1028   /* Get the time elapsed between the previous displayed packet and
1029      this packet. */
1030   nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, &prev_dis_ts);
1031
1032   /* If either
1033
1034         we have a display filter and are re-applying it;
1035
1036         we have a list of color filters;
1037
1038         we have tap listeners with filters;
1039
1040         we have tap listeners that require a protocol tree;
1041
1042         we have custom columns;
1043
1044      allocate a protocol tree root node, so that we'll construct
1045      a protocol tree against which a filter expression can be
1046      evaluated. */
1047   if ((dfcode != NULL && refilter) || color_filters_used() ||
1048       filtering_tap_listeners || (tap_flags & TL_REQUIRES_PROTO_TREE) ||
1049       have_custom_cols(&cf->cinfo))
1050           create_proto_tree = TRUE;
1051
1052   /* Dissect the frame. */
1053   edt = epan_dissect_new(create_proto_tree, FALSE);
1054
1055   if (dfcode != NULL && refilter) {
1056       epan_dissect_prime_dfilter(edt, dfcode);
1057   }
1058   /* prepare color filters */
1059   if (color_filters_used()) {
1060       color_filters_prime_edt(edt);
1061   }
1062
1063   col_custom_prime_edt(edt, &cf->cinfo);
1064
1065   tap_queue_init(edt);
1066   epan_dissect_run(edt, pseudo_header, buf, fdata, &cf->cinfo);
1067   tap_push_tapped_queue(edt);
1068
1069   /* If we have a display filter, apply it if we're refiltering, otherwise
1070      leave the "passed_dfilter" flag alone.
1071
1072      If we don't have a display filter, set "passed_dfilter" to 1. */
1073   if (dfcode != NULL) {
1074     if (refilter) {
1075       fdata->flags.passed_dfilter = dfilter_apply_edt(dfcode, edt) ? 1 : 0;
1076     }
1077   } else
1078     fdata->flags.passed_dfilter = 1;
1079
1080   if( (fdata->flags.passed_dfilter) || (edt->pi.fd->flags.ref_time) ){
1081     /* This frame either passed the display filter list or is marked as
1082        a time reference frame.  All time reference frames are displayed
1083        even if they dont pass the display filter */
1084     if(edt->pi.fd->flags.ref_time){
1085       /* if this was a TIME REF frame we should reset the cul bytes field */
1086       cum_bytes = fdata->pkt_len;
1087       fdata->cum_bytes =  cum_bytes;
1088     } else {
1089       /* increase cum_bytes with this packets length */
1090       cum_bytes += fdata->pkt_len;
1091     }
1092
1093     epan_dissect_fill_in_columns(edt);
1094
1095     /* If we haven't yet seen the first frame, this is it.
1096
1097        XXX - we must do this before we add the row to the display,
1098        as, if the display's GtkCList's selection mode is
1099        GTK_SELECTION_BROWSE, when the first entry is added to it,
1100        "cf_select_packet()" will be called, and it will fetch the row
1101        data for the 0th row, and will get a null pointer rather than
1102        "fdata", as "gtk_clist_append()" won't yet have returned and
1103        thus "gtk_clist_set_row_data()" won't yet have been called.
1104
1105        We thus need to leave behind bread crumbs so that
1106        "cf_select_packet()" can find this frame.  See the comment
1107        in "cf_select_packet()". */
1108     if (cf->first_displayed == NULL)
1109       cf->first_displayed = fdata;
1110
1111     /* This is the last frame we've seen so far. */
1112     cf->last_displayed = fdata;
1113
1114     /* XXX - GLIB1 implementation provided to support backport of this feature. */
1115 #if (GLIB_MAJOR_VERSION >= 2)
1116     fdata->col_expr.col_expr = g_strdupv(cf->cinfo.col_expr.col_expr);
1117     fdata->col_expr.col_expr_val = g_strdupv(cf->cinfo.col_expr.col_expr_val);
1118 #else
1119     {
1120       gint i;
1121
1122       fdata->col_expr.col_expr = (gchar **) g_malloc(sizeof(gchar *) * (cf->cinfo.num_cols + 1));
1123       fdata->col_expr.col_expr_val = (gchar **) g_malloc(sizeof(gchar *) * (cf->cinfo.num_cols + 1));
1124
1125       for (i=0; i <= cf->cinfo.num_cols; i++)
1126       {
1127         fdata->col_expr.col_expr[i] = g_strdup(cf->cinfo.col_expr.col_expr[i]);
1128         fdata->col_expr.col_expr_val[i] = g_strdup(cf->cinfo.col_expr.col_expr_val[i]);
1129       }
1130     }
1131 #endif
1132
1133 #ifdef NEW_PACKET_LIST
1134     row = new_packet_list_append(cf->cinfo, fdata);
1135 #else
1136     row = packet_list_append(cf->cinfo.col_data, fdata);
1137 #endif
1138
1139 #ifndef NEW_PACKET_LIST
1140     /* colorize packet: first apply color filters
1141      * then if packet is marked, use preferences to overwrite color
1142      * we do both to make sure that when a packet gets un-marked, the
1143      * color will be correctly set (fixes bug 2038)
1144      */
1145      fdata->color_filter = color_filters_colorize_packet(row, edt);
1146      if (fdata->flags.marked) {
1147        packet_list_set_colors(row, &prefs.gui_marked_fg, &prefs.gui_marked_bg);
1148      }
1149 #endif /* NEW_PACKET_LIST */
1150
1151     /* Set the time of the previous displayed frame to the time of this
1152        frame. */
1153     prev_dis_ts = fdata->abs_ts;
1154
1155     cf->displayed_count++;
1156   } else {
1157     /* This frame didn't pass the display filter, so it's not being added
1158        to the clist, and thus has no row. */
1159     row = -1;
1160   }
1161   epan_dissect_free(edt);
1162   return row;
1163 }
1164
1165 /* read in a new packet */
1166 /* returns the row of the new packet in the packet list or -1 if not displayed */
1167 static int
1168 read_packet(capture_file *cf, dfilter_t *dfcode,
1169             gboolean filtering_tap_listeners, guint tap_flags, gint64 offset)
1170 {
1171   const struct wtap_pkthdr *phdr = wtap_phdr(cf->wth);
1172   union wtap_pseudo_header *pseudo_header = wtap_pseudoheader(cf->wth);
1173   const guchar *buf = wtap_buf_ptr(cf->wth);
1174   frame_data   *fdata;
1175   int           passed;
1176   frame_data   *plist_end;
1177   epan_dissect_t *edt;
1178   int row = -1;
1179
1180   /* Allocate the next list entry, and add it to the list. */
1181   fdata = g_mem_chunk_alloc(cf->plist_chunk);
1182
1183   fdata->num = 0;
1184   fdata->next = NULL;
1185   fdata->prev = NULL;
1186   fdata->pfd  = NULL;
1187   fdata->pkt_len  = phdr->len;
1188   fdata->cap_len  = phdr->caplen;
1189   fdata->file_off = offset;
1190   fdata->lnk_t = phdr->pkt_encap;
1191   fdata->flags.encoding = CHAR_ASCII;
1192   fdata->flags.visited = 0;
1193   fdata->flags.marked = 0;
1194   fdata->flags.ref_time = 0;
1195   fdata->color_filter = NULL;
1196   fdata->col_expr.col_expr = NULL;
1197   fdata->col_expr.col_expr_val = NULL;
1198
1199   fdata->abs_ts.secs = phdr->ts.secs;
1200   fdata->abs_ts.nsecs = phdr->ts.nsecs;
1201
1202   if (cf->plist_end != NULL)
1203     nstime_delta(&fdata->del_cap_ts, &fdata->abs_ts, &cf->plist_end->abs_ts);
1204   else
1205     nstime_set_zero(&fdata->del_cap_ts);
1206
1207   passed = TRUE;
1208   if (cf->rfcode) {
1209     edt = epan_dissect_new(TRUE, FALSE);
1210     epan_dissect_prime_dfilter(edt, cf->rfcode);
1211     epan_dissect_run(edt, pseudo_header, buf, fdata, NULL);
1212     passed = dfilter_apply_edt(cf->rfcode, edt);
1213     epan_dissect_free(edt);
1214   }
1215   if (passed) {
1216     plist_end = cf->plist_end;
1217     fdata->prev = plist_end;
1218     if (plist_end != NULL)
1219       plist_end->next = fdata;
1220     else
1221       cf->plist = fdata;
1222     cf->plist_end = fdata;
1223
1224     cf->count++;
1225     cf->f_datalen = offset + phdr->caplen;
1226     fdata->num = cf->count;
1227     if (!cf->redissecting) {
1228       row = add_packet_to_packet_list(fdata, cf, dfcode,
1229                                       filtering_tap_listeners, tap_flags,
1230                                       pseudo_header, buf, TRUE);
1231     }
1232   } else {
1233     /* XXX - if we didn't have read filters, or if we could avoid
1234        allocating the "frame_data" structure until we knew whether
1235        the frame passed the read filter, we could use a G_ALLOC_ONLY
1236        memory chunk...
1237
1238        ...but, at least in one test I did, where I just made the chunk
1239        a G_ALLOC_ONLY chunk and read in a huge capture file, it didn't
1240        seem to save a noticeable amount of time or space. */
1241     g_strfreev(fdata->col_expr.col_expr);
1242     g_strfreev(fdata->col_expr.col_expr_val);
1243     g_mem_chunk_free(cf->plist_chunk, fdata);
1244   }
1245
1246   return row;
1247 }
1248
1249 cf_status_t
1250 cf_merge_files(char **out_filenamep, int in_file_count,
1251                char *const *in_filenames, int file_type, gboolean do_append)
1252 {
1253   merge_in_file_t  *in_files;
1254   wtap             *wth;
1255   char             *out_filename;
1256   char             *tmpname;
1257   int               out_fd;
1258   wtap_dumper      *pdh;
1259   int               open_err, read_err, write_err, close_err;
1260   gchar            *err_info;
1261   int               err_fileno;
1262   int               i;
1263   char              errmsg_errno[1024+1];
1264   const char       *errmsg;
1265   gboolean          got_read_error = FALSE, got_write_error = FALSE;
1266   gint64            data_offset;
1267   progdlg_t        *progbar = NULL;
1268   gboolean          stop_flag;
1269   gint64            f_len, file_pos;
1270   float             progbar_val;
1271   GTimeVal          start_time;
1272   gchar             status_str[100];
1273   gint64            progbar_nextstep;
1274   gint64            progbar_quantum;
1275
1276   /* open the input files */
1277   if (!merge_open_in_files(in_file_count, in_filenames, &in_files,
1278                            &open_err, &err_info, &err_fileno)) {
1279     g_free(in_files);
1280     cf_open_failure_alert_box(in_filenames[err_fileno], open_err, err_info,
1281                               FALSE, 0);
1282     return CF_ERROR;
1283   }
1284
1285   if (*out_filenamep != NULL) {
1286     out_filename = *out_filenamep;
1287     out_fd = ws_open(out_filename, O_CREAT|O_TRUNC|O_BINARY, 0600);
1288     if (out_fd == -1)
1289       open_err = errno;
1290   } else {
1291     out_fd = create_tempfile(&tmpname, "wireshark");
1292     if (out_fd == -1)
1293       open_err = errno;
1294     out_filename = g_strdup(tmpname);
1295     *out_filenamep = out_filename;
1296   }
1297   if (out_fd == -1) {
1298     err_info = NULL;
1299     merge_close_in_files(in_file_count, in_files);
1300     g_free(in_files);
1301     cf_open_failure_alert_box(out_filename, open_err, NULL, TRUE, file_type);
1302     return CF_ERROR;
1303   }
1304
1305   pdh = wtap_dump_fdopen(out_fd, file_type,
1306       merge_select_frame_type(in_file_count, in_files),
1307       merge_max_snapshot_length(in_file_count, in_files),
1308           FALSE /* compressed */, &open_err);
1309   if (pdh == NULL) {
1310     ws_close(out_fd);
1311     merge_close_in_files(in_file_count, in_files);
1312     g_free(in_files);
1313     cf_open_failure_alert_box(out_filename, open_err, err_info, TRUE,
1314                               file_type);
1315     return CF_ERROR;
1316   }
1317
1318   /* Get the sum of the sizes of all the files. */
1319   f_len = 0;
1320   for (i = 0; i < in_file_count; i++)
1321     f_len += in_files[i].size;
1322
1323   /* Update the progress bar when it gets to this value. */
1324   progbar_nextstep = 0;
1325   /* When we reach the value that triggers a progress bar update,
1326      bump that value by this amount. */
1327   progbar_quantum = f_len/N_PROGBAR_UPDATES;
1328   /* Progress so far. */
1329   progbar_val = 0.0f;
1330
1331   stop_flag = FALSE;
1332   g_get_current_time(&start_time);
1333
1334   /* do the merge (or append) */
1335   for (;;) {
1336     if (do_append)
1337       wth = merge_append_read_packet(in_file_count, in_files, &read_err,
1338                                      &err_info);
1339     else
1340       wth = merge_read_packet(in_file_count, in_files, &read_err,
1341                               &err_info);
1342     if (wth == NULL) {
1343       if (read_err != 0)
1344         got_read_error = TRUE;
1345       break;
1346     }
1347
1348     /* Get the sum of the data offsets in all of the files. */
1349     data_offset = 0;
1350     for (i = 0; i < in_file_count; i++)
1351       data_offset += in_files[i].data_offset;
1352
1353     /* Create the progress bar if necessary.
1354        We check on every iteration of the loop, so that it takes no
1355        longer than the standard time to create it (otherwise, for a
1356        large file, we might take considerably longer than that standard
1357        time in order to get to the next progress bar step). */
1358     if (progbar == NULL) {
1359       progbar = delayed_create_progress_dlg("Merging", "files",
1360         FALSE, &stop_flag, &start_time, progbar_val);
1361     }
1362
1363     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1364        when we update it, we have to run the GTK+ main loop to get it
1365        to repaint what's pending, and doing so may involve an "ioctl()"
1366        to see if there's any pending input from an X server, and doing
1367        that for every packet can be costly, especially on a big file. */
1368     if (data_offset >= progbar_nextstep) {
1369         /* Get the sum of the seek positions in all of the files. */
1370         file_pos = 0;
1371         for (i = 0; i < in_file_count; i++)
1372           file_pos += wtap_read_so_far(in_files[i].wth, NULL);
1373         progbar_val = (gfloat) file_pos / (gfloat) f_len;
1374         if (progbar_val > 1.0f) {
1375           /* Some file probably grew while we were reading it.
1376              That "shouldn't happen", so we'll just clip the progress
1377              value at 1.0. */
1378           progbar_val = 1.0f;
1379         }
1380         if (progbar != NULL) {
1381           g_snprintf(status_str, sizeof(status_str),
1382                      "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
1383                      file_pos / 1024, f_len / 1024);
1384           update_progress_dlg(progbar, progbar_val, status_str);
1385         }
1386         progbar_nextstep += progbar_quantum;
1387     }
1388
1389     if (stop_flag) {
1390       /* Well, the user decided to abort the merge. */
1391       break;
1392     }
1393
1394     if (!wtap_dump(pdh, wtap_phdr(wth), wtap_pseudoheader(wth),
1395          wtap_buf_ptr(wth), &write_err)) {
1396       got_write_error = TRUE;
1397       break;
1398     }
1399   }
1400
1401   /* We're done merging the files; destroy the progress bar if it was created. */
1402   if (progbar != NULL)
1403     destroy_progress_dlg(progbar);
1404
1405   merge_close_in_files(in_file_count, in_files);
1406   if (!got_read_error && !got_write_error) {
1407     if (!wtap_dump_close(pdh, &write_err))
1408       got_write_error = TRUE;
1409   } else
1410     wtap_dump_close(pdh, &close_err);
1411
1412   if (got_read_error) {
1413     /*
1414      * Find the file on which we got the error, and report the error.
1415      */
1416     for (i = 0; i < in_file_count; i++) {
1417       if (in_files[i].state == GOT_ERROR) {
1418         /* Put up a message box noting that a read failed somewhere along
1419            the line. */
1420         switch (read_err) {
1421
1422         case WTAP_ERR_UNSUPPORTED_ENCAP:
1423           g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1424                    "The capture file %%s has a packet with a network type that Wireshark doesn't support.\n(%s)",
1425                    err_info);
1426           g_free(err_info);
1427           errmsg = errmsg_errno;
1428           break;
1429
1430         case WTAP_ERR_CANT_READ:
1431           errmsg = "An attempt to read from the capture file %s failed for"
1432                    " some unknown reason.";
1433           break;
1434
1435         case WTAP_ERR_SHORT_READ:
1436           errmsg = "The capture file %s appears to have been cut short"
1437                    " in the middle of a packet.";
1438           break;
1439
1440         case WTAP_ERR_BAD_RECORD:
1441           g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1442                    "The capture file %%s appears to be damaged or corrupt.\n(%s)",
1443                    err_info);
1444           g_free(err_info);
1445           errmsg = errmsg_errno;
1446           break;
1447
1448         default:
1449           g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1450                    "An error occurred while reading the"
1451                    " capture file %%s: %s.", wtap_strerror(read_err));
1452           errmsg = errmsg_errno;
1453           break;
1454         }
1455         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, errmsg, in_files[i].filename);
1456       }
1457     }
1458   }
1459
1460   if (got_write_error) {
1461     /* Put up an alert box for the write error. */
1462     cf_write_failure_alert_box(out_filename, write_err);
1463   }
1464
1465   if (got_read_error || got_write_error || stop_flag) {
1466     /* Callers aren't expected to treat an error or an explicit abort
1467        differently - we put up error dialogs ourselves, so they don't
1468        have to. */
1469     return CF_ERROR;
1470   } else
1471     return CF_OK;
1472 }
1473
1474 cf_status_t
1475 cf_filter_packets(capture_file *cf, gchar *dftext, gboolean force)
1476 {
1477   const char *filter_new = dftext ? dftext : "";
1478   const char *filter_old = cf->dfilter ? cf->dfilter : "";
1479   dfilter_t   *dfcode;
1480
1481   /* if new filter equals old one, do nothing unless told to do so */
1482   if (!force && strcmp(filter_new, filter_old) == 0) {
1483     return CF_OK;
1484   }
1485
1486   dfcode=NULL;
1487
1488   if (dftext == NULL) {
1489     /* The new filter is an empty filter (i.e., display all packets).
1490      * so leave dfcode==NULL
1491      */
1492   } else {
1493     /*
1494      * We have a filter; make a copy of it (as we'll be saving it),
1495      * and try to compile it.
1496      */
1497     dftext = g_strdup(dftext);
1498     if (!dfilter_compile(dftext, &dfcode)) {
1499       /* The attempt failed; report an error. */
1500       gchar *safe_dftext = simple_dialog_format_message(dftext);
1501       gchar *safe_dfilter_error_msg = simple_dialog_format_message(
1502           dfilter_error_msg);
1503       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1504           "%s%s%s\n"
1505           "\n"
1506           "The following display filter isn't a valid display filter:\n%s\n"
1507           "See the help for a description of the display filter syntax.",
1508           simple_dialog_primary_start(), safe_dfilter_error_msg,
1509           simple_dialog_primary_end(), safe_dftext);
1510       g_free(safe_dfilter_error_msg);
1511       g_free(safe_dftext);
1512       g_free(dftext);
1513       return CF_ERROR;
1514     }
1515
1516     /* Was it empty? */
1517     if (dfcode == NULL) {
1518       /* Yes - free the filter text, and set it to null. */
1519       g_free(dftext);
1520       dftext = NULL;
1521     }
1522   }
1523
1524   /* We have a valid filter.  Replace the current filter. */
1525   g_free(cf->dfilter);
1526   cf->dfilter = dftext;
1527
1528   /* Now rescan the packet list, applying the new filter, but not
1529      throwing away information constructed on a previous pass. */
1530   if (dftext == NULL) {
1531     rescan_packets(cf, "Resetting", "Filter", TRUE, FALSE);
1532   } else {
1533     rescan_packets(cf, "Filtering", dftext, TRUE, FALSE);
1534   }
1535
1536   /* Cleanup and release all dfilter resources */
1537   if (dfcode != NULL){
1538     dfilter_free(dfcode);
1539   }
1540   return CF_OK;
1541 }
1542
1543 void
1544 cf_colorize_packets(capture_file *cf)
1545 {
1546   rescan_packets(cf, "Colorizing", "all packets", FALSE, FALSE);
1547 }
1548
1549 void
1550 cf_reftime_packets(capture_file *cf)
1551 {
1552   rescan_packets(cf, "Updating Reftime", "all packets", FALSE, FALSE);
1553 }
1554
1555 void
1556 cf_redissect_packets(capture_file *cf)
1557 {
1558   rescan_packets(cf, "Reprocessing", "all packets", TRUE, TRUE);
1559 }
1560
1561 /* Rescan the list of packets, reconstructing the CList.
1562
1563    "action" describes why we're doing this; it's used in the progress
1564    dialog box.
1565
1566    "action_item" describes what we're doing; it's used in the progress
1567    dialog box.
1568
1569    "refilter" is TRUE if we need to re-evaluate the filter expression.
1570
1571    "redissect" is TRUE if we need to make the dissectors reconstruct
1572    any state information they have (because a preference that affects
1573    some dissector has changed, meaning some dissector might construct
1574    its state differently from the way it was constructed the last time). */
1575 static void
1576 rescan_packets(capture_file *cf, const char *action, const char *action_item,
1577                 gboolean refilter, gboolean redissect)
1578 {
1579   frame_data *fdata;
1580   progdlg_t  *progbar = NULL;
1581   gboolean    stop_flag;
1582   int         count;
1583   int         err;
1584   gchar      *err_info;
1585   frame_data *selected_frame, *preceding_frame, *following_frame, *prev_frame;
1586   int         selected_row, prev_row, preceding_row, following_row;
1587   gboolean    selected_frame_seen;
1588   int         row;
1589   float       progbar_val;
1590   GTimeVal    start_time;
1591   gchar       status_str[100];
1592   int         progbar_nextstep;
1593   int         progbar_quantum;
1594   dfilter_t   *dfcode;
1595   gboolean    filtering_tap_listeners;
1596   guint       tap_flags;
1597
1598   /* Compile the current display filter.
1599    * We assume this will not fail since cf->dfilter is only set in
1600    * cf_filter IFF the filter was valid.
1601    */
1602   dfcode=NULL;
1603   if(cf->dfilter){
1604     dfilter_compile(cf->dfilter, &dfcode);
1605   }
1606
1607   /* Do we have any tap listeners with filters? */
1608   filtering_tap_listeners = have_filtering_tap_listeners();
1609
1610   /* Get the union of the flags for all tap listeners. */
1611   tap_flags = union_of_tap_listener_flags();
1612
1613   cum_bytes=0;
1614   reset_tap_listeners();
1615   /* Which frame, if any, is the currently selected frame?
1616      XXX - should the selected frame or the focus frame be the "current"
1617      frame, that frame being the one from which "Find Frame" searches
1618      start? */
1619   selected_frame = cf->current_frame;
1620
1621   /* We don't yet know what row that frame will be on, if any, after we
1622      rebuild the clist, however. */
1623   selected_row = -1;
1624
1625   if (redissect) {
1626     /* We need to re-initialize all the state information that protocols
1627        keep, because some preference that controls a dissector has changed,
1628        which might cause the state information to be constructed differently
1629        by that dissector. */
1630
1631     /* We might receive new packets while redissecting, and we don't
1632        want to dissect those before their time. */
1633     cf->redissecting = TRUE;
1634
1635     /* Initialize all data structures used for dissection. */
1636     init_dissection();
1637   }
1638
1639   /* Freeze the packet list while we redo it, so we don't get any
1640      screen updates while it happens. */
1641 #ifdef NEW_PACKET_LIST
1642   new_packet_list_freeze();
1643 #else
1644   packet_list_freeze();
1645
1646   /* Clear it out. */
1647   packet_list_clear();
1648 #endif
1649
1650   /* We don't yet know which will be the first and last frames displayed. */
1651   cf->first_displayed = NULL;
1652   cf->last_displayed = NULL;
1653
1654   /* We currently don't display any packets */
1655   cf->displayed_count = 0;
1656
1657   /* Iterate through the list of frames.  Call a routine for each frame
1658      to check whether it should be displayed and, if so, add it to
1659      the display list. */
1660   nstime_set_unset(&first_ts);
1661   nstime_set_unset(&prev_dis_ts);
1662
1663   /* Update the progress bar when it gets to this value. */
1664   progbar_nextstep = 0;
1665   /* When we reach the value that triggers a progress bar update,
1666      bump that value by this amount. */
1667   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
1668   /* Count of packets at which we've looked. */
1669   count = 0;
1670   /* Progress so far. */
1671   progbar_val = 0.0f;
1672
1673   stop_flag = FALSE;
1674   g_get_current_time(&start_time);
1675
1676   row = -1;             /* no previous row yet */
1677   prev_row = -1;
1678   prev_frame = NULL;
1679
1680   preceding_row = -1;
1681   preceding_frame = NULL;
1682   following_row = -1;
1683   following_frame = NULL;
1684
1685   selected_frame_seen = FALSE;
1686
1687   for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
1688     /* Create the progress bar if necessary.
1689        We check on every iteration of the loop, so that it takes no
1690        longer than the standard time to create it (otherwise, for a
1691        large file, we might take considerably longer than that standard
1692        time in order to get to the next progress bar step). */
1693     if (progbar == NULL)
1694       progbar = delayed_create_progress_dlg(action, action_item, TRUE,
1695                                             &stop_flag, &start_time,
1696                                             progbar_val);
1697
1698     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1699        when we update it, we have to run the GTK+ main loop to get it
1700        to repaint what's pending, and doing so may involve an "ioctl()"
1701        to see if there's any pending input from an X server, and doing
1702        that for every packet can be costly, especially on a big file. */
1703     if (count >= progbar_nextstep) {
1704       /* let's not divide by zero. I should never be started
1705        * with count == 0, so let's assert that
1706        */
1707       g_assert(cf->count > 0);
1708       progbar_val = (gfloat) count / cf->count;
1709
1710       if (progbar != NULL) {
1711         g_snprintf(status_str, sizeof(status_str),
1712                   "%4u of %u frames", count, cf->count);
1713         update_progress_dlg(progbar, progbar_val, status_str);
1714       }
1715
1716       progbar_nextstep += progbar_quantum;
1717     }
1718
1719     if (stop_flag) {
1720       /* Well, the user decided to abort the filtering.  Just stop.
1721
1722          XXX - go back to the previous filter?  Users probably just
1723          want not to wait for a filtering operation to finish;
1724          unless we cancel by having no filter, reverting to the
1725          previous filter will probably be even more expensive than
1726          continuing the filtering, as it involves going back to the
1727          beginning and filtering, and even with no filter we currently
1728          have to re-generate the entire clist, which is also expensive.
1729
1730          I'm not sure what Network Monitor does, but it doesn't appear
1731          to give you an unfiltered display if you cancel. */
1732       break;
1733     }
1734
1735     count++;
1736
1737     if (redissect) {
1738       /* Since all state for the frame was destroyed, mark the frame
1739        * as not visited, free the GSList referring to the state
1740        * data (the per-frame data itself was freed by
1741        * "init_dissection()"), and null out the GSList pointer. */
1742       fdata->flags.visited = 0;
1743       if (fdata->pfd) {
1744         g_slist_free(fdata->pfd);
1745         fdata->pfd = NULL;
1746       }
1747     }
1748
1749     if (!wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
1750         cf->pd, fdata->cap_len, &err, &err_info)) {
1751         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1752                       cf_read_error_message(err, err_info), cf->filename);
1753         break;
1754     }
1755
1756     /* If the previous frame is displayed, and we haven't yet seen the
1757        selected frame, remember that frame - it's the closest one we've
1758        yet seen before the selected frame. */
1759     if (prev_row != -1 && !selected_frame_seen) {
1760       preceding_row = prev_row;
1761       preceding_frame = prev_frame;
1762     }
1763     row = add_packet_to_packet_list(fdata, cf, dfcode, filtering_tap_listeners,
1764                                     tap_flags, &cf->pseudo_header, cf->pd,
1765                                     refilter);
1766
1767     /* If this frame is displayed, and this is the first frame we've
1768        seen displayed after the selected frame, remember this frame -
1769        it's the closest one we've yet seen at or after the selected
1770        frame. */
1771     if (row != -1 && selected_frame_seen && following_row == -1) {
1772       following_row = row;
1773       following_frame = fdata;
1774     }
1775     if (fdata == selected_frame) {
1776       selected_row = row;
1777       selected_frame_seen = TRUE;
1778     }
1779
1780     /* Remember this row/frame - it'll be the previous row/frame
1781        on the next pass through the loop. */
1782     prev_row = row;
1783     prev_frame = fdata;
1784   }
1785
1786   /* We are done redissecting the packet list. */
1787   cf->redissecting = FALSE;
1788
1789 #ifndef NEW_PACKET_LIST
1790   /* Re-sort the list using the previously selected order */
1791   packet_list_set_sort_column();
1792 #endif
1793
1794   if (redissect) {
1795     /* Clear out what remains of the visited flags and per-frame data
1796        pointers.
1797
1798        XXX - that may cause various forms of bogosity when dissecting
1799        these frames, as they won't have been seen by this sequential
1800        pass, but the only alternative I see is to keep scanning them
1801        even though the user requested that the scan stop, and that
1802        would leave the user stuck with an Wireshark grinding on
1803        until it finishes.  Should we just stick them with that? */
1804     for (; fdata != NULL; fdata = fdata->next) {
1805       fdata->flags.visited = 0;
1806       if (fdata->pfd) {
1807         g_slist_free(fdata->pfd);
1808         fdata->pfd = NULL;
1809       }
1810     }
1811   }
1812
1813   /* We're done filtering the packets; destroy the progress bar if it
1814      was created. */
1815   if (progbar != NULL)
1816     destroy_progress_dlg(progbar);
1817
1818   /* Unfreeze the packet list. */
1819 #ifdef NEW_PACKET_LIST
1820   new_packet_list_thaw();
1821 #else
1822   packet_list_thaw();
1823 #endif
1824
1825   if (selected_row == -1) {
1826     /* The selected frame didn't pass the filter. */
1827     if (selected_frame == NULL) {
1828       /* That's because there *was* no selected frame.  Make the first
1829          displayed frame the current frame. */
1830       selected_row = 0;
1831     } else {
1832       /* Find the nearest displayed frame to the selected frame (whether
1833          it's before or after that frame) and make that the current frame.
1834          If the next and previous displayed frames are equidistant from the
1835          selected frame, choose the next one. */
1836       g_assert(following_frame == NULL ||
1837                following_frame->num >= selected_frame->num);
1838       g_assert(preceding_frame == NULL ||
1839                preceding_frame->num <= selected_frame->num);
1840       if (following_frame == NULL) {
1841         /* No frame after the selected frame passed the filter, so we
1842            have to select the last displayed frame before the selected
1843            frame. */
1844         selected_row = preceding_row;
1845       } else if (preceding_frame == NULL) {
1846         /* No frame before the selected frame passed the filter, so we
1847            have to select the first displayed frame after the selected
1848            frame. */
1849         selected_row = following_row;
1850       } else {
1851         /* Frames before and after the selected frame passed the filter, so
1852            we'll select the previous frame */
1853         selected_row = preceding_row;
1854       }
1855     }
1856   }
1857
1858   if (selected_row == -1) {
1859     /* There are no frames displayed at all. */
1860     cf_unselect_packet(cf);
1861   } else {
1862 #ifndef NEW_PACKET_LIST
1863     /* Either the frame that was selected passed the filter, or we've
1864        found the nearest displayed frame to that frame.  Select it, make
1865        it the focus row, and make it visible. */
1866     if (selected_row == 0) {
1867       /* Set to invalid to force update of packet list and packet details */
1868       cf->current_row = -1;
1869     }
1870     packet_list_set_selected_row(selected_row);
1871 #endif /* NEW_PACKET_LIST */
1872   }
1873
1874   /* Cleanup and release all dfilter resources */
1875   if (dfcode != NULL){
1876     dfilter_free(dfcode);
1877   }
1878 }
1879
1880 typedef enum {
1881   PSP_FINISHED,
1882   PSP_STOPPED,
1883   PSP_FAILED
1884 } psp_return_t;
1885
1886 static psp_return_t
1887 process_specified_packets(capture_file *cf, packet_range_t *range,
1888     const char *string1, const char *string2, gboolean terminate_is_stop,
1889     gboolean (*callback)(capture_file *, frame_data *,
1890                          union wtap_pseudo_header *, const guint8 *, void *),
1891     void *callback_args)
1892 {
1893   frame_data *fdata;
1894   int         err;
1895   gchar      *err_info;
1896   union wtap_pseudo_header pseudo_header;
1897   guint8      pd[WTAP_MAX_PACKET_SIZE+1];
1898   psp_return_t ret = PSP_FINISHED;
1899
1900   progdlg_t  *progbar = NULL;
1901   int         progbar_count;
1902   float       progbar_val;
1903   gboolean    progbar_stop_flag;
1904   GTimeVal    progbar_start_time;
1905   gchar       progbar_status_str[100];
1906   int         progbar_nextstep;
1907   int         progbar_quantum;
1908   range_process_e process_this;
1909
1910   /* Update the progress bar when it gets to this value. */
1911   progbar_nextstep = 0;
1912   /* When we reach the value that triggers a progress bar update,
1913      bump that value by this amount. */
1914   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
1915   /* Count of packets at which we've looked. */
1916   progbar_count = 0;
1917   /* Progress so far. */
1918   progbar_val = 0.0f;
1919
1920   progbar_stop_flag = FALSE;
1921   g_get_current_time(&progbar_start_time);
1922
1923   packet_range_process_init(range);
1924
1925   /* Iterate through the list of packets, printing the packets that
1926      were selected by the current display filter.  */
1927   for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
1928     /* Create the progress bar if necessary.
1929        We check on every iteration of the loop, so that it takes no
1930        longer than the standard time to create it (otherwise, for a
1931        large file, we might take considerably longer than that standard
1932        time in order to get to the next progress bar step). */
1933     if (progbar == NULL)
1934       progbar = delayed_create_progress_dlg(string1, string2,
1935                                             terminate_is_stop,
1936                                             &progbar_stop_flag,
1937                                             &progbar_start_time,
1938                                             progbar_val);
1939
1940     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1941        when we update it, we have to run the GTK+ main loop to get it
1942        to repaint what's pending, and doing so may involve an "ioctl()"
1943        to see if there's any pending input from an X server, and doing
1944        that for every packet can be costly, especially on a big file. */
1945     if (progbar_count >= progbar_nextstep) {
1946       /* let's not divide by zero. I should never be started
1947        * with count == 0, so let's assert that
1948        */
1949       g_assert(cf->count > 0);
1950       progbar_val = (gfloat) progbar_count / cf->count;
1951
1952       if (progbar != NULL) {
1953         g_snprintf(progbar_status_str, sizeof(progbar_status_str),
1954                    "%4u of %u packets", progbar_count, cf->count);
1955         update_progress_dlg(progbar, progbar_val, progbar_status_str);
1956       }
1957
1958       progbar_nextstep += progbar_quantum;
1959     }
1960
1961     if (progbar_stop_flag) {
1962       /* Well, the user decided to abort the operation.  Just stop,
1963          and arrange to return PSP_STOPPED to our caller, so they know
1964          it was stopped explicitly. */
1965       ret = PSP_STOPPED;
1966       break;
1967     }
1968
1969     progbar_count++;
1970
1971     /* do we have to process this packet? */
1972     process_this = packet_range_process_packet(range, fdata);
1973     if (process_this == range_process_next) {
1974         /* this packet uninteresting, continue with next one */
1975         continue;
1976     } else if (process_this == range_processing_finished) {
1977         /* all interesting packets processed, stop the loop */
1978         break;
1979     }
1980
1981     /* Get the packet */
1982     if (!wtap_seek_read(cf->wth, fdata->file_off, &pseudo_header,
1983                         pd, fdata->cap_len, &err, &err_info)) {
1984       /* Attempt to get the packet failed. */
1985       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1986                     cf_read_error_message(err, err_info), cf->filename);
1987       ret = PSP_FAILED;
1988       break;
1989     }
1990     /* Process the packet */
1991     if (!callback(cf, fdata, &pseudo_header, pd, callback_args)) {
1992       /* Callback failed.  We assume it reported the error appropriately. */
1993       ret = PSP_FAILED;
1994       break;
1995     }
1996   }
1997
1998   /* We're done printing the packets; destroy the progress bar if
1999      it was created. */
2000   if (progbar != NULL)
2001     destroy_progress_dlg(progbar);
2002
2003   return ret;
2004 }
2005
2006 typedef struct {
2007   gboolean construct_protocol_tree;
2008   column_info *cinfo;
2009 } retap_callback_args_t;
2010
2011 static gboolean
2012 retap_packet(capture_file *cf _U_, frame_data *fdata,
2013              union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2014              void *argsp)
2015 {
2016   retap_callback_args_t *args = argsp;
2017   epan_dissect_t *edt;
2018
2019   edt = epan_dissect_new(args->construct_protocol_tree, FALSE);
2020   tap_queue_init(edt);
2021   epan_dissect_run(edt, pseudo_header, pd, fdata, args->cinfo);
2022   tap_push_tapped_queue(edt);
2023   epan_dissect_free(edt);
2024
2025   return TRUE;
2026 }
2027
2028 cf_read_status_t
2029 cf_retap_packets(capture_file *cf)
2030 {
2031   packet_range_t range;
2032   retap_callback_args_t callback_args;
2033   gboolean filtering_tap_listeners;
2034   guint tap_flags;
2035
2036   /* Do we have any tap listeners with filters? */
2037   filtering_tap_listeners = have_filtering_tap_listeners();
2038
2039   tap_flags = union_of_tap_listener_flags();
2040
2041   /* If any tap listeners have filters, or require the protocol tree,
2042      construct the protocol tree. */
2043   callback_args.construct_protocol_tree = filtering_tap_listeners ||
2044                                           (tap_flags & TL_REQUIRES_PROTO_TREE);
2045
2046   /* If any tap listeners require the columns, construct them. */
2047   callback_args.cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
2048
2049   /* Reset the tap listeners. */
2050   reset_tap_listeners();
2051
2052   /* Iterate through the list of packets, dissecting all packets and
2053      re-running the taps. */
2054   packet_range_init(&range);
2055   packet_range_process_init(&range);
2056   switch (process_specified_packets(cf, &range, "Recalculating statistics on",
2057                                     "all packets", TRUE, retap_packet,
2058                                     &callback_args)) {
2059   case PSP_FINISHED:
2060     /* Completed successfully. */
2061     return CF_READ_OK;
2062
2063   case PSP_STOPPED:
2064     /* Well, the user decided to abort the refiltering.
2065        Return CF_READ_ABORTED so our caller knows they did that. */
2066     return CF_READ_ABORTED;
2067
2068   case PSP_FAILED:
2069     /* Error while retapping. */
2070     return CF_READ_ERROR;
2071   }
2072
2073   g_assert_not_reached();
2074   return CF_READ_OK;
2075 }
2076
2077 typedef struct {
2078   print_args_t *print_args;
2079   gboolean      print_header_line;
2080   char         *header_line_buf;
2081   int           header_line_buf_len;
2082   gboolean      print_formfeed;
2083   gboolean      print_separator;
2084   char         *line_buf;
2085   int           line_buf_len;
2086   gint         *col_widths;
2087 } print_callback_args_t;
2088
2089 static gboolean
2090 print_packet(capture_file *cf, frame_data *fdata,
2091              union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2092              void *argsp)
2093 {
2094   print_callback_args_t *args = argsp;
2095   epan_dissect_t *edt;
2096   int             i;
2097   char           *cp;
2098   int             line_len;
2099   int             column_len;
2100   int             cp_off;
2101   gboolean        proto_tree_needed;
2102   char            bookmark_name[9+10+1];        /* "__frameNNNNNNNNNN__\0" */
2103   char            bookmark_title[6+10+1];       /* "Frame NNNNNNNNNN__\0" */
2104
2105   /* Create the protocol tree, and make it visible, if we're printing
2106      the dissection or the hex data.
2107      XXX - do we need it if we're just printing the hex data? */
2108   proto_tree_needed =
2109       args->print_args->print_dissections != print_dissections_none || args->print_args->print_hex || have_custom_cols(&cf->cinfo);
2110   edt = epan_dissect_new(proto_tree_needed, proto_tree_needed);
2111
2112   /* Fill in the column information if we're printing the summary
2113      information. */
2114   if (args->print_args->print_summary) {
2115     epan_dissect_run(edt, pseudo_header, pd, fdata, &cf->cinfo);
2116     epan_dissect_fill_in_columns(edt);
2117   } else
2118     epan_dissect_run(edt, pseudo_header, pd, fdata, NULL);
2119
2120   if (args->print_formfeed) {
2121     if (!new_page(args->print_args->stream))
2122       goto fail;
2123   } else {
2124       if (args->print_separator) {
2125         if (!print_line(args->print_args->stream, 0, ""))
2126           goto fail;
2127       }
2128   }
2129
2130   /*
2131    * We generate bookmarks, if the output format supports them.
2132    * The name is "__frameN__".
2133    */
2134   g_snprintf(bookmark_name, sizeof bookmark_name, "__frame%u__", fdata->num);
2135
2136   if (args->print_args->print_summary) {
2137     if (args->print_header_line) {
2138       if (!print_line(args->print_args->stream, 0, args->header_line_buf))
2139         goto fail;
2140       args->print_header_line = FALSE;  /* we might not need to print any more */
2141     }
2142     cp = &args->line_buf[0];
2143     line_len = 0;
2144     for (i = 0; i < cf->cinfo.num_cols; i++) {
2145       /* Find the length of the string for this column. */
2146       column_len = (int) strlen(cf->cinfo.col_data[i]);
2147       if (args->col_widths[i] > column_len)
2148          column_len = args->col_widths[i];
2149
2150       /* Make sure there's room in the line buffer for the column; if not,
2151          double its length. */
2152       line_len += column_len + 1;       /* "+1" for space */
2153       if (line_len > args->line_buf_len) {
2154         cp_off = (int) (cp - args->line_buf);
2155         args->line_buf_len = 2 * line_len;
2156         args->line_buf = g_realloc(args->line_buf, args->line_buf_len + 1);
2157         cp = args->line_buf + cp_off;
2158       }
2159
2160       /* Right-justify the packet number column. */
2161       if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2162         g_snprintf(cp, column_len+1, "%*s", args->col_widths[i], cf->cinfo.col_data[i]);
2163       else
2164         g_snprintf(cp, column_len+1, "%-*s", args->col_widths[i], cf->cinfo.col_data[i]);
2165       cp += column_len;
2166       if (i != cf->cinfo.num_cols - 1)
2167         *cp++ = ' ';
2168     }
2169     *cp = '\0';
2170
2171     /*
2172      * Generate a bookmark, using the summary line as the title.
2173      */
2174     if (!print_bookmark(args->print_args->stream, bookmark_name,
2175                         args->line_buf))
2176       goto fail;
2177
2178     if (!print_line(args->print_args->stream, 0, args->line_buf))
2179       goto fail;
2180   } else {
2181     /*
2182      * Generate a bookmark, using "Frame N" as the title, as we're not
2183      * printing the summary line.
2184      */
2185     g_snprintf(bookmark_title, sizeof bookmark_title, "Frame %u", fdata->num);
2186     if (!print_bookmark(args->print_args->stream, bookmark_name,
2187                         bookmark_title))
2188       goto fail;
2189   } /* if (print_summary) */
2190
2191   if (args->print_args->print_dissections != print_dissections_none) {
2192     if (args->print_args->print_summary) {
2193       /* Separate the summary line from the tree with a blank line. */
2194       if (!print_line(args->print_args->stream, 0, ""))
2195         goto fail;
2196     }
2197
2198     /* Print the information in that tree. */
2199     if (!proto_tree_print(args->print_args, edt, args->print_args->stream))
2200       goto fail;
2201
2202     /* Print a blank line if we print anything after this (aka more than one packet). */
2203     args->print_separator = TRUE;
2204
2205     /* Print a header line if we print any more packet summaries */
2206     args->print_header_line = TRUE;
2207   }
2208
2209   if (args->print_args->print_hex) {
2210     /* Print the full packet data as hex. */
2211     if (!print_hex_data(args->print_args->stream, edt))
2212       goto fail;
2213
2214     /* Print a blank line if we print anything after this (aka more than one packet). */
2215     args->print_separator = TRUE;
2216
2217     /* Print a header line if we print any more packet summaries */
2218     args->print_header_line = TRUE;
2219   } /* if (args->print_args->print_dissections != print_dissections_none) */
2220
2221   epan_dissect_free(edt);
2222
2223   /* do we want to have a formfeed between each packet from now on? */
2224   if(args->print_args->print_formfeed) {
2225     args->print_formfeed = TRUE;
2226   }
2227
2228   return TRUE;
2229
2230 fail:
2231   epan_dissect_free(edt);
2232   return FALSE;
2233 }
2234
2235 cf_print_status_t
2236 cf_print_packets(capture_file *cf, print_args_t *print_args)
2237 {
2238   int         i;
2239   print_callback_args_t callback_args;
2240   gint        data_width;
2241   char        *cp;
2242   int         cp_off;
2243   int         column_len;
2244   int         line_len;
2245   psp_return_t ret;
2246
2247   callback_args.print_args = print_args;
2248   callback_args.print_header_line = TRUE;
2249   callback_args.header_line_buf = NULL;
2250   callback_args.header_line_buf_len = 256;
2251   callback_args.print_formfeed = FALSE;
2252   callback_args.print_separator = FALSE;
2253   callback_args.line_buf = NULL;
2254   callback_args.line_buf_len = 256;
2255   callback_args.col_widths = NULL;
2256
2257   if (!print_preamble(print_args->stream, cf->filename)) {
2258     destroy_print_stream(print_args->stream);
2259     return CF_PRINT_WRITE_ERROR;
2260   }
2261
2262   if (print_args->print_summary) {
2263     /* We're printing packet summaries.  Allocate the header line buffer
2264        and get the column widths. */
2265     callback_args.header_line_buf = g_malloc(callback_args.header_line_buf_len + 1);
2266
2267     /* Find the widths for each of the columns - maximum of the
2268        width of the title and the width of the data - and construct
2269        a buffer with a line containing the column titles. */
2270     callback_args.col_widths = (gint *) g_malloc(sizeof(gint) * cf->cinfo.num_cols);
2271     cp = &callback_args.header_line_buf[0];
2272     line_len = 0;
2273     for (i = 0; i < cf->cinfo.num_cols; i++) {
2274       /* Don't pad the last column. */
2275       if (i == cf->cinfo.num_cols - 1)
2276         callback_args.col_widths[i] = 0;
2277       else {
2278         callback_args.col_widths[i] = (gint) strlen(cf->cinfo.col_title[i]);
2279         data_width = get_column_char_width(get_column_format(i));
2280         if (data_width > callback_args.col_widths[i])
2281           callback_args.col_widths[i] = data_width;
2282       }
2283
2284       /* Find the length of the string for this column. */
2285       column_len = (int) strlen(cf->cinfo.col_title[i]);
2286       if (callback_args.col_widths[i] > column_len)
2287         column_len = callback_args.col_widths[i];
2288
2289       /* Make sure there's room in the line buffer for the column; if not,
2290          double its length. */
2291       line_len += column_len + 1;       /* "+1" for space */
2292       if (line_len > callback_args.header_line_buf_len) {
2293         cp_off = (int) (cp - callback_args.header_line_buf);
2294         callback_args.header_line_buf_len = 2 * line_len;
2295         callback_args.header_line_buf = g_realloc(callback_args.header_line_buf,
2296                                                   callback_args.header_line_buf_len + 1);
2297         cp = callback_args.header_line_buf + cp_off;
2298       }
2299
2300       /* Right-justify the packet number column. */
2301 /*      if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2302         g_snprintf(cp, column_len+1, "%*s", callback_args.col_widths[i], cf->cinfo.col_title[i]);
2303       else*/
2304       g_snprintf(cp, column_len+1, "%-*s", callback_args.col_widths[i], cf->cinfo.col_title[i]);
2305       cp += column_len;
2306       if (i != cf->cinfo.num_cols - 1)
2307         *cp++ = ' ';
2308     }
2309     *cp = '\0';
2310
2311     /* Now start out the main line buffer with the same length as the
2312        header line buffer. */
2313     callback_args.line_buf_len = callback_args.header_line_buf_len;
2314     callback_args.line_buf = g_malloc(callback_args.line_buf_len + 1);
2315   } /* if (print_summary) */
2316
2317   /* Iterate through the list of packets, printing the packets we were
2318      told to print. */
2319   ret = process_specified_packets(cf, &print_args->range, "Printing",
2320                                   "selected packets", TRUE, print_packet,
2321                                   &callback_args);
2322
2323   g_free(callback_args.header_line_buf);
2324   g_free(callback_args.line_buf);
2325   g_free(callback_args.col_widths);
2326
2327   switch (ret) {
2328
2329   case PSP_FINISHED:
2330     /* Completed successfully. */
2331     break;
2332
2333   case PSP_STOPPED:
2334     /* Well, the user decided to abort the printing.
2335
2336        XXX - note that what got generated before they did that
2337        will get printed if we're piping to a print program; we'd
2338        have to write to a file and then hand that to the print
2339        program to make it actually not print anything. */
2340     break;
2341
2342   case PSP_FAILED:
2343     /* Error while printing.
2344
2345        XXX - note that what got generated before they did that
2346        will get printed if we're piping to a print program; we'd
2347        have to write to a file and then hand that to the print
2348        program to make it actually not print anything. */
2349     destroy_print_stream(print_args->stream);
2350     return CF_PRINT_WRITE_ERROR;
2351   }
2352
2353   if (!print_finale(print_args->stream)) {
2354     destroy_print_stream(print_args->stream);
2355     return CF_PRINT_WRITE_ERROR;
2356   }
2357
2358   if (!destroy_print_stream(print_args->stream))
2359     return CF_PRINT_WRITE_ERROR;
2360
2361   return CF_PRINT_OK;
2362 }
2363
2364 static gboolean
2365 write_pdml_packet(capture_file *cf _U_, frame_data *fdata,
2366                   union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2367                   void *argsp)
2368 {
2369   FILE *fh = argsp;
2370   epan_dissect_t *edt;
2371
2372   /* Create the protocol tree, but don't fill in the column information. */
2373   edt = epan_dissect_new(TRUE, TRUE);
2374   epan_dissect_run(edt, pseudo_header, pd, fdata, NULL);
2375
2376   /* Write out the information in that tree. */
2377   proto_tree_write_pdml(edt, fh);
2378
2379   epan_dissect_free(edt);
2380
2381   return !ferror(fh);
2382 }
2383
2384 cf_print_status_t
2385 cf_write_pdml_packets(capture_file *cf, print_args_t *print_args)
2386 {
2387   FILE        *fh;
2388   psp_return_t ret;
2389
2390   fh = ws_fopen(print_args->file, "w");
2391   if (fh == NULL)
2392     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2393
2394   write_pdml_preamble(fh);
2395   if (ferror(fh)) {
2396     fclose(fh);
2397     return CF_PRINT_WRITE_ERROR;
2398   }
2399
2400   /* Iterate through the list of packets, printing the packets we were
2401      told to print. */
2402   ret = process_specified_packets(cf, &print_args->range, "Writing PDML",
2403                                   "selected packets", TRUE,
2404                                   write_pdml_packet, fh);
2405
2406   switch (ret) {
2407
2408   case PSP_FINISHED:
2409     /* Completed successfully. */
2410     break;
2411
2412   case PSP_STOPPED:
2413     /* Well, the user decided to abort the printing. */
2414     break;
2415
2416   case PSP_FAILED:
2417     /* Error while printing. */
2418     fclose(fh);
2419     return CF_PRINT_WRITE_ERROR;
2420   }
2421
2422   write_pdml_finale(fh);
2423   if (ferror(fh)) {
2424     fclose(fh);
2425     return CF_PRINT_WRITE_ERROR;
2426   }
2427
2428   /* XXX - check for an error */
2429   fclose(fh);
2430
2431   return CF_PRINT_OK;
2432 }
2433
2434 static gboolean
2435 write_psml_packet(capture_file *cf, frame_data *fdata,
2436                   union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2437                   void *argsp)
2438 {
2439   FILE *fh = argsp;
2440   epan_dissect_t *edt;
2441   gboolean proto_tree_needed;
2442
2443   /* Fill in the column information, only create the protocol tree
2444      if having custom columns. */
2445   proto_tree_needed = have_custom_cols(&cf->cinfo);
2446   edt = epan_dissect_new(proto_tree_needed, proto_tree_needed);
2447   epan_dissect_run(edt, pseudo_header, pd, fdata, &cf->cinfo);
2448   epan_dissect_fill_in_columns(edt);
2449
2450   /* Write out the information in that tree. */
2451   proto_tree_write_psml(edt, fh);
2452
2453   epan_dissect_free(edt);
2454
2455   return !ferror(fh);
2456 }
2457
2458 cf_print_status_t
2459 cf_write_psml_packets(capture_file *cf, print_args_t *print_args)
2460 {
2461   FILE        *fh;
2462   psp_return_t ret;
2463
2464   fh = ws_fopen(print_args->file, "w");
2465   if (fh == NULL)
2466     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2467
2468   write_psml_preamble(fh);
2469   if (ferror(fh)) {
2470     fclose(fh);
2471     return CF_PRINT_WRITE_ERROR;
2472   }
2473
2474   /* Iterate through the list of packets, printing the packets we were
2475      told to print. */
2476   ret = process_specified_packets(cf, &print_args->range, "Writing PSML",
2477                                   "selected packets", TRUE,
2478                                   write_psml_packet, fh);
2479
2480   switch (ret) {
2481
2482   case PSP_FINISHED:
2483     /* Completed successfully. */
2484     break;
2485
2486   case PSP_STOPPED:
2487     /* Well, the user decided to abort the printing. */
2488     break;
2489
2490   case PSP_FAILED:
2491     /* Error while printing. */
2492     fclose(fh);
2493     return CF_PRINT_WRITE_ERROR;
2494   }
2495
2496   write_psml_finale(fh);
2497   if (ferror(fh)) {
2498     fclose(fh);
2499     return CF_PRINT_WRITE_ERROR;
2500   }
2501
2502   /* XXX - check for an error */
2503   fclose(fh);
2504
2505   return CF_PRINT_OK;
2506 }
2507
2508 static gboolean
2509 write_csv_packet(capture_file *cf, frame_data *fdata,
2510                  union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2511                  void *argsp)
2512 {
2513   FILE *fh = argsp;
2514   epan_dissect_t *edt;
2515   gboolean proto_tree_needed;
2516
2517   /* Fill in the column information, only create the protocol tree
2518      if having custom columns. */
2519   proto_tree_needed = have_custom_cols(&cf->cinfo);
2520   edt = epan_dissect_new(proto_tree_needed, proto_tree_needed);
2521   epan_dissect_run(edt, pseudo_header, pd, fdata, &cf->cinfo);
2522   epan_dissect_fill_in_columns(edt);
2523
2524   /* Write out the information in that tree. */
2525   proto_tree_write_csv(edt, fh);
2526
2527   epan_dissect_free(edt);
2528
2529   return !ferror(fh);
2530 }
2531
2532 cf_print_status_t
2533 cf_write_csv_packets(capture_file *cf, print_args_t *print_args)
2534 {
2535   FILE        *fh;
2536   psp_return_t ret;
2537
2538   fh = ws_fopen(print_args->file, "w");
2539   if (fh == NULL)
2540     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2541
2542   write_csv_preamble(fh);
2543   if (ferror(fh)) {
2544     fclose(fh);
2545     return CF_PRINT_WRITE_ERROR;
2546   }
2547
2548   /* Iterate through the list of packets, printing the packets we were
2549      told to print. */
2550   ret = process_specified_packets(cf, &print_args->range, "Writing CSV",
2551                                   "selected packets", TRUE,
2552                                   write_csv_packet, fh);
2553
2554   switch (ret) {
2555
2556   case PSP_FINISHED:
2557     /* Completed successfully. */
2558     break;
2559
2560   case PSP_STOPPED:
2561     /* Well, the user decided to abort the printing. */
2562     break;
2563
2564   case PSP_FAILED:
2565     /* Error while printing. */
2566     fclose(fh);
2567     return CF_PRINT_WRITE_ERROR;
2568   }
2569
2570   write_csv_finale(fh);
2571   if (ferror(fh)) {
2572     fclose(fh);
2573     return CF_PRINT_WRITE_ERROR;
2574   }
2575
2576   /* XXX - check for an error */
2577   fclose(fh);
2578
2579   return CF_PRINT_OK;
2580 }
2581
2582 static gboolean
2583 write_carrays_packet(capture_file *cf _U_, frame_data *fdata,
2584                      union wtap_pseudo_header *pseudo_header _U_,
2585                      const guint8 *pd, void *argsp)
2586 {
2587   FILE *fh = argsp;
2588
2589   proto_tree_write_carrays(pd, fdata->cap_len, fdata->num, fh);
2590   return !ferror(fh);
2591 }
2592
2593 cf_print_status_t
2594 cf_write_carrays_packets(capture_file *cf, print_args_t *print_args)
2595 {
2596   FILE        *fh;
2597   psp_return_t ret;
2598
2599   fh = ws_fopen(print_args->file, "w");
2600
2601   if (fh == NULL)
2602     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2603
2604   write_carrays_preamble(fh);
2605
2606   if (ferror(fh)) {
2607     fclose(fh);
2608     return CF_PRINT_WRITE_ERROR;
2609   }
2610
2611   /* Iterate through the list of packets, printing the packets we were
2612      told to print. */
2613   ret = process_specified_packets(cf, &print_args->range,
2614                                   "Writing C Arrays",
2615                                   "selected packets", TRUE,
2616                                   write_carrays_packet, fh);
2617   switch (ret) {
2618   case PSP_FINISHED:
2619     /* Completed successfully. */
2620     break;
2621   case PSP_STOPPED:
2622     /* Well, the user decided to abort the printing. */
2623     break;
2624   case PSP_FAILED:
2625     /* Error while printing. */
2626     fclose(fh);
2627     return CF_PRINT_WRITE_ERROR;
2628   }
2629
2630   write_carrays_finale(fh);
2631
2632   if (ferror(fh)) {
2633     fclose(fh);
2634     return CF_PRINT_WRITE_ERROR;
2635   }
2636
2637   fclose(fh);
2638   return CF_PRINT_OK;
2639 }
2640
2641 /* Scan through the packet list and change all columns that use the
2642    "command-line-specified" time stamp format to use the current
2643    value of that format. */
2644 void
2645 cf_change_time_formats(capture_file *cf)
2646 {
2647   frame_data *fdata;
2648   progdlg_t  *progbar = NULL;
2649   gboolean    stop_flag;
2650   int         count;
2651   int         row;
2652   int         i;
2653   float       progbar_val;
2654   GTimeVal    start_time;
2655   gchar       status_str[100];
2656   int         progbar_nextstep;
2657   int         progbar_quantum;
2658   gboolean    sorted_by_frame_column;
2659
2660
2661   /* adjust timestamp precision if auto is selected */
2662   cf_timestamp_auto_precision(cf);
2663
2664   /* Are there any columns with time stamps in the "command-line-specified"
2665      format?
2666
2667      XXX - we have to force the "column is writable" flag on, as it
2668      might be off from the last frame that was dissected. */
2669   col_set_writable(&cf->cinfo, TRUE);
2670   if (!check_col(&cf->cinfo, COL_CLS_TIME) &&
2671       !check_col(&cf->cinfo, COL_ABS_TIME) &&
2672       !check_col(&cf->cinfo, COL_ABS_DATE_TIME) &&
2673       !check_col(&cf->cinfo, COL_REL_TIME) &&
2674       !check_col(&cf->cinfo, COL_DELTA_TIME) &&
2675       !check_col(&cf->cinfo, COL_DELTA_TIME_DIS)) {
2676     /* No, there aren't any columns in that format, so we have no work
2677        to do. */
2678     return;
2679   }
2680
2681   /* Freeze the packet list while we redo it, so we don't get any
2682      screen updates while it happens. */
2683 #ifdef NEW_PACKET_LIST
2684   new_packet_list_freeze();
2685 #else
2686   packet_list_freeze();
2687 #endif
2688
2689   /* Update the progress bar when it gets to this value. */
2690   progbar_nextstep = 0;
2691   /* When we reach the value that triggers a progress bar update,
2692      bump that value by this amount. */
2693   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
2694   /* Count of packets at which we've looked. */
2695   count = 0;
2696   /* Progress so far. */
2697   progbar_val = 0.0f;
2698
2699   /*  If the rows are currently sorted by the frame column then we know
2700    *  the row number of each packet: it's the row number of the previously
2701    *  displayed packet + 1.
2702    *
2703    *  Otherwise, if the display is sorted by a different column then we have
2704    *  to use the O(N) packet_list_find_row_from_data() (thus making the job
2705    *  of changing the time display format O(N**2)).
2706    *
2707    *  (XXX - In fact it's still O(N**2) because gtk_clist_set_text() takes
2708    *  the row number and walks that many elements down the clist to find
2709    *  the appropriate element.)
2710    */
2711   sorted_by_frame_column = FALSE;
2712   for (i = 0; i < cf->cinfo.num_cols; i++) {
2713     if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2714     {
2715 #ifndef NEW_PACKET_LIST
2716       sorted_by_frame_column = (i == packet_list_get_sort_column());
2717 #endif
2718       break;
2719     }
2720   }
2721
2722   stop_flag = FALSE;
2723   g_get_current_time(&start_time);
2724
2725   /* Iterate through the list of packets, checking whether the packet
2726      is in a row of the summary list and, if so, whether there are
2727      any columns that show the time in the "command-line-specified"
2728      format and, if so, update that row. */
2729   for (fdata = cf->plist, row = -1; fdata != NULL; fdata = fdata->next) {
2730     /* Create the progress bar if necessary.
2731        We check on every iteration of the loop, so that it takes no
2732        longer than the standard time to create it (otherwise, for a
2733        large file, we might take considerably longer than that standard
2734        time in order to get to the next progress bar step). */
2735     if (progbar == NULL)
2736       progbar = delayed_create_progress_dlg("Changing", "time display",
2737         TRUE, &stop_flag, &start_time, progbar_val);
2738
2739     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
2740        when we update it, we have to run the GTK+ main loop to get it
2741        to repaint what's pending, and doing so may involve an "ioctl()"
2742        to see if there's any pending input from an X server, and doing
2743        that for every packet can be costly, especially on a big file. */
2744     if (count >= progbar_nextstep) {
2745       /* let's not divide by zero. I should never be started
2746        * with count == 0, so let's assert that
2747        */
2748       g_assert(cf->count > 0);
2749
2750       progbar_val = (gfloat) count / cf->count;
2751
2752       if (progbar != NULL) {
2753         g_snprintf(status_str, sizeof(status_str),
2754                    "%4u of %u packets", count, cf->count);
2755         update_progress_dlg(progbar, progbar_val, status_str);
2756       }
2757
2758       progbar_nextstep += progbar_quantum;
2759     }
2760
2761     if (stop_flag) {
2762       /* Well, the user decided to abort the redisplay.  Just stop.
2763
2764          XXX - this leaves the time field in the old format in
2765          frames we haven't yet processed.  So it goes; should we
2766          simply not offer them the option of stopping? */
2767       break;
2768     }
2769
2770     count++;
2771
2772     /* Find what row this packet is in. */
2773     if (!sorted_by_frame_column) {
2774       /* This function is O(N), so we try to avoid using it... */
2775 #ifndef NEW_PACKET_LIST
2776       row = packet_list_find_row_from_data(fdata);
2777 #endif
2778     } else {
2779       /* ...which we do by maintaining a count of packets that are
2780          being displayed (i.e., that have passed the display filter),
2781          and using the current value of that count as the row number
2782          (which is why we can only do it when the display is sorted
2783          by the frame number). */
2784       if (fdata->flags.passed_dfilter)
2785         row++;
2786       else
2787         continue;
2788     }
2789
2790     if (row != -1) {
2791       /* This packet is in the summary list, on row "row". */
2792
2793       for (i = 0; i < cf->cinfo.num_cols; i++) {
2794         if (col_has_time_fmt(&cf->cinfo, i)) {
2795           /* This is one of the columns that shows the time in
2796              "command-line-specified" format; update it. */
2797           cf->cinfo.col_buf[i][0] = '\0';
2798           col_set_fmt_time(fdata, &cf->cinfo, cf->cinfo.col_fmt[i], i);
2799 #ifndef NEW_PACKET_LIST
2800           packet_list_set_text(row, i, cf->cinfo.col_data[i]);
2801 #endif
2802         }
2803       }
2804     }
2805   }
2806
2807   /* We're done redisplaying the packets; destroy the progress bar if it
2808      was created. */
2809   if (progbar != NULL)
2810     destroy_progress_dlg(progbar);
2811
2812   /* Set the column widths of those columns that show the time in
2813      "command-line-specified" format. */
2814   for (i = 0; i < cf->cinfo.num_cols; i++) {
2815     if (col_has_time_fmt(&cf->cinfo, i)) {
2816 #ifndef NEW_PACKET_LIST
2817       packet_list_set_time_width(cf->cinfo.col_fmt[i], i);
2818 #endif
2819     }
2820   }
2821
2822   /* Unfreeze the packet list. */
2823 #ifdef NEW_PACKET_LIST
2824   new_packet_list_thaw();
2825 #else
2826   packet_list_thaw();
2827 #endif
2828 }
2829
2830 typedef struct {
2831         const char      *string;
2832         size_t          string_len;
2833         capture_file    *cf;
2834         gboolean        frame_matched;
2835 } match_data;
2836
2837 gboolean
2838 cf_find_packet_protocol_tree(capture_file *cf, const char *string)
2839 {
2840   match_data            mdata;
2841
2842   mdata.string = string;
2843   mdata.string_len = strlen(string);
2844   return find_packet(cf, match_protocol_tree, &mdata);
2845 }
2846
2847 static gboolean
2848 match_protocol_tree(capture_file *cf, frame_data *fdata, void *criterion)
2849 {
2850   match_data            *mdata = criterion;
2851   epan_dissect_t        *edt;
2852
2853   /* Construct the protocol tree, including the displayed text */
2854   edt = epan_dissect_new(TRUE, TRUE);
2855   /* We don't need the column information */
2856   epan_dissect_run(edt, &cf->pseudo_header, cf->pd, fdata, NULL);
2857
2858   /* Iterate through all the nodes, seeing if they have text that matches. */
2859   mdata->cf = cf;
2860   mdata->frame_matched = FALSE;
2861   proto_tree_children_foreach(edt->tree, match_subtree_text, mdata);
2862   epan_dissect_free(edt);
2863   return mdata->frame_matched;
2864 }
2865
2866 static void
2867 match_subtree_text(proto_node *node, gpointer data)
2868 {
2869   match_data    *mdata = (match_data*) data;
2870   const gchar   *string = mdata->string;
2871   size_t        string_len = mdata->string_len;
2872   capture_file  *cf = mdata->cf;
2873   field_info    *fi = PITEM_FINFO(node);
2874   gchar         label_str[ITEM_LABEL_LENGTH];
2875   gchar         *label_ptr;
2876   size_t        label_len;
2877   guint32       i;
2878   guint8        c_char;
2879   size_t        c_match = 0;
2880
2881   if (mdata->frame_matched) {
2882     /* We already had a match; don't bother doing any more work. */
2883     return;
2884   }
2885
2886   /* Don't match invisible entries. */
2887   if (PROTO_ITEM_IS_HIDDEN(node))
2888     return;
2889
2890   /* was a free format label produced? */
2891   if (fi->rep) {
2892     label_ptr = fi->rep->representation;
2893   } else {
2894     /* no, make a generic label */
2895     label_ptr = label_str;
2896     proto_item_fill_label(fi, label_str);
2897   }
2898
2899   /* Does that label match? */
2900   label_len = strlen(label_ptr);
2901   for (i = 0; i < label_len; i++) {
2902     c_char = label_ptr[i];
2903     if (cf->case_type)
2904       c_char = toupper(c_char);
2905     if (c_char == string[c_match]) {
2906       c_match++;
2907       if (c_match == string_len) {
2908         /* No need to look further; we have a match */
2909         mdata->frame_matched = TRUE;
2910         return;
2911       }
2912     } else
2913       c_match = 0;
2914   }
2915
2916   /* Recurse into the subtree, if it exists */
2917   if (node->first_child != NULL)
2918     proto_tree_children_foreach(node, match_subtree_text, mdata);
2919 }
2920
2921 gboolean
2922 cf_find_packet_summary_line(capture_file *cf, const char *string)
2923 {
2924   match_data            mdata;
2925
2926   mdata.string = string;
2927   mdata.string_len = strlen(string);
2928   return find_packet(cf, match_summary_line, &mdata);
2929 }
2930
2931 static gboolean
2932 match_summary_line(capture_file *cf, frame_data *fdata, void *criterion)
2933 {
2934   match_data            *mdata = criterion;
2935   const gchar           *string = mdata->string;
2936   size_t                string_len = mdata->string_len;
2937   epan_dissect_t        *edt;
2938   const char            *info_column;
2939   size_t                info_column_len;
2940   gboolean              frame_matched = FALSE;
2941   gint                  colx;
2942   guint32               i;
2943   guint8                c_char;
2944   size_t                c_match = 0;
2945
2946   /* Don't bother constructing the protocol tree */
2947   edt = epan_dissect_new(FALSE, FALSE);
2948   /* Get the column information */
2949   epan_dissect_run(edt, &cf->pseudo_header, cf->pd, fdata, &cf->cinfo);
2950
2951   /* Find the Info column */
2952   for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
2953     if (cf->cinfo.fmt_matx[colx][COL_INFO]) {
2954       /* Found it.  See if we match. */
2955       info_column = edt->pi.cinfo->col_data[colx];
2956       info_column_len = strlen(info_column);
2957       for (i = 0; i < info_column_len; i++) {
2958         c_char = info_column[i];
2959         if (cf->case_type)
2960           c_char = toupper(c_char);
2961         if (c_char == string[c_match]) {
2962           c_match++;
2963           if (c_match == string_len) {
2964             frame_matched = TRUE;
2965             break;
2966           }
2967         } else
2968           c_match = 0;
2969       }
2970       break;
2971     }
2972   }
2973   epan_dissect_free(edt);
2974   return frame_matched;
2975 }
2976
2977 typedef struct {
2978         const guint8 *data;
2979         size_t data_len;
2980 } cbs_t;        /* "Counted byte string" */
2981
2982 gboolean
2983 cf_find_packet_data(capture_file *cf, const guint8 *string, size_t string_size)
2984 {
2985   cbs_t info;
2986
2987   info.data = string;
2988   info.data_len = string_size;
2989
2990   /* String or hex search? */
2991   if (cf->string) {
2992     /* String search - what type of string? */
2993     switch (cf->scs_type) {
2994
2995     case SCS_ASCII_AND_UNICODE:
2996       return find_packet(cf, match_ascii_and_unicode, &info);
2997
2998     case SCS_ASCII:
2999       return find_packet(cf, match_ascii, &info);
3000
3001     case SCS_UNICODE:
3002       return find_packet(cf, match_unicode, &info);
3003
3004     default:
3005       g_assert_not_reached();
3006       return FALSE;
3007     }
3008   } else
3009     return find_packet(cf, match_binary, &info);
3010 }
3011
3012 static gboolean
3013 match_ascii_and_unicode(capture_file *cf, frame_data *fdata, void *criterion)
3014 {
3015   cbs_t         *info = criterion;
3016   const guint8  *ascii_text = info->data;
3017   size_t        textlen = info->data_len;
3018   gboolean      frame_matched;
3019   guint32       buf_len;
3020   guint32       i;
3021   guint8        c_char;
3022   size_t        c_match = 0;
3023
3024   frame_matched = FALSE;
3025   buf_len = fdata->pkt_len;
3026   for (i = 0; i < buf_len; i++) {
3027     c_char = cf->pd[i];
3028     if (cf->case_type)
3029       c_char = toupper(c_char);
3030     if (c_char != 0) {
3031       if (c_char == ascii_text[c_match]) {
3032         c_match++;
3033         if (c_match == textlen) {
3034           frame_matched = TRUE;
3035           cf->search_pos = i; /* Save the position of the last character
3036                                for highlighting the field. */
3037           break;
3038         }
3039       } else
3040         c_match = 0;
3041     }
3042   }
3043   return frame_matched;
3044 }
3045
3046 static gboolean
3047 match_ascii(capture_file *cf, frame_data *fdata, void *criterion)
3048 {
3049   cbs_t         *info = criterion;
3050   const guint8  *ascii_text = info->data;
3051   size_t        textlen = info->data_len;
3052   gboolean      frame_matched;
3053   guint32       buf_len;
3054   guint32       i;
3055   guint8        c_char;
3056   size_t        c_match = 0;
3057
3058   frame_matched = FALSE;
3059   buf_len = fdata->pkt_len;
3060   for (i = 0; i < buf_len; i++) {
3061     c_char = cf->pd[i];
3062     if (cf->case_type)
3063       c_char = toupper(c_char);
3064     if (c_char == ascii_text[c_match]) {
3065       c_match++;
3066       if (c_match == textlen) {
3067         frame_matched = TRUE;
3068         cf->search_pos = i; /* Save the position of the last character
3069                                for highlighting the field. */
3070         break;
3071       }
3072     } else
3073       c_match = 0;
3074   }
3075   return frame_matched;
3076 }
3077
3078 static gboolean
3079 match_unicode(capture_file *cf, frame_data *fdata, void *criterion)
3080 {
3081   cbs_t         *info = criterion;
3082   const guint8  *ascii_text = info->data;
3083   size_t        textlen = info->data_len;
3084   gboolean      frame_matched;
3085   guint32       buf_len;
3086   guint32       i;
3087   guint8        c_char;
3088   size_t        c_match = 0;
3089
3090   frame_matched = FALSE;
3091   buf_len = fdata->pkt_len;
3092   for (i = 0; i < buf_len; i++) {
3093     c_char = cf->pd[i];
3094     if (cf->case_type)
3095       c_char = toupper(c_char);
3096     if (c_char == ascii_text[c_match]) {
3097       c_match++;
3098       i++;
3099       if (c_match == textlen) {
3100         frame_matched = TRUE;
3101         cf->search_pos = i; /* Save the position of the last character
3102                                for highlighting the field. */
3103         break;
3104       }
3105     } else
3106       c_match = 0;
3107   }
3108   return frame_matched;
3109 }
3110
3111 static gboolean
3112 match_binary(capture_file *cf, frame_data *fdata, void *criterion)
3113 {
3114   cbs_t         *info = criterion;
3115   const guint8  *binary_data = info->data;
3116   size_t        datalen = info->data_len;
3117   gboolean      frame_matched;
3118   guint32       buf_len;
3119   guint32       i;
3120   size_t        c_match = 0;
3121
3122   frame_matched = FALSE;
3123   buf_len = fdata->pkt_len;
3124   for (i = 0; i < buf_len; i++) {
3125     if (cf->pd[i] == binary_data[c_match]) {
3126       c_match++;
3127       if (c_match == datalen) {
3128         frame_matched = TRUE;
3129         cf->search_pos = i; /* Save the position of the last character
3130                                for highlighting the field. */
3131         break;
3132       }
3133     } else
3134       c_match = 0;
3135   }
3136   return frame_matched;
3137 }
3138
3139 gboolean
3140 cf_find_packet_dfilter(capture_file *cf, dfilter_t *sfcode)
3141 {
3142   return find_packet(cf, match_dfilter, sfcode);
3143 }
3144
3145 static gboolean
3146 match_dfilter(capture_file *cf, frame_data *fdata, void *criterion)
3147 {
3148   dfilter_t             *sfcode = criterion;
3149   epan_dissect_t        *edt;
3150   gboolean              frame_matched;
3151
3152   edt = epan_dissect_new(TRUE, FALSE);
3153   epan_dissect_prime_dfilter(edt, sfcode);
3154   epan_dissect_run(edt, &cf->pseudo_header, cf->pd, fdata, NULL);
3155   frame_matched = dfilter_apply_edt(sfcode, edt);
3156   epan_dissect_free(edt);
3157   return frame_matched;
3158 }
3159
3160 static gboolean
3161 find_packet(capture_file *cf,
3162             gboolean (*match_function)(capture_file *, frame_data *, void *),
3163             void *criterion)
3164 {
3165   frame_data *start_fd;
3166   frame_data *fdata;
3167   frame_data *new_fd = NULL;
3168   progdlg_t  *progbar = NULL;
3169   gboolean    stop_flag;
3170   int         count;
3171   int         err;
3172   gchar      *err_info;
3173 #ifndef NEW_PACKET_LIST
3174   int         row;
3175 #endif
3176   float       progbar_val;
3177   GTimeVal    start_time;
3178   gchar       status_str[100];
3179   int         progbar_nextstep;
3180   int         progbar_quantum;
3181   char       *title;
3182
3183   start_fd = cf->current_frame;
3184   if (start_fd != NULL)  {
3185     /* Iterate through the list of packets, starting at the packet we've
3186        picked, calling a routine to run the filter on the packet, see if
3187        it matches, and stop if so.  */
3188     count = 0;
3189     fdata = start_fd;
3190
3191     /* Update the progress bar when it gets to this value. */
3192     progbar_nextstep = 0;
3193     /* When we reach the value that triggers a progress bar update,
3194        bump that value by this amount. */
3195     progbar_quantum = cf->count/N_PROGBAR_UPDATES;
3196     /* Progress so far. */
3197     progbar_val = 0.0f;
3198
3199     stop_flag = FALSE;
3200     g_get_current_time(&start_time);
3201
3202     fdata = start_fd;
3203     title = cf->sfilter?cf->sfilter:"";
3204     for (;;) {
3205       /* Create the progress bar if necessary.
3206          We check on every iteration of the loop, so that it takes no
3207          longer than the standard time to create it (otherwise, for a
3208          large file, we might take considerably longer than that standard
3209          time in order to get to the next progress bar step). */
3210       if (progbar == NULL)
3211          progbar = delayed_create_progress_dlg("Searching", title,
3212            FALSE, &stop_flag, &start_time, progbar_val);
3213
3214       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
3215          when we update it, we have to run the GTK+ main loop to get it
3216          to repaint what's pending, and doing so may involve an "ioctl()"
3217          to see if there's any pending input from an X server, and doing
3218          that for every packet can be costly, especially on a big file. */
3219       if (count >= progbar_nextstep) {
3220         /* let's not divide by zero. I should never be started
3221          * with count == 0, so let's assert that
3222          */
3223         g_assert(cf->count > 0);
3224
3225         progbar_val = (gfloat) count / cf->count;
3226
3227         if (progbar != NULL) {
3228           g_snprintf(status_str, sizeof(status_str),
3229                      "%4u of %u packets", count, cf->count);
3230           update_progress_dlg(progbar, progbar_val, status_str);
3231         }
3232
3233         progbar_nextstep += progbar_quantum;
3234       }
3235
3236       if (stop_flag) {
3237         /* Well, the user decided to abort the search.  Go back to the
3238            frame where we started. */
3239         new_fd = start_fd;
3240         break;
3241       }
3242
3243       /* Go past the current frame. */
3244       if (cf->sbackward) {
3245         /* Go on to the previous frame. */
3246         fdata = fdata->prev;
3247         if (fdata == NULL) {
3248           /*
3249            * XXX - other apps have a bit more of a detailed message
3250            * for this, and instead of offering "OK" and "Cancel",
3251            * they offer things such as "Continue" and "Cancel";
3252            * we need an API for popping up alert boxes with
3253            * {Verb} and "Cancel".
3254            */
3255
3256           if (prefs.gui_find_wrap)
3257           {
3258               simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3259                             "%sBeginning of capture exceeded!%s\n\n"
3260                             "Search is continued from the end of the capture.",
3261                             simple_dialog_primary_start(), simple_dialog_primary_end());
3262               fdata = cf->plist_end;    /* wrap around */
3263           }
3264           else
3265           {
3266               simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3267                             "%sBeginning of capture exceeded!%s\n\n"
3268                             "Try searching forwards.",
3269                             simple_dialog_primary_start(), simple_dialog_primary_end());
3270               fdata = start_fd;        /* stay on previous packet */
3271           }
3272         }
3273       } else {
3274         /* Go on to the next frame. */
3275         fdata = fdata->next;
3276         if (fdata == NULL) {
3277           if (prefs.gui_find_wrap)
3278           {
3279               simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3280                             "%sEnd of capture exceeded!%s\n\n"
3281                             "Search is continued from the start of the capture.",
3282                             simple_dialog_primary_start(), simple_dialog_primary_end());
3283               fdata = cf->plist;        /* wrap around */
3284           }
3285           else
3286           {
3287               simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3288                             "%sEnd of capture exceeded!%s\n\n"
3289                             "Try searching backwards.",
3290                             simple_dialog_primary_start(), simple_dialog_primary_end());
3291               fdata = start_fd;     /* stay on previous packet */
3292           }
3293         }
3294       }
3295
3296       count++;
3297
3298       /* Is this packet in the display? */
3299       if (fdata->flags.passed_dfilter) {
3300         /* Yes.  Load its data. */
3301         if (!wtap_seek_read(cf->wth, fdata->file_off, &cf->pseudo_header,
3302                         cf->pd, fdata->cap_len, &err, &err_info)) {
3303           /* Read error.  Report the error, and go back to the frame
3304              where we started. */
3305           simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3306                         cf_read_error_message(err, err_info), cf->filename);
3307           new_fd = start_fd;
3308           break;
3309         }
3310
3311         /* Does it match the search criterion? */
3312         if ((*match_function)(cf, fdata, criterion)) {
3313           new_fd = fdata;
3314           break;        /* found it! */
3315         }
3316       }
3317
3318       if (fdata == start_fd) {
3319         /* We're back to the frame we were on originally, and that frame
3320            doesn't match the search filter.  The search failed. */
3321         break;
3322       }
3323     }
3324
3325     /* We're done scanning the packets; destroy the progress bar if it
3326        was created. */
3327     if (progbar != NULL)
3328       destroy_progress_dlg(progbar);
3329   }
3330
3331   if (new_fd != NULL) {
3332 #ifndef NEW_PACKET_LIST
3333     /* We found a frame.  Find what row it's in. */
3334     row = packet_list_find_row_from_data(new_fd);
3335     if (row == -1) {
3336         /* We didn't find a row even though we know that a frame
3337          * exists that satifies the search criteria. This means that the
3338          * frame isn't being displayed currently so we can't select it. */
3339         simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3340                       "%sEnd of capture exceeded!%s\n\n"
3341                       "The capture file is probably not fully loaded.",
3342                       simple_dialog_primary_start(), simple_dialog_primary_end());
3343         return FALSE;
3344     }
3345
3346     /* Select that row, make it the focus row, and make it visible. */
3347     packet_list_set_selected_row(row);
3348 #endif /* NEW_PACKET_LIST */
3349     return TRUE;        /* success */
3350   } else
3351     return FALSE;       /* failure */
3352 }
3353
3354 gboolean
3355 cf_goto_frame(capture_file *cf, guint fnumber)
3356 {
3357   frame_data *fdata;
3358 #ifndef NEW_PACKET_LIST
3359   int row;
3360 #endif
3361
3362   for (fdata = cf->plist; fdata != NULL && fdata->num < fnumber; fdata = fdata->next)
3363     ;
3364
3365   if (fdata == NULL) {
3366     /* we didn't find a packet with that packet number */
3367     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3368                   "There is no packet with the packet number %u.", fnumber);
3369     return FALSE;       /* we failed to go to that packet */
3370   }
3371   if (!fdata->flags.passed_dfilter) {
3372     /* that packet currently isn't displayed */
3373     /* XXX - add it to the set of displayed packets? */
3374     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3375                   "The packet number %u isn't currently being displayed.", fnumber);
3376     return FALSE;       /* we failed to go to that packet */
3377   }
3378
3379 #ifndef NEW_PACKET_LIST
3380   /* We found that packet, and it's currently being displayed.
3381      Find what row it's in. */
3382   row = packet_list_find_row_from_data(fdata);
3383   g_assert(row != -1);
3384
3385   /* Select that row, make it the focus row, and make it visible. */
3386   packet_list_set_selected_row(row);
3387 #endif /* NEW_PACKET_LIST */
3388   return TRUE;  /* we got to that packet */
3389 }
3390
3391 gboolean
3392 cf_goto_top_frame(capture_file *cf)
3393 {
3394   frame_data *fdata;
3395 #ifndef NEW_PACKET_LIST
3396   int row;
3397 #endif
3398   frame_data *lowest_fdata = NULL;
3399
3400   for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
3401     if (fdata->flags.passed_dfilter) {
3402         lowest_fdata = fdata;
3403         break;
3404     }
3405   }
3406
3407   if (lowest_fdata == NULL) {
3408       return FALSE;
3409   }
3410
3411 #ifndef NEW_PACKET_LIST
3412   /* We found that packet, and it's currently being displayed.
3413      Find what row it's in. */
3414   row = packet_list_find_row_from_data(lowest_fdata);
3415   g_assert(row != -1);
3416
3417   /* Select that row, make it the focus row, and make it visible. */
3418   packet_list_set_selected_row(row);
3419 #endif /* NEW_PACKET_LIST */
3420   return TRUE;  /* we got to that packet */
3421 }
3422
3423 gboolean
3424 cf_goto_bottom_frame(capture_file *cf)
3425 {
3426   frame_data *fdata;
3427 #ifndef NEW_PACKET_LIST
3428   int row;
3429 #endif
3430   frame_data *highest_fdata = NULL;
3431
3432   for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
3433     if (fdata->flags.passed_dfilter) {
3434         highest_fdata = fdata;
3435     }
3436   }
3437
3438   if (highest_fdata == NULL) {
3439       return FALSE;
3440   }
3441
3442 #ifndef NEW_PACKET_LIST
3443   /* We found that packet, and it's currently being displayed.
3444      Find what row it's in. */
3445   row = packet_list_find_row_from_data(highest_fdata);
3446   g_assert(row != -1);
3447
3448   /* Select that row, make it the focus row, and make it visible. */
3449   packet_list_set_selected_row(row);
3450 #endif /* NEW_PACKET_LIST */
3451   return TRUE;  /* we got to that packet */
3452 }
3453
3454 /*
3455  * Go to frame specified by currently selected protocol tree item.
3456  */
3457 gboolean
3458 cf_goto_framenum(capture_file *cf)
3459 {
3460   header_field_info       *hfinfo;
3461   guint32                 framenum;
3462
3463   if (cf->finfo_selected) {
3464     hfinfo = cf->finfo_selected->hfinfo;
3465     g_assert(hfinfo);
3466     if (hfinfo->type == FT_FRAMENUM) {
3467       framenum = fvalue_get_uinteger(&cf->finfo_selected->value);
3468       if (framenum != 0)
3469         return cf_goto_frame(cf, framenum);
3470       }
3471   }
3472
3473   return FALSE;
3474 }
3475
3476 /* Select the packet on a given row. */
3477 void
3478 cf_select_packet(capture_file *cf, int row)
3479 {
3480   frame_data *fdata;
3481   int err;
3482   gchar *err_info;
3483
3484   /* Get the frame data struct pointer for this frame */
3485 #ifdef NEW_PACKET_LIST
3486   fdata = new_packet_list_get_row_data(row);
3487 #else
3488   fdata = (frame_data *)packet_list_get_row_data(row);
3489 #endif
3490
3491   if (fdata == NULL) {
3492     /* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
3493        the first entry is added to it by "real_insert_row()", that row
3494        is selected (see "real_insert_row()", in "gtk/gtkclist.c", in both
3495        our version and the vanilla GTK+ version).
3496
3497        This means that a "select-row" signal is emitted; this causes
3498        "packet_list_select_cb()" to be called, which causes "cf_select_packet()"
3499        to be called.
3500
3501        "cf_select_packet()" fetches, above, the data associated with the
3502        row that was selected; however, as "gtk_clist_append()", which
3503        called "real_insert_row()", hasn't yet returned, we haven't yet
3504        associated any data with that row, so we get back a null pointer.
3505
3506        We can't assume that there's only one frame in the frame list,
3507        either, as we may be filtering the display.
3508
3509        We therefore assume that, if "row" is 0, i.e. the first row
3510        is being selected, and "cf->first_displayed" equals
3511        "cf->last_displayed", i.e. there's only one frame being
3512        displayed, that frame is the frame we want.
3513
3514        This means we have to set "cf->first_displayed" and
3515        "cf->last_displayed" before adding the row to the
3516        GtkCList; see the comment in "add_packet_to_packet_list()". */
3517
3518        if (row == 0 && cf->first_displayed == cf->last_displayed)
3519          fdata = cf->first_displayed;
3520   }
3521
3522   /* If fdata _still_ isn't set simply give up. */
3523   if (fdata == NULL) {
3524     return;
3525   }
3526
3527   /* Get the data in that frame. */
3528   if (!wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
3529                        cf->pd, fdata->cap_len, &err, &err_info)) {
3530     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3531                   cf_read_error_message(err, err_info), cf->filename);
3532     return;
3533   }
3534
3535   /* Record that this frame is the current frame. */
3536   cf->current_frame = fdata;
3537   cf->current_row = row;
3538
3539   /* Create the logical protocol tree. */
3540   if (cf->edt != NULL) {
3541     epan_dissect_free(cf->edt);
3542     cf->edt = NULL;
3543   }
3544   /* We don't need the columns here. */
3545   cf->edt = epan_dissect_new(TRUE, TRUE);
3546
3547   epan_dissect_run(cf->edt, &cf->pseudo_header, cf->pd, cf->current_frame,
3548           NULL);
3549
3550   dfilter_macro_build_ftv_cache(cf->edt->tree);
3551
3552   cf_callback_invoke(cf_cb_packet_selected, cf);
3553 }
3554
3555 /* Unselect the selected packet, if any. */
3556 void
3557 cf_unselect_packet(capture_file *cf)
3558 {
3559   /* Destroy the epan_dissect_t for the unselected packet. */
3560   if (cf->edt != NULL) {
3561     epan_dissect_free(cf->edt);
3562     cf->edt = NULL;
3563   }
3564
3565   /* No packet is selected. */
3566   cf->current_frame = NULL;
3567   cf->current_row = 0;
3568
3569   cf_callback_invoke(cf_cb_packet_unselected, cf);
3570
3571   /* No protocol tree means no selected field. */
3572   cf_unselect_field(cf);
3573 }
3574
3575 /* Unset the selected protocol tree field, if any. */
3576 void
3577 cf_unselect_field(capture_file *cf)
3578 {
3579   cf->finfo_selected = NULL;
3580
3581   cf_callback_invoke(cf_cb_field_unselected, cf);
3582 }
3583
3584 /*
3585  * Mark a particular frame.
3586  */
3587 void
3588 cf_mark_frame(capture_file *cf, frame_data *frame)
3589 {
3590   if (! frame->flags.marked) {
3591     frame->flags.marked = TRUE;
3592     if (cf->count > cf->marked_count)
3593       cf->marked_count++;
3594   }
3595 }
3596
3597 /*
3598  * Unmark a particular frame.
3599  */
3600 void
3601 cf_unmark_frame(capture_file *cf, frame_data *frame)
3602 {
3603   if (frame->flags.marked) {
3604     frame->flags.marked = FALSE;
3605     if (cf->marked_count > 0)
3606       cf->marked_count--;
3607   }
3608 }
3609
3610 typedef struct {
3611   wtap_dumper *pdh;
3612   const char  *fname;
3613 } save_callback_args_t;
3614
3615 /*
3616  * Save a capture to a file, in a particular format, saving either
3617  * all packets, all currently-displayed packets, or all marked packets.
3618  *
3619  * Returns TRUE if it succeeds, FALSE otherwise; if it fails, it pops
3620  * up a message box for the failure.
3621  */
3622 static gboolean
3623 save_packet(capture_file *cf _U_, frame_data *fdata,
3624             union wtap_pseudo_header *pseudo_header, const guint8 *pd,
3625             void *argsp)
3626 {
3627   save_callback_args_t *args = argsp;
3628   struct wtap_pkthdr hdr;
3629   int           err;
3630
3631   /* init the wtap header for saving */
3632   hdr.ts.secs    = fdata->abs_ts.secs;
3633   hdr.ts.nsecs   = fdata->abs_ts.nsecs;
3634   hdr.caplen     = fdata->cap_len;
3635   hdr.len        = fdata->pkt_len;
3636   hdr.pkt_encap  = fdata->lnk_t;
3637
3638   /* and save the packet */
3639   if (!wtap_dump(args->pdh, &hdr, pseudo_header, pd, &err)) {
3640     cf_write_failure_alert_box(args->fname, err);
3641     return FALSE;
3642   }
3643   return TRUE;
3644 }
3645
3646 /*
3647  * Can this capture file be saved in any format except by copying the raw data?
3648  */
3649 gboolean
3650 cf_can_save_as(capture_file *cf)
3651 {
3652   int ft;
3653
3654   for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
3655     /* To save a file with Wiretap, Wiretap has to handle that format,
3656        and its code to handle that format must be able to write a file
3657        with this file's encapsulation type. */
3658     if (wtap_dump_can_open(ft) && wtap_dump_can_write_encap(ft, cf->lnk_t)) {
3659       /* OK, we can write it out in this type. */
3660       return TRUE;
3661     }
3662   }
3663
3664   /* No, we couldn't save it in any format. */
3665   return FALSE;
3666 }
3667
3668 cf_status_t
3669 cf_save(capture_file *cf, const char *fname, packet_range_t *range, guint save_format, gboolean compressed)
3670 {
3671   gchar        *from_filename;
3672   int           err;
3673   gboolean      do_copy;
3674   wtap_dumper  *pdh;
3675   save_callback_args_t callback_args;
3676
3677   cf_callback_invoke(cf_cb_file_safe_started, (gpointer) fname);
3678
3679   /* don't write over an existing file. */
3680   /* this should've been already checked by our caller, just to be sure... */
3681   if (file_exists(fname)) {
3682     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3683       "%sCapture file: \"%s\" already exists!%s\n\n"
3684       "Please choose a different filename.",
3685       simple_dialog_primary_start(), fname, simple_dialog_primary_end());
3686     goto fail;
3687   }
3688
3689   packet_range_process_init(range);
3690
3691
3692   if (packet_range_process_all(range) && save_format == cf->cd_t) {
3693     /* We're not filtering packets, and we're saving it in the format
3694        it's already in, so we can just move or copy the raw data. */
3695
3696     if (cf->is_tempfile) {
3697       /* The file being saved is a temporary file from a live
3698          capture, so it doesn't need to stay around under that name;
3699          first, try renaming the capture buffer file to the new name. */
3700 #ifndef _WIN32
3701       if (ws_rename(cf->filename, fname) == 0) {
3702         /* That succeeded - there's no need to copy the source file. */
3703         from_filename = NULL;
3704         do_copy = FALSE;
3705       } else {
3706         if (errno == EXDEV) {
3707           /* They're on different file systems, so we have to copy the
3708              file. */
3709           do_copy = TRUE;
3710           from_filename = cf->filename;
3711         } else {
3712           /* The rename failed, but not because they're on different
3713              file systems - put up an error message.  (Or should we
3714              just punt and try to copy?  The only reason why I'd
3715              expect the rename to fail and the copy to succeed would
3716              be if we didn't have permission to remove the file from
3717              the temporary directory, and that might be fixable - but
3718              is it worth requiring the user to go off and fix it?) */
3719           simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3720                                 file_rename_error_message(errno), fname);
3721           goto fail;
3722         }
3723       }
3724 #else
3725       do_copy = TRUE;
3726       from_filename = cf->filename;
3727 #endif
3728     } else {
3729       /* It's a permanent file, so we should copy it, and not remove the
3730          original. */
3731       do_copy = TRUE;
3732       from_filename = cf->filename;
3733     }
3734
3735     if (do_copy) {
3736       /* Copy the file, if we haven't moved it. */
3737       if (!copy_file_binary_mode(from_filename, fname))
3738         goto fail;
3739     }
3740   } else {
3741     /* Either we're filtering packets, or we're saving in a different
3742        format; we can't do that by copying or moving the capture file,
3743        we have to do it by writing the packets out in Wiretap. */
3744     pdh = wtap_dump_open(fname, save_format, cf->lnk_t, cf->snap,
3745                 compressed, &err);
3746     if (pdh == NULL) {
3747       cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
3748       goto fail;
3749     }
3750
3751     /* XXX - we let the user save a subset of the packets.
3752
3753        If we do that, should we make that file the current file?  If so,
3754        it means we can no longer get at the other packets.  What does
3755        NetMon do? */
3756
3757     /* Iterate through the list of packets, processing the packets we were
3758        told to process.
3759
3760        XXX - we've already called "packet_range_process_init(range)", but
3761        "process_specified_packets()" will do it again.  Fortunately,
3762        that's harmless in this case, as we haven't done anything to
3763        "range" since we initialized it. */
3764     callback_args.pdh = pdh;
3765     callback_args.fname = fname;
3766     switch (process_specified_packets(cf, range, "Saving", "selected packets",
3767                                       TRUE, save_packet, &callback_args)) {
3768
3769     case PSP_FINISHED:
3770       /* Completed successfully. */
3771       break;
3772
3773     case PSP_STOPPED:
3774       /* The user decided to abort the saving.
3775          XXX - remove the output file? */
3776       break;
3777
3778     case PSP_FAILED:
3779       /* Error while saving. */
3780       wtap_dump_close(pdh, &err);
3781       goto fail;
3782     }
3783
3784     if (!wtap_dump_close(pdh, &err)) {
3785       cf_close_failure_alert_box(fname, err);
3786       goto fail;
3787     }
3788   }
3789
3790   cf_callback_invoke(cf_cb_file_safe_finished, NULL);
3791
3792   if (packet_range_process_all(range)) {
3793     /* We saved the entire capture, not just some packets from it.
3794        Open and read the file we saved it to.
3795
3796        XXX - this is somewhat of a waste; we already have the
3797        packets, all this gets us is updated file type information
3798        (which we could just stuff into "cf"), and having the new
3799        file be the one we have opened and from which we're reading
3800        the data, and it means we have to spend time opening and
3801        reading the file, which could be a significant amount of
3802        time if the file is large. */
3803     cf->user_saved = TRUE;
3804
3805     if ((cf_open(cf, fname, FALSE, &err)) == CF_OK) {
3806       /* XXX - report errors if this fails?
3807          What should we return if it fails or is aborted? */
3808       switch (cf_read(cf)) {
3809
3810       case CF_READ_OK:
3811       case CF_READ_ERROR:
3812         /* Just because we got an error, that doesn't mean we were unable
3813            to read any of the file; we handle what we could get from the
3814            file. */
3815         break;
3816
3817       case CF_READ_ABORTED:
3818         /* The user bailed out of re-reading the capture file; the
3819            capture file has been closed - just return (without
3820            changing any menu settings; "cf_close()" set them
3821            correctly for the "no capture file open" state). */
3822         break;
3823       }
3824       cf_callback_invoke(cf_cb_file_safe_reload_finished, NULL);
3825     }
3826   }
3827   return CF_OK;
3828
3829 fail:
3830   cf_callback_invoke(cf_cb_file_safe_failed, NULL);
3831   return CF_ERROR;
3832 }
3833
3834 static void
3835 cf_open_failure_alert_box(const char *filename, int err, gchar *err_info,
3836                           gboolean for_writing, int file_type)
3837 {
3838   if (err < 0) {
3839     /* Wiretap error. */
3840     switch (err) {
3841
3842     case WTAP_ERR_NOT_REGULAR_FILE:
3843       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3844                     "The file \"%s\" is a \"special file\" or socket or other non-regular file.",
3845                     filename);
3846       break;
3847
3848     case WTAP_ERR_RANDOM_OPEN_PIPE:
3849       /* Seen only when opening a capture file for reading. */
3850       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3851                     "The file \"%s\" is a pipe or FIFO; Wireshark can't read pipe or FIFO files.",
3852                     filename);
3853       break;
3854
3855     case WTAP_ERR_FILE_UNKNOWN_FORMAT:
3856       /* Seen only when opening a capture file for reading. */
3857       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3858                     "The file \"%s\" isn't a capture file in a format Wireshark understands.",
3859                     filename);
3860       break;
3861
3862     case WTAP_ERR_UNSUPPORTED:
3863       /* Seen only when opening a capture file for reading. */
3864       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3865                     "The file \"%s\" isn't a capture file in a format Wireshark understands.\n"
3866                     "(%s)",
3867                     filename, err_info);
3868       g_free(err_info);
3869       break;
3870
3871     case WTAP_ERR_CANT_WRITE_TO_PIPE:
3872       /* Seen only when opening a capture file for writing. */
3873       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3874                     "The file \"%s\" is a pipe, and %s capture files can't be "
3875                     "written to a pipe.",
3876                     filename, wtap_file_type_string(file_type));
3877       break;
3878
3879     case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
3880       /* Seen only when opening a capture file for writing. */
3881       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3882                     "Wireshark doesn't support writing capture files in that format.");
3883       break;
3884
3885     case WTAP_ERR_UNSUPPORTED_ENCAP:
3886       if (for_writing) {
3887         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3888                       "Wireshark can't save this capture in that format.");
3889       } else {
3890         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3891                       "The file \"%s\" is a capture for a network type that Wireshark doesn't support.\n"
3892                       "(%s)",
3893                       filename, err_info);
3894         g_free(err_info);
3895       }
3896       break;
3897
3898     case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
3899       if (for_writing) {
3900         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3901                       "Wireshark can't save this capture in that format.");
3902       } else {
3903         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3904                       "The file \"%s\" is a capture for a network type that Wireshark doesn't support.",
3905                       filename);
3906       }
3907       break;
3908
3909     case WTAP_ERR_BAD_RECORD:
3910       /* Seen only when opening a capture file for reading. */
3911       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3912                     "The file \"%s\" appears to be damaged or corrupt.\n"
3913                     "(%s)",
3914                     filename, err_info);
3915       g_free(err_info);
3916       break;
3917
3918     case WTAP_ERR_CANT_OPEN:
3919       if (for_writing) {
3920         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3921                       "The file \"%s\" could not be created for some unknown reason.",
3922                       filename);
3923       } else {
3924         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3925                       "The file \"%s\" could not be opened for some unknown reason.",
3926                       filename);
3927       }
3928       break;
3929
3930     case WTAP_ERR_SHORT_READ:
3931       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3932                     "The file \"%s\" appears to have been cut short"
3933                     " in the middle of a packet or other data.",
3934                     filename);
3935       break;
3936
3937     case WTAP_ERR_SHORT_WRITE:
3938       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3939                     "A full header couldn't be written to the file \"%s\".",
3940                     filename);
3941       break;
3942
3943     case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
3944       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3945                     "Gzip compression not supported by this file type.");
3946       break;
3947
3948     default:
3949       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3950                     "The file \"%s\" could not be %s: %s.",
3951                     filename,
3952                     for_writing ? "created" : "opened",
3953                     wtap_strerror(err));
3954       break;
3955     }
3956   } else {
3957     /* OS error. */
3958     open_failure_alert_box(filename, err, for_writing);
3959   }
3960 }
3961
3962 static const char *
3963 file_rename_error_message(int err)
3964 {
3965   const char *errmsg;
3966   static char errmsg_errno[1024+1];
3967
3968   switch (err) {
3969
3970   case ENOENT:
3971     errmsg = "The path to the file \"%s\" doesn't exist.";
3972     break;
3973
3974   case EACCES:
3975     errmsg = "You don't have permission to move the capture file to \"%s\".";
3976     break;
3977
3978   default:
3979     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
3980                     "The file \"%%s\" could not be moved: %s.",
3981                                 wtap_strerror(err));
3982     errmsg = errmsg_errno;
3983     break;
3984   }
3985   return errmsg;
3986 }
3987
3988 char *
3989 cf_read_error_message(int err, gchar *err_info)
3990 {
3991   static char errmsg_errno[1024+1];
3992
3993   switch (err) {
3994
3995   case WTAP_ERR_UNSUPPORTED_ENCAP:
3996     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
3997                "The file \"%%s\" has a packet with a network type that Wireshark doesn't support.\n(%s)",
3998                err_info);
3999     g_free(err_info);
4000     break;
4001
4002   case WTAP_ERR_BAD_RECORD:
4003     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
4004              "An error occurred while reading from the file \"%%s\": %s.\n(%s)",
4005              wtap_strerror(err), err_info);
4006     g_free(err_info);
4007     break;
4008
4009   default:
4010     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
4011              "An error occurred while reading from the file \"%%s\": %s.",
4012              wtap_strerror(err));
4013     break;
4014   }
4015   return errmsg_errno;
4016 }
4017
4018 static void
4019 cf_write_failure_alert_box(const char *filename, int err)
4020 {
4021   if (err < 0) {
4022     /* Wiretap error. */
4023     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4024                   "An error occurred while writing to the file \"%s\": %s.",
4025                   filename, wtap_strerror(err));
4026   } else {
4027     /* OS error. */
4028     write_failure_alert_box(filename, err);
4029   }
4030 }
4031
4032 /* Check for write errors - if the file is being written to an NFS server,
4033    a write error may not show up until the file is closed, as NFS clients
4034    might not send writes to the server until the "write()" call finishes,
4035    so that the write may fail on the server but the "write()" may succeed. */
4036 static void
4037 cf_close_failure_alert_box(const char *filename, int err)
4038 {
4039   if (err < 0) {
4040     /* Wiretap error. */
4041     switch (err) {
4042
4043     case WTAP_ERR_CANT_CLOSE:
4044       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4045                     "The file \"%s\" couldn't be closed for some unknown reason.",
4046                     filename);
4047       break;
4048
4049     case WTAP_ERR_SHORT_WRITE:
4050       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4051                     "Not all the packets could be written to the file \"%s\".",
4052                     filename);
4053       break;
4054
4055     default:
4056       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4057                     "An error occurred while closing the file \"%s\": %s.",
4058                     filename, wtap_strerror(err));
4059       break;
4060     }
4061   } else {
4062     /* OS error.
4063        We assume that a close error from the OS is really a write error. */
4064     write_failure_alert_box(filename, err);
4065   }
4066 }
4067
4068 /* Reload the current capture file. */
4069 void
4070 cf_reload(capture_file *cf) {
4071   gchar *filename;
4072   gboolean is_tempfile;
4073   int err;
4074
4075   /* If the file could be opened, "cf_open()" calls "cf_close()"
4076      to get rid of state for the old capture file before filling in state
4077      for the new capture file.  "cf_close()" will remove the file if
4078      it's a temporary file; we don't want that to happen (for one thing,
4079      it'd prevent subsequent reopens from working).  Remember whether it's
4080      a temporary file, mark it as not being a temporary file, and then
4081      reopen it as the type of file it was.
4082
4083      Also, "cf_close()" will free "cf->filename", so we must make
4084      a copy of it first. */
4085   filename = g_strdup(cf->filename);
4086   is_tempfile = cf->is_tempfile;
4087   cf->is_tempfile = FALSE;
4088   if (cf_open(cf, filename, is_tempfile, &err) == CF_OK) {
4089     switch (cf_read(cf)) {
4090
4091     case CF_READ_OK:
4092     case CF_READ_ERROR:
4093       /* Just because we got an error, that doesn't mean we were unable
4094          to read any of the file; we handle what we could get from the
4095          file. */
4096       break;
4097
4098     case CF_READ_ABORTED:
4099       /* The user bailed out of re-reading the capture file; the
4100          capture file has been closed - just free the capture file name
4101          string and return (without changing the last containing
4102          directory). */
4103       g_free(filename);
4104       return;
4105     }
4106   } else {
4107     /* The open failed, so "cf->is_tempfile" wasn't set to "is_tempfile".
4108        Instead, the file was left open, so we should restore "cf->is_tempfile"
4109        ourselves.
4110
4111        XXX - change the menu?  Presumably "cf_open()" will do that;
4112        make sure it does! */
4113     cf->is_tempfile = is_tempfile;
4114   }
4115   /* "cf_open()" made a copy of the file name we handed it, so
4116      we should free up our copy. */
4117   g_free(filename);
4118 }