1 # include "../hdr/macros.h" 2 # include "dir.h" 3 4 #define IROOT 2 5 SCCSID(@(#)curdir.c 4.2); 6 /* 7 current directory. 8 Places the full pathname of the current directory in `str'. 9 Handles file systems not mounted on a root directory 10 via /etc/mtab (see mtab(V)). 11 NOTE: PWB systems don't use mtab(V), but they don't mount 12 file systems anywhere but on a root directory (so far, at least). 13 14 returns 0 on success 15 < 0 on failure. 16 17 Current directory on return: 18 success: same as on entry 19 failure: UNKNOWN! 20 */ 21 22 23 static char *curdirp; 24 25 struct mtab { 26 char m_dir[32]; 27 char m_spcl[32]; 28 }; 29 30 static struct mtab mtab; 31 32 curdir(str) 33 char *str; 34 { 35 register int n; 36 37 curdirp = str; 38 n = findir(0); 39 return(n+chdir(str)); 40 } 41 42 43 # define ADDSLASH if (flag) *curdirp++ = '/'; 44 # define QUIT { close(fd); return(-1); } 45 46 findir(flag) 47 { 48 register int fd,inum; 49 register char *tp; 50 char *slashp; 51 int dev, r; 52 struct dir entry; 53 struct stat s; 54 55 if (stat(".",&s)<0) return(-1); 56 if ((inum = s.st_ino) == IROOT) { 57 dev = s.st_dev; 58 if ((fd = open("/",0))<0) return(-1); 59 if (fstat(fd,&s)<0) 60 QUIT; 61 if (dev == s.st_dev) { 62 *curdirp++ = '/'; 63 *curdirp = 0; 64 close(fd); 65 return(0); 66 } 67 slashp = entry.d_name; 68 slashp--; 69 while (read(fd,&entry,sizeof(entry)) == sizeof(entry)) { 70 if (entry.d_ino == 0) continue; 71 *slashp = '/'; 72 if (stat(slashp,&s)<0) continue; 73 if (s.st_dev != dev) continue; 74 if ((s.st_mode&S_IFMT) != S_IFDIR) continue; 75 for (tp = slashp; *curdirp = (*tp++); curdirp++); 76 ADDSLASH; 77 *curdirp = 0; 78 close(fd); 79 return(0); 80 } 81 if ((fd = open("/etc/mtab", 0))<0) return(-1); 82 while (read(fd,&mtab,64) == 64) { 83 char devstr[40]; 84 strcpy(devstr, "/dev/"); 85 strcat(devstr, mtab.m_spcl); 86 if (stat(devstr,&s)<0) 87 continue; 88 if (s.st_rdev != dev) continue; 89 for (tp = mtab.m_dir; *curdirp = *tp++; curdirp++); 90 ADDSLASH; 91 *curdirp = 0; 92 return(0); 93 } 94 QUIT; 95 } 96 if ((fd = open("..",0))<0) return(-1); 97 for (entry.d_ino = 0; entry.d_ino != inum; ) 98 if (read(fd,&entry,sizeof(entry)) != sizeof(entry)) 99 QUIT; 100 close(fd); 101 if (chdir("..")<0) return(-1); 102 if (findir(-1)<0) r = -1; 103 else r = 0; 104 for (tp = entry.d_name; *curdirp = (*tp++); curdirp++); 105 ADDSLASH; 106 *curdirp = 0; 107 return(r); 108 } 109