Add the ability to specify a filter to be used when reading the file to

the "Open File" dialog box (the "Open File" dialog box equivalent of the
"-R" flag).  Have "load_cap_file()" take the filter expression as an
argument, and make the global "rfilter" into a member of a
"capture_file" structure.

When reading a temporary capture file after a live capture, don't apply
any filter.

Move the code that pops up error boxes on file opens when reading a
capture file back to "load_cap_file()"; it also pops up error boxes if
the filter expression can't be parsed.

Don't enable "File/Save" or "File/Save As..." if an attempt to read a
capture file fails - if there was already an open capture file, it was
closed by "load_cap_file()", so we no longer have an open file to save.

svn path=/trunk/; revision=460
This commit is contained in:
Guy Harris 1999-08-10 07:16:47 +00:00
parent 7ec128ccb2
commit 8eb998e360
5 changed files with 146 additions and 120 deletions

View File

@ -1,7 +1,7 @@
/* capture.c /* capture.c
* Routines for packet capture windows * Routines for packet capture windows
* *
* $Id: capture.c,v 1.41 1999/08/05 11:12:14 deniel Exp $ * $Id: capture.c,v 1.42 1999/08/10 07:12:53 guy Exp $
* *
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org> * By Gerald Combs <gerald@zing.org>
@ -598,11 +598,8 @@ capture(void) {
if (pch) { if (pch) {
/* "pch" is non-NULL only if we successfully started a capture. /* "pch" is non-NULL only if we successfully started a capture.
If we haven't, there's no capture file to load. */ If we haven't, there's no capture file to load. */
err = load_cap_file(cf.save_file, &cf); err = load_cap_file(cf.save_file, NULL, &cf);
if (err != 0) { if (err == 0) {
simple_dialog(ESD_TYPE_WARN, NULL,
file_open_error_message(err, FALSE), cf.save_file);
} else {
set_menu_sensitivity("/File/Save", TRUE); set_menu_sensitivity("/File/Save", TRUE);
set_menu_sensitivity("/File/Save As...", FALSE); set_menu_sensitivity("/File/Save As...", FALSE);
} }

View File

@ -121,7 +121,7 @@ Reads packet data from I<file>.
=item -R =item -R
Causes the specified filter (which uses the syntax of display filters, Causes the specified filter (which uses the syntax of display filters,
rather than that of capture filters) to be applied, when a packet file rather than that of capture filters) to be applied, when a capture file
is read, to all packets read from the capture file; packets not matching is read, to all packets read from the capture file; packets not matching
the filter are discarded. the filter are discarded.
@ -169,7 +169,10 @@ Sets the default capture file name.
=item File:Open, File:Close, File:Reload =item File:Open, File:Close, File:Reload
Open, close, or reload a capture file. Open, close, or reload a capture file. The I<File:Open> dialog box
allows a filter to be specified; when the capture file is read, the
filter is applied to all packets read from the file, and packets not
matching the filter are discarded.
=item File:Print =item File:Print

View File

