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