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