static char Sccsid[]="@(#)curdir.c	2.1 ";

# define	IROOT	2
# include	"sys/types.h"
# include	"macros.h"

#include <stdio.h>
#include "sys/param.h"
#include "mnttab.h"
#include "sys/dir.h"
#include "sys/filsys.h"
/*
	current directory.
	Places the full pathname of the current directory in `str'.
	Handles file systems not mounted on a root directory
	via /etc/mtab (see mtab(V)).
	NOTE: PWB systems don't use mtab(V), but they don't mount
	file systems anywhere but on a root directory (so far, at least).

	returns 0 on success
	< 0 on failure.

	Current directory on return:
		success: same as on entry
		failure: UNKNOWN!
*/
static char *curdirp;

struct mtab {
	char	m_devstr[6];
	char	m_spcl[32];
	char	m_dir[32];
};
static char	*flg[] = {
	"read/write",
	"read only"
	};

static struct mnttab mtab[NMOUNT], *mp;
static struct filsys super;


curdir(str)
char *str;
{
	register int n;

	curdirp = str;
	n = findir(0);
	return(n+chdir(str));
}


# define ADDSLASH	if (flag) *curdirp++ = '/';
# define QUIT		{ close(fd); return(-1); }

findir(flag)
{
	register int fd,inum;
	register char *tp;
	char *slashp,tmp[100];
	int dev, r;
	struct direct entry;
	struct stat s;

	if (stat(".",&s)<0) return(-1);
	if ((inum = s.st_ino) == IROOT) {
		dev = s.st_dev;
		if ((fd = open("/",0))<0) return(-1);
		if (fstat(fd,&s)<0)
			QUIT;
		if (dev == s.st_dev) {
			*curdirp++ = '/';
			*curdirp = 0;
			close(fd);
			return(0);
		}
		slashp = entry.d_name;
		slashp--;
		while (read(fd,&entry,sizeof(entry)) == sizeof(entry)) {
			if (entry.d_ino == 0) continue;
			*slashp = '/';
			if (stat(slashp,&s)<0) continue;
			if (s.st_dev != dev) continue;
			if ((s.st_mode&S_IFMT) != S_IFDIR) continue;
			for (tp = slashp; *curdirp = (*tp++); curdirp++);
			ADDSLASH;
			*curdirp = 0;
			close(fd);
			return(0);
		}
		close(fd);

		fd = open("/etc/mnttab",0);
		if(fd < 0) {
			fprintf(stderr, "curdir: cannot open /etc/mnttab!\n");
			return(-1);
		}
		read(fd, mtab, sizeof mtab);
		for(mp = mtab; mp < &mtab[NMOUNT]; mp++) {
			if(mp->mt_dev[0]) {
				sprintf(tmp,"/dev/%s",mp->mt_dev);
				if ( stat(tmp,&s) < 0 )
					QUIT;
				if ( s.st_rdev != dev ) continue;
				for ( tp = mp->mt_filsys; *curdirp = (*tp++); curdirp++ );
				ADDSLASH;
				close(fd);
	/*  test print
				printf("%.10s on /dev/%s %s on %s",
				mp->mt_filsys, mp->mt_dev,
				flg[mp->mt_ro_flg], ctime(&mp->mt_time));
	end test print */
				return(0);
			}
		}
	
		QUIT;
	}
	if ((fd = open("..",0))<0) return(-1);
	for (entry.d_ino = 0; entry.d_ino != inum; )
		if (read(fd,&entry,sizeof(entry)) != sizeof(entry))
			QUIT;
	close(fd);
	if (chdir("..")<0) return(-1);
	if (findir(-1)<0) r = -1;
	else r = 0;
	for (tp = entry.d_name; *curdirp = (*tp++); curdirp++);
	ADDSLASH;
	*curdirp = 0;
	return(r);
}
