confparse.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377
  1. /* Copyright (c) 2001 Matej Pfajfar.
  2. * Copyright (c) 2001-2004, Roger Dingledine.
  3. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  4. * Copyright (c) 2007-2016, The Tor Project, Inc. */
  5. /* See LICENSE for licensing information */
  6. /**
  7. * \file confparse.c
  8. *
  9. * \brief Back-end for parsing and generating key-value files, used to
  10. * implement the torrc file format and the state file.
  11. *
  12. * This module is used by config.c to parse and encode torrc
  13. * configuration files, and by statefile.c to parse and encode the
  14. * $DATADIR/state file.
  15. *
  16. * To use this module, its callers provide an instance of
  17. * config_format_t to describe the mappings from a set of configuration
  18. * options to a number of fields in a C structure. With this mapping,
  19. * the functions here can convert back and forth between the C structure
  20. * specified, and a linked list of key-value pairs.
  21. */
  22. #include "or.h"
  23. #include "confparse.h"
  24. #include "routerset.h"
  25. static uint64_t config_parse_memunit(const char *s, int *ok);
  26. static int config_parse_msec_interval(const char *s, int *ok);
  27. static int config_parse_interval(const char *s, int *ok);
  28. static void config_reset(const config_format_t *fmt, void *options,
  29. const config_var_t *var, int use_defaults);
  30. /** Allocate an empty configuration object of a given format type. */
  31. void *
  32. config_new(const config_format_t *fmt)
  33. {
  34. void *opts = tor_malloc_zero(fmt->size);
  35. *(uint32_t*)STRUCT_VAR_P(opts, fmt->magic_offset) = fmt->magic;
  36. CONFIG_CHECK(fmt, opts);
  37. return opts;
  38. }
  39. /*
  40. * Functions to parse config options
  41. */
  42. /** If <b>option</b> is an official abbreviation for a longer option,
  43. * return the longer option. Otherwise return <b>option</b>.
  44. * If <b>command_line</b> is set, apply all abbreviations. Otherwise, only
  45. * apply abbreviations that work for the config file and the command line.
  46. * If <b>warn_obsolete</b> is set, warn about deprecated names. */
  47. const char *
  48. config_expand_abbrev(const config_format_t *fmt, const char *option,
  49. int command_line, int warn_obsolete)
  50. {
  51. int i;
  52. if (! fmt->abbrevs)
  53. return option;
  54. for (i=0; fmt->abbrevs[i].abbreviated; ++i) {
  55. /* Abbreviations are case insensitive. */
  56. if (!strcasecmp(option,fmt->abbrevs[i].abbreviated) &&
  57. (command_line || !fmt->abbrevs[i].commandline_only)) {
  58. if (warn_obsolete && fmt->abbrevs[i].warn) {
  59. log_warn(LD_CONFIG,
  60. "The configuration option '%s' is deprecated; "
  61. "use '%s' instead.",
  62. fmt->abbrevs[i].abbreviated,
  63. fmt->abbrevs[i].full);
  64. }
  65. /* Keep going through the list in case we want to rewrite it more.
  66. * (We could imagine recursing here, but I don't want to get the
  67. * user into an infinite loop if we craft our list wrong.) */
  68. option = fmt->abbrevs[i].full;
  69. }
  70. }
  71. return option;
  72. }
  73. /** Helper: allocate a new configuration option mapping 'key' to 'val',
  74. * append it to *<b>lst</b>. */
  75. void
  76. config_line_append(config_line_t **lst,
  77. const char *key,
  78. const char *val)
  79. {
  80. config_line_t *newline;
  81. newline = tor_malloc_zero(sizeof(config_line_t));
  82. newline->key = tor_strdup(key);
  83. newline->value = tor_strdup(val);
  84. newline->next = NULL;
  85. while (*lst)
  86. lst = &((*lst)->next);
  87. (*lst) = newline;
  88. }
  89. /** Return the line in <b>lines</b> whose key is exactly <b>key</b>, or NULL
  90. * if no such key exists. For handling commandline-only options only; other
  91. * options should be looked up in the appropriate data structure. */
  92. const config_line_t *
  93. config_line_find(const config_line_t *lines,
  94. const char *key)
  95. {
  96. const config_line_t *cl;
  97. for (cl = lines; cl; cl = cl->next) {
  98. if (!strcmp(cl->key, key))
  99. return cl;
  100. }
  101. return NULL;
  102. }
  103. /** Helper: parse the config string and strdup into key/value
  104. * strings. Set *result to the list, or NULL if parsing the string
  105. * failed. Return 0 on success, -1 on failure. Warn and ignore any
  106. * misformatted lines.
  107. *
  108. * If <b>extended</b> is set, then treat keys beginning with / and with + as
  109. * indicating "clear" and "append" respectively. */
  110. int
  111. config_get_lines(const char *string, config_line_t **result, int extended)
  112. {
  113. config_line_t *list = NULL, **next;
  114. char *k, *v;
  115. const char *parse_err;
  116. next = &list;
  117. do {
  118. k = v = NULL;
  119. string = parse_config_line_from_str_verbose(string, &k, &v, &parse_err);
  120. if (!string) {
  121. log_warn(LD_CONFIG, "Error while parsing configuration: %s",
  122. parse_err?parse_err:"<unknown>");
  123. config_free_lines(list);
  124. tor_free(k);
  125. tor_free(v);
  126. return -1;
  127. }
  128. if (k && v) {
  129. unsigned command = CONFIG_LINE_NORMAL;
  130. if (extended) {
  131. if (k[0] == '+') {
  132. char *k_new = tor_strdup(k+1);
  133. tor_free(k);
  134. k = k_new;
  135. command = CONFIG_LINE_APPEND;
  136. } else if (k[0] == '/') {
  137. char *k_new = tor_strdup(k+1);
  138. tor_free(k);
  139. k = k_new;
  140. tor_free(v);
  141. v = tor_strdup("");
  142. command = CONFIG_LINE_CLEAR;
  143. }
  144. }
  145. /* This list can get long, so we keep a pointer to the end of it
  146. * rather than using config_line_append over and over and getting
  147. * n^2 performance. */
  148. *next = tor_malloc_zero(sizeof(config_line_t));
  149. (*next)->key = k;
  150. (*next)->value = v;
  151. (*next)->next = NULL;
  152. (*next)->command = command;
  153. next = &((*next)->next);
  154. } else {
  155. tor_free(k);
  156. tor_free(v);
  157. }
  158. } while (*string);
  159. *result = list;
  160. return 0;
  161. }
  162. /**
  163. * Free all the configuration lines on the linked list <b>front</b>.
  164. */
  165. void
  166. config_free_lines(config_line_t *front)
  167. {
  168. config_line_t *tmp;
  169. while (front) {
  170. tmp = front;
  171. front = tmp->next;
  172. tor_free(tmp->key);
  173. tor_free(tmp->value);
  174. tor_free(tmp);
  175. }
  176. }
  177. /** If <b>key</b> is a deprecated configuration option, return the message
  178. * explaining why it is deprecated (which may be an empty string). Return NULL
  179. * if it is not deprecated. The <b>key</b> field must be fully expanded. */
  180. const char *
  181. config_find_deprecation(const config_format_t *fmt, const char *key)
  182. {
  183. if (BUG(fmt == NULL) || BUG(key == NULL))
  184. return NULL;
  185. if (fmt->deprecations == NULL)
  186. return NULL;
  187. const config_deprecation_t *d;
  188. for (d = fmt->deprecations; d->name; ++d) {
  189. if (!strcasecmp(d->name, key)) {
  190. return d->why_deprecated ? d->why_deprecated : "";
  191. }
  192. }
  193. return NULL;
  194. }
  195. /** As config_find_option, but return a non-const pointer. */
  196. config_var_t *
  197. config_find_option_mutable(config_format_t *fmt, const char *key)
  198. {
  199. int i;
  200. size_t keylen = strlen(key);
  201. if (!keylen)
  202. return NULL; /* if they say "--" on the command line, it's not an option */
  203. /* First, check for an exact (case-insensitive) match */
  204. for (i=0; fmt->vars[i].name; ++i) {
  205. if (!strcasecmp(key, fmt->vars[i].name)) {
  206. return &fmt->vars[i];
  207. }
  208. }
  209. /* If none, check for an abbreviated match */
  210. for (i=0; fmt->vars[i].name; ++i) {
  211. if (!strncasecmp(key, fmt->vars[i].name, keylen)) {
  212. log_warn(LD_CONFIG, "The abbreviation '%s' is deprecated. "
  213. "Please use '%s' instead",
  214. key, fmt->vars[i].name);
  215. return &fmt->vars[i];
  216. }
  217. }
  218. /* Okay, unrecognized option */
  219. return NULL;
  220. }
  221. /** If <b>key</b> is a configuration option, return the corresponding const
  222. * config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
  223. * warn, and return the corresponding const config_var_t. Otherwise return
  224. * NULL.
  225. */
  226. const config_var_t *
  227. config_find_option(const config_format_t *fmt, const char *key)
  228. {
  229. return config_find_option_mutable((config_format_t*)fmt, key);
  230. }
  231. /** Return the number of option entries in <b>fmt</b>. */
  232. static int
  233. config_count_options(const config_format_t *fmt)
  234. {
  235. int i;
  236. for (i=0; fmt->vars[i].name; ++i)
  237. ;
  238. return i;
  239. }
  240. /*
  241. * Functions to assign config options.
  242. */
  243. /** <b>c</b>-\>key is known to be a real key. Update <b>options</b>
  244. * with <b>c</b>-\>value and return 0, or return -1 if bad value.
  245. *
  246. * Called from config_assign_line() and option_reset().
  247. */
  248. static int
  249. config_assign_value(const config_format_t *fmt, void *options,
  250. config_line_t *c, char **msg)
  251. {
  252. int i, ok;
  253. const config_var_t *var;
  254. void *lvalue;
  255. int *csv_int;
  256. smartlist_t *csv_str;
  257. CONFIG_CHECK(fmt, options);
  258. var = config_find_option(fmt, c->key);
  259. tor_assert(var);
  260. lvalue = STRUCT_VAR_P(options, var->var_offset);
  261. switch (var->type) {
  262. case CONFIG_TYPE_PORT:
  263. if (!strcasecmp(c->value, "auto")) {
  264. *(int *)lvalue = CFG_AUTO_PORT;
  265. break;
  266. }
  267. /* fall through */
  268. case CONFIG_TYPE_INT:
  269. case CONFIG_TYPE_UINT:
  270. i = (int)tor_parse_long(c->value, 10,
  271. var->type==CONFIG_TYPE_INT ? INT_MIN : 0,
  272. var->type==CONFIG_TYPE_PORT ? 65535 : INT_MAX,
  273. &ok, NULL);
  274. if (!ok) {
  275. tor_asprintf(msg,
  276. "Int keyword '%s %s' is malformed or out of bounds.",
  277. c->key, c->value);
  278. return -1;
  279. }
  280. *(int *)lvalue = i;
  281. break;
  282. case CONFIG_TYPE_INTERVAL: {
  283. i = config_parse_interval(c->value, &ok);
  284. if (!ok) {
  285. tor_asprintf(msg,
  286. "Interval '%s %s' is malformed or out of bounds.",
  287. c->key, c->value);
  288. return -1;
  289. }
  290. *(int *)lvalue = i;
  291. break;
  292. }
  293. case CONFIG_TYPE_MSEC_INTERVAL: {
  294. i = config_parse_msec_interval(c->value, &ok);
  295. if (!ok) {
  296. tor_asprintf(msg,
  297. "Msec interval '%s %s' is malformed or out of bounds.",
  298. c->key, c->value);
  299. return -1;
  300. }
  301. *(int *)lvalue = i;
  302. break;
  303. }
  304. case CONFIG_TYPE_MEMUNIT: {
  305. uint64_t u64 = config_parse_memunit(c->value, &ok);
  306. if (!ok) {
  307. tor_asprintf(msg,
  308. "Value '%s %s' is malformed or out of bounds.",
  309. c->key, c->value);
  310. return -1;
  311. }
  312. *(uint64_t *)lvalue = u64;
  313. break;
  314. }
  315. case CONFIG_TYPE_BOOL:
  316. i = (int)tor_parse_long(c->value, 10, 0, 1, &ok, NULL);
  317. if (!ok) {
  318. tor_asprintf(msg,
  319. "Boolean '%s %s' expects 0 or 1.",
  320. c->key, c->value);
  321. return -1;
  322. }
  323. *(int *)lvalue = i;
  324. break;
  325. case CONFIG_TYPE_AUTOBOOL:
  326. if (!strcmp(c->value, "auto"))
  327. *(int *)lvalue = -1;
  328. else if (!strcmp(c->value, "0"))
  329. *(int *)lvalue = 0;
  330. else if (!strcmp(c->value, "1"))
  331. *(int *)lvalue = 1;
  332. else {
  333. tor_asprintf(msg, "Boolean '%s %s' expects 0, 1, or 'auto'.",
  334. c->key, c->value);
  335. return -1;
  336. }
  337. break;
  338. case CONFIG_TYPE_STRING:
  339. case CONFIG_TYPE_FILENAME:
  340. tor_free(*(char **)lvalue);
  341. *(char **)lvalue = tor_strdup(c->value);
  342. break;
  343. case CONFIG_TYPE_DOUBLE:
  344. *(double *)lvalue = atof(c->value);
  345. break;
  346. case CONFIG_TYPE_ISOTIME:
  347. if (parse_iso_time(c->value, (time_t *)lvalue)) {
  348. tor_asprintf(msg,
  349. "Invalid time '%s' for keyword '%s'", c->value, c->key);
  350. return -1;
  351. }
  352. break;
  353. case CONFIG_TYPE_ROUTERSET:
  354. if (*(routerset_t**)lvalue) {
  355. routerset_free(*(routerset_t**)lvalue);
  356. }
  357. *(routerset_t**)lvalue = routerset_new();
  358. if (routerset_parse(*(routerset_t**)lvalue, c->value, c->key)<0) {
  359. tor_asprintf(msg, "Invalid exit list '%s' for option '%s'",
  360. c->value, c->key);
  361. return -1;
  362. }
  363. break;
  364. case CONFIG_TYPE_CSV:
  365. if (*(smartlist_t**)lvalue) {
  366. SMARTLIST_FOREACH(*(smartlist_t**)lvalue, char *, cp, tor_free(cp));
  367. smartlist_clear(*(smartlist_t**)lvalue);
  368. } else {
  369. *(smartlist_t**)lvalue = smartlist_new();
  370. }
  371. smartlist_split_string(*(smartlist_t**)lvalue, c->value, ",",
  372. SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  373. break;
  374. case CONFIG_TYPE_CSV_INTERVAL:
  375. if (*(smartlist_t**)lvalue) {
  376. SMARTLIST_FOREACH(*(smartlist_t**)lvalue, int *, cp, tor_free(cp));
  377. smartlist_clear(*(smartlist_t**)lvalue);
  378. } else {
  379. *(smartlist_t**)lvalue = smartlist_new();
  380. }
  381. csv_str = smartlist_new();
  382. smartlist_split_string(csv_str, c->value, ",",
  383. SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
  384. SMARTLIST_FOREACH_BEGIN(csv_str, char *, str)
  385. {
  386. i = config_parse_interval(str, &ok);
  387. if (!ok) {
  388. tor_asprintf(msg,
  389. "Interval in '%s %s' is malformed or out of bounds.",
  390. c->key, c->value);
  391. SMARTLIST_FOREACH(csv_str, char *, cp, tor_free(cp));
  392. smartlist_free(csv_str);
  393. return -1;
  394. }
  395. csv_int = tor_malloc_zero(sizeof(int));
  396. *csv_int = i;
  397. smartlist_add(*(smartlist_t**)lvalue, csv_int);
  398. }
  399. SMARTLIST_FOREACH_END(str);
  400. SMARTLIST_FOREACH(csv_str, char *, cp, tor_free(cp));
  401. smartlist_free(csv_str);
  402. break;
  403. case CONFIG_TYPE_LINELIST:
  404. case CONFIG_TYPE_LINELIST_S:
  405. {
  406. config_line_t *lastval = *(config_line_t**)lvalue;
  407. if (lastval && lastval->fragile) {
  408. if (c->command != CONFIG_LINE_APPEND) {
  409. config_free_lines(lastval);
  410. *(config_line_t**)lvalue = NULL;
  411. } else {
  412. lastval->fragile = 0;
  413. }
  414. }
  415. config_line_append((config_line_t**)lvalue, c->key, c->value);
  416. }
  417. break;
  418. case CONFIG_TYPE_OBSOLETE:
  419. log_warn(LD_CONFIG, "Skipping obsolete configuration option '%s'", c->key);
  420. break;
  421. case CONFIG_TYPE_LINELIST_V:
  422. tor_asprintf(msg,
  423. "You may not provide a value for virtual option '%s'", c->key);
  424. return -1;
  425. default:
  426. tor_assert(0);
  427. break;
  428. }
  429. return 0;
  430. }
  431. /** Mark every linelist in <b>options</b> "fragile", so that fresh assignments
  432. * to it will replace old ones. */
  433. static void
  434. config_mark_lists_fragile(const config_format_t *fmt, void *options)
  435. {
  436. int i;
  437. tor_assert(fmt);
  438. tor_assert(options);
  439. for (i = 0; fmt->vars[i].name; ++i) {
  440. const config_var_t *var = &fmt->vars[i];
  441. config_line_t *list;
  442. if (var->type != CONFIG_TYPE_LINELIST &&
  443. var->type != CONFIG_TYPE_LINELIST_V)
  444. continue;
  445. list = *(config_line_t **)STRUCT_VAR_P(options, var->var_offset);
  446. if (list)
  447. list->fragile = 1;
  448. }
  449. }
  450. void
  451. warn_deprecated_option(const char *what, const char *why)
  452. {
  453. const char *space = (why && strlen(why)) ? " " : "";
  454. log_warn(LD_CONFIG, "The %s option is deprecated, and will most likely "
  455. "be removed in a future version of Tor.%s%s (If you think this is "
  456. "a mistake, please let us know!)",
  457. what, space, why);
  458. }
  459. /** If <b>c</b> is a syntactically valid configuration line, update
  460. * <b>options</b> with its value and return 0. Otherwise return -1 for bad
  461. * key, -2 for bad value.
  462. *
  463. * If <b>clear_first</b> is set, clear the value first. Then if
  464. * <b>use_defaults</b> is set, set the value to the default.
  465. *
  466. * Called from config_assign().
  467. */
  468. static int
  469. config_assign_line(const config_format_t *fmt, void *options,
  470. config_line_t *c, unsigned flags,
  471. bitarray_t *options_seen, char **msg)
  472. {
  473. const unsigned use_defaults = flags & CAL_USE_DEFAULTS;
  474. const unsigned clear_first = flags & CAL_CLEAR_FIRST;
  475. const unsigned warn_deprecations = flags & CAL_WARN_DEPRECATIONS;
  476. const config_var_t *var;
  477. CONFIG_CHECK(fmt, options);
  478. var = config_find_option(fmt, c->key);
  479. if (!var) {
  480. if (fmt->extra) {
  481. void *lvalue = STRUCT_VAR_P(options, fmt->extra->var_offset);
  482. log_info(LD_CONFIG,
  483. "Found unrecognized option '%s'; saving it.", c->key);
  484. config_line_append((config_line_t**)lvalue, c->key, c->value);
  485. return 0;
  486. } else {
  487. tor_asprintf(msg,
  488. "Unknown option '%s'. Failing.", c->key);
  489. return -1;
  490. }
  491. }
  492. /* Put keyword into canonical case. */
  493. if (strcmp(var->name, c->key)) {
  494. tor_free(c->key);
  495. c->key = tor_strdup(var->name);
  496. }
  497. const char *deprecation_msg;
  498. if (warn_deprecations &&
  499. (deprecation_msg = config_find_deprecation(fmt, var->name))) {
  500. warn_deprecated_option(var->name, deprecation_msg);
  501. }
  502. if (!strlen(c->value)) {
  503. /* reset or clear it, then return */
  504. if (!clear_first) {
  505. if ((var->type == CONFIG_TYPE_LINELIST ||
  506. var->type == CONFIG_TYPE_LINELIST_S) &&
  507. c->command != CONFIG_LINE_CLEAR) {
  508. /* We got an empty linelist from the torrc or command line.
  509. As a special case, call this an error. Warn and ignore. */
  510. log_warn(LD_CONFIG,
  511. "Linelist option '%s' has no value. Skipping.", c->key);
  512. } else { /* not already cleared */
  513. config_reset(fmt, options, var, use_defaults);
  514. }
  515. }
  516. return 0;
  517. } else if (c->command == CONFIG_LINE_CLEAR && !clear_first) {
  518. config_reset(fmt, options, var, use_defaults);
  519. }
  520. if (options_seen && (var->type != CONFIG_TYPE_LINELIST &&
  521. var->type != CONFIG_TYPE_LINELIST_S)) {
  522. /* We're tracking which options we've seen, and this option is not
  523. * supposed to occur more than once. */
  524. int var_index = (int)(var - fmt->vars);
  525. if (bitarray_is_set(options_seen, var_index)) {
  526. log_warn(LD_CONFIG, "Option '%s' used more than once; all but the last "
  527. "value will be ignored.", var->name);
  528. }
  529. bitarray_set(options_seen, var_index);
  530. }
  531. if (config_assign_value(fmt, options, c, msg) < 0)
  532. return -2;
  533. return 0;
  534. }
  535. /** Restore the option named <b>key</b> in options to its default value.
  536. * Called from config_assign(). */
  537. static void
  538. config_reset_line(const config_format_t *fmt, void *options,
  539. const char *key, int use_defaults)
  540. {
  541. const config_var_t *var;
  542. CONFIG_CHECK(fmt, options);
  543. var = config_find_option(fmt, key);
  544. if (!var)
  545. return; /* give error on next pass. */
  546. config_reset(fmt, options, var, use_defaults);
  547. }
  548. /** Return true iff value needs to be quoted and escaped to be used in
  549. * a configuration file. */
  550. static int
  551. config_value_needs_escape(const char *value)
  552. {
  553. if (*value == '\"')
  554. return 1;
  555. while (*value) {
  556. switch (*value)
  557. {
  558. case '\r':
  559. case '\n':
  560. case '#':
  561. /* Note: quotes and backspaces need special handling when we are using
  562. * quotes, not otherwise, so they don't trigger escaping on their
  563. * own. */
  564. return 1;
  565. default:
  566. if (!TOR_ISPRINT(*value))
  567. return 1;
  568. }
  569. ++value;
  570. }
  571. return 0;
  572. }
  573. /** Return a newly allocated deep copy of the lines in <b>inp</b>. */
  574. config_line_t *
  575. config_lines_dup(const config_line_t *inp)
  576. {
  577. config_line_t *result = NULL;
  578. config_line_t **next_out = &result;
  579. while (inp) {
  580. *next_out = tor_malloc_zero(sizeof(config_line_t));
  581. (*next_out)->key = tor_strdup(inp->key);
  582. (*next_out)->value = tor_strdup(inp->value);
  583. inp = inp->next;
  584. next_out = &((*next_out)->next);
  585. }
  586. (*next_out) = NULL;
  587. return result;
  588. }
  589. /** Return newly allocated line or lines corresponding to <b>key</b> in the
  590. * configuration <b>options</b>. If <b>escape_val</b> is true and a
  591. * value needs to be quoted before it's put in a config file, quote and
  592. * escape that value. Return NULL if no such key exists. */
  593. config_line_t *
  594. config_get_assigned_option(const config_format_t *fmt, const void *options,
  595. const char *key, int escape_val)
  596. {
  597. const config_var_t *var;
  598. const void *value;
  599. config_line_t *result;
  600. smartlist_t *csv_str;
  601. tor_assert(options && key);
  602. CONFIG_CHECK(fmt, options);
  603. var = config_find_option(fmt, key);
  604. if (!var) {
  605. log_warn(LD_CONFIG, "Unknown option '%s'. Failing.", key);
  606. return NULL;
  607. }
  608. value = STRUCT_VAR_P(options, var->var_offset);
  609. result = tor_malloc_zero(sizeof(config_line_t));
  610. result->key = tor_strdup(var->name);
  611. switch (var->type)
  612. {
  613. case CONFIG_TYPE_STRING:
  614. case CONFIG_TYPE_FILENAME:
  615. if (*(char**)value) {
  616. result->value = tor_strdup(*(char**)value);
  617. } else {
  618. tor_free(result->key);
  619. tor_free(result);
  620. return NULL;
  621. }
  622. break;
  623. case CONFIG_TYPE_ISOTIME:
  624. if (*(time_t*)value) {
  625. result->value = tor_malloc(ISO_TIME_LEN+1);
  626. format_iso_time(result->value, *(time_t*)value);
  627. } else {
  628. tor_free(result->key);
  629. tor_free(result);
  630. }
  631. escape_val = 0; /* Can't need escape. */
  632. break;
  633. case CONFIG_TYPE_PORT:
  634. if (*(int*)value == CFG_AUTO_PORT) {
  635. result->value = tor_strdup("auto");
  636. escape_val = 0;
  637. break;
  638. }
  639. /* fall through */
  640. case CONFIG_TYPE_INTERVAL:
  641. case CONFIG_TYPE_MSEC_INTERVAL:
  642. case CONFIG_TYPE_UINT:
  643. case CONFIG_TYPE_INT:
  644. /* This means every or_options_t uint or bool element
  645. * needs to be an int. Not, say, a uint16_t or char. */
  646. tor_asprintf(&result->value, "%d", *(int*)value);
  647. escape_val = 0; /* Can't need escape. */
  648. break;
  649. case CONFIG_TYPE_MEMUNIT:
  650. tor_asprintf(&result->value, U64_FORMAT,
  651. U64_PRINTF_ARG(*(uint64_t*)value));
  652. escape_val = 0; /* Can't need escape. */
  653. break;
  654. case CONFIG_TYPE_DOUBLE:
  655. tor_asprintf(&result->value, "%f", *(double*)value);
  656. escape_val = 0; /* Can't need escape. */
  657. break;
  658. case CONFIG_TYPE_AUTOBOOL:
  659. if (*(int*)value == -1) {
  660. result->value = tor_strdup("auto");
  661. escape_val = 0;
  662. break;
  663. }
  664. /* fall through */
  665. case CONFIG_TYPE_BOOL:
  666. result->value = tor_strdup(*(int*)value ? "1" : "0");
  667. escape_val = 0; /* Can't need escape. */
  668. break;
  669. case CONFIG_TYPE_ROUTERSET:
  670. result->value = routerset_to_string(*(routerset_t**)value);
  671. break;
  672. case CONFIG_TYPE_CSV:
  673. if (*(smartlist_t**)value)
  674. result->value =
  675. smartlist_join_strings(*(smartlist_t**)value, ",", 0, NULL);
  676. else
  677. result->value = tor_strdup("");
  678. break;
  679. case CONFIG_TYPE_CSV_INTERVAL:
  680. if (*(smartlist_t**)value) {
  681. csv_str = smartlist_new();
  682. SMARTLIST_FOREACH_BEGIN(*(smartlist_t**)value, int *, i)
  683. {
  684. smartlist_add_asprintf(csv_str, "%d", *i);
  685. }
  686. SMARTLIST_FOREACH_END(i);
  687. result->value = smartlist_join_strings(csv_str, ",", 0, NULL);
  688. SMARTLIST_FOREACH(csv_str, char *, cp, tor_free(cp));
  689. smartlist_free(csv_str);
  690. } else
  691. result->value = tor_strdup("");
  692. break;
  693. case CONFIG_TYPE_OBSOLETE:
  694. log_fn(LOG_INFO, LD_CONFIG,
  695. "You asked me for the value of an obsolete config option '%s'.",
  696. key);
  697. tor_free(result->key);
  698. tor_free(result);
  699. return NULL;
  700. case CONFIG_TYPE_LINELIST_S:
  701. log_warn(LD_CONFIG,
  702. "Can't return context-sensitive '%s' on its own", key);
  703. tor_free(result->key);
  704. tor_free(result);
  705. return NULL;
  706. case CONFIG_TYPE_LINELIST:
  707. case CONFIG_TYPE_LINELIST_V:
  708. tor_free(result->key);
  709. tor_free(result);
  710. result = config_lines_dup(*(const config_line_t**)value);
  711. break;
  712. default:
  713. tor_free(result->key);
  714. tor_free(result);
  715. log_warn(LD_BUG,"Unknown type %d for known key '%s'",
  716. var->type, key);
  717. return NULL;
  718. }
  719. if (escape_val) {
  720. config_line_t *line;
  721. for (line = result; line; line = line->next) {
  722. if (line->value && config_value_needs_escape(line->value)) {
  723. char *newval = esc_for_log(line->value);
  724. tor_free(line->value);
  725. line->value = newval;
  726. }
  727. }
  728. }
  729. return result;
  730. }
  731. /** Iterate through the linked list of requested options <b>list</b>.
  732. * For each item, convert as appropriate and assign to <b>options</b>.
  733. * If an item is unrecognized, set *msg and return -1 immediately,
  734. * else return 0 for success.
  735. *
  736. * If <b>clear_first</b>, interpret config options as replacing (not
  737. * extending) their previous values. If <b>clear_first</b> is set,
  738. * then <b>use_defaults</b> to decide if you set to defaults after
  739. * clearing, or make the value 0 or NULL.
  740. *
  741. * Here are the use cases:
  742. * 1. A non-empty AllowInvalid line in your torrc. Appends to current
  743. * if linelist, replaces current if csv.
  744. * 2. An empty AllowInvalid line in your torrc. Should clear it.
  745. * 3. "RESETCONF AllowInvalid" sets it to default.
  746. * 4. "SETCONF AllowInvalid" makes it NULL.
  747. * 5. "SETCONF AllowInvalid=foo" clears it and sets it to "foo".
  748. *
  749. * Use_defaults Clear_first
  750. * 0 0 "append"
  751. * 1 0 undefined, don't use
  752. * 0 1 "set to null first"
  753. * 1 1 "set to defaults first"
  754. * Return 0 on success, -1 on bad key, -2 on bad value.
  755. *
  756. * As an additional special case, if a LINELIST config option has
  757. * no value and clear_first is 0, then warn and ignore it.
  758. */
  759. /*
  760. There are three call cases for config_assign() currently.
  761. Case one: Torrc entry
  762. options_init_from_torrc() calls config_assign(0, 0)
  763. calls config_assign_line(0, 0).
  764. if value is empty, calls config_reset(0) and returns.
  765. calls config_assign_value(), appends.
  766. Case two: setconf
  767. options_trial_assign() calls config_assign(0, 1)
  768. calls config_reset_line(0)
  769. calls config_reset(0)
  770. calls option_clear().
  771. calls config_assign_line(0, 1).
  772. if value is empty, returns.
  773. calls config_assign_value(), appends.
  774. Case three: resetconf
  775. options_trial_assign() calls config_assign(1, 1)
  776. calls config_reset_line(1)
  777. calls config_reset(1)
  778. calls option_clear().
  779. calls config_assign_value(default)
  780. calls config_assign_line(1, 1).
  781. returns.
  782. */
  783. int
  784. config_assign(const config_format_t *fmt, void *options, config_line_t *list,
  785. unsigned config_assign_flags, char **msg)
  786. {
  787. config_line_t *p;
  788. bitarray_t *options_seen;
  789. const int n_options = config_count_options(fmt);
  790. const unsigned clear_first = config_assign_flags & CAL_CLEAR_FIRST;
  791. const unsigned use_defaults = config_assign_flags & CAL_USE_DEFAULTS;
  792. CONFIG_CHECK(fmt, options);
  793. /* pass 1: normalize keys */
  794. for (p = list; p; p = p->next) {
  795. const char *full = config_expand_abbrev(fmt, p->key, 0, 1);
  796. if (strcmp(full,p->key)) {
  797. tor_free(p->key);
  798. p->key = tor_strdup(full);
  799. }
  800. }
  801. /* pass 2: if we're reading from a resetting source, clear all
  802. * mentioned config options, and maybe set to their defaults. */
  803. if (clear_first) {
  804. for (p = list; p; p = p->next)
  805. config_reset_line(fmt, options, p->key, use_defaults);
  806. }
  807. options_seen = bitarray_init_zero(n_options);
  808. /* pass 3: assign. */
  809. while (list) {
  810. int r;
  811. if ((r=config_assign_line(fmt, options, list, config_assign_flags,
  812. options_seen, msg))) {
  813. bitarray_free(options_seen);
  814. return r;
  815. }
  816. list = list->next;
  817. }
  818. bitarray_free(options_seen);
  819. /** Now we're done assigning a group of options to the configuration.
  820. * Subsequent group assignments should _replace_ linelists, not extend
  821. * them. */
  822. config_mark_lists_fragile(fmt, options);
  823. return 0;
  824. }
  825. /** Reset config option <b>var</b> to 0, 0.0, NULL, or the equivalent.
  826. * Called from config_reset() and config_free(). */
  827. static void
  828. config_clear(const config_format_t *fmt, void *options,
  829. const config_var_t *var)
  830. {
  831. void *lvalue = STRUCT_VAR_P(options, var->var_offset);
  832. (void)fmt; /* unused */
  833. switch (var->type) {
  834. case CONFIG_TYPE_STRING:
  835. case CONFIG_TYPE_FILENAME:
  836. tor_free(*(char**)lvalue);
  837. break;
  838. case CONFIG_TYPE_DOUBLE:
  839. *(double*)lvalue = 0.0;
  840. break;
  841. case CONFIG_TYPE_ISOTIME:
  842. *(time_t*)lvalue = 0;
  843. break;
  844. case CONFIG_TYPE_INTERVAL:
  845. case CONFIG_TYPE_MSEC_INTERVAL:
  846. case CONFIG_TYPE_UINT:
  847. case CONFIG_TYPE_INT:
  848. case CONFIG_TYPE_PORT:
  849. case CONFIG_TYPE_BOOL:
  850. *(int*)lvalue = 0;
  851. break;
  852. case CONFIG_TYPE_AUTOBOOL:
  853. *(int*)lvalue = -1;
  854. break;
  855. case CONFIG_TYPE_MEMUNIT:
  856. *(uint64_t*)lvalue = 0;
  857. break;
  858. case CONFIG_TYPE_ROUTERSET:
  859. if (*(routerset_t**)lvalue) {
  860. routerset_free(*(routerset_t**)lvalue);
  861. *(routerset_t**)lvalue = NULL;
  862. }
  863. break;
  864. case CONFIG_TYPE_CSV:
  865. if (*(smartlist_t**)lvalue) {
  866. SMARTLIST_FOREACH(*(smartlist_t **)lvalue, char *, cp, tor_free(cp));
  867. smartlist_free(*(smartlist_t **)lvalue);
  868. *(smartlist_t **)lvalue = NULL;
  869. }
  870. break;
  871. case CONFIG_TYPE_CSV_INTERVAL:
  872. if (*(smartlist_t**)lvalue) {
  873. SMARTLIST_FOREACH(*(smartlist_t **)lvalue, int *, cp, tor_free(cp));
  874. smartlist_free(*(smartlist_t **)lvalue);
  875. *(smartlist_t **)lvalue = NULL;
  876. }
  877. break;
  878. case CONFIG_TYPE_LINELIST:
  879. case CONFIG_TYPE_LINELIST_S:
  880. config_free_lines(*(config_line_t **)lvalue);
  881. *(config_line_t **)lvalue = NULL;
  882. break;
  883. case CONFIG_TYPE_LINELIST_V:
  884. /* handled by linelist_s. */
  885. break;
  886. case CONFIG_TYPE_OBSOLETE:
  887. break;
  888. }
  889. }
  890. /** Clear the option indexed by <b>var</b> in <b>options</b>. Then if
  891. * <b>use_defaults</b>, set it to its default value.
  892. * Called by config_init() and option_reset_line() and option_assign_line(). */
  893. static void
  894. config_reset(const config_format_t *fmt, void *options,
  895. const config_var_t *var, int use_defaults)
  896. {
  897. config_line_t *c;
  898. char *msg = NULL;
  899. CONFIG_CHECK(fmt, options);
  900. config_clear(fmt, options, var); /* clear it first */
  901. if (!use_defaults)
  902. return; /* all done */
  903. if (var->initvalue) {
  904. c = tor_malloc_zero(sizeof(config_line_t));
  905. c->key = tor_strdup(var->name);
  906. c->value = tor_strdup(var->initvalue);
  907. if (config_assign_value(fmt, options, c, &msg) < 0) {
  908. log_warn(LD_BUG, "Failed to assign default: %s", msg);
  909. tor_free(msg); /* if this happens it's a bug */
  910. }
  911. config_free_lines(c);
  912. }
  913. }
  914. /** Release storage held by <b>options</b>. */
  915. void
  916. config_free(const config_format_t *fmt, void *options)
  917. {
  918. int i;
  919. if (!options)
  920. return;
  921. tor_assert(fmt);
  922. for (i=0; fmt->vars[i].name; ++i)
  923. config_clear(fmt, options, &(fmt->vars[i]));
  924. if (fmt->extra) {
  925. config_line_t **linep = STRUCT_VAR_P(options, fmt->extra->var_offset);
  926. config_free_lines(*linep);
  927. *linep = NULL;
  928. }
  929. tor_free(options);
  930. }
  931. /** Return true iff a and b contain identical keys and values in identical
  932. * order. */
  933. int
  934. config_lines_eq(config_line_t *a, config_line_t *b)
  935. {
  936. while (a && b) {
  937. if (strcasecmp(a->key, b->key) || strcmp(a->value, b->value))
  938. return 0;
  939. a = a->next;
  940. b = b->next;
  941. }
  942. if (a || b)
  943. return 0;
  944. return 1;
  945. }
  946. /** Return the number of lines in <b>a</b> whose key is <b>key</b>. */
  947. int
  948. config_count_key(const config_line_t *a, const char *key)
  949. {
  950. int n = 0;
  951. while (a) {
  952. if (!strcasecmp(a->key, key)) {
  953. ++n;
  954. }
  955. a = a->next;
  956. }
  957. return n;
  958. }
  959. /** Return true iff the option <b>name</b> has the same value in <b>o1</b>
  960. * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
  961. */
  962. int
  963. config_is_same(const config_format_t *fmt,
  964. const void *o1, const void *o2,
  965. const char *name)
  966. {
  967. config_line_t *c1, *c2;
  968. int r = 1;
  969. CONFIG_CHECK(fmt, o1);
  970. CONFIG_CHECK(fmt, o2);
  971. c1 = config_get_assigned_option(fmt, o1, name, 0);
  972. c2 = config_get_assigned_option(fmt, o2, name, 0);
  973. r = config_lines_eq(c1, c2);
  974. config_free_lines(c1);
  975. config_free_lines(c2);
  976. return r;
  977. }
  978. /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
  979. void *
  980. config_dup(const config_format_t *fmt, const void *old)
  981. {
  982. void *newopts;
  983. int i;
  984. config_line_t *line;
  985. newopts = config_new(fmt);
  986. for (i=0; fmt->vars[i].name; ++i) {
  987. if (fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
  988. continue;
  989. if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE)
  990. continue;
  991. line = config_get_assigned_option(fmt, old, fmt->vars[i].name, 0);
  992. if (line) {
  993. char *msg = NULL;
  994. if (config_assign(fmt, newopts, line, 0, &msg) < 0) {
  995. log_err(LD_BUG, "config_get_assigned_option() generated "
  996. "something we couldn't config_assign(): %s", msg);
  997. tor_free(msg);
  998. tor_assert(0);
  999. }
  1000. }
  1001. config_free_lines(line);
  1002. }
  1003. return newopts;
  1004. }
  1005. /** Set all vars in the configuration object <b>options</b> to their default
  1006. * values. */
  1007. void
  1008. config_init(const config_format_t *fmt, void *options)
  1009. {
  1010. int i;
  1011. const config_var_t *var;
  1012. CONFIG_CHECK(fmt, options);
  1013. for (i=0; fmt->vars[i].name; ++i) {
  1014. var = &fmt->vars[i];
  1015. if (!var->initvalue)
  1016. continue; /* defaults to NULL or 0 */
  1017. config_reset(fmt, options, var, 1);
  1018. }
  1019. }
  1020. /** Allocate and return a new string holding the written-out values of the vars
  1021. * in 'options'. If 'minimal', do not write out any default-valued vars.
  1022. * Else, if comment_defaults, write default values as comments.
  1023. */
  1024. char *
  1025. config_dump(const config_format_t *fmt, const void *default_options,
  1026. const void *options, int minimal,
  1027. int comment_defaults)
  1028. {
  1029. smartlist_t *elements;
  1030. const void *defaults = default_options;
  1031. void *defaults_tmp = NULL;
  1032. config_line_t *line, *assigned;
  1033. char *result;
  1034. int i;
  1035. char *msg = NULL;
  1036. if (defaults == NULL) {
  1037. defaults = defaults_tmp = config_new(fmt);
  1038. config_init(fmt, defaults_tmp);
  1039. }
  1040. /* XXX use a 1 here so we don't add a new log line while dumping */
  1041. if (default_options == NULL) {
  1042. if (fmt->validate_fn(NULL, defaults_tmp, defaults_tmp, 1, &msg) < 0) {
  1043. log_err(LD_BUG, "Failed to validate default config: %s", msg);
  1044. tor_free(msg);
  1045. tor_assert(0);
  1046. }
  1047. }
  1048. elements = smartlist_new();
  1049. for (i=0; fmt->vars[i].name; ++i) {
  1050. int comment_option = 0;
  1051. if (fmt->vars[i].type == CONFIG_TYPE_OBSOLETE ||
  1052. fmt->vars[i].type == CONFIG_TYPE_LINELIST_S)
  1053. continue;
  1054. /* Don't save 'hidden' control variables. */
  1055. if (!strcmpstart(fmt->vars[i].name, "__"))
  1056. continue;
  1057. if (minimal && config_is_same(fmt, options, defaults, fmt->vars[i].name))
  1058. continue;
  1059. else if (comment_defaults &&
  1060. config_is_same(fmt, options, defaults, fmt->vars[i].name))
  1061. comment_option = 1;
  1062. line = assigned =
  1063. config_get_assigned_option(fmt, options, fmt->vars[i].name, 1);
  1064. for (; line; line = line->next) {
  1065. smartlist_add_asprintf(elements, "%s%s %s\n",
  1066. comment_option ? "# " : "",
  1067. line->key, line->value);
  1068. }
  1069. config_free_lines(assigned);
  1070. }
  1071. if (fmt->extra) {
  1072. line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->var_offset);
  1073. for (; line; line = line->next) {
  1074. smartlist_add_asprintf(elements, "%s %s\n", line->key, line->value);
  1075. }
  1076. }
  1077. result = smartlist_join_strings(elements, "", 0, NULL);
  1078. SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
  1079. smartlist_free(elements);
  1080. if (defaults_tmp)
  1081. config_free(fmt, defaults_tmp);
  1082. return result;
  1083. }
  1084. /** Mapping from a unit name to a multiplier for converting that unit into a
  1085. * base unit. Used by config_parse_unit. */
  1086. struct unit_table_t {
  1087. const char *unit; /**< The name of the unit */
  1088. uint64_t multiplier; /**< How many of the base unit appear in this unit */
  1089. };
  1090. /** Table to map the names of memory units to the number of bytes they
  1091. * contain. */
  1092. static struct unit_table_t memory_units[] = {
  1093. { "", 1 },
  1094. { "b", 1<< 0 },
  1095. { "byte", 1<< 0 },
  1096. { "bytes", 1<< 0 },
  1097. { "kb", 1<<10 },
  1098. { "kbyte", 1<<10 },
  1099. { "kbytes", 1<<10 },
  1100. { "kilobyte", 1<<10 },
  1101. { "kilobytes", 1<<10 },
  1102. { "kilobits", 1<<7 },
  1103. { "kilobit", 1<<7 },
  1104. { "kbits", 1<<7 },
  1105. { "kbit", 1<<7 },
  1106. { "m", 1<<20 },
  1107. { "mb", 1<<20 },
  1108. { "mbyte", 1<<20 },
  1109. { "mbytes", 1<<20 },
  1110. { "megabyte", 1<<20 },
  1111. { "megabytes", 1<<20 },
  1112. { "megabits", 1<<17 },
  1113. { "megabit", 1<<17 },
  1114. { "mbits", 1<<17 },
  1115. { "mbit", 1<<17 },
  1116. { "gb", 1<<30 },
  1117. { "gbyte", 1<<30 },
  1118. { "gbytes", 1<<30 },
  1119. { "gigabyte", 1<<30 },
  1120. { "gigabytes", 1<<30 },
  1121. { "gigabits", 1<<27 },
  1122. { "gigabit", 1<<27 },
  1123. { "gbits", 1<<27 },
  1124. { "gbit", 1<<27 },
  1125. { "tb", U64_LITERAL(1)<<40 },
  1126. { "tbyte", U64_LITERAL(1)<<40 },
  1127. { "tbytes", U64_LITERAL(1)<<40 },
  1128. { "terabyte", U64_LITERAL(1)<<40 },
  1129. { "terabytes", U64_LITERAL(1)<<40 },
  1130. { "terabits", U64_LITERAL(1)<<37 },
  1131. { "terabit", U64_LITERAL(1)<<37 },
  1132. { "tbits", U64_LITERAL(1)<<37 },
  1133. { "tbit", U64_LITERAL(1)<<37 },
  1134. { NULL, 0 },
  1135. };
  1136. /** Table to map the names of time units to the number of seconds they
  1137. * contain. */
  1138. static struct unit_table_t time_units[] = {
  1139. { "", 1 },
  1140. { "second", 1 },
  1141. { "seconds", 1 },
  1142. { "minute", 60 },
  1143. { "minutes", 60 },
  1144. { "hour", 60*60 },
  1145. { "hours", 60*60 },
  1146. { "day", 24*60*60 },
  1147. { "days", 24*60*60 },
  1148. { "week", 7*24*60*60 },
  1149. { "weeks", 7*24*60*60 },
  1150. { "month", 2629728, }, /* about 30.437 days */
  1151. { "months", 2629728, },
  1152. { NULL, 0 },
  1153. };
  1154. /** Table to map the names of time units to the number of milliseconds
  1155. * they contain. */
  1156. static struct unit_table_t time_msec_units[] = {
  1157. { "", 1 },
  1158. { "msec", 1 },
  1159. { "millisecond", 1 },
  1160. { "milliseconds", 1 },
  1161. { "second", 1000 },
  1162. { "seconds", 1000 },
  1163. { "minute", 60*1000 },
  1164. { "minutes", 60*1000 },
  1165. { "hour", 60*60*1000 },
  1166. { "hours", 60*60*1000 },
  1167. { "day", 24*60*60*1000 },
  1168. { "days", 24*60*60*1000 },
  1169. { "week", 7*24*60*60*1000 },
  1170. { "weeks", 7*24*60*60*1000 },
  1171. { NULL, 0 },
  1172. };
  1173. /** Parse a string <b>val</b> containing a number, zero or more
  1174. * spaces, and an optional unit string. If the unit appears in the
  1175. * table <b>u</b>, then multiply the number by the unit multiplier.
  1176. * On success, set *<b>ok</b> to 1 and return this product.
  1177. * Otherwise, set *<b>ok</b> to 0.
  1178. */
  1179. static uint64_t
  1180. config_parse_units(const char *val, struct unit_table_t *u, int *ok)
  1181. {
  1182. uint64_t v = 0;
  1183. double d = 0;
  1184. int use_float = 0;
  1185. char *cp;
  1186. tor_assert(ok);
  1187. v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
  1188. if (!*ok || (cp && *cp == '.')) {
  1189. d = tor_parse_double(val, 0, (double)UINT64_MAX, ok, &cp);
  1190. if (!*ok)
  1191. goto done;
  1192. use_float = 1;
  1193. }
  1194. if (!cp) {
  1195. *ok = 1;
  1196. v = use_float ? DBL_TO_U64(d) : v;
  1197. goto done;
  1198. }
  1199. cp = (char*) eat_whitespace(cp);
  1200. for ( ;u->unit;++u) {
  1201. if (!strcasecmp(u->unit, cp)) {
  1202. if (use_float)
  1203. v = (uint64_t)(u->multiplier * d);
  1204. else
  1205. v *= u->multiplier;
  1206. *ok = 1;
  1207. goto done;
  1208. }
  1209. }
  1210. log_warn(LD_CONFIG, "Unknown unit '%s'.", cp);
  1211. *ok = 0;
  1212. done:
  1213. if (*ok)
  1214. return v;
  1215. else
  1216. return 0;
  1217. }
  1218. /** Parse a string in the format "number unit", where unit is a unit of
  1219. * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
  1220. * and return the number of bytes specified. Otherwise, set
  1221. * *<b>ok</b> to false and return 0. */
  1222. static uint64_t
  1223. config_parse_memunit(const char *s, int *ok)
  1224. {
  1225. uint64_t u = config_parse_units(s, memory_units, ok);
  1226. return u;
  1227. }
  1228. /** Parse a string in the format "number unit", where unit is a unit of
  1229. * time in milliseconds. On success, set *<b>ok</b> to true and return
  1230. * the number of milliseconds in the provided interval. Otherwise, set
  1231. * *<b>ok</b> to 0 and return -1. */
  1232. static int
  1233. config_parse_msec_interval(const char *s, int *ok)
  1234. {
  1235. uint64_t r;
  1236. r = config_parse_units(s, time_msec_units, ok);
  1237. if (!ok)
  1238. return -1;
  1239. if (r > INT_MAX) {
  1240. log_warn(LD_CONFIG, "Msec interval '%s' is too long", s);
  1241. *ok = 0;
  1242. return -1;
  1243. }
  1244. return (int)r;
  1245. }
  1246. /** Parse a string in the format "number unit", where unit is a unit of time.
  1247. * On success, set *<b>ok</b> to true and return the number of seconds in
  1248. * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
  1249. */
  1250. static int
  1251. config_parse_interval(const char *s, int *ok)
  1252. {
  1253. uint64_t r;
  1254. r = config_parse_units(s, time_units, ok);
  1255. if (!ok)
  1256. return -1;
  1257. if (r > INT_MAX) {
  1258. log_warn(LD_CONFIG, "Interval '%s' is too long", s);
  1259. *ok = 0;
  1260. return -1;
  1261. }
  1262. return (int)r;
  1263. }