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