Have separate capture and display filter lists; some filter dialog boxes

use the capture filter lists, and others use the display filter list, as
appropriate.

Have separate menu items for editing the capture and display filter
lists.

Have separate "~/.ethereal/cfilters" and "~/.ethereal/dfilters" files
for the two lists; if either of those files isn't found, we try
"~/.ethereal/filters", which means that you will start out with two
identical lists holding all your filters - if certain filters belong
only in one list, you'll have to delete them by hand from the other
list.

Do I/O error checking when reading and writing filter lists; when
writing a filter list, write it to a new file, and then rename the new
file on top of the old file, so that you don't lose your old filter list
if, for example, you run out of disk space or disk quota.


git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@2948 f5534014-38df-0310-8fa8-9805f1628bb7
This commit is contained in:
guy 2001-01-28 09:13:10 +00:00
parent 2e1178251f
commit 6725db54d5
7 changed files with 629 additions and 159 deletions

View File

@ -264,11 +264,15 @@ Allows you to unmark all packets that are currently displayed.
Sets the packet printing, column display, TCP stream coloring, and GUI
options (see L<"Preferences"> below).
=item Edit:Filters
=item Edit:Capture Filters
Edits the saved list of filters, allowing filters to be added, changed,
or deleted, and lets a selected filter be applied to the current
capture, if any.
Edits the saved list of capture filters, allowing filters to be added,
changed, or deleted.
=item Edit:Display Filters
Edits the saved list of display filters, allowing filters to be added,
changed, or deleted.
=item Edit:Protocols
@ -468,8 +472,8 @@ of each column in the packet list.
The I<Column title> entry is used to specify the title of the column
displayed at the top of the packet list. The type of data that the column
displays can be specified using the I<Column format> option menu. The row
of buttons on the left perform the following actions:
displays can be specified using the I<Column format> option menu.
The row of buttons on the left perform the following actions:
=over 6
@ -553,21 +557,49 @@ controlling the way Ethereal handles those protocols.
=back
=item Filters
=item Edit Capture Filter List
The I<Filters> dialog lets you create and modify filters, and set the
default filter to use when capturing data or opening a capture file.
=item Edit Display Filter List
The I<Filter name> entry specifies a descriptive name for a filter, e.g.
B<Web and DNS traffic>. The I<Filter string> entry is the text that
actually describes the filtering action to take, as described above.The
dialog buttons perform the following actions:
=item Capture Filter
=item Display Filter
=item Read Filter
=item Search Filter
The I<Edit Capture Filter List> dialog lets you create, modify, and
delete capture filters, and the I<Edit Display Filter List> dialog lets
you create, modify, and delete display filters.
The I<Capture Filter> dialog lets you do all of the editing operations
listed, and also lets you choose or construct a filter to be used when
capturing packets.
The I<Display Filter> dialog lets you do all of the editing operations
listed, and also lets you choose or construct a filter to be used to
filter the current capture being viewed.
The I<Read Filter> dialog lets you do all of the editing operations
listed, and also lets you choose or construct a filter to be used to
as a read filter for a capture file you open.
The I<Search Filter> dialog lets you do all of the editing operations
listed, and also lets you choose or construct a filter expression to be
used in a find operation.
In all of those dialogs, the I<Filter name> entry specifies a
descriptive name for a filter, e.g. B<Web and DNS traffic>. The
I<Filter string> entry is the text that actually describes the filtering
action to take, as described above.The dialog buttons perform the
following actions:
=over 6
=item New
If there is text in the two entry boxes, it creates a new associated list
If there is text in the two entry boxes, creates a new associated list
item.
=item Change
@ -585,26 +617,39 @@ Deletes the currently selected list item.
=item Add Expression...
Pops up a dialog box to allow you to construct a filter expression to
test a particular field; it offers lists of field names, and, when
appropriate, lists from which to select tests to perform on the field
and values with which to compare it.
For display filter expressions, pops up a dialog box to allow you to
construct a filter expression to test a particular field; it offers
lists of field names, and, when appropriate, lists from which to select
tests to perform on the field and values with which to compare it. In
that dialog box, the OK button will cause the filter expression you
constructed to be entered into the I<Filter string> entry at the current
cursor position.
=item OK
Sets the filter in the I<Filter string> entry as the active filter. If
nothing is selected, turns filtering off.
In the I<Edit Capture Filter List> and I<Edit Display Filter List>
dialogs, closes the dialog box. In the I<Capture Filter> dialog, closes
the dialog box and makes the filter in the I<Filter string> entry the
filter in the I<Capture Preferences> dialog. In the I<Display Filter>
dialog, closes the dialog box and makes the filter in the I<Filter
string> entry the current display filter, and applies it to the current
capture. In the I<Read Filter> dialog, closes the dialog box and makes
the filter in the I<Filter string> entry the filter in the I<Open
Capture File> dialog. In the I<Search Filter> dialog, closes the dialog
box and makes the filter in the I<Filter string> entry the filter in the
I<Find Frame> dialog.
=item Apply
Sets the filter in the I<Filter string> entry as the active filter, and
applies it to the current capture, if any. (The currently selected list
item must be a display filter, not a capture filter.) If nothing is
selected, turns filtering off.
Makes the filter in the I<Filter string> entry the current display
filter, and applies it to the current capture.
=item Save
Saves the current filter list in F<$HOME/.ethereal/filters>.
Saves the current filter list in F<$HOME/.ethereal/cfilters> if the list
of filters being edited is the list of capture filters or in
F<$HOME/.ethereal/dfilters> if the list of filters being edited is the
list of display filters.
=item Cancel

300
filters.c
View File

