Beispiel #1
0
static int
choose(struct xml_node *st, struct xml_node *xt, struct xml_node *rt)
{
    struct xml_node *s = NULL;
    struct xml_node *sc = NULL;
    int match = 0;

    /* first try matching 'when' statement */
    while ((s = xml_child_each(st, s, XML_ELEMENT)) != NULL) {
	if (s->xn_namespace && strcmp(s->xn_namespace, "xsl") == 0){ 
	    if (strcmp(s->xn_name, "when")==0){
		if (choose_test(s, xt, rt, &match) < 0)
		    return -1;
		if (match)
		    break;
	    }
	}
    }
    if (!match){ /* no match above - find otherwise */
	if ((s = xml_xpath(st, "/otherwise")) != NULL &&
	    s->xn_namespace && 
	    strcmp(s->xn_namespace, "xsl") == 0){
	    while ((sc = xml_child_each(s, sc, XML_ELEMENT)) != NULL) 
		if (traverse(sc, xt, rt) < 0)
		    return -1;
	}
    }
    return 0;
}
Beispiel #2
0
/*! Compare two dbs using XML. Write to file and run diff
 */
static int
compare_xmls(cxobj *xc1, 
	     cxobj *xc2, 
	     int    astext)
{
    int    fd;
    FILE  *f;
    char   filename1[MAXPATHLEN];
    char   filename2[MAXPATHLEN];
    char   cmd[MAXPATHLEN];
    int    retval = -1;
    cxobj *xc;

    snprintf(filename1, sizeof(filename1), "/tmp/cliconXXXXXX");
    snprintf(filename2, sizeof(filename2), "/tmp/cliconXXXXXX");
    if ((fd = mkstemp(filename1)) < 0){
	clicon_err(OE_UNDEF, errno, "tmpfile: %s", strerror (errno));
	goto done;
    }
    if ((f = fdopen(fd, "w")) == NULL)
	goto done;
    xc = NULL;
    if (astext)
	while ((xc = xml_child_each(xc1, xc, -1)) != NULL)
	    xml2txt(f, xc, 0);
    else
	while ((xc = xml_child_each(xc1, xc, -1)) != NULL)
	    xml_print(f, xc);

    fclose(f);
    close(fd);

    if ((fd = mkstemp(filename2)) < 0){
	clicon_err(OE_UNDEF, errno, "mkstemp: %s", strerror (errno));
	goto done;
    }
    if ((f = fdopen(fd, "w")) == NULL)
	goto done;
    xc = NULL;
    if (astext)
	while ((xc = xml_child_each(xc2, xc, -1)) != NULL)
	    xml2txt(f, xc, 0);
    else
	while ((xc = xml_child_each(xc2, xc, -1)) != NULL)
	    xml_print(f, xc);
    fclose(f);
    close(fd);

    snprintf(cmd, sizeof(cmd), "/usr/bin/diff -dU 1 %s %s |  grep -v @@ | sed 1,2d", 		 filename1, filename2);
    if (system(cmd) < 0)
	goto done;

    retval = 0;
  done:
    unlink(filename1);
    unlink(filename2);
    return retval;
}
Beispiel #3
0
/*! This is the callback used by cli_setlog to print log message in CLI
 * param[in]  s    UNIX socket from backend  where message should be read
 * param[in]  arg  format: txt, xml, xml2txt, xml2json
 */
static int
cli_notification_cb(int   s, 
		    void *arg)
{
    struct clicon_msg *reply = NULL;
    int                eof;
    int                retval = -1;
    cxobj             *xt = NULL;
    cxobj             *xe;
    cxobj             *x;
    enum format_enum format = (enum format_enum)arg;
    
    /* get msg (this is the reason this function is called) */
    if (clicon_msg_rcv(s, &reply, &eof) < 0)
	goto done;
    if (eof){
	clicon_err(OE_PROTO, ESHUTDOWN, "Socket unexpected close");
	close(s);
	errno = ESHUTDOWN;
	event_unreg_fd(s, cli_notification_cb);
	goto done;
    }
    if (clicon_msg_decode(reply, NULL, &xt) < 0) /* XXX pass yang_spec */
	goto done;
    if ((xe = xpath_first(xt, "//event")) != NULL){
	x = NULL;
	while ((x = xml_child_each(xe, x, -1)) != NULL) {
	    switch (format){
	    case FORMAT_XML:
		if (clicon_xml2file(stdout, x, 0, 1) < 0)
		    goto done;
		break;
	    case FORMAT_TEXT:
		if (xml2txt(stdout, x, 0) < 0)
		    goto done;
		break;
	    case FORMAT_JSON:
		if (xml2json(stdout, x, 1) < 0)
		    goto done;
		break;
	    default:
		break;
	    }
	}
    }
    retval = 0;
  done:
    if (xt)
	xml_free(xt);
    if (reply)
	free(reply);
    return retval;
}
Beispiel #4
0
/*
 * <xsl:if test="expr"/>
 */
