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