Annotation of rpm2html/rdf.c, revision 1.39

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

Webmaster