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