Added cmdl_show proof-of-concept
[people/xl0/gpxe.git] / src / core / settings.c
index 4df491f..a7a708a 100644 (file)
@@ -21,6 +21,8 @@
 #include <string.h>
 #include <errno.h>
 #include <assert.h>
+#include <vsprintf.h>
+#include <gpxe/in.h>
 #include <gpxe/settings.h>
 
 /** @file
@@ -116,17 +118,19 @@ find_or_build_config_setting ( const char *name,
  *
  * @v context          Configuration context
  * @v name             Configuration setting name
- * @ret value          Setting value (as a string), or NULL
+ * @v buf              Buffer to contain value
+ * @v len              Length of buffer
+ * @ret rc             Return status code
  */
-const char * ( show_setting ) ( struct config_context *context,
-                               const char *name ) {
+int ( show_setting ) ( struct config_context *context, const char *name,
+                      char *buf, size_t len ) {
        struct config_setting *setting;
        struct config_setting tmp_setting;
 
        setting = find_or_build_config_setting ( name, &tmp_setting );
        if ( ! setting )
-               return NULL;
-       return setting->type->show ( context, setting );
+               return -ENOENT;
+       return setting->type->show ( context, setting, buf, len );
 }
 
 /** Set value of setting
@@ -146,3 +150,137 @@ int ( set_setting ) ( struct config_context *context, const char *name,
                return -ENOENT;
        return setting->type->set ( context, setting, value );
 }
+
+/**
+ * Show value of string setting
+ *
+ * @v context          Configuration context
+ * @v setting          Configuration setting
+ * @v buf              Buffer to contain value
+ * @v len              Length of buffer
+ * @ret rc             Return status code
+ */
+static int show_string ( struct config_context *context,
+                        struct config_setting *setting,
+                        char *buf, size_t len ) {
+       struct dhcp_option *option;
+
+       option = find_dhcp_option ( context->options, setting->tag );
+       if ( ! option )
+               return -ENOENT;
+       dhcp_snprintf ( buf, len, option );
+       return 0;
+}
+
+/** Set value of string setting
+ *
+ * @v context          Configuration context
+ * @v setting          Configuration setting
+ * @v value            Setting value (as a string)
+ * @ret rc             Return status code
+ */ 
+static int set_string ( struct config_context *context,
+                       struct config_setting *setting,
+                       const char *value ) {
+       struct dhcp_option *option;
+
+       option = set_dhcp_option ( context->options, setting->tag,
+                                  value, strlen ( value ) );
+       if ( ! option )
+               return -ENOMEM;
+       return 0;
+}
+
+/** A string configuration setting */
+struct config_setting_type config_setting_type_string __config_setting_type = {
+       .name = "string",
+       .show = show_string,
+       .set = set_string,
+};
+
+/**
+ * Show value of IPv4 setting
+ *
+ * @v context          Configuration context
+ * @v setting          Configuration setting
+ * @v buf              Buffer to contain value
+ * @v len              Length of buffer
+ * @ret rc             Return status code
+ */
+static int show_ipv4 ( struct config_context *context,
+                      struct config_setting *setting,
+                      char *buf, size_t len ) {
+       struct dhcp_option *option;
+       struct in_addr ipv4;
+
+       option = find_dhcp_option ( context->options, setting->tag );
+       if ( ! option )
+               return -ENOENT;
+       dhcp_ipv4_option ( option, &ipv4 );
+       snprintf ( buf, len, inet_ntoa ( ipv4 ) );
+       return 0;
+}
+
+/** Set value of IPV4 setting
+ *
+ * @v context          Configuration context
+ * @v setting          Configuration setting
+ * @v value            Setting value (as a string)
+ * @ret rc             Return status code
+ */ 
+static int set_ipv4 ( struct config_context *context,
+                     struct config_setting *setting,
+                     const char *value ) {
+       struct dhcp_option *option;
+       struct in_addr ipv4;
+       int rc;
+       
+       if ( ( rc = inet_aton ( value, &ipv4 ) ) != 0 )
+               return rc;
+       option = set_dhcp_option ( context->options, setting->tag,
+                                  &ipv4, sizeof ( ipv4 ) );
+       if ( ! option )
+               return -ENOMEM;
+       return 0;
+}
+
+/** An IPv4 configuration setting */
+struct config_setting_type config_setting_type_ipv4 __config_setting_type = {
+       .name = "ipv4",
+       .show = show_ipv4,
+       .set = set_ipv4,
+};
+
+/** Some basic setting definitions */
+struct config_setting basic_config_settings[] __config_setting = {
+       {
+               .name = "hostname",
+               .tag = DHCP_HOST_NAME,
+               .type = &config_setting_type_string,
+       },
+       {
+               .name = "ip",
+               .tag = DHCP_EB_YIADDR,
+               .type = &config_setting_type_ipv4,
+       },
+};
+
+
+
+/* Quick and dirty proof of concept */
+int cmdl_show ( int argc, char **argv ) {
+       char buf[256];
+       struct config_context dummy_context = { NULL };
+       int rc;
+
+       if ( argc < 2 )
+               return -EINVAL;
+       
+       if ( ( rc = show_setting ( &dummy_context, argv[1],
+                                  buf, sizeof ( buf ) ) ) != 0 )
+               return rc;
+
+       printf ( "%s = %s\n", argv[1], buf );
+       return 0;
+}
+