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