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