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