lib/macro.c: Canonicalize paths in rpmGetPath().
authorjbj <devnull@localhost>
Wed, 24 Nov 1999 00:03:54 +0000 (00:03 +0000)
committerjbj <devnull@localhost>
Wed, 24 Nov 1999 00:03:54 +0000 (00:03 +0000)
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

18 files changed:
build.c
build/build.c
build/files.c
build/myftw.c
build/parsePreamble.c
build/parsePrep.c
build/parseSpec.c
build/rpmspec.h
build/spec.c
lib/cpio.c
lib/macro.c
lib/misc.c
lib/rpmio.h
lib/rpmurl.h
lib/url.c
macros.in
po/rpm.pot
rpmio/macro.c

diff --git a/build.c b/build.c
index 4eb6266..95f9cf1 100644 (file)
--- a/build.c
+++ b/build.c
@@ -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,
index 48d273c..22ee3fa 100644 (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;
 }
index 0442110..8d9d2b9 100644 (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);
index 971061f..0271bbf 100644 (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;
        }
     }
index d4b1818..e40d29c 100644 (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;
-
-       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;
     }
index 8987082..1c044d0 100644 (file)
            { 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 */
index 36201a7..f914ffe 100644 (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);
index c87e158..bc850ff 100644 (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;
index 613f998..4a4a611 100644 (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);
index 7d0a3a9..48b22fc 100644 (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)
index ea71b43..bf8a5a4 100644 (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;
 }
 
index 5a22f20..5aa16c7 100644 (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;
 }
 
index ddb5289..13e7e36 100644 (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);
index f3e7708..5508453 100644 (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 */
index 85950d5..361d168 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -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;
     }
 
index 6384011..37ddfeb 100644 (file)
--- a/macros.in
+++ b/macros.in
@@ -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}}\"\
index f918f79..04cbeaf 100644 (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 ""
index ea71b43..bf8a5a4 100644 (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;
 }