Annotation of rpm2html/rdf.c, revision 1.16

1.1       httpng      1: /*
                      2:  * rdf.c : implementation for the RDF encoding/decoding of RPM informations.
                      3:  */
                      4: 
1.2       httpng      5: #include "config.h"
1.6       veillard    6: #include <sys/stat.h>
1.2       httpng      7: #ifdef HAVE_FCNTL_H
                      8: #include <fcntl.h>
                      9: #endif
                     10: #include <stdio.h>
                     11: #include <stdlib.h>
                     12: #include <string.h>
                     13: #ifdef HAVE_UNISTD_H
                     14: #include <unistd.h>
                     15: #endif
                     16: #include <time.h>
1.1       httpng     17: #include <errno.h>
1.2       httpng     18: #include <ctype.h>
1.1       httpng     19: 
                     20: #include "rpm2html.h"
                     21: #include "rpmdata.h"
1.4       veillard   22: #include "html.h"
1.7       veillard   23: #include "language.h"
1.4       veillard   24: 
                     25: #include "rdf_api.h"
1.1       httpng     26: #include "rdf.h"
                     27: 
                     28: /*
1.16    ! veillard   29:  * Open and process an RDF file in the incoming tree of an rpm2html mirror.
        !            30:  */
        !            31: rpmDataPtr rpmOpenRdf(char *nameRdf, rpmDirPtr dir, rpmSubdirPtr tree) {
        !            32:     char file[1000];
        !            33:     rpmDataPtr rpm;
        !            34: 
        !            35:     /*
        !            36:      * create path
        !            37:      */
        !            38:     if (tree->htmlpath[0] != '\0')
        !            39:        sprintf(file, "%s/%s/%s", dir->rpmdir, tree->rpmpath, nameRdf);
        !            40:     else
        !            41:        sprintf(file, "%s/%s", dir->rpmdir, nameRdf);
        !            42: 
        !            43:     rpm = rpmOpenRdfFile(file);
        !            44: 
        !            45:     if (rpm != NULL) {
        !            46:        /* setup tree and subdir informations */
        !            47:        rpm->dir = dir;
        !            48:        if (tree) {
        !            49:            if ((tree->rpmpath != NULL) && (tree->rpmpath[0] != '\0'))
        !            50:                rpm->subdir = strdup(tree->rpmpath);
        !            51:            else
        !            52:                rpm->subdir = NULL;
        !            53:        } else
        !            54:            rpm->subdir = NULL;
        !            55: 
        !            56:        /* Add the package files to the real filesystem tree if asked for */
        !            57:        if ((dir->build_tree != 0) && (rpm->filelist != NULL)) {
        !            58:            char *cur, *filename;
        !            59:            
        !            60:            cur = rpm->filelist;
        !            61:            while ((*cur != '\0') && (*cur != '/')) cur++;
        !            62:            filename = cur;
        !            63:            while (*cur != '\0') {
        !            64:                if ((*cur == '\n') || (*cur == '\r')) {
        !            65:                    if (cur != filename)
        !            66:                        rpmAddRealFile(dir->root, filename, rpm);
        !            67:                    while ((*cur != '\0') && (*cur != '/')) cur++;
        !            68:                    filename = cur;
        !            69:                } else
        !            70:                    cur++;
        !            71:            }
        !            72:            if (cur != filename)
        !            73:                rpmAddRealFile(dir->root, filename, rpm);
        !            74:        }
        !            75: 
        !            76:        /* Register this package */
        !            77:        rpmAddSoftware(rpm);
        !            78: 
        !            79:        /* dump the HTML related to this package */
        !            80:        if (rpm2html_dump_html)
        !            81:            dumpRpmHtml(rpm, tree);
        !            82:        if (rpm2html_dump_rdf)
        !            83:            dumpRpmRdf(rpm, tree);
        !            84: 
        !            85:        /* free large amount of data not used later */
        !            86:        if (rpm->filelist) free(rpm->filelist);
        !            87:        rpm->filelist = NULL;
        !            88:        if (rpm->copyright) free(rpm->copyright);
        !            89:        rpm->copyright = NULL;
        !            90:        if (rpm->changelog) free(rpm->changelog);
        !            91:        rpm->changelog = NULL;
        !            92:        if (rpm->description) free(rpm->description);
        !            93:        rpm->description = NULL;
        !            94: 
        !            95:        /* increment the counters */
        !            96:        rpm2html_files++;
        !            97:        rpm2html_size += rpm->size / 1024;
        !            98:     }
        !            99:     return(rpm);
        !           100: }
        !           101: 
        !           102: /*
1.1       httpng    103:  * Open an RDF file call the parser to create a XML tree
                    104:  * Then walk the tree and build an rpmData structure for
                    105:  * the corresponding package.
                    106:  */
