/* * load environment variable */ bool_t loadenv(char * file) { struct xml * root, * env; root = xml_parse_file(file); if(!root || !root->name) return FALSE; if(strcmp(root->name, "environment") != 0) { xml_free(root); return FALSE; } clearenv(); for(env = xml_child(root, "env"); env; env = env->next) { if(env->txt) putenv(env->txt); } xml_free(root); return TRUE; }
xml_node *xml_parse( const char *filename ) { int done = 0; FILE *xptr; XML_Parser p; static char buf[BUFSIZE]; xml_node root, *ret; if( (xptr = fopen( filename, "r" )) == NULL ) { fprintf( stderr, "Unable to open file: %s\n", filename ); return NULL; } root.child = NULL; if( (ret = xml_alloc(&root)) == NULL ) { fclose( xptr ); fprintf( stderr, "Out of memory\n" ); return NULL; } if( (p = XML_ParserCreate( NULL )) == NULL ) { fclose( xptr ); fprintf( stderr, "Out of memory\n" ); return NULL; } XML_SetUserData( p, &ret ); XML_SetElementHandler( p, xml_el_start, xml_el_end ); XML_SetCharacterDataHandler( p, xml_charhndl ); while( !done ) { int len; len = fread( buf, 1, BUFSIZE, xptr ); if( ferror( xptr ) ) { fprintf( stderr, "Read error\n" ); xml_free( ret ); ret = NULL; break; } done = feof( xptr ); if( XML_Parse(p, buf, len, done) == 0 ) { fprintf( stderr, "Parse error at line %d:\n%s\n", (int) XML_GetCurrentLineNumber(p), XML_ErrorString( XML_GetErrorCode(p) ) ); xml_free( ret ); ret = NULL; break; } } if( ret != NULL ) ret->parent = NULL; fclose( xptr ); XML_ParserFree( p ); return ret; }
/* free a previously allocated XmlNode */ void xml_free(XmlNode *target) { int i; for(i=0; i<target->nattrib*2; i++) if(target->attrib[i]) free(target->attrib[i]); if(target->attrib)free(target->attrib); if(target->child)xml_free(target->child); if(target->next)xml_free(target->next); free(target->name); free(target); }
/*! Create a new notification subscription * @param[in] h Clicon handle * @param{in] stream name of notificatio/log stream (CLICON is predefined) * @param{in] filter message filter, eg xpath for xml notifications * @param[out] s0 socket returned where notification mesages will appear * @retval 0 OK * @retval -1 Error and logged to syslog * @note When using netconf create-subsrciption,status and format is not supported */ int clicon_rpc_create_subscription(clicon_handle h, char *stream, char *filter, int *s0) { int retval = -1; struct clicon_msg *msg = NULL; cxobj *xret = NULL; cxobj *xerr; char *username; username = clicon_username_get(h); if ((msg = clicon_msg_encode("<rpc username=\"%s\"><create-subscription xmlns=\"urn:ietf:params:xml:ns:netmod:notification\">" "<stream>%s</stream>" "<filter type=\"xpath\" select=\"%s\" />" "</create-subscription></rpc>", username?username:"", stream?stream:"", filter?filter:"")) == NULL) goto done; if (clicon_rpc_msg(h, msg, &xret, s0) < 0) goto done; if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ clicon_rpc_generate_error("Create subscription", xerr); goto done; } retval = 0; done: if (xret) xml_free(xret); if (msg) free(msg); return retval; }
/*! Send a debug request to backend server * @param[in] h CLICON handle * @param[in] level Debug level * @retval 0 OK * @retval -1 Error and logged to syslog */ int clicon_rpc_debug(clicon_handle h, int level) { int retval = -1; struct clicon_msg *msg = NULL; cxobj *xret = NULL; cxobj *xerr; char *username; username = clicon_username_get(h); /* XXX: hardcoded example yang, should be clixon-config!!! */ if ((msg = clicon_msg_encode("<rpc username=\"%s\"><debug xmlns=\"http://clicon.org/lib\"><level>%d</level></debug></rpc>", username?username:"", level)) == 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("Debug",xerr); goto done; } if (xpath_first(xret, "//rpc-reply/ok") == NULL){ clicon_err(OE_XML, 0, "rpc error"); /* XXX extract info from rpc-error */ goto done; } retval = 0; done: if (msg) free(msg); if (xret) xml_free(xret); return retval; }
/*! Commit changes send a commit request to backend daemon * @param[in] h CLICON handle * @retval 0 OK * @retval -1 Error and logged to syslog */ int clicon_rpc_commit(clicon_handle h) { int retval = -1; struct clicon_msg *msg = NULL; cxobj *xret = NULL; cxobj *xerr; char *username; username = clicon_username_get(h); if ((msg = clicon_msg_encode("<rpc username=\"%s\"><commit/></rpc>", username?username:"")) == 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(CLIXON_ERRSTR_COMMIT_FAILED, xerr); goto done; } retval = 0; done: if (xret) xml_free(xret); if (msg) free(msg); return retval; }
/*! Discard all changes in candidate / revert to running * @param[in] h CLICON handle * @retval 0 OK * @retval -1 Error and logged to syslog */ int clicon_rpc_discard_changes(clicon_handle h) { int retval = -1; struct clicon_msg *msg = NULL; cxobj *xret = NULL; cxobj *xerr; char *username; username = clicon_username_get(h); if ((msg = clicon_msg_encode("<rpc username=\"%s\"><discard-changes/></rpc>", username?username:"")) == 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("Discard changes", xerr); goto done; } retval = 0; done: if (xret) xml_free(xret); if (msg) free(msg); return retval; }
/*! Kill other user sessions * @param[in] h CLICON handle * @param[in] session_id Session id of other user session * @retval 0 OK * @retval -1 Error and logged to syslog */ int clicon_rpc_kill_session(clicon_handle h, int session_id) { int retval = -1; struct clicon_msg *msg = NULL; cxobj *xret = NULL; cxobj *xerr; char *username; username = clicon_username_get(h); if ((msg = clicon_msg_encode("<rpc username=\"%s\"><kill-session><session-id>%d</session-id></kill-session></rpc>", username?username:"", session_id)) == 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("Kill session", xerr); goto done; } retval = 0; done: if (xret) xml_free(xret); if (msg) free(msg); return retval; }
/*! Send validate request to backend daemon * @param[in] h CLICON handle * @param[in] db Name of database * @retval 0 OK * @retval -1 Error and logged to syslog */ int clicon_rpc_validate(clicon_handle h, char *db) { int retval = -1; struct clicon_msg *msg = NULL; cxobj *xret = NULL; cxobj *xerr; char *username; username = clicon_username_get(h); if ((msg = clicon_msg_encode("<rpc username=\"%s\"><validate><source><%s/></source></validate></rpc>", username?username:"", db)) == 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(CLIXON_ERRSTR_VALIDATE_FAILED, xerr); goto done; } retval = 0; done: if (msg) free(msg); if (xret) xml_free(xret); return retval; }
/*! Unlock a database * @param[in] h CLICON handle * @param[in] db database, eg "running" * @retval 0 OK * @retval -1 Error and logged to syslog */ int clicon_rpc_unlock(clicon_handle h, char *db) { int retval = -1; struct clicon_msg *msg = NULL; cxobj *xret = NULL; cxobj *xerr; char *username; username = clicon_username_get(h); if ((msg = clicon_msg_encode("<rpc username=\"%s\"><unlock><target><%s/></target></unlock></rpc>", username?username:"", db)) == 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("Configuration unlock", xerr); goto done; } retval = 0; done: if (xret) xml_free(xret); if (msg) free(msg); return retval; }
/*! Send a request to backend to delete a config database * @param[in] h CLICON handle * @param[in] db database, eg "running" * @retval 0 OK * @retval -1 Error and logged to syslog * @code * if (clicon_rpc_delete_config(h, "startup") < 0) * err; * @endcode */ int clicon_rpc_delete_config(clicon_handle h, char *db) { int retval = -1; struct clicon_msg *msg = NULL; cxobj *xret = NULL; cxobj *xerr; char *username; username = clicon_username_get(h); if ((msg = clicon_msg_encode("<rpc username=\"%s\"><edit-config><target><%s/></target><default-operation>none</default-operation><config operation=\"delete\"/></edit-config></rpc>", username?username:"", db)) == 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("Deleting configuration", xerr); goto done; } retval = 0; done: if (xret) xml_free(xret); if (msg) free(msg); return retval; }
MODULE free_switches_structure (void) { if (xml_switches) xml_free (xml_switches); xml_switches = NULL; }
void xml_el_start( void *data, const char *name, const char **attr ) { int i, nattr = 1; xml_node *node = xml_alloc( *((xml_node **) data) ); if( node == NULL ) { fprintf( stderr, "Out of memory\n" ); return; } node->key = strdup( name ); for( i=0;attr[i];i++ ) nattr++; if( (node->attr = (char **) malloc( sizeof( char * ) *nattr )) == NULL ) { fprintf( stderr, "Out of memory\n" ); xml_free( node ); return; } for( i=0;attr[i];i++ ) { node->attr[i] = strdup( attr[i] ); //printf("ATTR: %s\n", attr[i]); } node->attr[i] = NULL; *((xml_node **) data) = node; }
char *test_read_input() { FILE *f; /* open, read and parse some invalid xml */ f = fopen("test.invalid.xml", "r"); mu_assert("read invalid xml", read_input(f) == 0); fclose(f); mu_assert("parse invalid xml", xml_parse(buf) == XML_STATUS_INVALID); /* open, read and parse some valid xml */ f = fopen("test.xml", "r"); mu_assert("read valid xml", read_input(f) == 0); fclose(f); mu_assert("buffer contains request", strncmp(buf,"<request>", 9) == 0); mu_assert("parse some valid xml", xml_parse(buf) == XML_STATUS_OK); /* fetch value of an element */ char *value = xml_element("//username"); mu_assert("perform xpath search for element", value != NULL); mu_assert("get value of xml element", strcmp(value, "iamauser") == 0); xml_free(value); xml_cleanup(); return 0; }
void prepare_xml_file (char *filename) { int rc; rc = xml_load_file (& xml_root, PATH, filename, FALSE); if (rc == XML_NOERROR) { xml_source = xml_first_child (xml_root); if (xml_source) { xml_put_attr (xml_switches, "filename", filename); xml_put_attr (xml_switches, "template", "1"); } else xml_free (xml_root); } else { coprintf ("%s E: Error processing %s...", me, filename); coprintf (xml_error ()); raise_exception (anomaly_event); } }
/*! Merge xml in filename into database * @retval -1 Error * @retval 0 Validation failed (with cbret set) * @retval 1 Validation OK */ static int load_extraxml(clicon_handle h, char *filename, const char *db, cbuf *cbret) { int retval = -1; cxobj *xt = NULL; int fd = -1; if (filename == NULL) return 1; if ((fd = open(filename, O_RDONLY)) < 0){ clicon_err(OE_UNIX, errno, "open(%s)", filename); goto done; } if (xml_parse_file(fd, "</config>", NULL, &xt) < 0) goto done; /* Replace parent w first child */ if (xml_rootchild(xt, 0, &xt) < 0) goto done; /* Merge user reset state */ retval = xmldb_put(h, (char*)db, OP_MERGE, xt, clicon_username_get(h), cbret); done: if (fd != -1) close(fd); if (xt) xml_free(xt); return retval; }
/* bootstrap the structures for xml_parse() to be able to get started */ XmlNode* xml_load(const char * filename) { struct XMLBUF xml; XmlNode *ret = NULL; // printf("xml_load(\"%s\");\n", filename); xml.error = 0; xml.eof = 0; xml.read_index = 0; xml.fptr = fopen(filename, "rb"); if(!xml.fptr) return NULL; xml.buf = malloc(BUFFER+1); if(!xml.buf) goto xml_load_fail_malloc_buf; xml.buf[BUFFER]=0; xml.len = BUFFER; xml_read_file(&xml); ret = xml_parse(&xml); if(xml.error) { xml_free(ret); ret = NULL; } free(xml.buf); xml_load_fail_malloc_buf: fclose(xml.fptr); return ret; }
static oss_post_object_group_result_t * construct_post_object_group_response(curl_request_param_t *user_data) { const char *response = user_data->recv_buffer->ptr; assert(response != NULL); XmlNode *xml, *bucket_tag, *key_tag, *etag_tag, *size_tag; unsigned int response_len = strlen(response); xml = xml_load_buffer(response, response_len); oss_post_object_group_result_t *result = post_object_group_result_initialize(); bucket_tag = xml_find(xml, "Bucket"); result->set_bucket_name(result, *bucket_tag->child->attrib); key_tag = xml_find(xml, "Key"); result->set_key(result, *key_tag->child->attrib); etag_tag = xml_find(xml, "ETag"); result->set_etag(result, *etag_tag->child->attrib); size_tag = xml_find(xml,"Size"); unsigned int size = (unsigned int)atoi(*size_tag->child->attrib); result->set_size(result, size); oss_free_user_data(user_data); xml_free(xml); return result; }
unsigned short oss_get_retcode_from_response(const char *response) { unsigned short ret; assert(response != NULL); if (strlen(response) == 0) return NETWORK_NOT_AVAILABLE; XmlNode *xml, *code_tag; char *retinfo; unsigned int response_len = strlen(response); xml = xml_load_buffer(response, response_len); if (NULL == xml) { return OSSCLIB_INTERNAL_ERROR; } code_tag = xml_find(xml, "Code"); if (code_tag != NULL) { retinfo = *code_tag->child->attrib; ret = oss_get_retcode_from_retinfo(retinfo); } else { ret = NGINX_NOT_AVAILABLE; } xml_free(xml); return ret; }
/* we add another function: * XmlNode *xml_load_buffer(const char *buffer) to fit our need. */ XmlNode* xml_load_buffer(const char * buffer, unsigned int buffer_len) { struct XMLBUF xml; XmlNode *ret = NULL; xml.error = 0; xml.eof = 1; xml.read_index = 0; xml.fptr = NULL; xml.buf = (char *)malloc(sizeof(char) * buffer_len + 1); if(!xml.buf) goto xml_load_fail_malloc_buf; memset(xml.buf, 0, buffer_len + 1); xml.len = buffer_len; memcpy(xml.buf, buffer, buffer_len); ret = xml_parse(&xml); if(xml.error) { xml_free(ret); ret = NULL; } free(xml.buf); xml_load_fail_malloc_buf: return ret; }
static oss_access_control_list_t * construct_get_bucket_acl_response( curl_request_param_t *user_data) { const char *response = user_data->recv_buffer->ptr; assert(response != NULL); XmlNode *xml, *grant_tag, *owner_tag; unsigned int response_len = strlen(response); xml = xml_load_buffer(response, response_len); owner_tag = xml_find(xml, "Owner"); oss_owner_t *owner = owner_initialize_with_id(*owner_tag->child->child->attrib, *owner_tag->child->next->child->attrib); grant_tag = xml_find(xml, "Grant"); oss_access_control_list_t *acl = access_control_list_initialize(); acl->set_grant(acl, *grant_tag->child->attrib); acl->set_owner(acl, owner); oss_free_user_data(user_data); xml_free(xml); return acl; }
Bool load_config (const char *filename) { int rc; XML_ITEM *config = NULL; XML_ITEM *root = NULL; char fullname[FILE_NAME_MAX + 1]; root = xml_create ("root", NULL); ASSERT (filename != NULL); ASSERT (strlen(filename) < FILE_NAME_MAX); default_extension (fullname, filename, "cfg"); rc = xml_load_file (&root, ".", fullname, FALSE); if (rc != XML_NOERROR) { coprintf ("Error while loading \"%s\". Check file presence and consistence", fullname); display_usage (); return FALSE;; } config = xml_first_child (root); ASSERT (config); /* default server is localhost */ main_server = mem_strdup (xml_get_attr (config, "smtp", "127.0.0.1")); main_sender = mem_strdup (xml_get_attr (config, "sender", "admin@crjo")); main_dest = mem_strdup (xml_get_attr (config, "dest", "user@crjo")); xml_free (root); return TRUE; }
int main(void) { XmlNode *x, *t; /* This is how many tests you plan to run */ plan_tests(12); ok1(x = xml_load("./test/test.xml1")); ok1(!xml_find(x, "Doesn't Exist")); ok1(t = xml_find(x, "one")); ok1(xml_find(t, "two")); ok1(!xml_attr(t, "foobar")); ok1(!xml_attr(t, "Doesn't Exist")); ok1(xml_attr(t, "barfoo")); xml_free(x); /* Simple thing we expect to succeed */ ok1(!test_load("does not exist")); /* A file that doesn't exist */ ok1(test_load("./test/test.xml1")); /* A basic xml file. */ ok1(test_load("./test/test.xml2")); /* Very small well-formed xml file. */ ok1(test_load("./test/test.xml3")); /* Smallest well-formed xml file. */ ok1(test_load("./test/test.xml4")); /* A single unclosed tag. */ /* Same, with an explicit description of the test. */ // ok(some_test(), "%s with no args should return 1", "some_test") /* How to print out messages for debugging. */ // diag("Address of some_test is %p", &some_test) /* Conditional tests must be explicitly skipped. */ /* This exits depending on whether all tests passed */ return exit_status(); }
static int test_load(const char * filename) { XmlNode *xml = xml_load(filename); if(!xml) return 0; xml_free(xml); return 1; }
MODULE free_xml_structures (void) { if (xml_root) xml_free (xml_root); xml_root = NULL; xml_source = NULL; }
void xml_free( xml *x ) { if ( x->tag ) { newstr_free( x->tag ); free( x->tag ); } if ( x->value ) { newstr_free( x->value ); free( x->value ); } if ( x->a ) { xmlattrib_free( x->a ); free( x->a ); } if ( x->down ) xml_free( x->down ); if ( x->next ) xml_free( x->next ); }
int main (int argc, char **argv) { XML *xml; QUEUE *q; QUEUEROW *r; MIME *m; char *ch; int arg = 1; xml = xml_parse (PhineasConfig); loadpath (cfg_installdir (xml)); queue_init (xml); /* test folder polling */ if ((argc > arg) && (strcmp (argv[arg], "-f") == 0)) { fpoller_register ("ebxml", ebxml_fprocessor); fpoller_task (xml); arg++; ran = 0; } /* test message from queue */ if ((argc > arg) && (strcmp (argv[arg], "-m") == 0)) { if ((q = queue_find ("MemSendQ")) == NULL) error ("can't find MemSendQ"); else if ((r = queue_pop (q)) == NULL) error ("can't pop row\n"); /* else if ((m = ebxml_getsoap (xml, r)) == NULL) error ("can't get soap container\n"); */ else if ((m = ebxml_getmessage (xml, r)) == NULL) error ("can't get message\n"); else if ((ch = mime_format (m)) == NULL) error ("Can't format soap containter\n"); else debug ("message MIME\n%s\n", ch); free (ch); mime_free (m); queue_row_free (r); arg++; } /* test queue polling */ if ((argc > arg) && (strcmp (argv[arg], "-q") == 0)) { qpoller_register ("EbXmlSndQ", ebxml_qprocessor); qpoller_task (xml); arg++; ran = 0; } queue_shutdown (); xml_free (xml); info ("%s %s\n", argv[0], Errors ? "failed" : "passed"); exit (Errors); }
/*! Compare two dbs using XML. Write to file and run diff * @param[in] h Clicon handle * @param[in] cvv * @param[in] arg arg: 0 as xml, 1: as text */ int compare_dbs(clicon_handle h, cvec *cvv, cvec *argv) { cxobj *xc1 = NULL; /* running xml */ cxobj *xc2 = NULL; /* candidate xml */ cxobj *xerr; int retval = -1; int astext; if (cvec_len(argv) > 1){ clicon_err(OE_PLUGIN, 0, "Requires 0 or 1 element. If given: astext flag 0|1"); goto done; } if (cvec_len(argv)) astext = cv_int32_get(cvec_i(argv, 0)); else astext = 0; if (clicon_rpc_get_config(h, "running", "/", &xc1) < 0) goto done; if ((xerr = xpath_first(xc1, "/rpc-error")) != NULL){ clicon_rpc_generate_error("Get configuration", xerr); goto done; } if (clicon_rpc_get_config(h, "candidate", "/", &xc2) < 0) goto done; if ((xerr = xpath_first(xc2, "/rpc-error")) != NULL){ clicon_rpc_generate_error("Get configuration", xerr); goto done; } if (compare_xmls(xc1, xc2, astext) < 0) /* astext? */ goto done; retval = 0; done: if (xc1) xml_free(xc1); if (xc2) xml_free(xc2); return retval; }
/*! Load extra XML via file and/or reset callback, and merge with current * An application can add extra XML either via the -c <file> option or * via the .ca_reset callback. This XML is "merged" into running, that is, * it does not trigger validation calbacks. * The function uses an extra "tmp" database, loads the file to it, and calls * the reset function on it. * @param[in] h Clicon handle * @param[in] file (Optional) extra xml file * @param[out] status Startup status * @param[out] cbret If status is invalid contains error message * @retval -1 Error * @retval 0 Validation failed * @retval 1 OK running -----------------+----+------> reset loadfile / merge tmp |-------+-----+-----+ reset extrafile */ int startup_extraxml(clicon_handle h, char *file, cbuf *cbret) { int retval = -1; char *db = "tmp"; int ret; cxobj *xt = NULL; /* Potentially upgraded XML */ /* Clear tmp db */ if (startup_db_reset(h, db) < 0) goto done; /* Application may define extra xml in its reset function*/ if (clixon_plugin_reset(h, db) < 0) goto done; /* Extra XML can also be added via file */ if (file){ /* Parse and load file into tmp db */ if ((ret = load_extraxml(h, file, db, cbret)) < 0) goto done; if (ret == 0) goto fail; } /* Validate the tmp db and return possibly upgraded xml in xt */ if ((ret = startup_validate(h, db, &xt, cbret)) < 0) goto done; if (ret == 0) goto fail; if (xt==NULL || xml_child_nr(xt)==0) goto ok; /* Write (potentially modified) xml tree xt back to tmp */ if ((ret = xmldb_put(h, "tmp", OP_REPLACE, xt, clicon_username_get(h), cbret)) < 0) goto done; /* Merge tmp into running (no commit) */ if ((ret = db_merge(h, db, "running", cbret)) < 0) goto fail; if (ret == 0) goto fail; ok: retval = 1; done: if (xt) xml_free(xt); if (xmldb_delete(h, "tmp") != 0 && errno != ENOENT) return -1; return retval; fail: retval = 0; goto done; }
bool_t saveenv(char * file) { struct environ_t * environ = &(runtime_get()->__environ); struct environ_t * p; struct xml * root, * env; char * str; int fd; root = xml_new("environment"); if(!root) return FALSE; for(p = environ->next; p != environ; p = p->next) { env = xml_add_child(root, "env", 0); xml_set_txt(env, p->content); } str = xml_toxml(root); if(!str) { xml_free(root); return FALSE; } fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)); if(fd < 0) { free(str); xml_free(root); return FALSE; } write(fd, str, strlen(str)); close(fd); free(str); xml_free(root); return TRUE; }