00001 #include <stdio.h>
00002 #include <string.h>
00003 #include <sys/utsname.h>
00004 #include <libxml/xmlmemory.h>
00005 #include <libxml/parser.h>
00006 #include <libxml/xmlwriter.h>
00007 #include <glib.h>
00008
00009 #include "lpbot.h"
00010
00019 static lp_record_ver *parseVersion(xmlDoc *doc, xmlNode *cur)
00020 {
00021 xmlChar *key;
00022 cur = cur->xmlChildrenNode;
00023 lp_record_ver *ver = g_new0(lp_record_ver, 1);
00024
00025 while (cur != NULL)
00026 {
00027 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
00028 if ((!xmlStrcmp(cur->name, (const xmlChar *)"date")))
00029 ver->date = atoi((char*)key);
00030 if ((!xmlStrcmp(cur->name, (const xmlChar *)"author")))
00031 ver->author = strdup((char*)key);
00032 if ((!xmlStrcmp(cur->name, (const xmlChar *)"content")))
00033 ver->content = g_string_new((char*)key);
00034 xmlFree(key);
00035 cur = cur->next;
00036 }
00037 return ver;
00038 }
00039
00045 static int parseRecord(xmlDoc *doc, xmlNode *cur)
00046 {
00047 xmlChar *key;
00048 cur = cur->xmlChildrenNode;
00049 lp_record *record = g_new0(lp_record, 1);
00050
00051 while (cur != NULL)
00052 {
00053 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
00054 if ((!xmlStrcmp(cur->name, (const xmlChar *)"name")))
00055 record->name = strdup((char*)key);
00056 if((!xmlStrcmp(cur->name, (const xmlChar *)"version")))
00057 record->versions = g_list_append(record->versions, parseVersion(doc, cur));
00058 xmlFree(key);
00059 cur = cur->next;
00060 }
00061 config->records = g_list_append(config->records, record);
00062 return(0);
00063 }
00064
00069 int parseRecords(char *docname)
00070 {
00071 xmlDocPtr doc;
00072 xmlNodePtr cur;
00073 xmlChar *key;
00074
00075 doc = xmlParseFile(docname);
00076
00077 if(doc == NULL)
00078 {
00079 fprintf(stderr, "document not parsed successfully\n");
00080 return(1);
00081 }
00082
00083 cur = xmlDocGetRootElement(doc);
00084
00085 if(cur == NULL)
00086 {
00087 fprintf(stderr, "empty document\n");
00088 xmlFreeDoc(doc);
00089 return(1);
00090 }
00091
00092 if(xmlStrcmp(cur->name, (const xmlChar *)"records"))
00093 {
00094 fprintf(stderr, "document of the wrong type, root node != records");
00095 xmlFreeDoc(doc);
00096 return(1);
00097 }
00098
00099 cur = cur->xmlChildrenNode;
00100 while(cur != NULL)
00101 {
00102 key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
00103 if((!xmlStrcmp(cur->name, (const xmlChar *)"record")))
00104 if(parseRecord(doc, cur))
00105 return(1);
00106 xmlFree(key);
00107 cur = cur->next;
00108 }
00109 xmlFreeDoc(doc);
00110 return(0);
00111 }
00112
00117 int saveRecords(char *docname)
00118 {
00119 int i, j;
00120 xmlTextWriterPtr writer;
00121
00122 writer = xmlNewTextWriterFilename("db.xml", 0);
00123 xmlTextWriterSetIndentString(writer, BAD_CAST "\t");
00124 xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL);
00125 xmlTextWriterStartElement(writer, BAD_CAST "records");
00126 for(i=0;i<g_list_length(config->records);i++)
00127 {
00128 lp_record *record = g_list_nth_data(config->records, i);
00129
00130 xmlTextWriterSetIndent(writer, 1);
00131 xmlTextWriterStartElement(writer, BAD_CAST "record");
00132 xmlTextWriterSetIndent(writer, 2);
00133 xmlTextWriterWriteFormatElement(writer, BAD_CAST "name", "%s", record->name);
00134 for(j=0;j<g_list_length(record->versions);j++)
00135 {
00136 lp_record_ver *ver = g_list_nth_data(record->versions, j);
00137
00138 xmlTextWriterStartElement(writer, BAD_CAST "version");
00139 xmlTextWriterSetIndent(writer, 3);
00140 xmlTextWriterWriteFormatElement(writer, BAD_CAST "date", "%d", ver->date);
00141 xmlTextWriterWriteFormatElement(writer, BAD_CAST "author", "%s", ver->author);
00142 xmlTextWriterWriteFormatElement(writer, BAD_CAST "content", "%s", ver->content->str);
00143 xmlTextWriterSetIndent(writer, 2);
00144 xmlTextWriterEndElement(writer);
00145 }
00146 xmlTextWriterSetIndent(writer, 1);
00147 xmlTextWriterEndElement(writer);
00148 }
00149 xmlTextWriterSetIndent(writer, 0);
00150 xmlTextWriterEndElement(writer);
00151 xmlTextWriterEndDocument(writer);
00152 xmlFreeTextWriter(writer);
00153 return 0;
00154 }
00155
00159 void lp_record_free(lp_record *rec)
00160 {
00161 int i;
00162 free(rec->name);
00163 for(i=0;i<g_list_length(rec->versions);i++)
00164 lp_record_ver_free(g_list_nth_data(rec->versions, i));
00165 g_list_free(rec->versions);
00166 }
00167
00171 void lp_record_ver_free(lp_record_ver *ver)
00172 {
00173 free(ver->author);
00174 g_string_free(ver->content, TRUE);
00175 }
00176