1.16    ! veillard  107: rpmDataPtr rpmOpenRdfFile(char *file) {
1.6       veillard  108:     char nameBuffer[200];
1.5       veillard  109:     rdfSchema rdf;
                    110:     rdfNamespace rpmNs;
                    111:     rdfNamespace rdfNs;
                    112:     rdfDescription desc;
                    113:     rdfBag bag;
1.7       veillard  114:     rdfElement elem;
1.5       veillard  115:     char *value;
                    116:     rpmDataPtr rpm;
1.6       veillard  117:     struct stat buf;
1.7       veillard  118:     int i;
1.5       veillard  119: 
                    120:     rdf = rdfRead(file);
                    121:     if (rdf == NULL) return(NULL);
                    122: 
                    123:     /*
                    124:      * Start the analyze, check that's an RDf for RPM packages.
                    125:      */
                    126:     rdfNs = rdfGetNamespace(rdf, "http://www.w3.org/TR/WD-rdf-syntax#");
                    127:     if (rdfNs == NULL) {
                    128:         fprintf(stderr, "%s is not an RDF schema\n", file);
                    129:        rdfDestroySchema(rdf);
                    130:        return(NULL);
                    131:     }
                    132:     rpmNs = rdfGetNamespace(rdf, "http://www.rpm.org/");
                    133:     if (rdfNs == NULL) {
                    134:         fprintf(stderr, "%s is not an RPM specific RDF schema\n", file);
                    135:        rdfDestroySchema(rdf);
                    136:        return(NULL);
                    137:     }
                    138:     desc = rdfFirstDescription(rdf);
                    139:     if (rdfNs == NULL) {
                    140:         fprintf(stderr, "%s RDF schema seems empty\n", file);
                    141:        rdfDestroySchema(rdf);
                    142:        return(NULL);
                    143:     }
                    144: 
                    145:     /*
                    146:      * We are pretty sure that it will be a valid schema,
1.6       veillard  147:      * Allocate the rpmData structure, initialize it.
1.5       veillard  148:      */
                    149:     rpm = (rpmDataPtr) malloc(sizeof(rpmData));
                    150:     if (rpm == NULL) {
                    151:         fprintf(stderr, "rpmOpenRdf : out of memory !\n");
                    152:        rdfDestroySchema(rdf);
                    153:        return(NULL);
                    154:     }
1.6       veillard  155:     memset(rpm, 0, sizeof(rpmData));
1.5       veillard  156: 
1.6       veillard  157:     stat(file, &buf);
                    158:     rpm->stamp = buf.st_mtime;
                    159: 
                    160:     /*
                    161:      * Now extract all the metadata informations from the RDF tree
                    162:      */
1.5       veillard  163:     rdfGetValue(desc, "Name", rpmNs, &value, NULL);
                    164:     if (value != NULL) rpm->name = strdup(value);
                    165:     else {
                    166:         fprintf(stderr, "%s RDF schema invalid : no Name\n", file);
                    167:        rdfDestroySchema(rdf);
                    168:        return(NULL);
                    169:     }
                    170:     rdfGetValue(desc, "Version", rpmNs, &value, NULL);
                    171:     if (value != NULL) rpm->version = strdup(value);
                    172:     else {
                    173:         fprintf(stderr, "%s RDF schema invalid : no Version\n", file);
                    174:        rdfDestroySchema(rdf);
                    175:        return(NULL);
                    176:     }
                    177:     rdfGetValue(desc, "Release", rpmNs, &value, NULL);
                    178:     if (value != NULL) rpm->release = strdup(value);
                    179:     else {
                    180:         fprintf(stderr, "%s RDF schema invalid : no Release\n", file);
                    181:        rdfDestroySchema(rdf);
                    182:        return(NULL);
                    183:     }
                    184:     rdfGetValue(desc, "URL", rpmNs, &value, NULL);
                    185:     if (value != NULL) rpm->url = strdup(value);
1.7       veillard  186:     else rpm->url = NULL;
                    187: 
1.5       veillard  188:     rdfGetValue(desc, "Arch", rpmNs, &value, NULL);
                    189:     if (value != NULL) rpm->arch = strdup(value);
1.7       veillard  190:     else rpm->arch = strdup(localizedStrings[LANG_NONE]);
                    191: 
1.5       veillard  192:     rdfGetValue(desc, "Os", rpmNs, &value, NULL);
                    193:     if (value != NULL) rpm->os = strdup(value);
1.7       veillard  194:     else rpm->os = strdup("linux");
                    195: 
1.5       veillard  196:     rdfGetValue(desc, "Distribution", rpmNs, &value, NULL);
                    197:     if (value != NULL) rpm->distribution = strdup(value);
1.7       veillard  198:     else rpm->distribution = strdup(localizedStrings[LANG_UNKNOWN]);
                    199: 
1.5       veillard  200:     rdfGetValue(desc, "Vendor", rpmNs, &value, NULL);
                    201:     if (value != NULL) rpm->vendor = strdup(value);
1.7       veillard  202:     else rpm->vendor = strdup(localizedStrings[LANG_UNKNOWN]);
                    203: 
1.5       veillard  204:     rdfGetValue(desc, "Packager", rpmNs, &value, NULL);
                    205:     if (value != NULL) rpm->packager = strdup(value);
1.7       veillard  206:     else rpm->packager = NULL;
                    207: 
1.5       veillard  208:     rdfGetValue(desc, "Group", rpmNs, &value, NULL);
                    209:     if (value != NULL) rpm->group = strdup(value);
1.7       veillard  210:     else rpm->group = strdup(localizedStrings[LANG_NO_GROUP]);
                    211:     
1.5       veillard  212:     rdfGetValue(desc, "Summary", rpmNs, &value, NULL);
                    213:     if (value != NULL) rpm->summary = strdup(value);
1.7       veillard  214:     else rpm->summary = strdup(localizedStrings[LANG_NO_SUMMARY]);
                    215: 
1.5       veillard  216:     rdfGetValue(desc, "Description", rpmNs, &value, NULL);
                    217:     if (value != NULL) rpm->description = strdup(value);
1.7       veillard  218:     else rpm->description = strdup(localizedStrings[LANG_NO_DESCRIPTION]);
                    219: 
1.5       veillard  220:     rdfGetValue(desc, "Copyright", rpmNs, &value, NULL);
                    221:     if (value != NULL) rpm->copyright = strdup(value);
1.7       veillard  222:     else rpm->copyright = NULL;
                    223: 
1.5       veillard  224:     rdfGetValue(desc, "Changelog", rpmNs, &value, NULL);
                    225:     if (value != NULL) rpm->changelog = strdup(value);
1.7       veillard  226:     else rpm->changelog = NULL;
                    227: 
                    228:     rdfGetValue(desc, "Sources", rpmNs, &value, NULL);
                    229:     if (value != NULL) {
                    230:         rpm->srcrpm = strdup(value);
                    231:     } else rpm->srcrpm = strdup("");
                    232: 
                    233:     rdfGetValue(desc, "Size", rpmNs, &value, NULL);
                    234:     if (value != NULL) {
                    235:         if (sscanf(value, "%d", &(rpm->size)) != 1)
                    236:            rpm->size = 0;
                    237:     } else rpm->size = 0;
                    238: 
                    239:     rdfGetValue(desc, "Date", rpmNs, &value, NULL);
                    240:     if (value != NULL) {
1.8       veillard  241:         if (sscanf(value, "%d", &i) != 1)
1.7       veillard  242:            rpm->date = 0;
1.8       veillard  243:        else
                    244:            rpm->date = i;
1.7       veillard  245:     } else rpm->date = 0;
                    246: 
                    247:     rdfGetValue(desc, "BuildHost", rpmNs, &value, NULL);
                    248:     if (value != NULL) rpm->host = strdup(value);
                    249:     else rpm->host = strdup(localizedStrings[LANG_NO_HOST]);
                    250: 
                    251:     rdfGetValue(desc, "Files", rpmNs, &value, NULL);
                    252:     if (value != NULL) rpm->filelist = strdup(value);
                    253:     else rpm->filelist = NULL;
                    254: 
                    255:     /*
                    256:      * Fetching packages provided is a bit more tricky, one have to
                    257:      * find the RDF Bag, and scan it's values.
                    258:      */
                    259:     rpm->nb_resources = 0;
                    260:     rdfGetValue(desc, "Provides", rpmNs, NULL, &bag);
                    261:     if (bag != NULL) {
                    262:         elem = rdfFirstChild(bag);
1.11      veillard  263:        rpm->max_resources = 5;
                    264:        rpm->resources = (rpmRessPtr *) malloc(rpm->max_resources *
                    265:                                               sizeof(rpmRessPtr));
                    266:        if (rpm->resources == NULL) {
                    267:            fprintf(stderr, "rpmOpenRdf : ran out of memory\n");
                    268:            exit(1);
                    269:        }
1.7       veillard  270:        i = 0;
                    271:        while (elem != NULL) {
1.11      veillard  272:            if (i >= rpm->max_resources) {
                    273:                rpm->max_resources *= 2;
                    274:                rpm->resources = (rpmRessPtr *) realloc(rpm->resources,
                    275:                                   rpm->max_resources * sizeof(rpmRessPtr));
                    276:                if (rpm->resources == NULL) {
                    277:                    fprintf(stderr, "rpmOpenRdf : ran out of memory\n");
                    278:                    exit(1);
                    279:                }
1.7       veillard  280:            }
                    281:            /*
                    282:             * Check that we are scanning an RPM Resource.
                    283:             */
                    284:            if ((!strcmp(rdfElemGetPropertyName(elem), "Resource")) &&
                    285:                (rdfElemGetNamespace(elem) == rpmNs)) {
                    286:                value = rdfElemGetValue(elem);
                    287:                if (value != NULL) {
                    288:                    rpm->resources[i] = rpmRessAdd(value, rpm, 0);
                    289:                    i++;
                    290:                    rpm->nb_resources++;
1.8       veillard  291:                } else if (verbose > 1) {
1.7       veillard  292:                    fprintf(stderr, "%s : malformed Resource element !\n", file);
                    293:                }
1.8       veillard  294:            } else if (verbose > 1) {
1.7       veillard  295:                fprintf(stderr, "%s : malformed Provides bag !\n", file);
                    296:            }
                    297:            elem = rdfNextElem(elem);
                    298:        }
1.8       veillard  299:     } else if (verbose > 1) {
1.7       veillard  300:         fprintf(stderr, "%s doesn't export any resource\n", file);
                    301:     }
                    302: 
                    303:     /*
                    304:      * idem for the dependencies.
                    305:      */
                    306:     rpm->nb_requires = 0;
                    307:     rdfGetValue(desc, "Requires", rpmNs, NULL, &bag);
                    308:     if (bag != NULL) {
                    309:         elem = rdfFirstChild(bag);
1.11      veillard  310:        rpm->max_requires = 5;
                    311:        rpm->requires = (rpmRessPtr *) malloc(rpm->max_requires *
                    312:                                               sizeof(rpmRessPtr));
                    313:        if (rpm->requires == NULL) {
                    314:            fprintf(stderr, "rpmOpenRdf : ran out of memory\n");
                    315:            exit(1);
                    316:        }
1.7       veillard  317:        i = 0;
                    318:        while (elem != NULL) {
1.11      veillard  319:            if (i >= rpm->max_requires) {
                    320:                rpm->max_requires *= 2;
                    321:                rpm->requires = (rpmRessPtr *) realloc(rpm->requires,
                    322:                                   rpm->max_requires * sizeof(rpmRessPtr));
                    323:                if (rpm->requires == NULL) {
                    324:                    fprintf(stderr, "rpmOpenRdf : ran out of memory\n");
                    325:                    exit(1);
                    326:                }
1.7       veillard  327:            }
                    328:            /*
                    329:             * Check that we are scanning an RPM Resource.
                    330:             */
                    331:            if ((!strcmp(rdfElemGetPropertyName(elem), "Resource")) &&
                    332:                (rdfElemGetNamespace(elem) == rpmNs)) {
                    333:                value = rdfElemGetValue(elem);
                    334:                if (value != NULL) {
                    335:                    rpm->requires[i] = rpmRequAdd(value, rpm, 0);
                    336:                    i++;
                    337:                    rpm->nb_requires++;
1.8       veillard  338:                } else if (verbose > 1) {
1.7       veillard  339:                    fprintf(stderr, "%s : malformed Resource element !\n", file);
                    340:                }
1.8       veillard  341:            } else if (verbose > 1) {
1.7       veillard  342:                fprintf(stderr, "%s : malformed Provides bag !\n", file);
                    343:            }
                    344:            elem = rdfNextElem(elem);
                    345:        }
                    346:     }
1.5       veillard  347: 
1.6       veillard  348:     /*
                    349:      * Finish filling the rpmData structure.
                    350:      */
                    351: #ifdef HAVE_SNPRINTF
                    352:     sprintf(nameBuffer, "%s-%s-%s.rpm",
                    353:             rpm->name, rpm->version, rpm->release);
                    354: #else
                    355:     snprintf(nameBuffer, 200, "%s-%s-%s.rpm",
                    356:              rpm->name, rpm->version, rpm->release);
                    357: #endif
                    358:     rpm->filename = strdup(nameBuffer);
                    359: 
                    360: 
                    361:     /*
                    362:      * Cleanup.
                    363:      */
1.5       veillard  364:     rdfDestroySchema(rdf);
                    365:     return(rpm);
1.1       httpng    366: }
                    367: 
                    368: /*
1.4       veillard  369:  * Create and RDF file containing the description for the given RPM data.
1.1       httpng    370:  */
                    371: void dumpRpmRdf(rpmDataPtr rpm, rpmSubdirPtr tree) {
1.12      veillard  372:     FILE *output;
                    373:     struct stat stat_buf;
1.1       httpng    374:     struct tm * tstruct;
                    375:     rpmDirPtr dir = rpm->dir;
1.3       veillard  376:     char *base = dir->dir;
1.1       httpng    377:     int i;
1.4       veillard  378:     char buf[10000];
                    379:     char file[1000];
1.12      veillard  380:     char *buffer;
                    381:     int size;
                    382:     int stat_res;
1.4       veillard  383:     rdfSchema rdf;
                    384:     rdfNamespace rpmNs;
                    385:     rdfDescription desc;
                    386:     rdfBag bag;
1.1       httpng    387: 
1.7       veillard  388:     if (!rpm2html_dump_rdf) return;
                    389: 
1.3       veillard  390:     if (rpm2html_rdf_dir != NULL) base = rpm2html_rdf_dir;
                    391: 
1.1       httpng    392:     if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) {
                    393:        if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
1.4       veillard  394:            sprintf(file, "%s/%s/%s/%s.rdf", base, dir->subdir,
1.1       httpng    395:                    rpm->subdir, rpmName(rpm));
                    396:        else
1.4       veillard  397:            sprintf(file, "%s/%s/%s.rdf", base, dir->subdir, rpmName(rpm));
1.1       httpng    398:     } else {
                    399:        if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
1.4       veillard  400:            sprintf(file, "%s/%s/%s.rdf", base, rpm->subdir, rpmName(rpm));
1.1       httpng    401:        else
1.4       veillard  402:            sprintf(file, "%s/%s.rdf", base, rpmName(rpm));
1.1       httpng    403:     }
                    404: 
