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