6a0d2ba86de1972529e4d48027532f65071afe6f
[metze/wireshark/wip.git] / file.c
1 /* file.c
2  * File I/O routines
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24
25 #include "config.h"
26
27 #ifdef HAVE_UNISTD_H
28 #include <unistd.h>
29 #endif
30
31 #include <time.h>
32
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <errno.h>
38 #include <signal.h>
39
40 #ifdef HAVE_FCNTL_H
41 #include <fcntl.h>
42 #endif
43
44 #include <epan/epan.h>
45 #include <epan/expert.h>
46 #include <epan/filesystem.h>
47
48 #include "color.h"
49 #include "color_filters.h"
50 #include "cfile.h"
51 #include <epan/column.h>
52 #include <epan/packet.h>
53 #include <epan/column-utils.h>
54 #include "file.h"
55 #include "fileset.h"
56 #include "frame_tvbuff.h"
57 #include "wsutil/tempfile.h"
58 #include "merge.h"
59
60 #include <epan/prefs.h>
61 #include <epan/dfilter/dfilter.h>
62 #include <epan/epan_dissect.h>
63 #include <epan/tap.h>
64 #include <epan/dissectors/packet-data.h>
65 #include <epan/dissectors/packet-ber.h>
66 #include <epan/timestamp.h>
67 #include <epan/dfilter/dfilter-macro.h>
68 #include <wsutil/file_util.h>
69 #include <epan/strutil.h>
70 #include <epan/addr_resolv.h>
71
72 #include "ui/alert_box.h"
73 #include "ui/simple_dialog.h"
74 #include "ui/main_statusbar.h"
75 #include "ui/progress_dlg.h"
76 #include "ui/ui_util.h"
77
78 #include "version_info.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 guint32 cum_bytes;
110 static nstime_t first_ts;
111 static frame_data *prev_dis;
112 static frame_data *prev_cap;
113
114 static gulong computed_elapsed;
115
116 static void cf_reset_state(capture_file *cf);
117
118 static int read_packet(capture_file *cf, dfilter_t *dfcode,
119     gboolean create_proto_tree, column_info *cinfo, gint64 offset);
120
121 static void rescan_packets(capture_file *cf, const char *action, const char *action_item, gboolean redissect);
122
123 typedef enum {
124   MR_NOTMATCHED,
125   MR_MATCHED,
126   MR_ERROR
127 } match_result;
128 static match_result match_protocol_tree(capture_file *cf, frame_data *fdata,
129     void *criterion);
130 static void match_subtree_text(proto_node *node, gpointer data);
131 static match_result match_summary_line(capture_file *cf, frame_data *fdata,
132     void *criterion);
133 static match_result match_narrow_and_wide(capture_file *cf, frame_data *fdata,
134     void *criterion);
135 static match_result match_narrow(capture_file *cf, frame_data *fdata,
136     void *criterion);
137 static match_result match_wide(capture_file *cf, frame_data *fdata,
138     void *criterion);
139 static match_result match_binary(capture_file *cf, frame_data *fdata,
140     void *criterion);
141 static match_result match_dfilter(capture_file *cf, frame_data *fdata,
142     void *criterion);
143 static match_result match_marked(capture_file *cf, frame_data *fdata,
144     void *criterion);
145 static match_result match_time_reference(capture_file *cf, frame_data *fdata,
146     void *criterion);
147 static gboolean find_packet(capture_file *cf,
148     match_result (*match_function)(capture_file *, frame_data *, void *),
149     void *criterion, search_direction dir);
150
151 static void cf_open_failure_alert_box(const char *filename, int err,
152                       gchar *err_info, gboolean for_writing,
153                       int file_type);
154 static void cf_rename_failure_alert_box(const char *filename, int err);
155 static void cf_close_failure_alert_box(const char *filename, int err);
156 static void ref_time_packets(capture_file *cf);
157 /* Update the progress bar this many times when reading a file. */
158 #define N_PROGBAR_UPDATES   100
159 /* We read around 200k/100ms don't update the progress bar more often than that */
160 #define MIN_QUANTUM         200000
161 #define MIN_NUMBER_OF_PACKET 1500
162
163 /*
164  * We could probably use g_signal_...() instead of the callbacks below but that
165  * would require linking our CLI programs to libgobject and creating an object
166  * instance for the signals.
167  */
168 typedef struct {
169   cf_callback_t cb_fct;
170   gpointer      user_data;
171 } cf_callback_data_t;
172
173 static GList *cf_callbacks = NULL;
174
175 static void
176 cf_callback_invoke(int event, gpointer data)
177 {
178   cf_callback_data_t *cb;
179   GList              *cb_item = cf_callbacks;
180
181   /* there should be at least one interested */
182   g_assert(cb_item != NULL);
183
184   while (cb_item != NULL) {
185     cb = (cf_callback_data_t *)cb_item->data;
186     cb->cb_fct(event, data, cb->user_data);
187     cb_item = g_list_next(cb_item);
188   }
189 }
190
191
192 void
193 cf_callback_add(cf_callback_t func, gpointer user_data)
194 {
195   cf_callback_data_t *cb;
196
197   cb = g_new(cf_callback_data_t,1);
198   cb->cb_fct = func;
199   cb->user_data = user_data;
200
201   cf_callbacks = g_list_append(cf_callbacks, cb);
202 }
203
204 void
205 cf_callback_remove(cf_callback_t func)
206 {
207   cf_callback_data_t *cb;
208   GList              *cb_item = cf_callbacks;
209
210   while (cb_item != NULL) {
211     cb = (cf_callback_data_t *)cb_item->data;
212     if (cb->cb_fct == func) {
213       cf_callbacks = g_list_remove(cf_callbacks, cb);
214       g_free(cb);
215       return;
216     }
217     cb_item = g_list_next(cb_item);
218   }
219
220   g_assert_not_reached();
221 }
222
223 void
224 cf_timestamp_auto_precision(capture_file *cf)
225 {
226   int i;
227   int prec = timestamp_get_precision();
228
229
230   /* don't try to get the file's precision if none is opened */
231   if (cf->state == FILE_CLOSED) {
232     return;
233   }
234
235   /* if we are in auto mode, set precision of current file */
236   if (prec == TS_PREC_AUTO ||
237      prec == TS_PREC_AUTO_SEC ||
238      prec == TS_PREC_AUTO_DSEC ||
239      prec == TS_PREC_AUTO_CSEC ||
240      prec == TS_PREC_AUTO_MSEC ||
241      prec == TS_PREC_AUTO_USEC ||
242      prec == TS_PREC_AUTO_NSEC)
243   {
244     switch(wtap_file_tsprecision(cf->wth)) {
245     case(WTAP_FILE_TSPREC_SEC):
246       timestamp_set_precision(TS_PREC_AUTO_SEC);
247       break;
248     case(WTAP_FILE_TSPREC_DSEC):
249       timestamp_set_precision(TS_PREC_AUTO_DSEC);
250       break;
251     case(WTAP_FILE_TSPREC_CSEC):
252       timestamp_set_precision(TS_PREC_AUTO_CSEC);
253       break;
254     case(WTAP_FILE_TSPREC_MSEC):
255       timestamp_set_precision(TS_PREC_AUTO_MSEC);
256       break;
257     case(WTAP_FILE_TSPREC_USEC):
258       timestamp_set_precision(TS_PREC_AUTO_USEC);
259       break;
260     case(WTAP_FILE_TSPREC_NSEC):
261       timestamp_set_precision(TS_PREC_AUTO_NSEC);
262       break;
263     default:
264       g_assert_not_reached();
265     }
266   }
267   /* Set the column widths of those columns that show the time in
268      "command-line-specified" format. */
269   for (i = 0; i < cf->cinfo.num_cols; i++) {
270     if (col_has_time_fmt(&cf->cinfo, i)) {
271       packet_list_resize_column(i);
272     }
273   }
274 }
275
276 gulong
277 cf_get_computed_elapsed(void)
278 {
279   return computed_elapsed;
280 }
281
282 static void reset_elapsed(void)
283 {
284   computed_elapsed = 0;
285 }
286
287 /*
288  * GLIB_CHECK_VERSION(2,28,0) adds g_get_real_time which could minimize or
289  * replace this
290  */
291 static void compute_elapsed(GTimeVal *start_time)
292 {
293   gdouble  delta_time;
294   GTimeVal time_now;
295
296   g_get_current_time(&time_now);
297
298   delta_time = (time_now.tv_sec - start_time->tv_sec) * 1e6 +
299     time_now.tv_usec - start_time->tv_usec;
300
301   computed_elapsed = (gulong) (delta_time / 1000); /* ms */
302 }
303
304 cf_status_t
305 cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
306 {
307   wtap  *wth;
308   gchar *err_info;
309
310   wth = wtap_open_offline(fname, err, &err_info, TRUE);
311   if (wth == NULL)
312     goto fail;
313
314   /* The open succeeded.  Close whatever capture file we had open,
315      and fill in the information for this file. */
316   cf_close(cf);
317
318   /* XXX - we really want to initialize this after we've read all
319      the packets, so we know how much we'll ultimately need. */
320   buffer_init(&cf->buf, 1500);
321
322   /* Cleanup all data structures used for dissection. */
323   cleanup_dissection();
324   /* Initialize all data structures used for dissection. */
325   init_dissection();
326
327   /* We're about to start reading the file. */
328   cf->state = FILE_READ_IN_PROGRESS;
329
330   cf->wth = wth;
331   cf->f_datalen = 0;
332
333   /* Set the file name because we need it to set the follow stream filter.
334      XXX - is that still true?  We need it for other reasons, though,
335      in any case. */
336   cf->filename = g_strdup(fname);
337
338   /* Indicate whether it's a permanent or temporary file. */
339   cf->is_tempfile = is_tempfile;
340
341   /* No user changes yet. */
342   cf->unsaved_changes = FALSE;
343
344   reset_elapsed();
345
346   cf->cd_t        = wtap_file_type(cf->wth);
347   cf->linktypes = g_array_sized_new(FALSE, FALSE, (guint) sizeof(int), 1);
348   cf->count     = 0;
349   cf->packet_comment_count = 0;
350   cf->displayed_count = 0;
351   cf->marked_count = 0;
352   cf->ignored_count = 0;
353   cf->ref_time_count = 0;
354   cf->drops_known = FALSE;
355   cf->drops     = 0;
356   cf->snap      = wtap_snapshot_length(cf->wth);
357   if (cf->snap == 0) {
358     /* Snapshot length not known. */
359     cf->has_snap = FALSE;
360     cf->snap = WTAP_MAX_PACKET_SIZE;
361   } else
362     cf->has_snap = TRUE;
363
364   /* Allocate a frame_data_sequence for the frames in this file */
365   cf->frames = new_frame_data_sequence();
366
367   nstime_set_zero(&cf->elapsed_time);
368   nstime_set_unset(&first_ts);
369   prev_dis = NULL;
370   prev_cap = NULL;
371   cum_bytes = 0;
372
373   /* Adjust timestamp precision if auto is selected, col width will be adjusted */
374   cf_timestamp_auto_precision(cf);
375   /* XXX needed ? */
376   packet_list_queue_draw();
377   cf_callback_invoke(cf_cb_file_opened, cf);
378
379   if (cf->cd_t == WTAP_FILE_BER) {
380     /* tell the BER dissector the file name */
381     ber_set_filename(cf->filename);
382   }
383
384   wtap_set_cb_new_ipv4(cf->wth, add_ipv4_name);
385   wtap_set_cb_new_ipv6(cf->wth, (wtap_new_ipv6_callback_t) add_ipv6_name);
386
387   return CF_OK;
388
389 fail:
390   cf_open_failure_alert_box(fname, *err, err_info, FALSE, 0);
391   return CF_ERROR;
392 }
393
394 /*
395  * Add an encapsulation type to cf->linktypes.
396  */
397 static void
398 cf_add_encapsulation_type(capture_file *cf, int encap)
399 {
400   guint i;
401
402   for (i = 0; i < cf->linktypes->len; i++) {
403     if (g_array_index(cf->linktypes, gint, i) == encap)
404       return; /* it's already there */
405   }
406   /* It's not already there - add it. */
407   g_array_append_val(cf->linktypes, encap);
408 }
409
410 /*
411  * Reset the state for the currently closed file, but don't do the
412  * UI callbacks; this is for use in "cf_open()", where we don't
413  * want the UI to go from "file open" to "file closed" back to
414  * "file open", we want it to go from "old file open" to "new file
415  * open and being read".
416  *
417  * XXX - currently, cf_open() calls cf_close(), rather than
418  * cf_reset_state().
419  */
420 static void
421 cf_reset_state(capture_file *cf)
422 {
423   /* Die if we're in the middle of reading a file. */
424   g_assert(cf->state != FILE_READ_IN_PROGRESS);
425
426   if (cf->wth) {
427     wtap_close(cf->wth);
428     cf->wth = NULL;
429   }
430   /* We have no file open... */
431   if (cf->filename != NULL) {
432     /* If it's a temporary file, remove it. */
433     if (cf->is_tempfile)
434       ws_unlink(cf->filename);
435     g_free(cf->filename);
436     cf->filename = NULL;
437   }
438   /* ...which means we have no changes to that file to save. */
439   cf->unsaved_changes = FALSE;
440
441   /* Free up the packet buffer. */
442   buffer_free(&cf->buf);
443
444   dfilter_free(cf->rfcode);
445   cf->rfcode = NULL;
446   if (cf->frames != NULL) {
447     free_frame_data_sequence(cf->frames);
448     cf->frames = NULL;
449   }
450 #ifdef WANT_PACKET_EDITOR
451   if (cf->edited_frames) {
452     g_tree_destroy(cf->edited_frames);
453     cf->edited_frames = NULL;
454   }
455 #endif
456   cf_unselect_packet(cf);   /* nothing to select */
457   cf->first_displayed = 0;
458   cf->last_displayed = 0;
459
460   /* No frames, no frame selected, no field in that frame selected. */
461   cf->count = 0;
462   cf->current_frame = 0;
463   cf->current_row = 0;
464   cf->finfo_selected = NULL;
465
466   /* No frame link-layer types, either. */
467   g_array_free(cf->linktypes, TRUE);
468   cf->linktypes = NULL;
469
470   /* Clear the packet list. */
471   packet_list_freeze();
472   packet_list_clear();
473   packet_list_thaw();
474
475   cf->f_datalen = 0;
476   nstime_set_zero(&cf->elapsed_time);
477
478   reset_tap_listeners();
479
480   /* We have no file open. */
481   cf->state = FILE_CLOSED;
482 }
483
484 /* Reset everything to a pristine state */
485 void
486 cf_close(capture_file *cf)
487 {
488   if (cf->state != FILE_CLOSED) {
489     cf_callback_invoke(cf_cb_file_closing, cf);
490
491   /* close things, if not already closed before */
492     color_filters_cleanup();
493     cf_reset_state(cf);
494     cleanup_dissection();
495
496     cf_callback_invoke(cf_cb_file_closed, cf);
497   }
498 }
499
500 static float
501 calc_progbar_val(capture_file *cf, gint64 size, gint64 file_pos, gchar *status_str, gulong status_size)
502 {
503   float progbar_val;
504
505   progbar_val = (gfloat) file_pos / (gfloat) size;
506   if (progbar_val > 1.0) {
507
508     /*  The file probably grew while we were reading it.
509      *  Update file size, and try again.
510      */
511     size = wtap_file_size(cf->wth, NULL);
512
513     if (size >= 0)
514       progbar_val = (gfloat) file_pos / (gfloat) size;
515
516     /*  If it's still > 1, either "wtap_file_size()" failed (in which
517      *  case there's not much we can do about it), or the file
518      *  *shrank* (in which case there's not much we can do about
519      *  it); just clip the progress value at 1.0.
520      */
521     if (progbar_val > 1.0f)
522       progbar_val = 1.0f;
523   }
524
525   g_snprintf(status_str, status_size,
526              "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
527              file_pos / 1024, size / 1024);
528
529   return progbar_val;
530 }
531
532 cf_read_status_t
533 cf_read(capture_file *cf, gboolean reloading)
534 {
535   int                  err;
536   gchar               *err_info;
537   gchar               *name_ptr;
538   progdlg_t           *progbar        = NULL;
539   gboolean             stop_flag;
540   GTimeVal             start_time;
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   TRY {
578 #ifdef HAVE_LIBPCAP
579     int     displayed_once    = 0;
580 #endif
581     int     count             = 0;
582
583     gint64  size;
584     gint64  file_pos;
585     gint64  data_offset;
586
587     gint64  progbar_quantum;
588     gint64  progbar_nextstep;
589     float   progbar_val;
590     gchar   status_str[100];
591
592     column_info *cinfo;
593
594     cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
595
596     /* Find the size of the file. */
597     size = wtap_file_size(cf->wth, NULL);
598
599     /* Update the progress bar when it gets to this value. */
600     progbar_nextstep = 0;
601     /* When we reach the value that triggers a progress bar update,
602        bump that value by this amount. */
603     if (size >= 0) {
604       progbar_quantum = size/N_PROGBAR_UPDATES;
605       if (progbar_quantum < MIN_QUANTUM)
606         progbar_quantum = MIN_QUANTUM;
607     }else
608       progbar_quantum = 0;
609
610     while ((wtap_read(cf->wth, &err, &err_info, &data_offset))) {
611       if (size >= 0) {
612         count++;
613         file_pos = wtap_read_so_far(cf->wth);
614
615         /* Create the progress bar if necessary.
616          * Check whether it should be created or not every MIN_NUMBER_OF_PACKET
617          */
618         if ((progbar == NULL) && !(count % MIN_NUMBER_OF_PACKET)) {
619           progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
620           if (reloading)
621             progbar = delayed_create_progress_dlg(cf->window, "Reloading", name_ptr,
622                 TRUE, &stop_flag, &start_time, progbar_val);
623           else
624             progbar = delayed_create_progress_dlg(cf->window, "Loading", name_ptr,
625                 TRUE, &stop_flag, &start_time, progbar_val);
626         }
627
628         /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
629            when we update it, we have to run the GTK+ main loop to get it
630            to repaint what's pending, and doing so may involve an "ioctl()"
631            to see if there's any pending input from an X server, and doing
632            that for every packet can be costly, especially on a big file. */
633         if (file_pos >= progbar_nextstep) {
634           if (progbar != NULL) {
635             progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
636             /* update the packet bar content on the first run or frequently on very large files */
637 #ifdef HAVE_LIBPCAP
638             if (progbar_quantum > 500000 || displayed_once == 0) {
639               if ((auto_scroll_live || displayed_once == 0 || cf->displayed_count < 1000) && cf->count != 0) {
640                 displayed_once = 1;
641                 packets_bar_update();
642               }
643             }
644 #endif /* HAVE_LIBPCAP */
645             update_progress_dlg(progbar, progbar_val, status_str);
646           }
647           progbar_nextstep += progbar_quantum;
648         }
649       }
650
651       if (stop_flag) {
652         /* Well, the user decided to abort the read. He/She will be warned and
653            it might be enough for him/her to work with the already loaded
654            packets.
655            This is especially true for very large capture files, where you don't
656            want to wait loading the whole file (which may last minutes or even
657            hours even on fast machines) just to see that it was the wrong file. */
658         break;
659       }
660       read_packet(cf, dfcode, create_proto_tree, cinfo, data_offset);
661     }
662   }
663   CATCH(OutOfMemoryError) {
664     simple_message_box(ESD_TYPE_ERROR, NULL,
665                    "Some infos / workarounds can be found at:\n"
666                    "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
667                    "Sorry, but Wireshark has run out of memory and has to terminate now!");
668 #if 0
669     /* Could we close the current capture and free up memory from that? */
670 #else
671     /* we have to terminate, as we cannot recover from the memory error */
672     exit(1);
673 #endif
674   }
675   ENDTRY;
676
677   /* Free the display name */
678   g_free(name_ptr);
679
680   /* Cleanup and release all dfilter resources */
681   if (dfcode != NULL) {
682     dfilter_free(dfcode);
683   }
684
685   /* We're done reading the file; destroy the progress bar if it was created. */
686   if (progbar != NULL)
687     destroy_progress_dlg(progbar);
688
689   /* We're done reading sequentially through the file. */
690   cf->state = FILE_READ_DONE;
691
692   /* Close the sequential I/O side, to free up memory it requires. */
693   wtap_sequential_close(cf->wth);
694
695   /* Allow the protocol dissectors to free up memory that they
696    * don't need after the sequential run-through of the packets. */
697   postseq_cleanup_all_protocols();
698
699   /* compute the time it took to load the file */
700   compute_elapsed(&start_time);
701
702   /* Set the file encapsulation type now; we don't know what it is until
703      we've looked at all the packets, as we don't know until then whether
704      there's more than one type (and thus whether it's
705      WTAP_ENCAP_PER_PACKET). */
706   cf->lnk_t = wtap_file_encap(cf->wth);
707
708   cf->current_frame = frame_data_sequence_find(cf->frames, cf->first_displayed);
709   cf->current_row = 0;
710
711   packet_list_thaw();
712   if (reloading)
713     cf_callback_invoke(cf_cb_file_reload_finished, cf);
714   else
715     cf_callback_invoke(cf_cb_file_read_finished, cf);
716
717   /* If we have any displayed packets to select, select the first of those
718      packets by making the first row the selected row. */
719   if (cf->first_displayed != 0) {
720     packet_list_select_first_row();
721   }
722
723   if (stop_flag) {
724     simple_message_box(ESD_TYPE_WARN, NULL,
725                   "The remaining packets in the file were discarded.\n"
726                   "\n"
727                   "As a lot of packets from the original file will be missing,\n"
728                   "remember to be careful when saving the current content to a file.\n",
729                   "File loading was cancelled!");
730     return CF_READ_ERROR;
731   }
732
733   if (err != 0) {
734     /* Put up a message box noting that the read failed somewhere along
735        the line.  Don't throw out the stuff we managed to read, though,
736        if any. */
737     switch (err) {
738
739     case WTAP_ERR_UNSUPPORTED:
740       simple_error_message_box(
741                  "The capture file contains record data that Wireshark doesn't support.\n(%s)",
742                  err_info);
743       g_free(err_info);
744       break;
745
746     case WTAP_ERR_UNSUPPORTED_ENCAP:
747       simple_error_message_box(
748                  "The capture file has a packet with a network type that Wireshark doesn't support.\n(%s)",
749                  err_info);
750       g_free(err_info);
751       break;
752
753     case WTAP_ERR_CANT_READ:
754       simple_error_message_box(
755                  "An attempt to read from the capture file failed for"
756                  " some unknown reason.");
757       break;
758
759     case WTAP_ERR_SHORT_READ:
760       simple_error_message_box(
761                  "The capture file appears to have been cut short"
762                  " in the middle of a packet.");
763       break;
764
765     case WTAP_ERR_BAD_FILE:
766       simple_error_message_box(
767                  "The capture file appears to be damaged or corrupt.\n(%s)",
768                  err_info);
769       g_free(err_info);
770       break;
771
772     case WTAP_ERR_DECOMPRESS:
773       simple_error_message_box(
774                  "The compressed capture file appears to be damaged or corrupt.\n"
775                  "(%s)", err_info);
776       g_free(err_info);
777       break;
778
779     default:
780       simple_error_message_box(
781                  "An error occurred while reading the"
782                  " capture file: %s.", wtap_strerror(err));
783       break;
784     }
785     return CF_READ_ERROR;
786   } else
787     return CF_READ_OK;
788 }
789
790 #ifdef HAVE_LIBPCAP
791 cf_status_t
792 cf_start_tail(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
793 {
794   cf_status_t cf_status;
795
796   cf_status = cf_open(cf, fname, is_tempfile, err);
797   return cf_status;
798 }
799
800 cf_read_status_t
801 cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
802 {
803   gchar            *err_info;
804   int               newly_displayed_packets = 0;
805   dfilter_t        *dfcode;
806   volatile gboolean create_proto_tree;
807   guint             tap_flags;
808   gboolean          compiled;
809
810   /* Compile the current display filter.
811    * We assume this will not fail since cf->dfilter is only set in
812    * cf_filter IFF the filter was valid.
813    */
814   compiled = dfilter_compile(cf->dfilter, &dfcode);
815   g_assert(!cf->dfilter || (compiled && dfcode));
816
817   /* Get the union of the flags for all tap listeners. */
818   tap_flags = union_of_tap_listener_flags();
819   create_proto_tree =
820     (dfcode != NULL || have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
821
822   *err = 0;
823
824   packet_list_check_end();
825   /* Don't freeze/thaw the list when doing live capture */
826   /*packet_list_freeze();*/
827
828   /*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: %u new: %u", cf->count, to_read);*/
829
830   TRY {
831     gint64 data_offset = 0;
832     column_info *cinfo;
833
834     cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
835
836     while (to_read != 0) {
837       wtap_cleareof(cf->wth);
838       if (!wtap_read(cf->wth, err, &err_info, &data_offset)) {
839         break;
840       }
841       if (cf->state == FILE_READ_ABORTED) {
842         /* Well, the user decided to exit Wireshark.  Break out of the
843            loop, and let the code below (which is called even if there
844            aren't any packets left to read) exit. */
845         break;
846       }
847       if (read_packet(cf, dfcode, create_proto_tree, (column_info *) cinfo, data_offset) != -1) {
848         newly_displayed_packets++;
849       }
850       to_read--;
851     }
852   }
853   CATCH(OutOfMemoryError) {
854     simple_message_box(ESD_TYPE_ERROR, NULL,
855                    "Some infos / workarounds can be found at:\n"
856                    "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
857                    "Sorry, but Wireshark has run out of memory and has to terminate now!");
858 #if 0
859     /* Could we close the current capture and free up memory from that? */
860     return CF_READ_ABORTED;
861 #else
862     /* we have to terminate, as we cannot recover from the memory error */
863     exit(1);
864 #endif
865   }
866   ENDTRY;
867
868   /* Update the file encapsulation; it might have changed based on the
869      packets we've read. */
870   cf->lnk_t = wtap_file_encap(cf->wth);
871
872   /* Cleanup and release all dfilter resources */
873   if (dfcode != NULL) {
874     dfilter_free(dfcode);
875   }
876
877   /*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: count %u state: %u err: %u",
878     cf->count, cf->state, *err);*/
879
880   /* Don't freeze/thaw the list when doing live capture */
881   /*packet_list_thaw();*/
882   /* With the new packet list the first packet
883    * isn't automatically selected.
884    */
885   if (!cf->current_frame)
886     packet_list_select_first_row();
887
888   /* moving to the end of the packet list - if the user requested so and
889      we have some new packets. */
890   if (newly_displayed_packets && auto_scroll_live && cf->count != 0)
891       packet_list_moveto_end();
892
893   if (cf->state == FILE_READ_ABORTED) {
894     /* Well, the user decided to exit Wireshark.  Return CF_READ_ABORTED
895        so that our caller can kill off the capture child process;
896        this will cause an EOF on the pipe from the child, so
897        "cf_finish_tail()" will be called, and it will clean up
898        and exit. */
899     return CF_READ_ABORTED;
900   } else if (*err != 0) {
901     /* We got an error reading the capture file.
902        XXX - pop up a dialog box instead? */
903     g_warning("Error \"%s\" while reading: \"%s\" (\"%s\")",
904         wtap_strerror(*err), err_info, cf->filename);
905     g_free(err_info);
906
907     return CF_READ_ERROR;
908   } else
909     return CF_READ_OK;
910 }
911
912 void
913 cf_fake_continue_tail(capture_file *cf) {
914   cf->state = FILE_READ_DONE;
915 }
916
917 cf_read_status_t
918 cf_finish_tail(capture_file *cf, int *err)
919 {
920   gchar     *err_info;
921   gint64     data_offset;
922   dfilter_t *dfcode;
923   column_info *cinfo;
924   gboolean   create_proto_tree;
925   guint      tap_flags;
926   gboolean   compiled;
927
928   /* Compile the current display filter.
929    * We assume this will not fail since cf->dfilter is only set in
930    * cf_filter IFF the filter was valid.
931    */
932   compiled = dfilter_compile(cf->dfilter, &dfcode);
933   g_assert(!cf->dfilter || (compiled && dfcode));
934
935   /* Get the union of the flags for all tap listeners. */
936   tap_flags = union_of_tap_listener_flags();
937   cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
938   create_proto_tree =
939     (dfcode != NULL || have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
940
941   if (cf->wth == NULL) {
942     cf_close(cf);
943     return CF_READ_ERROR;
944   }
945
946   packet_list_check_end();
947   /* Don't freeze/thaw the list when doing live capture */
948   /*packet_list_freeze();*/
949
950   while ((wtap_read(cf->wth, err, &err_info, &data_offset))) {
951     if (cf->state == FILE_READ_ABORTED) {
952       /* Well, the user decided to abort the read.  Break out of the
953          loop, and let the code below (which is called even if there
954          aren't any packets left to read) exit. */
955       break;
956     }
957     read_packet(cf, dfcode, create_proto_tree, cinfo, data_offset);
958   }
959
960   /* Cleanup and release all dfilter resources */
961   if (dfcode != NULL) {
962     dfilter_free(dfcode);
963   }
964
965   /* Don't freeze/thaw the list when doing live capture */
966   /*packet_list_thaw();*/
967
968   if (cf->state == FILE_READ_ABORTED) {
969     /* Well, the user decided to abort the read.  We're only called
970        when the child capture process closes the pipe to us (meaning
971        it's probably exited), so we can just close the capture
972        file; we return CF_READ_ABORTED so our caller can do whatever
973        is appropriate when that happens. */
974     cf_close(cf);
975     return CF_READ_ABORTED;
976   }
977
978   if (auto_scroll_live && cf->count != 0)
979     packet_list_moveto_end();
980
981   /* We're done reading sequentially through the file. */
982   cf->state = FILE_READ_DONE;
983
984   /* We're done reading sequentially through the file; close the
985      sequential I/O side, to free up memory it requires. */
986   wtap_sequential_close(cf->wth);
987
988   /* Allow the protocol dissectors to free up memory that they
989    * don't need after the sequential run-through of the packets. */
990   postseq_cleanup_all_protocols();
991
992   /* Update the file encapsulation; it might have changed based on the
993      packets we've read. */
994   cf->lnk_t = wtap_file_encap(cf->wth);
995
996   /* Update the details in the file-set dialog, as the capture file
997    * has likely grown since we first stat-ed it */
998   fileset_update_file(cf->filename);
999
1000   if (*err != 0) {
1001     /* We got an error reading the capture file.
1002        XXX - pop up a dialog box? */
1003
1004     g_warning("Error \"%s\" while reading: \"%s\" (\"%s\")",
1005         wtap_strerror(*err), err_info, cf->filename);
1006     g_free(err_info);
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     dfilter_t *dfcode, gboolean create_proto_tree, column_info *cinfo,
1119     struct wtap_pkthdr *phdr, const guint8 *buf, gboolean add_to_packet_list)
1120 {
1121   epan_dissect_t  edt;
1122   gint            row               = -1;
1123
1124   frame_data_set_before_dissect(fdata, &cf->elapsed_time,
1125                                 &first_ts, prev_dis, prev_cap);
1126   prev_cap = fdata;
1127
1128   /* Dissect the frame. */
1129   epan_dissect_init(&edt, create_proto_tree, FALSE);
1130
1131   if (dfcode != NULL) {
1132       epan_dissect_prime_dfilter(&edt, dfcode);
1133   }
1134
1135   epan_dissect_run_with_taps(&edt, phdr, frame_tvbuff_new(fdata, buf), fdata, cinfo);
1136
1137   /* If we don't have a display filter, set "passed_dfilter" to 1. */
1138   if (dfcode != NULL) {
1139     fdata->flags.passed_dfilter = dfilter_apply_edt(dfcode, &edt) ? 1 : 0;
1140
1141     if (fdata->flags.passed_dfilter) {
1142       /* This frame passed the display filter but it may depend on other
1143        * (potentially not displayed) frames.  Find those frames and mark them
1144        * as depended upon.
1145        */
1146       g_slist_foreach(edt.pi.dependent_frames, find_and_mark_frame_depended_upon, cf->frames);
1147     }
1148   } else
1149     fdata->flags.passed_dfilter = 1;
1150
1151   if (fdata->flags.passed_dfilter || fdata->flags.ref_time)
1152     cf->displayed_count++;
1153
1154   if (add_to_packet_list) {
1155     /* We fill the needed columns from new_packet_list */
1156       row = packet_list_append(cinfo, fdata, &edt.pi);
1157   }
1158
1159   if (fdata->flags.passed_dfilter || fdata->flags.ref_time)
1160   {
1161     frame_data_set_after_dissect(fdata, &cum_bytes);
1162     prev_dis = fdata;
1163
1164     /* If we haven't yet seen the first frame, this is it.
1165
1166        XXX - we must do this before we add the row to the display,
1167        as, if the display's GtkCList's selection mode is
1168        GTK_SELECTION_BROWSE, when the first entry is added to it,
1169        "cf_select_packet()" will be called, and it will fetch the row
1170        data for the 0th row, and will get a null pointer rather than
1171        "fdata", as "gtk_clist_append()" won't yet have returned and
1172        thus "gtk_clist_set_row_data()" won't yet have been called.
1173
1174        We thus need to leave behind bread crumbs so that
1175        "cf_select_packet()" can find this frame.  See the comment
1176        in "cf_select_packet()". */
1177     if (cf->first_displayed == 0)
1178       cf->first_displayed = fdata->num;
1179
1180     /* This is the last frame we've seen so far. */
1181     cf->last_displayed = fdata->num;
1182   }
1183
1184   epan_dissect_cleanup(&edt);
1185   return row;
1186 }
1187
1188 /* read in a new packet */
1189 /* returns the row of the new packet in the packet list or -1 if not displayed */
1190 static int
1191 read_packet(capture_file *cf, dfilter_t *dfcode,
1192             gboolean create_proto_tree, column_info *cinfo, gint64 offset)
1193 {
1194   struct wtap_pkthdr *phdr = wtap_phdr(cf->wth);
1195   const guint8 *buf = wtap_buf_ptr(cf->wth);
1196   frame_data    fdlocal;
1197   guint32       framenum;
1198   frame_data   *fdata;
1199   int           passed;
1200   int           row = -1;
1201
1202   /* Add this packet's link-layer encapsulation type to cf->linktypes, if
1203      it's not already there.
1204      XXX - yes, this is O(N), so if every packet had a different
1205      link-layer encapsulation type, it'd be O(N^2) to read the file, but
1206      there are probably going to be a small number of encapsulation types
1207      in a file. */
1208   cf_add_encapsulation_type(cf, phdr->pkt_encap);
1209
1210   /* The frame number of this packet is one more than the count of
1211      frames in the file so far. */
1212   framenum = cf->count + 1;
1213
1214   frame_data_init(&fdlocal, framenum, phdr, offset, cum_bytes);
1215
1216   passed = TRUE;
1217   if (cf->rfcode) {
1218     epan_dissect_t edt;
1219     epan_dissect_init(&edt, TRUE, FALSE);
1220     epan_dissect_prime_dfilter(&edt, cf->rfcode);
1221     epan_dissect_run(&edt, phdr, frame_tvbuff_new(&fdlocal, buf), &fdlocal, NULL);
1222     passed = dfilter_apply_edt(cf->rfcode, &edt);
1223     epan_dissect_cleanup(&edt);
1224   }
1225
1226   if (passed) {
1227     /* This does a shallow copy of fdlocal, which is good enough. */
1228     fdata = frame_data_sequence_add(cf->frames, &fdlocal);
1229
1230     cf->count++;
1231     if (fdlocal.opt_comment != NULL)
1232       cf->packet_comment_count++;
1233     cf->f_datalen = offset + fdlocal.cap_len;
1234
1235     if (!cf->redissecting) {
1236       row = add_packet_to_packet_list(fdata, cf, dfcode,
1237                                       create_proto_tree, cinfo,
1238                                       phdr, buf, TRUE);
1239     }
1240   }
1241
1242   return row;
1243 }
1244
1245 cf_status_t
1246 cf_merge_files(char **out_filenamep, int in_file_count,
1247                char *const *in_filenames, int file_type, gboolean do_append)
1248 {
1249   merge_in_file_t *in_files, *in_file;
1250   char            *out_filename;
1251   char            *tmpname;
1252   int              out_fd;
1253   wtap_dumper     *pdh;
1254   int              open_err, read_err, write_err, close_err;
1255   gchar           *err_info;
1256   int              err_fileno;
1257   int              i;
1258   gboolean         got_read_error     = FALSE, got_write_error = FALSE;
1259   gint64           data_offset;
1260   progdlg_t       *progbar            = NULL;
1261   gboolean         stop_flag;
1262   gint64           f_len, file_pos;
1263   float            progbar_val;
1264   GTimeVal         start_time;
1265   gchar            status_str[100];
1266   gint64           progbar_nextstep;
1267   gint64           progbar_quantum;
1268   gchar           *display_basename;
1269   int              selected_frame_type;
1270   gboolean         fake_interface_ids = FALSE;
1271
1272   /* open the input files */
1273   if (!merge_open_in_files(in_file_count, in_filenames, &in_files,
1274                            &open_err, &err_info, &err_fileno)) {
1275     g_free(in_files);
1276     cf_open_failure_alert_box(in_filenames[err_fileno], open_err, err_info,
1277                               FALSE, 0);
1278     return CF_ERROR;
1279   }
1280
1281   if (*out_filenamep != NULL) {
1282     out_filename = *out_filenamep;
1283     out_fd = ws_open(out_filename, O_CREAT|O_TRUNC|O_BINARY, 0600);
1284     if (out_fd == -1)
1285       open_err = errno;
1286   } else {
1287     out_fd = create_tempfile(&tmpname, "wireshark");
1288     if (out_fd == -1)
1289       open_err = errno;
1290     out_filename = g_strdup(tmpname);
1291     *out_filenamep = out_filename;
1292   }
1293   if (out_fd == -1) {
1294     err_info = NULL;
1295     merge_close_in_files(in_file_count, in_files);
1296     g_free(in_files);
1297     cf_open_failure_alert_box(out_filename, open_err, NULL, TRUE, file_type);
1298     return CF_ERROR;
1299   }
1300
1301   selected_frame_type = merge_select_frame_type(in_file_count, in_files);
1302
1303   /* If we are trying to merge a number of libpcap files with different encapsulation types
1304    * change the output file type to pcapng and create SHB and IDB:s for the new file use the
1305    * interface index stored in in_files per file to change the phdr before writing the datablock.
1306    * XXX should it be an option to convert to pcapng?
1307    *
1308    * We need something similar when merging pcapng files possibly with an option to say
1309    * the same interface(s) used in all in files. SHBs comments should be merged together.
1310    */
1311   if ((selected_frame_type == WTAP_ENCAP_PER_PACKET)&&(file_type == WTAP_FILE_PCAP)) {
1312     /* Write output in pcapng format */
1313     wtapng_section_t            *shb_hdr;
1314     wtapng_iface_descriptions_t *idb_inf, *idb_inf_merge_file;
1315     wtapng_if_descr_t            int_data, *file_int_data;
1316     GString                     *comment_gstr;
1317
1318     fake_interface_ids = TRUE;
1319     /* Create SHB info */
1320     shb_hdr      = wtap_file_get_shb_info(in_files[0].wth);
1321     comment_gstr = g_string_new("");
1322     g_string_append_printf(comment_gstr, "%s \n",shb_hdr->opt_comment);
1323     g_string_append_printf(comment_gstr, "File created by merging: \n");
1324     file_type = WTAP_FILE_PCAPNG;
1325
1326     for (i = 0; i < in_file_count; i++) {
1327         g_string_append_printf(comment_gstr, "File%d: %s \n",i+1,in_files[i].filename);
1328     }
1329     shb_hdr->section_length = -1;
1330     /* options */
1331     shb_hdr->opt_comment   = g_string_free(comment_gstr, FALSE);  /* NULL if not available */
1332     shb_hdr->shb_hardware  = NULL;        /* NULL if not available, UTF-8 string containing the        */
1333                                           /*  description of the hardware used to create this section. */
1334     shb_hdr->shb_os        = NULL;        /* NULL if not available, UTF-8 string containing the name   */
1335                                           /*  of the operating system used to create this section.     */
1336     shb_hdr->shb_user_appl = "Wireshark"; /* NULL if not available, UTF-8 string containing the name   */
1337                                           /*  of the application used to create this section.          */
1338
1339     /* create fake IDB info */
1340     idb_inf = g_new(wtapng_iface_descriptions_t,1);
1341     idb_inf->number_of_interfaces = in_file_count; /* TODO make this the number of DIFFERENT encapsulation types
1342                                                     * check that snaplength is the same too?
1343                                                     */
1344     idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
1345
1346     for (i = 0; i < in_file_count; i++) {
1347       idb_inf_merge_file               = wtap_file_get_idb_info(in_files[i].wth);
1348       /* read the interface data from the in file to our combined interfca data */
1349       file_int_data = &g_array_index (idb_inf_merge_file->interface_data, wtapng_if_descr_t, 0);
1350       int_data.wtap_encap            = file_int_data->wtap_encap;
1351       int_data.time_units_per_second = file_int_data->time_units_per_second;
1352       int_data.link_type             = file_int_data->link_type;
1353       int_data.snap_len              = file_int_data->snap_len;
1354       int_data.if_name               = g_strdup(file_int_data->if_name);
1355       int_data.opt_comment           = NULL;
1356       int_data.if_description        = NULL;
1357       int_data.if_speed              = 0;
1358       int_data.if_tsresol            = 6;
1359       int_data.if_filter_str         = NULL;
1360       int_data.bpf_filter_len        = 0;
1361       int_data.if_filter_bpf_bytes   = NULL;
1362       int_data.if_os                 = NULL;
1363       int_data.if_fcslen             = -1;
1364       int_data.num_stat_entries      = 0;          /* Number of ISB:s */
1365       int_data.interface_statistics  = NULL;
1366
1367       g_array_append_val(idb_inf->interface_data, int_data);
1368       g_free(idb_inf_merge_file);
1369
1370       /* Set fake interface Id in per file data */
1371       in_files[i].interface_id = i;
1372     }
1373
1374     pdh = wtap_dump_fdopen_ng(out_fd, file_type,
1375                               selected_frame_type,
1376                               merge_max_snapshot_length(in_file_count, in_files),
1377                               FALSE /* compressed */, shb_hdr, idb_inf /* wtapng_iface_descriptions_t *idb_inf */, &open_err);
1378
1379     if (pdh == NULL) {
1380       ws_close(out_fd);
1381       merge_close_in_files(in_file_count, in_files);
1382       g_free(in_files);
1383       cf_open_failure_alert_box(out_filename, open_err, err_info, TRUE,
1384                                 file_type);
1385       return CF_ERROR;
1386     }
1387
1388   } else {
1389
1390     pdh = wtap_dump_fdopen(out_fd, file_type,
1391                            selected_frame_type,
1392                            merge_max_snapshot_length(in_file_count, in_files),
1393                            FALSE /* compressed */, &open_err);
1394     if (pdh == NULL) {
1395       ws_close(out_fd);
1396       merge_close_in_files(in_file_count, in_files);
1397       g_free(in_files);
1398       cf_open_failure_alert_box(out_filename, open_err, err_info, TRUE,
1399                                 file_type);
1400       return CF_ERROR;
1401     }
1402   }
1403
1404   /* Get the sum of the sizes of all the files. */
1405   f_len = 0;
1406   for (i = 0; i < in_file_count; i++)
1407     f_len += in_files[i].size;
1408
1409   /* Update the progress bar when it gets to this value. */
1410   progbar_nextstep = 0;
1411   /* When we reach the value that triggers a progress bar update,
1412      bump that value by this amount. */
1413   progbar_quantum = f_len/N_PROGBAR_UPDATES;
1414   /* Progress so far. */
1415   progbar_val = 0.0f;
1416
1417   stop_flag = FALSE;
1418   g_get_current_time(&start_time);
1419
1420   /* do the merge (or append) */
1421   for (;;) {
1422     if (do_append)
1423       in_file = merge_append_read_packet(in_file_count, in_files, &read_err,
1424                                          &err_info);
1425     else
1426       in_file = merge_read_packet(in_file_count, in_files, &read_err,
1427                                   &err_info);
1428     if (in_file == NULL) {
1429       /* EOF */
1430       break;
1431     }
1432
1433     if (read_err != 0) {
1434       /* I/O error reading from in_file */
1435       got_read_error = TRUE;
1436       break;
1437     }
1438
1439     /* Get the sum of the data offsets in all of the files. */
1440     data_offset = 0;
1441     for (i = 0; i < in_file_count; i++)
1442       data_offset += in_files[i].data_offset;
1443
1444     /* Create the progress bar if necessary.
1445        We check on every iteration of the loop, so that it takes no
1446        longer than the standard time to create it (otherwise, for a
1447        large file, we might take considerably longer than that standard
1448        time in order to get to the next progress bar step). */
1449     if (progbar == NULL) {
1450       progbar = delayed_create_progress_dlg(NULL, "Merging", "files",
1451         FALSE, &stop_flag, &start_time, progbar_val);
1452     }
1453
1454     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1455        when we update it, we have to run the GTK+ main loop to get it
1456        to repaint what's pending, and doing so may involve an "ioctl()"
1457        to see if there's any pending input from an X server, and doing
1458        that for every packet can be costly, especially on a big file. */
1459     if (data_offset >= progbar_nextstep) {
1460         /* Get the sum of the seek positions in all of the files. */
1461         file_pos = 0;
1462         for (i = 0; i < in_file_count; i++)
1463           file_pos += wtap_read_so_far(in_files[i].wth);
1464         progbar_val = (gfloat) file_pos / (gfloat) f_len;
1465         if (progbar_val > 1.0f) {
1466           /* Some file probably grew while we were reading it.
1467              That "shouldn't happen", so we'll just clip the progress
1468              value at 1.0. */
1469           progbar_val = 1.0f;
1470         }
1471         if (progbar != NULL) {
1472           g_snprintf(status_str, sizeof(status_str),
1473                      "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
1474                      file_pos / 1024, f_len / 1024);
1475           update_progress_dlg(progbar, progbar_val, status_str);
1476         }
1477         progbar_nextstep += progbar_quantum;
1478     }
1479
1480     if (stop_flag) {
1481       /* Well, the user decided to abort the merge. */
1482       break;
1483     }
1484
1485     /* If we have WTAP_ENCAP_PER_PACKETend the infiles are of type WTAP_FILE_PCAP
1486      * we need to set the interface id in the paket header = the interface index we used
1487      * in the IDBs interface description for this file(encapsulation type).
1488      */
1489     if (fake_interface_ids) {
1490       struct wtap_pkthdr *phdr;
1491
1492       phdr = wtap_phdr(in_file->wth);
1493       phdr->interface_id = in_file->interface_id;
1494       phdr->presence_flags = phdr->presence_flags | WTAP_HAS_INTERFACE_ID;
1495     }
1496     if (!wtap_dump(pdh, wtap_phdr(in_file->wth),
1497                    wtap_buf_ptr(in_file->wth), &write_err)) {
1498       got_write_error = TRUE;
1499       break;
1500     }
1501   }
1502
1503   /* We're done merging the files; destroy the progress bar if it was created. */
1504   if (progbar != NULL)
1505     destroy_progress_dlg(progbar);
1506
1507   merge_close_in_files(in_file_count, in_files);
1508   if (!got_read_error && !got_write_error) {
1509     if (!wtap_dump_close(pdh, &write_err))
1510       got_write_error = TRUE;
1511   } else
1512     wtap_dump_close(pdh, &close_err);
1513
1514   if (got_read_error) {
1515     /*
1516      * Find the file on which we got the error, and report the error.
1517      */
1518     for (i = 0; i < in_file_count; i++) {
1519       if (in_files[i].state == GOT_ERROR) {
1520         /* Put up a message box noting that a read failed somewhere along
1521            the line. */
1522         display_basename = g_filename_display_basename(in_files[i].filename);
1523         switch (read_err) {
1524
1525         case WTAP_ERR_UNSUPPORTED_ENCAP:
1526           simple_error_message_box(
1527                      "The capture file %s has a packet with a network type that Wireshark doesn't support.\n(%s)",
1528                      display_basename, err_info);
1529           g_free(err_info);
1530           break;
1531
1532         case WTAP_ERR_CANT_READ:
1533           simple_error_message_box(
1534                      "An attempt to read from the capture file %s failed for"
1535                      " some unknown reason.", display_basename);
1536           break;
1537
1538         case WTAP_ERR_SHORT_READ:
1539           simple_error_message_box(
1540                      "The capture file %s appears to have been cut short"
1541                       " in the middle of a packet.", display_basename);
1542           break;
1543
1544         case WTAP_ERR_BAD_FILE:
1545           simple_error_message_box(
1546                      "The capture file %s appears to be damaged or corrupt.\n(%s)",
1547                      display_basename, err_info);
1548           g_free(err_info);
1549           break;
1550
1551         case WTAP_ERR_DECOMPRESS:
1552           simple_error_message_box(
1553                      "The compressed capture file %s appears to be damaged or corrupt.\n"
1554                      "(%s)", display_basename, err_info);
1555           g_free(err_info);
1556           break;
1557
1558         default:
1559           simple_error_message_box(
1560                      "An error occurred while reading the"
1561                      " capture file %s: %s.",
1562                      display_basename,  wtap_strerror(read_err));
1563           break;
1564         }
1565         g_free(display_basename);
1566       }
1567     }
1568   }
1569
1570   if (got_write_error) {
1571     /* Put up an alert box for the write error. */
1572     if (write_err < 0) {
1573       /* Wiretap error. */
1574       switch (write_err) {
1575
1576       case WTAP_ERR_UNSUPPORTED_ENCAP:
1577         /*
1578          * This is a problem with the particular frame we're writing;
1579          * note that, and give the frame number.
1580          */
1581         display_basename = g_filename_display_basename(in_file->filename);
1582         simple_error_message_box(
1583                       "Frame %u of \"%s\" has a network type that can't be saved in a \"%s\" file.",
1584                       in_file->packet_num, display_basename,
1585                       wtap_file_type_string(file_type));
1586         g_free(display_basename);
1587         break;
1588
1589       default:
1590         display_basename = g_filename_display_basename(out_filename);
1591         simple_error_message_box(
1592                       "An error occurred while writing to the file \"%s\": %s.",
1593                       out_filename, wtap_strerror(write_err));
1594         g_free(display_basename);
1595         break;
1596       }
1597     } else {
1598       /* OS error. */
1599       write_failure_alert_box(out_filename, write_err);
1600     }
1601   }
1602
1603   if (got_read_error || got_write_error || stop_flag) {
1604     /* Callers aren't expected to treat an error or an explicit abort
1605        differently - we put up error dialogs ourselves, so they don't
1606        have to. */
1607     return CF_ERROR;
1608   } else
1609     return CF_OK;
1610 }
1611
1612 cf_status_t
1613 cf_filter_packets(capture_file *cf, gchar *dftext, gboolean force)
1614 {
1615   const char *filter_new = dftext ? dftext : "";
1616   const char *filter_old = cf->dfilter ? cf->dfilter : "";
1617   dfilter_t  *dfcode;
1618   GTimeVal    start_time;
1619
1620   /* if new filter equals old one, do nothing unless told to do so */
1621   if (!force && strcmp(filter_new, filter_old) == 0) {
1622     return CF_OK;
1623   }
1624
1625   dfcode=NULL;
1626
1627   if (dftext == NULL) {
1628     /* The new filter is an empty filter (i.e., display all packets).
1629      * so leave dfcode==NULL
1630      */
1631   } else {
1632     /*
1633      * We have a filter; make a copy of it (as we'll be saving it),
1634      * and try to compile it.
1635      */
1636     dftext = g_strdup(dftext);
1637     if (!dfilter_compile(dftext, &dfcode)) {
1638       /* The attempt failed; report an error. */
1639       simple_message_box(ESD_TYPE_ERROR, NULL,
1640           "See the help for a description of the display filter syntax.",
1641           "\"%s\" isn't a valid display filter: %s",
1642           dftext, dfilter_error_msg);
1643       g_free(dftext);
1644       return CF_ERROR;
1645     }
1646
1647     /* Was it empty? */
1648     if (dfcode == NULL) {
1649       /* Yes - free the filter text, and set it to null. */
1650       g_free(dftext);
1651       dftext = NULL;
1652     }
1653   }
1654
1655   /* We have a valid filter.  Replace the current filter. */
1656   g_free(cf->dfilter);
1657   cf->dfilter = dftext;
1658   g_get_current_time(&start_time);
1659
1660
1661   /* Now rescan the packet list, applying the new filter, but not
1662      throwing away information constructed on a previous pass. */
1663   if (dftext == NULL) {
1664     rescan_packets(cf, "Resetting", "Filter", FALSE);
1665   } else {
1666     rescan_packets(cf, "Filtering", dftext, FALSE);
1667   }
1668
1669   /* Cleanup and release all dfilter resources */
1670   dfilter_free(dfcode);
1671
1672   return CF_OK;
1673 }
1674
1675 void
1676 cf_reftime_packets(capture_file *cf)
1677 {
1678   ref_time_packets(cf);
1679 }
1680
1681 void
1682 cf_redissect_packets(capture_file *cf)
1683 {
1684   rescan_packets(cf, "Reprocessing", "all packets", TRUE);
1685 }
1686
1687 gboolean
1688 cf_read_frame_r(capture_file *cf, frame_data *fdata,
1689                 struct wtap_pkthdr *phdr, Buffer *buf)
1690 {
1691   int    err;
1692   gchar *err_info;
1693   gchar *display_basename;
1694
1695 #ifdef WANT_PACKET_EDITOR
1696   /* if fdata->file_off == -1 it means packet was edited, and we must find data inside edited_frames tree */
1697   if (G_UNLIKELY(fdata->file_off == -1)) {
1698     const modified_frame_data *frame = (const modified_frame_data *) g_tree_lookup(cf->edited_frames, GINT_TO_POINTER(fdata->num));
1699
1700     if (!frame) {
1701       simple_error_message_box("fdata->file_off == -1, but can't find modified frame!");
1702       return FALSE;
1703     }
1704
1705     *phdr = frame->phdr;
1706     buffer_assure_space(buf, frame->phdr.caplen);
1707     memcpy(buffer_start_ptr(buf), frame->pd, frame->phdr.caplen);
1708     return TRUE;
1709   }
1710 #endif
1711
1712   if (!wtap_seek_read(cf->wth, fdata->file_off, phdr, buf,
1713                       fdata->cap_len, &err, &err_info)) {
1714     display_basename = g_filename_display_basename(cf->filename);
1715     switch (err) {
1716
1717     case WTAP_ERR_UNSUPPORTED_ENCAP:
1718       simple_error_message_box("The file \"%s\" has a packet with a network type that Wireshark doesn't support.\n(%s)",
1719                  display_basename, err_info);
1720       g_free(err_info);
1721       break;
1722
1723     case WTAP_ERR_BAD_FILE:
1724       simple_error_message_box("An error occurred while reading from the file \"%s\": %s.\n(%s)",
1725                  display_basename, wtap_strerror(err), err_info);
1726       g_free(err_info);
1727       break;
1728
1729     default:
1730       simple_error_message_box(
1731                  "An error occurred while reading from the file \"%s\": %s.",
1732                  display_basename, wtap_strerror(err));
1733       break;
1734     }
1735     g_free(display_basename);
1736     return FALSE;
1737   }
1738   return TRUE;
1739 }
1740
1741 gboolean
1742 cf_read_frame(capture_file *cf, frame_data *fdata)
1743 {
1744   return cf_read_frame_r(cf, fdata, &cf->phdr, &cf->buf);
1745 }
1746
1747 /* Rescan the list of packets, reconstructing the CList.
1748
1749    "action" describes why we're doing this; it's used in the progress
1750    dialog box.
1751
1752    "action_item" describes what we're doing; it's used in the progress
1753    dialog box.
1754
1755    "redissect" is TRUE if we need to make the dissectors reconstruct
1756    any state information they have (because a preference that affects
1757    some dissector has changed, meaning some dissector might construct
1758    its state differently from the way it was constructed the last time). */
1759 static void
1760 rescan_packets(capture_file *cf, const char *action, const char *action_item, gboolean redissect)
1761 {
1762   /* Rescan packets new packet list */
1763   guint32     framenum;
1764   frame_data *fdata;
1765   progdlg_t  *progbar = NULL;
1766   gboolean    stop_flag;
1767   int         count;
1768   frame_data *selected_frame, *preceding_frame, *following_frame, *prev_frame;
1769   int         selected_frame_num, preceding_frame_num, following_frame_num, prev_frame_num;
1770   gboolean    selected_frame_seen;
1771   float       progbar_val;
1772   GTimeVal    start_time;
1773   gchar       status_str[100];
1774   int         progbar_nextstep;
1775   int         progbar_quantum;
1776   dfilter_t  *dfcode;
1777   column_info *cinfo;
1778   gboolean    create_proto_tree;
1779   guint       tap_flags;
1780   gboolean    add_to_packet_list = FALSE;
1781   gboolean    compiled;
1782   guint32     frames_count;
1783
1784   /* Compile the current display filter.
1785    * We assume this will not fail since cf->dfilter is only set in
1786    * cf_filter IFF the filter was valid.
1787    */
1788   compiled = dfilter_compile(cf->dfilter, &dfcode);
1789   g_assert(!cf->dfilter || (compiled && dfcode));
1790
1791   /* Get the union of the flags for all tap listeners. */
1792   tap_flags = union_of_tap_listener_flags();
1793   cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
1794   create_proto_tree =
1795     (dfcode != NULL || have_filtering_tap_listeners() || (tap_flags & TL_REQUIRES_PROTO_TREE));
1796
1797   reset_tap_listeners();
1798   /* Which frame, if any, is the currently selected frame?
1799      XXX - should the selected frame or the focus frame be the "current"
1800      frame, that frame being the one from which "Find Frame" searches
1801      start? */
1802   selected_frame = cf->current_frame;
1803
1804   /* Mark frame num as not found */
1805   selected_frame_num = -1;
1806
1807   /* Freeze the packet list while we redo it, so we don't get any
1808      screen updates while it happens. */
1809   packet_list_freeze();
1810
1811   if (redissect) {
1812     /* We need to re-initialize all the state information that protocols
1813        keep, because some preference that controls a dissector has changed,
1814        which might cause the state information to be constructed differently
1815        by that dissector. */
1816
1817     /* We might receive new packets while redissecting, and we don't
1818        want to dissect those before their time. */
1819     cf->redissecting = TRUE;
1820
1821     /* Cleanup all data structures used for dissection. */
1822     cleanup_dissection();
1823     /* Initialize all data structures used for dissection. */
1824     init_dissection();
1825
1826     /* We need to redissect the packets so we have to discard our old
1827      * packet list store. */
1828     packet_list_clear();
1829     add_to_packet_list = TRUE;
1830   }
1831
1832   /* We don't yet know which will be the first and last frames displayed. */
1833   cf->first_displayed = 0;
1834   cf->last_displayed = 0;
1835
1836   /* We currently don't display any packets */
1837   cf->displayed_count = 0;
1838
1839   /* Iterate through the list of frames.  Call a routine for each frame
1840      to check whether it should be displayed and, if so, add it to
1841      the display list. */
1842   nstime_set_unset(&first_ts);
1843   prev_dis = NULL;
1844   prev_cap = NULL;
1845   cum_bytes = 0;
1846
1847   /* Update the progress bar when it gets to this value. */
1848   progbar_nextstep = 0;
1849   /* When we reach the value that triggers a progress bar update,
1850      bump that value by this amount. */
1851   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
1852   /* Count of packets at which we've looked. */
1853   count = 0;
1854   /* Progress so far. */
1855   progbar_val = 0.0f;
1856
1857   stop_flag = FALSE;
1858   g_get_current_time(&start_time);
1859
1860   /* no previous row yet */
1861   prev_frame_num = -1;
1862   prev_frame = NULL;
1863
1864   preceding_frame_num = -1;
1865   preceding_frame = NULL;
1866   following_frame_num = -1;
1867   following_frame = NULL;
1868
1869   selected_frame_seen = FALSE;
1870
1871   frames_count = cf->count;
1872   for (framenum = 1; framenum <= frames_count; framenum++) {
1873     fdata = frame_data_sequence_find(cf->frames, framenum);
1874
1875     /* Create the progress bar if necessary.
1876        We check on every iteration of the loop, so that it takes no
1877        longer than the standard time to create it (otherwise, for a
1878        large file, we might take considerably longer than that standard
1879        time in order to get to the next progress bar step). */
1880     if (progbar == NULL)
1881       progbar = delayed_create_progress_dlg(cf->window, action, action_item, TRUE,
1882                                             &stop_flag, &start_time,
1883                                             progbar_val);
1884
1885     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1886        when we update it, we have to run the GTK+ main loop to get it
1887        to repaint what's pending, and doing so may involve an "ioctl()"
1888        to see if there's any pending input from an X server, and doing
1889        that for every packet can be costly, especially on a big file. */
1890     if (count >= progbar_nextstep) {
1891       /* let's not divide by zero. I should never be started
1892        * with count == 0, so let's assert that
1893        */
1894       g_assert(cf->count > 0);
1895       progbar_val = (gfloat) count / frames_count;
1896
1897       if (progbar != NULL) {
1898         g_snprintf(status_str, sizeof(status_str),
1899                   "%4u of %u frames", count, frames_count);
1900         update_progress_dlg(progbar, progbar_val, status_str);
1901       }
1902
1903       progbar_nextstep += progbar_quantum;
1904     }
1905
1906     if (stop_flag) {
1907       /* Well, the user decided to abort the filtering.  Just stop.
1908
1909          XXX - go back to the previous filter?  Users probably just
1910          want not to wait for a filtering operation to finish;
1911          unless we cancel by having no filter, reverting to the
1912          previous filter will probably be even more expensive than
1913          continuing the filtering, as it involves going back to the
1914          beginning and filtering, and even with no filter we currently
1915          have to re-generate the entire clist, which is also expensive.
1916
1917          I'm not sure what Network Monitor does, but it doesn't appear
1918          to give you an unfiltered display if you cancel. */
1919       break;
1920     }
1921
1922     count++;
1923
1924     if (redissect) {
1925       /* Since all state for the frame was destroyed, mark the frame
1926        * as not visited, free the GSList referring to the state
1927        * data (the per-frame data itself was freed by
1928        * "init_dissection()"), and null out the GSList pointer. */
1929       frame_data_reset(fdata);
1930       frames_count = cf->count;
1931     }
1932
1933     /* Frame dependencies from the previous dissection/filtering are no longer valid. */
1934     fdata->flags.dependent_of_displayed = 0;
1935
1936     if (!cf_read_frame(cf, fdata))
1937       break; /* error reading the frame */
1938
1939     /* If the previous frame is displayed, and we haven't yet seen the
1940        selected frame, remember that frame - it's the closest one we've
1941        yet seen before the selected frame. */
1942     if (prev_frame_num != -1 && !selected_frame_seen && prev_frame->flags.passed_dfilter) {
1943       preceding_frame_num = prev_frame_num;
1944       preceding_frame = prev_frame;
1945     }
1946     add_packet_to_packet_list(fdata, cf, dfcode, create_proto_tree,
1947                                     cinfo, &cf->phdr,
1948                                     buffer_start_ptr(&cf->buf),
1949                                     add_to_packet_list);
1950
1951     /* If this frame is displayed, and this is the first frame we've
1952        seen displayed after the selected frame, remember this frame -
1953        it's the closest one we've yet seen at or after the selected
1954        frame. */
1955     if (fdata->flags.passed_dfilter && selected_frame_seen && following_frame_num == -1) {
1956       following_frame_num = fdata->num;
1957       following_frame = fdata;
1958     }
1959     if (fdata == selected_frame) {
1960       selected_frame_seen = TRUE;
1961       if (fdata->flags.passed_dfilter)
1962           selected_frame_num = fdata->num;
1963     }
1964
1965     /* Remember this frame - it'll be the previous frame
1966        on the next pass through the loop. */
1967     prev_frame_num = fdata->num;
1968     prev_frame = fdata;
1969   }
1970
1971   /* We are done redissecting the packet list. */
1972   cf->redissecting = FALSE;
1973
1974   if (redissect) {
1975       frames_count = cf->count;
1976     /* Clear out what remains of the visited flags and per-frame data
1977        pointers.
1978
1979        XXX - that may cause various forms of bogosity when dissecting
1980        these frames, as they won't have been seen by this sequential
1981        pass, but the only alternative I see is to keep scanning them
1982        even though the user requested that the scan stop, and that
1983        would leave the user stuck with an Wireshark grinding on
1984        until it finishes.  Should we just stick them with that? */
1985     for (; framenum <= frames_count; framenum++) {
1986       fdata = frame_data_sequence_find(cf->frames, framenum);
1987       frame_data_reset(fdata);
1988     }
1989   }
1990
1991   /* We're done filtering the packets; destroy the progress bar if it
1992      was created. */
1993   if (progbar != NULL)
1994     destroy_progress_dlg(progbar);
1995
1996   /* Unfreeze the packet list. */
1997   if (!add_to_packet_list)
1998     packet_list_recreate_visible_rows();
1999
2000   /* Compute the time it took to filter the file */
2001   compute_elapsed(&start_time);
2002
2003   packet_list_thaw();
2004
2005   if (selected_frame_num == -1) {
2006     /* The selected frame didn't pass the filter. */
2007     if (selected_frame == NULL) {
2008       /* That's because there *was* no selected frame.  Make the first
2009          displayed frame the current frame. */
2010       selected_frame_num = 0;
2011     } else {
2012       /* Find the nearest displayed frame to the selected frame (whether
2013          it's before or after that frame) and make that the current frame.
2014          If the next and previous displayed frames are equidistant from the
2015          selected frame, choose the next one. */
2016       g_assert(following_frame == NULL ||
2017                following_frame->num >= selected_frame->num);
2018       g_assert(preceding_frame == NULL ||
2019                preceding_frame->num <= selected_frame->num);
2020       if (following_frame == NULL) {
2021         /* No frame after the selected frame passed the filter, so we
2022            have to select the last displayed frame before the selected
2023            frame. */
2024         selected_frame_num = preceding_frame_num;
2025         selected_frame = preceding_frame;
2026       } else if (preceding_frame == NULL) {
2027         /* No frame before the selected frame passed the filter, so we
2028            have to select the first displayed frame after the selected
2029            frame. */
2030         selected_frame_num = following_frame_num;
2031         selected_frame = following_frame;
2032       } else {
2033         /* Frames before and after the selected frame passed the filter, so
2034            we'll select the previous frame */
2035         selected_frame_num = preceding_frame_num;
2036         selected_frame = preceding_frame;
2037       }
2038     }
2039   }
2040
2041   if (selected_frame_num == -1) {
2042     /* There are no frames displayed at all. */
2043     cf_unselect_packet(cf);
2044   } else {
2045     /* Either the frame that was selected passed the filter, or we've
2046        found the nearest displayed frame to that frame.  Select it, make
2047        it the focus row, and make it visible. */
2048     /* Set to invalid to force update of packet list and packet details */
2049     cf->current_row = -1;
2050     if (selected_frame_num == 0) {
2051       packet_list_select_first_row();
2052     }else{
2053       if (!packet_list_select_row_from_data(selected_frame)) {
2054         /* We didn't find a row corresponding to this frame.
2055            This means that the frame isn't being displayed currently,
2056            so we can't select it. */
2057         simple_message_box(ESD_TYPE_INFO, NULL,
2058                            "The capture file is probably not fully dissected.",
2059                            "End of capture exceeded!");
2060       }
2061     }
2062   }
2063
2064   /* Cleanup and release all dfilter resources */
2065   dfilter_free(dfcode);
2066 }
2067
2068
2069 /*
2070  * Scan trough all frame data and recalculate the ref time
2071  * without rereading the file.
2072  * XXX - do we need a progres bar or is this fast enough?
2073  */
2074 static void
2075 ref_time_packets(capture_file *cf)
2076 {
2077   guint32     framenum;
2078   frame_data *fdata;
2079
2080   nstime_set_unset(&first_ts);
2081   prev_dis = NULL;
2082   cum_bytes = 0;
2083
2084   for (framenum = 1; framenum <= cf->count; framenum++) {
2085     fdata = frame_data_sequence_find(cf->frames, framenum);
2086
2087     /* just add some value here until we know if it is being displayed or not */
2088     fdata->cum_bytes = cum_bytes + fdata->pkt_len;
2089
2090     /*
2091      *Timestamps
2092      */
2093
2094     /* If we don't have the time stamp of the first packet in the
2095      capture, it's because this is the first packet.  Save the time
2096      stamp of this packet as the time stamp of the first packet. */
2097     if (nstime_is_unset(&first_ts)) {
2098         first_ts  = fdata->abs_ts;
2099     }
2100       /* if this frames is marked as a reference time frame, reset
2101         firstsec and firstusec to this frame */
2102     if (fdata->flags.ref_time) {
2103         first_ts = fdata->abs_ts;
2104     }
2105
2106     /* If we don't have the time stamp of the previous displayed packet,
2107      it's because this is the first displayed packet.  Save the time
2108      stamp of this packet as the time stamp of the previous displayed
2109      packet. */
2110     if (prev_dis == NULL) {
2111         prev_dis = fdata;
2112     }
2113
2114     /* Get the time elapsed between the first packet and this packet. */
2115     nstime_delta(&fdata->rel_ts, &fdata->abs_ts, &first_ts);
2116
2117     /* If it's greater than the current elapsed time, set the elapsed time
2118      to it (we check for "greater than" so as not to be confused by
2119      time moving backwards). */
2120     if ((gint32)cf->elapsed_time.secs < fdata->rel_ts.secs
2121         || ((gint32)cf->elapsed_time.secs == fdata->rel_ts.secs && (gint32)cf->elapsed_time.nsecs < fdata->rel_ts.nsecs)) {
2122         cf->elapsed_time = fdata->rel_ts;
2123     }
2124
2125     /* If this frame is displayed, get the time elapsed between the
2126      previous displayed packet and this packet. */
2127     if ( fdata->flags.passed_dfilter ) {
2128         fdata->prev_dis = prev_dis;
2129         prev_dis = fdata;
2130     }
2131
2132     /*
2133      * Byte counts
2134      */
2135     if ( (fdata->flags.passed_dfilter) || (fdata->flags.ref_time) ) {
2136         /* This frame either passed the display filter list or is marked as
2137         a time reference frame.  All time reference frames are displayed
2138         even if they dont pass the display filter */
2139         if (fdata->flags.ref_time) {
2140             /* if this was a TIME REF frame we should reset the cum_bytes field */
2141             cum_bytes = fdata->pkt_len;
2142             fdata->cum_bytes =  cum_bytes;
2143         } else {
2144             /* increase cum_bytes with this packets length */
2145             cum_bytes += fdata->pkt_len;
2146         }
2147     }
2148   }
2149 }
2150
2151 typedef enum {
2152   PSP_FINISHED,
2153   PSP_STOPPED,
2154   PSP_FAILED
2155 } psp_return_t;
2156
2157 static psp_return_t
2158 process_specified_packets(capture_file *cf, packet_range_t *range,
2159     const char *string1, const char *string2, gboolean terminate_is_stop,
2160     gboolean (*callback)(capture_file *, frame_data *,
2161                          struct wtap_pkthdr *, const guint8 *, void *),
2162     void *callback_args)
2163 {
2164   guint32          framenum;
2165   frame_data      *fdata;
2166   Buffer           buf;
2167   psp_return_t     ret     = PSP_FINISHED;
2168
2169   progdlg_t       *progbar = NULL;
2170   int              progbar_count;
2171   float            progbar_val;
2172   gboolean         progbar_stop_flag;
2173   GTimeVal         progbar_start_time;
2174   gchar            progbar_status_str[100];
2175   int              progbar_nextstep;
2176   int              progbar_quantum;
2177   range_process_e  process_this;
2178   struct wtap_pkthdr phdr;
2179
2180   buffer_init(&buf, 1500);
2181
2182   /* Update the progress bar when it gets to this value. */
2183   progbar_nextstep = 0;
2184   /* When we reach the value that triggers a progress bar update,
2185      bump that value by this amount. */
2186   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
2187   /* Count of packets at which we've looked. */
2188   progbar_count = 0;
2189   /* Progress so far. */
2190   progbar_val = 0.0f;
2191
2192   progbar_stop_flag = FALSE;
2193   g_get_current_time(&progbar_start_time);
2194
2195   if (range != NULL)
2196     packet_range_process_init(range);
2197
2198   /* Iterate through all the packets, printing the packets that
2199      were selected by the current display filter.  */
2200   for (framenum = 1; framenum <= cf->count; framenum++) {
2201     fdata = frame_data_sequence_find(cf->frames, framenum);
2202
2203     /* Create the progress bar if necessary.
2204        We check on every iteration of the loop, so that it takes no
2205        longer than the standard time to create it (otherwise, for a
2206        large file, we might take considerably longer than that standard
2207        time in order to get to the next progress bar step). */
2208     if (progbar == NULL)
2209       progbar = delayed_create_progress_dlg(cf->window, string1, string2,
2210                                             terminate_is_stop,
2211                                             &progbar_stop_flag,
2212                                             &progbar_start_time,
2213                                             progbar_val);
2214
2215     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
2216        when we update it, we have to run the GTK+ main loop to get it
2217        to repaint what's pending, and doing so may involve an "ioctl()"
2218        to see if there's any pending input from an X server, and doing
2219        that for every packet can be costly, especially on a big file. */
2220     if (progbar_count >= progbar_nextstep) {
2221       /* let's not divide by zero. I should never be started
2222        * with count == 0, so let's assert that
2223        */
2224       g_assert(cf->count > 0);
2225       progbar_val = (gfloat) progbar_count / cf->count;
2226
2227       if (progbar != NULL) {
2228         g_snprintf(progbar_status_str, sizeof(progbar_status_str),
2229                    "%4u of %u packets", progbar_count, cf->count);
2230         update_progress_dlg(progbar, progbar_val, progbar_status_str);
2231       }
2232
2233       progbar_nextstep += progbar_quantum;
2234     }
2235
2236     if (progbar_stop_flag) {
2237       /* Well, the user decided to abort the operation.  Just stop,
2238          and arrange to return PSP_STOPPED to our caller, so they know
2239          it was stopped explicitly. */
2240       ret = PSP_STOPPED;
2241       break;
2242     }
2243
2244     progbar_count++;
2245
2246     if (range != NULL) {
2247       /* do we have to process this packet? */
2248       process_this = packet_range_process_packet(range, fdata);
2249       if (process_this == range_process_next) {
2250         /* this packet uninteresting, continue with next one */
2251         continue;
2252       } else if (process_this == range_processing_finished) {
2253         /* all interesting packets processed, stop the loop */
2254         break;
2255       }
2256     }
2257
2258     /* Get the packet */
2259     if (!cf_read_frame_r(cf, fdata, &phdr, &buf)) {
2260       /* Attempt to get the packet failed. */
2261       ret = PSP_FAILED;
2262       break;
2263     }
2264     /* Process the packet */
2265     if (!callback(cf, fdata, &phdr, buffer_start_ptr(&buf), callback_args)) {
2266       /* Callback failed.  We assume it reported the error appropriately. */
2267       ret = PSP_FAILED;
2268       break;
2269     }
2270   }
2271
2272   /* We're done printing the packets; destroy the progress bar if
2273      it was created. */
2274   if (progbar != NULL)
2275     destroy_progress_dlg(progbar);
2276
2277   buffer_free(&buf);
2278
2279   return ret;
2280 }
2281
2282 typedef struct {
2283   gboolean     construct_protocol_tree;
2284   column_info *cinfo;
2285 } retap_callback_args_t;
2286
2287 static gboolean
2288 retap_packet(capture_file *cf _U_, frame_data *fdata,
2289              struct wtap_pkthdr *phdr, const guint8 *pd,
2290              void *argsp)
2291 {
2292   retap_callback_args_t *args = (retap_callback_args_t *)argsp;
2293   epan_dissect_t         edt;
2294
2295   epan_dissect_init(&edt, args->construct_protocol_tree, FALSE);
2296   epan_dissect_run_with_taps(&edt, phdr, frame_tvbuff_new(fdata, pd), fdata, args->cinfo);
2297   epan_dissect_cleanup(&edt);
2298
2299   return TRUE;
2300 }
2301
2302 cf_read_status_t
2303 cf_retap_packets(capture_file *cf)
2304 {
2305   packet_range_t        range;
2306   retap_callback_args_t callback_args;
2307   gboolean              filtering_tap_listeners;
2308   guint                 tap_flags;
2309
2310   /* Do we have any tap listeners with filters? */
2311   filtering_tap_listeners = have_filtering_tap_listeners();
2312
2313   tap_flags = union_of_tap_listener_flags();
2314
2315   /* If any tap listeners have filters, or require the protocol tree,
2316      construct the protocol tree. */
2317   callback_args.construct_protocol_tree = filtering_tap_listeners ||
2318                                           (tap_flags & TL_REQUIRES_PROTO_TREE);
2319
2320   /* If any tap listeners require the columns, construct them. */
2321   callback_args.cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
2322
2323   /* Reset the tap listeners. */
2324   reset_tap_listeners();
2325
2326   /* Iterate through the list of packets, dissecting all packets and
2327      re-running the taps. */
2328   packet_range_init(&range, cf);
2329   packet_range_process_init(&range);
2330   switch (process_specified_packets(cf, &range, "Recalculating statistics on",
2331                                     "all packets", TRUE, retap_packet,
2332                                     &callback_args)) {
2333   case PSP_FINISHED:
2334     /* Completed successfully. */
2335     return CF_READ_OK;
2336
2337   case PSP_STOPPED:
2338     /* Well, the user decided to abort the refiltering.
2339        Return CF_READ_ABORTED so our caller knows they did that. */
2340     return CF_READ_ABORTED;
2341
2342   case PSP_FAILED:
2343     /* Error while retapping. */
2344     return CF_READ_ERROR;
2345   }
2346
2347   g_assert_not_reached();
2348   return CF_READ_OK;
2349 }
2350
2351 typedef struct {
2352   print_args_t *print_args;
2353   gboolean      print_header_line;
2354   char         *header_line_buf;
2355   int           header_line_buf_len;
2356   gboolean      print_formfeed;
2357   gboolean      print_separator;
2358   char         *line_buf;
2359   int           line_buf_len;
2360   gint         *col_widths;
2361   int           num_visible_cols;
2362   gint         *visible_cols;
2363 } print_callback_args_t;
2364
2365 static gboolean
2366 print_packet(capture_file *cf, frame_data *fdata,
2367              struct wtap_pkthdr *phdr, const guint8 *pd,
2368              void *argsp)
2369 {
2370   print_callback_args_t *args = (print_callback_args_t *)argsp;
2371   epan_dissect_t  edt;
2372   int             i;
2373   char           *cp;
2374   int             line_len;
2375   int             column_len;
2376   int             cp_off;
2377   gboolean        proto_tree_needed;
2378   char            bookmark_name[9+10+1];  /* "__frameNNNNNNNNNN__\0" */
2379   char            bookmark_title[6+10+1]; /* "Frame NNNNNNNNNN__\0"  */
2380
2381   /* Create the protocol tree, and make it visible, if we're printing
2382      the dissection or the hex data.
2383      XXX - do we need it if we're just printing the hex data? */
2384   proto_tree_needed =
2385       args->print_args->print_dissections != print_dissections_none || args->print_args->print_hex || have_custom_cols(&cf->cinfo);
2386   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2387
2388   /* Fill in the column information if we're printing the summary
2389      information. */
2390   if (args->print_args->print_summary) {
2391     col_custom_prime_edt(&edt, &cf->cinfo);
2392     epan_dissect_run(&edt, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
2393     epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
2394   } else
2395     epan_dissect_run(&edt, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
2396
2397   if (args->print_formfeed) {
2398     if (!new_page(args->print_args->stream))
2399       goto fail;
2400   } else {
2401       if (args->print_separator) {
2402         if (!print_line(args->print_args->stream, 0, ""))
2403           goto fail;
2404       }
2405   }
2406
2407   /*
2408    * We generate bookmarks, if the output format supports them.
2409    * The name is "__frameN__".
2410    */
2411   g_snprintf(bookmark_name, sizeof bookmark_name, "__frame%u__", fdata->num);
2412
2413   if (args->print_args->print_summary) {
2414     if (!args->print_args->print_col_headings)
2415         args->print_header_line = FALSE;
2416     if (args->print_header_line) {
2417       if (!print_line(args->print_args->stream, 0, args->header_line_buf))
2418         goto fail;
2419       args->print_header_line = FALSE;  /* we might not need to print any more */
2420     }
2421     cp = &args->line_buf[0];
2422     line_len = 0;
2423     for (i = 0; i < args->num_visible_cols; i++) {
2424       /* Find the length of the string for this column. */
2425       column_len = (int) strlen(cf->cinfo.col_data[args->visible_cols[i]]);
2426       if (args->col_widths[i] > column_len)
2427          column_len = args->col_widths[i];
2428
2429       /* Make sure there's room in the line buffer for the column; if not,
2430          double its length. */
2431       line_len += column_len + 1;   /* "+1" for space */
2432       if (line_len > args->line_buf_len) {
2433         cp_off = (int) (cp - args->line_buf);
2434         args->line_buf_len = 2 * line_len;
2435         args->line_buf = (char *)g_realloc(args->line_buf, args->line_buf_len + 1);
2436         cp = args->line_buf + cp_off;
2437       }
2438
2439       /* Right-justify the packet number column. */
2440       if (cf->cinfo.col_fmt[args->visible_cols[i]] == COL_NUMBER)
2441         g_snprintf(cp, column_len+1, "%*s", args->col_widths[i], cf->cinfo.col_data[args->visible_cols[i]]);
2442       else
2443         g_snprintf(cp, column_len+1, "%-*s", args->col_widths[i], cf->cinfo.col_data[args->visible_cols[i]]);
2444       cp += column_len;
2445       if (i != args->num_visible_cols - 1)
2446         *cp++ = ' ';
2447     }
2448     *cp = '\0';
2449
2450     /*
2451      * Generate a bookmark, using the summary line as the title.
2452      */
2453     if (!print_bookmark(args->print_args->stream, bookmark_name,
2454                         args->line_buf))
2455       goto fail;
2456
2457     if (!print_line(args->print_args->stream, 0, args->line_buf))
2458       goto fail;
2459   } else {
2460     /*
2461      * Generate a bookmark, using "Frame N" as the title, as we're not
2462      * printing the summary line.
2463      */
2464     g_snprintf(bookmark_title, sizeof bookmark_title, "Frame %u", fdata->num);
2465     if (!print_bookmark(args->print_args->stream, bookmark_name,
2466                         bookmark_title))
2467       goto fail;
2468   } /* if (print_summary) */
2469
2470   if (args->print_args->print_dissections != print_dissections_none) {
2471     if (args->print_args->print_summary) {
2472       /* Separate the summary line from the tree with a blank line. */
2473       if (!print_line(args->print_args->stream, 0, ""))
2474         goto fail;
2475     }
2476
2477     /* Print the information in that tree. */
2478     if (!proto_tree_print(args->print_args, &edt, args->print_args->stream))
2479       goto fail;
2480
2481     /* Print a blank line if we print anything after this (aka more than one packet). */
2482     args->print_separator = TRUE;
2483
2484     /* Print a header line if we print any more packet summaries */
2485     if (args->print_args->print_col_headings)
2486         args->print_header_line = TRUE;
2487   }
2488
2489   if (args->print_args->print_hex) {
2490     if (args->print_args->print_summary || (args->print_args->print_dissections != print_dissections_none)) {
2491       if (!print_line(args->print_args->stream, 0, ""))
2492         goto fail;
2493     }
2494     /* Print the full packet data as hex. */
2495     if (!print_hex_data(args->print_args->stream, &edt))
2496       goto fail;
2497
2498     /* Print a blank line if we print anything after this (aka more than one packet). */
2499     args->print_separator = TRUE;
2500
2501     /* Print a header line if we print any more packet summaries */
2502     if (args->print_args->print_col_headings)
2503         args->print_header_line = TRUE;
2504   } /* if (args->print_args->print_dissections != print_dissections_none) */
2505
2506   epan_dissect_cleanup(&edt);
2507
2508   /* do we want to have a formfeed between each packet from now on? */
2509   if (args->print_args->print_formfeed) {
2510     args->print_formfeed = TRUE;
2511   }
2512
2513   return TRUE;
2514
2515 fail:
2516   epan_dissect_cleanup(&edt);
2517   return FALSE;
2518 }
2519
2520 cf_print_status_t
2521 cf_print_packets(capture_file *cf, print_args_t *print_args)
2522 {
2523   print_callback_args_t callback_args;
2524   gint          data_width;
2525   char         *cp;
2526   int           i, cp_off, column_len, line_len;
2527   int           num_visible_col = 0, last_visible_col = 0, visible_col_count;
2528   psp_return_t  ret;
2529   GList        *clp;
2530   fmt_data     *cfmt;
2531
2532   callback_args.print_args = print_args;
2533   callback_args.print_header_line = print_args->print_col_headings;
2534   callback_args.header_line_buf = NULL;
2535   callback_args.header_line_buf_len = 256;
2536   callback_args.print_formfeed = FALSE;
2537   callback_args.print_separator = FALSE;
2538   callback_args.line_buf = NULL;
2539   callback_args.line_buf_len = 256;
2540   callback_args.col_widths = NULL;
2541   callback_args.num_visible_cols = 0;
2542   callback_args.visible_cols = NULL;
2543
2544   if (!print_preamble(print_args->stream, cf->filename, wireshark_svnversion)) {
2545     destroy_print_stream(print_args->stream);
2546     return CF_PRINT_WRITE_ERROR;
2547   }
2548
2549   if (print_args->print_summary) {
2550     /* We're printing packet summaries.  Allocate the header line buffer
2551        and get the column widths. */
2552     callback_args.header_line_buf = (char *)g_malloc(callback_args.header_line_buf_len + 1);
2553
2554     /* Find the number of visible columns and the last visible column */
2555     for (i = 0; i < prefs.num_cols; i++) {
2556
2557         clp = g_list_nth(prefs.col_list, i);
2558         if (clp == NULL) /* Sanity check, Invalid column requested */
2559             continue;
2560
2561         cfmt = (fmt_data *) clp->data;
2562         if (cfmt->visible) {
2563             num_visible_col++;
2564             last_visible_col = i;
2565         }
2566     }
2567
2568     /* Find the widths for each of the columns - maximum of the
2569        width of the title and the width of the data - and construct
2570        a buffer with a line containing the column titles. */
2571     callback_args.num_visible_cols = num_visible_col;
2572     callback_args.col_widths = (gint *) g_malloc(sizeof(gint) * num_visible_col);
2573     callback_args.visible_cols = (gint *) g_malloc(sizeof(gint) * num_visible_col);
2574     cp = &callback_args.header_line_buf[0];
2575     line_len = 0;
2576     visible_col_count = 0;
2577     for (i = 0; i < cf->cinfo.num_cols; i++) {
2578
2579       clp = g_list_nth(prefs.col_list, i);
2580       if (clp == NULL) /* Sanity check, Invalid column requested */
2581           continue;
2582
2583       cfmt = (fmt_data *) clp->data;
2584       if (cfmt->visible == FALSE)
2585           continue;
2586
2587       /* Save the order of visible columns */
2588       callback_args.visible_cols[visible_col_count] = i;
2589
2590       /* Don't pad the last column. */
2591       if (i == last_visible_col)
2592         callback_args.col_widths[visible_col_count] = 0;
2593       else {
2594         callback_args.col_widths[visible_col_count] = (gint) strlen(cf->cinfo.col_title[i]);
2595         data_width = get_column_char_width(get_column_format(i));
2596         if (data_width > callback_args.col_widths[visible_col_count])
2597           callback_args.col_widths[visible_col_count] = data_width;
2598       }
2599
2600       /* Find the length of the string for this column. */
2601       column_len = (int) strlen(cf->cinfo.col_title[i]);
2602       if (callback_args.col_widths[i] > column_len)
2603         column_len = callback_args.col_widths[visible_col_count];
2604
2605       /* Make sure there's room in the line buffer for the column; if not,
2606          double its length. */
2607       line_len += column_len + 1;   /* "+1" for space */
2608       if (line_len > callback_args.header_line_buf_len) {
2609         cp_off = (int) (cp - callback_args.header_line_buf);
2610         callback_args.header_line_buf_len = 2 * line_len;
2611         callback_args.header_line_buf = (char *)g_realloc(callback_args.header_line_buf,
2612                                                   callback_args.header_line_buf_len + 1);
2613         cp = callback_args.header_line_buf + cp_off;
2614       }
2615
2616       /* Right-justify the packet number column. */
2617 /*      if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2618         g_snprintf(cp, column_len+1, "%*s", callback_args.col_widths[visible_col_count], cf->cinfo.col_title[i]);
2619       else*/
2620       g_snprintf(cp, column_len+1, "%-*s", callback_args.col_widths[visible_col_count], cf->cinfo.col_title[i]);
2621       cp += column_len;
2622       if (i != cf->cinfo.num_cols - 1)
2623         *cp++ = ' ';
2624
2625       visible_col_count++;
2626     }
2627     *cp = '\0';
2628
2629     /* Now start out the main line buffer with the same length as the
2630        header line buffer. */
2631     callback_args.line_buf_len = callback_args.header_line_buf_len;
2632     callback_args.line_buf = (char *)g_malloc(callback_args.line_buf_len + 1);
2633   } /* if (print_summary) */
2634
2635   /* Iterate through the list of packets, printing the packets we were
2636      told to print. */
2637   ret = process_specified_packets(cf, &print_args->range, "Printing",
2638                                   "selected packets", TRUE, print_packet,
2639                                   &callback_args);
2640
2641   g_free(callback_args.header_line_buf);
2642   g_free(callback_args.line_buf);
2643   g_free(callback_args.col_widths);
2644   g_free(callback_args.visible_cols);
2645
2646   switch (ret) {
2647
2648   case PSP_FINISHED:
2649     /* Completed successfully. */
2650     break;
2651
2652   case PSP_STOPPED:
2653     /* Well, the user decided to abort the printing.
2654
2655        XXX - note that what got generated before they did that
2656        will get printed if we're piping to a print program; we'd
2657        have to write to a file and then hand that to the print
2658        program to make it actually not print anything. */
2659     break;
2660
2661   case PSP_FAILED:
2662     /* Error while printing.
2663
2664        XXX - note that what got generated before they did that
2665        will get printed if we're piping to a print program; we'd
2666        have to write to a file and then hand that to the print
2667        program to make it actually not print anything. */
2668     destroy_print_stream(print_args->stream);
2669     return CF_PRINT_WRITE_ERROR;
2670   }
2671
2672   if (!print_finale(print_args->stream)) {
2673     destroy_print_stream(print_args->stream);
2674     return CF_PRINT_WRITE_ERROR;
2675   }
2676
2677   if (!destroy_print_stream(print_args->stream))
2678     return CF_PRINT_WRITE_ERROR;
2679
2680   return CF_PRINT_OK;
2681 }
2682
2683 static gboolean
2684 write_pdml_packet(capture_file *cf _U_, frame_data *fdata,
2685                   struct wtap_pkthdr *phdr, const guint8 *pd,
2686           void *argsp)
2687 {
2688   FILE           *fh = (FILE *)argsp;
2689   epan_dissect_t  edt;
2690
2691   /* Create the protocol tree, but don't fill in the column information. */
2692   epan_dissect_init(&edt, TRUE, TRUE);
2693   epan_dissect_run(&edt, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
2694
2695   /* Write out the information in that tree. */
2696   proto_tree_write_pdml(&edt, fh);
2697
2698   epan_dissect_cleanup(&edt);
2699
2700   return !ferror(fh);
2701 }
2702
2703 cf_print_status_t
2704 cf_write_pdml_packets(capture_file *cf, print_args_t *print_args)
2705 {
2706   FILE         *fh;
2707   psp_return_t  ret;
2708
2709   fh = ws_fopen(print_args->file, "w");
2710   if (fh == NULL)
2711     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2712
2713   write_pdml_preamble(fh, cf->filename);
2714   if (ferror(fh)) {
2715     fclose(fh);
2716     return CF_PRINT_WRITE_ERROR;
2717   }
2718
2719   /* Iterate through the list of packets, printing the packets we were
2720      told to print. */
2721   ret = process_specified_packets(cf, &print_args->range, "Writing PDML",
2722                                   "selected packets", TRUE,
2723                                   write_pdml_packet, fh);
2724
2725   switch (ret) {
2726
2727   case PSP_FINISHED:
2728     /* Completed successfully. */
2729     break;
2730
2731   case PSP_STOPPED:
2732     /* Well, the user decided to abort the printing. */
2733     break;
2734
2735   case PSP_FAILED:
2736     /* Error while printing. */
2737     fclose(fh);
2738     return CF_PRINT_WRITE_ERROR;
2739   }
2740
2741   write_pdml_finale(fh);
2742   if (ferror(fh)) {
2743     fclose(fh);
2744     return CF_PRINT_WRITE_ERROR;
2745   }
2746
2747   /* XXX - check for an error */
2748   fclose(fh);
2749
2750   return CF_PRINT_OK;
2751 }
2752
2753 static gboolean
2754 write_psml_packet(capture_file *cf, frame_data *fdata,
2755                   struct wtap_pkthdr *phdr, const guint8 *pd,
2756           void *argsp)
2757 {
2758   FILE           *fh = (FILE *)argsp;
2759   epan_dissect_t  edt;
2760   gboolean        proto_tree_needed;
2761
2762   /* Fill in the column information, only create the protocol tree
2763      if having custom columns. */
2764   proto_tree_needed = have_custom_cols(&cf->cinfo);
2765   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2766   col_custom_prime_edt(&edt, &cf->cinfo);
2767   epan_dissect_run(&edt, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
2768   epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
2769
2770   /* Write out the information in that tree. */
2771   proto_tree_write_psml(&edt, fh);
2772
2773   epan_dissect_cleanup(&edt);
2774
2775   return !ferror(fh);
2776 }
2777
2778 cf_print_status_t
2779 cf_write_psml_packets(capture_file *cf, print_args_t *print_args)
2780 {
2781   FILE         *fh;
2782   psp_return_t  ret;
2783
2784   fh = ws_fopen(print_args->file, "w");
2785   if (fh == NULL)
2786     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2787
2788   write_psml_preamble(fh);
2789   if (ferror(fh)) {
2790     fclose(fh);
2791     return CF_PRINT_WRITE_ERROR;
2792   }
2793
2794   /* Iterate through the list of packets, printing the packets we were
2795      told to print. */
2796   ret = process_specified_packets(cf, &print_args->range, "Writing PSML",
2797                                   "selected packets", TRUE,
2798                                   write_psml_packet, fh);
2799
2800   switch (ret) {
2801
2802   case PSP_FINISHED:
2803     /* Completed successfully. */
2804     break;
2805
2806   case PSP_STOPPED:
2807     /* Well, the user decided to abort the printing. */
2808     break;
2809
2810   case PSP_FAILED:
2811     /* Error while printing. */
2812     fclose(fh);
2813     return CF_PRINT_WRITE_ERROR;
2814   }
2815
2816   write_psml_finale(fh);
2817   if (ferror(fh)) {
2818     fclose(fh);
2819     return CF_PRINT_WRITE_ERROR;
2820   }
2821
2822   /* XXX - check for an error */
2823   fclose(fh);
2824
2825   return CF_PRINT_OK;
2826 }
2827
2828 static gboolean
2829 write_csv_packet(capture_file *cf, frame_data *fdata,
2830                  struct wtap_pkthdr *phdr, const guint8 *pd,
2831                  void *argsp)
2832 {
2833   FILE           *fh = (FILE *)argsp;
2834   epan_dissect_t  edt;
2835   gboolean        proto_tree_needed;
2836
2837   /* Fill in the column information, only create the protocol tree
2838      if having custom columns. */
2839   proto_tree_needed = have_custom_cols(&cf->cinfo);
2840   epan_dissect_init(&edt, proto_tree_needed, proto_tree_needed);
2841   col_custom_prime_edt(&edt, &cf->cinfo);
2842   epan_dissect_run(&edt, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
2843   epan_dissect_fill_in_columns(&edt, FALSE, TRUE);
2844
2845   /* Write out the information in that tree. */
2846   proto_tree_write_csv(&edt, fh);
2847
2848   epan_dissect_cleanup(&edt);
2849
2850   return !ferror(fh);
2851 }
2852
2853 cf_print_status_t
2854 cf_write_csv_packets(capture_file *cf, print_args_t *print_args)
2855 {
2856   FILE         *fh;
2857   psp_return_t  ret;
2858
2859   fh = ws_fopen(print_args->file, "w");
2860   if (fh == NULL)
2861     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2862
2863   write_csv_preamble(fh);
2864   if (ferror(fh)) {
2865     fclose(fh);
2866     return CF_PRINT_WRITE_ERROR;
2867   }
2868
2869   /* Iterate through the list of packets, printing the packets we were
2870      told to print. */
2871   ret = process_specified_packets(cf, &print_args->range, "Writing CSV",
2872                                   "selected packets", TRUE,
2873                                   write_csv_packet, fh);
2874
2875   switch (ret) {
2876
2877   case PSP_FINISHED:
2878     /* Completed successfully. */
2879     break;
2880
2881   case PSP_STOPPED:
2882     /* Well, the user decided to abort the printing. */
2883     break;
2884
2885   case PSP_FAILED:
2886     /* Error while printing. */
2887     fclose(fh);
2888     return CF_PRINT_WRITE_ERROR;
2889   }
2890
2891   write_csv_finale(fh);
2892   if (ferror(fh)) {
2893     fclose(fh);
2894     return CF_PRINT_WRITE_ERROR;
2895   }
2896
2897   /* XXX - check for an error */
2898   fclose(fh);
2899
2900   return CF_PRINT_OK;
2901 }
2902
2903 static gboolean
2904 write_carrays_packet(capture_file *cf _U_, frame_data *fdata,
2905              struct wtap_pkthdr *phdr,
2906              const guint8 *pd, void *argsp)
2907 {
2908   FILE           *fh = (FILE *)argsp;
2909   epan_dissect_t  edt;
2910
2911   epan_dissect_init(&edt, TRUE, TRUE);
2912   epan_dissect_run(&edt, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
2913   proto_tree_write_carrays(fdata->num, fh, &edt);
2914   epan_dissect_cleanup(&edt);
2915
2916   return !ferror(fh);
2917 }
2918
2919 cf_print_status_t
2920 cf_write_carrays_packets(capture_file *cf, print_args_t *print_args)
2921 {
2922   FILE         *fh;
2923   psp_return_t  ret;
2924
2925   fh = ws_fopen(print_args->file, "w");
2926
2927   if (fh == NULL)
2928     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2929
2930   write_carrays_preamble(fh);
2931
2932   if (ferror(fh)) {
2933     fclose(fh);
2934     return CF_PRINT_WRITE_ERROR;
2935   }
2936
2937   /* Iterate through the list of packets, printing the packets we were
2938      told to print. */
2939   ret = process_specified_packets(cf, &print_args->range,
2940                   "Writing C Arrays",
2941                   "selected packets", TRUE,
2942                                   write_carrays_packet, fh);
2943   switch (ret) {
2944   case PSP_FINISHED:
2945     /* Completed successfully. */
2946     break;
2947   case PSP_STOPPED:
2948     /* Well, the user decided to abort the printing. */
2949     break;
2950   case PSP_FAILED:
2951     /* Error while printing. */
2952     fclose(fh);
2953     return CF_PRINT_WRITE_ERROR;
2954   }
2955
2956   write_carrays_finale(fh);
2957
2958   if (ferror(fh)) {
2959     fclose(fh);
2960     return CF_PRINT_WRITE_ERROR;
2961   }
2962
2963   fclose(fh);
2964   return CF_PRINT_OK;
2965 }
2966
2967 gboolean
2968 cf_find_packet_protocol_tree(capture_file *cf, const char *string,
2969                              search_direction dir)
2970 {
2971   match_data mdata;
2972
2973   mdata.string = string;
2974   mdata.string_len = strlen(string);
2975   return find_packet(cf, match_protocol_tree, &mdata, dir);
2976 }
2977
2978 gboolean
2979 cf_find_string_protocol_tree(capture_file *cf, proto_tree *tree,  match_data *mdata)
2980 {
2981   mdata->frame_matched = FALSE;
2982   mdata->string = convert_string_case(cf->sfilter, cf->case_type);
2983   mdata->string_len = strlen(mdata->string);
2984   mdata->cf = cf;
2985   /* Iterate through all the nodes looking for matching text */
2986   proto_tree_children_foreach(tree, match_subtree_text, mdata);
2987   return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
2988 }
2989
2990 static match_result
2991 match_protocol_tree(capture_file *cf, frame_data *fdata, void *criterion)
2992 {
2993   match_data     *mdata = (match_data *)criterion;
2994   epan_dissect_t  edt;
2995
2996   /* Load the frame's data. */
2997   if (!cf_read_frame(cf, fdata)) {
2998     /* Attempt to get the packet failed. */
2999     return MR_ERROR;
3000   }
3001
3002   /* Construct the protocol tree, including the displayed text */
3003   epan_dissect_init(&edt, TRUE, TRUE);
3004   /* We don't need the column information */
3005   epan_dissect_run(&edt, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata, NULL);
3006
3007   /* Iterate through all the nodes, seeing if they have text that matches. */
3008   mdata->cf = cf;
3009   mdata->frame_matched = FALSE;
3010   proto_tree_children_foreach(edt.tree, match_subtree_text, mdata);
3011   epan_dissect_cleanup(&edt);
3012   return mdata->frame_matched ? MR_MATCHED : MR_NOTMATCHED;
3013 }
3014
3015 static void
3016 match_subtree_text(proto_node *node, gpointer data)
3017 {
3018   match_data   *mdata      = (match_data *) data;
3019   const gchar  *string     = mdata->string;
3020   size_t        string_len = mdata->string_len;
3021   capture_file *cf         = mdata->cf;
3022   field_info   *fi         = PNODE_FINFO(node);
3023   gchar         label_str[ITEM_LABEL_LENGTH];
3024   gchar        *label_ptr;
3025   size_t        label_len;
3026   guint32       i;
3027   guint8        c_char;
3028   size_t        c_match    = 0;
3029
3030   /* dissection with an invisible proto tree? */
3031   g_assert(fi);
3032
3033   if (mdata->frame_matched) {
3034     /* We already had a match; don't bother doing any more work. */
3035     return;
3036   }
3037
3038   /* Don't match invisible entries. */
3039   if (PROTO_ITEM_IS_HIDDEN(node))
3040     return;
3041
3042   /* was a free format label produced? */
3043   if (fi->rep) {
3044     label_ptr = fi->rep->representation;
3045   } else {
3046     /* no, make a generic label */
3047     label_ptr = label_str;
3048     proto_item_fill_label(fi, label_str);
3049   }
3050
3051   /* Does that label match? */
3052   label_len = strlen(label_ptr);
3053   for (i = 0; i < label_len; i++) {
3054     c_char = label_ptr[i];
3055     if (cf->case_type)
3056       c_char = toupper(c_char);
3057     if (c_char == string[c_match]) {
3058       c_match++;
3059       if (c_match == string_len) {
3060         /* No need to look further; we have a match */
3061         mdata->frame_matched = TRUE;
3062         mdata->finfo = fi;
3063         return;
3064       }
3065     } else
3066       c_match = 0;
3067   }
3068
3069   /* Recurse into the subtree, if it exists */
3070   if (node->first_child != NULL)
3071     proto_tree_children_foreach(node, match_subtree_text, mdata);
3072 }
3073
3074 gboolean
3075 cf_find_packet_summary_line(capture_file *cf, const char *string,
3076                             search_direction dir)
3077 {
3078   match_data mdata;
3079
3080   mdata.string = string;
3081   mdata.string_len = strlen(string);
3082   return find_packet(cf, match_summary_line, &mdata, dir);
3083 }
3084
3085 static match_result
3086 match_summary_line(capture_file *cf, frame_data *fdata, void *criterion)
3087 {
3088   match_data     *mdata      = (match_data *)criterion;
3089   const gchar    *string     = mdata->string;
3090   size_t          string_len = mdata->string_len;
3091   epan_dissect_t  edt;
3092   const char     *info_column;
3093   size_t          info_column_len;
3094   match_result    result     = MR_NOTMATCHED;
3095   gint            colx;
3096   guint32         i;
3097   guint8          c_char;
3098   size_t          c_match    = 0;
3099
3100   /* Load the frame's data. */
3101   if (!cf_read_frame(cf, fdata)) {
3102     /* Attempt to get the packet failed. */
3103     return MR_ERROR;
3104   }
3105
3106   /* Don't bother constructing the protocol tree */
3107   epan_dissect_init(&edt, FALSE, FALSE);
3108   /* Get the column information */
3109   epan_dissect_run(&edt, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata,
3110                    &cf->cinfo);
3111
3112   /* Find the Info column */
3113   for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
3114     if (cf->cinfo.fmt_matx[colx][COL_INFO]) {
3115       /* Found it.  See if we match. */
3116       info_column = edt.pi.cinfo->col_data[colx];
3117       info_column_len = strlen(info_column);
3118       for (i = 0; i < info_column_len; i++) {
3119         c_char = info_column[i];
3120         if (cf->case_type)
3121           c_char = toupper(c_char);
3122         if (c_char == string[c_match]) {
3123           c_match++;
3124           if (c_match == string_len) {
3125             result = MR_MATCHED;
3126             break;
3127           }
3128         } else
3129           c_match = 0;
3130       }
3131       break;
3132     }
3133   }
3134   epan_dissect_cleanup(&edt);
3135   return result;
3136 }
3137
3138 typedef struct {
3139     const guint8 *data;
3140     size_t        data_len;
3141 } cbs_t;    /* "Counted byte string" */
3142
3143
3144 /*
3145  * The current match_* routines only support ASCII case insensitivity and don't
3146  * convert UTF-8 inputs to UTF-16 for matching.
3147  *
3148  * We could modify them to use the GLib Unicode routines or the International
3149  * Components for Unicode library but it's not apparent that we could do so
3150  * without consuming a lot more CPU and memory or that searching would be
3151  * significantly better.
3152  */
3153
3154 gboolean
3155 cf_find_packet_data(capture_file *cf, const guint8 *string, size_t string_size,
3156                     search_direction dir)
3157 {
3158   cbs_t info;
3159
3160   info.data = string;
3161   info.data_len = string_size;
3162
3163   /* String or hex search? */
3164   if (cf->string) {
3165     /* String search - what type of string? */
3166     switch (cf->scs_type) {
3167
3168     case SCS_NARROW_AND_WIDE:
3169       return find_packet(cf, match_narrow_and_wide, &info, dir);
3170
3171     case SCS_NARROW:
3172       return find_packet(cf, match_narrow, &info, dir);
3173
3174     case SCS_WIDE:
3175       return find_packet(cf, match_wide, &info, dir);
3176
3177     default:
3178       g_assert_not_reached();
3179       return FALSE;
3180     }
3181   } else
3182     return find_packet(cf, match_binary, &info, dir);
3183 }
3184
3185 static match_result
3186 match_narrow_and_wide(capture_file *cf, frame_data *fdata, void *criterion)
3187 {
3188   cbs_t        *info       = (cbs_t *)criterion;
3189   const guint8 *ascii_text = info->data;
3190   size_t        textlen    = info->data_len;
3191   match_result  result;
3192   guint32       buf_len;
3193   guint8       *pd;
3194   guint32       i;
3195   guint8        c_char;
3196   size_t        c_match    = 0;
3197
3198   /* Load the frame's data. */
3199   if (!cf_read_frame(cf, fdata)) {
3200     /* Attempt to get the packet failed. */
3201     return MR_ERROR;
3202   }
3203
3204   result = MR_NOTMATCHED;
3205   buf_len = fdata->cap_len;
3206   pd = buffer_start_ptr(&cf->buf);
3207   i = 0;
3208   while (i < buf_len) {
3209     c_char = pd[i];
3210     if (cf->case_type)
3211       c_char = toupper(c_char);
3212     if (c_char != '\0') {
3213       if (c_char == ascii_text[c_match]) {
3214         c_match += 1;
3215         if (c_match == textlen) {
3216           result = MR_MATCHED;
3217           cf->search_pos = i; /* Save the position of the last character
3218                                  for highlighting the field. */
3219           break;
3220         }
3221       }
3222       else {
3223         g_assert(i>=c_match);
3224         i -= (guint32)c_match;
3225         c_match = 0;
3226       }
3227     }
3228     i += 1;
3229   }
3230   return result;
3231 }
3232
3233 static match_result
3234 match_narrow(capture_file *cf, frame_data *fdata, void *criterion)
3235 {
3236   guint8       *pd;
3237   cbs_t        *info       = (cbs_t *)criterion;
3238   const guint8 *ascii_text = info->data;
3239   size_t        textlen    = info->data_len;
3240   match_result  result;
3241   guint32       buf_len;
3242   guint32       i;
3243   guint8        c_char;
3244   size_t        c_match    = 0;
3245
3246   /* Load the frame's data. */
3247   if (!cf_read_frame(cf, fdata)) {
3248     /* Attempt to get the packet failed. */
3249     return MR_ERROR;
3250   }
3251
3252   result = MR_NOTMATCHED;
3253   buf_len = fdata->cap_len;
3254   pd = buffer_start_ptr(&cf->buf);
3255   i = 0;
3256   while (i < buf_len) {
3257     c_char = pd[i];
3258     if (cf->case_type)
3259       c_char = toupper(c_char);
3260     if (c_char == ascii_text[c_match]) {
3261       c_match += 1;
3262       if (c_match == textlen) {
3263         result = MR_MATCHED;
3264         cf->search_pos = i; /* Save the position of the last character
3265                                for highlighting the field. */
3266         break;
3267       }
3268     }
3269     else {
3270       g_assert(i>=c_match);
3271       i -= (guint32)c_match;
3272       c_match = 0;
3273     }
3274     i += 1;
3275   }
3276
3277   return result;
3278 }
3279
3280 static match_result
3281 match_wide(capture_file *cf, frame_data *fdata, void *criterion)
3282 {
3283   cbs_t        *info       = (cbs_t *)criterion;
3284   const guint8 *ascii_text = info->data;
3285   size_t        textlen    = info->data_len;
3286   match_result  result;
3287   guint32       buf_len;
3288   guint8       *pd;
3289   guint32       i;
3290   guint8        c_char;
3291   size_t        c_match    = 0;
3292
3293   /* Load the frame's data. */
3294   if (!cf_read_frame(cf, fdata)) {
3295     /* Attempt to get the packet failed. */
3296     return MR_ERROR;
3297   }
3298
3299   result = MR_NOTMATCHED;
3300   buf_len = fdata->cap_len;
3301   pd = buffer_start_ptr(&cf->buf);
3302   i = 0;
3303   while (i < buf_len) {
3304     c_char = pd[i];
3305     if (cf->case_type)
3306       c_char = toupper(c_char);
3307     if (c_char == ascii_text[c_match]) {
3308       c_match += 1;
3309       if (c_match == textlen) {
3310         result = MR_MATCHED;
3311         cf->search_pos = i; /* Save the position of the last character
3312                                for highlighting the field. */
3313         break;
3314       }
3315       i += 1;
3316     }
3317     else {
3318       g_assert(i>=(c_match*2));
3319       i -= (guint32)c_match*2;
3320       c_match = 0;
3321     }
3322     i += 1;
3323   }
3324   return result;
3325 }
3326
3327 static match_result
3328 match_binary(capture_file *cf, frame_data *fdata, void *criterion)
3329 {
3330   cbs_t        *info        = (cbs_t *)criterion;
3331   const guint8 *binary_data = info->data;
3332   size_t        datalen     = info->data_len;
3333   match_result  result;
3334   guint32       buf_len;
3335   guint8       *pd;
3336   guint32       i;
3337   size_t        c_match     = 0;
3338
3339   /* Load the frame's data. */
3340   if (!cf_read_frame(cf, fdata)) {
3341     /* Attempt to get the packet failed. */
3342     return MR_ERROR;
3343   }
3344
3345   result = MR_NOTMATCHED;
3346   buf_len = fdata->cap_len;
3347   pd = buffer_start_ptr(&cf->buf);
3348   i = 0;
3349   while (i < buf_len) {
3350     if (pd[i] == binary_data[c_match]) {
3351       c_match += 1;
3352       if (c_match == datalen) {
3353         result = MR_MATCHED;
3354         cf->search_pos = i; /* Save the position of the last character
3355                                for highlighting the field. */
3356         break;
3357       }
3358     }
3359     else {
3360       g_assert(i>=c_match);
3361       i -= (guint32)c_match;
3362       c_match = 0;
3363     }
3364     i += 1;
3365   }
3366   return result;
3367 }
3368
3369 gboolean
3370 cf_find_packet_dfilter(capture_file *cf, dfilter_t *sfcode,
3371                        search_direction dir)
3372 {
3373   return find_packet(cf, match_dfilter, sfcode, dir);
3374 }
3375
3376 gboolean
3377 cf_find_packet_dfilter_string(capture_file *cf, const char *filter,
3378                               search_direction dir)
3379 {
3380   dfilter_t *sfcode;
3381   gboolean   result;
3382
3383   if (!dfilter_compile(filter, &sfcode)) {
3384      /*
3385       * XXX - this shouldn't happen, as the filter string is machine
3386       * generated
3387       */
3388     return FALSE;
3389   }
3390   if (sfcode == NULL) {
3391     /*
3392      * XXX - this shouldn't happen, as the filter string is machine
3393      * generated.
3394      */
3395     return FALSE;
3396   }
3397   result = find_packet(cf, match_dfilter, sfcode, dir);
3398   dfilter_free(sfcode);
3399   return result;
3400 }
3401
3402 static match_result
3403 match_dfilter(capture_file *cf, frame_data *fdata, void *criterion)
3404 {
3405   dfilter_t      *sfcode = (dfilter_t *)criterion;
3406   epan_dissect_t  edt;
3407   match_result    result;
3408
3409   /* Load the frame's data. */
3410   if (!cf_read_frame(cf, fdata)) {
3411     /* Attempt to get the packet failed. */
3412     return MR_ERROR;
3413   }
3414
3415   epan_dissect_init(&edt, TRUE, FALSE);
3416   epan_dissect_prime_dfilter(&edt, sfcode);
3417   epan_dissect_run(&edt, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata, NULL);
3418   result = dfilter_apply_edt(sfcode, &edt) ? MR_MATCHED : MR_NOTMATCHED;
3419   epan_dissect_cleanup(&edt);
3420   return result;
3421 }
3422
3423 gboolean
3424 cf_find_packet_marked(capture_file *cf, search_direction dir)
3425 {
3426   return find_packet(cf, match_marked, NULL, dir);
3427 }
3428
3429 static match_result
3430 match_marked(capture_file *cf _U_, frame_data *fdata, void *criterion _U_)
3431 {
3432   return fdata->flags.marked ? MR_MATCHED : MR_NOTMATCHED;
3433 }
3434
3435 gboolean
3436 cf_find_packet_time_reference(capture_file *cf, search_direction dir)
3437 {
3438   return find_packet(cf, match_time_reference, NULL, dir);
3439 }
3440
3441 static match_result
3442 match_time_reference(capture_file *cf _U_, frame_data *fdata, void *criterion _U_)
3443 {
3444   return fdata->flags.ref_time ? MR_MATCHED : MR_NOTMATCHED;
3445 }
3446
3447 static gboolean
3448 find_packet(capture_file *cf,
3449             match_result (*match_function)(capture_file *, frame_data *, void *),
3450             void *criterion, search_direction dir)
3451 {
3452   frame_data  *start_fd;
3453   guint32      framenum;
3454   frame_data  *fdata;
3455   frame_data  *new_fd = NULL;
3456   progdlg_t   *progbar = NULL;
3457   gboolean     stop_flag;
3458   int          count;
3459   gboolean     found;
3460   float        progbar_val;
3461   GTimeVal     start_time;
3462   gchar        status_str[100];
3463   int          progbar_nextstep;
3464   int          progbar_quantum;
3465   const char  *title;
3466   match_result result;
3467
3468   start_fd = cf->current_frame;
3469   if (start_fd != NULL)  {
3470     /* Iterate through the list of packets, starting at the packet we've
3471        picked, calling a routine to run the filter on the packet, see if
3472        it matches, and stop if so.  */
3473     count = 0;
3474     framenum = start_fd->num;
3475
3476     /* Update the progress bar when it gets to this value. */
3477     progbar_nextstep = 0;
3478     /* When we reach the value that triggers a progress bar update,
3479        bump that value by this amount. */
3480     progbar_quantum = cf->count/N_PROGBAR_UPDATES;
3481     /* Progress so far. */
3482     progbar_val = 0.0f;
3483
3484     stop_flag = FALSE;
3485     g_get_current_time(&start_time);
3486
3487     title = cf->sfilter?cf->sfilter:"";
3488     for (;;) {
3489       /* Create the progress bar if necessary.
3490          We check on every iteration of the loop, so that it takes no
3491          longer than the standard time to create it (otherwise, for a
3492          large file, we might take considerably longer than that standard
3493          time in order to get to the next progress bar step). */
3494       if (progbar == NULL)
3495          progbar = delayed_create_progress_dlg(cf->window, "Searching", title,
3496            FALSE, &stop_flag, &start_time, progbar_val);
3497
3498       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
3499          when we update it, we have to run the GTK+ main loop to get it
3500          to repaint what's pending, and doing so may involve an "ioctl()"
3501          to see if there's any pending input from an X server, and doing
3502          that for every packet can be costly, especially on a big file. */
3503       if (count >= progbar_nextstep) {
3504         /* let's not divide by zero. I should never be started
3505          * with count == 0, so let's assert that
3506          */
3507         g_assert(cf->count > 0);
3508
3509         progbar_val = (gfloat) count / cf->count;
3510
3511         if (progbar != NULL) {
3512           g_snprintf(status_str, sizeof(status_str),
3513                      "%4u of %u packets", count, cf->count);
3514           update_progress_dlg(progbar, progbar_val, status_str);
3515         }
3516
3517         progbar_nextstep += progbar_quantum;
3518       }
3519
3520       if (stop_flag) {
3521         /* Well, the user decided to abort the search.  Go back to the
3522            frame where we started. */
3523         new_fd = start_fd;
3524         break;
3525       }
3526
3527       /* Go past the current frame. */
3528       if (dir == SD_BACKWARD) {
3529         /* Go on to the previous frame. */
3530         if (framenum == 1) {
3531           /*
3532            * XXX - other apps have a bit more of a detailed message
3533            * for this, and instead of offering "OK" and "Cancel",
3534            * they offer things such as "Continue" and "Cancel";
3535            * we need an API for popping up alert boxes with
3536            * {Verb} and "Cancel".
3537            */
3538
3539           if (prefs.gui_find_wrap)
3540           {
3541               statusbar_push_temporary_msg("Search reached the beginning. Continuing at end.");
3542               framenum = cf->count;     /* wrap around */
3543           }
3544           else
3545           {
3546               statusbar_push_temporary_msg("Search reached the beginning.");
3547               framenum = start_fd->num; /* stay on previous packet */
3548           }
3549         } else
3550           framenum--;
3551       } else {
3552         /* Go on to the next frame. */
3553         if (framenum == cf->count) {
3554           if (prefs.gui_find_wrap)
3555           {
3556               statusbar_push_temporary_msg("Search reached the end. Continuing at beginning.");
3557               framenum = 1;             /* wrap around */
3558           }
3559           else
3560           {
3561               statusbar_push_temporary_msg("Search reached the end.");
3562               framenum = start_fd->num; /* stay on previous packet */
3563           }
3564         } else
3565           framenum++;
3566       }
3567       fdata = frame_data_sequence_find(cf->frames, framenum);
3568
3569       count++;
3570
3571       /* Is this packet in the display? */
3572       if (fdata->flags.passed_dfilter) {
3573         /* Yes.  Does it match the search criterion? */
3574         result = (*match_function)(cf, fdata, criterion);
3575         if (result == MR_ERROR) {
3576           /* Error; our caller has reported the error.  Go back to the frame
3577              where we started. */
3578           new_fd = start_fd;
3579           break;
3580         } else if (result == MR_MATCHED) {
3581           /* Yes.  Go to the new frame. */
3582           new_fd = fdata;
3583           break;
3584         }
3585       }
3586
3587       if (fdata == start_fd) {
3588         /* We're back to the frame we were on originally, and that frame
3589            doesn't match the search filter.  The search failed. */
3590         break;
3591       }
3592     }
3593
3594     /* We're done scanning the packets; destroy the progress bar if it
3595        was created. */
3596     if (progbar != NULL)
3597       destroy_progress_dlg(progbar);
3598   }
3599
3600   if (new_fd != NULL) {
3601     /* Find and select */
3602     cf->search_in_progress = TRUE;
3603     found = packet_list_select_row_from_data(new_fd);
3604     cf->search_in_progress = FALSE;
3605     cf->search_pos = 0; /* Reset the position */
3606     if (!found) {
3607       /* We didn't find a row corresponding to this frame.
3608          This means that the frame isn't being displayed currently,
3609          so we can't select it. */
3610       simple_message_box(ESD_TYPE_INFO, NULL,
3611                          "The capture file is probably not fully dissected.",
3612                          "End of capture exceeded!");
3613       return FALSE;
3614     }
3615     return TRUE;    /* success */
3616   } else
3617     return FALSE;   /* failure */
3618 }
3619
3620 gboolean
3621 cf_goto_frame(capture_file *cf, guint fnumber)
3622 {
3623   frame_data *fdata;
3624
3625   fdata = frame_data_sequence_find(cf->frames, fnumber);
3626
3627   if (fdata == NULL) {
3628     /* we didn't find a packet with that packet number */
3629     statusbar_push_temporary_msg("There is no packet number %u.", fnumber);
3630     return FALSE;   /* we failed to go to that packet */
3631   }
3632   if (!fdata->flags.passed_dfilter) {
3633     /* that packet currently isn't displayed */
3634     /* XXX - add it to the set of displayed packets? */
3635     statusbar_push_temporary_msg("Packet number %u isn't displayed.", fnumber);
3636     return FALSE;   /* we failed to go to that packet */
3637   }
3638
3639   if (!packet_list_select_row_from_data(fdata)) {
3640     /* We didn't find a row corresponding to this frame.
3641        This means that the frame isn't being displayed currently,
3642        so we can't select it. */
3643     simple_message_box(ESD_TYPE_INFO, NULL,
3644                        "The capture file is probably not fully dissected.",
3645                        "End of capture exceeded!");
3646     return FALSE;
3647   }
3648   return TRUE;  /* we got to that packet */
3649 }
3650
3651 gboolean
3652 cf_goto_top_frame(void)
3653 {
3654   /* Find and select */
3655   packet_list_select_first_row();
3656   return TRUE;  /* we got to that packet */
3657 }
3658
3659 gboolean
3660 cf_goto_bottom_frame(void)
3661 {
3662   /* Find and select */
3663   packet_list_select_last_row();
3664   return TRUE;  /* we got to that packet */
3665 }
3666
3667 /*
3668  * Go to frame specified by currently selected protocol tree item.
3669  */
3670 gboolean
3671 cf_goto_framenum(capture_file *cf)
3672 {
3673   header_field_info *hfinfo;
3674   guint32            framenum;
3675
3676   if (cf->finfo_selected) {
3677     hfinfo = cf->finfo_selected->hfinfo;
3678     g_assert(hfinfo);
3679     if (hfinfo->type == FT_FRAMENUM) {
3680       framenum = fvalue_get_uinteger(&cf->finfo_selected->value);
3681       if (framenum != 0)
3682         return cf_goto_frame(cf, framenum);
3683       }
3684   }
3685
3686   return FALSE;
3687 }
3688
3689 /* Select the packet on a given row. */
3690 void
3691 cf_select_packet(capture_file *cf, int row)
3692 {
3693   epan_dissect_t *old_edt;
3694   frame_data     *fdata;
3695
3696   /* Get the frame data struct pointer for this frame */
3697   fdata = packet_list_get_row_data(row);
3698
3699   if (fdata == NULL) {
3700     /* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
3701        the first entry is added to it by "real_insert_row()", that row
3702        is selected (see "real_insert_row()", in "ui/gtk/gtkclist.c", in both
3703        our version and the vanilla GTK+ version).
3704
3705        This means that a "select-row" signal is emitted; this causes
3706        "packet_list_select_cb()" to be called, which causes "cf_select_packet()"
3707        to be called.
3708
3709        "cf_select_packet()" fetches, above, the data associated with the
3710        row that was selected; however, as "gtk_clist_append()", which
3711        called "real_insert_row()", hasn't yet returned, we haven't yet
3712        associated any data with that row, so we get back a null pointer.
3713
3714        We can't assume that there's only one frame in the frame list,
3715        either, as we may be filtering the display.
3716
3717        We therefore assume that, if "row" is 0, i.e. the first row
3718        is being selected, and "cf->first_displayed" equals
3719        "cf->last_displayed", i.e. there's only one frame being
3720        displayed, that frame is the frame we want.
3721
3722        This means we have to set "cf->first_displayed" and
3723        "cf->last_displayed" before adding the row to the
3724        GtkCList; see the comment in "add_packet_to_packet_list()". */
3725
3726        if (row == 0 && cf->first_displayed == cf->last_displayed)
3727          fdata = frame_data_sequence_find(cf->frames, cf->first_displayed);
3728   }
3729
3730   /* If fdata _still_ isn't set simply give up. */
3731   if (fdata == NULL) {
3732     return;
3733   }
3734
3735   /* Get the data in that frame. */
3736   if (!cf_read_frame (cf, fdata)) {
3737     return;
3738   }
3739
3740   /* Record that this frame is the current frame. */
3741   cf->current_frame = fdata;
3742   cf->current_row = row;
3743
3744   old_edt = cf->edt;
3745   /* Create the logical protocol tree. */
3746   /* We don't need the columns here. */
3747   cf->edt = epan_dissect_new(TRUE, TRUE);
3748
3749   tap_build_interesting(cf->edt);
3750   epan_dissect_run(cf->edt, &cf->phdr, frame_tvbuff_new_buffer(cf->current_frame, &cf->buf),
3751                    cf->current_frame, NULL);
3752
3753   dfilter_macro_build_ftv_cache(cf->edt->tree);
3754
3755   cf_callback_invoke(cf_cb_packet_selected, cf);
3756
3757   if (old_edt != NULL)
3758     epan_dissect_free(old_edt);
3759
3760 }
3761
3762 /* Unselect the selected packet, if any. */
3763 void
3764 cf_unselect_packet(capture_file *cf)
3765 {
3766   epan_dissect_t *old_edt = cf->edt;
3767
3768   cf->edt = NULL;
3769
3770   /* No packet is selected. */
3771   cf->current_frame = NULL;
3772   cf->current_row = 0;
3773
3774   cf_callback_invoke(cf_cb_packet_unselected, cf);
3775
3776   /* No protocol tree means no selected field. */
3777   cf_unselect_field(cf);
3778
3779   /* Destroy the epan_dissect_t for the unselected packet. */
3780   if (old_edt != NULL)
3781     epan_dissect_free(old_edt);
3782 }
3783
3784 /* Unset the selected protocol tree field, if any. */
3785 void
3786 cf_unselect_field(capture_file *cf)
3787 {
3788   cf->finfo_selected = NULL;
3789
3790   cf_callback_invoke(cf_cb_field_unselected, cf);
3791 }
3792
3793 /*
3794  * Mark a particular frame.
3795  */
3796 void
3797 cf_mark_frame(capture_file *cf, frame_data *frame)
3798 {
3799   if (! frame->flags.marked) {
3800     frame->flags.marked = TRUE;
3801     if (cf->count > cf->marked_count)
3802       cf->marked_count++;
3803   }
3804 }
3805
3806 /*
3807  * Unmark a particular frame.
3808  */
3809 void
3810 cf_unmark_frame(capture_file *cf, frame_data *frame)
3811 {
3812   if (frame->flags.marked) {
3813     frame->flags.marked = FALSE;
3814     if (cf->marked_count > 0)
3815       cf->marked_count--;
3816   }
3817 }
3818
3819 /*
3820  * Ignore a particular frame.
3821  */
3822 void
3823 cf_ignore_frame(capture_file *cf, frame_data *frame)
3824 {
3825   if (! frame->flags.ignored) {
3826     frame->flags.ignored = TRUE;
3827     if (cf->count > cf->ignored_count)
3828       cf->ignored_count++;
3829   }
3830 }
3831
3832 /*
3833  * Un-ignore a particular frame.
3834  */
3835 void
3836 cf_unignore_frame(capture_file *cf, frame_data *frame)
3837 {
3838   if (frame->flags.ignored) {
3839     frame->flags.ignored = FALSE;
3840     if (cf->ignored_count > 0)
3841       cf->ignored_count--;
3842   }
3843 }
3844
3845 /*