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