Переглянути джерело

Added basic infrastructure for manipulating settings.

tags/v0.9.3
Michael Brown 18 роки тому
джерело
коміт
db46972349
2 змінених файлів з 251 додано та 0 видалено
  1. 148
    0
      src/core/settings.c
  2. 103
    0
      src/include/gpxe/settings.h

+ 148
- 0
src/core/settings.c Переглянути файл

@@ -0,0 +1,148 @@
1
+/*
2
+ * Copyright (C) 2006 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
+
19
+#include <stdint.h>
20
+#include <stdlib.h>
21
+#include <string.h>
22
+#include <errno.h>
23
+#include <assert.h>
24
+#include <gpxe/settings.h>
25
+
26
+/** @file
27
+ *
28
+ * Configuration settings
29
+ *
30
+ */
31
+
32
+/** Registered configuration setting types */
33
+static struct config_setting_type
34
+config_setting_types[0] __table_start ( config_setting_types );
35
+static struct config_setting_type
36
+config_setting_types_end[0] __table_end ( config_setting_types );
37
+
38
+/** Registered configuration settings */
39
+static struct config_setting
40
+config_settings[0] __table_start ( config_settings );
41
+static struct config_setting
42
+config_settings_end[0] __table_end ( config_settings );
43
+
44
+/**
45
+ * Find configuration setting type
46
+ *
47
+ * @v name		Name
48
+ * @ret type		Configuration setting type, or NULL
49
+ */
50
+static struct config_setting_type *
51
+find_config_setting_type ( const char *name ) {
52
+	struct config_setting_type *type;
53
+
54
+	for ( type = config_setting_types ; type < config_setting_types_end ;
55
+	      type++ ) {
56
+		if ( strcmp ( name, type->name ) == 0 )
57
+			return type;
58
+	}
59
+	return NULL;
60
+}
61
+
62
+/**
63
+ * Find configuration setting
64
+ *
65
+ * @v name		Name
66
+ * @ret setting		Configuration setting, or NULL
67
+ */
68
+static struct config_setting * find_config_setting ( const char *name ) {
69
+	struct config_setting *setting;
70
+
71
+	for ( setting = config_settings ; setting < config_settings_end ;
72
+	      setting++ ) {
73
+		if ( strcmp ( name, setting->name ) == 0 )
74
+			return setting;
75
+	}
76
+	return NULL;
77
+}
78
+
79
+/**
80
+ * Find or build configuration setting
81
+ *
82
+ * @v name		Name
83
+ * @v tmp_setting	Temporary buffer for constructing a setting
84
+ * @ret setting		Configuration setting, or NULL
85
+ *
86
+ * Find setting if it exists.  If it doesn't exist, but the name is of
87
+ * the form "<num>.<type>" (e.g. "12.string"), then construct a
88
+ * setting for that tag and data type, and return it.  The constructed
89
+ * setting will be placed in the temporary buffer.
90
+ */
91
+static struct config_setting *
92
+find_or_build_config_setting ( const char *name,
93
+			       struct config_setting *tmp_setting ) {
94
+	struct config_setting *setting;
95
+	char *separator;
96
+
97
+	/* Look in the list of registered settings first */
98
+	setting = find_config_setting ( name );
99
+	if ( setting )
100
+		return setting;
101
+
102
+	/* If name is of the form "<num>.<type>", try to construct a setting */
103
+	setting = tmp_setting;
104
+	memset ( setting, 0, sizeof ( *setting ) );
105
+	setting->name = name;
106
+	setting->tag = strtoul ( name, &separator, 10 );
107
+	if ( *separator != '.' )
108
+		return NULL;
109
+	setting->type = find_config_setting_type ( separator + 1 );
110
+	if ( ! setting->type )
111
+		return NULL;
112
+	return setting;
113
+}
114
+
115
+/** Show value of setting
116
+ *
117
+ * @v context		Configuration context
118
+ * @v name		Configuration setting name
119
+ * @ret value		Setting value (as a string), or NULL
120
+ */
121
+const char * ( show_setting ) ( struct config_context *context,
122
+				const char *name ) {
123
+	struct config_setting *setting;
124
+	struct config_setting tmp_setting;
125
+
126
+	setting = find_or_build_config_setting ( name, &tmp_setting );
127
+	if ( ! setting )
128
+		return NULL;
129
+	return setting->type->show ( context, setting );
130
+}
131
+
132
+/** Set value of setting
133
+ *
134
+ * @v context		Configuration context
135
+ * @v name		Configuration setting name
136
+ * @v value		Setting value (as a string)
137
+ * @ret rc		Return status code
138
+ */
139
+int ( set_setting ) ( struct config_context *context, const char *name,
140
+		      const char *value ) {
141
+	struct config_setting *setting;
142
+	struct config_setting tmp_setting;
143
+
144
+	setting = find_or_build_config_setting ( name, &tmp_setting );
145
+	if ( ! setting )
146
+		return -ENOENT;
147
+	return setting->type->set ( context, setting, value );
148
+}

