From: Ravi Kondamuru:
[obnox/wireshark/wip.git] / file.c
1 /* file.c
2  * File I/O routines
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #ifdef HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32
33 #include <time.h>
34
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <ctype.h>
39 #include <errno.h>
40 #include <signal.h>
41
42 #ifdef HAVE_FCNTL_H
43 #include <fcntl.h>
44 #endif
45
46 #include <epan/epan.h>
47 #include <epan/filesystem.h>
48
49 #include "color.h"
50 #include "color_filters.h"
51 #include "cfile.h"
52 #include <epan/column.h>
53 #include <epan/packet.h>
54 #include <epan/column-utils.h>
55 #include "packet-range.h"
56 #include "print.h"
57 #include "file.h"
58 #include "fileset.h"
59 #include "tempfile.h"
60 #include "merge.h"
61 #include "alert_box.h"
62 #include "simple_dialog.h"
63 #include "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     /* Set to invalid to force update of packet list and packet details */
1979     cf->current_row = -1;
1980     if (selected_frame_num == 0) {
1981       new_packet_list_select_first_row();
1982     }else{
1983       new_packet_list_find_row_from_data(selected_frame, TRUE);
1984     }
1985   }
1986
1987   /* Cleanup and release all dfilter resources */
1988   dfilter_free(dfcode);
1989 }
1990
1991 #else
1992
1993 static void
1994 rescan_packets(capture_file *cf, const char *action, const char *action_item,
1995         gboolean refilter, gboolean redissect)
1996 {
1997   frame_data *fdata;
1998   progdlg_t  *progbar = NULL;
1999   gboolean    stop_flag;
2000   int         count;
2001   int         err;
2002   gchar      *err_info;
2003   frame_data *selected_frame, *preceding_frame, *following_frame, *prev_frame;
2004   int         selected_row, prev_row, preceding_row, following_row;
2005   gboolean    selected_frame_seen;
2006   int         row;
2007   float       progbar_val;
2008   GTimeVal    start_time;
2009   gchar       status_str[100];
2010   int         progbar_nextstep;
2011   int         progbar_quantum;
2012   dfilter_t   *dfcode;
2013   gboolean    filtering_tap_listeners;
2014   guint       tap_flags;
2015   gboolean    add_to_packet_list = TRUE;
2016   gboolean compiled;
2017
2018   /* Compile the current display filter.
2019    * We assume this will not fail since cf->dfilter is only set in
2020    * cf_filter IFF the filter was valid.
2021    */
2022   compiled = dfilter_compile(cf->dfilter, &dfcode);
2023   g_assert(!cf->dfilter || (compiled && dfcode));
2024
2025   /* Do we have any tap listeners with filters? */
2026   filtering_tap_listeners = have_filtering_tap_listeners();
2027
2028   /* Get the union of the flags for all tap listeners. */
2029   tap_flags = union_of_tap_listener_flags();
2030
2031   reset_tap_listeners();
2032   /* Which frame, if any, is the currently selected frame?
2033      XXX - should the selected frame or the focus frame be the "current"
2034      frame, that frame being the one from which "Find Frame" searches
2035      start? */
2036   selected_frame = cf->current_frame;
2037
2038   /* We don't yet know what row that frame will be on, if any, after we
2039      rebuild the clist, however. */
2040   selected_row = -1;
2041
2042   /* Freeze the packet list while we redo it, so we don't get any
2043      screen updates while it happens. */
2044   packet_list_freeze();
2045
2046   /* Clear it out. */
2047   packet_list_clear();
2048
2049   if (redissect) {
2050     /* We need to re-initialize all the state information that protocols
2051        keep, because some preference that controls a dissector has changed,
2052        which might cause the state information to be constructed differently
2053        by that dissector. */
2054
2055     /* We might receive new packets while redissecting, and we don't
2056        want to dissect those before their time. */
2057     cf->redissecting = TRUE;
2058
2059     /* Cleanup all data structures used for dissection. */
2060     cleanup_dissection();
2061     /* Initialize all data structures used for dissection. */
2062     init_dissection();
2063
2064   }
2065
2066   /* We don't yet know which will be the first and last frames displayed. */
2067   cf->first_displayed = NULL;
2068   cf->last_displayed = NULL;
2069
2070   reset_elapsed();
2071
2072   /* We currently don't display any packets */
2073   cf->displayed_count = 0;
2074
2075   /* Iterate through the list of frames.  Call a routine for each frame
2076      to check whether it should be displayed and, if so, add it to
2077      the display list. */
2078   nstime_set_unset(&first_ts);
2079   nstime_set_unset(&prev_dis_ts);
2080   nstime_set_unset(&prev_cap_ts);
2081   cum_bytes = 0;
2082
2083   /* Update the progress bar when it gets to this value. */
2084   progbar_nextstep = 0;
2085   /* When we reach the value that triggers a progress bar update,
2086      bump that value by this amount. */
2087   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
2088   /* Count of packets at which we've looked. */
2089   count = 0;
2090   /* Progress so far. */
2091   progbar_val = 0.0f;
2092
2093   stop_flag = FALSE;
2094   g_get_current_time(&start_time);
2095
2096   row = -1;     /* no previous row yet */
2097   prev_row = -1;
2098   prev_frame = NULL;
2099
2100   preceding_row = -1;
2101   preceding_frame = NULL;
2102   following_row = -1;
2103   following_frame = NULL;
2104
2105   selected_frame_seen = FALSE;
2106
2107   for (fdata = cf->plist_start; fdata != NULL; fdata = fdata->next) {
2108     /* Create the progress bar if necessary.
2109        We check on every iteration of the loop, so that it takes no
2110        longer than the standard time to create it (otherwise, for a
2111        large file, we might take considerably longer than that standard
2112        time in order to get to the next progress bar step). */
2113     if (progbar == NULL)
2114       progbar = delayed_create_progress_dlg(action, action_item, TRUE,
2115                                             &stop_flag, &start_time,
2116                                             progbar_val);
2117
2118     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
2119        when we update it, we have to run the GTK+ main loop to get it
2120        to repaint what's pending, and doing so may involve an "ioctl()"
2121        to see if there's any pending input from an X server, and doing
2122        that for every packet can be costly, especially on a big file. */
2123     if (count >= progbar_nextstep) {
2124       /* let's not divide by zero. I should never be started
2125        * with count == 0, so let's assert that
2126        */
2127       g_assert(cf->count > 0);
2128       progbar_val = (gfloat) count / cf->count;
2129
2130       if (progbar != NULL) {
2131         g_snprintf(status_str, sizeof(status_str),
2132                   "%4u of %u frames", count, cf->count);
2133         update_progress_dlg(progbar, progbar_val, status_str);
2134       }
2135
2136       progbar_nextstep += progbar_quantum;
2137     }
2138
2139     if (stop_flag) {
2140       /* Well, the user decided to abort the filtering.  Just stop.
2141
2142          XXX - go back to the previous filter?  Users probably just
2143      want not to wait for a filtering operation to finish;
2144      unless we cancel by having no filter, reverting to the
2145      previous filter will probably be even more expensive than
2146      continuing the filtering, as it involves going back to the
2147      beginning and filtering, and even with no filter we currently
2148      have to re-generate the entire clist, which is also expensive.
2149
2150      I'm not sure what Network Monitor does, but it doesn't appear
2151      to give you an unfiltered display if you cancel. */
2152       break;
2153     }
2154
2155     count++;
2156
2157     if (redissect) {
2158       /* Since all state for the frame was destroyed, mark the frame
2159        * as not visited, free the GSList referring to the state
2160        * data (the per-frame data itself was freed by
2161        * "init_dissection()"), and null out the GSList pointer.
2162        */
2163       fdata->flags.visited = 0;
2164       frame_data_cleanup(fdata);
2165     }
2166
2167     if (!wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
2168         cf->pd, fdata->cap_len, &err, &err_info)) {
2169             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2170             cf_read_error_message(err, err_info), cf->filename);
2171             break;
2172     }
2173
2174     /* If the previous frame is displayed, and we haven't yet seen the
2175        selected frame, remember that frame - it's the closest one we've
2176        yet seen before the selected frame. */
2177     if (prev_row != -1 && !selected_frame_seen) {
2178       preceding_row = prev_row;
2179       preceding_frame = prev_frame;
2180     }
2181     row = add_packet_to_packet_list(fdata, cf, dfcode, filtering_tap_listeners,
2182                                     tap_flags, &cf->pseudo_header, cf->pd,
2183                                     refilter,
2184                                     add_to_packet_list);
2185
2186     /* If this frame is displayed, and this is the first frame we've
2187        seen displayed after the selected frame, remember this frame -
2188        it's the closest one we've yet seen at or after the selected
2189        frame. */
2190     if (row != -1 && selected_frame_seen && following_row == -1) {
2191       following_row = row;
2192       following_frame = fdata;
2193     }
2194     if (fdata == selected_frame) {
2195       selected_row = row;
2196       selected_frame_seen = TRUE;
2197     }
2198
2199     /* Remember this row/frame - it'll be the previous row/frame
2200        on the next pass through the loop. */
2201     prev_row = row;
2202     prev_frame = fdata;
2203   }
2204
2205   /* We are done redissecting the packet list. */
2206   cf->redissecting = FALSE;
2207
2208   if (redissect) {
2209     /* Clear out what remains of the visited flags and per-frame data
2210        pointers.
2211
2212        XXX - that may cause various forms of bogosity when dissecting
2213        these frames, as they won't have been seen by this sequential
2214        pass, but the only alternative I see is to keep scanning them
2215        even though the user requested that the scan stop, and that
2216        would leave the user stuck with an Wireshark grinding on
2217        until it finishes.  Should we just stick them with that? */
2218     for (; fdata != NULL; fdata = fdata->next) {
2219       fdata->flags.visited = 0;
2220       frame_data_cleanup(fdata);
2221     }
2222   }
2223
2224   /* We're done filtering the packets; destroy the progress bar if it
2225      was created. */
2226   if (progbar != NULL)
2227     destroy_progress_dlg(progbar);
2228
2229   /* Unfreeze the packet list. */
2230   packet_list_thaw();
2231
2232   if (selected_row == -1) {
2233     /* The selected frame didn't pass the filter. */
2234     if (selected_frame == NULL) {
2235       /* That's because there *was* no selected frame.  Make the first
2236          displayed frame the current frame. */
2237       selected_row = 0;
2238     } else {
2239       /* Find the nearest displayed frame to the selected frame (whether
2240          it's before or after that frame) and make that the current frame.
2241          If the next and previous displayed frames are equidistant from the
2242          selected frame, choose the next one. */
2243       g_assert(following_frame == NULL ||
2244                following_frame->num >= selected_frame->num);
2245       g_assert(preceding_frame == NULL ||
2246                preceding_frame->num <= selected_frame->num);
2247       if (following_frame == NULL) {
2248         /* No frame after the selected frame passed the filter, so we
2249            have to select the last displayed frame before the selected
2250            frame. */
2251         selected_row = preceding_row;
2252       } else if (preceding_frame == NULL) {
2253         /* No frame before the selected frame passed the filter, so we
2254            have to select the first displayed frame after the selected
2255            frame. */
2256         selected_row = following_row;
2257       } else {
2258         /* Frames before and after the selected frame passed the filter, so
2259            we'll select the previous frame */
2260         selected_row = preceding_row;
2261       }
2262     }
2263   }
2264
2265   if (selected_row == -1) {
2266     /* There are no frames displayed at all. */
2267     cf_unselect_packet(cf);
2268   } else {
2269     /* Either the frame that was selected passed the filter, or we've
2270        found the nearest displayed frame to that frame.  Select it, make
2271        it the focus row, and make it visible. */
2272     if (selected_row == 0) {
2273       /* Set to invalid to force update of packet list and packet details */
2274       cf->current_row = -1;
2275     }
2276     packet_list_set_selected_row(selected_row);
2277   }
2278
2279   /* Cleanup and release all dfilter resources */
2280   dfilter_free(dfcode);
2281 }
2282 #endif /* NEW_PACKET_LIST */
2283
2284 /*
2285  * Scan trough all frame data and recalculate the ref time
2286  * without rereading the file.
2287  * XXX - do we need a progres bar or is this fast enough?
2288  */
2289 #ifdef NEW_PACKET_LIST
2290 static void
2291 ref_time_packets(capture_file *cf)
2292 {
2293   frame_data *fdata;
2294
2295   nstime_set_unset(&first_ts);
2296   nstime_set_unset(&prev_dis_ts);
2297   nstime_set_unset(&prev_cap_ts);
2298   cum_bytes = 0;
2299
2300   for (fdata = cf->plist_start; fdata != NULL; fdata = fdata->next) {
2301     /* just add some value here until we know if it is being displayed or not */
2302     fdata->cum_bytes = cum_bytes + fdata->pkt_len;
2303
2304     /* If we don't have the time stamp of the first packet in the
2305      capture, it's because this is the first packet.  Save the time
2306      stamp of this packet as the time stamp of the first packet. */
2307     if (nstime_is_unset(&first_ts)) {
2308         first_ts  = fdata->abs_ts;
2309     }
2310       /* if this frames is marked as a reference time frame, reset
2311         firstsec and firstusec to this frame */
2312     if(fdata->flags.ref_time){
2313     first_ts = fdata->abs_ts;
2314     }
2315
2316     /* If we don't have the time stamp of the previous displayed packet,
2317      it's because this is the first displayed packet.  Save the time
2318      stamp of this packet as the time stamp of the previous displayed
2319      packet. */
2320     if (nstime_is_unset(&prev_dis_ts)) {
2321         prev_dis_ts = fdata->abs_ts;
2322     }
2323
2324     /* Get the time elapsed between the first packet and this packet. */
2325     nstime_delta(&fdata->rel_ts, &fdata->abs_ts, &first_ts);
2326
2327     /* If it's greater than the current elapsed time, set the elapsed time
2328      to it (we check for "greater than" so as not to be confused by
2329      time moving backwards). */
2330     if ((gint32)cf->elapsed_time.secs < fdata->rel_ts.secs
2331         || ((gint32)cf->elapsed_time.secs == fdata->rel_ts.secs && (gint32)cf->elapsed_time.nsecs < fdata->rel_ts.nsecs)) {
2332         cf->elapsed_time = fdata->rel_ts;
2333     }
2334
2335     /* Get the time elapsed between the previous displayed packet and
2336      this packet. */
2337     nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, &prev_dis_ts);
2338
2339     if( (fdata->flags.passed_dfilter) || (fdata->flags.ref_time) ){
2340         /* This frame either passed the display filter list or is marked as
2341         a time reference frame.  All time reference frames are displayed
2342         even if they dont pass the display filter */
2343         if(fdata->flags.ref_time){
2344             /* if this was a TIME REF frame we should reset the cul bytes field */
2345             cum_bytes = fdata->pkt_len;
2346             fdata->cum_bytes =  cum_bytes;
2347         } else {
2348             /* increase cum_bytes with this packets length */
2349             cum_bytes += fdata->pkt_len;
2350         }
2351     }
2352   }
2353 }
2354 #endif
2355
2356 typedef enum {
2357   PSP_FINISHED,
2358   PSP_STOPPED,
2359   PSP_FAILED
2360 } psp_return_t;
2361
2362 static psp_return_t
2363 process_specified_packets(capture_file *cf, packet_range_t *range,
2364     const char *string1, const char *string2, gboolean terminate_is_stop,
2365     gboolean (*callback)(capture_file *, frame_data *,
2366                          union wtap_pseudo_header *, const guint8 *, void *),
2367     void *callback_args)
2368 {
2369   frame_data *fdata;
2370   int         err;
2371   gchar      *err_info;
2372   union wtap_pseudo_header pseudo_header;
2373   guint8      pd[WTAP_MAX_PACKET_SIZE+1];
2374   psp_return_t ret = PSP_FINISHED;
2375
2376   progdlg_t  *progbar = NULL;
2377   int         progbar_count;
2378   float       progbar_val;
2379   gboolean    progbar_stop_flag;
2380   GTimeVal    progbar_start_time;
2381   gchar       progbar_status_str[100];
2382   int         progbar_nextstep;
2383   int         progbar_quantum;
2384   range_process_e process_this;
2385
2386   /* Update the progress bar when it gets to this value. */
2387   progbar_nextstep = 0;
2388   /* When we reach the value that triggers a progress bar update,
2389      bump that value by this amount. */
2390   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
2391   /* Count of packets at which we've looked. */
2392   progbar_count = 0;
2393   /* Progress so far. */
2394   progbar_val = 0.0f;
2395
2396   progbar_stop_flag = FALSE;
2397   g_get_current_time(&progbar_start_time);
2398
2399   packet_range_process_init(range);
2400
2401   /* Iterate through the list of packets, printing the packets that
2402      were selected by the current display filter.  */
2403   for (fdata = cf->plist_start; fdata != NULL; fdata = fdata->next) {
2404     /* Create the progress bar if necessary.
2405        We check on every iteration of the loop, so that it takes no
2406        longer than the standard time to create it (otherwise, for a
2407        large file, we might take considerably longer than that standard
2408        time in order to get to the next progress bar step). */
2409     if (progbar == NULL)
2410       progbar = delayed_create_progress_dlg(string1, string2,
2411                                             terminate_is_stop,
2412                                             &progbar_stop_flag,
2413                                             &progbar_start_time,
2414                                             progbar_val);
2415
2416     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
2417        when we update it, we have to run the GTK+ main loop to get it
2418        to repaint what's pending, and doing so may involve an "ioctl()"
2419        to see if there's any pending input from an X server, and doing
2420        that for every packet can be costly, especially on a big file. */
2421     if (progbar_count >= progbar_nextstep) {
2422       /* let's not divide by zero. I should never be started
2423        * with count == 0, so let's assert that
2424        */
2425       g_assert(cf->count > 0);
2426       progbar_val = (gfloat) progbar_count / cf->count;
2427
2428       if (progbar != NULL) {
2429         g_snprintf(progbar_status_str, sizeof(progbar_status_str),
2430                    "%4u of %u packets", progbar_count, cf->count);
2431         update_progress_dlg(progbar, progbar_val, progbar_status_str);
2432       }
2433
2434       progbar_nextstep += progbar_quantum;
2435     }
2436
2437     if (progbar_stop_flag) {
2438       /* Well, the user decided to abort the operation.  Just stop,
2439          and arrange to return PSP_STOPPED to our caller, so they know
2440          it was stopped explicitly. */
2441       ret = PSP_STOPPED;
2442       break;
2443     }
2444
2445     progbar_count++;
2446
2447     /* do we have to process this packet? */
2448     process_this = packet_range_process_packet(range, fdata);
2449     if (process_this == range_process_next) {
2450         /* this packet uninteresting, continue with next one */
2451         continue;
2452     } else if (process_this == range_processing_finished) {
2453         /* all interesting packets processed, stop the loop */
2454         break;
2455     }
2456
2457     /* Get the packet */
2458     if (!wtap_seek_read(cf->wth, fdata->file_off, &pseudo_header,
2459                         pd, fdata->cap_len, &err, &err_info)) {
2460       /* Attempt to get the packet failed. */
2461       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
2462                     cf_read_error_message(err, err_info), cf->filename);
2463       ret = PSP_FAILED;
2464       break;
2465     }
2466     /* Process the packet */
2467     if (!callback(cf, fdata, &pseudo_header, pd, callback_args)) {
2468       /* Callback failed.  We assume it reported the error appropriately. */
2469       ret = PSP_FAILED;
2470       break;
2471     }
2472   }
2473
2474   /* We're done printing the packets; destroy the progress bar if
2475      it was created. */
2476   if (progbar != NULL)
2477     destroy_progress_dlg(progbar);
2478
2479   return ret;
2480 }
2481
2482 typedef struct {
2483   gboolean construct_protocol_tree;
2484   column_info *cinfo;
2485 } retap_callback_args_t;
2486
2487 static gboolean
2488 retap_packet(capture_file *cf _U_, frame_data *fdata,
2489              union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2490              void *argsp)
2491 {
2492   retap_callback_args_t *args = argsp;
2493   epan_dissect_t edt;
2494
2495   epan_dissect_init(&edt, args->construct_protocol_tree, FALSE);
2496   tap_queue_init(&edt);
2497   epan_dissect_run(&edt, pseudo_header, pd, fdata, args->cinfo);
2498   tap_push_tapped_queue(&edt);
2499   epan_dissect_cleanup(&edt);
2500
2501   return TRUE;
2502 }
2503
2504 cf_read_status_t
2505 cf_retap_packets(capture_file *cf)
2506 {
2507   packet_range_t range;
2508   retap_callback_args_t callback_args;
2509   gboolean filtering_tap_listeners;
2510   guint tap_flags;
2511
2512   /* Do we have any tap listeners with filters? */
2513   filtering_tap_listeners = have_filtering_tap_listeners();
2514
2515   tap_flags = union_of_tap_listener_flags();
2516
2517   /* If any tap listeners have filters, or require the protocol tree,
2518      construct the protocol tree. */
2519   callback_args.construct_protocol_tree = filtering_tap_listeners ||
2520                                           (tap_flags & TL_REQUIRES_PROTO_TREE);
2521
2522   /* If any tap listeners require the columns, construct them. */
2523   callback_args.cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
2524
2525   /* Reset the tap listeners. */
2526   reset_tap_listeners();
2527
2528   /* Iterate through the list of packets, dissecting all packets and
2529      re-running the taps. */
2530   packet_range_init(&range);
2531   packet_range_process_init(&range);
2532   switch (process_specified_packets(cf, &range, "Recalculating statistics on",
2533                                     "all packets", TRUE, retap_packet,
2534                                     &callback_args)) {
2535   case PSP_FINISHED:
2536     /* Completed successfully. */
2537     return CF_READ_OK;
2538
2539   case PSP_STOPPED:
2540     /* Well, the user decided to abort the refiltering.
2541        Return CF_READ_ABORTED so our caller knows they did that. */
2542     return CF_READ_ABORTED;
2543
2544   case PSP_FAILED:
2545     /* Error while retapping. */
2546     return CF_READ_ERROR;
2547   }
2548
2549   g_assert_not_reached();
2550   return CF_READ_OK;
2551 }
2552
2553 typedef struct {
2554   print_args_t *print_args;
2555   gboolean      print_header_line;
2556   char         *header_line_buf;
2557   int           header_line_buf_len;
2558   gboolean      print_formfeed;
2559   gboolean      print_separator;
2560   char         *line_buf;
2561   int           line_buf_len;
2562   gint         *col_widths;
2563 } print_callback_args_t;
2564
2565 static gboolean
2566 print_packet(capture_file *cf, frame_data *fdata,
2567              union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2568              void *argsp)
2569 {
2570   print_callback_args_t *args = argsp;
2571   epan_dissect_t edt;
2572   int             i;
2573   char           *cp;
2574   int             line_len;
2575   int             column_len;
2576   int             cp_off;
2577   gboolean        proto_tree_needed;
2578   char            bookmark_name[9+10+1];    /* "__frameNNNNNNNNNN__\0" */
2579   char            bookmark_title[6+10+1];   /* "Frame NNNNNNNNNN__\0" */
2580
2581   /* Create the protocol tree, and make it visible, if we're printing
2582      the dissection or the hex data.
2583      XXX - do we need it if we're just printing the hex data? */
2584   proto_tree_needed =
2585       args->print_args->print_dissections != print_dissections_none || args->print_args->print_hex || have_custom_cols(&cf->cinfo);
2586   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2587
2588   /* Fill in the column information if we're printing the summary
2589      information. */
2590   if (args->print_args->print_summary) {
2591     epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
2592     epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
2593   } else
2594     epan_dissect_run(&edt, pseudo_header, pd, fdata, NULL);
2595
2596   if (args->print_formfeed) {
2597     if (!new_page(args->print_args->stream))
2598       goto fail;
2599   } else {
2600       if (args->print_separator) {
2601         if (!print_line(args->print_args->stream, 0, ""))
2602           goto fail;
2603       }
2604   }
2605
2606   /*
2607    * We generate bookmarks, if the output format supports them.
2608    * The name is "__frameN__".
2609    */
2610   g_snprintf(bookmark_name, sizeof bookmark_name, "__frame%u__", fdata->num);
2611
2612   if (args->print_args->print_summary) {
2613     if (args->print_header_line) {
2614       if (!print_line(args->print_args->stream, 0, args->header_line_buf))
2615         goto fail;
2616       args->print_header_line = FALSE;  /* we might not need to print any more */
2617     }
2618     cp = &args->line_buf[0];
2619     line_len = 0;
2620     for (i = 0; i < cf->cinfo.num_cols; i++) {
2621       /* Find the length of the string for this column. */
2622       column_len = (int) strlen(cf->cinfo.col_data[i]);
2623       if (args->col_widths[i] > column_len)
2624          column_len = args->col_widths[i];
2625
2626       /* Make sure there's room in the line buffer for the column; if not,
2627          double its length. */
2628       line_len += column_len + 1;   /* "+1" for space */
2629       if (line_len > args->line_buf_len) {
2630         cp_off = (int) (cp - args->line_buf);
2631         args->line_buf_len = 2 * line_len;
2632         args->line_buf = g_realloc(args->line_buf, args->line_buf_len + 1);
2633         cp = args->line_buf + cp_off;
2634       }
2635
2636       /* Right-justify the packet number column. */
2637       if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2638         g_snprintf(cp, column_len+1, "%*s", args->col_widths[i], cf->cinfo.col_data[i]);
2639       else
2640         g_snprintf(cp, column_len+1, "%-*s", args->col_widths[i], cf->cinfo.col_data[i]);
2641       cp += column_len;
2642       if (i != cf->cinfo.num_cols - 1)
2643         *cp++ = ' ';
2644     }
2645     *cp = '\0';
2646
2647     /*
2648      * Generate a bookmark, using the summary line as the title.
2649      */
2650     if (!print_bookmark(args->print_args->stream, bookmark_name,
2651                         args->line_buf))
2652       goto fail;
2653
2654     if (!print_line(args->print_args->stream, 0, args->line_buf))
2655       goto fail;
2656   } else {
2657     /*
2658      * Generate a bookmark, using "Frame N" as the title, as we're not
2659      * printing the summary line.
2660      */
2661     g_snprintf(bookmark_title, sizeof bookmark_title, "Frame %u", fdata->num);
2662     if (!print_bookmark(args->print_args->stream, bookmark_name,
2663                         bookmark_title))
2664       goto fail;
2665   } /* if (print_summary) */
2666
2667   if (args->print_args->print_dissections != print_dissections_none) {
2668     if (args->print_args->print_summary) {
2669       /* Separate the summary line from the tree with a blank line. */
2670       if (!print_line(args->print_args->stream, 0, ""))
2671         goto fail;
2672     }
2673
2674     /* Print the information in that tree. */
2675     if (!proto_tree_print(args->print_args, &edt, args->print_args->stream))
2676       goto fail;
2677
2678     /* Print a blank line if we print anything after this (aka more than one packet). */
2679     args->print_separator = TRUE;
2680
2681     /* Print a header line if we print any more packet summaries */
2682     args->print_header_line = TRUE;
2683   }
2684
2685   if (args->print_args->print_hex) {
2686     /* Print the full packet data as hex. */
2687     if (!print_hex_data(args->print_args->stream, &edt))
2688       goto fail;
2689
2690     /* Print a blank line if we print anything after this (aka more than one packet). */
2691     args->print_separator = TRUE;
2692
2693     /* Print a header line if we print any more packet summaries */
2694     args->print_header_line = TRUE;
2695   } /* if (args->print_args->print_dissections != print_dissections_none) */
2696
2697   epan_dissect_cleanup(&edt);
2698
2699   /* do we want to have a formfeed between each packet from now on? */
2700   if(args->print_args->print_formfeed) {
2701     args->print_formfeed = TRUE;
2702   }
2703
2704   return TRUE;
2705
2706 fail:
2707   epan_dissect_cleanup(&edt);
2708   return FALSE;
2709 }
2710
2711 cf_print_status_t
2712 cf_print_packets(capture_file *cf, print_args_t *print_args)
2713 {
2714   int         i;
2715   print_callback_args_t callback_args;
2716   gint        data_width;
2717   char        *cp;
2718   int         cp_off;
2719   int         column_len;
2720   int         line_len;
2721   psp_return_t ret;
2722
2723   callback_args.print_args = print_args;
2724   callback_args.print_header_line = TRUE;
2725   callback_args.header_line_buf = NULL;
2726   callback_args.header_line_buf_len = 256;
2727   callback_args.print_formfeed = FALSE;
2728   callback_args.print_separator = FALSE;
2729   callback_args.line_buf = NULL;
2730   callback_args.line_buf_len = 256;
2731   callback_args.col_widths = NULL;
2732
2733   if (!print_preamble(print_args->stream, cf->filename)) {
2734     destroy_print_stream(print_args->stream);
2735     return CF_PRINT_WRITE_ERROR;
2736   }
2737
2738   if (print_args->print_summary) {
2739     /* We're printing packet summaries.  Allocate the header line buffer
2740        and get the column widths. */
2741     callback_args.header_line_buf = g_malloc(callback_args.header_line_buf_len + 1);
2742
2743     /* Find the widths for each of the columns - maximum of the
2744        width of the title and the width of the data - and construct
2745        a buffer with a line containing the column titles. */
2746     callback_args.col_widths = (gint *) g_malloc(sizeof(gint) * cf->cinfo.num_cols);
2747     cp = &callback_args.header_line_buf[0];
2748     line_len = 0;
2749     for (i = 0; i < cf->cinfo.num_cols; i++) {
2750       /* Don't pad the last column. */
2751       if (i == cf->cinfo.num_cols - 1)
2752         callback_args.col_widths[i] = 0;
2753       else {
2754         callback_args.col_widths[i] = (gint) strlen(cf->cinfo.col_title[i]);
2755         data_width = get_column_char_width(get_column_format(i));
2756         if (data_width > callback_args.col_widths[i])
2757           callback_args.col_widths[i] = data_width;
2758       }
2759
2760       /* Find the length of the string for this column. */
2761       column_len = (int) strlen(cf->cinfo.col_title[i]);
2762       if (callback_args.col_widths[i] > column_len)
2763         column_len = callback_args.col_widths[i];
2764
2765       /* Make sure there's room in the line buffer for the column; if not,
2766          double its length. */
2767       line_len += column_len + 1;   /* "+1" for space */
2768       if (line_len > callback_args.header_line_buf_len) {
2769         cp_off = (int) (cp - callback_args.header_line_buf);
2770         callback_args.header_line_buf_len = 2 * line_len;
2771         callback_args.header_line_buf = g_realloc(callback_args.header_line_buf,
2772                                                   callback_args.header_line_buf_len + 1);
2773         cp = callback_args.header_line_buf + cp_off;
2774       }
2775
2776       /* Right-justify the packet number column. */
2777 /*      if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2778         g_snprintf(cp, column_len+1, "%*s", callback_args.col_widths[i], cf->cinfo.col_title[i]);
2779       else*/
2780       g_snprintf(cp, column_len+1, "%-*s", callback_args.col_widths[i], cf->cinfo.col_title[i]);
2781       cp += column_len;
2782       if (i != cf->cinfo.num_cols - 1)
2783         *cp++ = ' ';
2784     }
2785     *cp = '\0';
2786
2787     /* Now start out the main line buffer with the same length as the
2788        header line buffer. */
2789     callback_args.line_buf_len = callback_args.header_line_buf_len;
2790     callback_args.line_buf = g_malloc(callback_args.line_buf_len + 1);
2791   } /* if (print_summary) */
2792
2793   /* Iterate through the list of packets, printing the packets we were
2794      told to print. */
2795   ret = process_specified_packets(cf, &print_args->range, "Printing",
2796                                   "selected packets", TRUE, print_packet,
2797                                   &callback_args);
2798
2799   g_free(callback_args.header_line_buf);
2800   g_free(callback_args.line_buf);
2801   g_free(callback_args.col_widths);
2802
2803   switch (ret) {
2804
2805   case PSP_FINISHED:
2806     /* Completed successfully. */
2807     break;
2808
2809   case PSP_STOPPED:
2810     /* Well, the user decided to abort the printing.
2811
2812        XXX - note that what got generated before they did that
2813        will get printed if we're piping to a print program; we'd
2814        have to write to a file and then hand that to the print
2815        program to make it actually not print anything. */
2816     break;
2817
2818   case PSP_FAILED:
2819     /* Error while printing.
2820
2821        XXX - note that what got generated before they did that
2822        will get printed if we're piping to a print program; we'd
2823        have to write to a file and then hand that to the print
2824        program to make it actually not print anything. */
2825     destroy_print_stream(print_args->stream);
2826     return CF_PRINT_WRITE_ERROR;
2827   }
2828
2829   if (!print_finale(print_args->stream)) {
2830     destroy_print_stream(print_args->stream);
2831     return CF_PRINT_WRITE_ERROR;
2832   }
2833
2834   if (!destroy_print_stream(print_args->stream))
2835     return CF_PRINT_WRITE_ERROR;
2836
2837   return CF_PRINT_OK;
2838 }
2839
2840 static gboolean
2841 write_pdml_packet(capture_file *cf _U_, frame_data *fdata,
2842                   union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2843           void *argsp)
2844 {
2845   FILE *fh = argsp;
2846   epan_dissect_t edt;
2847
2848   /* Create the protocol tree, but don't fill in the column information. */
2849   epan_dissect_init(&edt, TRUE, TRUE);
2850   epan_dissect_run(&edt, pseudo_header, pd, fdata, NULL);
2851
2852   /* Write out the information in that tree. */
2853   proto_tree_write_pdml(&edt, fh);
2854
2855   epan_dissect_cleanup(&edt);
2856
2857   return !ferror(fh);
2858 }
2859
2860 cf_print_status_t
2861 cf_write_pdml_packets(capture_file *cf, print_args_t *print_args)
2862 {
2863   FILE        *fh;
2864   psp_return_t ret;
2865
2866   fh = ws_fopen(print_args->file, "w");
2867   if (fh == NULL)
2868     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2869
2870   write_pdml_preamble(fh);
2871   if (ferror(fh)) {
2872     fclose(fh);
2873     return CF_PRINT_WRITE_ERROR;
2874   }
2875
2876   /* Iterate through the list of packets, printing the packets we were
2877      told to print. */
2878   ret = process_specified_packets(cf, &print_args->range, "Writing PDML",
2879                                   "selected packets", TRUE,
2880                                   write_pdml_packet, fh);
2881
2882   switch (ret) {
2883
2884   case PSP_FINISHED:
2885     /* Completed successfully. */
2886     break;
2887
2888   case PSP_STOPPED:
2889     /* Well, the user decided to abort the printing. */
2890     break;
2891
2892   case PSP_FAILED:
2893     /* Error while printing. */
2894     fclose(fh);
2895     return CF_PRINT_WRITE_ERROR;
2896   }
2897
2898   write_pdml_finale(fh);
2899   if (ferror(fh)) {
2900     fclose(fh);
2901     return CF_PRINT_WRITE_ERROR;
2902   }
2903
2904   /* XXX - check for an error */
2905   fclose(fh);
2906
2907   return CF_PRINT_OK;
2908 }
2909
2910 static gboolean
2911 write_psml_packet(capture_file *cf, frame_data *fdata,
2912                   union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2913           void *argsp)
2914 {
2915   FILE *fh = argsp;
2916   epan_dissect_t edt;
2917   gboolean proto_tree_needed;
2918
2919   /* Fill in the column information, only create the protocol tree
2920      if having custom columns. */
2921   proto_tree_needed = have_custom_cols(&cf->cinfo);
2922   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2923   epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
2924   epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
2925
2926   /* Write out the information in that tree. */
2927   proto_tree_write_psml(&edt, fh);
2928
2929   epan_dissect_cleanup(&edt);
2930
2931   return !ferror(fh);
2932 }
2933
2934 cf_print_status_t
2935 cf_write_psml_packets(capture_file *cf, print_args_t *print_args)
2936 {
2937   FILE        *fh;
2938   psp_return_t ret;
2939
2940   fh = ws_fopen(print_args->file, "w");
2941   if (fh == NULL)
2942     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2943
2944   write_psml_preamble(fh);
2945   if (ferror(fh)) {
2946     fclose(fh);
2947     return CF_PRINT_WRITE_ERROR;
2948   }
2949
2950   /* Iterate through the list of packets, printing the packets we were
2951      told to print. */
2952   ret = process_specified_packets(cf, &print_args->range, "Writing PSML",
2953                                   "selected packets", TRUE,
2954                                   write_psml_packet, fh);
2955
2956   switch (ret) {
2957
2958   case PSP_FINISHED:
2959     /* Completed successfully. */
2960     break;
2961
2962   case PSP_STOPPED:
2963     /* Well, the user decided to abort the printing. */
2964     break;
2965
2966   case PSP_FAILED:
2967     /* Error while printing. */
2968     fclose(fh);
2969     return CF_PRINT_WRITE_ERROR;
2970   }
2971
2972   write_psml_finale(fh);
2973   if (ferror(fh)) {
2974     fclose(fh);
2975     return CF_PRINT_WRITE_ERROR;
2976   }
2977
2978   /* XXX - check for an error */
2979   fclose(fh);
2980
2981   return CF_PRINT_OK;
2982 }
2983
2984 static gboolean
2985 write_csv_packet(capture_file *cf, frame_data *fdata,
2986                  union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2987                  void *argsp)
2988 {
2989   FILE *fh = argsp;
2990   epan_dissect_t edt;
2991   gboolean proto_tree_needed;
2992
2993   /* Fill in the column information, only create the protocol tree
2994      if having custom columns. */
2995   proto_tree_needed = have_custom_cols(&cf->cinfo);
2996   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2997   epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
2998   epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
2999
3000   /* Write out the information in that tree. */
3001   proto_tree_write_csv(&edt, fh);
3002
3003   epan_dissect_cleanup(&edt);
3004
3005   return !ferror(fh);
3006 }
3007
3008 cf_print_status_t
3009 cf_write_csv_packets(capture_file *cf, print_args_t *print_args)
3010 {
3011   FILE        *fh;
3012   psp_return_t ret;
3013
3014   fh = ws_fopen(print_args->file, "w");
3015   if (fh == NULL)
3016     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
3017
3018   write_csv_preamble(fh);
3019   if (ferror(fh)) {
3020     fclose(fh);
3021     return CF_PRINT_WRITE_ERROR;
3022   }
3023
3024   /* Iterate through the list of packets, printing the packets we were
3025      told to print. */
3026   ret = process_specified_packets(cf, &print_args->range, "Writing CSV",
3027                                   "selected packets", TRUE,
3028                                   write_csv_packet, fh);
3029
3030   switch (ret) {
3031
3032   case PSP_FINISHED:
3033     /* Completed successfully. */
3034     break;
3035
3036   case PSP_STOPPED:
3037     /* Well, the user decided to abort the printing. */
3038     break;
3039
3040   case PSP_FAILED:
3041     /* Error while printing. */
3042     fclose(fh);
3043     return CF_PRINT_WRITE_ERROR;
3044   }
3045
3046   write_csv_finale(fh);
3047   if (ferror(fh)) {
3048     fclose(fh);
3049     return CF_PRINT_WRITE_ERROR;
3050   }
3051
3052   /* XXX - check for an error */
3053   fclose(fh);
3054
3055   return CF_PRINT_OK;
3056 }
3057
3058 static gboolean
3059 write_carrays_packet(capture_file *cf _U_, frame_data *fdata,
3060              union wtap_pseudo_header *pseudo_header _U_,
3061              const guint8 *pd, void *argsp)
3062 {
3063   FILE *fh = argsp;
3064
3065   proto_tree_write_carrays(pd, fdata->cap_len, fdata->num, fh);
3066   return !ferror(fh);
3067 }
3068
3069 cf_print_status_t
3070 cf_write_carrays_packets(capture_file *cf, print_args_t *print_args)
3071 {
3072   FILE        *fh;
3073   psp_return_t ret;
3074
3075   fh = ws_fopen(print_args->file, "w");
3076
3077   if (fh == NULL)
3078     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
3079
3080   write_carrays_preamble(fh);
3081
3082   if (ferror(fh)) {
3083     fclose(fh);
3084     return CF_PRINT_WRITE_ERROR;
3085   }
3086
3087   /* Iterate through the list of packets, printing the packets we were
3088      told to print. */
3089   ret = process_specified_packets(cf, &print_args->range,
3090                   "Writing C Arrays",
3091                   "selected packets", TRUE,
3092                                   write_carrays_packet, fh);
3093   switch (ret) {
3094   case PSP_FINISHED:
3095     /* Completed successfully. */
3096     break;
3097   case PSP_STOPPED:
3098     /* Well, the user decided to abort the printing. */
3099     break;
3100   case PSP_FAILED:
3101     /* Error while printing. */
3102     fclose(fh);
3103     return CF_PRINT_WRITE_ERROR;
3104   }
3105
3106   write_carrays_finale(fh);
3107
3108   if (ferror(fh)) {
3109     fclose(fh);
3110     return CF_PRINT_WRITE_ERROR;
3111   }
3112
3113   fclose(fh);
3114   return CF_PRINT_OK;
3115 }
3116
3117 #ifndef NEW_PACKET_LIST /* This function is not needed with the new packet list */
3118
3119 /* Scan through the packet list and change all columns that use the
3120    "command-line-specified" time stamp format to use the current
3121    value of that format. */
3122 void
3123 cf_change_time_formats(capture_file *cf)
3124 {
3125   int         i;
3126   frame_data *fdata;
3127   progdlg_t  *progbar = NULL;
3128   gboolean    stop_flag;
3129   int         count;
3130   int         row;
3131   float       progbar_val;
3132   GTimeVal    start_time;
3133   gchar       status_str[100];
3134   int         progbar_nextstep;
3135   int         progbar_quantum;
3136   gboolean    sorted_by_frame_column;
3137
3138   /* Adjust timestamp precision if auto is selected */
3139   cf_timestamp_auto_precision(cf);
3140
3141   /* Are there any columns with time stamps in the "command-line-specified"
3142      format?
3143
3144      XXX - we have to force the "column is writable" flag on, as it
3145      might be off from the last frame that was dissected. */
3146   col_set_writable(&cf->cinfo, TRUE);
3147   if (!check_col(&cf->cinfo, COL_CLS_TIME) &&
3148       !check_col(&cf->cinfo, COL_ABS_TIME) &&
3149       !check_col(&cf->cinfo, COL_ABS_DATE_TIME) &&
3150       !check_col(&cf->cinfo, COL_REL_TIME) &&
3151       !check_col(&cf->cinfo, COL_DELTA_TIME) &&
3152       !check_col(&cf->cinfo, COL_DELTA_TIME_DIS)) {
3153     /* No, there aren't any columns in that format, so we have no work
3154        to do. */
3155     return;
3156   }
3157
3158   /* Freeze the packet list while we redo it, so we don't get any
3159      screen updates while it happens. */
3160   packet_list_freeze();
3161
3162   /* Update the progress bar when it gets to this value. */
3163   progbar_nextstep = 0;
3164   /* When we reach the value that triggers a progress bar update,
3165      bump that value by this amount. */
3166   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
3167   /* Count of packets at which we've looked. */
3168   count = 0;
3169   /* Progress so far. */
3170   progbar_val = 0.0f;
3171
3172   /*  If the rows are currently sorted by the frame column then we know
3173    *  the row number of each packet: it's the row number of the previously
3174    *  displayed packet + 1.
3175    *
3176    *  Otherwise, if the display is sorted by a different column then we have
3177    *  to use the O(N) packet_list_find_row_from_data() (thus making the job
3178    *  of changing the time display format O(N**2)).
3179    *
3180    *  (XXX - In fact it's still O(N**2) because gtk_clist_set_text() takes
3181    *  the row number and walks that many elements down the clist to find
3182    *  the appropriate element.)
3183    */
3184   sorted_by_frame_column = FALSE;
3185   for (i = 0; i < cf->cinfo.num_cols; i++) {
3186     if (cf->cinfo.col_fmt[i] == COL_NUMBER)
3187     {
3188       sorted_by_frame_column = (i == packet_list_get_sort_column());
3189       break;
3190     }
3191   }
3192
3193   stop_flag = FALSE;
3194   g_get_current_time(&start_time);
3195
3196   /* Iterate through the list of packets, checking whether the packet
3197      is in a row of the summary list and, if so, whether there are
3198      any columns that show the time in the "command-line-specified"
3199      format and, if so, update that row. */
3200   for (fdata = cf->plist_start, row = -1; fdata != NULL; fdata = fdata->next) {
3201     /* Create the progress bar if necessary.
3202        We check on every iteration of the loop, so that it takes no
3203        longer than the standard time to create it (otherwise, for a
3204        large file, we might take considerably longer than that standard
3205        time in order to get to the next progress bar step). */
3206     if (progbar == NULL)
3207       progbar = delayed_create_progress_dlg("Changing", "time display",
3208         TRUE, &stop_flag, &start_time, progbar_val);
3209
3210     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
3211        when we update it, we have to run the GTK+ main loop to get it
3212        to repaint what's pending, and doing so may involve an "ioctl()"
3213        to see if there's any pending input from an X server, and doing
3214        that for every packet can be costly, especially on a big file. */
3215     if (count >= progbar_nextstep) {
3216       /* let's not divide by zero. I should never be started
3217        * with count == 0, so let's assert that
3218        */
3219       g_assert(cf->count > 0);
3220
3221       progbar_val = (gfloat) count / cf->count;
3222
3223       if (progbar != NULL) {
3224         g_snprintf(status_str, sizeof(status_str),
3225                    "%4u of %u packets", count, cf->count);
3226         update_progress_dlg(progbar, progbar_val, status_str);
3227       }
3228
3229       progbar_nextstep += progbar_quantum;
3230     }
3231
3232     if (stop_flag) {
3233       /* Well, the user decided to abort the redisplay.  Just stop.
3234
3235          XXX - this leaves the time field in the old format in
3236      frames we haven't yet processed.  So it goes; should we
3237      simply not offer them the option of stopping? */
3238       break;
3239     }
3240
3241     count++;
3242
3243     /* Find what row this packet is in. */
3244     if (!sorted_by_frame_column) {
3245       /* This function is O(N), so we try to avoid using it... */
3246       row = packet_list_find_row_from_data(fdata);
3247     } else {
3248       /* ...which we do by maintaining a count of packets that are
3249          being displayed (i.e., that have passed the display filter),
3250          and using the current value of that count as the row number
3251          (which is why we can only do it when the display is sorted
3252          by the frame number). */
3253       if (fdata->flags.passed_dfilter)
3254         row++;
3255       else
3256         continue;
3257     }
3258
3259     if (row != -1) {
3260       /* This packet is in the summary list, on row "row". */
3261
3262       for (i = 0; i < cf->cinfo.num_cols; i++) {
3263         if (col_has_time_fmt(&cf->cinfo, i)) {
3264           /* This is one of the columns that shows the time in
3265              "command-line-specified" format; update it. */
3266           cf->cinfo.col_buf[i][0] = '\0';
3267           col_set_fmt_time(fdata, &cf->cinfo, cf->cinfo.col_fmt[i], i);
3268           packet_list_set_text(row, i, cf->cinfo.col_data[i]);
3269         }
3270       }
3271     }
3272   }
3273
3274   /* We're done redisplaying the packets; destroy the progress bar if it
3275      was created. */
3276   if (progbar != NULL)
3277     destroy_progress_dlg(progbar);
3278
3279   /* Set the column widths of those columns that show the time in
3280      "command-line-specified" format. */
3281   for (i = 0; i < cf->cinfo.num_cols; i++) {
3282     if (col_has_time_fmt(&cf->cinfo, i)) {
3283       packet_list_set_time_width(cf->cinfo.col_fmt[i], i);
3284     }
3285   }
3286
3287   /* Unfreeze the packet list. */
3288   packet_list_thaw();
3289 }
3290 #endif /* NEW_PACKET_LIST */
3291
3292
3293 typedef struct {
3294     const char  *string;
3295     size_t      string_len;
3296     capture_file    *cf;
3297     gboolean    frame_matched;
3298 } match_data;
3299
3300 gboolean
3301 cf_find_packet_protocol_tree(capture_file *cf, const char *string)
3302 {
3303   match_data        mdata;
3304
3305   mdata.string = string;
3306   mdata.string_len = strlen(string);
3307   return find_packet(cf, match_protocol_tree, &mdata);
3308 }
3309
3310 static gboolean
3311 match_protocol_tree(capture_file *cf, frame_data *fdata, void *criterion)
3312 {
3313   match_data        *mdata = criterion;
3314   epan_dissect_t    edt;
3315
3316   /* Construct the protocol tree, including the displayed text */
3317   epan_dissect_init(&edt, TRUE, TRUE);
3318   /* We don't need the column information */
3319   epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, NULL);
3320
3321   /* Iterate through all the nodes, seeing if they have text that matches. */
3322   mdata->cf = cf;
3323   mdata->frame_matched = FALSE;
3324   proto_tree_children_foreach(edt.tree, match_subtree_text, mdata);
3325   epan_dissect_cleanup(&edt);
3326   return mdata->frame_matched;
3327 }
3328
3329 static void
3330 match_subtree_text(proto_node *node, gpointer data)
3331 {
3332   match_data    *mdata = (match_data*) data;
3333   const gchar   *string = mdata->string;
3334   size_t    string_len = mdata->string_len;
3335   capture_file  *cf = mdata->cf;
3336   field_info    *fi = PNODE_FINFO(node);
3337   gchar     label_str[ITEM_LABEL_LENGTH];
3338   gchar     *label_ptr;
3339   size_t    label_len;
3340   guint32   i;
3341   guint8    c_char;
3342   size_t    c_match = 0;
3343
3344   g_assert(fi && "dissection with an invisible proto tree?");
3345
3346   if (mdata->frame_matched) {
3347     /* We already had a match; don't bother doing any more work. */
3348     return;
3349   }
3350
3351   /* Don't match invisible entries. */
3352   if (PROTO_ITEM_IS_HIDDEN(node))
3353     return;
3354
3355   /* was a free format label produced? */
3356   if (fi->rep) {
3357     label_ptr = fi->rep->representation;
3358   } else {
3359     /* no, make a generic label */
3360     label_ptr = label_str;
3361     proto_item_fill_label(fi, label_str);
3362   }
3363
3364   /* Does that label match? */
3365   label_len = strlen(label_ptr);
3366   for (i = 0; i < label_len; i++) {
3367     c_char = label_ptr[i];
3368     if (cf->case_type)
3369       c_char = toupper(c_char);
3370     if (c_char == string[c_match]) {
3371       c_match++;
3372       if (c_match == string_len) {
3373     /* No need to look further; we have a match */
3374     mdata->frame_matched = TRUE;
3375     return;
3376       }
3377     } else
3378       c_match = 0;
3379   }
3380
3381   /* Recurse into the subtree, if it exists */
3382   if (node->first_child != NULL)
3383     proto_tree_children_foreach(node, match_subtree_text, mdata);
3384 }
3385
3386 gboolean
3387 cf_find_packet_summary_line(capture_file *cf, const char *string)
3388 {
3389   match_data        mdata;
3390
3391   mdata.string = string;
3392   mdata.string_len = strlen(string);
3393   return find_packet(cf, match_summary_line, &mdata);
3394 }
3395
3396 static gboolean
3397 match_summary_line(capture_file *cf, frame_data *fdata, void *criterion)
3398 {
3399   match_data        *mdata = criterion;
3400   const gchar       *string = mdata->string;
3401   size_t        string_len = mdata->string_len;
3402   epan_dissect_t    edt;
3403   const char        *info_column;
3404   size_t        info_column_len;
3405   gboolean      frame_matched = FALSE;
3406   gint          colx;
3407   guint32       i;
3408   guint8        c_char;
3409   size_t        c_match = 0;
3410
3411   /* Don't bother constructing the protocol tree */
3412   epan_dissect_init(&edt, FALSE, FALSE);
3413   /* Get the column information */
3414   epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, &cf->cinfo);
3415
3416   /* Find the Info column */
3417   for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
3418     if (cf->cinfo.fmt_matx[colx][COL_INFO]) {
3419       /* Found it.  See if we match. */
3420       info_column = edt.pi.cinfo->col_data[colx];
3421       info_column_len = strlen(info_column);
3422       for (i = 0; i < info_column_len; i++) {
3423     c_char = info_column[i];
3424     if (cf->case_type)
3425       c_char = toupper(c_char);
3426     if (c_char == string[c_match]) {
3427       c_match++;
3428       if (c_match == string_len) {
3429         frame_matched = TRUE;
3430         break;
3431       }
3432     } else
3433       c_match = 0;
3434       }
3435       break;
3436     }
3437   }
3438   epan_dissect_cleanup(&edt);
3439   return frame_matched;
3440 }
3441
3442 typedef struct {
3443     const guint8 *data;
3444     size_t data_len;
3445 } cbs_t;    /* "Counted byte string" */
3446
3447 gboolean
3448 cf_find_packet_data(capture_file *cf, const guint8 *string, size_t string_size)
3449 {
3450   cbs_t info;
3451
3452   info.data = string;
3453   info.data_len = string_size;
3454
3455   /* String or hex search? */
3456   if (cf->string) {
3457     /* String search - what type of string? */
3458     switch (cf->scs_type) {
3459
3460     case SCS_ASCII_AND_UNICODE:
3461       return find_packet(cf, match_ascii_and_unicode, &info);
3462
3463     case SCS_ASCII:
3464       return find_packet(cf, match_ascii, &info);
3465
3466     case SCS_UNICODE:
3467       return find_packet(cf, match_unicode, &info);
3468
3469     default:
3470       g_assert_not_reached();
3471       return FALSE;
3472     }
3473   } else
3474     return find_packet(cf, match_binary, &info);
3475 }
3476
3477 static gboolean
3478 match_ascii_and_unicode(capture_file *cf, frame_data *fdata, void *criterion)
3479 {
3480   cbs_t     *info = criterion;
3481   const guint8  *ascii_text = info->data;
3482   size_t    textlen = info->data_len;
3483   gboolean  frame_matched;
3484   guint32   buf_len;
3485   guint32   i;
3486   guint8    c_char;
3487   size_t    c_match = 0;
3488
3489   frame_matched = FALSE;
3490   buf_len = fdata->pkt_len;
3491   for (i = 0; i < buf_len; i++) {
3492     c_char = cf->pd[i];
3493     if (cf->case_type)
3494       c_char = toupper(c_char);
3495     if (c_char != 0) {
3496       if (c_char == ascii_text[c_match]) {
3497     c_match++;
3498     if (c_match == textlen) {
3499       frame_matched = TRUE;
3500       cf->search_pos = i; /* Save the position of the last character
3501                    for highlighting the field. */
3502       break;
3503     }
3504       } else
3505     c_match = 0;
3506     }
3507   }
3508   return frame_matched;
3509 }
3510
3511 static gboolean
3512 match_ascii(capture_file *cf, frame_data *fdata, void *criterion)
3513 {
3514   cbs_t     *info = criterion;
3515   const guint8  *ascii_text = info->data;
3516   size_t    textlen = info->data_len;
3517   gboolean  frame_matched;
3518   guint32   buf_len;
3519   guint32   i;
3520   guint8    c_char;
3521   size_t    c_match = 0;
3522
3523   frame_matched = FALSE;
3524   buf_len = fdata->pkt_len;
3525   for (i = 0; i < buf_len; i++) {
3526     c_char = cf->pd[i];
3527     if (cf->case_type)
3528       c_char = toupper(c_char);
3529     if (c_char == ascii_text[c_match]) {
3530       c_match++;
3531       if (c_match == textlen) {
3532     frame_matched = TRUE;
3533     cf->search_pos = i; /* Save the position of the last character
3534                    for highlighting the field. */
3535     break;
3536       }
3537     } else
3538       c_match = 0;
3539   }
3540   return frame_matched;
3541 }
3542
3543 static gboolean
3544 match_unicode(capture_file *cf, frame_data *fdata, void *criterion)
3545 {
3546   cbs_t     *info = criterion;
3547   const guint8  *ascii_text = info->data;
3548   size_t    textlen = info->data_len;
3549   gboolean  frame_matched;
3550   guint32   buf_len;
3551   guint32   i;
3552   guint8    c_char;
3553   size_t    c_match = 0;
3554
3555   frame_matched = FALSE;
3556   buf_len = fdata->pkt_len;
3557   for (i = 0; i < buf_len; i++) {
3558     c_char = cf->pd[i];
3559     if (cf->case_type)
3560       c_char = toupper(c_char);
3561     if (c_char == ascii_text[c_match]) {
3562       c_match++;
3563       i++;
3564       if (c_match == textlen) {
3565     frame_matched = TRUE;
3566     cf->search_pos = i; /* Save the position of the last character
3567                    for highlighting the field. */
3568     break;
3569       }
3570     } else
3571       c_match = 0;
3572   }
3573   return frame_matched;
3574 }
3575
3576 static gboolean
3577 match_binary(capture_file *cf, frame_data *fdata, void *criterion)
3578 {
3579   cbs_t     *info = criterion;
3580   const guint8  *binary_data = info->data;
3581   size_t    datalen = info->data_len;
3582   gboolean  frame_matched;
3583   guint32   buf_len;
3584   guint32   i;
3585   size_t    c_match = 0;
3586
3587   frame_matched = FALSE;
3588   buf_len = fdata->pkt_len;
3589   for (i = 0; i < buf_len; i++) {
3590     if (cf->pd[i] == binary_data[c_match]) {
3591       c_match++;
3592       if (c_match == datalen) {
3593     frame_matched = TRUE;
3594     cf->search_pos = i; /* Save the position of the last character
3595                    for highlighting the field. */
3596     break;
3597       }
3598     } else
3599       c_match = 0;
3600   }
3601   return frame_matched;
3602 }
3603
3604 gboolean
3605 cf_find_packet_dfilter(capture_file *cf, dfilter_t *sfcode)
3606 {
3607   return find_packet(cf, match_dfilter, sfcode);
3608 }
3609
3610 static gboolean
3611 match_dfilter(capture_file *cf, frame_data *fdata, void *criterion)
3612 {
3613   dfilter_t     *sfcode = criterion;
3614   epan_dissect_t    edt;
3615   gboolean      frame_matched;
3616
3617   epan_dissect_init(&edt, TRUE, FALSE);
3618   epan_dissect_prime_dfilter(&edt, sfcode);
3619   epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, NULL);
3620   frame_matched = dfilter_apply_edt(sfcode, &edt);
3621   epan_dissect_cleanup(&edt);
3622   return frame_matched;
3623 }
3624
3625 static gboolean
3626 find_packet(capture_file *cf,
3627             gboolean (*match_function)(capture_file *, frame_data *, void *),
3628             void *criterion)
3629 {
3630   frame_data *start_fd;
3631   frame_data *fdata;
3632   frame_data *new_fd = NULL;
3633   progdlg_t  *progbar = NULL;
3634   gboolean    stop_flag;
3635   int         count;
3636   int         err;
3637   gchar      *err_info;
3638   int         row;
3639   float       progbar_val;
3640   GTimeVal    start_time;
3641   gchar       status_str[100];
3642   int         progbar_nextstep;
3643   int         progbar_quantum;
3644   char       *title;
3645
3646   start_fd = cf->current_frame;
3647   if (start_fd != NULL)  {
3648     /* Iterate through the list of packets, starting at the packet we've
3649        picked, calling a routine to run the filter on the packet, see if
3650        it matches, and stop if so.  */
3651     count = 0;
3652     fdata = start_fd;
3653
3654     /* Update the progress bar when it gets to this value. */
3655     progbar_nextstep = 0;
3656     /* When we reach the value that triggers a progress bar update,
3657        bump that value by this amount. */
3658     progbar_quantum = cf->count/N_PROGBAR_UPDATES;
3659     /* Progress so far. */
3660     progbar_val = 0.0f;
3661
3662     stop_flag = FALSE;
3663     g_get_current_time(&start_time);
3664
3665     fdata = start_fd;
3666     title = cf->sfilter?cf->sfilter:"";
3667     for (;;) {
3668       /* Create the progress bar if necessary.
3669          We check on every iteration of the loop, so that it takes no
3670          longer than the standard time to create it (otherwise, for a
3671          large file, we might take considerably longer than that standard
3672          time in order to get to the next progress bar step). */
3673       if (progbar == NULL)
3674          progbar = delayed_create_progress_dlg("Searching", title,
3675            FALSE, &stop_flag, &start_time, progbar_val);
3676
3677       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
3678          when we update it, we have to run the GTK+ main loop to get it
3679          to repaint what's pending, and doing so may involve an "ioctl()"
3680          to see if there's any pending input from an X server, and doing
3681          that for every packet can be costly, especially on a big file. */
3682       if (count >= progbar_nextstep) {
3683         /* let's not divide by zero. I should never be started
3684          * with count == 0, so let's assert that
3685          */
3686         g_assert(cf->count > 0);
3687
3688         progbar_val = (gfloat) count / cf->count;
3689
3690         if (progbar != NULL) {
3691           g_snprintf(status_str, sizeof(status_str),
3692                      "%4u of %u packets", count, cf->count);
3693           update_progress_dlg(progbar, progbar_val, status_str);
3694         }
3695
3696         progbar_nextstep += progbar_quantum;
3697       }
3698
3699       if (stop_flag) {
3700         /* Well, the user decided to abort the search.  Go back to the
3701            frame where we started. */
3702         new_fd = start_fd;
3703         break;
3704       }
3705
3706       /* Go past the current frame. */
3707       if (cf->sbackward) {
3708         /* Go on to the previous frame. */
3709         fdata = fdata->prev;
3710         if (fdata == NULL) {
3711           /*
3712            * XXX - other apps have a bit more of a detailed message
3713            * for this, and instead of offering "OK" and "Cancel",
3714            * they offer things such as "Continue" and "Cancel";
3715            * we need an API for popping up alert boxes with
3716            * {Verb} and "Cancel".
3717            */
3718
3719           if (prefs.gui_find_wrap)
3720           {
3721               simple_status("Search reached the beginning. Continuing at end.");
3722               fdata = cf->plist_end;    /* wrap around */
3723           }
3724           else
3725           {
3726               simple_status("Search reached the beginning.");
3727               fdata = start_fd;        /* stay on previous packet */
3728           }
3729         }
3730       } else {
3731         /* Go on to the next frame. */
3732         fdata = fdata->next;
3733         if (fdata == NULL) {
3734           if (prefs.gui_find_wrap)
3735           {
3736               simple_status("Search reached the end. Continuing at beginning.");
3737               fdata = cf->plist_start;    /* wrap around */
3738           }
3739           else
3740           {
3741               simple_status("Search reached the end.");
3742               fdata = start_fd;     /* stay on previous packet */
3743           }
3744         }
3745       }
3746
3747       count++;
3748
3749       /* Is this packet in the display? */
3750       if (fdata->flags.passed_dfilter) {
3751         /* Yes.  Load its data. */
3752         if (!wtap_seek_read(cf->wth, fdata->file_off, &cf->pseudo_header,
3753                 cf->pd, fdata->cap_len, &err, &err_info)) {
3754           /* Read error.  Report the error, and go back to the frame
3755              where we started. */
3756           simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3757             cf_read_error_message(err, err_info), cf->filename);
3758           new_fd = start_fd;
3759           break;
3760         }
3761
3762     /* Does it match the search criterion? */
3763     if ((*match_function)(cf, fdata, criterion)) {
3764           new_fd = fdata;
3765           break;    /* found it! */
3766         }
3767       }
3768
3769       if (fdata == start_fd) {
3770         /* We're back to the frame we were on originally, and that frame
3771        doesn't match the search filter.  The search failed. */
3772         break;
3773       }
3774     }
3775
3776     /* We're done scanning the packets; destroy the progress bar if it
3777        was created. */
3778     if (progbar != NULL)
3779       destroy_progress_dlg(progbar);
3780   }
3781
3782   if (new_fd != NULL) {
3783 #ifdef NEW_PACKET_LIST
3784       /* Find and select */
3785       row = new_packet_list_find_row_from_data(fdata, TRUE);
3786 #else
3787     /* We found a frame.  Find what row it's in. */
3788     row = packet_list_find_row_from_data(new_fd);
3789 #endif /* NEW_PACKET_LIST */
3790     if (row == -1) {
3791         /* We didn't find a row even though we know that a frame
3792          * exists that satifies the search criteria. This means that the
3793          * frame isn't being displayed currently so we can't select it. */
3794         simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3795                       "%sEnd of capture exceeded!%s\n\n"
3796                       "The capture file is probably not fully loaded.",
3797                       simple_dialog_primary_start(), simple_dialog_primary_end());
3798         return FALSE;
3799     }
3800
3801 #ifndef NEW_PACKET_LIST
3802     /* Select that row, make it the focus row, and make it visible. */
3803     packet_list_set_selected_row(row);
3804 #endif /* NEW_PACKET_LIST */
3805     return TRUE;    /* success */
3806   } else
3807     return FALSE;   /* failure */
3808 }
3809
3810 gboolean
3811 cf_goto_frame(capture_file *cf, guint fnumber)
3812 {
3813   frame_data *fdata;
3814   int row;
3815
3816   for (fdata = cf->plist_start; fdata != NULL && fdata->num < fnumber; fdata = fdata->next)
3817     ;
3818
3819   if (fdata == NULL) {
3820     /* we didn't find a packet with that packet number */
3821     simple_status("There is no packet number %u.", fnumber);
3822     return FALSE;   /* we failed to go to that packet */
3823   }
3824   if (!fdata->flags.passed_dfilter) {
3825     /* that packet currently isn't displayed */
3826     /* XXX - add it to the set of displayed packets? */
3827     simple_status("Packet number %u isn't displayed.", fnumber);
3828     return FALSE;   /* we failed to go to that packet */
3829   }
3830
3831 #ifdef NEW_PACKET_LIST
3832   row = new_packet_list_find_row_from_data(fdata, TRUE);
3833 #else
3834   /* We found that packet, and it's currently being displayed.
3835      Find what row it's in. */
3836   row = packet_list_find_row_from_data(fdata);
3837   g_assert(row != -1);
3838
3839   /* Select that row, make it the focus row, and make it visible. */
3840   packet_list_set_selected_row(row);
3841 #endif /* NEW_PACKET_LIST */
3842   return TRUE;  /* we got to that packet */
3843 }
3844
3845 gboolean
3846 cf_goto_top_frame(capture_file *cf _U_)
3847 {
3848 #ifdef NEW_PACKET_LIST
3849   /* Find and select */
3850   new_packet_list_select_first_row();
3851 #else
3852   frame_data *fdata;
3853   int row;
3854   frame_data *lowest_fdata = NULL;
3855
3856   for (fdata = cf->plist_start; fdata != NULL; fdata = fdata->next) {
3857     if (fdata->flags.passed_dfilter) {
3858         lowest_fdata = fdata;
3859         break;
3860     }
3861   }
3862
3863   if (lowest_fdata == NULL) {
3864       return FALSE;
3865   }
3866
3867   /* We found that packet, and it's currently being displayed.
3868      Find what row it's in. */
3869   row = packet_list_find_row_from_data(lowest_fdata);
3870   g_assert(row != -1);
3871
3872   /* Select that row, make it the focus row, and make it visible. */
3873   packet_list_set_selected_row(row);
3874 #endif /* NEW_PACKET_LIST */
3875   return TRUE;  /* we got to that packet */
3876 }
3877
3878 gboolean
3879 cf_goto_bottom_frame(capture_file *cf _U_) /* cf is unused w/ NEW_PACKET_LIST */
3880 {
3881 #ifdef NEW_PACKET_LIST
3882   /* Find and select */
3883   new_packet_list_select_last_row();
3884 #else
3885   frame_data *fdata;
3886   int row;
3887   frame_data *highest_fdata = NULL;
3888
3889   for (fdata = cf->plist_start; fdata != NULL; fdata = fdata->next) {
3890     if (fdata->flags.passed_dfilter) {
3891         highest_fdata = fdata;
3892     }
3893   }
3894
3895   if (highest_fdata == NULL) {
3896       return FALSE;
3897   }
3898
3899   /* We found that packet, and it's currently being displayed.
3900      Find what row it's in. */
3901   row = packet_list_find_row_from_data(highest_fdata);
3902   g_assert(row != -1);
3903
3904   /* Select that row, make it the focus row, and make it visible. */
3905   packet_list_set_selected_row(row);
3906 #endif /* NEW_PACKET_LIST */
3907   return TRUE;  /* we got to that packet */
3908 }
3909
3910 /*
3911  * Go to frame specified by currently selected protocol tree item.
3912  */
3913 gboolean
3914 cf_goto_framenum(capture_file *cf)
3915 {
3916   header_field_info       *hfinfo;
3917   guint32                 framenum;
3918
3919   if (cf->finfo_selected) {
3920     hfinfo = cf->finfo_selected->hfinfo;
3921     g_assert(hfinfo);
3922     if (hfinfo->type == FT_FRAMENUM) {
3923       framenum = fvalue_get_uinteger(&cf->finfo_selected->value);
3924       if (framenum != 0)
3925         return cf_goto_frame(cf, framenum);
3926       }
3927   }
3928
3929   return FALSE;
3930 }
3931
3932 /* Select the packet on a given row. */
3933 void
3934 cf_select_packet(capture_file *cf, int row)
3935 {
3936   frame_data *fdata;
3937   int err;
3938   gchar *err_info;
3939
3940   /* Get the frame data struct pointer for this frame */
3941 #ifdef NEW_PACKET_LIST
3942   fdata = new_packet_list_get_row_data(row);
3943 #else
3944   fdata = (frame_data *)packet_list_get_row_data(row);
3945 #endif
3946
3947   if (fdata == NULL) {
3948     /* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
3949        the first entry is added to it by "real_insert_row()", that row
3950        is selected (see "real_insert_row()", in "gtk/gtkclist.c", in both
3951        our version and the vanilla GTK+ version).
3952
3953        This means that a "select-row" signal is emitted; this causes
3954        "packet_list_select_cb()" to be called, which causes "cf_select_packet()"
3955        to be called.
3956
3957        "cf_select_packet()" fetches, above, the data associated with the
3958        row that was selected; however, as "gtk_clist_append()", which
3959        called "real_insert_row()", hasn't yet returned, we haven't yet
3960        associated any data with that row, so we get back a null pointer.
3961
3962        We can't assume that there's only one frame in the frame list,
3963        either, as we may be filtering the display.
3964
3965        We therefore assume that, if "row" is 0, i.e. the first row
3966        is being selected, and "cf->first_displayed" equals
3967        "cf->last_displayed", i.e. there's only one frame being
3968        displayed, that frame is the frame we want.
3969
3970        This means we have to set "cf->first_displayed" and
3971        "cf->last_displayed" before adding the row to the
3972        GtkCList; see the comment in "add_packet_to_packet_list()". */
3973
3974        if (row == 0 && cf->first_displayed == cf->last_displayed)
3975          fdata = cf->first_displayed;
3976   }
3977
3978   /* If fdata _still_ isn't set simply give up. */
3979   if (fdata == NULL) {
3980     return;
3981   }
3982
3983   /* Get the data in that frame. */
3984   if (!wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
3985                cf->pd, fdata->cap_len, &err, &err_info)) {
3986     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3987           cf_read_error_message(err, err_info), cf->filename);
3988     return;
3989   }
3990
3991   /* Record that this frame is the current frame. */
3992   cf->current_frame = fdata;
3993   cf->current_row = row;
3994
3995   /* Create the logical protocol tree. */
3996   if (cf->edt != NULL)
3997     epan_dissect_free(cf->edt);
3998
3999   /* We don't need the columns here. */
4000   cf->edt = epan_dissect_new(TRUE, TRUE);
4001
4002   tap_build_interesting(cf->edt);
4003   epan_dissect_run(cf->edt, &cf->pseudo_header, cf->pd, cf->current_frame,
4004           NULL);
4005
4006   dfilter_macro_build_ftv_cache(cf->edt->tree);
4007
4008   cf_callback_invoke(cf_cb_packet_selected, cf);
4009 }
4010
4011 /* Unselect the selected packet, if any. */
4012 void
4013 cf_unselect_packet(capture_file *cf)
4014 {
4015   /* Destroy the epan_dissect_t for the unselected packet. */
4016   if (cf->edt != NULL) {
4017     epan_dissect_free(cf->edt);
4018     cf->edt = NULL;
4019   }
4020
4021   /* No packet is selected. */
4022   cf->current_frame = NULL;
4023   cf->current_row = 0;
4024
4025   cf_callback_invoke(cf_cb_packet_unselected, cf);
4026
4027   /* No protocol tree means no selected field. */
4028   cf_unselect_field(cf);
4029 }
4030
4031 /* Unset the selected protocol tree field, if any. */
4032 void
4033 cf_unselect_field(capture_file *cf)
4034 {
4035   cf->finfo_selected = NULL;
4036
4037   cf_callback_invoke(cf_cb_field_unselected, cf);
4038 }
4039
4040 /*
4041  * Mark a particular frame.
4042  */
4043 void
4044 cf_mark_frame(capture_file *cf, frame_data *frame)
4045 {
4046   if (! frame->flags.marked) {
4047     frame->flags.marked = TRUE;
4048     if (cf->count > cf->marked_count)
4049       cf->marked_count++;
4050   }
4051 }
4052
4053 /*
4054  * Unmark a particular frame.
4055  */
4056 void
4057 cf_unmark_frame(capture_file *cf, frame_data *frame)
4058 {
4059   if (frame->flags.marked) {
4060     frame->flags.marked = FALSE;
4061     if (cf->marked_count > 0)
4062       cf->marked_count--;
4063   }
4064 }
4065
4066 typedef struct {
4067   wtap_dumper *pdh;
4068   const char  *fname;
4069 } save_callback_args_t;
4070
4071 /*
4072  * Save a capture to a file, in a particular format, saving either
4073  * all packets, all currently-displayed packets, or all marked packets.
4074  *
4075  * Returns TRUE if it succeeds, FALSE otherwise; if it fails, it pops
4076  * up a message box for the failure.
4077  */
4078 static gboolean
4079 save_packet(capture_file *cf _U_, frame_data *fdata,
4080             union wtap_pseudo_header *pseudo_header, const guint8 *pd,
4081             void *argsp)
4082 {
4083   save_callback_args_t *args = argsp;
4084   struct wtap_pkthdr hdr;
4085   int           err;
4086
4087   /* init the wtap header for saving */
4088   hdr.ts.secs    = fdata->abs_ts.secs;
4089   hdr.ts.nsecs   = fdata->abs_ts.nsecs;
4090   hdr.caplen     = fdata->cap_len;
4091   hdr.len        = fdata->pkt_len;
4092   hdr.pkt_encap  = fdata->lnk_t;
4093
4094   /* and save the packet */
4095   if (!wtap_dump(args->pdh, &hdr, pseudo_header, pd, &err)) {
4096     cf_write_failure_alert_box(args->fname, err);
4097     return FALSE;
4098   }
4099   return TRUE;
4100 }
4101
4102 /*
4103  * Can this capture file be saved in any format except by copying the raw data?
4104  */
4105 gboolean
4106 cf_can_save_as(capture_file *cf)
4107 {
4108   int ft;
4109
4110   for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
4111     /* To save a file with Wiretap, Wiretap has to handle that format,
4112        and its code to handle that format must be able to write a file
4113        with this file's encapsulation type. */
4114     if (wtap_dump_can_open(ft) && wtap_dump_can_write_encap(ft, cf->lnk_t)) {
4115       /* OK, we can write it out in this type. */
4116       return TRUE;
4117     }
4118   }
4119
4120   /* No, we couldn't save it in any format. */
4121   return FALSE;
4122 }
4123
4124 cf_status_t
4125 cf_save(capture_file *cf, const char *fname, packet_range_t *range, guint save_format, gboolean compressed)
4126 {
4127   gchar        *from_filename;
4128   int           err;
4129   gboolean      do_copy;
4130   wtap_dumper  *pdh;
4131   save_callback_args_t callback_args;
4132
4133   cf_callback_invoke(cf_cb_file_safe_started, (gpointer) fname);
4134
4135   /* don't write over an existing file. */
4136   /* this should've been already checked by our caller, just to be sure... */
4137   if (file_exists(fname)) {
4138     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4139       "%sCapture file: \"%s\" already exists!%s\n\n"
4140       "Please choose a different filename.",
4141       simple_dialog_primary_start(), fname, simple_dialog_primary_end());
4142     goto fail;
4143   }
4144
4145   packet_range_process_init(range);
4146
4147
4148   if (packet_range_process_all(range) && save_format == cf->cd_t) {
4149     /* We're not filtering packets, and we're saving it in the format
4150        it's already in, so we can just move or copy the raw data. */
4151
4152     if (cf->is_tempfile) {
4153       /* The file being saved is a temporary file from a live
4154          capture, so it doesn't need to stay around under that name;
4155      first, try renaming the capture buffer file to the new name. */
4156 #ifndef _WIN32
4157       if (ws_rename(cf->filename, fname) == 0) {
4158         /* That succeeded - there's no need to copy the source file. */
4159         from_filename = NULL;
4160     do_copy = FALSE;
4161       } else {
4162         if (errno == EXDEV) {
4163       /* They're on different file systems, so we have to copy the
4164          file. */
4165       do_copy = TRUE;
4166           from_filename = cf->filename;
4167     } else {
4168       /* The rename failed, but not because they're on different
4169          file systems - put up an error message.  (Or should we
4170          just punt and try to copy?  The only reason why I'd
4171          expect the rename to fail and the copy to succeed would
4172          be if we didn't have permission to remove the file from
4173          the temporary directory, and that might be fixable - but
4174          is it worth requiring the user to go off and fix it?) */
4175       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4176                 file_rename_error_message(errno), fname);
4177       goto fail;
4178     }
4179       }
4180 #else
4181       do_copy = TRUE;
4182       from_filename = cf->filename;
4183 #endif
4184     } else {
4185       /* It's a permanent file, so we should copy it, and not remove the
4186          original. */
4187       do_copy = TRUE;
4188       from_filename = cf->filename;
4189     }
4190
4191     if (do_copy) {
4192       /* Copy the file, if we haven't moved it. */
4193       if (!copy_file_binary_mode(from_filename, fname))
4194     goto fail;
4195     }
4196   } else {
4197     /* Either we're filtering packets, or we're saving in a different
4198        format; we can't do that by copying or moving the capture file,
4199        we have to do it by writing the packets out in Wiretap. */
4200     pdh = wtap_dump_open(fname, save_format, cf->lnk_t, cf->snap,
4201         compressed, &err);
4202     if (pdh == NULL) {
4203       cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
4204       goto fail;
4205     }
4206
4207     /* XXX - we let the user save a subset of the packets.
4208
4209        If we do that, should we make that file the current file?  If so,
4210        it means we can no longer get at the other packets.  What does
4211        NetMon do? */
4212
4213     /* Iterate through the list of packets, processing the packets we were
4214        told to process.
4215
4216        XXX - we've already called "packet_range_process_init(range)", but
4217        "process_specified_packets()" will do it again.  Fortunately,
4218        that's harmless in this case, as we haven't done anything to
4219        "range" since we initialized it. */
4220     callback_args.pdh = pdh;
4221     callback_args.fname = fname;
4222     switch (process_specified_packets(cf, range, "Saving", "selected packets",
4223                                       TRUE, save_packet, &callback_args)) {
4224
4225     case PSP_FINISHED:
4226       /* Completed successfully. */
4227       break;
4228
4229     case PSP_STOPPED:
4230       /* The user decided to abort the saving.
4231          XXX - remove the output file? */
4232       break;
4233
4234     case PSP_FAILED:
4235       /* Error while saving. */
4236       wtap_dump_close(pdh, &err);
4237       goto fail;
4238     }
4239
4240     if (!wtap_dump_close(pdh, &err)) {
4241       cf_close_failure_alert_box(fname, err);
4242       goto fail;
4243     }
4244   }
4245
4246   cf_callback_invoke(cf_cb_file_safe_finished, NULL);
4247
4248   if (packet_range_process_all(range)) {
4249     /* We saved the entire capture, not just some packets from it.
4250        Open and read the file we saved it to.
4251
4252        XXX - this is somewhat of a waste; we already have the
4253        packets, all this gets us is updated file type information
4254        (which we could just stuff into "cf"), and having the new
4255        file be the one we have opened and from which we're reading
4256        the data, and it means we have to spend time opening and
4257        reading the file, which could be a significant amount of
4258        time if the file is large. */
4259     cf->user_saved = TRUE;
4260
4261     if ((cf_open(cf, fname, FALSE, &err)) == CF_OK) {
4262       /* XXX - report errors if this fails?
4263          What should we return if it fails or is aborted? */
4264       switch (cf_read(cf)) {
4265
4266       case CF_READ_OK:
4267       case CF_READ_ERROR:
4268     /* Just because we got an error, that doesn't mean we were unable
4269        to read any of the file; we handle what we could get from the
4270        file. */
4271     break;
4272
4273       case CF_READ_ABORTED:
4274     /* The user bailed out of re-reading the capture file; the
4275        capture file has been closed - just return (without
4276        changing any menu settings; "cf_close()" set them
4277        correctly for the "no capture file open" state). */
4278     break;
4279       }
4280       cf_callback_invoke(cf_cb_file_safe_reload_finished, NULL);
4281     }
4282   }
4283   return CF_OK;
4284
4285 fail:
4286   cf_callback_invoke(cf_cb_file_safe_failed, NULL);
4287   return CF_ERROR;
4288 }
4289
4290 static void
4291 cf_open_failure_alert_box(const char *filename, int err, gchar *err_info,
4292                           gboolean for_writing, int file_type)
4293 {
4294   if (err < 0) {
4295     /* Wiretap error. */
4296     switch (err) {
4297
4298     case WTAP_ERR_NOT_REGULAR_FILE:
4299       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4300             "The file \"%s\" is a \"special file\" or socket or other non-regular file.",
4301             filename);
4302       break;
4303
4304     case WTAP_ERR_RANDOM_OPEN_PIPE:
4305       /* Seen only when opening a capture file for reading. */
4306       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4307             "The file \"%s\" is a pipe or FIFO; Wireshark can't read pipe or FIFO files.",
4308             filename);
4309       break;
4310
4311     case WTAP_ERR_FILE_UNKNOWN_FORMAT:
4312       /* Seen only when opening a capture file for reading. */
4313       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4314             "The file \"%s\" isn't a capture file in a format Wireshark understands.",
4315             filename);
4316       break;
4317
4318     case WTAP_ERR_UNSUPPORTED:
4319       /* Seen only when opening a capture file for reading. */
4320       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4321             "The file \"%s\" isn't a capture file in a format Wireshark understands.\n"
4322             "(%s)",
4323             filename, err_info);
4324       g_free(err_info);
4325       break;
4326
4327     case WTAP_ERR_CANT_WRITE_TO_PIPE:
4328       /* Seen only when opening a capture file for writing. */
4329       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4330             "The file \"%s\" is a pipe, and %s capture files can't be "
4331             "written to a pipe.",
4332             filename, wtap_file_type_string(file_type));
4333       break;
4334
4335     case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
4336       /* Seen only when opening a capture file for writing. */
4337       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4338             "Wireshark doesn't support writing capture files in that format.");
4339       break;
4340
4341     case WTAP_ERR_UNSUPPORTED_ENCAP:
4342       if (for_writing) {
4343     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4344               "Wireshark can't save this capture in that format.");
4345       } else {
4346     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4347               "The file \"%s\" is a capture for a network type that Wireshark doesn't support.\n"
4348               "(%s)",
4349               filename, err_info);
4350         g_free(err_info);
4351       }
4352       break;
4353
4354     case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
4355       if (for_writing) {
4356     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4357               "Wireshark can't save this capture in that format.");
4358       } else {
4359     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4360               "The file \"%s\" is a capture for a network type that Wireshark doesn't support.",
4361               filename);
4362       }
4363       break;
4364
4365     case WTAP_ERR_BAD_RECORD:
4366       /* Seen only when opening a capture file for reading. */
4367       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4368             "The file \"%s\" appears to be damaged or corrupt.\n"
4369             "(%s)",
4370             filename, err_info);
4371       g_free(err_info);
4372       break;
4373
4374     case WTAP_ERR_CANT_OPEN:
4375       if (for_writing) {
4376     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4377               "The file \"%s\" could not be created for some unknown reason.",
4378               filename);
4379       } else {
4380     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4381               "The file \"%s\" could not be opened for some unknown reason.",
4382               filename);
4383       }
4384       break;
4385
4386     case WTAP_ERR_SHORT_READ:
4387       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4388             "The file \"%s\" appears to have been cut short"
4389             " in the middle of a packet or other data.",
4390             filename);
4391       break;
4392
4393     case WTAP_ERR_SHORT_WRITE:
4394       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4395             "A full header couldn't be written to the file \"%s\".",
4396             filename);
4397       break;
4398
4399     case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
4400       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4401             "Gzip compression not supported by this file type.");
4402       break;
4403
4404     default:
4405       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4406             "The file \"%s\" could not be %s: %s.",
4407             filename,
4408             for_writing ? "created" : "opened",
4409             wtap_strerror(err));
4410       break;
4411     }
4412   } else {
4413     /* OS error. */
4414     open_failure_alert_box(filename, err, for_writing);
4415   }
4416 }
4417
4418 static const char *
4419 file_rename_error_message(int err)
4420 {
4421   const char *errmsg;
4422   static char errmsg_errno[1024+1];
4423
4424   switch (err) {
4425
4426   case ENOENT:
4427     errmsg = "The path to the file \"%s\" doesn't exist.";
4428     break;
4429
4430   case EACCES:
4431     errmsg = "You don't have permission to move the capture file to \"%s\".";
4432     break;
4433
4434   default:
4435     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
4436             "The file \"%%s\" could not be moved: %s.",
4437                 wtap_strerror(err));
4438     errmsg = errmsg_errno;
4439     break;
4440   }
4441   return errmsg;
4442 }
4443
4444 char *
4445 cf_read_error_message(int err, gchar *err_info)
4446 {
4447   static char errmsg_errno[1024+1];
4448
4449   switch (err) {
4450
4451   case WTAP_ERR_UNSUPPORTED_ENCAP:
4452     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
4453                "The file \"%%s\" has a packet with a network type that Wireshark doesn't support.\n(%s)",
4454                err_info);
4455     g_free(err_info);
4456     break;
4457
4458   case WTAP_ERR_BAD_RECORD:
4459     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
4460          "An error occurred while reading from the file \"%%s\": %s.\n(%s)",
4461          wtap_strerror(err), err_info);
4462     g_free(err_info);
4463     break;
4464
4465   default:
4466     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
4467          "An error occurred while reading from the file \"%%s\": %s.",
4468          wtap_strerror(err));
4469     break;
4470   }
4471   return errmsg_errno;
4472 }
4473
4474 static void
4475 cf_write_failure_alert_box(const char *filename, int err)
4476 {
4477   if (err < 0) {
4478     /* Wiretap error. */
4479     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4480           "An error occurred while writing to the file \"%s\": %s.",
4481           filename, wtap_strerror(err));
4482   } else {
4483     /* OS error. */
4484     write_failure_alert_box(filename, err);
4485   }
4486 }
4487
4488 /* Check for write errors - if the file is being written to an NFS server,
4489    a write error may not show up until the file is closed, as NFS clients
4490    might not send writes to the server until the "write()" call finishes,
4491    so that the write may fail on the server but the "write()" may succeed. */
4492 static void
4493 cf_close_failure_alert_box(const char *filename, int err)
4494 {
4495   if (err < 0) {
4496     /* Wiretap error. */
4497     switch (err) {
4498
4499     case WTAP_ERR_CANT_CLOSE:
4500       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4501             "The file \"%s\" couldn't be closed for some unknown reason.",
4502             filename);
4503       break;
4504
4505     case WTAP_ERR_SHORT_WRITE:
4506       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4507             "Not all the packets could be written to the file \"%s\".",
4508                     filename);
4509       break;
4510
4511     default:
4512       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4513             "An error occurred while closing the file \"%s\": %s.",
4514             filename, wtap_strerror(err));
4515       break;
4516     }
4517   } else {
4518     /* OS error.
4519        We assume that a close error from the OS is really a write error. */
4520     write_failure_alert_box(filename, err);
4521   }
4522 }
4523
4524 /* Reload the current capture file. */
4525 void
4526 cf_reload(capture_file *cf) {
4527   gchar *filename;
4528   gboolean is_tempfile;
4529   int err;
4530
4531   /* If the file could be opened, "cf_open()" calls "cf_close()"
4532      to get rid of state for the old capture file before filling in state
4533      for the new capture file.  "cf_close()" will remove the file if
4534      it's a temporary file; we don't want that to happen (for one thing,
4535      it'd prevent subsequent reopens from working).  Remember whether it's
4536      a temporary file, mark it as not being a temporary file, and then
4537      reopen it as the type of file it was.
4538
4539      Also, "cf_close()" will free "cf->filename", so we must make
4540      a copy of it first. */
4541   filename = g_strdup(cf->filename);
4542   is_tempfile = cf->is_tempfile;
4543   cf->is_tempfile = FALSE;
4544   if (cf_open(cf, filename, is_tempfile, &err) == CF_OK) {
4545     switch (cf_read(cf)) {
4546
4547     case CF_READ_OK:
4548     case CF_READ_ERROR:
4549       /* Just because we got an error, that doesn't mean we were unable
4550          to read any of the file; we handle what we could get from the
4551          file. */
4552       break;
4553
4554     case CF_READ_ABORTED:
4555       /* The user bailed out of re-reading the capture file; the
4556          capture file has been closed - just free the capture file name
4557          string and return (without changing the last containing
4558          directory). */
4559       g_free(filename);
4560       return;
4561     }
4562   } else {
4563     /* The open failed, so "cf->is_tempfile" wasn't set to "is_tempfile".
4564        Instead, the file was left open, so we should restore "cf->is_tempfile"
4565        ourselves.
4566
4567        XXX - change the menu?  Presumably "cf_open()" will do that;
4568        make sure it does! */
4569     cf->is_tempfile = is_tempfile;
4570   }
4571   /* "cf_open()" made a copy of the file name we handed it, so
4572      we should free up our copy. */
4573   g_free(filename);
4574 }