confparse.c 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382
  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. if (!strcmpstart(line->key, "__")) {
  1066. /* This check detects "hidden" variables inside LINELIST_V structures.
  1067. */
  1068. continue;
  1069. }
  1070. smartlist_add_asprintf(elements, "%s%s %s\n",
  1071. comment_option ? "# " : "",
  1072. line->key, line->value);
  1073. }
  1074. config_free_lines(assigned);
  1075. }
  1076. if (fmt->extra) {
  1077. line = *(config_line_t**)STRUCT_VAR_P(options, fmt->extra->var_offset);
  1078. for (; line; line = line->next) {
  1079. smartlist_add_asprintf(elements, "%s %s\n", line->key, line->value);
  1080. }
  1081. }
  1082. result = smartlist_join_strings(elements, "", 0, NULL);
  1083. SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
  1084. smartlist_free(elements);
  1085. if (defaults_tmp)
  1086. config_free(fmt, defaults_tmp);
  1087. return result;
  1088. }
  1089. /** Mapping from a unit name to a multiplier for converting that unit into a
  1090. * base unit. Used by config_parse_unit. */
  1091. struct unit_table_t {
  1092. const char *unit; /**< The name of the unit */
  1093. uint64_t multiplier; /**< How many of the base unit appear in this unit */
  1094. };
  1095. /** Table to map the names of memory units to the number of bytes they
  1096. * contain. */
  1097. static struct unit_table_t memory_units[] = {
  1098. { "", 1 },
  1099. { "b", 1<< 0 },
  1100. { "byte", 1<< 0 },
  1101. { "bytes", 1<< 0 },
  1102. { "kb", 1<<10 },
  1103. { "kbyte", 1<<10 },
  1104. { "kbytes", 1<<10 },
  1105. { "kilobyte", 1<<10 },
  1106. { "kilobytes", 1<<10 },
  1107. { "kilobits", 1<<7 },
  1108. { "kilobit", 1<<7 },
  1109. { "kbits", 1<<7 },
  1110. { "kbit", 1<<7 },
  1111. { "m", 1<<20 },
  1112. { "mb", 1<<20 },
  1113. { "mbyte", 1<<20 },
  1114. { "mbytes", 1<<20 },
  1115. { "megabyte", 1<<20 },
  1116. { "megabytes", 1<<20 },
  1117. { "megabits", 1<<17 },
  1118. { "megabit", 1<<17 },
  1119. { "mbits", 1<<17 },
  1120. { "mbit", 1<<17 },
  1121. { "gb", 1<<30 },
  1122. { "gbyte", 1<<30 },
  1123. { "gbytes", 1<<30 },
  1124. { "gigabyte", 1<<30 },
  1125. { "gigabytes", 1<<30 },
  1126. { "gigabits", 1<<27 },
  1127. { "gigabit", 1<<27 },
  1128. { "gbits", 1<<27 },
  1129. { "gbit", 1<<27 },
  1130. { "tb", U64_LITERAL(1)<<40 },
  1131. { "tbyte", U64_LITERAL(1)<<40 },
  1132. { "tbytes", U64_LITERAL(1)<<40 },
  1133. { "terabyte", U64_LITERAL(1)<<40 },
  1134. { "terabytes", U64_LITERAL(1)<<40 },
  1135. { "terabits", U64_LITERAL(1)<<37 },
  1136. { "terabit", U64_LITERAL(1)<<37 },
  1137. { "tbits", U64_LITERAL(1)<<37 },
  1138. { "tbit", U64_LITERAL(1)<<37 },
  1139. { NULL, 0 },
  1140. };
  1141. /** Table to map the names of time units to the number of seconds they
  1142. * contain. */
  1143. static struct unit_table_t time_units[] = {
  1144. { "", 1 },
  1145. { "second", 1 },
  1146. { "seconds", 1 },
  1147. { "minute", 60 },
  1148. { "minutes", 60 },
  1149. { "hour", 60*60 },
  1150. { "hours", 60*60 },
  1151. { "day", 24*60*60 },
  1152. { "days", 24*60*60 },
  1153. { "week", 7*24*60*60 },
  1154. { "weeks", 7*24*60*60 },
  1155. { "month", 2629728, }, /* about 30.437 days */
  1156. { "months", 2629728, },
  1157. { NULL, 0 },
  1158. };
  1159. /** Table to map the names of time units to the number of milliseconds
  1160. * they contain. */
  1161. static struct unit_table_t time_msec_units[] = {
  1162. { "", 1 },
  1163. { "msec", 1 },
  1164. { "millisecond", 1 },
  1165. { "milliseconds", 1 },
  1166. { "second", 1000 },
  1167. { "seconds", 1000 },
  1168. { "minute", 60*1000 },
  1169. { "minutes", 60*1000 },
  1170. { "hour", 60*60*1000 },
  1171. { "hours", 60*60*1000 },
  1172. { "day", 24*60*60*1000 },
  1173. { "days", 24*60*60*1000 },
  1174. { "week", 7*24*60*60*1000 },
  1175. { "weeks", 7*24*60*60*1000 },
  1176. { NULL, 0 },
  1177. };
  1178. /** Parse a string <b>val</b> containing a number, zero or more
  1179. * spaces, and an optional unit string. If the unit appears in the
  1180. * table <b>u</b>, then multiply the number by the unit multiplier.
  1181. * On success, set *<b>ok</b> to 1 and return this product.
  1182. * Otherwise, set *<b>ok</b> to 0.
  1183. */
  1184. static uint64_t
  1185. config_parse_units(const char *val, struct unit_table_t *u, int *ok)
  1186. {
  1187. uint64_t v = 0;
  1188. double d = 0;
  1189. int use_float = 0;
  1190. char *cp;
  1191. tor_assert(ok);
  1192. v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
  1193. if (!*ok || (cp && *cp == '.')) {
  1194. d = tor_parse_double(val, 0, (double)UINT64_MAX, ok, &cp);
  1195. if (!*ok)
  1196. goto done;
  1197. use_float = 1;
  1198. }
  1199. if (!cp) {
  1200. *ok = 1;
  1201. v = use_float ? DBL_TO_U64(d) : v;
  1202. goto done;
  1203. }
  1204. cp = (char*) eat_whitespace(cp);
  1205. for ( ;u->unit;++u) {
  1206. if (!strcasecmp(u->unit, cp)) {
  1207. if (use_float)
  1208. v = (uint64_t)(u->multiplier * d);
  1209. else
  1210. v *= u->multiplier;
  1211. *ok = 1;
  1212. goto done;
  1213. }
  1214. }
  1215. log_warn(LD_CONFIG, "Unknown unit '%s'.", cp);
  1216. *ok = 0;
  1217. done:
  1218. if (*ok)
  1219. return v;
  1220. else
  1221. return 0;
  1222. }
  1223. /** Parse a string in the format "number unit", where unit is a unit of
  1224. * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
  1225. * and return the number of bytes specified. Otherwise, set
  1226. * *<b>ok</b> to false and return 0. */
  1227. static uint64_t
  1228. config_parse_memunit(const char *s, int *ok)
  1229. {
  1230. uint64_t u = config_parse_units(s, memory_units, ok);
  1231. return u;
  1232. }
  1233. /** Parse a string in the format "number unit", where unit is a unit of
  1234. * time in milliseconds. On success, set *<b>ok</b> to true and return
  1235. * the number of milliseconds in the provided interval. Otherwise, set
  1236. * *<b>ok</b> to 0 and return -1. */
  1237. static int
  1238. config_parse_msec_interval(const char *s, int *ok)
  1239. {
  1240. uint64_t r;
  1241. r = config_parse_units(s, time_msec_units, ok);
  1242. if (!ok)
  1243. return -1;
  1244. if (r > INT_MAX) {
  1245. log_warn(LD_CONFIG, "Msec interval '%s' is too long", s);
  1246. *ok = 0;
  1247. return -1;
  1248. }
  1249. return (int)r;
  1250. }
  1251. /** Parse a string in the format "number unit", where unit is a unit of time.
  1252. * On success, set *<b>ok</b> to true and return the number of seconds in
  1253. * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
  1254. */
  1255. static int
  1256. config_parse_interval(const char *s, int *ok)
  1257. {
  1258. uint64_t r;
  1259. r = config_parse_units(s, time_units, ok);
  1260. if (!ok)
  1261. return -1;
  1262. if (r > INT_MAX) {
  1263. log_warn(LD_CONFIG, "Interval '%s' is too long", s);
  1264. *ok = 0;
  1265. return -1;
  1266. }
  1267. return (int)r;
  1268. }