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