From a40980339b13e3b506c2317b5b4864127039eb2c Mon Sep 17 00:00:00 2001 From: mp Date: Sun, 11 Mar 2007 22:33:41 +0000 Subject: Import of tcsh-6.15.00 --- contrib/tcsh/sh.dir.c | 626 +++++++++++++++++++++++++------------------------- 1 file changed, 313 insertions(+), 313 deletions(-) (limited to 'contrib/tcsh/sh.dir.c') diff --git a/contrib/tcsh/sh.dir.c b/contrib/tcsh/sh.dir.c index fdd85b7..3fd8d70 100644 --- a/contrib/tcsh/sh.dir.c +++ b/contrib/tcsh/sh.dir.c @@ -1,4 +1,4 @@ -/* $Header: /src/pub/tcsh/sh.dir.c,v 3.66 2005/03/03 16:40:53 kim Exp $ */ +/* $Header: /p/tcsh/cvsroot/tcsh/sh.dir.c,v 3.79 2006/09/25 18:17:26 christos Exp $ */ /* * sh.dir.c: Directory manipulation functions */ @@ -33,32 +33,62 @@ #include "sh.h" #include "ed.h" -RCSID("$Id: sh.dir.c,v 3.66 2005/03/03 16:40:53 kim Exp $") +RCSID("$tcsh: sh.dir.c,v 3.79 2006/09/25 18:17:26 christos Exp $") /* * C Shell - directory management */ -static void dstart __P((const char *)); -static struct directory *dfind __P((Char *)); -static Char *dfollow __P((Char *)); -static void printdirs __P((int)); -static Char *dgoto __P((Char *)); -static void dnewcwd __P((struct directory *, int)); -static void dset __P((Char *)); -static void dextract __P((struct directory *)); -static int skipargs __P((Char ***, const char *, - const char *)); -static void dgetstack __P((void)); +static Char *agetcwd (void); +static void dstart (const char *); +static struct directory *dfind (Char *); +static Char *dfollow (Char *); +static void printdirs (int); +static Char *dgoto (Char *); +static void dnewcwd (struct directory *, int); +static void dset (Char *); +static void dextract (struct directory *); +static int skipargs (Char ***, const char *, + const char *); +static void dgetstack (void); static struct directory dhead INIT_ZERO_STRUCT; /* "head" of loop */ static int printd; /* force name to be printed */ int bequiet = 0; /* do not print dir stack -strike */ +static Char * +agetcwd(void) +{ + char *buf; + Char *cwd; + size_t len; + + len = MAXPATHLEN; + buf = xmalloc(len); + while (getcwd(buf, len) == NULL) { + int err; + + err = errno; + if (err != ERANGE) { + xfree(buf); + errno = err; + return NULL; + } + len *= 2; + buf = xrealloc(buf, len); + } + if (*buf == '\0') { + xfree(buf); + return NULL; + } + cwd = SAVE(buf); + xfree(buf); + return cwd; +} + static void -dstart(from) - const char *from; +dstart(const char *from) { xprintf(CGETS(12, 1, "%s: Trying to start from \"%s\"\n"), progname, from); } @@ -67,22 +97,19 @@ dstart(from) * dinit - initialize current working directory */ void -dinit(hp) - Char *hp; +dinit(Char *hp) { - char *tcp; - Char *cp; + Char *cp, *tcp; struct directory *dp; - char path[MAXPATHLEN]; /* Don't believe the login shell home, because it may be a symlink */ - tcp = (char *) getcwd(path, sizeof(path)); - if (tcp == NULL || *tcp == '\0') { + tcp = agetcwd(); + if (tcp == NULL) { xprintf("%s: %s\n", progname, strerror(errno)); if (hp && *hp) { - tcp = short2str(hp); - dstart(tcp); - if (chdir(tcp) == -1) + char *xcp = short2str(hp); + dstart(xcp); + if (chdir(xcp) == -1) cp = NULL; else cp = Strsave(hp); @@ -100,12 +127,13 @@ dinit(hp) else { #ifdef S_IFLNK struct stat swd, shp; + int swd_ok; + swd_ok = stat(short2str(tcp), &swd) == 0; /* * See if $HOME is the working directory we got and use that */ - if (hp && *hp && - stat(tcp, &swd) != -1 && stat(short2str(hp), &shp) != -1 && + if (swd_ok && hp && *hp && stat(short2str(hp), &shp) != -1 && DEV_DEV_COMPARE(swd.st_dev, shp.st_dev) && swd.st_ino == shp.st_ino) cp = Strsave(hp); @@ -115,40 +143,46 @@ dinit(hp) /* * use PWD if we have it (for subshells) */ - if ((cwd = getenv("PWD")) != NULL) { - if (stat(cwd, &shp) != -1 && + if (swd_ok && (cwd = getenv("PWD")) != NULL) { + if (stat(cwd, &shp) != -1 && DEV_DEV_COMPARE(swd.st_dev, shp.st_dev) && - swd.st_ino == shp.st_ino) - tcp = cwd; + swd.st_ino == shp.st_ino) { + tcp = SAVE(cwd); + cleanup_push(tcp, xfree); + } } - cp = dcanon(SAVE(tcp), STRNULL); + cleanup_push(tcp, xfree); + cp = dcanon(tcp, STRNULL); + cleanup_ignore(tcp); + cleanup_until(tcp); } #else /* S_IFLNK */ - cp = dcanon(SAVE(tcp), STRNULL); + cleanup_push(tcp, xfree); + cp = dcanon(tcp, STRNULL); + cleanup_ignore(tcp); + cleanup_until(tcp); #endif /* S_IFLNK */ } - dp = (struct directory *) xcalloc(sizeof(struct directory), 1); + dp = xcalloc(sizeof(struct directory), 1); dp->di_name = cp; dp->di_count = 0; dhead.di_next = dhead.di_prev = dp; dp->di_next = dp->di_prev = &dhead; printd = 0; dnewcwd(dp, 0); - set(STRdirstack, Strsave(dp->di_name), VAR_READWRITE|VAR_NOGLOB); + setcopy(STRdirstack, dp->di_name, VAR_READWRITE|VAR_NOGLOB); } static void -dset(dp) -Char *dp; +dset(Char *dp) { /* * Don't call set() directly cause if the directory contains ` or * other junk characters glob will fail. */ - set(STRowd, Strsave(varval(STRcwd)), VAR_READWRITE|VAR_NOGLOB); - set(STRcwd, Strsave(dp), VAR_READWRITE|VAR_NOGLOB); - + setcopy(STRowd, varval(STRcwd), VAR_READWRITE|VAR_NOGLOB); + setcopy(STRcwd, dp, VAR_READWRITE|VAR_NOGLOB); tsetenv(STRPWD, dp); } @@ -162,10 +196,7 @@ Char *dp; #define DIR_OLD 0x80 /* - */ static int -skipargs(v, dstr, str) - Char ***v; - const char *dstr; - const char *str; +skipargs(Char ***v, const char *dstr, const char *str) { Char **n = *v, *s; @@ -175,15 +206,12 @@ skipargs(v, dstr, str) dflag |= DIR_OLD; else { char *p; - while (loop && *s != '\0') /* examine flags */ + while (*s != '\0') /* examine flags */ { if ((p = strchr(dstr, *s++)) != NULL) dflag |= (1 << (p - dstr)); - else { + else stderror(ERR_DIRUS, short2str(**v), dstr, str); - loop = 0; /* break from both loops */ - break; - } } } if (*n && (dflag & DIR_OLD)) @@ -200,11 +228,9 @@ skipargs(v, dstr, str) */ /*ARGSUSED*/ void -dodirs(v, c) - Char **v; - struct command *c; +dodirs(Char **v, struct command *c) { - static char flags[] = "plvnSLc"; + static const char flags[] = "plvnSLc"; int dflag = skipargs(&v, flags, ""); USE(c); @@ -234,8 +260,7 @@ dodirs(v, c) } static void -printdirs(dflag) - int dflag; +printdirs(int dflag) { struct directory *dp; Char *s, *user; @@ -259,7 +284,7 @@ printdirs(dflag) len = (int) (Strlen(s) + 1); cur += len; - if ((dflag & DIR_LINE) && cur >= T_Cols - 1 && len < T_Cols) { + if ((dflag & DIR_LINE) && cur >= TermH - 1 && len < TermH) { xputchar('\n'); cur = len; } @@ -272,8 +297,7 @@ printdirs(dflag) } void -dtildepr(dir) - Char *dir; +dtildepr(Char *dir) { Char* user; if ((user = getusername(&dir)) != NULL) @@ -283,7 +307,7 @@ dtildepr(dir) } void -dtilde() +dtilde(void) { struct directory *d = dcwd; @@ -307,9 +331,7 @@ dtilde() * Otherwise, a copy is made and sent back. */ Char * -dnormalize(cp, expnd) - Char *cp; - int expnd; +dnormalize(const Char *cp, int expnd) { /* return true if dp is of the form "../xxx" or "/../xxx" */ @@ -318,34 +340,44 @@ dnormalize(cp, expnd) #ifdef S_IFLNK if (expnd) { + struct Strbuf buf = Strbuf_INIT; int dotdot = 0; - Char *dp, *cwd, *start = cp, buf[MAXPATHLEN]; - struct stat sb; -# ifdef apollo + Char *dp, *cwd; + const Char *start = cp; +# ifdef HAVE_SLASHSLASH int slashslash; -# endif /* apollo */ +# endif /* HAVE_SLASHSLASH */ /* * count the number of "../xxx" or "xxx/../xxx" in the path */ - for (dp=start; *dp && *(dp+1); dp++) - if (IS_DOTDOT(start, dp)) + for ( ; *cp && *(cp + 1); cp++) + if (IS_DOTDOT(start, cp)) dotdot++; + /* * if none, we are done. */ if (dotdot == 0) - return (Strsave(cp)); - + return (Strsave(start)); + +# ifdef notdef + struct stat sb; /* + * We disable this test because: + * cd /tmp; mkdir dir1 dir2; cd dir2; ln -s /tmp/dir1; cd dir1; + * echo ../../dir1 does not expand. We had enabled this before + * because it was bothering people with expansions in compilation + * lines like -I../../foo. Maybe we need some kind of finer grain + * control? + * * If the path doesn't exist, we are done too. */ - if (lstat(short2str(cp), &sb) != 0 && errno == ENOENT) - return (Strsave(cp)); - + if (lstat(short2str(start), &sb) != 0 && errno == ENOENT) + return (Strsave(start)); +# endif - cwd = (Char *) xmalloc((size_t) (((int) Strlen(dcwd->di_name) + 3) * - sizeof(Char))); + cwd = xmalloc((Strlen(dcwd->di_name) + 3) * sizeof(Char)); (void) Strcpy(cwd, dcwd->di_name); /* @@ -354,24 +386,24 @@ dnormalize(cp, expnd) */ if (ABSOLUTEP(start)) *cwd = '\0'; -# ifdef apollo +# ifdef HAVE_SLASHSLASH slashslash = cwd[0] == '/' && cwd[1] == '/'; -# endif /* apollo */ +# endif /* HAVE_SLASHSLASH */ /* * Ignore . and count ..'s */ - for (;;) { + cp = start; + do { dotdot = 0; - buf[0] = '\0'; - dp = buf; + buf.len = 0; while (*cp) if (IS_DOT(start, cp)) { if (*++cp) cp++; } else if (IS_DOTDOT(start, cp)) { - if (buf[0]) + if (buf.len != 0) break; /* finish analyzing .././../xxx/[..] */ dotdot++; cp += 2; @@ -379,15 +411,15 @@ dnormalize(cp, expnd) cp++; } else - *dp++ = *cp++; + Strbuf_append1(&buf, *cp++); - *dp = '\0'; + Strbuf_terminate(&buf); while (dotdot > 0) if ((dp = Strrchr(cwd, '/')) != NULL) { -# ifdef apollo +# ifdef HAVE_SLASHSLASH if (dp == &cwd[1]) slashslash = 1; -# endif /* apollo */ +# endif /* HAVE_SLASHSLASH */ *dp = '\0'; dotdot--; } @@ -396,29 +428,38 @@ dnormalize(cp, expnd) if (!*cwd) { /* too many ..'s, starts with "/" */ cwd[0] = '/'; -# ifdef apollo - cwd[1] = '/'; +# ifdef HAVE_SLASHSLASH + /* + * Only append another slash, if already the former cwd + * was in a double-slash path. + */ + cwd[1] = slashslash ? '/' : '\0'; cwd[2] = '\0'; -# else /* !apollo */ +# else /* !HAVE_SLASHSLASH */ cwd[1] = '\0'; -# endif /* apollo */ +# endif /* HAVE_SLASHSLASH */ } -# ifdef apollo +# ifdef HAVE_SLASHSLASH else if (slashslash && cwd[1] == '\0') { cwd[1] = '/'; cwd[2] = '\0'; } -# endif /* apollo */ - - if (buf[0]) { - if ((TRM(cwd[(dotdot = (int) Strlen(cwd)) - 1])) != '/') - cwd[dotdot++] = '/'; - cwd[dotdot] = '\0'; - dp = Strspl(cwd, TRM(buf[0]) == '/' ? &buf[1] : buf); - xfree((ptr_t) cwd); +# endif /* HAVE_SLASHSLASH */ + + if (buf.len != 0) { + size_t i; + + i = Strlen(cwd); + if (TRM(cwd[i - 1]) != '/') { + cwd[i++] = '/'; + cwd[i] = '\0'; + } + dp = Strspl(cwd, TRM(buf.s[0]) == '/' ? &buf.s[1] : buf.s); + xfree(cwd); cwd = dp; - if ((TRM(cwd[(dotdot = (int) Strlen(cwd)) - 1])) == '/') - cwd[--dotdot] = '\0'; + i = Strlen(cwd) - 1; + if (TRM(cwd[i]) == '/') + cwd[i] = '\0'; } /* Reduction of ".." following the stuff we collected in buf * only makes sense if the directory item in buf really exists. @@ -428,13 +469,13 @@ dnormalize(cp, expnd) if (cwd[0]) { struct stat exists; if (0 != stat(short2str(cwd), &exists)) { - xfree((ptr_t) cwd); + xfree(buf.s); + xfree(cwd); return Strsave(start); } } - if (!*cp) - break; - } + } while (*cp != '\0'); + xfree(buf.s); return cwd; } #endif /* S_IFLNK */ @@ -447,9 +488,7 @@ dnormalize(cp, expnd) */ /*ARGSUSED*/ void -dochngd(v, c) - Char **v; - struct command *c; +dochngd(Char **v, struct command *c) { Char *cp; struct directory *dp; @@ -486,7 +525,7 @@ dochngd(v, c) else if ((cp = dfollow(cp)) == NULL) return; - dp = (struct directory *) xcalloc(sizeof(struct directory), 1); + dp = xcalloc(sizeof(struct directory), 1); dp->di_name = cp; dp->di_count = 0; dp->di_next = dcwd->di_next; @@ -498,32 +537,27 @@ dochngd(v, c) } static Char * -dgoto(cp) - Char *cp; +dgoto(Char *cp) { - Char *dp; + Char *dp, *ret; if (!ABSOLUTEP(cp)) { Char *p, *q; - int cwdlen; + size_t cwdlen; - for (p = dcwd->di_name; *p++;) - continue; - if ((cwdlen = (int) (p - dcwd->di_name - 1)) == 1) /* root */ + cwdlen = Strlen(dcwd->di_name); + if (cwdlen == 1) /* root */ cwdlen = 0; - for (p = cp; *p++;) - continue; - dp = (Char *) xmalloc((size_t)((cwdlen + (p - cp) + 1) * sizeof(Char))); + dp = xmalloc((cwdlen + Strlen(cp) + 2) * sizeof(Char)); for (p = dp, q = dcwd->di_name; (*p++ = *q++) != '\0';) continue; if (cwdlen) p[-1] = '/'; else p--; /* don't add a / after root */ - for (q = cp; (*p++ = *q++) != '\0';) - continue; - xfree((ptr_t) cp); + Strcpy(p, cp); + xfree(cp); cp = dp; dp += cwdlen; } @@ -531,114 +565,127 @@ dgoto(cp) dp = cp; #if defined(WINNT_NATIVE) - cp = SAVE(getcwd(NULL, 0)); + return agetcwd(); #elif defined(__CYGWIN__) - if (ABSOLUTEP(cp) && cp[1] == ':') /* Only DOS paths are treated that way */ - cp = SAVE(getcwd(NULL, 0)); - else - cp = dcanon(cp, dp); + if (ABSOLUTEP(cp) && cp[1] == ':') { /* Only DOS paths are treated that way */ + return agetcwd(); + } else { + cleanup_push(cp, xfree); + ret = dcanon(cp, dp); + cleanup_ignore(cp); + cleanup_until(cp); + } #else /* !WINNT_NATIVE */ - cp = dcanon(cp, dp); + cleanup_push(cp, xfree); + ret = dcanon(cp, dp); + cleanup_ignore(cp); + cleanup_until(cp); #endif /* WINNT_NATIVE */ - return cp; + return ret; } /* * dfollow - change to arg directory; fall back on cdpath if not valid */ static Char * -dfollow(cp) - Char *cp; +dfollow(Char *cp) { Char *dp; struct varent *c; - char ebuf[MAXPATHLEN]; int serrno; cp = globone(cp, G_ERROR); + cleanup_push(cp, xfree); #ifdef apollo if (Strchr(cp, '`')) { - char *dptr, *ptr; + char *dptr; if (chdir(dptr = short2str(cp)) < 0) stderror(ERR_SYSTEM, dptr, strerror(errno)); - else if ((ptr = getcwd(ebuf, sizeof(ebuf))) && *ptr != '\0') { - xfree((ptr_t) cp); - cp = Strsave(str2short(ptr)); - return dgoto(cp); + dp = agetcwd(); + cleanup_push(dp, xfree); + if (dp != NULL) { + cleanup_until(cp); + return dgoto(dp); } - else - stderror(ERR_SYSTEM, dptr, ebuf); + else + stderror(ERR_SYSTEM, dptr, strerror(errno)); } #endif /* apollo */ - - (void) strncpy(ebuf, short2str(cp), MAXPATHLEN); - ebuf[MAXPATHLEN-1] = '\0'; + /* * if we are ignoring symlinks, try to fix relatives now. * if we are expading symlinks, it should be done by now. */ dp = dnormalize(cp, symlinks == SYM_IGNORE); if (chdir(short2str(dp)) >= 0) { - xfree((ptr_t) cp); + cleanup_until(cp); return dgoto(dp); } else { - xfree((ptr_t) dp); - if (chdir(short2str(cp)) >= 0) + xfree(dp); + if (chdir(short2str(cp)) >= 0) { + cleanup_ignore(cp); + cleanup_until(cp); return dgoto(cp); - else if (errno != ENOENT && errno != ENOTDIR) - stderror(ERR_SYSTEM, ebuf, strerror(errno)); + } + else if (errno != ENOENT && errno != ENOTDIR) { + int err; + + err = errno; + stderror(ERR_SYSTEM, short2str(cp), strerror(err)); + } serrno = errno; } if (cp[0] != '/' && !prefix(STRdotsl, cp) && !prefix(STRdotdotsl, cp) && (c = adrof(STRcdpath)) && c->vec != NULL) { + struct Strbuf buf = Strbuf_INIT; Char **cdp; - Char *p; - Char buf[MAXPATHLEN]; for (cdp = c->vec; *cdp; cdp++) { - for (dp = buf, p = *cdp; (*dp++ = *p++) != '\0';) - continue; - dp[-1] = '/'; - for (p = cp; (*dp++ = *p++) != '\0';) - continue; + buf.len = 0; + Strbuf_append(&buf, *cdp); + Strbuf_append1(&buf, '/'); + Strbuf_append(&buf, cp); + Strbuf_terminate(&buf); /* * We always want to fix the directory here * If we are normalizing symlinks */ - dp = dnormalize(buf, symlinks == SYM_IGNORE || - symlinks == SYM_EXPAND); + dp = dnormalize(buf.s, symlinks == SYM_IGNORE || + symlinks == SYM_EXPAND); if (chdir(short2str(dp)) >= 0) { printd = 1; - xfree((ptr_t) cp); + xfree(buf.s); + cleanup_until(cp); return dgoto(dp); } else if (chdir(short2str(cp)) >= 0) { printd = 1; - xfree((ptr_t) dp); + xfree(dp); + xfree(buf.s); + cleanup_ignore(cp); + cleanup_until(cp); return dgoto(cp); } } + xfree(buf.s); } dp = varval(cp); if ((dp[0] == '/' || dp[0] == '.') && chdir(short2str(dp)) >= 0) { - xfree((ptr_t) cp); + cleanup_until(cp); cp = Strsave(dp); printd = 1; return dgoto(cp); } - xfree((ptr_t) cp); /* * on login source of ~/.cshdirs, errors are eaten. the dir stack is all * directories we could get to. */ - if (!bequiet) { - stderror(ERR_SYSTEM, ebuf, strerror(serrno)); - return (NULL); - } - else - return (NULL); + if (!bequiet) + stderror(ERR_SYSTEM, short2str(cp), strerror(serrno)); + cleanup_until(cp); + return (NULL); } @@ -649,9 +696,7 @@ dfollow(cp) */ /*ARGSUSED*/ void -dopushd(v, c) - Char **v; - struct command *c; +dopushd(Char **v, struct command *c) { struct directory *dp; Char *cp; @@ -667,10 +712,9 @@ dopushd(v, c) stderror(ERR_NAME | ERR_NOHOMEDIR); if (chdir(short2str(cp)) < 0) stderror(ERR_NAME | ERR_CANTCHANGE); - cp = Strsave(cp); /* hmmm... PWP */ if ((cp = dfollow(cp)) == NULL) return; - dp = (struct directory *) xcalloc(sizeof(struct directory), 1); + dp = xcalloc(sizeof(struct directory), 1); dp->di_name = cp; dp->di_count = 0; dp->di_prev = dcwd; @@ -716,7 +760,7 @@ dopushd(v, c) if ((ccp = dfollow(cp)) == NULL) return; - dp = (struct directory *) xcalloc(sizeof(struct directory), 1); + dp = xcalloc(sizeof(struct directory), 1); dp->di_name = ccp; dp->di_count = 0; dp->di_prev = dcwd; @@ -731,8 +775,7 @@ dopushd(v, c) * dfind - find a directory if specified by numeric (+n) argument */ static struct directory * -dfind(cp) - Char *cp; +dfind(Char *cp) { struct directory *dp; int i; @@ -762,9 +805,7 @@ dfind(cp) */ /*ARGSUSED*/ void -dopopd(v, c) - Char **v; - struct command *c; +dopopd(Char **v, struct command *c) { Char *cp; struct directory *dp, *p = NULL; @@ -795,29 +836,28 @@ dopopd(v, c) } dp->di_prev->di_next = dp->di_next; dp->di_next->di_prev = dp->di_prev; + dfree(dp); if (dp == dcwd) { - dnewcwd(p, dflag); + dnewcwd(p, dflag); } else { printdirs(dflag); } - dfree(dp); } /* * dfree - free the directory (or keep it if it still has ref count) */ void -dfree(dp) - struct directory *dp; +dfree(struct directory *dp) { if (dp->di_count != 0) { dp->di_next = dp->di_prev = 0; } else { - xfree((ptr_t) dp->di_name); - xfree((ptr_t) dp); + xfree(dp->di_name); + xfree(dp); } } @@ -827,29 +867,23 @@ dfree(dp) * constructed (always have ..'s, directories have links) */ Char * -dcanon(cp, p) - Char *cp, *p; +dcanon(Char *cp, Char *p) { Char *sp; Char *p1, *p2; /* general purpose */ int slash; -#ifdef apollo +#ifdef HAVE_SLASHSLASH int slashslash; -#endif /* apollo */ +#endif /* HAVE_SLASHSLASH */ size_t clen; #ifdef S_IFLNK /* if we have symlinks */ - Char mlink[MAXPATHLEN]; - char tlink[MAXPATHLEN]; - int cc; - Char *newcp; + Char *mlink, *newcp; + char *tlink; + size_t cc; #endif /* S_IFLNK */ - /* - * if the path given is too long truncate it! - */ - if ((clen = Strlen(cp)) >= MAXPATHLEN) - cp[clen = MAXPATHLEN - 1] = '\0'; + clen = Strlen(cp); /* * christos: if the path given does not start with a slash prepend cwd. If @@ -857,33 +891,33 @@ dcanon(cp, p) * correct it. */ if (!ABSOLUTEP(cp)) { - Char tmpdir[MAXPATHLEN]; + Char *tmpdir; size_t len; p1 = varval(STRcwd); if (p1 == STRNULL || !ABSOLUTEP(p1)) { - char *tmp = (char *)getcwd((char *)tmpdir, sizeof(tmpdir)); - if (tmp == NULL || *tmp == '\0') { + Char *new_cwd = agetcwd(); + + if (new_cwd == NULL) { xprintf("%s: %s\n", progname, strerror(errno)); - set(STRcwd, SAVE("/"), VAR_READWRITE|VAR_NOGLOB); - } else { - set(STRcwd, SAVE(tmp), VAR_READWRITE|VAR_NOGLOB); + setcopy(STRcwd, str2short("/"), VAR_READWRITE|VAR_NOGLOB); } + else + setv(STRcwd, new_cwd, VAR_READWRITE|VAR_NOGLOB); p1 = varval(STRcwd); } len = Strlen(p1); - if (len + clen + 1 >= MAXPATHLEN) - cp[MAXPATHLEN - (len + 1)] = '\0'; + tmpdir = xmalloc((len + clen + 2) * sizeof (*tmpdir)); (void) Strcpy(tmpdir, p1); (void) Strcat(tmpdir, STRslash); (void) Strcat(tmpdir, cp); - xfree((ptr_t) cp); - cp = p = Strsave(tmpdir); + xfree(cp); + cp = p = tmpdir; } -#ifdef apollo +#ifdef HAVE_SLASHSLASH slashslash = (cp[0] == '/' && cp[1] == '/'); -#endif /* apollo */ +#endif /* HAVE_SLASHSLASH */ while (*p) { /* for each component */ sp = p; /* save slash address */ @@ -902,10 +936,10 @@ dcanon(cp, p) break; } -#ifdef apollo +#ifdef HAVE_SLASHSLASH if (&cp[1] == sp && sp[0] == '.' && sp[1] == '.' && sp[2] == '\0') slashslash = 1; -#endif /* apollo */ +#endif /* HAVE_SLASHSLASH */ if (*sp == '\0') { /* if component is null */ if (--sp == cp) /* if path is one char (i.e. /) */ break; @@ -933,12 +967,9 @@ dcanon(cp, p) *--sp = 0; /* form the pathname for readlink */ #ifdef S_IFLNK /* if we have symlinks */ if (sp != cp && /* symlinks != SYM_IGNORE && */ - (cc = readlink(short2str(cp), tlink, - sizeof(tlink) - 1)) >= 0) { - tlink[cc] = '\0'; - (void) Strncpy(mlink, str2short(tlink), - sizeof(mlink) / sizeof(Char)); - mlink[sizeof(mlink) / sizeof(Char) - 1] = '\0'; + (tlink = areadlink(short2str(cp))) != NULL) { + mlink = str2short(tlink); + xfree(tlink); if (slash) *p = '/'; @@ -946,11 +977,6 @@ dcanon(cp, p) * Point p to the '/' in "/..", and restore the '/'. */ *(p = sp) = '/'; - /* - * find length of p - */ - for (p1 = p; *p1++;) - continue; if (*mlink != '/') { /* * Relative path, expand it between the "yyy/" and the @@ -963,9 +989,8 @@ dcanon(cp, p) /* * New length is "yyy/" + mlink + "/.." and rest */ - p1 = newcp = (Char *) xmalloc((size_t) - (((sp - cp) + cc + (p1 - p)) * - sizeof(Char))); + p1 = newcp = xmalloc(((sp - cp) + Strlen(mlink) + + Strlen(p) + 1) * sizeof(Char)); /* * Copy new path into newcp */ @@ -981,28 +1006,17 @@ dcanon(cp, p) p = sp - cp - 1 + newcp; } else { - /* - * New length is mlink + "/.." and rest - */ - p1 = newcp = (Char *) xmalloc((size_t) - ((cc + (p1 - p)) * sizeof(Char))); - /* - * Copy new path into newcp - */ - for (p2 = mlink; (*p1++ = *p2++) != '\0';) - continue; - for (p1--, p2 = p; (*p1++ = *p2++) != '\0';) - continue; + newcp = Strspl(mlink, p); /* * Restart canonicalization at beginning */ p = newcp; } - xfree((ptr_t) cp); + xfree(cp); cp = newcp; -#ifdef apollo +#ifdef HAVE_SLASHSLASH slashslash = (cp[0] == '/' && cp[1] == '/'); -#endif /* apollo */ +#endif /* HAVE_SLASHSLASH */ continue; /* canonicalize the link */ } #endif /* S_IFLNK */ @@ -1024,12 +1038,9 @@ dcanon(cp, p) #ifdef S_IFLNK /* if we have symlinks */ if (sp != cp && symlinks == SYM_CHASE && - (cc = readlink(short2str(cp), tlink, - sizeof(tlink) - 1)) >= 0) { - tlink[cc] = '\0'; - (void) Strncpy(mlink, str2short(tlink), - sizeof(mlink) / sizeof(Char)); - mlink[sizeof(mlink) / sizeof(Char) - 1] = '\0'; + (tlink = areadlink(short2str(cp))) != NULL) { + mlink = str2short(tlink); + xfree(tlink); /* * restore the '/'. @@ -1042,11 +1053,6 @@ dcanon(cp, p) */ sp = p; - /* - * find length of p - */ - for (p1 = p; *p1++;) - continue; if (*mlink != '/') { /* * Relative path, expand it between the "yyy/" and the @@ -1060,9 +1066,8 @@ dcanon(cp, p) /* * New length is "yyy/" + mlink + "/.." and rest */ - p1 = newcp = (Char *) xmalloc((size_t) - (((sp - cp) + cc + (p1 - p)) - * sizeof(Char))); + p1 = newcp = xmalloc(((sp - cp) + Strlen(mlink) + + Strlen(p) + 1) * sizeof(Char)); /* * Copy new path into newcp */ @@ -1078,28 +1083,17 @@ dcanon(cp, p) p = sp - cp - 1 + newcp; } else { - /* - * New length is mlink + the rest - */ - p1 = newcp = (Char *) xmalloc((size_t) - ((cc + (p1 - p)) * sizeof(Char))); - /* - * Copy new path into newcp - */ - for (p2 = mlink; (*p1++ = *p2++) != '\0';) - continue; - for (p1--, p2 = p; (*p1++ = *p2++) != '\0';) - continue; + newcp = Strspl(mlink, p); /* * Restart canonicalization at beginning */ p = newcp; } - xfree((ptr_t) cp); + xfree(cp); cp = newcp; -#ifdef apollo +#ifdef HAVE_SLASHSLASH slashslash = (cp[0] == '/' && cp[1] == '/'); -#endif /* apollo */ +#endif /* HAVE_SLASHSLASH */ continue; /* canonicalize the mlink */ } #endif /* S_IFLNK */ @@ -1113,17 +1107,18 @@ dcanon(cp, p) */ #ifdef S_IFLNK p1 = varval(STRhome); - cc = (int) Strlen(p1); + cc = Strlen(p1); /* * See if we're not in a subdir of STRhome */ - if (p1 && *p1 == '/' && (Strncmp(p1, cp, (size_t) cc) != 0 || + if (p1 && *p1 == '/' && (Strncmp(p1, cp, cc) != 0 || (cp[cc] != '/' && cp[cc] != '\0'))) { static ino_t home_ino = (ino_t) -1; static dev_t home_dev = (dev_t) -1; static Char *home_ptr = NULL; struct stat statbuf; int found; + Char *copy; /* * Get dev and ino of STRhome @@ -1137,8 +1132,7 @@ dcanon(cp, p) /* * Start comparing dev & ino backwards */ - p2 = Strncpy(mlink, cp, sizeof(mlink) / sizeof(Char)); - mlink[sizeof(mlink) / sizeof(Char) - 1] = '\0'; + p2 = copy = Strsave(cp); found = 0; while (*p2 && stat(short2str(p2), &statbuf) != -1) { if (DEV_DEV_COMPARE(statbuf.st_dev, home_dev) && @@ -1157,25 +1151,28 @@ dcanon(cp, p) * Use STRhome to make '~' work */ newcp = Strspl(p1, cp + Strlen(p2)); - xfree((ptr_t) cp); + xfree(cp); cp = newcp; } + xfree(copy); } #endif /* S_IFLNK */ -#ifdef apollo +#ifdef HAVE_SLASHSLASH if (slashslash) { if (cp[1] != '/') { - p = (Char *) xmalloc((size_t) (Strlen(cp) + 2) * sizeof(Char)); + p = xmalloc((Strlen(cp) + 2) * sizeof(Char)); *p = '/'; (void) Strcpy(&p[1], cp); - xfree((ptr_t) cp); + xfree(cp); cp = p; } } - if (cp[1] == '/' && cp[2] == '/') - (void) Strcpy(&cp[1], &cp[2]); -#endif /* apollo */ + if (cp[1] == '/' && cp[2] == '/') { + for (p1 = &cp[1], p2 = &cp[2]; (*p1++ = *p2++) != '\0';) + continue; + } +#endif /* HAVE_SLASHSLASH */ return cp; } @@ -1184,9 +1181,7 @@ dcanon(cp, p) * dnewcwd - make a new directory in the loop the current one */ static void -dnewcwd(dp, dflag) - struct directory *dp; - int dflag; +dnewcwd(struct directory *dp, int dflag) { int print; @@ -1217,7 +1212,7 @@ dnewcwd(dp, dflag) } void -dsetstack() +dsetstack(void) { Char **cp; struct varent *vp; @@ -1240,7 +1235,7 @@ dsetstack() /* put back the stack */ for (cp = vp->vec; cp && *cp && **cp; cp++) { - dp = (struct directory *) xcalloc(sizeof(struct directory), 1); + dp = xcalloc(sizeof(struct directory), 1); dp->di_name = Strsave(*cp); dp->di_count = 0; dp->di_prev = dcwd; @@ -1252,7 +1247,7 @@ dsetstack() } static void -dgetstack() +dgetstack(void) { int i = 0; Char **dblk, **dbp; @@ -1261,13 +1256,16 @@ dgetstack() if (adrof(STRdirstack) == NULL) return; - for (dn = dhead.di_prev; dn != &dhead; dn = dn->di_prev, i++) + for (dn = dhead.di_prev; dn != &dhead; dn = dn->di_prev, i++) continue; - dbp = dblk = (Char**) xmalloc((size_t) (i + 1) * sizeof(Char *)); - for (dn = dhead.di_prev; dn != &dhead; dn = dn->di_prev, dbp++) + dbp = dblk = xmalloc((i + 1) * sizeof(Char *)); + for (dn = dhead.di_prev; dn != &dhead; dn = dn->di_prev, dbp++) *dbp = Strsave(dn->di_name); *dbp = NULL; + cleanup_push(dblk, blk_cleanup); setq(STRdirstack, dblk, &shvhed, VAR_READWRITE); + cleanup_ignore(dblk); + cleanup_until(dblk); } /* @@ -1275,10 +1273,8 @@ dgetstack() * Support routine for the stack hack. Finds nth directory in * the directory stack, or finds last directory in stack. */ -int -getstakd(s, cnt) - Char *s; - int cnt; +const Char * +getstakd(int cnt) { struct directory *dp; @@ -1294,12 +1290,10 @@ getstakd(s, cnt) if (dp == &dhead) dp = dp->di_prev; if (dp == dcwd) - return (0); + return NULL; } } - (void) Strncpy(s, dp->di_name, BUFSIZE); - s[BUFSIZE - 1] = '\0'; - return (1); + return dp->di_name; } /* @@ -1310,8 +1304,7 @@ getstakd(s, cnt) * position, and pushes it onto the top. */ static void -dextract(dp) - struct directory *dp; +dextract(struct directory *dp) { if (dp == dcwd) return; @@ -1323,21 +1316,28 @@ dextract(dp) dcwd->di_next = dp; } +static void +bequiet_cleanup(void *dummy) +{ + USE(dummy); + bequiet = 0; +} + void -loaddirs(fname) - Char *fname; +loaddirs(Char *fname) { static Char *loaddirs_cmd[] = { STRsource, NULL, NULL }; bequiet = 1; - if (fname) + cleanup_push(&bequiet, bequiet_cleanup); + if (fname) loaddirs_cmd[1] = fname; else if ((fname = varval(STRdirsfile)) != STRNULL) loaddirs_cmd[1] = fname; else loaddirs_cmd[1] = STRtildotdirs; - dosource(loaddirs_cmd, (struct command *)0); - bequiet = 0; + dosource(loaddirs_cmd, NULL); + cleanup_until(&bequiet); } /* @@ -1348,16 +1348,14 @@ loaddirs(fname) * -strike */ void -recdirs(fname, def) - Char *fname; - int def; +recdirs(Char *fname, int def) { int fp, ftmp, oldidfds; int cdflag = 0; struct directory *dp; unsigned int num; Char *snum; - Char qname[MAXPATHLEN*2]; + struct Strbuf qname = Strbuf_INIT; if (fname == NULL && !def) return; @@ -1370,9 +1368,10 @@ recdirs(fname, def) } else fname = globone(fname, G_ERROR); - - if ((fp = creat(short2str(fname), 0600)) == -1) { - xfree((ptr_t) fname); + cleanup_push(fname, xfree); + + if ((fp = xcreat(short2str(fname), 0600)) == -1) { + cleanup_until(fname); return; } @@ -1386,6 +1385,7 @@ recdirs(fname, def) ftmp = SHOUT; SHOUT = fp; + cleanup_push(&qname, Strbuf_cleanup); dp = dcwd->di_next; do { if (dp == &dhead) @@ -1393,18 +1393,18 @@ recdirs(fname, def) if (cdflag == 0) { cdflag = 1; - xprintf("cd %S\n", quote_meta(qname, dp->di_name)); + xprintf("cd %S\n", quote_meta(&qname, dp->di_name)); } else - xprintf("pushd %S\n", quote_meta(qname, dp->di_name)); + xprintf("pushd %S\n", quote_meta(&qname, dp->di_name)); if (num-- == 0) break; } while ((dp = dp->di_next) != dcwd->di_next); - (void) close(fp); + xclose(fp); SHOUT = ftmp; didfds = oldidfds; - xfree((ptr_t) fname); + cleanup_until(fname); } -- cgit v1.1