diff options
Diffstat (limited to 'qdos')
-rw-r--r-- | qdos/IZREADME.SMS | 600 | ||||
-rw-r--r-- | qdos/Makefile.qdos | 143 | ||||
-rw-r--r-- | qdos/Makefile.qlzip | 139 | ||||
-rw-r--r-- | qdos/config.s | 153 | ||||
-rw-r--r-- | qdos/crc68.s | 99 | ||||
-rw-r--r-- | qdos/match.s | 138 | ||||
-rw-r--r-- | qdos/osdep.h | 33 | ||||
-rw-r--r-- | qdos/qdos.c | 877 | ||||
-rw-r--r-- | qdos/qfileio.c | 235 | ||||
-rw-r--r-- | qdos/zipup.h | 19 |
10 files changed, 2436 insertions, 0 deletions
diff --git a/qdos/IZREADME.SMS b/qdos/IZREADME.SMS new file mode 100644 index 0000000..9ad1503 --- /dev/null +++ b/qdos/IZREADME.SMS @@ -0,0 +1,600 @@ +IZREADME_SMS (IZREADME.SMS): Info-ZIP for SMS/QDOS, last revised: 15-Jun-1998 +=============================================================================== +[was "InfoZIP_SMSQDOS_ReadMe" in J. Hudson's original ports, ca. 08/1995] + +Info-ZIP Programs +================= + +Zip +UnZip +UnZipSFX +fUnZip + +Introduction +------------ + +This archive is a result of frustrations with contemporary (August 95) +versions of Zip and UnZip. While they use the same compression +algorithms as the Info-ZIP programs, there the compatibility ends. If +you just use Zip/UnZip only on SMS/QDOS, then perhaps this is not a +problem (but I know for some users it still is); if you use Zip/UnZip +to transport source code and data between diverse systems, then the +disregard for Info-ZIP standards is inconvenient, particularly the +fact that directories are not supported and files are always stored +underscored. + +This release of Zip/UnZip offers: + + o zipfile/directory compatibility with all other supported + platforms + + o SMS/QDOS compatibility and back-compatible with earlier + versions. + + o Improved performance (Zip is typically 50% faster) + + o Command-line compatibility with Info-ZIP + + o Self-extracting archives (but not very elegantly) + + o Archives are marked as 'created by SMS/QDOS'. + + o Optional recursion into directories + + o Directory structure restored on unzip of Info-ZIP/PKZIP- + compatible archives. + + o Config'urable for listing and unpack formats (Info-ZIP (.) or + SMS/QDOS (_) and 'Press any key' timeouts. Override options + from command line. + +Info-ZIP Standards +------------------ + +This (rather long-winded and waffling) section discusses the +conventions and standards used by Info-ZIP-compatible archivers and how +"Info-ZIP for SMS/QDOS" achieves compatibility. + +Info-ZIP Zip/UnZip on all supported platforms (Unix, DOS, OS/2, NT, +VAX/VMS, Amiga etc etc), works in a specific way. (Until now SMS/QDOS +was neither 'supported' nor Info-ZIP-compliant.) + + a. The zipfile directory is in (/.) (Unix) format. + + b. When zips are listed, it is in 'zipfile' (Unix) format. + + c. When files are added, they are defined in native format. + + d. When files are added, this is shown in 'zipfile' format. + + e. When files are unpacked, this is done to native format, but + selection is done in 'zipfile' format. + +Basically, the listing and stored format of a file is that of the +destination. + +So, given a file structure at some arbitrary 'root' level. + + Makefile + src (Dir) + afile.c + bfile.c + docs (Dir) + prog.txt + hdr (Dir) + cfile.h + dfile.h + +Then these would be in Unix (and Amiga) as + + Makefile + src/afile.c + src/bfile.c + src/docs/prog.txt + hdr/cfile.h + hdr/dfile.h + +This is also how the zipfile directory appears. + +And in DOS/OS2/NT + + Makefile + src\afile.c + src\docs\prog.txt + hdr\cfile.h .. etc + +And in VMS (we SHOUT in VMS and have a silly file system) + + MAKEFILE + [SRC]AFILE.C + [SRC.DOC]PROG.TXT + [HDR]CFILE.H .. etc + (OK VMS purist, [.SRC] etc. Only an example) + +And in SMS/QDOS (quiet again, but slightly ludicrous !) + + Makefile + src_afile_c + src_doc_prog_txt + hdr_cfile_h .. etc + +The main problem regarding SMS/QDOS is not that of extensions - (after +all, only VMS and DOS _really_ have extensions; Unix, AmigaDOS, NT and +OS/2 (and Win95) allow multiple '.' in.long.file.names. + +The SMS/QDOS problem is that '_' is both a legal file name character +and a directory separator. This creates the difficulties, as +directories and files are somewhat different objects. + +It is the intention that these versions of SMS/QDOS Zip/UnZip will +follow the Info-ZIP rules, thus providing compatibility with the other +platforms. It is possible to zip the file structure described above on +SMS/QDOS and unpack it on VMS and get the VMS structure as shown in the +example (and vice-versa). [We only choose the most obtuse file +systems for the examples]. + +In order to achieve this, SMS/QDOS names are mapped into Unix-style +ones when the zipfile is created and un-mapped when it is unpacked. +There is an option to unpack in 'zipfile' format (i.e. with '.' rather +than '_'), but there will be no option to pack to all '_'. That would +contravene the standard. However, a file + + src_split_name_c (which is src->split_name_c !) + src/split_name.c) + +where src is a hard directory, would be stored in the zip directory as + + src/split_name.c + +It does handle '_' with a little intelligence. + +The default UnZip option will be to translate '.' to '_'; this is +because there are still many QDOS/Minerva users that cannot handle '.' +without quotes, which is immensely inconvenient. For many SMS users +'_' is also the most natural and convenient option. It also means that +SMS/QDOS <-> SMS/QDOS Zip - UnZip sequences are transparent. + +There will, however, be two ways around this in UnZip. + + 1. It is possible to Config the UnZip default to be '.' + translations (or not). + + 2. The UnZip -Q1 option will toggle the default (Config'ed) + state. + +Examples: + +Given that we want/have + + Makefile (Makefile) + src/afile.c (src_afile_c) + src/bfile.c (src_bfile_c) + src/docs/prog.txt (src_docs_prog_txt) + hdr/cfile.h (hdr_cfile_h) + hdr/dfile.h (hdr_dfile_h) + +Then on SMS/QDOS we might have added the *.c files as + + ex zip;'-r test *_c' + +(or VMS, just to do something different) + + zip -r test [.src]*.c + +In both cases the file lists as above (left). + +To unpack on SMS/QDOS (just the _c/.c files) + + ex unzip;'test src/*.c' + + (and VMS, unzip test src/*.c) + +i.e. in both cases using the 'zipfile' format. As a concession to +SMS/QDOS, you could also have: + + ex unzip;'test src_*_c' + + but not unzip test [.src]*.c on VMS !!!!! Sorry, dinosaurs. + +Both SMS/QDOS commands unpack to + + src_afile_c etc, where src_ is a hard sub-directory. + +(and the VMS example would unpack to [.src]afile.c, (or to src\afile.c on +DOS/NT/OS2 etc). + +Options & SMS/QDOS Features +--------------------------- + +The options supported by Zip/UnZip are basically those documented in +the Info-ZIP documents and shown in on-line 'usage'. In particular, -r +and -j work as intended. + +PLEASE NOTE: Previous SMS/QDOS zip/unzips have NOT followed these +conventions, for example -r was not implemented and -j was reversed. + +A number of -Q (SMS/QDOS-specific) options (not yet in the current +documents or usage screens) are implemented. + +The Zip 2.0.1 (and later) default is to add SMS/QDOS headers where +file type = 1 (exe) or 2 (rel) or (type > 0 && != 255 and (filesize % +64) != 0). Directories are included anyway, unless you zip -D. + +Where a header is added for an 'exe' file a '*' is displayed after the +name in the zip display (and '#' for 'rel' files). + +The -Q options for Zip are: + + -Q1 Don't add headers for ANY files + -Q2 Add headers for all files + -Q4 Don't wait for interactive key press + + (additive, so -Q5 => no headers, no wait, -Q6 all headers, + no wait etc) + + (the default is exec/rel headers, 5 sec wait) + +Zip has rationalised the file header storage in zipfiles. The +previous Zip used to store a QDOS header for each file. This was very +wasteful, for example compressing a SMS/QDOS release of PGP in this +way came to 730Kb, too large for a DD disk. Changing the Zip program +just to add a header record for the single PGP exe and the zipfile +size went down to around 690Kb. + +And for UnZip + + -Q1 Toggle unpack format status ('.' <-> '_') + -Q2 Toggle listing format + -Q4 Don't wait for key press + +Files Types +----------- + +The history of QDOS suffers from incompatible feature +implementations. For example, Thor directories have file type 3, CST +have type 4 and Level 2 have type 255. Some software writers (both +amateur and otherwise) have used type 3 or 4 for other purposes +(backward compatibility ?? who cares ??). + +In order to bypass problems cause by incompatible (inconsiderate ?) +usage of file types, the file type denoting a directory is a +Config'urable item. The default is set to -1 (65535 in Config terms), +which means "determine directory type from the file header of the root +directory". If this is appears unsuccessful on your system, the value +can be Config'ed in the range 3-255. + +Zip assumes a file is a directory if: + + ((type == CONFIGed_type) && (file_size % 64) == 0) + +If you are unfortunate enough have files of that pass this test but +are not directories, then Zip will loop endless, as SMS/QDOS opens the +root directory again !!! (recursion: see recursion etc). + +I suggest you refrain from zipping such files and contact the software +supplier and point out the error of their ways. + +File Naming Issues +------------------ + +Zip will append a '_zip' suffix to the archive filename when the +supplied name (i.e. excluding device/directory parts) does not +contain a '_' or a '.'. This is broadly compatible with Info-ZIP, +taking into account the '_' aberation. + +So + ex zip;'ram2_test ...' >> ram2_test_zip + + ex zip;'ram2_test.zip ...' >> ram2_test.zip + + ex zip;'ram2_test_rep ... ' >> ram2_test_rep + + ex zip;'ram2_fdbbs.rep ... ' >> ram2_fdbbs.rep + + ex zip;'ram2_test_rep.zip ...' >> ram2_test_rep.zip + +This implies that if a file ram2_test.zip exists, and you do: + + ex zip;'ram2_test ...' + +Then a new file (test_zip) is created, rather than 'test.zip' being +updated. + +Zip supports extensive recursive wild-carding, again the fact that '_' +can be a directory separator as well as part of a file name makes this +a bit tricky, but given the example: + + test1_bas + test2_bas + dir1->demo1_bas where -> indicates a sub dir + dir2->demo2_bas + + ex zip;'ram2_test *_bas' + just finds test1_bas, test2_bas + + ex zip;'-r ram2_test *_bas' + recurses and finds all the files + +You might think that + + ex zip;'-r ram2_test *_*_bas' + +would just find the files in the subdirectories--well yes, but it will +also find very other sub-dir'ed _bas file on the disk too. This is +a feature. + +The pattern matching supports Unix-style 'regex' so you could: + + ex zip;'ram2_test dir?_*_bas' + or + ex zip;'ram2_test dir[12]_*_bas + + +UnZip has now got a fixed -d option. This is used to specify the +directory to unpack the zipfile into, it must follow immediately +after the zip name. + + ex unzip;'ram2_test_zip -d ram3_ *_txt' + +would unpack all *_txt files to ram3_ . + +It is not necessary to set the default directory to pack files, Zip +will remove any device names (and store any hard directory names, +unless you zip -j). + + ex zip;'ram1_test flp1_*' + + -----> + adding: file.dat (deflated 50%) + adding: menu.rext # (deflated xx%) + adding: zip * (deflated yy%) + adding: hard_one (stored 0%) + adding: hard_one/stuff.bas (deflated ...) + +Due to the way the file-mapping is implemented, it is not supported +over the nX_ type network device. + +Config Options +-------------- + +A limited number of SMS/QDOS specific functions can be set using the +QJump Config program. + + For Zip: + + Timeout for interactive 'Press any key' prompt + + 65535 Wait forever (aka -1) + 0 No wait + n (1-32767) Wait for 'n' clocks (1/50 sec) + + Other values are unsupported. Note Config works on 'unsigned' + integer values (at least according to my manual). + + Directory file type key. + + Config will accept any value in the range 3-255, known useful + values are 3 (Thor), 4 (CST) and 255 (Level 2 devices). A value + of 65535 (aka -1) means "determine from device info". + + For UnZip: + + Timeout as above + + Unpack mode (SMS/QOS ('_') or Info-ZIP ('.') + + List format (Info-ZIP ('.') or SMS/QDOS ('_') + + +When the 'Press a key' text is displayed, if you press ESC, then it +waits until you press any other key, infinite timeout. This may be +useful if you want (much) more time to study a listing etc. + +Defaults for timeout and directory type are 250 and -1 respectively. + +More Goodies +------------ + +Part of the Zip compression code is now in assembler; it runs +noticably faster than the previous version. Compressing some arbitrary +files with the previous Zip it took 251 seconds, with Zip 2.0.1 it +took (a mere) 170 seconds (68008 QL). + +More good news is that SMS/QDOS is just another system option on top +of standard Info-ZIP, unlike the previous ports that were much more +SMS/QDOS specific. For example, compiling the standard source with c68 +(i.e. #define QDOS), then you get an SMS/QDOS version. + +Compile with Linux/gcc and get the standard Linux version. Now, here's +the cool bit; compile with Linux/gcc and "-DQLZIP", and get a standard +Linux Zip/UnZip with SMS/QDOS (header) extensions. + +so, on Linux: + + zip -Q stuff.zip qtpi zip unzip + +the -Q tells Zip to look for XTc68/Lux68 cross-compiler data size +blocks and produce a zipfile with SMS/QDOS headers in it (for exec +type programs). This works for exec files produced by the XTc68/Lux68 +cross compilers and ANY SMS/QDOS files copied to a Unix or MS-DOS disk +from an SMS/QDOS floppy using 'qltools v2.2' (or later). + +Self Extracting Archives +------------------------ + +Info-ZIP self-extracting archives (_sfx) are created in a rather +'brute-force' way. The UnZipSFX program is prepended to a zipfile. + +i.e. file_sfx = unzipsfx + file_zip + ex file_sfx + +Although the UnZipSFX program is a cut-down UnZip, it is still around +30Kb - 50Kb, depending on platform. + +The success of this approach depends on how the operating system +loader loads executable files. On most systems where the loader only +loads the actual program part (Unix, VMS, DOS et al), the this is +quite efficient; if you make, say, a 4Mb zipfile and prepend a 30Kb +UnZipSFX image, then the system only loads the 30Kb program and the +process is efficient as the zipped data part is still unpacked from +disk. These systems also supply the running UnZipSFX program stub with +the path name of the file it was loaded from, so the program knows +what it has to unpack (so on Linux, for example): + + cat /usr/bin/unzipsfx test.zip > test.sfx # concatenate the files + chmod 755 test.sfx # make executable + test.sfx # to extract, it + # 'knows' it is "test.sfx" + +Unfortunately, the more simplistic nature of SMS/QDOS makes this much +more difficult and rather less efficient as: (see note 1) + + a. The SMS/QDOS 'loader' loads the whole file into memory. + + b. The SMS/DOS 'loader'/c68 run-time system does not return the + name of the file from which it was loaded. + + c. You cannot so easily create a image file by concatenating two + files, it is also necessary to ensure the executable file + header is set correctly. + + d. The show stopper. The data space required for the + self-extracting archive is required, as not easily maintained + during electronic transfer. + + +If anyone is still interested, then the following support for UnZipSFX +is provided. + + o A program 'makesfx' will combine a stub (callstub), UnZipSFX image + and a zipfile to produce a sfx (self-extracting zip) file. + + o A callable interface is supplied. The user calls the SFX file, + which creates the files necessary to do the extraction. + +The makesfx program concatenates the supplied files to standard +output. + +So, to create a sfx of all the _c files in the default directory. + + # 1st create a zipfile of the required files + + ex zip;'ram1_test_zip *_c' + + # Now create the sfx file (ram2_test_sfx) + # our UnZipSFX image is in 'win1_bin' + # as is the call stub. + +ex makesfx;'-o test_sfx -x win1_bin_unzipsfx -s win1_bin_callstub -z ram1_test_zip' + +The arguments to makesfx are: + + -s stubfile + -x UnZipSFX_program + -z Zip_file + -o Output_file + +You can now unpack the _sfx file on any SMS/QDOS-compatible +system. + + f$ = "win2_tmp_test_sfx" + a = alchp(flen(\f$)) + lbytes f$,a + call a + rechp(a) + +ZipInfo +------- + +Given the above note concerning SMS/QDOS programs not knowing the name +by which the program was invoked, then the usual symbolic-link-of-unzip- +to-zipinfo trick is unavailable (presupposing there is some some SMS/QDOS +trick to emulate symbolic links). + +ZipInfo functionality is only available via 'unzip -Z'. There is no +separate ZipInfo program. + +Caveat ATP Users +---------------- + +ATP for SMS/QDOS users should pay particular attention to the +Zip/UnZip options in their atprc and compare with Info-ZIP Zip/UnZip +usage. Older versions of Zip/UnZip screwed up -j. + + + zip -jk + unzip -jo + +Distribution & Copyright +------------------------ + +This software is written by and largely copyrighted by the 'Info-ZIP' +group whose members are noted in the accompanying documentation. This +particular SMS/QDOS port plus 'makesfx' was written by, but is not +copyrighted by, Jonathan R Hudson. The SMS/QDOS code in this release +is written from scratch and is not dependent on previous SMS/QDOS +releases, but is (largely) compatible. + +As a courtesy to the authors of this package, please ensure that the +documentation is supplied when it is re-distributed. + +In particular, if this archive is split into Zip and UnZip components, +ensure that this document ("IZREADME_SMS") is supplied in +each component. + +SMS/QDOS version by: +Jonathan R Hudson (jrhudson@bigfoot.com) + +I am grateful to Graham Goodwin for finding some most imaginative +means of breaking the beta code. + +I'd also like to thank Thierry Godefroy for providing the 2.1/5.2 +source code and making the initial contact with the Info-ZIP group. + +And of course, many, many thanks to the Info-ZIP workers for making +this code freely available. + +Note 1 +------ + +The 'C' language FAQ ('frequently asked questions' [comp.lang.c]) +notes on the matter of obtaining the load file name of a 'C' program: + +16.5: How can my program discover the complete pathname to the + executable file from which it was invoked? + +A: argv[0] may contain all or part of the pathname, or it may + contain nothing. You may be able to duplicate the command + language interpreter's search path logic to locate the + executable if the name in argv[0] is present but incomplete. + However, there is no guaranteed or portable solution. + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Note 2 +------ + +NUL files for SMS2. There appears to be a conflict between SMS2/LBASIC +compiled programs and c68 programs using nul as stdin. + + EW zip,nul;'ram1_test *_bas' # will not work + + # This does work ! + EW zip,#FOP_IN('nul');'ram2_test *_bas' : CLOSE + +Note 3 +------ + +version number incremented to 2.0.1a and 5.12a to accomodate Erling +Jacobsen's exit message requirements + +version number incremented to Zip 2.0.1b to fix bug on zipping files +starting with leading underscore. + +version number incremented to UnZip 5.12b to fix UnZip problem on +files zipped with leading './', and linked with revised (fixed) c68 +'utime' function (could corrupt level 1 files). (source code _only_ as +IZQ004.zip). + +Ported Zip 2.1 and UnZip 5.2 (July 1996). Released as INZIP005.zip + +All later versions --- see Info-ZIP release notes and documentation. diff --git a/qdos/Makefile.qdos b/qdos/Makefile.qdos new file mode 100644 index 0000000..1028273 --- /dev/null +++ b/qdos/Makefile.qdos @@ -0,0 +1,143 @@ +include /etc/ql.mak + +# Makefile for Zip, ZipNote, ZipCloak and ZipSplit + +MAKE = make +SHELL = /bin/sh + +# +BIND = $(CC) + +# probably can change this to 'install' if you have it +INSTALL = cp + +# target directories - where to install executables and man pages to +BINDIR = +manext=1 +MANDIR = +ZIPMANUAL = MANUAL + +# flags +# CFLAGS flags for C compile +# LFLAGS1 flags after output file spec, before obj file list +# LFLAGS2 flags after obj file list (libraries, etc) +CFLAGS = -O -DASMV -DASM_CRC +LFLAGS1 = -v +#LFLAGS2 = -lutime + +all: zip + +# object file lists +OBJZ = zip.o zipfile.o zipup.o fileio.o util.o globals.o crypt.o qdos.o ttyio.o +OBJI = deflate.o trees.o qfileio.o crctab.o +OBJA = config.o crc68.o match.o +# crc32.o +OBJQ = qdos_.o config.o qfileio_.o +OBJU = zipfile_.o zipup_.o fileio_.o util_.o globals.o $(OBJQ) +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o $(OBJU) crctab.o crypt_.o +OBJS = zipsplit.o $(OBJU) + + +# suffix rules +.SUFFIXES: +.SUFFIXES: _.o .o .c .doc .1 +.c_.o: + rm -f $*_.c; ln $< $*_.c + $(CC) $(CFLAGS) -DUTIL -c $*_.c + rm -f $*_.c +.c.o: + $(CC) $(CFLAGS) -c $< + +.1.doc: + nroff -man $< | col -b | uniq > $@ + +# rules for zip, zipnote, zipcloak, zipsplit, and zip.doc. +$(OBJZ): zip.h ziperr.h tailor.h +$(OBJI): zip.h ziperr.h tailor.h +$(OBJN): zip.h ziperr.h tailor.h +$(OBJS): zip.h ziperr.h tailor.h +$(OBJC): zip.h ziperr.h tailor.h +zip.o zipup.o crypt.o zipup_.o zipcloak.o crypt_.o: crypt.h + +qfileio.o: qdos/qfileio.c + cp qdos/qfileio.c qfileio.c + $(CC) $(CFLAGS) -c qfileio.c + rm -f qfileio.c + +qfileio_.o: qdos/qfileio.c + cp qdos/qfileio.c qfileio_.c + $(CC) $(CFLAGS) -DUTIL -c qfileio_.c + rm -f qfileio_.c + +match.o: qdos/match.s + cp qdos/match.s ./_match.s + $(AS) _match.s -o match.o + rm -f _match.s + +crc68.o: qdos/crc68.s + cp qdos/crc68.s ./crc68.s + $(AS) crc68.s -o crc68.o + rm -f crc68.s + +config.o: qdos/config.s + cp qdos/config.s ./config.x + $(CC) -c -DZIP config.x -o config.o + rm -f config.x + +ZIPS = zip$E zipnote$E zipsplit$E zipcloak$E + +zip.o zipup.o zipnote.o zipcloak.o zipsplit.o: revision.h +zips: $(ZIPS) +zipsman: $(ZIPS) $(ZIPMANUAL) + +qdos.o: qdos/qdos.c + cp qdos/qdos.c . + $(CC) -c -oqdos.o qdos.c + rm -f qdos.c + +qdos_.o: qdos/qdos.c + cp qdos/qdos.c ./qdos_.c + $(CC) -DUTIL -c -oqdos_.o qdos_.c + rm -f qdos_.c + +zip$E: $(OBJZ) $(OBJI) $(OBJA) + $(BIND) -o zip$E $(LFLAGS1) $(OBJZ) $(OBJI) $(OBJA) $(LFLAGS2) +zipnote$E: $(OBJN) + $(BIND) -o zipnote$E $(LFLAGS1) $(OBJN) $(LFLAGS2) +zipcloak$E: $(OBJC) + $(BIND) -o zipcloak$E $(LFLAGS1) $(OBJC) $(LFLAGS2) +zipsplit$E: $(OBJS) + $(BIND) -o zipsplit$E $(LFLAGS1) $(OBJS) $(LFLAGS2) + +$(ZIPMANUAL): man/zip.1 + nroff -man man/zip.1 | col -b | uniq > $(ZIPMANUAL) + +# install +install: $(ZIPS) + $(INSTALL) $(ZIPS) $(BINDIR) + $(INSTALL) man/zip.1 $(MANDIR)/zip.$(manext) + +uninstall: + -cd $(BINDIR); rm -f $(ZIPS) + -cd $(MANDIR); rm -f zip.$(manext) + +flags: configure + sh configure flags + +# These symbols, when #defined using -D have these effects on compilation: +# ZMEM - includes C language versions of memset(), memcpy(), and +# memcmp() (util.c). +# SYSV - use <sys/dirent.h> and the library opendir() +# DIRENT - use <sys/dirent.h> and getdents() instead of <sys/dir.h> +# and opendir(), etc. (fileio.c). +# NODIR - used for 3B1, which has neither getdents() nor opendir(). +# NDIR - use "ndir.h" instead of <sys/dir.h> (fileio.c). +# UTIL - select routines for utilities (note, cloak, and split). +# PROTO - enable function prototypes. +# RMDIR - remove directories using a system("rmdir ...") call. +# CONVEX - for Convex make target. +# AIX - for AIX make target. +# LINUX - for linux make target. + +# end of Makefile diff --git a/qdos/Makefile.qlzip b/qdos/Makefile.qlzip new file mode 100644 index 0000000..e12f004 --- /dev/null +++ b/qdos/Makefile.qlzip @@ -0,0 +1,139 @@ +# Makefile for Zip, ZipNote, ZipCloak and ZipSplit + +# what you can make ... +all: zip + +#MAKE = make -f unix/Makefile +SHELL = /bin/sh + +# (to use the Gnu compiler, change cc to gcc in CC and BIND) +CC = cc +BIND = $(CC) +AS = $(CC) -c +E = +CPP = /lib/cpp + +# probably can change this to 'install' if you have it +INSTALL = cp + +# target directories - where to install executables and man pages to +prefix = /usr/local +BINDIR = $(prefix)/bin +manext=1 +MANDIR = $(prefix)/man/man$(manext) +ZIPMANUAL = MANUAL + +# flags +# CFLAGS flags for C compile +# LFLAGS1 flags after output file spec, before obj file list +# LFLAGS2 flags after obj file list (libraries, etc) +CFLAGS = -O2 -fno-strength-reduce -I. -DUNIX -DQLZIP -DASM_CRC +LFLAGS1 = +LFLAGS2 = -s + +# object file lists +OBJZ = zip.o zipfile.o zipup.o fileio.o util.o globals.o crypt.o ttyio.o \ + unix.o crc_gcc.o crctab.o qdos.o +OBJI = deflate.o trees.o +OBJA = +OBJU = zipfile_.o fileio_.o util_.o globals.o unix_.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 unix/osdep.h + +# suffix rules +.SUFFIXES: +.SUFFIXES: _.o .o .c .doc .1 +.c_.o: + rm -f $*_.c; ln $< $*_.c + $(CC) -c $(CFLAGS) -DUTIL $*_.c + rm -f $*_.c +.c.o: + $(CC) -c $(CFLAGS) $< + +.1.doc: + nroff -man $< | col -b | uniq > $@ + +# rules for zip, zipnote, zipcloak, zipsplit, and the Zip MANUAL. +$(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 +zipup.o: unix/zipup.h + +match.o: match.S + $(CPP) match.S > _match.s + $(AS) _match.s + mv _match.o match.o + rm -f _match.s + +unix.o: unix/unix.c + $(CC) -c $(CFLAGS) unix/unix.c + +unix_.o: unix/unix.c + rm -f $*_.c; ln unix/unix.c $*_.c + $(CC) -c $(CFLAGS) -DUTIL $*_.c + rm -f $*_.c + +qdos.o: qdos/qdos.c + $(CC) -c $(CFLAGS) qdos/qdos.c + +crc_gcc.o: crc_i386.S # 32bit, GNU AS + gcc -O3 -I. -DASM_CRC -Di386 -x assembler-with-cpp -c -o $@ crc_i386.S + +ZIPS = zip$E zipnote$E zipsplit$E zipcloak$E + +zips: $(ZIPS) +zipsman: $(ZIPS) $(ZIPMANUAL) + +zip$E: $(OBJZ) $(OBJI) $(OBJA) + $(BIND) -o qlzip$E $(LFLAGS1) $(OBJZ) $(OBJI) $(OBJA) $(LFLAGS2) +zipnote$E: $(OBJN) + $(BIND) -o zipnote$E $(LFLAGS1) $(OBJN) $(LFLAGS2) +zipcloak$E: $(OBJC) + $(BIND) -o zipcloak$E $(LFLAGS1) $(OBJC) $(LFLAGS2) +zipsplit$E: $(OBJS) + $(BIND) -o zipsplit$E $(LFLAGS1) $(OBJS) $(LFLAGS2) + +$(ZIPMANUAL): man/zip.1 + nroff -man man/zip.1 | col -b | uniq > $(ZIPMANUAL) + +# install +install: $(ZIPS) + $(INSTALL) $(ZIPS) $(BINDIR) + $(INSTALL) man/zip.1 $(MANDIR)/zip.$(manext) + +uninstall: + -cd $(BINDIR); rm -f $(ZIPS) + -cd $(MANDIR); rm -f zip.$(manext) + +dist: + zip -u9T zip`sed -e '/VERSION/!d' -e 's/.*"\(.*\)".*/\1/' \ + -e s/[.]//g -e q revision.h` \ + `awk '/^Makefile/,/vms_zip.rnh/ {print $$1}' < contents` + +flags: unix/configure + sh unix/configure "${CC}" "${CFLAGS}" + +# These symbols, when #defined using -D have these effects on compilation: +# ZMEM - includes C language versions of memset(), memcpy(), +# and memcmp() (util.c). +# HAVE_DIRENT_H - use <dirent.h> instead of <sys/dir.h> +# NODIR - for 3B1, which has neither getdents() nor opendir(). +# HAVE_NDIR_H - use <ndir.h> (unix/unix.c). +# HAVE_SYS_DIR_H - use <sys/dir.h> +# HAVE_SYS_NDIR_H - use <sys/ndir.h> +# UTIL - select routines for utilities (note, cloak, split) +# NO_RMDIR - remove directories using a system("rmdir ...") call. +# NO_PROTO - cannot handle ANSI prototypes +# NO_CONST - cannot handle ANSI const + +# Generic targets: + +# end of Makefile diff --git a/qdos/config.s b/qdos/config.s new file mode 100644 index 0000000..56a2a85 --- /dev/null +++ b/qdos/config.s @@ -0,0 +1,153 @@ +;=========================================================================== +; 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 +;=========================================================================== +# +.globl _qlflag +.globl _qlwait +#ifdef ZIP +.globl _dtype +#endif + +.data + ds.w 0 + dc.b '<<QCFX>>01' +#ifdef ZIP + dc.w 8 + dc.b 'Info-ZIP' +* 12345678901234567890 + ds.w 0 + dc.w 4 + dc.b 'qdos' + ds.w 0 +#else + dc.w 10 + dc.b 'Info-UNZIP' +* 12345678901234567890 + ds.w 0 + dc.w 4 + dc.b 'qdos' + ds.w 0 +#endif + dc.b 10 + dc.b 0 +l_4: dc.w _qlwait-l_4 + dc.w 0 + dc.w 0 +l_5: dc.w hpt-l_5 +l_6: dc.w hxx-l_6 + +#ifdef ZIP + dc.b 10 + dc.b 0 +d_4: dc.w _dtype-d_4 + dc.w 0 + dc.w 0 +d_5: dc.w dpt-d_5 +d_6: dc.w dxx-d_6 + +#else + dc.b 4 + dc.b 0 +l5: + dc.w list1-l5 + dc.w 0 +l5a: + dc.w Postit-l5a ; post proc +l6: + dc.w apt-l6 +l7: + dc.w axx-l7 +* ------------------------------------- + dc.b 4 + dc.b 0 +l8: + dc.w list2-l8 + dc.w 0 +l8a: + dc.w Postit-l8a ; post proc +l9: + dc.w bpt-l9 +la: + dc.w bxx-la +* ------------------------------------- +#endif + dc.w -1 ; end + +_qlflag: + dc.w 0 +_qlwait: + dc.w 250 +_dtype: + dc.w 255 + +hpt: dc.w 10 + dc.b 'Exit Delay' +* 12345678901234567890 + ds.w 0 +hxx: dc.w 0 + dc.w $ffff + dc.w -1 +#ifdef ZIP +dpt: dc.w 14 + dc.b 'Directory Type' +* 12345678901234567890 + ds.w 0 +dxx: dc.w 3 + dc.w $ff + dc.w -1 +#else + +list1: + dc.b 0 +list2: + dc.b 0 + +apt: + dc.w 11 + dc.b 'Unpack Mode' +* 12345678901234567890 +.even +axx: dc.b 0 + dc.b 0 + dc.w 8 + dc.b 'SMS/QDOS' +.even + dc.b 1 + dc.b 0 + dc.w 7 + dc.b 'Default' +.even + dc.w -1 +.even +bpt: + dc.w 12 + dc.b 'Listing Mode' +* 12345678901234567890 +.even +bxx: + dc.w 0 + dc.w 7 + dc.b 'Default' +.even + dc.b 2 + dc.b 0 + dc.w 8 + dc.b 'SMS/QDOS' +* 12345678901234567890 +.even + dc.w -1 +Postit: + lea.l _qlflag,a0 + move.b list1,d0 + move.b d0,(a0) + move.b list2,d0 + or.b d0,(a0) + moveq #0,d0 + rts +#endif + end diff --git a/qdos/crc68.s b/qdos/crc68.s new file mode 100644 index 0000000..cf74e47 --- /dev/null +++ b/qdos/crc68.s @@ -0,0 +1,99 @@ +;=========================================================================== +; 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 +;=========================================================================== +.text + +.globl _crc32 ; (ulg val, uch *buf, extent bufsize) +.globl _get_crc_table ; ulg *get_crc_table(void) + +_crc32: + move.l 8(sp),d0 + bne valid + moveq #0,d0 + rts +valid: movem.l d2/d3,-(sp) + jsr _get_crc_table + move.l d0,a0 + move.l 12(sp),d0 + move.l 16(sp),a1 + move.l 20(sp),d1 + not.l d0 + + move.l d1,d2 + lsr.l #3,d1 + bra decr8 +loop8: moveq #0,d3 + move.b (a1)+,d3 + eor.b d0,d3 + lsl.w #2,d3 + move.l 0(a0,d3.w),d3 + lsr.l #8,d0 + eor.l d3,d0 + moveq #0,d3 + move.b (a1)+,d3 + eor.b d0,d3 + lsl.w #2,d3 + move.l 0(a0,d3.w),d3 + lsr.l #8,d0 + eor.l d3,d0 + moveq #0,d3 + move.b (a1)+,d3 + eor.b d0,d3 + lsl.w #2,d3 + move.l 0(a0,d3.w),d3 + lsr.l #8,d0 + eor.l d3,d0 + moveq #0,d3 + move.b (a1)+,d3 + eor.b d0,d3 + lsl.w #2,d3 + move.l 0(a0,d3.w),d3 + lsr.l #8,d0 + eor.l d3,d0 + moveq #0,d3 + move.b (a1)+,d3 + eor.b d0,d3 + lsl.w #2,d3 + move.l 0(a0,d3.w),d3 + lsr.l #8,d0 + eor.l d3,d0 + moveq #0,d3 + move.b (a1)+,d3 + eor.b d0,d3 + lsl.w #2,d3 + move.l 0(a0,d3.w),d3 + lsr.l #8,d0 + eor.l d3,d0 + moveq #0,d3 + move.b (a1)+,d3 + eor.b d0,d3 + lsl.w #2,d3 + move.l 0(a0,d3.w),d3 + lsr.l #8,d0 + eor.l d3,d0 + moveq #0,d3 + move.b (a1)+,d3 + eor.b d0,d3 + lsl.w #2,d3 + move.l 0(a0,d3.w),d3 + lsr.l #8,d0 + eor.l d3,d0 +decr8: dbra d1,loop8 + and.w #7,d2 + bra decr1 +loop1: moveq #0,d3 + move.b (a1)+,d3 + eor.b d0,d3 + lsl.w #2,d3 + move.l 0(a0,d3.w),d3 + lsr.l #8,d0 + eor.l d3,d0 +decr1: dbra d2,loop1 +done: movem.l (sp)+,d2/d3 + not.l d0 + rts diff --git a/qdos/match.s b/qdos/match.s new file mode 100644 index 0000000..53b3013 --- /dev/null +++ b/qdos/match.s @@ -0,0 +1,138 @@ +;=========================================================================== +; 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. +; +; This code will run with registerized parameters too, unless SAS +; changes parameter passing conventions between new releases of SAS/C. + + +;;Cur_Match equr d0 ; Must be in d0! +;;Best_Len equr d1 +;;Loop_Counter equr d2 +;;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 a4 + +MAX_MATCH equ 258 +MIN_MATCH equ 3 +WSIZE equ 32768 +MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1 + + + .globl _max_chain_length + .globl _prev_length + .globl _prev + .globl _window + .globl _strstart + .globl _good_match + .globl _match_start + .globl _nice_match + + .text + .globl _match_init + .globl _longest_match + +_match_init: + rts + + +_longest_match: + move.l 4(sp),d0 + movem.l d2-d7/a2-a4,-(sp) + move.l _max_chain_length,d6 + move.l _prev_length,d1 + lea _prev,a2 + lea _window+MIN_MATCH,a4 + move.l _strstart,d5 + move.l a4,a3 + add.l d5,a3 + subi.w #MAX_DIST,d5 + bhi limit_ok + moveq #0,d5 +limit_ok: + cmp.l _good_match,d1 + bcs length_ok + lsr.l #2,d6 +length_ok: + subq.l #1,d6 + + move.b -MIN_MATCH(a3),d3 + lsl.w #8,d3 + move.b -MIN_MATCH+1(a3),d3 + move.b -MIN_MATCH-1(a3,d1),d4 + lsl.w #8,d4 + move.b -MIN_MATCH(a3,d1),d4 + + bra do_scan + +long_loop: + + move.b -MIN_MATCH-1(a3,d1),d4 + lsl.w #8,d4 + move.b -MIN_MATCH(a3,d1),d4 + +short_loop: + lsl.w #1,d0 + move.w 0(a2,d0.l),d0 + cmp.w d5,d0 + dbls d6,do_scan + bra return + +do_scan: + move.l a4,a1 + add.l d0,a1 + + move.b -MIN_MATCH-1(a1,d1),d7 + lsl.w #8,d7 + move.b -MIN_MATCH(a1,d1),d7 + cmp.w d7,d4 + bne short_loop + move.b -MIN_MATCH(a1),d7 + lsl.w #8,d7 + move.b -MIN_MATCH+1(a1),d7 + cmp.w d7,d3 + bne short_loop + + move.w #(MAX_MATCH-MIN_MATCH),d2 + move.l a3,a0 + +scan_loop: + cmpm.b (a1)+,(a0)+ + dbne d2,scan_loop + + sub.l a3,a0 + addq.l #(MIN_MATCH-1),a0 + cmp.l d1,a0 + bls short_loop + move.l a0,d1 + move.l d0,_match_start + cmp.l _nice_match,d1 + bcs long_loop +return: + move.l d1,d0 + movem.l (sp)+,d2-d7/a2-a4 + rts + end + + diff --git a/qdos/osdep.h b/qdos/osdep.h new file mode 100644 index 0000000..72169c1 --- /dev/null +++ b/qdos/osdep.h @@ -0,0 +1,33 @@ +/* + 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 _QDOS_OPDEP +#define _QDOS_OPDEP + +#include <stdlib.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <ctype.h> + +char * ql2Unix(char *); +char * Unix2ql(char *, char **); +int wild (char *); +char *LastDir(char *); +void QDOSexit(void); +short devlen(char *); + +/* + * XXX NO_RENAME instead of the following define ? + */ +#define link rename +#define USE_CASE_MAP +#define USE_EF_UT_TIME +#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \ + procname(n, 1)) +#endif diff --git a/qdos/qdos.c b/qdos/qdos.c new file mode 100644 index 0000000..f07f56e --- /dev/null +++ b/qdos/qdos.c @@ -0,0 +1,877 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2004-May-22 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + * Yes this file is necessary; the QDOS file system is the most + * ludicrous known to man (even more so than VMS!). + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <dirent.h> +#include <unistd.h> + +#include "zip.h" +#include "crypt.h" +#include "ttyio.h" + +#ifdef QDOS + +# include <qdos.h> + +#if CRYPT + +char *getp(m, p, n) + ZCONST char *m; /* prompt for password */ + char *p; /* return value: line input */ + int n; /* bytes available in p[] */ +{ + int c; /* one-byte buffer for read() to use */ + int i; /* number of characters input */ + char *w; /* warning on retry */ + + /* get password */ + w = ""; + sd_cure(getchid(0), -1); /* enable cursor */ + do { + fputs(w, stderr); /* warning if back again */ + fputs(m, stderr); /* display prompt and flush */ + fflush(stderr); + i = 0; + do { + c = getch(); + if (c == 0xc2) { + if (i > 0) { + i--; /* the `del' keys works */ + fputs("\b \b", stderr); + } + } + else if (i < n) { + p[i++] = c; /* truncate past n */ + if(c != '\n') putc('*', stderr); + } + } while (c != '\n'); + + putc('\n', stderr); fflush(stderr); + w = "(line too long--try again)\n"; + } while (p[i-1] != '\n'); + + p[i-1] = 0; /* terminate at newline */ + sd_curs(getchid(0), -1); /* suppress cursor */ + return p; /* return pointer to password */ + +} /* end function getp() */ + +#endif /* CRYPT */ + + +#define __attribute__(p) + +int newname(char *, int, int); + +#else /* !QDOS */ +#define QDOS_FLMAX 36 + +short qlflag = 0; + +struct qdirect { + long d_length __attribute__ ((packed)); /* file length */ + unsigned char d_access __attribute__ ((packed)); /* file access type */ + unsigned char d_type __attribute__ ((packed)); /* file type */ + long d_datalen __attribute__ ((packed)); /* data length */ + long d_reserved __attribute__ ((packed));/* Unused */ + short d_szname __attribute__ ((packed)); /* size of name */ + char d_name[QDOS_FLMAX] __attribute__ ((packed));/* name area */ + long d_update __attribute__ ((packed)); /* last update */ + long d_refdate __attribute__ ((packed)); + long d_backup __attribute__ ((packed)); /* EOD */ + } ; +#endif /* ?QDOS */ + +#define SHORTID 0x4afb /* in big-endian order !! */ +#define LONGID "QDOS02" +#define EXTRALEN (sizeof(struct qdirect) + 8) + +typedef struct +{ + unsigned short shortid __attribute__ ((packed)); + struct + { + unsigned char lo __attribute__ ((packed)); + unsigned char hi __attribute__ ((packed)); + } len __attribute__ ((packed)); + char longid[8] __attribute__ ((packed)); + struct qdirect header __attribute__ ((packed)); +} qdosextra; + +#ifdef USE_EF_UT_TIME +local int GetExtraTime(struct zlist far *z, iztimes *z_utim, unsigned ut_flg); +#endif + +#ifdef QDOS + +#define rev_short(x) (x) +#define rev_long(x) (x) + +char _prog_name[] = "zip"; +char _copyright[] = "(c) Info-ZIP Group"; +long _stack = 16*1024; +char * _endmsg = NULL; + +extern void consetup_title(chanid_t,struct WINDOWDEF *); +void (*_consetup)(chanid_t,struct WINDOWDEF *) = consetup_title; + +struct WINDOWDEF _condetails = +{ + 2, + 1, + 0, + 7, + 500, + 220, + 2, + 30 +}; + +extern short qlwait; +extern short dtype; + +#define CHECKDIR(p1) (((p1).d_type == dtype) && (((p1).d_length % 64) == 0)) + +char * stpcpy (char *d, ZCONST char *s) +{ + while(*d++ = *s++) + ; /* Null loop */ + return d-1; +} + +static jobid_t chowner(chanid_t chan) +{ + extern char *_sys_var; + char *scht; + long *cdb; + long jid; + + scht = *((char **)(_sys_var + 0x78)); + cdb = *(long **)((long *)scht + (chan & 0xffff)); + jid = *(cdb + 2); + return jid; +} + +void QDOSexit(void) +{ + jobid_t me,you; + + me = getpid(); + you = chowner(getchid(0)); + + if((me == you) && ((qlflag & 4) == 0)) + { + if(isatty(0) && isatty(2) && qlwait) + { + char c = 0; + fputs("Press a key to exit", stderr); + if((io_fbyte(getchid(0), qlwait, &c) == 0) && c == 27) + { + io_fbyte(getchid(0), -1, &c); + } + } + } + exit(0); +} + +/* Access seems to be *always* broken in c68 */ +/* Not accurate, just works */ + +int access (char *f, int mode) +{ + struct stat st; + int fd; + + if((fd = stat(f, &st)) == 0) + { + switch(fd) + { + case F_OK: + break; + case R_OK: + fd = (st.st_mode & 0444) == 0; + break; + case W_OK: + fd = (st.st_mode & 0222) == 0; + break; + case X_OK: + fd = (st.st_mode & 0111) == 0; + break; + default: + fd = -1; + break; + } + } + return fd; +} + +/* Fixup a Mickey Mouse file naming system */ + +char * Unix2ql (char *qlname, char **dot) +{ + static char path[64]; + char name[64]; + char *q, *r, *s; + + strcpy(name, qlname); + if(*name == '~') + { + r = name+1; + getcwd(path, sizeof(path)); + q = path + strlen(path); + if(*(q-1) != '_') + { + *q++ = '_'; + } + } + else + { + q = path; + r = name; + } + + if(*r == '/') + { + r++; + } + + strcpy(q, r); + + while (*q) + { + if(*q == '/' || *q == '.') + { + if(*q == '.' && dot) + { + *dot = name + (q - path); + } + *q = '_'; + } + + q++; + } + return path; +} + +#if 0 /* Not used in ZIP */ + +GuessAltName(char *name, char *dot) +{ + if(dot) + { + *dot = '.'; + } + else + { + if((dot = strrchr(name, '_'))) + { + *dot = '.'; + } + } +} + +#endif /* 0 */ + +short devlen(char *p) +{ + char defpath[40]; + short deflen = 0, ok = 0; + + getcwd(defpath, sizeof(defpath)); + deflen = strlen(defpath); + if(deflen) + { + if(strnicmp(p, defpath, deflen) == 0) + { + ok = 1; + } + } + + if(!ok) + { + if(isdirdev(p)) + { + deflen = 5; + } + else + { + deflen = 0; + } + } + return deflen; +} + +char * ql2Unix (char *qlname) +{ + struct stat st; + int sts; + char *p, *r, *s, *ldp; + char *pnam = NULL; + static char path[64]; + short deflen; + char name[64]; + + strcpy(name, qlname); + strcpy(path, name); + + deflen = devlen(qlname); + + p = name + deflen; + pnam = path + deflen; + + if(s = strrchr(p, '_')) + { + *s = 0; + sts = stat(name, &st); + if(deflen && sts ==0 && (st.st_mode & S_IFDIR)) + { + *(path+(s-name)) = '/'; + } + else + { + *(path+(s-name)) = '.'; + } + } + + ldp = p; + for(r = p; *r; r++) + { + if(r != ldp && *r == '_') + { + *r = 0; + if(deflen) + { + sts = stat(name, &st); + } + else + sts = -1; + + if(sts ==0 && (st.st_mode & S_IFDIR)) + { + *(path+(r-name)) = '/'; + ldp = r + 1; + } + else + { + *(path+(r-name)) = '_'; + } + *r = '_'; + } + } + return pnam; +} + +char *LastDir(char *ws) +{ + char *p; + char *q = ws; + struct stat s; + + for(p = ws; *p; p++) + { + if(p != ws && *p == '_') + { + char c; + + p++; + c = *p; + *p = 0; + if(stat(ws, &s) == 0 && S_ISDIR(s.st_mode)) + { + q = p; + } + *p = c; + } + } + return q; +} + +# ifndef UTIL + +static int add_dir(char * dnam) +{ + int e = ZE_OK; + char *p; + short nlen; + + nlen = strlen(dnam); + if(p = malloc(nlen + 2)) + { + strncpy (p, dnam, nlen); + if(*(p+nlen) != '_') + { + *(p+nlen) = '_'; + *(p+nlen+1) = '\0'; + } + if ((e = newname(p, 1, 0)) != ZE_OK) + { + free(p); + } + } + else + { + e = ZE_MEM; + } + return e; +} + +int qlwild (char *dnam, short dorecurse, short l) +{ + static char match[40] = {0}; + static char ddev[8] = {0}; + static short nc; + static short llen; + static char base[40]; + + int chid; + struct qdirect qd; + char *dp; + int e = ZE_MISS; + + if (l == 0) + { + nc = 0; + *base = '\0'; + if (isdirdev (dnam)) + { + dp = dnam; + strncpy (ddev, dnam, 5); + } + else + { + + char *p; + char temp[40]; + + getcwd (temp, 40); + + llen = strlen(temp); + p = (temp + llen - 1); + if (*p != '_') + { + *p++ = '_'; + *p = 0; + } + + strncpy (ddev, temp, 5); + dp = base; + p = stpcpy (dp, temp); + strcpy (p, dnam); + } + + { + char *q = isshexp (dp); + if(q) + { + strcpy (match, dp + 5); + if (q) + { + while (q != dp && *q != '_') + { + q--; + } + *(++q) = '\0'; + } + } + else + { + struct stat s; + if (stat(dp, &s) == 0) + { + if (!(s.st_mode & S_IFDIR)) + { + return procname(dp, 0); + } + } + else + { + return ZE_MISS; /* woops, no wildcards! */ + } + } + + } + } + else + { + dp = dnam; + } + + if ((chid = io_open (dp, 4L)) > 0) + { + int id = 0; + while (io_fstrg (chid, -1, &qd, 64) > 0) + { + short j; + + if (qd.d_szname) + { + if (CHECKDIR(qd)) + { + if(dorecurse) + { + char fnam[256], *p; + + p = stpcpy (fnam, ddev); + strncpy (p, qd.d_name, qd.d_szname); + *(p + qd.d_szname) = 0; + e = qlwild (fnam, dorecurse, l+1); + } + else + { + continue; + } + } + else + { + char nam[48]; + strcpy(nam, ddev); + + strncpy (nam + 5, qd.d_name, qd.d_szname); + *(nam + 5 + qd.d_szname) = 0; + + if (MATCH (match, nam + 5, 0) == 1) + { + if(dirnames && l && id == 0) + { + id = 1; + if((e = add_dir(dp)) != ZE_OK) + { + return e; + } + } + + if((e = procname(nam, 0)) == ZE_OK) + { + nc++; + } + } + } + } + } + io_close (chid); + } + + if (l == 0) + { + *ddev = 0; + *match = 0; + e = (nc) ? ZE_OK : ZE_MISS; + } + return e; + +} + +int wild(char *p) +{ + return qlwild(p, recurse, 0); +} +# endif /* !UTIL */ + +/* + * Return QDOS error, 0 if exec 1 if found but not exe or rel + */ +int qlstat(char *name, struct qdirect *qs, char *flag) +{ + int r; + r = qstat(name, qs); + if(r == 0) + { + if(qs->d_type == 0) + { + r = 1; + } + else if(CHECKDIR(*qs)) + { + r = 255; + } + } + return r; +} + +#else /* !QDOS */ + +long rev_long (ulg l) +{ + uch cc[4]; + cc[0] = (uch)(l >> 24); + cc[1] = (uch)((l >> 16) & 0xff); + cc[2] = (uch)((l >> 8) & 0xff); + cc[3] = (uch)(l & 0xff); + return *(ulg *)cc; +} + +short rev_short (ush s) +{ + uch cc[2]; + cc[0] = (uch)((s >> 8) & 0xff); + cc[1] = (uch)(s & 0xff); + return *(ush *)cc; +} + +#define O_BINARY 0 + +int qlstat(char *name, struct qdirect *qs, char *flag) +{ + int r = -1; + int n, fd; + struct stat s; + struct _ntc_ + { + long id; + long dlen; + } ntc; + + *flag = 0; + if((fd = open(name, O_RDONLY | O_BINARY)) > 0) + { + short nl; + + fstat(fd, &s); + lseek(fd, -8, SEEK_END); + read(fd, &ntc, 8); + qs->d_length = rev_long(s.st_size); + qs->d_update = rev_long(s.st_ctime + 283996800); + + nl = strlen(name); + if(nl > QDOS_FLMAX) + { + nl = QDOS_FLMAX; + *flag = 1; + } + qs->d_szname = rev_short(nl); + memcpy(qs->d_name, name, nl); + + if(ntc.id == *(long *)"XTcc") + { + qs->d_datalen = ntc.dlen; /* This is big endian */ + qs->d_type = 1; + r = 0; + } + else + { + qs->d_type = 0; + qs->d_datalen = 0; + r = 1; + } + close(fd); + return r; + } + else + { + fprintf(stderr, "Fails %d\n", fd); + return r; + } +} + +#endif /* ?QDOS */ + +#ifdef USE_EF_UT_TIME + +#define EB_L_UT_SIZE (EB_HEADSIZE + eb_l_ut_len) +#define EB_C_UT_SIZE (EB_HEADSIZE + eb_c_ut_len) + +#ifdef UNIX +#define EB_L_UX2_SIZE (EB_HEADSIZE + EB_UX2_MINLEN) +#define EB_C_UX2_SIZE EB_HEADSIZE +#define EF_L_UT_UX2_SIZE (EB_L_UT_SIZE + EB_L_UX2_SIZE) +#define EF_C_UT_UX2_SIZE (EB_C_UT_SIZE + EB_C_UX2_SIZE) +#else +#define EF_L_UT_UX2_SIZE EB_L_UT_SIZE +#define EF_C_UT_UX2_SIZE EB_C_UT_SIZE +#endif + +local int GetExtraTime(struct zlist far *z, iztimes *z_utim, unsigned ut_flg) +{ + char *eb_l_ptr; + char *eb_c_ptr; + char *eb_pt; + extent eb_l_ut_len = 0; + extent eb_c_ut_len = 0; + +#ifdef UNIX + struct stat s; + + /* For the full sized UT local field including the UID/GID fields, we + * have to stat the file, again. */ + if (stat(z->name, &s)) + return ZE_OPEN; + /* update times in z_utim, stat() call might have changed atime... */ + z_utim->mtime = s.st_mtime; + z_utim->atime = s.st_atime; + z_utim->ctime = s.st_mtime; /* best guess (st_ctime != creation time) */ +#endif /* UNIX */ + +#ifdef IZ_CHECK_TZ + if (!zp_tz_is_valid) + ut_flg = 0; /* disable UT e.f creation if no valid TZ info */ +#endif + if (ut_flg != 0) { + if (ut_flg & EB_UT_FL_MTIME) + eb_l_ut_len = eb_c_ut_len = 1; + if (ut_flg & EB_UT_FL_ATIME) + eb_l_ut_len++; + if (ut_flg & EB_UT_FL_CTIME) + eb_l_ut_len++; + + eb_l_ut_len = EB_UT_LEN(eb_l_ut_len); + eb_c_ut_len = EB_UT_LEN(eb_c_ut_len); + } + + if (EF_L_UT_UX2_SIZE > EB_HEADSIZE) { + if(z->ext) + eb_l_ptr = realloc(z->extra, (z->ext + EF_L_UT_UX2_SIZE)); + else + eb_l_ptr = malloc(EF_L_UT_UX2_SIZE); + + if (eb_l_ptr == NULL) + return ZE_MEM; + + if(z->cext) + eb_c_ptr = realloc(z->cextra, (z->cext + EF_C_UT_UX2_SIZE)); + else + eb_c_ptr = malloc(EF_C_UT_UX2_SIZE); + + if (eb_c_ptr == NULL) + return ZE_MEM; + + z->extra = eb_l_ptr; + eb_l_ptr += z->ext; + z->ext += EF_L_UT_UX2_SIZE; + + if (ut_flg != 0) { + eb_l_ptr[0] = 'U'; + eb_l_ptr[1] = 'T'; + eb_l_ptr[2] = eb_l_ut_len; /* length of data part of e.f. */ + eb_l_ptr[3] = 0; + eb_l_ptr[4] = ut_flg; + eb_pt = eb_l_ptr + 5; + if (ut_flg & EB_UT_FL_MTIME) { + *eb_pt++ = (char)(z_utim->mtime); + *eb_pt++ = (char)(z_utim->mtime >> 8); + *eb_pt++ = (char)(z_utim->mtime >> 16); + *eb_pt++ = (char)(z_utim->mtime >> 24); + } + if (ut_flg & EB_UT_FL_ATIME) { + *eb_pt++ = (char)(z_utim->atime); + *eb_pt++ = (char)(z_utim->atime >> 8); + *eb_pt++ = (char)(z_utim->atime >> 16); + *eb_pt++ = (char)(z_utim->atime >> 24); + } + if (ut_flg & EB_UT_FL_CTIME) { + *eb_pt++ = (char)(z_utim->ctime); + *eb_pt++ = (char)(z_utim->ctime >> 8); + *eb_pt++ = (char)(z_utim->ctime >> 16); + *eb_pt++ = (char)(z_utim->ctime >> 24); + } + } +#ifdef UNIX + else { + eb_pt = eb_l_ptr; + } + *eb_pt++ = 'U'; + *eb_pt++ = 'x'; + *eb_pt++ = EB_UX2_MINLEN; /* length of data part of local e.f. */ + *eb_pt++ = 0; + *eb_pt++ = (char)(s.st_uid); + *eb_pt++ = (char)(s.st_uid >> 8); + *eb_pt++ = (char)(s.st_gid); + *eb_pt++ = (char)(s.st_gid >> 8); +#endif /* UNIX */ + + z->cextra = eb_c_ptr; + eb_c_ptr += z->cext; + z->cext += EF_C_UT_UX2_SIZE; + + if (ut_flg != 0) { + memcpy(eb_c_ptr, eb_l_ptr, EB_C_UT_SIZE); + eb_c_ptr[EB_LEN] = eb_c_ut_len; + } +#ifdef UNIX + memcpy(eb_c_ptr+EB_C_UT_SIZE, eb_l_ptr+EB_L_UT_SIZE, EB_C_UX2_SIZE); + eb_c_ptr[EB_LEN+EB_C_UT_SIZE] = 0; +#endif /* UNIX */ + } + + return ZE_OK; +} + +#endif /* USE_EF_UT_TIME */ + + +int set_extra_field (struct zlist *z, iztimes *z_utim ) +{ + int rv = 0; + int last_rv = 0; + char flag = 0; + + if ((qlflag & 3) != 1) + { + qdosextra *lq, *cq; + if ((lq = (qdosextra *) calloc(sizeof(qdosextra), 1)) == NULL) + return ZE_MEM; + if ((cq = (qdosextra *) calloc(sizeof(qdosextra), 1)) == NULL) + return ZE_MEM; + + rv = qlstat(z->name, &(lq->header), &flag); + + if (rv == 0 || (rv == 1 && (qlflag & 2))) + { + lq->shortid = rev_short((short) SHORTID); + lq->len.lo = (unsigned char)(EXTRALEN & 0xff); + lq->len.hi = (unsigned char)(EXTRALEN >> 8); + strcpy(lq->longid, LONGID); + + memcpy(cq, lq, sizeof(qdosextra)); + + z->ext = sizeof(qdosextra); + z->cext = sizeof(qdosextra); + z->extra = (void *) lq; + z->cextra = (void *) cq; + fprintf (stderr, " %c", + lq->header.d_datalen ? '*' : '#'); + } + else if (rv == -1) + { + fprintf(stderr, + "%s: warning: cannot stat %s, no file header added\n", + "zip", z->name); + } + if(flag) + { + fputs (" !", stderr); + } + } + last_rv = (rv == -1 ? ZE_OPEN : ZE_OK); + +#ifdef USE_EF_UT_TIME +# ifdef QDOS +# define IZ_UT_FLAGS EB_UT_FL_MTIME +# endif +# ifdef UNIX +# define IZ_UT_FLAGS (EB_UT_FL_MTIME | EB_UT_FL_ATIME) +# endif +# ifndef IZ_UT_FLAGS +# define IZ_UT_FLAGS EB_UT_FL_MTIME +# endif + + rv = GetExtraTime(z, z_utim, IZ_UT_FLAGS); + if (rv != ZE_OK) + last_rv = rv; +#endif /* USE_EF_UT_TIME */ + + return last_rv; +} diff --git a/qdos/qfileio.c b/qdos/qfileio.c new file mode 100644 index 0000000..07a6bd8 --- /dev/null +++ b/qdos/qfileio.c @@ -0,0 +1,235 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2004-May-22 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#include "zip.h" + +#ifndef UTIL /* the companion #endif is a bit of ways down ... */ + +#include <time.h> +#include <utime.h> + +#include <errno.h> + +#ifdef S_IWRITE +# undef S_IWRITE +#endif /* S_IWRITE */ +#define S_IWRITE S_IWUSR + + +extern char *label; +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + + +typedef time_t statime; +#define PAD 0 +#define PATH_END '/' + +/* Local functions */ + +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 */ + 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 (SSTAT(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(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; + } + 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; + + t = ql2Unix(x); + + dosflag = dosify; /* default for non-DOS and non-OS/2 */ + + /* Make changes, if any, to the copied name (leave original intact) */ + + if (!pathput) + t = last(t, PATH_END); + + /* Discard directory names with zip -rj */ + if (*t == '\0') + return t; + + /* 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, Unix2ql(n, NULL)); + 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. */ +{ + struct utimbuf u; /* argument for utime() const ?? */ + + /* Convert DOS time to time_t format in u */ + u.actime = u.modtime = dos2unixtime(d); + utime(f, &u); +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. 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; + } + + name = malloc(len+1); + if (!name) + return 0; /* ideally, would like to report alloc-failure warning/error */ + + 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) { + free(name); + error("fstat(stdin)"); + } + } else if (LSSTAT(name, &s) != 0) { + /* Accept about any file kind including directories + * (stored with trailing / with -r option) + */ + free(name); + return 0; + } + + if (a != NULL) { + *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE); + if ((s.st_mode & S_IFMT) == S_IFDIR) { + *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(&s.st_mtime); +} + + +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 */ + + +void version_local() +{ + puts ("Compiled with c68 v4.2x on " __DATE__); +} diff --git a/qdos/zipup.h b/qdos/zipup.h new file mode 100644 index 0000000..1de3f61 --- /dev/null +++ b/qdos/zipup.h @@ -0,0 +1,19 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#ifndef O_RDONLY +# define O_RDONLY 0 +#endif +#define fhow O_RDONLY +#define fbad (-1) +typedef int ftype; +#define zopen(n,p) open(n,p) +#define zread(f,b,n) read(f,b,n) +#define zclose(f) close(f) +#define zerr(f) (k == (extent)(-1L)) +#define zstdin 0 |