1.12      veillard  405:     /*
                    406:      * Check wether the RPM timestamp is older than the filestamp.
                    407:      */
                    408:     if ((stat_res = stat(file, &stat_buf)) == 0) {
                    409:         if (stat_buf.st_mtime > rpm->stamp) return;
                    410:     }
1.9       veillard  411: 
                    412:     /*
                    413:      * Create the directory if needed
                    414:      */
                    415:     if ((dir->subdir != NULL) && (dir->subdir[0] != '\0')) {
                    416:        if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
                    417:            sprintf(buf, "%s/%s/%s", base, dir->subdir, rpm->subdir);
                    418:        else
                    419:            sprintf(buf, "%s/%s", base, dir->subdir);
                    420:     } else {
                    421:        if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0'))
                    422:            sprintf(buf, "%s/%s", base, rpm->subdir);
                    423:        else
                    424:            sprintf(buf, "%s", base);
                    425:     }
                    426:     createDirectory(buf);
                    427: 
1.4       veillard  428:     /*
                    429:      * build the RDF document tree
                    430:      * Note : the order is not important but following the rpmData
                    431:      *        structure order is easier to check.
                    432:      */
                    433:     rdf = rdfNewSchema();
                    434:     rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
                    435: 
1.2       httpng    436:     if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
                    437:        if (dir->mirrors[0] != NULL)
