Annotation of rpm2html/rpmopen.c, revision 1.35

1.1       veillard    1: /*
                      2:  * rpmopen.c : open an extract informations from RPM files.
                      3:  *
1.11      veillard    4:  * Copyright (c) 1997 Daniel Veillard <veillard@apocalypse.org>
1.9       veillard    5:  * See COPYING for the status of this software.
1.1       veillard    6:  *
1.35    ! veillard    7:  * $Id: rpmopen.c,v 1.34 1998/03/13 07:30:13 veillard Exp $
1.1       veillard    8:  */
                      9: 
1.9       veillard   10: #include <config.h>
1.1       veillard   11: #include <sys/types.h>
                     12: #include <sys/stat.h>
1.9       veillard   13: #ifdef HAVE_FCNTL_H
1.1       veillard   14: #include <fcntl.h>
1.9       veillard   15: #endif
1.1       veillard   16: #include <stdio.h>
                     17: #include <stdlib.h>
                     18: #include <string.h>
1.9       veillard   19: #ifdef HAVE_UNISTD_H
1.1       veillard   20: #include <unistd.h>
1.9       veillard   21: #endif
1.6       veillard   22: #include <dirent.h>
1.13      veillard   23: #include <errno.h>
1.31      veillard   24: #include <time.h>
1.1       veillard   25: 
                     26: #include <rpm/rpmlib.h>
                     27: 
                     28: #include "rpmdata.h"
