Пример #1
0
void
test_copy (void) {
	char str1[] = "\x01\x01x\x01\x01y\x01\x01xy\x01\x01";
	char *str2 = (char *)NULL;
	char *str3 = (char *)NULL;

	cbuffer_t *buf1 = (cbuffer_t *)NULL;
	cbuffer_t *buf2 = (cbuffer_t *)NULL;

	buf1 = cbuf_new();
	buf2 = cbuf_new();

	cbuf_import (buf1, str1, strlen (str1));
	cbuf_copy (buf2, buf1);

	printf ("test_copy(): str1 = %s\n", str1);

	str2 = (char *)xmalloc (buf1->sz + 1);
	memset (str2, (int)NULL, buf1->sz + 1);
	memcpy (str2, buf1->data, buf1->sz);

	str3 = (char *)xmalloc (buf2->sz + 1);
	memset (str3, (int)NULL, buf2->sz + 1);
	memcpy (str3, buf2->data, buf2->sz);

	printf ("test_copy(): str2 = %s\ntest_copy(): str3 = %s\n", str2, str3);

	xfree (str2);
	xfree (str3);

	cbuf_delete (buf1);
	cbuf_delete (buf2);
}
Пример #2
0
void
test_split (void) {
	char str0[] = "\x01";
	char str1[] = "\x01\x01x\x01y\x01z\x01xy\x01yz";
	char str2[] = "buffer one\n\x01\x02\nend buffer\n";
	char str3[] = "buffer two\n\x01\x02\nend buffer\n";

	deque_t *split = (deque_t *)NULL;

	cbuffer_t *buf1 = (cbuffer_t *)NULL;
	cbuffer_t *buf2 = (cbuffer_t *)NULL;
	cbuffer_t *buf3 = (cbuffer_t *)NULL;

	buf1 = cbuf_new ();
	buf2 = cbuf_new ();
	buf3 = cbuf_new ();

	cbuf_import (buf1, str1, strlen (str1));
	cbuf_import (buf2, str2, strlen (str2));
	cbuf_import (buf3, str3, strlen (str3));

	split = cbuf_split (buf1, (void *)str0, 1);
	printf ("test_split(): len = %d\n", deque_length (split));

	deque_push (split, buf2);
	printf ("test_split(): len = %d\n", deque_length (split));

	deque_push (split, buf3);
	printf ("test_split(): len = %d\n", deque_length (split));

	cbuf_delete (buf1);
	deque_delete (split, cbuf_delete_callback);
}
Пример #3
0
struct reg_parse* reg_parse_new(const void* ctx,
				struct reg_parse_callback cb,
				const char* str_enc, unsigned flags)
{
	struct reg_parse* s = talloc_zero(ctx, struct reg_parse);
	if (s == NULL)
		return NULL;
	s->key     = cbuf_new(s);
	s->valname = cbuf_new(s);
	s->valblob = cbuf_new(s);
	s->tmp     = cbuf_new(s);
	if ( (s->tmp == NULL) || (s->valblob == NULL)
	     || (s->valname == NULL) || (s->key == NULL) )
	{
		goto fail;
	}

	s->reg_format_callback.writeline = (reg_format_callback_writeline_t)&reg_parse_line;
	s->reg_format_callback.data      = s;

	s->valtype = 0;
	if (cb.key == NULL) {
		cb.key = (reg_parse_callback_key_t)&nop;
	}
	if (cb.val == NULL) {
		cb.val = (reg_parse_callback_val_t)&nop;
	}
	if (cb.val_del == NULL) {
		cb.val_del = (reg_parse_callback_val_del_t)&nop;
	}
	if (cb.comment == NULL) {
		cb.comment = (reg_parse_callback_comment_t)&nop;
	}

	s->call = cb;
	s->linenum = 0;
	s->state = STATE_DEFAULT;
	s->flags = flags;

	if (str_enc && !set_iconv(&s->str2UTF16, "UTF-16LE", str_enc)) {
		DEBUG(0, ("reg_parse_new: failed to set encoding: %s",
			  str_enc));
		goto fail;
	}

	assert(&s->reg_format_callback == (struct reg_format_callback*)s);
	return s;
fail:
	talloc_free(s);
	return NULL;
}
Пример #4
0
/*! Generate and log clicon error function call from Netconf error message
 * @param[in]  xerr    Netconf error message on the level: <rpc-reply><rpc-error>
 */
