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