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