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