From d4b31cf98f85550155156726ad9f3424def07fb7 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 15 Jul 2009 10:02:49 -0400 Subject: [PATCH] Allow interval and memunit cfg variables to be set to fractions. --- ChangeLog | 3 +++ src/or/config.c | 55 +++++++++++++++++++++++++++++++++++-------------- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 30a776c29e..0ecf3d74b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -32,6 +32,9 @@ Changes in version 0.2.2.1-alpha - 2009-??-?? connecting clients to disk every 24 hours. To enable this, run configure with the --enable-entry-stats option, and set "EntryStatistics 1" in your torrc. + - Time and memory units in the configuration file can now be set to + fractional units. For example, "2.5 MB" is now a valid value for + AccountingMax. o Minor bugfixes - Hidden service clients didn't use a cached service descriptor that diff --git a/src/or/config.c b/src/or/config.c index 087a907e48..19212fe899 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -4791,30 +4791,55 @@ static struct unit_table_t time_units[] = { static uint64_t config_parse_units(const char *val, struct unit_table_t *u, int *ok) { - uint64_t v; - char *cp; + uint64_t v = 0; + double d = 0; + int use_float = 0; + + smartlist_t *sl; tor_assert(ok); + sl = smartlist_create(); + smartlist_split_string(sl, val, NULL, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 3); - v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp); - if (!*ok) - return 0; - if (!cp) { - *ok = 1; - return v; + if (smartlist_len(sl) < 1 || smartlist_len(sl) > 2) { + *ok = 0; + goto done; } - while (TOR_ISSPACE(*cp)) - ++cp; + + v = tor_parse_uint64(smartlist_get(sl,0), 10, 0, UINT64_MAX, ok, NULL); + if (!*ok) { + int r = sscanf(smartlist_get(sl,0), "%lf", &d); + if (r == 0 || d < 0) + goto done; + use_float = 1; + } + + if (smartlist_len(sl) == 1) { + *ok = 1; + v = use_float ? DBL_TO_U64(d) : v; + goto done; + } + for ( ;u->unit;++u) { - if (!strcasecmp(u->unit, cp)) { - v *= u->multiplier; + if (!strcasecmp(u->unit, smartlist_get(sl,1))) { + if (use_float) + v = u->multiplier * d; + else + v *= u->multiplier; *ok = 1; - return v; + goto done; } } - log_warn(LD_CONFIG, "Unknown unit '%s'.", cp); + log_warn(LD_CONFIG, "Unknown unit '%s'.", (char*)smartlist_get(sl,1)); *ok = 0; - return 0; + done: + SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp)); + smartlist_free(sl); + + if (*ok) + return v; + else + return 0; } /** Parse a string in the format "number unit", where unit is a unit of