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