packet-dcerpc: dissect the auth verifier of PDU_CO_CANCEL, PDU_ORPHANED and PDU_FAULT
[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
1151        XXX - we must do this before we add the row to the display,
1152        as, if the display's GtkCList's selection mode is
1153        GTK_SELECTION_BROWSE, when the first entry is added to it,
1154        "cf_select_packet()" will be called, and it will fetch the row
1155        data for the 0th row, and will get a null pointer rather than
1156        "fdata", as "gtk_clist_append()" won't yet have returned and
1157        thus "gtk_clist_set_row_data()" won't yet have been called.
1158
1159        We thus need to leave behind bread crumbs so that
1160        "cf_select_packet()" can find this frame.  See the comment
1161        in "cf_select_packet()". */
1162     if (cf->first_displayed == 0)
1163       cf->first_displayed = fdata->num;
1164
1165     /* This is the last frame we've seen so far. */
1166     cf->last_displayed = fdata->num;
1167   }
1168
1169   epan_dissect_reset(edt);
1170   return row;
1171 }
1172
1173 /* read in a new packet */
1174 /* returns the row of the new packet in the packet list or -1 if not displayed */
1175 static int
1176 read_packet(capture_file *cf, dfilter_t *dfcode, epan_dissect_t *edt,
1177             column_info *cinfo, gint64 offset)
1178 {
1179   struct wtap_pkthdr *phdr = wtap_phdr(cf->wth);
1180   const guint8 *buf = wtap_buf_ptr(cf->wth);
1181   frame_data    fdlocal;
1182   guint32       framenum;
1183   frame_data   *fdata;
1184   gboolean      passed;
1185   int           row = -1;
1186
1187   /* Add this packet's link-layer encapsulation type to cf->linktypes, if
1188      it's not already there.
1189      XXX - yes, this is O(N), so if every packet had a different
1190      link-layer encapsulation type, it'd be O(N^2) to read the file, but
1191      there are probably going to be a small number of encapsulation types
1192      in a file. */
1193   cf_add_encapsulation_type(cf, phdr->pkt_encap);
1194
1195   /* The frame number of this packet is one more than the count of
1196      frames in the file so far. */
1197   framenum = cf->count + 1;
1198
1199   frame_data_init(&fdlocal, framenum, phdr, offset, cf->cum_bytes);
1200
1201   passed = TRUE;
1202   if (cf->rfcode) {
1203     epan_dissect_t rf_edt;
1204
1205     epan_dissect_init(&rf_edt, cf->epan, TRUE, FALSE);
1206     epan_dissect_prime_dfilter(&rf_edt, cf->rfcode);
1207     epan_dissect_run(&rf_edt, cf->cd_t, phdr, frame_tvbuff_new(&fdlocal, buf), &fdlocal, NULL);
1208     passed = dfilter_apply_edt(cf->rfcode, &rf_edt);
1209     epan_dissect_cleanup(&rf_edt);
1210   }
1211
1212   if (passed) {
1213     /* This does a shallow copy of fdlocal, which is good enough. */
1214     fdata = frame_data_sequence_add(cf->frames, &fdlocal);
1215
1216     cf->count++;
1217     if (phdr->opt_comment != NULL)
1218       cf->packet_comment_count++;
1219     cf->f_datalen = offset + fdlocal.cap_len;
1220
1221     if (!cf->redissecting) {
1222       row = add_packet_to_packet_list(fdata, cf, edt, dfcode,
1223                                       cinfo, phdr, buf, TRUE);
1224     }
1225   }
1226
1227   return row;
1228 }
1229
1230
1231 typedef struct _callback_data_t {
1232   gint64           f_len;
1233   GTimeVal         start_time;
1234   progdlg_t       *progbar;
1235   GTimer          *prog_timer;
1236   gboolean         stop_flag;
1237 } callback_data_t;
1238
1239
1240 static gboolean
1241 merge_callback(merge_event event, int num _U_,
1242                const merge_in_file_t in_files[], const guint in_file_count,
1243                void *data)
1244 {
1245   guint i;
1246   callback_data_t *cb_data = (callback_data_t*) data;
1247
1248   g_assert(cb_data != NULL);
1249
1250   switch (event) {
1251
1252     case MERGE_EVENT_INPUT_FILES_OPENED:
1253       /* do nothing */
1254       break;
1255
1256     case MERGE_EVENT_FRAME_TYPE_SELECTED:
1257       /* do nothing */
1258       break;
1259
1260     case MERGE_EVENT_READY_TO_MERGE:
1261       /* Get the sum of the sizes of all the files. */
1262       for (i = 0; i < in_file_count; i++)
1263         cb_data->f_len += in_files[i].size;
1264
1265       cb_data->prog_timer = g_timer_new();
1266       g_timer_start(cb_data->prog_timer);
1267
1268       g_get_current_time(&cb_data->start_time);
1269       break;
1270
1271     case MERGE_EVENT_PACKET_WAS_READ:
1272       {
1273         gint64 data_offset = 0;
1274
1275         /* Get the sum of the data offsets in all of the files. */
1276         data_offset = 0;
1277         for (i = 0; i < in_file_count; i++)
1278           data_offset += in_files[i].data_offset;
1279
1280         /* Create the progress bar if necessary.
1281            We check on every iteration of the loop, so that it takes no
1282            longer than the standard time to create it (otherwise, for a
1283            large file, we might take considerably longer than that standard
1284            time in order to get to the next progress bar step). */
1285         if (cb_data->progbar == NULL) {
1286           cb_data->progbar = delayed_create_progress_dlg(NULL, "Merging", "files",
1287             FALSE, &cb_data->stop_flag, &cb_data->start_time, 0.0f);
1288         }
1289
1290         /*
1291          * Update the progress bar, but do it only after
1292          * PROGBAR_UPDATE_INTERVAL has elapsed. Calling update_progress_dlg
1293          * and packets_bar_update will likely trigger UI paint events, which
1294          * might take a while depending on the platform and display. Reset
1295          * our timer *after* painting.
1296          */
1297         if (g_timer_elapsed(cb_data->prog_timer, NULL) > PROGBAR_UPDATE_INTERVAL) {
1298             float  progbar_val;
1299             gint64 file_pos = 0;
1300             /* Get the sum of the seek positions in all of the files. */
1301             for (i = 0; i < in_file_count; i++)
1302               file_pos += wtap_read_so_far(in_files[i].wth);
1303
1304             progbar_val = (gfloat) file_pos / (gfloat) cb_data->f_len;
1305             if (progbar_val > 1.0f) {
1306               /* Some file probably grew while we were reading it.
1307                  That "shouldn't happen", so we'll just clip the progress
1308                  value at 1.0. */
1309               progbar_val = 1.0f;
1310             }
1311
1312             if (cb_data->progbar != NULL) {
1313               gchar status_str[100];
1314               g_snprintf(status_str, sizeof(status_str),
1315                          "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
1316                          file_pos / 1024, cb_data->f_len / 1024);
1317               update_progress_dlg(cb_data->progbar, progbar_val, status_str);
1318             }
1319             g_timer_start(cb_data->prog_timer);
1320         }
1321       }
1322       break;
1323
1324     case MERGE_EVENT_DONE:
1325       /* We're done merging the files; destroy the progress bar if it was created. */
1326       if (cb_data->progbar != NULL)
1327         destroy_progress_dlg(cb_data->progbar);
1328       g_timer_destroy(cb_data->prog_timer);
1329       break;
1330   }
1331
1332   return cb_data->stop_flag;
1333 }
1334
1335
1336
1337 cf_status_t
1338 cf_merge_files(char **out_filenamep, int in_file_count,
1339                char *const *in_filenames, int file_type, gboolean do_append)
1340 {
1341   char                      *out_filename;
1342   char                      *tmpname;
1343   int                        out_fd;
1344   int                        err      = 0;
1345   gchar                     *err_info = NULL;
1346   guint                      err_fileno;
1347   merge_result               status;
1348   merge_progress_callback_t  cb;
1349
1350
1351   if (*out_filenamep != NULL) {
1352     out_filename = *out_filenamep;
1353     out_fd = ws_open(out_filename, O_CREAT|O_TRUNC|O_BINARY, 0600);
1354     if (out_fd == -1)
1355       err = errno;
1356   } else {
1357     out_fd = create_tempfile(&tmpname, "wireshark", NULL);
1358     if (out_fd == -1)
1359       err = errno;
1360     out_filename = g_strdup(tmpname);
1361     *out_filenamep = out_filename;
1362   }
1363   if (out_fd == -1) {
1364     cf_open_failure_alert_box(out_filename, err, NULL, TRUE, file_type);
1365     return CF_ERROR;
1366   }
1367
1368   /* prepare our callback routine */
1369   cb.callback_func = merge_callback;
1370   cb.data = g_malloc0(sizeof(callback_data_t));
1371
1372   /* merge the files */
1373   status = merge_files(out_fd, out_filename, file_type,
1374                        (const char *const *) in_filenames, in_file_count,
1375                        do_append, IDB_MERGE_MODE_ALL_SAME, 0 /* snaplen */,
1376                        "Wireshark", &cb, &err, &err_info, &err_fileno);
1377
1378   g_free(cb.data);
1379
1380   switch (status) {
1381     case MERGE_OK:
1382       break;
1383
1384     case MERGE_USER_ABORTED:
1385       /* this isn't really an error, though we will return CF_ERROR later */
1386       break;
1387
1388     case MERGE_ERR_CANT_OPEN_INFILE:
1389       cf_open_failure_alert_box(in_filenames[err_fileno], err, err_info,
1390                                 FALSE, 0);
1391       ws_close(out_fd);
1392       break;
1393
1394     case MERGE_ERR_CANT_OPEN_OUTFILE:
1395       cf_open_failure_alert_box(out_filename, err, err_info, TRUE,
1396                                 file_type);
1397       ws_close(out_fd);
1398       break;
1399
1400     case MERGE_ERR_CANT_READ_INFILE:      /* fall through */
1401     case MERGE_ERR_BAD_PHDR_INTERFACE_ID:
1402     case MERGE_ERR_CANT_WRITE_OUTFILE:
1403     case MERGE_ERR_CANT_CLOSE_OUTFILE:
1404     default:
1405       simple_error_message_box("%s", err_info ? err_info : "unknown error");
1406       break;
1407   }
1408
1409   g_free(err_info);
1410   /* for general case, no need to close out_fd: file handle associated to this file
1411      descriptor was already closed by the call to wtap_dump_close() in merge_files() */
1412
1413   if (status != MERGE_OK) {
1414     /* Callers aren't expected to treat an error or an explicit abort
1415        differently - we put up error dialogs ourselves, so they don't
1416        have to. */
1417     return CF_ERROR;
1418   } else
1419     return CF_OK;
1420 }
1421
1422 cf_status_t
1423 cf_filter_packets(capture_file *cf, gchar *dftext, gboolean force)
1424 {
1425   const char *filter_new = dftext ? dftext : "";
1426   const char *filter_old = cf->dfilter ? cf->dfilter : "";
1427   dfilter_t  *dfcode;
1428   gchar      *err_msg;
1429   GTimeVal    start_time;
1430
1431   /* if new filter equals old one, do nothing unless told to do so */
1432   if (!force && strcmp(filter_new, filter_old) == 0) {
1433     return CF_OK;
1434   }
1435
1436   dfcode=NULL;
1437
1438   if (dftext == NULL) {
1439     /* The new filter is an empty filter (i.e., display all packets).
1440      * so leave dfcode==NULL
1441      */
1442   } else {
1443     /*
1444      * We have a filter; make a copy of it (as we'll be saving it),
1445      * and try to compile it.
1446      */
1447     dftext = g_strdup(dftext);
1448     if (!dfilter_compile(dftext, &dfcode, &err_msg)) {
1449       /* The attempt failed; report an error. */
1450       simple_message_box(ESD_TYPE_ERROR, NULL,
1451           "See the help for a description of the display filter syntax.",
1452           "\"%s\" isn't a valid display filter: %s",
1453           dftext, err_msg);
1454       g_free(err_msg);
1455       g_free(dftext);
1456       return CF_ERROR;
1457     }
1458
1459     /* Was it empty? */
1460     if (dfcode == NULL) {
1461       /* Yes - free the filter text, and set it to null. */
1462       g_free(dftext);
1463       dftext = NULL;
1464     }
1465   }
1466
1467   /* We have a valid filter.  Replace the current filter. */
1468   g_free(cf->dfilter);
1469   cf->dfilter = dftext;
1470   g_get_current_time(&start_time);
1471
1472
1473   /* Now rescan the packet list, applying the new filter, but not
1474      throwing away information constructed on a previous pass. */
1475   if (cf->state != FILE_CLOSED) {
1476     if (dftext == NULL) {
1477       rescan_packets(cf, "Resetting", "Filter", FALSE);
1478     } else {
1479       rescan_packets(cf, "Filtering", dftext, FALSE);
1480     }
1481   }
1482
1483   /* Cleanup and release all dfilter resources */
1484   dfilter_free(dfcode);
1485
1486   return CF_OK;
1487 }
1488
1489 void
1490 cf_reftime_packets(capture_file *cf)
1491 {
1492   ref_time_packets(cf);
1493 }
1494
1495 void
1496 cf_redissect_packets(capture_file *cf)
1497 {
1498   if (cf->state != FILE_CLOSED) {
1499     rescan_packets(cf, "Reprocessing", "all packets", TRUE);
1500   }
1501 }
1502
1503 gboolean
1504 cf_read_record_r(capture_file *cf, const frame_data *fdata,
1505                  struct wtap_pkthdr *phdr, Buffer *buf)
1506 {
1507   int    err;
1508   gchar *err_info;
1509   gchar *display_basename;
1510
1511 #ifdef WANT_PACKET_EDITOR
1512   /* if fdata->file_off == -1 it means packet was edited, and we must find data inside edited_frames tree */
1513   if (G_UNLIKELY(fdata->file_off == -1)) {
1514     const modified_frame_data *frame = (const modified_frame_data *) g_tree_lookup(cf->edited_frames, GINT_TO_POINTER(fdata->num));
1515
1516     if (!frame) {
1517       simple_error_message_box("fdata->file_off == -1, but can't find modified frame.");
1518       return FALSE;
1519     }
1520
1521     *phdr = frame->phdr;
1522     ws_buffer_assure_space(buf, frame->phdr.caplen);
1523     memcpy(ws_buffer_start_ptr(buf), frame->pd, frame->phdr.caplen);
1524     return TRUE;
1525   }
1526 #endif
1527
1528   if (!wtap_seek_read(cf->wth, fdata->file_off, phdr, buf, &err, &err_info)) {
1529     display_basename = g_filename_display_basename(cf->filename);
1530     switch (err) {
1531
1532     case WTAP_ERR_BAD_FILE:
1533       simple_error_message_box("An error occurred while reading from the file \"%s\": %s.\n(%s)",
1534                  display_basename, wtap_strerror(err),
1535                  err_info != NULL ? err_info : "no information supplied");
1536       g_free(err_info);
1537       break;
1538
1539     default:
1540       simple_error_message_box(
1541                  "An error occurred while reading from the file \"%s\": %s.",
1542                  display_basename, wtap_strerror(err));
1543       break;
1544     }
1545     g_free(display_basename);
1546     return FALSE;
1547   }
1548   return TRUE;
1549 }
1550
1551 gboolean
1552 cf_read_record(capture_file *cf, frame_data *fdata)
1553 {
1554   return cf_read_record_r(cf, fdata, &cf->phdr, &cf->buf);
1555 }
1556
1557 /* Rescan the list of packets, reconstructing the CList.
1558
1559    "action" describes why we're doing this; it's used in the progress
1560    dialog box.
1561
1562    "action_item" describes what we're doing; it's used in the progress
1563    dialog box.
1564
1565    "redissect" is TRUE if we need to make the dissectors reconstruct
1566    any state information they have (because a preference that affects
1567    some dissector has changed, meaning some dissector might construct
1568    its state differently from the way it was constructed the last time). */
1569 static void
1570 rescan_packets(capture_file *cf, const char *action, const char *action_item, gboolean redissect)
1571 {
1572   /* Rescan packets new packet list */
1573   guint32     framenum;
1574   frame_data *fdata;
1575   progdlg_t  *progbar = NULL;
1576   GTimer     *prog_timer = g_timer_new();
1577   int         count;
1578   frame_data *selected_frame, *preceding_frame, *following_frame, *prev_frame;
1579   int         selected_frame_num, preceding_frame_num, following_frame_num, prev_frame_num;
1580   gboolean    selected_frame_seen;
1581   float       progbar_val;
1582   GTimeVal    start_time;
1583   gchar       status_str[100];
1584   epan_dissect_t  edt;
1585   dfilter_t  *dfcode;
1586   column_info *cinfo;
1587   gboolean    create_proto_tree;
1588   guint       tap_flags;
1589   gboolean    add_to_packet_list = FALSE;
1590   gboolean    compiled;
1591   guint32     frames_count;
1592
1593   /* Compile the current display filter.
1594    * We assume this will not fail since cf->dfilter is only set in
1595    * cf_filter IFF the filter was valid.
1596    */
1597   compiled = dfilter_compile(cf->dfilter, &dfcode, NULL);
1598   g_assert(!cf->dfilter || (compiled && dfcode));
1599
1600   /* Get the union of the flags for all tap listeners. */
1601   tap_flags = union_of_tap_listener_flags();
1602   cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
1603   create_proto_tree =
1604     (dfcode != NULL || have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
1605
1606   reset_tap_listeners();
1607   /* Which frame, if any, is the currently selected frame?
1608      XXX - should the selected frame or the focus frame be the "current"
1609      frame, that frame being the one from which "Find Frame" searches
1610      start? */
1611   selected_frame = cf->current_frame;
1612
1613   /* Mark frame num as not found */
1614   selected_frame_num = -1;
1615
1616   /* Freeze the packet list while we redo it, so we don't get any
1617      screen updates while it happens. */
1618   packet_list_freeze();
1619
1620   if (redissect) {
1621     /* We need to re-initialize all the state information that protocols
1622        keep, because some preference that controls a dissector has changed,
1623        which might cause the state information to be constructed differently
1624        by that dissector. */
1625
1626     /* We might receive new packets while redissecting, and we don't
1627        want to dissect those before their time. */
1628     cf->redissecting = TRUE;
1629
1630     /* 'reset' dissection session */
1631     epan_free(cf->epan);
1632     if (cf->edt && cf->edt->pi.fd) {
1633       /* All pointers in "per frame proto data" for the currently selected
1634          packet are allocated in wmem_file_scope() and deallocated in epan_free().
1635          Free them here to avoid unintended usage in packet_list_clear(). */
1636       frame_data_destroy(cf->edt->pi.fd);
1637     }
1638     cf->epan = ws_epan_new(cf);
1639     cf->cinfo.epan = cf->epan;
1640
1641     /* A new Lua tap listener may be registered in lua_prime_all_fields()
1642        called via epan_new() / init_dissection() when reloading Lua plugins. */
1643     if (!create_proto_tree && have_filtering_tap_listeners()) {
1644       create_proto_tree = TRUE;
1645     }
1646
1647     /* We need to redissect the packets so we have to discard our old
1648      * packet list store. */
1649     packet_list_clear();
1650     add_to_packet_list = TRUE;
1651   }
1652
1653   /* We don't yet know which will be the first and last frames displayed. */
1654   cf->first_displayed = 0;
1655   cf->last_displayed = 0;
1656
1657   /* We currently don't display any packets */
1658   cf->displayed_count = 0;
1659
1660   /* Iterate through the list of frames.  Call a routine for each frame
1661      to check whether it should be displayed and, if so, add it to
1662      the display list. */
1663   cf->ref = NULL;
1664   cf->prev_dis = NULL;
1665   cf->prev_cap = NULL;
1666   cf->cum_bytes = 0;
1667
1668   cf_callback_invoke(cf_cb_file_rescan_started, cf);
1669
1670   g_timer_start(prog_timer);
1671   /* Count of packets at which we've looked. */
1672   count = 0;
1673   /* Progress so far. */
1674   progbar_val = 0.0f;
1675
1676   cf->stop_flag = FALSE;
1677   g_get_current_time(&start_time);
1678
1679   /* no previous row yet */
1680   prev_frame_num = -1;
1681   prev_frame = NULL;
1682
1683   preceding_frame_num = -1;
1684   preceding_frame = NULL;
1685   following_frame_num = -1;
1686   following_frame = NULL;
1687
1688   selected_frame_seen = FALSE;
1689
1690   frames_count = cf->count;
1691
1692   epan_dissect_init(&edt, cf->epan, create_proto_tree, FALSE);
1693
1694   for (framenum = 1; framenum <= frames_count; framenum++) {
1695     fdata = frame_data_sequence_find(cf->frames, framenum);
1696
1697     /* Create the progress bar if necessary.
1698        We check on every iteration of the loop, so that it takes no
1699        longer than the standard time to create it (otherwise, for a
1700        large file, we might take considerably longer than that standard
1701        time in order to get to the next progress bar step). */
1702     if (progbar == NULL)
1703       progbar = delayed_create_progress_dlg(cf->window, action, action_item, TRUE,
1704                                             &cf->stop_flag,
1705                                             &start_time,
1706                                             progbar_val);
1707
1708     /*
1709      * Update the progress bar, but do it only after PROGBAR_UPDATE_INTERVAL
1710      * has elapsed. Calling update_progress_dlg and packets_bar_update will
1711      * likely trigger UI paint events, which might take a while depending on
1712      * the platform and display. Reset our timer *after* painting.
1713      */
1714     if (g_timer_elapsed(prog_timer, NULL) > PROGBAR_UPDATE_INTERVAL) {
1715       /* let's not divide by zero. I should never be started
1716        * with count == 0, so let's assert that
1717        */
1718       g_assert(cf->count > 0);
1719       progbar_val = (gfloat) count / frames_count;
1720
1721       if (progbar != NULL) {
1722         g_snprintf(status_str, sizeof(status_str),
1723                   "%4u of %u frames", count, frames_count);
1724         update_progress_dlg(progbar, progbar_val, status_str);
1725       }
1726
1727       g_timer_start(prog_timer);
1728     }
1729
1730     if (cf->stop_flag) {
1731       /* Well, the user decided to abort the filtering.  Just stop.
1732
1733          XXX - go back to the previous filter?  Users probably just
1734          want not to wait for a filtering operation to finish;
1735          unless we cancel by having no filter, reverting to the
1736          previous filter will probably be even more expensive than
1737          continuing the filtering, as it involves going back to the
1738          beginning and filtering, and even with no filter we currently
1739          have to re-generate the entire clist, which is also expensive.
1740
1741          I'm not sure what Network Monitor does, but it doesn't appear
1742          to give you an unfiltered display if you cancel. */
1743       break;
1744     }
1745
1746     count++;
1747
1748     if (redissect) {
1749       /* Since all state for the frame was destroyed, mark the frame
1750        * as not visited, free the GSList referring to the state
1751        * data (the per-frame data itself was freed by
1752        * "init_dissection()"), and null out the GSList pointer. */
1753       frame_data_reset(fdata);
1754       frames_count = cf->count;
1755     }
1756
1757     /* Frame dependencies from the previous dissection/filtering are no longer valid. */
1758     fdata->flags.dependent_of_displayed = 0;
1759
1760     if (!cf_read_record(cf, fdata))
1761       break; /* error reading the frame */
1762
1763     /* If the previous frame is displayed, and we haven't yet seen the
1764        selected frame, remember that frame - it's the closest one we've
1765        yet seen before the selected frame. */
1766     if (prev_frame_num != -1 && !selected_frame_seen && prev_frame->flags.passed_dfilter) {
1767       preceding_frame_num = prev_frame_num;
1768       preceding_frame = prev_frame;
1769     }
1770
1771     add_packet_to_packet_list(fdata, cf, &edt, dfcode,
1772                                     cinfo, &cf->phdr,
1773                                     ws_buffer_start_ptr(&cf->buf),
1774                                     add_to_packet_list);
1775
1776     /* If this frame is displayed, and this is the first frame we've
1777        seen displayed after the selected frame, remember this frame -
1778        it's the closest one we've yet seen at or after the selected
1779        frame. */
1780     if (fdata->flags.passed_dfilter && selected_frame_seen && following_frame_num == -1) {
1781       following_frame_num = fdata->num;
1782       following_frame = fdata;
1783     }
1784     if (fdata == selected_frame) {
1785       selected_frame_seen = TRUE;
1786       if (fdata->flags.passed_dfilter)
1787           selected_frame_num = fdata->num;
1788     }
1789
1790     /* Remember this frame - it'll be the previous frame
1791        on the next pass through the loop. */
1792     prev_frame_num = fdata->num;
1793     prev_frame = fdata;
1794   }
1795
1796   epan_dissect_cleanup(&edt);
1797
1798   /* We are done redissecting the packet list. */
1799   cf->redissecting = FALSE;
1800
1801   if (redissect) {
1802       frames_count = cf->count;
1803     /* Clear out what remains of the visited flags and per-frame data
1804        pointers.
1805
1806        XXX - that may cause various forms of bogosity when dissecting
1807        these frames, as they won't have been seen by this sequential
1808        pass, but the only alternative I see is to keep scanning them
1809        even though the user requested that the scan stop, and that
1810        would leave the user stuck with an Wireshark grinding on
1811        until it finishes.  Should we just stick them with that? */
1812     for (; framenum <= frames_count; framenum++) {
1813       fdata = frame_data_sequence_find(cf->frames, framenum);
1814       frame_data_reset(fdata);
1815     }
1816   }
1817
1818   /* We're done filtering the packets; destroy the progress bar if it
1819      was created. */
1820   if (progbar != NULL)
1821     destroy_progress_dlg(progbar);
1822   g_timer_destroy(prog_timer);
1823
1824   /* Unfreeze the packet list. */
1825   if (!add_to_packet_list)
1826     packet_list_recreate_visible_rows();
1827
1828   /* Compute the time it took to filter the file */
1829   compute_elapsed(cf, &start_time);
1830
1831   packet_list_thaw();
1832
1833   cf_callback_invoke(cf_cb_file_rescan_finished, cf);
1834
1835   if (selected_frame_num == -1) {
1836     /* The selected frame didn't pass the filter. */
1837     if (selected_frame == NULL) {
1838       /* That's because there *was* no selected frame.  Make the first
1839          displayed frame the current frame. */
1840       selected_frame_num = 0;
1841     } else {
1842       /* Find the nearest displayed frame to the selected frame (whether
1843          it's before or after that frame) and make that the current frame.
1844          If the next and previous displayed frames are equidistant from the
1845          selected frame, choose the next one. */
1846       g_assert(following_frame == NULL ||
1847                following_frame->num >= selected_frame->num);
1848       g_assert(preceding_frame == NULL ||
1849                preceding_frame->num <= selected_frame->num);
1850       if (following_frame == NULL) {
1851         /* No frame after the selected frame passed the filter, so we
1852            have to select the last displayed frame before the selected
1853            frame. */
1854         selected_frame_num = preceding_frame_num;
1855         selected_frame = preceding_frame;
1856       } else if (preceding_frame == NULL) {
1857         /* No frame before the selected frame passed the filter, so we
1858            have to select the first displayed frame after the selected
1859            frame. */
1860         selected_frame_num = following_frame_num;
1861         selected_frame = following_frame;
1862       } else {
1863         /* Frames before and after the selected frame passed the filter, so
1864            we'll select the previous frame */
1865         selected_frame_num = preceding_frame_num;
1866         selected_frame = preceding_frame;
1867       }
1868     }
1869   }
1870
1871   if (selected_frame_num == -1) {
1872     /* There are no frames displayed at all. */
1873     cf_unselect_packet(cf);
1874   } else {
1875     /* Either the frame that was selected passed the filter, or we've
1876        found the nearest displayed frame to that frame.  Select it, make
1877        it the focus row, and make it visible. */
1878     /* Set to invalid to force update of packet list and packet details */
1879     cf->current_row = -1;
1880     if (selected_frame_num == 0) {
1881       packet_list_select_first_row();
1882     }else{
1883       if (!packet_list_select_row_from_data(selected_frame)) {
1884         /* We didn't find a row corresponding to this frame.
1885            This means that the frame isn't being displayed currently,
1886            so we can't select it. */
1887         simple_message_box(ESD_TYPE_INFO, NULL,
1888                            "The capture file is probably not fully dissected.",
1889                            "End of capture exceeded.");
1890       }
1891     }
1892   }
1893
1894   /* Cleanup and release all dfilter resources */
1895   dfilter_free(dfcode);
1896 }
1897
1898
1899 /*
1900  * Scan through all frame data and recalculate the ref time
1901  * without rereading the file.
1902  * XXX - do we need a progres bar or is this fast enough?
1903  */
1904 static void
1905 ref_time_packets(capture_file *cf)
1906 {
1907   guint32     framenum;
1908   frame_data *fdata;
1909   nstime_t rel_ts;
1910
1911   cf->ref = NULL;
1912   cf->prev_dis = NULL;
1913   cf->cum_bytes = 0;
1914
1915   for (framenum = 1; framenum <= cf->count; framenum++) {
1916     fdata = frame_data_sequence_find(cf->frames, framenum);
1917
1918     /* just add some value here until we know if it is being displayed or not */
1919     fdata->cum_bytes = cf->cum_bytes + fdata->pkt_len;
1920
1921     /*
1922      *Timestamps
1923      */
1924
1925     /* If we don't have the time stamp of the first packet in the
1926      capture, it's because this is the first packet.  Save the time
1927      stamp of this packet as the time stamp of the first packet. */
1928     if (cf->ref == NULL)
1929         cf->ref = fdata;
1930       /* if this frames is marked as a reference time frame, reset
1931         firstsec and firstusec to this frame */
1932     if (fdata->flags.ref_time)
1933         cf->ref = fdata;
1934
1935     /* If we don't have the time stamp of the previous displayed packet,
1936      it's because this is the first displayed packet.  Save the time
1937      stamp of this packet as the time stamp of the previous displayed
1938      packet. */
1939     if (cf->prev_dis == NULL) {
1940         cf->prev_dis = fdata;
1941     }
1942
1943     /* Get the time elapsed between the first packet and this packet. */
1944     fdata->frame_ref_num = (fdata != cf->ref) ? cf->ref->num : 0;
1945     nstime_delta(&rel_ts, &fdata->abs_ts, &cf->ref->abs_ts);
1946
1947     /* If it's greater than the current elapsed time, set the elapsed time
1948      to it (we check for "greater than" so as not to be confused by
1949      time moving backwards). */
1950     if ((gint32)cf->elapsed_time.secs < rel_ts.secs
1951         || ((gint32)cf->elapsed_time.secs == rel_ts.secs && (gint32)cf->elapsed_time.nsecs < rel_ts.nsecs)) {
1952         cf->elapsed_time = rel_ts;
1953     }
1954
1955     /* If this frame is displayed, get the time elapsed between the
1956      previous displayed packet and this packet. */
1957     if ( fdata->flags.passed_dfilter ) {
1958         fdata->prev_dis_num = cf->prev_dis->num;
1959         cf->prev_dis = fdata;
1960     }
1961
1962     /*
1963      * Byte counts
1964      */
1965     if ( (fdata->flags.passed_dfilter) || (fdata->flags.ref_time) ) {
1966         /* This frame either passed the display filter list or is marked as
1967         a time reference frame.  All time reference frames are displayed
1968         even if they don't pass the display filter */
1969         if (fdata->flags.ref_time) {
1970             /* if this was a TIME REF frame we should reset the cum_bytes field */
1971             cf->cum_bytes = fdata->pkt_len;
1972             fdata->cum_bytes = cf->cum_bytes;
1973         } else {
1974             /* increase cum_bytes with this packets length */
1975             cf->cum_bytes += fdata->pkt_len;
1976         }
1977     }
1978   }
1979 }
1980
1981 typedef enum {
1982   PSP_FINISHED,
1983   PSP_STOPPED,
1984   PSP_FAILED
1985 } psp_return_t;
1986
1987 static psp_return_t
1988 process_specified_records(capture_file *cf, packet_range_t *range,
1989     const char *string1, const char *string2, gboolean terminate_is_stop,
1990     gboolean (*callback)(capture_file *, frame_data *,
1991                          struct wtap_pkthdr *, const guint8 *, void *),
1992     void *callback_args,
1993     gboolean show_progress_bar)
1994 {
1995   guint32          framenum;
1996   frame_data      *fdata;
1997   Buffer           buf;
1998   psp_return_t     ret     = PSP_FINISHED;
1999
2000   progdlg_t       *progbar = NULL;
2001   GTimer          *prog_timer = g_timer_new();
2002   int              progbar_count;
2003   float            progbar_val;
2004   GTimeVal         progbar_start_time;
2005   gchar            progbar_status_str[100];
2006   range_process_e  process_this;
2007   struct wtap_pkthdr phdr;
2008
2009   wtap_phdr_init(&phdr);
2010   ws_buffer_init(&buf, 1500);
2011
2012   g_timer_start(prog_timer);
2013   /* Count of packets at which we've looked. */
2014   progbar_count = 0;
2015   /* Progress so far. */
2016   progbar_val = 0.0f;
2017
2018   cf->stop_flag = FALSE;
2019   g_get_current_time(&progbar_start_time);
2020
2021   if (range != NULL)
2022     packet_range_process_init(range);
2023
2024   /* Iterate through all the packets, printing the packets that
2025      were selected by the current display filter.  */
2026   for (framenum = 1; framenum <= cf->count; framenum++) {
2027     fdata = frame_data_sequence_find(cf->frames, framenum);
2028
2029     /* Create the progress bar if necessary.
2030        We check on every iteration of the loop, so that it takes no
2031        longer than the standard time to create it (otherwise, for a
2032        large file, we might take considerably longer than that standard
2033        time in order to get to the next progress bar step). */
2034     if (show_progress_bar && progbar == NULL)
2035       progbar = delayed_create_progress_dlg(cf->window, string1, string2,
2036                                             terminate_is_stop,
2037                                             &cf->stop_flag,
2038                                             &progbar_start_time,
2039                                             progbar_val);
2040
2041     /*
2042      * Update the progress bar, but do it only after PROGBAR_UPDATE_INTERVAL
2043      * has elapsed. Calling update_progress_dlg and packets_bar_update will
2044      * likely trigger UI paint events, which might take a while depending on
2045      * the platform and display. Reset our timer *after* painting.
2046      */
2047     if (progbar && g_timer_elapsed(prog_timer, NULL) > PROGBAR_UPDATE_INTERVAL) {
2048       /* let's not divide by zero. I should never be started
2049        * with count == 0, so let's assert that
2050        */
2051       g_assert(cf->count > 0);
2052       progbar_val = (gfloat) progbar_count / cf->count;
2053
2054       g_snprintf(progbar_status_str, sizeof(progbar_status_str),
2055                   "%4u of %u packets", progbar_count, cf->count);
2056       update_progress_dlg(progbar, progbar_val, progbar_status_str);
2057
2058       g_timer_start(prog_timer);
2059     }
2060
2061     if (cf->stop_flag) {
2062       /* Well, the user decided to abort the operation.  Just stop,
2063          and arrange to return PSP_STOPPED to our caller, so they know
2064          it was stopped explicitly. */
2065       ret = PSP_STOPPED;
2066       break;
2067     }
2068
2069     progbar_count++;
2070
2071     if (range != NULL) {
2072       /* do we have to process this packet? */
2073       process_this = packet_range_process_packet(range, fdata);
2074       if (process_this == range_process_next) {
2075         /* this packet uninteresting, continue with next one */
2076         continue;
2077       } else if (process_this == range_processing_finished) {
2078         /* all interesting packets processed, stop the loop */
2079         break;
2080       }
2081     }
2082
2083     /* Get the packet */
2084     if (!cf_read_record_r(cf, fdata, &phdr, &buf)) {
2085       /* Attempt to get the packet failed. */
2086       ret = PSP_FAILED;
2087       break;
2088     }
2089     /* Process the packet */
2090     if (!callback(cf, fdata, &phdr, ws_buffer_start_ptr(&buf), callback_args)) {
2091       /* Callback failed.  We assume it reported the error appropriately. */
2092       ret = PSP_FAILED;
2093       break;
2094     }
2095   }
2096
2097   /* We're done printing the packets; destroy the progress bar if
2098      it was created. */
2099   if (progbar != NULL)
2100     destroy_progress_dlg(progbar);
2101   g_timer_destroy(prog_timer);
2102
2103   wtap_phdr_cleanup(&phdr);
2104   ws_buffer_free(&buf);
2105
2106   return ret;
2107 }
2108
2109 typedef struct {
2110   epan_dissect_t edt;
2111   column_info *cinfo;
2112 } retap_callback_args_t;
2113
2114 static gboolean
2115 retap_packet(capture_file *cf, frame_data *fdata,
2116              struct wtap_pkthdr *phdr, const guint8 *pd,
2117              void *argsp)
2118 {
2119   retap_callback_args_t *args = (retap_callback_args_t *)argsp;
2120
2121   epan_dissect_run_with_taps(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, args->cinfo);
2122   epan_dissect_reset(&args->edt);
2123
2124   return TRUE;
2125 }
2126
2127 cf_read_status_t
2128 cf_retap_packets(capture_file *cf)
2129 {
2130   packet_range_t        range;
2131   retap_callback_args_t callback_args;
2132   gboolean              construct_protocol_tree;
2133   gboolean              filtering_tap_listeners;
2134   guint                 tap_flags;
2135   psp_return_t          ret;
2136
2137   /* Presumably the user closed the capture file. */
2138   if (cf == NULL) {
2139     return CF_READ_ABORTED;
2140   }
2141
2142   cf_callback_invoke(cf_cb_file_retap_started, cf);
2143
2144   /* Do we have any tap listeners with filters? */
2145   filtering_tap_listeners = have_filtering_tap_listeners();
2146
2147   tap_flags = union_of_tap_listener_flags();
2148
2149   /* If any tap listeners have filters, or require the protocol tree,
2150      construct the protocol tree. */
2151   construct_protocol_tree = filtering_tap_listeners ||
2152                             (tap_flags & TL_REQUIRES_PROTO_TREE);
2153
2154   /* If any tap listeners require the columns, construct them. */
2155   callback_args.cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
2156
2157   /* Reset the tap listeners. */
2158   reset_tap_listeners();
2159
2160   epan_dissect_init(&callback_args.edt, cf->epan, construct_protocol_tree, FALSE);
2161
2162   /* Iterate through the list of packets, dissecting all packets and
2163      re-running the taps. */
2164   packet_range_init(&range, cf);
2165   packet_range_process_init(&range);
2166
2167   ret = process_specified_records(cf, &range, "Recalculating statistics on",
2168                                   "all packets", TRUE, retap_packet,
2169                                   &callback_args, TRUE);
2170
2171   epan_dissect_cleanup(&callback_args.edt);
2172
2173   cf_callback_invoke(cf_cb_file_retap_finished, cf);
2174
2175   switch (ret) {
2176   case PSP_FINISHED:
2177     /* Completed successfully. */
2178     return CF_READ_OK;
2179
2180   case PSP_STOPPED:
2181     /* Well, the user decided to abort the refiltering.
2182        Return CF_READ_ABORTED so our caller knows they did that. */
2183     return CF_READ_ABORTED;
2184
2185   case PSP_FAILED:
2186     /* Error while retapping. */
2187     return CF_READ_ERROR;
2188   }
2189
2190   g_assert_not_reached();
2191   return CF_READ_OK;
2192 }
2193
2194 typedef struct {
2195   print_args_t *print_args;
2196   gboolean      print_header_line;
2197   char         *header_line_buf;
2198   int           header_line_buf_len;
2199   gboolean      print_formfeed;
2200   gboolean      print_separator;
2201   char         *line_buf;
2202   int           line_buf_len;
2203   gint         *col_widths;
2204   int           num_visible_cols;
2205   gint         *visible_cols;
2206   epan_dissect_t edt;
2207 } print_callback_args_t;
2208
2209 static gboolean
2210 print_packet(capture_file *cf, frame_data *fdata,
2211              struct wtap_pkthdr *phdr, const guint8 *pd,
2212              void *argsp)
2213 {
2214   print_callback_args_t *args = (print_callback_args_t *)argsp;
2215   int             i;
2216   char           *cp;
2217   int             line_len;
2218   int             column_len;
2219   int             cp_off;
2220   char            bookmark_name[9+10+1];  /* "__frameNNNNNNNNNN__\0" */
2221   char            bookmark_title[6+10+1]; /* "Frame NNNNNNNNNN__\0"  */
2222   col_item_t*     col_item;
2223
2224   /* Fill in the column information if we're printing the summary
2225      information. */
2226   if (args->print_args->print_summary) {
2227     col_custom_prime_edt(&args->edt, &cf->cinfo);
2228     epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
2229     epan_dissect_fill_in_columns(&args->edt, FALSE, TRUE);
2230   } else
2231     epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
2232
2233   if (args->print_formfeed) {
2234     if (!new_page(args->print_args->stream))
2235       goto fail;
2236   } else {
2237       if (args->print_separator) {
2238         if (!print_line(args->print_args->stream, 0, ""))
2239           goto fail;
2240       }
2241   }
2242
2243   /*
2244    * We generate bookmarks, if the output format supports them.
2245    * The name is "__frameN__".
2246    */
2247   g_snprintf(bookmark_name, sizeof bookmark_name, "__frame%u__", fdata->num);
2248
2249   if (args->print_args->print_summary) {
2250     if (!args->print_args->print_col_headings)
2251         args->print_header_line = FALSE;
2252     if (args->print_header_line) {
2253       if (!print_line(args->print_args->stream, 0, args->header_line_buf))
2254         goto fail;
2255       args->print_header_line = FALSE;  /* we might not need to print any more */
2256     }
2257     cp = &args->line_buf[0];
2258     line_len = 0;
2259     for (i = 0; i < args->num_visible_cols; i++) {
2260       col_item = &cf->cinfo.columns[args->visible_cols[i]];
2261       /* Find the length of the string for this column. */
2262       column_len = (int) strlen(col_item->col_data);
2263       if (args->col_widths[i] > column_len)
2264          column_len = args->col_widths[i];
2265
2266       /* Make sure there's room in the line buffer for the column; if not,
2267          double its length. */
2268       line_len += column_len + 1;   /* "+1" for space */
2269       if (line_len > args->line_buf_len) {
2270         cp_off = (int) (cp - args->line_buf);
2271         args->line_buf_len = 2 * line_len;
2272         args->line_buf = (char *)g_realloc(args->line_buf, args->line_buf_len + 1);
2273         cp = args->line_buf + cp_off;
2274       }
2275
2276       /* Right-justify the packet number column. */
2277       if (col_item->col_fmt == COL_NUMBER)
2278         g_snprintf(cp, column_len+1, "%*s", args->col_widths[i], col_item->col_data);
2279       else
2280         g_snprintf(cp, column_len+1, "%-*s", args->col_widths[i], col_item->col_data);
2281       cp += column_len;
2282       if (i != args->num_visible_cols - 1)
2283         *cp++ = ' ';
2284     }
2285     *cp = '\0';
2286
2287     /*
2288      * Generate a bookmark, using the summary line as the title.
2289      */
2290     if (!print_bookmark(args->print_args->stream, bookmark_name,
2291                         args->line_buf))
2292       goto fail;
2293
2294     if (!print_line(args->print_args->stream, 0, args->line_buf))
2295       goto fail;
2296   } else {
2297     /*
2298      * Generate a bookmark, using "Frame N" as the title, as we're not
2299      * printing the summary line.
2300      */
2301     g_snprintf(bookmark_title, sizeof bookmark_title, "Frame %u", fdata->num);
2302     if (!print_bookmark(args->print_args->stream, bookmark_name,
2303                         bookmark_title))
2304       goto fail;
2305   } /* if (print_summary) */
2306
2307   if (args->print_args->print_dissections != print_dissections_none) {
2308     if (args->print_args->print_summary) {
2309       /* Separate the summary line from the tree with a blank line. */
2310       if (!print_line(args->print_args->stream, 0, ""))
2311         goto fail;
2312     }
2313
2314     /* Print the information in that tree. */
2315     if (!proto_tree_print(args->print_args, &args->edt, NULL, args->print_args->stream))
2316       goto fail;
2317
2318     /* Print a blank line if we print anything after this (aka more than one packet). */
2319     args->print_separator = TRUE;
2320
2321     /* Print a header line if we print any more packet summaries */
2322     if (args->print_args->print_col_headings)
2323         args->print_header_line = TRUE;
2324   }
2325
2326   if (args->print_args->print_hex) {
2327     if (args->print_args->print_summary || (args->print_args->print_dissections != print_dissections_none)) {
2328       if (!print_line(args->print_args->stream, 0, ""))
2329         goto fail;
2330     }
2331     /* Print the full packet data as hex. */
2332     if (!print_hex_data(args->print_args->stream, &args->edt))
2333       goto fail;
2334
2335     /* Print a blank line if we print anything after this (aka more than one packet). */
2336     args->print_separator = TRUE;
2337
2338     /* Print a header line if we print any more packet summaries */
2339     if (args->print_args->print_col_headings)
2340         args->print_header_line = TRUE;
2341   } /* if (args->print_args->print_dissections != print_dissections_none) */
2342
2343   epan_dissect_reset(&args->edt);
2344
2345   /* do we want to have a formfeed between each packet from now on? */
2346   if (args->print_args->print_formfeed) {
2347     args->print_formfeed = TRUE;
2348   }
2349
2350   return TRUE;
2351
2352 fail:
2353   epan_dissect_reset(&args->edt);
2354   return FALSE;
2355 }
2356
2357 cf_print_status_t
2358 cf_print_packets(capture_file *cf, print_args_t *print_args,
2359                  gboolean show_progress_bar)
2360 {
2361   print_callback_args_t callback_args;
2362   gint          data_width;
2363   char         *cp;
2364   int           i, cp_off, column_len, line_len;
2365   int           num_visible_col = 0, last_visible_col = 0, visible_col_count;
2366   psp_return_t  ret;
2367   GList        *clp;
2368   fmt_data     *cfmt;
2369   gboolean      proto_tree_needed;
2370
2371   callback_args.print_args = print_args;
2372   callback_args.print_header_line = print_args->print_col_headings;
2373   callback_args.header_line_buf = NULL;
2374   callback_args.header_line_buf_len = 256;
2375   callback_args.print_formfeed = FALSE;
2376   callback_args.print_separator = FALSE;
2377   callback_args.line_buf = NULL;
2378   callback_args.line_buf_len = 256;
2379   callback_args.col_widths = NULL;
2380   callback_args.num_visible_cols = 0;
2381   callback_args.visible_cols = NULL;
2382
2383   if (!print_preamble(print_args->stream, cf->filename, get_ws_vcs_version_info())) {
2384     destroy_print_stream(print_args->stream);
2385     return CF_PRINT_WRITE_ERROR;
2386   }
2387
2388   if (print_args->print_summary) {
2389     /* We're printing packet summaries.  Allocate the header line buffer
2390        and get the column widths. */
2391     callback_args.header_line_buf = (char *)g_malloc(callback_args.header_line_buf_len + 1);
2392
2393     /* Find the number of visible columns and the last visible column */
2394     for (i = 0; i < prefs.num_cols; i++) {
2395
2396         clp = g_list_nth(prefs.col_list, i);
2397         if (clp == NULL) /* Sanity check, Invalid column requested */
2398             continue;
2399
2400         cfmt = (fmt_data *) clp->data;
2401         if (cfmt->visible) {
2402             num_visible_col++;
2403             last_visible_col = i;
2404         }
2405     }
2406
2407     /* Find the widths for each of the columns - maximum of the
2408        width of the title and the width of the data - and construct
2409        a buffer with a line containing the column titles. */
2410     callback_args.num_visible_cols = num_visible_col;
2411     callback_args.col_widths = (gint *) g_malloc(sizeof(gint) * num_visible_col);
2412     callback_args.visible_cols = (gint *) g_malloc(sizeof(gint) * num_visible_col);
2413     cp = &callback_args.header_line_buf[0];
2414     line_len = 0;
2415     visible_col_count = 0;
2416     for (i = 0; i < cf->cinfo.num_cols; i++) {
2417
2418       clp = g_list_nth(prefs.col_list, i);
2419       if (clp == NULL) /* Sanity check, Invalid column requested */
2420           continue;
2421
2422       cfmt = (fmt_data *) clp->data;
2423       if (cfmt->visible == FALSE)
2424           continue;
2425
2426       /* Save the order of visible columns */
2427       callback_args.visible_cols[visible_col_count] = i;
2428
2429       /* Don't pad the last column. */
2430       if (i == last_visible_col)
2431         callback_args.col_widths[visible_col_count] = 0;
2432       else {
2433         callback_args.col_widths[visible_col_count] = (gint) strlen(cf->cinfo.columns[i].col_title);
2434         data_width = get_column_char_width(get_column_format(i));
2435         if (data_width > callback_args.col_widths[visible_col_count])
2436           callback_args.col_widths[visible_col_count] = data_width;
2437       }
2438
2439       /* Find the length of the string for this column. */
2440       column_len = (int) strlen(cf->cinfo.columns[i].col_title);
2441       if (callback_args.col_widths[i] > column_len)
2442         column_len = callback_args.col_widths[visible_col_count];
2443
2444       /* Make sure there's room in the line buffer for the column; if not,
2445          double its length. */
2446       line_len += column_len + 1;   /* "+1" for space */
2447       if (line_len > callback_args.header_line_buf_len) {
2448         cp_off = (int) (cp - callback_args.header_line_buf);
2449         callback_args.header_line_buf_len = 2 * line_len;
2450         callback_args.header_line_buf = (char *)g_realloc(callback_args.header_line_buf,
2451                                                   callback_args.header_line_buf_len + 1);
2452         cp = callback_args.header_line_buf + cp_off;
2453       }
2454
2455       /* Right-justify the packet number column. */
2456 /*      if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2457         g_snprintf(cp, column_len+1, "%*s", callback_args.col_widths[visible_col_count], cf->cinfo.columns[i].col_title);
2458       else*/
2459       g_snprintf(cp, column_len+1, "%-*s", callback_args.col_widths[visible_col_count], cf->cinfo.columns[i].col_title);
2460       cp += column_len;
2461       if (i != cf->cinfo.num_cols - 1)
2462         *cp++ = ' ';
2463
2464       visible_col_count++;
2465     }
2466     *cp = '\0';
2467
2468     /* Now start out the main line buffer with the same length as the
2469        header line buffer. */
2470     callback_args.line_buf_len = callback_args.header_line_buf_len;
2471     callback_args.line_buf = (char *)g_malloc(callback_args.line_buf_len + 1);
2472   } /* if (print_summary) */
2473
2474   /* Create the protocol tree, and make it visible, if we're printing
2475      the dissection or the hex data.
2476      XXX - do we need it if we're just printing the hex data? */
2477   proto_tree_needed =
2478       callback_args.print_args->print_dissections != print_dissections_none ||
2479       callback_args.print_args->print_hex ||
2480       have_custom_cols(&cf->cinfo) || have_field_extractors();
2481   epan_dissect_init(&callback_args.edt, cf->epan, proto_tree_needed, proto_tree_needed);
2482
2483   /* Iterate through the list of packets, printing the packets we were
2484      told to print. */
2485   ret = process_specified_records(cf, &print_args->range, "Printing",
2486                                   "selected packets", TRUE, print_packet,
2487                                   &callback_args, show_progress_bar);
2488   epan_dissect_cleanup(&callback_args.edt);
2489   g_free(callback_args.header_line_buf);
2490   g_free(callback_args.line_buf);
2491   g_free(callback_args.col_widths);
2492   g_free(callback_args.visible_cols);
2493
2494   switch (ret) {
2495
2496   case PSP_FINISHED:
2497     /* Completed successfully. */
2498     break;
2499
2500   case PSP_STOPPED:
2501     /* Well, the user decided to abort the printing.
2502
2503        XXX - note that what got generated before they did that
2504        will get printed if we're piping to a print program; we'd
2505        have to write to a file and then hand that to the print
2506        program to make it actually not print anything. */
2507     break;
2508
2509   case PSP_FAILED:
2510     /* Error while printing.
2511
2512        XXX - note that what got generated before they did that
2513        will get printed if we're piping to a print program; we'd
2514        have to write to a file and then hand that to the print
2515        program to make it actually not print anything. */
2516     destroy_print_stream(print_args->stream);
2517     return CF_PRINT_WRITE_ERROR;
2518   }
2519
2520   if (!print_finale(print_args->stream)) {
2521     destroy_print_stream(print_args->stream);
2522     return CF_PRINT_WRITE_ERROR;
2523   }
2524
2525   if (!destroy_print_stream(print_args->stream))
2526     return CF_PRINT_WRITE_ERROR;
2527
2528   return CF_PRINT_OK;
2529 }
2530
2531 typedef struct {
2532   FILE *fh;
2533   epan_dissect_t edt;
2534   print_args_t *print_args;
2535 } write_packet_callback_args_t;
2536
2537 static gboolean
2538 write_pdml_packet(capture_file *cf, frame_data *fdata,
2539                   struct wtap_pkthdr *phdr, const guint8 *pd,
2540           void *argsp)
2541 {
2542   write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
2543
2544   /* Create the protocol tree, but don't fill in the column information. */
2545   epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
2546
2547   /* Write out the information in that tree. */
2548   write_pdml_proto_tree(NULL, NULL, &args->edt, args->fh);
2549
2550   epan_dissect_reset(&args->edt);
2551
2552   return !ferror(args->fh);
2553 }
2554
2555 cf_print_status_t
2556 cf_write_pdml_packets(capture_file *cf, print_args_t *print_args)
2557 {
2558   write_packet_callback_args_t callback_args;
2559   FILE         *fh;
2560   psp_return_t  ret;
2561
2562   fh = ws_fopen(print_args->file, "w");
2563   if (fh == NULL)
2564     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2565
2566   write_pdml_preamble(fh, cf->filename);
2567   if (ferror(fh)) {
2568     fclose(fh);
2569     return CF_PRINT_WRITE_ERROR;
2570   }
2571
2572   callback_args.fh = fh;
2573   callback_args.print_args = print_args;
2574   epan_dissect_init(&callback_args.edt, cf->epan, TRUE, TRUE);
2575
2576   /* Iterate through the list of packets, printing the packets we were
2577      told to print. */
2578   ret = process_specified_records(cf, &print_args->range, "Writing PDML",
2579                                   "selected packets", TRUE,
2580                                   write_pdml_packet, &callback_args, TRUE);
2581
2582   epan_dissect_cleanup(&callback_args.edt);
2583
2584   switch (ret) {
2585
2586   case PSP_FINISHED:
2587     /* Completed successfully. */
2588     break;
2589
2590   case PSP_STOPPED:
2591     /* Well, the user decided to abort the printing. */
2592     break;
2593
2594   case PSP_FAILED:
2595     /* Error while printing. */
2596     fclose(fh);
2597     return CF_PRINT_WRITE_ERROR;
2598   }
2599
2600   write_pdml_finale(fh);
2601   if (ferror(fh)) {
2602     fclose(fh);
2603     return CF_PRINT_WRITE_ERROR;
2604   }
2605
2606   /* XXX - check for an error */
2607   fclose(fh);
2608
2609   return CF_PRINT_OK;
2610 }
2611
2612 static gboolean
2613 write_psml_packet(capture_file *cf, frame_data *fdata,
2614                   struct wtap_pkthdr *phdr, const guint8 *pd,
2615           void *argsp)
2616 {
2617   write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
2618
2619   /* Fill in the column information */
2620   col_custom_prime_edt(&args->edt, &cf->cinfo);
2621   epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
2622   epan_dissect_fill_in_columns(&args->edt, FALSE, TRUE);
2623
2624   /* Write out the column information. */
2625   write_psml_columns(&args->edt, args->fh);
2626
2627   epan_dissect_reset(&args->edt);
2628
2629   return !ferror(args->fh);
2630 }
2631
2632 cf_print_status_t
2633 cf_write_psml_packets(capture_file *cf, print_args_t *print_args)
2634 {
2635   write_packet_callback_args_t callback_args;
2636   FILE         *fh;
2637   psp_return_t  ret;
2638
2639   gboolean proto_tree_needed;
2640
2641   fh = ws_fopen(print_args->file, "w");
2642   if (fh == NULL)
2643     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2644
2645   write_psml_preamble(&cf->cinfo, fh);
2646   if (ferror(fh)) {
2647     fclose(fh);
2648     return CF_PRINT_WRITE_ERROR;
2649   }
2650
2651   callback_args.fh = fh;
2652   callback_args.print_args = print_args;
2653
2654   /* Fill in the column information, only create the protocol tree
2655      if having custom columns or field extractors. */
2656   proto_tree_needed = have_custom_cols(&cf->cinfo) || have_field_extractors();
2657   epan_dissect_init(&callback_args.edt, cf->epan, proto_tree_needed, proto_tree_needed);
2658
2659   /* Iterate through the list of packets, printing the packets we were
2660      told to print. */
2661   ret = process_specified_records(cf, &print_args->range, "Writing PSML",
2662                                   "selected packets", TRUE,
2663                                   write_psml_packet, &callback_args, TRUE);
2664
2665   epan_dissect_cleanup(&callback_args.edt);
2666
2667   switch (ret) {
2668
2669   case PSP_FINISHED:
2670     /* Completed successfully. */
2671     break;
2672
2673   case PSP_STOPPED:
2674     /* Well, the user decided to abort the printing. */
2675     break;
2676
2677   case PSP_FAILED:
2678     /* Error while printing. */
2679     fclose(fh);
2680     return CF_PRINT_WRITE_ERROR;
2681   }
2682
2683   write_psml_finale(fh);
2684   if (ferror(fh)) {
2685     fclose(fh);
2686     return CF_PRINT_WRITE_ERROR;
2687   }
2688
2689   /* XXX - check for an error */
2690   fclose(fh);
2691
2692   return CF_PRINT_OK;
2693 }
2694
2695 static gboolean
2696 write_csv_packet(capture_file *cf, frame_data *fdata,
2697                  struct wtap_pkthdr *phdr, const guint8 *pd,
2698                  void *argsp)
2699 {
2700   write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
2701
2702   /* Fill in the column information */
2703   col_custom_prime_edt(&args->edt, &cf->cinfo);
2704   epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
2705   epan_dissect_fill_in_columns(&args->edt, FALSE, TRUE);
2706
2707   /* Write out the column information. */
2708   write_csv_columns(&args->edt, args->fh);
2709
2710   epan_dissect_reset(&args->edt);
2711
2712   return !ferror(args->fh);
2713 }
2714
2715 cf_print_status_t
2716 cf_write_csv_packets(capture_file *cf, print_args_t *print_args)
2717 {
2718   write_packet_callback_args_t callback_args;
2719   gboolean        proto_tree_needed;
2720   FILE         *fh;
2721   psp_return_t  ret;
2722
2723   fh = ws_fopen(print_args->file, "w");
2724   if (fh == NULL)
2725     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2726
2727   write_csv_column_titles(&cf->cinfo, fh);
2728   if (ferror(fh)) {
2729     fclose(fh);
2730     return CF_PRINT_WRITE_ERROR;
2731   }
2732
2733   callback_args.fh = fh;
2734   callback_args.print_args = print_args;
2735
2736   /* only create the protocol tree if having custom columns or field extractors. */
2737   proto_tree_needed = have_custom_cols(&cf->cinfo) || have_field_extractors();
2738   epan_dissect_init(&callback_args.edt, cf->epan, proto_tree_needed, proto_tree_needed);
2739
2740   /* Iterate through the list of packets, printing the packets we were
2741      told to print. */
2742   ret = process_specified_records(cf, &print_args->range, "Writing CSV",
2743                                   "selected packets", TRUE,
2744                                   write_csv_packet, &callback_args, TRUE);
2745
2746   epan_dissect_cleanup(&callback_args.edt);
2747
2748   switch (ret) {
2749
2750   case PSP_FINISHED:
2751     /* Completed successfully. */
2752     break;
2753
2754   case PSP_STOPPED:
2755     /* Well, the user decided to abort the printing. */
2756     break;
2757
2758   case PSP_FAILED:
2759     /* Error while printing. */
2760     fclose(fh);
2761     return CF_PRINT_WRITE_ERROR;
2762   }
2763
2764   /* XXX - check for an error */
2765   fclose(fh);
2766
2767   return CF_PRINT_OK;
2768 }
2769
2770 static gboolean
2771 carrays_write_packet(capture_file *cf, frame_data *fdata,
2772              struct wtap_pkthdr *phdr,
2773              const guint8 *pd, void *argsp)
2774 {
2775   write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
2776
2777   epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
2778   write_carrays_hex_data(fdata->num, args->fh, &args->edt);
2779   epan_dissect_reset(&args->edt);
2780
2781   return !ferror(args->fh);
2782 }
2783
2784 cf_print_status_t
2785 cf_write_carrays_packets(capture_file *cf, print_args_t *print_args)
2786 {
2787   write_packet_callback_args_t callback_args;
2788   FILE         *fh;
2789   psp_return_t  ret;
2790
2791   fh = ws_fopen(print_args->file, "w");
2792
2793   if (fh == NULL)
2794     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2795
2796   if (ferror(fh)) {
2797     fclose(fh);
2798     return CF_PRINT_WRITE_ERROR;
2799   }
2800
2801   callback_args.fh = fh;
2802   callback_args.print_args = print_args;
2803   epan_dissect_init(&callback_args.edt, cf->epan, TRUE, TRUE);
2804
2805   /* Iterate through the list of packets, printing the packets we were
2806      told to print. */
2807   ret = process_specified_records(cf, &print_args->range,
2808                                   "Writing C Arrays",
2809                                   "selected packets", TRUE,
2810                                   carrays_write_packet, &callback_args, TRUE);
2811
2812   epan_dissect_cleanup(&callback_args.edt);
2813
2814   switch (ret) {
2815   case PSP_FINISHED:
2816     /* Completed successfully. */
2817     break;
2818   case PSP_STOPPED:
2819     /* Well, the user decided to abort the printing. */
2820     break;
2821   case PSP_FAILED:
2822     /* Error while printing. */
2823     fclose(fh);
2824     return CF_PRINT_WRITE_ERROR;
2825   }
2826
2827   fclose(fh);
2828   return CF_PRINT_OK;
2829 }
2830
2831 static gboolean
2832 write_json_packet(capture_file *cf, frame_data *fdata,
2833                   struct wtap_pkthdr *phdr, const guint8 *pd,
2834           void *argsp)
2835 {
2836   write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
2837
2838   /* Create the protocol tree, but don't fill in the column information. */
2839   epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
2840
2841   /* Write out the information in that tree. */
2842   write_json_proto_tree(NULL, args->print_args, NULL, &args->edt, args->fh);
2843
2844   epan_dissect_reset(&args->edt);
2845
2846   return !ferror(args->fh);
2847 }
2848
2849 cf_print_status_t
2850 cf_write_json_packets(capture_file *cf, print_args_t *print_args)
2851 {
2852   write_packet_callback_args_t callback_args;
2853   FILE         *fh;
2854   psp_return_t  ret;
2855
2856   fh = ws_fopen(print_args->file, "w");
2857   if (fh == NULL)
2858     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2859
2860   write_json_preamble(fh);
2861   if (ferror(fh)) {
2862     fclose(fh);
2863     return CF_PRINT_WRITE_ERROR;
2864   }
2865
2866   callback_args.fh = fh;
2867   callback_args.print_args = print_args;
2868   epan_dissect_init(&callback_args.edt, cf->epan, TRUE, TRUE);
2869
2870   /* Iterate through the list of packets, printing the packets we were
2871      told to print. */
2872   ret = process_specified_records(cf, &print_args->range, "Writing PDML",
2873                                   "selected packets", TRUE,
2874                                   write_json_packet, &callback_args, TRUE);
2875
2876   epan_dissect_cleanup(&callback_args.edt);
2877
2878   switch (ret) {
2879
2880   case PSP_FINISHED:
2881     /* Completed successfully. */
2882     break;
2883
2884   case PSP_STOPPED:
2885     /* Well, the user decided to abort the printing. */
2886     break;
2887
2888   case PSP_FAILED:
2889     /* Error while printing. */
2890     fclose(fh);
2891     return CF_PRINT_WRITE_ERROR;
2892   }
2893
2894   write_json_finale(fh);
2895   if (ferror(fh)) {
2896     fclose(fh);
2897     return CF_PRINT_WRITE_ERROR;
2898   }
2899
2900   /* XXX - check for an error */
2901   fclose(fh);
2902
2903   return CF_PRINT_OK;
2904 }
2905
2906 gboolean
2907 cf_find_packet_protocol_tree(capture_file *cf, const char *string,
2908                              search_direction dir)
2909 {
2910   match_data mdata;
2911
2912   mdata.string = string;
2913   mdata.string_len = strlen(string);
2914   return find_packet(cf, match_protocol_tree, &mdata, dir);
2915 }
2916
2917 gboolean
2918 cf_find_string_protocol_tree(capture_file *cf, proto_tree *tree,  match_data *mdata)
2919 {
2920   mdata->frame_matched = FALSE;
2921   mdata->string = convert_string_case(cf->sfilter, cf->case_type);
2922   mdata->string_len = strlen(mdata->string);
2923   mdata->cf = cf;
2924   /* Iterate through all the nodes looking for matching text */
2925   proto_tree_children_foreach(tree, match_subtree_text, mdata);
2926   return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
2927 }
2928
2929 static match_result
2930 match_protocol_tree(capture_file *cf, frame_data *fdata, void *criterion)
2931 {
2932   match_data     *mdata = (match_data *)criterion;
2933   epan_dissect_t  edt;
2934
2935   /* Load the frame's data. */
2936   if (!cf_read_record(cf, fdata)) {
2937     /* Attempt to get the packet failed. */
2938     return MR_ERROR;
2939   }
2940
2941   /* Construct the protocol tree, including the displayed text */
2942   epan_dissect_init(&edt, cf->epan, TRUE, TRUE);
2943   /* We don't need the column information */
2944   epan_dissect_run(&edt, cf->cd_t, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata, NULL);
2945
2946   /* Iterate through all the nodes, seeing if they have text that matches. */
2947   mdata->cf = cf;
2948   mdata->frame_matched = FALSE;
2949   proto_tree_children_foreach(edt.tree, match_subtree_text, mdata);
2950   epan_dissect_cleanup(&edt);
2951   return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
2952 }
2953
2954 static void
2955 match_subtree_text(proto_node *node, gpointer data)
2956 {
2957   match_data   *mdata      = (match_data *) data;
2958   const gchar  *string     = mdata->string;
2959   size_t        string_len = mdata->string_len;
2960   capture_file *cf         = mdata->cf;
2961   field_info   *fi         = PNODE_FINFO(node);
2962   gchar         label_str[ITEM_LABEL_LENGTH];
2963   gchar        *label_ptr;
2964   size_t        label_len;
2965   guint32       i;
2966   guint8        c_char;
2967   size_t        c_match    = 0;
2968
2969   /* dissection with an invisible proto tree? */
2970   g_assert(fi);
2971
2972   if (mdata->frame_matched) {
2973     /* We already had a match; don't bother doing any more work. */
2974     return;
2975   }
2976
2977   /* Don't match invisible entries. */
2978   if (PROTO_ITEM_IS_HIDDEN(node))
2979     return;
2980
2981   /* was a free format label produced? */
2982   if (fi->rep) {
2983     label_ptr = fi->rep->representation;
2984   } else {
2985     /* no, make a generic label */
2986     label_ptr = label_str;
2987     proto_item_fill_label(fi, label_str);
2988   }
2989
2990   if (cf->regex) {
2991     if (g_regex_match(cf->regex, label_ptr, (GRegexMatchFlags) 0, NULL)) {
2992       mdata->frame_matched = TRUE;
2993       mdata->finfo = fi;
2994       return;
2995     }
2996   } else {
2997     /* Does that label match? */
2998     label_len = strlen(label_ptr);
2999     for (i = 0; i < label_len; i++) {
3000       c_char = label_ptr[i];
3001       if (cf->case_type)
3002         c_char = g_ascii_toupper(c_char);
3003       if (c_char == string[c_match]) {
3004         c_match++;
3005         if (c_match == string_len) {
3006           /* No need to look further; we have a match */
3007           mdata->frame_matched = TRUE;
3008           mdata->finfo = fi;
3009           return;
3010         }
3011       } else
3012         c_match = 0;
3013     }
3014   }
3015
3016   /* Recurse into the subtree, if it exists */
3017   if (node->first_child != NULL)
3018     proto_tree_children_foreach(node, match_subtree_text, mdata);
3019 }
3020
3021 gboolean
3022 cf_find_packet_summary_line(capture_file *cf, const char *string,
3023                             search_direction dir)
3024 {
3025   match_data mdata;
3026
3027   mdata.string = string;
3028   mdata.string_len = strlen(string);
3029   return find_packet(cf, match_summary_line, &mdata, dir);
3030 }
3031
3032 static match_result
3033 match_summary_line(capture_file *cf, frame_data *fdata, void *criterion)
3034 {
3035   match_data     *mdata      = (match_data *)criterion;
3036   const gchar    *string     = mdata->string;
3037   size_t          string_len = mdata->string_len;
3038   epan_dissect_t  edt;
3039   const char     *info_column;
3040   size_t          info_column_len;
3041   match_result    result     = MR_NOTMATCHED;
3042   gint            colx;
3043   guint32         i;
3044   guint8          c_char;
3045   size_t          c_match    = 0;
3046
3047   /* Load the frame's data. */
3048   if (!cf_read_record(cf, fdata)) {
3049     /* Attempt to get the packet failed. */
3050     return MR_ERROR;
3051   }
3052
3053   /* Don't bother constructing the protocol tree */
3054   epan_dissect_init(&edt, cf->epan, FALSE, FALSE);
3055   /* Get the column information */
3056   epan_dissect_run(&edt, cf->cd_t, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata,
3057                    &cf->cinfo);
3058
3059   /* Find the Info column */
3060   for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
3061     if (cf->cinfo.columns[colx].fmt_matx[COL_INFO]) {
3062       /* Found it.  See if we match. */
3063       info_column = edt.pi.cinfo->columns[colx].col_data;
3064       info_column_len = strlen(info_column);
3065       if (cf->regex) {
3066         if (g_regex_match(cf->regex, info_column, (GRegexMatchFlags) 0, NULL)) {
3067           result = MR_MATCHED;
3068           break;
3069         }
3070       } else {
3071         for (i = 0; i < info_column_len; i++) {
3072           c_char = info_column[i];
3073           if (cf->case_type)
3074             c_char = g_ascii_toupper(c_char);
3075           if (c_char == string[c_match]) {
3076             c_match++;
3077             if (c_match == string_len) {
3078               result = MR_MATCHED;
3079               break;
3080             }
3081           } else
3082             c_match = 0;
3083         }
3084       }
3085       break;
3086     }
3087   }
3088   epan_dissect_cleanup(&edt);
3089   return result;
3090 }
3091
3092 typedef struct {
3093     const guint8 *data;
3094     size_t        data_len;
3095 } cbs_t;    /* "Counted byte string" */
3096
3097
3098 /*
3099  * The current match_* routines only support ASCII case insensitivity and don't
3100  * convert UTF-8 inputs to UTF-16 for matching.
3101  *
3102  * We could modify them to use the GLib Unicode routines or the International
3103  * Components for Unicode library but it's not apparent that we could do so
3104  * without consuming a lot more CPU and memory or that searching would be
3105  * significantly better.
3106  */
3107
3108 gboolean
3109 cf_find_packet_data(capture_file *cf, const guint8 *string, size_t string_size,
3110                     search_direction dir)
3111 {
3112   cbs_t info;
3113
3114   info.data = string;
3115   info.data_len = string_size;
3116
3117   /* Regex, String or hex search? */
3118   if (cf->regex) {
3119     /* Regular Expression search */
3120     return find_packet(cf, match_regex, NULL, dir);
3121   } else if (cf->string) {
3122     /* String search - what type of string? */
3123     switch (cf->scs_type) {
3124
3125     case SCS_NARROW_AND_WIDE:
3126       return find_packet(cf, match_narrow_and_wide, &info, dir);
3127
3128     case SCS_NARROW:
3129       return find_packet(cf, match_narrow, &info, dir);
3130
3131     case SCS_WIDE:
3132       return find_packet(cf, match_wide, &info, dir);
3133
3134     default:
3135       g_assert_not_reached();
3136       return FALSE;
3137     }
3138   } else
3139     return find_packet(cf, match_binary, &info, dir);
3140 }
3141
3142 static match_result
3143 match_narrow_and_wide(capture_file *cf, frame_data *fdata, void *criterion)
3144 {
3145   cbs_t        *info       = (cbs_t *)criterion;
3146   const guint8 *ascii_text = info->data;
3147   size_t        textlen    = info->data_len;
3148   match_result  result;
3149   guint32       buf_len;
3150   guint8       *pd;
3151   guint32       i;
3152   guint8        c_char;
3153   size_t        c_match    = 0;
3154
3155   /* Load the frame's data. */
3156   if (!cf_read_record(cf, fdata)) {
3157     /* Attempt to get the packet failed. */
3158     return MR_ERROR;
3159   }
3160
3161   result = MR_NOTMATCHED;
3162   buf_len = fdata->cap_len;
3163   pd = ws_buffer_start_ptr(&cf->buf);
3164   i = 0;
3165   while (i < buf_len) {
3166     c_char = pd[i];
3167     if (cf->case_type)
3168       c_char = g_ascii_toupper(c_char);
3169     if (c_char != '\0') {
3170       if (c_char == ascii_text[c_match]) {
3171         c_match += 1;
3172         if (c_match == textlen) {
3173           result = MR_MATCHED;
3174           cf->search_pos = i; /* Save the position of the last character
3175                                  for highlighting the field. */
3176           cf->search_len = (guint32)textlen;
3177           break;
3178         }
3179       }
3180       else {
3181         g_assert(i>=c_match);
3182         i -= (guint32)c_match;
3183         c_match = 0;
3184       }
3185     }
3186     i += 1;
3187   }
3188   return result;
3189 }
3190
3191 static match_result
3192 match_narrow(capture_file *cf, frame_data *fdata, void *criterion)
3193 {
3194   guint8       *pd;
3195   cbs_t        *info       = (cbs_t *)criterion;
3196   const guint8 *ascii_text = info->data;
3197   size_t        textlen    = info->data_len;
3198   match_result  result;
3199   guint32       buf_len;
3200   guint32       i;
3201   guint8        c_char;
3202   size_t        c_match    = 0;
3203
3204   /* Load the frame's data. */
3205   if (!cf_read_record(cf, fdata)) {
3206     /* Attempt to get the packet failed. */
3207     return MR_ERROR;
3208   }
3209
3210   result = MR_NOTMATCHED;
3211   buf_len = fdata->cap_len;
3212   pd = ws_buffer_start_ptr(&cf->buf);
3213   i = 0;
3214   while (i < buf_len) {
3215     c_char = pd[i];
3216     if (cf->case_type)
3217       c_char = g_ascii_toupper(c_char);
3218     if (c_char == ascii_text[c_match]) {
3219       c_match += 1;
3220       if (c_match == textlen) {
3221         result = MR_MATCHED;
3222         cf->search_pos = i; /* Save the position of the last character
3223                                for highlighting the field. */
3224         cf->search_len = (guint32)textlen;
3225         break;
3226       }
3227     }
3228     else {
3229       g_assert(i>=c_match);
3230       i -= (guint32)c_match;
3231       c_match = 0;
3232     }
3233     i += 1;
3234   }
3235
3236   return result;
3237 }
3238
3239 static match_result
3240 match_wide(capture_file *cf, frame_data *fdata, void *criterion)
3241 {
3242   cbs_t        *info       = (cbs_t *)criterion;
3243   const guint8 *ascii_text = info->data;
3244   size_t        textlen    = info->data_len;
3245   match_result  result;
3246   guint32       buf_len;
3247   guint8       *pd;
3248   guint32       i;
3249   guint8        c_char;
3250   size_t        c_match    = 0;
3251
3252   /* Load the frame's data. */
3253   if (!cf_read_record(cf, fdata)) {
3254     /* Attempt to get the packet failed. */
3255     return MR_ERROR;
3256   }
3257
3258   result = MR_NOTMATCHED;
3259   buf_len = fdata->cap_len;
3260   pd = ws_buffer_start_ptr(&cf->buf);
3261   i = 0;
3262   while (i < buf_len) {
3263     c_char = pd[i];
3264     if (cf->case_type)
3265       c_char = g_ascii_toupper(c_char);
3266     if (c_char == ascii_text[c_match]) {
3267       c_match += 1;
3268       if (c_match == textlen) {
3269         result = MR_MATCHED;
3270         cf->search_pos = i; /* Save the position of the last character
3271                                for highlighting the field. */
3272         cf->search_len = (guint32)textlen;
3273         break;
3274       }
3275       i += 1;
3276     }
3277     else {
3278       g_assert(i>=(c_match*2));
3279       i -= (guint32)c_match*2;
3280       c_match = 0;
3281     }
3282     i += 1;
3283   }
3284   return result;
3285 }
3286
3287 static match_result
3288 match_binary(capture_file *cf, frame_data *fdata, void *criterion)
3289 {
3290   cbs_t        *info        = (cbs_t *)criterion;
3291   const guint8 *binary_data = info->data;
3292   size_t        datalen     = info->data_len;
3293   match_result  result;
3294   guint32       buf_len;
3295   guint8       *pd;
3296   guint32       i;
3297   size_t        c_match     = 0;
3298
3299   /* Load the frame's data. */
3300   if (!cf_read_record(cf, fdata)) {
3301     /* Attempt to get the packet failed. */
3302     return MR_ERROR;
3303   }
3304
3305   result = MR_NOTMATCHED;
3306   buf_len = fdata->cap_len;
3307   pd = ws_buffer_start_ptr(&cf->buf);
3308   i = 0;
3309   while (i < buf_len) {
3310     if (pd[i] == binary_data[c_match]) {
3311       c_match += 1;
3312       if (c_match == datalen) {
3313         result = MR_MATCHED;
3314         cf->search_pos = i; /* Save the position of the last character
3315                                for highlighting the field. */
3316         cf->search_len = (guint32)datalen;
3317         break;
3318       }
3319     }
3320     else {
3321       g_assert(i>=c_match);
3322       i -= (guint32)c_match;
3323       c_match = 0;
3324     }
3325     i += 1;
3326   }
3327   return result;
3328 }
3329
3330 static match_result
3331 match_regex(capture_file *cf, frame_data *fdata, void *criterion _U_)
3332 {
3333     match_result  result = MR_NOTMATCHED;
3334     GMatchInfo   *match_info = NULL;
3335
3336     /* Load the frame's data. */
3337     if (!cf_read_record(cf, fdata)) {
3338         /* Attempt to get the packet failed. */
3339         return MR_ERROR;
3340     }
3341
3342     if (g_regex_match_full(cf->regex, (const gchar *)ws_buffer_start_ptr(&cf->buf), fdata->cap_len,
3343                            0, (GRegexMatchFlags) 0, &match_info, NULL))
3344     {
3345         gint start_pos = 0, end_pos = 0;
3346         g_match_info_fetch_pos (match_info, 0, &start_pos, &end_pos);
3347         cf->search_pos = end_pos - 1;
3348         cf->search_len = end_pos - start_pos;
3349         result = MR_MATCHED;
3350     }
3351     return result;
3352 }
3353
3354 gboolean
3355 cf_find_packet_dfilter(capture_file *cf, dfilter_t *sfcode,
3356                        search_direction dir)
3357 {
3358   return find_packet(cf, match_dfilter, sfcode, dir);
3359 }
3360
3361 gboolean
3362 cf_find_packet_dfilter_string(capture_file *cf, const char *filter,
3363                               search_direction dir)
3364 {
3365   dfilter_t *sfcode;
3366   gboolean   result;
3367
3368   if (!dfilter_compile(filter, &sfcode, NULL)) {
3369      /*
3370       * XXX - this shouldn't happen, as the filter string is machine
3371       * generated
3372       */
3373     return FALSE;
3374   }
3375   if (sfcode == NULL) {
3376     /*
3377      * XXX - this shouldn't happen, as the filter string is machine
3378      * generated.
3379      */
3380     return FALSE;
3381   }
3382   result = find_packet(cf, match_dfilter, sfcode, dir);
3383   dfilter_free(sfcode);
3384   return result;
3385 }
3386
3387 static match_result
3388 match_dfilter(capture_file *cf, frame_data *fdata, void *criterion)
3389 {
3390   dfilter_t      *sfcode = (dfilter_t *)criterion;
3391   epan_dissect_t  edt;
3392   match_result    result;
3393
3394   /* Load the frame's data. */
3395   if (!cf_read_record(cf, fdata)) {
3396     /* Attempt to get the packet failed. */
3397     return MR_ERROR;
3398   }
3399
3400   epan_dissect_init(&edt, cf->epan, TRUE, FALSE);
3401   epan_dissect_prime_dfilter(&edt, sfcode);
3402   epan_dissect_run(&edt, cf->cd_t, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata, NULL);
3403   result = dfilter_apply_edt(sfcode, &edt) ? MR_MATCHED : MR_NOTMATCHED;
3404   epan_dissect_cleanup(&edt);
3405   return result;
3406 }
3407
3408 gboolean
3409 cf_find_packet_marked(capture_file *cf, search_direction dir)
3410 {
3411   return find_packet(cf, match_marked, NULL, dir);
3412 }
3413
3414 static match_result
3415 match_marked(capture_file *cf _U_, frame_data *fdata, void *criterion _U_)
3416 {
3417   return fdata->flags.marked ? MR_MATCHED : MR_NOTMATCHED;
3418 }
3419
3420 gboolean
3421 cf_find_packet_time_reference(capture_file *cf, search_direction dir)
3422 {
3423   return find_packet(cf, match_time_reference, NULL, dir);
3424 }
3425
3426 static match_result
3427 match_time_reference(capture_file *cf _U_, frame_data *fdata, void *criterion _U_)
3428 {
3429   return fdata->flags.ref_time ? MR_MATCHED : MR_NOTMATCHED;
3430 }
3431
3432 static gboolean
3433 find_packet(capture_file *cf,
3434             match_result (*match_function)(capture_file *, frame_data *, void *),
3435             void *criterion, search_direction dir)
3436 {
3437   frame_data  *start_fd;
3438   guint32      framenum;
3439   frame_data  *fdata;
3440   frame_data  *new_fd = NULL;
3441   progdlg_t   *progbar = NULL;
3442   GTimer      *prog_timer = g_timer_new();
3443   int          count;
3444   gboolean     found;
3445   float        progbar_val;
3446   GTimeVal     start_time;
3447   gchar        status_str[100];
3448   const char  *title;
3449   match_result result;
3450
3451   start_fd = cf->current_frame;
3452   if (start_fd != NULL)  {
3453     /* Iterate through the list of packets, starting at the packet we've
3454        picked, calling a routine to run the filter on the packet, see if
3455        it matches, and stop if so.  */
3456     count = 0;
3457     framenum = start_fd->num;
3458
3459     g_timer_start(prog_timer);
3460     /* Progress so far. */
3461     progbar_val = 0.0f;
3462
3463     cf->stop_flag = FALSE;
3464     g_get_current_time(&start_time);
3465
3466     title = cf->sfilter?cf->sfilter:"";
3467     for (;;) {
3468       /* Create the progress bar if necessary.
3469          We check on every iteration of the loop, so that it takes no
3470          longer than the standard time to create it (otherwise, for a
3471          large file, we might take considerably longer than that standard
3472          time in order to get to the next progress bar step). */
3473       if (progbar == NULL)
3474          progbar = delayed_create_progress_dlg(cf->window, "Searching", title,
3475            FALSE, &cf->stop_flag, &start_time, progbar_val);
3476
3477       /*
3478        * Update the progress bar, but do it only after PROGBAR_UPDATE_INTERVAL
3479        * has elapsed. Calling update_progress_dlg and packets_bar_update will
3480        * likely trigger UI paint events, which might take a while depending on
3481        * the platform and display. Reset our timer *after* painting.
3482        */
3483       if (g_timer_elapsed(prog_timer, NULL) > PROGBAR_UPDATE_INTERVAL) {
3484         /* let's not divide by zero. I should never be started
3485          * with count == 0, so let's assert that
3486          */
3487         g_assert(cf->count > 0);
3488
3489         progbar_val = (gfloat) count / cf->count;
3490
3491         g_snprintf(status_str, sizeof(status_str),
3492                     "%4u of %u packets", count, cf->count);
3493         update_progress_dlg(progbar, progbar_val, status_str);
3494
3495         g_timer_start(prog_timer);
3496       }
3497
3498       if (cf->stop_flag) {
3499         /* Well, the user decided to abort the search.  Go back to the
3500            frame where we started. */
3501         new_fd = start_fd;
3502         break;
3503       }
3504
3505       /* Go past the current frame. */
3506       if (dir == SD_BACKWARD) {
3507         /* Go on to the previous frame. */
3508         if (framenum == 1) {
3509           /*
3510            * XXX - other apps have a bit more of a detailed message
3511            * for this, and instead of offering "OK" and "Cancel",
3512            * they offer things such as "Continue" and "Cancel";
3513            * we need an API for popping up alert boxes with
3514            * {Verb} and "Cancel".
3515            */
3516
3517           if (prefs.gui_find_wrap)
3518           {
3519               statusbar_push_temporary_msg("Search reached the beginning. Continuing at end.");
3520               framenum = cf->count;     /* wrap around */
3521           }
3522           else
3523           {
3524               statusbar_push_temporary_msg("Search reached the beginning.");
3525               framenum = start_fd->num; /* stay on previous packet */
3526           }
3527         } else
3528           framenum--;
3529       } else {
3530         /* Go on to the next frame. */
3531         if (framenum == cf->count) {
3532           if (prefs.gui_find_wrap)
3533           {
3534               statusbar_push_temporary_msg("Search reached the end. Continuing at beginning.");
3535               framenum = 1;             /* wrap around */
3536           }
3537           else
3538           {
3539               statusbar_push_temporary_msg("Search reached the end.");
3540               framenum = start_fd->num; /* stay on previous packet */
3541           }
3542         } else
3543           framenum++;
3544       }
3545       fdata = frame_data_sequence_find(cf->frames, framenum);
3546
3547       count++;
3548
3549       /* Is this packet in the display? */
3550       if (fdata->flags.passed_dfilter) {
3551         /* Yes.  Does it match the search criterion? */
3552         result = (*match_function)(cf, fdata, criterion);
3553         if (result == MR_ERROR) {
3554           /* Error; our caller has reported the error.  Go back to the frame
3555              where we started. */
3556           new_fd = start_fd;
3557           break;
3558         } else if (result == MR_MATCHED) {
3559           /* Yes.  Go to the new frame. */
3560           new_fd = fdata;
3561           break;
3562         }
3563       }
3564
3565       if (fdata == start_fd) {
3566         /* We're back to the frame we were on originally, and that frame
3567            doesn't match the search filter.  The search failed. */
3568         break;
3569       }
3570     }
3571
3572     /* We're done scanning the packets; destroy the progress bar if it
3573        was created. */
3574     if (progbar != NULL)
3575       destroy_progress_dlg(progbar);
3576     g_timer_destroy(prog_timer);
3577   }
3578
3579   if (new_fd != NULL) {
3580     /* Find and select */
3581     cf->search_in_progress = TRUE;
3582     found = packet_list_select_row_from_data(new_fd);
3583     cf->search_in_progress = FALSE;
3584     cf->search_pos = 0; /* Reset the position */
3585     cf->search_len = 0; /* Reset length */
3586     if (!found) {
3587       /* We didn't find a row corresponding to this frame.
3588          This means that the frame isn't being displayed currently,
3589          so we can't select it. */
3590       simple_message_box(ESD_TYPE_INFO, NULL,
3591                          "The capture file is probably not fully dissected.",
3592                          "End of capture exceeded.");
3593       return FALSE;
3594     }
3595     return TRUE;    /* success */
3596   } else
3597     return FALSE;   /* failure */
3598 }
3599
3600 gboolean
3601 cf_goto_frame(capture_file *cf, guint fnumber)
3602 {
3603   frame_data *fdata;
3604
3605   if (cf == NULL || cf->frames == NULL) {
3606     /* we don't have a loaded capture file - fix for bugs 11810 & 11989 */
3607     statusbar_push_temporary_msg("There is no file loaded");
3608     return FALSE;   /* we failed to go to that packet */
3609   }
3610
3611   fdata = frame_data_sequence_find(cf->frames, fnumber);
3612
3613   if (fdata == NULL) {
3614     /* we didn't find a packet with that packet number */
3615     statusbar_push_temporary_msg("There is no packet number %u.", fnumber);
3616     return FALSE;   /* we failed to go to that packet */
3617   }
3618   if (!fdata->flags.passed_dfilter) {
3619     /* that packet currently isn't displayed */
3620     /* XXX - add it to the set of displayed packets? */
3621     statusbar_push_temporary_msg("Packet number %u isn't displayed.", fnumber);
3622     return FALSE;   /* we failed to go to that packet */
3623   }
3624
3625   if (!packet_list_select_row_from_data(fdata)) {
3626     /* We didn't find a row corresponding to this frame.
3627        This means that the frame isn't being displayed currently,
3628        so we can't select it. */
3629     simple_message_box(ESD_TYPE_INFO, NULL,
3630                        "The capture file is probably not fully dissected.",
3631                        "End of capture exceeded.");
3632     return FALSE;
3633   }
3634   return TRUE;  /* we got to that packet */
3635 }
3636
3637 gboolean
3638 cf_goto_top_frame(void)
3639 {
3640   /* Find and select */
3641   packet_list_select_first_row();
3642   return TRUE;  /* we got to that packet */
3643 }
3644
3645 gboolean
3646 cf_goto_bottom_frame(void)
3647 {
3648   /* Find and select */
3649   packet_list_select_last_row();
3650   return TRUE;  /* we got to that packet */
3651 }
3652
3653 /*
3654  * Go to frame specified by currently selected protocol tree item.
3655  */
3656 gboolean
3657 cf_goto_framenum(capture_file *cf)
3658 {
3659   header_field_info *hfinfo;
3660   guint32            framenum;
3661
3662   if (cf->finfo_selected) {
3663     hfinfo = cf->finfo_selected->hfinfo;
3664     g_assert(hfinfo);
3665     if (hfinfo->type == FT_FRAMENUM) {
3666       framenum = fvalue_get_uinteger(&cf->finfo_selected->value);
3667       if (framenum != 0)
3668         return cf_goto_frame(cf, framenum);
3669       }
3670   }
3671
3672   return FALSE;
3673 }
3674
3675 /* Select the packet on a given row. */
3676 void
3677 cf_select_packet(capture_file *cf, int row)
3678 {
3679   epan_dissect_t *old_edt;
3680   frame_data     *fdata;
3681
3682   /* Get the frame data struct pointer for this frame */
3683   fdata = packet_list_get_row_data(row);
3684
3685   if (fdata == NULL) {
3686     /* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
3687        the first entry is added to it by "real_insert_row()", that row
3688        is selected (see "real_insert_row()", in "ui/gtk/gtkclist.c", in both
3689        our version and the vanilla GTK+ version).
3690
3691        This means that a "select-row" signal is emitted; this causes
3692        "packet_list_select_cb()" to be called, which causes "cf_select_packet()"
3693        to be called.
3694
3695        "cf_select_packet()" fetches, above, the data associated with the
3696        row that was selected; however, as "gtk_clist_append()", which
3697        called "real_insert_row()", hasn't yet returned, we haven't yet
3698        associated any data with that row, so we get back a null pointer.
3699
3700        We can't assume that there's only one frame in the frame list,
3701        either, as we may be filtering the display.
3702
3703        We therefore assume that, if "row" is 0, i.e. the first row
3704        is being selected, and "cf->first_displayed" equals
3705        "cf->last_displayed", i.e. there's only one frame being
3706        displayed, that frame is the frame we want.
3707
3708        This means we have to set "cf->first_displayed" and
3709        "cf->last_displayed" before adding the row to the
3710        GtkCList; see the comment in "add_packet_to_packet_list()". */
3711
3712        if (row == 0 && cf->first_displayed == cf->last_displayed)
3713          fdata = frame_data_sequence_find(cf->frames, cf->first_displayed);
3714   }
3715
3716   /* If fdata _still_ isn't set simply give up. */
3717   if (fdata == NULL) {
3718     return;
3719   }
3720
3721   /* Get the data in that frame. */
3722   if (!cf_read_record (cf, fdata)) {
3723     return;
3724   }
3725
3726   /* Record that this frame is the current frame. */
3727   cf->current_frame = fdata;
3728   cf->current_row = row;
3729
3730   old_edt = cf->edt;
3731   /* Create the logical protocol tree. */
3732   /* We don't need the columns here. */
3733   cf->edt = epan_dissect_new(cf->epan, TRUE, TRUE);
3734
3735   tap_build_interesting(cf->edt);
3736   epan_dissect_run(cf->edt, cf->cd_t, &cf->phdr, frame_tvbuff_new_buffer(cf->current_frame, &cf->buf),
3737                    cf->current_frame, NULL);
3738
3739   dfilter_macro_build_ftv_cache(cf->edt->tree);
3740
3741   cf_callback_invoke(cf_cb_packet_selected, cf);
3742
3743   if (old_edt != NULL)
3744     epan_dissect_free(old_edt);
3745
3746 }
3747
3748 /* Unselect the selected packet, if any. */
3749 void
3750 cf_unselect_packet(capture_file *cf)
3751 {
3752   epan_dissect_t *old_edt = cf->edt;
3753
3754   cf->edt = NULL;
3755
3756   /* No packet is selected. */
3757   cf->current_frame = NULL;
3758   cf->current_row = 0;
3759
3760   cf_callback_invoke(cf_cb_packet_unselected, cf);
3761
3762   /* No protocol tree means no selected field. */
3763   cf_unselect_field(cf);
3764
3765   /* Destroy the epan_dissect_t for the unselected packet. */
3766   if (old_edt != NULL)
3767     epan_dissect_free(old_edt);
3768 }
3769
3770 /* Unset the selected protocol tree field, if any. */
3771 void
3772 cf_unselect_field(capture_file *cf)
3773 {
3774   cf->finfo_selected = NULL;
3775
3776   cf_callback_invoke(cf_cb_field_unselected, cf);
3777 }
3778
3779 /*
3780  * Mark a particular frame.
3781  */
3782 void
3783 cf_mark_frame(capture_file *cf, frame_data *frame)
3784 {
3785   if (! frame->flags.marked) {
3786     frame->flags.marked = TRUE;
3787     if (cf->count > cf->marked_count)
3788       cf->marked_count++;
3789   }
3790 }
3791
3792 /*
3793  * Unmark a particular frame.
3794  */
3795 void
3796 cf_unmark_frame(capture_file *cf, frame_data *frame)
3797 {
3798   if (frame->flags.marked) {
3799     frame->flags.marked = FALSE;
3800     if (cf->marked_count > 0)
3801       cf->marked_count--;
3802   }
3803 }
3804
3805 /*
3806  * Ignore a particular frame.
3807  */
3808 void
3809 cf_ignore_frame(capture_file *cf, frame_data *frame)
3810 {
3811   if (! frame->flags.ignored) {
3812     frame->flags.ignored = TRUE;
3813     if (cf->count > cf->ignored_count)
3814       cf->ignored_count++;
3815   }
3816 }
3817
3818 /*
3819  * Un-ignore a particular frame.
3820  */
3821 void
3822 cf_unignore_frame(capture_file *cf, frame_data *frame)
3823 {
3824   if (frame->flags.ignored) {
3825     frame->flags.ignored = FALSE;
3826     if (cf->ignored_count > 0)
3827       cf->ignored_count--;
3828   }
3829 }
3830
3831 /*
3832  * Read the comment in SHB block
3833  */
3834
3835 const gchar *
3836 cf_read_shb_comment(capture_file *cf)
3837 {
3838   wtap_block_t shb_inf;
3839   char *shb_comment;
3840
3841   /* Get the SHB. */
3842   /* XXX - support multiple SHBs */
3843   shb_inf = wtap_file_get_shb(cf->wth);
3844
3845   /* Get the first comment from the SHB. */
3846   /* XXX - support multiple comments */
3847   if (wtap_block_get_nth_string_option_value(shb_inf, OPT_COMMENT, 0, &shb_comment) != WTAP_OPTTYPE_SUCCESS)
3848     return NULL;
3849   return shb_comment;
3850 }
3851
3852 void
3853 cf_update_capture_comment(capture_file *cf, gchar *comment)
3854 {
3855   wtap_block_t shb_inf;
3856   gchar *shb_comment;
3857
3858   /* Get the SHB. */
3859   /* XXX - support multiple SHBs */
3860   shb_inf = wtap_file_get_shb(cf->wth);
3861
3862   /* Get the first comment from the SHB. */
3863   /* XXX - support multiple comments */
3864   if (wtap_block_get_nth_string_option_value(shb_inf, OPT_COMMENT, 0, &shb_comment) != WTAP_OPTTYPE_SUCCESS) {
3865     /* There's no comment - add one. */
3866     wtap_block_add_string_option(shb_inf, OPT_COMMENT, comment, strlen(comment));
3867   } else {
3868     /* See if the comment has changed or not */
3869     if (strcmp(shb_comment, comment) == 0) {
3870       g_free(comment);
3871       return;
3872     }
3873
3874     /* The comment has changed, let's update it */
3875     wtap_block_set_nth_string_option_value(shb_inf, OPT_COMMENT, 0, comment, strlen(comment));
3876   }
3877   /* Mark the file as having unsaved changes */
3878   cf->unsaved_changes = TRUE;
3879 }
3880
3881 static const char *
3882 cf_get_user_packet_comment(capture_file *cf, const frame_data *fd)
3883 {
3884   if (cf->frames_user_comments)
3885      return (const char *)g_tree_lookup(cf->frames_user_comments, fd);
3886
3887   /* g_warning? */
3888   return NULL;
3889 }
3890
3891 char *
3892 cf_get_comment(capture_file *cf, const frame_data *fd)
3893 {
3894   char *comment;
3895
3896   /* fetch user comment */
3897   if (fd->flags.has_user_comment)
3898     return g_strdup(cf_get_user_packet_comment(cf, fd));
3899
3900   /* fetch phdr comment */
3901   if (fd->flags.has_phdr_comment) {
3902     struct wtap_pkthdr phdr; /* Packet header */
3903     Buffer buf; /* Packet data */
3904
3905     wtap_phdr_init(&phdr);
3906     ws_buffer_init(&buf, 1500);
3907
3908     if (!cf_read_record_r(cf, fd, &phdr, &buf))
3909       { /* XXX, what we can do here? */ }
3910
3911     comment = phdr.opt_comment;
3912     wtap_phdr_cleanup(&phdr);
3913     ws_buffer_free(&buf);
3914     return comment;
3915   }
3916   return NULL;
3917 }
3918
3919 static int
3920 frame_cmp(gconstpointer a, gconstpointer b, gpointer user_data _U_)
3921 {
3922   const frame_data *fdata1 = (const frame_data *) a;
3923   const frame_data *fdata2 = (const frame_data *) b;
3924
3925   return (fdata1->num < fdata2->num) ? -1 :
3926     (fdata1->num > fdata2->num) ? 1 :
3927     0;
3928 }
3929
3930 gboolean
3931 cf_set_user_packet_comment(capture_file *cf, frame_data *fd, const gchar *new_comment)
3932 {
3933   char *pkt_comment = cf_get_comment(cf, fd);
3934
3935   /* Check if the comment has changed */
3936   if (!g_strcmp0(pkt_comment, new_comment)) {
3937     g_free(pkt_comment);
3938     return FALSE;
3939   }
3940   g_free(pkt_comment);
3941
3942   if (pkt_comment)
3943     cf->packet_comment_count--;
3944
3945   if (new_comment)
3946     cf->packet_comment_count++;
3947
3948   fd->flags.has_user_comment = TRUE;
3949
3950   if (!cf->frames_user_comments)
3951     cf->frames_user_comments = g_tree_new_full(frame_cmp, NULL, NULL, g_free);
3952
3953   /* insert new packet comment */
3954   g_tree_replace(cf->frames_user_comments, fd, g_strdup(new_comment));
3955
3956   expert_update_comment_count(cf->packet_comment_count);
3957
3958   /* OK, we have unsaved changes. */
3959   cf->unsaved_changes = TRUE;
3960   return TRUE;
3961 }
3962
3963 /*
3964  * What types of comments does this capture file have?
3965  */
3966 guint32
3967 cf_comment_types(capture_file *cf)
3968 {
3969   guint32 comment_types = 0;
3970
3971   if (cf_read_shb_comment(cf) != NULL)
3972     comment_types |= WTAP_COMMENT_PER_SECTION;
3973   if (cf->packet_comment_count != 0)
3974     comment_types |= WTAP_COMMENT_PER_PACKET;
3975   return comment_types;
3976 }
3977
3978 /*
3979  * Add a resolved address to this file's list of resolved addresses.
3980  */
3981 gboolean
3982 cf_add_ip_name_from_string(capture_file *cf, const char *addr, const char *name)
3983 {
3984   /*
3985    * XXX - support multiple resolved address lists, and add to the one
3986    * attached to this file?
3987    */
3988   if (!add_ip_name_from_string(addr, name))
3989     return FALSE;
3990
3991   /* OK, we have unsaved changes. */
3992   cf->unsaved_changes = TRUE;
3993   return TRUE;
3994 }
3995
3996 #ifdef WANT_PACKET_EDITOR
3997 static gint
3998 g_direct_compare_func(gconstpointer a, gconstpointer b, gpointer user_data _U_)
3999 {
4000   if (a > b)
4001     return 1;
4002   else if (a < b)
4003     return -1;
4004   else
4005     return 0;
4006 }
4007
4008 static void
4009 modified_frame_data_free(gpointer data)
4010 {
4011   modified_frame_data *mfd = (modified_frame_data *)data;
4012
4013   g_free(mfd->pd);
4014   g_free(mfd);
4015 }
4016
4017 /*
4018  * Give a frame new, edited data.
4019  */
4020 void
4021 cf_set_frame_edited(capture_file *cf, frame_data *fd,
4022                     struct wtap_pkthdr *phdr, guint8 *pd)
4023 {
4024   modified_frame_data *mfd = (modified_frame_data *)g_malloc(sizeof(modified_frame_data));
4025
4026   mfd->phdr = *phdr;
4027   mfd->pd = (char *)pd;
4028
4029   if (cf->edited_frames == NULL)
4030     cf->edited_frames = g_tree_new_full(g_direct_compare_func, NULL, NULL,
4031                                         modified_frame_data_free);
4032   g_tree_insert(cf->edited_frames, GINT_TO_POINTER(fd->num), mfd);
4033   fd->file_off = -1;
4034
4035   /* Mark the file as having unsaved changes */
4036   cf->unsaved_changes = TRUE;
4037 }
4038 #endif
4039
4040 typedef struct {
4041   wtap_dumper *pdh;
4042   const char  *fname;
4043   int          file_type;
4044 } save_callback_args_t;
4045
4046 /*
4047  * Save a capture to a file, in a particular format, saving either
4048  * all packets, all currently-displayed packets, or all marked packets.
4049  *
4050  * Returns TRUE if it succeeds, FALSE otherwise; if it fails, it pops
4051  * up a message box for the failure.
4052  */
4053 static gboolean
4054 save_record(capture_file *cf, frame_data *fdata,
4055             struct wtap_pkthdr *phdr, const guint8 *pd,
4056             void *argsp)
4057 {
4058   save_callback_args_t *args = (save_callback_args_t *)argsp;
4059   struct wtap_pkthdr    hdr;
4060   int           err;
4061   gchar        *err_info;
4062   gchar        *display_basename;
4063   const char   *pkt_comment;
4064
4065   if (fdata->flags.has_user_comment)
4066     pkt_comment = cf_get_user_packet_comment(cf, fdata);
4067   else
4068     pkt_comment = phdr->opt_comment;
4069
4070   /* init the wtap header for saving */
4071   /* TODO: reuse phdr */
4072   /* XXX - these are the only flags that correspond to data that we have
4073      in the frame_data structure and that matter on a per-packet basis.
4074
4075      For WTAP_HAS_CAP_LEN, either the file format has separate "captured"
4076      and "on the wire" lengths, or it doesn't.
4077
4078      For WTAP_HAS_DROP_COUNT, Wiretap doesn't actually supply the value
4079      to its callers.
4080
4081      For WTAP_HAS_PACK_FLAGS, we currently don't save the FCS length
4082      from the packet flags. */
4083   hdr.rec_type = phdr->rec_type;
4084   hdr.presence_flags = 0;
4085   if (fdata->flags.has_ts)
4086     hdr.presence_flags |= WTAP_HAS_TS;
4087   if (phdr->presence_flags & WTAP_HAS_INTERFACE_ID)
4088     hdr.presence_flags |= WTAP_HAS_INTERFACE_ID;
4089   if (phdr->presence_flags & WTAP_HAS_PACK_FLAGS)
4090     hdr.presence_flags |= WTAP_HAS_PACK_FLAGS;
4091   hdr.ts           = phdr->ts;
4092   hdr.caplen       = phdr->caplen;
4093   hdr.len          = phdr->len;
4094   hdr.pkt_encap    = phdr->pkt_encap;
4095   /* pcapng */
4096   hdr.interface_id = phdr->interface_id;   /* identifier of the interface. */
4097   /* options */
4098   hdr.pack_flags   = phdr->pack_flags;
4099   hdr.opt_comment  = g_strdup(pkt_comment);
4100
4101   /* pseudo */
4102   hdr.pseudo_header = phdr->pseudo_header;
4103 #if 0
4104   hdr.drop_count   =
4105   hdr.pack_flags   =     /* XXX - 0 for now (any value for "we don't have it"?) */
4106 #endif
4107   /* and save the packet */
4108   if (!wtap_dump(args->pdh, &hdr, pd, &err, &err_info)) {
4109     if (err < 0) {
4110       /* Wiretap error. */
4111       switch (err) {
4112
4113       case WTAP_ERR_UNWRITABLE_ENCAP:
4114         /*
4115          * This is a problem with the particular frame we're writing and
4116          * the file type and subtype we're writing; note that, and report
4117          * the frame number and file type/subtype.
4118          */
4119         simple_error_message_box(
4120                       "Frame %u has a network type that can't be saved in a \"%s\" file.",
4121                       fdata->num, wtap_file_type_subtype_string(args->file_type));
4122         break;
4123
4124       case WTAP_ERR_PACKET_TOO_LARGE:
4125         /*
4126          * This is a problem with the particular frame we're writing and
4127          * the file type and subtype we're writing; note that, and report
4128          * the frame number and file type/subtype.
4129          */
4130         simple_error_message_box(
4131                       "Frame %u is larger than Wireshark supports in a \"%s\" file.",
4132                       fdata->num, wtap_file_type_subtype_string(args->file_type));
4133         break;
4134
4135       case WTAP_ERR_UNWRITABLE_REC_TYPE:
4136         /*
4137          * This is a problem with the particular record we're writing and
4138          * the file type and subtype we're writing; note that, and report
4139          * the record number and file type/subtype.
4140          */
4141         simple_error_message_box(
4142                       "Record %u has a record type that can't be saved in a \"%s\" file.",
4143                       fdata->num, wtap_file_type_subtype_string(args->file_type));
4144         break;
4145
4146       case WTAP_ERR_UNWRITABLE_REC_DATA:
4147         /*
4148          * This is a problem with the particular frame we're writing and
4149          * the file type and subtype we're writing; note that, and report
4150          * the frame number and file type/subtype.
4151          */
4152         simple_error_message_box(
4153                       "Record %u has data that can't be saved in a \"%s\" file.\n(%s)",
4154                       fdata->num, wtap_file_type_subtype_string(args->file_type),
4155                       err_info != NULL ? err_info : "no information supplied");
4156         g_free(err_info);
4157         break;
4158
4159       default:
4160         display_basename = g_filename_display_basename(args->fname);
4161         simple_error_message_box(
4162                       "An error occurred while writing to the file \"%s\": %s.",
4163                       display_basename, wtap_strerror(err));
4164         g_free(display_basename);
4165         break;
4166       }
4167     } else {
4168       /* OS error. */
4169       write_failure_alert_box(args->fname, err);
4170     }
4171     return FALSE;
4172   }
4173
4174   g_free(hdr.opt_comment);
4175   return TRUE;
4176 }
4177
4178 /*
4179  * Can this capture file be written out in any format using Wiretap
4180  * rather than by copying the raw data?
4181  */
4182 gboolean
4183 cf_can_write_with_wiretap(capture_file *cf)
4184 {
4185   /* We don't care whether we support the comments in this file or not;
4186      if we can't, we'll offer the user the option of discarding the
4187      comments. */
4188   return wtap_dump_can_write(cf->linktypes, 0);
4189 }
4190
4191 /*
4192  * Should we let the user do a save?
4193  *
4194  * We should if:
4195  *
4196  *  the file has unsaved changes, and we can save it in some
4197  *  format through Wiretap
4198  *
4199  * or
4200  *
4201  *  the file is a temporary file and has no unsaved changes (so
4202  *  that "saving" it just means copying it).
4203  *
4204  * XXX - we shouldn't allow files to be edited if they can't be saved,
4205  * so cf->unsaved_changes should be true only if the file can be saved.
4206  *
4207  * We don't care whether we support the comments in this file or not;
4208  * if we can't, we'll offer the user the option of discarding the
4209  * comments.
4210  */
4211 gboolean
4212 cf_can_save(capture_file *cf)
4213 {
4214   if (cf->unsaved_changes && wtap_dump_can_write(cf->linktypes, 0)) {
4215     /* Saved changes, and we can write it out with Wiretap. */
4216     return TRUE;
4217   }
4218
4219   if (cf->is_tempfile && !cf->unsaved_changes) {
4220     /*
4221      * Temporary file with no unsaved changes, so we can just do a
4222      * raw binary copy.
4223      */
4224     return TRUE;
4225   }
4226
4227   /* Nothing to save. */
4228   return FALSE;
4229 }
4230
4231 /*
4232  * Should we let the user do a "save as"?
4233  *
4234  * That's true if:
4235  *
4236  *  we can save it in some format through Wiretap
4237  *
4238  * or
4239  *
4240  *  the file is a temporary file and has no unsaved changes (so
4241  *  that "saving" it just means copying it).
4242  *
4243  * XXX - we shouldn't allow files to be edited if they can't be saved,
4244  * so cf->unsaved_changes should be true only if the file can be saved.
4245  *
4246  * We don't care whether we support the comments in this file or not;
4247  * if we can't, we'll offer the user the option of discarding the
4248  * comments.
4249  */
4250 gboolean
4251 cf_can_save_as(capture_file *cf)
4252 {
4253   if (wtap_dump_can_write(cf->linktypes, 0)) {
4254     /* We can write it out with Wiretap. */
4255     return TRUE;
4256   }
4257
4258   if (cf->is_tempfile && !cf->unsaved_changes) {
4259     /*
4260      * Temporary file with no unsaved changes, so we can just do a
4261      * raw binary copy.
4262      */
4263     return TRUE;
4264   }
4265
4266   /* Nothing to save. */
4267   return FALSE;
4268 }
4269
4270 /*
4271  * Does this file have unsaved data?
4272  */
4273 gboolean
4274 cf_has_unsaved_data(capture_file *cf)
4275 {
4276   /*
4277    * If this is a temporary file, or a file with unsaved changes, it
4278    * has unsaved data.
4279    */
4280   return (cf->is_tempfile && cf->count>0) || cf->unsaved_changes;
4281 }
4282
4283 /*
4284  * Quick scan to find packet offsets.
4285  */
4286 static cf_read_status_t
4287 rescan_file(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
4288 {
4289   const struct wtap_pkthdr *phdr;
4290   gchar               *err_info;
4291   gchar               *name_ptr;
4292   gint64               data_offset;
4293   progdlg_t           *progbar        = NULL;
4294   GTimer              *prog_timer = g_timer_new();
4295   gint64               size;
4296   float                progbar_val;
4297   GTimeVal             start_time;
4298   gchar                status_str[100];
4299   guint32              framenum;
4300   frame_data          *fdata;
4301   int                  count          = 0;
4302
4303   /* Close the old handle. */
4304   wtap_close(cf->wth);
4305
4306   /* Open the new file. */
4307   /* XXX: this will go through all open_routines for a matching one. But right
4308      now rescan_file() is only used when a file is being saved to a different
4309      format than the original, and the user is not given a choice of which
4310      reader to use (only which format to save it in), so doing this makes
4311      sense for now. */
4312   cf->wth = wtap_open_offline(fname, WTAP_TYPE_AUTO, err, &err_info, TRUE);
4313   if (cf->wth == NULL) {
4314     cf_open_failure_alert_box(fname, *err, err_info, FALSE, 0);
4315     return CF_READ_ERROR;
4316   }
4317
4318   /* We're scanning a file whose contents should be the same as what
4319      we had before, so we don't discard dissection state etc.. */
4320   cf->f_datalen = 0;
4321
4322   /* Set the file name because we need it to set the follow stream filter.
4323      XXX - is that still true?  We need it for other reasons, though,
4324      in any case. */
4325   cf->filename = g_strdup(fname);
4326
4327   /* Indicate whether it's a permanent or temporary file. */
4328   cf->is_tempfile = is_tempfile;
4329
4330   /* No user changes yet. */
4331   cf->unsaved_changes = FALSE;
4332
4333   cf->cd_t        = wtap_file_type_subtype(cf->wth);
4334   cf->linktypes = g_array_sized_new(FALSE, FALSE, (guint) sizeof(int), 1);
4335
4336   cf->snap      = wtap_snapshot_length(cf->wth);
4337   if (cf->snap == 0) {
4338     /* Snapshot length not known. */
4339     cf->has_snap = FALSE;
4340     cf->snap = WTAP_MAX_PACKET_SIZE;
4341   } else
4342     cf->has_snap = TRUE;
4343
4344   name_ptr = g_filename_display_basename(cf->filename);
4345
4346   cf_callback_invoke(cf_cb_file_rescan_started, cf);
4347
4348   /* Record whether the file is compressed.
4349      XXX - do we know this at open time? */
4350   cf->iscompressed = wtap_iscompressed(cf->wth);
4351
4352   /* Find the size of the file. */
4353   size = wtap_file_size(cf->wth, NULL);
4354
4355   g_timer_start(prog_timer);
4356
4357   cf->stop_flag = FALSE;
4358   g_get_current_time(&start_time);
4359
4360   framenum = 0;
4361   phdr = wtap_phdr(cf->wth);
4362   while ((wtap_read(cf->wth, err, &err_info, &data_offset))) {
4363     framenum++;
4364     fdata = frame_data_sequence_find(cf->frames, framenum);
4365     fdata->file_off = data_offset;
4366     if (size >= 0) {
4367       count++;
4368       cf->f_datalen = wtap_read_so_far(cf->wth);
4369
4370       /* Create the progress bar if necessary. */
4371       if (progress_is_slow(progbar, prog_timer, size, cf->f_datalen)) {
4372         progbar_val = calc_progbar_val(cf, size, cf->f_datalen, status_str, sizeof(status_str));
4373         progbar = delayed_create_progress_dlg(cf->window, "Rescanning", name_ptr,
4374                                               TRUE, &cf->stop_flag, &start_time, progbar_val);
4375       }
4376
4377       /*
4378        * Update the progress bar, but do it only after PROGBAR_UPDATE_INTERVAL
4379        * has elapsed. Calling update_progress_dlg and packets_bar_update will
4380        * likely trigger UI paint events, which might take a while depending on
4381        * the platform and display. Reset our timer *after* painting.
4382        */
4383       if (progbar && g_timer_elapsed(prog_timer, NULL) > PROGBAR_UPDATE_INTERVAL) {
4384         progbar_val = calc_progbar_val(cf, size, cf->f_datalen, status_str, sizeof(status_str));
4385         /* update the packet bar content on the first run or frequently on very large files */
4386         update_progress_dlg(progbar, progbar_val, status_str);
4387         packets_bar_update();
4388         g_timer_start(prog_timer);
4389       }
4390     }
4391
4392     if (cf->stop_flag) {
4393       /* Well, the user decided to abort the rescan.  Sadly, as this
4394          isn't a reread, recovering is difficult, so we'll just
4395          close the current capture. */
4396       break;
4397     }
4398
4399     /* Add this packet's link-layer encapsulation type to cf->linktypes, if
4400        it's not already there.
4401        XXX - yes, this is O(N), so if every packet had a different
4402        link-layer encapsulation type, it'd be O(N^2) to read the file, but
4403        there are probably going to be a small number of encapsulation types
4404        in a file. */
4405     cf_add_encapsulation_type(cf, phdr->pkt_encap);
4406   }
4407
4408   /* Free the display name */
4409   g_free(name_ptr);
4410
4411   /* We're done reading the file; destroy the progress bar if it was created. */
4412   if (progbar != NULL)
4413     destroy_progress_dlg(progbar);
4414   g_timer_destroy(prog_timer);
4415
4416   /* We're done reading sequentially through the file. */
4417   cf->state = FILE_READ_DONE;
4418
4419   /* Close the sequential I/O side, to free up memory it requires. */
4420   wtap_sequential_close(cf->wth);
4421
4422   /* compute the time it took to load the file */
4423   compute_elapsed(cf, &start_time);
4424
4425   /* Set the file encapsulation type now; we don't know what it is until
4426      we've looked at all the packets, as we don't know until then whether
4427      there's more than one type (and thus whether it's
4428      WTAP_ENCAP_PER_PACKET). */
4429   cf->lnk_t = wtap_file_encap(cf->wth);
4430
4431   cf_callback_invoke(cf_cb_file_rescan_finished, cf);
4432
4433   if (cf->stop_flag) {
4434     /* Our caller will give up at this point. */
4435     return CF_READ_ABORTED;
4436   }
4437
4438   if (*err != 0) {
4439     /* Put up a message box noting that the read failed somewhere along
4440        the line.  Don't throw out the stuff we managed to read, though,
4441        if any. */
4442     switch (*err) {
4443
4444     case WTAP_ERR_UNSUPPORTED:
4445       simple_error_message_box(
4446                  "The capture file contains record data that Wireshark doesn't support.\n(%s)",
4447                  err_info != NULL ? err_info : "no information supplied");
4448       g_free(err_info);
4449       break;
4450
4451     case WTAP_ERR_SHORT_READ:
4452       simple_error_message_box(
4453                  "The capture file appears to have been cut short"
4454                  " in the middle of a packet.");
4455       break;
4456
4457     case WTAP_ERR_BAD_FILE:
4458       simple_error_message_box(
4459                  "The capture file appears to be damaged or corrupt.\n(%s)",
4460                  err_info != NULL ? err_info : "no information supplied");
4461       g_free(err_info);
4462       break;
4463
4464     case WTAP_ERR_DECOMPRESS:
4465       simple_error_message_box(
4466                  "The compressed capture file appears to be damaged or corrupt.\n"
4467                  "(%s)",
4468                  err_info != NULL ? err_info : "no information supplied");
4469       g_free(err_info);
4470       break;
4471
4472     default:
4473       simple_error_message_box(
4474                  "An error occurred while reading the"
4475                  " capture file: %s.", wtap_strerror(*err));
4476       break;
4477     }
4478     return CF_READ_ERROR;
4479   } else
4480     return CF_READ_OK;
4481 }
4482
4483 cf_write_status_t
4484 cf_save_records(capture_file *cf, const char *fname, guint save_format,
4485                 gboolean compressed, gboolean discard_comments,
4486                 gboolean dont_reopen)
4487 {
4488   gchar           *err_info;
4489   gchar           *fname_new = NULL;
4490   wtap_dumper     *pdh;
4491   frame_data      *fdata;
4492   addrinfo_lists_t *addr_lists;
4493   guint            framenum;
4494   int              err;
4495 #ifdef _WIN32
4496   gchar           *display_basename;
4497 #endif
4498   enum {
4499      SAVE_WITH_MOVE,
4500      SAVE_WITH_COPY,
4501      SAVE_WITH_WTAP
4502   }                    how_to_save;
4503   save_callback_args_t callback_args;
4504
4505   cf_callback_invoke(cf_cb_file_save_started, (gpointer)fname);
4506
4507   addr_lists = get_addrinfo_list();
4508
4509   if (save_format == cf->cd_t && compressed == cf->iscompressed
4510       && !discard_comments && !cf->unsaved_changes
4511       && !(addr_lists && wtap_dump_has_name_resolution(save_format))) {
4512     /* We're saving in the format it's already in, and we're
4513        not discarding comments, and there are no changes we have
4514        in memory that aren't saved to the file, and we have no name
4515        resolution blocks to write, so we can just move or copy the raw data. */
4516
4517     if (cf->is_tempfile) {
4518       /* The file being saved is a temporary file from a live
4519          capture, so it doesn't need to stay around under that name;
4520          first, try renaming the capture buffer file to the new name.
4521          This acts as a "safe save", in that, if the file already
4522          exists, the existing file will be removed only if the rename
4523          succeeds.
4524
4525          Sadly, on Windows, as we have the current capture file
4526          open, even MoveFileEx() with MOVEFILE_REPLACE_EXISTING
4527          (to cause the rename to remove an existing target), as
4528          done by ws_stdio_rename() (ws_rename() is #defined to
4529          be ws_stdio_rename() on Windows) will fail.
4530
4531          According to the MSDN documentation for CreateFile(), if,
4532          when we open a capture file, we were to directly do a CreateFile(),
4533          opening with FILE_SHARE_DELETE|FILE_SHARE_READ, and then
4534          convert it to a file descriptor with _open_osfhandle(),
4535          that would allow the file to be renamed out from under us.
4536
4537          However, that doesn't work in practice.  Perhaps the problem
4538          is that the process doing the rename is the process that
4539          has the file open. */
4540 #ifndef _WIN32
4541       if (ws_rename(cf->filename, fname) == 0) {
4542         /* That succeeded - there's no need to copy the source file. */
4543         how_to_save = SAVE_WITH_MOVE;
4544       } else {
4545         if (errno == EXDEV) {
4546           /* They're on different file systems, so we have to copy the
4547              file. */
4548           how_to_save = SAVE_WITH_COPY;
4549         } else {
4550           /* The rename failed, but not because they're on different
4551              file systems - put up an error message.  (Or should we
4552              just punt and try to copy?  The only reason why I'd
4553              expect the rename to fail and the copy to succeed would
4554              be if we didn't have permission to remove the file from
4555              the temporary directory, and that might be fixable - but
4556              is it worth requiring the user to go off and fix it?) */
4557           cf_rename_failure_alert_box(fname, errno);
4558           goto fail;
4559         }
4560       }
4561 #else
4562       how_to_save = SAVE_WITH_COPY;
4563 #endif
4564     } else {
4565       /* It's a permanent file, so we should copy it, and not remove the
4566          original. */
4567       how_to_save = SAVE_WITH_COPY;
4568     }
4569
4570     if (how_to_save == SAVE_WITH_COPY) {
4571       /* Copy the file, if we haven't moved it.  If we're overwriting
4572          an existing file, we do it with a "safe save", by writing
4573          to a new file and, if the write succeeds, renaming the
4574          new file on top of the old file. */
4575       if (file_exists(fname)) {
4576         fname_new = g_strdup_printf("%s~", fname);
4577         if (!copy_file_binary_mode(cf->filename, fname_new))
4578           goto fail;
4579       } else {
4580         if (!copy_file_binary_mode(cf->filename, fname))
4581           goto fail;
4582       }
4583     }
4584   } else {
4585     /* Either we're saving in a different format or we're saving changes,
4586        such as added, modified, or removed comments, that haven't yet
4587        been written to the underlying file; we can't do that by copying
4588        or moving the capture file, we have to do it by writing the packets
4589        out in Wiretap. */
4590
4591     GArray                      *shb_hdrs = NULL;
4592     wtapng_iface_descriptions_t *idb_inf = NULL;
4593     GArray                      *nrb_hdrs = NULL;
4594     int encap;
4595
4596     /* XXX: what free's this shb_hdr? */
4597     shb_hdrs = wtap_file_get_shb_for_new_file(cf->wth);
4598     idb_inf = wtap_file_get_idb_info(cf->wth);
4599     nrb_hdrs = wtap_file_get_nrb_for_new_file(cf->wth);
4600
4601     /* Determine what file encapsulation type we should use. */
4602     encap = wtap_dump_file_encap_type(cf->linktypes);
4603
4604     if (file_exists(fname)) {
4605       /* We're overwriting an existing file; write out to a new file,
4606          and, if that succeeds, rename the new file on top of the
4607          old file.  That makes this a "safe save", so that we don't
4608          lose the old file if we have a problem writing out the new
4609          file.  (If the existing file is the current capture file,
4610          we *HAVE* to do that, otherwise we're overwriting the file
4611          from which we're reading the packets that we're writing!) */
4612       fname_new = g_strdup_printf("%s~", fname);
4613       pdh = wtap_dump_open_ng(fname_new, save_format, encap, cf->snap,
4614                               compressed, shb_hdrs, idb_inf, nrb_hdrs, &err);
4615     } else {
4616       pdh = wtap_dump_open_ng(fname, save_format, encap, cf->snap,
4617                               compressed, shb_hdrs, idb_inf, nrb_hdrs, &err);
4618     }
4619     g_free(idb_inf);
4620     idb_inf = NULL;
4621
4622     if (pdh == NULL) {
4623       cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
4624       goto fail;
4625     }
4626
4627     /* Add address resolution */
4628     wtap_dump_set_addrinfo_list(pdh, addr_lists);
4629
4630     /* Iterate through the list of packets, processing all the packets. */
4631     callback_args.pdh = pdh;
4632     callback_args.fname = fname;
4633     callback_args.file_type = save_format;
4634     switch (process_specified_records(cf, NULL, "Saving", "packets",
4635                                       TRUE, save_record, &callback_args, TRUE)) {
4636
4637     case PSP_FINISHED:
4638       /* Completed successfully. */
4639       break;
4640
4641     case PSP_STOPPED:
4642       /* The user decided to abort the saving.
4643          If we're writing to a temporary file, remove it.
4644          XXX - should we do so even if we're not writing to a
4645          temporary file? */
4646       wtap_dump_close(pdh, &err);
4647       if (fname_new != NULL)
4648         ws_unlink(fname_new);
4649       cf_callback_invoke(cf_cb_file_save_stopped, NULL);
4650       return CF_WRITE_ABORTED;
4651
4652     case PSP_FAILED:
4653       /* Error while saving.
4654          If we're writing to a temporary file, remove it. */
4655       if (fname_new != NULL)
4656         ws_unlink(fname_new);
4657       wtap_dump_close(pdh, &err);
4658       goto fail;
4659     }
4660
4661     if (!wtap_dump_close(pdh, &err)) {
4662       cf_close_failure_alert_box(fname, err);
4663       goto fail;
4664     }
4665
4666     how_to_save = SAVE_WITH_WTAP;
4667   }
4668
4669   if (fname_new != NULL) {
4670     /* We wrote out to fname_new, and should rename it on top of
4671        fname.  fname_new is now closed, so that should be possible even
4672        on Windows.  However, on Windows, we first need to close whatever
4673        file descriptors we have open for fname. */
4674 #ifdef _WIN32
4675     wtap_fdclose(cf->wth);
4676 #endif
4677     /* Now do the rename. */
4678     if (ws_rename(fname_new, fname) == -1) {
4679       /* Well, the rename failed. */
4680       cf_rename_failure_alert_box(fname, errno);
4681 #ifdef _WIN32
4682       /* Attempt to reopen the random file descriptor using the
4683          current file's filename.  (At this point, the sequential
4684          file descriptor is closed.) */
4685       if (!wtap_fdreopen(cf->wth, cf->filename, &err)) {
4686         /* Oh, well, we're screwed. */
4687         display_basename = g_filename_display_basename(cf->filename);
4688         simple_error_message_box(
4689                       file_open_error_message(err, FALSE), display_basename);
4690         g_free(display_basename);
4691       }
4692 #endif
4693       goto fail;
4694     }
4695   }
4696
4697   cf_callback_invoke(cf_cb_file_save_finished, NULL);
4698   cf->unsaved_changes = FALSE;
4699
4700   if (!dont_reopen) {
4701     switch (how_to_save) {
4702
4703     case SAVE_WITH_MOVE:
4704       /* We just moved the file, so the wtap structure refers to the
4705          new file, and all the information other than the filename
4706          and the "is temporary" status applies to the new file; just
4707          update that. */
4708       g_free(cf->filename);
4709       cf->filename = g_strdup(fname);
4710       cf->is_tempfile = FALSE;
4711       cf_callback_invoke(cf_cb_file_fast_save_finished, cf);
4712       break;
4713
4714     case SAVE_WITH_COPY:
4715       /* We just copied the file, s all the information other than
4716          the wtap structure, the filename, and the "is temporary"
4717          status applies to the new file; just update that. */
4718       wtap_close(cf->wth);
4719       /* Although we're just "copying" and then opening the copy, it will
4720          try all open_routine readers to open the copy, so we need to
4721          reset the cfile's open_type. */
4722       cf->open_type = WTAP_TYPE_AUTO;
4723       cf->wth = wtap_open_offline(fname, WTAP_TYPE_AUTO, &err, &err_info, TRUE);
4724       if (cf->wth == NULL) {
4725         cf_open_failure_alert_box(fname, err, err_info, FALSE, 0);
4726         cf_close(cf);
4727       } else {
4728         g_free(cf->filename);
4729         cf->filename = g_strdup(fname);
4730         cf->is_tempfile = FALSE;
4731       }
4732       cf_callback_invoke(cf_cb_file_fast_save_finished, cf);
4733       break;
4734
4735     case SAVE_WITH_WTAP:
4736       /* Open and read the file we saved to.
4737
4738          XXX - this is somewhat of a waste; we already have the
4739          packets, all this gets us is updated file type information
4740          (which we could just stuff into "cf"), and having the new
4741          file be the one we have opened and from which we're reading
4742          the data, and it means we have to spend time opening and
4743          reading the file, which could be a significant amount of
4744          time if the file is large.
4745
4746          If the capture-file-writing code were to return the
4747          seek offset of each packet it writes, we could save that
4748          in the frame_data structure for the frame, and just open
4749          the file without reading it again...
4750
4751          ...as long as, for gzipped files, the process of writing
4752          out the file *also* generates the information needed to
4753          support fast random access to the compressed file. */
4754       /* rescan_file will cause us to try all open_routines, so
4755          reset cfile's open_type */
4756       cf->open_type = WTAP_TYPE_AUTO;
4757       if (rescan_file(cf, fname, FALSE, &err) != CF_READ_OK) {
4758         /* The rescan failed; just close the file.  Either
4759            a dialog was popped up for the failure, so the
4760            user knows what happened, or they stopped the
4761            rescan, in which case they know what happened. */
4762         cf_close(cf);
4763       }
4764       break;
4765     }
4766
4767     /* If we were told to discard the comments, do so. */
4768     if (discard_comments) {
4769       /* Remove SHB comment, if any. */
4770       wtap_write_shb_comment(cf->wth, NULL);
4771
4772       /* remove all user comments */
4773       for (framenum = 1; framenum <= cf->count; framenum++) {
4774         fdata = frame_data_sequence_find(cf->frames, framenum);
4775
4776         fdata->flags.has_phdr_comment = FALSE;
4777         fdata->flags.has_user_comment = FALSE;
4778       }
4779
4780       if (cf->frames_user_comments) {
4781         g_tree_destroy(cf->frames_user_comments);
4782         cf->frames_user_comments = NULL;
4783       }
4784
4785       cf->packet_comment_count = 0;
4786     }
4787   }
4788   return CF_WRITE_OK;
4789
4790 fail:
4791   if (fname_new != NULL) {
4792     /* We were trying to write to a temporary file; get rid of it if it
4793        exists.  (We don't care whether this fails, as, if it fails,
4794        there's not much we can do about it.  I guess if it failed for
4795        a reason other than "it doesn't exist", we could report an
4796        error, so the user knows there's a junk file that they might
4797        want to clean up.) */
4798     ws_unlink(fname_new);
4799     g_free(fname_new);
4800   }
4801   cf_callback_invoke(cf_cb_file_save_failed, NULL);
4802   return CF_WRITE_ERROR;
4803 }
4804
4805 cf_write_status_t
4806 cf_export_specified_packets(capture_file *cf, const char *fname,
4807                             packet_range_t *range, guint save_format,
4808                             gboolean compressed)
4809 {
4810   gchar                       *fname_new = NULL;
4811   int                          err;
4812   wtap_dumper                 *pdh;
4813   save_callback_args_t         callback_args;
4814   GArray                      *shb_hdrs = NULL;
4815   wtapng_iface_descriptions_t *idb_inf = NULL;
4816   GArray                      *nrb_hdrs = NULL;
4817   int                          encap;
4818
4819   cf_callback_invoke(cf_cb_file_export_specified_packets_started, (gpointer)fname);
4820
4821   packet_range_process_init(range);
4822
4823   /* We're writing out specified packets from the specified capture
4824      file to another file.  Even if all captured packets are to be
4825      written, don't special-case the operation - read each packet
4826      and then write it out if it's one of the specified ones. */
4827
4828   /* XXX: what free's this shb_hdr? */
4829   shb_hdrs = wtap_file_get_shb_for_new_file(cf->wth);
4830   idb_inf = wtap_file_get_idb_info(cf->wth);
4831   nrb_hdrs = wtap_file_get_nrb_for_new_file(cf->wth);
4832
4833   /* Determine what file encapsulation type we should use. */
4834   encap = wtap_dump_file_encap_type(cf->linktypes);
4835
4836   if (file_exists(fname)) {
4837     /* We're overwriting an existing file; write out to a new file,
4838        and, if that succeeds, rename the new file on top of the
4839        old file.  That makes this a "safe save", so that we don't
4840        lose the old file if we have a problem writing out the new
4841        file.  (If the existing file is the current capture file,
4842        we *HAVE* to do that, otherwise we're overwriting the file
4843        from which we're reading the packets that we're writing!) */
4844     fname_new = g_strdup_printf("%s~", fname);
4845     pdh = wtap_dump_open_ng(fname_new, save_format, encap, cf->snap,
4846                             compressed, shb_hdrs, idb_inf, nrb_hdrs, &err);
4847   } else {
4848     pdh = wtap_dump_open_ng(fname, save_format, encap, cf->snap,
4849                             compressed, shb_hdrs, idb_inf, nrb_hdrs, &err);
4850   }
4851   g_free(idb_inf);
4852   idb_inf = NULL;
4853
4854   if (pdh == NULL) {
4855     cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
4856     goto fail;
4857   }
4858
4859   /* Add address resolution */
4860   wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list());
4861
4862   /* Iterate through the list of packets, processing the packets we were
4863      told to process.
4864
4865      XXX - we've already called "packet_range_process_init(range)", but
4866      "process_specified_records()" will do it again.  Fortunately,
4867      that's harmless in this case, as we haven't done anything to
4868      "range" since we initialized it. */
4869   callback_args.pdh = pdh;
4870   callback_args.fname = fname;
4871   callback_args.file_type = save_format;
4872   switch (process_specified_records(cf, range, "Writing", "specified records",
4873                                     TRUE, save_record, &callback_args, TRUE)) {
4874
4875   case PSP_FINISHED:
4876     /* Completed successfully. */
4877     break;
4878
4879   case PSP_STOPPED:
4880       /* The user decided to abort the saving.
4881          If we're writing to a temporary file, remove it.
4882          XXX - should we do so even if we're not writing to a
4883          temporary file? */
4884       wtap_dump_close(pdh, &err);
4885       if (fname_new != NULL)
4886         ws_unlink(fname_new);
4887       cf_callback_invoke(cf_cb_file_export_specified_packets_stopped, NULL);
4888       return CF_WRITE_ABORTED;
4889     break;
4890
4891   case PSP_FAILED:
4892     /* Error while saving.
4893        If we're writing to a temporary file, remove it. */
4894     if (fname_new != NULL)
4895       ws_unlink(fname_new);
4896     wtap_dump_close(pdh, &err);
4897     goto fail;
4898   }
4899
4900   if (!wtap_dump_close(pdh, &err)) {
4901     cf_close_failure_alert_box(fname, err);
4902     goto fail;
4903   }
4904
4905   if (fname_new != NULL) {
4906     /* We wrote out to fname_new, and should rename it on top of
4907        fname; fname is now closed, so that should be possible even
4908        on Windows.  Do the rename. */
4909     if (ws_rename(fname_new, fname) == -1) {
4910       /* Well, the rename failed. */
4911       cf_rename_failure_alert_box(fname, errno);
4912       goto fail;
4913     }
4914   }
4915
4916   cf_callback_invoke(cf_cb_file_export_specified_packets_finished, NULL);
4917   return CF_WRITE_OK;
4918
4919 fail:
4920   if (fname_new != NULL) {
4921     /* We were trying to write to a temporary file; get rid of it if it
4922        exists.  (We don't care whether this fails, as, if it fails,
4923        there's not much we can do about it.  I guess if it failed for
4924        a reason other than "it doesn't exist", we could report an
4925        error, so the user knows there's a junk file that they might
4926        want to clean up.) */
4927     ws_unlink(fname_new);
4928     g_free(fname_new);
4929   }
4930   cf_callback_invoke(cf_cb_file_export_specified_packets_failed, NULL);
4931   return CF_WRITE_ERROR;
4932 }
4933
4934 static void
4935 cf_open_failure_alert_box(const char *filename, int err, gchar *err_info,
4936                           gboolean for_writing, int file_type)
4937 {
4938   gchar *display_basename;
4939
4940   if (err < 0) {
4941     /* Wiretap error. */
4942     display_basename = g_filename_display_basename(filename);
4943     switch (err) {
4944
4945     case WTAP_ERR_NOT_REGULAR_FILE:
4946       simple_error_message_box(
4947             "The file \"%s\" is a \"special file\" or socket or other non-regular file.",
4948             display_basename);
4949       break;
4950
4951     case WTAP_ERR_RANDOM_OPEN_PIPE:
4952       /* Seen only when opening a capture file for reading. */
4953       simple_error_message_box(
4954             "The file \"%s\" is a pipe or FIFO; Wireshark can't read pipe or FIFO files.\n"
4955             "To capture from a pipe or FIFO use wireshark -i -",
4956             display_basename);
4957       break;
4958
4959     case WTAP_ERR_FILE_UNKNOWN_FORMAT:
4960       /* Seen only when opening a capture file for reading. */
4961       simple_error_message_box(
4962             "The file \"%s\" isn't a capture file in a format Wireshark understands.",
4963             display_basename);
4964       break;
4965
4966     case WTAP_ERR_UNSUPPORTED:
4967       /* Seen only when opening a capture file for reading. */
4968       simple_error_message_box(
4969             "The file \"%s\" contains record data that Wireshark doesn't support.\n"
4970             "(%s)",
4971             display_basename,
4972             err_info != NULL ? err_info : "no information supplied");
4973       g_free(err_info);
4974       break;
4975
4976     case WTAP_ERR_CANT_WRITE_TO_PIPE:
4977       /* Seen only when opening a capture file for writing. */
4978       simple_error_message_box(
4979             "The file \"%s\" is a pipe, and %s capture files can't be "
4980             "written to a pipe.",
4981             display_basename, wtap_file_type_subtype_string(file_type));
4982       break;
4983
4984     case WTAP_ERR_UNWRITABLE_FILE_TYPE:
4985       /* Seen only when opening a capture file for writing. */
4986       simple_error_message_box(
4987             "Wireshark doesn't support writing capture files in that format.");
4988       break;
4989
4990     case WTAP_ERR_UNWRITABLE_ENCAP:
4991       /* Seen only when opening a capture file for writing. */
4992       simple_error_message_box("Wireshark can't save this capture in that format.");
4993       break;
4994
4995     case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
4996       if (for_writing) {
4997         simple_error_message_box(
4998               "Wireshark can't save this capture in that format.");
4999       } else {
5000         simple_error_message_box(
5001               "The file \"%s\" is a capture for a network type that Wireshark doesn't support.",
5002               display_basename);
5003       }
5004       break;
5005
5006     case WTAP_ERR_BAD_FILE:
5007       /* Seen only when opening a capture file for reading. */
5008       simple_error_message_box(
5009             "The file \"%s\" appears to be damaged or corrupt.\n"
5010             "(%s)",
5011             display_basename,
5012             err_info != NULL ? err_info : "no information supplied");
5013       g_free(err_info);
5014       break;
5015
5016     case WTAP_ERR_CANT_OPEN:
5017       if (for_writing) {
5018         simple_error_message_box(
5019               "The file \"%s\" could not be created for some unknown reason.",
5020               display_basename);
5021       } else {
5022         simple_error_message_box(
5023               "The file \"%s\" could not be opened for some unknown reason.",
5024               display_basename);
5025       }
5026       break;
5027
5028     case WTAP_ERR_SHORT_READ:
5029       simple_error_message_box(
5030             "The file \"%s\" appears to have been cut short"
5031             " in the middle of a packet or other data.",
5032             display_basename);
5033       break;
5034
5035     case WTAP_ERR_SHORT_WRITE:
5036       simple_error_message_box(
5037             "A full header couldn't be written to the file \"%s\".",
5038             display_basename);
5039       break;
5040
5041     case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
5042       simple_error_message_box(
5043             "This file type cannot be written as a compressed file.");
5044       break;
5045
5046     case WTAP_ERR_DECOMPRESS:
5047       simple_error_message_box(
5048             "The compressed file \"%s\" appears to be damaged or corrupt.\n"
5049             "(%s)", display_basename,
5050             err_info != NULL ? err_info : "no information supplied");
5051       g_free(err_info);
5052       break;
5053
5054     default:
5055       simple_error_message_box(
5056             "The file \"%s\" could not be %s: %s.",
5057             display_basename,
5058             for_writing ? "created" : "opened",
5059             wtap_strerror(err));
5060       break;
5061     }
5062     g_free(display_basename);
5063   } else {
5064     /* OS error. */
5065     open_failure_alert_box(filename, err, for_writing);
5066   }
5067 }
5068
5069 /*
5070  * XXX - whether we mention the source pathname, the target pathname,
5071  * or both depends on the error and on what we find if we look for
5072  * one or both of them.
5073  */
5074 static void
5075 cf_rename_failure_alert_box(const char *filename, int err)
5076 {
5077   gchar *display_basename;
5078
5079   display_basename = g_filename_display_basename(filename);
5080   switch (err) {
5081
5082   case ENOENT:
5083     /* XXX - should check whether the source exists and, if not,
5084        report it as the problem and, if so, report the destination
5085        as the problem. */
5086     simple_error_message_box("The path to the file \"%s\" doesn't exist.",
5087                              display_basename);
5088     break;
5089
5090   case EACCES:
5091     /* XXX - if we're doing a rename after a safe save, we should
5092        probably say something else. */
5093     simple_error_message_box("You don't have permission to move the capture file to \"%s\".",
5094                              display_basename);
5095     break;
5096
5097   default:
5098     /* XXX - this should probably mention both the source and destination
5099        pathnames. */
5100     simple_error_message_box("The file \"%s\" could not be moved: %s.",
5101                              display_basename, wtap_strerror(err));
5102     break;
5103   }
5104   g_free(display_basename);
5105 }
5106
5107 /* Check for write errors - if the file is being written to an NFS server,
5108    a write error may not show up until the file is closed, as NFS clients
5109    might not send writes to the server until the "write()" call finishes,
5110    so that the write may fail on the server but the "write()" may succeed. */
5111 static void
5112 cf_close_failure_alert_box(const char *filename, int err)
5113 {
5114   gchar *display_basename;
5115
5116   if (err < 0) {
5117     /* Wiretap error. */
5118     display_basename = g_filename_display_basename(filename);
5119     switch (err) {
5120
5121     case WTAP_ERR_CANT_CLOSE:
5122       simple_error_message_box(
5123             "The file \"%s\" couldn't be closed for some unknown reason.",
5124             display_basename);
5125       break;
5126
5127     case WTAP_ERR_SHORT_WRITE:
5128       simple_error_message_box(
5129             "Not all the packets could be written to the file \"%s\".",
5130                     display_basename);
5131       break;
5132
5133     default:
5134       simple_error_message_box(
5135             "An error occurred while closing the file \"%s\": %s.",
5136             display_basename, wtap_strerror(err));
5137       break;
5138     }
5139     g_free(display_basename);
5140   } else {
5141     /* OS error.
5142        We assume that a close error from the OS is really a write error. */
5143     write_failure_alert_box(filename, err);
5144   }
5145 }
5146
5147 /* Reload the current capture file. */
5148 void
5149 cf_reload(capture_file *cf) {
5150   gchar    *filename;
5151   gboolean  is_tempfile;
5152   int       err;
5153
5154   /* If the file could be opened, "cf_open()" calls "cf_close()"
5155      to get rid of state for the old capture file before filling in state
5156      for the new capture file.  "cf_close()" will remove the file if
5157      it's a temporary file; we don't want that to happen (for one thing,
5158      it'd prevent subsequent reopens from working).  Remember whether it's
5159      a temporary file, mark it as not being a temporary file, and then
5160      reopen it as the type of file it was.
5161
5162      Also, "cf_close()" will free "cf->filename", so we must make
5163      a copy of it first. */
5164   filename = g_strdup(cf->filename);
5165   is_tempfile = cf->is_tempfile;
5166   cf->is_tempfile = FALSE;
5167   if (cf_open(cf, filename, cf->open_type, is_tempfile, &err) == CF_OK) {
5168     switch (cf_read(cf, TRUE)) {
5169
5170     case CF_READ_OK:
5171     case CF_READ_ERROR:
5172       /* Just because we got an error, that doesn't mean we were unable
5173          to read any of the file; we handle what we could get from the
5174          file. */
5175       break;
5176
5177     case CF_READ_ABORTED:
5178       /* The user bailed out of re-reading the capture file; the
5179          capture file has been closed - just free the capture file name
5180          string and return (without changing the last containing
5181          directory). */
5182       g_free(filename);
5183       return;
5184     }
5185   } else {
5186     /* The open failed, so "cf->is_tempfile" wasn't set to "is_tempfile".
5187        Instead, the file was left open, so we should restore "cf->is_tempfile"
5188        ourselves.
5189
5190        XXX - change the menu?  Presumably "cf_open()" will do that;
5191        make sure it does! */
5192     cf->is_tempfile = is_tempfile;
5193   }
5194   /* "cf_open()" made a copy of the file name we handed it, so
5195      we should free up our copy. */
5196   g_free(filename);
5197 }
5198
5199 /*
5200  * Editor modelines
5201  *
5202  * Local Variables:
5203  * c-basic-offset: 2
5204  * tab-width: 8
5205  * indent-tabs-mode: nil
5206  * End:
5207  *
5208  * ex: set shiftwidth=2 tabstop=8 expandtab:
5209  * :indentSize=2:tabSize=8:noTabs=true:
5210  */