static struct uci_context *ctx;
enum {
/* section cmds */
- CMD_GET = 1,
- CMD_SET = 2,
- CMD_DEL = 3,
+ CMD_GET,
+ CMD_SET,
+ CMD_DEL,
+ CMD_RENAME,
/* package cmds */
- CMD_SHOW = 4,
- CMD_EXPORT = 5,
- CMD_COMMIT = 6,
+ CMD_SHOW,
+ CMD_EXPORT,
+ CMD_COMMIT,
};
static void uci_usage(int argc, char **argv)
char *section = NULL;
char *option = NULL;
char *value = NULL;
+ char **ptr = NULL;
struct uci_package *p = NULL;
struct uci_element *e = NULL;
if (argc != 2)
return 255;
- if (uci_parse_tuple(ctx, argv[1], &package, §ion, &option, (cmd == CMD_SET ? &value : NULL)) != UCI_OK)
+ switch(cmd) {
+ case CMD_SET:
+ case CMD_RENAME:
+ ptr = &value;
+ break;
+ default:
+ break;
+ }
+ if (uci_parse_tuple(ctx, argv[1], &package, §ion, &option, ptr) != UCI_OK)
return 1;
if (uci_load(ctx, package, &p) != UCI_OK) {
/* throw the value to stdout */
printf("%s\n", value);
break;
+ case CMD_RENAME:
+ if (uci_rename(ctx, p, section, option, value) != UCI_OK) {
+ uci_perror(ctx, appname);
+ return 1;
+ }
+ break;
case CMD_SET:
if (uci_set(ctx, p, section, option, value) != UCI_OK) {
uci_perror(ctx, appname);
}
break;
case CMD_DEL:
- if (uci_del(ctx, p, section, option) != UCI_OK) {
+ if (uci_delete(ctx, p, section, option) != UCI_OK) {
uci_perror(ctx, appname);
return 1;
}
cmd = CMD_GET;
else if (!strcasecmp(argv[0], "set"))
cmd = CMD_SET;
+ else if (!strcasecmp(argv[0], "ren") ||
+ !strcasecmp(argv[0], "rename"))
+ cmd = CMD_RENAME;
else if (!strcasecmp(argv[0], "del"))
cmd = CMD_DEL;
+ else
+ cmd = -1;
switch(cmd) {
case CMD_GET:
case CMD_SET:
case CMD_DEL:
+ case CMD_RENAME:
return uci_do_section_cmd(cmd, argc, argv);
case CMD_SHOW:
case CMD_EXPORT:
static void uci_parse_history_line(struct uci_context *ctx, struct uci_package *p, char *buf)
{
bool delete = false;
+ bool rename = false;
char *package = NULL;
char *section = NULL;
char *option = NULL;
if (buf[0] == '-') {
delete = true;
buf++;
+ } else if (buf[0] == '@') {
+ rename = true;
+ buf++;
}
UCI_INTERNAL(uci_parse_tuple, ctx, buf, &package, §ion, &option, &value);
if (option && !uci_validate_name(option))
goto error;
- if (delete)
- UCI_INTERNAL(uci_del, ctx, p, section, option);
+ if (rename)
+ UCI_INTERNAL(uci_rename, ctx, p, section, option, value);
+ else if (delete)
+ UCI_INTERNAL(uci_delete, ctx, p, section, option);
else
UCI_INTERNAL(uci_set, ctx, p, section, option, value);
if (h->cmd == UCI_CMD_REMOVE)
fprintf(f, "-");
+ else if (h->cmd == UCI_CMD_RENAME)
+ fprintf(f, "@");
fprintf(f, "%s.%s", p->e.name, h->section);
if (e->name)
int datalen = size;
void *ptr;
- if (name)
- datalen += strlen(name) + 1;
ptr = uci_malloc(ctx, datalen);
e = (struct uci_element *) ptr;
e->type = type;
if (name) {
- e->name = (char *) ptr + size;
- strcpy(e->name, name);
+ UCI_TRAP_SAVE(ctx, error);
+ e->name = uci_strdup(ctx, name);
+ UCI_TRAP_RESTORE(ctx);
}
uci_list_init(&e->list);
+ goto done;
+error:
+ free(ptr);
+ UCI_THROW(ctx, ctx->errno);
+
+done:
return e;
}
static void
uci_free_element(struct uci_element *e)
{
+ if (e->name)
+ free(e->name);
if (!uci_list_empty(&e->list))
uci_list_del(&e->list);
free(e);
return 0;
}
-int uci_del(struct uci_context *ctx, struct uci_package *p, char *section, char *option)
+int uci_rename(struct uci_context *ctx, struct uci_package *p, char *section, char *option, char *name)
+{
+ /* NB: UCI_INTERNAL use means without history tracking */
+ bool internal = ctx->internal;
+ struct uci_element *e;
+ struct uci_section *s = NULL;
+ struct uci_option *o = NULL;
+
+ UCI_HANDLE_ERR(ctx);
+ UCI_ASSERT(ctx, p != NULL);
+ UCI_ASSERT(ctx, section != NULL);
+
+ UCI_INTERNAL(uci_lookup, ctx, &e, p, section, option);
+
+ if (!internal)
+ uci_add_history(ctx, p, UCI_CMD_RENAME, section, option, name);
+
+ name = uci_strdup(ctx, name);
+ if (e->name)
+ free(e->name);
+ e->name = name;
+
+ return 0;
+}
+
+
+int uci_delete(struct uci_context *ctx, struct uci_package *p, char *section, char *option)
{
/* NB: pass on internal flag to uci_del_element */
bool internal = ctx->internal;
extern int uci_set(struct uci_context *ctx, struct uci_package *p, char *section, char *option, char *value);
/**
- * uci_del_element: Delete a section or option
+ * uci_rename: Rename an element
+ * @ctx: uci context
+ * @package: package name
+ * @section: section name
+ * @option: option name
+ * @name: new name
+ */
+extern int uci_rename(struct uci_context *ctx, struct uci_package *p, char *section, char *option, char *name);
+
+/**
+ * uci_delete_element: Delete a section or option
* @ctx: uci context
* @e: element (section or option)
*/
-extern int uci_del_element(struct uci_context *ctx, struct uci_element *e);
+extern int uci_delete_element(struct uci_context *ctx, struct uci_element *e);
/**
- * uci_del: Delete a section or option
+ * uci_delete: Delete a section or option
* @ctx: uci context
* @p: uci package
* @section: section name
* @option: option name (optional)
*/
-extern int uci_del(struct uci_context *ctx, struct uci_package *p, char *section, char *option);
+extern int uci_delete(struct uci_context *ctx, struct uci_package *p, char *section, char *option);
/**
* uci_save: save change history for a package
enum uci_command {
UCI_CMD_ADD,
UCI_CMD_REMOVE,
- UCI_CMD_CHANGE
+ UCI_CMD_CHANGE,
+ UCI_CMD_RENAME
};
struct uci_history