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