void ScopeNewScalar(EvalContext *ctx, VarRef lval, const char *rval, DataType dt) { CfDebug("NewScalar(%s,%s,%s)\n", lval.scope, lval.lval, rval); assert(!ScopeIsReserved(lval.scope)); if (ScopeIsReserved(lval.scope)) { ScopeNewSpecialScalar(ctx, lval.scope, lval.lval, rval, dt); } Rval rvald; if (EvalContextVariableGet(ctx, lval, &rvald, NULL)) { ScopeDeleteScalar(lval); } /* * We know AddVariableHash does not change passed Rval structure or its * contents, but we have no easy way to express it in C type system, hence cast. */ EvalContextVariablePut(ctx, lval, (Rval) {(char *) rval, RVAL_TYPE_SCALAR }, dt); }
void VerifyServices(EvalContext *ctx, Attributes a, Promise *pp, const ReportContext *report_context) { CfLock thislock; // allow to start Cfengine windows executor without license #ifdef __MINGW32__ if ((LICENSES == 0) && (strcmp(WINSERVICE_NAME, pp->promiser) != 0)) { return; } #endif thislock = AcquireLock(pp->promiser, VUQNAME, CFSTARTTIME, a, pp, false); if (thislock.lock == NULL) { return; } ScopeNewScalar("this", "promiser", pp->promiser, DATA_TYPE_STRING); PromiseBanner(ctx, pp); if (strcmp(a.service.service_type, "windows") == 0) { VerifyWindowsService(ctx, a, pp); } else { DoVerifyServices(ctx, a, pp, report_context); } ScopeDeleteScalar("this", "promiser"); YieldCurrentLock(thislock); }
int VerifyMethod(EvalContext *ctx, char *attrname, Attributes a, Promise *pp) { Bundle *bp; void *vp; FnCall *fp; char method_name[CF_EXPANDSIZE], qualified_method[CF_BUFSIZE], *method_deref; Rlist *params = NULL; int retval = false; CfLock thislock; char lockname[CF_BUFSIZE]; if (a.havebundle) { if ((vp = ConstraintGetRvalValue(ctx, attrname, pp, RVAL_TYPE_FNCALL))) { fp = (FnCall *) vp; ExpandScalar(ctx, PromiseGetBundle(pp)->name, fp->name, method_name); params = fp->args; } else if ((vp = ConstraintGetRvalValue(ctx, attrname, pp, RVAL_TYPE_SCALAR))) { ExpandScalar(ctx, PromiseGetBundle(pp)->name, (char *) vp, method_name); params = NULL; } else { return false; } } GetLockName(lockname, "method", pp->promiser, params); thislock = AcquireLock(ctx, lockname, VUQNAME, CFSTARTTIME, a.transaction, pp, false); if (thislock.lock == NULL) { return false; } PromiseBanner(pp); if (strncmp(method_name,"default:",strlen("default:")) == 0) // CF_NS == ':' { method_deref = strchr(method_name, CF_NS) + 1; } else if ((strchr(method_name, CF_NS) == NULL) && (strcmp(PromiseGetNamespace(pp), "default") != 0)) { snprintf(qualified_method, CF_BUFSIZE, "%s%c%s", PromiseGetNamespace(pp), CF_NS, method_name); method_deref = qualified_method; } else { method_deref = method_name; } bp = PolicyGetBundle(PolicyFromPromise(pp), NULL, "agent", method_deref); if (!bp) { bp = PolicyGetBundle(PolicyFromPromise(pp), NULL, "common", method_deref); } if (bp) { BannerSubBundle(bp, params); EvalContextStackPushBundleFrame(ctx, bp, a.inherit); ScopeClear(bp->name); BundleHashVariables(ctx, bp); ScopeAugment(ctx, bp, pp, params); retval = ScheduleAgentOperations(ctx, bp); GetReturnValue(ctx, bp->name, pp); EvalContextStackPopFrame(ctx); switch (retval) { case PROMISE_RESULT_FAIL: cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_FAIL, pp, a, "Method failed in some repairs or aborted"); break; case PROMISE_RESULT_CHANGE: cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, pp, a, "Method invoked repairs"); break; default: cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Method verified"); break; } for (const Rlist *rp = bp->args; rp; rp = rp->next) { const char *lval = rp->item; ScopeDeleteScalar((VarRef) { NULL, bp->name, lval }); } } else { if (IsCf3VarString(method_name)) { Log(LOG_LEVEL_ERR, "A variable seems to have been used for the name of the method. In this case, the promiser also needs to contain the unique name of the method"); } if (bp && (bp->name)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Method '%s' was used but was not defined", bp->name); } else { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "A method attempted to use a bundle '%s' that was apparently not defined", method_name); } } YieldCurrentLock(thislock); return retval; }