int
clicon_rpc_generate_error(char  *format, 
			  cxobj *xerr)
{
    int    retval = -1;
    cbuf  *cb = NULL;
    cxobj *x;

    if ((cb = cbuf_new()) ==NULL){
	clicon_err(OE_XML, errno, "cbuf_new");
	goto done;
    }
    if ((x=xpath_first(xerr, "error-type"))!=NULL)
	cprintf(cb, "%s ", xml_body(x));
    if ((x=xpath_first(xerr, "error-tag"))!=NULL)
	cprintf(cb, "%s ", xml_body(x));
    if ((x=xpath_first(xerr, "error-message"))!=NULL)
	cprintf(cb, "%s ", xml_body(x));
    if ((x=xpath_first(xerr, "error-info"))!=NULL)
	clicon_xml2cbuf(cb, xml_child_i(x,0), 0, 0);
    clicon_log(LOG_ERR, "%s: %s", format, cbuf_get(cb));
    retval = 0;
 done:
    if (cb)
	cbuf_free(cb);
    return retval;
}
Пример #5
0
void
test_replace (void) {
	char str1[] = "\x01\x01\x01x\x01y\x01z\x01xy\x01yz\x01";
	char *str2 = (char *)NULL;

	cbuffer_t *buf1 = (cbuffer_t *)NULL;
	cbuffer_t *buf2 = (cbuffer_t *)NULL;

	buf1 = cbuf_new ();

	cbuf_import (buf1, str1, strlen (str1));

	buf2 = cbuf_replace (buf1, "\x01", ", ", 1, 2);

	if (buf2 != (cbuffer_t *)NULL) {
		str2 = (char *)xmalloc (buf2->sz + 1);
		if (str2 != (char *)NULL) {
			memset (str2, (int)NULL, buf2->sz + 1);
			memcpy (str2, buf2->data, buf2->sz);
			printf ("test_replace(): str1 = %s\n", str1);
			printf ("test_replace(): str2 = %s\n", str2);
			xfree (str2);
		}
	}

	cbuf_delete (buf1);
	cbuf_delete (buf2);
}
Пример #6
0
/**
 * Parse option string
 * @param[in,out] ptr parse position
 * @param[in] mem_ctx talloc context
 * @param[out] name ptr 2 value
 * @param[out] value ptr 2 value
 * @return true on success
 */
bool srprs_option(const char** ptr, const void* mem_ctx, char** name, char** value)
{
	const char* pos = *ptr;
	void* ctx = talloc_new(mem_ctx);

	cbuf* key = cbuf_new(ctx);
	cbuf* val = NULL;

	while(srprs_charsetinv(&pos, ",= \t\n\r", key))
		;
	if (pos == *ptr) {
		talloc_free(ctx);
		return false;
	}

	if (name != NULL) {
		*name = talloc_steal(mem_ctx, cbuf_gets(key, 0));
	}

	if (*pos == '=') {
		val = cbuf_new(ctx);
		pos++;
		if (!srprs_quoted_string(ptr, val, NULL)) {
			while(srprs_charsetinv(&pos, ", \t\n\r", val))
				;
		}
		if (value != NULL) {
			*value = talloc_steal(mem_ctx, cbuf_gets(val, 0));
		}
	} else {
		if (value != NULL) {
			*value = NULL;
		}
	}

	while(srprs_char(&pos, ','))
		;

	*ptr = pos;
	return true;
}
Пример #7
0
/**
 * create a new component manager */
