void KeepPromiseBundles() { struct Bundle *bp; struct Rlist *rp,*params; struct FnCall *fp; char rettype,*name; void *retval; int ok = true; if (CBUNDLESEQUENCE) { CfOut(cf_inform,""," >> Using command line specified bundlesequence"); retval = CBUNDLESEQUENCE; rettype = CF_LIST; } else if (GetVariable("control_common","bundlesequence",&retval,&rettype) == cf_notype) { CfOut(cf_error,""," !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); CfOut(cf_error,""," !! No bundlesequence in the common control body"); CfOut(cf_error,""," !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); exit(1); } if (rettype != CF_LIST) { FatalError("Promised bundlesequence was not a list"); } for (rp = (struct Rlist *)retval; rp != NULL; rp=rp->next) { switch (rp->type) { case CF_SCALAR: name = (char *)rp->item; params = NULL; if (strcmp(name,CF_NULL_VALUE) == 0) { continue; } break; case CF_FNCALL: fp = (struct FnCall *)rp->item; name = (char *)fp->name; params = (struct Rlist *)fp->args; break; default: name = NULL; params = NULL; CfOut(cf_error,"","Illegal item found in bundlesequence: "); ShowRval(stdout,rp->item,rp->type); printf(" = %c\n",rp->type); ok = false; break; } if (!IGNORE_MISSING_BUNDLES) { if (!(GetBundle(name,"agent")||(GetBundle(name,"common")))) { CfOut(cf_error,"","Bundle \"%s\" listed in the bundlesequence was not found\n",name); ok = false; } } } if (!ok) { FatalError("Errors in agent bundles"); } if (VERBOSE || DEBUG) { printf("%s> -> Bundlesequence => ",VPREFIX); ShowRval(stdout,retval,rettype); printf("\n"); } /* If all is okay, go ahead and evaluate */ for (rp = (struct Rlist *)retval; rp != NULL; rp=rp->next) { switch (rp->type) { case CF_FNCALL: fp = (struct FnCall *)rp->item; name = (char *)fp->name; params = (struct Rlist *)fp->args; break; default: name = (char *)rp->item; params = NULL; break; } if ((bp = GetBundle(name,"agent")) || (bp = GetBundle(name,"common"))) { SetBundleOutputs(bp->name); AugmentScope(bp->name,bp->args,params); BannerBundle(bp,params); THIS_BUNDLE = bp->name; DeletePrivateClassContext(); // Each time we change bundle ScheduleAgentOperations(bp); ResetBundleOutputs(bp->name); } } }
static void KeepPromiseBundles(Policy *policy, GenericAgentConfig *config, const ReportContext *report_context) { Bundle *bp; Rlist *rp, *params; FnCall *fp; char *name; Rval retval; int ok = true; if (config->bundlesequence) { CfOut(cf_inform, "", " >> Using command line specified bundlesequence"); retval = (Rval) { config->bundlesequence, RVAL_TYPE_LIST }; } else if (GetVariable("control_common", "bundlesequence", &retval) == DATA_TYPE_NONE) { // TODO: somewhat frenzied way of telling user about an error CfOut(cf_error, "", " !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); CfOut(cf_error, "", " !! No bundlesequence in the common control body"); CfOut(cf_error, "", " !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); exit(1); } // TODO: should've been checked a long time ago, remove? if (retval.type != RVAL_TYPE_LIST) { FatalError("Promised bundlesequence was not a list"); } for (rp = (Rlist *) retval.item; rp != NULL; rp = rp->next) { switch (rp->type) { case RVAL_TYPE_SCALAR: name = (char *) rp->item; params = NULL; if (strcmp(name, CF_NULL_VALUE) == 0) { continue; } break; case RVAL_TYPE_FNCALL: fp = (FnCall *) rp->item; name = (char *) fp->name; params = (Rlist *) fp->args; break; default: name = NULL; params = NULL; CfOut(cf_error, "", "Illegal item found in bundlesequence: "); ShowRval(stdout, (Rval) {rp->item, rp->type}); printf(" = %c\n", rp->type); ok = false; break; } if (!config->ignore_missing_bundles) { if (!(PolicyGetBundle(policy, NULL, "agent", name) || (PolicyGetBundle(policy, NULL, "common", name)))) { CfOut(cf_error, "", "Bundle \"%s\" listed in the bundlesequence was not found\n", name); ok = false; } } } if (!ok) { FatalError("Errors in agent bundles"); } if (VERBOSE || DEBUG) { printf("%s> -> Bundlesequence => ", VPREFIX); ShowRval(stdout, retval); printf("\n"); } /* If all is okay, go ahead and evaluate */ for (rp = (Rlist *) retval.item; rp != NULL; rp = rp->next) { switch (rp->type) { case RVAL_TYPE_FNCALL: fp = (FnCall *) rp->item; name = (char *) fp->name; params = (Rlist *) fp->args; break; default: name = (char *) rp->item; params = NULL; break; } if ((bp = PolicyGetBundle(policy, NULL, "agent", name)) || (bp = PolicyGetBundle(policy, NULL, "common", name))) { char ns[CF_BUFSIZE]; snprintf(ns,CF_BUFSIZE,"%s_meta", name); NewScope(ns); SetBundleOutputs(bp->name); AugmentScope(bp->name, bp->ns, bp->args, params); BannerBundle(bp, params); THIS_BUNDLE = bp->name; DeletePrivateClassContext(); // Each time we change bundle ScheduleAgentOperations(bp, report_context); ResetBundleOutputs(bp->name); } } }
int VerifyMethod(EvalContext *ctx, char *attrname, Attributes a, Promise *pp, const ReportContext *report_context) { 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(PromiseGetBundle(pp)->name, fp->name, method_name); params = fp->args; } else if ((vp = ConstraintGetRvalValue(ctx, attrname, pp, RVAL_TYPE_SCALAR))) { ExpandScalar(PromiseGetBundle(pp)->name, (char *) vp, method_name); params = NULL; } else { return false; } } GetLockName(lockname, "method", pp->promiser, params); thislock = AcquireLock(lockname, VUQNAME, CFSTARTTIME, a, 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, report_context); char ns[CF_BUFSIZE]; snprintf(ns,CF_BUFSIZE,"%s_meta",method_name); SetBundleOutputs(bp->name); ScopeAugment(ctx, bp, params); retval = ScheduleAgentOperations(ctx, bp, report_context); GetReturnValue(ctx, bp->name, pp); ResetBundleOutputs(bp->name); EvalContextStackPopFrame(ctx); switch (retval) { case PROMISE_RESULT_FAIL: cfPS(ctx, OUTPUT_LEVEL_INFORM, PROMISE_RESULT_FAIL, "", pp, a, " !! Method failed in some repairs or aborted\n"); break; case PROMISE_RESULT_CHANGE: cfPS(ctx, OUTPUT_LEVEL_VERBOSE, PROMISE_RESULT_CHANGE, "", pp, a, " !! Method invoked repairs\n"); break; default: cfPS(ctx, OUTPUT_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, "", pp, a, " -> Method verified\n"); 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)) { CfOut(OUTPUT_LEVEL_ERROR, "", " !! 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, OUTPUT_LEVEL_ERROR, PROMISE_RESULT_FAIL, "", pp, a, " !! Method \"%s\" was used but was not defined!\n", bp->name); } else { cfPS(ctx, OUTPUT_LEVEL_ERROR, PROMISE_RESULT_FAIL, "", pp, a, " !! A method attempted to use a bundle \"%s\" that was apparently not defined!\n", method_name); } } YieldCurrentLock(thislock); return retval; }