da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Research
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * pwd library support
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * pop long dir component chdir stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (dp = d)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * push long dir component onto stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic struct dirlist*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpushdir(register struct dirlist* d, char* dots, char* path, char* end)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct dirlist* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(p = newof(0, struct dirlist, 1, 0)) || chdir(dots))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p) free(p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return a pointer to the absolute path name of .
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * this path name may be longer than PATH_MAX
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * a few environment variables are checked before the search algorithm
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return value is placed in buf of len chars
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if buf is 0 then space is allocated via malloc() with
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * len extra chars after the path name
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 0 is returned on error with errno set as appropriate
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static struct
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { /*previous*/0 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "PWD" },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { "HOME" },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fs3d(FS3D_TEST) && (namlen = mount(".", dots, FS3D_GET|FS3D_VIEW|FS3D_SIZE(sizeof(dots)), NiL)) > 1 && namlen < sizeof(dots))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!(buf = newof(0, char, namlen, len))) ERROR(ENOMEM);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((env[n].name && (p = getenv(env[n].name)) || (p = env[n].path)) && *p == '/' && !stat(p, cur))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cur->st_ino == par->st_ino && cur->st_dev == par->st_dev)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(buf = newof(0, char, len, extra))) ERROR(ENOMEM);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(dirstk = pushdir(dirstk, dots, p, buf + len - 1))) ERROR(ERANGE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *d++ = '.';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *d++ = '.';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *d++ = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *--p = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*d++ = *p++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (extra >= 0 && !(buf = newof(buf, char, len, extra))) ERROR(ENOMEM);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * this fallthrough handles logical naming
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (namlen >= PATH_MAX || !(dirstk = pushdir(dirstk, dots + 3, p, buf + len - 1))) ERROR(ERANGE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin } while (stat(dots, &tstst) || tstst.st_ino != cur->st_ino || tstst.st_dev != cur->st_dev);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*p) *--p = '/';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (extra < 0 || !(buf = newof(buf, char, len += PATH_MAX, extra))) ERROR(ERANGE);