static void EvaluateBundle(EvalContext *ctx, const Bundle *bp, const char * const *seq) { EvalContextStackPushBundleFrame(ctx, bp, NULL, false); for (int type = 0; seq[type] != NULL; type++) { const PromiseType *sp = BundleGetPromiseType((Bundle *)bp, seq[type]); /* Some promise types might not be there. */ if (!sp || SeqLength(sp->promises) == 0) { Log(LOG_LEVEL_DEBUG, "No promise type %s in bundle %s", seq[type], bp->name); continue; } EvalContextStackPushPromiseTypeFrame(ctx, sp); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, KeepServerPromise, NULL); } EvalContextStackPopFrame(ctx); } /* Check if we are having some other promise types which we * should evaluate. THIS IS ONLY FOR BACKWARD COMPATIBILITY! */ for (size_t j = 0; j < SeqLength(bp->promise_types); j++) { PromiseType *sp = SeqAt(bp->promise_types, j); /* Skipping evaluation of promise as this was evaluated in * loop above. */ if (!IsPromiseTypeNotInTypeSequence(sp->name, seq)) { Log(LOG_LEVEL_DEBUG, "Skipping subsequent evaluation of " "promise type %s in bundle %s", sp->name, bp->name); continue; } Log(LOG_LEVEL_WARNING, "Trying to evaluate unsupported/obsolete " "promise type %s in %s bundle %s", sp->name, bp->type, bp->name); EvalContextStackPushPromiseTypeFrame(ctx, sp); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, KeepServerPromise, NULL); } EvalContextStackPopFrame(ctx); } EvalContextStackPopFrame(ctx); }
static void test_expand_promise_slist(void **state) { actuator_state = 0; EvalContext *ctx = *state; { VarRef *lval = VarRefParse("default:bundle.foo"); Rlist *list = NULL; RlistAppendScalar(&list, "a"); RlistAppendScalar(&list, "b"); EvalContextVariablePut(ctx, lval, list, CF_DATA_TYPE_STRING_LIST, NULL); RlistDestroy(list); VarRefDestroy(lval); } Policy *policy = PolicyNew(); Bundle *bundle = PolicyAppendBundle(policy, NamespaceDefault(), "bundle", "agent", NULL, NULL); PromiseType *promise_type = BundleAppendPromiseType(bundle, "dummy"); Promise *promise = PromiseTypeAppendPromise(promise_type, "$(foo)", (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, "any", NULL); EvalContextStackPushBundleFrame(ctx, bundle, NULL, false); EvalContextStackPushPromiseTypeFrame(ctx, promise_type); ExpandPromise(ctx, promise, actuator_expand_promise_slist, NULL); EvalContextStackPopFrame(ctx); EvalContextStackPopFrame(ctx); assert_int_equal(2, actuator_state); PolicyDestroy(policy); }
static void ResolveCommonClassPromises(EvalContext *ctx, PromiseType *pt) { assert(strcmp("classes", pt->name) == 0); assert(strcmp(pt->parent_bundle->type, "common") == 0); for (size_t i = 0; i < SeqLength(pt->promises); i++) { Promise *pp = SeqAt(pt->promises, i); char *sp = NULL; if (VarClassExcluded(ctx, pp, &sp)) { if (LEGACY_OUTPUT) { Log(LOG_LEVEL_VERBOSE, "\n"); Log(LOG_LEVEL_VERBOSE, ". . . . . . . . . . . . . . . . . . . . . . . . . . . . "); Log(LOG_LEVEL_VERBOSE, "Skipping whole next promise (%s), as var-context %s is not relevant", pp->promiser, sp); Log(LOG_LEVEL_VERBOSE, ". . . . . . . . . . . . . . . . . . . . . . . . . . . . "); } else { Log(LOG_LEVEL_VERBOSE, "Skipping next promise '%s', as var-context '%s' is not relevant", pp->promiser, sp); } continue; } ExpandPromise(ctx, pp, VerifyClassPromise, NULL); } }
static void test_expand_promise_array_with_scalar_arg(void **state) { EvalContext *ctx = *state; { VarRef *lval = VarRefParse("default:bundle.foo[one]"); EvalContextVariablePut(ctx, lval, "first", CF_DATA_TYPE_STRING, NULL); VarRefDestroy(lval); } { VarRef *lval = VarRefParse("default:bundle.bar"); EvalContextVariablePut(ctx, lval, "one", CF_DATA_TYPE_STRING, NULL); VarRefDestroy(lval); } Policy *policy = PolicyNew(); Bundle *bundle = PolicyAppendBundle(policy, NamespaceDefault(), "bundle", "agent", NULL, NULL); PromiseType *promise_type = BundleAppendPromiseType(bundle, "dummy"); Promise *promise = PromiseTypeAppendPromise(promise_type, "$(foo[$(bar)])", (Rval) { NULL, RVAL_TYPE_NOPROMISEE }, "any", NULL); EvalContextStackPushBundleFrame(ctx, bundle, NULL, false); EvalContextStackPushPromiseTypeFrame(ctx, promise_type); ExpandPromise(ctx, promise, actuator_expand_promise_array_with_scalar_arg, NULL); EvalContextStackPopFrame(ctx); EvalContextStackPopFrame(ctx); PolicyDestroy(policy); }
int ScheduleAgentOperations(struct Bundle *bp) { struct SubType *sp; struct Promise *pp; enum typesequence type; int pass; if (PROCESSREFRESH == NULL || (PROCESSREFRESH && IsRegexItemIn(PROCESSREFRESH,bp->name))) { DeleteItemList(PROCESSTABLE); PROCESSTABLE = NULL; } for (pass = 1; pass < CF_DONEPASSES; pass++) { for (type = 0; TYPESEQUENCE[type] != NULL; type++) { ClassBanner(type); if ((sp = GetSubTypeForBundle(TYPESEQUENCE[type],bp)) == NULL) { continue; } BannerSubType(bp->name,sp->name,pass); SetScope(bp->name); if (!NewTypeContext(type)) { continue; } for (pp = sp->promiselist; pp != NULL; pp=pp->next) { SaveClassEnvironment(); ExpandPromise(cf_agent,bp->name,pp,KeepAgentPromise); if (Abort()) { NoteClassUsage(VADDCLASSES); DeleteTypeContext(type); return false; } } DeleteTypeContext(type); } } NoteClassUsage(VADDCLASSES); return true; }
static void CheckCommonClassPromises(struct Promise *classlist) { struct Promise *pp; CfOut(cf_verbose,""," -> Checking common class promises...\n"); for (pp = classlist; pp != NULL; pp=pp->next) { ExpandPromise(cf_agent,THIS_BUNDLE,pp,KeepClassContextPromise); } }
void BundleResolve(EvalContext *ctx, const Bundle *bundle) { Log(LOG_LEVEL_DEBUG, "Resolving variables in bundle '%s' '%s'", bundle->type, bundle->name); if (strcmp(bundle->type, "common") == 0) { for (size_t j = 0; j < SeqLength(bundle->promise_types); j++) { PromiseType *pt = SeqAt(bundle->promise_types, j); if (strcmp(pt->name, "classes") == 0) { EvalContextStackPushPromiseTypeFrame(ctx, pt); for (size_t i = 0; i < SeqLength(pt->promises); i++) { Promise *pp = SeqAt(pt->promises, i); ExpandPromise(ctx, pp, VerifyClassPromise, NULL); } EvalContextStackPopFrame(ctx); } } } for (size_t j = 0; j < SeqLength(bundle->promise_types); j++) { PromiseType *pt = SeqAt(bundle->promise_types, j); if (strcmp(pt->name, "vars") == 0) { EvalContextStackPushPromiseTypeFrame(ctx, pt); for (size_t i = 0; i < SeqLength(pt->promises); i++) { Promise *pp = SeqAt(pt->promises, i); ExpandPromise(ctx, pp, (PromiseActuator*)VerifyVarPromise, NULL); } EvalContextStackPopFrame(ctx); } } }
void BundleResolvePromiseType(EvalContext *ctx, const Bundle *bundle, const char *type, PromiseActuator *actuator) { for (size_t j = 0; j < SeqLength(bundle->promise_types); j++) { PromiseType *pt = SeqAt(bundle->promise_types, j); if (strcmp(pt->name, type) == 0) { EvalContextStackPushPromiseTypeFrame(ctx, pt); for (size_t i = 0; i < SeqLength(pt->promises); i++) { Promise *pp = SeqAt(pt->promises, i); ExpandPromise(ctx, pp, actuator, NULL); } EvalContextStackPopFrame(ctx); } } }
static void KeepPromiseBundles(EvalContext *ctx, const Policy *policy) { /* Dial up the generic promise expansion with a callback */ CleanReportBookFilterSet(); for (size_t i = 0; i < SeqLength(policy->bundles); i++) { Bundle *bp = SeqAt(policy->bundles, i); if ((strcmp(bp->type, CF_AGENTTYPES[AGENT_TYPE_SERVER]) == 0) || (strcmp(bp->type, CF_AGENTTYPES[AGENT_TYPE_COMMON]) == 0)) { if (RlistLen(bp->args) > 0) { Log(LOG_LEVEL_WARNING, "Cannot implicitly evaluate bundle '%s %s', as this bundle takes arguments.", bp->type, bp->name); continue; } BannerBundle(bp, NULL); EvalContextStackPushBundleFrame(ctx, bp, NULL, false); for (size_t j = 0; j < SeqLength(bp->promise_types); j++) { PromiseType *sp = SeqAt(bp->promise_types, j); if ((strcmp(sp->name, "access") != 0) && (strcmp(sp->name, "roles") != 0)) { continue; } BannerPromiseType(bp->name, sp->name, 0); EvalContextStackPushPromiseTypeFrame(ctx, sp); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, KeepServerPromise, NULL); } EvalContextStackPopFrame(ctx); } EvalContextStackPopFrame(ctx); } } }
static void KeepPromiseBundles(EvalContext *ctx, Policy *policy, const ReportContext *report_context) { /* Dial up the generic promise expansion with a callback */ for (size_t i = 0; i < SeqLength(policy->bundles); i++) { Bundle *bp = SeqAt(policy->bundles, i); if ((strcmp(bp->type, CF_AGENTTYPES[AGENT_TYPE_SERVER]) == 0) || (strcmp(bp->type, CF_AGENTTYPES[AGENT_TYPE_COMMON]) == 0)) { if (RlistLen(bp->args) > 0) { CfOut(OUTPUT_LEVEL_ERROR, "", "Cannot implicitly evaluate bundle %s %s, as this bundle takes arguments.", bp->type, bp->name); continue; } BannerBundle(bp, NULL); for (size_t j = 0; j < SeqLength(bp->promise_types); j++) { PromiseType *sp = SeqAt(bp->promise_types, j); if ((strcmp(sp->name, "access") != 0) && (strcmp(sp->name, "roles") != 0)) { continue; } BannerPromiseType(bp->name, sp->name, 0); EvalContextStackPushBundleFrame(ctx, bp, false); ScopeAugment(ctx, bp, NULL); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, KeepServerPromise, report_context); } EvalContextStackPopFrame(ctx); } } } }
static void VerifyPromises(EvalContext *ctx, Policy *policy, GenericAgentConfig *config) { /* Now look once through ALL the bundles themselves */ for (size_t i = 0; i < SeqLength(policy->bundles); i++) { Bundle *bp = SeqAt(policy->bundles, i); EvalContextStackPushBundleFrame(ctx, bp, NULL, false); for (size_t j = 0; j < SeqLength(bp->promise_types); j++) { PromiseType *sp = SeqAt(bp->promise_types, j); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, CommonEvalPromise, NULL); } } EvalContextStackPopFrame(ctx); } PolicyResolve(ctx, policy, config); // TODO: need to move this inside PolicyCheckRunnable eventually. if (!config->bundlesequence && config->check_runnable) { // only verify policy-defined bundlesequence for cf-agent, cf-promises if ((config->agent_type == AGENT_TYPE_AGENT) || (config->agent_type == AGENT_TYPE_COMMON)) { if (!VerifyBundleSequence(ctx, policy, config)) { FatalError(ctx, "Errors in promise bundles"); } } } }
static void KeepPromiseBundles() { Bundle *bp; SubType *sp; Promise *pp; char *scope; /* Dial up the generic promise expansion with a callback */ for (bp = BUNDLES; bp != NULL; bp = bp->next) /* get schedule */ { scope = bp->name; SetNewScope(bp->name); if ((strcmp(bp->type, CF_AGENTTYPES[cf_server]) == 0) || (strcmp(bp->type, CF_AGENTTYPES[cf_common]) == 0)) { DeletePrivateClassContext(); // Each time we change bundle BannerBundle(bp, NULL); scope = bp->name; for (sp = bp->subtypes; sp != NULL; sp = sp->next) /* get schedule */ { if (strcmp(sp->name, "access") != 0 && strcmp(sp->name, "roles") != 0) { continue; } BannerSubType(scope, sp->name, 0); SetScope(scope); AugmentScope(scope, NULL, NULL); for (pp = sp->promiselist; pp != NULL; pp = pp->next) { ExpandPromise(cf_server, scope, pp, KeepServerPromise); } } } } }
static void KeepPromiseBundles(EvalContext *ctx, const Policy *policy) { /* Dial up the generic promise expansion with a callback */ CleanReportBookFilterSet(); for (size_t i = 0; i < SeqLength(policy->bundles); i++) { Bundle *bp = SeqAt(policy->bundles, i); if ((strcmp(bp->type, CF_AGENTTYPES[AGENT_TYPE_SERVER]) == 0) || (strcmp(bp->type, CF_AGENTTYPES[AGENT_TYPE_COMMON]) == 0)) { if (RlistLen(bp->args) > 0) { Log(LOG_LEVEL_WARNING, "Cannot implicitly evaluate bundle '%s %s', as this bundle takes arguments.", bp->type, bp->name); continue; } EvalContextStackPushBundleFrame(ctx, bp, NULL, false); for (int type = 0; SERVER_TYPESEQUENCE[type] != NULL; type++) { const PromiseType *sp = BundleGetPromiseType((Bundle *)bp, SERVER_TYPESEQUENCE[type]); /* Some promise types might not be there. */ if (!sp || SeqLength(sp->promises) == 0) { Log(LOG_LEVEL_DEBUG, "No promise type %s in bundle %s", SERVER_TYPESEQUENCE[type], bp->name); continue; } EvalContextStackPushPromiseTypeFrame(ctx, sp); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, KeepServerPromise, NULL); } EvalContextStackPopFrame(ctx); } /* Check if we are having some other promise types which we * should evaluate. THIS IS ONLY FOR BACKWARD COMPATIBILITY! */ for (size_t j = 0; j < SeqLength(bp->promise_types); j++) { PromiseType *sp = SeqAt(bp->promise_types, j); /* Skipping evaluation of promise as this was evaluated in * loop above. */ if (!IsPromiseTypeNotInServerTypeSequence(sp->name)) { Log(LOG_LEVEL_DEBUG, "Skipping subsequent evaluation of " "promise type %s in bundle %s", sp->name, bp->name); continue; } Log(LOG_LEVEL_WARNING, "Trying to evaluate unsupported/obsolete " "promise type %s in bundle %s", sp->name, bp->name); EvalContextStackPushPromiseTypeFrame(ctx, sp); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, KeepServerPromise, NULL); } EvalContextStackPopFrame(ctx); } EvalContextStackPopFrame(ctx); } } }
static void VerifyPromises(enum cfagenttype agent) { struct Bundle *bp; struct SubType *sp; struct Promise *pp; struct Body *bdp; struct Rlist *rp; struct FnCall *fp; char *scope; if (REQUIRE_COMMENTS == CF_UNDEFINED) { for (bdp = BODIES; bdp != NULL; bdp = bdp->next) /* get schedule */ { if ((strcmp(bdp->name,"control") == 0) && (strcmp(bdp->type,"common") == 0)) { REQUIRE_COMMENTS = GetRawBooleanConstraint("require_comments",bdp->conlist); break; } } } for (rp = BODYPARTS; rp != NULL; rp=rp->next) { switch (rp->type) { case CF_SCALAR: if (!IsBody(BODIES,(char *)rp->item)) { CfOut(cf_error,"","Undeclared promise body \"%s()\" was referenced in a promise\n",(char *)rp->item); ERRORCOUNT++; } break; case CF_FNCALL: fp = (struct FnCall *)rp->item; if (!IsBody(BODIES,fp->name)) { CfOut(cf_error,"","Undeclared promise body \"%s()\" was referenced in a promise\n",fp->name); ERRORCOUNT++; } break; } } /* Check for undefined subbundles */ for (rp = SUBBUNDLES; rp != NULL; rp=rp->next) { switch (rp->type) { case CF_SCALAR: if (!IGNORE_MISSING_BUNDLES && !IsCf3VarString(rp->item) && !IsBundle(BUNDLES,(char *)rp->item)) { CfOut(cf_error,"","Undeclared promise bundle \"%s()\" was referenced in a promise\n",(char *)rp->item); ERRORCOUNT++; } break; case CF_FNCALL: fp = (struct FnCall *)rp->item; if (!IGNORE_MISSING_BUNDLES && !IsCf3VarString(fp->name) && !IsBundle(BUNDLES,fp->name)) { CfOut(cf_error,"","Undeclared promise bundle \"%s()\" was referenced in a promise\n",fp->name); ERRORCOUNT++; } break; } } /* Now look once through ALL the bundles themselves */ for (bp = BUNDLES; bp != NULL; bp = bp->next) /* get schedule */ { scope = bp->name; THIS_BUNDLE = bp->name; for (sp = bp->subtypes; sp != NULL; sp = sp->next) /* get schedule */ { if (strcmp(sp->name,"classes") == 0) { /* these should not be evaluated here */ if (agent != cf_common) { continue; } } for (pp = sp->promiselist; pp != NULL; pp=pp->next) { ExpandPromise(agent,scope,pp,NULL); } } } HashVariables(NULL); HashControls(); /* Now look once through the sequences bundles themselves */ if (VerifyBundleSequence(agent) == false) { FatalError("Errors in promise bundles"); } }
int ScheduleAgentOperations(Bundle *bp, const ReportContext *report_context) // NB - this function can be called recursively through "methods" { SubType *sp; enum typesequence type; int pass; int save_pr_kept = PR_KEPT; int save_pr_repaired = PR_REPAIRED; int save_pr_notkept = PR_NOTKEPT; if (PROCESSREFRESH == NULL || (PROCESSREFRESH && IsRegexItemIn(PROCESSREFRESH, bp->name))) { DeleteItemList(PROCESSTABLE); PROCESSTABLE = NULL; } for (pass = 1; pass < CF_DONEPASSES; pass++) { for (type = 0; AGENT_TYPESEQUENCE[type] != NULL; type++) { ClassBanner(type); if ((sp = BundleGetSubType(bp, AGENT_TYPESEQUENCE[type])) == NULL) { continue; } BannerSubType(bp->name, sp->name, pass); SetScope(bp->name); if (!NewTypeContext(type)) { continue; } for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); if (ALLCLASSESREPORT) { SaveClassEnvironment(); } if (pass == 1) // Count the number of promises modelled for efficiency { CF_TOPICS++; } ExpandPromise(AGENT_TYPE_AGENT, bp->name, pp, KeepAgentPromise, report_context); if (Abort()) { NoteClassUsage(VADDCLASSES, false); DeleteTypeContext(bp->parent_policy, type, report_context); NoteBundleCompliance(bp, save_pr_kept, save_pr_repaired, save_pr_notkept); return false; } } DeleteTypeContext(bp->parent_policy, type, report_context); } } NoteClassUsage(VADDCLASSES, false); return NoteBundleCompliance(bp, save_pr_kept, save_pr_repaired, save_pr_notkept); }
Policy *LoadPolicy(EvalContext *ctx, GenericAgentConfig *config) { StringSet *parsed_files_and_checksums = StringSetNew(); StringSet *failed_files = StringSetNew(); Policy *policy = LoadPolicyFile(ctx, config, config->input_file, parsed_files_and_checksums, failed_files); if (StringSetSize(failed_files) > 0) { Log(LOG_LEVEL_ERR, "There are syntax errors in policy files"); exit(EXIT_FAILURE); } StringSetDestroy(parsed_files_and_checksums); StringSetDestroy(failed_files); { Seq *errors = SeqNew(100, PolicyErrorDestroy); if (PolicyCheckPartial(policy, errors)) { if (!config->bundlesequence && (PolicyIsRunnable(policy) || config->check_runnable)) { Log(LOG_LEVEL_VERBOSE, "Running full policy integrity checks"); PolicyCheckRunnable(ctx, policy, errors, config->ignore_missing_bundles); } } if (SeqLength(errors) > 0) { Writer *writer = FileWriter(stderr); for (size_t i = 0; i < errors->length; i++) { PolicyErrorWrite(writer, errors->data[i]); } WriterClose(writer); exit(EXIT_FAILURE); // TODO: do not exit } SeqDestroy(errors); } if (LogGetGlobalLevel() >= LOG_LEVEL_VERBOSE) { ShowContext(ctx); } if (policy) { for (size_t i = 0; i < SeqLength(policy->bundles); i++) { Bundle *bp = SeqAt(policy->bundles, i); EvalContextStackPushBundleFrame(ctx, bp, NULL, false); for (size_t j = 0; j < SeqLength(bp->promise_types); j++) { PromiseType *sp = SeqAt(bp->promise_types, j); EvalContextStackPushPromiseTypeFrame(ctx, sp); for (size_t ppi = 0; ppi < SeqLength(sp->promises); ppi++) { Promise *pp = SeqAt(sp->promises, ppi); ExpandPromise(ctx, pp, CommonEvalPromise, NULL); } EvalContextStackPopFrame(ctx); } EvalContextStackPopFrame(ctx); } PolicyResolve(ctx, policy, config); // TODO: need to move this inside PolicyCheckRunnable eventually. if (!config->bundlesequence && config->check_runnable) { // only verify policy-defined bundlesequence for cf-agent, cf-promises if ((config->agent_type == AGENT_TYPE_AGENT) || (config->agent_type == AGENT_TYPE_COMMON)) { if (!VerifyBundleSequence(ctx, policy, config)) { FatalError(ctx, "Errors in promise bundles: could not verify bundlesequence"); } } } } JsonElement *validated_doc = ReadReleaseIdFileFromInputs(); if (validated_doc) { const char *release_id = JsonObjectGetAsString(validated_doc, "releaseId"); if (release_id) { policy->release_id = xstrdup(release_id); } JsonDestroy(validated_doc); } return policy; }
static void KeepPromiseBundles() { Bundle *bp; SubType *sp; Promise *pp; Rlist *rp, *params; FnCall *fp; char *name; Rval retval; int ok = true; enum typesequence type; if (GetVariable("control_common", "bundlesequence", &retval) == cf_notype) { CfOut(cf_error, "", " !! No bundlesequence in the common control body"); exit(1); } for (rp = (Rlist *) retval.item; rp != NULL; rp = rp->next) { switch (rp->type) { case CF_SCALAR: name = (char *) rp->item; params = NULL; break; case CF_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 (!(GetBundle(name, "knowledge") || (GetBundle(name, "common")))) { CfOut(cf_error, "", " !! Bundle \"%s\" listed in the bundlesequence was not found\n", name); ok = false; } } if (!ok) { FatalError("Errors in knowledge bundles"); } /* If all is okay, go ahead and evaluate */ for (type = 0; TYPESEQUENCE[type] != NULL; type++) { for (rp = (Rlist *) retval.item; rp != NULL; rp = rp->next) { switch (rp->type) { case CF_FNCALL: fp = (FnCall *) rp->item; name = (char *) fp->name; params = (Rlist *) fp->args; break; default: name = (char *) rp->item; params = NULL; break; } if ((bp = GetBundle(name, "knowledge")) || (bp = GetBundle(name, "common"))) { BannerBundle(bp, params); AugmentScope(bp->name, bp->args, params); DeletePrivateClassContext(); // Each time we change bundle } if ((sp = GetSubTypeForBundle(TYPESEQUENCE[type], bp)) == NULL) { continue; } BannerSubType(bp->name, sp->name, 1); for (pp = sp->promiselist; pp != NULL; pp = pp->next) { ExpandPromise(cf_know, bp->name, pp, KeepKnowledgePromise); } } } }