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