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