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