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