settings.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502
  1. /*
  2. *
  3. * Embedded Linux library
  4. *
  5. * Copyright (C) 2011-2014 Intel Corporation. All rights reserved.
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. */
  22. #ifdef HAVE_CONFIG_H
  23. #include <config.h>
  24. #endif
  25. #if __STDC_VERSION__ <= 199409L
  26. #define _DEFAULT_SOURCE /* for strto{u}ll() */
  27. #endif
  28. #define _GNU_SOURCE
  29. #include <stdio.h>
  30. #include <errno.h>
  31. #include <fcntl.h>
  32. #include <unistd.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include <strings.h>
  36. #include <stdbool.h>
  37. #include <stdint.h>
  38. #include <sys/types.h>
  39. #include <sys/stat.h>
  40. #include <sys/mman.h>
  41. #include "useful.h"
  42. #include "strv.h"
  43. #include "utf8.h"
  44. #include "string.h"
  45. #include "queue.h"
  46. #include "settings.h"
  47. #include "private.h"
  48. #include "missing.h"
  49. #include "pem-private.h"
  50. struct setting_data {
  51. char *key;
  52. char *value;
  53. };
  54. struct embedded_group_data {
  55. char *name;
  56. char type[32];
  57. size_t len;
  58. char data[0];
  59. };
  60. struct group_data {
  61. char *name;
  62. struct l_queue *settings;
  63. };
  64. struct l_settings {
  65. l_settings_debug_cb_t debug_handler;
  66. l_settings_destroy_cb_t debug_destroy;
  67. void *debug_data;
  68. struct l_queue *groups;
  69. struct l_queue *embedded_groups;
  70. };
  71. static void setting_destroy(void *data)
  72. {
  73. struct setting_data *pair = data;
  74. l_free(pair->key);
  75. explicit_bzero(pair->value, strlen(pair->value));
  76. l_free(pair->value);
  77. l_free(pair);
  78. }
  79. static void group_destroy(void *data)
  80. {
  81. struct group_data *group = data;
  82. l_free(group->name);
  83. l_queue_destroy(group->settings, setting_destroy);
  84. l_free(group);
  85. }
  86. static void embedded_group_destroy(void *data)
  87. {
  88. struct embedded_group_data *group = data;
  89. l_free(group->name);
  90. l_free(group);
  91. }
  92. LIB_EXPORT struct l_settings *l_settings_new(void)
  93. {
  94. struct l_settings *settings;
  95. settings = l_new(struct l_settings, 1);
  96. settings->groups = l_queue_new();
  97. settings->embedded_groups = l_queue_new();
  98. return settings;
  99. }
  100. LIB_EXPORT void l_settings_free(struct l_settings *settings)
  101. {
  102. if (unlikely(!settings))
  103. return;
  104. if (settings->debug_destroy)
  105. settings->debug_destroy(settings->debug_data);
  106. l_queue_destroy(settings->groups, group_destroy);
  107. l_queue_destroy(settings->embedded_groups, embedded_group_destroy);
  108. l_free(settings);
  109. }
  110. static char *unescape_value(const char *value)
  111. {
  112. char *ret;
  113. char *n;
  114. const char *o;
  115. ret = l_new(char, strlen(value) + 1);
  116. for (n = ret, o = value; *o; o++, n++) {
  117. if (*o != '\\') {
  118. *n = *o;
  119. continue;
  120. }
  121. o += 1;
  122. switch (*o) {
  123. case 's':
  124. *n = ' ';
  125. break;
  126. case 'n':
  127. *n = '\n';
  128. break;
  129. case 't':
  130. *n = '\t';
  131. break;
  132. case 'r':
  133. *n = '\r';
  134. break;
  135. case '\\':
  136. *n = '\\';
  137. break;
  138. default:
  139. explicit_bzero(ret, n - ret);
  140. l_free(ret);
  141. return NULL;
  142. }
  143. }
  144. return ret;
  145. }
  146. static char *escape_value(const char *value)
  147. {
  148. size_t i;
  149. size_t j;
  150. char *ret;
  151. bool lead_whitespace;
  152. for (i = 0, j = 0, lead_whitespace = true; value[i]; i++) {
  153. switch (value[i]) {
  154. case ' ':
  155. case '\t':
  156. if (lead_whitespace)
  157. j += 1;
  158. break;
  159. case '\n':
  160. case '\r':
  161. case '\\':
  162. j += 1;
  163. /* fall through */
  164. default:
  165. lead_whitespace = false;
  166. }
  167. }
  168. ret = l_malloc(i + j + 1);
  169. for (i = 0, j = 0, lead_whitespace = true; value[i]; i++) {
  170. switch (value[i]) {
  171. case ' ':
  172. if (lead_whitespace) {
  173. ret[j++] = '\\';
  174. ret[j++] = 's';
  175. } else
  176. ret[j++] = value[i];
  177. break;
  178. case '\t':
  179. if (lead_whitespace) {
  180. ret[j++] = '\\';
  181. ret[j++] = 't';
  182. } else
  183. ret[j++] = value[i];
  184. break;
  185. case '\n':
  186. ret[j++] = '\\';
  187. ret[j++] = 'n';
  188. lead_whitespace = false;
  189. break;
  190. case '\r':
  191. ret[j++] = '\\';
  192. ret[j++] = 'r';
  193. lead_whitespace = false;
  194. break;
  195. case '\\':
  196. ret[j++] = '\\';
  197. ret[j++] = '\\';
  198. lead_whitespace = false;
  199. break;
  200. default:
  201. ret[j++] = value[i];
  202. lead_whitespace = false;
  203. }
  204. }
  205. ret[j] = '\0';
  206. return ret;
  207. }
  208. static ssize_t parse_pem(const char *data, size_t len)
  209. {
  210. const char *ptr;
  211. const char *end;
  212. size_t count = 0;
  213. ptr = data;
  214. end = data + len;
  215. while (ptr && ptr < end) {
  216. const char *pem_start = ptr;
  217. if (!pem_next(ptr, len, NULL, NULL, &ptr, true)) {
  218. if (ptr)
  219. return -EINVAL;
  220. break;
  221. }
  222. len -= ptr - pem_start;
  223. count += ptr - pem_start;
  224. }
  225. return count;
  226. }
  227. struct group_extension {
  228. char *name;
  229. ssize_t (*parse)(const char *data, size_t len);
  230. };
  231. static const struct group_extension pem_extension = {
  232. .name = "pem",
  233. .parse = parse_pem,
  234. };
  235. static const struct group_extension *extensions[] = {
  236. &pem_extension,
  237. NULL
  238. };
  239. static const struct group_extension *find_group_extension(const char *type,
  240. size_t len)
  241. {
  242. unsigned int i;
  243. for (i = 0; extensions[i]; i++) {
  244. if (!strncmp(type, extensions[i]->name, len))
  245. return extensions[i];
  246. }
  247. return NULL;
  248. }
  249. static ssize_t parse_embedded_group(struct l_settings *setting,
  250. const char *data,
  251. size_t line_len, size_t len,
  252. size_t line)
  253. {
  254. struct embedded_group_data *group;
  255. const struct group_extension *ext;
  256. const char *ptr;
  257. const char *type;
  258. size_t type_len;
  259. const char *name;
  260. size_t name_len;
  261. ssize_t bytes;
  262. /* Must be at least [@a@b] */
  263. if (line_len < 6)
  264. goto invalid_group;
  265. /* caller checked data[1] == '@', next char is type */
  266. type = data + 2;
  267. ptr = memchr(type, '@', line_len - 2);
  268. type_len = ptr - type;
  269. if (!ptr || type_len > 31 || type_len < 1)
  270. goto invalid_group;
  271. if (ptr + 1 > data + line_len)
  272. goto invalid_group;
  273. name = ptr + 1;
  274. /* subtract [@@ + type */
  275. ptr = memchr(name, ']', line_len - 3 - type_len);
  276. name_len = ptr - name;
  277. if (!ptr || name_len < 1)
  278. goto invalid_group;
  279. ext = find_group_extension(type, type_len);
  280. if (!ext)
  281. goto invalid_group;
  282. if (ptr + 2 > data + len) {
  283. l_util_debug(setting->debug_handler, setting->debug_data,
  284. "Embedded group had no payload");
  285. return -EINVAL;
  286. }
  287. bytes = ext->parse(ptr + 2, len - line_len);
  288. if (bytes < 0) {
  289. l_util_debug(setting->debug_handler, setting->debug_data,
  290. "Failed to parse embedded group data");
  291. return -EINVAL;
  292. }
  293. group = l_malloc(sizeof(struct embedded_group_data) + bytes + 1);
  294. group->name = l_strndup(name, name_len);
  295. memcpy(group->type, type, type_len);
  296. group->type[type_len] = '\0';
  297. group->len = bytes;
  298. memcpy(group->data, ptr + 2, bytes);
  299. group->data[bytes] = '\0';
  300. l_queue_push_tail(setting->embedded_groups, group);
  301. return bytes;
  302. invalid_group:
  303. l_util_debug(setting->debug_handler, setting->debug_data,
  304. "Invalid embedded group at line %zd", line);
  305. return -EINVAL;
  306. }
  307. static bool parse_group(struct l_settings *settings, const char *data,
  308. size_t len, size_t line)
  309. {
  310. size_t i = 1;
  311. size_t end;
  312. struct group_data *group;
  313. while (i < len && data[i] != ']') {
  314. if (l_ascii_isprint(data[i]) == false || data[i] == '[') {
  315. l_util_debug(settings->debug_handler,
  316. settings->debug_data,
  317. "Invalid group name at line %zd", line);
  318. return false;
  319. }
  320. i += 1;
  321. }
  322. if (i >= len) {
  323. l_util_debug(settings->debug_handler, settings->debug_data,
  324. "Unterminated group name at line %zd", line);
  325. return false;
  326. }
  327. end = i;
  328. i += 1;
  329. while (i < len && l_ascii_isblank(data[i]))
  330. i += 1;
  331. if (i != len) {
  332. l_util_debug(settings->debug_handler, settings->debug_data,
  333. "Junk characters at the end of line %zd", line);
  334. return false;
  335. }
  336. group = l_new(struct group_data, 1);
  337. group->name = l_strndup(data + 1, end - 1);
  338. group->settings = l_queue_new();
  339. l_queue_push_tail(settings->groups, group);
  340. return true;
  341. }
  342. static bool validate_key_character(char c)
  343. {
  344. if (l_ascii_isalnum(c))
  345. return true;
  346. if (c == '_' || c == '-' || c == '.')
  347. return true;
  348. return false;
  349. }
  350. static unsigned int parse_key(struct l_settings *settings, const char *data,
  351. size_t len, size_t line)
  352. {
  353. unsigned int i;
  354. unsigned int end;
  355. struct group_data *group;
  356. struct setting_data *pair;
  357. for (i = 0; i < len; i++) {
  358. if (validate_key_character(data[i]))
  359. continue;
  360. if (l_ascii_isblank(data[i]))
  361. break;
  362. l_util_debug(settings->debug_handler, settings->debug_data,
  363. "Invalid character in Key on line %zd", line);
  364. return 0;
  365. }
  366. end = i;
  367. /* Make sure the rest of the characters are blanks */
  368. while (i < len) {
  369. if (l_ascii_isblank(data[i++]))
  370. continue;
  371. l_util_debug(settings->debug_handler, settings->debug_data,
  372. "Garbage after Key on line %zd", line);
  373. return 0;
  374. }
  375. group = l_queue_peek_tail(settings->groups);
  376. pair = l_new(struct setting_data, 1);
  377. pair->key = l_strndup(data, end);
  378. l_queue_push_head(group->settings, pair);
  379. return end;
  380. }
  381. static bool parse_value(struct l_settings *settings, const char *data,
  382. size_t len, size_t line)
  383. {
  384. unsigned int end = len;
  385. struct group_data *group;
  386. struct setting_data *pair;
  387. group = l_queue_peek_tail(settings->groups);
  388. pair = l_queue_pop_head(group->settings);
  389. if (!l_utf8_validate(data, len, NULL)) {
  390. l_util_debug(settings->debug_handler, settings->debug_data,
  391. "Invalid UTF8 in value on line: %zd", line);
  392. l_free(pair->key);
  393. l_free(pair);
  394. return false;
  395. }
  396. pair->value = l_strndup(data, end);
  397. l_queue_push_tail(group->settings, pair);
  398. return true;
  399. }
  400. static bool parse_keyvalue(struct l_settings *settings, const char *data,
  401. size_t len, size_t line)
  402. {
  403. const char *equal = memchr(data, '=', len);
  404. if (!equal) {
  405. l_util_debug(settings->debug_handler, settings->debug_data,
  406. "Delimiter '=' not found on line: %zd", line);
  407. return false;
  408. }
  409. if (equal == data) {
  410. l_util_debug(settings->debug_handler, settings->debug_data,
  411. "Empty key on line: %zd", line);
  412. return false;
  413. }
  414. if (!parse_key(settings, data, equal - data, line))
  415. return false;
  416. equal += 1;
  417. while (equal < data + len && l_ascii_isblank(*equal))
  418. equal += 1;
  419. return parse_value(settings, equal, len - (equal - data), line);
  420. }
  421. LIB_EXPORT bool l_settings_load_from_data(struct l_settings *settings,
  422. const char *data, size_t len)
  423. {
  424. size_t pos = 0;
  425. bool r = true;
  426. bool has_group = false;
  427. const char *eol;
  428. size_t line = 1;
  429. size_t line_len;
  430. if (unlikely(!settings || !data || !len))
  431. return false;
  432. while (pos < len && r) {
  433. if (l_ascii_isblank(data[pos])) {
  434. pos += 1;
  435. continue;
  436. }
  437. if (data[pos] == '\n') {
  438. line += 1;
  439. pos += 1;
  440. continue;
  441. }
  442. eol = memchr(data + pos, '\n', len - pos);
  443. if (!eol)
  444. eol = data + len;
  445. line_len = eol - data - pos;
  446. if (line_len > 1 && data[pos] == '[' && data[pos + 1] == '@') {
  447. ssize_t ret;
  448. ret = parse_embedded_group(settings, data + pos,
  449. line_len, len - pos,
  450. line);
  451. if (ret < 0)
  452. return false;
  453. /*
  454. * This is the offset for the actual raw data, the
  455. * group line will be offset below
  456. */
  457. pos += ret;
  458. } else if (data[pos] == '[') {
  459. r = parse_group(settings, data + pos, line_len, line);
  460. if (r)
  461. has_group = true;
  462. } else if (data[pos] != '#') {
  463. if (!has_group)
  464. return false;
  465. r = parse_keyvalue(settings, data + pos, line_len,
  466. line);
  467. }
  468. pos += line_len;
  469. }
  470. return r;
  471. }
  472. LIB_EXPORT char *l_settings_to_data(const struct l_settings *settings,
  473. size_t *len)
  474. {
  475. struct l_string *buf;
  476. char *ret;
  477. const struct l_queue_entry *group_entry;
  478. if (unlikely(!settings))
  479. return NULL;
  480. buf = l_string_new(255);
  481. group_entry = l_queue_get_entries(settings->groups);
  482. while (group_entry) {
  483. struct group_data *group = group_entry->data;
  484. const struct l_queue_entry *setting_entry;
  485. l_string_append_printf(buf, "[%s]\n", group->name);
  486. setting_entry = l_queue_get_entries(group->settings);
  487. while (setting_entry) {
  488. struct setting_data *setting = setting_entry->data;
  489. l_string_append_printf(buf, "%s=%s\n",
  490. setting->key, setting->value);
  491. setting_entry = setting_entry->next;
  492. }
  493. if (group_entry->next)
  494. l_string_append_c(buf, '\n');
  495. group_entry = group_entry->next;
  496. }
  497. group_entry = l_queue_get_entries(settings->embedded_groups);
  498. if (group_entry && l_queue_length(settings->groups) > 0)
  499. l_string_append_c(buf, '\n');
  500. while (group_entry) {
  501. struct embedded_group_data *group = group_entry->data;
  502. l_string_append_printf(buf, "[@%s@%s]\n%s",
  503. group->type,
  504. group->name,
  505. group->data);
  506. if (group_entry->next)
  507. l_string_append_c(buf, '\n');
  508. group_entry = group_entry->next;
  509. }
  510. ret = l_string_unwrap(buf);
  511. if (len)
  512. *len = strlen(ret);
  513. return ret;
  514. }
  515. LIB_EXPORT bool l_settings_load_from_file(struct l_settings *settings,
  516. const char *filename)
  517. {
  518. int fd;
  519. struct stat st;
  520. char *data;
  521. bool r;
  522. if (unlikely(!settings || !filename))
  523. return false;
  524. fd = open(filename, O_RDONLY);
  525. if (fd < 0) {
  526. l_util_debug(settings->debug_handler, settings->debug_data,
  527. "Could not open %s (%s)", filename,
  528. strerror(errno));
  529. return false;
  530. }
  531. if (fstat(fd, &st) < 0) {
  532. l_util_debug(settings->debug_handler, settings->debug_data,
  533. "Could not stat %s (%s)", filename,
  534. strerror(errno));
  535. close(fd);
  536. return false;
  537. }
  538. /* Nothing to do, assume success */
  539. if (st.st_size == 0) {
  540. close(fd);
  541. return true;
  542. }
  543. data = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
  544. if (data == MAP_FAILED) {
  545. l_util_debug(settings->debug_handler, settings->debug_data,
  546. "Could not mmap %s (%s)", filename,
  547. strerror(errno));
  548. close(fd);
  549. return false;
  550. }
  551. r = l_settings_load_from_data(settings, data, st.st_size);
  552. munmap(data, st.st_size);
  553. close(fd);
  554. return r;
  555. }
  556. LIB_EXPORT bool l_settings_set_debug(struct l_settings *settings,
  557. l_settings_debug_cb_t callback,
  558. void *user_data,
  559. l_settings_destroy_cb_t destroy)
  560. {
  561. if (unlikely(!settings))
  562. return false;
  563. if (settings->debug_destroy)
  564. settings->debug_destroy(settings->debug_data);
  565. settings->debug_handler = callback;
  566. settings->debug_destroy = destroy;
  567. settings->debug_data = user_data;
  568. return true;
  569. }
  570. static bool group_match(const void *a, const void *b)
  571. {
  572. const struct group_data *group = a;
  573. const char *name = b;
  574. return !strcmp(group->name, name);
  575. }
  576. struct gather_data {
  577. int cur;
  578. char **v;
  579. };
  580. static void gather_groups(void *data, void *user_data)
  581. {
  582. struct group_data *group_data = data;
  583. struct gather_data *gather = user_data;
  584. gather->v[gather->cur++] = l_strdup(group_data->name);
  585. }
  586. LIB_EXPORT char **l_settings_get_groups(const struct l_settings *settings)
  587. {
  588. char **ret;
  589. struct gather_data gather;
  590. if (unlikely(!settings))
  591. return NULL;
  592. ret = l_new(char *, l_queue_length(settings->groups) + 1);
  593. gather.v = ret;
  594. gather.cur = 0;
  595. l_queue_foreach(settings->groups, gather_groups, &gather);
  596. return ret;
  597. }
  598. LIB_EXPORT bool l_settings_has_group(const struct l_settings *settings,
  599. const char *group_name)
  600. {
  601. struct group_data *group;
  602. if (unlikely(!settings))
  603. return false;
  604. group = l_queue_find(settings->groups, group_match, group_name);
  605. return !!group;
  606. }
  607. static bool key_match(const void *a, const void *b)
  608. {
  609. const struct setting_data *setting = a;
  610. const char *key = b;
  611. return !strcmp(setting->key, key);
  612. }
  613. static void gather_keys(void *data, void *user_data)
  614. {
  615. struct setting_data *setting_data = data;
  616. struct gather_data *gather = user_data;
  617. gather->v[gather->cur++] = l_strdup(setting_data->key);
  618. }
  619. LIB_EXPORT char **l_settings_get_keys(const struct l_settings *settings,
  620. const char *group_name)
  621. {
  622. char **ret;
  623. struct group_data *group_data;
  624. struct gather_data gather;
  625. if (unlikely(!settings))
  626. return NULL;
  627. group_data = l_queue_find(settings->groups, group_match, group_name);
  628. if (!group_data)
  629. return NULL;
  630. ret = l_new(char *, l_queue_length(group_data->settings) + 1);
  631. gather.v = ret;
  632. gather.cur = 0;
  633. l_queue_foreach(group_data->settings, gather_keys, &gather);
  634. return ret;
  635. }
  636. LIB_EXPORT bool l_settings_has_key(const struct l_settings *settings,
  637. const char *group_name, const char *key)
  638. {
  639. struct group_data *group;
  640. struct setting_data *setting;
  641. if (unlikely(!settings))
  642. return false;
  643. group = l_queue_find(settings->groups, group_match, group_name);
  644. if (!group)
  645. return false;
  646. setting = l_queue_find(group->settings, key_match, key);
  647. return !!setting;
  648. }
  649. LIB_EXPORT const char *l_settings_get_value(const struct l_settings *settings,
  650. const char *group_name,
  651. const char *key)
  652. {
  653. struct group_data *group;
  654. struct setting_data *setting;
  655. if (unlikely(!settings))
  656. return NULL;
  657. group = l_queue_find(settings->groups, group_match, group_name);
  658. if (!group)
  659. return NULL;
  660. setting = l_queue_find(group->settings, key_match, key);
  661. if (!setting)
  662. return NULL;
  663. return setting->value;
  664. }
  665. static bool validate_group_name(const char *group_name)
  666. {
  667. int i;
  668. for (i = 0; group_name[i]; i++) {
  669. if (!l_ascii_isprint(group_name[i]))
  670. return false;
  671. if (group_name[i] == ']' || group_name[i] == '[')
  672. return false;
  673. }
  674. return true;
  675. }
  676. LIB_EXPORT bool l_settings_add_group(struct l_settings *settings,
  677. const char *group_name)
  678. {
  679. struct group_data *group;
  680. if (unlikely(!settings || !group_name))
  681. return false;
  682. if (!validate_group_name(group_name)) {
  683. l_util_debug(settings->debug_handler, settings->debug_data,
  684. "Invalid group name %s", group_name);
  685. return false;
  686. }
  687. group = l_queue_find(settings->groups, group_match, group_name);
  688. if (group) {
  689. l_util_debug(settings->debug_handler, settings->debug_data,
  690. "Group %s exists", group_name);
  691. return true;
  692. }
  693. group = l_new(struct group_data, 1);
  694. group->name = l_strdup(group_name);
  695. group->settings = l_queue_new();
  696. l_queue_push_tail(settings->groups, group);
  697. return true;
  698. }
  699. static bool validate_key(const char *key)
  700. {
  701. int i;
  702. for (i = 0; key[i]; i++) {
  703. if (!validate_key_character(key[i]))
  704. return false;
  705. }
  706. return true;
  707. }
  708. static bool set_value(struct l_settings *settings, const char *group_name,
  709. const char *key, char *value)
  710. {
  711. struct group_data *group;
  712. struct setting_data *pair;
  713. if (!validate_group_name(group_name)) {
  714. l_util_debug(settings->debug_handler, settings->debug_data,
  715. "Invalid group name %s", group_name);
  716. goto error;
  717. }
  718. if (!validate_key(key)) {
  719. l_util_debug(settings->debug_handler, settings->debug_data,
  720. "Invalid key %s", key);
  721. goto error;
  722. }
  723. group = l_queue_find(settings->groups, group_match, group_name);
  724. if (!group) {
  725. group = l_new(struct group_data, 1);
  726. group->name = l_strdup(group_name);
  727. group->settings = l_queue_new();
  728. l_queue_push_tail(settings->groups, group);
  729. goto add_pair;
  730. }
  731. pair = l_queue_find(group->settings, key_match, key);
  732. if (!pair) {
  733. add_pair:
  734. pair = l_new(struct setting_data, 1);
  735. pair->key = l_strdup(key);
  736. pair->value = value;
  737. l_queue_push_tail(group->settings, pair);
  738. return true;
  739. }
  740. explicit_bzero(pair->value, strlen(pair->value));
  741. l_free(pair->value);
  742. pair->value = value;
  743. return true;
  744. error:
  745. explicit_bzero(value, strlen(value));
  746. l_free(value);
  747. return false;
  748. }
  749. LIB_EXPORT bool l_settings_set_value(struct l_settings *settings,
  750. const char *group_name, const char *key,
  751. const char *value)
  752. {
  753. if (unlikely(!settings || !value))
  754. return false;
  755. return set_value(settings, group_name, key, l_strdup(value));
  756. }
  757. LIB_EXPORT bool l_settings_get_bool(const struct l_settings *settings,
  758. const char *group_name, const char *key,
  759. bool *out)
  760. {
  761. const char *value;
  762. value = l_settings_get_value(settings, group_name, key);
  763. if (!value)
  764. return false;
  765. if (!strcasecmp(value, "true") || !strcmp(value, "1")) {
  766. if (out)
  767. *out = true;
  768. return true;
  769. }
  770. if (!strcasecmp(value, "false") || !strcmp(value, "0")) {
  771. if (out)
  772. *out = false;
  773. return true;
  774. }
  775. l_util_debug(settings->debug_handler, settings->debug_data,
  776. "Could not interpret %s as a bool", value);
  777. return false;
  778. }
  779. LIB_EXPORT bool l_settings_set_bool(struct l_settings *settings,
  780. const char *group_name, const char *key,
  781. bool in)
  782. {
  783. static const char *true_str = "true";
  784. static const char *false_str = "false";
  785. const char *v;
  786. if (in == false)
  787. v = false_str;
  788. else
  789. v = true_str;
  790. return l_settings_set_value(settings, group_name, key, v);
  791. }
  792. LIB_EXPORT bool l_settings_get_int(const struct l_settings *settings,
  793. const char *group_name,
  794. const char *key, int *out)
  795. {
  796. const char *value = l_settings_get_value(settings, group_name, key);
  797. long int r;
  798. int t;
  799. char *endp;
  800. if (!value)
  801. return false;
  802. if (*value == '\0')
  803. goto error;
  804. errno = 0;
  805. t = r = strtol(value, &endp, 0);
  806. if (*endp != '\0')
  807. goto error;
  808. if (unlikely(errno == ERANGE || r != t))
  809. goto error;
  810. if (out)
  811. *out = r;
  812. return true;
  813. error:
  814. l_util_debug(settings->debug_handler, settings->debug_data,
  815. "Could not interpret %s as an int", value);
  816. return false;
  817. }
  818. LIB_EXPORT bool l_settings_set_int(struct l_settings *settings,
  819. const char *group_name, const char *key,
  820. int in)
  821. {
  822. char buf[64];
  823. snprintf(buf, sizeof(buf), "%d", in);
  824. return l_settings_set_value(settings, group_name, key, buf);
  825. }
  826. LIB_EXPORT bool l_settings_get_uint(const struct l_settings *settings,
  827. const char *group_name, const char *key,
  828. unsigned int *out)
  829. {
  830. const char *value = l_settings_get_value(settings, group_name, key);
  831. unsigned long int r;
  832. unsigned int t;
  833. char *endp;
  834. if (!value)
  835. return false;
  836. if (*value == '\0')
  837. goto error;
  838. errno = 0;
  839. t = r = strtoul(value, &endp, 0);
  840. if (*endp != '\0')
  841. goto error;
  842. if (unlikely(errno == ERANGE || r != t))
  843. goto error;
  844. if (out)
  845. *out = r;
  846. return true;
  847. error:
  848. l_util_debug(settings->debug_handler, settings->debug_data,
  849. "Could not interpret %s as a uint", value);
  850. return false;
  851. }
  852. LIB_EXPORT bool l_settings_set_uint(struct l_settings *settings,
  853. const char *group_name, const char *key,
  854. unsigned int in)
  855. {
  856. char buf[64];
  857. snprintf(buf, sizeof(buf), "%u", in);
  858. return l_settings_set_value(settings, group_name, key, buf);
  859. }
  860. LIB_EXPORT bool l_settings_get_int64(const struct l_settings *settings,
  861. const char *group_name, const char *key,
  862. int64_t *out)
  863. {
  864. const char *value = l_settings_get_value(settings, group_name, key);
  865. int64_t r;
  866. char *endp;
  867. if (!value)
  868. return false;
  869. if (*value == '\0')
  870. goto error;
  871. errno = 0;
  872. r = strtoll(value, &endp, 0);
  873. if (*endp != '\0')
  874. goto error;
  875. if (unlikely(errno == ERANGE))
  876. goto error;
  877. if (out)
  878. *out = r;
  879. return true;
  880. error:
  881. l_util_debug(settings->debug_handler, settings->debug_data,
  882. "Could not interpret %s as an int64", value);
  883. return false;
  884. }
  885. LIB_EXPORT bool l_settings_set_int64(struct l_settings *settings,
  886. const char *group_name, const char *key,
  887. int64_t in)
  888. {
  889. char buf[64];
  890. snprintf(buf, sizeof(buf), "%" PRId64, in);
  891. return l_settings_set_value(settings, group_name, key, buf);
  892. }
  893. LIB_EXPORT bool l_settings_get_uint64(const struct l_settings *settings,
  894. const char *group_name, const char *key,
  895. uint64_t *out)
  896. {
  897. const char *value = l_settings_get_value(settings, group_name, key);
  898. uint64_t r;
  899. char *endp;
  900. if (!value)
  901. return false;
  902. if (*value == '\0')
  903. goto error;
  904. errno = 0;
  905. r = strtoull(value, &endp, 0);
  906. if (*endp != '\0')
  907. goto error;
  908. if (unlikely(errno == ERANGE))
  909. goto error;
  910. if (out)
  911. *out = r;
  912. return true;
  913. error:
  914. l_util_debug(settings->debug_handler, settings->debug_data,
  915. "Could not interpret %s as a uint64", value);
  916. return false;
  917. }
  918. LIB_EXPORT bool l_settings_set_uint64(struct l_settings *settings,
  919. const char *group_name, const char *key,
  920. uint64_t in)
  921. {
  922. char buf[64];
  923. snprintf(buf, sizeof(buf), "%" PRIu64, in);
  924. return l_settings_set_value(settings, group_name, key, buf);
  925. }
  926. LIB_EXPORT char *l_settings_get_string(const struct l_settings *settings,
  927. const char *group_name, const char *key)
  928. {
  929. const char *value = l_settings_get_value(settings, group_name, key);
  930. if (!value)
  931. return NULL;
  932. return unescape_value(value);
  933. }
  934. LIB_EXPORT bool l_settings_set_string(struct l_settings *settings,
  935. const char *group_name, const char *key,
  936. const char *value)
  937. {
  938. char *buf;
  939. if (unlikely(!settings || !value))
  940. return false;
  941. buf = escape_value(value);
  942. return set_value(settings, group_name, key, buf);
  943. }
  944. LIB_EXPORT char **l_settings_get_string_list(const struct l_settings *settings,
  945. const char *group_name,
  946. const char *key,
  947. const char delimiter)
  948. {
  949. const char *value = l_settings_get_value(settings, group_name, key);
  950. char *str;
  951. char **ret;
  952. if (!value)
  953. return NULL;
  954. str = unescape_value(value);
  955. if (str == NULL)
  956. return NULL;
  957. ret = l_strsplit(str, delimiter);
  958. l_free(str);
  959. return ret;
  960. }
  961. LIB_EXPORT bool l_settings_set_string_list(struct l_settings *settings,
  962. const char *group_name, const char *key,
  963. char **value, char delimiter)
  964. {
  965. char *buf;
  966. char *tmp;
  967. if (unlikely(!settings || !value))
  968. return false;
  969. tmp = l_strjoinv(value, delimiter);
  970. buf = escape_value(tmp);
  971. l_free(tmp);
  972. return set_value(settings, group_name, key, buf);
  973. }
  974. LIB_EXPORT bool l_settings_get_double(const struct l_settings *settings,
  975. const char *group_name, const char *key,
  976. double *out)
  977. {
  978. const char *value = l_settings_get_value(settings, group_name, key);
  979. char *endp;
  980. double r;
  981. if (!value)
  982. return NULL;
  983. if (*value == '\0')
  984. goto error;
  985. errno = 0;
  986. r = strtod(value, &endp);
  987. if (*endp != '\0')
  988. goto error;
  989. if (unlikely(errno == ERANGE))
  990. goto error;
  991. if (out)
  992. *out = r;
  993. return true;
  994. error:
  995. l_util_debug(settings->debug_handler, settings->debug_data,
  996. "Could not interpret %s as a double", value);
  997. return false;
  998. }
  999. LIB_EXPORT bool l_settings_set_double(struct l_settings *settings,
  1000. const char *group_name, const char *key,
  1001. double in)
  1002. {
  1003. L_AUTO_FREE_VAR(char *, buf);
  1004. buf = l_strdup_printf("%f", in);
  1005. return l_settings_set_value(settings, group_name, key, buf);
  1006. }
  1007. LIB_EXPORT bool l_settings_get_float(const struct l_settings *settings,
  1008. const char *group_name, const char *key,
  1009. float *out)
  1010. {
  1011. const char *value = l_settings_get_value(settings, group_name, key);
  1012. char *endp;
  1013. float r;
  1014. if (!value)
  1015. return NULL;
  1016. if (*value == '\0')
  1017. goto error;
  1018. errno = 0;
  1019. r = strtof(value, &endp);
  1020. if (*endp != '\0')
  1021. goto error;
  1022. if (unlikely(errno == ERANGE))
  1023. goto error;
  1024. if (out)
  1025. *out = r;
  1026. return true;
  1027. error:
  1028. l_util_debug(settings->debug_handler, settings->debug_data,
  1029. "Could not interpret %s as a float", value);
  1030. return false;
  1031. }
  1032. LIB_EXPORT bool l_settings_set_float(struct l_settings *settings,
  1033. const char *group_name, const char *key,
  1034. float in)
  1035. {
  1036. L_AUTO_FREE_VAR(char *, buf);
  1037. buf = l_strdup_printf("%f", (double)in);
  1038. return l_settings_set_value(settings, group_name, key, buf);
  1039. }
  1040. LIB_EXPORT uint8_t *l_settings_get_bytes(const struct l_settings *settings,
  1041. const char *group_name,
  1042. const char *key,
  1043. size_t *out_len)
  1044. {
  1045. const char *value = l_settings_get_value(settings, group_name, key);
  1046. if (!value)
  1047. return NULL;
  1048. if (value[0] == '\0') {
  1049. *out_len = 0;
  1050. /* Return something that can be l_freed but is not a NULL */
  1051. return l_memdup("", 1);
  1052. }
  1053. return l_util_from_hexstring(value, out_len);
  1054. }
  1055. LIB_EXPORT bool l_settings_set_bytes(struct l_settings *settings,
  1056. const char *group_name, const char *key,
  1057. const uint8_t *value, size_t value_len)
  1058. {
  1059. char *buf;
  1060. if (unlikely(!settings || !value))
  1061. return false;
  1062. if (value_len)
  1063. buf = l_util_hexstring(value, value_len);
  1064. else
  1065. buf = l_strdup("");
  1066. return set_value(settings, group_name, key, buf);
  1067. }
  1068. LIB_EXPORT bool l_settings_remove_group(struct l_settings *settings,
  1069. const char *group_name)
  1070. {
  1071. struct group_data *group;
  1072. if (unlikely(!settings))
  1073. return false;
  1074. group = l_queue_remove_if(settings->groups, group_match, group_name);
  1075. if (!group)
  1076. return false;
  1077. group_destroy(group);
  1078. return true;
  1079. }
  1080. LIB_EXPORT bool l_settings_remove_key(struct l_settings *settings,
  1081. const char *group_name,
  1082. const char *key)
  1083. {
  1084. struct group_data *group;
  1085. struct setting_data *setting;
  1086. if (unlikely(!settings))
  1087. return false;
  1088. group = l_queue_find(settings->groups, group_match, group_name);
  1089. if (!group)
  1090. return false;
  1091. setting = l_queue_remove_if(group->settings, key_match, key);
  1092. if (!setting)
  1093. return false;
  1094. setting_destroy(setting);
  1095. return true;
  1096. }
  1097. static void gather_embedded_groups(void *data, void *user_data)
  1098. {
  1099. struct embedded_group_data *group_data = data;
  1100. struct gather_data *gather = user_data;
  1101. gather->v[gather->cur++] = l_strdup(group_data->name);
  1102. }
  1103. LIB_EXPORT char **l_settings_get_embedded_groups(struct l_settings *settings)
  1104. {
  1105. char **ret;
  1106. struct gather_data gather;
  1107. if (unlikely(!settings))
  1108. return NULL;
  1109. ret = l_new(char *, l_queue_length(settings->groups) + 1);
  1110. gather.v = ret;
  1111. gather.cur = 0;
  1112. l_queue_foreach(settings->embedded_groups, gather_embedded_groups,
  1113. &gather);
  1114. return ret;
  1115. }
  1116. static bool embedded_group_match(const void *a, const void *b)
  1117. {
  1118. const struct embedded_group_data *group = a;
  1119. const char *name = b;
  1120. return !strcmp(group->name, name);
  1121. }
  1122. LIB_EXPORT bool l_settings_has_embedded_group(struct l_settings *settings,
  1123. const char *group)
  1124. {
  1125. struct embedded_group_data *group_data;
  1126. if (unlikely(!settings))
  1127. return false;
  1128. group_data = l_queue_find(settings->embedded_groups,
  1129. embedded_group_match, group);
  1130. return group_data != NULL;
  1131. }
  1132. LIB_EXPORT const char *l_settings_get_embedded_value(
  1133. struct l_settings *settings,
  1134. const char *group_name,
  1135. const char **out_type)
  1136. {
  1137. struct embedded_group_data *group;
  1138. if (unlikely(!settings))
  1139. return false;
  1140. group = l_queue_find(settings->embedded_groups,
  1141. embedded_group_match, group_name);
  1142. if (!group)
  1143. return NULL;
  1144. if (out_type)
  1145. *out_type = group->type;
  1146. return group->data;
  1147. }