@ -1,6 +1,6 @@
/* ethereal.c /* ethereal.c
* *
* $Id: ethereal.c,v 1.78 1999/08/10 04:13:37 guy Exp $ * $Id: ethereal.c,v 1.79 1999/08/10 07:12:51 guy Exp $
* *
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org> * By Gerald Combs <gerald@zing.org>
@ -119,7 +119,6 @@ gchar comp_info_str[256];
gchar *ethereal_path = NULL; gchar *ethereal_path = NULL;
gchar *medium_font = MONO_MEDIUM_FONT; gchar *medium_font = MONO_MEDIUM_FONT;
gchar *bold_font = MONO_BOLD_FONT; gchar *bold_font = MONO_BOLD_FONT;
gchar *rfilter = NULL;
ts_type timestamp_type = RELATIVE; ts_type timestamp_type = RELATIVE;
@ -137,6 +136,7 @@ int quit_after_cap; /* Makes a "capture only mode". Implies -k */
static gint tree_selected_start=-1, tree_selected_len=-1; static gint tree_selected_start=-1, tree_selected_len=-1;
#define E_DFILTER_TE_KEY "display_filter_te" #define E_DFILTER_TE_KEY "display_filter_te"
#define E_RFILTER_TE_KEY "read_filter_te"
/* About Ethereal window */ /* About Ethereal window */
void void
@ -178,23 +178,25 @@ about_ethereal( GtkWidget *w, gpointer data ) {
void void
file_sel_ok_cb(GtkWidget *w, GtkFileSelection *fs) { file_sel_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
gchar *cf_name; gchar *cf_name;
GtkWidget *filter_te;
gchar *rfilter;
int err; int err;
cf_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION (fs))); cf_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION (fs)));
filter_te = gtk_object_get_data(GTK_OBJECT(w), E_RFILTER_TE_KEY);
rfilter = g_strdup(gtk_entry_get_text(GTK_ENTRY(filter_te)));
gtk_widget_hide(GTK_WIDGET (fs)); gtk_widget_hide(GTK_WIDGET (fs));
gtk_widget_destroy(GTK_WIDGET (fs)); gtk_widget_destroy(GTK_WIDGET (fs));
/* this depends upon load_cap_file removing the filename from /* this depends upon load_cap_file removing the filename from
* cf_name, leaving only the path to the directory. */ * cf_name, leaving only the path to the directory. */
if ((err = load_cap_file(cf_name, &cf)) == 0) if ((err = load_cap_file(cf_name, rfilter, &cf)) == 0)
chdir(cf_name); chdir(cf_name);
else {
simple_dialog(ESD_TYPE_WARN, NULL, file_open_error_message(err, FALSE),
cf_name);
}
g_free(cf_name); g_free(cf_name);
if (err == 0) {
set_menu_sensitivity("/File/Save", FALSE); set_menu_sensitivity("/File/Save", FALSE);
set_menu_sensitivity("/File/Save As...", TRUE); set_menu_sensitivity("/File/Save As...", TRUE);
}
} }
/* Update the progress bar */ /* Update the progress bar */
@ -385,6 +387,8 @@ match_selected_cb(GtkWidget *w, gpointer data)
/* Open a file */ /* Open a file */
void void
file_open_cmd_cb(GtkWidget *w, gpointer data) { file_open_cmd_cb(GtkWidget *w, gpointer data) {
GtkWidget *filter_hbox, *filter_bt, *filter_te;
file_sel = gtk_file_selection_new ("Ethereal: Open Capture File"); file_sel = gtk_file_selection_new ("Ethereal: Open Capture File");
/* Connect the ok_button to file_ok_sel_cb function and pass along the /* Connect the ok_button to file_ok_sel_cb function and pass along the
@ -397,6 +401,28 @@ file_open_cmd_cb(GtkWidget *w, gpointer data) {
gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_sel)->ok_button), gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_sel)->ok_button),
E_DFILTER_TE_KEY, gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY)); E_DFILTER_TE_KEY, gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY));
filter_hbox = gtk_hbox_new(FALSE, 1);
gtk_container_border_width(GTK_CONTAINER(filter_hbox), 0);
gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION(file_sel)->action_area),
filter_hbox, FALSE, FALSE, 0);
gtk_widget_show(filter_hbox);
filter_bt = gtk_button_new_with_label("Filter:");
gtk_signal_connect(GTK_OBJECT(filter_bt), "clicked",
GTK_SIGNAL_FUNC(prefs_cb), (gpointer) E_PR_PG_FILTER);
gtk_box_pack_start(GTK_BOX(filter_hbox), filter_bt, FALSE, TRUE, 0);
gtk_widget_show(filter_bt);
filter_te = gtk_entry_new();
gtk_object_set_data(GTK_OBJECT(filter_bt), E_FILT_TE_PTR_KEY, filter_te);
gtk_box_pack_start(GTK_BOX(filter_hbox), filter_te, TRUE, TRUE, 3);
if (cf.rfilter != NULL)
gtk_entry_set_text(GTK_ENTRY(filter_te), cf.rfilter);
gtk_widget_show(filter_te);
gtk_object_set_data(GTK_OBJECT(GTK_FILE_SELECTION(file_sel)->ok_button),
E_RFILTER_TE_KEY, filter_te);
/* Connect the cancel_button to destroy the widget */ /* Connect the cancel_button to destroy the widget */
gtk_signal_connect_object(GTK_OBJECT (GTK_FILE_SELECTION gtk_signal_connect_object(GTK_OBJECT (GTK_FILE_SELECTION
(file_sel)->cancel_button), "clicked", (GtkSignalFunc) (file_sel)->cancel_button), "clicked", (GtkSignalFunc)
@ -471,14 +497,11 @@ file_save_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
g_free(cf.save_file); g_free(cf.save_file);
cf.save_file = g_strdup(cf_name); cf.save_file = g_strdup(cf_name);
cf.user_saved = 1; cf.user_saved = 1;
err = load_cap_file(cf_name, &cf); err = load_cap_file(cf_name, g_strdup(cf.rfilter), &cf);
if (err != 0) { if (err == 0) {
simple_dialog(ESD_TYPE_WARN, NULL,
file_open_error_message(err, FALSE), cf_name);
}
set_menu_sensitivity("/File/Save", FALSE); set_menu_sensitivity("/File/Save", FALSE);
set_menu_sensitivity("/File/Save As...", TRUE); set_menu_sensitivity("/File/Save As...", TRUE);
}
} }
static void static void
@ -495,32 +518,25 @@ file_save_as_ok_cb(GtkWidget *w, GtkFileSelection *fs) {
g_free(cf.save_file); g_free(cf.save_file);
cf.save_file = g_strdup(cf_name); cf.save_file = g_strdup(cf_name);
cf.user_saved = 1; cf.user_saved = 1;
err = load_cap_file(cf_name, &cf); err = load_cap_file(cf_name, g_strdup(cf.rfilter), &cf);
if (err != 0) { if (err == 0) {
simple_dialog(ESD_TYPE_WARN, NULL,
file_open_error_message(err, FALSE), cf_name);
}
set_menu_sensitivity("/File/Save", FALSE); set_menu_sensitivity("/File/Save", FALSE);
set_menu_sensitivity("/File/Save As...", TRUE); set_menu_sensitivity("/File/Save As...", TRUE);
}
} }
/* Reload a file using the current display filter */ /* Reload a file using the current read and display filters */
void void
file_reload_cmd_cb(GtkWidget *w, gpointer data) { file_reload_cmd_cb(GtkWidget *w, gpointer data) {
/*GtkWidget *filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY);*/ /*GtkWidget *filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY);*/
GtkWidget *filter_te; GtkWidget *filter_te;
int err;
filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY); filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY);
if (cf.dfilter) g_free(cf.dfilter); if (cf.dfilter) g_free(cf.dfilter);
cf.dfilter = g_strdup(gtk_entry_get_text(GTK_ENTRY(filter_te))); cf.dfilter = g_strdup(gtk_entry_get_text(GTK_ENTRY(filter_te)));
err = load_cap_file(cf.filename, &cf); load_cap_file(cf.filename, g_strdup(cf.rfilter), &cf);
if (err != 0) { /* XXX - change the menu if it fails? */
simple_dialog(ESD_TYPE_WARN, NULL, file_open_error_message(err, FALSE),
cf.filename);
}
} }
/* Run the current display filter on the current packet set, and /* Run the current display filter on the current packet set, and
@ -976,7 +992,7 @@ main(int argc, char *argv[])
GtkAccelGroup *accel; GtkAccelGroup *accel;
GtkWidget *packet_sw; GtkWidget *packet_sw;
gint pl_size = 280, tv_size = 95, bv_size = 75; gint pl_size = 280, tv_size = 95, bv_size = 75;
gchar *rc_file, *cf_name = NULL; gchar *rc_file, *cf_name = NULL, *rfilter = NULL;
e_prefs *prefs; e_prefs *prefs;
gchar **col_title; gchar **col_title;
@ -1350,12 +1366,9 @@ main(int argc, char *argv[])
alert box, so, if we get one of those, it's more likely to come alert box, so, if we get one of those, it's more likely to come
up on top of us. */ up on top of us. */
if (cf_name) { if (cf_name) {
err = load_cap_file(cf_name, &cf); err = load_cap_file(cf_name, rfilter, &cf);
if (err != 0) {
simple_dialog(ESD_TYPE_WARN, NULL, file_open_error_message(err, FALSE),
cf_name);
}
cf_name[0] = '\0'; cf_name[0] = '\0';
if (err == 0)
set_menu_sensitivity("/File/Save As...", TRUE); set_menu_sensitivity("/File/Save As...", TRUE);
} }

