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