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