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