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