1.4       veillard  438:            sprintf(buf, "%s/%s/%s",
1.2       httpng    439:                dir->mirrors[0], rpm->subdir, rpm->filename);
                    440:        else
1.4       veillard  441:            sprintf(buf, "%s/%s/%s",
1.2       httpng    442:                dir->ftp, rpm->subdir, rpm->filename);
                    443:     } else {
                    444:        if (dir->mirrors[0] != NULL)
1.4       veillard  445:            sprintf(buf, "%s/%s",
1.2       httpng    446:                dir->mirrors[0], rpm->filename);
                    447:        else
1.4       veillard  448:            sprintf(buf, "%s/%s",
1.2       httpng    449:                dir->ftp, rpm->filename);
                    450:     }
1.4       veillard  451:     desc = rdfAddDescription(rdf, NULL, buf);
                    452: 
                    453:     rdfSetValue(desc, "Name", rpmNs, rpm->name);
                    454:     rdfSetValue(desc, "Version", rpmNs, rpm->version);
                    455:     rdfSetValue(desc, "Release", rpmNs, rpm->release);
                    456:     if (rpm->url)
                    457:         rdfSetValue(desc, "URL", rpmNs, rpm->url);
                    458:     if (rpm->arch)
                    459:         rdfSetValue(desc, "Arch", rpmNs, rpm->arch);
                    460:     if (rpm->os)
                    461:         rdfSetValue(desc, "Os", rpmNs, rpm->os);
