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