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