1.7       veillard   29: #include "html.h"
1.8       veillard   30: #include "rpm2html.h"
1.12      veillard   31: #include "language.h"
1.1       veillard   32: 
                     33: /*
                     34:  * Get the internal number associated to an RPM tag.
                     35:  */
                     36: static int getTagNumber(char *tag) {
                     37:     int i;
                     38:     const struct headerTagTableEntry * t;
                     39: 
                     40:     for (i = 0, t = rpmTagTable; i < rpmTagTableSize; i++, t++) {
                     41:        if (!strcasecmp(tag, t->name)) return(t->val);
                     42:     }
                     43:     fprintf(stderr, "getTagNumber(%s) : unknown tag !\n", tag);
                     44:     return(-1);
                     45: }
                     46: 
                     47: /*
1.11      veillard   48:  * rpmAnalyze : analyze an RPM record, read and parse the header and 
                     49:  *              fill the informations in the database.
1.1       veillard   50:  */
1.32      veillard   51: rpmDataPtr rpmAnalyze(char *nameRpm, Header h, rpmDirPtr dir, const char *subdir,
                     52:                       time_t stamp) {
1.11      veillard   53:     int installed = dir->installbase;
1.2       veillard   54:     char * name = NULL, * version = NULL, * release = NULL;
1.1       veillard   55:     int_32 count, type;
1.2       veillard   56:     void * p = NULL;
1.10      veillard   57:     int val, i, j;
1.1       veillard   58:     rpmDataPtr rpm = NULL;
1.5       veillard   59:     static char buffer[500000];
1.11      veillard   60:     static char nameBuffer[500];
1.1       veillard   61: 
                     62:     /* extract informations from the header */
                     63:     headerGetEntry(h, RPMTAG_NAME, &type, (void **) &name, &count);
                     64:     headerGetEntry(h, RPMTAG_VERSION, &type, (void **) &version, &count);
                     65:     headerGetEntry(h, RPMTAG_RELEASE, &type, (void **) &release, &count);
                     66:         
                     67:     /* allocate a new rpmData block, fill it */
                     68:     rpm = (rpmDataPtr) malloc(sizeof(rpmData));
1.15      veillard   69:     memset(rpm, 0, sizeof(rpmData));
1.1       veillard   70:     if (rpm == NULL) {
                     71:          fprintf(stderr, "cannot allocate %d bytes: %s\n", sizeof(rpmData),
                     72:                 strerror(errno));
1.32      veillard   73:          return(NULL);
1.1       veillard   74:     }
1.6       veillard   75:     rpm->dir = dir;
1.24      veillard   76:     rpm->subdir = strdup(subdir);
1.20      veillard   77:     rpm->stamp = stamp;
1.1       veillard   78:     rpm->name = strdup(name);
                     79:     rpm->version = strdup(version);
                     80:     rpm->release = strdup(release);
                     81: 
1.26      veillard   82:     /* get all the resources provided by this RPM */
1.2       veillard   83:     if (!headerGetEntry(h, RPMTAG_SUMMARY, &type, &p, &count) || !p) {
1.27      veillard   84:         rpm->summary = strdup(localizedStrings[LANG_NO_SUMMARY]);
1.2       veillard   85:     } else {
1.19      veillard   86:        rpm->summary = strdupHTML((char *) p);
1.2       veillard   87:     }
1.28      veillard   88:     if (!headerGetEntry(h, RPMTAG_DESCRIPTION, &type, &p, &count) || !p ||
                     89:         (type != RPM_STRING_TYPE)) {
1.27      veillard   90:         rpm->description = strdup(localizedStrings[LANG_NO_DESCRIPTION]);
1.2       veillard   91:     } else {
1.19      veillard   92:        rpm->description = strdupHTML((char *) p);
1.2       veillard   93:     }
1.28      veillard   94:     if (!headerGetEntry(h, RPMTAG_DISTRIBUTION, &type, &p, &count) || !p ||
                     95:         (type != RPM_STRING_TYPE)) {
1.27      veillard   96:         rpm->distribution = strdup(localizedStrings[LANG_UNKNOWN]);
1.2       veillard   97:     } else {
                     98:        rpm->distribution = strdup((char *) p);
                     99:     }
1.28      veillard  100:     if (!headerGetEntry(h, RPMTAG_ARCH, &type, &p, &count) || !p ||
                    101:         (type != RPM_STRING_TYPE)) {
1.29      veillard  102:        if (type == RPM_INT8_TYPE) {
                    103:            /*
1.32      veillard  104:             * Old packages.
1.29      veillard  105:             */
                    106:            switch (*((char *) p)) {
                    107:                case 1:
                    108:                    rpm->arch = strdup("i386");
                    109:                    break;
                    110:                default:
                    111:                    rpm->arch = strdup("i386");
                    112:                    break;
                    113:            }
                    114:        } else
                    115:            rpm->arch = strdup(localizedStrings[LANG_NONE]);
1.11      veillard  116:        if (nameRpm == NULL) {
1.12      veillard  117:            sprintf(nameBuffer, "%s-%s-%s.rpm", name, version, release);
1.11      veillard  118:            nameRpm = nameBuffer;
                    119:        }
1.2       veillard  120:     } else {
                    121:        rpm->arch = strdup((char *) p);
1.11      veillard  122:        if (nameRpm == NULL) {
1.12      veillard  123:            sprintf(nameBuffer, "%s-%s-%s.%s.rpm",
                    124:                    name, version, release, (char *)p);
1.11      veillard  125:            nameRpm = nameBuffer;
                    126:        }
1.2       veillard  127:     }
1.28      veillard  128:     if (!headerGetEntry(h, RPMTAG_OS, &type, &p, &count) || !p ||
                    129:         (type != RPM_STRING_TYPE)) {
1.29      veillard  130:        if (type == RPM_INT8_TYPE) {
                    131:            /*
1.32      veillard  132:             * Old packages.
1.29      veillard  133:             */
                    134:            switch (*((char *) p)) {
                    135:                case 1:
                    136:                    rpm->os = strdup("linux");
                    137:                    break;
                    138:                default:
                    139:                    rpm->os = strdup("linux");
                    140:                    break;
                    141:            }
                    142:        } else
                    143:            rpm->os = strdup("");
1.7       veillard  144:     } else {
                    145:        rpm->os = strdup((char *) p);
                    146:     }
1.28      veillard  147:     if (!headerGetEntry(h, RPMTAG_VENDOR, &type, &p, &count) || !p ||
                    148:         (type != RPM_STRING_TYPE)) {
1.7       veillard  149:         rpm->vendor = NULL;
1.2       veillard  150:     } else {
                    151:        rpm->vendor = strdup((char *) p);
                    152:     }
1.28      veillard  153:     if (!headerGetEntry(h, RPMTAG_GROUP, &type, &p, &count) || !p ||
                    154:         (type != RPM_STRING_TYPE)) {
1.27      veillard  155:         rpm->group = strdup(localizedStrings[LANG_NO_GROUP]);
1.2       veillard  156:     } else {
                    157:        rpm->group = strdup((char *) p);
                    158:     }
1.28      veillard  159:     if (!headerGetEntry(h, RPMTAG_BUILDHOST, &type, &p, &count) || !p ||
                    160:         (type != RPM_STRING_TYPE)) {
1.27      veillard  161:         rpm->host = strdup(localizedStrings[LANG_NO_HOST]);
1.2       veillard  162:     } else {
                    163:        rpm->host = strdup((char *) p);
                    164:     }
                    165:     if (!headerGetEntry(h, RPMTAG_SIZE, &type, &p, &count) || !p) {
                    166:         rpm->size = 0;
                    167:     } else {
                    168:        rpm->size = *((int *) p);
                    169:     }
1.11      veillard  170:     if (installed) {
                    171:        if (!headerGetEntry(h, RPMTAG_INSTALLTIME, &type, &p, &count) || !p) {
                    172:            rpm->date = 0;
                    173:        } else {
                    174:            rpm->date = *((int_32 *) p);
                    175:        }
1.2       veillard  176:     } else {
1.11      veillard  177:        if (!headerGetEntry(h, RPMTAG_BUILDTIME, &type, &p, &count) || !p) {
                    178:            rpm->date = 0;
                    179:        } else {
                    180:            rpm->date = *((int_32 *) p);
                    181:        }
1.2       veillard  182:     }
1.28      veillard  183:     if (!headerGetEntry(h, RPMTAG_SOURCERPM, &type, &p, &count) || !p ||
                    184:         (type != RPM_STRING_TYPE)) {
1.27      veillard  185:         rpm->srcrpm = strdup("");
1.2       veillard  186:     } else {
                    187:        rpm->srcrpm = strdup((char *) p);
                    188:     }
1.28      veillard  189:     if (!headerGetEntry(h, RPMTAG_URL, &type, &p, &count) || !p ||
                    190:         (type != RPM_STRING_TYPE)) {
1.7       veillard  191:         rpm->url = NULL;
                    192:     } else {
                    193:        rpm->url = strdup((char *) p);
                    194:     }
1.28      veillard  195:     if (!headerGetEntry(h, RPMTAG_PACKAGER, &type, &p, &count) || !p ||
                    196:         (type != RPM_STRING_TYPE)) {
1.7       veillard  197:         rpm->packager = NULL;
                    198:     } else {
                    199:        rpm->packager = strdup((char *) p);
                    200:     }
1.28      veillard  201:     if (!headerGetEntry(h, RPMTAG_COPYRIGHT, &type, &p, &count) || !p ||
                    202:         (type != RPM_STRING_TYPE)) {
1.7       veillard  203:         rpm->copyright = NULL;
                    204:     } else {
                    205:        rpm->copyright = strdup((char *) p);
                    206:     }
1.31      veillard  207:     /* Pick up changelog entries */
                    208:     if (!headerGetEntry(h, RPMTAG_CHANGELOGTEXT, &type, &p, &count) || !p) {
                    209:         rpm->changelog = NULL;
                    210:     } else {
                    211:       time_t *dates;
                    212:       char **names;
                    213:       char **holdp = (char **)p;
                    214:       char *cp;
                    215:       struct tm *tm_buf;
                    216:       int i, len, pos;
                    217:       char date_string[50];
                    218:       char *res = buffer;
                    219:       *res = '\0';
                    220:       headerGetEntry(h, RPMTAG_CHANGELOGTIME, &type, (void *)&dates, &count);
                    221:       headerGetEntry(h, RPMTAG_CHANGELOGNAME, &type, (void *)&names, &count);
                    222:       for (i = 0;  i < count;  i++) {
                    223:        tm_buf = localtime(&dates[i]);
                    224:         strftime(date_string, sizeof(date_string) - 1, "%a %b %d %Y", tm_buf);
                    225:        len = sprintf(res, "* %s %s\n", date_string, names[i]);
                    226:        res += len;
                    227:        cp = holdp[i];
                    228:        pos = 0;
                    229:        while (*cp) {
                    230:          if (pos++ == 0) {
                    231:            *res++ = ' ';
                    232:            *res++ = ' ';           
                    233:          }
                    234:          *res++ = *cp;
                    235:          if (*cp++ == '\n') pos = 0;
                    236:        }
                    237:        *res++ = '\n';
                    238:       }
                    239:       *res = '\0';
                    240:       rpm->changelog = strdup(buffer);
                    241:     }
1.7       veillard  242:     if (rpm->vendor == NULL) {
1.15      veillard  243:         if (rpm->packager != NULL) rpm->vendor = strdup(rpm->packager);
                    244:        else rpm->vendor = strdup(localizedStrings[LANG_UNKNOWN]);
1.7       veillard  245:     }
1.2       veillard  246: 
1.11      veillard  247:     rpm->filename = strdup(nameRpm);
                    248: 
1.26      veillard  249:     /* package-xxx.rpm provides the resource "package" */
                    250:     rpm->nb_resources = 1;
                    251:     rpm->resources[0] = rpmRessAdd(name, rpm, installed);
1.10      veillard  252: 
1.1       veillard  253:     val = getTagNumber("RPMTAG_PROVIDES");
                    254:     if (!headerGetEntry(h, val, &type, &p, &count) || !p) {
1.26      veillard  255:         rpm->nb_resources = 1;
1.1       veillard  256:     } else {
1.26      veillard  257:        if (count >= MAX_RES) {
                    258:            fprintf(stderr, "MAX_RES %d overflow, increase the limit!\n",
                    259:                    MAX_RES);
                    260:            count = MAX_RES;
1.1       veillard  261:        }
                    262: 
1.26      veillard  263:         for (i = 0, j = rpm->nb_resources; i < count;j++, i++) {
                    264:            rpm->resources[j] = rpmRessAdd(((char **) p)[i], rpm, installed);
1.4       veillard  265:        }
1.26      veillard  266:        rpm->nb_resources += count;
1.4       veillard  267:     }
                    268: 
                    269:     val = getTagNumber("RPMTAG_REQUIRENAME");
                    270:     if (!headerGetEntry(h, val, &type, &p, &count) || !p) {
                    271:         rpm->nb_requires = 0;
                    272:     } else {
                    273:        if (count >= MAX_REQU) {
                    274:            fprintf(stderr, "MAX_REQU %d overflow, increase the limit!\n",
                    275:                    MAX_REQU);
                    276:            count = MAX_REQU;
                    277:        }
                    278: 
                    279:        rpm->nb_requires = count;
                    280:         for (i = 0; i < count;i++) {
1.11      veillard  281:            rpm->requires[i] = rpmRequAdd(((char **) p)[i], rpm, installed);
1.1       veillard  282:        }
1.5       veillard  283:     }
                    284:     val = getTagNumber("RPMTAG_FILENAMES");
                    285:     if (!headerGetEntry(h, val, &type, &p, &count) || !p) {
1.7       veillard  286:         rpm->filelist = NULL; /* No filelist in the package ! */
1.5       veillard  287:     } else {
                    288:         char *ptr = buffer;
                    289:        for (i = 0; i < count;i++) {
                    290:            ptr += sprintf(ptr, "%s\n", ((char **) p)[i]);
                    291:        }
                    292:        rpm->filelist = strdup(buffer);
1.1       veillard  293:     }
                    294: 
1.32      veillard  295:     /* insert the package informations in the database
1.11      veillard  296:     if (installed) {
                    297:        rpm->next = rpmInstalledList;
                    298:        rpmInstalledList = rpm;
                    299:     } else {
                    300:        rpm->next = rpmList;
                    301:        rpmList = rpm;
1.32      veillard  302:     } */
1.17      veillard  303: 
                    304:     /* Register this package */
                    305:     rpmAddSoftware(rpm);
1.7       veillard  306: 
                    307:     /* dump the HTML related to this package */
                    308:     dumpRpmHtml(rpm);
                    309: 
                    310:     /* free large amount of data not used later */
                    311:     if (rpm->filelist) free(rpm->filelist);
1.15      veillard  312:     rpm->filelist = NULL;
1.7       veillard  313:     if (rpm->copyright) free(rpm->copyright);
1.15      veillard  314:     rpm->copyright = NULL;
1.31      veillard  315:     if (rpm->changelog) free(rpm->changelog);
                    316:     rpm->changelog = NULL;
1.15      veillard  317:     if (rpm->description) free(rpm->description);
                    318:     rpm->description = NULL;
1.8       veillard  319: 
                    320:     /* increment the counters */
1.11      veillard  321:     if (installed) {
                    322:        rpm2html_install_files++;
1.21      veillard  323:        rpm2html_install_size += rpm->size / 1024;
1.11      veillard  324:     } else {
                    325:        rpm2html_files++;
1.21      veillard  326:        rpm2html_size += rpm->size / 1024;
1.11      veillard  327:     }
1.7       veillard  328: 
1.32      veillard  329:     return(rpm);
1.11      veillard  330: }
                    331: 
                    332: /*
                    333:  * rpmOpen : open an RPM file, read and parse the header and 
                    334:  *           fill the informations in the database.
                    335:  */