@ -1,7 +1,7 @@
/* filters.c
* Code for reading and writing the filters file.
*
* $Id: filters.c,v 1.2 2001/01/28 04:52:28 guy Exp $
* $Id: filters.c,v 1.3 2001/01/28 09:13:07 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -30,6 +30,7 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
@ -46,44 +47,125 @@
#include "filters.h"
#include "util.h"
/*
* Old filter file name.
*/
#define FILTER_FILE_NAME "filters"
/*
* Capture filter file name.
*/
#define CFILTER_FILE_NAME "cfilters"
/*
* Display filter file name.
*/
#define DFILTER_FILE_NAME "dfilters"
#define FILTER_LINE_SIZE 2048
/*
* List of filters.
* List of capture filters.
*/
GList *fl = NULL;
static GList *capture_filters = NULL;
/*
* List of display filters.
*/
static GList *display_filters = NULL;
/*
* Read in a list of filters.
*
* On success, "*pref_path_return" is set to NULL.
* On error, "*pref_path_return" is set to point to the pathname of
* the file we tried to read - it should be freed by our caller -
* and "*errno_return" is set to the error.
*/
void
get_filter_list(void)
read_filter_list(filter_list_type_t list, char **pref_path_return,
int *errno_return)
{
GList *flp;
filter_def *filt;
char *ff_path, *ff_dir = PF_DIR, *ff_name;
FILE *ff;
gchar *ff_path, *ff_name = PF_DIR "/filters", f_buf[FILTER_LINE_SIZE];
gchar *name_begin, *name_end, *filt_begin;
GList **flp;
GList *fl_ent;
filter_def *filt;
char f_buf[FILTER_LINE_SIZE];
char *name_begin, *name_end, *filt_begin;
int len, line = 0;
/* If we already have a list of filters, discard it. */
if (fl != NULL) {
flp = g_list_first(fl);
while (flp) {
filt = (filter_def *) flp->data;
g_free(filt->name);
g_free(filt->strval);
g_free(filt);
flp = flp->next;
}
g_list_free(fl);
fl = NULL;
*pref_path_return = NULL; /* assume no error */
switch (list) {
case CFILTER_LIST:
ff_name = CFILTER_FILE_NAME;
flp = &capture_filters;
break;
case DFILTER_LIST:
ff_name = DFILTER_FILE_NAME;
flp = &display_filters;
break;
default:
g_assert_not_reached();
return;
}
/* To do: generalize this */
ff_path = (gchar *) g_malloc(strlen(get_home_dir()) + strlen(ff_name) + 4);
sprintf(ff_path, "%s/%s", get_home_dir(), ff_name);
ff_path = (gchar *) g_malloc(strlen(get_home_dir()) + strlen(ff_dir) +
strlen(ff_name) + 4);
sprintf(ff_path, "%s/%s/%s", get_home_dir(), ff_dir, ff_name);
if ((ff = fopen(ff_path, "r")) == NULL) {
g_free(ff_path);
return;
/*
* Did that fail because we the file didn't exist?
*/
if (errno != ENOENT) {
/*
* No. Just give up.
*/
*pref_path_return = ff_path;
*errno_return = errno;
return;
}
/*
* Yes. See if there's a "filters" file; if so, read it.
* This means that a user will start out with their capture and
* display filter lists being identical; each list may contain
* filters that don't belong in that list. The user can edit
* the filter lists, and delete the ones that don't belong in
* a particular list.
*/
sprintf(ff_path, "%s/%s/%s", get_home_dir(), ff_dir, FILTER_FILE_NAME);
if ((ff = fopen(ff_path, "r")) == NULL) {
/*
* Well, that didn't work, either. Just give up.
* Return an error if the file existed but we couldn't open it.
*/
if (errno != ENOENT) {
*pref_path_return = ff_path;
*errno_return = errno;
}
return;
}
}
/* If we already have a list of filters, discard it. */
if (*flp != NULL) {
fl_ent = g_list_first(*flp);
while (fl_ent != NULL) {
filt = (filter_def *) fl_ent->data;
g_free(filt->name);
g_free(filt->strval);
g_free(filt);
fl_ent = fl_ent->next;
}
g_list_free(*flp);
*flp = NULL;
}
while (fgets(f_buf, FILTER_LINE_SIZE, ff)) {
@ -115,23 +197,130 @@ get_filter_list(void)
filt = (filter_def *) g_malloc(sizeof(filter_def));
filt->name = g_strdup(name_begin);
filt->strval = g_strdup(filt_begin);
fl = g_list_append(fl, filt);
*flp = g_list_append(*flp, filt);
}
if (ferror(ff)) {
*pref_path_return = ff_path;
*errno_return = errno;
} else
g_free(ff_path);
fclose(ff);
g_free(ff_path);
}
void
save_filter_list(void)
/*
* Get a pointer to a list of filters.
*/
static GList **
get_filter_list(filter_list_type_t list)
{
GList **flp;
switch (list) {
case CFILTER_LIST:
flp = &capture_filters;
break;
case DFILTER_LIST:
flp = &display_filters;
break;
default:
g_assert_not_reached();
flp = NULL;
}
return flp;
}
/*
* Get a pointer to the first entry in a filter list.
*/
GList *
get_filter_list_first(filter_list_type_t list)
{
GList **flp;
flp = get_filter_list(list);
return g_list_first(*flp);
}
/*
* Add a new filter to the end of a list.
* Returns a pointer to the newly-added entry.
*/
GList *
add_to_filter_list(filter_list_type_t list, char *name, char *expression)
{
GList **flp;
filter_def *filt;
flp = get_filter_list(list);
filt = (filter_def *) g_malloc(sizeof(filter_def));
filt->name = g_strdup(name);
filt->strval = g_strdup(expression);
*flp = g_list_append(*flp, filt);
return g_list_last(*flp);
}
/*
* Remove a filter from a list.
*/
void
remove_from_filter_list(filter_list_type_t list, GList *fl_entry)
{
GList **flp;
filter_def *filt;
flp = get_filter_list(list);
filt = (filter_def *) fl_entry->data;
g_free(filt->name);
g_free(filt->strval);
g_free(filt);
*flp = g_list_remove_link(*flp, fl_entry);
}
/*
* Write out a list of filters.
*
* On success, "*pref_path_return" is set to NULL.
* On error, "*pref_path_return" is set to point to the pathname of
* the file we tried to read - it should be freed by our caller -
* and "*errno_return" is set to the error.
*/
void
save_filter_list(filter_list_type_t list, char **pref_path_return,
int *errno_return)
{
gchar *ff_path, *ff_path_new, *ff_dir = PF_DIR, *ff_name;
int path_length;
GList *fl;
GList *flp;
filter_def *filt;
gchar *ff_path, *ff_dir = PF_DIR, *ff_name = "filters";
FILE *ff;
struct stat s_buf;
ff_path = (gchar *) g_malloc(strlen(get_home_dir()) + strlen(ff_dir) +
strlen(ff_name) + 4);
*pref_path_return = NULL; /* assume no error */
switch (list) {
case CFILTER_LIST:
ff_name = CFILTER_FILE_NAME;
fl = capture_filters;
break;
case DFILTER_LIST:
ff_name = DFILTER_FILE_NAME;
fl = display_filters;
break;
default:
g_assert_not_reached();
return;
}
path_length = strlen(get_home_dir()) + strlen(ff_dir) + strlen(ff_name)
+ 4 + 4;
ff_path = (gchar *) g_malloc(path_length);
sprintf(ff_path, "%s/%s", get_home_dir(), ff_dir);
if (stat(ff_path, &s_buf) != 0)
@ -143,15 +332,50 @@ save_filter_list(void)
sprintf(ff_path, "%s/%s/%s", get_home_dir(), ff_dir, ff_name);
if ((ff = fopen(ff_path, "w")) != NULL) {
flp = g_list_first(fl);
while (flp) {
filt = (filter_def *) flp->data;
fprintf(ff, "\"%s\" %s\n", filt->name, filt->strval);
flp = flp->next;
/* Write to "XXX.new", and rename if that succeeds.
That means we don't trash the file if we fail to write it out
completely. */
ff_path_new = (gchar *) g_malloc(path_length);
sprintf(ff_path_new, "%s/%s/%s.new", get_home_dir(), ff_dir, ff_name);
if ((ff = fopen(ff_path_new, "w")) == NULL) {
*pref_path_return = ff_path;
*errno_return = errno;
g_free(ff_path_new);
return;
}
flp = g_list_first(fl);
while (flp) {
filt = (filter_def *) flp->data;
fprintf(ff, "\"%s\" %s\n", filt->name, filt->strval);
if (ferror(ff)) {
*pref_path_return = ff_path;
*errno_return = errno;
fclose(ff);
unlink(ff_path_new);
g_free(ff_path_new);
return;
}
fclose(ff);
flp = flp->next;
}
if (fclose(ff) == EOF) {
*pref_path_return = ff_path;
*errno_return = errno;
unlink(ff_path_new);
g_free(ff_path_new);
return;
}
/* XXX - does "rename()" exist on Win32? If so, does it remove the
target first? If so, does that mean it's not atomic? */
if (rename(ff_path_new, ff_path) < 0) {
*pref_path_return = ff_path;
*errno_return = errno;
unlink(ff_path_new);
g_free(ff_path);
g_free(ff_path_new);
return;
}
g_free(ff_path_new);
g_free(ff_path);
}

View File

@ -1,7 +1,7 @@
/* filters.c
* Declarations of routines for reading and writing the filters file.
*
* $Id: filters.h,v 1.1 2001/01/28 04:43:24 guy Exp $
* $Id: filters.h,v 1.2 2001/01/28 09:13:07 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -24,9 +24,12 @@
*/
/*
* List of filters.
* Filter lists.
*/
extern GList *fl;
typedef enum {
CFILTER_LIST, /* capture filter list */
DFILTER_LIST /* display filter list */
} filter_list_type_t;
/*
* Item in a list of filters.
@ -36,6 +39,41 @@ typedef struct {
char *strval; /* filter expression */
} filter_def;
void get_filter_list(void);
/*
* Read in a list of filters.
*
* On success, "*pref_path_return" is set to NULL.
* On error, "*pref_path_return" is set to point to the pathname of
* the file we tried to read - it should be freed by our caller -
* and "*errno_return" is set to the error.
*/
void read_filter_list(filter_list_type_t list, char **pref_path_return,
int *errno_return);
void save_filter_list(void);
/*
* Get a pointer to the first entry in a filter list.
*/
GList *get_filter_list_first(filter_list_type_t list);
/*
* Add a new filter to the end of a list.
* Returns a pointer to the newly-added entry.
*/
GList *add_to_filter_list(filter_list_type_t list, char *name,
char *expression);
/*
* Remove a filter from a list.
*/
void remove_from_filter_list(filter_list_type_t list, GList *fl_entry);
/*
* Write out a list of filters.
*
* On success, "*pref_path_return" is set to NULL.
* On error, "*pref_path_return" is set to point to the pathname of
* the file we tried to read - it should be freed by our caller -
* and "*errno_return" is set to the error.
*/
void save_filter_list(filter_list_type_t list, char **pref_path_return,
int *errno_return);

View File

@ -3,7 +3,7 @@
* (This used to be a notebook page under "Preferences", hence the
* "prefs" in the file name.)
*
* $Id: filter_prefs.c,v 1.25 2001/01/28 04:52:29 guy Exp $
* $Id: filter_prefs.c,v 1.26 2001/01/28 09:13:09 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -29,6 +29,8 @@
# include "config.h"
#endif
#include <string.h>
#include <gtk/gtk.h>
#include <epan.h>
@ -38,6 +40,7 @@
#include "filter_prefs.h"
#include "dlg_utils.h"
#include "ui_util.h"
#include "simple_dialog.h"
#include "prefs_dlg.h"
#include "dfilter_expr_dlg.h"
@ -60,7 +63,7 @@ typedef struct _filter_cb_data {
} filter_cb_data;
static GtkWidget *filter_dialog_new(GtkWidget *caller, GtkWidget *filter_te,
construct_args_t *construct_args, gboolean wants_add_expression_button);
filter_list_type_t list, construct_args_t *construct_args);
static void filter_dlg_dclick(GtkWidget *dummy, gpointer main_w_arg);
static void filter_dlg_ok_cb(GtkWidget *ok_bt, gpointer dummy);
static void filter_dlg_apply_cb(GtkWidget *apply_bt, gpointer dummy);
@ -133,8 +136,8 @@ capture_filter_construct_cb(GtkWidget *w, gpointer user_data)
parent_filter_te = gtk_object_get_data(GTK_OBJECT(w), E_FILT_TE_PTR_KEY);
/* Now create a new dialog, without an "Add Expression..." button. */
filter_browse_w = filter_dialog_new(caller, parent_filter_te, &args,
FALSE);
filter_browse_w = filter_dialog_new(caller, parent_filter_te,
CFILTER_LIST, &args);
/* Set the E_FILT_CALLER_PTR_KEY for the new dialog to point to
our caller. */
@ -187,7 +190,7 @@ display_filter_construct_cb(GtkWidget *w, gpointer construct_args_ptr)
/* Now create a new dialog, possibly with an "Apply" button, and
definitely with an "Add Expression..." button. */
filter_browse_w = filter_dialog_new(caller, parent_filter_te,
construct_args, TRUE);
DFILTER_LIST, construct_args);
/* Set the E_FILT_CALLER_PTR_KEY for the new dialog to point to
our caller. */
@ -199,25 +202,26 @@ display_filter_construct_cb(GtkWidget *w, gpointer construct_args_ptr)
filter_browse_w);
}
static GtkWidget *global_filter_w;
static GtkWidget *global_cfilter_w;
/* Create a filter dialog for editing; this is to be used as a callback
for menu items, toolbars, etc.. */
/* Create a filter dialog for editing capture filters; this is to be used
as a callback for menu items, toolbars, etc.. */
void
filter_dialog_cb(GtkWidget *w)
cfilter_dialog_cb(GtkWidget *w)
{
/* No Apply button, and there's no text widget to set, much less
activate, on "OK". */
static construct_args_t args = {
"Ethereal: Edit Filter List",
"Ethereal: Edit Capture Filter List",
FALSE,
FALSE
};
/* Has a filter dialog box already been opened for editing? */
if (global_filter_w != NULL) {
/* Has a filter dialog box already been opened for editing
capture filters? */
if (global_cfilter_w != NULL) {
/* Yes. Just reactivate it. */
reactivate_window(global_filter_w);
reactivate_window(global_cfilter_w);
return;
}
@ -226,30 +230,97 @@ filter_dialog_cb(GtkWidget *w)
* a button next to some text entry field, so don't associate it
* with a text entry field.
*/
global_filter_w = filter_dialog_new(NULL, NULL, &args, TRUE);
global_cfilter_w = filter_dialog_new(NULL, NULL, CFILTER_LIST, &args);
}
/* List of filter dialogs, so that if the list of filters changes (the
model, if you will), we can update all of their lists displaying
static GtkWidget *global_dfilter_w;
/* Create a filter dialog for editing display filters; this is to be used
as a callback for menu items, toolbars, etc.. */
void
dfilter_dialog_cb(GtkWidget *w)
{
/* No Apply button, and there's no text widget to set, much less
activate, on "OK". */
static construct_args_t args = {
"Ethereal: Edit Display Filter List",
FALSE,
FALSE
};
/* Has a filter dialog box already been opened for editing
display filters? */
if (global_dfilter_w != NULL) {
/* Yes. Just reactivate it. */
reactivate_window(global_dfilter_w);
return;
}
/*
* No. Create one; we didn't pop this up as a result of pressing
* a button next to some text entry field, so don't associate it
* with a text entry field.
*/
global_dfilter_w = filter_dialog_new(NULL, NULL, DFILTER_LIST, &args);
}
/* List of capture filter dialogs, so that if the list of filters changes
(the model, if you will), we can update all of their lists displaying
the filters (the views). */
static GList *filter_dialogs;
static GList *cfilter_dialogs;
/* List of display filter dialogs, so that if the list of filters changes
(the model, if you will), we can update all of their lists displaying
the filters (the views). */
static GList *dfilter_dialogs;
static void
remember_filter_dialog(GtkWidget *main_w)
remember_filter_dialog(GtkWidget *main_w, GList **filter_dialogs)
{
filter_dialogs = g_list_append(filter_dialogs, main_w);
*filter_dialogs = g_list_append(*filter_dialogs, main_w);
}
/* Remove a filter dialog from the list of filter_dialogss. */
/* Remove a filter dialog from the specified list of filter_dialogs. */
static void
forget_filter_dialog(GtkWidget *main_w)
forget_filter_dialog(GtkWidget *main_w, filter_list_type_t list)
{
filter_dialogs = g_list_remove(filter_dialogs, main_w);
switch (list) {
case CFILTER_LIST:
cfilter_dialogs = g_list_remove(cfilter_dialogs, main_w);
break;
case DFILTER_LIST:
dfilter_dialogs = g_list_remove(dfilter_dialogs, main_w);
break;
default:
g_assert_not_reached();
break;
}
}
/* Get the dialog list corresponding to a particular filter list. */
static GList *
get_filter_dialog_list(filter_list_type_t list)
{
switch (list) {
case CFILTER_LIST:
return cfilter_dialogs;
case DFILTER_LIST:
return dfilter_dialogs;
default:
g_assert_not_reached();
return NULL;
}
}
static GtkWidget *
filter_dialog_new(GtkWidget *caller, GtkWidget *parent_filter_te,
construct_args_t *construct_args, gboolean wants_add_expression_button)
filter_list_type_t list, construct_args_t *construct_args)
{
GtkWidget *main_w, /* main window */
*main_vb, /* main container */
@ -277,9 +348,35 @@ filter_dialog_new(GtkWidget *caller, GtkWidget *parent_filter_te,
*filter_te,
*add_expression_bt;
GtkWidget *l_select = NULL;
GList *flp = NULL;
GList *fl_entry;
filter_def *filt;
gchar *filter_te_str = NULL;
GList **filter_dialogs;
static filter_list_type_t cfilter_list = CFILTER_LIST;
static filter_list_type_t dfilter_list = DFILTER_LIST;
filter_list_type_t *filter_list_p;
/* Get a pointer to a static variable holding the type of filter on
which we're working, so we can pass that pointer to callback
routines. */
switch (list) {
case CFILTER_LIST:
filter_dialogs = &cfilter_dialogs;
filter_list_p = &cfilter_list;
break;
case DFILTER_LIST:
filter_dialogs = &dfilter_dialogs;
filter_list_p = &dfilter_list;
break;
default:
g_assert_not_reached();
filter_dialogs = NULL;
filter_list_p = NULL;
break;
}
main_w = dlg_window_new(construct_args->title);
gtk_object_set_data(GTK_OBJECT(main_w), E_FILT_CONSTRUCT_ARGS_KEY,
@ -288,7 +385,7 @@ filter_dialog_new(GtkWidget *caller, GtkWidget *parent_filter_te,
/* Call a handler when we're destroyed, so we can inform
our caller, if any, that we've been destroyed. */
gtk_signal_connect(GTK_OBJECT(main_w), "destroy",
GTK_SIGNAL_FUNC(filter_dlg_destroy), NULL);
GTK_SIGNAL_FUNC(filter_dlg_destroy), filter_list_p);
main_vb = gtk_vbox_new(FALSE, 5);
gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
@ -316,14 +413,14 @@ filter_dialog_new(GtkWidget *caller, GtkWidget *parent_filter_te,
new_bt = gtk_button_new_with_label ("New");
gtk_signal_connect(GTK_OBJECT(new_bt), "clicked",
GTK_SIGNAL_FUNC(filter_new_bt_clicked_cb), NULL);
GTK_SIGNAL_FUNC(filter_new_bt_clicked_cb), filter_list_p);
gtk_container_add(GTK_CONTAINER(list_bb), new_bt);
gtk_widget_show(new_bt);
chg_bt = gtk_button_new_with_label ("Change");
gtk_widget_set_sensitive(chg_bt, FALSE);
gtk_signal_connect(GTK_OBJECT(chg_bt), "clicked",
GTK_SIGNAL_FUNC(filter_chg_bt_clicked_cb), NULL);
GTK_SIGNAL_FUNC(filter_chg_bt_clicked_cb), filter_list_p);
gtk_object_set_data(GTK_OBJECT(main_w), E_FILT_CHG_BT_KEY, chg_bt);
gtk_signal_connect(GTK_OBJECT(chg_bt), "destroy",
GTK_SIGNAL_FUNC(filter_chg_bt_destroy_cb), NULL);
@ -333,7 +430,7 @@ filter_dialog_new(GtkWidget *caller, GtkWidget *parent_filter_te,
copy_bt = gtk_button_new_with_label ("Copy");
gtk_widget_set_sensitive(copy_bt, FALSE);
gtk_signal_connect(GTK_OBJECT(copy_bt), "clicked",
GTK_SIGNAL_FUNC(filter_copy_bt_clicked_cb), NULL);
GTK_SIGNAL_FUNC(filter_copy_bt_clicked_cb), filter_list_p);
gtk_object_set_data(GTK_OBJECT(main_w), E_FILT_COPY_BT_KEY, copy_bt);
gtk_signal_connect(GTK_OBJECT(copy_bt), "destroy",
GTK_SIGNAL_FUNC(filter_copy_bt_destroy_cb), NULL);
@ -343,14 +440,14 @@ filter_dialog_new(GtkWidget *caller, GtkWidget *parent_filter_te,
del_bt = gtk_button_new_with_label ("Delete");
gtk_widget_set_sensitive(del_bt, FALSE);
gtk_signal_connect(GTK_OBJECT(del_bt), "clicked",
GTK_SIGNAL_FUNC(filter_del_bt_clicked_cb), NULL);
GTK_SIGNAL_FUNC(filter_del_bt_clicked_cb), filter_list_p);
gtk_object_set_data(GTK_OBJECT(main_w), E_FILT_DEL_BT_KEY, del_bt);
gtk_signal_connect(GTK_OBJECT(del_bt), "destroy",
GTK_SIGNAL_FUNC(filter_del_bt_destroy_cb), NULL);
gtk_container_add(GTK_CONTAINER(list_bb), del_bt);
gtk_widget_show(del_bt);
if (wants_add_expression_button) {
if (list == DFILTER_LIST) {
/* Create the "Add Expression..." button, to pop up a dialog
for constructing filter comparison expressions. */
add_expression_bt = gtk_button_new_with_label("Add Expression...");
@ -381,9 +478,9 @@ filter_dialog_new(GtkWidget *caller, GtkWidget *parent_filter_te,
gtk_object_set_data(GTK_OBJECT(filter_l), E_FILT_DBLFUNC_KEY, filter_dlg_dclick);
gtk_object_set_data(GTK_OBJECT(filter_l), E_FILT_DBLARG_KEY, main_w);
flp = g_list_first(fl);
while (flp) {
filt = (filter_def *) flp->data;
fl_entry = get_filter_list_first(list);
while (fl_entry != NULL) {
filt = (filter_def *) fl_entry->data;
nl_lb = gtk_label_new(filt->name);
nl_item = gtk_list_item_new();
@ -396,14 +493,15 @@ filter_dialog_new(GtkWidget *caller, GtkWidget *parent_filter_te,
gtk_container_add(GTK_CONTAINER(filter_l), nl_item);
gtk_widget_show(nl_item);
gtk_object_set_data(GTK_OBJECT(nl_item), E_FILT_LBL_KEY, nl_lb);
gtk_object_set_data(GTK_OBJECT(nl_item), E_FILT_LIST_ITEM_MODEL_KEY, flp);
gtk_object_set_data(GTK_OBJECT(nl_item), E_FILT_LIST_ITEM_MODEL_KEY,
fl_entry);
if (filter_te_str && filt->strval) {
if (strcmp(filter_te_str, filt->strval) == 0)
l_select = nl_item;
}
flp = flp->next;
fl_entry = fl_entry->next;
}
/* Middle row: Filter name entry */
@ -475,7 +573,7 @@ filter_dialog_new(GtkWidget *caller, GtkWidget *parent_filter_te,
save_bt = gtk_button_new_with_label ("Save");
gtk_signal_connect(GTK_OBJECT(save_bt), "clicked",
GTK_SIGNAL_FUNC(filter_dlg_save_cb), GTK_OBJECT(main_w));
GTK_SIGNAL_FUNC(filter_dlg_save_cb), filter_list_p);
GTK_WIDGET_SET_FLAGS(save_bt, GTK_CAN_DEFAULT);
gtk_box_pack_start(GTK_BOX(bbox), save_bt, TRUE, TRUE, 0);
gtk_widget_show(save_bt);
@ -489,7 +587,7 @@ filter_dialog_new(GtkWidget *caller, GtkWidget *parent_filter_te,
dlg_set_cancel(main_w, cancel_bt);
remember_filter_dialog(main_w);
remember_filter_dialog(main_w, filter_dialogs);
gtk_widget_show(main_w);
@ -585,9 +683,36 @@ filter_apply(GtkWidget *main_w)
}
static void
filter_dlg_save_cb(GtkWidget *save_bt, gpointer parent_w)
filter_dlg_save_cb(GtkWidget *save_bt, gpointer data)
{
save_filter_list();
filter_list_type_t list = *(filter_list_type_t *)data;
char *f_path;
int f_save_errno;
char *filter_type;
save_filter_list(list, &f_path, &f_save_errno);
if (f_path != NULL) {
/* We had an error saving the filter. */
switch (list) {
case CFILTER_LIST:
filter_type = "capture";
break;
case DFILTER_LIST:
filter_type = "display";
break;
default:
g_assert_not_reached();
filter_type = NULL;
break;
}
simple_dialog(ESD_TYPE_CRIT, NULL,
"Could not save to your %s filter file\n\"%s\": %s.",
filter_type, f_path, strerror(f_save_errno));
g_free(f_path);
}
}
static void
@ -599,6 +724,7 @@ filter_dlg_cancel_cb(GtkWidget *cancel_bt, gpointer parent_w)
static void
filter_dlg_destroy(GtkWidget *win, gpointer data)
{
filter_list_type_t list = *(filter_list_type_t *)data;
GtkWidget *caller;
/* Get the widget that requested that we be popped up, if any.
@ -613,12 +739,26 @@ filter_dlg_destroy(GtkWidget *win, gpointer data)
} else {
/* This is an editing dialog popped up from, for example,
a menu item; note that we no longer have one. */
g_assert(win == global_filter_w);
global_filter_w = NULL;
switch (list) {
case CFILTER_LIST:
g_assert(win == global_cfilter_w);
global_cfilter_w = NULL;
break;
case DFILTER_LIST:
g_assert(win == global_dfilter_w);
global_dfilter_w = NULL;
break;
default:
g_assert_not_reached();
break;
}
}
/* Remove this from the list of filter dialog windows. */
forget_filter_dialog(win);
forget_filter_dialog(win, list);
/* Now nuke this window. */
gtk_grab_remove(GTK_WIDGET(win));
@ -760,7 +900,8 @@ filter_new_bt_clicked_cb(GtkWidget *w, gpointer data)
GtkWidget *name_te = gtk_object_get_data(GTK_OBJECT(main_w), E_FILT_NAME_TE_KEY);
GtkWidget *filter_te = gtk_object_get_data(GTK_OBJECT(main_w), E_FILT_FILTER_TE_KEY);
GtkWidget *filter_l = gtk_object_get_data(GTK_OBJECT(main_w), E_FILT_FILTER_L_KEY);
filter_def *filt;
filter_list_type_t list = *(filter_list_type_t *)data;
GList *fl_entry;
gchar *name, *strval;
new_filter_cb_args_t args;
@ -768,16 +909,14 @@ filter_new_bt_clicked_cb(GtkWidget *w, gpointer data)
strval = gtk_entry_get_text(GTK_ENTRY(filter_te));
if (strlen(name) > 0 && strlen(strval) > 0) {
filt = (filter_def *) g_malloc(sizeof(filter_def));
filt->name = g_strdup(name);
filt->strval = g_strdup(strval);
fl = g_list_append(fl, filt);
/* Add a new entry to the filter list. */
fl_entry = add_to_filter_list(list, name, strval);
/* Update all the filter list widgets, not just the one in
the dialog box in which we clicked on "Copy". */
args.active_filter_l = filter_l;
args.nflp = g_list_last(fl);
g_list_foreach(filter_dialogs, new_filter_cb, &args);
args.nflp = fl_entry;
g_list_foreach(get_filter_dialog_list(list), new_filter_cb, &args);
}
}
@ -817,9 +956,10 @@ filter_chg_bt_clicked_cb(GtkWidget *w, gpointer data)
GtkWidget *filter_l = gtk_object_get_data(GTK_OBJECT(main_w), E_FILT_FILTER_L_KEY);
filter_def *filt;
gchar *name = "", *strval = "";
GList *sl, *flp;
GList *sl, *fl_entry;
GtkObject *l_item;
GtkLabel *nl_lb;
filter_list_type_t list = *(filter_list_type_t *)data;
sl = GTK_LIST(filter_l)->selection;
name = gtk_entry_get_text(GTK_ENTRY(name_te));
@ -827,10 +967,10 @@ filter_chg_bt_clicked_cb(GtkWidget *w, gpointer data)
if (sl) { /* Something was selected */
l_item = GTK_OBJECT(sl->data);
flp = (GList *) gtk_object_get_data(l_item, E_FILT_LIST_ITEM_MODEL_KEY);
nl_lb = (GtkLabel *) gtk_object_get_data(l_item, E_FILT_LBL_KEY);
if (flp && nl_lb) {
filt = (filter_def *) flp->data;
fl_entry = (GList *) gtk_object_get_data(l_item, E_FILT_LIST_ITEM_MODEL_KEY);
nl_lb = (GtkLabel *) gtk_object_get_data(l_item, E_FILT_LBL_KEY);
if (fl_entry != NULL && nl_lb != NULL) {
filt = (filter_def *) fl_entry->data;
if (strlen(name) > 0 && strlen(strval) > 0 && filt) {
g_free(filt->name);
@ -840,7 +980,7 @@ filter_chg_bt_clicked_cb(GtkWidget *w, gpointer data)
/* Update all the filter list widgets, not just the one in
the dialog box in which we clicked on "Copy". */
g_list_foreach(filter_dialogs, chg_filter_cb, flp);
g_list_foreach(get_filter_dialog_list(list), chg_filter_cb, fl_entry);
}
}
}
@ -859,29 +999,30 @@ filter_copy_bt_clicked_cb(GtkWidget *w, gpointer data)
{
GtkWidget *main_w = gtk_widget_get_toplevel(w);
GtkWidget *filter_l = gtk_object_get_data(GTK_OBJECT(main_w), E_FILT_FILTER_L_KEY);
GList *sl, *flp;
filter_def *filt, *nfilt;
gchar *prefix = "Copy of ";
GList *sl, *fl_entry, *nfl_entry;
gchar *prefix = "Copy of ", *name;
GtkObject *l_item;
filter_def *filt;
filter_list_type_t list = *(filter_list_type_t *)data;
new_filter_cb_args_t args;
sl = GTK_LIST(filter_l)->selection;
if (sl) { /* Something was selected */
l_item = GTK_OBJECT(sl->data);
flp = (GList *) gtk_object_get_data(l_item, E_FILT_LIST_ITEM_MODEL_KEY);
if (flp) {
filt = (filter_def *) flp->data;
nfilt = (filter_def *) g_malloc(sizeof(filter_def));
nfilt->name = g_malloc(strlen(prefix) + strlen(filt->name) + 1);
sprintf(nfilt->name, "%s%s", prefix, filt->name);
nfilt->strval = g_strdup(filt->strval);
fl = g_list_append(fl, nfilt);
fl_entry = (GList *) gtk_object_get_data(l_item, E_FILT_LIST_ITEM_MODEL_KEY);
if (fl_entry != NULL) {
/* Add a new entry, copying the existing entry, to the filter list. */
filt = (filter_def *) fl_entry->data;
name = g_malloc(strlen(prefix) + strlen(filt->name) + 1);
sprintf(name, "%s%s", prefix, filt->name);
nfl_entry = add_to_filter_list(list, name, filt->strval);
g_free(name);
/* Update all the filter list widgets, not just the one in
the dialog box in which we clicked on "Copy". */
args.active_filter_l = filter_l;
args.nflp = g_list_last(fl);
g_list_foreach(filter_dialogs, new_filter_cb, &args);
args.nflp = nfl_entry;
g_list_foreach(get_filter_dialog_list(list), new_filter_cb, &args);
}
}
}
@ -909,27 +1050,24 @@ filter_del_bt_clicked_cb(GtkWidget *w, gpointer data)
{
GtkWidget *main_w = gtk_widget_get_toplevel(w);
GtkWidget *filter_l = gtk_object_get_data(GTK_OBJECT(main_w), E_FILT_FILTER_L_KEY);
GList *sl, *flp;
filter_def *filt;
filter_list_type_t list = *(filter_list_type_t *)data;
GList *sl, *fl_entry;
GtkObject *l_item;
gint pos;
sl = GTK_LIST(filter_l)->selection;
if (sl) { /* Something was selected */
l_item = GTK_OBJECT(sl->data);
pos = gtk_list_child_position(GTK_LIST(filter_l),
GTK_WIDGET(l_item));
flp = (GList *) gtk_object_get_data(l_item, E_FILT_LIST_ITEM_MODEL_KEY);
if (flp) {
filt = (filter_def *) flp->data;
g_free(filt->name);
g_free(filt->strval);
g_free(filt);
fl = g_list_remove_link(fl, flp);
fl_entry = (GList *) gtk_object_get_data(l_item, E_FILT_LIST_ITEM_MODEL_KEY);
if (fl_entry != NULL) {
/* Remove the entry from the filter list. */
remove_from_filter_list(list, fl_entry);
/* Update all the filter list widgets, not just the one in
the dialog box in which we clicked on "Delete". */
g_list_foreach(filter_dialogs, delete_filter_cb, &pos);
g_list_foreach(get_filter_dialog_list(list), delete_filter_cb, &pos);
}
}
}

View File

@ -3,7 +3,7 @@
* (This used to be a notebook page under "Preferences", hence the
* "prefs" in the file name.)
*
* $Id: filter_prefs.h,v 1.9 2001/01/21 02:27:24 guy Exp $
* $Id: filter_prefs.h,v 1.10 2001/01/28 09:13:10 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -41,7 +41,8 @@ typedef struct {
void capture_filter_construct_cb(GtkWidget *w, gpointer user_data);
void display_filter_construct_cb(GtkWidget *w, gpointer construct_args_ptr);
void filter_dialog_cb(GtkWidget *);
void cfilter_dialog_cb(GtkWidget *w);
void dfilter_dialog_cb(GtkWidget *w);
#define E_FILT_TE_KEY "filter_te"
#define E_FILT_TE_PTR_KEY "filter_te_ptr"

View File

@ -1,6 +1,6 @@
/* main.c
*
* $Id: main.c,v 1.174 2001/01/28 04:52:29 guy Exp $
* $Id: main.c,v 1.175 2001/01/28 09:13:10 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@ -855,8 +855,8 @@ main(int argc, char *argv[])
WSADATA wsaData;
#endif
char *gpf_path, *pf_path;
int gpf_open_errno, pf_open_errno;
char *gpf_path, *pf_path, *cf_path, *df_path;
int gpf_open_errno, pf_open_errno, cf_open_errno, df_open_errno;
int err;
#ifdef HAVE_LIBPCAP
gboolean start_capture = FALSE;
@ -928,8 +928,11 @@ main(int argc, char *argv[])
/* Read the preference files. */
prefs = read_prefs(&gpf_open_errno, &gpf_path, &pf_open_errno, &pf_path);
/* Read the filter file. */
get_filter_list();
/* Read the capture filter file. */
read_filter_list(CFILTER_LIST, &cf_path, &cf_open_errno);
/* Read the display filter file. */
read_filter_list(DFILTER_LIST, &df_path, &df_open_errno);
/* Initialize the capture file struct */
cfile.plist = NULL;
@ -1365,6 +1368,26 @@ main(int argc, char *argv[])
strerror(pf_open_errno));
}
/* If the user's capture filter file exists but we failed to open it,
pop up an alert box; we defer that until now, so that the alert
box is more likely to come up on top of the main window. */
if (cf_path != NULL) {
simple_dialog(ESD_TYPE_WARN, NULL,
"Could not open your capture filter file\n\"%s\": %s.", cf_path,
strerror(cf_open_errno));
g_free(cf_path);
}
/* If the user's display filter file exists but we failed to open it,
pop up an alert box; we defer that until now, so that the alert
box is more likely to come up on top of the main window. */
if (df_path != NULL) {
simple_dialog(ESD_TYPE_WARN, NULL,
"Could not open your display filter file\n\"%s\": %s.", df_path,
strerror(df_open_errno));
g_free(df_path);
}
#ifdef HAVE_LIBPCAP
if (capture_child) {
/* This is the child process for a sync mode or fork mode capture,

View File

@ -1,7 +1,7 @@
/* menu.c
* Menu routines
*
* $Id: menu.c,v 1.46 2000/10/19 22:59:24 guy Exp $
* $Id: menu.c,v 1.47 2001/01/28 09:13:10 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -120,7 +120,8 @@ static GtkItemFactoryEntry menu_items[] =
{"/Edit/_Unmark All Frames", NULL, GTK_MENU_FUNC(unmark_all_frames_cb), 0, NULL},
{"/Edit/<separator>", NULL, NULL, 0, "<Separator>"},
{"/Edit/_Preferences...", NULL, GTK_MENU_FUNC(prefs_cb), 0, NULL},
{"/Edit/_Filters...", NULL, GTK_MENU_FUNC(filter_dialog_cb), 0, NULL},
{"/Edit/_Capture Filters...", NULL, GTK_MENU_FUNC(cfilter_dialog_cb), 0, NULL},
{"/Edit/_Display Filters...", NULL, GTK_MENU_FUNC(dfilter_dialog_cb), 0, NULL},
{"/Edit/P_rotocols...", NULL, GTK_MENU_FUNC(proto_cb), 0, NULL},
#ifdef HAVE_LIBPCAP
{"/_Capture", NULL, NULL, 0, "<Branch>" },
@ -159,7 +160,7 @@ static int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
static GtkItemFactoryEntry packet_list_menu_items[] =
{
{"/Follow TCP Stream", NULL, GTK_MENU_FUNC(follow_stream_cb), 0, NULL},
{"/Filters...", NULL, GTK_MENU_FUNC(filter_dialog_cb), 0, NULL},
{"/Display Filters...", NULL, GTK_MENU_FUNC(dfilter_dialog_cb), 0, NULL},
{"/<separator>", NULL, NULL, 0, "<Separator>"},
{"/Colorize Display...", NULL, GTK_MENU_FUNC(color_display_cb), 0, NULL},
{"/Print...", NULL, GTK_MENU_FUNC(file_print_cmd_cb), 0, NULL},
@ -170,7 +171,7 @@ static GtkItemFactoryEntry packet_list_menu_items[] =
static GtkItemFactoryEntry tree_view_menu_items[] =
{
{"/Follow TCP Stream", NULL, GTK_MENU_FUNC(follow_stream_cb), 0, NULL},
{"/Filters...", NULL, GTK_MENU_FUNC(filter_dialog_cb), 0, NULL},
{"/Display Filters...", NULL, GTK_MENU_FUNC(dfilter_dialog_cb), 0, NULL},
{"/<separator>", NULL, NULL, 0, "<Separator>"},
{"/Resolve Name", NULL, GTK_MENU_FUNC(resolve_name_cb), 0, NULL},
{"/Protocol Properties...", NULL, GTK_MENU_FUNC(properties_cb), 0, NULL},
@ -183,7 +184,7 @@ static GtkItemFactoryEntry tree_view_menu_items[] =
static GtkItemFactoryEntry hexdump_menu_items[] =
{
{"/Follow TCP Stream", NULL, GTK_MENU_FUNC(follow_stream_cb), 0, NULL},
{"/Filters...", NULL, GTK_MENU_FUNC(filter_dialog_cb), 0, NULL}
{"/Display Filters...", NULL, GTK_MENU_FUNC(dfilter_dialog_cb), 0, NULL}
};
static int initialize = TRUE;