From 4acc22dd2f30f063c7b07fdbc911384feeda58eb Mon Sep 17 00:00:00 2001 From: Kim Kibum Date: Fri, 24 Aug 2012 14:34:26 +0900 Subject: upload source --- theos/Makefile | 135 ++++++++++++++ theos/README | 34 ++++ theos/_chmod.c | 21 +++ theos/_fprintf.c | 26 +++ theos/_isatty.c | 26 +++ theos/_rename.c | 83 +++++++++ theos/_setargv.c | 140 ++++++++++++++ theos/_stat.c | 461 +++++++++++++++++++++++++++++++++++++++++++++ theos/charconv.h | 93 ++++++++++ theos/osdep.h | 58 ++++++ theos/stat.h | 106 +++++++++++ theos/theos.c | 558 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ theos/zipup.h | 19 ++ 13 files changed, 1760 insertions(+) create mode 100644 theos/Makefile create mode 100644 theos/README create mode 100644 theos/_chmod.c create mode 100644 theos/_fprintf.c create mode 100644 theos/_isatty.c create mode 100644 theos/_rename.c create mode 100644 theos/_setargv.c create mode 100644 theos/_stat.c create mode 100644 theos/charconv.h create mode 100644 theos/osdep.h create mode 100644 theos/stat.h create mode 100644 theos/theos.c create mode 100644 theos/zipup.h (limited to 'theos') diff --git a/theos/Makefile b/theos/Makefile new file mode 100644 index 0000000..cb3d6da --- /dev/null +++ b/theos/Makefile @@ -0,0 +1,135 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for +# THEOS ANSI C +# To use, do "make -f theos/makefile" +# This make file uses cl, a C compiler and linker driver written by +# Jean-Michel Dubois. Send a mail to jmdubois@ibcfrance.fr to get it for free. +# MAINWA_BUG Workaround argument expansion failure +# LOCATE_BUG Workaround stat, fopen and open failure on relative paths to +# root dir. + +CC=cl +CFLAGS=-Zi -W3 -DDYN_ALLOC -DCRYPT -DMAINWA_BUG -DLOCATE_BUG +LD=cl -o +LDFLAGS=-m -Zi +AS=cc +ASFLAGS= + +UTILFLAGS=-DUTIL $(CFLAGS) -Fo + +# variables + +# object file lists +OBJZ = zip.o zipfile.o zipup.o fileio.o util.o globals.o crypt.o ttyio.o \ + theos.o crc32.o crctab.o _fprintf.o _stat.o _chmod.o _isatty.o \ + _setargv.o _rename.o +OBJI = deflate.o trees.o +OBJA = +OBJU = zipfile_.o fileio_.o util_.o globals.o theos_.o _rename.o _stat.o \ + _chmod.o _fprintf.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o $(OBJU) crctab.o crypt_.o ttyio.o +OBJS = zipsplit.o $(OBJU) + +ZIPS = zip.command zipnote.command zipsplit.command zipcloak.command + +zips: $(ZIPS) + +zip.o: zip.h theos/osdep.h ziperr.h tailor.h ttyio.h revision.h zip.c + $(CC) -c $(CFLAGS) $*.c + +zipfile.o: zip.h theos/osdep.h ziperr.h tailor.h zipfile.c + $(CC) -c $(CFLAGS) $*.c + +zipup.o: zip.h theos/osdep.h ziperr.h tailor.h revision.h zipup.c + $(CC) -c $(CFLAGS) $*.c + +fileio.o: zip.h theos/osdep.h ziperr.h tailor.h fileio.c + $(CC) -c $(CFLAGS) $*.c + +util.o: zip.h theos/osdep.h theos/charconv.h ziperr.h tailor.h util.c + $(CC) -c $(CFLAGS) $*.c + +globals.o: zip.h theos/osdep.h ziperr.h tailor.h globals.c + $(CC) -c $(CFLAGS) $*.c + +crc32.o: zip.h theos/osdep.h ziperr.h tailor.h crc32.c + $(CC) -c $(CFLAGS) $*.c + +crctab.o: zip.h theos/osdep.h ziperr.h tailor.h crctab.c + $(CC) -c $(CFLAGS) $*.c + +deflate.o: zip.h theos/osdep.h ziperr.h tailor.h deflate.c + $(CC) -c $(CFLAGS) $*.c + +trees.o: zip.h theos/osdep.h ziperr.h tailor.h trees.c + $(CC) -c $(CFLAGS) $*.c + +crypt.o: zip.h theos/osdep.h ziperr.h tailor.h crypt.c + $(CC) -c $(CFLAGS) $*.c + +theos.o: zip.h theos/osdep.h ziperr.h tailor.h theos/theos.c + $(CC) -c $(CFLAGS) -Fo$@ theos/theos.c + +_fprintf.o: theos/_fprintf.c + $(CC) -c $(CFLAGS) -Fo$@ theos/_fprintf.c + +_stat.o: theos/_stat.c + $(CC) -c $(CFLAGS) -Fo$@ theos/_stat.c + +_chmod.o: theos/_chmod.c + $(CC) -c $(CFLAGS) -Fo$@ theos/_chmod.c + +_isatty.o: theos/_isatty.c + $(CC) -c $(CFLAGS) -Fo$@ theos/_isatty.c + +_rename.o: theos/_rename.c + $(CC) -c $(CFLAGS) -Fo$@ theos/_rename.c + +_setargv.o: theos/_setargv.c + $(CC) -c $(CFLAGS) -Fo$@ theos/_setargv.c + +ttyio.o: zip.h theos/osdep.h ziperr.h tailor.h ttyio.h ttyio.c + $(CC) -c $(CFLAGS) $*.c + +zipcloak.o: zip.h theos/osdep.h ziperr.h tailor.h ttyio.h revision.h zipcloak.c + $(CC) -c $(CFLAGS) $*.c + +zipnote.o: zip.h theos/osdep.h ziperr.h tailor.h revision.h zipnote.c + $(CC) -c $(CFLAGS) $*.c + +zipsplit.o: zipsplit.c zip.h theos/osdep.h ziperr.h tailor.h revision.h + $(CC) -c $(CFLAGS) $*.c + +zipfile_.o: zipfile.c zip.h theos/osdep.h ziperr.h tailor.h + $(CC) -c $(UTILFLAGS)$@ zipfile.c + +fileio_.o: fileio.c zip.h theos/osdep.h ziperr.h tailor.h + $(CC) -c $(UTILFLAGS)$@ fileio.c + +theos_.o: zip.h theos/osdep.h ziperr.h tailor.h theos/theos.c + $(CC) -c $(UTILFLAGS)$@ theos/theos.c + +util_.o: util.c zip.h theos/osdep.h ziperr.h tailor.h + $(CC) -c $(UTILFLAGS)$@ util.c + +crypt_.o: zip.h theos/osdep.h ziperr.h tailor.h crypt.c + $(CC) -c $(UTILFLAGS)$@ crypt.c + +zip.command: $(OBJZ) $(OBJI) + $(LD) $@ $(OBJZ) $(OBJI) $(LDFLAGS) + +zipcloak.command: $(OBJC) + $(LD) $@ $(OBJC) $(LDFLAGS) + +zipnote.command: $(OBJN) + $(LD) $@ $(OBJN) $(LDFLAGS) + +zipsplit.command: $(OBJS) + $(LD) $@ $(OBJS) $(LDFLAGS) + +install: $(ZIPS) + copy *.command /system.cmd32.=(rep noq not + +clean: + erase *.o(noq not + erase *.command(noq not diff --git a/theos/README b/theos/README new file mode 100644 index 0000000..1ec99d3 --- /dev/null +++ b/theos/README @@ -0,0 +1,34 @@ +This Theos port supports all the unusual features of Theos filesystem. + +Under Theos filesystem files are typed. Types include : +- stream +- relative +- keyed +- indexed (ISAM) +- program (86 real mode, 16 bits protected mode, 32 bits protected mode) +- directory +- library (contains files of any other types librry and directory excepted). + +Most of the information on the type and on the structure of a file are not +contained in the file itself but its in directory entry. For all types of +files, directory and stream files excepted, this information is vital. If it +is lost, the file can no longer be usable. + +In zip files the information is stored in an extra block with type "Th". + +A few years ago I ported ZIP for internal use and spreaded it a little around +me. It was using a non portable extra block structure. Its type was "TH". +For backward compatibility it is supported by UNZIP 5.4.0 port to Theos. +ZIP archives created with ZIP 2.3 port MUST be unzipped with 5.4.0 or a later +version. + +Also disk search sequence is supported. The disk name is not stored into +the zip archive. + +Thanks to Bob Baker from Stockboy Services who spent his time to check this +port under other conditions than mines. + +Jean-Michel Dubois +IBC France / THEOS France +jmdubois@ibcfrance.fr +jean-michel-dubois@wanadoo.fr diff --git a/theos/_chmod.c b/theos/_chmod.c new file mode 100644 index 0000000..0937b45 --- /dev/null +++ b/theos/_chmod.c @@ -0,0 +1,21 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/* Change UNIX modes */ + +#pragma library + +#include + +int _chmod(const char *fname, short mask) +{ + extern char _um2tm_(short); + + return _filechange(fname,'p',(size_t) _um2tm_(mask)|0x80); +} + diff --git a/theos/_fprintf.c b/theos/_fprintf.c new file mode 100644 index 0000000..5c8c927 --- /dev/null +++ b/theos/_fprintf.c @@ -0,0 +1,26 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#include +#include + +/* for Info and similar macroes. fprintf is already a macro and fprintf x + * fools the preprocessor + */ + +int _fprintf(FILE* fp, const char* fmt, ...) +{ + va_list ap; + long n; + + va_start(ap, fmt); + n = vfprintf(fp, fmt, (long*) ap); + va_end(ap); + return n; +} + diff --git a/theos/_isatty.c b/theos/_isatty.c new file mode 100644 index 0000000..26f177b --- /dev/null +++ b/theos/_isatty.c @@ -0,0 +1,26 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/* replace standard library function who needs a FILE* */ + +#pragma library + +#include +#include +#include +#include + +short _isatty(int fd) +{ + register short lub; + + lub = (int) _fcntl(&stdin[fd], 5, (size_t) 0); + return (lub >= CONIN && lub <= CONOUT) + || (lub >= COM1 && lub <= COM4) + || (lub >= COM5 && lub <= COM16); +} diff --git a/theos/_rename.c b/theos/_rename.c new file mode 100644 index 0000000..04eb204 --- /dev/null +++ b/theos/_rename.c @@ -0,0 +1,83 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#include +#include +#include +#include + +#define EXDEV 590 + +#define _sys_rename() _sc_140() +extern unsigned short _sys_rename(const char _far *oldfn, char *newfn); + +/* rename a file. Report an error on cross disk renames */ + +static void _n_(const char* fn, char* bfn) +{ + if (*fn != '.' && *fn != '/') + strcpy(bfn, "./"); + else + *bfn = '\0'; + strcat(bfn, fn); +} + +int _rename(const char* old, const char* new) +{ + char* p; + char* q; + char* r; + char olddrv, newdrv; + char dir[FILENAME_MAX]; + short status; + char bold[FILENAME_MAX], bnew[FILENAME_MAX]; + + p = strrchr(old, ':'); + q = strrchr(new, ':'); + + /* if at least one path includes a disk name, check for equality */ + if (p != NULL || q != NULL) { + /* getcwd return a NULL pointer for /:S */ + getcwd(dir, FILENAME_MAX); + r = strrchr(dir, ':'); + + if (p == NULL) + p = r; + olddrv = p ? p[1] : 'S'; + + if (q == NULL) + q = r; + newdrv = q ? q[1] : 'S'; + + /* return an error if uppercased disk names are not the same */ + if ((old & ~0x20) != (new & ~0x20)) { + _errarg = NULL; + return errno = _errnum = EXDEV; + } + } + /* prepend ./ if there is no path to force rename to work on files + * in the current directory instead of default library + */ + _n_(old, bold); + _n_(new, bnew); + + status = _sys_rename(bold, bnew); + /* can be : + * 0 no error + * 19 "old" file not found + * 44 "new" file already exist + * 45 "new" filename missing + * 46 "old" file name missing + */ + if (status) { + errno = _errnum = status; + _errarg = (status == 44 || status == 45) ? new : old; + } + + return status; +} diff --git a/theos/_setargv.c b/theos/_setargv.c new file mode 100644 index 0000000..d76f955 --- /dev/null +++ b/theos/_setargv.c @@ -0,0 +1,140 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/* + * __setargv.c - command argument expander + * + * Author : Jean-Michel Dubois + * Date : 09/26/92 + * + * Function: Expands the command line arguments by replacing any filename + * including wilcards by the sorted list of matching files name. + * Strings beginning by a dash are considered as options and left + * unchanged. + * + * Syntax : void _setargv(int *argc, char ***argv); + * + * Returns : new argc. Caller's argc and argv are updated. + * If a insufficient memory condition occurs, return 0 and errno + * is set to ENOMEM. + * + * Example : + * main(int argc, char **argv) + * { + * if (_setargv(&argc, &argv)) { + * ... + */ +#pragma library + +#include +#include +#include +#include +#include +#include +#include + +/* Allocate argv array in 16 entries chunks */ + +static int allocarg(int n, int l, char ***nargv, char *s) +{ + if ((n+1) > l) { /* If array full */ + l += 16; /* increase size and reallocate */ + if (!(*nargv = (char **) realloc(*nargv,l * sizeof (void *)))) { + errno = _errnum = ENOMEM; /* Not enough memory */ + return 0; + } + } + (*nargv)[n] = strdup(s); /* Save argument */ + return l; /* Return new maxsize */ +} + +/* Comparison function for qsort */ + +static int sortcmp(char **p, char **q) +{ + return stricmp(*p,*q); +} + +/* Main body of the function */ + +int _setargv(int *argc, char ***argv) +{ + register int nargc; /* New arguments counter */ + char **nargv; /* New arguments pointers */ + register int i, l, base; + char *p, *q, *r; + char path[FILENAME_MAX]; + + _errnum = 0; + nargc = 0; /* Initialise counter, size counter */ + l = *argc; /* and new argument vector to the */ + /* current argv array size */ + + if ((nargv = (char **) calloc((size_t) *argc, sizeof (void *))) != NULL) { + /* For each initial argument */ + for (i = 0; i < *argc; i++) { + q = (*argv)[i]; + if (q[0] == '-' || ! testwild(q)) { + /* if it begins with a dash or doesnt include + * wildcard simply add it to the new array + */ + if (! (l = allocarg(nargc, l, &nargv, q))) + return 0; /* Not enough memory */ + nargc++; + } else { + /* else keep current counter for qsort */ + base = nargc; + /* open directory with argument */ + diropen(q); + while ((r = dirread()) != NULL) { + /* reduce path to given one */ + if ((p = strrchr(q, '/')) != NULL) { + strncpy(path, q, p-q+1); + path[p-q+1] = '\0'; + } else + path[0] = '\0'; + + if ((p = strrchr(r, '/')) != NULL) + strcat(path, p+1); + else + strcat(path, r); + + if (peekscr(&SCR->searchseq[1]) == 255 + && strchr(q, ':') == NULL) { + *strchr(path, ':') = '\0'; + } + /* and add each matching filename. */ + if (! (l = allocarg(nargc,l,&nargv,path))) + return 0;/* Not enough memory */ + nargc++; + } + if (nargc == base) { + /* if no match found include wild card name */ + if (! (l = allocarg(nargc, l, &nargv, q))) + return 0; /* Not enough memory */ + nargc++; + } else if ((nargc - base) > 1) + /* If more than one file name matchs */ + /* sort arguments. */ + qsort(&(nargv[base]),(size_t)nargc-base, + sizeof(void *),sortcmp); + dirclose(); + } + } + /* Update caller's parameters */ + *argc = nargc; + *argv = nargv; + /* and sign on success */ + return nargc; + } + + /* If it is not possible to allocate initial array, sign on error */ + _errnum = ENOMEM; + return 0; +} diff --git a/theos/_stat.c b/theos/_stat.c new file mode 100644 index 0000000..6855d28 --- /dev/null +++ b/theos/_stat.c @@ -0,0 +1,461 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#pragma library +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "theos/stat.h" + +/* replacement for standard library functions stat and fstat */ + +int _stat_(struct stat* st, struct fdb* fdb); +int _dstat_(struct stat* st); + +#define peekucb() peeknuc() + +/* map THEOS protection code to Unix modes */ + +unsigned short _tm2um_(char protect) +{ + unsigned short umask = 0; + + if (!(protect & _FDB_READ_PROTECT)) + umask = S_IRUSR|S_IRGRP; + + if (!(protect & _FDB_WRITE_PROTECT)) + umask |= S_IWUSR|S_IWGRP; + + if (!(protect & _FDB_EXECUTE_PROTECT)) + umask |= S_IXUSR|S_IXGRP; + + if (!(protect & _FDB_ERASE_PROTECT)) + umask |= S_IEUSR|S_IEGRP; + + if (!(protect & _FDB_SHARED_READ_PROTECT)) { + if (_osmajor > 3) + umask |= S_IROTH|S_IXOTH; + else + umask |= S_IROTH; + } + + if (!(protect & _FDB_SHARED_WRITE_PROTECT)) + umask |= S_IWOTH; + + if (!(protect & _FDB_MODIFIED)) { + if (_osmajor > 3) + umask |= S_IMODF; + else + umask |= S_IXOTH; + } + + if (protect & _FDB_NOT_HIDDEN) + umask |= S_INHID; + + return umask; +} + +/* map Unix modes to THEOS protections */ + +char _um2tm_(unsigned short mask) +{ + char protect = 0; + + if (!(mask & (S_IRUSR|S_IRGRP))) + protect |= _FDB_READ_PROTECT; + + if (!(mask & (S_IWUSR|S_IWGRP))) + protect |= _FDB_WRITE_PROTECT; + + if (!(mask & (S_IXUSR|S_IXGRP))) + protect |= _FDB_EXECUTE_PROTECT; + + if (!(mask & (S_IEUSR|S_IEGRP))) + protect |= _FDB_ERASE_PROTECT; + + if (_osmajor < 4) { + if (!(mask & S_IROTH)) + protect |= _FDB_SHARED_READ_PROTECT; + } else { + if (!(mask & (S_IROTH|S_IXOTH))) + protect |= _FDB_SHARED_READ_PROTECT; + } + + if (!(mask & S_IWOTH)) + protect |= _FDB_SHARED_WRITE_PROTECT; + + if (mask & S_IMODF && _osmajor > 3) + protect |= _FDB_MODIFIED; + + if (mask & S_INHID && _osmajor > 3) + protect |= _FDB_NOT_HIDDEN; + + return protect; +} + +/* root directory stat */ + +static int rdirstat(const char* fn, struct stat *st) +{ + register char* p = strchr(fn, ':'); + char drive; + + drive = p ? p[1] : 'S'; + + if (drive >= 'a' && drive <= 'Z') + drive -= 0x40; + + memset(st, 0, sizeof(struct stat)); + + if (getlub(drive - 'A') != 255) { + st->st_org = _FDB_STAT_DIRECTORY; + st->st_mode = S_IFDIR|S_IRUSR|S_IWUSR|S_IROTH|S_IWOTH; + st->st_nlink = 1; + st->st_dev = st->st_rdev = drive - 'A'; + st->st_uid = st->st_gid = getuid(); + st->st_protect = _FDB_ERASE_PROTECT; + return 0; + } + errno = _errnum = ENOENT; + _errarg = fn; + return -1; +} + +#ifdef LOCATE_BUG + +/* locate fails when stating a file in root dir from a directory with a + * relative path. Workaround by setting directory to root dir + * getting the file directory block, then restoring the current directory. + */ + +struct fdb* __locate(const char* fn, char* buf, short* drv) +{ + struct fdb* fdb; + char buf2[FILENAME_MAX]; + char cwd[FILENAME_MAX]; + char drive[3]; + char* p; + char* q; + + /* return if file found */ + if (fdb = _locate(fn, buf, drv)) + return fdb; + + /* if file name does not contain a path delimiter it really does not exist. + */ + strcpy(buf2, fn); + + if ((p = strrchr(buf2, '/')) == NULL) + return NULL; + + /* get drive name from file path */ + q = strrchr(buf2, ':'); + + /* cat drive name if any to directory path */ + if (q) { + strncpy(drive, q, 2); + drive[2] = '\0'; + strcpy(p, q); + } else + *p = '\0'; + /* save current directory */ + getcwd(cwd, FILENAME_MAX); + /* chdir to directory path */ + chdir(buf2); + /* get File Directory Block */ + p = strrchr(fn, '/'); + fdb = _locate(p + 1, buf, drv); + /* restore current directory */ + chdir(cwd); + return fdb; +} + +#undef _locate +#define _locate() __locate() + +/* same cause, same consequence for fopen and open. +*/ + +FILE* _fopen(const char* fn, const char* mode) +{ + FILE* fp; + char buf[FILENAME_MAX]; + short drv; + + /* prepend a path to current dir to avoid use of default library */ + if (*fn != '.' && *fn != '/') { + strcpy(buf, "./"); + strcat(buf, fn); + return fopen(buf, mode); + } + + if (fp = fopen(fn, mode)) + return fp; + + /* see comment for _locate */ + if (_locate(fn, buf, &drv)) { + fn = strrchr(fn, '/'); + return fopen(fn, mode); + } + return NULL; +} + +#undef open +int open(const char*, int, ...); + +int __open(const char* fn, int mode) +{ + int fd; + char buf[FILENAME_MAX]; + short drv; + + /* prepend a path to current dir to avoid use of default library */ + if (*fn != '.' && *fn != '/') { + strcpy(buf, "./"); + strcat(buf, fn); + return open(buf, mode); + } + + if ((fd = open(fn, mode)) != EOF) + return fd; + + /* see comment for _locate */ + if (_locate(fn, buf, &drv)) { + fn = strrchr(fn, '/'); + if (fn) + return open(fn, mode); + } + return EOF; +} +#endif + +/* replacement for standard file stat */ + +int _stat(const char *_fn, struct stat *st) +{ + char buf[FILENAME_MAX], buf2[FILENAME_MAX], buf3[FILENAME_MAX]; + register struct fdb* fdb; + register char* p; + register char* fn; + + fn = strcpy(buf3, _fn); + + if (p = strrchr(fn, ':')) + *p = 0; + + /* on current drive ./:d and .:m point to current dir + * on another drive to root directory, workaround to avoid it */ + + if (! strcmp(fn, "/") || ! strcmp(fn, ".") || ! strcmp(fn, "./")) { + if (p == NULL) { + /* current dir on current drive */ + fn = getcwd(buf2, FILENAME_MAX); + /* getcwd returns NULL on root dir on drive S */ + if (fn == NULL) + fn = strcpy(buf2, "/:S"); + /* getcwd returns /:d on root dir on any other drive */ + if (fn[1] == ':') + return rdirstat(fn, st); + } else { + *p = ':'; + return rdirstat(fn, st); + } + if (p) + *p = ':'; + } else { + if (p) + *p = ':'; + if (*fn != '.' && *fn != '/') { + strcpy(buf2, "./"); + fn = strcat(buf2, fn); + } + } + + if (buf2 != fn) + strcpy(buf2, fn); + /* remove trailing slash before optional disk name */ + if (p = strrchr(buf2, '/')) { + if (p[1] == ':') { + *p = p[1]; + p[1] = p[2]; + p[2] = p[3]; + } else if (p[1] == '\0') + *p = '\0'; + } + /* if fn is a file get file directory block structure and device */ + if (fdb = _locate(buf2, buf, &st->st_dev)) { + /* is it a file from another user... */ + if (strchr(buf2, '\\') + /* a public system file... */ + || fdb->fileowner == 0 + /* or a file from the current user account ? */ + || fdb->fileowner == getuid()) + /* yes, return stat */ + return _stat_(st, fdb); + else { + /* no, say file doesn't exist */ + errno = _errnum = ENOENT; + _errarg = fn; + return -1; + } + } + /* else should be a device, get device number from device name */ + st->st_rdev = st->st_dev = _lub_name(*fn == ':' ? fn+1 : fn); + /* if it is really a device return device status */ + if (st->st_dev != -1 && getlub(st->st_dev) != 255) + return _dstat_(st); + /* neither an existing file or a device name, return EOF */ + st->st_rdev = st->st_dev = 0; + errno = _errnum = ENOENT; + _errarg = fn; + return -1; +} + +/* replacement for fstat */ + +int _fstat(int fd, struct stat *st) +{ + unsigned short fsanum; + struct fsa fsa; + register FILE *fp; + int status; + register int i; + register char *p; + + if (fd < FOPEN_MAX) { + fp = &stdin[fd]; + /* get File Save Area number */ + if (_fcntl(fp,1,0) & 0x80) { + fsanum = (unsigned short) _fcntl(fp,83,0); + st->st_dev = (unsigned short) _fcntl(fp,5,0); + + if (st->st_dev >= A_DISK && st->st_dev <= Z_DISK) { + /* if opened file is a disk file */ + /* copy far fsa in protected segment to local fsa */ + for (i = 0, fsanum *= sizeof(fsa), p = (char *) &fsa; + i < (sizeof(fsa)); + i++, fsanum++, p++) + *p = _peekfsa((char *) fsanum); + /* build stat structure from fsa */ + status = _stat_(st, (struct fdb*) &fsa); + /* get blocksize */ + if ((st->st_blksize = _fcntl(fp,817,0)) == 0) + st->st_blksize = BUFSIZ; + return status; + } + /* return device status */ + return _dstat_(st); + } + } + errno = _errnum = EBADF; + return -1; +} + +static int _isprt(int dev) +{ + return IS_PRT_LUB(dev); +} + +/* device stat */ + +int _dstat_(st) +register struct stat* st; +{ + register struct ucb* ucb; + + ucb = getucb(st->st_dev); + st->st_ino = 0; + if (st->st_dev <= Z_DISK + || (st->st_dev >= TAPE1 && st->st_dev <= TAPE4)) { + st->st_mode = S_IFBLK | S_IWUSR | S_IRUSR; + if (peekucb(&ucb->devowner) == 255) + st->st_mode |= S_IWGRP | S_IWOTH | S_IRGRP | S_IROTH; + } else { + st->st_mode = S_IFCHR | S_IWUSR; + if (_isprt(st->st_dev)) + st->st_mode |= S_IRUSR; + if (peekucb(&ucb->devowner) == 255) { + st->st_mode |= S_IWGRP | S_IWOTH; + if (_isprt(st->st_dev)) + st->st_mode |= S_IRGRP | S_IROTH; + } + } + st->st_nlink = 1; + st->st_uid = st->st_gid = getuid(); + st->st_size = 0; + st->st_atime = st->st_mtime = st->st_ctime = 0; + st->st_rlen = 0; + st->st_klen = 0; + st->st_grow = 0; + st->st_blksize = 0; + return 0; +} + +/* regular file stat */ + +int _stat_(st, fdb) +register struct stat* st; +register struct fdb* fdb; +{ + st->st_rdev = st->st_dev; + st->st_ino = 0; + st->st_org = fdb->filestat; + + /* map fdb file status to stat mode */ + switch (fdb->filestat) { + case _FDB_STAT_LIBRARY: st->st_mode = S_IFLIB; break; + case _FDB_STAT_DIRECTORY: st->st_mode = S_IFDIR; break; + case _FDB_STAT_STREAM: st->st_mode = S_IFREG; break; + case _FDB_STAT_RELATIVE: st->st_mode = S_IFREL; break; + case _FDB_STAT_KEYED: st->st_mode = S_IFKEY; break; + case _FDB_STAT_INDEXED: st->st_mode = S_IFIND; break; + case _FDB_STAT_RANDOM: st->st_mode = S_IFRND; break; + case _FDB_STAT_PROGRAM: st->st_mode = S_IFR16; break; + case _FDB_STAT_16_BIT_PROGRAM: st->st_mode = S_IFP16; break; + case _FDB_STAT_32_BIT_PROGRAM: st->st_mode = S_IFP32; break; + } + + /* map theos file protection codes to stat mode */ + st->st_mode |= _tm2um_(st->st_protect = fdb->protect); + st->st_nlink = 1; + st->st_uid = st->st_gid = fdb->fileowner; + st->st_size = fdb->filesize; + st->st_atime = st->st_mtime = st->st_ctime = getfiledate(fdb); + st->st_blksize = 0; + /* specific theos information */ + st->st_rlen = fdb->reclen; + st->st_klen = fdb->keylen; + st->st_grow = fdb->filegrow; + return 0; +} + +#include + +/* standard diropen fails on path endung with a '/', workaround */ + +struct dirent* _opendir(const char* dirpath) +{ + int l; + char dirp[FILENAME_MAX]; + struct dirent* dir; + + if (dirpath && (l = strlen(dirpath))) { + if (dirpath[l - 1] == '/') { + strcpy(dirp, dirpath); + dirp[l - 1] = '\0'; + return opendir(dirp); + } + } + return opendir(dirpath); +} diff --git a/theos/charconv.h b/theos/charconv.h new file mode 100644 index 0000000..a2d8dfa --- /dev/null +++ b/theos/charconv.h @@ -0,0 +1,93 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ + +#ifdef IZ_THS2ISO_ARRAY +ZCONST uch Far ths2iso[] = { + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 80 - 87 */ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 88 - 8F */ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 90 - 97 */ + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* 98 - 9F */ + 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, /* A0 - A7 */ + 0x2B, 0x2D, 0x7C, 0x2B, 0x2B, 0x2B, 0x2B, 0x23, /* A8 - AF */ + 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, /* B0 - B7 */ + 0x3D, 0x23, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, /* B8 - BF */ + 0xC4, 0xE4, 0xE2, 0xE0, 0xE1, 0xC9, 0xEB, 0xEA, /* C0 - C7 */ + 0xE8, 0xE9, 0xEF, 0xEE, 0xEC, 0xED, 0xD6, 0xF6, /* C8 - CF */ + 0xF4, 0xF2, 0xF3, 0xDC, 0xFC, 0xFB, 0xF9, 0xFA, /* D0 - D7 */ + 0xC7, 0xE7, 0xD1, 0xF1, 0xC6, 0xE6, 0xC5, 0xE5, /* D8 - DF */ + 0xDF, 0xBF, 0xA1, 0xA2, 0xA3, 0xA5, 0xB5, 0xA4, /* E0 - E7 */ + 0xBC, 0xBD, 0xFF, 0xA7, 0xB0, 0xB2, 0x20, 0x20, /* E8 - EF */ + 0x20, 0xB1, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, /* F0 - F7 */ + 0x20, 0x20, 0xB7, 0x20, 0x20, 0x20, 0x20, 0x20 /* F8 - FF */ +}; +#endif /* IZ_THS2ISO_ARRAY */ + +#ifdef IZ_THS2OEM_ARRAY +ZCONST uch Far ths2oem[] = { + 254,254,254,254, 254,254,134,135, /* 80 - 87 */ + 136,137,138,139, 140,141,142,143, /* 88 - 8F */ + 144,145,146,147, 148,149,150,151, /* 90 - 97 */ + 152,153,154,155, 156,157,158,159, /* 98 - 9F */ + 218,191,217,192, 197,195,180,194, /* A0 - A7 */ + 193,196,179,218, 191,217,192,201, /* A8 - AF */ + 183,188,200,206, 199,182,203,202, /* B0 - B7 */ + 205,186,186,187, 188,189,190,191, /* B8 - BF */ + 142,132,131,133, 160,144,137,136, /* C0 - C7 */ + 138,130,139,140, 141,161,153,148, /* C8 - CF */ + 147,149,162,154, 129,150,151,163, /* D0 - D7 */ + 128,135,165,164, 146,145,143,134, /* D8 - DF */ + 225,168,173,155, 156,157,158, 31, /* E0 - E7 */ + 172,171,152, 21, 248,253,238,239, /* E8 - EF */ + 240,241,242,243, 244,245,246,247, /* F0 - F7 */ + 248,249,250,251, 252,253,254,255 /* F8 - FF */ +}; +#endif /* IZ_THS2OEM_ARRAY */ + +#ifdef IZ_ISO2THS_ARRAY +ZCONST uch Far iso2ths[] = { + 0x3F, 0x3F, 0x27, 0x3F, 0x22, 0x2E, 0xA4, 0xB3, /* 80 - 87 */ + 0x5E, 0x25, 0x53, 0x3C, 0x4F, 0x3F, 0x3F, 0x3F, /* 88 - 8F */ + 0x3F, 0x27, 0x27, 0x22, 0x22, 0x07, 0x2D, 0x2D, /* 90 - 97 */ + 0x7E, 0x54, 0x73, 0x3E, 0x6F, 0x3F, 0x3F, 0x59, /* 98 - 9F */ + 0x20, 0xE2, 0xE3, 0xE4, 0xE7, 0xE5, 0x7C, 0xEB, /* A0 - A7 */ + 0x20, 0x20, 0x20, 0x22, 0x20, 0x2D, 0x20, 0x2D, /* A8 - AF */ + 0xEC, 0xF1, 0xED, 0x20, 0x20, 0xE6, 0x20, 0xFA, /* B0 - B7 */ + 0x20, 0x20, 0x20, 0x22, 0xE8, 0xE9, 0x20, 0xE1, /* B8 - BF */ + 0xC3, 0xC4, 0xC2, 0x41, 0xC0, 0xDE, 0xDC, 0xD8, /* C0 - C7 */ + 0xC8, 0xC5, 0xC7, 0xC6, 0xCC, 0xCD, 0xCB, 0xCA, /* C8 - CF */ + 0x44, 0xDA, 0xD1, 0xD2, 0xD0, 0x4F, 0xCE, 0x78, /* D0 - D7 */ + 0x4F, 0xD6, 0xD7, 0xD5, 0xD3, 0x59, 0x20, 0xE0, /* D8 - DF */ + 0xC3, 0xC4, 0xC2, 0x61, 0xC1, 0xDF, 0xDD, 0xD9, /* E0 - E7 */ + 0xC8, 0xC9, 0xC7, 0xC6, 0xCC, 0xCD, 0xCB, 0xCA, /* E8 - EF */ + 0x64, 0xDB, 0xD1, 0xD2, 0xD0, 0x4F, 0xCF, 0xF1, /* F0 - F7 */ + 0x6F, 0xD6, 0xD7, 0xD5, 0xD4, 0x79, 0x20, 0xEA /* F8 - FF */ +}; +#endif /* IZ_ISO2THS_ARRAY */ + +#ifdef IZ_OEM2THS_ARRAY +ZCONST uch Far oem2ths[] = { + 216,212,201,194, 193,195,223,217, /* 80 - 87 */ + 199,198,200,202, 203,204,192,222, /* 88 - 8F */ + 197,221,220,208, 207,209,213,214, /* 90 - 97 */ + 234,206,211,227, 228,229,230,159, /* 98 - 9F */ + 196,205,210,215, 219,218,254,254, /* A0 - A7 */ + 225,254,254,233, 232,226, 34, 34, /* A8 - AF */ + 254,254,254,170, 166,166,181,176, /* B0 - B7 */ + 161,181,185,176, 177,177,162,161, /* B8 - BF */ + 163,168,167,165, 169,164,165,180, /* C0 - C7 */ + 178,175,183,182, 180,184,179,168, /* C8 - CF */ + 183,167,182,178, 163,160,175,179, /* D0 - D7 */ + 164,162,160,254, 254,254,254,254, /* D8 - DF */ + 254,224,254,254, 254,254,254, 31, /* E0 - E7 */ + 254,254,254, 21, 254,254,238,239, /* E8 - EF */ + 240,241,242,243, 244,245,246,247, /* F0 - F7 */ + 236,249,250,251, 252,237,254,255 /* F8 - FF */ +}; +#endif /* IZ_OEM2THS_ARRAY */ + diff --git a/theos/osdep.h b/theos/osdep.h new file mode 100644 index 0000000..4f4857e --- /dev/null +++ b/theos/osdep.h @@ -0,0 +1,58 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/* + * XXX this should somehow depend on the stuff in revision.h + */ +#pragma prog 2.3,0,0,0 + +/* use argument expansion */ +#if !defined(UTIL) && !defined(MAINWA_BUG) +# pragma wild argv +#endif + +#include +#include +#include +#include > +#include +#include +#include "theos/stat.h" /* use JMD's extended stat function */ + +#define isatty() _isatty() /* THEOS isatty uses a FILE* instead of a fd */ +int _isatty(int fd); + +#define deletedir(d) rmdir(d) + +/* will come later */ +#if 0 +#define USE_EF_UT_TIME /* Enable use of "UT" extra field time info */ +#endif + +#if DEBUG +int _fprintf(FILE* fp, const char* fmt, ...); +#endif + +/* for rename() replacement. Standard function is bugged */ + +int _rename(const char* old, const char* new); +#define rename(a,b) _rename(a,b) + +#ifdef LOCATE_BUG +/* for fopen replacement. Standard function fails on relative path pointing + * to root directory. + */ +#undef _fopen +#undef open +#define fopen() _fopen() +FILE* _fopen(const char*, const char*); +#define open() __open() +FILE* __open(const char*, int); +#endif + +#define EXDEV 10000 diff --git a/theos/stat.h b/theos/stat.h new file mode 100644 index 0000000..3a716f8 --- /dev/null +++ b/theos/stat.h @@ -0,0 +1,106 @@ +#ifndef __theos_stat_h +#define __theos_stat_h +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ + +/* extended stat structure for stat, fstat, chmod */ +/* Written by Jean-Michel Dubois */ + +#pragma field word +struct stat { + unsigned short st_mode; /* file attributes */ + #define S_IFMT 0xf000 /* file type mask */ + #define S_IFIFO 0x1000 /* pipe */ + #define S_IFCHR 0x2000 /* char device */ + #define S_IFSOCK 0x3000 /* socket */ + #define S_IFDIR 0x4000 /* directory */ + #define S_IFLIB 0x5000 /* library */ + #define S_IFBLK 0x6000 /* block device */ + #define S_IFREG 0x8000 /* regular file */ + #define S_IFREL 0x9000 /* relative (direct) */ + #define S_IFKEY 0xA000 /* keyed */ + #define S_IFIND 0xB000 /* indexed */ + #define S_IFRND 0xC000 /* ???? */ + #define S_IFR16 0xD000 /* 16 bit real mode program */ + #define S_IFP16 0xE000 /* 16 bit protected mode prog */ + #define S_IFP32 0xF000 /* 32 bit protected mode prog */ + + #define S_ISUID 0x0800 /* meaningless */ + #define S_ISGID 0x0400 /* meaningless */ + #define S_ISVTX 0x0200 /* meaningless */ + + #define S_IMODF 0x0800 /* modified */ + #define S_INHID 0x0400 /* not hidden */ + + #define S_IRWXU 0x03c0 /* read,write,execute: owner */ + #define S_IEUSR 0x0200 /* erase permission: owner */ + #define S_IRUSR 0x0100 /* read permission: owner */ + #define S_IWUSR 0x0080 /* write permission: owner */ + #define S_IXUSR 0x0040 /* execute permission: owner */ + /* group permissions */ + #define S_IRWXG 0x0238 + #define S_IEGRP 0x0200 + #define S_IRGRP 0x0020 + #define S_IWGRP 0x0010 + #define S_IXGRP 0x0008 + /* other never has erase permission */ + #define S_IRWXO 0x0207 /* read,write,execute: other */ + #define S_IROTH 0x0004 /* read permission: other */ + #define S_IWOTH 0x0002 /* write permission: other */ + #define S_IXOTH 0x0001 /* execute permission: other */ + + #define S_IREAD 0x0100 /* read permission, owner */ + #define S_IEXEC 0x0040 /* execute permission, owner */ + #define S_IWRITE 0x0080 /* write permission, owner */ + short st_ino; /* not used */ + short st_dev; /* not used */ + short st_rdev; /* not used */ + short st_nlink; /* not used */ + short st_uid; /* owner id */ + short st_gid; /* not used */ + unsigned long st_size; /* size of file */ + unsigned long st_atime; /* not used */ + unsigned long st_mtime; /* date & time last modified */ + unsigned long st_ctime; /* not used */ + unsigned long st_blksize; /* buffer size */ + unsigned short st_org; /* organization */ + unsigned short st_rlen; /* record size */ + unsigned short st_klen; /* key size */ + char st_grow; /* growing factor */ + char st_protect; /* native protections */ +}; +#pragma field + +#define S_ISREG(m) (((m) & S_IFMT) >= S_IFREG) +#define S_ISLIB(m) (((m) & S_IFMT) == S_IFLIB) +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) + +#define S_ISSEQ(m) (((m) & S_IFMT) == S_IFREG) +#define S_ISREL(m) (((m) & S_IFMT) == S_IFREL) +#define S_ISKEY(m) (((m) & S_IFMT) == S_IFKEY) +#define S_ISIND(m) (((m) & S_IFMT) == S_IFIND) +#define S_ISPRG(m) (((m) & S_IFMT) >= S_IFP16) +#define S_ISLNK(m) 0 + +/* avoid conflict with original THEOS functions */ + +#define stat(a,b) _stat(a,b) +#define fstat(a,b) _fstat(a,b) +#define chmod(a,b) _chmod(a,b) + +extern int _stat(const char *file, struct stat *statptr); +extern int _fstat(int fd, struct stat *statptr); +extern int _chmod(const char *file, short mask); + +#define _chstat(a,b) ((int) _sc_168(a,'p',(size_t)(b))) +extern unsigned short _sc_168(const char _far *fn, int cmd, size_t value); + +#endif /* !__theos_stat_h */ diff --git a/theos/theos.c b/theos/theos.c new file mode 100644 index 0000000..17db108 --- /dev/null +++ b/theos/theos.c @@ -0,0 +1,558 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2004-May-22 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/*--------------------------------------------------------------------------- + + theos.c (zip) + + Contribution by Jean-Michel Dubois. 20-Jun-1995, 20-Dec-98 + + THEOS specific extra informations + + ---------------------------------------------------------------------------*/ + + +#include + +#ifndef UTIL + +#include "zip.h" + +#include +#include +#include +#include +#include +#include + +#define opendir(a) _opendir(a) +extern struct dirent* _opendir(char* fname); + +#define PAD 0 + +#define RET_ERROR 1 +#define RET_SUCCESS 0 +#define RET_EOF 0 + +extern char *label; +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +/* match from Phase One Systems */ + +int match(char *s, char *p) /*S Returns non-zero if string matches + the literal mask */ +{ + int matched, k; + + if (!(*p)) + return 1; + for(;;) { + if ( (!(*s)) && (!(*p)) ) + return(1); + else if ( !(*p) ) + return(0); + else if (*p == '*') { + if (!*(p+1)) + return(1); + k=0; + do { + matched = match(s+k,p+1); + k++; + } while ( (!matched) && *(s+k)); + return(matched); + } else if (*p == '@') { + if (!((*s >= 'a' && *s <= 'z') + ||(*s >= 'A' && *s <= 'Z'))) + return(0); + } else if (*p == '#') { + if (*s < '0' || *s > '9') + return(0); + } else if (*p != '?') { + if (tolower(*s) != tolower(*p)) + return(0); + } + s++; p++; + } +} + +local char *readd(d) +DIR *d; /* directory stream to read from */ +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e; + + e = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; +} + +/* check if file is a member of a library */ + +int ismember(char* path) +{ + char* p; + + if ((p = strrchr(path, '/')) == NULL) + p = path; + return ((p = strchr(p, '.')) && (p = strchr(p + 1, '.'))); +} + +/* extract library name from a file name */ + +char* libname(char* path) +{ + char* p; + static char lib[FILENAME_MAX]; + char drive[3]; + + strcpy(lib, path); + if (p = strrchr(lib, ':')) { + strncpy(drive, p, 2); + drive[2] = '\0'; + *p = '\0' ; + } else + drive[0] = '\0'; + + if ((p = strrchr(lib, '/')) == NULL) + p = lib; + + p = strchr(p, '.'); + p = strchr(p + 1, '.'); + *p = 0; + strcat(lib, drive); + return lib; +} + +int procname(n, caseflag) +char *n; /* name to process */ +int caseflag; /* true to force case-sensitive match */ +/* Process a name or sh expression to operate on (or exclude). Return + an error code in the ZE_ class. */ +{ + char *a; /* path and name for recursion */ + DIR *d; /* directory stream from opendir() */ + char *e; /* pointer to name from readd() */ + int m; /* matched flag */ + char *p; /* path for recursion */ + struct stat s; /* result of stat() */ + struct zlist *z; /* steps through zfiles list */ + struct flist *f; /* steps through files list */ + char* path; /* full name */ + char drive[3]; /* drive name */ + int recursion; /* save recurse flag */ + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0, caseflag); + else if (LSSTAT(n, &s)) { + /* Not a file or directory--search for shell expression in zip file */ + p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */ + m = 1; + for (z = zfiles; z != NULL; z = z->nxt) { + if (match(z->iname, p)) + { + z->mark = pcount ? filter(z->zname, caseflag) : 1; + if (verbose) + fprintf(mesg, "zip diagnostic: %scluding %s\n", + z->mark ? "in" : "ex", z->name); + m = 0; + } + } + free((zvoid *)p); + return m ? ZE_MISS : ZE_OK; + } + + /* Live name--use if file, recurse if directory or library */ + if (S_ISREG(s.st_mode)) { + if ((path = malloc(strlen(n) + 2)) == NULL) + return ZE_MEM; + + strcpy(path, n); + + /* if member name, include library name before any member name */ + if (ismember(path)) { + strcpy(path, libname(path)); + /* mask recursion flag to avoid endless loop recursion + * if -r is used with member names + */ + recursion = recurse; + recurse = FALSE; + if ((m = procname(path, caseflag)) != ZE_OK) /* recurse on name */ + { + if (m == ZE_MISS) + zipwarn("name not matched: ", path); + else + ziperr(m, a); + } + /* restore recursion flag */ + recurse = recursion; + } + + strcpy(path, n); + + if ((p = strchr(path, ':')) != NULL) { + p[2] = '\0'; + strcpy(drive, p); + } else + drive[0] = '\0'; + + /* remove trailing dot in flat file name */ + p = strend(path) - 1; + if (*p == '.') + *p = '\0'; + + strcat(path, drive); + /* add or remove name of file */ + if ((m = newname(path, 0, caseflag)) != ZE_OK) { + free(path); + return m; + } + free(path); + } else if (S_ISLIB(s.st_mode)) { + if ((path = malloc(strlen(n) + 2)) == NULL) + return ZE_MEM; + + strcpy(path, n); + + if ((p = strchr(path, ':')) != NULL) { + p[2] = '\0'; + strcpy(drive, p); + } else + drive[0] = '\0'; + + /* add a trailing dot in flat file name... */ + p = strend(path) - 1; + if (*p != '/') + strcat(path, "/"); + p = strend(path); + /* ... then add drive name */ + strcpy(p, drive); + + /* don't include the library name twice... or more */ + for (f = found; f != NULL; f = f->nxt) { + if (! stricmp(path, f->name)) { + free(path); + return ZE_OK; + } + } + /* add or remove name of library */ + if ((m = newname(path, 0, caseflag)) != ZE_OK) { + free(path); + return m; + } + /* recurse into library if required */ + strcpy(p - 1, ".*"); + strcat(p, drive); + if (recurse && diropen(path) == 0) + { + while ((e = dirread()) != NULL) { + if (strcmp(e, ".") && strcmp(e, "..")) + { + if (*drive == '\0') + *strchr(e, ':') = '\0'; + if ((a = malloc(strlen(e) + 1)) == NULL) + { + dirclose(); + free((zvoid *)p); + return ZE_MEM; + } + strcpy(a, e); + if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */ + { + if (m == ZE_MISS) + zipwarn("name not matched: ", a); + else + ziperr(m, a); + } + free((zvoid *)a); + } + } + dirclose(); + } + free(path); + } else { + /* Add trailing / to the directory name */ + if ((p = malloc(strlen(n)+2)) == NULL) + return ZE_MEM; + if (strcmp(n, ".") == 0) { + *p = '\0'; /* avoid "./" prefix and do not create zip entry */ + } else { + strcpy(p, n); + a = p + strlen(p); + if (a[-1] != '/') + strcpy(a, "/"); + if (dirnames && (m = newname(p, 1, caseflag)) != ZE_OK) { + free((zvoid *)p); + return m; + } + } + /* recurse into directory */ + if (recurse && (d = opendir(n)) != NULL) + { + while ((e = readd(d)) != NULL) { + if (strcmp(e, ".") && strcmp(e, "..")) + { + if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL) + { + closedir(d); + free((zvoid *)p); + return ZE_MEM; + } + strcat(strcpy(a, p), e); + if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */ + { + if (m == ZE_MISS) + zipwarn("name not matched: ", a); + else + ziperr(m, a); + } + free((zvoid *)a); + } + } + closedir(d); + } + free((zvoid *)p); + } + return ZE_OK; +} + +char *ex2in(x, isdir, pdosflag) +char *x; /* external file name */ +int isdir; /* input: x is a directory */ +int *pdosflag; /* output: force MSDOS file attributes? */ +/* Convert the external file name to a zip file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *n; /* internal file name (malloc'ed) */ + char *t; /* shortened name */ + char *p; + int dosflag; + + dosflag = dosify; /* default for non-DOS and non-OS/2 */ + + /* Find starting point in name before doing malloc */ + for (t = x; *t == '/'; t++) + ; + + /* Make changes, if any, to the copied name (leave original intact) */ + if (!pathput) + t = last(t, '/'); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + + strcpy(n, t); + if (p = strchr(n, ':')) + *p = '\0'; + for (p = n; *p = tolower(*p); p++); + + if (isdir == 42) return n; /* avoid warning on unused variable */ + + if (dosify) + msname(n); + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + return n; +} + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + return x; +} + +/* + * XXX use ztimbuf in both POSIX and non POSIX cases ? + */ +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ + struct utimbuf u; /* argument for utime() const ?? */ + + /* Convert DOS time to time_t format in u */ + u.actime = u.modtime = dos2unixtime(d); + utime(f, &u); +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. Bits 8 to 15 contains native THEOS protection + code. If n is not NULL, store the file size there. If t is not NULL, + the file's access, modification and creation times are stored there as + UNIX time_t values. If f is "-", use standard input as the file. If f is + a device, return a file size of -1 */ +{ + struct stat s; /* results of stat() */ + char *name; + unsigned int len = strlen(f); + + if (f == label) { + if (a != NULL) + *a = label_mode; + if (n != NULL) + *n = -2L; /* convention for a label name */ + if (t != NULL) + t->atime = t->mtime = t->ctime = label_utim; + return label_time; + } + + if ((name = malloc(len + 1)) == NULL) { + ZIPERR(ZE_MEM, "filetime"); + } + strcpy(name, f); + + if (name[len - 1] == '/' || name[len - 1] == '.') + name[len - 1] = '\0'; + + /* not all systems allow stat'ing a file with / appended */ + if (strcmp(f, "-") == 0) { + if (fstat(fileno(stdin), &s) != 0) { + free(name); + error("fstat(stdin)"); + } + } else if (LSSTAT(name, &s) != 0) { + /* Accept about any file kind including directories + * (stored with trailing / with -r option) + */ + free(name); + return 0; + } + + if (a != NULL) { + *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE); + if ((s.st_mode & S_IFMT) == S_IFDIR + || (s.st_mode & S_IFMT) == S_IFLIB) { + *a |= MSDOS_DIR_ATTR; + } + /* Map Theos' hidden attribute to DOS's hidden attribute */ + if (!(st.st_protect & 0x80)) + *a |= MSDOS_HIDDEN_ATTR; + *a |= ((ulg) s.st_protect) << 8; + } + if (n != NULL) + *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = t->mtime; /* best guess, (s.st_ctime: last status change!!) */ + } + + free(name); + + return unix2dostime(&s.st_mtime); +} +/* + * Get file THEOS attributes and store them into extent fields. + * On error leave z intact. + */ + +/* +* Extra record format +* =================== +* signature (2 bytes) = 'T','h' +* size (2 bytes) +* flags (1 byte) +* filesize (4 bytes) +* keylen (2 bytes) +* reclen (2 bytes) +* filegrow (1 byte) +* reserved (4 bytes) +*/ + +#define EB_L_THSIZE 4 +#define EB_L_TH_SIZE 14 + +int set_extra_field(z, z_utim) + struct zlist *z; + iztimes *z_utim; + /* store full data in local header but just modification time stamp info + in central header */ +{ + char *extra = NULL; + char *p; + char c; + struct stat st; + int status; + + if (status = stat(z->name, &st)) { + p = &z->name[strlen(z->name) - 1]; + if (*p == '/' || *p == '.') { + c = *p; + *p = '\0'; + status = stat(z->name, &st); + *p = c; + } +#ifdef DEBUG + fprintf(stderr, "set_extra_field: stat for file %s:\n status = %d\n", + z->name, status); +#endif + if (status) + return RET_ERROR; + } + + if ((extra = malloc(EB_L_TH_SIZE)) == NULL ) { + fprintf(stderr, "set_extra_field: Insufficient memory.\n" ); + return RET_ERROR; + } + + + extra[0] = 'T'; + extra[1] = 'h'; + extra[2] = EB_L_TH_SIZE; + extra[3] = EB_L_TH_SIZE >> 8; + extra[4] = 0; + extra[5] = st.st_size; + extra[6] = st.st_size >> 8; + extra[7] = st.st_size >> 16; + extra[8] = st.st_size >> 24; + extra[9] = st.st_org; + extra[10] = st.st_rlen; + extra[11] = st.st_rlen >> 8; + extra[12] = st.st_klen; + extra[13] = st.st_klen >> 8; + extra[14] = st.st_grow; + extra[15] = st.st_protect; + extra[16] = 0; + extra[17] = 0; + z->ext = z->cext = EB_L_TH_SIZE + EB_HEADSIZE; + z->extra = z->cextra = extra; + return RET_SUCCESS; +} +#endif + +/******************************/ +/* Function version_local() */ +/******************************/ + +void version_local() +{ + printf("Compiled with THEOS C 5.28 for THEOS 4.x on %s %s.\n\n", + __DATE__, __TIME__); +} + diff --git a/theos/zipup.h b/theos/zipup.h new file mode 100644 index 0000000..1de3f61 --- /dev/null +++ b/theos/zipup.h @@ -0,0 +1,19 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#ifndef O_RDONLY +# define O_RDONLY 0 +#endif +#define fhow O_RDONLY +#define fbad (-1) +typedef int ftype; +#define zopen(n,p) open(n,p) +#define zread(f,b,n) read(f,b,n) +#define zclose(f) close(f) +#define zerr(f) (k == (extent)(-1L)) +#define zstdin 0 -- cgit v1.2.3