aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2008-02-15 22:36:24 +0000
committerGerald Combs <gerald@wireshark.org>2008-02-15 22:36:24 +0000
commit6537c76fb62d583eb5f98308c15ae31c1712a31a (patch)
tree8865e9d95e6828e9a2ca528a96d3c7d08ff80943 /epan
parenteba80d5c38f495d1943355f8f5a439c1ab3d99d0 (diff)
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
Diffstat (limited to 'epan')
-rw-r--r--epan/prefs.c75
-rw-r--r--epan/uat.c25
-rw-r--r--epan/uat.h96
-rw-r--r--epan/uat_load.l66
4 files changed, 209 insertions, 53 deletions
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.
@@ -1505,6 +1505,52 @@ read_prefs_file(const char *pf_path, FILE *pf, pref_set_pair_cb pref_set_pair_fc
}
/*
+ * 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 "<pref name>:<pref value>", as might appear
* as an argument to a "-o" option, parse it and set the preference in
* question. Return an indication of whether it succeeded or failed
@@ -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 <luis.ontanon@gmail.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* 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;
+ }
+}