Annotation of rpm2html/rdf.c, revision 1.32

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

Webmaster