Turn the code of "colorize_packet()" into a static routine that is given

a word to use in the progress dialog, and a flag indicating whether the
display filter is to be reevaluated or not, and:

	have "colorize_packet()" call that routine with "Colorizing" and
	FALSE as those arguments;

	have the filtering code call that routine with "Filtering" and
	TRUE as those arguments;

	add an exported routine to call that routine with "Reprocessing"
	and TRUE as those arguments, to use to re-generate the packet
	list and to re-filter the packets if a protocol preference has
	been changed.

Keep track of whether preferences are changed from their initial value
by a preferences file or a command-line option, or from their previous
value by the "Preferences" dialog box; have "prefs_apply_all()" only
call the "apply" callback for a module if they have.

Call "prefs_apply_all()" after the command-line arguments have been
parsed and after "OK" has been clicked in the "Preferences" dialog box,
to notify modules of preference changes if they've registered a callback
for that.

After "OK" has been clicked in the "Preferences" dialog box, if any
preferences have changed, call the reprocessing routine, as the summary
line for some frames and/or the current display filter's value when
applied to some frames may have changed as a result of a preference
change.  Do the same after "OK" or "Apply" has been clicked in the
"Display Options" dialog box (as it controls a protocol preferences
item.

svn path=/trunk/; revision=2126
This commit is contained in:
Guy Harris 2000-07-09 03:29:42 +00:00
parent 57d8e47ad0
commit 0a71de8137
9 changed files with 190 additions and 64 deletions

111
file.c
View File

@ -1,7 +1,7 @@
/* file.c
* File I/O routines
*
* $Id: file.c,v 1.196 2000/07/07 23:09:03 guy Exp $
* $Id: file.c,v 1.197 2000/07/09 03:29:26 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -95,6 +95,9 @@ static guint32 prevsec, prevusec;
static void read_packet(capture_file *cf, int offset);
static void rescan_packets(capture_file *cf, const char *action,
gboolean refilter);
static void set_selected_row(int row);
static void freeze_clist(capture_file *cf);
@ -589,7 +592,8 @@ apply_color_filter(gpointer filter_arg, gpointer argp)
static int
add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
union wtap_pseudo_header *pseudo_header, const u_char *buf)
union wtap_pseudo_header *pseudo_header, const u_char *buf,
gboolean refilter)
{
apply_color_filter_args args;
gint i, row;
@ -620,36 +624,56 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
fdata->cinfo->col_data[i][0] = '\0';
}
/* Apply the filters */
if (cf->dfcode != NULL || filter_list != NULL) {
protocol_tree = proto_tree_create_root();
dissect_packet(pseudo_header, buf, fdata, protocol_tree);
if (cf->dfcode != NULL)
fdata->flags.passed_dfilter = dfilter_apply(cf->dfcode, protocol_tree, buf, fdata->cap_len) ? 1 : 0;
else
fdata->flags.passed_dfilter = 1;
/* If either
/* Apply color filters, if we have any. */
we have a display filter and are re-applying it;
we have a list of color filters;
we have plugins to apply;
allocate a protocol tree root node, so that we'll construct
a protocol tree against which a filter expression can be
evaluated. */
if ((cf->dfcode != NULL && refilter) || filter_list != NULL
#ifdef HAVE_PLUGINS
|| enabled_plugins_number > 0
#endif
)
protocol_tree = proto_tree_create_root();
/* Dissect the frame. */
dissect_packet(pseudo_header, buf, fdata, protocol_tree);
/* If we have a display filter, apply it if we're refiltering, otherwise
leave the "passed_dfilter" flag alone.
If we don't have a display filter, set "passed_dfilter" to 1. */
if (cf->dfcode != NULL) {
if (refilter) {
if (cf->dfcode != NULL)
fdata->flags.passed_dfilter = dfilter_apply(cf->dfcode, protocol_tree, buf, fdata->cap_len) ? 1 : 0;
else
fdata->flags.passed_dfilter = 1;
}
} else
fdata->flags.passed_dfilter = 1;
/* If we have color filters, and the frame is to be displayed, apply
the color filters. */
if (fdata->flags.passed_dfilter) {
if (filter_list != NULL) {
args.protocol_tree = protocol_tree;
args.pd = buf;
args.fdata = fdata;
g_slist_foreach(filter_list, apply_color_filter, &args);
}
}
/* There are no more filters to apply, so we don't need any protocol
tree; free it if we created it. */
if (protocol_tree != NULL)
proto_tree_free(protocol_tree);
}
else {
#ifdef HAVE_PLUGINS
if (enabled_plugins_number > 0)
protocol_tree = proto_tree_create_root();
#endif
dissect_packet(pseudo_header, buf, fdata, protocol_tree);
fdata->flags.passed_dfilter = 1;
#ifdef HAVE_PLUGINS
if (protocol_tree)
proto_tree_free(protocol_tree);
#endif
}
if (fdata->flags.passed_dfilter) {
/* This frame passed the display filter, so add it to the clist. */
@ -766,7 +790,7 @@ read_packet(capture_file *cf, int offset)
cf->count++;
fdata->num = cf->count;
add_packet_to_packet_list(fdata, cf, pseudo_header, buf);
add_packet_to_packet_list(fdata, cf, pseudo_header, buf, TRUE);
} else {
/* XXX - if we didn't have read filters, or if we could avoid
allocating the "frame_data" structure until we knew whether
@ -814,17 +838,31 @@ filter_packets(capture_file *cf, gchar *dftext)
dfilter_destroy(cf->dfcode);
cf->dfcode = dfcode;
/* Now go through the list of packets we've read from the capture file,
applying the current display filter, and, if the packet passes the
display filter, add it to the summary display, appropriately
colored. (That's how we colorize the display - it's like filtering
the display, only we don't install a new filter.) */
colorize_packets(cf);
/* Now rescan the packet list, applying the new filter. */
rescan_packets(cf, "Filtering", TRUE);
return 1;
}
void
colorize_packets(capture_file *cf)
{
rescan_packets(cf, "Colorizing", FALSE);
}
void
redissect_packets(capture_file *cf)
{
rescan_packets(cf, "Reprocessing", TRUE);
}
/* Rescan the list of packets, reconstructing the CList.
"action" describes why we're doing this; it's used in the progress
dialog box.
"refilter" is TRUE if we need to re-evaluate the filter expression. */
static void
rescan_packets(capture_file *cf, const char *action, gboolean refilter)
{
frame_data *fdata;
progdlg_t *progbar;
@ -866,9 +904,9 @@ colorize_packets(capture_file *cf)
cf->first_displayed = NULL;
cf->last_displayed = NULL;
/* Iterate through the list of packets, calling a routine
to run the filter on the packet, see if it matches, and
put it in the display list if so. */
/* Iterate through the list of frames. Call a routine for each frame
to check whether it should be displayed and, if so, add it to
the display list. */
firstsec = 0;
firstusec = 0;
prevsec = 0;
@ -883,7 +921,7 @@ colorize_packets(capture_file *cf)
count = 0;
stop_flag = FALSE;
progbar = create_progress_dlg("Filtering", "Stop", &stop_flag);
progbar = create_progress_dlg(action, "Stop", &stop_flag);
for (fdata = cf->plist; fdata != NULL; fdata = fdata->next) {
/* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
@ -923,7 +961,8 @@ colorize_packets(capture_file *cf)
wtap_seek_read (cf->wth, fdata->file_off, &cf->pseudo_header,
cf->pd, fdata->cap_len);
row = add_packet_to_packet_list(fdata, cf, &cf->pseudo_header, cf->pd);
row = add_packet_to_packet_list(fdata, cf, &cf->pseudo_header, cf->pd,
refilter);
if (fdata == selected_frame)
selected_row = row;
}

3
file.h
View File

@ -1,7 +1,7 @@
/* file.h
* Definitions for file structures and routines
*
* $Id: file.h,v 1.70 2000/07/03 08:35:41 guy Exp $
* $Id: file.h,v 1.71 2000/07/09 03:29:27 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -140,6 +140,7 @@ int save_cap_file(char *, capture_file *, gboolean, guint);
int filter_packets(capture_file *cf, gchar *dfilter);
void colorize_packets(capture_file *);
void redissect_packets(capture_file *cf);
int print_packets(capture_file *cf, print_args_t *print_args);
void change_time_formats(capture_file *);
gboolean find_packet(capture_file *cf, dfilter *sfcode);

View File

@ -1,7 +1,7 @@
/* display_opts.c
* Routines for packet display windows
*
* $Id: display_opts.c,v 1.10 2000/07/05 02:45:39 guy Exp $
* $Id: display_opts.c,v 1.11 2000/07/09 03:29:40 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -241,6 +241,7 @@ static void
get_display_options(GtkWidget *parent_w)
{
GtkWidget *button;
gboolean bval;
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
E_DISPLAY_TIME_ABS_KEY);
@ -267,7 +268,20 @@ get_display_options(GtkWidget *parent_w)
button = (GtkWidget *) gtk_object_get_data(GTK_OBJECT(parent_w),
E_DISPLAY_IP_DSCP_KEY);
g_ip_dscp_actif = (GTK_TOGGLE_BUTTON (button)->active);
bval = (GTK_TOGGLE_BUTTON (button)->active);
if (g_ip_dscp_actif != bval) {
g_ip_dscp_actif = bval;
/* XXX - we "know" here that the IP dissector doesn't need to be
notified if this preference changed.
Ultimately, we should probably remove this item from the
"Display options" dialog box, as it can be changed from the
"IP" tab in the "Preferences" dialog box. */
/* Redissect all the packets, and re-evaluate the display filter. */
redissect_packets(&cfile);
}
}
static void

View File

@ -1,6 +1,6 @@
/* main.c
*
* $Id: main.c,v 1.128 2000/07/05 09:41:04 guy Exp $
* $Id: main.c,v 1.129 2000/07/09 03:29:40 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -1485,6 +1485,11 @@ main(int argc, char *argv[])
}
}
/* Notify all registered modules that have had any of their preferences
changed either from one of the preferences file or from the command
line that its preferences have changed. */
prefs_apply_all();
#ifndef HAVE_LIBPCAP
if (capture_option_specified)
fprintf(stderr, "This version of Ethereal was not built with support for capturing packets.\n");

View File

@ -1,7 +1,7 @@
/* prefs_dlg.c
* Routines for handling preferences
*
* $Id: prefs_dlg.c,v 1.14 2000/07/05 09:41:07 guy Exp $
* $Id: prefs_dlg.c,v 1.15 2000/07/09 03:29:42 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -334,8 +334,11 @@ pref_fetch(pref_t *pref, gpointer user_data)
char *str_val;
char *p;
guint uval;
gboolean bval;
GSList *rb_entry;
GtkWidget *button;
gint enumval;
gboolean *pref_changed_p = user_data;
/* Fetch the value of the preference, and set the appropriate variable
to it. */
@ -348,11 +351,18 @@ pref_fetch(pref_t *pref, gpointer user_data)
if (p == value || *p != '\0')
return PREFS_SET_SYNTAX_ERR; /* number was bad */
#endif
*pref->varp.uint = uval;
if (*pref->varp.uint != uval) {
*pref_changed_p = TRUE;
*pref->varp.uint = uval;
}
break;
case PREF_BOOL:
*pref->varp.bool = GTK_TOGGLE_BUTTON(pref->control)->active;
bval = GTK_TOGGLE_BUTTON(pref->control)->active;
if (*pref->varp.bool != bval) {
*pref_changed_p = TRUE;
*pref->varp.bool = bval;
}
break;
case PREF_ENUM:
@ -377,15 +387,22 @@ pref_fetch(pref_t *pref, gpointer user_data)
/* Get the label, and translate it to a value. */
gtk_label_get(GTK_LABEL(label), &label_string);
*pref->varp.enump = find_val_for_string(label_string,
enumval = find_val_for_string(label_string,
pref->info.enum_info.enumvals, 1);
if (*pref->varp.enump != enumval) {
*pref_changed_p = TRUE;
*pref->varp.enump = enumval;
}
break;
case PREF_STRING:
str_val = gtk_entry_get_text(GTK_ENTRY(pref->control));
if (*pref->varp.string != NULL)
g_free(*pref->varp.string);
*pref->varp.string = g_strdup(str_val);
if (*pref->varp.string == NULL || strcmp(*pref->varp.string, str_val) != 0) {
*pref_changed_p = TRUE;
if (*pref->varp.string != NULL)
g_free(*pref->varp.string);
*pref->varp.string = g_strdup(str_val);
}
break;
}
}
@ -393,9 +410,18 @@ pref_fetch(pref_t *pref, gpointer user_data)
static void
module_prefs_fetch(module_t *module, gpointer user_data)
{
gboolean *must_redissect_p = user_data;
/* For all preferences in this module, fetch its value from this
module's notebook page. */
prefs_pref_foreach(module, pref_fetch, NULL);
module's notebook page. Find out whether any of them changed. */
module->prefs_changed = FALSE; /* assume none of them changed */
prefs_pref_foreach(module, pref_fetch, &module->prefs_changed);
/* If any of them changed, indicate that we must redissect and refilter
the current capture (if we have one), as the preference change
could cause packets to be dissected differently. */
if (module->prefs_changed)
*must_redissect_p = TRUE;
}
static void
@ -432,13 +458,21 @@ module_prefs_clean(module_t *module, gpointer user_data)
static void
prefs_main_ok_cb(GtkWidget *ok_bt, gpointer parent_w)
{
gboolean must_redissect = FALSE;
printer_prefs_ok(gtk_object_get_data(GTK_OBJECT(parent_w), E_PRINT_PAGE_KEY));
column_prefs_ok(gtk_object_get_data(GTK_OBJECT(parent_w), E_COLUMN_PAGE_KEY));
stream_prefs_ok(gtk_object_get_data(GTK_OBJECT(parent_w), E_STREAM_PAGE_KEY));
gui_prefs_ok(gtk_object_get_data(GTK_OBJECT(parent_w), E_GUI_PAGE_KEY));
prefs_module_foreach(module_prefs_fetch, NULL);
prefs_module_foreach(module_prefs_fetch, &must_redissect);
prefs_apply_all();
prefs_module_foreach(module_prefs_clean, NULL);
gtk_widget_destroy(GTK_WIDGET(parent_w));
if (must_redissect) {
/* Redissect all the packets, and re-evaluate the display filter. */
redissect_packets(&cfile);
}
}
static void

