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