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