RNSAP updated to V7.5.0 (2007-06)
[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 "file_util.h"
79
80
81
82 #ifdef HAVE_LIBPCAP
83 gboolean auto_scroll_live;
84 #endif
85
86 static nstime_t first_ts;
87 static nstime_t prev_dis_ts;
88 static guint32 cum_bytes = 0;
89
90 static void cf_reset_state(capture_file *cf);
91
92 static int read_packet(capture_file *cf, dfilter_t *dfcode, gint64 offset);
93
94 static void rescan_packets(capture_file *cf, const char *action, const char *action_item,
95         gboolean refilter, gboolean redissect);
96
97 static gboolean match_protocol_tree(capture_file *cf, frame_data *fdata,
98         void *criterion);
99 static void match_subtree_text(proto_node *node, gpointer data);
100 static gboolean match_summary_line(capture_file *cf, frame_data *fdata,
101         void *criterion);
102 static gboolean match_ascii_and_unicode(capture_file *cf, frame_data *fdata,
103         void *criterion);
104 static gboolean match_ascii(capture_file *cf, frame_data *fdata,
105         void *criterion);
106 static gboolean match_unicode(capture_file *cf, frame_data *fdata,
107         void *criterion);
108 static gboolean match_binary(capture_file *cf, frame_data *fdata,
109         void *criterion);
110 static gboolean match_dfilter(capture_file *cf, frame_data *fdata,
111         void *criterion);
112 static gboolean find_packet(capture_file *cf,
113         gboolean (*match_function)(capture_file *, frame_data *, void *),
114         void *criterion);
115
116 static void cf_open_failure_alert_box(const char *filename, int err,
117                                       gchar *err_info, gboolean for_writing,
118                                       int file_type);
119 static const char *file_rename_error_message(int err);
120 static void cf_write_failure_alert_box(const char *filename, int err);
121 static void cf_close_failure_alert_box(const char *filename, int err);
122 static   gboolean copy_binary_file(const char *from_filename, const char *to_filename);
123
124 /* Update the progress bar this many times when reading a file. */
125 #define N_PROGBAR_UPDATES       100
126
127 /* Number of "frame_data" structures per memory chunk.
128    XXX - is this the right number? */
129 #define FRAME_DATA_CHUNK_SIZE   1024
130
131
132 /* one callback for now, we could have a list later */
133 static cf_callback_t cf_cb = NULL;
134 static gpointer cf_cb_user_data = NULL;
135
136 void
137 cf_callback_invoke(int event, gpointer data)
138 {
139     g_assert(cf_cb != NULL);
140     cf_cb(event, data, cf_cb_user_data);
141 }
142
143
144 void
145 cf_callback_add(cf_callback_t func, gpointer user_data)
146 {
147     /* More than one callback listener is currently not implemented,
148        but should be easy to do. */
149     g_assert(cf_cb == NULL);
150     cf_cb = func;
151     cf_cb_user_data = user_data;
152 }
153
154 void
155 cf_callback_remove(cf_callback_t func _U_)
156 {
157     g_assert(cf_cb != NULL);
158     cf_cb = NULL;
159     cf_cb_user_data = NULL;
160 }
161
162 void
163 cf_timestamp_auto_precision(capture_file *cf)
164 {
165         int prec = timestamp_get_precision();
166
167
168         /* don't try to get the file's precision if none is opened */
169         if(cf->state == FILE_CLOSED) {
170                 return;
171         }
172
173         /* if we are in auto mode, set precision of current file */
174         if(prec == TS_PREC_AUTO ||
175           prec == TS_PREC_AUTO_SEC ||
176           prec == TS_PREC_AUTO_DSEC ||
177           prec == TS_PREC_AUTO_CSEC ||
178           prec == TS_PREC_AUTO_MSEC ||
179           prec == TS_PREC_AUTO_USEC ||
180           prec == TS_PREC_AUTO_NSEC)
181         {
182                 switch(wtap_file_tsprecision(cf->wth)) {
183                 case(WTAP_FILE_TSPREC_SEC):
184                         timestamp_set_precision(TS_PREC_AUTO_SEC);
185                         break;
186                 case(WTAP_FILE_TSPREC_DSEC):
187                         timestamp_set_precision(TS_PREC_AUTO_DSEC);
188                         break;
189                 case(WTAP_FILE_TSPREC_CSEC):
190                         timestamp_set_precision(TS_PREC_AUTO_CSEC);
191                         break;
192                 case(WTAP_FILE_TSPREC_MSEC):
193                         timestamp_set_precision(TS_PREC_AUTO_MSEC);
194                         break;
195                 case(WTAP_FILE_TSPREC_USEC):
196                         timestamp_set_precision(TS_PREC_AUTO_USEC);
197                         break;
198                 case(WTAP_FILE_TSPREC_NSEC):
199                         timestamp_set_precision(TS_PREC_AUTO_NSEC);
200                         break;
201                 default:
202                         g_assert_not_reached();
203                 }
204         }
205 }
206
207
208 cf_status_t
209 cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
210 {
211   wtap       *wth;
212   gchar       *err_info;
213
214   wth = wtap_open_offline(fname, err, &err_info, TRUE);
215   if (wth == NULL)
216     goto fail;
217
218   /* The open succeeded.  Close whatever capture file we had open,
219      and fill in the information for this file. */
220   cf_reset_state(cf);
221
222   /* Initialize all data structures used for dissection. */
223   init_dissection();
224
225   /* We're about to start reading the file. */
226   cf->state = FILE_READ_IN_PROGRESS;
227
228   cf->wth = wth;
229   cf->f_datalen = 0;
230
231   /* Set the file name because we need it to set the follow stream filter.
232      XXX - is that still true?  We need it for other reasons, though,
233      in any case. */
234   cf->filename = g_strdup(fname);
235
236   /* Indicate whether it's a permanent or temporary file. */
237   cf->is_tempfile = is_tempfile;
238
239   /* If it's a temporary capture buffer file, mark it as not saved. */
240   cf->user_saved = !is_tempfile;
241
242   cf->cd_t        = wtap_file_type(cf->wth);
243   cf->count     = 0;
244   cf->displayed_count = 0;
245   cf->marked_count = 0;
246   cf->drops_known = FALSE;
247   cf->drops     = 0;
248   cf->snap      = wtap_snapshot_length(cf->wth);
249   if (cf->snap == 0) {
250     /* Snapshot length not known. */
251     cf->has_snap = FALSE;
252     cf->snap = WTAP_MAX_PACKET_SIZE;
253   } else
254     cf->has_snap = TRUE;
255   nstime_set_zero(&cf->elapsed_time);
256   nstime_set_unset(&first_ts);
257   nstime_set_unset(&prev_dis_ts);
258
259   cf->plist_chunk = g_mem_chunk_new("frame_data_chunk",
260         sizeof(frame_data),
261         FRAME_DATA_CHUNK_SIZE * sizeof(frame_data),
262         G_ALLOC_AND_FREE);
263   g_assert(cf->plist_chunk);
264
265   /* change the time formats now, as we might have a new precision */
266   cf_change_time_formats(cf);
267
268   fileset_file_opened(fname);
269
270   if(cf->cd_t == WTAP_FILE_BER) {
271     /* tell the BER dissector the file name */
272     ber_set_filename(cf->filename);
273   }
274
275   return CF_OK;
276
277 fail:
278   cf_open_failure_alert_box(fname, *err, err_info, FALSE, 0);
279   return CF_ERROR;
280 }
281
282
283 /*
284  * Reset the state for the currently closed file, but don't do the
285  * UI callbacks; this is for use in "cf_open()", where we don't
286  * want the UI to go from "file open" to "file closed" back to
287  * "file open", we want it to go from "old file open" to "new file
288  * open and being read".
289  */
290 static void
291 cf_reset_state(capture_file *cf)
292 {
293   /* Die if we're in the middle of reading a file. */
294   g_assert(cf->state != FILE_READ_IN_PROGRESS);
295
296   if (cf->wth) {
297     wtap_close(cf->wth);
298     cf->wth = NULL;
299   }
300   /* We have no file open... */
301   if (cf->filename != NULL) {
302     /* If it's a temporary file, remove it. */
303     if (cf->is_tempfile)
304       eth_unlink(cf->filename);
305     g_free(cf->filename);
306     cf->filename = NULL;
307   }
308   /* ...which means we have nothing to save. */
309   cf->user_saved = FALSE;
310
311   if (cf->plist_chunk != NULL) {
312     g_mem_chunk_destroy(cf->plist_chunk);
313     cf->plist_chunk = NULL;
314   }
315   if (cf->rfcode != NULL) {
316     dfilter_free(cf->rfcode);
317     cf->rfcode = NULL;
318   }
319   cf->plist = NULL;
320   cf->plist_end = NULL;
321   cf_unselect_packet(cf);       /* nothing to select */
322   cf->first_displayed = NULL;
323   cf->last_displayed = NULL;
324
325   /* No frame selected, no field in that frame selected. */
326   cf->current_frame = NULL;
327   cf->finfo_selected = NULL;
328
329   /* Clear the packet list. */
330   packet_list_freeze();
331   packet_list_clear();
332   packet_list_thaw();
333
334   cf->f_datalen = 0;
335   cf->count = 0;
336   nstime_set_zero(&cf->elapsed_time);
337
338   reset_tap_listeners();
339
340   /* We have no file open. */
341   cf->state = FILE_CLOSED;
342
343   fileset_file_closed();
344 }
345
346 /* Reset everything to a pristine state */
347 void
348 cf_close(capture_file *cf)
349 {
350   /* do GUI things even if file is already closed,
351    * e.g. to cleanup things if a capture couldn't be started */
352   cf_callback_invoke(cf_cb_file_closing, cf);
353
354   /* close things, if not already closed before */
355   if(cf->state != FILE_CLOSED) {
356
357           color_filters_cleanup();
358
359           cf_reset_state(cf);
360
361           cleanup_dissection();
362   }
363
364   cf_callback_invoke(cf_cb_file_closed, cf);
365 }
366
367 /* an out of memory exception occured, wait for a user button press to exit */
368 void outofmemory_cb(gpointer dialog _U_, gint btn _U_, gpointer data _U_)
369 {
370     main_window_exit();
371 }
372
373 cf_read_status_t
374 cf_read(capture_file *cf)
375 {
376   int         err;
377   gchar       *err_info;
378   const gchar *name_ptr;
379   const char  *errmsg;
380   char         errmsg_errno[1024+1];
381   gchar        err_str[2048+1];
382   gint64       data_offset;
383   progdlg_t *volatile progbar = NULL;
384   gboolean     stop_flag;
385   volatile gint64 size;
386   gint64       file_pos;
387   volatile float progbar_val;
388   GTimeVal     start_time;
389   gchar        status_str[100];
390   volatile gint64 progbar_nextstep;
391   volatile gint64 progbar_quantum;
392   dfilter_t   *dfcode;
393
394   /* Compile the current display filter.
395    * We assume this will not fail since cf->dfilter is only set in 
396    * cf_filter IFF the filter was valid.
397    */
398   dfcode=NULL;
399   if(cf->dfilter){
400     dfilter_compile(cf->dfilter, &dfcode);
401   }
402
403   cum_bytes=0;
404
405   reset_tap_listeners();
406   tap_dfilter_dlg_update();
407
408   cf_callback_invoke(cf_cb_file_read_start, cf);
409
410   name_ptr = get_basename(cf->filename);
411
412   /* Find the size of the file. */
413   size = wtap_file_size(cf->wth, NULL);
414
415   /* Update the progress bar when it gets to this value. */
416   progbar_nextstep = 0;
417   /* When we reach the value that triggers a progress bar update,
418      bump that value by this amount. */
419   if (size >= 0)
420     progbar_quantum = size/N_PROGBAR_UPDATES;
421   else
422     progbar_quantum = 0;
423   /* Progress so far. */
424   progbar_val = 0.0;
425
426   packet_list_freeze();
427
428   stop_flag = FALSE;
429   g_get_current_time(&start_time);
430
431   while ((wtap_read(cf->wth, &err, &err_info, &data_offset))) {
432     if (size >= 0) {
433       /* Create the progress bar if necessary.
434          We check on every iteration of the loop, so that it takes no
435          longer than the standard time to create it (otherwise, for a
436          large file, we might take considerably longer than that standard
437          time in order to get to the next progress bar step). */
438       if (progbar == NULL) {
439         progbar = delayed_create_progress_dlg("Loading", name_ptr,
440           TRUE, &stop_flag, &start_time, progbar_val);
441       }
442
443       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
444          when we update it, we have to run the GTK+ main loop to get it
445          to repaint what's pending, and doing so may involve an "ioctl()"
446          to see if there's any pending input from an X server, and doing
447          that for every packet can be costly, especially on a big file. */
448       if (data_offset >= progbar_nextstep) {
449           file_pos = wtap_read_so_far(cf->wth, NULL);
450           progbar_val = (gfloat) file_pos / (gfloat) size;
451           if (progbar_val > 1.0) {
452             /* The file probably grew while we were reading it.
453                Update file size, and try again. */
454             size = wtap_file_size(cf->wth, NULL);
455             if (size >= 0)
456               progbar_val = (gfloat) file_pos / (gfloat) size;
457             /* If it's still > 1, either "wtap_file_size()" failed (in which
458                case there's not much we can do about it), or the file
459                *shrank* (in which case there's not much we can do about
460                it); just clip the progress value at 1.0. */
461             if (progbar_val > 1.0)
462               progbar_val = 1.0;
463           }
464           if (progbar != NULL) {
465                 /* update the packet lists content on the first run or frequently on very large files */
466               /* (on smaller files the display update takes longer than reading the file) */
467 #ifdef HAVE_LIBPCAP
468               if(progbar_quantum > 500000 || progbar_nextstep == 0) {
469             packet_list_thaw();
470             if (auto_scroll_live && cf->plist_end != NULL)
471               packet_list_moveto_end();
472             packet_list_freeze();
473               }
474 #endif
475
476             g_snprintf(status_str, sizeof(status_str),
477                        "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
478                        file_pos / 1024, size / 1024);
479             update_progress_dlg(progbar, progbar_val, status_str);
480           }
481          progbar_nextstep += progbar_quantum;
482       }
483     }
484
485     if (stop_flag) {
486       /* Well, the user decided to abort the read. He/She will be warned and
487          it might be enough for him/her to work with the already loaded
488          packets.
489          This is especially true for very large capture files, where you don't
490          want to wait loading the whole file (which may last minutes or even
491          hours even on fast machines) just to see that it was the wrong file. */
492       break;
493     }
494     TRY {
495         read_packet(cf, dfcode, data_offset);
496     }
497     CATCH(OutOfMemoryError) {
498         gpointer dialog;
499
500         dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
501               "%sOut Of Memory!%s\n"
502               "\n"
503               "Sorry, but Wireshark has to terminate now!\n"
504               "\n"
505               "Some infos / workarounds can be found at:\n"
506               "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
507               simple_dialog_primary_start(), simple_dialog_primary_end());
508         /* we have to terminate, as we cannot recover from the memory error */
509         simple_dialog_set_cb(dialog, outofmemory_cb, NULL);
510         while(1) {
511             main_window_update();
512             /* XXX - how to avoid a busy wait? */
513             /* Sleep(100); */
514         };
515         break;
516     }
517     ENDTRY;
518   }
519
520   /* Cleanup and release all dfilter resources */
521   if (dfcode != NULL){
522     dfilter_free(dfcode);
523   }
524
525   /* We're done reading the file; destroy the progress bar if it was created. */
526   if (progbar != NULL)
527     destroy_progress_dlg(progbar);
528
529   /* We're done reading sequentially through the file. */
530   cf->state = FILE_READ_DONE;
531
532   /* Close the sequential I/O side, to free up memory it requires. */
533   wtap_sequential_close(cf->wth);
534
535   /* Allow the protocol dissectors to free up memory that they
536    * don't need after the sequential run-through of the packets. */
537   postseq_cleanup_all_protocols();
538
539   /* Set the file encapsulation type now; we don't know what it is until
540      we've looked at all the packets, as we don't know until then whether
541      there's more than one type (and thus whether it's
542      WTAP_ENCAP_PER_PACKET). */
543   cf->lnk_t = wtap_file_encap(cf->wth);
544
545   cf->current_frame = cf->first_displayed;
546   packet_list_thaw();
547
548   cf_callback_invoke(cf_cb_file_read_finished, cf);
549
550   /* If we have any displayed packets to select, select the first of those
551      packets by making the first row the selected row. */
552   if (cf->first_displayed != NULL)
553     packet_list_select_row(0);
554
555   if(stop_flag) {
556     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
557           "%sFile loading was cancelled!%s\n"
558           "\n"
559                   "The remaining packets in the file were discarded.\n"
560           "\n"
561           "As a lot of packets from the original file will be missing,\n"
562                   "remember to be careful when saving the current content to a file.\n",
563           simple_dialog_primary_start(), simple_dialog_primary_end());
564     return CF_READ_ERROR;
565   }
566
567   if (err != 0) {
568     /* Put up a message box noting that the read failed somewhere along
569        the line.  Don't throw out the stuff we managed to read, though,
570        if any. */
571     switch (err) {
572
573     case WTAP_ERR_UNSUPPORTED_ENCAP:
574       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
575                "The capture file has a packet with a network type that Wireshark doesn't support.\n(%s)",
576                err_info);
577       g_free(err_info);
578       errmsg = errmsg_errno;
579       break;
580
581     case WTAP_ERR_CANT_READ:
582       errmsg = "An attempt to read from the capture file failed for"
583                " some unknown reason.";
584       break;
585
586     case WTAP_ERR_SHORT_READ:
587       errmsg = "The capture file appears to have been cut short"
588                " in the middle of a packet.";
589       break;
590
591     case WTAP_ERR_BAD_RECORD:
592       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
593                "The capture file appears to be damaged or corrupt.\n(%s)",
594                err_info);
595       g_free(err_info);
596       errmsg = errmsg_errno;
597       break;
598
599     default:
600       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
601                "An error occurred while reading the"
602                " capture file: %s.", wtap_strerror(err));
603       errmsg = errmsg_errno;
604       break;
605     }
606     g_snprintf(err_str, sizeof err_str, errmsg);
607     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, err_str);
608     return CF_READ_ERROR;
609   } else
610     return CF_READ_OK;
611 }
612
613 #ifdef HAVE_LIBPCAP
614 cf_status_t
615 cf_start_tail(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
616 {
617   cf_status_t cf_status;
618
619   cf_status = cf_open(cf, fname, is_tempfile, err);
620   return cf_status;
621 }
622
623 cf_read_status_t
624 cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
625 {
626   gint64 data_offset = 0;
627   gchar *err_info;
628   volatile int newly_displayed_packets = 0;
629   dfilter_t   *dfcode;
630   gboolean at_end;
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   at_end = packet_list_at_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 && at_end)
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   gboolean at_end;
733
734   /* Compile the current display filter.
735    * We assume this will not fail since cf->dfilter is only set in 
736    * cf_filter IFF the filter was valid.
737    */
738   dfcode=NULL;
739   if(cf->dfilter){
740     dfilter_compile(cf->dfilter, &dfcode);
741   }
742
743   if(cf->wth == NULL) {
744     cf_close(cf);
745     return CF_READ_ERROR;
746   }
747
748   at_end = packet_list_at_end();
749   packet_list_freeze();
750
751   while ((wtap_read(cf->wth, err, &err_info, &data_offset))) {
752     if (cf->state == FILE_READ_ABORTED) {
753       /* Well, the user decided to abort the read.  Break out of the
754          loop, and let the code below (which is called even if there
755          aren't any packets left to read) exit. */
756       break;
757     }
758         read_packet(cf, dfcode, data_offset);
759   }
760
761   /* Cleanup and release all dfilter resources */
762   if (dfcode != NULL){
763     dfilter_free(dfcode);
764   }
765
766   packet_list_thaw();
767
768   if (cf->state == FILE_READ_ABORTED) {
769     /* Well, the user decided to abort the read.  We're only called
770        when the child capture process closes the pipe to us (meaning
771        it's probably exited), so we can just close the capture
772        file; we return CF_READ_ABORTED so our caller can do whatever
773        is appropriate when that happens. */
774     cf_close(cf);
775     return CF_READ_ABORTED;
776   }
777
778   if (auto_scroll_live && cf->plist_end != NULL && at_end)
779     /* XXX - this cheats and looks inside the packet list to find the final
780        row number. */
781     packet_list_moveto_end();
782
783   /* We're done reading sequentially through the file. */
784   cf->state = FILE_READ_DONE;
785
786   /* We're done reading sequentially through the file; close the
787      sequential I/O side, to free up memory it requires. */
788   wtap_sequential_close(cf->wth);
789
790   /* Allow the protocol dissectors to free up memory that they
791    * don't need after the sequential run-through of the packets. */
792   postseq_cleanup_all_protocols();
793
794   /* Set the file encapsulation type now; we don't know what it is until
795      we've looked at all the packets, as we don't know until then whether
796      there's more than one type (and thus whether it's
797      WTAP_ENCAP_PER_PACKET). */
798   cf->lnk_t = wtap_file_encap(cf->wth);
799
800   if (*err != 0) {
801     /* We got an error reading the capture file.
802        XXX - pop up a dialog box? */
803     return CF_READ_ERROR;
804   } else {
805     return CF_READ_OK;
806   }
807 }
808 #endif /* HAVE_LIBPCAP */
809
810 const gchar *
811 cf_get_display_name(capture_file *cf)
812 {
813   const gchar *displayname;
814
815   /* Return a name to use in displays */
816   if (!cf->is_tempfile) {
817     /* Get the last component of the file name, and use that. */
818     if (cf->filename){
819       displayname = get_basename(cf->filename);
820     } else {
821       displayname="(No file)";
822     }
823   } else {
824     /* The file we read is a temporary file from a live capture;
825        we don't mention its name. */
826     displayname = "(Untitled)";
827   }
828   return displayname;
829 }
830
831 /* XXX - use a macro instead? */
832 int
833 cf_get_packet_count(capture_file *cf)
834 {
835     return cf->count;
836 }
837
838 /* XXX - use a macro instead? */
839 void
840 cf_set_packet_count(capture_file *cf, int packet_count)
841 {
842     cf->count = packet_count;
843 }
844
845 /* XXX - use a macro instead? */
846 gboolean
847 cf_is_tempfile(capture_file *cf)
848 {
849     return cf->is_tempfile;
850 }
851
852 void cf_set_tempfile(capture_file *cf, gboolean is_tempfile)
853 {
854     cf->is_tempfile = is_tempfile;
855 }
856
857
858 /* XXX - use a macro instead? */
859 void cf_set_drops_known(capture_file *cf, gboolean drops_known)
860 {
861     cf->drops_known = drops_known;
862 }
863
864 /* XXX - use a macro instead? */
865 void cf_set_drops(capture_file *cf, guint32 drops)
866 {
867     cf->drops = drops;
868 }
869
870 /* XXX - use a macro instead? */
871 gboolean cf_get_drops_known(capture_file *cf)
872 {
873     return cf->drops_known;
874 }
875
876 /* XXX - use a macro instead? */
877 guint32 cf_get_drops(capture_file *cf)
878 {
879     return cf->drops;
880 }
881
882 void cf_set_rfcode(capture_file *cf, dfilter_t *rfcode)
883 {
884     cf->rfcode = rfcode;
885 }
886
887 static int
888 add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
889         dfilter_t *dfcode,
890         union wtap_pseudo_header *pseudo_header, const guchar *buf,
891         gboolean refilter)
892 {
893   gint          row;
894   gboolean      create_proto_tree = FALSE;
895   epan_dissect_t *edt;
896
897   /* just add some value here until we know if it is being displayed or not */
898   fdata->cum_bytes  = cum_bytes + fdata->pkt_len;
899
900   /* If we don't have the time stamp of the first packet in the
901      capture, it's because this is the first packet.  Save the time
902      stamp of this packet as the time stamp of the first packet. */
903   if (nstime_is_unset(&first_ts)) {
904     first_ts  = fdata->abs_ts;
905   }
906   /* if this frames is marked as a reference time frame, reset
907      firstsec and firstusec to this frame */
908   if(fdata->flags.ref_time){
909     first_ts = fdata->abs_ts;
910   }
911
912   /* If we don't have the time stamp of the previous displayed packet,
913      it's because this is the first displayed packet.  Save the time
914      stamp of this packet as the time stamp of the previous displayed
915      packet. */
916   if (nstime_is_unset(&prev_dis_ts)) {
917     prev_dis_ts = fdata->abs_ts;
918   }
919
920   /* Get the time elapsed between the first packet and this packet. */
921   nstime_delta(&fdata->rel_ts, &fdata->abs_ts, &first_ts);
922
923   /* If it's greater than the current elapsed time, set the elapsed time
924      to it (we check for "greater than" so as not to be confused by
925      time moving backwards). */
926   if ((gint32)cf->elapsed_time.secs < fdata->rel_ts.secs
927   || ((gint32)cf->elapsed_time.secs == fdata->rel_ts.secs && (gint32)cf->elapsed_time.nsecs < fdata->rel_ts.nsecs)) {
928     cf->elapsed_time = fdata->rel_ts;
929   }
930
931   /* Get the time elapsed between the previous displayed packet and
932      this packet. */
933   nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, &prev_dis_ts);
934
935   /* If either
936
937         we have a display filter and are re-applying it;
938
939         we have a list of color filters;
940
941         we have tap listeners;
942
943      allocate a protocol tree root node, so that we'll construct
944      a protocol tree against which a filter expression can be
945      evaluated. */
946   if ((dfcode != NULL && refilter) || color_filters_used()
947         || num_tap_filters != 0)
948           create_proto_tree = TRUE;
949
950   /* Dissect the frame. */
951   edt = epan_dissect_new(create_proto_tree, FALSE);
952
953   if (dfcode != NULL && refilter) {
954       epan_dissect_prime_dfilter(edt, dfcode);
955   }
956   /* prepare color filters */
957   if (color_filters_used()) {
958       color_filters_prime_edt(edt);
959   }
960   tap_queue_init(edt);
961   epan_dissect_run(edt, pseudo_header, buf, fdata, &cf->cinfo);
962   tap_push_tapped_queue(edt);
963
964   /* If we have a display filter, apply it if we're refiltering, otherwise
965      leave the "passed_dfilter" flag alone.
966
967      If we don't have a display filter, set "passed_dfilter" to 1. */
968   if (dfcode != NULL) {
969     if (refilter) {
970       fdata->flags.passed_dfilter = dfilter_apply_edt(dfcode, edt) ? 1 : 0;
971     }
972   } else
973     fdata->flags.passed_dfilter = 1;
974
975   if( (fdata->flags.passed_dfilter)
976    || (edt->pi.fd->flags.ref_time) ){
977     /* This frame either passed the display filter list or is marked as
978        a time reference frame.  All time reference frames are displayed
979        even if they dont pass the display filter */
980     /* if this was a TIME REF frame we should reset the cul bytes field */
981     if(edt->pi.fd->flags.ref_time){
982       cum_bytes = fdata->pkt_len;
983       fdata->cum_bytes  = cum_bytes;
984     }
985
986     /* increase cum_bytes with this packets length */
987     cum_bytes += fdata->pkt_len;
988
989     epan_dissect_fill_in_columns(edt);
990
991     /* If we haven't yet seen the first frame, this is it.
992
993        XXX - we must do this before we add the row to the display,
994        as, if the display's GtkCList's selection mode is
995        GTK_SELECTION_BROWSE, when the first entry is added to it,
996        "cf_select_packet()" will be called, and it will fetch the row
997        data for the 0th row, and will get a null pointer rather than
998        "fdata", as "gtk_clist_append()" won't yet have returned and
999        thus "gtk_clist_set_row_data()" won't yet have been called.
1000
1001        We thus need to leave behind bread crumbs so that
1002        "cf_select_packet()" can find this frame.  See the comment
1003        in "cf_select_packet()". */
1004     if (cf->first_displayed == NULL)
1005       cf->first_displayed = fdata;
1006
1007     /* This is the last frame we've seen so far. */
1008     cf->last_displayed = fdata;
1009
1010     row = packet_list_append(cf->cinfo.col_data, fdata);
1011
1012     /* colorize packet: if packet is marked, use preferences,
1013        otherwise try to apply color filters */
1014       if (fdata->flags.marked) {
1015           fdata->color_filter = NULL;
1016           packet_list_set_colors(row, &prefs.gui_marked_fg, &prefs.gui_marked_bg);
1017       } else {
1018           fdata->color_filter = color_filters_colorize_packet(row, edt);
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     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     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     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   cf_callback_invoke(cf_cb_packet_selected, cf);
3256 }
3257
3258 /* Unselect the selected packet, if any. */
3259 void
3260 cf_unselect_packet(capture_file *cf)
3261 {
3262   /* Destroy the epan_dissect_t for the unselected packet. */
3263   if (cf->edt != NULL) {
3264     epan_dissect_free(cf->edt);
3265     cf->edt = NULL;
3266   }
3267
3268   /* No packet is selected. */
3269   cf->current_frame = NULL;
3270
3271   cf_callback_invoke(cf_cb_packet_unselected, cf);
3272
3273   /* No protocol tree means no selected field. */
3274   cf_unselect_field(cf);
3275 }
3276
3277 /* Unset the selected protocol tree field, if any. */
3278 void
3279 cf_unselect_field(capture_file *cf)
3280 {
3281   cf->finfo_selected = NULL;
3282
3283   cf_callback_invoke(cf_cb_field_unselected, cf);
3284 }
3285
3286 /*
3287  * Mark a particular frame.
3288  */
3289 void
3290 cf_mark_frame(capture_file *cf, frame_data *frame)
3291 {
3292   if (! frame->flags.marked) {
3293     frame->flags.marked = TRUE;
3294     if (cf->count > cf->marked_count)
3295       cf->marked_count++;
3296   }
3297 }
3298
3299 /*
3300  * Unmark a particular frame.
3301  */
3302 void
3303 cf_unmark_frame(capture_file *cf, frame_data *frame)
3304 {
3305   if (frame->flags.marked) {
3306     frame->flags.marked = FALSE;
3307     if (cf->marked_count > 0)
3308       cf->marked_count--;
3309   }
3310 }
3311
3312 typedef struct {
3313   wtap_dumper *pdh;
3314   const char  *fname;
3315 } save_callback_args_t;
3316
3317 /*
3318  * Save a capture to a file, in a particular format, saving either
3319  * all packets, all currently-displayed packets, or all marked packets.
3320  *
3321  * Returns TRUE if it succeeds, FALSE otherwise; if it fails, it pops
3322  * up a message box for the failure.
3323  */
3324 static gboolean
3325 save_packet(capture_file *cf _U_, frame_data *fdata,
3326             union wtap_pseudo_header *pseudo_header, const guint8 *pd,
3327             void *argsp)
3328 {
3329   save_callback_args_t *args = argsp;
3330   struct wtap_pkthdr hdr;
3331   int           err;
3332
3333   /* init the wtap header for saving */
3334   hdr.ts.secs    = fdata->abs_ts.secs;
3335   hdr.ts.nsecs   = fdata->abs_ts.nsecs;
3336   hdr.caplen     = fdata->cap_len;
3337   hdr.len        = fdata->pkt_len;
3338   hdr.pkt_encap  = fdata->lnk_t;
3339
3340   /* and save the packet */
3341   if (!wtap_dump(args->pdh, &hdr, pseudo_header, pd, &err)) {
3342     cf_write_failure_alert_box(args->fname, err);
3343     return FALSE;
3344   }
3345   return TRUE;
3346 }
3347
3348 /*
3349  * Can this capture file be saved in any format except by copying the raw data?
3350  */
3351 gboolean
3352 cf_can_save_as(capture_file *cf)
3353 {
3354   int ft;
3355
3356   for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
3357     /* To save a file with Wiretap, Wiretap has to handle that format,
3358        and its code to handle that format must be able to write a file
3359        with this file's encapsulation type. */
3360     if (wtap_dump_can_open(ft) && wtap_dump_can_write_encap(ft, cf->lnk_t)) {
3361       /* OK, we can write it out in this type. */
3362       return TRUE;
3363     }
3364   }
3365
3366   /* No, we couldn't save it in any format. */
3367   return FALSE;
3368 }
3369
3370 cf_status_t
3371 cf_save(capture_file *cf, const char *fname, packet_range_t *range, guint save_format, gboolean compressed)
3372 {
3373   gchar        *from_filename;
3374   int           err;
3375   gboolean      do_copy;
3376   wtap_dumper  *pdh;
3377   save_callback_args_t callback_args;
3378
3379   cf_callback_invoke(cf_cb_file_safe_started, (gpointer) fname);
3380
3381   /* don't write over an existing file. */
3382   /* this should've been already checked by our caller, just to be sure... */
3383   if (file_exists(fname)) {
3384     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3385       "%sCapture file: \"%s\" already exists!%s\n\n"
3386       "Please choose a different filename.",
3387       simple_dialog_primary_start(), fname, simple_dialog_primary_end());
3388     goto fail;
3389   }
3390
3391   packet_range_process_init(range);
3392
3393
3394   if (packet_range_process_all(range) && save_format == cf->cd_t) {
3395     /* We're not filtering packets, and we're saving it in the format
3396        it's already in, so we can just move or copy the raw data. */
3397
3398     if (cf->is_tempfile) {
3399       /* The file being saved is a temporary file from a live
3400          capture, so it doesn't need to stay around under that name;
3401          first, try renaming the capture buffer file to the new name. */
3402 #ifndef _WIN32
3403       if (eth_rename(cf->filename, fname) == 0) {
3404         /* That succeeded - there's no need to copy the source file. */
3405         from_filename = NULL;
3406         do_copy = FALSE;
3407       } else {
3408         if (errno == EXDEV) {
3409           /* They're on different file systems, so we have to copy the
3410              file. */
3411           do_copy = TRUE;
3412           from_filename = cf->filename;
3413         } else {
3414           /* The rename failed, but not because they're on different
3415              file systems - put up an error message.  (Or should we
3416              just punt and try to copy?  The only reason why I'd
3417              expect the rename to fail and the copy to succeed would
3418              be if we didn't have permission to remove the file from
3419              the temporary directory, and that might be fixable - but
3420              is it worth requiring the user to go off and fix it?) */
3421           simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3422                                 file_rename_error_message(errno), fname);
3423           goto fail;
3424         }
3425       }
3426 #else
3427       do_copy = TRUE;
3428       from_filename = cf->filename;
3429 #endif
3430     } else {
3431       /* It's a permanent file, so we should copy it, and not remove the
3432          original. */
3433       do_copy = TRUE;
3434       from_filename = cf->filename;
3435     }
3436
3437     if (do_copy) {
3438       /* Copy the file, if we haven't moved it. */
3439       if (!copy_binary_file(from_filename, fname))
3440         goto fail;
3441     }
3442   } else {
3443     /* Either we're filtering packets, or we're saving in a different
3444        format; we can't do that by copying or moving the capture file,
3445        we have to do it by writing the packets out in Wiretap. */
3446     pdh = wtap_dump_open(fname, save_format, cf->lnk_t, cf->snap,
3447                 compressed, &err);
3448     if (pdh == NULL) {
3449       cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
3450       goto fail;
3451     }
3452
3453     /* XXX - we let the user save a subset of the packets.
3454
3455        If we do that, should we make that file the current file?  If so,
3456        it means we can no longer get at the other packets.  What does
3457        NetMon do? */
3458
3459     /* Iterate through the list of packets, processing the packets we were
3460        told to process.
3461
3462        XXX - we've already called "packet_range_process_init(range)", but
3463        "process_specified_packets()" will do it again.  Fortunately,
3464        that's harmless in this case, as we haven't done anything to
3465        "range" since we initialized it. */
3466     callback_args.pdh = pdh;
3467     callback_args.fname = fname;
3468     switch (process_specified_packets(cf, range, "Saving", "selected packets",
3469                                       TRUE, save_packet, &callback_args)) {
3470
3471     case PSP_FINISHED:
3472       /* Completed successfully. */
3473       break;
3474
3475     case PSP_STOPPED:
3476       /* The user decided to abort the saving.
3477          XXX - remove the output file? */
3478       break;
3479
3480     case PSP_FAILED:
3481       /* Error while saving. */
3482       wtap_dump_close(pdh, &err);
3483       goto fail;
3484     }
3485
3486     if (!wtap_dump_close(pdh, &err)) {
3487       cf_close_failure_alert_box(fname, err);
3488       goto fail;
3489     }
3490   }
3491
3492   cf_callback_invoke(cf_cb_file_safe_finished, NULL);
3493
3494   if (packet_range_process_all(range)) {
3495     /* We saved the entire capture, not just some packets from it.
3496        Open and read the file we saved it to.
3497
3498        XXX - this is somewhat of a waste; we already have the
3499        packets, all this gets us is updated file type information
3500        (which we could just stuff into "cf"), and having the new
3501        file be the one we have opened and from which we're reading
3502        the data, and it means we have to spend time opening and
3503        reading the file, which could be a significant amount of
3504        time if the file is large. */
3505     cf->user_saved = TRUE;
3506
3507     if ((cf_open(cf, fname, FALSE, &err)) == CF_OK) {
3508       /* XXX - report errors if this fails?
3509          What should we return if it fails or is aborted? */
3510       switch (cf_read(cf)) {
3511
3512       case CF_READ_OK:
3513       case CF_READ_ERROR:
3514         /* Just because we got an error, that doesn't mean we were unable
3515            to read any of the file; we handle what we could get from the
3516            file. */
3517         break;
3518
3519       case CF_READ_ABORTED:
3520         /* The user bailed out of re-reading the capture file; the
3521            capture file has been closed - just return (without
3522            changing any menu settings; "cf_close()" set them
3523            correctly for the "no capture file open" state). */
3524         break;
3525       }
3526       cf_callback_invoke(cf_cb_file_safe_reload_finished, NULL);
3527     }
3528   }
3529   return CF_OK;
3530
3531 fail:
3532   cf_callback_invoke(cf_cb_file_safe_failed, NULL);
3533   return CF_ERROR;
3534 }
3535
3536 static void
3537 cf_open_failure_alert_box(const char *filename, int err, gchar *err_info,
3538                           gboolean for_writing, int file_type)
3539 {
3540   if (err < 0) {
3541     /* Wiretap error. */
3542     switch (err) {
3543
3544     case WTAP_ERR_NOT_REGULAR_FILE:
3545       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3546                     "The file \"%s\" is a \"special file\" or socket or other non-regular file.",
3547                     filename);
3548       break;
3549
3550     case WTAP_ERR_RANDOM_OPEN_PIPE:
3551       /* Seen only when opening a capture file for reading. */
3552       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3553                     "The file \"%s\" is a pipe or FIFO; Wireshark can't read pipe or FIFO files.",
3554                     filename);
3555       break;
3556
3557     case WTAP_ERR_FILE_UNKNOWN_FORMAT:
3558       /* Seen only when opening a capture file for reading. */
3559       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3560                     "The file \"%s\" isn't a capture file in a format Wireshark understands.",
3561                     filename);
3562       break;
3563
3564     case WTAP_ERR_UNSUPPORTED:
3565       /* Seen only when opening a capture file for reading. */
3566       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3567                     "The file \"%s\" isn't a capture file in a format Wireshark understands.\n"
3568                     "(%s)",
3569                     filename, err_info);
3570       g_free(err_info);
3571       break;
3572
3573     case WTAP_ERR_CANT_WRITE_TO_PIPE:
3574       /* Seen only when opening a capture file for writing. */
3575       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3576                     "The file \"%s\" is a pipe, and %s capture files can't be "
3577                     "written to a pipe.",
3578                     filename, wtap_file_type_string(file_type));
3579       break;
3580
3581     case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
3582       /* Seen only when opening a capture file for writing. */
3583       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3584                     "Wireshark doesn't support writing capture files in that format.");
3585       break;
3586
3587     case WTAP_ERR_UNSUPPORTED_ENCAP:
3588       if (for_writing) {
3589         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3590                       "Wireshark can't save this capture in that format.");
3591       } else {
3592         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3593                       "The file \"%s\" is a capture for a network type that Wireshark doesn't support.\n"
3594                       "(%s)",
3595                       filename, err_info);
3596         g_free(err_info);
3597       }
3598       break;
3599
3600     case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
3601       if (for_writing) {
3602         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3603                       "Wireshark can't save this capture in that format.");
3604       } else {
3605         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3606                       "The file \"%s\" is a capture for a network type that Wireshark doesn't support.",
3607                       filename);
3608       }
3609       break;
3610
3611     case WTAP_ERR_BAD_RECORD:
3612       /* Seen only when opening a capture file for reading. */
3613       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3614                     "The file \"%s\" appears to be damaged or corrupt.\n"
3615                     "(%s)",
3616                     filename, err_info);
3617       g_free(err_info);
3618       break;
3619
3620     case WTAP_ERR_CANT_OPEN:
3621       if (for_writing) {
3622         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3623                       "The file \"%s\" could not be created for some unknown reason.",
3624                       filename);
3625       } else {
3626         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3627                       "The file \"%s\" could not be opened for some unknown reason.",
3628                       filename);
3629       }
3630       break;
3631
3632     case WTAP_ERR_SHORT_READ:
3633       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3634                     "The file \"%s\" appears to have been cut short"
3635                     " in the middle of a packet or other data.",
3636                     filename);
3637       break;
3638
3639     case WTAP_ERR_SHORT_WRITE:
3640       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3641                     "A full header couldn't be written to the file \"%s\".",
3642                     filename);
3643       break;
3644
3645     case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
3646       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3647                     "Gzip compression not supported by this file type.");
3648       break;
3649
3650     default:
3651       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3652                     "The file \"%s\" could not be %s: %s.",
3653                     filename,
3654                     for_writing ? "created" : "opened",
3655                     wtap_strerror(err));
3656       break;
3657     }
3658   } else {
3659     /* OS error. */
3660     open_failure_alert_box(filename, err, for_writing);
3661   }
3662 }
3663
3664 static const char *
3665 file_rename_error_message(int err)
3666 {
3667   const char *errmsg;
3668   static char errmsg_errno[1024+1];
3669
3670   switch (err) {
3671
3672   case ENOENT:
3673     errmsg = "The path to the file \"%s\" doesn't exist.";
3674     break;
3675
3676   case EACCES:
3677     errmsg = "You don't have permission to move the capture file to \"%s\".";
3678     break;
3679
3680   default:
3681     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
3682                     "The file \"%%s\" could not be moved: %s.",
3683                                 wtap_strerror(err));
3684     errmsg = errmsg_errno;
3685     break;
3686   }
3687   return errmsg;
3688 }
3689
3690 char *
3691 cf_read_error_message(int err, const gchar *err_info)
3692 {
3693   static char errmsg_errno[1024+1];
3694
3695   switch (err) {
3696
3697   case WTAP_ERR_UNSUPPORTED_ENCAP:
3698       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
3699                "The file \"%%s\" has a packet with a network type that Wireshark doesn't support.\n(%s)",
3700                err_info);
3701       break;
3702
3703   case WTAP_ERR_BAD_RECORD:
3704     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
3705              "An error occurred while reading from the file \"%%s\": %s.\n(%s)",
3706              wtap_strerror(err), err_info);
3707     break;
3708
3709   default:
3710     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
3711              "An error occurred while reading from the file \"%%s\": %s.",
3712              wtap_strerror(err));
3713     break;
3714   }
3715   return errmsg_errno;
3716 }
3717
3718 static void
3719 cf_write_failure_alert_box(const char *filename, int err)
3720 {
3721   if (err < 0) {
3722     /* Wiretap error. */
3723     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3724                   "An error occurred while writing to the file \"%s\": %s.",
3725                   filename, wtap_strerror(err));
3726   } else {
3727     /* OS error. */
3728     write_failure_alert_box(filename, err);
3729   }
3730 }
3731
3732 /* Check for write errors - if the file is being written to an NFS server,
3733    a write error may not show up until the file is closed, as NFS clients
3734    might not send writes to the server until the "write()" call finishes,
3735    so that the write may fail on the server but the "write()" may succeed. */
3736 static void
3737 cf_close_failure_alert_box(const char *filename, int err)
3738 {
3739   if (err < 0) {
3740     /* Wiretap error. */
3741     switch (err) {
3742
3743     case WTAP_ERR_CANT_CLOSE:
3744       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3745                     "The file \"%s\" couldn't be closed for some unknown reason.",
3746                     filename);
3747       break;
3748
3749     case WTAP_ERR_SHORT_WRITE:
3750       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3751                     "Not all the packets could be written to the file \"%s\".",
3752                     filename);
3753       break;
3754
3755     default:
3756       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3757                     "An error occurred while closing the file \"%s\": %s.",
3758                     filename, wtap_strerror(err));
3759       break;
3760     }
3761   } else {
3762     /* OS error.
3763        We assume that a close error from the OS is really a write error. */
3764     write_failure_alert_box(filename, err);
3765   }
3766 }
3767
3768 /* Reload the current capture file. */
3769 void
3770 cf_reload(capture_file *cf) {
3771   gchar *filename;
3772   gboolean is_tempfile;
3773   int err;
3774
3775   /* If the file could be opened, "cf_open()" calls "cf_close()"
3776      to get rid of state for the old capture file before filling in state
3777      for the new capture file.  "cf_close()" will remove the file if
3778      it's a temporary file; we don't want that to happen (for one thing,
3779      it'd prevent subsequent reopens from working).  Remember whether it's
3780      a temporary file, mark it as not being a temporary file, and then
3781      reopen it as the type of file it was.
3782
3783      Also, "cf_close()" will free "cf->filename", so we must make
3784      a copy of it first. */
3785   filename = g_strdup(cf->filename);
3786   is_tempfile = cf->is_tempfile;
3787   cf->is_tempfile = FALSE;
3788   if (cf_open(cf, filename, is_tempfile, &err) == CF_OK) {
3789     switch (cf_read(cf)) {
3790
3791     case CF_READ_OK:
3792     case CF_READ_ERROR:
3793       /* Just because we got an error, that doesn't mean we were unable
3794          to read any of the file; we handle what we could get from the
3795          file. */
3796       break;
3797
3798     case CF_READ_ABORTED:
3799       /* The user bailed out of re-reading the capture file; the
3800          capture file has been closed - just free the capture file name
3801          string and return (without changing the last containing
3802          directory). */
3803       g_free(filename);
3804       return;
3805     }
3806   } else {
3807     /* The open failed, so "cf->is_tempfile" wasn't set to "is_tempfile".
3808        Instead, the file was left open, so we should restore "cf->is_tempfile"
3809        ourselves.
3810
3811        XXX - change the menu?  Presumably "cf_open()" will do that;
3812        make sure it does! */
3813     cf->is_tempfile = is_tempfile;
3814   }
3815   /* "cf_open()" made a copy of the file name we handed it, so
3816      we should free up our copy. */
3817   g_free(filename);
3818 }
3819
3820 /* Copies a file in binary mode, for those operating systems that care about
3821  * such things.
3822  * Returns TRUE on success, FALSE on failure. If a failure, it also
3823  * displays a simple dialog window with the error message.
3824  */
3825 static gboolean
3826 copy_binary_file(const char *from_filename, const char *to_filename)
3827 {
3828   int           from_fd, to_fd, nread, nwritten, err;
3829   guint8        pd[65536];
3830
3831   /* Copy the raw bytes of the file. */
3832   from_fd = eth_open(from_filename, O_RDONLY | O_BINARY, 0000 /* no creation so don't matter */);
3833   if (from_fd < 0) {
3834     open_failure_alert_box(from_filename, errno, FALSE);
3835     goto done;
3836   }
3837
3838   /* Use open() instead of creat() so that we can pass the O_BINARY
3839      flag, which is relevant on Win32; it appears that "creat()"
3840      may open the file in text mode, not binary mode, but we want
3841      to copy the raw bytes of the file, so we need the output file
3842      to be open in binary mode. */
3843   to_fd = eth_open(to_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
3844   if (to_fd < 0) {
3845     open_failure_alert_box(to_filename, errno, TRUE);
3846     eth_close(from_fd);
3847     goto done;
3848   }
3849
3850   while ((nread = eth_read(from_fd, pd, sizeof pd)) > 0) {
3851     nwritten = eth_write(to_fd, pd, nread);
3852     if (nwritten < nread) {
3853       if (nwritten < 0)
3854         err = errno;
3855       else
3856         err = WTAP_ERR_SHORT_WRITE;
3857       write_failure_alert_box(to_filename, err);
3858       eth_close(from_fd);
3859       eth_close(to_fd);
3860       goto done;
3861     }
3862   }
3863   if (nread < 0) {
3864     err = errno;
3865     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3866                   "An error occurred while reading from the file \"%s\": %s.",
3867                   from_filename, strerror(err));
3868     eth_close(from_fd);
3869     eth_close(to_fd);
3870     goto done;
3871   }
3872   eth_close(from_fd);
3873   if (eth_close(to_fd) < 0) {
3874     write_failure_alert_box(to_filename, errno);
3875     goto done;
3876   }
3877
3878   return TRUE;
3879
3880 done:
3881   return FALSE;
3882 }