[Settings] Start revamping the configuration settings API.
[people/dverkamp/gpxe.git] / src / include / gpxe / settings.h
index 1b9c059..7198399 100644 (file)
@@ -8,73 +8,96 @@
  */
 
 #include <stdint.h>
-#include <gpxe/dhcp.h>
 #include <gpxe/tables.h>
+#include <gpxe/list.h>
+#include <gpxe/refcnt.h>
 
-struct config_setting;
+struct settings;
+struct in_addr;
 
-/**
- * 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
+/** Settings block operations */
+struct settings_operations {
+       /** Set value of setting
+        *
+        * @v settings          Settings block
+        * @v tag               Setting tag number
+        * @v data              Setting data, or NULL to clear setting
+        * @v len               Length of setting data
+        * @ret rc              Return status code
+        */
+       int ( * set ) ( struct settings *settings, unsigned int tag,
+                       const void *data, size_t len );
+       /** Get value of setting
+        *
+        * @v settings          Settings block
+        * @v tag               Setting tag number
+        * @v data              Buffer to fill with setting data
+        * @v len               Length of buffer
+        * @ret len             Length of setting data, or negative error
         *
-        * If NULL, all registered DHCP options blocks will be used.
+        * The actual length of the setting will be returned even if
+        * the buffer was too small.
         */
-       struct dhcp_option_block *options;
+       int ( * get ) ( struct settings *settings, unsigned int tag,
+                       void *data, size_t len );
+};
+
+/** A settings block */
+struct settings {
+       /** Reference counter */
+       struct refcnt *refcnt;
+       /** Name */
+       char name[16];
+       /** List of all settings */
+       struct list_head list;
+       /** Settings block operations */
+       struct settings_operations *op;
 };
 
 /**
- * A configuration setting type
+ * A setting type
  *
- * This represents a type of configuration setting (e.g. string, IPv4
- * address, etc.).
+ * This represents a type of setting (e.g. string, IPv4 address,
+ * etc.).
  */
-struct config_setting_type {
+struct 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
+       /** Parse and set value of setting
         *
-        * @v context           Configuration context
-        * @v setting           Configuration setting
-        * @v buf               Buffer to contain value
+        * @v settings          Settings block
+        * @v tag               Setting tag number
+        * @v value             Formatted setting data
+        * @ret rc              Return status code
+        */
+       int ( * setf ) ( struct settings *settings, unsigned int tag,
+                        const char *value );
+       /** Get and format value of setting
+        *
+        * @v settings          Settings block, or NULL to search all blocks
+        * @v tag               Setting tag number
+        * @v buf               Buffer to contain formatted 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,
+       int ( * getf ) ( struct settings *settings, unsigned int tag,
                         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 )
+#define        __setting_type \
+       __table ( struct setting_type, setting_types, 01 )
 
 /**
- * A configuration setting
+ * A named setting
  *
- * This represents a single configuration setting (e.g. "hostname").
+ * This represents a single setting (e.g. "hostname"), encapsulating
+ * the information about the setting's tag number and type.
  */
-struct config_setting {
+struct named_setting {
        /** Name
         *
         * This is the human-readable name for the setting.  Where
@@ -84,71 +107,90 @@ struct config_setting {
        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.
-        */
+       /** Setting tag number */
        unsigned int tag;
-       /** Configuration setting type
+       /** Setting type
         *
         * This identifies the type of setting (e.g. string, IPv4
         * address, etc.).
         */
-       struct config_setting_type *type;
+       struct setting_type *type;
 };
 
 /** Declare a configuration setting */
-#define        __config_setting __table ( struct config_setting, config_settings, 01 )
+#define        __named_setting __table ( struct named_setting, named_settings, 01 )
+
+extern struct settings interactive_settings;
+
+extern int get_setting ( struct settings *settings, unsigned int tag,
+                        void *data, size_t len );
+extern int get_setting_len ( struct settings *settings, unsigned int tag );
+extern int get_string_setting ( struct settings *settings, unsigned int tag,
+                               char *data, size_t len );
+extern int get_ipv4_setting ( struct settings *settings, unsigned int tag,
+                             struct in_addr *inp );
+extern int get_int_setting ( struct settings *settings, unsigned int tag,
+                            long *value );
+extern int get_uint_setting ( struct settings *settings, unsigned int tag,
+                             unsigned long *value );
+extern struct settings * find_settings ( const char *name );
+extern int set_typed_setting ( struct settings *settings,
+                              unsigned int tag, struct setting_type *type,
+                              const char *value );
+extern int set_named_setting ( const char *name, const char *value );
+extern int get_named_setting ( const char *name, char *buf, size_t len );
 
 /**
- * Show value of setting
+ * Set 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
+ * @v settings         Settings block
+ * @v tag              Setting tag number
+ * @v data             Setting data, or NULL to clear setting
+ * @v len              Length of setting data
+ * @ret rc             Return status code
  */
-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 );
+static inline int set_setting ( struct settings *settings, unsigned int tag,
+                               const void *data, size_t len ) {
+       return settings->op->set ( settings, tag, data, len );
 }
 
-extern int set_setting ( struct config_context *context,
-                        struct config_setting *setting,
-                        const char *value );
-
 /**
- * Clear setting
+ * Delete setting
  *
- * @v context          Configuration context
- * @v setting          Configuration setting
+ * @v settings         Settings block
+ * @v tag              Setting tag number
  * @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;
+static inline int delete_setting ( struct settings *settings,
+                                  unsigned int tag ) {
+       return set_setting ( settings, tag, NULL, 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 );
+/**
+ * Get and format value of setting
+ *
+ * @v settings         Settings block, or NULL to search all blocks
+ * @v tag              Setting tag number
+ * @v type             Settings type
+ * @v buf              Buffer to contain formatted value
+ * @v len              Length of buffer
+ * @ret len            Length of formatted value, or negative error
+ */
+static inline int get_typed_setting ( struct settings *settings,
+                                     unsigned int tag,
+                                     struct setting_type *type,
+                                     char *buf, size_t len ) {
+       return type->getf ( settings, tag, buf, len );
+}
 
 /**
- * Clear named setting
+ * Delete named setting
  *
- * @v context          Configuration context
- * @v name             Configuration setting name
+ * @v name             Name of setting
  * @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 );
+static inline int delete_named_setting ( const char *name ) {
+       return set_named_setting ( name, NULL );
 }
 
 #endif /* _GPXE_SETTINGS_H */