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