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