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