Res *setVariableValue(char *varName, Res *val, ruleExecInfo_t *rei, Env *env, rError_t *errmsg, Region *r) { int i; char *varMap; char errbuf[ERR_MSG_LEN]; if (varName[0] == '$') { if(TYPE(val)!=T_STRING) { snprintf(errbuf, ERR_MSG_LEN, "error: assign a nonstring value to session variable %s.", varName); addRErrorMsg(errmsg, RE_UNSUPPORTED_OP_OR_TYPE, errbuf); return newErrorRes(r, RE_UNSUPPORTED_OP_OR_TYPE); } i = getVarMap("", varName, &varMap, 0); if (i < 0) { snprintf(errbuf, ERR_MSG_LEN, "error: unsupported session variable \"%s\".",varName); addRErrorMsg(errmsg, RE_UNSUPPORTED_SESSION_VAR, errbuf); return newErrorRes(r, RE_UNSUPPORTED_SESSION_VAR); } setVarValue(varMap, rei, strdup(val->text)); return newIntRes(r, 0); } else if(varName[0] == '*') { if(lookupFromEnv(env, varName)==NULL) { /* new variable */ if(insertIntoHashTable(env->current, varName, val) == 0) { snprintf(errbuf, ERR_MSG_LEN, "error: unable to write to local variable \"%s\".",varName); addRErrorMsg(errmsg, RE_UNABLE_TO_WRITE_LOCAL_VAR, errbuf); return newErrorRes(r, RE_UNABLE_TO_WRITE_LOCAL_VAR); } } else { updateInEnv(env, varName, val); } return newIntRes(r, 0); } return newIntRes(r, 0); }
int rsGetHierFromLeafId( rsComm_t* _comm, get_hier_inp_t* _inp, get_hier_out_t** _out ) { if( !_comm || !_inp || !_out ) { addRErrorMsg( &_comm->rError, STDOUT_STATUS, "null input param(s)"); return SYS_INTERNAL_NULL_INPUT_ERR; } ( *_out ) = ( get_hier_out_t* )malloc( sizeof( get_hier_out_t ) ); std::string hier; irods::error ret = resc_mgr.leaf_id_to_hier( _inp->resc_id_, hier ); if( !ret.ok() ) { addRErrorMsg( &_comm->rError, STDOUT_STATUS, ret.result().c_str() ); return ret.code(); } rstrcpy( (*_out)->hier_, hier.c_str(), MAX_NAME_LEN ); return 0; }
int _rsSpecificQuery( rsComm_t *rsComm, specificQueryInp_t *specificQueryInp, genQueryOut_t **genQueryOut ) { int status; *genQueryOut = ( genQueryOut_t* )malloc( sizeof( genQueryOut_t ) ); memset( ( char * )*genQueryOut, 0, sizeof( genQueryOut_t ) ); status = chlSpecificQuery( *specificQueryInp, *genQueryOut ); if ( status == CAT_UNKNOWN_SPECIFIC_QUERY ) { int i; i = addRErrorMsg( &rsComm->rError, 0, "The SQL is not pre-defined.\n See 'iadmin h asq' (add specific query)" ); if ( i < 0 ) { irods::log( i, "addErrorMsg failed" ); } } if ( status < 0 ) { clearGenQueryOut( *genQueryOut ); free( *genQueryOut ); *genQueryOut = NULL; if ( status != CAT_NO_ROWS_FOUND ) { rodsLog( LOG_NOTICE, "_rsSpecificQuery: specificQuery status = %d", status ); } return status; } return status; }
int readRuleSetFromLocalFile( const char *ruleBaseName, const char *rulesFileName, RuleSet *ruleSet, Env *funcDesc, int *errloc, rError_t *errmsg, Region *r ) { FILE *file; char errbuf[ERR_MSG_LEN]; file = fopen( rulesFileName, "r" ); if ( file == NULL ) { snprintf( errbuf, ERR_MSG_LEN, "readRuleSetFromFile() could not open rules file %s\n", rulesFileName ); addRErrorMsg( errmsg, RULES_FILE_READ_ERROR, errbuf ); return RULES_FILE_READ_ERROR; } Pointer *e = newPointer( file, ruleBaseName ); int ret = parseRuleSet( e, ruleSet, funcDesc, errloc, errmsg, r ); deletePointer( e ); if ( ret < 0 ) { return ret; } Node *errnode{}; ExprType *restype = typeRuleSet( ruleSet, errmsg, &errnode, r ); if ( getNodeType( restype ) == T_ERROR ) { if ( NULL != errnode ) { *errloc = NODE_EXPR_POS( errnode ); } return RE_TYPE_ERROR; } return 0; }
ExprType *typeRule( RuleDesc *rule, Env *funcDesc, Hashtable *varTypes, List *typingConstraints, rError_t *errmsg, Node **errnode, Region *r ) { /* printf("%s\n", node->subtrees[0]->text); */ addRErrorMsg( errmsg, -1, ERR_MSG_SEP ); char buf[ERR_MSG_LEN]; Node *node = rule->node; int dynamictyping = rule->dynamictyping; ExprType *resType = typeExpression3( node->subtrees[1], dynamictyping, funcDesc, varTypes, typingConstraints, errmsg, errnode, r ); /*printf("Type %d\n",resType->t); */ RE_ERROR( getNodeType( resType ) == T_ERROR ); if ( getNodeType( resType ) != T_BOOL && getNodeType( resType ) != T_VAR && getNodeType( resType ) != T_DYNAMIC ) { char buf2[1024], buf3[ERR_MSG_LEN]; typeToString( resType, varTypes, buf2, 1024 ); snprintf( buf3, ERR_MSG_LEN, "error: the type %s of the rule condition is not supported", buf2 ); generateErrMsg( buf3, NODE_EXPR_POS( node->subtrees[1] ), node->subtrees[1]->base, buf ); addRErrorMsg( errmsg, RE_TYPE_ERROR, buf ); RE_ERROR( 1 ); } resType = typeExpression3( node->subtrees[2], dynamictyping, funcDesc, varTypes, typingConstraints, errmsg, errnode, r ); RE_ERROR( getNodeType( resType ) == T_ERROR ); resType = typeExpression3( node->subtrees[3], dynamictyping, funcDesc, varTypes, typingConstraints, errmsg, errnode, r ); RE_ERROR( getNodeType( resType ) == T_ERROR ); /* printVarTypeEnvToStdOut(varTypes); */ RE_ERROR( solveConstraints( typingConstraints, varTypes, errmsg, errnode, r ) == ABSURDITY ); int i; for ( i = 1; i <= 3; i++ ) { // 1 = cond, 2 = actions, 3 = recovery postProcessCoercion( node->subtrees[i], varTypes, errmsg, errnode, r ); postProcessActions( node->subtrees[i], funcDesc, errmsg, errnode, r ); } /*printTree(node, 0); */ return newSimpType( T_INT, r ); error: snprintf( buf, ERR_MSG_LEN, "type error: in rule %s", node->subtrees[0]->text ); addRErrorMsg( errmsg, RE_TYPE_ERROR, buf ); return resType; }
int typeNode( Node *node, Hashtable *varTypes, rError_t *errmsg, Node **errnode, Region *r ) { if ( ( node->option & OPTION_TYPED ) == 0 ) { /*printTree(node, 0); */ List *typingConstraints = newList( r ); Res *resType = typeExpression3( node, 0, ruleEngineConfig.extFuncDescIndex, varTypes, typingConstraints, errmsg, errnode, r ); /*printf("Type %d\n",resType->t); */ if ( getNodeType( resType ) == T_ERROR ) { addRErrorMsg( errmsg, RE_TYPE_ERROR, "type error: in rule" ); return RE_TYPE_ERROR; } postProcessCoercion( node, varTypes, errmsg, errnode, r ); postProcessActions( node, ruleEngineConfig.extFuncDescIndex, errmsg, errnode, r ); /* printTree(node, 0); */ varTypes = NULL; node->option |= OPTION_TYPED; } return 0; }
error impostor_resource::report_error( resource_plugin_context& _ctx ) { std::string resc_name; error ret = _ctx.prop_map().get< std::string >( RESOURCE_NAME, resc_name ); if( !ret.ok() ){ return PASS( ret ); } std::string resc_type; ret = _ctx.prop_map().get< std::string >( RESOURCE_TYPE, resc_type ); if( !ret.ok() ){ return PASS( ret ); } std::string msg( "NOTE :: Direct Access of Impostor Resource [" ); msg += resc_name + "] of Given Type [" + resc_type + "]"; addRErrorMsg( &_ctx.comm()->rError, STDOUT_STATUS, msg.c_str() ); return ERROR( INVALID_ACCESS_TO_IMPOSTOR_RESOURCE, msg ); }
/************************ Res to Microservice parameter ***********************/ int convertResToMsParam(msParam_t *var, Res *res, rError_t *errmsg) { strArray_t *arr = NULL; intArray_t *arr2 = NULL; int i = 0; int maxlen = 0; var->inpOutBuf = NULL; var->label = NULL; switch(TYPE(res)) { case T_ERROR: /* error message */ var->inOutStruct = (int *)malloc(sizeof(int)); *((int *)var->inOutStruct) = RES_ERR_CODE(res); var->type = strdup(INT_MS_T); break; case T_DOUBLE: /* number */ var->inOutStruct = (double *)malloc(sizeof(double)); *((double *)var->inOutStruct) = RES_DOUBLE_VAL(res); var->type = strdup(DOUBLE_MS_T); break; case T_INT: /* number */ var->inOutStruct = (int *)malloc(sizeof(int)); *((int *)var->inOutStruct) = RES_INT_VAL(res); var->type = strdup(INT_MS_T); break; case T_STRING: /* string */ var->inOutStruct = res->text == NULL? NULL : strdup(res->text); var->type = strdup(STR_MS_T); break; case T_PATH: /* path */ var->inOutStruct = res->text == NULL? NULL : strdup(res->text); var->type = strdup(STR_MS_T); break; case T_DATETIME: /* date time */ /*var->inOutStruct = (time_t *)malloc(sizeof(time_t)); */ /**((time_t *)var->inOutStruct) = res->value.t; */ /*var->type = strdup(DATETIME_MS_T); */ /* Here we pass datatime as an integer to reuse exiting packing instructions. Need to change to long int. */ var->inOutStruct = (rodsLong_t *)malloc(sizeof(int)); *((rodsLong_t *)var->inOutStruct) = RES_TIME_VAL(res); var->type = strdup(INT_MS_T); break; case T_CONS: if(strcmp(T_CONS_TYPE_NAME(res->exprType), LIST) == 0) { switch(getNodeType(T_CONS_TYPE_ARG(res->exprType, 0))) { case T_STRING: arr = (strArray_t *)malloc(sizeof(strArray_t)); arr->len = res->degree; maxlen = 0; for(i=0;i<res->degree;i++) { int slen = RES_STRING_STR_LEN(res->subtrees[i]); maxlen = maxlen < slen? slen: maxlen; } arr->size = maxlen; arr->value = (char *)malloc(sizeof(char)*maxlen*(arr->len)); for(i=0;i<res->degree;i++) { strcpy(arr->value + maxlen*i, res->subtrees[i]->text); } var->inOutStruct = arr; var->type = strdup(StrArray_MS_T); break; case T_INT: arr2 = (intArray_t *)malloc(sizeof(intArray_t)); arr2->len = res->degree; arr2->value = (int *)malloc(sizeof(int)*(arr2->len)); for(i=0;i<res->degree;i++) { arr2->value[i] = RES_INT_VAL(res); } var->inOutStruct = arr2; var->type = strdup(IntArray_MS_T); break; /*case T_IRODS: var->inOutStruct = res->value.uninterpreted.inOutStruct; var->inpOutBuf = res->value.uninterpreted.inOutBuffer; var->type = strdup(KeyValPair_MS_T); break;*/ default: /* current there is no existing packing instructions for arbitrary collection */ /* report error */ addRErrorMsg(errmsg, RE_PACKING_ERROR, "no packing instruction for arbitrary collection type"); return RE_PACKING_ERROR; } } else { addRErrorMsg(errmsg, RE_PACKING_ERROR, "no packing instruction for arbitrary constructed type"); return RE_PACKING_ERROR; } break; case T_IRODS: var->inOutStruct = RES_UNINTER_STRUCT(res); var->inpOutBuf = RES_UNINTER_BUFFER(res); var->type = strdup(res->exprType->text); break; case T_UNSPECED: var->inOutStruct = NULL; var->type = NULL; break; default: /*error */ addRErrorMsg(errmsg, RE_PACKING_ERROR, "no packing instruction for arbitrary type"); return RE_PACKING_ERROR; } return 0; }
int _rsRuleExecDel( rsComm_t *rsComm, ruleExecDelInp_t *ruleExecDelInp ) { genQueryOut_t *genQueryOut = NULL; int status; sqlResult_t *reiFilePath; sqlResult_t *ruleUserName; char reiDir[MAX_NAME_LEN]; std::string svc_role; irods::error ret = get_catalog_service_role(svc_role); if(!ret.ok()) { irods::log(PASS(ret)); return ret.code(); } status = getReInfoById( rsComm, ruleExecDelInp->ruleExecId, &genQueryOut ); if ( status < 0 ) { rodsLog( LOG_ERROR, "_rsRuleExecDel: getReInfoById failed, status = %d", status ); /* unregister it anyway */ if( irods::CFG_SERVICE_ROLE_PROVIDER == svc_role ) { status = chlDelRuleExec( rsComm, ruleExecDelInp->ruleExecId ); if ( status < 0 ) { rodsLog( LOG_ERROR, "_rsRuleExecDel: chlDelRuleExec for %s error, status = %d", ruleExecDelInp->ruleExecId, status ); } return status; } else if( irods::CFG_SERVICE_ROLE_CONSUMER == svc_role ) { rodsLog( LOG_ERROR, "_rsRuleExecDel: chlDelRuleExec only in ICAT host" ); return SYS_NO_RCAT_SERVER_ERR; } else { const auto err{ERROR(SYS_SERVICE_ROLE_NOT_SUPPORTED, (boost::format("role not supported [%s]") % svc_role.c_str()).str().c_str())}; irods::log(err); return err.code(); } } if ( ( reiFilePath = getSqlResultByInx( genQueryOut, COL_RULE_EXEC_REI_FILE_PATH ) ) == NULL ) { rodsLog( LOG_NOTICE, "_rsRuleExecDel: getSqlResultByInx for REI_FILE_PATH failed" ); return UNMATCHED_KEY_OR_INDEX; } /* First check permission (now that API is allowed for non-admin users) */ if ( rsComm->proxyUser.authInfo.authFlag < LOCAL_PRIV_USER_AUTH ) { if ( rsComm->proxyUser.authInfo.authFlag == LOCAL_USER_AUTH ) { if ( ( ruleUserName = getSqlResultByInx( genQueryOut, COL_RULE_EXEC_USER_NAME ) ) == NULL ) { rodsLog( LOG_NOTICE, "_rsRuleExecDel: getSqlResultByInx for COL_RULE_EXEC_USER_NAME failed" ); return UNMATCHED_KEY_OR_INDEX; } if ( strncmp( ruleUserName->value, rsComm->clientUser.userName, MAX_NAME_LEN ) != 0 ) { return USER_ACCESS_DENIED; } } else { return USER_ACCESS_DENIED; } } /* some sanity check */ snprintf( reiDir, MAX_NAME_LEN, "/%-s/%-s.", PACKED_REI_DIR, REI_FILE_NAME ); if ( strstr( reiFilePath->value, reiDir ) == NULL ) { if( irods::CFG_SERVICE_ROLE_PROVIDER == svc_role ) { int i; char errMsg[105]; rodsLog( LOG_NOTICE, "_rsRuleExecDel: reiFilePath: %s is not a proper rei path", reiFilePath->value ); /* Try to unregister it anyway */ status = chlDelRuleExec( rsComm, ruleExecDelInp->ruleExecId ); if ( status ) { return ( status ); /* that failed too, report it */ } /* Add a message to the error stack for the client user */ snprintf( errMsg, sizeof errMsg, "Rule was removed but reiPath was invalid: %s", reiFilePath->value ); i = addRErrorMsg( &rsComm->rError, 0, errMsg ); if ( i < 0 ) { irods::log( ERROR( i, "addRErrorMsg failed" ) ); } freeGenQueryOut( &genQueryOut ); return SYS_INVALID_FILE_PATH; } else if( irods::CFG_SERVICE_ROLE_CONSUMER == svc_role ) { rodsLog( LOG_ERROR, "_rsRuleExecDel: chlDelRuleExec only in ICAT host" ); return SYS_NO_RCAT_SERVER_ERR; } else { const auto err{ERROR(SYS_SERVICE_ROLE_NOT_SUPPORTED, (boost::format("role not supported [%s]") % svc_role.c_str()).str().c_str())}; irods::log(err); return err.code(); } } status = unlink( reiFilePath->value ); if ( status < 0 ) { status = UNIX_FILE_UNLINK_ERR - errno; rodsLog( LOG_ERROR, "_rsRuleExecDel: unlink of %s error, status = %d", reiFilePath->value, status ); if ( errno != ENOENT ) { freeGenQueryOut( &genQueryOut ); return status; } } if( irods::CFG_SERVICE_ROLE_PROVIDER == svc_role ) { int unlinkStatus = status; /* unregister it */ status = chlDelRuleExec( rsComm, ruleExecDelInp->ruleExecId ); if ( status < 0 ) { rodsLog( LOG_ERROR, "_rsRuleExecDel: chlDelRuleExec for %s error, status = %d", ruleExecDelInp->ruleExecId, status ); } if ( unlinkStatus ) { int i; char errMsg[105]; /* Add a message to the error stack for the client user */ snprintf( errMsg, sizeof errMsg, "Rule was removed but unlink of rei file failed" ); i = addRErrorMsg( &rsComm->rError, 0, errMsg ); if ( i < 0 ) { irods::log( ERROR( i, "addRErrorMsg failed" ) ); } snprintf( errMsg, sizeof errMsg, "rei file: %s", reiFilePath->value ); i = addRErrorMsg( &rsComm->rError, 1, errMsg ); if (i < 0) { irods::log(ERROR(i, "addRErrorMsg failed")); } if ( status == 0 ) { /* return this error if no other error occurred */ status = unlinkStatus; } } freeGenQueryOut( &genQueryOut ); return status; } else if( irods::CFG_SERVICE_ROLE_CONSUMER == svc_role ) { rodsLog( LOG_ERROR, "_rsRuleExecDel: chlDelRuleExec only in ICAT host" ); return SYS_NO_RCAT_SERVER_ERR; } else { const auto err{ERROR(SYS_SERVICE_ROLE_NOT_SUPPORTED, (boost::format("role not supported [%s]") % svc_role.c_str()).str().c_str())}; irods::log(err); return err.code(); } }
void rodsLogAndErrorMsg (int level, rError_t *myError, int status, char *formatStr, ...) { char bigString[BIG_STRING_LEN]; char *prefix; time_t timeValue; int i; FILE *errOrOut; va_list ap; char errMsg[ERR_MSG_LEN]; char extraInfo[100]; #ifdef windows_platform char nt_log_msg[2048]; #endif if (level > verbosityLevel) return; va_start(ap, formatStr); i = vsnprintf(bigString, BIG_STRING_LEN-1, formatStr, ap); va_end(ap); extraInfo[0]='\0'; errOrOut = stdout; if (ProcessType == SERVER_PT || ProcessType == AGENT_PT || ProcessType == RE_SERVER_PT) { char timeBuf[100]; time(&timeValue); rstrcpy(timeBuf, ctime(&timeValue), 90); timeBuf[19]='\0'; myPid = getpid(); snprintf(extraInfo, 100-1, "%s pid:%d ", timeBuf+4, myPid); } else { if (level <= LOG_ERROR || level == LOG_SQL) errOrOut=stderr; } prefix=""; if (level == LOG_SQL) prefix="LOG_SQL"; if (level == LOG_SYS_FATAL) prefix="SYSTEM FATAL"; if (level == LOG_SYS_WARNING) prefix="SYSTEM WARNING"; if (level == LOG_ERROR) prefix="ERROR"; if (level == LOG_NOTICE) prefix="NOTICE"; if (level <= LOG_DEBUG) prefix="DEBUG"; if (bigString[strlen(bigString)-1]=='\n') { #ifndef windows_platform fprintf(errOrOut, "%s%s: %s", extraInfo, prefix, bigString); if (myError != NULL) { snprintf (errMsg, ERR_MSG_LEN, "%s: %s", prefix, bigString); addRErrorMsg (myError, status, errMsg); } #else sprintf(nt_log_msg, "%s%s: %s", extraInfo, prefix, bigString); rodsNtElog(nt_log_msg); #endif } else { #ifndef windows_platform fprintf(errOrOut, "%s%s: %s\n", extraInfo, prefix, bigString); if (myError != NULL) { snprintf (errMsg, ERR_MSG_LEN, "%s: %s\n", prefix, bigString); addRErrorMsg (myError, status, errMsg); } #else sprintf(nt_log_msg, "%s%s: %s\n", extraInfo, prefix, bigString); rodsNtElog(nt_log_msg); #endif } #ifndef windows_platform fflush (errOrOut); #endif }
/* parse and compute an expression * */ Res *parseAndComputeExpression( char *expr, Env *env, ruleExecInfo_t *rei, int reiSaveFlag, rError_t *errmsg, Region *r ) { Res *res = NULL; char buf[ERR_MSG_LEN > 1024 ? ERR_MSG_LEN : 1024]; int rulegen; Node *node = NULL, *recoNode = NULL; #ifdef DEBUG snprintf( buf, 1024, "parseAndComputeExpression: %s\n", expr ); writeToTmp( "entry.log", buf ); #endif if ( overflow( expr, MAX_RULE_LEN ) ) { addRErrorMsg( errmsg, RE_BUFFER_OVERFLOW, "error: potential buffer overflow" ); return newErrorRes( r, RE_BUFFER_OVERFLOW ); } Pointer *e = newPointer2( expr ); ParserContext *pc = newParserContext( errmsg, r ); if ( e == NULL ) { addRErrorMsg( errmsg, RE_POINTER_ERROR, "error: can not create pointer." ); res = newErrorRes( r, RE_POINTER_ERROR ); RETURN; } rulegen = isRuleGenSyntax( expr ); if ( rulegen ) { node = parseTermRuleGen( e, rulegen, pc ); } else { node = parseActionsRuleGen( e, rulegen, 1, pc ); } if ( node == NULL ) { addRErrorMsg( errmsg, RE_OUT_OF_MEMORY, "error: out of memory." ); res = newErrorRes( r, RE_OUT_OF_MEMORY ); RETURN; } else if ( getNodeType( node ) == N_ERROR ) { generateErrMsg( "error: syntax error", NODE_EXPR_POS( node ), node->base, buf ); addRErrorMsg( errmsg, RE_PARSER_ERROR, buf ); res = newErrorRes( r, RE_PARSER_ERROR ); RETURN; } else { Token *token; token = nextTokenRuleGen( e, pc, 0, 0 ); if ( strcmp( token->text, "|" ) == 0 ) { recoNode = parseActionsRuleGen( e, rulegen, 1, pc ); if ( recoNode == NULL ) { addRErrorMsg( errmsg, RE_OUT_OF_MEMORY, "error: out of memory." ); res = newErrorRes( r, RE_OUT_OF_MEMORY ); RETURN; } else if ( getNodeType( recoNode ) == N_ERROR ) { generateErrMsg( "error: syntax error", NODE_EXPR_POS( recoNode ), recoNode->base, buf ); addRErrorMsg( errmsg, RE_PARSER_ERROR, buf ); res = newErrorRes( r, RE_PARSER_ERROR ); RETURN; } token = nextTokenRuleGen( e, pc, 0, 0 ); } if ( token->type != TK_EOS ) { Label pos; getFPos( &pos, e, pc ); generateErrMsg( "error: unparsed suffix", pos.exprloc, pos.base, buf ); addRErrorMsg( errmsg, RE_UNPARSED_SUFFIX, buf ); res = newErrorRes( r, RE_UNPARSED_SUFFIX ); RETURN; } } res = computeNode( node, NULL, env, rei, reiSaveFlag, errmsg, r ); ret: deleteParserContext( pc ); deletePointer( e ); return res; }
ExprType *typeRuleSet( RuleSet *ruleset, rError_t *errmsg, Node **errnode, Region *r ) { Env *funcDesc = ruleEngineConfig.extFuncDescIndex; Hashtable *ruleType = newHashTable2( MAX_NUM_RULES * 2, r ); ExprType *res; int i; for ( i = 0; i < ruleset->len; i++ ) { RuleDesc *rule = ruleset->rules[i]; if ( rule->ruleType == RK_REL || rule->ruleType == RK_FUNC ) { List *typingConstraints = newList( r ); Hashtable *varTypes = newHashTable2( 100, r ); ExprType *restype = typeRule( rule, funcDesc, varTypes, typingConstraints, errmsg, errnode, r ); /*char buf[1024]; */ /*typingConstraintsToString(typingConstraints, buf, 1024); */ /*printf("rule %s, typing constraints: %s\n", ruleset->rules[i]->subtrees[0]->text, buf); */ if ( getNodeType( restype ) == T_ERROR ) { res = restype; char *errbuf = ( char * ) malloc( ERR_MSG_LEN * 1024 * sizeof( char ) ); errMsgToString( errmsg, errbuf, ERR_MSG_LEN * 1024 ); #ifdef DEBUG writeToTmp( "ruleerr.log", errbuf ); writeToTmp( "ruleerr.log", "\n" ); #endif rodsLog( LOG_ERROR, "%s", errbuf ); free( errbuf ); freeRErrorContent( errmsg ); RETURN; } /* check that function names are unique and do not conflict with system msis */ char errbuf[ERR_MSG_LEN]; char *ruleName = rule->node->subtrees[0]->text; FunctionDesc *fd; if ( ( fd = ( FunctionDesc * )lookupFromEnv( funcDesc, ruleName ) ) != NULL ) { if ( getNodeType( fd ) != N_FD_EXTERNAL && getNodeType( fd ) != N_FD_RULE_INDEX_LIST ) { char *err; switch ( getNodeType( fd ) ) { case N_FD_CONSTRUCTOR: err = "redefinition of constructor"; break; case N_FD_DECONSTRUCTOR: err = "redefinition of deconstructor"; break; case N_FD_FUNCTION: err = "redefinition of system microservice"; break; default: err = "redefinition of system symbol"; break; } generateErrMsg( err, NODE_EXPR_POS( rule->node ), rule->node->base, errbuf ); addRErrorMsg( errmsg, RE_FUNCTION_REDEFINITION, errbuf ); res = newErrorType( RE_FUNCTION_REDEFINITION, r ); *errnode = rule->node; RETURN; } } RuleDesc *rd = ( RuleDesc * )lookupFromHashTable( ruleType, ruleName ); if ( rd != NULL ) { if ( rule->ruleType == RK_FUNC || rd ->ruleType == RK_FUNC ) { generateErrMsg( "redefinition of function", NODE_EXPR_POS( rule->node ), rule->node->base, errbuf ); addRErrorMsg( errmsg, RE_FUNCTION_REDEFINITION, errbuf ); generateErrMsg( "previous definition", NODE_EXPR_POS( rd->node ), rd->node->base, errbuf ); addRErrorMsg( errmsg, RE_FUNCTION_REDEFINITION, errbuf ); res = newErrorType( RE_FUNCTION_REDEFINITION, r ); *errnode = rule->node; RETURN; } } else { insertIntoHashTable( ruleType, ruleName, rule ); } } } res = newSimpType( T_INT, r ); /* Although a rule set does not have type T_INT, return T_INT to indicate success. */ ret: return res; }
/* call an action with actionName and string parameters */ Res *computeExpressionWithParams( const char *actionName, const char **params, int paramsCount, ruleExecInfo_t *rei, int reiSaveFlag, msParamArray_t *msParamArray, rError_t *errmsg, Region *r ) { #ifdef DEBUG char buf[ERR_MSG_LEN > 1024 ? ERR_MSG_LEN : 1024]; snprintf( buf, 1024, "computExpressionWithParams: %s\n", actionName ); writeToTmp( "entry.log", buf ); #endif /* set clearDelayed to 0 so that nested calls to this function do not call clearDelay() */ int recclearDelayed = ruleEngineConfig.clearDelayed; ruleEngineConfig.clearDelayed = 0; if ( overflow( actionName, MAX_NAME_LEN ) ) { addRErrorMsg( errmsg, RE_BUFFER_OVERFLOW, "error: potential buffer overflow" ); return newErrorRes( r, RE_BUFFER_OVERFLOW ); } int k; for ( k = 0; k < paramsCount; k++ ) { if ( overflow( params[k], MAX_RULE_LEN ) ) { addRErrorMsg( errmsg, RE_BUFFER_OVERFLOW, "error: potential buffer overflow" ); return newErrorRes( r, RE_BUFFER_OVERFLOW ); } } Node** paramNodes = ( Node ** )region_alloc( r, sizeof( Node * ) * paramsCount ); int i; for ( i = 0; i < paramsCount; i++ ) { Node *node; /*Pointer *e = newPointer2(params[i]); if(e == NULL) { addRErrorMsg(errmsg, -1, "error: can not create Pointer."); return newErrorRes(r, -1); } node = parseTermRuleGen(e, 1, errmsg, r);*/ node = newNode( TK_STRING, params[i], 0, r ); /*if(node==NULL) { addRErrorMsg(errmsg, OUT_OF_MEMORY, "error: out of memory."); return newErrorRes(r, OUT_OF_MEMORY); } else if (getNodeType(node) == N_ERROR) { return newErrorRes(r, RES_ERR_CODE(node)); }*/ paramNodes[i] = node; } Node *node = createFunctionNode( actionName, paramNodes, paramsCount, NULL, r ); Env *global = newEnv( newHashTable2( 10, r ), NULL, NULL, r ); Env *env = newEnv( newHashTable2( 10, r ), global, NULL, r ); if ( msParamArray != NULL ) { convertMsParamArrayToEnv( msParamArray, global, r ); deleteFromHashTable(global->current, "ruleExecOut"); } Res *res = computeNode( node, NULL, env, rei, reiSaveFlag, errmsg, r ); /* deleteEnv(env, 3); */ if ( recclearDelayed ) { clearDelayed(); } ruleEngineConfig.clearDelayed = recclearDelayed; return res; }
/* parse and compute a rule */ int parseAndComputeRule( char *rule, Env *env, ruleExecInfo_t *rei, int reiSaveFlag, rError_t *errmsg, Region *r ) { if ( overflow( rule, MAX_RULE_LEN ) ) { addRErrorMsg( errmsg, RE_BUFFER_OVERFLOW, "error: potential buffer overflow" ); return RE_BUFFER_OVERFLOW; } Node *node; Pointer *e = newPointer2( rule ); if ( e == NULL ) { addRErrorMsg( errmsg, RE_POINTER_ERROR, "error: can not create a Pointer." ); return RE_POINTER_ERROR; } int tempLen = ruleEngineConfig.extRuleSet->len; int checkPoint = checkPointExtRuleSet( r ); int rescode; int errloc; /* add rules into ext rule set */ rescode = parseRuleSet( e, ruleEngineConfig.extRuleSet, ruleEngineConfig.extFuncDescIndex, &errloc, errmsg, r ); deletePointer( e ); if ( rescode != 0 ) { return RE_PARSER_ERROR; } RuleDesc *rd = NULL; Res *res = NULL; /* add rules into rule index */ int i; for ( i = tempLen; i < ruleEngineConfig.extRuleSet->len; i++ ) { if ( ruleEngineConfig.extRuleSet->rules[i]->ruleType == RK_FUNC || ruleEngineConfig.extRuleSet->rules[i]->ruleType == RK_REL ) { appendRuleIntoExtIndex( ruleEngineConfig.extRuleSet->rules[i], i, r ); } } for ( i = tempLen; i < ruleEngineConfig.extRuleSet->len; i++ ) { if ( ruleEngineConfig.extRuleSet->rules[i]->ruleType == RK_FUNC || ruleEngineConfig.extRuleSet->rules[i]->ruleType == RK_REL ) { Hashtable *varTypes = newHashTable2( 10, r ); List *typingConstraints = newList( r ); Node *errnode; ExprType *type = typeRule( ruleEngineConfig.extRuleSet->rules[i], ruleEngineConfig.extFuncDescIndex, varTypes, typingConstraints, errmsg, &errnode, r ); if ( getNodeType( type ) == T_ERROR ) { /* rescode = TYPE_ERROR; # TGR, since renamed to RE_TYPE_ERROR */ rescode = RE_TYPE_ERROR; RETURN; } } } /* exec the first rule */ rd = ruleEngineConfig.extRuleSet->rules[tempLen]; node = rd->node; res = execRuleNodeRes( node, NULL, 0, GlobalAllRuleExecFlag, env, rei, reiSaveFlag, errmsg, r ); rescode = getNodeType( res ) == N_ERROR ? RES_ERR_CODE( res ) : 0; ret: /* remove rules from ext rule set */ popExtRuleSet( checkPoint ); return rescode; }
int rsCollCreate( rsComm_t *rsComm, collInp_t *collCreateInp ) { int status; rodsServerHost_t *rodsServerHost = NULL; ruleExecInfo_t rei; collInfo_t collInfo; specCollCache_t *specCollCache = NULL; dataObjInfo_t *dataObjInfo = NULL; irods::error ret = validate_logical_path( collCreateInp->collName ); if ( !ret.ok() ) { if ( rsComm->rError.len < MAX_ERROR_MESSAGES ) { char error_msg[ERR_MSG_LEN]; snprintf(error_msg, ERR_MSG_LEN, "%s", ret.user_result().c_str()); addRErrorMsg( &rsComm->rError, ret.code(), error_msg ); } irods::log( ret ); return SYS_INVALID_INPUT_PARAM; } // Issue 3913: retain status in case string too long status = resolveLinkedPath( rsComm, collCreateInp->collName, &specCollCache, &collCreateInp->condInput ); // Issue 3913: retain status in case string too long if (status == USER_STRLEN_TOOLONG) { return USER_STRLEN_TOOLONG; } status = getAndConnRcatHost( rsComm, MASTER_RCAT, ( const char* )collCreateInp->collName, &rodsServerHost ); if ( status < 0 || rodsServerHost == NULL ) { // JMC cppcheck return status; } if ( rodsServerHost->localFlag == LOCAL_HOST ) { initReiWithCollInp( &rei, rsComm, collCreateInp, &collInfo ); status = applyRule( "acPreprocForCollCreate", NULL, &rei, NO_SAVE_REI ); if ( status < 0 ) { if ( rei.status < 0 ) { status = rei.status; } rodsLog( LOG_ERROR, "rsCollCreate:acPreprocForCollCreate error for %s,stat=%d", collCreateInp->collName, status ); return status; } if ( getValByKey( &collCreateInp->condInput, RECURSIVE_OPR__KW ) != NULL ) { status = rsMkCollR( rsComm, "/", collCreateInp->collName ); return status; } std::string svc_role; irods::error ret = get_catalog_service_role(svc_role); if(!ret.ok()) { irods::log(PASS(ret)); return ret.code(); } if( irods::CFG_SERVICE_ROLE_PROVIDER == svc_role ) { /* for STRUCT_FILE_COLL to make a directory in the structFile, the * COLLECTION_TYPE_KW must be set */ status = resolvePathInSpecColl( rsComm, collCreateInp->collName, WRITE_COLL_PERM, 0, &dataObjInfo ); if ( status >= 0 ) { freeDataObjInfo( dataObjInfo ); if ( status == COLL_OBJ_T ) { return 0; } else if ( status == DATA_OBJ_T ) { return USER_INPUT_PATH_ERR; } } else if ( status == SYS_SPEC_COLL_OBJ_NOT_EXIST ) { /* for STRUCT_FILE_COLL to make a directory in the structFile, the * COLLECTION_TYPE_KW must be set */ if ( dataObjInfo != NULL && dataObjInfo->specColl != NULL && dataObjInfo->specColl->collClass == LINKED_COLL ) { /* should not be here because if has been translated */ return SYS_COLL_LINK_PATH_ERR; } else { status = l3Mkdir( rsComm, dataObjInfo ); } freeDataObjInfo( dataObjInfo ); return status; } else { if ( isColl( rsComm, collCreateInp->collName, NULL ) >= 0 ) { return CATALOG_ALREADY_HAS_ITEM_BY_THAT_NAME; } status = _rsRegColl( rsComm, collCreateInp ); } rei.status = status; if ( status >= 0 ) { rei.status = applyRule( "acPostProcForCollCreate", NULL, &rei, NO_SAVE_REI ); if ( rei.status < 0 ) { rodsLog( LOG_ERROR, "rsCollCreate:acPostProcForCollCreate error for %s,stat=%d", collCreateInp->collName, status ); } } } else if( irods::CFG_SERVICE_ROLE_CONSUMER == svc_role ) { status = SYS_NO_RCAT_SERVER_ERR; } else { rodsLog( LOG_ERROR, "role not supported [%s]", svc_role.c_str() ); status = SYS_SERVICE_ROLE_NOT_SUPPORTED; } } else { status = rcCollCreate( rodsServerHost->conn, collCreateInp ); } return status; }
irods::error test_source_replica_for_write_permissions( rsComm_t* _comm, dataObjInfo_t* _data_obj_info ) { if( !_comm || !_data_obj_info ) { return ERROR( SYS_INTERNAL_NULL_INPUT_ERR, "null _data_obj_info or _comm" ); } std::string location; irods::error ret = irods::get_loc_for_hier_string( _data_obj_info->rescHier, location ); if ( !ret.ok() ) { return PASS( ret ); } // test the source hier to determine if we have write access to the data // stored. if not then we cannot unlink that replica and should throw an // error. fileOpenInp_t open_inp; memset( &open_inp, 0, sizeof( open_inp ) ); open_inp.mode = getDefFileMode(); open_inp.flags = O_WRONLY; rstrcpy( open_inp.resc_name_, _data_obj_info->rescName, MAX_NAME_LEN ); rstrcpy( open_inp.resc_hier_, _data_obj_info->rescHier, MAX_NAME_LEN ); rstrcpy( open_inp.objPath, _data_obj_info->objPath, MAX_NAME_LEN ); rstrcpy( open_inp.addr.hostAddr, location.c_str(), NAME_LEN ); rstrcpy( open_inp.fileName, _data_obj_info->filePath, MAX_NAME_LEN ); rstrcpy( open_inp.in_pdmo, _data_obj_info->in_pdmo, MAX_NAME_LEN ); // kv passthru copyKeyVal( &_data_obj_info->condInput, &open_inp.condInput ); int l3_idx = rsFileOpen( _comm, &open_inp ); clearKeyVal( &open_inp.condInput ); if( l3_idx < 0 ) { std::string msg = "unable to open "; msg += _data_obj_info->objPath; msg += " for unlink"; addRErrorMsg( &_comm->rError, SYS_USER_NO_PERMISSION, msg.c_str() ); return ERROR( SYS_USER_NO_PERMISSION, msg ); } fileCloseInp_t close_inp; memset( &close_inp, 0, sizeof( close_inp ) ); close_inp.fileInx = l3_idx; int status = rsFileClose( _comm, &close_inp ); if( status < 0 ) { std::string msg = "failed to close "; msg += _data_obj_info->objPath; return ERROR( status, msg ); } return SUCCESS(); } // test_source_replica_for_write_permissions