
/*
 * pwd.c -- return the current working directory
 *
 * $Id$
 */

#include <h/mh.h>

static char curwd[PATH_MAX];


char *
pwd(void)
{
    register char *cp;

    if (!getcwd (curwd, PATH_MAX)) {
	admonish (NULL, "unable to determine working directory");
	if (!mypath || !*mypath
		|| (strcpy (curwd, mypath), chdir (curwd)) == NOTOK) {
	    strcpy (curwd, "/");
	    chdir (curwd);
	}
	return curwd;
    }

    if ((cp = curwd + strlen (curwd) - 1) > curwd && *cp == '/')
	*cp = 0;

    return curwd;
}


#if 0 /* currently commented out.  need to add to configure.in */

/* getwd() - get the current working directory */

/* Algorithm from several sources, -ljobs, pwd.c, etc., etc. */

int
getwd(char *cwd)
{
    int found;
    char tmp1[BUFSIZ], tmp2[BUFSIZ];
    struct stat st1, st2, root;
    register struct direct *dp;
    register DIR *dd;

    strcpy (cwd, "/");
    stat ("/", &root);

    for (;;) {
	if ((dd = opendir ("..")) == NULL)
	    return NOTOK;
	if (stat (".", &st2) == NOTOK || stat ("..", &st1) == NOTOK)
	    goto out;
	if (st2.st_ino == root.st_ino && st2.st_dev == root.st_dev) {
	    closedir (dd);
	    return chdir (cwd);
	}

	if (st2.st_ino == st1.st_ino && st2.st_dev == st1.st_dev) {
	    closedir (dd);
	    chdir ("/");
	    if ((dd = opendir (".")) == NULL)
		return NOTOK;
	    if (stat (".", &st1) < 0)
		goto out;
	    if (st2.st_dev != st1.st_dev)
		while (dp = readdir (dd)) {
		    if (stat (dp->d_name, &st1) == NOTOK)
			goto out;
		    if (st2.st_dev == st1.st_dev) {
			sprintf (tmp1, "%s%s", dp->d_name, cwd);
			strcpy (cwd + 1, tmp1);
			closedir (dd);
			return (chdir (cwd));
		    }
		}
	    else {
		closedir (dd);
		return (chdir (cwd));
	    }
	}

	found = 0;
	while (dp = readdir (dd)) {
	    sprintf (tmp2, "../%s", dp->d_name);
	    if (stat (tmp2, &st1) != NOTOK
		    && st1.st_ino == st2.st_ino
		    && st1.st_dev == st2.st_dev) {
		closedir (dd);
		found++;
		chdir ("..");
		sprintf (tmp1, "%s%s", dp->d_name, cwd);
		strcpy (cwd + 1, tmp1);
		break;
	    }
	}
	if (!found)
	    goto out;
    }

out: ;
    closedir (dd);
    return NOTOK;
}

#endif
