Ejemplo n.º 1
0
/*! Return object in original tree from  object in a referenced tree
 * Given an object in a referenced tree, and the top of the original tree,
 * return the corresponding object in the original tree.
 * The figure tries to show:
     ref-tree      orig
     -----        ----- pt0
       o            o (given top)
     /   \        /   \
    o     o      o     o
     \            \
      o co1         o co0
       (given)     (we want to find this)
 */
int
reference_path_match(cg_obj    *co1, 
		     parse_tree pt0, 
		     cg_obj   **co0p)
{
    cg_obj    *co0, *co;

    if (co1 == NULL)
	return -1;
    if (co1->co_treeref){ /* at top */
	if ((co0 = co_find_one(pt0, co1->co_command)) == NULL)
	    return -1;
	*co0p = co0;
	return 0;
    }
    if (reference_path_match(co_up(co1), pt0, &co) < 0)
	return -1;
    if ((co0 = co_find_one(co->co_pt, co1->co_command)) == NULL)
	return -1;
    *co0p = co0;
    return 0;
}
Ejemplo n.º 2
0
/*
 * generic_validate
 *
 * key values are checked for validity independent of user-defined callbacks
 * They are checked as follows:
 * 1. If no value and default value defined, add it.
 * 2. If no value and mandatory flag set in spec, report error.
 * 3. Validate value versus spec, and report error if no match. Currently only int ranges and
 *    string regexp checked.
 */
static int
generic_validate(clicon_handle h, char *dbname, const struct dbdiff *dd)
{
    int             i, j;
    char           *key;
    cvec           *cvec = NULL;
    cg_var         *cv;
    cg_varspec     *cs;
    int             retval = -1;
    cg_obj         *co;
    cg_obj         *cov;
    parse_tree     *dbspec_co;
    char           *reason = NULL;
    parse_tree     *pt;

    if ((dbspec_co = clicon_dbspec_pt(h)) == NULL)
	goto done;
    /* dd->df_ents[].dfe_key1 (running),  
       dd->df_ents[].dfe_key2 (candidate) */
    for (i = 0; i < dd->df_nr; i++) {
	if ((key = dd->df_ents[i].dfe_key2) == NULL)
	    continue;
	if ((co = key2spec_co(dbspec_co, key)) == NULL)
	    continue;
	/* read variable list from db */
	if ((cvec = dbkey2cvec(dbname, key)) == NULL) 
	    goto done;
	/* Loop over all co:s children (spec) and check if actual values
	   in db(cv) satisfies them */
	pt = &co->co_pt;
	for (j=0; j<pt->pt_len; j++){
	    if ((cov = pt->pt_vec[j]) == NULL)
		continue;
	    if (cov->co_type == CO_VARIABLE){

		/* There is no db-value, but dbspec has default value */
		if ((cv = dbspec_default_get(cov)) != NULL &&
		    cvec_find(cvec, cov->co_command) == NULL){
		    cv_flag_set(cv, V_DEFAULT); /* mark it as default XXX not survive DB */
		    /* add default value to cvec */
		    if (cvec_add_cv(cvec, cv) < 0){
			clicon_err(OE_CFG, 0, "cvec_add_cv");
			goto done;
		    }
		    /* Write to database */
		    if (cvec2dbkey(dbname, key, cvec) < 0)
			goto done;
		}
		else
		if (!dbspec_optional_get(cov) && cvec_find(cvec, cov->co_command) == NULL){
		    clicon_err(OE_CFG, 0, 
			       "key %s: Missing mandatory variable: %s\n",
			       key, cov->co_command);
		    goto done;
		}
	    }
	}
	cv = NULL;
	/* Loop over all actual db/cv:s och check their validity */	
	while ((cv = cvec_each(cvec, cv))) {
	    if ((cov = co_find_one(*pt, cv_name_get(cv))) == NULL){
		clicon_err(OE_CFG, 0, "key %s: variable %s not found in co-spec", 
			   key, cv_name_get(cv));
		goto done;
	    }
	    if ((cs = co2varspec(cov)) == NULL)
		continue;
	    if (cv_validate(cv, cs, &reason) != 1){ /* We ignore errors */
		clicon_err(OE_DB, 0, 
			   "key %s: validation of %s failed\n",
			   key, cov->co_command);
		goto done;
	    }

	}
	if (cvec){
	    cvec_free(cvec);
	    cvec = NULL;
	}
    } /* for */
    retval = 0;
  done:
    if (cvec)
	cvec_free(cvec);
    if (reason)
	free(reason);
    return retval;
}