~ubuntu-branches/ubuntu/precise/unzip/precise-proposed

« back to all changes in this revision

Viewing changes to theos/_stat.c

  • Committer: Bazaar Package Importer
  • Author(s): Santiago Vila
  • Date: 2004-06-06 17:57:46 UTC
  • Revision ID: james.westby@ubuntu.com-20040606175746-nl7p2dgp3aobyc2c
Tags: upstream-5.51
ImportĀ upstreamĀ versionĀ 5.51

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <stdio.h>
 
11
#include <stdlib.h>
 
12
#include <errno.h>
 
13
#include <string.h>
 
14
#include <sc.h>
 
15
#include <peek.h>
 
16
#include <lub.h>
 
17
#include <fdb.h>
 
18
#include <fsa.h>
 
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 <direct.h>
 
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
}