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