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