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