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