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