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