Pass {delayed_}create_progress_dlg a pointer the top level window
[metze/wireshark/wip.git] / file.c
1 /* file.c
2  * File I/O routines
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #ifdef HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32
33 #include <time.h>
34
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <ctype.h>
39 #include <errno.h>
40 #include <signal.h>
41
42 #ifdef HAVE_FCNTL_H
43 #include <fcntl.h>
44 #endif
45
46 #include <epan/epan.h>
47 #include <epan/filesystem.h>
48
49 #include "color.h"
50 #include "color_filters.h"
51 #include "cfile.h"
52 #include <epan/column.h>
53 #include <epan/packet.h>
54 #include <epan/column-utils.h>
55 #include "packet-range.h"
56 #include "print.h"
57 #include "file.h"
58 #include "fileset.h"
59 #include "tempfile.h"
60 #include "merge.h"
61
62 #include <epan/prefs.h>
63 #include <epan/dfilter/dfilter.h>
64 #include <epan/epan_dissect.h>
65 #include <epan/tap.h>
66 #include <epan/dissectors/packet-data.h>
67 #include <epan/dissectors/packet-ber.h>
68 #include <epan/timestamp.h>
69 #include <epan/dfilter/dfilter-macro.h>
70 #include <wsutil/file_util.h>
71 #include <epan/strutil.h>
72 #include <epan/addr_resolv.h>
73
74 #include "ui/alert_box.h"
75 #include "ui/simple_dialog.h"
76 #include "ui/main_statusbar.h"
77 #include "ui/progress_dlg.h"
78 #include "ui/ui_util.h"
79
80 #ifdef HAVE_LIBPCAP
81 gboolean auto_scroll_live;
82 #endif
83
84 static guint32 cum_bytes;
85 static nstime_t first_ts;
86 static nstime_t prev_dis_ts;
87 static nstime_t prev_cap_ts;
88
89 static gulong computed_elapsed;
90
91 static void cf_reset_state(capture_file *cf);
92
93 static int read_packet(capture_file *cf, dfilter_t *dfcode,
94     gboolean filtering_tap_listeners, guint tap_flags, gint64 offset);
95
96 static void rescan_packets(capture_file *cf, const char *action, const char *action_item,
97     gboolean refilter, gboolean redissect);
98
99 typedef enum {
100   MR_NOTMATCHED,
101   MR_MATCHED,
102   MR_ERROR
103 } match_result;
104 static match_result match_protocol_tree(capture_file *cf, frame_data *fdata,
105     void *criterion);
106 static void match_subtree_text(proto_node *node, gpointer data);
107 static match_result match_summary_line(capture_file *cf, frame_data *fdata,
108     void *criterion);
109 static match_result match_ascii_and_unicode(capture_file *cf, frame_data *fdata,
110     void *criterion);
111 static match_result match_ascii(capture_file *cf, frame_data *fdata,
112     void *criterion);
113 static match_result match_unicode(capture_file *cf, frame_data *fdata,
114     void *criterion);
115 static match_result match_binary(capture_file *cf, frame_data *fdata,
116     void *criterion);
117 static match_result match_dfilter(capture_file *cf, frame_data *fdata,
118     void *criterion);
119 static match_result match_marked(capture_file *cf, frame_data *fdata,
120     void *criterion);
121 static match_result match_time_reference(capture_file *cf, frame_data *fdata,
122     void *criterion);
123 static gboolean find_packet(capture_file *cf,
124     match_result (*match_function)(capture_file *, frame_data *, void *),
125     void *criterion, search_direction dir);
126
127 static void cf_open_failure_alert_box(const char *filename, int err,
128                       gchar *err_info, gboolean for_writing,
129                       int file_type);
130 static void cf_rename_failure_alert_box(const char *filename, int err);
131 static void cf_close_failure_alert_box(const char *filename, int err);
132 static void ref_time_packets(capture_file *cf);
133 /* Update the progress bar this many times when reading a file. */
134 #define N_PROGBAR_UPDATES   100
135 /* We read around 200k/100ms don't update the progress bar more often than that */
136 #define MIN_QUANTUM         200000
137 #define MIN_NUMBER_OF_PACKET 1500
138
139 /*
140  * We could probably use g_signal_...() instead of the callbacks below but that
141  * would require linking our CLI programs to libgobject and creating an object
142  * instance for the signals.
143  */
144 typedef struct {
145   cf_callback_t cb_fct;
146   gpointer user_data;
147 } cf_callback_data_t;
148
149 static GList *cf_callbacks = NULL;
150
151 static void
152 cf_callback_invoke(int event, gpointer data)
153 {
154   cf_callback_data_t *cb;
155   GList *cb_item = cf_callbacks;
156
157   /* there should be at least one interested */
158   g_assert(cb_item != NULL);
159
160   while(cb_item != NULL) {
161     cb = cb_item->data;
162     cb->cb_fct(event, data, cb->user_data);
163     cb_item = g_list_next(cb_item);
164   }
165 }
166
167
168 void
169 cf_callback_add(cf_callback_t func, gpointer user_data)
170 {
171   cf_callback_data_t *cb;
172
173   cb = g_malloc(sizeof(cf_callback_data_t));
174   cb->cb_fct = func;
175   cb->user_data = user_data;
176
177   cf_callbacks = g_list_append(cf_callbacks, cb);
178 }
179
180 void
181 cf_callback_remove(cf_callback_t func)
182 {
183   cf_callback_data_t *cb;
184   GList *cb_item = cf_callbacks;
185
186   while(cb_item != NULL) {
187     cb = cb_item->data;
188     if(cb->cb_fct == func) {
189       cf_callbacks = g_list_remove(cf_callbacks, cb);
190       g_free(cb);
191       return;
192     }
193     cb_item = g_list_next(cb_item);
194   }
195
196   g_assert_not_reached();
197 }
198
199 void
200 cf_timestamp_auto_precision(capture_file *cf)
201 {
202   int i;
203   int prec = timestamp_get_precision();
204
205
206   /* don't try to get the file's precision if none is opened */
207   if(cf->state == FILE_CLOSED) {
208     return;
209   }
210
211   /* if we are in auto mode, set precision of current file */
212   if(prec == TS_PREC_AUTO ||
213      prec == TS_PREC_AUTO_SEC ||
214      prec == TS_PREC_AUTO_DSEC ||
215      prec == TS_PREC_AUTO_CSEC ||
216      prec == TS_PREC_AUTO_MSEC ||
217      prec == TS_PREC_AUTO_USEC ||
218      prec == TS_PREC_AUTO_NSEC)
219   {
220     switch(wtap_file_tsprecision(cf->wth)) {
221     case(WTAP_FILE_TSPREC_SEC):
222       timestamp_set_precision(TS_PREC_AUTO_SEC);
223       break;
224     case(WTAP_FILE_TSPREC_DSEC):
225       timestamp_set_precision(TS_PREC_AUTO_DSEC);
226       break;
227     case(WTAP_FILE_TSPREC_CSEC):
228       timestamp_set_precision(TS_PREC_AUTO_CSEC);
229       break;
230     case(WTAP_FILE_TSPREC_MSEC):
231       timestamp_set_precision(TS_PREC_AUTO_MSEC);
232       break;
233     case(WTAP_FILE_TSPREC_USEC):
234       timestamp_set_precision(TS_PREC_AUTO_USEC);
235       break;
236     case(WTAP_FILE_TSPREC_NSEC):
237       timestamp_set_precision(TS_PREC_AUTO_NSEC);
238       break;
239     default:
240       g_assert_not_reached();
241     }
242   }
243   /* Set the column widths of those columns that show the time in
244      "command-line-specified" format. */
245   for (i = 0; i < cf->cinfo.num_cols; i++) {
246     if (col_has_time_fmt(&cf->cinfo, i)) {
247       new_packet_list_resize_column(i);
248     }
249   }
250 }
251
252 gulong
253 cf_get_computed_elapsed(void)
254 {
255   return computed_elapsed;
256 }
257
258 static void reset_elapsed(void)
259 {
260   computed_elapsed = 0;
261 }
262
263 static void compute_elapsed(GTimeVal *start_time)
264 {
265   gdouble    delta_time;
266   GTimeVal   time_now;
267
268   g_get_current_time(&time_now);
269
270   delta_time = (time_now.tv_sec - start_time->tv_sec) * 1e6 +
271     time_now.tv_usec - start_time->tv_usec;
272
273   computed_elapsed = (gulong) (delta_time / 1000); /* ms */
274 }
275
276 cf_status_t
277 cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
278 {
279   wtap       *wth;
280   gchar       *err_info;
281
282   wth = wtap_open_offline(fname, err, &err_info, TRUE);
283   if (wth == NULL)
284     goto fail;
285
286   /* The open succeeded.  Close whatever capture file we had open,
287      and fill in the information for this file. */
288   cf_close(cf);
289
290   /* Cleanup all data structures used for dissection. */
291   cleanup_dissection();
292   /* Initialize all data structures used for dissection. */
293   init_dissection();
294
295   /* We're about to start reading the file. */
296   cf->state = FILE_READ_IN_PROGRESS;
297
298   cf->wth = wth;
299   cf->f_datalen = 0;
300
301   /* Set the file name because we need it to set the follow stream filter.
302      XXX - is that still true?  We need it for other reasons, though,
303      in any case. */
304   cf->filename = g_strdup(fname);
305
306   /* Indicate whether it's a permanent or temporary file. */
307   cf->is_tempfile = is_tempfile;
308
309   /* No user changes yet. */
310   cf->unsaved_changes = FALSE;
311
312   reset_elapsed();
313
314   cf->cd_t        = wtap_file_type(cf->wth);
315   cf->linktypes = g_array_sized_new(FALSE, FALSE, (guint) sizeof(int), 1);
316   cf->count     = 0;
317   cf->packet_comment_count = 0;
318   cf->displayed_count = 0;
319   cf->marked_count = 0;
320   cf->ignored_count = 0;
321   cf->ref_time_count = 0;
322   cf->drops_known = FALSE;
323   cf->drops     = 0;
324   cf->snap      = wtap_snapshot_length(cf->wth);
325   if (cf->snap == 0) {
326     /* Snapshot length not known. */
327     cf->has_snap = FALSE;
328     cf->snap = WTAP_MAX_PACKET_SIZE;
329   } else
330     cf->has_snap = TRUE;
331
332   /* Allocate a frame_data_sequence for the frames in this file */
333   cf->frames = new_frame_data_sequence();
334
335   nstime_set_zero(&cf->elapsed_time);
336   nstime_set_unset(&first_ts);
337   nstime_set_unset(&prev_dis_ts);
338   nstime_set_unset(&prev_cap_ts);
339   cum_bytes = 0;
340
341   /* Adjust timestamp precision if auto is selected, col width will be adjusted */
342   cf_timestamp_auto_precision(cf);
343   /* XXX needed ? */
344   new_packet_list_queue_draw();
345   fileset_file_opened(fname);
346
347   if(cf->cd_t == WTAP_FILE_BER) {
348     /* tell the BER dissector the file name */
349     ber_set_filename(cf->filename);
350   }
351
352   wtap_set_cb_new_ipv4(cf->wth, add_ipv4_name);
353   wtap_set_cb_new_ipv6(cf->wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
354
355   return CF_OK;
356
357 fail:
358   cf_open_failure_alert_box(fname, *err, err_info, FALSE, 0);
359   return CF_ERROR;
360 }
361
362 /*
363  * Add an encapsulation type to cf->linktypes.
364  */
365 void
366 cf_add_encapsulation_type(capture_file *cf, int encap)
367 {
368   guint i;
369
370   for (i = 0; i < cf->linktypes->len; i++) {
371     if (g_array_index(cf->linktypes, gint, i) == encap)
372       return; /* it's already there */
373   }
374   /* It's not already there - add it. */
375   g_array_append_val(cf->linktypes, encap);
376 }
377
378 /*
379  * Reset the state for the currently closed file, but don't do the
380  * UI callbacks; this is for use in "cf_open()", where we don't
381  * want the UI to go from "file open" to "file closed" back to
382  * "file open", we want it to go from "old file open" to "new file
383  * open and being read".
384  *
385  * XXX - currently, cf_open() calls cf_close(), rather than
386  * cf_reset_state().
387  */
388 static void
389 cf_reset_state(capture_file *cf)
390 {
391   /* Die if we're in the middle of reading a file. */
392   g_assert(cf->state != FILE_READ_IN_PROGRESS);
393
394   if (cf->wth) {
395     wtap_close(cf->wth);
396     cf->wth = NULL;
397   }
398   /* We have no file open... */
399   if (cf->filename != NULL) {
400     /* If it's a temporary file, remove it. */
401     if (cf->is_tempfile)
402       ws_unlink(cf->filename);
403     g_free(cf->filename);
404     cf->filename = NULL;
405   }
406   /* ...which means we have no changes to that file to save. */
407   cf->unsaved_changes = FALSE;
408
409   dfilter_free(cf->rfcode);
410   cf->rfcode = NULL;
411   if (cf->frames != NULL) {
412     free_frame_data_sequence(cf->frames);
413     cf->frames = NULL;
414   }
415 #ifdef WANT_PACKET_EDITOR
416   if (cf->edited_frames) {
417     g_tree_destroy(cf->edited_frames);
418     cf->edited_frames = NULL;
419   }
420 #endif
421   cf_unselect_packet(cf);   /* nothing to select */
422   cf->first_displayed = 0;
423   cf->last_displayed = 0;
424
425   /* No frames, no frame selected, no field in that frame selected. */
426   cf->count = 0;
427   cf->current_frame = 0;
428   cf->current_row = 0;
429   cf->finfo_selected = NULL;
430
431   /* No frame link-layer types, either. */
432   g_array_free(cf->linktypes, TRUE);
433   cf->linktypes = NULL;
434
435   /* Clear the packet list. */
436   new_packet_list_freeze();
437   new_packet_list_clear();
438   new_packet_list_thaw();
439
440   cf->f_datalen = 0;
441   nstime_set_zero(&cf->elapsed_time);
442
443   reset_tap_listeners();
444
445   /* We have no file open. */
446   cf->state = FILE_CLOSED;
447
448   fileset_file_closed();
449 }
450
451 /* Reset everything to a pristine state */
452 void
453 cf_close(capture_file *cf)
454 {
455   if(cf->state != FILE_CLOSED) {
456     cf_callback_invoke(cf_cb_file_closing, cf);
457
458   /* close things, if not already closed before */
459     color_filters_cleanup();
460     cf_reset_state(cf);
461     cleanup_dissection();
462
463     cf_callback_invoke(cf_cb_file_closed, cf);
464   }
465 }
466
467 static float
468 calc_progbar_val(capture_file *cf, gint64 size, gint64 file_pos, gchar *status_str, gulong status_size)
469 {
470   float   progbar_val;
471
472   progbar_val = (gfloat) file_pos / (gfloat) size;
473   if (progbar_val > 1.0) {
474
475     /*  The file probably grew while we were reading it.
476      *  Update file size, and try again.
477      */
478     size = wtap_file_size(cf->wth, NULL);
479
480     if (size >= 0)
481       progbar_val = (gfloat) file_pos / (gfloat) size;
482
483     /*  If it's still > 1, either "wtap_file_size()" failed (in which
484      *  case there's not much we can do about it), or the file
485      *  *shrank* (in which case there's not much we can do about
486      *  it); just clip the progress value at 1.0.
487      */
488     if (progbar_val > 1.0f)
489       progbar_val = 1.0f;
490   }
491
492   g_snprintf(status_str, status_size,
493              "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
494              file_pos / 1024, size / 1024);
495
496   return progbar_val;
497 }
498
499 cf_read_status_t
500 cf_read(capture_file *cf, gboolean reloading)
501 {
502   int         err;
503   gchar       *err_info;
504   gchar       *name_ptr;
505   gint64       data_offset;
506   gint64       file_pos;
507   progdlg_t *volatile progbar = NULL;
508   gboolean     stop_flag;
509   volatile gint64 size;
510   volatile float progbar_val;
511   GTimeVal     start_time;
512   gchar        status_str[100];
513   volatile gint64 progbar_nextstep;
514   volatile gint64 progbar_quantum;
515   dfilter_t   *dfcode;
516   gboolean    filtering_tap_listeners;
517   guint       tap_flags;
518   volatile int count = 0;
519 #ifdef HAVE_LIBPCAP
520   volatile int displayed_once = 0;
521 #endif
522   gboolean compiled;
523
524   /* Compile the current display filter.
525    * We assume this will not fail since cf->dfilter is only set in
526    * cf_filter IFF the filter was valid.
527    */
528   compiled = dfilter_compile(cf->dfilter, &dfcode);
529   g_assert(!cf->dfilter || (compiled && dfcode));
530
531   /* Do we have any tap listeners with filters? */
532   filtering_tap_listeners = have_filtering_tap_listeners();
533
534   /* Get the union of the flags for all tap listeners. */
535   tap_flags = union_of_tap_listener_flags();
536
537   reset_tap_listeners();
538
539   name_ptr = g_filename_display_basename(cf->filename);
540
541   if (reloading)
542     cf_callback_invoke(cf_cb_file_reload_started, cf);
543   else
544     cf_callback_invoke(cf_cb_file_read_started, cf);
545
546   /* Record whether the file is compressed.
547      XXX - do we know this at open time? */
548   cf->iscompressed = wtap_iscompressed(cf->wth);
549
550   /* Find the size of the file. */
551   size = wtap_file_size(cf->wth, NULL);
552
553   /* Update the progress bar when it gets to this value. */
554   progbar_nextstep = 0;
555   /* When we reach the value that triggers a progress bar update,
556      bump that value by this amount. */
557   if (size >= 0){
558     progbar_quantum = size/N_PROGBAR_UPDATES;
559     if (progbar_quantum < MIN_QUANTUM)
560       progbar_quantum = MIN_QUANTUM;
561   }else
562     progbar_quantum = 0;
563   /* Progress so far. */
564   progbar_val = 0.0f;
565
566   /* The packet list window will be empty until the file is completly loaded */
567   new_packet_list_freeze();
568
569   stop_flag = FALSE;
570   g_get_current_time(&start_time);
571
572   while ((wtap_read(cf->wth, &err, &err_info, &data_offset))) {
573     if (size >= 0) {
574       count++;
575       file_pos = wtap_read_so_far(cf->wth);
576
577       /* Create the progress bar if necessary.
578        * Check whether it should be created or not every MIN_NUMBER_OF_PACKET
579        */
580       if ((progbar == NULL) && !(count % MIN_NUMBER_OF_PACKET)){
581         progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
582         if (reloading)
583           progbar = delayed_create_progress_dlg(cf->window, "Reloading", name_ptr,
584                                                 TRUE, &stop_flag, &start_time, progbar_val);
585         else
586           progbar = delayed_create_progress_dlg(cf->window, "Loading", name_ptr,
587                                                 TRUE, &stop_flag, &start_time, progbar_val);
588       }
589
590       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
591          when we update it, we have to run the GTK+ main loop to get it
592          to repaint what's pending, and doing so may involve an "ioctl()"
593          to see if there's any pending input from an X server, and doing
594          that for every packet can be costly, especially on a big file. */
595       if (file_pos >= progbar_nextstep) {
596         if (progbar != NULL) {
597           progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
598           /* update the packet bar content on the first run or frequently on very large files */
599 #ifdef HAVE_LIBPCAP
600           if (progbar_quantum > 500000 || displayed_once == 0) {
601             if ((auto_scroll_live || displayed_once == 0 || cf->displayed_count < 1000) && cf->count != 0) {
602               displayed_once = 1;
603               packets_bar_update();
604             }
605           }
606 #endif /* HAVE_LIBPCAP */
607           update_progress_dlg(progbar, progbar_val, status_str);
608         }
609         progbar_nextstep += progbar_quantum;
610       }
611     }
612
613     if (stop_flag) {
614       /* Well, the user decided to abort the read. He/She will be warned and
615          it might be enough for him/her to work with the already loaded
616          packets.
617          This is especially true for very large capture files, where you don't
618          want to wait loading the whole file (which may last minutes or even
619          hours even on fast machines) just to see that it was the wrong file. */
620       break;
621     }
622     TRY {
623       read_packet(cf, dfcode, filtering_tap_listeners, tap_flags, data_offset);
624     }
625     CATCH(OutOfMemoryError) {
626       simple_message_box(ESD_TYPE_ERROR, NULL,
627                      "Some infos / workarounds can be found at:\n"
628                      "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
629                      "Sorry, but Wireshark has run out of memory and has to terminate now!");
630 #if 0
631       /* Could we close the current capture and free up memory from that? */
632       break;
633 #else
634       /* we have to terminate, as we cannot recover from the memory error */
635       exit(1);
636 #endif
637     }
638     ENDTRY;
639   }
640
641   /* Free the display name */
642   g_free(name_ptr);
643
644   /* Cleanup and release all dfilter resources */
645   if (dfcode != NULL){
646     dfilter_free(dfcode);
647   }
648
649   /* We're done reading the file; destroy the progress bar if it was created. */
650   if (progbar != NULL)
651     destroy_progress_dlg(progbar);
652
653   /* We're done reading sequentially through the file. */
654   cf->state = FILE_READ_DONE;
655
656   /* Close the sequential I/O side, to free up memory it requires. */
657   wtap_sequential_close(cf->wth);
658
659   /* Allow the protocol dissectors to free up memory that they
660    * don't need after the sequential run-through of the packets. */
661   postseq_cleanup_all_protocols();
662
663   /* compute the time it took to load the file */
664   compute_elapsed(&start_time);
665
666   /* Set the file encapsulation type now; we don't know what it is until
667      we've looked at all the packets, as we don't know until then whether
668      there's more than one type (and thus whether it's
669      WTAP_ENCAP_PER_PACKET). */
670   cf->lnk_t = wtap_file_encap(cf->wth);
671
672   cf->current_frame = frame_data_sequence_find(cf->frames, cf->first_displayed);
673   cf->current_row = 0;
674
675   new_packet_list_thaw();
676   if (reloading)
677     cf_callback_invoke(cf_cb_file_reload_finished, cf);
678   else
679     cf_callback_invoke(cf_cb_file_read_finished, cf);
680
681   /* If we have any displayed packets to select, select the first of those
682      packets by making the first row the selected row. */
683   if (cf->first_displayed != 0){
684     new_packet_list_select_first_row();
685   }
686
687   if(stop_flag) {
688     simple_message_box(ESD_TYPE_WARN, NULL,
689                   "The remaining packets in the file were discarded.\n"
690                   "\n"
691                   "As a lot of packets from the original file will be missing,\n"
692                   "remember to be careful when saving the current content to a file.\n",
693                   "File loading was cancelled!");
694     return CF_READ_ERROR;
695   }
696
697   if (err != 0) {
698     /* Put up a message box noting that the read failed somewhere along
699        the line.  Don't throw out the stuff we managed to read, though,
700        if any. */
701     switch (err) {
702
703     case WTAP_ERR_UNSUPPORTED:
704       simple_error_message_box(
705                  "The capture file contains record data that Wireshark doesn't support.\n(%s)",
706                  err_info);
707       g_free(err_info);
708       break;
709
710     case WTAP_ERR_UNSUPPORTED_ENCAP:
711       simple_error_message_box(
712                  "The capture file has a packet with a network type that Wireshark doesn't support.\n(%s)",
713                  err_info);
714       g_free(err_info);
715       break;
716
717     case WTAP_ERR_CANT_READ:
718       simple_error_message_box(
719                  "An attempt to read from the capture file failed for"
720                  " some unknown reason.");
721       break;
722
723     case WTAP_ERR_SHORT_READ:
724       simple_error_message_box(
725                  "The capture file appears to have been cut short"
726                  " in the middle of a packet.");
727       break;
728
729     case WTAP_ERR_BAD_FILE:
730       simple_error_message_box(
731                  "The capture file appears to be damaged or corrupt.\n(%s)",
732                  err_info);
733       g_free(err_info);
734       break;
735
736     case WTAP_ERR_DECOMPRESS:
737       simple_error_message_box(
738                  "The compressed capture file appears to be damaged or corrupt.\n"
739                  "(%s)", err_info);
740       g_free(err_info);
741       break;
742
743     default:
744       simple_error_message_box(
745                  "An error occurred while reading the"
746                  " capture file: %s.", wtap_strerror(err));
747       break;
748     }
749     return CF_READ_ERROR;
750   } else
751     return CF_READ_OK;
752 }
753
754 #ifdef HAVE_LIBPCAP
755 cf_status_t
756 cf_start_tail(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
757 {
758   cf_status_t cf_status;
759
760   cf_status = cf_open(cf, fname, is_tempfile, err);
761   return cf_status;
762 }
763
764 cf_read_status_t
765 cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
766 {
767   gint64 data_offset = 0;
768   gchar *err_info;
769   volatile int newly_displayed_packets = 0;
770   dfilter_t   *dfcode;
771   gboolean filtering_tap_listeners;
772   guint tap_flags;
773   gboolean compiled;
774
775   /* Compile the current display filter.
776    * We assume this will not fail since cf->dfilter is only set in
777    * cf_filter IFF the filter was valid.
778    */
779   compiled = dfilter_compile(cf->dfilter, &dfcode);
780   g_assert(!cf->dfilter || (compiled && dfcode));
781
782   /* Do we have any tap listeners with filters? */
783   filtering_tap_listeners = have_filtering_tap_listeners();
784
785   /* Get the union of the flags for all tap listeners. */
786   tap_flags = union_of_tap_listener_flags();
787
788   *err = 0;
789
790   new_packet_list_check_end();
791   /* Don't freeze/thaw the list when doing live capture */
792   /*new_packet_list_freeze();*/
793
794   /*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: %u new: %u", cf->count, to_read);*/
795
796   while (to_read != 0) {
797     wtap_cleareof(cf->wth);
798     if (!wtap_read(cf->wth, err, &err_info, &data_offset)) {
799       break;
800     }
801     if (cf->state == FILE_READ_ABORTED) {
802       /* Well, the user decided to exit Wireshark.  Break out of the
803          loop, and let the code below (which is called even if there
804          aren't any packets left to read) exit. */
805       break;
806     }
807     TRY{
808       if (read_packet(cf, dfcode, filtering_tap_listeners, tap_flags,
809                       data_offset) != -1) {
810         newly_displayed_packets++;
811       }
812     }
813     CATCH(OutOfMemoryError) {
814       simple_message_box(ESD_TYPE_ERROR, NULL,
815                      "Some infos / workarounds can be found at:\n"
816                      "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
817                      "Sorry, but Wireshark has run out of memory and has to terminate now!");
818 #if 0
819       /* Could we close the current capture and free up memory from that? */
820       return CF_READ_ABORTED;
821 #else
822       /* we have to terminate, as we cannot recover from the memory error */
823       exit(1);
824 #endif
825     }
826     ENDTRY;
827     to_read--;
828   }
829
830   /* Update the file encapsulation; it might have changed based on the
831      packets we've read. */
832   cf->lnk_t = wtap_file_encap(cf->wth);
833
834   /* Cleanup and release all dfilter resources */
835   if (dfcode != NULL){
836     dfilter_free(dfcode);
837   }
838
839   /*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: count %u state: %u err: %u",
840     cf->count, cf->state, *err);*/
841
842   /* Don't freeze/thaw the list when doing live capture */
843   /*new_packet_list_thaw();*/
844   /* With the new packet list the first packet
845    * isn't automatically selected.
846    */
847   if(!cf->current_frame)
848     new_packet_list_select_first_row();
849
850   /* moving to the end of the packet list - if the user requested so and
851      we have some new packets. */
852   if (newly_displayed_packets && auto_scroll_live && cf->count != 0)
853       new_packet_list_moveto_end();
854
855   if (cf->state == FILE_READ_ABORTED) {
856     /* Well, the user decided to exit Wireshark.  Return CF_READ_ABORTED
857        so that our caller can kill off the capture child process;
858        this will cause an EOF on the pipe from the child, so
859        "cf_finish_tail()" will be called, and it will clean up
860        and exit. */
861     return CF_READ_ABORTED;
862   } else if (*err != 0) {
863     /* We got an error reading the capture file.
864        XXX - pop up a dialog box instead? */
865     g_warning("Error \"%s\" while reading: \"%s\"\n",
866         wtap_strerror(*err), cf->filename);
867
868     return CF_READ_ERROR;
869   } else
870     return CF_READ_OK;
871 }
872
873 void
874 cf_fake_continue_tail(capture_file *cf) {
875   cf->state = FILE_READ_DONE;
876 }
877
878 cf_read_status_t
879 cf_finish_tail(capture_file *cf, int *err)
880 {
881   gchar *err_info;
882   gint64 data_offset;
883   dfilter_t   *dfcode;
884   gboolean filtering_tap_listeners;
885   guint tap_flags;
886   gboolean compiled;
887
888   /* Compile the current display filter.
889    * We assume this will not fail since cf->dfilter is only set in
890    * cf_filter IFF the filter was valid.
891    */
892   compiled = dfilter_compile(cf->dfilter, &dfcode);
893   g_assert(!cf->dfilter || (compiled && dfcode));
894
895   /* Do we have any tap listeners with filters? */
896   filtering_tap_listeners = have_filtering_tap_listeners();
897
898   /* Get the union of the flags for all tap listeners. */
899   tap_flags = union_of_tap_listener_flags();
900
901   if(cf->wth == NULL) {
902     cf_close(cf);
903     return CF_READ_ERROR;
904   }
905
906   new_packet_list_check_end();
907   /* Don't freeze/thaw the list when doing live capture */
908   /*new_packet_list_freeze();*/
909
910   while ((wtap_read(cf->wth, err, &err_info, &data_offset))) {
911     if (cf->state == FILE_READ_ABORTED) {
912       /* Well, the user decided to abort the read.  Break out of the
913          loop, and let the code below (which is called even if there
914          aren't any packets left to read) exit. */
915       break;
916     }
917     read_packet(cf, dfcode, filtering_tap_listeners, tap_flags, data_offset);
918   }
919
920   /* Cleanup and release all dfilter resources */
921   if (dfcode != NULL){
922     dfilter_free(dfcode);
923   }
924
925   /* Don't freeze/thaw the list when doing live capture */
926   /*new_packet_list_thaw();*/
927
928   if (cf->state == FILE_READ_ABORTED) {
929     /* Well, the user decided to abort the read.  We're only called
930        when the child capture process closes the pipe to us (meaning
931        it's probably exited), so we can just close the capture
932        file; we return CF_READ_ABORTED so our caller can do whatever
933        is appropriate when that happens. */
934     cf_close(cf);
935     return CF_READ_ABORTED;
936   }
937
938   if (auto_scroll_live && cf->count != 0)
939     new_packet_list_moveto_end();
940
941   /* We're done reading sequentially through the file. */
942   cf->state = FILE_READ_DONE;
943
944   /* We're done reading sequentially through the file; close the
945      sequential I/O side, to free up memory it requires. */
946   wtap_sequential_close(cf->wth);
947
948   /* Allow the protocol dissectors to free up memory that they
949    * don't need after the sequential run-through of the packets. */
950   postseq_cleanup_all_protocols();
951
952   /* Update the file encapsulation; it might have changed based on the
953      packets we've read. */
954   cf->lnk_t = wtap_file_encap(cf->wth);
955
956   /* Update the details in the file-set dialog, as the capture file
957    * has likely grown since we first stat-ed it */
958   fileset_update_file(cf->filename);
959
960   if (*err != 0) {
961     /* We got an error reading the capture file.
962        XXX - pop up a dialog box? */
963     return CF_READ_ERROR;
964   } else {
965     return CF_READ_OK;
966   }
967 }
968 #endif /* HAVE_LIBPCAP */
969
970 gchar *
971 cf_get_display_name(capture_file *cf)
972 {
973   gchar *displayname;
974
975   /* Return a name to use in displays */
976   if (!cf->is_tempfile) {
977     /* Get the last component of the file name, and use that. */
978     if (cf->filename){
979       displayname = g_filename_display_basename(cf->filename);
980     } else {
981       displayname=g_strdup("(No file)");
982     }
983   } else {
984     /* The file we read is a temporary file from a live capture or
985        a merge operation; we don't mention its name, but, if it's
986        from a capture, give the source of the capture. */
987     if (cf->source) {
988       displayname = g_strdup(cf->source);
989     } else {
990       displayname = g_strdup("(Untitled)");
991     }
992   }
993   return displayname;
994 }
995
996 void cf_set_tempfile_source(capture_file *cf, gchar *source) {
997   if (cf->source) {
998     g_free(cf->source);
999   }
1000
1001   if (source) {
1002     cf->source = g_strdup(source);
1003   } else {
1004     cf->source = g_strdup("");
1005   }
1006 }
1007
1008 const gchar *cf_get_tempfile_source(capture_file *cf) {
1009   if (!cf->source) {
1010     return "";
1011   }
1012
1013   return cf->source;
1014 }
1015
1016 /* XXX - use a macro instead? */
1017 int
1018 cf_get_packet_count(capture_file *cf)
1019 {
1020   return cf->count;
1021 }
1022
1023 /* XXX - use a macro instead? */
1024 void
1025 cf_set_packet_count(capture_file *cf, int packet_count)
1026 {
1027   cf->count = packet_count;
1028 }
1029
1030 /* XXX - use a macro instead? */
1031 gboolean
1032 cf_is_tempfile(capture_file *cf)
1033 {
1034   return cf->is_tempfile;
1035 }
1036
1037 void cf_set_tempfile(capture_file *cf, gboolean is_tempfile)
1038 {
1039   cf->is_tempfile = is_tempfile;
1040 }
1041
1042
1043 /* XXX - use a macro instead? */
1044 void cf_set_drops_known(capture_file *cf, gboolean drops_known)
1045 {
1046   cf->drops_known = drops_known;
1047 }
1048
1049 /* XXX - use a macro instead? */
1050 void cf_set_drops(capture_file *cf, guint32 drops)
1051 {
1052   cf->drops = drops;
1053 }
1054
1055 /* XXX - use a macro instead? */
1056 gboolean cf_get_drops_known(capture_file *cf)
1057 {
1058   return cf->drops_known;
1059 }
1060
1061 /* XXX - use a macro instead? */
1062 guint32 cf_get_drops(capture_file *cf)
1063 {
1064   return cf->drops;
1065 }
1066
1067 void cf_set_rfcode(capture_file *cf, dfilter_t *rfcode)
1068 {
1069   cf->rfcode = rfcode;
1070 }
1071
1072 static void
1073 find_and_mark_frame_depended_upon(gpointer data, gpointer user_data)
1074 {
1075   frame_data *dependent_fd;
1076   guint32 dependent_frame = GPOINTER_TO_UINT(data);
1077   capture_file *cf = (capture_file *)user_data;
1078
1079   dependent_fd = frame_data_sequence_find(cf->frames, dependent_frame);
1080   dependent_fd->flags.dependent_of_displayed = 1;
1081 }
1082
1083 static int
1084 add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
1085     dfilter_t *dfcode, gboolean filtering_tap_listeners,
1086     guint tap_flags,
1087     union wtap_pseudo_header *pseudo_header, const guchar *buf,
1088     gboolean refilter,
1089     gboolean add_to_packet_list)
1090 {
1091   gboolean  create_proto_tree = FALSE;
1092   epan_dissect_t edt;
1093   column_info *cinfo;
1094   gint row = -1;
1095
1096   cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
1097
1098   frame_data_set_before_dissect(fdata, &cf->elapsed_time,
1099                                 &first_ts, &prev_dis_ts, &prev_cap_ts);
1100
1101   /* If either
1102     + we have a display filter and are re-applying it;
1103     + we have tap listeners with filters;
1104     + we have tap listeners that require a protocol tree;
1105
1106      allocate a protocol tree root node, so that we'll construct
1107      a protocol tree against which a filter expression can be
1108      evaluated. */
1109   if ((dfcode != NULL && refilter) ||
1110       filtering_tap_listeners || (tap_flags & TL_REQUIRES_PROTO_TREE))
1111       create_proto_tree = TRUE;
1112
1113   /* Dissect the frame. */
1114   epan_dissect_init(&edt, create_proto_tree, FALSE);
1115
1116   if (dfcode != NULL && refilter) {
1117       epan_dissect_prime_dfilter(&edt, dfcode);
1118   }
1119
1120   tap_queue_init(&edt);
1121   epan_dissect_run(&edt, pseudo_header, buf, fdata, cinfo);
1122   tap_push_tapped_queue(&edt);
1123
1124   /* If we have a display filter, apply it if we're refiltering, otherwise
1125      leave the "passed_dfilter" flag alone.
1126
1127      If we don't have a display filter, set "passed_dfilter" to 1. */
1128   if (dfcode != NULL) {
1129     if (refilter) {
1130       fdata->flags.passed_dfilter = dfilter_apply_edt(dfcode, &edt) ? 1 : 0;
1131
1132       if (fdata->flags.passed_dfilter) {
1133         /* This frame passed the display filter but it may depend on other
1134          * (potentially not displayed) frames.  Find those frames and mark them
1135          * as depended upon.
1136          */
1137         g_slist_foreach(edt.pi.dependent_frames, find_and_mark_frame_depended_upon, cf);
1138       }
1139     }
1140   } else
1141     fdata->flags.passed_dfilter = 1;
1142
1143   if(fdata->flags.passed_dfilter || fdata->flags.ref_time)
1144     cf->displayed_count++;
1145
1146   if (add_to_packet_list) {
1147     /* We fill the needed columns from new_packet_list */
1148       row = new_packet_list_append(cinfo, fdata, &edt.pi);
1149   }
1150
1151   if(fdata->flags.passed_dfilter || fdata->flags.ref_time)
1152   {
1153     frame_data_set_after_dissect(fdata, &cum_bytes, &prev_dis_ts);
1154
1155     /* If we haven't yet seen the first frame, this is it.
1156
1157        XXX - we must do this before we add the row to the display,
1158        as, if the display's GtkCList's selection mode is
1159        GTK_SELECTION_BROWSE, when the first entry is added to it,
1160        "cf_select_packet()" will be called, and it will fetch the row
1161        data for the 0th row, and will get a null pointer rather than
1162        "fdata", as "gtk_clist_append()" won't yet have returned and
1163        thus "gtk_clist_set_row_data()" won't yet have been called.
1164
1165        We thus need to leave behind bread crumbs so that
1166        "cf_select_packet()" can find this frame.  See the comment
1167        in "cf_select_packet()". */
1168     if (cf->first_displayed == 0)
1169       cf->first_displayed = fdata->num;
1170
1171     /* This is the last frame we've seen so far. */
1172     cf->last_displayed = fdata->num;
1173   }
1174
1175   epan_dissect_cleanup(&edt);
1176   return row;
1177 }
1178
1179 /* read in a new packet */
1180 /* returns the row of the new packet in the packet list or -1 if not displayed */
1181 static int
1182 read_packet(capture_file *cf, dfilter_t *dfcode,
1183             gboolean filtering_tap_listeners, guint tap_flags, gint64 offset)
1184 {
1185   const struct wtap_pkthdr *phdr = wtap_phdr(cf->wth);
1186   union wtap_pseudo_header *pseudo_header = wtap_pseudoheader(cf->wth);
1187   const guchar *buf = wtap_buf_ptr(cf->wth);
1188   frame_data    fdlocal;
1189   guint32       framenum;
1190   frame_data   *fdata;
1191   int           passed;
1192   int           row = -1;
1193
1194   /* Add this packet's link-layer encapsulation type to cf->linktypes, if
1195      it's not already there.
1196      XXX - yes, this is O(N), so if every packet had a different
1197      link-layer encapsulation type, it'd be O(N^2) to read the file, but
1198      there are probably going to be a small number of encapsulation types
1199      in a file. */
1200   cf_add_encapsulation_type(cf, phdr->pkt_encap);
1201
1202   /* The frame number of this packet is one more than the count of
1203      frames in the file so far. */
1204   framenum = cf->count + 1;
1205
1206   frame_data_init(&fdlocal, framenum, phdr, offset, cum_bytes);
1207
1208   passed = TRUE;
1209   if (cf->rfcode) {
1210     epan_dissect_t edt;
1211     epan_dissect_init(&edt, TRUE, FALSE);
1212     epan_dissect_prime_dfilter(&edt, cf->rfcode);
1213     epan_dissect_run(&edt, pseudo_header, buf, &fdlocal, NULL);
1214     passed = dfilter_apply_edt(cf->rfcode, &edt);
1215     epan_dissect_cleanup(&edt);
1216   }
1217
1218   if (passed) {
1219     /* This does a shallow copy of fdlocal, which is good enough. */
1220     fdata = frame_data_sequence_add(cf->frames, &fdlocal);
1221
1222     cf->count++;
1223     if (fdlocal.opt_comment != NULL)
1224       cf->packet_comment_count++;
1225     cf->f_datalen = offset + fdlocal.cap_len;
1226
1227     if (!cf->redissecting) {
1228       row = add_packet_to_packet_list(fdata, cf, dfcode,
1229                                       filtering_tap_listeners, tap_flags,
1230                                       pseudo_header, buf, TRUE, TRUE);
1231     }
1232   }
1233
1234   return row;
1235 }
1236
1237 cf_status_t
1238 cf_merge_files(char **out_filenamep, int in_file_count,
1239                char *const *in_filenames, int file_type, gboolean do_append)
1240 {
1241   merge_in_file_t  *in_files, *in_file;
1242   char             *out_filename;
1243   char             *tmpname;
1244   int               out_fd;
1245   wtap_dumper      *pdh;
1246   int               open_err, read_err, write_err, close_err;
1247   gchar            *err_info;
1248   int               err_fileno;
1249   int               i;
1250   gboolean          got_read_error = FALSE, got_write_error = FALSE;
1251   gint64            data_offset;
1252   progdlg_t        *progbar = NULL;
1253   gboolean          stop_flag;
1254   gint64            f_len, file_pos;
1255   float             progbar_val;
1256   GTimeVal          start_time;
1257   gchar             status_str[100];
1258   gint64            progbar_nextstep;
1259   gint64            progbar_quantum;
1260   gchar            *display_basename;
1261
1262   /* open the input files */
1263   if (!merge_open_in_files(in_file_count, in_filenames, &in_files,
1264                            &open_err, &err_info, &err_fileno)) {
1265     g_free(in_files);
1266     cf_open_failure_alert_box(in_filenames[err_fileno], open_err, err_info,
1267                               FALSE, 0);
1268     return CF_ERROR;
1269   }
1270
1271   if (*out_filenamep != NULL) {
1272     out_filename = *out_filenamep;
1273     out_fd = ws_open(out_filename, O_CREAT|O_TRUNC|O_BINARY, 0600);
1274     if (out_fd == -1)
1275       open_err = errno;
1276   } else {
1277     out_fd = create_tempfile(&tmpname, "wireshark");
1278     if (out_fd == -1)
1279       open_err = errno;
1280     out_filename = g_strdup(tmpname);
1281     *out_filenamep = out_filename;
1282   }
1283   if (out_fd == -1) {
1284     err_info = NULL;
1285     merge_close_in_files(in_file_count, in_files);
1286     g_free(in_files);
1287     cf_open_failure_alert_box(out_filename, open_err, NULL, TRUE, file_type);
1288     return CF_ERROR;
1289   }
1290
1291   pdh = wtap_dump_fdopen(out_fd, file_type,
1292       merge_select_frame_type(in_file_count, in_files),
1293       merge_max_snapshot_length(in_file_count, in_files),
1294       FALSE /* compressed */, &open_err);
1295   if (pdh == NULL) {
1296     ws_close(out_fd);
1297     merge_close_in_files(in_file_count, in_files);
1298     g_free(in_files);
1299     cf_open_failure_alert_box(out_filename, open_err, err_info, TRUE,
1300                               file_type);
1301     return CF_ERROR;
1302   }
1303
1304   /* Get the sum of the sizes of all the files. */
1305   f_len = 0;
1306   for (i = 0; i < in_file_count; i++)
1307     f_len += in_files[i].size;
1308
1309   /* Update the progress bar when it gets to this value. */
1310   progbar_nextstep = 0;
1311   /* When we reach the value that triggers a progress bar update,
1312      bump that value by this amount. */
1313   progbar_quantum = f_len/N_PROGBAR_UPDATES;
1314   /* Progress so far. */
1315   progbar_val = 0.0f;
1316
1317   stop_flag = FALSE;
1318   g_get_current_time(&start_time);
1319
1320   /* do the merge (or append) */
1321   for (;;) {
1322     if (do_append)
1323       in_file = merge_append_read_packet(in_file_count, in_files, &read_err,
1324                                          &err_info);
1325     else
1326       in_file = merge_read_packet(in_file_count, in_files, &read_err,
1327                                   &err_info);
1328     if (in_file == NULL) {
1329       /* EOF */
1330       break;
1331     }
1332
1333     if (read_err != 0) {
1334       /* I/O error reading from in_file */
1335       got_read_error = TRUE;
1336       break;
1337     }
1338
1339     /* Get the sum of the data offsets in all of the files. */
1340     data_offset = 0;
1341     for (i = 0; i < in_file_count; i++)
1342       data_offset += in_files[i].data_offset;
1343
1344     /* Create the progress bar if necessary.
1345        We check on every iteration of the loop, so that it takes no
1346        longer than the standard time to create it (otherwise, for a
1347        large file, we might take considerably longer than that standard
1348        time in order to get to the next progress bar step). */
1349     if (progbar == NULL) {
1350       progbar = delayed_create_progress_dlg(NULL, "Merging", "files",
1351         FALSE, &stop_flag, &start_time, progbar_val);
1352     }
1353
1354     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1355        when we update it, we have to run the GTK+ main loop to get it
1356        to repaint what's pending, and doing so may involve an "ioctl()"
1357        to see if there's any pending input from an X server, and doing
1358        that for every packet can be costly, especially on a big file. */
1359     if (data_offset >= progbar_nextstep) {
1360         /* Get the sum of the seek positions in all of the files. */
1361         file_pos = 0;
1362         for (i = 0; i < in_file_count; i++)
1363           file_pos += wtap_read_so_far(in_files[i].wth);
1364         progbar_val = (gfloat) file_pos / (gfloat) f_len;
1365         if (progbar_val > 1.0f) {
1366           /* Some file probably grew while we were reading it.
1367              That "shouldn't happen", so we'll just clip the progress
1368              value at 1.0. */
1369           progbar_val = 1.0f;
1370         }
1371         if (progbar != NULL) {
1372           g_snprintf(status_str, sizeof(status_str),
1373                      "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
1374                      file_pos / 1024, f_len / 1024);
1375           update_progress_dlg(progbar, progbar_val, status_str);
1376         }
1377         progbar_nextstep += progbar_quantum;
1378     }
1379
1380     if (stop_flag) {
1381       /* Well, the user decided to abort the merge. */
1382       break;
1383     }
1384
1385     if (!wtap_dump(pdh, wtap_phdr(in_file->wth), wtap_pseudoheader(in_file->wth),
1386          wtap_buf_ptr(in_file->wth), &write_err)) {
1387       got_write_error = TRUE;
1388       break;
1389     }
1390   }
1391
1392   /* We're done merging the files; destroy the progress bar if it was created. */
1393   if (progbar != NULL)
1394     destroy_progress_dlg(progbar);
1395
1396   merge_close_in_files(in_file_count, in_files);
1397   if (!got_read_error && !got_write_error) {
1398     if (!wtap_dump_close(pdh, &write_err))
1399       got_write_error = TRUE;
1400   } else
1401     wtap_dump_close(pdh, &close_err);
1402
1403   if (got_read_error) {
1404     /*
1405      * Find the file on which we got the error, and report the error.
1406      */
1407     for (i = 0; i < in_file_count; i++) {
1408       if (in_files[i].state == GOT_ERROR) {
1409         /* Put up a message box noting that a read failed somewhere along
1410            the line. */
1411         display_basename = g_filename_display_basename(in_files[i].filename);
1412         switch (read_err) {
1413
1414         case WTAP_ERR_UNSUPPORTED_ENCAP:
1415           simple_error_message_box(
1416                      "The capture file %s has a packet with a network type that Wireshark doesn't support.\n(%s)",
1417                      display_basename, err_info);
1418           g_free(err_info);
1419           break;
1420
1421         case WTAP_ERR_CANT_READ:
1422           simple_error_message_box(
1423                      "An attempt to read from the capture file %s failed for"
1424                      " some unknown reason.", display_basename);
1425           break;
1426
1427         case WTAP_ERR_SHORT_READ:
1428           simple_error_message_box(
1429                      "The capture file %s appears to have been cut short"
1430                       " in the middle of a packet.", display_basename);
1431           break;
1432
1433         case WTAP_ERR_BAD_FILE:
1434           simple_error_message_box(
1435                      "The capture file %s appears to be damaged or corrupt.\n(%s)",
1436                      display_basename, err_info);
1437           g_free(err_info);
1438           break;
1439
1440         case WTAP_ERR_DECOMPRESS:
1441           simple_error_message_box(
1442                      "The compressed capture file %s appears to be damaged or corrupt.\n"
1443                      "(%s)", display_basename, err_info);
1444           g_free(err_info);
1445           break;
1446
1447         default:
1448           simple_error_message_box(
1449                      "An error occurred while reading the"
1450                      " capture file %s: %s.",
1451                      display_basename,  wtap_strerror(read_err));
1452           break;
1453         }
1454         g_free(display_basename);
1455       }
1456     }
1457   }
1458
1459   if (got_write_error) {
1460     /* Put up an alert box for the write error. */
1461     if (write_err < 0) {
1462       /* Wiretap error. */
1463       switch (write_err) {
1464
1465       case WTAP_ERR_UNSUPPORTED_ENCAP:
1466         /*
1467          * This is a problem with the particular frame we're writing;
1468          * note that, and give the frame number.
1469          */
1470         display_basename = g_filename_display_basename(in_file->filename);
1471         simple_error_message_box(
1472                       "Frame %u of \"%s\" has a network type that can't be saved in a \"%s\" file.",
1473                       in_file->packet_num, display_basename,
1474                       wtap_file_type_string(file_type));
1475         g_free(display_basename);
1476         break;
1477
1478       default:
1479         display_basename = g_filename_display_basename(out_filename);
1480         simple_error_message_box(
1481                       "An error occurred while writing to the file \"%s\": %s.",
1482                       out_filename, wtap_strerror(write_err));
1483         g_free(display_basename);
1484         break;
1485       }
1486     } else {
1487       /* OS error. */
1488       write_failure_alert_box(out_filename, write_err);
1489     }
1490   }
1491
1492   if (got_read_error || got_write_error || stop_flag) {
1493     /* Callers aren't expected to treat an error or an explicit abort
1494        differently - we put up error dialogs ourselves, so they don't
1495        have to. */
1496     return CF_ERROR;
1497   } else
1498     return CF_OK;
1499 }
1500
1501 cf_status_t
1502 cf_filter_packets(capture_file *cf, gchar *dftext, gboolean force)
1503 {
1504   const char *filter_new = dftext ? dftext : "";
1505   const char *filter_old = cf->dfilter ? cf->dfilter : "";
1506   dfilter_t   *dfcode;
1507   GTimeVal     start_time;
1508
1509   /* if new filter equals old one, do nothing unless told to do so */
1510   if (!force && strcmp(filter_new, filter_old) == 0) {
1511     return CF_OK;
1512   }
1513
1514   dfcode=NULL;
1515
1516   if (dftext == NULL) {
1517     /* The new filter is an empty filter (i.e., display all packets).
1518      * so leave dfcode==NULL
1519      */
1520   } else {
1521     /*
1522      * We have a filter; make a copy of it (as we'll be saving it),
1523      * and try to compile it.
1524      */
1525     dftext = g_strdup(dftext);
1526     if (!dfilter_compile(dftext, &dfcode)) {
1527       /* The attempt failed; report an error. */
1528       gchar *safe_dftext = simple_dialog_format_message(dftext);
1529       gchar *safe_dfilter_error_msg = simple_dialog_format_message(dfilter_error_msg);
1530       simple_message_box(ESD_TYPE_ERROR, NULL,
1531           "See the help for a description of the display filter syntax.",
1532           "\"%s\" isn't a valid display filter: %s",
1533           safe_dftext, safe_dfilter_error_msg);
1534       g_free(safe_dfilter_error_msg);
1535       g_free(safe_dftext);
1536       g_free(dftext);
1537       return CF_ERROR;
1538     }
1539
1540     /* Was it empty? */
1541     if (dfcode == NULL) {
1542       /* Yes - free the filter text, and set it to null. */
1543       g_free(dftext);
1544       dftext = NULL;
1545     }
1546   }
1547
1548   /* We have a valid filter.  Replace the current filter. */
1549   g_free(cf->dfilter);
1550   cf->dfilter = dftext;
1551   g_get_current_time(&start_time);
1552
1553
1554   /* Now rescan the packet list, applying the new filter, but not
1555      throwing away information constructed on a previous pass. */
1556   if (dftext == NULL) {
1557     rescan_packets(cf, "Resetting", "Filter", TRUE, FALSE);
1558   } else {
1559     rescan_packets(cf, "Filtering", dftext, TRUE, FALSE);
1560   }
1561
1562   /* Cleanup and release all dfilter resources */
1563   dfilter_free(dfcode);
1564
1565   return CF_OK;
1566 }
1567
1568 void
1569 cf_reftime_packets(capture_file *cf)
1570 {
1571
1572   ref_time_packets(cf);
1573 }
1574
1575 void
1576 cf_redissect_packets(capture_file *cf)
1577 {
1578   rescan_packets(cf, "Reprocessing", "all packets", TRUE, TRUE);
1579 }
1580
1581 gboolean
1582 cf_read_frame_r(capture_file *cf, frame_data *fdata,
1583                 union wtap_pseudo_header *pseudo_header, guint8 *pd)
1584 {
1585   int err;
1586   gchar *err_info;
1587   gchar *display_basename;
1588
1589 #ifdef WANT_PACKET_EDITOR
1590   /* if fdata->file_off == -1 it means packet was edited, and we must find data inside edited_frames tree */
1591   if (G_UNLIKELY(fdata->file_off == -1)) {
1592     const modified_frame_data *frame = (const modified_frame_data *) g_tree_lookup(cf->edited_frames, GINT_TO_POINTER(fdata->num));
1593
1594     if (!frame) {
1595       simple_error_message_box("fdata->file_off == -1, but can't find modified frame!");
1596       return FALSE;
1597     }
1598
1599     *pseudo_header = frame->ph;
1600     memcpy(pd, frame->pd, fdata->cap_len);
1601     return TRUE;
1602   }
1603 #endif
1604
1605   if (!wtap_seek_read(cf->wth, fdata->file_off, pseudo_header, pd,
1606                       fdata->cap_len, &err, &err_info)) {
1607     display_basename = g_filename_display_basename(cf->filename);
1608     switch (err) {
1609
1610     case WTAP_ERR_UNSUPPORTED_ENCAP:
1611       simple_error_message_box("The file \"%s\" has a packet with a network type that Wireshark doesn't support.\n(%s)",
1612                  display_basename, err_info);
1613       g_free(err_info);
1614       break;
1615
1616     case WTAP_ERR_BAD_FILE:
1617       simple_error_message_box("An error occurred while reading from the file \"%s\": %s.\n(%s)",
1618                  display_basename, wtap_strerror(err), err_info);
1619       g_free(err_info);
1620       break;
1621
1622     default:
1623       simple_error_message_box(
1624                  "An error occurred while reading from the file \"%s\": %s.",
1625                  display_basename, wtap_strerror(err));
1626       break;
1627     }
1628     g_free(display_basename);
1629     return FALSE;
1630   }
1631   return TRUE;
1632 }
1633
1634 gboolean
1635 cf_read_frame(capture_file *cf, frame_data *fdata)
1636 {
1637   return cf_read_frame_r(cf, fdata, &cf->pseudo_header, cf->pd);
1638 }
1639
1640 /* Rescan the list of packets, reconstructing the CList.
1641
1642    "action" describes why we're doing this; it's used in the progress
1643    dialog box.
1644
1645    "action_item" describes what we're doing; it's used in the progress
1646    dialog box.
1647
1648    "refilter" is TRUE if we need to re-evaluate the filter expression.
1649
1650    "redissect" is TRUE if we need to make the dissectors reconstruct
1651    any state information they have (because a preference that affects
1652    some dissector has changed, meaning some dissector might construct
1653    its state differently from the way it was constructed the last time). */
1654 static void
1655 rescan_packets(capture_file *cf, const char *action, const char *action_item,
1656         gboolean refilter, gboolean redissect)
1657 {
1658   /* Rescan packets new packet list */
1659   guint32     framenum;
1660   frame_data *fdata;
1661   progdlg_t  *progbar = NULL;
1662   gboolean    stop_flag;
1663   int         count;
1664   frame_data *selected_frame, *preceding_frame, *following_frame, *prev_frame;
1665   int         selected_frame_num, preceding_frame_num, following_frame_num, prev_frame_num;
1666   gboolean    selected_frame_seen;
1667   float       progbar_val;
1668   GTimeVal    start_time;
1669   gchar       status_str[100];
1670   int         progbar_nextstep;
1671   int         progbar_quantum;
1672   dfilter_t   *dfcode;
1673   gboolean    filtering_tap_listeners;
1674   guint       tap_flags;
1675   gboolean    add_to_packet_list = FALSE;
1676   gboolean compiled;
1677
1678   /* Compile the current display filter.
1679    * We assume this will not fail since cf->dfilter is only set in
1680    * cf_filter IFF the filter was valid.
1681    */
1682   compiled = dfilter_compile(cf->dfilter, &dfcode);
1683   g_assert(!cf->dfilter || (compiled && dfcode));
1684
1685   /* Do we have any tap listeners with filters? */
1686   filtering_tap_listeners = have_filtering_tap_listeners();
1687
1688   /* Get the union of the flags for all tap listeners. */
1689   tap_flags = union_of_tap_listener_flags();
1690
1691   reset_tap_listeners();
1692   /* Which frame, if any, is the currently selected frame?
1693      XXX - should the selected frame or the focus frame be the "current"
1694      frame, that frame being the one from which "Find Frame" searches
1695      start? */
1696   selected_frame = cf->current_frame;
1697
1698   /* Mark frame num as not found */
1699   selected_frame_num = -1;
1700
1701   /* Freeze the packet list while we redo it, so we don't get any
1702      screen updates while it happens. */
1703   new_packet_list_freeze();
1704
1705   if (redissect) {
1706     /* We need to re-initialize all the state information that protocols
1707        keep, because some preference that controls a dissector has changed,
1708        which might cause the state information to be constructed differently
1709        by that dissector. */
1710
1711     /* We might receive new packets while redissecting, and we don't
1712        want to dissect those before their time. */
1713     cf->redissecting = TRUE;
1714
1715     /* Cleanup all data structures used for dissection. */
1716     cleanup_dissection();
1717     /* Initialize all data structures used for dissection. */
1718     init_dissection();
1719
1720     /* We need to redissect the packets so we have to discard our old
1721      * packet list store. */
1722     new_packet_list_clear();
1723     add_to_packet_list = TRUE;
1724   }
1725
1726   /* We don't yet know which will be the first and last frames displayed. */
1727   cf->first_displayed = 0;
1728   cf->last_displayed = 0;
1729
1730   /* We currently don't display any packets */
1731   cf->displayed_count = 0;
1732
1733   /* Iterate through the list of frames.  Call a routine for each frame
1734      to check whether it should be displayed and, if so, add it to
1735      the display list. */
1736   nstime_set_unset(&first_ts);
1737   nstime_set_unset(&prev_dis_ts);
1738   nstime_set_unset(&prev_cap_ts);
1739   cum_bytes = 0;
1740
1741   /* Update the progress bar when it gets to this value. */
1742   progbar_nextstep = 0;
1743   /* When we reach the value that triggers a progress bar update,
1744      bump that value by this amount. */
1745   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
1746   /* Count of packets at which we've looked. */
1747   count = 0;
1748   /* Progress so far. */
1749   progbar_val = 0.0f;
1750
1751   stop_flag = FALSE;
1752   g_get_current_time(&start_time);
1753
1754   /* no previous row yet */
1755   prev_frame_num = -1;
1756   prev_frame = NULL;
1757
1758   preceding_frame_num = -1;
1759   preceding_frame = NULL;
1760   following_frame_num = -1;
1761   following_frame = NULL;
1762
1763   selected_frame_seen = FALSE;
1764
1765   for (framenum = 1; framenum <= cf->count; framenum++) {
1766     fdata = frame_data_sequence_find(cf->frames, framenum);
1767
1768     /* Create the progress bar if necessary.
1769        We check on every iteration of the loop, so that it takes no
1770        longer than the standard time to create it (otherwise, for a
1771        large file, we might take considerably longer than that standard
1772        time in order to get to the next progress bar step). */
1773     if (progbar == NULL)
1774       progbar = delayed_create_progress_dlg(cf->window, action, action_item, TRUE,
1775                                             &stop_flag, &start_time,
1776                                             progbar_val);
1777
1778     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1779        when we update it, we have to run the GTK+ main loop to get it
1780        to repaint what's pending, and doing so may involve an "ioctl()"
1781        to see if there's any pending input from an X server, and doing
1782        that for every packet can be costly, especially on a big file. */
1783     if (count >= progbar_nextstep) {
1784       /* let's not divide by zero. I should never be started
1785        * with count == 0, so let's assert that
1786        */
1787       g_assert(cf->count > 0);
1788       progbar_val = (gfloat) count / cf->count;
1789
1790       if (progbar != NULL) {
1791         g_snprintf(status_str, sizeof(status_str),
1792                   "%4u of %u frames", count, cf->count);
1793         update_progress_dlg(progbar, progbar_val, status_str);
1794       }
1795
1796       progbar_nextstep += progbar_quantum;
1797     }
1798
1799     if (stop_flag) {
1800       /* Well, the user decided to abort the filtering.  Just stop.
1801
1802          XXX - go back to the previous filter?  Users probably just
1803          want not to wait for a filtering operation to finish;
1804          unless we cancel by having no filter, reverting to the
1805          previous filter will probably be even more expensive than
1806          continuing the filtering, as it involves going back to the
1807          beginning and filtering, and even with no filter we currently
1808          have to re-generate the entire clist, which is also expensive.
1809
1810          I'm not sure what Network Monitor does, but it doesn't appear
1811          to give you an unfiltered display if you cancel. */
1812       break;
1813     }
1814
1815     count++;
1816
1817     if (redissect) {
1818       /* Since all state for the frame was destroyed, mark the frame
1819        * as not visited, free the GSList referring to the state
1820        * data (the per-frame data itself was freed by
1821        * "init_dissection()"), and null out the GSList pointer. */
1822       fdata->flags.visited = 0;
1823       frame_data_cleanup(fdata);
1824     }
1825
1826     if (redissect || refilter) {
1827       /* If we're redissecting or refiltering then any frame dependencies
1828        * from the previous dissection/filtering are no longer valid.
1829        */
1830       fdata->flags.dependent_of_displayed = 0;
1831     }
1832
1833     if (!cf_read_frame(cf, fdata))
1834       break; /* error reading the frame */
1835
1836     /* If the previous frame is displayed, and we haven't yet seen the
1837        selected frame, remember that frame - it's the closest one we've
1838        yet seen before the selected frame. */
1839     if (prev_frame_num != -1 && !selected_frame_seen && prev_frame->flags.passed_dfilter) {
1840       preceding_frame_num = prev_frame_num;
1841       preceding_frame = prev_frame;
1842     }
1843     add_packet_to_packet_list(fdata, cf, dfcode, filtering_tap_listeners,
1844                                     tap_flags, &cf->pseudo_header, cf->pd,
1845                                     refilter,
1846                                     add_to_packet_list);
1847
1848     /* If this frame is displayed, and this is the first frame we've
1849        seen displayed after the selected frame, remember this frame -
1850        it's the closest one we've yet seen at or after the selected
1851        frame. */
1852     if (fdata->flags.passed_dfilter && selected_frame_seen && following_frame_num == -1) {
1853       following_frame_num = fdata->num;
1854       following_frame = fdata;
1855     }
1856     if (fdata == selected_frame) {
1857       selected_frame_seen = TRUE;
1858       if (fdata->flags.passed_dfilter)
1859           selected_frame_num = fdata->num;
1860     }
1861
1862     /* Remember this frame - it'll be the previous frame
1863        on the next pass through the loop. */
1864     prev_frame_num = fdata->num;
1865     prev_frame = fdata;
1866   }
1867
1868   /* We are done redissecting the packet list. */
1869   cf->redissecting = FALSE;
1870
1871   if (redissect) {
1872     /* Clear out what remains of the visited flags and per-frame data
1873        pointers.
1874
1875        XXX - that may cause various forms of bogosity when dissecting
1876        these frames, as they won't have been seen by this sequential
1877        pass, but the only alternative I see is to keep scanning them
1878        even though the user requested that the scan stop, and that
1879        would leave the user stuck with an Wireshark grinding on
1880        until it finishes.  Should we just stick them with that? */
1881     for (; framenum <= cf->count; framenum++) {
1882       fdata = frame_data_sequence_find(cf->frames, framenum);
1883       fdata->flags.visited = 0;
1884       frame_data_cleanup(fdata);
1885     }
1886   }
1887
1888   /* We're done filtering the packets; destroy the progress bar if it
1889      was created. */
1890   if (progbar != NULL)
1891     destroy_progress_dlg(progbar);
1892
1893   /* Unfreeze the packet list. */
1894   if (!add_to_packet_list)
1895     new_packet_list_recreate_visible_rows();
1896
1897   /* Compute the time it took to filter the file */
1898   compute_elapsed(&start_time);
1899
1900   new_packet_list_thaw();
1901
1902   if (selected_frame_num == -1) {
1903     /* The selected frame didn't pass the filter. */
1904     if (selected_frame == NULL) {
1905       /* That's because there *was* no selected frame.  Make the first
1906          displayed frame the current frame. */
1907       selected_frame_num = 0;
1908     } else {
1909       /* Find the nearest displayed frame to the selected frame (whether
1910          it's before or after that frame) and make that the current frame.
1911          If the next and previous displayed frames are equidistant from the
1912          selected frame, choose the next one. */
1913       g_assert(following_frame == NULL ||
1914                following_frame->num >= selected_frame->num);
1915       g_assert(preceding_frame == NULL ||
1916                preceding_frame->num <= selected_frame->num);
1917       if (following_frame == NULL) {
1918         /* No frame after the selected frame passed the filter, so we
1919            have to select the last displayed frame before the selected
1920            frame. */
1921         selected_frame_num = preceding_frame_num;
1922         selected_frame = preceding_frame;
1923       } else if (preceding_frame == NULL) {
1924         /* No frame before the selected frame passed the filter, so we
1925            have to select the first displayed frame after the selected
1926            frame. */
1927         selected_frame_num = following_frame_num;
1928         selected_frame = following_frame;
1929       } else {
1930         /* Frames before and after the selected frame passed the filter, so
1931            we'll select the previous frame */
1932         selected_frame_num = preceding_frame_num;
1933         selected_frame = preceding_frame;
1934       }
1935     }
1936   }
1937
1938   if (selected_frame_num == -1) {
1939     /* There are no frames displayed at all. */
1940     cf_unselect_packet(cf);
1941   } else {
1942     /* Either the frame that was selected passed the filter, or we've
1943        found the nearest displayed frame to that frame.  Select it, make
1944        it the focus row, and make it visible. */
1945     /* Set to invalid to force update of packet list and packet details */
1946     cf->current_row = -1;
1947     if (selected_frame_num == 0) {
1948       new_packet_list_select_first_row();
1949     }else{
1950       if (!new_packet_list_select_row_from_data(selected_frame)) {
1951         /* We didn't find a row corresponding to this frame.
1952            This means that the frame isn't being displayed currently,
1953            so we can't select it. */
1954         simple_message_box(ESD_TYPE_INFO, NULL,
1955                            "The capture file is probably not fully dissected.",
1956                            "End of capture exceeded!");
1957       }
1958     }
1959   }
1960
1961   /* Cleanup and release all dfilter resources */
1962   dfilter_free(dfcode);
1963 }
1964
1965
1966 /*
1967  * Scan trough all frame data and recalculate the ref time
1968  * without rereading the file.
1969  * XXX - do we need a progres bar or is this fast enough?
1970  */
1971 static void
1972 ref_time_packets(capture_file *cf)
1973 {
1974   guint32 framenum;
1975   frame_data *fdata;
1976
1977   nstime_set_unset(&first_ts);
1978   nstime_set_unset(&prev_dis_ts);
1979   cum_bytes = 0;
1980
1981   for (framenum = 1; framenum <= cf->count; framenum++) {
1982     fdata = frame_data_sequence_find(cf->frames, framenum);
1983
1984     /* just add some value here until we know if it is being displayed or not */
1985     fdata->cum_bytes = cum_bytes + fdata->pkt_len;
1986
1987     /*
1988      *Timestamps
1989      */
1990
1991     /* If we don't have the time stamp of the first packet in the
1992      capture, it's because this is the first packet.  Save the time
1993      stamp of this packet as the time stamp of the first packet. */
1994     if (nstime_is_unset(&first_ts)) {
1995         first_ts  = fdata->abs_ts;
1996     }
1997       /* if this frames is marked as a reference time frame, reset
1998         firstsec and firstusec to this frame */
1999     if(fdata->flags.ref_time){
2000         first_ts = fdata->abs_ts;
2001     }
2002
2003     /* If we don't have the time stamp of the previous displayed packet,
2004      it's because this is the first displayed packet.  Save the time
2005      stamp of this packet as the time stamp of the previous displayed
2006      packet. */
2007     if (nstime_is_unset(&prev_dis_ts)) {
2008         prev_dis_ts = fdata->abs_ts;
2009     }
2010
2011     /* Get the time elapsed between the first packet and this packet. */
2012     nstime_delta(&fdata->rel_ts, &fdata->abs_ts, &first_ts);
2013
2014     /* If it's greater than the current elapsed time, set the elapsed time
2015      to it (we check for "greater than" so as not to be confused by
2016      time moving backwards). */
2017     if ((gint32)cf->elapsed_time.secs < fdata->rel_ts.secs
2018         || ((gint32)cf->elapsed_time.secs == fdata->rel_ts.secs && (gint32)cf->elapsed_time.nsecs < fdata->rel_ts.nsecs)) {
2019         cf->elapsed_time = fdata->rel_ts;
2020     }
2021
2022     /* If this frame is displayed, get the time elapsed between the
2023      previous displayed packet and this packet. */
2024     if( fdata->flags.passed_dfilter ) {
2025         nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, &prev_dis_ts);
2026         prev_dis_ts = fdata->abs_ts;
2027     }
2028
2029     /*
2030      * Byte counts
2031      */
2032     if( (fdata->flags.passed_dfilter) || (fdata->flags.ref_time) ){
2033         /* This frame either passed the display filter list or is marked as
2034         a time reference frame.  All time reference frames are displayed
2035         even if they dont pass the display filter */
2036         if(fdata->flags.ref_time){
2037             /* if this was a TIME REF frame we should reset the cum_bytes field */
2038             cum_bytes = fdata->pkt_len;
2039             fdata->cum_bytes =  cum_bytes;
2040         } else {
2041             /* increase cum_bytes with this packets length */
2042             cum_bytes += fdata->pkt_len;
2043         }
2044     }
2045   }
2046 }
2047
2048 typedef enum {
2049   PSP_FINISHED,
2050   PSP_STOPPED,
2051   PSP_FAILED
2052 } psp_return_t;
2053
2054 static psp_return_t
2055 process_specified_packets(capture_file *cf, packet_range_t *range,
2056     const char *string1, const char *string2, gboolean terminate_is_stop,
2057     gboolean (*callback)(capture_file *, frame_data *,
2058                          union wtap_pseudo_header *, const guint8 *, void *),
2059     void *callback_args)
2060 {
2061   guint32 framenum;
2062   frame_data *fdata;
2063   union wtap_pseudo_header pseudo_header;
2064   guint8      pd[WTAP_MAX_PACKET_SIZE+1];
2065   psp_return_t ret = PSP_FINISHED;
2066
2067   progdlg_t  *progbar = NULL;
2068   int         progbar_count;
2069   float       progbar_val;
2070   gboolean    progbar_stop_flag;
2071   GTimeVal    progbar_start_time;
2072   gchar       progbar_status_str[100];
2073   int         progbar_nextstep;
2074   int         progbar_quantum;
2075   range_process_e process_this;
2076
2077   /* Update the progress bar when it gets to this value. */
2078   progbar_nextstep = 0;
2079   /* When we reach the value that triggers a progress bar update,
2080      bump that value by this amount. */
2081   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
2082   /* Count of packets at which we've looked. */
2083   progbar_count = 0;
2084   /* Progress so far. */
2085   progbar_val = 0.0f;
2086
2087   progbar_stop_flag = FALSE;
2088   g_get_current_time(&progbar_start_time);
2089
2090   if (range != NULL)
2091     packet_range_process_init(range);
2092
2093   /* Iterate through all the packets, printing the packets that
2094      were selected by the current display filter.  */
2095   for (framenum = 1; framenum <= cf->count; framenum++) {
2096     fdata = frame_data_sequence_find(cf->frames, framenum);
2097
2098     /* Create the progress bar if necessary.
2099        We check on every iteration of the loop, so that it takes no
2100        longer than the standard time to create it (otherwise, for a
2101        large file, we might take considerably longer than that standard
2102        time in order to get to the next progress bar step). */
2103     if (progbar == NULL)
2104       progbar = delayed_create_progress_dlg(cf->window, string1, string2,
2105                                             terminate_is_stop,
2106                                             &progbar_stop_flag,
2107                                             &progbar_start_time,
2108                                             progbar_val);
2109
2110     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
2111        when we update it, we have to run the GTK+ main loop to get it
2112        to repaint what's pending, and doing so may involve an "ioctl()"
2113        to see if there's any pending input from an X server, and doing
2114        that for every packet can be costly, especially on a big file. */
2115     if (progbar_count >= progbar_nextstep) {
2116       /* let's not divide by zero. I should never be started
2117        * with count == 0, so let's assert that
2118        */
2119       g_assert(cf->count > 0);
2120       progbar_val = (gfloat) progbar_count / cf->count;
2121
2122       if (progbar != NULL) {
2123         g_snprintf(progbar_status_str, sizeof(progbar_status_str),
2124                    "%4u of %u packets", progbar_count, cf->count);
2125         update_progress_dlg(progbar, progbar_val, progbar_status_str);
2126       }
2127
2128       progbar_nextstep += progbar_quantum;
2129     }
2130
2131     if (progbar_stop_flag) {
2132       /* Well, the user decided to abort the operation.  Just stop,
2133          and arrange to return PSP_STOPPED to our caller, so they know
2134          it was stopped explicitly. */
2135       ret = PSP_STOPPED;
2136       break;
2137     }
2138
2139     progbar_count++;
2140
2141     if (range != NULL) {
2142       /* do we have to process this packet? */
2143       process_this = packet_range_process_packet(range, fdata);
2144       if (process_this == range_process_next) {
2145         /* this packet uninteresting, continue with next one */
2146         continue;
2147       } else if (process_this == range_processing_finished) {
2148         /* all interesting packets processed, stop the loop */
2149         break;
2150       }
2151     }
2152
2153     /* Get the packet */
2154     if (!cf_read_frame_r(cf, fdata, &pseudo_header, pd)) {
2155       /* Attempt to get the packet failed. */
2156       ret = PSP_FAILED;
2157       break;
2158     }
2159     /* Process the packet */
2160     if (!callback(cf, fdata, &pseudo_header, pd, callback_args)) {
2161       /* Callback failed.  We assume it reported the error appropriately. */
2162       ret = PSP_FAILED;
2163       break;
2164     }
2165   }
2166
2167   /* We're done printing the packets; destroy the progress bar if
2168      it was created. */
2169   if (progbar != NULL)
2170     destroy_progress_dlg(progbar);
2171
2172   return ret;
2173 }
2174
2175 typedef struct {
2176   gboolean construct_protocol_tree;
2177   column_info *cinfo;
2178 } retap_callback_args_t;
2179
2180 static gboolean
2181 retap_packet(capture_file *cf _U_, frame_data *fdata,
2182              union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2183              void *argsp)
2184 {
2185   retap_callback_args_t *args = argsp;
2186   epan_dissect_t edt;
2187
2188   epan_dissect_init(&edt, args->construct_protocol_tree, FALSE);
2189   tap_queue_init(&edt);
2190   epan_dissect_run(&edt, pseudo_header, pd, fdata, args->cinfo);
2191   tap_push_tapped_queue(&edt);
2192   epan_dissect_cleanup(&edt);
2193
2194   return TRUE;
2195 }
2196
2197 cf_read_status_t
2198 cf_retap_packets(capture_file *cf)
2199 {
2200   packet_range_t range;
2201   retap_callback_args_t callback_args;
2202   gboolean filtering_tap_listeners;
2203   guint tap_flags;
2204
2205   /* Do we have any tap listeners with filters? */
2206   filtering_tap_listeners = have_filtering_tap_listeners();
2207
2208   tap_flags = union_of_tap_listener_flags();
2209
2210   /* If any tap listeners have filters, or require the protocol tree,
2211      construct the protocol tree. */
2212   callback_args.construct_protocol_tree = filtering_tap_listeners ||
2213                                           (tap_flags & TL_REQUIRES_PROTO_TREE);
2214
2215   /* If any tap listeners require the columns, construct them. */
2216   callback_args.cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
2217
2218   /* Reset the tap listeners. */
2219   reset_tap_listeners();
2220
2221   /* Iterate through the list of packets, dissecting all packets and
2222      re-running the taps. */
2223   packet_range_init(&range);
2224   packet_range_process_init(&range);
2225   switch (process_specified_packets(cf, &range, "Recalculating statistics on",
2226                                     "all packets", TRUE, retap_packet,
2227                                     &callback_args)) {
2228   case PSP_FINISHED:
2229     /* Completed successfully. */
2230     return CF_READ_OK;
2231
2232   case PSP_STOPPED:
2233     /* Well, the user decided to abort the refiltering.
2234        Return CF_READ_ABORTED so our caller knows they did that. */
2235     return CF_READ_ABORTED;
2236
2237   case PSP_FAILED:
2238     /* Error while retapping. */
2239     return CF_READ_ERROR;
2240   }
2241
2242   g_assert_not_reached();
2243   return CF_READ_OK;
2244 }
2245
2246 typedef struct {
2247   print_args_t *print_args;
2248   gboolean      print_header_line;
2249   char         *header_line_buf;
2250   int           header_line_buf_len;
2251   gboolean      print_formfeed;
2252   gboolean      print_separator;
2253   char         *line_buf;
2254   int           line_buf_len;
2255   gint         *col_widths;
2256   int           num_visible_cols;
2257   gint         *visible_cols;
2258 } print_callback_args_t;
2259
2260 static gboolean
2261 print_packet(capture_file *cf, frame_data *fdata,
2262              union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2263              void *argsp)
2264 {
2265   print_callback_args_t *args = argsp;
2266   epan_dissect_t edt;
2267   int             i;
2268   char           *cp;
2269   int             line_len;
2270   int             column_len;
2271   int             cp_off;
2272   gboolean        proto_tree_needed;
2273   char            bookmark_name[9+10+1];    /* "__frameNNNNNNNNNN__\0" */
2274   char            bookmark_title[6+10+1];   /* "Frame NNNNNNNNNN__\0" */
2275
2276   /* Create the protocol tree, and make it visible, if we're printing
2277      the dissection or the hex data.
2278      XXX - do we need it if we're just printing the hex data? */
2279   proto_tree_needed =
2280       args->print_args->print_dissections != print_dissections_none || args->print_args->print_hex || have_custom_cols(&cf->cinfo);
2281   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2282
2283   /* Fill in the column information if we're printing the summary
2284      information. */
2285   if (args->print_args->print_summary) {
2286     col_custom_prime_edt(&edt, &cf->cinfo);
2287     epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
2288     epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
2289   } else
2290     epan_dissect_run(&edt, pseudo_header, pd, fdata, NULL);
2291
2292   if (args->print_formfeed) {
2293     if (!new_page(args->print_args->stream))
2294       goto fail;
2295   } else {
2296       if (args->print_separator) {
2297         if (!print_line(args->print_args->stream, 0, ""))
2298           goto fail;
2299       }
2300   }
2301
2302   /*
2303    * We generate bookmarks, if the output format supports them.
2304    * The name is "__frameN__".
2305    */
2306   g_snprintf(bookmark_name, sizeof bookmark_name, "__frame%u__", fdata->num);
2307
2308   if (args->print_args->print_summary) {
2309     if (args->print_header_line) {
2310       if (!print_line(args->print_args->stream, 0, args->header_line_buf))
2311         goto fail;
2312       args->print_header_line = FALSE;  /* we might not need to print any more */
2313     }
2314     cp = &args->line_buf[0];
2315     line_len = 0;
2316     for (i = 0; i < args->num_visible_cols; i++) {
2317       /* Find the length of the string for this column. */
2318       column_len = (int) strlen(cf->cinfo.col_data[args->visible_cols[i]]);
2319       if (args->col_widths[i] > column_len)
2320          column_len = args->col_widths[i];
2321
2322       /* Make sure there's room in the line buffer for the column; if not,
2323          double its length. */
2324       line_len += column_len + 1;   /* "+1" for space */
2325       if (line_len > args->line_buf_len) {
2326         cp_off = (int) (cp - args->line_buf);
2327         args->line_buf_len = 2 * line_len;
2328         args->line_buf = g_realloc(args->line_buf, args->line_buf_len + 1);
2329         cp = args->line_buf + cp_off;
2330       }
2331
2332       /* Right-justify the packet number column. */
2333       if (cf->cinfo.col_fmt[args->visible_cols[i]] == COL_NUMBER)
2334         g_snprintf(cp, column_len+1, "%*s", args->col_widths[i], cf->cinfo.col_data[args->visible_cols[i]]);
2335       else
2336         g_snprintf(cp, column_len+1, "%-*s", args->col_widths[i], cf->cinfo.col_data[args->visible_cols[i]]);
2337       cp += column_len;
2338       if (i != args->num_visible_cols - 1)
2339         *cp++ = ' ';
2340     }
2341     *cp = '\0';
2342
2343     /*
2344      * Generate a bookmark, using the summary line as the title.
2345      */
2346     if (!print_bookmark(args->print_args->stream, bookmark_name,
2347                         args->line_buf))
2348       goto fail;
2349
2350     if (!print_line(args->print_args->stream, 0, args->line_buf))
2351       goto fail;
2352   } else {
2353     /*
2354      * Generate a bookmark, using "Frame N" as the title, as we're not
2355      * printing the summary line.
2356      */
2357     g_snprintf(bookmark_title, sizeof bookmark_title, "Frame %u", fdata->num);
2358     if (!print_bookmark(args->print_args->stream, bookmark_name,
2359                         bookmark_title))
2360       goto fail;
2361   } /* if (print_summary) */
2362
2363   if (args->print_args->print_dissections != print_dissections_none) {
2364     if (args->print_args->print_summary) {
2365       /* Separate the summary line from the tree with a blank line. */
2366       if (!print_line(args->print_args->stream, 0, ""))
2367         goto fail;
2368     }
2369
2370     /* Print the information in that tree. */
2371     if (!proto_tree_print(args->print_args, &edt, args->print_args->stream))
2372       goto fail;
2373
2374     /* Print a blank line if we print anything after this (aka more than one packet). */
2375     args->print_separator = TRUE;
2376
2377     /* Print a header line if we print any more packet summaries */
2378     args->print_header_line = TRUE;
2379   }
2380
2381   if (args->print_args->print_hex) {
2382     /* Print the full packet data as hex. */
2383     if (!print_hex_data(args->print_args->stream, &edt))
2384       goto fail;
2385
2386     /* Print a blank line if we print anything after this (aka more than one packet). */
2387     args->print_separator = TRUE;
2388
2389     /* Print a header line if we print any more packet summaries */
2390     args->print_header_line = TRUE;
2391   } /* if (args->print_args->print_dissections != print_dissections_none) */
2392
2393   epan_dissect_cleanup(&edt);
2394
2395   /* do we want to have a formfeed between each packet from now on? */
2396   if(args->print_args->print_formfeed) {
2397     args->print_formfeed = TRUE;
2398   }
2399
2400   return TRUE;
2401
2402 fail:
2403   epan_dissect_cleanup(&edt);
2404   return FALSE;
2405 }
2406
2407 cf_print_status_t
2408 cf_print_packets(capture_file *cf, print_args_t *print_args)
2409 {
2410   print_callback_args_t callback_args;
2411   gint        data_width;
2412   char        *cp;
2413   int         i, cp_off, column_len, line_len;
2414   int         num_visible_col = 0, last_visible_col = 0, visible_col_count;
2415   psp_return_t ret;
2416   GList       *clp;
2417   fmt_data    *cfmt;
2418
2419   callback_args.print_args = print_args;
2420   callback_args.print_header_line = TRUE;
2421   callback_args.header_line_buf = NULL;
2422   callback_args.header_line_buf_len = 256;
2423   callback_args.print_formfeed = FALSE;
2424   callback_args.print_separator = FALSE;
2425   callback_args.line_buf = NULL;
2426   callback_args.line_buf_len = 256;
2427   callback_args.col_widths = NULL;
2428   callback_args.num_visible_cols = 0;
2429   callback_args.visible_cols = NULL;
2430
2431   if (!print_preamble(print_args->stream, cf->filename)) {
2432     destroy_print_stream(print_args->stream);
2433     return CF_PRINT_WRITE_ERROR;
2434   }
2435
2436   if (print_args->print_summary) {
2437     /* We're printing packet summaries.  Allocate the header line buffer
2438        and get the column widths. */
2439     callback_args.header_line_buf = g_malloc(callback_args.header_line_buf_len + 1);
2440
2441     /* Find the number of visible columns and the last visible column */
2442     for (i = 0; i < prefs.num_cols; i++) {
2443
2444         clp = g_list_nth(prefs.col_list, i);
2445         if (clp == NULL) /* Sanity check, Invalid column requested */
2446             continue;
2447
2448         cfmt = (fmt_data *) clp->data;
2449         if (cfmt->visible) {
2450             num_visible_col++;
2451             last_visible_col = i;
2452         }
2453     }
2454
2455     /* Find the widths for each of the columns - maximum of the
2456        width of the title and the width of the data - and construct
2457        a buffer with a line containing the column titles. */
2458     callback_args.num_visible_cols = num_visible_col;
2459     callback_args.col_widths = (gint *) g_malloc(sizeof(gint) * num_visible_col);
2460     callback_args.visible_cols = (gint *) g_malloc(sizeof(gint) * num_visible_col);
2461     cp = &callback_args.header_line_buf[0];
2462     line_len = 0;
2463     visible_col_count = 0;
2464     for (i = 0; i < cf->cinfo.num_cols; i++) {
2465
2466       clp = g_list_nth(prefs.col_list, i);
2467       if (clp == NULL) /* Sanity check, Invalid column requested */
2468           continue;
2469
2470       cfmt = (fmt_data *) clp->data;
2471       if (cfmt->visible == FALSE)
2472           continue;
2473
2474       /* Save the order of visible columns */
2475       callback_args.visible_cols[visible_col_count] = i;
2476
2477       /* Don't pad the last column. */
2478       if (i == last_visible_col)
2479         callback_args.col_widths[visible_col_count] = 0;
2480       else {
2481         callback_args.col_widths[visible_col_count] = (gint) strlen(cf->cinfo.col_title[i]);
2482         data_width = get_column_char_width(get_column_format(i));
2483         if (data_width > callback_args.col_widths[visible_col_count])
2484           callback_args.col_widths[visible_col_count] = data_width;
2485       }
2486
2487       /* Find the length of the string for this column. */
2488       column_len = (int) strlen(cf->cinfo.col_title[i]);
2489       if (callback_args.col_widths[i] > column_len)
2490         column_len = callback_args.col_widths[visible_col_count];
2491
2492       /* Make sure there's room in the line buffer for the column; if not,
2493          double its length. */
2494       line_len += column_len + 1;   /* "+1" for space */
2495       if (line_len > callback_args.header_line_buf_len) {
2496         cp_off = (int) (cp - callback_args.header_line_buf);
2497         callback_args.header_line_buf_len = 2 * line_len;
2498         callback_args.header_line_buf = g_realloc(callback_args.header_line_buf,
2499                                                   callback_args.header_line_buf_len + 1);
2500         cp = callback_args.header_line_buf + cp_off;
2501       }
2502
2503       /* Right-justify the packet number column. */
2504 /*      if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2505         g_snprintf(cp, column_len+1, "%*s", callback_args.col_widths[visible_col_count], cf->cinfo.col_title[i]);
2506       else*/
2507       g_snprintf(cp, column_len+1, "%-*s", callback_args.col_widths[visible_col_count], cf->cinfo.col_title[i]);
2508       cp += column_len;
2509       if (i != cf->cinfo.num_cols - 1)
2510         *cp++ = ' ';
2511
2512       visible_col_count++;
2513     }
2514     *cp = '\0';
2515
2516     /* Now start out the main line buffer with the same length as the
2517        header line buffer. */
2518     callback_args.line_buf_len = callback_args.header_line_buf_len;
2519     callback_args.line_buf = g_malloc(callback_args.line_buf_len + 1);
2520   } /* if (print_summary) */
2521
2522   /* Iterate through the list of packets, printing the packets we were
2523      told to print. */
2524   ret = process_specified_packets(cf, &print_args->range, "Printing",
2525                                   "selected packets", TRUE, print_packet,
2526                                   &callback_args);
2527
2528   g_free(callback_args.header_line_buf);
2529   g_free(callback_args.line_buf);
2530   g_free(callback_args.col_widths);
2531   g_free(callback_args.visible_cols);
2532
2533   switch (ret) {
2534
2535   case PSP_FINISHED:
2536     /* Completed successfully. */
2537     break;
2538
2539   case PSP_STOPPED:
2540     /* Well, the user decided to abort the printing.
2541
2542        XXX - note that what got generated before they did that
2543        will get printed if we're piping to a print program; we'd
2544        have to write to a file and then hand that to the print
2545        program to make it actually not print anything. */
2546     break;
2547
2548   case PSP_FAILED:
2549     /* Error while printing.
2550
2551        XXX - note that what got generated before they did that
2552        will get printed if we're piping to a print program; we'd
2553        have to write to a file and then hand that to the print
2554        program to make it actually not print anything. */
2555     destroy_print_stream(print_args->stream);
2556     return CF_PRINT_WRITE_ERROR;
2557   }
2558
2559   if (!print_finale(print_args->stream)) {
2560     destroy_print_stream(print_args->stream);
2561     return CF_PRINT_WRITE_ERROR;
2562   }
2563
2564   if (!destroy_print_stream(print_args->stream))
2565     return CF_PRINT_WRITE_ERROR;
2566
2567   return CF_PRINT_OK;
2568 }
2569
2570 static gboolean
2571 write_pdml_packet(capture_file *cf _U_, frame_data *fdata,
2572                   union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2573           void *argsp)
2574 {
2575   FILE *fh = argsp;
2576   epan_dissect_t edt;
2577
2578   /* Create the protocol tree, but don't fill in the column information. */
2579   epan_dissect_init(&edt, TRUE, TRUE);
2580   epan_dissect_run(&edt, pseudo_header, pd, fdata, NULL);
2581
2582   /* Write out the information in that tree. */
2583   proto_tree_write_pdml(&edt, fh);
2584
2585   epan_dissect_cleanup(&edt);
2586
2587   return !ferror(fh);
2588 }
2589
2590 cf_print_status_t
2591 cf_write_pdml_packets(capture_file *cf, print_args_t *print_args)
2592 {
2593   FILE        *fh;
2594   psp_return_t ret;
2595
2596   fh = ws_fopen(print_args->file, "w");
2597   if (fh == NULL)
2598     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2599
2600   write_pdml_preamble(fh, cf->filename);
2601   if (ferror(fh)) {
2602     fclose(fh);
2603     return CF_PRINT_WRITE_ERROR;
2604   }
2605
2606   /* Iterate through the list of packets, printing the packets we were
2607      told to print. */
2608   ret = process_specified_packets(cf, &print_args->range, "Writing PDML",
2609                                   "selected packets", TRUE,
2610                                   write_pdml_packet, fh);
2611
2612   switch (ret) {
2613
2614   case PSP_FINISHED:
2615     /* Completed successfully. */
2616     break;
2617
2618   case PSP_STOPPED:
2619     /* Well, the user decided to abort the printing. */
2620     break;
2621
2622   case PSP_FAILED:
2623     /* Error while printing. */
2624     fclose(fh);
2625     return CF_PRINT_WRITE_ERROR;
2626   }
2627
2628   write_pdml_finale(fh);
2629   if (ferror(fh)) {
2630     fclose(fh);
2631     return CF_PRINT_WRITE_ERROR;
2632   }
2633
2634   /* XXX - check for an error */
2635   fclose(fh);
2636
2637   return CF_PRINT_OK;
2638 }
2639
2640 static gboolean
2641 write_psml_packet(capture_file *cf, frame_data *fdata,
2642                   union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2643           void *argsp)
2644 {
2645   FILE *fh = argsp;
2646   epan_dissect_t edt;
2647   gboolean proto_tree_needed;
2648
2649   /* Fill in the column information, only create the protocol tree
2650      if having custom columns. */
2651   proto_tree_needed = have_custom_cols(&cf->cinfo);
2652   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2653   col_custom_prime_edt(&edt, &cf->cinfo);
2654   epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
2655   epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
2656
2657   /* Write out the information in that tree. */
2658   proto_tree_write_psml(&edt, fh);
2659
2660   epan_dissect_cleanup(&edt);
2661
2662   return !ferror(fh);
2663 }
2664
2665 cf_print_status_t
2666 cf_write_psml_packets(capture_file *cf, print_args_t *print_args)
2667 {
2668   FILE        *fh;
2669   psp_return_t ret;
2670
2671   fh = ws_fopen(print_args->file, "w");
2672   if (fh == NULL)
2673     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2674
2675   write_psml_preamble(fh);
2676   if (ferror(fh)) {
2677     fclose(fh);
2678     return CF_PRINT_WRITE_ERROR;
2679   }
2680
2681   /* Iterate through the list of packets, printing the packets we were
2682      told to print. */
2683   ret = process_specified_packets(cf, &print_args->range, "Writing PSML",
2684                                   "selected packets", TRUE,
2685                                   write_psml_packet, fh);
2686
2687   switch (ret) {
2688
2689   case PSP_FINISHED:
2690     /* Completed successfully. */
2691     break;
2692
2693   case PSP_STOPPED:
2694     /* Well, the user decided to abort the printing. */
2695     break;
2696
2697   case PSP_FAILED:
2698     /* Error while printing. */
2699     fclose(fh);
2700     return CF_PRINT_WRITE_ERROR;
2701   }
2702
2703   write_psml_finale(fh);
2704   if (ferror(fh)) {
2705     fclose(fh);
2706     return CF_PRINT_WRITE_ERROR;
2707   }
2708
2709   /* XXX - check for an error */
2710   fclose(fh);
2711
2712   return CF_PRINT_OK;
2713 }
2714
2715 static gboolean
2716 write_csv_packet(capture_file *cf, frame_data *fdata,
2717                  union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2718                  void *argsp)
2719 {
2720   FILE *fh = argsp;
2721   epan_dissect_t edt;
2722   gboolean proto_tree_needed;
2723
2724   /* Fill in the column information, only create the protocol tree
2725      if having custom columns. */
2726   proto_tree_needed = have_custom_cols(&cf->cinfo);
2727   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2728   col_custom_prime_edt(&edt, &cf->cinfo);
2729   epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
2730   epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
2731
2732   /* Write out the information in that tree. */
2733   proto_tree_write_csv(&edt, fh);
2734
2735   epan_dissect_cleanup(&edt);
2736
2737   return !ferror(fh);
2738 }
2739
2740 cf_print_status_t
2741 cf_write_csv_packets(capture_file *cf, print_args_t *print_args)
2742 {
2743   FILE        *fh;
2744   psp_return_t ret;
2745
2746   fh = ws_fopen(print_args->file, "w");
2747   if (fh == NULL)
2748     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2749
2750   write_csv_preamble(fh);
2751   if (ferror(fh)) {
2752     fclose(fh);
2753     return CF_PRINT_WRITE_ERROR;
2754   }
2755
2756   /* Iterate through the list of packets, printing the packets we were
2757      told to print. */
2758   ret = process_specified_packets(cf, &print_args->range, "Writing CSV",
2759                                   "selected packets", TRUE,
2760                                   write_csv_packet, fh);
2761
2762   switch (ret) {
2763
2764   case PSP_FINISHED:
2765     /* Completed successfully. */
2766     break;
2767
2768   case PSP_STOPPED:
2769     /* Well, the user decided to abort the printing. */
2770     break;
2771
2772   case PSP_FAILED:
2773     /* Error while printing. */
2774     fclose(fh);
2775     return CF_PRINT_WRITE_ERROR;
2776   }
2777
2778   write_csv_finale(fh);
2779   if (ferror(fh)) {
2780     fclose(fh);
2781     return CF_PRINT_WRITE_ERROR;
2782   }
2783
2784   /* XXX - check for an error */
2785   fclose(fh);
2786
2787   return CF_PRINT_OK;
2788 }
2789
2790 static gboolean
2791 write_carrays_packet(capture_file *cf _U_, frame_data *fdata,
2792              union wtap_pseudo_header *pseudo_header,
2793              const guint8 *pd, void *argsp)
2794 {
2795   FILE *fh = argsp;
2796   epan_dissect_t edt;
2797
2798   epan_dissect_init(&edt, TRUE, TRUE);
2799   epan_dissect_run(&edt, pseudo_header, pd, fdata, NULL);
2800   proto_tree_write_carrays(fdata->num, fh, &edt);
2801   epan_dissect_cleanup(&edt);
2802
2803   return !ferror(fh);
2804 }
2805
2806 cf_print_status_t
2807 cf_write_carrays_packets(capture_file *cf, print_args_t *print_args)
2808 {
2809   FILE        *fh;
2810   psp_return_t ret;
2811
2812   fh = ws_fopen(print_args->file, "w");
2813
2814   if (fh == NULL)
2815     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2816
2817   write_carrays_preamble(fh);
2818
2819   if (ferror(fh)) {
2820     fclose(fh);
2821     return CF_PRINT_WRITE_ERROR;
2822   }
2823
2824   /* Iterate through the list of packets, printing the packets we were
2825      told to print. */
2826   ret = process_specified_packets(cf, &print_args->range,
2827                   "Writing C Arrays",
2828                   "selected packets", TRUE,
2829                                   write_carrays_packet, fh);
2830   switch (ret) {
2831   case PSP_FINISHED:
2832     /* Completed successfully. */
2833     break;
2834   case PSP_STOPPED:
2835     /* Well, the user decided to abort the printing. */
2836     break;
2837   case PSP_FAILED:
2838     /* Error while printing. */
2839     fclose(fh);
2840     return CF_PRINT_WRITE_ERROR;
2841   }
2842
2843   write_carrays_finale(fh);
2844
2845   if (ferror(fh)) {
2846     fclose(fh);
2847     return CF_PRINT_WRITE_ERROR;
2848   }
2849
2850   fclose(fh);
2851   return CF_PRINT_OK;
2852 }
2853
2854 gboolean
2855 cf_find_packet_protocol_tree(capture_file *cf, const char *string,
2856                              search_direction dir)
2857 {
2858   match_data        mdata;
2859
2860   mdata.string = string;
2861   mdata.string_len = strlen(string);
2862   return find_packet(cf, match_protocol_tree, &mdata, dir);
2863 }
2864
2865 gboolean
2866 cf_find_string_protocol_tree(capture_file *cf, proto_tree *tree,  match_data *mdata)
2867 {
2868   mdata->frame_matched = FALSE;
2869   mdata->string = convert_string_case(cf->sfilter, cf->case_type);
2870   mdata->string_len = strlen(mdata->string);
2871   mdata->cf = cf;
2872   /* Iterate through all the nodes looking for matching text */
2873   proto_tree_children_foreach(tree, match_subtree_text, mdata);
2874   return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
2875 }
2876
2877 static match_result
2878 match_protocol_tree(capture_file *cf, frame_data *fdata, void *criterion)
2879 {
2880   match_data        *mdata = criterion;
2881   epan_dissect_t    edt;
2882
2883   /* Load the frame's data. */
2884   if (!cf_read_frame(cf, fdata)) {
2885     /* Attempt to get the packet failed. */
2886     return MR_ERROR;
2887   }
2888
2889   /* Construct the protocol tree, including the displayed text */
2890   epan_dissect_init(&edt, TRUE, TRUE);
2891   /* We don't need the column information */
2892   epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, NULL);
2893
2894   /* Iterate through all the nodes, seeing if they have text that matches. */
2895   mdata->cf = cf;
2896   mdata->frame_matched = FALSE;
2897   proto_tree_children_foreach(edt.tree, match_subtree_text, mdata);
2898   epan_dissect_cleanup(&edt);
2899   return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
2900 }
2901
2902 static void
2903 match_subtree_text(proto_node *node, gpointer data)
2904 {
2905   match_data    *mdata = (match_data *) data;
2906   const gchar   *string = mdata->string;
2907   size_t        string_len = mdata->string_len;
2908   capture_file  *cf = mdata->cf;
2909   field_info    *fi = PNODE_FINFO(node);
2910   gchar         label_str[ITEM_LABEL_LENGTH];
2911   gchar         *label_ptr;
2912   size_t        label_len;
2913   guint32       i;
2914   guint8        c_char;
2915   size_t        c_match = 0;
2916
2917   g_assert(fi && "dissection with an invisible proto tree?");
2918
2919   if (mdata->frame_matched) {
2920     /* We already had a match; don't bother doing any more work. */
2921     return;
2922   }
2923
2924   /* Don't match invisible entries. */
2925   if (PROTO_ITEM_IS_HIDDEN(node))
2926     return;
2927
2928   /* was a free format label produced? */
2929   if (fi->rep) {
2930     label_ptr = fi->rep->representation;
2931   } else {
2932     /* no, make a generic label */
2933     label_ptr = label_str;
2934     proto_item_fill_label(fi, label_str);
2935   }
2936
2937   /* Does that label match? */
2938   label_len = strlen(label_ptr);
2939   for (i = 0; i < label_len; i++) {
2940     c_char = label_ptr[i];
2941     if (cf->case_type)
2942       c_char = toupper(c_char);
2943     if (c_char == string[c_match]) {
2944       c_match++;
2945       if (c_match == string_len) {
2946         /* No need to look further; we have a match */
2947         mdata->frame_matched = TRUE;
2948         mdata->finfo = fi;
2949         return;
2950       }
2951     } else
2952       c_match = 0;
2953   }
2954
2955   /* Recurse into the subtree, if it exists */
2956   if (node->first_child != NULL)
2957     proto_tree_children_foreach(node, match_subtree_text, mdata);
2958 }
2959
2960 gboolean
2961 cf_find_packet_summary_line(capture_file *cf, const char *string,
2962                             search_direction dir)
2963 {
2964   match_data        mdata;
2965
2966   mdata.string = string;
2967   mdata.string_len = strlen(string);
2968   return find_packet(cf, match_summary_line, &mdata, dir);
2969 }
2970
2971 static match_result
2972 match_summary_line(capture_file *cf, frame_data *fdata, void *criterion)
2973 {
2974   match_data        *mdata = criterion;
2975   const gchar       *string = mdata->string;
2976   size_t            string_len = mdata->string_len;
2977   epan_dissect_t    edt;
2978   const char        *info_column;
2979   size_t            info_column_len;
2980   match_result      result = MR_NOTMATCHED;
2981   gint              colx;
2982   guint32           i;
2983   guint8            c_char;
2984   size_t            c_match = 0;
2985
2986   /* Load the frame's data. */
2987   if (!cf_read_frame(cf, fdata)) {
2988     /* Attempt to get the packet failed. */
2989     return MR_ERROR;
2990   }
2991
2992   /* Don't bother constructing the protocol tree */
2993   epan_dissect_init(&edt, FALSE, FALSE);
2994   /* Get the column information */
2995   epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, &cf->cinfo);
2996
2997   /* Find the Info column */
2998   for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
2999     if (cf->cinfo.fmt_matx[colx][COL_INFO]) {
3000       /* Found it.  See if we match. */
3001       info_column = edt.pi.cinfo->col_data[colx];
3002       info_column_len = strlen(info_column);
3003       for (i = 0; i < info_column_len; i++) {
3004         c_char = info_column[i];
3005         if (cf->case_type)
3006           c_char = toupper(c_char);
3007         if (c_char == string[c_match]) {
3008           c_match++;
3009           if (c_match == string_len) {
3010             result = MR_MATCHED;
3011             break;
3012           }
3013         } else
3014           c_match = 0;
3015       }
3016       break;
3017     }
3018   }
3019   epan_dissect_cleanup(&edt);
3020   return result;
3021 }
3022
3023 typedef struct {
3024     const guint8 *data;
3025     size_t data_len;
3026 } cbs_t;    /* "Counted byte string" */
3027
3028 gboolean
3029 cf_find_packet_data(capture_file *cf, const guint8 *string, size_t string_size,
3030                     search_direction dir)
3031 {
3032   cbs_t info;
3033
3034   info.data = string;
3035   info.data_len = string_size;
3036
3037   /* String or hex search? */
3038   if (cf->string) {
3039     /* String search - what type of string? */
3040     switch (cf->scs_type) {
3041
3042     case SCS_ASCII_AND_UNICODE:
3043       return find_packet(cf, match_ascii_and_unicode, &info, dir);
3044
3045     case SCS_ASCII:
3046       return find_packet(cf, match_ascii, &info, dir);
3047
3048     case SCS_UNICODE:
3049       return find_packet(cf, match_unicode, &info, dir);
3050
3051     default:
3052       g_assert_not_reached();
3053       return FALSE;
3054     }
3055   } else
3056     return find_packet(cf, match_binary, &info, dir);
3057 }
3058
3059 static match_result
3060 match_ascii_and_unicode(capture_file *cf, frame_data *fdata, void *criterion)
3061 {
3062   cbs_t        *info = criterion;
3063   const guint8 *ascii_text = info->data;
3064   size_t       textlen = info->data_len;
3065   match_result result;
3066   guint32      buf_len;
3067   guint32      i;
3068   guint8       c_char;
3069   size_t       c_match = 0;
3070
3071   /* Load the frame's data. */
3072   if (!cf_read_frame(cf, fdata)) {
3073     /* Attempt to get the packet failed. */
3074     return MR_ERROR;
3075   }
3076
3077   result = MR_NOTMATCHED;
3078   buf_len = fdata->pkt_len;
3079   i = 0;
3080   while (i < buf_len) {
3081     c_char = cf->pd[i];
3082     if (cf->case_type)
3083       c_char = toupper(c_char);
3084     if (c_char != '\0') {
3085       if (c_char == ascii_text[c_match]) {
3086         c_match += 1;
3087         if (c_match == textlen) {
3088           result = MR_MATCHED;
3089           cf->search_pos = i; /* Save the position of the last character
3090                                  for highlighting the field. */
3091           break;
3092         }
3093       }
3094       else {
3095         g_assert(i>=c_match);
3096         i -= (guint32)c_match;
3097         c_match = 0;
3098       }
3099     }
3100     i += 1;
3101   }
3102   return result;
3103 }
3104
3105 static match_result
3106 match_ascii(capture_file *cf, frame_data *fdata, void *criterion)
3107 {
3108   cbs_t        *info = criterion;
3109   const guint8 *ascii_text = info->data;
3110   size_t       textlen = info->data_len;
3111   match_result result;
3112   guint32      buf_len;
3113   guint32      i;
3114   guint8       c_char;
3115   size_t       c_match = 0;
3116
3117   /* Load the frame's data. */
3118   if (!cf_read_frame(cf, fdata)) {
3119     /* Attempt to get the packet failed. */
3120     return MR_ERROR;
3121   }
3122
3123   result = MR_NOTMATCHED;
3124   buf_len = fdata->pkt_len;
3125   i = 0;
3126   while (i < buf_len) {
3127     c_char = cf->pd[i];
3128     if (cf->case_type)
3129       c_char = toupper(c_char);
3130     if (c_char == ascii_text[c_match]) {
3131       c_match += 1;
3132       if (c_match == textlen) {
3133         result = MR_MATCHED;
3134         cf->search_pos = i; /* Save the position of the last character
3135                                for highlighting the field. */
3136         break;
3137       }
3138     }
3139     else {
3140       g_assert(i>=c_match);
3141       i -= (guint32)c_match;
3142       c_match = 0;
3143     }
3144     i += 1;
3145   }
3146
3147   return result;
3148 }
3149
3150 static match_result
3151 match_unicode(capture_file *cf, frame_data *fdata, void *criterion)
3152 {
3153   cbs_t        *info = criterion;
3154   const guint8 *ascii_text = info->data;
3155   size_t       textlen = info->data_len;
3156   match_result result;
3157   guint32      buf_len;
3158   guint32      i;
3159   guint8       c_char;
3160   size_t       c_match = 0;
3161
3162   /* Load the frame's data. */
3163   if (!cf_read_frame(cf, fdata)) {
3164     /* Attempt to get the packet failed. */
3165     return MR_ERROR;
3166   }
3167
3168   result = MR_NOTMATCHED;
3169   buf_len = fdata->pkt_len;
3170   i = 0;
3171   while (i < buf_len) {
3172     c_char = cf->pd[i];
3173     if (cf->case_type)
3174       c_char = toupper(c_char);
3175     if (c_char == ascii_text[c_match]) {
3176       c_match += 1;
3177       if (c_match == textlen) {
3178         result = MR_MATCHED;
3179         cf->search_pos = i; /* Save the position of the last character
3180                                for highlighting the field. */
3181         break;
3182       }
3183       i += 1;
3184     }
3185     else {
3186       g_assert(i>=(c_match*2));
3187       i -= (guint32)c_match*2;
3188       c_match = 0;
3189     }
3190     i += 1;
3191   }
3192   return result;
3193 }
3194
3195 static match_result
3196 match_binary(capture_file *cf, frame_data *fdata, void *criterion)
3197 {
3198   cbs_t        *info = criterion;
3199   const guint8 *binary_data = info->data;
3200   size_t       datalen = info->data_len;
3201   match_result result;
3202   guint32      buf_len;
3203   guint32      i;
3204   size_t       c_match = 0;
3205
3206   /* Load the frame's data. */
3207   if (!cf_read_frame(cf, fdata)) {
3208     /* Attempt to get the packet failed. */
3209     return MR_ERROR;
3210   }
3211
3212   result = MR_NOTMATCHED;
3213   buf_len = fdata->pkt_len;
3214   i = 0;
3215   while (i < buf_len) {
3216     if (cf->pd[i] == binary_data[c_match]) {
3217       c_match += 1;
3218       if (c_match == datalen) {
3219         result = MR_MATCHED;
3220         cf->search_pos = i; /* Save the position of the last character
3221                                for highlighting the field. */
3222         break;
3223       }
3224     }
3225     else {
3226       g_assert(i>=c_match);
3227       i -= (guint32)c_match;
3228       c_match = 0;
3229     }
3230     i += 1;
3231   }
3232   return result;
3233 }
3234
3235 gboolean
3236 cf_find_packet_dfilter(capture_file *cf, dfilter_t *sfcode,
3237                        search_direction dir)
3238 {
3239   return find_packet(cf, match_dfilter, sfcode, dir);
3240 }
3241
3242 gboolean
3243 cf_find_packet_dfilter_string(capture_file *cf, const char *filter,
3244                               search_direction dir)
3245 {
3246   dfilter_t *sfcode;
3247   gboolean result;
3248
3249   if (!dfilter_compile(filter, &sfcode)) {
3250      /*
3251       * XXX - this shouldn't happen, as the filter string is machine
3252       * generated
3253       */
3254     return FALSE;
3255   }
3256   if (sfcode == NULL) {
3257     /*
3258      * XXX - this shouldn't happen, as the filter string is machine
3259      * generated.
3260      */
3261     return FALSE;
3262   }
3263   result = find_packet(cf, match_dfilter, sfcode, dir);
3264   dfilter_free(sfcode);
3265   return result;
3266 }
3267
3268 static match_result
3269 match_dfilter(capture_file *cf, frame_data *fdata, void *criterion)
3270 {
3271   dfilter_t      *sfcode = criterion;
3272   epan_dissect_t edt;
3273   match_result   result;
3274
3275   /* Load the frame's data. */
3276   if (!cf_read_frame(cf, fdata)) {
3277     /* Attempt to get the packet failed. */
3278     return MR_ERROR;
3279   }
3280
3281   epan_dissect_init(&edt, TRUE, FALSE);
3282   epan_dissect_prime_dfilter(&edt, sfcode);
3283   epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, NULL);
3284   result = dfilter_apply_edt(sfcode, &edt) ? MR_MATCHED : MR_NOTMATCHED;
3285   epan_dissect_cleanup(&edt);
3286   return result;
3287 }
3288
3289 gboolean
3290 cf_find_packet_marked(capture_file *cf, search_direction dir)
3291 {
3292   return find_packet(cf, match_marked, NULL, dir);
3293 }
3294
3295 static match_result
3296 match_marked(capture_file *cf _U_, frame_data *fdata, void *criterion _U_)
3297 {
3298   return fdata->flags.marked ? MR_MATCHED : MR_NOTMATCHED;
3299 }
3300
3301 gboolean
3302 cf_find_packet_time_reference(capture_file *cf, search_direction dir)
3303 {
3304   return find_packet(cf, match_time_reference, NULL, dir);
3305 }
3306
3307 static match_result
3308 match_time_reference(capture_file *cf _U_, frame_data *fdata, void *criterion _U_)
3309 {
3310   return fdata->flags.ref_time ? MR_MATCHED : MR_NOTMATCHED;
3311 }
3312
3313 static gboolean
3314 find_packet(capture_file *cf,
3315             match_result (*match_function)(capture_file *, frame_data *, void *),
3316             void *criterion, search_direction dir)
3317 {
3318   frame_data  *start_fd;
3319   guint32      framenum;
3320   frame_data  *fdata;
3321   frame_data  *new_fd = NULL;
3322   progdlg_t   *progbar = NULL;
3323   gboolean     stop_flag;
3324   int          count;
3325   gboolean     found;
3326   float        progbar_val;
3327   GTimeVal     start_time;
3328   gchar        status_str[100];
3329   int          progbar_nextstep;
3330   int          progbar_quantum;
3331   const char  *title;
3332   match_result result;
3333
3334   start_fd = cf->current_frame;
3335   if (start_fd != NULL)  {
3336     /* Iterate through the list of packets, starting at the packet we've
3337        picked, calling a routine to run the filter on the packet, see if
3338        it matches, and stop if so.  */
3339     count = 0;
3340     framenum = start_fd->num;
3341
3342     /* Update the progress bar when it gets to this value. */
3343     progbar_nextstep = 0;
3344     /* When we reach the value that triggers a progress bar update,
3345        bump that value by this amount. */
3346     progbar_quantum = cf->count/N_PROGBAR_UPDATES;
3347     /* Progress so far. */
3348     progbar_val = 0.0f;
3349
3350     stop_flag = FALSE;
3351     g_get_current_time(&start_time);
3352
3353     title = cf->sfilter?cf->sfilter:"";
3354     for (;;) {
3355       /* Create the progress bar if necessary.
3356          We check on every iteration of the loop, so that it takes no
3357          longer than the standard time to create it (otherwise, for a
3358          large file, we might take considerably longer than that standard
3359          time in order to get to the next progress bar step). */
3360       if (progbar == NULL)
3361          progbar = delayed_create_progress_dlg(cf->window, "Searching", title,
3362            FALSE, &stop_flag, &start_time, progbar_val);
3363
3364       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
3365          when we update it, we have to run the GTK+ main loop to get it
3366          to repaint what's pending, and doing so may involve an "ioctl()"
3367          to see if there's any pending input from an X server, and doing
3368          that for every packet can be costly, especially on a big file. */
3369       if (count >= progbar_nextstep) {
3370         /* let's not divide by zero. I should never be started
3371          * with count == 0, so let's assert that
3372          */
3373         g_assert(cf->count > 0);
3374
3375         progbar_val = (gfloat) count / cf->count;
3376
3377         if (progbar != NULL) {
3378           g_snprintf(status_str, sizeof(status_str),
3379                      "%4u of %u packets", count, cf->count);
3380           update_progress_dlg(progbar, progbar_val, status_str);
3381         }
3382
3383         progbar_nextstep += progbar_quantum;
3384       }
3385
3386       if (stop_flag) {
3387         /* Well, the user decided to abort the search.  Go back to the
3388            frame where we started. */
3389         new_fd = start_fd;
3390         break;
3391       }
3392
3393       /* Go past the current frame. */
3394       if (dir == SD_BACKWARD) {
3395         /* Go on to the previous frame. */
3396         if (framenum == 1) {
3397           /*
3398            * XXX - other apps have a bit more of a detailed message
3399            * for this, and instead of offering "OK" and "Cancel",
3400            * they offer things such as "Continue" and "Cancel";
3401            * we need an API for popping up alert boxes with
3402            * {Verb} and "Cancel".
3403            */
3404
3405           if (prefs.gui_find_wrap)
3406           {
3407               statusbar_push_temporary_msg("Search reached the beginning. Continuing at end.");
3408               framenum = cf->count;     /* wrap around */
3409           }
3410           else
3411           {
3412               statusbar_push_temporary_msg("Search reached the beginning.");
3413               framenum = start_fd->num; /* stay on previous packet */
3414           }
3415         } else
3416           framenum--;
3417       } else {
3418         /* Go on to the next frame. */
3419         if (framenum == cf->count) {
3420           if (prefs.gui_find_wrap)
3421           {
3422               statusbar_push_temporary_msg("Search reached the end. Continuing at beginning.");
3423               framenum = 1;             /* wrap around */
3424           }
3425           else
3426           {
3427               statusbar_push_temporary_msg("Search reached the end.");
3428               framenum = start_fd->num; /* stay on previous packet */
3429           }
3430         } else
3431           framenum++;
3432       }
3433       fdata = frame_data_sequence_find(cf->frames, framenum);
3434
3435       count++;
3436
3437       /* Is this packet in the display? */
3438       if (fdata->flags.passed_dfilter) {
3439         /* Yes.  Does it match the search criterion? */
3440         result = (*match_function)(cf, fdata, criterion);
3441         if (result == MR_ERROR) {
3442           /* Error; our caller has reported the error.  Go back to the frame
3443              where we started. */
3444           new_fd = start_fd;
3445           break;
3446         } else if (result == MR_MATCHED) {
3447           /* Yes.  Go to the new frame. */
3448           new_fd = fdata;
3449           break;
3450         }
3451       }
3452
3453       if (fdata == start_fd) {
3454         /* We're back to the frame we were on originally, and that frame
3455            doesn't match the search filter.  The search failed. */
3456         break;
3457       }
3458     }
3459
3460     /* We're done scanning the packets; destroy the progress bar if it
3461        was created. */
3462     if (progbar != NULL)
3463       destroy_progress_dlg(progbar);
3464   }
3465
3466   if (new_fd != NULL) {
3467     /* Find and select */
3468     cf->search_in_progress = TRUE;
3469     found = new_packet_list_select_row_from_data(new_fd);
3470     cf->search_in_progress = FALSE;
3471     cf->search_pos = 0; /* Reset the position */
3472     if (!found) {
3473       /* We didn't find a row corresponding to this frame.
3474          This means that the frame isn't being displayed currently,
3475          so we can't select it. */
3476       simple_message_box(ESD_TYPE_INFO, NULL,
3477                          "The capture file is probably not fully dissected.",
3478                          "End of capture exceeded!");
3479       return FALSE;
3480     }
3481     return TRUE;    /* success */
3482   } else
3483     return FALSE;   /* failure */
3484 }
3485
3486 gboolean
3487 cf_goto_frame(capture_file *cf, guint fnumber)
3488 {
3489   frame_data *fdata;
3490
3491   fdata = frame_data_sequence_find(cf->frames, fnumber);
3492
3493   if (fdata == NULL) {
3494     /* we didn't find a packet with that packet number */
3495     statusbar_push_temporary_msg("There is no packet number %u.", fnumber);
3496     return FALSE;   /* we failed to go to that packet */
3497   }
3498   if (!fdata->flags.passed_dfilter) {
3499     /* that packet currently isn't displayed */
3500     /* XXX - add it to the set of displayed packets? */
3501     statusbar_push_temporary_msg("Packet number %u isn't displayed.", fnumber);
3502     return FALSE;   /* we failed to go to that packet */
3503   }
3504
3505   if (!new_packet_list_select_row_from_data(fdata)) {
3506     /* We didn't find a row corresponding to this frame.
3507        This means that the frame isn't being displayed currently,
3508        so we can't select it. */
3509     simple_message_box(ESD_TYPE_INFO, NULL,
3510                        "The capture file is probably not fully dissected.",
3511                        "End of capture exceeded!");
3512     return FALSE;
3513   }
3514   return TRUE;  /* we got to that packet */
3515 }
3516
3517 gboolean
3518 cf_goto_top_frame(void)
3519 {
3520   /* Find and select */
3521   new_packet_list_select_first_row();
3522   return TRUE;  /* we got to that packet */
3523 }
3524
3525 gboolean
3526 cf_goto_bottom_frame(void)
3527 {
3528   /* Find and select */
3529   new_packet_list_select_last_row();
3530   return TRUE;  /* we got to that packet */
3531 }
3532
3533 /*
3534  * Go to frame specified by currently selected protocol tree item.
3535  */
3536 gboolean
3537 cf_goto_framenum(capture_file *cf)
3538 {
3539   header_field_info       *hfinfo;
3540   guint32                 framenum;
3541
3542   if (cf->finfo_selected) {
3543     hfinfo = cf->finfo_selected->hfinfo;
3544     g_assert(hfinfo);
3545     if (hfinfo->type == FT_FRAMENUM) {
3546       framenum = fvalue_get_uinteger(&cf->finfo_selected->value);
3547       if (framenum != 0)
3548         return cf_goto_frame(cf, framenum);
3549       }
3550   }
3551
3552   return FALSE;
3553 }
3554
3555 /* Select the packet on a given row. */
3556 void
3557 cf_select_packet(capture_file *cf, int row)
3558 {
3559   epan_dissect_t *old_edt;
3560   frame_data *fdata;
3561
3562   /* Get the frame data struct pointer for this frame */
3563   fdata = new_packet_list_get_row_data(row);
3564
3565   if (fdata == NULL) {
3566     /* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
3567        the first entry is added to it by "real_insert_row()", that row
3568        is selected (see "real_insert_row()", in "ui/gtk/gtkclist.c", in both
3569        our version and the vanilla GTK+ version).
3570
3571        This means that a "select-row" signal is emitted; this causes
3572        "packet_list_select_cb()" to be called, which causes "cf_select_packet()"
3573        to be called.
3574
3575        "cf_select_packet()" fetches, above, the data associated with the
3576        row that was selected; however, as "gtk_clist_append()", which
3577        called "real_insert_row()", hasn't yet returned, we haven't yet
3578        associated any data with that row, so we get back a null pointer.
3579
3580        We can't assume that there's only one frame in the frame list,
3581        either, as we may be filtering the display.
3582
3583        We therefore assume that, if "row" is 0, i.e. the first row
3584        is being selected, and "cf->first_displayed" equals
3585        "cf->last_displayed", i.e. there's only one frame being
3586        displayed, that frame is the frame we want.
3587
3588        This means we have to set "cf->first_displayed" and
3589        "cf->last_displayed" before adding the row to the
3590        GtkCList; see the comment in "add_packet_to_packet_list()". */
3591
3592        if (row == 0 && cf->first_displayed == cf->last_displayed)
3593          fdata = frame_data_sequence_find(cf->frames, cf->first_displayed);
3594   }
3595
3596   /* If fdata _still_ isn't set simply give up. */
3597   if (fdata == NULL) {
3598     return;
3599   }
3600
3601   /* Get the data in that frame. */
3602   if (!cf_read_frame (cf, fdata)) {
3603     return;
3604   }
3605
3606   /* Record that this frame is the current frame. */
3607   cf->current_frame = fdata;
3608   cf->current_row = row;
3609
3610   old_edt = cf->edt;
3611   /* Create the logical protocol tree. */
3612   /* We don't need the columns here. */
3613   cf->edt = epan_dissect_new(TRUE, TRUE);
3614
3615   tap_build_interesting(cf->edt);
3616   epan_dissect_run(cf->edt, &cf->pseudo_header, cf->pd, cf->current_frame,
3617           NULL);
3618
3619   dfilter_macro_build_ftv_cache(cf->edt->tree);
3620
3621   cf_callback_invoke(cf_cb_packet_selected, cf);
3622
3623   if (old_edt != NULL)
3624     epan_dissect_free(old_edt);
3625
3626 }
3627
3628 /* Unselect the selected packet, if any. */
3629 void
3630 cf_unselect_packet(capture_file *cf)
3631 {
3632   epan_dissect_t *old_edt = cf->edt;
3633
3634   cf->edt = NULL;
3635
3636   /* No packet is selected. */
3637   cf->current_frame = NULL;
3638   cf->current_row = 0;
3639
3640   cf_callback_invoke(cf_cb_packet_unselected, cf);
3641
3642   /* No protocol tree means no selected field. */
3643   cf_unselect_field(cf);
3644
3645   /* Destroy the epan_dissect_t for the unselected packet. */
3646   if (old_edt != NULL)
3647     epan_dissect_free(old_edt);
3648 }
3649
3650 /* Unset the selected protocol tree field, if any. */
3651 void
3652 cf_unselect_field(capture_file *cf)
3653 {
3654   cf->finfo_selected = NULL;
3655
3656   cf_callback_invoke(cf_cb_field_unselected, cf);
3657 }
3658
3659 /*
3660  * Mark a particular frame.
3661  */
3662 void
3663 cf_mark_frame(capture_file *cf, frame_data *frame)
3664 {
3665   if (! frame->flags.marked) {
3666     frame->flags.marked = TRUE;
3667     if (cf->count > cf->marked_count)
3668       cf->marked_count++;
3669   }
3670 }
3671
3672 /*
3673  * Unmark a particular frame.
3674  */
3675 void
3676 cf_unmark_frame(capture_file *cf, frame_data *frame)
3677 {
3678   if (frame->flags.marked) {
3679     frame->flags.marked = FALSE;
3680     if (cf->marked_count > 0)
3681       cf->marked_count--;
3682   }
3683 }
3684
3685 /*
3686  * Ignore a particular frame.
3687  */
3688 void
3689 cf_ignore_frame(capture_file *cf, frame_data *frame)
3690 {
3691   if (! frame->flags.ignored) {
3692     frame->flags.ignored = TRUE;
3693     if (cf->count > cf->ignored_count)
3694       cf->ignored_count++;
3695   }
3696 }
3697
3698 /*
3699  * Un-ignore a particular frame.
3700  */
3701 void
3702 cf_unignore_frame(capture_file *cf, frame_data *frame)
3703 {
3704   if (frame->flags.ignored) {
3705     frame->flags.ignored = FALSE;
3706     if (cf->ignored_count > 0)
3707       cf->ignored_count--;
3708   }
3709 }
3710
3711 /*
3712  * Read the comment in SHB block
3713  */
3714
3715 const gchar *
3716 cf_read_shb_comment(capture_file *cf)
3717 {
3718   wtapng_section_t *shb_inf;
3719   const gchar *temp_str;
3720
3721   /* Get info from SHB */
3722   shb_inf = wtap_file_get_shb_info(cf->wth);
3723   if(shb_inf == NULL)
3724         return NULL;
3725   temp_str = shb_inf->opt_comment;
3726   g_free(shb_inf);
3727
3728   return temp_str;
3729
3730 }
3731
3732 void
3733 cf_update_capture_comment(capture_file *cf, gchar *comment)
3734 {
3735   wtapng_section_t *shb_inf;
3736
3737   /* Get info from SHB */
3738   shb_inf = wtap_file_get_shb_info(cf->wth);
3739
3740   /* See if the comment has changed or not */
3741   if (shb_inf && shb_inf->opt_comment) {
3742     if (strcmp(shb_inf->opt_comment, comment) == 0) {
3743       g_free(comment);
3744       g_free(shb_inf);
3745       return;
3746     }
3747   }
3748
3749   g_free(shb_inf);
3750
3751   /* The comment has changed, let's update it */
3752   wtap_write_shb_comment(cf->wth, comment);
3753   /* Mark the file as having unsaved changes */
3754   cf->unsaved_changes = TRUE;
3755 }
3756
3757 void
3758 cf_update_packet_comment(capture_file *cf, frame_data *fdata, gchar *comment)
3759 {
3760   if (fdata->opt_comment != NULL) {
3761     /* OK, remove the old comment. */
3762     g_free(fdata->opt_comment);
3763     fdata->opt_comment = NULL;
3764     cf->packet_comment_count--;
3765   }
3766   if (comment != NULL) {
3767     /* Add the new comment. */
3768     fdata->opt_comment = comment;
3769     cf->packet_comment_count++;
3770   }
3771
3772   /* OK, we have unsaved changes. */
3773   cf->unsaved_changes = TRUE;
3774 }
3775
3776 /*
3777  * Does this capture file have any comments?
3778  */
3779 gboolean
3780 cf_has_comments(capture_file *cf)
3781 {
3782   return (cf_read_shb_comment(cf) != NULL || cf->packet_comment_count != 0);
3783 }
3784
3785 typedef struct {
3786   wtap_dumper *pdh;
3787   const char  *fname;
3788   int          file_type;
3789 } save_callback_args_t;
3790
3791 /*
3792  * Save a capture to a file, in a particular format, saving either
3793  * all packets, all currently-displayed packets, or all marked packets.
3794  *
3795  * Returns TRUE if it succeeds, FALSE otherwise; if it fails, it pops
3796  * up a message box for the failure.
3797  */
3798 static gboolean
3799 save_packet(capture_file *cf _U_, frame_data *fdata,
3800             union wtap_pseudo_header *pseudo_header, const guint8 *pd,
3801             void *argsp)
3802 {
3803   save_callback_args_t *args = argsp;
3804   struct wtap_pkthdr hdr;
3805   int           err;
3806   gchar        *display_basename;
3807
3808   /* init the wtap header for saving */
3809   /* XXX - these are the only flags that correspond to data that we have
3810      in the frame_data structure and that matter on a per-packet basis.
3811
3812      For WTAP_HAS_CAP_LEN, either the file format has separate "captured"
3813      and "on the wire" lengths, or it doesn't.
3814
3815      For WTAP_HAS_DROP_COUNT, Wiretap doesn't actually supply the value
3816      to its callers.
3817
3818      For WTAP_HAS_PACK_FLAGS, we currently don't save the FCS length
3819      from the packet flags. */
3820   hdr.presence_flags = 0;
3821   if (fdata->flags.has_ts)
3822     hdr.presence_flags |= WTAP_HAS_TS;
3823   if (fdata->flags.has_ts)
3824     hdr.presence_flags |= WTAP_HAS_INTERFACE_ID;
3825   hdr.ts.secs      = fdata->abs_ts.secs;
3826   hdr.ts.nsecs     = fdata->abs_ts.nsecs;
3827   hdr.caplen       = fdata->cap_len;
3828   hdr.len          = fdata->pkt_len;
3829   hdr.pkt_encap    = fdata->lnk_t;
3830   /* pcapng */
3831   hdr.interface_id = fdata->interface_id;   /* identifier of the interface. */
3832   /* options */
3833   hdr.opt_comment  = fdata->opt_comment; /* NULL if not available */
3834 #if 0
3835   hdr.drop_count   =
3836   hdr.pack_flags   =     /* XXX - 0 for now (any value for "we don't have it"?) */
3837 #endif
3838   /* and save the packet */
3839   if (!wtap_dump(args->pdh, &hdr, pseudo_header, pd, &err)) {
3840     if (err < 0) {
3841       /* Wiretap error. */
3842       switch (err) {
3843
3844       case WTAP_ERR_UNSUPPORTED_ENCAP:
3845         /*
3846          * This is a problem with the particular frame we're writing;
3847          * note that, and give the frame number.
3848          */
3849         simple_error_message_box(
3850                       "Frame %u has a network type that can't be saved in a \"%s\" file.",
3851                       fdata->num, wtap_file_type_string(args->file_type));
3852         break;
3853
3854       default:
3855         display_basename = g_filename_display_basename(args->fname);
3856         simple_error_message_box(
3857                       "An error occurred while writing to the file \"%s\": %s.",
3858                       display_basename, wtap_strerror(err));
3859         g_free(display_basename);
3860         break;
3861       }
3862     } else {
3863       /* OS error. */
3864       write_failure_alert_box(args->fname, err);
3865     }
3866     return FALSE;
3867   }
3868   return TRUE;
3869 }
3870
3871 /*
3872  * Can this capture file be written out in any format using Wiretap
3873  * rather than by copying the raw data?
3874  */
3875 gboolean
3876 cf_can_write_with_wiretap(capture_file *cf)
3877 {
3878   int ft;
3879
3880   for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
3881     /* To save a file with Wiretap, Wiretap has to handle that format,
3882        and its code to handle that format must be able to write a file
3883        with this file's encapsulation types. */
3884     if (wtap_dump_can_write_encaps(ft, cf->linktypes)) {
3885       /* OK, we can write it out in this type. */
3886       return TRUE;
3887     }
3888   }
3889
3890   /* No, we couldn't save it in any format. */
3891   return FALSE;
3892 }
3893
3894 /*
3895  * Quick scan to find packet offsets.
3896  */
3897 static cf_read_status_t
3898 rescan_file(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
3899 {
3900   const struct wtap_pkthdr *phdr;
3901   gchar       *err_info;
3902   gchar       *name_ptr;
3903   gint64       data_offset;
3904   gint64       file_pos;
3905   progdlg_t *volatile progbar = NULL;
3906   gboolean     stop_flag;
3907   volatile gint64 size;
3908   volatile float progbar_val;
3909   GTimeVal     start_time;
3910   gchar        status_str[100];
3911   volatile gint64 progbar_nextstep;
3912   volatile gint64 progbar_quantum;
3913   guint32       framenum;
3914   frame_data   *fdata;
3915   volatile int count = 0;
3916 #ifdef HAVE_LIBPCAP
3917   volatile int displayed_once = 0;
3918 #endif
3919
3920   /* Close the old handle. */
3921   wtap_close(cf->wth);
3922
3923   /* Open the new file. */
3924   cf->wth = wtap_open_offline(fname, err, &err_info, TRUE);
3925   if (cf->wth == NULL) {
3926     cf_open_failure_alert_box(fname, *err, err_info, FALSE, 0);
3927     return CF_READ_ERROR;
3928   }
3929
3930   /* We're scanning a file whose contents should be the same as what
3931      we had before, so we don't discard dissection state etc.. */
3932   cf->f_datalen = 0;
3933
3934   /* Set the file name because we need it to set the follow stream filter.
3935      XXX - is that still true?  We need it for other reasons, though,
3936      in any case. */
3937   cf->filename = g_strdup(fname);
3938
3939   /* Indicate whether it's a permanent or temporary file. */
3940   cf->is_tempfile = is_tempfile;
3941
3942   /* No user changes yet. */
3943   cf->unsaved_changes = FALSE;
3944
3945   cf->cd_t        = wtap_file_type(cf->wth);
3946   cf->linktypes = g_array_sized_new(FALSE, FALSE, (guint) sizeof(int), 1);
3947
3948   cf->snap      = wtap_snapshot_length(cf->wth);
3949   if (cf->snap == 0) {
3950     /* Snapshot length not known. */
3951     cf->has_snap = FALSE;
3952     cf->snap = WTAP_MAX_PACKET_SIZE;
3953   } else
3954     cf->has_snap = TRUE;
3955
3956   name_ptr = g_filename_display_basename(cf->filename);
3957
3958   cf_callback_invoke(cf_cb_file_rescan_started, cf);
3959
3960   /* Record whether the file is compressed.
3961      XXX - do we know this at open time? */
3962   cf->iscompressed = wtap_iscompressed(cf->wth);
3963
3964   /* Find the size of the file. */
3965   size = wtap_file_size(cf->wth, NULL);
3966
3967   /* Update the progress bar when it gets to this value. */
3968   progbar_nextstep = 0;
3969   /* When we reach the value that triggers a progress bar update,
3970      bump that value by this amount. */
3971   if (size >= 0){
3972     progbar_quantum = size/N_PROGBAR_UPDATES;
3973     if (progbar_quantum < MIN_QUANTUM)
3974       progbar_quantum = MIN_QUANTUM;
3975   }else
3976     progbar_quantum = 0;
3977   /* Progress so far. */
3978   progbar_val = 0.0f;
3979
3980   stop_flag = FALSE;
3981   g_get_current_time(&start_time);
3982
3983   framenum = 0;
3984   phdr = wtap_phdr(cf->wth);
3985   while ((wtap_read(cf->wth, err, &err_info, &data_offset))) {
3986     framenum++;
3987     fdata = frame_data_sequence_find(cf->frames, framenum);
3988     fdata->file_off = data_offset;
3989     if (size >= 0) {
3990       count++;
3991       file_pos = wtap_read_so_far(cf->wth);
3992
3993       /* Create the progress bar if necessary.
3994        * Check whether it should be created or not every MIN_NUMBER_OF_PACKET
3995        */
3996       if ((progbar == NULL) && !(count % MIN_NUMBER_OF_PACKET)){
3997         progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
3998         progbar = delayed_create_progress_dlg(cf->window, "Rescanning", name_ptr,
3999                                               TRUE, &stop_flag, &start_time, progbar_val);
4000       }
4001
4002       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
4003          when we update it, we have to run the GTK+ main loop to get it
4004          to repaint what's pending, and doing so may involve an "ioctl()"
4005          to see if there's any pending input from an X server, and doing
4006          that for every packet can be costly, especially on a big file. */
4007       if (file_pos >= progbar_nextstep) {
4008         if (progbar != NULL) {
4009           progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
4010           /* update the packet bar content on the first run or frequently on very large files */
4011 #ifdef HAVE_LIBPCAP
4012           if (progbar_quantum > 500000 || displayed_once == 0) {
4013             if ((auto_scroll_live || displayed_once == 0 || cf->displayed_count < 1000) && cf->count != 0) {
4014               displayed_once = 1;
4015               packets_bar_update();
4016             }
4017           }
4018 #endif /* HAVE_LIBPCAP */
4019           update_progress_dlg(progbar, progbar_val, status_str);
4020         }
4021         progbar_nextstep += progbar_quantum;
4022       }
4023     }
4024
4025     if (stop_flag) {
4026       /* Well, the user decided to abort the rescan.  Sadly, as this
4027          isn't a reread, recovering is difficult, so we'll just
4028          close the current capture. */
4029       break;
4030     }
4031
4032     /* Add this packet's link-layer encapsulation type to cf->linktypes, if
4033        it's not already there.
4034        XXX - yes, this is O(N), so if every packet had a different
4035        link-layer encapsulation type, it'd be O(N^2) to read the file, but
4036        there are probably going to be a small number of encapsulation types
4037        in a file. */
4038     cf_add_encapsulation_type(cf, phdr->pkt_encap);
4039   }
4040
4041   /* Free the display name */
4042   g_free(name_ptr);
4043
4044   /* We're done reading the file; destroy the progress bar if it was created. */
4045   if (progbar != NULL)
4046     destroy_progress_dlg(progbar);
4047
4048   /* We're done reading sequentially through the file. */
4049   cf->state = FILE_READ_DONE;
4050
4051   /* Close the sequential I/O side, to free up memory it requires. */
4052   wtap_sequential_close(cf->wth);
4053
4054   /* compute the time it took to load the file */
4055   compute_elapsed(&start_time);
4056
4057   /* Set the file encapsulation type now; we don't know what it is until
4058      we've looked at all the packets, as we don't know until then whether
4059      there's more than one type (and thus whether it's
4060      WTAP_ENCAP_PER_PACKET). */
4061   cf->lnk_t = wtap_file_encap(cf->wth);
4062
4063   cf_callback_invoke(cf_cb_file_rescan_finished, cf);
4064
4065   if (stop_flag) {
4066     /* Our caller will give up at this point. */
4067     return CF_READ_ABORTED;
4068   }
4069
4070   if (*err != 0) {
4071     /* Put up a message box noting that the read failed somewhere along
4072        the line.  Don't throw out the stuff we managed to read, though,
4073        if any. */
4074     switch (*err) {
4075
4076     case WTAP_ERR_UNSUPPORTED:
4077       simple_error_message_box(
4078                  "The capture file contains record data that Wireshark doesn't support.\n(%s)",
4079                  err_info);
4080       g_free(err_info);
4081       break;
4082
4083     case WTAP_ERR_UNSUPPORTED_ENCAP:
4084       simple_error_message_box(
4085                  "The capture file has a packet with a network type that Wireshark doesn't support.\n(%s)",
4086                  err_info);
4087       g_free(err_info);
4088       break;
4089
4090     case WTAP_ERR_CANT_READ:
4091       simple_error_message_box(
4092                  "An attempt to read from the capture file failed for"
4093                  " some unknown reason.");
4094       break;
4095
4096     case WTAP_ERR_SHORT_READ:
4097       simple_error_message_box(
4098                  "The capture file appears to have been cut short"
4099                  " in the middle of a packet.");
4100       break;
4101
4102     case WTAP_ERR_BAD_FILE:
4103       simple_error_message_box(
4104                  "The capture file appears to be damaged or corrupt.\n(%s)",
4105                  err_info);
4106       g_free(err_info);
4107       break;
4108
4109     case WTAP_ERR_DECOMPRESS:
4110       simple_error_message_box(
4111                  "The compressed capture file appears to be damaged or corrupt.\n"
4112                  "(%s)", err_info);
4113       g_free(err_info);
4114       break;
4115
4116     default:
4117       simple_error_message_box(
4118                  "An error occurred while reading the"
4119                  " capture file: %s.", wtap_strerror(*err));
4120       break;
4121     }
4122     return CF_READ_ERROR;
4123   } else
4124     return CF_READ_OK;
4125 }
4126
4127 cf_write_status_t
4128 cf_save_packets(capture_file *cf, const char *fname, guint save_format,
4129                 gboolean compressed, gboolean discard_comments,
4130                 gboolean dont_reopen)
4131 {
4132   gchar        *fname_new = NULL;
4133   int           err;
4134   gchar        *err_info;
4135   enum {
4136      SAVE_WITH_MOVE,
4137      SAVE_WITH_COPY,
4138      SAVE_WITH_WTAP
4139   }             how_to_save;
4140   wtap_dumper  *pdh;
4141   save_callback_args_t callback_args;
4142 #ifdef _WIN32
4143   gchar        *display_basename;
4144 #endif
4145   guint         framenum;
4146   frame_data   *fdata;
4147
4148   cf_callback_invoke(cf_cb_file_save_started, (gpointer)fname);
4149
4150   if (save_format == cf->cd_t && compressed == cf->iscompressed
4151       && !discard_comments && !cf->unsaved_changes) {
4152     /* We're saving in the format it's already in, and we're
4153        not discarding comments, and there are no changes we have
4154        in memory that aren't saved to the file, so we can just move
4155        or copy the raw data. */
4156
4157     if (cf->is_tempfile) {
4158       /* The file being saved is a temporary file from a live
4159          capture, so it doesn't need to stay around under that name;
4160          first, try renaming the capture buffer file to the new name.
4161          This acts as a "safe save", in that, if the file already
4162          exists, the existing file will be removed only if the rename
4163          succeeds.
4164
4165          Sadly, on Windows, as we have the current capture file
4166          open, even MoveFileEx() with MOVEFILE_REPLACE_EXISTING
4167          (to cause the rename to remove an existing target), as
4168          done by ws_stdio_rename() (ws_rename() is #defined to
4169          be ws_stdio_rename() on Windows) will fail.
4170
4171          According to the MSDN documentation for CreateFile(), if,
4172          when we open a capture file, we were to directly do a CreateFile(),
4173          opening with FILE_SHARE_DELETE|FILE_SHARE_READ, and then
4174          convert it to a file descriptor with _open_osfhandle(),
4175          that would allow the file to be renamed out from under us.
4176
4177          However, that doesn't work in practice.  Perhaps the problem
4178          is that the process doing the rename is the process that
4179          has the file open. */
4180 #ifndef _WIN32
4181       if (ws_rename(cf->filename, fname) == 0) {
4182         /* That succeeded - there's no need to copy the source file. */
4183         how_to_save = SAVE_WITH_MOVE;
4184       } else {
4185         if (errno == EXDEV) {
4186           /* They're on different file systems, so we have to copy the
4187              file. */
4188           how_to_save = SAVE_WITH_COPY;
4189         } else {
4190           /* The rename failed, but not because they're on different
4191              file systems - put up an error message.  (Or should we
4192              just punt and try to copy?  The only reason why I'd
4193              expect the rename to fail and the copy to succeed would
4194              be if we didn't have permission to remove the file from
4195              the temporary directory, and that might be fixable - but
4196              is it worth requiring the user to go off and fix it?) */
4197           cf_rename_failure_alert_box(fname, errno);
4198           goto fail;
4199         }
4200       }
4201 #else
4202       how_to_save = SAVE_WITH_COPY;
4203 #endif
4204     } else {
4205       /* It's a permanent file, so we should copy it, and not remove the
4206          original. */
4207       how_to_save = SAVE_WITH_COPY;
4208     }
4209
4210     if (how_to_save == SAVE_WITH_COPY) {
4211       /* Copy the file, if we haven't moved it.  If we're overwriting
4212          an existing file, we do it with a "safe save", by writing
4213          to a new file and, if the write succeeds, renaming the
4214          new file on top of the old file. */
4215       if (file_exists(fname)) {
4216         fname_new = g_strdup_printf("%s~", fname);
4217         if (!copy_file_binary_mode(cf->filename, fname_new))
4218           goto fail;
4219       } else {
4220         if (!copy_file_binary_mode(cf->filename, fname))
4221           goto fail;
4222       }
4223     }
4224   } else {
4225     /* Either we're saving in a different format or we're saving changes,
4226        such as added, modified, or removed comments, that haven't yet
4227        been written to the underlying file; we can't do that by copying
4228        or moving the capture file, we have to do it by writing the packets
4229        out in Wiretap. */
4230
4231     wtapng_section_t *shb_hdr = NULL;
4232     wtapng_iface_descriptions_t *idb_inf = NULL;
4233
4234     shb_hdr = wtap_file_get_shb_info(cf->wth);
4235     idb_inf = wtap_file_get_idb_info(cf->wth);
4236
4237     if (file_exists(fname)) {
4238       /* We're overwriting an existing file; write out to a new file,
4239          and, if that succeeds, rename the new file on top of the
4240          old file.  That makes this a "safe save", so that we don't
4241          lose the old file if we have a problem writing out the new
4242          file.  (If the existing file is the current capture file,
4243          we *HAVE* to do that, otherwise we're overwriting the file
4244          from which we're reading the packets that we're writing!) */
4245       fname_new = g_strdup_printf("%s~", fname);
4246       pdh = wtap_dump_open_ng(fname_new, save_format, cf->lnk_t, cf->snap,
4247                               compressed, shb_hdr, idb_inf, &err);
4248     } else {
4249       pdh = wtap_dump_open_ng(fname, save_format, cf->lnk_t, cf->snap,
4250                               compressed, shb_hdr, idb_inf, &err);
4251     }
4252     g_free(idb_inf);
4253     idb_inf = NULL;
4254
4255     if (pdh == NULL) {
4256       cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
4257       goto fail;
4258     }
4259
4260     /* Add address resolution */
4261     wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list());
4262
4263     /* Iterate through the list of packets, processing all the packets. */
4264     callback_args.pdh = pdh;
4265     callback_args.fname = fname;
4266     callback_args.file_type = save_format;
4267     switch (process_specified_packets(cf, NULL, "Saving", "packets",
4268                                       TRUE, save_packet, &callback_args)) {
4269
4270     case PSP_FINISHED:
4271       /* Completed successfully. */
4272       break;
4273
4274     case PSP_STOPPED:
4275       /* The user decided to abort the saving.
4276          If we're writing to a temporary file, remove it.
4277          XXX - should we do so even if we're not writing to a
4278          temporary file? */
4279       wtap_dump_close(pdh, &err);
4280       if (fname_new != NULL)
4281         ws_unlink(fname_new);
4282       cf_callback_invoke(cf_cb_file_save_stopped, NULL);
4283       return CF_WRITE_ABORTED;
4284
4285     case PSP_FAILED:
4286       /* Error while saving.
4287          If we're writing to a temporary file, remove it. */
4288       if (fname_new != NULL)
4289         ws_unlink(fname_new);
4290       wtap_dump_close(pdh, &err);
4291       goto fail;
4292     }
4293
4294     if (!wtap_dump_close(pdh, &err)) {
4295       cf_close_failure_alert_box(fname, err);
4296       goto fail;
4297     }
4298
4299     how_to_save = SAVE_WITH_WTAP;
4300   }
4301
4302   if (fname_new != NULL) {
4303     /* We wrote out to fname_new, and should rename it on top of
4304        fname.  fname_new is now closed, so that should be possible even
4305        on Windows.  However, on Windows, we first need to close whatever
4306        file descriptors we have open for fname. */
4307 #ifdef _WIN32
4308     wtap_fdclose(cf->wth);
4309 #endif
4310     /* Now do the rename. */
4311     if (ws_rename(fname_new, fname) == -1) {
4312       /* Well, the rename failed. */
4313       cf_rename_failure_alert_box(fname, errno);
4314 #ifdef _WIN32
4315       /* Attempt to reopen the random file descriptor using the
4316          current file's filename.  (At this point, the sequential
4317          file descriptor is closed.) */
4318       if (!wtap_fdreopen(cf->wth, cf->filename, &err)) {
4319         /* Oh, well, we're screwed. */
4320         display_basename = g_filename_display_basename(cf->filename);
4321         simple_error_message_box(
4322                       file_open_error_message(err, FALSE), display_basename);
4323         g_free(display_basename);
4324       }
4325 #endif
4326       goto fail;
4327     }
4328   }
4329
4330   cf_callback_invoke(cf_cb_file_save_finished, NULL);
4331   cf->unsaved_changes = FALSE;
4332
4333   if (!dont_reopen) {
4334     switch (how_to_save) {
4335
4336     case SAVE_WITH_MOVE:
4337       /* We just moved the file, so the wtap structure refers to the
4338          new file, and all the information other than the filename
4339          and the "is temporary" status applies to the new file; just
4340          update that. */
4341       g_free(cf->filename);
4342       cf->filename = g_strdup(fname);
4343       cf->is_tempfile = FALSE;
4344       cf_callback_invoke(cf_cb_file_fast_save_finished, cf);
4345       break;
4346
4347     case SAVE_WITH_COPY:
4348       /* We just copied the file, s all the information other than
4349          the wtap structure, the filename, and the "is temporary"
4350          status applies to the new file; just update that. */
4351       wtap_close(cf->wth);
4352       cf->wth = wtap_open_offline(fname, &err, &err_info, TRUE);
4353       if (cf->wth == NULL) {
4354         cf_open_failure_alert_box(fname, err, err_info, FALSE, 0);
4355         cf_close(cf);
4356       } else {
4357         g_free(cf->filename);
4358         cf->filename = g_strdup(fname);
4359         cf->is_tempfile = FALSE;
4360       }
4361       cf_callback_invoke(cf_cb_file_fast_save_finished, cf);
4362       break;
4363
4364     case SAVE_WITH_WTAP:
4365       /* Open and read the file we saved to.
4366
4367          XXX - this is somewhat of a waste; we already have the
4368          packets, all this gets us is updated file type information
4369          (which we could just stuff into "cf"), and having the new
4370          file be the one we have opened and from which we're reading
4371          the data, and it means we have to spend time opening and
4372          reading the file, which could be a significant amount of
4373          time if the file is large.
4374
4375          If the capture-file-writing code were to return the
4376          seek offset of each packet it writes, we could save that
4377          in the frame_data structure for the frame, and just open
4378          the file without reading it again...
4379
4380          ...as long as, for gzipped files, the process of writing
4381          out the file *also* generates the information needed to
4382          support fast random access to the compressed file. */
4383       if (rescan_file(cf, fname, FALSE, &err) != CF_READ_OK) {
4384         /* The rescan failed; just close the file.  Either
4385            a dialog was popped up for the failure, so the
4386            user knows what happened, or they stopped the
4387            rescan, in which case they know what happened. */
4388         cf_close(cf);
4389       }
4390       break;
4391     }
4392
4393     /* If we were told to discard the comments, do so. */
4394     if (discard_comments) {
4395       /* Remove SHB comment, if any. */
4396       wtap_write_shb_comment(cf->wth, NULL);
4397
4398       /* Remove packet comments. */
4399       for (framenum = 1; framenum <= cf->count; framenum++) {
4400         fdata = frame_data_sequence_find(cf->frames, framenum);
4401         if (fdata->opt_comment) {
4402           g_free(fdata->opt_comment);
4403           fdata->opt_comment = NULL;
4404           cf->packet_comment_count--;
4405         }
4406       }
4407     }
4408   }
4409   return CF_WRITE_OK;
4410
4411 fail:
4412   if (fname_new != NULL) {
4413     /* We were trying to write to a temporary file; get rid of it if it
4414        exists.  (We don't care whether this fails, as, if it fails,
4415        there's not much we can do about it.  I guess if it failed for
4416        a reason other than "it doesn't exist", we could report an
4417        error, so the user knows there's a junk file that they might
4418        want to clean up.) */
4419     ws_unlink(fname_new);
4420     g_free(fname_new);
4421   }
4422   cf_callback_invoke(cf_cb_file_save_failed, NULL);
4423   return CF_WRITE_ERROR;
4424 }
4425
4426 cf_write_status_t
4427 cf_export_specified_packets(capture_file *cf, const char *fname,
4428                             packet_range_t *range, guint save_format,
4429                             gboolean compressed)
4430 {
4431   gchar        *fname_new = NULL;
4432   int           err;
4433   wtap_dumper  *pdh;
4434   save_callback_args_t callback_args;
4435   wtapng_section_t *shb_hdr = NULL;
4436   wtapng_iface_descriptions_t *idb_inf = NULL;
4437
4438   cf_callback_invoke(cf_cb_file_export_specified_packets_started, (gpointer)fname);
4439
4440   packet_range_process_init(range);
4441
4442   /* We're writing out specified packets from the specified capture
4443      file to another file.  Even if all captured packets are to be
4444      written, don't special-case the operation - read each packet
4445      and then write it out if it's one of the specified ones. */
4446
4447   shb_hdr = wtap_file_get_shb_info(cf->wth);
4448   idb_inf = wtap_file_get_idb_info(cf->wth);
4449
4450   if (file_exists(fname)) {
4451     /* We're overwriting an existing file; write out to a new file,
4452        and, if that succeeds, rename the new file on top of the
4453        old file.  That makes this a "safe save", so that we don't
4454        lose the old file if we have a problem writing out the new
4455        file.  (If the existing file is the current capture file,
4456        we *HAVE* to do that, otherwise we're overwriting the file
4457        from which we're reading the packets that we're writing!) */
4458     fname_new = g_strdup_printf("%s~", fname);
4459     pdh = wtap_dump_open_ng(fname_new, save_format, cf->lnk_t, cf->snap,
4460                             compressed, shb_hdr, idb_inf, &err);
4461   } else {
4462     pdh = wtap_dump_open_ng(fname, save_format, cf->lnk_t, cf->snap,
4463                             compressed, shb_hdr, idb_inf, &err);
4464   }
4465   g_free(idb_inf);
4466   idb_inf = NULL;
4467
4468   if (pdh == NULL) {
4469     cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
4470     goto fail;
4471   }
4472
4473   /* Add address resolution */
4474   wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list());
4475
4476   /* Iterate through the list of packets, processing the packets we were
4477      told to process.
4478
4479      XXX - we've already called "packet_range_process_init(range)", but
4480      "process_specified_packets()" will do it again.  Fortunately,
4481      that's harmless in this case, as we haven't done anything to
4482      "range" since we initialized it. */
4483   callback_args.pdh = pdh;
4484   callback_args.fname = fname;
4485   callback_args.file_type = save_format;
4486   switch (process_specified_packets(cf, range, "Writing", "specified packets",
4487                                     TRUE, save_packet, &callback_args)) {
4488
4489   case PSP_FINISHED:
4490     /* Completed successfully. */
4491     break;
4492
4493   case PSP_STOPPED:
4494       /* The user decided to abort the saving.
4495          If we're writing to a temporary file, remove it.
4496          XXX - should we do so even if we're not writing to a
4497          temporary file? */
4498       wtap_dump_close(pdh, &err);
4499       if (fname_new != NULL)
4500         ws_unlink(fname_new);
4501       cf_callback_invoke(cf_cb_file_export_specified_packets_stopped, NULL);
4502       return CF_WRITE_ABORTED;
4503     break;
4504
4505   case PSP_FAILED:
4506     /* Error while saving.
4507        If we're writing to a temporary file, remove it. */
4508     if (fname_new != NULL)
4509       ws_unlink(fname_new);
4510     wtap_dump_close(pdh, &err);
4511     goto fail;
4512   }
4513
4514   if (!wtap_dump_close(pdh, &err)) {
4515     cf_close_failure_alert_box(fname, err);
4516     goto fail;
4517   }
4518
4519   if (fname_new != NULL) {
4520     /* We wrote out to fname_new, and should rename it on top of
4521        fname; fname is now closed, so that should be possible even
4522        on Windows.  Do the rename. */
4523     if (ws_rename(fname_new, fname) == -1) {
4524       /* Well, the rename failed. */
4525       cf_rename_failure_alert_box(fname, errno);
4526       goto fail;
4527     }
4528   }
4529
4530   cf_callback_invoke(cf_cb_file_export_specified_packets_finished, NULL);
4531   return CF_WRITE_OK;
4532
4533 fail:
4534   if (fname_new != NULL) {
4535     /* We were trying to write to a temporary file; get rid of it if it
4536        exists.  (We don't care whether this fails, as, if it fails,
4537        there's not much we can do about it.  I guess if it failed for
4538        a reason other than "it doesn't exist", we could report an
4539        error, so the user knows there's a junk file that they might
4540        want to clean up.) */
4541     ws_unlink(fname_new);
4542     g_free(fname_new);
4543   }
4544   cf_callback_invoke(cf_cb_file_export_specified_packets_failed, NULL);
4545   return CF_WRITE_ERROR;
4546 }
4547
4548 static void
4549 cf_open_failure_alert_box(const char *filename, int err, gchar *err_info,
4550                           gboolean for_writing, int file_type)
4551 {
4552   gchar *display_basename;
4553
4554   if (err < 0) {
4555     /* Wiretap error. */
4556     display_basename = g_filename_display_basename(filename);
4557     switch (err) {
4558
4559     case WTAP_ERR_NOT_REGULAR_FILE:
4560       simple_error_message_box(
4561             "The file \"%s\" is a \"special file\" or socket or other non-regular file.",
4562             display_basename);
4563       break;
4564
4565     case WTAP_ERR_RANDOM_OPEN_PIPE:
4566       /* Seen only when opening a capture file for reading. */
4567       simple_error_message_box(
4568             "The file \"%s\" is a pipe or FIFO; Wireshark can't read pipe or FIFO files.\n"
4569             "To capture from a pipe or FIFO use wireshark -i -",
4570             display_basename);
4571       break;
4572
4573     case WTAP_ERR_FILE_UNKNOWN_FORMAT:
4574       /* Seen only when opening a capture file for reading. */
4575       simple_error_message_box(
4576             "The file \"%s\" isn't a capture file in a format Wireshark understands.",
4577             display_basename);
4578       break;
4579
4580     case WTAP_ERR_UNSUPPORTED:
4581       /* Seen only when opening a capture file for reading. */
4582       simple_error_message_box(
4583             "The file \"%s\" isn't a capture file in a format Wireshark understands.\n"
4584             "(%s)",
4585             display_basename, err_info);
4586       g_free(err_info);
4587       break;
4588
4589     case WTAP_ERR_CANT_WRITE_TO_PIPE:
4590       /* Seen only when opening a capture file for writing. */
4591       simple_error_message_box(
4592             "The file \"%s\" is a pipe, and %s capture files can't be "
4593             "written to a pipe.",
4594             display_basename, wtap_file_type_string(file_type));
4595       break;
4596
4597     case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
4598       /* Seen only when opening a capture file for writing. */
4599       simple_error_message_box(
4600             "Wireshark doesn't support writing capture files in that format.");
4601       break;
4602
4603     case WTAP_ERR_UNSUPPORTED_ENCAP:
4604       if (for_writing) {
4605         simple_error_message_box("Wireshark can't save this capture in that format.");
4606       } else {
4607         simple_error_message_box(
4608               "The file \"%s\" is a capture for a network type that Wireshark doesn't support.\n"
4609               "(%s)",
4610               display_basename, err_info);
4611         g_free(err_info);
4612       }
4613       break;
4614
4615     case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
4616       if (for_writing) {
4617         simple_error_message_box(
4618               "Wireshark can't save this capture in that format.");
4619       } else {
4620         simple_error_message_box(
4621               "The file \"%s\" is a capture for a network type that Wireshark doesn't support.",
4622               display_basename);
4623       }
4624       break;
4625
4626     case WTAP_ERR_BAD_FILE:
4627       /* Seen only when opening a capture file for reading. */
4628       simple_error_message_box(
4629             "The file \"%s\" appears to be damaged or corrupt.\n"
4630             "(%s)",
4631             display_basename, err_info);
4632       g_free(err_info);
4633       break;
4634
4635     case WTAP_ERR_CANT_OPEN:
4636       if (for_writing) {
4637         simple_error_message_box(
4638               "The file \"%s\" could not be created for some unknown reason.",
4639               display_basename);
4640       } else {
4641         simple_error_message_box(
4642               "The file \"%s\" could not be opened for some unknown reason.",
4643               display_basename);
4644       }
4645       break;
4646
4647     case WTAP_ERR_SHORT_READ:
4648       simple_error_message_box(
4649             "The file \"%s\" appears to have been cut short"
4650             " in the middle of a packet or other data.",
4651             display_basename);
4652       break;
4653
4654     case WTAP_ERR_SHORT_WRITE:
4655       simple_error_message_box(
4656             "A full header couldn't be written to the file \"%s\".",
4657             display_basename);
4658       break;
4659
4660     case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
4661       simple_error_message_box(
4662             "This file type cannot be written as a compressed file.");
4663       break;
4664
4665     case WTAP_ERR_DECOMPRESS:
4666       simple_error_message_box(
4667             "The compressed file \"%s\" appears to be damaged or corrupt.\n"
4668             "(%s)", display_basename, err_info);
4669       g_free(err_info);
4670       break;
4671
4672     default:
4673       simple_error_message_box(
4674             "The file \"%s\" could not be %s: %s.",
4675             display_basename,
4676             for_writing ? "created" : "opened",
4677             wtap_strerror(err));
4678       break;
4679     }
4680     g_free(display_basename);
4681   } else {
4682     /* OS error. */
4683     open_failure_alert_box(filename, err, for_writing);
4684   }
4685 }
4686
4687 /*
4688  * XXX - whether we mention the source pathname, the target pathname,
4689  * or both depends on the error and on what we find if we look for
4690  * one or both of them.
4691  */
4692 static void
4693 cf_rename_failure_alert_box(const char *filename, int err)
4694 {
4695   gchar *display_basename;
4696
4697   display_basename = g_filename_display_basename(filename);
4698   switch (err) {
4699
4700   case ENOENT:
4701     /* XXX - should check whether the source exists and, if not,
4702        report it as the problem and, if so, report the destination
4703        as the problem. */
4704     simple_error_message_box("The path to the file \"%s\" doesn't exist.",
4705                              display_basename);
4706     break;
4707
4708   case EACCES:
4709     /* XXX - if we're doing a rename after a safe save, we should
4710        probably say something else. */
4711     simple_error_message_box("You don't have permission to move the capture file to \"%s\".",
4712                              display_basename);
4713     break;
4714
4715   default:
4716     /* XXX - this should probably mention both the source and destination
4717        pathnames. */
4718     simple_error_message_box("The file \"%s\" could not be moved: %s.",
4719                              display_basename, wtap_strerror(err));
4720     break;
4721   }
4722   g_free(display_basename);
4723 }
4724
4725 /* Check for write errors - if the file is being written to an NFS server,
4726    a write error may not show up until the file is closed, as NFS clients
4727    might not send writes to the server until the "write()" call finishes,
4728    so that the write may fail on the server but the "write()" may succeed. */
4729 static void
4730 cf_close_failure_alert_box(const char *filename, int err)
4731 {
4732   gchar *display_basename;
4733
4734   if (err < 0) {
4735     /* Wiretap error. */
4736     display_basename = g_filename_display_basename(filename);
4737     switch (err) {
4738
4739     case WTAP_ERR_CANT_CLOSE:
4740       simple_error_message_box(
4741             "The file \"%s\" couldn't be closed for some unknown reason.",
4742             display_basename);
4743       break;
4744
4745     case WTAP_ERR_SHORT_WRITE:
4746       simple_error_message_box(
4747             "Not all the packets could be written to the file \"%s\".",
4748                     display_basename);
4749       break;
4750
4751     default:
4752       simple_error_message_box(
4753             "An error occurred while closing the file \"%s\": %s.",
4754             display_basename, wtap_strerror(err));
4755       break;
4756     }
4757     g_free(display_basename);
4758   } else {
4759     /* OS error.
4760        We assume that a close error from the OS is really a write error. */
4761     write_failure_alert_box(filename, err);
4762   }
4763 }
4764
4765 /* Reload the current capture file. */
4766 void
4767 cf_reload(capture_file *cf) {
4768   gchar *filename;
4769   gboolean is_tempfile;
4770   int err;
4771
4772   /* If the file could be opened, "cf_open()" calls "cf_close()"
4773      to get rid of state for the old capture file before filling in state
4774      for the new capture file.  "cf_close()" will remove the file if
4775      it's a temporary file; we don't want that to happen (for one thing,
4776      it'd prevent subsequent reopens from working).  Remember whether it's
4777      a temporary file, mark it as not being a temporary file, and then
4778      reopen it as the type of file it was.
4779
4780      Also, "cf_close()" will free "cf->filename", so we must make
4781      a copy of it first. */
4782   filename = g_strdup(cf->filename);
4783   is_tempfile = cf->is_tempfile;
4784   cf->is_tempfile = FALSE;
4785   if (cf_open(cf, filename, is_tempfile, &err) == CF_OK) {
4786     switch (cf_read(cf, TRUE)) {
4787
4788     case CF_READ_OK:
4789     case CF_READ_ERROR:
4790       /* Just because we got an error, that doesn't mean we were unable
4791          to read any of the file; we handle what we could get from the
4792          file. */
4793       break;
4794
4795     case CF_READ_ABORTED:
4796       /* The user bailed out of re-reading the capture file; the
4797          capture file has been closed - just free the capture file name
4798          string and return (without changing the last containing
4799          directory). */
4800       g_free(filename);
4801       return;
4802     }
4803   } else {
4804     /* The open failed, so "cf->is_tempfile" wasn't set to "is_tempfile".
4805        Instead, the file was left open, so we should restore "cf->is_tempfile"
4806        ourselves.
4807
4808        XXX - change the menu?  Presumably "cf_open()" will do that;
4809        make sure it does! */
4810     cf->is_tempfile = is_tempfile;
4811   }
4812   /* "cf_open()" made a copy of the file name we handed it, so
4813      we should free up our copy. */
4814   g_free(filename);
4815 }
4816
4817 /*
4818  * Editor modelines
4819  *
4820  * Local Variables:
4821  * c-basic-offset: 2
4822  * tab-width: 8
4823  * indent-tabs-mode: nil
4824  * End:
4825  *
4826  * ex: set shiftwidth=2 tabstop=8 expandtab:
4827  * :indentSize=2:tabSize=8:noTabs=true:
4828  */