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