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