confparse.c 34 KB

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