[settings] Add the uristring setting type
authorMichael Brown <mcb30@etherboot.org>
Wed, 24 Sep 2008 06:22:42 +0000 (07:22 +0100)
committerMichael Brown <mcb30@etherboot.org>
Wed, 24 Sep 2008 06:22:42 +0000 (07:22 +0100)
This allows settings to be expanded in a way that is safe to include
within a URI string, such as

  kernel http://10.0.0.1/boot.php?mf=${manufacturer:uristring}

where the ${manufacturer} setting may contain characters that are not
permitted (or have reserved purposes) within a URI.

Since whitespace characters will be URI-encoded (e.g. "%20" for a
space character), this also works around the problem that spaces
within an expanded setting would cause the shell to split command-line
arguments incorrectly.

src/core/settings.c

index e660ae7..a1299ee 100644 (file)
@@ -28,6 +28,7 @@
 #include <gpxe/vsprintf.h>
 #include <gpxe/dhcp.h>
 #include <gpxe/uuid.h>
 #include <gpxe/vsprintf.h>
 #include <gpxe/dhcp.h>
 #include <gpxe/uuid.h>
+#include <gpxe/uri.h>
 #include <gpxe/settings.h>
 
 /** @file
 #include <gpxe/settings.h>
 
 /** @file
@@ -745,6 +746,58 @@ struct setting_type setting_type_string __setting_type = {
        .fetchf = fetchf_string,
 };
 
        .fetchf = fetchf_string,
 };
 
+/**
+ * Parse and store value of URI-encoded string setting
+ *
+ * @v settings         Settings block
+ * @v setting          Setting to store
+ * @v value            Formatted setting data
+ * @ret rc             Return status code
+ */
+static int storef_uristring ( struct settings *settings,
+                             struct setting *setting,
+                             const char *value ) {
+       char buf[ strlen ( value ) + 1 ]; /* Decoding never expands string */
+       size_t len;
+
+       len = uri_decode ( value, buf, sizeof ( buf ) );
+       return store_setting ( settings, setting, buf, len );
+}
+
+/**
+ * Fetch and format value of URI-encoded string setting
+ *
+ * @v settings         Settings block, or NULL to search all blocks
+ * @v setting          Setting to fetch
+ * @v buf              Buffer to contain formatted value
+ * @v len              Length of buffer
+ * @ret len            Length of formatted value, or negative error
+ */
+static int fetchf_uristring ( struct settings *settings,
+                             struct setting *setting,
+                             char *buf, size_t len ) {
+       size_t raw_len;
+
+       /* We need to always retrieve the full raw string to know the
+        * length of the encoded string.
+        */
+       raw_len = fetch_setting ( settings, setting, NULL, 0 );
+       {
+               char raw_buf[ raw_len + 1 ];
+       
+               fetch_string_setting ( settings, setting, raw_buf,
+                                      sizeof ( raw_buf ) );
+               return uri_encode ( raw_buf, buf, len );
+       }
+}
+
+/** A URI-encoded string setting type */
+struct setting_type setting_type_uristring __setting_type = {
+       .name = "uristring",
+       .storef = storef_uristring,
+       .fetchf = fetchf_uristring,
+};
+
 /**
  * Parse and store value of IPv4 address setting
  *
 /**
  * Parse and store value of IPv4 address setting
  *