summaryrefslogtreecommitdiffstats
path: root/contrib/tcsh/sh.dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tcsh/sh.dir.c')
-rw-r--r--contrib/tcsh/sh.dir.c626
1 files changed, 313 insertions, 313 deletions
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);
}
OpenPOWER on IntegriCloud