I don't understand how this variable might be clobbered, but mark it volatile to...
[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, 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     /* Print the full packet data as hex. */
2479     if (!print_hex_data(args->print_args->stream, &edt))
2480       goto fail;
2481
2482     /* Print a blank line if we print anything after this (aka more than one packet). */
2483     args->print_separator = TRUE;
2484
2485     /* Print a header line if we print any more packet summaries */
2486     args->print_header_line = TRUE;
2487   } /* if (args->print_args->print_dissections != print_dissections_none) */
2488
2489   epan_dissect_cleanup(&edt);
2490
2491   /* do we want to have a formfeed between each packet from now on? */
2492   if (args->print_args->print_formfeed) {
2493     args->print_formfeed = TRUE;
2494   }
2495
2496   return TRUE;
2497
2498 fail:
2499   epan_dissect_cleanup(&edt);
2500   return FALSE;
2501 }
2502
2503 cf_print_status_t
2504 cf_print_packets(capture_file *cf, print_args_t *print_args)
2505 {
2506   print_callback_args_t callback_args;
2507   gint          data_width;
2508   char         *cp;
2509   int           i, cp_off, column_len, line_len;
2510   int           num_visible_col = 0, last_visible_col = 0, visible_col_count;
2511   psp_return_t  ret;
2512   GList        *clp;
2513   fmt_data     *cfmt;
2514
2515   callback_args.print_args = print_args;
2516   callback_args.print_header_line = TRUE;
2517   callback_args.header_line_buf = NULL;
2518   callback_args.header_line_buf_len = 256;
2519   callback_args.print_formfeed = FALSE;
2520   callback_args.print_separator = FALSE;
2521   callback_args.line_buf = NULL;
2522   callback_args.line_buf_len = 256;
2523   callback_args.col_widths = NULL;
2524   callback_args.num_visible_cols = 0;
2525   callback_args.visible_cols = NULL;
2526
2527   if (!print_preamble(print_args->stream, cf->filename)) {
2528     destroy_print_stream(print_args->stream);
2529     return CF_PRINT_WRITE_ERROR;
2530   }
2531
2532   if (print_args->print_summary) {
2533     /* We're printing packet summaries.  Allocate the header line buffer
2534        and get the column widths. */
2535     callback_args.header_line_buf = g_malloc(callback_args.header_line_buf_len + 1);
2536
2537     /* Find the number of visible columns and the last visible column */
2538     for (i = 0; i < prefs.num_cols; i++) {
2539
2540         clp = g_list_nth(prefs.col_list, i);
2541         if (clp == NULL) /* Sanity check, Invalid column requested */
2542             continue;
2543
2544         cfmt = (fmt_data *) clp->data;
2545         if (cfmt->visible) {
2546             num_visible_col++;
2547             last_visible_col = i;
2548         }
2549     }
2550
2551     /* Find the widths for each of the columns - maximum of the
2552        width of the title and the width of the data - and construct
2553        a buffer with a line containing the column titles. */
2554     callback_args.num_visible_cols = num_visible_col;
2555     callback_args.col_widths = (gint *) g_malloc(sizeof(gint) * num_visible_col);
2556     callback_args.visible_cols = (gint *) g_malloc(sizeof(gint) * num_visible_col);
2557     cp = &callback_args.header_line_buf[0];
2558     line_len = 0;
2559     visible_col_count = 0;
2560     for (i = 0; i < cf->cinfo.num_cols; i++) {
2561
2562       clp = g_list_nth(prefs.col_list, i);
2563       if (clp == NULL) /* Sanity check, Invalid column requested */
2564           continue;
2565
2566       cfmt = (fmt_data *) clp->data;
2567       if (cfmt->visible == FALSE)
2568           continue;
2569
2570       /* Save the order of visible columns */
2571       callback_args.visible_cols[visible_col_count] = i;
2572
2573       /* Don't pad the last column. */
2574       if (i == last_visible_col)
2575         callback_args.col_widths[visible_col_count] = 0;
2576       else {
2577         callback_args.col_widths[visible_col_count] = (gint) strlen(cf->cinfo.col_title[i]);
2578         data_width = get_column_char_width(get_column_format(i));
2579         if (data_width > callback_args.col_widths[visible_col_count])
2580           callback_args.col_widths[visible_col_count] = data_width;
2581       }
2582
2583       /* Find the length of the string for this column. */
2584       column_len = (int) strlen(cf->cinfo.col_title[i]);
2585       if (callback_args.col_widths[i] > column_len)
2586         column_len = callback_args.col_widths[visible_col_count];
2587
2588       /* Make sure there's room in the line buffer for the column; if not,
2589          double its length. */
2590       line_len += column_len + 1;   /* "+1" for space */
2591       if (line_len > callback_args.header_line_buf_len) {
2592         cp_off = (int) (cp - callback_args.header_line_buf);
2593         callback_args.header_line_buf_len = 2 * line_len;
2594         callback_args.header_line_buf = g_realloc(callback_args.header_line_buf,
2595                                                   callback_args.header_line_buf_len + 1);
2596         cp = callback_args.header_line_buf + cp_off;
2597       }
2598
2599       /* Right-justify the packet number column. */
2600 /*      if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2601         g_snprintf(cp, column_len+1, "%*s", callback_args.col_widths[visible_col_count], cf->cinfo.col_title[i]);
2602       else*/
2603       g_snprintf(cp, column_len+1, "%-*s", callback_args.col_widths[visible_col_count], cf->cinfo.col_title[i]);
2604       cp += column_len;
2605       if (i != cf->cinfo.num_cols - 1)
2606         *cp++ = ' ';
2607
2608       visible_col_count++;
2609     }
2610     *cp = '\0';
2611
2612     /* Now start out the main line buffer with the same length as the
2613        header line buffer. */
2614     callback_args.line_buf_len = callback_args.header_line_buf_len;
2615     callback_args.line_buf = g_malloc(callback_args.line_buf_len + 1);
2616   } /* if (print_summary) */
2617
2618   /* Iterate through the list of packets, printing the packets we were
2619      told to print. */
2620   ret = process_specified_packets(cf, &print_args->range, "Printing",
2621                                   "selected packets", TRUE, print_packet,
2622                                   &callback_args);
2623
2624   g_free(callback_args.header_line_buf);
2625   g_free(callback_args.line_buf);
2626   g_free(callback_args.col_widths);
2627   g_free(callback_args.visible_cols);
2628
2629   switch (ret) {
2630
2631   case PSP_FINISHED:
2632     /* Completed successfully. */
2633     break;
2634
2635   case PSP_STOPPED:
2636     /* Well, the user decided to abort the printing.
2637
2638        XXX - note that what got generated before they did that
2639        will get printed if we're piping to a print program; we'd
2640        have to write to a file and then hand that to the print
2641        program to make it actually not print anything. */
2642     break;
2643
2644   case PSP_FAILED:
2645     /* Error while printing.
2646
2647        XXX - note that what got generated before they did that
2648        will get printed if we're piping to a print program; we'd
2649        have to write to a file and then hand that to the print
2650        program to make it actually not print anything. */
2651     destroy_print_stream(print_args->stream);
2652     return CF_PRINT_WRITE_ERROR;
2653   }
2654
2655   if (!print_finale(print_args->stream)) {
2656     destroy_print_stream(print_args->stream);
2657     return CF_PRINT_WRITE_ERROR;
2658   }
2659
2660   if (!destroy_print_stream(print_args->stream))
2661     return CF_PRINT_WRITE_ERROR;
2662
2663   return CF_PRINT_OK;
2664 }
2665
2666 static gboolean
2667 write_pdml_packet(capture_file *cf _U_, frame_data *fdata,
2668                   struct wtap_pkthdr *phdr, const guint8 *pd,
2669           void *argsp)
2670 {
2671   FILE           *fh = argsp;
2672   epan_dissect_t  edt;
2673
2674   /* Create the protocol tree, but don't fill in the column information. */
2675   epan_dissect_init(&edt, TRUE, TRUE);
2676   epan_dissect_run(&edt, phdr, pd, fdata, NULL);
2677
2678   /* Write out the information in that tree. */
2679   proto_tree_write_pdml(&edt, fh);
2680
2681   epan_dissect_cleanup(&edt);
2682
2683   return !ferror(fh);
2684 }
2685
2686 cf_print_status_t
2687 cf_write_pdml_packets(capture_file *cf, print_args_t *print_args)
2688 {
2689   FILE         *fh;
2690   psp_return_t  ret;
2691
2692   fh = ws_fopen(print_args->file, "w");
2693   if (fh == NULL)
2694     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2695
2696   write_pdml_preamble(fh, cf->filename);
2697   if (ferror(fh)) {
2698     fclose(fh);
2699     return CF_PRINT_WRITE_ERROR;
2700   }
2701
2702   /* Iterate through the list of packets, printing the packets we were
2703      told to print. */
2704   ret = process_specified_packets(cf, &print_args->range, "Writing PDML",
2705                                   "selected packets", TRUE,
2706                                   write_pdml_packet, fh);
2707
2708   switch (ret) {
2709
2710   case PSP_FINISHED:
2711     /* Completed successfully. */
2712     break;
2713
2714   case PSP_STOPPED:
2715     /* Well, the user decided to abort the printing. */
2716     break;
2717
2718   case PSP_FAILED:
2719     /* Error while printing. */
2720     fclose(fh);
2721     return CF_PRINT_WRITE_ERROR;
2722   }
2723
2724   write_pdml_finale(fh);
2725   if (ferror(fh)) {
2726     fclose(fh);
2727     return CF_PRINT_WRITE_ERROR;
2728   }
2729
2730   /* XXX - check for an error */
2731   fclose(fh);
2732
2733   return CF_PRINT_OK;
2734 }
2735
2736 static gboolean
2737 write_psml_packet(capture_file *cf, frame_data *fdata,
2738                   struct wtap_pkthdr *phdr, const guint8 *pd,
2739           void *argsp)
2740 {
2741   FILE           *fh = argsp;
2742   epan_dissect_t  edt;
2743   gboolean        proto_tree_needed;
2744
2745   /* Fill in the column information, only create the protocol tree
2746      if having custom columns. */
2747   proto_tree_needed = have_custom_cols(&cf->cinfo);
2748   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2749   col_custom_prime_edt(&edt, &cf->cinfo);
2750   epan_dissect_run(&edt, phdr, pd, fdata, &cf->cinfo);
2751   epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
2752
2753   /* Write out the information in that tree. */
2754   proto_tree_write_psml(&edt, fh);
2755
2756   epan_dissect_cleanup(&edt);
2757
2758   return !ferror(fh);
2759 }
2760
2761 cf_print_status_t
2762 cf_write_psml_packets(capture_file *cf, print_args_t *print_args)
2763 {
2764   FILE         *fh;
2765   psp_return_t  ret;
2766
2767   fh = ws_fopen(print_args->file, "w");
2768   if (fh == NULL)
2769     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2770
2771   write_psml_preamble(fh);
2772   if (ferror(fh)) {
2773     fclose(fh);
2774     return CF_PRINT_WRITE_ERROR;
2775   }
2776
2777   /* Iterate through the list of packets, printing the packets we were
2778      told to print. */
2779   ret = process_specified_packets(cf, &print_args->range, "Writing PSML",
2780                                   "selected packets", TRUE,
2781                                   write_psml_packet, fh);
2782
2783   switch (ret) {
2784
2785   case PSP_FINISHED:
2786     /* Completed successfully. */
2787     break;
2788
2789   case PSP_STOPPED:
2790     /* Well, the user decided to abort the printing. */
2791     break;
2792
2793   case PSP_FAILED:
2794     /* Error while printing. */
2795     fclose(fh);
2796     return CF_PRINT_WRITE_ERROR;
2797   }
2798
2799   write_psml_finale(fh);
2800   if (ferror(fh)) {
2801     fclose(fh);
2802     return CF_PRINT_WRITE_ERROR;
2803   }
2804
2805   /* XXX - check for an error */
2806   fclose(fh);
2807
2808   return CF_PRINT_OK;
2809 }
2810
2811 static gboolean
2812 write_csv_packet(capture_file *cf, frame_data *fdata,
2813                  struct wtap_pkthdr *phdr, const guint8 *pd,
2814                  void *argsp)
2815 {
2816   FILE           *fh = argsp;
2817   epan_dissect_t  edt;
2818   gboolean        proto_tree_needed;
2819
2820   /* Fill in the column information, only create the protocol tree
2821      if having custom columns. */
2822   proto_tree_needed = have_custom_cols(&cf->cinfo);
2823   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2824   col_custom_prime_edt(&edt, &cf->cinfo);
2825   epan_dissect_run(&edt, phdr, pd, fdata, &cf->cinfo);
2826   epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
2827
2828   /* Write out the information in that tree. */
2829   proto_tree_write_csv(&edt, fh);
2830
2831   epan_dissect_cleanup(&edt);
2832
2833   return !ferror(fh);
2834 }
2835
2836 cf_print_status_t
2837 cf_write_csv_packets(capture_file *cf, print_args_t *print_args)
2838 {
2839   FILE         *fh;
2840   psp_return_t  ret;
2841
2842   fh = ws_fopen(print_args->file, "w");
2843   if (fh == NULL)
2844     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2845
2846   write_csv_preamble(fh);
2847   if (ferror(fh)) {
2848     fclose(fh);
2849     return CF_PRINT_WRITE_ERROR;
2850   }
2851
2852   /* Iterate through the list of packets, printing the packets we were
2853      told to print. */
2854   ret = process_specified_packets(cf, &print_args->range, "Writing CSV",
2855                                   "selected packets", TRUE,
2856                                   write_csv_packet, fh);
2857
2858   switch (ret) {
2859
2860   case PSP_FINISHED:
2861     /* Completed successfully. */
2862     break;
2863
2864   case PSP_STOPPED:
2865     /* Well, the user decided to abort the printing. */
2866     break;
2867
2868   case PSP_FAILED:
2869     /* Error while printing. */
2870     fclose(fh);
2871     return CF_PRINT_WRITE_ERROR;
2872   }
2873
2874   write_csv_finale(fh);
2875   if (ferror(fh)) {
2876     fclose(fh);
2877     return CF_PRINT_WRITE_ERROR;
2878   }
2879
2880   /* XXX - check for an error */
2881   fclose(fh);
2882
2883   return CF_PRINT_OK;
2884 }
2885
2886 static gboolean
2887 write_carrays_packet(capture_file *cf _U_, frame_data *fdata,
2888              struct wtap_pkthdr *phdr,
2889              const guint8 *pd, void *argsp)
2890 {
2891   FILE           *fh = argsp;
2892   epan_dissect_t  edt;
2893
2894   epan_dissect_init(&edt, TRUE, TRUE);
2895   epan_dissect_run(&edt, phdr, pd, fdata, NULL);
2896   proto_tree_write_carrays(fdata->num, fh, &edt);
2897   epan_dissect_cleanup(&edt);
2898
2899   return !ferror(fh);
2900 }
2901
2902 cf_print_status_t
2903 cf_write_carrays_packets(capture_file *cf, print_args_t *print_args)
2904 {
2905   FILE         *fh;
2906   psp_return_t  ret;
2907
2908   fh = ws_fopen(print_args->file, "w");
2909
2910   if (fh == NULL)
2911     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2912
2913   write_carrays_preamble(fh);
2914
2915   if (ferror(fh)) {
2916     fclose(fh);
2917     return CF_PRINT_WRITE_ERROR;
2918   }
2919
2920   /* Iterate through the list of packets, printing the packets we were
2921      told to print. */
2922   ret = process_specified_packets(cf, &print_args->range,
2923                   "Writing C Arrays",
2924                   "selected packets", TRUE,
2925                                   write_carrays_packet, fh);
2926   switch (ret) {
2927   case PSP_FINISHED:
2928     /* Completed successfully. */
2929     break;
2930   case PSP_STOPPED:
2931     /* Well, the user decided to abort the printing. */
2932     break;
2933   case PSP_FAILED:
2934     /* Error while printing. */
2935     fclose(fh);
2936     return CF_PRINT_WRITE_ERROR;
2937   }
2938
2939   write_carrays_finale(fh);
2940
2941   if (ferror(fh)) {
2942     fclose(fh);
2943     return CF_PRINT_WRITE_ERROR;
2944   }
2945
2946   fclose(fh);
2947   return CF_PRINT_OK;
2948 }
2949
2950 gboolean
2951 cf_find_packet_protocol_tree(capture_file *cf, const char *string,
2952                              search_direction dir)
2953 {
2954   match_data mdata;
2955
2956   mdata.string = string;
2957   mdata.string_len = strlen(string);
2958   return find_packet(cf, match_protocol_tree, &mdata, dir);
2959 }
2960
2961 gboolean
2962 cf_find_string_protocol_tree(capture_file *cf, proto_tree *tree,  match_data *mdata)
2963 {
2964   mdata->frame_matched = FALSE;
2965   mdata->string = convert_string_case(cf->sfilter, cf->case_type);
2966   mdata->string_len = strlen(mdata->string);
2967   mdata->cf = cf;
2968   /* Iterate through all the nodes looking for matching text */
2969   proto_tree_children_foreach(tree, match_subtree_text, mdata);
2970   return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
2971 }
2972
2973 static match_result
2974 match_protocol_tree(capture_file *cf, frame_data *fdata, void *criterion)
2975 {
2976   match_data     *mdata = criterion;
2977   epan_dissect_t  edt;
2978
2979   /* Load the frame's data. */
2980   if (!cf_read_frame(cf, fdata)) {
2981     /* Attempt to get the packet failed. */
2982     return MR_ERROR;
2983   }
2984
2985   /* Construct the protocol tree, including the displayed text */
2986   epan_dissect_init(&edt, TRUE, TRUE);
2987   /* We don't need the column information */
2988   epan_dissect_run(&edt, &cf->phdr, cf->pd, fdata, NULL);
2989
2990   /* Iterate through all the nodes, seeing if they have text that matches. */
2991   mdata->cf = cf;
2992   mdata->frame_matched = FALSE;
2993   proto_tree_children_foreach(edt.tree, match_subtree_text, mdata);
2994   epan_dissect_cleanup(&edt);
2995   return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
2996 }
2997
2998 static void
2999 match_subtree_text(proto_node *node, gpointer data)
3000 {
3001   match_data   *mdata      = (match_data *) data;
3002   const gchar  *string     = mdata->string;
3003   size_t        string_len = mdata->string_len;
3004   capture_file *cf         = mdata->cf;
3005   field_info   *fi         = PNODE_FINFO(node);
3006   gchar         label_str[ITEM_LABEL_LENGTH];
3007   gchar        *label_ptr;
3008   size_t        label_len;
3009   guint32       i;
3010   guint8        c_char;
3011   size_t        c_match    = 0;
3012
3013   /* dissection with an invisible proto tree? */
3014   g_assert(fi);
3015
3016   if (mdata->frame_matched) {
3017     /* We already had a match; don't bother doing any more work. */
3018     return;
3019   }
3020
3021   /* Don't match invisible entries. */
3022   if (PROTO_ITEM_IS_HIDDEN(node))
3023     return;
3024
3025   /* was a free format label produced? */
3026   if (fi->rep) {
3027     label_ptr = fi->rep->representation;
3028   } else {
3029     /* no, make a generic label */
3030     label_ptr = label_str;
3031     proto_item_fill_label(fi, label_str);
3032   }
3033
3034   /* Does that label match? */
3035   label_len = strlen(label_ptr);
3036   for (i = 0; i < label_len; i++) {
3037     c_char = label_ptr[i];
3038     if (cf->case_type)
3039       c_char = toupper(c_char);
3040     if (c_char == string[c_match]) {
3041       c_match++;
3042       if (c_match == string_len) {
3043         /* No need to look further; we have a match */
3044         mdata->frame_matched = TRUE;
3045         mdata->finfo = fi;
3046         return;
3047       }
3048     } else
3049       c_match = 0;
3050   }
3051
3052   /* Recurse into the subtree, if it exists */
3053   if (node->first_child != NULL)
3054     proto_tree_children_foreach(node, match_subtree_text, mdata);
3055 }
3056
3057 gboolean
3058 cf_find_packet_summary_line(capture_file *cf, const char *string,
3059                             search_direction dir)
3060 {
3061   match_data mdata;
3062
3063   mdata.string = string;
3064   mdata.string_len = strlen(string);
3065   return find_packet(cf, match_summary_line, &mdata, dir);
3066 }
3067
3068 static match_result
3069 match_summary_line(capture_file *cf, frame_data *fdata, void *criterion)
3070 {
3071   match_data     *mdata      = criterion;
3072   const gchar    *string     = mdata->string;
3073   size_t          string_len = mdata->string_len;
3074   epan_dissect_t  edt;
3075   const char     *info_column;
3076   size_t          info_column_len;
3077   match_result    result     = MR_NOTMATCHED;
3078   gint            colx;
3079   guint32         i;
3080   guint8          c_char;
3081   size_t          c_match    = 0;
3082
3083   /* Load the frame's data. */
3084   if (!cf_read_frame(cf, fdata)) {
3085     /* Attempt to get the packet failed. */
3086     return MR_ERROR;
3087   }
3088
3089   /* Don't bother constructing the protocol tree */
3090   epan_dissect_init(&edt, FALSE, FALSE);
3091   /* Get the column information */
3092   epan_dissect_run(&edt, &cf->phdr, cf->pd, fdata, &cf->cinfo);
3093
3094   /* Find the Info column */
3095   for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
3096     if (cf->cinfo.fmt_matx[colx][COL_INFO]) {
3097       /* Found it.  See if we match. */
3098       info_column = edt.pi.cinfo->col_data[colx];
3099       info_column_len = strlen(info_column);
3100       for (i = 0; i < info_column_len; i++) {
3101         c_char = info_column[i];
3102         if (cf->case_type)
3103           c_char = toupper(c_char);
3104         if (c_char == string[c_match]) {
3105           c_match++;
3106           if (c_match == string_len) {
3107             result = MR_MATCHED;
3108             break;
3109           }
3110         } else
3111           c_match = 0;
3112       }
3113       break;
3114     }
3115   }
3116   epan_dissect_cleanup(&edt);
3117   return result;
3118 }
3119
3120 typedef struct {
3121     const guint8 *data;
3122     size_t        data_len;
3123 } cbs_t;    /* "Counted byte string" */
3124
3125 gboolean
3126 cf_find_packet_data(capture_file *cf, const guint8 *string, size_t string_size,
3127                     search_direction dir)
3128 {
3129   cbs_t info;
3130
3131   info.data = string;
3132   info.data_len = string_size;
3133
3134   /* String or hex search? */
3135   if (cf->string) {
3136     /* String search - what type of string? */
3137     switch (cf->scs_type) {
3138
3139     case SCS_ASCII_AND_UNICODE:
3140       return find_packet(cf, match_ascii_and_unicode, &info, dir);
3141
3142     case SCS_ASCII:
3143       return find_packet(cf, match_ascii, &info, dir);
3144
3145     case SCS_UNICODE:
3146       return find_packet(cf, match_unicode, &info, dir);
3147
3148     default:
3149       g_assert_not_reached();
3150       return FALSE;
3151     }
3152   } else
3153     return find_packet(cf, match_binary, &info, dir);
3154 }
3155
3156 static match_result
3157 match_ascii_and_unicode(capture_file *cf, frame_data *fdata, void *criterion)
3158 {
3159   cbs_t        *info       = criterion;
3160   const guint8 *ascii_text = info->data;
3161   size_t        textlen    = info->data_len;
3162   match_result  result;
3163   guint32       buf_len;
3164   guint32       i;
3165   guint8        c_char;
3166   size_t        c_match    = 0;
3167
3168   /* Load the frame's data. */
3169   if (!cf_read_frame(cf, fdata)) {
3170     /* Attempt to get the packet failed. */
3171     return MR_ERROR;
3172   }
3173
3174   result = MR_NOTMATCHED;
3175   buf_len = fdata->cap_len;
3176   i = 0;
3177   while (i < buf_len) {
3178     c_char = cf->pd[i];
3179     if (cf->case_type)
3180       c_char = toupper(c_char);
3181     if (c_char != '\0') {
3182       if (c_char == ascii_text[c_match]) {
3183         c_match += 1;
3184         if (c_match == textlen) {
3185           result = MR_MATCHED;
3186           cf->search_pos = i; /* Save the position of the last character
3187                                  for highlighting the field. */
3188           break;
3189         }
3190       }
3191       else {
3192         g_assert(i>=c_match);
3193         i -= (guint32)c_match;
3194         c_match = 0;
3195       }
3196     }
3197     i += 1;
3198   }
3199   return result;
3200 }
3201
3202 static match_result
3203 match_ascii(capture_file *cf, frame_data *fdata, void *criterion)
3204 {
3205   cbs_t        *info       = criterion;
3206   const guint8 *ascii_text = info->data;
3207   size_t        textlen    = info->data_len;
3208   match_result  result;
3209   guint32       buf_len;
3210   guint32       i;
3211   guint8        c_char;
3212   size_t        c_match    = 0;
3213
3214   /* Load the frame's data. */
3215   if (!cf_read_frame(cf, fdata)) {
3216     /* Attempt to get the packet failed. */
3217     return MR_ERROR;
3218   }
3219
3220   result = MR_NOTMATCHED;
3221   buf_len = fdata->cap_len;
3222   i = 0;
3223   while (i < buf_len) {
3224     c_char = cf->pd[i];
3225     if (cf->case_type)
3226       c_char = toupper(c_char);
3227     if (c_char == ascii_text[c_match]) {
3228       c_match += 1;
3229       if (c_match == textlen) {
3230         result = MR_MATCHED;
3231         cf->search_pos = i; /* Save the position of the last character
3232                                for highlighting the field. */
3233         break;
3234       }
3235     }
3236     else {
3237       g_assert(i>=c_match);
3238       i -= (guint32)c_match;
3239       c_match = 0;
3240     }
3241     i += 1;
3242   }
3243
3244   return result;
3245 }
3246
3247 static match_result
3248 match_unicode(capture_file *cf, frame_data *fdata, void *criterion)
3249 {
3250   cbs_t        *info       = criterion;
3251   const guint8 *ascii_text = info->data;
3252   size_t        textlen    = info->data_len;
3253   match_result  result;
3254   guint32       buf_len;
3255   guint32       i;
3256   guint8        c_char;
3257   size_t        c_match    = 0;
3258
3259   /* Load the frame's data. */
3260   if (!cf_read_frame(cf, fdata)) {
3261     /* Attempt to get the packet failed. */
3262     return MR_ERROR;
3263   }
3264
3265   result = MR_NOTMATCHED;
3266   buf_len = fdata->cap_len;
3267   i = 0;
3268   while (i < buf_len) {
3269     c_char = cf->pd[i];
3270     if (cf->case_type)
3271       c_char = toupper(c_char);
3272     if (c_char == ascii_text[c_match]) {
3273       c_match += 1;
3274       if (c_match == textlen) {
3275         result = MR_MATCHED;
3276         cf->search_pos = i; /* Save the position of the last character
3277                                for highlighting the field. */
3278         break;
3279       }
3280       i += 1;
3281     }
3282     else {
3283       g_assert(i>=(c_match*2));
3284       i -= (guint32)c_match*2;
3285       c_match = 0;
3286     }
3287     i += 1;
3288   }
3289   return result;
3290 }
3291
3292 static match_result
3293 match_binary(capture_file *cf, frame_data *fdata, void *criterion)
3294 {
3295   cbs_t        *info        = criterion;
3296   const guint8 *binary_data = info->data;
3297   size_t        datalen     = info->data_len;
3298   match_result  result;
3299   guint32       buf_len;
3300   guint32       i;
3301   size_t        c_match     = 0;
3302
3303   /* Load the frame's data. */
3304   if (!cf_read_frame(cf, fdata)) {
3305     /* Attempt to get the packet failed. */
3306     return MR_ERROR;
3307   }
3308
3309   result = MR_NOTMATCHED;
3310   buf_len = fdata->cap_len;
3311   i = 0;
3312   while (i < buf_len) {
3313     if (cf->pd[i] == binary_data[c_match]) {
3314       c_match += 1;
3315       if (c_match == datalen) {
3316         result = MR_MATCHED;
3317         cf->search_pos = i; /* Save the position of the last character
3318                                for highlighting the field. */
3319         break;
3320       }
3321     }
3322     else {
3323       g_assert(i>=c_match);
3324       i -= (guint32)c_match;
3325       c_match = 0;
3326     }
3327     i += 1;
3328   }
3329   return result;
3330 }
3331
3332 gboolean
3333 cf_find_packet_dfilter(capture_file *cf, dfilter_t *sfcode,
3334                        search_direction dir)
3335 {
3336   return find_packet(cf, match_dfilter, sfcode, dir);
3337 }
3338
3339 gboolean
3340 cf_find_packet_dfilter_string(capture_file *cf, const char *filter,
3341                               search_direction dir)
3342 {
3343   dfilter_t *sfcode;
3344   gboolean   result;
3345
3346   if (!dfilter_compile(filter, &sfcode)) {
3347      /*
3348       * XXX - this shouldn't happen, as the filter string is machine
3349       * generated
3350       */
3351     return FALSE;
3352   }
3353   if (sfcode == NULL) {
3354     /*
3355      * XXX - this shouldn't happen, as the filter string is machine
3356      * generated.
3357      */
3358     return FALSE;
3359   }
3360   result = find_packet(cf, match_dfilter, sfcode, dir);
3361   dfilter_free(sfcode);
3362   return result;
3363 }
3364
3365 static match_result
3366 match_dfilter(capture_file *cf, frame_data *fdata, void *criterion)
3367 {
3368   dfilter_t      *sfcode = criterion;
3369   epan_dissect_t  edt;
3370   match_result    result;
3371
3372   /* Load the frame's data. */
3373   if (!cf_read_frame(cf, fdata)) {
3374     /* Attempt to get the packet failed. */
3375     return MR_ERROR;
3376   }
3377
3378   epan_dissect_init(&edt, TRUE, FALSE);
3379   epan_dissect_prime_dfilter(&edt, sfcode);
3380   epan_dissect_run(&edt, &cf->phdr, cf->pd, fdata, NULL);
3381   result = dfilter_apply_edt(sfcode, &edt) ? MR_MATCHED : MR_NOTMATCHED;
3382   epan_dissect_cleanup(&edt);
3383   return result;
3384 }
3385
3386 gboolean
3387 cf_find_packet_marked(capture_file *cf, search_direction dir)
3388 {
3389   return find_packet(cf, match_marked, NULL, dir);
3390 }
3391
3392 static match_result
3393 match_marked(capture_file *cf _U_, frame_data *fdata, void *criterion _U_)
3394 {
3395   return fdata->flags.marked ? MR_MATCHED : MR_NOTMATCHED;
3396 }
3397
3398 gboolean
3399 cf_find_packet_time_reference(capture_file *cf, search_direction dir)
3400 {
3401   return find_packet(cf, match_time_reference, NULL, dir);
3402 }
3403
3404 static match_result
3405 match_time_reference(capture_file *cf _U_, frame_data *fdata, void *criterion _U_)
3406 {
3407   return fdata->flags.ref_time ? MR_MATCHED : MR_NOTMATCHED;
3408 }
3409
3410 static gboolean
3411 find_packet(capture_file *cf,
3412             match_result (*match_function)(capture_file *, frame_data *, void *),
3413             void *criterion, search_direction dir)
3414 {
3415   frame_data  *start_fd;
3416   guint32      framenum;
3417   frame_data  *fdata;
3418   frame_data  *new_fd = NULL;
3419   progdlg_t   *progbar = NULL;
3420   gboolean     stop_flag;
3421   int          count;
3422   gboolean     found;
3423   float        progbar_val;
3424   GTimeVal     start_time;
3425   gchar        status_str[100];
3426   int          progbar_nextstep;
3427   int          progbar_quantum;
3428   const char  *title;
3429   match_result result;
3430
3431   start_fd = cf->current_frame;
3432   if (start_fd != NULL)  {
3433     /* Iterate through the list of packets, starting at the packet we've
3434        picked, calling a routine to run the filter on the packet, see if
3435        it matches, and stop if so.  */
3436     count = 0;
3437     framenum = start_fd->num;
3438
3439     /* Update the progress bar when it gets to this value. */
3440     progbar_nextstep = 0;
3441     /* When we reach the value that triggers a progress bar update,
3442        bump that value by this amount. */
3443     progbar_quantum = cf->count/N_PROGBAR_UPDATES;
3444     /* Progress so far. */
3445     progbar_val = 0.0f;
3446
3447     stop_flag = FALSE;
3448     g_get_current_time(&start_time);
3449
3450     title = cf->sfilter?cf->sfilter:"";
3451     for (;;) {
3452       /* Create the progress bar if necessary.
3453          We check on every iteration of the loop, so that it takes no
3454          longer than the standard time to create it (otherwise, for a
3455          large file, we might take considerably longer than that standard
3456          time in order to get to the next progress bar step). */
3457       if (progbar == NULL)
3458          progbar = delayed_create_progress_dlg(cf->window, "Searching", title,
3459            FALSE, &stop_flag, &start_time, progbar_val);
3460
3461       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
3462          when we update it, we have to run the GTK+ main loop to get it
3463          to repaint what's pending, and doing so may involve an "ioctl()"
3464          to see if there's any pending input from an X server, and doing
3465          that for every packet can be costly, especially on a big file. */
3466       if (count >= progbar_nextstep) {
3467         /* let's not divide by zero. I should never be started
3468          * with count == 0, so let's assert that
3469          */
3470         g_assert(cf->count > 0);
3471
3472         progbar_val = (gfloat) count / cf->count;
3473
3474         if (progbar != NULL) {
3475           g_snprintf(status_str, sizeof(status_str),
3476                      "%4u of %u packets", count, cf->count);
3477           update_progress_dlg(progbar, progbar_val, status_str);
3478         }
3479
3480         progbar_nextstep += progbar_quantum;
3481       }
3482
3483       if (stop_flag) {
3484         /* Well, the user decided to abort the search.  Go back to the
3485            frame where we started. */
3486         new_fd = start_fd;
3487         break;
3488       }
3489
3490       /* Go past the current frame. */
3491       if (dir == SD_BACKWARD) {
3492         /* Go on to the previous frame. */
3493         if (framenum == 1) {
3494           /*
3495            * XXX - other apps have a bit more of a detailed message
3496            * for this, and instead of offering "OK" and "Cancel",
3497            * they offer things such as "Continue" and "Cancel";
3498            * we need an API for popping up alert boxes with
3499            * {Verb} and "Cancel".
3500            */
3501
3502           if (prefs.gui_find_wrap)
3503           {
3504               statusbar_push_temporary_msg("Search reached the beginning. Continuing at end.");
3505               framenum = cf->count;     /* wrap around */
3506           }
3507           else
3508           {
3509               statusbar_push_temporary_msg("Search reached the beginning.");
3510               framenum = start_fd->num; /* stay on previous packet */
3511           }
3512         } else
3513           framenum--;
3514       } else {
3515         /* Go on to the next frame. */
3516         if (framenum == cf->count) {
3517           if (prefs.gui_find_wrap)
3518           {
3519               statusbar_push_temporary_msg("Search reached the end. Continuing at beginning.");
3520               framenum = 1;             /* wrap around */
3521           }
3522           else
3523           {
3524               statusbar_push_temporary_msg("Search reached the end.");
3525               framenum = start_fd->num; /* stay on previous packet */
3526           }
3527         } else
3528           framenum++;
3529       }
3530       fdata = frame_data_sequence_find(cf->frames, framenum);
3531
3532       count++;
3533
3534       /* Is this packet in the display? */
3535       if (fdata->flags.passed_dfilter) {
3536         /* Yes.  Does it match the search criterion? */
3537         result = (*match_function)(cf, fdata, criterion);
3538         if (result == MR_ERROR) {
3539           /* Error; our caller has reported the error.  Go back to the frame
3540              where we started. */
3541           new_fd = start_fd;
3542           break;
3543         } else if (result == MR_MATCHED) {
3544           /* Yes.  Go to the new frame. */
3545           new_fd = fdata;
3546           break;
3547         }
3548       }
3549
3550       if (fdata == start_fd) {
3551         /* We're back to the frame we were on originally, and that frame
3552            doesn't match the search filter.  The search failed. */
3553         break;
3554       }
3555     }
3556
3557     /* We're done scanning the packets; destroy the progress bar if it
3558        was created. */
3559     if (progbar != NULL)
3560       destroy_progress_dlg(progbar);
3561   }
3562
3563   if (new_fd != NULL) {
3564     /* Find and select */
3565     cf->search_in_progress = TRUE;
3566     found = packet_list_select_row_from_data(new_fd);
3567     cf->search_in_progress = FALSE;
3568     cf->search_pos = 0; /* Reset the position */
3569     if (!found) {
3570       /* We didn't find a row corresponding to this frame.
3571          This means that the frame isn't being displayed currently,
3572          so we can't select it. */
3573       simple_message_box(ESD_TYPE_INFO, NULL,
3574                          "The capture file is probably not fully dissected.",
3575                          "End of capture exceeded!");
3576       return FALSE;
3577     }
3578     return TRUE;    /* success */
3579   } else
3580     return FALSE;   /* failure */
3581 }
3582
3583 gboolean
3584 cf_goto_frame(capture_file *cf, guint fnumber)
3585 {
3586   frame_data *fdata;
3587
3588   fdata = frame_data_sequence_find(cf->frames, fnumber);
3589
3590   if (fdata == NULL) {
3591     /* we didn't find a packet with that packet number */
3592     statusbar_push_temporary_msg("There is no packet number %u.", fnumber);
3593     return FALSE;   /* we failed to go to that packet */
3594   }
3595   if (!fdata->flags.passed_dfilter) {
3596     /* that packet currently isn't displayed */
3597     /* XXX - add it to the set of displayed packets? */
3598     statusbar_push_temporary_msg("Packet number %u isn't displayed.", fnumber);
3599     return FALSE;   /* we failed to go to that packet */
3600   }
3601
3602   if (!packet_list_select_row_from_data(fdata)) {
3603     /* We didn't find a row corresponding to this frame.
3604        This means that the frame isn't being displayed currently,
3605        so we can't select it. */
3606     simple_message_box(ESD_TYPE_INFO, NULL,
3607                        "The capture file is probably not fully dissected.",
3608                        "End of capture exceeded!");
3609     return FALSE;
3610   }
3611   return TRUE;  /* we got to that packet */
3612 }
3613
3614 gboolean
3615 cf_goto_top_frame(void)
3616 {
3617   /* Find and select */
3618   packet_list_select_first_row();
3619   return TRUE;  /* we got to that packet */
3620 }
3621
3622 gboolean
3623 cf_goto_bottom_frame(void)
3624 {
3625   /* Find and select */
3626   packet_list_select_last_row();
3627   return TRUE;  /* we got to that packet */
3628 }
3629
3630 /*
3631  * Go to frame specified by currently selected protocol tree item.
3632  */
3633 gboolean
3634 cf_goto_framenum(capture_file *cf)
3635 {
3636   header_field_info *hfinfo;
3637   guint32            framenum;
3638
3639   if (cf->finfo_selected) {
3640     hfinfo = cf->finfo_selected->hfinfo;
3641     g_assert(hfinfo);
3642     if (hfinfo->type == FT_FRAMENUM) {
3643       framenum = fvalue_get_uinteger(&cf->finfo_selected->value);
3644       if (framenum != 0)
3645         return cf_goto_frame(cf, framenum);
3646       }
3647   }
3648
3649   return FALSE;
3650 }
3651
3652 /* Select the packet on a given row. */
3653 void
3654 cf_select_packet(capture_file *cf, int row)
3655 {
3656   epan_dissect_t *old_edt;
3657   frame_data     *fdata;
3658
3659   /* Get the frame data struct pointer for this frame */
3660   fdata = packet_list_get_row_data(row);
3661
3662   if (fdata == NULL) {
3663     /* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
3664        the first entry is added to it by "real_insert_row()", that row
3665        is selected (see "real_insert_row()", in "ui/gtk/gtkclist.c", in both
3666        our version and the vanilla GTK+ version).
3667
3668        This means that a "select-row" signal is emitted; this causes
3669        "packet_list_select_cb()" to be called, which causes "cf_select_packet()"
3670        to be called.
3671
3672        "cf_select_packet()" fetches, above, the data associated with the
3673        row that was selected; however, as "gtk_clist_append()", which
3674        called "real_insert_row()", hasn't yet returned, we haven't yet
3675        associated any data with that row, so we get back a null pointer.
3676
3677        We can't assume that there's only one frame in the frame list,
3678        either, as we may be filtering the display.
3679
3680        We therefore assume that, if "row" is 0, i.e. the first row
3681        is being selected, and "cf->first_displayed" equals
3682        "cf->last_displayed", i.e. there's only one frame being
3683        displayed, that frame is the frame we want.
3684
3685        This means we have to set "cf->first_displayed" and
3686        "cf->last_displayed" before adding the row to the
3687        GtkCList; see the comment in "add_packet_to_packet_list()". */
3688
3689        if (row == 0 && cf->first_displayed == cf->last_displayed)
3690          fdata = frame_data_sequence_find(cf->frames, cf->first_displayed);
3691   }
3692
3693   /* If fdata _still_ isn't set simply give up. */
3694   if (fdata == NULL) {
3695     return;
3696   }
3697
3698   /* Get the data in that frame. */
3699   if (!cf_read_frame (cf, fdata)) {
3700     return;
3701   }
3702
3703   /* Record that this frame is the current frame. */
3704   cf->current_frame = fdata;
3705   cf->current_row = row;
3706
3707   old_edt = cf->edt;
3708   /* Create the logical protocol tree. */
3709   /* We don't need the columns here. */
3710   cf->edt = epan_dissect_new(TRUE, TRUE);
3711
3712   tap_build_interesting(cf->edt);
3713   epan_dissect_run(cf->edt, &cf->phdr, cf->pd, cf->current_frame, 
3714           NULL);
3715
3716   dfilter_macro_build_ftv_cache(cf->edt->tree);
3717
3718   cf_callback_invoke(cf_cb_packet_selected, cf);
3719
3720   if (old_edt != NULL)
3721     epan_dissect_free(old_edt);
3722
3723 }
3724
3725 /* Unselect the selected packet, if any. */
3726 void
3727 cf_unselect_packet(capture_file *cf)
3728 {
3729   epan_dissect_t *old_edt = cf->edt;
3730
3731   cf->edt = NULL;
3732
3733   /* No packet is selected. */
3734   cf->current_frame = NULL;
3735   cf->current_row = 0;
3736
3737   cf_callback_invoke(cf_cb_packet_unselected, cf);
3738
3739   /* No protocol tree means no selected field. */
3740   cf_unselect_field(cf);
3741
3742   /* Destroy the epan_dissect_t for the unselected packet. */
3743   if (old_edt != NULL)
3744     epan_dissect_free(old_edt);
3745 }
3746
3747 /* Unset the selected protocol tree field, if any. */
3748 void
3749 cf_unselect_field(capture_file *cf)
3750 {
3751   cf->finfo_selected = NULL;
3752
3753   cf_callback_invoke(cf_cb_field_unselected, cf);
3754 }
3755
3756 /*
3757  * Mark a particular frame.
3758  */
3759 void
3760 cf_mark_frame(capture_file *cf, frame_data *frame)
3761 {
3762   if (! frame->flags.marked) {
3763     frame->flags.marked = TRUE;
3764     if (cf->count > cf->marked_count)
3765       cf->marked_count++;
3766   }
3767 }
3768
3769 /*
3770  * Unmark a particular frame.
3771  */
3772 void
3773 cf_unmark_frame(capture_file *cf, frame_data *frame)
3774 {
3775   if (frame->flags.marked) {
3776     frame->flags.marked = FALSE;
3777     if (cf->marked_count > 0)
3778       cf->marked_count--;
3779   }
3780 }
3781
3782 /*
3783  * Ignore a particular frame.
3784  */
3785 void
3786 cf_ignore_frame(capture_file *cf, frame_data *frame)
3787 {
3788   if (! frame->flags.ignored) {
3789     frame->flags.ignored = TRUE;
3790     if (cf->count > cf->ignored_count)
3791       cf->ignored_count++;
3792   }
3793 }
3794
3795 /*
3796  * Un-ignore a particular frame.
3797  */
3798 void
3799 cf_unignore_frame(capture_file *cf, frame_data *frame)
3800 {
3801   if (frame->flags.ignored) {
3802     frame->flags.ignored = FALSE;
3803     if (cf->ignored_count > 0)
3804       cf->ignored_count--;
3805   }
3806 }
3807
3808 /*
3809  * Read the comment in SHB block
3810  */
3811
3812 const gchar *
3813 cf_read_shb_comment(capture_file *cf)
3814 {
3815   wtapng_section_t *shb_inf;
3816   const gchar      *temp_str;
3817
3818   /* Get info from SHB */
3819   shb_inf = wtap_file_get_shb_info(cf->wth);
3820   if (shb_inf == NULL)
3821         return NULL;
3822   temp_str = shb_inf->opt_comment;
3823   g_free(shb_inf);
3824
3825   return temp_str;
3826
3827 }
3828
3829 void
3830 cf_update_capture_comment(capture_file *cf, gchar *comment)
3831 {
3832   wtapng_section_t *shb_inf;
3833
3834   /* Get info from SHB */
3835   shb_inf = wtap_file_get_shb_info(cf->wth);
3836
3837   /* See if the comment has changed or not */
3838   if (shb_inf && shb_inf->opt_comment) {
3839     if (strcmp(shb_inf->opt_comment, comment) == 0) {
3840       g_free(comment);
3841       g_free(shb_inf);
3842       return;
3843     }
3844   }
3845
3846   g_free(shb_inf);
3847
3848   /* The comment has changed, let's update it */
3849   wtap_write_shb_comment(cf->wth, comment);
3850   /* Mark the file as having unsaved changes */
3851   cf->unsaved_changes = TRUE;
3852 }
3853
3854 void
3855 cf_update_packet_comment(capture_file *cf, frame_data *fdata, gchar *comment)
3856 {
3857   if (fdata->opt_comment != NULL) {
3858     /* OK, remove the old comment. */
3859     g_free(fdata->opt_comment);
3860     fdata->opt_comment = NULL;
3861     cf->packet_comment_count--;
3862   }
3863   if (comment != NULL) {
3864     /* Add the new comment. */
3865     fdata->opt_comment = comment;
3866     cf->packet_comment_count++;
3867   }
3868
3869   /* OK, we have unsaved changes. */
3870   cf->unsaved_changes = TRUE;
3871 }
3872
3873 /*
3874  * Does this capture file have any comments?
3875  */
3876 gboolean
3877 cf_has_comments(capture_file *cf)
3878 {
3879   return (cf_read_shb_comment(cf) != NULL || cf->packet_comment_count != 0);
3880 }
3881
3882 typedef struct {
3883   wtap_dumper *pdh;
3884   const char  *fname;
3885   int          file_type;
3886 } save_callback_args_t;
3887
3888 /*
3889  * Save a capture to a file, in a particular format, saving either
3890  * all packets, all currently-displayed packets, or all marked packets.
3891  *
3892  * Returns TRUE if it succeeds, FALSE otherwise; if it fails, it pops
3893  * up a message box for the failure.
3894  */
3895 static gboolean
3896 save_packet(capture_file *cf _U_, frame_data *fdata,
3897             struct wtap_pkthdr *phdr, const guint8 *pd,
3898             void *argsp)
3899 {
3900   save_callback_args_t *args = argsp;
3901   struct wtap_pkthdr    hdr;
3902   int           err;
3903   gchar        *display_basename;
3904
3905   /* init the wtap header for saving */
3906   /* TODO: reuse phdr */
3907   /* XXX - these are the only flags that correspond to data that we have
3908      in the frame_data structure and that matter on a per-packet basis.
3909
3910      For WTAP_HAS_CAP_LEN, either the file format has separate "captured"
3911      and "on the wire" lengths, or it doesn't.
3912
3913      For WTAP_HAS_DROP_COUNT, Wiretap doesn't actually supply the value
3914      to its callers.
3915
3916      For WTAP_HAS_PACK_FLAGS, we currently don't save the FCS length
3917      from the packet flags. */
3918   hdr.presence_flags = 0;
3919   if (fdata->flags.has_ts)
3920     hdr.presence_flags |= WTAP_HAS_TS;
3921   if (fdata->flags.has_if_id)
3922     hdr.presence_flags |= WTAP_HAS_INTERFACE_ID;
3923   hdr.ts.secs      = fdata->abs_ts.secs;
3924   hdr.ts.nsecs     = fdata->abs_ts.nsecs;
3925   hdr.caplen       = fdata->cap_len;
3926   hdr.len          = fdata->pkt_len;
3927   hdr.pkt_encap    = fdata->lnk_t;
3928   /* pcapng */
3929   hdr.interface_id = fdata->interface_id;   /* identifier of the interface. */
3930   /* options */
3931   hdr.opt_comment  = fdata->opt_comment; /* NULL if not available */
3932   /* pseudo */
3933   hdr.pseudo_header = phdr->pseudo_header;
3934 #if 0
3935   hdr.drop_count   =
3936   hdr.pack_flags   =     /* XXX - 0 for now (any value for "we don't have it"?) */
3937 #endif
3938   /* and save the packet */
3939   if (!wtap_dump(args->pdh, &hdr, pd, &err)) {
3940     if (err < 0) {
3941       /* Wiretap error. */
3942       switch (err) {
3943
3944       case WTAP_ERR_UNSUPPORTED_ENCAP:
3945         /*
3946          * This is a problem with the particular frame we're writing;
3947          * note that, and give the frame number.
3948          */
3949         simple_error_message_box(
3950                       "Frame %u has a network type that can't be saved in a \"%s\" file.",
3951                       fdata->num, wtap_file_type_string(args->file_type));
3952         break;
3953
3954       default:
3955         display_basename = g_filename_display_basename(args->fname);
3956         simple_error_message_box(
3957                       "An error occurred while writing to the file \"%s\": %s.",
3958                       display_basename, wtap_strerror(err));
3959         g_free(display_basename);
3960         break;
3961       }
3962     } else {
3963       /* OS error. */
3964       write_failure_alert_box(args->fname, err);
3965     }
3966     return FALSE;
3967   }
3968   return TRUE;
3969 }
3970
3971 /*
3972  * Can this capture file be written out in any format using Wiretap
3973  * rather than by copying the raw data?
3974  */
3975 gboolean
3976 cf_can_write_with_wiretap(capture_file *cf)
3977 {
3978   int ft;
3979
3980   for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
3981     /* To save a file with Wiretap, Wiretap has to handle that format,
3982        and its code to handle that format must be able to write a file
3983        with this file's encapsulation types. */
3984     if (wtap_dump_can_write_encaps(ft, cf->linktypes)) {
3985       /* OK, we can write it out in this type. */
3986       return TRUE;
3987     }
3988   }
3989
3990   /* No, we couldn't save it in any format. */
3991   return FALSE;
3992 }
3993
3994 /*
3995  * Quick scan to find packet offsets.
3996  */
3997 static cf_read_status_t
3998 rescan_file(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
3999 {
4000   const struct wtap_pkthdr *phdr;
4001   gchar               *err_info;
4002   gchar               *name_ptr;
4003   gint64               data_offset;
4004   gint64               file_pos;
4005   progdlg_t *volatile  progbar        = NULL;
4006   gboolean             stop_flag;
4007   volatile gint64      size;
4008   volatile float       progbar_val;
4009   GTimeVal             start_time;
4010   gchar                status_str[100];
4011   volatile gint64      progbar_nextstep;
4012   volatile gint64      progbar_quantum;
4013   guint32              framenum;
4014   frame_data          *fdata;
4015   volatile int         count          = 0;
4016 #ifdef HAVE_LIBPCAP
4017   volatile int         displayed_once = 0;
4018 #endif
4019
4020   /* Close the old handle. */
4021   wtap_close(cf->wth);
4022
4023   /* Open the new file. */
4024   cf->wth = wtap_open_offline(fname, err, &err_info, TRUE);
4025   if (cf->wth == NULL) {
4026     cf_open_failure_alert_box(fname, *err, err_info, FALSE, 0);
4027     return CF_READ_ERROR;
4028   }
4029
4030   /* We're scanning a file whose contents should be the same as what
4031      we had before, so we don't discard dissection state etc.. */
4032   cf->f_datalen = 0;
4033
4034   /* Set the file name because we need it to set the follow stream filter.
4035      XXX - is that still true?  We need it for other reasons, though,
4036      in any case. */
4037   cf->filename = g_strdup(fname);
4038
4039   /* Indicate whether it's a permanent or temporary file. */
4040   cf->is_tempfile = is_tempfile;
4041
4042   /* No user changes yet. */
4043   cf->unsaved_changes = FALSE;
4044
4045   cf->cd_t        = wtap_file_type(cf->wth);
4046   cf->linktypes = g_array_sized_new(FALSE, FALSE, (guint) sizeof(int), 1);
4047
4048   cf->snap      = wtap_snapshot_length(cf->wth);
4049   if (cf->snap == 0) {
4050     /* Snapshot length not known. */
4051     cf->has_snap = FALSE;
4052     cf->snap = WTAP_MAX_PACKET_SIZE;
4053   } else
4054     cf->has_snap = TRUE;
4055
4056   name_ptr = g_filename_display_basename(cf->filename);
4057
4058   cf_callback_invoke(cf_cb_file_rescan_started, cf);
4059
4060   /* Record whether the file is compressed.
4061      XXX - do we know this at open time? */
4062   cf->iscompressed = wtap_iscompressed(cf->wth);
4063
4064   /* Find the size of the file. */
4065   size = wtap_file_size(cf->wth, NULL);
4066
4067   /* Update the progress bar when it gets to this value. */
4068   progbar_nextstep = 0;
4069   /* When we reach the value that triggers a progress bar update,
4070      bump that value by this amount. */
4071   if (size >= 0) {
4072     progbar_quantum = size/N_PROGBAR_UPDATES;
4073     if (progbar_quantum < MIN_QUANTUM)
4074       progbar_quantum = MIN_QUANTUM;
4075   }else
4076     progbar_quantum = 0;
4077   /* Progress so far. */
4078   progbar_val = 0.0f;
4079
4080   stop_flag = FALSE;
4081   g_get_current_time(&start_time);
4082
4083   framenum = 0;
4084   phdr = wtap_phdr(cf->wth);
4085   while ((wtap_read(cf->wth, err, &err_info, &data_offset))) {
4086     framenum++;
4087     fdata = frame_data_sequence_find(cf->frames, framenum);
4088     fdata->file_off = data_offset;
4089     if (size >= 0) {
4090       count++;
4091       file_pos = wtap_read_so_far(cf->wth);
4092
4093       /* Create the progress bar if necessary.
4094        * Check whether it should be created or not every MIN_NUMBER_OF_PACKET
4095        */
4096       if ((progbar == NULL) && !(count % MIN_NUMBER_OF_PACKET)) {
4097         progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
4098         progbar = delayed_create_progress_dlg(cf->window, "Rescanning", name_ptr,
4099                                               TRUE, &stop_flag, &start_time, progbar_val);
4100       }
4101
4102       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
4103          when we update it, we have to run the GTK+ main loop to get it
4104          to repaint what's pending, and doing so may involve an "ioctl()"
4105          to see if there's any pending input from an X server, and doing
4106          that for every packet can be costly, especially on a big file. */
4107       if (file_pos >= progbar_nextstep) {
4108         if (progbar != NULL) {
4109           progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
4110           /* update the packet bar content on the first run or frequently on very large files */
4111 #ifdef HAVE_LIBPCAP
4112           if (progbar_quantum > 500000 || displayed_once == 0) {
4113             if ((auto_scroll_live || displayed_once == 0 || cf->displayed_count < 1000) && cf->count != 0) {
4114               displayed_once = 1;
4115               packets_bar_update();
4116             }
4117           }
4118 #endif /* HAVE_LIBPCAP */
4119           update_progress_dlg(progbar, progbar_val, status_str);
4120         }
4121         progbar_nextstep += progbar_quantum;
4122       }
4123     }
4124
4125     if (stop_flag) {
4126       /* Well, the user decided to abort the rescan.  Sadly, as this
4127          isn't a reread, recovering is difficult, so we'll just
4128          close the current capture. */
4129       break;
4130     }
4131
4132     /* Add this packet's link-layer encapsulation type to cf->linktypes, if
4133        it's not already there.
4134        XXX - yes, this is O(N), so if every packet had a different
4135        link-layer encapsulation type, it'd be O(N^2) to read the file, but
4136        there are probably going to be a small number of encapsulation types
4137        in a file. */
4138     cf_add_encapsulation_type(cf, phdr->pkt_encap);
4139   }
4140
4141   /* Free the display name */
4142   g_free(name_ptr);
4143
4144   /* We're done reading the file; destroy the progress bar if it was created. */
4145   if (progbar != NULL)
4146     destroy_progress_dlg(progbar);
4147
4148   /* We're done reading sequentially through the file. */
4149   cf->state = FILE_READ_DONE;
4150
4151   /* Close the sequential I/O side, to free up memory it requires. */
4152   wtap_sequential_close(cf->wth);
4153
4154   /* compute the time it took to load the file */
4155   compute_elapsed(&start_time);
4156
4157   /* Set the file encapsulation type now; we don't know what it is until
4158      we've looked at all the packets, as we don't know until then whether
4159      there's more than one type (and thus whether it's
4160      WTAP_ENCAP_PER_PACKET). */
4161   cf->lnk_t = wtap_file_encap(cf->wth);
4162
4163   cf_callback_invoke(cf_cb_file_rescan_finished, cf);
4164
4165   if (stop_flag) {
4166     /* Our caller will give up at this point. */
4167     return CF_READ_ABORTED;
4168   }
4169
4170   if (*err != 0) {
4171     /* Put up a message box noting that the read failed somewhere along
4172        the line.  Don't throw out the stuff we managed to read, though,
4173        if any. */
4174     switch (*err) {
4175
4176     case WTAP_ERR_UNSUPPORTED:
4177       simple_error_message_box(
4178                  "The capture file contains record data that Wireshark doesn't support.\n(%s)",
4179                  err_info);
4180       g_free(err_info);
4181       break;
4182
4183     case WTAP_ERR_UNSUPPORTED_ENCAP:
4184       simple_error_message_box(
4185                  "The capture file has a packet with a network type that Wireshark doesn't support.\n(%s)",
4186                  err_info);
4187       g_free(err_info);
4188       break;
4189
4190     case WTAP_ERR_CANT_READ:
4191       simple_error_message_box(
4192                  "An attempt to read from the capture file failed for"
4193                  " some unknown reason.");
4194       break;
4195
4196     case WTAP_ERR_SHORT_READ:
4197       simple_error_message_box(
4198                  "The capture file appears to have been cut short"
4199                  " in the middle of a packet.");
4200       break;
4201
4202     case WTAP_ERR_BAD_FILE:
4203       simple_error_message_box(
4204                  "The capture file appears to be damaged or corrupt.\n(%s)",
4205                  err_info);
4206       g_free(err_info);
4207       break;
4208
4209     case WTAP_ERR_DECOMPRESS:
4210       simple_error_message_box(
4211                  "The compressed capture file appears to be damaged or corrupt.\n"
4212                  "(%s)", err_info);
4213       g_free(err_info);
4214       break;
4215
4216     default:
4217       simple_error_message_box(
4218                  "An error occurred while reading the"
4219                  " capture file: %s.", wtap_strerror(*err));
4220       break;
4221     }
4222     return CF_READ_ERROR;
4223   } else
4224     return CF_READ_OK;
4225 }
4226
4227 cf_write_status_t
4228 cf_save_packets(capture_file *cf, const char *fname, guint save_format,
4229                 gboolean compressed, gboolean discard_comments,
4230                 gboolean dont_reopen)
4231 {
4232   gchar        *fname_new = NULL;
4233   int           err;
4234   gchar        *err_info;
4235   enum {
4236      SAVE_WITH_MOVE,
4237      SAVE_WITH_COPY,
4238      SAVE_WITH_WTAP
4239   }             how_to_save;
4240   wtap_dumper  *pdh;
4241   save_callback_args_t callback_args;
4242 #ifdef _WIN32
4243   gchar        *display_basename;
4244 #endif
4245   guint         framenum;
4246   frame_data   *fdata;
4247
4248   cf_callback_invoke(cf_cb_file_save_started, (gpointer)fname);
4249
4250   if (save_format == cf->cd_t && compressed == cf->iscompressed
4251       && !discard_comments && !cf->unsaved_changes) {
4252     /* We're saving in the format it's already in, and we're
4253        not discarding comments, and there are no changes we have
4254        in memory that aren't saved to the file, so we can just move
4255        or copy the raw data. */
4256
4257     if (cf->is_tempfile) {
4258       /* The file being saved is a temporary file from a live
4259          capture, so it doesn't need to stay around under that name;
4260          first, try renaming the capture buffer file to the new name.
4261          This acts as a "safe save", in that, if the file already
4262          exists, the existing file will be removed only if the rename
4263          succeeds.
4264
4265          Sadly, on Windows, as we have the current capture file
4266          open, even MoveFileEx() with MOVEFILE_REPLACE_EXISTING
4267          (to cause the rename to remove an existing target), as
4268          done by ws_stdio_rename() (ws_rename() is #defined to
4269          be ws_stdio_rename() on Windows) will fail.
4270
4271          According to the MSDN documentation for CreateFile(), if,
4272          when we open a capture file, we were to directly do a CreateFile(),
4273          opening with FILE_SHARE_DELETE|FILE_SHARE_READ, and then
4274          convert it to a file descriptor with _open_osfhandle(),
4275          that would allow the file to be renamed out from under us.
4276
4277          However, that doesn't work in practice.  Perhaps the problem
4278          is that the process doing the rename is the process that
4279          has the file open. */
4280 #ifndef _WIN32
4281       if (ws_rename(cf->filename, fname) == 0) {
4282         /* That succeeded - there's no need to copy the source file. */
4283         how_to_save = SAVE_WITH_MOVE;
4284       } else {
4285         if (errno == EXDEV) {
4286           /* They're on different file systems, so we have to copy the
4287              file. */
4288           how_to_save = SAVE_WITH_COPY;
4289         } else {
4290           /* The rename failed, but not because they're on different
4291              file systems - put up an error message.  (Or should we
4292              just punt and try to copy?  The only reason why I'd
4293              expect the rename to fail and the copy to succeed would
4294              be if we didn't have permission to remove the file from
4295              the temporary directory, and that might be fixable - but
4296              is it worth requiring the user to go off and fix it?) */
4297           cf_rename_failure_alert_box(fname, errno);
4298           goto fail;
4299         }
4300       }
4301 #else
4302       how_to_save = SAVE_WITH_COPY;
4303 #endif
4304     } else {
4305       /* It's a permanent file, so we should copy it, and not remove the
4306          original. */
4307       how_to_save = SAVE_WITH_COPY;
4308     }
4309
4310     if (how_to_save == SAVE_WITH_COPY) {
4311       /* Copy the file, if we haven't moved it.  If we're overwriting
4312          an existing file, we do it with a "safe save", by writing
4313          to a new file and, if the write succeeds, renaming the
4314          new file on top of the old file. */
4315       if (file_exists(fname)) {
4316         fname_new = g_strdup_printf("%s~", fname);
4317         if (!copy_file_binary_mode(cf->filename, fname_new))
4318           goto fail;
4319       } else {
4320         if (!copy_file_binary_mode(cf->filename, fname))
4321           goto fail;
4322       }
4323     }
4324   } else {
4325     /* Either we're saving in a different format or we're saving changes,
4326        such as added, modified, or removed comments, that haven't yet
4327        been written to the underlying file; we can't do that by copying
4328        or moving the capture file, we have to do it by writing the packets
4329        out in Wiretap. */
4330
4331     wtapng_section_t *shb_hdr = NULL;
4332     wtapng_iface_descriptions_t *idb_inf = NULL;
4333     int encap;
4334
4335     shb_hdr = wtap_file_get_shb_info(cf->wth);
4336     idb_inf = wtap_file_get_idb_info(cf->wth);
4337
4338     /* Determine what file encapsulation type we should use. */
4339     encap = wtap_dump_file_encap_type(cf->linktypes);
4340
4341     if (file_exists(fname)) {
4342       /* We're overwriting an existing file; write out to a new file,
4343          and, if that succeeds, rename the new file on top of the
4344          old file.  That makes this a "safe save", so that we don't
4345          lose the old file if we have a problem writing out the new
4346          file.  (If the existing file is the current capture file,
4347          we *HAVE* to do that, otherwise we're overwriting the file
4348          from which we're reading the packets that we're writing!) */
4349       fname_new = g_strdup_printf("%s~", fname);
4350       pdh = wtap_dump_open_ng(fname_new, save_format, encap, cf->snap,
4351                               compressed, shb_hdr, idb_inf, &err);
4352     } else {
4353       pdh = wtap_dump_open_ng(fname, save_format, encap, cf->snap,
4354                               compressed, shb_hdr, idb_inf, &err);
4355     }
4356     g_free(idb_inf);
4357     idb_inf = NULL;
4358
4359     if (pdh == NULL) {
4360       cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
4361       goto fail;
4362     }
4363
4364     /* Add address resolution */
4365     wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list());
4366
4367     /* Iterate through the list of packets, processing all the packets. */
4368     callback_args.pdh = pdh;
4369     callback_args.fname = fname;
4370     callback_args.file_type = save_format;
4371     switch (process_specified_packets(cf, NULL, "Saving", "packets",
4372                                       TRUE, save_packet, &callback_args)) {
4373
4374     case PSP_FINISHED:
4375       /* Completed successfully. */
4376       break;
4377
4378     case PSP_STOPPED:
4379       /* The user decided to abort the saving.
4380          If we're writing to a temporary file, remove it.
4381          XXX - should we do so even if we're not writing to a
4382          temporary file? */
4383       wtap_dump_close(pdh, &err);
4384       if (fname_new != NULL)
4385         ws_unlink(fname_new);
4386       cf_callback_invoke(cf_cb_file_save_stopped, NULL);
4387       return CF_WRITE_ABORTED;
4388
4389     case PSP_FAILED:
4390       /* Error while saving.
4391          If we're writing to a temporary file, remove it. */
4392       if (fname_new != NULL)
4393         ws_unlink(fname_new);
4394       wtap_dump_close(pdh, &err);
4395       goto fail;
4396     }
4397
4398     if (!wtap_dump_close(pdh, &err)) {
4399       cf_close_failure_alert_box(fname, err);
4400       goto fail;
4401     }
4402
4403     how_to_save = SAVE_WITH_WTAP;
4404   }
4405
4406   if (fname_new != NULL) {
4407     /* We wrote out to fname_new, and should rename it on top of
4408        fname.  fname_new is now closed, so that should be possible even
4409        on Windows.  However, on Windows, we first need to close whatever
4410        file descriptors we have open for fname. */
4411 #ifdef _WIN32
4412     wtap_fdclose(cf->wth);
4413 #endif
4414     /* Now do the rename. */
4415     if (ws_rename(fname_new, fname) == -1) {
4416       /* Well, the rename failed. */
4417       cf_rename_failure_alert_box(fname, errno);
4418 #ifdef _WIN32
4419       /* Attempt to reopen the random file descriptor using the
4420          current file's filename.  (At this point, the sequential
4421          file descriptor is closed.) */
4422       if (!wtap_fdreopen(cf->wth, cf->filename, &err)) {
4423         /* Oh, well, we're screwed. */
4424         display_basename = g_filename_display_basename(cf->filename);
4425         simple_error_message_box(
4426                       file_open_error_message(err, FALSE), display_basename);
4427         g_free(display_basename);
4428       }
4429 #endif
4430       goto fail;
4431     }
4432   }
4433
4434   cf_callback_invoke(cf_cb_file_save_finished, NULL);
4435   cf->unsaved_changes = FALSE;
4436
4437   if (!dont_reopen) {
4438     switch (how_to_save) {
4439
4440     case SAVE_WITH_MOVE:
4441       /* We just moved the file, so the wtap structure refers to the
4442          new file, and all the information other than the filename
4443          and the "is temporary" status applies to the new file; just
4444          update that. */
4445       g_free(cf->filename);
4446       cf->filename = g_strdup(fname);
4447       cf->is_tempfile = FALSE;
4448       cf_callback_invoke(cf_cb_file_fast_save_finished, cf);
4449       break;
4450
4451     case SAVE_WITH_COPY:
4452       /* We just copied the file, s all the information other than
4453          the wtap structure, the filename, and the "is temporary"
4454          status applies to the new file; just update that. */
4455       wtap_close(cf->wth);
4456       cf->wth = wtap_open_offline(fname, &err, &err_info, TRUE);
4457       if (cf->wth == NULL) {
4458         cf_open_failure_alert_box(fname, err, err_info, FALSE, 0);
4459         cf_close(cf);
4460       } else {
4461         g_free(cf->filename);
4462         cf->filename = g_strdup(fname);
4463         cf->is_tempfile = FALSE;
4464       }
4465       cf_callback_invoke(cf_cb_file_fast_save_finished, cf);
4466       break;
4467
4468     case SAVE_WITH_WTAP:
4469       /* Open and read the file we saved to.
4470
4471          XXX - this is somewhat of a waste; we already have the
4472          packets, all this gets us is updated file type information
4473          (which we could just stuff into "cf"), and having the new
4474          file be the one we have opened and from which we're reading
4475          the data, and it means we have to spend time opening and
4476          reading the file, which could be a significant amount of
4477          time if the file is large.
4478
4479          If the capture-file-writing code were to return the
4480          seek offset of each packet it writes, we could save that
4481          in the frame_data structure for the frame, and just open
4482          the file without reading it again...
4483
4484          ...as long as, for gzipped files, the process of writing
4485          out the file *also* generates the information needed to
4486          support fast random access to the compressed file. */
4487       if (rescan_file(cf, fname, FALSE, &err) != CF_READ_OK) {
4488         /* The rescan failed; just close the file.  Either
4489            a dialog was popped up for the failure, so the
4490            user knows what happened, or they stopped the
4491            rescan, in which case they know what happened. */
4492         cf_close(cf);
4493       }
4494       break;
4495     }
4496
4497     /* If we were told to discard the comments, do so. */
4498     if (discard_comments) {
4499       /* Remove SHB comment, if any. */
4500       wtap_write_shb_comment(cf->wth, NULL);
4501
4502       /* Remove packet comments. */
4503       for (framenum = 1; framenum <= cf->count; framenum++) {
4504         fdata = frame_data_sequence_find(cf->frames, framenum);
4505         if (fdata->opt_comment) {
4506           g_free(fdata->opt_comment);
4507           fdata->opt_comment = NULL;
4508           cf->packet_comment_count--;
4509         }
4510       }
4511     }
4512   }
4513   return CF_WRITE_OK;
4514
4515 fail:
4516   if (fname_new != NULL) {
4517     /* We were trying to write to a temporary file; get rid of it if it
4518        exists.  (We don't care whether this fails, as, if it fails,
4519        there's not much we can do about it.  I guess if it failed for
4520        a reason other than "it doesn't exist", we could report an
4521        error, so the user knows there's a junk file that they might
4522        want to clean up.) */
4523     ws_unlink(fname_new);
4524     g_free(fname_new);
4525   }
4526   cf_callback_invoke(cf_cb_file_save_failed, NULL);
4527   return CF_WRITE_ERROR;
4528 }
4529
4530 cf_write_status_t
4531 cf_export_specified_packets(capture_file *cf, const char *fname,
4532                             packet_range_t *range, guint save_format,
4533                             gboolean compressed)
4534 {
4535   gchar                       *fname_new = NULL;
4536   int                          err;
4537   wtap_dumper                 *pdh;
4538   save_callback_args_t         callback_args;
4539   wtapng_section_t            *shb_hdr;
4540   wtapng_iface_descriptions_t *idb_inf;
4541   int                          encap;
4542
4543   cf_callback_invoke(cf_cb_file_export_specified_packets_started, (gpointer)fname);
4544
4545   packet_range_process_init(range);
4546
4547   /* We're writing out specified packets from the specified capture
4548      file to another file.  Even if all captured packets are to be
4549      written, don't special-case the operation - read each packet
4550      and then write it out if it's one of the specified ones. */
4551
4552   shb_hdr = wtap_file_get_shb_info(cf->wth);
4553   idb_inf = wtap_file_get_idb_info(cf->wth);
4554
4555   /* Determine what file encapsulation type we should use. */
4556   encap = wtap_dump_file_encap_type(cf->linktypes);
4557
4558   if (file_exists(fname)) {
4559     /* We're overwriting an existing file; write out to a new file,
4560        and, if that succeeds, rename the new file on top of the
4561        old file.  That makes this a "safe save", so that we don't
4562        lose the old file if we have a problem writing out the new
4563        file.  (If the existing file is the current capture file,
4564        we *HAVE* to do that, otherwise we're overwriting the file
4565        from which we're reading the packets that we're writing!) */
4566     fname_new = g_strdup_printf("%s~", fname);
4567     pdh = wtap_dump_open_ng(fname_new, save_format, encap, cf->snap,
4568                             compressed, shb_hdr, idb_inf, &err);
4569   } else {
4570     pdh = wtap_dump_open_ng(fname, save_format, encap, cf->snap,
4571                             compressed, shb_hdr, idb_inf, &err);
4572   }
4573   g_free(idb_inf);
4574   idb_inf = NULL;
4575
4576   if (pdh == NULL) {
4577     cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
4578     goto fail;
4579   }
4580
4581   /* Add address resolution */
4582   wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list());
4583
4584   /* Iterate through the list of packets, processing the packets we were
4585      told to process.
4586
4587      XXX - we've already called "packet_range_process_init(range)", but
4588      "process_specified_packets()" will do it again.  Fortunately,
4589      that's harmless in this case, as we haven't done anything to
4590      "range" since we initialized it. */
4591   callback_args.pdh = pdh;
4592   callback_args.fname = fname;
4593   callback_args.file_type = save_format;
4594   switch (process_specified_packets(cf, range, "Writing", "specified packets",
4595                                     TRUE, save_packet, &callback_args)) {
4596
4597   case PSP_FINISHED:
4598     /* Completed successfully. */
4599     break;
4600
4601   case PSP_STOPPED:
4602       /* The user decided to abort the saving.
4603          If we're writing to a temporary file, remove it.
4604          XXX - should we do so even if we're not writing to a
4605          temporary file? */
4606       wtap_dump_close(pdh, &err);
4607       if (fname_new != NULL)
4608         ws_unlink(fname_new);
4609       cf_callback_invoke(cf_cb_file_export_specified_packets_stopped, NULL);
4610       return CF_WRITE_ABORTED;
4611     break;
4612
4613   case PSP_FAILED:
4614     /* Error while saving.
4615        If we're writing to a temporary file, remove it. */
4616     if (fname_new != NULL)
4617       ws_unlink(fname_new);
4618     wtap_dump_close(pdh, &err);
4619     goto fail;
4620   }
4621
4622   if (!wtap_dump_close(pdh, &err)) {
4623     cf_close_failure_alert_box(fname, err);
4624     goto fail;
4625   }
4626
4627   if (fname_new != NULL) {
4628     /* We wrote out to fname_new, and should rename it on top of
4629        fname; fname is now closed, so that should be possible even
4630        on Windows.  Do the rename. */
4631     if (ws_rename(fname_new, fname) == -1) {
4632       /* Well, the rename failed. */
4633       cf_rename_failure_alert_box(fname, errno);
4634       goto fail;
4635     }
4636   }
4637
4638   cf_callback_invoke(cf_cb_file_export_specified_packets_finished, NULL);
4639   return CF_WRITE_OK;
4640
4641 fail:
4642   if (fname_new != NULL) {
4643     /* We were trying to write to a temporary file; get rid of it if it
4644        exists.  (We don't care whether this fails, as, if it fails,
4645        there's not much we can do about it.  I guess if it failed for
4646        a reason other than "it doesn't exist", we could report an
4647        error, so the user knows there's a junk file that they might
4648        want to clean up.) */
4649     ws_unlink(fname_new);
4650     g_free(fname_new);
4651   }
4652   cf_callback_invoke(cf_cb_file_export_specified_packets_failed, NULL);
4653   return CF_WRITE_ERROR;
4654 }
4655
4656 static void
4657 cf_open_failure_alert_box(const char *filename, int err, gchar *err_info,
4658                           gboolean for_writing, int file_type)
4659 {
4660   gchar *display_basename;
4661
4662   if (err < 0) {
4663     /* Wiretap error. */
4664     display_basename = g_filename_display_basename(filename);
4665     switch (err) {
4666
4667     case WTAP_ERR_NOT_REGULAR_FILE:
4668       simple_error_message_box(
4669             "The file \"%s\" is a \"special file\" or socket or other non-regular file.",
4670             display_basename);
4671       break;
4672
4673     case WTAP_ERR_RANDOM_OPEN_PIPE:
4674       /* Seen only when opening a capture file for reading. */
4675       simple_error_message_box(
4676             "The file \"%s\" is a pipe or FIFO; Wireshark can't read pipe or FIFO files.\n"
4677             "To capture from a pipe or FIFO use wireshark -i -",
4678             display_basename);
4679       break;
4680
4681     case WTAP_ERR_FILE_UNKNOWN_FORMAT:
4682       /* Seen only when opening a capture file for reading. */
4683       simple_error_message_box(
4684             "The file \"%s\" isn't a capture file in a format Wireshark understands.",
4685             display_basename);
4686       break;
4687
4688     case WTAP_ERR_UNSUPPORTED:
4689       /* Seen only when opening a capture file for reading. */
4690       simple_error_message_box(
4691             "The file \"%s\" isn't a capture file in a format Wireshark understands.\n"
4692             "(%s)",
4693             display_basename, err_info);
4694       g_free(err_info);
4695       break;
4696
4697     case WTAP_ERR_CANT_WRITE_TO_PIPE:
4698       /* Seen only when opening a capture file for writing. */
4699       simple_error_message_box(
4700             "The file \"%s\" is a pipe, and %s capture files can't be "
4701             "written to a pipe.",
4702             display_basename, wtap_file_type_string(file_type));
4703       break;
4704
4705     case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
4706       /* Seen only when opening a capture file for writing. */
4707       simple_error_message_box(
4708             "Wireshark doesn't support writing capture files in that format.");
4709       break;
4710
4711     case WTAP_ERR_UNSUPPORTED_ENCAP:
4712       if (for_writing) {
4713         simple_error_message_box("Wireshark can't save this capture in that format.");
4714       } else {
4715         simple_error_message_box(
4716               "The file \"%s\" is a capture for a network type that Wireshark doesn't support.\n"
4717               "(%s)",
4718               display_basename, err_info);
4719         g_free(err_info);
4720       }
4721       break;
4722
4723     case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
4724       if (for_writing) {
4725         simple_error_message_box(
4726               "Wireshark can't save this capture in that format.");
4727       } else {
4728         simple_error_message_box(
4729               "The file \"%s\" is a capture for a network type that Wireshark doesn't support.",
4730               display_basename);
4731       }
4732       break;
4733
4734     case WTAP_ERR_BAD_FILE:
4735       /* Seen only when opening a capture file for reading. */
4736       simple_error_message_box(
4737             "The file \"%s\" appears to be damaged or corrupt.\n"
4738             "(%s)",
4739             display_basename, err_info);
4740       g_free(err_info);
4741       break;
4742
4743     case WTAP_ERR_CANT_OPEN:
4744       if (for_writing) {
4745         simple_error_message_box(
4746               "The file \"%s\" could not be created for some unknown reason.",
4747               display_basename);
4748       } else {
4749         simple_error_message_box(
4750               "The file \"%s\" could not be opened for some unknown reason.",
4751               display_basename);
4752       }
4753       break;
4754
4755     case WTAP_ERR_SHORT_READ:
4756       simple_error_message_box(
4757             "The file \"%s\" appears to have been cut short"
4758             " in the middle of a packet or other data.",
4759             display_basename);
4760       break;
4761
4762     case WTAP_ERR_SHORT_WRITE:
4763       simple_error_message_box(
4764             "A full header couldn't be written to the file \"%s\".",
4765             display_basename);
4766       break;
4767
4768     case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
4769       simple_error_message_box(
4770             "This file type cannot be written as a compressed file.");
4771       break;
4772
4773     case WTAP_ERR_DECOMPRESS:
4774       simple_error_message_box(
4775             "The compressed file \"%s\" appears to be damaged or corrupt.\n"
4776             "(%s)", display_basename, err_info);
4777       g_free(err_info);
4778       break;
4779
4780     default:
4781       simple_error_message_box(
4782             "The file \"%s\" could not be %s: %s.",
4783             display_basename,
4784             for_writing ? "created" : "opened",
4785             wtap_strerror(err));
4786       break;
4787     }
4788     g_free(display_basename);
4789   } else {
4790     /* OS error. */
4791     open_failure_alert_box(filename, err, for_writing);
4792   }
4793 }
4794
4795 /*
4796  * XXX - whether we mention the source pathname, the target pathname,
4797  * or both depends on the error and on what we find if we look for
4798  * one or both of them.
4799  */
4800 static void
4801 cf_rename_failure_alert_box(const char *filename, int err)
4802 {
4803   gchar *display_basename;
4804
4805   display_basename = g_filename_display_basename(filename);
4806   switch (err) {
4807
4808   case ENOENT:
4809     /* XXX - should check whether the source exists and, if not,
4810        report it as the problem and, if so, report the destination
4811        as the problem. */
4812     simple_error_message_box("The path to the file \"%s\" doesn't exist.",
4813                              display_basename);
4814     break;
4815
4816   case EACCES:
4817     /* XXX - if we're doing a rename after a safe save, we should
4818        probably say something else. */
4819     simple_error_message_box("You don't have permission to move the capture file to \"%s\".",
4820                              display_basename);
4821     break;
4822
4823   default:
4824     /* XXX - this should probably mention both the source and destination
4825        pathnames. */
4826     simple_error_message_box("The file \"%s\" could not be moved: %s.",
4827                              display_basename, wtap_strerror(err));
4828     break;
4829   }
4830   g_free(display_basename);
4831 }
4832
4833 /* Check for write errors - if the file is being written to an NFS server,
4834    a write error may not show up until the file is closed, as NFS clients
4835    might not send writes to the server until the "write()" call finishes,
4836    so that the write may fail on the server but the "write()" may succeed. */
4837 static void
4838 cf_close_failure_alert_box(const char *filename, int err)
4839 {
4840   gchar *display_basename;
4841
4842   if (err < 0) {
4843     /* Wiretap error. */
4844     display_basename = g_filename_display_basename(filename);
4845     switch (err) {
4846
4847     case WTAP_ERR_CANT_CLOSE:
4848       simple_error_message_box(
4849             "The file \"%s\" couldn't be closed for some unknown reason.",
4850             display_basename);
4851       break;
4852
4853     case WTAP_ERR_SHORT_WRITE:
4854       simple_error_message_box(
4855             "Not all the packets could be written to the file \"%s\".",
4856                     display_basename);
4857       break;
4858
4859     default:
4860       simple_error_message_box(
4861             "An error occurred while closing the file \"%s\": %s.",
4862             display_basename, wtap_strerror(err));
4863       break;
4864     }
4865     g_free(display_basename);
4866   } else {
4867     /* OS error.
4868        We assume that a close error from the OS is really a write error. */
4869     write_failure_alert_box(filename, err);
4870   }
4871 }
4872
4873 /* Reload the current capture file. */
4874 void
4875 cf_reload(capture_file *cf) {
4876   gchar    *filename;
4877   gboolean  is_tempfile;
4878   int       err;
4879
4880   /* If the file could be opened, "cf_open()" calls "cf_close()"
4881      to get rid of state for the old capture file before filling in state
4882      for the new capture file.  "cf_close()" will remove the file if
4883      it's a temporary file; we don't want that to happen (for one thing,
4884      it'd prevent subsequent reopens from working).  Remember whether it's
4885      a temporary file, mark it as not being a temporary file, and then
4886      reopen it as the type of file it was.
4887
4888      Also, "cf_close()" will free "cf->filename", so we must make
4889      a copy of it first. */
4890   filename = g_strdup(cf->filename);
4891   is_tempfile = cf->is_tempfile;
4892   cf->is_tempfile = FALSE;
4893   if (cf_open(cf, filename, is_tempfile, &err) == CF_OK) {
4894     switch (cf_read(cf, TRUE)) {
4895
4896     case CF_READ_OK:
4897     case CF_READ_ERROR:
4898       /* Just because we got an error, that doesn't mean we were unable
4899          to read any of the file; we handle what we could get from the
4900          file. */
4901       break;
4902
4903     case CF_READ_ABORTED:
4904       /* The user bailed out of re-reading the capture file; the
4905          capture file has been closed - just free the capture file name
4906          string and return (without changing the last containing
4907          directory). */
4908       g_free(filename);
4909       return;
4910     }
4911   } else {
4912     /* The open failed, so "cf->is_tempfile" wasn't set to "is_tempfile".
4913        Instead, the file was left open, so we should restore "cf->is_tempfile"
4914        ourselves.
4915
4916        XXX - change the menu?  Presumably "cf_open()" will do that;
4917        make sure it does! */
4918     cf->is_tempfile = is_tempfile;
4919   }
4920   /* "cf_open()" made a copy of the file name we handed it, so
4921      we should free up our copy. */
4922   g_free(filename);
4923 }
4924
4925 /*
4926  * Editor modelines
4927  *
4928  * Local Variables:
4929  * c-basic-offset: 2
4930  * tab-width: 8
4931  * indent-tabs-mode: nil
4932  * End:
4933  *
4934  * ex: set shiftwidth=2 tabstop=8 expandtab:
4935  * :indentSize=2:tabSize=8:noTabs=true:
4936  */