+
+int get_option_as_string(const struct nvram_accessor *nvram, struct cb_cmos_option_table *option_table, char **dest, char *name)
+{
+ void *raw;
+ struct cb_cmos_entries *cmos_entry = lookup_cmos_entry(option_table, name);
+ if (!cmos_entry)
+ return 1;
+ int cmos_length = (cmos_entry->length+7)/8;
+
+ /* extra byte to ensure 0-terminated strings */
+ raw = malloc(cmos_length+1);
+ memset(raw, 0, cmos_length+1);
+
+ int ret = get_option_with(nvram, option_table, raw, name);
+
+ struct cb_cmos_enums *cmos_enum;
+ switch (cmos_entry->config) {
+ case 'h':
+ /* only works on little endian.
+ 26 bytes is enough for a 64bit value in decimal */
+ *dest = malloc(26);
+ sprintf(*dest, "%ull", *(u64*)raw);
+ break;
+ case 's':
+ *dest = strdup(raw);
+ break;
+ case 'e':
+ cmos_enum = lookup_cmos_enum_by_value(option_table, cmos_entry->config_id, (u8*)raw);
+ *dest = strdup((const char*)cmos_enum->text);
+ break;
+ default: /* fail */
+ return 1;
+ }
+ free(raw);
+ return ret;
+}
+
+int set_option_from_string(const struct nvram_accessor *nvram, struct cb_cmos_option_table *option_table, char *value, char *name)
+{
+ void *raw;
+ struct cb_cmos_entries *cmos_entry = lookup_cmos_entry(option_table, name);
+ if (!cmos_entry)
+ return 1;
+
+ struct cb_cmos_enums *cmos_enum;
+ switch (cmos_entry->config) {
+ case 'h':
+ /* only works on little endian */
+ raw = malloc(8);
+ *(u64*)raw = strtoull(value, NULL, 0);
+ break;
+ case 's':
+ raw = strdup(value);
+ break;
+ case 'e':
+ cmos_enum = lookup_cmos_enum_by_label(option_table, cmos_entry->config_id, value);
+ raw = malloc(sizeof(u32));
+ *(u32*)raw = cmos_enum->value;
+ break;
+ default: /* fail */
+ return 1;
+ }
+
+ int ret = set_option_with(nvram, option_table, raw, name);
+ free(raw);
+ return ret;
+}