Check the values of the protocol preferences before fetching them; if

any are not valid, pop up an alert box and don't dismiss the preferences
dialog.

svn path=/trunk/; revision=12269
This commit is contained in:
Guy Harris 2004-10-12 03:13:17 +00:00
parent 38ed258bc5
commit eb088099b0
3 changed files with 115 additions and 39 deletions

View File

@ -316,43 +316,39 @@ find_module(const char *name)
return (module_t *) list_entry->data; return (module_t *) list_entry->data;
} }
typedef struct {
module_cb callback;
gpointer user_data;
} module_cb_arg_t;
static void
do_module_callback(gpointer data, gpointer user_data)
{
module_t *module = data;
module_cb_arg_t *arg = user_data;
if (!module->obsolete)
(*arg->callback)(module, arg->user_data);
}
/* /*
* Call a callback function, with a specified argument, for each module * Call a callback function, with a specified argument, for each module
* in a list of modules. If the list is NULL, searches the top-level * in a list of modules. If the list is NULL, searches the top-level
* list in the display tree of modules. * list in the display tree of modules. If any callback returns a
* non-zero value, we stop and return that value, otherwise we
* return 0.
* *
* Ignores "obsolete" modules; their sole purpose is to allow old * Ignores "obsolete" modules; their sole purpose is to allow old
* preferences for dissectors that no longer have preferences to be * preferences for dissectors that no longer have preferences to be
* silently ignored in preference files. Does not ignore subtrees, * silently ignored in preference files. Does not ignore subtrees,
* as this can be used when walking the display tree of modules. * as this can be used when walking the display tree of modules.
*/ */
void guint
prefs_module_list_foreach(GList *module_list, module_cb callback, prefs_module_list_foreach(GList *module_list, module_cb callback,
gpointer user_data) gpointer user_data)
{ {
module_cb_arg_t arg; GList *elem;
module_t *module;
guint ret;
if (module_list == NULL) if (module_list == NULL)
module_list = top_level_modules; module_list = top_level_modules;
arg.callback = callback; for (elem = g_list_first(module_list); elem != NULL;
arg.user_data = user_data; elem = g_list_next(elem)) {
g_list_foreach(module_list, do_module_callback, &arg); module = elem->data;
if (!module->obsolete) {
ret = (*callback)(module, user_data);
if (ret != 0)
return ret;
}
}
return 0;
} }
/* /*
@ -363,10 +359,10 @@ prefs_module_list_foreach(GList *module_list, module_cb callback,
* preferences for dissectors that no longer have preferences to be * preferences for dissectors that no longer have preferences to be
* silently ignored in preference files. * silently ignored in preference files.
*/ */
void guint
prefs_modules_foreach(module_cb callback, gpointer user_data) prefs_modules_foreach(module_cb callback, gpointer user_data)
{ {
prefs_module_list_foreach(modules, callback, user_data); return prefs_module_list_foreach(modules, callback, user_data);
} }
static void static void

View File

