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