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