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