summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/utils/editreg.c113
1 files changed, 104 insertions, 9 deletions
diff --git a/source3/utils/editreg.c b/source3/utils/editreg.c
index fb75601f26..5e79df1a14 100644
--- a/source3/utils/editreg.c
+++ b/source3/utils/editreg.c
@@ -962,11 +962,53 @@ int nt_delete_reg_key(REG_KEY *key, int delete_name)
}
/*
+ * Convert a string to a value ...
+ * FIXME: Error handling and convert this at command parse time ...
+ */
+void *str_to_val(int type, char *val, int *len)
+{
+ unsigned int *dwordp = NULL;
+
+ if (!len || !val) return NULL;
+
+ switch (type) {
+ case REG_TYPE_REGSZ:
+ *len = strlen(val);
+ return (void *)val;
+
+ case REG_TYPE_DWORD:
+ dwordp = (unsigned int *)malloc(sizeof(unsigned int));
+ if (!dwordp) return NULL;
+ /* Allow for ddddd and 0xhhhhh and 0ooooo */
+ if (strncmp(val, "0x", 2) == 0 || strncmp(val, "0X", 2) == 0) {
+ sscanf(val, "0[xX]%X", dwordp);
+ }
+ else if (*val == '0') {
+ sscanf(val, "0%o", dwordp);
+ }
+ else {
+ sscanf(val, "%d", dwordp);
+ }
+ *len = sizeof(unsigned int);
+ return (void *)dwordp;
+
+ /* FIXME: Implement more of these */
+
+ default:
+ return NULL;
+ break;
+ }
+
+ return NULL;
+}
+
+/*
* Add a value to the key specified ... We have to parse the value some more
* based on the type to get it in the correct internal form
- * An empty name will be converted to "<No Name>" before here
+ * An empty name will be converted to "<No Name>" before here
+ * Hmmm, maybe not. has_name is for that
*/
-REG_KEY *nt_add_reg_value(REG_KEY *key, char *name, int type, char *value)
+VAL_KEY *nt_add_reg_value(REG_KEY *key, char *name, int type, char *value)
{
int i;
VAL_KEY *tmp = NULL;
@@ -977,8 +1019,10 @@ REG_KEY *nt_add_reg_value(REG_KEY *key, char *name, int type, char *value)
for (i = 0; i < key->values->val_count; i++) {
if (strcmp(name, key->values->vals[i]->name) == 0){ /* Change the value */
-
-
+ free(key->values->vals[i]->data_blk);
+ key->values->vals[i]->data_blk = str_to_val(type, value, &
+ key->values->vals[i]->data_len);
+ return key->values->vals[i];
}
}
@@ -991,8 +1035,30 @@ REG_KEY *nt_add_reg_value(REG_KEY *key, char *name, int type, char *value)
bzero(tmp, sizeof(VAL_KEY));
tmp->name = strdup(name);
+ tmp->has_name = True;
if (!tmp->name) goto error;
tmp->data_type = type;
+ tmp->data_blk = str_to_val(type, value, &tmp->data_len);
+
+ /* Now, add to val list */
+
+ if (key->values->val_count >= key->values->max_vals) {
+ /*
+ * Allocate some more space
+ */
+
+ if ((key->values = (VAL_LIST *)realloc(key->values, sizeof(VAL_LIST) +
+ key->values->val_count - 1 +
+ REG_KEY_LIST_SIZE))) {
+ key->values->max_vals += REG_KEY_LIST_SIZE;
+ }
+ else goto error;
+ }
+
+ i = key->values->val_count;
+ key->values->val_count++;
+ key->values->vals[i] = tmp;
+ return tmp;
error:
if (tmp) nt_delete_val_key(tmp);
@@ -1000,7 +1066,7 @@ REG_KEY *nt_add_reg_value(REG_KEY *key, char *name, int type, char *value)
}
/*
- * Delete a value. We return the value and let the caller deal witj it.
+ * Delete a value. We return the value and let the caller deal with it.
*/
VAL_KEY *nt_delete_reg_value(REG_KEY *key, char *name)
{
@@ -1008,8 +1074,11 @@ VAL_KEY *nt_delete_reg_value(REG_KEY *key, char *name)
if (!key || !key->values || !name || !*name) return NULL;
+ /* FIXME: Allow empty value name */
for (i = 0; i< key->values->val_count; i++) {
- if (strcmp(name, key->values->vals[i]->name) == 0) {
+ if ((!key->values->vals[i]->has_name && !*name) ||
+ (key->values->vals[i]->has_name &&
+ strcmp(name, key->values->vals[i]->name) == 0)) {
VAL_KEY *val;
val = key->values->vals[i];
@@ -2269,6 +2338,15 @@ typedef struct cmd_line {
char *line;
} CMD_LINE;
+void free_val_spec_list(VAL_SPEC_LIST *vl)
+{
+ if (!vl) return;
+ if (vl->name) free(vl->name);
+ if (vl->val) free(vl->val);
+ free(vl);
+
+}
+
/*
* Some routines to handle lines of info in the command files
*/
@@ -2505,14 +2583,16 @@ char *parse_value(struct cmd_line *cl, int *vtype, char **val)
while (*tstr == ' ') tstr++; /* Skip leading white space */
p2 = strchr(p2, ':');
- if (!p2) goto error;
-
- *p2 = 0; p2++; /* split on the : */
+ if (p2) {
+ *p2 = 0; p2++; /* split on the : */
+ }
*vtype = parse_value_type(tstr);
if (!vtype) goto error;
+ if (!p2 || !*p2) return nstr;
+
/* Now, parse the value string. It should return a newly malloc'd string */
while (*p2 == ' ') p2++; /* Skip leading space */
@@ -2736,6 +2816,7 @@ CMD *regedit4_get_cmd(int fd)
vl = (struct val_spec_list *)malloc(sizeof(struct val_spec_list));
if (!vl) goto error;
vl->next = NULL;
+ vl->val = NULL;
vl->name = parse_value(cl, &vl->type, &vl->val);
if (!vl->name) goto error;
if (cmd->val_spec_list == NULL) {
@@ -3183,6 +3264,20 @@ int main(int argc, char *argv[])
}
while (cmd->val_count) {
+ VAL_SPEC_LIST *val = cmd->val_spec_list;
+ VAL_KEY *reg_val = NULL;
+
+ if (val->type == REG_TYPE_DELETE) {
+ reg_val = nt_delete_reg_value(tmp, val -> name);
+ if (reg_val) nt_delete_val_key(reg_val);
+ }
+ else {
+ reg_val = nt_add_reg_value(tmp, reg_val->name, val->type,
+ val->val);
+ }
+
+ cmd->val_spec_list = val->next;
+ free_val_spec_list(val);
cmd->val_count--;
}