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