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