1.2       httpng    462:     if (rpm->distribution)
1.4       veillard  463:         rdfSetValue(desc, "Distribution", rpmNs, rpm->distribution);
1.2       httpng    464:     if (rpm->vendor)
1.4       veillard  465:         rdfSetValue(desc, "Vendor", rpmNs, rpm->vendor);
                    466:     if (rpm->packager)
                    467:         rdfSetValue(desc, "Packager", rpmNs, rpm->packager);
                    468:     if (rpm->group)
                    469:         rdfSetValue(desc, "Group", rpmNs, rpm->group);
                    470:     if (rpm->summary)
                    471:        rdfSetValue(desc, "Summary", rpmNs, rpm->summary);
                    472:     if (rpm->description)
                    473:        rdfSetValue(desc, "Description", rpmNs, rpm->description);
                    474:     if (rpm->copyright)
                    475:        rdfSetValue(desc, "Copyright", rpmNs, rpm->copyright);
                    476:     if (rpm->changelog)
                    477:         rdfSetValue(desc, "Changelog", rpmNs, rpm->changelog);
                    478:     if (rpm->srcrpm) {
1.7       veillard  479:        rdfSetValue(desc, "Sources", rpmNs, rpm->srcrpm);
1.4       veillard  480:        if (dir->ftpsrc) {
1.7       veillard  481:            rdfSetValue(desc, "SourcesFtp", rpmNs, dir->ftpsrc);
1.4       veillard  482:        }
                    483:     }
