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