When using the new packet list select the first packet when the file read is complete...
[metze/wireshark/wip.git] / file.c
1 /* file.c
2  * File I/O routines
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #ifdef HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32
33 #include <time.h>
34
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <ctype.h>
39 #include <errno.h>
40 #include <signal.h>
41
42 #ifdef HAVE_FCNTL_H
43 #include <fcntl.h>
44 #endif
45
46 #include <epan/epan.h>
47 #include <epan/filesystem.h>
48
49 #include "color.h"
50 #include "color_filters.h"
51 #include "cfile.h"
52 #include <epan/column.h>
53 #include <epan/packet.h>
54 #include <epan/column-utils.h>
55 #include "packet-range.h"
56 #include "print.h"
57 #include "file.h"
58 #include "fileset.h"
59 #include "tempfile.h"
60 #include "merge.h"
61 #include "alert_box.h"
62 #include "simple_dialog.h"
63 #include "progress_dlg.h"
64 #include "ui_util.h"
65 #include <epan/prefs.h>
66 #include <epan/dfilter/dfilter.h>
67 #include <epan/epan_dissect.h>
68 #include <epan/tap.h>
69 #include <epan/dissectors/packet-data.h>
70 #include <epan/dissectors/packet-ber.h>
71 #include <epan/timestamp.h>
72 #include <epan/dfilter/dfilter-macro.h>
73 #include <wsutil/file_util.h>
74 #include <epan/strutil.h>
75
76
77 #ifdef HAVE_LIBPCAP
78 gboolean auto_scroll_live;
79 #endif
80
81 static nstime_t first_ts;
82 static nstime_t prev_dis_ts;
83 static guint32 cum_bytes = 0;
84
85 static void cf_reset_state(capture_file *cf);
86
87 static int read_packet(capture_file *cf, dfilter_t *dfcode,
88     gboolean filtering_tap_listeners, guint tap_flags, gint64 offset);
89
90 static void rescan_packets(capture_file *cf, const char *action, const char *action_item,
91         gboolean refilter, gboolean redissect);
92
93 static gboolean match_protocol_tree(capture_file *cf, frame_data *fdata,
94         void *criterion);
95 static void match_subtree_text(proto_node *node, gpointer data);
96 static gboolean match_summary_line(capture_file *cf, frame_data *fdata,
97         void *criterion);
98 static gboolean match_ascii_and_unicode(capture_file *cf, frame_data *fdata,
99         void *criterion);
100 static gboolean match_ascii(capture_file *cf, frame_data *fdata,
101         void *criterion);
102 static gboolean match_unicode(capture_file *cf, frame_data *fdata,
103         void *criterion);
104 static gboolean match_binary(capture_file *cf, frame_data *fdata,
105         void *criterion);
106 static gboolean match_dfilter(capture_file *cf, frame_data *fdata,
107         void *criterion);
108 static gboolean find_packet(capture_file *cf,
109         gboolean (*match_function)(capture_file *, frame_data *, void *),
110         void *criterion);
111
112 static void cf_open_failure_alert_box(const char *filename, int err,
113                                       gchar *err_info, gboolean for_writing,
114                                       int file_type);
115 static const char *file_rename_error_message(int err);
116 static void cf_write_failure_alert_box(const char *filename, int err);
117 static void cf_close_failure_alert_box(const char *filename, int err);
118
119 /* Update the progress bar this many times when reading a file. */
120 #define N_PROGBAR_UPDATES       100
121
122 /* Number of "frame_data" structures per memory chunk.
123    XXX - is this the right number? */
124 #define FRAME_DATA_CHUNK_SIZE   1024
125
126
127 /* this callback mechanism should possibly be replaced by the g_signal_...() stuff (if I only would know how :-) */
128 typedef struct {
129     cf_callback_t cb_fct;
130     gpointer user_data;
131 } cf_callback_data_t;
132
133 static GList *cf_callbacks = NULL;
134
135 static void
136 cf_callback_invoke(int event, gpointer data)
137 {
138     cf_callback_data_t *cb;
139     GList *cb_item = cf_callbacks;
140
141     /* there should be at least one interested */
142     g_assert(cb_item != NULL);
143
144     while(cb_item != NULL) {
145         cb = cb_item->data;
146         cb->cb_fct(event, data, cb->user_data);
147         cb_item = g_list_next(cb_item);
148     }
149 }
150
151
152 void
153 cf_callback_add(cf_callback_t func, gpointer user_data)
154 {
155     cf_callback_data_t *cb;
156
157     cb = g_malloc(sizeof(cf_callback_data_t));
158     cb->cb_fct = func;
159     cb->user_data = user_data;
160
161     cf_callbacks = g_list_append(cf_callbacks, cb);
162 }
163
164 void
165 cf_callback_remove(cf_callback_t func)
166 {
167     cf_callback_data_t *cb;
168     GList *cb_item = cf_callbacks;
169
170     while(cb_item != NULL) {
171         cb = cb_item->data;
172         if(cb->cb_fct == func) {
173             cf_callbacks = g_list_remove(cf_callbacks, cb);
174             g_free(cb);
175             return;
176         }
177         cb_item = g_list_next(cb_item);
178     }
179
180     g_assert_not_reached();
181 }
182
183 void
184 cf_timestamp_auto_precision(capture_file *cf)
185 {
186         int prec = timestamp_get_precision();
187
188
189         /* don't try to get the file's precision if none is opened */
190         if(cf->state == FILE_CLOSED) {
191                 return;
192         }
193
194         /* if we are in auto mode, set precision of current file */
195         if(prec == TS_PREC_AUTO ||
196           prec == TS_PREC_AUTO_SEC ||
197           prec == TS_PREC_AUTO_DSEC ||
198           prec == TS_PREC_AUTO_CSEC ||
199           prec == TS_PREC_AUTO_MSEC ||
200           prec == TS_PREC_AUTO_USEC ||
201           prec == TS_PREC_AUTO_NSEC)
202         {
203                 switch(wtap_file_tsprecision(cf->wth)) {
204                 case(WTAP_FILE_TSPREC_SEC):
205                         timestamp_set_precision(TS_PREC_AUTO_SEC);
206                         break;
207                 case(WTAP_FILE_TSPREC_DSEC):
208                         timestamp_set_precision(TS_PREC_AUTO_DSEC);
209                         break;
210                 case(WTAP_FILE_TSPREC_CSEC):
211                         timestamp_set_precision(TS_PREC_AUTO_CSEC);
212                         break;
213                 case(WTAP_FILE_TSPREC_MSEC):
214                         timestamp_set_precision(TS_PREC_AUTO_MSEC);
215                         break;
216                 case(WTAP_FILE_TSPREC_USEC):
217                         timestamp_set_precision(TS_PREC_AUTO_USEC);
218                         break;
219                 case(WTAP_FILE_TSPREC_NSEC):
220                         timestamp_set_precision(TS_PREC_AUTO_NSEC);
221                         break;
222                 default:
223                         g_assert_not_reached();
224                 }
225         }
226 }
227
228
229 cf_status_t
230 cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
231 {
232   wtap       *wth;
233   gchar       *err_info;
234
235   wth = wtap_open_offline(fname, err, &err_info, TRUE);
236   if (wth == NULL)
237     goto fail;
238
239   /* The open succeeded.  Close whatever capture file we had open,
240      and fill in the information for this file. */
241   cf_reset_state(cf);
242
243   /* Initialize all data structures used for dissection. */
244   init_dissection();
245
246   /* We're about to start reading the file. */
247   cf->state = FILE_READ_IN_PROGRESS;
248
249   cf->wth = wth;
250   cf->f_datalen = 0;
251
252   /* Set the file name because we need it to set the follow stream filter.
253      XXX - is that still true?  We need it for other reasons, though,
254      in any case. */
255   cf->filename = g_strdup(fname);
256
257   /* Indicate whether it's a permanent or temporary file. */
258   cf->is_tempfile = is_tempfile;
259
260   /* If it's a temporary capture buffer file, mark it as not saved. */
261   cf->user_saved = !is_tempfile;
262
263   cf->cd_t        = wtap_file_type(cf->wth);
264   cf->count     = 0;
265   cf->displayed_count = 0;
266   cf->marked_count = 0;
267   cf->drops_known = FALSE;
268   cf->drops     = 0;
269   cf->snap      = wtap_snapshot_length(cf->wth);
270   if (cf->snap == 0) {
271     /* Snapshot length not known. */
272     cf->has_snap = FALSE;
273     cf->snap = WTAP_MAX_PACKET_SIZE;
274   } else
275     cf->has_snap = TRUE;
276   nstime_set_zero(&cf->elapsed_time);
277   nstime_set_unset(&first_ts);
278   nstime_set_unset(&prev_dis_ts);
279
280   cf->plist_chunk = g_mem_chunk_new("frame_data_chunk",
281         sizeof(frame_data),
282         FRAME_DATA_CHUNK_SIZE * sizeof(frame_data),
283         G_ALLOC_AND_FREE);
284   g_assert(cf->plist_chunk);
285
286   /* change the time formats now, as we might have a new precision */
287   cf_change_time_formats(cf);
288
289   fileset_file_opened(fname);
290
291   if(cf->cd_t == WTAP_FILE_BER) {
292     /* tell the BER dissector the file name */
293     ber_set_filename(cf->filename);
294   }
295
296   return CF_OK;
297
298 fail:
299   cf_open_failure_alert_box(fname, *err, err_info, FALSE, 0);
300   return CF_ERROR;
301 }
302
303
304 /*
305  * Reset the state for the currently closed file, but don't do the
306  * UI callbacks; this is for use in "cf_open()", where we don't
307  * want the UI to go from "file open" to "file closed" back to
308  * "file open", we want it to go from "old file open" to "new file
309  * open and being read".
310  */
311 static void
312 cf_reset_state(capture_file *cf)
313 {
314   /* Die if we're in the middle of reading a file. */
315   g_assert(cf->state != FILE_READ_IN_PROGRESS);
316
317   if (cf->wth) {
318     wtap_close(cf->wth);
319     cf->wth = NULL;
320   }
321   /* We have no file open... */
322   if (cf->filename != NULL) {
323     /* If it's a temporary file, remove it. */
324     if (cf->is_tempfile)
325       ws_unlink(cf->filename);
326     g_free(cf->filename);
327     cf->filename = NULL;
328   }
329   /* ...which means we have nothing to save. */
330   cf->user_saved = FALSE;
331
332   if (cf->plist_chunk != NULL) {
333     g_mem_chunk_destroy(cf->plist_chunk);
334     cf->plist_chunk = NULL;
335   }
336   if (cf->rfcode != NULL) {
337     dfilter_free(cf->rfcode);
338     cf->rfcode = NULL;
339   }
340   cf->plist = NULL;
341   cf->plist_end = NULL;
342   cf_unselect_packet(cf);       /* nothing to select */
343   cf->first_displayed = NULL;
344   cf->last_displayed = NULL;
345
346   /* No frame selected, no field in that frame selected. */
347   cf->current_frame = NULL;
348   cf->current_row = 0;
349   cf->finfo_selected = NULL;
350
351   /* Clear the packet list. */
352 #ifdef NEW_PACKET_LIST
353   new_packet_list_freeze();
354   new_packet_list_thaw();
355 #else
356   packet_list_freeze();
357   packet_list_clear();
358   packet_list_thaw();
359 #endif
360
361   cf->f_datalen = 0;
362   cf->count = 0;
363   nstime_set_zero(&cf->elapsed_time);
364
365   reset_tap_listeners();
366
367   /* We have no file open. */
368   cf->state = FILE_CLOSED;
369
370   fileset_file_closed();
371 }
372
373 /* Reset everything to a pristine state */
374 void
375 cf_close(capture_file *cf)
376 {
377   /* do GUI things even if file is already closed,
378    * e.g. to cleanup things if a capture couldn't be started */
379   cf_callback_invoke(cf_cb_file_closing, cf);
380
381   /* close things, if not already closed before */
382   if(cf->state != FILE_CLOSED) {
383     color_filters_cleanup();
384     cf_reset_state(cf);
385     cleanup_dissection();
386   }
387
388   cf_callback_invoke(cf_cb_file_closed, cf);
389 }
390
391 /* an out of memory exception occured, wait for a user button press to exit */
392 void outofmemory_cb(gpointer dialog _U_, gint btn _U_, gpointer data _U_)
393 {
394     main_window_exit();
395 }
396
397 cf_read_status_t
398 cf_read(capture_file *cf)
399 {
400   int         err;
401   gchar       *err_info;
402   const gchar *name_ptr;
403   const char  *errmsg;
404   char         errmsg_errno[1024+1];
405   gint64       data_offset;
406   progdlg_t *volatile progbar = NULL;
407   gboolean     stop_flag;
408   volatile gint64 size;
409   gint64       file_pos;
410   volatile float progbar_val;
411   GTimeVal     start_time;
412   gchar        status_str[100];
413   volatile gint64 progbar_nextstep;
414   volatile gint64 progbar_quantum;
415   dfilter_t   *dfcode;
416   gboolean    filtering_tap_listeners;
417   guint       tap_flags;
418 #ifdef HAVE_LIBPCAP
419   volatile int displayed_once = 0;
420 #endif
421
422   /* Compile the current display filter.
423    * We assume this will not fail since cf->dfilter is only set in
424    * cf_filter IFF the filter was valid.
425    */
426   dfcode=NULL;
427   if(cf->dfilter){
428     dfilter_compile(cf->dfilter, &dfcode);
429   }
430
431   /* Do we have any tap listeners with filters? */
432   filtering_tap_listeners = have_filtering_tap_listeners();
433
434   /* Get the union of the flags for all tap listeners. */
435   tap_flags = union_of_tap_listener_flags();
436
437   cum_bytes=0;
438
439   reset_tap_listeners();
440
441   cf_callback_invoke(cf_cb_file_read_start, cf);
442
443   name_ptr = get_basename(cf->filename);
444
445   /* Find the size of the file. */
446   size = wtap_file_size(cf->wth, NULL);
447
448   /* Update the progress bar when it gets to this value. */
449   progbar_nextstep = 0;
450   /* When we reach the value that triggers a progress bar update,
451      bump that value by this amount. */
452   if (size >= 0)
453     progbar_quantum = size/N_PROGBAR_UPDATES;
454   else
455     progbar_quantum = 0;
456   /* Progress so far. */
457   progbar_val = 0.0f;
458
459 #ifdef NEW_PACKET_LIST
460   new_packet_list_freeze();
461 #else
462   packet_list_freeze();
463 #endif
464
465   stop_flag = FALSE;
466   g_get_current_time(&start_time);
467
468   while ((wtap_read(cf->wth, &err, &err_info, &data_offset))) {
469     if (size >= 0) {
470       /* Create the progress bar if necessary.
471          We check on every iteration of the loop, so that it takes no
472          longer than the standard time to create it (otherwise, for a
473          large file, we might take considerably longer than that standard
474          time in order to get to the next progress bar step). */
475       if (progbar == NULL) {
476         progbar = delayed_create_progress_dlg("Loading", name_ptr,
477           TRUE, &stop_flag, &start_time, progbar_val);
478       }
479
480       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
481          when we update it, we have to run the GTK+ main loop to get it
482          to repaint what's pending, and doing so may involve an "ioctl()"
483          to see if there's any pending input from an X server, and doing
484          that for every packet can be costly, especially on a big file. */
485       if (data_offset >= progbar_nextstep) {
486           file_pos = wtap_read_so_far(cf->wth, NULL);
487           progbar_val = (gfloat) file_pos / (gfloat) size;
488           if (progbar_val > 1.0) {
489             /* The file probably grew while we were reading it.
490                Update file size, and try again. */
491             size = wtap_file_size(cf->wth, NULL);
492             if (size >= 0)
493               progbar_val = (gfloat) file_pos / (gfloat) size;
494             /* If it's still > 1, either "wtap_file_size()" failed (in which
495                case there's not much we can do about it), or the file
496                *shrank* (in which case there's not much we can do about
497                it); just clip the progress value at 1.0. */
498             if (progbar_val > 1.0f)
499               progbar_val = 1.0f;
500           }
501           if (progbar != NULL) {
502               /* update the packet lists content on the first run or frequently on very large files */
503               /* (on smaller files the display update takes longer than reading the file) */
504 #ifdef HAVE_LIBPCAP
505               if (progbar_quantum > 500000 || displayed_once == 0) {
506                   if ((auto_scroll_live || displayed_once == 0 || cf->displayed_count < 1000) && cf->plist_end != NULL) {
507                       displayed_once = 1;
508 #ifdef NEW_PACKET_LIST
509                       /* XXX - Add move to end function call.  Freeze/thaw if
510                       * necessary. */
511 #else
512                       packet_list_thaw();
513                       if (auto_scroll_live)
514                           packet_list_moveto_end();
515                       packet_list_freeze();
516 #endif /* NEW_PACKET_LIST */
517                   }
518               }
519 #endif /* HAVE_LIBPCAP */
520             g_snprintf(status_str, sizeof(status_str),
521                        "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
522                        file_pos / 1024, size / 1024);
523             update_progress_dlg(progbar, progbar_val, status_str);
524           }
525          progbar_nextstep += progbar_quantum;
526       }
527     }
528
529     if (stop_flag) {
530       /* Well, the user decided to abort the read. He/She will be warned and
531          it might be enough for him/her to work with the already loaded
532          packets.
533          This is especially true for very large capture files, where you don't
534          want to wait loading the whole file (which may last minutes or even
535          hours even on fast machines) just to see that it was the wrong file. */
536       break;
537     }
538     TRY {
539         read_packet(cf, dfcode, filtering_tap_listeners, tap_flags, data_offset);
540     }
541     CATCH(OutOfMemoryError) {
542         gpointer dialog;
543
544         dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
545               "%sOut Of Memory!%s\n"
546               "\n"
547               "Sorry, but Wireshark has to terminate now!\n"
548               "\n"
549               "Some infos / workarounds can be found at:\n"
550               "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
551               simple_dialog_primary_start(), simple_dialog_primary_end());
552         /* we have to terminate, as we cannot recover from the memory error */
553         simple_dialog_set_cb(dialog, outofmemory_cb, NULL);
554         while(1) {
555             main_window_update();
556             /* XXX - how to avoid a busy wait? */
557             /* Sleep(100); */
558         };
559         break;
560     }
561     ENDTRY;
562   }
563
564   /* Cleanup and release all dfilter resources */
565   if (dfcode != NULL){
566     dfilter_free(dfcode);
567   }
568
569   /* We're done reading the file; destroy the progress bar if it was created. */
570   if (progbar != NULL)
571     destroy_progress_dlg(progbar);
572
573   /* We're done reading sequentially through the file. */
574   cf->state = FILE_READ_DONE;
575
576   /* Close the sequential I/O side, to free up memory it requires. */
577   wtap_sequential_close(cf->wth);
578
579   /* Allow the protocol dissectors to free up memory that they
580    * don't need after the sequential run-through of the packets. */
581   postseq_cleanup_all_protocols();
582
583   /* Set the file encapsulation type now; we don't know what it is until
584      we've looked at all the packets, as we don't know until then whether
585      there's more than one type (and thus whether it's
586      WTAP_ENCAP_PER_PACKET). */
587   cf->lnk_t = wtap_file_encap(cf->wth);
588
589   cf->current_frame = cf->first_displayed;
590   cf->current_row = 0;
591
592 #ifdef NEW_PACKET_LIST
593   new_packet_list_thaw();
594 #else
595   packet_list_thaw();
596 #endif
597
598   cf_callback_invoke(cf_cb_file_read_finished, cf);
599
600   /* If we have any displayed packets to select, select the first of those
601      packets by making the first row the selected row. */
602   if (cf->first_displayed != NULL){
603 #ifdef NEW_PACKET_LIST
604     new_packet_list_select_first_row();
605 #else
606     packet_list_select_row(0);
607 #endif /* NEW_PACKET_LIST */
608   }
609
610   if(stop_flag) {
611     simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
612           "%sFile loading was cancelled!%s\n"
613           "\n"
614                   "The remaining packets in the file were discarded.\n"
615           "\n"
616           "As a lot of packets from the original file will be missing,\n"
617                   "remember to be careful when saving the current content to a file.\n",
618           simple_dialog_primary_start(), simple_dialog_primary_end());
619     return CF_READ_ERROR;
620   }
621
622   if (err != 0) {
623     /* Put up a message box noting that the read failed somewhere along
624        the line.  Don't throw out the stuff we managed to read, though,
625        if any. */
626     switch (err) {
627
628     case WTAP_ERR_UNSUPPORTED_ENCAP:
629       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
630                "The capture file has a packet with a network type that Wireshark doesn't support.\n(%s)",
631                err_info);
632       g_free(err_info);
633       errmsg = errmsg_errno;
634       break;
635
636     case WTAP_ERR_CANT_READ:
637       errmsg = "An attempt to read from the capture file failed for"
638                " some unknown reason.";
639       break;
640
641     case WTAP_ERR_SHORT_READ:
642       errmsg = "The capture file appears to have been cut short"
643                " in the middle of a packet.";
644       break;
645
646     case WTAP_ERR_BAD_RECORD:
647       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
648                "The capture file appears to be damaged or corrupt.\n(%s)",
649                err_info);
650       g_free(err_info);
651       errmsg = errmsg_errno;
652       break;
653
654     default:
655       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
656                "An error occurred while reading the"
657                " capture file: %s.", wtap_strerror(err));
658       errmsg = errmsg_errno;
659       break;
660     }
661     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", errmsg);
662     return CF_READ_ERROR;
663   } else
664     return CF_READ_OK;
665 }
666
667 #ifdef HAVE_LIBPCAP
668 cf_status_t
669 cf_start_tail(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
670 {
671   cf_status_t cf_status;
672
673   cf_status = cf_open(cf, fname, is_tempfile, err);
674   return cf_status;
675 }
676
677 cf_read_status_t
678 cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
679 {
680   gint64 data_offset = 0;
681   gchar *err_info;
682   volatile int newly_displayed_packets = 0;
683   dfilter_t   *dfcode;
684   gboolean filtering_tap_listeners;
685   guint tap_flags;
686
687   /* Compile the current display filter.
688    * We assume this will not fail since cf->dfilter is only set in
689    * cf_filter IFF the filter was valid.
690    */
691   dfcode=NULL;
692   if(cf->dfilter){
693     dfilter_compile(cf->dfilter, &dfcode);
694   }
695
696   /* Do we have any tap listeners with filters? */
697   filtering_tap_listeners = have_filtering_tap_listeners();
698
699   /* Get the union of the flags for all tap listeners. */
700   tap_flags = union_of_tap_listener_flags();
701
702   *err = 0;
703
704 #ifdef NEW_PACKET_LIST
705   new_packet_list_freeze();
706 #else
707   packet_list_check_end();
708   packet_list_freeze();
709 #endif
710
711   /*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: %u new: %u", cf->count, to_read);*/
712
713   while (to_read != 0 && (wtap_read(cf->wth, err, &err_info, &data_offset))) {
714     if (cf->state == FILE_READ_ABORTED) {
715       /* Well, the user decided to exit Wireshark.  Break out of the
716          loop, and let the code below (which is called even if there
717          aren't any packets left to read) exit. */
718       break;
719     }
720     TRY{
721         if (read_packet(cf, dfcode, filtering_tap_listeners, tap_flags,
722                         data_offset) != -1) {
723             newly_displayed_packets++;
724         }
725     }
726     CATCH(OutOfMemoryError) {
727         gpointer dialog;
728
729         dialog = simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
730               "%sOut Of Memory!%s\n"
731               "\n"
732               "Sorry, but Wireshark has to terminate now!\n"
733               "\n"
734               "The capture file is not lost, it can be found at:\n"
735               "%s\n"
736               "\n"
737               "Some infos / workarounds can be found at:\n"
738               "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
739               simple_dialog_primary_start(), simple_dialog_primary_end(), cf->filename);
740         /* we have to terminate, as we cannot recover from the memory error */
741         simple_dialog_set_cb(dialog, outofmemory_cb, NULL);
742         while(1) {
743             main_window_update();
744             /* XXX - how to avoid a busy wait? */
745             /* Sleep(100); */
746         };
747 #ifdef NEW_PACKET_LIST
748         new_packet_list_thaw();
749 #else
750         packet_list_thaw();
751 #endif
752         return CF_READ_ABORTED;
753     }
754     ENDTRY;
755     to_read--;
756   }
757
758   /* Cleanup and release all dfilter resources */
759   if (dfcode != NULL){
760     dfilter_free(dfcode);
761   }
762
763   /*g_log(NULL, G_LOG_LEVEL_MESSAGE, "cf_continue_tail: count %u state: %u err: %u",
764           cf->count, cf->state, *err);*/
765
766 #ifdef NEW_PACKET_LIST
767   new_packet_list_thaw();
768 #else
769   /* XXX - this causes "flickering" of the list */
770   packet_list_thaw();
771 #endif
772
773 #ifndef NEW_PACKET_LIST
774   /* moving to the end of the packet list - if the user requested so and
775      we have some new packets.
776      this doesn't seem to work well with a frozen GTK_Clist, so do this after
777      packet_list_thaw() is done, see bugzilla 1188 */
778   /* XXX - this cheats and looks inside the packet list to find the final
779      row number. */
780   if (newly_displayed_packets && auto_scroll_live && cf->plist_end != NULL)
781     packet_list_moveto_end();
782 #endif /* NEW_PACKET_LIST */
783
784   if (cf->state == FILE_READ_ABORTED) {
785     /* Well, the user decided to exit Wireshark.  Return CF_READ_ABORTED
786        so that our caller can kill off the capture child process;
787        this will cause an EOF on the pipe from the child, so
788        "cf_finish_tail()" will be called, and it will clean up
789        and exit. */
790     return CF_READ_ABORTED;
791   } else if (*err != 0) {
792     /* We got an error reading the capture file.
793        XXX - pop up a dialog box instead? */
794         g_warning("Error \"%s\" while reading: \"%s\"\n",
795                 wtap_strerror(*err), cf->filename);
796
797     return CF_READ_ERROR;
798   } else
799     return CF_READ_OK;
800 }
801
802 cf_read_status_t
803 cf_finish_tail(capture_file *cf, int *err)
804 {
805   gchar *err_info;
806   gint64 data_offset;
807   dfilter_t   *dfcode;
808   gboolean filtering_tap_listeners;
809   guint tap_flags;
810
811   /* Compile the current display filter.
812    * We assume this will not fail since cf->dfilter is only set in
813    * cf_filter IFF the filter was valid.
814    */
815   dfcode=NULL;
816   if(cf->dfilter){
817     dfilter_compile(cf->dfilter, &dfcode);
818   }
819
820   /* Do we have any tap listeners with filters? */
821   filtering_tap_listeners = have_filtering_tap_listeners();
822
823   /* Get the union of the flags for all tap listeners. */
824   tap_flags = union_of_tap_listener_flags();
825
826   if(cf->wth == NULL) {
827     cf_close(cf);
828     return CF_READ_ERROR;
829   }
830
831 #ifdef NEW_PACKET_LIST
832   new_packet_list_freeze();
833 #else
834   packet_list_check_end();
835   packet_list_freeze();
836 #endif
837
838   while ((wtap_read(cf->wth, err, &err_info, &data_offset))) {
839     if (cf->state == FILE_READ_ABORTED) {
840       /* Well, the user decided to abort the read.  Break out of the
841          loop, and let the code below (which is called even if there
842          aren't any packets left to read) exit. */
843       break;
844     }
845     read_packet(cf, dfcode, filtering_tap_listeners, tap_flags, data_offset);
846   }
847
848   /* Cleanup and release all dfilter resources */
849   if (dfcode != NULL){
850     dfilter_free(dfcode);
851   }
852
853 #ifdef NEW_PACKET_LIST
854   new_packet_list_thaw();
855 #else
856   packet_list_thaw();
857 #endif
858
859   if (cf->state == FILE_READ_ABORTED) {
860     /* Well, the user decided to abort the read.  We're only called
861        when the child capture process closes the pipe to us (meaning
862        it's probably exited), so we can just close the capture
863        file; we return CF_READ_ABORTED so our caller can do whatever
864        is appropriate when that happens. */
865     cf_close(cf);
866     return CF_READ_ABORTED;
867   }
868
869 #ifndef NEW_PACKET_LIST
870   if (auto_scroll_live && cf->plist_end != NULL)
871     /* XXX - this cheats and looks inside the packet list to find the final
872        row number. */
873     packet_list_moveto_end();
874 #endif
875
876   /* We're done reading sequentially through the file. */
877   cf->state = FILE_READ_DONE;
878
879   /* We're done reading sequentially through the file; close the
880      sequential I/O side, to free up memory it requires. */
881   wtap_sequential_close(cf->wth);
882
883   /* Allow the protocol dissectors to free up memory that they
884    * don't need after the sequential run-through of the packets. */
885   postseq_cleanup_all_protocols();
886
887   /* Set the file encapsulation type now; we don't know what it is until
888      we've looked at all the packets, as we don't know until then whether
889      there's more than one type (and thus whether it's
890      WTAP_ENCAP_PER_PACKET). */
891   cf->lnk_t = wtap_file_encap(cf->wth);
892
893   if (*err != 0) {
894     /* We got an error reading the capture file.
895        XXX - pop up a dialog box? */
896     return CF_READ_ERROR;
897   } else {
898     return CF_READ_OK;
899   }
900 }
901 #endif /* HAVE_LIBPCAP */
902
903 const gchar *
904 cf_get_display_name(capture_file *cf)
905 {
906   const gchar *displayname;
907
908   /* Return a name to use in displays */
909   if (!cf->is_tempfile) {
910     /* Get the last component of the file name, and use that. */
911     if (cf->filename){
912       displayname = get_basename(cf->filename);
913     } else {
914       displayname="(No file)";
915     }
916   } else {
917     /* The file we read is a temporary file from a live capture;
918        we don't mention its name. */
919     displayname = "(Untitled)";
920   }
921   return displayname;
922 }
923
924 /* XXX - use a macro instead? */
925 int
926 cf_get_packet_count(capture_file *cf)
927 {
928     return cf->count;
929 }
930
931 /* XXX - use a macro instead? */
932 void
933 cf_set_packet_count(capture_file *cf, int packet_count)
934 {
935     cf->count = packet_count;
936 }
937
938 /* XXX - use a macro instead? */
939 gboolean
940 cf_is_tempfile(capture_file *cf)
941 {
942     return cf->is_tempfile;
943 }
944
945 void cf_set_tempfile(capture_file *cf, gboolean is_tempfile)
946 {
947     cf->is_tempfile = is_tempfile;
948 }
949
950
951 /* XXX - use a macro instead? */
952 void cf_set_drops_known(capture_file *cf, gboolean drops_known)
953 {
954     cf->drops_known = drops_known;
955 }
956
957 /* XXX - use a macro instead? */
958 void cf_set_drops(capture_file *cf, guint32 drops)
959 {
960     cf->drops = drops;
961 }
962
963 /* XXX - use a macro instead? */
964 gboolean cf_get_drops_known(capture_file *cf)
965 {
966     return cf->drops_known;
967 }
968
969 /* XXX - use a macro instead? */
970 guint32 cf_get_drops(capture_file *cf)
971 {
972     return cf->drops;
973 }
974
975 void cf_set_rfcode(capture_file *cf, dfilter_t *rfcode)
976 {
977     cf->rfcode = rfcode;
978 }
979
980 static int
981 add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
982         dfilter_t *dfcode, gboolean filtering_tap_listeners,
983         guint tap_flags,
984         union wtap_pseudo_header *pseudo_header, const guchar *buf,
985         gboolean refilter)
986 {
987   gint          row;
988   gboolean      create_proto_tree = FALSE;
989   epan_dissect_t *edt;
990
991   /* just add some value here until we know if it is being displayed or not */
992   fdata->cum_bytes  = cum_bytes + fdata->pkt_len;
993
994   /* If we don't have the time stamp of the first packet in the
995      capture, it's because this is the first packet.  Save the time
996      stamp of this packet as the time stamp of the first packet. */
997   if (nstime_is_unset(&first_ts)) {
998     first_ts  = fdata->abs_ts;
999   }
1000   /* if this frames is marked as a reference time frame, reset
1001      firstsec and firstusec to this frame */
1002   if(fdata->flags.ref_time){
1003     first_ts = fdata->abs_ts;
1004   }
1005
1006   /* If we don't have the time stamp of the previous displayed packet,
1007      it's because this is the first displayed packet.  Save the time
1008      stamp of this packet as the time stamp of the previous displayed
1009      packet. */
1010   if (nstime_is_unset(&prev_dis_ts)) {
1011     prev_dis_ts = fdata->abs_ts;
1012   }
1013
1014   /* Get the time elapsed between the first packet and this packet. */
1015   nstime_delta(&fdata->rel_ts, &fdata->abs_ts, &first_ts);
1016
1017   /* If it's greater than the current elapsed time, set the elapsed time
1018      to it (we check for "greater than" so as not to be confused by
1019      time moving backwards). */
1020   if ((gint32)cf->elapsed_time.secs < fdata->rel_ts.secs
1021   || ((gint32)cf->elapsed_time.secs == fdata->rel_ts.secs && (gint32)cf->elapsed_time.nsecs < fdata->rel_ts.nsecs)) {
1022     cf->elapsed_time = fdata->rel_ts;
1023   }
1024
1025   /* Get the time elapsed between the previous displayed packet and
1026      this packet. */
1027   nstime_delta(&fdata->del_dis_ts, &fdata->abs_ts, &prev_dis_ts);
1028
1029   /* If either
1030
1031         we have a display filter and are re-applying it;
1032
1033         we have a list of color filters;
1034
1035         we have tap listeners with filters;
1036
1037     we have tap listeners that require a protocol tree;
1038
1039         we have custom columns;
1040
1041      allocate a protocol tree root node, so that we'll construct
1042      a protocol tree against which a filter expression can be
1043      evaluated. */
1044   if ((dfcode != NULL && refilter) || color_filters_used() ||
1045       filtering_tap_listeners || (tap_flags & TL_REQUIRES_PROTO_TREE) ||
1046       have_custom_cols(&cf->cinfo))
1047           create_proto_tree = TRUE;
1048
1049   /* Dissect the frame. */
1050   edt = epan_dissect_new(create_proto_tree, FALSE);
1051
1052   if (dfcode != NULL && refilter) {
1053       epan_dissect_prime_dfilter(edt, dfcode);
1054   }
1055   /* prepare color filters */
1056   if (color_filters_used()) {
1057       color_filters_prime_edt(edt);
1058   }
1059
1060   col_custom_prime_edt(edt, &cf->cinfo);
1061
1062   tap_queue_init(edt);
1063   epan_dissect_run(edt, pseudo_header, buf, fdata, &cf->cinfo);
1064   tap_push_tapped_queue(edt);
1065
1066   /* If we have a display filter, apply it if we're refiltering, otherwise
1067      leave the "passed_dfilter" flag alone.
1068
1069      If we don't have a display filter, set "passed_dfilter" to 1. */
1070   if (dfcode != NULL) {
1071     if (refilter) {
1072       fdata->flags.passed_dfilter = dfilter_apply_edt(dfcode, edt) ? 1 : 0;
1073     }
1074   } else
1075     fdata->flags.passed_dfilter = 1;
1076
1077   if( (fdata->flags.passed_dfilter) || (edt->pi.fd->flags.ref_time) ){
1078     /* This frame either passed the display filter list or is marked as
1079        a time reference frame.  All time reference frames are displayed
1080        even if they dont pass the display filter */
1081     if(edt->pi.fd->flags.ref_time){
1082       /* if this was a TIME REF frame we should reset the cul bytes field */
1083       cum_bytes = fdata->pkt_len;
1084       fdata->cum_bytes =  cum_bytes;
1085     } else {
1086       /* increase cum_bytes with this packets length */
1087       cum_bytes += fdata->pkt_len;
1088     }
1089
1090     epan_dissect_fill_in_columns(edt);
1091
1092     /* If we haven't yet seen the first frame, this is it.
1093
1094        XXX - we must do this before we add the row to the display,
1095        as, if the display's GtkCList's selection mode is
1096        GTK_SELECTION_BROWSE, when the first entry is added to it,
1097        "cf_select_packet()" will be called, and it will fetch the row
1098        data for the 0th row, and will get a null pointer rather than
1099        "fdata", as "gtk_clist_append()" won't yet have returned and
1100        thus "gtk_clist_set_row_data()" won't yet have been called.
1101
1102        We thus need to leave behind bread crumbs so that
1103        "cf_select_packet()" can find this frame.  See the comment
1104        in "cf_select_packet()". */
1105     if (cf->first_displayed == NULL)
1106       cf->first_displayed = fdata;
1107
1108     /* This is the last frame we've seen so far. */
1109     cf->last_displayed = fdata;
1110
1111 #ifdef NEW_PACKET_LIST
1112     /* This function returns the color_t that was applied to the packet (in
1113      * the old packet list).  Applying the color to the packet is only done
1114      * in the following function when not using the new packet list. */
1115     fdata->color_filter = color_filters_colorize_packet(0, edt); 
1116
1117     row = new_packet_list_append(&cf->cinfo, fdata);
1118 #else
1119     row = packet_list_append(cf->cinfo.col_data, fdata);
1120
1121     /* colorize packet: first apply color filters
1122      * then if packet is marked, use preferences to overwrite color
1123      * we do both to make sure that when a packet gets un-marked, the
1124      * color will be correctly set (fixes bug 2038)
1125      */
1126      fdata->color_filter = color_filters_colorize_packet(row, edt);
1127      if (fdata->flags.marked) {
1128        packet_list_set_colors(row, &prefs.gui_marked_fg, &prefs.gui_marked_bg);
1129      }
1130 #endif /* NEW_PACKET_LIST */
1131
1132     /* Set the time of the previous displayed frame to the time of this
1133        frame. */
1134     prev_dis_ts = fdata->abs_ts;
1135
1136     cf->displayed_count++;
1137   } else {
1138     /* This frame didn't pass the display filter, so it's not being added
1139        to the clist, and thus has no row. */
1140     row = -1;
1141   }
1142   epan_dissect_free(edt);
1143   return row;
1144 }
1145
1146 /* read in a new packet */
1147 /* returns the row of the new packet in the packet list or -1 if not displayed */
1148 static int
1149 read_packet(capture_file *cf, dfilter_t *dfcode,
1150             gboolean filtering_tap_listeners, guint tap_flags, gint64 offset)
1151 {
1152   const struct wtap_pkthdr *phdr = wtap_phdr(cf->wth);
1153   union wtap_pseudo_header *pseudo_header = wtap_pseudoheader(cf->wth);
1154   const guchar *buf = wtap_buf_ptr(cf->wth);
1155   frame_data   *fdata;
1156   int           passed;
1157   frame_data   *plist_end;
1158   epan_dissect_t *edt;
1159   int row = -1;
1160
1161   /* Allocate the next list entry, and add it to the list. */
1162   fdata = g_mem_chunk_alloc(cf->plist_chunk);
1163
1164   fdata->num = 0;
1165   fdata->next = NULL;
1166   fdata->prev = NULL;
1167   fdata->pfd  = NULL;
1168   fdata->pkt_len  = phdr->len;
1169   fdata->cap_len  = phdr->caplen;
1170   fdata->file_off = offset;
1171   fdata->lnk_t = phdr->pkt_encap;
1172   fdata->flags.encoding = CHAR_ASCII;
1173   fdata->flags.visited = 0;
1174   fdata->flags.marked = 0;
1175   fdata->flags.ref_time = 0;
1176   fdata->color_filter = NULL;
1177
1178   fdata->abs_ts.secs = phdr->ts.secs;
1179   fdata->abs_ts.nsecs = phdr->ts.nsecs;
1180
1181   if (cf->plist_end != NULL)
1182     nstime_delta(&fdata->del_cap_ts, &fdata->abs_ts, &cf->plist_end->abs_ts);
1183   else
1184     nstime_set_zero(&fdata->del_cap_ts);
1185
1186   passed = TRUE;
1187   if (cf->rfcode) {
1188     edt = epan_dissect_new(TRUE, FALSE);
1189     epan_dissect_prime_dfilter(edt, cf->rfcode);
1190     epan_dissect_run(edt, pseudo_header, buf, fdata, NULL);
1191     passed = dfilter_apply_edt(cf->rfcode, edt);
1192     epan_dissect_free(edt);
1193   }
1194   if (passed) {
1195     plist_end = cf->plist_end;
1196     fdata->prev = plist_end;
1197     if (plist_end != NULL)
1198       plist_end->next = fdata;
1199     else
1200       cf->plist = fdata;
1201     cf->plist_end = fdata;
1202
1203     cf->count++;
1204     cf->f_datalen = offset + phdr->caplen;
1205     fdata->num = cf->count;
1206     if (!cf->redissecting) {
1207       row = add_packet_to_packet_list(fdata, cf, dfcode,
1208                                       filtering_tap_listeners, tap_flags,
1209                                       pseudo_header, buf, TRUE);
1210     }
1211   } else {
1212     /* XXX - if we didn't have read filters, or if we could avoid
1213        allocating the "frame_data" structure until we knew whether
1214        the frame passed the read filter, we could use a G_ALLOC_ONLY
1215        memory chunk...
1216
1217        ...but, at least in one test I did, where I just made the chunk
1218        a G_ALLOC_ONLY chunk and read in a huge capture file, it didn't
1219        seem to save a noticeable amount of time or space. */
1220     g_mem_chunk_free(cf->plist_chunk, fdata);
1221   }
1222
1223   return row;
1224 }
1225
1226 cf_status_t
1227 cf_merge_files(char **out_filenamep, int in_file_count,
1228                char *const *in_filenames, int file_type, gboolean do_append)
1229 {
1230   merge_in_file_t  *in_files;
1231   wtap             *wth;
1232   char             *out_filename;
1233   char             *tmpname;
1234   int               out_fd;
1235   wtap_dumper      *pdh;
1236   int               open_err, read_err, write_err, close_err;
1237   gchar            *err_info;
1238   int               err_fileno;
1239   int               i;
1240   char              errmsg_errno[1024+1];
1241   const char       *errmsg;
1242   gboolean          got_read_error = FALSE, got_write_error = FALSE;
1243   gint64            data_offset;
1244   progdlg_t        *progbar = NULL;
1245   gboolean          stop_flag;
1246   gint64            f_len, file_pos;
1247   float             progbar_val;
1248   GTimeVal          start_time;
1249   gchar             status_str[100];
1250   gint64            progbar_nextstep;
1251   gint64            progbar_quantum;
1252
1253   /* open the input files */
1254   if (!merge_open_in_files(in_file_count, in_filenames, &in_files,
1255                            &open_err, &err_info, &err_fileno)) {
1256     g_free(in_files);
1257     cf_open_failure_alert_box(in_filenames[err_fileno], open_err, err_info,
1258                               FALSE, 0);
1259     return CF_ERROR;
1260   }
1261
1262   if (*out_filenamep != NULL) {
1263     out_filename = *out_filenamep;
1264     out_fd = ws_open(out_filename, O_CREAT|O_TRUNC|O_BINARY, 0600);
1265     if (out_fd == -1)
1266       open_err = errno;
1267   } else {
1268     out_fd = create_tempfile(&tmpname, "wireshark");
1269     if (out_fd == -1)
1270       open_err = errno;
1271     out_filename = g_strdup(tmpname);
1272     *out_filenamep = out_filename;
1273   }
1274   if (out_fd == -1) {
1275     err_info = NULL;
1276     merge_close_in_files(in_file_count, in_files);
1277     g_free(in_files);
1278     cf_open_failure_alert_box(out_filename, open_err, NULL, TRUE, file_type);
1279     return CF_ERROR;
1280   }
1281
1282   pdh = wtap_dump_fdopen(out_fd, file_type,
1283       merge_select_frame_type(in_file_count, in_files),
1284       merge_max_snapshot_length(in_file_count, in_files),
1285           FALSE /* compressed */, &open_err);
1286   if (pdh == NULL) {
1287     ws_close(out_fd);
1288     merge_close_in_files(in_file_count, in_files);
1289     g_free(in_files);
1290     cf_open_failure_alert_box(out_filename, open_err, err_info, TRUE,
1291                               file_type);
1292     return CF_ERROR;
1293   }
1294
1295   /* Get the sum of the sizes of all the files. */
1296   f_len = 0;
1297   for (i = 0; i < in_file_count; i++)
1298     f_len += in_files[i].size;
1299
1300   /* Update the progress bar when it gets to this value. */
1301   progbar_nextstep = 0;
1302   /* When we reach the value that triggers a progress bar update,
1303      bump that value by this amount. */
1304   progbar_quantum = f_len/N_PROGBAR_UPDATES;
1305   /* Progress so far. */
1306   progbar_val = 0.0f;
1307
1308   stop_flag = FALSE;
1309   g_get_current_time(&start_time);
1310
1311   /* do the merge (or append) */
1312   for (;;) {
1313     if (do_append)
1314       wth = merge_append_read_packet(in_file_count, in_files, &read_err,
1315                                      &err_info);
1316     else
1317       wth = merge_read_packet(in_file_count, in_files, &read_err,
1318                               &err_info);
1319     if (wth == NULL) {
1320       if (read_err != 0)
1321         got_read_error = TRUE;
1322       break;
1323     }
1324
1325     /* Get the sum of the data offsets in all of the files. */
1326     data_offset = 0;
1327     for (i = 0; i < in_file_count; i++)
1328       data_offset += in_files[i].data_offset;
1329
1330     /* Create the progress bar if necessary.
1331        We check on every iteration of the loop, so that it takes no
1332        longer than the standard time to create it (otherwise, for a
1333        large file, we might take considerably longer than that standard
1334        time in order to get to the next progress bar step). */
1335     if (progbar == NULL) {
1336       progbar = delayed_create_progress_dlg("Merging", "files",
1337         FALSE, &stop_flag, &start_time, progbar_val);
1338     }
1339
1340     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1341        when we update it, we have to run the GTK+ main loop to get it
1342        to repaint what's pending, and doing so may involve an "ioctl()"
1343        to see if there's any pending input from an X server, and doing
1344        that for every packet can be costly, especially on a big file. */
1345     if (data_offset >= progbar_nextstep) {
1346         /* Get the sum of the seek positions in all of the files. */
1347         file_pos = 0;
1348         for (i = 0; i < in_file_count; i++)
1349           file_pos += wtap_read_so_far(in_files[i].wth, NULL);
1350         progbar_val = (gfloat) file_pos / (gfloat) f_len;
1351         if (progbar_val > 1.0f) {
1352           /* Some file probably grew while we were reading it.
1353              That "shouldn't happen", so we'll just clip the progress
1354              value at 1.0. */
1355           progbar_val = 1.0f;
1356         }
1357         if (progbar != NULL) {
1358           g_snprintf(status_str, sizeof(status_str),
1359                      "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
1360                      file_pos / 1024, f_len / 1024);
1361           update_progress_dlg(progbar, progbar_val, status_str);
1362         }
1363         progbar_nextstep += progbar_quantum;
1364     }
1365
1366     if (stop_flag) {
1367       /* Well, the user decided to abort the merge. */
1368       break;
1369     }
1370
1371     if (!wtap_dump(pdh, wtap_phdr(wth), wtap_pseudoheader(wth),
1372          wtap_buf_ptr(wth), &write_err)) {
1373       got_write_error = TRUE;
1374       break;
1375     }
1376   }
1377
1378   /* We're done merging the files; destroy the progress bar if it was created. */
1379   if (progbar != NULL)
1380     destroy_progress_dlg(progbar);
1381
1382   merge_close_in_files(in_file_count, in_files);
1383   if (!got_read_error && !got_write_error) {
1384     if (!wtap_dump_close(pdh, &write_err))
1385       got_write_error = TRUE;
1386   } else
1387     wtap_dump_close(pdh, &close_err);
1388
1389   if (got_read_error) {
1390     /*
1391      * Find the file on which we got the error, and report the error.
1392      */
1393     for (i = 0; i < in_file_count; i++) {
1394       if (in_files[i].state == GOT_ERROR) {
1395         /* Put up a message box noting that a read failed somewhere along
1396            the line. */
1397         switch (read_err) {
1398
1399         case WTAP_ERR_UNSUPPORTED_ENCAP:
1400           g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1401                    "The capture file %%s has a packet with a network type that Wireshark doesn't support.\n(%s)",
1402                    err_info);
1403           g_free(err_info);
1404           errmsg = errmsg_errno;
1405           break;
1406
1407         case WTAP_ERR_CANT_READ:
1408           errmsg = "An attempt to read from the capture file %s failed for"
1409                    " some unknown reason.";
1410           break;
1411
1412         case WTAP_ERR_SHORT_READ:
1413           errmsg = "The capture file %s appears to have been cut short"
1414                    " in the middle of a packet.";
1415           break;
1416
1417         case WTAP_ERR_BAD_RECORD:
1418           g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1419                    "The capture file %%s appears to be damaged or corrupt.\n(%s)",
1420                    err_info);
1421           g_free(err_info);
1422           errmsg = errmsg_errno;
1423           break;
1424
1425         default:
1426           g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1427                    "An error occurred while reading the"
1428                    " capture file %%s: %s.", wtap_strerror(read_err));
1429           errmsg = errmsg_errno;
1430           break;
1431         }
1432         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, errmsg, in_files[i].filename);
1433       }
1434     }
1435   }
1436
1437   if (got_write_error) {
1438     /* Put up an alert box for the write error. */
1439     cf_write_failure_alert_box(out_filename, write_err);
1440   }
1441
1442   if (got_read_error || got_write_error || stop_flag) {
1443     /* Callers aren't expected to treat an error or an explicit abort
1444        differently - we put up error dialogs ourselves, so they don't
1445        have to. */
1446     return CF_ERROR;
1447   } else
1448     return CF_OK;
1449 }
1450
1451 cf_status_t
1452 cf_filter_packets(capture_file *cf, gchar *dftext, gboolean force)
1453 {
1454   const char *filter_new = dftext ? dftext : "";
1455   const char *filter_old = cf->dfilter ? cf->dfilter : "";
1456   dfilter_t   *dfcode;
1457
1458   /* if new filter equals old one, do nothing unless told to do so */
1459   if (!force && strcmp(filter_new, filter_old) == 0) {
1460     return CF_OK;
1461   }
1462
1463   dfcode=NULL;
1464
1465   if (dftext == NULL) {
1466     /* The new filter is an empty filter (i.e., display all packets).
1467      * so leave dfcode==NULL
1468      */
1469   } else {
1470     /*
1471      * We have a filter; make a copy of it (as we'll be saving it),
1472      * and try to compile it.
1473      */
1474     dftext = g_strdup(dftext);
1475     if (!dfilter_compile(dftext, &dfcode)) {
1476       /* The attempt failed; report an error. */
1477       gchar *safe_dftext = simple_dialog_format_message(dftext);
1478       gchar *safe_dfilter_error_msg = simple_dialog_format_message(
1479           dfilter_error_msg);
1480       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1481           "%s%s%s\n"
1482           "\n"
1483           "The following display filter isn't a valid display filter:\n%s\n"
1484           "See the help for a description of the display filter syntax.",
1485           simple_dialog_primary_start(), safe_dfilter_error_msg,
1486           simple_dialog_primary_end(), safe_dftext);
1487       g_free(safe_dfilter_error_msg);
1488       g_free(safe_dftext);
1489       g_free(dftext);
1490       return CF_ERROR;
1491     }
1492
1493     /* Was it empty? */
1494     if (dfcode == NULL) {
1495       /* Yes - free the filter text, and set it to null. */
1496       g_free(dftext);
1497       dftext = NULL;
1498     }
1499   }
1500
1501   /* We have a valid filter.  Replace the current filter. */
1502   g_free(cf->dfilter);
1503   cf->dfilter = dftext;
1504
1505   /* Now rescan the packet list, applying the new filter, but not
1506      throwing away information constructed on a previous pass. */
1507   if (dftext == NULL) {
1508     rescan_packets(cf, "Resetting", "Filter", TRUE, FALSE);
1509   } else {
1510     rescan_packets(cf, "Filtering", dftext, TRUE, FALSE);
1511   }
1512
1513   /* Cleanup and release all dfilter resources */
1514   if (dfcode != NULL){
1515     dfilter_free(dfcode);
1516   }
1517   return CF_OK;
1518 }
1519
1520 void
1521 cf_colorize_packets(capture_file *cf)
1522 {
1523   rescan_packets(cf, "Colorizing", "all packets", FALSE, FALSE);
1524 }
1525
1526 void
1527 cf_reftime_packets(capture_file *cf)
1528 {
1529   rescan_packets(cf, "Updating Reftime", "all packets", FALSE, FALSE);
1530 }
1531
1532 void
1533 cf_redissect_packets(capture_file *cf)
1534 {
1535   rescan_packets(cf, "Reprocessing", "all packets", TRUE, TRUE);
1536 }
1537
1538 /* Rescan the list of packets, reconstructing the CList.
1539
1540    "action" describes why we're doing this; it's used in the progress
1541    dialog box.
1542
1543    "action_item" describes what we're doing; it's used in the progress
1544    dialog box.
1545
1546    "refilter" is TRUE if we need to re-evaluate the filter expression.
1547
1548    "redissect" is TRUE if we need to make the dissectors reconstruct
1549    any state information they have (because a preference that affects
1550    some dissector has changed, meaning some dissector might construct
1551    its state differently from the way it was constructed the last time). */
1552 static void
1553 rescan_packets(capture_file *cf, const char *action, const char *action_item,
1554                 gboolean refilter, gboolean redissect)
1555 {
1556   frame_data *fdata;
1557   progdlg_t  *progbar = NULL;
1558   gboolean    stop_flag;
1559   int         count;
1560   int         err;
1561   gchar      *err_info;
1562   frame_data *selected_frame, *preceding_frame, *following_frame, *prev_frame;
1563   int         selected_row, prev_row, preceding_row, following_row;
1564   gboolean    selected_frame_seen;
1565   int         row;
1566   float       progbar_val;
1567   GTimeVal    start_time;
1568   gchar       status_str[100];
1569   int         progbar_nextstep;
1570   int         progbar_quantum;
1571   dfilter_t   *dfcode;
1572   gboolean    filtering_tap_listeners;
1573   guint       tap_flags;
1574
1575   /* Compile the current display filter.
1576    * We assume this will not fail since cf->dfilter is only set in
1577    * cf_filter IFF the filter was valid.
1578    */
1579   dfcode=NULL;
1580   if(cf->dfilter){
1581     dfilter_compile(cf->dfilter, &dfcode);
1582   }
1583
1584   /* Do we have any tap listeners with filters? */
1585   filtering_tap_listeners = have_filtering_tap_listeners();
1586
1587   /* Get the union of the flags for all tap listeners. */
1588   tap_flags = union_of_tap_listener_flags();
1589
1590   cum_bytes=0;
1591   reset_tap_listeners();
1592   /* Which frame, if any, is the currently selected frame?
1593      XXX - should the selected frame or the focus frame be the "current"
1594      frame, that frame being the one from which "Find Frame" searches
1595      start? */
1596   selected_frame = cf->current_frame;
1597
1598   /* We don't yet know what row that frame will be on, if any, after we
1599      rebuild the clist, however. */
1600   selected_row = -1;
1601
1602   if (redissect) {
1603     /* We need to re-initialize all the state information that protocols
1604        keep, because some preference that controls a dissector has changed,
1605        which might cause the state information to be constructed differently
1606        by that dissector. */
1607
1608     /* We might receive new packets while redissecting, and we don't
1609        want to dissect those before their time. */
1610     cf->redissecting = TRUE;
1611
1612     /* Initialize all data structures used for dissection. */
1613     init_dissection();
1614   }
1615
1616   /* Freeze the packet list while we redo it, so we don't get any
1617      screen updates while it happens. */
1618 #ifdef NEW_PACKET_LIST
1619   new_packet_list_freeze();
1620 #else
1621   packet_list_freeze();
1622
1623   /* Clear it out. */
1624   packet_list_clear();
1625 #endif
1626
1627   /* We don't yet know which will be the first and last frames displayed. */
1628   cf->first_displayed = NULL;
1629   cf->last_displayed = NULL;
1630
1631   /* We currently don't display any packets */
1632   cf->displayed_count = 0;
1633
1634   /* Iterate through the list of frames.  Call a routine for each frame
1635      to check whether it should be displayed and, if so, add it to
1636      the display list. */
1637   nstime_set_unset(&first_ts);
1638   nstime_set_unset(&prev_dis_ts);
1639
1640   /* Update the progress bar when it gets to this value. */
1641   progbar_nextstep = 0;
1642   /* When we reach the value that triggers a progress bar update,
1643      bump that value by this amount. */
1644   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
1645   /* Count of packets at which we've looked. */
1646   count = 0;
1647   /* Progress so far. */
1648   progbar_val = 0.0f;
1649
1650   stop_flag = FALSE;
1651   g_get_current_time(&start_time);
1652
1653   row = -1;             /* no previous row yet */
1654   prev_row = -1;
1655   prev_frame = NULL;
1656
1657   preceding_row = -1;
1658   preceding_frame = NULL;
1659   following_row = -1;
1660   following_frame = NULL;
1661
1662   selected_frame_seen = FALSE;
1663
1664   for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
1665     /* Create the progress bar if necessary.
1666        We check on every iteration of the loop, so that it takes no
1667        longer than the standard time to create it (otherwise, for a
1668        large file, we might take considerably longer than that standard
1669        time in order to get to the next progress bar step). */
1670     if (progbar == NULL)
1671       progbar = delayed_create_progress_dlg(action, action_item, TRUE,
1672                                             &stop_flag, &start_time,
1673                                             progbar_val);
1674
1675     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1676        when we update it, we have to run the GTK+ main loop to get it
1677        to repaint what's pending, and doing so may involve an "ioctl()"
1678        to see if there's any pending input from an X server, and doing
1679        that for every packet can be costly, especially on a big file. */
1680     if (count >= progbar_nextstep) {
1681       /* let's not divide by zero. I should never be started
1682        * with count == 0, so let's assert that
1683        */
1684       g_assert(cf->count > 0);
1685       progbar_val = (gfloat) count / cf->count;
1686
1687       if (progbar != NULL) {
1688         g_snprintf(status_str, sizeof(status_str),
1689                   "%4u of %u frames", count, cf->count);
1690         update_progress_dlg(progbar, progbar_val, status_str);
1691       }
1692
1693       progbar_nextstep += progbar_quantum;
1694     }
1695
1696     if (stop_flag) {
1697       /* Well, the user decided to abort the filtering.  Just stop.
1698
1699          XXX - go back to the previous filter?  Users probably just
1700          want not to wait for a filtering operation to finish;
1701          unless we cancel by having no filter, reverting to the
1702          previous filter will probably be even more expensive than
1703          continuing the filtering, as it involves going back to the
1704          beginning and filtering, and even with no filter we currently
1705          have to re-generate the entire clist, which is also expensive.
1706
1707          I'm not sure what Network Monitor does, but it doesn't appear
1708          to give you an unfiltered display if you cancel. */
1709       break;
1710     }
1711
1712     count++;
1713
1714     if (redissect) {
1715       /* Since all state for the frame was destroyed, mark the frame
1716        * as not visited, free the GSList referring to the state
1717        * data (the per-frame data itself was freed by
1718        * "init_dissection()"), and null out the GSList pointer. */
1719       fdata->flags.visited = 0;
1720       if (fdata->pfd) {
1721                 g_slist_free(fdata->pfd);
1722         fdata->pfd = NULL;
1723       }
1724     }
1725
1726     if (!wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
1727         cf->pd, fdata->cap_len, &err, &err_info)) {
1728                         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1729                     cf_read_error_message(err, err_info), cf->filename);
1730                         break;
1731     }
1732
1733     /* If the previous frame is displayed, and we haven't yet seen the
1734        selected frame, remember that frame - it's the closest one we've
1735        yet seen before the selected frame. */
1736     if (prev_row != -1 && !selected_frame_seen) {
1737       preceding_row = prev_row;
1738       preceding_frame = prev_frame;
1739     }
1740     row = add_packet_to_packet_list(fdata, cf, dfcode, filtering_tap_listeners,
1741                                     tap_flags, &cf->pseudo_header, cf->pd,
1742                                     refilter);
1743
1744     /* If this frame is displayed, and this is the first frame we've
1745        seen displayed after the selected frame, remember this frame -
1746        it's the closest one we've yet seen at or after the selected
1747        frame. */
1748     if (row != -1 && selected_frame_seen && following_row == -1) {
1749       following_row = row;
1750       following_frame = fdata;
1751     }
1752     if (fdata == selected_frame) {
1753       selected_row = row;
1754       selected_frame_seen = TRUE;
1755     }
1756
1757     /* Remember this row/frame - it'll be the previous row/frame
1758        on the next pass through the loop. */
1759     prev_row = row;
1760     prev_frame = fdata;
1761   }
1762
1763   /* We are done redissecting the packet list. */
1764   cf->redissecting = FALSE;
1765
1766 #ifndef NEW_PACKET_LIST
1767   /* Re-sort the list using the previously selected order */
1768   packet_list_set_sort_column();
1769 #endif
1770
1771   if (redissect) {
1772     /* Clear out what remains of the visited flags and per-frame data
1773        pointers.
1774
1775        XXX - that may cause various forms of bogosity when dissecting
1776        these frames, as they won't have been seen by this sequential
1777        pass, but the only alternative I see is to keep scanning them
1778        even though the user requested that the scan stop, and that
1779        would leave the user stuck with an Wireshark grinding on
1780        until it finishes.  Should we just stick them with that? */
1781     for (; fdata != NULL; fdata = fdata->next) {
1782       fdata->flags.visited = 0;
1783       if (fdata->pfd) {
1784                 g_slist_free(fdata->pfd);
1785         fdata->pfd = NULL;
1786       }
1787     }
1788   }
1789
1790   /* We're done filtering the packets; destroy the progress bar if it
1791      was created. */
1792   if (progbar != NULL)
1793     destroy_progress_dlg(progbar);
1794
1795   /* Unfreeze the packet list. */
1796 #ifdef NEW_PACKET_LIST
1797   new_packet_list_thaw();
1798 #else
1799   packet_list_thaw();
1800 #endif
1801
1802   if (selected_row == -1) {
1803     /* The selected frame didn't pass the filter. */
1804     if (selected_frame == NULL) {
1805       /* That's because there *was* no selected frame.  Make the first
1806          displayed frame the current frame. */
1807       selected_row = 0;
1808     } else {
1809       /* Find the nearest displayed frame to the selected frame (whether
1810          it's before or after that frame) and make that the current frame.
1811          If the next and previous displayed frames are equidistant from the
1812          selected frame, choose the next one. */
1813       g_assert(following_frame == NULL ||
1814                following_frame->num >= selected_frame->num);
1815       g_assert(preceding_frame == NULL ||
1816                preceding_frame->num <= selected_frame->num);
1817       if (following_frame == NULL) {
1818         /* No frame after the selected frame passed the filter, so we
1819            have to select the last displayed frame before the selected
1820            frame. */
1821         selected_row = preceding_row;
1822       } else if (preceding_frame == NULL) {
1823         /* No frame before the selected frame passed the filter, so we
1824            have to select the first displayed frame after the selected
1825            frame. */
1826         selected_row = following_row;
1827       } else {
1828         /* Frames before and after the selected frame passed the filter, so
1829                    we'll select the previous frame */
1830         selected_row = preceding_row;
1831       }
1832     }
1833   }
1834
1835   if (selected_row == -1) {
1836     /* There are no frames displayed at all. */
1837     cf_unselect_packet(cf);
1838   } else {
1839 #ifndef NEW_PACKET_LIST
1840     /* Either the frame that was selected passed the filter, or we've
1841        found the nearest displayed frame to that frame.  Select it, make
1842        it the focus row, and make it visible. */
1843     if (selected_row == 0) {
1844       /* Set to invalid to force update of packet list and packet details */
1845       cf->current_row = -1;
1846     }
1847     packet_list_set_selected_row(selected_row);
1848 #endif /* NEW_PACKET_LIST */
1849   }
1850
1851   /* Cleanup and release all dfilter resources */
1852   if (dfcode != NULL){
1853     dfilter_free(dfcode);
1854   }
1855 }
1856
1857 typedef enum {
1858   PSP_FINISHED,
1859   PSP_STOPPED,
1860   PSP_FAILED
1861 } psp_return_t;
1862
1863 static psp_return_t
1864 process_specified_packets(capture_file *cf, packet_range_t *range,
1865     const char *string1, const char *string2, gboolean terminate_is_stop,
1866     gboolean (*callback)(capture_file *, frame_data *,
1867                          union wtap_pseudo_header *, const guint8 *, void *),
1868     void *callback_args)
1869 {
1870   frame_data *fdata;
1871   int         err;
1872   gchar      *err_info;
1873   union wtap_pseudo_header pseudo_header;
1874   guint8      pd[WTAP_MAX_PACKET_SIZE+1];
1875   psp_return_t ret = PSP_FINISHED;
1876
1877   progdlg_t  *progbar = NULL;
1878   int         progbar_count;
1879   float       progbar_val;
1880   gboolean    progbar_stop_flag;
1881   GTimeVal    progbar_start_time;
1882   gchar       progbar_status_str[100];
1883   int         progbar_nextstep;
1884   int         progbar_quantum;
1885   range_process_e process_this;
1886
1887   /* Update the progress bar when it gets to this value. */
1888   progbar_nextstep = 0;
1889   /* When we reach the value that triggers a progress bar update,
1890      bump that value by this amount. */
1891   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
1892   /* Count of packets at which we've looked. */
1893   progbar_count = 0;
1894   /* Progress so far. */
1895   progbar_val = 0.0f;
1896
1897   progbar_stop_flag = FALSE;
1898   g_get_current_time(&progbar_start_time);
1899
1900   packet_range_process_init(range);
1901
1902   /* Iterate through the list of packets, printing the packets that
1903      were selected by the current display filter.  */
1904   for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
1905     /* Create the progress bar if necessary.
1906        We check on every iteration of the loop, so that it takes no
1907        longer than the standard time to create it (otherwise, for a
1908        large file, we might take considerably longer than that standard
1909        time in order to get to the next progress bar step). */
1910     if (progbar == NULL)
1911       progbar = delayed_create_progress_dlg(string1, string2,
1912                                             terminate_is_stop,
1913                                             &progbar_stop_flag,
1914                                             &progbar_start_time,
1915                                             progbar_val);
1916
1917     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
1918        when we update it, we have to run the GTK+ main loop to get it
1919        to repaint what's pending, and doing so may involve an "ioctl()"
1920        to see if there's any pending input from an X server, and doing
1921        that for every packet can be costly, especially on a big file. */
1922     if (progbar_count >= progbar_nextstep) {
1923       /* let's not divide by zero. I should never be started
1924        * with count == 0, so let's assert that
1925        */
1926       g_assert(cf->count > 0);
1927       progbar_val = (gfloat) progbar_count / cf->count;
1928
1929       if (progbar != NULL) {
1930         g_snprintf(progbar_status_str, sizeof(progbar_status_str),
1931                    "%4u of %u packets", progbar_count, cf->count);
1932         update_progress_dlg(progbar, progbar_val, progbar_status_str);
1933       }
1934
1935       progbar_nextstep += progbar_quantum;
1936     }
1937
1938     if (progbar_stop_flag) {
1939       /* Well, the user decided to abort the operation.  Just stop,
1940          and arrange to return PSP_STOPPED to our caller, so they know
1941          it was stopped explicitly. */
1942       ret = PSP_STOPPED;
1943       break;
1944     }
1945
1946     progbar_count++;
1947
1948     /* do we have to process this packet? */
1949     process_this = packet_range_process_packet(range, fdata);
1950     if (process_this == range_process_next) {
1951         /* this packet uninteresting, continue with next one */
1952         continue;
1953     } else if (process_this == range_processing_finished) {
1954         /* all interesting packets processed, stop the loop */
1955         break;
1956     }
1957
1958     /* Get the packet */
1959     if (!wtap_seek_read(cf->wth, fdata->file_off, &pseudo_header,
1960                         pd, fdata->cap_len, &err, &err_info)) {
1961       /* Attempt to get the packet failed. */
1962       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
1963                     cf_read_error_message(err, err_info), cf->filename);
1964       ret = PSP_FAILED;
1965       break;
1966     }
1967     /* Process the packet */
1968     if (!callback(cf, fdata, &pseudo_header, pd, callback_args)) {
1969       /* Callback failed.  We assume it reported the error appropriately. */
1970       ret = PSP_FAILED;
1971       break;
1972     }
1973   }
1974
1975   /* We're done printing the packets; destroy the progress bar if
1976      it was created. */
1977   if (progbar != NULL)
1978     destroy_progress_dlg(progbar);
1979
1980   return ret;
1981 }
1982
1983 typedef struct {
1984   gboolean construct_protocol_tree;
1985   column_info *cinfo;
1986 } retap_callback_args_t;
1987
1988 static gboolean
1989 retap_packet(capture_file *cf _U_, frame_data *fdata,
1990              union wtap_pseudo_header *pseudo_header, const guint8 *pd,
1991              void *argsp)
1992 {
1993   retap_callback_args_t *args = argsp;
1994   epan_dissect_t *edt;
1995
1996   edt = epan_dissect_new(args->construct_protocol_tree, FALSE);
1997   tap_queue_init(edt);
1998   epan_dissect_run(edt, pseudo_header, pd, fdata, args->cinfo);
1999   tap_push_tapped_queue(edt);
2000   epan_dissect_free(edt);
2001
2002   return TRUE;
2003 }
2004
2005 cf_read_status_t
2006 cf_retap_packets(capture_file *cf)
2007 {
2008   packet_range_t range;
2009   retap_callback_args_t callback_args;
2010   gboolean filtering_tap_listeners;
2011   guint tap_flags;
2012
2013   /* Do we have any tap listeners with filters? */
2014   filtering_tap_listeners = have_filtering_tap_listeners();
2015
2016   tap_flags = union_of_tap_listener_flags();
2017
2018   /* If any tap listeners have filters, or require the protocol tree,
2019      construct the protocol tree. */
2020   callback_args.construct_protocol_tree = filtering_tap_listeners ||
2021                                           (tap_flags & TL_REQUIRES_PROTO_TREE);
2022
2023   /* If any tap listeners require the columns, construct them. */
2024   callback_args.cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
2025
2026   /* Reset the tap listeners. */
2027   reset_tap_listeners();
2028
2029   /* Iterate through the list of packets, dissecting all packets and
2030      re-running the taps. */
2031   packet_range_init(&range);
2032   packet_range_process_init(&range);
2033   switch (process_specified_packets(cf, &range, "Recalculating statistics on",
2034                                     "all packets", TRUE, retap_packet,
2035                                     &callback_args)) {
2036   case PSP_FINISHED:
2037     /* Completed successfully. */
2038     return CF_READ_OK;
2039
2040   case PSP_STOPPED:
2041     /* Well, the user decided to abort the refiltering.
2042        Return CF_READ_ABORTED so our caller knows they did that. */
2043     return CF_READ_ABORTED;
2044
2045   case PSP_FAILED:
2046     /* Error while retapping. */
2047     return CF_READ_ERROR;
2048   }
2049
2050   g_assert_not_reached();
2051   return CF_READ_OK;
2052 }
2053
2054 typedef struct {
2055   print_args_t *print_args;
2056   gboolean      print_header_line;
2057   char         *header_line_buf;
2058   int           header_line_buf_len;
2059   gboolean      print_formfeed;
2060   gboolean      print_separator;
2061   char         *line_buf;
2062   int           line_buf_len;
2063   gint         *col_widths;
2064 } print_callback_args_t;
2065
2066 static gboolean
2067 print_packet(capture_file *cf, frame_data *fdata,
2068              union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2069              void *argsp)
2070 {
2071   print_callback_args_t *args = argsp;
2072   epan_dissect_t *edt;
2073   int             i;
2074   char           *cp;
2075   int             line_len;
2076   int             column_len;
2077   int             cp_off;
2078   gboolean        proto_tree_needed;
2079   char            bookmark_name[9+10+1];        /* "__frameNNNNNNNNNN__\0" */
2080   char            bookmark_title[6+10+1];       /* "Frame NNNNNNNNNN__\0" */
2081
2082   /* Create the protocol tree, and make it visible, if we're printing
2083      the dissection or the hex data.
2084      XXX - do we need it if we're just printing the hex data? */
2085   proto_tree_needed =
2086       args->print_args->print_dissections != print_dissections_none || args->print_args->print_hex || have_custom_cols(&cf->cinfo);
2087   edt = epan_dissect_new(proto_tree_needed, proto_tree_needed);
2088
2089   /* Fill in the column information if we're printing the summary
2090      information. */
2091   if (args->print_args->print_summary) {
2092     epan_dissect_run(edt, pseudo_header, pd, fdata, &cf->cinfo);
2093     epan_dissect_fill_in_columns(edt);
2094   } else
2095     epan_dissect_run(edt, pseudo_header, pd, fdata, NULL);
2096
2097   if (args->print_formfeed) {
2098     if (!new_page(args->print_args->stream))
2099       goto fail;
2100   } else {
2101       if (args->print_separator) {
2102         if (!print_line(args->print_args->stream, 0, ""))
2103           goto fail;
2104       }
2105   }
2106
2107   /*
2108    * We generate bookmarks, if the output format supports them.
2109    * The name is "__frameN__".
2110    */
2111   g_snprintf(bookmark_name, sizeof bookmark_name, "__frame%u__", fdata->num);
2112
2113   if (args->print_args->print_summary) {
2114     if (args->print_header_line) {
2115       if (!print_line(args->print_args->stream, 0, args->header_line_buf))
2116         goto fail;
2117       args->print_header_line = FALSE;  /* we might not need to print any more */
2118     }
2119     cp = &args->line_buf[0];
2120     line_len = 0;
2121     for (i = 0; i < cf->cinfo.num_cols; i++) {
2122       /* Find the length of the string for this column. */
2123       column_len = (int) strlen(cf->cinfo.col_data[i]);
2124       if (args->col_widths[i] > column_len)
2125          column_len = args->col_widths[i];
2126
2127       /* Make sure there's room in the line buffer for the column; if not,
2128          double its length. */
2129       line_len += column_len + 1;       /* "+1" for space */
2130       if (line_len > args->line_buf_len) {
2131         cp_off = (int) (cp - args->line_buf);
2132         args->line_buf_len = 2 * line_len;
2133         args->line_buf = g_realloc(args->line_buf, args->line_buf_len + 1);
2134         cp = args->line_buf + cp_off;
2135       }
2136
2137       /* Right-justify the packet number column. */
2138       if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2139         g_snprintf(cp, column_len+1, "%*s", args->col_widths[i], cf->cinfo.col_data[i]);
2140       else
2141         g_snprintf(cp, column_len+1, "%-*s", args->col_widths[i], cf->cinfo.col_data[i]);
2142       cp += column_len;
2143       if (i != cf->cinfo.num_cols - 1)
2144         *cp++ = ' ';
2145     }
2146     *cp = '\0';
2147
2148     /*
2149      * Generate a bookmark, using the summary line as the title.
2150      */
2151     if (!print_bookmark(args->print_args->stream, bookmark_name,
2152                         args->line_buf))
2153       goto fail;
2154
2155     if (!print_line(args->print_args->stream, 0, args->line_buf))
2156       goto fail;
2157   } else {
2158     /*
2159      * Generate a bookmark, using "Frame N" as the title, as we're not
2160      * printing the summary line.
2161      */
2162     g_snprintf(bookmark_title, sizeof bookmark_title, "Frame %u", fdata->num);
2163     if (!print_bookmark(args->print_args->stream, bookmark_name,
2164                         bookmark_title))
2165       goto fail;
2166   } /* if (print_summary) */
2167
2168   if (args->print_args->print_dissections != print_dissections_none) {
2169     if (args->print_args->print_summary) {
2170       /* Separate the summary line from the tree with a blank line. */
2171       if (!print_line(args->print_args->stream, 0, ""))
2172         goto fail;
2173     }
2174
2175     /* Print the information in that tree. */
2176     if (!proto_tree_print(args->print_args, edt, args->print_args->stream))
2177       goto fail;
2178
2179     /* Print a blank line if we print anything after this (aka more than one packet). */
2180     args->print_separator = TRUE;
2181
2182     /* Print a header line if we print any more packet summaries */
2183     args->print_header_line = TRUE;
2184   }
2185
2186   if (args->print_args->print_hex) {
2187     /* Print the full packet data as hex. */
2188     if (!print_hex_data(args->print_args->stream, edt))
2189       goto fail;
2190
2191     /* Print a blank line if we print anything after this (aka more than one packet). */
2192     args->print_separator = TRUE;
2193
2194     /* Print a header line if we print any more packet summaries */
2195     args->print_header_line = TRUE;
2196   } /* if (args->print_args->print_dissections != print_dissections_none) */
2197
2198   epan_dissect_free(edt);
2199
2200   /* do we want to have a formfeed between each packet from now on? */
2201   if(args->print_args->print_formfeed) {
2202     args->print_formfeed = TRUE;
2203   }
2204
2205   return TRUE;
2206
2207 fail:
2208   epan_dissect_free(edt);
2209   return FALSE;
2210 }
2211
2212 cf_print_status_t
2213 cf_print_packets(capture_file *cf, print_args_t *print_args)
2214 {
2215   int         i;
2216   print_callback_args_t callback_args;
2217   gint        data_width;
2218   char        *cp;
2219   int         cp_off;
2220   int         column_len;
2221   int         line_len;
2222   psp_return_t ret;
2223
2224   callback_args.print_args = print_args;
2225   callback_args.print_header_line = TRUE;
2226   callback_args.header_line_buf = NULL;
2227   callback_args.header_line_buf_len = 256;
2228   callback_args.print_formfeed = FALSE;
2229   callback_args.print_separator = FALSE;
2230   callback_args.line_buf = NULL;
2231   callback_args.line_buf_len = 256;
2232   callback_args.col_widths = NULL;
2233
2234   if (!print_preamble(print_args->stream, cf->filename)) {
2235     destroy_print_stream(print_args->stream);
2236     return CF_PRINT_WRITE_ERROR;
2237   }
2238
2239   if (print_args->print_summary) {
2240     /* We're printing packet summaries.  Allocate the header line buffer
2241        and get the column widths. */
2242     callback_args.header_line_buf = g_malloc(callback_args.header_line_buf_len + 1);
2243
2244     /* Find the widths for each of the columns - maximum of the
2245        width of the title and the width of the data - and construct
2246        a buffer with a line containing the column titles. */
2247     callback_args.col_widths = (gint *) g_malloc(sizeof(gint) * cf->cinfo.num_cols);
2248     cp = &callback_args.header_line_buf[0];
2249     line_len = 0;
2250     for (i = 0; i < cf->cinfo.num_cols; i++) {
2251       /* Don't pad the last column. */
2252       if (i == cf->cinfo.num_cols - 1)
2253         callback_args.col_widths[i] = 0;
2254       else {
2255         callback_args.col_widths[i] = (gint) strlen(cf->cinfo.col_title[i]);
2256         data_width = get_column_char_width(get_column_format(i));
2257         if (data_width > callback_args.col_widths[i])
2258           callback_args.col_widths[i] = data_width;
2259       }
2260
2261       /* Find the length of the string for this column. */
2262       column_len = (int) strlen(cf->cinfo.col_title[i]);
2263       if (callback_args.col_widths[i] > column_len)
2264         column_len = callback_args.col_widths[i];
2265
2266       /* Make sure there's room in the line buffer for the column; if not,
2267          double its length. */
2268       line_len += column_len + 1;       /* "+1" for space */
2269       if (line_len > callback_args.header_line_buf_len) {
2270         cp_off = (int) (cp - callback_args.header_line_buf);
2271         callback_args.header_line_buf_len = 2 * line_len;
2272         callback_args.header_line_buf = g_realloc(callback_args.header_line_buf,
2273                                                   callback_args.header_line_buf_len + 1);
2274         cp = callback_args.header_line_buf + cp_off;
2275       }
2276
2277       /* Right-justify the packet number column. */
2278 /*      if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2279         g_snprintf(cp, column_len+1, "%*s", callback_args.col_widths[i], cf->cinfo.col_title[i]);
2280       else*/
2281       g_snprintf(cp, column_len+1, "%-*s", callback_args.col_widths[i], cf->cinfo.col_title[i]);
2282       cp += column_len;
2283       if (i != cf->cinfo.num_cols - 1)
2284         *cp++ = ' ';
2285     }
2286     *cp = '\0';
2287
2288     /* Now start out the main line buffer with the same length as the
2289        header line buffer. */
2290     callback_args.line_buf_len = callback_args.header_line_buf_len;
2291     callback_args.line_buf = g_malloc(callback_args.line_buf_len + 1);
2292   } /* if (print_summary) */
2293
2294   /* Iterate through the list of packets, printing the packets we were
2295      told to print. */
2296   ret = process_specified_packets(cf, &print_args->range, "Printing",
2297                                   "selected packets", TRUE, print_packet,
2298                                   &callback_args);
2299
2300   g_free(callback_args.header_line_buf);
2301   g_free(callback_args.line_buf);
2302   g_free(callback_args.col_widths);
2303
2304   switch (ret) {
2305
2306   case PSP_FINISHED:
2307     /* Completed successfully. */
2308     break;
2309
2310   case PSP_STOPPED:
2311     /* Well, the user decided to abort the printing.
2312
2313        XXX - note that what got generated before they did that
2314        will get printed if we're piping to a print program; we'd
2315        have to write to a file and then hand that to the print
2316        program to make it actually not print anything. */
2317     break;
2318
2319   case PSP_FAILED:
2320     /* Error while printing.
2321
2322        XXX - note that what got generated before they did that
2323        will get printed if we're piping to a print program; we'd
2324        have to write to a file and then hand that to the print
2325        program to make it actually not print anything. */
2326     destroy_print_stream(print_args->stream);
2327     return CF_PRINT_WRITE_ERROR;
2328   }
2329
2330   if (!print_finale(print_args->stream)) {
2331     destroy_print_stream(print_args->stream);
2332     return CF_PRINT_WRITE_ERROR;
2333   }
2334
2335   if (!destroy_print_stream(print_args->stream))
2336     return CF_PRINT_WRITE_ERROR;
2337
2338   return CF_PRINT_OK;
2339 }
2340
2341 static gboolean
2342 write_pdml_packet(capture_file *cf _U_, frame_data *fdata,
2343                   union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2344                   void *argsp)
2345 {
2346   FILE *fh = argsp;
2347   epan_dissect_t *edt;
2348
2349   /* Create the protocol tree, but don't fill in the column information. */
2350   edt = epan_dissect_new(TRUE, TRUE);
2351   epan_dissect_run(edt, pseudo_header, pd, fdata, NULL);
2352
2353   /* Write out the information in that tree. */
2354   proto_tree_write_pdml(edt, fh);
2355
2356   epan_dissect_free(edt);
2357
2358   return !ferror(fh);
2359 }
2360
2361 cf_print_status_t
2362 cf_write_pdml_packets(capture_file *cf, print_args_t *print_args)
2363 {
2364   FILE        *fh;
2365   psp_return_t ret;
2366
2367   fh = ws_fopen(print_args->file, "w");
2368   if (fh == NULL)
2369     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2370
2371   write_pdml_preamble(fh);
2372   if (ferror(fh)) {
2373     fclose(fh);
2374     return CF_PRINT_WRITE_ERROR;
2375   }
2376
2377   /* Iterate through the list of packets, printing the packets we were
2378      told to print. */
2379   ret = process_specified_packets(cf, &print_args->range, "Writing PDML",
2380                                   "selected packets", TRUE,
2381                                   write_pdml_packet, fh);
2382
2383   switch (ret) {
2384
2385   case PSP_FINISHED:
2386     /* Completed successfully. */
2387     break;
2388
2389   case PSP_STOPPED:
2390     /* Well, the user decided to abort the printing. */
2391     break;
2392
2393   case PSP_FAILED:
2394     /* Error while printing. */
2395     fclose(fh);
2396     return CF_PRINT_WRITE_ERROR;
2397   }
2398
2399   write_pdml_finale(fh);
2400   if (ferror(fh)) {
2401     fclose(fh);
2402     return CF_PRINT_WRITE_ERROR;
2403   }
2404
2405   /* XXX - check for an error */
2406   fclose(fh);
2407
2408   return CF_PRINT_OK;
2409 }
2410
2411 static gboolean
2412 write_psml_packet(capture_file *cf, frame_data *fdata,
2413                   union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2414                   void *argsp)
2415 {
2416   FILE *fh = argsp;
2417   epan_dissect_t *edt;
2418   gboolean proto_tree_needed;
2419
2420   /* Fill in the column information, only create the protocol tree
2421      if having custom columns. */
2422   proto_tree_needed = have_custom_cols(&cf->cinfo);
2423   edt = epan_dissect_new(proto_tree_needed, proto_tree_needed);
2424   epan_dissect_run(edt, pseudo_header, pd, fdata, &cf->cinfo);
2425   epan_dissect_fill_in_columns(edt);
2426
2427   /* Write out the information in that tree. */
2428   proto_tree_write_psml(edt, fh);
2429
2430   epan_dissect_free(edt);
2431
2432   return !ferror(fh);
2433 }
2434
2435 cf_print_status_t
2436 cf_write_psml_packets(capture_file *cf, print_args_t *print_args)
2437 {
2438   FILE        *fh;
2439   psp_return_t ret;
2440
2441   fh = ws_fopen(print_args->file, "w");
2442   if (fh == NULL)
2443     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2444
2445   write_psml_preamble(fh);
2446   if (ferror(fh)) {
2447     fclose(fh);
2448     return CF_PRINT_WRITE_ERROR;
2449   }
2450
2451   /* Iterate through the list of packets, printing the packets we were
2452      told to print. */
2453   ret = process_specified_packets(cf, &print_args->range, "Writing PSML",
2454                                   "selected packets", TRUE,
2455                                   write_psml_packet, fh);
2456
2457   switch (ret) {
2458
2459   case PSP_FINISHED:
2460     /* Completed successfully. */
2461     break;
2462
2463   case PSP_STOPPED:
2464     /* Well, the user decided to abort the printing. */
2465     break;
2466
2467   case PSP_FAILED:
2468     /* Error while printing. */
2469     fclose(fh);
2470     return CF_PRINT_WRITE_ERROR;
2471   }
2472
2473   write_psml_finale(fh);
2474   if (ferror(fh)) {
2475     fclose(fh);
2476     return CF_PRINT_WRITE_ERROR;
2477   }
2478
2479   /* XXX - check for an error */
2480   fclose(fh);
2481
2482   return CF_PRINT_OK;
2483 }
2484
2485 static gboolean
2486 write_csv_packet(capture_file *cf, frame_data *fdata,
2487                  union wtap_pseudo_header *pseudo_header, const guint8 *pd,
2488                  void *argsp)
2489 {
2490   FILE *fh = argsp;
2491   epan_dissect_t *edt;
2492   gboolean proto_tree_needed;
2493
2494   /* Fill in the column information, only create the protocol tree
2495      if having custom columns. */
2496   proto_tree_needed = have_custom_cols(&cf->cinfo);
2497   edt = epan_dissect_new(proto_tree_needed, proto_tree_needed);
2498   epan_dissect_run(edt, pseudo_header, pd, fdata, &cf->cinfo);
2499   epan_dissect_fill_in_columns(edt);
2500
2501   /* Write out the information in that tree. */
2502   proto_tree_write_csv(edt, fh);
2503
2504   epan_dissect_free(edt);
2505
2506   return !ferror(fh);
2507 }
2508
2509 cf_print_status_t
2510 cf_write_csv_packets(capture_file *cf, print_args_t *print_args)
2511 {
2512   FILE        *fh;
2513   psp_return_t ret;
2514
2515   fh = ws_fopen(print_args->file, "w");
2516   if (fh == NULL)
2517     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2518
2519   write_csv_preamble(fh);
2520   if (ferror(fh)) {
2521     fclose(fh);
2522     return CF_PRINT_WRITE_ERROR;
2523   }
2524
2525   /* Iterate through the list of packets, printing the packets we were
2526      told to print. */
2527   ret = process_specified_packets(cf, &print_args->range, "Writing CSV",
2528                                   "selected packets", TRUE,
2529                                   write_csv_packet, fh);
2530
2531   switch (ret) {
2532
2533   case PSP_FINISHED:
2534     /* Completed successfully. */
2535     break;
2536
2537   case PSP_STOPPED:
2538     /* Well, the user decided to abort the printing. */
2539     break;
2540
2541   case PSP_FAILED:
2542     /* Error while printing. */
2543     fclose(fh);
2544     return CF_PRINT_WRITE_ERROR;
2545   }
2546
2547   write_csv_finale(fh);
2548   if (ferror(fh)) {
2549     fclose(fh);
2550     return CF_PRINT_WRITE_ERROR;
2551   }
2552
2553   /* XXX - check for an error */
2554   fclose(fh);
2555
2556   return CF_PRINT_OK;
2557 }
2558
2559 static gboolean
2560 write_carrays_packet(capture_file *cf _U_, frame_data *fdata,
2561                      union wtap_pseudo_header *pseudo_header _U_,
2562                      const guint8 *pd, void *argsp)
2563 {
2564   FILE *fh = argsp;
2565
2566   proto_tree_write_carrays(pd, fdata->cap_len, fdata->num, fh);
2567   return !ferror(fh);
2568 }
2569
2570 cf_print_status_t
2571 cf_write_carrays_packets(capture_file *cf, print_args_t *print_args)
2572 {
2573   FILE        *fh;
2574   psp_return_t ret;
2575
2576   fh = ws_fopen(print_args->file, "w");
2577
2578   if (fh == NULL)
2579     return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
2580
2581   write_carrays_preamble(fh);
2582
2583   if (ferror(fh)) {
2584     fclose(fh);
2585     return CF_PRINT_WRITE_ERROR;
2586   }
2587
2588   /* Iterate through the list of packets, printing the packets we were
2589      told to print. */
2590   ret = process_specified_packets(cf, &print_args->range,
2591                                   "Writing C Arrays",
2592                                   "selected packets", TRUE,
2593                                   write_carrays_packet, fh);
2594   switch (ret) {
2595   case PSP_FINISHED:
2596     /* Completed successfully. */
2597     break;
2598   case PSP_STOPPED:
2599     /* Well, the user decided to abort the printing. */
2600     break;
2601   case PSP_FAILED:
2602     /* Error while printing. */
2603     fclose(fh);
2604     return CF_PRINT_WRITE_ERROR;
2605   }
2606
2607   write_carrays_finale(fh);
2608
2609   if (ferror(fh)) {
2610     fclose(fh);
2611     return CF_PRINT_WRITE_ERROR;
2612   }
2613
2614   fclose(fh);
2615   return CF_PRINT_OK;
2616 }
2617
2618 /* Scan through the packet list and change all columns that use the
2619    "command-line-specified" time stamp format to use the current
2620    value of that format. */
2621 void
2622 cf_change_time_formats(capture_file *cf)
2623 {
2624   frame_data *fdata;
2625   progdlg_t  *progbar = NULL;
2626   gboolean    stop_flag;
2627   int         count;
2628   int         row;
2629   int         i;
2630   float       progbar_val;
2631   GTimeVal    start_time;
2632   gchar       status_str[100];
2633   int         progbar_nextstep;
2634   int         progbar_quantum;
2635   gboolean    sorted_by_frame_column;
2636
2637
2638   /* adjust timestamp precision if auto is selected */
2639   cf_timestamp_auto_precision(cf);
2640
2641   /* Are there any columns with time stamps in the "command-line-specified"
2642      format?
2643
2644      XXX - we have to force the "column is writable" flag on, as it
2645      might be off from the last frame that was dissected. */
2646   col_set_writable(&cf->cinfo, TRUE);
2647   if (!check_col(&cf->cinfo, COL_CLS_TIME) &&
2648       !check_col(&cf->cinfo, COL_ABS_TIME) &&
2649       !check_col(&cf->cinfo, COL_ABS_DATE_TIME) &&
2650       !check_col(&cf->cinfo, COL_REL_TIME) &&
2651       !check_col(&cf->cinfo, COL_DELTA_TIME) &&
2652       !check_col(&cf->cinfo, COL_DELTA_TIME_DIS)) {
2653     /* No, there aren't any columns in that format, so we have no work
2654        to do. */
2655     return;
2656   }
2657
2658   /* Freeze the packet list while we redo it, so we don't get any
2659      screen updates while it happens. */
2660 #ifdef NEW_PACKET_LIST
2661   new_packet_list_freeze();
2662 #else
2663   packet_list_freeze();
2664 #endif
2665
2666   /* Update the progress bar when it gets to this value. */
2667   progbar_nextstep = 0;
2668   /* When we reach the value that triggers a progress bar update,
2669      bump that value by this amount. */
2670   progbar_quantum = cf->count/N_PROGBAR_UPDATES;
2671   /* Count of packets at which we've looked. */
2672   count = 0;
2673   /* Progress so far. */
2674   progbar_val = 0.0f;
2675
2676   /*  If the rows are currently sorted by the frame column then we know
2677    *  the row number of each packet: it's the row number of the previously
2678    *  displayed packet + 1.
2679    *
2680    *  Otherwise, if the display is sorted by a different column then we have
2681    *  to use the O(N) packet_list_find_row_from_data() (thus making the job
2682    *  of changing the time display format O(N**2)).
2683    *
2684    *  (XXX - In fact it's still O(N**2) because gtk_clist_set_text() takes
2685    *  the row number and walks that many elements down the clist to find
2686    *  the appropriate element.)
2687    */
2688   sorted_by_frame_column = FALSE;
2689   for (i = 0; i < cf->cinfo.num_cols; i++) {
2690     if (cf->cinfo.col_fmt[i] == COL_NUMBER)
2691     {
2692 #ifndef NEW_PACKET_LIST
2693       sorted_by_frame_column = (i == packet_list_get_sort_column());
2694 #endif
2695       break;
2696     }
2697   }
2698
2699   stop_flag = FALSE;
2700   g_get_current_time(&start_time);
2701
2702   /* Iterate through the list of packets, checking whether the packet
2703      is in a row of the summary list and, if so, whether there are
2704      any columns that show the time in the "command-line-specified"
2705      format and, if so, update that row. */
2706   for (fdata = cf->plist, row = -1; fdata != NULL; fdata = fdata->next) {
2707     /* Create the progress bar if necessary.
2708        We check on every iteration of the loop, so that it takes no
2709        longer than the standard time to create it (otherwise, for a
2710        large file, we might take considerably longer than that standard
2711        time in order to get to the next progress bar step). */
2712     if (progbar == NULL)
2713       progbar = delayed_create_progress_dlg("Changing", "time display",
2714         TRUE, &stop_flag, &start_time, progbar_val);
2715
2716     /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
2717        when we update it, we have to run the GTK+ main loop to get it
2718        to repaint what's pending, and doing so may involve an "ioctl()"
2719        to see if there's any pending input from an X server, and doing
2720        that for every packet can be costly, especially on a big file. */
2721     if (count >= progbar_nextstep) {
2722       /* let's not divide by zero. I should never be started
2723        * with count == 0, so let's assert that
2724        */
2725       g_assert(cf->count > 0);
2726
2727       progbar_val = (gfloat) count / cf->count;
2728
2729       if (progbar != NULL) {
2730         g_snprintf(status_str, sizeof(status_str),
2731                    "%4u of %u packets", count, cf->count);
2732         update_progress_dlg(progbar, progbar_val, status_str);
2733       }
2734
2735       progbar_nextstep += progbar_quantum;
2736     }
2737
2738     if (stop_flag) {
2739       /* Well, the user decided to abort the redisplay.  Just stop.
2740
2741          XXX - this leaves the time field in the old format in
2742          frames we haven't yet processed.  So it goes; should we
2743          simply not offer them the option of stopping? */
2744       break;
2745     }
2746
2747     count++;
2748
2749     /* Find what row this packet is in. */
2750     if (!sorted_by_frame_column) {
2751       /* This function is O(N), so we try to avoid using it... */
2752 #ifdef NEW_PACKET_LIST
2753           row = new_packet_list_find_row_from_data(fdata, FALSE);
2754 #else
2755       row = packet_list_find_row_from_data(fdata);
2756 #endif
2757     } else {
2758       /* ...which we do by maintaining a count of packets that are
2759          being displayed (i.e., that have passed the display filter),
2760          and using the current value of that count as the row number
2761          (which is why we can only do it when the display is sorted
2762          by the frame number). */
2763       if (fdata->flags.passed_dfilter)
2764         row++;
2765       else
2766         continue;
2767     }
2768
2769     if (row != -1) {
2770       /* This packet is in the summary list, on row "row". */
2771
2772       for (i = 0; i < cf->cinfo.num_cols; i++) {
2773         if (col_has_time_fmt(&cf->cinfo, i)) {
2774           /* This is one of the columns that shows the time in
2775              "command-line-specified" format; update it. */
2776           cf->cinfo.col_buf[i][0] = '\0';
2777           col_set_fmt_time(fdata, &cf->cinfo, cf->cinfo.col_fmt[i], i);
2778 #ifdef NEW_PACKET_LIST
2779 #else
2780           packet_list_set_text(row, i, cf->cinfo.col_data[i]);
2781 #endif
2782         }
2783       }
2784     }
2785   }
2786
2787   /* We're done redisplaying the packets; destroy the progress bar if it
2788      was created. */
2789   if (progbar != NULL)
2790     destroy_progress_dlg(progbar);
2791
2792   /* Set the column widths of those columns that show the time in
2793      "command-line-specified" format. */
2794   for (i = 0; i < cf->cinfo.num_cols; i++) {
2795     if (col_has_time_fmt(&cf->cinfo, i)) {
2796 #ifndef NEW_PACKET_LIST
2797       packet_list_set_time_width(cf->cinfo.col_fmt[i], i);
2798 #endif
2799     }
2800   }
2801
2802   /* Unfreeze the packet list. */
2803 #ifdef NEW_PACKET_LIST
2804   new_packet_list_thaw();
2805 #else
2806   packet_list_thaw();
2807 #endif
2808 }
2809
2810 typedef struct {
2811         const char      *string;
2812         size_t          string_len;
2813         capture_file    *cf;
2814         gboolean        frame_matched;
2815 } match_data;
2816
2817 gboolean
2818 cf_find_packet_protocol_tree(capture_file *cf, const char *string)
2819 {
2820   match_data            mdata;
2821
2822   mdata.string = string;
2823   mdata.string_len = strlen(string);
2824   return find_packet(cf, match_protocol_tree, &mdata);
2825 }
2826
2827 static gboolean
2828 match_protocol_tree(capture_file *cf, frame_data *fdata, void *criterion)
2829 {
2830   match_data            *mdata = criterion;
2831   epan_dissect_t        *edt;
2832
2833   /* Construct the protocol tree, including the displayed text */
2834   edt = epan_dissect_new(TRUE, TRUE);
2835   /* We don't need the column information */
2836   epan_dissect_run(edt, &cf->pseudo_header, cf->pd, fdata, NULL);
2837
2838   /* Iterate through all the nodes, seeing if they have text that matches. */
2839   mdata->cf = cf;
2840   mdata->frame_matched = FALSE;
2841   proto_tree_children_foreach(edt->tree, match_subtree_text, mdata);
2842   epan_dissect_free(edt);
2843   return mdata->frame_matched;
2844 }
2845
2846 static void
2847 match_subtree_text(proto_node *node, gpointer data)
2848 {
2849   match_data    *mdata = (match_data*) data;
2850   const gchar   *string = mdata->string;
2851   size_t        string_len = mdata->string_len;
2852   capture_file  *cf = mdata->cf;
2853   field_info    *fi = PITEM_FINFO(node);
2854   gchar         label_str[ITEM_LABEL_LENGTH];
2855   gchar         *label_ptr;
2856   size_t        label_len;
2857   guint32       i;
2858   guint8        c_char;
2859   size_t        c_match = 0;
2860
2861   if (mdata->frame_matched) {
2862     /* We already had a match; don't bother doing any more work. */
2863     return;
2864   }
2865
2866   /* Don't match invisible entries. */
2867   if (PROTO_ITEM_IS_HIDDEN(node))
2868     return;
2869
2870   /* was a free format label produced? */
2871   if (fi->rep) {
2872     label_ptr = fi->rep->representation;
2873   } else {
2874     /* no, make a generic label */
2875     label_ptr = label_str;
2876     proto_item_fill_label(fi, label_str);
2877   }
2878
2879   /* Does that label match? */
2880   label_len = strlen(label_ptr);
2881   for (i = 0; i < label_len; i++) {
2882     c_char = label_ptr[i];
2883     if (cf->case_type)
2884       c_char = toupper(c_char);
2885     if (c_char == string[c_match]) {
2886       c_match++;
2887       if (c_match == string_len) {
2888         /* No need to look further; we have a match */
2889         mdata->frame_matched = TRUE;
2890         return;
2891       }
2892     } else
2893       c_match = 0;
2894   }
2895
2896   /* Recurse into the subtree, if it exists */
2897   if (node->first_child != NULL)
2898     proto_tree_children_foreach(node, match_subtree_text, mdata);
2899 }
2900
2901 gboolean
2902 cf_find_packet_summary_line(capture_file *cf, const char *string)
2903 {
2904   match_data            mdata;
2905
2906   mdata.string = string;
2907   mdata.string_len = strlen(string);
2908   return find_packet(cf, match_summary_line, &mdata);
2909 }
2910
2911 static gboolean
2912 match_summary_line(capture_file *cf, frame_data *fdata, void *criterion)
2913 {
2914   match_data            *mdata = criterion;
2915   const gchar           *string = mdata->string;
2916   size_t                string_len = mdata->string_len;
2917   epan_dissect_t        *edt;
2918   const char            *info_column;
2919   size_t                info_column_len;
2920   gboolean              frame_matched = FALSE;
2921   gint                  colx;
2922   guint32               i;
2923   guint8                c_char;
2924   size_t                c_match = 0;
2925
2926   /* Don't bother constructing the protocol tree */
2927   edt = epan_dissect_new(FALSE, FALSE);
2928   /* Get the column information */
2929   epan_dissect_run(edt, &cf->pseudo_header, cf->pd, fdata, &cf->cinfo);
2930
2931   /* Find the Info column */
2932   for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
2933     if (cf->cinfo.fmt_matx[colx][COL_INFO]) {
2934       /* Found it.  See if we match. */
2935       info_column = edt->pi.cinfo->col_data[colx];
2936       info_column_len = strlen(info_column);
2937       for (i = 0; i < info_column_len; i++) {
2938         c_char = info_column[i];
2939         if (cf->case_type)
2940           c_char = toupper(c_char);
2941         if (c_char == string[c_match]) {
2942           c_match++;
2943           if (c_match == string_len) {
2944             frame_matched = TRUE;
2945             break;
2946           }
2947         } else
2948           c_match = 0;
2949       }
2950       break;
2951     }
2952   }
2953   epan_dissect_free(edt);
2954   return frame_matched;
2955 }
2956
2957 typedef struct {
2958         const guint8 *data;
2959         size_t data_len;
2960 } cbs_t;        /* "Counted byte string" */
2961
2962 gboolean
2963 cf_find_packet_data(capture_file *cf, const guint8 *string, size_t string_size)
2964 {
2965   cbs_t info;
2966
2967   info.data = string;
2968   info.data_len = string_size;
2969
2970   /* String or hex search? */
2971   if (cf->string) {
2972     /* String search - what type of string? */
2973     switch (cf->scs_type) {
2974
2975     case SCS_ASCII_AND_UNICODE:
2976       return find_packet(cf, match_ascii_and_unicode, &info);
2977
2978     case SCS_ASCII:
2979       return find_packet(cf, match_ascii, &info);
2980
2981     case SCS_UNICODE:
2982       return find_packet(cf, match_unicode, &info);
2983
2984     default:
2985       g_assert_not_reached();
2986       return FALSE;
2987     }
2988   } else
2989     return find_packet(cf, match_binary, &info);
2990 }
2991
2992 static gboolean
2993 match_ascii_and_unicode(capture_file *cf, frame_data *fdata, void *criterion)
2994 {
2995   cbs_t         *info = criterion;
2996   const guint8  *ascii_text = info->data;
2997   size_t        textlen = info->data_len;
2998   gboolean      frame_matched;
2999   guint32       buf_len;
3000   guint32       i;
3001   guint8        c_char;
3002   size_t        c_match = 0;
3003
3004   frame_matched = FALSE;
3005   buf_len = fdata->pkt_len;
3006   for (i = 0; i < buf_len; i++) {
3007     c_char = cf->pd[i];
3008     if (cf->case_type)
3009       c_char = toupper(c_char);
3010     if (c_char != 0) {
3011       if (c_char == ascii_text[c_match]) {
3012         c_match++;
3013         if (c_match == textlen) {
3014           frame_matched = TRUE;
3015           cf->search_pos = i; /* Save the position of the last character
3016                                for highlighting the field. */
3017           break;
3018         }
3019       } else
3020         c_match = 0;
3021     }
3022   }
3023   return frame_matched;
3024 }
3025
3026 static gboolean
3027 match_ascii(capture_file *cf, frame_data *fdata, void *criterion)
3028 {
3029   cbs_t         *info = criterion;
3030   const guint8  *ascii_text = info->data;
3031   size_t        textlen = info->data_len;
3032   gboolean      frame_matched;
3033   guint32       buf_len;
3034   guint32       i;
3035   guint8        c_char;
3036   size_t        c_match = 0;
3037
3038   frame_matched = FALSE;
3039   buf_len = fdata->pkt_len;
3040   for (i = 0; i < buf_len; i++) {
3041     c_char = cf->pd[i];
3042     if (cf->case_type)
3043       c_char = toupper(c_char);
3044     if (c_char == ascii_text[c_match]) {
3045       c_match++;
3046       if (c_match == textlen) {
3047         frame_matched = TRUE;
3048         cf->search_pos = i; /* Save the position of the last character
3049                                for highlighting the field. */
3050         break;
3051       }
3052     } else
3053       c_match = 0;
3054   }
3055   return frame_matched;
3056 }
3057
3058 static gboolean
3059 match_unicode(capture_file *cf, frame_data *fdata, void *criterion)
3060 {
3061   cbs_t         *info = criterion;
3062   const guint8  *ascii_text = info->data;
3063   size_t        textlen = info->data_len;
3064   gboolean      frame_matched;
3065   guint32       buf_len;
3066   guint32       i;
3067   guint8        c_char;
3068   size_t        c_match = 0;
3069
3070   frame_matched = FALSE;
3071   buf_len = fdata->pkt_len;
3072   for (i = 0; i < buf_len; i++) {
3073     c_char = cf->pd[i];
3074     if (cf->case_type)
3075       c_char = toupper(c_char);
3076     if (c_char == ascii_text[c_match]) {
3077       c_match++;
3078       i++;
3079       if (c_match == textlen) {
3080         frame_matched = TRUE;
3081         cf->search_pos = i; /* Save the position of the last character
3082                                for highlighting the field. */
3083         break;
3084       }
3085     } else
3086       c_match = 0;
3087   }
3088   return frame_matched;
3089 }
3090
3091 static gboolean
3092 match_binary(capture_file *cf, frame_data *fdata, void *criterion)
3093 {
3094   cbs_t         *info = criterion;
3095   const guint8  *binary_data = info->data;
3096   size_t        datalen = info->data_len;
3097   gboolean      frame_matched;
3098   guint32       buf_len;
3099   guint32       i;
3100   size_t        c_match = 0;
3101
3102   frame_matched = FALSE;
3103   buf_len = fdata->pkt_len;
3104   for (i = 0; i < buf_len; i++) {
3105     if (cf->pd[i] == binary_data[c_match]) {
3106       c_match++;
3107       if (c_match == datalen) {
3108         frame_matched = TRUE;
3109         cf->search_pos = i; /* Save the position of the last character
3110                                for highlighting the field. */
3111         break;
3112       }
3113     } else
3114       c_match = 0;
3115   }
3116   return frame_matched;
3117 }
3118
3119 gboolean
3120 cf_find_packet_dfilter(capture_file *cf, dfilter_t *sfcode)
3121 {
3122   return find_packet(cf, match_dfilter, sfcode);
3123 }
3124
3125 static gboolean
3126 match_dfilter(capture_file *cf, frame_data *fdata, void *criterion)
3127 {
3128   dfilter_t             *sfcode = criterion;
3129   epan_dissect_t        *edt;
3130   gboolean              frame_matched;
3131
3132   edt = epan_dissect_new(TRUE, FALSE);
3133   epan_dissect_prime_dfilter(edt, sfcode);
3134   epan_dissect_run(edt, &cf->pseudo_header, cf->pd, fdata, NULL);
3135   frame_matched = dfilter_apply_edt(sfcode, edt);
3136   epan_dissect_free(edt);
3137   return frame_matched;
3138 }
3139
3140 static gboolean
3141 find_packet(capture_file *cf,
3142             gboolean (*match_function)(capture_file *, frame_data *, void *),
3143             void *criterion)
3144 {
3145   frame_data *start_fd;
3146   frame_data *fdata;
3147   frame_data *new_fd = NULL;
3148   progdlg_t  *progbar = NULL;
3149   gboolean    stop_flag;
3150   int         count;
3151   int         err;
3152   gchar      *err_info;
3153   int         row;
3154   float       progbar_val;
3155   GTimeVal    start_time;
3156   gchar       status_str[100];
3157   int         progbar_nextstep;
3158   int         progbar_quantum;
3159   char       *title;
3160
3161   start_fd = cf->current_frame;
3162   if (start_fd != NULL)  {
3163     /* Iterate through the list of packets, starting at the packet we've
3164        picked, calling a routine to run the filter on the packet, see if
3165        it matches, and stop if so.  */
3166     count = 0;
3167     fdata = start_fd;
3168
3169     /* Update the progress bar when it gets to this value. */
3170     progbar_nextstep = 0;
3171     /* When we reach the value that triggers a progress bar update,
3172        bump that value by this amount. */
3173     progbar_quantum = cf->count/N_PROGBAR_UPDATES;
3174     /* Progress so far. */
3175     progbar_val = 0.0f;
3176
3177     stop_flag = FALSE;
3178     g_get_current_time(&start_time);
3179
3180     fdata = start_fd;
3181     title = cf->sfilter?cf->sfilter:"";
3182     for (;;) {
3183       /* Create the progress bar if necessary.
3184          We check on every iteration of the loop, so that it takes no
3185          longer than the standard time to create it (otherwise, for a
3186          large file, we might take considerably longer than that standard
3187          time in order to get to the next progress bar step). */
3188       if (progbar == NULL)
3189          progbar = delayed_create_progress_dlg("Searching", title,
3190            FALSE, &stop_flag, &start_time, progbar_val);
3191
3192       /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
3193          when we update it, we have to run the GTK+ main loop to get it
3194          to repaint what's pending, and doing so may involve an "ioctl()"
3195          to see if there's any pending input from an X server, and doing
3196          that for every packet can be costly, especially on a big file. */
3197       if (count >= progbar_nextstep) {
3198         /* let's not divide by zero. I should never be started
3199          * with count == 0, so let's assert that
3200          */
3201         g_assert(cf->count > 0);
3202
3203         progbar_val = (gfloat) count / cf->count;
3204
3205         if (progbar != NULL) {
3206           g_snprintf(status_str, sizeof(status_str),
3207                      "%4u of %u packets", count, cf->count);
3208           update_progress_dlg(progbar, progbar_val, status_str);
3209         }
3210
3211         progbar_nextstep += progbar_quantum;
3212       }
3213
3214       if (stop_flag) {
3215         /* Well, the user decided to abort the search.  Go back to the
3216            frame where we started. */
3217         new_fd = start_fd;
3218         break;
3219       }
3220
3221       /* Go past the current frame. */
3222       if (cf->sbackward) {
3223         /* Go on to the previous frame. */
3224         fdata = fdata->prev;
3225         if (fdata == NULL) {
3226           /*
3227            * XXX - other apps have a bit more of a detailed message
3228            * for this, and instead of offering "OK" and "Cancel",
3229            * they offer things such as "Continue" and "Cancel";
3230            * we need an API for popping up alert boxes with
3231            * {Verb} and "Cancel".
3232            */
3233
3234           if (prefs.gui_find_wrap)
3235           {
3236               simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3237                             "%sBeginning of capture exceeded!%s\n\n"
3238                             "Search is continued from the end of the capture.",
3239                             simple_dialog_primary_start(), simple_dialog_primary_end());
3240               fdata = cf->plist_end;    /* wrap around */
3241           }
3242           else
3243           {
3244               simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3245                             "%sBeginning of capture exceeded!%s\n\n"
3246                             "Try searching forwards.",
3247                             simple_dialog_primary_start(), simple_dialog_primary_end());
3248               fdata = start_fd;        /* stay on previous packet */
3249           }
3250         }
3251       } else {
3252         /* Go on to the next frame. */
3253         fdata = fdata->next;
3254         if (fdata == NULL) {
3255           if (prefs.gui_find_wrap)
3256           {
3257               simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3258                             "%sEnd of capture exceeded!%s\n\n"
3259                             "Search is continued from the start of the capture.",
3260                             simple_dialog_primary_start(), simple_dialog_primary_end());
3261               fdata = cf->plist;        /* wrap around */
3262           }
3263           else
3264           {
3265               simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3266                             "%sEnd of capture exceeded!%s\n\n"
3267                             "Try searching backwards.",
3268                             simple_dialog_primary_start(), simple_dialog_primary_end());
3269               fdata = start_fd;     /* stay on previous packet */
3270           }
3271         }
3272       }
3273
3274       count++;
3275
3276       /* Is this packet in the display? */
3277       if (fdata->flags.passed_dfilter) {
3278         /* Yes.  Load its data. */
3279         if (!wtap_seek_read(cf->wth, fdata->file_off, &cf->pseudo_header,
3280                         cf->pd, fdata->cap_len, &err, &err_info)) {
3281           /* Read error.  Report the error, and go back to the frame
3282              where we started. */
3283           simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3284                         cf_read_error_message(err, err_info), cf->filename);
3285           new_fd = start_fd;
3286           break;
3287         }
3288
3289         /* Does it match the search criterion? */
3290         if ((*match_function)(cf, fdata, criterion)) {
3291           new_fd = fdata;
3292           break;        /* found it! */
3293         }
3294       }
3295
3296       if (fdata == start_fd) {
3297         /* We're back to the frame we were on originally, and that frame
3298            doesn't match the search filter.  The search failed. */
3299         break;
3300       }
3301     }
3302
3303     /* We're done scanning the packets; destroy the progress bar if it
3304        was created. */
3305     if (progbar != NULL)
3306       destroy_progress_dlg(progbar);
3307   }
3308
3309   if (new_fd != NULL) {
3310 #ifdef NEW_PACKET_LIST
3311           /* Find and select */
3312           row = new_packet_list_find_row_from_data(fdata, TRUE);
3313 #else
3314     /* We found a frame.  Find what row it's in. */
3315     row = packet_list_find_row_from_data(new_fd);
3316 #endif /* NEW_PACKET_LIST */
3317     if (row == -1) {
3318         /* We didn't find a row even though we know that a frame
3319          * exists that satifies the search criteria. This means that the
3320          * frame isn't being displayed currently so we can't select it. */
3321         simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
3322                       "%sEnd of capture exceeded!%s\n\n"
3323                       "The capture file is probably not fully loaded.",
3324                       simple_dialog_primary_start(), simple_dialog_primary_end());
3325         return FALSE;
3326     }
3327
3328 #ifndef NEW_PACKET_LIST
3329     /* Select that row, make it the focus row, and make it visible. */
3330     packet_list_set_selected_row(row);
3331 #endif /* NEW_PACKET_LIST */
3332     return TRUE;        /* success */
3333   } else
3334     return FALSE;       /* failure */
3335 }
3336
3337 gboolean
3338 cf_goto_frame(capture_file *cf, guint fnumber)
3339 {
3340   frame_data *fdata;
3341   int row;
3342
3343   for (fdata = cf->plist; fdata != NULL && fdata->num < fnumber; fdata = fdata->next)
3344     ;
3345
3346   if (fdata == NULL) {
3347     /* we didn't find a packet with that packet number */
3348     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3349                   "There is no packet with the packet number %u.", fnumber);
3350     return FALSE;       /* we failed to go to that packet */
3351   }
3352   if (!fdata->flags.passed_dfilter) {
3353     /* that packet currently isn't displayed */
3354     /* XXX - add it to the set of displayed packets? */
3355     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3356                   "The packet number %u isn't currently being displayed.", fnumber);
3357     return FALSE;       /* we failed to go to that packet */
3358   }
3359
3360 #ifdef NEW_PACKET_LIST
3361   row = new_packet_list_find_row_from_data(fdata, TRUE);
3362 #else
3363   /* We found that packet, and it's currently being displayed.
3364      Find what row it's in. */
3365   row = packet_list_find_row_from_data(fdata);
3366   g_assert(row != -1);
3367
3368   /* Select that row, make it the focus row, and make it visible. */
3369   packet_list_set_selected_row(row);
3370 #endif /* NEW_PACKET_LIST */
3371   return TRUE;  /* we got to that packet */
3372 }
3373
3374 gboolean
3375 cf_goto_top_frame(capture_file *cf)
3376 {
3377   frame_data *fdata;
3378   int row;
3379   frame_data *lowest_fdata = NULL;
3380
3381   for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
3382     if (fdata->flags.passed_dfilter) {
3383         lowest_fdata = fdata;
3384         break;
3385     }
3386   }
3387
3388   if (lowest_fdata == NULL) {
3389       return FALSE;
3390   }
3391
3392 #ifdef NEW_PACKET_LIST
3393   /* Find and select */
3394   row = new_packet_list_find_row_from_data(fdata, TRUE);
3395 #else
3396   /* We found that packet, and it's currently being displayed.
3397      Find what row it's in. */
3398   row = packet_list_find_row_from_data(lowest_fdata);
3399   g_assert(row != -1);
3400
3401   /* Select that row, make it the focus row, and make it visible. */
3402   packet_list_set_selected_row(row);
3403 #endif /* NEW_PACKET_LIST */
3404   return TRUE;  /* we got to that packet */
3405 }
3406
3407 gboolean
3408 cf_goto_bottom_frame(capture_file *cf)
3409 {
3410   frame_data *fdata;
3411   int row;
3412   frame_data *highest_fdata = NULL;
3413
3414   for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
3415     if (fdata->flags.passed_dfilter) {
3416         highest_fdata = fdata;
3417     }
3418   }
3419
3420   if (highest_fdata == NULL) {
3421       return FALSE;
3422   }
3423
3424 #ifdef NEW_PACKET_LIST
3425   /* Find and select */
3426   row = new_packet_list_find_row_from_data(fdata, TRUE);
3427 #else
3428   /* We found that packet, and it's currently being displayed.
3429      Find what row it's in. */
3430   row = packet_list_find_row_from_data(highest_fdata);
3431   g_assert(row != -1);
3432
3433   /* Select that row, make it the focus row, and make it visible. */
3434   packet_list_set_selected_row(row);
3435 #endif /* NEW_PACKET_LIST */
3436   return TRUE;  /* we got to that packet */
3437 }
3438
3439 /*
3440  * Go to frame specified by currently selected protocol tree item.
3441  */
3442 gboolean
3443 cf_goto_framenum(capture_file *cf)
3444 {
3445   header_field_info       *hfinfo;
3446   guint32                 framenum;
3447
3448   if (cf->finfo_selected) {
3449     hfinfo = cf->finfo_selected->hfinfo;
3450     g_assert(hfinfo);
3451     if (hfinfo->type == FT_FRAMENUM) {
3452       framenum = fvalue_get_uinteger(&cf->finfo_selected->value);
3453       if (framenum != 0)
3454         return cf_goto_frame(cf, framenum);
3455       }
3456   }
3457
3458   return FALSE;
3459 }
3460
3461 /* Select the packet on a given row. */
3462 void
3463 cf_select_packet(capture_file *cf, int row)
3464 {
3465   frame_data *fdata;
3466   int err;
3467   gchar *err_info;
3468
3469   /* Get the frame data struct pointer for this frame */
3470 #ifdef NEW_PACKET_LIST
3471   fdata = new_packet_list_get_row_data(row);
3472 #else
3473   fdata = (frame_data *)packet_list_get_row_data(row);
3474 #endif
3475
3476   if (fdata == NULL) {
3477     /* XXX - if a GtkCList's selection mode is GTK_SELECTION_BROWSE, when
3478        the first entry is added to it by "real_insert_row()", that row
3479        is selected (see "real_insert_row()", in "gtk/gtkclist.c", in both
3480        our version and the vanilla GTK+ version).
3481
3482        This means that a "select-row" signal is emitted; this causes
3483        "packet_list_select_cb()" to be called, which causes "cf_select_packet()"
3484        to be called.
3485
3486        "cf_select_packet()" fetches, above, the data associated with the
3487        row that was selected; however, as "gtk_clist_append()", which
3488        called "real_insert_row()", hasn't yet returned, we haven't yet
3489        associated any data with that row, so we get back a null pointer.
3490
3491        We can't assume that there's only one frame in the frame list,
3492        either, as we may be filtering the display.
3493
3494        We therefore assume that, if "row" is 0, i.e. the first row
3495        is being selected, and "cf->first_displayed" equals
3496        "cf->last_displayed", i.e. there's only one frame being
3497        displayed, that frame is the frame we want.
3498
3499        This means we have to set "cf->first_displayed" and
3500        "cf->last_displayed" before adding the row to the
3501        GtkCList; see the comment in "add_packet_to_packet_list()". */
3502
3503        if (row == 0 && cf->first_displayed == cf->last_displayed)
3504          fdata = cf->first_displayed;
3505   }
3506
3507   /* If fdata _still_ isn't set simply give up. */
3508   if (fdata == NULL) {
3509     return;
3510   }
3511
3512   /* Get the data in that frame. */
3513   if (!wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
3514                        cf->pd, fdata->cap_len, &err, &err_info)) {
3515     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3516                   cf_read_error_message(err, err_info), cf->filename);
3517     return;
3518   }
3519
3520   /* Record that this frame is the current frame. */
3521   cf->current_frame = fdata;
3522   cf->current_row = row;
3523
3524   /* Create the logical protocol tree. */
3525   if (cf->edt != NULL) {
3526     epan_dissect_free(cf->edt);
3527     cf->edt = NULL;
3528   }
3529   /* We don't need the columns here. */
3530   cf->edt = epan_dissect_new(TRUE, TRUE);
3531
3532   epan_dissect_run(cf->edt, &cf->pseudo_header, cf->pd, cf->current_frame,
3533           NULL);
3534
3535   dfilter_macro_build_ftv_cache(cf->edt->tree);
3536
3537   cf_callback_invoke(cf_cb_packet_selected, cf);
3538 }
3539
3540 /* Unselect the selected packet, if any. */
3541 void
3542 cf_unselect_packet(capture_file *cf)
3543 {
3544   /* Destroy the epan_dissect_t for the unselected packet. */
3545   if (cf->edt != NULL) {
3546     epan_dissect_free(cf->edt);
3547     cf->edt = NULL;
3548   }
3549
3550   /* No packet is selected. */
3551   cf->current_frame = NULL;
3552   cf->current_row = 0;
3553
3554   cf_callback_invoke(cf_cb_packet_unselected, cf);
3555
3556   /* No protocol tree means no selected field. */
3557   cf_unselect_field(cf);
3558 }
3559
3560 /* Unset the selected protocol tree field, if any. */
3561 void
3562 cf_unselect_field(capture_file *cf)
3563 {
3564   cf->finfo_selected = NULL;
3565
3566   cf_callback_invoke(cf_cb_field_unselected, cf);
3567 }
3568
3569 /*
3570  * Mark a particular frame.
3571  */
3572 void
3573 cf_mark_frame(capture_file *cf, frame_data *frame)
3574 {
3575   if (! frame->flags.marked) {
3576     frame->flags.marked = TRUE;
3577     if (cf->count > cf->marked_count)
3578       cf->marked_count++;
3579   }
3580 }
3581
3582 /*
3583  * Unmark a particular frame.
3584  */
3585 void
3586 cf_unmark_frame(capture_file *cf, frame_data *frame)
3587 {
3588   if (frame->flags.marked) {
3589     frame->flags.marked = FALSE;
3590     if (cf->marked_count > 0)
3591       cf->marked_count--;
3592   }
3593 }
3594
3595 typedef struct {
3596   wtap_dumper *pdh;
3597   const char  *fname;
3598 } save_callback_args_t;
3599
3600 /*
3601  * Save a capture to a file, in a particular format, saving either
3602  * all packets, all currently-displayed packets, or all marked packets.
3603  *
3604  * Returns TRUE if it succeeds, FALSE otherwise; if it fails, it pops
3605  * up a message box for the failure.
3606  */
3607 static gboolean
3608 save_packet(capture_file *cf _U_, frame_data *fdata,
3609             union wtap_pseudo_header *pseudo_header, const guint8 *pd,
3610             void *argsp)
3611 {
3612   save_callback_args_t *args = argsp;
3613   struct wtap_pkthdr hdr;
3614   int           err;
3615
3616   /* init the wtap header for saving */
3617   hdr.ts.secs    = fdata->abs_ts.secs;
3618   hdr.ts.nsecs   = fdata->abs_ts.nsecs;
3619   hdr.caplen     = fdata->cap_len;
3620   hdr.len        = fdata->pkt_len;
3621   hdr.pkt_encap  = fdata->lnk_t;
3622
3623   /* and save the packet */
3624   if (!wtap_dump(args->pdh, &hdr, pseudo_header, pd, &err)) {
3625     cf_write_failure_alert_box(args->fname, err);
3626     return FALSE;
3627   }
3628   return TRUE;
3629 }
3630
3631 /*
3632  * Can this capture file be saved in any format except by copying the raw data?
3633  */
3634 gboolean
3635 cf_can_save_as(capture_file *cf)
3636 {
3637   int ft;
3638
3639   for (ft = 0; ft < WTAP_NUM_FILE_TYPES; ft++) {
3640     /* To save a file with Wiretap, Wiretap has to handle that format,
3641        and its code to handle that format must be able to write a file
3642        with this file's encapsulation type. */
3643     if (wtap_dump_can_open(ft) && wtap_dump_can_write_encap(ft, cf->lnk_t)) {
3644       /* OK, we can write it out in this type. */
3645       return TRUE;
3646     }
3647   }
3648
3649   /* No, we couldn't save it in any format. */
3650   return FALSE;
3651 }
3652
3653 cf_status_t
3654 cf_save(capture_file *cf, const char *fname, packet_range_t *range, guint save_format, gboolean compressed)
3655 {
3656   gchar        *from_filename;
3657   int           err;
3658   gboolean      do_copy;
3659   wtap_dumper  *pdh;
3660   save_callback_args_t callback_args;
3661
3662   cf_callback_invoke(cf_cb_file_safe_started, (gpointer) fname);
3663
3664   /* don't write over an existing file. */
3665   /* this should've been already checked by our caller, just to be sure... */
3666   if (file_exists(fname)) {
3667     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3668       "%sCapture file: \"%s\" already exists!%s\n\n"
3669       "Please choose a different filename.",
3670       simple_dialog_primary_start(), fname, simple_dialog_primary_end());
3671     goto fail;
3672   }
3673
3674   packet_range_process_init(range);
3675
3676
3677   if (packet_range_process_all(range) && save_format == cf->cd_t) {
3678     /* We're not filtering packets, and we're saving it in the format
3679        it's already in, so we can just move or copy the raw data. */
3680
3681     if (cf->is_tempfile) {
3682       /* The file being saved is a temporary file from a live
3683          capture, so it doesn't need to stay around under that name;
3684          first, try renaming the capture buffer file to the new name. */
3685 #ifndef _WIN32
3686       if (ws_rename(cf->filename, fname) == 0) {
3687         /* That succeeded - there's no need to copy the source file. */
3688         from_filename = NULL;
3689         do_copy = FALSE;
3690       } else {
3691         if (errno == EXDEV) {
3692           /* They're on different file systems, so we have to copy the
3693              file. */
3694           do_copy = TRUE;
3695           from_filename = cf->filename;
3696         } else {
3697           /* The rename failed, but not because they're on different
3698              file systems - put up an error message.  (Or should we
3699              just punt and try to copy?  The only reason why I'd
3700              expect the rename to fail and the copy to succeed would
3701              be if we didn't have permission to remove the file from
3702              the temporary directory, and that might be fixable - but
3703              is it worth requiring the user to go off and fix it?) */
3704           simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3705                                 file_rename_error_message(errno), fname);
3706           goto fail;
3707         }
3708       }
3709 #else
3710       do_copy = TRUE;
3711       from_filename = cf->filename;
3712 #endif
3713     } else {
3714       /* It's a permanent file, so we should copy it, and not remove the
3715          original. */
3716       do_copy = TRUE;
3717       from_filename = cf->filename;
3718     }
3719
3720     if (do_copy) {
3721       /* Copy the file, if we haven't moved it. */
3722       if (!copy_file_binary_mode(from_filename, fname))
3723         goto fail;
3724     }
3725   } else {
3726     /* Either we're filtering packets, or we're saving in a different
3727        format; we can't do that by copying or moving the capture file,
3728        we have to do it by writing the packets out in Wiretap. */
3729     pdh = wtap_dump_open(fname, save_format, cf->lnk_t, cf->snap,
3730                 compressed, &err);
3731     if (pdh == NULL) {
3732       cf_open_failure_alert_box(fname, err, NULL, TRUE, save_format);
3733       goto fail;
3734     }
3735
3736     /* XXX - we let the user save a subset of the packets.
3737
3738        If we do that, should we make that file the current file?  If so,
3739        it means we can no longer get at the other packets.  What does
3740        NetMon do? */
3741
3742     /* Iterate through the list of packets, processing the packets we were
3743        told to process.
3744
3745        XXX - we've already called "packet_range_process_init(range)", but
3746        "process_specified_packets()" will do it again.  Fortunately,
3747        that's harmless in this case, as we haven't done anything to
3748        "range" since we initialized it. */
3749     callback_args.pdh = pdh;
3750     callback_args.fname = fname;
3751     switch (process_specified_packets(cf, range, "Saving", "selected packets",
3752                                       TRUE, save_packet, &callback_args)) {
3753
3754     case PSP_FINISHED:
3755       /* Completed successfully. */
3756       break;
3757
3758     case PSP_STOPPED:
3759       /* The user decided to abort the saving.
3760          XXX - remove the output file? */
3761       break;
3762
3763     case PSP_FAILED:
3764       /* Error while saving. */
3765       wtap_dump_close(pdh, &err);
3766       goto fail;
3767     }
3768
3769     if (!wtap_dump_close(pdh, &err)) {
3770       cf_close_failure_alert_box(fname, err);
3771       goto fail;
3772     }
3773   }
3774
3775   cf_callback_invoke(cf_cb_file_safe_finished, NULL);
3776
3777   if (packet_range_process_all(range)) {
3778     /* We saved the entire capture, not just some packets from it.
3779        Open and read the file we saved it to.
3780
3781        XXX - this is somewhat of a waste; we already have the
3782        packets, all this gets us is updated file type information
3783        (which we could just stuff into "cf"), and having the new
3784        file be the one we have opened and from which we're reading
3785        the data, and it means we have to spend time opening and
3786        reading the file, which could be a significant amount of
3787        time if the file is large. */
3788     cf->user_saved = TRUE;
3789
3790     if ((cf_open(cf, fname, FALSE, &err)) == CF_OK) {
3791       /* XXX - report errors if this fails?
3792          What should we return if it fails or is aborted? */
3793       switch (cf_read(cf)) {
3794
3795       case CF_READ_OK:
3796       case CF_READ_ERROR:
3797         /* Just because we got an error, that doesn't mean we were unable
3798            to read any of the file; we handle what we could get from the
3799            file. */
3800         break;
3801
3802       case CF_READ_ABORTED:
3803         /* The user bailed out of re-reading the capture file; the
3804            capture file has been closed - just return (without
3805            changing any menu settings; "cf_close()" set them
3806            correctly for the "no capture file open" state). */
3807         break;
3808       }
3809       cf_callback_invoke(cf_cb_file_safe_reload_finished, NULL);
3810     }
3811   }
3812   return CF_OK;
3813
3814 fail:
3815   cf_callback_invoke(cf_cb_file_safe_failed, NULL);
3816   return CF_ERROR;
3817 }
3818
3819 static void
3820 cf_open_failure_alert_box(const char *filename, int err, gchar *err_info,
3821                           gboolean for_writing, int file_type)
3822 {
3823   if (err < 0) {
3824     /* Wiretap error. */
3825     switch (err) {
3826
3827     case WTAP_ERR_NOT_REGULAR_FILE:
3828       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3829                     "The file \"%s\" is a \"special file\" or socket or other non-regular file.",
3830                     filename);
3831       break;
3832
3833     case WTAP_ERR_RANDOM_OPEN_PIPE:
3834       /* Seen only when opening a capture file for reading. */
3835       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3836                     "The file \"%s\" is a pipe or FIFO; Wireshark can't read pipe or FIFO files.",
3837                     filename);
3838       break;
3839
3840     case WTAP_ERR_FILE_UNKNOWN_FORMAT:
3841       /* Seen only when opening a capture file for reading. */
3842       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3843                     "The file \"%s\" isn't a capture file in a format Wireshark understands.",
3844                     filename);
3845       break;
3846
3847     case WTAP_ERR_UNSUPPORTED:
3848       /* Seen only when opening a capture file for reading. */
3849       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3850                     "The file \"%s\" isn't a capture file in a format Wireshark understands.\n"
3851                     "(%s)",
3852                     filename, err_info);
3853       g_free(err_info);
3854       break;
3855
3856     case WTAP_ERR_CANT_WRITE_TO_PIPE:
3857       /* Seen only when opening a capture file for writing. */
3858       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3859                     "The file \"%s\" is a pipe, and %s capture files can't be "
3860                     "written to a pipe.",
3861                     filename, wtap_file_type_string(file_type));
3862       break;
3863
3864     case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
3865       /* Seen only when opening a capture file for writing. */
3866       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3867                     "Wireshark doesn't support writing capture files in that format.");
3868       break;
3869
3870     case WTAP_ERR_UNSUPPORTED_ENCAP:
3871       if (for_writing) {
3872         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3873                       "Wireshark can't save this capture in that format.");
3874       } else {
3875         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3876                       "The file \"%s\" is a capture for a network type that Wireshark doesn't support.\n"
3877                       "(%s)",
3878                       filename, err_info);
3879         g_free(err_info);
3880       }
3881       break;
3882
3883     case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
3884       if (for_writing) {
3885         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3886                       "Wireshark can't save this capture in that format.");
3887       } else {
3888         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3889                       "The file \"%s\" is a capture for a network type that Wireshark doesn't support.",
3890                       filename);
3891       }
3892       break;
3893
3894     case WTAP_ERR_BAD_RECORD:
3895       /* Seen only when opening a capture file for reading. */
3896       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3897                     "The file \"%s\" appears to be damaged or corrupt.\n"
3898                     "(%s)",
3899                     filename, err_info);
3900       g_free(err_info);
3901       break;
3902
3903     case WTAP_ERR_CANT_OPEN:
3904       if (for_writing) {
3905         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3906                       "The file \"%s\" could not be created for some unknown reason.",
3907                       filename);
3908       } else {
3909         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3910                       "The file \"%s\" could not be opened for some unknown reason.",
3911                       filename);
3912       }
3913       break;
3914
3915     case WTAP_ERR_SHORT_READ:
3916       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3917                     "The file \"%s\" appears to have been cut short"
3918                     " in the middle of a packet or other data.",
3919                     filename);
3920       break;
3921
3922     case WTAP_ERR_SHORT_WRITE:
3923       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3924                     "A full header couldn't be written to the file \"%s\".",
3925                     filename);
3926       break;
3927
3928     case WTAP_ERR_COMPRESSION_NOT_SUPPORTED:
3929       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3930                     "Gzip compression not supported by this file type.");
3931       break;
3932
3933     default:
3934       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
3935                     "The file \"%s\" could not be %s: %s.",
3936                     filename,
3937                     for_writing ? "created" : "opened",
3938                     wtap_strerror(err));
3939       break;
3940     }
3941   } else {
3942     /* OS error. */
3943     open_failure_alert_box(filename, err, for_writing);
3944   }
3945 }
3946
3947 static const char *
3948 file_rename_error_message(int err)
3949 {
3950   const char *errmsg;
3951   static char errmsg_errno[1024+1];
3952
3953   switch (err) {
3954
3955   case ENOENT:
3956     errmsg = "The path to the file \"%s\" doesn't exist.";
3957     break;
3958
3959   case EACCES:
3960     errmsg = "You don't have permission to move the capture file to \"%s\".";
3961     break;
3962
3963   default:
3964     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
3965                     "The file \"%%s\" could not be moved: %s.",
3966                                 wtap_strerror(err));
3967     errmsg = errmsg_errno;
3968     break;
3969   }
3970   return errmsg;
3971 }
3972
3973 char *
3974 cf_read_error_message(int err, gchar *err_info)
3975 {
3976   static char errmsg_errno[1024+1];
3977
3978   switch (err) {
3979
3980   case WTAP_ERR_UNSUPPORTED_ENCAP:
3981     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
3982                "The file \"%%s\" has a packet with a network type that Wireshark doesn't support.\n(%s)",
3983                err_info);
3984     g_free(err_info);
3985     break;
3986
3987   case WTAP_ERR_BAD_RECORD:
3988     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
3989              "An error occurred while reading from the file \"%%s\": %s.\n(%s)",
3990              wtap_strerror(err), err_info);
3991     g_free(err_info);
3992     break;
3993
3994   default:
3995     g_snprintf(errmsg_errno, sizeof(errmsg_errno),
3996              "An error occurred while reading from the file \"%%s\": %s.",
3997              wtap_strerror(err));
3998     break;
3999   }
4000   return errmsg_errno;
4001 }
4002
4003 static void
4004 cf_write_failure_alert_box(const char *filename, int err)
4005 {
4006   if (err < 0) {
4007     /* Wiretap error. */
4008     simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4009                   "An error occurred while writing to the file \"%s\": %s.",
4010                   filename, wtap_strerror(err));
4011   } else {
4012     /* OS error. */
4013     write_failure_alert_box(filename, err);
4014   }
4015 }
4016
4017 /* Check for write errors - if the file is being written to an NFS server,
4018    a write error may not show up until the file is closed, as NFS clients
4019    might not send writes to the server until the "write()" call finishes,
4020    so that the write may fail on the server but the "write()" may succeed. */
4021 static void
4022 cf_close_failure_alert_box(const char *filename, int err)
4023 {
4024   if (err < 0) {
4025     /* Wiretap error. */
4026     switch (err) {
4027
4028     case WTAP_ERR_CANT_CLOSE:
4029       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4030                     "The file \"%s\" couldn't be closed for some unknown reason.",
4031                     filename);
4032       break;
4033
4034     case WTAP_ERR_SHORT_WRITE:
4035       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4036                     "Not all the packets could be written to the file \"%s\".",
4037                     filename);
4038       break;
4039
4040     default:
4041       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
4042                     "An error occurred while closing the file \"%s\": %s.",
4043                     filename, wtap_strerror(err));
4044       break;
4045     }
4046   } else {
4047     /* OS error.
4048        We assume that a close error from the OS is really a write error. */
4049     write_failure_alert_box(filename, err);
4050   }
4051 }
4052
4053 /* Reload the current capture file. */
4054 void
4055 cf_reload(capture_file *cf) {
4056   gchar *filename;
4057   gboolean is_tempfile;
4058   int err;
4059
4060   /* If the file could be opened, "cf_open()" calls "cf_close()"
4061      to get rid of state for the old capture file before filling in state
4062      for the new capture file.  "cf_close()" will remove the file if
4063      it's a temporary file; we don't want that to happen (for one thing,
4064      it'd prevent subsequent reopens from working).  Remember whether it's
4065      a temporary file, mark it as not being a temporary file, and then
4066      reopen it as the type of file it was.
4067
4068      Also, "cf_close()" will free "cf->filename", so we must make
4069      a copy of it first. */
4070   filename = g_strdup(cf->filename);
4071   is_tempfile = cf->is_tempfile;
4072   cf->is_tempfile = FALSE;
4073   if (cf_open(cf, filename, is_tempfile, &err) == CF_OK) {
4074     switch (cf_read(cf)) {
4075
4076     case CF_READ_OK:
4077     case CF_READ_ERROR:
4078       /* Just because we got an error, that doesn't mean we were unable
4079          to read any of the file; we handle what we could get from the
4080          file. */
4081       break;
4082
4083     case CF_READ_ABORTED:
4084       /* The user bailed out of re-reading the capture file; the
4085          capture file has been closed - just free the capture file name
4086          string and return (without changing the last containing
4087          directory). */
4088       g_free(filename);
4089       return;
4090     }
4091   } else {
4092     /* The open failed, so "cf->is_tempfile" wasn't set to "is_tempfile".
4093        Instead, the file was left open, so we should restore "cf->is_tempfile"
4094        ourselves.
4095
4096        XXX - change the menu?  Presumably "cf_open()" will do that;
4097        make sure it does! */
4098     cf->is_tempfile = is_tempfile;
4099   }
4100   /* "cf_open()" made a copy of the file name we handed it, so
4101      we should free up our copy. */
4102   g_free(filename);
4103 }