Commit 458da8a8 authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

Move unit-parsing code to src/lib/confmgt

lib/confmgt is at a higher level than lib/conf, since it needs to
call down to logging and similar modules.
parent 246599ab
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -162,6 +162,8 @@ uptime-*.json
/src/lib/libtor-buf-testing.a
/src/lib/libtor-compress.a
/src/lib/libtor-compress-testing.a
/src/lib/libtor-confmgt.a
/src/lib/libtor-confmgt-testing.a
/src/lib/libtor-container.a
/src/lib/libtor-container-testing.a
/src/lib/libtor-crypt-ops.a
+2 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ TOR_UTIL_LIBS = \
	src/lib/libtor-math.a \
	src/lib/libtor-meminfo.a \
	src/lib/libtor-osinfo.a \
	src/lib/libtor-confmgt.a \
	src/lib/libtor-log.a \
	src/lib/libtor-lock.a \
	src/lib/libtor-fdio.a \
@@ -88,6 +89,7 @@ TOR_UTIL_TESTING_LIBS = \
	src/lib/libtor-meminfo-testing.a \
	src/lib/libtor-osinfo-testing.a \
	src/lib/libtor-term-testing.a \
	src/lib/libtor-confmgt-testing.a \
	src/lib/libtor-log-testing.a \
	src/lib/libtor-lock-testing.a \
	src/lib/libtor-fdio-testing.a \
+1 −193
Original line number Diff line number Diff line
@@ -26,12 +26,10 @@
#include "app/config/confparse.h"
#include "feature/nodelist/routerset.h"

#include "lib/confmgt/unitparse.h"
#include "lib/container/bitarray.h"
#include "lib/encoding/confline.h"

static uint64_t config_parse_memunit(const char *s, int *ok);
static int config_parse_msec_interval(const char *s, int *ok);
static int config_parse_interval(const char *s, int *ok);
static void config_reset(const config_format_t *fmt, void *options,
                         const config_var_t *var, int use_defaults);

@@ -1014,193 +1012,3 @@ config_dump(const config_format_t *fmt, const void *default_options,
  }
  return result;
}

/** Mapping from a unit name to a multiplier for converting that unit into a
 * base unit.  Used by config_parse_unit. */
struct unit_table_t {
  const char *unit; /**< The name of the unit */
  uint64_t multiplier; /**< How many of the base unit appear in this unit */
};

/** Table to map the names of memory units to the number of bytes they
 * contain. */
static struct unit_table_t memory_units[] = {
  { "",          1 },
  { "b",         1<< 0 },
  { "byte",      1<< 0 },
  { "bytes",     1<< 0 },
  { "kb",        1<<10 },
  { "kbyte",     1<<10 },
  { "kbytes",    1<<10 },
  { "kilobyte",  1<<10 },
  { "kilobytes", 1<<10 },
  { "kilobits",  1<<7  },
  { "kilobit",   1<<7  },
  { "kbits",     1<<7  },
  { "kbit",      1<<7  },
  { "m",         1<<20 },
  { "mb",        1<<20 },
  { "mbyte",     1<<20 },
  { "mbytes",    1<<20 },
  { "megabyte",  1<<20 },
  { "megabytes", 1<<20 },
  { "megabits",  1<<17 },
  { "megabit",   1<<17 },
  { "mbits",     1<<17 },
  { "mbit",      1<<17 },
  { "gb",        1<<30 },
  { "gbyte",     1<<30 },
  { "gbytes",    1<<30 },
  { "gigabyte",  1<<30 },
  { "gigabytes", 1<<30 },
  { "gigabits",  1<<27 },
  { "gigabit",   1<<27 },
  { "gbits",     1<<27 },
  { "gbit",      1<<27 },
  { "tb",        UINT64_C(1)<<40 },
  { "tbyte",     UINT64_C(1)<<40 },
  { "tbytes",    UINT64_C(1)<<40 },
  { "terabyte",  UINT64_C(1)<<40 },
  { "terabytes", UINT64_C(1)<<40 },
  { "terabits",  UINT64_C(1)<<37 },
  { "terabit",   UINT64_C(1)<<37 },
  { "tbits",     UINT64_C(1)<<37 },
  { "tbit",      UINT64_C(1)<<37 },
  { NULL, 0 },
};

/** Table to map the names of time units to the number of seconds they
 * contain. */