1.2       httpng    484:     tstruct = localtime(&(rpm->date));
                    485: #ifdef HAVE_STRFTIME
                    486:     strftime(buf, sizeof(buf) - 1, "%c", tstruct);
                    487: #else
                    488: #error "no strftime, please check !"
                    489: #endif
1.4       veillard  490:     rdfSetValue(desc, "BuildDate", rpmNs, buf);
1.12      veillard  491:     sprintf(buf, "%d", (int) rpm->date);
1.10      veillard  492:     rdfSetValue(desc, "Date", rpmNs, buf);
1.4       veillard  493:     sprintf(buf, "%d", rpm->size);
                    494:     rdfSetValue(desc, "Size", rpmNs, buf);
1.2       httpng    495:     if (rpm->host)
1.4       veillard  496:         rdfSetValue(desc, "BuildHost", rpmNs, rpm->host);
1.2       httpng    497:     if (rpm->nb_resources > 0) {
1.7       veillard  498:        /** !!!!!
                    499:        sprintf(buf, "%d", rpm->nb_resources);
                    500:        rdfSetValue(desc, "NbProvides", rpmNs, buf);
                    501:         */
1.4       veillard  502:        bag = rdfBagCreate(rdf, desc, "Provides", rpmNs);
1.2       httpng    503:         for (i = 0;i < rpm->nb_resources;i++) {
1.4       veillard  504:            rdfBagAddValue(bag, "Resource", rpmNs,
                    505:                           rpm->resources[i]->name, NULL);
1.2       httpng    506:         }
                    507:     }
                    508:     if (rpm->nb_requires > 0) {
1.7       veillard  509:        /** !!!!!
                    510:         sprintf(buf, "%d", rpm->nb_requires);
                    511:        rdfSetValue(desc, "NbRequires", rpmNs, buf);
                    512:         */
1.4       veillard  513:        bag = rdfBagCreate(rdf, desc, "Requires", rpmNs);
1.2       httpng    514:         for (i = 0;i < rpm->nb_requires;i++) {
1.4       veillard  515:            rdfBagAddValue(bag, "Resource", rpmNs,
                    516:                           rpm->requires[i]->name, NULL);
1.2       httpng    517:         }
                    518:     }
                    519:     if (rpm->filelist)