1.35    ! veillard  336: rpmDataPtr rpmOpen(char *nameRpm, rpmDirPtr dir, rpmSubdirPtr tree) {
1.32      veillard  337:     rpmDataPtr cur;
1.11      veillard  338:     int fd;
                    339:     int rc;
                    340:     Header h = NULL;
                    341:     int isSource;
                    342:     char buffer[500];
1.20      veillard  343:     struct stat buf;
1.11      veillard  344: 
                    345:     /* open the file for reading */
1.35    ! veillard  346:     if (tree->htmlpath[0] != '\0')
        !           347:        sprintf(buffer, "%s/%s/%s", dir->rpmdir, tree->rpmpath, nameRpm);
1.24      veillard  348:     else
                    349:        sprintf(buffer, "%s/%s", dir->rpmdir, nameRpm);
1.11      veillard  350:     if ((fd = open(buffer, O_RDONLY)) < 0) {
                    351:          fprintf(stderr, "open of %s failed: %s\n", buffer,
                    352:                 strerror(errno));
1.32      veillard  353:         return(NULL);
1.11      veillard  354:     }
                    355: 
1.20      veillard  356:     stat(buffer, &buf);
                    357: 
1.11      veillard  358:     /* read the RPM header */
                    359:     rc = rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL);
                    360:     switch (rc) {
                    361:        case 0:
                    362:            if (!h) {
                    363:                fprintf(stderr,
                    364:                        "old format source packages cannot be queried\n");
1.32      veillard  365:                return(NULL);
1.11      veillard  366:            }
                    367:            break;
                    368:        case 1:
                    369:            fprintf(stderr, "%s does not appear to be a RPM package\n",
                    370:                    nameRpm);
1.32      veillard  371:            return(NULL);
1.11      veillard  372:        case 2:
                    373:            fprintf(stderr, "query of %s failed\n", nameRpm);
1.32      veillard  374:            return(NULL);
1.11      veillard  375:        default:
                    376:            fprintf(stderr, "rpmReadPackageHeader(%s): unknown error %d\n",
                    377:                    nameRpm, rc);
1.32      veillard  378:            return(NULL);
1.11      veillard  379:     }
                    380: 