42
file.c
View File

@ -1,7 +1,7 @@
/* file.c /* file.c
* File I/O routines * File I/O routines
* *
* $Id: file.c,v 1.60 1999/08/10 06:54:12 guy Exp $ * $Id: file.c,v 1.61 1999/08/10 07:12:52 guy Exp $
* *
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org> * By Gerald Combs <gerald@zing.org>
@ -82,7 +82,6 @@ extern GtkWidget *packet_list, *prog_bar, *info_bar, *byte_view, *tree_view;
extern guint file_ctx; extern guint file_ctx;
extern int sync_mode; extern int sync_mode;
extern int sync_pipe[]; extern int sync_pipe[];
extern gchar *rfilter;
guint cap_input_id; guint cap_input_id;
@ -187,7 +186,7 @@ close_cap_file(capture_file *cf, void *w, guint context) {
} }
int int
load_cap_file(char *fname, capture_file *cf) { load_cap_file(char *fname, char *rfilter, capture_file *cf) {
gchar *name_ptr, *load_msg, *load_fmt = " Loading: %s..."; gchar *name_ptr, *load_msg, *load_fmt = " Loading: %s...";
gchar *done_fmt = " File: %s Drops: %d"; gchar *done_fmt = " File: %s Drops: %d";
gchar *err_fmt = " Error: Could not load '%s'"; gchar *err_fmt = " Error: Could not load '%s'";
@ -204,35 +203,40 @@ load_cap_file(char *fname, capture_file *cf) {
name_ptr = fname; name_ptr = fname;
else else
name_ptr++; name_ptr++;
load_msg = g_malloc(strlen(name_ptr) + strlen(load_fmt) + 2);
sprintf(load_msg, load_fmt, name_ptr);
gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, load_msg);
timeout = gtk_timeout_add(250, file_progress_cb, (gpointer) cf);
rfcode = NULL; rfcode = NULL;
if (rfilter) if (rfilter)
if (dfilter_compile(rfilter, &rfcode) != 0) { if (dfilter_compile(rfilter, &rfcode) != 0) {
simple_dialog(ESD_TYPE_WARN, NULL, simple_dialog(ESD_TYPE_WARN, NULL,
"Unable to parse filter string \"%s\".", rfilter); "Unable to parse filter string \"%s\".", rfilter);
goto fail;
} }
err = open_cap_file(fname, cf); err = open_cap_file(fname, cf);
if ((err == 0) && (cf->cd_t != WTAP_FILE_UNKNOWN)) { if (err != 0) {
simple_dialog(ESD_TYPE_WARN, NULL,
file_open_error_message(err, FALSE), fname);
goto fail;
}
load_msg = g_malloc(strlen(name_ptr) + strlen(load_fmt) + 2);
sprintf(load_msg, load_fmt, name_ptr);
gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, load_msg);
timeout = gtk_timeout_add(250, file_progress_cb, (gpointer) cf);
freeze_clist(cf); freeze_clist(cf);
wtap_loop(cf->wth, 0, wtap_dispatch_cb, (u_char *) cf); wtap_loop(cf->wth, 0, wtap_dispatch_cb, (u_char *) cf);
wtap_close(cf->wth); wtap_close(cf->wth);
cf->wth = NULL; cf->wth = NULL;
cf->fh = fopen(fname, "r"); cf->fh = fopen(fname, "r");
thaw_clist(cf); thaw_clist(cf);
}
gtk_timeout_remove(timeout); gtk_timeout_remove(timeout);
gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar), 0); gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar), 0);
gtk_statusbar_pop(GTK_STATUSBAR(info_bar), file_ctx); gtk_statusbar_pop(GTK_STATUSBAR(info_bar), file_ctx);
if (err == 0) {
msg_len = strlen(name_ptr) + strlen(done_fmt) + 64; msg_len = strlen(name_ptr) + strlen(done_fmt) + 64;
load_msg = g_realloc(load_msg, msg_len); load_msg = g_realloc(load_msg, msg_len);
@ -246,20 +250,28 @@ load_cap_file(char *fname, capture_file *cf) {
/* name_ptr[-1] = '\0'; Why is this here? It causes problems with capture files */ /* name_ptr[-1] = '\0'; Why is this here? It causes problems with capture files */
/* Remember the new read filter string. */
if (cf->rfilter != NULL)
g_free(cf->rfilter);
cf->rfilter = rfilter;
/* Enable menu items that make sense if you have a capture. */ /* Enable menu items that make sense if you have a capture. */
set_menu_sensitivity("/File/Close", TRUE); set_menu_sensitivity("/File/Close", TRUE);
set_menu_sensitivity("/File/Reload", TRUE); set_menu_sensitivity("/File/Reload", TRUE);
set_menu_sensitivity("/File/Print...", TRUE); set_menu_sensitivity("/File/Print...", TRUE);
set_menu_sensitivity("/Display/Options...", TRUE); set_menu_sensitivity("/Display/Options...", TRUE);
set_menu_sensitivity("/Tools/Summary", TRUE); set_menu_sensitivity("/Tools/Summary", TRUE);
} else { return 0;
fail:
msg_len = strlen(name_ptr) + strlen(err_fmt) + 2; msg_len = strlen(name_ptr) + strlen(err_fmt) + 2;
load_msg = g_realloc(load_msg, msg_len); load_msg = g_malloc(msg_len);
snprintf(load_msg, msg_len, err_fmt, name_ptr); snprintf(load_msg, msg_len, err_fmt, name_ptr);
gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, load_msg); gtk_statusbar_push(GTK_STATUSBAR(info_bar), file_ctx, load_msg);
g_free(load_msg); g_free(load_msg);
} if (rfilter != NULL)
return err; g_free(rfilter); /* assumed to be "g_strdup()"ed, if not null */
return -1;
} }
#ifdef HAVE_LIBPCAP #ifdef HAVE_LIBPCAP

