Commit | Line | Data |
---|---|---|
8d53e756 EA |
1 | # include "../hdr/macros.h" |
2 | # include "dir.h" | |
d1b30827 | 3 | |
8d53e756 | 4 | #define IROOT 2 |
fef2d2b7 | 5 | SCCSID(@(#)curdir.c 4.3); |
8d53e756 EA |
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 { | |
8d53e756 | 26 | char m_dir[32]; |
d1b30827 | 27 | char m_spcl[32]; |
8d53e756 EA |
28 | }; |
29 | ||
30 | static struct mtab mtab; | |
31 | ||
32 | curdir(str) | |
33 | char *str; | |
34 | { | |
35 | register int n; | |
36 | ||
8d53e756 EA |
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 | } | |
fef2d2b7 | 81 | close(fd); |
8d53e756 | 82 | if ((fd = open("/etc/mtab", 0))<0) return(-1); |
d1b30827 EA |
83 | while (read(fd,&mtab,64) == 64) { |
84 | char devstr[40]; | |
85 | strcpy(devstr, "/dev/"); | |
86 | strcat(devstr, mtab.m_spcl); | |
87 | if (stat(devstr,&s)<0) | |
88 | continue; | |
8d53e756 EA |
89 | if (s.st_rdev != dev) continue; |
90 | for (tp = mtab.m_dir; *curdirp = *tp++; curdirp++); | |
91 | ADDSLASH; | |
92 | *curdirp = 0; | |
fef2d2b7 | 93 | close(fd); |
8d53e756 EA |
94 | return(0); |
95 | } | |
96 | QUIT; | |
97 | } | |
98 | if ((fd = open("..",0))<0) return(-1); | |
99 | for (entry.d_ino = 0; entry.d_ino != inum; ) | |
100 | if (read(fd,&entry,sizeof(entry)) != sizeof(entry)) | |
101 | QUIT; | |
102 | close(fd); | |
103 | if (chdir("..")<0) return(-1); | |
104 | if (findir(-1)<0) r = -1; | |
105 | else r = 0; | |
106 | for (tp = entry.d_name; *curdirp = (*tp++); curdirp++); | |
107 | ADDSLASH; | |
108 | *curdirp = 0; | |
109 | return(r); | |
110 | } |