diff options
Diffstat (limited to 'src/xml.c')
-rw-r--r-- | src/xml.c | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/src/xml.c b/src/xml.c new file mode 100644 index 0000000..4ec82b2 --- /dev/null +++ b/src/xml.c @@ -0,0 +1,186 @@ +/* + * xml.c + * + * Rudimentary XML parser + * + * (c) 2002-2005 Thomas White <taw27@srcf.ucam.org> + * Part of TuxMessenger - GTK+-based MSN Messenger client + * + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 dated June, 1991. + * + * This package is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this package; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <string.h> +#include <stdlib.h> +#include <libxml/xmlmemory.h> +#include <libxml/parser.h> + +#include "routines.h" +#include "debug.h" + +char *xml_getfield(const char *xml, const char *field) { + + char *identifier_start; + char *value; + + identifier_start = strstr(xml, field); + + if ( identifier_start == NULL ) { + return NULL; + } + + value = routines_lindex(identifier_start + strlen(field) + 2, 0); + value[strlen(value)-1] = '\0'; + + return value; + +} + +char *xml_killillegalchars(const char *temp) { + + char *result; + unsigned int i; + + if ( temp == NULL ) { + return strdup(""); + } + + result = malloc(strlen(temp)+1); + strcpy(result, temp); + for ( i=0; i<strlen(result); i++ ) { + + if ( result[i] == '/' ) { + result[i] = '-'; + } + + /* Don't even think about directory traversal... */ + if ( result[i] == '.' ) { + result[i] = '-'; + } + + } + + return result; + +} + +/* Get the block of text between two given tags. */ +char *xml_getblock(const char *xml, size_t xmllength, const char *rootnode, const char *keyword, int entities) { + + xmlDocPtr doc; + xmlNodePtr cur; + + doc = xmlParseMemory(xml, xmllength); + + if (doc == NULL ) { + return NULL; + } + + cur = xmlDocGetRootElement(doc); + + if (cur == NULL) { + xmlFreeDoc(doc); + return NULL; + } + + if (xmlStrcmp(cur->name, rootnode)) { + xmlFreeDoc(doc); + return NULL; + } + + cur = cur->xmlChildrenNode; + while (cur != NULL) { + + if ((!xmlStrcmp(cur->name, keyword))) { + + char *resultchar; + + xmlChar *result = xmlNodeListGetString(doc, cur->xmlChildrenNode, entities); + if ( result == NULL ) { + return NULL; + } + resultchar = strdup(result); + xmlFree(result); + return resultchar; + + } + + cur = cur->next; + + } + + return NULL; + +} + +/* Set the block of text between two given tags. */ +char *xml_setblock(const char *xml, size_t xmllength, const char *rootnode, const char *keyword, const char *value) { + + xmlDocPtr doc; + xmlNodePtr cur; + + doc = xmlParseMemory(xml, xmllength); + + if (doc == NULL ) { + return NULL; + } + + cur = xmlDocGetRootElement(doc); + + if (cur == NULL) { + xmlFreeDoc(doc); + return NULL; + } + + if (xmlStrcmp(cur->name, rootnode)) { + xmlFreeDoc(doc); + return NULL; + } + + cur = cur->xmlChildrenNode; + while (cur != NULL) { + + if ((!xmlStrcmp(cur->name, keyword))) { + + xmlChar *xmlbuf; + size_t xmlbuflength; + char *text; + + xmlNewTextChild(cur->parent, NULL, keyword, value); + xmlUnlinkNode(cur); + xmlFreeNode(cur); + + xmlDocDumpFormatMemory(doc, &xmlbuf, &xmlbuflength, 0); + text = malloc(xmlbuflength+1); + memcpy(text, xmlbuf, xmlbuflength+1); + xmlFree(xmlbuf); + + return text; + + + + } + + cur = cur->next; + + } + + return NULL; + +} |