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);
+ char *Pmode, char *Uname, char *Gname, char *prefix);
static int compare_fe(const void *ap, const void *bp);
static int add_file_aux(const char *file, struct stat *sb, int flag);
static int glob_error(const char *foo, int bar);
int process_filelist(Header header, struct PackageRec *pr,
StringBuf sb, int *size, char *name,
- char *version, char *release, int type)
+ char *version, char *release, int type, char *prefix)
{
char buf[1024];
char **files, **fp;
int offset = strlen(getVar(RPMVAR_ROOT) ? : "");
c += add_file(&fes, &(glob_result.gl_pathv[x][offset]),
isdoc, isconf, isdir, verify_flags,
- currPmode, currUname, currGname);
+ currPmode, currUname, currGname, prefix);
x++;
}
globfree(&glob_result);
} else {
c = add_file(&fes, filename, isdoc, isconf, isdir,
- verify_flags, currPmode, currUname, currGname);
+ verify_flags, currPmode, currUname,
+ currGname, prefix);
}
} else {
/* Source package are the simple case */
static char *GUname;
static char *GGname;
static struct file_entry **Gfestack;
+static char *Gprefix;
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)
+ char *Pmode, char *Uname, char *Gname, char *prefix)
{
struct file_entry *p;
char *copyTo, copied;
+ const char *prefixTest, *prefixPtr;
const char *copyFrom;
char fullname[1024];
int mode;
GPmode = Pmode;
GUname = Uname;
GGname = Gname;
+ Gprefix = prefix;
p = malloc(sizeof(struct file_entry));
} else {
strcpy(fullname, name);
}
+
+ /* If we are using a prefix, validate the file */
+ if (prefix) {
+ prefixTest = name;
+ prefixPtr = prefix;
+ while (*prefixTest == '/') {
+ prefixTest++; /* Skip leading "/" */
+ }
+ while (*prefixPtr && (*prefixTest == *prefixPtr)) {
+ prefixPtr++;
+ prefixTest++;
+ }
+ if (*prefixPtr) {
+ error(RPMERR_BADSPEC, "File doesn't match prefix: %s", name);
+ return 0;
+ }
+ }
+
+ /* OK, finally stat() the file */
if (lstat(fullname, &p->statbuf)) {
return 0;
}
/* 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);
+ GPmode, GUname, GGname, Gprefix);
return 0; /* for ftw() */
}
int process_filelist(Header header, struct PackageRec *pr, StringBuf sb,
int *size, char *name, char *version,
- char *release, int type);
+ char *release, int type, char *prefix);
#endif _FILES_H_
#include "reqprov.h"
static int writeMagic(int fd, char *name, unsigned short type);
-static int cpio_gzip(int fd, char *tempdir, char *writePtr, int *archiveSize);
+static int cpio_gzip(int fd, char *tempdir, char *writePtr,
+ int *archiveSize, char *prefix);
static int generateRPM(char *name, /* name-version-release */
char *filename, /* output filename */
int type, /* source or binary */
Header header, /* the header */
char *stempdir, /* directory containing sources */
char *fileList, /* list of files for cpio */
- char *passPhrase);
+ char *passPhrase, /* PGP passphrase */
+ char *prefix);
static int generateRPM(char *name, /* name-version-release */
Header header, /* the header */
char *stempdir, /* directory containing sources */
char *fileList, /* list of files for cpio */
- char *passPhrase)
+ char *passPhrase,
+ char *prefix)
{
int_32 sigtype;
char *sigtarget, *archiveTemp;
fprintf(stderr, "Could not open %s\n", archiveTemp);
return 1;
}
- if (cpio_gzip(fd, stempdir, fileList, &archiveSize)) {
+ if (cpio_gzip(fd, stempdir, fileList, &archiveSize, prefix)) {
close(fd);
unlink(archiveTemp);
return 1;
return 0;
}
-static int cpio_gzip(int fd, char *tempdir, char *writePtr, int *archiveSize)
+static int cpio_gzip(int fd, char *tempdir, char *writePtr,
+ int *archiveSize, char *prefix)
{
int cpioPID, gzipPID;
int cpioDead, gzipDead;
/* This is important! */
chdir("/");
}
+ if (prefix) {
+ if (chdir(prefix)) {
+ error(RPMERR_EXEC, "Couldn't chdir to %s", prefix);
+ exit(RPMERR_EXEC);
+ }
+ }
execlp("cpio", "cpio",
(isVerbose()) ? "-ov" : "-o",
char *vendor;
char *dist;
char *packageVersion, *packageRelease;
+ char *prefix;
+ int prefixLen;
int size;
StringBuf cpioFileList;
char **farray, *file;
dist = getVar(RPMVAR_DISTRIBUTION);
}
+ if (s->prefix) {
+ prefix = s->prefix;
+ while (*prefix && (*prefix == '/')) {
+ prefix++;
+ }
+ if (! *prefix) {
+ prefix = NULL;
+ }
+ prefixLen = strlen(prefix);
+ }
+
/* Look through for each package */
pr = s->packages;
while (pr) {
/**** Process the file list ****/
if (process_filelist(outHeader, pr, pr->filelist, &size, nametmp,
- packageVersion, packageRelease, RPMLEAD_BINARY)) {
+ packageVersion, packageRelease, RPMLEAD_BINARY,
+ prefix)) {
return 1;
}
while (*file == '/') {
file++; /* Skip leading "/" */
}
+ if (prefix) {
+ if (strncmp(prefix, file, prefixLen)) {
+ error(RPMERR_BADSPEC, "File doesn't match prefix: %s",
+ file);
+ return 1;
+ }
+ file += prefixLen + 1; /* 1 for "/" */
+ }
appendLineStringBuf(cpioFileList, file);
}
name, getArchName());
if (generateRPM(name, filename, RPMLEAD_BINARY, outHeader, NULL,
- getStringBuf(cpioFileList), passPhrase)) {
+ getStringBuf(cpioFileList), passPhrase, prefix)) {
/* Build failed */
return 1;
}
/* Process the file list */
if (process_filelist(outHeader, NULL, filelist, &size,
- s->name, version, release, RPMLEAD_SOURCE)) {
+ s->name, version, release, RPMLEAD_SOURCE,
+ NULL)) {
return 1;
}
message(MESS_VERBOSE, "Source Packaging: %s\n", fullname);
if (generateRPM(fullname, filename, RPMLEAD_SOURCE, outHeader,
- tempdir, getStringBuf(cpioFileList), passPhrase)) {
+ tempdir, getStringBuf(cpioFileList), passPhrase, NULL)) {
return 1;
}
FREE(s->specfile);
FREE(s->noSource);
FREE(s->noPatch);
+ FREE(s->prefix);
freeSources(s);
freeStringBuf(s->prep);
freeStringBuf(s->build);
{RPMTAG_PROVIDES, 0, "provides"},
{RPMTAG_REQUIREFLAGS, 0, "requires"},
{RPMTAG_CONFLICTFLAGS, 0, "conflicts"},
+ {RPMTAG_DEFAULTPREFIX, 0, "prefix"},
{0, 0, 0}
};
spec->noPatch = NULL;
spec->numNoSource = 0;
spec->numNoPatch = 0;
+ spec->prefix = NULL;
sb = newStringBuf();
reset_spec(); /* Reset the parser */
case RPMTAG_URL:
addEntry(cur_package->header, tag, STRING_TYPE, s, 1);
break;
+ case RPMTAG_DEFAULTPREFIX:
+ spec->prefix = strdup(s);
+ addEntry(cur_package->header, tag, STRING_TYPE, s, 1);
+ break;
case RPMTAG_SERIAL:
serial = atoi(s);
addEntry(cur_package->header, tag, INT32_TYPE, &serial, 1);
StringBuf doc;
StringBuf clean;
+ char *prefix;
+
struct PackageRec *packages;
/* The first package record is the "main" package and contains
* the bulk of the preamble information. Subsequent package