00001 #include "system.h"
00002 const char *__progname;
00003
00004 #include <rpmlib.h>
00005 #define _RPMXP_INTERNAL
00006 #include "rpmxp.h"
00007 #include "debug.h"
00008
00009 int _rpmxp_debug = 0;
00010
00011 const char * rpmxpDTD = "\
00012 <?xml version=\"1.0\"?>\n\
00013 <!DOCTYPE rpmHeader [\n\
00014 <!ELEMENT rpmHeader (rpmTag+)>\n\
00015 <!ELEMENT rpmTag (string+|integer+|base64+)>\n\
00016 <!ATTLIST rpmTag name CDATA #REQUIRED>\n\
00017 <!ELEMENT string (#PCDATA)>\n\
00018 <!ELEMENT integer (#PCDATA)>\n\
00019 <!ELEMENT base64 (#PCDATA)>\n\
00020 ]>\n\
00021 ";
00022
00023 rpmxp rpmxpFree(rpmxp xp)
00024 {
00025 if (xp != NULL) {
00026 if (xp->value) {
00027 xmlFree(xp->value);
00028 xp->value = NULL;
00029 }
00030 if (xp->name) {
00031 xmlFree(xp->name);
00032 xp->name = NULL;
00033 }
00034 if (xp->reader != NULL) {
00035 xmlFreeTextReader(xp->reader);
00036 xp->reader = NULL;
00037 }
00038 free(xp);
00039 xp = NULL;
00040 }
00041 return xp;
00042 }
00043
00044 rpmxp rpmxpNew(const char * fn)
00045 {
00046 rpmxp xp = calloc(1, sizeof(*xp));
00047
00048 if (xp == NULL)
00049 return NULL;
00050 if (fn) {
00051 int xx;
00052 xp->reader = xmlNewTextReaderFilename(fn);
00053 if (xp->reader == NULL)
00054 return rpmxpFree(xp);
00055 xx = xmlTextReaderSetParserProp(xp->reader, XML_PARSER_VALIDATE, 1);
00056 xx = xmlTextReaderSetParserProp(xp->reader, XML_PARSER_SUBST_ENTITIES, 1);
00057 }
00058 xp->name = NULL;
00059 xp->value = NULL;
00060 xp->depth = 0;
00061 xp->nodeType = 0;
00062 xp->isEmptyElement = 0;
00063 xp->n = 2;
00064 return xp;
00065 }
00066
00074 static headerTagTableEntry myTagByName(headerTagTableEntry tbl, const char * name)
00075 {
00076 int x = (strncmp(name, "RPMTAG_", (sizeof("RPMTAG_")-1))
00077 ? (sizeof("RPMTAG_")-1) : 0);
00078
00079 for (; tbl->name != NULL; tbl++) {
00080 if (!xstrcasecmp(tbl->name+x, name))
00081 return tbl;
00082 }
00083 return NULL;
00084 }
00085
00086 int rpmxpRead(rpmxp xp)
00087 {
00088 return xmlTextReaderRead(xp->reader);
00089 }
00090
00091 int rpmxpProcess(rpmxp xp)
00092 {
00093 int rc = 0;
00094
00095 xp->name = xmlTextReaderName(xp->reader);
00096 xp->value = xmlTextReaderValue(xp->reader);
00097 xp->depth = xmlTextReaderDepth(xp->reader);
00098 xp->nodeType = xmlTextReaderNodeType(xp->reader);
00099 xp->isEmptyElement = xmlTextReaderIsEmptyElement(xp->reader);
00100
00101 if (xp->name == NULL)
00102 xp->name = xmlStrdup(BAD_CAST "--");
00103
00104 if (_rpmxp_debug)
00105 printf("%d %d %s %d\n", xp->depth, xp->nodeType, xp->name, xp->isEmptyElement);
00106 switch (xp->nodeType) {
00107 case XML_READER_TYPE_ELEMENT:
00108 printf("%*s<%s", (xp->n * xp->depth), "", xp->name);
00109 while (xmlTextReaderMoveToNextAttribute(xp->reader) != 0) {
00110 xmlChar * attrN = xmlTextReaderName(xp->reader);
00111 xmlChar * attrV = xmlTextReaderValue(xp->reader);
00112 printf(" %s", attrN);
00113 if (attrV) {
00114 printf("=\"%s\"", attrV);
00115 if (!strcmp(xp->name, "rpmTag") && !strcmp(attrN, "name")) {
00116
00117 xp->tte = myTagByName(rpmTagTable, attrV);
00118 }
00119 xmlFree(attrV);
00120 }
00121 xmlFree(attrN);
00122 }
00123 if (xp->isEmptyElement) {
00124 printf("/>\n");
00125 if (xp->h && xp->tte) {
00126 headerTagTableEntry tte = xp->tte;
00127 if (!strcmp(xp->name, "string")) {
00128 const char * nstr = "";
00129 (void) headerAddOrAppendEntry(xp->h, tte->val, tte->type, &nstr, 1);
00130 } else
00131 if (!strcmp(xp->name, "integer")) {
00132 int i = 0;
00133 (void) headerAddOrAppendEntry(xp->h, tte->val, tte->type, &i, 1);
00134 }
00135 }
00136 } else {
00137 printf(">");
00138 if (xp->depth < 2)
00139 printf("\n");
00140 }
00141 if (!strcmp(xp->name, "rpmHeader")) {
00142 xp->h = headerNew();
00143 }
00144 break;
00145 case XML_READER_TYPE_END_ELEMENT:
00146 if (xp->depth < 2)
00147 printf("%*s", (xp->n * xp->depth), "");
00148 printf("</%s>\n", xp->name);
00149 if (!strcmp(xp->name, "rpmHeader")) {
00150 if (xp->h) {
00151 FD_t fdo = Fopen("time.xmlhdr", "w.ufdio");
00152 if (fdo != NULL) {
00153 headerWrite(fdo, xp->h, HEADER_MAGIC_YES);
00154 Fclose(fdo);
00155 }
00156 }
00157 xp->h = headerFree(xp->h);
00158 } else
00159 if (!strcmp(xp->name, "rpmTag")) {
00160 xp->tte = NULL;
00161 }
00162 break;
00163 case XML_READER_TYPE_TEXT:
00164 printf("%s", xp->value);
00165 if (xp->h && xp->tte) {
00166 headerTagTableEntry tte = xp->tte;
00167 switch (tte->type) {
00168 case RPM_NULL_TYPE:
00169 {
00170 } break;
00171 case RPM_CHAR_TYPE:
00172 { char c = xp->value[0];
00173 (void) headerAddOrAppendEntry(xp->h, tte->val, tte->type, &c, 1);
00174 } break;
00175 case RPM_INT8_TYPE:
00176 { int_8 i = strtol(xp->value, NULL, 0);
00177 (void) headerAddOrAppendEntry(xp->h, tte->val, tte->type, &i, 1);
00178 } break;
00179 case RPM_INT16_TYPE:
00180 { int_16 i = strtol(xp->value, NULL, 0);
00181 (void) headerAddOrAppendEntry(xp->h, tte->val, tte->type, &i, 1);
00182 } break;
00183 case RPM_INT32_TYPE:
00184 { int_32 i = strtoll(xp->value, NULL, 0);
00185 (void) headerAddOrAppendEntry(xp->h, tte->val, tte->type, &i, 1);
00186 } break;
00187 case RPM_STRING_TYPE:
00188 { const char * s = xp->value;
00189 (void) headerAddEntry(xp->h, tte->val, tte->type, s, 1);
00190 } break;
00191 case RPM_BIN_TYPE:
00192 { const char * s = xp->value;
00193 void * b;
00194 size_t nb;
00195 b64decode(s, &b, &nb);
00196 (void) headerAddEntry(xp->h, tte->val, tte->type, b, nb);
00197 } break;
00198 case RPM_STRING_ARRAY_TYPE:
00199 { const char * s = xp->value;
00200 (void) headerAddOrAppendEntry(xp->h, tte->val, tte->type, &s, 1);
00201 } break;
00202 case RPM_I18NSTRING_TYPE:
00203 { const char * s = xp->value;
00204 (void) headerAddI18NString(xp->h, tte->val, s, "C");
00205 } break;
00206 default:
00207 break;
00208 }
00209 }
00210 break;
00211 case XML_READER_TYPE_DOCUMENT_TYPE:
00212 break;
00213 case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
00214 break;
00215
00216 case XML_READER_TYPE_NONE:
00217 case XML_READER_TYPE_ATTRIBUTE:
00218 case XML_READER_TYPE_CDATA:
00219 case XML_READER_TYPE_ENTITY_REFERENCE:
00220 case XML_READER_TYPE_ENTITY:
00221 case XML_READER_TYPE_PROCESSING_INSTRUCTION:
00222 case XML_READER_TYPE_COMMENT:
00223 case XML_READER_TYPE_DOCUMENT:
00224 case XML_READER_TYPE_DOCUMENT_FRAGMENT:
00225 case XML_READER_TYPE_NOTATION:
00226 case XML_READER_TYPE_WHITESPACE:
00227 case XML_READER_TYPE_END_ENTITY:
00228 case XML_READER_TYPE_XML_DECLARATION:
00229 default:
00230 printf("%d %d %s %d\n", xp->depth, xp->nodeType,
00231 xp->name, xp->isEmptyElement);
00232 if (xp->value)
00233 printf(" %s", xp->value);
00234 if (xp->depth < 2)
00235 printf("\n");
00236 rc = -1;
00237 break;
00238 }
00239
00240 if (xp->value != NULL) {
00241 xmlFree(xp->value);
00242 xp->value = NULL;
00243 }
00244 if (xp->name != NULL) {
00245 xmlFree(xp->name);
00246 xp->name = NULL;
00247 }
00248 return rc;
00249 }
00250
00251 int rpmxpParseFile(rpmxp xp)
00252 {
00253 int ret = -1;
00254
00255 if (xp != NULL)
00256 while ((ret = rpmxpRead(xp)) == 1)
00257 rpmxpProcess(xp);
00258 return ret;
00259 }
00260
00261 int main(int argc, char ** argv)
00262 {
00263 const char * fn = "time.xml";
00264 rpmxp xp;
00265 int ec = 0;
00266
00267 xp = rpmxpNew(fn);
00268 rpmxpParseFile(xp);
00269 xp = rpmxpFree(xp);
00270
00271 return ec;
00272 }