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