View File

@ -2,7 +2,7 @@
* Definitions for implementation of preference handling routines;
* used by "friends" of the preferences type.
*
* $Id: prefs-int.h,v 1.1 2000/07/05 09:40:40 guy Exp $
* $Id: prefs-int.h,v 1.2 2000/07/09 03:29:27 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -33,6 +33,7 @@ struct pref_module {
void (*apply_cb)(void); /* routine to call when preferences applied */
GList *prefs; /* list of its preferences */
int numprefs; /* number of preferences */
gboolean prefs_changed; /* if TRUE, a preference has changed since we last checked */
};
typedef enum {

44
prefs.c
View File

@ -1,7 +1,7 @@
/* prefs.c
* Routines for handling preferences
*
* $Id: prefs.c,v 1.31 2000/07/05 09:40:41 guy Exp $
* $Id: prefs.c,v 1.32 2000/07/09 03:29:28 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -100,6 +100,7 @@ prefs_register_module(const char *name, const char *title,
module->apply_cb = apply_cb;
module->prefs = NULL; /* no preferences, to start */
module->numprefs = 0;
module->prefs_changed = FALSE;
modules = g_list_append(modules, module);
@ -161,11 +162,18 @@ call_apply_cb(gpointer data, gpointer user_data)
{
module_t *module = data;
(*module->apply_cb)();
if (module->prefs_changed) {
if (module->apply_cb != NULL)
(*module->apply_cb)();
module->prefs_changed = FALSE;
}
}
/*
* Call the "apply" callback function for each module.
* Call the "apply" callback function for each module if any of its
* preferences have changed, and then clear the flag saying its
* preferences have changed, as the module has been notified of that
* fact.
*/
void
prefs_apply_all(void)
@ -714,6 +722,8 @@ set_pref(gchar *pref_name, gchar *value)
fmt_data *cfmt;
unsigned long int cval;
guint uval;
gboolean bval;
gint enum_val;
char *p;
gchar *dotp;
module_t *module;
@ -836,27 +846,41 @@ set_pref(gchar *pref_name, gchar *value)
uval = strtoul(value, &p, pref->info.base);
if (p == value || *p != '\0')
return PREFS_SET_SYNTAX_ERR; /* number was bad */
*pref->varp.uint = uval;
if (*pref->varp.uint != uval) {
module->prefs_changed = TRUE;
*pref->varp.uint = uval;
}
break;
case PREF_BOOL:
/* XXX - give an error if it's neither "true" nor "false"? */
if (strcasecmp(value, "true") == 0)
*pref->varp.bool = TRUE;
bval = TRUE;
else
*pref->varp.bool = FALSE;
bval = FALSE;
if (*pref->varp.bool != bval) {
module->prefs_changed = TRUE;
*pref->varp.bool = bval;
}
break;
case PREF_ENUM:
/* XXX - give an error if it doesn't match? */
*pref->varp.enump = find_val_for_string(value,
enum_val = find_val_for_string(value,
pref->info.enum_info.enumvals, 1);
if (*pref->varp.enump != enum_val) {
module->prefs_changed = TRUE;
*pref->varp.enump = enum_val;
}
break;
case PREF_STRING:
if (*pref->varp.string != NULL)
g_free(*pref->varp.string);
*pref->varp.string = g_strdup(value);
if (*pref->varp.string == NULL || strcmp(*pref->varp.string, value) != 0) {
module->prefs_changed = TRUE;
if (*pref->varp.string != NULL)
g_free(*pref->varp.string);
*pref->varp.string = g_strdup(value);
}
break;
}
}

View File

@ -1,7 +1,7 @@
/* prefs.h
* Definitions for preference handling routines
*
* $Id: prefs.h,v 1.16 2000/07/05 09:40:42 guy Exp $
* $Id: prefs.h,v 1.17 2000/07/09 03:29:28 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -76,7 +76,10 @@ typedef void (*module_cb)(module_t *module, gpointer user_data);
void prefs_module_foreach(module_cb callback, gpointer user_data);
/*
* Call the "apply" callback function for each module.
* Call the "apply" callback function for each module if any of its
* preferences have changed, and then clear the flag saying its
* preferences have changed, as the module has been notified of that
* fact.
*/
void prefs_apply_all(void);

View File

@ -1,6 +1,6 @@
/* tethereal.c
*
* $Id: tethereal.c,v 1.34 2000/07/05 09:40:43 guy Exp $
* $Id: tethereal.c,v 1.35 2000/07/09 03:29:29 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@ -411,6 +411,11 @@ main(int argc, char *argv[])
}
}
/* Notify all registered modules that have had any of their preferences
changed either from one of the preferences file or from the command
line that its preferences have changed. */
prefs_apply_all();
#ifndef HAVE_LIBPCAP
if (capture_option_specified)
fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");