diff options
author | Kim Kibum <kb0929.kim@samsung.com> | 2012-08-24 14:34:26 +0900 |
---|---|---|
committer | Kim Kibum <kb0929.kim@samsung.com> | 2012-08-24 14:34:26 +0900 |
commit | 4acc22dd2f30f063c7b07fdbc911384feeda58eb (patch) | |
tree | a78b9ba604297cddb9a23424ccc8abfc6ae7ba94 /acorn | |
parent | 3101b2a7be8f0e3cc6ff469ce2597945c862264b (diff) | |
download | zip-4acc22dd2f30f063c7b07fdbc911384feeda58eb.tar.gz zip-4acc22dd2f30f063c7b07fdbc911384feeda58eb.tar.bz2 zip-4acc22dd2f30f063c7b07fdbc911384feeda58eb.zip |
upload source
Diffstat (limited to 'acorn')
-rw-r--r-- | acorn/GMakefile | 130 | ||||
-rw-r--r-- | acorn/ReadMe | 85 | ||||
-rw-r--r-- | acorn/ReadMe.GMakefile | 14 | ||||
-rw-r--r-- | acorn/RunMe1st | 23 | ||||
-rw-r--r-- | acorn/acornzip.c | 593 | ||||
-rw-r--r-- | acorn/makefile | 111 | ||||
-rw-r--r-- | acorn/match.s | 217 | ||||
-rw-r--r-- | acorn/osdep.h | 28 | ||||
-rw-r--r-- | acorn/riscos.c | 394 | ||||
-rw-r--r-- | acorn/riscos.h | 119 | ||||
-rw-r--r-- | acorn/sendbits.s | 105 | ||||
-rw-r--r-- | acorn/srcrename | bin | 0 -> 6175 bytes | |||
-rw-r--r-- | acorn/swiven.h | 59 | ||||
-rw-r--r-- | acorn/swiven.s | 276 | ||||
-rw-r--r-- | acorn/zipup.h | 16 |
15 files changed, 2170 insertions, 0 deletions
diff --git a/acorn/GMakefile b/acorn/GMakefile new file mode 100644 index 0000000..e9f02bc --- /dev/null +++ b/acorn/GMakefile @@ -0,0 +1,130 @@ +# Makefile for Zip, ZipNote, ZipCloak and ZipSplit + +# add -g to CC to debug +# add -d to BIND to debug +CC = gcc -mlibscl +BIND = $(CC) +AS = $(CC) -c +ASM = AS +SQUEEZE = squeeze -v +E = + +# flags +# CFLAGS flags for C compile +# LFLAGS1 flags after output file spec, before obj file list +# LFLAGS2 flags after obj file list (libraries, etc) +# +LIB = +CFLAGS = -O2 -mthrowback -DASMV +ASMFLAGS = -throwback -objasm -upper +LFLAGS1 = +LFLAGS2 = $(LIB) + +# Uncomment the following line to enable support for Unix +# Extra Field (Timezone) +#CFLAGS = $(CFLAGS) -DUSE_EF_UT_TIME + +# object file lists +OBJZ = o.zip o.zipfile o.zipup o.fileio o.util o.globals o.crc32 o.crctab \ + o.crypt o.ttyio o.riscos o.acornzip o.swiven + +OBJI = o.deflate o.trees +OBJA = o.match o.sendbits +OBJU = o.zipfile_ o.fileio_ o.util_ o.globals o.riscos o.acornzip_ o.swiven +OBJN = o.zipnote $(OBJU) +OBJC = o.zipcloak $(OBJU) o.crctab o.crypt_ o.ttyio +OBJS = o.zipsplit $(OBJU) + +ZIP_H = h.zip h.ziperr h.tailor acorn.h.osdep acorn.h.riscos acorn.h.swiven + +all: zip zipnote zipsplit zipcloak + +install: %.zip %.zipnote %.zipsplit %.zipcloak %.acorn.zipsfx \ + zip zipnote zipsplit zipcloak acorn.zipsfx + $(SQUEEZE) zip %.zip + $(SQUEEZE) zipnote %.zipnote + $(SQUEEZE) zipsplit %.zipsplit + $(SQUEEZE) zipcloak %.zipcloak + copy acorn.zipsfx %.zipsfx ~CVF + +# rules for zip, zipnote, zipcloak and zipsplit + +o.api: c.api + $(CC) $(CFLAGS) -c c.api -o o.api +o.crc32: c.crc32 $(ZIP_H) + $(CC) $(CFLAGS) -c c.crc32 -o o.crc32 +o.crctab: c.crctab $(ZIP_H) + $(CC) $(CFLAGS) -c c.crctab -o o.crctab +o.crypt: c.crypt $(ZIP_H) h.crypt h.ttyio + $(CC) $(CFLAGS) -c c.crypt -o o.crypt +o.deflate: c.deflate $(ZIP_H) + $(CC) $(CFLAGS) -c c.deflate -o o.deflate +o.fileio: c.fileio $(ZIP_H) + $(CC) $(CFLAGS) -c c.fileio -o o.fileio +o.globals: c.globals $(ZIP_H) + $(CC) $(CFLAGS) -c c.globals -o o.globals +o.mktime: c.mktime + $(CC) $(CFLAGS) -c c.mktime -o o.mktime +o.trees: c.trees $(ZIP_H) + $(CC) $(CFLAGS) -c c.trees -o o.trees +o.ttyio: c.ttyio $(ZIP_H) h.crypt + $(CC) $(CFLAGS) -c c.ttyio -o o.ttyio +o.util: c.util $(ZIP_H) + $(CC) $(CFLAGS) -c c.util -o o.util +o.zip: c.zip $(ZIP_H) h.crypt h.revision h.ttyio + $(CC) $(CFLAGS) -c c.zip -o o.zip +o.zipcloak: c.zipcloak $(ZIP_H) h.crypt h.revision h.ttyio + $(CC) $(CFLAGS) -c c.zipcloak -o o.zipcloak +o.zipfile: c.zipfile $(ZIP_H) + $(CC) $(CFLAGS) -c c.zipfile -o o.zipfile +o.zipnote: c.zipnote $(ZIP_H) h.revision + $(CC) $(CFLAGS) -c c.zipnote -o o.zipnote +o.zipsplit: c.zipsplit $(ZIP_H) h.revision + $(CC) $(CFLAGS) -c c.zipsplit -o o.zipsplit +o.zipup: c.zipup $(ZIP_H) h.crypt h.revision + $(CC) $(CFLAGS) -c c.zipup -o o.zipup + +o.crypt_: c.crypt $(ZIP_H) h.crypt h.ttyio + $(CC) $(CFLAGS) -DUTIL -c c.crypt -o o.crypt_ +o.util_: c.util $(ZIP_H) + $(CC) $(CFLAGS) -DUTIL -c c.util -o o.util_ +o.fileio_: c.fileio $(ZIP_H) + $(CC) $(CFLAGS) -DUTIL -c c.fileio -o o.fileio_ +o.zipfile_: c.zipfile $(ZIP_H) + $(CC) $(CFLAGS) -DUTIL -c c.zipfile -o o.zipfile_ +o.acornzip_: acorn.c.acornzip $(ZIP_H) + $(CC) $(CFLAGS) -I@ -DUTIL -c acorn.c.acornzip -o o.acornzip_ + +o.riscos: acorn.c.riscos acorn.h.riscos $(ZIP_H) + $(CC) $(CFLAGS) -I@ -c acorn.c.riscos -o o.riscos + +o.acornzip: acorn.c.acornzip $(ZIP_H) + $(CC) $(CFLAGS) -I@ -c acorn.c.acornzip -o o.acornzip + +o.match: acorn.s.match + $(ASM) $(ASMFLAGS) -I@ acorn.s.match -o o.match + +o.sendbits: acorn.s.sendbits + $(ASM) $(ASMFLAGS) -I@ acorn.s.sendbits -o o.sendbits + +o.swiven: acorn.s.swiven + $(ASM) $(ASMFLAGS) -I@ acorn.s.swiven -o o.swiven + +zip: $(OBJZ) $(OBJI) $(OBJA) + $(BIND) -o zip$(E) $(LFLAGS1) $(OBJZ) $(OBJI) $(OBJA) $(LFLAGS2) +zipnote: $(OBJN) + $(BIND) -o zipnote$(E) $(LFLAGS1) $(OBJN) $(LFLAGS2) +zipcloak: $(OBJC) + $(BIND) -o zipcloak$(E) $(LFLAGS1) $(OBJC) $(LFLAGS2) +zipsplit: $(OBJS) + $(BIND) -o zipsplit$(E) $(LFLAGS1) $(OBJS) $(LFLAGS2) + +clean: + remove zip + remove zipcloak + remove zipsplit + remove zipnote + create o.!fake! 0 + wipe o.* ~cf + +# end of Makefile diff --git a/acorn/ReadMe b/acorn/ReadMe new file mode 100644 index 0000000..41c37a5 --- /dev/null +++ b/acorn/ReadMe @@ -0,0 +1,85 @@ +Acorn-specific compile instructions +----------------------------------- + +Use the "RunMe1st" file (it is an Obey file) to convert all the files from +"filename/[chs]" to "[chs].filename" (so that zip could be easily compiled +under RISC OS). It will also set the correct makefile. + +To compile just set the CSD to the main zip directory and run 'amu'. + +Currently only the Acorn C V5 compiler has been tested but probably also +Acorn C V4 and the Acorn Assembler V2 will be able to compile zip. + +The default makefile is configured without the support for the +Extended Timestamp Extra Field. If you wan to enable it you have to +add "-DUSE_EF_UT_TIME" to CFLAGS (see makefile). Without the Extended +Timestamp Field support, zipfiles created by zip are identical to the +zipfiles created by SparkFS. However, the Extended Timestamp Field can +be useful if you are going to unzip your zipfiles on a non-RISC OS machine +since the correct time stamp will be preserved across different timezones. +Note that in this case, both the SparkFS Extra Field and the Extended +Timestamp Extra Field will be used, so the zipfiles will still be fully +compatible with SparkFS and with the RISC OS version of unzip. + +The executables-only distributions will be compiled without the support for +the Extended Timestamp Extra Field. If you need it but you can't compile zip +yourself, you can contact the authors at the Info-ZIP address who will do it +for you. + + +Acorn-specific usage instructions +--------------------------------- + +An extra option ('I') has been added to the Acorn port: if it is specified +zip will not consider Image files (eg. DOS partitions or Spark archives when +SparkFS is loaded) as directories but will store them as single files. This +means that if you have, say, SparkFS loaded, zipping a Spark archive will +result in a zipfile containing a directory (and its content) while using the +'I' option will result in a zipfile containing a Spark archive. Obviously +this second case will also be obtained (without the 'I' option) if SparkFS +isn't loaded. + +When adding files to a zipfile; to maintain FileCore compliance, all +files named "file/ext" will be added to the archive as "file.ext". +This presents no problem if you wish to use unzip to extract them on any +other machine, as the files are correctly named. This also presents no +problem if you use unzip for RISC OS, as the files are converted back to +"file/ext" format. The only problem appears when you use SparkFS to +decompress the files, as a file called "file.ext" will be extracted as +"file_ext", not what it was added as. You must be careful about this. + +Case Specific. Depending on how you type the command, files will be added +exactly as named; in this example: +*zip new/zip newfile +*zip new/zip NewFile +*zip new/zip NEWFILE +will create an archive containing 3 copies of the same Risc OS file 'newfile' +called 'newfile', 'NewFile' and 'NEWFILE'. Please be careful. + +The Acorn port conserves file attributes, including filetype, so if you +zip on an Acorn, and unzip on another Acorn, filetypes will be maintained +precisely as if you used uncompressed files. If you de-archive on another +machine (PC, Mac, Unix etc..), filetypes will be ignored, but the files +will be identical despite this. This feature is fully compatible with +SparkFS, so zipfiles created by zip will be correctly uncompressed (including +filetype, etc.) by SparkFS. + +An additional feature went into this port to cope better with C-code +and extensions. This allows the acorn files "c.foo" to be added to the +archive as "foo/c", eventually appearing in the archive as "foo.c", allowing +for better handling of C or C++ code. Example: +*Set Zip$Exts "dir1:dir2:dir3" +*zip new/zip dir1.file +*zip new/zip dir2.help +*zip new/zip dir3.textfile +Creates a zipfile new/zip, with entries file.dir1, help.dir2, textfile.dir3. +The usual settings for Zip$Exts are "h:o:s:c", allowing C code to be added +to the archive in standard form. + +A final note about the Acorn port regards the use of the 'n' option: this is +used to specify a list of suffixes that will not be compressed (eg. .ZIP, +since it is already a compressed file). Since RISC OS uses filetypes instead +of suffixes, this list of suffixes is actually considered as a list of +filetypes (3 hex digit format). By default, zip doesn't compress filetypes +DDC (Archive, Spark or Zip), D96 (CFS files) and 68E (PackDir). + diff --git a/acorn/ReadMe.GMakefile b/acorn/ReadMe.GMakefile new file mode 100644 index 0000000..714fe2d --- /dev/null +++ b/acorn/ReadMe.GMakefile @@ -0,0 +1,14 @@ +GMakefile is for use with Acorn RISC OS and the forthcoming +post-Acorn RISC OS for the compilation of both the current release and +development versions of zip. + +It is recommended that you use gcc 2.95.4 or higher and you will need a +suitable 'make' utility. Both are available from +<URL:http://hard-mofo.dsvr.net/gcc/>. + +You will need the files gcc.zip and cc1.zip for the C compiler with the +documentation available in the gccdoc.zip archive. GNU make can be +found in the utils.zip archive, although most versions of 'make' should be +fine. + +When using gcc, check RunMe1st for two lines which need uncommenting. diff --git a/acorn/RunMe1st b/acorn/RunMe1st new file mode 100644 index 0000000..a330adb --- /dev/null +++ b/acorn/RunMe1st @@ -0,0 +1,23 @@ +| This Obey file prepares the zip port for a Desktop C re-compile. +| Run it and it will copy all the needed files into the correct +| place. + +| Set the correct type of 'srcrename' so that the only requirement +| for the user is to set 'RunMe1st' to Obey +SetType <Obey$Dir>.srcrename FF8 + +| Run 'srcrename' on the main zip directory with recursion enabled +/<Obey$Dir>.srcrename -r -e c:h:s:o <Obey$Dir>.^ + +| Create the 'o' directory +CDir <Obey$Dir>.^.o + +| Put the Makefile in its correct place and set the correct filetype +Copy <Obey$Dir>.makefile <Obey$Dir>.^.makefile ~C ~V F + +| Uncomment the following lines if you're using gcc +|| Put the Makefile in its correct place and set the correct filetype +|Copy <Obey$Dir>.GMakefile <Obey$Dir>.^.makefile ~C~VF + +SetType <Obey$Dir>.^.makefile FE1 +SetType <Obey$Dir>.zipsfx Obey diff --git a/acorn/acornzip.c b/acorn/acornzip.c new file mode 100644 index 0000000..8de308c --- /dev/null +++ b/acorn/acornzip.c @@ -0,0 +1,593 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2004-May-22 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#include <stdlib.h> +#include <string.h> +#include "zip.h" + +#ifndef UTIL + +#define PAD 0 +#define PATH_END '/' + + +local int wild_recurse(char *whole, char *wildtail); +local int uxtime2acornftime(unsigned *pexadr, unsigned *pldadr, time_t ut); + +extern char *label; +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +char *readd(DIR *d) +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e; + + e = readdir(d); + return (e == NULL ? (char *) NULL : e->d_name); +} + +/* What we have here is a mostly-generic routine using opend()/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]". */ + +/* 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; + struct stat statb; + int disk_not_mounted=0; + int e = ZE_MISS; + + if (!isshexp(wildtail)) { + if (stat(whole,&statb)==0 && (statb.st_mode & S_IREAD)!=0) { + 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 == '.') { + 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, '.')) != NULL) { + /* this "+ 1" dodges the ^^^ hole left by *glue == 0 */ + *(subwild++) = 0; /* wildtail = one component pattern */ + newlen = strlen(whole) + strlen(subwild) + 32; + } else + newlen = strlen(whole) + 31; + 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++) = '.'; + 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 = '.'; + if (newwhole) free(newwhole); + if (e == ZE_MISS && amatch) + e = ZE_OK; + return e; +} + +int wild(p) +char *p; +{ + char *path; + int toret; + + /* special handling of stdin request */ + if (strcmp(p, "-") == 0) /* if compressing stdin */ + return newname(p, 0, 0); + + path=p; + if (strchr(p, ':')==NULL && *p!='@') { + if (!(path=malloc(strlen(p)+3))) { + return ZE_MEM; + } + strcpy(path,"@."); + strcat(path,p); + } + + toret=wild_recurse(path, path); + + if (path!=p) { + free(path); + } + return toret; +} + +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; + if (strcmp(n, ".") == 0) { + *p = '\0'; /* avoid "./" prefix and do not create zip entry */ + } else { + strcpy(p, n); + a = p + strlen(p); + if (a[-1] != '.') + strcpy(a, "."); + if (dirnames && (m = newname(p, 1, caseflag)) != ZE_OK) { + free((zvoid *)p); + return m; + } + } + /* recurse into directory */ + if (recurse && (d = opendir(n)) != NULL) + { + while ((e = readd(d)) != NULL) { + if (strcmp(e, ".") && strcmp(e, "..")) + { + if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL) + { + closedir(d); + free((zvoid *)p); + return ZE_MEM; + } + strcat(strcpy(a, p), e); + if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */ + { + if (m == ZE_MISS) + zipwarn("name not matched: ", a); + else + ziperr(m, a); + } + free((zvoid *)a); + } + } + closedir(d); + } + free((zvoid *)p); + } /* (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 */ + char *tmp; + int dosflag; + char *lastlastdir=NULL; /* pointer to 2 dirs before... */ + char *lastdir=NULL; /* pointer to last dir... */ + + /* Malloc space for internal name and copy it */ + if ((tmp = malloc(strlen(x) + 1)) == NULL) + return NULL; + strcpy(tmp, x); + + dosflag = dosify; /* default for non-DOS and non-OS/2 */ + + /* Find starting point in name before doing malloc */ + for(t=tmp;*t;t++) { + if (*t=='/') { + *t='.'; + } + else if (*t=='.') { + *t='/'; + lastlastdir=lastdir; + lastdir=t+1; + } + } + + t=strchr(tmp,'$'); /* skip FS name */ + if (t!=NULL) + t+=2; /* skip '.' after '$' */ + else + t=tmp; + if (*t=='@') /* skip @. at the beginning of filenames */ + t+=2; + + /* Make changes, if any, to the copied name (leave original intact) */ + + /* return a pointer to '\0' if the file is a directory with the same + same name as an extension to swap (eg. 'c', 'h', etc.) */ + if (isdir && exts2swap!=NULL) { + if (lastlastdir==NULL) + lastlastdir=t; + if (checkext(lastlastdir)) { + free((void *)tmp); + n=malloc(1); + if (n!=NULL) + *n='\0'; + return n; + } + } + + if (exts2swap!=NULL && lastdir!=NULL) { + if (lastlastdir==NULL) + lastlastdir=t; + if (checkext(lastlastdir)) { + if (swapext(lastlastdir,lastdir-1)) { + free((void *)tmp); + return NULL; + } + } + } + + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) { + free((void *)tmp); + return NULL; + } + strcpy(n, t); + + free((void *)tmp); + + 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 */ + char *t; /* scans name */ + char *lastext=NULL; /* pointer to last extension */ + char *lastdir=NULL; /* pointer to last dir */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + + for(t=x;*t;t++) { + if (*t=='.') { + *t='/'; + lastext=t+1; + } + else if (*t=='/') { + *t='.'; + lastdir=t+1; + } + } + + if (exts2swap!=NULL && (int)lastext>(int)lastdir) { + if (lastdir==NULL) + lastdir=x; + if (checkext(lastext)) { + if (swapext(lastdir,lastext-1)) { + free((void *)x); + return NULL; + } + } + } + + return x; +} + +local int uxtime2acornftime(unsigned *pexadr, unsigned *pldadr, time_t ut) +{ + unsigned timlo; /* 3 lower bytes of acorn file-time plus carry byte */ + unsigned timhi; /* 2 high bytes of acorn file-time */ + + timlo = ((unsigned)ut & 0x00ffffffU) * 100 + 0x00996a00U; + timhi = ((unsigned)ut >> 24); + timhi = timhi * 100 + 0x0000336eU + (timlo >> 24); + if (timhi & 0xffff0000U) + return 1; /* calculation overflow, do not change time */ + + /* insert the five time bytes into loadaddr and execaddr variables */ + *pexadr = (timlo & 0x00ffffffU) | ((timhi & 0x000000ffU) << 24); + *pldadr = (*pldadr & 0xffffff00U) | ((timhi >> 8) & 0x000000ffU); + + return 0; /* subject to future extension to signal overflow */ +} + +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 m_time; + unsigned int loadaddr, execaddr; + int attr; + + /* Convert DOS time to time_t format in m_time */ + m_time = dos2unixtime(d); + + /* set the file's modification time */ + SWI_OS_File_5(f,NULL,&loadaddr,NULL,NULL,&attr); + + if (uxtime2acornftime(&execaddr, &loadaddr, m_time) != 0) + return; + + SWI_OS_File_1(f,loadaddr,execaddr,attr); +} + +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() */ + char *name; + unsigned int len = strlen(f); + + if (f == label) { + if (a != NULL) + *a = label_mode; + if (n != NULL) + *n = -2L; /* convention for a label name */ + if (t != NULL) + t->atime = t->mtime = t->ctime = label_utim; + return label_time; + } + + if ((name = malloc(len + 1)) == NULL) { + ZIPERR(ZE_MEM, "filetime"); + } + strcpy(name, f); + if (name[len - 1] == '.') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + + if (strcmp(f, "-") == 0) { + /* forge stat values for stdin since Amiga and RISCOS have no fstat() */ + s.st_mode = (S_IREAD|S_IWRITE|S_IFREG); + s.st_size = -1; + s.st_mtime = time(&s.st_mtime); + } else if (LSSTAT(name, &s) != 0) { + /* Accept about any file kind including directories + * (stored with trailing / with -r option) + */ + free(name); + return 0; + } + + if (a != NULL) { + *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE); + if ((s.st_mode & S_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; + } + + free(name); + + return unix2dostime((time_t *) &s.st_mtime); +} + +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; +{ +#ifdef USE_EF_UT_TIME + char *eb_ptr; +#endif /* USE_EF_UT_TIME */ + char *name; + extra_block *block; + +#define EB_SPARK_LEN 20 +#define EB_SPARK_SIZE (EB_HEADSIZE+EB_SPARK_LEN) +#ifdef USE_EF_UT_TIME +# ifdef IZ_CHECK_TZ +# define EB_UTTIME_SIZE (zp_tz_is_valid ? EB_HEADSIZE+EB_UT_LEN(1) : 0) +# else +# define EB_UTTIME_SIZE (EB_HEADSIZE+EB_UT_LEN(1)) +# endif +#else +# define EB_UTTIME_SIZE 0 +#endif +#define EF_SPARK_TOTALSIZE (EB_SPARK_SIZE + EB_UTTIME_SIZE) + + if ((name=(char *)malloc(strlen(z->name)+1))==NULL) { + fprintf(stderr," set_extra_field: not enough memory for directory name\n"); + return ZE_MEM; + } + + strcpy(name,z->name); + + if (name[strlen(name)-1]=='.') { /* remove the last '.' in directory names */ + name[strlen(name)-1]=0; + } + + z->extra=(char *)malloc(EF_SPARK_TOTALSIZE); + if (z->extra==NULL) { + fprintf(stderr," set_extra_field: not enough memory\n"); + free(name); + return ZE_MEM; + } + z->cextra = z->extra; + z->cext = z->ext = EF_SPARK_TOTALSIZE; + + block=(extra_block *)z->extra; + block->ID=SPARKID; + block->size=EB_SPARK_LEN; + block->ID_2=SPARKID_2; + block->zero=0; + + if (SWI_OS_File_5(name,NULL,&block->loadaddr,&block->execaddr, + NULL,&block->attr) != NULL) { + fprintf(stderr," OS error while set_extra_field of %s\n",name); + } + + free(name); + +#ifdef USE_EF_UT_TIME +# ifdef IZ_CHECK_TZ + if (zp_tz_is_valid) { +# endif + eb_ptr = z->extra + EB_SPARK_SIZE; + + eb_ptr[0] = 'U'; + eb_ptr[1] = 'T'; + eb_ptr[2] = EB_UT_LEN(1); /* length of data part of e.f. */ + eb_ptr[3] = 0; + eb_ptr[4] = EB_UT_FL_MTIME; + eb_ptr[5] = (char)(z_utim->mtime); + eb_ptr[6] = (char)(z_utim->mtime >> 8); + eb_ptr[7] = (char)(z_utim->mtime >> 16); + eb_ptr[8] = (char)(z_utim->mtime >> 24); +# ifdef IZ_CHECK_TZ + } +# endif +#endif /* USE_EF_UT_TIME */ + + return ZE_OK; +} + +#endif /* !UTIL */ + + +/******************************/ +/* Function version_local() */ +/******************************/ + +void version_local() +{ + static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n"; + + printf(CompiledWith, +#ifdef __GNUC__ + "gcc ", __VERSION__, +#else +# ifdef __CC_NORCROFT + "Norcroft ", "cc", +# else + "cc", "", +# endif +#endif + + "RISC OS", + + " (Acorn Computers Ltd)", + +#ifdef __DATE__ + " on ", __DATE__ +#else + "", "" +#endif + ); + +} /* end function version_local() */ diff --git a/acorn/makefile b/acorn/makefile new file mode 100644 index 0000000..5aa1c5c --- /dev/null +++ b/acorn/makefile @@ -0,0 +1,111 @@ +# Makefile for Zip, ZipNote, ZipCloak and ZipSplit + +# add -g to CC to debug +# add -d to BIND to debug +CC = cc +BIND = link +AS = $(CC) -c +ASM = objasm +SQUEEZE = squeeze -v +E = + +# flags +# CFLAGS flags for C compile +# LFLAGS1 flags after output file spec, before obj file list +# LFLAGS2 flags after obj file list (libraries, etc) +# +LIB = +CBASE = -throwback -wn -DASMV -apcs 3/26 +CFLAGS = $(CBASE) -IC:,@. +ASMFLAGS = -Throwback -Stamp -NoCache -CloseExec -quit -apcs 3/26 +LFLAGS1 = +LFLAGS2 = $(LIB) C:o.Stubs + +# Uncomment the following line to enable support for Unix +# Extra Field (Timezone) +#CFLAGS = $(CFLAGS) -DUSE_EF_UT_TIME + +# object file lists +OBJZ = zip.o zipfile.o zipup.o fileio.o util.o globals.o crc32.o crctab.o \ + crypt.o ttyio.o riscos.o acornzip.o swiven.o + +OBJI = deflate.o trees.o +OBJA = match.o sendbits.o +OBJU = zipfile_.o fileio_.o util_.o globals.o riscos.o acornzip_.o swiven.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o $(OBJU) crctab.o crypt_.o ttyio.o +OBJS = zipsplit.o $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h acorn/osdep.h acorn/riscos.h acorn/swiven.h + +all: zip zipnote zipsplit zipcloak + + +install: %.zip %.zipnote %.zipsplit %.zipcloak %.zipsfx \ + zip zipnote zipsplit zipcloak zipsfx + $(SQUEEZE) zip %.zip + $(SQUEEZE) zipnote %.zipnote + $(SQUEEZE) zipsplit %.zipsplit + $(SQUEEZE) zipcloak %.zipcloak + copy acorn.zipsfx %.zipsfx ~CVF + +# suffix rules +.SUFFIXES: _.o .o .c +.c_.o: + $(CC) $(CFLAGS) -DUTIL -c $*.c -o $*_.o +.c.o: + $(CC) $(CFLAGS) -c $< +.s.o: + $(ASM) $(ASMFLAGS) -from @*.s -to @*.o + +# rules for zip, zipnote, zipcloak and zipsplit +$(OBJZ): $(ZIP_H) +$(OBJI): $(ZIP_H) +$(OBJN): $(ZIP_H) +$(OBJS): $(ZIP_H) +$(OBJC): $(ZIP_H) +zip.o zipup.o crypt.o ttyio.o zipcloak.o crypt_.o: crypt.h +zip.o zipup.o zipnote.o zipcloak.o zipsplit.o: revision.h +zip.o crypt.o ttyio.o zipcloak.o crypt_.o: ttyio.h + +crypt_.o: crypt.c + $(CC) $(CFLAGS) -DUTIL -c c.crypt -o o.crypt_ +util_.o: util.c + $(CC) $(CFLAGS) -DUTIL -c c.util -o o.util_ +fileio_.o: fileio.c + $(CC) $(CFLAGS) -DUTIL -c c.fileio -o o.fileio_ +zipfile_.o: zipfile.c + $(CC) $(CFLAGS) -DUTIL -c c.zipfile -o o.zipfile_ +acornzip_.o: acorn/acornzip.c $(ZIP_H) + $(CC) $(CFLAGS) -DUTIL -c acorn/acornzip.c -o o.acornzip_ + +riscos.o: acorn/riscos.c acorn/riscos.h + $(CC) $(CFLAGS) -c acorn/riscos.c + +acornzip.o: acorn/acornzip.c $(ZIP_H) + $(CC) $(CFLAGS) -c acorn/acornzip.c + +match.o: acorn/match.s + $(ASM) $(ASMFLAGS) -from acorn.s.match -to o.match + +sendbits.o: acorn/sendbits.s + $(ASM) $(ASMFLAGS) -from acorn.s.sendbits -to o.sendbits + +swiven.o: acorn/swiven.s + $(ASM) $(ASMFLAGS) -from acorn.s.swiven -to o.swiven + +zip: $(OBJZ) $(OBJI) $(OBJA) + $(BIND) -o zip$(E) $(LFLAGS1) $(OBJZ) $(OBJI) $(OBJA) $(LFLAGS2) +zipnote: $(OBJN) + $(BIND) -o zipnote$(E) $(LFLAGS1) $(OBJN) $(LFLAGS2) +zipcloak: $(OBJC) + $(BIND) -o zipcloak$(E) $(LFLAGS1) $(OBJC) $(LFLAGS2) +zipsplit: $(OBJS) + $(BIND) -o zipsplit$(E) $(LFLAGS1) $(OBJS) $(LFLAGS2) + +clean: ;remove zip; remove zipcloak; + remove zipsplit; remove zipnote; + create o.!fake! 0 + wipe o.* ~cf + +# end of Makefile diff --git a/acorn/match.s b/acorn/match.s new file mode 100644 index 0000000..ee68ce6 --- /dev/null +++ b/acorn/match.s @@ -0,0 +1,217 @@ +;=========================================================================== +; 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.s for ARM by Sergio Monesi. + +r0 RN 0 +r1 RN 1 +r2 RN 2 +r3 RN 3 +r4 RN 4 +r5 RN 5 +r6 RN 6 +r7 RN 7 +r8 RN 8 +r9 RN 9 +sl RN 10 +fp RN 11 +ip RN 12 +sp RN 13 +lr RN 14 +pc RN 15 + +MAX_DIST EQU 32506 +WMASK EQU 32767 +MAX_MATCH EQU 258 + + AREA |C$$code|, CODE, READONLY + + +; r1 = chain_lenght +; r2 = scan +; r3 = match +; r4 = len (tmp) +; r5 = best_len +; r6 = limit +; r7 = strend +; r8 = scan_end1 +; r9 = scan_end +; lr = window +; fp = prev + +|__max_chain_length| + IMPORT max_chain_length + DCD max_chain_length +|__window| + IMPORT window + DCD window +|__prev| + IMPORT prev + DCD prev +|__prev_length| + IMPORT prev_length + DCD prev_length +|__strstart| + IMPORT strstart + DCD strstart +|__good_match| + IMPORT good_match + DCD good_match +|__nice_match| + IMPORT nice_match + DCD nice_match +|__match_start| + IMPORT match_start + DCD match_start + + DCB "longest_match" + DCB &00,&00,&00 + DCD &ff000010 + + EXPORT longest_match +longest_match + STMFD sp!, {r4-r9,fp,lr} + + LDR fp, [pc, #|__prev|-.-8] + + LDR r1, [pc, #|__max_chain_length|-.-8] + LDR r1, [r1] + LDR lr, [pc, #|__window|-.-8] + + LDR ip, [pc, #|__strstart|-.-8] + LDR ip, [ip] + ADD r2, lr, ip + LDR r5, [pc, #|__prev_length|-.-8] + LDR r5, [r5] + SUBS ip, ip, #MAX_DIST-250 ; if r6 > MAX_DIST + SUBCSS r6, ip, #250 ; r6 = r6 - MAXDIST + MOVLS r6, #0 ; else r6 = 0 + + ADD r7, r2, #MAX_MATCH-256 + ADD r7, r7, #256 ; r7 = r2 + MAX_MATCH (=258); + + SUB ip, r5, #1 + LDRB r8, [r2, ip] + LDRB r9, [r2, r5] + + LDR ip, [pc, #|__good_match|-.-8] + LDR ip, [ip] + CMP r5, ip + MOVCS r1, r1, LSR #2 + +cycle + ADD r3, lr, r0 + + LDRB ip, [r3, r5] + CMP ip, r9 + BNE cycle_end + + SUB ip, r5, #1 + LDRB ip, [r3, ip] + CMP ip, r8 + BNE cycle_end + + LDRB ip, [r2] + LDRB r4, [r3] + CMP ip, r4 + BNE cycle_end + + LDRB ip, [r3, #1] + LDRB r4, [r2, #1] + CMP ip, r4 + BNE cycle_end + + ADD r2, r2, #2 + ADD r3, r3, #2 + +inn_cycle + LDRB ip, [r2, #1]! + LDRB r4, [r3, #1]! + CMP ip, r4 + BNE exit_inn_cycle + + LDRB ip, [r2, #1]! + LDRB r4, [r3, #1]! + CMP ip, r4 + BNE exit_inn_cycle + + LDRB ip, [r2, #1]! + LDRB r4, [r3, #1]! + CMP ip, r4 + BNE exit_inn_cycle + + LDRB ip, [r2, #1]! + LDRB r4, [r3, #1]! + CMP ip, r4 + BNE exit_inn_cycle + + LDRB ip, [r2, #1]! + LDRB r4, [r3, #1]! + CMP ip, r4 + BNE exit_inn_cycle + + LDRB ip, [r2, #1]! + LDRB r4, [r3, #1]! + CMP ip, r4 + BNE exit_inn_cycle + + LDRB ip, [r2, #1]! + LDRB r4, [r3, #1]! + CMP ip, r4 + BNE exit_inn_cycle + + LDRB ip, [r2, #1]! + LDRB r4, [r3, #1]! + CMP ip, r4 + BNE exit_inn_cycle + + CMP r2, r7 + BCC inn_cycle + +exit_inn_cycle + SUB r4, r2, r7 ; len = MAX_MATCH - (int)(strend - scan); + ADD r4, r4, #MAX_MATCH-256 + ADD r4, r4, #256 + + SUB r2, r2, r4 ; scan = strend - MAX_MATCH + + CMP r4, r5 ; if (len > best_len) { + BLE cycle_end + + LDR ip, [pc, #|__match_start|-.-8] ; match_start = cur_match; + STR r0, [ip] + MOV r5, r4 ; best_len = len; + + LDR ip, [pc, #|__nice_match|-.-8] ; if (len >= nice_match) + LDR ip, [ip] + CMP r4, ip + BGE exit_match ; break; + + SUB ip, r5, #1 ; scan_end1 = scan[best_len-1]; + LDRB r8, [r2, ip] + LDRB r9, [r2, r5] ; scan_end = scan[best_len]; + +cycle_end + MOV ip, r0, LSL #17 ; cur_match & WMASK + MOV ip, ip, LSR #17 + + LDR r0, [fp, ip, ASL #1] ; cur_match = prev[cur_match & WMASK] + MOV r0, r0, ASL #16 + MOV r0, r0, LSR #16 + + CMP r0, r6 ; cur_match > limit + BLS exit_match + SUBS r1, r1, #1 ; --chain_length + BNE cycle ; chain_length != 0 + +exit_match + MOV r0, r5 + + LDMFD sp!, {r4-r9,fp,pc}^ + + END diff --git a/acorn/osdep.h b/acorn/osdep.h new file mode 100644 index 0000000..ea002ef --- /dev/null +++ b/acorn/osdep.h @@ -0,0 +1,28 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2004-May-22 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#include "riscos.h" + +#define RISCOS +#define NO_SYMLINK +#define NO_FCNTL_H +#define NO_UNISTD_H +#define NO_MKTEMP + +#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \ + procname(n, 1)) + +#define isatty(a) 1 +#define fseek(f,o,t) riscos_fseek((f),(o),(t)) + +#define localtime riscos_localtime +#define gmtime riscos_gmtime + +#ifdef ZCRYPT_INTERNAL +# define ZCR_SEED2 (unsigned)3141592654L /* use PI as seed pattern */ +#endif diff --git a/acorn/riscos.c b/acorn/riscos.c new file mode 100644 index 0000000..eb1b897 --- /dev/null +++ b/acorn/riscos.c @@ -0,0 +1,394 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2004-May-22 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* riscos.c */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "zip.h" +#include "riscos.h" + +#define MAXEXT 256 + +/* External globals */ +extern int scanimage; + +/* Local globals (!?!?) */ +char *exts2swap = NULL; /* Extensions to swap (actually, directory names) */ + +int stat(char *filename,struct stat *res) +{ + int attr; /* object attributes */ + unsigned int load; /* load address */ + unsigned int exec; /* exec address */ + int type; /* type: 0 not found, 1 file, 2 dir, 3 image */ + + if (!res) + return -1; + + if (SWI_OS_File_5(filename,&type,&load,&exec,(int *)&res->st_size,&attr)!=NULL) + return -1; + + if (type==0) + return -1; + + res->st_dev=0; + res->st_ino=0; + res->st_nlink=0; + res->st_uid=1; + res->st_gid=1; + res->st_rdev=0; + res->st_blksize=1024; + + res->st_mode = ((attr & 0001) << 8) | ((attr & 0002) << 6) | + ((attr & 0020) >> 2) | ((attr & 0040) >> 4); + + switch (type) { + case 1: /* File */ + res->st_mode |= S_IFREG; + break; + case 2: /* Directory */ + res->st_mode |= S_IFDIR | 0700; + break; + case 3: /* Image file */ + if (scanimage) + res->st_mode |= S_IFDIR | 0700; + else + res->st_mode |= S_IFREG; + break; + } + + if ((((unsigned int) load) >> 20) == 0xfff) { /* date stamped file */ + unsigned int t1, t2, tc; + + t1 = (unsigned int) (exec); + t2 = (unsigned int) (load & 0xff); + + tc = 0x6e996a00U; + if (t1 < tc) + t2--; + t1 -= tc; + t2 -= 0x33; /* 00:00:00 Jan. 1 1970 = 0x336e996a00 */ + + t1 = (t1 / 100) + (t2 * 42949673U); /* 0x100000000 / 100 = 42949672.96 */ + t1 -= (t2 / 25); /* compensate for .04 error */ + + res->st_atime = res->st_mtime = res->st_ctime = t1; + } + else + res->st_atime = res->st_mtime = res->st_ctime = 0; + + return 0; +} + +#ifndef SFX + +DIR *opendir(char *dirname) +{ + DIR *thisdir; + int type; + int attr; + os_error *er; + + thisdir=(DIR *)malloc(sizeof(DIR)); + if (thisdir==NULL) + return NULL; + + thisdir->dirname=(char *)malloc(strlen(dirname)+1); + if (thisdir->dirname==NULL) { + free(thisdir); + return NULL; + } + + strcpy(thisdir->dirname,dirname); + if (thisdir->dirname[strlen(thisdir->dirname)-1]=='.') + thisdir->dirname[strlen(thisdir->dirname)-1]=0; + + if (er=SWI_OS_File_5(thisdir->dirname,&type,NULL,NULL,NULL,&attr),er!=NULL || + type<=1 || (type==3 && !scanimage)) + { + free(thisdir->dirname); + free(thisdir); + return NULL; + } + + thisdir->buf=malloc(DIR_BUFSIZE); + if (thisdir->buf==NULL) { + free(thisdir->dirname); + free(thisdir); + return NULL; + } + + thisdir->size=DIR_BUFSIZE; + thisdir->offset=0; + thisdir->read=0; + + return thisdir; +} + +struct dirent *readdir(DIR *d) +{ + static struct dirent dent; + + if (d->read==0) { /* no more objects read in the buffer */ + if (d->offset==-1) { /* no more objects to read */ + return NULL; + } + + d->read=255; + if (SWI_OS_GBPB_9(d->dirname,d->buf,&d->read,&d->offset,DIR_BUFSIZE,NULL)!=NULL) + return NULL; + + if (d->read==0) { + d->offset=-1; + return NULL; + } + d->read--; + d->act=(char *)d->buf; + } + else { /* some object is ready in buffer */ + d->read--; + d->act=(char *)(d->act+strlen(d->act)+1); + } + + strcpy(dent.d_name,d->act); + dent.d_namlen=strlen(dent.d_name); + + return &dent; +} + +void closedir(DIR *d) +{ + if (d->buf!=NULL) + free(d->buf); + if (d->dirname!=NULL) + free(d->dirname); + free(d); +} + +int unlink(f) +char *f; /* file to delete */ +/* Delete the file *f, returning non-zero on failure. */ +{ + os_error *er; + char canon[256]; + int size=255; + + er=SWI_OS_FSControl_37(f,canon,&size); + if (er==NULL) { + er=SWI_OS_FSControl_27(canon,0x100); + } + else { + er=SWI_OS_FSControl_27(f,0x100); + } + return (int)er; +} + +int deletedir(char *d) +{ + int objtype; + char *s; + int len; + os_error *er; + + len = strlen(d); + if ((s = malloc(len + 1)) == NULL) + return -1; + + strcpy(s,d); + if (s[len-1]=='.') + s[len-1]=0; + + if (er=SWI_OS_File_5(s,&objtype,NULL,NULL,NULL,NULL),er!=NULL) { + free(s); + return -1; + } + if (objtype<2 || (!scanimage && objtype==3)) { + /* this is a file or it doesn't exist */ + free(s); + return -1; + } + + if (er=SWI_OS_File_6(s),er!=NULL) { + /* maybe this is a problem with the DDEUtils module, try to canonicalise the path */ + char canon[256]; + int size=255; + + if (er=SWI_OS_FSControl_37(s,canon,&size),er!=NULL) { + free(s); + return -1; + } + if (er=SWI_OS_File_6(canon),er!=NULL) { + free(s); + return -1; + } + } + free(s); + return 0; +} + +#endif /* !SFX */ + +int chmod(char *file, int mode) +{ +/*************** NOT YET IMPLEMENTED!!!!!! ******************/ +/* I don't know if this will be needed or not... */ + file=file; + mode=mode; + return 0; +} + +void setfiletype(char *fname,int ftype) +{ + char str[256]; + sprintf(str,"SetType %s &%3.3X",fname,ftype); + SWI_OS_CLI(str); +} + +void getRISCOSexts(char *envstr) +{ + char *envptr; /* value returned by getenv */ + + envptr = getenv(envstr); + if (envptr == NULL || *envptr == 0) return; + + exts2swap=malloc(1+strlen(envptr)); + if (exts2swap == NULL) + return; + + strcpy(exts2swap, envptr); +} + +int checkext(char *suff) +{ + register char *extptr=exts2swap; + register char *suffptr; + register int e,s; + + if (extptr != NULL) while(*extptr) { + suffptr=suff; + e=*extptr; s=*suffptr; + while (e && e!=':' && s && s!='.' && s!='/' && e==s) { + e=*++extptr; s=*++suffptr; + } + if (e==':') e=0; + if (s=='.' || s=='/') s=0; + if (!e && !s) { + return 1; + } + while(*extptr!=':' && *extptr!='\0') /* skip to next extension */ + extptr++; + if (*extptr!='\0') + extptr++; + } + return 0; +} + +int swapext(char *name, char *exptr) +{ + char *ext; + char *p1=exptr; + char *p2; + int extchar=*exptr; + unsigned int i=0; + + while(*++p1 && *p1!='.' && *p1!='/') + ; + ext=malloc(i=p1-exptr); + if (!ext) + return 1; + memcpy(ext, exptr+1, i); + p2=exptr-1; + p1=exptr+i-1; + while(p2 >= name) + *p1--=*p2--; + strcpy(name,ext); + *p1=(extchar=='/'?'.':'/'); + free(ext); + return 0; +} + +void remove_prefix(void) +{ + SWI_DDEUtils_Prefix(NULL); +} + +void set_prefix(void) +{ + char *pref; + int size=0; + + if (SWI_OS_FSControl_37("@",pref,&size)!=NULL) + return; + + size=1-size; + + if (pref=malloc(size),pref!=NULL) { + if (SWI_OS_FSControl_37("@",pref,&size)!=NULL) { + free(pref); + return; + } + + if (SWI_DDEUtils_Prefix(pref)==NULL) { + atexit(remove_prefix); + } + + free(pref); + } +} + +#ifdef localtime +# undef localtime +#endif + +#ifdef gmtime +# undef gmtime +#endif + +/* Acorn's implementation of localtime() and gmtime() + * doesn't consider the timezone offset, so we have to + * add it before calling the library functions + */ + +struct tm *riscos_localtime(const time_t *timer) +{ + time_t localt=*timer; + + localt+=SWI_Read_Timezone()/100; + + return localtime(&localt); +} + +struct tm *riscos_gmtime(const time_t *timer) +{ + time_t localt=*timer; + + localt+=SWI_Read_Timezone()/100; + + return gmtime(&localt); +} + + +int riscos_fseek(FILE *fd, long offset, int whence) +{ + int ret; + switch (whence) + { + case SEEK_END: + ret = (fseek) (fd, 0, SEEK_END); + if (ret) + return ret; + /* fall through */ + case SEEK_CUR: + offset += ftell (fd); + /* fall through */ + default: /* SEEK_SET */ + return (fseek) (fd, offset < 0 ? 0 : offset, SEEK_SET); + } +} diff --git a/acorn/riscos.h b/acorn/riscos.h new file mode 100644 index 0000000..2bbd72e --- /dev/null +++ b/acorn/riscos.h @@ -0,0 +1,119 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2004-May-22 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.htmlse.html +*/ +/* riscos.h */ + +#ifndef __riscos_h +#define __riscos_h + +#include <time.h> +#include <stdio.h> + +typedef struct { + int errnum; + char errmess[252]; +} os_error; + +#ifndef __swiven_h +# include "swiven.h" +#endif + +#define MAXPATHLEN 256 +#define MAXFILENAMELEN 64 /* should be 11 for ADFS, 13 for DOS, 64 seems a sensible value... */ +#define DIR_BUFSIZE 1024 /* this should be enough to read a whole E-Format directory */ + +struct stat { + unsigned int st_dev; + int st_ino; + unsigned int st_mode; + int st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned int st_rdev; + unsigned int st_size; + unsigned int st_blksize; + time_t st_atime; + time_t st_mtime; + time_t st_ctime; +}; + +typedef struct { + char *dirname; + void *buf; + int size; + char *act; + int offset; + int read; +} DIR; + +#define dstrm DIR + +struct dirent { + unsigned int d_off; /* offset of next disk directory entry */ + int d_fileno; /* file number of entry */ + size_t d_reclen; /* length of this record */ + size_t d_namlen; /* length of d_name */ + char d_name[MAXFILENAMELEN]; /* name */ +}; + +typedef struct { + unsigned int load_addr; + unsigned int exec_addr; + int lenght; + int attrib; + int objtype; + char name[13]; +} riscos_direntry; + +#define SPARKID 0x4341 /* = "AC" */ +#define SPARKID_2 0x30435241 /* = "ARC0" */ + +typedef struct { + short ID; + short size; + int ID_2; + unsigned int loadaddr; + unsigned int execaddr; + int attr; + int zero; +} extra_block; + + +#define S_IFMT 0770000 + +#define S_IFDIR 0040000 +#define S_IFREG 0100000 /* 0200000 in UnixLib !?!?!?!? */ + +#ifndef S_IEXEC +# define S_IEXEC 0000100 +# define S_IWRITE 0000200 +# define S_IREAD 0000400 +#endif + +extern char *exts2swap; /* Extensions to swap */ + +int stat(char *filename,struct stat *res); +DIR *opendir(char *dirname); +struct dirent *readdir(DIR *d); +char *readd(DIR *d); +void closedir(DIR *d); +int unlink(char *f); +int chmod(char *file, int mode); +void setfiletype(char *fname,int ftype); +void getRISCOSexts(char *envstr); +int checkext(char *suff); +int swapext(char *name, char *exptr); +void remove_prefix(void); +void set_prefix(void); +struct tm *riscos_localtime(const time_t *timer); +struct tm *riscos_gmtime(const time_t *timer); + +int riscos_fseek(FILE *fd, long offset, int whence); +/* work around broken assumption that fseek() is OK with -ve file offsets */ + +#endif /* !__riscos_h */ diff --git a/acorn/sendbits.s b/acorn/sendbits.s new file mode 100644 index 0000000..f12921a --- /dev/null +++ b/acorn/sendbits.s @@ -0,0 +1,105 @@ +;=========================================================================== +; 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 +;=========================================================================== +; sendbits.s for ARM by Sergio Monesi and Darren Salt. + +r0 RN 0 +r1 RN 1 +r2 RN 2 +r3 RN 3 +r4 RN 4 +r5 RN 5 +r6 RN 6 +r7 RN 7 +r8 RN 8 +r9 RN 9 +sl RN 10 +fp RN 11 +ip RN 12 +sp RN 13 +lr RN 14 +pc RN 15 + + AREA |Asm$$Code|, CODE, READONLY + + = "send_bits",0 + ALIGN + & &FF00000C + + IMPORT __rt_stkovf_split_small + IMPORT flush_outbuf + + IMPORT bi_valid + IMPORT bi_buf + IMPORT out_size + IMPORT out_offset + IMPORT out_buf + + EXPORT send_bits +send_bits + MOV ip,sp + STMDB sp!,{r4,r5,fp,ip,lr,pc} + SUB fp,ip,#4 + LDR r5,=bi_buf + LDR r3,=bi_valid + LDR r4,[r5] + LDR r2,[r3] + ORR r4,r4,r0,LSL r2 ; |= value<<bi_valid + ADD r2,r2,r1 ; += length + CMP r2,#&10 + STRLE r2,[r3] ; short? store & return + STRLE r4,[r5] + LDMLEDB fp,{r4,r5,fp,sp,pc}^ + + SUB r2,r2,#&10 ; adjust bi_valid, bi_buf + MOV ip,r4,LSR #16 ; (done early, keeping the old bi_buf + STR r2,[r3] ; in R4 for later storage) + STR ip,[r5] + + LDR r0,=out_size + LDR r1,=out_offset + LDR r0,[r0] + LDR r2,[r1] + SUB r0,r0,#1 + CMP r2,r0 ; if out_offset >= out_size-1 + LDRHS r0,=out_buf + LDRHS r0,[r0] + BLHS flush_outbuf ; then flush the buffer + LDR r0,=out_buf + LDR r1,=out_offset + LDR r0,[r0] + LDR r2,[r1] + MOV r5,r4,LSR #8 + STRB r4,[r0,r2]! ; store 'old' bi_buf + STRB r5,[r0,#1] + ADD r2,r2,#2 + STR r2,[r1] + + LDMDB fp,{r4,r5,fp,sp,pc}^ + + +ptr_bi & bi_valid + & bi_buf + + + = "bi_reverse",0 + ALIGN + & &FF00000C + + EXPORT bi_reverse +bi_reverse + MOV r2,#0 +loop MOVS r0,r0,LSR #1 + ADCS r2,r2,r2 + SUBS r1,r1,#1 + BNE loop + MOV r0,r2 + MOVS pc,lr + + + END diff --git a/acorn/srcrename b/acorn/srcrename Binary files differnew file mode 100644 index 0000000..7bd6119 --- /dev/null +++ b/acorn/srcrename diff --git a/acorn/swiven.h b/acorn/swiven.h new file mode 100644 index 0000000..c860d7d --- /dev/null +++ b/acorn/swiven.h @@ -0,0 +1,59 @@ +/* + 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 +*/ +/* swiven.h */ + +#ifndef __swiven_h +#define __swiven_h + +os_error *SWI_OS_FSControl_26(char *source, char *dest, int actionmask); +/* copy */ + +os_error *SWI_OS_FSControl_27(char *filename, int actionmask); +/* wipe */ + +os_error *SWI_OS_GBPB_9(char *dirname, void *buf, int *number, + int *offset, int size, char *match); +/* read dir */ + +os_error *SWI_OS_File_1(char *filename, unsigned int loadaddr, + unsigned int execaddr, int attrib); +/* write file attributes */ + +os_error *SWI_OS_File_5(char *filename, int *objtype, unsigned int *loadaddr, + unsigned int *execaddr, int *length, int *attrib); +/* read file info */ + +os_error *SWI_OS_File_6(char *filename); +/* delete */ + +os_error *SWI_OS_File_7(char *filename, int loadaddr, int execaddr, int size); +/* create an empty file */ + +os_error *SWI_OS_CLI(char *cmd); +/* execute a command */ + +int SWI_OS_ReadC(void); +/* get a key from the keyboard buffer */ + +os_error *SWI_OS_ReadVarVal(char *var, char *buf, int len, int *bytesused); +/* reads an OS varibale */ + +os_error *SWI_OS_FSControl_54(char *buffer, int dir, char *fsname, int *size); +/* reads the path of a specified directory */ + +os_error *SWI_OS_FSControl_37(char *pathname, char *buffer, int *size); +/* canonicalise path */ + +os_error *SWI_DDEUtils_Prefix(char *dir); +/* sets the 'prefix' directory */ + +int SWI_Read_Timezone(void); +/* returns the timezone offset (centiseconds) */ + +#endif /* !__swiven_h */ diff --git a/acorn/swiven.s b/acorn/swiven.s new file mode 100644 index 0000000..1630124 --- /dev/null +++ b/acorn/swiven.s @@ -0,0 +1,276 @@ +;=========================================================================== +; 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 +;=========================================================================== +; SWI veneers used by Zip/Unzip +; + +r0 RN 0 +r1 RN 1 +r2 RN 2 +r3 RN 3 +r4 RN 4 +r5 RN 5 +r6 RN 6 +r7 RN 7 +r8 RN 8 +r9 RN 9 +r10 RN 10 +r11 RN 11 +r12 RN 12 +sp RN 13 +lr RN 14 +pc RN 15 + +sl RN 10 +fp RN 11 +ip RN 12 + + +XOS_Bit EQU &020000 + +OS_GBPB EQU &00000C +OS_File EQU &000008 +OS_FSControl EQU &000029 +OS_CLI EQU &000005 +OS_ReadC EQU &000004 +OS_ReadVarVal EQU &000023 +DDEUtils_Prefix EQU &042580 +Territory_ReadCurrentTimeZone EQU &043048 + + MACRO + STARTCODE $name + EXPORT $name +$name + MEND + + + AREA |C$$code|, CODE, READONLY + +; os_error *SWI_OS_FSControl_26(char *source, char *dest, int actionmask); + + STARTCODE SWI_OS_FSControl_26 + + MOV ip, lr + + MOV r3, r2 + MOV r2, r1 + MOV r1, r0 + MOV r0, #26 + + SWI OS_FSControl + XOS_Bit + + MOVVC r0, #0 + + MOVS pc, ip + + +; os_error *SWI_OS_FSControl_27(char *filename, int actionmask); + + STARTCODE SWI_OS_FSControl_27 + + MOV ip, lr + + MOV r3, r1 + MOV r1, r0 + MOV r0, #27 + + SWI OS_FSControl + XOS_Bit + + MOVVC r0, #0 + + MOVS pc, ip + + +; os_error *SWI_OS_GBPB_9(char *dirname, void *buf, int *number, +; int *offset, int size, char *match); + + STARTCODE SWI_OS_GBPB_9 + + MOV ip, sp + STMFD sp!, {r2-r6,lr} + LDMIA ip, {r5,r6} + LDR r4, [r3] + LDR r3, [r2] + MOV r2, r1 + MOV r1, r0 + MOV r0, #9 + SWI OS_GBPB + XOS_Bit + LDMVSFD sp!, {r2-r6,pc}^ + MOV r0, #0 + LDMFD sp, {r5,r6} + STR r3, [r5] + STR r4, [r6] + LDMFD sp!, {r2-r6,pc}^ + + +; os_error *SWI_OS_File_1(char *filename, int loadaddr, int execaddr, int attrib); + + STARTCODE SWI_OS_File_1 + + STMFD sp!, {r5,lr} + MOV r5, r3 + MOV r3, r2 + MOV r2, r1 + MOV r1, r0 + MOV r0, #1 + SWI OS_File + XOS_Bit + MOVVC r0, #0 + LDMFD sp!, {r5,pc}^ + + + +; os_error *SWI_OS_File_5(char *filename, int *objtype, int *loadaddr, +; int *execaddr, int *length, int *attrib); + + STARTCODE SWI_OS_File_5 + + STMFD sp!, {r1-r5,lr} + MOV r1, r0 + MOV r0, #5 + SWI OS_File + XOS_Bit + LDMVSFD sp!, {r1-r5,pc}^ + LDR lr, [sp] + TEQ lr, #0 + STRNE r0, [lr] + LDR lr, [sp, #4] + TEQ lr ,#0 + STRNE r2, [lr] + LDR lr, [sp, #8] + TEQ lr, #0 + STRNE r3, [lr] + LDR lr, [sp ,#24] + TEQ lr, #0 + STRNE r4, [lr] + LDR lr, [sp ,#28] + TEQ lr, #0 + STRNE r5, [lr] + MOV r0, #0 + LDMFD sp!, {r1-r5,pc}^ + + +; os_error *SWI_OS_File_6(char *filename); + + STARTCODE SWI_OS_File_6 + + STMFD sp!, {r4-r5,lr} + MOV r1, r0 + MOV r0, #6 + SWI OS_File + XOS_Bit + MOVVC r0, #0 + LDMFD sp!, {r4-r5,pc}^ + + +; os_error *SWI_OS_File_7(char *filename, int loadaddr, int execaddr, int size); + + STARTCODE SWI_OS_File_7 + + STMFD sp!, {r4-r5,lr} + MOV r5, r3 + MOV r4, #0 + MOV r3, r2 + MOV r2, r1 + MOV r1, r0 + MOV r0, #7 + SWI OS_File + XOS_Bit + MOVVC r0, #0 + LDMFD sp!, {r4-r5,pc}^ + + +; os_error *SWI_OS_CLI(char *cmd); + + STARTCODE SWI_OS_CLI + + MOV ip, lr + SWI OS_CLI + XOS_Bit + MOVVC r0, #0 + MOVS pc, ip + + +; int SWI_OS_ReadC(void); + + STARTCODE SWI_OS_ReadC + + MOV ip, lr + SWI OS_ReadC + XOS_Bit + MOVS pc, ip + + +; os_error *SWI_OS_ReadVarVal(char *var, char *buf, int len, int *bytesused); + + STARTCODE SWI_OS_ReadVarVal + + STMFD sp!, {r4,lr} + MOV ip, r3 + MOV r3, #0 + MOV r4, #0 + SWI OS_ReadVarVal + XOS_Bit + LDMVSFD sp!, {r4,pc}^ + TEQ ip, #0 + STRNE r2, [ip] + MOV r0, #0 + LDMFD sp!, {r4,pc}^ + + +; os_error *SWI_OS_FSControl_54(char *buffer, int dir, char *fsname, int *size); + + STARTCODE SWI_OS_FSControl_54 + + STMFD sp!, {r3-r6,lr} + LDR r5, [r3] + MOV r3, r2 + MOV r2, r1 + MOV r1, r0 + MOV r0, #54 + SWI OS_FSControl + XOS_Bit + LDMVSFD sp!, {r3-r6,pc}^ + MOV r0, #0 + LDMFD sp!, {r3} + STR r5, [r3] + LDMFD sp!, {r4-r6,pc}^ + + +; os_error *SWI_OS_FSControl_37(char *pathname, char *buffer, int *size); + + STARTCODE SWI_OS_FSControl_37 + + STMFD sp!, {r2,r3-r5,lr} + LDR r5, [r2] + MOV r3, #0 + MOV r4, #0 + MOV r2, r1 + MOV r1, r0 + MOV r0, #37 + SWI OS_FSControl + XOS_Bit + LDMVSFD sp!, {r2,r3-r5,pc}^ + MOV r0, #0 + LDMFD sp!, {r2} + STR r5, [r2] + LDMFD sp!, {r3-r5,pc}^ + + +; os_error *SWI_DDEUtils_Prefix(char *dir); + + STARTCODE SWI_DDEUtils_Prefix + + MOV ip, lr + SWI DDEUtils_Prefix + XOS_Bit + MOVVC r0, #0 + MOVS pc, ip + +; int SWI_Read_Timezone(void); + + STARTCODE SWI_Read_Timezone + + MOV ip, lr + SWI Territory_ReadCurrentTimeZone + XOS_Bit + MOVVC r0, r1 + MOVVS r0, #0 + MOVS pc, ip + + + END diff --git a/acorn/zipup.h b/acorn/zipup.h new file mode 100644 index 0000000..47c3536 --- /dev/null +++ b/acorn/zipup.h @@ -0,0 +1,16 @@ +/* + 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 +*/ +#define fhow "r" +#define fbad (NULL) +typedef FILE *ftype; +#define zopen(n,p) fopen(n,p) +#define zread(f,b,n) fread((b),1,(n),(FILE*)(f)) +#define zclose(f) fclose(f) +#define zerr(f) (k==(extent)(-1L)) +#define zstdin 0 |