5
file.h
View File

@ -1,7 +1,7 @@
/* file.h /* file.h
* Definitions for file structures and routines * Definitions for file structures and routines
* *
* $Id: file.h,v 1.27 1999/08/10 04:13:37 guy Exp $ * $Id: file.h,v 1.28 1999/08/10 07:12:52 guy Exp $
* *
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org> * By Gerald Combs <gerald@zing.org>
@ -63,6 +63,7 @@ typedef struct _capture_file {
gchar *save_file; /* File that user saved capture to */ gchar *save_file; /* File that user saved capture to */
gint user_saved;/* Was capture file saved by user yet? */ gint user_saved;/* Was capture file saved by user yet? */
wtap *wth; /* Wiretap session */ wtap *wth; /* Wiretap session */
gchar *rfilter; /* Read filter string */
gchar *dfilter; /* Display filter string */ gchar *dfilter; /* Display filter string */
GNode *dfcode; /* Compiled display filter program */ GNode *dfcode; /* Compiled display filter program */
#ifdef HAVE_LIBPCAP #ifdef HAVE_LIBPCAP
@ -101,7 +102,7 @@ typedef struct _capture_file {
int open_cap_file(char *, capture_file *); int open_cap_file(char *, capture_file *);
void close_cap_file(capture_file *, void *, guint); void close_cap_file(capture_file *, void *, guint);
int load_cap_file(char *, capture_file *); int load_cap_file(char *, char *, capture_file *);
int tail_cap_file(char *, capture_file *); int tail_cap_file(char *, capture_file *);
/* size_t read_frame_header(capture_file *); */ /* size_t read_frame_header(capture_file *); */