void *component_manager_new(void *ctx, void *subject)
{
    component_manager_t *cm;

    cm = calloc(1, sizeof(component_manager_t));
    cm->components = hashmap_new(__ulong_hash, __ulong_compare,11);
    cm->ctx = ctx;
    cm->subject = subject;
//    cm->event_queue = llqueue_new();
    cm->event_queue = cbuf_new(16);
    return cm;
}
Пример #8
0
void
test_import (void) {
	char str1[] = "buffer one\n\x01\x02\nend buffer\n";
	char str2[] = "buffer two\n\x01\x02\nend buffer\n";
	char str3[] = "x" "\x01" "y" "\x01" "z" "\x01" "xy" "\x01" "yz";

	cbuffer_t *buf1 = (cbuffer_t *)NULL;
	cbuffer_t *buf2 = (cbuffer_t *)NULL;
	cbuffer_t *buf3 = (cbuffer_t *)NULL;

	buf1 = cbuf_new ();
	buf2 = cbuf_new ();
	buf3 = cbuf_new ();

	cbuf_import (buf1, str1, strlen (str1));
	cbuf_import (buf2, str2, strlen (str2));
	cbuf_import (buf3, str3, strlen (str3));

	cbuf_delete (buf1);
	cbuf_delete (buf2);
	cbuf_delete (buf3);
}
Пример #9
0
void
test_search (void) {
	char str1[] = "\x01\x01x234x\x01\x01y\x01\x01xy123\x01\x01";
	deque_t *lst = (deque_t *)NULL;

	cbuffer_t *buf1 = (cbuffer_t *)NULL;
	buf1 = cbuf_new();
	cbuf_import (buf1, str1, strlen (str1));

	lst = cbuf_search (buf1, "\x01", 1);

	printf ("test_search(): len = %d\n", deque_length (lst));

	deque_delete_nocb (lst);
	cbuf_delete (buf1);
}
Пример #10
0
/*! Get database configuration
 * Same as clicon_proto_change just with a cvec instead of lvec
 * @param[in]  h        CLICON handle
 * @param[in]  db       Name of database
 * @param[in]  xpath    XPath (or "")
 * @param[out] xt       XML tree. Free with xml_free. 
 *                      Either <config> or <rpc-error>. 
 * @retval    0         OK
 * @retval   -1         Error, fatal or xml
 * @code
 *    cxobj *xt = NULL;
 *    if (clicon_rpc_get_config(h, "running", "/", &xt) < 0)
 *       err;
 *   if ((xerr = xpath_first(xt, "/rpc-error")) != NULL){
 *	clicon_rpc_generate_error("", xerr);
 *      err;
 *  }
 *    if (xt)
 *       xml_free(xt);
 * @endcode
 * @see clicon_rpc_generate_error
 */
