Distinguish between "failed" and "user stopped it" for "save as" and
[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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, 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 const char *file_rename_error_message(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->count     = 0;
316   cf->displayed_count = 0;
317   cf->marked_count = 0;
318   cf->ignored_count = 0;
319   cf->ref_time_count = 0;
320   cf->drops_known = FALSE;
321   cf->drops     = 0;
322   cf->snap      = wtap_snapshot_length(cf->wth);
323   if (cf->snap == 0) {
324     /* Snapshot length not known. */
325     cf->has_snap = FALSE;
326     cf->snap = WTAP_MAX_PACKET_SIZE;
327   } else
328     cf->has_snap = TRUE;
329
330   /* Allocate a frame_data_sequence for the frames in this file */
331   cf->frames = new_frame_data_sequence();
332
333   nstime_set_zero(&cf->elapsed_time);
334   nstime_set_unset(&first_ts);
335   nstime_set_unset(&prev_dis_ts);
336   nstime_set_unset(&prev_cap_ts);
337   cum_bytes = 0;
338
339   /* Adjust timestamp precision if auto is selected, col width will be adjusted */
340   cf_timestamp_auto_precision(cf);
341   /* XXX needed ? */
342   new_packet_list_queue_draw();
343   fileset_file_opened(fname);
344
345   if(cf->cd_t == WTAP_FILE_BER) {
346     /* tell the BER dissector the file name */
347     ber_set_filename(cf->filename);
348   }
349
350   wtap_set_cb_new_ipv4(cf->wth, add_ipv4_name);
351   wtap_set_cb_new_ipv6(cf->wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
352
353   return CF_OK;
354
355 fail:
356   cf_open_failure_alert_box(fname, *err, err_info, FALSE, 0);
357   return CF_ERROR;
358 }
359
360
361 /*
362  * Reset the state for the currently closed file, but don't do the
363  * UI callbacks; this is for use in "cf_open()", where we don't
364  * want the UI to go from "file open" to "file closed" back to
365  * "file open", we want it to go from "old file open" to "new file
366  * open and being read".
367  *
368  * XXX - currently, cf_open() calls cf_close(), rather than
369  * cf_reset_state().
370  */
371 static void
372 cf_reset_state(capture_file *cf)
373 {
374   /* Die if we're in the middle of reading a file. */
375   g_assert(cf->state != FILE_READ_IN_PROGRESS);
376
377   if (cf->wth) {
378     wtap_close(cf->wth);
379     cf->wth = NULL;
380   }
381   /* We have no file open... */
382   if (cf->filename != NULL) {
383     /* If it's a temporary file, remove it. */
384     if (cf->is_tempfile)
385       ws_unlink(cf->filename);
386     g_free(cf->filename);
387     cf->filename = NULL;
388   }
389   /* ...which means we have no changes to that file to save. */
390   cf->unsaved_changes = FALSE;
391
392   dfilter_free(cf->rfcode);
393   cf->rfcode = NULL;
394   if (cf->frames != NULL) {
395     free_frame_data_sequence(cf->frames);
396     cf->frames = NULL;
397   }
398 #ifdef WANT_PACKET_EDITOR
399   if (cf->edited_frames) {
400     g_tree_destroy(cf->edited_frames);
401     cf->edited_frames = NULL;
402   }
403 #endif
404   cf_unselect_packet(cf);   /* nothing to select */
405   cf->first_displayed = 0;
406   cf->last_displayed = 0;
407
408   /* No frames, no frame selected, no field in that frame selected. */
409   cf->count = 0;
410   cf->current_frame = 0;
411   cf->current_row = 0;
412   cf->finfo_selected = NULL;
413
414   /* Clear the packet list. */
415   new_packet_list_freeze();
416   new_packet_list_clear();
417   new_packet_list_thaw();
418
419   cf->f_datalen = 0;
420   nstime_set_zero(&cf->elapsed_time);
421
422   reset_tap_listeners();
423
424   /* We have no file open. */
425   cf->state = FILE_CLOSED;
426
427   fileset_file_closed();
428 }
429
430 /* Reset everything to a pristine state */
431 void
432 cf_close(capture_file *cf)
433 {
434   if(cf->state != FILE_CLOSED) {
435     cf_callback_invoke(cf_cb_file_closing, cf);
436
437   /* close things, if not already closed before */
438     color_filters_cleanup();
439     cf_reset_state(cf);
440     cleanup_dissection();
441
442     cf_callback_invoke(cf_cb_file_closed, cf);
443   }
444 }
445
446 /* an out of memory exception occured, wait for a user button press to exit */
447 static void outofmemory_cb(gpointer dialog _U_, gint btn _U_, gpointer data _U_)
448 {
449     main_window_exit();
450 }
451
452 static float
453 calc_progbar_val(capture_file *cf, gint64 size, gint64 file_pos, gchar *status_str, gulong status_size)
454 {
455   float   progbar_val;
456
457   progbar_val = (gfloat) file_pos / (gfloat) size;
458   if (progbar_val > 1.0) {
459
460     /*  The file probably grew while we were reading it.
461      *  Update file size, and try again.
462      */
463     size = wtap_file_size(cf->wth, NULL);
464
465     if (size >= 0)
466       progbar_val = (gfloat) file_pos / (gfloat) size;
467
468     /*  If it's still > 1, either "wtap_file_size()" failed (in which
469      *  case there's not much we can do about it), or the file
470      *  *shrank* (in which case there's not much we can do about
471      *  it); just clip the progress value at 1.0.
472      */
473     if (progbar_val > 1.0f)
474       progbar_val = 1.0f;
475   }
476
477   g_snprintf(status_str, status_size,
478              "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
479              file_pos / 1024, size / 1024);
480
481   return progbar_val;
482 }
483
484 cf_read_status_t
485 cf_read(capture_file *cf, gboolean reloading)
486 {
487   int         err;
488   gchar       *err_info;
489   gchar       *name_ptr;
490   const char  *errmsg;
491   char         errmsg_errno[1024+1];
492   gint64       data_offset;
493   gint64       file_pos;
494   progdlg_t *volatile progbar = NULL;
495   gboolean     stop_flag;
496   volatile gint64 size;
497   volatile float progbar_val;
498   GTimeVal     start_time;
499   gchar        status_str[100];
500   volatile gint64 progbar_nextstep;
501   volatile gint64 progbar_quantum;
502   dfilter_t   *dfcode;
503   gboolean    filtering_tap_listeners;
504   guint       tap_flags;
505   volatile int count = 0;
506 #ifdef HAVE_LIBPCAP
507   volatile int displayed_once = 0;
508 #endif
509   gboolean compiled;
510
511   /* Compile the current display filter.
512    * We assume this will not fail since cf->dfilter is only set in
513    * cf_filter IFF the filter was valid.
514    */
515   compiled = dfilter_compile(cf->dfilter, &dfcode);
516   g_assert(!cf->dfilter || (compiled && dfcode));
517
518   /* Do we have any tap listeners with filters? */
519   filtering_tap_listeners = have_filtering_tap_listeners();
520
521   /* Get the union of the flags for all tap listeners. */
522   tap_flags = union_of_tap_listener_flags();
523
524   reset_tap_listeners();
525
526   name_ptr = g_filename_display_basename(cf->filename);
527
528   if (reloading)
529     cf_callback_invoke(cf_cb_file_reload_started, cf);
530   else
531     cf_callback_invoke(cf_cb_file_read_started, cf);
532
533   /* Record whether the file is compressed. */
534   cf->iscompressed = wtap_iscompressed(cf->wth);
535
536   /* Find the size of the file. */
537   size = wtap_file_size(cf->wth, NULL);
538
539   /* Update the progress bar when it gets to this value. */
540   progbar_nextstep = 0;
541   /* When we reach the value that triggers a progress bar update,
542      bump that value by this amount. */
543   if (size >= 0){
544     progbar_quantum = size/N_PROGBAR_UPDATES;
545     if (progbar_quantum < MIN_QUANTUM)
546       progbar_quantum = MIN_QUANTUM;
547   }else
548     progbar_quantum = 0;
549   /* Progress so far. */
550   progbar_val = 0.0f;
551
552   /* The packet list window will be empty untill the file is completly loaded */
553   new_packet_list_freeze();
554
555   stop_flag = FALSE;
556   g_get_current_time(&start_time);
557
558   while ((wtap_read(cf->wth, &err, &err_info, &data_offset))) {
559     if (size >= 0) {
560       count++;
561       file_pos = wtap_read_so_far(cf->wth);
562
563       /* Create the progress bar if necessary.
564        * Check whether it should be created or not every MIN_NUMBER_OF_PACKET
565        */
566       if ((progbar == NULL) && !(count % MIN_NUMBER_OF_PACKET)){
567         progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
568         if (reloading)
569           progbar = delayed_create_progress_dlg("Reloading", name_ptr,
570                                                 TRUE, &stop_flag, &start_time, progbar_val);
571         else
572           progbar = delayed_create_progress_dlg("Loading", name_ptr,
573                                                 TRUE, &stop_flag, &start_time, progbar_val);
574       }
575
576       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
577          when we update it, we have to run the GTK+ main loop to get it
578          to repaint what's pending, and doing so may involve an "ioctl()"
579          to see if there's any pending input from an X server, and doing
580          that for every packet can be costly, especially on a big file. */
581       if (file_pos >= progbar_nextstep) {
582         if (progbar != NULL) {
583           progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
584           /* update the packet bar content on the first run or frequently on very large files */
585 #ifdef HAVE_LIBPCAP
586           if (progbar_quantum > 500000 || displayed_once == 0) {
587             if ((auto_scroll_live || displayed_once == 0 || cf->displayed_count < 1000) && cf->count != 0) {
588               displayed_once = 1;
589               packets_bar_update();
590             }
591           }
592 #endif /* HAVE_LIBPCAP */
593           update_progress_dlg(progbar, progbar_val, status_str);
594         }
595         progbar_nextstep += progbar_quantum;
596       }
597     }
598
599     if (stop_flag) {
600       /* Well, the user decided to abort the read. He/She will be warned and
601          it might be enough for him/her to work with the already loaded
602          packets.
603          This is especially true for very large capture files, where you don't
604          want to wait loading the whole file (which may last minutes or even
605          hours even on fast machines) just to see that it was the wrong file. */
606       break;
607     }
608     TRY {
609       read_packet(cf, dfcode, filtering_tap_listeners, tap_flags, data_offset);
610     }
611     CATCH(OutOfMemoryError) {
612       gpointer dialog;
613
614       dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
615                              "%sOut Of Memory!%s\n"
616                              "\n"
617                              "Sorry, but Wireshark has to terminate now!\n"
618                              "\n"
619                              "Some infos / workarounds can be found at:\n"
620                              "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
621                              simple_dialog_primary_start(), simple_dialog_primary_end());
622       /* we have to terminate, as we cannot recover from the memory error */
623       simple_dialog_set_cb(dialog, outofmemory_cb, NULL);
624       while(1) {
625         main_window_update();
626         /* XXX - how to avoid a busy wait? */
627         /* Sleep(100); */
628       };
629       break;
630     }
631     ENDTRY;
632   }
633
634   /* Free the display name */
635   g_free(name_ptr);
636
637   /* Cleanup and release all dfilter resources */
638   if (dfcode != NULL){
639     dfilter_free(dfcode);
640   }
641
642   /* We're done reading the file; destroy the progress bar if it was created. */
643   if (progbar != NULL)
644     destroy_progress_dlg(progbar);
645
646   /* We're done reading sequentially through the file. */
647   cf->state = FILE_READ_DONE;
648
649   /* Close the sequential I/O side, to free up memory it requires. */
650   wtap_sequential_close(cf->wth);
651
652   /* Allow the protocol dissectors to free up memory that they
653    * don't need after the sequential run-through of the packets. */
654   postseq_cleanup_all_protocols();
655
656   /* compute the time it took to load the file */
657   compute_elapsed(&start_time);
658
659   /* Set the file encapsulation type now; we don't know what it is until
660      we've looked at all the packets, as we don't know until then whether
661      there's more than one type (and thus whether it's
662      WTAP_ENCAP_PER_PACKET). */
663   cf->lnk_t = wtap_file_encap(cf->wth);
664
665   cf->current_frame = frame_data_sequence_find(cf->frames, cf->first_displayed);
666   cf->current_row = 0;
667
668   new_packet_list_thaw();
669   if (reloading)
670     cf_callback_invoke(cf_cb_file_reload_finished, cf);
671   else
672     cf_callback_invoke(cf_cb_file_read_finished, cf);
673
674   /* If we have any displayed packets to select, select the first of those
675      packets by making the first row the selected row. */
676   if (cf->first_displayed != 0){
677     new_packet_list_select_first_row();
678   }
679
680   if(stop_flag) {
681     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
682                   "%sFile loading was cancelled!%s\n"
683                   "\n"
684                   "The remaining packets in the file were discarded.\n"
685                   "\n"
686                   "As a lot of packets from the original file will be missing,\n"
687                   "remember to be careful when saving the current content to a file.\n",
688                   simple_dialog_primary_start(), simple_dialog_primary_end());
689     return CF_READ_ERROR;
690   }
691
692   if (err != 0) {
693     /* Put up a message box noting that the read failed somewhere along
694        the line.  Don't throw out the stuff we managed to read, though,
695        if any. */
696     switch (err) {
697
698     case WTAP_ERR_UNSUPPORTED:
699       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
700                  "The capture file contains record data that TShark doesn't support.\n(%s)",
701                  err_info);
702       g_free(err_info);
703       errmsg = errmsg_errno;
704       break;
705
706     case WTAP_ERR_UNSUPPORTED_ENCAP:
707       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
708                  "The capture file has a packet with a network type that Wireshark doesn't support.\n(%s)",
709                  err_info);
710       g_free(err_info);
711       errmsg = errmsg_errno;
712       break;
713
714     case WTAP_ERR_CANT_READ:
715       errmsg = "An attempt to read from the capture file failed for"
716         " some unknown reason.";
717       break;
718
719     case WTAP_ERR_SHORT_READ:
720       errmsg = "The capture file appears to have been cut short"
721         " in the middle of a packet.";
722       break;
723
724     case WTAP_ERR_BAD_FILE:
725       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
726                  "The capture file appears to be damaged or corrupt.\n(%s)",
727                  err_info);
728       g_free(err_info);
729       errmsg = errmsg_errno;
730       break;
731
732     case WTAP_ERR_DECOMPRESS:
733       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
734                  "The compressed capture file appears to be damaged or corrupt.\n"
735                  "(%s)", err_info);
736       g_free(err_info);
737       errmsg = errmsg_errno;
738       break;
739
740     default:
741       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
742                  "An error occurred while reading the"
743                  " capture file: %s.", wtap_strerror(err));
744       errmsg = errmsg_errno;
745       break;
746     }
747     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", errmsg);
748     return CF_READ_ERROR;
749   } else
750     return CF_READ_OK;
751 }
752
753 #ifdef HAVE_LIBPCAP
754 cf_status_t
755 cf_start_tail(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
756 {
757   cf_status_t cf_status;
758
759   cf_status = cf_open(cf, fname, is_tempfile, err);
760   return cf_status;
761 }
762
763 cf_read_status_t
764 cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
765 {
766   gint64 data_offset = 0;
767   gchar *err_info;
768   volatile int newly_displayed_packets = 0;
769   dfilter_t   *dfcode;
770   gboolean filtering_tap_listeners;
771   guint tap_flags;
772   gboolean compiled;
773
774   /* Compile the current display filter.
775    * We assume this will not fail since cf->dfilter is only set in
776    * cf_filter IFF the filter was valid.
777    */
778   compiled = dfilter_compile(cf->dfilter, &dfcode);
779   g_assert(!cf->dfilter || (compiled && dfcode));
780
781   /* Do we have any tap listeners with filters? */
782   filtering_tap_listeners = have_filtering_tap_listeners();
783
784   /* Get the union of the flags for all tap listeners. */
785   tap_flags = union_of_tap_listener_flags();
786
787   *err = 0;
788
789   new_packet_list_check_end();
790   /* Don't freeze/thaw the list when doing live capture */
791   /*new_packet_list_freeze();*/
792
793   /*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: %u new: %u", cf->count, to_read);*/
794
795   while (to_read != 0) {
796     wtap_cleareof(cf->wth);
797     if (!wtap_read(cf->wth, err, &err_info, &data_offset)) {
798       break;
799     }
800     if (cf->state == FILE_READ_ABORTED) {
801       /* Well, the user decided to exit Wireshark.  Break out of the
802          loop, and let the code below (which is called even if there
803          aren't any packets left to read) exit. */
804       break;
805     }
806     TRY{
807       if (read_packet(cf, dfcode, filtering_tap_listeners, tap_flags,
808                       data_offset) != -1) {
809         newly_displayed_packets++;
810       }
811     }
812     CATCH(OutOfMemoryError) {
813       gpointer dialog;
814
815       dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
816                              "%sOut Of Memory!%s\n"
817                              "\n"
818                              "Sorry, but Wireshark has to terminate now!\n"
819                              "\n"
820                              "The capture file is not lost, it can be found at:\n"
821                              "%s\n"
822                              "\n"
823                              "Some infos / workarounds can be found at:\n"
824                              "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
825                              simple_dialog_primary_start(), simple_dialog_primary_end(), cf->filename);
826       /* we have to terminate, as we cannot recover from the memory error */
827       simple_dialog_set_cb(dialog, outofmemory_cb, NULL);
828       while(1) {
829         main_window_update();
830         /* XXX - how to avoid a busy wait? */
831         /* Sleep(100); */
832       };
833       /* Don't freeze/thaw the list when doing live capture */
834       /*new_packet_list_thaw();*/
835       return CF_READ_ABORTED;
836     }
837     ENDTRY;
838     to_read--;
839   }
840
841   /* Update the file encapsulation; it might have changed based on the
842      packets we've read. */
843   cf->lnk_t = wtap_file_encap(cf->wth);
844
845   /* Cleanup and release all dfilter resources */
846   if (dfcode != NULL){
847     dfilter_free(dfcode);
848   }
849
850   /*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: count %u state: %u err: %u",
851     cf->count, cf->state, *err);*/
852
853   /* Don't freeze/thaw the list when doing live capture */
854   /*new_packet_list_thaw();*/
855   /* With the new packet list the first packet
856    * isn't automatically selected.
857    */
858   if(!cf->current_frame)
859     new_packet_list_select_first_row();
860
861   /* moving to the end of the packet list - if the user requested so and
862      we have some new packets. */
863   if (newly_displayed_packets && auto_scroll_live && cf->count != 0)
864       new_packet_list_moveto_end();
865
866   if (cf->state == FILE_READ_ABORTED) {
867     /* Well, the user decided to exit Wireshark.  Return CF_READ_ABORTED
868        so that our caller can kill off the capture child process;
869        this will cause an EOF on the pipe from the child, so
870        "cf_finish_tail()" will be called, and it will clean up
871        and exit. */
872     return CF_READ_ABORTED;
873   } else if (*err != 0) {
874     /* We got an error reading the capture file.
875        XXX - pop up a dialog box instead? */
876     g_warning("Error \"%s\" while reading: \"%s\"\n",
877         wtap_strerror(*err), cf->filename);
878
879     return CF_READ_ERROR;
880   } else
881     return CF_READ_OK;
882 }
883
884 void
885 cf_fake_continue_tail(capture_file *cf) {
886   cf->state = FILE_READ_DONE;
887 }
888
889 cf_read_status_t
890 cf_finish_tail(capture_file *cf, int *err)
891 {
892   gchar *err_info;
893   gint64 data_offset;
894   dfilter_t   *dfcode;
895   gboolean filtering_tap_listeners;
896   guint tap_flags;
897   gboolean compiled;
898
899   /* Compile the current display filter.
900    * We assume this will not fail since cf->dfilter is only set in
901    * cf_filter IFF the filter was valid.
902    */
903   compiled = dfilter_compile(cf->dfilter, &dfcode);
904   g_assert(!cf->dfilter || (compiled && dfcode));
905
906   /* Do we have any tap listeners with filters? */
907   filtering_tap_listeners = have_filtering_tap_listeners();
908
909   /* Get the union of the flags for all tap listeners. */
910   tap_flags = union_of_tap_listener_flags();
911
912   if(cf->wth == NULL) {
913     cf_close(cf);
914     return CF_READ_ERROR;
915   }
916
917   new_packet_list_check_end();
918   /* Don't freeze/thaw the list when doing live capture */
919   /*new_packet_list_freeze();*/
920
921   while ((wtap_read(cf->wth, err, &err_info, &data_offset))) {
922     if (cf->state == FILE_READ_ABORTED) {
923       /* Well, the user decided to abort the read.  Break out of the
924          loop, and let the code below (which is called even if there
925      aren't any packets left to read) exit. */
926       break;
927     }
928     read_packet(cf, dfcode, filtering_tap_listeners, tap_flags, data_offset);
929   }
930
931   /* Cleanup and release all dfilter resources */
932   if (dfcode != NULL){
933     dfilter_free(dfcode);
934   }
935
936   /* Don't freeze/thaw the list when doing live capture */
937   /*new_packet_list_thaw();*/
938
939   if (cf->state == FILE_READ_ABORTED) {
940     /* Well, the user decided to abort the read.  We're only called
941        when the child capture process closes the pipe to us (meaning
942        it's probably exited), so we can just close the capture
943        file; we return CF_READ_ABORTED so our caller can do whatever
944        is appropriate when that happens. */
945     cf_close(cf);
946     return CF_READ_ABORTED;
947   }
948
949   if (auto_scroll_live && cf->count != 0)
950     new_packet_list_moveto_end();
951
952   /* We're done reading sequentially through the file. */
953   cf->state = FILE_READ_DONE;
954
955   /* We're done reading sequentially through the file; close the
956      sequential I/O side, to free up memory it requires. */
957   wtap_sequential_close(cf->wth);
958
959   /* Allow the protocol dissectors to free up memory that they
960    * don't need after the sequential run-through of the packets. */
961   postseq_cleanup_all_protocols();
962
963   /* Update the file encapsulation; it might have changed based on the
964      packets we've read. */
965   cf->lnk_t = wtap_file_encap(cf->wth);
966
967   if (*err != 0) {
968     /* We got an error reading the capture file.
969        XXX - pop up a dialog box? */
970     return CF_READ_ERROR;
971   } else {
972     return CF_READ_OK;
973   }
974 }
975 #endif /* HAVE_LIBPCAP */
976
977 gchar *
978 cf_get_display_name(capture_file *cf)
979 {
980   gchar *displayname;
981
982   /* Return a name to use in displays */
983   if (!cf->is_tempfile) {
984     /* Get the last component of the file name, and use that. */
985     if (cf->filename){
986       displayname = g_filename_display_basename(cf->filename);
987     } else {
988       displayname=g_strdup("(No file)");
989     }
990   } else {
991     /* The file we read is a temporary file from a live capture or
992        a merge operation; we don't mention its name, but, if it's
993        from a capture, give the source of the capture. */
994     if (cf->source) {
995       displayname = g_strdup(cf->source);
996     } else {
997       displayname = g_strdup("(Untitled)");
998     }
999   }
1000   return displayname;
1001 }
1002
1003 void cf_set_tempfile_source(capture_file *cf, gchar *source) {
1004   if (cf->source) {
1005     g_free(cf->source);
1006   }
1007
1008   if (source) {
1009     cf->source = g_strdup(source);
1010   } else {
1011     cf->source = g_strdup("");
1012   }
1013 }
1014
1015 const gchar *cf_get_tempfile_source(capture_file *cf) {
1016   if (!cf->source) {
1017     return "";
1018   }
1019
1020   return cf->source;
1021 }
1022
1023 /* XXX - use a macro instead? */
1024 int
1025 cf_get_packet_count(capture_file *cf)
1026 {
1027   return cf->count;
1028 }
1029
1030 /* XXX - use a macro instead? */
1031 void
1032 cf_set_packet_count(capture_file *cf, int packet_count)
1033 {
1034   cf->count = packet_count;
1035 }
1036
1037 /* XXX - use a macro instead? */
1038 gboolean
1039 cf_is_tempfile(capture_file *cf)
1040 {
1041   return cf->is_tempfile;
1042 }
1043
1044 void cf_set_tempfile(capture_file *cf, gboolean is_tempfile)
1045 {
1046   cf->is_tempfile = is_tempfile;
1047 }
1048
1049
1050 /* XXX - use a macro instead? */
1051 void cf_set_drops_known(capture_file *cf, gboolean drops_known)
1052 {
1053   cf->drops_known = drops_known;
1054 }
1055
1056 /* XXX - use a macro instead? */
1057 void cf_set_drops(capture_file *cf, guint32 drops)
1058 {
1059   cf->drops = drops;
1060 }
1061
1062 /* XXX - use a macro instead? */
1063 gboolean cf_get_drops_known(capture_file *cf)
1064 {
1065   return cf->drops_known;
1066 }
1067
1068 /* XXX - use a macro instead? */
1069 guint32 cf_get_drops(capture_file *cf)
1070 {
1071   return cf->drops;
1072 }
1073
1074 void cf_set_rfcode(capture_file *cf, dfilter_t *rfcode)
1075 {
1076   cf->rfcode = rfcode;
1077 }
1078
1079 static void
1080 find_and_mark_frame_depended_upon(gpointer data, gpointer user_data)
1081 {
1082   frame_data *dependent_fd;
1083   guint32 dependent_frame = GPOINTER_TO_UINT(data);
1084   capture_file *cf = (capture_file *)user_data;
1085
1086   dependent_fd = frame_data_sequence_find(cf->frames, dependent_frame);
1087   dependent_fd->flags.dependent_of_displayed = 1;
1088 }
1089
1090 static int
1091 add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
1092     dfilter_t *dfcode, gboolean filtering_tap_listeners,
1093     guint tap_flags,
1094     union wtap_pseudo_header *pseudo_header, const guchar *buf,
1095     gboolean refilter,
1096     gboolean add_to_packet_list)
1097 {
1098   gboolean  create_proto_tree = FALSE;
1099   epan_dissect_t edt;
1100   column_info *cinfo;
1101   gint row = -1;
1102
1103   cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
1104
1105   frame_data_set_before_dissect(fdata, &cf->elapsed_time,
1106                                 &first_ts, &prev_dis_ts, &prev_cap_ts);
1107
1108   /* If either
1109     + we have a display filter and are re-applying it;
1110     + we have tap listeners with filters;
1111     + we have tap listeners that require a protocol tree;
1112
1113      allocate a protocol tree root node, so that we'll construct
1114      a protocol tree against which a filter expression can be
1115      evaluated. */
1116   if ((dfcode != NULL && refilter) ||
1117       filtering_tap_listeners || (tap_flags & TL_REQUIRES_PROTO_TREE))
1118       create_proto_tree = TRUE;
1119
1120   /* Dissect the frame. */
1121   epan_dissect_init(&edt, create_proto_tree, FALSE);
1122
1123   if (dfcode != NULL && refilter) {
1124       epan_dissect_prime_dfilter(&edt, dfcode);
1125   }
1126
1127   tap_queue_init(&edt);
1128   epan_dissect_run(&edt, pseudo_header, buf, fdata, cinfo);
1129   tap_push_tapped_queue(&edt);
1130
1131   /* If we have a display filter, apply it if we're refiltering, otherwise
1132      leave the "passed_dfilter" flag alone.
1133
1134      If we don't have a display filter, set "passed_dfilter" to 1. */
1135   if (dfcode != NULL) {
1136     if (refilter) {
1137       fdata->flags.passed_dfilter = dfilter_apply_edt(dfcode, &edt) ? 1 : 0;
1138
1139       if (fdata->flags.passed_dfilter) {
1140         /* This frame passed the display filter but it may depend on other
1141          * (potentially not displayed) frames.  Find those frames and mark them
1142          * as depended upon.
1143          */
1144         g_slist_foreach(edt.pi.dependent_frames, find_and_mark_frame_depended_upon, cf);
1145       }
1146     }
1147   } else
1148     fdata->flags.passed_dfilter = 1;
1149
1150   if(fdata->flags.passed_dfilter || fdata->flags.ref_time)
1151     cf->displayed_count++;
1152
1153   if (add_to_packet_list) {
1154     /* We fill the needed columns from new_packet_list */
1155       row = new_packet_list_append(cinfo, fdata, &edt.pi);
1156   }
1157
1158   if(fdata->flags.passed_dfilter || fdata->flags.ref_time)
1159   {
1160     frame_data_set_after_dissect(fdata, &cum_bytes, &prev_dis_ts);
1161
1162     /* If we haven't yet seen the first frame, this is it.
1163
1164        XXX - we must do this before we add the row to the display,
1165        as, if the display's GtkCList's selection mode is
1166        GTK_SELECTION_BROWSE, when the first entry is added to it,
1167        "cf_select_packet()" will be called, and it will fetch the row
1168        data for the 0th row, and will get a null pointer rather than
1169        "fdata", as "gtk_clist_append()" won't yet have returned and
1170        thus "gtk_clist_set_row_data()" won't yet have been called.
1171
1172        We thus need to leave behind bread crumbs so that
1173        "cf_select_packet()" can find this frame.  See the comment
1174        in "cf_select_packet()". */
1175     if (cf->first_displayed == 0)
1176       cf->first_displayed = fdata->num;
1177
1178     /* This is the last frame we've seen so far. */
1179     cf->last_displayed = fdata->num;
1180   }
1181
1182   epan_dissect_cleanup(&edt);
1183   return row;
1184 }
1185
1186 /* read in a new packet */
1187 /* returns the row of the new packet in the packet list or -1 if not displayed */
1188 static int
1189 read_packet(capture_file *cf, dfilter_t *dfcode,
1190             gboolean filtering_tap_listeners, guint tap_flags, gint64 offset)
1191 {
1192   const struct wtap_pkthdr *phdr = wtap_phdr(cf->wth);
1193   union wtap_pseudo_header *pseudo_header = wtap_pseudoheader(cf->wth);
1194   const guchar *buf = wtap_buf_ptr(cf->wth);
1195   frame_data    fdlocal;
1196   guint32       framenum;
1197   frame_data   *fdata;
1198   int           passed;
1199   int           row = -1;
1200
1201   /* The frame number of this packet is one more than the count of
1202      frames in this packet. */
1203   framenum = cf->count + 1;
1204
1205   frame_data_init(&fdlocal, framenum, phdr, offset, cum_bytes);
1206
1207   passed = TRUE;
1208   if (cf->rfcode) {
1209     epan_dissect_t edt;
1210     epan_dissect_init(&edt, TRUE, FALSE);
1211     epan_dissect_prime_dfilter(&edt, cf->rfcode);
1212     epan_dissect_run(&edt, pseudo_header, buf, &fdlocal, NULL);
1213     passed = dfilter_apply_edt(cf->rfcode, &edt);
1214     epan_dissect_cleanup(&edt);
1215   }
1216
1217   if (passed) {
1218     /* This does a shallow copy of fdlocal, which is good enough. */
1219     fdata = frame_data_sequence_add(cf->frames, &fdlocal);
1220
1221     cf->count++;
1222     cf->f_datalen = offset + fdlocal.cap_len;
1223
1224     if (!cf->redissecting) {
1225       row = add_packet_to_packet_list(fdata, cf, dfcode,
1226                                       filtering_tap_listeners, tap_flags,
1227                                       pseudo_header, buf, TRUE, TRUE);
1228     }
1229   }
1230
1231   return row;
1232 }
1233
1234 cf_status_t
1235 cf_merge_files(char **out_filenamep, int in_file_count,
1236                char *const *in_filenames, int file_type, gboolean do_append)
1237 {
1238   merge_in_file_t  *in_files, *in_file;
1239   char             *out_filename;
1240   char             *tmpname;
1241   int               out_fd;
1242   wtap_dumper      *pdh;
1243   int               open_err, read_err, write_err, close_err;
1244   gchar            *err_info;
1245   int               err_fileno;
1246   int               i;
1247   char              errmsg_errno[1024+1];
1248   const char       *errmsg;
1249   gboolean          got_read_error = FALSE, got_write_error = FALSE;
1250   gint64            data_offset;
1251   progdlg_t        *progbar = NULL;
1252   gboolean          stop_flag;
1253   gint64            f_len, file_pos;
1254   float             progbar_val;
1255   GTimeVal          start_time;
1256   gchar             status_str[100];
1257   gint64            progbar_nextstep;
1258   gint64            progbar_quantum;
1259
1260   /* open the input files */
1261   if (!merge_open_in_files(in_file_count, in_filenames, &in_files,
1262                            &open_err, &err_info, &err_fileno)) {
1263     g_free(in_files);
1264     cf_open_failure_alert_box(in_filenames[err_fileno], open_err, err_info,
1265                               FALSE, 0);
1266     return CF_ERROR;
1267   }
1268
1269   if (*out_filenamep != NULL) {
1270     out_filename = *out_filenamep;
1271     out_fd = ws_open(out_filename, O_CREAT|O_TRUNC|O_BINARY, 0600);
1272     if (out_fd == -1)
1273       open_err = errno;
1274   } else {
1275     out_fd = create_tempfile(&tmpname, "wireshark");
1276     if (out_fd == -1)
1277       open_err = errno;
1278     out_filename = g_strdup(tmpname);
1279     *out_filenamep = out_filename;
1280   }
1281   if (out_fd == -1) {
1282     err_info = NULL;
1283     merge_close_in_files(in_file_count, in_files);
1284     g_free(in_files);
1285     cf_open_failure_alert_box(out_filename, open_err, NULL, TRUE, file_type);
1286     return CF_ERROR;
1287   }
1288
1289   pdh = wtap_dump_fdopen(out_fd, file_type,
1290       merge_select_frame_type(in_file_count, in_files),
1291       merge_max_snapshot_length(in_file_count, in_files),
1292       FALSE /* compressed */, &open_err);
1293   if (pdh == NULL) {
1294     ws_close(out_fd);
1295     merge_close_in_files(in_file_count, in_files);
1296     g_free(in_files);
1297     cf_open_failure_alert_box(out_filename, open_err, err_info, TRUE,
1298                               file_type);
1299     return CF_ERROR;
1300   }
1301
1302   /* Get the sum of the sizes of all the files. */
1303   f_len = 0;
1304   for (i = 0; i < in_file_count; i++)
1305     f_len += in_files[i].size;
1306
1307   /* Update the progress bar when it gets to this value. */
1308   progbar_nextstep = 0;
1309   /* When we reach the value that triggers a progress bar update,
1310      bump that value by this amount. */
1311   progbar_quantum = f_len/N_PROGBAR_UPDATES;
1312   /* Progress so far. */
1313   progbar_val = 0.0f;
1314
1315   stop_flag = FALSE;
1316   g_get_current_time(&start_time);
1317
1318   /* do the merge (or append) */
1319   for (;;) {
1320     if (do_append)
1321       in_file = merge_append_read_packet(in_file_count, in_files, &read_err,
1322                                          &err_info);
1323     else
1324       in_file = merge_read_packet(in_file_count, in_files, &read_err,
1325                                   &err_info);
1326     if (in_file == NULL) {
1327       /* EOF */
1328       break;
1329     }
1330
1331     if (read_err != 0) {
1332       /* I/O error reading from in_file */
1333       got_read_error = TRUE;
1334       break;
1335     }
1336
1337     /* Get the sum of the data offsets in all of the files. */
1338     data_offset = 0;
1339     for (i = 0; i < in_file_count; i++)
1340       data_offset += in_files[i].data_offset;
1341
1342     /* Create the progress bar if necessary.
1343        We check on every iteration of the loop, so that it takes no
1344        longer than the standard time to create it (otherwise, for a
1345        large file, we might take considerably longer than that standard
1346        time in order to get to the next progress bar step). */
1347     if (progbar == NULL) {
1348       progbar = delayed_create_progress_dlg("Merging", "files",
1349         FALSE, &stop_flag, &start_time, progbar_val);
1350     }
1351
1352     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1353        when we update it, we have to run the GTK+ main loop to get it
1354        to repaint what's pending, and doing so may involve an "ioctl()"
1355        to see if there's any pending input from an X server, and doing
1356        that for every packet can be costly, especially on a big file. */
1357     if (data_offset >= progbar_nextstep) {
1358         /* Get the sum of the seek positions in all of the files. */
1359         file_pos = 0;
1360         for (i = 0; i < in_file_count; i++)
1361           file_pos += wtap_read_so_far(in_files[i].wth);
1362         progbar_val = (gfloat) file_pos / (gfloat) f_len;
1363         if (progbar_val > 1.0f) {
1364           /* Some file probably grew while we were reading it.
1365              That "shouldn't happen", so we'll just clip the progress
1366              value at 1.0. */
1367           progbar_val = 1.0f;
1368         }
1369         if (progbar != NULL) {
1370           g_snprintf(status_str, sizeof(status_str),
1371                      "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
1372                      file_pos / 1024, f_len / 1024);
1373           update_progress_dlg(progbar, progbar_val, status_str);
1374         }
1375         progbar_nextstep += progbar_quantum;
1376     }
1377
1378     if (stop_flag) {
1379       /* Well, the user decided to abort the merge. */
1380       break;
1381     }
1382
1383     if (!wtap_dump(pdh, wtap_phdr(in_file->wth), wtap_pseudoheader(in_file->wth),
1384          wtap_buf_ptr(in_file->wth), &write_err)) {
1385       got_write_error = TRUE;
1386       break;
1387     }
1388   }
1389
1390   /* We're done merging the files; destroy the progress bar if it was created. */
1391   if (progbar != NULL)
1392     destroy_progress_dlg(progbar);
1393
1394   merge_close_in_files(in_file_count, in_files);
1395   if (!got_read_error && !got_write_error) {
1396     if (!wtap_dump_close(pdh, &write_err))
1397       got_write_error = TRUE;
1398   } else
1399     wtap_dump_close(pdh, &close_err);
1400
1401   if (got_read_error) {
1402     /*
1403      * Find the file on which we got the error, and report the error.
1404      */
1405     for (i = 0; i < in_file_count; i++) {
1406       if (in_files[i].state == GOT_ERROR) {
1407         /* Put up a message box noting that a read failed somewhere along
1408            the line. */
1409         switch (read_err) {
1410
1411         case WTAP_ERR_UNSUPPORTED_ENCAP:
1412           g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1413                      "The capture file %%s has a packet with a network type that Wireshark doesn't support.\n(%s)",
1414                      err_info);
1415           g_free(err_info);
1416           errmsg = errmsg_errno;
1417           break;
1418
1419         case WTAP_ERR_CANT_READ:
1420           errmsg = "An attempt to read from the capture file %s failed for"
1421                    " some unknown reason.";
1422           break;
1423
1424         case WTAP_ERR_SHORT_READ:
1425           errmsg = "The capture file %s appears to have been cut short"
1426                    " in the middle of a packet.";
1427           break;
1428
1429         case WTAP_ERR_BAD_FILE:
1430           g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1431                      "The capture file %%s appears to be damaged or corrupt.\n(%s)",
1432                      err_info);
1433           g_free(err_info);
1434           errmsg = errmsg_errno;
1435           break;
1436
1437         case WTAP_ERR_DECOMPRESS:
1438           g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1439                      "The compressed capture file %%s appears to be damaged or corrupt.\n"
1440                      "(%s)", err_info);
1441           g_free(err_info);
1442           errmsg = errmsg_errno;
1443           break;
1444
1445         default:
1446           g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1447                      "An error occurred while reading the"
1448                      " capture file %%s: %s.", wtap_strerror(read_err));
1449           errmsg = errmsg_errno;
1450           break;
1451         }
1452         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, errmsg, in_files[i].filename);
1453       }
1454     }
1455   }
1456
1457   if (got_write_error) {
1458     /* Put up an alert box for the write error. */
1459     if (write_err < 0) {
1460       /* Wiretap error. */
1461       switch (write_err) {
1462
1463       case WTAP_ERR_UNSUPPORTED_ENCAP:
1464         /*
1465          * This is a problem with the particular frame we're writing;
1466          * note that, and give the frame number.
1467          */
1468         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1469                       "Frame %u of \"%s\" has a network type that can't be saved in a \"%s\" file.",
1470                       in_file->packet_num, in_file->filename,
1471                       wtap_file_type_string(file_type));
1472         break;
1473
1474       default:
1475         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1476                       "An error occurred while writing to the file \"%s\": %s.",
1477                       out_filename, wtap_strerror(write_err));
1478         break;
1479       }
1480     } else {
1481       /* OS error. */
1482       write_failure_alert_box(out_filename, write_err);
1483     }
1484   }
1485
1486   if (got_read_error || got_write_error || stop_flag) {
1487     /* Callers aren't expected to treat an error or an explicit abort
1488        differently - we put up error dialogs ourselves, so they don't
1489        have to. */
1490     return CF_ERROR;
1491   } else
1492     return CF_OK;
1493 }
1494
1495 cf_status_t
1496 cf_filter_packets(capture_file *cf, gchar *dftext, gboolean force)
1497 {
1498   const char *filter_new = dftext ? dftext : "";
1499   const char *filter_old = cf->dfilter ? cf->dfilter : "";
1500   dfilter_t   *dfcode;
1501   GTimeVal     start_time;
1502
1503   /* if new filter equals old one, do nothing unless told to do so */
1504   if (!force && strcmp(filter_new, filter_old) == 0) {
1505     return CF_OK;
1506   }
1507
1508   dfcode=NULL;
1509
1510   if (dftext == NULL) {
1511     /* The new filter is an empty filter (i.e., display all packets).
1512      * so leave dfcode==NULL
1513      */
1514   } else {
1515     /*
1516      * We have a filter; make a copy of it (as we'll be saving it),
1517      * and try to compile it.
1518      */
1519     dftext = g_strdup(dftext);
1520     if (!dfilter_compile(dftext, &dfcode)) {
1521       /* The attempt failed; report an error. */
1522       gchar *safe_dftext = simple_dialog_format_message(dftext);
1523       gchar *safe_dfilter_error_msg = simple_dialog_format_message(
1524       dfilter_error_msg);
1525       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1526           "%s%s%s\n"
1527           "\n"
1528           "The following display filter isn't a valid display filter:\n%s\n"
1529           "See the help for a description of the display filter syntax.",
1530           simple_dialog_primary_start(), safe_dfilter_error_msg,
1531           simple_dialog_primary_end(), safe_dftext);
1532       g_free(safe_dfilter_error_msg);
1533       g_free(safe_dftext);
1534       g_free(dftext);
1535       return CF_ERROR;
1536     }
1537
1538     /* Was it empty? */
1539     if (dfcode == NULL) {
1540       /* Yes - free the filter text, and set it to null. */
1541       g_free(dftext);
1542       dftext = NULL;
1543     }
1544   }
1545
1546   /* We have a valid filter.  Replace the current filter. */
1547   g_free(cf->dfilter);
1548   cf->dfilter = dftext;
1549   g_get_current_time(&start_time);
1550
1551
1552   /* Now rescan the packet list, applying the new filter, but not
1553      throwing away information constructed on a previous pass. */
1554   if (dftext == NULL) {
1555     rescan_packets(cf, "Resetting", "Filter", TRUE, FALSE);
1556   } else {
1557     rescan_packets(cf, "Filtering", dftext, TRUE, FALSE);
1558   }
1559
1560   /* Cleanup and release all dfilter resources */
1561   dfilter_free(dfcode);
1562
1563   return CF_OK;
1564 }
1565
1566 void
1567 cf_reftime_packets(capture_file *cf)
1568 {
1569
1570   ref_time_packets(cf);
1571 }
1572
1573 void
1574 cf_redissect_packets(capture_file *cf)
1575 {
1576   rescan_packets(cf, "Reprocessing", "all packets", TRUE, TRUE);
1577 }
1578
1579 gboolean
1580 cf_read_frame_r(capture_file *cf, frame_data *fdata,
1581                 union wtap_pseudo_header *pseudo_header, guint8 *pd)
1582 {
1583   int err;
1584   gchar *err_info;
1585   char errmsg_errno[1024+1];
1586
1587 #ifdef WANT_PACKET_EDITOR
1588   /* if fdata->file_off == -1 it means packet was edited, and we must find data inside edited_frames tree */
1589   if (G_UNLIKELY(fdata->file_off == -1)) {
1590     const modified_frame_data *frame = (const modified_frame_data *) g_tree_lookup(cf->edited_frames, GINT_TO_POINTER(fdata->num));
1591
1592     if (!frame) {
1593       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "fdata->file_off == -1, but can't find modified frame!");
1594       return FALSE;
1595     }
1596
1597     *pseudo_header = frame->ph;
1598     memcpy(pd, frame->pd, fdata->cap_len);
1599     return TRUE;
1600   }
1601 #endif
1602
1603   if (!wtap_seek_read(cf->wth, fdata->file_off, pseudo_header, pd,
1604                       fdata->cap_len, &err, &err_info)) {
1605     switch (err) {
1606
1607     case WTAP_ERR_UNSUPPORTED_ENCAP:
1608       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1609                  "The file \"%%s\" has a packet with a network type that Wireshark doesn't support.\n(%s)",
1610                  err_info);
1611       g_free(err_info);
1612       break;
1613
1614     case WTAP_ERR_BAD_FILE:
1615       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1616                  "An error occurred while reading from the file \"%%s\": %s.\n(%s)",
1617                  wtap_strerror(err), err_info);
1618       g_free(err_info);
1619       break;
1620
1621     default:
1622       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1623                  "An error occurred while reading from the file \"%%s\": %s.",
1624                  wtap_strerror(err));
1625       break;
1626     }
1627     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, errmsg_errno, cf->filename);
1628     return FALSE;
1629   }
1630   return TRUE;
1631 }
1632
1633 gboolean
1634 cf_read_frame(capture_file *cf, frame_data *fdata)
1635 {
1636   return cf_read_frame_r(cf, fdata, &cf->pseudo_header, cf->pd);
1637 }
1638
1639 /* Rescan the list of packets, reconstructing the CList.
1640
1641    "action" describes why we're doing this; it's used in the progress
1642    dialog box.
1643
1644    "action_item" describes what we're doing; it's used in the progress
1645    dialog box.
1646
1647    "refilter" is TRUE if we need to re-evaluate the filter expression.
1648
1649    "redissect" is TRUE if we need to make the dissectors reconstruct
1650    any state information they have (because a preference that affects
1651    some dissector has changed, meaning some dissector might construct
1652    its state differently from the way it was constructed the last time). */
1653 static void
1654 rescan_packets(capture_file *cf, const char *action, const char *action_item,
1655         gboolean refilter, gboolean redissect)
1656 {
1657   /* Rescan packets new packet list */
1658   guint32     framenum;
1659   frame_data *fdata;
1660   progdlg_t  *progbar = NULL;
1661   gboolean    stop_flag;
1662   int         count;
1663   frame_data *selected_frame, *preceding_frame, *following_frame, *prev_frame;
1664   int         selected_frame_num, preceding_frame_num, following_frame_num, prev_frame_num;
1665   gboolean    selected_frame_seen;
1666   float       progbar_val;
1667   GTimeVal    start_time;
1668   gchar       status_str[100];
1669   int         progbar_nextstep;
1670   int         progbar_quantum;
1671   dfilter_t   *dfcode;
1672   gboolean    filtering_tap_listeners;
1673   guint       tap_flags;
1674   gboolean    add_to_packet_list = FALSE;
1675   gboolean compiled;
1676
1677   /* Compile the current display filter.
1678    * We assume this will not fail since cf->dfilter is only set in
1679    * cf_filter IFF the filter was valid.
1680    */
1681   compiled = dfilter_compile(cf->dfilter, &dfcode);
1682   g_assert(!cf->dfilter || (compiled && dfcode));
1683
1684   /* Do we have any tap listeners with filters? */
1685   filtering_tap_listeners = have_filtering_tap_listeners();
1686
1687   /* Get the union of the flags for all tap listeners. */
1688   tap_flags = union_of_tap_listener_flags();
1689
1690   reset_tap_listeners();
1691   /* Which frame, if any, is the currently selected frame?
1692      XXX - should the selected frame or the focus frame be the "current"
1693      frame, that frame being the one from which "Find Frame" searches
1694      start? */
1695   selected_frame = cf->current_frame;
1696
1697   /* Mark frame num as not found */
1698   selected_frame_num = -1;
1699
1700   /* Freeze the packet list while we redo it, so we don't get any
1701      screen updates while it happens. */
1702   new_packet_list_freeze();
1703
1704   if (redissect) {
1705     /* We need to re-initialize all the state information that protocols
1706        keep, because some preference that controls a dissector has changed,
1707        which might cause the state information to be constructed differently
1708        by that dissector. */
1709
1710     /* We might receive new packets while redissecting, and we don't
1711        want to dissect those before their time. */
1712     cf->redissecting = TRUE;
1713
1714     /* Cleanup all data structures used for dissection. */
1715     cleanup_dissection();
1716     /* Initialize all data structures used for dissection. */
1717     init_dissection();
1718
1719     /* We need to redissect the packets so we have to discard our old
1720      * packet list store. */
1721     new_packet_list_clear();
1722     add_to_packet_list = TRUE;
1723   }
1724
1725   /* We don't yet know which will be the first and last frames displayed. */
1726   cf->first_displayed = 0;
1727   cf->last_displayed = 0;
1728
1729   /* We currently don't display any packets */
1730   cf->displayed_count = 0;
1731
1732   /* Iterate through the list of frames.  Call a routine for each frame
1733      to check whether it should be displayed and, if so, add it to
1734      the display list. */
1735   nstime_set_unset(&first_ts);
1736   nstime_set_unset(&prev_dis_ts);
1737   nstime_set_unset(&prev_cap_ts);
1738   cum_bytes = 0;
1739
1740   /* Update the progress bar when it gets to this value. */
1741   progbar_nextstep = 0;
1742   /* When we reach the value that triggers a progress bar update,
1743      bump that value by this amount. */
1744   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
1745   /* Count of packets at which we've looked. */
1746   count = 0;
1747   /* Progress so far. */
1748   progbar_val = 0.0f;
1749
1750   stop_flag = FALSE;
1751   g_get_current_time(&start_time);
1752
1753   /* no previous row yet */
1754   prev_frame_num = -1;
1755   prev_frame = NULL;
1756
1757   preceding_frame_num = -1;
1758   preceding_frame = NULL;
1759   following_frame_num = -1;
1760   following_frame = NULL;
1761
1762   selected_frame_seen = FALSE;
1763
1764   for (framenum = 1; framenum <= cf->count; framenum++) {
1765     fdata = frame_data_sequence_find(cf->frames, framenum);
1766
1767     /* Create the progress bar if necessary.
1768        We check on every iteration of the loop, so that it takes no
1769        longer than the standard time to create it (otherwise, for a
1770        large file, we might take considerably longer than that standard
1771        time in order to get to the next progress bar step). */
1772     if (progbar == NULL)
1773       progbar = delayed_create_progress_dlg(action, action_item, TRUE,
1774                                             &stop_flag, &start_time,
1775                                             progbar_val);
1776
1777     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1778        when we update it, we have to run the GTK+ main loop to get it
1779        to repaint what's pending, and doing so may involve an "ioctl()"
1780        to see if there's any pending input from an X server, and doing
1781        that for every packet can be costly, especially on a big file. */
1782     if (count >= progbar_nextstep) {
1783       /* let's not divide by zero. I should never be started
1784        * with count == 0, so let's assert that
1785        */
1786       g_assert(cf->count > 0);
1787       progbar_val = (gfloat) count / cf->count;
1788
1789       if (progbar != NULL) {
1790         g_snprintf(status_str, sizeof(status_str),
1791                   "%4u of %u frames", count, cf->count);
1792         update_progress_dlg(progbar, progbar_val, status_str);
1793       }
1794
1795       progbar_nextstep += progbar_quantum;
1796     }
1797
1798     if (stop_flag) {
1799       /* Well, the user decided to abort the filtering.  Just stop.
1800
1801          XXX - go back to the previous filter?  Users probably just
1802          want not to wait for a filtering operation to finish;
1803          unless we cancel by having no filter, reverting to the
1804          previous filter will probably be even more expensive than
1805          continuing the filtering, as it involves going back to the
1806          beginning and filtering, and even with no filter we currently
1807          have to re-generate the entire clist, which is also expensive.
1808
1809          I'm not sure what Network Monitor does, but it doesn't appear
1810          to give you an unfiltered display if you cancel. */
1811       break;
1812     }
1813
1814     count++;
1815
1816     if (redissect) {
1817       /* Since all state for the frame was destroyed, mark the frame
1818        * as not visited, free the GSList referring to the state
1819        * data (the per-frame data itself was freed by
1820        * "init_dissection()"), and null out the GSList pointer. */
1821       fdata->flags.visited = 0;
1822       frame_data_cleanup(fdata);
1823     }
1824
1825     if (redissect || refilter) {
1826       /* If we're redissecting or refiltering then any frame dependencies 
1827        * from the previous dissection/filtering are no longer valid.
1828        */
1829       fdata->flags.dependent_of_displayed = 0;
1830     }
1831
1832     if (!cf_read_frame(cf, fdata))
1833       break; /* error reading the frame */
1834
1835     /* If the previous frame is displayed, and we haven't yet seen the
1836        selected frame, remember that frame - it's the closest one we've
1837        yet seen before the selected frame. */
1838     if (prev_frame_num != -1 && !selected_frame_seen && prev_frame->flags.passed_dfilter) {
1839       preceding_frame_num = prev_frame_num;
1840       preceding_frame = prev_frame;
1841     }
1842     add_packet_to_packet_list(fdata, cf, dfcode, filtering_tap_listeners,
1843                                     tap_flags, &cf->pseudo_header, cf->pd,
1844                                     refilter,
1845                                     add_to_packet_list);
1846
1847     /* If this frame is displayed, and this is the first frame we've
1848        seen displayed after the selected frame, remember this frame -
1849        it's the closest one we've yet seen at or after the selected
1850        frame. */
1851     if (fdata->flags.passed_dfilter && selected_frame_seen && following_frame_num == -1) {
1852       following_frame_num = fdata->num;
1853       following_frame = fdata;
1854     }
1855     if (fdata == selected_frame) {
1856       selected_frame_seen = TRUE;
1857       if (fdata->flags.passed_dfilter)
1858           selected_frame_num = fdata->num;
1859     }
1860
1861     /* Remember this frame - it'll be the previous frame
1862        on the next pass through the loop. */
1863     prev_frame_num = fdata->num;
1864     prev_frame = fdata;
1865   }
1866
1867   /* We are done redissecting the packet list. */
1868   cf->redissecting = FALSE;
1869
1870   if (redissect) {
1871     /* Clear out what remains of the visited flags and per-frame data
1872        pointers.
1873
1874        XXX - that may cause various forms of bogosity when dissecting
1875        these frames, as they won't have been seen by this sequential
1876        pass, but the only alternative I see is to keep scanning them
1877        even though the user requested that the scan stop, and that
1878        would leave the user stuck with an Wireshark grinding on
1879        until it finishes.  Should we just stick them with that? */
1880     for (; framenum <= cf->count; framenum++) {
1881       fdata = frame_data_sequence_find(cf->frames, framenum);
1882       fdata->flags.visited = 0;
1883       frame_data_cleanup(fdata);
1884     }
1885   }
1886
1887   /* We're done filtering the packets; destroy the progress bar if it
1888      was created. */
1889   if (progbar != NULL)
1890     destroy_progress_dlg(progbar);
1891
1892   /* Unfreeze the packet list. */
1893   if (!add_to_packet_list)
1894     new_packet_list_recreate_visible_rows();
1895
1896   /* Compute the time it took to filter the file */
1897   compute_elapsed(&start_time);
1898
1899   new_packet_list_thaw();
1900
1901   if (selected_frame_num == -1) {
1902     /* The selected frame didn't pass the filter. */
1903     if (selected_frame == NULL) {
1904       /* That's because there *was* no selected frame.  Make the first
1905          displayed frame the current frame. */
1906       selected_frame_num = 0;
1907     } else {
1908       /* Find the nearest displayed frame to the selected frame (whether
1909          it's before or after that frame) and make that the current frame.
1910          If the next and previous displayed frames are equidistant from the
1911          selected frame, choose the next one. */
1912       g_assert(following_frame == NULL ||
1913                following_frame->num >= selected_frame->num);
1914       g_assert(preceding_frame == NULL ||
1915                preceding_frame->num <= selected_frame->num);
1916       if (following_frame == NULL) {
1917         /* No frame after the selected frame passed the filter, so we
1918            have to select the last displayed frame before the selected
1919            frame. */
1920         selected_frame_num = preceding_frame_num;
1921         selected_frame = preceding_frame;
1922       } else if (preceding_frame == NULL) {
1923         /* No frame before the selected frame passed the filter, so we
1924            have to select the first displayed frame after the selected
1925            frame. */
1926         selected_frame_num = following_frame_num;
1927         selected_frame = following_frame;
1928       } else {
1929         /* Frames before and after the selected frame passed the filter, so
1930            we'll select the previous frame */
1931         selected_frame_num = preceding_frame_num;
1932         selected_frame = preceding_frame;
1933       }
1934     }
1935   }
1936
1937   if (selected_frame_num == -1) {
1938     /* There are no frames displayed at all. */
1939     cf_unselect_packet(cf);
1940   } else {
1941     /* Either the frame that was selected passed the filter, or we've
1942        found the nearest displayed frame to that frame.  Select it, make
1943        it the focus row, and make it visible. */
1944     /* Set to invalid to force update of packet list and packet details */
1945     cf->current_row = -1;
1946     if (selected_frame_num == 0) {
1947       new_packet_list_select_first_row();
1948     }else{
1949       if (!new_packet_list_select_row_from_data(selected_frame)) {
1950         /* We didn't find a row corresponding to this frame.
1951            This means that the frame isn't being displayed currently,
1952            so we can't select it. */
1953         simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
1954                       "%sEnd of capture exceeded!%s\n\n"
1955                       "The capture file is probably not fully dissected.",
1956                       simple_dialog_primary_start(), simple_dialog_primary_end());
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_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3441                     "%sEnd of capture exceeded!%s\n\n"
3442                     "The capture file is probably not fully dissected.",
3443                     simple_dialog_primary_start(), simple_dialog_primary_end());
3444       return FALSE;
3445     }
3446     return TRUE;    /* success */
3447   } else
3448     return FALSE;   /* failure */
3449 }
3450
3451 gboolean
3452 cf_goto_frame(capture_file *cf, guint fnumber)
3453 {
3454   frame_data *fdata;
3455
3456   fdata = frame_data_sequence_find(cf->frames, fnumber);
3457
3458   if (fdata == NULL) {
3459     /* we didn't find a packet with that packet number */
3460     statusbar_push_temporary_msg("There is no packet number %u.", fnumber);
3461     return FALSE;   /* we failed to go to that packet */
3462   }
3463   if (!fdata->flags.passed_dfilter) {
3464     /* that packet currently isn't displayed */
3465     /* XXX - add it to the set of displayed packets? */
3466     statusbar_push_temporary_msg("Packet number %u isn't displayed.", fnumber);
3467     return FALSE;   /* we failed to go to that packet */
3468   }
3469
3470   if (!new_packet_list_select_row_from_data(fdata)) {
3471     /* We didn't find a row corresponding to this frame.
3472        This means that the frame isn't being displayed currently,
3473        so we can't select it. */
3474     simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3475                   "%sEnd of capture exceeded!%s\n\n"
3476                   "The capture file is probably not fully dissected.",
3477                   simple_dialog_primary_start(), simple_dialog_primary_end());
3478     return FALSE;
3479   }
3480   return TRUE;  /* we got to that packet */
3481 }
3482
3483 gboolean
3484 cf_goto_top_frame(void)
3485 {
3486   /* Find and select */
3487   new_packet_list_select_first_row();
3488   return TRUE;  /* we got to that packet */
3489 }
3490
3491 gboolean
3492 cf_goto_bottom_frame(void)
3493 {
3494   /* Find and select */
3495   new_packet_list_select_last_row();
3496   return TRUE;  /* we got to that packet */
3497 }
3498
3499 /*
3500  * Go to frame specified by currently selected protocol tree item.
3501  */
3502 gboolean
3503 cf_goto_framenum(capture_file *cf)
3504 {
3505   header_field_info       *hfinfo;
3506   guint32                 framenum;
3507
3508   if (cf->finfo_selected) {
3509     hfinfo = cf->finfo_selected->hfinfo;
3510     g_assert(hfinfo);
3511     if (hfinfo->type == FT_FRAMENUM) {
3512       framenum = fvalue_get_uinteger(&cf->finfo_selected->value);
3513       if (framenum != 0)
3514         return cf_goto_frame(cf, framenum);
3515       }
3516   }
3517
3518   return FALSE;
3519 }
3520
3521 /* Select the packet on a given row. */
3522 void
3523 cf_select_packet(capture_file *cf, int row)
3524 {
3525   frame_data *fdata;
3526
3527   /* Get the frame data struct pointer for this frame */
3528   fdata = new_packet_list_get_row_data(row);
3529
3530   if (fdata == NULL) {
3531     /* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
3532        the first entry is added to it by "real_insert_row()", that row
3533        is selected (see "real_insert_row()", in "ui/gtk/gtkclist.c", in both
3534        our version and the vanilla GTK+ version).
3535
3536        This means that a "select-row" signal is emitted; this causes
3537        "packet_list_select_cb()" to be called, which causes "cf_select_packet()"
3538        to be called.
3539
3540        "cf_select_packet()" fetches, above, the data associated with the
3541        row that was selected; however, as "gtk_clist_append()", which
3542        called "real_insert_row()", hasn't yet returned, we haven't yet
3543        associated any data with that row, so we get back a null pointer.
3544
3545        We can't assume that there's only one frame in the frame list,
3546        either, as we may be filtering the display.
3547
3548        We therefore assume that, if "row" is 0, i.e. the first row
3549        is being selected, and "cf->first_displayed" equals
3550        "cf->last_displayed", i.e. there's only one frame being
3551        displayed, that frame is the frame we want.
3552
3553        This means we have to set "cf->first_displayed" and
3554        "cf->last_displayed" before adding the row to the
3555        GtkCList; see the comment in "add_packet_to_packet_list()". */
3556
3557        if (row == 0 && cf->first_displayed == cf->last_displayed)
3558          fdata = frame_data_sequence_find(cf->frames, cf->first_displayed);
3559   }
3560
3561   /* If fdata _still_ isn't set simply give up. */
3562   if (fdata == NULL) {
3563     return;
3564   }
3565
3566   /* Get the data in that frame. */
3567   if (!cf_read_frame (cf, fdata)) {
3568     return;
3569   }
3570
3571   /* Record that this frame is the current frame. */
3572   cf->current_frame = fdata;
3573   cf->current_row = row;
3574
3575   /* Create the logical protocol tree. */
3576   if (cf->edt != NULL)
3577     epan_dissect_free(cf->edt);
3578
3579   /* We don't need the columns here. */
3580   cf->edt = epan_dissect_new(TRUE, TRUE);
3581
3582   tap_build_interesting(cf->edt);
3583   epan_dissect_run(cf->edt, &cf->pseudo_header, cf->pd, cf->current_frame,
3584           NULL);
3585
3586   dfilter_macro_build_ftv_cache(cf->edt->tree);
3587
3588   cf_callback_invoke(cf_cb_packet_selected, cf);
3589 }
3590
3591 /* Unselect the selected packet, if any. */
3592 void
3593 cf_unselect_packet(capture_file *cf)
3594 {
3595   /* Destroy the epan_dissect_t for the unselected packet. */
3596   if (cf->edt != NULL) {
3597     epan_dissect_free(cf->edt);
3598     cf->edt = NULL;
3599   }
3600
3601   /* No packet is selected. */
3602   cf->current_frame = NULL;
3603   cf->current_row = 0;
3604
3605   cf_callback_invoke(cf_cb_packet_unselected, cf);
3606
3607   /* No protocol tree means no selected field. */
3608   cf_unselect_field(cf);
3609 }
3610
3611 /* Unset the selected protocol tree field, if any. */
3612 void
3613 cf_unselect_field(capture_file *cf)
3614 {
3615   cf->finfo_selected = NULL;
3616
3617   cf_callback_invoke(cf_cb_field_unselected, cf);
3618 }
3619
3620 /*
3621  * Mark a particular frame.
3622  */
3623 void
3624 cf_mark_frame(capture_file *cf, frame_data *frame)
3625 {
3626   if (! frame->flags.marked) {
3627     frame->flags.marked = TRUE;
3628     if (cf->count > cf->marked_count)
3629       cf->marked_count++;
3630   }
3631 }
3632
3633 /*
3634  * Unmark a particular frame.
3635  */
3636 void
3637 cf_unmark_frame(capture_file *cf, frame_data *frame)
3638 {
3639   if (frame->flags.marked) {
3640     frame->flags.marked = FALSE;
3641     if (cf->marked_count > 0)
3642       cf->marked_count--;
3643   }
3644 }
3645
3646 /*
3647  * Ignore a particular frame.
3648  */
3649 void
3650 cf_ignore_frame(capture_file *cf, frame_data *frame)
3651 {
3652   if (! frame->flags.ignored) {
3653     frame->flags.ignored = TRUE;
3654     if (cf->count > cf->ignored_count)
3655       cf->ignored_count++;
3656   }
3657 }
3658
3659 /*
3660  * Un-ignore a particular frame.
3661  */
3662 void
3663 cf_unignore_frame(capture_file *cf, frame_data *frame)
3664 {
3665   if (frame->flags.ignored) {
3666     frame->flags.ignored = FALSE;
3667     if (cf->ignored_count > 0)
3668       cf->ignored_count--;
3669   }
3670 }
3671
3672 /*
3673  * Read the comment in SHB block
3674  */
3675
3676 const gchar *
3677 cf_read_shb_comment(capture_file *cf)
3678 {
3679   wtapng_section_t *shb_inf;
3680   const gchar *temp_str;
3681
3682   /* Get info from SHB */
3683   shb_inf = wtap_file_get_shb_info(cf->wth);
3684   if(shb_inf == NULL)
3685         return NULL;
3686   temp_str = shb_inf->opt_comment;
3687   g_free(shb_inf);
3688
3689   return temp_str;
3690
3691 }
3692
3693 void
3694 cf_update_capture_comment(capture_file *cf, gchar *comment)
3695 {
3696   wtapng_section_t *shb_inf;
3697
3698   /* Get info from SHB */
3699   shb_inf = wtap_file_get_shb_info(cf->wth);
3700
3701   /* See if the comment has changed or not */
3702   if (shb_inf && shb_inf->opt_comment) {
3703     if (strcmp(shb_inf->opt_comment, comment) == 0) {
3704       g_free(comment);
3705       g_free(shb_inf);
3706       return;
3707     }
3708   }
3709
3710   g_free(shb_inf);
3711
3712   /* The comment has changed, let's update it */
3713   wtap_write_shb_comment(cf->wth, comment);
3714   /* Mark the file as having unsaved changes */
3715   cf->unsaved_changes = TRUE;
3716 }
3717
3718 typedef struct {
3719   wtap_dumper *pdh;
3720   const char  *fname;
3721   int          file_type;
3722 } save_callback_args_t;
3723
3724 /*
3725  * Save a capture to a file, in a particular format, saving either
3726  * all packets, all currently-displayed packets, or all marked packets.
3727  *
3728  * Returns TRUE if it succeeds, FALSE otherwise; if it fails, it pops
3729  * up a message box for the failure.
3730  */
3731 static gboolean
3732 save_packet(capture_file *cf _U_, frame_data *fdata,
3733             union wtap_pseudo_header *pseudo_header, const guint8 *pd,
3734             void *argsp)
3735 {
3736   save_callback_args_t *args = argsp;
3737   struct wtap_pkthdr hdr;
3738   int           err;
3739
3740   /* init the wtap header for saving */
3741   /* XXX - these are the only flags that correspond to data that we have
3742      in the frame_data structure and that matter on a per-packet basis.
3743
3744      For WTAP_HAS_CAP_LEN, either the file format has separate "captured"
3745      and "on the wire" lengths, or it doesn't.
3746
3747      For WTAP_HAS_DROP_COUNT, Wiretap doesn't actually supply the value
3748      to its callers.
3749
3750      For WTAP_HAS_PACK_FLAGS, we currently don't save the FCS length
3751      from the packet flags. */
3752   hdr.presence_flags = 0;
3753   if (fdata->flags.has_ts)
3754     hdr.presence_flags |= WTAP_HAS_TS;
3755   if (fdata->flags.has_ts)
3756     hdr.presence_flags |= WTAP_HAS_INTERFACE_ID;
3757   hdr.ts.secs      = fdata->abs_ts.secs;
3758   hdr.ts.nsecs     = fdata->abs_ts.nsecs;
3759   hdr.caplen       = fdata->cap_len;
3760   hdr.len          = fdata->pkt_len;
3761   hdr.pkt_encap    = fdata->lnk_t;
3762   /* pcapng */
3763   hdr.interface_id = fdata->interface_id;   /* identifier of the interface. */
3764   /* options */
3765   hdr.opt_comment  = fdata->opt_comment; /* NULL if not available */
3766 #if 0
3767   hdr.drop_count   =
3768   hdr.pack_flags   =     /* XXX - 0 for now (any value for "we don't have it"?) */
3769 #endif
3770   /* and save the packet */
3771   if (!wtap_dump(args->pdh, &hdr, pseudo_header, pd, &err)) {
3772     if (err < 0) {
3773       /* Wiretap error. */
3774       switch (err) {
3775
3776       case WTAP_ERR_UNSUPPORTED_ENCAP:
3777         /*
3778          * This is a problem with the particular frame we're writing;
3779          * note that, and give the frame number.
3780          */
3781         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3782                       "Frame %u has a network type that can't be saved in a \"%s\" file.",
3783                       fdata->num, wtap_file_type_string(args->file_type));
3784         break;
3785
3786       default:
3787         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3788                       "An error occurred while writing to the file \"%s\": %s.",
3789                       args->fname, wtap_strerror(err));
3790         break;
3791       }
3792     } else {
3793       /* OS error. */
3794       write_failure_alert_box(args->fname, err);
3795     }
3796     return FALSE;
3797   }
3798   return TRUE;
3799 }
3800
3801 /*
3802  * Can this capture file be saved in any format except by copying the raw data?
3803  */
3804 gboolean
3805 cf_can_save_as(capture_file *cf)
3806 {
3807   int ft;
3808
3809   for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
3810     /* To save a file with Wiretap, Wiretap has to handle that format,
3811        and its code to handle that format must be able to write a file
3812        with this file's encapsulation type. */
3813     if (wtap_dump_can_open(ft) && wtap_dump_can_write_encap(ft, cf->lnk_t)) {
3814       /* OK, we can write it out in this type. */
3815       return TRUE;
3816     }
3817   }
3818
3819   /* No, we couldn't save it in any format. */
3820   return FALSE;
3821 }
3822
3823 cf_write_status_t
3824 cf_save_packets(capture_file *cf, const char *fname, guint save_format,
3825                 gboolean compressed, gboolean dont_reopen)
3826 {
3827   gchar        *fname_new = NULL;
3828   int           err;
3829   gboolean      do_copy;
3830   wtap_dumper  *pdh;
3831   save_callback_args_t callback_args;
3832
3833   cf_callback_invoke(cf_cb_file_save_started, (gpointer)fname);
3834
3835   if (save_format == cf->cd_t && compressed == cf->iscompressed
3836       && !cf->unsaved_changes) {
3837     /* We're saving in the format it's already in, and there are no
3838        changes we have in memory that aren't saved to the file, so
3839        we can just move or copy the raw data. */
3840
3841     if (cf->is_tempfile) {
3842       /* The file being saved is a temporary file from a live
3843          capture, so it doesn't need to stay around under that name;
3844          first, try renaming the capture buffer file to the new name.
3845          This acts as a "safe save", in that, if the file already
3846          exists, the existing file will be removed only if the rename
3847          succeeds.
3848
3849          Sadly, on Windows, as we have the current capture file
3850          open, even MoveFileEx() with MOVEFILE_REPLACE_EXISTING
3851          (to cause the rename to remove an existing target), as
3852          done by ws_stdio_rename() (ws_rename() is #defined to
3853          be ws_stdio_rename() on Windows) will fail.
3854
3855          According to the MSDN documentation for CreateFile(), if,
3856          when we open a capture file, we were to directly do a CreateFile(),
3857          opening with FILE_SHARE_DELETE|FILE_SHARE_READ, and then
3858          convert it to a file descriptor with _open_osfhandle(),
3859          that would allow the file to be renamed out from under us.
3860
3861          However, that doesn't work in practice.  Perhaps the problem
3862          is that the process doing the rename is the process that
3863          has the file open. */
3864 #ifndef _WIN32
3865       if (ws_rename(cf->filename, fname) == 0) {
3866         /* That succeeded - there's no need to copy the source file. */
3867         do_copy = FALSE;
3868       } else {
3869         if (errno == EXDEV) {
3870           /* They're on different file systems, so we have to copy the
3871              file. */
3872           do_copy = TRUE;
3873         } else {
3874           /* The rename failed, but not because they're on different
3875              file systems - put up an error message.  (Or should we
3876              just punt and try to copy?  The only reason why I'd
3877              expect the rename to fail and the copy to succeed would
3878              be if we didn't have permission to remove the file from
3879              the temporary directory, and that might be fixable - but
3880              is it worth requiring the user to go off and fix it?) */
3881           simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3882                         file_rename_error_message(errno), fname);
3883           goto fail;
3884         }
3885       }
3886 #else
3887       do_copy = TRUE;
3888 #endif
3889     } else {
3890       /* It's a permanent file, so we should copy it, and not remove the
3891          original. */
3892       do_copy = TRUE;
3893     }
3894
3895     if (do_copy) {
3896       /* Copy the file, if we haven't moved it.  If we're overwriting
3897          an existing file, we do it with a "safe save", by writing
3898          to a new file and, if the write succeeds, renaming the
3899          new file on top of the old file. */
3900       if (file_exists(fname)) {
3901         fname_new = g_strdup_printf("%s~", fname);
3902         if (!copy_file_binary_mode(cf->filename, fname_new))
3903           goto fail;
3904       } else {
3905         if (!copy_file_binary_mode(cf->filename, fname))
3906           goto fail;
3907       }
3908     }
3909   } else {
3910     /* Either we're saving in a different format or we're saving changes,
3911        such as added, modified, or removed comments, that haven't yet
3912        been written to the underlying file; we can't do that by copying
3913        or moving the capture file, we have to do it by writing the packets
3914        out in Wiretap. */
3915
3916     wtapng_section_t *shb_hdr = NULL;
3917     wtapng_iface_descriptions_t *idb_inf = NULL;
3918
3919     shb_hdr = wtap_file_get_shb_info(cf->wth);
3920     idb_inf = wtap_file_get_idb_info(cf->wth);
3921
3922     if (file_exists(fname)) {
3923       /* We're overwriting an existing file; write out to a new file,
3924          and, if that succeeds, rename the new file on top of the
3925          old file.  That makes this a "safe save", so that we don't
3926          lose the old file if we have a problem writing out the new
3927          file.  (If the existing file is the current capture file,
3928          we *HAVE* to do that, otherwise we're overwriting the file
3929          from which we're reading the packets that we're writing!) */
3930       fname_new = g_strdup_printf("%s~", fname);
3931       pdh = wtap_dump_open_ng(fname_new, save_format, cf->lnk_t, cf->snap,
3932                               compressed, shb_hdr, idb_inf, &err);
3933     } else {
3934       pdh = wtap_dump_open_ng(fname, save_format, cf->lnk_t, cf->snap,
3935                               compressed, shb_hdr, idb_inf, &err);
3936     }
3937     g_free(idb_inf);
3938     idb_inf = NULL;
3939
3940     if (pdh == NULL) {
3941       cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
3942       goto fail;
3943     }
3944
3945     /* Add address resolution */
3946     wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list());
3947
3948     /* Iterate through the list of packets, processing all the packets. */
3949     callback_args.pdh = pdh;
3950     callback_args.fname = fname;
3951     callback_args.file_type = save_format;
3952     switch (process_specified_packets(cf, NULL, "Saving", "packets",
3953                                       TRUE, save_packet, &callback_args)) {
3954
3955     case PSP_FINISHED:
3956       /* Completed successfully. */
3957       break;
3958
3959     case PSP_STOPPED:
3960       /* The user decided to abort the saving.
3961          If we're writing to a temporary file, remove it.
3962          XXX - should we do so even if we're not writing to a
3963          temporary file? */
3964       wtap_dump_close(pdh, &err);
3965       if (fname_new != NULL)
3966         ws_unlink(fname_new);
3967       cf_callback_invoke(cf_cb_file_save_stopped, NULL);
3968       return CF_WRITE_ABORTED;
3969
3970     case PSP_FAILED:
3971       /* Error while saving.
3972          If we're writing to a temporary file, remove it. */
3973       if (fname_new != NULL)
3974         ws_unlink(fname_new);
3975       wtap_dump_close(pdh, &err);
3976       goto fail;
3977     }
3978
3979     if (!wtap_dump_close(pdh, &err)) {
3980       cf_close_failure_alert_box(fname, err);
3981       goto fail;
3982     }
3983   }
3984
3985   if (fname_new != NULL) {
3986     /* We wrote out to fname_new, and should rename it on top of
3987        fname.  fname_new is now closed, so that should be possible even
3988        on Windows.  However, on Windows, we first need to close whatever
3989        file descriptors we have open for fname. */
3990 #ifdef _WIN32
3991     wtap_fdclose(cf->wth);
3992 #endif
3993     /* Now do the rename. */
3994     if (ws_rename(fname_new, fname) == -1) {
3995       /* Well, the rename failed. */
3996       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3997                     file_rename_error_message(errno), fname);
3998 #ifdef _WIN32
3999       /* Attempt to reopen the random file descriptor using the
4000          current file's filename.  (At this point, the sequential
4001          file descriptor is closed.) */
4002       if (!wtap_fdreopen(cf->wth, cf->filename, &err)) {
4003         /* Oh, well, we're screwed. */
4004         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4005                       file_open_error_message(err, FALSE), cf->filename);
4006       }
4007 #endif
4008       goto fail;
4009     }
4010   }
4011
4012   cf_callback_invoke(cf_cb_file_save_finished, NULL);
4013   cf->unsaved_changes = FALSE;
4014
4015   if (!dont_reopen) {
4016     /* Open and read the file we saved to.
4017
4018        XXX - this is somewhat of a waste; we already have the
4019        packets, all this gets us is updated file type information
4020        (which we could just stuff into "cf"), and having the new
4021        file be the one we have opened and from which we're reading
4022        the data, and it means we have to spend time opening and
4023        reading the file, which could be a significant amount of
4024        time if the file is large.
4025
4026        If the capture-file-writing code were to return the
4027        seek offset of each packet it writes, we could save that
4028        in the frame_data structure for the frame, and just open
4029        the file without reading it again. */
4030
4031     if ((cf_open(cf, fname, FALSE, &err)) == CF_OK) {
4032       /* XXX - report errors if this fails?
4033          What should we return if it fails or is aborted? */
4034
4035       switch (cf_read(cf, TRUE)) {
4036
4037       case CF_READ_OK:
4038       case CF_READ_ERROR:
4039         /* Just because we got an error, that doesn't mean we were unable
4040            to read any of the file; we handle what we could get from the
4041            file. */
4042         break;
4043
4044       case CF_READ_ABORTED:
4045         /* The user bailed out of re-reading the capture file; the
4046            capture file has been closed - just return (without
4047            changing any menu settings; "cf_close()" set them
4048            correctly for the "no capture file open" state). */
4049         break;
4050       }
4051     }
4052   }
4053   return CF_WRITE_OK;
4054
4055 fail:
4056   if (fname_new != NULL) {
4057     /* We were trying to write to a temporary file; get rid of it if it
4058        exists.  (We don't care whether this fails, as, if it fails,
4059        there's not much we can do about it.  I guess if it failed for
4060        a reason other than "it doesn't exist", we could report an
4061        error, so the user knows there's a junk file that they might
4062        want to clean up.) */
4063     ws_unlink(fname_new);
4064     g_free(fname_new);
4065   }
4066   cf_callback_invoke(cf_cb_file_save_failed, NULL);
4067   return CF_WRITE_ERROR;
4068 }
4069
4070 cf_write_status_t
4071 cf_export_specified_packets(capture_file *cf, const char *fname,
4072                             packet_range_t *range, guint save_format,
4073                             gboolean compressed)
4074 {
4075   gchar        *fname_new = NULL;
4076   int           err;
4077   wtap_dumper  *pdh;
4078   save_callback_args_t callback_args;
4079   wtapng_section_t *shb_hdr = NULL;
4080   wtapng_iface_descriptions_t *idb_inf = NULL;
4081
4082   cf_callback_invoke(cf_cb_file_export_specified_packets_started, (gpointer)fname);
4083
4084   packet_range_process_init(range);
4085
4086   /* We're writing out specified packets from the specified capture
4087      file to another file.  Even if all captured packets are to be
4088      written, don't special-case the operation - read each packet
4089      and then write it out if it's one of the specified ones. */
4090
4091   shb_hdr = wtap_file_get_shb_info(cf->wth);
4092   idb_inf = wtap_file_get_idb_info(cf->wth);
4093
4094   if (file_exists(fname)) {
4095     /* We're overwriting an existing file; write out to a new file,
4096        and, if that succeeds, rename the new file on top of the
4097        old file.  That makes this a "safe save", so that we don't
4098        lose the old file if we have a problem writing out the new
4099        file.  (If the existing file is the current capture file,
4100        we *HAVE* to do that, otherwise we're overwriting the file
4101        from which we're reading the packets that we're writing!) */
4102     fname_new = g_strdup_printf("%s~", fname);
4103     pdh = wtap_dump_open_ng(fname_new, save_format, cf->lnk_t, cf->snap,
4104                             compressed, shb_hdr, idb_inf, &err);
4105   } else {
4106     pdh = wtap_dump_open_ng(fname, save_format, cf->lnk_t, cf->snap,
4107                             compressed, shb_hdr, idb_inf, &err);
4108   }
4109   g_free(idb_inf);
4110   idb_inf = NULL;
4111
4112   if (pdh == NULL) {
4113     cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
4114     goto fail;
4115   }
4116
4117   /* Add address resolution */
4118   wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list());
4119
4120   /* Iterate through the list of packets, processing the packets we were
4121      told to process.
4122
4123      XXX - we've already called "packet_range_process_init(range)", but
4124      "process_specified_packets()" will do it again.  Fortunately,
4125      that's harmless in this case, as we haven't done anything to
4126      "range" since we initialized it. */
4127   callback_args.pdh = pdh;
4128   callback_args.fname = fname;
4129   callback_args.file_type = save_format;
4130   switch (process_specified_packets(cf, range, "Writing", "specified packets",
4131                                     TRUE, save_packet, &callback_args)) {
4132
4133   case PSP_FINISHED:
4134     /* Completed successfully. */
4135     break;
4136
4137   case PSP_STOPPED:
4138       /* The user decided to abort the saving.
4139          If we're writing to a temporary file, remove it.
4140          XXX - should we do so even if we're not writing to a
4141          temporary file? */
4142       wtap_dump_close(pdh, &err);
4143       if (fname_new != NULL)
4144         ws_unlink(fname_new);
4145       cf_callback_invoke(cf_cb_file_export_specified_packets_stopped, NULL);
4146       return CF_WRITE_ABORTED;
4147     break;
4148
4149   case PSP_FAILED:
4150     /* Error while saving.
4151        If we're writing to a temporary file, remove it. */
4152     if (fname_new != NULL)
4153       ws_unlink(fname_new);
4154     wtap_dump_close(pdh, &err);
4155     goto fail;
4156   }
4157
4158   if (!wtap_dump_close(pdh, &err)) {
4159     cf_close_failure_alert_box(fname, err);
4160     goto fail;
4161   }
4162
4163   if (fname_new != NULL) {
4164     /* We wrote out to fname_new, and should rename it on top of
4165        fname; fname is now closed, so that should be possible even
4166        on Windows.  Do the rename. */
4167     if (ws_rename(fname_new, fname) == -1) {
4168       /* Well, the rename failed. */
4169       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4170                     file_rename_error_message(errno), fname);
4171       goto fail;
4172     }
4173   }
4174
4175   cf_callback_invoke(cf_cb_file_export_specified_packets_finished, NULL);
4176   return CF_WRITE_OK;
4177
4178 fail:
4179   if (fname_new != NULL) {
4180     /* We were trying to write to a temporary file; get rid of it if it
4181        exists.  (We don't care whether this fails, as, if it fails,
4182        there's not much we can do about it.  I guess if it failed for
4183        a reason other than "it doesn't exist", we could report an
4184        error, so the user knows there's a junk file that they might
4185        want to clean up.) */
4186     ws_unlink(fname_new);
4187     g_free(fname_new);
4188   }
4189   cf_callback_invoke(cf_cb_file_export_specified_packets_failed, NULL);
4190   return CF_WRITE_ERROR;
4191 }
4192
4193 static void
4194 cf_open_failure_alert_box(const char *filename, int err, gchar *err_info,
4195                           gboolean for_writing, int file_type)
4196 {
4197   if (err < 0) {
4198     /* Wiretap error. */
4199     switch (err) {
4200
4201     case WTAP_ERR_NOT_REGULAR_FILE:
4202       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4203             "The file \"%s\" is a \"special file\" or socket or other non-regular file.",
4204             filename);
4205       break;
4206
4207     case WTAP_ERR_RANDOM_OPEN_PIPE:
4208       /* Seen only when opening a capture file for reading. */
4209       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4210             "The file \"%s\" is a pipe or FIFO; Wireshark can't read pipe or FIFO files.\n"
4211             "To capture from a pipe or FIFO use wireshark -i -",
4212             filename);
4213       break;
4214
4215     case WTAP_ERR_FILE_UNKNOWN_FORMAT:
4216       /* Seen only when opening a capture file for reading. */
4217       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4218             "The file \"%s\" isn't a capture file in a format Wireshark understands.",
4219             filename);
4220       break;
4221
4222     case WTAP_ERR_UNSUPPORTED:
4223       /* Seen only when opening a capture file for reading. */
4224       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4225             "The file \"%s\" isn't a capture file in a format Wireshark understands.\n"
4226             "(%s)",
4227             filename, err_info);
4228       g_free(err_info);
4229       break;
4230
4231     case WTAP_ERR_CANT_WRITE_TO_PIPE:
4232       /* Seen only when opening a capture file for writing. */
4233       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4234             "The file \"%s\" is a pipe, and %s capture files can't be "
4235             "written to a pipe.",
4236             filename, wtap_file_type_string(file_type));
4237       break;
4238
4239     case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
4240       /* Seen only when opening a capture file for writing. */
4241       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4242             "Wireshark doesn't support writing capture files in that format.");
4243       break;
4244
4245     case WTAP_ERR_UNSUPPORTED_ENCAP:
4246       if (for_writing) {
4247         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4248               "Wireshark can't save this capture in that format.");
4249       } else {
4250         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4251               "The file \"%s\" is a capture for a network type that Wireshark doesn't support.\n"
4252               "(%s)",
4253               filename, err_info);
4254         g_free(err_info);
4255       }
4256       break;
4257
4258     case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
4259       if (for_writing) {
4260         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4261               "Wireshark can't save this capture in that format.");
4262       } else {
4263         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4264               "The file \"%s\" is a capture for a network type that Wireshark doesn't support.",
4265               filename);
4266       }
4267       break;
4268
4269     case WTAP_ERR_BAD_FILE:
4270       /* Seen only when opening a capture file for reading. */
4271       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4272             "The file \"%s\" appears to be damaged or corrupt.\n"
4273             "(%s)",
4274             filename, err_info);
4275       g_free(err_info);
4276       break;
4277
4278     case WTAP_ERR_CANT_OPEN:
4279       if (for_writing) {
4280         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4281               "The file \"%s\" could not be created for some unknown reason.",
4282               filename);
4283       } else {
4284         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4285               "The file \"%s\" could not be opened for some unknown reason.",
4286               filename);
4287       }
4288       break;
4289
4290     case WTAP_ERR_SHORT_READ:
4291       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4292             "The file \"%s\" appears to have been cut short"
4293             " in the middle of a packet or other data.",
4294             filename);
4295       break;
4296
4297     case WTAP_ERR_SHORT_WRITE:
4298       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4299             "A full header couldn't be written to the file \"%s\".",
4300             filename);
4301       break;
4302
4303     case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
4304       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4305             "This file type cannot be written as a compressed file.");
4306       break;
4307
4308     case WTAP_ERR_DECOMPRESS:
4309       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4310             "The compressed file \"%s\" appears to be damaged or corrupt.\n"
4311             "(%s)", filename, err_info);
4312       g_free(err_info);
4313       break;
4314
4315     default:
4316       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4317             "The file \"%s\" could not be %s: %s.",
4318             filename,
4319             for_writing ? "created" : "opened",
4320             wtap_strerror(err));
4321       break;
4322     }
4323   } else {
4324     /* OS error. */
4325     open_failure_alert_box(filename, err, for_writing);
4326   }
4327 }
4328
4329 /*
4330  * XXX - whether we mention the source pathname, the target pathname,
4331  * or both depends on the error and on what we find if we look for
4332  * one or both of them.
4333  */
4334 static const char *
4335 file_rename_error_message(int err)
4336 {
4337   const char *errmsg;
4338   static char errmsg_errno[1024+1];
4339
4340   switch (err) {
4341
4342   case ENOENT:
4343     /* XXX - should check whether the source exists and, if not,
4344        report it as the problem and, if so, report the destination
4345        as the problem. */
4346     errmsg = "The path to the file \"%s\" doesn't exist.";
4347     break;
4348
4349   case EACCES:
4350     /* XXX - if we're doing a rename after a safe save, we should
4351        probably say something else. */
4352     errmsg = "You don't have permission to move the capture file to \"%s\".";
4353     break;
4354
4355   default:
4356     /* XXX - this should probably mention both the source and destination
4357        pathnames. */
4358     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
4359             "The file \"%%s\" could not be moved: %s.",
4360                 wtap_strerror(err));
4361     errmsg = errmsg_errno;
4362     break;
4363   }
4364   return errmsg;
4365 }
4366
4367 /* Check for write errors - if the file is being written to an NFS server,
4368    a write error may not show up until the file is closed, as NFS clients
4369    might not send writes to the server until the "write()" call finishes,
4370    so that the write may fail on the server but the "write()" may succeed. */
4371 static void
4372 cf_close_failure_alert_box(const char *filename, int err)
4373 {
4374   if (err < 0) {
4375     /* Wiretap error. */
4376     switch (err) {
4377
4378     case WTAP_ERR_CANT_CLOSE:
4379       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4380             "The file \"%s\" couldn't be closed for some unknown reason.",
4381             filename);
4382       break;
4383
4384     case WTAP_ERR_SHORT_WRITE:
4385       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4386             "Not all the packets could be written to the file \"%s\".",
4387                     filename);
4388       break;
4389
4390     default:
4391       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4392             "An error occurred while closing the file \"%s\": %s.",
4393             filename, wtap_strerror(err));
4394       break;
4395     }
4396   } else {
4397     /* OS error.
4398        We assume that a close error from the OS is really a write error. */
4399     write_failure_alert_box(filename, err);
4400   }
4401 }
4402
4403 /* Reload the current capture file. */
4404 void
4405 cf_reload(capture_file *cf) {
4406   gchar *filename;
4407   gboolean is_tempfile;
4408   int err;
4409
4410   /* If the file could be opened, "cf_open()" calls "cf_close()"
4411      to get rid of state for the old capture file before filling in state
4412      for the new capture file.  "cf_close()" will remove the file if
4413      it's a temporary file; we don't want that to happen (for one thing,
4414      it'd prevent subsequent reopens from working).  Remember whether it's
4415      a temporary file, mark it as not being a temporary file, and then
4416      reopen it as the type of file it was.
4417
4418      Also, "cf_close()" will free "cf->filename", so we must make
4419      a copy of it first. */
4420   filename = g_strdup(cf->filename);
4421   is_tempfile = cf->is_tempfile;
4422   cf->is_tempfile = FALSE;
4423   if (cf_open(cf, filename, is_tempfile, &err) == CF_OK) {
4424     switch (cf_read(cf, TRUE)) {
4425
4426     case CF_READ_OK:
4427     case CF_READ_ERROR:
4428       /* Just because we got an error, that doesn't mean we were unable
4429          to read any of the file; we handle what we could get from the
4430          file. */
4431       break;
4432
4433     case CF_READ_ABORTED:
4434       /* The user bailed out of re-reading the capture file; the
4435          capture file has been closed - just free the capture file name
4436          string and return (without changing the last containing
4437          directory). */
4438       g_free(filename);
4439       return;
4440     }
4441   } else {
4442     /* The open failed, so "cf->is_tempfile" wasn't set to "is_tempfile".
4443        Instead, the file was left open, so we should restore "cf->is_tempfile"
4444        ourselves.
4445
4446        XXX - change the menu?  Presumably "cf_open()" will do that;
4447        make sure it does! */
4448     cf->is_tempfile = is_tempfile;
4449   }
4450   /* "cf_open()" made a copy of the file name we handed it, so
4451      we should free up our copy. */
4452   g_free(filename);
4453 }
4454
4455 /*
4456  * Editor modelines
4457  *
4458  * Local Variables:
4459  * c-basic-offset: 2
4460  * tab-width: 8
4461  * indent-tabs-mode: nil
4462  * End:
4463  *
4464  * ex: set shiftwidth=2 tabstop=8 expandtab:
4465  * :indentSize=2:tabSize=8:noTabs=true:
4466  */