1995-12-21 06:49:40 +08:00
|
|
|
/* RPM - Copyright (C) 1995 Red Hat Software
|
|
|
|
*
|
|
|
|
* pack.c - routines for packaging
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/utsname.h>
|
|
|
|
#include <sys/wait.h>
|
|
|
|
#include <sys/stat.h>
|
1996-02-20 07:00:16 +08:00
|
|
|
#include <sys/signal.h>
|
1995-12-21 06:49:40 +08:00
|
|
|
#include <string.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <time.h>
|
1995-12-28 00:52:14 +08:00
|
|
|
#include <ftw.h>
|
1995-12-28 03:50:19 +08:00
|
|
|
#include <netinet/in.h>
|
1996-01-10 00:28:15 +08:00
|
|
|
#include <pwd.h>
|
|
|
|
#include <grp.h>
|
1996-01-12 15:31:41 +08:00
|
|
|
#include <netdb.h>
|
1996-01-18 01:47:28 +08:00
|
|
|
#include <glob.h>
|
1996-02-20 07:00:16 +08:00
|
|
|
#include <zlib.h>
|
1995-12-21 06:49:40 +08:00
|
|
|
|
|
|
|
#include "header.h"
|
|
|
|
#include "specP.h"
|
|
|
|
#include "rpmerr.h"
|
1995-12-28 03:45:36 +08:00
|
|
|
#include "rpmlead.h"
|
|
|
|
#include "rpmlib.h"
|
1996-02-19 10:24:47 +08:00
|
|
|
#include "signature.h"
|
1995-12-21 06:49:40 +08:00
|
|
|
#include "misc.h"
|
|
|
|
#include "pack.h"
|
|
|
|
#include "messages.h"
|
|
|
|
#include "md5.h"
|
|
|
|
|
|
|
|
#define BINARY_HEADER 0
|
|
|
|
#define SOURCE_HEADER 1
|
|
|
|
|
|
|
|
struct file_entry {
|
|
|
|
char file[1024];
|
|
|
|
int isdoc;
|
|
|
|
int isconf;
|
1996-02-19 10:24:47 +08:00
|
|
|
int verify_flags;
|
1996-01-10 00:28:15 +08:00
|
|
|
char *uname; /* reference -- do not free */
|
|
|
|
char *gname; /* reference -- do not free */
|
1995-12-21 06:49:40 +08:00
|
|
|
struct stat statbuf;
|
|
|
|
struct file_entry *next;
|
|
|
|
};
|
|
|
|
|
1996-02-20 07:00:16 +08:00
|
|
|
static int cpio_gzip(Header header, int fd, char *tempdir, int *archiveSize);
|
1996-02-19 10:24:47 +08:00
|
|
|
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);
|
1996-01-12 10:48:35 +08:00
|
|
|
static int compare_fe(const void *ap, const void *bp);
|
1996-01-29 11:33:06 +08:00
|
|
|
static int process_filelist(Header header, StringBuf sb, int *size,
|
|
|
|
char *name, char *version, char *release,
|
|
|
|
int type);
|
1996-01-12 15:31:41 +08:00
|
|
|
static char *buildHost(void);
|
1996-01-30 10:16:47 +08:00
|
|
|
static int add_file_aux(const char *file, struct stat *sb, int flag);
|
1996-01-10 00:28:15 +08:00
|
|
|
static char *getUname(uid_t uid);
|
|
|
|
static char *getGname(gid_t gid);
|
1996-01-18 02:17:50 +08:00
|
|
|
static int glob_error(const char *foo, int bar);
|
|
|
|
static int glob_pattern_p (char *pattern);
|
1996-02-19 10:24:47 +08:00
|
|
|
static int parseForVerify(char *buf, int *verify_flags);
|
|
|
|
|
|
|
|
static
|
|
|
|
int generateRPM(char *name, /* name-version-release */
|
|
|
|
int type, /* source or binary */
|
|
|
|
Header header, /* the header */
|
1996-02-21 00:00:04 +08:00
|
|
|
char *stempdir, /* directory containing sources */
|
|
|
|
char *passPhrase);
|
1995-12-21 06:49:40 +08:00
|
|
|
|
1996-01-12 15:31:41 +08:00
|
|
|
static void resetDocdir(void);
|
|
|
|
static void addDocdir(char *dirname);
|
|
|
|
static int isDoc(char *filename);
|
|
|
|
|
1996-02-19 10:24:47 +08:00
|
|
|
int generateRPM(char *name, /* name-version-release */
|
|
|
|
int type, /* source or binary */
|
|
|
|
Header header, /* the header */
|
1996-02-21 00:00:04 +08:00
|
|
|
char *stempdir, /* directory containing sources */
|
|
|
|
char *passPhrase)
|
1996-02-19 10:24:47 +08:00
|
|
|
{
|
|
|
|
unsigned short sigtype;
|
|
|
|
char *archName;
|
|
|
|
char filename[1024];
|
1996-02-20 07:00:16 +08:00
|
|
|
char *sigtarget, *archiveTemp;
|
|
|
|
int fd, ifd, count, archiveSize;
|
|
|
|
unsigned char buffer[8192];
|
1996-02-19 10:24:47 +08:00
|
|
|
|
|
|
|
/* Figure out the signature type */
|
|
|
|
if ((sigtype = sigLookupType()) == RPMSIG_BAD) {
|
|
|
|
error(RPMERR_BADSIGTYPE, "Bad signature type in rpmrc");
|
|
|
|
return RPMERR_BADSIGTYPE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make the output RPM filename */
|
|
|
|
if (type == RPMLEAD_SOURCE) {
|
|
|
|
sprintf(filename, "%s/%s.src.rpm", getVar(RPMVAR_SRPMDIR), name);
|
|
|
|
} else {
|
|
|
|
archName = getArchName();
|
|
|
|
sprintf(filename, "%s/%s/%s.%s.rpm", getVar(RPMVAR_RPMDIR),
|
|
|
|
archName, name, archName);
|
|
|
|
}
|
|
|
|
|
1996-02-20 07:00:16 +08:00
|
|
|
/* Write the archive to a temp file so we can get the size */
|
1996-03-29 09:26:20 +08:00
|
|
|
archiveTemp = tempnam("/var/tmp", "rpmbuild");
|
1996-02-20 07:00:16 +08:00
|
|
|
fd = open(archiveTemp, O_WRONLY|O_CREAT|O_TRUNC, 0644);
|
|
|
|
if (cpio_gzip(header, fd, stempdir, &archiveSize)) {
|
1996-02-22 09:35:34 +08:00
|
|
|
close(fd);
|
|
|
|
unlink(archiveTemp);
|
1996-02-20 07:00:16 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
/* Add the archive size to the Header */
|
|
|
|
addEntry(header, RPMTAG_ARCHIVESIZE, INT32_TYPE, &archiveSize, 1);
|
|
|
|
|
|
|
|
/* Now write the header and append the archive */
|
1996-03-29 09:26:20 +08:00
|
|
|
sigtarget = tempnam("/var/tmp", "rpmbuild");
|
1996-02-19 10:24:47 +08:00
|
|
|
fd = open(sigtarget, O_WRONLY|O_CREAT|O_TRUNC, 0644);
|
|
|
|
writeHeader(fd, header);
|
1996-02-20 07:00:16 +08:00
|
|
|
ifd = open(archiveTemp, O_RDONLY, 0644);
|
|
|
|
while ((count = read(ifd, buffer, sizeof(buffer))) > 0) {
|
1996-02-22 23:34:27 +08:00
|
|
|
if (count == -1) {
|
|
|
|
perror("Couldn't read archiveTemp");
|
1996-02-22 23:46:54 +08:00
|
|
|
close(fd);
|
|
|
|
close(ifd);
|
|
|
|
unlink(archiveTemp);
|
|
|
|
unlink(sigtarget);
|
|
|
|
return 1;
|
1996-02-22 23:34:27 +08:00
|
|
|
}
|
|
|
|
if (write(fd, buffer, count) < 0) {
|
|
|
|
perror("Couldn't write package to temp file");
|
1996-02-22 23:46:54 +08:00
|
|
|
close(fd);
|
|
|
|
close(ifd);
|
|
|
|
unlink(archiveTemp);
|
|
|
|
unlink(sigtarget);
|
|
|
|
return 1;
|
1996-02-22 23:34:27 +08:00
|
|
|
}
|
1996-02-19 10:24:47 +08:00
|
|
|
}
|
1996-02-20 07:00:16 +08:00
|
|
|
close(ifd);
|
1996-02-19 10:24:47 +08:00
|
|
|
close(fd);
|
1996-02-20 07:00:16 +08:00
|
|
|
unlink(archiveTemp);
|
1996-02-19 10:24:47 +08:00
|
|
|
|
|
|
|
/* Now write the lead */
|
|
|
|
fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644);
|
|
|
|
if (writeMagic(fd, name, type, sigtype)) {
|
1996-02-22 09:35:34 +08:00
|
|
|
close(fd);
|
|
|
|
unlink(sigtarget);
|
|
|
|
unlink(filename);
|
1996-02-19 10:24:47 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Generate the signature */
|
|
|
|
message(MESS_VERBOSE, "Generating signature: %d\n", sigtype);
|
|
|
|
fflush(stdout);
|
1996-02-22 09:35:34 +08:00
|
|
|
if (makeSignature(sigtarget, sigtype, fd, passPhrase)) {
|
|
|
|
close(fd);
|
|
|
|
unlink(sigtarget);
|
|
|
|
unlink(filename);
|
|
|
|
return 1;
|
|
|
|
}
|
1996-02-19 10:24:47 +08:00
|
|
|
|
|
|
|
/* Append the header and archive */
|
|
|
|
ifd = open(sigtarget, O_RDONLY);
|
1996-02-20 07:00:16 +08:00
|
|
|
while ((count = read(ifd, buffer, sizeof(buffer))) > 0) {
|
1996-02-22 23:34:27 +08:00
|
|
|
if (count == -1) {
|
|
|
|
perror("Couldn't read sigtarget");
|
1996-02-22 23:46:54 +08:00
|
|
|
close(ifd);
|
|
|
|
close(fd);
|
|
|
|
unlink(sigtarget);
|
|
|
|
unlink(filename);
|
|
|
|
return 1;
|
1996-02-22 23:34:27 +08:00
|
|
|
}
|
|
|
|
if (write(fd, buffer, count) < 0) {
|
|
|
|
perror("Couldn't write package");
|
1996-02-22 23:46:54 +08:00
|
|
|
close(ifd);
|
|
|
|
close(fd);
|
|
|
|
unlink(sigtarget);
|
|
|
|
unlink(filename);
|
|
|
|
return 1;
|
1996-02-22 23:34:27 +08:00
|
|
|
}
|
1996-02-19 10:24:47 +08:00
|
|
|
}
|
|
|
|
close(ifd);
|
|
|
|
close(fd);
|
|
|
|
unlink(sigtarget);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int writeMagic(int fd, char *name,
|
|
|
|
unsigned short type,
|
|
|
|
unsigned short sigtype)
|
1995-12-21 06:49:40 +08:00
|
|
|
{
|
1995-12-28 03:45:36 +08:00
|
|
|
struct rpmlead lead;
|
1995-12-21 06:49:40 +08:00
|
|
|
|
1995-12-28 03:45:36 +08:00
|
|
|
lead.major = 2;
|
|
|
|
lead.minor = 0;
|
1996-01-05 11:13:40 +08:00
|
|
|
lead.type = type;
|
|
|
|
lead.archnum = getArchNum();
|
|
|
|
lead.osnum = getOsNum();
|
1996-02-19 10:24:47 +08:00
|
|
|
lead.signature_type = sigtype;
|
1995-12-28 03:45:36 +08:00
|
|
|
strncpy(lead.name, name, sizeof(lead.name));
|
|
|
|
|
1996-01-05 11:13:40 +08:00
|
|
|
writeLead(fd, &lead);
|
1995-12-21 06:49:40 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1996-02-20 07:00:16 +08:00
|
|
|
static int cpio_gzip(Header header, int fd, char *tempdir, int *archiveSize)
|
1995-12-21 06:49:40 +08:00
|
|
|
{
|
1995-12-28 00:52:14 +08:00
|
|
|
char **f, *s;
|
1995-12-21 06:49:40 +08:00
|
|
|
int count;
|
1996-02-29 08:55:31 +08:00
|
|
|
int cpioPID, gzipPID;
|
|
|
|
int cpioDead, gzipDead;
|
|
|
|
int toCpio[2];
|
|
|
|
int fromCpio[2];
|
|
|
|
int toGzip[2];
|
|
|
|
|
1996-02-21 07:31:59 +08:00
|
|
|
StringBuf writeBuff;
|
|
|
|
char *writePtr;
|
|
|
|
int writeBytesLeft, bytesWritten;
|
1995-12-21 06:49:40 +08:00
|
|
|
|
1996-02-29 08:55:31 +08:00
|
|
|
int bytes;
|
|
|
|
unsigned char buf[8192];
|
|
|
|
|
|
|
|
int status;
|
|
|
|
void *oldhandler;
|
|
|
|
|
1996-02-20 07:00:16 +08:00
|
|
|
*archiveSize = 0;
|
|
|
|
|
1996-02-29 08:55:31 +08:00
|
|
|
pipe(toCpio);
|
|
|
|
pipe(fromCpio);
|
1995-12-21 06:49:40 +08:00
|
|
|
|
1996-02-20 07:00:16 +08:00
|
|
|
oldhandler = signal(SIGPIPE, SIG_IGN);
|
|
|
|
|
1996-02-29 08:55:31 +08:00
|
|
|
/* CPIO */
|
1995-12-21 06:49:40 +08:00
|
|
|
if (!(cpioPID = fork())) {
|
|
|
|
close(0);
|
|
|
|
close(1);
|
1996-02-29 08:55:31 +08:00
|
|
|
close(toCpio[1]);
|
|
|
|
close(fromCpio[0]);
|
1995-12-21 06:49:40 +08:00
|
|
|
close(fd);
|
|
|
|
|
1996-02-29 08:55:31 +08:00
|
|
|
dup2(toCpio[0], 0); /* Make stdin the in pipe */
|
|
|
|
dup2(fromCpio[1], 1); /* Make stdout the out pipe */
|
1995-12-21 06:49:40 +08:00
|
|
|
|
1996-01-08 15:07:35 +08:00
|
|
|
if (tempdir) {
|
|
|
|
chdir(tempdir);
|
|
|
|
} else if (getVar(RPMVAR_ROOT)) {
|
1995-12-28 00:52:14 +08:00
|
|
|
if (chdir(getVar(RPMVAR_ROOT))) {
|
|
|
|
error(RPMERR_EXEC, "Couldn't chdir to %s",
|
|
|
|
getVar(RPMVAR_ROOT));
|
|
|
|
exit(RPMERR_EXEC);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
chdir("/");
|
|
|
|
}
|
|
|
|
|
1996-01-08 15:07:35 +08:00
|
|
|
execlp("cpio", "cpio",
|
|
|
|
(isVerbose()) ? "-ov" : "-o",
|
|
|
|
(tempdir) ? "-LH" : "-H",
|
|
|
|
"crc", NULL);
|
1995-12-21 06:49:40 +08:00
|
|
|
error(RPMERR_EXEC, "Couldn't exec cpio");
|
|
|
|
exit(RPMERR_EXEC);
|
|
|
|
}
|
|
|
|
if (cpioPID < 0) {
|
1996-02-29 08:55:31 +08:00
|
|
|
error(RPMERR_FORK, "Couldn't fork cpio");
|
1995-12-21 06:49:40 +08:00
|
|
|
return RPMERR_FORK;
|
|
|
|
}
|
|
|
|
|
1996-02-29 08:55:31 +08:00
|
|
|
pipe(toGzip);
|
|
|
|
|
|
|
|
/* GZIP */
|
|
|
|
if (!(gzipPID = fork())) {
|
|
|
|
close(0);
|
|
|
|
close(1);
|
|
|
|
close(toGzip[1]);
|
|
|
|
close(toCpio[0]);
|
|
|
|
close(toCpio[1]);
|
|
|
|
close(fromCpio[0]);
|
|
|
|
close(fromCpio[1]);
|
|
|
|
|
|
|
|
dup2(toGzip[0], 0); /* Make stdin the in pipe */
|
|
|
|
dup2(fd, 1); /* Make stdout the passed-in fd */
|
1995-12-21 06:49:40 +08:00
|
|
|
|
1996-02-29 08:55:31 +08:00
|
|
|
execlp("gzip", "gzip", "-c9fn", NULL);
|
|
|
|
error(RPMERR_EXEC, "Couldn't exec gzip");
|
|
|
|
exit(RPMERR_EXEC);
|
|
|
|
}
|
|
|
|
if (gzipPID < 0) {
|
|
|
|
error(RPMERR_FORK, "Couldn't fork gzip");
|
|
|
|
return RPMERR_FORK;
|
|
|
|
}
|
|
|
|
|
|
|
|
close(toCpio[0]);
|
|
|
|
close(fromCpio[1]);
|
|
|
|
close(toGzip[0]);
|
|
|
|
|
|
|
|
/* It is OK to block writing to gzip. But it is not OK */
|
|
|
|
/* to block reading or writing from/to cpio. */
|
|
|
|
fcntl(fromCpio[0], F_SETFL, O_NONBLOCK);
|
|
|
|
fcntl(toCpio[1], F_SETFL, O_NONBLOCK);
|
1995-12-21 06:49:40 +08:00
|
|
|
|
1996-02-20 07:00:16 +08:00
|
|
|
if (!getEntry(header, RPMTAG_FILENAMES, NULL, (void **) &f, &count)) {
|
|
|
|
/* count may already be 0, but this is safer */
|
|
|
|
count = 0;
|
1995-12-21 06:49:40 +08:00
|
|
|
}
|
1996-02-20 07:00:16 +08:00
|
|
|
|
1996-02-21 07:31:59 +08:00
|
|
|
writeBuff = newStringBuf();
|
|
|
|
writeBytesLeft = 0;
|
|
|
|
while (count--) {
|
|
|
|
s = *f++;
|
|
|
|
if (!tempdir) {
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
writeBytesLeft += strlen(s) + 1;
|
|
|
|
appendLineStringBuf(writeBuff, s);
|
|
|
|
}
|
|
|
|
writePtr = getStringBuf(writeBuff);
|
|
|
|
|
1996-02-20 07:00:16 +08:00
|
|
|
cpioDead = 0;
|
1996-02-29 08:55:31 +08:00
|
|
|
gzipDead = 0;
|
1996-02-20 07:00:16 +08:00
|
|
|
do {
|
|
|
|
if (waitpid(cpioPID, &status, WNOHANG)) {
|
|
|
|
cpioDead = 1;
|
|
|
|
}
|
1996-02-29 08:55:31 +08:00
|
|
|
if (waitpid(gzipPID, &status, WNOHANG)) {
|
|
|
|
gzipDead = 1;
|
|
|
|
}
|
1995-12-21 06:49:40 +08:00
|
|
|
|
1996-02-29 08:55:31 +08:00
|
|
|
/* Write some stuff to the cpio process if possible */
|
1996-02-21 07:31:59 +08:00
|
|
|
if (writeBytesLeft) {
|
|
|
|
if ((bytesWritten =
|
1996-02-29 08:55:31 +08:00
|
|
|
write(toCpio[1], writePtr,
|
1996-02-21 07:31:59 +08:00
|
|
|
(1024<writeBytesLeft) ? 1024 : writeBytesLeft)) < 0) {
|
|
|
|
if (errno != EAGAIN) {
|
|
|
|
perror("Damn!");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
bytesWritten = 0;
|
|
|
|
}
|
|
|
|
writeBytesLeft -= bytesWritten;
|
|
|
|
writePtr += bytesWritten;
|
1996-02-20 07:00:16 +08:00
|
|
|
} else {
|
1996-02-29 08:55:31 +08:00
|
|
|
close(toCpio[1]);
|
1996-02-20 07:00:16 +08:00
|
|
|
}
|
|
|
|
|
1996-02-29 08:55:31 +08:00
|
|
|
/* Read any data from cpio, write it to gzip */
|
|
|
|
bytes = read(fromCpio[0], buf, sizeof(buf));
|
1996-02-20 07:00:16 +08:00
|
|
|
while (bytes > 0) {
|
|
|
|
*archiveSize += bytes;
|
1996-02-29 08:55:31 +08:00
|
|
|
write(toGzip[1], buf, bytes);
|
|
|
|
bytes = read(fromCpio[0], buf, sizeof(buf));
|
1995-12-21 06:49:40 +08:00
|
|
|
}
|
|
|
|
|
1996-02-29 08:55:31 +08:00
|
|
|
/* while cpio is running, or we are writing to gzip */
|
|
|
|
/* terminate if gzip dies on us in the middle */
|
|
|
|
} while (((!cpioDead) || bytes) && (!gzipDead));
|
1996-02-20 07:00:16 +08:00
|
|
|
|
1996-02-29 08:55:31 +08:00
|
|
|
if (gzipDead) {
|
|
|
|
error(RPMERR_GZIP, "gzip died");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
close(toGzip[1]); /* Terminates the gzip process */
|
|
|
|
close(toCpio[1]);
|
|
|
|
close(fromCpio[0]);
|
1996-02-20 07:00:16 +08:00
|
|
|
|
|
|
|
signal(SIGPIPE, oldhandler);
|
1996-02-29 08:55:31 +08:00
|
|
|
|
|
|
|
if (writeBytesLeft) {
|
|
|
|
error(RPMERR_CPIO, "failed to write all data to cpio");
|
|
|
|
return 1;
|
|
|
|
}
|
1995-12-21 06:49:40 +08:00
|
|
|
waitpid(cpioPID, &status, 0);
|
|
|
|
if (!WIFEXITED(status) || WEXITSTATUS(status)) {
|
|
|
|
error(RPMERR_CPIO, "cpio failed");
|
|
|
|
return 1;
|
|
|
|
}
|
1996-02-29 08:55:31 +08:00
|
|
|
waitpid(gzipPID, &status, 0);
|
|
|
|
if (!WIFEXITED(status) || WEXITSTATUS(status)) {
|
|
|
|
error(RPMERR_GZIP, "gzip failed");
|
|
|
|
return 1;
|
|
|
|
}
|
1995-12-21 06:49:40 +08:00
|
|
|
|
1996-02-21 07:31:59 +08:00
|
|
|
freeStringBuf(writeBuff);
|
1995-12-21 06:49:40 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1996-01-12 15:31:41 +08:00
|
|
|
/* 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;
|
|
|
|
}
|
|
|
|
|
1996-01-10 00:28:15 +08:00
|
|
|
static char *getUname(uid_t uid)
|
|
|
|
{
|
|
|
|
static uid_t uids[1024];
|
|
|
|
static char *unames[1024];
|
|
|
|
static int used = 0;
|
|
|
|
|
|
|
|
struct passwd *pw;
|
|
|
|
int x;
|
|
|
|
|
|
|
|
x = 0;
|
|
|
|
while (x < 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;
|
|
|
|
used++;
|
|
|
|
if (pw) {
|
|
|
|
unames[x] = strdup(pw->pw_name);
|
|
|
|
} else {
|
|
|
|
unames[x] = "";
|
|
|
|
}
|
|
|
|
return unames[x];
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *getGname(gid_t gid)
|
|
|
|
{
|
|
|
|
static gid_t gids[1024];
|
|
|
|
static char *gnames[1024];
|
|
|
|
static int used = 0;
|
|
|
|
|
|
|
|
struct group *gr;
|
|
|
|
int x;
|
|
|
|
|
|
|
|
x = 0;
|
|
|
|
while (x < 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;
|
|
|
|
used++;
|
|
|
|
if (gr) {
|
|
|
|
gnames[x] = strdup(gr->gr_name);
|
|
|
|
} else {
|
|
|
|
gnames[x] = "";
|
|
|
|
}
|
|
|
|
return gnames[x];
|
|
|
|
}
|
|
|
|
|
1995-12-28 00:52:14 +08:00
|
|
|
/* Need three globals to keep track of things in ftw() */
|
|
|
|
static int Gisdoc;
|
|
|
|
static int Gisconf;
|
1996-02-19 10:24:47 +08:00
|
|
|
static int Gverify_flags;
|
1995-12-28 00:52:14 +08:00
|
|
|
static int Gcount;
|
|
|
|
static struct file_entry **Gfestack;
|
|
|
|
|
1996-02-19 10:24:47 +08:00
|
|
|
static int add_file(struct file_entry **festack, const char *name,
|
|
|
|
int isdoc, int isconf, int isdir, int verify_flags)
|
1995-12-21 06:49:40 +08:00
|
|
|
{
|
|
|
|
struct file_entry *p;
|
1995-12-28 00:52:14 +08:00
|
|
|
char fullname[1024];
|
|
|
|
|
|
|
|
/* Set these up for ftw() */
|
|
|
|
Gfestack = festack;
|
|
|
|
Gisdoc = isdoc;
|
|
|
|
Gisconf = isconf;
|
1996-02-19 10:24:47 +08:00
|
|
|
Gverify_flags = verify_flags;
|
1995-12-28 00:52:14 +08:00
|
|
|
|
1995-12-21 06:49:40 +08:00
|
|
|
p = malloc(sizeof(struct file_entry));
|
|
|
|
strcpy(p->file, name);
|
|
|
|
p->isdoc = isdoc;
|
|
|
|
p->isconf = isconf;
|
1996-02-19 10:24:47 +08:00
|
|
|
p->verify_flags = verify_flags;
|
1995-12-28 00:52:14 +08:00
|
|
|
if (getVar(RPMVAR_ROOT)) {
|
|
|
|
sprintf(fullname, "%s%s", getVar(RPMVAR_ROOT), name);
|
|
|
|
} else {
|
|
|
|
strcpy(fullname, name);
|
|
|
|
}
|
|
|
|
if (lstat(fullname, &p->statbuf)) {
|
|
|
|
return 0;
|
|
|
|
}
|
1996-01-10 00:28:15 +08:00
|
|
|
p->uname = getUname(p->statbuf.st_uid);
|
|
|
|
p->gname = getGname(p->statbuf.st_gid);
|
1995-12-28 00:52:14 +08:00
|
|
|
|
|
|
|
if ((! isdir) && S_ISDIR(p->statbuf.st_mode)) {
|
|
|
|
/* This means we need to decend with ftw() */
|
|
|
|
Gcount = 0;
|
|
|
|
|
1995-12-28 01:33:28 +08:00
|
|
|
ftw(fullname, add_file_aux, 16);
|
1995-12-28 00:52:14 +08:00
|
|
|
|
|
|
|
free(p);
|
1995-12-21 06:49:40 +08:00
|
|
|
|
1995-12-28 00:52:14 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1996-01-30 10:16:47 +08:00
|
|
|
static int add_file_aux(const char *file, struct stat *sb, int flag)
|
1995-12-28 00:52:14 +08:00
|
|
|
{
|
1996-01-30 10:16:47 +08:00
|
|
|
const char *name = file;
|
1995-12-28 00:52:14 +08:00
|
|
|
|
|
|
|
if (getVar(RPMVAR_ROOT)) {
|
|
|
|
name += strlen(getVar(RPMVAR_ROOT));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The 1 will cause add_file() to *not* descend */
|
|
|
|
/* directories -- ftw() is already doing it! */
|
1996-02-19 10:24:47 +08:00
|
|
|
Gcount += add_file(Gfestack, name, Gisdoc, Gisconf, 1, Gverify_flags);
|
1995-12-28 00:52:14 +08:00
|
|
|
|
|
|
|
return 0; /* for ftw() */
|
1995-12-21 06:49:40 +08:00
|
|
|
}
|
|
|
|
|
1996-01-12 10:48:35 +08:00
|
|
|
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;
|
|
|
|
|
1996-01-13 01:03:48 +08:00
|
|
|
return strcmp(a, b);
|
1996-01-12 10:48:35 +08:00
|
|
|
}
|
|
|
|
|
1996-01-18 01:47:28 +08:00
|
|
|
/* 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. */
|
1996-01-18 02:17:50 +08:00
|
|
|
static int glob_pattern_p (char *pattern)
|
1996-01-18 01:47:28 +08:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
1996-01-18 02:17:50 +08:00
|
|
|
static int glob_error(const char *foo, int bar)
|
1996-01-18 01:47:28 +08:00
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
1996-02-19 10:24:47 +08:00
|
|
|
static int parseForVerify(char *buf, int *verify_flags)
|
|
|
|
{
|
|
|
|
char *p, *start, *end;
|
|
|
|
char ourbuf[1024];
|
1996-02-20 07:41:46 +08:00
|
|
|
int not;
|
1996-02-19 10:24:47 +08:00
|
|
|
|
|
|
|
if (!(p = start = strstr(buf, "%verify"))) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
p += 7;
|
1996-02-20 07:41:46 +08:00
|
|
|
while (*p && *p == ' ' && *p == '\t') {
|
1996-02-19 10:24:47 +08:00
|
|
|
p++;
|
|
|
|
}
|
1996-02-20 07:41:46 +08:00
|
|
|
|
|
|
|
if (*p != '(') {
|
|
|
|
error(RPMERR_BADSPEC, "Bad %%verify() syntax: %s", buf);
|
|
|
|
return 0;
|
|
|
|
}
|
1996-02-19 10:24:47 +08:00
|
|
|
p++;
|
|
|
|
|
|
|
|
end = p;
|
1996-02-20 07:41:46 +08:00
|
|
|
while (*end && *end != ')') {
|
1996-02-19 10:24:47 +08:00
|
|
|
end++;
|
|
|
|
}
|
|
|
|
|
1996-02-20 07:41:46 +08:00
|
|
|
if (! *end) {
|
|
|
|
error(RPMERR_BADSPEC, "Bad %%verify() syntax: %s", buf);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1996-02-19 10:24:47 +08:00
|
|
|
strncpy(ourbuf, p, end-p);
|
1996-02-28 07:40:44 +08:00
|
|
|
ourbuf[end-p] = '\0';
|
1996-02-19 10:24:47 +08:00
|
|
|
while (start <= end) {
|
|
|
|
*start++ = ' ';
|
|
|
|
}
|
|
|
|
|
1996-02-20 09:35:04 +08:00
|
|
|
p = strtok(ourbuf, ", \n\t");
|
1996-02-20 07:41:46 +08:00
|
|
|
not = 0;
|
|
|
|
*verify_flags = VERIFY_NONE;
|
1996-02-19 10:24:47 +08:00
|
|
|
while (p) {
|
1996-02-20 07:41:46 +08:00
|
|
|
if (!strcmp(p, "not")) {
|
|
|
|
not = 1;
|
1996-02-19 10:24:47 +08:00
|
|
|
} else if (!strcmp(p, "md5")) {
|
1996-02-20 07:41:46 +08:00
|
|
|
*verify_flags |= VERIFY_MD5;
|
|
|
|
} else if (!strcmp(p, "size")) {
|
|
|
|
*verify_flags |= VERIFY_FILESIZE;
|
|
|
|
} else if (!strcmp(p, "link")) {
|
|
|
|
*verify_flags |= VERIFY_LINKTO;
|
1996-02-20 10:33:52 +08:00
|
|
|
} else if (!strcmp(p, "user")) {
|
|
|
|
*verify_flags |= VERIFY_USER;
|
|
|
|
} else if (!strcmp(p, "group")) {
|
|
|
|
*verify_flags |= VERIFY_GROUP;
|
1996-02-20 07:41:46 +08:00
|
|
|
} 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;
|
1996-02-19 10:24:47 +08:00
|
|
|
} else {
|
1996-02-20 07:41:46 +08:00
|
|
|
error(RPMERR_BADSPEC, "Invalid %%verify token: %s", p);
|
1996-02-19 10:24:47 +08:00
|
|
|
return 0;
|
|
|
|
}
|
1996-02-20 09:35:04 +08:00
|
|
|
p = strtok(NULL, ", \n\t");
|
1996-02-19 10:24:47 +08:00
|
|
|
}
|
|
|
|
|
1996-02-20 07:41:46 +08:00
|
|
|
if (not) {
|
|
|
|
*verify_flags = ~(*verify_flags);
|
|
|
|
}
|
|
|
|
|
1996-02-19 10:24:47 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
1996-01-29 11:33:06 +08:00
|
|
|
static int process_filelist(Header header, StringBuf sb, int *size,
|
|
|
|
char *name, char *version, char *release, int type)
|
1995-12-21 06:49:40 +08:00
|
|
|
{
|
|
|
|
char buf[1024];
|
|
|
|
char **files, **fp;
|
|
|
|
struct file_entry *fes, *fest;
|
1996-01-12 10:48:35 +08:00
|
|
|
struct file_entry **file_entry_array;
|
1996-02-19 10:24:47 +08:00
|
|
|
int isdoc, isconf, isdir, verify_flags;
|
1995-12-21 06:49:40 +08:00
|
|
|
char *filename, *s;
|
|
|
|
char *str;
|
|
|
|
int count = 0;
|
1996-02-19 10:24:47 +08:00
|
|
|
int c, x;
|
1996-01-18 01:47:28 +08:00
|
|
|
glob_t glob_result;
|
1996-01-29 11:33:06 +08:00
|
|
|
int special_doc;
|
|
|
|
int passed_special_doc = 0;
|
1995-12-21 06:49:40 +08:00
|
|
|
|
|
|
|
fes = NULL;
|
1996-01-10 07:41:35 +08:00
|
|
|
*size = 0;
|
1996-01-12 15:31:41 +08:00
|
|
|
|
|
|
|
resetDocdir();
|
1996-01-10 07:41:35 +08:00
|
|
|
|
1995-12-21 06:49:40 +08:00
|
|
|
str = getStringBuf(sb);
|
|
|
|
files = splitString(str, strlen(str), '\n');
|
|
|
|
fp = files;
|
|
|
|
|
|
|
|
while (*fp) {
|
|
|
|
strcpy(buf, *fp); /* temp copy */
|
|
|
|
isdoc = 0;
|
1996-01-29 11:33:06 +08:00
|
|
|
special_doc = 0;
|
1995-12-21 06:49:40 +08:00
|
|
|
isconf = 0;
|
|
|
|
isdir = 0;
|
1996-02-19 10:24:47 +08:00
|
|
|
verify_flags = VERIFY_ALL;
|
1995-12-21 06:49:40 +08:00
|
|
|
filename = NULL;
|
1996-02-19 10:24:47 +08:00
|
|
|
|
|
|
|
/* First preparse buf for %verify() */
|
|
|
|
if (!parseForVerify(buf, &verify_flags)) {
|
|
|
|
return(RPMERR_BADSPEC);
|
|
|
|
}
|
|
|
|
|
1995-12-21 06:49:40 +08:00
|
|
|
s = strtok(buf, " \t\n");
|
|
|
|
while (s) {
|
1996-02-21 23:28:47 +08:00
|
|
|
if (!strcmp(s, "%docdir")) {
|
|
|
|
s = strtok(NULL, " \t\n");
|
|
|
|
addDocdir(s);
|
|
|
|
break;
|
|
|
|
} else if (!strcmp(s, "%doc")) {
|
1995-12-21 06:49:40 +08:00
|
|
|
isdoc = 1;
|
|
|
|
} else if (!strcmp(s, "%config")) {
|
|
|
|
isconf = 1;
|
|
|
|
} else if (!strcmp(s, "%dir")) {
|
|
|
|
isdir = 1;
|
|
|
|
} else {
|
1996-01-29 11:33:06 +08:00
|
|
|
if (isdoc && (*s != '/')) {
|
|
|
|
/* This is a special %doc macro */
|
|
|
|
special_doc = 1;
|
|
|
|
} else {
|
|
|
|
filename = s;
|
|
|
|
}
|
1995-12-21 06:49:40 +08:00
|
|
|
}
|
|
|
|
s = strtok(NULL, " \t\n");
|
|
|
|
}
|
1996-01-29 11:33:06 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
1995-12-21 06:49:40 +08:00
|
|
|
if (! filename) {
|
|
|
|
fp++;
|
|
|
|
continue;
|
|
|
|
}
|
1995-12-28 00:52:14 +08:00
|
|
|
|
1996-01-08 15:07:35 +08:00
|
|
|
if (type == RPMLEAD_BINARY) {
|
|
|
|
/* check that file starts with leading "/" */
|
|
|
|
if (*filename != '/') {
|
|
|
|
error(RPMERR_BADSPEC,
|
|
|
|
"File needs leading \"/\": %s", filename);
|
|
|
|
return(RPMERR_BADSPEC);
|
|
|
|
}
|
1995-12-28 00:52:14 +08:00
|
|
|
|
1996-01-18 01:47:28 +08:00
|
|
|
if (glob_pattern_p(filename)) {
|
|
|
|
if (glob(filename, 0, glob_error, &glob_result)) {
|
|
|
|
error(RPMERR_BADSPEC,
|
|
|
|
"No matches: %s", filename);
|
|
|
|
return(RPMERR_BADSPEC);
|
|
|
|
}
|
|
|
|
if (glob_result.gl_pathc < 1) {
|
|
|
|
error(RPMERR_BADSPEC,
|
|
|
|
"No matches: %s", filename);
|
|
|
|
return(RPMERR_BADSPEC);
|
|
|
|
}
|
|
|
|
x = 0;
|
|
|
|
c = 0;
|
|
|
|
while (x < glob_result.gl_pathc) {
|
|
|
|
c += add_file(&fes, glob_result.gl_pathv[x],
|
1996-02-19 10:24:47 +08:00
|
|
|
isdoc, isconf, isdir, verify_flags);
|
1996-01-18 01:47:28 +08:00
|
|
|
x++;
|
|
|
|
}
|
|
|
|
globfree(&glob_result);
|
|
|
|
} else {
|
1996-02-19 10:24:47 +08:00
|
|
|
c = add_file(&fes, filename, isdoc, isconf,
|
|
|
|
isdir, verify_flags);
|
1996-01-18 01:47:28 +08:00
|
|
|
}
|
1996-01-08 15:07:35 +08:00
|
|
|
} else {
|
|
|
|
/* Source package are the simple case */
|
|
|
|
fest = malloc(sizeof(struct file_entry));
|
|
|
|
fest->isdoc = 0;
|
|
|
|
fest->isconf = 0;
|
1996-02-19 10:24:47 +08:00
|
|
|
fest->verify_flags = 0; /* XXX - something else? */
|
1996-01-08 15:07:35 +08:00
|
|
|
stat(filename, &fest->statbuf);
|
1996-01-10 00:28:15 +08:00
|
|
|
fest->uname = getUname(fest->statbuf.st_uid);
|
|
|
|
fest->gname = getGname(fest->statbuf.st_gid);
|
1996-01-08 15:07:35 +08:00
|
|
|
strcpy(fest->file, filename);
|
|
|
|
fest->next = fes;
|
|
|
|
fes = fest;
|
|
|
|
c = 1;
|
|
|
|
}
|
|
|
|
|
1995-12-28 00:52:14 +08:00
|
|
|
if (! c) {
|
|
|
|
error(RPMERR_BADSPEC, "File not found: %s", filename);
|
|
|
|
return(RPMERR_BADSPEC);
|
|
|
|
}
|
|
|
|
count += c;
|
1995-12-21 06:49:40 +08:00
|
|
|
|
|
|
|
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;
|
1996-01-10 00:28:15 +08:00
|
|
|
char ** fileUnameList;
|
|
|
|
char ** fileGnameList;
|
1995-12-21 06:49:40 +08:00
|
|
|
int_32 * fileMtimesList;
|
|
|
|
int_32 * fileFlagsList;
|
|
|
|
int_16 * fileModesList;
|
|
|
|
int_16 * fileRDevsList;
|
1996-02-19 10:24:47 +08:00
|
|
|
int_32 * fileVerifyFlagsList;
|
1995-12-21 06:49:40 +08:00
|
|
|
|
|
|
|
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);
|
1996-01-10 00:28:15 +08:00
|
|
|
fileUnameList = malloc(sizeof(char *) * count);
|
|
|
|
fileGnameList = malloc(sizeof(char *) * count);
|
1995-12-21 06:49:40 +08:00
|
|
|
fileMtimesList = malloc(sizeof(int_32) * count);
|
|
|
|
fileFlagsList = malloc(sizeof(int_32) * count);
|
|
|
|
fileModesList = malloc(sizeof(int_16) * count);
|
|
|
|
fileRDevsList = malloc(sizeof(int_16) * count);
|
1996-02-19 10:24:47 +08:00
|
|
|
fileVerifyFlagsList = malloc(sizeof(int_32) * count);
|
1995-12-21 06:49:40 +08:00
|
|
|
|
1996-01-12 10:48:35 +08:00
|
|
|
/* Build a reverse sorted file array. */
|
|
|
|
/* This makes uninstalls a lot easier. */
|
|
|
|
file_entry_array = malloc(sizeof(struct file_entry *) * count);
|
|
|
|
c = 0;
|
1995-12-21 06:49:40 +08:00
|
|
|
fest = fes;
|
1996-01-12 10:48:35 +08:00
|
|
|
while (fest) {
|
|
|
|
file_entry_array[c++] = fest;
|
|
|
|
fest = fest->next;
|
|
|
|
}
|
1996-02-19 10:24:47 +08:00
|
|
|
qsort(file_entry_array, count, sizeof(struct file_entry *),
|
|
|
|
compare_fe);
|
1996-01-12 10:48:35 +08:00
|
|
|
|
|
|
|
c = 0;
|
|
|
|
while (c < count) {
|
|
|
|
fest = file_entry_array[c];
|
1996-01-08 15:07:35 +08:00
|
|
|
if (type == RPMLEAD_BINARY) {
|
1996-01-12 10:48:35 +08:00
|
|
|
fileList[c] = fest->file;
|
1996-01-08 15:07:35 +08:00
|
|
|
} else {
|
1996-01-12 10:48:35 +08:00
|
|
|
fileList[c] = strrchr(fest->file, '/') + 1;
|
1996-01-08 15:07:35 +08:00
|
|
|
}
|
1996-01-12 10:48:35 +08:00
|
|
|
fileUnameList[c] = fest->uname;
|
|
|
|
fileGnameList[c] = fest->gname;
|
|
|
|
*size += fest->statbuf.st_size;
|
|
|
|
if (S_ISREG(fest->statbuf.st_mode)) {
|
1996-02-21 07:31:59 +08:00
|
|
|
if (getVar(RPMVAR_ROOT)) {
|
|
|
|
sprintf(buf, "%s%s", getVar(RPMVAR_ROOT), fest->file);
|
|
|
|
} else {
|
|
|
|
strcpy(buf, fest->file);
|
|
|
|
}
|
|
|
|
mdfile(buf, buf);
|
1995-12-28 00:52:14 +08:00
|
|
|
fileMD5List[c] = strdup(buf);
|
1996-01-12 10:48:35 +08:00
|
|
|
message(MESS_DEBUG, "md5(%s) = %s\n", fest->file, buf);
|
1995-12-28 00:52:14 +08:00
|
|
|
} else {
|
|
|
|
/* This is stupid */
|
|
|
|
fileMD5List[c] = strdup("");
|
|
|
|
}
|
1996-01-12 10:48:35 +08:00
|
|
|
fileSizeList[c] = fest->statbuf.st_size;
|
|
|
|
fileUIDList[c] = fest->statbuf.st_uid;
|
|
|
|
fileGIDList[c] = fest->statbuf.st_gid;
|
|
|
|
fileMtimesList[c] = fest->statbuf.st_mtime;
|
1995-12-21 06:49:40 +08:00
|
|
|
fileFlagsList[c] = 0;
|
1996-01-12 15:31:41 +08:00
|
|
|
if (isDoc(fest->file))
|
|
|
|
fileFlagsList[c] |= RPMFILE_DOC;
|
1996-01-12 10:48:35 +08:00
|
|
|
if (fest->isdoc)
|
1995-12-21 06:49:40 +08:00
|
|
|
fileFlagsList[c] |= RPMFILE_DOC;
|
1996-01-12 10:48:35 +08:00
|
|
|
if (fest->isconf)
|
1995-12-21 06:49:40 +08:00
|
|
|
fileFlagsList[c] |= RPMFILE_CONFIG;
|
|
|
|
|
1996-01-12 10:48:35 +08:00
|
|
|
fileModesList[c] = fest->statbuf.st_mode;
|
|
|
|
fileRDevsList[c] = fest->statbuf.st_rdev;
|
1996-02-19 10:24:47 +08:00
|
|
|
fileVerifyFlagsList[c] = fest->verify_flags;
|
1995-12-21 06:49:40 +08:00
|
|
|
|
1996-01-12 10:48:35 +08:00
|
|
|
if (S_ISLNK(fest->statbuf.st_mode)) {
|
1995-12-28 00:52:14 +08:00
|
|
|
if (getVar(RPMVAR_ROOT)) {
|
1996-01-12 10:48:35 +08:00
|
|
|
sprintf(buf, "%s%s", getVar(RPMVAR_ROOT), fest->file);
|
1995-12-28 00:52:14 +08:00
|
|
|
} else {
|
1996-01-12 10:48:35 +08:00
|
|
|
strcpy(buf, fest->file);
|
1995-12-28 00:52:14 +08:00
|
|
|
}
|
1996-02-21 07:31:59 +08:00
|
|
|
buf[readlink(buf, buf, 1024)] = '\0';
|
1995-12-21 06:49:40 +08:00
|
|
|
fileLinktoList[c] = strdup(buf);
|
|
|
|
} else {
|
|
|
|
/* This is stupid */
|
|
|
|
fileLinktoList[c] = strdup("");
|
|
|
|
}
|
1996-01-12 10:48:35 +08:00
|
|
|
c++;
|
1995-12-21 06:49:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Add the header entries */
|
|
|
|
c = count;
|
1995-12-21 07:32:38 +08:00
|
|
|
addEntry(header, RPMTAG_FILENAMES, STRING_ARRAY_TYPE, fileList, c);
|
1996-01-10 00:28:15 +08:00
|
|
|
addEntry(header, RPMTAG_FILELINKTOS, STRING_ARRAY_TYPE,
|
|
|
|
fileLinktoList, c);
|
1995-12-21 07:32:38 +08:00
|
|
|
addEntry(header, RPMTAG_FILEMD5S, STRING_ARRAY_TYPE, fileMD5List, c);
|
1995-12-21 06:49:40 +08:00
|
|
|
addEntry(header, RPMTAG_FILESIZES, INT32_TYPE, fileSizeList, c);
|
|
|
|
addEntry(header, RPMTAG_FILEUIDS, INT32_TYPE, fileUIDList, c);
|
|
|
|
addEntry(header, RPMTAG_FILEGIDS, INT32_TYPE, fileGIDList, c);
|
1996-01-10 00:28:15 +08:00
|
|
|
addEntry(header, RPMTAG_FILEUSERNAME, STRING_ARRAY_TYPE,
|
|
|
|
fileUnameList, c);
|
|
|
|
addEntry(header, RPMTAG_FILEGROUPNAME, STRING_ARRAY_TYPE,
|
|
|
|
fileGnameList, c);
|
1995-12-21 06:49:40 +08:00
|
|
|
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);
|
1996-02-19 10:24:47 +08:00
|
|
|
addEntry(header, RPMTAG_FILEVERIFYFLAGS, INT32_TYPE,
|
|
|
|
fileVerifyFlagsList, c);
|
1995-12-21 06:49:40 +08:00
|
|
|
|
|
|
|
/* Free the allocated strings */
|
|
|
|
c = count;
|
|
|
|
while (c--) {
|
|
|
|
free(fileMD5List[c]);
|
|
|
|
free(fileLinktoList[c]);
|
|
|
|
}
|
1996-01-12 10:48:35 +08:00
|
|
|
|
1996-02-19 10:24:47 +08:00
|
|
|
/* 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);
|
|
|
|
|
1996-01-12 10:48:35 +08:00
|
|
|
/* Free the file entry array */
|
|
|
|
free(file_entry_array);
|
1995-12-21 06:49:40 +08:00
|
|
|
|
|
|
|
/* Free the file entry stack */
|
1996-01-12 10:48:35 +08:00
|
|
|
fest = fes;
|
1995-12-21 06:49:40 +08:00
|
|
|
while (fest) {
|
|
|
|
fes = fest->next;
|
|
|
|
free(fest);
|
|
|
|
fest = fes;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
freeSplitString(files);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1996-01-08 15:07:35 +08:00
|
|
|
static time_t buildtime;
|
|
|
|
void markBuildTime(void)
|
|
|
|
{
|
|
|
|
buildtime = time(NULL);
|
|
|
|
}
|
|
|
|
|
1996-01-12 15:31:41 +08:00
|
|
|
static char *buildHost(void)
|
|
|
|
{
|
|
|
|
static char hostname[1024];
|
|
|
|
static int gotit = 0;
|
|
|
|
struct hostent *hbn;
|
|
|
|
|
|
|
|
if (! gotit) {
|
|
|
|
gethostname(hostname, sizeof(hostname));
|
|
|
|
hbn = gethostbyname(hostname);
|
|
|
|
strcpy(hostname, hbn->h_name);
|
|
|
|
gotit = 1;
|
|
|
|
}
|
|
|
|
return(hostname);
|
|
|
|
}
|
|
|
|
|
1996-02-21 00:00:04 +08:00
|
|
|
int packageBinaries(Spec s, char *passPhrase)
|
1995-12-21 06:49:40 +08:00
|
|
|
{
|
|
|
|
char name[1024];
|
1996-02-22 01:19:17 +08:00
|
|
|
char *nametmp;
|
1995-12-21 06:49:40 +08:00
|
|
|
char filename[1024];
|
1996-01-18 02:17:50 +08:00
|
|
|
char sourcerpm[1024];
|
1996-01-08 15:07:35 +08:00
|
|
|
char *icon;
|
|
|
|
int iconFD;
|
|
|
|
struct stat statbuf;
|
1995-12-21 06:49:40 +08:00
|
|
|
struct PackageRec *pr;
|
|
|
|
Header outHeader;
|
|
|
|
HeaderIterator headerIter;
|
|
|
|
int_32 tag, type, c;
|
|
|
|
void *ptr;
|
|
|
|
char *version;
|
|
|
|
char *release;
|
1996-02-19 10:24:47 +08:00
|
|
|
char *vendor;
|
|
|
|
char *dist;
|
1996-02-21 01:55:15 +08:00
|
|
|
char *packageVersion, *packageRelease;
|
1996-01-10 07:41:35 +08:00
|
|
|
int size;
|
1996-01-12 10:48:35 +08:00
|
|
|
int_8 os, arch;
|
1996-02-19 10:24:47 +08:00
|
|
|
|
1995-12-21 06:49:40 +08:00
|
|
|
if (!getEntry(s->packages->header, RPMTAG_VERSION, NULL,
|
|
|
|
(void *) &version, NULL)) {
|
|
|
|
error(RPMERR_BADSPEC, "No version field");
|
|
|
|
return RPMERR_BADSPEC;
|
|
|
|
}
|
|
|
|
if (!getEntry(s->packages->header, RPMTAG_RELEASE, NULL,
|
|
|
|
(void *) &release, NULL)) {
|
|
|
|
error(RPMERR_BADSPEC, "No release field");
|
|
|
|
return RPMERR_BADSPEC;
|
|
|
|
}
|
|
|
|
|
1996-01-13 07:46:47 +08:00
|
|
|
sprintf(sourcerpm, "%s-%s-%s.src.rpm", s->name, version, release);
|
|
|
|
|
1996-02-19 10:24:47 +08:00
|
|
|
vendor = NULL;
|
|
|
|
if (!isEntry(s->packages->header, RPMTAG_VENDOR)) {
|
|
|
|
vendor = getVar(RPMVAR_VENDOR);
|
|
|
|
}
|
|
|
|
dist = NULL;
|
|
|
|
if (!isEntry(s->packages->header, RPMTAG_DISTRIBUTION)) {
|
|
|
|
dist = getVar(RPMVAR_DISTRIBUTION);
|
|
|
|
}
|
|
|
|
|
1995-12-21 06:49:40 +08:00
|
|
|
/* Look through for each package */
|
|
|
|
pr = s->packages;
|
|
|
|
while (pr) {
|
1996-02-19 10:24:47 +08:00
|
|
|
/* A file count of -1 means no package */
|
1995-12-21 06:49:40 +08:00
|
|
|
if (pr->files == -1) {
|
|
|
|
pr = pr->next;
|
|
|
|
continue;
|
|
|
|
}
|
1996-02-21 01:55:15 +08:00
|
|
|
|
|
|
|
/* Handle subpackage version/release overrides */
|
|
|
|
if (!getEntry(pr->header, RPMTAG_VERSION, NULL,
|
|
|
|
(void *) &packageVersion, NULL)) {
|
|
|
|
packageVersion = version;
|
|
|
|
}
|
|
|
|
if (!getEntry(pr->header, RPMTAG_RELEASE, NULL,
|
|
|
|
(void *) &packageRelease, NULL)) {
|
|
|
|
packageRelease = release;
|
|
|
|
}
|
1995-12-21 06:49:40 +08:00
|
|
|
|
1996-02-19 10:24:47 +08:00
|
|
|
/* Figure out the name of this package */
|
1996-02-22 01:19:17 +08:00
|
|
|
if (!getEntry(pr->header, RPMTAG_NAME, NULL, (void *)&nametmp, NULL)) {
|
|
|
|
error(RPMERR_INTERNAL, "Package has no name!");
|
|
|
|
return RPMERR_INTERNAL;
|
1995-12-21 06:49:40 +08:00
|
|
|
}
|
1996-02-22 01:19:17 +08:00
|
|
|
sprintf(name, "%s-%s-%s", nametmp, packageVersion, packageRelease);
|
1996-02-19 10:24:47 +08:00
|
|
|
|
1996-02-21 07:31:59 +08:00
|
|
|
message(MESS_VERBOSE, "Binary Packaging: %s\n", name);
|
|
|
|
|
1996-02-19 10:24:47 +08:00
|
|
|
/**** Generate the Header ****/
|
1995-12-21 06:49:40 +08:00
|
|
|
|
|
|
|
/* Here's the plan: copy the package's header, */
|
|
|
|
/* then add entries from the primary header */
|
|
|
|
/* that don't already exist. */
|
|
|
|
outHeader = copyHeader(pr->header);
|
|
|
|
headerIter = initIterator(s->packages->header);
|
|
|
|
while (nextIterator(headerIter, &tag, &type, &ptr, &c)) {
|
|
|
|
/* Some tags we don't copy */
|
|
|
|
switch (tag) {
|
|
|
|
case RPMTAG_PREIN:
|
|
|
|
case RPMTAG_POSTIN:
|
|
|
|
case RPMTAG_PREUN:
|
|
|
|
case RPMTAG_POSTUN:
|
|
|
|
continue;
|
|
|
|
break; /* Shouldn't need this */
|
|
|
|
default:
|
|
|
|
if (! isEntry(outHeader, tag)) {
|
|
|
|
addEntry(outHeader, tag, type, ptr, c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
freeIterator(headerIter);
|
|
|
|
|
|
|
|
/* Add some final entries to the header */
|
1996-01-12 10:48:35 +08:00
|
|
|
os = getArchNum();
|
|
|
|
arch = getArchNum();
|
|
|
|
addEntry(outHeader, RPMTAG_OS, INT8_TYPE, &os, 1);
|
|
|
|
addEntry(outHeader, RPMTAG_ARCH, INT8_TYPE, &arch, 1);
|
1995-12-21 06:49:40 +08:00
|
|
|
addEntry(outHeader, RPMTAG_BUILDTIME, INT32_TYPE, &buildtime, 1);
|
1996-01-12 15:31:41 +08:00
|
|
|
addEntry(outHeader, RPMTAG_BUILDHOST, STRING_TYPE, buildHost(), 1);
|
1996-01-13 07:46:47 +08:00
|
|
|
addEntry(outHeader, RPMTAG_SOURCERPM, STRING_TYPE, sourcerpm, 1);
|
1996-01-08 15:07:35 +08:00
|
|
|
if (pr->icon) {
|
|
|
|
sprintf(filename, "%s/%s", getVar(RPMVAR_SOURCEDIR), pr->icon);
|
|
|
|
stat(filename, &statbuf);
|
|
|
|
icon = malloc(statbuf.st_size);
|
|
|
|
iconFD = open(filename, O_RDONLY, 0644);
|
|
|
|
read(iconFD, icon, statbuf.st_size);
|
|
|
|
close(iconFD);
|
1996-01-10 07:41:35 +08:00
|
|
|
if (! strncmp(icon, "GIF", 3)) {
|
|
|
|
addEntry(outHeader, RPMTAG_GIF, BIN_TYPE,
|
|
|
|
icon, statbuf.st_size);
|
|
|
|
} else if (! strncmp(icon, "/* XPM", 6)) {
|
|
|
|
addEntry(outHeader, RPMTAG_XPM, BIN_TYPE,
|
|
|
|
icon, statbuf.st_size);
|
|
|
|
} else {
|
1996-02-15 00:56:02 +08:00
|
|
|
error(RPMERR_BADSPEC, "Unknown icon type");
|
|
|
|
return 1;
|
1996-01-10 07:41:35 +08:00
|
|
|
}
|
1996-01-08 15:07:35 +08:00
|
|
|
free(icon);
|
|
|
|
}
|
1996-02-19 10:24:47 +08:00
|
|
|
if (vendor) {
|
|
|
|
addEntry(outHeader, RPMTAG_VENDOR, STRING_TYPE, vendor, 1);
|
|
|
|
}
|
|
|
|
if (dist) {
|
|
|
|
addEntry(outHeader, RPMTAG_DISTRIBUTION, STRING_TYPE, dist, 1);
|
|
|
|
}
|
1996-01-08 15:07:35 +08:00
|
|
|
|
1996-02-19 10:24:47 +08:00
|
|
|
/**** Process the file list ****/
|
1995-12-21 06:49:40 +08:00
|
|
|
|
1996-02-23 11:47:43 +08:00
|
|
|
if (process_filelist(outHeader, pr->filelist, &size, nametmp,
|
1996-02-21 01:55:15 +08:00
|
|
|
packageVersion, packageRelease, RPMLEAD_BINARY)) {
|
1995-12-21 06:49:40 +08:00
|
|
|
return 1;
|
|
|
|
}
|
1996-02-19 10:24:47 +08:00
|
|
|
/* And add the final Header entry */
|
|
|
|
addEntry(outHeader, RPMTAG_SIZE, INT32_TYPE, &size, 1);
|
|
|
|
|
|
|
|
/**** Make the RPM ****/
|
|
|
|
|
1996-02-22 09:35:34 +08:00
|
|
|
if (generateRPM(name, RPMLEAD_BINARY, outHeader, NULL, passPhrase)) {
|
|
|
|
/* Build failed */
|
|
|
|
return 1;
|
|
|
|
}
|
1995-12-21 06:49:40 +08:00
|
|
|
|
|
|
|
freeHeader(outHeader);
|
|
|
|
pr = pr->next;
|
|
|
|
}
|
1996-02-19 10:24:47 +08:00
|
|
|
|
1995-12-21 06:49:40 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1996-01-08 15:07:35 +08:00
|
|
|
/**************** SOURCE PACKAGING ************************/
|
|
|
|
|
1996-02-21 00:00:04 +08:00
|
|
|
int packageSource(Spec s, char *passPhrase)
|
1995-12-21 06:49:40 +08:00
|
|
|
{
|
1996-01-08 15:07:35 +08:00
|
|
|
struct sources *source;
|
|
|
|
struct PackageRec *package;
|
|
|
|
char *tempdir;
|
1996-02-19 10:24:47 +08:00
|
|
|
char src[1024], dest[1024], fullname[1024];
|
1996-01-08 15:07:35 +08:00
|
|
|
char *version;
|
|
|
|
char *release;
|
1996-02-19 10:24:47 +08:00
|
|
|
char *vendor;
|
|
|
|
char *dist;
|
1996-01-08 15:07:35 +08:00
|
|
|
Header outHeader;
|
|
|
|
StringBuf filelist;
|
1996-01-10 07:41:35 +08:00
|
|
|
int size;
|
1996-01-12 10:48:35 +08:00
|
|
|
int_8 os, arch;
|
1996-01-18 02:17:50 +08:00
|
|
|
char **sources;
|
|
|
|
char **patches;
|
|
|
|
int scount, pcount;
|
1996-01-08 15:07:35 +08:00
|
|
|
|
1996-02-19 10:24:47 +08:00
|
|
|
/**** Create links for all the sources ****/
|
|
|
|
|
1996-03-29 09:26:20 +08:00
|
|
|
tempdir = tempnam("/var/tmp", "rpmbuild");
|
1996-01-08 15:07:35 +08:00
|
|
|
mkdir(tempdir, 0700);
|
|
|
|
|
|
|
|
filelist = newStringBuf();
|
1996-01-18 02:17:50 +08:00
|
|
|
|
1996-02-17 01:37:53 +08:00
|
|
|
sources = malloc((s->numSources+1) * sizeof(char *));
|
|
|
|
patches = malloc((s->numPatches+1) * sizeof(char *));
|
1996-01-08 15:07:35 +08:00
|
|
|
|
|
|
|
/* Link in the spec file and all the sources */
|
|
|
|
sprintf(dest, "%s%s", tempdir, strrchr(s->specfile, '/'));
|
|
|
|
symlink(s->specfile, dest);
|
|
|
|
appendLineStringBuf(filelist, dest);
|
|
|
|
source = s->sources;
|
1996-01-18 02:17:50 +08:00
|
|
|
scount = 0;
|
|
|
|
pcount = 0;
|
1996-01-08 15:07:35 +08:00
|
|
|
while (source) {
|
|
|
|
sprintf(src, "%s/%s", getVar(RPMVAR_SOURCEDIR), source->source);
|
|
|
|
sprintf(dest, "%s/%s", tempdir, source->source);
|
|
|
|
symlink(src, dest);
|
|
|
|
appendLineStringBuf(filelist, dest);
|
1996-01-18 02:17:50 +08:00
|
|
|
if (source->ispatch) {
|
|
|
|
patches[pcount++] = source->fullSource;
|
|
|
|
} else {
|
|
|
|
sources[scount++] = source->fullSource;
|
|
|
|
}
|
1996-01-08 15:07:35 +08:00
|
|
|
source = source->next;
|
|
|
|
}
|
|
|
|
/* ... and icons */
|
|
|
|
package = s->packages;
|
|
|
|
while (package) {
|
|
|
|
if (package->icon) {
|
|
|
|
sprintf(src, "%s/%s", getVar(RPMVAR_SOURCEDIR), package->icon);
|
1996-01-29 11:33:06 +08:00
|
|
|
sprintf(dest, "%s/%s", tempdir, package->icon);
|
1996-01-08 15:07:35 +08:00
|
|
|
appendLineStringBuf(filelist, dest);
|
|
|
|
symlink(src, dest);
|
|
|
|
}
|
|
|
|
package = package->next;
|
|
|
|
}
|
|
|
|
|
1996-02-19 10:24:47 +08:00
|
|
|
/**** Generate the Header ****/
|
1996-01-08 15:07:35 +08:00
|
|
|
|
|
|
|
if (!getEntry(s->packages->header, RPMTAG_VERSION, NULL,
|
|
|
|
(void *) &version, NULL)) {
|
|
|
|
error(RPMERR_BADSPEC, "No version field");
|
|
|
|
return RPMERR_BADSPEC;
|
|
|
|
}
|
|
|
|
if (!getEntry(s->packages->header, RPMTAG_RELEASE, NULL,
|
|
|
|
(void *) &release, NULL)) {
|
|
|
|
error(RPMERR_BADSPEC, "No release field");
|
|
|
|
return RPMERR_BADSPEC;
|
|
|
|
}
|
|
|
|
|
|
|
|
outHeader = copyHeader(s->packages->header);
|
1996-01-12 10:48:35 +08:00
|
|
|
os = getArchNum();
|
|
|
|
arch = getArchNum();
|
|
|
|
addEntry(outHeader, RPMTAG_OS, INT8_TYPE, &os, 1);
|
|
|
|
addEntry(outHeader, RPMTAG_ARCH, INT8_TYPE, &arch, 1);
|
1996-01-08 15:07:35 +08:00
|
|
|
addEntry(outHeader, RPMTAG_BUILDTIME, INT32_TYPE, &buildtime, 1);
|
1996-01-12 15:31:41 +08:00
|
|
|
addEntry(outHeader, RPMTAG_BUILDHOST, STRING_TYPE, buildHost(), 1);
|
1996-02-15 00:56:02 +08:00
|
|
|
if (scount)
|
|
|
|
addEntry(outHeader, RPMTAG_SOURCE, STRING_ARRAY_TYPE, sources, scount);
|
|
|
|
if (pcount)
|
|
|
|
addEntry(outHeader, RPMTAG_PATCH, STRING_ARRAY_TYPE, patches, pcount);
|
1996-02-19 10:24:47 +08:00
|
|
|
if (!isEntry(s->packages->header, RPMTAG_VENDOR)) {
|
|
|
|
if ((vendor = getVar(RPMVAR_VENDOR))) {
|
|
|
|
addEntry(outHeader, RPMTAG_VENDOR, STRING_TYPE, vendor, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!isEntry(s->packages->header, RPMTAG_DISTRIBUTION)) {
|
|
|
|
if ((dist = getVar(RPMVAR_DISTRIBUTION))) {
|
|
|
|
addEntry(outHeader, RPMTAG_DISTRIBUTION, STRING_TYPE, dist, 1);
|
|
|
|
}
|
|
|
|
}
|
1996-01-08 15:07:35 +08:00
|
|
|
|
1996-02-19 10:24:47 +08:00
|
|
|
/* Process the file list */
|
1996-01-29 11:33:06 +08:00
|
|
|
if (process_filelist(outHeader, filelist, &size,
|
|
|
|
s->name, version, release, RPMLEAD_SOURCE)) {
|
1996-01-08 15:07:35 +08:00
|
|
|
return 1;
|
|
|
|
}
|
1996-02-19 10:24:47 +08:00
|
|
|
/* And add the final Header entry */
|
1996-01-10 07:41:35 +08:00
|
|
|
addEntry(outHeader, RPMTAG_SIZE, INT32_TYPE, &size, 1);
|
|
|
|
|
1996-02-19 10:24:47 +08:00
|
|
|
/**** Make the RPM ****/
|
1996-01-08 15:07:35 +08:00
|
|
|
|
1996-02-19 10:24:47 +08:00
|
|
|
sprintf(fullname, "%s-%s-%s", s->name, version, release);
|
1996-02-21 07:31:59 +08:00
|
|
|
message(MESS_VERBOSE, "Source Packaging: %s\n", fullname);
|
|
|
|
|
1996-02-22 09:35:34 +08:00
|
|
|
if (generateRPM(fullname, RPMLEAD_SOURCE, outHeader,
|
|
|
|
tempdir, passPhrase)) {
|
|
|
|
return 1;
|
|
|
|
}
|
1996-01-08 15:07:35 +08:00
|
|
|
|
1996-02-19 10:24:47 +08:00
|
|
|
/**** Now clean up ****/
|
1996-01-08 15:07:35 +08:00
|
|
|
|
|
|
|
freeStringBuf(filelist);
|
|
|
|
|
|
|
|
source = s->sources;
|
|
|
|
while (source) {
|
|
|
|
sprintf(dest, "%s/%s", tempdir, source->source);
|
|
|
|
unlink(dest);
|
|
|
|
source = source->next;
|
|
|
|
}
|
|
|
|
package = s->packages;
|
|
|
|
while (package) {
|
|
|
|
if (package->icon) {
|
1996-01-29 11:33:06 +08:00
|
|
|
sprintf(dest, "%s/%s", tempdir, package->icon);
|
1996-01-08 15:07:35 +08:00
|
|
|
unlink(dest);
|
|
|
|
}
|
|
|
|
package = package->next;
|
|
|
|
}
|
1996-01-29 11:33:06 +08:00
|
|
|
sprintf(dest, "%s%s", tempdir, strrchr(s->specfile, '/'));
|
|
|
|
unlink(dest);
|
1996-01-08 15:07:35 +08:00
|
|
|
rmdir(tempdir);
|
|
|
|
|
1995-12-21 06:49:40 +08:00
|
|
|
return 0;
|
|
|
|
}
|
1996-02-15 04:07:09 +08:00
|
|
|
|
|
|
|
/****************** 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;
|
|
|
|
}
|
|
|
|
|
1996-02-15 06:31:37 +08:00
|
|
|
return 0;
|
1996-02-15 04:07:09 +08:00
|
|
|
}
|