int
clicon_rpc_get_config(clicon_handle       h, 
		      char               *db, 
		      char               *xpath,
		      cxobj             **xt)
{
    int                retval = -1;
    struct clicon_msg *msg = NULL;
    cbuf              *cb = NULL;
    cxobj             *xret = NULL;
    cxobj             *xd;
    char              *username;
    
    if ((cb = cbuf_new()) == NULL)
	goto done;
    cprintf(cb, "<rpc");
    if ((username = clicon_username_get(h)) != NULL)
	cprintf(cb, " username=\"%s\"", username);
    cprintf(cb, "><get-config><source><%s/></source>", db);
    if (xpath && strlen(xpath))
	cprintf(cb, "<filter type=\"xpath\" select=\"%s\"/>", xpath);
    cprintf(cb, "</get-config></rpc>");
    if ((msg = clicon_msg_encode("%s", cbuf_get(cb))) == NULL)
	goto done;
    if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
	goto done;
    /* Send xml error back: first check error, then ok */
    if ((xd = xpath_first(xret, "/rpc-reply/rpc-error")) != NULL)
	xd = xml_parent(xd); /* point to rpc-reply */
    else if ((xd = xpath_first(xret, "/rpc-reply/data")) == NULL)
	if ((xd = xml_new("data", NULL, NULL)) == NULL)
	    goto done;
    if (xt){
	if (xml_rm(xd) < 0)
	    goto done;
	*xt = xd;
    }
    retval = 0;
  done:
    if (cb)
	cbuf_free(cb);
    if (xret)
	xml_free(xret);
    if (msg)
	free(msg);
    return retval;
}
Пример #11
0
void
test_tail_head (void) {
	char str1[] = "123456";
	char *str2 = (char *)NULL;
	char *str3 = (char *)NULL;

	cbuffer_t *buf1;
	cbuffer_t *buf2;
	cbuffer_t *buf3;
	buf1 = (cbuffer_t *)NULL;
	buf2 = (cbuffer_t *)NULL;
	buf3 = (cbuffer_t *)NULL;

	printf ("test_tail_head(): str1 = %s\n", (char *)str1);

	buf1 = cbuf_new();
	cbuf_import (buf1, str1, strlen (str1));

	buf2 = cbuf_head (buf1, 3);
	str2 = (char *)malloc (buf2->sz + 1);
	if (str2 != (char *)NULL) {
		memset (str2, (int)NULL, buf2->sz + 1);
		memcpy (str2, buf2->data, buf2->sz);
		printf ("test_tail_head(): str2 = %s\n", str2);
		free (str2);
	}

	buf3 = cbuf_tail (buf1, 3);
	str3 = (char *)malloc (buf3->sz + 1);
	if (str3 != (char *)NULL) {
		memset (str3, (int)NULL, buf3->sz + 1);
		memcpy (str3, buf3->data, buf3->sz);
		printf ("test_tail_head(): str3 = %s\n", str3);
		free (str3);
	}

	cbuf_delete (buf2);
	cbuf_delete (buf3);

	buf2 = cbuf_head_cut (buf1, 3);
	buf3 = cbuf_tail_cut (buf2, 3);

	cbuf_delete (buf2);
	cbuf_delete (buf3);

	cbuf_delete (buf1);
}
Пример #12
0
connection *comm_connect(char *ipaddress, int connections) {
	int i, port;
	connection *conn;
	
	if (in_thread == NULL) start_threads();
	if (connections < 1) return NULL;
	if (ipaddress == NULL) return NULL;
	
	conn = (connection *) malloc(sizeof(connection));
	
	conn->label = strdup(ipaddress);
	conn->connected = 0;
	conn->sockets = (out_socket *) malloc(connections * sizeof(out_socket));
	conn->num_sockets = connections;
	
	// setup the outgoing connections
	for (i = 0; i < connections; i++) {
		conn->sockets[i].fd = connect_to_socket(ipaddress, SOPHIA_PORT);
		set_non_blocking(conn->sockets[i].fd);
		pthread_mutex_init(&(conn->sockets[i].fd_lock), 0);
		conn->sockets[i].backlog = 0;
		conn->sockets[i].done = 0;
	}
	
	conn->connected = 1;
	
	// setup the rget connection
	conn->rget_settings.buffer = cbuf_new();
	conn->rget_settings.client_fd = -1;
	
	conn->rget_settings.server_fd = -1;
	while( conn->rget_settings.server_fd < 0 ) {
		port = randomise_port();
		conn->rget_settings.server_fd = listen_on_socket(port);
	}
	
	// comm_send(conn, 1, "void", 1, NULL, NULL, "[RGetRegisterClient \"%d\" \"%s\"]", port, "10.0.0.12"); // REMOTE get_local_ip());
	comm_send(conn, 1, "void", 1, NULL, NULL, "[RGetRegisterClient \"%d\" \"%s\"]", port, get_local_ip(conn->sockets[0].fd));
	// wait to accept the rget connection
	while (conn->rget_settings.client_fd < 0) { conn->rget_settings.client_fd = accept(conn->rget_settings.server_fd, NULL, 0); }
	
	// add this connect to the inbound subsystem
	comm_in_add(&(conn->rget_settings));
	
	return conn;
}
Пример #13
0
/*! Send database entries as XML to backend daemon
 * @param[in] h          CLICON handle
 * @param[in] db         Name of database
 * @param[in] op         Operation on database item: OP_MERGE, OP_REPLACE
 * @param[in] xml        XML string. Ex: <config><a>..</a><b>...</b></config>
 * @retval    0          OK
 * @retval   -1          Error and logged to syslog
 * @note xml arg need to have <config> as top element
 * @code
 * if (clicon_rpc_edit_config(h, "running", OP_MERGE, 
 *                            "<config><a>4</a></config>") < 0)
 *    err;
 * @endcode
 */
int
clicon_rpc_edit_config(clicon_handle       h, 
		       char               *db, 
		       enum operation_type op,
		       char               *xmlstr)
{
    int                retval = -1;
    struct clicon_msg *msg = NULL;
    cbuf              *cb = NULL;
    cxobj             *xret = NULL;
    cxobj             *xerr;
    char              *username;

    if ((cb = cbuf_new()) == NULL)
	goto done;
    cprintf(cb, "<rpc %s", DEFAULT_XMLNS);
    if ((username = clicon_username_get(h)) != NULL)
	cprintf(cb, " username=\"%s\"", username);
    cprintf(cb, "><edit-config><target><%s/></target>", db);
    cprintf(cb, "<default-operation>%s</default-operation>", 
	    xml_operation2str(op));
    if (xmlstr)
	cprintf(cb, "%s", xmlstr);
    cprintf(cb, "</edit-config></rpc>");
    if ((msg = clicon_msg_encode("%s", cbuf_get(cb))) == NULL)
	goto done;
    if (clicon_rpc_msg(h, msg, &xret, NULL) < 0)
	goto done;
    if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){
	clicon_rpc_generate_error("Editing configuration", xerr);
	goto done;
    }
    retval = 0;
  done:
    if (xret)
	xml_free(xret);
    if (cb)
	cbuf_free(cb);
    if (msg)
	free(msg);
    return retval;
}
Пример #14
0
/*! Reset running and start in failsafe mode. If no failsafe then quit.
  Typically done when startup status is not OK so

failsafe      ----------------------+
                            reset    \ commit
running                       |-------+---------------> RUNNING FAILSAFE
 */
