static void test_prepend_scalar(void **state) { Rlist *list = NULL; PrependRScalar(&list, "stuff", CF_SCALAR); PrependRScalar(&list, "more-stuff", CF_SCALAR); assert_string_equal(list->item, "more-stuff"); DeleteRlist(list); }
static void test_length(void **state) { Rlist *list = NULL; assert_int_equal(RlistLen(list), 0); PrependRScalar(&list, "stuff", CF_SCALAR); assert_int_equal(RlistLen(list), 1); PrependRScalar(&list, "more-stuff", CF_SCALAR); assert_int_equal(RlistLen(list), 2); DeleteRlist(list); }
static void test_copy(void **state) { Rlist *list = NULL, *copy = NULL; PrependRScalar(&list, "stuff", CF_SCALAR); PrependRScalar(&list, "more-stuff", CF_SCALAR); copy = CopyRlist(list); assert_string_equal(list->item, copy->item); assert_string_equal(list->next->item, copy->next->item); DeleteRlist(list); DeleteRlist(copy); }
static Rlist *GetSQLTables(CfdbConn *cfdb) { Rlist *list = NULL; char query[CF_MAXVARSIZE]; ListTables(cfdb->type, query); CfNewQueryDB(cfdb, query); if (cfdb->maxcolumns != 1) { CfOut(cf_error, "", "Could not make sense of the columns"); CfDeleteQuery(cfdb); return NULL; } while (CfFetchRow(cfdb)) { PrependRScalar(&list, CfFetchColumn(cfdb, 0), CF_SCALAR); } CfDeleteQuery(cfdb); return list; }
static Topic *AddTopic(Topic **list, char *name, char *context) { Topic *tp; if ((tp = TopicExists(name, context))) { CfOut(cf_verbose, "", " -> Topic %s already defined, ok\n", name); } else { tp = xmalloc(sizeof(Topic)); tp->topic_name = xstrdup(NormalizeTopic(name)); if (context && strlen(context) > 0) { tp->topic_context = xstrdup(NormalizeTopic(context)); } else { tp->topic_context = xstrdup("any"); } tp->id = GLOBAL_ID++; tp->associations = NULL; tp->next = *list; *list = tp; CF_TOPICS++; // This section must come last, as there is possible recursion and memory ref needs to be complete first if (strcmp(tp->topic_context, "any") != 0) { // Every topic in a special context is generalized by itself in context "any" char gen[CF_BUFSIZE]; Rlist *rlist = 0; snprintf(gen, CF_BUFSIZE - 1, "any::%s", tp->topic_name); PrependRScalar(&rlist, gen, CF_SCALAR); AddTopicAssociation(tp, &(tp->associations), KM_GENERALIZES_B, KM_GENERALIZES_F, rlist, true, tp->topic_context, tp->topic_name); DeleteRlist(rlist); } } return tp; }
void HashToList(Scope *sp, Rlist **list) { if (sp == NULL) { return; } HashIterator i = HashIteratorInit(sp->hashtable); CfAssoc *assoc; while ((assoc = HashIteratorNext(&i))) { PrependRScalar(list, assoc->lval, CF_SCALAR); } }
static void ThisAgentInit(void) { strcpy(WEBDRIVER, ""); strcpy(LICENSE_COMPANY, ""); strcpy(MANDIR, "."); SHOWREPORTS = false; if (InsertTopic("any", "any")) { Rlist *list = NULL; PrependRScalar(&list, "Description", CF_SCALAR); AddOccurrence(&OCCURRENCES, "The generic knowledge context - any time, any place, anywhere", list, cfk_literal, "any"); DeleteRlist(list); } }
GenericAgentConfig CheckOpts(int argc, char **argv) { extern char *optarg; int optindex = 0; int c; GenericAgentConfig config = GenericAgentDefaultConfig(cf_common); while ((c = getopt_long(argc, argv, "advnIf:D:N:VSrxMb:pg:h", OPTIONS, &optindex)) != EOF) { switch ((char) c) { case 'f': if (optarg && strlen(optarg) < 5) { FatalError(" -f used but argument \"%s\" incorrect", optarg); } SetInputFile(optarg); MINUSF = true; break; case 'd': NewClass("opt_debug"); DEBUG = true; break; case 'b': if (optarg) { config.bundlesequence = SplitStringAsRList(optarg, ','); CBUNDLESEQUENCE_STR = optarg; } break; case 'K': IGNORELOCK = true; break; case 'D': NewClassesFromString(optarg); break; case 'N': NegateClassesFromString(optarg); break; case 'I': INFORM = true; break; case 'v': VERBOSE = true; break; case 'n': DONTDO = true; IGNORELOCK = true; LOOKUP = true; NewClass("opt_dry_run"); break; case 'V': PrintVersionBanner("cf-promises"); exit(0); case 'h': Syntax("cf-promises - cfengine's promise analyzer", OPTIONS, HINTS, ID); exit(0); case 'M': ManPage("cf-promises - cfengine's promise analyzer", OPTIONS, HINTS, ID); exit(0); case 'r': PrependRScalar(&GOALS, "goal.*", CF_SCALAR); SHOWREPORTS = true; break; case 'x': SelfDiagnostic(); exit(0); case 'a': printf("Self-analysis is not yet implemented.\n"); exit(0); break; /* case 'p': SHOW_PARSE_TREE = true; break; */ case 'g': USE_GCC_BRIEF_FORMAT = true; break; default: Syntax("cf-promises - cfengine's promise analyzer", OPTIONS, HINTS, ID); exit(1); } } if (argv[optind] != NULL) { CfOut(cf_error, "", "Unexpected argument with no preceding option: %s\n", argv[optind]); } CfDebug("Set debugging\n"); return config; }
static void CheckControlPromises(char *scope,char *agent,struct Constraint *controllist) { struct Constraint *cp; struct BodySyntax *bp = NULL; struct Rlist *rp; int i = 0; struct Rval returnval; char rettype; void *retval; Debug("CheckControlPromises(%s)\n",agent); for (i = 0; CF_ALL_BODIES[i].bs != NULL; i++) { bp = CF_ALL_BODIES[i].bs; if (strcmp(agent,CF_ALL_BODIES[i].btype) == 0) { break; } } if (bp == NULL) { FatalError("Unknown agent"); } for (cp = controllist; cp != NULL; cp=cp->next) { if (IsExcluded(cp->classes)) { continue; } if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_bundlesequence].lval) == 0) { returnval = ExpandPrivateRval(CONTEXTID,cp->rval,cp->type); } else { returnval = EvaluateFinalRval(CONTEXTID,cp->rval,cp->type,true,NULL); } DeleteVariable(scope,cp->lval); if (!AddVariableHash(scope,cp->lval,returnval.item,returnval.rtype,GetControlDatatype(cp->lval,bp),cp->audit->filename,cp->lineno)) { CfOut(cf_error,""," !! Rule from %s at/before line %d\n",cp->audit->filename,cp->lineno); } if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_output_prefix].lval) == 0) { strncpy(VPREFIX,returnval.item,CF_MAXVARSIZE); } if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_domain].lval) == 0) { strcpy(VDOMAIN,cp->rval); CfOut(cf_verbose,"","SET domain = %s\n",VDOMAIN); DeleteScalar("sys","domain"); DeleteScalar("sys","fqhost"); snprintf(VFQNAME,CF_MAXVARSIZE,"%s.%s",VUQNAME,VDOMAIN); NewScalar("sys","fqhost",VFQNAME,cf_str); NewScalar("sys","domain",VDOMAIN,cf_str); DeleteClass("undefined_domain"); NewClass(VDOMAIN); } if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_ignore_missing_inputs].lval) == 0) { CfOut(cf_verbose,"","SET ignore_missing_inputs %s\n",cp->rval); IGNORE_MISSING_INPUTS = GetBoolean(cp->rval); } if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_ignore_missing_bundles].lval) == 0) { CfOut(cf_verbose,"","SET ignore_missing_bundles %s\n",cp->rval); IGNORE_MISSING_BUNDLES = GetBoolean(cp->rval); } if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_goalpatterns].lval) == 0) { GOALS = NULL; for (rp = (struct Rlist *)returnval.item; rp != NULL; rp=rp->next) { PrependRScalar(&GOALS,rp->item,CF_SCALAR); } CfOut(cf_verbose,"","SET goal_patterns list\n"); continue; } if (strcmp(cp->lval,CFG_CONTROLBODY[cfg_goalcategories].lval) == 0) { GOALCATEGORIES = NULL; for (rp = (struct Rlist *)returnval.item; rp != NULL; rp=rp->next) { PrependRScalar(&GOALCATEGORIES,rp->item,CF_SCALAR); } CfOut(cf_verbose,"","SET goal_categories list\n"); continue; } DeleteRvalItem(returnval.item,returnval.rtype); } }
static void VerifyTopicPromise(Promise *pp) { char id[CF_BUFSIZE]; Attributes a = { {0} }; Topic *tp = NULL, *otp; Rlist *rp, *rps, *contexts; char *handle = (char *) GetConstraintValue("handle", pp, CF_SCALAR); a = GetTopicsAttributes(pp); CfOut(cf_verbose, "", " -> Attempting to install topic %s::%s \n", pp->classes, pp->promiser); // Add a standard reserved word contexts = SplitContextExpression(pp->classes, pp); for (rp = contexts; rp != NULL; rp = rp->next) { if ((tp = InsertTopic(pp->promiser, rp->item)) == NULL) { return; } CfOut(cf_verbose, "", " -> New topic promise for \"%s\" about context \"%s\"", pp->promiser, ScalarValue(rp)); if (a.fwd_name && a.bwd_name) { AddTopicAssociation(tp, &(tp->associations), a.fwd_name, a.bwd_name, a.associates, true, rp->item, pp->promiser); } // Handle all synonyms as associations if (a.synonyms) { for (rps = a.synonyms; rps != NULL; rps = rps->next) { otp = IdempInsertTopic(rps->item); CfOut(cf_verbose, "", " ---> %s is a synonym for %s", ScalarValue(rps), tp->topic_name); } AddTopicAssociation(tp, &(tp->associations), KM_SYNONYM, KM_SYNONYM, a.synonyms, true, rp->item, pp->promiser); } // Handle all generalizations as associations if (a.general) { for (rps = a.general; rps != NULL; rps = rps->next) { otp = IdempInsertTopic(rps->item); CfOut(cf_verbose, "", " ---> %s is a generalization for %s", ScalarValue(rps), tp->topic_name); } AddTopicAssociation(tp, &(tp->associations), KM_GENERALIZES_B, KM_GENERALIZES_F, a.general, true, rp->item, pp->promiser); } if (handle) { char synonym[CF_BUFSIZE]; snprintf(synonym, CF_BUFSIZE - 1, "handles::%s", handle); otp = IdempInsertTopic(synonym); PrependRScalar(&(a.synonyms), otp->topic_name, CF_SCALAR); } // Treat comments as occurrences of information. if (pp->ref) { Rlist *list = NULL; snprintf(id, CF_MAXVARSIZE, "%s.%s", pp->classes, CanonifyName(pp->promiser)); PrependRScalar(&list, "description", CF_SCALAR); AddOccurrence(&OCCURRENCES, pp->ref, list, cfk_literal, id); DeleteRlist(list); } if (handle) { Rlist *list = NULL; PrependRScalar(&list, handle, CF_SCALAR); AddTopicAssociation(tp, &(tp->associations), "is the promise of", "stands for", list, true, rp->item, pp->promiser); DeleteRlist(list); list = NULL; snprintf(id, CF_MAXVARSIZE, "%s.%s", pp->classes, handle); PrependRScalar(&list, "description", CF_SCALAR); AddOccurrence(&OCCURRENCES, pp->ref, list, cfk_literal, id); DeleteRlist(list); } } DeleteRlist(contexts); }
static void AddTopicAssociation(Topic *this_tp, TopicAssociation **list, char *fwd_name, char *bwd_name, Rlist *passociates, int ok_to_add_inverse, char *from_context, char *from_topic) { TopicAssociation *ta = NULL, *texist; char fwd_context[CF_MAXVARSIZE]; Rlist *rp; Topic *new_tp; char contexttopic[CF_BUFSIZE], ntopic[CF_BUFSIZE], ncontext[CF_BUFSIZE]; strncpy(ntopic, NormalizeTopic(from_topic), CF_BUFSIZE - 1); strncpy(ncontext, NormalizeTopic(from_context), CF_BUFSIZE - 1); snprintf(contexttopic, CF_MAXVARSIZE, "%s::%s", ncontext, ntopic); strncpy(fwd_context, CanonifyName(fwd_name), CF_MAXVARSIZE - 1); if (passociates == NULL || passociates->item == NULL) { CfOut(cf_error, "", " !! A topic must have at least one associate in association %s", fwd_name); return; } if ((texist = AssociationExists(*list, fwd_name, bwd_name)) == NULL) { ta = xcalloc(1, sizeof(TopicAssociation)); ta->fwd_name = xstrdup(fwd_name); if (bwd_name) { ta->bwd_name = xstrdup(bwd_name); } ta->fwd_context = xstrdup(fwd_context); ta->next = *list; *list = ta; } else { ta = texist; } /* Association now exists, so add new members */ if (ok_to_add_inverse) { CfOut(cf_verbose, "", " -> BEGIN add fwd associates for %s::%s", ncontext, ntopic); } else { CfOut(cf_verbose, "", " ---> BEGIN reverse associations %s::%s", ncontext, ntopic); } // First make sure topics pointed to exist so that they can point to us also for (rp = passociates; rp != NULL; rp = rp->next) { char normalform[CF_BUFSIZE] = { 0 }; strncpy(normalform, NormalizeTopic(rp->item), CF_BUFSIZE - 1); new_tp = IdempInsertTopic(normalform); if (strcmp(contexttopic, normalform) == 0) { CfOut(cf_verbose, "", " ! Excluding self-reference to %s", ScalarValue(rp)); continue; } if (ok_to_add_inverse) { CfOut(cf_verbose, "", " --> Adding '%s' with id %d as an associate of '%s::%s'", normalform, new_tp->id, this_tp->topic_context, this_tp->topic_name); } else { CfOut(cf_verbose, "", " ---> Reverse '%s' with id %d as an associate of '%s::%s' (inverse)", normalform, new_tp->id, this_tp->topic_context, this_tp->topic_name); } if (!IsItemIn(ta->associates, normalform)) { PrependFullItem(&(ta->associates), normalform, NULL, new_tp->id, 0); if (ok_to_add_inverse) { // inverse is from normalform to ncontext::ntopic char rev[CF_BUFSIZE], ndt[CF_BUFSIZE], ndc[CF_BUFSIZE]; Rlist *rlist = 0; snprintf(rev, CF_BUFSIZE - 1, "%s::%s", ncontext, ntopic); PrependRScalar(&rlist, rev, CF_SCALAR); // Stupid to have to declassify + reclassify, but .. DeClassifyTopic(normalform, ndt, ndc); AddTopicAssociation(new_tp, &(new_tp->associations), bwd_name, fwd_name, rlist, false, ndc, ndt); DeleteRlist(rlist); } } else { CfOut(cf_verbose, "", " -> Already in %s::%s's associate list", ncontext, ntopic); } CF_EDGES++; } if (ok_to_add_inverse) { CfOut(cf_verbose, "", " -> END add fwd associates for %s::%s", ncontext, ntopic); } else { CfOut(cf_verbose, "", " ---> END reverse associations %s::%s", ncontext, ntopic); } }