diff options
-rw-r--r-- | build.c | 97 | ||||
-rw-r--r-- | build/build.c | 115 | ||||
-rw-r--r-- | build/files.c | 201 | ||||
-rw-r--r-- | build/myftw.c | 20 | ||||
-rw-r--r-- | build/parsePreamble.c | 49 | ||||
-rw-r--r-- | build/parsePrep.c | 14 | ||||
-rw-r--r-- | build/parseSpec.c | 49 | ||||
-rw-r--r-- | build/rpmspec.h | 4 | ||||
-rw-r--r-- | build/spec.c | 6 | ||||
-rw-r--r-- | lib/cpio.c | 14 | ||||
-rw-r--r-- | lib/macro.c | 114 | ||||
-rw-r--r-- | lib/misc.c | 4 | ||||
-rw-r--r-- | lib/rpmio.h | 11 | ||||
-rw-r--r-- | lib/rpmurl.h | 1 | ||||
-rw-r--r-- | lib/url.c | 23 | ||||
-rw-r--r-- | macros.in | 5 | ||||
-rw-r--r-- | po/rpm.pot | 267 | ||||
-rw-r--r-- | rpmio/macro.c | 114 |
18 files changed, 667 insertions, 441 deletions
@@ -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, diff --git a/build/build.c b/build/build.c index 48d273c05..22ee3fae3 100644 --- a/build/build.c +++ b/build/build.c @@ -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; } diff --git a/build/files.c b/build/files.c index 04421104f..8d9d2b935 100644 --- a/build/files.c +++ b/build/files.c @@ -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); diff --git a/build/myftw.c b/build/myftw.c index 971061f33..0271bbf1d 100644 --- a/build/myftw.c +++ b/build/myftw.c @@ -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; } } diff --git a/build/parsePreamble.c b/build/parsePreamble.c index d4b181897..e40d29cde 100644 --- a/build/parsePreamble.c +++ b/build/parsePreamble.c @@ -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; - - if (buildURL == NULL) { - - buildURL = rpmGenPath(spec->rootURL, "%{?buildroot:%{buildroot}}", NULL); - - if (strcmp(spec->rootURL, buildURL)) { - spec->buildURL = buildURL; + const char * buildRootURL = spec->buildRootURL; + + /* + * 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; } diff --git a/build/parsePrep.c b/build/parsePrep.c index 8987082f6..1c044d049 100644 --- a/build/parsePrep.c +++ b/build/parsePrep.c @@ -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 */ diff --git a/build/parseSpec.c b/build/parseSpec.c index 36201a74b..f914ffee8 100644 --- a/build/parseSpec.c +++ b/build/parseSpec.c @@ -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); diff --git a/build/rpmspec.h b/build/rpmspec.h index c87e1582d..bc850ff0c 100644 --- a/build/rpmspec.h +++ b/build/rpmspec.h @@ -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; diff --git a/build/spec.c b/build/spec.c index 613f9984e..4a4a611ec 100644 --- a/build/spec.c +++ b/build/spec.c @@ -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); diff --git a/lib/cpio.c b/lib/cpio.c index 7d0a3a914..48b22fcdb 100644 --- a/lib/cpio.c +++ b/lib/cpio.c @@ -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) diff --git a/lib/macro.c b/lib/macro.c index ea71b43c1..bf8a5a412 100644 --- a/lib/macro.c +++ b/lib/macro.c @@ -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; } diff --git a/lib/misc.c b/lib/misc.c index 5a22f205b..5aa16c796 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -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; } diff --git a/lib/rpmio.h b/lib/rpmio.h index ddb5289fc..13e7e3686 100644 --- a/lib/rpmio.h +++ b/lib/rpmio.h @@ -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); diff --git a/lib/rpmurl.h b/lib/rpmurl.h index f3e7708ca..5508453aa 100644 --- a/lib/rpmurl.h +++ b/lib/rpmurl.h @@ -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 */ @@ -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; } @@ -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}}\"\ diff --git a/po/rpm.pot b/po/rpm.pot index f918f7981..04cbeaf6e 100644 --- a/po/rpm.pot +++ b/po/rpm.pot @@ -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 "" diff --git a/rpmio/macro.c b/rpmio/macro.c index ea71b43c1..bf8a5a412 100644 --- a/rpmio/macro.c +++ b/rpmio/macro.c @@ -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; } |