You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210
  1. /*
  2. * Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. #include <stdint.h>
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <strings.h>
  23. #include <byteswap.h>
  24. #include <errno.h>
  25. #include <assert.h>
  26. #include <gpxe/in.h>
  27. #include <gpxe/vsprintf.h>
  28. #include <gpxe/dhcp.h>
  29. #include <gpxe/uuid.h>
  30. #include <gpxe/uri.h>
  31. #include <gpxe/settings.h>
  32. /** @file
  33. *
  34. * Configuration settings
  35. *
  36. */
  37. /** Registered settings */
  38. static struct setting settings[0]
  39. __table_start ( struct setting, settings );
  40. static struct setting settings_end[0]
  41. __table_end ( struct setting, settings );
  42. /** Registered setting types */
  43. static struct setting_type setting_types[0]
  44. __table_start ( struct setting_type, setting_types );
  45. static struct setting_type setting_types_end[0]
  46. __table_end ( struct setting_type, setting_types );
  47. /** Registered settings applicators */
  48. static struct settings_applicator settings_applicators[0]
  49. __table_start ( struct settings_applicator, settings_applicators );
  50. static struct settings_applicator settings_applicators_end[0]
  51. __table_end ( struct settings_applicator, settings_applicators );
  52. /******************************************************************************
  53. *
  54. * Registered settings blocks
  55. *
  56. ******************************************************************************
  57. */
  58. /**
  59. * Store value of simple setting
  60. *
  61. * @v options DHCP option block
  62. * @v setting Setting to store
  63. * @v data Setting data, or NULL to clear setting
  64. * @v len Length of setting data
  65. * @ret rc Return status code
  66. */
  67. int simple_settings_store ( struct settings *settings, struct setting *setting,
  68. const void *data, size_t len ) {
  69. struct simple_settings *simple =
  70. container_of ( settings, struct simple_settings, settings );
  71. return dhcpopt_extensible_store ( &simple->dhcpopts, setting->tag,
  72. data, len );
  73. }
  74. /**
  75. * Fetch value of simple setting
  76. *
  77. * @v options DHCP option block
  78. * @v setting Setting to fetch
  79. * @v data Buffer to fill with setting data
  80. * @v len Length of buffer
  81. * @ret len Length of setting data, or negative error
  82. */
  83. int simple_settings_fetch ( struct settings *settings, struct setting *setting,
  84. void *data, size_t len ) {
  85. struct simple_settings *simple =
  86. container_of ( settings, struct simple_settings, settings );
  87. return dhcpopt_fetch ( &simple->dhcpopts, setting->tag, data, len );
  88. }
  89. /** Simple settings operations */
  90. struct settings_operations simple_settings_operations = {
  91. .store = simple_settings_store,
  92. .fetch = simple_settings_fetch,
  93. };
  94. /** Root simple settings block */
  95. struct simple_settings simple_settings_root = {
  96. .settings = {
  97. .refcnt = NULL,
  98. .name = "",
  99. .siblings =
  100. LIST_HEAD_INIT ( simple_settings_root.settings.siblings ),
  101. .children =
  102. LIST_HEAD_INIT ( simple_settings_root.settings.children ),
  103. .op = &simple_settings_operations,
  104. },
  105. };
  106. /** Root settings block */
  107. #define settings_root simple_settings_root.settings
  108. /**
  109. * Apply all settings
  110. *
  111. * @ret rc Return status code
  112. */
  113. static int apply_settings ( void ) {
  114. struct settings_applicator *applicator;
  115. int rc;
  116. /* Call all settings applicators */
  117. for ( applicator = settings_applicators ;
  118. applicator < settings_applicators_end ; applicator++ ) {
  119. if ( ( rc = applicator->apply() ) != 0 ) {
  120. DBG ( "Could not apply settings using applicator "
  121. "%p: %s\n", applicator, strerror ( rc ) );
  122. return rc;
  123. }
  124. }
  125. return 0;
  126. }
  127. /**
  128. * Reprioritise settings
  129. *
  130. * @v settings Settings block
  131. *
  132. * Reorders the settings block amongst its siblings according to its
  133. * priority.
  134. */
  135. static void reprioritise_settings ( struct settings *settings ) {
  136. struct settings *parent = settings->parent;
  137. long priority;
  138. struct settings *tmp;
  139. long tmp_priority;
  140. /* Stop when we reach the top of the tree */
  141. if ( ! parent )
  142. return;
  143. /* Read priority, if present */
  144. priority = fetch_intz_setting ( settings, &priority_setting );
  145. /* Remove from siblings list */
  146. list_del ( &settings->siblings );
  147. /* Reinsert after any existing blocks which have a higher priority */
  148. list_for_each_entry ( tmp, &parent->children, siblings ) {
  149. tmp_priority = fetch_intz_setting ( tmp, &priority_setting );
  150. if ( priority > tmp_priority )
  151. break;
  152. }
  153. list_add_tail ( &settings->siblings, &tmp->siblings );
  154. /* Recurse up the tree */
  155. reprioritise_settings ( parent );
  156. }
  157. /**
  158. * Register settings block
  159. *
  160. * @v settings Settings block
  161. * @v parent Parent settings block, or NULL
  162. * @ret rc Return status code
  163. */
  164. int register_settings ( struct settings *settings, struct settings *parent ) {
  165. struct settings *old_settings;
  166. /* NULL parent => add to settings root */
  167. assert ( settings != NULL );
  168. if ( parent == NULL )
  169. parent = &settings_root;
  170. /* Remove any existing settings with the same name */
  171. if ( ( old_settings = find_child_settings ( parent, settings->name ) ))
  172. unregister_settings ( old_settings );
  173. /* Add to list of settings */
  174. ref_get ( settings->refcnt );
  175. ref_get ( parent->refcnt );
  176. settings->parent = parent;
  177. list_add_tail ( &settings->siblings, &parent->children );
  178. DBGC ( settings, "Settings %p registered\n", settings );
  179. /* Fix up settings priority */
  180. reprioritise_settings ( settings );
  181. /* Apply potentially-updated settings */
  182. apply_settings();
  183. return 0;
  184. }
  185. /**
  186. * Unregister settings block
  187. *
  188. * @v settings Settings block
  189. */
  190. void unregister_settings ( struct settings *settings ) {
  191. /* Remove from list of settings */
  192. ref_put ( settings->refcnt );
  193. ref_put ( settings->parent->refcnt );
  194. settings->parent = NULL;
  195. list_del ( &settings->siblings );
  196. DBGC ( settings, "Settings %p unregistered\n", settings );
  197. /* Apply potentially-updated settings */
  198. apply_settings();
  199. }
  200. /**
  201. * Find child named settings block
  202. *
  203. * @v parent Parent settings block
  204. * @v name Name within this parent
  205. * @ret settings Settings block, or NULL
  206. */
  207. struct settings * find_child_settings ( struct settings *parent,
  208. const char *name ) {
  209. struct settings *settings;
  210. size_t len;
  211. /* NULL parent => add to settings root */
  212. if ( parent == NULL )
  213. parent = &settings_root;
  214. /* Look for a child whose name matches the initial component */
  215. list_for_each_entry ( settings, &parent->children, siblings ) {
  216. len = strlen ( settings->name );
  217. if ( strncmp ( name, settings->name, len ) != 0 )
  218. continue;
  219. if ( name[len] == 0 )
  220. return settings;
  221. if ( name[len] == '.' )
  222. return find_child_settings ( settings,
  223. ( name + len + 1 ) );
  224. }
  225. return NULL;
  226. }
  227. /**
  228. * Find named settings block
  229. *
  230. * @v name Name
  231. * @ret settings Settings block, or NULL
  232. */
  233. struct settings * find_settings ( const char *name ) {
  234. /* If name is empty, use the root */
  235. if ( ! *name )
  236. return &settings_root;
  237. return find_child_settings ( &settings_root, name );
  238. }
  239. /******************************************************************************
  240. *
  241. * Core settings routines
  242. *
  243. ******************************************************************************
  244. */
  245. /**
  246. * Store value of setting
  247. *
  248. * @v settings Settings block, or NULL
  249. * @v setting Setting to store
  250. * @v data Setting data, or NULL to clear setting
  251. * @v len Length of setting data
  252. * @ret rc Return status code
  253. */
  254. int store_setting ( struct settings *settings, struct setting *setting,
  255. const void *data, size_t len ) {
  256. int rc;
  257. /* NULL settings implies storing into the global settings root */
  258. if ( ! settings )
  259. settings = &settings_root;
  260. /* Store setting */
  261. if ( ( rc = settings->op->store ( settings, setting,
  262. data, len ) ) != 0 )
  263. return rc;
  264. /* Reprioritise settings if necessary */
  265. if ( setting_cmp ( setting, &priority_setting ) == 0 )
  266. reprioritise_settings ( settings );
  267. /* If these settings are registered, apply potentially-updated
  268. * settings
  269. */
  270. for ( ; settings ; settings = settings->parent ) {
  271. if ( settings == &settings_root ) {
  272. if ( ( rc = apply_settings() ) != 0 )
  273. return rc;
  274. break;
  275. }
  276. }
  277. return 0;
  278. }
  279. /**
  280. * Fetch value of setting
  281. *
  282. * @v settings Settings block, or NULL to search all blocks
  283. * @v setting Setting to fetch
  284. * @v data Buffer to fill with setting data
  285. * @v len Length of buffer
  286. * @ret len Length of setting data, or negative error
  287. *
  288. * The actual length of the setting will be returned even if
  289. * the buffer was too small.
  290. */
  291. int fetch_setting ( struct settings *settings, struct setting *setting,
  292. void *data, size_t len ) {
  293. struct settings *child;
  294. int ret;
  295. /* Avoid returning uninitialised data on error */
  296. memset ( data, 0, len );
  297. /* NULL settings implies starting at the global settings root */
  298. if ( ! settings )
  299. settings = &settings_root;
  300. /* Try this block first */
  301. if ( ( ret = settings->op->fetch ( settings, setting,
  302. data, len ) ) >= 0 )
  303. return ret;
  304. /* Recurse into each child block in turn */
  305. list_for_each_entry ( child, &settings->children, siblings ) {
  306. if ( ( ret = fetch_setting ( child, setting,
  307. data, len ) ) >= 0 )
  308. return ret;
  309. }
  310. return -ENOENT;
  311. }
  312. /**
  313. * Fetch length of setting
  314. *
  315. * @v settings Settings block, or NULL to search all blocks
  316. * @v setting Setting to fetch
  317. * @ret len Length of setting data, or negative error
  318. *
  319. * This function can also be used as an existence check for the
  320. * setting.
  321. */
  322. int fetch_setting_len ( struct settings *settings, struct setting *setting ) {
  323. return fetch_setting ( settings, setting, NULL, 0 );
  324. }
  325. /**
  326. * Fetch value of string setting
  327. *
  328. * @v settings Settings block, or NULL to search all blocks
  329. * @v setting Setting to fetch
  330. * @v data Buffer to fill with setting string data
  331. * @v len Length of buffer
  332. * @ret len Length of string setting, or negative error
  333. *
  334. * The resulting string is guaranteed to be correctly NUL-terminated.
  335. * The returned length will be the length of the underlying setting
  336. * data.
  337. */
  338. int fetch_string_setting ( struct settings *settings, struct setting *setting,
  339. char *data, size_t len ) {
  340. memset ( data, 0, len );
  341. return fetch_setting ( settings, setting, data,
  342. ( ( len > 0 ) ? ( len - 1 ) : 0 ) );
  343. }
  344. /**
  345. * Fetch value of string setting
  346. *
  347. * @v settings Settings block, or NULL to search all blocks
  348. * @v setting Setting to fetch
  349. * @v data Buffer to allocate and fill with setting string data
  350. * @ret len Length of string setting, or negative error
  351. *
  352. * The resulting string is guaranteed to be correctly NUL-terminated.
  353. * The returned length will be the length of the underlying setting
  354. * data. The caller is responsible for eventually freeing the
  355. * allocated buffer.
  356. */
  357. int fetch_string_setting_copy ( struct settings *settings,
  358. struct setting *setting,
  359. char **data ) {
  360. int len;
  361. int check_len;
  362. len = fetch_setting_len ( settings, setting );
  363. if ( len < 0 )
  364. return len;
  365. *data = malloc ( len + 1 );
  366. if ( ! *data )
  367. return -ENOMEM;
  368. fetch_string_setting ( settings, setting, *data, ( len + 1 ) );
  369. assert ( check_len == len );
  370. return len;
  371. }
  372. /**
  373. * Fetch value of IPv4 address setting
  374. *
  375. * @v settings Settings block, or NULL to search all blocks
  376. * @v setting Setting to fetch
  377. * @v inp IPv4 address to fill in
  378. * @ret len Length of setting, or negative error
  379. */
  380. int fetch_ipv4_setting ( struct settings *settings, struct setting *setting,
  381. struct in_addr *inp ) {
  382. int len;
  383. len = fetch_setting ( settings, setting, inp, sizeof ( *inp ) );
  384. if ( len < 0 )
  385. return len;
  386. if ( len < ( int ) sizeof ( *inp ) )
  387. return -ERANGE;
  388. return len;
  389. }
  390. /**
  391. * Fetch value of signed integer setting
  392. *
  393. * @v settings Settings block, or NULL to search all blocks
  394. * @v setting Setting to fetch
  395. * @v value Integer value to fill in
  396. * @ret len Length of setting, or negative error
  397. */
  398. int fetch_int_setting ( struct settings *settings, struct setting *setting,
  399. long *value ) {
  400. union {
  401. uint8_t u8[ sizeof ( long ) ];
  402. int8_t s8[ sizeof ( long ) ];
  403. } buf;
  404. int len;
  405. int i;
  406. /* Avoid returning uninitialised data on error */
  407. *value = 0;
  408. /* Fetch raw (network-ordered, variable-length) setting */
  409. len = fetch_setting ( settings, setting, &buf, sizeof ( buf ) );
  410. if ( len < 0 )
  411. return len;
  412. if ( len > ( int ) sizeof ( buf ) )
  413. return -ERANGE;
  414. /* Convert to host-ordered signed long */
  415. *value = ( ( buf.s8[0] >= 0 ) ? 0 : -1L );
  416. for ( i = 0 ; i < len ; i++ ) {
  417. *value = ( ( *value << 8 ) | buf.u8[i] );
  418. }
  419. return len;
  420. }
  421. /**
  422. * Fetch value of unsigned integer setting
  423. *
  424. * @v settings Settings block, or NULL to search all blocks
  425. * @v setting Setting to fetch
  426. * @v value Integer value to fill in
  427. * @ret len Length of setting, or negative error
  428. */
  429. int fetch_uint_setting ( struct settings *settings, struct setting *setting,
  430. unsigned long *value ) {
  431. long svalue;
  432. int len;
  433. /* Avoid returning uninitialised data on error */
  434. *value = 0;
  435. /* Fetch as a signed long */
  436. len = fetch_int_setting ( settings, setting, &svalue );
  437. if ( len < 0 )
  438. return len;
  439. /* Mask off sign-extended bits */
  440. *value = ( svalue & ( -1UL >> ( sizeof ( long ) - len ) ) );
  441. return len;
  442. }
  443. /**
  444. * Fetch value of signed integer setting, or zero
  445. *
  446. * @v settings Settings block, or NULL to search all blocks
  447. * @v setting Setting to fetch
  448. * @ret value Setting value, or zero
  449. */
  450. long fetch_intz_setting ( struct settings *settings, struct setting *setting ){
  451. long value;
  452. fetch_int_setting ( settings, setting, &value );
  453. return value;
  454. }
  455. /**
  456. * Fetch value of unsigned integer setting, or zero
  457. *
  458. * @v settings Settings block, or NULL to search all blocks
  459. * @v setting Setting to fetch
  460. * @ret value Setting value, or zero
  461. */
  462. unsigned long fetch_uintz_setting ( struct settings *settings,
  463. struct setting *setting ) {
  464. unsigned long value;
  465. fetch_uint_setting ( settings, setting, &value );
  466. return value;
  467. }
  468. /**
  469. * Fetch value of UUID setting
  470. *
  471. * @v settings Settings block, or NULL to search all blocks
  472. * @v setting Setting to fetch
  473. * @v uuid UUID to fill in
  474. * @ret len Length of setting, or negative error
  475. */
  476. int fetch_uuid_setting ( struct settings *settings, struct setting *setting,
  477. union uuid *uuid ) {
  478. int len;
  479. len = fetch_setting ( settings, setting, uuid, sizeof ( *uuid ) );
  480. if ( len < 0 )
  481. return len;
  482. if ( len != sizeof ( *uuid ) )
  483. return -ERANGE;
  484. return len;
  485. }
  486. /**
  487. * Compare two settings
  488. *
  489. * @v a Setting to compare
  490. * @v b Setting to compare
  491. * @ret 0 Settings are the same
  492. * @ret non-zero Settings are not the same
  493. */
  494. int setting_cmp ( struct setting *a, struct setting *b ) {
  495. /* If the settings have tags, compare them */
  496. if ( a->tag && ( a->tag == b->tag ) )
  497. return 0;
  498. /* Otherwise, compare the names */
  499. return strcmp ( a->name, b->name );
  500. }
  501. /******************************************************************************
  502. *
  503. * Formatted setting routines
  504. *
  505. ******************************************************************************
  506. */
  507. /**
  508. * Store value of typed setting
  509. *
  510. * @v settings Settings block
  511. * @v setting Setting to store
  512. * @v type Settings type
  513. * @v value Formatted setting data, or NULL
  514. * @ret rc Return status code
  515. */
  516. int storef_setting ( struct settings *settings, struct setting *setting,
  517. const char *value ) {
  518. /* NULL value implies deletion. Avoid imposing the burden of
  519. * checking for NULL values on each typed setting's storef()
  520. * method.
  521. */
  522. if ( ! value )
  523. return delete_setting ( settings, setting );
  524. return setting->type->storef ( settings, setting, value );
  525. }
  526. /**
  527. * Find named setting
  528. *
  529. * @v name Name
  530. * @ret setting Named setting, or NULL
  531. */
  532. static struct setting * find_setting ( const char *name ) {
  533. struct setting *setting;
  534. for ( setting = settings ; setting < settings_end ; setting++ ) {
  535. if ( strcmp ( name, setting->name ) == 0 )
  536. return setting;
  537. }
  538. return NULL;
  539. }
  540. /**
  541. * Find setting type
  542. *
  543. * @v name Name
  544. * @ret type Setting type, or NULL
  545. */
  546. static struct setting_type * find_setting_type ( const char *name ) {
  547. struct setting_type *type;
  548. for ( type = setting_types ; type < setting_types_end ; type++ ) {
  549. if ( strcmp ( name, type->name ) == 0 )
  550. return type;
  551. }
  552. return NULL;
  553. }
  554. /**
  555. * Parse setting name
  556. *
  557. * @v name Name of setting
  558. * @v settings Settings block to fill in
  559. * @v setting Setting to fill in
  560. * @ret rc Return status code
  561. *
  562. * Interprets a name of the form
  563. * "[settings_name/]tag_name[:type_name]" and fills in the appropriate
  564. * fields.
  565. */
  566. static int parse_setting_name ( const char *name, struct settings **settings,
  567. struct setting *setting ) {
  568. char tmp_name[ strlen ( name ) + 1 ];
  569. char *settings_name;
  570. char *setting_name;
  571. char *type_name;
  572. struct setting *named_setting;
  573. char *tmp;
  574. /* Set defaults */
  575. *settings = &settings_root;
  576. memset ( setting, 0, sizeof ( *setting ) );
  577. setting->type = &setting_type_hex;
  578. /* Split name into "[settings_name/]setting_name[:type_name]" */
  579. memcpy ( tmp_name, name, sizeof ( tmp_name ) );
  580. if ( ( setting_name = strchr ( tmp_name, '/' ) ) != NULL ) {
  581. *(setting_name++) = 0;
  582. settings_name = tmp_name;
  583. } else {
  584. setting_name = tmp_name;
  585. settings_name = NULL;
  586. }
  587. if ( ( type_name = strchr ( setting_name, ':' ) ) != NULL )
  588. *(type_name++) = 0;
  589. /* Identify settings block, if specified */
  590. if ( settings_name ) {
  591. *settings = find_settings ( settings_name );
  592. if ( *settings == NULL ) {
  593. DBG ( "Unrecognised settings block \"%s\" in \"%s\"\n",
  594. settings_name, name );
  595. return -ENODEV;
  596. }
  597. }
  598. /* Identify tag number */
  599. if ( ( named_setting = find_setting ( setting_name ) ) != NULL ) {
  600. memcpy ( setting, named_setting, sizeof ( *setting ) );
  601. } else {
  602. /* Unrecognised name: try to interpret as a tag number */
  603. tmp = setting_name;
  604. while ( 1 ) {
  605. setting->tag = ( ( setting->tag << 8 ) |
  606. strtoul ( tmp, &tmp, 0 ) );
  607. if ( *tmp == 0 )
  608. break;
  609. if ( *tmp != '.' ) {
  610. DBG ( "Invalid setting \"%s\" in \"%s\"\n",
  611. setting_name, name );
  612. return -ENOENT;
  613. }
  614. tmp++;
  615. }
  616. setting->tag |= (*settings)->tag_magic;
  617. }
  618. /* Identify setting type, if specified */
  619. if ( type_name ) {
  620. setting->type = find_setting_type ( type_name );
  621. if ( setting->type == NULL ) {
  622. DBG ( "Invalid setting type \"%s\" in \"%s\"\n",
  623. type_name, name );
  624. return -ENOTSUP;
  625. }
  626. }
  627. return 0;
  628. }
  629. /**
  630. * Parse and store value of named setting
  631. *
  632. * @v name Name of setting
  633. * @v value Formatted setting data, or NULL
  634. * @ret rc Return status code
  635. */
  636. int storef_named_setting ( const char *name, const char *value ) {
  637. struct settings *settings;
  638. struct setting setting;
  639. int rc;
  640. if ( ( rc = parse_setting_name ( name, &settings, &setting ) ) != 0 )
  641. return rc;
  642. return storef_setting ( settings, &setting, value );
  643. }
  644. /**
  645. * Fetch and format value of named setting
  646. *
  647. * @v name Name of setting
  648. * @v buf Buffer to contain formatted value
  649. * @v len Length of buffer
  650. * @ret len Length of formatted value, or negative error
  651. */
  652. int fetchf_named_setting ( const char *name, char *buf, size_t len ) {
  653. struct settings *settings;
  654. struct setting setting;
  655. int rc;
  656. if ( ( rc = parse_setting_name ( name, &settings, &setting ) ) != 0 )
  657. return rc;
  658. return fetchf_setting ( settings, &setting, buf, len );
  659. }
  660. /******************************************************************************
  661. *
  662. * Setting types
  663. *
  664. ******************************************************************************
  665. */
  666. /**
  667. * Parse and store value of string setting
  668. *
  669. * @v settings Settings block
  670. * @v setting Setting to store
  671. * @v value Formatted setting data
  672. * @ret rc Return status code
  673. */
  674. static int storef_string ( struct settings *settings, struct setting *setting,
  675. const char *value ) {
  676. return store_setting ( settings, setting, value, strlen ( value ) );
  677. }
  678. /**
  679. * Fetch and format value of string setting
  680. *
  681. * @v settings Settings block, or NULL to search all blocks
  682. * @v setting Setting to fetch
  683. * @v buf Buffer to contain formatted value
  684. * @v len Length of buffer
  685. * @ret len Length of formatted value, or negative error
  686. */
  687. static int fetchf_string ( struct settings *settings, struct setting *setting,
  688. char *buf, size_t len ) {
  689. return fetch_string_setting ( settings, setting, buf, len );
  690. }
  691. /** A string setting type */
  692. struct setting_type setting_type_string __setting_type = {
  693. .name = "string",
  694. .storef = storef_string,
  695. .fetchf = fetchf_string,
  696. };
  697. /**
  698. * Parse and store value of URI-encoded string setting
  699. *
  700. * @v settings Settings block
  701. * @v setting Setting to store
  702. * @v value Formatted setting data
  703. * @ret rc Return status code
  704. */
  705. static int storef_uristring ( struct settings *settings,
  706. struct setting *setting,
  707. const char *value ) {
  708. char buf[ strlen ( value ) + 1 ]; /* Decoding never expands string */
  709. size_t len;
  710. len = uri_decode ( value, buf, sizeof ( buf ) );
  711. return store_setting ( settings, setting, buf, len );
  712. }
  713. /**
  714. * Fetch and format value of URI-encoded string setting
  715. *
  716. * @v settings Settings block, or NULL to search all blocks
  717. * @v setting Setting to fetch
  718. * @v buf Buffer to contain formatted value
  719. * @v len Length of buffer
  720. * @ret len Length of formatted value, or negative error
  721. */
  722. static int fetchf_uristring ( struct settings *settings,
  723. struct setting *setting,
  724. char *buf, size_t len ) {
  725. ssize_t raw_len;
  726. /* We need to always retrieve the full raw string to know the
  727. * length of the encoded string.
  728. */
  729. raw_len = fetch_setting ( settings, setting, NULL, 0 );
  730. if ( raw_len < 0 )
  731. return raw_len;
  732. {
  733. char raw_buf[ raw_len + 1 ];
  734. fetch_string_setting ( settings, setting, raw_buf,
  735. sizeof ( raw_buf ) );
  736. return uri_encode ( raw_buf, buf, len );
  737. }
  738. }
  739. /** A URI-encoded string setting type */
  740. struct setting_type setting_type_uristring __setting_type = {
  741. .name = "uristring",
  742. .storef = storef_uristring,
  743. .fetchf = fetchf_uristring,
  744. };
  745. /**
  746. * Parse and store value of IPv4 address setting
  747. *
  748. * @v settings Settings block
  749. * @v setting Setting to store
  750. * @v value Formatted setting data
  751. * @ret rc Return status code
  752. */
  753. static int storef_ipv4 ( struct settings *settings, struct setting *setting,
  754. const char *value ) {
  755. struct in_addr ipv4;
  756. if ( inet_aton ( value, &ipv4 ) == 0 )
  757. return -EINVAL;
  758. return store_setting ( settings, setting, &ipv4, sizeof ( ipv4 ) );
  759. }
  760. /**
  761. * Fetch and format value of IPv4 address setting
  762. *
  763. * @v settings Settings block, or NULL to search all blocks
  764. * @v setting Setting to fetch
  765. * @v buf Buffer to contain formatted value
  766. * @v len Length of buffer
  767. * @ret len Length of formatted value, or negative error
  768. */
  769. static int fetchf_ipv4 ( struct settings *settings, struct setting *setting,
  770. char *buf, size_t len ) {
  771. struct in_addr ipv4;
  772. int raw_len;
  773. if ( ( raw_len = fetch_ipv4_setting ( settings, setting, &ipv4 ) ) < 0)
  774. return raw_len;
  775. return snprintf ( buf, len, "%s", inet_ntoa ( ipv4 ) );
  776. }
  777. /** An IPv4 address setting type */
  778. struct setting_type setting_type_ipv4 __setting_type = {
  779. .name = "ipv4",
  780. .storef = storef_ipv4,
  781. .fetchf = fetchf_ipv4,
  782. };
  783. /**
  784. * Parse and store value of integer setting
  785. *
  786. * @v settings Settings block
  787. * @v setting Setting to store
  788. * @v value Formatted setting data
  789. * @v size Integer size, in bytes
  790. * @ret rc Return status code
  791. */
  792. static int storef_int ( struct settings *settings, struct setting *setting,
  793. const char *value, unsigned int size ) {
  794. union {
  795. uint32_t num;
  796. uint8_t bytes[4];
  797. } u;
  798. char *endp;
  799. u.num = htonl ( strtoul ( value, &endp, 0 ) );
  800. if ( *endp )
  801. return -EINVAL;
  802. return store_setting ( settings, setting,
  803. &u.bytes[ sizeof ( u ) - size ], size );
  804. }
  805. /**
  806. * Parse and store value of 8-bit integer setting
  807. *
  808. * @v settings Settings block
  809. * @v setting Setting to store
  810. * @v value Formatted setting data
  811. * @v size Integer size, in bytes
  812. * @ret rc Return status code
  813. */
  814. static int storef_int8 ( struct settings *settings, struct setting *setting,
  815. const char *value ) {
  816. return storef_int ( settings, setting, value, 1 );
  817. }
  818. /**
  819. * Parse and store value of 16-bit integer setting
  820. *
  821. * @v settings Settings block
  822. * @v setting Setting to store
  823. * @v value Formatted setting data
  824. * @v size Integer size, in bytes
  825. * @ret rc Return status code
  826. */
  827. static int storef_int16 ( struct settings *settings, struct setting *setting,
  828. const char *value ) {
  829. return storef_int ( settings, setting, value, 2 );
  830. }
  831. /**
  832. * Parse and store value of 32-bit integer setting
  833. *
  834. * @v settings Settings block
  835. * @v setting Setting to store
  836. * @v value Formatted setting data
  837. * @v size Integer size, in bytes
  838. * @ret rc Return status code
  839. */
  840. static int storef_int32 ( struct settings *settings, struct setting *setting,
  841. const char *value ) {
  842. return storef_int ( settings, setting, value, 4 );
  843. }
  844. /**
  845. * Fetch and format value of signed integer setting
  846. *
  847. * @v settings Settings block, or NULL to search all blocks
  848. * @v setting Setting to fetch
  849. * @v buf Buffer to contain formatted value
  850. * @v len Length of buffer
  851. * @ret len Length of formatted value, or negative error
  852. */
  853. static int fetchf_int ( struct settings *settings, struct setting *setting,
  854. char *buf, size_t len ) {
  855. long value;
  856. int rc;
  857. if ( ( rc = fetch_int_setting ( settings, setting, &value ) ) < 0 )
  858. return rc;
  859. return snprintf ( buf, len, "%ld", value );
  860. }
  861. /**
  862. * Fetch and format value of unsigned integer setting
  863. *
  864. * @v settings Settings block, or NULL to search all blocks
  865. * @v setting Setting to fetch
  866. * @v buf Buffer to contain formatted value
  867. * @v len Length of buffer
  868. * @ret len Length of formatted value, or negative error
  869. */
  870. static int fetchf_uint ( struct settings *settings, struct setting *setting,
  871. char *buf, size_t len ) {
  872. unsigned long value;
  873. int rc;
  874. if ( ( rc = fetch_uint_setting ( settings, setting, &value ) ) < 0 )
  875. return rc;
  876. return snprintf ( buf, len, "%#lx", value );
  877. }
  878. /** A signed 8-bit integer setting type */
  879. struct setting_type setting_type_int8 __setting_type = {
  880. .name = "int8",
  881. .storef = storef_int8,
  882. .fetchf = fetchf_int,
  883. };
  884. /** A signed 16-bit integer setting type */
  885. struct setting_type setting_type_int16 __setting_type = {
  886. .name = "int16",
  887. .storef = storef_int16,
  888. .fetchf = fetchf_int,
  889. };
  890. /** A signed 32-bit integer setting type */
  891. struct setting_type setting_type_int32 __setting_type = {
  892. .name = "int32",
  893. .storef = storef_int32,
  894. .fetchf = fetchf_int,
  895. };
  896. /** An unsigned 8-bit integer setting type */
  897. struct setting_type setting_type_uint8 __setting_type = {
  898. .name = "uint8",
  899. .storef = storef_int8,
  900. .fetchf = fetchf_uint,
  901. };
  902. /** An unsigned 16-bit integer setting type */
  903. struct setting_type setting_type_uint16 __setting_type = {
  904. .name = "uint16",
  905. .storef = storef_int16,
  906. .fetchf = fetchf_uint,
  907. };
  908. /** An unsigned 32-bit integer setting type */
  909. struct setting_type setting_type_uint32 __setting_type = {
  910. .name = "uint32",
  911. .storef = storef_int32,
  912. .fetchf = fetchf_uint,
  913. };
  914. /**
  915. * Parse and store value of hex string setting
  916. *
  917. * @v settings Settings block
  918. * @v setting Setting to store
  919. * @v value Formatted setting data
  920. * @ret rc Return status code
  921. */
  922. static int storef_hex ( struct settings *settings, struct setting *setting,
  923. const char *value ) {
  924. char *ptr = ( char * ) value;
  925. uint8_t bytes[ strlen ( value ) ]; /* cannot exceed strlen(value) */
  926. unsigned int len = 0;
  927. while ( 1 ) {
  928. bytes[len++] = strtoul ( ptr, &ptr, 16 );
  929. switch ( *ptr ) {
  930. case '\0' :
  931. return store_setting ( settings, setting, bytes, len );
  932. case ':' :
  933. ptr++;
  934. break;
  935. default :
  936. return -EINVAL;
  937. }
  938. }
  939. }
  940. /**
  941. * Fetch and format value of hex string setting
  942. *
  943. * @v settings Settings block, or NULL to search all blocks
  944. * @v setting Setting to fetch
  945. * @v buf Buffer to contain formatted value
  946. * @v len Length of buffer
  947. * @ret len Length of formatted value, or negative error
  948. */
  949. static int fetchf_hex ( struct settings *settings, struct setting *setting,
  950. char *buf, size_t len ) {
  951. int raw_len;
  952. int check_len;
  953. int used = 0;
  954. int i;
  955. raw_len = fetch_setting_len ( settings, setting );
  956. if ( raw_len < 0 )
  957. return raw_len;
  958. {
  959. uint8_t raw[raw_len];
  960. check_len = fetch_setting ( settings, setting, raw,
  961. sizeof ( raw ) );
  962. if ( check_len < 0 )
  963. return check_len;
  964. assert ( check_len == raw_len );
  965. if ( len )
  966. buf[0] = 0; /* Ensure that a terminating NUL exists */
  967. for ( i = 0 ; i < raw_len ; i++ ) {
  968. used += ssnprintf ( ( buf + used ), ( len - used ),
  969. "%s%02x", ( used ? ":" : "" ),
  970. raw[i] );
  971. }
  972. return used;
  973. }
  974. }
  975. /** A hex-string setting */
  976. struct setting_type setting_type_hex __setting_type = {
  977. .name = "hex",
  978. .storef = storef_hex,
  979. .fetchf = fetchf_hex,
  980. };
  981. /**
  982. * Parse and store value of UUID setting
  983. *
  984. * @v settings Settings block
  985. * @v setting Setting to store
  986. * @v value Formatted setting data
  987. * @ret rc Return status code
  988. */
  989. static int storef_uuid ( struct settings *settings __unused,
  990. struct setting *setting __unused,
  991. const char *value __unused ) {
  992. return -ENOTSUP;
  993. }
  994. /**
  995. * Fetch and format value of UUID setting
  996. *
  997. * @v settings Settings block, or NULL to search all blocks
  998. * @v setting Setting to fetch
  999. * @v buf Buffer to contain formatted value
  1000. * @v len Length of buffer
  1001. * @ret len Length of formatted value, or negative error
  1002. */
  1003. static int fetchf_uuid ( struct settings *settings, struct setting *setting,
  1004. char *buf, size_t len ) {
  1005. union uuid uuid;
  1006. int raw_len;
  1007. if ( ( raw_len = fetch_uuid_setting ( settings, setting, &uuid ) ) < 0)
  1008. return raw_len;
  1009. return snprintf ( buf, len, "%s", uuid_ntoa ( &uuid ) );
  1010. }
  1011. /** UUID setting type */
  1012. struct setting_type setting_type_uuid __setting_type = {
  1013. .name = "uuid",
  1014. .storef = storef_uuid,
  1015. .fetchf = fetchf_uuid,
  1016. };
  1017. /******************************************************************************
  1018. *
  1019. * Settings
  1020. *
  1021. ******************************************************************************
  1022. */
  1023. /** Hostname setting */
  1024. struct setting hostname_setting __setting = {
  1025. .name = "hostname",
  1026. .description = "Host name",
  1027. .tag = DHCP_HOST_NAME,
  1028. .type = &setting_type_string,
  1029. };
  1030. /** Filename setting */
  1031. struct setting filename_setting __setting = {
  1032. .name = "filename",
  1033. .description = "Boot filename",
  1034. .tag = DHCP_BOOTFILE_NAME,
  1035. .type = &setting_type_string,
  1036. };
  1037. /** Root path setting */
  1038. struct setting root_path_setting __setting = {
  1039. .name = "root-path",
  1040. .description = "NFS/iSCSI root path",
  1041. .tag = DHCP_ROOT_PATH,
  1042. .type = &setting_type_string,
  1043. };
  1044. /** Username setting */
  1045. struct setting username_setting __setting = {
  1046. .name = "username",
  1047. .description = "User name",
  1048. .tag = DHCP_EB_USERNAME,
  1049. .type = &setting_type_string,
  1050. };
  1051. /** Password setting */
  1052. struct setting password_setting __setting = {
  1053. .name = "password",
  1054. .description = "Password",
  1055. .tag = DHCP_EB_PASSWORD,
  1056. .type = &setting_type_string,
  1057. };
  1058. /** Priority setting */
  1059. struct setting priority_setting __setting = {
  1060. .name = "priority",
  1061. .description = "Priority of these settings",
  1062. .tag = DHCP_EB_PRIORITY,
  1063. .type = &setting_type_int8,
  1064. };