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