diff options
author | Lorry <lorry@roadtrain.codethink.co.uk> | 2012-07-20 19:30:57 +0100 |
---|---|---|
committer | Lorry <lorry@roadtrain.codethink.co.uk> | 2012-07-20 19:30:57 +0100 |
commit | 04664087ad66f5614f82a2cfba3ae4eda15e792b (patch) | |
tree | 332090b15fd2db1b93abf40dccf06211d9aba297 /amiga | |
download | zip-04664087ad66f5614f82a2cfba3ae4eda15e792b.tar.gz |
Tarball conversion
Diffstat (limited to 'amiga')
-rw-r--r-- | amiga/LMKfile | 117 | ||||
-rw-r--r-- | amiga/README | 1 | ||||
-rw-r--r-- | amiga/amiga.c | 138 | ||||
-rw-r--r-- | amiga/amiga.h | 54 | ||||
-rw-r--r-- | amiga/amigazip.c | 507 | ||||
-rw-r--r-- | amiga/crc_68.a | 144 | ||||
-rw-r--r-- | amiga/deflate.a | 1053 | ||||
-rw-r--r-- | amiga/filedate.c | 599 | ||||
-rw-r--r-- | amiga/makefile.azt | 304 | ||||
-rw-r--r-- | amiga/match.a | 182 | ||||
-rw-r--r-- | amiga/match_68.a | 273 | ||||
-rw-r--r-- | amiga/osdep.h | 119 | ||||
-rw-r--r-- | amiga/smakefile | 662 | ||||
-rw-r--r-- | amiga/stat.c | 293 | ||||
-rw-r--r-- | amiga/z-stat.h | 95 | ||||
-rw-r--r-- | amiga/zipup.h | 25 |
16 files changed, 4566 insertions, 0 deletions
diff --git a/amiga/LMKfile b/amiga/LMKfile new file mode 100644 index 0000000..8c838ea --- /dev/null +++ b/amiga/LMKfile @@ -0,0 +1,117 @@ +# Makefile for Zip, ZipNote, ZipCloak and ZipSplit, Amiga SAS/C 5.10b +# See the master Makefile under the top level Zip/Unzip source directory +# for more information on compiler macros and flags for this version. +# Last update: Jan 07, 2007 +# -John Bush, <J.Bush@MD-B.Prime.COM>, <JBush@BIX.COM> + + +####################### +# MACROBE DEFINITIONS # +####################### + +# Compiler and loader debug flags. Omit comments as req'd. +# Do not set when building production version. +# CDBG = -d3 +# LDBG = ADDSYM + +DEFINES = -DNO_MKTEMP +CC = lc +OPT = -O +CFLAGS = $(OPT) $(DEFINES) $(CDBG) -v -mat -cuisf -b0 -j85i86i87i100i + +LD = blink +LDSTART = LIB:c.o +LDFLAGS = LIB LIB:lc.lib+LIB:amiga.lib + +TMPFILE = ram:MakeZip.tmp + +############################################### +# BASIC COMPILE INSTRUCTIONS AND DEPENDENCIES # +############################################### + +# default C rules +.c.o: + $(CC) $(CFLAGS) -o$@ $*.c + +# Alternate rules for routines containing entries needed by utilities +.c.oo: + $(CC) $(CFLAGS) -DUTIL -o$*.oo $*.c + +# object file macrough lists + +HFILES = zip.h ziperr.h tailor.h revision.h crc32.h crypt.h ttyio.h \ + amiga/amiga.h amiga/zipup.h amiga/osdep.h + +OBJA = zipfile.o zipup.o fileio.o util.o globals.o crc32.o crypt.o \ + timezone.o ttyio.o amiga.o amigazip.o filedate.o +OBJI = deflate.o trees.o +OBJU = zipfile.oo fileio.oo util.oo globals.o timezone.o \ + amiga.o amigazip.oo filedate.o + +OBJZ = zip.o $(OBJA) $(OBJI) + +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o $(OBJU) crc32.oo crypt.oo ttyio.o +OBJS = zipsplit.o $(OBJU) + +ZIPS = zip zipnote zipcloak zipsplit + +all: Message $(ZIPS) + +Message: + -echo " " + -echo "WARNING: Lattice 5.x HAS NOT BEEN TESTED WITH THIS ZIP VERSION" + -echo "Report problems to <zip-bugs@lists.wku.edu>" + -echo " " + +zip: $(OBJZ) $(HFILES) + -echo "$(OBJZ)" > $(TMPFILE) + $(LD) TO Zip FROM $(LDSTART) WITH $(TMPFILE) $(LDFLAGS) $(LDBG) + -delete $(TMPFILE) Zip.info + +zipnote: $(OBJN) $(HFILES) + -echo "$(OBJN)" > $(TMPFILE) + $(LD) TO ZipNote FROM $(LDSTART) WITH $(TMPFILE) $(LDFLAGS) $(LDBG) + -delete $(TMPFILE) ZipNote.info + +zipcloak: $(OBJC) $(HFILES) + -echo "$(OBJC)" > $(TMPFILE) + $(LD) TO ZipCloak FROM $(LDSTART) WITH $(TMPFILE) $(LDFLAGS) $(LDBG) + -delete $(TMPFILE) ZipCloak.info + +zipsplit: $(OBJS) $(HFILES) + -echo "$(OBJS)" > $(TMPFILE) + $(LD) TO ZipSplit FROM $(LDSTART) WITH $(TMPFILE) $(LDFLAGS) $(LDBG) + -delete $(TMPFILE) ZipSplit.info + +clean: + -delete $(OBJZ) all quiet force >nil: + -delete $(OBJU) all quiet force >nil: + -delete $(OBJA) all quiet force >nil: + -delete $(OBJI) all quiet force >nil: + -delete $(OBJN) all quiet force >nil: + -delete $(OBJC) all quiet force >nil: + -delete $(OBJS) all quiet force >nil: + +zip.o: zip.c $(HFILES) +zipnote.o: zipnote.c $(HFILES) +zipcloak.o: zipcloak.c $(HFILES) +crypt.o: crypt.c $(HFILES) +ttyio.o: ttyio.c $(HFILES) +zipsplit.o: zipsplit.c $(HFILES) +deflate.o: deflate.c $(HFILES) +trees.o: trees.c $(HFILES) +zipfile.o: zipfile.c $(HFILES) +zipup.o: zipup.c $(HFILES) +fileio.o: fileio.c $(HFILES) +util.o: util.c $(HFILES) +timezone.o: timezone.c $(HFILES) timezone.h +crc32.o: crc32.c $(HFILES) +crctab.o: crctab.c $(HFILES) +globals.o: globals.c $(HFILES) + +# Amiga specific objects +amiga.o: amiga/amiga.c $(HFILES) +amigazip.o: amiga/amigazip.c $(HFILES) + +# end of Makefile diff --git a/amiga/README b/amiga/README new file mode 100644 index 0000000..861ff85 --- /dev/null +++ b/amiga/README @@ -0,0 +1 @@ +the -A option currently does not work for the amiga. diff --git a/amiga/amiga.c b/amiga/amiga.c new file mode 100644 index 0000000..797d6d8 --- /dev/null +++ b/amiga/amiga.c @@ -0,0 +1,138 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2005-Feb-10 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* OS specific routines for AMIGA platform. + * + * John Bush <John.Bush@east.sun.com> BIX: jbush + * Paul Kienitz <kie@pacbell.net> + * + * History: + * + * Date DoBee Comments + * ------- -------- ----------------------------------------------- + * 21Jan93 JBush Original coding. + * Incorporated filedate.c (existing routine). + * + * 31Jan93 JBush Made filedate.c include unconditional. + * + * 18Jul93 PaulK Moved Aztec _abort() here from stat.c because we + * can't share the same one between Zip and UnZip. + * Added close_leftover_open_dirs() call to it. + * + * 17Apr95 PaulK Added Amiga internal version string so that + * installer programs can compare the version being + * installed to see if the copy the user already has + * is older or newer. Added Prestart_Hook to support + * debug tracing in deflate.a. + * + * 6May95 PaulK Added GetComment() for filenote support. + * + * 12Nov95 PaulK Added #define ZIP in front of filedate.c, for + * new options in there; removed declare of set_con() + * since echon() no longer expands to it (or anything). + * + * 12Feb96 PaulK Removed call of echon() entirely. + * + * 12Jul97 PaulK Made both Aztec and SAS define USE_TIME_LIB for filedate.c + * + * 26Aug97 PaulK Added ClearIOErr_exit() + * + * 2Jan98 HWalt Adapted for SAS/C using stat.c replacement functions + * + * 6Jun00 PaulK Removed references to time_lib, since new filedate.c + * supercedes it + */ + +#include <exec/memory.h> +#ifdef AZTEC_C +# include <libraries/dos.h> +# include <libraries/dosextens.h> +# include <clib/exec_protos.h> +# include <clib/dos_protos.h> +# include <pragmas/exec_lib.h> +# include <pragmas/dos_lib.h> +#else +# include <proto/exec.h> +# include <proto/dos.h> +#endif +#include <stdlib.h> +#include "ziperr.h" +void ziperr(int c, const char *h); + +#define ZIP +#if !defined(UTIL) +# define NO_MKTIME +#endif + +#ifdef AZTEC_C + +/* ============================================================= */ +/* filedate.c is an external file, since it's shared with UnZip. */ +/* Aztec includes it here, but SAS/C now compiles it separately. */ +# include "amiga/filedate.c" + +/* the same applies to stat.c */ +# include "amiga/stat.c" + +# define setenv BOGUS_INCOMPATIBLE_setenv +# include <fcntl.h> +# undef setenv +# ifdef DEBUG +# define PRESTART_HOOK +# endif +#endif + +extern void close_leftover_open_dirs(void); + + +/* the following handles cleanup when a ^C interrupt happens: */ + +void _abort(void) /* called when ^C is pressed */ +{ + close_leftover_open_dirs(); + ziperr(ZE_ABORT, "^C"); +} + +void ClearIOErr_exit(int e) /* EXIT is defined as this */ +{ + if (!e) + ((struct Process *) FindTask(NULL))->pr_Result2 = 0; + /* we clear IoErr() since we are successful, in a 1.x-compatible way */ + exit(e); +} + + +/* Make sure the version number here matches the number in revision.h */ +/* as closely as possible in strict decimal "#.#" form: */ +const char version_id[] = "\0$VER: Zip 2.3 (" +# include "env:VersionDate" +")\r\n"; + +/* call this with an arg of NULL to free storage: */ + +char *GetComment(char *filename) +{ + BPTR lk; + static struct FileInfoBlock *fib = NULL; + + if (!filename) { + if (fib) FreeMem(fib, sizeof(*fib)); + fib = NULL; + return NULL; + } + if (!fib) { + if (!(fib = AllocMem(sizeof(*fib), MEMF_PUBLIC))) + ziperr(ZE_MEM, "was checking filenotes"); + } + if (!(lk = Lock(filename, ACCESS_READ))) + return NULL; + if (!Examine(lk, fib)) + fib->fib_Comment[0] = '\0'; + UnLock(lk); + return fib->fib_Comment[0] ? &fib->fib_Comment[0] : NULL; +} diff --git a/amiga/amiga.h b/amiga/amiga.h new file mode 100644 index 0000000..a1461d8 --- /dev/null +++ b/amiga/amiga.h @@ -0,0 +1,54 @@ +/* + 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 __amiga_amiga_h +#define __amiga_amiga_h + +/* amiga.h + * + * Globular definitions that affect all of AmigaDom. + * + * Originally included in unzip.h, extracted for simplicity and eeze of + * maintenance by John Bush. + * + * This version is for use with Zip. It is not globally included, but used + * only by functions in amiga/amigazip.c. Much material that was needed for + * UnZip is absent here. + * + */ + +#include <fcntl.h> /* O_BINARY for open() w/o CR/LF translation */ +#include "amiga/z-stat.h" /* substitute for <stat.h> and <dire(c|n)t.h> */ +#define direct dirent + +#ifndef MODERN +# define MODERN +#endif + +#ifdef AZTEC_C /* Manx Aztec C, 5.0 or newer only */ +# include <clib/dos_protos.h> +# include <pragmas/dos_lib.h> /* do inline dos.library calls */ +# define O_BINARY 0 +#endif /* AZTEC_C */ + + +#ifdef __SASC +# include <dirent.h> +# include <dos.h> +# define disk_not_mounted 0 +# if ( (!defined(O_BINARY)) && defined(O_RAW)) +# define O_BINARY O_RAW +# endif +#endif /* SASC */ + + +/* Funkshine Prough Toe Taipes */ + +LONG FileDate (char *, time_t[]); + +#endif /* __amiga_amiga_h */ diff --git a/amiga/amigazip.c b/amiga/amigazip.c new file mode 100644 index 0000000..4e69d62 --- /dev/null +++ b/amiga/amigazip.c @@ -0,0 +1,507 @@ +/* + 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 "zip.h" +#include "amiga/amiga.h" + +#ifndef UTIL /* the companion #endif is a bit of ways down ... */ + +#define utime FileDate + +#define PAD 0 +#define PATH_END '/' + +/* Local globals (kinda like "military intelligence" or "broadcast quality") */ + +extern char *label; /* still declared in fileio.c */ +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +/* Local functions */ +local char *readd OF((DIR *)); +local int wild_recurse OF((char *, char *)); + + +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 = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; +} + + +/* What we have here is a mostly-generic routine using opendir()/readd() and */ +/* isshexp()/MATCH() to find all the files matching a multi-part filespec */ +/* using the portable pattern syntax. It shouldn't take too much fiddling */ +/* to make it usable for any other platform that has directory hierarchies */ +/* but no shell-level pattern matching. It works for patterns throughout */ +/* the pathname, such as "foo:*.?/source/x*.[ch]". */ + +#define ONENAMELEN 30 +/* the length of one filename component on the Amiga */ + +/* whole is a pathname with wildcards, wildtail points somewhere in the */ +/* middle of it. All wildcards to be expanded must come AFTER wildtail. */ + +local int wild_recurse(whole, wildtail) char *whole; char *wildtail; +{ + DIR *dir; + char *subwild, *name, *newwhole = NULL, *glue = NULL, plug = 0, plug2; + ush newlen, amatch = 0; + BPTR lok; + int e = ZE_MISS; + + if (!isshexp(wildtail)) + if (lok = Lock(whole, ACCESS_READ)) { /* p exists? */ + UnLock(lok); + return procname(whole, 0); + } else + return ZE_MISS; /* woops, no wildcards! */ + + /* back up thru path components till existing dir found */ + do { + name = wildtail + strlen(wildtail) - 1; + for (;;) + if (name-- <= wildtail || *name == PATH_END) { + subwild = name + 1; + plug2 = *subwild; + *subwild = 0; + break; + } + if (glue) + *glue = plug; + glue = subwild; + plug = plug2; + dir = opendir(whole); + } while (!dir && !disk_not_mounted && subwild > wildtail); + wildtail = subwild; /* skip past non-wild components */ + + if ((subwild = strchr(wildtail + 1, PATH_END)) != NULL) { + /* this "+ 1" dodges the ^^^ hole left by *glue == 0 */ + *(subwild++) = 0; /* wildtail = one component pattern */ + newlen = strlen(whole) + strlen(subwild) + (ONENAMELEN + 2); + } else + newlen = strlen(whole) + (ONENAMELEN + 1); + if (!dir || !(newwhole = malloc(newlen))) { + if (glue) + *glue = plug; + + e = dir ? ZE_MEM : ZE_MISS; + goto ohforgetit; + } + strcpy(newwhole, whole); + newlen = strlen(newwhole); + if (glue) + *glue = plug; /* repair damage to whole */ + if (!isshexp(wildtail)) { + e = ZE_MISS; /* non-wild name not found */ + goto ohforgetit; + } + + while (name = readd(dir)) { + if (MATCH(wildtail, name, 0)) { + strcpy(newwhole + newlen, name); + if (subwild) { + name = newwhole + strlen(newwhole); + *(name++) = PATH_END; + strcpy(name, subwild); + e = wild_recurse(newwhole, name); + } else + e = procname(newwhole, 0); + newwhole[newlen] = 0; + if (e == ZE_OK) + amatch = 1; + else if (e != ZE_MISS) + break; + } + } + + ohforgetit: + if (dir) closedir(dir); + if (subwild) *--subwild = PATH_END; + if (newwhole) free(newwhole); + if (e == ZE_MISS && amatch) + e = ZE_OK; + return e; +} + +int wild(p) char *p; +{ + char *use; + + /* special handling of stdin request */ + if (strcmp(p, "-") == 0) /* if compressing stdin */ + return newname(p, 0, 0); + + /* wild_recurse() can't handle colons in wildcard part: */ + if (use = strchr(p, ':')) { + if (strchr(++use, ':')) + return ZE_PARMS; + } else + use = p; + + return wild_recurse(p, use); +} + + +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 far *z; /* steps through zfiles list */ + + 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(p, z->iname, caseflag)) + { + 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 */ + if ((s.st_mode & S_IFDIR) == 0) + { + /* add or remove name of file */ + if ((m = newname(n, 0, caseflag)) != ZE_OK) + return m; + } else { + /* Add trailing / to the directory name */ + if ((p = malloc(strlen(n)+2)) == NULL) + return ZE_MEM; + strcpy(p, n); + a = p + strlen(p); + if (*p && a[-1] != '/' && 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 ((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); + } /* (s.st_mode & S_IFDIR) == 0) */ + 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 */ + int dosflag; + + dosflag = dosify; /* default for non-DOS and non-OS/2 */ + + /* Find starting point in name before doing malloc */ + if ((t = strrchr(x, ':')) != NULL) /* reject ":" */ + t++; + else + t = x; + { /* reject "//" */ + char *tt = t; + while (tt = strchr(tt, '/')) + while (*++tt == '/') + t = tt; + } + while (*t == '/') /* reject leading "/" on what's left */ + t++; + + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + + 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; +} + +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. */ +{ + time_t u[2]; /* argument for utime() */ + + /* Convert DOS time to time_t format in u */ + u[0] = u[1] = dos2unixtime(d); + + /* Set updated and accessed times of f */ + 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. 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() */ + /* convert FNMAX to malloc - 11/8/04 EG */ + char *name; + 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] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + + if (strcmp(f, "-") == 0) { + if (fstat(fileno(stdin), &s) != 0) + error("fstat(stdin)"); + } else if (SSTAT(name, &s) != 0) { + /* Accept about any file kind including directories + * (stored with trailing / with -r option) + */ + free(name); + return 0; + } + free(name); + + if (a != NULL) { + *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE); + if ((s.st_mode & S_IFDIR) != 0) { + *a |= MSDOS_DIR_ATTR; + } + } + 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 = s.st_ctime; + } + + return unix2dostime(&s.st_mtime); +} + +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; + /* create extra field and change z->att if desired */ +{ +#ifdef USE_EF_UT_TIME +#ifdef IZ_CHECK_TZ + if (!zp_tz_is_valid) return ZE_OK; /* skip silently if no valid TZ info */ +#endif + + if ((z->extra = (char *)malloc(EB_HEADSIZE+EB_UT_LEN(1))) == NULL) + return ZE_MEM; + + z->extra[0] = 'U'; + z->extra[1] = 'T'; + z->extra[2] = EB_UT_LEN(1); /* length of data part of e.f. */ + z->extra[3] = 0; + z->extra[4] = EB_UT_FL_MTIME; + z->extra[5] = (char)(z_utim->mtime); + z->extra[6] = (char)(z_utim->mtime >> 8); + z->extra[7] = (char)(z_utim->mtime >> 16); + z->extra[8] = (char)(z_utim->mtime >> 24); + + z->cextra = z->extra; + z->cext = z->ext = (EB_HEADSIZE+EB_UT_LEN(1)); + + return ZE_OK; +#else /* !USE_EF_UT_TIME */ + return (int)(z-z); +#endif /* ?USE_EF_UT_TIME */ +} + +int deletedir(d) +char *d; /* directory to delete */ +/* Delete the directory *d if it is empty, do nothing otherwise. + Return the result of rmdir(), delete(), or system(). + For VMS, d must be in format [x.y]z.dir;1 (not [x.y.z]). + */ +{ + return rmdir(d); +} + +#endif /* !UTIL */ + + +/******************************/ +/* Function version_local() */ +/******************************/ + + +/* NOTE: the following include depends upon the environment + * variable $Workbench to be set correctly. (Set by + * default, by Version command in Startup-sequence.) + */ +int WBversion = (int) +#include "ENV:Workbench" +; + +void version_local() +{ + static ZCONST char CompiledWith[] = "Compiled with %s%s under %s%s%s%s.\n\n"; + +/* Define buffers. */ + + char buf1[16]; /* compiler name */ + char buf2[16]; /* revstamp */ + char buf3[16]; /* OS */ + char buf4[16]; /* Date */ +/* char buf5[16]; /* Time */ + +/* format "with" name strings */ + +#ifdef AMIGA +# ifdef __SASC + strcpy(buf1,"SAS/C "); +# else +# ifdef LATTICE + strcpy(buf1,"Lattice C "); +# else +# ifdef AZTEC_C + strcpy(buf1,"Manx Aztec C "); +# else + strcpy(buf1,"UNKNOWN "); +# endif +# endif +# endif +/* "under" */ + sprintf(buf3,"AmigaDOS v%d",WBversion); +#else + strcpy(buf1,"Unknown compiler "); + strcpy(buf3,"Unknown OS"); +#endif + +/* Define revision, date, and time strings. + * NOTE: Do not calculate run time, be sure to use time compiled. + * Pass these strings via your makefile if undefined. + */ + +#if defined(__VERSION__) && defined(__REVISION__) + sprintf(buf2,"version %d.%d",__VERSION__,__REVISION__); +#else +# ifdef __VERSION__ + sprintf(buf2,"version %d",__VERSION__); +# else + sprintf(buf2,"unknown version"); +# endif +#endif + +#ifdef __DATE__ + sprintf(buf4," on %s",__DATE__); +#else + strcpy(buf4," unknown date"); +#endif + +/****** +#ifdef __TIME__ + sprintf(buf5," at %s",__TIME__); +#else + strcpy(buf5," unknown time"); +#endif +******/ + +/* Print strings using "CompiledWith" mask defined above. + * ("Compiled with %s%s under %s%s%s%s.") + */ + + printf(CompiledWith, + buf1, + buf2, + buf3, + buf4, + /* buf5, */ "", + "" ); /* buf6 not used */ + +} /* end function version_local() */ diff --git a/amiga/crc_68.a b/amiga/crc_68.a new file mode 100644 index 0000000..4cc2a25 --- /dev/null +++ b/amiga/crc_68.a @@ -0,0 +1,144 @@ +;=========================================================================== +; Copyright (c) 1990-2000 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 2000-Apr-09 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, all these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +;=========================================================================== +; crc_68 created by Paul Kienitz, last modified 04 Jan 96. +; +; Return an updated 32 bit CRC value, given the old value and a block of data. +; The CRC table used to compute the value is gotten by calling get_crc_table(). +; This replaces the older updcrc() function used in Zip and fUnZip. The +; prototype of the function is: +; +; ulg crc32(ulg crcval, uch *text, extent textlen); +; +; On the Amiga, type extent is always unsigned long, not unsigned int, because +; int can be short or long at whim, but size_t is long. +; +; If using this source on a non-Amiga 680x0 system, note that we treat +; a0/a1/d0/d1 as scratch registers not preserved across function calls. +; We do not bother to support registerized arguments for crc32() -- the +; textlen parm is usually large enough so that savings outside the loop +; are pointless. +; +; Define NO_UNROLLED_LOOPS to use a simple short loop which might be more +; efficient on certain machines with dinky instruction caches ('020?), or for +; processing short strings. If loops are unrolled, the textlen parm must be +; less than 512K; if not unrolled, it must be less than 64K. + + xdef _crc32 ; (ulg val, uch *buf, extent bufsize) + +DO_CRC0 MACRO + moveq #0,ltemp + move.b (textbuf)+,ltemp + eor.b crcval,ltemp + lsl.w #2,ltemp + move.l (crc_table,ltemp.w),ltemp + lsr.l #8,crcval + eor.l ltemp,crcval + ENDM + + machine mc68020 + +DO_CRC2 MACRO + move.b (textbuf)+,btemp + eor.b crcval,btemp + lsr.l #8,crcval + move.l (crc_table,btemp.w*4),ltemp + eor.l ltemp,crcval + ENDM + +crc_table equr a0 array of unsigned long +crcval equr d0 unsigned long initial value +textbuf equr a1 array of unsigned char +textbufsize equr d1 unsigned long (count of bytes in textbuf) +btemp equr d2 +ltemp equr d3 + + + xref _get_crc_table ; ulg *get_crc_table(void) + + NOLIST + INCLUDE 'exec/execbase.i' + LIST + xref _SysBase ; struct ExecBase * + + +_crc32: + move.l 8(sp),d0 + bne.s valid + moveq #0,d0 + rts +valid: movem.l btemp/ltemp,-(sp) + jsr _get_crc_table + move.l d0,ltemp + move.l 12(sp),crcval + move.l 16(sp),textbuf + move.l 20(sp),textbufsize + not.l crcval + move.l _SysBase,crc_table + move.w AttnFlags(crc_table),btemp + move.l ltemp,crc_table + btst #AFB_68020,btemp + bne twenty + + IFD NO_UNROLLED_LOOPS + + bra.s decr +loop: DO_CRC0 +decr: dbra textbufsize,loop + bra.s done + +twenty: moveq #0,btemp + bra.s decr2 +loop2: DO_CRC2 +decr2: dbra textbufsize,loop2 + + ELSE ; !NO_UNROLLED_LOOPS + + move.l textbufsize,btemp + lsr.l #3,textbufsize + bra decr8 +loop8: DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 +decr8: dbra textbufsize,loop8 + and.w #7,btemp + bra.s decr1 +loop1: DO_CRC0 +decr1: dbra btemp,loop1 + bra done + +twenty: moveq #0,btemp + move.l textbufsize,-(sp) + lsr.l #3,textbufsize + bra decr82 +loop82: DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 +decr82: dbra textbufsize,loop82 + move.l (sp)+,textbufsize + and.w #7,textbufsize + bra.s decr12 +loop12: DO_CRC2 +decr12: dbra textbufsize,loop12 + + ENDC ; ?NO_UNROLLED_LOOPS + +done: movem.l (sp)+,btemp/ltemp + not.l crcval +;;;;; move.l crcval,d0 ; crcval already is d0 + rts diff --git a/amiga/deflate.a b/amiga/deflate.a new file mode 100644 index 0000000..b21adae --- /dev/null +++ b/amiga/deflate.a @@ -0,0 +1,1053 @@ +;=========================================================================== +; 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 +;=========================================================================== +; This is a 680x0 assembly language translation of the Info-ZIP source file +; deflate.c, by Paul Kienitz. The function longest_match is based in part +; on match.a by Carsten Steger, which in turn is partly based on match.s +; for 386 by Jean-loup Gailly and Kai Uwe Rommel. Mostly, however, this +; material is based on deflate.c, by Gailly, Rommel, and Igor Mandrichenko. +; This code is not commented very much; see deflate.c for comments that explain +; what the functions are doing. +; +; The symbols that can be used to select different versions are as follows: +; +; CPU020 if defined, use 68020 instructions always. +; +; CPUTEST if defined, check at runtime for CPU type. Another symbol +; specifying the platform-specific test must be used with this. +; If neither of these is defined, use 68000 instructions only. +; Runtime test is nonportable; it is different for each OS. +; +; AMIGA use Amiga-specific test for 68020, if CPUTEST defined. Also +; tells it that registers d0/a0/d1/a1 are not preserved by +; function calls. At present, if AMIGA is not defined, it +; causes functions to preserve all registers. ALL OF THIS CODE +; CURRENTLY ASSUMES THAT REGISTERS D2-D7/A2-A6 WILL BE PRESERVED +; BY ANY FUNCTIONS THAT IT CALLS. +; +; DYN_ALLOC should be defined here if it is defined for C source; tells us +; that big arrays are allocated instead of static. +; +; WSIZE must be defined as the same number used for WSIZE in the C +; source, and must be a power of two <= 32768. As elsewhere, +; the default value is 32768. +; +; INT16 define this if ints are 16 bits; otherwise 32 bit ints assumed. +; +; SMALL_MEM define this if it is defined in the C source; otherwise it uses +; the MEDIUM_MEM model. BIG_MEM and MMAP are *not* supported. +; The FULL_SEARCH option in deflate.c is also not supported. +; +; DEBUG activates some tracing output, as in the C source. +; +; QUADLONG this selects a different version of the innermost longest_match +; loop code for 68020 operations, comparing bytes four at a time +; instead of two at a time. It seems to be a tiny bit faster on +; average, but it's slower often enough that one can't generalize. +; +; This code currently assumes that function results are returned in D0 for +; all platforms. It assumes that args to functions are pushed onto the stack, +; last arg first. It also currently assumes that all C symbols have an +; underscore prepended when referenced from assembly. + + IFND CPU020 + IFND CPUTEST +CPU000 equ 1 + ENDC + ENDC + +; Use these macros for accessing variables of type int: + IFD INT16 +MOVINT MACRO + move.w \1,\2 + ENDM +CLRINT MACRO + clr.w \1 + ENDM +INTSIZE equ 2 + ELSE ; !INT16 +MOVINT MACRO + move.l \1,\2 + ENDM +CLRINT MACRO + clr.l \1 + ENDM +INTSIZE equ 4 + ENDC + + IFD DYN_ALLOC +BASEPTR MACRO + move.l \1,\2 + ENDM + ELSE +BASEPTR MACRO + lea \1,\2 + ENDM + ENDC + +; constants we use, many of them adjustable: + +MAX_MATCH equ 258 +MIN_MATCH equ 3 +TOO_FAR equ 4096 + IFND WSIZE +WSIZE equ 32768 + ENDC +WMASK equ WSIZE-1 +MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1 +MIN_LOOKAHEAD equ MAX_MATCH+MIN_MATCH+1 +; IFD BIG_MEM ; NOT supported -- type Pos needs to be 32 bits +;HASH_BITS equ 15 +; ELSE + IFD SMALL_MEM +HASH_BITS equ 13 + ELSE +HASH_BITS equ 14 ; default -- MEDIUM_MEM + ENDC +; ENDC ; BIG_MEM +HASH_SIZE equ 1<<HASH_BITS +HASH_MASK equ HASH_SIZE-1 +H_SHIFT equ (HASH_BITS+MIN_MATCH-1)/MIN_MATCH +B_SLOW equ 1 +B_FAST equ 2 +ZE_MEM equ 4 +EOF equ -1 + +; struct config is defined by these offsets: +Good_length equ 0 +Max_lazy equ 2 +Nice_length equ 4 +Max_chain equ 6 +Sizeof_config equ 8 + + +; external functions we call: + xref _ct_tally ; int ct_tally(int, int) + xref _flush_block ; unsigned long F(char *, unsigned long, int) + xref _ziperr ; void ziperr(int, char *) + xref _error ; void error(char *) + xref _calloc ; stdlib function: void *calloc(size_t, size_t) + xref _free ; stdlib function: void free(void *) + IFD DEBUG + xref _fputc ; stdio function: int fputc(int, FILE *) + xref _stderr ; pointer to FILE, which we pass to fputc + ENDC + +; our entry points: + xdef _lm_init ; void lm_init(int level, unsigned short *flags) + xdef _lm_free ; void lm_free(void) + xdef _deflate ; void deflate(void) ...the big one + xdef _fill_window ; this line is just for debugging + + +; ============================================================================ +; Here is where we have our global variables. + + section deflatevars,data + +; external global variables we reference: + xref _verbose ; signed int + xref _level ; signed int + xref _read_buf ; int (*read_buf)(char *, unsigned int) + +; global variables we make available: + + xdef _window + xdef _prev + xdef _head + xdef _window_size + xdef _block_start + xdef _strstart + + IFD DYN_ALLOC +_prev: ds.l 1 ; pointer to calloc()'d unsigned short array +_head: ds.l 1 ; pointer to calloc()'d unsigned short array +_window: ds.l 1 ; pointer to calloc()'d unsigned char array + ELSE ; !DYN_ALLOC +_prev: ds.w WSIZE ; array of unsigned short +_head: ds.w HASH_SIZE ; array of unsigned short +_window: ds.b 2*WSIZE ; array of unsigned char + ENDC ; ?DYN_ALLOC +_window_size: ds.l 1 ; unsigned long +_block_start: ds.l 1 ; unsigned long +_strstart: ds.w INTSIZE/2 ; unsigned int + +; Now here are our private variables: + + IFD CPUTEST +is020: ds.w 1 ; bool: CPU type is '020 or higher + ENDC +ins_h: ds.w 1 ; unsigned short +sliding: ds.w 1 ; bool: the file is read a piece at a time +eofile: ds.w 1 ; bool: we have read in the end of the file +max_lazy_match: ds.w 1 ; unsigned short +lookahead: ds.w 1 ; unsigned short + +; These are NOT DECLARED AS STATIC in deflate.c, but currently could be: +max_chain_len: ds.w 1 ; unsigned short (unsigned int in deflate.c) +prev_length: ds.w 1 ; unsigned short (unsigned int in deflate.c) +good_match: ds.w 1 ; unsigned short (unsigned int in deflate.c) +nice_match: ds.w 1 ; unsigned short (signed int in deflate.c) +match_start: ds.w 1 ; unsigned short (unsigned int in deflate.c) + +; This array of struct config is a constant and could be in the code section: +config_table: dc.w 0,0,0,0 ; level 0: store uncompressed + dc.w 4,4,8,4 ; level 1: fastest, loosest compression + dc.w 4,5,16,8 ; level 2 + dc.w 4,6,32,32 ; level 3: highest to use deflate_fast + dc.w 4,4,16,16 ; level 4: lowest to use lazy matches + dc.w 8,16,32,32 ; level 5 + dc.w 8,16,128,128 ; level 6: the default level + dc.w 8,32,128,256 ; level 7 + dc.w 32,128,258,1024 ; level 8 + dc.w 32,258,258,4096 ; level 9: maximum compression, slow + + +;;CAL_SH MACRO ; macro for calling zcalloc() +;; IFD INT16 +;; move.w #2,-(sp) +;; move.w #\1,-(sp) +;; jsr _zcalloc +;; addq #4,sp +;; ELSE +;; pea 2 +;; pea \1 +;; jsr _zcalloc +;; addq #8,sp +;; ENDC +;; ENDM + +CAL_SH MACRO ; Okay, we're back to using regular calloc()... + pea 2 + pea \1 + jsr _calloc + addq #8,sp + ENDM + +; ============================================================================ +; And here we begin our functions. match_init is for internal use only: + + section deflate,code + +match_init: + IFD CPUTEST ; now check for platform type + IFD AMIGA ; Amiga specific test for '020 CPU: + xref _SysBase + NOLIST + INCLUDE 'exec/execbase.i' + LIST + + clr.w is020 ; default value is 68000 + move.l _SysBase,a0 + btst #AFB_68020,AttnFlags+1(a0) + beq.s cheap + move.w #1,is020 +cheap: + ELSE ; !AMIGA + + FAIL Write an '020-detector for your system here! +; On the Macintosh, I believe GetEnvironment() provides the information. + + ENDC ; AMIGA + ENDC ; CPUTEST + rts ; match_init consists only of rts if CPUTEST unset + + +; ============================================================================ +; Here is longest_match(), the function that the rest of this was built up +; from, the hottest hot spot in the program and therefore the most heavily +; optimized. It has two different versions, one for '020 and higher CPUs, and +; one for 68000/68010. It can test at runtime which version to use if you +; create a test function in match_init for your platform. Currently such a +; test is implemented for the Amiga. It can also be assembled to use '000 or +; '020 code only. + +Cur_Match equr d0 ; unsigned int, kept valid as long +Best_Len equr d1 ; unsigned int, kept valid as long +Scan_Start equr d3 ; pair of bytes +Scan_End equr d4 ; pair of bytes +Limit equr d5 ; unsigned int +Chain_Length equr d6 ; unsigned int +Scan_Test equr d7 ; counter, pair of bytes sometimes +Scan equr a0 ; pointer to unsigned char +Match equr a1 ; pointer to unsigned char +Prev_Address equr a2 ; pointer to unsigned short +Scan_Ini equr a3 ; pointer to unsigned char +Match_Ini equr a5 ; pointer to unsigned char +; Note: "pair of bytes" means the two low order bytes of the register in +; 68020 code, but means the lowest and third lowest bytes on the 68000. + IFD AMIGA +SAVEREGS reg d3-d7/a2/a3/a5 ; don't protect d0/d1/a0/a1 + ELSE ; !AMIGA +SAVEREGS reg d1/d3-d7/a0-a3/a5 ; protect all except d0 return val + ENDC ; ?AMIGA +; d2, a4, a6 not used... on Amiga, a4 is used by small-data memory model + + +longest_match: + movem.l SAVEREGS,-(sp) + +; setup steps common to byte and word versions: + IFD INT16 + and.l #$0000FFFF,Cur_Match ; upper half must be zero! +; we use an and.l down here for the sake of ATSIGN/REGARGS. + moveq #0,Limit ; so adding to Scan_Ini works + ENDC + move.w max_chain_len,Chain_Length + move.w prev_length,Best_Len + MOVINT _strstart,Limit + BASEPTR _prev,Prev_Address + BASEPTR _window,Match_Ini + move.l Match_Ini,Scan_Ini + addq #MIN_MATCH,Match_Ini ; optimizes inner loop + add.l Limit,Scan_Ini + sub.w #MAX_DIST,Limit + bhi.s limit_ok + moveq #0,Limit +limit_ok: + cmp.w good_match,Best_Len + blo.s length_ok + lsr.w #2,Chain_Length +length_ok: + subq.w #1,Chain_Length + + IFD CPUTEST + tst.w is020 ; can we use '020 stuff today? + bne WORD_match + ENDC + + IFND CPU020 + +; for 68000 or 68010, use byte operations: + moveq #0,Scan_Start ; clear 2nd & 4th bytes, use 1st & 3rd + moveq #0,Scan_End ; likewise + moveq #0,Scan_Test ; likewise + move.b (Scan_Ini),Scan_Start + swap Scan_Start ; swap is faster than 8 bit shift + move.b 1(Scan_Ini),Scan_Start + move.b -1(Scan_Ini,Best_Len.w),Scan_End + swap Scan_End + move.b 0(Scan_Ini,Best_Len.w),Scan_End + bra.s bdo_scan + +blong_loop: + move.b -1(Scan_Ini,Best_Len.w),Scan_End + swap Scan_End + move.b 0(Scan_Ini,Best_Len.w),Scan_End + +bshort_loop: + add.w Cur_Match,Cur_Match ; assert value before doubling < 32K + IFNE 32768-WSIZE + and.w #(WMASK*2),Cur_Match + ENDC + move.w (Prev_Address,Cur_Match.l),Cur_Match + cmp.w Limit,Cur_Match + dbls Chain_Length,bdo_scan + bra return + +bdo_scan: + move.l Match_Ini,Match + add.l Cur_Match,Match + move.b -MIN_MATCH-1(Match,Best_Len.w),Scan_Test + swap Scan_Test + move.b -MIN_MATCH(Match,Best_Len.w),Scan_Test + cmp.l Scan_Test,Scan_End + bne.s bshort_loop + move.b -MIN_MATCH(Match),Scan_Test + swap Scan_Test + move.b -MIN_MATCH+1(Match),Scan_Test + cmp.l Scan_Test,Scan_Start + bne.s bshort_loop + move.w #(MAX_MATCH-3),Scan_Test + lea MIN_MATCH(Scan_Ini),Scan ; offset optimizes inner loop + +bscan_loop: + cmp.b (Match)+,(Scan)+ + dbne Scan_Test,bscan_loop + subq #1,Scan + + sub.l Scan_Ini,Scan ; assert difference is 16 bits + cmp.w Best_Len,Scan + bls.s bshort_loop + MOVINT Scan,Best_Len + move.w Cur_Match,match_start + cmp.w nice_match,Best_Len + blo.s blong_loop + IFD CPUTEST + bra return + ENDC + + ENDC ; !CPU020 + + IFND CPU000 + MACHINE MC68020 + +; for 68020 or higher, use word operations even on odd addresses: +WORD_match: + move.w (Scan_Ini),Scan_Start + move.w -1(Scan_Ini,Best_Len.w),Scan_End + bra.s wdo_scan + +wlong_loop: + move.w -1(Scan_Ini,Best_Len.w),Scan_End + +wshort_loop: + and.w #WMASK,Cur_Match + move.w (Prev_Address,Cur_Match.w*2),Cur_Match ; '020 addressing mode + cmp.w Limit,Cur_Match + dbls Chain_Length,wdo_scan + bra.s return + +wdo_scan: + move.l Match_Ini,Match + add.l Cur_Match,Match + cmp.w -MIN_MATCH-1(Match,Best_Len.w),Scan_End + bne.s wshort_loop + cmp.w -MIN_MATCH(Match),Scan_Start + bne.s wshort_loop + IFD QUADLONG +; By some measurements, this version of the code is a little tiny bit faster. +; But on some files it's slower. It probably pays off only when there are +; long match strings, and costs in the most common case of three-byte matches. + moveq #((MAX_MATCH-MIN_MATCH)/16),Scan_Test ; value = 15 + lea MIN_MATCH(Scan_Ini),Scan ; offset optimizes inner loop + +wscan_loop: + cmp.l (Match)+,(Scan)+ ; test four bytes at a time + bne.s odd + cmp.l (Match)+,(Scan)+ + bne.s odd + cmp.l (Match)+,(Scan)+ + bne.s odd + cmp.l (Match)+,(Scan)+ + dbne Scan_Test,wscan_loop ; '020 can cache a bigger loop +odd: + subq #4,Scan + subq #4,Match + cmp.b (Match)+,(Scan)+ ; find good bytes in bad longword + bne.s even + cmp.b (Match)+,(Scan)+ + bne.s even + cmp.b (Match)+,(Scan)+ + beq.s steven +even: subq #1,Scan + ELSE ; !QUADLONG + moveq #((MAX_MATCH-MIN_MATCH)/2),Scan_Test ; value = 127 + lea MIN_MATCH(Scan_Ini),Scan ; offset optimizes inner loop + +wscan_loop: + cmp.w (Match)+,(Scan)+ + dbne Scan_Test,wscan_loop + subq #2,Scan + move.b -2(Match),Scan_Test + cmp.b (Scan),Scan_Test + bne.s steven + addq #1,Scan + ENDC ; ?QUADLONG +steven: + sub.l Scan_Ini,Scan ; assert: difference is 16 bits + cmp.w Best_Len,Scan + bls.s wshort_loop + MOVINT Scan,Best_Len + move.w Cur_Match,match_start + cmp.w nice_match,Best_Len + blo.s wlong_loop + + MACHINE MC68000 + ENDC ; !CPU000 + +return: + MOVINT Best_Len,d0 ; return value (upper half should be clear) + movem.l (sp)+,SAVEREGS + rts + + +; ============================================================================= +; This is the deflate() function itself, our main entry point. It calls +; longest_match, above, and some outside functions. It is a hot spot, but not +; as hot as longest_match. It uses no special '020 code. + +; ================== Several macros used in deflate() and later functions: + +; Arg 1 is D-reg that new ins_h value is to be left in, +; arg 2 is the byte value to be hashed into it, which must not be the same reg +UP_HASH MACRO + move.w ins_h,\1 + asl.w #H_SHIFT,\1 + eor.b \2,\1 + and.w #HASH_MASK,\1 ; ((ins_h << H_SHIFT) ^ c) & HASH_MASK + move.w \1,ins_h ; ins_h = that + ENDM + +; Arg 1 is scratch A, arg 2 is scratch D +IN_STR MACRO + move.l Strst,\2 + addq.w #MIN_MATCH-1,\2 + move.b (Window,\2.l),\2 ; window[strstart + MIN_MATCH - 1] + UP_HASH Head,\2 + add.l Head,Head ; assert upper word is zero before add + BASEPTR _head,\1 + add.l Head,\1 + move.w (\1),Head ; hash_head = head[ins_h] + move.w Strst,(\1) ; head[ins_h] = strstart + move.l Strst,\2 + IFNE WSIZE-32768 + and.w #WMASK,\2 + ENDC + add.w \2,\2 ; masks implicitly when WSIZE == 32768 + move.w Head,(Prev,\2.l) ; prev[str_start & WMASK] = hash_head + ENDM + +; Arg 1 is bool (int) EOF flag, flush_block result is in d0, trashes d1/a0/a1 +FLUSH_B MACRO + IFC '\1','#0' + CLRINT -(sp) + ELSE + MOVINT \1,-(sp) + ENDC + move.l _block_start,d0 + blt.s nenu\@ + move.l Window,a0 + add.l d0,a0 + bra.s nun\@ +nenu\@: sub.l a0,a0 ; if block_start < 0, push NULL +nun\@: sub.l Strst,d0 + neg.l d0 + move.l d0,-(sp) + move.l a0,-(sp) + jsr _flush_block + lea 8+INTSIZE(sp),sp + ENDM + +; This expands to nothing unless DEBUG is defined. +; Arg 1 is a byte to be trace-outputted -- if it is d0 it must be a valid int +TRACE_C MACRO + IFD DEBUG + cmp.w #1,_verbose+INTSIZE-2 ; test lower word only + ble.s qui\@ + IFNC '\1','d0' + moveq #0,d0 + move.b \1,d0 + ENDC + move.l _stderr,-(sp) + MOVINT d0,-(sp) + jsr _fputc + addq #4+INTSIZE,sp +qui\@: + ENDC ; DEBUG + ENDM + +; ================== Here are the register vars we use, and deflate() itself: + +Window equr a2 ; cached address of window[] +Prev equr a3 ; cached address of prev[] +Strst equr d7 ; strstart cached as a longword +Look equr d6 ; lookahead cached as short +Head equr d5 ; local variable hash_head, short +PrevL equr d4 ; prev_length cached as short +MatchL equr d3 ; local variable match_length, unsigned short +Avail equr d2 ; local variable available_match, bool +PrevM equr a5 ; local variable prev_match, int in an A-reg + + IFD AMIGA +DEFREGS reg d2-d7/a2/a3/a5 + ELSE +DEFREGS reg d0-d7/a0/a2/a3/a5 ; play it safe, preserve all regs + ENDC + + +_deflate: ; first, setup steps common to deflate and deflate_fast: + movem.l DEFREGS,-(sp) + IFD INT16 + moveq #0,Strst ; make sure strstart is valid as a long + ENDC + moveq #0,Head ; ditto for hash_head + MOVINT _strstart,Strst + move.w lookahead,Look + move.w prev_length,PrevL + BASEPTR _window,Window + BASEPTR _prev,Prev + MOVINT _level,d0 + cmp.w #3,d0 + ble deflate_fast + moveq #MIN_MATCH-1,MatchL + moveq #0,Avail + +look_loop: + tst.w Look + beq last_tally + IN_STR a0,d0 + move.w MatchL,PrevL + move.w match_start,PrevM + move.w #MIN_MATCH-1,MatchL + + tst.w Head + beq.s no_new_match + cmp.w max_lazy_match,PrevL + bhs.s no_new_match + move.w Strst,d0 + sub.w Head,d0 + cmp.w #MAX_DIST,d0 + bhi.s no_new_match + move.w PrevL,prev_length ; longest_match reads these variables + MOVINT Strst,_strstart + MOVINT Head,d0 ; parm for longest_match + bsr longest_match ; sets match_start + cmp.w Look,d0 ; does length exceed valid data? + bls.s stml + move.w Look,d0 +stml: move.w d0,MatchL ; valid length of match + cmp.w #MIN_MATCH,MatchL ; is the match only three bytes? + bne.s no_new_match + move.w match_start,d0 + sub.w Strst,d0 + cmp.w #-TOO_FAR,d0 + bge.s no_new_match + moveq #MIN_MATCH-1,MatchL ; mark the current match as no good + +no_new_match: + cmp.w #MIN_MATCH,PrevL + blo literal + cmp.w MatchL,PrevL + blo literal + ; CHECK_MATCH Strst-1,PrevM,PrevL + MOVINT Strst,_strstart ; ct_tally reads this variable + move.l PrevL,d0 + subq.w #MIN_MATCH,d0 + MOVINT d0,-(sp) + move.l Strst,d0 + sub.w PrevM,d0 + subq.w #1,d0 + MOVINT d0,-(sp) + jsr _ct_tally ; sets d0 true if we have to flush + addq #2*INTSIZE,sp + subq.w #3,PrevL ; convert for dbra (prev_length - 2) + sub.w PrevL,Look + subq.w #2,Look +insertmatch: + addq.w #1,Strst + IN_STR a0,d1 ; don't clobber d0 + dbra PrevL,insertmatch + moveq #0,Avail + moveq #0,PrevL ; not needed? + moveq #MIN_MATCH-1,MatchL + addq.w #1,Strst + tst.w d0 + beq refill + FLUSH_B #0 + move.l Strst,_block_start + bra.s refill + +literal: + tst.w Avail + bne.s yeslit + moveq #1,Avail + bra.s skipliteral +yeslit: TRACE_C <-1(Window,Strst.l)> + MOVINT Strst,_strstart ; ct_tally reads this variable + moveq #0,d0 + move.b -1(Window,Strst.l),d0 + MOVINT d0,-(sp) + CLRINT -(sp) + jsr _ct_tally + addq #2*INTSIZE,sp + tst.w d0 + beq.s skipliteral + FLUSH_B #0 + move.l Strst,_block_start +skipliteral: + addq.w #1,Strst + subq.w #1,Look + +refill: + cmp.w #MIN_LOOKAHEAD,Look + bhs look_loop + bsr fill_window + bra look_loop + +last_tally: + tst.w Avail + beq last_flush + MOVINT Strst,_strstart ; ct_tally reads this variable + moveq #0,d0 + move.b -1(Window,Strst.l),d0 + MOVINT d0,-(sp) + CLRINT -(sp) + jsr _ct_tally + addq #2*INTSIZE,sp +last_flush: + FLUSH_B #1 + bra deflate_exit + +; ================== This is another version used for low compression levels: + +deflate_fast: + moveq #0,MatchL + moveq #MIN_MATCH-1,PrevL +flook_loop: + tst.w Look + beq flast_flush + + IN_STR a0,d0 + tst.w Head + beq.s fno_new_match + move.w Strst,d0 + sub.w Head,d0 + cmp.w #MAX_DIST,d0 + bhi.s fno_new_match + move.w PrevL,prev_length ; longest_match reads these variables + MOVINT Strst,_strstart + MOVINT Head,d0 ; parm for longest_match + bsr longest_match ; sets match_start + cmp.w Look,d0 ; does length exceed valid data? + bls.s fstml + move.w Look,d0 +fstml: move.w d0,MatchL ; valid length of match + +fno_new_match: + cmp.w #MIN_MATCH,MatchL + blo fliteral + ; CHECK_MATCH Strst,match_start,MatchL + MOVINT Strst,_strstart ; ct_tally reads this variable + move.l MatchL,d0 + subq.w #MIN_MATCH,d0 + MOVINT d0,-(sp) + move.l Strst,d0 + sub.w match_start,d0 + MOVINT d0,-(sp) + jsr _ct_tally ; sets d0 true if we have to flush + addq #2*INTSIZE,sp + sub.w MatchL,Look + cmp.w max_lazy_match,MatchL + bhi ftoolong + subq.w #2,MatchL +finsertmatch: + addq.w #1,Strst + IN_STR a0,d1 ; preserve d0 + dbra MatchL,finsertmatch + moveq #0,MatchL ; not needed? + addq.w #1,Strst + bra.s flushfill + +ftoolong: + add.w MatchL,Strst + moveq #0,MatchL + moveq #0,d1 ; preserve d0 + move.b (Window,Strst.l),d1 + move.w d1,ins_h +; My assembler objects to passing <1(Window,Strst.l)> directly to UP_HASH... + move.b 1(Window,Strst.l),Avail ; Avail is not used in deflate_fast + UP_HASH d1,Avail ; preserve d0 + IFNE MIN_MATCH-3 + FAIL needs to UP_HASH another MIN_MATCH-3 times, but with what arg? + ENDC + bra.s flushfill + +fliteral: + TRACE_C <(Window,Strst.l)> + MOVINT Strst,_strstart ; ct_tally reads this variable + moveq #0,d0 + move.b (Window,Strst.l),d0 + MOVINT d0,-(sp) + CLRINT -(sp) + jsr _ct_tally ; d0 set if we need to flush + addq #2*INTSIZE,sp + addq.w #1,Strst + subq.w #1,Look + +flushfill: + tst.w d0 + beq.s frefill + FLUSH_B #0 + move.l Strst,_block_start +frefill: + cmp.w #MIN_LOOKAHEAD,Look + bhs flook_loop + bsr fill_window + bra flook_loop + +flast_flush: + FLUSH_B #1 ; sets our return value + +deflate_exit: + MOVINT Strst,_strstart ; save back cached values + move.w PrevL,prev_length + move.w Look,lookahead + movem.l (sp)+,DEFREGS + rts + + +; ========================================================================= +; void fill_window(void) calls the input function to refill the sliding +; window that we use to find substring matches in. + +More equr Head ; local variable in fill_window +WindTop equr Prev ; local variable used for sliding +SlidIx equr PrevL ; local variable used for sliding + + IFD AMIGA +FWREGS reg d2-d5/a2-a6 ; does NOT include Look and Strst + ELSE +FWREGS reg d1-d5/a0-a6 ; likewise + ENDC +; all registers available to be clobbered by the sliding operation: +; we exclude More, WindTop, SlidIx, Look, Strst, Window, a4 and a7. +SPAREGS reg d0-d3/a0-a1/a5-a6 +SPCOUNT equ 8 ; number of registers in SPAREGS + + +_fill_window: ; C-callable entry point + movem.l Strst/Look,-(sp) + IFD INT16 + moveq #0,Strst ; Strst must be valid as a long + ENDC + MOVINT _strstart,Strst + move.w lookahead,Look + BASEPTR _window,Window + bsr.s fill_window + MOVINT Strst,_strstart + move.w Look,lookahead + movem.l (sp)+,Strst/Look + rts + +; strstart, lookahead, and window must be cached in Strst, Look, and Window: +fill_window: ; asm-callable entry point + movem.l FWREGS,-(sp) + tst.w eofile ; we put this up here for speed + bne fwdone + and.l #$FFFF,Look ; make sure Look is valid as long +fw_refill: + move.l _window_size,More ; <= 64K + sub.l Look,More + sub.l Strst,More ; Strst is already valid as long + cmp.w #EOF,More + bne.s notboundary + subq.w #1,More + bra checkend + +notboundary: + tst.w sliding + beq checkend + cmp.w #WSIZE+MAX_DIST,Strst + blo checkend + IFGT 32768-WSIZE + lea WSIZE(Window),WindTop ; WindTop is aligned when Window is + ELSE + move.l Window,WindTop + add.l #WSIZE,WindTop + ENDC + move.l Window,d0 + and.w #3,d0 + beq.s isaligned + subq.w #1,d0 +align: move.b (WindTop)+,(Window)+ ; copy up to a longword boundary + dbra d0,align +isaligned: +; This is faster than a simple move.l (WindTop)+,(Window)+ / dbra loop: + move.w #(WSIZE-1)/(4*SPCOUNT),SlidIx +slide: movem.l (WindTop)+,SPAREGS ; copy, 32 bytes at a time! + movem.l SPAREGS,(Window) ; a slight overshoot doesn't matter. + lea 4*SPCOUNT(Window),Window ; can't use (aN)+ as movem.l dest + dbra SlidIx,slide + BASEPTR _window,Window ; restore cached value + sub.w #WSIZE,match_start + sub.w #WSIZE,Strst + sub.l #WSIZE,_block_start + add.w #WSIZE,More + BASEPTR _head,a0 + move.w #HASH_SIZE-1,d0 +fixhead: + move.w (a0),d1 + sub.w #WSIZE,d1 + bpl.s headok + moveq #0,d1 +headok: move.w d1,(a0)+ + dbra d0,fixhead + BASEPTR _prev,a0 + move.w #WSIZE-1,d0 +fixprev: + move.w (a0),d1 + sub.w #WSIZE,d1 + bpl.s prevok + moveq #0,d1 +prevok: move.w d1,(a0)+ + dbra d0,fixprev + TRACE_C #'.' + +checkend: ; assert eofile is false + MOVINT More,-(sp) ; assert More's upper word is zero + move.l Strst,d0 + add.w Look,d0 + add.l Window,d0 + move.l d0,-(sp) + move.l _read_buf,a0 + jsr (a0) ; refill the upper part of the window + addq #4+INTSIZE,sp + tst.w d0 + beq.s iseof + cmp.w #EOF,d0 + beq.s iseof + add.w d0,Look + cmp.w #MIN_LOOKAHEAD,Look + blo fw_refill ; eofile is still false + + bra.s fwdone +iseof: move.w #1,eofile +fwdone: movem.l (sp)+,FWREGS + rts + + +; ========================================================================= +; void lm_free(void) frees dynamic arrays in the DYN_ALLOC version. + + xdef _lm_free ; the entry point + +_lm_free: + IFD DYN_ALLOC + move.l _window,d0 + beq.s lf_no_window + move.l d0,-(sp) + jsr _free + addq #4,sp + clr.l _window +lf_no_window: + move.l _prev,d0 + beq.s lf_no_prev + move.l d0,-(sp) + jsr _free + move.l _head,(sp) ; reuse the same stack arg slot + jsr _free + addq #4,sp + clr.l _prev + clr.l _head +lf_no_prev: + ENDC + rts + +; ============================================================================ +; void lm_init(int pack_level, unsigned short *flags) allocates dynamic arrays +; if any, and initializes all variables so that deflate() is ready to go. + + xdef _lm_init ; the entry point + +Level equr d2 +;Window equr a2 ; as in deflate() + IFD AMIGA +INIREGS reg d2/a2 + ELSE +INIREGS reg d0-d2/a0-a1 + ENDC + +_lm_init: + MOVINT 4(sp),d0 + move.l 4+INTSIZE(sp),a0 + movem.l INIREGS,-(sp) + move.w d0,Level + cmp.w #1,Level + blt.s levelerr + bgt.s try9 + bset.b #B_FAST,1(a0) +try9: cmp.w #9,Level + bgt.s levelerr + blt.s levelok + bset.b #B_SLOW,1(a0) + bra.s levelok +levelerr: + pea level_message + jsr _error ; never returns +levelok: + clr.w sliding + tst.l _window_size + bne.s gotawindowsize + move.w #1,sliding + move.l #2*WSIZE,_window_size +gotawindowsize: + + BASEPTR _window,Window + IFD DYN_ALLOC + move.l Window,d0 ; fake tst.l + bne.s gotsomewind + CAL_SH WSIZE + move.l d0,Window + move.l d0,_window + bne.s gotsomewind + pea window_message + MOVINT #ZE_MEM,-(sp) + jsr _ziperr ; never returns +gotsomewind: + tst.l _prev + bne.s gotsomehead + CAL_SH WSIZE + move.l d0,_prev + beq.s nohead + CAL_SH HASH_SIZE + move.l d0,_head + bne.s gotfreshhead ; newly calloc'd memory is zeroed +nohead: pea hash_message + MOVINT #ZE_MEM,-(sp) + jsr _ziperr ; never returns +gotsomehead: + ENDC ; DYN_ALLOC + + move.w #(HASH_SIZE/2)-1,d0 ; two shortwords per loop + BASEPTR _head,a0 +wipeh: clr.l (a0)+ + dbra d0,wipeh +gotfreshhead: + move.l Level,d0 + IFEQ Sizeof_config-8 + asl.l #3,d0 + ELSE + mulu #Sizeof_config,d0 + ENDC + lea config_table,a0 + add.l d0,a0 + move.w Max_lazy(a0),max_lazy_match + move.w Good_length(a0),good_match + move.w Nice_length(a0),nice_match + move.w Max_chain(a0),max_chain_len + CLRINT _strstart + clr.l _block_start + bsr match_init + + clr.w eofile + MOVINT #WSIZE,-(sp) ; We read only 32K because lookahead is short + move.l Window,-(sp) ; even when int size is long, as if deflate.c + move.l _read_buf,a0 ; were compiled with MAXSEG_64K defined. + jsr (a0) + addq #4+INTSIZE,sp + move.w d0,lookahead + beq.s noread + cmp.w #EOF,d0 + bne.s irefill +noread: move.w #1,eofile + clr.w lookahead + bra.s init_done + +irefill: + move.w lookahead,d0 + cmp.w #MIN_LOOKAHEAD,d0 + bhs.s hashify + bsr _fill_window ; use the C-callable version +hashify: + clr.w ins_h + moveq #MIN_MATCH-2,d0 +hash1: move.b (Window)+,d1 + UP_HASH Level,d1 + dbra d0,hash1 + +init_done: + movem.l (sp)+,INIREGS + rts + +; strings for error messages: +hash_message dc.b 'hash table allocation',0 +window_message dc.b 'window allocation',0 +level_message dc.b 'bad pack level',0 + + end diff --git a/amiga/filedate.c b/amiga/filedate.c new file mode 100644 index 0000000..9ccbdda --- /dev/null +++ b/amiga/filedate.c @@ -0,0 +1,599 @@ +/* + Copyright (c) 1990-2002 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* Low-level Amiga routines shared between Zip and UnZip. + * + * Contains: FileDate() + * getenv() [replaces inadequate standard library version] + * setenv() [SAS/C only, replaces standard library version] + * set_TZ() [SAS/C only] + * GetPlatformLocalTimezone() [callback from timezone.c tzset()] + * time() + * sendpkt() + * Agetch() + * + * The first five are used by most Info-ZIP programs except fUnZip. + * The last two are used by all except the non-CRYPT version of fUnZip. + * Probably some of the stuff in here is unused by ZipNote and ZipSplit too... + * sendpkt() is used by Agetch() and FileDate(), and by screensize() in + * amiga/amiga.c (UnZip); time() is used only by Zip. + */ + + +/* HISTORY/CHANGES + * 2 Sep 92, Greg Roelofs, Original coding. + * 6 Sep 92, John Bush, Incorporated into UnZip 5.1 + * 6 Sep 92, John Bush, Interlude "FileDate()" defined, which calls or + * redefines SetFileDate() depending upon AMIGADOS2 definition. + * 11 Oct 92, John Bush, Eliminated AMIGADOS2 switch by determining + * revision via OpenLibrary() call. Now only one version of + * the program runs on both platforms (1.3.x vs. 2.x) + * 11 Oct 92, John Bush, Merged with Zip version and changed arg passing + * to take time_t input instead of struct DateStamp. + * Arg passing made to conform with utime(). + * 22 Nov 92, Paul Kienitz, fixed includes for Aztec and cleaned up some + * lint-ish errors; simplified test for AmigaDOS version. + * 11 Nov 95, Paul Kienitz, added Agetch() for crypt password input and + * UnZip's "More" prompt -- simplifies crypt.h and avoids + * use of library code redundant with sendpkt(). Made it + * available to fUnZip, which does not use FileDate(). + * 22 Nov 95, Paul Kienitz, created a new tzset() that gets the current + * timezone from the Locale preferences. These exist only under + * AmigaDOS 2.1 and up, but it is probably correctly set on more + * Amigas than the TZ environment variable is. We check that + * only if TZ is not validly set. We do not parse daylight + * savings syntax except to check for presence vs. absence of a + * DST part; United States rules are assumed. This is better + * than the tzset()s in the Amiga compilers' libraries do. + * 15 Jan 96, Chr. Spieler, corrected the logic when to select low level + * sendpkt() (when FileDate(), Agetch() or windowheight() is used), + * and AMIGA's Agetch() (CRYPT, and UnZip(SFX)'s UzpMorePause()). + * 10 Feb 96, Paul Kienitz, re-fiddled that selection logic again, moved + * stuff around for clarity. + * 16 Mar 96, Paul Kienitz, created a replacement localtime() to go with the + * new tzset(), because Aztec's is hopelessly broken. Also + * gmtime(), which localtime() calls. + * 12 Apr 96, Paul Kienitz, daylight savings was being handled incorrectly. + * 21 Apr 96, Paul Kienitz, had to replace time() as well, Aztec's returns + * local time instead of GMT. That's why their localtime() was bad, + * because it assumed time_t was already local, and gmtime() was + * the one that checked TZ. + * 23 Apr 96, Chr. Spieler, deactivated time() replacement for UnZip stuff. + * Currently, the UnZip sources do not make use of time() (and do + * not supply the working mktime() replacement, either!). + * 29 Apr 96, Paul Kienitz, created a replacement getenv() out of code that + * was previously embedded in tzset(), for reliable global test + * of whether TZ is set or not. + * 19 Jun 96, Haidinger Walter, re-adapted for current SAS/C compiler. + * 7 Jul 96, Paul Kienitz, smoothed together compiler-related changes. + * 4 Feb 97, Haidinger Walter, added set_TZ() for SAS/C. + * 23 Apr 97, Paul Kienitz, corrected Unix->Amiga DST error by adding + * mkgmtime() so localtime() could be used. + * 28 Apr 97, Christian Spieler, deactivated mkgmtime() definition for ZIP; + * the Zip sources supply this function as part of util.c. + * 24 May 97, Haidinger Walter, added time_lib support for SAS/C and moved + * set_TZ() to time_lib.c. + * 12 Jul 97, Paul Kienitz, adapted time_lib stuff for Aztec. + * 26 Jul 97, Chr. Spieler, old mkgmtime() fixed (ydays[] def, sign vs unsign). + * 30 Dec 97, Haidinger Walter, adaptation for SAS/C using z-stat.h functions. + * 19 Feb 98, Haidinger Walter, removed alloc_remember, more SAS.C fixes. + * 23 Apr 98, Chr. Spieler, removed mkgmtime(), changed FileDate to convert to + * Amiga file-time directly. + * 24 Apr 98, Paul Kienitz, clip Unix dates earlier than 1978 in FileDate(). + * 02 Sep 98, Paul Kienitz, C. Spieler, always include zip.h to get a defined + * header inclusion sequence that resolves all header dependencies. + * 06 Jun 00, Paul Kienitz, removed time_lib.c due to its incompatible license, + * moved set_TZ() back here, replaced minimal tzset() and localtime() + * with new versions derived from GNU glibc source. Gave locale_TZ() + * reasonable European defaults for daylight savings. + * 17 Jun 00, Paul Kienitz, threw out GNU code because of objections to the GPL + * virus, replaced with similar functions based on the public domain + * timezone code at ftp://elsie.nci.nih.gov/pub. As with the GNU + * stuff, support for timezone files and leap seconds was removed. + * 23 Aug 00, Paul Kienitz, moved timezone code out from here into separate + * platform-independent module 'timezone.c'. + * 31 Dec 00, Christian Spieler, moved system-specific timezone help funcions + * back in here, from 'timezone.c'. + * 07 Jan 01, Paul Kienitz, Chr. Spieler, added missing #include "timezone.h" + * and "symbolic" preprocessor constants for time calculations. + * 15 Jan 02, Paul Kienitz, excluded all time handling code from compilation + * for Zip utilities (when "defined(UTIL)") + */ + +#ifndef __amiga_filedate_c +#define __amiga_filedate_c + + +#include "zip.h" +#include <ctype.h> +#include <errno.h> + +#include <exec/types.h> +#include <exec/execbase.h> +#include <exec/memory.h> +#include <dos/dosextens.h> + +#ifdef AZTEC_C +# include <libraries/dos.h> +# include <libraries/dosextens.h> +# include <clib/exec_protos.h> +# include <clib/dos_protos.h> +# include <clib/locale_protos.h> +# include <pragmas/exec_lib.h> +# include <pragmas/dos_lib.h> +# include <pragmas/locale_lib.h> +# define ESRCH ENOENT +# define EOSERR EIO +#endif + +#ifdef __SASC +# include <stdlib.h> +# if (defined(_M68020) && (!defined(__USE_SYSBASE))) + /* on 68020 or higher processors it is faster */ +# define __USE_SYSBASE /* to use the pragma libcall instead of syscall */ +# endif /* to access functions of the exec.library */ +# include <proto/exec.h> /* see SAS/C manual:part 2,chapter 2,pages 6-7 */ +# include <proto/dos.h> +# include <proto/locale.h> +# ifdef DEBUG +# include <sprof.h> +# endif +# ifdef MWDEBUG +# include <stdio.h> /* include both before memwatch.h again just */ +# include <stdlib.h> /* to be safe */ +# include "memwatch.h" +# endif /* MWDEBUG */ +#endif /* __SASC */ + +#include "crypt.h" /* just so we can tell if CRYPT is supported */ + + +#if (!defined(FUNZIP) && !defined(UTIL)) + +#include "timezone.h" /* for AMIGA-specific timezone callbacks */ + +#ifndef SUCCESS +# define SUCCESS (-1L) +# define FAILURE 0L +#endif + +#define ReqVers 36L /* required library version for SetFileDate() */ +#define ENVSIZE 100 /* max space allowed for an environment var */ + +extern struct ExecBase *SysBase; + +#ifndef min +# define min(a, b) ((a) < (b) ? (a) : (b)) +# define max(a, b) ((a) < (b) ? (b) : (a)) +#endif + +#if defined(ZIP) || defined(HAVE_MKTIME) +static const unsigned short ydays[] = + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; +#else +extern const unsigned short ydays[]; /* in unzip's fileio.c */ +#endif + +#define LEAP(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0) +#define YDAYS(m, y) (ydays[m] + (m > 1 && LEAP(y))) +/* Number of leap years from 1978 to `y' (not including `y' itself). */ +#define ANLEAP(y) (((y) - 1977) / 4 - ((y) - 1901) / 100 + ((y) - 1601) / 400) +#define SECSPERMIN 60 +#define MINSPERHOUR 60 +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +#define SECSPERDAY 86400L + +/* prototypes */ +char *getenv(const char *var); +#ifdef __SASC +/* XXX !! We have really got to find a way to operate without these. */ +int setenv(const char *var, const char *value, int overwrite); +void set_TZ(long time_zone, int day_light); +#endif + +LONG FileDate(char *filename, time_t u[]); +LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs); +int Agetch(void); + +/* =============================================================== */ + +/***********************/ +/* Function filedate() */ +/***********************/ + +/* FileDate() (originally utime.c), by Paul Wells. Modified by John Bush + * and others (see also sendpkt() comments, below); NewtWare SetFileDate() + * clone cheaply ripped off from utime(). + */ + +/* DESCRIPTION + * This routine chooses between 2 methods to set the file date on AMIGA. + * Since AmigaDOS 2.x came out, SetFileDate() was available in ROM (v.36 + * and higher). Under AmigaDOS 1.3.x (less than v.36 ROM), SetFileDate() + * must be accomplished by constructing a message packet and sending it + * to the file system handler of the file to be stamped. + * + * The system's ROM version is extracted from the external system Library + * base. + * + * NOTE: although argument passing conforms with utime(), note the + * following differences: + * - Return value is boolean success/failure. + * - If a structure or array is passed, only the first value + * is used, which *may* correspond to date accessed and not + * date modified. + */ + +LONG FileDate(filename, u) + char *filename; + time_t u[]; +{ + LONG SetFileDate(UBYTE *filename, struct DateStamp *pDate); + LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs); + struct MsgPort *taskport; + BPTR dirlock, lock; + struct FileInfoBlock *fib; + LONG pktargs[4]; + UBYTE *ptr; + long ret; + + struct DateStamp pDate; + struct tm *ltm; + int years; + + tzset(); + /* Amiga file date is based on 01-Jan-1978 00:00:00 (local time): + * 8 years and 2 leapdays difference from Unix time. + */ + ltm = localtime(&u[0]); + years = ltm->tm_year + 1900; + if (years < 1978) + pDate.ds_Days = pDate.ds_Minute = pDate.ds_Tick = 0; + else { + pDate.ds_Days = (years - 1978) * 365L + (ANLEAP(years)) + + YDAYS(ltm->tm_mon, years) + (ltm->tm_mday - 1); + pDate.ds_Minute = ltm->tm_hour * 60 + ltm->tm_min; + pDate.ds_Tick = ltm->tm_sec * TICKS_PER_SECOND; + } + + if (SysBase->LibNode.lib_Version >= ReqVers) + { + return (SetFileDate(filename,&pDate)); /* native routine at 2.0+ */ + } + else /* !(SysBase->lib_Version >=ReqVers) */ + { + if( !(taskport = (struct MsgPort *)DeviceProc(filename)) ) + { + errno = ESRCH; /* no such process */ + return FAILURE; + } + + if( !(lock = Lock(filename,SHARED_LOCK)) ) + { + errno = ENOENT; /* no such file */ + return FAILURE; + } + + if( !(fib = (struct FileInfoBlock *)AllocMem( + (long)sizeof(struct FileInfoBlock),MEMF_PUBLIC|MEMF_CLEAR)) ) + { + errno = ENOMEM; /* insufficient memory */ + UnLock(lock); + return FAILURE; + } + + if( Examine(lock,fib)==FAILURE ) + { + errno = EOSERR; /* operating system error */ + UnLock(lock); + FreeMem(fib,(long)sizeof(*fib)); + return FAILURE; + } + + dirlock = ParentDir(lock); + ptr = (UBYTE *)AllocMem(64L,MEMF_PUBLIC); + strcpy((ptr+1),fib->fib_FileName); + *ptr = strlen(fib->fib_FileName); + FreeMem(fib,(long)sizeof(*fib)); + UnLock(lock); + + /* now fill in argument array */ + + pktargs[0] = 0; + pktargs[1] = (LONG)dirlock; + pktargs[2] = (LONG)&ptr[0] >> 2; + pktargs[3] = (LONG)&pDate; + + errno = ret = sendpkt(taskport,ACTION_SET_DATE,pktargs,4L); + + FreeMem(ptr,64L); + UnLock(dirlock); + + return SUCCESS; + } /* ?(SysBase->lib_Version >= ReqVers) */ +} /* FileDate() */ + + +char *getenv(const char *var) /* not reentrant! */ +{ + static char space[ENVSIZE]; + struct Process *me = (void *) FindTask(NULL); + void *old_window = me->pr_WindowPtr; + char *ret = NULL; + + me->pr_WindowPtr = (void *) -1; /* suppress any "Please insert" popups */ + if (SysBase->LibNode.lib_Version >= ReqVers) { + if (GetVar((char *) var, space, ENVSIZE - 1, /*GVF_GLOBAL_ONLY*/ 0) > 0) + ret = space; + } else { /* early AmigaDOS, get env var the crude way */ + BPTR hand, foot, spine; + int z = 0; + if (foot = Lock("ENV:", ACCESS_READ)) { + spine = CurrentDir(foot); + if (hand = Open((char *) var, MODE_OLDFILE)) { + z = Read(hand, space, ENVSIZE - 1); + Close(hand); + } + UnLock(CurrentDir(spine)); + } + if (z > 0) { + space[z] = '\0'; + ret = space; + } + } + me->pr_WindowPtr = old_window; + return ret; +} + +#ifdef __SASC +int setenv(const char *var, const char *value, int overwrite) +{ + struct Process *me = (void *) FindTask(NULL); + void *old_window = me->pr_WindowPtr; + int ret = -1; + + me->pr_WindowPtr = (void *) -1; /* suppress any "Please insert" popups */ + if (SysBase->LibNode.lib_Version >= ReqVers) + ret = !SetVar((char *)var, (char *)value, -1, GVF_GLOBAL_ONLY | LV_VAR); + else { + BPTR hand, foot, spine; + long len = value ? strlen(value) : 0; + if (foot = Lock("ENV:", ACCESS_READ)) { + spine = CurrentDir(foot); + if (len) { + if (hand = Open((char *) var, MODE_NEWFILE)) { + ret = Write(hand, (char *) value, len + 1) >= len; + Close(hand); + } + } else + ret = DeleteFile((char *) var); + UnLock(CurrentDir(spine)); + } + } + me->pr_WindowPtr = old_window; + return ret; +} + +/* Stores data from timezone and daylight to ENV:TZ. */ +/* ENV:TZ is required to exist by some other SAS/C library functions, */ +/* like stat() or fstat(). */ +void set_TZ(long time_zone, int day_light) +{ + char put_tz[MAXTIMEZONELEN]; /* string for putenv: "TZ=aaabbb:bb:bbccc" */ + int offset; + void *exists; /* dummy ptr to see if global envvar TZ already exists */ + exists = (void *)getenv(TZ_ENVVAR); + /* see if there is already an envvar TZ_ENVVAR. If not, create it */ + if (exists == NULL) { + /* create TZ string by pieces: */ + sprintf(put_tz, "GMT%+ld", time_zone / 3600L); + if (time_zone % 3600L) { + offset = (int) labs(time_zone % 3600L); + sprintf(put_tz + strlen(put_tz), ":%02d", offset / 60); + if (offset % 60) + sprintf(put_tz + strlen(put_tz), ":%02d", offset % 60); + } + if (day_light) + strcat(put_tz,"DST"); + setenv(TZ_ENVVAR, put_tz, 1); + } +} +#endif /* __SASC */ + +/* set state as well as possible from settings found in locale.library */ +int GetPlatformLocalTimezone(sp, fill_tzstate_from_rules) + register struct state * ZCONST sp; + void (*fill_tzstate_from_rules)(struct state * ZCONST sp_res, + ZCONST struct rule * ZCONST start, + ZCONST struct rule * ZCONST end); +{ + struct Library *LocaleBase; + struct Locale *ll; + struct Process *me = (void *) FindTask(NULL); + void *old_window = me->pr_WindowPtr; + BPTR eh; + int z, valid = FALSE; + + /* read timezone from locale.library if TZ envvar missing */ + me->pr_WindowPtr = (void *) -1; /* suppress any "Please insert" popups */ + if (LocaleBase = OpenLibrary("locale.library", 0)) { + if (ll = OpenLocale(NULL)) { + z = ll->loc_GMTOffset; /* in minutes */ + if (z == -300) { + if (eh = Lock("ENV:sys/locale.prefs", ACCESS_READ)) { + UnLock(eh); + valid = TRUE; + } else + z = 300; /* bug: locale not initialized, default bogus! */ + } else + valid = TRUE; + if (valid) { + struct rule startrule, stoprule; + + sp->timecnt = 0; + sp->typecnt = 1; + sp->charcnt = 2; + sp->chars[0] = sp->chars[1] = '\0'; + sp->ttis[0].tt_abbrind = 0; + sp->ttis[1].tt_abbrind = 1; + sp->ttis[0].tt_gmtoff = -z * MINSPERHOUR; + sp->ttis[1].tt_gmtoff = -z * MINSPERHOUR + SECSPERHOUR; + sp->ttis[0].tt_isdst = 0; + sp->ttis[1].tt_isdst = 1; + stoprule.r_type = MONTH_NTH_DAY_OF_WEEK; + stoprule.r_day = 0; + stoprule.r_week = 5; + stoprule.r_mon = 10; + stoprule.r_time = 2 * SECSPERHOUR; + startrule = stoprule; + startrule.r_mon = 4; + startrule.r_week = 1; + if (z >= -180 && z < 150) { + /* At this point we make a really gratuitous assumption: */ + /* if the time zone could be Europe, we use the European */ + /* Union rules without checking what country we're in. */ + /* The AmigaDOS locale country codes do not, at least in */ + /* 2.x versions of the OS, recognize very many countries */ + /* outside of Europe and North America. */ + sp->typecnt = 2; + startrule.r_mon = 3; /* one week earlier than US DST */ + startrule.r_week = 5; + } else if (z >= 150 && z <= 480 && + /* no DST in alaska, hawaii */ + (ll->loc_CountryCode == 0x55534100 /*"USA"*/ || + ll->loc_CountryCode == 0x43414E00 /*"CAN"*/)) + sp->typecnt = 2; + /* We check the country code for U.S. or Canada because */ + /* most of Latin America has no DST. Even in these two */ + /* countries there are some exceptions... */ + /* else if... Feel free to add more cases here! */ + + if (sp->typecnt > 1) + (*fill_tzstate_from_rules)(sp, &startrule, &stoprule); + } + CloseLocale(ll); + } + CloseLibrary(LocaleBase); + } + me->pr_WindowPtr = old_window; + return valid; +} + +#ifdef ZIP +time_t time(time_t *tp) +{ + time_t t; + struct DateStamp ds; + DateStamp(&ds); + t = ds.ds_Tick / TICKS_PER_SECOND + ds.ds_Minute * 60 + + (ds.ds_Days + 2922) * SECSPERDAY; + t = mktime(gmtime(&t)); + /* gmtime leaves ds in the local timezone, mktime converts it to GMT */ + if (tp) *tp = t; + return t; +} +#endif /* ZIP */ + +#endif /* !FUNZIP && !UTIL */ + + +#if CRYPT || !defined(FUNZIP) + +/* sendpkt.c + * by A. Finkel, P. Lindsay, C. Sheppner + * returns Res1 of the reply packet + */ +/* +#include <exec/types.h> +#include <exec/memory.h> +#include <libraries/dos.h> +#include <libraries/dosextens.h> +#include <proto/exec.h> +#include <proto/dos.h> +*/ + +LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs); + +LONG sendpkt(pid,action,args,nargs) +struct MsgPort *pid; /* process identifier (handler message port) */ +LONG action, /* packet type (desired action) */ + *args, /* a pointer to argument list */ + nargs; /* number of arguments in list */ +{ + + struct MsgPort *replyport, *CreatePort(UBYTE *, long); + void DeletePort(struct MsgPort *); + struct StandardPacket *packet; + LONG count, *pargs, res1; + + replyport = CreatePort(NULL,0L); + if( !replyport ) return(0); + + packet = (struct StandardPacket *)AllocMem( + (long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR); + if( !packet ) + { + DeletePort(replyport); + return(0); + } + + packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt); + packet->sp_Pkt.dp_Link = &(packet->sp_Msg); + packet->sp_Pkt.dp_Port = replyport; + packet->sp_Pkt.dp_Type = action; + + /* copy the args into the packet */ + pargs = &(packet->sp_Pkt.dp_Arg1); /* address of 1st argument */ + for( count=0; count<nargs; count++ ) + pargs[count] = args[count]; + + PutMsg(pid,(struct Message *)packet); /* send packet */ + + WaitPort(replyport); + GetMsg(replyport); + + res1 = packet->sp_Pkt.dp_Res1; + + FreeMem((char *)packet,(long)sizeof(*packet)); + DeletePort(replyport); + + return(res1); + +} /* sendpkt() */ + +#endif /* CRYPT || !FUNZIP */ + + +#if CRYPT || (defined(UNZIP) && !defined(FUNZIP)) + +/* Agetch() reads one raw keystroke -- uses sendpkt() */ + +int Agetch(void) +{ + LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs); + struct Task *me = FindTask(NULL); + struct CommandLineInterface *cli = BADDR(((struct Process *) me)->pr_CLI); + BPTR fh = cli->cli_StandardInput; /* this is immune to < redirection */ + void *conp = ((struct FileHandle *) BADDR(fh))->fh_Type; + char longspace[8]; + long *flag = (long *) ((ULONG) &longspace[4] & ~3); /* LONGWORD ALIGNED! */ + UBYTE c; + + *flag = 1; + sendpkt(conp, ACTION_SCREEN_MODE, flag, 1); /* assume success */ + Read(fh, &c, 1); + *flag = 0; + sendpkt(conp, ACTION_SCREEN_MODE, flag, 1); + if (c == 3) /* ^C in input */ + Signal(me, SIGBREAKF_CTRL_C); + return c; +} + +#endif /* CRYPT || (UNZIP && !FUNZIP) */ + +#endif /* __amiga_filedate_c*/ diff --git a/amiga/makefile.azt b/amiga/makefile.azt new file mode 100644 index 0000000..d9390c8 --- /dev/null +++ b/amiga/makefile.azt @@ -0,0 +1,304 @@ +# Makefile for Zip, ZipNote, ZipCloak, ZipSplit for Aztec C 5.2 +# Also ZipLM, a version of Zip that needs much less free memory +# -- Paul Kienitz, last updated 07 Jan 2007 + +# Make sure platform is defined correctly, and select memory usage options: +DEFINES = -d AMIGA -d DYN_ALLOC -d ASM_CRC + +CC = cc +AS = as +LD = ln +LDLIBS = -lc16 + + +# -------- RELEASE VERSION: +CFLAGS = -psb0e -sabfmnpu -wcr0u $(DEFINES) +# -pbs means unsigned chars and short ints, -sabfmnpu is various small +# optimizations, -wcr0u adjusts type checking strictness +ASOPTS = -n -eAMIGA -eDYN_ALLOC -eCPUTEST -eINT16 +LDFLAGS = -m +q + +# -------- DEBUG VERSION: +CFLAGD = -bs -psb0e -s0f0n -wcr0u $(DEFINES) +# -bs is include source debugging info, -s0f0n is avoid hard-to-debug +# optimizations +LDFLAGD = -m +q -g -w + +# -------- MINIMUM MEMORY USAGE RELEASE VERSION: +WSIZ = WSIZE=4096 +LOWFLAGS = $(CFLAGS) -d $(WSIZ) -d SMALL_MEM +LOWASOPTS = $(ASOPTS) -e$(WSIZ) -eSMALL_MEM +# Options used for assembling amiga/deflate.a; must generally match the +# settings in DEFINES. + +# -------- MINIMUM MEMORY USAGE DEBUG VERSION: +LOWFLAGD = $(CFLAGD) -d $(WSIZ) -d SMALL_MEM + +# the directory where we stick all the object files: +O = obA/ + + +# default C rules +.c.o : + $(CC) $(CFLAGS) -o $@ $*.c + +# rules for routines containing entries needed by utilities +.c.oo : + $(CC) $(CFLAGS) -d UTIL -o $@ $*.c + +# rules for the low-memory version: + +.c.ol : + $(CC) $(LOWFLAGS) -o $@ $*.c + +# default C rules for debugging +.c.od : + $(CC) $(CFLAGD) -o $@ $*.c + +# debugging rules for routines containing entries needed by utilities +.c.dd : + $(CC) $(CFLAGD) -d UTIL -o $@ $*.c + +# rules for the debugging low-memory version: + +.c.dl : + $(CC) $(LOWFLAGD) -o $@ $*.c + + +# object file lists + +ZIP_H = zip.h ziperr.h tailor.h amiga/osdep.h amiga/z-stat.h + + +OBJZ = $(O)zip.o $(O)deflate.o \ + $(O)trees.o $(O)zipfile.o $(O)zipup.o $(O)util.o $(O)timezone.o \ + $(O)fileio.o $(O)globals.o $(O)crc32.o $(O)crypt.o $(O)ttyio.o \ + $(O)amiga.o $(O)amigazip.o $(O)crc_68.o + +OBJL = $(O)zip.ol $(O)deflate.ol \ + $(O)trees.ol $(O)zipfile.ol $(O)zipup.ol $(O)util.ol $(O)timezone.ol \ + $(O)fileio.ol $(O)globals.ol $(O)crc32.ol $(O)crypt.ol $(O)ttyio.ol \ + $(O)amiga.ol $(O)amigazip.ol $(O)crc_68.o + +OBJU = $(O)zipfile.oo $(O)fileio.oo \ + $(O)util.oo $(O)globals.o $(O)amiga.oo $(O)amigazip.oo +OBJN = $(O)zipnote.o $(OBJU) +OBJC = $(O)zipcloak.o $(OBJU) $(O)crc32.oo \ + $(O)crypt.oo $(O)ttyio.o +OBJS = $(O)zipsplit.o $(OBJU) + +# These are the debuggable versions: + +DBJZ = $(O)zip.od $(O)deflate.od \ + $(O)trees.od $(O)zipfile.od $(O)zipup.od $(O)util.od $(O)timezone.od \ + $(O)fileio.od $(O)globals.od $(O)crc32.od $(O)crypt.od $(O)ttyio.od \ + $(O)amiga.od $(O)amigazip.od $(O)crc_68.o + +DBJL = $(O)zip.dl $(O)deflate.dl \ + $(O)trees.dl $(O)zipfile.dl $(O)zipup.dl $(O)util.dl $(O)timezone.dl \ + $(O)fileio.dl $(O)globals.dl $(O)crc32.dl $(O)crypt.dl $(O)ttyio.dl \ + $(O)amiga.dl $(O)amigazip.dl $(O)crc_68.o + +DBJU = $(O)zipfile.dd $(O)fileio.dd \ + $(O)util.dd $(O)globals.od $(O)amiga.dd $(O)amigazip.dd +DBJN = $(O)zipnote.od $(DBJU) +DBJC = $(O)zipcloak.od $(DBJU) $(O)crc32.dd \ + $(O)crypt.dd $(O)ttyio.od +DBJS = $(O)zipsplit.od $(DBJU) + + +# HERE WE GO: + +all : Zip ZipNote ZipSplit ZipCloak ZipLM + +z : Zip + +n : ZipNote + +s : ZipSplit + +c : ZipCloak + +l : ZipLM + +# Debug versions: + +dall : Zip.dbg ZipNote.dbg ZipSplit.dbg ZipCloak.dbg ZipLM.dbg + +dz : Zip.dbg + +dn : ZipNote.dbg + +ds : ZipSplit.dbg + +dc : ZipCloak.dbg + +dl : ZipLM.dbg + + +Zip : $(OBJZ) $(ZIP_H) + $(LD) $(LDFLAGS) -o $@ $(OBJZ) $(LDLIBS) + -@delete Zip.dbg + +ZipNote : $(OBJN) $(ZIP_H) + $(LD) $(LDFLAGS) -o $@ $(OBJN) $(LDLIBS) + -@delete ZipNote.dbg + +ZipSplit : $(OBJS) $(ZIP_H) + $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS) + -@delete ZipSplit.dbg + +ZipCloak : $(OBJC) $(ZIP_H) + $(LD) $(LDFLAGS) -o $@ $(OBJC) $(LDLIBS) + -@delete ZipCloak.dbg + +ZipLM : $(OBJL) $(ZIP_H) + $(LD) $(LDFLAGS) -o $@ $(OBJL) $(LDLIBS) + -@delete ZipLM.dbg + + +Zip.dbg : $(DBJZ) $(ZIP_H) + $(LD) $(LDFLAGD) -o Zip $(DBJZ) $(LDLIBS) + +ZipNote.dbg : $(DBJN) $(ZIP_H) + $(LD) $(LDFLAGD) -o ZipNote $(DBJN) $(LDLIBS) + +ZipSplit.dbg : $(DBJS) $(ZIP_H) + $(LD) $(LDFLAGD) -o ZipSplit $(DBJS) $(LDLIBS) + +ZipCloak.dbg : $(DBJC) $(ZIP_H) + $(LD) $(LDFLAGD) -o ZipCloak $(DBJC) $(LDLIBS) + +ZipLM.dbg : $(DBJL) $(ZIP_H) + $(LD) $(LDFLAGD) -o ZipLM $(DBJL) $(LDLIBS) + + +clean : bugclean + -delete quiet $(OBJZ) + -delete quiet $(OBJL) + -delete quiet $(O)zipnote.o $(O)zipcloak.o $(O)zipsplit.o \ + $(O)crypt.oo $(OBJU) + +bugclean : + -delete quiet $(DBJZ) + -delete quiet $(DBJL) + -delete quiet $(O)zipnote.od $(O)zipcloak.od $(O)zipsplit.od \ + $(O)crypt.dd $(DBJU) + +cleaner : clean + -delete quiet Zip ZipNote ZipSplit ZipCloak ZipLM + -delete quiet Zip.dbg ZipNote.dbg ZipSplit.dbg ZipCloak.dbg ZipLM.dbg + + +# header dependencies: + +$(O)zip.o $(O)zipnote.o $(O)zipcloak.o $(O)zipsplit.o $(O)crypt.o $(O)ttyio.o \ + $(O)deflate.o $(O)trees.o $(O)zipfile.o $(O)zipup.o $(O)fileio.o $(O)util.o \ + $(O)timezone.o $(O)crc32.o $(O)globals.o $(O)amiga.o : $(ZIP_H) + +$(O)zip.ol $(O)zipnote.ol $(O)zipcloak.ol $(O)zipsplit.ol $(O)crypt.ol \ + $(O)ttyio.ol $(O)deflate.ol $(O)trees.ol $(O)zipfile.ol $(O)zipup.ol \ + $(O)fileio.ol $(O)util.ol $(O)timezone.ol $(O)crc32.ol $(O)globals.ol \ + $(O)amiga.ol : $(ZIP_H) + +$(O)crc32.oo $(O)crypt.oo $(O)zipfile.oo $(O)fileio.oo $(O)util.oo : $(ZIP_H) + +$(O)amigazip.o $(O)amigazip.ol $(O)amigazip.oo : amiga/amiga.h $(ZIP_H) + +$(O)zip.o $(O)zipnote.o $(O)zipcloak.o $(O)zipsplit.o $(O)zipup.o \ + $(O)zip.ol $(O)zipnote.ol $(O)zipcloak.ol $(O)zipsplit.ol \ + $(O)zipup.ol : revision.h + +$(O)amiga.o $(O)amiga.ol : crypt.h + +$(O)crc32.o $(O)crc32.oo $(O)crc32.ol $(O)crypt.o $(O)crypt.oo $(O)crypt.ol \ + $(O)zipcloak.o $(O)zipcloak.ol $(O)zip.o $(O)zip.ol \ + $(O)zipup.o $(O)zipup.ol \ + $(O)zipfile.o $(O)zipfile.oo $(O)zipfile.ol \ + $(O)fileio.o $(O)fileio.oo $(O)fileio.ol : crc32.h + +$(O)crypt.o $(O)crypt.oo $(O)crypt.ol $(O)ttyio.o $(O)ttyio.ol \ + $(O)zipcloak.o $(O)zipcloak.ol $(O)zip.o $(O)zip.ol \ + $(O)zipup.o $(O)zipup.ol : crypt.h ttyio.h + +$(O)timezone.o $(O)timezone.ol $(O)timezone.od $(O)timezone.dl \ + $(O)amiga.o $(O)amiga.ol $(O)amiga.oo : timezone.h + +$(O)zipup.o $(O)zipup.ol : amiga/zipup.h + + +# SPECIAL CASES: + +# -mr changes expression parsing; avoids a bogus "expression too complex" error: +$(O)trees.o : trees.c + $(CC) $(CFLAGS) -mr -o $@ trees.c + +$(O)trees.ol : trees.c + $(CC) $(LOWFLAGS) -mr -o $@ trees.c + +$(O)trees.od : trees.c + $(CC) $(CFLAGD) -mr -o $@ trees.c + +$(O)trees.ld : trees.c + $(CC) $(LOWFLAGD) -mr -o $@ trees.c + +# Substitute the assembly version of deflate.c: (but not in debug version) +$(O)deflate.o : amiga/deflate.a + $(AS) $(ASOPTS) -o $@ amiga/deflate.a + +$(O)deflate.ol : amiga/deflate.a + $(AS) $(LOWASOPTS) -o $@ amiga/deflate.a + +# The assembly CRC function: +$(O)crc_68.o : amiga/crc_68.a + $(AS) -n -o $@ amiga/crc_68.a + +# Put the Amiga internal version data with today's date into amiga.c: +$(O)amiga.o : amiga/amiga.c amiga/filedate.c amiga/stat.c + rx > env:VersionDate "say '""'translate(date('E'), '.', '/')'""'" + $(CC) $(CFLAGS) -o $@ amiga/amiga.c + delete env:VersionDate + +$(O)amiga.ol : amiga/amiga.c amiga/filedate.c amiga/stat.c + rx > env:VersionDate "say '""'translate(date('E'), '.', '/')'""'" + $(CC) $(LOWFLAGS) -o $@ amiga/amiga.c + delete env:VersionDate + +$(O)amiga.od : amiga/amiga.c amiga/filedate.c amiga/stat.c + rx > env:VersionDate "say '""'translate(date('E'), '.', '/')'""'" + $(CC) $(CFLAGD) -o $@ amiga/amiga.c + delete env:VersionDate + +$(O)amiga.ld : amiga/amiga.c amiga/filedate.c amiga/stat.c + rx > env:VersionDate "say '""'translate(date('E'), '.', '/')'""'" + $(CC) $(LOWFLAGD) -o $@ amiga/amiga.c + delete env:VersionDate + +$(O)amiga.oo : amiga/amiga.c amiga/filedate.c amiga/stat.c + rx > env:VersionDate "say '""'translate(date('E'), '.', '/')'""'" + $(CC) $(CFLAGS) -d UTIL -o $@ amiga/amiga.c + delete env:VersionDate + +$(O)amiga.dd : amiga/amiga.c amiga/filedate.c amiga/stat.c + rx > env:VersionDate "say '""'translate(date('E'), '.', '/')'""'" + $(CC) $(CFLAGD) -d UTIL -o $@ amiga/amiga.c + delete env:VersionDate + +# Put the compiler version number into amigazip.c: +$(O)amigazip.o : amiga/amigazip.c + $(CC) $(CFLAGS) -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c + +$(O)amigazip.ol : amiga/amigazip.c + $(CC) $(LOWFLAGS) -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c + +$(O)amigazip.od : amiga/amigazip.c + $(CC) $(CFLAGD) -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c + +$(O)amigazip.ld : amiga/amigazip.c + $(CC) $(LOWFLAGD) -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c + +$(O)amigazip.oo : amiga/amigazip.c + $(CC) $(CFLAGS) -d UTIL -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c + +$(O)amigazip.dd : amiga/amigazip.c + $(CC) $(CFLAGD) -d UTIL -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c diff --git a/amiga/match.a b/amiga/match.a new file mode 100644 index 0000000..ec5bcf0 --- /dev/null +++ b/amiga/match.a @@ -0,0 +1,182 @@ +;=========================================================================== +; 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 +;=========================================================================== +; match.a -- optional optimized asm version of longest match in deflate.c +; Written by Jean-loup Gailly +; Adapted for the Amiga by Carsten Steger <stegerc@informatik.tu-muenchen.de> +; using the code in match.S. +; The major change in this code consists of removing all unaligned +; word accesses, because they cause 68000-based Amigas to crash. +; For maximum speed, UNALIGNED_OK can be defined in Makefile.sasc. +; The program will then only run on 68020-based Amigas, though. +; If you have reduced WSIZE in zip.h, then make sure this is +; assembled with an equivalent -dWSIZE=<whatever>. +; +; This code will run with registerized parameters too, unless SAS +; changes parameter passing conventions between new releases of SAS/C. + + +Cur_Match reg d0 ; Must be in d0! +Best_Len reg d1 +Loop_Counter reg d2 +Scan_Start reg d3 +Scan_End reg d4 +Limit reg d5 +Chain_Length reg d6 +Scan_Test reg d7 +Scan reg a0 +Match reg a1 +Prev_Address reg a2 +Scan_Ini reg a3 +Match_Ini reg a4 + +MAX_MATCH equ 258 +MIN_MATCH equ 3 + ifnd WSIZE +WSIZE equ 32768 + endc +MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1 + + + xref _max_chain_length + xref _prev_length + xref _prev + xref _window + xref _strstart + xref _good_match + xref _match_start + xref _nice_match + + + section match,code + + xdef _match_init + xdef @match_init + xdef _longest_match + xdef @longest_match + + +_match_init: +@match_init: + rts + + +_longest_match: + move.l 4(sp),Cur_Match +@longest_match: + ifd UNALIGNED_OK + movem.l d2-d6/a2-a4,-(sp) + else + movem.l d2-d7/a2-a4,-(sp) + endc + move.l _max_chain_length,Chain_Length + move.l _prev_length,Best_Len + lea _prev,Prev_Address + lea _window+MIN_MATCH,Match_Ini + move.l _strstart,Limit + move.l Match_Ini,Scan_Ini + add.l Limit,Scan_Ini + subi.w #MAX_DIST,Limit + bhi.b limit_ok + moveq #0,Limit +limit_ok: + cmp.l _good_match,Best_Len + bcs.b length_ok + lsr.l #2,Chain_Length +length_ok: + subq.l #1,Chain_Length + + ifd UNALIGNED_OK + + move.w -MIN_MATCH(Scan_Ini),Scan_Start + move.w -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End + + else + + move.b -MIN_MATCH(Scan_Ini),Scan_Start + lsl.w #8,Scan_Start + move.b -MIN_MATCH+1(Scan_Ini),Scan_Start + move.b -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End + lsl.w #8,Scan_End + move.b -MIN_MATCH(Scan_Ini,Best_Len.L),Scan_End + + endc + + bra.b do_scan + +long_loop: + + ifd UNALIGNED_OK + + move.w -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End + + else + + move.b -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End + lsl.w #8,Scan_End + move.b -MIN_MATCH(Scan_Ini,Best_Len.L),Scan_End + + endc + +short_loop: + lsl.w #1,Cur_Match + move.w 0(Prev_Address,Cur_Match.L),Cur_Match + cmp.w Limit,Cur_Match + dbls Chain_Length,do_scan + bra.b return + +do_scan: + move.l Match_Ini,Match + add.l Cur_Match,Match + + ifd UNALIGNED_OK + + cmp.w -MIN_MATCH-1(Match,Best_Len.L),Scan_End + bne.b short_loop + cmp.w -MIN_MATCH(Match),Scan_Start + bne.b short_loop + + else + + move.b -MIN_MATCH-1(Match,Best_Len.L),Scan_Test + lsl.w #8,Scan_Test + move.b -MIN_MATCH(Match,Best_Len.L),Scan_Test + cmp.w Scan_Test,Scan_End + bne.b short_loop + move.b -MIN_MATCH(Match),Scan_Test + lsl.w #8,Scan_Test + move.b -MIN_MATCH+1(Match),Scan_Test + cmp.w Scan_Test,Scan_Start + bne.b short_loop + + endc + + move.w #(MAX_MATCH-MIN_MATCH),Loop_Counter + move.l Scan_Ini,Scan +scan_loop: + cmpm.b (Match)+,(Scan)+ + dbne Loop_Counter,scan_loop + + sub.l Scan_Ini,Scan + addq.l #(MIN_MATCH-1),Scan + cmp.l Best_Len,Scan + bls.b short_loop + move.l Scan,Best_Len + move.l Cur_Match,_match_start + cmp.l _nice_match,Best_Len + bcs.b long_loop +return: + move.l Best_Len,d0 + ifd UNALIGNED_OK + movem.l (sp)+,d2-d6/a2-a4 + else + movem.l (sp)+,d2-d7/a2-a4 + endc + rts + + end diff --git a/amiga/match_68.a b/amiga/match_68.a new file mode 100644 index 0000000..d1a6c39 --- /dev/null +++ b/amiga/match_68.a @@ -0,0 +1,273 @@ +;=========================================================================== +; 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 +;=========================================================================== +; This is a 68000 assembly language version of the Zip function +; longest_match(). It is written for any 680x0 based computer, but at this +; time the feature for runtime testing of CPU type is only supported for the +; Amiga. Hopefully a similar test for the Macintosh is possible, and for any +; other system that supports both 68000 and 68020+ CPUs. This is written by +; Paul Kienitz, partially derived from a simpler version by Carsten Steger, +; derived in turn from a 386 assembly function by Jean-loup Gailly and Kai Uwe +; Rommel... but also based directly on the C original. +; +; The main difference of this from other longest_match() implementations is +; that it includes both byte based and word based versions of the function, +; and various symbols can be defined to select whether to use one routine or +; the other, or to do a platform-specific test at runtime. The symbols that +; can be used to select behavior are as follows: +; +; CPU020 if defined, use 68020 instructions always +; CPUTEST if defined, check at runtime for CPU type. Another symbol +; specifying the platform-specific test must be used with this. +; If neither of these is defined, use 68000 instructions only. +; AMIGA use Amiga-specific test for 68020, if CPUTEST defined. Also +; tells it to let a0/a1/d1 be clobbered by functions. +; ATSIGN define entry symbols in @foo form as well as _foo, with +; @longest_match taking its parm in d0 instead of on the stack. +; WSIZE if defined, determines the sliding window size for deflate; +; the default is 32K. If you have reduced WSIZE for the C code, +; make sure that this module is assembled with an equivalent +; "-dWSIZE=<whatever>" (or "-e...") switch. +; +; NOTE: no provision is made for 16 bit ints. All external int variables are +; treated as 32 bit values. This also assumes that longest_match's result is +; returned in D0. + + IFND CPU020 + IFND CPUTEST +CPU000 equ 1 + ENDC + ENDC + +; global variables: + xref _max_chain_length ; unsigned int + xref _prev_length ; unsigned int + xref _match_start ; unsigned int + xref _strstart ; unsigned int + xref _good_match ; signed int + xref _nice_match ; signed int + xref _window ; array of unsigned char + xref _prev ; array of unsigned short + +; our entry points: + xdef _match_init ; void match_init(void); + xdef _longest_match ; int longest_match(unsigned cur_match); + IFD ATSIGN + xdef @match_init ; for SAS assembler + xdef @longest_match ; ditto + ENDC + +; flag variable for remembering CPU type: + IFD CPUTEST + section cpuflag,data +is020: ds.w 1 + ENDC + + + section match,code +_match_init: + IFD ATSIGN +@match_init: + ENDC + + IFD CPUTEST ; now check for platform type + IFD AMIGA ; Amiga specific test for '020 CPU: + + xref _SysBase + + NOLIST + INCLUDE 'exec/execbase.i' + LIST + + clr.w is020 ; default value is 68000 + move.l _SysBase,a0 + btst #AFB_68020,AttnFlags+1(a0) + beq.s cheap + move.w #1,is020 + +cheap: + ELSE ; !AMIGA + + !! Write an '020-detector for your system here! + + ENDC ; AMIGA + ENDC ; CPUTEST + rts ; match_init consists only of rts if CPUTEST unset + + + IFD AMIGA +SAVEREGS reg d3-d7/a2/a3/a5 ; don't protect d0/d1/a0/a1 + ELSE +SAVEREGS reg d1/d3-d7/a0-a3/a5 ; protect all but d0 return val + ENDC + +Cur_Match equr d0 ; Must be in d0! +Best_Len equr d1 +Scan_Start equr d3 +Scan_End equr d4 +Limit equr d5 +Chain_Length equr d6 +Scan_Test equr d7 +Scan equr a0 +Match equr a1 +Prev_Address equr a2 +Scan_Ini equr a3 +Match_Ini equr a5 + + +MAX_MATCH equ 258 +MIN_MATCH equ 3 + IFND WSIZE +WSIZE equ 32768 + ENDC +MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1 + +_longest_match: + move.l 4(sp),Cur_Match ; stack arg to register + IFD ATSIGN +@longest_match: + ENDC + movem.l SAVEREGS,-(sp) + +; setup steps common to byte and word versions: + move.l _max_chain_length,Chain_Length + move.l _prev_length,Best_Len + lea _prev,Prev_Address + lea _window,Match_Ini + move.l _strstart,Limit + move.l Match_Ini,Scan_Ini + addq #MIN_MATCH,Match_Ini + add.l Limit,Scan_Ini + subi.w #MAX_DIST,Limit + bhi.s limit_ok + moveq #0,Limit +limit_ok: + cmp.l _good_match,Best_Len + bcs.s length_ok + lsr.l #2,Chain_Length +length_ok: + subq.l #1,Chain_Length + + IFD CPUTEST + tst.w is020 ; can we use '020 stuff today? + bne WORD_match + ENDC + + IFND CPU020 + +; for 68000 or 68010, use byte operations: + moveq #0,Scan_Start ; clear 2nd and 4th bytes, use 1st & 3rd + moveq #0,Scan_End + moveq #0,Scan_Test + move.b (Scan_Ini),Scan_Start + swap Scan_Start + move.b 1(Scan_Ini),Scan_Start + move.b -1(Scan_Ini,Best_Len),Scan_End + swap Scan_End + move.b 0(Scan_Ini,Best_Len),Scan_End + bra.s bdo_scan + +blong_loop: + move.b -1(Scan_Ini,Best_Len),Scan_End + swap Scan_End + move.b 0(Scan_Ini,Best_Len),Scan_End + +bshort_loop: + add.w Cur_Match,Cur_Match + move.w 0(Prev_Address,Cur_Match.l),Cur_Match + cmp.l Limit,Cur_Match + dbls Chain_Length,bdo_scan + bra return + +bdo_scan: + move.l Match_Ini,Match + add.l Cur_Match,Match + move.b -MIN_MATCH-1(Match,Best_Len),Scan_Test + swap Scan_Test + move.b -MIN_MATCH(Match,Best_Len),Scan_Test + cmp.l Scan_Test,Scan_End + bne.s bshort_loop + move.b -MIN_MATCH(Match),Scan_Test + swap Scan_Test + move.b -MIN_MATCH+1(Match),Scan_Test + cmp.l Scan_Test,Scan_Start + bne.s bshort_loop + move.w #(MAX_MATCH-MIN_MATCH),Scan_Test + lea MIN_MATCH(Scan_Ini),Scan + +bscan_loop: + cmpm.b (Match)+,(Scan)+ + dbne Scan_Test,bscan_loop + subq #1,Scan + + sub.l Scan_Ini,Scan + cmp.l Best_Len,Scan + bls.s bshort_loop + move.l Scan,Best_Len + move.l Cur_Match,_match_start + cmp.l _nice_match,Best_Len + bcs.s blong_loop + IFD CPUTEST + bra return + ENDC + + ENDC ; !CPU020 + + IFND CPU000 + +; for 68020 or higher, use word operations even on odd addresses: +WORD_match: + move.w (Scan_Ini),Scan_Start + move.w -1(Scan_Ini,Best_Len),Scan_End + bra.s wdo_scan + +wlong_loop: + move.w -1(Scan_Ini,Best_Len),Scan_End + +wshort_loop: + add.w Cur_Match,Cur_Match + move.w (Prev_Address,Cur_Match.l),Cur_Match + cmp.l Limit,Cur_Match + dbls Chain_Length,wdo_scan + bra.s return + +wdo_scan: + move.l Match_Ini,Match + add.l Cur_Match,Match + cmp.w -MIN_MATCH-1(Match,Best_Len),Scan_End + bne.s wshort_loop + cmp.w -MIN_MATCH(Match),Scan_Start + bne.s wshort_loop + moveq #((MAX_MATCH-MIN_MATCH)/2),Scan_Test ; value = 127 + lea MIN_MATCH(Scan_Ini),Scan + +wscan_loop: + cmpm.w (Match)+,(Scan)+ + dbne Scan_Test,wscan_loop + subq #2,Scan + move.b -MIN_MATCH+1(Match),Scan_Test + cmp.b (Scan),Scan_Test + bne steven + addq #1,Scan +steven: + sub.l Scan_Ini,Scan + cmp.l Best_Len,Scan + bls.s wshort_loop + move.l Scan,Best_Len + move.l Cur_Match,_match_start + cmp.l _nice_match,Best_Len + bcs.s wlong_loop + + ENDC ; !CPU000 + +return: + move.l Best_Len,d0 ; function return value + movem.l (sp)+,SAVEREGS + rts + + end diff --git a/amiga/osdep.h b/amiga/osdep.h new file mode 100644 index 0000000..c573cf8 --- /dev/null +++ b/amiga/osdep.h @@ -0,0 +1,119 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2005-Feb-10 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#ifndef __amiga_osdep_h +#define __amiga_osdep_h + +/* default to MEDIUM_MEM, but allow makefile override */ +#if ( (!defined(BIG_MEM)) && (!defined(SMALL_MEM))) +# define MEDIUM_MEM +#endif + +/* check that TZ environment variable is defined before using UTC times */ +#if (!defined(NO_IZ_CHECK_TZ) && !defined(IZ_CHECK_TZ)) +# define IZ_CHECK_TZ +#endif + +#ifndef IZTZ_GETLOCALETZINFO +# define IZTZ_GETLOCALETZINFO GetPlatformLocalTimezone +#endif + +/* AmigaDOS can't even support disk partitions over 4GB, let alone files */ +#define NO_LARGE_FILE_SUPPORT +#ifdef LARGE_FILE_SUPPORT +# undef LARGE_FILE_SUPPORT +#endif + +#define USE_CASE_MAP +#define USE_EF_UT_TIME +#define HANDLE_AMIGA_SFX +#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \ + procname(n, 1)) +#define EXIT(e) ClearIOErr_exit(e) +void ClearIOErr_exit(int e); + +#include "amiga/z-stat.h" + +#ifdef __SASC +# include <sys/types.h> +# include <exec/execbase.h> +# if (defined(_M68020) && (!defined(__USE_SYSBASE))) + /* on 68020 or higher processors it is faster */ +# define __USE_SYSBASE /* to use the pragma libcall instead of syscall */ +# endif /* to access functions of the exec.library */ +# include <proto/exec.h> /* see SAS/C manual:part 2,chapter 2,pages 6-7 */ +# include <proto/dos.h> +# if (defined(_M68020) && !defined(UNALIGNED_OK)) +# define UNALIGNED_OK +# endif +# ifndef REENTRANT +# define REENTRANT +# endif +# if (defined(_NEAR_DATA) && !defined(DYN_ALLOC)) +# define DYN_ALLOC +# endif +# ifdef DEBUG +# include <sprof.h> /* profiler header file */ +# endif +# ifndef IZTZ_SETLOCALTZINFO + /* XXX !! We have really got to find a way to operate without these. */ +# define IZTZ_SETLOCALTZINFO +# endif + +/* + A word on short-integers and SAS/C (a bug of [mc]alloc?) + Using short integers (i.e. compiling with option SHORT-INTEGERS) is + *not* recommended. To get maximum compression ratio the window size stored + in WSIZE should be 32k (0x8000). However, since the size of the window[] + array is 2*WSIZE, 65536 bytes must be allocated. The calloc function can + only allocate UINT_MAX (defined in limits.h) bytes which is one byte short + (65535) of the maximum window size if you are compiling with short-ints. + You'll get an error message "Out of memory (window allocation)" whenever + you try to deflate. Note that the compiler won't produce any warning. + The maximum window size with short-integers is therefore 32768 bytes. + The following is only implemented to allow the use of short-integers but + it is once again not recommended because of a loss in compression ratio. +*/ +# if (defined(_SHORTINT) && !defined(WSIZE)) +# define WSIZE 0x4000 /* only half of maximum window size */ +# endif /* possible with short-integers */ +#endif /* __SASC */ +/* + With Aztec C, using short integers imposes no size limits and makes + the program run faster, even with 32 bit CPUs, so it's recommended. +*/ +#ifdef AZTEC_C +# define NO_UNISTD_H +# define NO_RMDIR +# define BROKEN_FSEEK +# ifndef IZTZ_DEFINESTDGLOBALS +# define IZTZ_DEFINESTDGLOBALS +# endif +#endif + +extern int real_timezone_is_set; +void tzset(void); +#define VALID_TIMEZONE(tempvar) (tzset(), real_timezone_is_set) + +#ifdef ZCRYPT_INTERNAL +# ifndef CLIB_EXEC_PROTOS_H + void *FindTask(void *); +# endif +# define ZCR_SEED2 (unsigned)(ulg)FindTask(NULL) +#endif + +int Agetch(void); /* getch() like function, in amiga/filedate.c */ +char *GetComment(char *); + +#define FOPR "rb" +#define FOPM "rb+" +#define FOPW "wb" +/* prototype for ctrl-C trap function */ +void _abort(void); + +#endif /* !__amiga_osdep_h */ diff --git a/amiga/smakefile b/amiga/smakefile new file mode 100644 index 0000000..ce1317d --- /dev/null +++ b/amiga/smakefile @@ -0,0 +1,662 @@ +#=========================================================================== +# Makefile for Zip, ZipNote, ZipCloak, ZipSplit AMIGA SAS/C Version 6.58 +# Version: 2.3 last revised: 07 Jan 2007 +#=========================================================================== +# -John Bush, <John.Bush@East.Sun.COM> +# or: <JBush@Bix.COM> + +# updated for SAS/C Version 6.56+ and AmigaDOS 3.1 (V40) +# by Haidinger Walter, <walthaid@unix.ict.tuwien.ac.at> + +# additional supplements and maintenance by Paul Kienitz + +# This makefile should work with at least AmigaDOS 2.04 (V37) (not tested) +# and will probably not work with AmigaDOS 1.3 (V34) + +# If you have any improvements, critics or else please feel free to mail. +# Any response is appreciated. Haidinger Walter <walthaid@unix.ict.tuwien.ac.at> + +# Available targets: +# all builds all executeables below +# zip builds zip executeable +# zipsplit builds zipsplit executeable +# zipcloak builds zipcloak executeable +# zipnote builds zipnote executeable +# ziplm builds low memory version of zip executable +# clean remove all files created by the compilation +# spotless like clean target but removes binaries too + + +########################## +# USER MACRO DEFINITIONS # +########################## + +# *** NOTE *** +# The assembly version is not implemented yet. +# (Un)commenting the assembler macros has no effect unless the +# file dependencies are changed too. +# Most of the amiga/*.a files do not assmble with 68000 instructions. +# Any help is appreciated, of course. + +# Set the processor to generate code for. +# Compiler: ANY 68000 68010 68020 68030 68040 68060 +# Assembler: 0 0 1 2 3 4 n/a +# Defaults: ANY and 0 +# +CUSECPU = ANY +AUSECPU = 0 + +# UNCOMMENT to use 68020 instructions in the assembly version of deflate.o +# Only use if code is generated for 68020 or higher processors above. +# Note: You could use CPUTEST too to enable runtime cpu detection. +# However, it is not recommended since both 68000 and 68020 code will be +# included which would be an unnecessary increase in size. +# (see amiga/deflate.a for more information) +# +#AUSE020 = CPU020 + +# To disable the assembler replacements and use the standard C source, +# you have to change the Zip and ZipLM dependencies. See below for details. +# (remember that assembler use is *not* implemented yet) + +# Uncomment both CUTIL and LUTIL to make use of utility.library of OS 2.04+ +# The utility.library is *not* used for UnZipSFX to ensure maximum portability +# between the different Amiga systems (minimal config: 68000 and OS 1.2). +# You can change this by adding the $(LUTIL) macro in the UnZipSFX linking +# rules (See below: Final output targets, UnZipSFX:). +# WARNINGS when using the utility library: +# 1. All Executables will *only* work with AmigaDOS 2.04 (v37) or higher. +# 2. You *need not* compile/link with short-integers using the +# utility.library. It will crash your machine. See Libraries below. +# +# Default: commented (not used) +# +#CUTIL = UTILLIB DEFINE=_UTILLIB +#LUTIL = WITH SC:LIB/utillib.with # include necessary linker defines +# Choose one stack-handling method (default=faster) +# StackExtend: Dynamic runtime stack extension. You won't notice stack overflows. +# StackCheck: On a stack overflow a requester appears which allows you to exit. +# Note that either stack watching will slow down your executable because of the +# extra code run on each function entry. On the other hand, you won't crash +# anymore due to stack overflows. However, you should not have *any* stack +# problems with Info-ZIP programs if you raise your stack to 10000 (which I'd +# recommend as a minimum default stack for all applications) or more using the +# shell stack command. Type 'Stack 20000' or add it to your S:Shell-Startup. +# BTW: Typing 'Stack' prints your current stack size. +# +CSTACK = NOSTACKCHECK STACKEXTEND # slow, but always works +#CSTACK = STACKCHECK NOSTACKEXTEND # slow, requester & graceful exit +#CSTACK = NOSTACKCHECK NOSTACKEXTEND # faster but relies on larger stack (>=10K) + + +# +# LIBRARIES +# --------- + +# Choose one DATAOPTS , SASLIB , ASMOPTS and LSTARTUP +# Always comment/uncomment all macros of a set. + +# Library to use with near data and 2-byte integers +# Notes: o slower than 4-byte integers with 68000 cpu +# o *not* recommended due to poor overall performance +# o see comment in amiga/osdep.h +#DATAOPTS = DATA=NEAR SHORTINTEGERS DEF=_NEAR_DATA +#SASLIB = scs +#ASMOPTS = -dINT16 +#LSTARTUP = cres.o + +# Library to use with near data and 4-byte integers (DEFAULT) +# *** use this with the utility.library *** +DATAOPTS = DATA=NEAR DEF=_NEAR_DATA +SASLIB = sc +ASMOPTS = +LSTARTUP = cres.o + +# Library to use with far data and 2-byte integers +# use if DYN_ALLOC is not defined +# old default - far data always works but is slower +#DATAOPTS = DATA=FAR SHORTINTEGERS DEF=_FAR_DATA +#SASLIB = scsnb +#ASMOPTS = -dINT16 +#LSTARTUP = c.o + +# Library to use with far data and 4-byte integers +# if everything else fails: try this +#DATAOPTS = DATA=FAR DEF=_FAR_DATA +#SASLIB = scnb +#ASMOPTS = +#LSTARTUP = c.o + + +# +# DEBUGGING +# --------- + +# Default: No debugging information added. +# The three macros below will be overwritten if you choose to add +# debug info, therefore no need to comment. + +CDBG = NODEBUG NOPROFILE NOCOVERAGE # default: no debug info +ADBG = +LDBG = STRIPDEBUG # default: no debug info + +# Compiler and loader debug flags. Uncomment as needed. Recomment when done. +# Optimization disabled for faster compilation (by using NOOPT) + +#CDBG1 = DEF=DEBUG DEF=DEBUG_TIME # enables Info-Zip's debug output + +# Enable profiling and coverage when desired. Option COVERAGE commented +# seperately because running coverage may corrupt your drive in case of a +# system crash since a file 'cover.dat' is created in your working directory. +# Note that the use of COVERAGE forces the use of the c.o startup module. + +#CDBG2 = PROFILE +#CDBG3 = COVERAGE # must use c.o startup code: +#LSTARTUP = c.o # Uncomment *only* when you use COVERAGE + +# *Uncomment* here macros CDBG, ADBG and LDBG to include debugging information + +#CDBG = $(CDBG1) $(CDBG2) $(CDBG3) ADDSYM DEBUG=FULLFLUSH STACKCHECK NOOPT +#ADBG = DEBUG +#LDBG = ADDSYM + +# Optional use of memwatch.library which can be found in your +# sc:extras/memlib directory. Please read the short docs (memlib.doc). +# Note that memwatch.library has a small bug: MWTerm() displays always +# the first entry. +# Get the latest version from aminet (dev/debug/memlib.lha) or +# contact me to get the patch. Uncomment all macros to use. +#CMEMLIB = DEFINE=MWDEBUG=1 # define to enable library +#LMEMLIB = SC:LIB/memwatch.lib # path to library +#LSTARTUP = c.o # must use c.o with memlib! + + +# +# MAPPING +# ------- + +# Map filenames used when mapping (no need to comment) +# +MAPFZ = zip.map # Zip map filename +MAPFN = zipnote.map # ZipNote map filename +MAPFC = zipcloak.map # ZipCloak map filename +MAPFS = zipsplit.map # ZipSplit map filename +MAPFL = ziplm.map # Zip low memory version map filename + +# Map file output: Uncomment to highlight and bold headings. +# +#MAPFSTYLE = FANCY + +# Map flags for each EXECUTABLE. Uncomment to enable mapping. +# For map options please refer to: +# SAS/C v6 manual, volume 1: user's guide, chapter 8, page 136: map +# Default: all options enabled: f,h,l,o,s,x +# |-> options start here +#LMAPZ = $(MAPFSTYLE) MAP $(MAPFZ) f,h,l,o,s,x # Zip maps +#LMAPN = $(MAPFSTYLE) MAP $(MAPFN) f,h,l,o,s,x # ZipNote maps +#LMAPC = $(MAPFSTYLE) MAP $(MAPFC) f,h,l,o,s,x # ZipCloak maps +#LMAPS = $(MAPFSTYLE) MAP $(MAPFS) f,h,l,o,s,x # ZipSplit maps +#LMAPL = $(MAPFSTYLE) MAP $(MAPFL) f,h,l,o,s,x # Zip lowmem maps + +# +# LISTINGS +# -------- + +# Listfile-extensions for each executable (enter *with* dot) +# +LISTEXTZ = .lst # extension for Zip listfiles +LISTEXTU = .ulst # extension for utility listfiles (ZipNote,ZipCloak,ZipSplit) +LISTEXTL = .llst # extension for Zip low memory listfiles + + +# List files and cross references for each OBJECT. +# Add/remove flags as needed. Not all listed by default. +# Use LISTINCLUDES to determine the dependencies for smake +# +CLISTOPT = LISTHEADERS LISTMACROS # LISTSYSTEM LISTINCLUDES +CXREFOPT = XHEAD XSYS +# +# Uncomment to enable listing (default: commented) +# *** WARNING: List files require *lots* of disk space! +# +#CLIST = LIST $(CLISTOPT) +#CXREF = XREF $(CXREFOPT) + + +# +# SUPPRESSED COMPILER WARNINGS +# ---------------------------- + +# Compiler warnings to ignore +# +# Warning 105 : module does not define any externally-known symbols +# Warning 304 : Dead assignment eliminated... +# Note 306 : ...function inlined... +# Warning 317 : possibly uninitialized variable... +# Comment to enable. +# +CIGNORE = IGNORE=105,304,306,317 + + +# +# OBJECT EXTENSIONS +# + +# Extensions used for objects of each executeable. +# Transformation rules require unique extensions. +# Enter *with* dot. +# +O = .o # extension for Zip objects +OU = .uo # extension for utility objects (ZipNote, ZipSplit and ZipCloak) +OL = .lo # extension for low memory Zip objects + + +# Filename used to store converted options from environment variable +# LOCAL_ZIP. Default: scoptions_local_zip +# +CWITHOPT = scoptions_local_zip + + +# Filenames to store compiler options to prevent command line overflow +# +# Common options file for Zip and other executables +CFILE = scoptions-zip + + +# Temp filenames for object lists to load using linker "WITH" command. +OBJLISTZ = zip_objlist.with # Zip object list +OBJLISTN = zipnote_objlist.with # ZipNote object list +OBJLISTC = zipcloak_objlist.with # ZipCloak object list +OBJLISTS = zipsplit_objlist.with # ZipSplit object list +OBJLISTL = ziplm_objlist.with # Zip low-mem object list + + +# Filenames to store linker options +# +LWITHZ = zip.lnk # zip linker options +LWITHN = zipnote.lnk # zipnote linker options +LWITHC = zipcloak.lnk # zipcloak linker options +LWITHS = zipsplit.lnk # zipsplit linker options +LWITHL = ziplm.lnk # zip low-mem linker options + + +# Define AMIGA_BETA to print "Beta Notice" up front. See tailor.h. +# Undefine AMIGA_BETA when building a released version. +#CDEFBETA = DEF=AMIGA_BETA + +##################################### +# NOTHING TO CHANGE BEYOND HERE ... # +##################################### +# (except for C/asm dependencies) + +# Define MEDIUM_MEM for production release (per Paul Kienitz). +# This reduces runtime memory requirement but not speed or compression. +# Note: Do *not* use BIG_MEM or MMAP since it isn't yet supported by the + assembler version of deflate.c : amiga/deflate.a +CUSEMEM = DEF=MEDIUM_MEM +AUSEMEM = -DMEDIUM_MEM # for asm deflate.o, must match above + + +# Defines for building low-memory use version of Zip +WSIZEL = WSIZE=4096 # deflate.c window size for low-mem version +CLOWMEM = DEF=SMALL_MEM DEF=$(WSIZEL) +ALOWMEM = -DSMALL_MEM -D$(WSIZEL) # for asm deflate.o, must match above + + +# Compiler definitions +# +CC = sc +# +# Optimizer flags +# +OPTPASSES = 6 # set number of global optimizer passes +# +OPT1 = OPT OPTINL OPTINLOCAL OPTTIME OPTLOOP OPTSCHED +OPT2 = OPTCOMP=$(OPTPASSES) OPTDEP=$(OPTPASSES) OPTRDEP=$(OPTPASSES) +OPT = $(OPT1) $(OPT2) + + +# Compiler flags +# +CDEFINES = $(CMEMLIB) $(CDEFBETA) DEF=AMIGA +COPTIONS = $(DATAOPTS) CODE=NEAR CPU=$(CUSECPU) VERBOSE PARAMETERS=BOTH NOMINC +COPTIONS = $(COPTIONS) ERRORREXX NOERRORCONSOLE MEMSIZE=HUGE $(CLIST) $(CXREF) +COPTIONS = $(COPTIONS) $(CSTACK) $(CUTIL) STRICT UNSCHAR NOICONS STRINGMERGE +CFLAGS = $(CDEFINES) $(COPTIONS) $(OPT) $(CDBG) $(CIGNORE) + + +# Linker definitions +# See SASLIB definition above +# +LD = slink +# special linker flags for pure (i.e. resident) binary. +LDFLAGSS = FROM SC:LIB/$(LSTARTUP) +# common linker flags for all other executeables +LDFLAGSC = FROM SC:LIB/c.o +LDFLAGS2 = NOICONS $(LDBG) +LIBFLAGS = LIB $(LMEMLIB) SC:LIB/$(SASLIB).lib SC:LIB/amiga.lib + + +# Assembler definitions +# +ASM = asm +# +# Options used for assembling amiga/deflate.a +# Must match defines in C-Source. +# +AFLAGS0 = -d__SASC -dSASC -dAMIGA +AFLAGS1 = $(AUSE020) $(ASMOPTS) $(ADBG) +AFLAGS2 = -m$(AUSECPU) -jm -iINCLUDE: +AFLAGS = $(AFLAGS0) $(AFLAGS1) $(AFLAGS2) +ASMOPTSZ = $(AFLAGS) $(AUSEMEM) -dDYN_ALLOC # Zip asm flags +ASMOPTSL = $(AFLAGS) $(ALOWMEM) # Zip low-mem version asm flags + + +################## +# TARGET OBJECTS # +################## + + +# Zip objects +OBJZ1 = zip$(O) zipfile$(O) zipup$(O) fileio$(O) util$(O) globals$(O) +OBJZ2 = crc32$(O) crypt$(O) timezone$(O) ttyio$(O) +OBJZI = deflate$(O) trees$(O) +OBJZA = amiga$(O) amigazip$(O) stat$(O) filedate$(O) +OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZI) $(OBJZA) + +# Shared utility objects for ZipNote, ZipCloak and ZipSplit +OBJU1 = globals$(O) +OBJUU = zipfile$(OU) fileio$(OU) timezone$(O) util$(OU) +OBJUA = amigazip$(OU) amiga$(O) stat$(O) filedate$(O) +OBJU = $(OBJU1) $(OBJUU) $(OBJUA) + +# ZipNote objects +OBJN1 = zipnote$(O) +OBJN = $(OBJN1) $(OBJU) + +# ZipCloak objects +OBJC1 = zipcloak$(O) +OBJCU = $(OBJU) crypt$(OU) +OBJCS = crc32$(OU) ttyio$(O) +OBJC = $(OBJC1) $(OBJCU) $(OBJCS) + +#ZipSplit objects +OBJS1 = zipsplit$(O) +OBJS = $(OBJS1) $(OBJU) + +# ZipLM objects +OBJL1 = zip$(OL) zipfile$(OL) zipup$(OL) fileio$(OL) util$(OL) globals$(OL) +OBJL2 = crc32$(OL) crypt$(OL) timezone$(OL) ttyio$(OL) +OBJLI = deflate$(OL) trees$(OL) +OBJLA = amiga$(OL) amigazip$(OL) stat$(OL) filedate$(OL) +OBJL = $(OBJL1) $(OBJL2) $(OBJLI) $(OBJLA) + +# Common header files +ZIP_H1 = zip.h ziperr.h tailor.h +ZIP_HA = amiga/osdep.h amiga/z-stat.h +ZIP_H = $(ZIP_H1) $(ZIP_HA) + +# Output targets +ZIPS = Zip ZipNote ZipCloak ZipSplit ZipLM + + +# Temp filenames for object lists to load using linker "WITH" command. +OBJLISTZ = zip_objlist.with # Zip object list +OBJLISTN = zipnote_objlist.with # ZipNote object list +OBJLISTC = zipcloak_objlist.with # ZipCloak object list +OBJLISTS = zipsplit_objlist.with # ZipSplit object list +OBJLISTL = ziplm_objlist.with # Zip low-mem object list + +####################################### +# DEFAULT TARGET AND PROCESSING RULES # +####################################### + +all: request flush $(ZIPS) + +# Zip transformation rules +# +.c$(O): + $(CC) WITH=$(CFILE) $(CUSEMEM) LISTFILE=$>$(LISTEXTZ) OBJNAME=$@ $*.c + +# Zip low-memory version transformation rules +# +.c$(OL): + $(CC) WITH=$(CFILE) $(CLOWMEM) LISTFILE=$>$(LISTEXTL) OBJNAME=$@ $*.c + +# Utilities (ZipNote, ZipCloak and ZipSplit) transformation rules +# +.c$(OU): + $(CC) WITH=$(CFILE) $(CUSEMEM) DEF=UTIL LISTFILE=$>$(LISTEXTU) OBJNAME=$@ $*.c + + +######################### +# Final output targets. # +######################### + + +zip: local_zip CommonFlags $(OBJZ) + @Echo "$(OBJZ)" > $(OBJLISTZ) + Type $(OBJLISTZ) + @Echo "$(LDFLAGSS) $(LUTIL) WITH $(OBJLISTZ) $(LIBFLAGS)" \ + "$(LDFLAGS2) $(LMAPZ)" >$(LWITHZ) + Type $(LWITHZ) + $(LD) TO Zip WITH $(LWITHZ) + +zipnote: local_zip CommonFlags $(OBJN) + @Echo "$(OBJN)" > $(OBJLISTN) + Type $(OBJLISTN) + @Echo "$(LDFLAGSS) $(LUTIL) WITH $(OBJLISTN) $(LIBFLAGS) " \ + "$(LDFLAGS2) $(LMAPN)" >$(LWITHN) + Type $(LWITHN) + $(LD) TO ZipNote WITH $(LWITHN) + +zipcloak: local_zip CommonFlags $(OBJC) + @Echo "$(OBJC)" > $(OBJLISTC) + Type $(OBJLISTC) + @Echo "$(LDFLAGSS) $(LUTIL) WITH $(OBJLISTC) $(LIBFLAGS) " \ + "$(LDFLAGS2) $(LMAPC)" >$(LWITHC) + Type $(LWITHC) + $(LD) TO ZipCloak WITH $(LWITHC) + +zipsplit: local_zip CommonFlags $(OBJS) + @Echo "$(OBJS)" > $(OBJLISTS) + Type $(OBJLISTS) + @Echo "$(LDFLAGSS) $(LUTIL) WITH $(OBJLISTS) $(LIBFLAGS) " \ + "$(LDFLAGS2) $(LMAPS)" >$(LWITHS) + Type $(LWITHS) + $(LD) TO ZipSplit WITH $(LWITHS) + +ziplm: local_zip CommonFlags $(OBJL) + @Echo "$(OBJL)" > $(OBJLISTL) + Type $(OBJLISTL) + @Echo "$(LDFLAGSS) $(LUTIL) WITH $(OBJLISTL) $(LIBFLAGS) " \ + "$(LDFLAGS2) $(LMAPL)" >$(LWITHL) + Type $(LWITHL) + $(LD) TO ZipLM WITH $(LWITHL) + + +clean: + -Delete >nil: $(OBJZ) quiet + -Delete >nil: $(OBJN) quiet + -Delete >nil: $(OBJC) quiet + -Delete >nil: $(OBJS) quiet + -Delete >nil: $(OBJL) quiet + -Delete >nil: $(OBJLISTZ) $(OBJLISTL) $(OBJLISTN) $(OBJLISTS) $(OBJLISTC) quiet + -Delete >nil: $(MAPFZ) $(MAPFN) $(MAPFC) $(MAPFS) $(MAPFL) quiet + -Delete >nil: \#?$(LISTEXTZ) \#?$(LISTEXTU) \#?$(LISTEXTL) quiet + -Delete >nil: $(CWITHOPT) $(CFILE) quiet + -Delete >nil: $(LWITHZ) $(LWITHN) $(LWITHC) $(LWITHS) $(LWITHL) quiet + -Delete >nil: env:VersionDate quiet + -Delete >nil: \#?.q.?? \#?.tmp \#?.cov quiet + +spotless: clean + -Delete >nil: $(ZIPS) quiet + + +################ +# DEPENDENCIES # +################ + +# To change between the assembler and C sources, you have to comment/uncomment +# the approprite lines. C sources are marked by #C-src and assembler sources +# #asm-src at the end. +# Zip dependencies: +# + +zip$(O): zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +zipup$(O): zipup.c $(ZIP_H) revision.h crc32.h crypt.h amiga/zipup.h +zipfile$(O): zipfile.c $(ZIP_H) revision.h crc32.h +crypt$(O): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h +ttyio$(O): ttyio.c $(ZIP_H) crypt.h ttyio.h +deflate$(O): deflate.c $(ZIP_H) #C-src +trees$(O): trees.c $(ZIP_H) +fileio$(O): fileio.c $(ZIP_H) crc32.h +util$(O): util.c $(ZIP_H) +crc32$(O): crc32.c $(ZIP_H) crc32.h +globals$(O): globals.c $(ZIP_H) +timezone$(O): timezone.c $(ZIP_H) timezone.h +# Amiga specific objects +stat$(O): amiga/stat.c amiga/z-stat.h +filedate$(O): amiga/filedate.c crypt.h timezone.h +amiga$(O): amiga/amiga.c ziperr.h +amigazip$(O): amiga/amigazip.c $(ZIP_H) amiga/amiga.h env:Workbench +# Substitute assembly version of deflate.c: +#deflate$(O): amiga/deflate.a #asm-src +# $(ASM) $(ASMOPTSZ) -o$@ $*.a #asm-src + + +# Utility (ZipNote, ZipCloak, ZipSplit) dependencies: +# +zipnote$(O): zipnote.c $(ZIP_H) revision.h +zipcloak$(O): zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +zipsplit$(O): zipsplit.c $(ZIP_H) revision.h +zipfile$(OU): zipfile.c $(ZIP_H) revision.h crc32.h +fileio$(OU): fileio.c $(ZIP_H) crc32.h +util$(OU): util.c $(ZIP_H) +crc32$(OU): crc32.c $(ZIP_H) crc32.h +crypt$(OU): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h +# Amiga specific objects +amigazip$(OU): amiga/amigazip.c $(ZIP_H) amiga/amiga.h env:Workbench + +# ZipLM dependencies: +# +zip$(OL): zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +zipup$(OL): zipup.c $(ZIP_H) revision.h crc32.h crypt.h amiga/zipup.h +zipfile$(OL): zipfile.c $(ZIP_H) revision.h crc32.h +crypt$(OL): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h +ttyio$(OL): ttyio.c $(ZIP_H) crypt.h ttyio.h +deflate$(OL): deflate.c $(ZIP_H) +trees$(OL): trees.c $(ZIP_H) +fileio$(OL): fileio.c $(ZIP_H) crc32.h +util$(OL): util.c $(ZIP_H) +crc32$(OL): crc32.c $(ZIP_H) +globals$(OL): globals.c $(ZIP_H) +timezone$(OL): timezone.c $(ZIP_H) timezone.h +# Amiga specific objects +stat$(OL): amiga/stat.c amiga/z-stat.h +filedate$(OL): amiga/filedate.c crypt.h timezone.h +amiga$(OL): amiga/amiga.c ziperr.h +# Substitute assembly version of deflate.c: +#deflate$(OL): amiga/deflate.a +# $(ASM) $(ASMOPTSL) -o$@ $*.a + + +######################## +# DEPENDECIES END HERE # +######################## + +# flush all libraries to provide more mem for compilation +flush: + @Avail flush >nil: + +# write common compiler flags to file and echo to user +CommonFlags: + @Echo "$(CFLAGS)" >$(CFILE) + @Type "$(CWITHOPT)" >>$(CFILE) + -Type $(CFILE) + + +# special rules for adding Amiga internal version number to amiga/amiga.c +amiga$(O): + rx > env:VersionDate "say '""'translate(date('E'),'.','/')'""'" + $(CC) WITH=$(CFILE) $(CUSEMEM) LISTFILE=$>$(LISTEXTZ) OBJNAME=$@ $*.c + -Delete env:VersionDate + +amiga$(OL): + rx > env:VersionDate "say '""'translate(date('E'),'.','/')'""'" + $(CC) WITH=$(CFILE) $(CLOWMEM) LISTFILE=$>$(LISTEXTL) OBJNAME=$@ $*.c + -Delete env:VersionDate + + +# needed in amiga/amigazip.c +# should be set in startup-sequence, but just in case: +# (only works with OS 2.0 and above) + +env\:WorkBench: + @Execute < < (Workbench_smk.tmp) + FailAt 21 + If not exists ENV:Workbench + Version >nil: + SetEnv Workbench $$Workbench + Endif + < + + +# Read environment variable LOCAL_ZIP and convert options to SAS format +# +# e.g.: to define FOO_ONE and FOO_TWO enter: +# +# SetEnv LOCAL_ZIP "-DFOO_ONE -DFOO_TWO" +# +# Put the statement into your startup-sequence or (for AmigaDOS 2.0 or higher +# only) make sure LOCAL_ZIP is stored in the ENVARC: directory +# ( Copy ENV:LOCAL_ZIP ENVARC: ) +# + +local_zip: + @Execute < < (Local_Zip_smk.tmp) + Failat 21 + If exists ENV:LOCAL_ZIP + Echo "Using environment variable LOCAL_ZIP !" + Copy >NIL: ENV:LOCAL_ZIP SASCOPTS + Else + Echo "You could use envvar ZIP_OPT to set your special compilation options." + Delete >nil: SASCOPTS quiet + Endif + ; Do not remove the lctosc command! If LOCAL_ZIP is unset, an + ; empty file is created which needed by CommonFlags ! + lctosc >$(CWITHOPT) + < + + + +# Echo request to the user +# +request: + @Echo "" + @Echo " This makefile is for use with SAS/C version 6.58." + @Echo " If you still have an older version, please upgrade!" + @Echo " Patches are available on the Aminet under biz/patch/sc\#?." + @Echo "" + @Echo " Just a simple request..." + @Echo " Please give me a mail that you compiled whether you encounter any errors" + @Echo " or not. I'd just like to know how many Amiga users actually make use of" + @Echo " this makefile." + @Echo " If you mail me, I'll put you on my mailing-list and notify you whenever" + @Echo " new versions of Info-Zip are released." + @Echo " Have a look at the makefile for changes like CPU type, UtilLib, etc." + @Echo " Feel free to mail comments, suggestions, etc." + @Echo " Enjoy Info-Zip !" + @Echo " Haidinger Walter, <walthaid@unix.ict.tuwien.ac.at>" + @Echo "" + + +# Echo help in case of an error +# +.ONERROR: + @Echo "" + @Echo "[sigh] An error running this makefile was detected." + @Echo "This message may also appear if you interrupted smake by pressing CTRL-C." + @Echo "Contact Info-Zip authors at Zip-Bugs@lists.wku.edu or me for help." + @Echo "Haidinger Walter, <walthaid@unix.ict.tuwien.ac.at>" + diff --git a/amiga/stat.c b/amiga/stat.c new file mode 100644 index 0000000..6075c21 --- /dev/null +++ b/amiga/stat.c @@ -0,0 +1,293 @@ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* Here we have a handmade stat() function because Aztec's c.lib stat() */ +/* does not support an st_mode field, which we need... also a chmod(). */ + +/* This stat() is by Paul Wells, modified by Paul Kienitz. */ +/* Originally for use with Aztec C >= 5.0 and Lattice C <= 4.01 */ +/* Adapted for SAS/C 6.5x by Haidinger Walter */ + +/* POLICY DECISION: We will not attempt to remove global variables from */ +/* this source file for Aztec C. These routines are essentially just */ +/* augmentations of Aztec's c.lib, which is itself not reentrant. If */ +/* we want to produce a fully reentrant UnZip, we will have to use a */ +/* suitable startup module, such as purify.a for Aztec by Paul Kienitz. */ + +#ifndef __amiga_stat_c +#define __amiga_stat_c + +#include <exec/types.h> +#include <exec/memory.h> +#include "amiga/z-stat.h" /* fake version of stat.h */ +#include <string.h> + +#ifdef AZTEC_C +# include <libraries/dos.h> +# include <libraries/dosextens.h> +# include <clib/exec_protos.h> +# include <clib/dos_protos.h> +# include <pragmas/exec_lib.h> +# include <pragmas/dos_lib.h> +#endif +#ifdef __SASC +# include <sys/dir.h> /* SAS/C dir function prototypes */ +# include <sys/types.h> +# include <proto/exec.h> +# include <proto/dos.h> +#endif + +#ifndef SUCCESS +# define SUCCESS (-1) +# define FAILURE (0) +#endif + + +void close_leftover_open_dirs(void); /* prototype */ + +static DIR *dir_cleanup_list = NULL; /* for resource tracking */ + +/* CALL THIS WHEN HANDLING CTRL-C OR OTHER UNEXPECTED EXIT! */ +void close_leftover_open_dirs(void) +{ + while (dir_cleanup_list) + closedir(dir_cleanup_list); +} + + +unsigned short disk_not_mounted; + +extern int stat(const char *file, struct stat *buf); + +stat(file,buf) +const char *file; +struct stat *buf; +{ + + struct FileInfoBlock *inf; + BPTR lock; + time_t ftime; + struct tm local_tm; + + if( (lock = Lock((char *)file,SHARED_LOCK))==0 ) + /* file not found */ + return(-1); + + if( !(inf = (struct FileInfoBlock *)AllocMem( + (long)sizeof(struct FileInfoBlock),MEMF_PUBLIC|MEMF_CLEAR)) ) + { + UnLock(lock); + return(-1); + } + + if( Examine(lock,inf)==FAILURE ) + { + FreeMem((char *)inf,(long)sizeof(*inf)); + UnLock(lock); + return(-1); + } + + /* fill in buf */ + buf->st_dev = + buf->st_nlink = + buf->st_uid = + buf->st_gid = + buf->st_rdev = 0; + buf->st_ino = inf->fib_DiskKey; + buf->st_blocks = inf->fib_NumBlocks; + buf->st_size = inf->fib_Size; + + /* now the date. AmigaDOS has weird datestamps--- + * ds_Days is the number of days since 1-1-1978; + * however, as Unix wants date since 1-1-1970... + */ + + ftime = + (inf->fib_Date.ds_Days * 86400 ) + + (inf->fib_Date.ds_Minute * 60 ) + + (inf->fib_Date.ds_Tick / TICKS_PER_SECOND ) + + (86400 * 8 * 365 ) + + (86400 * 2 ); /* two leap years */ + + /* tzset(); */ /* this should be handled by mktime(), instead */ + /* ftime += timezone; */ + local_tm = *gmtime(&ftime); + local_tm.tm_isdst = -1; + ftime = mktime(&local_tm); + + buf->st_ctime = + buf->st_atime = + buf->st_mtime = ftime; + + buf->st_mode = (inf->fib_DirEntryType < 0 ? S_IFREG : S_IFDIR); + + /* lastly, throw in the protection bits */ + buf->st_mode |= ((inf->fib_Protection ^ 0xF) & 0xFF); + + FreeMem((char *)inf, (long)sizeof(*inf)); + UnLock((BPTR)lock); + + return(0); + +} + +int fstat(int handle, struct stat *buf) +{ + /* fake some reasonable values for stdin */ + buf->st_mode = (S_IREAD|S_IWRITE|S_IFREG); + buf->st_size = -1; + buf->st_mtime = time(&buf->st_mtime); + return 0; +} + + +/* opendir(), readdir(), closedir(), rmdir(), and chmod() by Paul Kienitz. */ + +DIR *opendir(const char *path) +{ + DIR *dd = AllocMem(sizeof(DIR), MEMF_PUBLIC); + if (!dd) return NULL; + if (!(dd->d_parentlock = Lock((char *)path, MODE_OLDFILE))) { + disk_not_mounted = IoErr() == ERROR_DEVICE_NOT_MOUNTED; + FreeMem(dd, sizeof(DIR)); + return NULL; + } else + disk_not_mounted = 0; + if (!Examine(dd->d_parentlock, &dd->d_fib) || dd->d_fib.fib_EntryType < 0) { + UnLock(dd->d_parentlock); + FreeMem(dd, sizeof(DIR)); + return NULL; + } + dd->d_cleanuplink = dir_cleanup_list; /* track them resources */ + if (dir_cleanup_list) + dir_cleanup_list->d_cleanupparent = &dd->d_cleanuplink; + dd->d_cleanupparent = &dir_cleanup_list; + dir_cleanup_list = dd; + return dd; +} + +void closedir(DIR *dd) +{ + if (dd) { + if (dd->d_cleanuplink) + dd->d_cleanuplink->d_cleanupparent = dd->d_cleanupparent; + *(dd->d_cleanupparent) = dd->d_cleanuplink; + if (dd->d_parentlock) + UnLock(dd->d_parentlock); + FreeMem(dd, sizeof(DIR)); + } +} + +struct dirent *readdir(DIR *dd) +{ + return (ExNext(dd->d_parentlock, &dd->d_fib) ? (struct dirent *)dd : NULL); +} + + +#ifdef AZTEC_C + +int rmdir(const char *path) +{ + return (DeleteFile((char *)path) ? 0 : IoErr()); +} + +int chmod(const char *filename, int bits) /* bits are as for st_mode */ +{ + long protmask = (bits & 0xFF) ^ 0xF; + return !SetProtection((char *)filename, protmask); +} + + +/* This here removes unnecessary bulk from the executable with Aztec: */ +void _wb_parse(void) { } + +/* fake a unix function that does not apply to amigados: */ +int umask(void) { return 0; } + + +# include <signal.h> + +/* C library signal() messes up debugging yet adds no actual usefulness */ +typedef void (*__signal_return_type)(int); +__signal_return_type signal() { return SIG_ERR; } + + +/* The following replaces Aztec's argv-parsing function for compatibility with +Unix-like syntax used on other platforms. It also fixes the problem the +standard _cli_parse() has of accepting only lower-ascii characters. */ + +int _argc, _arg_len; +char **_argv, *_arg_lin; + +void _cli_parse(struct Process *pp, long alen, register UBYTE *aptr) +{ + register UBYTE *cp; + register struct CommandLineInterface *cli; + register short c; + register short starred = 0; +# ifdef PRESTART_HOOK + void Prestart_Hook(void); +# endif + + cli = (struct CommandLineInterface *) (pp->pr_CLI << 2); + cp = (UBYTE *) (cli->cli_CommandName << 2); + _arg_len = cp[0] + alen + 2; + if (!(_arg_lin = AllocMem((long) _arg_len, 0L))) + return; + c = cp[0]; + strncpy(_arg_lin, cp + 1, c); + _arg_lin[c] = 0; + for (cp = _arg_lin + c + 1; alen && (*aptr < '\n' || *aptr > '\r'); alen--) + *cp++ = *aptr++; + *cp = 0; + aptr = cp = _arg_lin + c + 1; + for (_argc = 1; ; _argc++) { + while (*cp == ' ' || *cp == '\t') + cp++; + if (!*cp) + break; + if (*cp == '"') { + cp++; + while (c = *cp++) { + if (c == '"' && !starred) { + *aptr++ = 0; + starred = 0; + break; + } else if (c == '\\' && !starred) + starred = 1; + else { + *aptr++ = c; + starred = 0; + } + } + } else { + while ((c = *cp++) && c != ' ' && c != '\t') + *aptr++ = c; + *aptr++ = 0; + } + if (c == 0) + --cp; + } + *aptr = 0; + if (!(_argv = AllocMem((_argc + 1) * sizeof(*_argv), 0L))) { + _argc = 0; + return; + } + for (c = 0, cp = _arg_lin; c < _argc; c++) { + _argv[c] = cp; + cp += strlen(cp) + 1; + } + _argv[c] = NULL; +# ifdef PRESTART_HOOK + Prestart_Hook(); +# endif +} + +#endif /* AZTEC_C */ + +#endif /* __amiga_stat_c */ diff --git a/amiga/z-stat.h b/amiga/z-stat.h new file mode 100644 index 0000000..53d6cd1 --- /dev/null +++ b/amiga/z-stat.h @@ -0,0 +1,95 @@ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#ifndef __amiga_z_stat_h +#define __amiga_z_stat_h + +/* Since older versions of the Lattice C compiler for Amiga, and all current */ +/* versions of the Manx Aztec C compiler for Amiga, either provide no stat() */ +/* function or provide one inadequate for unzip (Aztec's has no st_mode */ +/* field), we provide our own stat() function in stat.c by Paul Wells, and */ +/* this fake stat.h file by Paul Kienitz. Paul Wells originally used the */ +/* Lattice stat.h but that does not work for Aztec and is not distributable */ +/* with this package, so I made a separate one. This has to be pulled into */ +/* unzip.h when compiling an Amiga version, as "amiga/z-stat.h". */ + +/* We also provide here a "struct dirent" for use with opendir() & readdir() */ +/* functions included in amiga/stat.c. If you use amiga/stat.c, this must */ +/* be included wherever you use either readdir() or stat(). */ + +#ifdef AZTEC_C +# define __STAT_H +#else /* __SASC */ +/* do not include the following header, replacement definitions are here */ +# define _STAT_H /* do not include SAS/C <stat.h> */ +# define _DIRENT_H /* do not include SAS/C <dirent.h> */ +# define _SYS_DIR_H /* do not include SAS/C <sys/dir.h> */ +# define _COMMIFMT_H /* do not include SAS/C <sys/commifmt.h> */ +# include <dos.h> +#endif +#include <libraries/dos.h> +#include <time.h> + + +struct stat { + unsigned short st_mode; + time_t st_ctime, st_atime, st_mtime; + long st_size; + long st_ino; + long st_blocks; + short st_attr, st_dev, st_nlink, st_uid, st_gid, st_rdev; +}; + +#define S_IFDIR (1<<11) +#define S_IFREG (1<<10) + +#if 0 + /* these values here are totally random: */ +# define S_IFLNK (1<<14) +# define S_IFSOCK (1<<13) +# define S_IFCHR (1<<8) +# define S_IFIFO (1<<7) +# define S_IFMT (S_IFDIR|S_IFREG|S_IFCHR|S_IFLNK) +#else +# define S_IFMT (S_IFDIR|S_IFREG) +#endif + +#define S_IHIDDEN (1<<7) +#define S_ISCRIPT (1<<6) +#define S_IPURE (1<<5) +#define S_IARCHIVE (1<<4) +#define S_IREAD (1<<3) +#define S_IWRITE (1<<2) +#define S_IEXECUTE (1<<1) +#define S_IDELETE (1<<0) + +int stat(const char *name, struct stat *buf); +int fstat(int handle, struct stat *buf); /* returns dummy values */ + +typedef struct dirent { + struct dirent *d_cleanuplink, + **d_cleanupparent; + BPTR d_parentlock; + struct FileInfoBlock d_fib; +} DIR; +#define d_name d_fib.fib_FileName + +extern unsigned short disk_not_mounted; /* flag set by opendir() */ + +DIR *opendir(const char *); +void closedir(DIR *); +void close_leftover_open_dirs(void); /* call this if aborted in mid-run */ +struct dirent *readdir(DIR *); +int umask(void); + +#ifdef AZTEC_C +int rmdir(const char *); +int chmod(const char *filename, int bits); +#endif + +#endif /* __amiga_z_stat_h */ diff --git a/amiga/zipup.h b/amiga/zipup.h new file mode 100644 index 0000000..c9316f4 --- /dev/null +++ b/amiga/zipup.h @@ -0,0 +1,25 @@ +/* + 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 __amiga_zipup_h +#define __amiga_zipup_h + +#ifndef O_RAW +# define O_RAW 0 +#endif +#define fhow (O_RDONLY | O_RAW) +#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 + +#endif /* __amiga_zipup_h */ + |