Annotation of rpm2html/rdf.c, revision 1.36

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

Webmaster