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