Exemple #1
0
/* Like getcwd(), except bsize is ignored if buf is 0 (PATH_MAX is used) */
char *
ksh_get_wd(char *buf, int bsize)
{
        char *b;
        char *ret;

        /* Note: we could just use plain getcwd(), but then we'd had to
         * inject possibly allocated space into the ATEMP area. */
        /* Assume getcwd() available */
        if (!buf) {
                bsize = MAXPATHLEN;
                b = alloc(MAXPATHLEN + 1, ATEMP);
        } else
                b = buf;

        ret = getcwd(b, bsize);

        if (!buf) {
                if (ret)
                        ret = aresize(b, strlen(b) + 1, ATEMP);
                else
                        afree(b, ATEMP);
        }

        return ret;
}
Exemple #2
0
/* called from expand.h:XcheckN() to grow buffer */
char *
Xcheck_grow_(XString *xsp, char *xp, int more)
{
        char *old_beg = xsp->beg;

        xsp->len += more > xsp->len ? more : xsp->len;
        xsp->beg = aresize(xsp->beg, xsp->len + 8, xsp->areap);
        xsp->end = xsp->beg + xsp->len;
        return xsp->beg + (xp - old_beg);
}
Exemple #3
0
/* called from XcheckN() to grow buffer */
char *
Xcheck_grow(XString *xsp, const char *xp, size_t more)
{
	const char *old_beg = xsp->beg;

	if (more < xsp->len)
		more = xsp->len;
	/* (xsp->len + X_EXTRA) never overflows */
	checkoktoadd(more, xsp->len + X_EXTRA);
	xsp->beg = aresize(xsp->beg, (xsp->len += more) + X_EXTRA, xsp->areap);
	xsp->end = xsp->beg + xsp->len;
	return (xsp->beg + (xp - old_beg));
}
Exemple #4
0
void
set_current_wd(char *path)
{
	int len;
	char *p = path;

	if (!p && !(p = ksh_get_wd((char *) 0, 0)))
		p = null;

	len = strlen(p) + 1;

	if (len > current_wd_size)
		current_wd = aresize(current_wd, current_wd_size = len, APERM);
	memcpy(current_wd, p, len);
	if (p != path && p != null)
		afree(p, ATEMP);
}
Exemple #5
0
/* Like getcwd(), except bsize is ignored if buf is 0 (PATH_MAX is used) */
char *
ksh_get_wd(size_t *dlen)
{
	char *ret, *b;
	size_t len = 1;

#ifdef NO_PATH_MAX
	if ((b = get_current_dir_name())) {
		len = strlen(b) + 1;
		strndupx(ret, b, len - 1, ATEMP);
		free(b);
	} else
		ret = NULL;
#else
	if ((ret = getcwd((b = alloc(PATH_MAX + 1, ATEMP)), PATH_MAX)))
		ret = aresize(b, len = (strlen(b) + 1), ATEMP);
	else
		afree(b, ATEMP);
#endif

	if (dlen)
		*dlen = len;
	return (ret);
}
Exemple #6
0
char *
do_realpath(const char *upath)
{
	char *xp, *ip, *tp, *ipath, *ldest = NULL;
	XString xs;
	size_t pos, len;
	int llen;
	struct stat sb;
#ifdef MKSH__NO_PATH_MAX
	size_t ldestlen = 0;
#define pathlen sb.st_size
#define pathcnd (ldestlen < (pathlen + 1))
#else
#define pathlen PATH_MAX
#define pathcnd (!ldest)
#endif
	/* max. recursion depth */
	int symlinks = 32;

	if (mksh_abspath(upath)) {
		/* upath is an absolute pathname */
		strdupx(ipath, upath, ATEMP);
	} else {
		/* upath is a relative pathname, prepend cwd */
		if ((tp = ksh_get_wd()) == NULL || !mksh_abspath(tp))
			return (NULL);
		ipath = shf_smprintf("%s%s%s", tp, "/", upath);
		afree(tp, ATEMP);
	}

	/* ipath and upath are in memory at the same time -> unchecked */
	Xinit(xs, xp, strlen(ip = ipath) + 1, ATEMP);

	/* now jump into the deep of the loop */
	goto beginning_of_a_pathname;

	while (*ip) {
		/* skip slashes in input */
		while (*ip == '/')
			++ip;
		if (!*ip)
			break;

		/* get next pathname component from input */
		tp = ip;
		while (*ip && *ip != '/')
			++ip;
		len = ip - tp;

		/* check input for "." and ".." */
		if (tp[0] == '.') {
			if (len == 1)
				/* just continue with the next one */
				continue;
			else if (len == 2 && tp[1] == '.') {
				/* strip off last pathname component */
				while (xp > Xstring(xs, xp))
					if (*--xp == '/')
						break;
				/* then continue with the next one */
				continue;
			}
		}

		/* store output position away, then append slash to output */
		pos = Xsavepos(xs, xp);
		/* 1 for the '/' and len + 1 for tp and the NUL from below */
		XcheckN(xs, xp, 1 + len + 1);
		Xput(xs, xp, '/');

		/* append next pathname component to output */
		memcpy(xp, tp, len);
		xp += len;
		*xp = '\0';

		/* lstat the current output, see if it's a symlink */
		if (mksh_lstat(Xstring(xs, xp), &sb)) {
			/* lstat failed */
			if (errno == ENOENT) {
				/* because the pathname does not exist */
				while (*ip == '/')
					/* skip any trailing slashes */
					++ip;
				/* no more components left? */
				if (!*ip)
					/* we can still return successfully */
					break;
				/* more components left? fall through */
			}
			/* not ENOENT or not at the end of ipath */
			goto notfound;
		}

		/* check if we encountered a symlink? */
		if (S_ISLNK(sb.st_mode)) {
#ifndef MKSH__NO_SYMLINK
			/* reached maximum recursion depth? */
			if (!symlinks--) {
				/* yep, prevent infinite loops */
				errno = ELOOP;
				goto notfound;
			}

			/* get symlink(7) target */
			if (pathcnd) {
#ifdef MKSH__NO_PATH_MAX
				if (notoktoadd(pathlen, 1)) {
					errno = ENAMETOOLONG;
					goto notfound;
				}
#endif
				ldest = aresize(ldest, pathlen + 1, ATEMP);
			}
			llen = readlink(Xstring(xs, xp), ldest, pathlen);
			if (llen < 0)
				/* oops... */
				goto notfound;
			ldest[llen] = '\0';

			/*
			 * restart if symlink target is an absolute path,
			 * otherwise continue with currently resolved prefix
			 */
			/* append rest of current input path to link target */
			tp = shf_smprintf("%s%s%s", ldest, *ip ? "/" : "", ip);
			afree(ipath, ATEMP);
			ip = ipath = tp;
			if (!mksh_abspath(ldest)) {
				/* symlink target is a relative path */
				xp = Xrestpos(xs, xp, pos);
			} else
#endif
			  {
				/* symlink target is an absolute path */
				xp = Xstring(xs, xp);
 beginning_of_a_pathname:
				/* assert: (ip == ipath)[0] == '/' */
				/* assert: xp == xs.beg => start of path */

				/* exactly two leading slashes? (SUSv4 3.266) */
				if (ip[1] == '/' && ip[2] != '/') {
					/* keep them, e.g. for UNC pathnames */
					Xput(xs, xp, '/');
				}
			}
		}
		/* otherwise (no symlink) merely go on */
	}

	/*
	 * either found the target and successfully resolved it,
	 * or found its parent directory and may create it
	 */
	if (Xlength(xs, xp) == 0)
		/*
		 * if the resolved pathname is "", make it "/",
		 * otherwise do not add a trailing slash
		 */
		Xput(xs, xp, '/');
	Xput(xs, xp, '\0');

	/*
	 * if source path had a trailing slash, check if target path
	 * is not a non-directory existing file
	 */
	if (ip > ipath && ip[-1] == '/') {
		if (stat(Xstring(xs, xp), &sb)) {
			if (errno != ENOENT)
				goto notfound;
		} else if (!S_ISDIR(sb.st_mode)) {
			errno = ENOTDIR;
			goto notfound;
		}
		/* target now either does not exist or is a directory */
	}

	/* return target path */
	if (ldest != NULL)
		afree(ldest, ATEMP);
	afree(ipath, ATEMP);
	return (Xclose(xs, xp));

 notfound:
	/* save; freeing memory might trash it */
	llen = errno;
	if (ldest != NULL)
		afree(ldest, ATEMP);
	afree(ipath, ATEMP);
	Xfree(xs, xp);
	errno = llen;
	return (NULL);

#undef pathlen
#undef pathcnd
}
Exemple #7
0
/* Like getcwd(), except bsize is ignored if buf is 0 (MAXPATHLEN is used) */
char *
ksh_get_wd(char *buf, int bsize)
{
#ifdef HAVE_GETCWD
	char *b;
	char *ret;

	/* Before memory allocated */
	HPUX_GETWD_BUG_CODE

	/* Assume getcwd() available */
	if (!buf) {
		bsize = MAXPATHLEN;
		b = alloc(MAXPATHLEN + 1, ATEMP);
	} else
		b = buf;

	ret = getcwd(b, bsize);

	if (!buf) {
		if (ret)
			ret = aresize(b, strlen(b) + 1, ATEMP);
		else
			afree(b, ATEMP);
	}

	return ret;
#else /* HAVE_GETCWD */
	extern char *getwd(char *);
	char *b;
	int len;

	/* Before memory allocated */
	HPUX_GETWD_BUG_CODE

	if (buf && bsize > MAXPATHLEN)
		b = buf;
	else
		b = alloc(MAXPATHLEN + 1, ATEMP);
	if (!getwd(b)) {
		errno = EACCES;
		if (b != buf)
			afree(b, ATEMP);
		return (char *) 0;
	}
	len = strlen(b) + 1;
	if (!buf)
		b = aresize(b, len, ATEMP);
	else if (buf != b) {
		if (len > bsize) {
			errno = ERANGE;
			return (char *) 0;
		}
		memcpy(buf, b, len);
		afree(b, ATEMP);
		b = buf;
	}

	return b;
#endif /* HAVE_GETCWD */
}