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