tools/rpmxml.c

Go to the documentation of this file.
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                     /* XXX rpmSTagTable gonna be needed. */
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 }

Generated on Fri Oct 12 08:44:55 2007 for rpm by  doxygen 1.5.2