瀏覽代碼

[Settings] Add int16, int32 and hex-string configuration setting types

Add parse and display routines for 16-bit and 32-bit integer configuration
settings.

Add parse and display routines for hex-string configuration settings.

Assume hex-string as a configuration setting type if no type is explicitly
specified.
tags/v0.9.4
Michael Brown 16 年之前
父節點
當前提交
e2613e8896
共有 1 個文件被更改,包括 131 次插入5 次删除
  1. 131
    5
      src/core/settings.c

+ 131
- 5
src/core/settings.c 查看文件

@@ -25,6 +25,7 @@
25 25
 #include <errno.h>
26 26
 #include <assert.h>
27 27
 #include <gpxe/in.h>
28
+#include <gpxe/vsprintf.h>
28 29
 #include <gpxe/settings.h>
29 30
 
30 31
 /** @file
@@ -45,6 +46,8 @@ static struct config_setting config_settings[0]
45 46
 static struct config_setting config_settings_end[0]
46 47
 	__table_end ( struct config_setting, config_settings );
47 48
 
49
+struct config_setting_type config_setting_type_hex __config_setting_type;
50
+
48 51
 /**
49 52
  * Find configuration setting type
50 53
  *
@@ -108,9 +111,16 @@ find_or_build_config_setting ( const char *name,
108 111
 	memset ( setting, 0, sizeof ( *setting ) );
109 112
 	setting->name = name;
110 113
 	setting->tag = strtoul ( name, &separator, 10 );
111
-	if ( *separator != '.' )
112
-		return NULL;
113
-	setting->type = find_config_setting_type ( separator + 1 );
114
+	switch ( *separator ) {
115
+	case '.' :
116
+		setting->type = find_config_setting_type ( separator + 1 );
117
+		break;
118
+	case '\0' :
119
+		setting->type = &config_setting_type_hex;
120
+		break;
121
+	default :
122
+		break;
123
+	}
114 124
 	if ( ! setting->type )
115 125
 		return NULL;
116 126
 	return setting;
@@ -340,11 +350,41 @@ static int set_int ( struct config_context *context,
340 350
  * @ret rc		Return status code
341 351
  */ 
342 352
 static int set_int8 ( struct config_context *context,
343
-			   struct config_setting *setting,
344
-			   const char *value ) {
353
+		      struct config_setting *setting,
354
+		      const char *value ) {
345 355
 	return set_int ( context, setting, value, 1 );
346 356
 }
347 357
 
358
+/**
359
+ * Set value of 16-bit integer setting
360
+ *
361
+ * @v context		Configuration context
362
+ * @v setting		Configuration setting
363
+ * @v value		Setting value (as a string)
364
+ * @v size		Size of integer (in bytes)
365
+ * @ret rc		Return status code
366
+ */ 
367
+static int set_int16 ( struct config_context *context,
368
+		       struct config_setting *setting,
369
+		       const char *value ) {
370
+	return set_int ( context, setting, value, 2 );
371
+}
372
+
373
+/**
374
+ * Set value of 32-bit integer setting
375
+ *
376
+ * @v context		Configuration context
377
+ * @v setting		Configuration setting
378
+ * @v value		Setting value (as a string)
379
+ * @v size		Size of integer (in bytes)
380
+ * @ret rc		Return status code
381
+ */ 
382
+static int set_int32 ( struct config_context *context,
383
+		       struct config_setting *setting,
384
+		       const char *value ) {
385
+	return set_int ( context, setting, value, 4 );
386
+}
387
+
348 388
 /** An 8-bit integer configuration setting */
349 389
 struct config_setting_type config_setting_type_int8 __config_setting_type = {
350 390
 	.name = "int8",
@@ -353,6 +393,92 @@ struct config_setting_type config_setting_type_int8 __config_setting_type = {
353 393
 	.set = set_int8,
354 394
 };
355 395
 
396
+/** A 16-bit integer configuration setting */
397
+struct config_setting_type config_setting_type_int16 __config_setting_type = {
398
+	.name = "int16",
399
+	.description = "16-bit integer",
400
+	.show = show_int,
401
+	.set = set_int16,
402
+};
403
+
404
+/** A 32-bit integer configuration setting */
405
+struct config_setting_type config_setting_type_int32 __config_setting_type = {
406
+	.name = "int32",
407
+	.description = "32-bit integer",
408
+	.show = show_int,
409
+	.set = set_int32,
410
+};
411
+
412
+/**
413
+ * Set value of hex-string setting
414
+ *
415
+ * @v context		Configuration context
416
+ * @v setting		Configuration setting
417
+ * @v value		Setting value (as a string)
418
+ * @ret rc		Return status code
419
+ */ 
420
+static int set_hex ( struct config_context *context,
421
+		     struct config_setting *setting,
422
+		     const char *value ) {
423
+	struct dhcp_option *option;
424
+	char *ptr = ( char * ) value;
425
+	uint8_t bytes[ strlen ( value ) ]; /* cannot exceed strlen(value) */
426
+	unsigned int len = 0;
427
+
428
+	while ( 1 ) {
429
+		bytes[len++] = strtoul ( ptr, &ptr, 16 );
430
+		switch ( *ptr ) {
431
+		case '\0' :
432
+			option = set_dhcp_option ( context->options,
433
+						   setting->tag, bytes, len );
434
+			if ( ! option )
435
+				return -ENOSPC;
436
+			return 0;
437
+		case ':' :
438
+			ptr++;
439
+			break;
440
+		default :
441
+			return -EINVAL;
442
+		}
443
+	}
444
+}
445
+
446
+/**
447
+ * Show value of hex-string setting
448
+ *
449
+ * @v context		Configuration context
450
+ * @v setting		Configuration setting
451
+ * @v buf		Buffer to contain value
452
+ * @v len		Length of buffer
453
+ * @ret len		Length of formatted value, or negative error
454
+ */
455
+static int show_hex ( struct config_context *context,
456
+		      struct config_setting *setting,
457
+		      char *buf, size_t len ) {
458
+	struct dhcp_option *option;
459
+	int used = 0;
460
+	int i;
461
+
462
+	option = find_dhcp_option ( context->options, setting->tag );
463
+	if ( ! option )
464
+		return -ENODATA;
465
+
466
+	for ( i = 0 ; i < option->len ; i++ ) {
467
+		used += ssnprintf ( ( buf + used ), ( len - used ),
468
+				    "%s%02x", ( used ? ":" : "" ),
469
+				    option->data.bytes[i] );
470
+	}
471
+	return used;
472
+}
473
+
474
+/** A hex-string configuration setting */
475
+struct config_setting_type config_setting_type_hex __config_setting_type = {
476
+	.name = "hex",
477
+	.description = "Hex string",
478
+	.show = show_hex,
479
+	.set = set_hex,
480
+};
481
+
356 482
 /** Some basic setting definitions */
357 483
 struct config_setting basic_config_settings[] __config_setting = {
358 484
 	{

Loading…
取消
儲存