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