1*2346Seric # include	"../hdr/macros.h"
2*2346Seric # include	"dir.h"
3*2346Seric #define IROOT 2
4*2346Seric SCCSID(@(#)curdir.c	4.1);
5*2346Seric /*
6*2346Seric 	current directory.
7*2346Seric 	Places the full pathname of the current directory in `str'.
8*2346Seric 	Handles file systems not mounted on a root directory
9*2346Seric 	via /etc/mtab (see mtab(V)).
10*2346Seric 	NOTE: PWB systems don't use mtab(V), but they don't mount
11*2346Seric 	file systems anywhere but on a root directory (so far, at least).
12*2346Seric 
13*2346Seric 	returns 0 on success
14*2346Seric 	< 0 on failure.
15*2346Seric 
16*2346Seric 	Current directory on return:
17*2346Seric 		success: same as on entry
18*2346Seric 		failure: UNKNOWN!
19*2346Seric */
20*2346Seric 
21*2346Seric 
22*2346Seric static char *curdirp;
23*2346Seric 
24*2346Seric struct mtab {
25*2346Seric 	char	m_devstr[6];
26*2346Seric 	char	m_spcl[32];
27*2346Seric 	char	m_dir[32];
28*2346Seric };
29*2346Seric 
30*2346Seric static struct mtab mtab;
31*2346Seric 
32*2346Seric curdir(str)
33*2346Seric char *str;
34*2346Seric {
35*2346Seric 	register int n;
36*2346Seric 
37*2346Seric 	copy("/dev//",mtab.m_devstr);
38*2346Seric 	curdirp = str;
39*2346Seric 	n = findir(0);
40*2346Seric 	return(n+chdir(str));
41*2346Seric }
42*2346Seric 
43*2346Seric 
44*2346Seric # define ADDSLASH	if (flag) *curdirp++ = '/';
45*2346Seric # define QUIT		{ close(fd); return(-1); }
46*2346Seric 
47*2346Seric findir(flag)
48*2346Seric {
49*2346Seric 	register int fd,inum;
50*2346Seric 	register char *tp;
51*2346Seric 	char *slashp;
52*2346Seric 	int dev, r;
53*2346Seric 	struct dir entry;
54*2346Seric 	struct stat s;
55*2346Seric 
56*2346Seric 	if (stat(".",&s)<0) return(-1);
57*2346Seric 	if ((inum = s.st_ino) == IROOT) {
58*2346Seric 		dev = s.st_dev;
59*2346Seric 		if ((fd = open("/",0))<0) return(-1);
60*2346Seric 		if (fstat(fd,&s)<0)
61*2346Seric 			QUIT;
62*2346Seric 		if (dev == s.st_dev) {
63*2346Seric 			*curdirp++ = '/';
64*2346Seric 			*curdirp = 0;
65*2346Seric 			close(fd);
66*2346Seric 			return(0);
67*2346Seric 		}
68*2346Seric 		slashp = entry.d_name;
69*2346Seric 		slashp--;
70*2346Seric 		while (read(fd,&entry,sizeof(entry)) == sizeof(entry)) {
71*2346Seric 			if (entry.d_ino == 0) continue;
72*2346Seric 			*slashp = '/';
73*2346Seric 			if (stat(slashp,&s)<0) continue;
74*2346Seric 			if (s.st_dev != dev) continue;
75*2346Seric 			if ((s.st_mode&S_IFMT) != S_IFDIR) continue;
76*2346Seric 			for (tp = slashp; *curdirp = (*tp++); curdirp++);
77*2346Seric 			ADDSLASH;
78*2346Seric 			*curdirp = 0;
79*2346Seric 			close(fd);
80*2346Seric 			return(0);
81*2346Seric 		}
82*2346Seric 		if ((fd = open("/etc/mtab", 0))<0) return(-1);
83*2346Seric 		while (read(fd,mtab.m_spcl,64) == 64) {
84*2346Seric 			if (stat(mtab.m_devstr,&s)<0)
85*2346Seric 				QUIT;
86*2346Seric 			if (s.st_rdev != dev) continue;
87*2346Seric 			for (tp = mtab.m_dir; *curdirp = *tp++; curdirp++);
88*2346Seric 			ADDSLASH;
89*2346Seric 			*curdirp = 0;
90*2346Seric 			return(0);
91*2346Seric 		}
92*2346Seric 		QUIT;
93*2346Seric 	}
94*2346Seric 	if ((fd = open("..",0))<0) return(-1);
95*2346Seric 	for (entry.d_ino = 0; entry.d_ino != inum; )
96*2346Seric 		if (read(fd,&entry,sizeof(entry)) != sizeof(entry))
97*2346Seric 			QUIT;
98*2346Seric 	close(fd);
99*2346Seric 	if (chdir("..")<0) return(-1);
100*2346Seric 	if (findir(-1)<0) r = -1;
101*2346Seric 	else r = 0;
102*2346Seric 	for (tp = entry.d_name; *curdirp = (*tp++); curdirp++);
103*2346Seric 	ADDSLASH;
104*2346Seric 	*curdirp = 0;
105*2346Seric 	return(r);
106*2346Seric }
107