int
startup_failsafe(clicon_handle h)
{
    int   retval = -1;
    int   ret;
    char *db = "failsafe";
    cbuf *cbret = NULL;

    if ((cbret = cbuf_new()) == NULL){
	clicon_err(OE_XML, errno, "cbuf_new");
	goto done;
    }
    if ((ret = xmldb_exists(h, db)) < 0)
	goto done;
    if (ret == 0){ /* No it does not exist, fail */
	clicon_err(OE_DB, 0, "Startup failed and no Failsafe database found, exiting");
	goto done;
    }
    /* Copy original running to tmp as backup (restore if error) */
    if (xmldb_copy(h, "running", "tmp") < 0)
	goto done;
    if (startup_db_reset(h, "running") < 0)
	goto done;
    ret = candidate_commit(h, db, cbret);
    if (ret != 1)
	if (xmldb_copy(h, "tmp", "running") < 0)
	    goto done;
    if (ret < 0)
	goto done;
    if (ret == 0){
	clicon_err(OE_DB, 0, "Startup failed, Failsafe database validation failed %s", cbuf_get(cbret));
	goto done;
    }
    clicon_log(LOG_NOTICE, "Startup failed, Failsafe database loaded ");
    retval = 0;
 done:
    if (cbret)
	cbuf_free(cbret);
    return retval;
}
Пример #15
0
/*! Generic xml netconf clicon rpc
 * Want to go over to use netconf directly between client and server,...
 * @param[in]  h       clicon handle
 * @param[in]  xml     XML netconf tree 
 * @param[out] xret    Return XML netconf tree, error or OK
 * @param[out] sp      Socket pointer for notification, otherwise NULL
 * @code
 *   cxobj *xret = NULL;
 *   int    s; 
 *   if (clicon_rpc_netconf_xml(h, x, &xret, &s) < 0)
 *	err;
 *   xml_free(xret);
 * @endcode

 * @see clicon_rpc_netconf xml as string instead of tree
 */
int
clicon_rpc_netconf_xml(clicon_handle  h, 
		       cxobj         *xml,
		       cxobj        **xret,
		       int           *sp)
{
    int                retval = -1;
    cbuf               *cb = NULL;

    if ((cb = cbuf_new()) == NULL){
	clicon_err(OE_XML, errno, "cbuf_new");
	goto done;
    }
    if (clicon_xml2cbuf(cb, xml, 0, 0) < 0)
	goto done;
    if (clicon_rpc_netconf(h, cbuf_get(cb), xret, sp) < 0)
	goto done;
    retval = 0;
 done:
    if (cb)
	cbuf_free(cb);
    return retval;
}
Пример #16
0
void
test_new (void) {
	cbuffer_t *buf = cbuf_new ();
	cbuf_delete (buf);
}
Пример #17
0
/*! Copy one configuration object to antother
 *
 * Works for objects that are items ina yang list with a keyname, eg as:
 *   list sender{ 
 *      key name;	
 *	leaf name{...
 *
 * @param[in]  h    CLICON handle
 * @param[in]  cvv  Vector of variables from CLIgen command-line
 * @param[in]  argv Vector: <db>, <xpath>, <field>, <fromvar>, <tovar>
 * Explanation of argv fields:
 *  db:     Database name, eg candidate|tmp|startup
 *  xpath:  XPATH expression with exactly two %s pointing to field and from name
 *  field:  Name of list key, eg name
 *  fromvar:Name of variable containing name of object to copy from (given by xpath)
 *  tovar:  Name of variable containing name of object to copy to.
 * @code
 * cli spec:
 *  copy snd <n1:string> to <n2:string>, cli_copy_config("candidate", "/sender[%s='%s']", "from", "n1", "n2");
 * cli command:
 *  copy snd from to to
 * @endcode
 */
