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