00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00027 #include <errno.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030
00031 #include "treeconf_int.h"
00032
00033 RCSTAG("@(#)$Id: tc_set.c,v 1.5 2005/06/07 04:53:50 klmitch Exp $");
00034
00047 static unsigned int
00048 _tc_set(treeconf_node_t *node, const char *value)
00049 {
00050 if (!node->tn_value)
00051 node->tn_value = node->tn_default;
00052
00053
00054 if ((!value && tn_isdef(node)) ||
00055 (value && node->tn_value && !strcmp(node->tn_value, value)))
00056 return 0;
00057
00058
00059 if (!value || (node->tn_default && !strcmp(node->tn_default, value)))
00060 value = node->tn_default;
00061 else if (value && !(value = strdup(value)))
00062 return ENOMEM;
00063
00064
00065 if (node->tn_value && !tn_isdef(node))
00066 free((void *)node->tn_value);
00067
00068 node->tn_value = value;
00069
00070 _tn_call_change(node);
00071
00072 return 0;
00073 }
00074
00075 unsigned int
00076 tc_set(treeconf_ctx_t *ctx, const char *name, const char *value,
00077 treeconf_node_t *parent)
00078 {
00079 treeconf_node_t *node;
00080 struct result res;
00081 unsigned int err = 0;
00082 int i;
00083
00084 initialize_trcf_error_table();
00085
00086
00087 if (!tx_verify(ctx) || !name ||
00088 (parent && (!tn_verify(parent) || parent->tn_context != ctx)))
00089 return EINVAL;
00090
00091
00092 if ((err = _tc_lookup_node(ctx, name, parent, &res)))
00093 return err;
00094
00095
00096 if (res.r_node && res.r_count == res.r_startnew) {
00097 if (res.r_node->tn_type == (TC_NODETYPE_IMPLICIT | TC_NODETYPE_NODE)) {
00098 _tc_release_children(res.r_node);
00099 res.r_node->tn_type = (res.r_node->tn_type & ~TC_NODETYPE_MASK) |
00100 TC_NODETYPE_VARIABLE;
00101 }
00102
00103 if ((res.r_node->tn_type & TC_NODETYPE_MASK) == TC_NODETYPE_VARIABLE)
00104 err = _tc_set(res.r_node, value);
00105 else
00106 err = TC_ERR_MISMATCH;
00107 } else if (_tn_call_nodown(res.r_node, &res.r_comps[res.r_startnew],
00108 res.r_count - res.r_startnew)) {
00109
00110 for (i = res.r_startnew, node = res.r_node; i < res.r_count; i++)
00111
00112 if (!(node = _tc_create_node(ctx, node,
00113 ((i == res.r_count - 1 ?
00114 (TC_NODETYPE_VARIABLE) :
00115 (TC_NODETYPE_NODE)) |
00116 TC_NODETYPE_IMPLICIT),
00117 res.r_comps[i].ts_string,
00118 res.r_comps[i].ts_length, 0,
00119 res.r_node->tn_nodown,
00120 res.r_node->tn_change, 0)))
00121 _tc_doerror(ENOMEM);
00122
00123 err = _tc_set(node, value);
00124 } else
00125 err = ENOENT;
00126
00127 error:
00128 free(res.r_comps);
00129
00130 return err;
00131 }