diff options
author | Michael Larson <slioch@slioch.vyatta.com> | 2010-07-19 15:05:05 -0700 |
---|---|---|
committer | Michael Larson <slioch@slioch.vyatta.com> | 2010-07-19 15:05:05 -0700 |
commit | 09c2415650e67e631f7b9fcad49bdd9a0b035698 (patch) | |
tree | 020b7bd407be58d1ffed24cd690a498674daeaea | |
parent | 97d8757a2fe575b2aba258859c8df37ca9ed7cf6 (diff) | |
download | vyatta-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.c | 117 | ||||
-rw-r--r-- | src/cli_val.h | 2 | ||||
-rw-r--r-- | src/commit2.c | 41 | ||||
-rw-r--r-- | src/exe_action.c | 2 |
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); } |