1.35    ! veillard  381:     cur = rpmAnalyze(nameRpm, h, dir, tree->rpmpath, buf.st_mtime);
1.11      veillard  382: 
                    383:     /* free the header and close the descriptor */
                    384:     headerFree(h);
                    385:     close(fd);
1.1       veillard  386: 
1.32      veillard  387:     return(cur);
1.6       veillard  388: }
                    389: 
                    390: /*
1.22      veillard  391:  * Scan one directory for RPM files this is where the recursive handling
                    392:  * is done.
1.6       veillard  393:  */
1.35    ! veillard  394: static rpmDataPtr rpmOneDirScan(rpmDirPtr dir, rpmSubdirPtr tree) {
        !           395:     rpmSubdirPtr subtree;
1.32      veillard  396:     rpmDataPtr ret = NULL, cur;
1.6       veillard  397:     struct dirent **namelist;
1.7       veillard  398:     char *filename;
1.22      veillard  399:     static char path[2000];
1.23      veillard  400:     struct stat buf;
1.7       veillard  401:     int len;
1.32      veillard  402:     int i, n;
1.6       veillard  403: 
1.24      veillard  404: 
                    405:     /*
                    406:      * Create the directory for the HTML pages
                    407:      */
1.35    ! veillard  408:     if (tree->htmlpath[0] != '\0')
        !           409:        sprintf(path, "%s/%s", dir->dir, tree->htmlpath);
        !           410:     else
        !           411:        sprintf(path, "%s", dir->dir);
1.24      veillard  412:     createDirectory(path);
                    413: 
                    414:     /*
                    415:      * Scan the repository.
                    416:      */
1.35    ! veillard  417:     if (tree->rpmpath[0] != '\0')
        !           418:        sprintf(path, "%s/%s", dir->rpmdir, tree->rpmpath);
1.24      veillard  419:     else
                    420:        sprintf(path, "%s", dir->rpmdir);
1.35    ! veillard  421:     if (verbose > 1)
1.24      veillard  422:         fprintf(stderr, "Scanning directory %s\n", path);
                    423: 
                    424:     n = scandir(path, &namelist, 0, alphasort);
                    425: 
1.6       veillard  426:     if (n < 0) {
1.24      veillard  427:         fprintf(stderr, "Listing of %s failed: %s\n", path,
1.6       veillard  428:                strerror(errno));
1.35    ! veillard  429:         rpmRemoveSubdir(tree);
1.32      veillard  430:        return(NULL);
1.6       veillard  431:     } else {
1.7       veillard  432:         for (i = 0;i < n;i++) {
1.32      veillard  433:            cur = NULL;
1.7       veillard  434:            filename = namelist[i]->d_name;
                    435:            len = strlen(filename);
1.24      veillard  436: 
                    437:            /*
                    438:             * Compute the full path
                    439:             */
1.35    ! veillard  440:            if (tree->rpmpath[0] != '\0')
        !           441:                sprintf(path, "%s/%s/%s", dir->rpmdir, tree->rpmpath,
        !           442:                        filename);
1.22      veillard  443:            else
1.24      veillard  444:                sprintf(path, "%s/%s", dir->rpmdir, filename);
1.22      veillard  445: 
                    446:            /*
1.25      veillard  447:             * Stat() the file to detect directory and symlimks
                    448:             */
1.30      veillard  449:            if (lstat(path, &buf) != 0) {
1.25      veillard  450:                fprintf(stderr, "Couldn't stat(%s)\n", path);
                    451:                continue;
                    452:            }
1.35    ! veillard  453: 
1.25      veillard  454:            /*
                    455:             * Don't follow of analyze symlinks,
                    456:             */
                    457:             if (S_ISLNK(buf.st_mode)) {
                    458:                if (verbose)
                    459:                    fprintf(stderr, "Dropping symlink %s\n", path);
                    460:                continue;
                    461:            }
1.35    ! veillard  462: 
1.25      veillard  463:            /*
1.23      veillard  464:             * Check for RPM files by looking at the suffix
1.22      veillard  465:             */
1.25      veillard  466:            else if ((len >= 5) && (!strcasecmp(&filename[len - 4], ".rpm"))) {
1.35    ! veillard  467:                cur = rpmOpen(filename, dir, tree);
1.22      veillard  468:            }
1.35    ! veillard  469: 
1.22      veillard  470:            /*
1.23      veillard  471:             * Else if this is a directory, recurse !
1.22      veillard  472:             */
1.25      veillard  473:            else if (S_ISDIR(buf.st_mode)) {
                    474:                if (filename[0] != '.') {
1.35    ! veillard  475:                    subtree = rpmNewSubdir(tree, filename, NULL, NULL, NULL);
        !           476:                    cur = rpmOneDirScan(dir, subtree);
1.25      veillard  477:                }
1.22      veillard  478:            }
1.32      veillard  479:            if (cur != NULL) ret = rpmAddList(ret, cur);
1.7       veillard  480:        }
1.6       veillard  481:     }
1.33      veillard  482: 
                    483:     /*
                    484:      * Dump the pages related to this directory.
                    485:      */
1.35    ! veillard  486:     if (ret != NULL) ret = dumpDirIndex(dir, tree, ret);
        !           487:     else rpmRemoveSubdir(tree);
        !           488: 
        !           489:     /*
        !           490:      * cleanup of local variables.
        !           491:      */
1.6       veillard  492:     free(namelist);
1.35    ! veillard  493: 
1.32      veillard  494:     return(ret);
1.22      veillard  495: }
                    496: 
                    497: /*
                    498:  * Scan a directory for RPM files.
                    499:  */
