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