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