1.4       veillard  520:         rdfSetValue(desc, "Files", rpmNs, rpm->filelist);
                    521: 
                    522:     /*
1.12      veillard  523:      * Save the RDF to a buffer, remove the tree.
1.4       veillard  524:      */
1.12      veillard  525:     rdfWriteMemory(rdf, &buffer, &size);
1.4       veillard  526:     rdfDestroySchema(rdf);
1.12      veillard  527: 
                    528:     /*
                    529:      * if the file already exists avoid to overwrite it if the content
                    530:      * didn't change.
                    531:      */
                    532:     if ((stat_res == 0) && (stat_buf.st_size == size)) {
                    533:         char *buffer2 = malloc(size * sizeof(char));
                    534: 
                    535:         if (buffer2 == NULL) {
                    536:            fprintf(stderr, " : running out of memory\n");
                    537:            return;
                    538:        }
                    539:        output = fopen(file, "r");
                    540:        if (output == NULL) {
                    541:            fprintf(stderr, "couldn't open %s for reading !\n", file);
                    542:            return;
                    543:        }
                    544:        if (fread(buffer2, size, 1, output) != 1) {
                    545:            fprintf(stderr, "Problem reading from %s !\n", file);
                    546:        }
                    547:        fclose(output);
                    548: 
                    549:        /*
                    550:         * Now compare the content !
                    551:         */
                    552:        if (!memcmp(buffer, buffer2, size)) {
                    553:            free(buffer2);
                    554:            if (verbose > 1)
                    555:                fprintf(stderr, "File %s : Content identical !\n", file);
                    556:            return;
                    557:        }
                    558:        free(buffer2);
                    559:     }
                    560: 
                    561:     /*
                    562:      * Dump the file.
                    563:      */
                    564:     if (verbose > 1) {
                    565:         printf("Dumping %s\n", file);
                    566:     }
                    567:     output = fopen(file, "w");
                    568:     if (output == NULL) {
                    569:         fprintf(stderr, "couldn't open %s for writing !\n", file);
                    570:        return;
                    571:     }
                    572:     if (fwrite(buffer, size, 1, output) != 1) {
                    573:         fprintf(stderr, "Problem writing to %s !\n", file);
                    574:     }
                    575:     fclose(output);
1.1       httpng    576: }
                    577: 
