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