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