int
cli_copy_config(clicon_handle h, 
		cvec         *cvv, 
		cvec         *argv)
{
    int          retval = -1;
    char        *db;
    cxobj       *x1 = NULL; 
    cxobj       *x2 = NULL; 
    cxobj       *x;
    char        *xpath;
    int          i;
    int          j;
    cbuf        *cb = NULL;
    char        *keyname;
    char        *fromvar;
    cg_var      *fromcv;
    char        *fromname = NULL;
    char        *tovar;
    cg_var      *tocv;
    char        *toname;
    cxobj       *xerr;

    if (cvec_len(argv) != 5){
	clicon_err(OE_PLUGIN, 0, "Requires four elements: <db> <xpath> <keyname> <from> <to>");
	goto done;
    }
    /* First argv argument: Database */
    db = cv_string_get(cvec_i(argv, 0));
    /* Second argv argument: xpath */
    xpath = cv_string_get(cvec_i(argv, 1));
    /* Third argv argument: name of keyname */
    keyname = cv_string_get(cvec_i(argv, 2));
    /* Fourth argv argument: from variable */
    fromvar = cv_string_get(cvec_i(argv, 3));
    /* Fifth argv argument: to variable */
    tovar = cv_string_get(cvec_i(argv, 4));
    
    /* Get from variable -> cv -> from name */
    if ((fromcv = cvec_find(cvv, fromvar)) == NULL){
	clicon_err(OE_PLUGIN, 0, "fromvar '%s' not found in cligen var list", fromvar);	
	goto done;
    }
    /* Get from name from cv */
    fromname = cv_string_get(fromcv);
    /* Create xpath */
    if ((cb = cbuf_new()) == NULL){
	clicon_err(OE_PLUGIN, errno, "cbuf_new");	
	goto done;
    }
    /* Sanity check that xpath contains exactly two %s, ie [%s='%s'] */
    j = 0;
    for (i=0; i<strlen(xpath); i++){
	if (xpath[i] == '%')
	    j++;
    }
    if (j != 2){
	clicon_err(OE_PLUGIN, 0, "xpath '%s' does not have two '%%'", xpath);	
	goto done;
    }
    cprintf(cb, xpath, keyname, fromname);	
    /* Get from object configuration and store in x1 */
    if (clicon_rpc_get_config(h, db, cbuf_get(cb), &x1) < 0)
	goto done;
    if ((xerr = xpath_first(x1, "/rpc-error")) != NULL){
	clicon_rpc_generate_error("Get configuration", xerr);
	goto done;
    }

    /* Get to variable -> cv -> to name */
    if ((tocv = cvec_find(cvv, tovar)) == NULL){
	clicon_err(OE_PLUGIN, 0, "tovar '%s' not found in cligen var list", tovar);
	goto done;
    }
    toname = cv_string_get(tocv);
    /* Create copy xml tree x2 */
    if ((x2 = xml_new("new", NULL, NULL)) == NULL)
	goto done;
    if (xml_copy(x1, x2) < 0)
	goto done;
    xml_name_set(x2, "config");
    cprintf(cb, "/%s", keyname);	
    if ((x = xpath_first(x2, "%s", cbuf_get(cb))) == NULL){
	clicon_err(OE_PLUGIN, 0, "Field %s not found in copy tree", keyname);
	goto done;
    }
    x = xml_find(x, "body");
    xml_value_set(x, toname);
    /* resuse cb */
    cbuf_reset(cb);
    /* create xml copy tree and merge it with database configuration */
    clicon_xml2cbuf(cb, x2, 0, 0);
    if (clicon_rpc_edit_config(h, db, OP_MERGE, cbuf_get(cb)) < 0)
	goto done;
    retval = 0;
 done:
    if (cb)
	cbuf_free(cb);
    if (x1 != NULL)
	xml_free(x1);
    if (x2 != NULL)
	xml_free(x2);
    return retval;
}
Пример #18
0
int main(void)
{
	CircBuf *cbuf;
	unsigned long val, val2;
	unsigned long vals[32];
	unsigned char c, c2;
	unsigned char s[10];
	int i, j;

	cbuf = cbuf_new(sizeof(val), 32);
	
	assert(cbuf != NULL);
	assert(cbuf->size == (sizeof(val) * 32));
	assert(cbuf_unread(cbuf) == 0);
	assert(cbuf_unwritten(cbuf) == 31);

	val = 0xaaaaaaaa;
	cbuf_put(cbuf, &val, 1);

	/* 
	 * Note:  unread() + unwritten() should always equal 31
	 * (one less than the size of the buffer)
	 */
	assert(cbuf_unread(cbuf) == 1);
	assert(cbuf_unwritten(cbuf) == 30);

	cbuf_peek(cbuf, 0, &val2, 1);
	
	assert(val2 == val);
	assert(cbuf_unread(cbuf) == 1);
	assert(cbuf_unwritten(cbuf) == 30);

	val = 0xdeadbeef;
	cbuf_put(cbuf, &val, 1);
	assert(cbuf_unread(cbuf) == 2);
	assert(cbuf_unwritten(cbuf) == 29);

	val2 = 0;
	cbuf_get(cbuf, &val2, 1);
	assert(val2 == 0xaaaaaaaa);
	assert(cbuf_unread(cbuf) == 1);
	assert(cbuf_unwritten(cbuf) == 30);

	val = 0xdeadbabe;
	cbuf_put(cbuf, &val, 1);
	val = 0x12345678;
	cbuf_put(cbuf, &val, 1);

	/* Write 10 elements */
	for (i = 0; i < 10; i++)
		vals[i] = i;
	cbuf_put(cbuf, vals, 10);

	assert(cbuf_unread(cbuf) == 13);
	assert(cbuf_unwritten(cbuf) == 18);

	val2 = 0;
	cbuf_get(cbuf, &val2, 1);
	assert(val2 == 0xdeadbeef);
	cbuf_get(cbuf, &val2, 1);
	assert(val2 == 0xdeadbabe);
	
	/* 
	 * Now let's try writing across the boundary.. we've written
	 * a total of 14 elements so far.  So let's write 18 now
	 * to make sure we're overwriting the first things we wrote.
	 */
	for (i = 0; i < 18; i++)
		vals[i] = 0xFFFF0000 | i;
	cbuf_put(cbuf, vals, 18);

	assert(cbuf_unread(cbuf) == 29);
	assert(cbuf_unwritten(cbuf) == 2);

	cbuf_get(cbuf, &val2, 1);
	assert(val2 == 0x12345678);

	cbuf_get(cbuf, vals, 10);
	for (i = 0; i < 10; i++)
		assert(vals[i] == i);
	assert(cbuf_unread(cbuf) == 18);
	assert(cbuf_unwritten(cbuf) == 13);

	/* Now read across boundary */
	cbuf_get(cbuf, vals, 18);
	for (i = 0; i < 18; i++)
		assert(vals[i] == (0xFFFF0000 | i));
	assert(cbuf_unread(cbuf) == 0);
	assert(cbuf_unwritten(cbuf) == 31);

	/* One more boundary test, writing 1 element at a time */
	for (i = 0; i < 31; i++) {
		val = (0xaaaa0000 | i);
		cbuf_put(cbuf, &val, 1);
	}

	assert(cbuf_unread(cbuf) == 31);
	assert(cbuf_unwritten(cbuf) == 0);

	for (i = 0; i < 31; i++) {
		cbuf_get(cbuf, &val, 1);
		assert(val == (0xaaaa0000 | i));
	}

	assert(cbuf_unread(cbuf) == 0);
	assert(cbuf_unwritten(cbuf) == 31);

	cbuf_destroy(cbuf);

	/* Test with character elements instead of longs */
	cbuf = cbuf_new(sizeof(c), 10);
	
	assert(cbuf != NULL);
	assert(cbuf->size == (sizeof(c) * 10));
	assert(cbuf_unread(cbuf) == 0);
	assert(cbuf_unwritten(cbuf) == 9);

	c = '@';
	cbuf_put(cbuf, &c, 1);

	assert(cbuf_unread(cbuf) == 1);
	assert(cbuf_unwritten(cbuf) == 8);

	cbuf_peek(cbuf, 0, &c2, 1);
	
	assert(c2 == c);
	assert(cbuf_unread(cbuf) == 1);
	assert(cbuf_unwritten(cbuf) == 8);

	c = 'a';
	cbuf_put(cbuf, &c, 1);
	assert(cbuf_unread(cbuf) == 2);
	assert(cbuf_unwritten(cbuf) == 7);

	c2 = '\0';
	cbuf_get(cbuf, &c2, 1);
	assert(c2 == '@');
	assert(cbuf_unread(cbuf) == 1);
	assert(cbuf_unwritten(cbuf) == 8);

	c = 'b';
	cbuf_put(cbuf, &c, 1);
	c = '#';
	cbuf_put(cbuf, &c, 1);

	cbuf_get(cbuf, &c, 1);
	assert(c == 'a');
	cbuf_get(cbuf, &c, 1);
	assert(c == 'b');

	assert(cbuf_unread(cbuf) == 1);
	assert(cbuf_unwritten(cbuf) == 8);

	/* Write 8 elements */
	for (i = 0; i < 8; i++)
		s[i] = (unsigned char) i;
	cbuf_put(cbuf, s, 8);

	assert(cbuf_unwritten(cbuf) == 0);
	assert(cbuf_unread(cbuf) == 9);

	c = '\0';
	cbuf_get(cbuf, &c, 1);
	assert(c == '#');

	for (i = 0; i < 8; i++)
		s[i] = '0';

	cbuf_get(cbuf, s, 8);
	for (i = 0; i < 8; i++)
		assert(s[i] == (unsigned char) i);


	assert(cbuf_unread(cbuf) == 0);
	assert(cbuf_unwritten(cbuf) == 9);

	cbuf_destroy(cbuf);	

	printf("Unit test PASSED\n");
	return 0;
}
Пример #19
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;
}
Пример #20
0
/*! Modify xml datastore from a callback using xml key format strings
 * @param[in]  h    Clicon handle
 * @param[in]  cvv  Vector of cli string and instantiated variables 
 * @param[in]  argv Vector. First element xml key format string, eg "/aaa/%s"
 * @param[in]  op   Operation to perform on database
 * Cvv will contain first the complete cli string, and then a set of optional
 * instantiated variables.
 * Example:
 * cvv[0]  = "set interfaces interface eth0 type bgp"
 * cvv[1]  = "eth0"
 * cvv[2]  = "bgp"
 * argv[0] = "/interfaces/interface/%s/type"
 * op: OP_MERGE
 * @see cli_callback_generate where arg is generated
 */
