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