summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Larson <slioch@slioch.vyatta.com>2010-07-19 15:05:05 -0700
committerMichael Larson <slioch@slioch.vyatta.com>2010-07-19 15:05:05 -0700
commit09c2415650e67e631f7b9fcad49bdd9a0b035698 (patch)
tree020b7bd407be58d1ffed24cd690a498674daeaea
parent97d8757a2fe575b2aba258859c8df37ca9ed7cf6 (diff)
downloadvyatta-cfg-09c2415650e67e631f7b9fcad49bdd9a0b035698.tar.gz
vyatta-cfg-09c2415650e67e631f7b9fcad49bdd9a0b035698.zip
modified syntax and commit checks now applied during commit.
modification allows for error statement to be placed after location of error node.
-rw-r--r--src/cli_new.c117
-rw-r--r--src/cli_val.h2
-rw-r--r--src/commit2.c41
-rw-r--r--src/exe_action.c2
4 files changed, 137 insertions, 25 deletions
diff --git a/src/cli_new.c b/src/cli_new.c
index 896206d..ae12622 100644
--- a/src/cli_new.c
+++ b/src/cli_new.c
@@ -77,8 +77,8 @@ static valstruct validate_value_val; /* value being validated
/* Local function declarations: */
static int check_comp(vtw_node *cur);
-static boolean check_syn_func(vtw_node *cur,const char* func,int line);
-#define check_syn(cur) check_syn_func((cur),__FUNCTION__,__LINE__)
+static boolean check_syn_func(vtw_node *cur,const char **outbuf, const char* func,int line);
+#define check_syn(cur,out_buf) check_syn_func((cur),(out_buf),__FUNCTION__,__LINE__)
void copy_path(vtw_path *to, vtw_path *from);
static int eval_va(valstruct *res, vtw_node *node);
static int expand_string(char *p);
@@ -621,14 +621,14 @@ void vtw_sort(valstruct *valp, vtw_sorted *sortp)
/* returns FALSE if execution returns non-null,
returns TRUE if every excution returns NULL
*/
-boolean execute_list(vtw_node *cur, vtw_def *def)
+boolean execute_list(vtw_node *cur, vtw_def *def, const char **outbuf)
{
boolean ret;
int status;
set_in_exec(TRUE);
status = char2val(def, get_at_string(), &validate_value_val);
if (status) return FALSE;
- ret = check_syn(cur);
+ ret = check_syn(cur,outbuf);
free_val(&validate_value_val);
set_in_exec(FALSE);
return ret;
@@ -1151,7 +1151,7 @@ static int change_var_value(const char* var_reference,const char* value, int act
return ret;
}
-int system_out(const char *command);
+int system_out(const char *command, const char **outbuf);
/****************************************************
check_syn:
@@ -1159,7 +1159,7 @@ int system_out(const char *command);
returns TRUE if all checks are OK,
returns FALSE if check fails.
****************************************************/
-static boolean check_syn_func(vtw_node *cur,const char* func,int line)
+static boolean check_syn_func(vtw_node *cur,const char **outbuf,const char* func,int line)
{
int status;
int ret;
@@ -1169,16 +1169,21 @@ static boolean check_syn_func(vtw_node *cur,const char* func,int line)
case LIST_OP:
ret = TRUE;
if (is_in_commit() || !cur->vtw_node_aux) {
- ret = check_syn(cur->vtw_node_left);
+ ret = check_syn(cur->vtw_node_left,outbuf);
}
if (!ret || !cur->vtw_node_right) /* or no right operand */
return ret;
- return check_syn(cur->vtw_node_right);
+ return check_syn(cur->vtw_node_right,outbuf);
case HELP_OP:
- ret = check_syn(cur->vtw_node_left);
+ ret = check_syn(cur->vtw_node_left,outbuf);
if (ret <= 0){
if (expand_string(cur->vtw_node_right->vtw_node_string) == VTWERR_OK) {
- fprintf(out_stream, "%s\n", exe_string);
+ if (outbuf == NULL) {
+ fprintf(out_stream, "%s\n", exe_string);
+ }
+ else {
+ strcat((char*)*outbuf, exe_string);
+ }
}
}
return ret;
@@ -1242,7 +1247,7 @@ static boolean check_syn_func(vtw_node *cur,const char* func,int line)
set_at_string(save_at);
return FALSE;
}
- ret = system_out(exe_string);
+ ret = system_out(exe_string,outbuf);
if (ret) {
set_at_string(save_at);
return FALSE;
@@ -1256,7 +1261,7 @@ static boolean check_syn_func(vtw_node *cur,const char* func,int line)
if (status != VTWERR_OK) {
return FALSE;
}
- ret = system_out(exe_string);
+ ret = system_out(exe_string,outbuf);
return !ret;
case PATTERN_OP: /* left to var, right to pattern */
@@ -1294,15 +1299,15 @@ static boolean check_syn_func(vtw_node *cur,const char* func,int line)
}
case OR_OP:
- ret = check_syn(cur->vtw_node_left) ||
- check_syn(cur->vtw_node_right);
+ ret = check_syn(cur->vtw_node_left,outbuf) ||
+ check_syn(cur->vtw_node_right,outbuf);
return ret;
case AND_OP:
- ret = check_syn(cur->vtw_node_left) &&
- check_syn(cur->vtw_node_right);
+ ret = check_syn(cur->vtw_node_left,outbuf) &&
+ check_syn(cur->vtw_node_right,outbuf);
return ret;
case NOT_OP:
- ret = check_syn(cur->vtw_node_left);
+ ret = check_syn(cur->vtw_node_left,outbuf);
return !ret;
case COND_OP: /* aux field specifies cond type (GT, GE, etc.)*/
@@ -2077,7 +2082,7 @@ boolean validate_value(vtw_def *def, char *cp)
ret = TRUE;
if (def->actions && def->actions[syntax_act].vtw_list_head){
in_validate_val = TRUE;
- ret = check_syn(def->actions[syntax_act].vtw_list_head);
+ ret = check_syn(def->actions[syntax_act].vtw_list_head,(const char **)NULL);
in_validate_val = FALSE;
}
validate_value_free_and_return:
@@ -2394,8 +2399,9 @@ restore_output()
* call system() with output re-enabled.
* output is again redirected before returning from here.
*/
+
int
-system_out(const char *command)
+old_system_out(const char *command)
{
int ret = -1;
if (restore_output() == -1) {
@@ -2406,9 +2412,82 @@ system_out(const char *command)
if (redirect_output() == -1) {
return -1;
}
+
+ // fprintf(out_stream,"old system out: %d, for cmd: %s\n",ret,command);
return ret;
}
+
+
+int
+system_out(const char *cmd, const char **outbuf)
+{
+ // fprintf(out_stream,"system out\n");
+ if (outbuf == NULL) {
+ return old_system_out(cmd);
+ }
+
+ /*
+ struct sigaction sa;
+ sigaction(SIGCHLD, NULL, &sa);
+ sa.sa_flags |= SA_NOCLDWAIT;//(since POSIX.1-2001 and Linux 2.6 and later)
+ sigaction(SIGCHLD, &sa, NULL);
+ */
+ if (cmd == NULL) {
+ return -1;
+ }
+ //should detach child process at this point
+ umask(0);
+ setsid();
+
+ int cp[2]; // Child to parent pipe
+
+ if( pipe(cp) < 0) {
+ return -1;
+ }
+
+ pid_t pid = fork();
+ if (pid == 0) {
+ //child
+ close(1); // Close current stdout./
+ dup2( cp[1],1); // Make stdout go to write end of pipe.
+ dup2( cp[1],2); // Make stderr go to write end of pipe.
+ close(0); // Close current stdin.
+ close( cp[0]);
+
+ int ret = system(cmd);
+ close( cp[1]);
+
+ //doing this to match old system out command, although this doesn't
+ //appear to be entirely correct in the interpretation of the error codes from system
+ if (ret > 255) {
+ ret = -1;
+ }
+
+ exit(ret);
+ }
+ else {
+ //parent
+ char buf[1025];
+ int size = 0;
+ memset(buf,'\0',1025);
+ close(cp[1]);
+ if (read(cp[0], &buf, 1024) > 0) {
+ strcat((char*)*outbuf,buf);
+ }
+
+ //now wait on child to kick the bucket
+ int status;
+ wait(&status);
+ close(cp[0]);
+ if (WIFEXITED(status) == TRUE) {
+ return WEXITSTATUS(status);
+ }
+ }
+ return 0;
+}
+
+
/**********************************************************/
diff --git a/src/cli_val.h b/src/cli_val.h
index fbd48d9..6918fcf 100644
--- a/src/cli_val.h
+++ b/src/cli_val.h
@@ -200,7 +200,7 @@ extern void touch(void);
extern int mkdir_p(const char *path);
extern const char *type_to_name(vtw_type_e type);
-extern boolean execute_list(vtw_node *cur, vtw_def *def);
+extern boolean execute_list(vtw_node *cur, vtw_def *def, const char **outbuf);
extern void touch_dir(const char *dp);
extern void touch_file(const char *name);
diff --git a/src/commit2.c b/src/commit2.c
index 56e4290..e3cc3df 100644
--- a/src/commit2.c
+++ b/src/commit2.c
@@ -550,7 +550,7 @@ process_func(GNode *node, gpointer data)
}
if (g_dump_actions == FALSE) {
- status = execute_list(c->_def.actions[result->_action].vtw_list_head,&c->_def);
+ status = execute_list(c->_def.actions[result->_action].vtw_list_head,&c->_def,NULL);
}
else {
char buf[MAX_LENGTH_DIR_PATH*sizeof(char)];
@@ -1265,7 +1265,7 @@ validate_func(GNode *node, gpointer data)
result->_data = (void*)coll;
}
}
-
+
//don't run syntax check on this node if it is unchanged.
if (IS_NOOP(d->_operation) && (c->_def.actions[syntax_act].vtw_list_head != NULL && c->_def.actions[syntax_act].vtw_list_head->vtw_node_aux == 0)) {
return FALSE;
@@ -1273,7 +1273,7 @@ validate_func(GNode *node, gpointer data)
//don't perform validation checks on disabled nodes
if ((d->_disable_op == K_LOCAL_DISABLE_OP) || (d->_disable_op == (K_LOCAL_DISABLE_OP | K_ACTIVE_DISABLE_OP))) {
- return FALSE; //SHOULD only hit the case where the node is locally disabled or globally disabled and not in a transition to active state
+ return FALSE; //SHOULD only hit the case where the node is locally disabled or globally disabled and not in a transition to active state
}
if (IS_DELETE(d->_operation) && !IS_ACTIVE(d->_operation)) {
@@ -1328,11 +1328,13 @@ validate_func(GNode *node, gpointer data)
fprintf(out_stream,"[START] %lu, %s@%s",(unsigned long)t.tv_sec,ActionNames[result->_action],d->_path);
}
+ char *outbuf = malloc(8192);
+ outbuf[0] = '\0';
boolean status = 1;
if (g_dump_actions == FALSE) {
//set location env
setenv(ENV_DATA_PATH,d->_path,1);
- status = execute_list(c->_def.actions[result->_action].vtw_list_head,&c->_def);
+ status = execute_list(c->_def.actions[result->_action].vtw_list_head,&c->_def,(const char**)&outbuf);
unsetenv(ENV_DATA_PATH);
}
else {
@@ -1360,6 +1362,35 @@ validate_func(GNode *node, gpointer data)
}
if (!status) { //EXECUTE_LIST RETURNS FALSE ON FAILURE....
+ //just need to convert slashes into spaces here
+ char path_buf[1024];
+ char tmp[1024];
+ char *ptr;
+ path_buf[0] = '\0';
+
+ strcpy(tmp,d->_path);
+ ptr = (char*)tmp;
+ char *slash = strchr(tmp,'/');
+ if (slash == NULL) {
+ strcat(path_buf,d->_path);
+ }
+ else {
+ do { //convert '/' to ' '
+ strncat(path_buf,ptr,slash - ptr);
+ strcat(path_buf," ");
+ ++slash;
+ ptr = slash;
+ } while ((slash = strchr(slash,'/')) != NULL);
+ }
+ if (strncmp(ptr,"value:",6) == 0) {
+ if (strlen(ptr)-6 > 0) {
+ strncat(path_buf,ptr+6,strlen(ptr)-6);
+ }
+ }
+ char *p = clind_unescape(path_buf);
+ if (strlen(outbuf) > 0) {
+ fprintf(out_stream,"[ %s ] \n %s\n",p,outbuf);
+ }
syslog(LOG_ERR,"commit error for %s:[%s]\n",ActionNames[result->_action],d->_path);
if (g_display_error_node) {
fprintf(out_stream,"%s:[%s]\n",ActionNames[result->_action],d->_path);
@@ -1369,8 +1400,10 @@ validate_func(GNode *node, gpointer data)
printf("commit2::validate_func(): FAILURE: status: %d\n",status);
syslog(LOG_DEBUG,"commit2::validate_func(): FAILURE: status: %d",status);
}
+ free(outbuf);
return result->_mode ? FALSE: TRUE; //WILL STOP AT THIS POINT if mode is not set for full syntax check
}
+ free(outbuf);
return FALSE;
}
diff --git a/src/exe_action.c b/src/exe_action.c
index f8920e1..b650a4f 100644
--- a/src/exe_action.c
+++ b/src/exe_action.c
@@ -100,7 +100,7 @@ main(int argc, char** argv)
//BROKEN--NEEDS TO BE FIX BELOW FOR DPATH AND CPATH
common_set_context(path,path);
- status = execute_list(def.actions[act].vtw_list_head,&def);
+ status = execute_list(def.actions[act].vtw_list_head,&def,NULL);
if (status == FALSE) {
printf("command failed! status: %d\n", status);
}