move a lot of stuff to names.c and files.c
authorroot <devnull@localhost>
Fri, 7 Jun 1996 18:31:31 +0000 (18:31 +0000)
committerroot <devnull@localhost>
Fri, 7 Jun 1996 18:31:31 +0000 (18:31 +0000)
CVS patchset: 619
CVS date: 1996/06/07 18:31:31

build/pack.c

index 29a4f87..2edc150 100644 (file)
@@ -1,93 +1,44 @@
-/* RPM - Copyright (C) 1995 Red Hat Software
- * 
- * pack.c - routines for packaging
- */
+/* The very final packaging steps */
 
 #include <stdlib.h>
-#include <ctype.h>
-#include <stdio.h>
 #include <unistd.h>
-#include <sys/utsname.h>
+#include <stdio.h>
+#include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
-#include <sys/signal.h>
-#include <string.h>
+#include <signal.h>
 #include <fcntl.h>
-#include <time.h>
-#include <ftw.h>
-#include <netinet/in.h>
-#include <pwd.h>
-#include <grp.h>
-#include <netdb.h>
-#include <glob.h>
-#include <zlib.h>
-#include <errno.h>
+#include <string.h>
 
+#include "pack.h"
 #include "header.h"
+#include "spec.h"
 #include "specP.h"
+#include "signature.h"
 #include "rpmerr.h"
 #include "rpmlead.h"
 #include "rpmlib.h"
-#include "signature.h"
 #include "misc.h"
-#include "pack.h"
-#include "build.h"
-#include "messages.h"
-#include "md5.h"
-#include "myftw.h"
-
-#define BINARY_HEADER 0
-#define SOURCE_HEADER 1
+#include "stringbuf.h"
+#include "names.h"
+#include "files.h"
+#include "reqprov.h"
 
-struct file_entry {
-    char file[1024];
-    int isdoc;
-    int isconf;
-    int verify_flags;
-    char *uname;  /* reference -- do not free */
-    char *gname;  /* reference -- do not free */
-    struct stat statbuf;
-    struct file_entry *next;
-};
-
-static int cpio_gzip(Header header, int fd, char *tempdir, int *archiveSize);
 static int writeMagic(int fd, char *name, unsigned short type,
                      unsigned short sigtype);
-static int add_file(struct file_entry **festack, const char *name,
-                   int isdoc, int isconf, int isdir, int verify_flags,
-                   char *Pmode, char *Uname, char *Gname);
-static int compare_fe(const void *ap, const void *bp);
-static int process_filelist(Header header, struct PackageRec *pr, StringBuf sb,
-                           int *size, char *name, char *version,
-                           char *release, int type);
-static char *buildHost(void);
-static int add_file_aux(const char *file, struct stat *sb, int flag);
-static char *getUname(uid_t uid);
-static char *getUnameS(char *uname);
-static char *getGname(gid_t gid);
-static char *getGnameS(char *gname);
-static int glob_error(const char *foo, int bar);
-static int glob_pattern_p (char *pattern);
-static int parseForVerify(char *buf, int *verify_flags);
-static int parseForAttr(char *origbuf, char **currPmode,
-                       char **currUname, char **currGname);
-
-static
-int generateRPM(char *name,       /* name-version-release         */
-               int type,         /* source or binary             */
-               Header header,    /* the header                   */
-               char *stempdir,   /* directory containing sources */
-               char *passPhrase);
-
-static void resetDocdir(void);
-static void addDocdir(char *dirname);
-static int isDoc(char *filename);
-
-int generateRPM(char *name,       /* name-version-release         */
-               int type,         /* source or binary             */
-               Header header,    /* the header                   */
-               char *stempdir,   /* directory containing sources */
-               char *passPhrase)
+static int cpio_gzip(Header header, int fd, char *tempdir, int *archiveSize);
+static int generateRPM(char *name,       /* name-version-release         */
+                      int type,         /* source or binary             */
+                      Header header,    /* the header                   */
+                      char *stempdir,   /* directory containing sources */
+                      char *passPhrase);
+
+
+static int generateRPM(char *name,       /* name-version-release         */
+                      int type,         /* source or binary             */
+                      Header header,    /* the header                   */
+                      char *stempdir,   /* directory containing sources */
+                      char *passPhrase)
 {
     unsigned short sigtype;
     char *archName;
@@ -409,841 +360,6 @@ static int cpio_gzip(Header header, int fd, char *tempdir, int *archiveSize)
     return 0;
 }
 
