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