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