@ -196,7 +196,7 @@ extern module_t *prefs_register_protocol_obsolete(int id);
/* /*
* Callback function for module list scanners. * Callback function for module list scanners.
*/ */
typedef void (*module_cb)(module_t *module, gpointer user_data); typedef guint (*module_cb)(module_t *module, gpointer user_data);
/* /*
* Call a callback function, with a specified argument, for each module * Call a callback function, with a specified argument, for each module
@ -208,7 +208,7 @@ typedef void (*module_cb)(module_t *module, gpointer user_data);
* silently ignored in preference files. Does not ignore subtrees, * silently ignored in preference files. Does not ignore subtrees,
* as this can be used when walking the display tree of modules. * as this can be used when walking the display tree of modules.
*/ */
extern void prefs_module_list_foreach(GList *module_list, module_cb callback, extern guint prefs_module_list_foreach(GList *module_list, module_cb callback,
gpointer user_data); gpointer user_data);
/* /*
@ -219,7 +219,7 @@ extern void prefs_module_list_foreach(GList *module_list, module_cb callback,
* preferences for dissectors that no longer have preferences to be * preferences for dissectors that no longer have preferences to be
* silently ignored in preference files. * silently ignored in preference files.
*/ */
extern void prefs_modules_foreach(module_cb callback, gpointer user_data); extern guint prefs_modules_foreach(module_cb callback, gpointer user_data);
/* /*
* Call the "apply" callback function for each module if any of its * Call the "apply" callback function for each module if any of its

View File

@ -213,7 +213,7 @@ pref_show(pref_t *pref, gpointer user_data)
#define MAX_TREE_NODE_NAME_LEN 64 #define MAX_TREE_NODE_NAME_LEN 64
/* show prefs page for each registered module (protocol) */ /* show prefs page for each registered module (protocol) */
static void static guint
module_prefs_show(module_t *module, gpointer user_data) module_prefs_show(module_t *module, gpointer user_data)
{ {
struct ct_struct *cts = user_data; struct ct_struct *cts = user_data;
@ -243,7 +243,7 @@ module_prefs_show(module_t *module, gpointer user_data)
* nothing under it that will be displayed, don't put it into * nothing under it that will be displayed, don't put it into
* the window. * the window.
*/ */
return; return 0;
} }
} }
@ -334,6 +334,8 @@ module_prefs_show(module_t *module, gpointer user_data)
/* Show 'em what we got */ /* Show 'em what we got */
gtk_widget_show_all(main_vb); gtk_widget_show_all(main_vb);
} }
return 0;
} }
@ -852,6 +854,53 @@ create_preference_entry(GtkWidget *main_tb, int table_position,
return entry; return entry;
} }
static guint
pref_check(pref_t *pref, gpointer user_data)
{
const char *str_val;
char *p;
guint uval;
pref_t **badpref = user_data;
/* Fetch the value of the preference, and check whether it's valid. */
switch (pref->type) {
case PREF_UINT:
str_val = gtk_entry_get_text(GTK_ENTRY(pref->control));
uval = strtoul(str_val, &p, pref->info.base);
if (p == str_val || *p != '\0') {
*badpref = pref;
return PREFS_SET_SYNTAX_ERR; /* number was bad */
}
break;
case PREF_BOOL:
/* Value can't be bad. */
break;
case PREF_ENUM:
/* Value can't be bad. */
break;
case PREF_STRING:
/* Value can't be bad. */
break;
case PREF_OBSOLETE:
g_assert_not_reached();
break;
}
return 0;
}
static guint
module_prefs_check(module_t *module, gpointer user_data)
{
/* For all preferences in this module, fetch its value from this
module's notebook page and check whether it's valid. */
return prefs_pref_foreach(module, pref_check, user_data);
}
static guint static guint
pref_fetch(pref_t *pref, gpointer user_data) pref_fetch(pref_t *pref, gpointer user_data)
{ {
@ -918,7 +967,7 @@ pref_fetch(pref_t *pref, gpointer user_data)
return 0; return 0;
} }
static void static guint
module_prefs_fetch(module_t *module, gpointer user_data) module_prefs_fetch(module_t *module, gpointer user_data)
{ {
gboolean *must_redissect_p = user_data; gboolean *must_redissect_p = user_data;
@ -933,6 +982,8 @@ module_prefs_fetch(module_t *module, gpointer user_data)
could cause packets to be dissected differently. */ could cause packets to be dissected differently. */
if (module->prefs_changed) if (module->prefs_changed)
*must_redissect_p = TRUE; *must_redissect_p = TRUE;
return 0; /* keep fetching module preferences */
} }
static guint static guint
@ -963,19 +1014,40 @@ pref_clean(pref_t *pref, gpointer user_data _U_)
return 0; return 0;
} }
static void static guint
module_prefs_clean(module_t *module, gpointer user_data _U_) module_prefs_clean(module_t *module, gpointer user_data _U_)
{ {
/* For all preferences in this module, clean up any cruft allocated for /* For all preferences in this module, clean up any cruft allocated for
use by the GUI code. */ use by the GUI code. */
prefs_pref_foreach(module, pref_clean, NULL); prefs_pref_foreach(module, pref_clean, NULL);
return 0; /* keep cleaning modules */
} }
/* fetch all pref values from all pages */ /* fetch all pref values from all pages */
static void static gboolean
prefs_main_fetch_all(GtkWidget *dlg, gboolean *must_redissect) prefs_main_fetch_all(GtkWidget *dlg, gboolean *must_redissect)
{ {
pref_t *badpref;
/* First, check that the values are all valid. */
/* XXX - check the non-registered preferences too */
switch (prefs_modules_foreach(module_prefs_check, (gpointer)&badpref)) {
case PREFS_SET_SYNTAX_ERR:
switch (badpref->type) {
case PREF_UINT:
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
"The value for \"%s\" is not a valid number.",
badpref->title);
return FALSE;
default:
g_assert_not_reached();
break;
}
}
/* Fetch the preferences (i.e., make sure all the values set in all of /* Fetch the preferences (i.e., make sure all the values set in all of
the preferences panes have been copied to "prefs" and the registered the preferences panes have been copied to "prefs" and the registered
preferences). */ preferences). */
@ -998,8 +1070,9 @@ prefs_main_fetch_all(GtkWidget *dlg, gboolean *must_redissect)
nameres_prefs_fetch(OBJECT_GET_DATA(dlg, E_NAMERES_PAGE_KEY)); nameres_prefs_fetch(OBJECT_GET_DATA(dlg, E_NAMERES_PAGE_KEY));
prefs_modules_foreach(module_prefs_fetch, must_redissect); prefs_modules_foreach(module_prefs_fetch, must_redissect);
}
return TRUE;
}
/* apply all pref values to the real world */ /* apply all pref values to the real world */
static void static void
@ -1066,7 +1139,8 @@ prefs_main_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w)
{ {
gboolean must_redissect = FALSE; gboolean must_redissect = FALSE;
prefs_main_fetch_all(parent_w, &must_redissect); if (!prefs_main_fetch_all(parent_w, &must_redissect))
return; /* Errors in some preference setting */
prefs_main_apply_all(parent_w); prefs_main_apply_all(parent_w);
@ -1084,7 +1158,8 @@ prefs_main_apply_cb(GtkWidget *apply_bt _U_, gpointer parent_w)
{ {
gboolean must_redissect = FALSE; gboolean must_redissect = FALSE;
prefs_main_fetch_all(parent_w, &must_redissect); if (!prefs_main_fetch_all(parent_w, &must_redissect))
return; /* Errors in some preference setting */
prefs_main_apply_all(parent_w); prefs_main_apply_all(parent_w);
@ -1102,7 +1177,8 @@ prefs_main_save_cb(GtkWidget *save_bt _U_, gpointer parent_w)
char *pf_dir_path; char *pf_dir_path;
char *pf_path; char *pf_path;
prefs_main_fetch_all(parent_w, &must_redissect); if (!prefs_main_fetch_all(parent_w, &must_redissect))
return; /* Errors in some preference setting */
/* Create the directory that holds personal configuration files, if /* Create the directory that holds personal configuration files, if
necessary. */ necessary. */
@ -1188,7 +1264,7 @@ pref_revert(pref_t *pref, gpointer user_data)
return 0; return 0;
} }
static void static guint
module_prefs_revert(module_t *module, gpointer user_data) module_prefs_revert(module_t *module, gpointer user_data)
{ {
gboolean *must_redissect_p = user_data; gboolean *must_redissect_p = user_data;
@ -1204,6 +1280,7 @@ module_prefs_revert(module_t *module, gpointer user_data)
could cause packets to be dissected differently. */ could cause packets to be dissected differently. */
if (module->prefs_changed) if (module->prefs_changed)
*must_redissect_p = TRUE; *must_redissect_p = TRUE;
return 0; /* keep processing modules */
} }
/* cancel button pressed, revert prefs to saved and exit dialog */ /* cancel button pressed, revert prefs to saved and exit dialog */
@ -1256,14 +1333,17 @@ struct properties_data {
module_t *module; module_t *module;
}; };
static void static guint
module_search_properties(module_t *module, gpointer user_data) module_search_properties(module_t *module, gpointer user_data)
{ {
struct properties_data *p = (struct properties_data *)user_data; struct properties_data *p = (struct properties_data *)user_data;
/* If this module has the specified title, remember it. */ /* If this module has the specified title, remember it. */
if (strcmp(module->title, p->title) == 0) if (strcmp(module->title, p->title) == 0) {
p->module = module; p->module = module;
return 1; /* stops the search */
}
return 0;
} }
void void