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.

settings.c 28KB

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