2323#include <string.h>
2424#include <errno.h>
2525#include <getopt.h>
26+ #include <byteswap.h>
2627#include <ipxe/settings.h>
2728#include <ipxe/command.h>
2829#include <ipxe/parseopt.h>
@@ -255,6 +256,73 @@ static int read_exec ( int argc, char **argv ) {
255256 return set_core_exec ( argc , argv , & clear_read_cmd , read_value );
256257}
257258
259+ /** "inc" options */
260+ struct inc_options {};
261+
262+ /** "inc" option list */
263+ static struct option_descriptor inc_opts [] = {};
264+
265+ /** "inc" command descriptor */
266+ static struct command_descriptor inc_cmd =
267+ COMMAND_DESC ( struct inc_options , inc_opts , 1 , 2 ,
268+ "<setting> [<increment>]" );
269+
270+ /**
271+ * "inc" command
272+ *
273+ * @v argc Argument count
274+ * @v argv Argument list
275+ * @ret rc Return status code
276+ */
277+ static int inc_exec ( int argc , char * * argv ) {
278+ struct inc_options opts ;
279+ struct named_setting setting ;
280+ unsigned int increment = 1 ;
281+ unsigned long value ;
282+ int rc ;
283+
284+ /* Parse options */
285+ if ( ( rc = parse_options ( argc , argv , & inc_cmd , & opts ) ) != 0 )
286+ goto err_parse_options ;
287+
288+ /* Parse setting name */
289+ if ( ( rc = parse_existing_setting ( argv [optind ], & setting ) ) != 0 )
290+ goto err_parse_setting ;
291+
292+ /* Parse increment (if present) */
293+ if ( ( ( optind + 1 ) < argc ) &&
294+ ( ( rc = parse_integer ( argv [ optind + 1 ], & increment ) ) != 0 ))
295+ goto err_parse_increment ;
296+
297+ /* Fetch existing setting value, if any, allowing for the fact
298+ * that numeric settings are big-endian and variable-length.
299+ */
300+ if ( ( rc = fetchn_setting ( setting .settings , & setting .setting ,
301+ & value ) ) != 0 ) {
302+ /* Treat as a non-existent :int32 setting with a zero value */
303+ value = 0 ;
304+ if ( ! setting .setting .type )
305+ setting .setting .type = & setting_type_int32 ;
306+ }
307+
308+ /* Increment value */
309+ value += increment ;
310+
311+ /* Store updated setting value */
312+ if ( ( rc = storen_setting ( setting .settings , & setting .setting ,
313+ value ) ) != 0 ) {
314+ printf ( "Could not store \"%s\": %s\n" ,
315+ setting .setting .name , strerror ( rc ) );
316+ goto err_store ;
317+ }
318+
319+ err_store :
320+ err_parse_increment :
321+ err_parse_setting :
322+ err_parse_options :
323+ return rc ;
324+ }
325+
258326/** Non-volatile option commands */
259327struct command nvo_commands [] __command = {
260328 {
@@ -273,4 +341,8 @@ struct command nvo_commands[] __command = {
273341 .name = "read" ,
274342 .exec = read_exec ,
275343 },
344+ {
345+ .name = "inc" ,
346+ .exec = inc_exec ,
347+ },
276348};
0 commit comments