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