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