+++ /dev/null
-#include <alloca.h>
-#include <ctype.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <glob.h>
-#include <dirent.h>
-#include <popt.h>
-#include <rpmlib.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <rpm/misc.h>
-#include <rpm/rpmts.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "hash.h"
-
-#define FILENAME_TAG 1000000
-#define FILESIZE_TAG 1000001
-#define CDNUM_TAG 1000002
-#define ORDER_TAG 1000003
-#define MATCHER_TAG 1000004
-
-void expandFilelist(Header h);
-void compressFilelist(Header h);
-
-struct onePackageInfo {
- char * name;
- char * arch;
-};
-
-int pkgInfoCmp(const void * a, const void * b) {
- const struct onePackageInfo * one = a;
- const struct onePackageInfo * two = b;
- int i;
-
- i = strcmp(one->name, two->name);
- if (i) return i;
-
- return strcmp(one->arch, two->arch);
-}
-
-/*int tagsInList2[] = {
- RPMTAG_FILESIZES, RPMTAG_FILEMODES, RPMTAG_FILEMD5S, RPMTAG_FILELINKTOS,
- RPMTAG_FILEFLAGS, RPMTAG_FILELANGS,
- RPMTAG_DIRNAMES, RPMTAG_DIRINDEXES, RPMTAG_BASENAMES,
- -1
- };*/
-int tagsInList2[] = { -1 };
-
-struct onePackageInfo * pkgList;
-int pkgListItems = 0;
-int pkgListAlloced = 0;
-char ** depOrder = NULL;
-hashTable requireTable;
-
-/* make sure its <package>-<version>-<release> */
-int sanityCheckDepOrderLine(char *line) {
- char *r, *v;
-
-
- r = strrchr(line, '-');
- if (!r)
- return -1;
-
- v = strrchr(r, '-');
- if (!v)
- return -1;
-
- return 0;
-
-}
-
-/* mmmm... linear search */
-int getOrder (char * fn)
-{
- char *p;
- int i;
-
- if (!depOrder || !depOrder[0] || !depOrder[0][0]) {
- return -1;
- }
-
- i = 0;
- p = depOrder[i];
- while (p && *p && strncmp (fn, p, strlen(p))) {
- p = depOrder[++i];
- }
-
- if (p) {
- return i;
- }
-
- fprintf (stderr, "WARNING: ordering not found for %s\n", fn);
-
- return -1;
-}
-
-int onePrePass(const char * dirName) {
- struct dirent * ent;
- DIR * dir;
- char * subdir = alloca(strlen(dirName) + 20);
- FD_t fd;
- int rc;
- Header h;
- char ** requires;
- int c;
- rpmts ts = rpmtsCreate();
- rpmtsSetRootDir(ts, "/");
- rpmtsSetVSFlags(ts, ~RPMVSF_NOHDRCHK);
- rpmtsCloseDB(ts);
-
- sprintf(subdir, "%s/RedHat/RPMS", dirName);
-
- dir = opendir(subdir);
- if (!dir) {
- fprintf(stderr,"error opening directory %s: %s\n", subdir,
- strerror(errno));
- return 1;
- }
-
- chdir(subdir);
-
- errno = 0;
- ent = readdir(dir);
- if (errno) {
- perror("readdir");
- return 1;
- }
-
- while (ent) {
- int i = strlen (ent->d_name);
-
- if (i > 4 && strcasecmp (&ent->d_name [i - 4], ".rpm") == 0) {
- fd = Fopen(ent->d_name, "r");
-
- if (!fd) {
- perror("open");
- exit(1);
- }
-
- rc = rpmReadPackageFile(ts, fd, ent->d_name, &h);
-
- if (!rc) {
- if (headerGetEntry(h, RPMTAG_REQUIRENAME, NULL,
- (void **) &requires, &c)) {
- while (c--)
- if (*requires[c] == '/')
- htAddToTable(requireTable, requires[c], ".");
- }
-
- headerFree(h);
- /* XXX free requires */
- }
-
- Fclose(fd);
- }
-
- errno = 0;
- ent = readdir(dir);
- if (errno) {
- perror("readdir");
- return 1;
- }
- }
-
- closedir(dir);
-
- return 0;
-}
-
-int onePass(FD_t outfd, FD_t out2fd, const char * dirName, int cdNum) {
- FD_t fd;
- struct dirent * ent;
- char * subdir = alloca(strlen(dirName) + 20);
- int errno;
- Header h, nh, h2;
- int rc;
- int_32 size;
- DIR * dir;
- struct stat sb;
- int_32 * fileSizes;
- int fileCount;
- int order = -1;
- char ** newFileList, ** fileNames;
- uint_32 * newFileFlags, * fileFlags;
- int newFileListCount;
- int marker = time(NULL); /* good enough counter; we'll increment it */
- rpmts ts = rpmtsCreate();
- rpmtsSetRootDir(ts, "/");
- rpmtsSetVSFlags(ts, ~RPMVSF_NOHDRCHK);
- rpmtsCloseDB(ts);
-
- sprintf(subdir, "%s/RedHat/RPMS", dirName);
-
- dir = opendir(subdir);
- if (!dir) {
- fprintf(stderr,"error opening directory %s: %s\n", subdir,
- strerror(errno));
- return 1;
- }
-
- chdir(subdir);
-
- errno = 0;
- ent = readdir(dir);
- if (errno) {
- perror("readdir");
- return 1;
- }
-
- while (ent) {
- int i = strlen (ent->d_name);
- if (i > 4 && strcasecmp (&ent->d_name [i - 4], ".rpm") == 0) {
- fd = Fopen(ent->d_name, "r");
-
- if (!fd) {
- perror("open");
- exit(1);
- }
-
- if (stat(ent->d_name, &sb)) {
- perror("stat");
- exit(1);
- }
- size = sb.st_size;
-
- rc = rpmReadPackageFile(ts, fd, ent->d_name, &h);
-
- if (!rc) {
- if (pkgListItems == pkgListAlloced) {
- pkgListAlloced += 100;
- pkgList = realloc(pkgList,
- sizeof(*pkgList) * pkgListAlloced);
- }
-
- headerGetEntry(h, RPMTAG_NAME, NULL,
- (void **) &pkgList[pkgListItems].name, NULL);
- headerGetEntry(h, RPMTAG_ARCH, NULL,
- (void **) &pkgList[pkgListItems].arch, NULL);
-
- pkgList[pkgListItems].name = strdup(pkgList[pkgListItems].name);
- pkgList[pkgListItems].arch = strdup(pkgList[pkgListItems].arch);
- pkgListItems++;
-
- headerRemoveEntry(h, RPMTAG_POSTIN);
- headerRemoveEntry(h, RPMTAG_POSTUN);
- headerRemoveEntry(h, RPMTAG_PREIN);
- headerRemoveEntry(h, RPMTAG_PREUN);
- headerRemoveEntry(h, RPMTAG_FILEUSERNAME);
- headerRemoveEntry(h, RPMTAG_FILEGROUPNAME);
- headerRemoveEntry(h, RPMTAG_FILEVERIFYFLAGS);
- headerRemoveEntry(h, RPMTAG_FILERDEVS);
- headerRemoveEntry(h, RPMTAG_FILEMTIMES);
- headerRemoveEntry(h, RPMTAG_FILEDEVICES);
- headerRemoveEntry(h, RPMTAG_FILEINODES);
- headerRemoveEntry(h, RPMTAG_TRIGGERSCRIPTS);
- headerRemoveEntry(h, RPMTAG_TRIGGERVERSION);
- headerRemoveEntry(h, RPMTAG_TRIGGERFLAGS);
- headerRemoveEntry(h, RPMTAG_TRIGGERNAME);
- headerRemoveEntry(h, RPMTAG_CHANGELOGTIME);
- headerRemoveEntry(h, RPMTAG_CHANGELOGNAME);
- headerRemoveEntry(h, RPMTAG_CHANGELOGTEXT);
- headerRemoveEntry(h, RPMTAG_ICON);
- headerRemoveEntry(h, RPMTAG_GIF);
- headerRemoveEntry(h, RPMTAG_VENDOR);
- headerRemoveEntry(h, RPMTAG_EXCLUDE);
- headerRemoveEntry(h, RPMTAG_EXCLUSIVE);
- headerRemoveEntry(h, RPMTAG_DISTRIBUTION);
- headerRemoveEntry(h, RPMTAG_VERIFYSCRIPT);
-
- /* new header sigs */
- headerRemoveEntry(h, RPMTAG_SIGSIZE);
- headerRemoveEntry(h, RPMTAG_SIGGPG);
- headerRemoveEntry(h, RPMTAG_SIGPGP);
-
- /* other stuff we don't need - msw */
- headerRemoveEntry(h, RPMTAG_PACKAGER);
- headerRemoveEntry(h, RPMTAG_LICENSE);
- headerRemoveEntry(h, RPMTAG_BUILDTIME);
- headerRemoveEntry(h, RPMTAG_BUILDHOST);
- headerRemoveEntry(h, RPMTAG_RPMVERSION);
- headerRemoveEntry(h, RPMTAG_POSTINPROG);
- headerRemoveEntry(h, RPMTAG_POSTUNPROG);
- headerRemoveEntry(h, RPMTAG_PREINPROG);
- headerRemoveEntry(h, RPMTAG_PREUNPROG);
- headerRemoveEntry(h, RPMTAG_COOKIE);
- headerRemoveEntry(h, RPMTAG_OPTFLAGS);
- headerRemoveEntry(h, RPMTAG_PAYLOADFORMAT);
- headerRemoveEntry(h, RPMTAG_PAYLOADCOMPRESSOR);
- headerRemoveEntry(h, RPMTAG_PAYLOADFLAGS);
-
- headerAddEntry(h, FILENAME_TAG, RPM_STRING_TYPE, ent->d_name, 1);
- headerAddEntry(h, FILESIZE_TAG, RPM_INT32_TYPE,
- &size, 1);
-
- /* Recaclulate the package size based on a 4k block size */
- if (headerGetEntry(h, RPMTAG_FILESIZES, NULL,
- (void **) &fileSizes, &fileCount)) {
- int fileNum;
- int newSize = 0;
- int * p;
-
- for (fileNum = 0; fileNum < fileCount; fileNum++)
- newSize += ((fileSizes[fileNum] + 4093) / 4096) * 4096;
-
- headerGetEntry(h, RPMTAG_SIZE, NULL, (void **) &p, NULL);
-
- headerRemoveEntry(h, RPMTAG_SIZE);
- headerAddEntry(h, RPMTAG_SIZE, RPM_INT32_TYPE,
- &newSize, 1);
- }
-
- if (cdNum > -1)
- headerAddEntry(h, CDNUM_TAG, RPM_INT32_TYPE,
- &cdNum, 1);
-
- if ((order = getOrder (ent->d_name)) > -1) {
- headerAddEntry(h, ORDER_TAG, RPM_INT32_TYPE,
- &order, 1);
- }
-
- expandFilelist(h);
- newFileList = NULL;
- if (headerGetEntry(h, RPMTAG_OLDFILENAMES, NULL,
- (void **) &fileNames, &fileCount)) {
- headerGetEntry(h, RPMTAG_FILEFLAGS, NULL,
- (void **) &fileFlags, NULL);
-
- newFileList = malloc(sizeof(*newFileList) * fileCount);
- newFileFlags = malloc(sizeof(*newFileList) * fileCount);
- newFileListCount = 0;
-
- for (i = 0; i < fileCount; i++) {
- if (htInTable(requireTable, fileNames[i], ".")) {
- newFileList[newFileListCount] = strdup(fileNames[i]);
- newFileFlags[newFileListCount] = fileFlags[i];
- newFileListCount++;
- }
- }
-
- if (!newFileListCount) {
- free(newFileList);
- free(newFileFlags);
- newFileList = NULL;
- }
-
- /* XXX free fileNames */
- }
- compressFilelist(h);
-
- h2 = headerNew();
- for (i = 0; tagsInList2[i] > -1; i++) {
- int_32 type, c;
- void * p;
-
- if (headerGetEntry(h, tagsInList2[i], &type, &p, &c)) {
- headerAddEntry(h2, tagsInList2[i], type, p, c);
- headerRemoveEntry(h, tagsInList2[i]);
- }
-
- /* XXX need to headerFreeData */
- }
-
- if (newFileList) {
- headerAddEntry(h, RPMTAG_OLDFILENAMES,
- RPM_STRING_ARRAY_TYPE,
- newFileList, newFileListCount);
- headerAddEntry(h, RPMTAG_FILEFLAGS,
- RPM_INT32_TYPE,
- &newFileFlags, newFileListCount);
-
- compressFilelist(h);
- while (newFileListCount--) {
- free(newFileList[newFileListCount]);
- }
- free(newFileList);
- free(newFileFlags);
- newFileList = NULL;
- }
-
- headerAddEntry(h, MATCHER_TAG, RPM_INT32_TYPE, &marker, 1);
- headerAddEntry(h2, MATCHER_TAG, RPM_INT32_TYPE, &marker, 1);
- marker++;
-
- nh = headerCopy (h);
- headerWrite(outfd, nh, HEADER_MAGIC_YES);
- headerWrite(out2fd, h2, HEADER_MAGIC_YES);
-
- headerFree(h);
- headerFree(nh);
- headerFree(h2);
- }
-
- Fclose(fd);
- }
-
- errno = 0;
- ent = readdir(dir);
- if (errno) {
- perror("readdir");
- return 1;
- }
- }
-
- closedir(dir);
-
- return 0;
-}
-
-static void usage(void) {
- fprintf(stderr, "genhdlist: genhdlist [--withnumbers] [--fileorder <path>] [--hdlist <path>] <paths>+\n");
- exit(1);
-}
-
-int main(int argc, const char ** argv) {
- char buf[300];
- FD_t outfd, out2fd;
- int cdNum = -1;
- const char ** args;
- int doNumber = 0;
- int rc;
- int i;
- char * hdListFile = NULL;
- char * hdListFile2 = NULL;
- char * depOrderFile = NULL;
- poptContext optCon;
- struct poptOption optionsTable[] = {
- { "hdlist", '\0', POPT_ARG_STRING, &hdListFile, 0 },
- { "withnumbers", '\0', 0, &doNumber, 0 },
- { "fileorder", '\0', POPT_ARG_STRING, &depOrderFile, 0 },
- { 0, 0, 0, 0, 0 }
- };
-
- optCon = poptGetContext("genhdlist", argc, argv, optionsTable, 0);
- poptReadDefaultConfig(optCon, 1);
-
- if ((rc = poptGetNextOpt(optCon)) < -1) {
- fprintf(stderr, "%s: bad argument %s: %s\n", "genhdlist",
- poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
- poptStrerror(rc));
- return 1;
- }
-
- args = poptGetArgs(optCon);
- if (!args || !args[0] || !args[0][0])
- usage();
-
- if (depOrderFile) {
- FILE *f;
- int nalloced = 0;
- int numpkgs = 0;
- int len = 0;
- char b[80];
-
- if (!(f = fopen(depOrderFile, "r"))) {
- fprintf (stderr, "Unable to read %s\n", depOrderFile);
- usage();
- }
-
- while ((fgets(b, sizeof(b) - 1, f))) {
- if (numpkgs == nalloced) {
- depOrder = realloc (depOrder, sizeof (char *) * (nalloced + 6));
- memset (depOrder + numpkgs, '\0', sizeof (char *) * 6);
- nalloced += 5;
- }
-
- len = strlen(b);
- /* chop */
- b[--len] = '\0';
-
- /* sanity check */
- /* should have the format of a <package name>-<version>-<release> */
- if (sanityCheckDepOrderLine(b)) {
- fprintf(stderr, "genhdlist: FATAL ERROR -> \"%s\" is not a package name!!\n",b);
- fprintf(stderr, "Your package list file %s is most likely CORRUPT!\n", depOrderFile);
- exit(1);
- }
-
- depOrder[numpkgs] = malloc (len + 1);
- strcpy (depOrder[numpkgs], b);
- numpkgs++;
- }
- depOrder[numpkgs] = NULL; /* end with a null */
- }
-
- requireTable = htNewTable(1000);
-
- if (!hdListFile) {
- strcpy(buf, args[0]);
- strcat(buf, "/RedHat/base/hdlist");
- hdListFile = buf;
- }
-
- unlink(hdListFile);
-
- hdListFile2 = malloc(strlen(hdListFile) + 2);
- sprintf(hdListFile2, "%s2", hdListFile);
-
- unlink (hdListFile);
- unlink (hdListFile2);
-
- outfd = Fopen(hdListFile, "w");
- if (!outfd) {
- fprintf(stderr,"error creating file %s: %s\n", hdListFile,
- strerror(errno));
- return 1;
- }
-
- out2fd = Fopen(hdListFile2, "w");
- if (!out2fd) {
- fprintf(stderr,"error creating file %s: %s\n", hdListFile2,
- strerror(errno));
- return 1;
- }
-
- if (doNumber)
- cdNum = 1;
-
-/* if (args > 1 && !doNumber) { */
-/* fprintf(stderr, "error: building hdlist for multiple trees without numbers\n"); */
-/* exit(1); */
-/* } */
-
- i = 0;
- while (args[i]) {
- if (onePrePass(args[i]))
- return 1;
- i++;
- }
-
- i = 0;
- while (args[i]) {
- if (onePass(outfd, out2fd, args[i], cdNum))
- return 1;
- if (doNumber) cdNum++;
- i++;
- }
-
- Fclose(outfd);
- Fclose(out2fd);
-
- poptFreeContext(optCon);
-
- qsort(pkgList, pkgListItems, sizeof(*pkgList), pkgInfoCmp);
- rc = 0;
- for (i = 1; i < pkgListItems; i++) {
- if (!pkgInfoCmp(pkgList + i - 1, pkgList + i)) {
- fprintf(stderr, "duplicate package for %s on %s\n",
- pkgList[i].name, pkgList[i].arch);
- rc = 1;
- }
- }
-
- return rc;
-}