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