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