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