1.35    ! veillard  500: static rpmDataPtr rpmDirScan(rpmDirPtr dir, rpmSubdirPtr tree) {
        !           501:     rpmSubdirPtr cur = rpmNewSubdir(tree, dir->name, 
        !           502:                  dir->subdir == NULL ? "" : dir->subdir, "", dir->color);
        !           503:     return(rpmOneDirScan(dir, cur));
1.6       veillard  504: }
                    505: 
                    506: /*
1.11      veillard  507:  * Scan the local RPM database for RPM files.
                    508:  */
1.32      veillard  509: static rpmDataPtr rpmBaseScan(rpmDirPtr dir) {
                    510:     rpmDataPtr ret = NULL, cur;
1.11      veillard  511:     rpmdb db;
                    512:     Header h = NULL;
1.32      veillard  513:     int offset;
1.11      veillard  514:     char *prefix = "/";
                    515: 
                    516:     if (rpmdbOpen(prefix, &db, O_RDONLY, 0644)) {
1.32      veillard  517:         return(NULL);
1.11      veillard  518:     }
                    519:     offset = rpmdbFirstRecNum(db);
                    520:     while (offset) {
                    521:         h = rpmdbGetRecord(db, offset);
                    522:        if (!h) {
                    523:            fprintf(stderr, "could not read database record!\n");
1.32      veillard  524:            return(ret);
1.11      veillard  525:        }
1.32      veillard  526:        cur = rpmAnalyze(NULL, h, dir, "", 0);
                    527:        if (cur != NULL) ret = rpmAddList(ret, cur);
1.11      veillard  528:        headerFree(h);
                    529:        offset = rpmdbNextRecNum(db, offset);
                    530:     }
                    531:     rpmdbClose(db);
                    532: 
1.32      veillard  533:     return(ret);
1.11      veillard  534: }
                    535: 
                    536: /*
1.6       veillard  537:  * Scan all registered directories.
                    538:  * One fist check for completeness of the informations in
                    539:  * the rpmDir structure.
                    540:  */
                    541: 
