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