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