static int
ifelement(struct xml_node *st, struct xml_node *xt, struct xml_node *rt)
{
    char *test;
    struct xml_node *s = NULL;

    if ((test = xml_get(st, "test")) == NULL)
	return 0;
    if (xml_xpath(xt, test) == NULL)
	return 0;
    while ((s = xml_child_each(st, s, XML_ELEMENT)) != NULL) 
	if (traverse(s, xt, rt) < 0)
	    return -1;
    return 0;
}
Beispiel #5
0
/*
 * <xsl:choose>
 *   <xsl:when test="expr"/>
 *   <xsl:when test="expr"/>
 *   <xsl:otherwise/>
 * </xsl:choose>
 */
static int
choose_test(struct xml_node *st, struct xml_node *xt, struct xml_node *rt, int *match)
{
    char *test;
    struct xml_node *s = NULL;

    *match = 0;
    if ((test = xml_get(st, "test")) == NULL)
	return 0;
    if (xml_xpath(xt, test) == NULL)
	return 0;
    *match = 1;
    while ((s = xml_child_each(st, s, -1)) != NULL) {
	if (s->xn_type == XML_ATTRIBUTE)
	    continue;
	if (traverse(s, xt, rt) < 0)
	    return -1;
    }
    return 0;
}
Beispiel #6
0
/*! Load a configuration file to candidate database
 * Utility function used by cligen spec file
 * @param[in] h     CLICON handle
 * @param[in] cvv   Vector of variables (where <varname> is found)
 * @param[in] argv  A string: "<varname> (merge|replace)" 
 *   <varname> is name of a variable occuring in "cvv" containing filename
 * @note that "filename" is local on client filesystem not backend. 
 * @note file is assumed to have a dummy top-tag, eg <clicon></clicon>
 * @code
 *   # cligen spec
 *   load file <name2:string>, load_config_file("name2","merge");
 * @endcode
 * @see save_config_file
 */
int 
load_config_file(clicon_handle h, 
		 cvec         *cvv, 
		 cvec         *argv)
{
    int         ret = -1;
    struct stat st;
    char       *filename = NULL;
    int         replace;
    cg_var     *cv;
    char       *opstr;
    char       *varstr;
    int         fd = -1;
    cxobj      *xt = NULL;
    cxobj      *x;
    cbuf       *cbxml;

    if (cvec_len(argv) != 2){
	if (cvec_len(argv)==1)
	    clicon_err(OE_PLUGIN, 0, "Got single argument:\"%s\". Expected \"<varname>,<op>\"", cv_string_get(cvec_i(argv,0)));
	else
	    clicon_err(OE_PLUGIN, 0, "Got %d arguments. Expected: <varname>,<op>", cvec_len(argv));
	goto done;
    }
    varstr = cv_string_get(cvec_i(argv, 0));
    opstr  = cv_string_get(cvec_i(argv, 1));
    if (strcmp(opstr, "merge") == 0) 
	replace = 0;
    else if (strcmp(opstr, "replace") == 0) 
	replace = 1;
    else{
	clicon_err(OE_PLUGIN, 0, "No such op: %s, expected merge or replace", opstr);	
	goto done;
    }
    if ((cv = cvec_find(cvv, varstr)) == NULL){
	clicon_err(OE_PLUGIN, 0, "No such var name: %s", varstr);	
	goto done;
    }
    filename = cv_string_get(cv);
    if (stat(filename, &st) < 0){
 	clicon_err(OE_UNIX, 0, "load_config: stat(%s): %s", 
		   filename, strerror(errno));
	goto done;
    }
    /* Open and parse local file into xml */
    if ((fd = open(filename, O_RDONLY)) < 0){
	clicon_err(OE_UNIX, errno, "open(%s)", filename);
	goto done;
    }
    if (xml_parse_file(fd, "</clicon>", NULL, &xt) < 0)
	goto done;
    if (xt == NULL)
	goto done;
    if ((cbxml = cbuf_new()) == NULL)
	goto done;
    x = NULL;
    while ((x = xml_child_each(xt, x, -1)) != NULL) {
	/* Ensure top-level is "config", maybe this is too rough? */
	xml_name_set(x, "config");
	if (clicon_xml2cbuf(cbxml, x, 0, 0) < 0)
	    goto done;
    }
    if (clicon_rpc_edit_config(h, "candidate",
			       replace?OP_REPLACE:OP_MERGE, 
			       cbuf_get(cbxml)) < 0)
	goto done;
    cbuf_free(cbxml);
    //    }
    ret = 0;
 done:
    if (xt)
	xml_free(xt);
    if (fd != -1)
	close(fd);
    return ret;
}