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