lib/macro.c: Canonicalize paths in rpmGetPath().

build.c: ditto.
build/build.c: ditto.
build/files.c: ditto.
build/parsePreamble.c: ditto.
build/parseSpec.c: ditto.
build/myftw.c: Use Opendir/Readdir/Closedir wrappers.
lib/cpio.c: Use Readlink/Stat/Lstat wrappers while building archive.
lib/rpmio.c: functional ftpLstat, ftpStat and ftpReadlink.

CVS patchset: 3432
CVS date: 1999/11/24 00:03:54
This commit is contained in:
jbj 1999-11-24 00:03:54 +00:00
parent abe7856bb0
commit 4221ce1aa1
18 changed files with 666 additions and 440 deletions

97
build.c
View File

@ -90,17 +90,22 @@ static int buildForTarget(const char *arg, struct rpmBuildArguments *ba,
int force, int nodeps)
{
int buildAmount = ba->buildAmount;
const char *buildRoot = ba->buildRootOverride;
const char *buildRootURL = NULL;
int test = ba->noBuild;
FILE *f;
const char * specfile;
struct stat statbuf;
const char * specFile;
const char * specURL;
int specut;
char buf[BUFSIZ];
Spec spec = NULL;
int rc;
rpmSetTables(RPM_MACHTABLE_BUILDARCH, RPM_MACHTABLE_BUILDOS);
if (ba->buildRootOverride)
buildRootURL = rpmGenPath(NULL, ba->buildRootOverride, NULL);
if (fromTarball) {
FILE *fp;
const char *specDir;
const char * tmpSpecFile;
char * cmd, *s;
@ -116,27 +121,27 @@ static int buildForTarget(const char *arg, struct rpmBuildArguments *ba,
cmd = alloca(strlen(arg) + 50 + strlen(tmpSpecFile));
sprintf(cmd, "gunzip < %s | tar xOvf - Specfile 2>&1 > %s",
arg, tmpSpecFile);
if (!(f = popen(cmd, "r"))) {
if (!(fp = popen(cmd, "r"))) {
fprintf(stderr, _("Failed to open tar pipe: %s\n"),
strerror(errno));
xfree(specDir);
xfree(tmpSpecFile);
return 1;
}
if ((!fgets(buf, sizeof(buf) - 1, f)) || !strchr(buf, '/')) {
if ((!fgets(buf, sizeof(buf) - 1, fp)) || !strchr(buf, '/')) {
/* Try again */
pclose(f);
pclose(fp);
sprintf(cmd, "gunzip < %s | tar xOvf - \\*.spec 2>&1 > %s", arg,
tmpSpecFile);
if (!(f = popen(cmd, "r"))) {
if (!(fp = popen(cmd, "r"))) {
fprintf(stderr, _("Failed to open tar pipe: %s\n"),
strerror(errno));
xfree(specDir);
xfree(tmpSpecFile);
return 1;
}
if (!fgets(buf, sizeof(buf) - 1, f)) {
if (!fgets(buf, sizeof(buf) - 1, fp)) {
/* Give up */
fprintf(stderr, _("Failed to read spec file from %s\n"), arg);
unlink(tmpSpecFile);
@ -145,7 +150,7 @@ static int buildForTarget(const char *arg, struct rpmBuildArguments *ba,
return 1;
}
}
pclose(f);
pclose(fp);
cmd = s = buf;
while (*cmd) {
@ -159,7 +164,7 @@ static int buildForTarget(const char *arg, struct rpmBuildArguments *ba,
s = cmd + strlen(cmd) - 1;
*s = '\0';
specfile = s = alloca(strlen(specDir) + strlen(cmd) + 5);
specURL = s = alloca(strlen(specDir) + strlen(cmd) + 5);
sprintf(s, "%s/%s", specDir, cmd);
res = rename(tmpSpecFile, s);
xfree(specDir);
@ -188,43 +193,43 @@ static int buildForTarget(const char *arg, struct rpmBuildArguments *ba,
addMacro(NULL, "_sourcedir", NULL, buf, RMIL_TARBALL);
} else {
specfile = arg;
specURL = arg;
}
switch (urlIsURL(specfile)) {
case URL_IS_UNKNOWN:
if (arg[0] == '/') {
specfile = arg;
} else {
char *s = alloca(BUFSIZ);
(void)getcwd(s, BUFSIZ);
strcat(s, "/");
strcat(s, arg);
specfile = s;
}
stat(specfile, &statbuf);
if (! S_ISREG(statbuf.st_mode)) {
fprintf(stderr, _("File is not a regular file: %s\n"), specfile);
return 1;
specut = urlPath(specURL, &specFile);
if (*specFile != '/') {
char *s = alloca(BUFSIZ);
(void)getcwd(s, BUFSIZ);
strcat(s, "/");
strcat(s, arg);
specURL = s;
}
if (specut != URL_IS_DASH) {
struct stat st;
Stat(specURL, &st);
if (! S_ISREG(st.st_mode)) {
fprintf(stderr, _("File is not a regular file: %s\n"), specURL);
rc = 1;
goto exit;
}
/* Try to verify that the file is actually a specfile */
if (!isSpecFile(specfile)) {
if (!isSpecFile(specURL)) {
fprintf(stderr, _("File %s does not appear to be a specfile.\n"),
specfile);
return 1;
specURL);
rc = 1;
goto exit;
}
break;
default:
break;
}
/* Parse the spec file */
#define _anyarch(_f) \
(((_f)&(RPMBUILD_PREP|RPMBUILD_BUILD|RPMBUILD_INSTALL|RPMBUILD_PACKAGEBINARY)) == 0)
if (parseSpec(&spec, specfile, ba->rootdir, buildRoot, 0, passPhrase,
cookie, _anyarch(buildAmount), force)) {
return 1;
if (parseSpec(&spec, specURL, ba->rootdir, buildRootURL, 0, passPhrase,
cookie, _anyarch(buildAmount), force)) {
rc = 1;
goto exit;
}
#undef _anyarch
@ -233,20 +238,24 @@ static int buildForTarget(const char *arg, struct rpmBuildArguments *ba,
/* Check build prerequisites */
if (!nodeps && checkSpec(spec->sourceHeader)) {
freeSpec(spec);
return 1;
rc = 1;
goto exit;
}
if (buildSpec(spec, buildAmount, test)) {
freeSpec(spec);
return 1;
rc = 1;
goto exit;
}
if (fromTarball) unlink(specfile);
if (fromTarball) Unlink(specURL);
rc = 0;
freeSpec(spec);
return 0;
exit:
if (spec)
freeSpec(spec);
if (buildRootURL)
xfree(buildRootURL);
return rc;
}
int build(const char *arg, struct rpmBuildArguments *ba, const char *passPhrase,

View File

@ -3,6 +3,8 @@
#include <rpmbuild.h>
#include <rpmurl.h>
static int _build_debug = 0;
static void doRmSource(Spec spec)
{
struct Source *p;
@ -34,23 +36,12 @@ static void doRmSource(Spec spec)
/*
* The _preScript string is expanded to export values to a script environment.
*/
int doScript(Spec spec, int what, const char *name, StringBuf sb, int test)
{
const char * rootURL = spec->rootURL;
const char * rootDir;
const char *scriptName = NULL;
const char * buildURL = rpmGenPath(rootURL, "%{_builddir}", "");
#ifdef DYING
const char * buildDir;
const char * buildSubdir;
const char * buildScript;
const char * remsh = rpmGetPath("%{?_remsh:%{_remsh}}", NULL);
const char * remchroot = rpmGetPath("%{?_remchroot:%{_remchroot}}", NULL);
const char * buildShell =
rpmGetPath("%{?_buildshell:%{_buildshell}}%{!?_buildshell:/bin/sh}", NULL);
const char * buildEnv = rpmExpand("%{_preScriptEnvironment}", NULL);
#else
const char * buildDirURL = rpmGenPath(rootURL, "%{_builddir}", "");
const char * buildScript;
const char * buildCmd = NULL;
const char * buildTemplate = NULL;
@ -59,7 +50,6 @@ int doScript(Spec spec, int what, const char *name, StringBuf sb, int test)
const char * mPost = NULL;
int argc = 0;
const char **argv = NULL;
#endif
FILE * fp = NULL;
urlinfo u = NULL;
@ -111,8 +101,7 @@ int doScript(Spec spec, int what, const char *name, StringBuf sb, int test)
goto exit;
}
if (makeTempFile(rootURL, &scriptName, &fd)) {
Fclose(fd);
if (makeTempFile(rootURL, &scriptName, &fd) || fd == NULL || Ferror(fd)) {
rpmError(RPMERR_SCRIPT, _("Unable to open temp file"));
rc = RPMERR_SCRIPT;
goto exit;
@ -122,7 +111,7 @@ int doScript(Spec spec, int what, const char *name, StringBuf sb, int test)
switch (rootut) {
case URL_IS_PATH:
case URL_IS_UNKNOWN:
(void)fchmod(Fileno(fd), 0600); /* XXX fubar on ufdio */
(void)fchmod(Fileno(fd), 0600);
break;
default:
break;
@ -140,28 +129,13 @@ int doScript(Spec spec, int what, const char *name, StringBuf sb, int test)
(void) urlPath(rootURL, &rootDir);
if (*rootDir == '\0') rootDir = "/";
#ifdef DYING
(void) urlPath(buildURL, &buildDir);
(void) urlPath(spec->buildSubdir, &buildSubdir);
#endif
(void) urlPath(scriptName, &buildScript);
buildTemplate = rpmExpand(mTemplate, NULL);
buildPost = rpmExpand(mPost, NULL);
#ifdef DYING
fprintf(fp, "#!%s\n", buildShell);
fputs(buildEnv, fp);
fputs("\n", fp);
fprintf(fp, rpmIsVerbose()
? "set -x\n\n"
: "exec > /dev/null\n\n");
fprintf(fp, "umask 022\ncd %s\n", buildDir);
#else
fputs(buildTemplate, fp);
#endif
if (what != RPMBUILD_PREP && what != RPMBUILD_RMBUILD && spec->buildSubdir)
fprintf(fp, "cd %s\n", spec->buildSubdir);
@ -172,11 +146,7 @@ int doScript(Spec spec, int what, const char *name, StringBuf sb, int test)
} else
fprintf(fp, "%s", getStringBuf(sb));
#ifdef DYING
fprintf(fp, "\nexit 0\n");
#else
fputs(buildPost, fp);
#endif
Fclose(xfd);
@ -185,12 +155,28 @@ int doScript(Spec spec, int what, const char *name, StringBuf sb, int test)
goto exit;
}
if (buildURL && buildURL[0] != '/' && (urlSplit(buildURL, &u) != 0)) {
if (_build_debug)
fprintf(stderr, "*** rootURL %s buildDirURL %s\n", rootURL, buildDirURL);
if (buildDirURL && buildDirURL[0] != '/' &&
(urlSplit(buildDirURL, &u) != 0)) {
rc = RPMERR_SCRIPT;
goto exit;
}
if (u)
addMacro(spec->macros, "_build_hostname", NULL, u->path, RMIL_SPEC);
if (u) {
switch (u->urltype) {
case URL_IS_FTP:
if (_build_debug)
fprintf(stderr, "*** addMacros\n");
addMacro(spec->macros, "_remsh", NULL, "%{__remsh}", RMIL_SPEC);
addMacro(spec->macros, "_remhost", NULL, u->host, RMIL_SPEC);
if (strcmp(rootDir, "/"))
addMacro(spec->macros, "_remroot", NULL, rootDir, RMIL_SPEC);
break;
case URL_IS_HTTP:
default:
break;
}
}
buildCmd = rpmExpand("%{___build_cmd}", " ", buildScript, NULL);
poptParseArgvString(buildCmd, &argc, &argv);
@ -198,33 +184,8 @@ int doScript(Spec spec, int what, const char *name, StringBuf sb, int test)
rpmMessage(RPMMESS_NORMAL, _("Executing(%s): %s\n"), name, buildCmd);
if (!(child = fork())) {
#ifdef DYING
fprintf(stderr, "*** root %s buildDir %s script %s remsh %s \n", rootDir, buildDir, scriptName, remsh);
if (u == NULL || *remsh == '\0') {
fprintf(stderr, "*** LOCAL %s %s -e %s %s\n", buildShell, buildShell, buildScript, buildScript);
if (rootURL) {
if (!(rootDir[0] == '/' && rootDir[1] == '\0')) {
chroot(rootDir);
chdir("/");
}
}
errno = 0;
execl(buildShell, buildShell, "-e", buildScript, buildScript, NULL);
} else {
if (*remchroot == '\0') {
fprintf(stderr, "*** REMSH %s %s %s -e %s %s\n", remsh, u->host, buildShell, buildScript, buildScript);
errno = 0;
execl(remsh, remsh, u->host, buildShell, "-e", buildScript, buildScript, NULL);
} else {
fprintf(stderr, "*** REMCHROOT %s %s %s %s -e %s %s\n", remsh, u->host, remchroot, buildShell, buildScript, buildScript);
errno = 0;
execl(remsh, remsh, u->host, remchroot, buildShell, "-e", buildScript, buildScript, NULL);
}
}
#else
errno = 0;
execvp(argv[0], (char *const *)argv);
#endif
rpmError(RPMERR_SCRIPT, _("Exec of %s failed (%s): %s"), scriptName, name, strerror(errno));
@ -246,19 +207,25 @@ exit:
Unlink(scriptName);
xfree(scriptName);
}
#ifdef DYING
FREE(buildShell);
FREE(buildEnv);
FREE(remsh);
FREE(remchroot);
#else
if (u)
delMacro(spec->macros, "_build_hostname");
if (u) {
switch (u->urltype) {
case URL_IS_FTP:
case URL_IS_HTTP:
if (_build_debug)
fprintf(stderr, "*** delMacros\n");
delMacro(spec->macros, "_remsh");
delMacro(spec->macros, "_remhost");
if (strcmp(rootDir, "/"))
delMacro(spec->macros, "_remroot");
break;
default:
break;
}
}
FREE(argv);
FREE(buildCmd);
FREE(buildTemplate);
#endif
FREE(buildURL);
FREE(buildDirURL);
return rc;
}

View File

@ -1,5 +1,7 @@
#include "system.h"
static int _debug = 0;
#define MYALLPERMS 07777
#include <regex.h>
@ -31,8 +33,8 @@ typedef struct {
#define fl_size fl_st.st_size
#define fl_mtime fl_st.st_mtime
const char *diskName; /* get file from here */
const char *fileName; /* filename in cpio archive */
const char *diskURL; /* get file from here */
const char *fileURL; /* filename in cpio archive */
/*@observer@*/ const char *uname;
/*@observer@*/ const char *gname;
int flags;
@ -50,7 +52,7 @@ typedef struct {
} AttrRec;
struct FileList {
const char *buildURL;
const char *buildRootURL;
const char *prefix;
int fileCount;
@ -129,12 +131,13 @@ static void dumpAttrRec(const char *msg, AttrRec *ar) {
*
* Return nonzero if PATTERN has any special globbing chars in it.
*/
static int myGlobPatternP (const char *pattern)
static int myGlobPatternP (const char *patternURL)
{
register const char *p = pattern;
register char c;
const char *p;
char c;
int open = 0;
(void) urlPath(patternURL, &p);
while ((c = *p++) != '\0')
switch (c) {
case '?':
@ -753,8 +756,8 @@ static int parseForSimple(/*@unused@*/Spec spec, Package pkg, char *buf,
static int compareFileListRecs(const void *ap, const void *bp)
{
const char *a = ((FileListRec *)ap)->fileName;
const char *b = ((FileListRec *)bp)->fileName;
const char *a = ((FileListRec *)ap)->fileURL;
const char *b = ((FileListRec *)bp)->fileURL;
return strcmp(a, b);
}
@ -797,15 +800,15 @@ static void genCpioListAndHeader(struct FileList *fl,
clp = *cpioList = xmalloc(sizeof(**cpioList) * fl->fileListRecsUsed);
for (flp = fl->fileList, count = fl->fileListRecsUsed; count > 0; flp++, count--) {
if ((count > 1) && !strcmp(flp->fileName, flp[1].fileName)) {
rpmError(RPMERR_BADSPEC, _("File listed twice: %s"), flp->fileName);
if ((count > 1) && !strcmp(flp->fileURL, flp[1].fileURL)) {
rpmError(RPMERR_BADSPEC, _("File listed twice: %s"), flp->fileURL);
fl->processingFailed = 1;
}
/* Make the cpio list */
if (! (flp->flags & RPMFILE_GHOST)) {
clp->fsPath = xstrdup(flp->diskName);
clp->archivePath = xstrdup(flp->fileName + skipLen);
clp->fsPath = xstrdup(flp->diskURL);
clp->archivePath = xstrdup(flp->fileURL + skipLen);
clp->finalMode = flp->fl_mode;
clp->finalUid = flp->fl_uid;
clp->finalGid = flp->fl_gid;
@ -822,7 +825,7 @@ static void genCpioListAndHeader(struct FileList *fl,
compressed file list write before we write the actual package to
disk. */
headerAddOrAppendEntry(h, RPMTAG_OLDFILENAMES, RPM_STRING_ARRAY_TYPE,
&(flp->fileName), 1);
&(flp->fileURL), 1);
if (sizeof(flp->fl_size) != sizeof(uint_32)) {
uint_32 psize = (uint_32)flp->fl_size;
@ -877,14 +880,14 @@ static void genCpioListAndHeader(struct FileList *fl,
buf[0] = '\0';
if (S_ISREG(flp->fl_mode))
mdfile(flp->diskName, buf);
mdfile(flp->diskURL, buf);
s = buf;
headerAddOrAppendEntry(h, RPMTAG_FILEMD5S, RPM_STRING_ARRAY_TYPE,
&s, 1);
buf[0] = '\0';
if (S_ISLNK(flp->fl_mode))
buf[readlink(flp->diskName, buf, BUFSIZ)] = '\0';
buf[readlink(flp->diskURL, buf, BUFSIZ)] = '\0';
s = buf;
headerAddOrAppendEntry(h, RPMTAG_FILELINKTOS, RPM_STRING_ARRAY_TYPE,
&s, 1);
@ -896,7 +899,7 @@ static void genCpioListAndHeader(struct FileList *fl,
headerAddOrAppendEntry(h, RPMTAG_FILEVERIFYFLAGS, RPM_INT32_TYPE,
&(flp->verifyFlags), 1);
if (!isSrc && isDoc(fl, flp->fileName))
if (!isSrc && isDoc(fl, flp->fileURL))
flp->flags |= RPMFILE_DOC;
if (S_ISDIR(flp->fl_mode))
flp->flags &= ~(RPMFILE_CONFIG|RPMFILE_DOC);
@ -911,16 +914,16 @@ static void genCpioListAndHeader(struct FileList *fl,
static void freeFileList(FileListRec *fileList, int count)
{
while (count--) {
FREE(fileList[count].diskName);
FREE(fileList[count].fileName);
FREE(fileList[count].diskURL);
FREE(fileList[count].fileURL);
FREE(fileList[count].langs);
}
FREE(fileList);
}
static int addFile(struct FileList *fl, const char *diskName, struct stat *statp)
static int addFile(struct FileList *fl, const char * diskURL, struct stat *statp)
{
const char *fileName = diskName;
const char *fileURL = diskURL;
struct stat statbuf;
mode_t fileMode;
uid_t fileUid;
@ -929,35 +932,60 @@ static int addFile(struct FileList *fl, const char *diskName, struct stat *statp
const char *fileGname;
char *lang;
/* Path may have prepended buildURL, so locate the original filename. */
if (_debug)
fprintf(stderr, "*** AF ENTRY buildRootURL %s fileURL %s diskURL %s\n", fl->buildRootURL, fileURL, diskURL);
/* Path may have prepended buildRootURL, so locate the original filename. */
#ifdef DYING
{ const char *s;
char c;
if ((s = fl->buildURL) != NULL) {
if ((s = fl->buildRootURL) != NULL) {
c = '\0';
while (*s) {
if (c == '/' && !(s[0] == '/' && s[1] == ':'))
while(*s && *s == '/') s++;
if (*s) {
fileName++;
fileURL++;
c = *s++;
}
}
}
}
#else
/*
* XXX There are 3 types of entry into addFile:
*
* From diskUrl statp
* =====================================================
* processBinaryFile path NULL
* processBinaryFile glob result path NULL
* myftw path stat
*
*/
{ const char *fileName;
int ut = urlPath(fileURL, &fileName);
if (fl->buildRootURL && strcmp(fl->buildRootURL, "/"))
fileURL += strlen(fl->buildRootURL);
}
#endif
if (_debug)
fprintf(stderr, "*** AF STRIP buildRootURL %s fileURL %s diskURL %s\n", fl->buildRootURL, fileURL, diskURL);
/* If we are using a prefix, validate the file */
if (!fl->inFtw && fl->prefix) {
const char *prefixTest = fileName;
const char *prefixTest;
const char *prefixPtr = fl->prefix;
(void) urlPath(fileURL, &prefixTest);
if (_debug)
fprintf(stderr, "*** AF prefixTest %s prefixPtr %s\n", prefixTest, prefixPtr);
while (*prefixPtr && *prefixTest && (*prefixTest == *prefixPtr)) {
prefixPtr++;
prefixTest++;
}
if (*prefixPtr || (*prefixTest && *prefixTest != '/')) {
rpmError(RPMERR_BADSPEC, _("File doesn't match prefix (%s): %s"),
fl->prefix, fileName);
fl->prefix, fileURL);
fl->processingFailed = 1;
return RPMERR_BADSPEC;
}
@ -965,8 +993,8 @@ static int addFile(struct FileList *fl, const char *diskName, struct stat *statp
if (statp == NULL) {
statp = &statbuf;
if (lstat(diskName, statp)) {
rpmError(RPMERR_BADSPEC, _("File not found: %s"), diskName);
if (Lstat(diskURL, statp)) {
rpmError(RPMERR_BADSPEC, _("File not found: %s"), diskURL);
fl->processingFailed = 1;
return RPMERR_BADSPEC;
}
@ -977,9 +1005,9 @@ static int addFile(struct FileList *fl, const char *diskName, struct stat *statp
/* instead of lstat(), which causes it to follow symlinks! */
/* It also has better callback support. */
fl->inFtw = 1; /* Flag to indicate file has buildURL prefixed */
fl->inFtw = 1; /* Flag to indicate file has buildRootURL prefixed */
fl->isDir = 1; /* Keep it from following myftw() again */
myftw(diskName, 16, (myftwFunc) addFile, fl);
myftw(diskURL, 16, (myftwFunc) addFile, fl);
fl->isDir = 0;
fl->inFtw = 0;
return 0;
@ -1024,7 +1052,7 @@ static int addFile(struct FileList *fl, const char *diskName, struct stat *statp
#endif
rpmMessage(RPMMESS_DEBUG, _("File %4d: %07o %s.%s\t %s\n"), fl->fileCount,
fileMode, fileUname, fileGname, fileName);
fileMode, fileUname, fileGname, fileURL);
/* Add to the file list */
if (fl->fileListRecsUsed == fl->fileListRecsAlloced) {
@ -1040,8 +1068,10 @@ static int addFile(struct FileList *fl, const char *diskName, struct stat *statp
flp->fl_uid = fileUid;
flp->fl_gid = fileGid;
flp->fileName = xstrdup(fileName);
flp->diskName = xstrdup(diskName);
flp->fileURL = xstrdup(fileURL);
flp->diskURL = xstrdup(diskURL);
if (_debug)
fprintf(stderr, "*** AF SAVE buildRootURL %s fileURL %s diskURL %s\n", fl->buildRootURL, fileURL, diskURL);
flp->uname = fileUname;
flp->gname = fileGname;
@ -1061,7 +1091,7 @@ static int addFile(struct FileList *fl, const char *diskName, struct stat *statp
*ncl++ = *ocl;
*ncl = '\0';
}
} else if (! parseForRegexLang(fileName, &lang)) {
} else if (! parseForRegexLang(fileURL, &lang)) {
flp->langs = xstrdup(lang);
} else {
flp->langs = xstrdup("");
@ -1085,29 +1115,38 @@ static int glob_error(/*@unused@*/const char *foo, /*@unused@*/int bar)
}
static int processBinaryFile(/*@unused@*/Package pkg, struct FileList *fl,
const char *fileName)
const char *fileURL)
{
int doGlob = myGlobPatternP(fileName);
const char *fn;
int doGlob;
const char *diskURL = NULL;
int rc = 0;
if (_debug)
fprintf(stderr, "*** PBF fileURL %s\n", fileURL);
doGlob = myGlobPatternP(fileURL);
/* Check that file starts with leading "/" */
if (*fileName != '/') {
rpmError(RPMERR_BADSPEC, _("File needs leading \"/\": %s"), fileName);
rc = 1;
goto exit;
{ const char * fileName;
(void) urlPath(fileURL, &fileName);
if (*fileName != '/') {
rpmError(RPMERR_BADSPEC, _("File needs leading \"/\": %s"), fileName);
rc = 1;
goto exit;
}
}
/* Copy file name or glob pattern removing multiple "/" chars. */
#ifdef DYING
{ const char *s;
char c, *t = alloca((fl->buildURL ? strlen(fl->buildURL) : 0) +
strlen(fileName) + 1);
char c, *t = alloca((fl->buildRootURL ? strlen(fl->buildRootURL) : 0) +
strlen(fileURL) + 1);
fn = t;
*t = c = '\0';
/* With a buildroot, prepend the buildURL now. */
if ((s = fl->buildURL) != NULL) {
/* With a buildroot, prepend the buildRootURL now. */
if ((s = fl->buildRootURL) != NULL) {
while (*s) {
if (c == '/' && !(s[0] == '/' && s[1] == ':'))
while(*s && *s == '/') s++;
@ -1128,27 +1167,77 @@ static int processBinaryFile(/*@unused@*/Package pkg, struct FileList *fl,
*t = '\0';
}
}
#else
/*
* Note: rpmGetPath should guarantee a "canonical" path. That means
* that the following pathologies should be weeded out:
* //bin//sh
* //usr//bin/
* /.././../usr/../bin//./sh (XXX FIXME: dots not handled yet)
*/
diskURL = rpmGenPath(fl->buildRootURL, NULL, fileURL);
#endif
if (doGlob) {
const char * diskRoot;
const char * globURL;
char * globRoot = NULL;
glob_t glob_result;
size_t maxb, nb;
int ut;
int i;
glob_result.gl_pathc = 0;
glob_result.gl_pathv = NULL;
if (glob(fn, 0, glob_error, &glob_result) ||
if (Glob(diskURL, 0, glob_error, &glob_result) ||
(glob_result.gl_pathc < 1)) {
rpmError(RPMERR_BADSPEC, _("File not found by glob: %s"), fn);
rpmError(RPMERR_BADSPEC, _("File not found by glob: %s"), diskURL);
rc = 1;
}
/* XXX Prepend the diskURL leader for globs that have stripped it off */
maxb = 0;
for (i = 0; i < glob_result.gl_pathc; i++) {
if ((nb = strlen(&(glob_result.gl_pathv[i][0]))) > maxb)
maxb = nb;
}
for (i = 0; rc == 0 && i < glob_result.gl_pathc; i++)
rc = addFile(fl, &(glob_result.gl_pathv[i][0]), NULL);
globfree(&glob_result);
ut = urlPath(diskURL, &diskRoot);
nb = ((ut > URL_IS_DASH) ? (diskRoot - diskURL) : 0);
maxb += nb;
maxb += 1;
globURL = globRoot = alloca(maxb);
switch (ut) {
case URL_IS_HTTP:
case URL_IS_FTP:
case URL_IS_PATH:
case URL_IS_DASH:
strncpy(globRoot, diskURL, nb);
break;
case URL_IS_UNKNOWN:
break;
}
globRoot += nb;
*globRoot = '\0';
if (_debug)
fprintf(stderr, "*** GLOB maxb %d diskURL %d %*s globURL %p %s\n", maxb, nb, nb, diskURL, globURL, globURL);
for (i = 0; rc == 0 && i < glob_result.gl_pathc; i++) {
const char * globFile = &(glob_result.gl_pathv[i][0]);
if (globRoot > globURL && globRoot[-1] == '/')
while (*globFile == '/') globFile++;
strcpy(globRoot, globFile);
rc = addFile(fl, globURL, NULL);
}
Globfree(&glob_result);
} else {
rc = addFile(fl, fn, NULL);
rc = addFile(fl, diskURL, NULL);
}
exit:
if (diskURL)
xfree(diskURL);
if (rc)
fl->processingFailed = 1;
return rc;
@ -1198,8 +1287,8 @@ static int processPackageFiles(Spec spec, Package pkg,
/* Init the file list structure */
/* XXX spec->buildURL == NULL, then xstrdup("") is returned */
fl.buildURL = rpmGenPath(spec->rootURL, spec->buildURL, NULL);
/* XXX spec->buildRootURL == NULL, then xstrdup("") is returned */
fl.buildRootURL = rpmGenPath(spec->rootURL, spec->buildRootURL, NULL);
if (headerGetEntry(pkg->header, RPMTAG_DEFAULTPREFIX,
NULL, (void **)&fl.prefix, NULL)) {
@ -1333,7 +1422,7 @@ static int processPackageFiles(Spec spec, Package pkg,
}
/* Clean up */
FREE(fl.buildURL);
FREE(fl.buildRootURL);
FREE(fl.prefix);
freeAttrRec(&fl.cur_ar);
@ -1510,14 +1599,16 @@ int processSourceFiles(Spec spec)
continue; /* XXX WRONG WRONG WRONG */
}
flp->diskName = xstrdup(s);
flp->diskURL = xstrdup(s);
fn = strrchr(s, '/');
if (fn)
fn++;
else
fn = s;
flp->fileName = xstrdup(fn);
flp->fileURL = xstrdup(fn);
if (_debug)
fprintf(stderr, "*** PSF fileName %s diskName %s\n", flp->fileURL, flp->diskURL);
flp->verifyFlags = RPMVERIFY_ALL;
stat(s, &flp->fl_st);

View File

@ -57,7 +57,7 @@ myftw_dir (DIR **dirs, int level, int descriptors,
errno = 0;
while ((entry = readdir (dirs[level])) != NULL)
while ((entry = Readdir (dirs[level])) != NULL)
{
struct stat s;
int flag, retval, newlev = 0;
@ -89,7 +89,7 @@ myftw_dir (DIR **dirs, int level, int descriptors,
if (Lstat (dir, &s) < 0)
{
/* Following POSIX.1 2.4 ENOENT is returned if the file cannot
* be stat'ed. This can happen for a file returned by readdir
* be stat'ed. This can happen for a file returned by Readdir
* if it's an unresolved symbolic link. This should be regarded
* as an forgivable error. -- Uli. */
if (errno != EACCES && errno != ENOENT)
@ -101,9 +101,9 @@ myftw_dir (DIR **dirs, int level, int descriptors,
newlev = (level + 1) % descriptors;
if (dirs[newlev] != NULL)
closedir (dirs[newlev]);
Closedir (dirs[newlev]);
dirs[newlev] = opendir (dir);
dirs[newlev] = Opendir (dir);
if (dirs[newlev] != NULL)
flag = MYFTW_D;
else
@ -128,7 +128,7 @@ myftw_dir (DIR **dirs, int level, int descriptors,
int save;
save = errno;
closedir (dirs[newlev]);
Closedir (dirs[newlev]);
errno = save;
dirs[newlev] = NULL;
}
@ -142,14 +142,14 @@ myftw_dir (DIR **dirs, int level, int descriptors,
int skip;
dir[len] = '\0';
dirs[level] = opendir (dir);
dirs[level] = Opendir (dir);
if (dirs[level] == NULL)
return -1;
skip = got;
while (skip-- != 0)
{
errno = 0;
if (readdir (dirs[level]) == NULL)
if (Readdir (dirs[level]) == NULL)
return errno == 0 ? 0 : -1;
}
}
@ -187,7 +187,7 @@ int myftw (const char *dir,
if (Lstat (dir, &s) < 0)
{
/* Following POSIX.1 2.4 ENOENT is returned if the file cannot
* be stat'ed. This can happen for a file returned by readdir
* be stat'ed. This can happen for a file returned by Readdir
* if it's an unresolved symbolic link. This should be regarded
* as an forgivable error. -- Uli. */
if (errno != EACCES && errno != ENOENT)
@ -196,7 +196,7 @@ int myftw (const char *dir,
}
else if (S_ISDIR (s.st_mode))
{
dirs[0] = opendir (dir);
dirs[0] = Opendir (dir);
if (dirs[0] != NULL)
flag = MYFTW_D;
else
@ -223,7 +223,7 @@ int myftw (const char *dir,
int save;
save = errno;
closedir (dirs[0]);
Closedir (dirs[0]);
errno = save;
}
}

View File

@ -1,5 +1,7 @@
#include "system.h"
static int _debug = 0;
#include <rpmbuild.h>
#include <rpmurl.h>
@ -397,36 +399,49 @@ static int handlePreambleTag(Spec spec, Package pkg, int tag, const char *macro,
case RPMTAG_BUILDROOT:
SINGLE_TOKEN_ONLY;
{ const char * buildRoot = NULL;
const char * buildURL = spec->buildURL;
const char * buildRootURL = spec->buildRootURL;
if (buildURL == NULL) {
buildURL = rpmGenPath(spec->rootURL, "%{?buildroot:%{buildroot}}", NULL);
if (strcmp(spec->rootURL, buildURL)) {
spec->buildURL = buildURL;
/*
* Note: rpmGenPath should guarantee a "canonical" path. That means
* that the following pathologies should be weeded out:
* //bin//sh
* //usr//bin/
* /.././../usr/../bin//./sh
*/
if (buildRootURL == NULL) {
buildRootURL = rpmGenPath(NULL, "%{?buildroot:%{buildroot}}", NULL);
if (strcmp(buildRootURL, "/")) {
spec->buildRootURL = buildRootURL;
if (_debug)
fprintf(stderr, "*** PPA BuildRoot %s set from macro\n", buildRootURL);
macro = NULL;
} else {
const char * specURL = field;
xfree(buildRootURL);
(void) urlPath(specURL, (const char **)&field);
xfree(buildURL);
buildURL = rpmGenPath(NULL, specURL, NULL);
spec->buildURL = buildURL;
if (*field == '\0') field = "/";
buildRootURL = rpmGenPath(spec->rootURL, field, NULL);
field = spec->buildRootURL = buildRootURL;
if (_debug)
fprintf(stderr, "*** PPA BuildRoot %s set from field\n", buildRootURL);
}
spec->gotBuildRootURL = 1;
} else {
if (_debug)
fprintf(stderr, "*** PPA BuildRoot %s already set, skipping field %s\n", buildRootURL, field);
macro = NULL;
}
(void) urlPath(buildURL, &buildRoot);
buildRootURL = rpmGenPath(NULL, spec->buildRootURL, NULL);
(void) urlPath(buildRootURL, &buildRoot);
if (*buildRoot == '\0') buildRoot = "/";
if (!strcmp(buildRoot, "/")) {
rpmError(RPMERR_BADSPEC,
_("line %d: BuildRoot can not be \"/\": %s"),
spec->lineNum, spec->line);
_("BuildRoot can not be \"/\": %s"), spec->buildRootURL);
xfree(buildRootURL);
return RPMERR_BADSPEC;
}
spec->gotBuildURL = 1;
xfree(buildRootURL);
} break;
case RPMTAG_PREFIXES:
addOrAppendListEntry(pkg->header, tag, field);
@ -735,7 +750,7 @@ int parsePreamble(Spec spec, int initialPackage)
/* Do some final processing on the header */
if (!spec->gotBuildURL && spec->buildURL) {
if (!spec->gotBuildRootURL && spec->buildRootURL) {
rpmError(RPMERR_BADSPEC, _("Spec file can't use BuildRoot"));
return RPMERR_BADSPEC;
}

View File

@ -18,16 +18,16 @@
{ 0, 0, 0, 0, 0, NULL, NULL}
};
static int checkOwners(const char *file)
static int checkOwners(const char *urlfn)
{
struct stat sb;
if (Lstat(file, &sb)) {
rpmError(RPMERR_BADSPEC, _("Bad source: %s: %s"), file, strerror(errno));
if (Lstat(urlfn, &sb)) {
rpmError(RPMERR_BADSPEC, _("Bad source: %s: %s"), urlfn, strerror(errno));
return RPMERR_BADSPEC;
}
if (!getUname(sb.st_uid) || !getGname(sb.st_gid)) {
rpmError(RPMERR_BADSPEC, _("Bad owner/group: %s"), file);
rpmError(RPMERR_BADSPEC, _("Bad owner/group: %s"), urlfn);
return RPMERR_BADSPEC;
}
@ -274,13 +274,13 @@ static int doSetupMacro(Spec spec, char *line)
poptFreeContext(optCon);
/* cd to the build dir */
{ const char * buildURL = rpmGenPath(spec->rootURL, "%{_builddir}", "");
{ const char * buildDirURL = rpmGenPath(spec->rootURL, "%{_builddir}", "");
const char *buildDir;
(void) urlPath(buildURL, &buildDir);
(void) urlPath(buildDirURL, &buildDir);
sprintf(buf, "cd %s", buildDir);
appendLineStringBuf(spec->prep, buf);
xfree(buildURL);
xfree(buildDirURL);
}
/* delete any old sources */

View File

@ -1,5 +1,7 @@
#include "system.h"
static int _debug = 0;
#include <rpmbuild.h>
#include <rpmurl.h>
@ -328,7 +330,7 @@ void closeSpec(Spec spec)
int noLang = 0; /* XXX FIXME: pass as arg */
int parseSpec(Spec *specp, const char *specFile, const char *rootURL,
const char *buildURL, int inBuildArch, const char *passPhrase,
const char *buildRootURL, int inBuildArch, const char *passPhrase,
char *cookie, int anyarch, int force)
{
int parsePart = PART_PREAMBLE;
@ -342,16 +344,30 @@ int parseSpec(Spec *specp, const char *specFile, const char *rootURL,
/* Set up a new Spec structure with no packages. */
spec = newSpec();
/*
* Note: rpmGetPath should guarantee a "canonical" path. That means
* that the following pathologies should be weeded out:
* //bin//sh
* //usr//bin/
* /.././../usr/../bin//./sh (XXX FIXME: dots not handled yet)
*/
spec->specFile = rpmGetPath(specFile, NULL);
spec->fileStack = newOpenFileInfo();
spec->fileStack->fileName = xstrdup(specFile);
spec->specFile = xstrdup(specFile);
if (buildURL) {
spec->fileStack->fileName = xstrdup(spec->specFile);
if (buildRootURL) {
const char * buildRoot;
spec->gotBuildURL = 1;
spec->buildURL = xstrdup(buildURL);
(void) urlPath(buildURL, &buildRoot);
(void) urlPath(buildRootURL, &buildRoot);
if (*buildRoot == '\0') buildRoot = "/";
if (!strcmp(buildRoot, "/")) {
rpmError(RPMERR_BADSPEC,
_("BuildRoot can not be \"/\": %s"), buildRootURL);
return RPMERR_BADSPEC;
}
spec->gotBuildRootURL = 1;
spec->buildRootURL = buildRootURL;
addMacro(spec->macros, "buildroot", NULL, buildRoot, RMIL_SPEC);
if (_debug)
fprintf(stderr, "*** PS buildRootURL %s macro set to %s\n", buildRootURL, buildRoot);
}
addMacro(NULL, "_docdir", NULL, "%{_defaultdocdir}", RMIL_SPEC);
spec->inBuildArchitectures = inBuildArch;
@ -365,20 +381,7 @@ int parseSpec(Spec *specp, const char *specFile, const char *rootURL,
if (cookie)
spec->cookie = xstrdup(cookie);
{ const char *timecheck = rpmExpand("%{_timecheck}", NULL);
if (timecheck && *timecheck != '%') {
if (parseNum(timecheck, &(spec->timeCheck))) {
rpmError(RPMERR_BADSPEC,
_("Timecheck value must be an integer: %s"), timecheck);
xfree(timecheck);
freeSpec(spec);
return RPMERR_BADSPEC;
}
} else {
spec->timeCheck = 0;
}
xfree(timecheck);
}
spec->timeCheck = rpmExpandNumeric("%{_timecheck}");
/* All the parse*() functions expect to have a line pre-read */
/* in the spec's line buffer. Except for parsePreamble(), */
@ -438,7 +441,7 @@ int parseSpec(Spec *specp, const char *specFile, const char *rootURL,
saveArch = xstrdup(saveArch);
rpmSetMachine(spec->buildArchitectures[x], NULL);
if (parseSpec(&(spec->buildArchitectureSpecs[index]),
specFile, spec->rootURL, buildURL, 1,
specFile, spec->rootURL, buildRootURL, 1,
passPhrase, cookie, anyarch, force)) {
spec->buildArchitectureCount = index;
freeSpec(spec);

View File

@ -97,8 +97,8 @@ struct SpecStruct {
int force;
int anyarch;
int gotBuildURL;
/*@only@*/ const char *buildURL;
int gotBuildRootURL;
/*@only@*/ const char *buildRootURL;
/*@only@*/ const char *buildSubdir;
char *passPhrase;

View File

@ -429,8 +429,8 @@ Spec newSpec(void)
spec->sourceCpioCount = 0;
spec->sourceCpioList = NULL;
spec->gotBuildURL = 0;
spec->buildURL = NULL;
spec->gotBuildRootURL = 0;
spec->buildRootURL = NULL;
spec->buildSubdir = NULL;
spec->passPhrase = NULL;
@ -464,7 +464,7 @@ void freeSpec(/*@only@*/ Spec spec)
freeStringBuf(spec->install); spec->install = NULL;
freeStringBuf(spec->clean); spec->clean = NULL;
FREE(spec->buildURL);
FREE(spec->buildRootURL);
FREE(spec->buildSubdir);
FREE(spec->specFile);
FREE(spec->sourceRpmName);

View File

@ -341,8 +341,8 @@ static int expandRegular(FD_t cfd, struct cpioHeader * hdr,
}
}
ofd = Fopen(hdr->path, "w.fdio"); /* XXX Fopen adds O_TRUNC */
if (Ferror(ofd))
ofd = Fopen(hdr->path, "r+.ufdio");
if (ofd == NULL || Ferror(ofd))
return CPIOERR_OPEN_FAILED;
cbInfo.file = hdr->path;
@ -706,7 +706,7 @@ static int writeFile(FD_t cfd, struct stat sb, struct cpioFileMapping * map,
/* While linux puts the size of a symlink in the st_size field,
I don't think that's a specified standard */
amount = readlink(map->fsPath, symbuf, sizeof(symbuf));
amount = Readlink(map->fsPath, symbuf, sizeof(symbuf));
if (amount <= 0) {
return CPIOERR_READLINK_FAILED;
}
@ -747,8 +747,8 @@ static int writeFile(FD_t cfd, struct stat sb, struct cpioFileMapping * map,
#endif
/* XXX unbuffered mmap generates *lots* of fdio debugging */
datafd = Fopen(map->fsPath, "r.fdio");
if (Ferror(datafd))
datafd = Fopen(map->fsPath, "r.ufdio");
if (datafd == NULL || Ferror(datafd))
return CPIOERR_OPEN_FAILED;
#if HAVE_MMAP
@ -885,9 +885,9 @@ int cpioBuildArchive(FD_t cfd, struct cpioFileMapping * mappings,
for (i = 0; i < numMappings; i++) {
if (mappings[i].mapFlags & CPIO_FOLLOW_SYMLINKS)
rc = stat(mappings[i].fsPath, &sb);
rc = Stat(mappings[i].fsPath, &sb);
else
rc = lstat(mappings[i].fsPath, &sb);
rc = Lstat(mappings[i].fsPath, &sb);
if (rc) {
if (failedFile)

View File

@ -1,5 +1,7 @@
#include "system.h"
static int _debug = 0;
#include <assert.h>
#include <stdarg.h>
@ -1464,43 +1466,92 @@ rpmExpandNumeric(const char *arg)
const char *
rpmGetPath(const char *path, ...)
{
char buf[BUFSIZ], *p, *pe;
char buf[BUFSIZ], *t, *te, *se;
const char *s;
va_list ap;
if (path == NULL)
return xstrdup("");
p = buf;
strcpy(p, path);
pe = p + strlen(p);
*pe = '\0';
t = buf;
te = stpcpy(t, path);
*te = '\0';
va_start(ap, path);
while ((s = va_arg(ap, const char *)) != NULL) {
/* XXX FIXME: this fixes only some of the "...//..." problems */
if (pe > p && pe[-1] == '/')
while(*s && *s == '/') s++;
if (*s != '\0') {
strcpy(pe, s);
pe += strlen(pe);
*pe = '\0';
}
te = stpcpy(te, s);
*te = '\0';
}
va_end(ap);
expandMacros(NULL, NULL, buf, sizeof(buf));
for (s = p = buf; *s; s++, p++) {
if (!(s > buf && s[-1] == ':'))
while (s[0] == '/' && s[1] == '/') s++;
*p = *s;
s = t = te = buf;
while (*s) {
/*fprintf(stderr, "*** got \"%.*s\"\trest \"%s\"\n", (t-buf), buf, s); */
switch(*s) {
case ':': /* handle url's */
if (s[1] == '/' && s[2] == '/') {
*t++ = *s++;
*t++ = *s++;
}
break;
case '/':
/* Move parent dir forward */
for (se = te + 1; se < t && *se != '/'; se++)
;
if (se < t && *se == '/') {
te = se;
/*fprintf(stderr, "*** next pdir \"%.*s\"\n", (te-buf), buf); */
}
while (s[1] == '/')
s++;
while (t > buf && t[-1] == '/')
t--;
break;
case '.':
/* Leading .. is special */
if (t == buf && s[1] == '.') {
*t++ = *s++;
break;
}
/* Single . is special */
if (t == buf && s[1] == '\0') {
break;
}
/* Trim leading ./ , embedded ./ , trailing /. */
if ((t == buf || t[-1] == '/') && (s[1] == '/' || s[1] == '\0')) {
/*fprintf(stderr, "*** Trim leading ./ , embedded ./ , trailing /.\n"); */
s++;
continue;
}
/* Trim embedded /../ and trailing /.. */
if (t > buf && t[-1] == '/' && s[1] == '.' && (s[2] == '/' || s[2] == '\0')) {
t = te;
/* Move parent dir forward */
if (te > buf)
for (--te; te > buf && *te != '/'; te--)
;
/*fprintf(stderr, "*** prev pdir \"%.*s\"\n", (te-buf), buf); */
s++;
s++;
continue;
}
break;
default:
break;
}
*t++ = *s++;
}
*p = '\0';
/* Trim trailing / (but leave single / alone) */
if (t > &buf[1] && t[-1] == '/')
t--;
*t = '\0';
return xstrdup(buf);
}
/* Merge 3 args into path, any or all of which may be a url. */
const char * rpmGenPath(const char * urlroot, const char * urlmdir,
const char *urlfile)
{
@ -1510,23 +1561,34 @@ const char * rpmGenPath(const char * urlroot, const char * urlmdir,
const char * result;
const char * url = NULL;
int nurl = 0;
int ut;
(void) urlPath(xroot, &root);
if (url == NULL && *root != '\0') {
if (_debug)
fprintf(stderr, "*** RGP xroot %s xmdir %s xfile %s\n", xroot, xmdir, xfile);
ut = urlPath(xroot, &root);
if (url == NULL && ut > URL_IS_DASH) {
url = xroot;
nurl = root - xroot;
if (_debug)
fprintf(stderr, "*** RGP ut %d root %s nurl %d\n", ut, root, nurl);
}
if (root == NULL || *root == '\0') root = "/";
(void) urlPath(xmdir, &mdir);
if (url == NULL && *mdir != '\0') {
ut = urlPath(xmdir, &mdir);
if (url == NULL && ut > URL_IS_DASH) {
url = xmdir;
nurl = mdir - xmdir;
if (_debug)
fprintf(stderr, "*** RGP ut %d mdir %s nurl %d\n", ut, mdir, nurl);
}
if (mdir == NULL || *mdir == '\0') mdir = "/";
(void) urlPath(xfile, &file);
if (url == NULL && *file != '\0') {
ut = urlPath(xfile, &file);
if (url == NULL && ut > URL_IS_DASH) {
url = xfile;
nurl = file - xfile;
if (_debug)
fprintf(stderr, "*** RGP ut %d file %s nurl %d\n", ut, file, nurl);
}
if (url && nurl > 0) {
@ -1536,11 +1598,13 @@ const char * rpmGenPath(const char * urlroot, const char * urlmdir,
} else
url = "";
result = rpmGetPath(url, root, mdir, file, NULL);
result = rpmGetPath(url, root, "/", mdir, "/", file, NULL);
xfree(xroot);
xfree(xmdir);
xfree(xfile);
if (_debug)
fprintf(stderr, "*** RGP result %s\n", result);
return result;
}

View File

@ -397,6 +397,9 @@ int makeTempFile(const char * prefix, const char ** fnptr, FD_t * fdptr) {
fd = Fopen(tempfn, "w+x.ufdio");
} while ((fd == NULL || Ferror(fd)) && errno == EEXIST);
if (fd == NULL || Ferror(fd))
goto errxit;
switch(temput) {
struct stat sb, sb2;
case URL_IS_PATH:
@ -432,6 +435,7 @@ int makeTempFile(const char * prefix, const char ** fnptr, FD_t * fdptr) {
errxit:
if (tempfn) xfree(tempfn);
if (fd) Fclose(fd);
return 1;
}

View File

@ -81,13 +81,22 @@ int Mkdir (const char * path, mode_t mode);
int Chdir (const char * path);
int Rmdir (const char * path);
int Rename (const char * oldpath, const char * newpath);
int Chroot (const char * path);
int Link (const char * oldpath, const char * newpath);
int Unlink (const char * path);
int Readlink(const char * path, char * buf, size_t bufsiz);
int Stat (const char * path, struct stat * st);
int Lstat (const char * path, struct stat * st);
int Access (const char * path, int amode);
int Glob (const char * pattern, int flags,
int errfunc(const char * epath, int eerrno), glob_t * pglob);
void Globfree(glob_t * pglob);
DIR * Opendir (const char * name);
struct dirent * Readdir (DIR * dir);
int Closedir(DIR * dir);
/*@observer@*/ extern FDIO_t gzdio;
void fdPush (FD_t fd, FDIO_t io, void * fp, int fdno);

View File

@ -27,6 +27,7 @@ typedef /*@abstract@*/ /*@refcounted@*/ struct urlinfo {
const char * proxyh; /* FTP/HTTP: proxy host */
int proxyp; /* FTP/HTTP: proxy port */
int port;
int urltype;
FD_t ctrl; /* control channel */
FD_t data; /* per-xfer data channel */
int bufAlloced; /* sizeof I/O buffer */

View File

@ -46,6 +46,7 @@ urlinfo XurlNew(const char *msg, const char *file, unsigned line)
memset(u, 0, sizeof(*u));
u->proxyp = -1;
u->port = -1;
u->urltype = URL_IS_UNKNOWN;
u->ctrl = NULL;
u->data = NULL;
u->bufAlloced = 0;
@ -214,7 +215,7 @@ static void urlFind(urlinfo *uret, int mustAsk)
FREE(u->proxyh);
/* Perform one-time FTP initialization */
if (u->service && !strcmp(u->service, "ftp")) {
if (u->urltype == URL_IS_FTP) {
if (mustAsk || (u->user != NULL && u->password == NULL)) {
char * prompt;
@ -255,7 +256,7 @@ static void urlFind(urlinfo *uret, int mustAsk)
}
/* Perform one-time HTTP initialization */
if (u->service && !strcmp(u->service, "http")) {
if (u->urltype == URL_IS_HTTP) {
if (u->proxyh == NULL) {
const char *proxy = rpmExpand("%{_httpproxy}", NULL);
@ -319,22 +320,23 @@ int urlPath(const char * url, const char ** pathp)
urltype = urlIsURL(url);
switch (urltype) {
case URL_IS_FTP:
path += sizeof("ftp://") - 1;
path = strchr(path, '/');
url += sizeof("ftp://") - 1;
path = strchr(url, '/');
if (path == NULL) path = url + strlen(url);
break;
case URL_IS_HTTP:
case URL_IS_PATH:
path += sizeof("file://") - 1;
path = strchr(path, '/');
url += sizeof("file://") - 1;
path = strchr(url, '/');
if (path == NULL) path = url + strlen(url);
break;
case URL_IS_UNKNOWN:
if (path == NULL) path = "";
break;
case URL_IS_DASH:
path = "";
break;
}
if (path == NULL) /* XXX gotta return something */
path = "";
if (pathp)
*pathp = path;
return urltype;
@ -361,6 +363,7 @@ int urlSplit(const char * url, urlinfo *uret)
}
u->url = xstrdup(url);
u->urltype = urlIsURL(url);
while (1) {
/* Point to end of next item */
@ -419,9 +422,9 @@ int urlSplit(const char * url, urlinfo *uret)
serv = /*@-unrecog@*/ getservbyname(u->service, "tcp") /*@=unrecog@*/;
if (serv != NULL)
u->port = ntohs(serv->s_port);
else if (!strcasecmp(u->service, "ftp"))
else if (u->urltype == URL_IS_FTP)
u->port = IPPORT_FTP;
else if (!strcasecmp(u->service, "http"))
else if (u->urltype == URL_IS_HTTP)
u->port = IPPORT_HTTP;
}

View File

@ -1,4 +1,4 @@
# $Id: macros.in,v 1.38 1999/11/19 18:19:41 jbj Exp $
# $Id: macros.in,v 1.39 1999/11/24 00:03:54 jbj Exp $
#==============================================================================
# Macro naming conventions (preliminary):
#
@ -58,6 +58,7 @@
%__objcopy @__OBJCOPY@
%__objdump @__OBJDUMP@
%__ranlib @RANLIB@
%__remsh %{__rsh}
%__strip @__STRIP@
# XXX avoid failures if tools are not installed when rpm is built.
@ -165,7 +166,7 @@ export RPM_BUILD_ROOT}
%___build_shell %{?_buildshell:%{_buildshell}}%{!?_buildshell:/bin/sh}
%___build_args -e
%___build_cmd %{?_sudo:%{_sudo} }%{?_remsh:%{_remsh} %{_build_hostname}}%{?_remsudo:%{_remsudo} }%{?_remchroot:%{_remchroot} }%{___build_shell} %{___build_args}
%___build_cmd %{?_sudo:%{_sudo} }%{?_remsh:%{_remsh} %{_remhost} }%{?_remsudo:%{_remsudo} }%{?_remchroot:%{_remchroot} %{_remroot} }%{___build_shell} %{___build_args}
%___build_pre \
RPM_SOURCE_DIR=\"%{u2p:%{_sourcedir}}\"\
RPM_BUILD_DIR=\"%{u2p:%{_builddir}}\"\

View File

@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 1999-11-19 12:50-0500\n"
"POT-Creation-Date: 1999-11-23 18:43-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -28,96 +28,96 @@ msgstr ""
msgid "Unable to open spec file %s: %s\n"
msgstr ""
#: build.c:120 build.c:133
#: build.c:125 build.c:138
#, c-format
msgid "Failed to open tar pipe: %s\n"
msgstr ""
#. Give up
#: build.c:141
#: build.c:146
#, c-format
msgid "Failed to read spec file from %s\n"
msgstr ""
#: build.c:169
#: build.c:174
#, c-format
msgid "Failed to rename %s to %s: %s\n"
msgstr ""
#: build.c:207
#: build.c:212
#, c-format
msgid "File is not a regular file: %s\n"
msgstr ""
#: build.c:213
#: build.c:219
#, c-format
msgid "File %s does not appear to be a specfile.\n"
msgstr ""
#. parse up the build operators
#: build.c:270
#: build.c:279
#, c-format
msgid "Building target platforms: %s\n"
msgstr ""
#: build.c:285
#: build.c:294
#, c-format
msgid "Building for target %s\n"
msgstr ""
#: build.c:335
#: build.c:344
msgid "buildroot already specified"
msgstr ""
#: build.c:342
#: build.c:351
msgid "--buildarch has been obsoleted. Use the --target option instead.\n"
msgstr ""
#: build.c:346
#: build.c:355
msgid "--buildos has been obsoleted. Use the --target option instead.\n"
msgstr ""
#: build.c:367
#: build.c:376
msgid "override build architecture"
msgstr ""
#: build.c:369
#: build.c:378
msgid "override build operating system"
msgstr ""
#: build.c:371
#: build.c:380
msgid "override build root"
msgstr ""
#: build.c:373 rpm.c:490
#: build.c:382 rpm.c:490
msgid "remove build tree when done"
msgstr ""
#: build.c:375
#: build.c:384
msgid "do not execute any stages of the build"
msgstr ""
#: build.c:377
#: build.c:386
msgid "do not accept I18N msgstr's from specfile"
msgstr ""
#: build.c:379
#: build.c:388
msgid "remove sources when done"
msgstr ""
#: build.c:381
#: build.c:390
msgid "remove specfile when done"
msgstr ""
#: build.c:383 rpm.c:488
#: build.c:392 rpm.c:488
msgid "skip straight to specified stage (only for c,i)"
msgstr ""
#: build.c:385
#: build.c:394
msgid "override target platform"
msgstr ""
#: build.c:387
#: build.c:396
msgid "lookup I18N strings in specfile catalog"
msgstr ""
@ -1234,21 +1234,21 @@ msgstr ""
msgid "cannot re-open payload: %s\n"
msgstr ""
#: build/build.c:116 build/pack.c:267
#: build/build.c:105 build/pack.c:267
msgid "Unable to open temp file"
msgstr ""
#: build/build.c:198
#: build/build.c:184
#, c-format
msgid "Executing(%s): %s\n"
msgstr ""
#: build/build.c:229
#: build/build.c:190
#, c-format
msgid "Exec of %s failed (%s): %s"
msgstr ""
#: build/build.c:237
#: build/build.c:198
#, c-format
msgid "Bad exit status from %s (%s)"
msgstr ""
@ -1306,158 +1306,158 @@ msgstr ""
msgid "syntax error in expression"
msgstr ""
#: build/files.c:228
#: build/files.c:231
#, c-format
msgid "TIMECHECK failure: %s\n"
msgstr ""
#: build/files.c:272 build/files.c:354 build/files.c:517
#: build/files.c:275 build/files.c:357 build/files.c:520
#, c-format
msgid "Missing '(' in %s %s"
msgstr ""
#: build/files.c:283 build/files.c:471 build/files.c:528
#: build/files.c:286 build/files.c:474 build/files.c:531
#, c-format
msgid "Missing ')' in %s(%s"
msgstr ""
#: build/files.c:321 build/files.c:496
#: build/files.c:324 build/files.c:499
#, c-format
msgid "Invalid %s token: %s"
msgstr ""
#: build/files.c:370
#: build/files.c:373
#, c-format
msgid "Non-white space follows %s(): %s"
msgstr ""
#: build/files.c:408
#: build/files.c:411
#, c-format
msgid "Bad syntax: %s(%s)"
msgstr ""
#: build/files.c:418
#: build/files.c:421
#, c-format
msgid "Bad mode spec: %s(%s)"
msgstr ""
#: build/files.c:430
#: build/files.c:433
#, c-format
msgid "Bad dirmode spec: %s(%s)"
msgstr ""
#: build/files.c:554
#: build/files.c:557
msgid "Unusual locale length: \"%.*s\" in %%lang(%s)"
msgstr ""
#: build/files.c:564
#: build/files.c:567
msgid "Duplicate locale %.*s in %%lang(%s)"
msgstr ""
#: build/files.c:659
#: build/files.c:662
msgid "Hit limit for %%docdir"
msgstr ""
#: build/files.c:665
#: build/files.c:668
msgid "Only one arg for %%docdir"
msgstr ""
#. We already got a file -- error
#: build/files.c:690
#: build/files.c:693
#, c-format
msgid "Two files on one line: %s"
msgstr ""
#: build/files.c:703
#: build/files.c:706
#, c-format
msgid "File must begin with \"/\": %s"
msgstr ""
#: build/files.c:715
#: build/files.c:718
msgid "Can't mix special %%doc with other forms: %s"
msgstr ""
#: build/files.c:801
#: build/files.c:804
#, c-format
msgid "File listed twice: %s"
msgstr ""
#: build/files.c:959
#: build/files.c:987
#, c-format
msgid "File doesn't match prefix (%s): %s"
msgstr ""
#: build/files.c:969
#: build/files.c:997
#, c-format
msgid "File not found: %s"
msgstr ""
#: build/files.c:1012
#: build/files.c:1040
#, c-format
msgid "Bad owner/group: %s\n"
msgstr ""
#: build/files.c:1026
#: build/files.c:1054
#, c-format
msgid "File %4d: %07o %s.%s\t %s\n"
msgstr ""
#: build/files.c:1096
#: build/files.c:1133
#, c-format
msgid "File needs leading \"/\": %s"
msgstr ""
#: build/files.c:1140
#: build/files.c:1194
#, c-format
msgid "File not found by glob: %s"
msgstr ""
#: build/files.c:1184
#: build/files.c:1273
msgid "Could not open %%files file %s: %s"
msgstr ""
#: build/files.c:1191 build/pack.c:480
#: build/files.c:1280 build/pack.c:480
#, c-format
msgid "line: %s"
msgstr ""
#: build/files.c:1532 build/parsePrep.c:30
#: build/files.c:1623 build/parsePrep.c:30
#, c-format
msgid "Bad owner/group: %s"
msgstr ""
#. XXX this error message is probably not seen.
#: build/files.c:1587
#: build/files.c:1678
#, c-format
msgid "Couldn't exec %s: %s"
msgstr ""
#: build/files.c:1592
#: build/files.c:1683
#, c-format
msgid "Couldn't fork %s: %s"
msgstr ""
#: build/files.c:1674
#: build/files.c:1765
#, c-format
msgid "%s failed"
msgstr ""
#: build/files.c:1678
#: build/files.c:1769
#, c-format
msgid "failed to write all data to %s"
msgstr ""
#: build/files.c:1767
#: build/files.c:1858
#, c-format
msgid "Finding %s: (using %s)...\n"
msgstr ""
#: build/files.c:1795 build/files.c:1804
#: build/files.c:1886 build/files.c:1895
#, c-format
msgid "Failed to find %s:"
msgstr ""
#: build/files.c:1910
#: build/files.c:2001
#, c-format
msgid "Processing files: %s-%s-%s\n"
msgstr ""
@ -1650,113 +1650,113 @@ msgstr ""
msgid "line %d: Second %%files list"
msgstr ""
#: build/parsePreamble.c:142
#: build/parsePreamble.c:144
#, c-format
msgid "Architecture is excluded: %s"
msgstr ""
#: build/parsePreamble.c:147
#: build/parsePreamble.c:149
#, c-format
msgid "Architecture is not included: %s"
msgstr ""
#: build/parsePreamble.c:152
#: build/parsePreamble.c:154
#, c-format
msgid "OS is excluded: %s"
msgstr ""
#: build/parsePreamble.c:157
#: build/parsePreamble.c:159
#, c-format
msgid "OS is not included: %s"
msgstr ""
#: build/parsePreamble.c:171
#: build/parsePreamble.c:173
#, c-format
msgid "%s field must be present in package: %s"
msgstr ""
#: build/parsePreamble.c:196
#: build/parsePreamble.c:198
#, c-format
msgid "Duplicate %s entries in package: %s"
msgstr ""
#: build/parsePreamble.c:243
#: build/parsePreamble.c:245
#, c-format
msgid "Unable to open icon %s: %s"
msgstr ""
#: build/parsePreamble.c:261
#: build/parsePreamble.c:263
#, c-format
msgid "Unable to read icon %s: %s"
msgstr ""
#: build/parsePreamble.c:274
#: build/parsePreamble.c:276
#, c-format
msgid "Unknown icon type: %s"
msgstr ""
#: build/parsePreamble.c:337
#: build/parsePreamble.c:339
#, c-format
msgid "line %d: Malformed tag: %s"
msgstr ""
#. Empty field
#: build/parsePreamble.c:345
#: build/parsePreamble.c:347
#, c-format
msgid "line %d: Empty tag: %s"
msgstr ""
#: build/parsePreamble.c:368 build/parsePreamble.c:375
#: build/parsePreamble.c:370 build/parsePreamble.c:377
#, c-format
msgid "line %d: Illegal char '-' in %s: %s"
msgstr ""
#: build/parsePreamble.c:425
#: build/parsePreamble.c:440 build/parseSpec.c:363
#, c-format
msgid "line %d: BuildRoot can not be \"/\": %s"
msgid "BuildRoot can not be \"/\": %s"
msgstr ""
#: build/parsePreamble.c:438
#: build/parsePreamble.c:453
#, c-format
msgid "line %d: Prefixes must not end with \"/\": %s"
msgstr ""
#: build/parsePreamble.c:450
#: build/parsePreamble.c:465
#, c-format
msgid "line %d: Docdir must begin with '/': %s"
msgstr ""
#: build/parsePreamble.c:462
#: build/parsePreamble.c:477
#, c-format
msgid "line %d: Epoch/Serial field must be a number: %s"
msgstr ""
#: build/parsePreamble.c:525
#: build/parsePreamble.c:540
#, c-format
msgid "line %d: Bad BuildArchitecture format: %s"
msgstr ""
#: build/parsePreamble.c:535
#: build/parsePreamble.c:550
#, c-format
msgid "Internal error: Bogus tag %d"
msgstr ""
#: build/parsePreamble.c:681
#: build/parsePreamble.c:696
#, c-format
msgid "Bad package specification: %s"
msgstr ""
#: build/parsePreamble.c:687
#: build/parsePreamble.c:702
#, c-format
msgid "Package already exists: %s"
msgstr ""
#: build/parsePreamble.c:714
#: build/parsePreamble.c:729
#, c-format
msgid "line %d: Unknown tag: %s"
msgstr ""
#: build/parsePreamble.c:739
#: build/parsePreamble.c:754
msgid "Spec file can't use BuildRoot"
msgstr ""
@ -1866,50 +1866,45 @@ msgstr ""
msgid "line %d: Second %s"
msgstr ""
#: build/parseSpec.c:127
#: build/parseSpec.c:129
#, c-format
msgid "line %d: %s"
msgstr ""
#. XXX Fstrerror
#: build/parseSpec.c:176
#: build/parseSpec.c:178
#, c-format
msgid "Unable to open %s: %s\n"
msgstr ""
#: build/parseSpec.c:188
#: build/parseSpec.c:190
msgid "Unclosed %%if"
msgstr ""
#: build/parseSpec.c:247
#: build/parseSpec.c:249
#, c-format
msgid "%s:%d: parseExpressionBoolean returns %d"
msgstr ""
#. Got an else with no %if !
#: build/parseSpec.c:255
#: build/parseSpec.c:257
msgid "%s:%d: Got a %%else with no if"
msgstr ""
#. Got an end with no %if !
#: build/parseSpec.c:266
#: build/parseSpec.c:268
msgid "%s:%d: Got a %%endif with no if"
msgstr ""
#: build/parseSpec.c:280 build/parseSpec.c:289
#: build/parseSpec.c:282 build/parseSpec.c:291
msgid "malformed %%include statement"
msgstr ""
#: build/parseSpec.c:372
#, c-format
msgid "Timecheck value must be an integer: %s"
msgstr ""
#: build/parseSpec.c:455
#: build/parseSpec.c:458
msgid "No buildable architectures"
msgstr ""
#: build/parseSpec.c:502
#: build/parseSpec.c:505
msgid "Package has no %%description: %s"
msgstr ""
@ -2309,84 +2304,84 @@ msgstr ""
msgid "cannot read header at %d for lookup"
msgstr ""
#: lib/macro.c:161
#: lib/macro.c:163
#, c-format
msgid "======================== active %d empty %d\n"
msgstr ""
#. XXX just in case
#: lib/macro.c:255
#: lib/macro.c:257
#, c-format
msgid "%3d>%*s(empty)"
msgstr ""
#: lib/macro.c:290
#: lib/macro.c:292
#, c-format
msgid "%3d<%*s(empty)\n"
msgstr ""
#: lib/macro.c:469
#: lib/macro.c:471
msgid "Macro %%%s has unterminated body"
msgstr ""
#: lib/macro.c:495
#: lib/macro.c:497
msgid "Macro %%%s has illegal name (%%define)"
msgstr ""
#: lib/macro.c:501
#: lib/macro.c:503
msgid "Macro %%%s has unterminated opts"
msgstr ""
#: lib/macro.c:506
#: lib/macro.c:508
msgid "Macro %%%s has empty body"
msgstr ""
#: lib/macro.c:511
#: lib/macro.c:513
msgid "Macro %%%s failed to expand"
msgstr ""
#: lib/macro.c:536
#: lib/macro.c:538
msgid "Macro %%%s has illegal name (%%undefine)"
msgstr ""
#: lib/macro.c:613
#: lib/macro.c:615
msgid "Macro %%%s (%s) was not used below level %d"
msgstr ""
#: lib/macro.c:710
#: lib/macro.c:712
#, c-format
msgid "Unknown option %c in %s(%s)"
msgstr ""
#: lib/macro.c:890
#: lib/macro.c:892
#, c-format
msgid "Recursion depth(%d) greater than max(%d)"
msgstr ""
#: lib/macro.c:956 lib/macro.c:972
#: lib/macro.c:958 lib/macro.c:974
#, c-format
msgid "Unterminated %c: %s"
msgstr ""
#: lib/macro.c:1012
#: lib/macro.c:1014
msgid "A %% is followed by an unparseable macro"
msgstr ""
#: lib/macro.c:1138
#: lib/macro.c:1140
msgid "Macro %%%.*s not found, skipping"
msgstr ""
#: lib/macro.c:1219
#: lib/macro.c:1221
msgid "Target buffer overflow"
msgstr ""
#. XXX Fstrerror
#: lib/macro.c:1374 lib/macro.c:1379
#: lib/macro.c:1376 lib/macro.c:1381
#, c-format
msgid "File %s: %s"
msgstr ""
#: lib/macro.c:1382
#: lib/macro.c:1384
#, c-format
msgid "File %s is smaller than %d bytes"
msgstr ""
@ -2407,7 +2402,7 @@ msgstr ""
msgid "internal error (rpm bug?): "
msgstr ""
#: lib/misc.c:405 lib/misc.c:410 lib/misc.c:416
#: lib/misc.c:408 lib/misc.c:413 lib/misc.c:419
#, c-format
msgid "error creating temporary file %s"
msgstr ""
@ -2838,7 +2833,7 @@ msgstr ""
msgid "opening database mode 0x%x in %s\n"
msgstr ""
#: lib/rpmdb.c:155 lib/url.c:444
#: lib/rpmdb.c:155 lib/url.c:447
#, c-format
msgid "failed to open %s: %s\n"
msgstr ""
@ -3032,59 +3027,59 @@ msgstr ""
msgid "Installing %s\n"
msgstr ""
#: lib/rpmio.c:675
#: lib/rpmio.c:686
msgid "Success"
msgstr ""
#: lib/rpmio.c:678
#: lib/rpmio.c:689
msgid "Bad server response"
msgstr ""
#: lib/rpmio.c:681
#: lib/rpmio.c:692
msgid "Server IO error"
msgstr ""
#: lib/rpmio.c:684
#: lib/rpmio.c:695
msgid "Server timeout"
msgstr ""
#: lib/rpmio.c:687
#: lib/rpmio.c:698
msgid "Unable to lookup server host address"
msgstr ""
#: lib/rpmio.c:690
#: lib/rpmio.c:701
msgid "Unable to lookup server host name"
msgstr ""
#: lib/rpmio.c:693
#: lib/rpmio.c:704
msgid "Failed to connect to server"
msgstr ""
#: lib/rpmio.c:696
#: lib/rpmio.c:707
msgid "Failed to establish data connection to server"
msgstr ""
#: lib/rpmio.c:699
#: lib/rpmio.c:710
msgid "IO error to local file"
msgstr ""
#: lib/rpmio.c:702
#: lib/rpmio.c:713
msgid "Error setting remote server to passive mode"
msgstr ""
#: lib/rpmio.c:705
#: lib/rpmio.c:716
msgid "File not found on server"
msgstr ""
#: lib/rpmio.c:708
#: lib/rpmio.c:719
msgid "Abort in progress"
msgstr ""
#: lib/rpmio.c:712
#: lib/rpmio.c:723
msgid "Unknown or unexpected error"
msgstr ""
#: lib/rpmio.c:1232
#: lib/rpmio.c:1244
#, c-format
msgid "logging into %s as %s, pw %s\n"
msgstr ""
@ -3383,37 +3378,37 @@ msgstr ""
msgid "execution of script failed"
msgstr ""
#: lib/url.c:80
#: lib/url.c:81
#, c-format
msgid "warning: u %p ctrl %p nrefs != 0 (%s %s)\n"
msgstr ""
#: lib/url.c:97
#: lib/url.c:98
#, c-format
msgid "warning: u %p data %p nrefs != 0 (%s %s)\n"
msgstr ""
#: lib/url.c:125
#: lib/url.c:126
#, c-format
msgid "warning: uCache[%d] %p nrefs(%d) != 1 (%s %s)\n"
msgstr ""
#: lib/url.c:222
#: lib/url.c:223
#, c-format
msgid "Password for %s@%s: "
msgstr ""
#: lib/url.c:247 lib/url.c:273
#: lib/url.c:248 lib/url.c:274
#, c-format
msgid "error: %sport must be a number\n"
msgstr ""
#: lib/url.c:408
#: lib/url.c:411
msgid "url port must be a number\n"
msgstr ""
#. XXX Fstrerror
#: lib/url.c:467
#: lib/url.c:470
#, c-format
msgid "failed to create %s: %s\n"
msgstr ""

View File

@ -1,5 +1,7 @@
#include "system.h"
static int _debug = 0;
#include <assert.h>
#include <stdarg.h>
@ -1464,43 +1466,92 @@ rpmExpandNumeric(const char *arg)
const char *
rpmGetPath(const char *path, ...)
{
char buf[BUFSIZ], *p, *pe;
char buf[BUFSIZ], *t, *te, *se;
const char *s;
va_list ap;
if (path == NULL)
return xstrdup("");
p = buf;
strcpy(p, path);
pe = p + strlen(p);
*pe = '\0';
t = buf;
te = stpcpy(t, path);
*te = '\0';
va_start(ap, path);
while ((s = va_arg(ap, const char *)) != NULL) {
/* XXX FIXME: this fixes only some of the "...//..." problems */
if (pe > p && pe[-1] == '/')
while(*s && *s == '/') s++;
if (*s != '\0') {
strcpy(pe, s);
pe += strlen(pe);
*pe = '\0';
}
te = stpcpy(te, s);
*te = '\0';
}
va_end(ap);
expandMacros(NULL, NULL, buf, sizeof(buf));
for (s = p = buf; *s; s++, p++) {
if (!(s > buf && s[-1] == ':'))
while (s[0] == '/' && s[1] == '/') s++;
*p = *s;
s = t = te = buf;
while (*s) {
/*fprintf(stderr, "*** got \"%.*s\"\trest \"%s\"\n", (t-buf), buf, s); */
switch(*s) {
case ':': /* handle url's */
if (s[1] == '/' && s[2] == '/') {
*t++ = *s++;
*t++ = *s++;
}
break;
case '/':
/* Move parent dir forward */
for (se = te + 1; se < t && *se != '/'; se++)
;
if (se < t && *se == '/') {
te = se;
/*fprintf(stderr, "*** next pdir \"%.*s\"\n", (te-buf), buf); */
}
while (s[1] == '/')
s++;
while (t > buf && t[-1] == '/')
t--;
break;
case '.':
/* Leading .. is special */
if (t == buf && s[1] == '.') {
*t++ = *s++;
break;
}
/* Single . is special */
if (t == buf && s[1] == '\0') {
break;
}
/* Trim leading ./ , embedded ./ , trailing /. */
if ((t == buf || t[-1] == '/') && (s[1] == '/' || s[1] == '\0')) {
/*fprintf(stderr, "*** Trim leading ./ , embedded ./ , trailing /.\n"); */
s++;
continue;
}
/* Trim embedded /../ and trailing /.. */
if (t > buf && t[-1] == '/' && s[1] == '.' && (s[2] == '/' || s[2] == '\0')) {
t = te;
/* Move parent dir forward */
if (te > buf)
for (--te; te > buf && *te != '/'; te--)
;
/*fprintf(stderr, "*** prev pdir \"%.*s\"\n", (te-buf), buf); */
s++;
s++;
continue;
}
break;
default:
break;
}
*t++ = *s++;
}
*p = '\0';
/* Trim trailing / (but leave single / alone) */
if (t > &buf[1] && t[-1] == '/')
t--;
*t = '\0';
return xstrdup(buf);
}
/* Merge 3 args into path, any or all of which may be a url. */
const char * rpmGenPath(const char * urlroot, const char * urlmdir,
const char *urlfile)
{
@ -1510,23 +1561,34 @@ const char * rpmGenPath(const char * urlroot, const char * urlmdir,
const char * result;
const char * url = NULL;
int nurl = 0;
int ut;
(void) urlPath(xroot, &root);
if (url == NULL && *root != '\0') {
if (_debug)
fprintf(stderr, "*** RGP xroot %s xmdir %s xfile %s\n", xroot, xmdir, xfile);
ut = urlPath(xroot, &root);
if (url == NULL && ut > URL_IS_DASH) {
url = xroot;
nurl = root - xroot;
if (_debug)
fprintf(stderr, "*** RGP ut %d root %s nurl %d\n", ut, root, nurl);
}
if (root == NULL || *root == '\0') root = "/";
(void) urlPath(xmdir, &mdir);
if (url == NULL && *mdir != '\0') {
ut = urlPath(xmdir, &mdir);
if (url == NULL && ut > URL_IS_DASH) {
url = xmdir;
nurl = mdir - xmdir;
if (_debug)
fprintf(stderr, "*** RGP ut %d mdir %s nurl %d\n", ut, mdir, nurl);
}
if (mdir == NULL || *mdir == '\0') mdir = "/";
(void) urlPath(xfile, &file);
if (url == NULL && *file != '\0') {
ut = urlPath(xfile, &file);
if (url == NULL && ut > URL_IS_DASH) {
url = xfile;
nurl = file - xfile;
if (_debug)
fprintf(stderr, "*** RGP ut %d file %s nurl %d\n", ut, file, nurl);
}
if (url && nurl > 0) {
@ -1536,11 +1598,13 @@ const char * rpmGenPath(const char * urlroot, const char * urlmdir,
} else
url = "";
result = rpmGetPath(url, root, mdir, file, NULL);
result = rpmGetPath(url, root, "/", mdir, "/", file, NULL);
xfree(xroot);
xfree(xmdir);
xfree(xfile);
if (_debug)
fprintf(stderr, "*** RGP result %s\n", result);
return result;
}