From 6537c76fb62d583eb5f98308c15ae31c1712a31a Mon Sep 17 00:00:00 2001 From: Gerald Combs Date: Fri, 15 Feb 2008 22:36:24 +0000 Subject: Extend the UAT and preferences code so that you can use the "-o" flag to override UAT entries from the command line, e.g. -o "uat:user_dlts:\"User 0 (DLT=147)\",\"http\",\"0\",\"\",\"0\",\"\"" Fix up white space. svn path=/trunk/; revision=24338 --- epan/prefs.c | 75 ++++++++++++++++++++++++++++++++++++-------- epan/uat.c | 25 +++++++++++++++ epan/uat.h | 96 +++++++++++++++++++++++++++++++++------------------------ epan/uat_load.l | 66 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 209 insertions(+), 53 deletions(-) (limited to 'epan') diff --git a/epan/prefs.c b/epan/prefs.c index babcaae1a0..6ba297f42a 100644 --- a/epan/prefs.c +++ b/epan/prefs.c @@ -316,7 +316,7 @@ prefs_register_protocol_subtree(const char *subtree, int id, void (*apply_cb)(vo if(!(new_module = find_subtree(subtree_module, ptr))) { /* create it */ new_module = prefs_register_subtree(subtree_module, ptr, NULL); - } + } subtree_module = new_module; ptr = sep; @@ -324,13 +324,13 @@ prefs_register_protocol_subtree(const char *subtree, int id, void (*apply_cb)(vo } /* g_free(csubtree); */ - + } protocol = find_protocol_by_id(id); return prefs_register_module(subtree_module, proto_get_protocol_filter_name(id), - proto_get_protocol_short_name(protocol), + proto_get_protocol_short_name(protocol), proto_get_protocol_name(id), apply_cb); } @@ -366,7 +366,7 @@ prefs_register_protocol_obsolete(int id) #if GLIB_MAJOR_VERSION < 2 static void *discard_const(const void *const_ptr) { - union { + union { const void *const_ptr; void *ptr; } stupid_const; @@ -429,8 +429,8 @@ prefs_module_list_foreach(emem_tree_t *module_list, module_cb callback, if (module_list == NULL) module_list = prefs_top_level_modules; - call_data.callback = callback; - call_data.user_data = user_data; + call_data.callback = callback; + call_data.user_data = user_data; call_data.ret = 0; pe_tree_foreach(module_list, call_foreach_cb, &call_data); return call_data.ret; @@ -476,7 +476,7 @@ prefs_modules_foreach(module_cb callback, gpointer user_data) * silently ignored in preference files. Does not ignore subtrees, * as this can be used when walking the display tree of modules. */ -guint +guint prefs_modules_foreach_submodules(module_t *module, module_cb callback, gpointer user_data) { return prefs_module_list_foreach((module)?module->submodules:prefs_top_level_modules, callback, user_data); @@ -765,9 +765,9 @@ extern void prefs_register_uat_preference(module_t *module, const char *title, const char *description, void* uat) { - + pref_t* preference = register_preference(module, name, title, description, PREF_UAT); - + preference->varp.uat = uat; } @@ -1078,7 +1078,7 @@ init_prefs(void) { return; uat_load_all(); - + prefs.pr_format = PR_FMT_TEXT; prefs.pr_dest = PR_DEST_CMD; prefs.pr_file = g_strdup("wireshark.out"); @@ -1282,7 +1282,7 @@ read_prefs(int *gpf_errno_return, int *gpf_read_errno_return, FILE *pf; init_prefs(); - + /* * If we don't already have the pathname of the global preferences * file, construct it. Then, in either case, try to open the file. @@ -1504,6 +1504,52 @@ read_prefs_file(const char *pf_path, FILE *pf, pref_set_pair_cb pref_set_pair_fc return 0; } +/* + * If we were handed a preference starting with "uat:", try to turn it into + * a valid uat entry. + */ +static gboolean +prefs_set_uat_pref(char *uat_entry) { + gchar *p, *colonp; + uat_t *uat; + gchar *err; + + colonp = strchr(uat_entry, ':'); + if (colonp == NULL) + return FALSE; + + p = colonp; + *p++ = '\0'; + + /* + * Skip over any white space (there probably won't be any, but + * as we allow it in the preferences file, we might as well + * allow it here). + */ + while (isspace((guchar)*p)) + p++; + if (*p == '\0') { + /* + * Put the colon back, so if our caller uses, in an + * error message, the string they passed us, the message + * looks correct. + */ + *colonp = ':'; + return FALSE; + } + + uat = uat_find(uat_entry); + *colonp = ':'; + if (uat == NULL) { + return FALSE; + } + + if (uat_load_str(uat, p, &err)) { + return TRUE; + } + return FALSE; +} + /* * Given a string of the form ":", as might appear * as an argument to a "-o" option, parse it and set the preference in @@ -1549,8 +1595,11 @@ prefs_set_pref(char *prefarg) *colonp = ':'; return PREFS_SET_SYNTAX_ERR; } - - ret = set_pref(prefarg, p, NULL); + if (strcmp(prefarg, "uat")) { + ret = set_pref(prefarg, p, NULL); + } else { + ret = prefs_set_uat_pref(p) ? PREFS_SET_OK : PREFS_SET_SYNTAX_ERR; + } *colonp = ':'; /* put the colon back */ return ret; } diff --git a/epan/uat.c b/epan/uat.c index 2935a08e0f..e94bb2d9bd 100644 --- a/epan/uat.c +++ b/epan/uat.c @@ -271,6 +271,19 @@ void uat_destroy(uat_t* uat) { } +uat_t *uat_find(gchar *name) { + guint i; + + for (i=0; i < all_uats->len; i++) { + uat_t* u = g_ptr_array_index(all_uats,i); + + if (strcmp(u->name, name) == 0 || strcmp(u->filename, name) == 0) { + return u; + } + } + return NULL; +} + void uat_clear(uat_t* uat) { guint i; @@ -595,3 +608,15 @@ CHK_STR_IS_DEF(isalnum) CHK_STR_IS_DEF(isdigit) CHK_STR_IS_DEF(isxdigit) +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=4 expandtab + * :indentSize=4:tabSize=4:noTabs=true: + */ diff --git a/epan/uat.h b/epan/uat.h index 942f9ca652..bc4f5495e7 100644 --- a/epan/uat.h +++ b/epan/uat.h @@ -5,23 +5,23 @@ * * User Accessible Tables * Mantain an array of user accessible data strucures - * + * * (c) 2007, Luis E. Garcia Ontanon * * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 2001 Gerald Combs - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. @@ -40,7 +40,7 @@ * the behaviour of the table is controlled by a series of callbacks * the caller must provide. * - * BEWARE that the user can change an uat at (almost) any time, + * BEWARE that the user can change an uat at (almost) any time, * That is pointers to records in an uat are valid only during the call * to the function that obtains them (do not store them). * @@ -96,7 +96,7 @@ typedef void (*uat_update_cb_t)(void* , const char** ); * the caller should provide one of these for every field! ********/ -/* +/* * given an input string (ptr, len) checks if the value is OK for a field in the record. * it will return TRUE if OK or else * it will return FALSE and may set *error to inform the user on what's @@ -125,18 +125,18 @@ typedef void (*uat_fld_set_cb_t)(void*, const char*, unsigned, void*, void*); */ typedef void (*uat_fld_tostr_cb_t)(void*, const char**, unsigned*, void*, void*); -/*********** +/*********** * Text Mode * * used for file and dialog representation of fileds in columns, - * when the file is read it modifies the way the value is passed back to the fld_set_cb + * when the file is read it modifies the way the value is passed back to the fld_set_cb * (see definition bellow for description) ***********/ typedef enum _uat_text_mode_t { PT_TXTMOD_NONE, /* not used */ - + PT_TXTMOD_STRING, /* file: @@ -179,21 +179,21 @@ typedef enum _uat_text_mode_t { typedef struct _uat_field_t { const char* name; uat_text_mode_t mode; - + struct { uat_fld_chk_cb_t chk; uat_fld_set_cb_t set; uat_fld_tostr_cb_t tostr; } cb; - + struct { void* chk; void* set; void* tostr; } cbdata; - + void* fld_data; - + const char* desc; struct _fld_data_t* priv; } uat_field_t; @@ -207,28 +207,18 @@ typedef struct _uat_field_t { #define UAT_CAT_CRYPTO "Decryption" #define UAT_CAT_FFMT "File Formats" -/* - * uat_new() - * - * creates a new uat - * - * name: the name of the table - * - * data_ptr: a pointer to a null terminated array of pointers to the data - * - * default_data: a pinter to a struct containing default values - * - * size: the size of the structure +/** Create a new uat * - * filename: the filename to be used (either in userdir or datadir) + * @param name The name of the table + * @param data_ptr A pointer to a null terminated array of pointers to the data + * @param default_data A pointer to a struct containing default values + * @param size The size of the structure + * @param filename The filename to be used (either in userdir or datadir) + * @param copy_cb A function that copies the data in the struct + * @param update_cb Will be called when a record is updated + * @param free_cb Will be called to destroy a struct in the dataset * - * copy_cb: a function that copies the data in the struct - * - * update_cb: will be called when a record is updated - * - * free_cb: will be called to destroy a struct in the dataset - * - * + * @return A freshly-allocated and populated uat_t struct. */ uat_t* uat_new(const char* name, size_t size, @@ -242,8 +232,34 @@ uat_t* uat_new(const char* name, uat_free_cb_t free_cb, uat_field_t* flds_array); +/** Populate a uat using its file. + * + * @param uat_in Pointer to a uat. Must not be NULL. + * @param err Upon failure, points to an error string. + * + * @return TRUE on success, FALSE on failure. + */ gboolean uat_load(uat_t* uat_in, char** err); +/** Create or update a single uat entry using a string. + * + * @param uat_in Pointer to a uat. Must not be NULL. + * @param entry The string representation of the entry. Format must match + * what's written to the uat's output file. + * @param err Upon failure, points to an error string. + * + * @return TRUE on success, FALSE on failure. + */ +gboolean uat_load_str(uat_t* uat_in, char* entry, char** err); + +/** Given a uat name or filename, find its pointer. + * + * @param name The name or filename of the uat + * + * @return A pointer to the uat on success, NULL on failure. + */ +uat_t *uat_find(gchar *name); + /* * uat_dup() * uat_se_dup() @@ -256,7 +272,7 @@ void* uat_se_dup(uat_t*, guint* len_p); uat_t* uat_get_table_by_name(const char* name); /* - * Some common uat_fld_chk_cbs + * Some common uat_fld_chk_cbs */ gboolean uat_fld_chk_str(void*, const char*, unsigned, void*,void*, const char** err); gboolean uat_fld_chk_proto(void*, const char*, unsigned, void*,void*, const char** err); @@ -361,7 +377,7 @@ static void basename ## _ ## field_name ## _tostr_cb(void* rec, const char** out /* * DEC Macros, - * a decimal number contained in + * a decimal number contained in */ #define UAT_DEC_CB_DEF(basename,field_name,rec_t) \ static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, void* u1 _U_, void* u2 _U_) {\ @@ -376,7 +392,7 @@ static void basename ## _ ## field_name ## _tostr_cb(void* rec, const char** out /* * HEX Macros, - * an hexadecimal number contained in + * an hexadecimal number contained in */ #define UAT_HEX_CB_DEF(basename,field_name,rec_t) \ static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, void* u1 _U_, void* u2 _U_) {\ @@ -391,8 +407,8 @@ static void basename ## _ ## field_name ## _tostr_cb(void* rec, const char** out /* * ENUM macros - * enum_t: name = ((enum_t*)ptr)->strptr - * value = ((enum_t*)ptr)->value + * enum_t: name = ((enum_t*)ptr)->strptr + * value = ((enum_t*)ptr)->value * rec_t: * value */ @@ -435,7 +451,7 @@ static void basename ## _ ## field_name ## _tostr_cb(void* rec, const char** out *out_ptr = (((rec_t*)rec)->name_field); \ *out_len = strlen(*out_ptr); \ } else { \ - *out_ptr = ""; *out_len = 0; } } + *out_ptr = ""; *out_len = 0; } } #define UAT_FLD_PROTO(basename,field_name,desc) \ @@ -454,7 +470,7 @@ static void basename ## _ ## field_name ## _tostr_cb(void* rec, const char** out if ( ((rec_t*)rec)->field_name ) { \ *out_ptr = range_convert_range(((rec_t*)rec)->field_name); *out_len = strlen(*out_ptr); \ } else { \ - *out_ptr = ""; *out_len = 0; } } + *out_ptr = ""; *out_len = 0; } } #define UAT_FLD_RANGE(basename,field_name,max,desc) \ diff --git a/epan/uat_load.l b/epan/uat_load.l index f5422e4cec..42593998d9 100644 --- a/epan/uat_load.l +++ b/epan/uat_load.l @@ -73,6 +73,8 @@ static gchar* error; static void* record; static guint linenum; + static gchar *parse_str; + static guint parse_str_pos; #define ERROR(fmtd) do { error = ep_strdup_printf("%s:%d: %s",uat->filename,linenum,ep_strdup_printf fmtd); yyterminate(); } while(0) @@ -97,6 +99,37 @@ #define DUMP_FIELD(s) #define DUMP(s) #endif + +/* Modified version of YY_INPUT generated by Flex 2.91 */ +#define YY_INPUT(buf,result,max_size) \ + if ( parse_str ) \ + { \ + int n = 0; \ + guint pslen = strlen(parse_str); \ + if (parse_str_pos < pslen) \ + { \ + n = pslen - parse_str_pos; \ + if (n > max_size) n = max_size; \ + memcpy(buf, parse_str + parse_str_pos, n); \ + parse_str_pos += n; \ + } \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + } + /* * XXX * quoted_string below fails badly on "...\\" @@ -246,6 +279,7 @@ gboolean uat_load(uat_t* uat_in, char** err) { gchar* fname = uat_get_actual_filename(uat_in, FALSE); uat = uat_in; + parse_str = NULL; if (!fname) { UAT_UPDATE(uat); @@ -281,3 +315,35 @@ gboolean uat_load(uat_t* uat_in, char** err) { return TRUE; } } + +gboolean uat_load_str(uat_t* uat_in, char* entry, char** err) { + uat = uat_in; + parse_str = g_strdup_printf("%s\n", entry); /* Records must end with a newline */ + parse_str_pos = 0; + yyin = NULL; + + error = NULL; + colnum = 0; + record = g_malloc0(uat->record_size); + linenum = 1; + + BEGIN START_OF_LINE; + DUMP(entry); + + yylex(); + yyrestart(NULL); + g_free(parse_str); + parse_str = NULL; + + uat->changed = TRUE; + uat->loaded = TRUE; + if (error) { + UAT_UPDATE(uat); + *err = ep_strdup(error); + return FALSE; + } else { + UAT_UPDATE(uat); + *err = NULL; + return TRUE; + } +} -- cgit v1.2.3