"Fossies" - the Fresh Open Source Software Archive

Member "rpm2html-1.11.2/rdf.c" (5 Oct 2010, 38014 Bytes) of package /linux/privat/rpm2html-1.11.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "rdf.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * rdf.c : implementation for the RDF encoding/decoding of RPM information.
    3  *
    4  * See Copyright for the status of this software.
    5  *
    6  * $Id: rdf.c,v 1.50 2010/10/05 14:36:54 hany Exp $
    7  */
    8 
    9 #include "config.h"
   10 #include <sys/stat.h>
   11 #ifdef HAVE_FCNTL_H
   12 #include <fcntl.h>
   13 #endif
   14 #include <stdio.h>
   15 #include <stdlib.h>
   16 #include <string.h>
   17 #ifdef HAVE_UNISTD_H
   18 #include <unistd.h>
   19 #endif
   20 #include <time.h>
   21 #include <errno.h>
   22 #include <ctype.h>
   23 #include <zlib.h>
   24 
   25 #include "rpm2html.h"
   26 #include "rpmdata.h"
   27 #include "html.h"
   28 #include "language.h"
   29 
   30 #include "rdf_api.h"
   31 #include "rdf.h"
   32 #ifdef WITH_SQL
   33 #include "sql.h"
   34 #endif
   35 
   36 #ifndef HAVE_SNPRINTF
   37 #error Sorry you really need snprintf for basic security reasons
   38 #endif
   39 
   40 /*
   41  * Open and process an RDF file in the incoming tree of an rpm2html mirror.
   42  */
   43 rpmDataPtr rpmOpenRdf(char *nameRdf, rpmDirPtr dir, rpmSubdirPtr tree) {
   44     char file[1000];
   45     rpmDataPtr rpm;
   46 #ifdef WITH_SQL
   47     int id;
   48     int i;
   49 #endif
   50 
   51     /*
   52      * create path
   53      */
   54     if (tree->htmlpath[0] != '\0')
   55     snprintf(file, sizeof(file), "%s/%s/%s", dir->rpmdir, tree->rpmpath, nameRdf);
   56     else
   57     snprintf(file, sizeof(file), "%s/%s", dir->rpmdir, nameRdf);
   58 
   59     rpm = rpmOpenRdfFile(file);
   60 
   61     if (rpm != NULL) {
   62     /* setup tree and subdir information */
   63     rpm->dir = dir;
   64     if (tree) {
   65         if ((tree->rpmpath != NULL) && (tree->rpmpath[0] != '\0'))
   66         rpm->subdir = stringAdd(tree->rpmpath);
   67         else
   68         rpm->subdir = NULL;
   69     } else
   70         rpm->subdir = NULL;
   71 
   72 #ifdef WITH_SQL
   73     id = sql_add_package(file, rpm->name, rpm->version, rpm->release,
   74             rpm->arch, dir->no, rpm->url, rpm->extra->srcrpm,
   75             dir->vendor, rpm->extra->packager,
   76             rpm->group, rpm->summary, rpm->extra->description,
   77             rpm->extra->copyright, rpm->date, rpm->size, rpm->os,
   78             rpm->distribution, rpm->vendor);
   79     if (id > 0) {
   80         for (i = 0;i < rpm->extra->nb_resources;i++)
   81         sql_add_provides(id, rpm->extra->resources[i]->name);
   82         for (i = 0;i < rpm->extra->nb_requires;i++)
   83         sql_add_requires(id, rpm->extra->requires[i]->name,
   84                      rpm->extra->requires[i]->flag,
   85                      rpm->extra->requires[i]->version);
   86     }
   87 #endif
   88 
   89     /* Add the package files to the real filesystem tree if asked for */
   90 #ifdef WITH_SQL
   91     if ((rpm->extra->filelist != NULL) &&
   92         ((dir->build_tree != 0) || (id > 0))) {
   93 #else
   94     if ((dir->build_tree != 0) && (rpm->extra->filelist != NULL)) {
   95 #endif
   96         char *cur, *filename;
   97         
   98         cur = rpm->extra->filelist;
   99         while ((*cur != '\0') && (*cur != '/')) cur++;
  100         filename = cur;
  101         while (*cur != '\0') {
  102         if ((*cur == '\n') || (*cur == '\r')) {
  103             if (cur != filename) {
  104 #ifdef WITH_SQL
  105             if (dir->build_tree != 0)
  106                 rpmAddRealFile(dir->root, filename, rpm);
  107             if (id > 0) {
  108                 *cur = 0;
  109                 sql_add_file(filename,id);
  110                 *cur = '\n';
  111             }
  112 #else
  113             rpmAddRealFile(dir->root, filename, rpm);
  114 #endif
  115             }
  116             while ((*cur != '\0') && (*cur != '/')) cur++;
  117             filename = cur;
  118         } else
  119             cur++;
  120         }
  121         if (cur != filename)
  122         rpmAddRealFile(dir->root, filename, rpm);
  123     }
  124 
  125     /* Register this package */
  126     rpmAddSoftware(rpm);
  127 
  128     /* dump the HTML related to this package */
  129     if (rpm2html_dump_html)
  130         dumpRpmHtml(rpm, tree);
  131     if (rpm2html_dump_rdf)
  132         dumpRpmRdf(rpm, tree);
  133 
  134     /* free large amount of data not used later */
  135         rpmFreeExtraData(rpm);
  136 
  137     /* increment the counters */
  138     rpm2html_files++;
  139     rpm2html_size += rpm->size / 1024;
  140     }
  141     return(rpm);
  142 }
  143 
  144 /*
  145  * Open an RDF file call the parser to create a XML tree
  146  * Then walk the tree and build an rpmData structure for
  147  * the corresponding package.
  148  */
  149 rpmDataPtr rpmOpenRdfFile(char *file) {
  150     char nameBuffer[200];
  151     rdfSchema rdf;
  152     rdfNamespace rpmNs;
  153     rdfNamespace rdfNs;
  154     rdfDescription desc;
  155     rdfBag bag;
  156     rdfElement elem;
  157     char *value;
  158     rpmDataPtr rpm;
  159     struct stat buf;
  160     int i;
  161 
  162     rdf = rdfRead(file);
  163     if (rdf == NULL) return(NULL);
  164 
  165     /*
  166      * Start the analyze, check that's an RDf for RPM packages.
  167      */
  168     rdfNs = rdfGetNamespace(rdf, "http://www.w3.org/TR/WD-rdf-syntax#");
  169     if (rdfNs == NULL) {
  170         fprintf(stderr, "%s is not an RDF schema\n", file);
  171     rdfDestroySchema(rdf);
  172     return(NULL);
  173     }
  174     rpmNs = rdfGetNamespace(rdf, "http://www.rpm.org/");
  175     if (rdfNs == NULL) {
  176         fprintf(stderr, "%s is not an RPM specific RDF schema\n", file);
  177     rdfDestroySchema(rdf);
  178     return(NULL);
  179     }
  180     desc = rdfFirstDescription(rdf);
  181     if (rdfNs == NULL) {
  182         fprintf(stderr, "%s RDF schema seems empty\n", file);
  183     rdfDestroySchema(rdf);
  184     return(NULL);
  185     }
  186 
  187     /*
  188      * We are pretty sure that it will be a valid schema,
  189      * allocate a new rpmData block, and an rpmExtraData block fill them
  190      */
  191     rpm = (rpmDataPtr) xmlMalloc(sizeof(rpmData));
  192     if (rpm == NULL) {
  193         fprintf(stderr, "cannot allocate %d bytes: %s\n", sizeof(rpmData),
  194             strerror(errno));
  195         return(NULL);
  196     }
  197     memset(rpm, 0, sizeof(rpmData));
  198     rpm->extra = (rpmExtraDataPtr) xmlMalloc(sizeof(rpmExtraData));
  199     if (rpm == NULL) {
  200         fprintf(stderr, "cannot allocate %d bytes: %s\n", sizeof(rpmExtraData),
  201             strerror(errno));
  202         return(NULL);
  203     }
  204     memset(rpm->extra, 0, sizeof(rpmExtraData));
  205 
  206     stat(file, &buf);
  207     rpm->extra->stamp = buf.st_mtime;
  208 
  209     /*
  210      * Now extract all the metadata information from the RDF tree
  211      */
  212     rdfGetValue(desc, "Name", rpmNs, &value, NULL);
  213     if (value != NULL) {
  214         rpm->name = stringAdd(value);
  215     xmlFree(value);
  216     } else {
  217         fprintf(stderr, "%s RDF schema invalid : no Name\n", file);
  218     rdfDestroySchema(rdf);
  219     return(NULL);
  220     }
  221     rdfGetValue(desc, "Version", rpmNs, &value, NULL);
  222     if (value != NULL) {
  223         rpm->version = stringAdd(value);
  224     xmlFree(value);
  225     } else {
  226         fprintf(stderr, "%s RDF schema invalid : no Version\n", file);
  227     rdfDestroySchema(rdf);
  228     return(NULL);
  229     }
  230     rdfGetValue(desc, "Release", rpmNs, &value, NULL);
  231     if (value != NULL) {
  232         rpm->release = stringAdd(value);
  233     xmlFree(value);
  234     } else {
  235         fprintf(stderr, "%s RDF schema invalid : no Release\n", file);
  236     rdfDestroySchema(rdf);
  237     return(NULL);
  238     }
  239     rdfGetValue(desc, "URL", rpmNs, &value, NULL);
  240     if (value != NULL) rpm->url = value;
  241     else rpm->url = NULL;
  242 
  243     rdfGetValue(desc, "Arch", rpmNs, &value, NULL);
  244     if (value != NULL) {
  245         rpm->arch = stringAdd(value);
  246     xmlFree(value);
  247     } else rpm->arch = xmlStrdup("noarch");
  248 
  249     rdfGetValue(desc, "Os", rpmNs, &value, NULL);
  250     if (value != NULL) {
  251         rpm->os = stringAdd(value);
  252     xmlFree(value);
  253     } else rpm->os = xmlStrdup("linux");
  254 
  255     rdfGetValue(desc, "Distribution", rpmNs, &value, NULL);
  256     if (value != NULL) {
  257         rpm->distribution = stringAdd(value);
  258     xmlFree(value);
  259     } else rpm->distribution = stringAdd(localizedStrings[LANG_UNKNOWN]);
  260 
  261     rdfGetValue(desc, "Vendor", rpmNs, &value, NULL);
  262     if (value != NULL) {
  263         rpm->vendor = stringAdd(value);
  264     xmlFree(value);
  265     } else rpm->vendor = xmlStrdup(localizedStrings[LANG_UNKNOWN]);
  266 
  267     rdfGetValue(desc, "Packager", rpmNs, &value, NULL);
  268     if (value != NULL) rpm->extra->packager = value;
  269     else rpm->extra->packager = NULL;
  270 
  271     rdfGetValue(desc, "Group", rpmNs, &value, NULL);
  272     if (value != NULL) {
  273         rpm->group = stringAdd(value);
  274     xmlFree(value);
  275     } else rpm->group = xmlStrdup(localizedStrings[LANG_NO_GROUP]);
  276     
  277     rdfGetValue(desc, "Summary", rpmNs, &value, NULL);
  278     if (value != NULL) rpm->summary = value;
  279     else rpm->summary = xmlStrdup(localizedStrings[LANG_NO_SUMMARY]);
  280 
  281     rdfGetValue(desc, "Description", rpmNs, &value, NULL);
  282     if (value != NULL) rpm->extra->description = value;
  283     else rpm->extra->description = xmlStrdup(localizedStrings[LANG_NO_DESCRIPTION]);
  284 
  285     rdfGetValue(desc, "Copyright", rpmNs, &value, NULL);
  286     if (value != NULL) rpm->extra->copyright = value;
  287     else rpm->extra->copyright = NULL;
  288 
  289     rdfGetValue(desc, "Changelog", rpmNs, &value, NULL);
  290     if (value != NULL) rpm->extra->changelog = value;
  291     else rpm->extra->changelog = NULL;
  292 
  293     rdfGetValue(desc, "Sources", rpmNs, &value, NULL);
  294     if (value != NULL) {
  295         rpm->extra->srcrpm = value;
  296     } else rpm->extra->srcrpm = xmlStrdup("");
  297 
  298     rdfGetValue(desc, "Size", rpmNs, &value, NULL);
  299     if (value != NULL) {
  300         if (sscanf(value, "%d", &(rpm->size)) != 1)
  301         rpm->size = 0;
  302     xmlFree(value);
  303     } else rpm->size = 0;
  304 
  305     rdfGetValue(desc, "Date", rpmNs, &value, NULL);
  306     if (value != NULL) {
  307         if (sscanf(value, "%d", &i) != 1)
  308         rpm->date = 0;
  309     else
  310         rpm->date = i;
  311     xmlFree(value);
  312     } else rpm->date = 0;
  313 
  314     rdfGetValue(desc, "BuildHost", rpmNs, &value, NULL);
  315     if (value != NULL) rpm->extra->host = value;
  316     else rpm->extra->host = xmlStrdup(localizedStrings[LANG_NO_HOST]);
  317 
  318     rdfGetValue(desc, "Files", rpmNs, &value, NULL);
  319     if (value != NULL) rpm->extra->filelist = value;
  320     else rpm->extra->filelist = NULL;
  321 
  322     /*
  323      * Fetching packages provided is a bit more tricky, one have to
  324      * find the RDF Bag, and scan it's values.
  325      */
  326     rpm->extra->nb_resources = 0;
  327     rdfGetValue(desc, "Provides", rpmNs, NULL, &bag);
  328     if (bag != NULL) {
  329         elem = rdfFirstChild(bag);
  330     rpm->extra->max_resources = 5;
  331     rpm->extra->resources = (rpmRessPtr *) xmlMalloc(rpm->extra->max_resources *
  332                                            sizeof(rpmRessPtr));
  333     if (rpm->extra->resources == NULL) {
  334         fprintf(stderr, "rpmOpenRdf : ran out of memory\n");
  335         exit(1);
  336     }
  337     i = 0;
  338     while (elem != NULL) {
  339         char *name; 
  340         if (i >= rpm->extra->max_resources) {
  341             rpm->extra->max_resources *= 2;
  342         rpm->extra->resources = (rpmRessPtr *) xmlRealloc(rpm->extra->resources,
  343                            rpm->extra->max_resources * sizeof(rpmRessPtr));
  344         if (rpm->extra->resources == NULL) {
  345             fprintf(stderr, "rpmOpenRdf : ran out of memory\n");
  346             exit(1);
  347         }
  348         }
  349         /*
  350          * Check that we are scanning an RPM Resource.
  351          */
  352         name = rdfElemGetPropertyName(elem);
  353         if ((name != NULL) &&
  354             (!strcmp(name, "Resource")) &&
  355             (rdfElemGetNamespace(elem) == rpmNs)) {
  356         value = rdfElemGetValue(elem);
  357         if (value != NULL) {
  358             rpm->extra->resources[i] = rpmRessAdd(value, rpm, 0);
  359             i++;
  360             rpm->extra->nb_resources++;
  361             xmlFree(value);
  362         } else if (rpm2htmlVerbose > 1) {
  363             fprintf(stderr, "%s : malformed Resource element !\n", file);
  364         }
  365         } else if (rpm2htmlVerbose > 1) {
  366             fprintf(stderr, "%s : malformed Provides bag !\n", file);
  367         }
  368         if (name != NULL) xmlFree(name);
  369         elem = rdfNextElem(elem);
  370     }
  371     } else if (rpm2htmlVerbose > 1) {
  372         fprintf(stderr, "%s doesn't export any resource\n", file);
  373     }
  374 
  375     /*
  376      * idem for the dependencies.
  377      */
  378     rpm->extra->nb_requires = 0;
  379     rdfGetValue(desc, "Requires", rpmNs, NULL, &bag);
  380     if (bag != NULL) {
  381         elem = rdfFirstChild(bag);
  382     rpm->extra->max_requires = 5;
  383     rpm->extra->requires = (rpmRessPtr *) xmlMalloc(rpm->extra->max_requires *
  384                                            sizeof(rpmRessPtr));
  385     if (rpm->extra->requires == NULL) {
  386         fprintf(stderr, "rpmOpenRdf : ran out of memory\n");
  387         exit(1);
  388     }
  389     i = 0;
  390     while (elem != NULL) {
  391         char *name; 
  392         if (i >= rpm->extra->max_requires) {
  393             rpm->extra->max_requires *= 2;
  394         rpm->extra->requires = (rpmRessPtr *) xmlRealloc(rpm->extra->requires,
  395                            rpm->extra->max_requires * sizeof(rpmRessPtr));
  396         if (rpm->extra->requires == NULL) {
  397             fprintf(stderr, "rpmOpenRdf : ran out of memory\n");
  398             exit(1);
  399         }
  400         }
  401         /*
  402          * Check that we are scanning an RPM Resource.
  403          */
  404         name = rdfElemGetPropertyName(elem);
  405         if ((name != NULL) &&
  406             (!strcmp(name, "Resource")) &&
  407             (rdfElemGetNamespace(elem) == rpmNs)) {
  408         value = rdfElemGetValue(elem);
  409         if (value != NULL) {
  410             rpm_dep_flag dep = RPM2HTML_REQ_NONE;
  411             xmlChar *reqval = NULL;
  412 
  413             if ((reqval = xmlGetProp(elem, "gt")) != NULL) {
  414             dep = RPM2HTML_REQ_GT;
  415             } else if ((reqval = xmlGetProp(elem, "geq")) != NULL) {
  416             dep = RPM2HTML_REQ_GEQ;
  417             } else if ((reqval = xmlGetProp(elem, "lt")) != NULL) {
  418             dep = RPM2HTML_REQ_LT;
  419             } else if ((reqval = xmlGetProp(elem, "leq")) != NULL) {
  420             dep = RPM2HTML_REQ_LEQ;
  421             } else if ((reqval = xmlGetProp(elem, "equ")) != NULL) {
  422             dep = RPM2HTML_REQ_EQU;
  423             }
  424 
  425             /*
  426              * TODO: fix to import RDF dept to a specific version
  427              */
  428             rpm->extra->requires[i] = rpmRequAdd(value,
  429                                              reqval, dep, rpm, 0); 
  430             i++;
  431             rpm->extra->nb_requires++;
  432             xmlFree(value);
  433             if (reqval != NULL)
  434             xmlFree(reqval);
  435         } else if (rpm2htmlVerbose > 1) {
  436             fprintf(stderr, "%s : malformed Resource element !\n", file);
  437         }
  438         } else if (rpm2htmlVerbose > 1) {
  439             fprintf(stderr, "%s : malformed Provides bag !\n", file);
  440         }
  441         if (name != NULL) xmlFree(name);
  442         elem = rdfNextElem(elem);
  443     }
  444     }
  445 
  446     /*
  447      * Finish filling the rpmData structure.
  448      */
  449     value = rdfGetDescriptionAbout(rdf, desc);
  450     if (value != NULL) {
  451         char *filename = &value[strlen(value)];
  452 
  453     while ((filename > value) && (*filename != '/'))
  454         filename --;
  455     rpm->filename = xmlStrdup(filename);
  456     xmlFree(value);
  457     } else {
  458     snprintf(nameBuffer, 200, "%s-%s-%s.%s.rpm",
  459          rpm->name, rpm->version, rpm->release, rpm->arch);
  460     rpm->filename = xmlStrdup(nameBuffer);
  461     }
  462 
  463 
  464     /*
  465      * Cleanup.
  466      */
  467     rdfDestroySchema(rdf);
  468     return(rpm);
  469 }
  470 
  471 /*
  472  * Create and RDF file containing the description for the given RPM data.
  473  */
  474 void dumpRpmRdf(rpmDataPtr rpm, rpmSubdirPtr tree) {
  475     FILE *output;
  476     struct stat stat_buf;
  477     struct tm * tstruct;
  478     rpmDirPtr dir = rpm->dir;
  479     char *base = dir->dir;
  480     int i;
  481     char buf[10000];
  482     char file[1000];
  483     char dotdot[50];
  484     char *buffer;
  485     int size;
  486     int stat_res = 0;
  487     rdfSchema rdf;
  488     rdfNamespace rpmNs;
  489     rdfDescription desc;
  490     rdfElement elem;
  491     rdfBag bag;
  492     int deep;
  493     const char *ptr;
  494 
  495     if (!rpm2html_dump_rdf) return;
  496 
  497     if (rpm2html_rdf_dir != NULL) base = rpm2html_rdf_dir;
  498 
  499     deep = 0;
  500     if (rpm->subdir != NULL)
  501     for (ptr = rpm->subdir, deep++;*ptr != 0;ptr++)
  502         if (*ptr == '/') deep++;
  503     if (dir->subdir != NULL)
  504     for (ptr = dir->subdir, deep++;*ptr != 0;ptr++)
  505         if (*ptr == '/') deep++;
  506     
  507     if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) {
  508     if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
  509         snprintf(file, sizeof(file), "%s/%s/%s/%s.rdf", base, dir->subdir,
  510                 rpm->subdir, rpmName(rpm));
  511     else
  512         snprintf(file, sizeof(file), "%s/%s/%s.rdf", base, dir->subdir, rpmName(rpm));
  513     } else {
  514     if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
  515         snprintf(file, sizeof(file), "%s/%s/%s.rdf", base, rpm->subdir, rpmName(rpm));
  516     else
  517         snprintf(file, sizeof(file), "%s/%s.rdf", base, rpmName(rpm));
  518     }
  519     dotdot[0] = '\0';
  520     for (;deep > 0;deep --)
  521     strcat(dotdot, "../");
  522 
  523     /*
  524      * Check wether the RPM timestamp is older than the filestamp.
  525     if ((stat_res = stat(file, &stat_buf)) == 0) {
  526         if (stat_buf.st_mtime > rpm->stamp) return;
  527     }
  528      */
  529     stat_res = stat(file, &stat_buf);
  530 
  531     /*
  532      * Create the directory if needed
  533      */
  534     if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) {
  535     if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
  536         snprintf(buf, sizeof(buf), "%s/%s/%s", base, dir->subdir, rpm->subdir);
  537     else
  538         snprintf(buf, sizeof(buf), "%s/%s", base, dir->subdir);
  539     } else {
  540     if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
  541         snprintf(buf, sizeof(buf), "%s/%s", base, rpm->subdir);
  542     else
  543         snprintf(buf, sizeof(buf), "%s", base);
  544     }
  545     createDirectory(buf);
  546 
  547     /*
  548      * build the RDF document tree
  549      * Note : the order is not important but following the rpmData
  550      *        structure order is easier to check.
  551      */
  552     rdf = rdfNewSchema();
  553     rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
  554 
  555     if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
  556     if (dir->mirrors[0] != NULL)
  557         snprintf(buf, sizeof(buf), "%s/%s/%s",
  558         dir->mirrors[0], rpm->subdir, rpm->filename);
  559     else
  560         snprintf(buf, sizeof(buf), "%s/%s/%s",
  561         dir->ftp, rpm->subdir, rpm->filename);
  562     } else {
  563     if (dir->mirrors[0] != NULL)
  564         snprintf(buf, sizeof(buf), "%s/%s",
  565         dir->mirrors[0], rpm->filename);
  566     else
  567         snprintf(buf, sizeof(buf), "%s/%s",
  568         dir->ftp, rpm->filename);
  569     }
  570     desc = rdfAddDescription(rdf, NULL, buf);
  571 
  572     rdfSetValue(desc, "Name", rpmNs, rpm->name);
  573     rdfSetValue(desc, "Version", rpmNs, rpm->version);
  574     rdfSetValue(desc, "Release", rpmNs, rpm->release);
  575     if (rpm->url)
  576         rdfSetValue(desc, "URL", rpmNs, rpm->url);
  577     if (rpm->arch)
  578         rdfSetValue(desc, "Arch", rpmNs, rpm->arch);
  579     if (rpm->os)
  580         rdfSetValue(desc, "Os", rpmNs, rpm->os);
  581     if (rpm->distribution)
  582         rdfSetValue(desc, "Distribution", rpmNs, rpm->distribution);
  583     if (rpm->vendor)
  584         rdfSetValue(desc, "Vendor", rpmNs, rpm->vendor);
  585     if (rpm->extra->packager)
  586         rdfSetValue(desc, "Packager", rpmNs, rpm->extra->packager);
  587     if (rpm->group)
  588         rdfSetValue(desc, "Group", rpmNs, rpm->group);
  589     if (rpm->summary)
  590     rdfSetValue(desc, "Summary", rpmNs, rpm->summary);
  591     if (rpm->extra->description)
  592     rdfSetValue(desc, "Description", rpmNs, rpm->extra->description);
  593     if (rpm->extra->copyright)
  594     rdfSetValue(desc, "Copyright", rpmNs, rpm->extra->copyright);
  595     if (rpm->extra->changelog)
  596         rdfSetValue(desc, "Changelog", rpmNs, rpm->extra->changelog);
  597     if (rpm->extra->srcrpm) {
  598     rdfSetValue(desc, "Sources", rpmNs, rpm->extra->srcrpm);
  599     if (dir->ftpsrc) {
  600         rdfSetValue(desc, "SourcesFtp", rpmNs, dir->ftpsrc);
  601     }
  602     }
  603     tstruct = localtime(&(rpm->date));
  604 #ifdef HAVE_STRFTIME
  605     strftime(buf, sizeof(buf) - 1, "%c", tstruct);
  606 #else
  607 #error "no strftime, please check !"
  608 #endif
  609     rdfSetValue(desc, "BuildDate", rpmNs, buf);
  610     snprintf(buf, sizeof(buf), "%d", (int) rpm->date);
  611     rdfSetValue(desc, "Date", rpmNs, buf);
  612     snprintf(buf, sizeof(buf), "%d", rpm->size);
  613     rdfSetValue(desc, "Size", rpmNs, buf);
  614     if (rpm->extra->host)
  615         rdfSetValue(desc, "BuildHost", rpmNs, rpm->extra->host);
  616     if (rpm->extra->nb_resources > 0) {
  617     bag = rdfBagCreate(rdf, desc, "Provides", rpmNs);
  618         for (i = 0;i < rpm->extra->nb_resources;i++) {
  619         elem = rdfBagAddValue(bag, "Resource", rpmNs,
  620                        rpm->extra->resources[i]->name, NULL);
  621         if (rpm->extra->resources[i]->name[0] != '/') {
  622         snprintf(buf, sizeof(buf) - 1, "%sresources/%s.rdf",
  623                  dotdot, rpm->extra->resources[i]->name);
  624         xmlSetProp(elem, "href", buf);
  625         }
  626         }
  627     }
  628     if (rpm->extra->nb_requires > 0) {
  629     bag = rdfBagCreate(rdf, desc, "Requires", rpmNs);
  630         for (i = 0;i < rpm->extra->nb_requires;i++) {
  631         elem = rdfBagAddValue(bag, "Resource", rpmNs,
  632                        rpm->extra->requires[i]->name, NULL);
  633         if (rpm->extra->requires[i]->name[0] != '/') {
  634         snprintf(buf, sizeof(buf) - 1, "%sresources/%s.rdf",
  635                  dotdot, rpm->extra->requires[i]->name);
  636         xmlSetProp(elem, "href", buf);
  637         }
  638         if (rpm->extra->requires[i]->version != NULL) {
  639         switch (rpm->extra->requires[i]->flag) {
  640             case RPM2HTML_REQ_LT:
  641             xmlSetProp(elem, "lt",
  642                    rpm->extra->requires[i]->version);
  643             break;
  644             case RPM2HTML_REQ_LEQ:
  645             xmlSetProp(elem, "leq",
  646                    rpm->extra->requires[i]->version);
  647             break;
  648             case RPM2HTML_REQ_GT:
  649             xmlSetProp(elem, "gt",
  650                    rpm->extra->requires[i]->version);
  651             break;
  652             case RPM2HTML_REQ_GEQ:
  653             xmlSetProp(elem, "geq",
  654                    rpm->extra->requires[i]->version);
  655             break;
  656             case RPM2HTML_REQ_EQU:
  657             xmlSetProp(elem, "equ",
  658                    rpm->extra->requires[i]->version);
  659             break;
  660             case RPM2HTML_REQ_NONE:
  661             break;
  662         }
  663         }
  664         }
  665     }
  666 
  667     if (rpm->extra->filelist)
  668         rdfSetValue(desc, "Files", rpmNs, rpm->extra->filelist);
  669 
  670     /*
  671      * Save the RDF to a buffer, remove the tree.
  672      */
  673     rdfWriteMemory(rdf, &buffer, &size);
  674     rdfDestroySchema(rdf);
  675     if (buffer == NULL) return;
  676 
  677     /*
  678      * if the file already exists avoid to overwrite it if the content
  679      * didn't change.
  680      */
  681     if ((stat_res == 0) && (stat_buf.st_size == size)) {
  682         char *buffer2 = xmlMalloc(size * sizeof(char));
  683 
  684         if (buffer2 == NULL) {
  685         fprintf(stderr, " : running out of memory\n");
  686         xmlFree(buffer);
  687         return;
  688     }
  689     output = fopen(file, "r");
  690     if (output == NULL) {
  691         fprintf(stderr, "couldn't open %s for reading !\n", file);
  692         xmlFree(buffer2);
  693         xmlFree(buffer);
  694         return;
  695     }
  696     if (fread(buffer2, size, 1, output) != 1) {
  697         fprintf(stderr, "Problem reading from %s !\n", file);
  698         xmlFree(buffer);
  699         xmlFree(buffer2);
  700     }
  701     fclose(output);
  702 
  703     /*
  704      * Now compare the content !
  705      */
  706     if (!memcmp(buffer, buffer2, size)) {
  707         xmlFree(buffer2);
  708         xmlFree(buffer);
  709         if (rpm2htmlVerbose > 1)
  710         fprintf(stderr, "File %s : Content identical !\n", file);
  711         return;
  712     }
  713     xmlFree(buffer2);
  714     }
  715 
  716     /*
  717      * Dump the file.
  718      */
  719     if (rpm2htmlVerbose > 1) {
  720         printf("Dumping %s\n", file);
  721     }
  722     output = fopen(file, "w");
  723     if (output == NULL) {
  724         fprintf(stderr, "couldn't open %s for writing !\n", file);
  725     return;
  726     }
  727     if (fwrite(buffer, size, 1, output) != 1) {
  728         fprintf(stderr, "Problem writing to %s !\n", file);
  729     }
  730     xmlFree(buffer);
  731     fclose(output);
  732 }
  733 
  734 /*
  735  * Create and RDF file containing information about a resource.
  736  */
  737 
  738 void dumpResRdf(rpmRessPtr res) {
  739     FILE *output;
  740     struct stat stat_buf;
  741     char *base;
  742     int i;
  743     char buf[10000];
  744     char file[1000];
  745     char *buffer;
  746     int size;
  747     int stat_res;
  748     rpmDataPtr rpm;
  749     rpmDirPtr dir;
  750     rdfSchema rdf;
  751     rdfNamespace rpmNs;
  752     rdfDescription desc;
  753     static int initialized = 0;
  754 
  755     if (!rpm2html_dump_rdf_resources) return;
  756 
  757     if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
  758     else return;
  759 
  760     if (res->nb_provider == 0) return;
  761 
  762     if (res->name[0] != '/')
  763         snprintf(file, sizeof(file), "%s/%s.rdf", base, res->name);
  764     else {
  765         // replace all '/' with '_' to avoid "couldn't open <base>//usr/bin/mailq.rdf for writing !"
  766 
  767         snprintf(buf, sizeof(buf), "%s", res->name);
  768         // we reuse 'buffer' as cursor here
  769         buffer = &buf[0];
  770         while (*buffer != '\0') {
  771             if (*buffer == '/')
  772                 *buffer = '_';
  773             buffer++;
  774         }
  775         snprintf(file, sizeof(file), "%s/%s.rdf", base, buf);
  776 
  777         if (rpm2htmlVerbose > 1)
  778             fprintf(stdout, "warning: '/' in resource name converted into '_': %s\n", buf);
  779     }
  780 
  781     /*
  782      * Create the directory if needed
  783      */
  784     if (!initialized) {
  785     snprintf(buf, sizeof(buf), "%s", base);
  786     createDirectory(buf);
  787         initialized = 1;
  788     }
  789 
  790     /*
  791      * build the RDF document tree
  792      * Note : the order is not important but following the rpmData
  793      *        structure order is easier to check.
  794      */
  795     rdf = rdfNewSchema();
  796     rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
  797     for (i = 0;i < res->nb_provider;i++) {
  798         rpm = res->provider[i];
  799     dir = rpm->dir;
  800     if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
  801         if (dir->mirrors[0] != NULL)
  802         snprintf(buf, sizeof(buf), "%s/%s/%s",
  803             dir->mirrors[0], rpm->subdir, rpm->filename);
  804         else
  805         snprintf(buf, sizeof(buf), "%s/%s/%s",
  806             dir->ftp, rpm->subdir, rpm->filename);
  807     } else {
  808         if (dir->mirrors[0] != NULL)
  809         snprintf(buf, sizeof(buf), "%s/%s",
  810             dir->mirrors[0], rpm->filename);
  811         else
  812         snprintf(buf, sizeof(buf), "%s/%s",
  813             dir->ftp, rpm->filename);
  814     }
  815     desc = rdfAddDescription(rdf, NULL, buf);
  816     if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) {
  817         if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
  818         snprintf(buf, sizeof(buf), "../%s/%s/%s.rdf", dir->subdir,
  819             rpm->subdir, rpmName(rpm));
  820         else
  821         snprintf(buf, sizeof(buf), "../%s/%s.rdf", dir->subdir, rpmName(rpm));
  822     } else {
  823         if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
  824         snprintf(buf, sizeof(buf), "../%s/%s.rdf", rpm->subdir, rpmName(rpm));
  825         else
  826         snprintf(buf, sizeof(buf), "../%s.rdf", rpmName(rpm));
  827     }
  828     xmlSetProp(desc, "href", buf);
  829     rdfSetValue(desc, "Name", rpmNs, rpm->name);
  830     rdfSetValue(desc, "Version", rpmNs, rpm->version);
  831     rdfSetValue(desc, "Release", rpmNs, rpm->release);
  832     if (rpm->arch)
  833         rdfSetValue(desc, "Arch", rpmNs, rpm->arch);
  834     if (rpm->os)
  835         rdfSetValue(desc, "Os", rpmNs, rpm->os);
  836     if (rpm->distribution)
  837         rdfSetValue(desc, "Distribution", rpmNs, rpm->distribution);
  838     if (rpm->vendor)
  839         rdfSetValue(desc, "Vendor", rpmNs, rpm->vendor);
  840     snprintf(buf, sizeof(buf), "%d", (int) rpm->date);
  841     rdfSetValue(desc, "Date", rpmNs, buf);
  842     snprintf(buf, sizeof(buf), "%d", (int) rpm->size);
  843     rdfSetValue(desc, "Size", rpmNs, buf);
  844     if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
  845         if ((dir->subdir != NULL) && (dir->subdir[0] != '\0'))
  846         snprintf(buf, sizeof(buf), "%s/%s",
  847             dir->subdir, rpm->subdir);
  848         else
  849         snprintf(buf, sizeof(buf), "%s",
  850             rpm->subdir);
  851     } else {
  852         if ((dir->subdir != NULL) && (dir->subdir[0] != '\0'))
  853         snprintf(buf, sizeof(buf), "%s",
  854             dir->subdir);
  855         else
  856         buf[0] = '\0';
  857     }
  858     if (buf[0] != '\0') 
  859         rdfSetValue(desc, "Subdir", rpmNs, buf);
  860     }
  861 
  862     /*
  863      * Save the RDF to a buffer, remove the tree.
  864      */
  865     rdfWriteMemory(rdf, &buffer, &size);
  866     rdfDestroySchema(rdf);
  867     if (buffer == NULL) return;
  868 
  869     /*
  870      * if the file already exists avoid to overwrite it if the content
  871      * didn't change.
  872      */
  873     stat_res = stat(file, &stat_buf);
  874 
  875     if ((stat_res == 0) && (stat_buf.st_size == size)) {
  876         char *buffer2 = xmlMalloc(size * sizeof(char));
  877 
  878         if (buffer2 == NULL) {
  879         fprintf(stderr, " : running out of memory\n");
  880         xmlFree(buffer);
  881         return;
  882     }
  883     output = fopen(file, "r");
  884     if (output == NULL) {
  885         fprintf(stderr, "couldn't open %s for reading !\n", file);
  886         xmlFree(buffer);
  887         xmlFree(buffer2);
  888         return;
  889     }
  890     if (fread(buffer2, size, 1, output) != 1) {
  891         fprintf(stderr, "Problem reading from %s !\n", file);
  892     }
  893     fclose(output);
  894 
  895     /*
  896      * Now compare the content !
  897      */
  898     if (!memcmp(buffer, buffer2, size)) {
  899         xmlFree(buffer2);
  900         xmlFree(buffer);
  901         if (rpm2htmlVerbose > 1)
  902         fprintf(stderr, "File %s : Content identical !\n", file);
  903         return;
  904     }
  905     xmlFree(buffer2);
  906     }
  907 
  908     /*
  909      * Dump the file.
  910      */
  911     if (rpm2htmlVerbose > 1) {
  912         printf("Dumping %s\n", file);
  913     }
  914     output = fopen(file, "w");
  915     if (output == NULL) {
  916         fprintf(stderr, "couldn't open %s for writing !\n", file);
  917     xmlFree(buffer);
  918     return;
  919     }
  920     if (fwrite(buffer, size, 1, output) != 1) {
  921         fprintf(stderr, "Problem writing to %s !\n", file);
  922     xmlFree(buffer);
  923     }
  924     fclose(output);
  925     xmlFree(buffer);
  926 }
  927 
  928 /*
  929  * Dump all the RDf files about known resources.
  930  */
  931 
  932 void dumpAllResRdf(void) {
  933     rpmRessPtr cur;
  934 
  935     if (!rpm2html_dump_rdf_resources) return;
  936 
  937     if (rpm2htmlVerbose)
  938       printf("Dumping resource RDF\n");
  939 
  940     cur = ressList;
  941 
  942     while (cur != NULL) {
  943         dumpResRdf(cur);
  944     cur = cur->next;
  945     }
  946 }
  947 
  948 /*
  949  * Dump an apropos RDF file for all packages.
  950  * Since the file is really too big to be kept as-if, it is compressed
  951  */
  952 
  953 void dumpAproposRdf(void) {
  954     rpmDataPtr rpm;
  955     char file[1000];
  956     char buf[1000];
  957     rdfSchema rdf;
  958     rdfNamespace rpmNs;
  959     rdfDescription desc;
  960     rpmDirPtr dir;
  961     char *base;
  962     char *buffer;
  963     int size;
  964     gzFile output;
  965     int res;
  966 
  967     if (!rpm2html_dump_rdf_resources) return;
  968 
  969     if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
  970     else return;
  971 
  972     if (rpm2htmlVerbose)
  973       printf("Dumping apropos RDF\n");
  974 
  975     snprintf(file, sizeof(file), "%s/fullIndex.rdf.gz", base);
  976     if (rpm2htmlVerbose > 1) {
  977         printf("Dumping %s\n", file);
  978     }
  979 
  980     /*
  981      * build the RDF document tree, one only dump the minimum needed
  982      * for searching.
  983      */
  984     rdf = rdfNewSchema();
  985     rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
  986 
  987     rpm = rpmSoftwareList;
  988 
  989     while (rpm != NULL) {
  990     dir = rpm->dir;
  991     if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
  992         if (dir->mirrors[0] != NULL)
  993         snprintf(buf, sizeof(buf), "%s/%s/%s",
  994             dir->mirrors[0], rpm->subdir, rpm->filename);
  995         else
  996         snprintf(buf, sizeof(buf), "%s/%s/%s",
  997             dir->ftp, rpm->subdir, rpm->filename);
  998     } else {
  999         if (dir->mirrors[0] != NULL)
 1000         snprintf(buf, sizeof(buf), "%s/%s",
 1001             dir->mirrors[0], rpm->filename);
 1002         else
 1003         snprintf(buf, sizeof(buf), "%s/%s",
 1004             dir->ftp, rpm->filename);
 1005     }
 1006     desc = rdfAddDescription(rdf, NULL, buf);
 1007     rdfSetValue(desc, "Name", rpmNs, rpm->name);
 1008     rdfSetValue(desc, "Summary", rpmNs, rpm->summary);
 1009     rpm = rpm->nextSoft;
 1010     }
 1011 
 1012     /*
 1013      * Dump the RDF tree, and cleanup.
 1014      */
 1015     rdfWriteMemory(rdf, &buffer, &size);
 1016     rdfDestroySchema(rdf);
 1017     if (buffer == NULL) return;
 1018 
 1019     /*
 1020      * Write the compressed version of the RDF base.
 1021      */
 1022     output = gzopen(file, "w9");
 1023     if (output == NULL) {
 1024         fprintf(stderr, "Could not write %s : gzopen failed\n", file);
 1025     xmlFree(buffer);
 1026     return;
 1027     }
 1028     res = gzwrite(output, buffer, size);
 1029     if (res <= 0) {
 1030         fprintf(stderr, "Could not write %s : gzwrite failed\n", file);
 1031     xmlFree(buffer);
 1032     return;
 1033     }
 1034     gzclose(output);
 1035     xmlFree(buffer);
 1036 }
 1037 
 1038 /*
 1039  * Dump the distribs/xxx.rdf file giving information about a
 1040  * specific distribution
 1041  */
 1042 
 1043 void dumpDistRdf(rpmDirPtr dir) {
 1044     char buf[101] = "";
 1045     char file[1000];
 1046     rdfSchema rdf;
 1047     rdfNamespace rpmNs;
 1048     rdfDescription desc;
 1049     rdfBag mirrors;
 1050     rdfElement mirror;
 1051     struct stat stat_buf;
 1052     int stat_res;
 1053     char *base, *ptr;
 1054     char *buffer;
 1055     int size;
 1056     FILE *output;
 1057     int i;
 1058 
 1059     if (!rpm2html_dump_rdf_resources) return;
 1060 
 1061     if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
 1062     else return;
 1063 
 1064     if (dir->subdir)
 1065     snprintf(buf, sizeof(buf), "%s", dir->subdir);
 1066     for (ptr = &buf[0]; *ptr; ptr++) if (*ptr == '/') *ptr = '_';
 1067     snprintf(file, sizeof(file), "%s/distribs", base);
 1068     createDirectory(file);
 1069     snprintf(file, sizeof(file), "%s/distribs/%s.rdf", base, buf);
 1070 
 1071     /*
 1072      * build the RDF document tree, one only dump the minimum needed
 1073      * for searching distributions information.
 1074      */
 1075     rdf = rdfNewSchema();
 1076     rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
 1077 
 1078     desc = rdfAddDescription(rdf, NULL, dir->ftp);
 1079     rdfSetValue(desc, "ID", rpmNs, dir->subdir);
 1080     rdfSetValue(desc, "Name", rpmNs, dir->name);
 1081     rdfSetValue(desc, "Origin", rpmNs, dir->ftp);
 1082     rdfSetValue(desc, "Sources", rpmNs, dir->ftpsrc);
 1083     snprintf(buf, sizeof(buf), "%d", dir->files);
 1084     mirrors = rdfBagCreate(rdf, desc, "Mirrors", rpmNs);
 1085     for (i = 0;i < dir->nb_mirrors;i++) {
 1086     mirror = rdfBagAddValue(mirrors, "Mirror", rpmNs, NULL, NULL);
 1087     rdfSetElementResource(rdf, mirror, dir->mirrors[i]);
 1088     }
 1089 
 1090     /*
 1091      * Dump the RDF tree, and cleanup.
 1092      */
 1093     rdfWriteMemory(rdf, &buffer, &size);
 1094     rdfDestroySchema(rdf);
 1095     if (buffer == NULL) return;
 1096 
 1097     /*
 1098      * if the file already exists avoid to overwrite it if the content
 1099      * didn't change.
 1100      */
 1101     stat_res = stat(file, &stat_buf);
 1102 
 1103     if ((stat_res == 0) && (stat_buf.st_size == size)) {
 1104         char *buffer2 = xmlMalloc(size * sizeof(char));
 1105 
 1106         if (buffer2 == NULL) {
 1107         fprintf(stderr, " : running out of memory\n");
 1108         xmlFree(buffer);
 1109         return;
 1110     }
 1111     output = fopen(file, "r");
 1112     if (output == NULL) {
 1113         fprintf(stderr, "couldn't open %s for reading !\n", file);
 1114         xmlFree(buffer2);
 1115         xmlFree(buffer);
 1116         return;
 1117     }
 1118     if (fread(buffer2, size, 1, output) != 1) {
 1119         fprintf(stderr, "Problem reading from %s !\n", file);
 1120     }
 1121     fclose(output);
 1122 
 1123     /*
 1124      * Now compare the content !
 1125      */
 1126     if (!memcmp(buffer, buffer2, size)) {
 1127         xmlFree(buffer2);
 1128         xmlFree(buffer);
 1129         if (rpm2htmlVerbose > 1)
 1130         fprintf(stderr, "File %s : Content identical !\n", file);
 1131         return;
 1132     }
 1133     xmlFree(buffer2);
 1134     }
 1135 
 1136     /*
 1137      * Dump the file.
 1138      */
 1139     if (rpm2htmlVerbose > 1) {
 1140         printf("Dumping %s\n", file);
 1141     }
 1142     output = fopen(file, "w");
 1143     if (output == NULL) {
 1144         fprintf(stderr, "couldn't open %s for writing !\n", file);
 1145     xmlFree(buffer);
 1146     return;
 1147     }
 1148     if (fwrite(buffer, size, 1, output) != 1) {
 1149         fprintf(stderr, "Problem writing to %s !\n", file);
 1150     xmlFree(buffer);
 1151     }
 1152     fclose(output);
 1153     xmlFree(buffer);
 1154 }
 1155 
 1156 /*
 1157  * Dump the distribs/metadata.rdf file listing all the recognized
 1158  * metadata mirrors sites.
 1159  */
 1160 
 1161 void dumpMetadataListRdf(void) {
 1162     char file[1000];
 1163     rdfSchema rdf;
 1164     rdfNamespace rpmNs;
 1165     rdfDescription desc;
 1166     struct stat stat_buf;
 1167     int stat_res;
 1168     char *base;
 1169     char *buffer;
 1170     int size;
 1171     FILE *output;
 1172     int i;
 1173 
 1174     if (!rpm2html_dump_rdf_resources) return;
 1175 
 1176     if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
 1177     else return;
 1178 
 1179     snprintf(file, sizeof(file), "%s/distribs", base);
 1180     createDirectory(file);
 1181     snprintf(file, sizeof(file), "%s/distribs/metadata.rdf", base);
 1182 
 1183     /*
 1184      * build the RDF document tree, one only dump the minimum needed
 1185      * for searching distributions information.
 1186      */
 1187     rdf = rdfNewSchema();
 1188     rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
 1189 
 1190     for (i = 0;i < nb_metadata_mirrors;i++){
 1191         desc = rdfAddDescription(rdf, NULL, metadata_mirrors[i]);
 1192     rdfSetValue(desc, "URI", rpmNs, metadata_mirrors[i]);
 1193     }
 1194 
 1195     /*
 1196      * Dump the RDF tree, and cleanup.
 1197      */
 1198     rdfWriteMemory(rdf, &buffer, &size);
 1199     rdfDestroySchema(rdf);
 1200     if (buffer == NULL) return;
 1201 
 1202     /*
 1203      * if the file already exists avoid to overwrite it if the content
 1204      * didn't change.
 1205      */
 1206     stat_res = stat(file, &stat_buf);
 1207 
 1208     if ((stat_res == 0) && (stat_buf.st_size == size)) {
 1209         char *buffer2 = xmlMalloc(size * sizeof(char));
 1210 
 1211         if (buffer2 == NULL) {
 1212         fprintf(stderr, " : running out of memory\n");
 1213         xmlFree(buffer);
 1214         return;
 1215     }
 1216     output = fopen(file, "r");
 1217     if (output == NULL) {
 1218         fprintf(stderr, "couldn't open %s for reading !\n", file);
 1219         xmlFree(buffer);
 1220         xmlFree(buffer2);
 1221         return;
 1222     }
 1223     if (fread(buffer2, size, 1, output) != 1) {
 1224         fprintf(stderr, "Problem reading from %s !\n", file);
 1225     }
 1226     fclose(output);
 1227 
 1228     /*
 1229      * Now compare the content !
 1230      */
 1231     if (!memcmp(buffer, buffer2, size)) {
 1232         xmlFree(buffer2);
 1233         xmlFree(buffer);
 1234         if (rpm2htmlVerbose > 1)
 1235         fprintf(stderr, "File %s : Content identical !\n", file);
 1236         return;
 1237     }
 1238     xmlFree(buffer2);
 1239     }
 1240 
 1241     /*
 1242      * Dump the file.
 1243      */
 1244     if (rpm2htmlVerbose > 1) {
 1245         printf("Dumping %s\n", file);
 1246     }
 1247     output = fopen(file, "w");
 1248     if (output == NULL) {
 1249         fprintf(stderr, "couldn't open %s for writing !\n", file);
 1250     return;
 1251     }
 1252     if (fwrite(buffer, size, 1, output) != 1) {
 1253         fprintf(stderr, "Problem writing to %s !\n", file);
 1254     }
 1255     fclose(output);
 1256     xmlFree(buffer);
 1257 }
 1258 
 1259 /*
 1260  * Dump the distribs/list.rdf file listing all the recognized distributions
 1261  * as well as the metadata mirrors list.
 1262  */
 1263 
 1264 void dumpDistListRdf(void) {
 1265     rpmDirPtr dir;
 1266     char file[1000];
 1267     rdfSchema rdf;
 1268     rdfNamespace rpmNs;
 1269     rdfDescription desc;
 1270     struct stat stat_buf;
 1271     int stat_res;
 1272     char *base;
 1273     char *buffer;
 1274     int size;
 1275     FILE *output;
 1276 
 1277     if (!rpm2html_dump_rdf_resources) return;
 1278 
 1279     if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
 1280     else return;
 1281 
 1282     if (rpm2htmlVerbose)
 1283       printf("Dumping distribution RDF\n");
 1284 
 1285     dumpMetadataListRdf();
 1286 
 1287     snprintf(file, sizeof(file), "%s/distribs", base);
 1288     createDirectory(file);
 1289     snprintf(file, sizeof(file), "%s/distribs/list.rdf", base);
 1290 
 1291     /*
 1292      * build the RDF document tree, one only dump the minimum needed
 1293      * for searching distributions information.
 1294      */
 1295     rdf = rdfNewSchema();
 1296     rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
 1297 
 1298     dir = dirList;
 1299     while (dir != NULL) {
 1300         desc = rdfAddDescription(rdf, NULL, dir->ftp);
 1301     rdfSetValue(desc, "ID", rpmNs, dir->subdir);
 1302     dumpDistRdf(dir);
 1303         dir = dir->next;
 1304     }
 1305     /*
 1306      * Dump the RDF tree, and cleanup.
 1307      */
 1308     rdfWriteMemory(rdf, &buffer, &size);
 1309     rdfDestroySchema(rdf);
 1310     if (buffer == NULL) return;
 1311 
 1312     /*
 1313      * if the file already exists avoid to overwrite it if the content
 1314      * didn't change.
 1315      */
 1316     stat_res = stat(file, &stat_buf);
 1317 
 1318     if ((stat_res == 0) && (stat_buf.st_size == size)) {
 1319         char *buffer2 = xmlMalloc(size * sizeof(char));
 1320 
 1321         if (buffer2 == NULL) {
 1322         fprintf(stderr, " : running out of memory\n");
 1323         xmlFree(buffer);
 1324         return;
 1325     }
 1326     output = fopen(file, "r");
 1327     if (output == NULL) {
 1328         fprintf(stderr, "couldn't open %s for reading !\n", file);
 1329         xmlFree(buffer);
 1330         xmlFree(buffer2);
 1331         return;
 1332     }
 1333     if (fread(buffer2, size, 1, output) != 1) {
 1334         fprintf(stderr, "Problem reading from %s !\n", file);
 1335     }
 1336     fclose(output);
 1337 
 1338     /*
 1339      * Now compare the content !
 1340      */
 1341     if (!memcmp(buffer, buffer2, size)) {
 1342         xmlFree(buffer2);
 1343         xmlFree(buffer);
 1344         if (rpm2htmlVerbose > 1)
 1345         fprintf(stderr, "File %s : Content identical !\n", file);
 1346         return;
 1347     }
 1348     xmlFree(buffer2);
 1349     }
 1350 
 1351     /*
 1352      * Dump the file.
 1353      */
 1354     if (rpm2htmlVerbose > 1) {
 1355         printf("Dumping %s\n", file);
 1356     }
 1357     output = fopen(file, "w");
 1358     if (output == NULL) {
 1359         fprintf(stderr, "couldn't open %s for writing !\n", file);
 1360     return;
 1361     }
 1362     if (fwrite(buffer, size, 1, output) != 1) {
 1363         fprintf(stderr, "Problem writing to %s !\n", file);
 1364     }
 1365     fclose(output);
 1366     xmlFree(buffer);
 1367 }
 1368