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