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