+ 103
- 0
src/include/gpxe/settings.h Переглянути файл

@@ -0,0 +1,103 @@
1
+#ifndef _GPXE_SETTINGS_H
2
+#define _GPXE_SETTINGS_H
3
+
4
+/** @file
5
+ *
6
+ * Configuration settings
7
+ *
8
+ */
9
+
10
+#include <stdint.h>
11
+#include <gpxe/dhcp.h>
12
+#include <gpxe/tables.h>
13
+
14
+struct config_setting;
15
+
16
+/**
17
+ * A configuration context
18
+ *
19
+ * This identifies the context within which settings are inspected and
20
+ * changed.  For example, the context might be global, or might be
21
+ * restricted to the settings stored in NVS on a particular device.
22
+ */
23
+struct config_context {
24
+	/** DHCP options block, or NULL
25
+	 *
26
+	 * If NULL, all registered DHCP options blocks will be used.
27
+	 */
28
+	struct dhcp_option_block *options;
29
+};
30
+
31
+/**
32
+ * A configuration setting type
33
+ *
34
+ * This represents a type of configuration setting (e.g. string, IPv4
35
+ * address, etc.).
36
+ */
37
+struct config_setting_type {
38
+	/** Name
39
+	 *
40
+	 * This is the name exposed to the user (e.g. "string").
41
+	 */
42
+	const char *name;
43
+	/** Show value of setting
44
+	 *
45
+	 * @v context		Configuration context
46
+	 * @v setting		Configuration setting
47
+	 * @ret value		Setting value (as a string), or NULL
48
+	 */
49
+	const char * ( * show ) ( struct config_context *context,
50
+				  struct config_setting *setting );
51
+	/** Set value of setting
52
+	 *
53
+	 * @v context		Configuration context
54
+	 * @v setting		Configuration setting
55
+	 * @v value		Setting value (as a string)
56
+	 * @ret rc		Return status code
57
+	 */ 
58
+	int ( * set ) ( struct config_context *context,
59
+			struct config_setting *setting,
60
+			const char *value );
61
+};
62
+
63
+/** Declare a configuration setting type */
64
+#define	__config_setting_type __table ( config_setting_types, 01 )
65
+
66
+/**
67
+ * A configuration setting
68
+ *
69
+ * This represents a single configuration setting (e.g. "hostname").
70
+ */
71
+struct config_setting {
72
+	/** Name
73
+	 *
74
+	 * This is the human-readable name for the setting.  Where
75
+	 * possible, it should match the name used in dhcpd.conf (see
76
+	 * dhcp-options(5)).
77
+	 */
78
+	const char *name;
79
+	/** DHCP option tag
80
+	 *
81
+	 * This is the DHCP tag used to identify the option in DHCP
82
+	 * packets and stored option blocks.
83
+	 */
84
+	unsigned int tag;
85
+	/** Configuration setting type
86
+	 *
87
+	 * This identifies the type of setting (e.g. string, IPv4
88
+	 * address, etc.).
89
+	 */
90
+	struct config_setting_type *type;
91
+};
92
+
93
+/** Declare a configuration setting */
94
+#define	__config_setting __table ( config_settings, 01 )
95
+
96
+/* Function prototypes */
97
+
98
+extern const char * ( show_setting ) ( struct config_context *context,
99
+				       const char *name );
100
+extern int ( set_setting ) ( struct config_context *context, const char *name,
101
+			     const char *value );
102
+
103
+#endif /* _GPXE_SETTINGS_H */

Завантаження…
Відмінити
Зберегти