static struct unit_table_t time_units[] = {
  { "",         1 },
  { "second",   1 },
  { "seconds",  1 },
  { "minute",   60 },
  { "minutes",  60 },
  { "hour",     60*60 },
  { "hours",    60*60 },
  { "day",      24*60*60 },
  { "days",     24*60*60 },
  { "week",     7*24*60*60 },
  { "weeks",    7*24*60*60 },
  { "month",    2629728, }, /* about 30.437 days */
  { "months",   2629728, },
  { NULL, 0 },
};

/** Table to map the names of time units to the number of milliseconds
 * they contain. */
static struct unit_table_t time_msec_units[] = {
  { "",         1 },
  { "msec",     1 },
  { "millisecond", 1 },
  { "milliseconds", 1 },
  { "second",   1000 },
  { "seconds",  1000 },
  { "minute",   60*1000 },
  { "minutes",  60*1000 },
  { "hour",     60*60*1000 },
  { "hours",    60*60*1000 },
  { "day",      24*60*60*1000 },
  { "days",     24*60*60*1000 },
  { "week",     7*24*60*60*1000 },
  { "weeks",    7*24*60*60*1000 },
  { NULL, 0 },
};

/** Parse a string <b>val</b> containing a number, zero or more
 * spaces, and an optional unit string.  If the unit appears in the
 * table <b>u</b>, then multiply the number by the unit multiplier.
 * On success, set *<b>ok</b> to 1 and return this product.
 * Otherwise, set *<b>ok</b> to 0.
 */
static uint64_t
config_parse_units(const char *val, struct unit_table_t *u, int *ok)
{
  uint64_t v = 0;
  double d = 0;
  int use_float = 0;
  char *cp;

  tor_assert(ok);

  v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
  if (!*ok || (cp && *cp == '.')) {
    d = tor_parse_double(val, 0, (double)UINT64_MAX, ok, &cp);
    if (!*ok)
      goto done;
    use_float = 1;
  }

  if (!cp) {
    *ok = 1;
    v = use_float ? ((uint64_t)d) :  v;
    goto done;
  }

  cp = (char*) eat_whitespace(cp);

  for ( ;u->unit;++u) {
    if (!strcasecmp(u->unit, cp)) {
      if (use_float)
        v = (uint64_t)(u->multiplier * d);
      else
        v *= u->multiplier;
      *ok = 1;
      goto done;
    }
  }
  log_warn(LD_CONFIG, "Unknown unit '%s'.", cp);
  *ok = 0;
 done:

  if (*ok)
    return v;
  else
    return 0;
}

/** Parse a string in the format "number unit", where unit is a unit of
 * information (byte, KB, M, etc).  On success, set *<b>ok</b> to true
 * and return the number of bytes specified.  Otherwise, set
 * *<b>ok</b> to false and return 0. */
static uint64_t
config_parse_memunit(const char *s, int *ok)
{
  uint64_t u = config_parse_units(s, memory_units, ok);
  return u;
}

/** Parse a string in the format "number unit", where unit is a unit of
 * time in milliseconds.  On success, set *<b>ok</b> to true and return
 * the number of milliseconds in the provided interval.  Otherwise, set
 * *<b>ok</b> to 0 and return -1. */
static int
config_parse_msec_interval(const char *s, int *ok)
{
  uint64_t r;
  r = config_parse_units(s, time_msec_units, ok);
  if (r > INT_MAX) {
    log_warn(LD_CONFIG, "Msec interval '%s' is too long", s);
    *ok = 0;
    return -1;
  }
  return (int)r;
}

/** Parse a string in the format "number unit", where unit is a unit of time.
 * On success, set *<b>ok</b> to true and return the number of seconds in
 * the provided interval.  Otherwise, set *<b>ok</b> to 0 and return -1.
 */
static int
config_parse_interval(const char *s, int *ok)
{
  uint64_t r;
  r = config_parse_units(s, time_units, ok);
  if (r > INT_MAX) {
    log_warn(LD_CONFIG, "Interval '%s' is too long", s);
    *ok = 0;
    return -1;
  }
  return (int)r;
}
+1 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ include src/lib/cc/include.am
include src/lib/ctime/include.am
include src/lib/compress/include.am
include src/lib/conf/include.am
include src/lib/confmgt/include.am
include src/lib/container/include.am
include src/lib/crypt_ops/include.am
include src/lib/defs/include.am
+7 −0
Original line number Diff line number Diff line
orconfig.h
lib/cc/*.h
lib/conf/*.h
lib/confmgt/*.h
lib/log/*.h
lib/malloc/*.h
lib/string/*.h
Loading