Move the common parts of iface_lists.[ch] from ui/gtk/ to ui/. Leave the
[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       simple_message_box(ESD_TYPE_ERROR, NULL,
1529           "See the help for a description of the display filter syntax.",
1530           "\"%s\" isn't a valid display filter: %s",
1531           dftext, dfilter_error_msg);
1532       g_free(dftext);
1533       return CF_ERROR;
1534     }
1535
1536     /* Was it empty? */
1537     if (dfcode == NULL) {
1538       /* Yes - free the filter text, and set it to null. */
1539       g_free(dftext);
1540       dftext = NULL;
1541     }
1542   }
1543
1544   /* We have a valid filter.  Replace the current filter. */
1545   g_free(cf->dfilter);
1546   cf->dfilter = dftext;
1547   g_get_current_time(&start_time);
1548
1549
1550   /* Now rescan the packet list, applying the new filter, but not
1551      throwing away information constructed on a previous pass. */
1552   if (dftext == NULL) {
1553     rescan_packets(cf, "Resetting", "Filter", TRUE, FALSE);
1554   } else {
1555     rescan_packets(cf, "Filtering", dftext, TRUE, FALSE);
1556   }
1557
1558   /* Cleanup and release all dfilter resources */
1559   dfilter_free(dfcode);
1560
1561   return CF_OK;
1562 }
1563
1564 void
1565 cf_reftime_packets(capture_file *cf)
1566 {
1567
1568   ref_time_packets(cf);
1569 }
1570
1571 void
1572 cf_redissect_packets(capture_file *cf)
1573 {
1574   rescan_packets(cf, "Reprocessing", "all packets", TRUE, TRUE);
1575 }
1576
1577 gboolean
1578 cf_read_frame_r(capture_file *cf, frame_data *fdata,
1579                 union wtap_pseudo_header *pseudo_header, guint8 *pd)
1580 {
1581   int err;
1582   gchar *err_info;
1583   gchar *display_basename;
1584
1585 #ifdef WANT_PACKET_EDITOR
1586   /* if fdata->file_off == -1 it means packet was edited, and we must find data inside edited_frames tree */
1587   if (G_UNLIKELY(fdata->file_off == -1)) {
1588     const modified_frame_data *frame = (const modified_frame_data *) g_tree_lookup(cf->edited_frames, GINT_TO_POINTER(fdata->num));
1589
1590     if (!frame) {
1591       simple_error_message_box("fdata->file_off == -1, but can't find modified frame!");
1592       return FALSE;
1593     }
1594
1595     *pseudo_header = frame->ph;
1596     memcpy(pd, frame->pd, fdata->cap_len);
1597     return TRUE;
1598   }
1599 #endif
1600
1601   if (!wtap_seek_read(cf->wth, fdata->file_off, pseudo_header, pd,
1602                       fdata->cap_len, &err, &err_info)) {
1603     display_basename = g_filename_display_basename(cf->filename);
1604     switch (err) {
1605
1606     case WTAP_ERR_UNSUPPORTED_ENCAP:
1607       simple_error_message_box("The file \"%s\" has a packet with a network type that Wireshark doesn't support.\n(%s)",
1608                  display_basename, err_info);
1609       g_free(err_info);
1610       break;
1611
1612     case WTAP_ERR_BAD_FILE:
1613       simple_error_message_box("An error occurred while reading from the file \"%s\": %s.\n(%s)",
1614                  display_basename, wtap_strerror(err), err_info);
1615       g_free(err_info);
1616       break;
1617
1618     default:
1619       simple_error_message_box(
1620                  "An error occurred while reading from the file \"%s\": %s.",
1621                  display_basename, wtap_strerror(err));
1622       break;
1623     }
1624     g_free(display_basename);
1625     return FALSE;
1626   }
1627   return TRUE;
1628 }
1629
1630 gboolean
1631 cf_read_frame(capture_file *cf, frame_data *fdata)
1632 {
1633   return cf_read_frame_r(cf, fdata, &cf->pseudo_header, cf->pd);
1634 }
1635
1636 /* Rescan the list of packets, reconstructing the CList.
1637
1638    "action" describes why we're doing this; it's used in the progress
1639    dialog box.
1640
1641    "action_item" describes what we're doing; it's used in the progress
1642    dialog box.
1643
1644    "refilter" is TRUE if we need to re-evaluate the filter expression.
1645
1646    "redissect" is TRUE if we need to make the dissectors reconstruct
1647    any state information they have (because a preference that affects
1648    some dissector has changed, meaning some dissector might construct
1649    its state differently from the way it was constructed the last time). */
1650 static void
1651 rescan_packets(capture_file *cf, const char *action, const char *action_item,
1652         gboolean refilter, gboolean redissect)
1653 {
1654   /* Rescan packets new packet list */
1655   guint32     framenum;
1656   frame_data *fdata;
1657   progdlg_t  *progbar = NULL;
1658   gboolean    stop_flag;
1659   int         count;
1660   frame_data *selected_frame, *preceding_frame, *following_frame, *prev_frame;
1661   int         selected_frame_num, preceding_frame_num, following_frame_num, prev_frame_num;
1662   gboolean    selected_frame_seen;
1663   float       progbar_val;
1664   GTimeVal    start_time;
1665   gchar       status_str[100];
1666   int         progbar_nextstep;
1667   int         progbar_quantum;
1668   dfilter_t   *dfcode;
1669   gboolean    filtering_tap_listeners;
1670   guint       tap_flags;
1671   gboolean    add_to_packet_list = FALSE;
1672   gboolean compiled;
1673
1674   /* Compile the current display filter.
1675    * We assume this will not fail since cf->dfilter is only set in
1676    * cf_filter IFF the filter was valid.
1677    */
1678   compiled = dfilter_compile(cf->dfilter, &dfcode);
1679   g_assert(!cf->dfilter || (compiled && dfcode));
1680
1681   /* Do we have any tap listeners with filters? */
1682   filtering_tap_listeners = have_filtering_tap_listeners();
1683
1684   /* Get the union of the flags for all tap listeners. */
1685   tap_flags = union_of_tap_listener_flags();
1686
1687   reset_tap_listeners();
1688   /* Which frame, if any, is the currently selected frame?
1689      XXX - should the selected frame or the focus frame be the "current"
1690      frame, that frame being the one from which "Find Frame" searches
1691      start? */
1692   selected_frame = cf->current_frame;
1693
1694   /* Mark frame num as not found */
1695   selected_frame_num = -1;
1696
1697   /* Freeze the packet list while we redo it, so we don't get any
1698      screen updates while it happens. */
1699   new_packet_list_freeze();
1700
1701   if (redissect) {
1702     /* We need to re-initialize all the state information that protocols
1703        keep, because some preference that controls a dissector has changed,
1704        which might cause the state information to be constructed differently
1705        by that dissector. */
1706
1707     /* We might receive new packets while redissecting, and we don't
1708        want to dissect those before their time. */
1709     cf->redissecting = TRUE;
1710
1711     /* Cleanup all data structures used for dissection. */
1712     cleanup_dissection();
1713     /* Initialize all data structures used for dissection. */
1714     init_dissection();
1715
1716     /* We need to redissect the packets so we have to discard our old
1717      * packet list store. */
1718     new_packet_list_clear();
1719     add_to_packet_list = TRUE;
1720   }
1721
1722   /* We don't yet know which will be the first and last frames displayed. */
1723   cf->first_displayed = 0;
1724   cf->last_displayed = 0;
1725
1726   /* We currently don't display any packets */
1727   cf->displayed_count = 0;
1728
1729   /* Iterate through the list of frames.  Call a routine for each frame
1730      to check whether it should be displayed and, if so, add it to
1731      the display list. */
1732   nstime_set_unset(&first_ts);
1733   nstime_set_unset(&prev_dis_ts);
1734   nstime_set_unset(&prev_cap_ts);
1735   cum_bytes = 0;
1736
1737   /* Update the progress bar when it gets to this value. */
1738   progbar_nextstep = 0;
1739   /* When we reach the value that triggers a progress bar update,
1740      bump that value by this amount. */
1741   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
1742   /* Count of packets at which we've looked. */
1743   count = 0;
1744   /* Progress so far. */
1745   progbar_val = 0.0f;
1746
1747   stop_flag = FALSE;
1748   g_get_current_time(&start_time);
1749
1750   /* no previous row yet */
1751   prev_frame_num = -1;
1752   prev_frame = NULL;
1753
1754   preceding_frame_num = -1;
1755   preceding_frame = NULL;
1756   following_frame_num = -1;
1757   following_frame = NULL;
1758
1759   selected_frame_seen = FALSE;
1760
1761   for (framenum = 1; framenum <= cf->count; framenum++) {
1762     fdata = frame_data_sequence_find(cf->frames, framenum);
1763
1764     /* Create the progress bar if necessary.
1765        We check on every iteration of the loop, so that it takes no
1766        longer than the standard time to create it (otherwise, for a
1767        large file, we might take considerably longer than that standard
1768        time in order to get to the next progress bar step). */
1769     if (progbar == NULL)
1770       progbar = delayed_create_progress_dlg(cf->window, action, action_item, TRUE,
1771                                             &stop_flag, &start_time,
1772                                             progbar_val);
1773
1774     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1775        when we update it, we have to run the GTK+ main loop to get it
1776        to repaint what's pending, and doing so may involve an "ioctl()"
1777        to see if there's any pending input from an X server, and doing
1778        that for every packet can be costly, especially on a big file. */
1779     if (count >= progbar_nextstep) {
1780       /* let's not divide by zero. I should never be started
1781        * with count == 0, so let's assert that
1782        */
1783       g_assert(cf->count > 0);
1784       progbar_val = (gfloat) count / cf->count;
1785
1786       if (progbar != NULL) {
1787         g_snprintf(status_str, sizeof(status_str),
1788                   "%4u of %u frames", count, cf->count);
1789         update_progress_dlg(progbar, progbar_val, status_str);
1790       }
1791
1792       progbar_nextstep += progbar_quantum;
1793     }
1794
1795     if (stop_flag) {
1796       /* Well, the user decided to abort the filtering.  Just stop.
1797
1798          XXX - go back to the previous filter?  Users probably just
1799          want not to wait for a filtering operation to finish;
1800          unless we cancel by having no filter, reverting to the
1801          previous filter will probably be even more expensive than
1802          continuing the filtering, as it involves going back to the
1803          beginning and filtering, and even with no filter we currently
1804          have to re-generate the entire clist, which is also expensive.
1805
1806          I'm not sure what Network Monitor does, but it doesn't appear
1807          to give you an unfiltered display if you cancel. */
1808       break;
1809     }
1810
1811     count++;
1812
1813     if (redissect) {
1814       /* Since all state for the frame was destroyed, mark the frame
1815        * as not visited, free the GSList referring to the state
1816        * data (the per-frame data itself was freed by
1817        * "init_dissection()"), and null out the GSList pointer. */
1818       fdata->flags.visited = 0;
1819       frame_data_cleanup(fdata);
1820     }
1821
1822     if (redissect || refilter) {
1823       /* If we're redissecting or refiltering then any frame dependencies
1824        * from the previous dissection/filtering are no longer valid.
1825        */
1826       fdata->flags.dependent_of_displayed = 0;
1827     }
1828
1829     if (!cf_read_frame(cf, fdata))
1830       break; /* error reading the frame */
1831
1832     /* If the previous frame is displayed, and we haven't yet seen the
1833        selected frame, remember that frame - it's the closest one we've
1834        yet seen before the selected frame. */
1835     if (prev_frame_num != -1 && !selected_frame_seen && prev_frame->flags.passed_dfilter) {
1836       preceding_frame_num = prev_frame_num;
1837       preceding_frame = prev_frame;
1838     }
1839     add_packet_to_packet_list(fdata, cf, dfcode, filtering_tap_listeners,
1840                                     tap_flags, &cf->pseudo_header, cf->pd,
1841                                     refilter,
1842                                     add_to_packet_list);
1843
1844     /* If this frame is displayed, and this is the first frame we've
1845        seen displayed after the selected frame, remember this frame -
1846        it's the closest one we've yet seen at or after the selected
1847        frame. */
1848     if (fdata->flags.passed_dfilter && selected_frame_seen && following_frame_num == -1) {
1849       following_frame_num = fdata->num;
1850       following_frame = fdata;
1851     }
1852     if (fdata == selected_frame) {
1853       selected_frame_seen = TRUE;
1854       if (fdata->flags.passed_dfilter)
1855           selected_frame_num = fdata->num;
1856     }
1857
1858     /* Remember this frame - it'll be the previous frame
1859        on the next pass through the loop. */
1860     prev_frame_num = fdata->num;
1861     prev_frame = fdata;
1862   }
1863
1864   /* We are done redissecting the packet list. */
1865   cf->redissecting = FALSE;
1866
1867   if (redissect) {
1868     /* Clear out what remains of the visited flags and per-frame data
1869        pointers.
1870
1871        XXX - that may cause various forms of bogosity when dissecting
1872        these frames, as they won't have been seen by this sequential
1873        pass, but the only alternative I see is to keep scanning them
1874        even though the user requested that the scan stop, and that
1875        would leave the user stuck with an Wireshark grinding on
1876        until it finishes.  Should we just stick them with that? */
1877     for (; framenum <= cf->count; framenum++) {
1878       fdata = frame_data_sequence_find(cf->frames, framenum);
1879       fdata->flags.visited = 0;
1880       frame_data_cleanup(fdata);
1881     }
1882   }
1883
1884   /* We're done filtering the packets; destroy the progress bar if it
1885      was created. */
1886   if (progbar != NULL)
1887     destroy_progress_dlg(progbar);
1888
1889   /* Unfreeze the packet list. */
1890   if (!add_to_packet_list)
1891     new_packet_list_recreate_visible_rows();
1892
1893   /* Compute the time it took to filter the file */
1894   compute_elapsed(&start_time);
1895
1896   new_packet_list_thaw();
1897
1898   if (selected_frame_num == -1) {
1899     /* The selected frame didn't pass the filter. */
1900     if (selected_frame == NULL) {
1901       /* That's because there *was* no selected frame.  Make the first
1902          displayed frame the current frame. */
1903       selected_frame_num = 0;
1904     } else {
1905       /* Find the nearest displayed frame to the selected frame (whether
1906          it's before or after that frame) and make that the current frame.
1907          If the next and previous displayed frames are equidistant from the
1908          selected frame, choose the next one. */
1909       g_assert(following_frame == NULL ||
1910                following_frame->num >= selected_frame->num);
1911       g_assert(preceding_frame == NULL ||
1912                preceding_frame->num <= selected_frame->num);
1913       if (following_frame == NULL) {
1914         /* No frame after the selected frame passed the filter, so we
1915            have to select the last displayed frame before the selected
1916            frame. */
1917         selected_frame_num = preceding_frame_num;
1918         selected_frame = preceding_frame;
1919       } else if (preceding_frame == NULL) {
1920         /* No frame before the selected frame passed the filter, so we
1921            have to select the first displayed frame after the selected
1922            frame. */
1923         selected_frame_num = following_frame_num;
1924         selected_frame = following_frame;
1925       } else {
1926         /* Frames before and after the selected frame passed the filter, so
1927            we'll select the previous frame */
1928         selected_frame_num = preceding_frame_num;
1929         selected_frame = preceding_frame;
1930       }
1931     }
1932   }
1933
1934   if (selected_frame_num == -1) {
1935     /* There are no frames displayed at all. */
1936     cf_unselect_packet(cf);
1937   } else {
1938     /* Either the frame that was selected passed the filter, or we've
1939        found the nearest displayed frame to that frame.  Select it, make
1940        it the focus row, and make it visible. */
1941     /* Set to invalid to force update of packet list and packet details */
1942     cf->current_row = -1;
1943     if (selected_frame_num == 0) {
1944       new_packet_list_select_first_row();
1945     }else{
1946       if (!new_packet_list_select_row_from_data(selected_frame)) {
1947         /* We didn't find a row corresponding to this frame.
1948            This means that the frame isn't being displayed currently,
1949            so we can't select it. */
1950         simple_message_box(ESD_TYPE_INFO, NULL,
1951                            "The capture file is probably not fully dissected.",
1952                            "End of capture exceeded!");
1953       }
1954     }
1955   }
1956
1957   /* Cleanup and release all dfilter resources */
1958   dfilter_free(dfcode);
1959 }
1960
1961
1962 /*
1963  * Scan trough all frame data and recalculate the ref time
1964  * without rereading the file.
1965  * XXX - do we need a progres bar or is this fast enough?
1966  */
1967 static void
1968 ref_time_packets(capture_file *cf)
1969 {
1970   guint32 framenum;
1971   frame_data *fdata;
1972
1973   nstime_set_unset(&first_ts);
1974   nstime_set_unset(&prev_dis_ts);
1975   cum_bytes = 0;
1976
1977   for (framenum = 1; framenum <= cf->count; framenum++) {
1978     fdata = frame_data_sequence_find(cf->frames, framenum);
1979
1980     /* just add some value here until we know if it is being displayed or not */
1981     fdata->cum_bytes = cum_bytes + fdata->pkt_len;
1982
1983     /*
1984      *Timestamps
1985      */
1986
1987     /* If we don't have the time stamp of the first packet in the
1988      capture, it's because this is the first packet.  Save the time
1989      stamp of this packet as the time stamp of the first packet. */
1990     if (nstime_is_unset(&first_ts)) {
1991         first_ts  = fdata->abs_ts;
1992     }
1993       /* if this frames is marked as a reference time frame, reset
1994         firstsec and firstusec to this frame */
1995     if(fdata->flags.ref_time){
1996         first_ts = fdata->abs_ts;
1997     }
1998
1999     /* If we don't have the time stamp of the previous displayed packet,
2000      it's because this is the first displayed packet.  Save the time
2001      stamp of this packet as the time stamp of the previous displayed
2002      packet. */
2003     if (nstime_is_unset(&prev_dis_ts)) {
2004         prev_dis_ts = fdata->abs_ts;
2005     }
2006
2007     /* Get the time elapsed between the first packet and this packet. */
2008     nstime_delta(&fdata->rel_ts, &fdata->abs_ts, &first_ts);
2009
2010     /* If it's greater than the current elapsed time, set the elapsed time
2011      to it (we check for "greater than" so as not to be confused by
2012      time moving backwards). */
2013     if ((gint32)cf->elapsed_time.secs < fdata->rel_ts.secs
2014         || ((gint32)cf->elapsed_time.secs == fdata->rel_ts.secs && (gint32)cf->elapsed_time.nsecs < fdata->rel_ts.nsecs)) {
2015         cf->elapsed_time = fdata->rel_ts;
2016     }
2017
2018     /* If this frame is displayed, get the time elapsed between the
2019      previous displayed packet and this packet. */
2020     if( fdata->flags.passed_dfilter ) {
2021         nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, &prev_dis_ts);
2022         prev_dis_ts = fdata->abs_ts;
2023     }
2024
2025     /*
2026      * Byte counts
2027      */
2028     if( (fdata->flags.passed_dfilter) || (fdata->flags.ref_time) ){
2029         /* This frame either passed the display filter list or is marked as
2030         a time reference frame.  All time reference frames are displayed
2031         even if they dont pass the display filter */
2032         if(fdata->flags.ref_time){
2033             /* if this was a TIME REF frame we should reset the cum_bytes field */
2034             cum_bytes = fdata->pkt_len;
2035             fdata->cum_bytes =  cum_bytes;
2036         } else {
2037             /* increase cum_bytes with this packets length */
2038             cum_bytes += fdata->pkt_len;
2039         }
2040     }
2041   }
2042 }
2043
2044 typedef enum {
2045   PSP_FINISHED,
2046   PSP_STOPPED,
2047   PSP_FAILED
2048 } psp_return_t;
2049
2050 static psp_return_t
2051 process_specified_packets(capture_file *cf, packet_range_t *range,
2052     const char *string1, const char *string2, gboolean terminate_is_stop,
2053     gboolean (*callback)(capture_file *, frame_data *,
2054                          union wtap_pseudo_header *, const guint8 *, void *),
2055     void *callback_args)
2056 {
2057   guint32 framenum;
2058   frame_data *fdata;
2059   union wtap_pseudo_header pseudo_header;
2060   guint8      pd[WTAP_MAX_PACKET_SIZE+1];
2061   psp_return_t ret = PSP_FINISHED;
2062
2063   progdlg_t  *progbar = NULL;
2064   int         progbar_count;
2065   float       progbar_val;
2066   gboolean    progbar_stop_flag;
2067   GTimeVal    progbar_start_time;
2068   gchar       progbar_status_str[100];
2069   int         progbar_nextstep;
2070   int         progbar_quantum;
2071   range_process_e process_this;
2072
2073   /* Update the progress bar when it gets to this value. */
2074   progbar_nextstep = 0;
2075   /* When we reach the value that triggers a progress bar update,
2076      bump that value by this amount. */
2077   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
2078   /* Count of packets at which we've looked. */
2079   progbar_count = 0;
2080   /* Progress so far. */
2081   progbar_val = 0.0f;
2082
2083   progbar_stop_flag = FALSE;
2084   g_get_current_time(&progbar_start_time);
2085
2086   if (range != NULL)
2087     packet_range_process_init(range);
2088
2089   /* Iterate through all the packets, printing the packets that
2090      were selected by the current display filter.  */
2091   for (framenum = 1; framenum <= cf->count; framenum++) {
2092     fdata = frame_data_sequence_find(cf->frames, framenum);
2093
2094     /* Create the progress bar if necessary.
2095        We check on every iteration of the loop, so that it takes no
2096        longer than the standard time to create it (otherwise, for a
2097        large file, we might take considerably longer than that standard
2098        time in order to get to the next progress bar step). */
2099     if (progbar == NULL)
2100       progbar = delayed_create_progress_dlg(cf->window, string1, string2,
2101                                             terminate_is_stop,
2102                                             &progbar_stop_flag,
2103                                             &progbar_start_time,
2104                                             progbar_val);
2105
2106     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
2107        when we update it, we have to run the GTK+ main loop to get it
2108        to repaint what's pending, and doing so may involve an "ioctl()"
2109        to see if there's any pending input from an X server, and doing
2110        that for every packet can be costly, especially on a big file. */
2111     if (progbar_count >= progbar_nextstep) {
2112       /* let's not divide by zero. I should never be started
2113        * with count == 0, so let's assert that
2114        */
2115       g_assert(cf->count > 0);
2116       progbar_val = (gfloat) progbar_count / cf->count;
2117
2118       if (progbar != NULL) {
2119         g_snprintf(progbar_status_str, sizeof(progbar_status_str),
2120                    "%4u of %u packets", progbar_count, cf->count);
2121         update_progress_dlg(progbar, progbar_val, progbar_status_str);
2122       }
2123
2124       progbar_nextstep += progbar_quantum;
2125     }
2126
2127     if (progbar_stop_flag) {
2128       /* Well, the user decided to abort the operation.  Just stop,
2129          and arrange to return PSP_STOPPED to our caller, so they know
2130          it was stopped explicitly. */
2131       ret = PSP_STOPPED;
2132       break;
2133     }
2134
2135     progbar_count++;
2136
2137     if (range != NULL) {
2138       /* do we have to process this packet? */
2139       process_this = packet_range_process_packet(range, fdata);
2140       if (process_this == range_process_next) {
2141         /* this packet uninteresting, continue with next one */
2142         continue;
2143       } else if (process_this == range_processing_finished) {
2144         /* all interesting packets processed, stop the loop */
2145         break;
2146       }
2147     }
2148
2149     /* Get the packet */
2150     if (!cf_read_frame_r(cf, fdata, &pseudo_header, pd)) {
2151       /* Attempt to get the packet failed. */
2152       ret = PSP_FAILED;
2153       break;
2154     }
2155     /* Process the packet */
2156     if (!callback(cf, fdata, &pseudo_header, pd, callback_args)) {
2157       /* Callback failed.  We assume it reported the error appropriately. */
2158       ret = PSP_FAILED;
2159       break;
2160     }
2161   }
2162
2163   /* We're done printing the packets; destroy the progress bar if
2164      it was created. */
2165   if (progbar != NULL)
2166     destroy_progress_dlg(progbar);
2167
2168   return ret;
2169 }
2170
2171 typedef struct {
2172   gboolean construct_protocol_tree;
2173   column_info *cinfo;
2174 } retap_callback_args_t;
2175
2176 static gboolean
2177 retap_packet(capture_file *cf _U_, frame_data *fdata,
2178              union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2179              void *argsp)
2180 {
2181   retap_callback_args_t *args = argsp;
2182   epan_dissect_t edt;
2183
2184   epan_dissect_init(&edt, args->construct_protocol_tree, FALSE);
2185   tap_queue_init(&edt);
2186   epan_dissect_run(&edt, pseudo_header, pd, fdata, args->cinfo);
2187   tap_push_tapped_queue(&edt);
2188   epan_dissect_cleanup(&edt);
2189
2190   return TRUE;
2191 }
2192
2193 cf_read_status_t
2194 cf_retap_packets(capture_file *cf)
2195 {
2196   packet_range_t range;
2197   retap_callback_args_t callback_args;
2198   gboolean filtering_tap_listeners;
2199   guint tap_flags;
2200
2201   /* Do we have any tap listeners with filters? */
2202   filtering_tap_listeners = have_filtering_tap_listeners();
2203
2204   tap_flags = union_of_tap_listener_flags();
2205
2206   /* If any tap listeners have filters, or require the protocol tree,
2207      construct the protocol tree. */
2208   callback_args.construct_protocol_tree = filtering_tap_listeners ||
2209                                           (tap_flags & TL_REQUIRES_PROTO_TREE);
2210
2211   /* If any tap listeners require the columns, construct them. */
2212   callback_args.cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
2213
2214   /* Reset the tap listeners. */
2215   reset_tap_listeners();
2216
2217   /* Iterate through the list of packets, dissecting all packets and
2218      re-running the taps. */
2219   packet_range_init(&range);
2220   packet_range_process_init(&range);
2221   switch (process_specified_packets(cf, &range, "Recalculating statistics on",
2222                                     "all packets", TRUE, retap_packet,
2223                                     &callback_args)) {
2224   case PSP_FINISHED:
2225     /* Completed successfully. */
2226     return CF_READ_OK;
2227
2228   case PSP_STOPPED:
2229     /* Well, the user decided to abort the refiltering.
2230        Return CF_READ_ABORTED so our caller knows they did that. */
2231     return CF_READ_ABORTED;
2232
2233   case PSP_FAILED:
2234     /* Error while retapping. */
2235     return CF_READ_ERROR;
2236   }
2237
2238   g_assert_not_reached();
2239   return CF_READ_OK;
2240 }
2241
2242 typedef struct {
2243   print_args_t *print_args;
2244   gboolean      print_header_line;
2245   char         *header_line_buf;
2246   int           header_line_buf_len;
2247   gboolean      print_formfeed;
2248   gboolean      print_separator;
2249   char         *line_buf;
2250   int           line_buf_len;
2251   gint         *col_widths;
2252   int           num_visible_cols;
2253   gint         *visible_cols;
2254 } print_callback_args_t;
2255
2256 static gboolean
2257 print_packet(capture_file *cf, frame_data *fdata,
2258              union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2259              void *argsp)
2260 {
2261   print_callback_args_t *args = argsp;
2262   epan_dissect_t edt;
2263   int             i;
2264   char           *cp;
2265   int             line_len;
2266   int             column_len;
2267   int             cp_off;
2268   gboolean        proto_tree_needed;
2269   char            bookmark_name[9+10+1];    /* "__frameNNNNNNNNNN__\0" */
2270   char            bookmark_title[6+10+1];   /* "Frame NNNNNNNNNN__\0" */
2271
2272   /* Create the protocol tree, and make it visible, if we're printing
2273      the dissection or the hex data.
2274      XXX - do we need it if we're just printing the hex data? */
2275   proto_tree_needed =
2276       args->print_args->print_dissections != print_dissections_none || args->print_args->print_hex || have_custom_cols(&cf->cinfo);
2277   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2278
2279   /* Fill in the column information if we're printing the summary
2280      information. */
2281   if (args->print_args->print_summary) {
2282     col_custom_prime_edt(&edt, &cf->cinfo);
2283     epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
2284     epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
2285   } else
2286     epan_dissect_run(&edt, pseudo_header, pd, fdata, NULL);
2287
2288   if (args->print_formfeed) {
2289     if (!new_page(args->print_args->stream))
2290       goto fail;
2291   } else {
2292       if (args->print_separator) {
2293         if (!print_line(args->print_args->stream, 0, ""))
2294           goto fail;
2295       }
2296   }
2297
2298   /*
2299    * We generate bookmarks, if the output format supports them.
2300    * The name is "__frameN__".
2301    */
2302   g_snprintf(bookmark_name, sizeof bookmark_name, "__frame%u__", fdata->num);
2303
2304   if (args->print_args->print_summary) {
2305     if (args->print_header_line) {
2306       if (!print_line(args->print_args->stream, 0, args->header_line_buf))
2307         goto fail;
2308       args->print_header_line = FALSE;  /* we might not need to print any more */
2309     }
2310     cp = &args->line_buf[0];
2311     line_len = 0;
2312     for (i = 0; i < args->num_visible_cols; i++) {
2313       /* Find the length of the string for this column. */
2314       column_len = (int) strlen(cf->cinfo.col_data[args->visible_cols[i]]);
2315       if (args->col_widths[i] > column_len)
2316          column_len = args->col_widths[i];
2317
2318       /* Make sure there's room in the line buffer for the column; if not,
2319          double its length. */
2320       line_len += column_len + 1;   /* "+1" for space */
2321       if (line_len > args->line_buf_len) {
2322         cp_off = (int) (cp - args->line_buf);
2323         args->line_buf_len = 2 * line_len;
2324         args->line_buf = g_realloc(args->line_buf, args->line_buf_len + 1);
2325         cp = args->line_buf + cp_off;
2326       }
2327
2328       /* Right-justify the packet number column. */
2329       if (cf->cinfo.col_fmt[args->visible_cols[i]] == COL_NUMBER)
2330         g_snprintf(cp, column_len+1, "%*s", args->col_widths[i], cf->cinfo.col_data[args->visible_cols[i]]);
2331       else
2332         g_snprintf(cp, column_len+1, "%-*s", args->col_widths[i], cf->cinfo.col_data[args->visible_cols[i]]);
2333       cp += column_len;
2334       if (i != args->num_visible_cols - 1)
2335         *cp++ = ' ';
2336     }
2337     *cp = '\0';
2338
2339     /*
2340      * Generate a bookmark, using the summary line as the title.
2341      */
2342     if (!print_bookmark(args->print_args->stream, bookmark_name,
2343                         args->line_buf))
2344       goto fail;
2345
2346     if (!print_line(args->print_args->stream, 0, args->line_buf))
2347       goto fail;
2348   } else {
2349     /*
2350      * Generate a bookmark, using "Frame N" as the title, as we're not
2351      * printing the summary line.
2352      */
2353     g_snprintf(bookmark_title, sizeof bookmark_title, "Frame %u", fdata->num);
2354     if (!print_bookmark(args->print_args->stream, bookmark_name,
2355                         bookmark_title))
2356       goto fail;
2357   } /* if (print_summary) */
2358
2359   if (args->print_args->print_dissections != print_dissections_none) {
2360     if (args->print_args->print_summary) {
2361       /* Separate the summary line from the tree with a blank line. */
2362       if (!print_line(args->print_args->stream, 0, ""))
2363         goto fail;
2364     }
2365
2366     /* Print the information in that tree. */
2367     if (!proto_tree_print(args->print_args, &edt, args->print_args->stream))
2368       goto fail;
2369
2370     /* Print a blank line if we print anything after this (aka more than one packet). */
2371     args->print_separator = TRUE;
2372
2373     /* Print a header line if we print any more packet summaries */
2374     args->print_header_line = TRUE;
2375   }
2376
2377   if (args->print_args->print_hex) {
2378     /* Print the full packet data as hex. */
2379     if (!print_hex_data(args->print_args->stream, &edt))
2380       goto fail;
2381
2382     /* Print a blank line if we print anything after this (aka more than one packet). */
2383     args->print_separator = TRUE;
2384
2385     /* Print a header line if we print any more packet summaries */
2386     args->print_header_line = TRUE;
2387   } /* if (args->print_args->print_dissections != print_dissections_none) */
2388
2389   epan_dissect_cleanup(&edt);
2390
2391   /* do we want to have a formfeed between each packet from now on? */
2392   if(args->print_args->print_formfeed) {
2393     args->print_formfeed = TRUE;
2394   }
2395
2396   return TRUE;
2397
2398 fail:
2399   epan_dissect_cleanup(&edt);
2400   return FALSE;
2401 }
2402
2403 cf_print_status_t
2404 cf_print_packets(capture_file *cf, print_args_t *print_args)
2405 {
2406   print_callback_args_t callback_args;
2407   gint        data_width;
2408   char        *cp;
2409   int         i, cp_off, column_len, line_len;
2410   int         num_visible_col = 0, last_visible_col = 0, visible_col_count;
2411   psp_return_t ret;
2412   GList       *clp;
2413   fmt_data    *cfmt;
2414
2415   callback_args.print_args = print_args;
2416   callback_args.print_header_line = TRUE;
2417   callback_args.header_line_buf = NULL;
2418   callback_args.header_line_buf_len = 256;
2419   callback_args.print_formfeed = FALSE;
2420   callback_args.print_separator = FALSE;
2421   callback_args.line_buf = NULL;
2422   callback_args.line_buf_len = 256;
2423   callback_args.col_widths = NULL;
2424   callback_args.num_visible_cols = 0;
2425   callback_args.visible_cols = NULL;
2426
2427   if (!print_preamble(print_args->stream, cf->filename)) {
2428     destroy_print_stream(print_args->stream);
2429     return CF_PRINT_WRITE_ERROR;
2430   }
2431
2432   if (print_args->print_summary) {
2433     /* We're printing packet summaries.  Allocate the header line buffer
2434        and get the column widths. */
2435     callback_args.header_line_buf = g_malloc(callback_args.header_line_buf_len + 1);
2436
2437     /* Find the number of visible columns and the last visible column */
2438     for (i = 0; i < prefs.num_cols; i++) {
2439
2440         clp = g_list_nth(prefs.col_list, i);
2441         if (clp == NULL) /* Sanity check, Invalid column requested */
2442             continue;
2443
2444         cfmt = (fmt_data *) clp->data;
2445         if (cfmt->visible) {
2446             num_visible_col++;
2447             last_visible_col = i;
2448         }
2449     }
2450
2451     /* Find the widths for each of the columns - maximum of the
2452        width of the title and the width of the data - and construct
2453        a buffer with a line containing the column titles. */
2454     callback_args.num_visible_cols = num_visible_col;
2455     callback_args.col_widths = (gint *) g_malloc(sizeof(gint) * num_visible_col);
2456     callback_args.visible_cols = (gint *) g_malloc(sizeof(gint) * num_visible_col);
2457     cp = &callback_args.header_line_buf[0];
2458     line_len = 0;
2459     visible_col_count = 0;
2460     for (i = 0; i < cf->cinfo.num_cols; i++) {
2461
2462       clp = g_list_nth(prefs.col_list, i);
2463       if (clp == NULL) /* Sanity check, Invalid column requested */
2464           continue;
2465
2466       cfmt = (fmt_data *) clp->data;
2467       if (cfmt->visible == FALSE)
2468           continue;
2469
2470       /* Save the order of visible columns */
2471       callback_args.visible_cols[visible_col_count] = i;
2472
2473       /* Don't pad the last column. */
2474       if (i == last_visible_col)
2475         callback_args.col_widths[visible_col_count] = 0;
2476       else {
2477         callback_args.col_widths[visible_col_count] = (gint) strlen(cf->cinfo.col_title[i]);
2478         data_width = get_column_char_width(get_column_format(i));
2479         if (data_width > callback_args.col_widths[visible_col_count])
2480           callback_args.col_widths[visible_col_count] = data_width;
2481       }
2482
2483       /* Find the length of the string for this column. */
2484       column_len = (int) strlen(cf->cinfo.col_title[i]);
2485       if (callback_args.col_widths[i] > column_len)
2486         column_len = callback_args.col_widths[visible_col_count];
2487
2488       /* Make sure there's room in the line buffer for the column; if not,
2489          double its length. */
2490       line_len += column_len + 1;   /* "+1" for space */
2491       if (line_len > callback_args.header_line_buf_len) {
2492         cp_off = (int) (cp - callback_args.header_line_buf);
2493         callback_args.header_line_buf_len = 2 * line_len;
2494         callback_args.header_line_buf = g_realloc(callback_args.header_line_buf,
2495                                                   callback_args.header_line_buf_len + 1);
2496         cp = callback_args.header_line_buf + cp_off;
2497       }
2498
2499       /* Right-justify the packet number column. */
2500 /*      if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2501         g_snprintf(cp, column_len+1, "%*s", callback_args.col_widths[visible_col_count], cf->cinfo.col_title[i]);
2502       else*/
2503       g_snprintf(cp, column_len+1, "%-*s", callback_args.col_widths[visible_col_count], cf->cinfo.col_title[i]);
2504       cp += column_len;
2505       if (i != cf->cinfo.num_cols - 1)
2506         *cp++ = ' ';
2507
2508       visible_col_count++;
2509     }
2510     *cp = '\0';
2511
2512     /* Now start out the main line buffer with the same length as the
2513        header line buffer. */
2514     callback_args.line_buf_len = callback_args.header_line_buf_len;
2515     callback_args.line_buf = g_malloc(callback_args.line_buf_len + 1);
2516   } /* if (print_summary) */
2517
2518   /* Iterate through the list of packets, printing the packets we were
2519      told to print. */
2520   ret = process_specified_packets(cf, &print_args->range, "Printing",
2521                                   "selected packets", TRUE, print_packet,
2522                                   &callback_args);
2523
2524   g_free(callback_args.header_line_buf);
2525   g_free(callback_args.line_buf);
2526   g_free(callback_args.col_widths);
2527   g_free(callback_args.visible_cols);
2528
2529   switch (ret) {
2530
2531   case PSP_FINISHED:
2532     /* Completed successfully. */
2533     break;
2534
2535   case PSP_STOPPED:
2536     /* Well, the user decided to abort the printing.
2537
2538        XXX - note that what got generated before they did that
2539        will get printed if we're piping to a print program; we'd
2540        have to write to a file and then hand that to the print
2541        program to make it actually not print anything. */
2542     break;
2543
2544   case PSP_FAILED:
2545     /* Error while printing.
2546
2547        XXX - note that what got generated before they did that
2548        will get printed if we're piping to a print program; we'd
2549        have to write to a file and then hand that to the print
2550        program to make it actually not print anything. */
2551     destroy_print_stream(print_args->stream);
2552     return CF_PRINT_WRITE_ERROR;
2553   }
2554
2555   if (!print_finale(print_args->stream)) {
2556     destroy_print_stream(print_args->stream);
2557     return CF_PRINT_WRITE_ERROR;
2558   }
2559
2560   if (!destroy_print_stream(print_args->stream))
2561     return CF_PRINT_WRITE_ERROR;
2562
2563   return CF_PRINT_OK;
2564 }
2565
2566 static gboolean
2567 write_pdml_packet(capture_file *cf _U_, frame_data *fdata,
2568                   union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2569           void *argsp)
2570 {
2571   FILE *fh = argsp;
2572   epan_dissect_t edt;
2573
2574   /* Create the protocol tree, but don't fill in the column information. */
2575   epan_dissect_init(&edt, TRUE, TRUE);
2576   epan_dissect_run(&edt, pseudo_header, pd, fdata, NULL);
2577
2578   /* Write out the information in that tree. */
2579   proto_tree_write_pdml(&edt, fh);
2580
2581   epan_dissect_cleanup(&edt);
2582
2583   return !ferror(fh);
2584 }
2585
2586 cf_print_status_t
2587 cf_write_pdml_packets(capture_file *cf, print_args_t *print_args)
2588 {
2589   FILE        *fh;
2590   psp_return_t ret;
2591
2592   fh = ws_fopen(print_args->file, "w");
2593   if (fh == NULL)
2594     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2595
2596   write_pdml_preamble(fh, cf->filename);
2597   if (ferror(fh)) {
2598     fclose(fh);
2599     return CF_PRINT_WRITE_ERROR;
2600   }
2601
2602   /* Iterate through the list of packets, printing the packets we were
2603      told to print. */
2604   ret = process_specified_packets(cf, &print_args->range, "Writing PDML",
2605                                   "selected packets", TRUE,
2606                                   write_pdml_packet, fh);
2607
2608   switch (ret) {
2609
2610   case PSP_FINISHED:
2611     /* Completed successfully. */
2612     break;
2613
2614   case PSP_STOPPED:
2615     /* Well, the user decided to abort the printing. */
2616     break;
2617
2618   case PSP_FAILED:
2619     /* Error while printing. */
2620     fclose(fh);
2621     return CF_PRINT_WRITE_ERROR;
2622   }
2623
2624   write_pdml_finale(fh);
2625   if (ferror(fh)) {
2626     fclose(fh);
2627     return CF_PRINT_WRITE_ERROR;
2628   }
2629
2630   /* XXX - check for an error */
2631   fclose(fh);
2632
2633   return CF_PRINT_OK;
2634 }
2635
2636 static gboolean
2637 write_psml_packet(capture_file *cf, frame_data *fdata,
2638                   union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2639           void *argsp)
2640 {
2641   FILE *fh = argsp;
2642   epan_dissect_t edt;
2643   gboolean proto_tree_needed;
2644
2645   /* Fill in the column information, only create the protocol tree
2646      if having custom columns. */
2647   proto_tree_needed = have_custom_cols(&cf->cinfo);
2648   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2649   col_custom_prime_edt(&edt, &cf->cinfo);
2650   epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
2651   epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
2652
2653   /* Write out the information in that tree. */
2654   proto_tree_write_psml(&edt, fh);
2655
2656   epan_dissect_cleanup(&edt);
2657
2658   return !ferror(fh);
2659 }
2660
2661 cf_print_status_t
2662 cf_write_psml_packets(capture_file *cf, print_args_t *print_args)
2663 {
2664   FILE        *fh;
2665   psp_return_t ret;
2666
2667   fh = ws_fopen(print_args->file, "w");
2668   if (fh == NULL)
2669     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2670
2671   write_psml_preamble(fh);
2672   if (ferror(fh)) {
2673     fclose(fh);
2674     return CF_PRINT_WRITE_ERROR;
2675   }
2676
2677   /* Iterate through the list of packets, printing the packets we were
2678      told to print. */
2679   ret = process_specified_packets(cf, &print_args->range, "Writing PSML",
2680                                   "selected packets", TRUE,
2681                                   write_psml_packet, fh);
2682
2683   switch (ret) {
2684
2685   case PSP_FINISHED:
2686     /* Completed successfully. */
2687     break;
2688
2689   case PSP_STOPPED:
2690     /* Well, the user decided to abort the printing. */
2691     break;
2692
2693   case PSP_FAILED:
2694     /* Error while printing. */
2695     fclose(fh);
2696     return CF_PRINT_WRITE_ERROR;
2697   }
2698
2699   write_psml_finale(fh);
2700   if (ferror(fh)) {
2701     fclose(fh);
2702     return CF_PRINT_WRITE_ERROR;
2703   }
2704
2705   /* XXX - check for an error */
2706   fclose(fh);
2707
2708   return CF_PRINT_OK;
2709 }
2710
2711 static gboolean
2712 write_csv_packet(capture_file *cf, frame_data *fdata,
2713                  union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2714                  void *argsp)
2715 {
2716   FILE *fh = argsp;
2717   epan_dissect_t edt;
2718   gboolean proto_tree_needed;
2719
2720   /* Fill in the column information, only create the protocol tree
2721      if having custom columns. */
2722   proto_tree_needed = have_custom_cols(&cf->cinfo);
2723   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2724   col_custom_prime_edt(&edt, &cf->cinfo);
2725   epan_dissect_run(&edt, pseudo_header, pd, fdata, &cf->cinfo);
2726   epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
2727
2728   /* Write out the information in that tree. */
2729   proto_tree_write_csv(&edt, fh);
2730
2731   epan_dissect_cleanup(&edt);
2732
2733   return !ferror(fh);
2734 }
2735
2736 cf_print_status_t
2737 cf_write_csv_packets(capture_file *cf, print_args_t *print_args)
2738 {
2739   FILE        *fh;
2740   psp_return_t ret;
2741
2742   fh = ws_fopen(print_args->file, "w");
2743   if (fh == NULL)
2744     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2745
2746   write_csv_preamble(fh);
2747   if (ferror(fh)) {
2748     fclose(fh);
2749     return CF_PRINT_WRITE_ERROR;
2750   }
2751
2752   /* Iterate through the list of packets, printing the packets we were
2753      told to print. */
2754   ret = process_specified_packets(cf, &print_args->range, "Writing CSV",
2755                                   "selected packets", TRUE,
2756                                   write_csv_packet, fh);
2757
2758   switch (ret) {
2759
2760   case PSP_FINISHED:
2761     /* Completed successfully. */
2762     break;
2763
2764   case PSP_STOPPED:
2765     /* Well, the user decided to abort the printing. */
2766     break;
2767
2768   case PSP_FAILED:
2769     /* Error while printing. */
2770     fclose(fh);
2771     return CF_PRINT_WRITE_ERROR;
2772   }
2773
2774   write_csv_finale(fh);
2775   if (ferror(fh)) {
2776     fclose(fh);
2777     return CF_PRINT_WRITE_ERROR;
2778   }
2779
2780   /* XXX - check for an error */
2781   fclose(fh);
2782
2783   return CF_PRINT_OK;
2784 }
2785
2786 static gboolean
2787 write_carrays_packet(capture_file *cf _U_, frame_data *fdata,
2788              union wtap_pseudo_header *pseudo_header,
2789              const guint8 *pd, void *argsp)
2790 {
2791   FILE *fh = argsp;
2792   epan_dissect_t edt;
2793
2794   epan_dissect_init(&edt, TRUE, TRUE);
2795   epan_dissect_run(&edt, pseudo_header, pd, fdata, NULL);
2796   proto_tree_write_carrays(fdata->num, fh, &edt);
2797   epan_dissect_cleanup(&edt);
2798
2799   return !ferror(fh);
2800 }
2801
2802 cf_print_status_t
2803 cf_write_carrays_packets(capture_file *cf, print_args_t *print_args)
2804 {
2805   FILE        *fh;
2806   psp_return_t ret;
2807
2808   fh = ws_fopen(print_args->file, "w");
2809
2810   if (fh == NULL)
2811     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2812
2813   write_carrays_preamble(fh);
2814
2815   if (ferror(fh)) {
2816     fclose(fh);
2817     return CF_PRINT_WRITE_ERROR;
2818   }
2819
2820   /* Iterate through the list of packets, printing the packets we were
2821      told to print. */
2822   ret = process_specified_packets(cf, &print_args->range,
2823                   "Writing C Arrays",
2824                   "selected packets", TRUE,
2825                                   write_carrays_packet, fh);
2826   switch (ret) {
2827   case PSP_FINISHED:
2828     /* Completed successfully. */
2829     break;
2830   case PSP_STOPPED:
2831     /* Well, the user decided to abort the printing. */
2832     break;
2833   case PSP_FAILED:
2834     /* Error while printing. */
2835     fclose(fh);
2836     return CF_PRINT_WRITE_ERROR;
2837   }
2838
2839   write_carrays_finale(fh);
2840
2841   if (ferror(fh)) {
2842     fclose(fh);
2843     return CF_PRINT_WRITE_ERROR;
2844   }
2845
2846   fclose(fh);
2847   return CF_PRINT_OK;
2848 }
2849
2850 gboolean
2851 cf_find_packet_protocol_tree(capture_file *cf, const char *string,
2852                              search_direction dir)
2853 {
2854   match_data        mdata;
2855
2856   mdata.string = string;
2857   mdata.string_len = strlen(string);
2858   return find_packet(cf, match_protocol_tree, &mdata, dir);
2859 }
2860
2861 gboolean
2862 cf_find_string_protocol_tree(capture_file *cf, proto_tree *tree,  match_data *mdata)
2863 {
2864   mdata->frame_matched = FALSE;
2865   mdata->string = convert_string_case(cf->sfilter, cf->case_type);
2866   mdata->string_len = strlen(mdata->string);
2867   mdata->cf = cf;
2868   /* Iterate through all the nodes looking for matching text */
2869   proto_tree_children_foreach(tree, match_subtree_text, mdata);
2870   return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
2871 }
2872
2873 static match_result
2874 match_protocol_tree(capture_file *cf, frame_data *fdata, void *criterion)
2875 {
2876   match_data        *mdata = criterion;
2877   epan_dissect_t    edt;
2878
2879   /* Load the frame's data. */
2880   if (!cf_read_frame(cf, fdata)) {
2881     /* Attempt to get the packet failed. */
2882     return MR_ERROR;
2883   }
2884
2885   /* Construct the protocol tree, including the displayed text */
2886   epan_dissect_init(&edt, TRUE, TRUE);
2887   /* We don't need the column information */
2888   epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, NULL);
2889
2890   /* Iterate through all the nodes, seeing if they have text that matches. */
2891   mdata->cf = cf;
2892   mdata->frame_matched = FALSE;
2893   proto_tree_children_foreach(edt.tree, match_subtree_text, mdata);
2894   epan_dissect_cleanup(&edt);
2895   return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
2896 }
2897
2898 static void
2899 match_subtree_text(proto_node *node, gpointer data)
2900 {
2901   match_data    *mdata = (match_data *) data;
2902   const gchar   *string = mdata->string;
2903   size_t        string_len = mdata->string_len;
2904   capture_file  *cf = mdata->cf;
2905   field_info    *fi = PNODE_FINFO(node);
2906   gchar         label_str[ITEM_LABEL_LENGTH];
2907   gchar         *label_ptr;
2908   size_t        label_len;
2909   guint32       i;
2910   guint8        c_char;
2911   size_t        c_match = 0;
2912
2913   g_assert(fi && "dissection with an invisible proto tree?");
2914
2915   if (mdata->frame_matched) {
2916     /* We already had a match; don't bother doing any more work. */
2917     return;
2918   }
2919
2920   /* Don't match invisible entries. */
2921   if (PROTO_ITEM_IS_HIDDEN(node))
2922     return;
2923
2924   /* was a free format label produced? */
2925   if (fi->rep) {
2926     label_ptr = fi->rep->representation;
2927   } else {
2928     /* no, make a generic label */
2929     label_ptr = label_str;
2930     proto_item_fill_label(fi, label_str);
2931   }
2932
2933   /* Does that label match? */
2934   label_len = strlen(label_ptr);
2935   for (i = 0; i < label_len; i++) {
2936     c_char = label_ptr[i];
2937     if (cf->case_type)
2938       c_char = toupper(c_char);
2939     if (c_char == string[c_match]) {
2940       c_match++;
2941       if (c_match == string_len) {
2942         /* No need to look further; we have a match */
2943         mdata->frame_matched = TRUE;
2944         mdata->finfo = fi;
2945         return;
2946       }
2947     } else
2948       c_match = 0;
2949   }
2950
2951   /* Recurse into the subtree, if it exists */
2952   if (node->first_child != NULL)
2953     proto_tree_children_foreach(node, match_subtree_text, mdata);
2954 }
2955
2956 gboolean
2957 cf_find_packet_summary_line(capture_file *cf, const char *string,
2958                             search_direction dir)
2959 {
2960   match_data        mdata;
2961
2962   mdata.string = string;
2963   mdata.string_len = strlen(string);
2964   return find_packet(cf, match_summary_line, &mdata, dir);
2965 }
2966
2967 static match_result
2968 match_summary_line(capture_file *cf, frame_data *fdata, void *criterion)
2969 {
2970   match_data        *mdata = criterion;
2971   const gchar       *string = mdata->string;
2972   size_t            string_len = mdata->string_len;
2973   epan_dissect_t    edt;
2974   const char        *info_column;
2975   size_t            info_column_len;
2976   match_result      result = MR_NOTMATCHED;
2977   gint              colx;
2978   guint32           i;
2979   guint8            c_char;
2980   size_t            c_match = 0;
2981
2982   /* Load the frame's data. */
2983   if (!cf_read_frame(cf, fdata)) {
2984     /* Attempt to get the packet failed. */
2985     return MR_ERROR;
2986   }
2987
2988   /* Don't bother constructing the protocol tree */
2989   epan_dissect_init(&edt, FALSE, FALSE);
2990   /* Get the column information */
2991   epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, &cf->cinfo);
2992
2993   /* Find the Info column */
2994   for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
2995     if (cf->cinfo.fmt_matx[colx][COL_INFO]) {
2996       /* Found it.  See if we match. */
2997       info_column = edt.pi.cinfo->col_data[colx];
2998       info_column_len = strlen(info_column);
2999       for (i = 0; i < info_column_len; i++) {
3000         c_char = info_column[i];
3001         if (cf->case_type)
3002           c_char = toupper(c_char);
3003         if (c_char == string[c_match]) {
3004           c_match++;
3005           if (c_match == string_len) {
3006             result = MR_MATCHED;
3007             break;
3008           }
3009         } else
3010           c_match = 0;
3011       }
3012       break;
3013     }
3014   }
3015   epan_dissect_cleanup(&edt);
3016   return result;
3017 }
3018
3019 typedef struct {
3020     const guint8 *data;
3021     size_t data_len;
3022 } cbs_t;    /* "Counted byte string" */
3023
3024 gboolean
3025 cf_find_packet_data(capture_file *cf, const guint8 *string, size_t string_size,
3026                     search_direction dir)
3027 {
3028   cbs_t info;
3029
3030   info.data = string;
3031   info.data_len = string_size;
3032
3033   /* String or hex search? */
3034   if (cf->string) {
3035     /* String search - what type of string? */
3036     switch (cf->scs_type) {
3037
3038     case SCS_ASCII_AND_UNICODE:
3039       return find_packet(cf, match_ascii_and_unicode, &info, dir);
3040
3041     case SCS_ASCII:
3042       return find_packet(cf, match_ascii, &info, dir);
3043
3044     case SCS_UNICODE:
3045       return find_packet(cf, match_unicode, &info, dir);
3046
3047     default:
3048       g_assert_not_reached();
3049       return FALSE;
3050     }
3051   } else
3052     return find_packet(cf, match_binary, &info, dir);
3053 }
3054
3055 static match_result
3056 match_ascii_and_unicode(capture_file *cf, frame_data *fdata, void *criterion)
3057 {
3058   cbs_t        *info = criterion;
3059   const guint8 *ascii_text = info->data;
3060   size_t       textlen = info->data_len;
3061   match_result result;
3062   guint32      buf_len;
3063   guint32      i;
3064   guint8       c_char;
3065   size_t       c_match = 0;
3066
3067   /* Load the frame's data. */
3068   if (!cf_read_frame(cf, fdata)) {
3069     /* Attempt to get the packet failed. */
3070     return MR_ERROR;
3071   }
3072
3073   result = MR_NOTMATCHED;
3074   buf_len = fdata->pkt_len;
3075   i = 0;
3076   while (i < buf_len) {
3077     c_char = cf->pd[i];
3078     if (cf->case_type)
3079       c_char = toupper(c_char);
3080     if (c_char != '\0') {
3081       if (c_char == ascii_text[c_match]) {
3082         c_match += 1;
3083         if (c_match == textlen) {
3084           result = MR_MATCHED;
3085           cf->search_pos = i; /* Save the position of the last character
3086                                  for highlighting the field. */
3087           break;
3088         }
3089       }
3090       else {
3091         g_assert(i>=c_match);
3092         i -= (guint32)c_match;
3093         c_match = 0;
3094       }
3095     }
3096     i += 1;
3097   }
3098   return result;
3099 }
3100
3101 static match_result
3102 match_ascii(capture_file *cf, frame_data *fdata, void *criterion)
3103 {
3104   cbs_t        *info = criterion;
3105   const guint8 *ascii_text = info->data;
3106   size_t       textlen = info->data_len;
3107   match_result result;
3108   guint32      buf_len;
3109   guint32      i;
3110   guint8       c_char;
3111   size_t       c_match = 0;
3112
3113   /* Load the frame's data. */
3114   if (!cf_read_frame(cf, fdata)) {
3115     /* Attempt to get the packet failed. */
3116     return MR_ERROR;
3117   }
3118
3119   result = MR_NOTMATCHED;
3120   buf_len = fdata->pkt_len;
3121   i = 0;
3122   while (i < buf_len) {
3123     c_char = cf->pd[i];
3124     if (cf->case_type)
3125       c_char = toupper(c_char);
3126     if (c_char == ascii_text[c_match]) {
3127       c_match += 1;
3128       if (c_match == textlen) {
3129         result = MR_MATCHED;
3130         cf->search_pos = i; /* Save the position of the last character
3131                                for highlighting the field. */
3132         break;
3133       }
3134     }
3135     else {
3136       g_assert(i>=c_match);
3137       i -= (guint32)c_match;
3138       c_match = 0;
3139     }
3140     i += 1;
3141   }
3142
3143   return result;
3144 }
3145
3146 static match_result
3147 match_unicode(capture_file *cf, frame_data *fdata, void *criterion)
3148 {
3149   cbs_t        *info = criterion;
3150   const guint8 *ascii_text = info->data;
3151   size_t       textlen = info->data_len;
3152   match_result result;
3153   guint32      buf_len;
3154   guint32      i;
3155   guint8       c_char;
3156   size_t       c_match = 0;
3157
3158   /* Load the frame's data. */
3159   if (!cf_read_frame(cf, fdata)) {
3160     /* Attempt to get the packet failed. */
3161     return MR_ERROR;
3162   }
3163
3164   result = MR_NOTMATCHED;
3165   buf_len = fdata->pkt_len;
3166   i = 0;
3167   while (i < buf_len) {
3168     c_char = cf->pd[i];
3169     if (cf->case_type)
3170       c_char = toupper(c_char);
3171     if (c_char == ascii_text[c_match]) {
3172       c_match += 1;
3173       if (c_match == textlen) {
3174         result = MR_MATCHED;
3175         cf->search_pos = i; /* Save the position of the last character
3176                                for highlighting the field. */
3177         break;
3178       }
3179       i += 1;
3180     }
3181     else {
3182       g_assert(i>=(c_match*2));
3183       i -= (guint32)c_match*2;
3184       c_match = 0;
3185     }
3186     i += 1;
3187   }
3188   return result;
3189 }
3190
3191 static match_result
3192 match_binary(capture_file *cf, frame_data *fdata, void *criterion)
3193 {
3194   cbs_t        *info = criterion;
3195   const guint8 *binary_data = info->data;
3196   size_t       datalen = info->data_len;
3197   match_result result;
3198   guint32      buf_len;
3199   guint32      i;
3200   size_t       c_match = 0;
3201
3202   /* Load the frame's data. */
3203   if (!cf_read_frame(cf, fdata)) {
3204     /* Attempt to get the packet failed. */
3205     return MR_ERROR;
3206   }
3207
3208   result = MR_NOTMATCHED;
3209   buf_len = fdata->pkt_len;
3210   i = 0;
3211   while (i < buf_len) {
3212     if (cf->pd[i] == binary_data[c_match]) {
3213       c_match += 1;
3214       if (c_match == datalen) {
3215         result = MR_MATCHED;
3216         cf->search_pos = i; /* Save the position of the last character
3217                                for highlighting the field. */
3218         break;
3219       }
3220     }
3221     else {
3222       g_assert(i>=c_match);
3223       i -= (guint32)c_match;
3224       c_match = 0;
3225     }
3226     i += 1;
3227   }
3228   return result;
3229 }
3230
3231 gboolean
3232 cf_find_packet_dfilter(capture_file *cf, dfilter_t *sfcode,
3233                        search_direction dir)
3234 {
3235   return find_packet(cf, match_dfilter, sfcode, dir);
3236 }
3237
3238 gboolean
3239 cf_find_packet_dfilter_string(capture_file *cf, const char *filter,
3240                               search_direction dir)
3241 {
3242   dfilter_t *sfcode;
3243   gboolean result;
3244
3245   if (!dfilter_compile(filter, &sfcode)) {
3246      /*
3247       * XXX - this shouldn't happen, as the filter string is machine
3248       * generated
3249       */
3250     return FALSE;
3251   }
3252   if (sfcode == NULL) {
3253     /*
3254      * XXX - this shouldn't happen, as the filter string is machine
3255      * generated.
3256      */
3257     return FALSE;
3258   }
3259   result = find_packet(cf, match_dfilter, sfcode, dir);
3260   dfilter_free(sfcode);
3261   return result;
3262 }
3263
3264 static match_result
3265 match_dfilter(capture_file *cf, frame_data *fdata, void *criterion)
3266 {
3267   dfilter_t      *sfcode = criterion;
3268   epan_dissect_t edt;
3269   match_result   result;
3270
3271   /* Load the frame's data. */
3272   if (!cf_read_frame(cf, fdata)) {
3273     /* Attempt to get the packet failed. */
3274     return MR_ERROR;
3275   }
3276
3277   epan_dissect_init(&edt, TRUE, FALSE);
3278   epan_dissect_prime_dfilter(&edt, sfcode);
3279   epan_dissect_run(&edt, &cf->pseudo_header, cf->pd, fdata, NULL);
3280   result = dfilter_apply_edt(sfcode, &edt) ? MR_MATCHED : MR_NOTMATCHED;
3281   epan_dissect_cleanup(&edt);
3282   return result;
3283 }
3284
3285 gboolean
3286 cf_find_packet_marked(capture_file *cf, search_direction dir)
3287 {
3288   return find_packet(cf, match_marked, NULL, dir);
3289 }
3290
3291 static match_result
3292 match_marked(capture_file *cf _U_, frame_data *fdata, void *criterion _U_)
3293 {
3294   return fdata->flags.marked ? MR_MATCHED : MR_NOTMATCHED;
3295 }
3296
3297 gboolean
3298 cf_find_packet_time_reference(capture_file *cf, search_direction dir)
3299 {
3300   return find_packet(cf, match_time_reference, NULL, dir);
3301 }
3302
3303 static match_result
3304 match_time_reference(capture_file *cf _U_, frame_data *fdata, void *criterion _U_)
3305 {
3306   return fdata->flags.ref_time ? MR_MATCHED : MR_NOTMATCHED;
3307 }
3308
3309 static gboolean
3310 find_packet(capture_file *cf,
3311             match_result (*match_function)(capture_file *, frame_data *, void *),
3312             void *criterion, search_direction dir)
3313 {
3314   frame_data  *start_fd;
3315   guint32      framenum;
3316   frame_data  *fdata;
3317   frame_data  *new_fd = NULL;
3318   progdlg_t   *progbar = NULL;
3319   gboolean     stop_flag;
3320   int          count;
3321   gboolean     found;
3322   float        progbar_val;
3323   GTimeVal     start_time;
3324   gchar        status_str[100];
3325   int          progbar_nextstep;
3326   int          progbar_quantum;
3327   const char  *title;
3328   match_result result;
3329
3330   start_fd = cf->current_frame;
3331   if (start_fd != NULL)  {
3332     /* Iterate through the list of packets, starting at the packet we've
3333        picked, calling a routine to run the filter on the packet, see if
3334        it matches, and stop if so.  */
3335     count = 0;
3336     framenum = start_fd->num;
3337
3338     /* Update the progress bar when it gets to this value. */
3339     progbar_nextstep = 0;
3340     /* When we reach the value that triggers a progress bar update,
3341        bump that value by this amount. */
3342     progbar_quantum = cf->count/N_PROGBAR_UPDATES;
3343     /* Progress so far. */
3344     progbar_val = 0.0f;
3345
3346     stop_flag = FALSE;
3347     g_get_current_time(&start_time);
3348
3349     title = cf->sfilter?cf->sfilter:"";
3350     for (;;) {
3351       /* Create the progress bar if necessary.
3352          We check on every iteration of the loop, so that it takes no
3353          longer than the standard time to create it (otherwise, for a
3354          large file, we might take considerably longer than that standard
3355          time in order to get to the next progress bar step). */
3356       if (progbar == NULL)
3357          progbar = delayed_create_progress_dlg(cf->window, "Searching", title,
3358            FALSE, &stop_flag, &start_time, progbar_val);
3359
3360       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
3361          when we update it, we have to run the GTK+ main loop to get it
3362          to repaint what's pending, and doing so may involve an "ioctl()"
3363          to see if there's any pending input from an X server, and doing
3364          that for every packet can be costly, especially on a big file. */
3365       if (count >= progbar_nextstep) {
3366         /* let's not divide by zero. I should never be started
3367          * with count == 0, so let's assert that
3368          */
3369         g_assert(cf->count > 0);
3370
3371         progbar_val = (gfloat) count / cf->count;
3372
3373         if (progbar != NULL) {
3374           g_snprintf(status_str, sizeof(status_str),
3375                      "%4u of %u packets", count, cf->count);
3376           update_progress_dlg(progbar, progbar_val, status_str);
3377         }
3378
3379         progbar_nextstep += progbar_quantum;
3380       }
3381
3382       if (stop_flag) {
3383         /* Well, the user decided to abort the search.  Go back to the
3384            frame where we started. */
3385         new_fd = start_fd;
3386         break;
3387       }
3388
3389       /* Go past the current frame. */
3390       if (dir == SD_BACKWARD) {
3391         /* Go on to the previous frame. */
3392         if (framenum == 1) {
3393           /*
3394            * XXX - other apps have a bit more of a detailed message
3395            * for this, and instead of offering "OK" and "Cancel",
3396            * they offer things such as "Continue" and "Cancel";
3397            * we need an API for popping up alert boxes with
3398            * {Verb} and "Cancel".
3399            */
3400
3401           if (prefs.gui_find_wrap)
3402           {
3403               statusbar_push_temporary_msg("Search reached the beginning. Continuing at end.");
3404               framenum = cf->count;     /* wrap around */
3405           }
3406           else
3407           {
3408               statusbar_push_temporary_msg("Search reached the beginning.");
3409               framenum = start_fd->num; /* stay on previous packet */
3410           }
3411         } else
3412           framenum--;
3413       } else {
3414         /* Go on to the next frame. */
3415         if (framenum == cf->count) {
3416           if (prefs.gui_find_wrap)
3417           {
3418               statusbar_push_temporary_msg("Search reached the end. Continuing at beginning.");
3419               framenum = 1;             /* wrap around */
3420           }
3421           else
3422           {
3423               statusbar_push_temporary_msg("Search reached the end.");
3424               framenum = start_fd->num; /* stay on previous packet */
3425           }
3426         } else
3427           framenum++;
3428       }
3429       fdata = frame_data_sequence_find(cf->frames, framenum);
3430
3431       count++;
3432
3433       /* Is this packet in the display? */
3434       if (fdata->flags.passed_dfilter) {
3435         /* Yes.  Does it match the search criterion? */
3436         result = (*match_function)(cf, fdata, criterion);
3437         if (result == MR_ERROR) {
3438           /* Error; our caller has reported the error.  Go back to the frame
3439              where we started. */
3440           new_fd = start_fd;
3441           break;
3442         } else if (result == MR_MATCHED) {
3443           /* Yes.  Go to the new frame. */
3444           new_fd = fdata;
3445           break;
3446         }
3447       }
3448
3449       if (fdata == start_fd) {
3450         /* We're back to the frame we were on originally, and that frame
3451            doesn't match the search filter.  The search failed. */
3452         break;
3453       }
3454     }
3455
3456     /* We're done scanning the packets; destroy the progress bar if it
3457        was created. */
3458     if (progbar != NULL)
3459       destroy_progress_dlg(progbar);
3460   }
3461
3462   if (new_fd != NULL) {
3463     /* Find and select */
3464     cf->search_in_progress = TRUE;
3465     found = new_packet_list_select_row_from_data(new_fd);
3466     cf->search_in_progress = FALSE;
3467     cf->search_pos = 0; /* Reset the position */
3468     if (!found) {
3469       /* We didn't find a row corresponding to this frame.
3470          This means that the frame isn't being displayed currently,
3471          so we can't select it. */
3472       simple_message_box(ESD_TYPE_INFO, NULL,
3473                          "The capture file is probably not fully dissected.",
3474                          "End of capture exceeded!");
3475       return FALSE;
3476     }
3477     return TRUE;    /* success */
3478   } else
3479     return FALSE;   /* failure */
3480 }
3481
3482 gboolean
3483 cf_goto_frame(capture_file *cf, guint fnumber)
3484 {
3485   frame_data *fdata;
3486
3487   fdata = frame_data_sequence_find(cf->frames, fnumber);
3488
3489   if (fdata == NULL) {
3490     /* we didn't find a packet with that packet number */
3491     statusbar_push_temporary_msg("There is no packet number %u.", fnumber);
3492     return FALSE;   /* we failed to go to that packet */
3493   }
3494   if (!fdata->flags.passed_dfilter) {
3495     /* that packet currently isn't displayed */
3496     /* XXX - add it to the set of displayed packets? */
3497     statusbar_push_temporary_msg("Packet number %u isn't displayed.", fnumber);
3498     return FALSE;   /* we failed to go to that packet */
3499   }
3500
3501   if (!new_packet_list_select_row_from_data(fdata)) {
3502     /* We didn't find a row corresponding to this frame.
3503        This means that the frame isn't being displayed currently,
3504        so we can't select it. */
3505     simple_message_box(ESD_TYPE_INFO, NULL,
3506                        "The capture file is probably not fully dissected.",
3507                        "End of capture exceeded!");
3508     return FALSE;
3509   }
3510   return TRUE;  /* we got to that packet */
3511 }
3512
3513 gboolean
3514 cf_goto_top_frame(void)
3515 {
3516   /* Find and select */
3517   new_packet_list_select_first_row();
3518   return TRUE;  /* we got to that packet */
3519 }
3520
3521 gboolean
3522 cf_goto_bottom_frame(void)
3523 {
3524   /* Find and select */
3525   new_packet_list_select_last_row();
3526   return TRUE;  /* we got to that packet */
3527 }
3528
3529 /*
3530  * Go to frame specified by currently selected protocol tree item.
3531  */
3532 gboolean
3533 cf_goto_framenum(capture_file *cf)
3534 {
3535   header_field_info       *hfinfo;
3536   guint32                 framenum;
3537
3538   if (cf->finfo_selected) {
3539     hfinfo = cf->finfo_selected->hfinfo;
3540     g_assert(hfinfo);
3541     if (hfinfo->type == FT_FRAMENUM) {
3542       framenum = fvalue_get_uinteger(&cf->finfo_selected->value);
3543       if (framenum != 0)
3544         return cf_goto_frame(cf, framenum);
3545       }
3546   }
3547
3548   return FALSE;
3549 }
3550
3551 /* Select the packet on a given row. */
3552 void
3553 cf_select_packet(capture_file *cf, int row)
3554 {
3555   epan_dissect_t *old_edt;
3556   frame_data *fdata;
3557
3558   /* Get the frame data struct pointer for this frame */
3559   fdata = new_packet_list_get_row_data(row);
3560
3561   if (fdata == NULL) {
3562     /* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
3563        the first entry is added to it by "real_insert_row()", that row
3564        is selected (see "real_insert_row()", in "ui/gtk/gtkclist.c", in both
3565        our version and the vanilla GTK+ version).
3566
3567        This means that a "select-row" signal is emitted; this causes
3568        "packet_list_select_cb()" to be called, which causes "cf_select_packet()"
3569        to be called.
3570
3571        "cf_select_packet()" fetches, above, the data associated with the
3572        row that was selected; however, as "gtk_clist_append()", which
3573        called "real_insert_row()", hasn't yet returned, we haven't yet
3574        associated any data with that row, so we get back a null pointer.
3575
3576        We can't assume that there's only one frame in the frame list,
3577        either, as we may be filtering the display.
3578
3579        We therefore assume that, if "row" is 0, i.e. the first row
3580        is being selected, and "cf->first_displayed" equals
3581        "cf->last_displayed", i.e. there's only one frame being
3582        displayed, that frame is the frame we want.
3583
3584        This means we have to set "cf->first_displayed" and
3585        "cf->last_displayed" before adding the row to the
3586        GtkCList; see the comment in "add_packet_to_packet_list()". */
3587
3588        if (row == 0 && cf->first_displayed == cf->last_displayed)
3589          fdata = frame_data_sequence_find(cf->frames, cf->first_displayed);
3590   }
3591
3592   /* If fdata _still_ isn't set simply give up. */
3593   if (fdata == NULL) {
3594     return;
3595   }
3596
3597   /* Get the data in that frame. */
3598   if (!cf_read_frame (cf, fdata)) {
3599     return;
3600   }
3601
3602   /* Record that this frame is the current frame. */
3603   cf->current_frame = fdata;
3604   cf->current_row = row;
3605
3606   old_edt = cf->edt;
3607   /* Create the logical protocol tree. */
3608   /* We don't need the columns here. */
3609   cf->edt = epan_dissect_new(TRUE, TRUE);
3610
3611   tap_build_interesting(cf->edt);
3612   epan_dissect_run(cf->edt, &cf->pseudo_header, cf->pd, cf->current_frame,
3613           NULL);
3614
3615   dfilter_macro_build_ftv_cache(cf->edt->tree);
3616
3617   cf_callback_invoke(cf_cb_packet_selected, cf);
3618
3619   if (old_edt != NULL)
3620     epan_dissect_free(old_edt);
3621
3622 }
3623
3624 /* Unselect the selected packet, if any. */
3625 void
3626 cf_unselect_packet(capture_file *cf)
3627 {
3628   epan_dissect_t *old_edt = cf->edt;
3629
3630   cf->edt = NULL;
3631
3632   /* No packet is selected. */
3633   cf->current_frame = NULL;
3634   cf->current_row = 0;
3635
3636   cf_callback_invoke(cf_cb_packet_unselected, cf);
3637
3638   /* No protocol tree means no selected field. */
3639   cf_unselect_field(cf);
3640
3641   /* Destroy the epan_dissect_t for the unselected packet. */
3642   if (old_edt != NULL)
3643     epan_dissect_free(old_edt);
3644 }
3645
3646 /* Unset the selected protocol tree field, if any. */
3647 void
3648 cf_unselect_field(capture_file *cf)
3649 {
3650   cf->finfo_selected = NULL;
3651
3652   cf_callback_invoke(cf_cb_field_unselected, cf);
3653 }
3654
3655 /*
3656  * Mark a particular frame.
3657  */
3658 void
3659 cf_mark_frame(capture_file *cf, frame_data *frame)
3660 {
3661   if (! frame->flags.marked) {
3662     frame->flags.marked = TRUE;
3663     if (cf->count > cf->marked_count)
3664       cf->marked_count++;
3665   }
3666 }
3667
3668 /*
3669  * Unmark a particular frame.
3670  */
3671 void
3672 cf_unmark_frame(capture_file *cf, frame_data *frame)
3673 {
3674   if (frame->flags.marked) {
3675     frame->flags.marked = FALSE;
3676     if (cf->marked_count > 0)
3677       cf->marked_count--;
3678   }
3679 }
3680
3681 /*
3682  * Ignore a particular frame.
3683  */
3684 void
3685 cf_ignore_frame(capture_file *cf, frame_data *frame)
3686 {
3687   if (! frame->flags.ignored) {
3688     frame->flags.ignored = TRUE;
3689     if (cf->count > cf->ignored_count)
3690       cf->ignored_count++;
3691   }
3692 }
3693
3694 /*
3695  * Un-ignore a particular frame.
3696  */
3697 void
3698 cf_unignore_frame(capture_file *cf, frame_data *frame)
3699 {
3700   if (frame->flags.ignored) {
3701     frame->flags.ignored = FALSE;
3702     if (cf->ignored_count > 0)
3703       cf->ignored_count--;
3704   }
3705 }
3706
3707 /*
3708  * Read the comment in SHB block
3709  */
3710
3711 const gchar *
3712 cf_read_shb_comment(capture_file *cf)
3713 {
3714   wtapng_section_t *shb_inf;
3715   const gchar *temp_str;
3716
3717   /* Get info from SHB */
3718   shb_inf = wtap_file_get_shb_info(cf->wth);
3719   if(shb_inf == NULL)
3720         return NULL;
3721   temp_str = shb_inf->opt_comment;
3722   g_free(shb_inf);
3723
3724   return temp_str;
3725
3726 }
3727
3728 void
3729 cf_update_capture_comment(capture_file *cf, gchar *comment)
3730 {
3731   wtapng_section_t *shb_inf;
3732
3733   /* Get info from SHB */
3734   shb_inf = wtap_file_get_shb_info(cf->wth);
3735
3736   /* See if the comment has changed or not */
3737   if (shb_inf && shb_inf->opt_comment) {
3738     if (strcmp(shb_inf->opt_comment, comment) == 0) {
3739       g_free(comment);
3740       g_free(shb_inf);
3741       return;
3742     }
3743   }
3744
3745   g_free(shb_inf);
3746
3747   /* The comment has changed, let's update it */
3748   wtap_write_shb_comment(cf->wth, comment);
3749   /* Mark the file as having unsaved changes */
3750   cf->unsaved_changes = TRUE;
3751 }
3752
3753 void
3754 cf_update_packet_comment(capture_file *cf, frame_data *fdata, gchar *comment)
3755 {
3756   if (fdata->opt_comment != NULL) {
3757     /* OK, remove the old comment. */
3758     g_free(fdata->opt_comment);
3759     fdata->opt_comment = NULL;
3760     cf->packet_comment_count--;
3761   }
3762   if (comment != NULL) {
3763     /* Add the new comment. */
3764     fdata->opt_comment = comment;
3765     cf->packet_comment_count++;
3766   }
3767
3768   /* OK, we have unsaved changes. */
3769   cf->unsaved_changes = TRUE;
3770 }
3771
3772 /*
3773  * Does this capture file have any comments?
3774  */
3775 gboolean
3776 cf_has_comments(capture_file *cf)
3777 {
3778   return (cf_read_shb_comment(cf) != NULL || cf->packet_comment_count != 0);
3779 }
3780
3781 typedef struct {
3782   wtap_dumper *pdh;
3783   const char  *fname;
3784   int          file_type;
3785 } save_callback_args_t;
3786
3787 /*
3788  * Save a capture to a file, in a particular format, saving either
3789  * all packets, all currently-displayed packets, or all marked packets.
3790  *
3791  * Returns TRUE if it succeeds, FALSE otherwise; if it fails, it pops
3792  * up a message box for the failure.
3793  */
3794 static gboolean
3795 save_packet(capture_file *cf _U_, frame_data *fdata,
3796             union wtap_pseudo_header *pseudo_header, const guint8 *pd,
3797             void *argsp)
3798 {
3799   save_callback_args_t *args = argsp;
3800   struct wtap_pkthdr hdr;
3801   int           err;
3802   gchar        *display_basename;
3803
3804   /* init the wtap header for saving */
3805   /* XXX - these are the only flags that correspond to data that we have
3806      in the frame_data structure and that matter on a per-packet basis.
3807
3808      For WTAP_HAS_CAP_LEN, either the file format has separate "captured"
3809      and "on the wire" lengths, or it doesn't.
3810
3811      For WTAP_HAS_DROP_COUNT, Wiretap doesn't actually supply the value
3812      to its callers.
3813
3814      For WTAP_HAS_PACK_FLAGS, we currently don't save the FCS length
3815      from the packet flags. */
3816   hdr.presence_flags = 0;
3817   if (fdata->flags.has_ts)
3818     hdr.presence_flags |= WTAP_HAS_TS;
3819   if (fdata->flags.has_ts)
3820     hdr.presence_flags |= WTAP_HAS_INTERFACE_ID;
3821   hdr.ts.secs      = fdata->abs_ts.secs;
3822   hdr.ts.nsecs     = fdata->abs_ts.nsecs;
3823   hdr.caplen       = fdata->cap_len;
3824   hdr.len          = fdata->pkt_len;
3825   hdr.pkt_encap    = fdata->lnk_t;
3826   /* pcapng */
3827   hdr.interface_id = fdata->interface_id;   /* identifier of the interface. */
3828   /* options */
3829   hdr.opt_comment  = fdata->opt_comment; /* NULL if not available */
3830 #if 0
3831   hdr.drop_count   =
3832   hdr.pack_flags   =     /* XXX - 0 for now (any value for "we don't have it"?) */
3833 #endif
3834   /* and save the packet */
3835   if (!wtap_dump(args->pdh, &hdr, pseudo_header, pd, &err)) {
3836     if (err < 0) {
3837       /* Wiretap error. */
3838       switch (err) {
3839
3840       case WTAP_ERR_UNSUPPORTED_ENCAP:
3841         /*
3842          * This is a problem with the particular frame we're writing;
3843          * note that, and give the frame number.
3844          */
3845         simple_error_message_box(
3846                       "Frame %u has a network type that can't be saved in a \"%s\" file.",
3847                       fdata->num, wtap_file_type_string(args->file_type));
3848         break;
3849
3850       default:
3851         display_basename = g_filename_display_basename(args->fname);
3852         simple_error_message_box(
3853                       "An error occurred while writing to the file \"%s\": %s.",
3854                       display_basename, wtap_strerror(err));
3855         g_free(display_basename);
3856         break;
3857       }
3858     } else {
3859       /* OS error. */
3860       write_failure_alert_box(args->fname, err);
3861     }
3862     return FALSE;
3863   }
3864   return TRUE;
3865 }
3866
3867 /*
3868  * Can this capture file be written out in any format using Wiretap
3869  * rather than by copying the raw data?
3870  */
3871 gboolean
3872 cf_can_write_with_wiretap(capture_file *cf)
3873 {
3874   int ft;
3875
3876   for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
3877     /* To save a file with Wiretap, Wiretap has to handle that format,
3878        and its code to handle that format must be able to write a file
3879        with this file's encapsulation types. */
3880     if (wtap_dump_can_write_encaps(ft, cf->linktypes)) {
3881       /* OK, we can write it out in this type. */
3882       return TRUE;
3883     }
3884   }
3885
3886   /* No, we couldn't save it in any format. */
3887   return FALSE;
3888 }
3889
3890 /*
3891  * Quick scan to find packet offsets.
3892  */
3893 static cf_read_status_t
3894 rescan_file(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
3895 {
3896   const struct wtap_pkthdr *phdr;
3897   gchar       *err_info;
3898   gchar       *name_ptr;
3899   gint64       data_offset;
3900   gint64       file_pos;
3901   progdlg_t *volatile progbar = NULL;
3902   gboolean     stop_flag;
3903   volatile gint64 size;
3904   volatile float progbar_val;
3905   GTimeVal     start_time;
3906   gchar        status_str[100];
3907   volatile gint64 progbar_nextstep;
3908   volatile gint64 progbar_quantum;
3909   guint32       framenum;
3910   frame_data   *fdata;
3911   volatile int count = 0;
3912 #ifdef HAVE_LIBPCAP
3913   volatile int displayed_once = 0;
3914 #endif
3915
3916   /* Close the old handle. */
3917   wtap_close(cf->wth);
3918
3919   /* Open the new file. */
3920   cf->wth = wtap_open_offline(fname, err, &err_info, TRUE);
3921   if (cf->wth == NULL) {
3922     cf_open_failure_alert_box(fname, *err, err_info, FALSE, 0);
3923     return CF_READ_ERROR;
3924   }
3925
3926   /* We're scanning a file whose contents should be the same as what
3927      we had before, so we don't discard dissection state etc.. */
3928   cf->f_datalen = 0;
3929
3930   /* Set the file name because we need it to set the follow stream filter.
3931      XXX - is that still true?  We need it for other reasons, though,
3932      in any case. */
3933   cf->filename = g_strdup(fname);
3934
3935   /* Indicate whether it's a permanent or temporary file. */
3936   cf->is_tempfile = is_tempfile;
3937
3938   /* No user changes yet. */
3939   cf->unsaved_changes = FALSE;
3940
3941   cf->cd_t        = wtap_file_type(cf->wth);
3942   cf->linktypes = g_array_sized_new(FALSE, FALSE, (guint) sizeof(int), 1);
3943
3944   cf->snap      = wtap_snapshot_length(cf->wth);
3945   if (cf->snap == 0) {
3946     /* Snapshot length not known. */
3947     cf->has_snap = FALSE;
3948     cf->snap = WTAP_MAX_PACKET_SIZE;
3949   } else
3950     cf->has_snap = TRUE;
3951
3952   name_ptr = g_filename_display_basename(cf->filename);
3953
3954   cf_callback_invoke(cf_cb_file_rescan_started, cf);
3955
3956   /* Record whether the file is compressed.
3957      XXX - do we know this at open time? */
3958   cf->iscompressed = wtap_iscompressed(cf->wth);
3959
3960   /* Find the size of the file. */
3961   size = wtap_file_size(cf->wth, NULL);
3962
3963   /* Update the progress bar when it gets to this value. */
3964   progbar_nextstep = 0;
3965   /* When we reach the value that triggers a progress bar update,
3966      bump that value by this amount. */
3967   if (size >= 0){
3968     progbar_quantum = size/N_PROGBAR_UPDATES;
3969     if (progbar_quantum < MIN_QUANTUM)
3970       progbar_quantum = MIN_QUANTUM;
3971   }else
3972     progbar_quantum = 0;
3973   /* Progress so far. */
3974   progbar_val = 0.0f;
3975
3976   stop_flag = FALSE;
3977   g_get_current_time(&start_time);
3978
3979   framenum = 0;
3980   phdr = wtap_phdr(cf->wth);
3981   while ((wtap_read(cf->wth, err, &err_info, &data_offset))) {
3982     framenum++;
3983     fdata = frame_data_sequence_find(cf->frames, framenum);
3984     fdata->file_off = data_offset;
3985     if (size >= 0) {
3986       count++;
3987       file_pos = wtap_read_so_far(cf->wth);
3988
3989       /* Create the progress bar if necessary.
3990        * Check whether it should be created or not every MIN_NUMBER_OF_PACKET
3991        */
3992       if ((progbar == NULL) && !(count % MIN_NUMBER_OF_PACKET)){
3993         progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
3994         progbar = delayed_create_progress_dlg(cf->window, "Rescanning", name_ptr,
3995                                               TRUE, &stop_flag, &start_time, progbar_val);
3996       }
3997
3998       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
3999          when we update it, we have to run the GTK+ main loop to get it
4000          to repaint what's pending, and doing so may involve an "ioctl()"
4001          to see if there's any pending input from an X server, and doing
4002          that for every packet can be costly, especially on a big file. */
4003       if (file_pos >= progbar_nextstep) {
4004         if (progbar != NULL) {
4005           progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
4006           /* update the packet bar content on the first run or frequently on very large files */
4007 #ifdef HAVE_LIBPCAP
4008           if (progbar_quantum > 500000 || displayed_once == 0) {
4009             if ((auto_scroll_live || displayed_once == 0 || cf->displayed_count < 1000) && cf->count != 0) {
4010               displayed_once = 1;
4011               packets_bar_update();
4012             }
4013           }
4014 #endif /* HAVE_LIBPCAP */
4015           update_progress_dlg(progbar, progbar_val, status_str);
4016         }
4017         progbar_nextstep += progbar_quantum;
4018       }
4019     }
4020
4021     if (stop_flag) {
4022       /* Well, the user decided to abort the rescan.  Sadly, as this
4023          isn't a reread, recovering is difficult, so we'll just
4024          close the current capture. */
4025       break;
4026     }
4027
4028     /* Add this packet's link-layer encapsulation type to cf->linktypes, if
4029        it's not already there.
4030        XXX - yes, this is O(N), so if every packet had a different
4031        link-layer encapsulation type, it'd be O(N^2) to read the file, but
4032        there are probably going to be a small number of encapsulation types
4033        in a file. */
4034     cf_add_encapsulation_type(cf, phdr->pkt_encap);
4035   }
4036
4037   /* Free the display name */
4038   g_free(name_ptr);
4039
4040   /* We're done reading the file; destroy the progress bar if it was created. */
4041   if (progbar != NULL)
4042     destroy_progress_dlg(progbar);
4043
4044   /* We're done reading sequentially through the file. */
4045   cf->state = FILE_READ_DONE;
4046
4047   /* Close the sequential I/O side, to free up memory it requires. */
4048   wtap_sequential_close(cf->wth);
4049
4050   /* compute the time it took to load the file */
4051   compute_elapsed(&start_time);
4052
4053   /* Set the file encapsulation type now; we don't know what it is until
4054      we've looked at all the packets, as we don't know until then whether
4055      there's more than one type (and thus whether it's
4056      WTAP_ENCAP_PER_PACKET). */
4057   cf->lnk_t = wtap_file_encap(cf->wth);
4058
4059   cf_callback_invoke(cf_cb_file_rescan_finished, cf);
4060
4061   if (stop_flag) {
4062     /* Our caller will give up at this point. */
4063     return CF_READ_ABORTED;
4064   }
4065
4066   if (*err != 0) {
4067     /* Put up a message box noting that the read failed somewhere along
4068        the line.  Don't throw out the stuff we managed to read, though,
4069        if any. */
4070     switch (*err) {
4071
4072     case WTAP_ERR_UNSUPPORTED:
4073       simple_error_message_box(
4074                  "The capture file contains record data that Wireshark doesn't support.\n(%s)",
4075                  err_info);
4076       g_free(err_info);
4077       break;
4078
4079     case WTAP_ERR_UNSUPPORTED_ENCAP:
4080       simple_error_message_box(
4081                  "The capture file has a packet with a network type that Wireshark doesn't support.\n(%s)",
4082                  err_info);
4083       g_free(err_info);
4084       break;
4085
4086     case WTAP_ERR_CANT_READ:
4087       simple_error_message_box(
4088                  "An attempt to read from the capture file failed for"
4089                  " some unknown reason.");
4090       break;
4091
4092     case WTAP_ERR_SHORT_READ:
4093       simple_error_message_box(
4094                  "The capture file appears to have been cut short"
4095                  " in the middle of a packet.");
4096       break;
4097
4098     case WTAP_ERR_BAD_FILE:
4099       simple_error_message_box(
4100                  "The capture file appears to be damaged or corrupt.\n(%s)",
4101                  err_info);
4102       g_free(err_info);
4103       break;
4104
4105     case WTAP_ERR_DECOMPRESS:
4106       simple_error_message_box(
4107                  "The compressed capture file appears to be damaged or corrupt.\n"
4108                  "(%s)", err_info);
4109       g_free(err_info);
4110       break;
4111
4112     default:
4113       simple_error_message_box(
4114                  "An error occurred while reading the"
4115                  " capture file: %s.", wtap_strerror(*err));
4116       break;
4117     }
4118     return CF_READ_ERROR;
4119   } else
4120     return CF_READ_OK;
4121 }
4122
4123 cf_write_status_t
4124 cf_save_packets(capture_file *cf, const char *fname, guint save_format,
4125                 gboolean compressed, gboolean discard_comments,
4126                 gboolean dont_reopen)
4127 {
4128   gchar        *fname_new = NULL;
4129   int           err;
4130   gchar        *err_info;
4131   enum {
4132      SAVE_WITH_MOVE,
4133      SAVE_WITH_COPY,
4134      SAVE_WITH_WTAP
4135   }             how_to_save;
4136   wtap_dumper  *pdh;
4137   save_callback_args_t callback_args;
4138 #ifdef _WIN32
4139   gchar        *display_basename;
4140 #endif
4141   guint         framenum;
4142   frame_data   *fdata;
4143
4144   cf_callback_invoke(cf_cb_file_save_started, (gpointer)fname);
4145
4146   if (save_format == cf->cd_t && compressed == cf->iscompressed
4147       && !discard_comments && !cf->unsaved_changes) {
4148     /* We're saving in the format it's already in, and we're
4149        not discarding comments, and there are no changes we have
4150        in memory that aren't saved to the file, so we can just move
4151        or copy the raw data. */
4152
4153     if (cf->is_tempfile) {
4154       /* The file being saved is a temporary file from a live
4155          capture, so it doesn't need to stay around under that name;
4156          first, try renaming the capture buffer file to the new name.
4157          This acts as a "safe save", in that, if the file already
4158          exists, the existing file will be removed only if the rename
4159          succeeds.
4160
4161          Sadly, on Windows, as we have the current capture file
4162          open, even MoveFileEx() with MOVEFILE_REPLACE_EXISTING
4163          (to cause the rename to remove an existing target), as
4164          done by ws_stdio_rename() (ws_rename() is #defined to
4165          be ws_stdio_rename() on Windows) will fail.
4166
4167          According to the MSDN documentation for CreateFile(), if,
4168          when we open a capture file, we were to directly do a CreateFile(),
4169          opening with FILE_SHARE_DELETE|FILE_SHARE_READ, and then
4170          convert it to a file descriptor with _open_osfhandle(),
4171          that would allow the file to be renamed out from under us.
4172
4173          However, that doesn't work in practice.  Perhaps the problem
4174          is that the process doing the rename is the process that
4175          has the file open. */
4176 #ifndef _WIN32
4177       if (ws_rename(cf->filename, fname) == 0) {
4178         /* That succeeded - there's no need to copy the source file. */
4179         how_to_save = SAVE_WITH_MOVE;
4180       } else {
4181         if (errno == EXDEV) {
4182           /* They're on different file systems, so we have to copy the
4183              file. */
4184           how_to_save = SAVE_WITH_COPY;
4185         } else {
4186           /* The rename failed, but not because they're on different
4187              file systems - put up an error message.  (Or should we
4188              just punt and try to copy?  The only reason why I'd
4189              expect the rename to fail and the copy to succeed would
4190              be if we didn't have permission to remove the file from
4191              the temporary directory, and that might be fixable - but
4192              is it worth requiring the user to go off and fix it?) */
4193           cf_rename_failure_alert_box(fname, errno);
4194           goto fail;
4195         }
4196       }
4197 #else
4198       how_to_save = SAVE_WITH_COPY;
4199 #endif
4200     } else {
4201       /* It's a permanent file, so we should copy it, and not remove the
4202          original. */
4203       how_to_save = SAVE_WITH_COPY;
4204     }
4205
4206     if (how_to_save == SAVE_WITH_COPY) {
4207       /* Copy the file, if we haven't moved it.  If we're overwriting
4208          an existing file, we do it with a "safe save", by writing
4209          to a new file and, if the write succeeds, renaming the
4210          new file on top of the old file. */
4211       if (file_exists(fname)) {
4212         fname_new = g_strdup_printf("%s~", fname);
4213         if (!copy_file_binary_mode(cf->filename, fname_new))
4214           goto fail;
4215       } else {
4216         if (!copy_file_binary_mode(cf->filename, fname))
4217           goto fail;
4218       }
4219     }
4220   } else {
4221     /* Either we're saving in a different format or we're saving changes,
4222        such as added, modified, or removed comments, that haven't yet
4223        been written to the underlying file; we can't do that by copying
4224        or moving the capture file, we have to do it by writing the packets
4225        out in Wiretap. */
4226
4227     wtapng_section_t *shb_hdr = NULL;
4228     wtapng_iface_descriptions_t *idb_inf = NULL;
4229     int encap;
4230
4231     shb_hdr = wtap_file_get_shb_info(cf->wth);
4232     idb_inf = wtap_file_get_idb_info(cf->wth);
4233
4234     /* Determine what file encapsulation type we should use. */
4235     encap = wtap_dump_file_encap_type(cf->linktypes);
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, encap, cf->snap,
4247                               compressed, shb_hdr, idb_inf, &err);
4248     } else {
4249       pdh = wtap_dump_open_ng(fname, save_format, encap, 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   int encap;
4438
4439   cf_callback_invoke(cf_cb_file_export_specified_packets_started, (gpointer)fname);
4440
4441   packet_range_process_init(range);
4442
4443   /* We're writing out specified packets from the specified capture
4444      file to another file.  Even if all captured packets are to be
4445      written, don't special-case the operation - read each packet
4446      and then write it out if it's one of the specified ones. */
4447
4448   shb_hdr = wtap_file_get_shb_info(cf->wth);
4449   idb_inf = wtap_file_get_idb_info(cf->wth);
4450
4451   /* Determine what file encapsulation type we should use. */
4452   encap = wtap_dump_file_encap_type(cf->linktypes);
4453
4454   if (file_exists(fname)) {
4455     /* We're overwriting an existing file; write out to a new file,
4456        and, if that succeeds, rename the new file on top of the
4457        old file.  That makes this a "safe save", so that we don't
4458        lose the old file if we have a problem writing out the new
4459        file.  (If the existing file is the current capture file,
4460        we *HAVE* to do that, otherwise we're overwriting the file
4461        from which we're reading the packets that we're writing!) */
4462     fname_new = g_strdup_printf("%s~", fname);
4463     pdh = wtap_dump_open_ng(fname_new, save_format, encap, cf->snap,
4464                             compressed, shb_hdr, idb_inf, &err);
4465   } else {
4466     pdh = wtap_dump_open_ng(fname, save_format, encap, cf->snap,
4467                             compressed, shb_hdr, idb_inf, &err);
4468   }
4469   g_free(idb_inf);
4470   idb_inf = NULL;
4471
4472   if (pdh == NULL) {
4473     cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
4474     goto fail;
4475   }
4476
4477   /* Add address resolution */
4478   wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list());
4479
4480   /* Iterate through the list of packets, processing the packets we were
4481      told to process.
4482
4483      XXX - we've already called "packet_range_process_init(range)", but
4484      "process_specified_packets()" will do it again.  Fortunately,
4485      that's harmless in this case, as we haven't done anything to
4486      "range" since we initialized it. */
4487   callback_args.pdh = pdh;
4488   callback_args.fname = fname;
4489   callback_args.file_type = save_format;
4490   switch (process_specified_packets(cf, range, "Writing", "specified packets",
4491                                     TRUE, save_packet, &callback_args)) {
4492
4493   case PSP_FINISHED:
4494     /* Completed successfully. */
4495     break;
4496
4497   case PSP_STOPPED:
4498       /* The user decided to abort the saving.
4499          If we're writing to a temporary file, remove it.
4500          XXX - should we do so even if we're not writing to a
4501          temporary file? */
4502       wtap_dump_close(pdh, &err);
4503       if (fname_new != NULL)
4504         ws_unlink(fname_new);
4505       cf_callback_invoke(cf_cb_file_export_specified_packets_stopped, NULL);
4506       return CF_WRITE_ABORTED;
4507     break;
4508
4509   case PSP_FAILED:
4510     /* Error while saving.
4511        If we're writing to a temporary file, remove it. */
4512     if (fname_new != NULL)
4513       ws_unlink(fname_new);
4514     wtap_dump_close(pdh, &err);
4515     goto fail;
4516   }
4517
4518   if (!wtap_dump_close(pdh, &err)) {
4519     cf_close_failure_alert_box(fname, err);
4520     goto fail;
4521   }
4522
4523   if (fname_new != NULL) {
4524     /* We wrote out to fname_new, and should rename it on top of
4525        fname; fname is now closed, so that should be possible even
4526        on Windows.  Do the rename. */
4527     if (ws_rename(fname_new, fname) == -1) {
4528       /* Well, the rename failed. */
4529       cf_rename_failure_alert_box(fname, errno);
4530       goto fail;
4531     }
4532   }
4533
4534   cf_callback_invoke(cf_cb_file_export_specified_packets_finished, NULL);
4535   return CF_WRITE_OK;
4536
4537 fail:
4538   if (fname_new != NULL) {
4539     /* We were trying to write to a temporary file; get rid of it if it
4540        exists.  (We don't care whether this fails, as, if it fails,
4541        there's not much we can do about it.  I guess if it failed for
4542        a reason other than "it doesn't exist", we could report an
4543        error, so the user knows there's a junk file that they might
4544        want to clean up.) */
4545     ws_unlink(fname_new);
4546     g_free(fname_new);
4547   }
4548   cf_callback_invoke(cf_cb_file_export_specified_packets_failed, NULL);
4549   return CF_WRITE_ERROR;
4550 }
4551
4552 static void
4553 cf_open_failure_alert_box(const char *filename, int err, gchar *err_info,
4554                           gboolean for_writing, int file_type)
4555 {
4556   gchar *display_basename;
4557
4558   if (err < 0) {
4559     /* Wiretap error. */
4560     display_basename = g_filename_display_basename(filename);
4561     switch (err) {
4562
4563     case WTAP_ERR_NOT_REGULAR_FILE:
4564       simple_error_message_box(
4565             "The file \"%s\" is a \"special file\" or socket or other non-regular file.",
4566             display_basename);
4567       break;
4568
4569     case WTAP_ERR_RANDOM_OPEN_PIPE:
4570       /* Seen only when opening a capture file for reading. */
4571       simple_error_message_box(
4572             "The file \"%s\" is a pipe or FIFO; Wireshark can't read pipe or FIFO files.\n"
4573             "To capture from a pipe or FIFO use wireshark -i -",
4574             display_basename);
4575       break;
4576
4577     case WTAP_ERR_FILE_UNKNOWN_FORMAT:
4578       /* Seen only when opening a capture file for reading. */
4579       simple_error_message_box(
4580             "The file \"%s\" isn't a capture file in a format Wireshark understands.",
4581             display_basename);
4582       break;
4583
4584     case WTAP_ERR_UNSUPPORTED:
4585       /* Seen only when opening a capture file for reading. */
4586       simple_error_message_box(
4587             "The file \"%s\" isn't a capture file in a format Wireshark understands.\n"
4588             "(%s)",
4589             display_basename, err_info);
4590       g_free(err_info);
4591       break;
4592
4593     case WTAP_ERR_CANT_WRITE_TO_PIPE:
4594       /* Seen only when opening a capture file for writing. */
4595       simple_error_message_box(
4596             "The file \"%s\" is a pipe, and %s capture files can't be "
4597             "written to a pipe.",
4598             display_basename, wtap_file_type_string(file_type));
4599       break;
4600
4601     case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
4602       /* Seen only when opening a capture file for writing. */
4603       simple_error_message_box(
4604             "Wireshark doesn't support writing capture files in that format.");
4605       break;
4606
4607     case WTAP_ERR_UNSUPPORTED_ENCAP:
4608       if (for_writing) {
4609         simple_error_message_box("Wireshark can't save this capture in that format.");
4610       } else {
4611         simple_error_message_box(
4612               "The file \"%s\" is a capture for a network type that Wireshark doesn't support.\n"
4613               "(%s)",
4614               display_basename, err_info);
4615         g_free(err_info);
4616       }
4617       break;
4618
4619     case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
4620       if (for_writing) {
4621         simple_error_message_box(
4622               "Wireshark can't save this capture in that format.");
4623       } else {
4624         simple_error_message_box(
4625               "The file \"%s\" is a capture for a network type that Wireshark doesn't support.",
4626               display_basename);
4627       }
4628       break;
4629
4630     case WTAP_ERR_BAD_FILE:
4631       /* Seen only when opening a capture file for reading. */
4632       simple_error_message_box(
4633             "The file \"%s\" appears to be damaged or corrupt.\n"
4634             "(%s)",
4635             display_basename, err_info);
4636       g_free(err_info);
4637       break;
4638
4639     case WTAP_ERR_CANT_OPEN:
4640       if (for_writing) {
4641         simple_error_message_box(
4642               "The file \"%s\" could not be created for some unknown reason.",
4643               display_basename);
4644       } else {
4645         simple_error_message_box(
4646               "The file \"%s\" could not be opened for some unknown reason.",
4647               display_basename);
4648       }
4649       break;
4650
4651     case WTAP_ERR_SHORT_READ:
4652       simple_error_message_box(
4653             "The file \"%s\" appears to have been cut short"
4654             " in the middle of a packet or other data.",
4655             display_basename);
4656       break;
4657
4658     case WTAP_ERR_SHORT_WRITE:
4659       simple_error_message_box(
4660             "A full header couldn't be written to the file \"%s\".",
4661             display_basename);
4662       break;
4663
4664     case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
4665       simple_error_message_box(
4666             "This file type cannot be written as a compressed file.");
4667       break;
4668
4669     case WTAP_ERR_DECOMPRESS:
4670       simple_error_message_box(
4671             "The compressed file \"%s\" appears to be damaged or corrupt.\n"
4672             "(%s)", display_basename, err_info);
4673       g_free(err_info);
4674       break;
4675
4676     default:
4677       simple_error_message_box(
4678             "The file \"%s\" could not be %s: %s.",
4679             display_basename,
4680             for_writing ? "created" : "opened",
4681             wtap_strerror(err));
4682       break;
4683     }
4684     g_free(display_basename);
4685   } else {
4686     /* OS error. */
4687     open_failure_alert_box(filename, err, for_writing);
4688   }
4689 }
4690
4691 /*
4692  * XXX - whether we mention the source pathname, the target pathname,
4693  * or both depends on the error and on what we find if we look for
4694  * one or both of them.
4695  */
4696 static void
4697 cf_rename_failure_alert_box(const char *filename, int err)
4698 {
4699   gchar *display_basename;
4700
4701   display_basename = g_filename_display_basename(filename);
4702   switch (err) {
4703
4704   case ENOENT:
4705     /* XXX - should check whether the source exists and, if not,
4706        report it as the problem and, if so, report the destination
4707        as the problem. */
4708     simple_error_message_box("The path to the file \"%s\" doesn't exist.",
4709                              display_basename);
4710     break;
4711
4712   case EACCES:
4713     /* XXX - if we're doing a rename after a safe save, we should
4714        probably say something else. */
4715     simple_error_message_box("You don't have permission to move the capture file to \"%s\".",
4716                              display_basename);
4717     break;
4718
4719   default:
4720     /* XXX - this should probably mention both the source and destination
4721        pathnames. */
4722     simple_error_message_box("The file \"%s\" could not be moved: %s.",
4723                              display_basename, wtap_strerror(err));
4724     break;
4725   }
4726   g_free(display_basename);
4727 }
4728
4729 /* Check for write errors - if the file is being written to an NFS server,
4730    a write error may not show up until the file is closed, as NFS clients
4731    might not send writes to the server until the "write()" call finishes,
4732    so that the write may fail on the server but the "write()" may succeed. */
4733 static void
4734 cf_close_failure_alert_box(const char *filename, int err)
4735 {
4736   gchar *display_basename;
4737
4738   if (err < 0) {
4739     /* Wiretap error. */
4740     display_basename = g_filename_display_basename(filename);
4741     switch (err) {
4742
4743     case WTAP_ERR_CANT_CLOSE:
4744       simple_error_message_box(
4745             "The file \"%s\" couldn't be closed for some unknown reason.",
4746             display_basename);
4747       break;
4748
4749     case WTAP_ERR_SHORT_WRITE:
4750       simple_error_message_box(
4751             "Not all the packets could be written to the file \"%s\".",
4752                     display_basename);
4753       break;
4754
4755     default:
4756       simple_error_message_box(
4757             "An error occurred while closing the file \"%s\": %s.",
4758             display_basename, wtap_strerror(err));
4759       break;
4760     }
4761     g_free(display_basename);
4762   } else {
4763     /* OS error.
4764        We assume that a close error from the OS is really a write error. */
4765     write_failure_alert_box(filename, err);
4766   }
4767 }
4768
4769 /* Reload the current capture file. */
4770 void
4771 cf_reload(capture_file *cf) {
4772   gchar *filename;
4773   gboolean is_tempfile;
4774   int err;
4775
4776   /* If the file could be opened, "cf_open()" calls "cf_close()"
4777      to get rid of state for the old capture file before filling in state
4778      for the new capture file.  "cf_close()" will remove the file if
4779      it's a temporary file; we don't want that to happen (for one thing,
4780      it'd prevent subsequent reopens from working).  Remember whether it's
4781      a temporary file, mark it as not being a temporary file, and then
4782      reopen it as the type of file it was.
4783
4784      Also, "cf_close()" will free "cf->filename", so we must make
4785      a copy of it first. */
4786   filename = g_strdup(cf->filename);
4787   is_tempfile = cf->is_tempfile;
4788   cf->is_tempfile = FALSE;
4789   if (cf_open(cf, filename, is_tempfile, &err) == CF_OK) {
4790     switch (cf_read(cf, TRUE)) {
4791
4792     case CF_READ_OK:
4793     case CF_READ_ERROR:
4794       /* Just because we got an error, that doesn't mean we were unable
4795          to read any of the file; we handle what we could get from the
4796          file. */
4797       break;
4798
4799     case CF_READ_ABORTED:
4800       /* The user bailed out of re-reading the capture file; the
4801          capture file has been closed - just free the capture file name
4802          string and return (without changing the last containing
4803          directory). */
4804       g_free(filename);
4805       return;
4806     }
4807   } else {
4808     /* The open failed, so "cf->is_tempfile" wasn't set to "is_tempfile".
4809        Instead, the file was left open, so we should restore "cf->is_tempfile"
4810        ourselves.
4811
4812        XXX - change the menu?  Presumably "cf_open()" will do that;
4813        make sure it does! */
4814     cf->is_tempfile = is_tempfile;
4815   }
4816   /* "cf_open()" made a copy of the file name we handed it, so
4817      we should free up our copy. */
4818   g_free(filename);
4819 }
4820
4821 /*
4822  * Editor modelines
4823  *
4824  * Local Variables:
4825  * c-basic-offset: 2
4826  * tab-width: 8
4827  * indent-tabs-mode: nil
4828  * End:
4829  *
4830  * ex: set shiftwidth=2 tabstop=8 expandtab:
4831  * :indentSize=2:tabSize=8:noTabs=true:
4832  */