Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6725 | siemargl | 1 | /* |
2 | Copyright (c) 1990-2000 Info-ZIP. All rights reserved. |
||
3 | |||
4 | See the accompanying file LICENSE, version 2000-Apr-09 or later |
||
5 | (the contents of which are also included in unzip.h) for terms of use. |
||
6 | If, for some reason, all these files are missing, the Info-ZIP license |
||
7 | also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html |
||
8 | */ |
||
9 | #pragma library |
||
10 | #include |
||
11 | #include |
||
12 | #include |
||
13 | #include |
||
14 | #include |
||
15 | #include |
||
16 | #include |
||
17 | #include |
||
18 | #include |
||
19 | #include "theos/stat.h" |
||
20 | |||
21 | /* replacement for standard library functions stat and fstat */ |
||
22 | |||
23 | int _stat_(struct stat* st, struct fdb* fdb); |
||
24 | int _dstat_(struct stat* st); |
||
25 | |||
26 | #define peekucb() peeknuc() |
||
27 | |||
28 | /* map THEOS protection code to Unix modes */ |
||
29 | |||
30 | unsigned short _tm2um_(char protect) |
||
31 | { |
||
32 | unsigned short umask = 0; |
||
33 | |||
34 | if (!(protect & _FDB_READ_PROTECT)) |
||
35 | umask = S_IRUSR|S_IRGRP; |
||
36 | |||
37 | if (!(protect & _FDB_WRITE_PROTECT)) |
||
38 | umask |= S_IWUSR|S_IWGRP; |
||
39 | |||
40 | if (!(protect & _FDB_EXECUTE_PROTECT)) |
||
41 | umask |= S_IXUSR|S_IXGRP; |
||
42 | |||
43 | if (!(protect & _FDB_ERASE_PROTECT)) |
||
44 | umask |= S_IEUSR|S_IEGRP; |
||
45 | |||
46 | if (!(protect & _FDB_SHARED_READ_PROTECT)) { |
||
47 | if (_osmajor > 3) |
||
48 | umask |= S_IROTH|S_IXOTH; |
||
49 | else |
||
50 | umask |= S_IROTH; |
||
51 | } |
||
52 | |||
53 | if (!(protect & _FDB_SHARED_WRITE_PROTECT)) |
||
54 | umask |= S_IWOTH; |
||
55 | |||
56 | if (!(protect & _FDB_MODIFIED)) { |
||
57 | if (_osmajor > 3) |
||
58 | umask |= S_IMODF; |
||
59 | else |
||
60 | umask |= S_IXOTH; |
||
61 | } |
||
62 | |||
63 | if (protect & _FDB_NOT_HIDDEN) |
||
64 | umask |= S_INHID; |
||
65 | |||
66 | return umask; |
||
67 | } |
||
68 | |||
69 | /* map Unix modes to THEOS protections */ |
||
70 | |||
71 | char _um2tm_(unsigned short mask) |
||
72 | { |
||
73 | char protect = 0; |
||
74 | |||
75 | if (!(mask & (S_IRUSR|S_IRGRP))) |
||
76 | protect |= _FDB_READ_PROTECT; |
||
77 | |||
78 | if (!(mask & (S_IWUSR|S_IWGRP))) |
||
79 | protect |= _FDB_WRITE_PROTECT; |
||
80 | |||
81 | if (!(mask & (S_IXUSR|S_IXGRP))) |
||
82 | protect |= _FDB_EXECUTE_PROTECT; |
||
83 | |||
84 | if (!(mask & (S_IEUSR|S_IEGRP))) |
||
85 | protect |= _FDB_ERASE_PROTECT; |
||
86 | |||
87 | if (_osmajor < 4) { |
||
88 | if (!(mask & S_IROTH)) |
||
89 | protect |= _FDB_SHARED_READ_PROTECT; |
||
90 | } else { |
||
91 | if (!(mask & (S_IROTH|S_IXOTH))) |
||
92 | protect |= _FDB_SHARED_READ_PROTECT; |
||
93 | } |
||
94 | |||
95 | if (!(mask & S_IWOTH)) |
||
96 | protect |= _FDB_SHARED_WRITE_PROTECT; |
||
97 | |||
98 | if (mask & S_IMODF && _osmajor > 3) |
||
99 | protect |= _FDB_MODIFIED; |
||
100 | |||
101 | if (mask & S_INHID && _osmajor > 3) |
||
102 | protect |= _FDB_NOT_HIDDEN; |
||
103 | |||
104 | return protect; |
||
105 | } |
||
106 | |||
107 | /* root directory stat */ |
||
108 | |||
109 | static int rdirstat(char* fn, struct stat *st) |
||
110 | { |
||
111 | register char* p = strchr(fn, ':'); |
||
112 | char drive; |
||
113 | |||
114 | drive = p ? p[1] : 'S'; |
||
115 | |||
116 | if (drive >= 'a' && drive <= 'Z') |
||
117 | drive -= 0x40; |
||
118 | |||
119 | memset(st, 0, sizeof(struct stat)); |
||
120 | |||
121 | if (getlub(drive - 'A') != 255) { |
||
122 | st->st_org = _FDB_STAT_DIRECTORY; |
||
123 | st->st_mode = S_IFDIR|S_IRUSR|S_IWUSR|S_IROTH|S_IWOTH; |
||
124 | st->st_nlink = 1; |
||
125 | st->st_dev = st->st_rdev = drive - 'A'; |
||
126 | st->st_uid = st->st_gid = getuid(); |
||
127 | st->st_protect = _FDB_ERASE_PROTECT; |
||
128 | return 0; |
||
129 | } |
||
130 | errno = _errnum = ENOENT; |
||
131 | _errarg = fn; |
||
132 | return -1; |
||
133 | } |
||
134 | |||
135 | /* file stat */ |
||
136 | |||
137 | int _stat(const char *fn, struct stat *st) |
||
138 | { |
||
139 | char buf[256], buf2[256]; |
||
140 | char *ifn; |
||
141 | register struct fdb *fdb; |
||
142 | register char *p; |
||
143 | |||
144 | if ((ifn = (char *)malloc(strlen(fn)+1)) == NULL) { |
||
145 | errno = _errnum = ENOMEM; |
||
146 | return -1; |
||
147 | } |
||
148 | |||
149 | if (p = strrchr(ifn, ':')) |
||
150 | *p = 0; |
||
151 | |||
152 | /* on current drive ./:d and .:m point to current dir |
||
153 | * on another drive to root directory */ |
||
154 | |||
155 | if (! strcmp(ifn, "/") || ! strcmp(ifn, ".") || ! strcmp(ifn, "./")) { |
||
156 | if (p == NULL) { |
||
157 | free(ifn); |
||
158 | /* current dir on current drive */ |
||
159 | ifn = getcwd(buf2, 256); |
||
160 | /* getcwd returns NULL on root dir on drive S */ |
||
161 | if (ifn == NULL) |
||
162 | strcpy(ifn = buf2, "/:S"); |
||
163 | /* getcwd returns /:d on root dir on any other drive */ |
||
164 | if (ifn[1] == ':') |
||
165 | return rdirstat(ifn, st); |
||
166 | } else { |
||
167 | int rstat; |
||
168 | *p = ':'; |
||
169 | rstat = rdirstat(ifn, st); |
||
170 | free(ifn); |
||
171 | return rstat; |
||
172 | } |
||
173 | } |
||
174 | |||
175 | if (p) |
||
176 | *p = ':'; |
||
177 | |||
178 | strcpy(buf2, ifn); |
||
179 | /* remove trailing slash before optional disk name */ |
||
180 | if (p = strrchr(buf2, '/')) { |
||
181 | if (p[1] == ':') { |
||
182 | *p = p[1]; |
||
183 | p[1] = p[2]; |
||
184 | p[2] = p[3]; |
||
185 | } else if (p[1] == '\0') |
||
186 | *p = '\0'; |
||
187 | } |
||
188 | /* if ifn is a file get file directory block structure and device */ |
||
189 | if (fdb = _locate(buf2, buf, &st->st_dev)) { |
||
190 | /* is it a file from another user... */ |
||
191 | if (strchr(buf2, '\\') |
||
192 | /* a public system file */ |
||
193 | || fdb->fileowner == 0 |
||
194 | /* or a file from the current user account ? */ |
||
195 | || fdb->fileowner == getuid()) { |
||
196 | /* yes, return stat */ |
||
197 | return _stat_(st, fdb); |
||
198 | } else { |
||
199 | /* no, say file doesn't exist */ |
||
200 | errno = _errnum = ENOENT; |
||
201 | _errarg = fn; |
||
202 | return -1; |
||
203 | } |
||
204 | } |
||
205 | /* else should be a device */ |
||
206 | st->st_rdev = st->st_dev = _lub_name(*ifn == ':' ? ifn+1 : ifn); |
||
207 | |||
208 | free(ifn); |
||
209 | if (st->st_dev != -1 && getlub(st->st_dev) != 255) |
||
210 | return _dstat_(st); |
||
211 | |||
212 | errno = _errnum = ENOENT; |
||
213 | _errarg = fn; |
||
214 | return -1; |
||
215 | } |
||
216 | |||
217 | int _fstat(int fd, struct stat *st) |
||
218 | { |
||
219 | unsigned short fsanum; |
||
220 | struct fsa fsa; |
||
221 | register FILE *fp; |
||
222 | int status; |
||
223 | register int i; |
||
224 | register char *p; |
||
225 | |||
226 | if (fd < FOPEN_MAX) { |
||
227 | fp = &stdin[fd]; |
||
228 | if (_fcntl(fp,1,0) & 0x80) { |
||
229 | fsanum = (unsigned short) _fcntl(fp,83,0); |
||
230 | st->st_dev = (unsigned short) _fcntl(fp,5,0); |
||
231 | |||
232 | if (st->st_dev >= A_DISK && st->st_dev <= Z_DISK) { |
||
233 | for (i = 0, fsanum *= sizeof(fsa), p = (char *) &fsa; |
||
234 | i < (sizeof(fsa)); |
||
235 | i++, fsanum++, p++) |
||
236 | *p = _peekfsa((char *) fsanum); |
||
237 | status = _stat_(st, (struct fdb*) &fsa); |
||
238 | if ((st->st_blksize = _fcntl(fp,817,0)) == 0) |
||
239 | st->st_blksize = BUFSIZ; |
||
240 | return status; |
||
241 | } |
||
242 | return _dstat_(st); |
||
243 | } |
||
244 | } |
||
245 | errno = _errnum = EBADF; |
||
246 | return -1; |
||
247 | } |
||
248 | |||
249 | static int _isprt(int dev) |
||
250 | { |
||
251 | return IS_PRT_LUB(dev); |
||
252 | } |
||
253 | |||
254 | /* device stat */ |
||
255 | |||
256 | int _dstat_(st) |
||
257 | register struct stat* st; |
||
258 | { |
||
259 | register struct ucb* ucb; |
||
260 | |||
261 | ucb = getucb(st->st_dev); |
||
262 | st->st_ino = 0; |
||
263 | if (st->st_dev <= Z_DISK |
||
264 | || (st->st_dev >= TAPE1 && st->st_dev <= TAPE4)) { |
||
265 | st->st_mode = S_IFBLK | S_IWUSR | S_IRUSR; |
||
266 | if (peekucb(&ucb->devowner) == 255) |
||
267 | st->st_mode |= S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH; |
||
268 | } else { |
||
269 | st->st_mode = S_IFCHR | S_IWUSR; |
||
270 | if (_isprt(st->st_dev)) |
||
271 | st->st_mode |= S_IRUSR; |
||
272 | if (peekucb(&ucb->devowner) == 255) { |
||
273 | st->st_mode |= S_IWGRP | S_IWOTH; |
||
274 | if (_isprt(st->st_dev)) |
||
275 | st->st_mode |= S_IRGRP | S_IROTH; |
||
276 | } |
||
277 | } |
||
278 | st->st_nlink = 1; |
||
279 | st->st_uid = st->st_gid = getuid(); |
||
280 | st->st_size = 0; |
||
281 | st->st_atime = st->st_mtime = st->st_ctime = 0; |
||
282 | st->st_rlen = 0; |
||
283 | st->st_klen = 0; |
||
284 | st->st_grow = 0; |
||
285 | st->st_blksize = 0; |
||
286 | return 0; |
||
287 | } |
||
288 | |||
289 | /* regular file stat */ |
||
290 | |||
291 | int _stat_(st, fdb) |
||
292 | register struct stat* st; |
||
293 | register struct fdb* fdb; |
||
294 | { |
||
295 | st->st_rdev = st->st_dev; |
||
296 | st->st_ino = 0; |
||
297 | st->st_org = fdb->filestat; |
||
298 | |||
299 | switch (fdb->filestat) { |
||
300 | case _FDB_STAT_LIBRARY: st->st_mode = S_IFLIB; break; |
||
301 | case _FDB_STAT_DIRECTORY: st->st_mode = S_IFDIR; break; |
||
302 | case _FDB_STAT_STREAM: st->st_mode = S_IFREG; break; |
||
303 | case _FDB_STAT_RELATIVE: st->st_mode = S_IFREL; break; |
||
304 | case _FDB_STAT_KEYED: st->st_mode = S_IFKEY; break; |
||
305 | case _FDB_STAT_INDEXED: st->st_mode = S_IFIND; break; |
||
306 | case _FDB_STAT_RANDOM: st->st_mode = S_IFRND; break; |
||
307 | case _FDB_STAT_PROGRAM: st->st_mode = S_IFR16; break; |
||
308 | case _FDB_STAT_16_BIT_PROGRAM: st->st_mode = S_IFP16; break; |
||
309 | case _FDB_STAT_32_BIT_PROGRAM: st->st_mode = S_IFP32; break; |
||
310 | } |
||
311 | |||
312 | st->st_mode |= _tm2um_(st->st_protect = fdb->protect); |
||
313 | st->st_nlink = 1; |
||
314 | st->st_uid = st->st_gid = fdb->fileowner; |
||
315 | st->st_size = fdb->filesize; |
||
316 | st->st_atime = st->st_mtime = st->st_ctime = getfiledate(fdb); |
||
317 | st->st_rlen = fdb->reclen; |
||
318 | st->st_klen = fdb->keylen; |
||
319 | st->st_grow = fdb->filegrow; |
||
320 | st->st_blksize = 0; |
||
321 | return 0; |
||
322 | } |
||
323 | |||
324 | #include |
||
325 | |||
326 | struct dirent* _opendir(const char* dirpath) |
||
327 | { |
||
328 | int l; |
||
329 | char *p; |
||
330 | struct dirent* dir; |
||
331 | char *mypath = NULL; |
||
332 | |||
333 | if (dirpath != NULL && |
||
334 | (mypath = (char *)malloc(strlen(dirpath)+1)) == NULL) { |
||
335 | errno = _errnum = ENOMEM; |
||
336 | return NULL; |
||
337 | } |
||
338 | |||
339 | if (mypath) { |
||
340 | l = strlen(mypath); |
||
341 | if (l) { |
||
342 | p = dirpath + l - 1; |
||
343 | if (*p == '/') { |
||
344 | *p = '\0'; |
||
345 | dir = opendir(dirpath); |
||
346 | *p = '/'; |
||
347 | return dir; |
||
348 | } |
||
349 | } |
||
350 | |||
351 | } |
||
352 | return opendir(mypath); |
||
353 | }=>=>>=>>=>> |