static int
cli_dbxml(clicon_handle       h, 
	  cvec               *cvv, 
	  cvec               *argv, 
	  enum operation_type op)
{
    int        retval = -1;
    char      *str = NULL;
    char      *api_path_fmt;  /* xml key format */
    char      *api_path = NULL; /* xml key */
    cg_var    *cval;
    int        len;
    cg_var    *arg;
    cbuf      *cb = NULL;
    yang_stmt *yspec;
    cxobj     *xbot = NULL; /* xpath, NULL if datastore */
    yang_stmt *y = NULL; /* yang spec of xpath */
    cxobj     *xtop = NULL; /* xpath root */
    cxobj     *xa;           /* attribute */
    cxobj     *xb;           /* body */

    if (cvec_len(argv) != 1){
	clicon_err(OE_PLUGIN, 0, "Requires one element to be xml key format string");
	goto done;
    }
    if ((yspec = clicon_dbspec_yang(h)) == NULL){
	clicon_err(OE_FATAL, 0, "No DB_SPEC");
	goto done;
    }
    arg = cvec_i(argv, 0);
    api_path_fmt = cv_string_get(arg);
    if (api_path_fmt2api_path(api_path_fmt, cvv, &api_path) < 0)
	goto done;
    /* Create config top-of-tree */
    if ((xtop = xml_new("config", NULL, NULL)) == NULL)
	goto done;
    xbot = xtop;
    if (api_path && api_path2xml(api_path, yspec, xtop, YC_DATANODE, 1, &xbot, &y) < 1)
	goto done; 
    if ((xa = xml_new("operation", xbot, NULL)) == NULL)
	goto done;
    xml_type_set(xa, CX_ATTR);
    if (xml_value_set(xa,  xml_operation2str(op)) < 0)
	goto done;
    if (yang_keyword_get(y) != Y_LIST && yang_keyword_get(y) != Y_LEAF_LIST){
	len = cvec_len(cvv);
	if (len > 1){
	    cval = cvec_i(cvv, len-1); 
	    if ((str = cv2str_dup(cval)) == NULL){
		clicon_err(OE_UNIX, errno, "cv2str_dup");
		goto done;
	    }
	    if ((xb = xml_new("body", xbot, NULL)) == NULL)
		goto done; 
	    xml_type_set(xb, CX_BODY);
	    if (xml_value_set(xb,  str) < 0)
		goto done;
	}
    }
    if ((cb = cbuf_new()) == NULL){
	clicon_err(OE_XML, errno, "cbuf_new");
	goto done;
    }
    if (clicon_xml2cbuf(cb, xtop, 0, 0) < 0)
	goto done;
    if (clicon_rpc_edit_config(h, "candidate", OP_NONE, cbuf_get(cb)) < 0)
	goto done;
    if (clicon_autocommit(h)) {
	if (clicon_rpc_commit(h) < 0) 
	    goto done;
    }
    retval = 0;
 done:
    if (cb)
	cbuf_free(cb);
    if (str)
	free(str);
    if (api_path)
	free(api_path);  
    if (xtop)
	xml_free(xtop);
    return retval;
}