2
Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
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
19
#include "theos/stat.h"
21
/* replacement for standard library functions stat and fstat */
23
int _stat_(struct stat* st, struct fdb* fdb);
24
int _dstat_(struct stat* st);
26
#define peekucb() peeknuc()
28
/* map THEOS protection code to Unix modes */
30
unsigned short _tm2um_(char protect)
32
unsigned short umask = 0;
34
if (!(protect & _FDB_READ_PROTECT))
35
umask = S_IRUSR|S_IRGRP;
37
if (!(protect & _FDB_WRITE_PROTECT))
38
umask |= S_IWUSR|S_IWGRP;
40
if (!(protect & _FDB_EXECUTE_PROTECT))
41
umask |= S_IXUSR|S_IXGRP;
43
if (!(protect & _FDB_ERASE_PROTECT))
44
umask |= S_IEUSR|S_IEGRP;
46
if (!(protect & _FDB_SHARED_READ_PROTECT)) {
48
umask |= S_IROTH|S_IXOTH;
53
if (!(protect & _FDB_SHARED_WRITE_PROTECT))
56
if (!(protect & _FDB_MODIFIED)) {
63
if (protect & _FDB_NOT_HIDDEN)
69
/* map Unix modes to THEOS protections */
71
char _um2tm_(unsigned short mask)
75
if (!(mask & (S_IRUSR|S_IRGRP)))
76
protect |= _FDB_READ_PROTECT;
78
if (!(mask & (S_IWUSR|S_IWGRP)))
79
protect |= _FDB_WRITE_PROTECT;
81
if (!(mask & (S_IXUSR|S_IXGRP)))
82
protect |= _FDB_EXECUTE_PROTECT;
84
if (!(mask & (S_IEUSR|S_IEGRP)))
85
protect |= _FDB_ERASE_PROTECT;
88
if (!(mask & S_IROTH))
89
protect |= _FDB_SHARED_READ_PROTECT;
91
if (!(mask & (S_IROTH|S_IXOTH)))
92
protect |= _FDB_SHARED_READ_PROTECT;
95
if (!(mask & S_IWOTH))
96
protect |= _FDB_SHARED_WRITE_PROTECT;
98
if (mask & S_IMODF && _osmajor > 3)
99
protect |= _FDB_MODIFIED;
101
if (mask & S_INHID && _osmajor > 3)
102
protect |= _FDB_NOT_HIDDEN;
107
/* root directory stat */
109
static int rdirstat(char* fn, struct stat *st)
111
register char* p = strchr(fn, ':');
114
drive = p ? p[1] : 'S';
116
if (drive >= 'a' && drive <= 'Z')
119
memset(st, 0, sizeof(struct stat));
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;
125
st->st_dev = st->st_rdev = drive - 'A';
126
st->st_uid = st->st_gid = getuid();
127
st->st_protect = _FDB_ERASE_PROTECT;
130
errno = _errnum = ENOENT;
137
int _stat(const char *fn, struct stat *st)
139
char buf[256], buf2[256];
141
register struct fdb *fdb;
144
if ((ifn = (char *)malloc(strlen(fn)+1)) == NULL) {
145
errno = _errnum = ENOMEM;
149
if (p = strrchr(ifn, ':'))
152
/* on current drive ./:d and .:m point to current dir
153
* on another drive to root directory */
155
if (! strcmp(ifn, "/") || ! strcmp(ifn, ".") || ! strcmp(ifn, "./")) {
158
/* current dir on current drive */
159
ifn = getcwd(buf2, 256);
160
/* getcwd returns NULL on root dir on drive S */
162
strcpy(ifn = buf2, "/:S");
163
/* getcwd returns /:d on root dir on any other drive */
165
return rdirstat(ifn, st);
169
rstat = rdirstat(ifn, st);
179
/* remove trailing slash before optional disk name */
180
if (p = strrchr(buf2, '/')) {
185
} else if (p[1] == '\0')
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);
199
/* no, say file doesn't exist */
200
errno = _errnum = ENOENT;
205
/* else should be a device */
206
st->st_rdev = st->st_dev = _lub_name(*ifn == ':' ? ifn+1 : ifn);
209
if (st->st_dev != -1 && getlub(st->st_dev) != 255)
212
errno = _errnum = ENOENT;
217
int _fstat(int fd, struct stat *st)
219
unsigned short fsanum;
226
if (fd < FOPEN_MAX) {
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);
232
if (st->st_dev >= A_DISK && st->st_dev <= Z_DISK) {
233
for (i = 0, fsanum *= sizeof(fsa), p = (char *) &fsa;
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;
245
errno = _errnum = EBADF;
249
static int _isprt(int dev)
251
return IS_PRT_LUB(dev);
257
register struct stat* st;
259
register struct ucb* ucb;
261
ucb = getucb(st->st_dev);
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;
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;
279
st->st_uid = st->st_gid = getuid();
281
st->st_atime = st->st_mtime = st->st_ctime = 0;
289
/* regular file stat */
292
register struct stat* st;
293
register struct fdb* fdb;
295
st->st_rdev = st->st_dev;
297
st->st_org = fdb->filestat;
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;
312
st->st_mode |= _tm2um_(st->st_protect = fdb->protect);
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;
326
struct dirent* _opendir(const char* dirpath)
333
if (dirpath != NULL &&
334
(mypath = (char *)malloc(strlen(dirpath)+1)) == NULL) {
335
errno = _errnum = ENOMEM;
345
dir = opendir(dirpath);
352
return opendir(mypath);