col_fmt not needed.
[metze/wireshark/wip.git] / file.c
1 /* file.c
2  * File I/O routines
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #ifdef HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32
33 #include <time.h>
34
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <ctype.h>
39 #include <errno.h>
40 #include <signal.h>
41
42 #ifdef HAVE_FCNTL_H
43 #include <fcntl.h>
44 #endif
45
46 #include <epan/epan.h>
47 #include <epan/filesystem.h>
48
49 #include "color.h"
50 #include "color_filters.h"
51 #include "cfile.h"
52 #include <epan/column.h>
53 #include <epan/packet.h>
54 #include <epan/column-utils.h>
55 #include "packet-range.h"
56 #include "print.h"
57 #include "file.h"
58 #include "fileset.h"
59 #include "tempfile.h"
60 #include "merge.h"
61 #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   fdata->lnk_t = phdr->pkt_encap;
1263   fdata->flags.encoding = CHAR_ASCII;
1264   fdata->flags.visited = 0;
1265   fdata->flags.marked = 0;
1266   fdata->flags.ref_time = 0;
1267   fdata->color_filter = NULL;
1268   fdata->col_text = NULL;
1269   fdata->col_text_len = NULL;
1270
1271   fdata->abs_ts.secs = phdr->ts.secs;
1272   fdata->abs_ts.nsecs = phdr->ts.nsecs;
1273
1274   if (cf->plist_end != NULL)
1275     nstime_delta(&fdata->del_cap_ts, &fdata->abs_ts, &cf->plist_end->abs_ts);
1276   else
1277     nstime_set_zero(&fdata->del_cap_ts);
1278
1279   passed = TRUE;
1280   if (cf->rfcode) {
1281     epan_dissect_t edt;
1282     epan_dissect_init(&edt, TRUE, FALSE);
1283     epan_dissect_prime_dfilter(&edt, cf->rfcode);
1284     epan_dissect_run(&edt, pseudo_header, buf, fdata, NULL);
1285     passed = dfilter_apply_edt(cf->rfcode, &edt);
1286     epan_dissect_cleanup(&edt);
1287   }
1288   if (passed) {
1289     plist_end = cf->plist_end;
1290     fdata->prev = plist_end;
1291     if (plist_end != NULL)
1292       plist_end->next = fdata;
1293     else
1294       cf->plist = fdata;
1295     cf->plist_end = fdata;
1296
1297     cf->count++;
1298     cf->f_datalen = offset + phdr->caplen;
1299     fdata->num = cf->count;
1300     if (!cf->redissecting) {
1301       row = add_packet_to_packet_list(fdata, cf, dfcode,
1302                                       filtering_tap_listeners, tap_flags,
1303                                       pseudo_header, buf, TRUE, TRUE);
1304     }
1305   } else {
1306     /* XXX - if we didn't have read filters, or if we could avoid
1307        allocating the "frame_data" structure until we knew whether
1308        the frame passed the read filter, we could use a G_ALLOC_ONLY
1309        memory chunk...
1310
1311        ...but, at least in one test I did, where I just made the chunk
1312        a G_ALLOC_ONLY chunk and read in a huge capture file, it didn't
1313        seem to save a noticeable amount of time or space. */
1314 #if GLIB_CHECK_VERSION(2,10,0)
1315   /* memory chunks have been deprecated in favor of the slice allocator,
1316    * which has been added in 2.10
1317    */
1318         g_slice_free(frame_data,fdata);
1319 #else
1320     g_mem_chunk_free(cf->plist_chunk, fdata);
1321 #endif
1322   }
1323
1324   return row;
1325 }
1326
1327 cf_status_t
1328 cf_merge_files(char **out_filenamep, int in_file_count,
1329                char *const *in_filenames, int file_type, gboolean do_append)
1330 {
1331   merge_in_file_t  *in_files;
1332   wtap             *wth;
1333   char             *out_filename;
1334   char             *tmpname;
1335   int               out_fd;
1336   wtap_dumper      *pdh;
1337   int               open_err, read_err, write_err, close_err;
1338   gchar            *err_info;
1339   int               err_fileno;
1340   int               i;
1341   char              errmsg_errno[1024+1];
1342   const char       *errmsg;
1343   gboolean          got_read_error = FALSE, got_write_error = FALSE;
1344   gint64            data_offset;
1345   progdlg_t        *progbar = NULL;
1346   gboolean          stop_flag;
1347   gint64            f_len, file_pos;
1348   float             progbar_val;
1349   GTimeVal          start_time;
1350   gchar             status_str[100];
1351   gint64            progbar_nextstep;
1352   gint64            progbar_quantum;
1353
1354   /* open the input files */
1355   if (!merge_open_in_files(in_file_count, in_filenames, &in_files,
1356                            &open_err, &err_info, &err_fileno)) {
1357     g_free(in_files);
1358     cf_open_failure_alert_box(in_filenames[err_fileno], open_err, err_info,
1359                               FALSE, 0);
1360     return CF_ERROR;
1361   }
1362
1363   if (*out_filenamep != NULL) {
1364     out_filename = *out_filenamep;
1365     out_fd = ws_open(out_filename, O_CREAT|O_TRUNC|O_BINARY, 0600);
1366     if (out_fd == -1)
1367       open_err = errno;
1368   } else {
1369     out_fd = create_tempfile(&tmpname, "wireshark");
1370     if (out_fd == -1)
1371       open_err = errno;
1372     out_filename = g_strdup(tmpname);
1373     *out_filenamep = out_filename;
1374   }
1375   if (out_fd == -1) {
1376     err_info = NULL;
1377     merge_close_in_files(in_file_count, in_files);
1378     g_free(in_files);
1379     cf_open_failure_alert_box(out_filename, open_err, NULL, TRUE, file_type);
1380     return CF_ERROR;
1381   }
1382
1383   pdh = wtap_dump_fdopen(out_fd, file_type,
1384       merge_select_frame_type(in_file_count, in_files),
1385       merge_max_snapshot_length(in_file_count, in_files),
1386           FALSE /* compressed */, &open_err);
1387   if (pdh == NULL) {
1388     ws_close(out_fd);
1389     merge_close_in_files(in_file_count, in_files);
1390     g_free(in_files);
1391     cf_open_failure_alert_box(out_filename, open_err, err_info, TRUE,
1392                               file_type);
1393     return CF_ERROR;
1394   }
1395
1396   /* Get the sum of the sizes of all the files. */
1397   f_len = 0;
1398   for (i = 0; i < in_file_count; i++)
1399     f_len += in_files[i].size;
1400
1401   /* Update the progress bar when it gets to this value. */
1402   progbar_nextstep = 0;
1403   /* When we reach the value that triggers a progress bar update,
1404      bump that value by this amount. */
1405   progbar_quantum = f_len/N_PROGBAR_UPDATES;
1406   /* Progress so far. */
1407   progbar_val = 0.0f;
1408
1409   stop_flag = FALSE;
1410   g_get_current_time(&start_time);
1411
1412   /* do the merge (or append) */
1413   for (;;) {
1414     if (do_append)
1415       wth = merge_append_read_packet(in_file_count, in_files, &read_err,
1416                                      &err_info);
1417     else
1418       wth = merge_read_packet(in_file_count, in_files, &read_err,
1419                               &err_info);
1420     if (wth == NULL) {
1421       if (read_err != 0)
1422         got_read_error = TRUE;
1423       break;
1424     }
1425
1426     /* Get the sum of the data offsets in all of the files. */
1427     data_offset = 0;
1428     for (i = 0; i < in_file_count; i++)
1429       data_offset += in_files[i].data_offset;
1430
1431     /* Create the progress bar if necessary.
1432        We check on every iteration of the loop, so that it takes no
1433        longer than the standard time to create it (otherwise, for a
1434        large file, we might take considerably longer than that standard
1435        time in order to get to the next progress bar step). */
1436     if (progbar == NULL) {
1437       progbar = delayed_create_progress_dlg("Merging", "files",
1438         FALSE, &stop_flag, &start_time, progbar_val);
1439     }
1440
1441     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1442        when we update it, we have to run the GTK+ main loop to get it
1443        to repaint what's pending, and doing so may involve an "ioctl()"
1444        to see if there's any pending input from an X server, and doing
1445        that for every packet can be costly, especially on a big file. */
1446     if (data_offset >= progbar_nextstep) {
1447         /* Get the sum of the seek positions in all of the files. */
1448         file_pos = 0;
1449         for (i = 0; i < in_file_count; i++)
1450           file_pos += wtap_read_so_far(in_files[i].wth, NULL);
1451         progbar_val = (gfloat) file_pos / (gfloat) f_len;
1452         if (progbar_val > 1.0f) {
1453           /* Some file probably grew while we were reading it.
1454              That "shouldn't happen", so we'll just clip the progress
1455              value at 1.0. */
1456           progbar_val = 1.0f;
1457         }
1458         if (progbar != NULL) {
1459           g_snprintf(status_str, sizeof(status_str),
1460                      "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
1461                      file_pos / 1024, f_len / 1024);
1462           update_progress_dlg(progbar, progbar_val, status_str);
1463         }
1464         progbar_nextstep += progbar_quantum;
1465     }
1466
1467     if (stop_flag) {
1468       /* Well, the user decided to abort the merge. */
1469       break;
1470     }
1471
1472     if (!wtap_dump(pdh, wtap_phdr(wth), wtap_pseudoheader(wth),
1473          wtap_buf_ptr(wth), &write_err)) {
1474       got_write_error = TRUE;
1475       break;
1476     }
1477   }
1478
1479   /* We're done merging the files; destroy the progress bar if it was created. */
1480   if (progbar != NULL)
1481     destroy_progress_dlg(progbar);
1482
1483   merge_close_in_files(in_file_count, in_files);
1484   if (!got_read_error && !got_write_error) {
1485     if (!wtap_dump_close(pdh, &write_err))
1486       got_write_error = TRUE;
1487   } else
1488     wtap_dump_close(pdh, &close_err);
1489
1490   if (got_read_error) {
1491     /*
1492      * Find the file on which we got the error, and report the error.
1493      */
1494     for (i = 0; i < in_file_count; i++) {
1495       if (in_files[i].state == GOT_ERROR) {
1496         /* Put up a message box noting that a read failed somewhere along
1497            the line. */
1498         switch (read_err) {
1499
1500         case WTAP_ERR_UNSUPPORTED_ENCAP:
1501           g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1502                    "The capture file %%s has a packet with a network type that Wireshark doesn't support.\n(%s)",
1503                    err_info);
1504           g_free(err_info);
1505           errmsg = errmsg_errno;
1506           break;
1507
1508         case WTAP_ERR_CANT_READ:
1509           errmsg = "An attempt to read from the capture file %s failed for"
1510                    " some unknown reason.";
1511           break;
1512
1513         case WTAP_ERR_SHORT_READ:
1514           errmsg = "The capture file %s appears to have been cut short"
1515                    " in the middle of a packet.";
1516           break;
1517
1518         case WTAP_ERR_BAD_RECORD:
1519           g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1520                    "The capture file %%s appears to be damaged or corrupt.\n(%s)",
1521                    err_info);
1522           g_free(err_info);
1523           errmsg = errmsg_errno;
1524           break;
1525
1526         default:
1527           g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1528                    "An error occurred while reading the"
1529                    " capture file %%s: %s.", wtap_strerror(read_err));
1530           errmsg = errmsg_errno;
1531           break;
1532         }
1533         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, errmsg, in_files[i].filename);
1534       }
1535     }
1536   }
1537
1538   if (got_write_error) {
1539     /* Put up an alert box for the write error. */
1540     cf_write_failure_alert_box(out_filename, write_err);
1541   }
1542
1543   if (got_read_error || got_write_error || stop_flag) {
1544     /* Callers aren't expected to treat an error or an explicit abort
1545        differently - we put up error dialogs ourselves, so they don't
1546        have to. */
1547     return CF_ERROR;
1548   } else
1549     return CF_OK;
1550 }
1551
1552 cf_status_t
1553 cf_filter_packets(capture_file *cf, gchar *dftext, gboolean force)
1554 {
1555   const char *filter_new = dftext ? dftext : "";
1556   const char *filter_old = cf->dfilter ? cf->dfilter : "";
1557   dfilter_t   *dfcode;
1558
1559   /* if new filter equals old one, do nothing unless told to do so */
1560   if (!force && strcmp(filter_new, filter_old) == 0) {
1561     return CF_OK;
1562   }
1563
1564   dfcode=NULL;
1565
1566   if (dftext == NULL) {
1567     /* The new filter is an empty filter (i.e., display all packets).
1568      * so leave dfcode==NULL
1569      */
1570   } else {
1571     /*
1572      * We have a filter; make a copy of it (as we'll be saving it),
1573      * and try to compile it.
1574      */
1575     dftext = g_strdup(dftext);
1576     if (!dfilter_compile(dftext, &dfcode)) {
1577       /* The attempt failed; report an error. */
1578       gchar *safe_dftext = simple_dialog_format_message(dftext);
1579       gchar *safe_dfilter_error_msg = simple_dialog_format_message(
1580           dfilter_error_msg);
1581       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1582           "%s%s%s\n"
1583           "\n"
1584           "The following display filter isn't a valid display filter:\n%s\n"
1585           "See the help for a description of the display filter syntax.",
1586           simple_dialog_primary_start(), safe_dfilter_error_msg,
1587           simple_dialog_primary_end(), safe_dftext);
1588       g_free(safe_dfilter_error_msg);
1589       g_free(safe_dftext);
1590       g_free(dftext);
1591       return CF_ERROR;
1592     }
1593
1594     /* Was it empty? */
1595     if (dfcode == NULL) {
1596       /* Yes - free the filter text, and set it to null. */
1597       g_free(dftext);
1598       dftext = NULL;
1599     }
1600   }
1601
1602   /* We have a valid filter.  Replace the current filter. */
1603   g_free(cf->dfilter);
1604   cf->dfilter = dftext;
1605
1606   /* Now rescan the packet list, applying the new filter, but not
1607      throwing away information constructed on a previous pass. */
1608   if (dftext == NULL) {
1609     rescan_packets(cf, "Resetting", "Filter", TRUE, FALSE);
1610   } else {
1611     rescan_packets(cf, "Filtering", dftext, TRUE, FALSE);
1612   }
1613
1614   /* Cleanup and release all dfilter resources */
1615   if (dfcode != NULL){
1616     dfilter_free(dfcode);
1617   }
1618   return CF_OK;
1619 }
1620
1621 void
1622 cf_colorize_packets(capture_file *cf)
1623 {
1624   rescan_packets(cf, "Colorizing", "all packets", FALSE, FALSE);
1625 }
1626
1627 void
1628 cf_reftime_packets(capture_file *cf)
1629 {
1630
1631 #ifdef NEW_PACKET_LIST
1632   ref_time_packets(cf);
1633 #else
1634   rescan_packets(cf, "Reprocessing", "all packets", TRUE, TRUE);
1635 #endif
1636 }
1637
1638 void
1639 cf_redissect_packets(capture_file *cf)
1640 {
1641   rescan_packets(cf, "Reprocessing", "all packets", TRUE, TRUE);
1642 }
1643
1644 /* Rescan the list of packets, reconstructing the CList.
1645
1646    "action" describes why we're doing this; it's used in the progress
1647    dialog box.
1648
1649    "action_item" describes what we're doing; it's used in the progress
1650    dialog box.
1651
1652    "refilter" is TRUE if we need to re-evaluate the filter expression.
1653
1654    "redissect" is TRUE if we need to make the dissectors reconstruct
1655    any state information they have (because a preference that affects
1656    some dissector has changed, meaning some dissector might construct
1657    its state differently from the way it was constructed the last time). */
1658 static void
1659 rescan_packets(capture_file *cf, const char *action, const char *action_item,
1660                 gboolean refilter, gboolean redissect)
1661 {
1662   frame_data *fdata;
1663   progdlg_t  *progbar = NULL;
1664   gboolean    stop_flag;
1665   int         count;
1666   int         err;
1667   gchar      *err_info;
1668   frame_data *selected_frame, *preceding_frame, *following_frame, *prev_frame;
1669   int         selected_row, prev_row, preceding_row, following_row;
1670   gboolean    selected_frame_seen;
1671   int         row;
1672   float       progbar_val;
1673   GTimeVal    start_time;
1674   gchar       status_str[100];
1675   int         progbar_nextstep;
1676   int         progbar_quantum;
1677   dfilter_t   *dfcode;
1678   gboolean    filtering_tap_listeners;
1679   guint       tap_flags;
1680 #ifdef NEW_PACKET_LIST
1681   gboolean    add_to_packet_list = FALSE;
1682 #else
1683   gboolean    add_to_packet_list = TRUE;
1684 #endif
1685
1686   /* Compile the current display filter.
1687    * We assume this will not fail since cf->dfilter is only set in
1688    * cf_filter IFF the filter was valid.
1689    */
1690   dfcode=NULL;
1691   if(cf->dfilter){
1692     dfilter_compile(cf->dfilter, &dfcode);
1693   }
1694
1695   /* Do we have any tap listeners with filters? */
1696   filtering_tap_listeners = have_filtering_tap_listeners();
1697
1698   /* Get the union of the flags for all tap listeners. */
1699   tap_flags = union_of_tap_listener_flags();
1700
1701   cum_bytes=0;
1702   reset_tap_listeners();
1703   /* Which frame, if any, is the currently selected frame?
1704      XXX - should the selected frame or the focus frame be the "current"
1705      frame, that frame being the one from which "Find Frame" searches
1706      start? */
1707   selected_frame = cf->current_frame;
1708
1709   /* We don't yet know what row that frame will be on, if any, after we
1710      rebuild the clist, however. */
1711   selected_row = -1;
1712
1713   /* Freeze the packet list while we redo it, so we don't get any
1714      screen updates while it happens. */
1715 #ifdef NEW_PACKET_LIST
1716   new_packet_list_freeze();
1717 #else
1718   packet_list_freeze();
1719
1720   /* Clear it out. */
1721   packet_list_clear();
1722 #endif
1723
1724   if (redissect) {
1725     /* We need to re-initialize all the state information that protocols
1726        keep, because some preference that controls a dissector has changed,
1727        which might cause the state information to be constructed differently
1728        by that dissector. */
1729
1730     /* We might receive new packets while redissecting, and we don't
1731        want to dissect those before their time. */
1732     cf->redissecting = TRUE;
1733
1734     /* Cleanup all data structures used for dissection. */
1735     cleanup_dissection();
1736     /* Initialize all data structures used for dissection. */
1737     init_dissection();
1738
1739 #ifdef NEW_PACKET_LIST
1740     /* We need to redissect the packets so we have to discard our old
1741      * packet list store. */
1742     new_packet_list_clear();
1743     add_to_packet_list = TRUE;
1744 #endif
1745   }
1746
1747   /* We don't yet know which will be the first and last frames displayed. */
1748   cf->first_displayed = NULL;
1749   cf->last_displayed = NULL;
1750
1751   /* We currently don't display any packets */
1752   cf->displayed_count = 0;
1753
1754   /* Iterate through the list of frames.  Call a routine for each frame
1755      to check whether it should be displayed and, if so, add it to
1756      the display list. */
1757   nstime_set_unset(&first_ts);
1758   nstime_set_unset(&prev_dis_ts);
1759
1760   /* Update the progress bar when it gets to this value. */
1761   progbar_nextstep = 0;
1762   /* When we reach the value that triggers a progress bar update,
1763      bump that value by this amount. */
1764   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
1765   /* Count of packets at which we've looked. */
1766   count = 0;
1767   /* Progress so far. */
1768   progbar_val = 0.0f;
1769
1770   stop_flag = FALSE;
1771   g_get_current_time(&start_time);
1772
1773   row = -1;             /* no previous row yet */
1774   prev_row = -1;
1775   prev_frame = NULL;
1776
1777   preceding_row = -1;
1778   preceding_frame = NULL;
1779   following_row = -1;
1780   following_frame = NULL;
1781
1782   selected_frame_seen = FALSE;
1783
1784   for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
1785     /* Create the progress bar if necessary.
1786        We check on every iteration of the loop, so that it takes no
1787        longer than the standard time to create it (otherwise, for a
1788        large file, we might take considerably longer than that standard
1789        time in order to get to the next progress bar step). */
1790     if (progbar == NULL)
1791       progbar = delayed_create_progress_dlg(action, action_item, TRUE,
1792                                             &stop_flag, &start_time,
1793                                             progbar_val);
1794
1795     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1796        when we update it, we have to run the GTK+ main loop to get it
1797        to repaint what's pending, and doing so may involve an "ioctl()"
1798        to see if there's any pending input from an X server, and doing
1799        that for every packet can be costly, especially on a big file. */
1800     if (count >= progbar_nextstep) {
1801       /* let's not divide by zero. I should never be started
1802        * with count == 0, so let's assert that
1803        */
1804       g_assert(cf->count > 0);
1805       progbar_val = (gfloat) count / cf->count;
1806
1807       if (progbar != NULL) {
1808         g_snprintf(status_str, sizeof(status_str),
1809                   "%4u of %u frames", count, cf->count);
1810         update_progress_dlg(progbar, progbar_val, status_str);
1811       }
1812
1813       progbar_nextstep += progbar_quantum;
1814     }
1815
1816     if (stop_flag) {
1817       /* Well, the user decided to abort the filtering.  Just stop.
1818
1819          XXX - go back to the previous filter?  Users probably just
1820          want not to wait for a filtering operation to finish;
1821          unless we cancel by having no filter, reverting to the
1822          previous filter will probably be even more expensive than
1823          continuing the filtering, as it involves going back to the
1824          beginning and filtering, and even with no filter we currently
1825          have to re-generate the entire clist, which is also expensive.
1826
1827          I'm not sure what Network Monitor does, but it doesn't appear
1828          to give you an unfiltered display if you cancel. */
1829       break;
1830     }
1831
1832     count++;
1833
1834     if (redissect) {
1835       /* Since all state for the frame was destroyed, mark the frame
1836        * as not visited, free the GSList referring to the state
1837        * data (the per-frame data itself was freed by
1838        * "init_dissection()"), and null out the GSList pointer. */
1839       fdata->flags.visited = 0;
1840       if (fdata->pfd) {
1841                 g_slist_free(fdata->pfd);
1842         fdata->pfd = NULL;
1843       }
1844     }
1845
1846     if (!wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
1847         cf->pd, fdata->cap_len, &err, &err_info)) {
1848                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1849                     cf_read_error_message(err, err_info), cf->filename);
1850                         break;
1851     }
1852
1853     /* If the previous frame is displayed, and we haven't yet seen the
1854        selected frame, remember that frame - it's the closest one we've
1855        yet seen before the selected frame. */
1856     if (prev_row != -1 && !selected_frame_seen) {
1857       preceding_row = prev_row;
1858       preceding_frame = prev_frame;
1859     }
1860     row = add_packet_to_packet_list(fdata, cf, dfcode, filtering_tap_listeners,
1861                                     tap_flags, &cf->pseudo_header, cf->pd,
1862                                     refilter,
1863                                     add_to_packet_list);
1864
1865     /* If this frame is displayed, and this is the first frame we've
1866        seen displayed after the selected frame, remember this frame -
1867        it's the closest one we've yet seen at or after the selected
1868        frame. */
1869     if (row != -1 && selected_frame_seen && following_row == -1) {
1870       following_row = row;
1871       following_frame = fdata;
1872     }
1873     if (fdata == selected_frame) {
1874       selected_row = row;
1875       selected_frame_seen = TRUE;
1876     }
1877
1878     /* Remember this row/frame - it'll be the previous row/frame
1879        on the next pass through the loop. */
1880     prev_row = row;
1881     prev_frame = fdata;
1882   }
1883
1884   /* We are done redissecting the packet list. */
1885   cf->redissecting = FALSE;
1886
1887 #ifndef NEW_PACKET_LIST
1888   /* Re-sort the list using the previously selected order */
1889   packet_list_set_sort_column();
1890 #endif
1891
1892   if (redissect) {
1893     /* Clear out what remains of the visited flags and per-frame data
1894        pointers.
1895
1896        XXX - that may cause various forms of bogosity when dissecting
1897        these frames, as they won't have been seen by this sequential
1898        pass, but the only alternative I see is to keep scanning them
1899        even though the user requested that the scan stop, and that
1900        would leave the user stuck with an Wireshark grinding on
1901        until it finishes.  Should we just stick them with that? */
1902     for (; fdata != NULL; fdata = fdata->next) {
1903       fdata->flags.visited = 0;
1904       if (fdata->pfd) {
1905                 g_slist_free(fdata->pfd);
1906         fdata->pfd = NULL;
1907       }
1908     }
1909   }
1910
1911   /* We're done filtering the packets; destroy the progress bar if it
1912      was created. */
1913   if (progbar != NULL)
1914     destroy_progress_dlg(progbar);
1915
1916   /* Unfreeze the packet list. */
1917 #ifdef NEW_PACKET_LIST
1918   if (!add_to_packet_list)
1919     new_packet_list_recreate_visible_rows();
1920   new_packet_list_thaw();
1921 #else
1922   packet_list_thaw();
1923 #endif
1924
1925   if (selected_row == -1) {
1926     /* The selected frame didn't pass the filter. */
1927     if (selected_frame == NULL) {
1928       /* That's because there *was* no selected frame.  Make the first
1929          displayed frame the current frame. */
1930       selected_row = 0;
1931     } else {
1932       /* Find the nearest displayed frame to the selected frame (whether
1933          it's before or after that frame) and make that the current frame.
1934          If the next and previous displayed frames are equidistant from the
1935          selected frame, choose the next one. */
1936       g_assert(following_frame == NULL ||
1937                following_frame->num >= selected_frame->num);
1938       g_assert(preceding_frame == NULL ||
1939                preceding_frame->num <= selected_frame->num);
1940       if (following_frame == NULL) {
1941         /* No frame after the selected frame passed the filter, so we
1942            have to select the last displayed frame before the selected
1943            frame. */
1944         selected_row = preceding_row;
1945       } else if (preceding_frame == NULL) {
1946         /* No frame before the selected frame passed the filter, so we
1947            have to select the first displayed frame after the selected
1948            frame. */
1949         selected_row = following_row;
1950       } else {
1951         /* Frames before and after the selected frame passed the filter, so
1952                    we'll select the previous frame */
1953         selected_row = preceding_row;
1954       }
1955     }
1956   }
1957
1958   if (selected_row == -1) {
1959     /* There are no frames displayed at all. */
1960     cf_unselect_packet(cf);
1961   } else {
1962 #ifndef NEW_PACKET_LIST
1963     /* Either the frame that was selected passed the filter, or we've
1964        found the nearest displayed frame to that frame.  Select it, make
1965        it the focus row, and make it visible. */
1966     if (selected_row == 0) {
1967       /* Set to invalid to force update of packet list and packet details */
1968       cf->current_row = -1;
1969     }
1970     packet_list_set_selected_row(selected_row);
1971 #endif /* NEW_PACKET_LIST */
1972   }
1973
1974   /* Cleanup and release all dfilter resources */
1975   if (dfcode != NULL){
1976     dfilter_free(dfcode);
1977   }
1978 }
1979 /*
1980  * Scan trough all frame data and recalculate the ref time
1981  * without rereading the file.
1982  * XXX - do we need a progres bar or is this fast enough?
1983  */
1984 #ifdef NEW_PACKET_LIST
1985 static void
1986 ref_time_packets(capture_file *cf)
1987 {
1988
1989
1990   frame_data *fdata;
1991
1992   nstime_set_unset(&first_ts);
1993   nstime_set_unset(&prev_dis_ts);
1994   cum_bytes=0;
1995
1996   for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
1997
1998         fdata->cum_bytes  = cum_bytes + fdata->pkt_len;
1999         /* just add some value here until we know if it is being displayed or not */
2000         fdata->cum_bytes  = cum_bytes + fdata->pkt_len;
2001
2002         /* If we don't have the time stamp of the first packet in the
2003      capture, it's because this is the first packet.  Save the time
2004      stamp of this packet as the time stamp of the first packet. */
2005         if (nstime_is_unset(&first_ts)) {
2006         first_ts  = fdata->abs_ts;
2007         }
2008           /* if this frames is marked as a reference time frame, reset
2009         firstsec and firstusec to this frame */
2010         if(fdata->flags.ref_time){
2011     first_ts = fdata->abs_ts;
2012         }
2013
2014         /* If we don't have the time stamp of the previous displayed packet,
2015      it's because this is the first displayed packet.  Save the time
2016      stamp of this packet as the time stamp of the previous displayed
2017      packet. */
2018         if (nstime_is_unset(&prev_dis_ts)) {
2019         prev_dis_ts = fdata->abs_ts;
2020         }
2021
2022         /* Get the time elapsed between the first packet and this packet. */
2023         nstime_delta(&fdata->rel_ts, &fdata->abs_ts, &first_ts);
2024
2025         /* If it's greater than the current elapsed time, set the elapsed time
2026      to it (we check for "greater than" so as not to be confused by
2027      time moving backwards). */
2028         if ((gint32)cf->elapsed_time.secs < fdata->rel_ts.secs
2029                 || ((gint32)cf->elapsed_time.secs == fdata->rel_ts.secs && (gint32)cf->elapsed_time.nsecs < fdata->rel_ts.nsecs)) {
2030         cf->elapsed_time = fdata->rel_ts;
2031         }
2032
2033         /* Get the time elapsed between the previous displayed packet and
2034      this packet. */
2035         nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, &prev_dis_ts);
2036
2037         if( (fdata->flags.passed_dfilter) || (fdata->flags.ref_time) ){
2038         /* This frame either passed the display filter list or is marked as
2039         a time reference frame.  All time reference frames are displayed
2040         even if they dont pass the display filter */
2041         if(fdata->flags.ref_time){
2042                         /* if this was a TIME REF frame we should reset the cul bytes field */
2043                 cum_bytes = fdata->pkt_len;
2044                 fdata->cum_bytes =  cum_bytes;
2045         } else {
2046                 /* increase cum_bytes with this packets length */
2047                 cum_bytes += fdata->pkt_len;
2048         }
2049         }
2050   }
2051 }
2052 #endif
2053 typedef enum {
2054   PSP_FINISHED,
2055   PSP_STOPPED,
2056   PSP_FAILED
2057 } psp_return_t;
2058
2059 static psp_return_t
2060 process_specified_packets(capture_file *cf, packet_range_t *range,
2061     const char *string1, const char *string2, gboolean terminate_is_stop,
2062     gboolean (*callback)(capture_file *, frame_data *,
2063                          union wtap_pseudo_header *, const guint8 *, void *),
2064     void *callback_args)
2065 {
2066   frame_data *fdata;
2067   int         err;
2068   gchar      *err_info;
2069   union wtap_pseudo_header pseudo_header;
2070   guint8      pd[WTAP_MAX_PACKET_SIZE+1];
2071   psp_return_t ret = PSP_FINISHED;
2072
2073   progdlg_t  *progbar = NULL;
2074   int         progbar_count;
2075   float       progbar_val;
2076   gboolean    progbar_stop_flag;
2077   GTimeVal    progbar_start_time;
2078   gchar       progbar_status_str[100];
2079   int         progbar_nextstep;
2080   int         progbar_quantum;
2081   range_process_e process_this;
2082
2083   /* Update the progress bar when it gets to this value. */
2084   progbar_nextstep = 0;
2085   /* When we reach the value that triggers a progress bar update,
2086      bump that value by this amount. */
2087   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
2088   /* Count of packets at which we've looked. */
2089   progbar_count = 0;
2090   /* Progress so far. */
2091   progbar_val = 0.0f;
2092
2093   progbar_stop_flag = FALSE;
2094   g_get_current_time(&progbar_start_time);
2095
2096   packet_range_process_init(range);
2097
2098   /* Iterate through the list of packets, printing the packets that
2099      were selected by the current display filter.  */
2100   for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
2101     /* Create the progress bar if necessary.
2102        We check on every iteration of the loop, so that it takes no
2103        longer than the standard time to create it (otherwise, for a
2104        large file, we might take considerably longer than that standard
2105        time in order to get to the next progress bar step). */
2106     if (progbar == NULL)
2107       progbar = delayed_create_progress_dlg(string1, string2,
2108                                             terminate_is_stop,
2109                                             &progbar_stop_flag,
2110                                             &progbar_start_time,
2111                                             progbar_val);
2112
2113     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
2114        when we update it, we have to run the GTK+ main loop to get it
2115        to repaint what's pending, and doing so may involve an "ioctl()"
2116        to see if there's any pending input from an X server, and doing
2117        that for every packet can be costly, especially on a big file. */
2118     if (progbar_count >= progbar_nextstep) {
2119       /* let's not divide by zero. I should never be started
2120        * with count == 0, so let's assert that
2121        */
2122       g_assert(cf->count > 0);
2123       progbar_val = (gfloat) progbar_count / cf->count;
2124
2125       if (progbar != NULL) {
2126         g_snprintf(progbar_status_str, sizeof(progbar_status_str),
2127                    "%4u of %u packets", progbar_count, cf->count);
2128         update_progress_dlg(progbar, progbar_val, progbar_status_str);
2129       }
2130
2131       progbar_nextstep += progbar_quantum;
2132     }
2133
2134     if (progbar_stop_flag) {
2135       /* Well, the user decided to abort the operation.  Just stop,
2136          and arrange to return PSP_STOPPED to our caller, so they know
2137          it was stopped explicitly. */
2138       ret = PSP_STOPPED;
2139       break;
2140     }
2141
2142     progbar_count++;
2143
2144     /* do we have to process this packet? */
2145     process_this = packet_range_process_packet(range, fdata);
2146     if (process_this == range_process_next) {
2147         /* this packet uninteresting, continue with next one */
2148         continue;
2149     } else if (process_this == range_processing_finished) {
2150         /* all interesting packets processed, stop the loop */
2151         break;
2152     }
2153
2154     /* Get the packet */
2155     if (!wtap_seek_read(cf->wth, fdata->file_off, &pseudo_header,
2156                         pd, fdata->cap_len, &err, &err_info)) {
2157       /* Attempt to get the packet failed. */
2158       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2159                     cf_read_error_message(err, err_info), cf->filename);
2160       ret = PSP_FAILED;
2161       break;
2162     }
2163     /* Process the packet */
2164     if (!callback(cf, fdata, &pseudo_header, pd, callback_args)) {
2165       /* Callback failed.  We assume it reported the error appropriately. */
2166       ret = PSP_FAILED;
2167       break;
2168     }
2169   }
2170
2171   /* We're done printing the packets; destroy the progress bar if
2172      it was created. */
2173   if (progbar != NULL)
2174     destroy_progress_dlg(progbar);
2175
2176   return ret;
2177 }
2178
2179 typedef struct {
2180   gboolean construct_protocol_tree;
2181   column_info *cinfo;
2182 } retap_callback_args_t;
2183
2184 static gboolean
2185 retap_packet(capture_file *cf _U_, frame_data *fdata,
2186              union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2187              void *argsp)
2188 {
2189   retap_callback_args_t *args = argsp;
2190   epan_dissect_t edt;
2191
2192   epan_dissect_init(&edt, args->construct_protocol_tree, FALSE);
2193   tap_queue_init(&edt);
2194   epan_dissect_run(&edt, pseudo_header, pd, fdata, args->cinfo);
2195   tap_push_tapped_queue(&edt);
2196   epan_dissect_cleanup(&edt);
2197
2198   return TRUE;
2199 }
2200
2201 cf_read_status_t
2202 cf_retap_packets(capture_file *cf)
2203 {
2204   packet_range_t range;
2205   retap_callback_args_t callback_args;
2206   gboolean filtering_tap_listeners;
2207   guint tap_flags;
2208
2209   /* Do we have any tap listeners with filters? */
2210   filtering_tap_listeners = have_filtering_tap_listeners();
2211
2212   tap_flags = union_of_tap_listener_flags();
2213
2214   /* If any tap listeners have filters, or require the protocol tree,
2215      construct the protocol tree. */
2216   callback_args.construct_protocol_tree = filtering_tap_listeners ||
2217                                           (tap_flags & TL_REQUIRES_PROTO_TREE);
2218
2219   /* If any tap listeners require the columns, construct them. */
2220   callback_args.cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
2221
2222   /* Reset the tap listeners. */
2223   reset_tap_listeners();
2224
2225   /* Iterate through the list of packets, dissecting all packets and
2226      re-running the taps. */
2227   packet_range_init(&range);
2228   packet_range_process_init(&range);
2229   switch (process_specified_packets(cf, &range, "Recalculating statistics on",
2230                                     "all packets", TRUE, retap_packet,
2231                                     &callback_args)) {
2232   case PSP_FINISHED:
2233     /* Completed successfully. */
2234     return CF_READ_OK;
2235
2236   case PSP_STOPPED:
2237     /* Well, the user decided to abort the refiltering.
2238        Return CF_READ_ABORTED so our caller knows they did that. */
2239     return CF_READ_ABORTED;
2240
2241   case PSP_FAILED:
2242     /* Error while retapping. */
2243     return CF_READ_ERROR;
2244   }
2245
2246   g_assert_not_reached();
2247   return CF_READ_OK;
2248 }
2249
2250 typedef struct {
2251   print_args_t *print_args;
2252   gboolean      print_header_line;
2253   char         *header_line_buf;
2254   int           header_line_buf_len;
2255   gboolean      print_formfeed;
2256   gboolean      print_separator;
2257   char         *line_buf;
2258   int           line_buf_len;
2259   gint         *col_widths;
2260 } print_callback_args_t;
2261
2262 static gboolean
2263 print_packet(capture_file *cf, frame_data *fdata,
2264              union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2265              void *argsp)
2266 {
2267   print_callback_args_t *args = argsp;
2268   epan_dissect_t edt;
2269   int             i;
2270   char           *cp;
2271   int             line_len;
2272   int             column_len;
2273   int             cp_off;
2274   gboolean        proto_tree_needed;
2275   char            bookmark_name[9+10+1];        /* "__frameNNNNNNNNNN__\0" */
2276   char            bookmark_title[6+10+1];       /* "Frame NNNNNNNNNN__\0" */
2277
2278   /* Create the protocol tree, and make it visible, if we're printing
2279      the dissection or the hex data.
2280      XXX - do we need it if we're just printing the hex data? */
2281   proto_tree_needed =
2282       args->print_args->print_dissections != print_dissections_none || args->print_args->print_hex || have_custom_cols(&cf->cinfo);
2283   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2284
2285   /* Fill in the column information if we're printing the summary
2286      information. */
2287   if (args->print_args->print_summary) {
2288     epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
2289     epan_dissect_fill_in_columns(&edt, TRUE);
2290   } else
2291     epan_dissect_run(&edt, pseudo_header, pd, fdata, NULL);
2292
2293   if (args->print_formfeed) {
2294     if (!new_page(args->print_args->stream))
2295       goto fail;
2296   } else {
2297       if (args->print_separator) {
2298         if (!print_line(args->print_args->stream, 0, ""))
2299           goto fail;
2300       }
2301   }
2302
2303   /*
2304    * We generate bookmarks, if the output format supports them.
2305    * The name is "__frameN__".
2306    */
2307   g_snprintf(bookmark_name, sizeof bookmark_name, "__frame%u__", fdata->num);
2308
2309   if (args->print_args->print_summary) {
2310     if (args->print_header_line) {
2311       if (!print_line(args->print_args->stream, 0, args->header_line_buf))
2312         goto fail;
2313       args->print_header_line = FALSE;  /* we might not need to print any more */
2314     }
2315     cp = &args->line_buf[0];
2316     line_len = 0;
2317     for (i = 0; i < cf->cinfo.num_cols; i++) {
2318       /* Find the length of the string for this column. */
2319       column_len = (int) strlen(cf->cinfo.col_data[i]);
2320       if (args->col_widths[i] > column_len)
2321          column_len = args->col_widths[i];
2322
2323       /* Make sure there's room in the line buffer for the column; if not,
2324          double its length. */
2325       line_len += column_len + 1;       /* "+1" for space */
2326       if (line_len > args->line_buf_len) {
2327         cp_off = (int) (cp - args->line_buf);
2328         args->line_buf_len = 2 * line_len;
2329         args->line_buf = g_realloc(args->line_buf, args->line_buf_len + 1);
2330         cp = args->line_buf + cp_off;
2331       }
2332
2333       /* Right-justify the packet number column. */
2334       if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2335         g_snprintf(cp, column_len+1, "%*s", args->col_widths[i], cf->cinfo.col_data[i]);
2336       else
2337         g_snprintf(cp, column_len+1, "%-*s", args->col_widths[i], cf->cinfo.col_data[i]);
2338       cp += column_len;
2339       if (i != cf->cinfo.num_cols - 1)
2340         *cp++ = ' ';
2341     }
2342     *cp = '\0';
2343
2344     /*
2345      * Generate a bookmark, using the summary line as the title.
2346      */
2347     if (!print_bookmark(args->print_args->stream, bookmark_name,
2348                         args->line_buf))
2349       goto fail;
2350
2351     if (!print_line(args->print_args->stream, 0, args->line_buf))
2352       goto fail;
2353   } else {
2354     /*
2355      * Generate a bookmark, using "Frame N" as the title, as we're not
2356      * printing the summary line.
2357      */
2358     g_snprintf(bookmark_title, sizeof bookmark_title, "Frame %u", fdata->num);
2359     if (!print_bookmark(args->print_args->stream, bookmark_name,
2360                         bookmark_title))
2361       goto fail;
2362   } /* if (print_summary) */
2363
2364   if (args->print_args->print_dissections != print_dissections_none) {
2365     if (args->print_args->print_summary) {
2366       /* Separate the summary line from the tree with a blank line. */
2367       if (!print_line(args->print_args->stream, 0, ""))
2368         goto fail;
2369     }
2370
2371     /* Print the information in that tree. */
2372     if (!proto_tree_print(args->print_args, &edt, args->print_args->stream))
2373       goto fail;
2374
2375     /* Print a blank line if we print anything after this (aka more than one packet). */
2376     args->print_separator = TRUE;
2377
2378     /* Print a header line if we print any more packet summaries */
2379     args->print_header_line = TRUE;
2380   }
2381
2382   if (args->print_args->print_hex) {
2383     /* Print the full packet data as hex. */
2384     if (!print_hex_data(args->print_args->stream, &edt))
2385       goto fail;
2386
2387     /* Print a blank line if we print anything after this (aka more than one packet). */
2388     args->print_separator = TRUE;
2389
2390     /* Print a header line if we print any more packet summaries */
2391     args->print_header_line = TRUE;
2392   } /* if (args->print_args->print_dissections != print_dissections_none) */
2393
2394   epan_dissect_cleanup(&edt);
2395
2396   /* do we want to have a formfeed between each packet from now on? */
2397   if(args->print_args->print_formfeed) {
2398     args->print_formfeed = TRUE;
2399   }
2400
2401   return TRUE;
2402
2403 fail:
2404   epan_dissect_cleanup(&edt);
2405   return FALSE;
2406 }
2407
2408 cf_print_status_t
2409 cf_print_packets(capture_file *cf, print_args_t *print_args)
2410 {
2411   int         i;
2412   print_callback_args_t callback_args;
2413   gint        data_width;
2414   char        *cp;
2415   int         cp_off;
2416   int         column_len;
2417   int         line_len;
2418   psp_return_t ret;
2419
2420   callback_args.print_args = print_args;
2421   callback_args.print_header_line = TRUE;
2422   callback_args.header_line_buf = NULL;
2423   callback_args.header_line_buf_len = 256;
2424   callback_args.print_formfeed = FALSE;
2425   callback_args.print_separator = FALSE;
2426   callback_args.line_buf = NULL;
2427   callback_args.line_buf_len = 256;
2428   callback_args.col_widths = NULL;
2429
2430   if (!print_preamble(print_args->stream, cf->filename)) {
2431     destroy_print_stream(print_args->stream);
2432     return CF_PRINT_WRITE_ERROR;
2433   }
2434
2435   if (print_args->print_summary) {
2436     /* We're printing packet summaries.  Allocate the header line buffer
2437        and get the column widths. */
2438     callback_args.header_line_buf = g_malloc(callback_args.header_line_buf_len + 1);
2439
2440     /* Find the widths for each of the columns - maximum of the
2441        width of the title and the width of the data - and construct
2442        a buffer with a line containing the column titles. */
2443     callback_args.col_widths = (gint *) g_malloc(sizeof(gint) * cf->cinfo.num_cols);
2444     cp = &callback_args.header_line_buf[0];
2445     line_len = 0;
2446     for (i = 0; i < cf->cinfo.num_cols; i++) {
2447       /* Don't pad the last column. */
2448       if (i == cf->cinfo.num_cols - 1)
2449         callback_args.col_widths[i] = 0;
2450       else {
2451         callback_args.col_widths[i] = (gint) strlen(cf->cinfo.col_title[i]);
2452         data_width = get_column_char_width(get_column_format(i));
2453         if (data_width > callback_args.col_widths[i])
2454           callback_args.col_widths[i] = data_width;
2455       }
2456
2457       /* Find the length of the string for this column. */
2458       column_len = (int) strlen(cf->cinfo.col_title[i]);
2459       if (callback_args.col_widths[i] > column_len)
2460         column_len = callback_args.col_widths[i];
2461
2462       /* Make sure there's room in the line buffer for the column; if not,
2463          double its length. */
2464       line_len += column_len + 1;       /* "+1" for space */
2465       if (line_len > callback_args.header_line_buf_len) {
2466         cp_off = (int) (cp - callback_args.header_line_buf);
2467         callback_args.header_line_buf_len = 2 * line_len;
2468         callback_args.header_line_buf = g_realloc(callback_args.header_line_buf,
2469                                                   callback_args.header_line_buf_len + 1);
2470         cp = callback_args.header_line_buf + cp_off;
2471       }
2472
2473       /* Right-justify the packet number column. */
2474 /*      if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2475         g_snprintf(cp, column_len+1, "%*s", callback_args.col_widths[i], cf->cinfo.col_title[i]);
2476       else*/
2477       g_snprintf(cp, column_len+1, "%-*s", callback_args.col_widths[i], cf->cinfo.col_title[i]);
2478       cp += column_len;
2479       if (i != cf->cinfo.num_cols - 1)
2480         *cp++ = ' ';
2481     }
2482     *cp = '\0';
2483
2484     /* Now start out the main line buffer with the same length as the
2485        header line buffer. */
2486     callback_args.line_buf_len = callback_args.header_line_buf_len;
2487     callback_args.line_buf = g_malloc(callback_args.line_buf_len + 1);
2488   } /* if (print_summary) */
2489
2490   /* Iterate through the list of packets, printing the packets we were
2491      told to print. */
2492   ret = process_specified_packets(cf, &print_args->range, "Printing",
2493                                   "selected packets", TRUE, print_packet,
2494                                   &callback_args);
2495
2496   g_free(callback_args.header_line_buf);
2497   g_free(callback_args.line_buf);
2498   g_free(callback_args.col_widths);
2499
2500   switch (ret) {
2501
2502   case PSP_FINISHED:
2503     /* Completed successfully. */
2504     break;
2505
2506   case PSP_STOPPED:
2507     /* Well, the user decided to abort the printing.
2508
2509        XXX - note that what got generated before they did that
2510        will get printed if we're piping to a print program; we'd
2511        have to write to a file and then hand that to the print
2512        program to make it actually not print anything. */
2513     break;
2514
2515   case PSP_FAILED:
2516     /* Error while printing.
2517
2518        XXX - note that what got generated before they did that
2519        will get printed if we're piping to a print program; we'd
2520        have to write to a file and then hand that to the print
2521        program to make it actually not print anything. */
2522     destroy_print_stream(print_args->stream);
2523     return CF_PRINT_WRITE_ERROR;
2524   }
2525
2526   if (!print_finale(print_args->stream)) {
2527     destroy_print_stream(print_args->stream);
2528     return CF_PRINT_WRITE_ERROR;
2529   }
2530
2531   if (!destroy_print_stream(print_args->stream))
2532     return CF_PRINT_WRITE_ERROR;
2533
2534   return CF_PRINT_OK;
2535 }
2536
2537 static gboolean
2538 write_pdml_packet(capture_file *cf _U_, frame_data *fdata,
2539                   union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2540                   void *argsp)
2541 {
2542   FILE *fh = argsp;
2543   epan_dissect_t edt;
2544
2545   /* Create the protocol tree, but don't fill in the column information. */
2546   epan_dissect_init(&edt, TRUE, TRUE);
2547   epan_dissect_run(&edt, pseudo_header, pd, fdata, NULL);
2548
2549   /* Write out the information in that tree. */
2550   proto_tree_write_pdml(&edt, fh);
2551
2552   epan_dissect_cleanup(&edt);
2553
2554   return !ferror(fh);
2555 }
2556
2557 cf_print_status_t
2558 cf_write_pdml_packets(capture_file *cf, print_args_t *print_args)
2559 {
2560   FILE        *fh;
2561   psp_return_t ret;
2562
2563   fh = ws_fopen(print_args->file, "w");
2564   if (fh == NULL)
2565     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2566
2567   write_pdml_preamble(fh);
2568   if (ferror(fh)) {
2569     fclose(fh);
2570     return CF_PRINT_WRITE_ERROR;
2571   }
2572
2573   /* Iterate through the list of packets, printing the packets we were
2574      told to print. */
2575   ret = process_specified_packets(cf, &print_args->range, "Writing PDML",
2576                                   "selected packets", TRUE,
2577                                   write_pdml_packet, fh);
2578
2579   switch (ret) {
2580
2581   case PSP_FINISHED:
2582     /* Completed successfully. */
2583     break;
2584
2585   case PSP_STOPPED:
2586     /* Well, the user decided to abort the printing. */
2587     break;
2588
2589   case PSP_FAILED:
2590     /* Error while printing. */
2591     fclose(fh);
2592     return CF_PRINT_WRITE_ERROR;
2593   }
2594
2595   write_pdml_finale(fh);
2596   if (ferror(fh)) {
2597     fclose(fh);
2598     return CF_PRINT_WRITE_ERROR;
2599   }
2600
2601   /* XXX - check for an error */
2602   fclose(fh);
2603
2604   return CF_PRINT_OK;
2605 }
2606
2607 static gboolean
2608 write_psml_packet(capture_file *cf, frame_data *fdata,
2609                   union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2610                   void *argsp)
2611 {
2612   FILE *fh = argsp;
2613   epan_dissect_t edt;
2614   gboolean proto_tree_needed;
2615
2616   /* Fill in the column information, only create the protocol tree
2617      if having custom columns. */
2618   proto_tree_needed = have_custom_cols(&cf->cinfo);
2619   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2620   epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
2621   epan_dissect_fill_in_columns(&edt, TRUE);
2622
2623   /* Write out the information in that tree. */
2624   proto_tree_write_psml(&edt, fh);
2625
2626   epan_dissect_cleanup(&edt);
2627
2628   return !ferror(fh);
2629 }
2630
2631 cf_print_status_t
2632 cf_write_psml_packets(capture_file *cf, print_args_t *print_args)
2633 {
2634   FILE        *fh;
2635   psp_return_t ret;
2636
2637   fh = ws_fopen(print_args->file, "w");
2638   if (fh == NULL)
2639     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2640
2641   write_psml_preamble(fh);
2642   if (ferror(fh)) {
2643     fclose(fh);
2644     return CF_PRINT_WRITE_ERROR;
2645   }
2646
2647   /* Iterate through the list of packets, printing the packets we were
2648      told to print. */
2649   ret = process_specified_packets(cf, &print_args->range, "Writing PSML",
2650                                   "selected packets", TRUE,
2651                                   write_psml_packet, fh);
2652
2653   switch (ret) {
2654
2655   case PSP_FINISHED:
2656     /* Completed successfully. */
2657     break;
2658
2659   case PSP_STOPPED:
2660     /* Well, the user decided to abort the printing. */
2661     break;
2662
2663   case PSP_FAILED:
2664     /* Error while printing. */
2665     fclose(fh);
2666     return CF_PRINT_WRITE_ERROR;
2667   }
2668
2669   write_psml_finale(fh);
2670   if (ferror(fh)) {
2671     fclose(fh);
2672     return CF_PRINT_WRITE_ERROR;
2673   }
2674
2675   /* XXX - check for an error */
2676   fclose(fh);
2677
2678   return CF_PRINT_OK;
2679 }
2680
2681 static gboolean
2682 write_csv_packet(capture_file *cf, frame_data *fdata,
2683                  union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2684                  void *argsp)
2685 {
2686   FILE *fh = argsp;
2687   epan_dissect_t edt;
2688   gboolean proto_tree_needed;
2689
2690   /* Fill in the column information, only create the protocol tree
2691      if having custom columns. */
2692   proto_tree_needed = have_custom_cols(&cf->cinfo);
2693   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2694   epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
2695   epan_dissect_fill_in_columns(&edt, TRUE);
2696
2697   /* Write out the information in that tree. */
2698   proto_tree_write_csv(&edt, fh);
2699
2700   epan_dissect_cleanup(&edt);
2701
2702   return !ferror(fh);
2703 }
2704
2705 cf_print_status_t
2706 cf_write_csv_packets(capture_file *cf, print_args_t *print_args)
2707 {
2708   FILE        *fh;
2709   psp_return_t ret;
2710
2711   fh = ws_fopen(print_args->file, "w");
2712   if (fh == NULL)
2713     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2714
2715   write_csv_preamble(fh);
2716   if (ferror(fh)) {
2717     fclose(fh);
2718     return CF_PRINT_WRITE_ERROR;
2719   }
2720
2721   /* Iterate through the list of packets, printing the packets we were
2722      told to print. */
2723   ret = process_specified_packets(cf, &print_args->range, "Writing CSV",
2724                                   "selected packets", TRUE,
2725                                   write_csv_packet, fh);
2726
2727   switch (ret) {
2728
2729   case PSP_FINISHED:
2730     /* Completed successfully. */
2731     break;
2732
2733   case PSP_STOPPED:
2734     /* Well, the user decided to abort the printing. */
2735     break;
2736
2737   case PSP_FAILED:
2738     /* Error while printing. */
2739     fclose(fh);
2740     return CF_PRINT_WRITE_ERROR;
2741   }
2742
2743   write_csv_finale(fh);
2744   if (ferror(fh)) {
2745     fclose(fh);
2746     return CF_PRINT_WRITE_ERROR;
2747   }
2748
2749   /* XXX - check for an error */
2750   fclose(fh);
2751
2752   return CF_PRINT_OK;
2753 }
2754
2755 static gboolean
2756 write_carrays_packet(capture_file *cf _U_, frame_data *fdata,
2757                      union wtap_pseudo_header *pseudo_header _U_,
2758                      const guint8 *pd, void *argsp)
2759 {
2760   FILE *fh = argsp;
2761
2762   proto_tree_write_carrays(pd, fdata->cap_len, fdata->num, fh);
2763   return !ferror(fh);
2764 }
2765
2766 cf_print_status_t
2767 cf_write_carrays_packets(capture_file *cf, print_args_t *print_args)
2768 {
2769   FILE        *fh;
2770   psp_return_t ret;
2771
2772   fh = ws_fopen(print_args->file, "w");
2773
2774   if (fh == NULL)
2775     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2776
2777   write_carrays_preamble(fh);
2778
2779   if (ferror(fh)) {
2780     fclose(fh);
2781     return CF_PRINT_WRITE_ERROR;
2782   }
2783
2784   /* Iterate through the list of packets, printing the packets we were
2785      told to print. */
2786   ret = process_specified_packets(cf, &print_args->range,
2787                                   "Writing C Arrays",
2788                                   "selected packets", TRUE,
2789                                   write_carrays_packet, fh);
2790   switch (ret) {
2791   case PSP_FINISHED:
2792     /* Completed successfully. */
2793     break;
2794   case PSP_STOPPED:
2795     /* Well, the user decided to abort the printing. */
2796     break;
2797   case PSP_FAILED:
2798     /* Error while printing. */
2799     fclose(fh);
2800     return CF_PRINT_WRITE_ERROR;
2801   }
2802
2803   write_carrays_finale(fh);
2804
2805   if (ferror(fh)) {
2806     fclose(fh);
2807     return CF_PRINT_WRITE_ERROR;
2808   }
2809
2810   fclose(fh);
2811   return CF_PRINT_OK;
2812 }
2813
2814 /* Scan through the packet list and change all columns that use the
2815    "command-line-specified" time stamp format to use the current
2816    value of that format. */
2817 void
2818 cf_change_time_formats(capture_file *cf)
2819 {
2820   frame_data *fdata;
2821   progdlg_t  *progbar = NULL;
2822   gboolean    stop_flag;
2823   int         count;
2824   int         row;
2825   int         i;
2826   float       progbar_val;
2827   GTimeVal    start_time;
2828   gchar       status_str[100];
2829   int         progbar_nextstep;
2830   int         progbar_quantum;
2831   gboolean    sorted_by_frame_column;
2832
2833
2834   /* adjust timestamp precision if auto is selected */
2835   cf_timestamp_auto_precision(cf);
2836
2837   /* Are there any columns with time stamps in the "command-line-specified"
2838      format?
2839
2840      XXX - we have to force the "column is writable" flag on, as it
2841      might be off from the last frame that was dissected. */
2842   col_set_writable(&cf->cinfo, TRUE);
2843   if (!check_col(&cf->cinfo, COL_CLS_TIME) &&
2844       !check_col(&cf->cinfo, COL_ABS_TIME) &&
2845       !check_col(&cf->cinfo, COL_ABS_DATE_TIME) &&
2846       !check_col(&cf->cinfo, COL_REL_TIME) &&
2847       !check_col(&cf->cinfo, COL_DELTA_TIME) &&
2848       !check_col(&cf->cinfo, COL_DELTA_TIME_DIS)) {
2849     /* No, there aren't any columns in that format, so we have no work
2850        to do. */
2851     return;
2852   }
2853
2854   /* Freeze the packet list while we redo it, so we don't get any
2855      screen updates while it happens. */
2856 #ifdef NEW_PACKET_LIST
2857   new_packet_list_freeze();
2858 #else
2859   packet_list_freeze();
2860 #endif
2861
2862   /* Update the progress bar when it gets to this value. */
2863   progbar_nextstep = 0;
2864   /* When we reach the value that triggers a progress bar update,
2865      bump that value by this amount. */
2866   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
2867   /* Count of packets at which we've looked. */
2868   count = 0;
2869   /* Progress so far. */
2870   progbar_val = 0.0f;
2871
2872   /*  If the rows are currently sorted by the frame column then we know
2873    *  the row number of each packet: it's the row number of the previously
2874    *  displayed packet + 1.
2875    *
2876    *  Otherwise, if the display is sorted by a different column then we have
2877    *  to use the O(N) packet_list_find_row_from_data() (thus making the job
2878    *  of changing the time display format O(N**2)).
2879    *
2880    *  (XXX - In fact it's still O(N**2) because gtk_clist_set_text() takes
2881    *  the row number and walks that many elements down the clist to find
2882    *  the appropriate element.)
2883    */
2884   sorted_by_frame_column = FALSE;
2885   for (i = 0; i < cf->cinfo.num_cols; i++) {
2886     if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2887     {
2888 #ifndef NEW_PACKET_LIST
2889       sorted_by_frame_column = (i == packet_list_get_sort_column());
2890 #endif
2891       break;
2892     }
2893   }
2894
2895   stop_flag = FALSE;
2896   g_get_current_time(&start_time);
2897
2898   /* Iterate through the list of packets, checking whether the packet
2899      is in a row of the summary list and, if so, whether there are
2900      any columns that show the time in the "command-line-specified"
2901      format and, if so, update that row. */
2902   for (fdata = cf->plist, row = -1; fdata != NULL; fdata = fdata->next) {
2903     /* Create the progress bar if necessary.
2904        We check on every iteration of the loop, so that it takes no
2905        longer than the standard time to create it (otherwise, for a
2906        large file, we might take considerably longer than that standard
2907        time in order to get to the next progress bar step). */
2908     if (progbar == NULL)
2909       progbar = delayed_create_progress_dlg("Changing", "time display",
2910         TRUE, &stop_flag, &start_time, progbar_val);
2911
2912     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
2913        when we update it, we have to run the GTK+ main loop to get it
2914        to repaint what's pending, and doing so may involve an "ioctl()"
2915        to see if there's any pending input from an X server, and doing
2916        that for every packet can be costly, especially on a big file. */
2917     if (count >= progbar_nextstep) {
2918       /* let's not divide by zero. I should never be started
2919        * with count == 0, so let's assert that
2920        */
2921       g_assert(cf->count > 0);
2922
2923       progbar_val = (gfloat) count / cf->count;
2924
2925       if (progbar != NULL) {
2926         g_snprintf(status_str, sizeof(status_str),
2927                    "%4u of %u packets", count, cf->count);
2928         update_progress_dlg(progbar, progbar_val, status_str);
2929       }
2930
2931       progbar_nextstep += progbar_quantum;
2932     }
2933
2934     if (stop_flag) {
2935       /* Well, the user decided to abort the redisplay.  Just stop.
2936
2937          XXX - this leaves the time field in the old format in
2938          frames we haven't yet processed.  So it goes; should we
2939          simply not offer them the option of stopping? */
2940       break;
2941     }
2942
2943     count++;
2944
2945     /* Find what row this packet is in. */
2946     if (!sorted_by_frame_column) {
2947       /* This function is O(N), so we try to avoid using it... */
2948 #ifdef NEW_PACKET_LIST
2949           row = new_packet_list_find_row_from_data(fdata, FALSE);
2950 #else
2951       row = packet_list_find_row_from_data(fdata);
2952 #endif
2953     } else {
2954       /* ...which we do by maintaining a count of packets that are
2955          being displayed (i.e., that have passed the display filter),
2956          and using the current value of that count as the row number
2957          (which is why we can only do it when the display is sorted
2958          by the frame number). */
2959       if (fdata->flags.passed_dfilter)
2960         row++;
2961       else
2962         continue;
2963     }
2964
2965     if (row != -1) {
2966       /* This packet is in the summary list, on row "row". */
2967
2968       for (i = 0; i < cf->cinfo.num_cols; i++) {
2969         if (col_has_time_fmt(&cf->cinfo, i)) {
2970           /* This is one of the columns that shows the time in
2971              "command-line-specified" format; update it. */
2972           cf->cinfo.col_buf[i][0] = '\0';
2973           col_set_fmt_time(fdata, &cf->cinfo, cf->cinfo.col_fmt[i], i);
2974 #ifdef NEW_PACKET_LIST
2975 #else
2976           packet_list_set_text(row, i, cf->cinfo.col_data[i]);
2977 #endif
2978         }
2979       }
2980     }
2981   }
2982
2983   /* We're done redisplaying the packets; destroy the progress bar if it
2984      was created. */
2985   if (progbar != NULL)
2986     destroy_progress_dlg(progbar);
2987
2988   /* Set the column widths of those columns that show the time in
2989      "command-line-specified" format. */
2990   for (i = 0; i < cf->cinfo.num_cols; i++) {
2991     if (col_has_time_fmt(&cf->cinfo, i)) {
2992 #ifdef NEW_PACKET_LIST
2993       new_packet_list_set_time_width(cf->cinfo.col_fmt[i], i);
2994 #else
2995       packet_list_set_time_width(cf->cinfo.col_fmt[i], i);
2996 #endif
2997     }
2998   }
2999
3000   /* Unfreeze the packet list. */
3001 #ifdef NEW_PACKET_LIST
3002   new_packet_list_thaw();
3003 #else
3004   packet_list_thaw();
3005 #endif
3006 }
3007
3008 typedef struct {
3009         const char      *string;
3010         size_t          string_len;
3011         capture_file    *cf;
3012         gboolean        frame_matched;
3013 } match_data;
3014
3015 gboolean
3016 cf_find_packet_protocol_tree(capture_file *cf, const char *string)
3017 {
3018   match_data            mdata;
3019
3020   mdata.string = string;
3021   mdata.string_len = strlen(string);
3022   return find_packet(cf, match_protocol_tree, &mdata);
3023 }
3024
3025 static gboolean
3026 match_protocol_tree(capture_file *cf, frame_data *fdata, void *criterion)
3027 {
3028   match_data            *mdata = criterion;
3029   epan_dissect_t        edt;
3030
3031   /* Construct the protocol tree, including the displayed text */
3032   epan_dissect_init(&edt, TRUE, TRUE);
3033   /* We don't need the column information */
3034   epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, NULL);
3035
3036   /* Iterate through all the nodes, seeing if they have text that matches. */
3037   mdata->cf = cf;
3038   mdata->frame_matched = FALSE;
3039   proto_tree_children_foreach(edt.tree, match_subtree_text, mdata);
3040   epan_dissect_cleanup(&edt);
3041   return mdata->frame_matched;
3042 }
3043
3044 static void
3045 match_subtree_text(proto_node *node, gpointer data)
3046 {
3047   match_data    *mdata = (match_data*) data;
3048   const gchar   *string = mdata->string;
3049   size_t        string_len = mdata->string_len;
3050   capture_file  *cf = mdata->cf;
3051   field_info    *fi = PNODE_FINFO(node);
3052   gchar         label_str[ITEM_LABEL_LENGTH];
3053   gchar         *label_ptr;
3054   size_t        label_len;
3055   guint32       i;
3056   guint8        c_char;
3057   size_t        c_match = 0;
3058
3059   g_assert(fi && "dissection with an invisible proto tree?");
3060
3061   if (mdata->frame_matched) {
3062     /* We already had a match; don't bother doing any more work. */
3063     return;
3064   }
3065
3066   /* Don't match invisible entries. */
3067   if (PROTO_ITEM_IS_HIDDEN(node))
3068     return;
3069
3070   /* was a free format label produced? */
3071   if (fi->rep) {
3072     label_ptr = fi->rep->representation;
3073   } else {
3074     /* no, make a generic label */
3075     label_ptr = label_str;
3076     proto_item_fill_label(fi, label_str);
3077   }
3078
3079   /* Does that label match? */
3080   label_len = strlen(label_ptr);
3081   for (i = 0; i < label_len; i++) {
3082     c_char = label_ptr[i];
3083     if (cf->case_type)
3084       c_char = toupper(c_char);
3085     if (c_char == string[c_match]) {
3086       c_match++;
3087       if (c_match == string_len) {
3088         /* No need to look further; we have a match */
3089         mdata->frame_matched = TRUE;
3090         return;
3091       }
3092     } else
3093       c_match = 0;
3094   }
3095
3096   /* Recurse into the subtree, if it exists */
3097   if (node->first_child != NULL)
3098     proto_tree_children_foreach(node, match_subtree_text, mdata);
3099 }
3100
3101 gboolean
3102 cf_find_packet_summary_line(capture_file *cf, const char *string)
3103 {
3104   match_data            mdata;
3105
3106   mdata.string = string;
3107   mdata.string_len = strlen(string);
3108   return find_packet(cf, match_summary_line, &mdata);
3109 }
3110
3111 static gboolean
3112 match_summary_line(capture_file *cf, frame_data *fdata, void *criterion)
3113 {
3114   match_data            *mdata = criterion;
3115   const gchar           *string = mdata->string;
3116   size_t                string_len = mdata->string_len;
3117   epan_dissect_t        edt;
3118   const char            *info_column;
3119   size_t                info_column_len;
3120   gboolean              frame_matched = FALSE;
3121   gint                  colx;
3122   guint32               i;
3123   guint8                c_char;
3124   size_t                c_match = 0;
3125
3126   /* Don't bother constructing the protocol tree */
3127   epan_dissect_init(&edt, FALSE, FALSE);
3128   /* Get the column information */
3129   epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, &cf->cinfo);
3130
3131   /* Find the Info column */
3132   for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
3133     if (cf->cinfo.fmt_matx[colx][COL_INFO]) {
3134       /* Found it.  See if we match. */
3135       info_column = edt.pi.cinfo->col_data[colx];
3136       info_column_len = strlen(info_column);
3137       for (i = 0; i < info_column_len; i++) {
3138         c_char = info_column[i];
3139         if (cf->case_type)
3140           c_char = toupper(c_char);
3141         if (c_char == string[c_match]) {
3142           c_match++;
3143           if (c_match == string_len) {
3144             frame_matched = TRUE;
3145             break;
3146           }
3147         } else
3148           c_match = 0;
3149       }
3150       break;
3151     }
3152   }
3153   epan_dissect_cleanup(&edt);
3154   return frame_matched;
3155 }
3156
3157 typedef struct {
3158         const guint8 *data;
3159         size_t data_len;
3160 } cbs_t;        /* "Counted byte string" */
3161
3162 gboolean
3163 cf_find_packet_data(capture_file *cf, const guint8 *string, size_t string_size)
3164 {
3165   cbs_t info;
3166
3167   info.data = string;
3168   info.data_len = string_size;
3169
3170   /* String or hex search? */
3171   if (cf->string) {
3172     /* String search - what type of string? */
3173     switch (cf->scs_type) {
3174
3175     case SCS_ASCII_AND_UNICODE:
3176       return find_packet(cf, match_ascii_and_unicode, &info);
3177
3178     case SCS_ASCII:
3179       return find_packet(cf, match_ascii, &info);
3180
3181     case SCS_UNICODE:
3182       return find_packet(cf, match_unicode, &info);
3183
3184     default:
3185       g_assert_not_reached();
3186       return FALSE;
3187     }
3188   } else
3189     return find_packet(cf, match_binary, &info);
3190 }
3191
3192 static gboolean
3193 match_ascii_and_unicode(capture_file *cf, frame_data *fdata, void *criterion)
3194 {
3195   cbs_t         *info = criterion;
3196   const guint8  *ascii_text = info->data;
3197   size_t        textlen = info->data_len;
3198   gboolean      frame_matched;
3199   guint32       buf_len;
3200   guint32       i;
3201   guint8        c_char;
3202   size_t        c_match = 0;
3203
3204   frame_matched = FALSE;
3205   buf_len = fdata->pkt_len;
3206   for (i = 0; i < buf_len; i++) {
3207     c_char = cf->pd[i];
3208     if (cf->case_type)
3209       c_char = toupper(c_char);
3210     if (c_char != 0) {
3211       if (c_char == ascii_text[c_match]) {
3212         c_match++;
3213         if (c_match == textlen) {
3214           frame_matched = TRUE;
3215           cf->search_pos = i; /* Save the position of the last character
3216                                for highlighting the field. */
3217           break;
3218         }
3219       } else
3220         c_match = 0;
3221     }
3222   }
3223   return frame_matched;
3224 }
3225
3226 static gboolean
3227 match_ascii(capture_file *cf, frame_data *fdata, void *criterion)
3228 {
3229   cbs_t         *info = criterion;
3230   const guint8  *ascii_text = info->data;
3231   size_t        textlen = info->data_len;
3232   gboolean      frame_matched;
3233   guint32       buf_len;
3234   guint32       i;
3235   guint8        c_char;
3236   size_t        c_match = 0;
3237
3238   frame_matched = FALSE;
3239   buf_len = fdata->pkt_len;
3240   for (i = 0; i < buf_len; i++) {
3241     c_char = cf->pd[i];
3242     if (cf->case_type)
3243       c_char = toupper(c_char);
3244     if (c_char == ascii_text[c_match]) {
3245       c_match++;
3246       if (c_match == textlen) {
3247         frame_matched = TRUE;
3248         cf->search_pos = i; /* Save the position of the last character
3249                                for highlighting the field. */
3250         break;
3251       }
3252     } else
3253       c_match = 0;
3254   }
3255   return frame_matched;
3256 }
3257
3258 static gboolean
3259 match_unicode(capture_file *cf, frame_data *fdata, void *criterion)
3260 {
3261   cbs_t         *info = criterion;
3262   const guint8  *ascii_text = info->data;
3263   size_t        textlen = info->data_len;
3264   gboolean      frame_matched;
3265   guint32       buf_len;
3266   guint32       i;
3267   guint8        c_char;
3268   size_t        c_match = 0;
3269
3270   frame_matched = FALSE;
3271   buf_len = fdata->pkt_len;
3272   for (i = 0; i < buf_len; i++) {
3273     c_char = cf->pd[i];
3274     if (cf->case_type)
3275       c_char = toupper(c_char);
3276     if (c_char == ascii_text[c_match]) {
3277       c_match++;
3278       i++;
3279       if (c_match == textlen) {
3280         frame_matched = TRUE;
3281         cf->search_pos = i; /* Save the position of the last character
3282                                for highlighting the field. */
3283         break;
3284       }
3285     } else
3286       c_match = 0;
3287   }
3288   return frame_matched;
3289 }
3290
3291 static gboolean
3292 match_binary(capture_file *cf, frame_data *fdata, void *criterion)
3293 {
3294   cbs_t         *info = criterion;
3295   const guint8  *binary_data = info->data;
3296   size_t        datalen = info->data_len;
3297   gboolean      frame_matched;
3298   guint32       buf_len;
3299   guint32       i;
3300   size_t        c_match = 0;
3301
3302   frame_matched = FALSE;
3303   buf_len = fdata->pkt_len;
3304   for (i = 0; i < buf_len; i++) {
3305     if (cf->pd[i] == binary_data[c_match]) {
3306       c_match++;
3307       if (c_match == datalen) {
3308         frame_matched = TRUE;
3309         cf->search_pos = i; /* Save the position of the last character
3310                                for highlighting the field. */
3311         break;
3312       }
3313     } else
3314       c_match = 0;
3315   }
3316   return frame_matched;
3317 }
3318
3319 gboolean
3320 cf_find_packet_dfilter(capture_file *cf, dfilter_t *sfcode)
3321 {
3322   return find_packet(cf, match_dfilter, sfcode);
3323 }
3324
3325 static gboolean
3326 match_dfilter(capture_file *cf, frame_data *fdata, void *criterion)
3327 {
3328   dfilter_t             *sfcode = criterion;
3329   epan_dissect_t        edt;
3330   gboolean              frame_matched;
3331
3332   epan_dissect_init(&edt, TRUE, FALSE);
3333   epan_dissect_prime_dfilter(&edt, sfcode);
3334   epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, NULL);
3335   frame_matched = dfilter_apply_edt(sfcode, &edt);
3336   epan_dissect_cleanup(&edt);
3337   return frame_matched;
3338 }
3339
3340 static gboolean
3341 find_packet(capture_file *cf,
3342             gboolean (*match_function)(capture_file *, frame_data *, void *),
3343             void *criterion)
3344 {
3345   frame_data *start_fd;
3346   frame_data *fdata;
3347   frame_data *new_fd = NULL;
3348   progdlg_t  *progbar = NULL;
3349   gboolean    stop_flag;
3350   int         count;
3351   int         err;
3352   gchar      *err_info;
3353   int         row;
3354   float       progbar_val;
3355   GTimeVal    start_time;
3356   gchar       status_str[100];
3357   int         progbar_nextstep;
3358   int         progbar_quantum;
3359   char       *title;
3360
3361   start_fd = cf->current_frame;
3362   if (start_fd != NULL)  {
3363     /* Iterate through the list of packets, starting at the packet we've
3364        picked, calling a routine to run the filter on the packet, see if
3365        it matches, and stop if so.  */
3366     count = 0;
3367     fdata = start_fd;
3368
3369     /* Update the progress bar when it gets to this value. */
3370     progbar_nextstep = 0;
3371     /* When we reach the value that triggers a progress bar update,
3372        bump that value by this amount. */
3373     progbar_quantum = cf->count/N_PROGBAR_UPDATES;
3374     /* Progress so far. */
3375     progbar_val = 0.0f;
3376
3377     stop_flag = FALSE;
3378     g_get_current_time(&start_time);
3379
3380     fdata = start_fd;
3381     title = cf->sfilter?cf->sfilter:"";
3382     for (;;) {
3383       /* Create the progress bar if necessary.
3384          We check on every iteration of the loop, so that it takes no
3385          longer than the standard time to create it (otherwise, for a
3386          large file, we might take considerably longer than that standard
3387          time in order to get to the next progress bar step). */
3388       if (progbar == NULL)
3389          progbar = delayed_create_progress_dlg("Searching", title,
3390            FALSE, &stop_flag, &start_time, progbar_val);
3391
3392       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
3393          when we update it, we have to run the GTK+ main loop to get it
3394          to repaint what's pending, and doing so may involve an "ioctl()"
3395          to see if there's any pending input from an X server, and doing
3396          that for every packet can be costly, especially on a big file. */
3397       if (count >= progbar_nextstep) {
3398         /* let's not divide by zero. I should never be started
3399          * with count == 0, so let's assert that
3400          */
3401         g_assert(cf->count > 0);
3402
3403         progbar_val = (gfloat) count / cf->count;
3404
3405         if (progbar != NULL) {
3406           g_snprintf(status_str, sizeof(status_str),
3407                      "%4u of %u packets", count, cf->count);
3408           update_progress_dlg(progbar, progbar_val, status_str);
3409         }
3410
3411         progbar_nextstep += progbar_quantum;
3412       }
3413
3414       if (stop_flag) {
3415         /* Well, the user decided to abort the search.  Go back to the
3416            frame where we started. */
3417         new_fd = start_fd;
3418         break;
3419       }
3420
3421       /* Go past the current frame. */
3422       if (cf->sbackward) {
3423         /* Go on to the previous frame. */
3424         fdata = fdata->prev;
3425         if (fdata == NULL) {
3426           /*
3427            * XXX - other apps have a bit more of a detailed message
3428            * for this, and instead of offering "OK" and "Cancel",
3429            * they offer things such as "Continue" and "Cancel";
3430            * we need an API for popping up alert boxes with
3431            * {Verb} and "Cancel".
3432            */
3433
3434           if (prefs.gui_find_wrap)
3435           {
3436               simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3437                             "%sBeginning of capture exceeded!%s\n\n"
3438                             "Search is continued from the end of the capture.",
3439                             simple_dialog_primary_start(), simple_dialog_primary_end());
3440               fdata = cf->plist_end;    /* wrap around */
3441           }
3442           else
3443           {
3444               simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3445                             "%sBeginning of capture exceeded!%s\n\n"
3446                             "Try searching forwards.",
3447                             simple_dialog_primary_start(), simple_dialog_primary_end());
3448               fdata = start_fd;        /* stay on previous packet */
3449           }
3450         }
3451       } else {
3452         /* Go on to the next frame. */
3453         fdata = fdata->next;
3454         if (fdata == NULL) {
3455           if (prefs.gui_find_wrap)
3456           {
3457               simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3458                             "%sEnd of capture exceeded!%s\n\n"
3459                             "Search is continued from the start of the capture.",
3460                             simple_dialog_primary_start(), simple_dialog_primary_end());
3461               fdata = cf->plist;        /* wrap around */
3462           }
3463           else
3464           {
3465               simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3466                             "%sEnd of capture exceeded!%s\n\n"
3467                             "Try searching backwards.",
3468                             simple_dialog_primary_start(), simple_dialog_primary_end());
3469               fdata = start_fd;     /* stay on previous packet */
3470           }
3471         }
3472       }
3473
3474       count++;
3475
3476       /* Is this packet in the display? */
3477       if (fdata->flags.passed_dfilter) {
3478         /* Yes.  Load its data. */
3479         if (!wtap_seek_read(cf->wth, fdata->file_off, &cf->pseudo_header,
3480                         cf->pd, fdata->cap_len, &err, &err_info)) {
3481           /* Read error.  Report the error, and go back to the frame
3482              where we started. */
3483           simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3484                         cf_read_error_message(err, err_info), cf->filename);
3485           new_fd = start_fd;
3486           break;
3487         }
3488
3489         /* Does it match the search criterion? */
3490         if ((*match_function)(cf, fdata, criterion)) {
3491           new_fd = fdata;
3492           break;        /* found it! */
3493         }
3494       }
3495
3496       if (fdata == start_fd) {
3497         /* We're back to the frame we were on originally, and that frame
3498            doesn't match the search filter.  The search failed. */
3499         break;
3500       }
3501     }
3502
3503     /* We're done scanning the packets; destroy the progress bar if it
3504        was created. */
3505     if (progbar != NULL)
3506       destroy_progress_dlg(progbar);
3507   }
3508
3509   if (new_fd != NULL) {
3510 #ifdef NEW_PACKET_LIST
3511           /* Find and select */
3512           row = new_packet_list_find_row_from_data(fdata, TRUE);
3513 #else
3514     /* We found a frame.  Find what row it's in. */
3515     row = packet_list_find_row_from_data(new_fd);
3516 #endif /* NEW_PACKET_LIST */
3517     if (row == -1) {
3518         /* We didn't find a row even though we know that a frame
3519          * exists that satifies the search criteria. This means that the
3520          * frame isn't being displayed currently so we can't select it. */
3521         simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3522                       "%sEnd of capture exceeded!%s\n\n"
3523                       "The capture file is probably not fully loaded.",
3524                       simple_dialog_primary_start(), simple_dialog_primary_end());
3525         return FALSE;
3526     }
3527
3528 #ifndef NEW_PACKET_LIST
3529     /* Select that row, make it the focus row, and make it visible. */
3530     packet_list_set_selected_row(row);
3531 #endif /* NEW_PACKET_LIST */
3532     return TRUE;        /* success */
3533   } else
3534     return FALSE;       /* failure */
3535 }
3536
3537 gboolean
3538 cf_goto_frame(capture_file *cf, guint fnumber)
3539 {
3540   frame_data *fdata;
3541   int row;
3542
3543   for (fdata = cf->plist; fdata != NULL && fdata->num < fnumber; fdata = fdata->next)
3544     ;
3545
3546   if (fdata == NULL) {
3547     /* we didn't find a packet with that packet number */
3548     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3549                   "There is no packet with the packet number %u.", fnumber);
3550     return FALSE;       /* we failed to go to that packet */
3551   }
3552   if (!fdata->flags.passed_dfilter) {
3553     /* that packet currently isn't displayed */
3554     /* XXX - add it to the set of displayed packets? */
3555     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3556                   "The packet number %u isn't currently being displayed.", fnumber);
3557     return FALSE;       /* we failed to go to that packet */
3558   }
3559
3560 #ifdef NEW_PACKET_LIST
3561   row = new_packet_list_find_row_from_data(fdata, TRUE);
3562 #else
3563   /* We found that packet, and it's currently being displayed.
3564      Find what row it's in. */
3565   row = packet_list_find_row_from_data(fdata);
3566   g_assert(row != -1);
3567
3568   /* Select that row, make it the focus row, and make it visible. */
3569   packet_list_set_selected_row(row);
3570 #endif /* NEW_PACKET_LIST */
3571   return TRUE;  /* we got to that packet */
3572 }
3573
3574 gboolean
3575 cf_goto_top_frame(capture_file *cf _U_)
3576 {
3577 #ifdef NEW_PACKET_LIST
3578   /* Find and select */
3579   new_packet_list_select_first_row();
3580 #else
3581   frame_data *fdata;
3582   int row;
3583   frame_data *lowest_fdata = NULL;
3584
3585   for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
3586     if (fdata->flags.passed_dfilter) {
3587         lowest_fdata = fdata;
3588         break;
3589     }
3590   }
3591
3592   if (lowest_fdata == NULL) {
3593       return FALSE;
3594   }
3595
3596   /* We found that packet, and it's currently being displayed.
3597      Find what row it's in. */
3598   row = packet_list_find_row_from_data(lowest_fdata);
3599   g_assert(row != -1);
3600
3601   /* Select that row, make it the focus row, and make it visible. */
3602   packet_list_set_selected_row(row);
3603 #endif /* NEW_PACKET_LIST */
3604   return TRUE;  /* we got to that packet */
3605 }
3606
3607 gboolean
3608 cf_goto_bottom_frame(capture_file *cf _U_) /* cf is unused w/ NEW_PACKET_LIST */
3609 {
3610 #ifdef NEW_PACKET_LIST
3611   /* Find and select */
3612   new_packet_list_select_last_row();
3613 #else
3614   frame_data *fdata;
3615   int row;
3616   frame_data *highest_fdata = NULL;
3617
3618   for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
3619     if (fdata->flags.passed_dfilter) {
3620         highest_fdata = fdata;
3621     }
3622   }
3623
3624   if (highest_fdata == NULL) {
3625       return FALSE;
3626   }
3627
3628   /* We found that packet, and it's currently being displayed.
3629      Find what row it's in. */
3630   row = packet_list_find_row_from_data(highest_fdata);
3631   g_assert(row != -1);
3632
3633   /* Select that row, make it the focus row, and make it visible. */
3634   packet_list_set_selected_row(row);
3635 #endif /* NEW_PACKET_LIST */
3636   return TRUE;  /* we got to that packet */
3637 }
3638
3639 /*
3640  * Go to frame specified by currently selected protocol tree item.
3641  */
3642 gboolean
3643 cf_goto_framenum(capture_file *cf)
3644 {
3645   header_field_info       *hfinfo;
3646   guint32                 framenum;
3647
3648   if (cf->finfo_selected) {
3649     hfinfo = cf->finfo_selected->hfinfo;
3650     g_assert(hfinfo);
3651     if (hfinfo->type == FT_FRAMENUM) {
3652       framenum = fvalue_get_uinteger(&cf->finfo_selected->value);
3653       if (framenum != 0)
3654         return cf_goto_frame(cf, framenum);
3655       }
3656   }
3657
3658   return FALSE;
3659 }
3660
3661 /* Select the packet on a given row. */
3662 void
3663 cf_select_packet(capture_file *cf, int row)
3664 {
3665   frame_data *fdata;
3666   int err;
3667   gchar *err_info;
3668
3669   /* Get the frame data struct pointer for this frame */
3670 #ifdef NEW_PACKET_LIST
3671   fdata = new_packet_list_get_row_data(row);
3672 #else
3673   fdata = (frame_data *)packet_list_get_row_data(row);
3674 #endif
3675
3676   if (fdata == NULL) {
3677     /* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
3678        the first entry is added to it by "real_insert_row()", that row
3679        is selected (see "real_insert_row()", in "gtk/gtkclist.c", in both
3680        our version and the vanilla GTK+ version).
3681
3682        This means that a "select-row" signal is emitted; this causes
3683        "packet_list_select_cb()" to be called, which causes "cf_select_packet()"
3684        to be called.
3685
3686        "cf_select_packet()" fetches, above, the data associated with the
3687        row that was selected; however, as "gtk_clist_append()", which
3688        called "real_insert_row()", hasn't yet returned, we haven't yet
3689        associated any data with that row, so we get back a null pointer.
3690
3691        We can't assume that there's only one frame in the frame list,
3692        either, as we may be filtering the display.
3693
3694        We therefore assume that, if "row" is 0, i.e. the first row
3695        is being selected, and "cf->first_displayed" equals
3696        "cf->last_displayed", i.e. there's only one frame being
3697        displayed, that frame is the frame we want.
3698
3699        This means we have to set "cf->first_displayed" and
3700        "cf->last_displayed" before adding the row to the
3701        GtkCList; see the comment in "add_packet_to_packet_list()". */
3702
3703        if (row == 0 && cf->first_displayed == cf->last_displayed)
3704          fdata = cf->first_displayed;
3705   }
3706
3707   /* If fdata _still_ isn't set simply give up. */
3708   if (fdata == NULL) {
3709     return;
3710   }
3711
3712   /* Get the data in that frame. */
3713   if (!wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
3714                        cf->pd, fdata->cap_len, &err, &err_info)) {
3715     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3716                   cf_read_error_message(err, err_info), cf->filename);
3717     return;
3718   }
3719
3720   /* Record that this frame is the current frame. */
3721   cf->current_frame = fdata;
3722   cf->current_row = row;
3723
3724   /* Create the logical protocol tree. */
3725   if (cf->edt != NULL)
3726     epan_dissect_free(cf->edt);
3727
3728   /* We don't need the columns here. */
3729   cf->edt = epan_dissect_new(TRUE, TRUE);
3730
3731   epan_dissect_run(cf->edt, &cf->pseudo_header, cf->pd, cf->current_frame,
3732           NULL);
3733
3734   dfilter_macro_build_ftv_cache(cf->edt->tree);
3735
3736   cf_callback_invoke(cf_cb_packet_selected, cf);
3737 }
3738
3739 /* Unselect the selected packet, if any. */
3740 void
3741 cf_unselect_packet(capture_file *cf)
3742 {
3743   /* Destroy the epan_dissect_t for the unselected packet. */
3744   if (cf->edt != NULL) {
3745     epan_dissect_free(cf->edt);
3746     cf->edt = NULL;
3747   }
3748
3749   /* No packet is selected. */
3750   cf->current_frame = NULL;
3751   cf->current_row = 0;
3752
3753   cf_callback_invoke(cf_cb_packet_unselected, cf);
3754
3755   /* No protocol tree means no selected field. */
3756   cf_unselect_field(cf);
3757 }
3758
3759 /* Unset the selected protocol tree field, if any. */
3760 void
3761 cf_unselect_field(capture_file *cf)
3762 {
3763   cf->finfo_selected = NULL;
3764
3765   cf_callback_invoke(cf_cb_field_unselected, cf);
3766 }
3767
3768 /*
3769  * Mark a particular frame.
3770  */
3771 void
3772 cf_mark_frame(capture_file *cf, frame_data *frame)
3773 {
3774   if (! frame->flags.marked) {
3775     frame->flags.marked = TRUE;
3776     if (cf->count > cf->marked_count)
3777       cf->marked_count++;
3778   }
3779 }
3780
3781 /*
3782  * Unmark a particular frame.
3783  */
3784 void
3785 cf_unmark_frame(capture_file *cf, frame_data *frame)
3786 {
3787   if (frame->flags.marked) {
3788     frame->flags.marked = FALSE;
3789     if (cf->marked_count > 0)
3790       cf->marked_count--;
3791   }
3792 }
3793
3794 typedef struct {
3795   wtap_dumper *pdh;
3796   const char  *fname;
3797 } save_callback_args_t;
3798
3799 /*
3800  * Save a capture to a file, in a particular format, saving either
3801  * all packets, all currently-displayed packets, or all marked packets.
3802  *
3803  * Returns TRUE if it succeeds, FALSE otherwise; if it fails, it pops
3804  * up a message box for the failure.
3805  */
3806 static gboolean
3807 save_packet(capture_file *cf _U_, frame_data *fdata,
3808             union wtap_pseudo_header *pseudo_header, const guint8 *pd,
3809             void *argsp)
3810 {
3811   save_callback_args_t *args = argsp;
3812   struct wtap_pkthdr hdr;
3813   int           err;
3814
3815   /* init the wtap header for saving */
3816   hdr.ts.secs    = fdata->abs_ts.secs;
3817   hdr.ts.nsecs   = fdata->abs_ts.nsecs;
3818   hdr.caplen     = fdata->cap_len;
3819   hdr.len        = fdata->pkt_len;
3820   hdr.pkt_encap  = fdata->lnk_t;
3821
3822   /* and save the packet */
3823   if (!wtap_dump(args->pdh, &hdr, pseudo_header, pd, &err)) {
3824     cf_write_failure_alert_box(args->fname, err);
3825     return FALSE;
3826   }
3827   return TRUE;
3828 }
3829
3830 /*
3831  * Can this capture file be saved in any format except by copying the raw data?
3832  */
3833 gboolean
3834 cf_can_save_as(capture_file *cf)
3835 {
3836   int ft;
3837
3838   for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
3839     /* To save a file with Wiretap, Wiretap has to handle that format,
3840        and its code to handle that format must be able to write a file
3841        with this file's encapsulation type. */
3842     if (wtap_dump_can_open(ft) && wtap_dump_can_write_encap(ft, cf->lnk_t)) {
3843       /* OK, we can write it out in this type. */
3844       return TRUE;
3845     }
3846   }
3847
3848   /* No, we couldn't save it in any format. */
3849   return FALSE;
3850 }
3851
3852 cf_status_t
3853 cf_save(capture_file *cf, const char *fname, packet_range_t *range, guint save_format, gboolean compressed)
3854 {
3855   gchar        *from_filename;
3856   int           err;
3857   gboolean      do_copy;
3858   wtap_dumper  *pdh;
3859   save_callback_args_t callback_args;
3860
3861   cf_callback_invoke(cf_cb_file_safe_started, (gpointer) fname);
3862
3863   /* don't write over an existing file. */
3864   /* this should've been already checked by our caller, just to be sure... */
3865   if (file_exists(fname)) {
3866     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3867       "%sCapture file: \"%s\" already exists!%s\n\n"
3868       "Please choose a different filename.",
3869       simple_dialog_primary_start(), fname, simple_dialog_primary_end());
3870     goto fail;
3871   }
3872
3873   packet_range_process_init(range);
3874
3875
3876   if (packet_range_process_all(range) && save_format == cf->cd_t) {
3877     /* We're not filtering packets, and we're saving it in the format
3878        it's already in, so we can just move or copy the raw data. */
3879
3880     if (cf->is_tempfile) {
3881       /* The file being saved is a temporary file from a live
3882          capture, so it doesn't need to stay around under that name;
3883          first, try renaming the capture buffer file to the new name. */
3884 #ifndef _WIN32
3885       if (ws_rename(cf->filename, fname) == 0) {
3886         /* That succeeded - there's no need to copy the source file. */
3887         from_filename = NULL;
3888         do_copy = FALSE;
3889       } else {
3890         if (errno == EXDEV) {
3891           /* They're on different file systems, so we have to copy the
3892              file. */
3893           do_copy = TRUE;
3894           from_filename = cf->filename;
3895         } else {
3896           /* The rename failed, but not because they're on different
3897              file systems - put up an error message.  (Or should we
3898              just punt and try to copy?  The only reason why I'd
3899              expect the rename to fail and the copy to succeed would
3900              be if we didn't have permission to remove the file from
3901              the temporary directory, and that might be fixable - but
3902              is it worth requiring the user to go off and fix it?) */
3903           simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3904                                 file_rename_error_message(errno), fname);
3905           goto fail;
3906         }
3907       }
3908 #else
3909       do_copy = TRUE;
3910       from_filename = cf->filename;
3911 #endif
3912     } else {
3913       /* It's a permanent file, so we should copy it, and not remove the
3914          original. */
3915       do_copy = TRUE;
3916       from_filename = cf->filename;
3917     }
3918
3919     if (do_copy) {
3920       /* Copy the file, if we haven't moved it. */
3921       if (!copy_file_binary_mode(from_filename, fname))
3922         goto fail;
3923     }
3924   } else {
3925     /* Either we're filtering packets, or we're saving in a different
3926        format; we can't do that by copying or moving the capture file,
3927        we have to do it by writing the packets out in Wiretap. */
3928     pdh = wtap_dump_open(fname, save_format, cf->lnk_t, cf->snap,
3929                 compressed, &err);
3930     if (pdh == NULL) {
3931       cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
3932       goto fail;
3933     }
3934
3935     /* XXX - we let the user save a subset of the packets.
3936
3937        If we do that, should we make that file the current file?  If so,
3938        it means we can no longer get at the other packets.  What does
3939        NetMon do? */
3940
3941     /* Iterate through the list of packets, processing the packets we were
3942        told to process.
3943
3944        XXX - we've already called "packet_range_process_init(range)", but
3945        "process_specified_packets()" will do it again.  Fortunately,
3946        that's harmless in this case, as we haven't done anything to
3947        "range" since we initialized it. */
3948     callback_args.pdh = pdh;
3949     callback_args.fname = fname;
3950     switch (process_specified_packets(cf, range, "Saving", "selected packets",
3951                                       TRUE, save_packet, &callback_args)) {
3952
3953     case PSP_FINISHED:
3954       /* Completed successfully. */
3955       break;
3956
3957     case PSP_STOPPED:
3958       /* The user decided to abort the saving.
3959          XXX - remove the output file? */
3960       break;
3961
3962     case PSP_FAILED:
3963       /* Error while saving. */
3964       wtap_dump_close(pdh, &err);
3965       goto fail;
3966     }
3967
3968     if (!wtap_dump_close(pdh, &err)) {
3969       cf_close_failure_alert_box(fname, err);
3970       goto fail;
3971     }
3972   }
3973
3974   cf_callback_invoke(cf_cb_file_safe_finished, NULL);
3975
3976   if (packet_range_process_all(range)) {
3977     /* We saved the entire capture, not just some packets from it.
3978        Open and read the file we saved it to.
3979
3980        XXX - this is somewhat of a waste; we already have the
3981        packets, all this gets us is updated file type information
3982        (which we could just stuff into "cf"), and having the new
3983        file be the one we have opened and from which we're reading
3984        the data, and it means we have to spend time opening and
3985        reading the file, which could be a significant amount of
3986        time if the file is large. */
3987     cf->user_saved = TRUE;
3988
3989     if ((cf_open(cf, fname, FALSE, &err)) == CF_OK) {
3990       /* XXX - report errors if this fails?
3991          What should we return if it fails or is aborted? */
3992       switch (cf_read(cf)) {
3993
3994       case CF_READ_OK:
3995       case CF_READ_ERROR:
3996         /* Just because we got an error, that doesn't mean we were unable
3997            to read any of the file; we handle what we could get from the
3998            file. */
3999         break;
4000
4001       case CF_READ_ABORTED:
4002         /* The user bailed out of re-reading the capture file; the
4003            capture file has been closed - just return (without
4004            changing any menu settings; "cf_close()" set them
4005            correctly for the "no capture file open" state). */
4006         break;
4007       }
4008       cf_callback_invoke(cf_cb_file_safe_reload_finished, NULL);
4009     }
4010   }
4011   return CF_OK;
4012
4013 fail:
4014   cf_callback_invoke(cf_cb_file_safe_failed, NULL);
4015   return CF_ERROR;
4016 }
4017
4018 static void
4019 cf_open_failure_alert_box(const char *filename, int err, gchar *err_info,
4020                           gboolean for_writing, int file_type)
4021 {
4022   if (err < 0) {
4023     /* Wiretap error. */
4024     switch (err) {
4025
4026     case WTAP_ERR_NOT_REGULAR_FILE:
4027       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4028                     "The file \"%s\" is a \"special file\" or socket or other non-regular file.",
4029                     filename);
4030       break;
4031
4032     case WTAP_ERR_RANDOM_OPEN_PIPE:
4033       /* Seen only when opening a capture file for reading. */
4034       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4035                     "The file \"%s\" is a pipe or FIFO; Wireshark can't read pipe or FIFO files.",
4036                     filename);
4037       break;
4038
4039     case WTAP_ERR_FILE_UNKNOWN_FORMAT:
4040       /* Seen only when opening a capture file for reading. */
4041       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4042                     "The file \"%s\" isn't a capture file in a format Wireshark understands.",
4043                     filename);
4044       break;
4045
4046     case WTAP_ERR_UNSUPPORTED:
4047       /* Seen only when opening a capture file for reading. */
4048       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4049                     "The file \"%s\" isn't a capture file in a format Wireshark understands.\n"
4050                     "(%s)",
4051                     filename, err_info);
4052       g_free(err_info);
4053       break;
4054
4055     case WTAP_ERR_CANT_WRITE_TO_PIPE:
4056       /* Seen only when opening a capture file for writing. */
4057       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4058                     "The file \"%s\" is a pipe, and %s capture files can't be "
4059                     "written to a pipe.",
4060                     filename, wtap_file_type_string(file_type));
4061       break;
4062
4063     case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
4064       /* Seen only when opening a capture file for writing. */
4065       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4066                     "Wireshark doesn't support writing capture files in that format.");
4067       break;
4068
4069     case WTAP_ERR_UNSUPPORTED_ENCAP:
4070       if (for_writing) {
4071         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4072                       "Wireshark can't save this capture in that format.");
4073       } else {
4074         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4075                       "The file \"%s\" is a capture for a network type that Wireshark doesn't support.\n"
4076                       "(%s)",
4077                       filename, err_info);
4078         g_free(err_info);
4079       }
4080       break;
4081
4082     case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
4083       if (for_writing) {
4084         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4085                       "Wireshark can't save this capture in that format.");
4086       } else {
4087         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4088                       "The file \"%s\" is a capture for a network type that Wireshark doesn't support.",
4089                       filename);
4090       }
4091       break;
4092
4093     case WTAP_ERR_BAD_RECORD:
4094       /* Seen only when opening a capture file for reading. */
4095       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4096                     "The file \"%s\" appears to be damaged or corrupt.\n"
4097                     "(%s)",
4098                     filename, err_info);
4099       g_free(err_info);
4100       break;
4101
4102     case WTAP_ERR_CANT_OPEN:
4103       if (for_writing) {
4104         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4105                       "The file \"%s\" could not be created for some unknown reason.",
4106                       filename);
4107       } else {
4108         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4109                       "The file \"%s\" could not be opened for some unknown reason.",
4110                       filename);
4111       }
4112       break;
4113
4114     case WTAP_ERR_SHORT_READ:
4115       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4116                     "The file \"%s\" appears to have been cut short"
4117                     " in the middle of a packet or other data.",
4118                     filename);
4119       break;
4120
4121     case WTAP_ERR_SHORT_WRITE:
4122       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4123                     "A full header couldn't be written to the file \"%s\".",
4124                     filename);
4125       break;
4126
4127     case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
4128       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4129                     "Gzip compression not supported by this file type.");
4130       break;
4131
4132     default:
4133       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4134                     "The file \"%s\" could not be %s: %s.",
4135                     filename,
4136                     for_writing ? "created" : "opened",
4137                     wtap_strerror(err));
4138       break;
4139     }
4140   } else {
4141     /* OS error. */
4142     open_failure_alert_box(filename, err, for_writing);
4143   }
4144 }
4145
4146 static const char *
4147 file_rename_error_message(int err)
4148 {
4149   const char *errmsg;
4150   static char errmsg_errno[1024+1];
4151
4152   switch (err) {
4153
4154   case ENOENT:
4155     errmsg = "The path to the file \"%s\" doesn't exist.";
4156     break;
4157
4158   case EACCES:
4159     errmsg = "You don't have permission to move the capture file to \"%s\".";
4160     break;
4161
4162   default:
4163     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
4164                     "The file \"%%s\" could not be moved: %s.",
4165                                 wtap_strerror(err));
4166     errmsg = errmsg_errno;
4167     break;
4168   }
4169   return errmsg;
4170 }
4171
4172 char *
4173 cf_read_error_message(int err, gchar *err_info)
4174 {
4175   static char errmsg_errno[1024+1];
4176
4177   switch (err) {
4178
4179   case WTAP_ERR_UNSUPPORTED_ENCAP:
4180     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
4181                "The file \"%%s\" has a packet with a network type that Wireshark doesn't support.\n(%s)",
4182                err_info);
4183     g_free(err_info);
4184     break;
4185
4186   case WTAP_ERR_BAD_RECORD:
4187     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
4188              "An error occurred while reading from the file \"%%s\": %s.\n(%s)",
4189              wtap_strerror(err), err_info);
4190     g_free(err_info);
4191     break;
4192
4193   default:
4194     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
4195              "An error occurred while reading from the file \"%%s\": %s.",
4196              wtap_strerror(err));
4197     break;
4198   }
4199   return errmsg_errno;
4200 }
4201
4202 static void
4203 cf_write_failure_alert_box(const char *filename, int err)
4204 {
4205   if (err < 0) {
4206     /* Wiretap error. */
4207     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4208                   "An error occurred while writing to the file \"%s\": %s.",
4209                   filename, wtap_strerror(err));
4210   } else {
4211     /* OS error. */
4212     write_failure_alert_box(filename, err);
4213   }
4214 }
4215
4216 /* Check for write errors - if the file is being written to an NFS server,
4217    a write error may not show up until the file is closed, as NFS clients
4218    might not send writes to the server until the "write()" call finishes,
4219    so that the write may fail on the server but the "write()" may succeed. */
4220 static void
4221 cf_close_failure_alert_box(const char *filename, int err)
4222 {
4223   if (err < 0) {
4224     /* Wiretap error. */
4225     switch (err) {
4226
4227     case WTAP_ERR_CANT_CLOSE:
4228       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4229                     "The file \"%s\" couldn't be closed for some unknown reason.",
4230                     filename);
4231       break;
4232
4233     case WTAP_ERR_SHORT_WRITE:
4234       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4235                     "Not all the packets could be written to the file \"%s\".",
4236                     filename);
4237       break;
4238
4239     default:
4240       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4241                     "An error occurred while closing the file \"%s\": %s.",
4242                     filename, wtap_strerror(err));
4243       break;
4244     }
4245   } else {
4246     /* OS error.
4247        We assume that a close error from the OS is really a write error. */
4248     write_failure_alert_box(filename, err);
4249   }
4250 }
4251
4252 /* Reload the current capture file. */
4253 void
4254 cf_reload(capture_file *cf) {
4255   gchar *filename;
4256   gboolean is_tempfile;
4257   int err;
4258
4259   /* If the file could be opened, "cf_open()" calls "cf_close()"
4260      to get rid of state for the old capture file before filling in state
4261      for the new capture file.  "cf_close()" will remove the file if
4262      it's a temporary file; we don't want that to happen (for one thing,
4263      it'd prevent subsequent reopens from working).  Remember whether it's
4264      a temporary file, mark it as not being a temporary file, and then
4265      reopen it as the type of file it was.
4266
4267      Also, "cf_close()" will free "cf->filename", so we must make
4268      a copy of it first. */
4269   filename = g_strdup(cf->filename);
4270   is_tempfile = cf->is_tempfile;
4271   cf->is_tempfile = FALSE;
4272   if (cf_open(cf, filename, is_tempfile, &err) == CF_OK) {
4273     switch (cf_read(cf)) {
4274
4275     case CF_READ_OK:
4276     case CF_READ_ERROR:
4277       /* Just because we got an error, that doesn't mean we were unable
4278          to read any of the file; we handle what we could get from the
4279          file. */
4280       break;
4281
4282     case CF_READ_ABORTED:
4283       /* The user bailed out of re-reading the capture file; the
4284          capture file has been closed - just free the capture file name
4285          string and return (without changing the last containing
4286          directory). */
4287       g_free(filename);
4288       return;
4289     }
4290   } else {
4291     /* The open failed, so "cf->is_tempfile" wasn't set to "is_tempfile".
4292        Instead, the file was left open, so we should restore "cf->is_tempfile"
4293        ourselves.
4294
4295        XXX - change the menu?  Presumably "cf_open()" will do that;
4296        make sure it does! */
4297     cf->is_tempfile = is_tempfile;
4298   }
4299   /* "cf_open()" made a copy of the file name we handed it, so
4300      we should free up our copy. */
4301   g_free(filename);
4302 }