Example #1
0
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);
}
Example #2
0
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);
}
Example #3
0
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);
}
Example #4
0
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;
}
Example #5
0
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;
}
Example #6
0
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);
    }
}
Example #7
0
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);
    }
}
Example #8
0
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);
   }
}
Example #10
0
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);
}
Example #11
0
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);
    }
}