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 * 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 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 83 prexit(cp) 84 char *cp; 85 { 86 write(2, cp, strlen(cp)); 87 exit(1); 88 } 89