summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xetc/bash_completion.d/20vyatta-cfg4
-rw-r--r--src/cli_parse.y39
-rw-r--r--src/cli_val.h2
-rw-r--r--src/commit2.c2
-rw-r--r--src/common/defs.h1
-rw-r--r--src/common/unionfs.c9
-rw-r--r--src/set.c57
7 files changed, 110 insertions, 4 deletions
diff --git a/etc/bash_completion.d/20vyatta-cfg b/etc/bash_completion.d/20vyatta-cfg
index d08c9d8..4463ee3 100755
--- a/etc/bash_completion.d/20vyatta-cfg
+++ b/etc/bash_completion.d/20vyatta-cfg
@@ -633,8 +633,8 @@ vyatta_parse_tmpl ()
s/^\([^;]\+\);.*$/\1 )/
s/[ ]*,[ ]*/ /gp
}
- s/^tag:/vyatta_cfg_tag=1/p
- s/^multi:/vyatta_cfg_multi=1/p
+ s/^tag:.*/vyatta_cfg_tag=1/p
+ s/^multi:.*/vyatta_cfg_multi=1/p
s/^type:[ ]\+\([^ ;]\+\)\(;.*\)\?/vyatta_cfg_type=\1/p
' $1`
diff --git a/src/cli_parse.y b/src/cli_parse.y
index dd3d7d2..89c6638 100644
--- a/src/cli_parse.y
+++ b/src/cli_parse.y
@@ -89,8 +89,45 @@ otherinput: type EOL
;
tag: /* empty */
- | TAG EOL {parse_defp->tag = TRUE;}
+ | TAG EOL {parse_defp->tag = TRUE;}
+ | TAG VALUE {
+ parse_defp->tag = TRUE;
+ char *tmp = $2.val;
+ long long int cval = 0;
+ char *endp = NULL;
+ errno = 0;
+ cval = strtoll(tmp, &endp, 10);
+ if (($2.val_type != INT_TYPE)
+ || (errno == ERANGE
+ && (cval == LLONG_MAX || cval == LLONG_MIN))
+ || (errno != 0 && cval == 0)
+ || (*endp != '\0') || (cval < 0) || (cval > UINT_MAX)) {
+ yy_cli_parse_error((const char *)
+ "Tag must be <u32>\n");
+ } else {
+ parse_defp->def_tag = cval;
+ }
+ }
| MULTI EOL {parse_defp->multi = TRUE;}
+ | MULTI VALUE
+ {
+ parse_defp->multi = TRUE;
+ char *tmp = $2.val;
+ long long int cval = 0;
+ char *endp = NULL;
+ errno = 0;
+ cval = strtoll(tmp, &endp, 10);
+ if (($2.val_type != INT_TYPE)
+ || (errno == ERANGE
+ && (cval == LLONG_MAX || cval == LLONG_MIN))
+ || (errno != 0 && cval == 0)
+ || (*endp != '\0') || (cval < 0) || (cval > UINT_MAX)) {
+ yy_cli_parse_error((const char *)
+ "Tag must be <u32>\n");
+ } else {
+ parse_defp->def_multi = cval;
+ }
+ }
;
type: TYPE TYPE_DEF SEMI STRING
diff --git a/src/cli_val.h b/src/cli_val.h
index e8fbe83..9b3bcda 100644
--- a/src/cli_val.h
+++ b/src/cli_val.h
@@ -106,6 +106,8 @@ typedef struct {
char *def_node_help;
char *def_default;
unsigned int def_priority;
+ unsigned int def_tag;
+ unsigned int def_multi;
boolean tag;
boolean multi;
vtw_list actions[top_act];
diff --git a/src/commit2.c b/src/commit2.c
index 3143e51..1b22bf8 100644
--- a/src/commit2.c
+++ b/src/commit2.c
@@ -816,7 +816,7 @@ dump_func(GNode *node, gpointer data)
fprintf(out," [VALUE]");
}
if (((struct VyattaNode*)gp)->_config._multi == TRUE) {
- fprintf(out," [MULTI]");
+ fprintf(out," [MULTI(%d)]",((struct VyattaNode*)gp)->_config._limit);
}
if (((struct VyattaNode*)gp)->_config._def.actions[syntax_act].vtw_list_head &&
((struct VyattaNode*)gp)->_config._def.actions[syntax_act].vtw_list_head->vtw_node_aux == 0) {
diff --git a/src/common/defs.h b/src/common/defs.h
index 934364a..8c68c1d 100644
--- a/src/common/defs.h
+++ b/src/common/defs.h
@@ -55,6 +55,7 @@ struct Config
{
boolean _multi;
int _priority;
+ int _limit;
vtw_def _def; //keep this here
char* _help;
char* _default;
diff --git a/src/common/unionfs.c b/src/common/unionfs.c
index b573d17..2220d73 100644
--- a/src/common/unionfs.c
+++ b/src/common/unionfs.c
@@ -225,6 +225,15 @@ retrieve_data(char* rel_data_path, GNode *node, char* root, NODE_OPERATION op)
}
//either multi or tag--shouldn't have made a difference, but arkady was confused.
vn->_config._multi = (def.tag | def.multi);
+ if (def.def_tag > 0) {
+ vn->_config._limit = def.def_tag;
+ }
+ else if (def.def_multi > 0) {
+ vn->_config._limit = def.def_multi;
+ }
+ else {
+ vn->_config._limit = 0;
+ }
}
}
diff --git a/src/set.c b/src/set.c
index 9be3fc8..47db90c 100644
--- a/src/set.c
+++ b/src/set.c
@@ -91,6 +91,63 @@ boolean set_validate(vtw_def *defp, char *valp, boolean empty_val)
}
return TRUE;
}
+
+ //apply limit count here, needs to be defined as a tag,multi and have a value set
+ if ((defp->tag || defp->multi) && (defp->def_tag > 0 || defp->def_multi > 0)) {
+ //get count of siblings
+
+ char path[2048];
+ char val[2048];
+ char last_val[2048];
+ char *pos = rindex(m_path.path,'/');
+ if (pos != NULL) {
+ int offset = pos - m_path.path;
+
+ strncpy(path,m_path.path,offset);
+ path[offset] = '\0';
+
+ strncpy(val,m_path.path + offset + 1, strlen(m_path.path) - offset - 1);
+ val[strlen(m_path.path) - offset - 1] = '\0';
+
+ // fprintf(out_stream,"val: %s, offset: %d, path: %s\n",val,offset,m_path.path);
+
+ int file_count = 0;
+ struct dirent* entry;
+ DIR* dirp = opendir(path); /* There should be error handling after this */
+ if (dirp != NULL) {
+ while ((entry = readdir(dirp)) != NULL) {
+ if (strcmp(entry->d_name,".") != 0 &&
+ strcmp(entry->d_name,"..") != 0) {
+ strcpy(last_val,entry->d_name);
+ file_count++;
+ }
+ }
+ closedir(dirp);
+
+ if (defp->tag && file_count == 1 && defp->def_tag == 1) {
+ //this is the special case, where the previous value should be deleted here...
+ char command[8192];
+ //let unionfs handle the diff
+ sprintf(command, "mv %s/%s %s/%s", path,last_val,path,val);
+ system(command);
+ }
+
+ if (defp->tag) {
+ if (defp->def_tag > 1 && file_count >= defp->def_tag) {
+ fprintf(out_stream,"Number of values exceeded for %s, allowed: %d, actual: %d\n",val,defp->def_tag,file_count);
+ return FALSE;
+ }
+ }
+ else {
+ if (defp->def_multi > 1 && file_count >= defp->def_multi) {
+ fprintf(out_stream,"Number of values exceeded for %s, allowed: %d, actual: %d\n",val,defp->def_multi,file_count);
+ return FALSE;
+ }
+ }
+ }
+ }
+ }
+
res = validate_value(defp, valp);
return res;
}