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