-/* XXX hard coded limit -- only 1024 %docdir allowed */
-static char *docdirs[1024];
-static int docdir_count;
-
-static void resetDocdir(void)
-{
-    while (docdir_count--) {
-        free(docdirs[docdir_count]);
-    }
-    docdir_count = 0;
-    docdirs[docdir_count++] = strdup("/usr/doc");
-    docdirs[docdir_count++] = strdup("/usr/man");
-    docdirs[docdir_count++] = strdup("/usr/info");
-}
-
-static void addDocdir(char *dirname)
-{
-    if (docdir_count == 1024) {
-       fprintf(stderr, "RPMERR_INTERNAL: Hit limit in addDocdir()\n");
-       exit(RPMERR_INTERNAL);
-    }
-    docdirs[docdir_count++] = strdup(dirname);
-}
-
-static int isDoc(char *filename)
-{
-    int x = 0;
-
-    while (x < docdir_count) {
-        if (strstr(filename, docdirs[x]) == filename) {
-           return 1;
-        }
-       x++;
-    }
-    return 0;
-}
-
-/* These should only be accessed by getUname() and getUnameS() */
-static uid_t uids[1024];
-static char *unames[1024];
-static int uid_used = 0;
-
-/*
- * getUname() takes a uid, gets the username, and creates an entry in the
- * table to hold a string containing the user name.
- */
-static char *getUname(uid_t uid)
-{
-    struct passwd *pw;
-    int x;
-
-    x = 0;
-    while (x < uid_used) {
-       if (uids[x] == uid) {
-           return unames[x];
-       }
-       x++;
-    }
-
-    /* XXX - This is the other hard coded limit */
-    if (x == 1024) {
-       fprintf(stderr, "RPMERR_INTERNAL: Hit limit in getUname()\n");
-       exit(RPMERR_INTERNAL);
-    }
-    
-    pw = getpwuid(uid);
-    uids[x] = uid;
-    uid_used++;
-    if (pw) {
-       unames[x] = strdup(pw->pw_name);
-    } else {
-       unames[x] = "";
-    }
-    return unames[x];
-}
-
-/*
- * getUnameS() takes a username, gets the uid, and creates an entry in the
- * table to hold a string containing the user name.
- */
-static char *getUnameS(char *uname)
-{
-    struct passwd *pw;
-    int x;
-
-    x = 0;
-    while (x < uid_used) {
-       if (!strcmp(unames[x],uname)) {
-           return unames[x];
-       }
-       x++;
-    }
-
-    /* XXX - This is the other hard coded limit */
-    if (x == 1024) {
-       fprintf(stderr, "RPMERR_INTERNAL: Hit limit in getUname()\n");
-       exit(RPMERR_INTERNAL);
-    }
-    
-    pw = getpwnam(uname);
-    uid_used++;
-    if (pw) {
-        uids[x] = pw->pw_uid;
-       unames[x] = strdup(pw->pw_name);
-    } else {
-        uids[x] = -1;
-       unames[x] = strdup(uname);
-    }
-    return unames[x];
-}
-
-/* These should only be accessed by getGname() and getGnameS() */
-static gid_t gids[1024];
-static char *gnames[1024];
-static int gid_used = 0;
-    
-/*
- * getGname() takes a gid, gets the group name, and creates an entry in the
- * table to hold a string containing the group name.
- */
-static char *getGname(gid_t gid)
-{
-    struct group *gr;
-    int x;
-
-    x = 0;
-    while (x < gid_used) {
-       if (gids[x] == gid) {
-           return gnames[x];
-       }
-       x++;
-    }
-
-    /* XXX - This is the other hard coded limit */
-    if (x == 1024) {
-       fprintf(stderr, "RPMERR_INTERNAL: Hit limit in getGname()\n");
-       exit(RPMERR_INTERNAL);
-    }
-    
-    gr = getgrgid(gid);
-    gids[x] = gid;
-    gid_used++;
-    if (gr) {
-       gnames[x] = strdup(gr->gr_name);
-    } else {
-       gnames[x] = "";
-    }
-    return gnames[x];
-}
-
-/*
- * getGnameS() takes a group name, gets the gid, and creates an entry in the
- * table to hold a string containing the group name.
- */
-static char *getGnameS(char *gname)
-{
-    struct group *gr;
-    int x;
-
-    x = 0;
-    while (x < gid_used) {
-       if (!strcmp(gnames[x], gname)) {
-           return gnames[x];
-       }
-       x++;
-    }
-
-    /* XXX - This is the other hard coded limit */
-    if (x == 1024) {
-       fprintf(stderr, "RPMERR_INTERNAL: Hit limit in getGname()\n");
-       exit(RPMERR_INTERNAL);
-    }
-    
-    gr = getgrnam(gname);
-    gid_used++;
-    if (gr) {
-       gids[x] = gr->gr_gid;
-       gnames[x] = strdup(gr->gr_name);
-    } else {
-       gids[x] = -1;
-       gnames[x] = strdup(gname);
-    }
-    return gnames[x];
-}
-
-/* Need three globals to keep track of things in ftw() */
-static int Gisdoc;
-static int Gisconf;
-static int Gverify_flags;
-static int Gcount;
-static char *GPmode;
-static char *GUname;
-static char *GGname;
-static struct file_entry **Gfestack;
-
-static int add_file(struct file_entry **festack, const char *name,
-                   int isdoc, int isconf, int isdir, int verify_flags,
-                   char *Pmode, char *Uname, char *Gname)
-{
-    struct file_entry *p;
-    char fullname[1024];
-    int mode;
-
-    /* Set these up for ftw() */
-    Gfestack = festack;
-    Gisdoc = isdoc;
-    Gisconf = isconf;
-    Gverify_flags = verify_flags;
-    GPmode = Pmode;
-    GUname = Uname;
-    GGname = Gname;
-
-    p = malloc(sizeof(struct file_entry));
-    strcpy(p->file, name);
-    p->isdoc = isdoc;
-    p->isconf = isconf;
-    p->verify_flags = verify_flags;
-    if (getVar(RPMVAR_ROOT)) {
-       sprintf(fullname, "%s%s", getVar(RPMVAR_ROOT), name);
-    } else {
-       strcpy(fullname, name);
-    }
-    if (lstat(fullname, &p->statbuf)) {
-       return 0;
-    }
-
-    /*
-     * If %attr() was specified, then use those values instead of
-     * what lstat() returned.
-     */
-    if (Pmode && strcmp(Pmode, "-")) {
-       sscanf(Pmode, "%o", &mode);
-       mode |= p->statbuf.st_mode & S_IFMT;
-       p->statbuf.st_mode = (unsigned short)mode;
-    }
-    
-    if (Uname && strcmp(Uname, "-")) {
-       p->uname = getUnameS(Uname);
-    } else {
-       p->uname = getUname(p->statbuf.st_uid);
-    }
-    
-    if (Gname && strcmp(Gname, "-")) {
-       p->gname = getGnameS(Gname);
-    } else {
-       p->gname = getGname(p->statbuf.st_gid);
-    }
-    
-    if ((! isdir) && S_ISDIR(p->statbuf.st_mode)) {
-       /* This means we need to descend with ftw() */
-       Gcount = 0;
-       
-       /* We use our own ftw() call, because ftw() uses stat()    */
-       /* instead of lstat(), which causes it to follow symlinks! */
-       myftw(fullname, add_file_aux, 16);
-       
-       free(p);
-
-       return Gcount;
-    } else {
-       /* Link it in */
-       p->next = *festack;
-       *festack = p;
-
-       message(MESS_DEBUG, "ADDING: %s\n", name);
-
-       /* return number of entries added */
-       return 1;
-    }
-}
-
-static int add_file_aux(const char *file, struct stat *sb, int flag)
-{
-    const char *name = file;
-
-    if (getVar(RPMVAR_ROOT)) {
-       name += strlen(getVar(RPMVAR_ROOT));
-    }
-
-    /* The 1 will cause add_file() to *not* descend */
-    /* directories -- ftw() is already doing it!    */
-    Gcount += add_file(Gfestack, name, Gisdoc, Gisconf, 1, Gverify_flags,
-                       GPmode, GUname, GGname);
-
-    return 0; /* for ftw() */
-}
-
-static int compare_fe(const void *ap, const void *bp)
-{
-    char *a, *b;
-
-    a = (*(struct file_entry **)ap)->file;
-    b = (*(struct file_entry **)bp)->file;
-
-    return strcmp(a, b);
-}
-
-/* glob_pattern_p() taken from bash
- * Copyright (C) 1985, 1988, 1989 Free Software Foundation, Inc.
- */
-
-/* Return nonzero if PATTERN has any special globbing chars in it.  */
-static int glob_pattern_p (char *pattern)
-{
-    register char *p = pattern;
-    register char c;
-    int open = 0;
-  
-    while ((c = *p++) != '\0')
-       switch (c) {
-       case '?':
-       case '*':
-           return (1);
-       case '[':      /* Only accept an open brace if there is a close */
-           open++;    /* brace to match it.  Bracket expressions must be */
-           continue;  /* complete, according to Posix.2 */
-       case ']':
-           if (open)
-               return (1);
-           continue;      
-       case '\\':
-           if (*p++ == '\0')
-               return (0);
-       }
-
-    return (0);
-}
-
-static int glob_error(const char *foo, int bar)
-{
-    return 1;
-}
-
-static int parseForAttr(char *buf, char **currPmode,
-                       char **currUname, char **currGname)
-{
-    char *p, *start, *end;
-    char ourbuf[1024];
-    int mode, x;
-
-    if (!(p = start = strstr(buf, "%attr"))) {
-       return 1;
-    }
-
-    *currPmode = *currUname = *currGname = NULL;
-
-    p += 5;
-    while (*p && (*p == ' ' || *p == '\t')) {
-       p++;
-    }
-
-    if (*p != '(') {
-       error(RPMERR_BADSPEC, "Bad %%attr() syntax: %s", buf);
-       return 0;
-    }
-    p++;
-
-    end = p;
-    while (*end && *end != ')') {
-       end++;
-    }
-
-    if (! *end) {
-       error(RPMERR_BADSPEC, "Bad %%attr() syntax: %s", buf);
-       return 0;
-    }
-
-    strncpy(ourbuf, p, end-p);
-    ourbuf[end-p] = '\0';
-
-    *currPmode = strtok(ourbuf, ", \n\t");
-    *currUname = strtok(NULL, ", \n\t");
-    *currGname = strtok(NULL, ", \n\t");
-
-    if (! (*currPmode && *currUname && *currGname)) {
-       error(RPMERR_BADSPEC, "Bad %%attr() syntax: %s", buf);
-       *currPmode = *currUname = *currGname = NULL;
-       return 0;
-    }
-
-    /* Do a quick test on the mode argument */
-    if (strcmp(*currPmode, "-")) {
-       x = sscanf(*currPmode, "%o", &mode);
-       if ((x == 0) || (mode >> 12)) {
-           error(RPMERR_BADSPEC, "Bad %%attr() mode spec: %s", buf);
-           *currPmode = *currUname = *currGname = NULL;
-           return 0;
-       }
-    }
-    
-    *currPmode = strdup(*currPmode);
-    *currUname = strdup(*currUname);
-    *currGname = strdup(*currGname);
-    
-    /* Set everything we just parsed to blank spaces */
-    while (start <= end) {
-       *start++ = ' ';
-    }
-
-    return 1;
-}
-
-static int parseForVerify(char *buf, int *verify_flags)
-{
-    char *p, *start, *end;
-    char ourbuf[1024];
-    int not;
-
-    if (!(p = start = strstr(buf, "%verify"))) {
-       return 1;
-    }
-
-    p += 7;
-    while (*p && (*p == ' ' || *p == '\t')) {
-       p++;
-    }
-
-    if (*p != '(') {
-       error(RPMERR_BADSPEC, "Bad %%verify() syntax: %s", buf);
-       return 0;
-    }
-    p++;
-
-    end = p;
-    while (*end && *end != ')') {
-       end++;
-    }
-
-    if (! *end) {
-       error(RPMERR_BADSPEC, "Bad %%verify() syntax: %s", buf);
-       return 0;
-    }
-
-    strncpy(ourbuf, p, end-p);
-    ourbuf[end-p] = '\0';
-    while (start <= end) {
-       *start++ = ' ';
-    }
-
-    p = strtok(ourbuf, ", \n\t");
-    not = 0;
-    *verify_flags = VERIFY_NONE;
-    while (p) {
-       if (!strcmp(p, "not")) {
-           not = 1;
-       } else if (!strcmp(p, "md5")) {
-           *verify_flags |= VERIFY_MD5;
-       } else if (!strcmp(p, "size")) {
-           *verify_flags |= VERIFY_FILESIZE;
-       } else if (!strcmp(p, "link")) {
-           *verify_flags |= VERIFY_LINKTO;
-       } else if (!strcmp(p, "user")) {
-           *verify_flags |= VERIFY_USER;
-       } else if (!strcmp(p, "group")) {
-           *verify_flags |= VERIFY_GROUP;
-       } else if (!strcmp(p, "mtime")) {
-           *verify_flags |= VERIFY_MTIME;
-       } else if (!strcmp(p, "mode")) {
-           *verify_flags |= VERIFY_MODE;
-       } else if (!strcmp(p, "rdev")) {
-           *verify_flags |= VERIFY_RDEV;
-       } else {
-           error(RPMERR_BADSPEC, "Invalid %%verify token: %s", p);
-           return 0;
-       }
-       p = strtok(NULL, ", \n\t");
-    }
-
-    if (not) {
-       *verify_flags = ~(*verify_flags);
-    }
-
-    return 1;
-}
-
-static int process_filelist(Header header, struct PackageRec *pr,
-                           StringBuf sb, int *size, char *name,
-                           char *version, char *release, int type)
-{
-    char buf[1024];
-    char **files, **fp;
-    struct file_entry *fes, *fest;
-    struct file_entry **file_entry_array;
-    int isdoc, isconf, isdir, verify_flags;
-    char *currPmode=NULL;      /* hold info from %attr() */
-    char *currUname=NULL;      /* hold info from %attr() */
-    char *currGname=NULL;      /* hold info from %attr() */
-    char *filename, *s;
-    char *str;
-    int count = 0;
-    int c, x;
-    glob_t glob_result;
-    int special_doc;
-    int passed_special_doc = 0;
-    FILE *file;
-
-    fes = NULL;
-    *size = 0;
-
-    resetDocdir();
-
-    if (type == RPMLEAD_BINARY && pr->fileFile) {
-       sprintf(buf, "%s/%s/%s", getVar(RPMVAR_BUILDDIR),
-               build_subdir, pr->fileFile);
-       message(MESS_DEBUG, "Reading file names from: %sXX\n", buf);
-       if ((file = fopen(buf, "r")) == NULL) {
-           perror("open fileFile");
-           exit(1);
-       }
-       while (fgets(buf, sizeof(buf), file)) {
-           appendStringBuf(sb, buf);
-       }
-       fclose(file);
-    }
-    
-    str = getStringBuf(sb);
-    files = splitString(str, strlen(str), '\n');
-    fp = files;
-
-    while (*fp) {
-       strcpy(buf, *fp);  /* temp copy */
-       isdoc = 0;
-       special_doc = 0;
-       isconf = 0;
-       isdir = 0;
-       if (currPmode) {
-           free (currPmode);
-           currPmode = NULL;
-       }
-       if (currUname) {
-           free (currUname);
-           currUname = NULL;
-       }
-       if (currGname) {
-           free (currGname);
-           currGname = NULL;
-       }
-       verify_flags = VERIFY_ALL;
-       filename = NULL;
-
-       /* First preparse buf for %verify() */
-       if (!parseForVerify(buf, &verify_flags)) {
-           return(RPMERR_BADSPEC);
-       }
-       
-       /* Next parse for for %attr() */
-       if (!parseForAttr(buf, &currPmode, &currUname, &currGname)) {
-           return(RPMERR_BADSPEC);
-       }
-
-       s = strtok(buf, " \t\n");
-       while (s) {
-           if (!strcmp(s, "%docdir")) {
-               s = strtok(NULL, " \t\n");
-               addDocdir(s);
-               break;
-           } else if (!strcmp(s, "%doc")) {
-               isdoc = 1;
-           } else if (!strcmp(s, "%config")) {
-               isconf = 1;
-           } else if (!strcmp(s, "%dir")) {
-               isdir = 1;
-           } else {
-               if (isdoc && (*s != '/')) {
-                   /* This is a special %doc macro */
-                   special_doc = 1;
-               } else {
-                   filename = s;
-               }
-           }
-           s = strtok(NULL, " \t\n");
-       }
-       if (special_doc) {
-           if (passed_special_doc) {
-               fp++;
-               continue;
-           } else {
-               if (filename || isconf || isdir) {
-                   error(RPMERR_BADSPEC,
-                         "Can't mix special %%doc with other forms: %s", fp);
-                   return(RPMERR_BADSPEC);
-               }
-               sprintf(buf, "%s/%s-%s-%s", getVar(RPMVAR_DOCDIR),
-                       name, version, release);
-               filename = buf;
-               passed_special_doc = 1;
-           }
-       }
-       if (! filename) {
-           fp++;
-           continue;
-       }
-
-       if (type == RPMLEAD_BINARY) {
-           /* check that file starts with leading "/" */
-           if (*filename != '/') {
-               error(RPMERR_BADSPEC,
-                     "File needs leading \"/\": %s", filename);
-               return(RPMERR_BADSPEC);
-           }
-
-           if (glob_pattern_p(filename)) {
-               char fullname[1024];
-
-               if (getVar(RPMVAR_ROOT)) {
-                   sprintf(fullname, "%s%s", getVar(RPMVAR_ROOT), filename);
-               } else {
-                   strcpy(fullname, filename);
-               }
-
-               if (glob(fullname, 0, glob_error, &glob_result)) {
-                   error(RPMERR_BADSPEC, "No matches: %s", fullname);
-                   return(RPMERR_BADSPEC);
-               }
-               if (glob_result.gl_pathc < 1) {
-                   error(RPMERR_BADSPEC, "No matches: %s", fullname);
-                   return(RPMERR_BADSPEC);
-               }
-               x = 0;
-               c = 0;
-               while (x < glob_result.gl_pathc) {
-                   int offset = strlen(getVar(RPMVAR_ROOT) ? : "");
-                   c += add_file(&fes, &(glob_result.gl_pathv[x][offset]),
-                                 isdoc, isconf, isdir, verify_flags,
-                                 currPmode, currUname, currGname);
-                   x++;
-               }
-               globfree(&glob_result);
-           } else {
-               c = add_file(&fes, filename, isdoc, isconf, isdir,
-                            verify_flags, currPmode, currUname, currGname);
-           }
-       } else {
-           /* Source package are the simple case */
-           fest = malloc(sizeof(struct file_entry));
-           fest->isdoc = 0;
-           fest->isconf = 0;
-           fest->verify_flags = 0;  /* XXX - something else? */
-           stat(filename, &fest->statbuf);
-           fest->uname = getUname(fest->statbuf.st_uid);
-           fest->gname = getGname(fest->statbuf.st_gid);
-           strcpy(fest->file, filename);
-           fest->next = fes;
-           fes = fest;
-           c = 1;
-       }
-           
-       if (! c) {
-           error(RPMERR_BADSPEC, "File not found: %s", filename);
-           return(RPMERR_BADSPEC);
-       }
-       count += c;
-       
-       fp++;
-    }
-
-    /* If there are no files, don't add anything to the header */
-    if (count) {
-       char ** fileList;
-       char ** fileMD5List;
-       char ** fileLinktoList;
-       int_32 * fileSizeList;
-       int_32 * fileUIDList;
-       int_32 * fileGIDList;
-       char ** fileUnameList;
-       char ** fileGnameList;
-       int_32 * fileMtimesList;
-       int_32 * fileFlagsList;
-       int_16 * fileModesList;
-       int_16 * fileRDevsList;
-       int_32 * fileVerifyFlagsList;
-
-       fileList = malloc(sizeof(char *) * count);
-       fileLinktoList = malloc(sizeof(char *) * count);
-       fileMD5List = malloc(sizeof(char *) * count);
-       fileSizeList = malloc(sizeof(int_32) * count);
-       fileUIDList = malloc(sizeof(int_32) * count);
-       fileGIDList = malloc(sizeof(int_32) * count);
-       fileUnameList = malloc(sizeof(char *) * count);
-       fileGnameList = malloc(sizeof(char *) * count);
-       fileMtimesList = malloc(sizeof(int_32) * count);
-       fileFlagsList = malloc(sizeof(int_32) * count);
-       fileModesList = malloc(sizeof(int_16) * count);
-       fileRDevsList = malloc(sizeof(int_16) * count);
-       fileVerifyFlagsList = malloc(sizeof(int_32) * count);
-
-       /* Build a reverse sorted file array.  */
-       /* This makes uninstalls a lot easier. */
-       file_entry_array = malloc(sizeof(struct file_entry *) * count);
-       c = 0;
-       fest = fes;
-       while (fest) {
-           file_entry_array[c++] = fest;
-           fest = fest->next;
-       }
-       qsort(file_entry_array, count, sizeof(struct file_entry *),
-             compare_fe);
-       
-       c = 0;
-       while (c < count) {
-           fest = file_entry_array[c];
-           if (type == RPMLEAD_BINARY) {
-               fileList[c] = fest->file;
-           } else {
-               fileList[c] = strrchr(fest->file, '/') + 1;
-           }
-           fileUnameList[c] = fest->uname;
-           fileGnameList[c] = fest->gname;
-           *size += fest->statbuf.st_size;
-           if (S_ISREG(fest->statbuf.st_mode)) {
-               if (getVar(RPMVAR_ROOT)) {
-                   sprintf(buf, "%s%s", getVar(RPMVAR_ROOT), fest->file);
-               } else {
-                   strcpy(buf, fest->file);
-               }
-               mdfile(buf, buf);
-               fileMD5List[c] = strdup(buf);
-               message(MESS_DEBUG, "md5(%s) = %s\n", fest->file, buf);
-           } else {
-               /* This is stupid */
-               fileMD5List[c] = strdup("");
-           }
-           fileSizeList[c] = fest->statbuf.st_size;
-           fileUIDList[c] = fest->statbuf.st_uid;
-           fileGIDList[c] = fest->statbuf.st_gid;
-           fileMtimesList[c] = fest->statbuf.st_mtime;
-           fileFlagsList[c] = 0;
-           if (isDoc(fest->file))
-               fileFlagsList[c] |= RPMFILE_DOC;
-           if (fest->isdoc) 
-               fileFlagsList[c] |= RPMFILE_DOC;
-           if (fest->isconf)
-               fileFlagsList[c] |= RPMFILE_CONFIG;
-
-           fileModesList[c] = fest->statbuf.st_mode;
-           fileRDevsList[c] = fest->statbuf.st_rdev;
-           fileVerifyFlagsList[c] = fest->verify_flags;
-
-           if (S_ISLNK(fest->statbuf.st_mode)) {
-               if (getVar(RPMVAR_ROOT)) {
-                   sprintf(buf, "%s%s", getVar(RPMVAR_ROOT), fest->file);
-               } else {
-                   strcpy(buf, fest->file);
-               }
-               buf[readlink(buf, buf, 1024)] = '\0';
-               fileLinktoList[c] = strdup(buf);
-           } else {
-               /* This is stupid */
-               fileLinktoList[c] = strdup("");
-           }
-           c++;
-       }
-
-       /* Add the header entries */
-       c = count;
-       addEntry(header, RPMTAG_FILENAMES, STRING_ARRAY_TYPE, fileList, c);
-       addEntry(header, RPMTAG_FILELINKTOS, STRING_ARRAY_TYPE,
-                fileLinktoList, c);
-       addEntry(header, RPMTAG_FILEMD5S, STRING_ARRAY_TYPE, fileMD5List, c);
-       addEntry(header, RPMTAG_FILESIZES, INT32_TYPE, fileSizeList, c);
-       addEntry(header, RPMTAG_FILEUIDS, INT32_TYPE, fileUIDList, c);
-       addEntry(header, RPMTAG_FILEGIDS, INT32_TYPE, fileGIDList, c);
-       addEntry(header, RPMTAG_FILEUSERNAME, STRING_ARRAY_TYPE,
-                fileUnameList, c);
-       addEntry(header, RPMTAG_FILEGROUPNAME, STRING_ARRAY_TYPE,
-                fileGnameList, c);
-       addEntry(header, RPMTAG_FILEMTIMES, INT32_TYPE, fileMtimesList, c);
-       addEntry(header, RPMTAG_FILEFLAGS, INT32_TYPE, fileFlagsList, c);
-       addEntry(header, RPMTAG_FILEMODES, INT16_TYPE, fileModesList, c);
-       addEntry(header, RPMTAG_FILERDEVS, INT16_TYPE, fileRDevsList, c);
-       addEntry(header, RPMTAG_FILEVERIFYFLAGS, INT32_TYPE,
-                fileVerifyFlagsList, c);
-       
-       /* Free the allocated strings */
-       c = count;
-       while (c--) {
-           free(fileMD5List[c]);
-           free(fileLinktoList[c]);
-       }
-
-       /* Free all those lists */
-       free(fileList);
-       free(fileLinktoList);
-       free(fileMD5List);
-       free(fileSizeList);
-       free(fileUIDList);
-       free(fileGIDList);
-       free(fileUnameList);
-       free(fileGnameList);
-       free(fileMtimesList);
-       free(fileFlagsList);
-       free(fileModesList);
-       free(fileRDevsList);
-       free(fileVerifyFlagsList);
-       
-       /* Free the file entry array */
-       free(file_entry_array);
-       
-       /* Free the file entry stack */
-       fest = fes;
-       while (fest) {
-           fes = fest->next;
-           free(fest);
-           fest = fes;
-       }
-    }
-    
-    freeSplitString(files);
-    return 0;
-}
-
-static time_t buildtime;
-void markBuildTime(void)
-{
-    buildtime = time(NULL);
-}
-
-static char *buildHost(void)
-{
-    static char hostname[1024];
-    static int gotit = 0;
-    struct hostent *hbn;
-
-    if (! gotit) {
-        gethostname(hostname, sizeof(hostname));
-       if ((hbn = gethostbyname(hostname))) {
-           strcpy(hostname, hbn->h_name);
-       } else {
-           message(MESS_WARNING, "Could not canonicalize hostname: %s\n",
-                   hostname);
-       }
-       gotit = 1;
-    }
-    return(hostname);
-}
 
 int packageBinaries(Spec s, char *passPhrase)
 {
@@ -1346,7 +462,7 @@ int packageBinaries(Spec s, char *passPhrase)
        arch = getArchNum();
        addEntry(outHeader, RPMTAG_OS, INT8_TYPE, &os, 1);
        addEntry(outHeader, RPMTAG_ARCH, INT8_TYPE, &arch, 1);
-       addEntry(outHeader, RPMTAG_BUILDTIME, INT32_TYPE, &buildtime, 1);
+       addEntry(outHeader, RPMTAG_BUILDTIME, INT32_TYPE, getBuildTime(), 1);
        addEntry(outHeader, RPMTAG_BUILDHOST, STRING_TYPE, buildHost(), 1);
        addEntry(outHeader, RPMTAG_SOURCERPM, STRING_TYPE, sourcerpm, 1);
        if (pr->icon) {
@@ -1382,8 +498,10 @@ int packageBinaries(Spec s, char *passPhrase)
            return 1;
        }
 
-       /* Add any require/provide entries */
-       addReqProvHeaderEntry(outHeader, pr);
+       /* Generate any automatic require/provide entries */
+       /* Then add the whole thing to the header         */
+       generateAutoReqProv(outHeader, pr);
+       processReqProv(outHeader, pr);
        
        /* And add the final Header entry */
        addEntry(outHeader, RPMTAG_SIZE, INT32_TYPE, &size, 1);
@@ -1481,7 +599,7 @@ int packageSource(Spec s, char *passPhrase)
     arch = getArchNum();
     addEntry(outHeader, RPMTAG_OS, INT8_TYPE, &os, 1);
     addEntry(outHeader, RPMTAG_ARCH, INT8_TYPE, &arch, 1);
-    addEntry(outHeader, RPMTAG_BUILDTIME, INT32_TYPE, &buildtime, 1);
+    addEntry(outHeader, RPMTAG_BUILDTIME, INT32_TYPE, getBuildTime(), 1);
     addEntry(outHeader, RPMTAG_BUILDHOST, STRING_TYPE, buildHost(), 1);
     if (scount) 
         addEntry(outHeader, RPMTAG_SOURCE, STRING_ARRAY_TYPE, sources, scount);
@@ -1540,38 +658,3 @@ int packageSource(Spec s, char *passPhrase)
     
     return 0;
 }
-
-/****************** Source Removal ********************/
-
-int doRmSource(Spec s)
-{
-    char filename[1024];
-    struct sources *source;
-    struct PackageRec *package;
-
-    /* spec file */
-    sprintf(filename, "%s%s", getVar(RPMVAR_SPECDIR),
-           strrchr(s->specfile, '/'));
-    unlink(filename);
-
-    /* sources and patches */
-    source = s->sources;
-    while (source) {
-       sprintf(filename, "%s/%s", getVar(RPMVAR_SOURCEDIR), source->source);
-       unlink(filename);
-       source = source->next;
-    }
-
-    /* icons */
-    package = s->packages;
-    while (package) {
-       if (package->icon) {
-           sprintf(filename, "%s/%s", getVar(RPMVAR_SOURCEDIR),
-                   package->icon);
-           unlink(filename);
-       }
-       package = package->next;
-    }
-    
-    return 0;
-}