aboutsummaryrefslogtreecommitdiff
path: root/src/xml.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xml.c')
-rw-r--r--src/xml.c186
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;
+
+}