/* * match_variable * INPUT: * string Input string to match * pvt variable type (from definition) * cmd variable string (from definition) - can contain range * RETURNS: * -1 Error (print msg on stderr) * 0 Not match and reason returned as malloced string. * 1 Match * Who prints errors? */ static int match_variable(cg_obj *co, char *str, char **reason) { int retval = -1; cg_var *cv; cg_varspec *cs; cs = &co->u.cou_var; if ((cv = cv_new(co->co_vtype)) == NULL) goto done; if ((retval = cv_parse1(str, cv, reason)) <= 0) goto done; retval = cv_validate(cv, cs, reason); done: if (cv) cv_free(cv); return retval; }
/* * 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; }