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