1603d95784ad758ff685e448351cf3d5edc6b8c7
[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_write_error) {
1552     if (!wtap_dump_close(pdh, &write_err))
1553       got_write_error = TRUE;
1554   } else {
1555     /*
1556      * We already got a write error; no need to report another
1557      * write error on close.
1558      *
1559      * Don't overwrite the earlier write error.
1560      */
1561     (void)wtap_dump_close(pdh, &close_err);
1562   }
1563
1564   if (got_read_error) {
1565     /*
1566      * Find the file on which we got the error, and report the error.
1567      */
1568     for (i = 0; i < in_file_count; i++) {
1569       if (in_files[i].state == GOT_ERROR) {
1570         /* Put up a message box noting that a read failed somewhere along
1571            the line. */
1572         display_basename = g_filename_display_basename(in_files[i].filename);
1573         switch (read_err) {
1574
1575         case WTAP_ERR_UNSUPPORTED_ENCAP:
1576           simple_error_message_box(
1577                      "The capture file %s has a packet with a network type that Wireshark doesn't support.\n(%s)",
1578                      display_basename, err_info);
1579           g_free(err_info);
1580           break;
1581
1582         case WTAP_ERR_CANT_READ:
1583           simple_error_message_box(
1584                      "An attempt to read from the capture file %s failed for"
1585                      " some unknown reason.", display_basename);
1586           break;
1587
1588         case WTAP_ERR_SHORT_READ:
1589           simple_error_message_box(
1590                      "The capture file %s appears to have been cut short"
1591                       " in the middle of a packet.", display_basename);
1592           break;
1593
1594         case WTAP_ERR_BAD_FILE:
1595           simple_error_message_box(
1596                      "The capture file %s appears to be damaged or corrupt.\n(%s)",
1597                      display_basename, err_info);
1598           g_free(err_info);
1599           break;
1600
1601         case WTAP_ERR_DECOMPRESS:
1602           simple_error_message_box(
1603                      "The compressed capture file %s appears to be damaged or corrupt.\n"
1604                      "(%s)", display_basename, err_info);
1605           g_free(err_info);
1606           break;
1607
1608         default:
1609           simple_error_message_box(
1610                      "An error occurred while reading the"
1611                      " capture file %s: %s.",
1612                      display_basename,  wtap_strerror(read_err));
1613           break;
1614         }
1615         g_free(display_basename);
1616       }
1617     }
1618   }
1619
1620   if (got_write_error) {
1621     /* Put up an alert box for the write error. */
1622     if (write_err < 0) {
1623       /* Wiretap error. */
1624       switch (write_err) {
1625
1626       case WTAP_ERR_UNSUPPORTED_ENCAP:
1627         /*
1628          * This is a problem with the particular frame we're writing and
1629          * the file type and subtype we're writing; note that, and report
1630          * the frame number and file type/subtype.
1631          */
1632         display_basename = g_filename_display_basename(in_file->filename);
1633         simple_error_message_box(
1634                       "Frame %u of \"%s\" has a network type that can't be saved in a \"%s\" file.",
1635                       in_file->packet_num, display_basename,
1636                       wtap_file_type_subtype_string(file_type));
1637         g_free(display_basename);
1638         break;
1639
1640       case WTAP_ERR_PACKET_TOO_LARGE:
1641         /*
1642          * This is a problem with the particular frame we're writing and
1643          * the file type and subtype we're writing; note that, and report
1644          * the frame number and file type/subtype.
1645          */
1646         display_basename = g_filename_display_basename(in_file->filename);
1647         simple_error_message_box(
1648                       "Frame %u of \"%s\" is too large for a \"%s\" file.",
1649                       in_file->packet_num, display_basename,
1650                       wtap_file_type_subtype_string(file_type));
1651         g_free(display_basename);
1652         break;
1653
1654       default:
1655         display_basename = g_filename_display_basename(out_filename);
1656         simple_error_message_box(
1657                       "An error occurred while writing to the file \"%s\": %s.",
1658                       out_filename, wtap_strerror(write_err));
1659         g_free(display_basename);
1660         break;
1661       }
1662     } else {
1663       /* OS error. */
1664       write_failure_alert_box(out_filename, write_err);
1665     }
1666   }
1667
1668   if (got_read_error || got_write_error || stop_flag) {
1669     /* Callers aren't expected to treat an error or an explicit abort
1670        differently - we put up error dialogs ourselves, so they don't
1671        have to. */
1672     return CF_ERROR;
1673   } else
1674     return CF_OK;
1675 }
1676
1677 cf_status_t
1678 cf_filter_packets(capture_file *cf, gchar *dftext, gboolean force)
1679 {
1680   const char *filter_new = dftext ? dftext : "";
1681   const char *filter_old = cf->dfilter ? cf->dfilter : "";
1682   dfilter_t  *dfcode;
1683   GTimeVal    start_time;
1684
1685   /* if new filter equals old one, do nothing unless told to do so */
1686   if (!force && strcmp(filter_new, filter_old) == 0) {
1687     return CF_OK;
1688   }
1689
1690   dfcode=NULL;
1691
1692   if (dftext == NULL) {
1693     /* The new filter is an empty filter (i.e., display all packets).
1694      * so leave dfcode==NULL
1695      */
1696   } else {
1697     /*
1698      * We have a filter; make a copy of it (as we'll be saving it),
1699      * and try to compile it.
1700      */
1701     dftext = g_strdup(dftext);
1702     if (!dfilter_compile(dftext, &dfcode)) {
1703       /* The attempt failed; report an error. */
1704       simple_message_box(ESD_TYPE_ERROR, NULL,
1705           "See the help for a description of the display filter syntax.",
1706           "\"%s\" isn't a valid display filter: %s",
1707           dftext, dfilter_error_msg);
1708       g_free(dftext);
1709       return CF_ERROR;
1710     }
1711
1712     /* Was it empty? */
1713     if (dfcode == NULL) {
1714       /* Yes - free the filter text, and set it to null. */
1715       g_free(dftext);
1716       dftext = NULL;
1717     }
1718   }
1719
1720   /* We have a valid filter.  Replace the current filter. */
1721   g_free(cf->dfilter);
1722   cf->dfilter = dftext;
1723   g_get_current_time(&start_time);
1724
1725
1726   /* Now rescan the packet list, applying the new filter, but not
1727      throwing away information constructed on a previous pass. */
1728   if (dftext == NULL) {
1729     rescan_packets(cf, "Resetting", "Filter", FALSE);
1730   } else {
1731     rescan_packets(cf, "Filtering", dftext, FALSE);
1732   }
1733
1734   /* Cleanup and release all dfilter resources */
1735   dfilter_free(dfcode);
1736
1737   return CF_OK;
1738 }
1739
1740 void
1741 cf_reftime_packets(capture_file *cf)
1742 {
1743   ref_time_packets(cf);
1744 }
1745
1746 void
1747 cf_redissect_packets(capture_file *cf)
1748 {
1749   if (cf->state != FILE_CLOSED) {
1750     rescan_packets(cf, "Reprocessing", "all packets", TRUE);
1751   }
1752 }
1753
1754 gboolean
1755 cf_read_frame_r(capture_file *cf, const frame_data *fdata,
1756                 struct wtap_pkthdr *phdr, Buffer *buf)
1757 {
1758   int    err;
1759   gchar *err_info;
1760   gchar *display_basename;
1761
1762 #ifdef WANT_PACKET_EDITOR
1763   /* if fdata->file_off == -1 it means packet was edited, and we must find data inside edited_frames tree */
1764   if (G_UNLIKELY(fdata->file_off == -1)) {
1765     const modified_frame_data *frame = (const modified_frame_data *) g_tree_lookup(cf->edited_frames, GINT_TO_POINTER(fdata->num));
1766
1767     if (!frame) {
1768       simple_error_message_box("fdata->file_off == -1, but can't find modified frame!");
1769       return FALSE;
1770     }
1771
1772     *phdr = frame->phdr;
1773     buffer_assure_space(buf, frame->phdr.caplen);
1774     memcpy(buffer_start_ptr(buf), frame->pd, frame->phdr.caplen);
1775     return TRUE;
1776   }
1777 #endif
1778
1779   if (!wtap_seek_read(cf->wth, fdata->file_off, phdr, buf, &err, &err_info)) {
1780     display_basename = g_filename_display_basename(cf->filename);
1781     switch (err) {
1782
1783     case WTAP_ERR_UNSUPPORTED_ENCAP:
1784       simple_error_message_box("The file \"%s\" has a packet with a network type that Wireshark doesn't support.\n(%s)",
1785                  display_basename, err_info);
1786       g_free(err_info);
1787       break;
1788
1789     case WTAP_ERR_BAD_FILE:
1790       simple_error_message_box("An error occurred while reading from the file \"%s\": %s.\n(%s)",
1791                  display_basename, wtap_strerror(err), err_info);
1792       g_free(err_info);
1793       break;
1794
1795     default:
1796       simple_error_message_box(
1797                  "An error occurred while reading from the file \"%s\": %s.",
1798                  display_basename, wtap_strerror(err));
1799       break;
1800     }
1801     g_free(display_basename);
1802     return FALSE;
1803   }
1804   return TRUE;
1805 }
1806
1807 gboolean
1808 cf_read_frame(capture_file *cf, frame_data *fdata)
1809 {
1810   return cf_read_frame_r(cf, fdata, &cf->phdr, &cf->buf);
1811 }
1812
1813 /* Rescan the list of packets, reconstructing the CList.
1814
1815    "action" describes why we're doing this; it's used in the progress
1816    dialog box.
1817
1818    "action_item" describes what we're doing; it's used in the progress
1819    dialog box.
1820
1821    "redissect" is TRUE if we need to make the dissectors reconstruct
1822    any state information they have (because a preference that affects
1823    some dissector has changed, meaning some dissector might construct
1824    its state differently from the way it was constructed the last time). */
1825 static void
1826 rescan_packets(capture_file *cf, const char *action, const char *action_item, gboolean redissect)
1827 {
1828   /* Rescan packets new packet list */
1829   guint32     framenum;
1830   frame_data *fdata;
1831   progdlg_t  *progbar = NULL;
1832   gboolean    stop_flag;
1833   int         count;
1834   frame_data *selected_frame, *preceding_frame, *following_frame, *prev_frame;
1835   int         selected_frame_num, preceding_frame_num, following_frame_num, prev_frame_num;
1836   gboolean    selected_frame_seen;
1837   float       progbar_val;
1838   GTimeVal    start_time;
1839   gchar       status_str[100];
1840   int         progbar_nextstep;
1841   int         progbar_quantum;
1842   epan_dissect_t  edt;
1843   dfilter_t  *dfcode;
1844   column_info *cinfo;
1845   gboolean    create_proto_tree;
1846   guint       tap_flags;
1847   gboolean    add_to_packet_list = FALSE;
1848   gboolean    compiled;
1849   guint32     frames_count;
1850
1851   /* Compile the current display filter.
1852    * We assume this will not fail since cf->dfilter is only set in
1853    * cf_filter IFF the filter was valid.
1854    */
1855   compiled = dfilter_compile(cf->dfilter, &dfcode);
1856   g_assert(!cf->dfilter || (compiled && dfcode));
1857
1858   /* Get the union of the flags for all tap listeners. */
1859   tap_flags = union_of_tap_listener_flags();
1860   cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
1861   create_proto_tree =
1862     (dfcode != NULL || have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
1863
1864   reset_tap_listeners();
1865   /* Which frame, if any, is the currently selected frame?
1866      XXX - should the selected frame or the focus frame be the "current"
1867      frame, that frame being the one from which "Find Frame" searches
1868      start? */
1869   selected_frame = cf->current_frame;
1870
1871   /* Mark frame num as not found */
1872   selected_frame_num = -1;
1873
1874   /* Freeze the packet list while we redo it, so we don't get any
1875      screen updates while it happens. */
1876   packet_list_freeze();
1877
1878   if (redissect) {
1879     /* We need to re-initialize all the state information that protocols
1880        keep, because some preference that controls a dissector has changed,
1881        which might cause the state information to be constructed differently
1882        by that dissector. */
1883
1884     /* We might receive new packets while redissecting, and we don't
1885        want to dissect those before their time. */
1886     cf->redissecting = TRUE;
1887
1888     /* 'reset' dissection session */
1889     epan_free(cf->epan);
1890     cf->epan = ws_epan_new(cf);
1891
1892     /* We need to redissect the packets so we have to discard our old
1893      * packet list store. */
1894     packet_list_clear();
1895     add_to_packet_list = TRUE;
1896   }
1897
1898   /* We don't yet know which will be the first and last frames displayed. */
1899   cf->first_displayed = 0;
1900   cf->last_displayed = 0;
1901
1902   /* We currently don't display any packets */
1903   cf->displayed_count = 0;
1904
1905   /* Iterate through the list of frames.  Call a routine for each frame
1906      to check whether it should be displayed and, if so, add it to
1907      the display list. */
1908   cf->ref = NULL;
1909   cf->prev_dis = NULL;
1910   cf->prev_cap = NULL;
1911   cf->cum_bytes = 0;
1912
1913   /* Update the progress bar when it gets to this value. */
1914   progbar_nextstep = 0;
1915   /* When we reach the value that triggers a progress bar update,
1916      bump that value by this amount. */
1917   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
1918   /* Count of packets at which we've looked. */
1919   count = 0;
1920   /* Progress so far. */
1921   progbar_val = 0.0f;
1922
1923   stop_flag = FALSE;
1924   g_get_current_time(&start_time);
1925
1926   /* no previous row yet */
1927   prev_frame_num = -1;
1928   prev_frame = NULL;
1929
1930   preceding_frame_num = -1;
1931   preceding_frame = NULL;
1932   following_frame_num = -1;
1933   following_frame = NULL;
1934
1935   selected_frame_seen = FALSE;
1936
1937   frames_count = cf->count;
1938
1939   epan_dissect_init(&edt, cf->epan, create_proto_tree, FALSE);
1940
1941   for (framenum = 1; framenum <= frames_count; framenum++) {
1942     fdata = frame_data_sequence_find(cf->frames, framenum);
1943
1944     /* Create the progress bar if necessary.
1945        We check on every iteration of the loop, so that it takes no
1946        longer than the standard time to create it (otherwise, for a
1947        large file, we might take considerably longer than that standard
1948        time in order to get to the next progress bar step). */
1949     if (progbar == NULL)
1950       progbar = delayed_create_progress_dlg(cf->window, action, action_item, TRUE,
1951                                             &stop_flag, &start_time,
1952                                             progbar_val);
1953
1954     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1955        when we update it, we have to run the GTK+ main loop to get it
1956        to repaint what's pending, and doing so may involve an "ioctl()"
1957        to see if there's any pending input from an X server, and doing
1958        that for every packet can be costly, especially on a big file. */
1959     if (count >= progbar_nextstep) {
1960       /* let's not divide by zero. I should never be started
1961        * with count == 0, so let's assert that
1962        */
1963       g_assert(cf->count > 0);
1964       progbar_val = (gfloat) count / frames_count;
1965
1966       if (progbar != NULL) {
1967         g_snprintf(status_str, sizeof(status_str),
1968                   "%4u of %u frames", count, frames_count);
1969         update_progress_dlg(progbar, progbar_val, status_str);
1970       }
1971
1972       progbar_nextstep += progbar_quantum;
1973     }
1974
1975     if (stop_flag) {
1976       /* Well, the user decided to abort the filtering.  Just stop.
1977
1978          XXX - go back to the previous filter?  Users probably just
1979          want not to wait for a filtering operation to finish;
1980          unless we cancel by having no filter, reverting to the
1981          previous filter will probably be even more expensive than
1982          continuing the filtering, as it involves going back to the
1983          beginning and filtering, and even with no filter we currently
1984          have to re-generate the entire clist, which is also expensive.
1985
1986          I'm not sure what Network Monitor does, but it doesn't appear
1987          to give you an unfiltered display if you cancel. */
1988       break;
1989     }
1990
1991     count++;
1992
1993     if (redissect) {
1994       /* Since all state for the frame was destroyed, mark the frame
1995        * as not visited, free the GSList referring to the state
1996        * data (the per-frame data itself was freed by
1997        * "init_dissection()"), and null out the GSList pointer. */
1998       frame_data_reset(fdata);
1999       frames_count = cf->count;
2000     }
2001
2002     /* Frame dependencies from the previous dissection/filtering are no longer valid. */
2003     fdata->flags.dependent_of_displayed = 0;
2004
2005     if (!cf_read_frame(cf, fdata))
2006       break; /* error reading the frame */
2007
2008     /* If the previous frame is displayed, and we haven't yet seen the
2009        selected frame, remember that frame - it's the closest one we've
2010        yet seen before the selected frame. */
2011     if (prev_frame_num != -1 && !selected_frame_seen && prev_frame->flags.passed_dfilter) {
2012       preceding_frame_num = prev_frame_num;
2013       preceding_frame = prev_frame;
2014     }
2015
2016     add_packet_to_packet_list(fdata, cf, &edt, dfcode,
2017                                     cinfo, &cf->phdr,
2018                                     buffer_start_ptr(&cf->buf),
2019                                     add_to_packet_list);
2020
2021     /* If this frame is displayed, and this is the first frame we've
2022        seen displayed after the selected frame, remember this frame -
2023        it's the closest one we've yet seen at or after the selected
2024        frame. */
2025     if (fdata->flags.passed_dfilter && selected_frame_seen && following_frame_num == -1) {
2026       following_frame_num = fdata->num;
2027       following_frame = fdata;
2028     }
2029     if (fdata == selected_frame) {
2030       selected_frame_seen = TRUE;
2031       if (fdata->flags.passed_dfilter)
2032           selected_frame_num = fdata->num;
2033     }
2034
2035     /* Remember this frame - it'll be the previous frame
2036        on the next pass through the loop. */
2037     prev_frame_num = fdata->num;
2038     prev_frame = fdata;
2039   }
2040
2041   epan_dissect_cleanup(&edt);
2042
2043   /* We are done redissecting the packet list. */
2044   cf->redissecting = FALSE;
2045
2046   if (redissect) {
2047       frames_count = cf->count;
2048     /* Clear out what remains of the visited flags and per-frame data
2049        pointers.
2050
2051        XXX - that may cause various forms of bogosity when dissecting
2052        these frames, as they won't have been seen by this sequential
2053        pass, but the only alternative I see is to keep scanning them
2054        even though the user requested that the scan stop, and that
2055        would leave the user stuck with an Wireshark grinding on
2056        until it finishes.  Should we just stick them with that? */
2057     for (; framenum <= frames_count; framenum++) {
2058       fdata = frame_data_sequence_find(cf->frames, framenum);
2059       frame_data_reset(fdata);
2060     }
2061   }
2062
2063   /* We're done filtering the packets; destroy the progress bar if it
2064      was created. */
2065   if (progbar != NULL)
2066     destroy_progress_dlg(progbar);
2067
2068   /* Unfreeze the packet list. */
2069   if (!add_to_packet_list)
2070     packet_list_recreate_visible_rows();
2071
2072   /* Compute the time it took to filter the file */
2073   compute_elapsed(cf, &start_time);
2074
2075   packet_list_thaw();
2076
2077   if (selected_frame_num == -1) {
2078     /* The selected frame didn't pass the filter. */
2079     if (selected_frame == NULL) {
2080       /* That's because there *was* no selected frame.  Make the first
2081          displayed frame the current frame. */
2082       selected_frame_num = 0;
2083     } else {
2084       /* Find the nearest displayed frame to the selected frame (whether
2085          it's before or after that frame) and make that the current frame.
2086          If the next and previous displayed frames are equidistant from the
2087          selected frame, choose the next one. */
2088       g_assert(following_frame == NULL ||
2089                following_frame->num >= selected_frame->num);
2090       g_assert(preceding_frame == NULL ||
2091                preceding_frame->num <= selected_frame->num);
2092       if (following_frame == NULL) {
2093         /* No frame after the selected frame passed the filter, so we
2094            have to select the last displayed frame before the selected
2095            frame. */
2096         selected_frame_num = preceding_frame_num;
2097         selected_frame = preceding_frame;
2098       } else if (preceding_frame == NULL) {
2099         /* No frame before the selected frame passed the filter, so we
2100            have to select the first displayed frame after the selected
2101            frame. */
2102         selected_frame_num = following_frame_num;
2103         selected_frame = following_frame;
2104       } else {
2105         /* Frames before and after the selected frame passed the filter, so
2106            we'll select the previous frame */
2107         selected_frame_num = preceding_frame_num;
2108         selected_frame = preceding_frame;
2109       }
2110     }
2111   }
2112
2113   if (selected_frame_num == -1) {
2114     /* There are no frames displayed at all. */
2115     cf_unselect_packet(cf);
2116   } else {
2117     /* Either the frame that was selected passed the filter, or we've
2118        found the nearest displayed frame to that frame.  Select it, make
2119        it the focus row, and make it visible. */
2120     /* Set to invalid to force update of packet list and packet details */
2121     cf->current_row = -1;
2122     if (selected_frame_num == 0) {
2123       packet_list_select_first_row();
2124     }else{
2125       if (!packet_list_select_row_from_data(selected_frame)) {
2126         /* We didn't find a row corresponding to this frame.
2127            This means that the frame isn't being displayed currently,
2128            so we can't select it. */
2129         simple_message_box(ESD_TYPE_INFO, NULL,
2130                            "The capture file is probably not fully dissected.",
2131                            "End of capture exceeded!");
2132       }
2133     }
2134   }
2135
2136   /* Cleanup and release all dfilter resources */
2137   dfilter_free(dfcode);
2138 }
2139
2140
2141 /*
2142  * Scan trough all frame data and recalculate the ref time
2143  * without rereading the file.
2144  * XXX - do we need a progres bar or is this fast enough?
2145  */
2146 static void
2147 ref_time_packets(capture_file *cf)
2148 {
2149   guint32     framenum;
2150   frame_data *fdata;
2151   nstime_t rel_ts;
2152
2153   cf->ref = NULL;
2154   cf->prev_dis = NULL;
2155   cf->cum_bytes = 0;
2156
2157   for (framenum = 1; framenum <= cf->count; framenum++) {
2158     fdata = frame_data_sequence_find(cf->frames, framenum);
2159
2160     /* just add some value here until we know if it is being displayed or not */
2161     fdata->cum_bytes = cf->cum_bytes + fdata->pkt_len;
2162
2163     /*
2164      *Timestamps
2165      */
2166
2167     /* If we don't have the time stamp of the first packet in the
2168      capture, it's because this is the first packet.  Save the time
2169      stamp of this packet as the time stamp of the first packet. */
2170     if (cf->ref == NULL)
2171         cf->ref = fdata;
2172       /* if this frames is marked as a reference time frame, reset
2173         firstsec and firstusec to this frame */
2174     if (fdata->flags.ref_time)
2175         cf->ref = fdata;
2176
2177     /* If we don't have the time stamp of the previous displayed packet,
2178      it's because this is the first displayed packet.  Save the time
2179      stamp of this packet as the time stamp of the previous displayed
2180      packet. */
2181     if (cf->prev_dis == NULL) {
2182         cf->prev_dis = fdata;
2183     }
2184
2185     /* Get the time elapsed between the first packet and this packet. */
2186     fdata->frame_ref_num = (fdata != cf->ref) ? cf->ref->num : 0;
2187     nstime_delta(&rel_ts, &fdata->abs_ts, &cf->ref->abs_ts);
2188
2189     /* If it's greater than the current elapsed time, set the elapsed time
2190      to it (we check for "greater than" so as not to be confused by
2191      time moving backwards). */
2192     if ((gint32)cf->elapsed_time.secs < rel_ts.secs
2193         || ((gint32)cf->elapsed_time.secs == rel_ts.secs && (gint32)cf->elapsed_time.nsecs < rel_ts.nsecs)) {
2194         cf->elapsed_time = rel_ts;
2195     }
2196
2197     /* If this frame is displayed, get the time elapsed between the
2198      previous displayed packet and this packet. */
2199     if ( fdata->flags.passed_dfilter ) {
2200         fdata->prev_dis_num = cf->prev_dis->num;
2201         cf->prev_dis = fdata;
2202     }
2203
2204     /*
2205      * Byte counts
2206      */
2207     if ( (fdata->flags.passed_dfilter) || (fdata->flags.ref_time) ) {
2208         /* This frame either passed the display filter list or is marked as
2209         a time reference frame.  All time reference frames are displayed
2210         even if they dont pass the display filter */
2211         if (fdata->flags.ref_time) {
2212             /* if this was a TIME REF frame we should reset the cum_bytes field */
2213             cf->cum_bytes = fdata->pkt_len;
2214             fdata->cum_bytes = cf->cum_bytes;
2215         } else {
2216             /* increase cum_bytes with this packets length */
2217             cf->cum_bytes += fdata->pkt_len;
2218         }
2219     }
2220   }
2221 }
2222
2223 typedef enum {
2224   PSP_FINISHED,
2225   PSP_STOPPED,
2226   PSP_FAILED
2227 } psp_return_t;
2228
2229 static psp_return_t
2230 process_specified_packets(capture_file *cf, packet_range_t *range,
2231     const char *string1, const char *string2, gboolean terminate_is_stop,
2232     gboolean (*callback)(capture_file *, frame_data *,
2233                          struct wtap_pkthdr *, const guint8 *, void *),
2234     void *callback_args)
2235 {
2236   guint32          framenum;
2237   frame_data      *fdata;
2238   Buffer           buf;
2239   psp_return_t     ret     = PSP_FINISHED;
2240
2241   progdlg_t       *progbar = NULL;
2242   int              progbar_count;
2243   float            progbar_val;
2244   gboolean         progbar_stop_flag;
2245   GTimeVal         progbar_start_time;
2246   gchar            progbar_status_str[100];
2247   int              progbar_nextstep;
2248   int              progbar_quantum;
2249   range_process_e  process_this;
2250   struct wtap_pkthdr phdr;
2251
2252   memset(&phdr, 0, sizeof(struct wtap_pkthdr));
2253   buffer_init(&buf, 1500);
2254
2255   /* Update the progress bar when it gets to this value. */
2256   progbar_nextstep = 0;
2257   /* When we reach the value that triggers a progress bar update,
2258      bump that value by this amount. */
2259   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
2260   /* Count of packets at which we've looked. */
2261   progbar_count = 0;
2262   /* Progress so far. */
2263   progbar_val = 0.0f;
2264
2265   progbar_stop_flag = FALSE;
2266   g_get_current_time(&progbar_start_time);
2267
2268   if (range != NULL)
2269     packet_range_process_init(range);
2270
2271   /* Iterate through all the packets, printing the packets that
2272      were selected by the current display filter.  */
2273   for (framenum = 1; framenum <= cf->count; framenum++) {
2274     fdata = frame_data_sequence_find(cf->frames, framenum);
2275
2276     /* Create the progress bar if necessary.
2277        We check on every iteration of the loop, so that it takes no
2278        longer than the standard time to create it (otherwise, for a
2279        large file, we might take considerably longer than that standard
2280        time in order to get to the next progress bar step). */
2281     if (progbar == NULL)
2282       progbar = delayed_create_progress_dlg(cf->window, string1, string2,
2283                                             terminate_is_stop,
2284                                             &progbar_stop_flag,
2285                                             &progbar_start_time,
2286                                             progbar_val);
2287
2288     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
2289        when we update it, we have to run the GTK+ main loop to get it
2290        to repaint what's pending, and doing so may involve an "ioctl()"
2291        to see if there's any pending input from an X server, and doing
2292        that for every packet can be costly, especially on a big file. */
2293     if (progbar_count >= progbar_nextstep) {
2294       /* let's not divide by zero. I should never be started
2295        * with count == 0, so let's assert that
2296        */
2297       g_assert(cf->count > 0);
2298       progbar_val = (gfloat) progbar_count / cf->count;
2299
2300       if (progbar != NULL) {
2301         g_snprintf(progbar_status_str, sizeof(progbar_status_str),
2302                    "%4u of %u packets", progbar_count, cf->count);
2303         update_progress_dlg(progbar, progbar_val, progbar_status_str);
2304       }
2305
2306       progbar_nextstep += progbar_quantum;
2307     }
2308
2309     if (progbar_stop_flag) {
2310       /* Well, the user decided to abort the operation.  Just stop,
2311          and arrange to return PSP_STOPPED to our caller, so they know
2312          it was stopped explicitly. */
2313       ret = PSP_STOPPED;
2314       break;
2315     }
2316
2317     progbar_count++;
2318
2319     if (range != NULL) {
2320       /* do we have to process this packet? */
2321       process_this = packet_range_process_packet(range, fdata);
2322       if (process_this == range_process_next) {
2323         /* this packet uninteresting, continue with next one */
2324         continue;
2325       } else if (process_this == range_processing_finished) {
2326         /* all interesting packets processed, stop the loop */
2327         break;
2328       }
2329     }
2330
2331     /* Get the packet */
2332     if (!cf_read_frame_r(cf, fdata, &phdr, &buf)) {
2333       /* Attempt to get the packet failed. */
2334       ret = PSP_FAILED;
2335       break;
2336     }
2337     /* Process the packet */
2338     if (!callback(cf, fdata, &phdr, buffer_start_ptr(&buf), callback_args)) {
2339       /* Callback failed.  We assume it reported the error appropriately. */
2340       ret = PSP_FAILED;
2341       break;
2342     }
2343   }
2344
2345   /* We're done printing the packets; destroy the progress bar if
2346      it was created. */
2347   if (progbar != NULL)
2348     destroy_progress_dlg(progbar);
2349
2350   buffer_free(&buf);
2351
2352   return ret;
2353 }
2354
2355 typedef struct {
2356   epan_dissect_t edt;
2357   column_info *cinfo;
2358 } retap_callback_args_t;
2359
2360 static gboolean
2361 retap_packet(capture_file *cf _U_, frame_data *fdata,
2362              struct wtap_pkthdr *phdr, const guint8 *pd,
2363              void *argsp)
2364 {
2365   retap_callback_args_t *args = (retap_callback_args_t *)argsp;
2366
2367   epan_dissect_run_with_taps(&args->edt, phdr, frame_tvbuff_new(fdata, pd), fdata, args->cinfo);
2368   epan_dissect_reset(&args->edt);
2369
2370   return TRUE;
2371 }
2372
2373 cf_read_status_t
2374 cf_retap_packets(capture_file *cf)
2375 {
2376   packet_range_t        range;
2377   retap_callback_args_t callback_args;
2378   gboolean              construct_protocol_tree;
2379   gboolean              filtering_tap_listeners;
2380   guint                 tap_flags;
2381   psp_return_t          ret;
2382
2383   /* Do we have any tap listeners with filters? */
2384   filtering_tap_listeners = have_filtering_tap_listeners();
2385
2386   tap_flags = union_of_tap_listener_flags();
2387
2388   /* If any tap listeners have filters, or require the protocol tree,
2389      construct the protocol tree. */
2390   construct_protocol_tree = filtering_tap_listeners ||
2391                             (tap_flags & TL_REQUIRES_PROTO_TREE);
2392
2393   /* If any tap listeners require the columns, construct them. */
2394   callback_args.cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
2395
2396   /* Reset the tap listeners. */
2397   reset_tap_listeners();
2398
2399   epan_dissect_init(&callback_args.edt, cf->epan, construct_protocol_tree, FALSE);
2400
2401   /* Iterate through the list of packets, dissecting all packets and
2402      re-running the taps. */
2403   packet_range_init(&range, cf);
2404   packet_range_process_init(&range);
2405
2406   ret = process_specified_packets(cf, &range, "Recalculating statistics on",
2407                                   "all packets", TRUE, retap_packet,
2408                                   &callback_args);
2409
2410   epan_dissect_cleanup(&callback_args.edt);
2411
2412   switch (ret) {
2413   case PSP_FINISHED:
2414     /* Completed successfully. */
2415     return CF_READ_OK;
2416
2417   case PSP_STOPPED:
2418     /* Well, the user decided to abort the refiltering.
2419        Return CF_READ_ABORTED so our caller knows they did that. */
2420     return CF_READ_ABORTED;
2421
2422   case PSP_FAILED:
2423     /* Error while retapping. */
2424     return CF_READ_ERROR;
2425   }
2426
2427   g_assert_not_reached();
2428   return CF_READ_OK;
2429 }
2430
2431 typedef struct {
2432   print_args_t *print_args;
2433   gboolean      print_header_line;
2434   char         *header_line_buf;
2435   int           header_line_buf_len;
2436   gboolean      print_formfeed;
2437   gboolean      print_separator;
2438   char         *line_buf;
2439   int           line_buf_len;
2440   gint         *col_widths;
2441   int           num_visible_cols;
2442   gint         *visible_cols;
2443   epan_dissect_t edt;
2444 } print_callback_args_t;
2445
2446 static gboolean
2447 print_packet(capture_file *cf, frame_data *fdata,
2448              struct wtap_pkthdr *phdr, const guint8 *pd,
2449              void *argsp)
2450 {
2451   print_callback_args_t *args = (print_callback_args_t *)argsp;
2452   int             i;
2453   char           *cp;
2454   int             line_len;
2455   int             column_len;
2456   int             cp_off;
2457   char            bookmark_name[9+10+1];  /* "__frameNNNNNNNNNN__\0" */
2458   char            bookmark_title[6+10+1]; /* "Frame NNNNNNNNNN__\0"  */
2459
2460   /* Fill in the column information if we're printing the summary
2461      information. */
2462   if (args->print_args->print_summary) {
2463     col_custom_prime_edt(&args->edt, &cf->cinfo);
2464     epan_dissect_run(&args->edt, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
2465     epan_dissect_fill_in_columns(&args->edt, FALSE, TRUE);
2466   } else
2467     epan_dissect_run(&args->edt, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
2468
2469   if (args->print_formfeed) {
2470     if (!new_page(args->print_args->stream))
2471       goto fail;
2472   } else {
2473       if (args->print_separator) {
2474         if (!print_line(args->print_args->stream, 0, ""))
2475           goto fail;
2476       }
2477   }
2478
2479   /*
2480    * We generate bookmarks, if the output format supports them.
2481    * The name is "__frameN__".
2482    */
2483   g_snprintf(bookmark_name, sizeof bookmark_name, "__frame%u__", fdata->num);
2484
2485   if (args->print_args->print_summary) {
2486     if (!args->print_args->print_col_headings)
2487         args->print_header_line = FALSE;
2488     if (args->print_header_line) {
2489       if (!print_line(args->print_args->stream, 0, args->header_line_buf))
2490         goto fail;
2491       args->print_header_line = FALSE;  /* we might not need to print any more */
2492     }
2493     cp = &args->line_buf[0];
2494     line_len = 0;
2495     for (i = 0; i < args->num_visible_cols; i++) {
2496       /* Find the length of the string for this column. */
2497       column_len = (int) strlen(cf->cinfo.col_data[args->visible_cols[i]]);
2498       if (args->col_widths[i] > column_len)
2499          column_len = args->col_widths[i];
2500
2501       /* Make sure there's room in the line buffer for the column; if not,
2502          double its length. */
2503       line_len += column_len + 1;   /* "+1" for space */
2504       if (line_len > args->line_buf_len) {
2505         cp_off = (int) (cp - args->line_buf);
2506         args->line_buf_len = 2 * line_len;
2507         args->line_buf = (char *)g_realloc(args->line_buf, args->line_buf_len + 1);
2508         cp = args->line_buf + cp_off;
2509       }
2510
2511       /* Right-justify the packet number column. */
2512       if (cf->cinfo.col_fmt[args->visible_cols[i]] == COL_NUMBER)
2513         g_snprintf(cp, column_len+1, "%*s", args->col_widths[i], cf->cinfo.col_data[args->visible_cols[i]]);
2514       else
2515         g_snprintf(cp, column_len+1, "%-*s", args->col_widths[i], cf->cinfo.col_data[args->visible_cols[i]]);
2516       cp += column_len;
2517       if (i != args->num_visible_cols - 1)
2518         *cp++ = ' ';
2519     }
2520     *cp = '\0';
2521
2522     /*
2523      * Generate a bookmark, using the summary line as the title.
2524      */
2525     if (!print_bookmark(args->print_args->stream, bookmark_name,
2526                         args->line_buf))
2527       goto fail;
2528
2529     if (!print_line(args->print_args->stream, 0, args->line_buf))
2530       goto fail;
2531   } else {
2532     /*
2533      * Generate a bookmark, using "Frame N" as the title, as we're not
2534      * printing the summary line.
2535      */
2536     g_snprintf(bookmark_title, sizeof bookmark_title, "Frame %u", fdata->num);
2537     if (!print_bookmark(args->print_args->stream, bookmark_name,
2538                         bookmark_title))
2539       goto fail;
2540   } /* if (print_summary) */
2541
2542   if (args->print_args->print_dissections != print_dissections_none) {
2543     if (args->print_args->print_summary) {
2544       /* Separate the summary line from the tree with a blank line. */
2545       if (!print_line(args->print_args->stream, 0, ""))
2546         goto fail;
2547     }
2548
2549     /* Print the information in that tree. */
2550     if (!proto_tree_print(args->print_args, &args->edt, args->print_args->stream))
2551       goto fail;
2552
2553     /* Print a blank line if we print anything after this (aka more than one packet). */
2554     args->print_separator = TRUE;
2555
2556     /* Print a header line if we print any more packet summaries */
2557     if (args->print_args->print_col_headings)
2558         args->print_header_line = TRUE;
2559   }
2560
2561   if (args->print_args->print_hex) {
2562     if (args->print_args->print_summary || (args->print_args->print_dissections != print_dissections_none)) {
2563       if (!print_line(args->print_args->stream, 0, ""))
2564         goto fail;
2565     }
2566     /* Print the full packet data as hex. */
2567     if (!print_hex_data(args->print_args->stream, &args->edt))
2568       goto fail;
2569
2570     /* Print a blank line if we print anything after this (aka more than one packet). */
2571     args->print_separator = TRUE;
2572
2573     /* Print a header line if we print any more packet summaries */
2574     if (args->print_args->print_col_headings)
2575         args->print_header_line = TRUE;
2576   } /* if (args->print_args->print_dissections != print_dissections_none) */
2577
2578   epan_dissect_reset(&args->edt);
2579
2580   /* do we want to have a formfeed between each packet from now on? */
2581   if (args->print_args->print_formfeed) {
2582     args->print_formfeed = TRUE;
2583   }
2584
2585   return TRUE;
2586
2587 fail:
2588   epan_dissect_reset(&args->edt);
2589   return FALSE;
2590 }
2591
2592 cf_print_status_t
2593 cf_print_packets(capture_file *cf, print_args_t *print_args)
2594 {
2595   print_callback_args_t callback_args;
2596   gint          data_width;
2597   char         *cp;
2598   int           i, cp_off, column_len, line_len;
2599   int           num_visible_col = 0, last_visible_col = 0, visible_col_count;
2600   psp_return_t  ret;
2601   GList        *clp;
2602   fmt_data     *cfmt;
2603   gboolean      proto_tree_needed;
2604
2605   callback_args.print_args = print_args;
2606   callback_args.print_header_line = print_args->print_col_headings;
2607   callback_args.header_line_buf = NULL;
2608   callback_args.header_line_buf_len = 256;
2609   callback_args.print_formfeed = FALSE;
2610   callback_args.print_separator = FALSE;
2611   callback_args.line_buf = NULL;
2612   callback_args.line_buf_len = 256;
2613   callback_args.col_widths = NULL;
2614   callback_args.num_visible_cols = 0;
2615   callback_args.visible_cols = NULL;
2616
2617   if (!print_preamble(print_args->stream, cf->filename, wireshark_svnversion)) {
2618     destroy_print_stream(print_args->stream);
2619     return CF_PRINT_WRITE_ERROR;
2620   }
2621
2622   if (print_args->print_summary) {
2623     /* We're printing packet summaries.  Allocate the header line buffer
2624        and get the column widths. */
2625     callback_args.header_line_buf = (char *)g_malloc(callback_args.header_line_buf_len + 1);
2626
2627     /* Find the number of visible columns and the last visible column */
2628     for (i = 0; i < prefs.num_cols; i++) {
2629
2630         clp = g_list_nth(prefs.col_list, i);
2631         if (clp == NULL) /* Sanity check, Invalid column requested */
2632             continue;
2633
2634         cfmt = (fmt_data *) clp->data;
2635         if (cfmt->visible) {
2636             num_visible_col++;
2637             last_visible_col = i;
2638         }
2639     }
2640
2641     /* Find the widths for each of the columns - maximum of the
2642        width of the title and the width of the data - and construct
2643        a buffer with a line containing the column titles. */
2644     callback_args.num_visible_cols = num_visible_col;
2645     callback_args.col_widths = (gint *) g_malloc(sizeof(gint) * num_visible_col);
2646     callback_args.visible_cols = (gint *) g_malloc(sizeof(gint) * num_visible_col);
2647     cp = &callback_args.header_line_buf[0];
2648     line_len = 0;
2649     visible_col_count = 0;
2650     for (i = 0; i < cf->cinfo.num_cols; i++) {
2651
2652       clp = g_list_nth(prefs.col_list, i);
2653       if (clp == NULL) /* Sanity check, Invalid column requested */
2654           continue;
2655
2656       cfmt = (fmt_data *) clp->data;
2657       if (cfmt->visible == FALSE)
2658           continue;
2659
2660       /* Save the order of visible columns */
2661       callback_args.visible_cols[visible_col_count] = i;
2662
2663       /* Don't pad the last column. */
2664       if (i == last_visible_col)
2665         callback_args.col_widths[visible_col_count] = 0;
2666       else {
2667         callback_args.col_widths[visible_col_count] = (gint) strlen(cf->cinfo.col_title[i]);
2668         data_width = get_column_char_width(get_column_format(i));
2669         if (data_width > callback_args.col_widths[visible_col_count])
2670           callback_args.col_widths[visible_col_count] = data_width;
2671       }
2672
2673       /* Find the length of the string for this column. */
2674       column_len = (int) strlen(cf->cinfo.col_title[i]);
2675       if (callback_args.col_widths[i] > column_len)
2676         column_len = callback_args.col_widths[visible_col_count];
2677
2678       /* Make sure there's room in the line buffer for the column; if not,
2679          double its length. */
2680       line_len += column_len + 1;   /* "+1" for space */
2681       if (line_len > callback_args.header_line_buf_len) {
2682         cp_off = (int) (cp - callback_args.header_line_buf);
2683         callback_args.header_line_buf_len = 2 * line_len;
2684         callback_args.header_line_buf = (char *)g_realloc(callback_args.header_line_buf,
2685                                                   callback_args.header_line_buf_len + 1);
2686         cp = callback_args.header_line_buf + cp_off;
2687       }
2688
2689       /* Right-justify the packet number column. */
2690 /*      if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2691         g_snprintf(cp, column_len+1, "%*s", callback_args.col_widths[visible_col_count], cf->cinfo.col_title[i]);
2692       else*/
2693       g_snprintf(cp, column_len+1, "%-*s", callback_args.col_widths[visible_col_count], cf->cinfo.col_title[i]);
2694       cp += column_len;
2695       if (i != cf->cinfo.num_cols - 1)
2696         *cp++ = ' ';
2697
2698       visible_col_count++;
2699     }
2700     *cp = '\0';
2701
2702     /* Now start out the main line buffer with the same length as the
2703        header line buffer. */
2704     callback_args.line_buf_len = callback_args.header_line_buf_len;
2705     callback_args.line_buf = (char *)g_malloc(callback_args.line_buf_len + 1);
2706   } /* if (print_summary) */
2707
2708   /* Create the protocol tree, and make it visible, if we're printing
2709      the dissection or the hex data.
2710      XXX - do we need it if we're just printing the hex data? */
2711   proto_tree_needed =
2712       callback_args.print_args->print_dissections != print_dissections_none ||
2713       callback_args.print_args->print_hex ||
2714       have_custom_cols(&cf->cinfo);
2715   epan_dissect_init(&callback_args.edt, cf->epan, proto_tree_needed, proto_tree_needed);
2716
2717   /* Iterate through the list of packets, printing the packets we were
2718      told to print. */
2719   ret = process_specified_packets(cf, &print_args->range, "Printing",
2720                                   "selected packets", TRUE, print_packet,
2721                                   &callback_args);
2722   epan_dissect_cleanup(&callback_args.edt);
2723   g_free(callback_args.header_line_buf);
2724   g_free(callback_args.line_buf);
2725   g_free(callback_args.col_widths);
2726   g_free(callback_args.visible_cols);
2727
2728   switch (ret) {
2729
2730   case PSP_FINISHED:
2731     /* Completed successfully. */
2732     break;
2733
2734   case PSP_STOPPED:
2735     /* Well, the user decided to abort the printing.
2736
2737        XXX - note that what got generated before they did that
2738        will get printed if we're piping to a print program; we'd
2739        have to write to a file and then hand that to the print
2740        program to make it actually not print anything. */
2741     break;
2742
2743   case PSP_FAILED:
2744     /* Error while printing.
2745
2746        XXX - note that what got generated before they did that
2747        will get printed if we're piping to a print program; we'd
2748        have to write to a file and then hand that to the print
2749        program to make it actually not print anything. */
2750     destroy_print_stream(print_args->stream);
2751     return CF_PRINT_WRITE_ERROR;
2752   }
2753
2754   if (!print_finale(print_args->stream)) {
2755     destroy_print_stream(print_args->stream);
2756     return CF_PRINT_WRITE_ERROR;
2757   }
2758
2759   if (!destroy_print_stream(print_args->stream))
2760     return CF_PRINT_WRITE_ERROR;
2761
2762   return CF_PRINT_OK;
2763 }
2764
2765 typedef struct {
2766   FILE *fh;
2767   epan_dissect_t edt;
2768 } write_packet_callback_args_t;
2769
2770 static gboolean
2771 write_pdml_packet(capture_file *cf _U_, frame_data *fdata,
2772                   struct wtap_pkthdr *phdr, const guint8 *pd,
2773           void *argsp)
2774 {
2775   write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
2776
2777   /* Create the protocol tree, but don't fill in the column information. */
2778   epan_dissect_run(&args->edt, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
2779
2780   /* Write out the information in that tree. */
2781   proto_tree_write_pdml(&args->edt, args->fh);
2782
2783   epan_dissect_reset(&args->edt);
2784
2785   return !ferror(args->fh);
2786 }
2787
2788 cf_print_status_t
2789 cf_write_pdml_packets(capture_file *cf, print_args_t *print_args)
2790 {
2791   write_packet_callback_args_t callback_args;
2792   FILE         *fh;
2793   psp_return_t  ret;
2794
2795   fh = ws_fopen(print_args->file, "w");
2796   if (fh == NULL)
2797     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2798
2799   write_pdml_preamble(fh, cf->filename);
2800   if (ferror(fh)) {
2801     fclose(fh);
2802     return CF_PRINT_WRITE_ERROR;
2803   }
2804
2805   callback_args.fh = fh;
2806   epan_dissect_init(&callback_args.edt, cf->epan, TRUE, TRUE);
2807
2808   /* Iterate through the list of packets, printing the packets we were
2809      told to print. */
2810   ret = process_specified_packets(cf, &print_args->range, "Writing PDML",
2811                                   "selected packets", TRUE,
2812                                   write_pdml_packet, &callback_args);
2813
2814   epan_dissect_cleanup(&callback_args.edt);
2815
2816   switch (ret) {
2817
2818   case PSP_FINISHED:
2819     /* Completed successfully. */
2820     break;
2821
2822   case PSP_STOPPED:
2823     /* Well, the user decided to abort the printing. */
2824     break;
2825
2826   case PSP_FAILED:
2827     /* Error while printing. */
2828     fclose(fh);
2829     return CF_PRINT_WRITE_ERROR;
2830   }
2831
2832   write_pdml_finale(fh);
2833   if (ferror(fh)) {
2834     fclose(fh);
2835     return CF_PRINT_WRITE_ERROR;
2836   }
2837
2838   /* XXX - check for an error */
2839   fclose(fh);
2840
2841   return CF_PRINT_OK;
2842 }
2843
2844 static gboolean
2845 write_psml_packet(capture_file *cf, frame_data *fdata,
2846                   struct wtap_pkthdr *phdr, const guint8 *pd,
2847           void *argsp)
2848 {
2849   write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
2850
2851   col_custom_prime_edt(&args->edt, &cf->cinfo);
2852   epan_dissect_run(&args->edt, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
2853   epan_dissect_fill_in_columns(&args->edt, FALSE, TRUE);
2854
2855   /* Write out the information in that tree. */
2856   proto_tree_write_psml(&args->edt, args->fh);
2857
2858   epan_dissect_reset(&args->edt);
2859
2860   return !ferror(args->fh);
2861 }
2862
2863 cf_print_status_t
2864 cf_write_psml_packets(capture_file *cf, print_args_t *print_args)
2865 {
2866   write_packet_callback_args_t callback_args;
2867   FILE         *fh;
2868   psp_return_t  ret;
2869
2870   gboolean proto_tree_needed;
2871
2872   fh = ws_fopen(print_args->file, "w");
2873   if (fh == NULL)
2874     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2875
2876   write_psml_preamble(fh);
2877   if (ferror(fh)) {
2878     fclose(fh);
2879     return CF_PRINT_WRITE_ERROR;
2880   }
2881
2882   callback_args.fh = fh;
2883
2884   /* Fill in the column information, only create the protocol tree
2885      if having custom columns. */
2886   proto_tree_needed = have_custom_cols(&cf->cinfo);
2887   epan_dissect_init(&callback_args.edt, cf->epan, proto_tree_needed, proto_tree_needed);
2888
2889   /* Iterate through the list of packets, printing the packets we were
2890      told to print. */
2891   ret = process_specified_packets(cf, &print_args->range, "Writing PSML",
2892                                   "selected packets", TRUE,
2893                                   write_psml_packet, &callback_args);
2894
2895   epan_dissect_cleanup(&callback_args.edt);
2896
2897   switch (ret) {
2898
2899   case PSP_FINISHED:
2900     /* Completed successfully. */
2901     break;
2902
2903   case PSP_STOPPED:
2904     /* Well, the user decided to abort the printing. */
2905     break;
2906
2907   case PSP_FAILED:
2908     /* Error while printing. */
2909     fclose(fh);
2910     return CF_PRINT_WRITE_ERROR;
2911   }
2912
2913   write_psml_finale(fh);
2914   if (ferror(fh)) {
2915     fclose(fh);
2916     return CF_PRINT_WRITE_ERROR;
2917   }
2918
2919   /* XXX - check for an error */
2920   fclose(fh);
2921
2922   return CF_PRINT_OK;
2923 }
2924
2925 static gboolean
2926 write_csv_packet(capture_file *cf, frame_data *fdata,
2927                  struct wtap_pkthdr *phdr, const guint8 *pd,
2928                  void *argsp)
2929 {
2930   write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
2931
2932   /* Fill in the column information */
2933   col_custom_prime_edt(&args->edt, &cf->cinfo);
2934   epan_dissect_run(&args->edt, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
2935   epan_dissect_fill_in_columns(&args->edt, FALSE, TRUE);
2936
2937   /* Write out the information in that tree. */
2938   proto_tree_write_csv(&args->edt, args->fh);
2939
2940   epan_dissect_reset(&args->edt);
2941
2942   return !ferror(args->fh);
2943 }
2944
2945 cf_print_status_t
2946 cf_write_csv_packets(capture_file *cf, print_args_t *print_args)
2947 {
2948   write_packet_callback_args_t callback_args;
2949   gboolean        proto_tree_needed;
2950   FILE         *fh;
2951   psp_return_t  ret;
2952
2953   fh = ws_fopen(print_args->file, "w");
2954   if (fh == NULL)
2955     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2956
2957   write_csv_preamble(fh);
2958   if (ferror(fh)) {
2959     fclose(fh);
2960     return CF_PRINT_WRITE_ERROR;
2961   }
2962
2963   callback_args.fh = fh;
2964
2965   /* only create the protocol tree if having custom columns. */
2966   proto_tree_needed = have_custom_cols(&cf->cinfo);
2967   epan_dissect_init(&callback_args.edt, cf->epan, proto_tree_needed, proto_tree_needed);
2968
2969   /* Iterate through the list of packets, printing the packets we were
2970      told to print. */
2971   ret = process_specified_packets(cf, &print_args->range, "Writing CSV",
2972                                   "selected packets", TRUE,
2973                                   write_csv_packet, &callback_args);
2974
2975   epan_dissect_cleanup(&callback_args.edt);
2976
2977   switch (ret) {
2978
2979   case PSP_FINISHED:
2980     /* Completed successfully. */
2981     break;
2982
2983   case PSP_STOPPED:
2984     /* Well, the user decided to abort the printing. */
2985     break;
2986
2987   case PSP_FAILED:
2988     /* Error while printing. */
2989     fclose(fh);
2990     return CF_PRINT_WRITE_ERROR;
2991   }
2992
2993   write_csv_finale(fh);
2994   if (ferror(fh)) {
2995     fclose(fh);
2996     return CF_PRINT_WRITE_ERROR;
2997   }
2998
2999   /* XXX - check for an error */
3000   fclose(fh);
3001
3002   return CF_PRINT_OK;
3003 }
3004
3005 static gboolean
3006 write_carrays_packet(capture_file *cf _U_, frame_data *fdata,
3007              struct wtap_pkthdr *phdr,
3008              const guint8 *pd, void *argsp)
3009 {
3010   write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
3011
3012   epan_dissect_run(&args->edt, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
3013   proto_tree_write_carrays(fdata->num, args->fh, &args->edt);
3014   epan_dissect_reset(&args->edt);
3015
3016   return !ferror(args->fh);
3017 }
3018
3019 cf_print_status_t
3020 cf_write_carrays_packets(capture_file *cf, print_args_t *print_args)
3021 {
3022   write_packet_callback_args_t callback_args;
3023   FILE         *fh;
3024   psp_return_t  ret;
3025
3026   fh = ws_fopen(print_args->file, "w");
3027
3028   if (fh == NULL)
3029     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
3030
3031   write_carrays_preamble(fh);
3032
3033   if (ferror(fh)) {
3034     fclose(fh);
3035     return CF_PRINT_WRITE_ERROR;
3036   }
3037
3038   callback_args.fh = fh;
3039   epan_dissect_init(&callback_args.edt, cf->epan, TRUE, TRUE);
3040
3041   /* Iterate through the list of packets, printing the packets we were
3042      told to print. */
3043   ret = process_specified_packets(cf, &print_args->range,
3044                   "Writing C Arrays",
3045                   "selected packets", TRUE,
3046                                   write_carrays_packet, &callback_args);
3047
3048   epan_dissect_cleanup(&callback_args.edt);
3049
3050   switch (ret) {
3051   case PSP_FINISHED:
3052     /* Completed successfully. */
3053     break;
3054   case PSP_STOPPED:
3055     /* Well, the user decided to abort the printing. */
3056     break;
3057   case PSP_FAILED:
3058     /* Error while printing. */
3059     fclose(fh);
3060     return CF_PRINT_WRITE_ERROR;
3061   }
3062
3063   write_carrays_finale(fh);
3064
3065   if (ferror(fh)) {
3066     fclose(fh);
3067     return CF_PRINT_WRITE_ERROR;
3068   }
3069
3070   fclose(fh);
3071   return CF_PRINT_OK;
3072 }
3073
3074 gboolean
3075 cf_find_packet_protocol_tree(capture_file *cf, const char *string,
3076                              search_direction dir)
3077 {
3078   match_data mdata;
3079
3080   mdata.string = string;
3081   mdata.string_len = strlen(string);
3082   return find_packet(cf, match_protocol_tree, &mdata, dir);
3083 }
3084
3085 gboolean
3086 cf_find_string_protocol_tree(capture_file *cf, proto_tree *tree,  match_data *mdata)
3087 {
3088   mdata->frame_matched = FALSE;
3089   mdata->string = convert_string_case(cf->sfilter, cf->case_type);
3090   mdata->string_len = strlen(mdata->string);
3091   mdata->cf = cf;
3092   /* Iterate through all the nodes looking for matching text */
3093   proto_tree_children_foreach(tree, match_subtree_text, mdata);
3094   return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
3095 }
3096
3097 static match_result
3098 match_protocol_tree(capture_file *cf, frame_data *fdata, void *criterion)
3099 {
3100   match_data     *mdata = (match_data *)criterion;
3101   epan_dissect_t  edt;
3102
3103   /* Load the frame's data. */
3104   if (!cf_read_frame(cf, fdata)) {
3105     /* Attempt to get the packet failed. */
3106     return MR_ERROR;
3107   }
3108
3109   /* Construct the protocol tree, including the displayed text */
3110   epan_dissect_init(&edt, cf->epan, TRUE, TRUE);
3111   /* We don't need the column information */
3112   epan_dissect_run(&edt, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata, NULL);
3113
3114   /* Iterate through all the nodes, seeing if they have text that matches. */
3115   mdata->cf = cf;
3116   mdata->frame_matched = FALSE;
3117   proto_tree_children_foreach(edt.tree, match_subtree_text, mdata);
3118   epan_dissect_cleanup(&edt);
3119   return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
3120 }
3121
3122 static void
3123 match_subtree_text(proto_node *node, gpointer data)
3124 {
3125   match_data   *mdata      = (match_data *) data;
3126   const gchar  *string     = mdata->string;
3127   size_t        string_len = mdata->string_len;
3128   capture_file *cf         = mdata->cf;
3129   field_info   *fi         = PNODE_FINFO(node);
3130   gchar         label_str[ITEM_LABEL_LENGTH];
3131   gchar        *label_ptr;
3132   size_t        label_len;
3133   guint32       i;
3134   guint8        c_char;
3135   size_t        c_match    = 0;
3136
3137   /* dissection with an invisible proto tree? */
3138   g_assert(fi);
3139
3140   if (mdata->frame_matched) {
3141     /* We already had a match; don't bother doing any more work. */
3142     return;
3143   }
3144
3145   /* Don't match invisible entries. */
3146   if (PROTO_ITEM_IS_HIDDEN(node))
3147     return;
3148
3149   /* was a free format label produced? */
3150   if (fi->rep) {
3151     label_ptr = fi->rep->representation;
3152   } else {
3153     /* no, make a generic label */
3154     label_ptr = label_str;
3155     proto_item_fill_label(fi, label_str);
3156   }
3157
3158   /* Does that label match? */
3159   label_len = strlen(label_ptr);
3160   for (i = 0; i < label_len; i++) {
3161     c_char = label_ptr[i];
3162     if (cf->case_type)
3163       c_char = toupper(c_char);
3164     if (c_char == string[c_match]) {
3165       c_match++;
3166       if (c_match == string_len) {
3167         /* No need to look further; we have a match */
3168         mdata->frame_matched = TRUE;
3169         mdata->finfo = fi;
3170         return;
3171       }
3172     } else
3173       c_match = 0;
3174   }
3175
3176   /* Recurse into the subtree, if it exists */
3177   if (node->first_child != NULL)
3178     proto_tree_children_foreach(node, match_subtree_text, mdata);
3179 }
3180
3181 gboolean
3182 cf_find_packet_summary_line(capture_file *cf, const char *string,
3183                             search_direction dir)
3184 {
3185   match_data mdata;
3186
3187   mdata.string = string;
3188   mdata.string_len = strlen(string);
3189   return find_packet(cf, match_summary_line, &mdata, dir);
3190 }
3191
3192 static match_result
3193 match_summary_line(capture_file *cf, frame_data *fdata, void *criterion)
3194 {
3195   match_data     *mdata      = (match_data *)criterion;
3196   const gchar    *string     = mdata->string;
3197   size_t          string_len = mdata->string_len;
3198   epan_dissect_t  edt;
3199   const char     *info_column;
3200   size_t          info_column_len;
3201   match_result    result     = MR_NOTMATCHED;
3202   gint            colx;
3203   guint32         i;
3204   guint8          c_char;
3205   size_t          c_match    = 0;
3206
3207   /* Load the frame's data. */
3208   if (!cf_read_frame(cf, fdata)) {
3209     /* Attempt to get the packet failed. */
3210     return MR_ERROR;
3211   }
3212
3213   /* Don't bother constructing the protocol tree */
3214   epan_dissect_init(&edt, cf->epan, FALSE, FALSE);
3215   /* Get the column information */
3216   epan_dissect_run(&edt, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata,
3217                    &cf->cinfo);
3218
3219   /* Find the Info column */
3220   for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
3221     if (cf->cinfo.fmt_matx[colx][COL_INFO]) {
3222       /* Found it.  See if we match. */
3223       info_column = edt.pi.cinfo->col_data[colx];
3224       info_column_len = strlen(info_column);
3225       for (i = 0; i < info_column_len; i++) {
3226         c_char = info_column[i];
3227         if (cf->case_type)
3228           c_char = toupper(c_char);
3229         if (c_char == string[c_match]) {
3230           c_match++;
3231           if (c_match == string_len) {
3232             result = MR_MATCHED;
3233             break;
3234           }
3235         } else
3236           c_match = 0;
3237       }
3238       break;
3239     }
3240   }
3241   epan_dissect_cleanup(&edt);
3242   return result;
3243 }
3244
3245 typedef struct {
3246     const guint8 *data;
3247     size_t        data_len;
3248 } cbs_t;    /* "Counted byte string" */
3249
3250
3251 /*
3252  * The current match_* routines only support ASCII case insensitivity and don't
3253  * convert UTF-8 inputs to UTF-16 for matching.
3254  *
3255  * We could modify them to use the GLib Unicode routines or the International
3256  * Components for Unicode library but it's not apparent that we could do so
3257  * without consuming a lot more CPU and memory or that searching would be
3258  * significantly better.
3259  */
3260
3261 gboolean
3262 cf_find_packet_data(capture_file *cf, const guint8 *string, size_t string_size,
3263                     search_direction dir)
3264 {
3265   cbs_t info;
3266
3267   info.data = string;
3268   info.data_len = string_size;
3269
3270   /* String or hex search? */
3271   if (cf->string) {
3272     /* String search - what type of string? */
3273     switch (cf->scs_type) {
3274
3275     case SCS_NARROW_AND_WIDE:
3276       return find_packet(cf, match_narrow_and_wide, &info, dir);
3277
3278     case SCS_NARROW:
3279       return find_packet(cf, match_narrow, &info, dir);
3280
3281     case SCS_WIDE:
3282       return find_packet(cf, match_wide, &info, dir);
3283
3284     default:
3285       g_assert_not_reached();
3286       return FALSE;
3287     }
3288   } else
3289     return find_packet(cf, match_binary, &info, dir);
3290 }
3291
3292 static match_result
3293 match_narrow_and_wide(capture_file *cf, frame_data *fdata, void *criterion)
3294 {
3295   cbs_t        *info       = (cbs_t *)criterion;
3296   const guint8 *ascii_text = info->data;
3297   size_t        textlen    = info->data_len;
3298   match_result  result;
3299   guint32       buf_len;
3300   guint8       *pd;
3301   guint32       i;
3302   guint8        c_char;
3303   size_t        c_match    = 0;
3304
3305   /* Load the frame's data. */
3306   if (!cf_read_frame(cf, fdata)) {
3307     /* Attempt to get the packet failed. */
3308     return MR_ERROR;
3309   }
3310
3311   result = MR_NOTMATCHED;
3312   buf_len = fdata->cap_len;
3313   pd = buffer_start_ptr(&cf->buf);
3314   i = 0;
3315   while (i < buf_len) {
3316     c_char = pd[i];
3317     if (cf->case_type)
3318       c_char = toupper(c_char);
3319     if (c_char != '\0') {
3320       if (c_char == ascii_text[c_match]) {
3321         c_match += 1;
3322         if (c_match == textlen) {
3323           result = MR_MATCHED;
3324           cf->search_pos = i; /* Save the position of the last character
3325                                  for highlighting the field. */
3326           break;
3327         }
3328       }
3329       else {
3330         g_assert(i>=c_match);
3331         i -= (guint32)c_match;
3332         c_match = 0;
3333       }
3334     }
3335     i += 1;
3336   }
3337   return result;
3338 }
3339
3340 static match_result
3341 match_narrow(capture_file *cf, frame_data *fdata, void *criterion)
3342 {
3343   guint8       *pd;
3344   cbs_t        *info       = (cbs_t *)criterion;
3345   const guint8 *ascii_text = info->data;
3346   size_t        textlen    = info->data_len;
3347   match_result  result;
3348   guint32       buf_len;
3349   guint32       i;
3350   guint8        c_char;
3351   size_t        c_match    = 0;
3352
3353   /* Load the frame's data. */
3354   if (!cf_read_frame(cf, fdata)) {
3355     /* Attempt to get the packet failed. */
3356     return MR_ERROR;
3357   }
3358
3359   result = MR_NOTMATCHED;
3360   buf_len = fdata->cap_len;
3361   pd = buffer_start_ptr(&cf->buf);
3362   i = 0;
3363   while (i < buf_len) {
3364     c_char = pd[i];
3365     if (cf->case_type)
3366       c_char = toupper(c_char);
3367     if (c_char == ascii_text[c_match]) {
3368       c_match += 1;
3369       if (c_match == textlen) {
3370         result = MR_MATCHED;
3371         cf->search_pos = i; /* Save the position of the last character
3372                                for highlighting the field. */
3373         break;
3374       }
3375     }
3376     else {
3377       g_assert(i>=c_match);
3378       i -= (guint32)c_match;
3379       c_match = 0;
3380     }
3381     i += 1;
3382   }
3383
3384   return result;
3385 }
3386
3387 static match_result
3388 match_wide(capture_file *cf, frame_data *fdata, void *criterion)
3389 {
3390   cbs_t        *info       = (cbs_t *)criterion;
3391   const guint8 *ascii_text = info->data;
3392   size_t        textlen    = info->data_len;
3393   match_result  result;
3394   guint32       buf_len;
3395   guint8       *pd;
3396   guint32       i;
3397   guint8        c_char;
3398   size_t        c_match    = 0;
3399
3400   /* Load the frame's data. */
3401   if (!cf_read_frame(cf, fdata)) {
3402     /* Attempt to get the packet failed. */
3403     return MR_ERROR;
3404   }
3405
3406   result = MR_NOTMATCHED;
3407   buf_len = fdata->cap_len;
3408   pd = buffer_start_ptr(&cf->buf);
3409   i = 0;
3410   while (i < buf_len) {
3411     c_char = pd[i];
3412     if (cf->case_type)
3413       c_char = toupper(c_char);
3414     if (c_char == ascii_text[c_match]) {
3415       c_match += 1;
3416       if (c_match == textlen) {
3417         result = MR_MATCHED;
3418         cf->search_pos = i; /* Save the position of the last character
3419                                for highlighting the field. */
3420         break;
3421       }
3422       i += 1;
3423     }
3424     else {
3425       g_assert(i>=(c_match*2));
3426       i -= (guint32)c_match*2;
3427       c_match = 0;
3428     }
3429     i += 1;
3430   }
3431   return result;
3432 }
3433
3434 static match_result
3435 match_binary(capture_file *cf, frame_data *fdata, void *criterion)
3436 {
3437   cbs_t        *info        = (cbs_t *)criterion;
3438   const guint8 *binary_data = info->data;
3439   size_t        datalen     = info->data_len;
3440   match_result  result;
3441   guint32       buf_len;
3442   guint8       *pd;
3443   guint32       i;
3444   size_t        c_match     = 0;
3445
3446   /* Load the frame's data. */
3447   if (!cf_read_frame(cf, fdata)) {
3448     /* Attempt to get the packet failed. */
3449     return MR_ERROR;
3450   }
3451
3452   result = MR_NOTMATCHED;
3453   buf_len = fdata->cap_len;
3454   pd = buffer_start_ptr(&cf->buf);
3455   i = 0;
3456   while (i < buf_len) {
3457     if (pd[i] == binary_data[c_match]) {
3458       c_match += 1;
3459       if (c_match == datalen) {
3460         result = MR_MATCHED;
3461         cf->search_pos = i; /* Save the position of the last character
3462                                for highlighting the field. */
3463         break;
3464       }
3465     }
3466     else {
3467       g_assert(i>=c_match);
3468       i -= (guint32)c_match;
3469       c_match = 0;
3470     }
3471     i += 1;
3472   }
3473   return result;
3474 }
3475
3476 gboolean
3477 cf_find_packet_dfilter(capture_file *cf, dfilter_t *sfcode,
3478                        search_direction dir)
3479 {
3480   return find_packet(cf, match_dfilter, sfcode, dir);
3481 }
3482
3483 gboolean
3484 cf_find_packet_dfilter_string(capture_file *cf, const char *filter,
3485                               search_direction dir)
3486 {
3487   dfilter_t *sfcode;
3488   gboolean   result;
3489
3490   if (!dfilter_compile(filter, &sfcode)) {
3491      /*
3492       * XXX - this shouldn't happen, as the filter string is machine
3493       * generated
3494       */
3495     return FALSE;
3496   }
3497   if (sfcode == NULL) {
3498     /*
3499      * XXX - this shouldn't happen, as the filter string is machine
3500      * generated.
3501      */
3502     return FALSE;
3503   }
3504   result = find_packet(cf, match_dfilter, sfcode, dir);
3505   dfilter_free(sfcode);
3506   return result;
3507 }
3508
3509 static match_result
3510 match_dfilter(capture_file *cf, frame_data *fdata, void *criterion)
3511 {
3512   dfilter_t      *sfcode = (dfilter_t *)criterion;
3513   epan_dissect_t  edt;
3514   match_result    result;
3515
3516   /* Load the frame's data. */
3517   if (!cf_read_frame(cf, fdata)) {
3518     /* Attempt to get the packet failed. */
3519     return MR_ERROR;
3520   }
3521
3522   epan_dissect_init(&edt, cf->epan, TRUE, FALSE);
3523   epan_dissect_prime_dfilter(&edt, sfcode);
3524   epan_dissect_run(&edt, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata, NULL);
3525   result = dfilter_apply_edt(sfcode, &edt) ? MR_MATCHED : MR_NOTMATCHED;
3526   epan_dissect_cleanup(&edt);
3527   return result;
3528 }
3529
3530 gboolean
3531 cf_find_packet_marked(capture_file *cf, search_direction dir)
3532 {
3533   return find_packet(cf, match_marked, NULL, dir);
3534 }
3535
3536 static match_result
3537 match_marked(capture_file *cf _U_, frame_data *fdata, void *criterion _U_)
3538 {
3539   return fdata->flags.marked ? MR_MATCHED : MR_NOTMATCHED;
3540 }
3541
3542 gboolean
3543 cf_find_packet_time_reference(capture_file *cf, search_direction dir)
3544 {
3545   return find_packet(cf, match_time_reference, NULL, dir);
3546 }
3547
3548 static match_result
3549 match_time_reference(capture_file *cf _U_, frame_data *fdata, void *criterion _U_)
3550 {
3551   return fdata->flags.ref_time ? MR_MATCHED : MR_NOTMATCHED;
3552 }
3553
3554 static gboolean
3555 find_packet(capture_file *cf,
3556             match_result (*match_function)(capture_file *, frame_data *, void *),
3557             void *criterion, search_direction dir)
3558 {
3559   frame_data  *start_fd;
3560   guint32      framenum;
3561   frame_data  *fdata;
3562   frame_data  *new_fd = NULL;
3563   progdlg_t   *progbar = NULL;
3564   gboolean     stop_flag;
3565   int          count;
3566   gboolean     found;
3567   float        progbar_val;
3568   GTimeVal     start_time;
3569   gchar        status_str[100];
3570   int          progbar_nextstep;
3571   int          progbar_quantum;
3572   const char  *title;
3573   match_result result;
3574
3575   start_fd = cf->current_frame;
3576   if (start_fd != NULL)  {
3577     /* Iterate through the list of packets, starting at the packet we've
3578        picked, calling a routine to run the filter on the packet, see if
3579        it matches, and stop if so.  */
3580     count = 0;
3581     framenum = start_fd->num;
3582
3583     /* Update the progress bar when it gets to this value. */
3584     progbar_nextstep = 0;
3585     /* When we reach the value that triggers a progress bar update,
3586        bump that value by this amount. */
3587     progbar_quantum = cf->count/N_PROGBAR_UPDATES;
3588     /* Progress so far. */
3589     progbar_val = 0.0f;
3590
3591     stop_flag = FALSE;
3592     g_get_current_time(&start_time);
3593
3594     title = cf->sfilter?cf->sfilter:"";
3595     for (;;) {
3596       /* Create the progress bar if necessary.
3597          We check on every iteration of the loop, so that it takes no
3598          longer than the standard time to create it (otherwise, for a
3599          large file, we might take considerably longer than that standard
3600          time in order to get to the next progress bar step). */
3601       if (progbar == NULL)
3602          progbar = delayed_create_progress_dlg(cf->window, "Searching", title,
3603            FALSE, &stop_flag, &start_time, progbar_val);
3604
3605       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
3606          when we update it, we have to run the GTK+ main loop to get it
3607          to repaint what's pending, and doing so may involve an "ioctl()"
3608          to see if there's any pending input from an X server, and doing
3609          that for every packet can be costly, especially on a big file. */
3610       if (count >= progbar_nextstep) {
3611         /* let's not divide by zero. I should never be started
3612          * with count == 0, so let's assert that
3613          */
3614         g_assert(cf->count > 0);
3615
3616         progbar_val = (gfloat) count / cf->count;
3617
3618         if (progbar != NULL) {
3619           g_snprintf(status_str, sizeof(status_str),
3620                      "%4u of %u packets", count, cf->count);
3621           update_progress_dlg(progbar, progbar_val, status_str);
3622         }
3623
3624         progbar_nextstep += progbar_quantum;
3625       }
3626
3627       if (stop_flag) {
3628         /* Well, the user decided to abort the search.  Go back to the
3629            frame where we started. */
3630         new_fd = start_fd;
3631         break;
3632       }
3633
3634       /* Go past the current frame. */
3635       if (dir == SD_BACKWARD) {
3636         /* Go on to the previous frame. */
3637         if (framenum == 1) {
3638           /*
3639            * XXX - other apps have a bit more of a detailed message
3640            * for this, and instead of offering "OK" and "Cancel",
3641            * they offer things such as "Continue" and "Cancel";
3642            * we need an API for popping up alert boxes with
3643            * {Verb} and "Cancel".
3644            */
3645
3646           if (prefs.gui_find_wrap)
3647           {
3648               statusbar_push_temporary_msg("Search reached the beginning. Continuing at end.");
3649               framenum = cf->count;     /* wrap around */
3650           }
3651           else
3652           {
3653               statusbar_push_temporary_msg("Search reached the beginning.");
3654               framenum = start_fd->num; /* stay on previous packet */
3655           }
3656         } else
3657           framenum--;
3658       } else {
3659         /* Go on to the next frame. */
3660         if (framenum == cf->count) {
3661           if (prefs.gui_find_wrap)
3662           {
3663               statusbar_push_temporary_msg("Search reached the end. Continuing at beginning.");
3664               framenum = 1;             /* wrap around */
3665           }
3666           else
3667           {
3668               statusbar_push_temporary_msg("Search reached the end.");
3669               framenum = start_fd->num; /* stay on previous packet */
3670           }
3671         } else
3672           framenum++;
3673       }
3674       fdata = frame_data_sequence_find(cf->frames, framenum);
3675
3676       count++;
3677
3678       /* Is this packet in the display? */
3679       if (fdata->flags.passed_dfilter) {
3680         /* Yes.  Does it match the search criterion? */
3681         result = (*match_function)(cf, fdata, criterion);
3682         if (result == MR_ERROR) {
3683           /* Error; our caller has reported the error.  Go back to the frame
3684              where we started. */
3685           new_fd = start_fd;
3686           break;
3687         } else if (result == MR_MATCHED) {
3688           /* Yes.  Go to the new frame. */
3689           new_fd = fdata;
3690           break;
3691         }
3692       }
3693
3694       if (fdata == start_fd) {
3695         /* We're back to the frame we were on originally, and that frame
3696            doesn't match the search filter.  The search failed. */
3697         break;
3698       }
3699     }
3700
3701     /* We're done scanning the packets; destroy the progress bar if it
3702        was created. */
3703     if (progbar != NULL)
3704       destroy_progress_dlg(progbar);
3705   }
3706
3707   if (new_fd != NULL) {
3708     /* Find and select */
3709     cf->search_in_progress = TRUE;
3710     found = packet_list_select_row_from_data(new_fd);
3711     cf->search_in_progress = FALSE;
3712     cf->search_pos = 0; /* Reset the position */
3713     if (!found) {
3714       /* We didn't find a row corresponding to this frame.
3715          This means that the frame isn't being displayed currently,
3716          so we can't select it. */
3717       simple_message_box(ESD_TYPE_INFO, NULL,
3718                          "The capture file is probably not fully dissected.",
3719                          "End of capture exceeded!");
3720       return FALSE;
3721     }
3722     return TRUE;    /* success */
3723   } else
3724     return FALSE;   /* failure */
3725 }
3726
3727 gboolean
3728 cf_goto_frame(capture_file *cf, guint fnumber)
3729 {
3730   frame_data *fdata;
3731
3732   fdata = frame_data_sequence_find(cf->frames, fnumber);
3733
3734   if (fdata == NULL) {
3735     /* we didn't find a packet with that packet number */
3736     statusbar_push_temporary_msg("There is no packet number %u.", fnumber);
3737     return FALSE;   /* we failed to go to that packet */
3738   }
3739   if (!fdata->flags.passed_dfilter) {
3740     /* that packet currently isn't displayed */
3741     /* XXX - add it to the set of displayed packets? */
3742     statusbar_push_temporary_msg("Packet number %u isn't displayed.", fnumber);
3743     return FALSE;   /* we failed to go to that packet */
3744   }
3745
3746   if (!packet_list_select_row_from_data(fdata)) {
3747     /* We didn't find a row corresponding to this frame.
3748        This means that the frame isn't being displayed currently,
3749        so we can't select it. */
3750     simple_message_box(ESD_TYPE_INFO, NULL,
3751                        "The capture file is probably not fully dissected.",
3752                        "End of capture exceeded!");
3753     return FALSE;
3754   }
3755   return TRUE;  /* we got to that packet */
3756 }
3757
3758 gboolean
3759 cf_goto_top_frame(void)
3760 {
3761   /* Find and select */
3762   packet_list_select_first_row();
3763   return TRUE;  /* we got to that packet */
3764 }
3765
3766 gboolean
3767 cf_goto_bottom_frame(void)
3768 {
3769   /* Find and select */
3770   packet_list_select_last_row();
3771   return TRUE;  /* we got to that packet */
3772 }
3773
3774 /*
3775  * Go to frame specified by currently selected protocol tree item.
3776  */
3777 gboolean
3778 cf_goto_framenum(capture_file *cf)
3779 {
3780   header_field_info *hfinfo;
3781   guint32            framenum;
3782
3783   if (cf->finfo_selected) {
3784     hfinfo = cf->finfo_selected->hfinfo;
3785     g_assert(hfinfo);
3786     if (hfinfo->type == FT_FRAMENUM) {
3787       framenum = fvalue_get_uinteger(&cf->finfo_selected->value);
3788       if (framenum != 0)
3789         return cf_goto_frame(cf, framenum);
3790       }
3791   }
3792
3793   return FALSE;
3794 }
3795
3796 /* Select the packet on a given row. */
3797 void
3798 cf_select_packet(capture_file *cf, int row)
3799 {
3800   epan_dissect_t *old_edt;
3801   frame_data     *fdata;
3802
3803   /* Get the frame data struct pointer for this frame */
3804   fdata = packet_list_get_row_data(row);
3805
3806   if (fdata == NULL) {
3807     /* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
3808        the first entry is added to it by "real_insert_row()", that row
3809        is selected (see "real_insert_row()", in "ui/gtk/gtkclist.c", in both
3810        our version and the vanilla GTK+ version).
3811
3812        This means that a "select-row" signal is emitted; this causes
3813        "packet_list_select_cb()" to be called, which causes "cf_select_packet()"
3814        to be called.
3815
3816        "cf_select_packet()" fetches, above, the data associated with the
3817        row that was selected; however, as "gtk_clist_append()", which
3818        called "real_insert_row()", hasn't yet returned, we haven't yet
3819        associated any data with that row, so we get back a null pointer.
3820
3821        We can't assume that there's only one frame in the frame list,
3822        either, as we may be filtering the display.
3823
3824        We therefore assume that, if "row" is 0, i.e. the first row
3825        is being selected, and "cf->first_displayed" equals
3826        "cf->last_displayed", i.e. there's only one frame being
3827        displayed, that frame is the frame we want.
3828
3829        This means we have to set "cf->first_displayed" and
3830        "cf->last_displayed" before adding the row to the
3831        GtkCList; see the comment in "add_packet_to_packet_list()". */
3832
3833        if (row == 0 && cf->first_displayed == cf->last_displayed)
3834          fdata = frame_data_sequence_find(cf->frames, cf->first_displayed);
3835   }
3836
3837   /* If fdata _still_ isn't set simply give up. */
3838   if (fdata == NULL) {
3839     return;
3840   }
3841
3842   /* Get the data in that frame. */
3843   if (!cf_read_frame (cf, fdata)) {
3844     return;
3845   }
3846
3847   /* Record that this frame is the current frame. */
3848   cf->current_frame = fdata;
3849   cf->current_row = row;
3850
3851   old_edt = cf->edt;
3852   /* Create the logical protocol tree. */
3853   /* We don't need the columns here. */
3854   cf->edt = epan_dissect_new(cf->epan, TRUE, TRUE);
3855
3856   tap_build_interesting(cf->edt);
3857   epan_dissect_run(cf->edt, &cf->phdr, frame_tvbuff_new_buffer(cf->current_frame, &cf->buf),
3858                    cf->current_frame, NULL);
3859
3860   dfilter_macro_build_ftv_cache(cf->edt->tree);
3861
3862   cf_callback_invoke(cf_cb_packet_selected, cf);
3863
3864   if (old_edt != NULL)
3865     epan_dissect_free(old_edt);
3866
3867 }
3868
3869 /* Unselect the selected packet, if any. */
3870 void
3871 cf_unselect_packet(capture_file *cf)
3872 {
3873   epan_dissect_t *old_edt = cf->edt;
3874
3875   cf->edt = NULL;
3876
3877   /* No packet is selected. */
3878   cf->current_frame = NULL;
3879   cf->current_row = 0;
3880
3881   cf_callback_invoke(cf_cb_packet_unselected, cf);
3882
3883   /* No protocol tree means no selected field. */
3884   cf_unselect_field(cf);
3885
3886   /* Destroy the epan_dissect_t for the unselected packet. */
3887   if (old_edt != NULL)
3888     epan_dissect_free(old_edt);
3889 }
3890
3891 /* Unset the selected protocol tree field, if any. */
3892 void
3893 cf_unselect_field(capture_file *cf)
3894 {
3895   cf->finfo_selected = NULL;
3896
3897   cf_callback_invoke(cf_cb_field_unselected, cf);
3898 }
3899
3900 /*
3901  * Mark a particular frame.
3902  */
3903 void
3904 cf_mark_frame(capture_file *cf, frame_data *frame)
3905 {
3906   if (! frame->flags.marked) {
3907     frame->flags.marked = TRUE;
3908     if (cf->count > cf->marked_count)
3909       cf->marked_count++;
3910   }
3911 }
3912
3913 /*
3914  * Unmark a particular frame.
3915  */
3916 void
3917 cf_unmark_frame(capture_file *cf, frame_data *frame)
3918 {
3919   if (frame->flags.marked) {
3920     frame->flags.marked = FALSE;
3921     if (cf->marked_count > 0)
3922       cf->marked_count--;
3923   }
3924 }
3925
3926 /*
3927  * Ignore a particular frame.
3928  */
3929 void
3930 cf_ignore_frame(capture_file *cf, frame_data *frame)
3931 {
3932   if (! frame->flags.ignored) {
3933     frame->flags.ignored = TRUE;
3934     if (cf->count > cf->ignored_count)
3935       cf->ignored_count++;
3936   }
3937 }
3938
3939 /*
3940  * Un-ignore a particular frame.
3941  */
3942 void
3943 cf_unignore_frame(capture_file *cf, frame_data *frame)
3944 {
3945   if (frame->flags.ignored) {
3946     frame->flags.ignored = FALSE;
3947     if (cf->ignored_count > 0)
3948       cf->ignored_count--;
3949   }
3950 }
3951
3952 /*
3953  * Read the comment in SHB block
3954  */
3955
3956 const gchar *
3957 cf_read_shb_comment(capture_file *cf)
3958 {
3959   wtapng_section_t *shb_inf;
3960   const gchar      *temp_str;
3961
3962   /* Get info from SHB */
3963   shb_inf = wtap_file_get_shb_info(cf->wth);
3964   if (shb_inf == NULL)
3965         return NULL;
3966   temp_str = shb_inf->opt_comment;
3967   g_free(shb_inf);
3968
3969   return temp_str;
3970
3971 }
3972
3973 void
3974 cf_update_capture_comment(capture_file *cf, gchar *comment)
3975 {
3976   wtapng_section_t *shb_inf;
3977
3978   /* Get info from SHB */
3979   shb_inf = wtap_file_get_shb_info(cf->wth);
3980
3981   /* See if the comment has changed or not */
3982   if (shb_inf && shb_inf->opt_comment) {
3983     if (strcmp(shb_inf->opt_comment, comment) == 0) {
3984       g_free(comment);
3985       g_free(shb_inf);
3986       return;
3987     }
3988   }
3989
3990   g_free(shb_inf);
3991
3992   /* The comment has changed, let's update it */
3993   wtap_write_shb_comment(cf->wth, comment);
3994   /* Mark the file as having unsaved changes */
3995   cf->unsaved_changes = TRUE;
3996 }
3997
3998 static const char *
3999 cf_get_user_packet_comment(capture_file *cf, const frame_data *fd)
4000 {
4001   if (cf->frames_user_comments)
4002      return (const char *)g_tree_lookup(cf->frames_user_comments, fd);
4003
4004   /* g_warning? */
4005   return NULL;
4006 }
4007
4008 char *
4009 cf_get_comment(capture_file *cf, const frame_data *fd)
4010 {
4011   /* fetch user comment */
4012   if (fd->flags.has_user_comment)
4013     return g_strdup(cf_get_user_packet_comment(cf, fd));
4014
4015   /* fetch phdr comment */
4016   if (fd->flags.has_phdr_comment) {
4017     struct wtap_pkthdr phdr; /* Packet header */
4018     Buffer buf; /* Packet data */
4019
4020     phdr.opt_comment = NULL;
4021
4022     buffer_init(&buf, 1500);
4023     if (!cf_read_frame_r(cf, fd, &phdr, &buf))
4024       { /* XXX, what we can do here? */ }
4025
4026     buffer_free(&buf);
4027     return phdr.opt_comment;
4028   }
4029   return NULL;
4030 }
4031
4032 static int
4033 frame_cmp(gconstpointer a, gconstpointer b, gpointer user_data _U_)
4034 {
4035   const frame_data *fdata1 = (const frame_data *) a;
4036   const frame_data *fdata2 = (const frame_data *) b;
4037
4038   return (fdata1->num < fdata2->num) ? -1 :
4039     (fdata1->num > fdata2->num) ? 1 :
4040     0;
4041 }
4042
4043 gboolean
4044 cf_set_user_packet_comment(capture_file *cf, frame_data *fd, const gchar *new_comment)
4045 {
4046   char *pkt_comment = cf_get_comment(cf, fd);
4047
4048   /* Check if the comment has changed */
4049   if (!g_strcmp0(pkt_comment, new_comment)) {
4050     g_free(pkt_comment);
4051     return FALSE;
4052   }
4053   g_free(pkt_comment);
4054
4055   if (pkt_comment)
4056     cf->packet_comment_count--;
4057
4058   if (new_comment)
4059     cf->packet_comment_count++;
4060
4061   fd->flags.has_user_comment = TRUE;
4062
4063   if (!cf->frames_user_comments)
4064     cf->frames_user_comments = g_tree_new_full(frame_cmp, NULL, NULL, g_free);
4065
4066   /* insert new packet comment */
4067   g_tree_replace(cf->frames_user_comments, fd, g_strdup(new_comment));
4068
4069   expert_update_comment_count(cf->packet_comment_count);
4070
4071   /* OK, we have unsaved changes. */
4072   cf->unsaved_changes = TRUE;
4073   return TRUE;
4074 }
4075
4076 /*
4077  * What types of comments does this capture file have?
4078  */
4079 guint32
4080 cf_comment_types(capture_file *cf)
4081 {
4082   guint32 comment_types = 0;
4083
4084   if (cf_read_shb_comment(cf) != NULL)
4085     comment_types |= WTAP_COMMENT_PER_SECTION;
4086   if (cf->packet_comment_count != 0)
4087     comment_types |= WTAP_COMMENT_PER_PACKET;
4088   return comment_types;
4089 }
4090
4091 typedef struct {
4092   wtap_dumper *pdh;
4093   const char  *fname;
4094   int          file_type;
4095 } save_callback_args_t;
4096
4097 /*
4098  * Save a capture to a file, in a particular format, saving either
4099  * all packets, all currently-displayed packets, or all marked packets.
4100  *
4101  * Returns TRUE if it succeeds, FALSE otherwise; if it fails, it pops
4102  * up a message box for the failure.
4103  */
4104 static gboolean
4105 save_packet(capture_file *cf _U_, frame_data *fdata,
4106             struct wtap_pkthdr *phdr, const guint8 *pd,
4107             void *argsp)
4108 {
4109   save_callback_args_t *args = (save_callback_args_t *)argsp;
4110   struct wtap_pkthdr    hdr;
4111   int           err;
4112   gchar        *display_basename;
4113   const char   *pkt_comment;
4114
4115   if (fdata->flags.has_user_comment)
4116     pkt_comment = cf_get_user_packet_comment(cf, fdata);
4117   else
4118     pkt_comment = phdr->opt_comment;
4119
4120   /* init the wtap header for saving */
4121   /* TODO: reuse phdr */
4122   /* XXX - these are the only flags that correspond to data that we have
4123      in the frame_data structure and that matter on a per-packet basis.
4124
4125      For WTAP_HAS_CAP_LEN, either the file format has separate "captured"
4126      and "on the wire" lengths, or it doesn't.
4127
4128      For WTAP_HAS_DROP_COUNT, Wiretap doesn't actually supply the value
4129      to its callers.
4130
4131      For WTAP_HAS_PACK_FLAGS, we currently don't save the FCS length
4132      from the packet flags. */
4133   hdr.presence_flags = 0;
4134   if (fdata->flags.has_ts)
4135     hdr.presence_flags |= WTAP_HAS_TS;
4136   if (phdr->presence_flags & WTAP_HAS_INTERFACE_ID)
4137     hdr.presence_flags |= WTAP_HAS_INTERFACE_ID;
4138   if (phdr->presence_flags & WTAP_HAS_PACK_FLAGS)
4139     hdr.presence_flags |= WTAP_HAS_PACK_FLAGS;
4140   hdr.ts.secs      = fdata->abs_ts.secs;
4141   hdr.ts.nsecs     = fdata->abs_ts.nsecs;
4142   hdr.caplen       = fdata->cap_len;
4143   hdr.len          = fdata->pkt_len;
4144   hdr.pkt_encap    = fdata->lnk_t;
4145   /* pcapng */
4146   hdr.interface_id = phdr->interface_id;   /* identifier of the interface. */
4147   /* options */
4148   hdr.pack_flags   = phdr->pack_flags;
4149   hdr.opt_comment  = g_strdup(pkt_comment);
4150
4151   /* pseudo */
4152   hdr.pseudo_header = phdr->pseudo_header;
4153 #if 0
4154   hdr.drop_count   =
4155   hdr.pack_flags   =     /* XXX - 0 for now (any value for "we don't have it"?) */
4156 #endif
4157   /* and save the packet */
4158   if (!wtap_dump(args->pdh, &hdr, pd, &err)) {
4159     if (err < 0) {
4160       /* Wiretap error. */
4161       switch (err) {
4162
4163       case WTAP_ERR_UNSUPPORTED_ENCAP:
4164         /*
4165          * This is a problem with the particular frame we're writing and
4166          * the file type and subtype we're writing; note that, and report
4167          * the frame number and file type/subtype.
4168          */
4169         simple_error_message_box(
4170                       "Frame %u has a network type that can't be saved in a \"%s\" file.",
4171                       fdata->num, wtap_file_type_subtype_string(args->file_type));
4172         break;
4173
4174       case WTAP_ERR_PACKET_TOO_LARGE:
4175         /*
4176          * This is a problem with the particular frame we're writing and
4177          * the file type and subtype we're writing; note that, and report
4178          * the frame number and file type/subtype.
4179          */
4180         simple_error_message_box(
4181                       "Frame %u is larger than Wireshark supports in a \"%s\" file.",
4182                       fdata->num, wtap_file_type_subtype_string(args->file_type));
4183         break;
4184
4185       default:
4186         display_basename = g_filename_display_basename(args->fname);
4187         simple_error_message_box(
4188                       "An error occurred while writing to the file \"%s\": %s.",
4189                       display_basename, wtap_strerror(err));
4190         g_free(display_basename);
4191         break;
4192       }
4193     } else {
4194       /* OS error. */
4195       write_failure_alert_box(args->fname, err);
4196     }
4197     return FALSE;
4198   }
4199
4200   g_free(hdr.opt_comment);
4201   return TRUE;
4202 }
4203
4204 /*
4205  * Can this capture file be written out in any format using Wiretap
4206  * rather than by copying the raw data?
4207  */
4208 gboolean
4209 cf_can_write_with_wiretap(capture_file *cf)
4210 {
4211   /* We don't care whether we support the comments in this file or not;
4212      if we can't, we'll offer the user the option of discarding the
4213      comments. */
4214   return wtap_dump_can_write(cf->linktypes, 0);
4215 }
4216
4217 /*
4218  * Should we let the user do a save?
4219  *
4220  * We should if:
4221  *
4222  *  the file has unsaved changes, and we can save it in some
4223  *  format through Wiretap
4224  *
4225  * or
4226  *
4227  *  the file is a temporary file and has no unsaved changes (so
4228  *  that "saving" it just means copying it).
4229  *
4230  * XXX - we shouldn't allow files to be edited if they can't be saved,
4231  * so cf->unsaved_changes should be true only if the file can be saved.
4232  *
4233  * We don't care whether we support the comments in this file or not;
4234  * if we can't, we'll offer the user the option of discarding the
4235  * comments.
4236  */
4237 gboolean
4238 cf_can_save(capture_file *cf)
4239 {
4240   if (cf->unsaved_changes && wtap_dump_can_write(cf->linktypes, 0)) {
4241     /* Saved changes, and we can write it out with Wiretap. */
4242     return TRUE;
4243   }
4244
4245   if (cf->is_tempfile && !cf->unsaved_changes) {
4246     /*
4247      * Temporary file with no unsaved changes, so we can just do a
4248      * raw binary copy.
4249      */
4250     return TRUE;
4251   }
4252
4253   /* Nothing to save. */
4254   return FALSE;
4255 }
4256
4257 /*
4258  * Should we let the user do a "save as"?
4259  *
4260  * That's true if:
4261  *
4262  *  we can save it in some format through Wiretap
4263  *
4264  * or
4265  *
4266  *  the file is a temporary file and has no unsaved changes (so
4267  *  that "saving" it just means copying it).
4268  *
4269  * XXX - we shouldn't allow files to be edited if they can't be saved,
4270  * so cf->unsaved_changes should be true only if the file can be saved.
4271  *
4272  * We don't care whether we support the comments in this file or not;
4273  * if we can't, we'll offer the user the option of discarding the
4274  * comments.
4275  */
4276 gboolean
4277 cf_can_save_as(capture_file *cf)
4278 {
4279   if (wtap_dump_can_write(cf->linktypes, 0)) {
4280     /* We can write it out with Wiretap. */
4281     return TRUE;
4282   }
4283
4284   if (cf->is_tempfile && !cf->unsaved_changes) {
4285     /*
4286      * Temporary file with no unsaved changes, so we can just do a
4287      * raw binary copy.
4288      */
4289     return TRUE;
4290   }
4291
4292   /* Nothing to save. */
4293   return FALSE;
4294 }
4295
4296 /*
4297  * Does this file have unsaved data?
4298  */
4299 gboolean
4300 cf_has_unsaved_data(capture_file *cf)
4301 {
4302   /*
4303    * If this is a temporary file, or a file with unsaved changes, it
4304    * has unsaved data.
4305    */
4306   return cf->is_tempfile || cf->unsaved_changes;
4307 }
4308
4309 /*
4310  * Quick scan to find packet offsets.
4311  */
4312 static cf_read_status_t
4313 rescan_file(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
4314 {
4315   const struct wtap_pkthdr *phdr;
4316   gchar               *err_info;
4317   gchar               *name_ptr;
4318   gint64               data_offset;
4319   gint64               file_pos;
4320   progdlg_t           *progbar        = NULL;
4321   gboolean             stop_flag;
4322   gint64               size;
4323   float                progbar_val;
4324   GTimeVal             start_time;
4325   gchar                status_str[100];
4326   gint64               progbar_nextstep;
4327   gint64               progbar_quantum;
4328   guint32              framenum;
4329   frame_data          *fdata;
4330   int                  count          = 0;
4331 #ifdef HAVE_LIBPCAP
4332   int                  displayed_once = 0;
4333 #endif
4334
4335   /* Close the old handle. */
4336   wtap_close(cf->wth);
4337
4338   /* Open the new file. */
4339   cf->wth = wtap_open_offline(fname, err, &err_info, TRUE);
4340   if (cf->wth == NULL) {
4341     cf_open_failure_alert_box(fname, *err, err_info, FALSE, 0);
4342     return CF_READ_ERROR;
4343   }
4344
4345   /* We're scanning a file whose contents should be the same as what
4346      we had before, so we don't discard dissection state etc.. */
4347   cf->f_datalen = 0;
4348
4349   /* Set the file name because we need it to set the follow stream filter.
4350      XXX - is that still true?  We need it for other reasons, though,
4351      in any case. */
4352   cf->filename = g_strdup(fname);
4353
4354   /* Indicate whether it's a permanent or temporary file. */
4355   cf->is_tempfile = is_tempfile;
4356
4357   /* No user changes yet. */
4358   cf->unsaved_changes = FALSE;
4359
4360   cf->cd_t        = wtap_file_type_subtype(cf->wth);
4361   cf->linktypes = g_array_sized_new(FALSE, FALSE, (guint) sizeof(int), 1);
4362
4363   cf->snap      = wtap_snapshot_length(cf->wth);
4364   if (cf->snap == 0) {
4365     /* Snapshot length not known. */
4366     cf->has_snap = FALSE;
4367     cf->snap = WTAP_MAX_PACKET_SIZE;
4368   } else
4369     cf->has_snap = TRUE;
4370
4371   name_ptr = g_filename_display_basename(cf->filename);
4372
4373   cf_callback_invoke(cf_cb_file_rescan_started, cf);
4374
4375   /* Record whether the file is compressed.
4376      XXX - do we know this at open time? */
4377   cf->iscompressed = wtap_iscompressed(cf->wth);
4378
4379   /* Find the size of the file. */
4380   size = wtap_file_size(cf->wth, NULL);
4381
4382   /* Update the progress bar when it gets to this value. */
4383   progbar_nextstep = 0;
4384   /* When we reach the value that triggers a progress bar update,
4385      bump that value by this amount. */
4386   if (size >= 0) {
4387     progbar_quantum = size/N_PROGBAR_UPDATES;
4388     if (progbar_quantum < MIN_QUANTUM)
4389       progbar_quantum = MIN_QUANTUM;
4390   }else
4391     progbar_quantum = 0;
4392
4393   stop_flag = FALSE;
4394   g_get_current_time(&start_time);
4395
4396   framenum = 0;
4397   phdr = wtap_phdr(cf->wth);
4398   while ((wtap_read(cf->wth, err, &err_info, &data_offset))) {
4399     framenum++;
4400     fdata = frame_data_sequence_find(cf->frames, framenum);
4401     fdata->file_off = data_offset;
4402     if (size >= 0) {
4403       count++;
4404       file_pos = wtap_read_so_far(cf->wth);
4405
4406       /* Create the progress bar if necessary.
4407        * Check whether it should be created or not every MIN_NUMBER_OF_PACKET
4408        */
4409       if ((progbar == NULL) && !(count % MIN_NUMBER_OF_PACKET)) {
4410         progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
4411         progbar = delayed_create_progress_dlg(cf->window, "Rescanning", name_ptr,
4412                                               TRUE, &stop_flag, &start_time, progbar_val);
4413       }
4414
4415       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
4416          when we update it, we have to run the GTK+ main loop to get it
4417          to repaint what's pending, and doing so may involve an "ioctl()"
4418          to see if there's any pending input from an X server, and doing
4419          that for every packet can be costly, especially on a big file. */
4420       if (file_pos >= progbar_nextstep) {
4421         if (progbar != NULL) {
4422           progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
4423           /* update the packet bar content on the first run or frequently on very large files */
4424 #ifdef HAVE_LIBPCAP
4425           if (progbar_quantum > 500000 || displayed_once == 0) {
4426             if ((auto_scroll_live || displayed_once == 0 || cf->displayed_count < 1000) && cf->count != 0) {
4427               displayed_once = 1;
4428               packets_bar_update();
4429             }
4430           }
4431 #endif /* HAVE_LIBPCAP */
4432           update_progress_dlg(progbar, progbar_val, status_str);
4433         }
4434         progbar_nextstep += progbar_quantum;
4435       }
4436     }
4437
4438     if (stop_flag) {
4439       /* Well, the user decided to abort the rescan.  Sadly, as this
4440          isn't a reread, recovering is difficult, so we'll just
4441          close the current capture. */
4442       break;
4443     }
4444
4445     /* Add this packet's link-layer encapsulation type to cf->linktypes, if
4446        it's not already there.
4447        XXX - yes, this is O(N), so if every packet had a different
4448        link-layer encapsulation type, it'd be O(N^2) to read the file, but
4449        there are probably going to be a small number of encapsulation types
4450        in a file. */
4451     cf_add_encapsulation_type(cf, phdr->pkt_encap);
4452   }
4453
4454   /* Free the display name */
4455   g_free(name_ptr);
4456
4457   /* We're done reading the file; destroy the progress bar if it was created. */
4458   if (progbar != NULL)
4459     destroy_progress_dlg(progbar);
4460
4461   /* We're done reading sequentially through the file. */
4462   cf->state = FILE_READ_DONE;
4463
4464   /* Close the sequential I/O side, to free up memory it requires. */
4465   wtap_sequential_close(cf->wth);
4466
4467   /* compute the time it took to load the file */
4468   compute_elapsed(cf, &start_time);
4469
4470   /* Set the file encapsulation type now; we don't know what it is until
4471      we've looked at all the packets, as we don't know until then whether
4472      there's more than one type (and thus whether it's
4473      WTAP_ENCAP_PER_PACKET). */
4474   cf->lnk_t = wtap_file_encap(cf->wth);
4475
4476   cf_callback_invoke(cf_cb_file_rescan_finished, cf);
4477
4478   if (stop_flag) {
4479     /* Our caller will give up at this point. */
4480     return CF_READ_ABORTED;
4481   }
4482
4483   if (*err != 0) {
4484     /* Put up a message box noting that the read failed somewhere along
4485        the line.  Don't throw out the stuff we managed to read, though,
4486        if any. */
4487     switch (*err) {
4488
4489     case WTAP_ERR_UNSUPPORTED:
4490       simple_error_message_box(
4491                  "The capture file contains record data that Wireshark doesn't support.\n(%s)",
4492                  err_info);
4493       g_free(err_info);
4494       break;
4495
4496     case WTAP_ERR_UNSUPPORTED_ENCAP:
4497       simple_error_message_box(
4498                  "The capture file has a packet with a network type that Wireshark doesn't support.\n(%s)",
4499                  err_info);
4500       g_free(err_info);
4501       break;
4502
4503     case WTAP_ERR_CANT_READ:
4504       simple_error_message_box(
4505                  "An attempt to read from the capture file failed for"
4506                  " some unknown reason.");
4507       break;
4508
4509     case WTAP_ERR_SHORT_READ:
4510       simple_error_message_box(
4511                  "The capture file appears to have been cut short"
4512                  " in the middle of a packet.");
4513       break;
4514
4515     case WTAP_ERR_BAD_FILE:
4516       simple_error_message_box(
4517                  "The capture file appears to be damaged or corrupt.\n(%s)",
4518                  err_info);
4519       g_free(err_info);
4520       break;
4521
4522     case WTAP_ERR_DECOMPRESS:
4523       simple_error_message_box(
4524                  "The compressed capture file appears to be damaged or corrupt.\n"
4525                  "(%s)", err_info);
4526       g_free(err_info);
4527       break;
4528
4529     default:
4530       simple_error_message_box(
4531                  "An error occurred while reading the"
4532                  " capture file: %s.", wtap_strerror(*err));
4533       break;
4534     }
4535     return CF_READ_ERROR;
4536   } else
4537     return CF_READ_OK;
4538 }
4539
4540 cf_write_status_t
4541 cf_save_packets(capture_file *cf, const char *fname, guint save_format,
4542                 gboolean compressed, gboolean discard_comments,
4543                 gboolean dont_reopen)
4544 {
4545   gchar           *err_info;
4546   gchar           *fname_new = NULL;
4547   wtap_dumper     *pdh;
4548   frame_data      *fdata;
4549   addrinfo_lists_t *addr_lists;
4550   guint            framenum;
4551   int              err;
4552 #ifdef _WIN32
4553   gchar           *display_basename;
4554 #endif
4555   enum {
4556      SAVE_WITH_MOVE,
4557      SAVE_WITH_COPY,
4558      SAVE_WITH_WTAP
4559   }                    how_to_save;
4560   save_callback_args_t callback_args;
4561
4562   cf_callback_invoke(cf_cb_file_save_started, (gpointer)fname);
4563
4564   addr_lists = get_addrinfo_list();
4565
4566   if (save_format == cf->cd_t && compressed == cf->iscompressed
4567       && !discard_comments && !cf->unsaved_changes
4568       && !(addr_lists && wtap_dump_has_name_resolution(save_format))) {
4569     /* We're saving in the format it's already in, and we're
4570        not discarding comments, and there are no changes we have
4571        in memory that aren't saved to the file, and we have no name
4572        resolution blocks to write, so we can just move or copy the raw data. */
4573
4574     if (cf->is_tempfile) {
4575       /* The file being saved is a temporary file from a live
4576          capture, so it doesn't need to stay around under that name;
4577          first, try renaming the capture buffer file to the new name.
4578          This acts as a "safe save", in that, if the file already
4579          exists, the existing file will be removed only if the rename
4580          succeeds.
4581
4582          Sadly, on Windows, as we have the current capture file
4583          open, even MoveFileEx() with MOVEFILE_REPLACE_EXISTING
4584          (to cause the rename to remove an existing target), as
4585          done by ws_stdio_rename() (ws_rename() is #defined to
4586          be ws_stdio_rename() on Windows) will fail.
4587
4588          According to the MSDN documentation for CreateFile(), if,
4589          when we open a capture file, we were to directly do a CreateFile(),
4590          opening with FILE_SHARE_DELETE|FILE_SHARE_READ, and then
4591          convert it to a file descriptor with _open_osfhandle(),
4592          that would allow the file to be renamed out from under us.
4593
4594          However, that doesn't work in practice.  Perhaps the problem
4595          is that the process doing the rename is the process that
4596          has the file open. */
4597 #ifndef _WIN32
4598       if (ws_rename(cf->filename, fname) == 0) {
4599         /* That succeeded - there's no need to copy the source file. */
4600         how_to_save = SAVE_WITH_MOVE;
4601       } else {
4602         if (errno == EXDEV) {
4603           /* They're on different file systems, so we have to copy the
4604              file. */
4605           how_to_save = SAVE_WITH_COPY;
4606         } else {
4607           /* The rename failed, but not because they're on different
4608              file systems - put up an error message.  (Or should we
4609              just punt and try to copy?  The only reason why I'd
4610              expect the rename to fail and the copy to succeed would
4611              be if we didn't have permission to remove the file from
4612              the temporary directory, and that might be fixable - but
4613              is it worth requiring the user to go off and fix it?) */
4614           cf_rename_failure_alert_box(fname, errno);
4615           goto fail;
4616         }
4617       }
4618 #else
4619       how_to_save = SAVE_WITH_COPY;
4620 #endif
4621     } else {
4622       /* It's a permanent file, so we should copy it, and not remove the
4623          original. */
4624       how_to_save = SAVE_WITH_COPY;
4625     }
4626
4627     if (how_to_save == SAVE_WITH_COPY) {
4628       /* Copy the file, if we haven't moved it.  If we're overwriting
4629          an existing file, we do it with a "safe save", by writing
4630          to a new file and, if the write succeeds, renaming the
4631          new file on top of the old file. */
4632       if (file_exists(fname)) {
4633         fname_new = g_strdup_printf("%s~", fname);
4634         if (!copy_file_binary_mode(cf->filename, fname_new))
4635           goto fail;
4636       } else {
4637         if (!copy_file_binary_mode(cf->filename, fname))
4638           goto fail;
4639       }
4640     }
4641   } else {
4642     /* Either we're saving in a different format or we're saving changes,
4643        such as added, modified, or removed comments, that haven't yet
4644        been written to the underlying file; we can't do that by copying
4645        or moving the capture file, we have to do it by writing the packets
4646        out in Wiretap. */
4647
4648     wtapng_section_t *shb_hdr = NULL;
4649     wtapng_iface_descriptions_t *idb_inf = NULL;
4650     int encap;
4651
4652     shb_hdr = wtap_file_get_shb_info(cf->wth);
4653     idb_inf = wtap_file_get_idb_info(cf->wth);
4654
4655     /* Determine what file encapsulation type we should use. */
4656     encap = wtap_dump_file_encap_type(cf->linktypes);
4657
4658     if (file_exists(fname)) {
4659       /* We're overwriting an existing file; write out to a new file,
4660          and, if that succeeds, rename the new file on top of the
4661          old file.  That makes this a "safe save", so that we don't
4662          lose the old file if we have a problem writing out the new
4663          file.  (If the existing file is the current capture file,
4664          we *HAVE* to do that, otherwise we're overwriting the file
4665          from which we're reading the packets that we're writing!) */
4666       fname_new = g_strdup_printf("%s~", fname);
4667       pdh = wtap_dump_open_ng(fname_new, save_format, encap, cf->snap,
4668                               compressed, shb_hdr, idb_inf, &err);
4669     } else {
4670       pdh = wtap_dump_open_ng(fname, save_format, encap, cf->snap,
4671                               compressed, shb_hdr, idb_inf, &err);
4672     }
4673     g_free(idb_inf);
4674     idb_inf = NULL;
4675
4676     if (pdh == NULL) {
4677       cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
4678       goto fail;
4679     }
4680
4681     /* Add address resolution */
4682     wtap_dump_set_addrinfo_list(pdh, addr_lists);
4683
4684     /* Iterate through the list of packets, processing all the packets. */
4685     callback_args.pdh = pdh;
4686     callback_args.fname = fname;
4687     callback_args.file_type = save_format;
4688     switch (process_specified_packets(cf, NULL, "Saving", "packets",
4689                                       TRUE, save_packet, &callback_args)) {
4690
4691     case PSP_FINISHED:
4692       /* Completed successfully. */
4693       break;
4694
4695     case PSP_STOPPED:
4696       /* The user decided to abort the saving.
4697          If we're writing to a temporary file, remove it.
4698          XXX - should we do so even if we're not writing to a
4699          temporary file? */
4700       wtap_dump_close(pdh, &err);
4701       if (fname_new != NULL)
4702         ws_unlink(fname_new);
4703       cf_callback_invoke(cf_cb_file_save_stopped, NULL);
4704       return CF_WRITE_ABORTED;
4705
4706     case PSP_FAILED:
4707       /* Error while saving.
4708          If we're writing to a temporary file, remove it. */
4709       if (fname_new != NULL)
4710         ws_unlink(fname_new);
4711       wtap_dump_close(pdh, &err);
4712       goto fail;
4713     }
4714
4715     if (!wtap_dump_close(pdh, &err)) {
4716       cf_close_failure_alert_box(fname, err);
4717       goto fail;
4718     }
4719
4720     how_to_save = SAVE_WITH_WTAP;
4721   }
4722
4723   if (fname_new != NULL) {
4724     /* We wrote out to fname_new, and should rename it on top of
4725        fname.  fname_new is now closed, so that should be possible even
4726        on Windows.  However, on Windows, we first need to close whatever
4727        file descriptors we have open for fname. */
4728 #ifdef _WIN32
4729     wtap_fdclose(cf->wth);
4730 #endif
4731     /* Now do the rename. */
4732     if (ws_rename(fname_new, fname) == -1) {
4733       /* Well, the rename failed. */
4734       cf_rename_failure_alert_box(fname, errno);
4735 #ifdef _WIN32
4736       /* Attempt to reopen the random file descriptor using the
4737          current file's filename.  (At this point, the sequential
4738          file descriptor is closed.) */
4739       if (!wtap_fdreopen(cf->wth, cf->filename, &err)) {
4740         /* Oh, well, we're screwed. */
4741         display_basename = g_filename_display_basename(cf->filename);
4742         simple_error_message_box(
4743                       file_open_error_message(err, FALSE), display_basename);
4744         g_free(display_basename);
4745       }
4746 #endif
4747       goto fail;
4748     }
4749   }
4750
4751   cf_callback_invoke(cf_cb_file_save_finished, NULL);
4752   cf->unsaved_changes = FALSE;
4753
4754   if (!dont_reopen) {
4755     switch (how_to_save) {
4756
4757     case SAVE_WITH_MOVE:
4758       /* We just moved the file, so the wtap structure refers to the
4759          new file, and all the information other than the filename
4760          and the "is temporary" status applies to the new file; just
4761          update that. */
4762       g_free(cf->filename);
4763       cf->filename = g_strdup(fname);
4764       cf->is_tempfile = FALSE;
4765       cf_callback_invoke(cf_cb_file_fast_save_finished, cf);
4766       break;
4767
4768     case SAVE_WITH_COPY:
4769       /* We just copied the file, s all the information other than
4770          the wtap structure, the filename, and the "is temporary"
4771          status applies to the new file; just update that. */
4772       wtap_close(cf->wth);
4773       cf->wth = wtap_open_offline(fname, &err, &err_info, TRUE);
4774       if (cf->wth == NULL) {
4775         cf_open_failure_alert_box(fname, err, err_info, FALSE, 0);
4776         cf_close(cf);
4777       } else {
4778         g_free(cf->filename);
4779         cf->filename = g_strdup(fname);
4780         cf->is_tempfile = FALSE;
4781       }
4782       cf_callback_invoke(cf_cb_file_fast_save_finished, cf);
4783       break;
4784
4785     case SAVE_WITH_WTAP:
4786       /* Open and read the file we saved to.
4787
4788          XXX - this is somewhat of a waste; we already have the
4789          packets, all this gets us is updated file type information
4790          (which we could just stuff into "cf"), and having the new
4791          file be the one we have opened and from which we're reading
4792          the data, and it means we have to spend time opening and
4793          reading the file, which could be a significant amount of
4794          time if the file is large.
4795
4796          If the capture-file-writing code were to return the
4797          seek offset of each packet it writes, we could save that
4798          in the frame_data structure for the frame, and just open
4799          the file without reading it again...
4800
4801          ...as long as, for gzipped files, the process of writing
4802          out the file *also* generates the information needed to
4803          support fast random access to the compressed file. */
4804       if (rescan_file(cf, fname, FALSE, &err) != CF_READ_OK) {
4805         /* The rescan failed; just close the file.  Either
4806            a dialog was popped up for the failure, so the
4807            user knows what happened, or they stopped the
4808            rescan, in which case they know what happened. */
4809         cf_close(cf);
4810       }
4811       break;
4812     }
4813
4814     /* If we were told to discard the comments, do so. */
4815     if (discard_comments) {
4816       /* Remove SHB comment, if any. */
4817       wtap_write_shb_comment(cf->wth, NULL);
4818
4819       /* remove all user comments */
4820       for (framenum = 1; framenum <= cf->count; framenum++) {
4821         fdata = frame_data_sequence_find(cf->frames, framenum);
4822
4823         fdata->flags.has_phdr_comment = FALSE;
4824         fdata->flags.has_user_comment = FALSE;
4825       }
4826
4827       if (cf->frames_user_comments) {
4828         g_tree_destroy(cf->frames_user_comments);
4829         cf->frames_user_comments = NULL;
4830       }
4831
4832       cf->packet_comment_count = 0;
4833     }
4834   }
4835   return CF_WRITE_OK;
4836
4837 fail:
4838   if (fname_new != NULL) {
4839     /* We were trying to write to a temporary file; get rid of it if it
4840        exists.  (We don't care whether this fails, as, if it fails,
4841        there's not much we can do about it.  I guess if it failed for
4842        a reason other than "it doesn't exist", we could report an
4843        error, so the user knows there's a junk file that they might
4844        want to clean up.) */
4845     ws_unlink(fname_new);
4846     g_free(fname_new);
4847   }
4848   cf_callback_invoke(cf_cb_file_save_failed, NULL);
4849   return CF_WRITE_ERROR;
4850 }
4851
4852 cf_write_status_t
4853 cf_export_specified_packets(capture_file *cf, const char *fname,
4854                             packet_range_t *range, guint save_format,
4855                             gboolean compressed)
4856 {
4857   gchar                       *fname_new = NULL;
4858   int                          err;
4859   wtap_dumper                 *pdh;
4860   save_callback_args_t         callback_args;
4861   wtapng_section_t            *shb_hdr;
4862   wtapng_iface_descriptions_t *idb_inf;
4863   int                          encap;
4864
4865   cf_callback_invoke(cf_cb_file_export_specified_packets_started, (gpointer)fname);
4866
4867   packet_range_process_init(range);
4868
4869   /* We're writing out specified packets from the specified capture
4870      file to another file.  Even if all captured packets are to be
4871      written, don't special-case the operation - read each packet
4872      and then write it out if it's one of the specified ones. */
4873
4874   shb_hdr = wtap_file_get_shb_info(cf->wth);
4875   idb_inf = wtap_file_get_idb_info(cf->wth);
4876
4877   /* Determine what file encapsulation type we should use. */
4878   encap = wtap_dump_file_encap_type(cf->linktypes);
4879
4880   if (file_exists(fname)) {
4881     /* We're overwriting an existing file; write out to a new file,
4882        and, if that succeeds, rename the new file on top of the
4883        old file.  That makes this a "safe save", so that we don't
4884        lose the old file if we have a problem writing out the new
4885        file.  (If the existing file is the current capture file,
4886        we *HAVE* to do that, otherwise we're overwriting the file
4887        from which we're reading the packets that we're writing!) */
4888     fname_new = g_strdup_printf("%s~", fname);
4889     pdh = wtap_dump_open_ng(fname_new, save_format, encap, cf->snap,
4890                             compressed, shb_hdr, idb_inf, &err);
4891   } else {
4892     pdh = wtap_dump_open_ng(fname, save_format, encap, cf->snap,
4893                             compressed, shb_hdr, idb_inf, &err);
4894   }
4895   g_free(idb_inf);
4896   idb_inf = NULL;
4897
4898   if (pdh == NULL) {
4899     cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
4900     goto fail;
4901   }
4902
4903   /* Add address resolution */
4904   wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list());
4905
4906   /* Iterate through the list of packets, processing the packets we were
4907      told to process.
4908
4909      XXX - we've already called "packet_range_process_init(range)", but
4910      "process_specified_packets()" will do it again.  Fortunately,
4911      that's harmless in this case, as we haven't done anything to
4912      "range" since we initialized it. */
4913   callback_args.pdh = pdh;
4914   callback_args.fname = fname;
4915   callback_args.file_type = save_format;
4916   switch (process_specified_packets(cf, range, "Writing", "specified packets",
4917                                     TRUE, save_packet, &callback_args)) {
4918
4919   case PSP_FINISHED:
4920     /* Completed successfully. */
4921     break;
4922
4923   case PSP_STOPPED:
4924       /* The user decided to abort the saving.
4925          If we're writing to a temporary file, remove it.
4926          XXX - should we do so even if we're not writing to a
4927          temporary file? */
4928       wtap_dump_close(pdh, &err);
4929       if (fname_new != NULL)
4930         ws_unlink(fname_new);
4931       cf_callback_invoke(cf_cb_file_export_specified_packets_stopped, NULL);
4932       return CF_WRITE_ABORTED;
4933     break;
4934
4935   case PSP_FAILED:
4936     /* Error while saving.
4937        If we're writing to a temporary file, remove it. */
4938     if (fname_new != NULL)
4939       ws_unlink(fname_new);
4940     wtap_dump_close(pdh, &err);
4941     goto fail;
4942   }
4943
4944   if (!wtap_dump_close(pdh, &err)) {
4945     cf_close_failure_alert_box(fname, err);
4946     goto fail;
4947   }
4948
4949   if (fname_new != NULL) {
4950     /* We wrote out to fname_new, and should rename it on top of
4951        fname; fname is now closed, so that should be possible even
4952        on Windows.  Do the rename. */
4953     if (ws_rename(fname_new, fname) == -1) {
4954       /* Well, the rename failed. */
4955       cf_rename_failure_alert_box(fname, errno);
4956       goto fail;
4957     }
4958   }
4959
4960   cf_callback_invoke(cf_cb_file_export_specified_packets_finished, NULL);
4961   return CF_WRITE_OK;
4962
4963 fail:
4964   if (fname_new != NULL) {
4965     /* We were trying to write to a temporary file; get rid of it if it
4966        exists.  (We don't care whether this fails, as, if it fails,
4967        there's not much we can do about it.  I guess if it failed for
4968        a reason other than "it doesn't exist", we could report an
4969        error, so the user knows there's a junk file that they might
4970        want to clean up.) */
4971     ws_unlink(fname_new);
4972     g_free(fname_new);
4973   }
4974   cf_callback_invoke(cf_cb_file_export_specified_packets_failed, NULL);
4975   return CF_WRITE_ERROR;
4976 }
4977
4978 static void
4979 cf_open_failure_alert_box(const char *filename, int err, gchar *err_info,
4980                           gboolean for_writing, int file_type)
4981 {
4982   gchar *display_basename;
4983
4984   if (err < 0) {
4985     /* Wiretap error. */
4986     display_basename = g_filename_display_basename(filename);
4987     switch (err) {
4988
4989     case WTAP_ERR_NOT_REGULAR_FILE:
4990       simple_error_message_box(
4991             "The file \"%s\" is a \"special file\" or socket or other non-regular file.",
4992             display_basename);
4993       break;
4994
4995     case WTAP_ERR_RANDOM_OPEN_PIPE:
4996       /* Seen only when opening a capture file for reading. */
4997       simple_error_message_box(
4998             "The file \"%s\" is a pipe or FIFO; Wireshark can't read pipe or FIFO files.\n"
4999             "To capture from a pipe or FIFO use wireshark -i -",
5000             display_basename);
5001       break;
5002
5003     case WTAP_ERR_FILE_UNKNOWN_FORMAT:
5004       /* Seen only when opening a capture file for reading. */
5005       simple_error_message_box(
5006             "The file \"%s\" isn't a capture file in a format Wireshark understands.",
5007             display_basename);
5008       break;
5009
5010     case WTAP_ERR_UNSUPPORTED:
5011       /* Seen only when opening a capture file for reading. */
5012       simple_error_message_box(
5013             "The file \"%s\" isn't a capture file in a format Wireshark understands.\n"
5014             "(%s)",
5015             display_basename, err_info);
5016       g_free(err_info);
5017       break;
5018
5019     case WTAP_ERR_CANT_WRITE_TO_PIPE:
5020       /* Seen only when opening a capture file for writing. */
5021       simple_error_message_box(
5022             "The file \"%s\" is a pipe, and %s capture files can't be "
5023             "written to a pipe.",
5024             display_basename, wtap_file_type_subtype_string(file_type));
5025       break;
5026
5027     case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
5028       /* Seen only when opening a capture file for writing. */
5029       simple_error_message_box(
5030             "Wireshark doesn't support writing capture files in that format.");
5031       break;
5032
5033     case WTAP_ERR_UNSUPPORTED_ENCAP:
5034       if (for_writing) {
5035         simple_error_message_box("Wireshark can't save this capture in that format.");
5036       } else {
5037         simple_error_message_box(
5038               "The file \"%s\" is a capture for a network type that Wireshark doesn't support.\n"
5039               "(%s)",
5040               display_basename, err_info);
5041         g_free(err_info);
5042       }
5043       break;
5044
5045     case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
5046       if (for_writing) {
5047         simple_error_message_box(
5048               "Wireshark can't save this capture in that format.");
5049       } else {
5050         simple_error_message_box(
5051               "The file \"%s\" is a capture for a network type that Wireshark doesn't support.",
5052               display_basename);
5053       }
5054       break;
5055
5056     case WTAP_ERR_BAD_FILE:
5057       /* Seen only when opening a capture file for reading. */
5058       simple_error_message_box(
5059             "The file \"%s\" appears to be damaged or corrupt.\n"
5060             "(%s)",
5061             display_basename, err_info);
5062       g_free(err_info);
5063       break;
5064
5065     case WTAP_ERR_CANT_OPEN:
5066       if (for_writing) {
5067         simple_error_message_box(
5068               "The file \"%s\" could not be created for some unknown reason.",
5069               display_basename);
5070       } else {
5071         simple_error_message_box(
5072               "The file \"%s\" could not be opened for some unknown reason.",
5073               display_basename);
5074       }
5075       break;
5076
5077     case WTAP_ERR_SHORT_READ:
5078       simple_error_message_box(
5079             "The file \"%s\" appears to have been cut short"
5080             " in the middle of a packet or other data.",
5081             display_basename);
5082       break;
5083
5084     case WTAP_ERR_SHORT_WRITE:
5085       simple_error_message_box(
5086             "A full header couldn't be written to the file \"%s\".",
5087             display_basename);
5088       break;
5089
5090     case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
5091       simple_error_message_box(
5092             "This file type cannot be written as a compressed file.");
5093       break;
5094
5095     case WTAP_ERR_DECOMPRESS:
5096       simple_error_message_box(
5097             "The compressed file \"%s\" appears to be damaged or corrupt.\n"
5098             "(%s)", display_basename, err_info);
5099       g_free(err_info);
5100       break;
5101
5102     default:
5103       simple_error_message_box(
5104             "The file \"%s\" could not be %s: %s.",
5105             display_basename,
5106             for_writing ? "created" : "opened",
5107             wtap_strerror(err));
5108       break;
5109     }
5110     g_free(display_basename);
5111   } else {
5112     /* OS error. */
5113     open_failure_alert_box(filename, err, for_writing);
5114   }
5115 }
5116
5117 /*
5118  * XXX - whether we mention the source pathname, the target pathname,
5119  * or both depends on the error and on what we find if we look for
5120  * one or both of them.
5121  */
5122 static void
5123 cf_rename_failure_alert_box(const char *filename, int err)
5124 {
5125   gchar *display_basename;
5126
5127   display_basename = g_filename_display_basename(filename);
5128   switch (err) {
5129
5130   case ENOENT:
5131     /* XXX - should check whether the source exists and, if not,
5132        report it as the problem and, if so, report the destination
5133        as the problem. */
5134     simple_error_message_box("The path to the file \"%s\" doesn't exist.",
5135                              display_basename);
5136     break;
5137
5138   case EACCES:
5139     /* XXX - if we're doing a rename after a safe save, we should
5140        probably say something else. */
5141     simple_error_message_box("You don't have permission to move the capture file to \"%s\".",
5142                              display_basename);
5143     break;
5144
5145   default:
5146     /* XXX - this should probably mention both the source and destination
5147        pathnames. */
5148     simple_error_message_box("The file \"%s\" could not be moved: %s.",
5149                              display_basename, wtap_strerror(err));
5150     break;
5151   }
5152   g_free(display_basename);
5153 }
5154
5155 /* Check for write errors - if the file is being written to an NFS server,
5156    a write error may not show up until the file is closed, as NFS clients
5157    might not send writes to the server until the "write()" call finishes,
5158    so that the write may fail on the server but the "write()" may succeed. */
5159 static void
5160 cf_close_failure_alert_box(const char *filename, int err)
5161 {
5162   gchar *display_basename;
5163
5164   if (err < 0) {
5165     /* Wiretap error. */
5166     display_basename = g_filename_display_basename(filename);
5167     switch (err) {
5168
5169     case WTAP_ERR_CANT_CLOSE:
5170       simple_error_message_box(
5171             "The file \"%s\" couldn't be closed for some unknown reason.",
5172             display_basename);
5173       break;
5174
5175     case WTAP_ERR_SHORT_WRITE:
5176       simple_error_message_box(
5177             "Not all the packets could be written to the file \"%s\".",
5178                     display_basename);
5179       break;
5180
5181     default:
5182       simple_error_message_box(
5183             "An error occurred while closing the file \"%s\": %s.",
5184             display_basename, wtap_strerror(err));
5185       break;
5186     }
5187     g_free(display_basename);
5188   } else {
5189     /* OS error.
5190        We assume that a close error from the OS is really a write error. */
5191     write_failure_alert_box(filename, err);
5192   }
5193 }
5194
5195 /* Reload the current capture file. */
5196 void
5197 cf_reload(capture_file *cf) {
5198   gchar    *filename;
5199   gboolean  is_tempfile;
5200   int       err;
5201
5202   /* If the file could be opened, "cf_open()" calls "cf_close()"
5203      to get rid of state for the old capture file before filling in state
5204      for the new capture file.  "cf_close()" will remove the file if
5205      it's a temporary file; we don't want that to happen (for one thing,
5206      it'd prevent subsequent reopens from working).  Remember whether it's
5207      a temporary file, mark it as not being a temporary file, and then
5208      reopen it as the type of file it was.
5209
5210      Also, "cf_close()" will free "cf->filename", so we must make
5211      a copy of it first. */
5212   filename = g_strdup(cf->filename);
5213   is_tempfile = cf->is_tempfile;
5214   cf->is_tempfile = FALSE;
5215   if (cf_open(cf, filename, is_tempfile, &err) == CF_OK) {
5216     switch (cf_read(cf, TRUE)) {
5217
5218     case CF_READ_OK:
5219     case CF_READ_ERROR:
5220       /* Just because we got an error, that doesn't mean we were unable
5221          to read any of the file; we handle what we could get from the
5222          file. */
5223       break;
5224
5225     case CF_READ_ABORTED:
5226       /* The user bailed out of re-reading the capture file; the
5227          capture file has been closed - just free the capture file name
5228          string and return (without changing the last containing
5229          directory). */
5230       g_free(filename);
5231       return;
5232     }
5233   } else {
5234     /* The open failed, so "cf->is_tempfile" wasn't set to "is_tempfile".
5235        Instead, the file was left open, so we should restore "cf->is_tempfile"
5236        ourselves.
5237
5238        XXX - change the menu?  Presumably "cf_open()" will do that;
5239        make sure it does! */
5240     cf->is_tempfile = is_tempfile;
5241   }
5242   /* "cf_open()" made a copy of the file name we handed it, so
5243      we should free up our copy. */
5244   g_free(filename);
5245 }
5246
5247 /*
5248  * Editor modelines
5249  *
5250  * Local Variables:
5251  * c-basic-offset: 2
5252  * tab-width: 8
5253  * indent-tabs-mode: nil
5254  * End:
5255  *
5256  * ex: set shiftwidth=2 tabstop=8 expandtab:
5257  * :indentSize=2:tabSize=8:noTabs=true:
5258  */