12346Seric /*
2*6635Ssam  * SCCSID(@(#)curdir.c	4.4);
3*6635Ssam  */
4*6635Ssam #include	<sys/param.h>
5*6635Ssam #include	<sys/stat.h>
6*6635Ssam #include	<sys/dir.h>
72346Seric 
8*6635Ssam #define	dot	"."
9*6635Ssam #define	dotdot	".."
102346Seric 
11*6635Ssam static	char	*name;
122346Seric 
13*6635Ssam static	int	off	= -1;
14*6635Ssam static	struct	stat	d, dd;
15*6635Ssam static	struct	direct	*dir;
16*6635Ssam static	DIR	*dirp;
17*6635Ssam static	int	cat(), prexit();
182346Seric 
19*6635Ssam char *
20*6635Ssam curdir(np)
21*6635Ssam char *np;
22*6635Ssam {
23*6635Ssam 	int rdev, rino;
242346Seric 
25*6635Ssam 	*np++ = '/';
26*6635Ssam 	name = np;
27*6635Ssam 	stat("/", &d);
28*6635Ssam 	rdev = d.st_dev;
29*6635Ssam 	rino = d.st_ino;
30*6635Ssam 	for (;;) {
31*6635Ssam 		stat(dot, &d);
32*6635Ssam 		if (d.st_ino==rino && d.st_dev==rdev)
33*6635Ssam 			goto done;
34*6635Ssam 		if ((dirp = opendir(dotdot)) == 0)
35*6635Ssam 			prexit("curdir: cannot open ..\n");
36*6635Ssam 		fstat(dirp->dd_fd, &dd);
37*6635Ssam 		chdir(dotdot);
38*6635Ssam 		if(d.st_dev == dd.st_dev) {
39*6635Ssam 			if(d.st_ino == dd.st_ino)
40*6635Ssam 				goto done;
41*6635Ssam 			do
42*6635Ssam 				if ((dir = readdir(dirp)) == 0)
43*6635Ssam 					prexit("curdir: read error in ..\n");
44*6635Ssam 			while (dir->d_ino != d.st_ino);
45*6635Ssam 		} else
46*6635Ssam 			do {
47*6635Ssam 				if ((dir = readdir(dirp)) == 0)
48*6635Ssam 					prexit("curdir: read error in ..\n");
49*6635Ssam 				stat(dir->d_name, &dd);
50*6635Ssam 			} while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev);
51*6635Ssam 		closedir(dirp);
52*6635Ssam 		cat();
53*6635Ssam 	}
54*6635Ssam done:
55*6635Ssam 	name--;
56*6635Ssam 	if (chdir(name) < 0) {
57*6635Ssam 		write(2, name, strlen(name));
58*6635Ssam 		prexit(": can't change back\n");
59*6635Ssam 	}
60*6635Ssam 	return (0);
61*6635Ssam }
622346Seric 
63*6635Ssam static
64*6635Ssam cat()
652346Seric {
66*6635Ssam 	register i, j;
672346Seric 
68*6635Ssam 	i = dir->d_namlen;
69*6635Ssam 	if ((off+i+2) > 1024-1)
70*6635Ssam 		return;
71*6635Ssam 	for(j=off+1; j>=0; --j)
72*6635Ssam 		name[j+i+1] = name[j];
73*6635Ssam 	if (off >= 0)
74*6635Ssam 		name[i] = '/';
75*6635Ssam 	off += i+1;
76*6635Ssam 	name[off] = 0;
77*6635Ssam 	for(--i; i>=0; --i)
78*6635Ssam 		name[i] = dir->d_name[i];
792346Seric }
802346Seric 
81*6635Ssam static
82*6635Ssam prexit(cp)
83*6635Ssam char *cp;
842346Seric {
85*6635Ssam 	write(2, cp, strlen(cp));
86*6635Ssam 	exit(1);
872346Seric }
88