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