/* * rpmopen.c : open an extract informations from RPM files. * * $Id: rpmopen.c,v 1.8 1997/11/13 06:37:39 veillard Exp $ * * $Log: rpmopen.c,v $ * Revision 1.8 1997/11/13 06:37:39 veillard * Added statistics, ByName, and generation of index.html, Daniel. * * Revision 1.7 1997/11/13 05:04:34 veillard * Lot of improvements, copyright, URLs, E-mail, and config files, Daniel. * * Revision 1.6 1997/11/12 07:06:53 veillard * Directory support and file scanning are now based on the config files, Daniel. * * Revision 1.5 1997/11/12 03:50:40 veillard * Version submitted to guilde@imag.fr, Daniel. * * Revision 1.4 1997/11/11 22:28:11 veillard * Added the support for dependancies on resources, Daniel. * * Revision 1.3 1997/11/11 21:18:53 veillard * Improved a lot, removed bugs related to sorting, Daniel. * * Revision 1.2 1997/11/11 11:10:11 veillard * State after one night of work, Daniel * * Revision 1.1.1.1 1997/11/11 07:12:32 veillard * First revision of RPM-Check * */ #include #include #include #include #include #include #include #include #include #include "rpmdata.h" #include "html.h" #include "rpm2html.h" /* * Get the internal number associated to an RPM tag. */ static int getTagNumber(char *tag) { int i; const struct headerTagTableEntry * t; for (i = 0, t = rpmTagTable; i < rpmTagTableSize; i++, t++) { if (!strcasecmp(tag, t->name)) return(t->val); } fprintf(stderr, "getTagNumber(%s) : unknown tag !\n", tag); return(-1); } /* * rpmOpen : open an RPM file, read and parse the header and * fill the informations in the database. */ int rpmOpen(char *nameRpm, rpmDirPtr dir) { int fd; int rc; Header h = NULL; int isSource; char * name = NULL, * version = NULL, * release = NULL; int_32 count, type; void * p = NULL; int val, i; rpmDataPtr rpm = NULL; static char buffer[500000]; /* open the file for reading */ sprintf(buffer, "%s/%s", dir->dir, nameRpm); if ((fd = open(buffer, O_RDONLY)) < 0) { fprintf(stderr, "open of %s failed: %s\n", buffer, strerror(errno)); goto error; } /* read the RPM header */ rc = rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL); switch (rc) { case 0: if (!h) { fprintf(stderr, "old format source packages cannot be queried\n"); goto error; } break; case 1: fprintf(stderr, "%s does not appear to be a RPM package\n", nameRpm); goto error; case 2: fprintf(stderr, "query of %s failed\n", nameRpm); goto error; default: fprintf(stderr, "rpmReadPackageHeader(%s): unknown error %d\n", nameRpm, rc); goto error; } /* extract informations from the header */ headerGetEntry(h, RPMTAG_NAME, &type, (void **) &name, &count); headerGetEntry(h, RPMTAG_VERSION, &type, (void **) &version, &count); headerGetEntry(h, RPMTAG_RELEASE, &type, (void **) &release, &count); /* allocate a new rpmData block, fill it */ rpm = (rpmDataPtr) malloc(sizeof(rpmData)); if (rpm == NULL) { fprintf(stderr, "cannot allocate %d bytes: %s\n", sizeof(rpmData), strerror(errno)); goto error; } rpm->dir = dir; rpm->filename = strdup(nameRpm); rpm->name = strdup(name); rpm->version = strdup(version); rpm->release = strdup(release); /* get all the ressources provided by this RPM */ if (!headerGetEntry(h, RPMTAG_SUMMARY, &type, &p, &count) || !p) { rpm->summary = "No Summary !"; } else { rpm->summary = strdup((char *) p); } if (!headerGetEntry(h, RPMTAG_DESCRIPTION, &type, &p, &count) || !p) { rpm->description = "No Description !"; } else { rpm->description = strdup((char *) p); } if (!headerGetEntry(h, RPMTAG_DISTRIBUTION, &type, &p, &count) || !p) { rpm->distribution = "unknown"; } else { rpm->distribution = strdup((char *) p); } if (!headerGetEntry(h, RPMTAG_ARCH, &type, &p, &count) || !p) { rpm->arch = "None"; } else { rpm->arch = strdup((char *) p); } if (!headerGetEntry(h, RPMTAG_OS, &type, &p, &count) || !p) { rpm->os = ""; } else { rpm->os = strdup((char *) p); } if (!headerGetEntry(h, RPMTAG_VENDOR, &type, &p, &count) || !p) { rpm->vendor = NULL; } else { rpm->vendor = strdup((char *) p); } if (!headerGetEntry(h, RPMTAG_GROUP, &type, &p, &count) || !p) { rpm->group = "unknown/group"; } else { rpm->group = strdup((char *) p); } if (!headerGetEntry(h, RPMTAG_BUILDHOST, &type, &p, &count) || !p) { rpm->host = "unknown.host"; } else { rpm->host = strdup((char *) p); } if (!headerGetEntry(h, RPMTAG_SIZE, &type, &p, &count) || !p) { rpm->size = 0; } else { rpm->size = *((int *) p); } if (!headerGetEntry(h, RPMTAG_BUILDTIME, &type, &p, &count) || !p) { rpm->date = 0; } else { rpm->date = *((int_32 *) p); } if (!headerGetEntry(h, RPMTAG_SOURCERPM, &type, &p, &count) || !p) { rpm->srcrpm = ""; } else { rpm->srcrpm = strdup((char *) p); } if (!headerGetEntry(h, RPMTAG_URL, &type, &p, &count) || !p) { rpm->url = NULL; } else { rpm->url = strdup((char *) p); } if (!headerGetEntry(h, RPMTAG_PACKAGER, &type, &p, &count) || !p) { rpm->packager = NULL; } else { rpm->packager = strdup((char *) p); } if (!headerGetEntry(h, RPMTAG_COPYRIGHT, &type, &p, &count) || !p) { rpm->copyright = NULL; } else { rpm->copyright = strdup((char *) p); } if (rpm->vendor == NULL) { if (rpm->packager != NULL) rpm->vendor = rpm->packager; else rpm->vendor = "unknown"; } val = getTagNumber("RPMTAG_PROVIDES"); if (!headerGetEntry(h, val, &type, &p, &count) || !p) { rpm->nb_ressources = 0; } else { if (count >= MAX_RESS) { fprintf(stderr, "MAX_RESS %d overflow, increase the limit!\n", MAX_RESS); count = MAX_RESS; } rpm->nb_ressources = count; for (i = 0; i < count;i++) { rpm->ressources[i] = rpmRessAdd(((char **) p)[i], rpm); } } val = getTagNumber("RPMTAG_REQUIRENAME"); if (!headerGetEntry(h, val, &type, &p, &count) || !p) { rpm->nb_requires = 0; } else { if (count >= MAX_REQU) { fprintf(stderr, "MAX_REQU %d overflow, increase the limit!\n", MAX_REQU); count = MAX_REQU; } rpm->nb_requires = count; for (i = 0; i < count;i++) { rpm->requires[i] = rpmRequAdd(((char **) p)[i], rpm); } } val = getTagNumber("RPMTAG_FILENAMES"); if (!headerGetEntry(h, val, &type, &p, &count) || !p) { rpm->filelist = NULL; /* No filelist in the package ! */ } else { char *ptr = buffer; for (i = 0; i < count;i++) { ptr += sprintf(ptr, "%s\n", ((char **) p)[i]); } rpm->filelist = strdup(buffer); } /* insert the package informations in the database */ rpm->next = rpmList; rpmList = rpm; /* free the header and close the descriptor */ headerFree(h); close(fd); /* dump the HTML related to this package */ dumpRpmHtml(rpm); /* free large amount of data not used later */ if (rpm->filelist) free(rpm->filelist); if (rpm->copyright) free(rpm->copyright); /* increment the counters */ rpm2html_files++; rpm2html_size += rpm->size; return(0); error: if (rpm != NULL) free(rpm); if (h != NULL) headerFree(h); if (fd >= 0) close(fd); return(-1); } /* * Scan a directory for RPM files. */ static int rpmDirScan(rpmDirPtr dir) { struct dirent **namelist; char *filename; int len; int n, i; n = scandir(dir->dir, &namelist, 0, alphasort); if (n < 0) { fprintf(stderr, "Listing of %s failed: %s\n", dir->dir, strerror(errno)); return(-1); } else { for (i = 0;i < n;i++) { /* check that this is a RPM file by looking at the suffix */ filename = namelist[i]->d_name; len = strlen(filename); if ((len >= 5) && (!strcasecmp(&filename[len - 4], ".rpm"))) rpmOpen(filename, dir); } } free(namelist); return(n); } /* * Scan all registered directories. * One fist check for completeness of the informations in * the rpmDir structure. */ int rpmDirScanAll(void) { int n = 0, i; rpmDirPtr dir = dirList; while (dir != NULL) { if (dir->dir == NULL) { fprintf(stderr, "?!? rpmDir without directory ?!? disabled !\n"); } else if (dir->ftp == NULL) { fprintf(stderr, "Directory %s disabled : no ftp field\n", dir->dir); } else if (dir->nb_urls <= 0) { fprintf(stderr, "Directory %s disabled : no url(s) field\n", dir->dir); } else { fprintf(stderr, "Scanning directory %s for RPMs\n", dir->dir); i = rpmDirScan(dir); if (i > 0) n += i; } dir = dir->next; } return(n); }