static ExpressionValue EvalTokenAsClass(const char *classname, void *param) { const EvalContext *ctx = ((EvalTokenAsClassContext *)param)->ctx; const char *ns = ((EvalTokenAsClassContext *)param)->ns; char qualified_class[CF_MAXVARSIZE]; if (strcmp(classname, "any") == 0) { return true; } if (strchr(classname, ':')) { if (strncmp(classname, "default:", strlen("default:")) == 0) { snprintf(qualified_class, CF_MAXVARSIZE, "%s", classname + strlen("default:")); } else { snprintf(qualified_class, CF_MAXVARSIZE, "%s", classname); } } else if (ns != NULL && strcmp(ns, "default") != 0) { snprintf(qualified_class, CF_MAXVARSIZE, "%s:%s", ns, (char *)classname); } else { snprintf(qualified_class, CF_MAXVARSIZE, "%s", classname); } if (EvalContextHeapContainsNegated(ctx, qualified_class)) { return false; } if (EvalContextStackFrameContainsNegated(ctx, qualified_class)) { return false; } if (EvalContextHeapContainsHard(ctx, classname)) // Hard classes are always unqualified { return true; } if (EvalContextHeapContainsSoft(ctx, qualified_class)) { return true; } if (EvalContextStackFrameContainsSoft(ctx, qualified_class)) { return true; } return false; }
void EvalContextStackFrameAddSoft(EvalContext *ctx, const char *context) { assert(SeqLength(ctx->stack) > 0); StackFrameBundle frame; { StackFrame *last_frame = LastStackFrameBundle(ctx); if (!last_frame) { ProgrammingError("Attempted to add a soft class on the stack, but stack had no bundle frame"); } frame = last_frame->data.bundle; } char copy[CF_BUFSIZE]; if (strcmp(frame.owner->ns, "default") != 0) { snprintf(copy, CF_MAXVARSIZE, "%s:%s", frame.owner->ns, context); } else { strncpy(copy, context, CF_MAXVARSIZE); } if (Chop(copy, CF_EXPANDSIZE) == -1) { CfOut(OUTPUT_LEVEL_ERROR, "", "Chop was called on a string that seemed to have no terminator"); } if (strlen(copy) == 0) { return; } CfDebug("NewBundleClass(%s)\n", copy); if (IsRegexItemIn(ctx, ctx->heap_abort_current_bundle, copy)) { CfOut(OUTPUT_LEVEL_ERROR, "", "Bundle %s aborted on defined class \"%s\"\n", frame.owner->name, copy); ABORTBUNDLE = true; } if (IsRegexItemIn(ctx, ctx->heap_abort, copy)) { CfOut(OUTPUT_LEVEL_ERROR, "", "cf-agent aborted on defined class \"%s\" defined in bundle %s\n", copy, frame.owner->name); exit(1); } if (EvalContextHeapContainsSoft(ctx, copy)) { CfOut(OUTPUT_LEVEL_ERROR, "", "WARNING - private class \"%s\" in bundle \"%s\" shadows a global class - you should choose a different name to avoid conflicts", copy, frame.owner->name); } if (EvalContextStackFrameContainsSoft(ctx, copy)) { return; } StringSetAdd(frame.contexts, xstrdup(copy)); for (const Item *ip = ctx->heap_abort; ip != NULL; ip = ip->next) { if (IsDefinedClass(ctx, ip->name, frame.owner->ns)) { CfOut(OUTPUT_LEVEL_ERROR, "", "cf-agent aborted on defined class \"%s\" defined in bundle %s\n", copy, frame.owner->name); exit(1); } } if (!ABORTBUNDLE) { for (const Item *ip = ctx->heap_abort_current_bundle; ip != NULL; ip = ip->next) { if (IsDefinedClass(ctx, ip->name, frame.owner->ns)) { CfOut(OUTPUT_LEVEL_ERROR, "", " -> Setting abort for \"%s\" when setting \"%s\"", ip->name, context); ABORTBUNDLE = true; break; } } } }
void NewBundleClass(EvalContext *ctx, const char *context, const char *bundle, const char *ns) { char copy[CF_BUFSIZE]; if (ns && strcmp(ns, "default") != 0) { snprintf(copy, CF_MAXVARSIZE, "%s:%s", ns, context); } else { strncpy(copy, context, CF_MAXVARSIZE); } if (Chop(copy, CF_EXPANDSIZE) == -1) { CfOut(OUTPUT_LEVEL_ERROR, "", "Chop was called on a string that seemed to have no terminator"); } if (strlen(copy) == 0) { return; } CfDebug("NewBundleClass(%s)\n", copy); if (IsRegexItemIn(ctx, ctx->heap_abort_current_bundle, copy)) { CfOut(OUTPUT_LEVEL_ERROR, "", "Bundle %s aborted on defined class \"%s\"\n", bundle, copy); ABORTBUNDLE = true; } if (IsRegexItemIn(ctx, ctx->heap_abort, copy)) { CfOut(OUTPUT_LEVEL_ERROR, "", "cf-agent aborted on defined class \"%s\" defined in bundle %s\n", copy, bundle); exit(1); } if (EvalContextHeapContainsSoft(ctx, copy)) { CfOut(OUTPUT_LEVEL_ERROR, "", "WARNING - private class \"%s\" in bundle \"%s\" shadows a global class - you should choose a different name to avoid conflicts", copy, bundle); } if (EvalContextStackFrameContainsSoft(ctx, copy)) { return; } EvalContextStackFrameAddSoft(ctx, copy); for (const Item *ip = ctx->heap_abort; ip != NULL; ip = ip->next) { if (IsDefinedClass(ctx, ip->name, ns)) { CfOut(OUTPUT_LEVEL_ERROR, "", "cf-agent aborted on defined class \"%s\" defined in bundle %s\n", copy, bundle); exit(1); } } if (!ABORTBUNDLE) { for (const Item *ip = ctx->heap_abort_current_bundle; ip != NULL; ip = ip->next) { if (IsDefinedClass(ctx, ip->name, ns)) { CfOut(OUTPUT_LEVEL_ERROR, "", " -> Setting abort for \"%s\" when setting \"%s\"", ip->name, context); ABORTBUNDLE = true; break; } } } }