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