summaryrefslogtreecommitdiffstats
path: root/src/include/gpxe/settings.h
blob: 1b9c059be0c00dcd4b5ddd1b73013c4e6c6b11c9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#ifndef _GPXE_SETTINGS_H
#define _GPXE_SETTINGS_H

/** @file
 *
 * Configuration settings
 *
 */

#include <stdint.h>
#include <gpxe/dhcp.h>
#include <gpxe/tables.h>

struct config_setting;

/**
 * A configuration context
 *
 * This identifies the context within which settings are inspected and
 * changed.  For example, the context might be global, or might be
 * restricted to the settings stored in NVS on a particular device.
 */
struct config_context {
	/** DHCP options block, or NULL
	 *
	 * If NULL, all registered DHCP options blocks will be used.
	 */
	struct dhcp_option_block *options;
};

/**
 * A configuration setting type
 *
 * This represents a type of configuration setting (e.g. string, IPv4
 * address, etc.).
 */
struct config_setting_type {
	/** Name
	 *
	 * This is the name exposed to the user (e.g. "string").
	 */
	const char *name;
	/** Description */
	const char *description;
	/** Show value of setting
	 *
	 * @v context		Configuration context
	 * @v setting		Configuration setting
	 * @v buf		Buffer to contain value
	 * @v len		Length of buffer
	 * @ret len		Length of formatted value, or negative error
	 */
	int ( * show ) ( struct config_context *context,
			 struct config_setting *setting,
			 char *buf, size_t len );
	/** Set value of setting
	 *
	 * @v context		Configuration context
	 * @v setting		Configuration setting
	 * @v value		Setting value (as a string)
	 * @ret rc		Return status code
	 */ 
	int ( * set ) ( struct config_context *context,
			struct config_setting *setting,
			const char *value );
};

/** Declare a configuration setting type */
#define	__config_setting_type \
	__table ( struct config_setting_type, config_setting_types, 01 )

/**
 * A configuration setting
 *
 * This represents a single configuration setting (e.g. "hostname").
 */
struct config_setting {
	/** Name
	 *
	 * This is the human-readable name for the setting.  Where
	 * possible, it should match the name used in dhcpd.conf (see
	 * dhcp-options(5)).
	 */
	const char *name;
	/** Description */
	const char *description;
	/** DHCP option tag
	 *
	 * This is the DHCP tag used to identify the option in DHCP
	 * packets and stored option blocks.
	 */
	unsigned int tag;
	/** Configuration setting type
	 *
	 * This identifies the type of setting (e.g. string, IPv4
	 * address, etc.).
	 */
	struct config_setting_type *type;
};

/** Declare a configuration setting */
#define	__config_setting __table ( struct config_setting, config_settings, 01 )

/**
 * Show value of setting
 *
 * @v context		Configuration context
 * @v setting		Configuration setting
 * @v buf		Buffer to contain value
 * @v len		Length of buffer
 * @ret len		Length of formatted value, or negative error
 */
static inline int show_setting ( struct config_context *context,
				 struct config_setting *setting,
				 char *buf, size_t len ) {
	return setting->type->show ( context, setting, buf, len );
}

extern int set_setting ( struct config_context *context,
			 struct config_setting *setting,
			 const char *value );

/**
 * Clear setting
 *
 * @v context		Configuration context
 * @v setting		Configuration setting
 * @ret rc		Return status code
 */
static inline int clear_setting ( struct config_context *context,
				  struct config_setting *setting ) {
	delete_dhcp_option ( context->options, setting->tag );
	return 0;
}

/* Function prototypes */
extern int show_named_setting ( struct config_context *context,
				const char *name, char *buf, size_t len );
extern int set_named_setting ( struct config_context *context,
			       const char *name, const char *value );

/**
 * Clear named setting
 *
 * @v context		Configuration context
 * @v name		Configuration setting name
 * @ret rc		Return status code
 */
static inline int clear_named_setting ( struct config_context *context,
					const char *name ) {
	return set_named_setting ( context, name, NULL );
}

#endif /* _GPXE_SETTINGS_H */