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