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