X-Git-Url: http://git.samba.org/samba.git/?p=obnox%2Fwireshark%2Fwip.git;a=blobdiff_plain;f=prefs.c;h=e1631c82f2cf3aaff4f4611fc36d78bc25c5ecd9;hp=ce77fe262579fa20e1074e51beda537203ccdbb3;hb=95077f6a6fe6e2052c168d99ea6f70af0de1a47b;hpb=6e04d82e435b3c934767b52d18bc3f267d001adb diff --git a/prefs.c b/prefs.c index ce77fe2625..e1631c82f2 100644 --- a/prefs.c +++ b/prefs.c @@ -1,12 +1,11 @@ /* prefs.c * Routines for handling preferences * - * $Id: prefs.c,v 1.49 2001/04/13 14:59:28 jfoster Exp $ + * $Id: prefs.c,v 1.56 2001/07/22 21:56:25 guy Exp $ * * Ethereal - Network traffic analyzer - * By Gerald Combs + * By Gerald Combs * Copyright 1998 Gerald Combs - * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -369,53 +368,125 @@ prefs_register_modules(void) { } -/* Parse through a list of comma-separated, quoted strings. Return a - list of the string data */ +/* Parse through a list of comma-separated, possibly quoted strings. + Return a list of the string data. */ static GList * -get_string_list(gchar *str) { - enum { PRE_QUOT, IN_QUOT, POST_QUOT }; - - gint state = PRE_QUOT, i = 0, j = 0; - gboolean backslash = FALSE; +get_string_list(gchar *str) +{ + gint i = 0, j = 0; + gboolean in_quot = FALSE, backslash = FALSE; gchar cur_c, *slstr = NULL; GList *sl = NULL; - - while ((cur_c = str[i]) != '\0') { + + /* Allocate a buffer for the first string. */ + slstr = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN); + j = 0; + + for (;;) { + cur_c = str[i]; + if (cur_c == '\0') { + /* It's the end of the input, so it's the end of the string we + were working on, and there's no more input. */ + if (in_quot || backslash) { + /* We were in the middle of a quoted string or backslash escape, + and ran out of characters; that's an error. */ + g_free(slstr); + clear_string_list(sl); + return NULL; + } + slstr[j] = '\0'; + sl = g_list_append(sl, slstr); + break; + } if (cur_c == '"' && ! backslash) { - switch (state) { - case PRE_QUOT: - state = IN_QUOT; - slstr = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN); - j = 0; - break; - case IN_QUOT: - state = POST_QUOT; - slstr[j] = '\0'; - sl = g_list_append(sl, slstr); - break; - case POST_QUOT: - clear_string_list(sl); - return NULL; - break; - default: - break; + if (!in_quot) { + /* We're not in the middle of a quoted string, and we saw a + quotation mark; we're now quoting. */ + in_quot = TRUE; + } else { + /* We're in the middle of a quoted string, and we saw a quotation + mark; we're no longer quoting. */ + in_quot = FALSE; } } else if (cur_c == '\\' && ! backslash) { + /* We saw a backslash, and the previous character wasn't a + backslash; escape the next character. */ backslash = TRUE; - } else if (cur_c == ',' && state == POST_QUOT) { - state = PRE_QUOT; - } else if (state == IN_QUOT && j < COL_MAX_LEN) { - slstr[j] = str[i]; - j++; + } else if (cur_c == ',' && ! in_quot && ! backslash) { + /* We saw a comma, and we're not in the middle of a quoted string + and it wasn't preceded by a backslash; it's the end of + the string we were working on... */ + slstr[j] = '\0'; + sl = g_list_append(sl, slstr); + + /* ...and the beginning of a new string. */ + slstr = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN); + j = 0; + } else { + /* It's a character to be put into a string; do so if there's room. */ + if (j < COL_MAX_LEN) { + slstr[j] = cur_c; + j++; + } + + /* If it was backslash-escaped, we're done with the backslash escape. */ + backslash = FALSE; } i++; } - if (state != POST_QUOT) { - clear_string_list(sl); - } return(sl); } +/* XXX - needs to handle quote marks inside the quoted string, by + backslash-escaping them. */ +#define MAX_FMT_PREF_LEN 1024 +#define MAX_FMT_PREF_LINE_LEN 60 +static gchar * +put_string_list(GList *sl) +{ + static gchar pref_str[MAX_FMT_PREF_LEN] = ""; + GList *clp = g_list_first(sl); + fmt_data *cfmt; + int cur_pos = 0, cur_len = 0, fmt_len; + + while (clp) { + cfmt = (fmt_data *) clp->data; + + fmt_len = strlen(cfmt->title) + 4; + if ((fmt_len + cur_len) < (MAX_FMT_PREF_LEN - 1)) { + if ((fmt_len + cur_pos) > MAX_FMT_PREF_LINE_LEN) { + cur_len--; + cur_pos = 0; + pref_str[cur_len] = '\n'; cur_len++; + pref_str[cur_len] = '\t'; cur_len++; + } + sprintf(&pref_str[cur_len], "\"%s\", ", cfmt->title); + cur_len += fmt_len; + cur_pos += fmt_len; + } + + fmt_len = strlen(cfmt->fmt) + 4; + if ((fmt_len + cur_len) < (MAX_FMT_PREF_LEN - 1)) { + if ((fmt_len + cur_pos) > MAX_FMT_PREF_LINE_LEN) { + cur_len--; + cur_pos = 0; + pref_str[cur_len] = '\n'; cur_len++; + pref_str[cur_len] = '\t'; cur_len++; + } + sprintf(&pref_str[cur_len], "\"%s\", ", cfmt->fmt); + cur_len += fmt_len; + cur_pos += fmt_len; + } + + clp = clp->next; + } + + if (cur_len > 2) + pref_str[cur_len - 2] = '\0'; + + return(pref_str); +} + void clear_string_list(GList *sl) { GList *l = sl; @@ -612,11 +683,10 @@ read_prefs(int *gpf_errno_return, char **gpf_path_return, prefs.gui_marked_bg.blue = 0; /* set the default values for the capture dialog box */ - prefs.capture_prom_mode = 0; - prefs.capture_real_time = 0; - prefs.capture_auto_scroll = 0; - prefs.capture_name_resolve= 1; - + prefs.capture_prom_mode = TRUE; + prefs.capture_real_time = FALSE; + prefs.capture_auto_scroll = FALSE; + prefs.name_resolve = PREFS_RESOLV_ALL; } /* Read the global preferences file, if it exists. */ @@ -851,11 +921,20 @@ prefs_set_pref(char *prefarg) #define PRS_GUI_MARKED_FG "gui.marked_frame.fg" #define PRS_GUI_MARKED_BG "gui.marked_frame.bg" +/* + * This applies to more than just captures, so it's not "capture.name_resolve"; + * "capture.name_resolve" is supported on input for backwards compatibility. + * + * It's not a preference for a particular part of Ethereal, it's used all + * over the place, so its name doesn't have two components. + */ +#define PRS_NAME_RESOLVE "name_resolve" +#define PRS_CAP_NAME_RESOLVE "capture.name_resolve" + /* values for the capture dialog box */ #define PRS_CAP_REAL_TIME "capture.real_time_update" #define PRS_CAP_PROM_MODE "capture.prom_mode" #define PRS_CAP_AUTO_SCROLL "capture.auto_scroll" -#define PRS_CAP_NAME_RESOLVE "capture.name_resolve" #define RED_COMPONENT(x) ((((x) >> 16) & 0xff) * 65535 / 255) #define GREEN_COMPONENT(x) ((((x) >> 8) & 0xff) * 65535 / 255) @@ -864,10 +943,70 @@ prefs_set_pref(char *prefarg) static gchar *pr_formats[] = { "text", "postscript" }; static gchar *pr_dests[] = { "command", "file" }; +typedef struct { + char letter; + guint32 value; +} name_resolve_opt_t; + +static name_resolve_opt_t name_resolve_opt[] = { + { 'm', PREFS_RESOLV_MAC }, + { 'n', PREFS_RESOLV_NETWORK }, + { 't', PREFS_RESOLV_TRANSPORT }, +}; + +#define N_NAME_RESOLVE_OPT (sizeof name_resolve_opt / sizeof name_resolve_opt[0]) + +static char * +name_resolve_to_string(guint32 name_resolve) +{ + static char string[N_NAME_RESOLVE_OPT+1]; + char *p; + unsigned int i; + gboolean all_opts_set = TRUE; + + if (name_resolve == PREFS_RESOLV_NONE) + return "FALSE"; + p = &string[0]; + for (i = 0; i < N_NAME_RESOLVE_OPT; i++) { + if (name_resolve & name_resolve_opt[i].value) + *p++ = name_resolve_opt[i].letter; + else + all_opts_set = FALSE; + } + *p = '\0'; + if (all_opts_set) + return "TRUE"; + return string; +} + +char +string_to_name_resolve(char *string, guint32 *name_resolve) +{ + char c; + unsigned int i; + + *name_resolve = 0; + while ((c = *string++) != '\0') { + for (i = 0; i < N_NAME_RESOLVE_OPT; i++) { + if (c == name_resolve_opt[i].letter) { + *name_resolve |= name_resolve_opt[i].value; + break; + } + } + if (i == N_NAME_RESOLVE_OPT) { + /* + * Unrecognized letter. + */ + return c; + } + } + return '\0'; +} + static int set_pref(gchar *pref_name, gchar *value) { - GList *col_l; + GList *col_l, *col_l_elt; gint llen; fmt_data *cfmt; unsigned long int cval; @@ -902,21 +1041,49 @@ set_pref(gchar *pref_name, gchar *value) if (prefs.pr_cmd) g_free(prefs.pr_cmd); prefs.pr_cmd = g_strdup(value); } else if (strcmp(pref_name, PRS_COL_FMT) == 0) { - if ((col_l = get_string_list(value)) && (g_list_length(col_l) % 2) == 0) { - free_col_info(&prefs); - prefs.col_list = NULL; - llen = g_list_length(col_l); - prefs.num_cols = llen / 2; - col_l = g_list_first(col_l); - while(col_l) { - cfmt = (fmt_data *) g_malloc(sizeof(fmt_data)); - cfmt->title = g_strdup(col_l->data); - col_l = col_l->next; - cfmt->fmt = g_strdup(col_l->data); - col_l = col_l->next; - prefs.col_list = g_list_append(prefs.col_list, cfmt); + col_l = get_string_list(value); + if (col_l == NULL) + return PREFS_SET_SYNTAX_ERR; + if ((g_list_length(col_l) % 2) != 0) { + /* A title didn't have a matching format. */ + clear_string_list(col_l); + return PREFS_SET_SYNTAX_ERR; + } + /* Check to make sure all column formats are valid. */ + col_l_elt = g_list_first(col_l); + while(col_l_elt) { + /* Make sure the title isn't empty. */ + if (strcmp(col_l_elt->data, "") == 0) { + /* It is. */ + clear_string_list(col_l); + return PREFS_SET_SYNTAX_ERR; } - /* To do: else print some sort of error? */ + + /* Go past the title. */ + col_l_elt = col_l_elt->next; + + /* Check the format. */ + if (get_column_format_from_str(col_l_elt->data) == -1) { + /* It's not a valid column format. */ + clear_string_list(col_l); + return PREFS_SET_SYNTAX_ERR; + } + + /* Go past the format. */ + col_l_elt = col_l_elt->next; + } + free_col_info(&prefs); + prefs.col_list = NULL; + llen = g_list_length(col_l); + prefs.num_cols = llen / 2; + col_l_elt = g_list_first(col_l); + while(col_l_elt) { + cfmt = (fmt_data *) g_malloc(sizeof(fmt_data)); + cfmt->title = g_strdup(col_l_elt->data); + col_l_elt = col_l_elt->next; + cfmt->fmt = g_strdup(col_l_elt->data); + col_l_elt = col_l_elt->next; + prefs.col_list = g_list_append(prefs.col_list, cfmt); } clear_string_list(col_l); } else if (strcmp(pref_name, PRS_STREAM_CL_FG) == 0) { @@ -944,21 +1111,21 @@ set_pref(gchar *pref_name, gchar *value) prefs.st_server_bg.green = GREEN_COMPONENT(cval); prefs.st_server_bg.blue = BLUE_COMPONENT(cval); } else if (strcmp(pref_name, PRS_GUI_SCROLLBAR_ON_RIGHT) == 0) { - if (strcmp(value, "TRUE") == 0) { + if (strcasecmp(value, "true") == 0) { prefs.gui_scrollbar_on_right = TRUE; } else { prefs.gui_scrollbar_on_right = FALSE; } } else if (strcmp(pref_name, PRS_GUI_PLIST_SEL_BROWSE) == 0) { - if (strcmp(value, "TRUE") == 0) { + if (strcasecmp(value, "true") == 0) { prefs.gui_plist_sel_browse = TRUE; } else { prefs.gui_plist_sel_browse = FALSE; } } else if (strcmp(pref_name, PRS_GUI_PTREE_SEL_BROWSE) == 0) { - if (strcmp(value, "TRUE") == 0) { + if (strcasecmp(value, "true") == 0) { prefs.gui_ptree_sel_browse = TRUE; } else { @@ -992,17 +1159,32 @@ set_pref(gchar *pref_name, gchar *value) /* handle the capture options */ } else if (strcmp(pref_name, PRS_CAP_PROM_MODE) == 0) { - prefs.capture_prom_mode = ((strcmp(value, "TRUE") == 0)?TRUE:FALSE); + prefs.capture_prom_mode = ((strcasecmp(value, "true") == 0)?TRUE:FALSE); } else if (strcmp(pref_name, PRS_CAP_REAL_TIME) == 0) { - prefs.capture_real_time = ((strcmp(value, "TRUE") == 0)?TRUE:FALSE); + prefs.capture_real_time = ((strcasecmp(value, "true") == 0)?TRUE:FALSE); } else if (strcmp(pref_name, PRS_CAP_AUTO_SCROLL) == 0) { - prefs.capture_auto_scroll = ((strcmp(value, "TRUE") == 0)?TRUE:FALSE); + prefs.capture_auto_scroll = ((strcasecmp(value, "true") == 0)?TRUE:FALSE); - } else if (strcmp(pref_name, PRS_CAP_NAME_RESOLVE) == 0) { - prefs.capture_name_resolve = ((strcmp(value, "TRUE") == 0)?TRUE:FALSE); - +/* handle the global options */ + } else if (strcmp(pref_name, PRS_NAME_RESOLVE) == 0 || + strcmp(pref_name, PRS_CAP_NAME_RESOLVE) == 0) { + /* + * "TRUE" and "FALSE", for backwards compatibility, are synonyms for + * PREFS_RESOLV_ALL and PREFS_RESOLV_NONE. + * + * Otherwise, we treat it as a list of name types we want to resolve. + */ + if (strcasecmp(value, "true") == 0) + prefs.name_resolve = PREFS_RESOLV_ALL; + else if (strcasecmp(value, "false") == 0) + prefs.name_resolve = PREFS_RESOLV_NONE; + else { + prefs.name_resolve = PREFS_RESOLV_NONE; /* start out with none set */ + if (string_to_name_resolve(value, &prefs.name_resolve) != '\0') + return PREFS_SET_SYNTAX_ERR; + } } else { /* To which module does this preference belong? */ dotp = strchr(pref_name, '.'); @@ -1268,7 +1450,7 @@ write_prefs(char **pf_path_return) fprintf (pf, "# Packet list column format. Each pair of strings consists " "of a column title \n# and its format.\n" - "%s: %s\n\n", PRS_COL_FMT, col_format_to_pref_str()); + "%s: %s\n\n", PRS_COL_FMT, put_string_list(prefs.col_list)); fprintf (pf, "# TCP stream window color preferences. Each value is a six " "digit hexadecimal value in the form rrggbb.\n"); @@ -1327,6 +1509,10 @@ write_prefs(char **pf_path_return) (prefs.gui_marked_bg.green * 255 / 65535), (prefs.gui_marked_bg.blue * 255 / 65535)); + fprintf(pf, "\n# Resolve addresses to names? TRUE/FALSE/{list of address types to resolve}\n"); + fprintf(pf, PRS_NAME_RESOLVE ": %s\n", + name_resolve_to_string(prefs.name_resolve)); + /* write the capture options */ fprintf(pf, "\n# Capture in promiscuous mode? TRUE/FALSE\n"); fprintf(pf, PRS_CAP_PROM_MODE ": %s\n", @@ -1340,10 +1526,6 @@ write_prefs(char **pf_path_return) fprintf(pf, PRS_CAP_AUTO_SCROLL ": %s\n", prefs.capture_auto_scroll == TRUE ? "TRUE" : "FALSE"); - fprintf(pf, "\n# resolve names during capture? TRUE/FALSE\n"); - fprintf(pf, PRS_CAP_NAME_RESOLVE ": %s\n", - prefs.capture_name_resolve == TRUE ? "TRUE" : "FALSE"); - g_list_foreach(modules, write_module_prefs, pf); fclose(pf); @@ -1392,7 +1574,7 @@ copy_prefs(e_prefs *dest, e_prefs *src) dest->capture_prom_mode = src->capture_prom_mode; dest->capture_real_time = src->capture_real_time; dest->capture_auto_scroll = src->capture_auto_scroll; - dest->capture_name_resolve = src->capture_name_resolve; + dest->name_resolve = src->name_resolve; }