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