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