1.13      veillard  578: /*
                    579:  * Create and RDF file containing informations about a resource.
                    580:  */
                    581: 
                    582: void dumpResRdf(rpmRessPtr res) {
                    583:     FILE *output;
                    584:     struct stat stat_buf;
                    585:     char *base;
                    586:     int i;
                    587:     char buf[10000];
                    588:     char file[1000];
                    589:     char *buffer;
                    590:     int size;
                    591:     int stat_res;
                    592:     rpmDataPtr rpm;
                    593:     rpmDirPtr dir;
                    594:     rdfSchema rdf;
                    595:     rdfNamespace rpmNs;
                    596:     rdfDescription desc;
                    597:     static int initialized = 0;
                    598: 
                    599:     if (!rpm2html_dump_rdf_resources) return;
                    600: 
                    601:     if (rpm2html_rdf_resources_dir != NULL) base = rpm2html_rdf_resources_dir;
                    602:     else return;
                    603: 
                    604:     if (res->nb_provider == 0) return;
                    605: 
1.15      veillard  606:     sprintf(file, "%s/%s.rdf", base, res->name);
                    607:     fprintf(stderr, "%s\n", res->name);
1.13      veillard  608: 
                    609:     /*
                    610:      * Create the directory if needed
                    611:      */
                    612:     if (!initialized) {
                    613:        sprintf(buf, "%s", base);
                    614:        createDirectory(buf);
                    615:         initialized = 1;
                    616:     }
                    617: 
                    618:     /*
                    619:      * build the RDF document tree
                    620:      * Note : the order is not important but following the rpmData
                    621:      *        structure order is easier to check.
                    622:      */
                    623:     rdf = rdfNewSchema();
                    624:     rpmNs = rdfNewNamespace(rdf, "http://www.rpm.org/", "RPM");
                    625: 
                    626:     for (i = 0;i < res->nb_provider;i++) {
                    627:         rpm = res->provider[i];
                    628:        dir = rpm->dir;
                    629:        if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
                    630:            if (dir->mirrors[0] != NULL)
                    631:                sprintf(buf, "%s/%s/%s",
                    632:                    dir->mirrors[0], rpm->subdir, rpm->filename);
                    633:            else
                    634:                sprintf(buf, "%s/%s/%s",
                    635:                    dir->ftp, rpm->subdir, rpm->filename);
                    636:        } else {
                    637:            if (dir->mirrors[0] != NULL)
                    638:                sprintf(buf, "%s/%s",
                    639:                    dir->mirrors[0], rpm->filename);
                    640:            else
                    641:                sprintf(buf, "%s/%s",
                    642:                    dir->ftp, rpm->filename);
                    643:        }
                    644:        desc = rdfAddDescription(rdf, NULL, buf);
                    645:        rdfSetValue(desc, "Name", rpmNs, rpm->name);
                    646:        rdfSetValue(desc, "Version", rpmNs, rpm->version);
                    647:        rdfSetValue(desc, "Release", rpmNs, rpm->release);
                    648:        if (rpm->arch)
                    649:            rdfSetValue(desc, "Arch", rpmNs, rpm->arch);
                    650:        if (rpm->os)
                    651:            rdfSetValue(desc, "Os", rpmNs, rpm->os);
                    652:        if (rpm->distribution)
                    653:            rdfSetValue(desc, "Distribution", rpmNs, rpm->distribution);
                    654:        if (rpm->vendor)
                    655:            rdfSetValue(desc, "Vendor", rpmNs, rpm->vendor);
                    656:        sprintf(buf, "%d", (int) rpm->date);
                    657:        rdfSetValue(desc, "Date", rpmNs, buf);
1.14      httpng    658:        if ((rpm->subdir != NULL) && (rpm->subdir[0] != '\0')) {
                    659:            if ((dir->subdir != NULL) && (dir->subdir[0] != '\0'))
                    660:                sprintf(buf, "%s/%s",
                    661:                    dir->subdir, rpm->subdir);
                    662:            else
                    663:                sprintf(buf, "%s",
                    664:                    rpm->subdir);
                    665:        } else {
                    666:            if ((dir->subdir != NULL) && (dir->subdir[0] != '\0'))
                    667:                sprintf(buf, "%s",
                    668:                    dir->subdir);
                    669:            else
                    670:                buf[0] = '\0';
                    671:        }
                    672:        if (buf[0] != '\0') 
                    673:            rdfSetValue(desc, "Subdir", rpmNs, buf);
1.13      veillard  674:     }
                    675: 
                    676:     /*
                    677:      * Save the RDF to a buffer, remove the tree.
                    678:      */
                    679:     rdfWriteMemory(rdf, &buffer, &size);
                    680:     rdfDestroySchema(rdf);
                    681: 
                    682:     /*
                    683:      * if the file already exists avoid to overwrite it if the content
                    684:      * didn't change.
                    685:      */
                    686:     stat_res = stat(file, &stat_buf);
                    687: 
                    688:     if ((stat_res == 0) && (stat_buf.st_size == size)) {
                    689:         char *buffer2 = malloc(size * sizeof(char));
                    690: 
                    691:         if (buffer2 == NULL) {
                    692:            fprintf(stderr, " : running out of memory\n");
                    693:            return;
                    694:        }
                    695:        output = fopen(file, "r");
                    696:        if (output == NULL) {
                    697:            fprintf(stderr, "couldn't open %s for reading !\n", file);
                    698:            return;
                    699:        }
                    700:        if (fread(buffer2, size, 1, output) != 1) {
                    701:            fprintf(stderr, "Problem reading from %s !\n", file);
                    702:        }
                    703:        fclose(output);
                    704: 
                    705:        /*
                    706:         * Now compare the content !
                    707:         */
                    708:        if (!memcmp(buffer, buffer2, size)) {
                    709:            free(buffer2);
                    710:            if (verbose > 1)
                    711:                fprintf(stderr, "File %s : Content identical !\n", file);
                    712:            return;
                    713:        }
                    714:        free(buffer2);
                    715:     }
                    716: 
                    717:     /*
                    718:      * Dump the file.
                    719:      */
                    720:     if (verbose > 1) {
                    721:         printf("Dumping %s\n", file);
                    722:     }
1.15      veillard  723:         fprintf(stderr, "Dumping %s\n", file);
1.13      veillard  724:     output = fopen(file, "w");
                    725:     if (output == NULL) {
                    726:         fprintf(stderr, "couldn't open %s for writing !\n", file);
                    727:        return;
                    728:     }
                    729:     if (fwrite(buffer, size, 1, output) != 1) {
                    730:         fprintf(stderr, "Problem writing to %s !\n", file);
                    731:     }
                    732:     fclose(output);
                    733: }
                    734: 
                    735: /*
                    736:  * Dump all the RDf files about known resources.
                    737:  */
                    738: 
                    739: void dumpAllResRdf(void) {
                    740:     rpmRessPtr cur;
                    741: 
                    742:     if (!rpm2html_dump_rdf_resources) return;
                    743: 
                    744:     cur = ressList;
                    745: 
                    746:     while (cur != NULL) {
                    747:         dumpResRdf(cur);
                    748:        cur = cur->next;
                    749:     }
                    750: }
                    751: 

Webmaster