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