1.32      veillard  542: rpmDataPtr rpmDirScanAll(void) {
1.18      veillard  543:     rpmDirPtr dir, next;
1.32      veillard  544:     rpmDataPtr ret = NULL, cur;
1.35    ! veillard  545:     rpmDataPtr rpmLists[MAX_SUB_DIRECTORIES];
        !           546:     int nbLists = 0;
        !           547:     int i;
1.18      veillard  548: 
                    549:     /*
                    550:      * first reverse the list ....
                    551:      */
                    552:     dir = dirList;
                    553:     dirList = NULL;
                    554:     while (dir != NULL) {
                    555:         next = dir->next;
                    556:        dir->next = dirList;
                    557:        dirList = dir;
                    558:        dir = next;
                    559:     }
                    560: 
1.35    ! veillard  561:     /*
        !           562:      * Allocate a directory tree.
        !           563:      */
        !           564:     dirTree = rpmNewSubdir(NULL, "", "", "", NULL);
        !           565: 
1.18      veillard  566:     dir = dirList;
1.6       veillard  567: 
                    568:     while (dir != NULL) {
1.32      veillard  569:         cur  = NULL;
                    570: 
1.14      veillard  571:        /*
                    572:         * Override default setting.
                    573:         */
1.15      veillard  574:        if ((dir->maint == NULL) && (rpm2html_maint != NULL))
                    575:            dir->maint = strdup(rpm2html_maint);
                    576:        if ((dir->mail == NULL) && (rpm2html_mail != NULL))
                    577:            dir->mail = strdup(rpm2html_mail);
                    578:        if ((dir->ftp == NULL) && (rpm2html_ftp != NULL))
                    579:            dir->ftp = strdup(rpm2html_ftp);
                    580:        if ((dir->ftpsrc == NULL) && (rpm2html_ftpsrc != NULL))
                    581:            dir->ftpsrc = strdup(rpm2html_ftpsrc);
                    582:        if ((dir->dir == NULL) && (rpm2html_dir != NULL))
                    583:            dir->dir = strdup(rpm2html_dir);
                    584:        if ((dir->host == NULL) && (rpm2html_host != NULL))
                    585:            dir->host = strdup(rpm2html_host);
                    586:        if ((dir->name == NULL) && (rpm2html_name != NULL))
                    587:            dir->name = strdup(rpm2html_name);
                    588:        if ((dir->url == NULL) && (rpm2html_url != NULL))
                    589:            dir->url = strdup(rpm2html_url);
1.14      veillard  590: 
                    591:         if (dir->rpmdir == NULL) {
1.6       veillard  592:            fprintf(stderr, "?!? rpmDir without directory ?!? disabled !\n");
1.14      veillard  593:        } else if (!strcmp(dir->rpmdir, "localbase")) {
1.11      veillard  594:            /* Scan the local RPM database instead of a directory */
1.32      veillard  595:             cur = rpmBaseScan(dir);
1.7       veillard  596:        } else if (dir->ftp == NULL) {
                    597:            fprintf(stderr, "Directory %s disabled : no ftp field\n",
1.14      veillard  598:                    dir->rpmdir);
1.6       veillard  599:        } else {
1.16      veillard  600:            if (verbose)
                    601:                fprintf(stderr, "Scanning directory %s for RPMs\n",dir->rpmdir);
1.35    ! veillard  602:            cur = rpmDirScan(dir, dirTree);
1.6       veillard  603:        }
                    604: 
1.35    ! veillard  605:        if (cur != NULL) {
        !           606:            if (nbLists < MAX_SUB_DIRECTORIES) {
        !           607:                rpmLists[nbLists] = cur;
        !           608:                nbLists++;
        !           609:                if (nbLists == MAX_SUB_DIRECTORIES) {
        !           610:                    fprintf(stderr, "Increase MAX_SUB_DIRECTORIES : %d \n",
        !           611:                            nbLists);
        !           612:                }
        !           613:            }
        !           614:        }
1.32      veillard  615: 
1.6       veillard  616:         dir = dir->next;
                    617:     }
1.35    ! veillard  618:     for (i = 0;i < nbLists;i++)
        !           619:        ret = rpmAddList(ret, rpmLists[i]);
1.32      veillard  620:     return(ret);
1.1       veillard  621: }
                    622: 

Webmaster