12346Seric /*
2*6718Ssam  * SCCSID(@(#)curdir.c	4.5);
36635Ssam  */
46635Ssam #include	<sys/param.h>
56635Ssam #include	<sys/stat.h>
66635Ssam #include	<sys/dir.h>
72346Seric 
86635Ssam #define	dot	"."
96635Ssam #define	dotdot	".."
102346Seric 
116635Ssam static	char	*name;
122346Seric 
13*6718Ssam static	int	off;
146635Ssam static	struct	stat	d, dd;
156635Ssam static	struct	direct	*dir;
166635Ssam static	DIR	*dirp;
176635Ssam static	int	cat(), prexit();
182346Seric 
196635Ssam char *
curdir(np)206635Ssam curdir(np)
216635Ssam char *np;
226635Ssam {
236635Ssam 	int rdev, rino;
242346Seric 
25*6718Ssam 	off = -1;
266635Ssam 	*np++ = '/';
276635Ssam 	name = np;
286635Ssam 	stat("/", &d);
296635Ssam 	rdev = d.st_dev;
306635Ssam 	rino = d.st_ino;
316635Ssam 	for (;;) {
326635Ssam 		stat(dot, &d);
336635Ssam 		if (d.st_ino==rino && d.st_dev==rdev)
346635Ssam 			goto done;
356635Ssam 		if ((dirp = opendir(dotdot)) == 0)
366635Ssam 			prexit("curdir: cannot open ..\n");
376635Ssam 		fstat(dirp->dd_fd, &dd);
386635Ssam 		chdir(dotdot);
396635Ssam 		if(d.st_dev == dd.st_dev) {
406635Ssam 			if(d.st_ino == dd.st_ino)
416635Ssam 				goto done;
426635Ssam 			do
436635Ssam 				if ((dir = readdir(dirp)) == 0)
446635Ssam 					prexit("curdir: read error in ..\n");
456635Ssam 			while (dir->d_ino != d.st_ino);
466635Ssam 		} else
476635Ssam 			do {
486635Ssam 				if ((dir = readdir(dirp)) == 0)
496635Ssam 					prexit("curdir: read error in ..\n");
506635Ssam 				stat(dir->d_name, &dd);
516635Ssam 			} while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev);
526635Ssam 		closedir(dirp);
536635Ssam 		cat();
546635Ssam 	}
556635Ssam done:
566635Ssam 	name--;
576635Ssam 	if (chdir(name) < 0) {
586635Ssam 		write(2, name, strlen(name));
596635Ssam 		prexit(": can't change back\n");
606635Ssam 	}
616635Ssam 	return (0);
626635Ssam }
632346Seric 
646635Ssam static
cat()656635Ssam cat()
662346Seric {
676635Ssam 	register i, j;
682346Seric 
696635Ssam 	i = dir->d_namlen;
706635Ssam 	if ((off+i+2) > 1024-1)
716635Ssam 		return;
726635Ssam 	for(j=off+1; j>=0; --j)
736635Ssam 		name[j+i+1] = name[j];
746635Ssam 	if (off >= 0)
756635Ssam 		name[i] = '/';
766635Ssam 	off += i+1;
776635Ssam 	name[off] = 0;
786635Ssam 	for(--i; i>=0; --i)
796635Ssam 		name[i] = dir->d_name[i];
802346Seric }
812346Seric 
826635Ssam static
prexit(cp)836635Ssam prexit(cp)
846635Ssam char *cp;
852346Seric {
866635Ssam 	write(2, cp, strlen(cp));
876635Ssam 	exit(1);
882346Seric }
89