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