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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * Copyright (C) 2010 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., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301, USA.
  18. */
  19. #include <stdint.h>
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <errno.h>
  24. #include <getopt.h>
  25. #include <ipxe/settings.h>
  26. #include <ipxe/command.h>
  27. #include <ipxe/parseopt.h>
  28. #include <readline/readline.h>
  29. FILE_LICENCE ( GPL2_OR_LATER );
  30. /** @file
  31. *
  32. * Non-volatile option commands
  33. *
  34. */
  35. /** "show" options */
  36. struct show_options {};
  37. /** "show" option list */
  38. static struct option_descriptor show_opts[] = {};
  39. /** "show" command descriptor */
  40. static struct command_descriptor show_cmd =
  41. COMMAND_DESC ( struct show_options, show_opts, 1, 1, "<setting>" );
  42. /**
  43. * "show" command
  44. *
  45. * @v argc Argument count
  46. * @v argv Argument list
  47. * @ret rc Return status code
  48. */
  49. static int show_exec ( int argc, char **argv ) {
  50. struct show_options opts;
  51. struct named_setting setting;
  52. struct settings *origin;
  53. char name_buf[32];
  54. char *value;
  55. int rc;
  56. /* Parse options */
  57. if ( ( rc = parse_options ( argc, argv, &show_cmd, &opts ) ) != 0 )
  58. goto err_parse_options;
  59. /* Parse setting name */
  60. if ( ( rc = parse_existing_setting ( argv[optind], &setting ) ) != 0 )
  61. goto err_parse_setting;
  62. /* Fetch formatted setting value */
  63. if ( ( rc = fetchf_setting_copy ( setting.settings, &setting.setting,
  64. &value ) ) < 0 ) {
  65. printf ( "Could not find \"%s\": %s\n",
  66. setting.setting.name, strerror ( rc ) );
  67. goto err_fetchf;
  68. }
  69. /* Fetch origin and format fully-qualified name */
  70. origin = fetch_setting_origin ( setting.settings, &setting.setting );
  71. assert ( origin != NULL );
  72. setting_name ( origin, &setting.setting, name_buf, sizeof ( name_buf ));
  73. /* Print setting value */
  74. printf ( "%s = %s\n", name_buf, value );
  75. /* Success */
  76. rc = 0;
  77. free ( value );
  78. err_fetchf:
  79. err_parse_setting:
  80. err_parse_options:
  81. return rc;
  82. }
  83. /** "set", "clear", and "read" options */
  84. struct set_core_options {};
  85. /** "set", "clear", and "read" option list */
  86. static struct option_descriptor set_core_opts[] = {};
  87. /** "set" command descriptor */
  88. static struct command_descriptor set_cmd =
  89. COMMAND_DESC ( struct set_core_options, set_core_opts, 1, MAX_ARGUMENTS,
  90. "<setting> <value>" );
  91. /** "clear" and "read" command descriptor */
  92. static struct command_descriptor clear_read_cmd =
  93. COMMAND_DESC ( struct set_core_options, set_core_opts, 1, 1,
  94. "<setting>" );
  95. /**
  96. * "set", "clear", and "read" command
  97. *
  98. * @v argc Argument count
  99. * @v argv Argument list
  100. * @v cmd Command descriptor
  101. * @v get_value Method to obtain setting value
  102. * @ret rc Return status code
  103. */
  104. static int set_core_exec ( int argc, char **argv,
  105. struct command_descriptor *cmd,
  106. int ( * get_value ) ( struct named_setting *setting,
  107. char **args, char **value ) ) {
  108. struct set_core_options opts;
  109. struct named_setting setting;
  110. char *value;
  111. int rc;
  112. /* Parse options */
  113. if ( ( rc = parse_options ( argc, argv, cmd, &opts ) ) != 0 )
  114. goto err_parse_options;
  115. /* Parse setting name */
  116. if ( ( rc = parse_autovivified_setting ( argv[optind],
  117. &setting ) ) != 0 )
  118. goto err_parse_setting;
  119. /* Parse setting value */
  120. if ( ( rc = get_value ( &setting, &argv[ optind + 1 ], &value ) ) != 0 )
  121. goto err_get_value;
  122. /* Apply default type if necessary */
  123. if ( ! setting.setting.type )
  124. setting.setting.type = &setting_type_string;
  125. /* Store setting */
  126. if ( ( rc = storef_setting ( setting.settings, &setting.setting,
  127. value ) ) != 0 ) {
  128. printf ( "Could not store \"%s\": %s\n",
  129. setting.setting.name, strerror ( rc ) );
  130. goto err_store;
  131. }
  132. err_store:
  133. free ( value );
  134. err_get_value:
  135. err_parse_setting:
  136. err_parse_options:
  137. return rc;
  138. }
  139. /**
  140. * Get setting value for "set" command
  141. *
  142. * @v setting Named setting
  143. * @v args Remaining arguments
  144. * @ret value Setting value
  145. * @ret rc Return status code
  146. */
  147. static int set_value ( struct named_setting *setting __unused,
  148. char **args, char **value ) {
  149. *value = concat_args ( args );
  150. if ( ! *value )
  151. return -ENOMEM;
  152. return 0;
  153. }
  154. /**
  155. * "set" command
  156. *
  157. * @v argc Argument count
  158. * @v argv Argument list
  159. * @ret rc Return status code
  160. */
  161. static int set_exec ( int argc, char **argv ) {
  162. return set_core_exec ( argc, argv, &set_cmd, set_value );
  163. }
  164. /**
  165. * Get setting value for "clear" command
  166. *
  167. * @v setting Named setting
  168. * @v args Remaining arguments
  169. * @ret value Setting value
  170. * @ret rc Return status code
  171. */
  172. static int clear_value ( struct named_setting *setting __unused,
  173. char **args __unused, char **value ) {
  174. *value = NULL;
  175. return 0;
  176. }
  177. /**
  178. * "clear" command
  179. *
  180. * @v argc Argument count
  181. * @v argv Argument list
  182. * @ret rc Return status code
  183. */
  184. static int clear_exec ( int argc, char **argv ) {
  185. return set_core_exec ( argc, argv, &clear_read_cmd, clear_value );
  186. }
  187. /**
  188. * Get setting value for "read" command
  189. *
  190. * @v setting Named setting
  191. * @v args Remaining arguments
  192. * @ret value Setting value
  193. * @ret rc Return status code
  194. */
  195. static int read_value ( struct named_setting *setting, char **args __unused,
  196. char **value ) {
  197. char *existing;
  198. int rc;
  199. /* Read existing value, treating errors as equivalent to an
  200. * empty initial setting.
  201. */
  202. fetchf_setting_copy ( setting->settings, &setting->setting, &existing );
  203. /* Read new value */
  204. if ( ( rc = readline_history ( NULL, existing, NULL, value ) ) != 0 )
  205. goto err_readline;
  206. err_readline:
  207. free ( existing );
  208. return rc;
  209. }
  210. /**
  211. * "read" command
  212. *
  213. * @v argc Argument count
  214. * @v argv Argument list
  215. * @ret rc Return status code
  216. */
  217. static int read_exec ( int argc, char **argv ) {
  218. return set_core_exec ( argc, argv, &clear_read_cmd, read_value );
  219. }
  220. /** Non-volatile option commands */
  221. struct command nvo_commands[] __command = {
  222. {
  223. .name = "show",
  224. .exec = show_exec,
  225. },
  226. {
  227. .name = "set",
  228. .exec = set_exec,
  229. },
  230. {
  231. .name = "clear",
  232. .exec = clear_exec,
  233. },
  234. {
  235. .name = "read",
  236. .exec = read_exec,
  237. },
  238. };