From: Sehong Na Date: Sat, 31 May 2014 04:21:47 +0000 (+0900) Subject: Initialize Tizen 2.3 X-Git-Tag: 2.3a_release X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Ftizen_2.3;p=toolchains%2Fzip.git Initialize Tizen 2.3 --- 8c954e6b466add4fef1fea08db1016da55cf146f diff --git a/BUGS b/BUGS new file mode 100644 index 0000000..21a9013 --- /dev/null +++ b/BUGS @@ -0,0 +1,6 @@ +- zip sometimes crashes on some versions of NetBSD (0.8, 0.9 and early + 0.9-current), FreeBSD (<= 1.1) and BSDI (< 1.1) . This is due to a + bug in stdio. + Upgrading the stdio package in /usr/src/lib/libc/stdio should + fix the problem. See *BSD mirrors in src/lib/libc/stdio + You must at least replace setvbuf.o in all the libc's with a newer version. diff --git a/Betas_Readme.txt b/Betas_Readme.txt new file mode 100644 index 0000000..26e965e --- /dev/null +++ b/Betas_Readme.txt @@ -0,0 +1,17 @@ +Betas are works in progress. When a beta has a seemingly stable set +of features, we may post a public beta so outside developers can see +where the code is going and make contributions or comment. + +A Release Candidate is a beta that we believe has the full feature +set that will be released. It's still being tested, and things can +still change, but we thought it close when we posted it. + +We take suggestions, bug fixes, and patches at any time, so send them in. + +We make no guarantees as to the state of betas so use at your own risk. +All code, including releases, are released under the Info-ZIP license. + +Enjoy! + +Ed Gordon +20 April 2008 diff --git a/CHANGES b/CHANGES new file mode 100644 index 0000000..751695f --- /dev/null +++ b/CHANGES @@ -0,0 +1,3460 @@ +------------------------- August 7th 1996 version 2.2a ------------------ + 1. QDOS port (Jonathan Hudson) + 2. win32 volumelabel handling (Paul) + 3. VM/CMS clean up (Greg Hartwig) + 4. leading "../" in internal filenames are allowed (Paul) + 5. System V packages support (John Bush) + 6. Fix handling of atx in zipup() (Onno, Greg) + 7. Fixed typo that caused zip -R to dump core (Onno) + 8. msdos/makefile.dj2: fix for command line too long when linking zip.exe + 9. win95 long filename support with djgpp v2 (Onno, Kimio Itoh) +------------------------- August 9th 1996 version 2.2b ------------------ + 1. windll: use wiz instead of wizip (Mike) + 2. use z->name NOT z->zname to open files (Onno, Mike) +------------------------ September 1st 1996 version 2.2c ------------------ + 1. windll: use fprintf instead of putc to send data to std{out,err} (Mike) + 2. os2: make borlandc version detection equal to unzip 5.30d (Kai Uwe) + 3. use #elif constructions for msdos,os2 and win32 compiler detection (Onno) + 4. fix for incorrect free in zip.c (Onno, Mike, Steve) + 5. BeBox port from Chris + 6. unix/{configure,Makefile} fixes for SCO Xenix 286 (Tom Schmidt) + 7. remove zilog entry from unix/Makefile (Onno) + 8. man page fixes (Tom Schmidt) + 9. SCO ODT {3,5} fixes (Bill Davidsen) +------------------------ October 8th 1996 version 2.2d ------------------ + 1. Fix bug in QDOS patch that broke zipsplit.c (Onno, Paul) + 2. Fix a couple of warnings from BorlandC (Mike) + 3. msdos/makefile.wat: Delete some more files when cleaning up (Paul) + 4. store msdos volumelabels without a dot in them (Paul) + 5. clean up of unix/{Makefile,configure,packaging} (Tom Schmidt) + 6. make QDOS port case independent (Jonathan Hudson) + 7. new amiga SASC makefile (Walter Haidinger) + 8. don't truncate filenames in win32's in2ex() (Paul) + 9. os2/makefile.os2 update for emx 0.9c (Kai Uwe) +10. password() function for QDOS (Jonathan) +11. fix the last(?) free() related bug (Mike) +12. win32: security descriptors operations (Scott Field) +13. win32: FILE_SHARE_DELETE is not defined in some win32 compilers (Onno) +14. win32: fix makefile.wat to include nt.c (Onno) +------------------------ January 17th 1997 version 2.2e ------------------ + 1. define USE_CASE_MAP in osdep.h for those ports that need it (Onno) + 2. define PROCNAME in osdep.h for those ports that need it (Onno) + 3. wild() prototype decl only if PROCNAME defined => delete MSVMS define (Onno) + 4. add DOS EMX makefile (E-Yen Tan) + 5. include a little earlier in qdos/qdos.c (Jonathan) + 6. add ttyio.o to OBJZ in qdos/Makefile.qdos (Jonathan) + 7. remove unused fprintebc define from zip.c (Onno) + 8. use the right password routine in ttyio.c for unzip (Mike) + 9. BeOS update from Chris +10. Fix for 'zip -r foo x:' (Paul) +11. Fix library bug on beos (Chris) +12. Fix calculating version number (kitoh_@mix.or.jp, Walter Haidinger) +13. IsWinNT always returned TRUE (Mike) +14. Windll update from Mike +15. Improved crc routines for x86 from Scott Field +16. Detect in unix/configure if we can use crc_i386.S (Onno) +17. Fix spurious internal logic error (Paul) +18. Fix to include directory names on the Acorn when needed (Sergio) +19. include zip.h in mvs.h (Onno, George Carr) +20. add workaround for AZTEC C compiler bug to revision.h (Paul, Walter) +21. MVS doesn't have rmdir (George Carr) +22. define and use USE_ZIPMAIN for WINDLL en VM_CMS (Onno) +23. Fixes from Greg Hartwig to make CMS standalone versions possible. +24. Move OS specific encryption stuff to the os specific directories (Christian) +25. Change password fetching interface in ttyio and crypt (Christian) +26. Update emx support for 0.9c (Christian) +27. Define WINDLL instead of MSWIN (Christian) +28. Extended time stamp extra field format support (Christian) +29. Support for rsxnt-emx 0.9c win32 compiler (Christian) +30. Use izshr017b (Christian) +------------------------ March 11th 1997 version 2.2f ------------------ + 1. Move makefile.emx, rsxwinnt.h and zip.def to win32 subdir (Kai Uwe) + 2. Add win32 target to makefile.os2 to allow cross compilation (Kai Uwe) + 3. Fix NTSD_EAS link time failures with win32 (Paul) + 4. Fix buffer freed too early in password verification code (Mike) + 5. Remove unix/zipgrep and man/zipgrep.1 (sanvila@ctv.es) + 6. Only use crc_i386.o when we're using an x86 (Onno, Mark) + 7. Remove carriage returns from amiga/crc_68.a (Paul) + 8. New windll from Mike + 9. Fix typo in os2/os2zip.c (Kai Uwe) +10. Don't use ctime (last file status change) for unix and qdos cross compile + (Greg) +11. added gccwin32 crosscompilation target (RSXNT) to os2/makefile.os2 (Kai Uwe) +12. fixed the OS/2 file attribute and time stamp generation for zipping + stdin ("-") (Kai Uwe) +13. fixed the atime and ctime stat fields for the OS/2 Watcom C library + (Kai Uwe) +14. added atime and ctime support for the UT extra field when generated under + OS/2, the atime and ctime values are only stored when zipping (Kai Uwe) +15. qdos patches from Jonathan Hudson mainly for extended time flag handling +16. amiga aztec compiler bug workaround (Paul) +17. fix -v output of zipcloak, zipnote and zipsplit (Paul) +18. new amiga/makefile.azt with targets for debug versions (Paul) +------------------------ March 31st 1997 version 2.2g ------------------ + 1. remove -I/usr/local/include from unix/Makefile (Chris) + 2. Update versinfolines in revision.h (Greg) + 3. change 1U to 0x1 to accomodate non ANSI compilers (Onno, Rodney Brown) + 4. win32zip.c: cast buffer parameter in memcompress() to char * (Mike) + 5. remove beos/zipgrep (Chris) + 6. correct the -e password verification check in zip.c (Christian) + 7. use ZCONST instead of const in the generic code. (Christian) + 8. fix mktime timezone correction when time is near to daylight/nodaylight + switch points. (Christian) + 9. correct dependencies in makefile.os2 (Christian) +10. use a more sensible default for iztime.ctime than "0" when system does not + not support creation time stamps. (Christian) +11. fix VMS_PK_EXTRA function interface declarations. (Christian) +12. implement atime/ctime support in win32. (Christian) +13. win32/win32.c: replacement getch() for Watcom. (Paul) +14. win32/makefile.wat: debug object files kept separate. (Paul) +15. msdos/makefile.wat: debug object files kept separate. (Paul) +16. Fix extended time defines for the acorn. (Sergio) +17. Define PROCNAME() in acorn/osdep.h (Sergio) +18. Ignore exit status of ${INSTALL_D} in unix/Makefile (Chris) +19. Add Metroworks and BEOS info to version() in several files (Chris) +20. Move defines for the password fetch to zip.h (Christian) +21. Support the obsolete version rsxnt 1.1 / emx 0.9b (Christian) +22. Remove obsolete "#define PROCNAME ..." from cmsmvs/cmsmvs.h (Christian) +23. Fix extended time defines for qdos (Jonathan Hudson) +24. Use watcom getch() from unz530q in win32/win32.c (Onno) +25. Don't install zipgrep via the unix package tools (John Bush) +26. use izshr021 (Onno) +27. Fix zipnote: use iname not zname in zipnote.c (Onno) +28. Create proginfo directory (Christian) +------------------------ May 5th 1997 version 2.2h -------------------- + 1. Fix vms/zipup.h: iztime --> iztimes (Onno, Mike Freeman) + 2. Remove windll/wizdll.def (Mike) + 3. Add a couple of external variable declaration to windll.h (Mike) + 4. Remove zipgrep from install in unix/Makefile (Onno) + 5. Make updating .zip files with extended time fields possible (Kai Uwe) + 6. Delete beos/Makefile.gcc, beos/Makefiles handles both compilers (Chris) + 7. Fixes for unused variables (Chris) + 8. Added very simplistic example how to load and call the windll (Mike) + 9. Updated windll documentation to note this example (Mike) +10. Removed an unused memeber of a structure in windll (Mike) +11. Add BUGS instead of infozip.who and algorith.doc with the packaging + tools (John Bush) +12. tailor.h: increment NUM_HOSTS to keep in sync with UnZip (Christian) +13. win32/osdep.h: remove NO_SECURE_TESTS define (Christian) +14. zip.h: add declaration for free_crc_table() (Christian) +15. windll: move everything that's not windows specific into api.* (Mike) +16. use iname when checking for directory names in zipfile.c (Sergio) +17. improved mktime.c with better error checking (Christian) +18. improved crc routines (Christian, Rodney Brown) +19. get the -z option working again (Onno, Brad Clarke) +20. define BROKEN_FSEEK and seekable() for those systems where fseek() + always returns 0 (== OK) (Onno, Jeffrey Altman) +------------------------ May 10th 1997 version 2.2i -------------------- + 1. win32's seekable should only check for FILE_TYPE_DISK (Onno, Jeffrey Altman) + 2. add (ulg) cast to zipbeg = ~0 in zipfile.c (Steve) + 3. seekable() *really* belongs in flush_block, keep it there (Onno) + 4. seekable() calls fseekable(FILE *) (Onno) + 5. define HAVE_FSEEKABLE if a port has their own fseekable (Onno) + 6. WatCom doesn't have _get_osfhandle, use _os_handle instead (Paul) + 7. upgrade to Mike's latest windll sources (Mike) + 8. add -P option so you can specify a password on the commandline (Onno) + 9. Get -@ working again (Onno) +10. emx+RSXNT doesn't know about _get_osfhandle() (Kai Uwe) +11. fix a couple of typos in the OS/2 makefiles (Kai Uwe) +12. fix initialization bug in windll code (Mike) +13. tweak deletedir for RISC OS (Sergio) +14. RISCOS doesn't know about fstat() (Sergio) +15. Remove acorn/acorn (Sergio) +16. Delete debugging statements from version_local() in msdos.c (Greg) +17. Fix huge bug in readzipfile() (Onno) +------------------------ May 18th 1997 version 2.2j -------------------- + 1. Add missing ';' after return ZE_PARMS in zip.c (Mike) + 2. Remove obsolete 'struct stat st' in zipfile.c (Onno) + 3. Get Amiga SFX handling working again (Paul) + 4. Get zip -A working again (Onno) + 5. Change an && to & in zipfile.c (Johnny) + 6. Fix handling of empty sfx archives (Onno, Mike) + 7. Remove experimental entries from the makefiles (Jean-loup) + 8. Add exit codes to the manual page (Onno) + 9. Remove lines from the help screen that contain lesser used options (Onno) +------------------------ June 8th 1997 version 2.2k -------------------- + 1. use zip -t ddmmyyyy for year 2000 stuff (Greg) + 2. zip -@ only handles ONE filename per line (Jean-loup) + 3. beos support for DR9 filesystem and symlinks (Chris) + 4. VB support for windll (Mike) +------------------------ June 10th 1997 version 2.2l ------------------- + 1. beos filetype support (Chris) + 2. fill the buffer in getnam() to get it working again (Onno) + 3. implement -x@filename and -i@filename (Onno) +------------------------ June 22nd 1997 version 2.2m ------------------- + 1. Add a ; after de nextarg label in main() (Onno, Erik Baatz) + 2. Initialize p to NULL in get_filters() (Onno, Frank Donahoe) + 3. Fix typo in first if statement in filetypes() (Johnny Lee) + 4. zip -A works again (Onno, Greg) + 5. don't free zipbuf for VMS and CMS_MVS in main() (Onno, Mike Freeman) + 6. fix make_zip.com, link_zip.com and vmsdefs.h for gcc 2.6.3 on VMS (Onno) + 7. clarify -g option in the man page (Jean-loup) +------------------------ July 6th 1997 version 2.2n ------------------- + 1. use local in readzipfile2() declaration (Onno, Mike Freeman) + 2. return values with windll in get_filters() (Mike) + 3. a couple of minor patches for BEOS (Chris) + 4. zip -g works again (Onno, Chris) + 5. Some more Visual Basic dll support (Mike) + 6. Fix stack overflow in readzipfile() for DOS (Onno, Michael Mauch) +------------------------ August 19th 1997 version 2.2o ------------------- + 1. beos README and Makefile tweaks from Chris. + 2. Syntax corrections for README and man/zip.1 (Frank Donahoe) + 3. Use name not iname when deleting directories in trash() (Christian) + 4. change several wkuvx1 to lists in e-mail addresses (Christian) + 5. default to PK style extra fields for VMS (Christian) + 6. use izshr023 (Christian) + 7. replace buggy time library functions (Walter Haidinger, Paul, Christian) + 8. in2ex() and stat() are needed also when UTIL isn't defined (Greg Hartwig) + 9. don't use type=record in fopen() for MVS and CMS (Greg Hartwig) +10. Change P and K literals to hex for EBCDIC systems (Greg Hartwig) +11. Add output path support for CMS and MVS (Greg Hartwig) +12. Add memtoasc and memtoebc for EBCDIC systems (Greg Hartwig) +13. Handle comments correctly to fix zipnote for CMS and MVS (Greg Hartwig) +14. Add -tt option (do not operate on files after date mmddyy) (Christian) +15. move alloc routines for DOS into the !UTIL block (Christian) +16. move UTIL blocks and version_local() functions to a more logical place + (Christian) +17. Handle -P, -R, -x@, -i@ and -tt for the VMS CLI (Christian) +18. Update VMS help file with the new options (Christian) +19. Use iname in MATCH, not zname (Jonathan Hudson) +20. windll: more Visual Basic support (Mike) +21. windll: more project makefiles (Mike) +22. windll: insert Zip in front of global variable names (Mike) +------------------------ August 25th 1997 version 2.2p ------------------- + 1. Remove unused flags from LFLAGS2 in unix/Makefile (Onno) + 2. SunOS make bug: change unix_.o rule in unix/Makefile (Onno, Mike Freeman) + 3. ZipIsWinNT() instead of IsWinNT() in zip.h (Mike) + 4. Fix -t and -tt behaviour for windll (Mike) + 5. Remove windll makefiles that are now elsewhere (Mike) + 6. BEOS: preserve file attributes associated with symbolic links (Chris) + 7. No need to use in2ex() for ziputils (Christian) + 8. Fix comment handling for EBCDIC systems (Christian) + 9. EBCDIC conversion for entry names read from zipfile in UTIL mode (Christian) +10. Fix "fatal" error messages on EBCDIC systems (Christian) +11. zipnote.c: Fix handling of entry name changes for EBCDIC systems (Christian) +12. removed a large part of "dead" code from ziputils version (Christian) +13. use z->iname in comparison functions for sorting (Christian) +14. new installation utils for the acorn (Sergio) +15. use LSSTAT in set_extra_field for unix and beos (Onno) +16. perror(z->zname) instead of perror("zip warning") (Onno, Geoff Pennington) +17. Amiga SFX should work again (Paul) +18. refer to zip22 in install.doc (Frank Donahoe) +------------------------ September 10th 1997 version 2.2q ------------------- + 1. Change .doc to .txt, these aren't MS-Word documents (John D. Mitchell) + 2. Change msdos$_(OBJ) to msdos_$(OBJ) (Kai Uwe) + 3. Fix a couple of amiga related glitches (Paul) + 4. Support for DOS packed .exe files in makefile.dj2 (Frank Donahoe) + 5. Change warning message for zip -A (Greg) +------------------------ September 29th 1997 version 2.2r ------------------- + 1. Fix make svr4package (Eric Baatz) + 2. Fix VMS warning (Mike Freeman, Christian) + 3. Clean up beos gcc port and beos README (Chris) +-------------------------- October 6th 1997 version 2.2s -------------------- + 1. Change lpPrint to lpZipPrint for windll (Mike) + 2. Change lpPassword to lpZipPassword for windll (Mike) + 3. Amiga timezone fixes (Paul) + 4. WatCom C 11.0 makefile fixes (Paul) + 5. Tandem port from Dave Smith + 6. Corrections and updates for install.txt (Christian) + 7. Minor VMS README update (Christian) +-------------------------- October 12th 1997 version 2.2t -------------------- + 1. qdos compiler bug workaround (Jonathan) + 2. prevent storing qdos specific filenames that exceed filesystem limits + (Jonathan) + 3. fix undelimited comment in fileio.c (Frank Donahoe) + 4. disable storing of symlinks in BEOS until OS support is available (Chris) + 5. Init hash_head to 0 in amiga/deflate.a (Paul) + 6. Upgrade to izshr025 (Christian) + 7. don't add ".zip" to ZIP name for TANDEM (Dave Smith) + 8. use zipup.h not tandem.h in zipup.c (Dave Smith) + 9. rename history to CHANGES (Onno) +10. rename install.txt to INSTALL (Onno) +11. rename zip.txt to ZIPMAN (Onno) +12. create WHATSNEW (Onno) +-------------------------- October 15th 1997 version 2.2u -------------------- + 1. Use Info-ZIP instead of Info-Zip (Christian) + 2. Note recent filename changes in several files (Christian) + 3. Remove a couple of items from the TODO list (Christian, Onno) + 4. Add windll port, zip -t yyyymmdd and zip -R to WHATSNEW (Christian) + 5. VMS documentation cleanups and clarifications (Christian) + 6. dist entry in unix/Makefile (Onno) + 7. remove duplicate amiga/timezone.txt (Christian) + 8. rename ZIPMAN to MANUAL and update a couple of files regarding this (Onno) +-------------------------- October 24th 1997 version 2.2v -------------------- + 1. izshr026: in WHERE wiz40 instead of wiz30 (Christian) + 2. izshr026: another couple of Info-ZIP spelling fixes (Christian) + 3. Remove zipgrep from the makefiles that still had it (Christian) + 4. Update makefiles to handle the MANUAL renaming change (Christian) + 5. Fix the last daylight savings bug on the Amiga (Paul) + 6. Fix the SCO Unix specialty detection in unix/configure (Onno, + bug reported by Bo Kullmar for Solaris 2.6 and with uname -X output + for SCO Unix from ken@apisys.com and dgsmith@vnet.ibm.com) + 7. Update WHERE and amiga/time_lib.c from unzip 5.32g (Greg) +-------------------------- October 26th 1997 version 2.2w -------------------- + 1. Additional +Onolimit check in unix/configure (Onno, Peter Jones) + 2. Use ZIPERR macro instead of ziperr (Christian) + 3. initialize z->lflg for zip entries without extra field (Christian) + 4. "local (+ locextend)" vs. "central" header consistency check (Christian) + 5. Override local header values with central header values with -A + and differences between these headers (Christain) + 6. made "deltaoff" signed long; offset adjustment may be negative (Christian) + 7. fix a number of "wild" deallocation bugs (Christian) + 8. When zipping from a FAT drive (only 8.3 DOS names) under OS/2 or + WIN32, set z->vem to "OS_DOS | ". + Mark as "made by DOS PKZIP 2.0" only when dosify was requested. (Christian) + 9. DOS port should not store fake unix style external attributes. (Christian) +10. amiga/time_lib.c from izshr028 (Christian) +-------------------------- October 31st 1997 version 2.2y -------------------- + 1. amiga/time_lib.c from izshr029 (Christian) + 2. Turbo C++ version code clarification (E-Yen Tan) + 3. Fix spelling in cmsvms/zipname.conven (Rodney Brown) + 4. Fix memset check in unix/configure for Unixware 2.1.1 (Rodney Brown) + 5. Forward declaration fixes for HP-UX bundled compiler (Rodney Brown) +-------------------------- November 3rd 1997 version 2.2 -------------------- + 1. Update WHERE (Greg). +-------------------------- January 4th 1998 version 2.21a ------------------- + 1. BSD friendly version of version_local() in unix/unix.c (Onno) + 2. No NT versions in DOS version_local() (Steve Salisbury) + 3. -t mmddyyyy instead of -t ddmmyyyy in WHATSNEW (Walter Haidinger) + 4. use generic fseekable() for rsxnt (Christian) + 5. Fix MSC 8.x warnings (Christian, Steve Salisbury) + 6. win32 Borland C++ makefile (E-Yen Tan) + 7. Tandem doesn't know about extensions like .zip,.arj, ... (Dave Smith) + 8. Use dosmatch for EMX and DJGPP too (Christian) + 9. dummy djgpp startup functions to remove command line globbing and + recognition of environment variables from djgpp.env (Christian) +10. include DJGPP_MINOR in DOS version_local() (Christian) +11. TC 2.0 doesn't have mktime() (Christian, mmp@earthling.net) +12. VMS: rename opendir() to zopendir() so avoiding name clash with + VMS 7.x POSIX libraries (Christian, Martin Zinser) +13. Add support for VMS DEC C V 5.6 features (Christian) +14. Use iname for comparison in check_dup (Christian Spieler, Christian Michel) +15. Fix access to uninitialized ioctx records in vms_get_attributes() + Christian, Robert Nielsen) +16. Parenthesis around MAX_MATCH>>1 in match.S (Greg) +17. Use strchr() not strrchr() for -i and -x to get -i@ and -x@ really + working (Onno, Kai Uwe) +18. add chmod statements to unix/Makefile (Quentin Barnes) +19. Windll: handle both -r and -R (Mike) +20. Windll: general error handler in main() via setjmp/longjmp (Mike) +21. Don't allow zip -i@x.lst foo.zip (Onno) +22. vms/link_zip.com: use .eqs. not .nes. when checking with f$search + for the zip AXP object library (David Dachtera) +23. rsxnt 1.3.1 fixes (E-Yen Tan) +-------------------------- January 20th 1998 version 2.21b ------------------- + 1. Bigger PATH_MAX for win32's windll (Mike) + 2. Update windll.txt w.r.t. PATH_MAX (Mike) + 3. Amiga SAS/C fixes (Walter, Paul) + 4. zip -i@ and -x@ should *really* work now ...... (Onno) +-------------------------- February 20th 1998 version 2.21c ------------------- + 1. make -f unix/Makefile qnx needs LN=ln in its options (Chris) + 2. Support Metroworks Codewarrior/x86 on BEOS (Chris) + 3. Add Norbert Pueschel to proginfo/infozip.who (Walter) + 4. Use big endian for Be types (Chris) + 5. zip -i and -x were broken by the -i@ fix last time around (Christian) + 6. win32 stat bandaid (Paul) + 7. acorn filetype and timestamp fixes (Sergio, D. Krumbholz) + 8. update to izshr30 (Christian) + 9. Support for NTSD in the RSXNT environment (Christian) +10. restructure readzipfile() (Christian) +11. Where needed define MATCH in osdep.h (Christian) +12. version_local() fixes for RSXNT (Christian) +13. New vmsmunch.c (Christian) +-------------------------- March 15th 1998 version 2.3a ------------------- + 1. Fixes for the windll API (Mike) + 2. Use CPUTYPE in BorlandC Makefile for DOS (E-Yen Tan) + 3. BEOS: -rostr not available for the x86 compiler (Chris) + 4. preserve file attributes of a symlink on BEOS (Chris) + 5. New VM/CMS README.CMS and version_local() (Ian Gorman) + 6. INSTALL fixes from Takahiro Watanabe + 7. OS/390 port from Paul von Behren + 8. new api.h from Mike +-------------------------- April 19th 1998 version 2.3b ------------------- + 1. Improve Tandem file I/O performance (Dave Smith) + 2. New VM/CMS README.CMS and version_local() (Ian Gorman) + 3. cygwin32 port from Cosmin Truta + 4. Workaround for tasm32 5.0 bug in win32/crc_i386.asm (Cosmin Truta) + 5. win32/match32.asm fixes for tasm 5.0 (Cosmin Truta) + 6. simplify OS/390 port (Christian) + 7. win32 timezone handling fixes (Christian) + 8. fix 40-bit time conversion on the acorn (Sergio and Christian) + 9. strip network part from UNC type filenames (Christian) +10. Makefile for OpenMVS (Ian Gorman) +11. Use the Watcom getch() for cygwin32 (Christian) +12. Borland C++ 5.x added to win32's version_local() (Cosmin Truta) +13. Borland C++ needs tzset() in win32 (Christian, Cosmin Truta) +-------------------------- May 21st 1998 version 2.3c ------------------- + 1. Better error messages for -i and -x (Christian) + 2. Win32 stat() wrapper needs dos2unixtime (Christian,Paul,Mike) + 3. DJGPP: use _chmod to handle LFN attributes correctly (Michael Mauch) + 4. Fix Borlandc warnings (Mike) + 5. win32/makefile.bor fixes from Michael Mauch + 6. win32/makefile.{dj,emx} fixes from E-Yen Tan + 7. Use izshr031 (Christian) + 8. CMS: use RECFM=V LRECL=32760 by adding "byteseek" (Greg Hartwig) + 9. Check external name for trailing "/" (Greg Hartwig) +10. More specific info in CMS version_local() (Greg Hartwig) +11. Changed usage info to refer to "fm" rather than "path" on CMS (Greg Hartwig) +12. No more "extra data" messages when using the same OS (Greg Hartwig) +13. Rewritten README.CMS, one version for ZIP and UNZIP (Greg Hartwig) +14. DOS/OS2/WIN32/UNIX: ex2in() strips off "//host/share/" from UNC names (SPC) +-------------------------- June 23rd 1998 version 2.3d ------------------- + 1. Fixed Win32's stat() bandaid handling of time stamps (SPC) + 2. General fix of file selections for DELETE and FRESHEN action (SPC) + 3. CMS_MVS: Use ASCII coding for TIME extra field ID (SPC) + 4. EBCDIC: Repaired bogus CMS_MVS fix in zipup.c; check the internal + name for trailing (ASCII) '/' to detect directory entries (SPC) + 5. Use explicit ASCII coding when comparing or setting chars in iname (SPC) + 6. Fixed win32/makefile.bor, win32/makefile.dj (support NTSD), + win32/makefile.emx (SPC) + 7. Replaced win32/makefile.cyg by win32/makefile.gcc, containing new + support for mingw32 GCC environment (SPC) + 8. Use izshr032 (SPC) + 9. Modified zipup.c to hold (un)compressed lengths in "ulg" variables, in + an attempt to support handling of huge (>2GByte) files. (SPC) +10. Removed some duplicate #defines from api.h, they are now in crypt.h (SPC) +11. Reenabled "extra data size" info messages in noisy mode for all systems + except RISCOS and CMS_MVS (SPC) +12. For EMX 0.9c, the runtime lib contains a working mktime(), use it (SPC) +13. Miscellanous cosmetic changes (SPC) +14. Move win32/makefile.emx to msdos (E-Yen Tan) +15. make api.h work with zcrypt2.8 (Mike) +16. define ydays differently in api.h to avoid linking problems (Mike) +17. New windll.txt (Mike) +18. win32 lcc patches (E-Yen Tan) +19. win32 lcc makefile (E-Yen Tan) +20. Multiple inclusion bug: no malloc.h when using lcc-win32 (E-Yen Tan) +21. New VB support files for windll (Mike Le Voi, Raymond King) +22. MacOS port by Dirk Haase +-------------------------- August 1st 1998 version 2.3e ------------------- + 1. Generalized check for validy of TZ timezone setup info, similar to + UnZip; use it on AMIGA and MSDOS, as before. (SPC) + 2. Apply TZ validy check on OS/2 and enable creation of UT e.f. (SPC) + 3. BEOS: New Makefile, updates for README and Contents (Chris Herborth) + 4. beos/beos.c: declare some private functions as "local" (SPC) + 5. Include memcompress() code only for ports that make use of it, controlled + by preprocessor symbol ZP_NEED_MEMCOMPR (SPC) + 6. cmsmvs/README.CMS fix: Zip archive entries to be extracted into var-length + records CMS files should >>NOT<< contain binary data ... (SPC) + 7. crc32.c, crctab.c: the crc polynom table is ZCONST (SPC) + 8. trees.c: fixed a bug in the deflate algorithm that limited the compressed + size of an archive member to 512 MByte (SPC) + 9. deflate.c: Integrated the changes found in zlib that are neccessary to make + the deflate algorithm deterministic; modified msdos/match.asm to take + care of the "nice_match" global no longer being constant. (SPC) +10. deflate.c, trees.c, zipup.c: Reorganized and simplified deflate's + compressed output buffer handling. I/O and compression code are now + separated more cleanly. (SPC) +11. Killed bits.c by moving its contents into trees.c resp. zipup.c; + synchronized all Makefiles and Make procedures with this change. (SPC) +12. Integrated support for optionally replacement of deflate and crc32 by + public domain zlib code. (SPC) +13. Synchronize the different variants (UNIX/GNU C, OS/2, WIN32) of i386 + assembler replacement for deflate's longest_match() (SPC) +14. Moved the EMX+rsxnt Makefile.emx from msdos/ back into win32/ (SPC) +15. Restored a separate Makefile.emx for DOS; on DOS, some make programs may + have difficulties with recursive invokation (SPC) +16. Fixed the "include header mess" of the new MACOS port and removed the + "work-around hacks" caused by these bad MACOS .h-file includes (SPC) +17. Integrated Dirk Haase's beta4 (27-Jun-98) release of MacZIP (Dirk Haase) +18. Added support for MS Quick C in the MSDOS version_local() report (SPC) +19. Added WIN32 rsxnt targets linking against the emx crtl DLL to Makefile.emx + in os2/ and win32/ (SPC) +20. Fixed typo in os2/os2.c wild() function. (Kai Uwe Rommel) +21. Removed ChangeNameForFAT() from os2/os2.c in2ex() to fix problem with + long filename support. (Kai Uwe Rommel) +22. os2/os2zip.[ch]: correct type of DOS-style timestamp data is "ulg" (SPC) +23. vms/cmdline.c: Removed wrong ';' behind if condition (Johnny Lee) +24. VMS: Preliminary preparations in C code for supporting GNU C on OpenVMS + Alpha (Onno van der Linden, Christian Spieler) +25. VMS: Fixed check against adding zipfile to itself in fileio.c (SPC) +26. WIN32: Added lcc-Win32 variants of i386 assembler code for crc32() and + longest_match(). (SPC) +27. WIN32: Removed bogus type-cast in assignment to statb st_mode member (SPC) +28. zip.c: Fixed MACOS-related typo that broke "-@" command option (SPC) +29. zipup.c: Fixed messed-up expression for assignment to z->ver (SPC) +30. MACOS extra fields: check realloc return values (Onno, Johnny Lee) +31. Fix the PUTBYTE macro in trees.c: >= instead of < (Onno) +-------------------------- September 6th 1998 version 2.3f ------------------- + 1. Add zp_tz_is_valid to globals.c (Onno, Frank Donahoe) + 2. Updated tandem files from Dave Smith + 3. Windll: allow comments to zip archive with VB (Mike) + 4. Windll: add support for -b and update the documentation (Mike) + 5. win32: use wbS for FOPW to handle large zip files better (Steve Miller) + 6. MVS fix: use fseek();clearerr() instead of rewind() (Onno, Lee Burton) + 7. Updated VB examples for windll (Mike) + 8. Tandem: use UTC timestamps and GID/UID in extra field (Dave Smith) + 9. Tandem: handle -o option (Dave Smith) +10. default for ZCONST is const in tailor.h, override in osdep.h (Onno) +11. additional Macintosh options in zip.c (Dirk Haase) +12. additional Macintosh options in zip.1 and MANUAL (Onno, Dirk Haase) +13. Integrate Beta 5 of the Macintosh Port (Dirk Haase) +-------------------------- October 27th 1998 version 2.3g ------------------- + 1. zip_tz_is_valid should be zp_tz_is_valid (Kai Uwe) + 2. MVS native (not OE) beta fixes (Keith Owens) + 3. LynxOS support from Giuseppe Guerrini + 4. MVS already has stat() and fstat() so use 'em (Keith Owens) + 5. MVS fix in readzipfile() for new, unopened dataset without EOF marker + (Keith Owens) + 6. Remove 16-bit stuff from windll/windll.rc (Mike) + 7. Windll: Use hCurrentInst not hInst (Mike) + 8. In util.c compare strchr() return value with NULL (Onno, Frank Donahoe) + 9. unix/unix.c: initialize variable t in ex2in() (Onno, Frank Danahoe) +10. Remove windll/borland subdirectory (Mike) +11. Really fix extra field realloc() for BeOS and MacOS (Christian) +12. Fix the dj2 LFN related access violation bug (Christian, Joe Forster) +13. proginfo/3rdparty.bug: Added more info about other Zip clone's bugs. +14. The global copyright definitions in revision.h now depend on DEFCPYRT + (Christian). +15. tandem/macros: removed obsolete object file references (Christian) +16. fix memory leak with the "filter" patterns (Christian, Leah Kramer) +17. zip.c: completed the support for MacOS specific -N (Christian) +18. reorganized the Mac specific help screen code (Christian) +19. zipup.c: corrected the USE_ZLIB code to emit "stored" entries under + the same conditions as the "native deflate" code (Christian) +20. A couple of vars that will never be negative should be unsigned (Christian) +-------------------------- November 18th 1998 version 2.3h ------------------- + 1. DJGPP: When compressing from stdin don't set binary mode if stdin is + a terminal (E-Yen Tan) + 2. Fix signed/unsigned comparisons in fileio.c, util.c and zipcloak.c + (Frank Donahoe) + 3. Move macgetch() prototype from macos/source/macos.c to macos/osdep.h + (Christian) + 4. _doserrno should have type int, not unsigned int (Christian) + 5. In zipfile.c init a file pointer with NULL to fix gcc warning (Christian) + 6. Upgrade to MacOS beta 7 (Dirk Haase) + 7. Move the #pragma statements from generic sources to cmsmvs.h (Christian) + 8. Support for QNX/Neutrino 2.0 (Chris) + 9. Default to -r in help screen add -R at the bottom (Chris) +10. Clean up Makefile for BeOS R4 on x86 (Chris) +11. Beos: If not storing symlinks store attributes of symlink target (Chris) +12. Use izshr037 (Christian) +13. Remove ZIPERR() macro from in {msdos,win32}/osdep.h (Christian) +14. win32/win32.c: Fix 1-day offset in non-64bit FileTime2utime() (Christian) +15. win32: enable 64-bit FileTime2utime() for MS VC++ >= 5.0 (Christian) +16. cygwin32 only has _P_WAIT (Thomas Klausner) +17. msname() should *really* ignore illegal characters (Thomas Klausner) +18. Fix a missing ')' in Opendir() from win32zip.c (Thomas Klausner) +-------------------------- December 5th 1998 version 2.3i ------------------- + 1. Remove the #pragma statements that were forgotten the first time (Ian) + 2. Remove obsolete macos/source/CharMap.h (Steve Salisbury) + 3. isatty(fileno(zstdin)) in zipup.c should be isatty(zstdin) + (Onno, E-Yen Tan) + 4. several "shut up warnings from compiler" fixes (Christian) + 5. several cosmetic source changes (Christian) + 6. win32: make NTSD handling to be robust against alignment and structure + padding problems (Christian) + 7. Apply don't set binary mode when stdin is a terminal in zipup.c for + MSDOS and human68k (Christian) + 8. Upgrade to MacOS beta 8 (Dirk Haase) + 9. Add callback for WINDLL to handle user termination (Mike) +10. Fix typo in acornzip.c (Darren Salt) +11. acorn/sendbits.s: pass correct parameters to flush_outbuf() (Darren Salt) +12. Fixes for IBM C/C++ 3.6 where time_t is a double (Kai Uwe) +13. Fixes for IBM Visual Age C++ for win32 (Douglas Hendrix) +14. man/zip.1: some version numbers in the text were still "2.2" (Christian) +15. win32/makefile.emx: added a compilation variant that generates + standalone executables (Christian) +16. change __CYGWIN32__ into __CYGWIN__ and add compatiblity definition for + B19 and older (Cosmin Truta) +17. create uniform win32 getch() replacement (Christian) +18. put back in define of USE_EF_UT_TIME in tandem.h (Dave Smith) +19. put back in define of USE_CASE_MAP in tandem.h (Dave Smith) +20. updates to make/macros to allow the object to be licensed (Dave Smith) +21. updates to macros/doit to remove mktime.c (Dave Smith) +22. updates to tandem.c for in2ex/mapname/chmod amendments to match Unzip + (Dave Smith) +23. Use izshr039.zip (Christian) +24. Init filenotes to 0 for the amiga too (Onno) +25. get_filters(): remove one flag=0 statement to make -R work again (Onno) +-------------------------- December 17th 1998 version 2.3j ------------------ + 1. FOPWT defines opening a temp file for writing (Ian) + 2. Remove handling of bits.c from a couple of tandem files (Christian) + 3. A couple of "shut up warnings from compiler" fixes (Christian) + 4. win32/osdep.h: removed duplicate "IZ_PACKED" definition (Christian) + 5. win32/zipup.h: remove invalid "elseif" preprocessor token (Christian) + 6. sync MacOS help screen with other ports (Christian) + 7. get_filters(): set flag to 0 when -R isn't used (Christian) + 8. "local extra != central extra" now has "info" status (Christian) + 9. use windll directory as "home" directory for builds (Mike) +10. CMS/MVS: define FOPWT (Ian) +11. Upgrade to MacOS beta 9 (Dirk Haase) +-------------------------- January 17th 1999 version 2.3k ------------------ + 1. Change FOPW into FOPW_TMP (Christian) + 2. win32: #include uses paths relative to the parent directory (Christian) + 3. Use forward slashes as path separator in #include statements (Christian) + 4. windll: fix descriptions of f{In,Ex}cludeDate (Christian) + 5. win32/makefile.lcc: add some -I options to find files in the + right places (Christian) + 6. Supply default empty IZ_PACKED define (Christian) + 7. windll: Fix some typos, descriptions (Christian) + 8. windll project files: use relative paths, no specific root directory + (Christian) + 9. windll project files: remove link references to import libraries that + are not used by the zip library (Christian) +10. windll: fix potential infinite loop in a VB sample (Mike) +11. windll/windll.txt: remove "may not work with VB" statement (Mike) +12. Multibyte character set support from Yoshioka Tsuneo +13. Theos port from Jean-Michel Dubois +14. Tandem: added simple handling of Enscribe files by converting them into + text type files (Dave Smith) +15. Tandem Extra Field ("TA") containing Tandem File Attributes (Dave Smith) +16. Tandem history file showing background info to (UN)ZIP ports (Dave Smith) +17. create ZIP file on tandem with special file code (1001) (Dave Smith) +18. made tandem.c & tandem.h code completely the same as UNZIP (Dave Smith) +19. unix/configure: move +Onolimit and -Olimit into the machine specific + section (Onno, John Wiersba) +-------------------------- February 21st 1999 version 2.3l ------------------ + 1. Fix qdos Makefile (Jonathan Hudson) + 2. fgets instead of gets in zipnote to fix linker warnings (Jonathan Hudson) + 3. Theos: remove _setargv.c and a reference in zip.c (Jean-Michel Dubois) + 4. Theos README (Jean-Michel Dubois) + 5. interchanged the fRecurse flag values for "-R" and "-r" (Christian) + 6. add "z" pr prefix to MBCS functions to avoid name clashes (Christian) + 7. Whenever the position of the increment operator does not matter, the + INCSTR variant is used, which has been mapped to the {PRE|POS}INCSTR + variant that is more efficient. (Christian) + 8. fixed the "-R" handling in fileio.c, filter() function (Christian) + 9. simplified some THEOS specific code additions (Christian) +10. changed the line break of the compiler version message in version_local() + for MSDOS and Win32 to take into account some verbose compilers (Christian) +11. removed the THEOS changes from ttyio.c. Instead, a THEOS specific + setup was added to ttyio.h (Christian) +12. sync vms/link_zip.com with the corresponding make_zip.com (Christian) +13. added compatibility settings for support of MBCS on Win32 with all tested + compilers to win32/osdep.h +14. added type-casts to isalpha() macro calls (Christian) +15. fixed win32's wild_match which was clobbered by the MBCS addition + (Christian) +16. finished up the "potential infinite loop" problems in the VB sample + that Mike started to repair (Christian) +17. in ziperr.h, AZTEK C might require the false comma that was removed + to satisfy THEOS C (Christian) +18. removed the bogus THEOS specific isdir check in zipup.c (Christian) +19. modified the code for line ending translation to be independent + of the local system's convention for '\n' and '\r'; this allowed + the removal of the THEOS specialities (Christian) +20. Tandem: -B option to zip Enscribe files with no record delimiters + (Dave Smith) +21. Tandem: attempt to catch Large Transfer mode failure (Dave Smith) +22. Theos: Fixed keyboard entry functions. (Jean-Michel Dubois) +23. Theos: workaround for the argument wild card expansion that is bugged + in the standard library. Managed by MAINWA_BUG flag. (Jean-Michel Dubois) +24. Theos: support for filenames and notes with accented characters. + (Jean-Michel Dubois) +25. Upgrade to MacOS final (Dirk Haase) +-------------------------- March 31st 1999 version 2.3m ------------------- + 1. Theos: for relative paths to root directory cause open, fopen and stat + failure, workaround this. (Jean-Michel Dubois) + 2. Theos: when no path is indicated in a file or directory name and the + file or directory doesn't exist in the current directory it looks for + the file or directory in the root directory, workaround this. + (Jean-Michel Dubois) + 3. Corrected some typos and spelling error in macos/HISTORY.TXT; skipped + off invisible trailing whitespace (Christian) + 4. proginfo/extra.fld: added documentation for Tandem and Theos extra + field layout (Christian with Dave D Smith resp. Jean-Michel Dubois) + 5. qdos/Makefile.qdos: The build of ZipCloak requires inclusion of + the crctab object module; qfileio_.o compilation requires the -DUTIL + flag (Christian) + 6. win32: fix incorrect MB_CUR_MAX macro for mingw32 and lcc (Christian) + 7. theos/_fprintf.c, theos/_rename.c, theos/osdep.h: Some function + parameters require the "const" attribute to achieve compatibility + with ANSI C requirements (Christian) + 8. theos/theos.c: map Theos' (No)Hidden file attribute to MSDOS Hidden + bit in the MSDOS part of zipentry header's external attribute field; + 9. theos/stat.h: prevent multiple inclusions +10. Theos: Fixed wild card management for options other than adding + (Jean-Michel Dubois) +11. Theos: Removed modifications of const strings (Jean-Michel Dubois) +12. Split tandem.c up into separate zip/unzip parts (Dave Smith, Christian) +13. Move inclusion of OS specific zipup.h files to tailor.h (Onno) +-------------------------- August 14th 1999 version 2.3n ------------------- + 1. Move inclusion of OS specific zipup.h files back to zipup.c (Onno) + 2. Remove getline() from zipnote.c and use gets() again (Onno) + 3. BeOS PowerPC R4.1 support (Chris) + 4. New DOIT and MACROS files for the tandem port (Dave Smith) + 5. Don't switch the console to binary mode (Michel de Ruiter) + 6. In some circumstances undosm could be freed twice (Mike) + 7. Also define const in tailor.h for ultrix (Onno, Foppa Uberti Massimo) + 8. Tandem: Change zopen in TANZIPC to allow opening of files with missing + alt keys (err 4) (Dave Smith) + 9. Tandem: Assume not DST if can't resolve time (no DST table available) + (Dave Smith) +10. WIN32: skip trailing dots and spaces in getnam (Onno, Dan Kegel) +11. Use ZE_NONE when nothing to freshen or update (Onno, Yuri Sidorenko) +12. Remove tabs from files that don't need them (Onno) +13. Remove tabs and spaces from the end of a text line (Onno) +14. Upgrade macos to 1.04b2 (Dirk) +15. Add -Q documentation to manual page (Jonathan Hudson) +16. Copy hiperspace files instead of renaming them (Keith Owens) +17. Disallow some more characters to appear in DOS filenames when using -k + (Onno, Thomas Klausner) +18. Document missing options and environment variables in the manual (Onno) +19. New acorn/GMakefile to compile with gcc on RISCOS (Darren Salt) +20. ISO 8601 date format support for -t and -tt (Rodney Brown) +-------------------------- September 21st 1999 version 2.3o ------------------- + 1. Sync zip.h license with LICENSE (Onno) + 2. Add copyright notice to README, os2zip.c and os2.zip.h (Onno, Greg) + 3. Fix the ASM variable in acorn/GMakefile (Darren Salt) + 4. Add another requirement to acorn/ReadMe.GMakefile (Darren Salt) + 5. Fix unbalanced parenthesis in vms_get_attributes declaration in zip.h + and move it to vms/zipup.h (Onno, Mike Freeman) + 6. Make a couple of os2 files public domain (Kai Uwe) + 7. Change and rename disclaimer array in revision.h (Onno) + 8. Change copyright array in revision.h (Onno) + 9. macstuff.c copyright is the same as macstuff.h (Christian) +10. WHATSNEW: add ISO 8601 dates supported (Christian) +11. fileio.c - msname(): strip off leading dots, these are illegal for + MSDOS compatible names (Christian) +13. fileio.c - replace(): deactivate "dead" code for CMS_MVS (Christian) +14. man/zip.1: "-$" option is also used for WIN32 ports +15. msdos/msdos.c - version_local(): break the version line for + GNU compilers too (Christian) +16. tailor.h: added typecasts to MBCS macros, to suppress "type mismatch" + warnings (Christian) +17. util.c, zip.h, zipfile.c: ZCONSTify several pointers (Christian) +18. util.c - recmatch(), zip.c - version_info(): add compile time option + WILD_STOP_AT_DIR (Christian, Darren Salt) +19. util.c - envargs(): MBCS related fixes (Christian) +20. win32/lm32_lcc.asm: add TAB characters that are required by the lcc + assembler source parser (Christian) +21. zip.c: fix the "is a console" check (Christian) +22. zipnote.c: use getline() (Christian) +23. zipup.c: use zclose() in case of I/O errors (Christian) +24. zipup.c: use ZE_WRITE when a write error occurs (Christian) +25. win32/win32.c: HAVE_INT64 is used by mingw32 (Cosmin Truta) +26. update shared sources to match izshr041 (Christian) +-------------------------- November 29th 1999 version 2.3 ------------------ + 1. Missing parenthesis in win32/win32.c (Steve Salisbury) + 2. Add Cosmin Truta to proginfo/infozip.who (Onno) + 3. Remove one parenthesis pair too many from vms_get_attributes() declaration + in vms/zipup.h (Mike Freeman) + 4. qdos .s are expected to start with a #, work around it (Jonathan Hudson) + 5. tandem: -B0 should be deflating not storing (Dave Smith) + 6. human68k updates from Shimazaki Ryo + 7. beos Makefile cleanup (Chris) + 8. workaround for fseek to negativate offset behaviour of the RISC OS + SharedCLibrary (Darren Salt) + 9. set file type for RISC OS in zipcloak.c (Darren Salt) +10. change tandem zgetch() to allow crypt version to work (Dave Smith) +11. fix a comment typo in acorn/riscos.c (Christian) +12. fileio.c: two type-cast to shut up noisy compilers (Christian) +13. human68k: fix missing case_flag argmument (Christian) +14. win32/win32.c: remove HAVE_INT64 completely (Christian) +15. zip.c: raise "cannot zip to console" error when stdout IS a tty (Christian) +16. zip.h: don't use dummy argument names in declarations (Christian) +17. Add missing semicolon in fileio.c (Shimazaki Ryo) +18. win32.c: IBMC compiler >= 3.50 have int64 (Kai Uwe) +19. Handle initialization error return value from MVS stat() in procname() + (Keith Owens) +20. Use RISC OS instead of RiscOS in the manual (Darren Salt) +21. Use # instead of ? as single character wildcard on RISC OS (Darren Salt) +22. New windll example.c (Mike) +23. Correct storage of 8-bit char filenames with RSXNT (Burkhard Hirzinger) +24. fix install in unix/Makefile (Santiago Vila, Onno) +25. Fix zip -L output (Santiago Vila, Onno) +26. Ignore unix special files (Jonathan O'Brien) +27. Upgrade to izshr042 (Onno) +28. Make copyright notice the same as in izshr042 (Onno) +29. Make copyright notice in zip.h the same as LICENSE (Christian) +30. Set tempzf to NULL _after_ it has been closed (Chris Kacher) +31. Change email address for Jonathan Hudson (Jonathan Hudson) +32. Remove win32/winzip.c.orig (Steve Salisbury) +33. Use 'Steve Salisbury' throughout the documentation (Steve Salisbury) +34. Change email address for Steve Salisbury (Steve Salisbury) +35. Change email address for Chris Herborth (Chris Herborth) +36. Use zip23 in INSTALL (Roger Cornelius) +37. Use zcrypt28 in INSTALL (Onno) +38. New acorn/srcrename (Darren Salt) +39. amiga/makefile.azt: make clean should remove some more items (Paul) +40. Change email address for Cosmin Truta (Cosmin Truta) +-------------------------- February 11th 2001 version 2.4a ------------------ + 1. Identify newer Borland compilers (Brad Clarke) + 2. Detect Turbo C 2.01 which doesn't have mktime (Brian Lindholm) + 3. Fix the use of -@ together with -i -x (Christian) + 4. Update msdos/README.DOS to match reality (Christian) + 5. win32: use assembler crc32 code (Christian) + 6. windll: _CRTIMP is needed in several function declarations (Christian) + 7. back to zip 2.2 memcompress() behaviour (Kelly Anderson) + 8. new amiga time code based on nih public domain code (Paul Kienitz) + 9. Detect some more Borland C++ builder versions (Brad Clarke) +10. Fix OS/2's extended file attributes compression code (Christian, Kai Uwe) +11. Correct translation of EBCDIC passwords to ASCII (Christian) +12. Attempt at integrating novell patches from Roger Foss (Onno) +13. Use izshr043 (Christian) +-------------------------- July 3rd 2001 version 2.4b ------------------ + 1. Fix OS/2's ACL compression code (Christian, Kai Uwe) + 2. Rename netware subdir to novell (Christian) + 3. Remove -dNETWARE -dDOS from novell Makefile (Christian) + 4. Remove defined(NETWARE) from the sources (Christian) + 5. printf is a macro in glibc 2.2, fix version_local function + (Christian, Matthew Wilcox) +-------------------------- January 13th 2002 version 2.4c ------------------ + 1. Use klist_items when initilizating koff[] in tandem.c (Dave Smith) + 2. Only call NLMsignals() in zip.c when NLM is defined (Mike, Onno) + 3. include riscos.h instead of acorn/riscos.h in acorn/osdep.h (Andy Wingate) + 4. Use izshr044 (Christian) +-------------------------- January 13th 2002 version 2.4d ------------------ + 1. Don't use mmap for stored entries (Christian) + 2. BIG_MEM and MMAP cannot be defined at the same time (Christian) + 3. Allow redirection of version screen to file (Christian) + 4. Fix for OS/2 output redirection bug (Christian, Kai Uwe) + 5. Acorn script for creating self extracting zips (Darren Salt) + 6. Update amiga makefiles to support revised timezone routines (Christian) + 7. Correct memcompress calculation for allocation size (Christian) + 8. Fix FORCE_METHOD debug option for level 1 and 2 (Christian) + 9. Whitespace cleanup in man/zip.1 (Christian) +10. Define IZ_IMP to specify compiler declaration prefixes (Christian) +11. make win32 and msdos version_local() "stdio-macro-safe" (Christian) +12. move tandem's zip specific zipopen to tanzip.c (Christian) +13. first parm is void * in external scope of vms_get_attributes() (Christian) +14. use right novell subdirectory in zipup.c (Christian) +15. update copyright for files modified in 2002 (Onno) +-------------------------- January 19th 2002 version 2.4e ------------------ + 1. Add MacOS X to version_local() (Mark) + 2. unix/configure: Init LFLAGS1 to "", MacOS X doesn't like -s (Onno, Mark) + 3. rename errors array to ziperrors to avoid MacOS X library clash (Mark) + 4. Support for the upx executable packer in DOS makefiles (Christian) + 5. remove obsolete -m486 switch from dos djgpp makefile (Christian) + 6. When using DOS, force the use of msdos style external attributes when + updating zip entries created under another OS (Christian) + 7. os2/makefile.os2: fixed ASFLAGS for watcom16dos (Christian) + 8. Update copyright and ftp address in several files (Christian) + 9. The RISCOS port uses '.' as directory separator, not '/' (Christian) +10. win32/makefile.bor: more options to compile the asm CRC code (Christian) +11. win32: use registry to handle timezones with MS C rtl (Christian) +12. acorn: use recommended practice for calling the linker (Andy Wingate) +13. unix/configure: check if CPP works else use ${CC} -E (Onno, Mark) +14. update versioninfolines in revision.h to match reality (Onno) +-------------------------- February 10th 2002 version 2.4f ------------------ + 1. vms: Zip -V is now able to handle file sizes up to 4Gb (Christian) + 2. vms: Include target environment detection for MMS/MMK (Christian) + 3. Change dummy message from zipcloak (Christian) + 4. acorn: add riscos specific -/ option (Darren) + 5. Update acorn's WILD_STOP_AT_DIR feature (Christian) + 6. acorn: Fix buffer allocation for -/ option (Christian, Darren) + 7. acorn: fix make clean (Andy Wingate) + 8. acorn: use tabs for GMakefile to make GNU make happy (Andy Wingate) + 9. tandem: use nskopen not zipopen (Dave Smith) +10. tandem: allow passing of CRYPT define (Dave Smith) +11. use izshr045 (Christian) +-------------------------- April 1st 2002 version 2.4g ------------------ + 1. acorn: fix assembler and compiler options in makefile (Darren) + 2. use izshr046 (Christian) + 3. MVS: define isatty to 1 to fix screen output (Christian) + 4. tandem: encryption really works now (Dave Smith) + 5. win32: detect Borland C++ builder 6 (Brad Clarke) +-------------------------- April 30th 2003 version 2.4h ------------------ + 1. tandem: fix temporary file contention (Dave Smith) + 2. cmsmvs: generate better filenames with -j (Owen Leibman) + 3. tandem: fix temporary file leftovers (Dave Smith) + 4. solaris: enable large file I/O to break 2G barrier (Rick Moakley, Onno) + +Note: Zip 2.4 was never released. That code was the start of the Zip 3.0 +effort below. Some changes and fixes also made it to the Zip 2.3x releases. + +---------------------- January 21st 2004 version 3.0a ---------------------- +Initial work on Zip 3.0 by Ed Gordon and Rainer Nausedat + 1. Changed some comments to update copyrights (Ed) + 2. Changed text in command line messages from zip 2.4 to zip 3.0 (Ed) + 3. Changes to many files for Zip64 wrapped in ifdef ZIP64_SUPPORT (Rainer) + 4. Attempt to fix buggy Win32 buffered 64-bit calls (Ed) + 5. Add functions to zipfile.c for Little-Endian memory writes (Rainer) + 6. Add functions to zipfile.c for writing Zip64 extra fields (Rainer) + 7. Major changes to putlocal, putcentral, and putend (Rainer) + 8. Fixing -F and -FF for Zip64 postponed (Ed and Rainer) + 9. Command line code replaced. Global table sets options, long options now + supported. Permutes so order of arguments can vary (Ed) +10. Fix bug where not allowed to use -@ with stdout but was with stdin. + Now can read filenames from stdin using -@ and output to stdout and + no longer am allowed to use -@ if reading from stdin (Ed) +11. Replace stat() with zstat(), fstat() with zfstat() and struct + stat with z_stat in Zip64 blocks. Put 64-bit file calls in ifdef + LARGE_FILE_SUPPORT blocks. Can implement Zip64 without > 4 GB + file support but for now need large files for Zip64 support (Ed) +12. Move port-specific code to osdep.h and win32.c (port specific) and + tailor.h (generic) and remove temporary os_io.c. As OF() is + not defined until after osdep.h includes in tailor.h function + prototypes for zfseeko, zftello, and zstat after that in tailor.h (Ed) +13. Settings of ZIP64_SUPPORT and LARGE_FILE_SUPPORT automatic based on + port and version of compiler. Defining NO_ZIP64_SUPPORT or + NO_LARGE_FILE_SUPPORT overrides this (Ed) +14. Bugs compiling scanzipf_fix(...) in zipfile.c and the fix functions could + use rewrite (Rainer and Ed) +15. Add prototype for zfopen for mapping to 64-bit fopen on ports using + inodes but not implemented (Ed) +16. More work on extended local headers and encypted archives (Rainer) +17. Fix DLL files so now compiles (Ed) +18. File size in dll limited to 32-bit in structure. A new DLL api is needed + to return 64-bit file sizes. Current api fixed to return max 32-bit if + more than that (Ed) +19. Add local header Zip64 support and local extra field. Fixed cast + to ulg missed previously that forced zstat to return value mod 4 GB in + zipup.c which kept local header code from seeing actual file size (Ed) +20. Add new option --force-zip64 to force use of zip64 fields. Could + be temporary (Ed) +21. Fix for VB added to api.c that just store the passed strings internally. + Should update api to optionally return file sizes as 64-bit in call back + and to accept RootDir and other strings in same call that zips (Ed) +22. Readme updated to describe new features and mention updated mail group + web links (Ed) +23. Minor bugs in output format found and fixed. Now can add + files > 4 GB to archive and unzip using major unzippers (Ed) +24. If zip used as filter (zip - -) and sizes exceed limits of extended + local header (data descriptor) then set max 32-bit values there. Major + unzippers ignore and use central directory values which are correct. Can + create Zip64 data descriptor using --force-zip64 option but seems no need + for it (Ed) +25. A few bugs in how headers are handled prevented zipping large numbers + of files. Fixed (Rainer) +26. A bit of an attempt to fix -F and -FF. Seems to work but not that + robust. More work needed (Ed) +27. After some cast and other fixes zip compiles on Linux Red Hat 9 using Unix + generic. Added automatic detection of fseeko64 and if detected + sets LARGE_FILE_SUPPORT and setting that sets ZIP64_SUPPORT. Works but + could not test large files on the small system (Ed) +28. Tried to fix bug that prevents zipnotes from compiling when ZIP64_SUPPORT + is set. Still broke. This crashes the Unix Makefile but after + zip is compiled (Ed) +---------------------- May 8th 2004 version 3.0b ---------------------- + 1. Update license headers on more files (Ed) + 2. Change many ZIP64_SUPPORT ifdefs to LARGE_FILE_SUPPORT where appropriate. + Now can test ports using three stages, compile with NO_LARGE_FILE_SUPPORT + (which disables ZIP64_SUPPORT) to test base code, compile with + NO_ZIP64_SUPPORT to test the 64-bit file calls (assuming port sets + LARGE_FILE_SUPPORT) but otherwise use the base code, and without either + to test Zip64 if enabled on port (Ed) + 3. Fix zipnotes bug by moving a ZIP64_SUPPORT block in zipfile.c (Ed) + 4. Add Large File Summit (LFS) code to Unix port to enable 64-bit calls. + Update configure to include test for all needed 64-bit file calls before + enabling LARGE_FILE_SUPPORT for unix port (Ed) + 5. Merge encryption code from zcrypt29 (files from unzip) into zip and + enable by default (Ed) + 6. New man pages for zipnote, zipsplit, and zipcloak (Greg, Ed) + 7. Add encryption notice to crypt.c comments and to version information + in zip.c (Greg, Ed) + 8. Add Russian OEM EBCDIC support when OEM_RUSS defined in ebcdic.h but + Dmitri reports that 0x2F not '/' so make recommended change in cutpath + call in zipfile.c used by -D option (Dmitri - Nov 10 2003 email) + 9. ToDo30 file added to list what's left to do in this release (Ed) +10. Change fopen to zfopen for large file code and map to fopen64 for + Unix (Ed) +11. ftello64 seems broken in zipup.c on Linux (kernel 2.4), returning + negatives past the 2 GB barrier, though ftello64 works in a test program. + Likely error in defines. For now skip ftello64 check for Unix with + LARGE_FILE_SUPPORT. +12. A few updates in Readme. Needs overhaul likely. Also verified mxserver + is gone and replaced with list addresses (Ed) +13. First iterations at updating WinDLL for Zip64 (Mike) +14. Decide to drop backward dll compatibility in favor of a cleaner + dll interface. Decide to add string interfaces for VB (Ed, Mike) +15. Add string interfaces to dll interface to bypass array limitations + imposed by VB and add -x and -i to interface (Mike) +16. Create new VB example using new Zip64 dll interface (Ed) +17. Add O_LARGEFILE define for zopen in unix/zipup.h to enable reading + large files in unix (Ed) +18. Combine ZpSetOptions and ZpArchive dll calls to allow removing all VB kluges + in api.c to work around VB garbage collecting passed strings (Mike) +19. Change new VBz64 example to use updated interface. All works without + kluges (Ed) +---------------------- August 15th 2004 version 3.0c ---------------------- + 1. Add date formats in -t and -tt date errors (Ed) + 2. Add -so to display all available options (Ed) + 3. Many fixes from Dan Nelson to fix some large file support problems and + add large file support to a few ports. Main change is rather than use + explicit 64-bit calls like fopen64 now set 64-bit environment and use + standard calls. Also add a define for 64-bit printf format used to + print 64-bit stats (Dan, Ed) + 4. Changes to Unix config based on suggestions from Dan Nelson. Check + if off_t is at least 64 bit (Dan, Ed) + 5. Add -- to get_option. Any arguments after -- on command line now + read as paths and not options (Ed) + 6. Add extended help (Ed) + 7. Change add_filter flag parameter from char to int as some compilers have + problems with char arguments (Ed) + 8. Changed filter() to do R and i separately so i has precedence over R (Ed) + 9. Split variable t in zip.c into t (off_t) and tf (ulg) (Ed) +10. Add quotes to zipname in check_zipfile for MSDOS to allow spaces in + archive path given to unzip to test ( , Ed) +11. Move zip.h include before ctype.h include in trees.c and zipup.c as + when ctype.h is first and using 64-bit environment at least on unix port + found it defines off_t as 4 bytes in those files as off_t is defined as + 8 bytes in other files and this changes the size of the zlist structure + which is not good (Ed) +12. Add default 64-bit file environment to tailor.h if LARGE_FILE_SUPPORT + is set but no port 64-bit file defines are set up earlier in the file. + Should allow other ports to set LARGE_FILE_SUPPORT on the compiler + command line to test if the standard defines work (Ed) +13. Adjust binary detection in trees.c by changing 20% binary (4 out of 5 + ascii) that used >> 2 to 2% (64 out of 65) using >> 6 instead. + trees.c (Ed) +---------------------- November 12th 2004 version 3.0d ---------------------- + 1. Add global variable for EncryptionPassword in VBz64 example and + some other password callback cleanup (Ed) + 2. Add -W option to turn on WILD_STOP_AT_DIR where wildcards will not + include directory boundaries in matches (Ed) + 3. Add -nw option "no wild" to completely disable wildcards in MATCH + function. Allows a list of files to be read in without worrying about + wildcards or escapes (Ed) + 4. Add -s option split-size but not implemented (Ed) + 5. Add -sp option split-pause but not implemented (Ed) + 6. Add changes for WiZ including moving Win32 64-bit wrappers into + win32i64.c to avoid naming conflict between libraries in WiZ (Mike, Ed) + 7. Some large file fixes in crypt.c (Ed) + 8. Add new error code ZE_UNSUP for unsupported compiler options. Add + check of size of zoff_t in zip.c when LARGE_FILE_SUPPORT enabled (Ed) + 9. Changed ZE_UNSUP to ZE_COMPERR to avoid conflict with unzip (Ed) +10. On VMS (sufficiently recent, non-VAX), DECC$ARGV_PARSE_STYLE is set + automatically to preserve case of the command line if the user has + SET PROCESS /PARSE = EXTEND. This obviates quoting upper-case + options, like -V, when enabled. VMS.C (Steven Schweda (SMS)) +11. On VMS, building with macro VMS_PRESERVE_CASE defined preserves case + of names in archive, instead of forcing lower-case (the former and + current default behavior). VMSZIP.C (SMS) +12. On VMS, in some of the simplest cases, ODS5 extended file name + escape characters ("^") are removed from names in archive. + VMSZIP.C (SMS) +13. On VMS, fixed a problem in some cases with mixed-case directory + names, where too much of the directory hierarchy was included in the + path names in the archive. VMSZIP.C (SMS) +14. On VMS, minor changes for large file support (long -> zoff_t). + VMSZIP.C (SMS) +15. On VMS, changed some structure declarations to typedefs, and + rearranged to simplify #if's and reduce potential name conflicts. + VMS.H, VMS_IM.C, VMS_PK.C (SMS) +16. On VMS, reformed -V (/VMS) processing. Added -VV (/VMS=ALL). + Removed some sign bits to accomodate files bigger than 2GB. + CMDLINE.C, VMS_IM.C, VMS_PK.C, ZIP.C, ZIP_CLI.CLD, ZIP_CLI.HELP, + ZIPUP.H (SMS) +17. Update command line options to support -VV as distinct option (Ed) +18. More VMS changes (SMS) +19. Add zoff_t format function (SMS) +20. On VMS, when -b was not used, temporary archive files were always + created in the current default directory, rather than in the archive + file destination directory. VMS now uses its own tempname() + function. FILEIO.C, VMS.C (SMS) +21. Remove using FNMAX for path size in a few places including filetime.c + to avoid exceeding limit (based on fixes from Greg and others) (Ed) +22. Add port atheos (Ruslan Nickolaev, Ed) +23. Bug fix adds different extra fields for local and central in VMS (SMS) +24. Now short options also take optional values as next argument (Ed) +25. Change -dd to control -v dots (SMS, Ed) +26. On VMS, a new open callback function senses (where supported) the + process RMS_DEFAULT values for file extend quantity (deq), + multi-block count (mbc), and multi-buffer count (mbf), and sets the + FAB/RAB parameters accordingly. The default deq is now much larger + than before (16384, was none), and the default mbc is now 127 + (up from 64), speeding creation of a large archive file. Explicitly + set RMS_DEFAULT values override built-in defaults. OSDEP.H, VMS.C + (SMS) +27. VMS CLI definitions and CLI help have been updated, and may be + approximately correct. CMDLINE.C, ZIP_CLI.CLD, ZIP_CLI.HELP (SMS) +28. The man file zip.1 updated and Makefile updated to generate manual + pages for zipcloak.1, zipnote.1, and zipsplit.1 (Ed) +---------------------- July 23rd 2005 version 3.0e ---------------------- + 1. Debian patch 004 - apply 2.4i configure changes from Onno to remove + need for -fno-builtin in unix/configure (Onno, Ed) + 2. Debian patch 005 for bug 279867 - fix bug that could crash on large paths + and create security problem. Apply patch changes from Greg (Greg, Ed) + 3. SourceForge patch 1074363 - add win32i64.c to win32/makefile.w32 (Ed) + 4. Add check when not ZIP64_SUPPORT in scanzipf_reg() in zipfile.c if + Zip64 archive being read (Ed) + 5. Renamed fzofft() used to format zoff_t values to zip_fzofft() to remove + conflict when combined with UnZip in WiZ (Mike) + 6. Add check in scanzipf_reg() in zipfile.c if Zip64 archive being read (Ed) + 7. Fixes for amiga/makefile.azt to define directory for object files (Paul) + 8. Define prototypes for local functions optionerr, get_shortopt and + get_longopt in fileio.c. Define err argument of optionerr as ZCONST (Paul) + 9. Add help_extended and DisplayRunningStats prototypes, fix other prototypes + in zip.c (Paul) +10. Split int kk off of k for argument types (Paul) +11. Aztec #endif quirk fix in zip.c for Amiga (Paul) +12. Add detection of binary in first buffer read from file in zipup.c to avoid + a -l or -ll translation on binary file. Not perfect but at least should + catch some binary files (Ed) +13. Remove check for >= 128 from binary check in zipup.c as <= 6 enough for + signed char (SMS, Ed) +14. SF Bug 1074368 - check for empty zip file in readzipfile() in zipfile.c + (Christian d'Heureuse, Ed) +15. Add error exit to prevent archive corruption when updating a large-file + archive with a small-file program. Add ZE_ZIP64 error. + ziperr.h, zipfile.c (SMS) +16. Change percent() in zipup.c to do rounding better, handle cases near limits + while rounding, and allow negative percent returns (SMS, Ed) +17. Add function ffile_size() in zipfile.c but in #if 0 block until determine + if works on all ports under all conditions. Currently only used for size + check for Zip64 archive detection if compiled without ZIP64_SUPPORT and + this check may already be handled in scanzipf_reg() and should be added to + scanzipf_fix() when that is updated (SMS, Ed) +18. Change >>1 to /2 in zipsplit.c to allow for negative percent returns (SMS) +19. Add type uzoff_t for unsigned zoff_t things. Should clean up some casting + (Ed) +20. Based on discussions with other development groups, when data descriptors + (extended local headers) are used, force to Zip64. This is compatible + with other unzips and does not require a change of the AppNote, but the + resulting archive requires Zip64 to read. Using standard data descriptors + would mean that the zip operation would fail if a Zip64 entry was + encountered. See zipfile.c (Ed) +21. Add define SPLIT_SUPPORT to enable splits. The command line options are + done and the globals are set up but nothing more. globals.c, zip.h, and + zip.c mainly (Ed) +22. Create spanning signature at beginning of archive when splitting enabled. + If reading a split archive skip the spanning signature unless creating a + split archive. zip.c, globals.c (Ed) +23. Start implementing split archives. Define two methods. split_method = 1 + updates local headers and is the most compatible but requires updating + previous splits. split_method = 2 uses data descriptors and should work + for streams and removable media but may not be as compatible with other + zip applications. (In part based on previous discussions with Rainer.) + Updated global variables to include bytes written to just the current + entry in the current split. zipfile.c (Ed) +24. Add note about output redirection to zip.1 (?, Ed) +25. Remove num < 0 check as num now unsigned. util.c (SMS, Ed) +26. Change lastchar to lastchr in fileio.c in places to avoid function by same + name (SMS, Ed) +27. Moved #endif /* !WINDLL */ in zip.c (Mike) +28. Account for vms directory version being ;1. vmszip.c (SMS) +29. Fix Zip64 check in scanzipf_reg to use the buffer. zipfile.c (Ed) +30. Default define size_t (for use by Steve's ffile_size() function). tailor.h (Ed) +31. Enable Steve's ffile_size() function and enable large file check. It + currently does not allow file sizes over 2 GB but the code is not supporting + it anyway without large file support. Should remove that part of the check + when the casts are fixed. zipfile.c (Ed) +32. Fixes for djgpp. Now compiles with djgpp 2 (Ed) +33. Add new VC6 projects for win32 and windll (Cosmin) +34. Convert some variables in zipsplit.c from ulg to zoff_t so compiles (Ed) +35. Add wildcards to extended help. zip.c (Ed) +36. For optional option value now '-' is same as missing value. fileio.c (Ed) +37. Remove extra free() from -dd option switch. zip.c (Ed) +38. Change write_unsigned_to_mem() to write_ulong_to_mem() and write_short_to_mem() + to write_ushort_to_mem(). zipfile.c (Ed) +39. Create new append to mem functions. zipfile.c (Ed) +40. Change zlist nam and ext from extent to ushort as that is what gets written. + zipfile.c (Ed) +41. Change GetSD to use ush instead of size_t. win32/win32zip.c (Ed) +42. Change PutLocal(), PutExtended(), PutCentral(), and PutEnd() to write to + memory and then write the block at once to the file. zipfile.c (Ed) +43. Change zcomlen from extent to ush, other extent conversions. zipfile.c, + globals.c, zip.h (Ed) +44. Add is_seekable() and global output_is_seekable. Do seekable check + when output file is opened. zipup.c, globals.c, zip.h, zip.c (Ed) +45. Do not increment files_so_far and bytes_so_far if file could not be read. + zip.c (Ed) +46. If force_zip64 set, only force compressed size in central directory to Zip64 + instead of all entries (csize, usize, off, disk) in Zip64 extra field. This + fixes inconsistent handling of disk numbers. zipfile.c (Ed) +47. Add end status if displaying running stats and not all files were read. + zip.c (Ed) +48. Change force_zip64 to zip64_archive in putend(). zipfile.c (Ed) +49. Enable the i686-optimized code by default. crc_i386.S, + win32/crc_i386.asm, win32/crc_i386.c (Cosmin) +50. Document and implement a new text detection scheme provided by Cosmin in + set_file_type(). Should be able to handle UTF-8 and some other character sets. + proginfo/txtvsbin.txt, trees.c (Cosmin, Johnny, Christian) +51. Update binary detection for -l and -ll to use Cosmin black list. zipup.c (Ed) +52. Change ZE_BIG to include read and write. ziperr.h (Ed) +53. If archive not seekable then use data descriptors. If ZIP64_SUPPORT always + create Zip64 data descriptors and add a Zip64 extra field to flag it is + a Zip64 data descriptor. This is klugy but should be compatible with other + unzips. See the note in zipfile.c for details. (Ed) +54. Use ush for comment length in putend(). Instead of extent use ush for + zcount and fcount same as in zip file. zip.h (Ed) +55. Update VB readme. windll/VB/readmeVB.txt (Ed) +56. Change (INSTALL) to (INSTALL_PROGRAM). unix/Makefile (, Ed) +57. During update the file and byte status counts were off. Fixed by not coun- + ting files copied from old to new as those are not in totals. zip.c (Ed) +58. Change from -b to -bx for nroff of manuals to text files. unix/Makefile (Ed) +59. Add cygwin to makefile. unix/Makefile (, Ed) +60. Fix bug where files to delete not added to list. zip.c (Ed) +61. Fix delete stats. zip.c (Ed) +62. Increment version of crypt to 2.10. Update default behavior notes. + crypt.c, crypt.h (Paul, Christian) +63. Format changes, add parentheses to zfseeko(), fix output bytes, add ifdef + blocks for ZIP10, fzofft formatting, casts. crypt.c (Christian) +64. Cast block_start to unsigned. deflate.c (Christian) +65. Let -R patterns match in subdirectories. Update filter() to use switch, + use global icount and Rcount, handle subdirectories, update icount and + RCount in filterlist_to_patterns(). fileio.c, zip.c, zip.h, globals.c + (Christian) +66. Enclose option -! and use_privileges under NTSD_EAS guard. globals.c, + zip.c, zip.h (Cosmin) +67. Updates to version, copyright, license. [I did not split the copyright + to 2 lines as it already takes up space on the help screen. Ed] + revision.h (Christian) +68. Add ZCONST to some read-only string pointer arguments in function + declarations. zipcloak.c, zipnote.c, zipsplit.c, zip.c, zip.h (Christian) +69. Fix byte counts on exit in zipcloak() and zipbare() to fix zipcloak bug + (Christian) +70. Modified zipnote.c to use WRBUFSIZ to handle line widths of at least 2047 + characters in write mode (Christian) +71. Change simple() and greedy() from zoff_t to uzoff_t. zipsplit.c (Christian) +72. Remove duplicate copyright notices. zipsplit.c (Christian) +73. Remove export notice from help page. Move notice to bottom of license + page. zipcloak.c (Ed) +74. File USexport.msg export history added. (Greg) +75. Added support for VMS ODS5 extended file names. (Eight-bit only, no + Unicode.) VMS name character "/" is mapped to Zip name character + "?". New command-line options -C[2|5][-] (/PRESERVE_CASE[=opts]) + control name case preservation and/or down-casing. globals.c, + zip.c, zip.h, vms/cmdline.c, vms/vms_im.c, vms/vms_pk.c, vms/vms.c, + vms/vmszip.c, vms/vms.h (SMS) +76. New VMS option -ww (/DOT_VERSION) stores version numbers as ".nnn" + instead of ";nnn" [changed from -Y to -ww (Ed)]. zip.c (SMS) +77. Changes to vms_open(). vms/vms_im.c, vms/vms_pk.c +78. Changes to vms_read(). vms/vms_pk.c (SMS) +79. Documentation updates. vms/vms_zip.rnh (SMS) +80. Minor updates. vms/zip_cli.help, vms/cmdline.c, vms/vms_zip.rnh (Ed) +81. Changes to vmsmunch(). vms/vmsmunch.c (SMS) +82. Do some updating of VMS options. vms/zip_cli.cld (SMS) +83. Moved the VMS-specific ziptyp() function from zipfile.c to vms/vms.c + to segregate better the RMS stuff. (SMS) +84. Put 64-bit calls in ZIP64_SUPPORT ifdef blocks, change some long parameters + for append to memory block functions to ulg, remove redundant includes, + add OFT protos to some functions with parameter types that get promoted + like ush to avoid warnings in VMS. zipfile.c (SMS) +85. Use zip_fzofft() to format number. zipsplit.c (SMS) +86. Add file_id.diz from Zip 2.31 (?, Ed) +87. Update install from Zip 2.31 (?, Ed) +88. Update license from Zip 2.31. License (?, Ed) +89. Update Readme.cr from Zip 2.31 (?, Ed) +90. Add 64-bit assembler for Win32 from Zip 2.31. win32/makefile.a64, + win32/readme.a64, win32/gvmat64.asm (?, Ed) +91. Update Readme (Ed) +92. Update headers. crctab.c, crc32.c, deflate.c, ebcdic.h, fileio.h (Ed) +93. Option for extra verbose VMS, change DIAG_FLAG from verbose to + (verbose >= 2). vms/vms.c (SMS) +94. Update copyright header. qdos/qdos.c (Christian, Ed) +95. Change exit(0) to exit(ZE_OK). qdos/qdos.c (Christian) +96. Change ulg to unsigned long. tailor.h (, Christian) +97. Default uzoff_t to unsigned long long if LARGE_FILE_SUPPORT manually + enabled for an otherwise unsupported port. tailor.h (Ed) +98. Update copyright header. tailor.h (Ed) +99. Change EXIT(0) to EXIT(ZE_LOGIC) for ziperr recursion. zip.c (Christian) +100. Change EXIT(0) to EXIT(ZE_OK) for successful returns. zip.c, + zipcloak.c (Christian) +101. Update license. zip.h (Christian) +102. Initialized mesg in zipcloak.c, zipnote.c, zipsplit.c to fix access + violation crashes. (Christian) +103. Added -q (Quiet mode) option to zipcloak, zipnote, zipsplit. (Christian) +104. Add proto of mb_clen(). fileio.c (Cosmin) +105. Synchronize ttyio.c and ttyio.h with the unzip-5.52 source. (Cosmin) +106. Control the POSIX emulation provided by some Unix-on-Windows compiler + distributions, such as Cygwin, via the FORCE_WIN32_OVER_UNIX macro. + tailor.h, win32/Makefile.gcc (Cosmin) +107. Remove getenv() declaration. util.c (Cosmin) +108. Fix definitions of zopen and zstdin. unix/zipup.h (Cosmin) +109. Enable binary file operations for DJGPP and Cygwin. unix/osdep.h (Cosmin) +110. Remove -DMSDOS from CFLAGS; use correct dependency in target crc_i386.obj. + win32/makefile.w32, win32/makenoas.w32 (Cosmin) +111. Update win32/makefile.bor and win32/makefile.gcc (Cosmin) +112. Put mktemp() declaration inside the NO_PROTO guard. tailor.h (Cosmin) +113. Use the right type (DWORD) for volSerNo, maxCompLen and fileSysFlags + in FSusesLocalTime(). win32/win32.c (Cosmin) +114. Set the "zip Debug" configuration as default. win32/vc6/zip.dsp (Cosmin) +115. Define ASM_CRC by default. win32/osdep.h (Cosmin) +116. Avoid using file names that are distinguished solely by letter case; + e.g. crc_i386.S and crc_i386.s. unix/Makefile (Cosmin) +117. Stylistic fix inside ex2in(). unix/unix.c (Cosmin) +118. Change zlist dsk from ush to ulg to support Zip64 and added casts in + zipfile.c to write ush. zip.h, zipfile.c (Christian, Ed) +119. Conditionally apply S_IFLNK to support DJGPP. unix/unix.c (Cosmin) +120. Change -dd [siz] (display dots, set optional dot size) to the options + -dd (turn dots on, use 10 MB default) and -ds siz (set dot size). + Found that using -dd with an optional value got confusing as detection + of an optional argument, when the next argument was not either an option + or the end of the line, was easy to overlook. Easier to avoid optional + values. zip.c (Ed) +121. Change text output of manual pages to zip.txt, zip.txt, zipcloak.txt, + zipnote.txt, zipsplit.txt. unix/Makefile (Christian, Ed) +122. Change comments using // to /* */ format. api.c, zip.c (Christian) +123. Add support for signals SIGABRT, SIGBREAK, SIGBUS, SIGILL, and SIGSEGV + to utilities. zipcloak.c, zipnote.c, zipsplit.c (Christian) +124. Update ToDo30.txt file (Ed) +125. Delete old Manual file (Ed) +126. Update WHERE from Zip 2.32 (Ed) +127. Change description of dot-size. zip.c (Ed) +128. Change VMS to use -ds to set dotsize. vms/cmdline.c (Ed) +129. Update manuals. man/zip.1, man/zipsplit.1, man/zipnote.1, + man/zipcloak.1 (Ed) +130. Detect i586, i686 and Cygwin in version_local(). unix/unix.c (Cosmin) +131. Add clean target. win32/makefile.w32, win32/makenoas.w32 (Cosmin) +132. Changed most 64-bit size/offset variable declarations (like zoff_t) + into "unsigned" type (like uzoff_t), for better backward compatibility + with non-ZIP64_SUPPORT setups where "ulg" was used for these variables. + deflate.c, fileio.c, globals.c, trees.c, vms/vms_pk.c, win32zip.c, + zip.c, zip.h, zipfile.c, zipup.c (Christian) +133. Add (ulg) cast to strstart in flush_block. deflate.c (Christian) +134. Updated Win32 LARGE_FILE_SUPPORT setup for Watcom and MinGW. + tailor.h, win32/osdep.h (Christian) +135. Add attempt count to tempname(). fileio.c (Christian) +136. Fixed size counter handling in debug code for Zip64. trees.c (Christian) +137. Moved cryptnote display text definition into revision.h, like was done + in Zip 2.31. zip.c, revision.h (Christian) +138. Add ZCONST. fileio.c (Christian) +139. Removed earlier change in trash() where ASCII-containing iname was + searched for native-coded '/' characters. [Added note but left as + changed 5/20/05 EG] zipfile.c (Christian) +140. Change zipup size error message to use zip_fzofft(). zipup.c (Christian) +141. Updated win32/makefile.wat to enable Zip64 support and use directory + for intermediate files. (Christian) +142. Change fcount and zcount from ulg to extent as extent is used internally, + but Zip64 standard supports up to ulg. Add note to zip.h. globals.c, + zip.h (Christian) +143. Define NO_W32TIMES_IZFIX in compile options when appropriate. Add + version information for USE_ZLIB compiler option. zip.c (Christian) +144. Add support for SIGABRT, SIGBREAK, SIGBUS, SIGILL, and SIGSEGV signals. + zip.c (Christian) +145. Add display-usize option to show uncompressed size. zip.c (Ed) +146. Add many descriptions to options table. zip.c (Ed) +147. Remove -R from help screen as on extended help screen. zip.c (Ed) +148. Add basics to extended help. zip.c (Ed) +149. Fix checks in scanzipf_reg() for empty file since cenbeg now unsigned. + Change buffer from t to b in small big check. Back up after small + zip big archive check. zipfile.c (Ed) +150. Change Zip64 not supported warning in scanzipf_reg(). zipfile.c (Ed) +151. Fix bug where local and central headers were not matching when compiled + with NO_LARGE_FILE_SUPPORT. Restored order of zlist structure elements + to match order of local header as scanzipf_reg() compares it as an + array of bytes to the local header. Gag. It needs fixing but at least + it works as intended now. zip.h, zipfile.c (Ed) +152. Minor fix from 10000 to 10 K for WriteNumString(). util.c (Ed) +153. Add overflow check to file_read(). zipup.c (SMS) +154. Add parameter p1 product specification. vms/collect_deps.com (SMS) +155. VMS changes. vms/descrip_mkdeps.mms (SMS) +156. Change zoff_t to uzoff_t and unsigned int to size_t. vms/vms_im.c, + vms/vms_pk.c (SMS) +157. Fix ; that was : at end of line. Fix DisplayNumString() prototype. + zip.h (Ed) +158. Get rid of leading blanks in DisplayNumString(). util.c (Ed) +159. Reset dot_count each file. zipup.c (Ed) +160. Minor changes to extended help. zip.c (Ed) +161. Move defines into DEFINED_ONCE block. api.h (Mike) +162. Add Still Remaining And Planned For Zip 3.0 section. WhatsNew (Ed) +163. Delete quotes around CHANGES. Readme (Ed) +164. Add -lf, open file at path and use for logging, -la, append to + existing logfile, and -li, include informational messages, options. + globals.c, zip.h, zip.c (Ed) +165. Update extended help to include logging. zip.c (Ed) +166. Add support for required short option value in form -o=value as optional + does. fileio.c (Ed) +167. If bytes_total is smaller than bytes_so_far for some reason then display + negative of bytes_to_go. This can happen if files grow in size after all + the sizes are initially added up. zip.c (Ed) +168. Use usize from filetime for adding to bytes_total when updating instead + of size in old entry. zip.c (Ed) +169. Change status counts files_so_far and bytes_so_far to include bad files + so the status counts end at the end but add bad_files_so_far and + bad_bytes_so_far to track bad files. After minor fixes it looks like + the counts remaining at the end are correct, even when some files are + not readable. Update bad file warnings. zip.c, zip.h, globals.c, + zipup.c (Ed) +170. Add uq for unsigned q in zipup(). Initialize z->len in case an error + later so have a valid size. zipup.c (Ed) +171. Check noisy in DisplayRunningStats() so logging is independent of it. + zip.c (Ed) +172. Add check in DOS for windows and if running DOS version on Windows warn + user. zip.c, msdos/msdos.c, msdos/osdep.h (Johnny) +173. Add errno.h for strerror(errno) call. zip.c, zipup.c (SMS) +174. Fix log problem if using -q option. zipup.c (Ed) +175. Change "Far char" to "char Far" as Far is a qualifier not for the char + type but the storage allocation of the array. fileio.c (Christian) +176. Update note on extent. globals.c (Christian, Ed) +177. Remove extra USE_ZLIB. zip.c (Christian) +178. Add note for the OEM_RUSS '/' bug. Need to look at later as it seems + the Russian bug remains unfixed. zipfile.c (Christian, Ed) +180. So byte counts always come out even, create good_bytes_so_far to + count bytes read in and convert bytes_so_far to use the counts + from the initial scan. If files change during the zip operation + good_bytes_so_far will change and not match bytes_so_far. + zip.h, globals.c, zip.c (Ed) +181. Changes to extended help. zip.c (Ed) +182. Update WhatsNew (Ed) +183. Update DLL resource copyright. windll.rc, windll.aps (Ed) +184. Add directory search improvements to Win32 (within recursion, reuse + attribs from directory lookup to avoid calling stat()). Add + getd_attribs(), procname_win32(). win32/win32zip.c (Johnny) +185. Cache result of IsFileSystemOldFAT() to avoid repetitive system calls + for identical information. win32/win32.c (Johnny) +186. Add optimization to dosmatch(): apply alternate shortcut code when the + pattern to match consists of one multichar wildcard ('*') followed + by a fixed string. util.c (Johnny) +187. Move DOS check_for_windows() checks to Help and Version and errors + only. Shorten message to one line. zip.c, msdos/msdos.c (Ed) +188. Define WIN32_OEM to enable oem ansi conversions for more than RSXNT. + Not yet fully implemented. win32/win32.c, win32zip.c, zip.c, + zipfile.c (Ed) +189. Directory search improvements for MSDOS. msdos/msdos.c (Johnny) +190. Add caching of directory information. If pattern is just *string no + need to recurse. win32/win32.c (Johnny) +191. If wild_stop_at_dir then do recurse to handle cases like a/b/*.txt. + win32/win32.c (Ed) +192. Additional improvements to directory search speedups, including + a) MSDOS port fixes for Turbo C++ compiler + b) In both Win32 and MSDOS, change getDirEntryAttr() into macro, + saving one function call overhead + e) Add explaining comment to optimized procname_{local} code + f) In util.c, move "*literal" pattern-matching optimization from + dosmatch() to recmatch(). Advantages: + - optimization used for all systems + - optimization applied to all occurences where a "*" is last wildcard + in pattern + - "dosmatch()" only preconditoning wrapper for matching workhorse + "recmatch()", it should not implement matching algorithms itself + - optimization not applied for WILD_STOP_AT_DIR option + g) >>>disabled<<< "*literal" optimization for all MBCS-aware environments, + because suspect that supplied optimization code is not MBCS-clean + (for details see the comment within the patch), so IS NOT USED for + win32 port! Can force activation of match optimization by specifying + conditional compilation symbol TEST_FOR_MBCS_CLEAN. + (Christian) +193. Add and move comments, implement changes for directory search improvements + in Zip 3.0 util.c (Ed) +194. In win32/win32.c, IsFileSystemOldFAT(), add declarations of static caching + variables where missing to fix win32 port compilation bug (Christian) +195. Correct changed arguments in RSXNT-only character set conversion + call. win32/win32zip.c (Christian) +196. Implement Directory Search improvements from Zip 2.32. win32/win32zip.c + (Johnny, Ed) +197. Debian Bug #312090 fix. Reworded man page to give multiple examples of + recursion, not just zip -r foo foo. man/zip.1 (Ed) +198. Change "-Aa -D_HPUX_SOURCE +e" to -Ae for HP. "HP-UX with the HP compiler + and on AIX 4.2.0. AIX 5.1 with gcc-3.4.3 (32-bit) and Darwin built fine + - though AIX 5.1 needed CC=gcc make -e ... to find gcc. According to the + HP-UX man page -Ae is equivalent to -Aa -D_HPUX_SOURCE +e it seems the + +e is needed and -Ae is more terse anyway." Expression generated before + was too long. unix/configure (Rodney Brown) +199. Add support for osf4.0f that does not have fseeko or ftello but has 64-bit + fseek and ftell though. tailor.h (Rodney) +200. Fix unsigned char to char in recmatch(), add casts for compares. util.c + (Ed) +201. Fix for alpha off_t long long. unix/osdep.h (Rodney) +202. Change shmatch() from uch to char and change parameters to recmatch(). + Change dosmatch(). util.c (SMS, Rodney, Ed) +203. Add local for DisplayRunningStats(). zip.c (Rodney, Ed) +204. Disable unused append_ubyte_to_mem(). Fix error messages in other append. + zipfile.c (Rodney, Ed) +205. Delete unused getDirEntryAttribs(). msdos/msdos.c (Christian) +206. Change warning when running msdos version on Windows. msdos/msdos.c (Ed) +207. Change recmatch() to support MBCS matching. util.c (Christian) +208. Update WhatsNew (Ed) +209. Update Readme (Ed) +210. Format Readme to fit in 80 character lines (SMS, Ed) +211. Rename install.vms to install_vms.txt. vms/install_vms.txt (SMS) +212. Add reference to vms/install_vms.txt in INSTALL (SMS) +213. Update INSTALL (Ed) +214. Remove ALT_NEXTBYTE and Building UnZip sections as no longer needed. + vms/notes.txt (SMS, Ed) +215. Add note to TODO (Ed) +216. Update Makefile message to suggest using generic. unix/Makefile (Ed) +217. Update text output of manual. zip.txt (Ed) +218. Update VMS section. INSTALL (SMS, Ed) +219. Minor changes in vms/install_vms.txt (SMS, Ed) +220. Update VMS install information. INSTALL, vms/install_vms.txt (SMS, Ed) +221. Do not use _stati64 under Cygwin. win32/osdep.h (Cosmin) +222. Add note to Makefile to use generic first. unix/Makefile (Ed) +223. Add Test option for VMS CLI. vms/cmdline.c (SMS, ?) +224. Add noconfirm to deletes, define symbol edit. vms/descrip.mms (SMS) +225. Changes to vms/install_vms.txt (SMS) +226. Add note on symbols to VMS. INSTALL (SMS) +227. Update license headers. vms/osdep.h, vms/vms.h, vms/vmsmunch.c, + vms/zipup.h, vms/vmszip.c, vms/vms.c, vms/vms_im.c, vms/vms_pk.c, + vms/command.c (Ed) +228. Add stsdef.h include for VMS and convert unzip test return to VMS + result for VMS. zip.c (SMS) +229. Add const to ziperr(). amiga/amiga.c (Paul) +230. Clean up makefile. amiga/makefile.azt (Paul) +231. Don't try Amiga large file support. amiga/osdep.h (Paul) +232. Add note on -V and -VV. vms/notes.txt (SMS) +233. Small update. vms/zip_cli.help (SMS) +234. Format Windows warning message. msdos/msdos.c (Christian) +235. Format changes. util.c (Christian) +236. Update VMS. INSTALL (SMS) +237. Add creation of intermediate object directories. msdos/makefile.wat + (Christian) +238. Add void * cast. msdos/msdos.c (Christian) +239. Add include for mktemp(). msdos/osdep.h (Christian) +240. Fix __RSXNT__ and WIN32_OEM define blocks. win32/win32.c (Christian) +241. Fix __RSXNT__ and WIN32_OEM define blocks. win32/win32zip.c (Christian) +242. Add != NULL to check. zip.c (Christian) +243. Fix WIN32_OEM. zipfile.c (Christian) +---------------------- October 11th 2005 version 3.0f01 ---------------------- +(the internal betas may be merged later) + 1. Add DSEG for Watcom data segment. msdos/makefile.wat (Christian) + 2. Add -zq and use assembler. os2/makefile.os2 (Christian) + 3. Update header. os2/match32.asm (Christian) + 4. Change len from int to unsigned int. os2/os2.c (Christian) + 5. In GetLongPathEA() limit tempbuf to CCHMAXPATH. os2/os2.c (Christian) + 6. Add DWATCOM_DSEG to use data segment. win32/makefile.wat (Christian) + 7. Update header and add DGROUP. win32/match32.asm (Christian) + 8. Add UNICODE_SUPPORT define. zip.h, zip.c (Ed) + 9. Add oname to f and z structs for the display name to use in messages. + Change z->zname to z->oname in messages. fileio.c, zip.c, win32zip.c, + zipup.c, zipfile.c, zip.h (Ed) +10. Move multi-byte defines to make global (they were needed with wide + characters but that was taken out and left them where they are). + fileio.c, zip.h +11. Add copy_args(), free_args(), and insert_arg() to create copy of argv + that can free() and to support inserting "@" in get_option for lists. + fileio.c, zip.h +12. Insert arg "@" after list if not followed by option. fileio.c +13. Add args variable and copy argv to args so can use insert_arg(). zip.c +14. Add MKS Korn Shell note. zip.c +15. Change cast of option in add_filter() calls from char to int. zip.c +16. Implement multi-byte version of Unicode support. To support Win32 NT + wide calls will require additional work not planned for this release. + Changes include (Ed): + - Add use_wide_to_mb_default flag. globals.c, zip.h + - Add compiler UNICODE_SUPPORT version information. zip.c + - Add uname to f and z structs for UTF-8 name. zip.c + - Moved some defines out of ZIP64 section. zipfile.c + - Add define UTF8_PATH_EF_TAG for Unicode Path extra field. Currently + the tag is 0x7075 which is 'u' 'p' for Unicode path and seems + free according to the AppNote. The extra field is + tag (2 bytes 'u' 'p') + size (2 bytes) + Unicode Path size (2 bytes) + unused (2 bytes set to 0) + unused (2 bytes set to 0) + Unicode path (variable) + The unused locations also serve as a check in case the tag is in + use already. + - Add add_Unicode_Path_local_extra_field() and + add_Unicode_Path_cen_extra_field() functions. zipfile.c + - Add read_Unicode_Path_entry() function. zipfile.c + - Set uname and oname in scanzipf_ref(). zipfile.c + - Add define wide_to_mb_default. Add zchar but not used. win32/osdep.h + - Add wide command line reading but don't use. win32/win32.c + - Add port functions for Unicode, including local_to_utf8_string(), + wide_to_escape_string() (for converting a wide character that can't be + converted to mb in the local character set to a reversable escape string), + escape_string_to_wide(), wide_to_local_string(), local_to_display_string() + (for creating the display version of name), utf8_to_local_string(), + local_to_wide_string(), wide_to_utf8_string() (NOT IMPLEMENTED), and + utf8_to_wide_string() (NOT IMPLEMENTED). win32/win32.c + - Implement attempt at escape function. Whenever a wide character can't + be mapped to the local character set, this function gets called. + Currently the wide character is converted to a string of hex digits. + If the wide can fit in 2 bytes then the form #1234 is used. If not, + the 4-byte form #L12345678 is used. + It compiles but needs the utf8 functions implemented. Also needs testing + in a multi-byte environment and only Windows is implemented so need to at + least do Unix. (Ed) +17. Update freeup() to include uname and oname. zip.c +18. Move define wide_to_mb_default so default for all is '_'. zip.h (Ed) +19. No changes needed to osdep.h and update unix/unix.c but not tested. (Ed) +---------------------- October 19th 2005 version 3.0f02 ---------------------- + 1. Remove null value check for split_size as get_option() already checks. + zip.c (Ed) + 2. Update f$search(). vms/descrip.mms (SMS) + 3. Save parse name before search and use that on failure. Change name parsing + in ziptyp() to solve a problem with search-list logical name device directory + specs. vms/vms.c (SMS) + 4. Compile in UNICODE_SUPPORT if have wchar_t and mbstowcs(). unix/configure (Ed) + 5. Move Unicode defines to zip.h and functions to fileio.c so generic. Create + a new OEM function for Windows. fileio.c, zip.h, tailor.h, win32/win32.c (Ed) + 6. Add UTF-8 functions. fileio.c (Paul) + 7. Convert Unicode functions to use zwchar defined as unsigned long for wide + char. fileio.c, zip.h (Ed) + 8. Add wchar_t check for Unix. unix/configure (Ed) + 9. Add default when zwchar (4 bytes) is too big for wchar_t (2 bytes). zip.h (Ed) +10. Allow for states for wide characters but surrogates not done. fileio.c (Ed) +11. Update WhatsNew (Ed) +---------------------- December 16th 2005 version 3.0f03 ---------------------- + 1. Fix broke encryption when ZIP64_SUPPORT enabled by accounting for need for + data description when encrypting. Data description is not required for + encryption (WinZip does not use one) but seems needed by Zip for some reason. + zipfile.c (Ed) + 2. Add function bfwrite() to do buffered fwrite(). Most output already is + written by zfwrite used by crypt.c which now calls bfwrite. All splitting + and new byte counts are done in bfwrite. fileio.c (Ed) + 3. Move some functions out of ZIP64_SUPPORT defines for use with UNICODE_SUPPORT. + zipfile.c, zip.h (Ed) + 4. Add is_ascii_string() and only create Unicode extra field if z->iname is + not ascii. zipfile.c, zip.h, fileio.c, (Ed) + 5. Add parameter rewrite to putlocal() to note when rewriting bytes so the bytes + rewritten are not counted in output totals. zipfile.c, zip.h (Ed) + 6. Handle VMS ... wildcard. util.c (SMS) + 7. Make tempzip file name global. zip.c, globals.c, zip.h (Ed) + 8. Add out_path global and -O path option to allow the output archive to have a + different name than the input archive, if there is one. This allows + updating a split archive, since output to the same split name would otherwise + be complicated and not user friendly. Use out_path for output. zip.h, + zip.c, globals.c (Ed) + 9. Many output functions that had output file y as parameter, such as zipup(), + zipcopy(), putlocal(), putcentral(), and putend(), now do not as y is + now global. This allows changing y as splits are created. zip.c (Ed) +10. Add function zipmessage() for writing messages like zipwarn() but are + informational. zip.c (Ed) +11. Minor changes to help. zip.c (Ed) +12. Add SPLIT_SUPPORT to version output. zip.c (Ed) +13. Add rename_split() to rename and set attributes for a split. zip.c (Ed) +14. Add set_filetype() to set attributes of split. zip.c (Ed) +15. Change variable a (holds attributes) to zipfile_attributes and make global. + zip.c, zip.h, globals.c (Ed) +16. Add key_needed flag for encryption and move setting key to after + command line processed. zip.c (SMS) +17. Initialize dot size using default only if dot_size not set. zip.c (Ed) +18. Change command line processing so that last -P or -e is used. zip.c + (Ed) +19. Fix broke writing of 4-byte spanning signature at the beginning of the archive + if splitting. zip.c (Ed) +20. Use bfcopy() instead of fcopy() to copy archive beginning. bfcopy() uses + global y. zip.c (Ed) +21. It looks like tempzf is no longer used. zip.c (Ed) +22. Account for SUNPRO_C and DECC_VER. Change SPARC to Sparc. unix/unix.c (SMS) +23. Remove GNUC. vms/cmdline.c (SMS) +24. Change case of system calls. vms/vms.c (SMS) +25. Add fix for VMS ... matching, but may change Zip to avoid ex2in() and in2ex() + for pattern matching in future. vms/vmszip.c (SMS) +26. Remove /NODIRNAMES and /DIRNAMES from VMS help. vms/zip_cli.help (SMS) +27. Define new globals zip64_eocd_disk, zip64_eocd_offset, current_local_tempname, + bytes_this_split, and bytes_this_entry for splits. globals.c, zip.h (Ed) +28. Add SUNPRO C and DEC C compile checks. unix/configure (SMS) +29. Add CFLAGS_NOOPT for removing optimization for configure. unix/Makefile (SMS) +30. Modify crypthead() to use bfwrite(). crypt.h, crypt.c (Ed) +31. Modify zfwrite() to use global output file. crypt.h, crypt.c (Ed) +32. Modify zfwrite() when no encryption to use bfwrite(). crypt.h (Ed) +33. Add bfcopy() to copy to y. fileio.c (Ed) +34. Add close_split() and bfwrite() for splits. fileio.c (Ed) +35. Add is_ascii_string() to check if UTF-8 extra field is needed. fileio.c (Ed) +36. Change Unicode escape of 2-byte wide from #1234 to #U1234. fileio.c (Ed) +37. Add read_Unicode_Path_entry() to read the UTF-8 path extra field. zipfile.c (Ed) +38. Latest Unicode Path extra field format is + 1 byte Version of Unicode Path Extra Field + 2 bytes Name Field Checksum + variable UTF-8 Version of Name +39. Use CRC-32 for Unicode Path Checksum and AND halves. zipfile.c (Paul) +40. Add Unicode Path Checksum check to make sure extra field applies to Name field + still. zipfile.c (Christian) +41. Move get_extra_field() out of Zip64 block and make available for splits. + zipfile.c (Ed) +42. Check in putlocal() using is_ascii_string() and don't create Unicode path + extra field if name is ASCII characters. zipfile.c (Ed) +43. If local header for split is on another disk and using split method 1, close + that split in putlocal() after rewrite local header. zipfile.c (Ed) +44. Fix data descriptor bug when encrypting where putextended() did not handle the + not Zip64 case, which mostly only happens now for encryption. zipfile.c (Ed) +45. Check for ASCII name using is_ascii_string() in putcentral() for Unicode path + extra field. zipfile.c (Ed) +46. Instead of single disk values, update putend() to use real split values for + current_disk, cd-start_disk, cd_entries_this_disk, cd_start_offset, + zip64_eocd_disk, zip64_eocd_offset, and current_disk and allow for + needing Zip64 if exceed standard max values for current_disk, cd_start_disk, + cd_entries_this_disk, total_cd_entries, and cd_start_offset. zipfile.c (Ed) +47. Use current_local_offset and current_local_disk for z->off and z->dsk in + zipup(). zipup.c (Ed) +48. Fix bug where force_zip64 was used to determine descriptor size but can have + Zip64 entry without force_zip64 so use zip64_entry. zipup.c (Ed) +49. Change the p - o != s compression size test for splits to bytes_this_entry + != (key ? s + 12 : s) and avoid ftell() in split. zipup.c (Ed) +50. If local header is on a previous split and split method 1 do the seek on that + split to update header. zipup.c (Ed) +51. For streaming, only force Zip64 if reading stdin and writing a non-seekable + device. In other cases can detect either the input file size and set Zip64 + if needed or seek in the output to update the local headers. zipup.c, + zipfile.c, zipup.c (Ed) +52. Allow creation of stored archives with descriptors for testing. Currently + they can't reliably be read but this is planned. zipup.c, zipfile.c, zip.c + (Ed) +53. Update help, adding in -e, -P, -s splitsize, -sp, and -sv options. zip.c (Ed) +54. Spelling fix in zipsplit man page. man/zipsplit.1, zipsplit.txt (Ed) +55. New option -sv and variable noisy_splits to enable verbose splitting. + Default is to quietly create splits, unless -sp set to pause between splits. + zip.h, zip.c, globals.c, fileio.c (Ed) +---------------------- December 23rd 2005 version 3.0f04 ---------------------- + 1. Move inlined text-vs-binary checks from file_read() into a separate, + new function named is_text_buf(). zipup.c, util.c, zip.h (Cosmin) + 2. Fix calls to putlocal to remove the removed dest parameter. crypt.c (Ed) + 3. Add get_split_path() to get the path for a split given the disk number. + fileio.c, zip.h (Ed) + 4. Change formatting of zipmessage() to remove tabbing and add formatting + to call to zipmessage(). fileio.c, zip.c (Ed) + 5. Initialize many variables such as y and tempzip. zip.c, fileio.c, + zipfile.c (Ed) + 6. Add loop to pause during split method 2 to allow changing disk or changing + the path for the next split. fileio.c (Ed) + 7. If after starting new split there is not enough room for the remaining buffer + for split method 1 display error and exit and for split method 2 we can + display a warning and user can replace disk or change path. fileio.c (Ed) + 8. Add list to store input file arguments using add_name() to add the name to + filelist_struc filelist and then process the names after the input archive + is read. zip.c (Ed) + 9. Fix infinite loop when opening a log file whose name contains multiple '/'. + zip.c (Cosmin) +10. Move split size message lower and only output if option sv sets + noisy splits. zip.c (Ed) +11. Set y to output file, remove output file from zipcopy(), putlocal(), + putcentral(), and putend(). zipsplit.c, zipnote.c, zipcloak.c (Ed) +12. Add code for not SPLIT_SUPPORT case. zipfile.c, zipup.c (Ed) +13. Prepend '-' to commands from target clean. + win32/makefile.w32, win32/makenoas.w32, win32/makefile.bor (Cosmin) +14. Must not call putenv() in iz_w32_prepareTZenv() under Cygwin. + win32/osdep.h (Cosmin) +15. Add browse info in Visual C++ 6 project. win32/vc6/zip*.dsp (Cosmin) +---------------------- December 27th 2005 version 3.0f05 ---------------------- + 1. Add proposed changes to License (Ed) + 2. Fix -l corruption bug by using memcpy() instead of wrongly changing the + buffer pointer. Fix was left out of last beta. zipup.c (Cosmin) + 3. Fix get_split_path() parameter. zip.h (SMS, Ed) + 4. Add -dg and display_globaldots to display dots globally for entire archive + instead of for each file. Is not affected by noisy flag. globals.c, + zip.h, zip.c, zipup.c, fileio.c (Ed) + 5. Make dot_count and dot_size uzoff_t, dot_count because with global dots + dot_count does not reset and with terabyte files the number of buffers + could exceed 2G, dot_size to allow use of ReadNumString() to read number. + zip.c, zip.h, globals.c (Ed) + 6. Add Deletion to help. zip.c (Ed) + 7. Fix delete date. zip.c (Ed) + 8. For streaming, need to assume Zip64 if writing a non-seekable device so + extra field for Zip64 is created if needed. zipup.c, zipfile.c, zipup.c (Ed) + 9. Add remove_local_extra_field() and remove_central_extra_field(). + zipfile.c (Ed) +10. Remove disabled copyright from license(). zip.c (Ed) +11. Clean up recent changes. zip.c, zipfile.c, fileio.c, zip.h, zipup.c (Ed) +12. Create scanzipf_regnew() for new file scan. zipfile.c (Ed) +---------------------- December 29th 2005 version 3.0f06 ---------------------- + 1. Change dot_size and dot_count from uzoff_t to zoff_t to allow use of + negative flag values. globals.c, zip.h (SMS, Ed) + 2. Remove file parameter to bfwrite() in putend(). zipfile.c (SMS, Ed) + 3. Add back code for not SPLIT_SUPPORT to putend(). zipfile.c (SMS, Ed) + 4. Change tag from ush to ulg in remove_local_extra_field() and + remove_central_extra_field() to avoid parameter problems. zipfile.c (Ed) + 5. Add allow_empty_archive to flag when want to create an empty archive. + globals.c, zip.h (Ed) + 6. Set allow_empty_archive when using -i and expecting an archive to be + created. This is in response to the 2/14/05 email. zip.c (Ed) + 7. Make before and after variables that hold the dates of files to + process or delete global so can use them in scanzipf_regnew(). zip.h, + zip.c, globals.c (Ed) + 8. Change scanzipf_regnew() to be based on scanzipf_fix() which seems closer. + Still have not coded the new regular zipfile reader. zipfile.c (Ed) + 9. For new reader first get add list and then read old archive and filter + as reading old entries. zip.c, zipfile.c (Ed) +10. Define USE_NEW_READ to turn on using new reader, which is being + created. This allows all to work while the new reader is being worked + on. zip.c, zipfile.c (Ed) +---------------------- January 9th 2006 version 3.0f07 ---------------------- + 1. Remove dest parameter from crypthead() and zipcopy(). crypt.c (SMS, Ed) + 2. Change -ds to handle dots for as small as every 32 KB. zip.c (Ed) + 3. Add ask_for_split_write_path() and ask_for_split_read_path() for + asking where to put the next write split and for locating the next + read split. zip.h, fileio.c (Ed) + 4. Add in_path to track where reading splits from. zip.h, globals.c, zip.c (Ed) + 5. Update copyright date on changed files to include 2006 (Ed) + 6. Replace stderr with mesg for most output messages. deflate.c, fileio.c, + trees.c, util.c, zip.c, zipcloak.c, zipfile.c, zipnote.c, zipsplit.c + 7. Add mesg_line_started to track if need new line on mesg output and update + zipmessage() and zipwarn() to use it. Set mesg_line_started to 1 when + newline not last character written to mesg and 0 when it is. deflate.c, + zip.h, zip.c, globals.c, zipup(), fileio.c (Ed) + 8. Include base_path as parameter for get_split_path(). fileio.c (Ed) + 9. Account for VMS version in split path. Add vms_file_version(). fileio.c, + zip.c, vms/vms.c, vms/vms.h (SMS) +10. Create crc16f() to create ANDed halves crc32 for Unicode using copy + of crc32() but may change to use main copy. zipfile.c, zip.h, + fileio.c (Ed) +11. Close in_path and out_path in finish() and ziperr(). zip.c (Ed) +12. Change perror() to strerror() and print to mesg in ziperr(). zip.c (Ed) +13. Add find_next_signature() to find the next signature when reading a + zip file. zipfile.c (Ed) +14. Add find_signature() to find a given signature from current point in + archive. zipfile.c (Ed) +15. Add at_signature() to check if at a given signature in archive. + zipfile.c (Ed) +16. Changes to scanzipf_regnew() but far from done. zipfile.c (Ed) +17. Changes to readzipfile() to close input archive file and allow new + zipfile reader to open and close files as goes through splits. + zipfile.c (Ed) +18. Change -s to default to MB and set minimum split size to 64k. + zip.c (Ed) +19. Add link to user32.lib for CharToOem(). makefile.w32, makenoas.w32 + (Cosmin) +20. Remove unused Z64_EFPos. globals.c (Ed) +---------------------- February 13th 2006 version 3.0f08 ---------------------- + 1. Move option checks before any work is done. zip.c (Ed) + 2. Update bfcopy() to handle reading splits and remove input file + parameter and use global in_file. fileio.c (Ed) + 3. Change ask_for_split_read_path() to allow user aborting. fileio.c (Ed) + 4. Change get_split_path() to use standard file extensions from most + recent AppNote of .z01, .z02, ..., .z99, .z100, .z101, ... fileio.c (Ed) + 5. Change is_ascii_string to use 0x7F for ASCII detection. fileio.c (Ed) + 6. Add copy_only global for when -O is used to change the format of an + archive without changing the contents. This allows for converting an + archive to a split archive for instance. The global copy_only is used + to output status information for copies when normally copied files + have no status messages. globals.c (Ed) + 7. Add in_file, split_path, total_disks, current_in_disk, and + current_in_offset as globals to track reading splits. zip.h, + globals.c (Ed) + 8. Update copyright date. revision.h (Ed) + 9. Close in_file if open in finish(). zip.c (Ed) +10. Add -O (big o) to extended help. zip.c (Ed) +11. Remove readzipfile() from zipstdout() and use main call later down. + zip.c (Ed) +12. Move archive reading and file scanning after command line checks. + zip.c (Ed) +13. If -O out_zip and so have_out is set then set copy_only and allow + copying instead of error message *Nothing to do*. zip.c (Ed) +14. If zipbeg is just 4 bytes and spanning then assume is spanning + signature and set zipbeg to 0 to ignore. zip.c (Ed) +15. Don't open initial write test as modify if have_out is set and so have + a separate output file. zip.c (Ed) +16. If zipbeg is 0 and nothing at beginning of archive to copy then don't + open input file until zipcopy() does. zip.c (Ed) +17. If stuff at beginning then copy and close input file. Should be able + to keep it open but easier to close it and let zipcopy() reopen it. + zip.c (Ed) +18. Add status message when copy_only set so something is displayed. + zip.c (Ed) +19. Instead of closing x at bottom close in_file. The variable x was used + inconsistently and it seemed easier to make in_file global instead. + Then again y remains the global output variable. zip.c (Ed) +20. Update copyright. zipnote.c, zipsplit.c, zipcloak.c (Ed) +21. Change adjust_zip_local_entry() to return 1 if the entry is Zip64 and + 0 if not. This is needed to know how large the extended local header + is later. zipfile.c (Ed) +22. Add read_Unicode_Path_local_entry() to read the local version of the + Unicode Path extra field. zipfile.c (Ed) +23. Handle disk in adjust_zip_central_entry(). zipfile.c (Ed) +24. Change USE_NEW_READ to SPLIT_SUPPORT as splits seems to be stable more + or less. zipfile.c (Ed) +25. Add is_signature() to compate signatures. zipfile.c (Ed) +26. Create scanzipf_fixnew(). It should look like scanzipf_regnew(). + zipfile.c (Ed) +27. Change scanzipf_regnew() to read the central directory and create zlist + and handle reading traditionally. Allows using central directory + information, in particular file sizes, in zipcopy() while reading + entries. Use global in_file instead of f for input file and set to NULL + when not a valid file so finish() only tries to close it if needed. + Check to make sure the End Of Central Directory record found is infact + the last one in case a stored archive is in the last 64 KB. Refuse + to update a split archive but recommend using -O instead. zipfile.c (Ed) +28. Change readable check in readzipfile() to require input archive to exist + if using -O out_archive. zipfile.c (Ed) +29. Change putlocal() to not create a Zip64 extra field unless needed and + on rewriting the local header to remove Zip64 extra field if was created + but not needed. Add check if assumed entry does not need Zip64 but does, + meaning probably the uncompressed size is less than 4 GB but the + compressed size is over 4 GB. zipfile.c (Ed) +30. Change zipcopy() to use the global in_file and y files and to open and + close read splits as needed. Checks the local header against the + central directory header to verify same file, which should be as using + the disk and offset values from the central directory. Update disk and + offset in central directory. zipfile.c (Ed) +31. Change out_path and out_len to base_path and base_len in + get_split_path(). fileio.c (SMS) +32. Update command line options for VMS to include verbose splitting. + vms/zip_cli.cmd, vms/cmdline.c (SMS) +33. Handle HP. unix/unix.c (SMS) +34. Add adler16() checksum function. util.c (Cosmin) +35. Use FILE_FLAG_BACKUP_SEMANTICS and a less demanding access mode + in CreateFile() when retrieving file attributes. Fixes a problem + when adding a directory entry from an NTFS or a CDFS partition + (i.e. one that stores timestamps using universal time), and the + directory timestamp is not the same daylight savings time setting. + The effect is an offset in the timestamp by one hour, if zip is + built using NT_TZBUG_WORKAROUND. The problem is not exposed, + however, if NO_W32TIMES_IZFIX is defined. win32/win32.c (Cosmin) +---------------------- March 19th 2006 version 3.0f09 ---------------------- + 1. Fix encryption problem where a large file with uncompressable data + can cause deflate to store bad data. See crypt.c for details. + Thanks to the nice people at WinZip for finding and providing the + details of this problem. crypt.c (Ed) + 2. Add note at top of Extended Help to refer to the Zip Manual. zip.c + (Ed) + 3. Update extended help for delete. zip.c (Ed) + 4. Change crypthead() to use buffer and bfwrite() which is split aware. + crypt.c (Ed) + 5. Create SPLIT_SUPPORT version of zipcloak() and zipbare() and read + local header rather than assume data using central header. crypt.c (Ed) + 6. Change zfwrite() to use global output file y. crypt.c (Ed) + 7. Remove in and out parameters from zipcloak() and zipbare() for + splits. crypt.h, zipcloak.c (Ed) + 8. Change get_split_path() to get_in_split_path() and get_out_split_path(). + zipfile.c, fileio.c, zip.h (Ed) + 9. Change crc32f() to crc32u(). fileio.c, zip.h (Ed) +10. Add encryption overwrite fix to copy_block() and remove from zfwrite(). + crypt.c, tree.c (Ed, Christian) +11. Add note on bug fix. WhatsNew (Ed) +12. Add copy_only mode. zip.c (Ed) +13. Make SPLIT_SUPPORT the default. zip.h (Ed) +14. Add set_filetype(), rename_split(), and zipmessage(). zipcloak.c, + zipnote.c, zipsplit.c (Ed) +15. Add long option support. zipcloak.c (Ed) +16. Set in_path. zipcloak.c, zipnote.c, zipsplit.c (Ed) +17. Use SPLIT_SUPPORT calls. zipcloak.c, zipnote.c, zipsplit.c (Ed) +18. Set current_disk, cd_start_disk, and cd_entries_this_disk for use + by putend() and bytes_this_split for putcentral(). zipsplit.c (Ed) +19. Include ctype.h for toupper(). zipfile.c (Ed) +20. Add readlocal() for utilities to read local header. zipfile.c (Ed) +21. Put Zip64 variables and code in ZIP64_SUPPORT ifdef in scanzipf_regnew(). + zipfile.c (Ed, SMS) +22. Use zip_fzofft() for converting offset. zipfile.c (Ed, SMS) +23. Add casts to many append to memory calls. zipfile.c (Ed) +24. Move handling of .zip split to get_in_split_path() and + get_out_split_path(). zipfile.c (Ed) +25. Handle fix = 3 case for ZipNote that renames entries in zipcopy(). + zipfile.c (Ed) +26. Restore clearing of extended local header bit when not encrypting. When + encrypting need to output extended local header using putextended() in + zipcopy(). zipfile.c (Ed) +27. Add notes on using file time for encrypting. zipup.c (Ed) +28. Remove extended local header bit separately for z->lflg (local flags) + and z->flg (central directory flags). These should be the same but + could be different. zipup.c (Ed) +29. Suppress command line globbing for MINGW. win32/win32.c (Christian) +30. Add EF UT time fix for delete. zip.c (Christian) +---------------------- April 28th 2006 version 3.0f10 ---------------------- + 1. Add note to extended help to escape [ as [[] or use -nw. zip.c (Ed) + 2. Remove local declaration of tempfile as now global. zipnote.c, + zipcloak.c (SMS) + 3. Add zip_fzofft() for outputting uzoff_t bin size c. zipsplit.c (SMS) + 4. Add only_archive_set and clear_archive_bits to do Window archive bit + selection and clearing. Add -AS option to require DOS Archive bit + be set and -AC to clear archive bits of included files. Add + ClearArchiveBit() to clear archive bits after archive created. + Only Win32. globals.c, zip.h, zip.c, win32zip.c, win32.c (Ed) + 5. Change procname_win32() and readd() to check archive bit. + win32/win32zip.c (Ed) + 6. Update copyright. win32/win32zip.h (Ed) + 7. Add mesg_line_started = 0 to stats to remove blank line when clearing + archive bits. zipup.c (Ed) + 8. Add zip_fzofft() to format split size. zipsplit.c (SMS) + 9. Update help for splits and archive bit and add note on escaping [. + zip.c (Ed) +10. Add -M option and bad_open_is_error to exit with error if any input + file unreadable. Also error if -M and would get "name not matched" + warning. zip.c (Ed) +11. Copy Zip 2.32 csharp example, though it is designed for zip32.dll and + not zip32z64.dll from Zip 3.0. Updated note. windll/csharp (Ed) +12. Change -M to -MM and define -mm to avoid accidental use of -m. + zip.c (Ed) +13. Define split_method -1 to not allow splitting, mainly used when reading + a split archive to stop automatic splitting of output with same + split size. Now -s=0 or -s- disables splitting. zip.h, globals.c, + zip.c (Ed) +14. Add fflush() after dots displayed. deflate.c, fileio.c, zipup.c (Ed) +15. Instead of assuming buffer size as 32 KB for dots, use WSIZE for + compressing and SBSZ for storing and calculate as dots are counted. + Now dot_count and dot_size are bytes instead of buffers. Add dots + to Delete and Archive modes. zip.c, zipup.c, deflate.c, fileio.c (Ed) +16. If reading a split archive and split size has not been given, get + size of first split read by zipcopy(), which should be the first + split, and set split size to that, making the output archive the same + split size as the input archive. Delay -sv split size message + if split size is 0 at first but then changed. zipfile.c (Ed) +17. Add proc_archive_name() for new archive mode to process names in old + archive only and skip looking on the file system. Easier than modifying + the various port codes. fileio.c (Ed) +18. Fix cd_start_offset bug. fileio.c (Ed) +19. Create new action ARCHIVE that looks for matches only in old archive + for Copy Mode. If no input paths and there is an output archive, + Copy Mode is assumed even without ARCHIVE. Old default Copy Mode + when no input files updated to work like -U mode and allow filters. + New global copy_only currently only used to control global dots. + zip.c, fileio.c, globals.c, zip.h (Ed) +20. Update help. Change extended help to more help. Update more help + to include internal modes delete and new Archive. Update help for + formatting options. Update help for wildcards. Remove streaming + examples from top basic section. Indent examples. Help for new + --out and Copy Mode. Add warnings that output using data descriptors + may not be compatible with some unzips. Update dots help and add + warning that dot size is approximate. Add help for new DOS archive + bit options. More help for -b and -MM. zip.c (Ed) +21. Add support for Unix FIFO (named pipe). Add set_extra_field() stat + name ending in '/' fix found in Zip 2.32. unix/unix.c (Ed) +22. Add check to not allow setting -U (internal copy) in similar cases to + -d (delete). zip.c (Ed) +23. Add counts for internal modes Delete and Archive. Byte counts for -db + remain uncompressed size for external modes, but internal modes Delete + and Archive now use compressed sizes as these copy that many bytes. + zip.c (Ed) +24. Add check for when ftell() wraps. zipup.c (Ed) +25. Add mesg_line_started = 0 to result percentage message. zipup.c (Ed) +26. Update contact information. unix/packaging/preinstall.in (SMS, Ed) +27. A few Zip64 fixes to set Zip64 correctly and fix disk and offset of + Zip64 End Of Central Directory. zipsplit.c (Ed) +28. Update comments for get_option(). fileio.c (Ed) +29. Update DLL version. windll/windll.rc (SMS, Ed) +30. New option -sf shows files that would be operated on. zip.c (Ed) +---------------------- May 5th 2006 version 3.0f11 ---------------------- + 1. Use C prototypes for Unicode functions. fileio.c (SMS) + 2. Change constant for mask in set_file_type from unsigned to signed. + trees.c (SMS) + 3. Use C prototypes for zip_fzofft() and zip_fuzofft() signed and + unsigned zoff_t formatting functions. util.c (SMS) + 4. Remove U from constants in Adler16 code. util.c, zip.h (SMS) + 5. Add spaces to VMS usage to avoid misinterpretation. zip.c (SMS) + 6. Add OF() to at_signature(). zipfile.c (SMS) + 7. Use zip_zofft() for entries error. zipfile.c (SMS) + 8. Remove U in constants in percent(). zipup.c (SMS) + 9. VMS command line updates. vms/cmdline.c, vms/descrip_deps.mms, + vms/vms_zip.rnh, zip_cli.cld, vms/zip_cli.help (SMS) +10. Update to VMS help. vms/zip_cli.help (Ed) +11. Check for memmove() and strerror(). Remove specific 64-bit support + for SunOS, as large file support now does. unix/configure (SMS) +12. Add emergency replacements for memmove() and strerror(). + unix/unix.c (SMS) +13. Remove old not SPLIT_SUPPORT code. globals.c, zipnote.c, fileio.c, + crypt.h, crypt.c, zipcloak.c, zip.h, zip.c, zipup.c, zipsplit.c, + zipfile.c (Ed) +---------------------- May 12th 2006 version 3.0f12 ---------------------- + 1. Add UNICODE_SUPPORT ifdef around uname in zipup(). zip.c (SMS) + 2. Change size from uzoff_t to zoff_t in zipcopy(). zipfile.c (SMS, Ed) + 3. Fix a bug where filetime() returns -1 for device but not handled in + byte counts. zip.c (Ed) + 4. Add check for UnZip version and exit if not 6.00 or later if + a Zip64 archive. Define popen() and pclose() in Win32 to native + _popen() and _pclose(). ziperr.h, zip.c, win32/osdep.h (Ed) + 5. Add -sb option to ring bell when pause to change disk. Use new + global split_bell. global.c, zip.h, zip.c, fileio.c (Ed) + 6. Enable crc32u() and use for Unicode extra field. fileio.c (Ed) + 7. Add -dv to display volume being written to. zip.c, zip.h, + globals.c (Ed) + 8. Update WhatsNew. WhatsNew (Ed) + 9. Help updates. zip.c (Ed) +10. Create option -X- (negated -X) to keep old extra fields and remove + -XX which is now -X. Make get_extra_field() global. Add + copy_nondup_extra_fields()to copy old extra fields not already + in new extra fields. zipup.c, zip.c, zipfile.c (Ed) +11. Use output name oname for -sf option to show files that would be + worked on. zip.c (Ed) +12. When updating or freshening old entries, read the old local header + with readlocal() to get local flags and extra fields. zip.c (Ed) +13. Add UNICODE_SUPPORT ifdefs around uname code. zip.c (SMS, Ed) +14. If WIN32_OEM set then on WIN32 store OEM name in archive. As read + DOS or WIN32 archives convert assumed OEM paths to ANSI. Remove old + WIN32_OEM code. Make oem_to_local_string() global for WIN32_OEM and + local_to_oem_string() global for WIN32_OEM and UNICODE_SUPPORT. + zip.h, zipfile.c, zipup.c, win32/win32.c, win32/win32zip.c (Ed) +15. Update error 8 to include wrong unzip. ziperr.h (Ed) +16. Change checksum for Unicode extra field to standard crc32 using + C version crc32u(). Add crctab.c. win32/vc6/zipnote.dsp, + win32/vc6/zipsplit.dsp, zipfile.c +17. Update readlocal() to handle multi-disk archives if not UTIL. + zipfile.c (Ed) +18. Convert size to signed zoff_t in zipcopy(). Update note. + zipfile.c (Ed) +19. Update Readme. Readme (Ed) +20. Add crctab.o to zipsplit and zipnote. unix/Makefile (Ed) +21. Proposed update to license. License (Ed) +---------------------- May 20th 2006 version 3.0f13 ---------------------- + 1. Reformat License file. License (Cosmin) + 2. Change %d to %lu for disk number and add cast. zip.c (Cosmin, Ed) + 3. Display Scanning files message after delay at start based on + suggestion from Greg. Currently the time is checked every 100 + entries processed. After 100 entries the start time is saved. + After 5 seconds or 100 entries after that, whichever takes + longer, the Scanning files message is displayed and every 2 seconds + or 100 entries, whichever takes longer, after that a dot is displayed. + fileio.c, zip.c, globals.c, zip.h (Greg, Ed) + 4. Add Unicode mismatch flag and option -UN. Default is now a Unicode + mismatch is an error. -UN=warn outputs warnings and continues, + -UN=ignore disables warnings, and -UN=no ignores the Unicode extra + fields. globals.c, zip.h, zipfile.c (Ed) + 5. Add options for VMS. vms/cmdline.c, vms/zip_cld.cld (SMS) + 6. Add casts to percent(). zipup.c (Ed) + 7. Minor changes to logfile formatting. zip.c (Ed) + 8. Update help. zip.c (Ed) + 9. Add -Z=compression-method option. zip.c (Ed) +10. Add sd: to -sd status messages. zip.c (Ed) +11. Instead of original argv[] use args[] for -sc show command line + to show final command line. zip.c (Ed) +12. Change argv[] to args[] for logfile. zip.c (Ed) +13. Put results of -sf show files in log file if open. zip.c (Ed) +14. Add Johnny's bzip2 patch but not tested. win32/makefile, zip.c, + zip.h, zipup.c (Johnny) +15. Minor tweeks to bzip2 to work with latest beta. zip.c, zipup.c (Ed) +16. Add -sf- to list files that would be included only in log file + and not on stdout as list can be long. Only list totals on stdout. + zip.c (Ed) +17. Create check_unzip_version(). Fix Unix check. Zip still creates + the temporary archive then does the check, and if it fails + the archive is deleted, even if the check fails because of the wrong + verion of UnZip. On Unix only 'unzip' the system version of UnZip + is checked, not './unzip' which would allow putting a local more + up to date version of UnZip in the current directory for the check. + There should be a way to override the system version of UnZip for + the -T test. zip.c (Ed) +---------------------- July 12th 2006 version 3.0f14 ---------------------- + 1. Change crypt version from 2.10 to 2.91 to match Zip 2.32 and avoid + confusion. crypt.h (Cosmin) + 2. Add abbrevmatch() to handle option values that can be abbreviated + like compression method. util.c, zip.h, zip.c (Ed) + 3. Change USE_BZIP2 to BZIP2_SUPPORT as USE_BZIP2 implies it replaces + deflation maybe. zip.c, zip.h, zipup.c (Ed) + 4. Update man page. man/zip.1, zip.txt (Ed) + 5. Add bzip2 to VMS. vms/build_zip.com, vms/bzlib.h, vms/cmdline.c, + vms/descrip.mms, vms/descrip_src.mms, vms/find_bzip2_lib.com, + vms/install_vms.txt, vms/zip_cli.cld (SMS) + 6. Remove zipfile parameter from bzfilecompress(). Add unsigned + cast for EOF in bzip2 code. Add bzip2 version information. + zipup.c, zip.c (SMS) + 7. Add bzip2 to Unix. unix/configure (SMS) + 8. Add and update bzip2 descriptions. INSTALL, README, WhatsNew, + bzip2/install.txt (SMS, Ed) + 9. Add vc6bz2 projects for compiling bzip2 code into zip (not the + best approach perhaps). win32/vc6/readmevc.txt, + win32/vc6bz2/readvcbz.txt, win32/vc6bz2/zip.dsp, win32/vc6bz2/zip.dsw, + win32/vc6bz2/zipcloak.dsp, win32/vc6bz2/zipnote.dsp, + win32/vc6bz2/zipsplit.dsp (Ed) +10. Add support for VC++ 2005 by disabling deprecation. win32/osdep.h + (Cosmin) +11. Update instructions for makefile. unix/Makefile (Ed) +12. Update todo list. todo30.txt (Ed) +13. Reduce #if 0 block to now allow extra data message. zipfile.c (Ed) +14. Add note that readlocal() reads local headers. zipfile.c (Ed) +15. Archive comment was not being read by new scanzipf_regew(). Added. + zipfile.c (Ed) +16. Handle reading and writing OEM comments. zipfile.c (Ed) +17. Update Zip64 data descriptor note. zipfile.c (Ed) +18. Format filetypes() check. zipup.c (Ed) +19. Update note to remember to force deflation for descriptors by + release. zipup.c (Ed) +20. In compression code using libraries, enable dots for noisy also. + zipup.c (Ed) +21. Update extended help to add more of the basic options and + compression method. zip.c (Ed) +22. Add additional lines bz_opt_ver2 and bz_opt_ver3 to bzip2 + version to give credit to bzip2. zip.c (Ed) +23. Add descriptions to version information for USE_EF_UT_TIME, + NTSD_EAS, WILD_STOP_AT_DIR, WIN32_OEM, LARGE_FILE_SUPPORT, + ZIP64_SUPPORT, and UNICODE_SUPPORT similar to how UnZip does. + zip.c (Ed) +24. Add note that crypt is modified in Zip 3. zip.c (Ed) +25. Use abbrevmatch() and update warnings for compression + method selection. zip.c (Ed) +26. Update config to handle either using IZ_BZIP2 to define + the location of the bzip2 files or the bzip2 directory. + unix/configure, zipup.c, zip.c (SMS, Ed) +---------------------- July 14th 2006 version 3.0f15 ---------------------- + 1. Change USE_BZIP2 to BZIP2_SUPPORT in VMS. vms/descrip_src.mms, + vms/build_zip.com (SMS) + 2. Add SYS$DISK:. vms/descrip.mms, vms/build_zip.com (SMS) + 3. Change vms/install.txt to [.vms]install.txt. bzip2/install.txt (SMS) + 4. Change VMS files to lower case. vms/mod_dep.com, vms/install_vms.txt, + vms/zip.opt, vms/hlp_lib_next.com, vms/notes.txt, vms/unixlib_gcc.h, + vms/unixio_gcc.h (SMS) + 5. Remove old VMS files. vms/descrip-old.mms (removed), + vms/link_zip.com (removed), vms/make_zip.com (removed), + vms/makefile.vms (removed) (SMS) +---------------------- July 24th 2006 version 3.0f16 ---------------------- + 1. Fix global dots so can set with dot size. deflate.c, fileio.c (Ed) + 2. Update License top line to refer only to license. License (Cosmin) + 3. Update License. License (Ed) + 4. Implement zero length UTF-8 path length as flag standard path is UTF-8 + and should use that. This allows Zip to use the standard path as + UTF-8 when the local character set is UTF-8. zipfile.c (Ed) + 5. Update WhatsNew. WhatsNew (Ed) + 6. Change case of bzip2/install.txt. INSTALL (Ed) + 7. Change MANUAL.txt to ZIP.txt and update ftp site. README (Ed) + 8. Update announcement. zip30f.ann (Ed) + 9. Now also check if OS has bzip2 library and can use that. + unix/configure, zip.c (Mark Adler, Ed) +10. Add fix from akt@m5.dion.ne.jp in Japan to recurse on doublebyte + characters without processing in recmatch(). This should not be needed + unless the rest of the code in there is broke for Japanese character + sets in some way. Need to test. util.c (Ed) +11. Add note for bzip2. zip.c (Ed) +12. Do not do seek wrap test if ftell() returns -1 as from a pipe. Add + output of last ftell() and current ftell() for zipfile too big seek + error. zipup.c (Ed) +13. Add version to the options table. Remove the check to display version + before the command line is processed. Add to option -v a check to + display the version if that is the only argument. Can still enable + verbose with piping by using zip -v - - format. zip.c (Ed) +14. Add abbrevmatch() for -UN option. zip.c (Ed) +---------------------- August 7th 2006 version 3.0f17 ---------------------- + 1. Change license modifications to retain intent of copyright holders, as + any major change in license conditions would require contacting all + copyright holders. LICENSE (Greg, Ed) + 2. Move debugging statement after zipstdout() where mesg is set to stderr. + Add mesg and fflush() to sd messages where needed so that messages go + to stderr when piping. zip.c (Ed) + 3. Update encryption comment. zipup.c (Ed) + 4. Do not use data descriptors for directories. zipup.c (Mark, Ed) + 5. Update Q & A to match license. README (Ed) + 6. Update WhatsNew. WHATSNEW (Ed) + 7. Add ifndef around version_info() for dll. zip.c (Ed) + 8. Add -TT (--unzip-path) to allow setting the unzip command to use with + -T to test the archive. zip.c (Ed) + 9. Add -DF (--difference-archive) which requires --out and turns off + copying unchanged entries to the new archive creating an archive with + just the changes and additions since the original archive was created. + zip.c, globals.c, zip.h (Ed) +10. Update help. zip.c (Ed) +---------------------- September 7th 2006 version 3.0f18 ---------------------- + 1. Split -t and -tt options and remove limitation that only one can be + used to allow setting a date range. zip.c, WhatsNew (Ed) + 2. Minor changes in comments. zipfile.c (Ed) + 3. Add entries for format of Unicode Path and Unicode Comment extra fields. + proginfo/extrafld.txt (Ed) + 4. Change note at top of infozip.who, but needs to be updated with all new + contributors. proginfo/infozip.who (Ed) + 5. Note Zip 3 and UnZip 6 now support Zip64. proginfo/ziplimit.txt (Ed) + 6. Add note on Unicode. README (Ed) + 7. Update WHATSNEW. WHATSNEW (Ed) + 8. Update help. zip.c (Ed) + 9. Add {} support to -TT option, allowing insertion of temp archive path + into the command string to -TT similar to Unix find does. zip.c (Ed) +10. Start changes for -F fix option. Add checks when reading input archive + and skip bad central directory entries and bad local entries. Currently + -F requires the central directory to be intact (except for bad CD entries + that will be skipped) and local entries and data to be where the + central directory say they are. This allows all recovered entries to + be complete with all central directory information. Calculate CRC of + input entry and compare to CRC from central directory. Allow skipping + split disks the user may not have. Store state of output archive + before each local entry and data are read, allowing seeking back and + restoring state to skip bad entries. fileio.c, global.c, zipfile.c, + zip.h (Ed) +11. Started changes for fixfix. fileio.c (Ed) +12. Update help on -t and -tt. zip.c (Ed) +13. Add note on Unicode support, but may change if add handling of names + with characters not supported in current character set. README (Ed) +14. Combined ToDo30.txt and ToDo but more to be done. TODO (Ed) +15. Update ToDo list. ToDo30.txt (Ed) +16. Add -F and -FF to help. zip.c (Ed) +17. Run fix mode in copy mode, as it is copying from one archive to + another, and use those checks. zip.c (Ed) +18. Add Try -F and Try -FF warnings in places. zipfile.c (Ed) +19. Allow reading version 4.6 (bzip2) archives. zipfile.c (Ed) +20. Add Unicode Path and Unicode Comment extra field descriptions. + proginfo/extrafld.txt (Ed) +21. First attempt at updating the Who file. proginfo/infozip.who (Ed) +22. Add note to top of ziplimit.txt. proginfo/ziplimit.txt (Ed) +23. Add possible fix for paths returned by the Win32 directory scan with + '?' in the name. These are characters in the Unicode name stored on + disk but not represented in the multi-byte character set used by zip + for the scan. In this case, return the short name in 8.3 format so + directory scan can continue. Could put the Unicode name in the Unicode + extra field, but not done. Add warning when long name is replaced + by short name. Not fully tested. win32/win32zip.c, zip.h, zip.c, + fileio.c (Ed) +24. If archive name and -sf are the only parameters, list archive contents. + zip.c (Ed) +---------------------- September 8th 2006 version 3.0f19 ---------------------- + 1. Fix error message. zipfile.c (SMS, Ed) + 2. Put crc32() in ifndef UTIL as only needed for fix. fileio.c (SMS, Ed) +---------------------- November 3rd 2006 version 3.0f20 ----------------------- + 1. Fix comment. vms/vmszip.c (SMS) + 2. Include oem_to_local_string() if UNICODE_SUPPORT. win32/win32.c, + zip.h (Ed) + 3. Modify procname_win32() to flag a path not supported by the local + character set so can get Unicode for it. Check Unicode names. + win32/win32zip.c (Ed) + 4. Add matching of escaped Unicode names to proc_archive_name() that + reads entries from an archive. Add sorted zlist zusort. + globals.c, fileio.c, zip.h, zipfile.c (Ed) + 5. Add support for non-local character set names and paths for WIN32, + getting and storing the UTF-8 path when needed. Use 8.3 name + when normal name has characters not supported in current local + character set. Note when short name used. zip.c, fileio.c (Ed) + 6. Add support for fix = 2 which reads local headers first to + bfcopy(). fileio.c, zip.h (Ed) + 7. Allow selection of .zip split in ask_for_split_read_path() when + reading a split archive that has no end records giving the total + split count. fileio.c (Ed) + 8. Add zoff_t casts to dot counts. fileio.c (Ed) + 9. Comment changes for Unicode. fileio.c (Ed) +10. Call wide_to_local_string() separately in utf8_to_local_string() + to free up temp value. fileio.c (Ed) +11. Support new AppNote bit 11 for forcing UTF-8, but needs finishing. + globals.c (Ed) +12. Add to zlist struct zuname for the escaped version of the UTF-8 + name in uname and add ouname for the display version of zuname. + zip.c, zip.h, zipfile.c (Ed) +13. Add zipmessage_nl() that can output to the screen and to the log + file like zipmessage(), but can write lines without a newline. + zip.c, zip.h, zipcloak.c, zipnote.c, zipsplit.c (Ed) +14. Update help for -FF and Unicode. zip.c (Ed) +15. Change > to >= for byte message check to avoid -0 (negative zero). + zip.c (Ed) +16. Add -su show unicode option which adds escaped unicode paths to + -sf. Also uses show_files = 3. zip.c (Ed) +17. Update comments for -UN and -X. zip.c (Ed) +18. Add support for new AppNote bit 11 that says standard path and + comment have UTF-8 when -UN=f is used. zip.c (Ed) +19. Fix zipfile name message by replacing value with zipfile. + zip.c (Ed) +20. Add new code for -FF, which processes archives by trying to read + the EOCDR to get split count, then starting with the local + entries. This option does not use the standard code but does + everything itself. Add scanzipf_fixnew(), which tries to read + the EOCDR, then the local entries, then the central directory. + zip.c, zipfile.c (Ed) +21. Update note for ZIP64_CENTRAL_DIR_TAIL_SIZE. zipfile.c (Ed) +22. Put read_Unicode_Path_entry() and read_Unicode_Path_local_entry() + into UNICODE_SUPPORT ifdef. zipfile.c (Ed) +23. Add zuqcmp() and zubcmp() to support Unicode sorted list of + paths. zipfile.c (Ed) +24. Update zsearch() to also search unicode paths. zipfile.c (Ed) +25. Split out iname in read_Unicode_Path_entry() for debugging. + Should put it back. Update Unicode mismatch warning. + zipfile.c (Ed) +26. Update Unicode in readlocal(). zipfile.c (Ed) +27. Add more Unicode support to scanzipf_regnew(). zipfile.c (Ed) +28. Add support for fix = 2 to zipcopy(). Add checks and warnings, + but allow scan to continue when can. Use local data to fill + in central directory fields in case no central directory entry + for local entry. zipfile.c (Ed) +29. Add get_win32_utf8path() to get UTF-8 from Windows if can. + zipfile.c (Ed) +---------------------- November 7th 2006 version 3.0f21 ----------------------- + 1. Add crude data descriptor support to -FF in bfcopy() that should be + updated by release. fileio.c (Ed) + 2. Change %d to %s and use zip_fzofft() to format zoff_t byte count. + zipfile.c (SMS, Ed) + 3. Call local_to_oem_string() for only WIN32 in zipcopy(). zipfile.c + (SMS, Ed) +---------------------- November 29th 2006 version 3.0f22 ----------------------- + 1. Change ' to " in extended help. zip.c (Ed) + 2. Change -dv disk number display to indisk>outdisk. zip.c (Ed) + 3. Finish -FF fix option. Move detailed output to require -v. zip.c (Ed) + 4. Add note to help to use -v with -FF to see details. zip.c (Ed) + 5. Add -sU option to view only Unicode names when exist. zip.c (Ed) + 6. Change default dot size in verbose from every buffer to 10 MB. zip.c (Ed) + 7. Exit if --out and in path same as out path. zip.c (Ed) + 8. Remove verbose information when fixing archive. zip.c (Ed) + 9. Initialize in disk to 0, but still problem with disk number of first entry + for each disk lagging by 1. zip.c (Ed) +10. Consistently use ZE error codes for exit from ask_for_split_read_path. + zipfile.c, zip.c (Ed) +11. Seek back when fix finds bad entries. Also skip last entry of split + if next split is missing. Should check if entry completed. zip.c (Ed) +12. Add messages to -sd for writing the central directory, replacing the old + zip file, and setting file type. zip.c (Ed) +13. Don't set file type on stdout. zip.c (Ed) +14. Increase errbuf from FNMAX + 81 to FNMAX + 4081. zip.h (Ed) +15. Add skip_this_disk, des_good, des_crc, des_csize, and des_usize globals + for -FF and reading data descriptors. Change note on display_volume. + Add global skip_current_disk. zip.h, globals.c (Ed) +16. BFWRITE_HEADER define now also does data descriptor. zip.h (Ed) +17. Skip zipoddities() if fix. Maybe can later add back. zipfile.c (Ed) +18. Update fix messages. zipfile.c (Ed) +19. Allow user to end archive early using ZE_EOF. zipfile.c, fileio.c (Ed) +20. Only show split numbers and offsets for -FF if verbose. zipfile.c (Ed) +21. Handle spanning signature at top of split archive. zipfile.c (Ed) +22. Only close in_file if open. zipfile.c (Ed) +23. Add note if no .zip and only splits suggest use -FF. zipfile.c (Ed) +24. In putlocal() and putcentral() only convert to OEM if z->vem == 20. + zipfile.c (Ed) +25. Do not OEM convert archive comment as PKWare says this should + be ASCII. zipfile.c (Ed) +26. Fix swap of siz and len and LOCSIZ and LOCLEN. zipfile.c (Ed) +27. Call read_Unicode_Path_local_entry() before OEM conversion so Unicode + checksum checks iname before conversion. zipfile.c (Ed) +28. Only check if local and central crc match if not stream entry. + zipfile.c (Ed) +29. Keep data descriptors if fix == 2, but need to look at this. + zipfile.c (Ed) +30. Fix bug adding up header bytes in n by adding 4 for signature. + zipfile.c (Ed) +31. If fix == 2 use local crc for central, otherwise use central crc + for local. zipfile.c (Ed) +32. In zipcopy(), check data descriptor and skip if not correct one. + zipfile.c (Ed) +33. Add SH, LG, and LLG macros from zipfile.c to allow reading the data in + the data descriptor. fileio.c (Ed) +34. In bfcopy(), read and check the data descriptor if n == -2. If + run out of bytes before find descriptor, return error. fileio.c (Ed) +35. In ask_for_split_read_path(), increase buf to SPLIT_MAX_PATH + 100, + fix bug by adding "- 1", set split_dir = "" if current directory, + and update prompts to add skip and end choices. Add skip and end + choices. fileio.c (Ed) +36. Increase buffer for fgets to SPLIT_MAXPATH. fileio.c (Ed) +37. Update WhatsNew. WhatsNew (Ed) +---------------------- December 10th 2006 version 3.0f23 ----------------------- + 1. Handle additional ODS5 issues by upper casing many symbols and file names. + vms/build_zip.com, vms/collect_deps.com, vms/descrip.mms, + vms/descrip_mkdeps.mms, vms/descrip_src.mms, vms/find_bzip2_lib.com (SMS) + 2. Update VMS Find Help Library code. vms/hlp_lib_next.com (SMS) + 3. Instead of tempname use temp_name as parameter to avoid function + tempname(). zipsplit.c, zipnote.c, zipcloak.c, zip.c (Ed) + 4. If fixing archive with -FF and no EOCDR to get disk count, see if top of + archive has spanning signature or local header and guess if it is + single-disk archive, then ask user to confirm. zipfile.c (Ed) + 5. For Unix where NO_MKSTEMP is not defined, replace mktemp() with mkstemp() + that avoids a race condition. zip.c, zipcloak.c, zipnote.c, fileio.c (Ed) + 6. Eliminate mkstemp() warning by using mkstemp() instead of mktemp() for + Unix. Only for UNIX and if NO_MKSTEMP is not defined. Many OS do not + have mkstemp(). zipcloak.c, zipnote.c, zip.c, fileio.c (Ed) + 7. If UNICODE_SUPPORT and UNIX then try to switch to UTF-8 locale to allow + displaying of Unicode, otherwise just get escapes. This results in some + characters displaying as whitespace if needed fonts, such as East Asian, + are not installed. zip.c (Ed) + 8. If new global unicode_escape_all is set, then escape all non-ASCII + characters when converting Unicode file path. This allows viewing paths + as escapes on Unix that would otherwise be white space. If not set, any + characters that map to the current locale are returned as is. Can only + display if either supported as base by the OS or fonts installed. Set + using -UN=escape option. zip.c, fileio.c, zip.h, globals.c (Ed) + 9. Update extended help for Unicode. zip.c (Ed) +10. All variables used by Win32 in global.c should now be initialized at + start so dll is initialized each call. zip.c (Ed) +---------------------- January 1st 2007 version 3.0f24 ----------------------- + 1. Fix a problem when building with (old, obsolete) IM attribute encoding + combined with bzip2 support. vms/descrip_src.mms (SMS) + 2. Update WHATSNEW. WhatsNew (Ed) + 3. Update README. ReadMe (Ed) + 4. Remove in_crc code. Too involved to implement but may look at later. + fileio.c, globals.c, zip.c (Ed) + 5. Use 0x50 and 0x4b for 'P' and 'K' in signatures to handle EBCDIC case. + zipfile.c, fileio.c (Ed) + 6. Implement new -FS file sync option that deletes entries missing on the + file system from an archive being updated. globals.c, zip.c (?, Ed) + 7. Update help. zip.h, zip.c (Ed) + 8. Include scanning files dots when update small but new file scan long. + zip.c (Ed) + 9. Ask if single-file archive when using -FF and can't tell. zipfile.c (Ed) +10. Display message when entry would be truncated. zipfile.c (Ed) +11. Check for VMS_IM_EXTRA. Update bzip2 support for VMS. Change + destination directory if large-file enabled. vms/build_zip.com, + vms/descrip_src.mms (SMS) +12. Change parameters for VMS bzip2 search. vms/find_bzip2_lib.com (SMS) +---------------------- January 12th 2007 version 3.0f25 ----------------------- + 1. Incorporate faster crc32.c including the Rodney Brown changes (originally + implemented in the zlib project) from UnZip, which includes the + IZ_CRC_BE_OPTIMIZ and IZ_CRC_LE_OPTIMIZ optimizations when those symbols + are defined. These modifications include: + - enlarge unrolling of loops to do 16 bytes per turn + - use offsets to access each item + - add support for "unfolded tables" optimization variant + crc32.c (Christian) + 2. As the crc32.c module now includes crc table generation, remove crctab.c. + crctab.c (remove) (Christian) + 3. Update crc i386 assembler code from UnZip (details see above). + win32/crc_lcc.asm, win32/crc_i386.asm, win32/crc_i386.c, crc_i386.S + (Christian) + 4. Guard against redefinition of symbols @CodeSize and @DataSize in memory + model setup section to work around Open Watcom (version 1.6) wasm + assembler problem. msdos/crc_i86.asm (Christian) + 5. Change type of keys[] array for new crc, add IZ_CRC_BE_OPTIMIZ, and + use new crypt crc table. Use header buffer instead of buf for header. + crypt.c, crypt.h (Christian) + 6. Update version and remove crc table. crypt.h (Christian) + 7. Add crc32.h, change sprintf() format for disk number from d to lu as + can go over 16-bit, remove crc32u(). fileio.c (Christian) + 8. Update to use new crc. msdos/makefile.bor, msdos/makefile.dj1, + msdos/makefile.dj2, msdos/makefile.emx, msdos/makefile.msc, + msdos/makefile.tc, msdos/makefile.wat, unix/Makefile, + vms/build_zip.com, vms/descrip_deps.mms, vms/descrip_src.mms, + vms/osdep.h, win32/makefile.bor, win32/makefile.dj, win32/makefile.emx, + win32/makefile.gcc, win32/makefile.ibm, win32/makefile.lcc, + win32/makefile.w10, win32/makefile.w32, win32/makefile.wat, + win32/makenoas.w32, win32/vc6/zip.dsp, + win32/vc6/zipcloak.dsp, win32/vc6/zipnote.dsp, win32/vc6/zipsplit.dsp, + win32/vc6bz2/zip.dsp, win32/vc6bz2/zipcloak.dsp, win32/vc6bz2/zipnote.dsp, + win32/vc6bz2/zipsplit.dsp, windll/visualc/dll/zip32.dsp, + windll/visualc/dll/zip32.mak, windll/visualc/lib/zip32.dsp, + win32/visualc/lib/zip32.mak (Christian) + 9. Include crc32.h. Make variable uname local in proc_archive_name(). + Remove unused num and new_base_path. Change %02d to %02l2 for + disk number in print format. Remove crc32u() as now use crc32(). + Add parentheses around conditions in loops. Use 0 instead of NULL + for zwchar. fileio.c (Christian) +10. Add z_uint4 defines from crypt.c to tailor.h. Move uch, ush, and ulg + typedefs before tailor.h include which needs them. tailor.h, zip.h (SMS) +11. Include crc32.h. change add_name() to return not int but long + since number of command line arguments can exceed 16 bits. Cast + variable option to (int) for subtraction. Change 0x400 to 0x400L. + Add braces to show_files print block. zip.c (Christian) +12. Add warning if use -F or -FF without --out. Change defined(NO_MKSTEMP) + to !defined(NO_MKSTEMP). zip.c (Ed) +13. Define EC64LOC and EC64REC for size of Zip64 EOCD Locator and Zip64 + EOCD Record. Add extern for crc_32_tab. Move crc32() to crc32.h. + zip.h (Christian) +14. Add crc.h. zipcloak.c (Christian) +15. Include crc32.h. Comment out scanzipf_reg() and scanzipf_fix() as + no longer used, which are left in for now for comparison. Cast + blocksize to extent for malloc(). Instead of 0x10000 malloc 0xFFFF for + extra field block so fits in 16 bits. Instead of crc32u() use crc32(). + Only do lflg != flg check for fix == 2. Add comments to various #endif. + Indent comment. Comment out copy_sig() which is not used. Reduce size + of SCAN_BUFSIZE to EC64REC for MEMORY16. Use ENDHEAD for EOCDR size. + Change %u to %lu in print formats for disk count. Use EC64LOC for size + of Zip64 EOCD Locator. Use EC64REC for size of Zip64 EOCD Record. + Add streaming and was_zip64 to ZIP64_SUPPORT. Remove lflg != flg check + in zipcopy(). zipfile.c (Christian) +16. Add note that z-flg & ~0xf check will fail if new bit 12 for UTF-8 paths + and comments is set. Update -FF warning. zipfile.c (Ed) +17. Include crc32.h. Modify tempzn update. Fix comment. Set + z->lflg = z->flg after deflate as deflate may have set bits in z->flg + [Ed, Christian]. Include BZIP2_SUPPORT block in !UTIL block. zipup.c + (Christian) +18. Changes to use crc32.c. acorn/gmakefile, acorn/makefile, amiga/lmkfile, + amiga/makefile.azt, amiga/smakefile, aosvs/make.cli, atari/makefile, + atheos/makefile, beos/makefile, cmsmvs/cczip.exec, cmsmvs/mvs.mki, + cmsmvs/zip.makefile, cmsmvs/zipmvsc.job, cmsmvs/zipvmc.exec, + human68k/makefile, human68k/makefile.gcc, novell/makefile, novell/zip.lnk, + os2/makefile.os2, qdos/makefile.qdos, qdos/makefile.qlzip, tandem/history, + tandem/macros, tandem/tandem.h, theos/makefile, tops20/make.mic, + unix/configure, unix/makefile, win32/makefile.a64 (Christian) +19. Add note to use BZ_NO_STDIO. bzip2/install.txt (Ed) +20. Remove crctab. cmsmvs/zipvmc.exec (Ed) +21. Update comment. macos/source/pathname.c (Christian) +22. Start of manual update. Zip.1 (Ed) +23. Changes to use crc32.c. vms/descrip.mms, vms/descrip_deps.mms, + vms/descrip_mkdeps.mms, vms/descrip_src.mms, vms/vms.c (SMS) +---------------------- January 17th 2007 version 3.0f26 ----------------------- + 1. Add note for UnZip. crypt.c (Christian) + 2. Change current_disk and disk_number from int to ulg. Change num from int + to unsigned int. [Even though a 16-bit system likely won't see more than + 64k disks, it probably should be ulg - Ed] Remove unused mbsize. Change + match from long to int as the number of possible options should always fit + in that. fileio.c, globals.c (Christian) + 3. Use -Gt to force some data into separate data segments so all data fits. + msdos/makefile.msc (Christian) + 4. Move some copyright constants to far to save near space. + revision.h (Christian) + 5. Change u for character from int to unsigned int. util.c (Christian) + 6. Move include of crc32.h from vms/vms.c to vms/vms_pk.c. vms/vms.c, + vms/vms_pk.c (Christian) + 7. Update crci386_.o. win32/makefile.gcc (Christian) + 8. Use NOASM=1 to disable assembler and clear variables when do not. + win32/makefile.w32 (Christian) + 9. Remove unused totalslashes and returnslashes from get_win32_utf8path(). + win32/win32zip.c (Christian) +10. Remove local versions of tempzip and tempzf. + zip.c (Christian) +11. Make options[] far. Change cd_start_disk from int to ulg. Cast -1 to + (ulg) for cd_start_disk. Put here = zftello() in DEBUG defines. + zip.h, zip.c (Christian) +12. Change length of zipfile comment parameter from ush to extent. Change + disk numbers from int to ulg in close_split(), ask_for_split_read_path(), + ask_for_split_write_path(), get_in_split_path(), find_in_split_path(), + get_out_split_path(). Add Far to longopt and name strings in + option_struct. zip.h (Christian) +13. Add far to options[]. zipcloak.c (Christian, Ed) +14. Define write_string_to_mem() only for UNICODE_SUPPORT. Change ulg to + extent for append to mem memory offset and blocksize parameters. Make + at_signature() local. Cast usValue to char. Remove unused oname in + read_Unicode_Path_local_entry(). Remove local definitions of zip64_entry + as Zip is always processing one entry at a time and this is a global + flag for the current entry. Make find_next_signature() and + find_signature() local. Add ZCONST to signature parameter. Make + is_signature() and at_signature() local. Change m, result of fread(), + from int to extent. Reduce SCAN_BUFSIZE from 0x40000 to the size of the + largest header being read. As find_next_signature() is used to scan for + the next signature and that reads a byte at a time, the scan buf is only + used to read in the found headers. Since we skip the extra parts of the + Zip64 EOCDR, all headers are a fixed size. Remove unused variables from + scanzipf_fixnew(). Use ENDCOM for end comment offset. Instead of 64 KB + seek back 128 KB to find EOCDR. Use ENDOFF and ENDTOT for offsets in + EOCDR. Remove tabs. Merge versions of putend(). Update Amiga SFX. + Remove unused offset in zipcopy(). Make size local in zipcopy(). + zipfile.c (Christian) +15. Update putend() comment. zipfile.c (Ed) +16. Add far to options[]. zipnote.c, zipsplit.c (Christian) +17. Add NO_ASM versions of Win32 zipnote, zipsplit, and zipcloak projects. + Add crc32.h and crc32.c to zipsplit and zipnote projects. + win32/vc6/zipsplit.dsp, win32/vc6/zipnote.dsp, win32/vc6/zipcloak.dsp (Ed) +18. Add NO_ASM versions of Win32 bzip2 zipnote, zipsplit, and Zipcloak + projects. Add crc32.h and crc32.c. win32/vc6bz2/zipsplit.dsp, + win32/vc6bz2/zipnote.dsp, win32/vc6bz2/zipcloak.dsp (Ed) +19. Update Win32 dll and lib projects and make files. + windll/visualc/lib/zip32.dsp, windll/visualc/lib/zip32.mak, + windll/visualc/dll/zip32.dsp, windll/visualc/dll/zip32.mak (Ed) +20. Remove space in front of #ifdef and other conditionals that slipped in. + zipfile.c, zipup.c (SMS) +21. Updates for bzip2. vms/bzlib.h, vms/install_vms.txt (SMS) +22. Updates. vms/notes.txt (SMS) +23. Update copyrights. crc32.c, deflate.c, globals.c, revision.h, ziperr.h, + trees.c, win32/nt.c, win32/win32.c, win32/win32i64.c, win32/win32zip.h, + win32/zipup.h (Ed) +24. Update WhatsNew. WHATSNEW (Ed) +---------------------- February 4th 2007 version 3.0f27 ----------------------- + 1. Fix array sizes and loop lengths in wide_to_escape_string(). fileio.c + (Johnny, Ed) + 2. Fix escape_string_to_wide() to handle hex strings, then comment out as + not used. zip.h, fileio.c (Ed) + 3. Use ZIPERRORS() macro instead of ziperrors[] array. zip.c, zipcloak.c, + zipnote.c, zipsplit.c (SMS) + 4. Add VMS-compatible "severity" values, add new ZE_SEV_PERR define to + set when perror() needs to be called, add ZIPERRORS() macro, change + PERR() to use ZE_SEV_PERR, change ziperrors[] to new structure array + to hold error strings, add new VMS facility names and severity codes + assigned by HP to ziperrors[] array, and add new official + VMS_MSG_IDENT. ziperr.h (SMS) + 5. Change ZE_SEV defines to ZE_S to save space and reformat ziperrors[]. + ziperr.h (Ed) + 6. Update install.txt to include generic Unix case. bzip2/install.txt (Ed) + 7. Add creation of message file and add NOMSG message. vms/build_zip.com, + vms/descrip.mms, vms/install_vms.txt (SMS) + 8. Update notes.txt to add changes to program exit status values and changes + to messages. vms/notes.txt (SMS) + 9. Include crc32.h, include ssdef.h, instead of FAB_OR_NAM use FAB_OR_NAML, + add status code summary note detailing old versus new error codes, and if + CTL_FAC_IZ_ZIP is 0x7FFF and OLD_STATUS is defined use old VMS error codes. + vms/vms.c (SMS) +10. Change FAB_OR_NAM to FAB_OR_NAML and remove NAME_DNA, NAME_DNS, NAME_FNA, + and NAME_FNS. vms/vms.h (SMS) +11. Change FAB_OR_NAM to FAB_OR_NAML. vms/vms_im.c, vms/vms_pk.c, + vms/vmszip.c (SMS) +12. Fix compile warning on VC 2005. win32/makefile.w32 (Johnny) +13. Update readmevb.txt and readvb64.txt. windll/vb/readmevb.txt, + windll/vbz64/readvb64.txt (Ed) +14. Change tch from int to ulg in utf8_from_ucs4_char(). Move comments to keep + line lengths to 80 characters. fileio.c (Christian) +15. Update comment for total_cd_entries. global.c, zip.c, zip.h (Christian) +16. Comment out unused Adler-16 code. util.c, zip.h (Christian) +17. Add InterlockedExchangePointer() macro if not defined. Update Initialize() + to use macro. nt.c (Christian) +18. Move zip64 eocd disk and offset variables next to input archive variables. + zip.c (Ed) +19. Remove zipbegset from scanzipf_fixnew() as offsets are ignored when this + is fixing archives. Add comment to cd_total_entries. Remove local + cd_start_disk and cd_start_offset as these are already global. Use + ZIP_UWORD16_MAX when disk number exceeds this to flag use of Zip64. + zipfile.c (Christian) +20. Some comment changes. zipfile.c (Ed) +21. Fix indentation in places. zipsplit.c (Christian) +22. Remove unused variable zfile. zipup.c (Christian) +23. Update manual. zip.1, zip.txt, zipsplit.txt (Ed) +---------------------- February 22nd 2007 version 3.0f28 ---------------------- + 1. Update notes. vms/notes.txt (SMS) + 2. Add stream_lf.fdl to specify carriage control. vms/stream_lf.fdl (SMS) + 3. Update License to also refer to www.info-zip.org and to hopefully provide + an example of misrepresentative use. LICENSE (Ed) + 4. Update Readme. README (Ed) + 5. Update WhatsNew. WHATSNEW (Ed) + 6. Change output archive cd_start_disk and cd_start_offset to input archive + local in_cd_start_disk and in_cd_start_offset in scanzipf_fixnew() and + scanzipf_regnew() to avoid mixing in and out. zipfile.c (Ed) + 7. Update copyright. Remove crc32.h include. vms/vms.c (Christian) + 8. Changes for new crc32. Remove CRC32. Add CRCA_0 and CRCAUO. Add + compiling of crc_i386.S. win32/makefile.emx. (Christian) + 9. Add handlers for better RSXNT and Windows OEM conversions. Add detailed + comments on conversions. win32/osdef.h (Christian) +10. Define CP_UTF8. win32/rsxntwin.h (Christian) +11. Define WIN32_LEAN_AND_MEAN to reduce size of Windows includes. + win32/win32.c, win32/win32zip.c, zip.c (Christian) +12. Use only standard FAT attributes if OEM. win32/win32zip.c (Christian) +13. Add use of INTERN_TO_OEM() and related OEM changes. Add console comment. + zip.c (Christian) +14. Change severity from char to int. Update macros. ziperror.h. (Christian) +15. Update Visual Basic project to clarify some of the code. + windll/vbz64/vbzip.vbp, windll/vbz64/vbzipbas.bas, + windll/vbz64/vbzipfrm.frm (Ed) +16. Update copyright. api.c (Ed) +17. Update format for duplicate entry warning. fileio.c (Ed) +18. Instead of ifdef __RSXNT__ use ifdef WIN32. Define WIN32_LEAN_AND_MEAN. + Use WIN32_CRT_OEM. Change OEM check from vem == 20 to vem & 0xff00 == 0 + and instead of local_to_oem_string() use _INTERN_OEM(). Remove unused + first_CD in scanzipf_fixnew(). Instead of oem_to_local_string() use + Ext_ASCII_TO_Native(). Instead of local_to_oem_string() use + INTERN_TO_OEM(). zipfile.c (Christian) +19. Replace escape from zipsplit man page with '. zipsplit.txt (Christian) +20. Instead of using 20 every time, account for dosify when setting vem. + Update FAT comment. zipup.c (Christian) +------------------------ March 3rd 2007 version 3.0f29 ------------------------- + 1. Remove crctab.c. vms/build_zip.com (SMS) + 2. Add LFLAGS_ARCH. vms/descrip.mms (SMS) + 3. Remove redundant includes descrip.h, rms.h, and atrdef.h. + vms/vmsmunch.c (SMS) + 4. Remove includes descrip.h and rms.h. vms/vmszip.c (SMS) + 5. Only define NO_UNISTD_H if __VAX defined or __CRTL_VER is + less than 70301000, allowing support of the new symbolic + links in VMS. Also use unlink instead of delete if version + above 70000000. vms/osdep.h (SMS) + 6. Formatting changes. vms/notes.txt, vms/install_vms.txt (Christian) + 7. Remove spaces before tabs. win32/makefile.emx (Christian) + 8. Formatting change. win32/osdep.h (Christian) + 9. If -y on VMS open the link not the target file. vms/vms_im.c (SMS) +10. If -y on VMS search for the link, not the target file. vms/vms_pk.c (SMS) +11. Change default for Unicode path mismatch from error to warning, so + processing will continue. zip.c, globals.c (Ed) +------------------------ March 12th 2007 version 3.0f30 ------------------------ + 1. Add bzip2 support for the reduced no stdio bzip2 library for VMS and Unix. + Use libbz2_ns_.olb for VMS bzip2 library which is compiled from the VMS + version of bzip2 with the BZ_NO_STDIO flag set. This flag removes most + standard bzip2 stdio support and enables using a callback routine for + errors. zbz2err.c, unix/Makefile, vms/build_zip.com, vms/descrip.mms, + vms/descrip_deps.mms, vms/descrip_src.mms (SMS) + 2. Add zbz2err.c to Win32 vc6bz2 project for support of BZ_NO_STDIO for bzip2. + Modify zbz2err.c to handle different ports. zbz2err.c (Ed) + 3. Update license. zip.h (Ed) + 4. Update copyright. zip.c, zipfile.c, zipup.c, zbz2err.c, revision.h (Ed) + 5. Fix bug where directories got set to ver 4.6 in local headers instead of + ver 1.0 when using bzip2. zipfile.c, zipup.c (Ed) + 6. Minor updates to INSTALL. INSTALL (Ed) + 7. Minor updates to README. README (Ed) + 8. Add BZ_NO_STDIO to vc6bz2 projects. Error routine seems to work. + win32/vc6bz2 (Ed) + 9. Set bit FAB$M_BIO (.fab$v_bio) in the FAB when using sys$open() on a + symlink. vms/vms_im.c (SMS) +10. Change sys$disk to SYS$DISK. vms/build_zip.com (SMS) +11. Update extended help. zip.c (Ed) +12. Update bzip2 install. bzip2/install.txt (Ed) +------------------------ March 19th 2007 version 3.0f31 ------------------------ + 1. Define bz2_olb as LIBBZ2_NS.OLB. Change LIBBZ2.OLB to bz2_olb. Use + ZZBZ2ERR.C error callback for bzip2. vms/build_zip.com (SMS) + 2. Change NO_SYMLINK to NO_SYMLINKS to be consistent with UnZip. tailor.h, + acorn/osdep.h, macos/osdep.h, tops20/osdep.h, vms/osdep.h (SMS) + 3. Minor note changes. Add section on Symbolic Links. vms/notes.txt (SMS) + 4. Update copyright. globals.c (Ed) + 5. Update License with official copy. LICENSE (Greg, Ed) + 6. Update Readme. README (Ed) + 7. Add support for NO_BZIP2_SUPPORT. tailor.h (Ed) + 8. Add common compiler flags to Install. INSTALL (Ed) + 9. Remove SPLIT_FILE define. zip.c (Ed) +10. Minor updates to extended help. zip.c (Ed) +11. Modify Makefile to also build bzip2 library if found. Split $MAKE + ("make -f unix/Makefile") into $MAKE and $MAKEF, leaving $MAKE as defined by + Make and defining $MAKEF to "-f unix/Makefile". Add clean_bzip2 target. + unix/Makefile (SMS) +12. Modify configure to handle compiling bzip2. unix/configure (SMS) +13. Remove linking bzip2 with utilities. Other changes. unix/Makefile (Ed) +14. Change bzip2 wrong library errors to warnings. Put back OS bzip2 library + check. Only compile bzip2 if in bzip2 directory. unix/configure (Ed) +15. More modifications to Makefile and configure to only allow compiling in + the bzip2 directory. unix/Makefile, unix/configure (Ed) +------------------------ March 27th 2007 version 3.0f32 ------------------------ + 1. Modify configure and Makefile to only allow compiling bzip2 in the Zip bzip2 + source directory. unix/Makefile, unix/configure (SMS, Ed) + 2. Update bzip2 installation instructions. bzip2/install.txt (SMS, Ed) + 3. Remove need for BZIP2_USEBZIP2DIR define by using an appropiate include dir + specification (-I ../../bzip2) when needed. zip.c, win32/vc6bz2/zip.dsp, + unix/configure (SMS, Ed, Christian) + 4. Update VC6 readme. win32/readmeVC.txt (Christian, Ed) + 5. Add crc32.h to VC projects. Add assembler group to zipcloak, zipnote, and + zipsplit projects. Add BZ_NO_STDIO to all configurations with bzip2 so + reduced bzip2 code is used. win32/vc6/zip.dsp, win32/vc6/zipcloak.dsp, + win32/vc6/zipnote.dsp, win32/vc6/zipsplit.dsp (Christian) + 6. Update VC6bz2 readme. win32/readVCBZ.txt (Christian, Ed) + 7. Modify bzip2 VC6 workspace to use standard zipcloak, zipnote, and zipsplit + projects as they don't need bzip2. win32/vc6bz2/zip.dsw (Christian) + 8. Fix zlib flag problem by properly setting and clearing deflInit flag to + initialize and release resources. zipup.c (Bill Brinzer, Christian) + 9. Update copyright. crypt.h, api.c, tailor.h, fileio.c, ziperr.h, + zipsplit.c, zipnote.c, zipcloak.c, util.c (Ed) +------------------------ April 25th 2007 version 3.0f33 ------------------------ + 1. Fix -dd display_dots option for VMS. Fix adding value for -ds to command + line. Fix /NAMES = AS_IS for older header files. cmdline.c (SMS) + 2. Add Win32 wide scan support. In fileio.c add Win32 wide functions lastw(), + msnamew(), newnamew(), wchar_to_wide_string(), is_ascii_stringw(), + wchar_to_local_string(), and wchar_to_utf8_string(). In globals.c + add no_win32_wide that is true if the wide versions of calls like + GetFileAttributesW() do not work as on Win9x without the Unicode kit. + In tailor.h define zwstat for stats that use wchar_t strings and + defines SSTATW and LSSTATW. In util.c add isshexpw() and recmatchw() + and dosmatchw() for matching using wchar_t strings. In win32.c add + FSusesLocalTimeW(), IsFileSystemOldFATW(), GetFileModeW(), GetLongPathEAW(), + and zstat_zipwin32w(). In win32zip.c add zdirscanw structure, + GetDirAttribsW(), zDIRSCANW, readdw(), wild_recursew(), procname_win32w(), + OpenDirScanW(), GetNextDirEntryW(), CloseDirScanW(), procnamew(), + local_to_wchar_string(), wchar_to_utf8_string(), in wild() code to + check if W versions are supported and send zip down byte or wide path, + ex2inw(), in2exw(), and filetimew(). In zipup.h define zwopen to use + wide paths. In zipup.c if supported use filetimew() and zwopen(). + In zip.h add namew, inamew, and znamew to zlist and flist. In zip.c + remove duplicate initialization of use_wide_to_mb_default, force_zip64, + zip64_entry, and zip64_archive. Use filetimew() if UNICODE_SUPPORT and + using wide paths for directory scan. Remove old 8.3 path Unicode fix as + now use wide paths and get all where the 8.3 kluge missed paths where + characters in path needed multiple code pages. Changes to bit 11 Unicode + but still not ready. fileio.c, globals.c, tailor.h, util.c, zipup.h, + win32/win32.c, win32/win32zip.c, win32/win32.h, zipup.c, zip.c (Ed) + 3. Update copyright. Don't define UNICODE_SUPPORT if already defined. + Define MATCHW and zstat_zipwin32w(). win32/osdep.h (Ed) +------------------------ April 29th 2007 version 3.0f34 ------------------------ + 1. Add temporary option -sC to test Unicode file creation enabled with + UNICODE_TEST define. zip.c, fileio.c (Ed) + 2. On Unix display control characters as ^X as UnZip. (SMS) fileio.c + 3. Update extended help. zip.c (Ed) + 4. Fix bugs in Unicode changes. zip.c, fileio.c (SMS, Ed) + 5. Add NAMES AS_IS support. Handle root dir [000000]. zip.h, + vms/install_vms.txt, vms/vmszip.c, vms/vmsmunch.c (SMS) + 6. Add global zipfile_exists to handle missing zipfile errors better. zip.h, + globals.c, zip.c (Ed) + 7. Add functions utf8_to_escape_string(), wide_to_escape_string(), + local_to_escape_string(), utf8_to_wchar_string(), and + rename wide_to_escape_string() to wide_char_to_escape_string(). fileio.c, + win32/win32zip.c, zip.h (Ed) + 9. Free f->inamew in fexpel(). Use zuname for matching. fileio.c (Ed) +10. Fix memory bug by setting z->namew, z->inamew, and z->znamew to NULL. + Set f->namew, f->inamew, and f->znamew to NULL for new file in newname(). + Free wide_string in local_to_utf8(). Other Unicode fixes. Add namew, + inamew, and znamew to freeup(). fileio.c, win32/win32zip.c, zip.h (Ed) +11. Move wchar functions only used by Windows to win32zip.c. fileio.c, + zip.h (Ed) +12. Fix spelling in manual. zip.1 (SMS, Ed) +13. Add zuebcmp() for Unicode. zipfile.c +14. Open files to read using wide name as input path. zipup.c (Ed) +15. Update help. zip.c (Ed) +16. Change -TT long option from --unzip-path to --unzip-command. zip.c (Ed) +17. Update Manual to include section on Unicode, add -TT option, make some + changes to Unicode in other sections, update copyright at bottom, and + some small changes to wording and examples. man/zip.1, zip.txt (Ed) +18. Put #ifdef WIN32 around WIN32 blocks. zipfile.c (Ed) +------------------------- May 14th 2007 version 3.0f35 ------------------------- + 1. Update VMS to include new options. vms/cmdline.c, vms/zip_cli.cld (SMS) + 2. Update VMS help. vms/vms_zip.rnh (SMS) + 3. Minor updates to VMS help. vms/vms_zip.rnh (Ed) + 4. Create global filter_match_case that defaults to 1 (case-sensitive). zip.c + zip.h, globals.c (Ed) + 5. Add option -fc to fold case for case-insensitive matching in filter(). + Currently enabled only for WIN32. zip.c, win32/osdep.h (Ed) + 6. Change (action == DELETE || action == FRESHEN) to filter_match_case in + PROCNAME() define. I just couldn't figure out what was going on here and + why the case flag was controlled by this. zip.c (Ed) + 7. Update WhatsNew. WHATSNEW (Ed) +------------------------- May 17th 2007 version 3.0f36 ------------------------- + 1. Touch date on generated file. vms/ZIP_MSG.MSG (SMS, Ed) + 2. Update Betas readme to include Release Candidates. Betas_Readme.txt (Ed) + 3. Update Zip 3.0f announcement. zip30f.ann (Ed) + 4. Minor updates to VMS help. vms/cvthelp.tpu, vms/vms_zip.rnh (SMS) + 5. Major changes to VMS CLI help. vms/zip_cli.help (SMS, Ed) + 6. Update license. revision.h (Ed) +------------------------- May 21st 2007 version 3.0f37 ------------------------- + 1. Rename -fc (fold case) to -ic (ignore case) which may be more intuitive. + zip.c (Ed) + 2. VMS CLI updates for new options. vms/cmdline.c, vms/vms_zip.rnh, + vms/zip_cli.cld, vms/zip_cli.help (SMS) + 3. Updates to support Watcom C, mingw, djgppv2 and msc-16-bit, including + supporting wide stat and compare calls and work-around for problem with + "no symlink support" detection. tailor.h, util.c, zip.c, win32/osdep.h, + win32/win32.c, win32/win32/zipup.h (Christian) +------------------------- May 29th 2007 version 3.0f38 ------------------------- + 1. Update description. file_id.diz (Ed) + 2. Handle better when not splitting and run out of disk space. Also, for split + method 1 (automatically write all splits to same place) exit if run out of + space instead of filling available space with near empty splits. For split + method 2 require splits to be at least 64K bytes (the minimum split size). + fileio.c (Ed) + 3. Add line break in ziperr() if message line has been started. zip.c (Ed) + 4. In ziperr() don't close output handle y if same as current_local_file handle + and just closed that. zip.c (Ed) + 5. Change default definition of PROCNAME() to handle new filter_match_case flag + and restore backward compatibility. zip.c (Christian, Ed) + 6. Add note detailing definition of PROCNAME(). zip.c (Ed) + 7. Remove nonlocalpath parameter from procname_win32() and procname_win32w() + and variables nonlocal_path and nonlocal_name as this is not used now that + unicode is implemented in WIN32 using the wide calls. + 8. Enable ignore case option for VMS. zip.c (SMS) + 9. Update -v and other updates in manual. man/zip.1 (Christian, Ed) +10. Updates for Watcom C and Win32 symlinks. win32/osdep.h (Christian) +11. Fix historic problem with VAX seeking. zipfile.c (SMS) +12. Add NAM_M_EXP_DEV. Add determination if device is in file specification. + If device name in file specification do ODS2 and ODS5 down-casing. + Define explicite_dev(). vms/vms.h, vms/vmszip.c (SMS) +------------------------- June 4th 2007 version 3.0f39 ------------------------- + 1. Update osdep.h to use new filter_match_case flag. vms/osdep.h (SMS) + 2. Fix unterminated string bug and trim extra allocated space in + local_to_display_string(). fileio.c (Ed) + 3. Updated extended help for -u and -ic options. zip.c (Ed) + 4. Update Manual. man/zip.1, zip.txt (Ed) +------------------------- June 15th 2007 version 3.0f40 ------------------------- + 1. Update Unicode Path and Unicode Comment descriptions based on suggestions + from WinZip. proginfo/extrafld.txt (Steve Gross, Ed) + 2. Update descriptions for Add, Update, and Freshen in the manual. man/zip.1 + (Christian) + 3. Update default definition of PROCNAME() to use filter_case_match flag to + turn off case matching in filter(). zip.c (Christian) + 4. Update WhatsNew. WHATSNEW (Ed) + 5. Update announcement. zip30f.ann (Ed) + 6. Update manual. man/zip.1, zip.txt (Ed) +------------------------- July 7th 2007 version 3.0f41 ------------------------- + 1. Use File Name as Unicode path if UTF-8 flag is set in header. zip.c, + globals.c, zipfile.c, zip.h (Ed) + 2. Update ToDo. TODO (Ed) + 3. Update WhatsNew. WHATSNEW (Ed) + 4. Update ReadMe. README (Ed) + 5. Fix problems with incompatible stat types on Win32. fileio.c, tailor.h, + zip.h, win32/win32.c, win32/win32zip.c, win32/osdep.h (Ed) + 6. Define NO_STREAMING_STORE to turn off storing while streaming. + INSTALL, zipup.c (Ed) + 7. Define UNICODE_ALLOW_FORCE to enable -UN=force option which is now + disabled and would need work. globals.c, zip.h (Ed) + 8. Add global using_utf8 to flag when OS current character set is UTF-8. + If an existing entry has the UTF-8 flag set the flag is kept. If a new + entry needs Unicode and on a UTF-8 system assume the strings are UTF-8 + and set the UTF-8 flag. globals.c, zip.h (Ed) + 9. Update Unicode extra field descriptions. proginfo/extrafld.txt (Ed) +10. Add include directory so can find bzip2 header file when using bzip2 + directory. unix/configure (Ed) +11. Fix wide character wild(), wild_recursew() and OpenDirScanW() for Win32 so + work like the regular versions. win32/win32zip.c (Ed) +12. Update Unicode in manual. Update -W description in manual zip.1 +13. Flush logfile writing. zip.c (Ed) +14. Update extended help for -UN option. Update help for Update to note it + updates files where the OS has a later date. Chance -UN=Exit to -UN=Quit + so can abbreviate to first letter. zip.c (Ed) +15. Fix a bug in readzipfile() when zip used in pipe. Other pipe fixes. zip.c, + zipfile.c (Ed) +------------------------ August 10th 2007 version 3.0f42 ----------------------- + 1. Update error message for -DF. zip.c (Ed) + 2. Add bzipped message to write to log file. zipup.c (Ed) + 3. Update bzip2 install instructions. bzip2/install.txt (Ed) + 4. Move local.h include to tailor.h to fix compiler multiple define. tailor.h, + zip.c (SMS) + 5. Add additional C compiler checks for GNU and HP. unix/configure (SMS) + 6. Fix to build libbz2.a. unix/Makefile (SMS) + 7. Update copyright. acorn/osdep.h, macos/osdep.h, tops20/osdep.h, + vms/vmszip.c, vms/vmsmunch.c, vms/vms_pk.c, vms/vms_im.c, vms/vms.h, + vms/vms.c, vms/osdep.h, win32/rsxntwin.h, win32/osdep.h, win32/nt.c (Ed) + 8. Change zfeeko(file, 0, SEEK_SET) to rewind(file) in ffile_size() so + EOF is always reset. This was creating problems in WIN32 when + NO_ZIP64_SUPPORT was set but LARGE_FILE_SUPPORT was set. zipfile.c (Ed) + 9. Update compile -v descriptions for LARGE_FILE_SUPPORT and ZIP64_SUPPORT to + be more specific as to what each does. zip.c (Ed) +10. Fix bug that added the local header size to the next entry compressed size + giving a wrong compressed size error if splitting and the split occurs when + writing a local header. fileio.c (Ed) +11. Remove UNICODE_TEST define from VC 6 projects. win32/vc6/zip.dsp, + win32/vc6/zipcloak.dsp, win32/vc6/zipnote.dsp, win32/vc6/zipsplit.dsp (Ed) +12. Update extended help. zip.c (Ed) +13. Only output -FF central directory messages in verbose mode. zipfile.c (Ed) +14. Add note about possible bug when copying entries from a split archive. + WHATSNEW (Ed) +------------------------ August 11th 2007 version 3.0f43 ----------------------- + 1. Display locale inside check to avoid NULL locale. zip.c (SMS, Ed) + 2. Add include wchar.h to tailor.h. tailor.h (SMS) +------------------------ August 21st 2007 version 3.0f44 ----------------------- + 1. Remove verbose messages when setting locale as verbose flag is not set yet. + zip.c (SMS, Ed) + 2. Change reading splits message "abort archive" to "abort archive - quit" and + change selection letter from a to q so q quits consistently. For quit, + don't confirm as more annoying than helpful. fileio.c (Ed) + 3. In bfwrite() handle case where a split ends at the end of one entry and + trying to write the next local header forces opening next split. This + caused copying entries from one archive to another to fail if this came up. + Also handle case where a new split is needed while writing central directory + entries. Now close last split and update pointers to point to the new + split. fileio.c (Ed) + 4. Update use of mesg_line_started and add new logfile_line_started to account + for line ends in logfile. fflush() output. zip.c, zip.h, globals.c (Ed) + 5. Move setting split size if input archive is split and split_size not set + to after archive is read. zipfile.c, zip.c (Ed) + 6. Update Manual to describe Unicode as implemented and note that old splits + are not automatically excluded. man/zip.1, zip.txt (Ed) + 7. Update WhatsNew to remove note that creating and copying split archives + is broke as it seems fully working now. WHATSNEW (Ed) + 8. Update announcement. zip30f.ann (Ed) +------------------------ August 31st 2007 version 3.0f45 ----------------------- + 1. Unicode fix for VMS. tailor.h (SMS) + 2. Add member current to zlist structure to flag when an archive entry is + current with the matching OS file using file time and size. This is used by + File Sync to copy current entries from archive. zip.h, zip.c (Ed) + 3. Comment out zip info verbose extra data message as this message does not + seem to add much. zipfile.c (Ed) + 4. Add local and central directory Version Needed To Extract to mismatch + warning. Update warning text. zipfile.c (Ed) + 5. Add function BlankRunningStats() to output blanks for the running stats + part of the line to use when displaying stats for entries not on the mark + list so all output lines up. zip.c + 6. Add -FS to extended help as new mode. zip.c (Ed) + 7. Update description of -FF to remove Assume Worst. zip.c (Ed) + 8. Add all_current flag that is set if all entries in archive are current and + skip updating archive if -FS and all entries are current. zip.c (Ed) + 9. Change argv[] to args[] for "try: zip" error message as message depends on + new argument order in args where options are now at beginning. zip.c (Ed) +10. For File Sync, copy entries to new archive if file time and size are the + same. If verbose, output ok when copying current entries, otherwise no + message when current_entry. Set all_current to 0 if an entry not marked or + a file not on OS as need to avoid the All Current message in these cases to + catch only deletions. zip.c (Ed) +11. Initialize variables excluding zipstate and setjmp() if USE_ZIPMAIN defined + to fix bug when recall zipmain(). zip.c (Ed) +12. Update Manual. zip.1, zip.txt (Ed) +13. Update WhatsNew. WHATSNEW (Ed) +14. Update announcement. zip30f.ann (Ed) +----------------------- September 5th 2007 version 3.0f46 ---------------------- + 1. Move write of local header after when GPB11 UTF-8 bit set in putlocal(). + zipfile.c (Ed) + 2. Change to uppercase for compatibility. vms/install_vms.txt (SMS) + 3. Set cenbeg and bytes_this_split to fix grow. Check if grow split archive. + zipfile.c, zip.c (Ed) +----------------------- September 14th 2007 version 3.0f47 -------------------- + 1. Include address for new Info-ZIP forum. Add note on 16-bit OS support. + Add note about text file line ends. README (Ed) + 2. Update WhatsNew to include latest on Unicode. Add section on plans for + Zip 3.1. WHATSNEW (Ed) + 3. Minor change in note for Unicode in extended help. zip.c (Ed) + 4. Modify definitions of Unicode extra fields based on discussions with PKWare + and WinZip. proginfo/extrafld.txt (Ed) + 5. Add note on UTF-8 flag. INSTALL (Ed) + 6. Minor updates to ToDo list. Needs more work. TODO (Ed) + 7. Update announcement. zip30f.ann (Ed) + 8. Change definition of IZ_OUR_BZIP2_DIR to be compatible with Configure and + to work with HP-UX. unix/Makefile (SMS) +------------------------ September 24th 2007 version 3.0f --------------------- + 1. Update extended help Unicode description. zip.c (Ed) + 2. Update Readme. README (Ed) + 3. Fix case of define identifying IA64. vms/vms.c (SMS) + 4. Update announcement date. zip30f.ann (Ed) + 5. Update Unicode extra field definitions based on changes proposed for + AppNote. extrafld.txt (Ed) +------------------------ October 17th 2007 version 3.0g01 --------------------- + 1. Can get stuck on open Unix FIFO so default to skip and add option -FI to + enable reading FIFO. Add global allow_fifo. zip.c, zip.h, globals.c + (Willus 0, Ed) + 2. As problems with MinGW with wide-character paths, disable wide-character + Unicode support. zip.c, unix/unix.c (Willus 0, Ed) + 3. Update manual installs to include zipcloak.1, zipnote.1, and zipsplit.1 + pages. unix/Makefile (Ed) + 4. Update Solaris packages. unix/Packaging/pkginfo.in, + unix/Packaging/postinstall, unix/Packaging/preinstall.in, + unix/Packaging/prototype (SMS) +------------------------ October 30th 2007 version 3.0g02 --------------------- + 1. Fix bug in get_in_split_path() where look for .zip split when attempting + to open archives without a .zip extension, even when a single file archive + like jar file. fileio.c (Gabriele (balducci@units.it), Ed) + 2. Fix bug where temp file got created in current working directory on Unix + by giving entire archive path to mkstemp() as template. fileio.c, zip.c + (Willus, Ed) + 3. Use 64-bit output functions for bits_sent. trees.c (SMS) + 4. Add -FF to fixfix -sd messages to make different from identical main + messages. zip.c (SMS, Ed) + 5. If quiet do not ask for splits and all splits must be in same location. + zipfile.c (Ed) + 6. Clean up making zip manuals. unix/Makefile (Ed, SMS) + 7. Add clean_exe to make. unix/Makefile (SMS) + 8. Update to VMS Notes, including adding details on symlinks, -V, and UTC + dates times. vms/notes.txt (SMS) + 9. Fix bug in wild() when calling wile_recursew() where qw should be + pointing inside pw. win32/win32zip.c (Willus, Ed) +10. Fix bug where is_ascii_string() fails when passed a NULL string. This + may fix problem where the CentOS mbstowcs() function is returning -1 when + trying to convert a file name with a bad character (0xe6), causing + local_to_wide_string() and then local_to_utf8_string() to return NULL, so + f->uname gets NULL and so is_ascii_string() fails with SIGSEGV. fileio.c + (Willus, Ed) +------------------------ October 31st 2007 version 3.0g03 --------------------- + 1. Add handling of -b temp directory when opening splits in bfwrite() using + mkstemp(). fileio.c (SMS, Ed) +------------------------ November 3rd 2007 version 3.0g04 --------------------- + 1. Move show_files to global so can avoid split warning for -sf. zip.c, + globals.c, zip.h, zipfile.c (Ed) + 2. Account for -b tempath when opening temp file. zip.c, zipnote.c, + zipcloak.c (SMS, Ed) +------------------------ November 4th 2007 version 3.0g05 --------------------- + 1. Minor fixes to fdopen calls. zipcloak.c, zipnote.c (SMS, Ed) +------------------------ November 4th 2007 version 3.0g06 --------------------- + 1. Add negation to -db, -dc, -dd, -dg, -du, -dv display options. zip.c (Ed) + 2. Put back UNICODE_SUPPORT no_win32_wide code left out in previous fix. + win32/win32zip.c (Willus, Ed) +------------------------ November 21st 2007 version 3.0g07 --------------------- + 1. Fix bug preventing newline in some cases in zipmessage(). zip.c (Ed) + 2. Update Unicode help. zip.c (Ed) + 3. Update -sd messages. zip.c (Ed) + 4. Add filetimew() for Unicode case. zip.c (Ed) + 5. Add ClearArchiveBitW() for Win32 wide. zip.c, zip.h, win32/win32.c (Ed) + 6. Only ask for .zip split if path ends in .znn or .znnn where n 0 to 9. This + allows -FF to work on .exe sfx files without adding .zip. zipfile.c (Ed) + 7. Fix bug where only backed up 20 bytes to find Z64 EOCD Locator. Now back + up 24 bytes to include size of Z64 EOCD Locator signature. This prevented + reading and updating archives greater than 4 GB. zipfile.c (Ed) + 8. If -FF on Win32 initialize wide strings namew, inamew, and znamew to NULL. + zipfile.c (Ed) + 9. Add #include to support towupper(). tailor.h (SMS) +------------------------ December 4th 2007 version 3.0g08 --------------------- + 1. Update dot_size comment. globals.c (Ed) + 2. Update Compression in extended help. zip.c (Ed) + 3. Add extended help on self extractor -A and -J. zip.c (Ed) + 4. Update VMS SYMLINK version information. zip.c (SMS) + 5. Remove not final from Unicode version information as final now. zip.c (Ed) + 6. Remove apparently not needed WINDLL variable retcode. zip.c (Ed) + 7. Fix -A to calculate sfx offset and adjust offsets as it should. zip.c (Ed) + 8. Split -F and -FF used with -A warning to separate warnings. zip.c (Ed) + 9. Add adjusting to can't to that to split archive error. zip.c (Ed) +10. Fix bug for -A that tries to open split by asking for disk 0 instead of + disk 1. Add adjust_offset and cd_total_size variables. Calculate + sfx offset by determining offset of start of central directory. Archives + larger than 4 GB are not supported as sfx archives but these don't seem + to work anyway. Add adjust_offset to Zip64 EOCDR offset and central + directory offsets. zip.c, zipfile.c (Ed) +11. Comment out here debug variable in find_next_signature(). zipfile.c (Ed) +12. Change %2x to %02x as format for parts of a signature in error messages. + zipfile.c (SMS) +13. Add warning adjusting split archives not yet supported. zipfile.c (Ed) +14. Add period to central directory comment. zipfile.c (Ed) +15. Update readme for vb Zip64 project. windll/vbz64/readvb64.txt (Ed) +16. Update comments of VB for Zip64 example. Add SplitSize to VB Zip64 + example. windll/vbz64/vbzipbas.bas, windll/vbz64/vbzipfrm.frm (Ed) +17. Add SourceForge to comment noting where can get the source code. + windll/vbz64/vbzipfrm.frm (Ed) +18. Update WhatsNew. WHATSNEW (Ed) +------------------------ December 12th 2007 version 3.0g09 -------------------- + 1. A few minor changes to extended help. zip.c (Ed) + 2. Uppercase beginning of most -sd messages. zip.c (Ed) + 3. Add spaces between options in some error messages. zip.c (Ed) + 4. Update comments in scanzipf_regnew(). zipfile.c (Ed) + 5. Update scanzipf_regnew() to figure out sfx offset. (Ed) + 6. Uppercase VMS RUNOFF file as apparently needed. VMS_ZIP.RNH (SMS) + 7. Add comments to zipmessage(). zip.c (Ed) + 8. Update extended help and option descriptions. zip.c (Ed) +------------------------ December 20th 2007 version 3.0g10 -------------------- + 1. Fix -F to include -A adjustment check. zipfile.c (Ed) + 2. Change -FF message when find EOCDR. zipfile.c (Ed) + 3. For -FF, reset first CD entry flag in_central_directory when a local entry + is found after CD entries so that another CD entry forces sorting of all + local entries to that point. This allows files with multiple archives in + them to be processed. zipfile.c (Ed) + 4. Add message when a local entry is found after a central directory. + zipfile.c (Ed) + 5. Remove word offset from disk offset location messages. zipfile.c (Ed) + 6. Make Adjust offset message more descriptive. zipfile.c (SMS, Ed) + 7. In scanzipf_regnew(), if adjustment to offsets, add it to + in_cd_start_offset. zipfile.c (Ed) + 8. Allocate cextra only if localz->ext not 0 in zipcopy(). zipfile.c (Ed) +------------------------ December 28th 2007 version 3.0g11 -------------------- + 1. Include definitions of zip64_eocdr_start and z64eocdl_offset in + ZIP64_SUPPORT ifdef block. Add comments for End Of CD Record (EOCDR). + Update comments for adjust offset detection. zipfile.c (Ed) + 2. Change ((uzoff_t)1 << 32) to 0xFFFFFFFF. zipfile.c (SMS, Ed) + 3. Leave off local header detection as not useful when searching for start + of central directory to get adjust offset. Looks like all expected cases + are now covered as long as archive is intact. zipfile.c (Ed) + 4. Update some warning messages. Simplify adjust offset information message. + zipfile.c (Ed) + 5. Add braces to unicode_mismatch if block. zipfile.c (Christian) + 6. Add (void *) cast in InterlockedExchangePointer() mutex calls to fix + compile warnings in MinGW (GCC 3.4.4). win32/nt.c (Christian) + 7. Remove unused nonlocalpath variable. win32/win32zip.c (Christian) + 8. Update betas readme file. betas_readme.txt (Ed) + 9. Partial update to Who list of contributors. proginfo/infozip.who (Ed) +10. Update ReadMe. Create Announcement. README, zip30g.ann (Ed) +11. Update WhatsNew. WHATSNEW (Ed) +------------------------ January 7th 2008 version 3.0g12 -------------------- + 1. Convert Scanning files message to use standard zipmessage_nl() so line + ends are generated when needed. fileio.c (Ed) + 2. Add line ends in DisplayRunningStats() if a display line has been + started. zip.c (Ed) + 3. For the command line listed at the top of the log file, add double + quotes around any arguments that have spaces in them. + zip.c (Ed) + 4. Instead of stdout use standard mesg output stream for show files. + Output new line for show files for display and log file if there was + output on the current line. zip.c (Ed) + 5. Comment out new line output code after zipup() and replace with + call to zipmessage_nl("", 1) to output new line if needed. + zip.c (Ed) + 6. In GetFileMode() and GetFileModeW() when get attributes fails + instead of fprintf(mesg, ...) use zipwarn() so error goes in + log file and new lines are displayed when needed. win32/win32.c (Ed) + 7. In GetSD(), change cbytes from long to ulg. Check cbytes (the + compressed size of the security descriptor) and issue warning if + the compressed security descriptor is greater than 0x7FFF (32k) + as the entire header this extra field is in needs to fit in the + 64k header. Should be a check on the running size of the header + so the actual space remaining is tracked. Maybe in Zip 3.1. If + cbytes OK cast to ush and store. win32/win32zip.c (Ed) + 8. Use zipmessage_nl() for bytes security message so new lines are + handled and message goes in log file. win32/win32zip.c (Ed) + 9. Add new option -RE to enable [list] (regex) matching in DOS and + WIN32 but disable [list] matching otherwise. Default behavior + is restored if ALLOW_REGEX is defined. globals.c, util.c, + zip.h, zip.c (Ed) +------------------------ January 20th 2008 version 3.0g13 -------------------- + 1. Update copyrights to 2008. zip.c, zipcloak.c, zipfile.c, zipnote.c, + zipsplit.c, zipup.c, README (Ed) + 2. Update Who. proginfo/infozip.who (Ed) +------------------------ January 30th 2008 version 3.0g14 -------------------- + 1. Update copyrights. fileio.c, globals.c, revision.h, util.c, zip.h, + win32/win32.c, win32/win32zip.c (Ed) + 2. Updates. README, proginfo/infozip.who (Ed) + 3. Update announcement and WhatsNew. zip30g.ann, WHATSNEW (Ed) + 4. Add ALLOW_REGEX to INSTALL define list. INSTALL (Ed) + 5. Change -sd message. zip.c (Ed) + 6. For bzip2 check for binary and set binary/text flag. Handle -l and -ll + line end conversions for bzip2. zipup.c (Ed) +------------------------ February 3rd 2008 version 3.0g -------------------- + 1. Change && to || to fix logic bug in show files. zip.c (Johnny) + 2. Add CLEAN and CLEAN_ALL VMS targets. vms/descrip_mkdeps.mms (SMS) +----------------------- February 22nd 2008 version 3.0h01 -------------------- + 1. Update some echo statements to use CFLAGS_OPT. Add GNUC check. + unix/configure (SMS) + 2. Only store UID and GID if 16 bit. unix/unix.c (Ed) +----------------------- March 21st 2008 version 3.0h02 -------------------- + 1. Change long Unicode escapes from 8 characters to 6 characters based on + change in UnZip 6.0. fileio.c (Ed) + 2. Put zuebcmp() declaration in #if 0 block as definition already is. This + function would be used to allow Unicode escapes on the command line + without using the -UN=escape option, but the utility of this is still + being determined. zipfile.c (SMS, Ed) + 3. Remove declaration for unused bz_deflate_init(). zipup.c (SMS, Ed) + 4. Add release announcement file, anticipating the long-awaited release. + zip30.ann (Ed) + 5. Update WhatsNew. WHATSNEW (Ed) +----------------------- March 24th 2008 version 3.0h03 -------------------- + 1. Update Unix configure script to better test for modern HP-UX compiler. + unix/configure (SMS) + 2. Updated Beta Readme. betas_readme.txt (Ed) + 3. Update Install. INSTALL (Ed) + 4. Update ReadMe. README (Ed) + 5. Small change to main help screen. zip.c (Ed) + 6. Small update to top of ToDo list. Actual updating of items still + needs to be done. TODO (Ed) +----------------------- April 2nd 2008 version 3.0h04 -------------------- + 1. Update copyright. crc32.h (Christian) + 2. Remove zip.h include. crc32.h (Christian) + 3. Add local prototypes for Unicode functions. Add cast for split size + check. Make many Unicode functions local. #if 0 out currently unused + utf8_chars(). Fix memory leak in wide_to_local_string() by adding + free() for buffer on error return. Fix memory leak in copy_args() on + error return by adding free-args(). Add ZCONST to arg in + insert_arg(). Shorten some lines to less than 80 characters. Add + free() to get_longopt() to fix memory leak. fileio.c (Christian) + 4. Create Win32 versions of wide_to_local_string() and + local_to_wide_string() so can use Win32 conversion functions. + fileio.c, win32/win32.c (Christian) + 5. Update comments for get_option(). fileio.c (Ed) + 6. Update encryption code readme. README.cr (Ed) + 7. Add prototype for recmatchw(). util.c (Christian) + 8. Change count_args() from static to local. util.c (Christian) + 9. Change ifdefs for includes for prototypes for version_info(), + zipstdout(), and check_zipfile() for WINDLL and MACOS and add + check_unzip_version(). zip.c (Christian) +10. Change ifndef NO_SYMLINKS to ifdef S_IFLNK for determining compiler + information. zip.c (Christian) +11. Change UTF-8 locale from en_GB.UTF-8 to .UTF-8. zip.c (Christian) +12. Change cast of -1 for dot_size from uzoff_t to zoff_t. + zip.c (Christian) +13. Change prototype for set_filetype to include parameter char *. + Change prototype of has_win32_wide to include parameter void. + zip.h (Christian) +14. Add prototypes for find_next_signature(), find_signature(), + and is_signature(). Change duplicate prototype scanzipf_regnew() + to missing prototype scanzipf_fixnew(). Change comment for Adler-16 + checksum to CRC-32 checksum as that is being used at that point in + the code. Move multiple uname assignments to common assignment. + Add inameLocal for WIN32_OEM and use define for inameLocal if not + to save memory allocation when not not using WIN32_OEM. Also + change _INTERN_OEM(str1) to INTERN_TO_OEM(src, dst) for OEM + conversion. Format comment for vem to fit in 80 character lines. + zipfile.c (Christian) +15. Change variable a from buffer to a pointer and add abf as the + buffer for zgetline() to handle NULL case. zipnote.c (Christian) +16. Change comments to zipentry comments and zipfile comment in + messages. zipnote.c (Ed) +17. Use uidgid_16bit as flag variable instead of uid_size. Modify + size check that prevents saving Unix UIDs and GIDs in the old + Unix extra field if they are not 16 bits. Change memory + allocation based on uidgid_16bit. Delete unused code for memory + copy for extra field. unix/unix.c (Christian, Ed) +18. Change compiler flag from -zp8 to -Zp8 for LCC Win32. + win32/makefile.lcc (Christian) +19. Add ifndef debug. Add bzip2 support. Add additional compiler + flags. win32/makenoas.w32 (Christian) +----------------------- April 10th 2008 version 3.0h05 -------------------- + 1. Fix bug found by forum poster where Zip stops recursing down a tree + when option -AS is set and a directory without the Windows archive + bit is reached. Now Zip continues down the tree to include files with + the bit set. win32/win32zip.c (forum poster, Ed) + 2. Update comments. win32/osdep.h (Ed) + 3. Update VMS notes to better organize and add information about file + name case. Additional small updates. vms/notes.txt (SMS) + 4. Fix bugs from previous changes to unix. unix/unix.c (SMS, Christian, + Ed) + 5. Add unix IBM support. unix/unix.c (SMS) + 6. Update INSTALL to account for new distribution structure and other + changes. INSTALL (SMS, Ed) + 7. Update bzip2 install readme. bzip2/install.txt (SMS, Ed) + 8. Fix bug noted in forum where -@ and -x generated a "nothing to + select from error" by also checking filelist variable populated by + -@ for entries. zip.c (forum poster, Ed) +----------------------- April 20th 2008 version 3.0h06 -------------------- + 1. Start announcement for Zip 3.0h public beta. zip30h.ann (Ed) + 2. Update beta readme. betas_readme.txt (Ed) + 3. Update case of README.CR. INSTALL (Ed) + 4. Change -W to -ws for option to stop wildcards from scanning directory + boundaries in path. This frees up -W for later use, maybe as extendted + option introducer. zip.c, man/zip.1 (Ed) + 5. Updated date in announcement to May 4th. zip30.ann (Ed) + 6. Added announcement for public beta Zip 3.0h. zip30h.ann (Ed) + 7. Fix large file support for MinGW by checking for compiler environments + before the check for (generic) gcc. zipup.c, win32/osdep.h + (Will, Christian) + 8. Fix large file support for bzip2. Additionally, the "dot printout" + code has also been adapted for LARGE_FILE support. zipup.c + (Will, Christian) + 9. Add comments to top of configure. unix/configure (Ed) +10. Move comment and comment out value size check for UID/GID extra field. + unix/unix.c (Ed) +11. Change case of file ToDo to TODO for consistency and to work with Unix + package. TODO (SMS, Ed) +----------------------- April 26th 2008 version 3.0h07 -------------------- + 1. For -AS, which for Windows only includes files with the archive bit + set, exclude directory entries (by setting -D) as some directories may + not have any files with the archive bit set and so the directory would + be empty. zip.c (Ed) + 2. Fix UID/GID size detection to use byte sizes and remove data fit test. + unix/unix.c (Ed) + 3. Update announcement. zip30h.ann (Ed) + 4. Add new unix extra field with tag 'ux' that stores UIDs/GIDs of 1 to 4 + bytes (8 to 32 bits). unix/unix.c (Ed) + 5. Update VB readme. windll/vbz64/readVB64.txt (Ed) + 6. For Unicode escaped output also show escape for ASCII 7-bit if + isprintable() is false. fileio.c (Ed) + 7. Use locale "en_US.UTF-8" for Unix. zip.c (Ed) + 8. Also show escaped Unicode for new files in found list. zip.c (Ed) + 9. Update manual. man/zip.1, zip.txt (Ed) +------------------------ May 4th 2008 version 3.0h08 ----------------------- + 1. Handle when a bad Unicode string in archive forces + utf8_to_wide_string() to return a NULL string. Give warning if UTF-8 + in existing archive is bad. Put WIN32 wide local header initializations + in UNICODE_SUPPORT block. fileio.c, zipfile.c (Ed) + 2. Leave out Unicode escape code if not Unicode enabled. zip.c (Ed) + 3. Enable oem_to_local_string() and local_to_oem_string() for WIN32 + even if no Unicode. zip.h, win32/win32.c (Christian, Ed) + 4. Update comment about encryption code. zipcloak.c (Ed) + 4. Update zipmessage_nl() and zipmessage() from zip.c. zipcloak.c, + zipnote.c, zipsplit.c (Ed) + 5. Add Mac OS X library check. unix/configure (SMS) + 6. Add 16-bit UID/GID check. unix/configure (Christian, Ed) + 7. Format echo and comment statements a bit. unix/configure (Ed) + 8. Only compile in old 16-bit UID/GID code if new define UIDGID_NOT_16BIT + from unix configure script is not defined. unix/unix.c (Christian) + 9. A couple changes to updated 16-bit UID/GID code. Add 64-bit + UID/GID support to new Unix extra field. unix/unix.c (Ed) +10. Remove redundant "license" from options table. zipcloak.c (Ed) +11. Remove old unix build files. unix/configure-orig, unix/Makefile-orig + (Christian) +12. Add -O (--output-file) option to ZipCloak. Fix bug by setting + out_path. zipcloak.c (Ed) +------------------------ May 8th 2008 version 3.0h09 ----------------------- + 1. Update copyright. Add check for NO_UNICODE_SUPPORT. tailor.h (Ed) + 2. Fix bug where Unicode General Purpose Bit Flag 11 should force keeping + the old name field but it was being overwritten by the escaped name + in the central directory header. Fixed some ZIPERR() calls in + putcentral() that referred to putlocal(). zipfile.c (Ed) + 3. Add comment about OCRCU8 and OCRCTB. unix/configure (Ed) + 4. Change line in instructions to note that manuals should be made after + Zip is made. Change OCRTB to OCRCTB. Add $(OCRCTB) to rule for + zipcloak$E so crc32_.o is linked in. Add comment for NO_UNICODE_SUPPORT + flag. unix/makefile (Ed) + 5. Update WhatsNew. Add additional items to the Zip 3.1 list. Add note + about Zip 2.4. WHATSNEW (Ed) + 6. Update Zip 3.0h announcement. zip30h.ann (Ed) + 7. Update manual pages. man/zip.1, man/zipsplit.1, man/zipnote.1, + man/zipcloak.1 (Ed) + 8. Add noted for UTF-8 locale. zip.c (Ed) + 9. Set UTF-8 locale for Unix in utilities if UNICODE_SUPPORT enabled + so can display and process paths in archives correctly. zipsplit.c, + zipcloak.c, zipnote.c (Ed) +------------------------ May 12th 2008 version 3.0h10 ---------------------- + 1. Add use of new Unix UID/GID extra field and of old Unix 16-bit UID/GID + extra field when system uses 16-bit UIDs/GIDs to version information. + zip.c (SMS, Ed) + 2. Add Unicode Path and Unicode Comment extra fields to extra fields list. + Update new Unix extra field revision date. proginfo/extrafld.txt (Ed) + 3. Add Mac hardware platform to version information. unix/unix.c (SMS) +------------------------ May 19th 2008 version 3.0h11 ---------------------- + 1. Initialize f->namew when streaming stdin to fix bug. fileio.c (Ed) + 2. Change force_zip64 to start as -1 as unset, then use 1 for forcing use + of Zip64 and 0 for disabling use of Zip64. Add negation of -fz to + prevent use of Zip64 during streaming from stdin to a non-seekable + output where data descriptors will be used, which allows creating + archives with the old stream format but will fail if a large file is + streamed. Default is still to force Zip64 data descriptors when + streaming, which covers all cases but requires a Zip64 compatible + unzip. zip.c, globals.c, zipfile.c (Ed) + 3. Handle case of bad Unicode in archive. zipfile.c (Ed) +------------------------ May 22nd 2008 version 3.0h12 ---------------------- + 1. Fix bug introduced last beta that prevented streaming large files. Use + separate error message depending on if -fz- was used. zipfile.c (Ed) + 2. Change non existent to nonexistent. unix/configure (SMS) + 3. Don't output blank line when zipmessage_nl() gets passed an empty + string. This removes blank lines for skipped entries when -FS used. + zip.c (Ed) +------------------------ May 27th 2008 version 3.0h13 ---------------------- + 1. Change UNICODE_ALLOW_FORCE to UNICODE_SUPPORT, -UN=force to -UN=UTF8, + and unicode_force to utf8_force. This option now standard with Unicode + support and forces Zip to save UTF-8 paths and comments, when not ASCII, + as if UTF-8 were the native character set. globals.c, zip.c, zip.h (Ed) + 2. Add note to Todo that it's out of date. TODO (Ed) + 3. Update WhatsNew. WHATSNEW (Ed) + 4. Update Unicode help in extended help. zip.c (Ed) + 5. Update announcements. zip30h.ann, zip30.ann (Ed) + 6. Fix bug with -UN=UTF8. zip.c, zipfile.c (Ed) + 7. Update Zip manual. man/zip.1, zip.txt (Ed) + 8. Attempt an update to zip limits document. proginfo/ziplimit.txt (Ed) + 9. Update README regarding forum postings. README (Ed) +10. Remove duplicate initialization lines for found and fnxt. zip.c (SMS) +------------------------ May 28th 2008 version 3.0h14 ---------------------- + 1. Remove >= 0 check from wide character check as value is unsigned. + fileio.c (SMS) + 2. In putlocal(), move nam and use_uname to UNICODE_SUPPORT block. If + no UNICODE_SUPPORT use z->nam instead of nam. zipfile.c (SMS, Ed) + 3. Update announcement date for beta. zip30h.ann (Ed) +------------------------ May 31st 2008 version 3.0h ------------------------ + 1. In putlocal() if using UTF-8 bit then also set UTF-8 bit in z->lflg so + is set in local header for streaming. zipfile.c (Ed) + 2. Update announcement date for beta. zip30h.ann (Ed) + 3. Rename lib and dll projects to zip32z64 and update project files so + project name is same as lib and dll libraries. Export make files. + windll/visualc/dll/zip32z64.dsp, windll/visualc/dll/zip32z64.dsw, + windll/visualc/dll/zip32z64.mak, windll/visualc/libzip32z64.dsp, + windll/visualc/libzip32z64.dsw, windll/visualc/libzip32z64.mak (Ed) +------------------------ June 7th 2008 version 3.0i01 ---------------------- + 1. Update Mac ReadMe to note Mac OS X uses Unix port. macos/readme.1st (Ed) + 2. Change UNIX to Unix in manual. Update dates in manual and add note + about Mac OS X. Change switch to switches. zip.1 (SMS, Ed) + 3. Add version information under Windows by adding a version resource. + win32/vc6/zip.dsp, win32/vc6bz2/zip.dsp, win32/zip.rc (Ed) +------------------------ June 15th 2008 version 3.0i02 ---------------------- + 1. Update Install instructions. INSTALL (Ed) + 2. Update ReadMe. README (Ed) + 3. Update ToDo list. TODO (Ed) + 4. Update WhatsNew. WHATSNEW (Ed) + 5. Add note to WHERE. WHERE (Ed) + 6. Update announcement. zip30.ann (Ed) + 7. Review man pages and update Zip man page. Compile text files from man + pages. man/zip.1, zip.txt, zipnote.txt, zipsplit.txt, zipcloak.txt (Ed) + 8. Update extended help. zip.c (Ed) +------------------------ June 17th 2008 version 3.0i03 ---------------------- + 1. Fix bug where UTF-8 flag was not being set when using_utf8 was set as + result of UTF-8 being current character set. zipfile.c (Ed) + 2. Update man page globbing description. man/zip.1, zip.txt (SMS, Ed) + 3. Update web address to bzip2 package for VMS. vms/install_vms.txt (SMS) +------------------------ June 21st 2008 version 3.0i04 ---------------------- + 1. Update comments. zbz2err.c (Christian) + 2. Put use_uname in UNICODE_SUPPORT block. zipfile.c (Christian) + 3. Increase st to 0x1400. msdos/makefile.msc (Christian) + 4. Update copyright and put @CodeSize and @DataSize into ifndef blocks for + Huge, Large, Compact, Medium, and Small. msdos/match.asm (Christian) + 5. Add check to disable symbolic links. msdos/osdep.h (Christian) + 6. Put Mac OS X compiler check into if Mac OS X block to avoid problems on + some other Unix ports with the check. unix/configure (SMS) + 7. Move set_extra_field() to fix compile problem. unix/unix.c (SMS) + 8. Update USEBZIP2 to USEBZ2 and -DUSE_BZIP2 to -DBZIP2_SUPPORT. Drop + -DMSDOS compile flag. win32/makefile.w32 (Christian) + 9. Change BZIP2_SUPPORT to USEBZ2. win32/makenoas.w32 (Christian) +------------------------ June 23rd 2008 version 3.0i05 ---------------------- + 1. Update and unify resources. Remove any MFC dependencies from the resource + files zip.rc and windll.rc. win32/zip.rc and windll/windll.rc now read + the version info from revision.h. windll.rc internal flags modified to + "32-bit dll". zip.rc internal flags liberated from "winnt 32-bit" + to "generic 32-bit windows". Win32 zip.exe also supported on Win9x + (32-bit). Update makefiles for Borland, MSC, GCC(mingw32), Watcom + to support inclusion of zip.rc version resources into zip.exe binary. + revision.h, msdos/osdep.h, win32/makefile.bor, win32/makefile.gcc, + win32/makefile.w10, win32/makefile.w32, win32/makefile.wat, + win32/makenoas.w32, win32/zip.rc, windll/windll.rc (Christian) + 2. Remove unused files. win32/resource.h, windll/resource.h, + windll/windll.aps, windll/zipver.h, windll/visualc/dll/zip32z64.mak, + windll/visualc/lib/zip32z64.mak (Christian) + 3. Update VMS. vms/descrip_deps.mms (SMS) +------------------------ June 26th 2008 version 3.0i06 ---------------------- + 1. Update Install and Readme in preparation for release. Update WhatsNew. + INSTALL, README, WHATSNEW (Ed) + 2. Update announcement. zip30.ann (Ed) + 3. Update original Visual Basic project comments and documentation. + windll/vb/readmevb.txt, windll/vb/vbzip.vbp, windll/vb/vbzip.vbw, + windll/vb/vbzipbas.bas, windll/vb/vbzipfrm.frm (Ed) + 4. Add bzip2 version of djgpp 2.x makefile thanks to Robert. Assumes a + standard djgpp installation. msdos/makebz2.dj2 (Robert Riebisch, Ed) +------------------------ June 27th 2008 version 3.0i07 ---------------------- + 1. Add DJGPP to bzip2 install instructions. bzip2/install.txt, + msdos/makebz2.dj2 (Robert, Ed) +------------------------- July 5th 2008 version 3.0 ------------------------- + 1. Add -sd to extended help. zip.c (Will, Ed) + 2. Fix memory bug when rebuilding Zip64 central directory extra field which + can crash MinGW and other ports when processing large files. zipfile.c + (Will) + 3. Fix -v bug preventing display of version information when options in + environment variables. zip.c (Ed) + 4. Update WhatsNew. WHATSNEW (Ed) + 5. Update announcement. zip30.ann (Ed) diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..be3e0c5 --- /dev/null +++ b/INSTALL @@ -0,0 +1,368 @@ +HOW TO INSTALL ZIP + + Zip is distributed as C source code that can be compiled on a + wide range of systems: Unix, VMS, MSDOS, OS/2, NT, Amiga, Atari, + BeOS, VM/CMS, ... You will need Unzip 5.0p1 or later (under any + system) or PKUNZIP 2.04g or later (under MSDOS) to unpack the + distribution file, in this case zip30.zip. But since you read this, + you have unpacked it already, or you cheated and got a tar.Z file... + + Note: Zip 3.0 distribution kits (unlike previously distributed + Zip 2.x kits) are created with a top-level directory ("zip30") in + the archive, making the creating of the zipsrc directory optional. + +Installation on Unix (see below for installation on other systems) + + Let's assume that you start from scratch and have not yet unpacked + the sources. First step, then, is to unpack Zip. The following + assumes that you have zip30.zip in the current directory. + + For example, to extract to a new zipsrc directory (assuming + zip30.zip is in the current directory): + + mkdir zipsrc + cd zipsrc + cp ../zip30.zip . + unzip zip30.zip + cd zip30 + + To extract in an existing directory, such as /usr/local/src/zip: + + cd /usr/local/src/zip + (copy zip30.zip here) + unzip zip30.zip + cd zip30 + + The first extracts all source files and documentation to the + directory "zipsrc/zip30". The second places the zip30 directory + in the "/usr/local/src/zip" directory. Both then cd in to the + zip30 directory where Zip will be built. + + Note: This release now includes the standard encryption code + previously in the separate package zcrypt29.zip, but you still + can decide whether to activate the crypt code or not. Crypt is + enabled by default, but you may disable it by specifying the + option -DNO_CRYPT in the LOCAL_ZIP environment variable (or by + adding this option to the compilation options in the appropiate + makefile). See README.CR for more on crypt. + + You then do: + + make -f unix/Makefile system + + where "system" is one of: generic, generic_gcc, + att6300, coherent, cray_v3, minix, sco_x286, xenix, zilog. + + For Unix systems where "cc" is the preferred C compiler command, + try + + make -f unix/Makefile generic + + first. If "gcc" is preferred, specify "generic_gcc" instead of + "generic". This should work on most systems and automatically + selects compilation options based on a set of tests (in + unix/configure), including detection of large file support + sufficient to enable Zip64 large archive features. If "generic" + (or "generic_gcc" if that is used) fail, then one of the special + targets given above may work. + + Among other special systems are Cray Unicos, Zilog Zeus and MINIX. + + The optimization settings for many systems should be close, but + if you see optimization for your system is not ideal, send in + the changes so we can improve it. + + By default, Zip uses the "deflate" compression method. To add + the additional optional "bzip2" compression method, see the file + bzip2/install.txt. Note that bzip2 support is provided by + compiling or linking in the bzip2 library. See the bzip2 site + (http://www.bzip.org/) for more on bzip2. + + If you get error messages such as "constant expected" in + deflate.c, add -DDYN_ALLOC to CFLAGS in your makefile entry. + + If you have lots of memory, try compiling with -DBIG_MEM. If your + system supports mmap(), try compiling with -DMMAP. This generally + gives faster compression but uses more memory. See the unix/Makefile + entry mmap_gcc for an example. + + If none of these compiles, links, and functions properly on + your Unix system, then your system apparently has specific + requirements we did not account for. See the file README for how + to get help. + + If the appropriate system was selected, then the executables zip, + zipnote, zipcloak, and zipsplit will be created. You can copy + them to an appropriate directory in the search path using: + + make -f unix/Makefile install + + The defaults are /usr/local/bin for the executables and + /usr/local/man/man1 for the manual pages. Change the macros + BINDIR and MANDIR in makefile to change these if needed. + + If necessary, add the directory with the Zip executables to your + shell's PATH (or "path") variable. (C-shell users may need to + use the "rehash" command so csh can find the new command in the + path.) You should now be ready to use Zip. + + You can get rid of the now unnecessary source and object files + with: + + cd .. + rm -r zip30 + + This will remove the directory zip30 and its contents created + by unzip. You should keep the zip30.zip file around though, + in case you need to build it again or want to give it to a + colleague. + + You can add the following lines to the file /etc/magic for + usage by the 'file' command: + +0 string PK Zip archive +>4 byte 011 (at least v0.9 to extract) +>4 byte 012 (at least v1.0 to extract) +>4 byte 013 (at least v1.1 to extract) +>4 byte 024 (at least v2.0 to extract) +>4 byte 025 (at least v2.1 to extract) + + +Installation on other systems + + The steps for installation under VMS, MSDOS, OS/2, NT, Amiga and + Atari are similar to the above: first unzip the distribution + files into their own directory. The system-dependent files are + stored in special subdirectories. + + For all the non-Unix ports which support the creation of "UT" extra + fields (these ports contain USE_EF_UT_TIME in the list of optional + features displayed with "zip -v"), the timezone environment variable TZ + should be set according to the local timezone in order for the -f, -u, + -o, and similar options to work correctly. This is not needed for the + WIN32 and WinDLL ports, since they get the timezone information from + the OS by other means. + + + MSDOS: + + Do one of: + + make msdos\makefile.msc (Microsoft C 5.1) + nmake -f msdos\makefile.msc (Microsoft C 6.0 and newer) + make -fmsdos\makefile.bor -DCC_REV=1 (Borland Turbo C++ 1.0) + make -fmsdos\makefile.bor (Borland C++ 2.0 and newer) + make -fmsdos\makefile.tc (Borland Turbo C 2.0x) + make -f msdos/makefile.dj1 (DJGPP v1.12m4) + make -f msdos/makefile.dj2 (DJGPP v2.01 and newer) + make -f msdos/makefile.emx (gcc/emx 0.9b and newer) + make -f os2/makefile.os2 gccdos (gcc/emx 0.9b and newer) + wmake -f msdos\makefile.wat (Watcom C 11.x 16-bit) + wmake -f msdos\makefile.wat PM=1 (Watcom C 11.x 32-bit, PMODE/W) + + for Microsoft, Borland C++ and Turbo C, Watcom C/C++ and the various + free GNU C implementations, respectively. More detailed instructions + can be found in the respective makefiles. + + + WIN32 (Windows NT/2K/XP/2K3 and Windows 95/98/ME): + + Supported compilers are Microsoft Visual C++, Borland C++, Watcom C/C++, + and miscellaneous free GNU C implementations (gcc/mingw, CygWin, ...). + The makefiles supplied in the win32/ subdirectory contain further + information. + + + Windows DLL (WIN32): + + Supported environments are Visual C++ (32-bit only, 5.x and newer). + For instructions how to build the DLLs and where find the makefiles, + look into windll/contents. + + + OS/2: + + Type + + {make} -f os2/makefile.os2 + + to get a list of supported targets/compiling environments. + (replace "{make}" with the name of your OS/2 make utility.) + + To initiate the actual compiling process, you have to specify + a system target: + + {make} -f os2/makefile.os2 {system} + + An example: type + + nmake -f os2/makefile.os2 msc + + for Microsoft C 6.00. + + + VMS (OpenVMS): + + The most complete information on building and installing Zip on VMS + is in [.vms]install_vms.txt. Optimists in a hurry may wish to try + commands like these: + + @ [.VMS]BUILD_ZIP.COM + or: + MMS /DESCRIP = [.VMS]DESCRIP.MMS CLEAN ! Or MMK ... + MMS /DESCRIP = [.VMS]DESCRIP.MMS ! Or MMK ... + + When the executables have been created (or located if already installed), + most users define foreign command symbols for the Zip executables, like + this: + + ZIP :== $ dev:[dir]ZIP.EXE ! UNIX-like command line. + or: + ZIP :== $ dev:[dir]ZIP_CLI.EXE ! VMS-like command line. + + Such symbol definitions are often added to a user's + SYS$LOGIN:LOGIN.COM procedure, or to a common, site-specific + procedure, like SYS$MANAGER:SYLOGIN.COM. + + Additional installation options are described in install_vms.txt. + + The builders create help text files, ZIP.HLP and ZIP_CLI.HLP. Also + see install_vms.txt for how to create the help libraries. + + +Mac OS: + + Mac OS X is part of the Unix port, so use the Unix installation above. + + Mac OS before Mac OS X use the Mac OS port, though little testing has + been done for that port recently. See macos/README.TXT for more on + this port. + + +Compiler Flags + + Zip should compile fine out of the box for your port. In particular, + for Unix the command + make -f unix/Makefile generic + should automatically detect the features available on your system and + set the flags appropriately. In some cases, however, you may need to + set one or more compiler flags yourself to get Zip to compile or to + add features you want or remove features that cause trouble for your + port. Below are the more common compiler macros you can set. + + LARGE_FILE_SUPPORT + Tell Zip that the OS supports large files (generally files larger + than 4 GB). Zip will try to compile in the large file calls + (typically 64-bit) for the OS instead of using the standard + (typically 32-bit) file calls. On Unix Zip tries to switch over to + the 64-bit file environment. If setting this flag causes errors + or Zip still can't handle large files on that port, then probably + either Zip doesn't have the code to support large files on your OS + (write a patch and send it in to us) or your OS doesn't support large + files. + + Note that the flag ZIP64_SUPPORT must also be set to create archives + with large files. + + This flag should be set automatically on Unix, Win32, and some + other ports. Setting NO_LARGE_FILE_SUPPORT turns this flag off. + + ZIP64_SUPPORT + Enable the Zip64 code in Zip that supports the Zip64 extensions noted + in the PKWare AppNote. These extensions allow storing files larger + than 4 GB in archives and the creating of archives larger than 4 GB. + They also allow storing more than 64K files in an archive. Currently + Zip does not handle archives of PKZip version 4.5 or later unless + this flag is set. + + To enable large file support in Zip, you generally need to set both + LARGE_FILE_SUPPORT (to read and write large files) and ZIP64_SUPPORT + (to store them in and read them from archives). Files larger than + 4 GB may be invisible to Zip (directory scans don't see them) if + LARGE_FILE_SUPPORT is not enabled. + + Keeping LARGE_FILE_SUPPORT and ZIP64_SUPPORT separate allows easier + debugging of these features. When testing large file support on an + OS, first set just LARGE_FILE_SUPPORT to test the file calls (all + should compile and work as before with small files), then turn on + ZIP64_SUPPORT to let Zip recognize and handle large files. + + This flag should be set automatically on most ports if + LARGE_FILE_SUPPORT is set. Setting NO_ZIP64_SUPPORT turns this flag + off. + + UNICODE_SUPPORT + Enable storing and using UTF-8 paths. These paths are stored in + a backward-compatible way so that archives with UTF-8 paths still + work on zips and unzips that don't support Unicode. This support + follows the recent additions to the PKWare AppNote for Unicode + support, except that Unicode comments on systems where UTF-8 is + not the current character set is not implemented in this release. + + On some ports UNICODE_SUPPORT is set automatically if wide characters + are supported. Setting NO_UNICODE_SUPPORT turns off this flag. + + USE_EF_UT_TIME + Enables storing UT time in an extra field. This becomes useful + for ports that normally store file times as local time, resulting + in problems when files are moved across time zones and when + there are daylight savings time changes. Zip and UnZip will + automatically correct for time zone changes when UT time is stored. + + This is usually set by default. Use NO_EF_UT_TIME to turn this off. + + NTSD_EAS (Win32 only) + Enable storing Windows NT file security descriptors. This allows + restoring the descriptors (file ACL's, etc.). + + This is on by default for Win32. Use NO_NTSD_EAS to turn this off. + + BZIP2_SUPPORT + Enable compressing zip entries using the bzip2 library. You must get + the bzip2 library from somewhere else as we only provide a way to + compile or link the library in and compress files using bzip2. Enables + a new compression method, bzip2, that can be used instead of the default + Zip compression method deflate. + + This flag is set on Unix, including Mac OS X, when compiling using + generic if the bzip2 library is found. Set on Win32 if the bzip2 + projects are used. See the VMS documentation for when VMS sets this + flag. Setting NO_BZIP2_SUPPORT turns this off. + + See bzip2/install.txt for more on installing bzip2 support. + + WIN32_OEM (Win32 only) + Enable saving paths on Win32 in the OEM character set. Zip has stored + paths using the standard ANSI local character set, but other zips have + used the OEM character set on MSDOS and Win32. This flag should make + Zip more compatible with other DOS and Win32 zips and unzips. It also + enables the translation of OEM paths in DOS archives to ANSI and should + eliminate some problems with funny characters showing up in path names. + + If Unicode is enabled and used, Unicode paths generally override + local paths using OEM character sets. + + This flag is on by default on most Win32 ports. Some ports apparently + have problems with OEM conversions. If your port or compiler does + funny things with file names, you may want to turn this off. Defining + NO_WIN32_OEM turns this flag off. + + NO_STREAMING_STORE + Because storing zip archives inside a zip entry adds "false" signatures + and this causes problems when using data descriptors if the archive + needs fixing, this option is provided to force deflating when streaming. + This version of Zip includes an advanced algorithm for correctly finding + these signatures, but if an archive is "broke", there is no telling + what's where. This is only a problem if an archive becomes broke for + some reason, but to be safe define this. + + ALLOW_REGEX + For MSDOS and Windows, now "[list]" wildcard matching (where any + character between [ and ] can be used to match the character at that + position) is turned off unless the new -RE option is used. Defining + this flag forces "[list]" matching to be always on as in previous + releases. + + +For command help on any of the zip* utilities, simply enter +the name with no arguments. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bcfe47e --- /dev/null +++ b/LICENSE @@ -0,0 +1,60 @@ +This is version 2007-Mar-4 of the Info-ZIP license. +The definitive version of this document should be available at +ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely and +a copy at http://www.info-zip.org/pub/infozip/license.html. + + +Copyright (c) 1990-2007 Info-ZIP. All rights reserved. + +For the purposes of this copyright and license, "Info-ZIP" is defined as +the following set of individuals: + + Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois, + Jean-loup Gailly, Hunter Goatley, Ed Gordon, Ian Gorman, Chris Herborth, + Dirk Haase, Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz, + David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko, + Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs, + Kai Uwe Rommel, Steve Salisbury, Dave Smith, Steven M. Schweda, + Christian Spieler, Cosmin Truta, Antoine Verheijen, Paul von Behren, + Rich Wales, Mike White. + +This software is provided "as is," without warranty of any kind, express +or implied. In no event shall Info-ZIP or its contributors be held liable +for any direct, indirect, incidental, special or consequential damages +arising out of the use of or inability to use this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the above disclaimer and the following restrictions: + + 1. Redistributions of source code (in whole or in part) must retain + the above copyright notice, definition, disclaimer, and this list + of conditions. + + 2. Redistributions in binary form (compiled executables and libraries) + must reproduce the above copyright notice, definition, disclaimer, + and this list of conditions in documentation and/or other materials + provided with the distribution. The sole exception to this condition + is redistribution of a standard UnZipSFX binary (including SFXWiz) as + part of a self-extracting archive; that is permitted without inclusion + of this license, as long as the normal SFX banner has not been removed + from the binary or disabled. + + 3. Altered versions--including, but not limited to, ports to new operating + systems, existing ports with new graphical interfaces, versions with + modified or added functionality, and dynamic, shared, or static library + versions not from Info-ZIP--must be plainly marked as such and must not + be misrepresented as being the original source or, if binaries, + compiled from the original source. Such altered versions also must not + be misrepresented as being Info-ZIP releases--including, but not + limited to, labeling of the altered versions with the names "Info-ZIP" + (or any variation thereof, including, but not limited to, different + capitalizations), "Pocket UnZip," "WiZ" or "MacZip" without the + explicit permission of Info-ZIP. Such altered versions are further + prohibited from misrepresentative use of the Zip-Bugs or Info-ZIP + e-mail addresses or the Info-ZIP URL(s), such as to imply Info-ZIP + will provide support for the altered versions. + + 4. Info-ZIP retains the right to use the names "Info-ZIP," "Zip," "UnZip," + "UnZipSFX," "WiZ," "Pocket UnZip," "Pocket Zip," and "MacZip" for its + own source and binary releases. diff --git a/README b/README new file mode 100644 index 0000000..a559425 --- /dev/null +++ b/README @@ -0,0 +1,234 @@ +Zip 3.0 is the first Zip update adding large file support. For now Zip 2.3x +remains available and supported, but users should switch to this new release. + +Testing for Zip 3.0 has focused mainly on Unix, VMS, Max OS X, and Win32, +and some other ports may not be fully supported yet. If you find your +favorite port is broke, send us the details or, better, send bug fixes. It's +possible that support for some older ports may be dropped in the future. + + + +Copyright (c) 1990-2008 Info-ZIP. All rights reserved. + +See the accompanying file LICENSE (the contents of which are also included +in unzip.h, zip.h and wiz.h) for terms of use. If, for some reason, all +of these files are missing, the Info-ZIP license also may be found at: +ftp://ftp.info-zip.org/pub/infozip/license.html and +http://www.info-zip.org/pub/infozip/license.html. + + +Zip 3.0 is a compression and file packaging utility. It is compatible with +PKZIP 2.04g (Phil Katz ZIP) for MSDOS systems. There is a companion to zip +called unzip (of course) which you should be able to find in the same place +you got zip. See the file 'WHERE' for details on ftp sites and mail +servers. + +So far zip has been ported to a wide array of Unix and other mainframes, +minis, and micros including VMS, OS/2, Minix, MSDOS, Windows, Atari, Amiga, +BeOS and VM/CMS. Although highly compatible with PKware's PKZIP and PKUNZIP +utilities of MSDOS fame, our primary objective has been one of portability +and other-than-MSDOS functionality. Features not found in the PKWare version +include creation of zip files in a pipe or on a device; VMS, BeOS and OS/2 +extended file attributes; conversion from Unix to MSDOS text file format; and, +of course, the ability to run on most of your favorite operating systems. And +it's free. + +See the file zip30.ann for a summary of new features in Zip 3.0 and WhatsNew +for the detailed list of new features and changes since Zip 2.32. The file +CHANGES details all day-to-day changes during development. + +Notes: + +Multi-volume support. This version does not support multi-volume spanned +archives as in pkzip 2.04g, and there is no intention at this point to support +spanned archives, but Zip 3.0 supports split archives. A split archive is an +archive split into a set of files, each file a piece of the archive and each +file using an extension, such as .z02 as in the file name archive.z02, that +provides the order of the splits. In contrast, a spanned archive is the +original multi-floppy archive supported by pkzip 2.0g where the split order +is contained in the volume labels. The contents of split and spanned archives +are mostly identical and there is a simple procedure to convert between the +formats. Many current unzips now support split archives. + +Zip64 support. This version supports Zip64 archives as described in the +PKWare AppNote. These archives use additional fields to support archives +greater than 2 GB and files in archives over the 2 GB previous limit (4 GB +on some ports). The Zip64 format also allows more than 64k entries in an +archive. Support by the OS for files larger than 4 GB is needed for Zip to +create and read large files and archives. On Unix, Win32, and some other +ports, large file and Zip64 support is automatically checked for and +compiled in if available. Use of Zip64 by Zip is automatic and to maximize +backward compatibility the Zip64 fields will only be used if needed. A +Zip64 archive requires a pkzip 4.5 compatible unzip, such as UnZip 6.0. + +Unicode support. This version has initial Unicode support. This allows +paths and names of files in other character sets to be accurately recreated +on OS that have sufficient character set support. On Win32, if wide +character calls are supported (not Win 9x unless Unicode support has been +added) all files (including paths with illegal characters in the current +character set) should now be readable by zip. Unicode support is provided +using a new set of UTF-8 path and comment extra fields and a new UTF-8 bit +for flagging when the current character set is already UTF-8. Zip 3.0 +maintains backward compatibility with older archives and is mostly compliant +with the new Unicode additions in the latest PKWare AppNote. The exception +is UTF-8 comments, which are not supported if UTF-8 is not the native +character set, but should be fully implemented in Zip 3.1. + +16-bit OS support. Though Zip 3.0 is designed to support the latest zip +standards and modern OS, some effort has been made to maintain support +for older and smaller systems. If you find Zip 3.0 does not fit on or +otherwise does not work well on a particular OS, send in the details and +we might be able to help. + +Compression methods. In addition to the standard store and deflate methods, +Zip now can use the bzip2 compression format using the bzip2 library. Though +bzip2 compression generally takes longer, in many cases using bzip2 results +in much better compression. However, many unzips may not yet support +bzip2 compressed entries in archives, so test your unzip first before using +bzip2 compression. + +Installation. Please read the file INSTALL for information on how to compile +and install zip, zipsplit, zipcloak, and zipnote and please read the manual +pages ZIP.txt, ZIPSPLIT.txt, ZIPCLOAK.txt, and ZIPNOTE.txt for information on +how to use them. Also, if you are using MSDOS or Windows, note that text +files in the distribution are generally in Unix line end format (LF only) +and Windows and DOS users will need to either convert the files as needed to +DOS line ends (CR LF) or extract the distribution contents using unzip -a. + +Utilities. At this point zipsplit, zipcloak, and zipnote should work with +large files, but they currently do not handle split archives. A work around +is to use zip to convert a split archive to a single file archive and then use +the utilities on that archive. + +Encryption. This version supports standard zip encryption. Until recently +the encryption code was distributed separately because of the US export +regulations but now is part of the main distribution. See crypt.c for +details. Decryption can be made with unzip 5.0p1 or later, or with zipcloak. + +Bug reports. All bug reports or patches should go to zip-bugs via the web +site contact form at http://www.info-zip.org/zip-bug.html (we have discontinued +the old email address zip-bugs@lists.wku.edu because of too much spam lately) +and suggestions for new features can be submitted there also (although we don't +promise to use all of them). We also are on SourceForge at +http://sourceforge.net/projects/infozip/ and now automatically get Bug Reports +and Feature Requests submitted there. In addition, a new Info-ZIP discussion +forum is available as well. See below. Though bug reports can be posted there, +we don't have automatic monitoring of all postings set up yet so you may want +to use the web form or SoureForge for a quicker response. A good approach may +be to post the details on the forum so others can benefit from the posting, +then use the web reply form to let us know you did that if you don't get a +reply in a reasonable time. + +Ports. If you're considering a port, please check in with zip-bugs FIRST, +since the code is constantly being updated behind the scenes. We'll +arrange to give you access to the latest source. + +Discussion group. If you'd like to keep up to date with our Zip (and companion +UnZip utility) development, join the ranks of BETA testers, add your own +thoughts and contributions, etc., check out the new discussion forum. This is +the latest offering, after the various Info-ZIP mailing-lists on +mxserver@lists.wku.edu (courtesy of Hunter Goatley) were no longer available +and the temporary QuickTopic discussion group for Info-ZIP issues at +http://www.quicktopic.com/27/H/V6ZQZ54uKNL died a horrible death due to large +amounts of spam. The new discussion forum is now available at +http://www.info-zip.org/board/board.pl (thanks again to Hunter Goatley) and +can be used to discuss issues, request features, and is one place new betas +and releases are announced. It also is a place to post bug reports, and +patches can be submitted as attachments. However, we don't yet get +automatic notification of all postings there so try one of the other methods +if you don't get a response. You can also post Bug Reports and Feature +Requests at Source Forge. However, the web site contact form remains +available if you would rather not post on the public forums. + +Frequently asked questions on zip and unzip: + +Q. When unzipping I get an error message about "compression method 8". + +A. This is standard deflate, which has been around for awhile. Please + get a current version of unzip. See the file 'WHERE' for details. + + +Q. How about "compression method 12"? + +A. Compression method 12 is bzip2 and requires a relatively modern unzip. + Please get the latest version of unzip. + + +Q. I can't extract this zip file that I just downloaded. I get + "zipfile is part of multi-disk archive" or some other message. + +A. Please make sure that you made the transfer in binary mode. Check + in particular that your copy has exactly the same size as the original. + Note that the above message also may actually mean you have only part + of a multi-part archive. Also note that UnZip 5.x does not and UnZip 6.0 + probably won't have multi-disk (split) archive support. A work around + is to use Zip 3.0 to convert the split archive to a single-file archive + then use UnZip on that archive. As a last result, if there's something + readable in what you have, zip -FF should be able to recover it. + + +Q. When running unzip, I get a message about "End-of-central-directory + signature not found". + +A. This usually means that your zip archive is damaged, or that you + have an uncompressed file with the same name in the same directory. + In the first case, it makes more sense to contact the person you + obtained the zip file from rather than the Info-ZIP software + developers, and to make sure that your copy is strictly identical to + the original. In the second case, use "unzip zipfile.zip" instead + of "unzip zipfile", to let unzip know which file is the zip archive + you want to extract. + + +Q. Why doesn't zip do just like PKZIP does? + +A. Zip is not a PKZIP clone and is not intended to be one. In some + cases we feel PKZIP does not do the right thing (e.g., not + including pathnames by default); in some cases the operating system + itself is responsible (e.g., under Unix it is the shell which + expands wildcards, not zip). Info-ZIP's and PKWARE's zipfiles + are interchangeable, not the programs. + + For example, if you are used to the following PKZIP command: + pkzip -rP foo *.c + you must use instead on Unix: + zip -R foo "*.c" + (the quotes are needed to let the shell know that it should + not expand the *.c argument but instead pass it on to the program, + but are not needed on ports that do not expand file paths like + MSDOS) + + +Q. Can I distribute zip and unzip sources and/or executables? + +A. You may redistribute the latest official distributions without any + modification, without even asking us for permission. You can charge + for the cost of the media (CDROM, diskettes, etc...) and a small copying + fee. If you want to distribute modified versions please contact us at + www.Info-ZIP.org first. You must not distribute beta versions. + The latest official distributions are always on ftp.Info-ZIP.org in + directory /pub/infozip and subdirectories and at SourceForge. + + +Q. Can I use the executables of zip and unzip to distribute my software? + +A. Yes, so long as it is made clear in the product documentation that + zip or unzip are not being sold, that the source code is freely + available, and that there are no extra or hidden charges resulting + from its use by or inclusion with the commercial product. See the + Info-ZIP license for more. Here is an example of a suitable notice: + + NOTE: is packaged on this CD using Info-ZIP's compression + utility. The installation program uses UnZip to read zip files from + the CD. Info-ZIP's software (Zip, UnZip and related utilities) is + freely distributed under the Info-ZIP license and can be obtained as + source code or executables from various anonymous-ftp sites, + including ftp://ftp.info-zip.org/pub/infozip. + + +Q. Can I use the source code of zip and unzip in my commercial application? + +A. Yes, as long as the conditions in the Info-ZIP license are met. We + recommend you include in your product documentation an acknowledgment + and note that the original compression sources are available at + www.Info-ZIP.org. If you have special requirements contact us. diff --git a/README.CR b/README.CR new file mode 100644 index 0000000..c777d19 --- /dev/null +++ b/README.CR @@ -0,0 +1,119 @@ +_____________________________________________________________________________ + + This is Info-ZIP's README.CR for zcrypt29.zip, last updated 27 March 2008. +_____________________________________________________________________________ + + +The files described below contain the encryption/decryption code for Zip 2.31, +UnZip 5.52, and WiZ 5.02 (and later). These files are included in the main +source distributions for all of these now, but the encryption patch is still +available for earlier versions of these. This file both describes the history +of the encryption package and notes the current conditions for use. Check +the comments at the top of crypt.c and crypt.h for additional information. + +As of version 2.9, this encryption source code is copyrighted by Info-ZIP; +see the enclosed LICENSE file for details. Older versions remain in the pub- +lic domain. Zcrypt was originally written in Europe and, as of April 2000, +can be freely distributed from the US as well as other countries. + +(The ability to export from the US is new and is due to a change in the Bureau +of Export Administration's regulations, as published in Volume 65, Number +10, of the Federal Register [14 January 2000]. Info-ZIP filed the required +notification via e-mail on 9 April 2000; see the USexport.msg file in this +archive. However, as of June 2002, it can now be freely distributed in both +source and object forms from any country, including the USA under License +Exception TSU of the U.S. Export Administration Regulations (section 740.13(e)) +of 6 June 2002.) + + LIKE ANYTHING ELSE THAT IS FREE, ZIP, UNZIP AND THEIR ASSOCIATED + UTILITIES ARE PROVIDED AS IS AND COME WITH NO WARRANTY OF ANY KIND, + EITHER EXPRESSED OR IMPLIED. IN NO EVENT WILL THE AUTHORS BE LIABLE + FOR ANY DAMAGES RESULTING FROM THE USE OF THIS SOFTWARE. + +The encryption code is a direct transcription of the algorithm from +Roger Schlafly, described by Phil Katz in the file appnote.txt. This +file is distributed with the PKZIP program (even in the version without +encryption capabilities). Note that the encryption will probably resist +attacks by amateurs if the password is well chosen and long enough (at +least 8 characters) but it will probably not resist attacks by experts. +Paul Kocher has made available information concerning a known-plaintext +attack for the PKWARE encryption scheme; see http://www.cryptography.com/ +for details.) Short passwords consisting of lowercase letters only can be +recovered in a few hours on any workstation. But for casual cryptography +designed to keep your mother from reading your mail, it's OK. + +For more serious encryption, check into PGP (Pretty Good Privacy), a +public-key-based encryption system available from various Internet sites. +PGP has Zip and UnZip built into it. The most recent version at the time +this was originally written was 6.5, although older versions were still +widespread. At the time of this writing there are now GPG, PGP Universal +2.0, and various others based on OpenPGP. + +We are looking at adding AES strong encryption to future versions of Zip and +UnZip. + +Zip 2.3x and UnZip 5.5x and later are compatible with PKZIP 2.04g. (Thanks +to Phil Katz for accepting our suggested minor changes to the zipfile format.) + +IMPORTANT NOTE: + + Zip archives produced by Zip 2.0 or later must not be *updated* by + Zip 1.1 or PKZIP 1.10 or PKZIP 1.93a, if they contain encrypted members + or if they have been produced in a pipe or on a non-seekable device. + The old versions of Zip or PKZIP would destroy the zip structure. The + old versions can list the contents of the zipfile but cannot extract + it anyway (because of the new compression algorithm). If you do not + use encryption and compress regular disk files, you need not worry about + this problem. + + +Contents that were distributed and now are part of the main source files: + + file what it is + ---- ---------- + README.CR this file + LICENSE Info-ZIP license (terms of reuse and redistribution) + USexport.msg export notice sent to US Bureau of Export Administration + WHERE where Zip/UnZip/WiZ and related utilities can be found + crypt.c code for encryption and decryption + crypt.h code for encryption and decryption + file_id.diz description file for some BBSes + +Most all of the files are in Unix (LF only) format. On MSDOS systems, you +can use the -a option of UnZip to convert the source files to CRLF +format. This is only necessary if you wish to edit the files -- they +will compile as is with Microsoft C and Turbo/Borland C++ 1.0 or +later. However, you will have to convert the files (using "unzip -a") +to the CRLF format to compile with the older Turbo C 1.0 or 2.0. You +should be able to find Zip and UnZip in the same place you found this +(see ftp://ftp.info-zip.org/pub/infozip/Info-ZIP.html or the file +"WHERE" for details). + +Current releases all have encryption built in. To update previous versions +using the zcrypt sources: + + (1) Get the main sources (e.g., Zip 2.3) and unpack into a working + directory, as usual. + + (2) Overwrite the dummy crypt.c and crypt.h from the main sources with + the versions from this package. If you want to overwrite directly + out of the zcrypt29 archive, do not use UnZip's freshen/updating + option; the dummy files may be newer than the real sources in + zcrypt29. ("unzip -o zcrypt29 -d /your/working/dir" will do the + Right Thing in most cases, although it may overwrite a newer WHERE + file under some circumstances.) + + (3) Read the main INSTALL document and compile normally! No makefile + changes are necessary on account of the zcrypt sources. You can + check that the version you just compiled has encryption or decryption + support enabled by typing "zip -v" or "unzip -v" and verifying that + the last "special compilation option" says encryption or decryption + is included. + +Encryption enables new "-e" and "-P password" options in Zip, and a new +"-P password" option in UnZip--see the normal Zip and UnZip documentation +for details. (Note that passing a plaintext password on the command line +is potentially much more insecure than being prompted for it interactively, +which is the default for UnZip and for Zip with "-e". Also note that the +interactive method allows UnZip to deal with archives that use different +passwords for different files.) diff --git a/TODO b/TODO new file mode 100644 index 0000000..8d51732 --- /dev/null +++ b/TODO @@ -0,0 +1,142 @@ +Todo list (last updated 12 June 2008). + +Features for next official version: + +- Extended attributes for Windows, Linux, and Mac OS X. +- Win32 ACL rewrite to use backup api to create new and more useful extra + field (need unzip support) (Kai). +- Allow -d@ to read in a list of names to delete (11/17/2005). +- AES encryption (3/19/05). + +Features that may make the next release: + +- Allow reading in list of files using @filename. +- When -R, -x, or -i pattern ends in a directory add / to the end + (11/5/2004 Nehal). +- Decide if -R, -i and -x should use external rather than internal patterns. + Also, change pattern matching to not do ex2in() and then in2ex() if + appropriate. (12/26/2005 SMS) +- Though Unicode paths have been implemented and tested, Unicode comments + are not yet supported (except for comments on UTF-8 native systems which + are supported). +- Verbose mode -v may still need work. + +- Add C# example for Zip 3.0 (need to be converted to new DLLs) - original + C# example added with note. +- Path Prefix maybe, so entries added to an archive can have a directory + path string prepended to each path so can zip multiple drives and avoid + name conflicts (4/17/2006). +- UNC paths like \\server\path (4/26/2005). +- Support for other languages maybe. + +- Add About page option similar to -h2 and -v but lists Info-ZIP + information (could be -sa) (4/29/2006). +- Update utilities ZipSplit, ZipNote, and ZipCloak to handle split archives. +- Update ziperr and finish if needed. +- Review memory allocation and fill in memory leaks if any. +- Enhance -FF to fix common problems such as archives ftp in text mode + and fixing checksums so entries can be extracted if that makes + sense (6/17/2007). +- Add \ to / conversion in zipsplit to fix problem in + 1/29/2004 email. +- Encryption bug with small stored file (12/27/2005) (fixed?). + +- When updating large archives with few entries being + updated maybe display something in large periods of + quiet (1/23/2006). +- Windows OEM comments (5/17/2006). +- Example of using MVS zip and unzip (3/30/2004) (Need one). +- UTF-8 comments need to be implemented (6/17/2007) +- Maybe convert ../ in archive (5/20/2006). +- Per so many buffers dll callback (12/23/2005 Ale). +- Allow rename stdin "-" to something else (12/27/2005 gregor). +- Check for possible buffer overrun weaknesses while reading zip files. +- Do Active Template Library (ATL) (4/27/2005). +- Flush Win16 support - to be determined (Mike). +- Way to convert file names on input, converting foo.c to dir/foo_bar.c + for instance (4/8/2004, 3/12/2004). +- French WiZ (not a Zip thing actually but dependent on zip and unzip). +- Then there is that wierd ^D being converted to \000 error reported + in 6/21/2003 email when Zip is outputted into a pipe on Windows ports. + +Old list: + +Main features still missing for next official version (last updated 2/11/2001): + +- what about the binary/text detection ? (seems done) +- -b and -t options in help screen (covered in -h2) +- findfirst/findnext and after that LSSTAT (performance!!) +- use IS_EXEC from djgpp stat.h +- use install in unix/Makefile instead of mkdir -p, look at install sh script. +- #elif for those ports that can handle it. +- what about zopen vs. fopen ? +- Add zcreate or zfcreate for win32. +- Assembler stuff in match.S (subexpressions) +- zipping huge files (> 2G, unsigned 32bit) (done) +- Testsuite for zip and unzip (John D. Mitchell) +- make a version.c or version.h that includes all the compiler names +- run utils with dmalloc(). +- what to do with zip -F and zip -FF (readzipfile2()) ? (done?) +- profiling of the code +- multi disk zip files (could be done) +- zipfile modification tool (Greg) +- Implement -- option (Thomas Klauser, wiz@danbala.tuwien.ac.at) (could be done) +- don't add files with "Archive bit" or add files with "Archive bit" + (uwe.becher@metronet.de) (could be done with -AS and -AC) +- 32 bit file attributes +- generate output without having to seek at all (this seems to be stream output) +- remove contractions from zip error messages, make them clearer (Steve) +- display "[text]" for ascii files when not quiet (no -q) (Timo Salmi) +- does zipnote accept names with version number? +- for a WORM, zip should create temp file only when updating; new archives + should be created directly. +- APPNOTE.TXT specifies "4) The entries in the central directory may + not necessarily be in the same order that files appear in the zipfile" + but readzipfile() relies on same order. (new read does not, and now + the read for -FF searches for central directory matches rather than + rely on the order) +- on Mac, MPW C 3.3.1 requires #if (a || b) ["#if a || b" taken as "#if a"] +- on Unix, let -S be "include non-regular files without reading from them" + (as pkzip on Unix). This requires unzip support. +- zip -l should do ebcdic->ascii translation on CMS and MVS +- zip as subroutine (zdig/241) (some work done on this) +- accept k and M in zipsplit +- store / (part of file name) as ! in OS/2 (problem only with -E ?) +- in addition to -l (LF to CR LF) and -ll (CR LF to LF) add -lc + (LF to CR LF but CR LF remains unchanged) + +Known bugs: + +- On VMS, zip fails reading some files with "byte record too large for + user's buffer". You must use the "-V" option for such files. + (many changes to VMS so may be fixed) + +- on MSDOS, zip386.exe does not like "zip -bc: foo ..." + +- on MSDOS, zip386.exe is sometimes much slower than zip.exe. This is + probably a problem with DJGPP (to be investigated). + +- on NT with C shell, zip should not do file name expansion again. + +- zip zipfile ... ignores existing zipfile if name does not have an extension + (except for the -A option, generally used on self-extracting files). + (archives should probably have extensions. Things like archive.jar work) + +- For an sfx file without extension, "zip -A sfx" works but "zip sfx -A" + doesn't. (because options were required first, but now both OK) + +- When storing files in a zipfile (-0), zip marks all of them as binary. + +- On VMS, some indexed files are not restored correctly after zip -V and unzip. + (This is now known to be a problem of UnZip. The workaround for Zip 2.2 + and newer is to use PK-style VMS extra fields; this is now the default. + NOTE that UnZip 5.32 has been fixed [971019]!) (many VMS changes so + this may be fixed) + +- zip and unzip should use the same pattern matching rules, particularly + on MSDOS and OS/2. On OS/2, "zip foo *.*" should also match files + without extension. + Partially DONE (OS/2 "*.*" matches "*".) + +- there should be a way to avoid updating archive members (only addition + of new files allowed) diff --git a/USexport.msg b/USexport.msg new file mode 100644 index 0000000..068aa9f --- /dev/null +++ b/USexport.msg @@ -0,0 +1,75 @@ +From roelofs (at) sonic.net Tue Jun 17 08:26:55 2003 +Date: Tue, 17 Jun 2003 08:26:50 -0700 +Message-Id: <200306171526.h5HFQoaw014091 (at) bolt.sonic.net> +From: Greg Roelofs +Reply-To: Greg Roelofs +To: crypt (at) bis.doc.gov, enc (at) ncsc.mil, web_site (at) bis.doc.gov +Subject: TSU NOTIFICATION - Encryption (Info-ZIP zcrypt.zip) +Cc: newt (at) pobox.com, zip-bugs (at) lists.wku.edu + + + SUBMISSION TYPE: TSU + SUBMITTED BY: Greg Roelofs + SUBMITTED FOR: the Info-ZIP group (an informal, Internet-based + collection of software developers with the contact + address given in next item) + POINT OF CONTACT: Zip-Bugs (at) lists.wku.edu + PHONE and/or FAX: n/a + MANUFACTURER: n/a + PRODUCT NAME/MODEL #: zcrypt + ECCN: 5D002 + + NOTIFICATION: + + ftp://ftp.info-zip.org/pub/infozip/src/zcrypt.zip + + +FURTHER COMMENTS: + +(1) This notice is being sent in order to ensure that we may legally + take advantage of the 6 June 2002 amendment to 740.13 regarding + "corresponding object code." The encryption code in question is + unchanged since our original notification of 9 April 2000, appended + below and also reproduced within the above zcrypt.zip archive. + (Indeed, there has been no change to the core encryption/decryption + code in well over five years.) + +(2) The (larger) source archives for Zip, UnZip, MacZip, WiZ, and + potentially other packages, currently available in the same ftp + directory given above, also contain (or may contain) copies of + the same zcrypt source code. + +(3) ftp.info-zip.org currently points to a site in Germany, so techni- + cally it is not involved in "US export" in any direct way. However, + we encourage other sites to "mirror" our software, and some of these + mirror sites may be US-based (and therefore involved in reexport of + the code in question). In addition, some Info-ZIP members reside in + the US, and www.info-zip.org currently points to a site in Kentucky. + + +ORIGINAL NOTIFICATION: + +From roelofs (at) sonic.net Sun Apr 9 15:11:45 2000 +Date: Sun, 9 Apr 2000 15:11:27 -0700 +Message-Id: <200004092211.PAA20023 (at) sonic.net> +From: Greg Roelofs +To: crypt (at) bxa.doc.gov +Subject: notice of export of unrestricted encryption source code +Cc: newt (at) pobox.com, zip-bugs (at) lists.wku.edu + +The Info-ZIP group, an informal, Internet-based collection of software +developers with contact address Zip-Bugs (at) lists.wku.edu, hereby notifies +the US Bureau of Export Administration (BXA) of the posting of freely +available encryption source code on the Internet under License Exception +TSU, to commence later today at this location: + + ftp://ftp.info-zip.org/pub/infozip/src/zcrypt.zip + +This notification is in accordance with section 740.13(e) of the amended +Export Administration Regulations, as published in the 14 January 2000 +issue of the Federal Register. + +-- +Greg Roelofs newt (at) pobox.com http://pobox.com/~newt/ +Newtware, PNG Group, Info-ZIP, Philips Research, ... + diff --git a/WHATSNEW b/WHATSNEW new file mode 100644 index 0000000..9e8d52b --- /dev/null +++ b/WHATSNEW @@ -0,0 +1,333 @@ +What's New + +Last updated 1 July 2008 + +This file is the full list of new features and major changes for Zip 3.0 +by beta release. See the announcement file zip30.ann for a quick summary +of all features and changes in Zip 3.0. Also see the file README for +release information, INSTALL for installation procedures, and the manual +pages zip.txt, zipsplit.txt, zipcloak.txt, and zipnote.txt for how to use +the new features. The file CHANGES has all the day-to-day changes made +during development. + + +Below are some of the more significant items on the list for Zip 3.1 +(see ToDo for a more complete list): + +- AES encryption. +- Extended attributes for Windows, Linux, and Mac OS X. +- Support -d@ for deleting list of files. +- Decide if -R, -i and -x should use external rather than internal patterns. +- Though Unicode paths have been implemented and tested, Unicode comments + are not yet supported (except for comments on UTF-8 native systems which + are supported). +- Verbose mode -v may still need work. +- When pattern is directory add end / automatically. +- Add C# example for Zip 3.0 (need to be converted to new DLLs) - original + C# example added with note. +- Path Prefix maybe, so entries added to an archive can have a directory + path string prepended to each path. +- UNC path support maybe. +- Support for other languages maybe. +- Send in your suggestions. +- ... + + +MAJOR CHANGES BY BETA VERSION +----------------------------- + +New things in Zip 3.0 since Zip 3.0h: + +- Unicode fixes. +- Test and fix various ports as needed. +- Update Win32 resource to support more Windows ports. +- Add djgpp 2.x makefile that includes bzip2. +- Add Win32 version resource to Win32 executable. +- Bug fixes. +- Documentation updates. +- Package for release. + + +New things in Zip 3.0h + +- Allow -@ and -x to work together. +- Unicode code cleanup. +- Allow forcing use of UTF-8 storage in standard path and comment. +- Update symbolic link checks. +- Add support for storing 32-bit UIDs/GIDs using new extra field. + Backward compatible support for the old 16-bit UID/GID extra field + remains if Zip is compiled on an OS that has 16-bit UID/GID + storage. +- Update VMS notes. +- Directory scan using -AS (include only files with Windows archive + bit set) now ignores archive bit on directories to include all files + with archive bit set in all directories. Also, to avoid empty + directories being created, -AS now does not store directory + entries. +- Add Unix IBM support. +- Change -W to -ws to free -W for later use. +- Fix large file support for MinGW. +- Fix large file support for bzip2. +- Fix compile error in ZipCloak when UNICODE_SUPPORT is not enabled. +- Fix Unicode bug in ZipCloak involving Unicode paths. +- Long Unicode escapes changed from #Lxxxxxxxx to #Lxxxxxx to shorten + paths with escaped Unicode. +- Bug fixes. + + +New things in Zip 3.0g + +- Add split support to VB project for Zip64. +- Disable reading of Unix FIFOs unless new -FI option used to avoid an + archiving operation stopping when it hits an active unfed FIFO. +- The "[list]" wildcard expression (regular expression matching of any + character or range of characters in list) is now disabled on DOS and + Windows as it has caused confusion when filenames have [ and ] in + them. The new -RE option reenables it. +- Add negation to many display options such as -dc and -db. +- Allow -FF to read and fix archives having local entries that appear + after central directory entries. +- Bug fixes. + + +New things in Zip 3.0f + +- bzip2 - The bzip2 compression method looks supported for at least + Windows, Unix, and VMS using the bzip2 library. A new option, -Z cm, + selects the compression method. + +- Split archives - Can now use -s to create a split archive. The + default is to update split files as the archive is being written, + which requires all splits to remain open until the archive is done. + This should be no problem when writing the archive to a hard drive, + for example, and this approach creates archives that should be + supported by all unzips that support splits. Adding the -sp option + enables split pause mode that instead writes splits that do not + need updating and pauses Zip after each split. This allows splits + to be written directly to removable media, however -sp archives + may not be as universally compatible. + +- Unicode support - Zip now stores Unicode paths that should be more + portable across character sets and languages. The unzip must have + Unicode support enabled or the Unicode paths are ignored. If + reading an archive with Unicode paths, unsupported characters are + replaced by #Uxxxx and #Lxxxxxxxx escapes in the file name. Option + -UN controls how Unicode is handled. Also, on systems where the + current character set is UTF-8, preliminary support for the new + General Purpose Bit Flag, bit 11, UTF-8 flag, that indicates UTF-8 + is stored in the path and comment fields is implemented for paths. +- Unicode on Win32 - On WIN32 systems that support the wide character + calls (mainly NT and later systems using NTFS), when UNICODE SUPPORT + is enabled Zip will now do directory scans using Unicode and convert + the Unicode paths to the local character set for storage in the standard + path field and store UTF-8 in the Unicode extra field. This allows + directory scans to complete successfully regardless of the character + set the path is in. On Win9x systems wide character scans are not + generally supported and Zip automatically uses a local character scan + instead. + +- Keep extra fields option - The default operation has been, and continues + to be, to read then strip old extra fields when reading entries from an + existing archive and then recreate the extra fields that Zip knows about. + Extra fields specific to each operating system get added by default also. + The new option -X- (negated -X) keeps any old extra fields, copying + them to the updated archive unchanged (unless Zip has updated them). + The unnegated -X still strips most all extra fields except Zip64, + Unicode, and UT time. + +- License - minor updates to the license. + +- Windows OEM - When compiled with WIN32_OEM (the default for WIN32), + Zip on WIN32 now stores OEM paths, which should be more compatible + with other zips and should fix some character set problems. +- Windows Archive Bit support - On Windows can now use new -AS + (include if archive bit set) option to select files with the DOS + archive bit set and use new -AC (clear archive bits) option to clear + the archive bits on files after the archive has been created. + But -DF is probably better. + +- Difference mode - A new option -DF (--dif) creates an output archive + that includes only files changed or new since the input archive was + created. Can use to create incremental backups. +- File Sync - The new option -FS enables File Sync, a new mode that + synchronizes the entries in an archive with the files on the file + system, adding updating, and deleting entries as needed. This + should create the same results as creating a new archive, but + since existing entries are copied, may be much faster. + +- Copy Mode - A new --out option allows creating a new archive with a + different name than the input archive, leaving the input archive + unchanged. This allows updating split archives. It also allows + for a new copy mode to select entries in one archive and copy them + directly to a new archive. +- Empty archives - Now an empty archive is created when -i or -i@ is used + and the file patterns given do not match anything. This has been + requested to support scripts. + +- Global dots - A new -dg option now displays progress dots as -dd does, + but instead of displaying them for each file, the dots track the total + bytes read for the archive. The -dg option also works when -q is used + to disable most output, which allows for something like zip -qdgds 100m + to be used to not display specific files but display a dot every 100 MB + as a global status. +- Date range - Can now use -t and -tt to set a date range +- Fix options - Option -F redone and can recover files from an archive + with a mostly complete central directory more reliably, but no longer + can handle truncated archives. Option -FF redone and now can salvage + files from slightly more damaged archives, including truncated archives. + In some ways -F is less powerful but more stable than it was and -FF will + be needed where -F in Zip 2.32 was enough. One big change is -F and -FF + both now support split archives. +- Console writing - Updates to how messages are written to the console have + been made including more consistent handling of line breaks. +- Show Files options - Option -sf lists the files that would be operated + on. This option can be used alone to list the files in an archive. + Also see options -su and -sU for showing Unicode paths. +- UnZip Check - Now check that UnZip 6.00 or later is being used for + unzip if testing a Zip64 archive. A new option -TT can be used to set + the unzip to use with the -T check. Currently UnZip does not support + split archives so split archives can't be tested by UnZip. +- Streaming - Directories are now handled better when streaming. +- Case matching - Normally all matching against archive entries is case + sensitive, so *.BAR will not match or find foo.bar in an archive + when deleting, copying, or freshening entries (deleting and copying + only on VMS). New option -ic (--ignore-case) enables case insensitive + matching. Currently -ic is only implemented on WIN32 and VMS. + +- Delete date bug fixed - Bug when using -d to delete files while + using -t or -tt to select the files based on date is fixed +- Large file encryption bug fixed - Fix for bug that very rarely + results in bad data being stored when deflating and encrypting + uncompressable data and resulting in CRC errors when extracting, + but the chance of error increases with file size (thanks to + WinZip for finding this bug). See CHANGES for details. + + +New things in Zip 3.0e + +- Bugs described in Debian patches 004 (unix configure script update) and + 005 (large path bug) fixed +- Various fixes +- Add optional running stats and also end stats if not all files could + be read +- Options -l and -ll now do quick binary check on first buffer and skip + formatting if first buffer has binary - still check at end to note + if formatting was done on file that was later determined to be binary, + but now potential file corruption is generally avoided +- Main binary check now uses new algorithm that should also treat UTF-8 and + other similar encodings as text, allowing proper line end translation + for UTF-8 files +- When output is not updatable by seeking back and Zip64 is enabled, output + is forced to Zip64 to avoid possible later need for Zip64 when not enabled +- More work on splits, but still not usable +- Fixes for djgpp +- Add log file capability to save all errors and optionally messages +- Add code to test for a Zip64 archive when compiled without Zip64 support +- New VC6 projects for Win32 and WinDLL +- Updates to extended help +- Changes to force-zip64 option +- ZE_BIG error now given also for files too big to read or write +- Fix file delete bug +- Update license +- Update export documentation +- Add VMS extended filename support +- Add directory traversal improvements, some for Win32 ports and some for + all ports, that can result in a 10 times increase in speed in some cases + + +New things in Zip 3.0d + +- Some large file crypt fixes +- Some updates to support WiZ +- On VMS, changed -V (/VMS) processing to truncate file at EOF, allowing + greater compatability with non-VMS systems. New -VV (/VMS=ALL) option + saves all allocated blocks in a file. (Previously, -V did neither.) +- On VMS, pushed 2GB file size limit with -V out to 4GB +- On VMS (recent, non-VAX), with SET PROCESS /PARSE = EXTEND, + command-line case is preserved. This obviates quoting upper-case + options, like -V, when enabled +- On VMS, fixed problems with mixed-case directory names. Also changed + to keep ODS5 extended file name escape characters ("^") out of the + archived names in simple cases +- Changes to the display dots +- Option -W should now force wildcard matching to not cross directory + separators. For example, a/b*r/d will match a/bar/d but not a/ba/r/d +- Option -nw should turn off all wildcard matching so foo[bar] is matched + literally and [bar] is not considered a regular expression +- Atheos port +- Debugging of Unix and VMS large file ports. Most features may work now + on these ports for large files. Still need to fix 2 GB to 4 GB when not + compiled with large file support +- On VMS, added an open callback function which (where supported) senses + the process RMS_DEFAULT values for file extend quantity (deq) + multi-block count (mbc), and multi-buffer count (mbf), and sets the + FAB/RAB parameters accordingly. The default deq is now much larger + than before (16384 blocks, was none), and the default mbc is now 127 + (up from 64), speeding creation of a large archive file. The "-v" + option shows some of the activity. On old VMS versions, RMS_DEFAULT + sensing (GETJPI) fails (silently, without "-v"), and no changes will + be made. Even there, (DCL) SET RMS /EXTEND = can help + performance. RMS_DEFAULT values override built-in default values. + + +New things in Zip 3.0c + +- Converted to using 64-bit file environment instead of transitional functions + like fseeko64 for ports that support it +- Added "--" argument to read all following arguments as paths +- Second help page added +- Binary detection adjusted from 20% binary is binary to 2% +- When -R and -i used together now -i has precedence over -R +- Archive names with spaces can now be tested on MSDOS and Win32 + + +New things in Zip 3.0b + +- Fixed ifdefs so can test base code by compiling with NO_LARGE_FILE_SUPPORT, then + compiling with NO_ZIP64_SUPPORT to test 64-bit file calls (if port enables) but + otherwise use base code, and compiling normally to enable Zip64 code +- Unix Zip64 fixes - should now be able to create and read large files +- WinDLL changes to support Zip64. Zip 3.0 dll named Zip32z64.dll +- New VB example to show use of Zip32z64.dll +- New options -sc (show final command line and exit) and -sd (show each + step zip is doing, a little different than verbose which is still there) added + to help debug but both or at least -sd might go away in the release +- Some minor posted bugs fixed (see Changes) + + +New things in Zip 3.0a + +- Initial Zip64 support allowing large files and large numbers of files +- New command line processor +- Other changes, see file Changes + + +Note: Zip 2.4 was never released. That code was the start of the Zip 3.0 +effort above. + + +New things in Zip 2.3 + +- IBM OS/390 port (Unix like, but EBCDIC) by Paul von Behren +- Apple Macintosh (MACOS) port by Dirk Haase +- Theos port by Jean-Michel Dubois +- Multibyte characterset support by Yoshioka Tsuneo +- Support for ISO 8601 date format with -t and -tt options +- Info-ZIP license + + +New things in Zip 2.2 + +- BEOS port by Chris Herborth +- QDOS port by Jonathan Hudson +- TANDEM port by Dave Smith +- WINDLL port (16-bit Win 3.x and 32-bit WinNT/Win95) by Mike White +- SYSV packages support by John Bush +- zip -P SeCrEt encrypts entries in the zip file with password SeCrEt + (WARNING: THIS IS INSECURE, use at your own risk) +- zip -R recurses into subdirectories of current dir like "PKZIP -rP" +- zip -x@exclude.lst excludes files specified in the file exclude.lst +- zip -i@include.lst includes files specified in the file include.lst +- zip -@ only handles one filename per line, but supports whitespace in names +- zip -t mmddyyyy, 4 digit year number for uniqueness of years beyond 2000 +- zip -tt mmddyyyy only includes files before a specified date diff --git a/WHERE b/WHERE new file mode 100644 index 0000000..94a0d55 --- /dev/null +++ b/WHERE @@ -0,0 +1,261 @@ +__________________________________________________________________________ + + This is the Info-ZIP file ``WHERE,'' last updated on 1 March 2005. +__________________________________________________________________________ + + This file is out of date. We plan to update the structure of the ftp + site shortly and should be updating this file as soon as that's done. + + The latest version of this file can be found online at: + + ftp://ftp.info-zip.org/pub/infozip/doc/WHERE + + Note that some ftp sites may not yet have the latest versions of Zip + and UnZip when you read this. The latest versions always appear in + ftp://ftp.info-zip.org/pub/infozip/ (and subdirectories thereof) first, + except for encryption binaries, which always appear in + ftp://ftp.icce.rug.nl/infozip/ (and subdirectories) first. + + IF YOU FIND AN ERROR: please let us know! We don't have time to + check each and every site personally (or even collectively), so any + number of the sites listed below may have moved or disappeared en- + tirely. E-mail to Zip-Bugs@lists.wku.edu and we'll update this file. +__________________________________________________________________________ + + +Info-ZIP's home WWW site is listed on Yahoo and is at: + + ftp://ftp.info-zip.org/pub/infozip/Info-ZIP.html (master version) + http://ftp.info-zip.org/pub/infozip/ (master version) + http://www.info-zip.org/ + +Note that the old sites at http://www.cdrom.com/pub/infozip/ and +http://www.freesoftware.com/pub/infozip are PERMANENTLY BROKEN. They +cannot be updated or removed, apparently. + +The Zip and UnZip pages have links to most known mirror sites carrying our +source and/or binary distributions, and they generally are more up-to-date +and have better information than what you are reading: + + ftp://ftp.info-zip.org/pub/infozip/Zip.html + ftp://ftp.info-zip.org/pub/infozip/UnZip.html + +The related zlib package by Info-ZIP's Jean-loup Gailly and Mark Adler is at: + + http://www.zlib.net/ + +Source-code archives for Info-ZIP's portable Zip, UnZip, and related +utilities: + + zip231.zip Zip 2.31 (deflation; includes zipnote/zipsplit/zipcloak) + zip231.tar.Z ditto, compress'd tar format + + zip11.zip Zip 1.1 (shrinking, implosion; compatible w. PKUNZIP 1.1) + zip11.tar.Z ditto, compress'd tar format + + unzip552.zip UnZip 5.52 (all methods[*]; unzip/funzip/unzipsfx/zipgrep) + unzip552.tar.gz ditto, gzip'd tar format + unzip552.tar.Z ditto, compress'd tar format + + unred552.zip UnZip 5.52 add-on, contains copyrighted unreduce support + + zcrypt29.zip encryption support for Zip 2.3[**] + zcrypt10.zip encryption support for Zip 1.1 + + MacZip106src.zip contains all the GUI stuff and the project files to build + the MacZip main-app. To build MacZip successfully, both + the Zip 2.31 and UnZip 5.52 sources are required, too. + + wiz502.zip WiZ 5.02, Windows 9x/NT GUI front-end for Info-ZIP DLLs + wiz502+dlls.zip WiZ 5.02, Windows 9x/NT GUI front-end plus DLL sources + +[*] Unreducing is disabled by default, but is available as add-on. + As of July 2004, Unisys's LZW patent was expired worldwide, and + unshrinking is turned on by default since the release of UnZip 5.52. + See UnZip's INSTALL file for details. + +[**] As of January 2000, US export regulations were amended to allow export + of free encryption source code from the US. As of June 2002, these + regulations were further relaxed to allow export of encryption binaries + associated with free encryption source code. The Zip 2.31, UnZip 5.52 + and Wiz 5.02 archives now include full crypto source code. As of the + Zip 2.31 release, all official binaries include encryption support; the + former "zcr" archives ceased to exist. + (Note that restrictions may still exist in other countries, of course.) + +Executables archives (and related files) for Info-ZIP's software; not all +of these will be immediately available due to lack of access to appropriate +systems on the part of Info-ZIP members. + + zip231x.zip MSDOS executables and docs + zip231x1.zip OS/2 1.x (16-bit) executables and docs + zip231x2.zip OS/2 2/3/4.x (32-bit) executables and docs + zip231xA.zip Amiga executables and docs + zip231xB.zip BeOS executables and docs + zip231xC.zip VM/CMS executable and docs + zip231xK.zip Tandem NSK executables and docs + zip231xM.xmit MVS classic executable + zip231xM-docs.zip MVS classic port, docs only + zip231dN.zip WinNT/Win9x (Intel) DLL, header files, docs + zip231xN.zip WinNT/Win9x (Intel) executables and docs + zip231xN-axp.zip WinNT (Alpha AXP) executables and docs + zip231xN-mip.zip WinNT (MIPS R4000) executables and docs + zip231xN-ppc.zip WinNT (PowerPC) executables and docs + zip231xO.zip IBM OS/390 Open Edition binaries and docs + zip231xQ.zip SMS/QDOS executables and docs + zip231xR.zip Acorn RISC OS executables and docs + zip231xT.zip Atari TOS executables and docs + zip231-vms-axp-obj.zip + VMS (Alpha AXP) object libs, link procedure and docs + zip231-vms-axp-exe.zip + VMS (Alpha AXP) executables for VMS 6.1 or later and docs + zip231-vms-vax-decc-obj.zip + VMS (VAX) object libs (new DEC C), link procedure and docs + zip231-vms-vax-decc-exe.zip + VMS (VAX) executables (DEC C) for VMS 6.1 or later; docs + zip231-vms-vax-vaxc-obj.zip + VMS (VAX) object libs (old VAX C), link procedure and docs + zip231x.hqx Macintosh BinHex'd executables and docs + + unz552x.exe MSDOS self-extracting executable (16-bit unzip, ..., docs) + unz552x3.exe MSDOS self-extracting executable (16-, 32-bit unzip, docs) + unz552x1.exe OS/2 1.x (16-bit) self-extracting executables and docs + unz552x2.exe OS/2 2/3/4.x (32-bit) self-extracting executables and docs + unz552d2.zip OS/2 2/3/4.x (32-bit) DLL, header file, demo exe and docs + unz552xA.ami Amiga self-extracting executables and docs + unz552xA.lha Amiga executables and docs, LHa archive + unz552xB.sfx BeOS self-extracting executables and docs + unz552xB.tar.gz BeOS executables and docs, gzip'd tar archive + unz552xC.mod VM/CMS executable module in "packed" format + unz552xC-docs.zip VM/CMS docs, only + unz552xF.zip FlexOS executable and docs + unz552xK.zip Tandem NSK executable and docs + unz552xM.xmit MVS classic executable + unz552xM-docs.zip MVS classic port, docs only + unz552dN.zip NT4/W2K/XP/2K3/W9x (32-bit Intel) DLL, header files, docs + unz552xN.exe NT/2K/XP/2K3/W9x self-extracting i386 executables and docs + unz552xN-axp.exe WinNT (Alpha AXP) self-extracting executables and docs + unz552xN-mip.exe WinNT (MIPS R4000) self-extracting executables and docs + unz552xN-ppc.exe WinNT (PowerPC) self-extracting executables and docs + unz552xQ.sfx SMS/QDOS self-extracting executables and docs + unz552xO.tar.Z IBM OS/390 Open edition (Unix-like), exes and docs + unz552xR.exe Acorn RISC OS self-extracting executables and docs + unz552xR.spk Acorn RISC OS Spark'd executables and docs + unz552xT.tos Atari TOS self-extracting executables and docs + unz552x-vms-axp-obj.bck VMS backup saveset, + contains UnZip (Alpha) obj libs, link procedure, docs + unz552x-vms-axp-obj.exe VMS (Alpha AXP) SFX archive (statically linked), + contains UnZip (Alpha) obj libs, link procedure, docs + unz552x-vms-axp-exe.exe VMS (Alpha AXP) SFX archive (dynamically linked), + contains UnZip (Alpha AXP, DEC C) executables and docs, + smaller than object archive, but requires VMS 6.1 + unz552x-vms-vax-decc-obj.bck VMS backup saveset, + contains UnZip (new DEC C) obj libs, link procedure, docs + unz552x-vms-vax-decc-obj.exe VMS (VAX) SFX archive (statically linked), + contains UnZip (new DEC C) obj libs, link procedure, docs + unz552x-vms-vax-decc-exe.exe VMS (VAX) SFX archive (dynamically linked), + contains UnZip (new DEC C) executables and docs, + smaller than object archive, but requires VMS 6.1 + unz552x-vms-vax-vaxc-obj.bck VMS backup saveset, + contains UnZip (old VAX C) obj libs, link procedure, docs + unz552x-vms-vax-vaxc-obj.exe VMS (VAX) SFX archive (statically linked), + contains UnZip (old VAX C) obj libs, link procedure, docs + unz552x.hqx Macintosh BinHex'd executables and docs for unzip + (unz552x.tar.{Z,gz} Unix exes/docs for Solaris 2.x, SCO Unix, Linux, etc., + depending on directory/location; generally only provided + in cases where the OS does *not* ship with a bundled C + compiler) + + MacZip106nc.hqx Macintosh combined Zip&UnZip application with GUI, + executables and docs (no encryption) + MacZip106c.hqx Macintosh combined Zip&UnZip application with GUI, + executables and docs (with encryption) + + wiz502xN.exe WiZ 5.02 32-bit (Win9x/NT/2K/XP/2K3) app+docs (self-extr.) + + UnzpHist.zip complete changes-history of UnZip and its precursors + ZipHist.zip complete changes-history of Zip + +ftp/web sites for the US-exportable sources and executables: + + NOTE: Look for the Info-ZIP file names given above (not PKWARE or third- + party stuff) in the following locations. Some sites like to use slightly + different names, such as zip-2.31.tar.gz instead of zip231.tar.Z. + + ftp://ftp.info-zip.org/pub/infozip/ [THE INFO-ZIP HOME SITE] + ftp://sunsite.doc.ic.ac.uk/packages/zip/ [MIRRORS THE INFO-ZIP HOME SITE] + ftp://unix.hensa.ac.uk/mirrors/uunet/pub/archiving/zip/ + + ftp://ftp.cmdl.noaa.gov/aerosol/doc/archiver/{all,dos,os2,mac,vax_alpha}/ + ftp://garbo.uwasa.fi/pc/arcers/ [AND OTHER GARBO MIRRORS] + ftp://garbo.uwasa.fi/unix/arcers/ [AND OTHER GARBO MIRRORS] + ftp://ftp.elf.stuba.sk/pub/pc/pack/ [AND OTHER STUBA MIRRORS] + ftp://ftp-os2.cdrom.com/pub/os2/archiver/ + ftp://ftp-os2.nmsu.edu/os2/archiver/ + ftp://ftp.informatik.tu-muenchen.de/pub/comp/os/os2/archiver/ + ftp://sumex-aim.stanford.edu/info-mac/cmp/ + ftp://ftp.wustl.edu/pub/aminet/util/arc/ [AND OTHER AMINET MIRRORS] + ftp://atari.archive.umich.edu/pub/Archivers/ [AND OTHER UMICH MIRRORS] + http://www.umich.edu/~archive/atari/Archivers/ + ftp://jake.educom.com.au/pub/infozip/acorn/ [Acorn RISC OS] + http://www.sitec.net/maczip/ [MacZip port] + +ftp/web sites for the encryption and decryption sources and/or executables: + + Outside the US: + ftp://ftp.info-zip.org/pub/infozip/ [THE INFO-ZIP HOME SITE] + ftp://ftp.icce.rug.nl/infozip/ [THE INFO-ZIP ENCRYPTION HOME SITE] + ftp://ftp.elf.stuba.sk/pub/pc/pack/ + ftp://garbo.uwasa.fi/pc/arcers/ + ftp://ftp.inria.fr/system/arch-compr/ + ftp://ftp.leo.org/pub/comp/os/os2/leo/archiver/ + (mail server at ftp-mailer@ftp.leo.org) + + ftp://ftp.win.tue.nl/pub/compression/zip/ + ftp://ftp.uni-erlangen.de/pub/pc/msdos/arc-utils/zip/ + + +The primary distribution site for the MacZip port can be found at: + + http://www.sitec.net/maczip/ + +ftp sites for VMS-format Zip and UnZip packages (sources, object files and +executables, no encryption/decryption--see also "Mail servers" section below): + + ftp.spc.edu [192.107.46.27] and ftp.wku.edu: + + [.MACRO32]AAAREADME.TXT + [.MACRO32.SAVESETS]UNZIP.BCK or UNZIP.ZIP (if already have older version) + [.MACRO32.SAVESETS]ZIP.ZIP + +To find other ftp/web sites: + + The "archie" ftp database utility can be used to find an ftp site near + you (although the command-line versions always seem to find old ver- + sions...the `FTPsearch' server at http://ftpsearch.ntnu.no/ftpsearch + --formerly `Archie 95'--is quite up-to-date, however). Or check a stan- + dard WWW search engine like AltaVista (http://www.altavista.digital.com/) + or Yahoo (http://www.yahoo.com/). If you don't know how to use these, + DON'T ASK US--read the web sites' help pages or check the Usenet groups + news.announce.newusers or news.answers or some such, or ask your system + administrator. + +Mail servers: + + To get the encryption sources by e-mail, send the following commands + to ftp-mailer@informatik.tu-muenchen.de: + + get /pub/comp/os/os2/archiver/zcrypt29.zip + quit + + To get the VMS Zip/UnZip package by e-mail, send the following + commands in the body of a mail message to fileserv@wku.edu (the + "HELP" command is also accepted): + + SEND FILESERV_TOOLS + SEND UNZIP + SEND ZIP + + To get Atari executables by e-mail, send a message to + atari@atari.archive.umich.edu for information about the mail server. +__________________________________________________________________________ diff --git a/acorn/GMakefile b/acorn/GMakefile new file mode 100644 index 0000000..01842c4 --- /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.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.crc32_ 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) h.crc32 + $(CC) $(CFLAGS) -c c.crc32 -o o.crc32 +o.crypt: c.crypt $(ZIP_H) h.crypt h.crc32 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) h.crc32 + $(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.crc32 h.crypt h.revision h.ttyio + $(CC) $(CFLAGS) -c c.zip -o o.zip +o.zipcloak: c.zipcloak $(ZIP_H) h.crc32 h.crypt h.revision h.ttyio + $(CC) $(CFLAGS) -c c.zipcloak -o o.zipcloak +o.zipfile: c.zipfile $(ZIP_H) h.crc32 + $(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.crc32 h.crypt h.revision + $(CC) $(CFLAGS) -c c.zipup -o o.zipup + +o.crc32_: c.crc32 $(ZIP_H) h.crc32 + $(CC) $(CFLAGS) -DUTIL -c c.crc32 -o o.crc32_ +o.crypt_: c.crypt $(ZIP_H) h.crypt h.crc32 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) h.crc32 + $(CC) $(CFLAGS) -DUTIL -c c.fileio -o o.fileio_ +o.zipfile_: c.zipfile $(ZIP_H) h.crc32 + $(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..8762cdb --- /dev/null +++ b/acorn/ReadMe.GMakefile @@ -0,0 +1,16 @@ +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 +. + +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 .srcrename FF8 + +| Run 'srcrename' on the main zip directory with recursion enabled +/.srcrename -r -e c:h:s:o .^ + +| Create the 'o' directory +CDir .^.o + +| Put the Makefile in its correct place and set the correct filetype +Copy .makefile .^.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 .GMakefile .^.makefile ~C~VF + +SetType .^.makefile FE1 +SetType .zipsfx Obey diff --git a/acorn/acornzip.c b/acorn/acornzip.c new file mode 100644 index 0000000..40debc0 --- /dev/null +++ b/acorn/acornzip.c @@ -0,0 +1,592 @@ +/* + Copyright (c) 1990-2002 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#include +#include +#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() */ + /* convert FNMAX to malloc - 11/8/04 EG */ + 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; + } + free(name); + + if (a != NULL) { + *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE); + if ((s.st_mode & S_IFDIR) != 0) { + *a |= MSDOS_DIR_ATTR; + } + } + if (n != NULL) + *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_ctime; + } + + return unix2dostime((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..323ffca --- /dev/null +++ b/acorn/makefile @@ -0,0 +1,115 @@ +# 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 \ + 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) crc32_.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 crc32.o crypt.o fileio.o zipfile.o zipup.o: crc32.h +zipcloak.o crc32_.o crypt_.o fileio_.o zipfile_.o: crc32.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 + +crc32_.o: crc32.c + $(CC) $(CFLAGS) -DUTIL -c c.crc32 -o o.crc32_ +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..9f7783e --- /dev/null +++ b/acorn/osdep.h @@ -0,0 +1,28 @@ +/* + Copyright (c) 1990-2007 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 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_SYMLINKS +#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..84dd2d3 --- /dev/null +++ b/acorn/riscos.c @@ -0,0 +1,394 @@ +/* + Copyright (c) 1990-2002 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* riscos.c */ + +#include +#include +#include +#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..c45a148 --- /dev/null +++ b/acorn/riscos.h @@ -0,0 +1,119 @@ +/* + Copyright (c) 1990-2002 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* riscos.h */ + +#ifndef __riscos_h +#define __riscos_h + +#include +#include + +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<= 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 new file mode 100644 index 0000000..7bd6119 Binary files /dev/null and b/acorn/srcrename differ 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/zipsfx b/acorn/zipsfx new file mode 100644 index 0000000..7d63492 --- /dev/null +++ b/acorn/zipsfx @@ -0,0 +1,9 @@ +| zipsfx 0.1 +| Written by Darren Salt +| Assumes that unzipsfx is on Run$Path (eg. in !Boot.Library) +| Assumes that IfThere is available as either *command or utility + +If "%1" = "" Then Error 220 Syntax: zipsfx | | +If "%0" = "" Then Error 220 Syntax: zipsfx | | +Copy Run:unzipsfx %1 A~C~D~F~L~N~R~S~T~V +Print %0 { >> %1 } \ No newline at end of file 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 diff --git a/amiga/LMKfile b/amiga/LMKfile new file mode 100644 index 0000000..8c838ea --- /dev/null +++ b/amiga/LMKfile @@ -0,0 +1,117 @@ +# Makefile for Zip, ZipNote, ZipCloak and ZipSplit, Amiga SAS/C 5.10b +# See the master Makefile under the top level Zip/Unzip source directory +# for more information on compiler macros and flags for this version. +# Last update: Jan 07, 2007 +# -John Bush, , + + +####################### +# MACROBE DEFINITIONS # +####################### + +# Compiler and loader debug flags. Omit comments as req'd. +# Do not set when building production version. +# CDBG = -d3 +# LDBG = ADDSYM + +DEFINES = -DNO_MKTEMP +CC = lc +OPT = -O +CFLAGS = $(OPT) $(DEFINES) $(CDBG) -v -mat -cuisf -b0 -j85i86i87i100i + +LD = blink +LDSTART = LIB:c.o +LDFLAGS = LIB LIB:lc.lib+LIB:amiga.lib + +TMPFILE = ram:MakeZip.tmp + +############################################### +# BASIC COMPILE INSTRUCTIONS AND DEPENDENCIES # +############################################### + +# default C rules +.c.o: + $(CC) $(CFLAGS) -o$@ $*.c + +# Alternate rules for routines containing entries needed by utilities +.c.oo: + $(CC) $(CFLAGS) -DUTIL -o$*.oo $*.c + +# object file macrough lists + +HFILES = zip.h ziperr.h tailor.h revision.h crc32.h crypt.h ttyio.h \ + amiga/amiga.h amiga/zipup.h amiga/osdep.h + +OBJA = zipfile.o zipup.o fileio.o util.o globals.o crc32.o crypt.o \ + timezone.o ttyio.o amiga.o amigazip.o filedate.o +OBJI = deflate.o trees.o +OBJU = zipfile.oo fileio.oo util.oo globals.o timezone.o \ + amiga.o amigazip.oo filedate.o + +OBJZ = zip.o $(OBJA) $(OBJI) + +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o $(OBJU) crc32.oo crypt.oo ttyio.o +OBJS = zipsplit.o $(OBJU) + +ZIPS = zip zipnote zipcloak zipsplit + +all: Message $(ZIPS) + +Message: + -echo " " + -echo "WARNING: Lattice 5.x HAS NOT BEEN TESTED WITH THIS ZIP VERSION" + -echo "Report problems to " + -echo " " + +zip: $(OBJZ) $(HFILES) + -echo "$(OBJZ)" > $(TMPFILE) + $(LD) TO Zip FROM $(LDSTART) WITH $(TMPFILE) $(LDFLAGS) $(LDBG) + -delete $(TMPFILE) Zip.info + +zipnote: $(OBJN) $(HFILES) + -echo "$(OBJN)" > $(TMPFILE) + $(LD) TO ZipNote FROM $(LDSTART) WITH $(TMPFILE) $(LDFLAGS) $(LDBG) + -delete $(TMPFILE) ZipNote.info + +zipcloak: $(OBJC) $(HFILES) + -echo "$(OBJC)" > $(TMPFILE) + $(LD) TO ZipCloak FROM $(LDSTART) WITH $(TMPFILE) $(LDFLAGS) $(LDBG) + -delete $(TMPFILE) ZipCloak.info + +zipsplit: $(OBJS) $(HFILES) + -echo "$(OBJS)" > $(TMPFILE) + $(LD) TO ZipSplit FROM $(LDSTART) WITH $(TMPFILE) $(LDFLAGS) $(LDBG) + -delete $(TMPFILE) ZipSplit.info + +clean: + -delete $(OBJZ) all quiet force >nil: + -delete $(OBJU) all quiet force >nil: + -delete $(OBJA) all quiet force >nil: + -delete $(OBJI) all quiet force >nil: + -delete $(OBJN) all quiet force >nil: + -delete $(OBJC) all quiet force >nil: + -delete $(OBJS) all quiet force >nil: + +zip.o: zip.c $(HFILES) +zipnote.o: zipnote.c $(HFILES) +zipcloak.o: zipcloak.c $(HFILES) +crypt.o: crypt.c $(HFILES) +ttyio.o: ttyio.c $(HFILES) +zipsplit.o: zipsplit.c $(HFILES) +deflate.o: deflate.c $(HFILES) +trees.o: trees.c $(HFILES) +zipfile.o: zipfile.c $(HFILES) +zipup.o: zipup.c $(HFILES) +fileio.o: fileio.c $(HFILES) +util.o: util.c $(HFILES) +timezone.o: timezone.c $(HFILES) timezone.h +crc32.o: crc32.c $(HFILES) +crctab.o: crctab.c $(HFILES) +globals.o: globals.c $(HFILES) + +# Amiga specific objects +amiga.o: amiga/amiga.c $(HFILES) +amigazip.o: amiga/amigazip.c $(HFILES) + +# end of Makefile diff --git a/amiga/README b/amiga/README new file mode 100644 index 0000000..861ff85 --- /dev/null +++ b/amiga/README @@ -0,0 +1 @@ +the -A option currently does not work for the amiga. diff --git a/amiga/amiga.c b/amiga/amiga.c new file mode 100644 index 0000000..797d6d8 --- /dev/null +++ b/amiga/amiga.c @@ -0,0 +1,138 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2005-Feb-10 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* OS specific routines for AMIGA platform. + * + * John Bush BIX: jbush + * Paul Kienitz + * + * History: + * + * Date DoBee Comments + * ------- -------- ----------------------------------------------- + * 21Jan93 JBush Original coding. + * Incorporated filedate.c (existing routine). + * + * 31Jan93 JBush Made filedate.c include unconditional. + * + * 18Jul93 PaulK Moved Aztec _abort() here from stat.c because we + * can't share the same one between Zip and UnZip. + * Added close_leftover_open_dirs() call to it. + * + * 17Apr95 PaulK Added Amiga internal version string so that + * installer programs can compare the version being + * installed to see if the copy the user already has + * is older or newer. Added Prestart_Hook to support + * debug tracing in deflate.a. + * + * 6May95 PaulK Added GetComment() for filenote support. + * + * 12Nov95 PaulK Added #define ZIP in front of filedate.c, for + * new options in there; removed declare of set_con() + * since echon() no longer expands to it (or anything). + * + * 12Feb96 PaulK Removed call of echon() entirely. + * + * 12Jul97 PaulK Made both Aztec and SAS define USE_TIME_LIB for filedate.c + * + * 26Aug97 PaulK Added ClearIOErr_exit() + * + * 2Jan98 HWalt Adapted for SAS/C using stat.c replacement functions + * + * 6Jun00 PaulK Removed references to time_lib, since new filedate.c + * supercedes it + */ + +#include +#ifdef AZTEC_C +# include +# include +# include +# include +# include +# include +#else +# include +# include +#endif +#include +#include "ziperr.h" +void ziperr(int c, const char *h); + +#define ZIP +#if !defined(UTIL) +# define NO_MKTIME +#endif + +#ifdef AZTEC_C + +/* ============================================================= */ +/* filedate.c is an external file, since it's shared with UnZip. */ +/* Aztec includes it here, but SAS/C now compiles it separately. */ +# include "amiga/filedate.c" + +/* the same applies to stat.c */ +# include "amiga/stat.c" + +# define setenv BOGUS_INCOMPATIBLE_setenv +# include +# undef setenv +# ifdef DEBUG +# define PRESTART_HOOK +# endif +#endif + +extern void close_leftover_open_dirs(void); + + +/* the following handles cleanup when a ^C interrupt happens: */ + +void _abort(void) /* called when ^C is pressed */ +{ + close_leftover_open_dirs(); + ziperr(ZE_ABORT, "^C"); +} + +void ClearIOErr_exit(int e) /* EXIT is defined as this */ +{ + if (!e) + ((struct Process *) FindTask(NULL))->pr_Result2 = 0; + /* we clear IoErr() since we are successful, in a 1.x-compatible way */ + exit(e); +} + + +/* Make sure the version number here matches the number in revision.h */ +/* as closely as possible in strict decimal "#.#" form: */ +const char version_id[] = "\0$VER: Zip 2.3 (" +# include "env:VersionDate" +")\r\n"; + +/* call this with an arg of NULL to free storage: */ + +char *GetComment(char *filename) +{ + BPTR lk; + static struct FileInfoBlock *fib = NULL; + + if (!filename) { + if (fib) FreeMem(fib, sizeof(*fib)); + fib = NULL; + return NULL; + } + if (!fib) { + if (!(fib = AllocMem(sizeof(*fib), MEMF_PUBLIC))) + ziperr(ZE_MEM, "was checking filenotes"); + } + if (!(lk = Lock(filename, ACCESS_READ))) + return NULL; + if (!Examine(lk, fib)) + fib->fib_Comment[0] = '\0'; + UnLock(lk); + return fib->fib_Comment[0] ? &fib->fib_Comment[0] : NULL; +} diff --git a/amiga/amiga.h b/amiga/amiga.h new file mode 100644 index 0000000..a1461d8 --- /dev/null +++ b/amiga/amiga.h @@ -0,0 +1,54 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#ifndef __amiga_amiga_h +#define __amiga_amiga_h + +/* amiga.h + * + * Globular definitions that affect all of AmigaDom. + * + * Originally included in unzip.h, extracted for simplicity and eeze of + * maintenance by John Bush. + * + * This version is for use with Zip. It is not globally included, but used + * only by functions in amiga/amigazip.c. Much material that was needed for + * UnZip is absent here. + * + */ + +#include /* O_BINARY for open() w/o CR/LF translation */ +#include "amiga/z-stat.h" /* substitute for and */ +#define direct dirent + +#ifndef MODERN +# define MODERN +#endif + +#ifdef AZTEC_C /* Manx Aztec C, 5.0 or newer only */ +# include +# include /* do inline dos.library calls */ +# define O_BINARY 0 +#endif /* AZTEC_C */ + + +#ifdef __SASC +# include +# include +# define disk_not_mounted 0 +# if ( (!defined(O_BINARY)) && defined(O_RAW)) +# define O_BINARY O_RAW +# endif +#endif /* SASC */ + + +/* Funkshine Prough Toe Taipes */ + +LONG FileDate (char *, time_t[]); + +#endif /* __amiga_amiga_h */ diff --git a/amiga/amigazip.c b/amiga/amigazip.c new file mode 100644 index 0000000..4e69d62 --- /dev/null +++ b/amiga/amigazip.c @@ -0,0 +1,507 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#include "zip.h" +#include "amiga/amiga.h" + +#ifndef UTIL /* the companion #endif is a bit of ways down ... */ + +#define utime FileDate + +#define PAD 0 +#define PATH_END '/' + +/* Local globals (kinda like "military intelligence" or "broadcast quality") */ + +extern char *label; /* still declared in fileio.c */ +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +/* Local functions */ +local char *readd OF((DIR *)); +local int wild_recurse OF((char *, char *)); + + +local char *readd(d) +DIR *d; /* directory stream to read from */ +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; +} + + +/* What we have here is a mostly-generic routine using opendir()/readd() and */ +/* isshexp()/MATCH() to find all the files matching a multi-part filespec */ +/* using the portable pattern syntax. It shouldn't take too much fiddling */ +/* to make it usable for any other platform that has directory hierarchies */ +/* but no shell-level pattern matching. It works for patterns throughout */ +/* the pathname, such as "foo:*.?/source/x*.[ch]". */ + +#define ONENAMELEN 30 +/* the length of one filename component on the Amiga */ + +/* whole is a pathname with wildcards, wildtail points somewhere in the */ +/* middle of it. All wildcards to be expanded must come AFTER wildtail. */ + +local int wild_recurse(whole, wildtail) char *whole; char *wildtail; +{ + DIR *dir; + char *subwild, *name, *newwhole = NULL, *glue = NULL, plug = 0, plug2; + ush newlen, amatch = 0; + BPTR lok; + int e = ZE_MISS; + + if (!isshexp(wildtail)) + if (lok = Lock(whole, ACCESS_READ)) { /* p exists? */ + UnLock(lok); + return procname(whole, 0); + } else + return ZE_MISS; /* woops, no wildcards! */ + + /* back up thru path components till existing dir found */ + do { + name = wildtail + strlen(wildtail) - 1; + for (;;) + if (name-- <= wildtail || *name == PATH_END) { + subwild = name + 1; + plug2 = *subwild; + *subwild = 0; + break; + } + if (glue) + *glue = plug; + glue = subwild; + plug = plug2; + dir = opendir(whole); + } while (!dir && !disk_not_mounted && subwild > wildtail); + wildtail = subwild; /* skip past non-wild components */ + + if ((subwild = strchr(wildtail + 1, PATH_END)) != NULL) { + /* this "+ 1" dodges the ^^^ hole left by *glue == 0 */ + *(subwild++) = 0; /* wildtail = one component pattern */ + newlen = strlen(whole) + strlen(subwild) + (ONENAMELEN + 2); + } else + newlen = strlen(whole) + (ONENAMELEN + 1); + if (!dir || !(newwhole = malloc(newlen))) { + if (glue) + *glue = plug; + + e = dir ? ZE_MEM : ZE_MISS; + goto ohforgetit; + } + strcpy(newwhole, whole); + newlen = strlen(newwhole); + if (glue) + *glue = plug; /* repair damage to whole */ + if (!isshexp(wildtail)) { + e = ZE_MISS; /* non-wild name not found */ + goto ohforgetit; + } + + while (name = readd(dir)) { + if (MATCH(wildtail, name, 0)) { + strcpy(newwhole + newlen, name); + if (subwild) { + name = newwhole + strlen(newwhole); + *(name++) = PATH_END; + strcpy(name, subwild); + e = wild_recurse(newwhole, name); + } else + e = procname(newwhole, 0); + newwhole[newlen] = 0; + if (e == ZE_OK) + amatch = 1; + else if (e != ZE_MISS) + break; + } + } + + ohforgetit: + if (dir) closedir(dir); + if (subwild) *--subwild = PATH_END; + if (newwhole) free(newwhole); + if (e == ZE_MISS && amatch) + e = ZE_OK; + return e; +} + +int wild(p) char *p; +{ + char *use; + + /* special handling of stdin request */ + if (strcmp(p, "-") == 0) /* if compressing stdin */ + return newname(p, 0, 0); + + /* wild_recurse() can't handle colons in wildcard part: */ + if (use = strchr(p, ':')) { + if (strchr(++use, ':')) + return ZE_PARMS; + } else + use = p; + + return wild_recurse(p, use); +} + + +int procname(n, caseflag) +char *n; /* name to process */ +int caseflag; /* true to force case-sensitive match */ +/* Process a name or sh expression to operate on (or exclude). Return + an error code in the ZE_ class. */ +{ + char *a; /* path and name for recursion */ + DIR *d; /* directory stream from opendir() */ + char *e; /* pointer to name from readd() */ + int m; /* matched flag */ + char *p; /* path for recursion */ + struct stat s; /* result of stat() */ + struct zlist far *z; /* steps through zfiles list */ + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0, caseflag); + else if (LSSTAT(n, &s)) + { + /* Not a file or directory--search for shell expression in zip file */ + p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */ + m = 1; + for (z = zfiles; z != NULL; z = z->nxt) { + if (MATCH(p, z->iname, caseflag)) + { + z->mark = pcount ? filter(z->zname, caseflag) : 1; + if (verbose) + fprintf(mesg, "zip diagnostic: %scluding %s\n", + z->mark ? "in" : "ex", z->name); + m = 0; + } + } + free((zvoid *)p); + return m ? ZE_MISS : ZE_OK; + } + + /* Live name--use if file, recurse if directory */ + if ((s.st_mode & S_IFDIR) == 0) + { + /* add or remove name of file */ + if ((m = newname(n, 0, caseflag)) != ZE_OK) + return m; + } else { + /* Add trailing / to the directory name */ + if ((p = malloc(strlen(n)+2)) == NULL) + return ZE_MEM; + strcpy(p, n); + a = p + strlen(p); + if (*p && a[-1] != '/' && a[-1] != ':') + strcpy(a, "/"); + if (dirnames && (m = newname(p, 1, caseflag)) != ZE_OK) { + free((zvoid *)p); + return m; + } + /* recurse into directory */ + if (recurse && (d = opendir(n)) != NULL) + { + while ((e = readd(d)) != NULL) { + if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL) + { + closedir(d); + free((zvoid *)p); + return ZE_MEM; + } + strcat(strcpy(a, p), e); + if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */ + { + if (m == ZE_MISS) + zipwarn("name not matched: ", a); + else + ziperr(m, a); + } + free((zvoid *)a); + } + closedir(d); + } + free((zvoid *)p); + } /* (s.st_mode & S_IFDIR) == 0) */ + return ZE_OK; +} + +char *ex2in(x, isdir, pdosflag) +char *x; /* external file name */ +int isdir; /* input: x is a directory */ +int *pdosflag; /* output: force MSDOS file attributes? */ +/* Convert the external file name to a zip file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *n; /* internal file name (malloc'ed) */ + char *t; /* shortened name */ + int dosflag; + + dosflag = dosify; /* default for non-DOS and non-OS/2 */ + + /* Find starting point in name before doing malloc */ + if ((t = strrchr(x, ':')) != NULL) /* reject ":" */ + t++; + else + t = x; + { /* reject "//" */ + char *tt = t; + while (tt = strchr(tt, '/')) + while (*++tt == '/') + t = tt; + } + while (*t == '/') /* reject leading "/" on what's left */ + t++; + + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + + if (dosify) + msname(n); + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + return n; +} + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + return x; +} + +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ + time_t u[2]; /* argument for utime() */ + + /* Convert DOS time to time_t format in u */ + u[0] = u[1] = dos2unixtime(d); + + /* Set updated and accessed times of f */ + utime(f, u); +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + /* convert FNMAX to malloc - 11/8/04 EG */ + char *name; + int len = strlen(f); + + if (f == label) { + if (a != NULL) + *a = label_mode; + if (n != NULL) + *n = -2L; /* convention for a label name */ + if (t != NULL) + t->atime = t->mtime = t->ctime = label_utim; + return label_time; + } + if ((name = malloc(len + 1)) == NULL) { + ZIPERR(ZE_MEM, "filetime"); + } + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + + if (strcmp(f, "-") == 0) { + if (fstat(fileno(stdin), &s) != 0) + error("fstat(stdin)"); + } else if (SSTAT(name, &s) != 0) { + /* Accept about any file kind including directories + * (stored with trailing / with -r option) + */ + free(name); + return 0; + } + free(name); + + if (a != NULL) { + *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE); + if ((s.st_mode & S_IFDIR) != 0) { + *a |= MSDOS_DIR_ATTR; + } + } + if (n != NULL) + *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_ctime; + } + + return unix2dostime(&s.st_mtime); +} + +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; + /* create extra field and change z->att if desired */ +{ +#ifdef USE_EF_UT_TIME +#ifdef IZ_CHECK_TZ + if (!zp_tz_is_valid) return ZE_OK; /* skip silently if no valid TZ info */ +#endif + + if ((z->extra = (char *)malloc(EB_HEADSIZE+EB_UT_LEN(1))) == NULL) + return ZE_MEM; + + z->extra[0] = 'U'; + z->extra[1] = 'T'; + z->extra[2] = EB_UT_LEN(1); /* length of data part of e.f. */ + z->extra[3] = 0; + z->extra[4] = EB_UT_FL_MTIME; + z->extra[5] = (char)(z_utim->mtime); + z->extra[6] = (char)(z_utim->mtime >> 8); + z->extra[7] = (char)(z_utim->mtime >> 16); + z->extra[8] = (char)(z_utim->mtime >> 24); + + z->cextra = z->extra; + z->cext = z->ext = (EB_HEADSIZE+EB_UT_LEN(1)); + + return ZE_OK; +#else /* !USE_EF_UT_TIME */ + return (int)(z-z); +#endif /* ?USE_EF_UT_TIME */ +} + +int deletedir(d) +char *d; /* directory to delete */ +/* Delete the directory *d if it is empty, do nothing otherwise. + Return the result of rmdir(), delete(), or system(). + For VMS, d must be in format [x.y]z.dir;1 (not [x.y.z]). + */ +{ + return rmdir(d); +} + +#endif /* !UTIL */ + + +/******************************/ +/* Function version_local() */ +/******************************/ + + +/* NOTE: the following include depends upon the environment + * variable $Workbench to be set correctly. (Set by + * default, by Version command in Startup-sequence.) + */ +int WBversion = (int) +#include "ENV:Workbench" +; + +void version_local() +{ + static ZCONST char CompiledWith[] = "Compiled with %s%s under %s%s%s%s.\n\n"; + +/* Define buffers. */ + + char buf1[16]; /* compiler name */ + char buf2[16]; /* revstamp */ + char buf3[16]; /* OS */ + char buf4[16]; /* Date */ +/* char buf5[16]; /* Time */ + +/* format "with" name strings */ + +#ifdef AMIGA +# ifdef __SASC + strcpy(buf1,"SAS/C "); +# else +# ifdef LATTICE + strcpy(buf1,"Lattice C "); +# else +# ifdef AZTEC_C + strcpy(buf1,"Manx Aztec C "); +# else + strcpy(buf1,"UNKNOWN "); +# endif +# endif +# endif +/* "under" */ + sprintf(buf3,"AmigaDOS v%d",WBversion); +#else + strcpy(buf1,"Unknown compiler "); + strcpy(buf3,"Unknown OS"); +#endif + +/* Define revision, date, and time strings. + * NOTE: Do not calculate run time, be sure to use time compiled. + * Pass these strings via your makefile if undefined. + */ + +#if defined(__VERSION__) && defined(__REVISION__) + sprintf(buf2,"version %d.%d",__VERSION__,__REVISION__); +#else +# ifdef __VERSION__ + sprintf(buf2,"version %d",__VERSION__); +# else + sprintf(buf2,"unknown version"); +# endif +#endif + +#ifdef __DATE__ + sprintf(buf4," on %s",__DATE__); +#else + strcpy(buf4," unknown date"); +#endif + +/****** +#ifdef __TIME__ + sprintf(buf5," at %s",__TIME__); +#else + strcpy(buf5," unknown time"); +#endif +******/ + +/* Print strings using "CompiledWith" mask defined above. + * ("Compiled with %s%s under %s%s%s%s.") + */ + + printf(CompiledWith, + buf1, + buf2, + buf3, + buf4, + /* buf5, */ "", + "" ); /* buf6 not used */ + +} /* end function version_local() */ diff --git a/amiga/crc_68.a b/amiga/crc_68.a new file mode 100644 index 0000000..4cc2a25 --- /dev/null +++ b/amiga/crc_68.a @@ -0,0 +1,144 @@ +;=========================================================================== +; Copyright (c) 1990-2000 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 2000-Apr-09 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, all these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +;=========================================================================== +; crc_68 created by Paul Kienitz, last modified 04 Jan 96. +; +; Return an updated 32 bit CRC value, given the old value and a block of data. +; The CRC table used to compute the value is gotten by calling get_crc_table(). +; This replaces the older updcrc() function used in Zip and fUnZip. The +; prototype of the function is: +; +; ulg crc32(ulg crcval, uch *text, extent textlen); +; +; On the Amiga, type extent is always unsigned long, not unsigned int, because +; int can be short or long at whim, but size_t is long. +; +; If using this source on a non-Amiga 680x0 system, note that we treat +; a0/a1/d0/d1 as scratch registers not preserved across function calls. +; We do not bother to support registerized arguments for crc32() -- the +; textlen parm is usually large enough so that savings outside the loop +; are pointless. +; +; Define NO_UNROLLED_LOOPS to use a simple short loop which might be more +; efficient on certain machines with dinky instruction caches ('020?), or for +; processing short strings. If loops are unrolled, the textlen parm must be +; less than 512K; if not unrolled, it must be less than 64K. + + xdef _crc32 ; (ulg val, uch *buf, extent bufsize) + +DO_CRC0 MACRO + moveq #0,ltemp + move.b (textbuf)+,ltemp + eor.b crcval,ltemp + lsl.w #2,ltemp + move.l (crc_table,ltemp.w),ltemp + lsr.l #8,crcval + eor.l ltemp,crcval + ENDM + + machine mc68020 + +DO_CRC2 MACRO + move.b (textbuf)+,btemp + eor.b crcval,btemp + lsr.l #8,crcval + move.l (crc_table,btemp.w*4),ltemp + eor.l ltemp,crcval + ENDM + +crc_table equr a0 array of unsigned long +crcval equr d0 unsigned long initial value +textbuf equr a1 array of unsigned char +textbufsize equr d1 unsigned long (count of bytes in textbuf) +btemp equr d2 +ltemp equr d3 + + + xref _get_crc_table ; ulg *get_crc_table(void) + + NOLIST + INCLUDE 'exec/execbase.i' + LIST + xref _SysBase ; struct ExecBase * + + +_crc32: + move.l 8(sp),d0 + bne.s valid + moveq #0,d0 + rts +valid: movem.l btemp/ltemp,-(sp) + jsr _get_crc_table + move.l d0,ltemp + move.l 12(sp),crcval + move.l 16(sp),textbuf + move.l 20(sp),textbufsize + not.l crcval + move.l _SysBase,crc_table + move.w AttnFlags(crc_table),btemp + move.l ltemp,crc_table + btst #AFB_68020,btemp + bne twenty + + IFD NO_UNROLLED_LOOPS + + bra.s decr +loop: DO_CRC0 +decr: dbra textbufsize,loop + bra.s done + +twenty: moveq #0,btemp + bra.s decr2 +loop2: DO_CRC2 +decr2: dbra textbufsize,loop2 + + ELSE ; !NO_UNROLLED_LOOPS + + move.l textbufsize,btemp + lsr.l #3,textbufsize + bra decr8 +loop8: DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 +decr8: dbra textbufsize,loop8 + and.w #7,btemp + bra.s decr1 +loop1: DO_CRC0 +decr1: dbra btemp,loop1 + bra done + +twenty: moveq #0,btemp + move.l textbufsize,-(sp) + lsr.l #3,textbufsize + bra decr82 +loop82: DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 +decr82: dbra textbufsize,loop82 + move.l (sp)+,textbufsize + and.w #7,textbufsize + bra.s decr12 +loop12: DO_CRC2 +decr12: dbra textbufsize,loop12 + + ENDC ; ?NO_UNROLLED_LOOPS + +done: movem.l (sp)+,btemp/ltemp + not.l crcval +;;;;; move.l crcval,d0 ; crcval already is d0 + rts diff --git a/amiga/deflate.a b/amiga/deflate.a new file mode 100644 index 0000000..b21adae --- /dev/null +++ b/amiga/deflate.a @@ -0,0 +1,1053 @@ +;=========================================================================== +; Copyright (c) 1990-1999 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 1999-Oct-05 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, both of these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +;=========================================================================== +; This is a 680x0 assembly language translation of the Info-ZIP source file +; deflate.c, by Paul Kienitz. The function longest_match is based in part +; on match.a by Carsten Steger, which in turn is partly based on match.s +; for 386 by Jean-loup Gailly and Kai Uwe Rommel. Mostly, however, this +; material is based on deflate.c, by Gailly, Rommel, and Igor Mandrichenko. +; This code is not commented very much; see deflate.c for comments that explain +; what the functions are doing. +; +; The symbols that can be used to select different versions are as follows: +; +; CPU020 if defined, use 68020 instructions always. +; +; CPUTEST if defined, check at runtime for CPU type. Another symbol +; specifying the platform-specific test must be used with this. +; If neither of these is defined, use 68000 instructions only. +; Runtime test is nonportable; it is different for each OS. +; +; AMIGA use Amiga-specific test for 68020, if CPUTEST defined. Also +; tells it that registers d0/a0/d1/a1 are not preserved by +; function calls. At present, if AMIGA is not defined, it +; causes functions to preserve all registers. ALL OF THIS CODE +; CURRENTLY ASSUMES THAT REGISTERS D2-D7/A2-A6 WILL BE PRESERVED +; BY ANY FUNCTIONS THAT IT CALLS. +; +; DYN_ALLOC should be defined here if it is defined for C source; tells us +; that big arrays are allocated instead of static. +; +; WSIZE must be defined as the same number used for WSIZE in the C +; source, and must be a power of two <= 32768. As elsewhere, +; the default value is 32768. +; +; INT16 define this if ints are 16 bits; otherwise 32 bit ints assumed. +; +; SMALL_MEM define this if it is defined in the C source; otherwise it uses +; the MEDIUM_MEM model. BIG_MEM and MMAP are *not* supported. +; The FULL_SEARCH option in deflate.c is also not supported. +; +; DEBUG activates some tracing output, as in the C source. +; +; QUADLONG this selects a different version of the innermost longest_match +; loop code for 68020 operations, comparing bytes four at a time +; instead of two at a time. It seems to be a tiny bit faster on +; average, but it's slower often enough that one can't generalize. +; +; This code currently assumes that function results are returned in D0 for +; all platforms. It assumes that args to functions are pushed onto the stack, +; last arg first. It also currently assumes that all C symbols have an +; underscore prepended when referenced from assembly. + + IFND CPU020 + IFND CPUTEST +CPU000 equ 1 + ENDC + ENDC + +; Use these macros for accessing variables of type int: + IFD INT16 +MOVINT MACRO + move.w \1,\2 + ENDM +CLRINT MACRO + clr.w \1 + ENDM +INTSIZE equ 2 + ELSE ; !INT16 +MOVINT MACRO + move.l \1,\2 + ENDM +CLRINT MACRO + clr.l \1 + ENDM +INTSIZE equ 4 + ENDC + + IFD DYN_ALLOC +BASEPTR MACRO + move.l \1,\2 + ENDM + ELSE +BASEPTR MACRO + lea \1,\2 + ENDM + ENDC + +; constants we use, many of them adjustable: + +MAX_MATCH equ 258 +MIN_MATCH equ 3 +TOO_FAR equ 4096 + IFND WSIZE +WSIZE equ 32768 + ENDC +WMASK equ WSIZE-1 +MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1 +MIN_LOOKAHEAD equ MAX_MATCH+MIN_MATCH+1 +; IFD BIG_MEM ; NOT supported -- type Pos needs to be 32 bits +;HASH_BITS equ 15 +; ELSE + IFD SMALL_MEM +HASH_BITS equ 13 + ELSE +HASH_BITS equ 14 ; default -- MEDIUM_MEM + ENDC +; ENDC ; BIG_MEM +HASH_SIZE equ 1< + MOVINT Strst,_strstart ; ct_tally reads this variable + moveq #0,d0 + move.b -1(Window,Strst.l),d0 + MOVINT d0,-(sp) + CLRINT -(sp) + jsr _ct_tally + addq #2*INTSIZE,sp + tst.w d0 + beq.s skipliteral + FLUSH_B #0 + move.l Strst,_block_start +skipliteral: + addq.w #1,Strst + subq.w #1,Look + +refill: + cmp.w #MIN_LOOKAHEAD,Look + bhs look_loop + bsr fill_window + bra look_loop + +last_tally: + tst.w Avail + beq last_flush + MOVINT Strst,_strstart ; ct_tally reads this variable + moveq #0,d0 + move.b -1(Window,Strst.l),d0 + MOVINT d0,-(sp) + CLRINT -(sp) + jsr _ct_tally + addq #2*INTSIZE,sp +last_flush: + FLUSH_B #1 + bra deflate_exit + +; ================== This is another version used for low compression levels: + +deflate_fast: + moveq #0,MatchL + moveq #MIN_MATCH-1,PrevL +flook_loop: + tst.w Look + beq flast_flush + + IN_STR a0,d0 + tst.w Head + beq.s fno_new_match + move.w Strst,d0 + sub.w Head,d0 + cmp.w #MAX_DIST,d0 + bhi.s fno_new_match + move.w PrevL,prev_length ; longest_match reads these variables + MOVINT Strst,_strstart + MOVINT Head,d0 ; parm for longest_match + bsr longest_match ; sets match_start + cmp.w Look,d0 ; does length exceed valid data? + bls.s fstml + move.w Look,d0 +fstml: move.w d0,MatchL ; valid length of match + +fno_new_match: + cmp.w #MIN_MATCH,MatchL + blo fliteral + ; CHECK_MATCH Strst,match_start,MatchL + MOVINT Strst,_strstart ; ct_tally reads this variable + move.l MatchL,d0 + subq.w #MIN_MATCH,d0 + MOVINT d0,-(sp) + move.l Strst,d0 + sub.w match_start,d0 + MOVINT d0,-(sp) + jsr _ct_tally ; sets d0 true if we have to flush + addq #2*INTSIZE,sp + sub.w MatchL,Look + cmp.w max_lazy_match,MatchL + bhi ftoolong + subq.w #2,MatchL +finsertmatch: + addq.w #1,Strst + IN_STR a0,d1 ; preserve d0 + dbra MatchL,finsertmatch + moveq #0,MatchL ; not needed? + addq.w #1,Strst + bra.s flushfill + +ftoolong: + add.w MatchL,Strst + moveq #0,MatchL + moveq #0,d1 ; preserve d0 + move.b (Window,Strst.l),d1 + move.w d1,ins_h +; My assembler objects to passing <1(Window,Strst.l)> directly to UP_HASH... + move.b 1(Window,Strst.l),Avail ; Avail is not used in deflate_fast + UP_HASH d1,Avail ; preserve d0 + IFNE MIN_MATCH-3 + FAIL needs to UP_HASH another MIN_MATCH-3 times, but with what arg? + ENDC + bra.s flushfill + +fliteral: + TRACE_C <(Window,Strst.l)> + MOVINT Strst,_strstart ; ct_tally reads this variable + moveq #0,d0 + move.b (Window,Strst.l),d0 + MOVINT d0,-(sp) + CLRINT -(sp) + jsr _ct_tally ; d0 set if we need to flush + addq #2*INTSIZE,sp + addq.w #1,Strst + subq.w #1,Look + +flushfill: + tst.w d0 + beq.s frefill + FLUSH_B #0 + move.l Strst,_block_start +frefill: + cmp.w #MIN_LOOKAHEAD,Look + bhs flook_loop + bsr fill_window + bra flook_loop + +flast_flush: + FLUSH_B #1 ; sets our return value + +deflate_exit: + MOVINT Strst,_strstart ; save back cached values + move.w PrevL,prev_length + move.w Look,lookahead + movem.l (sp)+,DEFREGS + rts + + +; ========================================================================= +; void fill_window(void) calls the input function to refill the sliding +; window that we use to find substring matches in. + +More equr Head ; local variable in fill_window +WindTop equr Prev ; local variable used for sliding +SlidIx equr PrevL ; local variable used for sliding + + IFD AMIGA +FWREGS reg d2-d5/a2-a6 ; does NOT include Look and Strst + ELSE +FWREGS reg d1-d5/a0-a6 ; likewise + ENDC +; all registers available to be clobbered by the sliding operation: +; we exclude More, WindTop, SlidIx, Look, Strst, Window, a4 and a7. +SPAREGS reg d0-d3/a0-a1/a5-a6 +SPCOUNT equ 8 ; number of registers in SPAREGS + + +_fill_window: ; C-callable entry point + movem.l Strst/Look,-(sp) + IFD INT16 + moveq #0,Strst ; Strst must be valid as a long + ENDC + MOVINT _strstart,Strst + move.w lookahead,Look + BASEPTR _window,Window + bsr.s fill_window + MOVINT Strst,_strstart + move.w Look,lookahead + movem.l (sp)+,Strst/Look + rts + +; strstart, lookahead, and window must be cached in Strst, Look, and Window: +fill_window: ; asm-callable entry point + movem.l FWREGS,-(sp) + tst.w eofile ; we put this up here for speed + bne fwdone + and.l #$FFFF,Look ; make sure Look is valid as long +fw_refill: + move.l _window_size,More ; <= 64K + sub.l Look,More + sub.l Strst,More ; Strst is already valid as long + cmp.w #EOF,More + bne.s notboundary + subq.w #1,More + bra checkend + +notboundary: + tst.w sliding + beq checkend + cmp.w #WSIZE+MAX_DIST,Strst + blo checkend + IFGT 32768-WSIZE + lea WSIZE(Window),WindTop ; WindTop is aligned when Window is + ELSE + move.l Window,WindTop + add.l #WSIZE,WindTop + ENDC + move.l Window,d0 + and.w #3,d0 + beq.s isaligned + subq.w #1,d0 +align: move.b (WindTop)+,(Window)+ ; copy up to a longword boundary + dbra d0,align +isaligned: +; This is faster than a simple move.l (WindTop)+,(Window)+ / dbra loop: + move.w #(WSIZE-1)/(4*SPCOUNT),SlidIx +slide: movem.l (WindTop)+,SPAREGS ; copy, 32 bytes at a time! + movem.l SPAREGS,(Window) ; a slight overshoot doesn't matter. + lea 4*SPCOUNT(Window),Window ; can't use (aN)+ as movem.l dest + dbra SlidIx,slide + BASEPTR _window,Window ; restore cached value + sub.w #WSIZE,match_start + sub.w #WSIZE,Strst + sub.l #WSIZE,_block_start + add.w #WSIZE,More + BASEPTR _head,a0 + move.w #HASH_SIZE-1,d0 +fixhead: + move.w (a0),d1 + sub.w #WSIZE,d1 + bpl.s headok + moveq #0,d1 +headok: move.w d1,(a0)+ + dbra d0,fixhead + BASEPTR _prev,a0 + move.w #WSIZE-1,d0 +fixprev: + move.w (a0),d1 + sub.w #WSIZE,d1 + bpl.s prevok + moveq #0,d1 +prevok: move.w d1,(a0)+ + dbra d0,fixprev + TRACE_C #'.' + +checkend: ; assert eofile is false + MOVINT More,-(sp) ; assert More's upper word is zero + move.l Strst,d0 + add.w Look,d0 + add.l Window,d0 + move.l d0,-(sp) + move.l _read_buf,a0 + jsr (a0) ; refill the upper part of the window + addq #4+INTSIZE,sp + tst.w d0 + beq.s iseof + cmp.w #EOF,d0 + beq.s iseof + add.w d0,Look + cmp.w #MIN_LOOKAHEAD,Look + blo fw_refill ; eofile is still false + + bra.s fwdone +iseof: move.w #1,eofile +fwdone: movem.l (sp)+,FWREGS + rts + + +; ========================================================================= +; void lm_free(void) frees dynamic arrays in the DYN_ALLOC version. + + xdef _lm_free ; the entry point + +_lm_free: + IFD DYN_ALLOC + move.l _window,d0 + beq.s lf_no_window + move.l d0,-(sp) + jsr _free + addq #4,sp + clr.l _window +lf_no_window: + move.l _prev,d0 + beq.s lf_no_prev + move.l d0,-(sp) + jsr _free + move.l _head,(sp) ; reuse the same stack arg slot + jsr _free + addq #4,sp + clr.l _prev + clr.l _head +lf_no_prev: + ENDC + rts + +; ============================================================================ +; void lm_init(int pack_level, unsigned short *flags) allocates dynamic arrays +; if any, and initializes all variables so that deflate() is ready to go. + + xdef _lm_init ; the entry point + +Level equr d2 +;Window equr a2 ; as in deflate() + IFD AMIGA +INIREGS reg d2/a2 + ELSE +INIREGS reg d0-d2/a0-a1 + ENDC + +_lm_init: + MOVINT 4(sp),d0 + move.l 4+INTSIZE(sp),a0 + movem.l INIREGS,-(sp) + move.w d0,Level + cmp.w #1,Level + blt.s levelerr + bgt.s try9 + bset.b #B_FAST,1(a0) +try9: cmp.w #9,Level + bgt.s levelerr + blt.s levelok + bset.b #B_SLOW,1(a0) + bra.s levelok +levelerr: + pea level_message + jsr _error ; never returns +levelok: + clr.w sliding + tst.l _window_size + bne.s gotawindowsize + move.w #1,sliding + move.l #2*WSIZE,_window_size +gotawindowsize: + + BASEPTR _window,Window + IFD DYN_ALLOC + move.l Window,d0 ; fake tst.l + bne.s gotsomewind + CAL_SH WSIZE + move.l d0,Window + move.l d0,_window + bne.s gotsomewind + pea window_message + MOVINT #ZE_MEM,-(sp) + jsr _ziperr ; never returns +gotsomewind: + tst.l _prev + bne.s gotsomehead + CAL_SH WSIZE + move.l d0,_prev + beq.s nohead + CAL_SH HASH_SIZE + move.l d0,_head + bne.s gotfreshhead ; newly calloc'd memory is zeroed +nohead: pea hash_message + MOVINT #ZE_MEM,-(sp) + jsr _ziperr ; never returns +gotsomehead: + ENDC ; DYN_ALLOC + + move.w #(HASH_SIZE/2)-1,d0 ; two shortwords per loop + BASEPTR _head,a0 +wipeh: clr.l (a0)+ + dbra d0,wipeh +gotfreshhead: + move.l Level,d0 + IFEQ Sizeof_config-8 + asl.l #3,d0 + ELSE + mulu #Sizeof_config,d0 + ENDC + lea config_table,a0 + add.l d0,a0 + move.w Max_lazy(a0),max_lazy_match + move.w Good_length(a0),good_match + move.w Nice_length(a0),nice_match + move.w Max_chain(a0),max_chain_len + CLRINT _strstart + clr.l _block_start + bsr match_init + + clr.w eofile + MOVINT #WSIZE,-(sp) ; We read only 32K because lookahead is short + move.l Window,-(sp) ; even when int size is long, as if deflate.c + move.l _read_buf,a0 ; were compiled with MAXSEG_64K defined. + jsr (a0) + addq #4+INTSIZE,sp + move.w d0,lookahead + beq.s noread + cmp.w #EOF,d0 + bne.s irefill +noread: move.w #1,eofile + clr.w lookahead + bra.s init_done + +irefill: + move.w lookahead,d0 + cmp.w #MIN_LOOKAHEAD,d0 + bhs.s hashify + bsr _fill_window ; use the C-callable version +hashify: + clr.w ins_h + moveq #MIN_MATCH-2,d0 +hash1: move.b (Window)+,d1 + UP_HASH Level,d1 + dbra d0,hash1 + +init_done: + movem.l (sp)+,INIREGS + rts + +; strings for error messages: +hash_message dc.b 'hash table allocation',0 +window_message dc.b 'window allocation',0 +level_message dc.b 'bad pack level',0 + + end diff --git a/amiga/filedate.c b/amiga/filedate.c new file mode 100644 index 0000000..9ccbdda --- /dev/null +++ b/amiga/filedate.c @@ -0,0 +1,599 @@ +/* + Copyright (c) 1990-2002 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* Low-level Amiga routines shared between Zip and UnZip. + * + * Contains: FileDate() + * getenv() [replaces inadequate standard library version] + * setenv() [SAS/C only, replaces standard library version] + * set_TZ() [SAS/C only] + * GetPlatformLocalTimezone() [callback from timezone.c tzset()] + * time() + * sendpkt() + * Agetch() + * + * The first five are used by most Info-ZIP programs except fUnZip. + * The last two are used by all except the non-CRYPT version of fUnZip. + * Probably some of the stuff in here is unused by ZipNote and ZipSplit too... + * sendpkt() is used by Agetch() and FileDate(), and by screensize() in + * amiga/amiga.c (UnZip); time() is used only by Zip. + */ + + +/* HISTORY/CHANGES + * 2 Sep 92, Greg Roelofs, Original coding. + * 6 Sep 92, John Bush, Incorporated into UnZip 5.1 + * 6 Sep 92, John Bush, Interlude "FileDate()" defined, which calls or + * redefines SetFileDate() depending upon AMIGADOS2 definition. + * 11 Oct 92, John Bush, Eliminated AMIGADOS2 switch by determining + * revision via OpenLibrary() call. Now only one version of + * the program runs on both platforms (1.3.x vs. 2.x) + * 11 Oct 92, John Bush, Merged with Zip version and changed arg passing + * to take time_t input instead of struct DateStamp. + * Arg passing made to conform with utime(). + * 22 Nov 92, Paul Kienitz, fixed includes for Aztec and cleaned up some + * lint-ish errors; simplified test for AmigaDOS version. + * 11 Nov 95, Paul Kienitz, added Agetch() for crypt password input and + * UnZip's "More" prompt -- simplifies crypt.h and avoids + * use of library code redundant with sendpkt(). Made it + * available to fUnZip, which does not use FileDate(). + * 22 Nov 95, Paul Kienitz, created a new tzset() that gets the current + * timezone from the Locale preferences. These exist only under + * AmigaDOS 2.1 and up, but it is probably correctly set on more + * Amigas than the TZ environment variable is. We check that + * only if TZ is not validly set. We do not parse daylight + * savings syntax except to check for presence vs. absence of a + * DST part; United States rules are assumed. This is better + * than the tzset()s in the Amiga compilers' libraries do. + * 15 Jan 96, Chr. Spieler, corrected the logic when to select low level + * sendpkt() (when FileDate(), Agetch() or windowheight() is used), + * and AMIGA's Agetch() (CRYPT, and UnZip(SFX)'s UzpMorePause()). + * 10 Feb 96, Paul Kienitz, re-fiddled that selection logic again, moved + * stuff around for clarity. + * 16 Mar 96, Paul Kienitz, created a replacement localtime() to go with the + * new tzset(), because Aztec's is hopelessly broken. Also + * gmtime(), which localtime() calls. + * 12 Apr 96, Paul Kienitz, daylight savings was being handled incorrectly. + * 21 Apr 96, Paul Kienitz, had to replace time() as well, Aztec's returns + * local time instead of GMT. That's why their localtime() was bad, + * because it assumed time_t was already local, and gmtime() was + * the one that checked TZ. + * 23 Apr 96, Chr. Spieler, deactivated time() replacement for UnZip stuff. + * Currently, the UnZip sources do not make use of time() (and do + * not supply the working mktime() replacement, either!). + * 29 Apr 96, Paul Kienitz, created a replacement getenv() out of code that + * was previously embedded in tzset(), for reliable global test + * of whether TZ is set or not. + * 19 Jun 96, Haidinger Walter, re-adapted for current SAS/C compiler. + * 7 Jul 96, Paul Kienitz, smoothed together compiler-related changes. + * 4 Feb 97, Haidinger Walter, added set_TZ() for SAS/C. + * 23 Apr 97, Paul Kienitz, corrected Unix->Amiga DST error by adding + * mkgmtime() so localtime() could be used. + * 28 Apr 97, Christian Spieler, deactivated mkgmtime() definition for ZIP; + * the Zip sources supply this function as part of util.c. + * 24 May 97, Haidinger Walter, added time_lib support for SAS/C and moved + * set_TZ() to time_lib.c. + * 12 Jul 97, Paul Kienitz, adapted time_lib stuff for Aztec. + * 26 Jul 97, Chr. Spieler, old mkgmtime() fixed (ydays[] def, sign vs unsign). + * 30 Dec 97, Haidinger Walter, adaptation for SAS/C using z-stat.h functions. + * 19 Feb 98, Haidinger Walter, removed alloc_remember, more SAS.C fixes. + * 23 Apr 98, Chr. Spieler, removed mkgmtime(), changed FileDate to convert to + * Amiga file-time directly. + * 24 Apr 98, Paul Kienitz, clip Unix dates earlier than 1978 in FileDate(). + * 02 Sep 98, Paul Kienitz, C. Spieler, always include zip.h to get a defined + * header inclusion sequence that resolves all header dependencies. + * 06 Jun 00, Paul Kienitz, removed time_lib.c due to its incompatible license, + * moved set_TZ() back here, replaced minimal tzset() and localtime() + * with new versions derived from GNU glibc source. Gave locale_TZ() + * reasonable European defaults for daylight savings. + * 17 Jun 00, Paul Kienitz, threw out GNU code because of objections to the GPL + * virus, replaced with similar functions based on the public domain + * timezone code at ftp://elsie.nci.nih.gov/pub. As with the GNU + * stuff, support for timezone files and leap seconds was removed. + * 23 Aug 00, Paul Kienitz, moved timezone code out from here into separate + * platform-independent module 'timezone.c'. + * 31 Dec 00, Christian Spieler, moved system-specific timezone help funcions + * back in here, from 'timezone.c'. + * 07 Jan 01, Paul Kienitz, Chr. Spieler, added missing #include "timezone.h" + * and "symbolic" preprocessor constants for time calculations. + * 15 Jan 02, Paul Kienitz, excluded all time handling code from compilation + * for Zip utilities (when "defined(UTIL)") + */ + +#ifndef __amiga_filedate_c +#define __amiga_filedate_c + + +#include "zip.h" +#include +#include + +#include +#include +#include +#include + +#ifdef AZTEC_C +# include +# include +# include +# include +# include +# include +# include +# include +# define ESRCH ENOENT +# define EOSERR EIO +#endif + +#ifdef __SASC +# include +# if (defined(_M68020) && (!defined(__USE_SYSBASE))) + /* on 68020 or higher processors it is faster */ +# define __USE_SYSBASE /* to use the pragma libcall instead of syscall */ +# endif /* to access functions of the exec.library */ +# include /* see SAS/C manual:part 2,chapter 2,pages 6-7 */ +# include +# include +# ifdef DEBUG +# include +# endif +# ifdef MWDEBUG +# include /* include both before memwatch.h again just */ +# include /* to be safe */ +# include "memwatch.h" +# endif /* MWDEBUG */ +#endif /* __SASC */ + +#include "crypt.h" /* just so we can tell if CRYPT is supported */ + + +#if (!defined(FUNZIP) && !defined(UTIL)) + +#include "timezone.h" /* for AMIGA-specific timezone callbacks */ + +#ifndef SUCCESS +# define SUCCESS (-1L) +# define FAILURE 0L +#endif + +#define ReqVers 36L /* required library version for SetFileDate() */ +#define ENVSIZE 100 /* max space allowed for an environment var */ + +extern struct ExecBase *SysBase; + +#ifndef min +# define min(a, b) ((a) < (b) ? (a) : (b)) +# define max(a, b) ((a) < (b) ? (b) : (a)) +#endif + +#if defined(ZIP) || defined(HAVE_MKTIME) +static const unsigned short ydays[] = + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; +#else +extern const unsigned short ydays[]; /* in unzip's fileio.c */ +#endif + +#define LEAP(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0) +#define YDAYS(m, y) (ydays[m] + (m > 1 && LEAP(y))) +/* Number of leap years from 1978 to `y' (not including `y' itself). */ +#define ANLEAP(y) (((y) - 1977) / 4 - ((y) - 1901) / 100 + ((y) - 1601) / 400) +#define SECSPERMIN 60 +#define MINSPERHOUR 60 +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +#define SECSPERDAY 86400L + +/* prototypes */ +char *getenv(const char *var); +#ifdef __SASC +/* XXX !! We have really got to find a way to operate without these. */ +int setenv(const char *var, const char *value, int overwrite); +void set_TZ(long time_zone, int day_light); +#endif + +LONG FileDate(char *filename, time_t u[]); +LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs); +int Agetch(void); + +/* =============================================================== */ + +/***********************/ +/* Function filedate() */ +/***********************/ + +/* FileDate() (originally utime.c), by Paul Wells. Modified by John Bush + * and others (see also sendpkt() comments, below); NewtWare SetFileDate() + * clone cheaply ripped off from utime(). + */ + +/* DESCRIPTION + * This routine chooses between 2 methods to set the file date on AMIGA. + * Since AmigaDOS 2.x came out, SetFileDate() was available in ROM (v.36 + * and higher). Under AmigaDOS 1.3.x (less than v.36 ROM), SetFileDate() + * must be accomplished by constructing a message packet and sending it + * to the file system handler of the file to be stamped. + * + * The system's ROM version is extracted from the external system Library + * base. + * + * NOTE: although argument passing conforms with utime(), note the + * following differences: + * - Return value is boolean success/failure. + * - If a structure or array is passed, only the first value + * is used, which *may* correspond to date accessed and not + * date modified. + */ + +LONG FileDate(filename, u) + char *filename; + time_t u[]; +{ + LONG SetFileDate(UBYTE *filename, struct DateStamp *pDate); + LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs); + struct MsgPort *taskport; + BPTR dirlock, lock; + struct FileInfoBlock *fib; + LONG pktargs[4]; + UBYTE *ptr; + long ret; + + struct DateStamp pDate; + struct tm *ltm; + int years; + + tzset(); + /* Amiga file date is based on 01-Jan-1978 00:00:00 (local time): + * 8 years and 2 leapdays difference from Unix time. + */ + ltm = localtime(&u[0]); + years = ltm->tm_year + 1900; + if (years < 1978) + pDate.ds_Days = pDate.ds_Minute = pDate.ds_Tick = 0; + else { + pDate.ds_Days = (years - 1978) * 365L + (ANLEAP(years)) + + YDAYS(ltm->tm_mon, years) + (ltm->tm_mday - 1); + pDate.ds_Minute = ltm->tm_hour * 60 + ltm->tm_min; + pDate.ds_Tick = ltm->tm_sec * TICKS_PER_SECOND; + } + + if (SysBase->LibNode.lib_Version >= ReqVers) + { + return (SetFileDate(filename,&pDate)); /* native routine at 2.0+ */ + } + else /* !(SysBase->lib_Version >=ReqVers) */ + { + if( !(taskport = (struct MsgPort *)DeviceProc(filename)) ) + { + errno = ESRCH; /* no such process */ + return FAILURE; + } + + if( !(lock = Lock(filename,SHARED_LOCK)) ) + { + errno = ENOENT; /* no such file */ + return FAILURE; + } + + if( !(fib = (struct FileInfoBlock *)AllocMem( + (long)sizeof(struct FileInfoBlock),MEMF_PUBLIC|MEMF_CLEAR)) ) + { + errno = ENOMEM; /* insufficient memory */ + UnLock(lock); + return FAILURE; + } + + if( Examine(lock,fib)==FAILURE ) + { + errno = EOSERR; /* operating system error */ + UnLock(lock); + FreeMem(fib,(long)sizeof(*fib)); + return FAILURE; + } + + dirlock = ParentDir(lock); + ptr = (UBYTE *)AllocMem(64L,MEMF_PUBLIC); + strcpy((ptr+1),fib->fib_FileName); + *ptr = strlen(fib->fib_FileName); + FreeMem(fib,(long)sizeof(*fib)); + UnLock(lock); + + /* now fill in argument array */ + + pktargs[0] = 0; + pktargs[1] = (LONG)dirlock; + pktargs[2] = (LONG)&ptr[0] >> 2; + pktargs[3] = (LONG)&pDate; + + errno = ret = sendpkt(taskport,ACTION_SET_DATE,pktargs,4L); + + FreeMem(ptr,64L); + UnLock(dirlock); + + return SUCCESS; + } /* ?(SysBase->lib_Version >= ReqVers) */ +} /* FileDate() */ + + +char *getenv(const char *var) /* not reentrant! */ +{ + static char space[ENVSIZE]; + struct Process *me = (void *) FindTask(NULL); + void *old_window = me->pr_WindowPtr; + char *ret = NULL; + + me->pr_WindowPtr = (void *) -1; /* suppress any "Please insert" popups */ + if (SysBase->LibNode.lib_Version >= ReqVers) { + if (GetVar((char *) var, space, ENVSIZE - 1, /*GVF_GLOBAL_ONLY*/ 0) > 0) + ret = space; + } else { /* early AmigaDOS, get env var the crude way */ + BPTR hand, foot, spine; + int z = 0; + if (foot = Lock("ENV:", ACCESS_READ)) { + spine = CurrentDir(foot); + if (hand = Open((char *) var, MODE_OLDFILE)) { + z = Read(hand, space, ENVSIZE - 1); + Close(hand); + } + UnLock(CurrentDir(spine)); + } + if (z > 0) { + space[z] = '\0'; + ret = space; + } + } + me->pr_WindowPtr = old_window; + return ret; +} + +#ifdef __SASC +int setenv(const char *var, const char *value, int overwrite) +{ + struct Process *me = (void *) FindTask(NULL); + void *old_window = me->pr_WindowPtr; + int ret = -1; + + me->pr_WindowPtr = (void *) -1; /* suppress any "Please insert" popups */ + if (SysBase->LibNode.lib_Version >= ReqVers) + ret = !SetVar((char *)var, (char *)value, -1, GVF_GLOBAL_ONLY | LV_VAR); + else { + BPTR hand, foot, spine; + long len = value ? strlen(value) : 0; + if (foot = Lock("ENV:", ACCESS_READ)) { + spine = CurrentDir(foot); + if (len) { + if (hand = Open((char *) var, MODE_NEWFILE)) { + ret = Write(hand, (char *) value, len + 1) >= len; + Close(hand); + } + } else + ret = DeleteFile((char *) var); + UnLock(CurrentDir(spine)); + } + } + me->pr_WindowPtr = old_window; + return ret; +} + +/* Stores data from timezone and daylight to ENV:TZ. */ +/* ENV:TZ is required to exist by some other SAS/C library functions, */ +/* like stat() or fstat(). */ +void set_TZ(long time_zone, int day_light) +{ + char put_tz[MAXTIMEZONELEN]; /* string for putenv: "TZ=aaabbb:bb:bbccc" */ + int offset; + void *exists; /* dummy ptr to see if global envvar TZ already exists */ + exists = (void *)getenv(TZ_ENVVAR); + /* see if there is already an envvar TZ_ENVVAR. If not, create it */ + if (exists == NULL) { + /* create TZ string by pieces: */ + sprintf(put_tz, "GMT%+ld", time_zone / 3600L); + if (time_zone % 3600L) { + offset = (int) labs(time_zone % 3600L); + sprintf(put_tz + strlen(put_tz), ":%02d", offset / 60); + if (offset % 60) + sprintf(put_tz + strlen(put_tz), ":%02d", offset % 60); + } + if (day_light) + strcat(put_tz,"DST"); + setenv(TZ_ENVVAR, put_tz, 1); + } +} +#endif /* __SASC */ + +/* set state as well as possible from settings found in locale.library */ +int GetPlatformLocalTimezone(sp, fill_tzstate_from_rules) + register struct state * ZCONST sp; + void (*fill_tzstate_from_rules)(struct state * ZCONST sp_res, + ZCONST struct rule * ZCONST start, + ZCONST struct rule * ZCONST end); +{ + struct Library *LocaleBase; + struct Locale *ll; + struct Process *me = (void *) FindTask(NULL); + void *old_window = me->pr_WindowPtr; + BPTR eh; + int z, valid = FALSE; + + /* read timezone from locale.library if TZ envvar missing */ + me->pr_WindowPtr = (void *) -1; /* suppress any "Please insert" popups */ + if (LocaleBase = OpenLibrary("locale.library", 0)) { + if (ll = OpenLocale(NULL)) { + z = ll->loc_GMTOffset; /* in minutes */ + if (z == -300) { + if (eh = Lock("ENV:sys/locale.prefs", ACCESS_READ)) { + UnLock(eh); + valid = TRUE; + } else + z = 300; /* bug: locale not initialized, default bogus! */ + } else + valid = TRUE; + if (valid) { + struct rule startrule, stoprule; + + sp->timecnt = 0; + sp->typecnt = 1; + sp->charcnt = 2; + sp->chars[0] = sp->chars[1] = '\0'; + sp->ttis[0].tt_abbrind = 0; + sp->ttis[1].tt_abbrind = 1; + sp->ttis[0].tt_gmtoff = -z * MINSPERHOUR; + sp->ttis[1].tt_gmtoff = -z * MINSPERHOUR + SECSPERHOUR; + sp->ttis[0].tt_isdst = 0; + sp->ttis[1].tt_isdst = 1; + stoprule.r_type = MONTH_NTH_DAY_OF_WEEK; + stoprule.r_day = 0; + stoprule.r_week = 5; + stoprule.r_mon = 10; + stoprule.r_time = 2 * SECSPERHOUR; + startrule = stoprule; + startrule.r_mon = 4; + startrule.r_week = 1; + if (z >= -180 && z < 150) { + /* At this point we make a really gratuitous assumption: */ + /* if the time zone could be Europe, we use the European */ + /* Union rules without checking what country we're in. */ + /* The AmigaDOS locale country codes do not, at least in */ + /* 2.x versions of the OS, recognize very many countries */ + /* outside of Europe and North America. */ + sp->typecnt = 2; + startrule.r_mon = 3; /* one week earlier than US DST */ + startrule.r_week = 5; + } else if (z >= 150 && z <= 480 && + /* no DST in alaska, hawaii */ + (ll->loc_CountryCode == 0x55534100 /*"USA"*/ || + ll->loc_CountryCode == 0x43414E00 /*"CAN"*/)) + sp->typecnt = 2; + /* We check the country code for U.S. or Canada because */ + /* most of Latin America has no DST. Even in these two */ + /* countries there are some exceptions... */ + /* else if... Feel free to add more cases here! */ + + if (sp->typecnt > 1) + (*fill_tzstate_from_rules)(sp, &startrule, &stoprule); + } + CloseLocale(ll); + } + CloseLibrary(LocaleBase); + } + me->pr_WindowPtr = old_window; + return valid; +} + +#ifdef ZIP +time_t time(time_t *tp) +{ + time_t t; + struct DateStamp ds; + DateStamp(&ds); + t = ds.ds_Tick / TICKS_PER_SECOND + ds.ds_Minute * 60 + + (ds.ds_Days + 2922) * SECSPERDAY; + t = mktime(gmtime(&t)); + /* gmtime leaves ds in the local timezone, mktime converts it to GMT */ + if (tp) *tp = t; + return t; +} +#endif /* ZIP */ + +#endif /* !FUNZIP && !UTIL */ + + +#if CRYPT || !defined(FUNZIP) + +/* sendpkt.c + * by A. Finkel, P. Lindsay, C. Sheppner + * returns Res1 of the reply packet + */ +/* +#include +#include +#include +#include +#include +#include +*/ + +LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs); + +LONG sendpkt(pid,action,args,nargs) +struct MsgPort *pid; /* process identifier (handler message port) */ +LONG action, /* packet type (desired action) */ + *args, /* a pointer to argument list */ + nargs; /* number of arguments in list */ +{ + + struct MsgPort *replyport, *CreatePort(UBYTE *, long); + void DeletePort(struct MsgPort *); + struct StandardPacket *packet; + LONG count, *pargs, res1; + + replyport = CreatePort(NULL,0L); + if( !replyport ) return(0); + + packet = (struct StandardPacket *)AllocMem( + (long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR); + if( !packet ) + { + DeletePort(replyport); + return(0); + } + + packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt); + packet->sp_Pkt.dp_Link = &(packet->sp_Msg); + packet->sp_Pkt.dp_Port = replyport; + packet->sp_Pkt.dp_Type = action; + + /* copy the args into the packet */ + pargs = &(packet->sp_Pkt.dp_Arg1); /* address of 1st argument */ + for( count=0; countsp_Pkt.dp_Res1; + + FreeMem((char *)packet,(long)sizeof(*packet)); + DeletePort(replyport); + + return(res1); + +} /* sendpkt() */ + +#endif /* CRYPT || !FUNZIP */ + + +#if CRYPT || (defined(UNZIP) && !defined(FUNZIP)) + +/* Agetch() reads one raw keystroke -- uses sendpkt() */ + +int Agetch(void) +{ + LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs); + struct Task *me = FindTask(NULL); + struct CommandLineInterface *cli = BADDR(((struct Process *) me)->pr_CLI); + BPTR fh = cli->cli_StandardInput; /* this is immune to < redirection */ + void *conp = ((struct FileHandle *) BADDR(fh))->fh_Type; + char longspace[8]; + long *flag = (long *) ((ULONG) &longspace[4] & ~3); /* LONGWORD ALIGNED! */ + UBYTE c; + + *flag = 1; + sendpkt(conp, ACTION_SCREEN_MODE, flag, 1); /* assume success */ + Read(fh, &c, 1); + *flag = 0; + sendpkt(conp, ACTION_SCREEN_MODE, flag, 1); + if (c == 3) /* ^C in input */ + Signal(me, SIGBREAKF_CTRL_C); + return c; +} + +#endif /* CRYPT || (UNZIP && !FUNZIP) */ + +#endif /* __amiga_filedate_c*/ diff --git a/amiga/makefile.azt b/amiga/makefile.azt new file mode 100644 index 0000000..d9390c8 --- /dev/null +++ b/amiga/makefile.azt @@ -0,0 +1,304 @@ +# Makefile for Zip, ZipNote, ZipCloak, ZipSplit for Aztec C 5.2 +# Also ZipLM, a version of Zip that needs much less free memory +# -- Paul Kienitz, last updated 07 Jan 2007 + +# Make sure platform is defined correctly, and select memory usage options: +DEFINES = -d AMIGA -d DYN_ALLOC -d ASM_CRC + +CC = cc +AS = as +LD = ln +LDLIBS = -lc16 + + +# -------- RELEASE VERSION: +CFLAGS = -psb0e -sabfmnpu -wcr0u $(DEFINES) +# -pbs means unsigned chars and short ints, -sabfmnpu is various small +# optimizations, -wcr0u adjusts type checking strictness +ASOPTS = -n -eAMIGA -eDYN_ALLOC -eCPUTEST -eINT16 +LDFLAGS = -m +q + +# -------- DEBUG VERSION: +CFLAGD = -bs -psb0e -s0f0n -wcr0u $(DEFINES) +# -bs is include source debugging info, -s0f0n is avoid hard-to-debug +# optimizations +LDFLAGD = -m +q -g -w + +# -------- MINIMUM MEMORY USAGE RELEASE VERSION: +WSIZ = WSIZE=4096 +LOWFLAGS = $(CFLAGS) -d $(WSIZ) -d SMALL_MEM +LOWASOPTS = $(ASOPTS) -e$(WSIZ) -eSMALL_MEM +# Options used for assembling amiga/deflate.a; must generally match the +# settings in DEFINES. + +# -------- MINIMUM MEMORY USAGE DEBUG VERSION: +LOWFLAGD = $(CFLAGD) -d $(WSIZ) -d SMALL_MEM + +# the directory where we stick all the object files: +O = obA/ + + +# default C rules +.c.o : + $(CC) $(CFLAGS) -o $@ $*.c + +# rules for routines containing entries needed by utilities +.c.oo : + $(CC) $(CFLAGS) -d UTIL -o $@ $*.c + +# rules for the low-memory version: + +.c.ol : + $(CC) $(LOWFLAGS) -o $@ $*.c + +# default C rules for debugging +.c.od : + $(CC) $(CFLAGD) -o $@ $*.c + +# debugging rules for routines containing entries needed by utilities +.c.dd : + $(CC) $(CFLAGD) -d UTIL -o $@ $*.c + +# rules for the debugging low-memory version: + +.c.dl : + $(CC) $(LOWFLAGD) -o $@ $*.c + + +# object file lists + +ZIP_H = zip.h ziperr.h tailor.h amiga/osdep.h amiga/z-stat.h + + +OBJZ = $(O)zip.o $(O)deflate.o \ + $(O)trees.o $(O)zipfile.o $(O)zipup.o $(O)util.o $(O)timezone.o \ + $(O)fileio.o $(O)globals.o $(O)crc32.o $(O)crypt.o $(O)ttyio.o \ + $(O)amiga.o $(O)amigazip.o $(O)crc_68.o + +OBJL = $(O)zip.ol $(O)deflate.ol \ + $(O)trees.ol $(O)zipfile.ol $(O)zipup.ol $(O)util.ol $(O)timezone.ol \ + $(O)fileio.ol $(O)globals.ol $(O)crc32.ol $(O)crypt.ol $(O)ttyio.ol \ + $(O)amiga.ol $(O)amigazip.ol $(O)crc_68.o + +OBJU = $(O)zipfile.oo $(O)fileio.oo \ + $(O)util.oo $(O)globals.o $(O)amiga.oo $(O)amigazip.oo +OBJN = $(O)zipnote.o $(OBJU) +OBJC = $(O)zipcloak.o $(OBJU) $(O)crc32.oo \ + $(O)crypt.oo $(O)ttyio.o +OBJS = $(O)zipsplit.o $(OBJU) + +# These are the debuggable versions: + +DBJZ = $(O)zip.od $(O)deflate.od \ + $(O)trees.od $(O)zipfile.od $(O)zipup.od $(O)util.od $(O)timezone.od \ + $(O)fileio.od $(O)globals.od $(O)crc32.od $(O)crypt.od $(O)ttyio.od \ + $(O)amiga.od $(O)amigazip.od $(O)crc_68.o + +DBJL = $(O)zip.dl $(O)deflate.dl \ + $(O)trees.dl $(O)zipfile.dl $(O)zipup.dl $(O)util.dl $(O)timezone.dl \ + $(O)fileio.dl $(O)globals.dl $(O)crc32.dl $(O)crypt.dl $(O)ttyio.dl \ + $(O)amiga.dl $(O)amigazip.dl $(O)crc_68.o + +DBJU = $(O)zipfile.dd $(O)fileio.dd \ + $(O)util.dd $(O)globals.od $(O)amiga.dd $(O)amigazip.dd +DBJN = $(O)zipnote.od $(DBJU) +DBJC = $(O)zipcloak.od $(DBJU) $(O)crc32.dd \ + $(O)crypt.dd $(O)ttyio.od +DBJS = $(O)zipsplit.od $(DBJU) + + +# HERE WE GO: + +all : Zip ZipNote ZipSplit ZipCloak ZipLM + +z : Zip + +n : ZipNote + +s : ZipSplit + +c : ZipCloak + +l : ZipLM + +# Debug versions: + +dall : Zip.dbg ZipNote.dbg ZipSplit.dbg ZipCloak.dbg ZipLM.dbg + +dz : Zip.dbg + +dn : ZipNote.dbg + +ds : ZipSplit.dbg + +dc : ZipCloak.dbg + +dl : ZipLM.dbg + + +Zip : $(OBJZ) $(ZIP_H) + $(LD) $(LDFLAGS) -o $@ $(OBJZ) $(LDLIBS) + -@delete Zip.dbg + +ZipNote : $(OBJN) $(ZIP_H) + $(LD) $(LDFLAGS) -o $@ $(OBJN) $(LDLIBS) + -@delete ZipNote.dbg + +ZipSplit : $(OBJS) $(ZIP_H) + $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS) + -@delete ZipSplit.dbg + +ZipCloak : $(OBJC) $(ZIP_H) + $(LD) $(LDFLAGS) -o $@ $(OBJC) $(LDLIBS) + -@delete ZipCloak.dbg + +ZipLM : $(OBJL) $(ZIP_H) + $(LD) $(LDFLAGS) -o $@ $(OBJL) $(LDLIBS) + -@delete ZipLM.dbg + + +Zip.dbg : $(DBJZ) $(ZIP_H) + $(LD) $(LDFLAGD) -o Zip $(DBJZ) $(LDLIBS) + +ZipNote.dbg : $(DBJN) $(ZIP_H) + $(LD) $(LDFLAGD) -o ZipNote $(DBJN) $(LDLIBS) + +ZipSplit.dbg : $(DBJS) $(ZIP_H) + $(LD) $(LDFLAGD) -o ZipSplit $(DBJS) $(LDLIBS) + +ZipCloak.dbg : $(DBJC) $(ZIP_H) + $(LD) $(LDFLAGD) -o ZipCloak $(DBJC) $(LDLIBS) + +ZipLM.dbg : $(DBJL) $(ZIP_H) + $(LD) $(LDFLAGD) -o ZipLM $(DBJL) $(LDLIBS) + + +clean : bugclean + -delete quiet $(OBJZ) + -delete quiet $(OBJL) + -delete quiet $(O)zipnote.o $(O)zipcloak.o $(O)zipsplit.o \ + $(O)crypt.oo $(OBJU) + +bugclean : + -delete quiet $(DBJZ) + -delete quiet $(DBJL) + -delete quiet $(O)zipnote.od $(O)zipcloak.od $(O)zipsplit.od \ + $(O)crypt.dd $(DBJU) + +cleaner : clean + -delete quiet Zip ZipNote ZipSplit ZipCloak ZipLM + -delete quiet Zip.dbg ZipNote.dbg ZipSplit.dbg ZipCloak.dbg ZipLM.dbg + + +# header dependencies: + +$(O)zip.o $(O)zipnote.o $(O)zipcloak.o $(O)zipsplit.o $(O)crypt.o $(O)ttyio.o \ + $(O)deflate.o $(O)trees.o $(O)zipfile.o $(O)zipup.o $(O)fileio.o $(O)util.o \ + $(O)timezone.o $(O)crc32.o $(O)globals.o $(O)amiga.o : $(ZIP_H) + +$(O)zip.ol $(O)zipnote.ol $(O)zipcloak.ol $(O)zipsplit.ol $(O)crypt.ol \ + $(O)ttyio.ol $(O)deflate.ol $(O)trees.ol $(O)zipfile.ol $(O)zipup.ol \ + $(O)fileio.ol $(O)util.ol $(O)timezone.ol $(O)crc32.ol $(O)globals.ol \ + $(O)amiga.ol : $(ZIP_H) + +$(O)crc32.oo $(O)crypt.oo $(O)zipfile.oo $(O)fileio.oo $(O)util.oo : $(ZIP_H) + +$(O)amigazip.o $(O)amigazip.ol $(O)amigazip.oo : amiga/amiga.h $(ZIP_H) + +$(O)zip.o $(O)zipnote.o $(O)zipcloak.o $(O)zipsplit.o $(O)zipup.o \ + $(O)zip.ol $(O)zipnote.ol $(O)zipcloak.ol $(O)zipsplit.ol \ + $(O)zipup.ol : revision.h + +$(O)amiga.o $(O)amiga.ol : crypt.h + +$(O)crc32.o $(O)crc32.oo $(O)crc32.ol $(O)crypt.o $(O)crypt.oo $(O)crypt.ol \ + $(O)zipcloak.o $(O)zipcloak.ol $(O)zip.o $(O)zip.ol \ + $(O)zipup.o $(O)zipup.ol \ + $(O)zipfile.o $(O)zipfile.oo $(O)zipfile.ol \ + $(O)fileio.o $(O)fileio.oo $(O)fileio.ol : crc32.h + +$(O)crypt.o $(O)crypt.oo $(O)crypt.ol $(O)ttyio.o $(O)ttyio.ol \ + $(O)zipcloak.o $(O)zipcloak.ol $(O)zip.o $(O)zip.ol \ + $(O)zipup.o $(O)zipup.ol : crypt.h ttyio.h + +$(O)timezone.o $(O)timezone.ol $(O)timezone.od $(O)timezone.dl \ + $(O)amiga.o $(O)amiga.ol $(O)amiga.oo : timezone.h + +$(O)zipup.o $(O)zipup.ol : amiga/zipup.h + + +# SPECIAL CASES: + +# -mr changes expression parsing; avoids a bogus "expression too complex" error: +$(O)trees.o : trees.c + $(CC) $(CFLAGS) -mr -o $@ trees.c + +$(O)trees.ol : trees.c + $(CC) $(LOWFLAGS) -mr -o $@ trees.c + +$(O)trees.od : trees.c + $(CC) $(CFLAGD) -mr -o $@ trees.c + +$(O)trees.ld : trees.c + $(CC) $(LOWFLAGD) -mr -o $@ trees.c + +# Substitute the assembly version of deflate.c: (but not in debug version) +$(O)deflate.o : amiga/deflate.a + $(AS) $(ASOPTS) -o $@ amiga/deflate.a + +$(O)deflate.ol : amiga/deflate.a + $(AS) $(LOWASOPTS) -o $@ amiga/deflate.a + +# The assembly CRC function: +$(O)crc_68.o : amiga/crc_68.a + $(AS) -n -o $@ amiga/crc_68.a + +# Put the Amiga internal version data with today's date into amiga.c: +$(O)amiga.o : amiga/amiga.c amiga/filedate.c amiga/stat.c + rx > env:VersionDate "say '""'translate(date('E'), '.', '/')'""'" + $(CC) $(CFLAGS) -o $@ amiga/amiga.c + delete env:VersionDate + +$(O)amiga.ol : amiga/amiga.c amiga/filedate.c amiga/stat.c + rx > env:VersionDate "say '""'translate(date('E'), '.', '/')'""'" + $(CC) $(LOWFLAGS) -o $@ amiga/amiga.c + delete env:VersionDate + +$(O)amiga.od : amiga/amiga.c amiga/filedate.c amiga/stat.c + rx > env:VersionDate "say '""'translate(date('E'), '.', '/')'""'" + $(CC) $(CFLAGD) -o $@ amiga/amiga.c + delete env:VersionDate + +$(O)amiga.ld : amiga/amiga.c amiga/filedate.c amiga/stat.c + rx > env:VersionDate "say '""'translate(date('E'), '.', '/')'""'" + $(CC) $(LOWFLAGD) -o $@ amiga/amiga.c + delete env:VersionDate + +$(O)amiga.oo : amiga/amiga.c amiga/filedate.c amiga/stat.c + rx > env:VersionDate "say '""'translate(date('E'), '.', '/')'""'" + $(CC) $(CFLAGS) -d UTIL -o $@ amiga/amiga.c + delete env:VersionDate + +$(O)amiga.dd : amiga/amiga.c amiga/filedate.c amiga/stat.c + rx > env:VersionDate "say '""'translate(date('E'), '.', '/')'""'" + $(CC) $(CFLAGD) -d UTIL -o $@ amiga/amiga.c + delete env:VersionDate + +# Put the compiler version number into amigazip.c: +$(O)amigazip.o : amiga/amigazip.c + $(CC) $(CFLAGS) -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c + +$(O)amigazip.ol : amiga/amigazip.c + $(CC) $(LOWFLAGS) -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c + +$(O)amigazip.od : amiga/amigazip.c + $(CC) $(CFLAGD) -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c + +$(O)amigazip.ld : amiga/amigazip.c + $(CC) $(LOWFLAGD) -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c + +$(O)amigazip.oo : amiga/amigazip.c + $(CC) $(CFLAGS) -d UTIL -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c + +$(O)amigazip.dd : amiga/amigazip.c + $(CC) $(CFLAGD) -d UTIL -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c diff --git a/amiga/match.a b/amiga/match.a new file mode 100644 index 0000000..ec5bcf0 --- /dev/null +++ b/amiga/match.a @@ -0,0 +1,182 @@ +;=========================================================================== +; Copyright (c) 1990-1999 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 1999-Oct-05 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, both of these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +;=========================================================================== +; match.a -- optional optimized asm version of longest match in deflate.c +; Written by Jean-loup Gailly +; Adapted for the Amiga by Carsten Steger +; using the code in match.S. +; The major change in this code consists of removing all unaligned +; word accesses, because they cause 68000-based Amigas to crash. +; For maximum speed, UNALIGNED_OK can be defined in Makefile.sasc. +; The program will then only run on 68020-based Amigas, though. +; If you have reduced WSIZE in zip.h, then make sure this is +; assembled with an equivalent -dWSIZE=. +; +; This code will run with registerized parameters too, unless SAS +; changes parameter passing conventions between new releases of SAS/C. + + +Cur_Match reg d0 ; Must be in d0! +Best_Len reg d1 +Loop_Counter reg d2 +Scan_Start reg d3 +Scan_End reg d4 +Limit reg d5 +Chain_Length reg d6 +Scan_Test reg d7 +Scan reg a0 +Match reg a1 +Prev_Address reg a2 +Scan_Ini reg a3 +Match_Ini reg a4 + +MAX_MATCH equ 258 +MIN_MATCH equ 3 + ifnd WSIZE +WSIZE equ 32768 + endc +MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1 + + + xref _max_chain_length + xref _prev_length + xref _prev + xref _window + xref _strstart + xref _good_match + xref _match_start + xref _nice_match + + + section match,code + + xdef _match_init + xdef @match_init + xdef _longest_match + xdef @longest_match + + +_match_init: +@match_init: + rts + + +_longest_match: + move.l 4(sp),Cur_Match +@longest_match: + ifd UNALIGNED_OK + movem.l d2-d6/a2-a4,-(sp) + else + movem.l d2-d7/a2-a4,-(sp) + endc + move.l _max_chain_length,Chain_Length + move.l _prev_length,Best_Len + lea _prev,Prev_Address + lea _window+MIN_MATCH,Match_Ini + move.l _strstart,Limit + move.l Match_Ini,Scan_Ini + add.l Limit,Scan_Ini + subi.w #MAX_DIST,Limit + bhi.b limit_ok + moveq #0,Limit +limit_ok: + cmp.l _good_match,Best_Len + bcs.b length_ok + lsr.l #2,Chain_Length +length_ok: + subq.l #1,Chain_Length + + ifd UNALIGNED_OK + + move.w -MIN_MATCH(Scan_Ini),Scan_Start + move.w -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End + + else + + move.b -MIN_MATCH(Scan_Ini),Scan_Start + lsl.w #8,Scan_Start + move.b -MIN_MATCH+1(Scan_Ini),Scan_Start + move.b -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End + lsl.w #8,Scan_End + move.b -MIN_MATCH(Scan_Ini,Best_Len.L),Scan_End + + endc + + bra.b do_scan + +long_loop: + + ifd UNALIGNED_OK + + move.w -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End + + else + + move.b -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End + lsl.w #8,Scan_End + move.b -MIN_MATCH(Scan_Ini,Best_Len.L),Scan_End + + endc + +short_loop: + lsl.w #1,Cur_Match + move.w 0(Prev_Address,Cur_Match.L),Cur_Match + cmp.w Limit,Cur_Match + dbls Chain_Length,do_scan + bra.b return + +do_scan: + move.l Match_Ini,Match + add.l Cur_Match,Match + + ifd UNALIGNED_OK + + cmp.w -MIN_MATCH-1(Match,Best_Len.L),Scan_End + bne.b short_loop + cmp.w -MIN_MATCH(Match),Scan_Start + bne.b short_loop + + else + + move.b -MIN_MATCH-1(Match,Best_Len.L),Scan_Test + lsl.w #8,Scan_Test + move.b -MIN_MATCH(Match,Best_Len.L),Scan_Test + cmp.w Scan_Test,Scan_End + bne.b short_loop + move.b -MIN_MATCH(Match),Scan_Test + lsl.w #8,Scan_Test + move.b -MIN_MATCH+1(Match),Scan_Test + cmp.w Scan_Test,Scan_Start + bne.b short_loop + + endc + + move.w #(MAX_MATCH-MIN_MATCH),Loop_Counter + move.l Scan_Ini,Scan +scan_loop: + cmpm.b (Match)+,(Scan)+ + dbne Loop_Counter,scan_loop + + sub.l Scan_Ini,Scan + addq.l #(MIN_MATCH-1),Scan + cmp.l Best_Len,Scan + bls.b short_loop + move.l Scan,Best_Len + move.l Cur_Match,_match_start + cmp.l _nice_match,Best_Len + bcs.b long_loop +return: + move.l Best_Len,d0 + ifd UNALIGNED_OK + movem.l (sp)+,d2-d6/a2-a4 + else + movem.l (sp)+,d2-d7/a2-a4 + endc + rts + + end diff --git a/amiga/match_68.a b/amiga/match_68.a new file mode 100644 index 0000000..d1a6c39 --- /dev/null +++ b/amiga/match_68.a @@ -0,0 +1,273 @@ +;=========================================================================== +; Copyright (c) 1990-1999 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 1999-Oct-05 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, both of these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +;=========================================================================== +; This is a 68000 assembly language version of the Zip function +; longest_match(). It is written for any 680x0 based computer, but at this +; time the feature for runtime testing of CPU type is only supported for the +; Amiga. Hopefully a similar test for the Macintosh is possible, and for any +; other system that supports both 68000 and 68020+ CPUs. This is written by +; Paul Kienitz, partially derived from a simpler version by Carsten Steger, +; derived in turn from a 386 assembly function by Jean-loup Gailly and Kai Uwe +; Rommel... but also based directly on the C original. +; +; The main difference of this from other longest_match() implementations is +; that it includes both byte based and word based versions of the function, +; and various symbols can be defined to select whether to use one routine or +; the other, or to do a platform-specific test at runtime. The symbols that +; can be used to select behavior are as follows: +; +; CPU020 if defined, use 68020 instructions always +; CPUTEST if defined, check at runtime for CPU type. Another symbol +; specifying the platform-specific test must be used with this. +; If neither of these is defined, use 68000 instructions only. +; AMIGA use Amiga-specific test for 68020, if CPUTEST defined. Also +; tells it to let a0/a1/d1 be clobbered by functions. +; ATSIGN define entry symbols in @foo form as well as _foo, with +; @longest_match taking its parm in d0 instead of on the stack. +; WSIZE if defined, determines the sliding window size for deflate; +; the default is 32K. If you have reduced WSIZE for the C code, +; make sure that this module is assembled with an equivalent +; "-dWSIZE=" (or "-e...") switch. +; +; NOTE: no provision is made for 16 bit ints. All external int variables are +; treated as 32 bit values. This also assumes that longest_match's result is +; returned in D0. + + IFND CPU020 + IFND CPUTEST +CPU000 equ 1 + ENDC + ENDC + +; global variables: + xref _max_chain_length ; unsigned int + xref _prev_length ; unsigned int + xref _match_start ; unsigned int + xref _strstart ; unsigned int + xref _good_match ; signed int + xref _nice_match ; signed int + xref _window ; array of unsigned char + xref _prev ; array of unsigned short + +; our entry points: + xdef _match_init ; void match_init(void); + xdef _longest_match ; int longest_match(unsigned cur_match); + IFD ATSIGN + xdef @match_init ; for SAS assembler + xdef @longest_match ; ditto + ENDC + +; flag variable for remembering CPU type: + IFD CPUTEST + section cpuflag,data +is020: ds.w 1 + ENDC + + + section match,code +_match_init: + IFD ATSIGN +@match_init: + ENDC + + IFD CPUTEST ; now check for platform type + IFD AMIGA ; Amiga specific test for '020 CPU: + + xref _SysBase + + NOLIST + INCLUDE 'exec/execbase.i' + LIST + + clr.w is020 ; default value is 68000 + move.l _SysBase,a0 + btst #AFB_68020,AttnFlags+1(a0) + beq.s cheap + move.w #1,is020 + +cheap: + ELSE ; !AMIGA + + !! Write an '020-detector for your system here! + + ENDC ; AMIGA + ENDC ; CPUTEST + rts ; match_init consists only of rts if CPUTEST unset + + + IFD AMIGA +SAVEREGS reg d3-d7/a2/a3/a5 ; don't protect d0/d1/a0/a1 + ELSE +SAVEREGS reg d1/d3-d7/a0-a3/a5 ; protect all but d0 return val + ENDC + +Cur_Match equr d0 ; Must be in d0! +Best_Len equr d1 +Scan_Start equr d3 +Scan_End equr d4 +Limit equr d5 +Chain_Length equr d6 +Scan_Test equr d7 +Scan equr a0 +Match equr a1 +Prev_Address equr a2 +Scan_Ini equr a3 +Match_Ini equr a5 + + +MAX_MATCH equ 258 +MIN_MATCH equ 3 + IFND WSIZE +WSIZE equ 32768 + ENDC +MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1 + +_longest_match: + move.l 4(sp),Cur_Match ; stack arg to register + IFD ATSIGN +@longest_match: + ENDC + movem.l SAVEREGS,-(sp) + +; setup steps common to byte and word versions: + move.l _max_chain_length,Chain_Length + move.l _prev_length,Best_Len + lea _prev,Prev_Address + lea _window,Match_Ini + move.l _strstart,Limit + move.l Match_Ini,Scan_Ini + addq #MIN_MATCH,Match_Ini + add.l Limit,Scan_Ini + subi.w #MAX_DIST,Limit + bhi.s limit_ok + moveq #0,Limit +limit_ok: + cmp.l _good_match,Best_Len + bcs.s length_ok + lsr.l #2,Chain_Length +length_ok: + subq.l #1,Chain_Length + + IFD CPUTEST + tst.w is020 ; can we use '020 stuff today? + bne WORD_match + ENDC + + IFND CPU020 + +; for 68000 or 68010, use byte operations: + moveq #0,Scan_Start ; clear 2nd and 4th bytes, use 1st & 3rd + moveq #0,Scan_End + moveq #0,Scan_Test + move.b (Scan_Ini),Scan_Start + swap Scan_Start + move.b 1(Scan_Ini),Scan_Start + move.b -1(Scan_Ini,Best_Len),Scan_End + swap Scan_End + move.b 0(Scan_Ini,Best_Len),Scan_End + bra.s bdo_scan + +blong_loop: + move.b -1(Scan_Ini,Best_Len),Scan_End + swap Scan_End + move.b 0(Scan_Ini,Best_Len),Scan_End + +bshort_loop: + add.w Cur_Match,Cur_Match + move.w 0(Prev_Address,Cur_Match.l),Cur_Match + cmp.l Limit,Cur_Match + dbls Chain_Length,bdo_scan + bra return + +bdo_scan: + move.l Match_Ini,Match + add.l Cur_Match,Match + move.b -MIN_MATCH-1(Match,Best_Len),Scan_Test + swap Scan_Test + move.b -MIN_MATCH(Match,Best_Len),Scan_Test + cmp.l Scan_Test,Scan_End + bne.s bshort_loop + move.b -MIN_MATCH(Match),Scan_Test + swap Scan_Test + move.b -MIN_MATCH+1(Match),Scan_Test + cmp.l Scan_Test,Scan_Start + bne.s bshort_loop + move.w #(MAX_MATCH-MIN_MATCH),Scan_Test + lea MIN_MATCH(Scan_Ini),Scan + +bscan_loop: + cmpm.b (Match)+,(Scan)+ + dbne Scan_Test,bscan_loop + subq #1,Scan + + sub.l Scan_Ini,Scan + cmp.l Best_Len,Scan + bls.s bshort_loop + move.l Scan,Best_Len + move.l Cur_Match,_match_start + cmp.l _nice_match,Best_Len + bcs.s blong_loop + IFD CPUTEST + bra return + ENDC + + ENDC ; !CPU020 + + IFND CPU000 + +; for 68020 or higher, use word operations even on odd addresses: +WORD_match: + move.w (Scan_Ini),Scan_Start + move.w -1(Scan_Ini,Best_Len),Scan_End + bra.s wdo_scan + +wlong_loop: + move.w -1(Scan_Ini,Best_Len),Scan_End + +wshort_loop: + add.w Cur_Match,Cur_Match + move.w (Prev_Address,Cur_Match.l),Cur_Match + cmp.l Limit,Cur_Match + dbls Chain_Length,wdo_scan + bra.s return + +wdo_scan: + move.l Match_Ini,Match + add.l Cur_Match,Match + cmp.w -MIN_MATCH-1(Match,Best_Len),Scan_End + bne.s wshort_loop + cmp.w -MIN_MATCH(Match),Scan_Start + bne.s wshort_loop + moveq #((MAX_MATCH-MIN_MATCH)/2),Scan_Test ; value = 127 + lea MIN_MATCH(Scan_Ini),Scan + +wscan_loop: + cmpm.w (Match)+,(Scan)+ + dbne Scan_Test,wscan_loop + subq #2,Scan + move.b -MIN_MATCH+1(Match),Scan_Test + cmp.b (Scan),Scan_Test + bne steven + addq #1,Scan +steven: + sub.l Scan_Ini,Scan + cmp.l Best_Len,Scan + bls.s wshort_loop + move.l Scan,Best_Len + move.l Cur_Match,_match_start + cmp.l _nice_match,Best_Len + bcs.s wlong_loop + + ENDC ; !CPU000 + +return: + move.l Best_Len,d0 ; function return value + movem.l (sp)+,SAVEREGS + rts + + end diff --git a/amiga/osdep.h b/amiga/osdep.h new file mode 100644 index 0000000..c573cf8 --- /dev/null +++ b/amiga/osdep.h @@ -0,0 +1,119 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2005-Feb-10 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#ifndef __amiga_osdep_h +#define __amiga_osdep_h + +/* default to MEDIUM_MEM, but allow makefile override */ +#if ( (!defined(BIG_MEM)) && (!defined(SMALL_MEM))) +# define MEDIUM_MEM +#endif + +/* check that TZ environment variable is defined before using UTC times */ +#if (!defined(NO_IZ_CHECK_TZ) && !defined(IZ_CHECK_TZ)) +# define IZ_CHECK_TZ +#endif + +#ifndef IZTZ_GETLOCALETZINFO +# define IZTZ_GETLOCALETZINFO GetPlatformLocalTimezone +#endif + +/* AmigaDOS can't even support disk partitions over 4GB, let alone files */ +#define NO_LARGE_FILE_SUPPORT +#ifdef LARGE_FILE_SUPPORT +# undef LARGE_FILE_SUPPORT +#endif + +#define USE_CASE_MAP +#define USE_EF_UT_TIME +#define HANDLE_AMIGA_SFX +#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \ + procname(n, 1)) +#define EXIT(e) ClearIOErr_exit(e) +void ClearIOErr_exit(int e); + +#include "amiga/z-stat.h" + +#ifdef __SASC +# include +# include +# if (defined(_M68020) && (!defined(__USE_SYSBASE))) + /* on 68020 or higher processors it is faster */ +# define __USE_SYSBASE /* to use the pragma libcall instead of syscall */ +# endif /* to access functions of the exec.library */ +# include /* see SAS/C manual:part 2,chapter 2,pages 6-7 */ +# include +# if (defined(_M68020) && !defined(UNALIGNED_OK)) +# define UNALIGNED_OK +# endif +# ifndef REENTRANT +# define REENTRANT +# endif +# if (defined(_NEAR_DATA) && !defined(DYN_ALLOC)) +# define DYN_ALLOC +# endif +# ifdef DEBUG +# include /* profiler header file */ +# endif +# ifndef IZTZ_SETLOCALTZINFO + /* XXX !! We have really got to find a way to operate without these. */ +# define IZTZ_SETLOCALTZINFO +# endif + +/* + A word on short-integers and SAS/C (a bug of [mc]alloc?) + Using short integers (i.e. compiling with option SHORT-INTEGERS) is + *not* recommended. To get maximum compression ratio the window size stored + in WSIZE should be 32k (0x8000). However, since the size of the window[] + array is 2*WSIZE, 65536 bytes must be allocated. The calloc function can + only allocate UINT_MAX (defined in limits.h) bytes which is one byte short + (65535) of the maximum window size if you are compiling with short-ints. + You'll get an error message "Out of memory (window allocation)" whenever + you try to deflate. Note that the compiler won't produce any warning. + The maximum window size with short-integers is therefore 32768 bytes. + The following is only implemented to allow the use of short-integers but + it is once again not recommended because of a loss in compression ratio. +*/ +# if (defined(_SHORTINT) && !defined(WSIZE)) +# define WSIZE 0x4000 /* only half of maximum window size */ +# endif /* possible with short-integers */ +#endif /* __SASC */ +/* + With Aztec C, using short integers imposes no size limits and makes + the program run faster, even with 32 bit CPUs, so it's recommended. +*/ +#ifdef AZTEC_C +# define NO_UNISTD_H +# define NO_RMDIR +# define BROKEN_FSEEK +# ifndef IZTZ_DEFINESTDGLOBALS +# define IZTZ_DEFINESTDGLOBALS +# endif +#endif + +extern int real_timezone_is_set; +void tzset(void); +#define VALID_TIMEZONE(tempvar) (tzset(), real_timezone_is_set) + +#ifdef ZCRYPT_INTERNAL +# ifndef CLIB_EXEC_PROTOS_H + void *FindTask(void *); +# endif +# define ZCR_SEED2 (unsigned)(ulg)FindTask(NULL) +#endif + +int Agetch(void); /* getch() like function, in amiga/filedate.c */ +char *GetComment(char *); + +#define FOPR "rb" +#define FOPM "rb+" +#define FOPW "wb" +/* prototype for ctrl-C trap function */ +void _abort(void); + +#endif /* !__amiga_osdep_h */ diff --git a/amiga/smakefile b/amiga/smakefile new file mode 100644 index 0000000..ce1317d --- /dev/null +++ b/amiga/smakefile @@ -0,0 +1,662 @@ +#=========================================================================== +# Makefile for Zip, ZipNote, ZipCloak, ZipSplit AMIGA SAS/C Version 6.58 +# Version: 2.3 last revised: 07 Jan 2007 +#=========================================================================== +# -John Bush, +# or: + +# updated for SAS/C Version 6.56+ and AmigaDOS 3.1 (V40) +# by Haidinger Walter, + +# additional supplements and maintenance by Paul Kienitz + +# This makefile should work with at least AmigaDOS 2.04 (V37) (not tested) +# and will probably not work with AmigaDOS 1.3 (V34) + +# If you have any improvements, critics or else please feel free to mail. +# Any response is appreciated. Haidinger Walter + +# Available targets: +# all builds all executeables below +# zip builds zip executeable +# zipsplit builds zipsplit executeable +# zipcloak builds zipcloak executeable +# zipnote builds zipnote executeable +# ziplm builds low memory version of zip executable +# clean remove all files created by the compilation +# spotless like clean target but removes binaries too + + +########################## +# USER MACRO DEFINITIONS # +########################## + +# *** NOTE *** +# The assembly version is not implemented yet. +# (Un)commenting the assembler macros has no effect unless the +# file dependencies are changed too. +# Most of the amiga/*.a files do not assmble with 68000 instructions. +# Any help is appreciated, of course. + +# Set the processor to generate code for. +# Compiler: ANY 68000 68010 68020 68030 68040 68060 +# Assembler: 0 0 1 2 3 4 n/a +# Defaults: ANY and 0 +# +CUSECPU = ANY +AUSECPU = 0 + +# UNCOMMENT to use 68020 instructions in the assembly version of deflate.o +# Only use if code is generated for 68020 or higher processors above. +# Note: You could use CPUTEST too to enable runtime cpu detection. +# However, it is not recommended since both 68000 and 68020 code will be +# included which would be an unnecessary increase in size. +# (see amiga/deflate.a for more information) +# +#AUSE020 = CPU020 + +# To disable the assembler replacements and use the standard C source, +# you have to change the Zip and ZipLM dependencies. See below for details. +# (remember that assembler use is *not* implemented yet) + +# Uncomment both CUTIL and LUTIL to make use of utility.library of OS 2.04+ +# The utility.library is *not* used for UnZipSFX to ensure maximum portability +# between the different Amiga systems (minimal config: 68000 and OS 1.2). +# You can change this by adding the $(LUTIL) macro in the UnZipSFX linking +# rules (See below: Final output targets, UnZipSFX:). +# WARNINGS when using the utility library: +# 1. All Executables will *only* work with AmigaDOS 2.04 (v37) or higher. +# 2. You *need not* compile/link with short-integers using the +# utility.library. It will crash your machine. See Libraries below. +# +# Default: commented (not used) +# +#CUTIL = UTILLIB DEFINE=_UTILLIB +#LUTIL = WITH SC:LIB/utillib.with # include necessary linker defines +# Choose one stack-handling method (default=faster) +# StackExtend: Dynamic runtime stack extension. You won't notice stack overflows. +# StackCheck: On a stack overflow a requester appears which allows you to exit. +# Note that either stack watching will slow down your executable because of the +# extra code run on each function entry. On the other hand, you won't crash +# anymore due to stack overflows. However, you should not have *any* stack +# problems with Info-ZIP programs if you raise your stack to 10000 (which I'd +# recommend as a minimum default stack for all applications) or more using the +# shell stack command. Type 'Stack 20000' or add it to your S:Shell-Startup. +# BTW: Typing 'Stack' prints your current stack size. +# +CSTACK = NOSTACKCHECK STACKEXTEND # slow, but always works +#CSTACK = STACKCHECK NOSTACKEXTEND # slow, requester & graceful exit +#CSTACK = NOSTACKCHECK NOSTACKEXTEND # faster but relies on larger stack (>=10K) + + +# +# LIBRARIES +# --------- + +# Choose one DATAOPTS , SASLIB , ASMOPTS and LSTARTUP +# Always comment/uncomment all macros of a set. + +# Library to use with near data and 2-byte integers +# Notes: o slower than 4-byte integers with 68000 cpu +# o *not* recommended due to poor overall performance +# o see comment in amiga/osdep.h +#DATAOPTS = DATA=NEAR SHORTINTEGERS DEF=_NEAR_DATA +#SASLIB = scs +#ASMOPTS = -dINT16 +#LSTARTUP = cres.o + +# Library to use with near data and 4-byte integers (DEFAULT) +# *** use this with the utility.library *** +DATAOPTS = DATA=NEAR DEF=_NEAR_DATA +SASLIB = sc +ASMOPTS = +LSTARTUP = cres.o + +# Library to use with far data and 2-byte integers +# use if DYN_ALLOC is not defined +# old default - far data always works but is slower +#DATAOPTS = DATA=FAR SHORTINTEGERS DEF=_FAR_DATA +#SASLIB = scsnb +#ASMOPTS = -dINT16 +#LSTARTUP = c.o + +# Library to use with far data and 4-byte integers +# if everything else fails: try this +#DATAOPTS = DATA=FAR DEF=_FAR_DATA +#SASLIB = scnb +#ASMOPTS = +#LSTARTUP = c.o + + +# +# DEBUGGING +# --------- + +# Default: No debugging information added. +# The three macros below will be overwritten if you choose to add +# debug info, therefore no need to comment. + +CDBG = NODEBUG NOPROFILE NOCOVERAGE # default: no debug info +ADBG = +LDBG = STRIPDEBUG # default: no debug info + +# Compiler and loader debug flags. Uncomment as needed. Recomment when done. +# Optimization disabled for faster compilation (by using NOOPT) + +#CDBG1 = DEF=DEBUG DEF=DEBUG_TIME # enables Info-Zip's debug output + +# Enable profiling and coverage when desired. Option COVERAGE commented +# seperately because running coverage may corrupt your drive in case of a +# system crash since a file 'cover.dat' is created in your working directory. +# Note that the use of COVERAGE forces the use of the c.o startup module. + +#CDBG2 = PROFILE +#CDBG3 = COVERAGE # must use c.o startup code: +#LSTARTUP = c.o # Uncomment *only* when you use COVERAGE + +# *Uncomment* here macros CDBG, ADBG and LDBG to include debugging information + +#CDBG = $(CDBG1) $(CDBG2) $(CDBG3) ADDSYM DEBUG=FULLFLUSH STACKCHECK NOOPT +#ADBG = DEBUG +#LDBG = ADDSYM + +# Optional use of memwatch.library which can be found in your +# sc:extras/memlib directory. Please read the short docs (memlib.doc). +# Note that memwatch.library has a small bug: MWTerm() displays always +# the first entry. +# Get the latest version from aminet (dev/debug/memlib.lha) or +# contact me to get the patch. Uncomment all macros to use. +#CMEMLIB = DEFINE=MWDEBUG=1 # define to enable library +#LMEMLIB = SC:LIB/memwatch.lib # path to library +#LSTARTUP = c.o # must use c.o with memlib! + + +# +# MAPPING +# ------- + +# Map filenames used when mapping (no need to comment) +# +MAPFZ = zip.map # Zip map filename +MAPFN = zipnote.map # ZipNote map filename +MAPFC = zipcloak.map # ZipCloak map filename +MAPFS = zipsplit.map # ZipSplit map filename +MAPFL = ziplm.map # Zip low memory version map filename + +# Map file output: Uncomment to highlight and bold headings. +# +#MAPFSTYLE = FANCY + +# Map flags for each EXECUTABLE. Uncomment to enable mapping. +# For map options please refer to: +# SAS/C v6 manual, volume 1: user's guide, chapter 8, page 136: map +# Default: all options enabled: f,h,l,o,s,x +# |-> options start here +#LMAPZ = $(MAPFSTYLE) MAP $(MAPFZ) f,h,l,o,s,x # Zip maps +#LMAPN = $(MAPFSTYLE) MAP $(MAPFN) f,h,l,o,s,x # ZipNote maps +#LMAPC = $(MAPFSTYLE) MAP $(MAPFC) f,h,l,o,s,x # ZipCloak maps +#LMAPS = $(MAPFSTYLE) MAP $(MAPFS) f,h,l,o,s,x # ZipSplit maps +#LMAPL = $(MAPFSTYLE) MAP $(MAPFL) f,h,l,o,s,x # Zip lowmem maps + +# +# LISTINGS +# -------- + +# Listfile-extensions for each executable (enter *with* dot) +# +LISTEXTZ = .lst # extension for Zip listfiles +LISTEXTU = .ulst # extension for utility listfiles (ZipNote,ZipCloak,ZipSplit) +LISTEXTL = .llst # extension for Zip low memory listfiles + + +# List files and cross references for each OBJECT. +# Add/remove flags as needed. Not all listed by default. +# Use LISTINCLUDES to determine the dependencies for smake +# +CLISTOPT = LISTHEADERS LISTMACROS # LISTSYSTEM LISTINCLUDES +CXREFOPT = XHEAD XSYS +# +# Uncomment to enable listing (default: commented) +# *** WARNING: List files require *lots* of disk space! +# +#CLIST = LIST $(CLISTOPT) +#CXREF = XREF $(CXREFOPT) + + +# +# SUPPRESSED COMPILER WARNINGS +# ---------------------------- + +# Compiler warnings to ignore +# +# Warning 105 : module does not define any externally-known symbols +# Warning 304 : Dead assignment eliminated... +# Note 306 : ...function inlined... +# Warning 317 : possibly uninitialized variable... +# Comment to enable. +# +CIGNORE = IGNORE=105,304,306,317 + + +# +# OBJECT EXTENSIONS +# + +# Extensions used for objects of each executeable. +# Transformation rules require unique extensions. +# Enter *with* dot. +# +O = .o # extension for Zip objects +OU = .uo # extension for utility objects (ZipNote, ZipSplit and ZipCloak) +OL = .lo # extension for low memory Zip objects + + +# Filename used to store converted options from environment variable +# LOCAL_ZIP. Default: scoptions_local_zip +# +CWITHOPT = scoptions_local_zip + + +# Filenames to store compiler options to prevent command line overflow +# +# Common options file for Zip and other executables +CFILE = scoptions-zip + + +# Temp filenames for object lists to load using linker "WITH" command. +OBJLISTZ = zip_objlist.with # Zip object list +OBJLISTN = zipnote_objlist.with # ZipNote object list +OBJLISTC = zipcloak_objlist.with # ZipCloak object list +OBJLISTS = zipsplit_objlist.with # ZipSplit object list +OBJLISTL = ziplm_objlist.with # Zip low-mem object list + + +# Filenames to store linker options +# +LWITHZ = zip.lnk # zip linker options +LWITHN = zipnote.lnk # zipnote linker options +LWITHC = zipcloak.lnk # zipcloak linker options +LWITHS = zipsplit.lnk # zipsplit linker options +LWITHL = ziplm.lnk # zip low-mem linker options + + +# Define AMIGA_BETA to print "Beta Notice" up front. See tailor.h. +# Undefine AMIGA_BETA when building a released version. +#CDEFBETA = DEF=AMIGA_BETA + +##################################### +# NOTHING TO CHANGE BEYOND HERE ... # +##################################### +# (except for C/asm dependencies) + +# Define MEDIUM_MEM for production release (per Paul Kienitz). +# This reduces runtime memory requirement but not speed or compression. +# Note: Do *not* use BIG_MEM or MMAP since it isn't yet supported by the + assembler version of deflate.c : amiga/deflate.a +CUSEMEM = DEF=MEDIUM_MEM +AUSEMEM = -DMEDIUM_MEM # for asm deflate.o, must match above + + +# Defines for building low-memory use version of Zip +WSIZEL = WSIZE=4096 # deflate.c window size for low-mem version +CLOWMEM = DEF=SMALL_MEM DEF=$(WSIZEL) +ALOWMEM = -DSMALL_MEM -D$(WSIZEL) # for asm deflate.o, must match above + + +# Compiler definitions +# +CC = sc +# +# Optimizer flags +# +OPTPASSES = 6 # set number of global optimizer passes +# +OPT1 = OPT OPTINL OPTINLOCAL OPTTIME OPTLOOP OPTSCHED +OPT2 = OPTCOMP=$(OPTPASSES) OPTDEP=$(OPTPASSES) OPTRDEP=$(OPTPASSES) +OPT = $(OPT1) $(OPT2) + + +# Compiler flags +# +CDEFINES = $(CMEMLIB) $(CDEFBETA) DEF=AMIGA +COPTIONS = $(DATAOPTS) CODE=NEAR CPU=$(CUSECPU) VERBOSE PARAMETERS=BOTH NOMINC +COPTIONS = $(COPTIONS) ERRORREXX NOERRORCONSOLE MEMSIZE=HUGE $(CLIST) $(CXREF) +COPTIONS = $(COPTIONS) $(CSTACK) $(CUTIL) STRICT UNSCHAR NOICONS STRINGMERGE +CFLAGS = $(CDEFINES) $(COPTIONS) $(OPT) $(CDBG) $(CIGNORE) + + +# Linker definitions +# See SASLIB definition above +# +LD = slink +# special linker flags for pure (i.e. resident) binary. +LDFLAGSS = FROM SC:LIB/$(LSTARTUP) +# common linker flags for all other executeables +LDFLAGSC = FROM SC:LIB/c.o +LDFLAGS2 = NOICONS $(LDBG) +LIBFLAGS = LIB $(LMEMLIB) SC:LIB/$(SASLIB).lib SC:LIB/amiga.lib + + +# Assembler definitions +# +ASM = asm +# +# Options used for assembling amiga/deflate.a +# Must match defines in C-Source. +# +AFLAGS0 = -d__SASC -dSASC -dAMIGA +AFLAGS1 = $(AUSE020) $(ASMOPTS) $(ADBG) +AFLAGS2 = -m$(AUSECPU) -jm -iINCLUDE: +AFLAGS = $(AFLAGS0) $(AFLAGS1) $(AFLAGS2) +ASMOPTSZ = $(AFLAGS) $(AUSEMEM) -dDYN_ALLOC # Zip asm flags +ASMOPTSL = $(AFLAGS) $(ALOWMEM) # Zip low-mem version asm flags + + +################## +# TARGET OBJECTS # +################## + + +# Zip objects +OBJZ1 = zip$(O) zipfile$(O) zipup$(O) fileio$(O) util$(O) globals$(O) +OBJZ2 = crc32$(O) crypt$(O) timezone$(O) ttyio$(O) +OBJZI = deflate$(O) trees$(O) +OBJZA = amiga$(O) amigazip$(O) stat$(O) filedate$(O) +OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZI) $(OBJZA) + +# Shared utility objects for ZipNote, ZipCloak and ZipSplit +OBJU1 = globals$(O) +OBJUU = zipfile$(OU) fileio$(OU) timezone$(O) util$(OU) +OBJUA = amigazip$(OU) amiga$(O) stat$(O) filedate$(O) +OBJU = $(OBJU1) $(OBJUU) $(OBJUA) + +# ZipNote objects +OBJN1 = zipnote$(O) +OBJN = $(OBJN1) $(OBJU) + +# ZipCloak objects +OBJC1 = zipcloak$(O) +OBJCU = $(OBJU) crypt$(OU) +OBJCS = crc32$(OU) ttyio$(O) +OBJC = $(OBJC1) $(OBJCU) $(OBJCS) + +#ZipSplit objects +OBJS1 = zipsplit$(O) +OBJS = $(OBJS1) $(OBJU) + +# ZipLM objects +OBJL1 = zip$(OL) zipfile$(OL) zipup$(OL) fileio$(OL) util$(OL) globals$(OL) +OBJL2 = crc32$(OL) crypt$(OL) timezone$(OL) ttyio$(OL) +OBJLI = deflate$(OL) trees$(OL) +OBJLA = amiga$(OL) amigazip$(OL) stat$(OL) filedate$(OL) +OBJL = $(OBJL1) $(OBJL2) $(OBJLI) $(OBJLA) + +# Common header files +ZIP_H1 = zip.h ziperr.h tailor.h +ZIP_HA = amiga/osdep.h amiga/z-stat.h +ZIP_H = $(ZIP_H1) $(ZIP_HA) + +# Output targets +ZIPS = Zip ZipNote ZipCloak ZipSplit ZipLM + + +# Temp filenames for object lists to load using linker "WITH" command. +OBJLISTZ = zip_objlist.with # Zip object list +OBJLISTN = zipnote_objlist.with # ZipNote object list +OBJLISTC = zipcloak_objlist.with # ZipCloak object list +OBJLISTS = zipsplit_objlist.with # ZipSplit object list +OBJLISTL = ziplm_objlist.with # Zip low-mem object list + +####################################### +# DEFAULT TARGET AND PROCESSING RULES # +####################################### + +all: request flush $(ZIPS) + +# Zip transformation rules +# +.c$(O): + $(CC) WITH=$(CFILE) $(CUSEMEM) LISTFILE=$>$(LISTEXTZ) OBJNAME=$@ $*.c + +# Zip low-memory version transformation rules +# +.c$(OL): + $(CC) WITH=$(CFILE) $(CLOWMEM) LISTFILE=$>$(LISTEXTL) OBJNAME=$@ $*.c + +# Utilities (ZipNote, ZipCloak and ZipSplit) transformation rules +# +.c$(OU): + $(CC) WITH=$(CFILE) $(CUSEMEM) DEF=UTIL LISTFILE=$>$(LISTEXTU) OBJNAME=$@ $*.c + + +######################### +# Final output targets. # +######################### + + +zip: local_zip CommonFlags $(OBJZ) + @Echo "$(OBJZ)" > $(OBJLISTZ) + Type $(OBJLISTZ) + @Echo "$(LDFLAGSS) $(LUTIL) WITH $(OBJLISTZ) $(LIBFLAGS)" \ + "$(LDFLAGS2) $(LMAPZ)" >$(LWITHZ) + Type $(LWITHZ) + $(LD) TO Zip WITH $(LWITHZ) + +zipnote: local_zip CommonFlags $(OBJN) + @Echo "$(OBJN)" > $(OBJLISTN) + Type $(OBJLISTN) + @Echo "$(LDFLAGSS) $(LUTIL) WITH $(OBJLISTN) $(LIBFLAGS) " \ + "$(LDFLAGS2) $(LMAPN)" >$(LWITHN) + Type $(LWITHN) + $(LD) TO ZipNote WITH $(LWITHN) + +zipcloak: local_zip CommonFlags $(OBJC) + @Echo "$(OBJC)" > $(OBJLISTC) + Type $(OBJLISTC) + @Echo "$(LDFLAGSS) $(LUTIL) WITH $(OBJLISTC) $(LIBFLAGS) " \ + "$(LDFLAGS2) $(LMAPC)" >$(LWITHC) + Type $(LWITHC) + $(LD) TO ZipCloak WITH $(LWITHC) + +zipsplit: local_zip CommonFlags $(OBJS) + @Echo "$(OBJS)" > $(OBJLISTS) + Type $(OBJLISTS) + @Echo "$(LDFLAGSS) $(LUTIL) WITH $(OBJLISTS) $(LIBFLAGS) " \ + "$(LDFLAGS2) $(LMAPS)" >$(LWITHS) + Type $(LWITHS) + $(LD) TO ZipSplit WITH $(LWITHS) + +ziplm: local_zip CommonFlags $(OBJL) + @Echo "$(OBJL)" > $(OBJLISTL) + Type $(OBJLISTL) + @Echo "$(LDFLAGSS) $(LUTIL) WITH $(OBJLISTL) $(LIBFLAGS) " \ + "$(LDFLAGS2) $(LMAPL)" >$(LWITHL) + Type $(LWITHL) + $(LD) TO ZipLM WITH $(LWITHL) + + +clean: + -Delete >nil: $(OBJZ) quiet + -Delete >nil: $(OBJN) quiet + -Delete >nil: $(OBJC) quiet + -Delete >nil: $(OBJS) quiet + -Delete >nil: $(OBJL) quiet + -Delete >nil: $(OBJLISTZ) $(OBJLISTL) $(OBJLISTN) $(OBJLISTS) $(OBJLISTC) quiet + -Delete >nil: $(MAPFZ) $(MAPFN) $(MAPFC) $(MAPFS) $(MAPFL) quiet + -Delete >nil: \#?$(LISTEXTZ) \#?$(LISTEXTU) \#?$(LISTEXTL) quiet + -Delete >nil: $(CWITHOPT) $(CFILE) quiet + -Delete >nil: $(LWITHZ) $(LWITHN) $(LWITHC) $(LWITHS) $(LWITHL) quiet + -Delete >nil: env:VersionDate quiet + -Delete >nil: \#?.q.?? \#?.tmp \#?.cov quiet + +spotless: clean + -Delete >nil: $(ZIPS) quiet + + +################ +# DEPENDENCIES # +################ + +# To change between the assembler and C sources, you have to comment/uncomment +# the approprite lines. C sources are marked by #C-src and assembler sources +# #asm-src at the end. +# Zip dependencies: +# + +zip$(O): zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +zipup$(O): zipup.c $(ZIP_H) revision.h crc32.h crypt.h amiga/zipup.h +zipfile$(O): zipfile.c $(ZIP_H) revision.h crc32.h +crypt$(O): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h +ttyio$(O): ttyio.c $(ZIP_H) crypt.h ttyio.h +deflate$(O): deflate.c $(ZIP_H) #C-src +trees$(O): trees.c $(ZIP_H) +fileio$(O): fileio.c $(ZIP_H) crc32.h +util$(O): util.c $(ZIP_H) +crc32$(O): crc32.c $(ZIP_H) crc32.h +globals$(O): globals.c $(ZIP_H) +timezone$(O): timezone.c $(ZIP_H) timezone.h +# Amiga specific objects +stat$(O): amiga/stat.c amiga/z-stat.h +filedate$(O): amiga/filedate.c crypt.h timezone.h +amiga$(O): amiga/amiga.c ziperr.h +amigazip$(O): amiga/amigazip.c $(ZIP_H) amiga/amiga.h env:Workbench +# Substitute assembly version of deflate.c: +#deflate$(O): amiga/deflate.a #asm-src +# $(ASM) $(ASMOPTSZ) -o$@ $*.a #asm-src + + +# Utility (ZipNote, ZipCloak, ZipSplit) dependencies: +# +zipnote$(O): zipnote.c $(ZIP_H) revision.h +zipcloak$(O): zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +zipsplit$(O): zipsplit.c $(ZIP_H) revision.h +zipfile$(OU): zipfile.c $(ZIP_H) revision.h crc32.h +fileio$(OU): fileio.c $(ZIP_H) crc32.h +util$(OU): util.c $(ZIP_H) +crc32$(OU): crc32.c $(ZIP_H) crc32.h +crypt$(OU): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h +# Amiga specific objects +amigazip$(OU): amiga/amigazip.c $(ZIP_H) amiga/amiga.h env:Workbench + +# ZipLM dependencies: +# +zip$(OL): zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +zipup$(OL): zipup.c $(ZIP_H) revision.h crc32.h crypt.h amiga/zipup.h +zipfile$(OL): zipfile.c $(ZIP_H) revision.h crc32.h +crypt$(OL): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h +ttyio$(OL): ttyio.c $(ZIP_H) crypt.h ttyio.h +deflate$(OL): deflate.c $(ZIP_H) +trees$(OL): trees.c $(ZIP_H) +fileio$(OL): fileio.c $(ZIP_H) crc32.h +util$(OL): util.c $(ZIP_H) +crc32$(OL): crc32.c $(ZIP_H) +globals$(OL): globals.c $(ZIP_H) +timezone$(OL): timezone.c $(ZIP_H) timezone.h +# Amiga specific objects +stat$(OL): amiga/stat.c amiga/z-stat.h +filedate$(OL): amiga/filedate.c crypt.h timezone.h +amiga$(OL): amiga/amiga.c ziperr.h +# Substitute assembly version of deflate.c: +#deflate$(OL): amiga/deflate.a +# $(ASM) $(ASMOPTSL) -o$@ $*.a + + +######################## +# DEPENDECIES END HERE # +######################## + +# flush all libraries to provide more mem for compilation +flush: + @Avail flush >nil: + +# write common compiler flags to file and echo to user +CommonFlags: + @Echo "$(CFLAGS)" >$(CFILE) + @Type "$(CWITHOPT)" >>$(CFILE) + -Type $(CFILE) + + +# special rules for adding Amiga internal version number to amiga/amiga.c +amiga$(O): + rx > env:VersionDate "say '""'translate(date('E'),'.','/')'""'" + $(CC) WITH=$(CFILE) $(CUSEMEM) LISTFILE=$>$(LISTEXTZ) OBJNAME=$@ $*.c + -Delete env:VersionDate + +amiga$(OL): + rx > env:VersionDate "say '""'translate(date('E'),'.','/')'""'" + $(CC) WITH=$(CFILE) $(CLOWMEM) LISTFILE=$>$(LISTEXTL) OBJNAME=$@ $*.c + -Delete env:VersionDate + + +# needed in amiga/amigazip.c +# should be set in startup-sequence, but just in case: +# (only works with OS 2.0 and above) + +env\:WorkBench: + @Execute < < (Workbench_smk.tmp) + FailAt 21 + If not exists ENV:Workbench + Version >nil: + SetEnv Workbench $$Workbench + Endif + < + + +# Read environment variable LOCAL_ZIP and convert options to SAS format +# +# e.g.: to define FOO_ONE and FOO_TWO enter: +# +# SetEnv LOCAL_ZIP "-DFOO_ONE -DFOO_TWO" +# +# Put the statement into your startup-sequence or (for AmigaDOS 2.0 or higher +# only) make sure LOCAL_ZIP is stored in the ENVARC: directory +# ( Copy ENV:LOCAL_ZIP ENVARC: ) +# + +local_zip: + @Execute < < (Local_Zip_smk.tmp) + Failat 21 + If exists ENV:LOCAL_ZIP + Echo "Using environment variable LOCAL_ZIP !" + Copy >NIL: ENV:LOCAL_ZIP SASCOPTS + Else + Echo "You could use envvar ZIP_OPT to set your special compilation options." + Delete >nil: SASCOPTS quiet + Endif + ; Do not remove the lctosc command! If LOCAL_ZIP is unset, an + ; empty file is created which needed by CommonFlags ! + lctosc >$(CWITHOPT) + < + + + +# Echo request to the user +# +request: + @Echo "" + @Echo " This makefile is for use with SAS/C version 6.58." + @Echo " If you still have an older version, please upgrade!" + @Echo " Patches are available on the Aminet under biz/patch/sc\#?." + @Echo "" + @Echo " Just a simple request..." + @Echo " Please give me a mail that you compiled whether you encounter any errors" + @Echo " or not. I'd just like to know how many Amiga users actually make use of" + @Echo " this makefile." + @Echo " If you mail me, I'll put you on my mailing-list and notify you whenever" + @Echo " new versions of Info-Zip are released." + @Echo " Have a look at the makefile for changes like CPU type, UtilLib, etc." + @Echo " Feel free to mail comments, suggestions, etc." + @Echo " Enjoy Info-Zip !" + @Echo " Haidinger Walter, " + @Echo "" + + +# Echo help in case of an error +# +.ONERROR: + @Echo "" + @Echo "[sigh] An error running this makefile was detected." + @Echo "This message may also appear if you interrupted smake by pressing CTRL-C." + @Echo "Contact Info-Zip authors at Zip-Bugs@lists.wku.edu or me for help." + @Echo "Haidinger Walter, " + diff --git a/amiga/stat.c b/amiga/stat.c new file mode 100644 index 0000000..6075c21 --- /dev/null +++ b/amiga/stat.c @@ -0,0 +1,293 @@ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* Here we have a handmade stat() function because Aztec's c.lib stat() */ +/* does not support an st_mode field, which we need... also a chmod(). */ + +/* This stat() is by Paul Wells, modified by Paul Kienitz. */ +/* Originally for use with Aztec C >= 5.0 and Lattice C <= 4.01 */ +/* Adapted for SAS/C 6.5x by Haidinger Walter */ + +/* POLICY DECISION: We will not attempt to remove global variables from */ +/* this source file for Aztec C. These routines are essentially just */ +/* augmentations of Aztec's c.lib, which is itself not reentrant. If */ +/* we want to produce a fully reentrant UnZip, we will have to use a */ +/* suitable startup module, such as purify.a for Aztec by Paul Kienitz. */ + +#ifndef __amiga_stat_c +#define __amiga_stat_c + +#include +#include +#include "amiga/z-stat.h" /* fake version of stat.h */ +#include + +#ifdef AZTEC_C +# include +# include +# include +# include +# include +# include +#endif +#ifdef __SASC +# include /* SAS/C dir function prototypes */ +# include +# include +# include +#endif + +#ifndef SUCCESS +# define SUCCESS (-1) +# define FAILURE (0) +#endif + + +void close_leftover_open_dirs(void); /* prototype */ + +static DIR *dir_cleanup_list = NULL; /* for resource tracking */ + +/* CALL THIS WHEN HANDLING CTRL-C OR OTHER UNEXPECTED EXIT! */ +void close_leftover_open_dirs(void) +{ + while (dir_cleanup_list) + closedir(dir_cleanup_list); +} + + +unsigned short disk_not_mounted; + +extern int stat(const char *file, struct stat *buf); + +stat(file,buf) +const char *file; +struct stat *buf; +{ + + struct FileInfoBlock *inf; + BPTR lock; + time_t ftime; + struct tm local_tm; + + if( (lock = Lock((char *)file,SHARED_LOCK))==0 ) + /* file not found */ + return(-1); + + if( !(inf = (struct FileInfoBlock *)AllocMem( + (long)sizeof(struct FileInfoBlock),MEMF_PUBLIC|MEMF_CLEAR)) ) + { + UnLock(lock); + return(-1); + } + + if( Examine(lock,inf)==FAILURE ) + { + FreeMem((char *)inf,(long)sizeof(*inf)); + UnLock(lock); + return(-1); + } + + /* fill in buf */ + buf->st_dev = + buf->st_nlink = + buf->st_uid = + buf->st_gid = + buf->st_rdev = 0; + buf->st_ino = inf->fib_DiskKey; + buf->st_blocks = inf->fib_NumBlocks; + buf->st_size = inf->fib_Size; + + /* now the date. AmigaDOS has weird datestamps--- + * ds_Days is the number of days since 1-1-1978; + * however, as Unix wants date since 1-1-1970... + */ + + ftime = + (inf->fib_Date.ds_Days * 86400 ) + + (inf->fib_Date.ds_Minute * 60 ) + + (inf->fib_Date.ds_Tick / TICKS_PER_SECOND ) + + (86400 * 8 * 365 ) + + (86400 * 2 ); /* two leap years */ + + /* tzset(); */ /* this should be handled by mktime(), instead */ + /* ftime += timezone; */ + local_tm = *gmtime(&ftime); + local_tm.tm_isdst = -1; + ftime = mktime(&local_tm); + + buf->st_ctime = + buf->st_atime = + buf->st_mtime = ftime; + + buf->st_mode = (inf->fib_DirEntryType < 0 ? S_IFREG : S_IFDIR); + + /* lastly, throw in the protection bits */ + buf->st_mode |= ((inf->fib_Protection ^ 0xF) & 0xFF); + + FreeMem((char *)inf, (long)sizeof(*inf)); + UnLock((BPTR)lock); + + return(0); + +} + +int fstat(int handle, struct stat *buf) +{ + /* fake some reasonable values for stdin */ + buf->st_mode = (S_IREAD|S_IWRITE|S_IFREG); + buf->st_size = -1; + buf->st_mtime = time(&buf->st_mtime); + return 0; +} + + +/* opendir(), readdir(), closedir(), rmdir(), and chmod() by Paul Kienitz. */ + +DIR *opendir(const char *path) +{ + DIR *dd = AllocMem(sizeof(DIR), MEMF_PUBLIC); + if (!dd) return NULL; + if (!(dd->d_parentlock = Lock((char *)path, MODE_OLDFILE))) { + disk_not_mounted = IoErr() == ERROR_DEVICE_NOT_MOUNTED; + FreeMem(dd, sizeof(DIR)); + return NULL; + } else + disk_not_mounted = 0; + if (!Examine(dd->d_parentlock, &dd->d_fib) || dd->d_fib.fib_EntryType < 0) { + UnLock(dd->d_parentlock); + FreeMem(dd, sizeof(DIR)); + return NULL; + } + dd->d_cleanuplink = dir_cleanup_list; /* track them resources */ + if (dir_cleanup_list) + dir_cleanup_list->d_cleanupparent = &dd->d_cleanuplink; + dd->d_cleanupparent = &dir_cleanup_list; + dir_cleanup_list = dd; + return dd; +} + +void closedir(DIR *dd) +{ + if (dd) { + if (dd->d_cleanuplink) + dd->d_cleanuplink->d_cleanupparent = dd->d_cleanupparent; + *(dd->d_cleanupparent) = dd->d_cleanuplink; + if (dd->d_parentlock) + UnLock(dd->d_parentlock); + FreeMem(dd, sizeof(DIR)); + } +} + +struct dirent *readdir(DIR *dd) +{ + return (ExNext(dd->d_parentlock, &dd->d_fib) ? (struct dirent *)dd : NULL); +} + + +#ifdef AZTEC_C + +int rmdir(const char *path) +{ + return (DeleteFile((char *)path) ? 0 : IoErr()); +} + +int chmod(const char *filename, int bits) /* bits are as for st_mode */ +{ + long protmask = (bits & 0xFF) ^ 0xF; + return !SetProtection((char *)filename, protmask); +} + + +/* This here removes unnecessary bulk from the executable with Aztec: */ +void _wb_parse(void) { } + +/* fake a unix function that does not apply to amigados: */ +int umask(void) { return 0; } + + +# include + +/* C library signal() messes up debugging yet adds no actual usefulness */ +typedef void (*__signal_return_type)(int); +__signal_return_type signal() { return SIG_ERR; } + + +/* The following replaces Aztec's argv-parsing function for compatibility with +Unix-like syntax used on other platforms. It also fixes the problem the +standard _cli_parse() has of accepting only lower-ascii characters. */ + +int _argc, _arg_len; +char **_argv, *_arg_lin; + +void _cli_parse(struct Process *pp, long alen, register UBYTE *aptr) +{ + register UBYTE *cp; + register struct CommandLineInterface *cli; + register short c; + register short starred = 0; +# ifdef PRESTART_HOOK + void Prestart_Hook(void); +# endif + + cli = (struct CommandLineInterface *) (pp->pr_CLI << 2); + cp = (UBYTE *) (cli->cli_CommandName << 2); + _arg_len = cp[0] + alen + 2; + if (!(_arg_lin = AllocMem((long) _arg_len, 0L))) + return; + c = cp[0]; + strncpy(_arg_lin, cp + 1, c); + _arg_lin[c] = 0; + for (cp = _arg_lin + c + 1; alen && (*aptr < '\n' || *aptr > '\r'); alen--) + *cp++ = *aptr++; + *cp = 0; + aptr = cp = _arg_lin + c + 1; + for (_argc = 1; ; _argc++) { + while (*cp == ' ' || *cp == '\t') + cp++; + if (!*cp) + break; + if (*cp == '"') { + cp++; + while (c = *cp++) { + if (c == '"' && !starred) { + *aptr++ = 0; + starred = 0; + break; + } else if (c == '\\' && !starred) + starred = 1; + else { + *aptr++ = c; + starred = 0; + } + } + } else { + while ((c = *cp++) && c != ' ' && c != '\t') + *aptr++ = c; + *aptr++ = 0; + } + if (c == 0) + --cp; + } + *aptr = 0; + if (!(_argv = AllocMem((_argc + 1) * sizeof(*_argv), 0L))) { + _argc = 0; + return; + } + for (c = 0, cp = _arg_lin; c < _argc; c++) { + _argv[c] = cp; + cp += strlen(cp) + 1; + } + _argv[c] = NULL; +# ifdef PRESTART_HOOK + Prestart_Hook(); +# endif +} + +#endif /* AZTEC_C */ + +#endif /* __amiga_stat_c */ diff --git a/amiga/z-stat.h b/amiga/z-stat.h new file mode 100644 index 0000000..53d6cd1 --- /dev/null +++ b/amiga/z-stat.h @@ -0,0 +1,95 @@ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#ifndef __amiga_z_stat_h +#define __amiga_z_stat_h + +/* Since older versions of the Lattice C compiler for Amiga, and all current */ +/* versions of the Manx Aztec C compiler for Amiga, either provide no stat() */ +/* function or provide one inadequate for unzip (Aztec's has no st_mode */ +/* field), we provide our own stat() function in stat.c by Paul Wells, and */ +/* this fake stat.h file by Paul Kienitz. Paul Wells originally used the */ +/* Lattice stat.h but that does not work for Aztec and is not distributable */ +/* with this package, so I made a separate one. This has to be pulled into */ +/* unzip.h when compiling an Amiga version, as "amiga/z-stat.h". */ + +/* We also provide here a "struct dirent" for use with opendir() & readdir() */ +/* functions included in amiga/stat.c. If you use amiga/stat.c, this must */ +/* be included wherever you use either readdir() or stat(). */ + +#ifdef AZTEC_C +# define __STAT_H +#else /* __SASC */ +/* do not include the following header, replacement definitions are here */ +# define _STAT_H /* do not include SAS/C */ +# define _DIRENT_H /* do not include SAS/C */ +# define _SYS_DIR_H /* do not include SAS/C */ +# define _COMMIFMT_H /* do not include SAS/C */ +# include +#endif +#include +#include + + +struct stat { + unsigned short st_mode; + time_t st_ctime, st_atime, st_mtime; + long st_size; + long st_ino; + long st_blocks; + short st_attr, st_dev, st_nlink, st_uid, st_gid, st_rdev; +}; + +#define S_IFDIR (1<<11) +#define S_IFREG (1<<10) + +#if 0 + /* these values here are totally random: */ +# define S_IFLNK (1<<14) +# define S_IFSOCK (1<<13) +# define S_IFCHR (1<<8) +# define S_IFIFO (1<<7) +# define S_IFMT (S_IFDIR|S_IFREG|S_IFCHR|S_IFLNK) +#else +# define S_IFMT (S_IFDIR|S_IFREG) +#endif + +#define S_IHIDDEN (1<<7) +#define S_ISCRIPT (1<<6) +#define S_IPURE (1<<5) +#define S_IARCHIVE (1<<4) +#define S_IREAD (1<<3) +#define S_IWRITE (1<<2) +#define S_IEXECUTE (1<<1) +#define S_IDELETE (1<<0) + +int stat(const char *name, struct stat *buf); +int fstat(int handle, struct stat *buf); /* returns dummy values */ + +typedef struct dirent { + struct dirent *d_cleanuplink, + **d_cleanupparent; + BPTR d_parentlock; + struct FileInfoBlock d_fib; +} DIR; +#define d_name d_fib.fib_FileName + +extern unsigned short disk_not_mounted; /* flag set by opendir() */ + +DIR *opendir(const char *); +void closedir(DIR *); +void close_leftover_open_dirs(void); /* call this if aborted in mid-run */ +struct dirent *readdir(DIR *); +int umask(void); + +#ifdef AZTEC_C +int rmdir(const char *); +int chmod(const char *filename, int bits); +#endif + +#endif /* __amiga_z_stat_h */ diff --git a/amiga/zipup.h b/amiga/zipup.h new file mode 100644 index 0000000..c9316f4 --- /dev/null +++ b/amiga/zipup.h @@ -0,0 +1,25 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#ifndef __amiga_zipup_h +#define __amiga_zipup_h + +#ifndef O_RAW +# define O_RAW 0 +#endif +#define fhow (O_RDONLY | O_RAW) +#define fbad (-1) +typedef int ftype; +#define zopen(n,p) open(n,p) +#define zread(f,b,n) read(f,b,n) +#define zclose(f) close(f) +#define zerr(f) (k == (extent)(-1L)) +#define zstdin 0 + +#endif /* __amiga_zipup_h */ + diff --git a/aosvs/aosvs.c b/aosvs/aosvs.c new file mode 100644 index 0000000..f944ad1 --- /dev/null +++ b/aosvs/aosvs.c @@ -0,0 +1,659 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#include +#include + +#include "zip.h" +#include /* parameter definitions */ +#include /* AOS/VS system call interface */ +#include /* AOS/VS ?FSTAT packet defs */ + +#ifndef UTIL /* AOS/VS specific fileio code not needed for UTILs */ + +#define PAD 0 +#define PATH_END ':' + +/* + * could probably avoid the union - + * all are same size & we're going to assume this + */ +typedef union zvsfstat_stru +{ + P_FSTAT norm_fstat_packet; /* normal fstat packet */ + P_FSTAT_DIR dir_fstat_packet; /* DIR/CPD fstat packet */ + P_FSTAT_UNIT unit_fstat_packet; /* unit (device) fstat packet */ + P_FSTAT_IPC ipc_fstat_packet; /* IPC file fstat packet */ +} ZVSFSTAT_STRU; + +typedef struct zextrafld +{ + char extra_header_id[2]; /* set to VS - in theory, an int */ + char extra_data_size[2]; /* size of rest, in Intel little-endian order */ + char extra_sentinel[4]; /* set to FCI w/ trailing null */ + unsigned char extra_rev; /* set to 10 for rev 1.0 */ + ZVSFSTAT_STRU fstat_packet; /* the fstat packet */ + char aclbuf[$MXACL]; /* raw ACL, or link-resolution name */ +} ZEXTRAFLD; + +#define ZEXTRA_HEADID "VS" +#define ZEXTRA_SENTINEL "FCI" +#define ZEXTRA_REV (unsigned char) 10 + +local ZEXTRAFLD zzextrafld; /* buffer for extra field containing + ?FSTAT packet & ACL buffer */ +local char zlinkres[$MXPL]; /* buf for link resolution contents */ +local char znamebuf[$MXPL]; /* buf for AOS/VS filename */ +static char vsnamebuf[$MXPL]; +static char uxnamebuf[FNMAX]; +static P_FSTAT vsfstatbuf; + +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +/* Local functions */ +local char *readd OF((DIR *)); + +char *readd(d) +DIR *d; /* directory stream to read from */ +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e; + + e = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; +} + +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 *strlower(s) +char *s; /* string to convert */ +/* Convert all uppercase letters to lowercase in string s */ +{ + char *p; /* scans string */ + + for (p = s; *p; p++) + if (*p >= 'A' && *p <= 'Z') + *p += 'a' - 'A'; + return s; +} + +char *strupper(s) +char *s; /* string to convert */ +/* Convert all lowercase letters to uppercase in string s */ +{ + char *p; /* scans string */ + + for (p = s; *p; p++) + if (*p >= 'a' && *p <= 'z') + *p -= 'a' - 'A'; + return s; +} + +char *ex2in(x, isdir, pdosflag) +char *x; /* external file name */ +int isdir; /* input: x is a directory */ +int *pdosflag; /* output: force MSDOS file attributes? */ +/* Convert the external file name to a zip file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *n; /* internal file name (malloc'ed) */ + char *t; /* shortened name */ + int dosflag; + + dosflag = dosify; /* default for non-DOS and non-OS/2 */ + + /* Find starting point in name before doing malloc */ + for (t = x; *t == '/'; t++) + ; + + if (*t == '=') /* AOS/VS for ./ */ + t++; + else if (*t == ':') /* AOS/VS for / */ + t++; + + if (!pathput) + t = last(t, PATH_END); + + if (*t == '^') /* AOS/VS for ../ */ + { + if ((n = malloc(strlen(t) + 3)) == NULL) + return NULL; + strcpy(n, "../"); + strcpy(n + 3, t + 1); + } + else if (*t == '@') /* AOS/VS for :PER:, kind of like /dev/ */ + { + if ((n = malloc(strlen(t) + 5)) == NULL) + return NULL; + strcpy(n, "/PER/"); + strcpy(n + 5, t + 1); + } + else + { + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + } + /* now turn AOS/VS dir separators (colons) into slashes */ + for (t = n; *t != '\0'; t++) + if (*t == ':') + *t = '/'; + /* + * Convert filename to uppercase (for correct matching). + * (It may make more sense to patch the matching code, since + * we may want those filenames in uppercase on the target system, + * but this seems better at present. If we're converting, uppercase + * also seems to make sense.) + */ + strupper(n); + + + if (dosify) + msname(n); + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + return n; +} + + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + + return x; +} + +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ + time_t u[2]; /* argument for utime() */ + + /* Convert DOS time to time_t format in u */ + u[0] = u[1] = dos2unixtime(d); + utime(f, u); +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + /* convert FNMAX to malloc - 11/8/04 EG */ + char *name; + int len = strlen(f); + + if (f == label) { + if (a != NULL) + *a = label_mode; + if (n != NULL) + *n = -2L; /* convention for a label name */ + if (t != NULL) + t->atime = t->mtime = t->ctime = label_utim; + return label_time; + } + if ((name = malloc(len + 1)) == NULL) { + ZIPERR(ZE_MEM, "filetime"); + } + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + + if (strcmp(f, "-") == 0) { + if (fstat(fileno(stdin), &s) != 0) + error("fstat(stdin)"); + } else if (LSSTAT(name, &s) != 0) { + /* Accept about any file kind including directories + * (stored with trailing / with -r option) + */ + free(name); + return 0; + } + free(name); + + if (a != NULL) { + *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE); + if ((s.st_mode & S_IFDIR) != 0) { + *a |= MSDOS_DIR_ATTR; + } + } + if (n != NULL) + *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_ctime; + } + + return unix2dostime(&s.st_ctime); +} + +int deletedir(d) +char *d; +{ + return rmdir(d); +} + +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; + /* create extra field and change z->att if desired */ + /* NOTE: this AOS/VS version assumes the pathname in z->name is an + * AOS/VS pathname, not a unix-style one. Since you can zip up using + * unix-style pathnames, this may create problems occasionally. + * We COULD add code to parse back to AOS/VS format ... + * (This might also fail for other reasons such as access denied, but + * that should already have occurred.) + * We set the central-dir extra fld pointer & length here to the same data. + */ +{ + int aclend = 0; +/* + * use this to simplify because different calls depending on + * whether links are resolved + */ + unsigned short errc; + + z->ext = 0; /* init to no extra field */ +/* get the ?FSTAT info & the acl - if no errors, get memory & store. + * (first, we have to cut off the trailing slash that was added if + * it's a dir, since AOS/VS doesn't accept that kind of thing) + */ + strncpy(znamebuf, z->name, $MXPL); + znamebuf[$MXPL-1] = '\0'; + if (znamebuf[strlen(znamebuf)-1] == '/') + znamebuf[strlen(znamebuf)-1] = '\0'; + if (linkput) + errc = sys_fstat(znamebuf, BIT1, &(zzextrafld.fstat_packet)); + else + errc = sys_fstat(znamebuf, 0, &(zzextrafld.fstat_packet)); + if (errc) + { + fprintf(stderr, + "\n Warning: can't get ?FSTAT info & acl of %s - error %d\n ", + znamebuf, errc); + perror("sys_fstat()"); + } + else + { + /* store the ACL - or, if a link (no ACL!), store the resolution name */ + if (zzextrafld.fstat_packet.norm_fstat_packet.styp_type != $FLNK) + { + if ((errc = sys_gacl(znamebuf, zzextrafld.aclbuf)) != 0) + { + fprintf(stderr, "\n Warning: can't get acl of %s - error %d\n ", + z->name, errc); + perror("sys_gacl()"); + } + else + { + /* find length of ACL - ends with double-null */ + while (aclend++ < $MXACL && + (zzextrafld.aclbuf[aclend - 1] != '\0' || + zzextrafld.aclbuf[aclend] != '\0')) + /* EMPTY LOOP */ ; + if ((z->cextra = z->extra = + malloc(sizeof(ZEXTRAFLD) - $MXACL + aclend + 4)) != NULL) + { + strncpy(zzextrafld.extra_header_id, ZEXTRA_HEADID, + sizeof(zzextrafld.extra_header_id)); + strncpy(zzextrafld.extra_sentinel, ZEXTRA_SENTINEL, + sizeof(zzextrafld.extra_sentinel)); + zzextrafld.extra_rev = ZEXTRA_REV; /* this is a char, no need + to worry about byte order */ + /* set size (Intel (little-endian)) 2-byte int, which we've set + as array to make it easier */ + errc = (unsigned short) (sizeof(ZEXTRAFLD) - $MXACL + aclend + 4 - + sizeof(zzextrafld.extra_header_id) - + sizeof(zzextrafld.extra_data_size)); + zzextrafld.extra_data_size[0] = errc & 0xFF; /* low-order byte */ + zzextrafld.extra_data_size[1] = errc >> 8; /* high-order byte */ + memcpy((char *) z->extra, (char *) &zzextrafld, + sizeof(ZEXTRAFLD) - $MXACL + aclend + 4); + z->cext = z->ext = sizeof(ZEXTRAFLD) - $MXACL + aclend + 4; + } + } + } + else /* a link */ + { + if ((errc = sys_glink(z->name, zzextrafld.aclbuf)) != 0) + { + fprintf(stderr, + "\n Warning: can't get link-resolution of %s - error %d\n ", + z->name, errc); + perror("sys_glink()"); + } + else + { + aclend = strlen(zzextrafld.aclbuf) + 1; + if ((z->extra = malloc(sizeof(ZEXTRAFLD) - $MXACL + aclend + 4)) + != NULL) + { + strncpy(zzextrafld.extra_header_id, ZEXTRA_HEADID, + sizeof(zzextrafld.extra_header_id)); + strncpy(zzextrafld.extra_sentinel, ZEXTRA_SENTINEL, + sizeof(zzextrafld.extra_sentinel)); + zzextrafld.extra_rev = ZEXTRA_REV; /* this is a char, no need + to worry about byte order */ + /* set size (Intel (little-endian)) 2-byte int, which we've set + as array to make it easier */ + errc = (unsigned short) (sizeof(ZEXTRAFLD) - $MXACL + aclend + 4 - + sizeof(zzextrafld.extra_header_id) - + sizeof(zzextrafld.extra_data_size)); + zzextrafld.extra_data_size[0] = errc & 0xFF; /* low-order byte */ + zzextrafld.extra_data_size[1] = errc >> 8; /* high-order byte */ + memcpy((char *) z->extra, (char *) &zzextrafld, + sizeof(ZEXTRAFLD) - $MXACL + aclend + 4); + z->ext = sizeof(ZEXTRAFLD) - $MXACL + aclend + 4; + } + } + } + } + return ZE_OK; +} + +#endif /* !UTIL */ + +void version_local() +{ + printf("Compiled with %s under %s.\n", + "a C compiler", + "AOS/VS" + ); +} + + +/* + * This file defines for AOS/VS two Unix functions relating to links; + * the calling code should have the following defines: + * + * #define lstat(path,buf) zvs_lstat(path,buf) + * #define readlink(path,buf,nbytes) zvs_readlink(path,buf,nbytes) + * + * For these functions, I'm going to define yet 2 MORE filename buffers + * and also insert code to change pathnames to Unix & back. This is + * easier than changing all the other places this kind of thing happens to + * be efficient. This is a kludge. I'm also going to put the functions + * here for my immediate convenience rather than somewhere else for + * someone else's. + * + * WARNING: the use of static buffers means that you'd better get your + * data out of these buffers before the next call to any of these functions! + * + */ + +/* ========================================================================= + * ZVS_LSTAT() - get (or simulate) stat information WITHOUT following symlinks + * This is intended to look to the outside like the unix lstat() + * function. We do a quick-&-dirty filename conversion. + * + * If the file is NOT a symbolic link, we can just do a stat() on it and + * that should be fine. But if it IS a link, we have to set the elements + * of the stat struct ourselves, since AOS/VS doesn't have a built-in + * lstat() function. + * + * RETURNS: 0 on success, or -1 otherwise + * + */ + +int zvs_lstat(char *path, struct stat *buf) +{ + char *cp_vs = vsnamebuf; + char *cp_ux = path; + int mm, dd, yy; + + /* + * Convert the Unix pathname to an AOS/VS pathname. + * This is quick & dirty; it won't handle (for instance) pathnames with + * ../ in the middle of them, and may choke on other Unixisms. We hope + * they're unlikely. + */ + if (!strncmp(cp_ux, "../", 3)) + { + *cp_vs++ = '^'; /* AOS/VS for ../ */ + cp_ux += 3; + } + else if (!strncmp(cp_ux, "./", 2)) + { + *cp_vs++ = '='; /* AOS/VS for ./ */ + cp_ux += 2; + } + + do + { + if (*cp_ux == '/') + { + *cp_vs++ = ':'; + } + else + { + *cp_vs++ = (char) toupper(*cp_ux); + } + + } while (*cp_ux++ != '\0' && cp_vs - vsnamebuf < sizeof(vsnamebuf)); + + /* If Unix name was too long for our buffer, return an error return */ + if (cp_vs - vsnamebuf >= sizeof(vsnamebuf) && *(cp_vs - 1) != '\0') + return (-1); /* error */ + + /* Make AOS/VS ?FSTAT call that won't follow links & see if we find + * anything. If not, we return error. + */ + if (sys_fstat(vsnamebuf, + BIT1, /* BIT1 says to not resolve links */ + &vsfstatbuf)) + return (-1); /* error */ + + /* If we DID find the file but it's not a link, + * call stat() and return its value. + */ + if (vsfstatbuf.styp_type != $FLNK) + return (stat(path, buf)); /* call with Unix pathname ... */ + + /* Otherwise, we have to kludge up values for the stat structure */ + memset((char *) buf, 0, sizeof(*buf)); /* init to nulls (0 values) */ + buf->st_mode = S_IFLNK | 0777; /* link and rwxrwxrwx */ + buf->st_uid = -1; /* this is what we get on AOS/VS + anyway (maybe unless we set up + a dummy password file?) */ + buf->st_nlink = 1; + /* The DG date we've got is days since 12/31/67 and seconds/2. So we + * need to subtract 732 days (if that's not negative), convert to seconds, + * and add adjusted seconds. + */ + if (vsfstatbuf.stch.short_time[0] < 732) + buf->st_ctime = buf->st_mtime = buf->st_atime = 0L; + else + { + buf->st_ctime = buf->st_mtime = buf->st_atime = + ((long) vsfstatbuf.stch.short_time[0] - 732L) * 24L * 3600L + + 2L * (long) vsfstatbuf.stch.short_time[1]; + } + + /* And we need to get the filename linked to and use its length as + * the file size. We'll use the Unix pathname buffer for this - hope + * it's big enough. (We won't overwrite anything, but we could get a + * truncated path.) If there's an error, here's our last chance to + * say anything. + */ + if ((buf->st_size = zvs_readlink(vsnamebuf, uxnamebuf, FNMAX)) < 0) + return (-1); + else + return (0); + +} /* end zvs_lstat() */ + +/* ========================================================================= + * ZVS_READLINK() - get pathname pointed to by an AOS/VS link file + * This is intended to look to the outside like the unix readlink() + * function. We do a quick-&-dirty filename conversion. + * + * RETURNS: the length of the output path (in bytes), or -1 if an error + * + */ + +int zvs_readlink(char *path, char *buf, int nbytes) +{ + char *cp_vs = vsnamebuf; + char *cp_ux = buf; + + /* This is called with z->name, the filename the user gave, so we'll get + * the link-resolution name on the assumption that it's a valid AOS/VS + * name. We're also assuming a reasonable value (> 5) for nbytes. + */ + if (sys_glink(path, vsnamebuf)) + return (-1); /* readlink() is supposed to return -1 on error */ + + /* Now, convert the AOS/VS pathname to a Unix pathname. + * Note that sys_glink(), unlike readlink(), does add a null. + */ + if (*cp_vs == '^') /* AOS/VS for ../ */ + { + strncpy(cp_ux, "../", 3); + cp_ux += 3; + cp_vs++; + } + else if (*cp_vs == '@') /* AOS/VS for :PER:, kind of like /dev/ */ + { + strncpy(cp_ux, "/PER/", 5); + cp_ux += 5; + cp_vs++; + } + else if (*cp_vs == '=') /* AOS/VS for ./ */ + { + strncpy(cp_ux, "./", 2); + cp_ux += 2; + cp_vs++; + } + while (*cp_vs != '\0' && cp_ux - buf < nbytes) + { + if (*cp_vs == ':') + { + *cp_ux++ = '/'; + } + else + { + *cp_ux++ = (char) toupper(*cp_vs); + } + cp_vs++; + } + + return (cp_ux - buf); /* # characters in Unix path (no trailing null) */ + +} /* end zvs_readlink() */ diff --git a/aosvs/make.cli b/aosvs/make.cli new file mode 100644 index 0000000..32b2624 --- /dev/null +++ b/aosvs/make.cli @@ -0,0 +1,5 @@ +push +prompt pop +sea :c_4.10 :c_4.10:lang_rt [!sea] +cc%0/%/link/NOUNX AOS_VS/DEFINE NODIR/DEFINE .C +pop diff --git a/api.c b/api.c new file mode 100644 index 0000000..b6f57e7 --- /dev/null +++ b/api.c @@ -0,0 +1,718 @@ +/* + api.c - Zip 3 + + Copyright (c) 1990-2007 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 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 +*/ +/*--------------------------------------------------------------------------- + + api.c + + This module supplies a Zip dll engine for use directly from C/C++ + programs. + + The entry points are: + + ZpVer *ZpVersion(void); + int EXPENTRY ZpInit(LPZIPUSERFUNCTIONS lpZipUserFunc); + int EXPENTRY ZpArchive(ZCL C, LPZPOPT Opts); + + This module is currently only used by the Windows dll, and is not used at + all by any of the other platforms, although it should be easy enough to + implement this on most platforms. + + ---------------------------------------------------------------------------*/ +#define __API_C + +#include +#ifdef WINDLL +# include +# include "windll/windll.h" +#endif + +#ifdef OS2 +# define INCL_DOSMEMMGR +# include +#endif + +#ifdef __BORLANDC__ +#include +#endif +#include +#include +#include "api.h" /* this includes zip.h */ +#include "crypt.h" +#include "revision.h" +#ifdef USE_ZLIB +# include "zlib.h" +#endif + + +DLLPRNT *lpZipPrint; +DLLPASSWORD *lpZipPassword; +extern DLLCOMMENT *lpComment; +ZIPUSERFUNCTIONS ZipUserFunctions, far * lpZipUserFunctions; + +int ZipRet; +char szOrigDir[PATH_MAX]; +BOOL fNo_int64 = FALSE; /* flag for DLLSERVICE_NO_INT64 */ + +/* Local forward declarations */ +extern int zipmain OF((int, char **)); +int AllocMemory(unsigned int, char *, char *, BOOL); +int ParseString(LPSTR, unsigned int); +void FreeArgVee(void); + +ZPOPT Options; +char **argVee; +unsigned int argCee; + +/*--------------------------------------------------------------------------- + Local functions + ---------------------------------------------------------------------------*/ + +char szRootDir[PATH_MAX], szExcludeList[PATH_MAX], szIncludeList[PATH_MAX], szTempDir[PATH_MAX]; + +int ParseString(LPSTR s, unsigned int ArgC) +{ +unsigned int i; +int root_flag, m, j; +char *str1, *str2, *str3; +size_t size; + +i = ArgC; +str1 = (char *) malloc(lstrlen(s)+4); +lstrcpy(str1, s); +lstrcat(str1, " @"); + +if ((szRootDir != NULL) && (szRootDir[0] != '\0')) + { + root_flag = TRUE; + if (szRootDir[lstrlen(szRootDir)-1] != '\\') + lstrcat(szRootDir, "\\"); + } +else + root_flag = FALSE; + +str2 = strchr(str1, '\"'); /* get first occurance of double quote */ + +while ((str3 = strchr(str1, '\t')) != NULL) + { + str3[0] = ' '; /* Change tabs into a single space */ + } + +/* Note that if a quoted string contains multiple adjacent spaces, they + will not be removed, because they could well point to a valid + folder/file name. +*/ +while ((str2 = strchr(str1, '\"')) != NULL) + /* Found a double quote if not NULL */ + { + str3 = strchr(str2+1, '\"'); /* Get the second quote */ + if (str3 == NULL) + { + free(str1); + return ZE_PARMS; /* Something is screwy with the + string, bail out */ + } + str3[0] = '\0'; /* terminate str2 with a NULL */ + + /* strip unwanted fully qualified path from entry */ + if (root_flag) + if ((_strnicmp(szRootDir, str2+1, lstrlen(szRootDir))) == 0) + { + m = 0; + str2++; + for (j = lstrlen(szRootDir); j < lstrlen(str2); j++) + str2[m++] = str2[j]; + str2[m] = '\0'; + str2--; + } + size = _msize(argVee); + if ((argVee = (char **)realloc(argVee, size + sizeof(char *))) == NULL) + { + fprintf(stdout, "Unable to allocate memory in zip dll\n"); + return ZE_MEM; + } + /* argCee is incremented in AllocMemory */ + if (AllocMemory(i, str2+1, "Creating file list from string", TRUE) != ZE_OK) + { + free(str1); + return ZE_MEM; + } + i++; + str3+=2; /* Point past the whitespace character */ + str2[0] = '\0'; /* Terminate str1 */ + lstrcat(str1, str3); + } /* end while */ + +/* points to first occurance of a space */ +str2 = strchr(str1, ' '); + +/* Go through the string character by character, looking for instances + of two spaces together. Terminate when you find the trailing @ +*/ +while ((str2[0] != '\0') && (str2[0] != '@')) + { + while ((str2[0] == ' ') && (str2[1] == ' ')) + { + str3 = &str2[1]; + str2[0] = '\0'; + lstrcat(str1, str3); + } + str2++; + } + +/* Do we still have a leading space? */ +if (str1[0] == ' ') + { + str3 = &str1[1]; + lstrcpy(str1, str3); /* Dump the leading space */ + } + + +/* Okay, now we have gotten rid of any tabs and replaced them with + spaces, and have replaced multiple spaces with a single space. We + couldn't do this before because the folder names could have actually + contained these characters. +*/ + +str2 = str3 = str1; + +while ((str2[0] != '\0') && (str3[0] != '@')) + { + str3 = strchr(str2+1, ' '); + str3[0] = '\0'; + /* strip unwanted fully qualified path from entry */ + if (root_flag) + if ((_strnicmp(szRootDir, str2, lstrlen(szRootDir))) == 0) + { + m = 0; + for (j = lstrlen(Options.szRootDir); j < lstrlen(str2); j++) + str2[m++] = str2[j]; + str2[m] = '\0'; + } + size = _msize(argVee); + if ((argVee = (char **)realloc(argVee, size + sizeof(char *))) == NULL) + { + fprintf(stdout, "Unable to allocate memory in zip dll\n"); + return ZE_MEM; + } + if (AllocMemory(i, str2, "Creating file list from string", TRUE) != ZE_OK) + { + free(str1); + return ZE_MEM; + } + i++; + str3++; + str2 = str3; + } +free(str1); +return ZE_OK; +} + +int AllocMemory(unsigned int i, char *cmd, char *str, BOOL IncrementArgCee) +{ +if ((argVee[i] = (char *) malloc( sizeof(char) * strlen(cmd)+1 )) == NULL) + { + if (IncrementArgCee) + argCee++; + FreeArgVee(); + fprintf(stdout, "Unable to allocate memory in zip library at %s\n", str); + return ZE_MEM; + } +strcpy( argVee[i], cmd ); +argCee++; +return ZE_OK; +} + +void FreeArgVee(void) +{ +unsigned i; + +/* Free the arguments in the array */ +for (i = 0; i < argCee; i++) + { + free (argVee[i]); + argVee[i] = NULL; + } +/* Then free the array itself */ +free(argVee); + +/* Restore the original working directory */ +chdir(szOrigDir); +#ifdef __BORLANDC__ +setdisk(toupper(szOrigDir[0]) - 'A'); +#endif + +} + + +/*--------------------------------------------------------------------------- + Documented API entry points + ---------------------------------------------------------------------------*/ + +int EXPENTRY ZpInit(LPZIPUSERFUNCTIONS lpZipUserFunc) +{ +ZipUserFunctions = *lpZipUserFunc; +lpZipUserFunctions = &ZipUserFunctions; + +if (!lpZipUserFunctions->print || + !lpZipUserFunctions->comment) + return FALSE; + +return TRUE; +} + +int EXPENTRY ZpArchive(ZCL C, LPZPOPT Opts) +/* Add, update, freshen, or delete zip entries in a zip file. See the + command help in help() zip.c */ +{ +int k, j, m; +size_t size; + +Options = *Opts; /* Save off options, and make them available locally */ +szRootDir[0] = '\0'; +szExcludeList[0] = '\0'; +szIncludeList[0] = '\0'; +szTempDir[0] = '\0'; +if (Options.szRootDir) lstrcpy(szRootDir, Options.szRootDir); +if (Options.szExcludeList) lstrcpy(szExcludeList, Options.szExcludeList); +if (Options.szIncludeList) lstrcpy(szIncludeList, Options.szIncludeList); +if (Options.szTempDir) lstrcpy(szTempDir, Options.szTempDir); + +getcwd(szOrigDir, PATH_MAX); /* Save current drive and directory */ + +if ((szRootDir != NULL) && (szRootDir[0] != '\0')) + { + /* Make sure there isn't a trailing slash */ + if (szRootDir[lstrlen(szRootDir)-1] == '\\') + szRootDir[lstrlen(szRootDir)-1] = '\0'; + + chdir(szRootDir); +#ifdef __BORLANDC__ + setdisk(toupper(szRootDir[0]) - 'A'); +#endif + } + +argCee = 0; + +/* malloc additional 40 to allow for additional command line arguments. Note + that we are also adding in the count for the include lists as well as the + exclude list. */ +if ((argVee = (char **)malloc((C.argc+40)*sizeof(char *))) == NULL) + { + fprintf(stdout, "Unable to allocate memory in zip dll\n"); + return ZE_MEM; + } +if ((argVee[argCee] = (char *) malloc( sizeof(char) * strlen("wiz.exe")+1 )) == NULL) + { + free(argVee); + fprintf(stdout, "Unable to allocate memory in zip dll\n"); + return ZE_MEM; + } +strcpy( argVee[argCee], "wiz.exe" ); +argCee++; + + +/* Set compression level efficacy -0...-9 */ +if (AllocMemory(argCee, "-0", "Compression", FALSE) != ZE_OK) + return ZE_MEM; + +/* Check to see if the compression level is set to a valid value. If + not, then set it to the default. +*/ +if ((Options.fLevel < '0') || (Options.fLevel > '9')) + { + Options.fLevel = '6'; + if (!Options.fDeleteEntries) + fprintf(stdout, "Compression level set to invalid value. Setting to default\n"); + } + +argVee[argCee-1][1] = Options.fLevel; + +if (Options.fOffsets) /* Update offsets for SFX prefix */ + { + if (AllocMemory(argCee, "-A", "Offsets", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fDeleteEntries) /* Delete files from zip file -d */ + { + if (AllocMemory(argCee, "-d", "Delete", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fNoDirEntries) /* Do not add directory entries -D */ + { + if (AllocMemory(argCee, "-D", "No Dir Entries", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fFreshen) /* Freshen zip file--overwrite only -f */ + { + if (AllocMemory(argCee, "-f", "Freshen", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fRepair) /* Fix archive -F or -FF */ + { + if (Options.fRepair == 1) + { + if (AllocMemory(argCee, "-F", "Repair", FALSE) != ZE_OK) + return ZE_MEM; + } + else + { + if (AllocMemory(argCee, "-FF", "Repair", FALSE) != ZE_OK) + return ZE_MEM; + } + } +if (Options.fGrow) /* Allow appending to a zip file -g */ + { + if (AllocMemory(argCee, "-g", "Appending", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fJunkDir) /* Junk directory names -j */ + { + if (AllocMemory(argCee, "-j", "Junk Dir Names", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fEncrypt) /* encrypt -e */ + { + if (AllocMemory(argCee, "-e", "Encrypt", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fJunkSFX) /* Junk sfx prefix */ + { + if (AllocMemory(argCee, "-J", "Junk SFX", FALSE) != ZE_OK) + return ZE_MEM; + } + +if (Options.fForce) /* Make entries using DOS names (k for Katz) -k */ + { + if (AllocMemory(argCee, "-k", "Force DOS", FALSE) != ZE_OK) + return ZE_MEM; + } + +if (Options.fLF_CRLF) /* Translate LF_CRLF -l */ + { + if (AllocMemory(argCee, "-l", "LF-CRLF", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fCRLF_LF) /* Translate CR/LF to LF -ll */ + { + if (AllocMemory(argCee, "-ll", "CRLF-LF", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fMove) /* Delete files added to or updated in zip file -m */ + { + if (AllocMemory(argCee, "-m", "Move", FALSE) != ZE_OK) + return ZE_MEM; + } + +if (Options.fLatestTime) /* Set zip file time to time of latest file in it -o */ + { + if (AllocMemory(argCee, "-o", "Time", FALSE) != ZE_OK) + return ZE_MEM; + } + +if (Options.fComment) /* Add archive comment "-z" */ + { + if (AllocMemory(argCee, "-z", "Comment", FALSE) != ZE_OK) + return ZE_MEM; + } + +if (Options.fQuiet) /* quiet operation -q */ + { + if (AllocMemory(argCee, "-q", "Quiet", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fRecurse == 1) /* recurse into subdirectories -r */ + { + if (AllocMemory(argCee, "-r", "Recurse -r", FALSE) != ZE_OK) + return ZE_MEM; + } +else if (Options.fRecurse == 2) /* recurse into subdirectories -R */ + { + if (AllocMemory(argCee, "-R", "Recurse -R", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fSystem) /* include system and hidden files -S */ + { + if (AllocMemory(argCee, "-S", "System", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fExcludeDate) /* Exclude files newer than specified date -tt */ + { + if ((Options.Date != NULL) && (Options.Date[0] != '\0')) + { + if (AllocMemory(argCee, "-tt", "Date", FALSE) != ZE_OK) + return ZE_MEM; + if (AllocMemory(argCee, Options.Date, "Date", FALSE) != ZE_OK) + return ZE_MEM; + } + } + +if (Options.fIncludeDate) /* include files newer than specified date -t */ + { + if ((Options.Date != NULL) && (Options.Date[0] != '\0')) + { + if (AllocMemory(argCee, "-t", "Date", FALSE) != ZE_OK) + return ZE_MEM; + if (AllocMemory(argCee, Options.Date, "Date", FALSE) != ZE_OK) + return ZE_MEM; + } + } + +if (Options.fUpdate) /* Update zip file--overwrite only if newer -u */ + { + if (AllocMemory(argCee, "-u", "Update", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fVerbose) /* Mention oddities in zip file structure -v */ + { + if (AllocMemory(argCee, "-v", "Verbose", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fVolume) /* Include volume label -$ */ + { + if (AllocMemory(argCee, "-$", "Volume", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.szSplitSize != NULL) /* Turn on archive splitting */ + { + if (AllocMemory(argCee, "-s", "Splitting", FALSE) != ZE_OK) + return ZE_MEM; + if (AllocMemory(argCee, Options.szSplitSize, "Split size", FALSE) != ZE_OK) + return ZE_MEM; + } +if (lpZipUserFunctions->split != NULL) /* Turn on archive split destinations select */ + { + if (AllocMemory(argCee, "-sp", "Split Pause Select Destination", FALSE) != ZE_OK) + return ZE_MEM; + } +#ifdef WIN32 +if (Options.fPrivilege) /* Use privileges -! */ + { + if (AllocMemory(argCee, "-!", "Privileges", FALSE) != ZE_OK) + return ZE_MEM; + } +#endif +if (Options.fExtra) /* Exclude extra attributes -X */ + { + if (AllocMemory(argCee, "-X", "Extra", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.IncludeList != NULL) /* Include file list -i */ + { + if (AllocMemory(argCee, "-i", "Include file list", FALSE) != ZE_OK) + return ZE_MEM; + k = 0; + if (Options.IncludeListCount > 0) + while ((Options.IncludeList[k] != NULL) && (Options.IncludeListCount != k+1)) + { + size = _msize(argVee); + if ((argVee = (char **)realloc(argVee, size + sizeof(char *))) == NULL) + { + fprintf(stdout, "Unable to allocate memory in zip dll\n"); + return ZE_MEM; + } + if (AllocMemory(argCee, Options.IncludeList[k], "Include file list array", TRUE) != ZE_OK) + { + return ZE_MEM; + } + k++; + } + else + while (Options.IncludeList[k] != NULL) + { + size = _msize(argVee); + if ((argVee = (char **)realloc(argVee, size + sizeof(char *))) == NULL) + { + FreeArgVee(); + fprintf(stdout, "Unable to allocate memory in zip dll\n"); + return ZE_MEM; + } + if (AllocMemory(argCee, Options.IncludeList[k], "Include file list array", TRUE) != ZE_OK) + return ZE_MEM; + k++; + } + + if (AllocMemory(argCee, "@", "End of Include List", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.ExcludeList != NULL) /* Exclude file list -x */ + { + if (AllocMemory(argCee, "-x", "Exclude file list", FALSE) != ZE_OK) + return ZE_MEM; + k = 0; + if (Options.ExcludeListCount > 0) + while ((Options.ExcludeList[k] != NULL) && (Options.ExcludeListCount != k+1)) + { + size = _msize(argVee); + if ((argVee = (char **)realloc(argVee, size + sizeof(char *))) == NULL) + { + fprintf(stdout, "Unable to allocate memory in zip dll\n"); + return ZE_MEM; + } + if (AllocMemory(argCee, Options.ExcludeList[k], "Exclude file list array", TRUE) != ZE_OK) + return ZE_MEM; + k++; + } + else + while (Options.ExcludeList[k] != NULL) + { + size = _msize(argVee); + if ((argVee = (char **)realloc(argVee, size + sizeof(char *))) == NULL) + { + FreeArgVee(); + fprintf(stdout, "Unable to allocate memory in zip dll\n"); + return ZE_MEM; + } + if (AllocMemory(argCee, Options.ExcludeList[k], "Exclude file list array", TRUE) != ZE_OK) + return ZE_MEM; + k++; + } + if (AllocMemory(argCee, "@", "End of Exclude List", FALSE) != ZE_OK) + return ZE_MEM; + } + +if (szIncludeList != NULL && szIncludeList[0] != '\0') /* Include file list -i */ + { + if (AllocMemory(argCee, "-i", "Include file list", FALSE) != ZE_OK) + return ZE_MEM; + if ((k = ParseString(szIncludeList, argCee)) != ZE_OK) + return k; /* Something was screwy with the parsed string + bail out */ + if (AllocMemory(argCee, "@", "End of Include List", FALSE) != ZE_OK) + return ZE_MEM; + } +if (szExcludeList != NULL && szExcludeList[0] != '\0') /* Exclude file list -x */ + { + if (AllocMemory(argCee, "-x", "Exclude file list", FALSE) != ZE_OK) + return ZE_MEM; + + if ((k = ParseString(szExcludeList, argCee)) != ZE_OK) + return k; /* Something was screwy with the parsed string + bail out */ + + if (AllocMemory(argCee, "@", "End of Exclude List", FALSE) != ZE_OK) + return ZE_MEM; + } + +if ((szTempDir != NULL) && (szTempDir[0] != '\0') + && Options.fTemp) /* Use temporary directory -b */ + { + if (AllocMemory(argCee, "-b", "Temp dir switch command", FALSE) != ZE_OK) + return ZE_MEM; + if (AllocMemory(argCee, szTempDir, "Temporary directory", FALSE) != ZE_OK) + return ZE_MEM; + } + +if (AllocMemory(argCee, C.lpszZipFN, "Zip file name", FALSE) != ZE_OK) + return ZE_MEM; + +if ((szRootDir != NULL) && (szRootDir[0] != '\0')) + { + if (szRootDir[lstrlen(szRootDir)-1] != '\\') + lstrcat(szRootDir, "\\"); /* append trailing \\ */ + if (C.FNV != NULL) + { + for (k = 0; k < C.argc; k++) + { + if (AllocMemory(argCee, C.FNV[k], "Making argv", FALSE) != ZE_OK) + return ZE_MEM; + if ((_strnicmp(szRootDir, C.FNV[k], lstrlen(szRootDir))) == 0) + { + m = 0; + for (j = lstrlen(szRootDir); j < lstrlen(C.FNV[k]); j++) + argVee[argCee-1][m++] = C.FNV[k][j]; + argVee[argCee-1][m] = '\0'; + } + } + } + + } +else + if (C.FNV != NULL) + for (k = 0; k < C.argc; k++) + { + if (AllocMemory(argCee, C.FNV[k], "Making argv", FALSE) != ZE_OK) + return ZE_MEM; + } + +if (C.lpszAltFNL != NULL) + { + if ((k = ParseString(C.lpszAltFNL, argCee)) != ZE_OK) + return k; /* Something was screwy with the parsed string + bail out + */ + } + + + +argVee[argCee] = NULL; + +ZipRet = zipmain(argCee, argVee); + +/* Free the arguments in the array. Note this also restores the + current directory + */ +FreeArgVee(); + +return ZipRet; +} + +#if CRYPT +int encr_passwd(int modeflag, char *pwbuf, int size, const char *zfn) + { + return (*lpZipUserFunctions->password)(pwbuf, size, ((modeflag == ZP_PW_VERIFY) ? + "Verify password: " : "Enter password: "), + (char *)zfn); + } +#endif /* CRYPT */ + +void EXPENTRY ZpVersion(ZpVer far * p) /* should be pointer to const struct */ + { + p->structlen = ZPVER_LEN; + +#ifdef BETA + p->flag = 1; +#else + p->flag = 0; +#endif +#ifdef CRYPT + p->fEncryption = TRUE; +#else + p->fEncryption = FALSE; +#endif + lstrcpy(p->betalevel, Z_BETALEVEL); + lstrcpy(p->date, REVDATE); + +#ifdef ZLIB_VERSION + lstrcpy(p->zlib_version, ZLIB_VERSION); + p->flag |= 2; +#else + p->zlib_version[0] = '\0'; +#endif + +#ifdef ZIP64_SUPPORT + p->flag |= 4; /* Flag that ZIP64 was compiled in. */ +#endif + + p->zip.major = Z_MAJORVER; + p->zip.minor = Z_MINORVER; + p->zip.patchlevel = Z_PATCHLEVEL; + +#ifdef OS2 + p->os2dll.major = D2_MAJORVER; + p->os2dll.minor = D2_MINORVER; + p->os2dll.patchlevel = D2_PATCHLEVEL; +#endif +#ifdef WINDLL + p->windll.major = DW_MAJORVER; + p->windll.minor = DW_MINORVER; + p->windll.patchlevel = DW_PATCHLEVEL; +#endif + } diff --git a/api.h b/api.h new file mode 100644 index 0000000..f609633 --- /dev/null +++ b/api.h @@ -0,0 +1,184 @@ +/* + api.h - Zip 3 + + Copyright (c) 1990-2007 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 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 +*/ +/* Only the Windows DLL is currently supported */ +#ifndef _ZIPAPI_H +#define _ZIPAPI_H + +#include "zip.h" + +#ifdef WIN32 +# ifndef PATH_MAX +# define PATH_MAX 260 +# endif +#else +# ifndef PATH_MAX +# define PATH_MAX 128 +# endif +#endif + +#if defined(WINDLL) || defined(API) +#include +/* Porting definations between Win 3.1x and Win32 */ +#ifdef WIN32 +# define far +# define _far +# define __far +# define near +# define _near +# define __near +#endif + +/*--------------------------------------------------------------------------- + Prototypes for public Zip API (DLL) functions. + ---------------------------------------------------------------------------*/ + +#define ZPVER_LEN sizeof(ZpVer) +/* These defines are set to zero for now, until OS/2 comes out + with a dll. + */ +#define D2_MAJORVER 0 +#define D2_MINORVER 0 +#define D2_PATCHLEVEL 0 + +/* intended to be a private struct: */ +typedef struct _zip_ver { + uch major; /* e.g., integer 5 */ + uch minor; /* e.g., 2 */ + uch patchlevel; /* e.g., 0 */ + uch not_used; +} _zip_version_type; + +typedef struct _ZpVer { + ulg structlen; /* length of the struct being passed */ + ulg flag; /* bit 0: is_beta bit 1: uses_zlib */ + char betalevel[10]; /* e.g., "g BETA" or "" */ + char date[20]; /* e.g., "4 Sep 95" (beta) or "4 September 1995" */ + char zlib_version[10]; /* e.g., "0.95" or NULL */ + BOOL fEncryption; /* TRUE if encryption enabled, FALSE otherwise */ + _zip_version_type zip; + _zip_version_type os2dll; + _zip_version_type windll; +} ZpVer; + +# ifndef EXPENTRY +# define EXPENTRY WINAPI +# endif + +#ifndef DEFINED_ONCE +#define DEFINED_ONCE +typedef int (WINAPI DLLPRNT) (LPSTR, unsigned long); +typedef int (WINAPI DLLPASSWORD) (LPSTR, int, LPCSTR, LPCSTR); +#endif +#ifdef ZIP64_SUPPORT +typedef int (WINAPI DLLSERVICE) (LPCSTR, unsigned __int64); +typedef int (WINAPI DLLSERVICE_NO_INT64) (LPCSTR, unsigned long, unsigned long); +#else +typedef int (WINAPI DLLSERVICE) (LPCSTR, unsigned long); +#endif +typedef int (WINAPI DLLSPLIT) (LPSTR); +typedef int (WINAPI DLLCOMMENT)(LPSTR); + +/* Structures */ + +typedef struct { /* zip options */ +LPSTR Date; /* Date to include after */ +LPSTR szRootDir; /* Directory to use as base for zipping */ +LPSTR szTempDir; /* Temporary directory used during zipping */ +BOOL fTemp; /* Use temporary directory '-b' during zipping */ +BOOL fSuffix; /* include suffixes (not implemented) */ +BOOL fEncrypt; /* encrypt files */ +BOOL fSystem; /* include system and hidden files */ +BOOL fVolume; /* Include volume label */ +BOOL fExtra; /* Exclude extra attributes */ +BOOL fNoDirEntries; /* Do not add directory entries */ +BOOL fExcludeDate; /* Exclude files newer than specified date */ +BOOL fIncludeDate; /* Include only files newer than specified date */ +BOOL fVerbose; /* Mention oddities in zip file structure */ +BOOL fQuiet; /* Quiet operation */ +BOOL fCRLF_LF; /* Translate CR/LF to LF */ +BOOL fLF_CRLF; /* Translate LF to CR/LF */ +BOOL fJunkDir; /* Junk directory names */ +BOOL fGrow; /* Allow appending to a zip file */ +BOOL fForce; /* Make entries using DOS names (k for Katz) */ +BOOL fMove; /* Delete files added or updated in zip file */ +BOOL fDeleteEntries; /* Delete files from zip file */ +BOOL fUpdate; /* Update zip file--overwrite only if newer */ +BOOL fFreshen; /* Freshen zip file--overwrite only */ +BOOL fJunkSFX; /* Junk SFX prefix */ +BOOL fLatestTime; /* Set zip file time to time of latest file in it */ +BOOL fComment; /* Put comment in zip file */ +BOOL fOffsets; /* Update archive offsets for SFX files */ +BOOL fPrivilege; /* Use privileges (WIN32 only) */ +BOOL fEncryption; /* TRUE if encryption supported, else FALSE. + this is a read only flag */ +LPSTR szSplitSize; /* This string contains the size that you want to + split the archive into. i.e. 100 for 100 bytes, + 2K for 2 k bytes, where K is 1024, m for meg + and g for gig. If this string is not NULL it + will automatically be assumed that you wish to + split an archive. */ +LPSTR szIncludeList; /* Pointer to include file list string (for VB) */ +long IncludeListCount; /* Count of file names in the include list array */ +char **IncludeList; /* Pointer to include file list array. Note that the last + entry in the array must be NULL */ +LPSTR szExcludeList; /* Pointer to exclude file list (for VB) */ +long ExcludeListCount; /* Count of file names in the include list array */ +char **ExcludeList; /* Pointer to exclude file list array. Note that the last + entry in the array must be NULL */ +int fRecurse; /* Recurse into subdirectories. 1 => -r, 2 => -R */ +int fRepair; /* Repair archive. 1 => -F, 2 => -FF */ +char fLevel; /* Compression level (0 - 9) */ +} ZPOPT, _far *LPZPOPT; + +typedef struct { + int argc; /* Count of files to zip */ + LPSTR lpszZipFN; /* name of archive to create/update */ + char **FNV; /* array of file names to zip up */ + LPSTR lpszAltFNL; /* pointer to a string containing a list of file + names to zip up, separated by whitespace. Intended + for use only by VB users, all others should set this + to NULL. */ +} ZCL, _far *LPZCL; + +typedef struct { + DLLPRNT *print; + DLLCOMMENT *comment; + DLLPASSWORD *password; + DLLSPLIT *split; /* This MUST be set to NULL unless you want to be queried + for a destination for each split archive. */ +#ifdef ZIP64_SUPPORT + DLLSERVICE *ServiceApplication64; + DLLSERVICE_NO_INT64 *ServiceApplication64_No_Int64; +#else + DLLSERVICE *ServiceApplication; +#endif +} ZIPUSERFUNCTIONS, far * LPZIPUSERFUNCTIONS; + +extern LPZIPUSERFUNCTIONS lpZipUserFunctions; + +void EXPENTRY ZpVersion(ZpVer far *); +int EXPENTRY ZpInit(LPZIPUSERFUNCTIONS lpZipUserFunc); +int EXPENTRY ZpArchive(ZCL C, LPZPOPT Opts); + +#if defined(ZIPLIB) || defined(COM_OBJECT) +# define ydays zp_ydays +#endif + + + +/* Functions not yet supported */ +#if 0 +int EXPENTRY ZpMain (int argc, char **argv); +int EXPENTRY ZpAltMain (int argc, char **argv, ZpInit *init); +#endif +#endif /* WINDLL? || API? */ + +#endif /* _ZIPAPI_H */ diff --git a/atari/Makefile b/atari/Makefile new file mode 100644 index 0000000..2c86196 --- /dev/null +++ b/atari/Makefile @@ -0,0 +1,111 @@ +# Makefile for Zip, ZipNote, ZipCloak and ZipSplit + +MAKE = make +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 +BINDIR = /usr/local/bin +manext=1 +MANDIR = /usr/local/man/man$(manext) + +# 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 +LFLAGS1 = +LFLAGS2 = -s + +# object file lists +OBJZ = zip.o zipfile.o zipup.o fileio.o util.o crc32.o globals.o \ + crypt.o ttyio.o atari.o + +OBJI = deflate.o trees.o +OBJA = +OBJU = zipfile_.o fileio_.o util_.o globals.o atari_.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o $(OBJU) crc32_.o crypt_.o ttyio.o +OBJS = zipsplit.o $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h atari/osdep.h + +# 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 the Zip MANUAL. +$(OBJZ): $(ZIP_H) +$(OBJI): $(ZIP_H) +$(OBJN): $(ZIP_H) +$(OBJS): $(ZIP_H) +$(OBJC): $(ZIP_H) +zip.o crc32.o crypt.o fileio.o zipfile.o zipup.o: crc32.h +zipcloak.o crc32_.o crypt_.o fileio_.o zipfile_.o: crc32.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: atari/zipup.h + +match.o: match.s + $(CPP) match.s > _match.s + $(AS) _match.s + mv _match.o match.o + rm -f _match.s + +ZIPS = zip$E zipnote$E zipsplit$E zipcloak$E + +zips: $(ZIPS) +zipsman: $(ZIPS) $(ZIPMANUAL) + +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) + +dist: $(ZIPMANUAL) + 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` + +# ATARI version (gcc 2.5.8 and Mintlibs PL46) +atari: + $(MAKE) zips CFLAGS="-O -DATARI" OBJA=atari/atari.o CC=gcc E=.ttp + +# clean up after making stuff and installing it +clean: + rm -f *.o $(ZIPS) flags diff --git a/atari/README b/atari/README new file mode 100644 index 0000000..cce4206 --- /dev/null +++ b/atari/README @@ -0,0 +1,5 @@ +From: harry@hal.westfalen.de (Harald Denker) + +The old zip ATARI port is based on TurboC which is no more +supported (for more than 3 years). I used the GNU gcc 2.5.8 and +MiNTlibs PL46. diff --git a/atari/atari.c b/atari/atari.c new file mode 100644 index 0000000..ce5196c --- /dev/null +++ b/atari/atari.c @@ -0,0 +1,681 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#include "zip.h" + +#ifndef UTIL /* the companion #endif is a bit of ways down ... */ + +#include +#include +#include +#include +#include +#include + + +#define PAD 0 +#define PATH_END '/' + +extern char *label; /* defined in fileio.c */ + +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + + +local char *readd(d) +DIR *d; /* directory stream to read from */ +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e; + + e = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; +} + +local char *getVolumeLabel(drive, vtime, vmode, utim) + int drive; /* drive name: 'A' .. 'Z' or '\0' for current drive */ + ulg *vtime; /* volume label creation time (DOS format) */ + ulg *vmode; /* volume label file mode */ + time_t utim;/* volume label creation time (UNIX format) */ + +/* If a volume label exists for the given drive, return its name and + set its time and mode. The returned name must be static data. */ +{ + static char vol[14]; + _DTA *dtaptr; + + if (drive) { + vol[0] = (char)drive; + strcpy(vol+1, ":/"); + } else { + strcpy(vol, "/"); + } + strcat(vol, "*.*"); + if (Fsfirst(vol, FA_LABEL) == 0) { + dtaptr = Fgetdta(); + strncpy(vol, dtaptr->dta_name, sizeof(vol)-1); + *vtime = ((ulg)dtaptr->dta_date << 16) | + ((ulg)dtaptr->dta_time & 0xffff); + *vmode = (ulg)dtaptr->dta_attribute; + return vol; + } + return NULL; +} + +char GetFileMode(char *name) +{ + struct stat sb; + + sb.st_attr = 0; + Fxattr(linkput ? 1 : 0, name, &sb); + if (errno == EINVAL) { + _DTA *dtaptr, *old; + old = Fgetdta(); + Fsfirst(name, FA_RDONLY+FA_HIDDEN+FA_SYSTEM+FA_DIR); + dtaptr = Fgetdta(); + sb.st_attr = dtaptr->dta_attribute; + Fsetdta(old); + } + return sb.st_attr & 0x3f; +} + + +int wild2(w) +char *w; /* path/pattern to match */ +/* If not in exclude mode, expand the pattern based on the contents of the + file system. Return an error code in the ZE_ class. */ +{ + DIR *d; /* stream for reading directory */ + char *e; /* name found in directory */ + int r; /* temporary variable */ + char *n; /* constructed name from directory */ + int f; /* true if there was a match */ + char *a; /* alloc'ed space for name */ + char *p; /* path */ + char *q; /* name */ + char v[5]; /* space for device current directory */ + + if (volume_label == 1) { + volume_label = 2; + label = getVolumeLabel(w[1] == ':' ? to_up(w[0]) : '\0', + &label_time, &label_mode, &label_utim); + if (label != NULL) { + newname(label, 0, 0); + } + if (w[1] == ':' && w[2] == '\0') return ZE_OK; + /* "zip -$ foo a:" can be used to force drive name */ + } + + /* special handling of stdin request */ + if (strcmp(w, "-") == 0) /* if compressing stdin */ + return newname(w, 0, 0); + + /* Allocate and copy pattern */ + if ((p = a = malloc(strlen(w) + 1)) == NULL) + return ZE_MEM; + strcpy(p, w); + + /* Normalize path delimiter as '/'. */ + for (q = p; *q; q++) /* use / consistently */ + if (*q == '\\') + *q = '/'; + + /* Only name can have special matching characters */ + if ((q = isshexp(p)) != NULL && + (strrchr(q, '/') != NULL || strrchr(q, ':') != NULL)) + { + free((zvoid *)a); + return ZE_PARMS; + } + + /* Separate path and name into p and q */ + if ((q = strrchr(p, '/')) != NULL && (q == p || q[-1] != ':')) + { + *q++ = '\0'; /* path/name -> path, name */ + if (*p == '\0') /* path is just / */ + p = strcpy(v, "/."); + } + else if ((q = strrchr(p, ':')) != NULL) + { /* has device and no or root path */ + *q++ = '\0'; + p = strcat(strcpy(v, p), ":"); /* copy device as path */ + if (*q == '/') /* -> device:/., name */ + { + strcat(p, "/"); + q++; + } + strcat(p, "."); + } + else if (recurse && (strcmp(p, ".") == 0 || strcmp(p, "..") == 0)) + { /* current or parent directory */ + /* I can't understand Mark's code so I am adding a hack here to get + * "zip -r foo ." to work. Allow the dubious "zip -r foo .." but + * reject "zip -rm foo ..". + */ + if (dispose && strcmp(p, "..") == 0) + ziperr(ZE_PARMS, "cannot remove parent directory"); + q = "*.*"; + } + else /* no path or device */ + { + q = p; + p = strcpy(v, "."); + } + if (recurse && *q == '\0') { + q = "*.*"; + } + /* Search that level for matching names */ + if ((d = opendir(p)) == NULL) + { + free((zvoid *)a); + return ZE_MISS; + } + if ((r = strlen(p)) > 1 && + (strcmp(p + r - 2, ":.") == 0 || strcmp(p + r - 2, "/.") == 0)) + *(p + r - 1) = '\0'; + f = 0; + while ((e = readd(d)) != NULL) { + if (strcmp(e, ".") && strcmp(e, "..") && MATCH(q, e, 0)) + { + f = 1; + if (strcmp(p, ".") == 0) { /* path is . */ + r = procname(e, 0); /* name is name */ + if (r) { + f = 0; + break; + } + } else + { + if ((n = malloc(strlen(p) + strlen(e) + 2)) == NULL) + { + free((zvoid *)a); + closedir(d); + return ZE_MEM; + } + n = strcpy(n, p); + if (n[r = strlen(n) - 1] != '/' && n[r] != ':') + strcat(n, "/"); + r = procname(strcat(n, e), 0); /* name is path/name */ + free((zvoid *)n); + if (r) { + f = 0; + break; + } + } + } + } + closedir(d); + + /* Done */ + free((zvoid *)a); + return f ? ZE_OK : ZE_MISS; +} + + +#include +#include + +void regerror( char ZCONST *msg ) { + perror( msg ); +} + +static int ret; +static regexp *regptr; +static short is_w, ind_w; +static char fullpath[FILENAME_MAX], file_arg[FILENAME_MAX]; + +#define FTW_F 0 +#define FTW_D 1 +#define FTW_DNR 2 +#define FTW_NS 3 + +static int ftwfunc( struct stat *stats, int ftw_status ) +{ + char *path = &fullpath[0]; + + if (strncmp(path, "./", 2) == 0) path += 2; + switch (ftw_status) { + case FTW_NS: + zipwarn("can't stat file: ", path); + ret = ZE_MISS; + return 0; + case FTW_F: + if (!is_w || regexec(regptr, path, 1)) { +#if 0 + char fn[FILENAME_MAX]; + int k; + if (S_ISLNK(stats->st_mode) && + (k = readlink(path, fn, FILENAME_MAX)) > 0) { + int l = strlen(path); + fn[k] = '\0'; + strcat(strcat(path, " -> "), fn); + ret = newname(path, 0, 0); /* procname(path, 0); */ + path[l] = '\0'; + } else +#endif + ret = newname(path, 0, 0); /* procname(path, 0); */ + } + return 0; + case FTW_DNR: + zipwarn("can't open directory: ", path); + ret = ZE_MISS; + return 0; + case FTW_D: + if (strcmp(path, ".") == 0) return 0; + if (is_w && ind_w > 0 && strncmp(path, file_arg, ind_w) != 0) + return 4; + } + return 0; +} + +static int myftw( int depth ) +{ + register DIR *dirp; + struct dirent *entp; + struct stat stats; + register char *p,*q; + register long i; + + if (LSSTAT(fullpath, &stats) < 0) + return ftwfunc(&stats, FTW_NS); + + if (!S_ISDIR(stats.st_mode)) + return ftwfunc(&stats, FTW_F); + + if ((dirp = opendir(fullpath)) == NULL) + return ftwfunc(&stats, FTW_DNR); + + if (i = ftwfunc(&stats, FTW_D)) { + closedir(dirp); + return (i == 4 ? 0 : (int)i); + } + i = strlen(fullpath); + p = &fullpath[i]; + *p++ = '/'; *p = '\0'; + if (dirnames && i > 1) { + q = (strncmp(fullpath, "./", 2) == 0 ? &fullpath[2] : &fullpath[0]); + ret = newname(q, 1, 0); + } + i = 0; + while (depth > 0 && (entp = readdir(dirp)) != 0) + if (strcmp(entp->d_name,".") != 0 && strcmp(entp->d_name,"..") != 0) { + strcpy(p, entp->d_name); + if (i = myftw(depth-1)) + depth = 0; /* force User's finish */ + } + closedir(dirp); + return (int)i; +} + +int wild( char *p ) +{ + char *d; + + ret = ZE_OK; + if (p == NULL) p = "*"; + + if (strcmp(p, "-") == 0) /* if compressing stdin */ + ret = newname(p, 0, 0); + + strcpy(fullpath, p); + /* now turning UNIX-Wildcards into basic regular expressions */ + for (is_w = ind_w = 0, d = &file_arg[0]; *p; d++, p++) + switch (*p) { + case '*': *d++ = '.'; *d = *p; is_w = 1; break; + case '?': *d = '.'; is_w = 1; break; + case '[': *d = *p; + if (*(p+1) == '!') { + *++d = '^'; p++; + } is_w = 1; break; + case '.': *d++ = '\\'; *d = *p; break; + default : *d = *p; + if (!is_w) ind_w++; + } + *++d = '\0'; + if (is_w) { + strcat( file_arg, "$" ); /* to get things like *.[ch] work */ + if ((regptr = regcomp( file_arg )) == NULL) + return ZE_MEM; + strcpy( fullpath, "." ); + myftw( recurse ? 99 : 1 ); + free(regptr); + } else if (recurse) { + myftw( 99 ); + } else + myftw( 1 ); /* ret = procname( fullpath, 0 ); */ + return ret; +} + +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 */ + for (p = n; *p; p++) /* use / consistently */ + if (*p == '\\') + *p = '/'; + if (!S_ISDIR(s.st_mode)) + { + /* 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, *p; /* shortened name */ + int dosflag; + + dosflag = 0; + + /* Find starting point in name before doing malloc */ + t = *x && *(x + 1) == ':' ? x + 2 : x; + while (*t == '/' || *t == '\\') + t++; + + /* Make changes, if any, to the copied name (leave original intact) */ + for (n = t; *n; n++) + if (*n == '\\') + *n = '/'; + + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); +#if 0 + if (p = strstr(t, " -> ")) /* shorten "link -> data" to "link" */ + *p = '\0'; +#endif + if (dosify) + msname(n); + + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + return n; +} + + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + return x; +} + +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ + struct utimbuf u; /* argument for utime() const ?? */ + + /* Convert DOS time to time_t format in u[0] and u[1] */ + u.actime = u.modtime = dos2unixtime(d); + + /* Set updated and accessed times of f */ + utime(f, &u); +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + /* convert FNMAX to malloc - 11/8/04 EG */ + char *name; + int len = strlen(f); + + if (f == label) { + if (a != NULL) + *a = label_mode; + if (n != NULL) + *n = -2L; /* convention for a label name */ + if (t != NULL) + t->atime = t->mtime = t->ctime = label_utim; + return label_time; + } + if ((name = malloc(len + 1)) == NULL) { + ZIPERR(ZE_MEM, "filetime"); + } + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + + if (strcmp(f, "-") == 0) { + if (fstat(fileno(stdin), &s) != 0) { + 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) | (ulg)GetFileMode(name); */ + *a = ((ulg)s.st_mode << 16) | (ulg)s.st_attr; + } + free(name); + if (n != NULL) + *n = S_ISREG(s.st_mode) ? s.st_size : -1L; + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_ctime; + } + + return unix2dostime(&s.st_mtime); +} + +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; + /* create extra field and change z->att if desired */ +{ +#ifdef USE_EF_UT_TIME +#ifdef IZ_CHECK_TZ + if (!zp_tz_is_valid) return ZE_OK; /* skip silently if no valid TZ info */ +#endif + + if ((z->extra = (char *)malloc(EB_HEADSIZE+EB_UT_LEN(2))) == NULL) + return ZE_MEM; + if ((z->cextra = (char *)malloc(EB_HEADSIZE+EB_UT_LEN(1))) == NULL) + return ZE_MEM; + + z->extra[0] = 'U'; + z->extra[1] = 'T'; + z->extra[2] = EB_UT_LEN(2); /* length of data part of e.f. */ + z->extra[3] = 0; + z->extra[4] = EB_UT_FL_MTIME | EB_UT_FL_ATIME; + z->extra[5] = (char)(z_utim->mtime); + z->extra[6] = (char)(z_utim->mtime >> 8); + z->extra[7] = (char)(z_utim->mtime >> 16); + z->extra[8] = (char)(z_utim->mtime >> 24); + z->extra[9] = (char)(z_utim->atime); + z->extra[10] = (char)(z_utim->atime >> 8); + z->extra[11] = (char)(z_utim->atime >> 16); + z->extra[12] = (char)(z_utim->atime >> 24); + + z->ext = (EB_HEADSIZE+EB_UX_LEN(2)); + + memcpy(z->cextra, z->extra, (EB_HEADSIZE+EB_UT_LEN(1))); + z->cextra[EB_LEN] = EB_UT_LEN(1); + z->cext = (EB_HEADSIZE+EB_UX_LEN(1)); + + return ZE_OK; +#else /* !USE_EF_UT_TIME */ + return (int)(z-z); +#endif /* ?USE_EF_UT_TIME */ +} + +int deletedir(d) +char *d; /* directory to delete */ +/* Delete the directory *d if it is empty, do nothing otherwise. + Return the result of rmdir(), delete(), or system(). + For VMS, d must be in format [x.y]z.dir;1 (not [x.y.z]). + */ +{ + return rmdir(d); +} + +#endif /* !UTIL */ + + +/******************************/ +/* Function version_local() */ +/******************************/ + +void version_local() +{ + static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n"; +#ifdef __TURBOC__ + char buf[40]; +#endif + + printf(CompiledWith, + +#ifdef __GNUC__ + "gcc ", __VERSION__, +#else +# if 0 + "cc ", (sprintf(buf, " version %d", _RELEASE), buf), +# else +# ifdef __TURBOC__ + "Turbo C", (sprintf(buf, " (0x%04x = %d)", __TURBOC__, __TURBOC__), buf), +# else + "unknown compiler", "", +# endif +# endif +#endif + +#ifdef __MINT__ + "Atari TOS/MiNT", +#else + "Atari TOS", +#endif + + " (Atari ST/TT/Falcon030)", + +#ifdef __DATE__ + " on ", __DATE__ +#else + "", "" +#endif + ); + +} /* end function version_local() */ diff --git a/atari/make_all.mup b/atari/make_all.mup new file mode 100644 index 0000000..5f8c4dc --- /dev/null +++ b/atari/make_all.mup @@ -0,0 +1,7 @@ +rm -f *.o *.sym *.ttp +make370 SHELL=/bin/mupfel.ttp CC=gcc CFLAGS="-O -DATARI" E=.ttp OBJA=atari.o zips +#make370 SHELL=/bin/mupfel.ttp CC=gcc CFLAGS="-g -D__NO_INLINE__ -DATARI" E=.ttp OBJA=atari.o zip.ttp +#make370 SHELL=/bin/mupfel.ttp CC=gcc CFLAGS="-g -D__NO_INLINE__ -DATARI" E=.sym OBJA=atari.o zip.sym LFLAGS2="-B/bin/sym-" +#make370 SHELL=/bin/mupfel.ttp CC=gcc CFLAGS="-O -DATARI" E=.ttp OBJA=atari.o -n zips > make_all.mup +#fixstk 32K pgp.ttp +prgflags 017 007 *.ttp diff --git a/atari/make_zip.mup b/atari/make_zip.mup new file mode 100644 index 0000000..4ea4c31 --- /dev/null +++ b/atari/make_zip.mup @@ -0,0 +1,7 @@ +#rm -f *.o *.sym *.ttp +#make370 SHELL=/bin/mupfel.ttp CC=gcc CFLAGS="-O -DATARI" E=.ttp OBJA=atari.o zips +make370 SHELL=/bin/mupfel.ttp CC=gcc CFLAGS="-g -D__NO_INLINE__ -DATARI" E=.ttp OBJA=atari.o zip.ttp +make370 SHELL=/bin/mupfel.ttp CC=gcc CFLAGS="-g -D__NO_INLINE__ -DATARI" E=.sym OBJA=atari.o zip.sym LFLAGS2="-B/bin/sym-" +#make370 SHELL=/bin/mupfel.ttp CC=gcc CFLAGS="-O -DATARI" E=.ttp OBJA=atari.o -n zips > make_all.mup +#fixstk 32K pgp.ttp +prgflags 017 007 *.ttp diff --git a/atari/osdep.h b/atari/osdep.h new file mode 100644 index 0000000..46387b6 --- /dev/null +++ b/atari/osdep.h @@ -0,0 +1,20 @@ +/* + 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 FOPR "rb" +#define FOPM "r+b" +#define FOPW "wb" + +#define DIRENT +#define NO_TERMIO +#define USE_CASE_MAP +#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \ + procname(n, 1)) + +#include +#include diff --git a/atari/zipup.h b/atari/zipup.h new file mode 100644 index 0000000..1de3f61 --- /dev/null +++ b/atari/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 diff --git a/atheos/Makefile b/atheos/Makefile new file mode 100644 index 0000000..91df1c8 --- /dev/null +++ b/atheos/Makefile @@ -0,0 +1,146 @@ +###################################################################### +# +# Makefile for Info-ZIP's zip, zipcloak, zipnote, and zipsplit on AtheOS +# +# Copyright (C) 1999-2007 Info-ZIP +# Chris Herborth (chrish@pobox.com) +# Ruslan Nickolaev (nruslan@hotbox.ru) +# +###################################################################### +# Things that don't change: + +# Punish people who don't have SMP hardware. +MAKE = make -j 4 -f atheos/Makefile +SHELL = /bin/sh + +LN = ln -s +RM = rm -f + +BIND = $(CC) +AS = as + +INSTALL = install + +# Target directories +prefix = /usr +BINDIR = $(prefix)/bin +manext = 1 +MANDIR = $(prefix)/man/man$(manext) +ZIPMANUAL = MANUAL + +VERSION = Version 2.3 of __DATE__ + +###################################################################### + +CC:=gcc +CFLAGS:=-O3 -march=i586 -Wall -I. -DHAVE_DIRENT_H -DPASSWD_FROM_STDIN -DASMV -DASM_CRC +LFLAGS1:= +LFLAGS2:= +TARGET=$(ZIPS) + +###################################################################### +# Helpful targets +all: + $(MAKE) CC=$(CC) CFLAGS="$(CFLAGS)" \ + LFLAGS1="$(LFLAGS1)" LFLAGS2="$(LFLAGS2)" \ + $(TARGET) + +###################################################################### +# Object file lists and other build goodies + +# Object file lists +OBJZ = zip.o zipfile.o zipup.o fileio.o util.o globals.o crc32.o crypt.o \ + ttyio.o atheos.o +OBJI = deflate.o trees.o +OBJA = match.o crc_i386.o +OBJU = zipfile_.o fileio_.o util_.o globals.o atheos_.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o $(OBJU) crc32_.o crypt_.o ttyio.o +OBJS = zipsplit.o $(OBJU) + +# Headers +ZIP_H = zip.h ziperr.h tailor.h atheos/osdep.h + +# What to build? +ZIPS = zip zipnote zipsplit zipcloak + +# suffix rules +.SUFFIXES: +.SUFFIXES: _.o .o .c .doc .1 +.c_.o: + $(RM) $*_.c; $(LN) $< $*_.c + $(CC) -c $(CFLAGS) -DUTIL $*_.c + $(RM) $*_.c + +.c.o: + $(CC) -c $(CFLAGS) $< + +.1.doc: + groff -man -Tascii $< > $@ + +# 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 crc32.o crypt.o fileio.o zipfile.o zipup.o: crc32.h +zipcloak.o crc32_.o crypt_.o fileio_.o zipfile_.o: crc32.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: atheos/zipup.h + +match.o: match.S + $(CC) -E match.S > matchs.s + $(AS) -o $@ matchs.s + $(RM) matchs.s + +crc_i386.o: crc_i386.S + $(CC) -E crc_i386.S > crc_i386s.s + $(AS) -o $@ crc_i386s.s + $(RM) crc_i386s.s + +atheos.o: atheos/atheos.c + $(CC) -c $(CFLAGS) atheos/atheos.c + +atheos_.o: atheos/atheos.c + $(RM) $*_.c; $(LN) atheos/atheos.c $*_.c + $(CC) -c $(CFLAGS) -DUTIL $*_.c + $(RM) $*_.c + +zips: $(ZIPS) +zipsman: $(ZIPS) $(ZIPMANUAL) + +zip: $(OBJZ) $(OBJI) $(OBJA) + $(BIND) -o zip $(LFLAGS1) $(OBJZ) $(OBJI) $(OBJA) $(LFLAGS2) +zipnote: $(OBJN) + $(BIND) -o zipnote $(LFLAGS1) $(OBJN) $(LFLAGS2) +zipcloak: $(OBJC) + $(BIND) -o zipcloak $(LFLAGS1) $(OBJC) $(LFLAGS2) +zipsplit: $(OBJS) + $(BIND) -o zipsplit $(LFLAGS1) $(OBJS) $(LFLAGS2) + +$(ZIPMANUAL): man/zip.1 + groff -man -Tascii man/zip.1 > $(ZIPMANUAL) + +# install +install: $(ZIPS) + $(INSTALL) -m755 $(ZIPS) $(BINDIR) + mkdir -p $(MANDIR) + $(INSTALL) -m644 man/zip.1 $(MANDIR)/zip.$(manext) + +uninstall: + -cd $(BINDIR); $(RM) $(ZIPS) + -cd $(MANDIR); $(RM) zip.$(manext) + +dist: $(ZIPMANUAL) + 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` + +# clean up after making stuff and installing it +clean: + $(RM) *.o $(ZIPS) flags + +# end of Makefile diff --git a/atheos/README b/atheos/README new file mode 100644 index 0000000..a96fffc --- /dev/null +++ b/atheos/README @@ -0,0 +1,21 @@ +Info-ZIP's zip for AtheOS/Syllable + +FEATURES + stores AtheOS/Syllable file attributes, compressing them if possible + +TODO +---- +There is only one thing to be fixed: + write_attr() should return count of writed bytes. However that's bug related with AFS only. + +Please report any bugs to Info-ZIP at www.info-zip.org. +If this bug related with AtheOS/Syllable only, you can mail me directly: nruslan@hotbox.ru. + +Visit the Info-ZIP web site (http://www.info-zip.org) for all the +latest zip and unzip information, FAQs, source code and ready-to-run +executables. + +- Ruslan Nickolaev (nruslan@hotbox.ru) + Sep 06/2004 + +(updated 12 November 2004) diff --git a/atheos/atheos.c b/atheos/atheos.c new file mode 100644 index 0000000..6f1c915 --- /dev/null +++ b/atheos/atheos.c @@ -0,0 +1,885 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html + + This AtheOS - specific file is based on unix.c and beos.c; + changes by Ruslan Nickolaev (nruslan@hotbox.ru) +*/ + +#include "zip.h" + +#ifndef UTIL /* the companion #endif is a bit of ways down ... */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define PAD 0 +#define PATH_END '/' + +/* Library functions not in (most) header files */ + +#ifdef _POSIX_VERSION +# include +#else + int utime OF((char *, time_t *)); +#endif + +extern char *label; +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +/* Local functions */ +local char *readd OF((DIR *)); +local int get_attr_dir( const char *, char **, off_t * ); +local int add_UT_ef( struct zlist far * ); +local int add_Ux_ef( struct zlist far * ); +local int add_At_ef( struct zlist far * ); + +local char *readd(d) +DIR *d; /* directory stream to read from */ +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e; + + e = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; +} + +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_IFREG) == S_IFREG || + (s.st_mode & S_IFLNK) == S_IFLNK) + { + /* add or remove name of file */ + if ((m = newname(n, 0, caseflag)) != ZE_OK) + return m; + } + else if ((s.st_mode & S_IFDIR) == S_IFDIR) + { + /* 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) */ + else + zipwarn("ignoring special file: ", n); + 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 = NULL; /* shortened name */ + int dosflag; + + dosflag = dosify; /* default for non-DOS and non-OS/2 */ + + /* Find starting point in name before doing malloc */ + /* Strip "//host/share/" part of a UNC name */ + if (!strncmp(x,"//",2) && (x[2] != '\0' && x[2] != '/')) { + n = x + 2; + while (*n != '\0' && *n != '/') + n++; /* strip host name */ + if (*n != '\0') { + n++; + while (*n != '\0' && *n != '/') + n++; /* strip `share' name */ + } + if (*n != '\0') + t = n + 1; + } else + t = x; + while (*t == '/') + t++; /* strip leading '/' chars to get a relative path */ + while (*t == '.' && t[1] == '/') + t += 2; /* strip redundant leading "./" sections */ + + /* Make changes, if any, to the copied name (leave original intact) */ + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + + if (isdir == 42) return n; /* avoid warning on unused variable */ + + if (dosify) + msname(n); + + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + return n; +} + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + return x; +} + +/* + * XXX use ztimbuf in both POSIX and non POSIX cases ? + */ +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ +#ifdef _POSIX_VERSION + struct utimbuf u; /* argument for utime() const ?? */ +#else + time_t u[2]; /* argument for utime() */ +#endif + + /* Convert DOS time to time_t format in u */ +#ifdef _POSIX_VERSION + u.actime = u.modtime = dos2unixtime(d); + utime(f, &u); +#else + u[0] = u[1] = dos2unixtime(d); + utime(f, u); +#endif + +} + +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; + int len = strlen(f); + + if (f == label) { + if (a != NULL) + *a = label_mode; + if (n != NULL) + *n = -2L; /* convention for a label name */ + if (t != NULL) + t->atime = t->mtime = t->ctime = label_utim; + return label_time; + } + if ((name = malloc(len + 1)) == NULL { + ZIPERR(ZE_MEM, "filetime"); + } + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + if (strcmp(f, "-") == 0) { + if (fstat(fileno(stdin), &s) != 0) { + 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; + } + free(name); + + if (a != NULL) { +#ifndef OS390 + *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE); +#else +/* +** The following defines are copied from the unizip source and represent the +** legacy Unix mode flags. These fixed bit masks are no longer required +** by XOPEN standards - the S_IS### macros being the new recommended method. +** The approach here of setting the legacy flags by testing the macros should +** work under any _XOPEN_SOURCE environment (and will just rebuild the same bit +** mask), but is required if the legacy bit flags differ from legacy Unix. +*/ +#define UNX_IFDIR 0040000 /* Unix directory */ +#define UNX_IFREG 0100000 /* Unix regular file */ +#define UNX_IFSOCK 0140000 /* Unix socket (BSD, not SysV or Amiga) */ +#define UNX_IFLNK 0120000 /* Unix symbolic link (not SysV, Amiga) */ +#define UNX_IFBLK 0060000 /* Unix block special (not Amiga) */ +#define UNX_IFCHR 0020000 /* Unix character special (not Amiga) */ +#define UNX_IFIFO 0010000 /* Unix fifo (BCC, not MSC or Amiga) */ + { + mode_t legacy_modes; + + /* Initialize with permission bits - which are not implementation optional */ + legacy_modes = s.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX); + if (S_ISDIR(s.st_mode)) + legacy_modes |= UNX_IFDIR; + if (S_ISREG(s.st_mode)) + legacy_modes |= UNX_IFREG; + if (S_ISLNK(s.st_mode)) + legacy_modes |= UNX_IFLNK; + if (S_ISBLK(s.st_mode)) + legacy_modes |= UNX_IFBLK; + if (S_ISCHR(s.st_mode)) + legacy_modes |= UNX_IFCHR; + if (S_ISFIFO(s.st_mode)) + legacy_modes |= UNX_IFIFO; + if (S_ISSOCK(s.st_mode)) + legacy_modes |= UNX_IFSOCK; + *a = ((ulg)legacy_modes << 16) | !(s.st_mode & S_IWRITE); + } +#endif + 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 = t->mtime; /* best guess, (s.st_ctime: last status change!!) */ + } + return unix2dostime(&s.st_mtime); +} + +/* ---------------------------------------------------------------------- + +Return a malloc()'d buffer containing all of the attributes and their names +for the file specified in name. You have to free() this yourself. The length +of the buffer is also returned. + +If get_attr_dir() fails, the buffer will be NULL, total_size will be 0, +and an error will be returned: + + EOK - no errors occurred + EINVAL - attr_buff was pointing at a buffer + ENOMEM - insufficient memory for attribute buffer + +Other errors are possible (whatever is returned by the fs_attrib.h functions). + +PROBLEMS: + +- pointers are 32-bits; attributes are limited to ssize_t in size so it's + possible to overflow... in practice, this isn't too likely... your + machine will thrash like hell before that happens + +*/ + +#define INITIAL_BUFF_SIZE 65536 + +int get_attr_dir( const char *name, char **attr_buff, off_t *total_size ) +{ + int retval = EOK; + int fd; + DIR *fa_dir; + struct dirent *fa_ent; + off_t attrs_size = 0; + size_t entname_size; + char *ptr; + struct attr_info fa_info; + + *total_size = 0; + + /* ----------------------------------------------------------------- */ + /* Sanity-check. */ + if( *attr_buff != NULL ) { + return EINVAL; + } + + /* ----------------------------------------------------------------- */ + /* Can we open the file/directory? */ + /* */ + /* linkput is a zip global; it's set to 1 if we're storing symbolic */ + /* links as symbolic links (instead of storing the thing the link */ + /* points to)... if we're storing the symbolic link as a link, we'll */ + /* want the link's file attributes, otherwise we want the target's. */ + + fd = open( name, linkput ? O_RDONLY | O_NOTRAVERSE : O_RDONLY ); + if( fd < 0 ) { + return errno; + } + + /* ----------------------------------------------------------------- */ + /* Allocate an initial buffer; 64k should usually be enough. */ + *attr_buff = (char *)malloc( INITIAL_BUFF_SIZE ); + ptr = *attr_buff; + if( ptr == NULL ) { + close( fd ); + + return ENOMEM; + } + + /* ----------------------------------------------------------------- */ + /* Open the attributes directory for this file. */ + fa_dir = open_attrdir( fd ); + if( fa_dir == NULL ) { + close( fd ); + + free( ptr ); + *attr_buff = NULL; + + return retval; + } + + /* ----------------------------------------------------------------- */ + /* Read all the attributes; the buffer could grow > 64K if there are */ + /* many and/or they are large. */ + while( ( fa_ent = read_attrdir( fa_dir ) ) != NULL ) { + retval = stat_attr( fd, fa_ent->d_name, &fa_info ); + /* TODO: check retval != EOK */ + + entname_size = strlen( fa_ent->d_name ) + 1; + attrs_size += entname_size + sizeof( struct attr_info ) + fa_info.ai_size; + + if( attrs_size > INITIAL_BUFF_SIZE ) { + unsigned long offset = ptr - *attr_buff; + + *attr_buff = (char *)realloc( *attr_buff, attrs_size ); + if( *attr_buff == NULL ) { + retval = close_attrdir( fa_dir ); + /* TODO: check retval != EOK */ + close( fd ); + return ENOMEM; + } + + ptr = *attr_buff + offset; + } + + /* Now copy the data for this attribute into the buffer. */ + strcpy( ptr, fa_ent->d_name ); + ptr += entname_size; + + memcpy( ptr, &fa_info, sizeof( struct attr_info ) ); + ptr += sizeof( struct attr_info ); + + if( fa_info.ai_size > 0 ) { + ssize_t read_bytes = read_attr( fd, fa_ent->d_name, fa_info.ai_type, ptr, 0, fa_info.ai_size ); + if( read_bytes != fa_info.ai_size ) { + /* print a warning about mismatched sizes */ + char buff[80]; + sprintf( buff, "read %d, expected %d", read_bytes, (ssize_t)fa_info.ai_size ); + zipwarn( "attribute size mismatch: ", buff ); + } + + ptr += fa_info.ai_size; + } + } + + /* ----------------------------------------------------------------- */ + /* Close the attribute directory. */ + retval = close_attrdir( fa_dir ); + /* TODO: check retval != EOK */ + + /* ----------------------------------------------------------------- */ + /* If the buffer is too big, shrink it. */ + if( attrs_size < INITIAL_BUFF_SIZE ) { + *attr_buff = (char *)realloc( *attr_buff, attrs_size ); + if( *attr_buff == NULL ) { + close( fd ); + return ENOMEM; + } + } + + *total_size = attrs_size; + + close( fd ); + + return EOK; +} + +/* ---------------------------------------------------------------------- */ +/* Add a 'UT' extra field to the zlist data pointed to by z. */ + +#define EB_L_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(2)) +#define EB_C_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(1)) + +local int add_UT_ef( struct zlist far *z ) +{ + char *l_ef = NULL; + char *c_ef = NULL; + struct stat s; + +#ifdef IZ_CHECK_TZ + if (!zp_tz_is_valid) + return ZE_OK; /* skip silently if no valid TZ info */ +#endif + + /* We can't work if there's no entry to work on. */ + if( z == NULL ) { + return ZE_LOGIC; + } + + /* Check to make sure we've got enough room in the extra fields. */ + if( z->ext + EB_L_UT_SIZE > USHRT_MAX || + z->cext + EB_C_UT_SIZE > USHRT_MAX ) { + return ZE_MEM; + } + + /* stat() the file (or the symlink) to get the data; if we can't get */ + /* the data, there's no point in trying to fill out the fields. */ + if(LSSTAT( z->name, &s ) ) { + return ZE_OPEN; + } + + /* Allocate memory for the local and central extra fields. */ + if( z->extra && z->ext != 0 ) { + l_ef = (char *)realloc( z->extra, z->ext + EB_L_UT_SIZE ); + } else { + l_ef = (char *)malloc( EB_L_UT_SIZE ); + z->ext = 0; + } + if( l_ef == NULL ) { + return ZE_MEM; + } + z->extra = l_ef; + l_ef += z->ext; + + if( z->cextra && z->cext != 0 ) { + c_ef = (char *)realloc( z->cextra, z->cext + EB_C_UT_SIZE ); + } else { + c_ef = (char *)malloc( EB_C_UT_SIZE ); + z->cext = 0; + } + if( c_ef == NULL ) { + return ZE_MEM; + } + z->cextra = c_ef; + c_ef += z->cext; + + /* Now add the local version of the field. */ + *l_ef++ = 'U'; + *l_ef++ = 'T'; + *l_ef++ = (char)(EB_UT_LEN(2)); /* length of data in local EF */ + *l_ef++ = (char)0; + *l_ef++ = (char)(EB_UT_FL_MTIME | EB_UT_FL_ATIME); + *l_ef++ = (char)(s.st_mtime); + *l_ef++ = (char)(s.st_mtime >> 8); + *l_ef++ = (char)(s.st_mtime >> 16); + *l_ef++ = (char)(s.st_mtime >> 24); + *l_ef++ = (char)(s.st_atime); + *l_ef++ = (char)(s.st_atime >> 8); + *l_ef++ = (char)(s.st_atime >> 16); + *l_ef++ = (char)(s.st_atime >> 24); + + z->ext += EB_L_UT_SIZE; + + /* Now add the central version. */ + memcpy(c_ef, l_ef-EB_L_UT_SIZE, EB_C_UT_SIZE); + c_ef[EB_LEN] = (char)(EB_UT_LEN(1)); /* length of data in central EF */ + + z->cext += EB_C_UT_SIZE; + + return ZE_OK; +} + +/* ---------------------------------------------------------------------- */ +/* Add a 'Ux' extra field to the zlist data pointed to by z. */ + +#define EB_L_UX2_SIZE (EB_HEADSIZE + EB_UX2_MINLEN) +#define EB_C_UX2_SIZE (EB_HEADSIZE) + +local int add_Ux_ef( struct zlist far *z ) +{ + char *l_ef = NULL; + char *c_ef = NULL; + struct stat s; + + /* Check to make sure we've got enough room in the extra fields. */ + if( z->ext + EB_L_UX2_SIZE > USHRT_MAX || + z->cext + EB_C_UX2_SIZE > USHRT_MAX ) { + return ZE_MEM; + } + + /* stat() the file (or the symlink) to get the data; if we can't get */ + /* the data, there's no point in trying to fill out the fields. */ + if(LSSTAT( z->name, &s ) ) { + return ZE_OPEN; + } + + /* Allocate memory for the local and central extra fields. */ + if( z->extra && z->ext != 0 ) { + l_ef = (char *)realloc( z->extra, z->ext + EB_L_UX2_SIZE ); + } else { + l_ef = (char *)malloc( EB_L_UX2_SIZE ); + z->ext = 0; + } + if( l_ef == NULL ) { + return ZE_MEM; + } + z->extra = l_ef; + l_ef += z->ext; + + if( z->cextra && z->cext != 0 ) { + c_ef = (char *)realloc( z->cextra, z->cext + EB_C_UX2_SIZE ); + } else { + c_ef = (char *)malloc( EB_C_UX2_SIZE ); + z->cext = 0; + } + if( c_ef == NULL ) { + return ZE_MEM; + } + z->cextra = c_ef; + c_ef += z->cext; + + /* Now add the local version of the field. */ + *l_ef++ = 'U'; + *l_ef++ = 'x'; + *l_ef++ = (char)(EB_UX2_MINLEN); + *l_ef++ = (char)(EB_UX2_MINLEN >> 8); + *l_ef++ = (char)(s.st_uid); + *l_ef++ = (char)(s.st_uid >> 8); + *l_ef++ = (char)(s.st_gid); + *l_ef++ = (char)(s.st_gid >> 8); + + z->ext += EB_L_UX2_SIZE; + + /* Now add the central version of the field. */ + *c_ef++ = 'U'; + *c_ef++ = 'x'; + *c_ef++ = 0; + *c_ef++ = 0; + + z->cext += EB_C_UX2_SIZE; + + return ZE_OK; +} + +/* ---------------------------------------------------------------------- */ +/* Add a 'At' extra field to the zlist data pointed to by z. */ + +#define EB_L_AT_SIZE (EB_HEADSIZE + EB_L_AT_LEN) /* + attr size */ +#define EB_C_AT_SIZE (EB_HEADSIZE + EB_C_AT_LEN) + +#define MEMCOMPRESS_HEADER 6 /* ush compression type, ulg CRC */ +#define DEFLAT_WORSTCASE_ADD 5 /* byte blocktype, 2 * ush blocklength */ +#define MEMCOMPRESS_OVERHEAD (MEMCOMPRESS_HEADER + DEFLAT_WORSTCASE_ADD) + +local int add_At_ef( struct zlist far *z ) +{ + char *l_ef = NULL; + char *c_ef = NULL; + char *attrbuff = NULL; + off_t attrsize = 0; + char *compbuff = NULL; + ush compsize = 0; + uch flags = 0; + + /* Check to make sure we've got enough room in the extra fields. */ + if( z->ext + EB_L_AT_SIZE > USHRT_MAX || + z->cext + EB_C_AT_SIZE > USHRT_MAX ) { + return ZE_MEM; + } + + /* Attempt to load up a buffer full of the file's attributes. */ + { + if (get_attr_dir( z->name, &attrbuff, &attrsize) != EOK ) { + return ZE_OPEN; + } + if (attrsize == 0) { + return ZE_OK; + } + if (attrbuff == NULL) { + return ZE_LOGIC; + } + + /* Check for way too much data. */ + if (attrsize > (off_t)ULONG_MAX) { + zipwarn( "uncompressed attributes truncated", "" ); + attrsize = (off_t)(ULONG_MAX - MEMCOMPRESS_OVERHEAD); + } + } + + if (verbose) { + printf( "\t[in=%lu]", (unsigned long)attrsize ); + } + + /* Try compressing the data */ + compbuff = (char *)malloc( (size_t)attrsize + MEMCOMPRESS_OVERHEAD ); + if( compbuff == NULL ) { + return ZE_MEM; + } + compsize = memcompress( compbuff, + (size_t)attrsize + MEMCOMPRESS_OVERHEAD, + attrbuff, + (size_t)attrsize ); + if (verbose) { + printf( " [out=%u]", compsize ); + } + + /* Attempt to optimise very small attributes. */ + if (compsize > attrsize) { + free( compbuff ); + compsize = (ush)attrsize; + compbuff = attrbuff; + + flags = EB_AT_FL_NATURAL; + } + + /* Check to see if we really have enough room in the EF for the data. */ + if( ( z->ext + compsize + EB_L_AT_LEN ) > USHRT_MAX ) { + compsize = USHRT_MAX - EB_L_AT_LEN - z->ext; + } + + /* Allocate memory for the local and central extra fields. */ + if( z->extra && z->ext != 0 ) { + l_ef = (char *)realloc( z->extra, z->ext + EB_L_AT_SIZE + compsize ); + } else { + l_ef = (char *)malloc( EB_L_AT_SIZE + compsize ); + z->ext = 0; + } + if( l_ef == NULL ) { + return ZE_MEM; + } + z->extra = l_ef; + l_ef += z->ext; + + if( z->cextra && z->cext != 0 ) { + c_ef = (char *)realloc( z->cextra, z->cext + EB_C_AT_SIZE ); + } else { + c_ef = (char *)malloc( EB_C_AT_SIZE ); + z->cext = 0; + } + if( c_ef == NULL ) { + return ZE_MEM; + } + z->cextra = c_ef; + c_ef += z->cext; + + /* Now add the local version of the field. */ + *l_ef++ = 'A'; + *l_ef++ = 't'; + *l_ef++ = (char)(compsize + EB_L_AT_LEN); + *l_ef++ = (char)((compsize + EB_L_AT_LEN) >> 8); + *l_ef++ = (char)((unsigned long)attrsize); + *l_ef++ = (char)((unsigned long)attrsize >> 8); + *l_ef++ = (char)((unsigned long)attrsize >> 16); + *l_ef++ = (char)((unsigned long)attrsize >> 24); + *l_ef++ = flags; + memcpy( l_ef, compbuff, (size_t)compsize ); + + z->ext += EB_L_AT_SIZE + compsize; + + /* And the central version. */ + *c_ef++ = 'A'; + *c_ef++ = 't'; + *c_ef++ = (char)(EB_C_AT_LEN); + *c_ef++ = (char)(EB_C_AT_LEN >> 8); + *c_ef++ = (char)compsize; + *c_ef++ = (char)(compsize >> 8); + *c_ef++ = (char)(compsize >> 16); + *c_ef++ = (char)(compsize >> 24); + *c_ef++ = flags; + + z->cext += EB_C_AT_SIZE; + + return ZE_OK; +} + +/* Extra field info: + - 'UT' - UNIX time extra field + - 'Ux' - UNIX uid/gid extra field + - 'At' - AtheOS file attributes extra field + + This is done the same way ../unix/unix.c stores the 'UT'/'Ux' fields + (full data in local header, only modification time in central header), + with the 'At' field added to the end and the size of the 'At' field + in the central header. + + See the end of atheos/osdep.h for a simple explanation of the 'At' EF + layout. + */ +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; + /* store full data in local header but just modification time stamp info + in central header */ +{ + int retval; + + /* Check to make sure z is valid. */ + if( z == NULL ) { + return ZE_LOGIC; + } + + retval = add_UT_ef(z); + if( retval != ZE_OK ) { + return retval; + } + + retval = add_Ux_ef(z); + if( retval != ZE_OK ) { + return retval; + } + + return add_At_ef(z); /* last function; we can use return value directly */ +} + +/* ---------------------------------------------------------------------- */ +/* Set a file's MIME type. */ +void setfiletype(const char *file, const char *type) +{ + int fd; + off_t nLen; + ssize_t nError; + + fd = open( file, O_RDWR ); + + if (fd < 0) { + zipwarn( "can't open zipfile to write file type", "" ); + } + + else + { + nLen = strlen( type ); + /* FIXME: write_attr() should return count of writed bytes */ + nError = write_attr( fd, "os::MimeType", O_TRUNC, ATTR_TYPE_STRING, type, 0, nLen ); + if (nError < 0) { + zipwarn( "couldn't write complete file type", "" ); + } + close( fd ); + } +} + +#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 + "(unknown compiler)", "", +#endif + + "Syllable", + +#if defined(i486) || defined(__i486) || defined(__i486__) || defined(i386) || defined(__i386) || defined(__i386__) + " (x86)", +#else + " (unknown platform)", +#endif + +#ifdef __DATE__ + " on ", __DATE__ +#else + "", "" +#endif + ); + +} /* end function version_local() */ diff --git a/atheos/osdep.h b/atheos/osdep.h new file mode 100644 index 0000000..0869f94 --- /dev/null +++ b/atheos/osdep.h @@ -0,0 +1,64 @@ +/* + 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 _OSDEP_H_ +#define _OSDEP_H_ + +#include +#include +#include + +#define USE_EF_UT_TIME /* Enable use of "UT" extra field time info */ + +#define EB_L_AT_LEN 5 /* min size is an unsigned long and flag */ +#define EB_C_AT_LEN 5 /* Length of data in local EF and flag. */ + +#define EB_AT_FL_NATURAL 0x01 /* data is 'natural' (not compressed) */ +#define EB_AT_FL_BADBITS 0xfe /* bits currently undefined */ + +#ifndef ZP_NEED_MEMCOMPR + define ZP_NEED_MEMCOMPR +#endif + +#define deletedir(d) rmdir(d); + +/* Set a file's MIME type. */ +void setfiletype( const char *file, const char *type ); + +/* +'At' extra-field layout: + +'At' - signature +ef_size - size of data in this EF (little-endian unsigned short) +full_size - uncompressed data size (little-endian unsigned long) +flag - flags (byte) + flags & EB_AT_FL_NATURAL = the data is not compressed + flags & EB_AT_FL_BADBITS = the data is corrupted or we + can't handle it properly +data - compressed or uncompressed file attribute data + +If flag & EB_AT_FL_NATURAL, the data is not compressed; this optimisation is +necessary to prevent wasted space for files with small attributes. In this +case, there should be ( ef_size - EB_L_AT_LEN ) bytes of data, and full_size +should equal ( ef_size - EB_L_AT_LEN ). + +If the data is compressed, there will be ( ef_size - EB_L_AT_LEN ) bytes of +compressed data, and full_size bytes of uncompressed data. + +If a file has absolutely no attributes, there will not be a 'At' extra field. + +The uncompressed data is arranged like this: + +attr_name\0 - C string +struct attr_info (little-endian) +attr_data (length in attr_info.ai_size) +*/ + +#endif + diff --git a/atheos/zipup.h b/atheos/zipup.h new file mode 100644 index 0000000..d3d39a3 --- /dev/null +++ b/atheos/zipup.h @@ -0,0 +1,24 @@ +/* + 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 _ZIPUP_H_ +#define _ZIPUP_H_ + +#ifndef O_RDONLY +# include +#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 + +#endif /* _ZIPUP_H_ */ diff --git a/beos/Contents b/beos/Contents new file mode 100644 index 0000000..939a535 --- /dev/null +++ b/beos/Contents @@ -0,0 +1,14 @@ +Contents of the "beos" sub-directory for Zip 2.2 and later: + + Contents this file + README Notes from the author of the BeOS port + Makefile makefile for building (sorry, no project files) + beos.c BeOS-specific routines (similar to the UNIX ones) + osdep.h BeOS-specific includes and whatnot + zipup.h Definitions for zip routines + +This port supports both Metrowerks CodeWarrior and GNU C as the compiler, +and PowerPC and x86 architectures. + +- Chris Herborth (chrish@pobox.com) + June 24, 1998 diff --git a/beos/Makefile b/beos/Makefile new file mode 100644 index 0000000..1b9e613 --- /dev/null +++ b/beos/Makefile @@ -0,0 +1,182 @@ +###################################################################### +# +# Makefile for Info-ZIP's zip, zipcloak, zipnote, and zipsplit on BeOS +# +# Copyright © 1999 Info-ZIP +# Chris Herborth (chrish@pobox.com) +# +# This is the new New and Improved Makefile for BeOS; it automatically +# detects your platform and uses the appropriate compiler and compiler +# flags. + +###################################################################### +# Things that don't change: + +# Punish people who don't have SMP hardware. +MAKE = make -j 4 -f beos/Makefile +SHELL = /bin/sh + +LN = ln -s + +BIND = $(CC) +AS = $(CC) -c +CPP = $(CC) -E + +INSTALL = install + +# Target directories +prefix = /boot/home/config +BINDIR = $(prefix)/bin +manext = 1 +MANDIR = $(prefix)/man/man$(manext) +ZIPMANUAL = MANUAL + +VERSION = Version 2.3 of __DATE__ + +###################################################################### +# Things that change: + +# PowerPC system +ifeq "$(BE_HOST_CPU)" "ppc" + +CC:=mwcc + +ifeq "$(shell uname -r)" "4.0" + +CFLAGS:=-O7 -opt schedule604 -rostr -w9 \ + -I. -DHAVE_DIRENT_H -DPASSWD_FROM_STDIN +LFLAGS1:=-warn + +else + +CFLAGS:=-O7 -proc 604e -w9 -I. -DHAVE_DIRENT_H -DPASSWD_FROM_STDIN +LFLAGS1:=-nodup + +endif + +LFLAGS2:=-L/boot/develop/lib/ppc -lbe -lroot +OBJA = +TARGET=$(ZIPS) + +# x86 system +else + +CC:=gcc + +# Removed -Wconversion and -Wshadow because of the unnecessary warnings +# they generate. - Sept. 28, 1999 +CFLAGS:=-O3 -mpentiumpro \ + -Wall -Wno-multichar -Wno-ctor-dtor-privacy \ + -Wbad-function-cast -Woverloaded-virtual \ + -I. -I/boot/develop/headers/be/support \ + -I/boot/develop/headers/be/storage \ + -DHAVE_DIRENT_H -DPASSWD_FROM_STDIN # -DASMV +LFLAGS1:= +LFLAGS2:=-L/boot/develop/lib/x86 -lbe -lroot +OBJA = #match.o +TARGET=$(ZIPS) + +endif + +###################################################################### +# Helpful targets +all: + $(MAKE) CC=$(CC) CFLAGS="$(CFLAGS)" \ + LFLAGS1="$(LFLAGS1)" LFLAGS2="$(LFLAGS2)" \ + $(TARGET) + +###################################################################### +# Object file lists and other build goodies + +# Object file lists +OBJZ = zip.o zipfile.o zipup.o fileio.o util.o globals.o crypt.o ttyio.o \ + beos.o crc32.o +OBJI = deflate.o trees.o +# OBJA moved into ifeq block above; we'll use assembly for x86 +OBJU = zipfile_.o fileio_.o util_.o globals.o beos_.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o $(OBJU) crc32_.o crypt_.o ttyio.o +OBJS = zipsplit.o $(OBJU) + +# Headers +ZIP_H = zip.h ziperr.h tailor.h beos/osdep.h + +# What to build? +ZIPS = zip zipnote zipsplit zipcloak + +# 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: + groff -man -Tascii $< > $@ + +# 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 crc32.o crypt.o fileio.o zipfile.o zipup.o: crc32.h +zipcloak.o crc32_.o crypt_.o fileio_.o zipfile_.o: crc32.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: beos/zipup.h + +match.o: match.S + $(CPP) match.S > _match.s + $(AS) _match.s + mv -f _match.o match.o + rm -f _match.s + +beos.o: beos/beos.c + $(CC) -c $(CFLAGS) beos/beos.c + +beos_.o: beos/beos.c + rm -f $*_.c; $(LN) beos/beos.c $*_.c + $(CC) -c $(CFLAGS) -DUTIL $*_.c + rm -f $*_.c + +zips: $(ZIPS) +zipsman: $(ZIPS) $(ZIPMANUAL) + +zip: $(OBJZ) $(OBJI) $(OBJA) + $(BIND) -o zip $(LFLAGS1) $(OBJZ) $(OBJI) $(OBJA) $(LFLAGS2) +zipnote: $(OBJN) + $(BIND) -o zipnote $(LFLAGS1) $(OBJN) $(LFLAGS2) +zipcloak: $(OBJC) + $(BIND) -o zipcloak $(LFLAGS1) $(OBJC) $(LFLAGS2) +zipsplit: $(OBJS) + $(BIND) -o zipsplit $(LFLAGS1) $(OBJS) $(LFLAGS2) + +$(ZIPMANUAL): man/zip.1 + groff -man -Tascii man/zip.1 > $(ZIPMANUAL) + +# install +install: $(ZIPS) + $(INSTALL) -m755 $(ZIPS) $(BINDIR) + mkdir -p $(MANDIR) + $(INSTALL) -m644 man/zip.1 $(MANDIR)/zip.$(manext) + +uninstall: + -cd $(BINDIR); rm -f $(ZIPS) + -cd $(MANDIR); rm -f zip.$(manext) + +dist: $(ZIPMANUAL) + 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` + +# clean up after making stuff and installing it +clean: + rm -f *.o $(ZIPS) flags + +# end of Makefile diff --git a/beos/README b/beos/README new file mode 100644 index 0000000..b985ea0 --- /dev/null +++ b/beos/README @@ -0,0 +1,31 @@ +Info-ZIP's zip for BeOS + +KNOWN BUGS + +- None! (as of zip 2.21) + +- building on x86 BeOS generates a hell of a lot of bugs; I'm not going to + worry about them until Be fixes their headers though... + +FEATURES + +- stores BeOS file attributes, compressing them if possible (as of 2.21, + this works properly for symbolic links, too; as of 2.3, this works + properly for symbolic links whether you're storing them as links or not) + +- zip files are created with the correct file type (application/zip) + +- supports both Metrowerks CodeWarrior (PowerPC platform) and GNU C + (x86 platform), automatically picking the default compiler for each + architecture + +Please report any bugs to the Zip-Bugs mailing list; our email address is +zip-bugs@lists.wku.edu. If it's something BeOS-specific, you could email +me directly. + +Visit the Info-ZIP web site (http://www.cdrom.com/pub/infozip/) for all the +latest zip and unzip information, FAQs, source code and ready-to-run +executables. + +- Chris Herborth (chrish@pobox.com) + April 2/1999 diff --git a/beos/beos.c b/beos/beos.c new file mode 100644 index 0000000..d8d16df --- /dev/null +++ b/beos/beos.c @@ -0,0 +1,945 @@ +/* + Copyright (c) 1990-2002 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + + This BeOS-specific file is based on unix.c in the unix directory; changes + by Chris Herborth (chrish@pobox.com). + +*/ + +#include "zip.h" + +#ifndef UTIL /* the companion #endif is a bit of ways down ... */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + + +#define PAD 0 +#define PATH_END '/' + +/* Library functions not in (most) header files */ + +#ifdef _POSIX_VERSION +# include +#else + int utime OF((char *, time_t *)); +#endif + +extern char *label; +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +/* Local functions */ +local char *readd OF((DIR *)); +local int get_attr_dir( const char *, char **, off_t * ); +local int add_UT_ef( struct zlist far * ); +local int add_Ux_ef( struct zlist far * ); +local int add_Be_ef( struct zlist far * ); + + +#ifdef NO_DIR /* for AT&T 3B1 */ +#include +#ifndef dirent +# define dirent direct +#endif +typedef FILE DIR; +/* +** Apparently originally by Rich Salz. +** Cleaned up and modified by James W. Birdsall. +*/ + +#define opendir(path) fopen(path, "r") + +struct dirent *readdir(dirp) +DIR *dirp; +{ + static struct dirent entry; + + if (dirp == NULL) + return NULL; + for (;;) + if (fread (&entry, sizeof (struct dirent), 1, dirp) == 0) + return NULL; + else if (entry.d_ino) + return (&entry); +} /* end of readdir() */ + +#define closedir(dirp) fclose(dirp) +#endif /* NO_DIR */ + + +local char *readd(d) +DIR *d; /* directory stream to read from */ +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e; + + e = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; +} + +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 */ + int dosflag; + + dosflag = dosify; /* default for non-DOS and non-OS/2 */ + + /* Find starting point in name before doing malloc */ + for (t = x; *t == '/'; t++) + ; /* strip leading '/' chars to get a relative path */ + while (*t == '.' && t[1] == '/') + t += 2; /* strip redundant leading "./" sections */ + + /* Make changes, if any, to the copied name (leave original intact) */ + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + + if (isdir == 42) return n; /* avoid warning on unused variable */ + + if (dosify) + msname(n); + + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + return n; +} + + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + return x; +} + +/* + * XXX use ztimbuf in both POSIX and non POSIX cases ? + */ +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ +#ifdef _POSIX_VERSION + struct utimbuf u; /* argument for utime() const ?? */ +#else + time_t u[2]; /* argument for utime() */ +#endif + + /* Convert DOS time to time_t format in u */ +#ifdef _POSIX_VERSION + u.actime = u.modtime = dos2unixtime(d); + utime(f, &u); +#else + u[0] = u[1] = dos2unixtime(d); + utime(f, u); +#endif + +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + /* convert FNAMX to malloc - 11/8/04 EG */ + char *name; + int len = strlen(f); + + if (f == label) { + if (a != NULL) + *a = label_mode; + if (n != NULL) + *n = -2L; /* convention for a label name */ + if (t != NULL) + t->atime = t->mtime = t->ctime = label_utim; + return label_time; + } + if ((name = malloc(len + 1)) == NULL) { + ZIPERR(ZE_MEM, "filetime"); + } + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + if (strcmp(f, "-") == 0) { + if (fstat(fileno(stdin), &s) != 0) { + 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; + } + free(name); + + 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_mtime; /* best guess (s.st_ctime: last status change!) */ + } + + return unix2dostime(&s.st_mtime); +} + +/* ---------------------------------------------------------------------- + +Return a malloc()'d buffer containing all of the attributes and their names +for the file specified in name. You have to free() this yourself. The length +of the buffer is also returned. + +If get_attr_dir() fails, the buffer will be NULL, total_size will be 0, +and an error will be returned: + + EOK - no errors occurred + EINVAL - attr_buff was pointing at a buffer + ENOMEM - insufficient memory for attribute buffer + +Other errors are possible (whatever is returned by the fs_attr.h functions). + +PROBLEMS: + +- pointers are 32-bits; attributes are limited to off_t in size so it's + possible to overflow... in practice, this isn't too likely... your + machine will thrash like hell before that happens + +*/ + +#define INITIAL_BUFF_SIZE 65536 + +int get_attr_dir( const char *name, char **attr_buff, off_t *total_size ) +{ + int retval = EOK; + int fd; + DIR *fa_dir; + struct dirent *fa_ent; + off_t attrs_size; + off_t this_size; + char *ptr; + struct attr_info fa_info; + struct attr_info big_fa_info; + + retval = EOK; + attrs_size = 0; /* gcc still says this is used uninitialized... */ + *total_size = 0; + + /* ----------------------------------------------------------------- */ + /* Sanity-check. */ + if( *attr_buff != NULL ) { + return EINVAL; + } + + /* ----------------------------------------------------------------- */ + /* Can we open the file/directory? */ + /* */ + /* linkput is a zip global; it's set to 1 if we're storing symbolic */ + /* links as symbolic links (instead of storing the thing the link */ + /* points to)... if we're storing the symbolic link as a link, we'll */ + /* want the link's file attributes, otherwise we want the target's. */ + if( linkput ) { + fd = open( name, O_RDONLY | O_NOTRAVERSE ); + } else { + fd = open( name, O_RDONLY ); + } + if( fd < 0 ) { + return errno; + } + + /* ----------------------------------------------------------------- */ + /* Allocate an initial buffer; 64k should usually be enough. */ + *attr_buff = (char *)malloc( INITIAL_BUFF_SIZE ); + ptr = *attr_buff; + if( ptr == NULL ) { + close( fd ); + + return ENOMEM; + } + + /* ----------------------------------------------------------------- */ + /* Open the attributes directory for this file. */ + fa_dir = fs_fopen_attr_dir( fd ); + if( fa_dir == NULL ) { + close( fd ); + + free( ptr ); + *attr_buff = NULL; + + return retval; + } + + /* ----------------------------------------------------------------- */ + /* Read all the attributes; the buffer could grow > 64K if there are */ + /* many and/or they are large. */ + fa_ent = fs_read_attr_dir( fa_dir ); + while( fa_ent != NULL ) { + retval = fs_stat_attr( fd, fa_ent->d_name, &fa_info ); + /* TODO: check retval != EOK */ + + this_size = strlen( fa_ent->d_name ) + 1; + this_size += sizeof( struct attr_info ); + this_size += fa_info.size; + + attrs_size += this_size; + + if( attrs_size > INITIAL_BUFF_SIZE ) { + unsigned long offset = ptr - *attr_buff; + + *attr_buff = (char *)realloc( *attr_buff, attrs_size ); + if( *attr_buff == NULL ) { + retval = fs_close_attr_dir( fa_dir ); + /* TODO: check retval != EOK */ + close( fd ); + + return ENOMEM; + } + + ptr = *attr_buff + offset; + } + + /* Now copy the data for this attribute into the buffer. */ + strcpy( ptr, fa_ent->d_name ); + ptr += strlen( fa_ent->d_name ); + *ptr++ = '\0'; + + /* We need to put a big-endian version of the fa_info data into */ + /* the archive. */ + big_fa_info.type = B_HOST_TO_BENDIAN_INT32( fa_info.type ); + big_fa_info.size = B_HOST_TO_BENDIAN_INT64( fa_info.size ); + memcpy( ptr, &big_fa_info, sizeof( struct attr_info ) ); + ptr += sizeof( struct attr_info ); + + if( fa_info.size > 0 ) { + ssize_t read_bytes; + + read_bytes = fs_read_attr( fd, fa_ent->d_name, fa_info.type, 0, + ptr, fa_info.size ); + if( read_bytes != fa_info.size ) { + /* print a warning about mismatched sizes */ + char buff[80]; + + sprintf( buff, "read %ld, expected %ld", + (ssize_t)read_bytes, (ssize_t)fa_info.size ); + zipwarn( "attribute size mismatch: ", buff ); + } + + /* Wave my magic wand... this swaps all the Be types to big- */ + /* endian automagically. */ + (void)swap_data( fa_info.type, ptr, fa_info.size, + B_SWAP_HOST_TO_BENDIAN ); + + ptr += fa_info.size; + } + + fa_ent = fs_read_attr_dir( fa_dir ); + } + + /* ----------------------------------------------------------------- */ + /* Close the attribute directory. */ + retval = fs_close_attr_dir( fa_dir ); + /* TODO: check retval != EOK */ + + /* ----------------------------------------------------------------- */ + /* If the buffer is too big, shrink it. */ + if( attrs_size < INITIAL_BUFF_SIZE ) { + *attr_buff = (char *)realloc( *attr_buff, attrs_size ); + if( *attr_buff == NULL ) { + /* This really shouldn't happen... */ + close( fd ); + + return ENOMEM; + } + } + + *total_size = attrs_size; + + close( fd ); + + return EOK; +} + +/* ---------------------------------------------------------------------- */ +/* Add a 'UT' extra field to the zlist data pointed to by z. */ + +#define EB_L_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(2)) +#define EB_C_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(1)) + +local int add_UT_ef( struct zlist far *z ) +{ + char *l_ef = NULL; + char *c_ef = NULL; + struct stat s; + +#ifdef IZ_CHECK_TZ + if (!zp_tz_is_valid) + return ZE_OK; /* skip silently if no valid TZ info */ +#endif + + /* We can't work if there's no entry to work on. */ + if( z == NULL ) { + return ZE_LOGIC; + } + + /* Check to make sure we've got enough room in the extra fields. */ + if( z->ext + EB_L_UT_SIZE > USHRT_MAX || + z->cext + EB_C_UT_SIZE > USHRT_MAX ) { + return ZE_MEM; + } + + /* stat() the file (or the symlink) to get the data; if we can't get */ + /* the data, there's no point in trying to fill out the fields. */ + if(LSSTAT( z->name, &s ) ) { + return ZE_OPEN; + } + + /* Allocate memory for the local and central extra fields. */ + if( z->extra && z->ext != 0 ) { + l_ef = (char *)realloc( z->extra, z->ext + EB_L_UT_SIZE ); + } else { + l_ef = (char *)malloc( EB_L_UT_SIZE ); + z->ext = 0; + } + if( l_ef == NULL ) { + return ZE_MEM; + } + z->extra = l_ef; + l_ef += z->ext; + + if( z->cextra && z->cext != 0 ) { + c_ef = (char *)realloc( z->cextra, z->cext + EB_C_UT_SIZE ); + } else { + c_ef = (char *)malloc( EB_C_UT_SIZE ); + z->cext = 0; + } + if( c_ef == NULL ) { + return ZE_MEM; + } + z->cextra = c_ef; + c_ef += z->cext; + + /* Now add the local version of the field. */ + *l_ef++ = 'U'; + *l_ef++ = 'T'; + *l_ef++ = (char)(EB_UT_LEN(2)); /* length of data in local EF */ + *l_ef++ = (char)0; + *l_ef++ = (char)(EB_UT_FL_MTIME | EB_UT_FL_ATIME); + *l_ef++ = (char)(s.st_mtime); + *l_ef++ = (char)(s.st_mtime >> 8); + *l_ef++ = (char)(s.st_mtime >> 16); + *l_ef++ = (char)(s.st_mtime >> 24); + *l_ef++ = (char)(s.st_atime); + *l_ef++ = (char)(s.st_atime >> 8); + *l_ef++ = (char)(s.st_atime >> 16); + *l_ef++ = (char)(s.st_atime >> 24); + + z->ext += EB_L_UT_SIZE; + + /* Now add the central version. */ + memcpy(c_ef, l_ef-EB_L_UT_SIZE, EB_C_UT_SIZE); + c_ef[EB_LEN] = (char)(EB_UT_LEN(1)); /* length of data in central EF */ + + z->cext += EB_C_UT_SIZE; + + return ZE_OK; +} + +/* ---------------------------------------------------------------------- */ +/* Add a 'Ux' extra field to the zlist data pointed to by z. */ + +#define EB_L_UX2_SIZE (EB_HEADSIZE + EB_UX2_MINLEN) +#define EB_C_UX2_SIZE (EB_HEADSIZE) + +local int add_Ux_ef( struct zlist far *z ) +{ + char *l_ef = NULL; + char *c_ef = NULL; + struct stat s; + + /* Check to make sure we've got enough room in the extra fields. */ + if( z->ext + EB_L_UX2_SIZE > USHRT_MAX || + z->cext + EB_C_UX2_SIZE > USHRT_MAX ) { + return ZE_MEM; + } + + /* stat() the file (or the symlink) to get the data; if we can't get */ + /* the data, there's no point in trying to fill out the fields. */ + if(LSSTAT( z->name, &s ) ) { + return ZE_OPEN; + } + + /* Allocate memory for the local and central extra fields. */ + if( z->extra && z->ext != 0 ) { + l_ef = (char *)realloc( z->extra, z->ext + EB_L_UX2_SIZE ); + } else { + l_ef = (char *)malloc( EB_L_UX2_SIZE ); + z->ext = 0; + } + if( l_ef == NULL ) { + return ZE_MEM; + } + z->extra = l_ef; + l_ef += z->ext; + + if( z->cextra && z->cext != 0 ) { + c_ef = (char *)realloc( z->cextra, z->cext + EB_C_UX2_SIZE ); + } else { + c_ef = (char *)malloc( EB_C_UX2_SIZE ); + z->cext = 0; + } + if( c_ef == NULL ) { + return ZE_MEM; + } + z->cextra = c_ef; + c_ef += z->cext; + + /* Now add the local version of the field. */ + *l_ef++ = 'U'; + *l_ef++ = 'x'; + *l_ef++ = (char)(EB_UX2_MINLEN); + *l_ef++ = (char)(EB_UX2_MINLEN >> 8); + *l_ef++ = (char)(s.st_uid); + *l_ef++ = (char)(s.st_uid >> 8); + *l_ef++ = (char)(s.st_gid); + *l_ef++ = (char)(s.st_gid >> 8); + + z->ext += EB_L_UX2_SIZE; + + /* Now add the central version of the field. */ + *c_ef++ = 'U'; + *c_ef++ = 'x'; + *c_ef++ = 0; + *c_ef++ = 0; + + z->cext += EB_C_UX2_SIZE; + + return ZE_OK; +} + +/* ---------------------------------------------------------------------- */ +/* Add a 'Be' extra field to the zlist data pointed to by z. */ + +#define EB_L_BE_SIZE (EB_HEADSIZE + EB_L_BE_LEN) /* + attr size */ +#define EB_C_BE_SIZE (EB_HEADSIZE + EB_C_BE_LEN) + +/* maximum memcompress overhead is the sum of the compression header length */ +/* (6 = ush compression type, ulg CRC) and the worstcase deflate overhead */ +/* when uncompressible data are kept in 2 "stored" blocks (5 per block = */ +/* byte blocktype + 2 * ush blocklength) */ +#define MEMCOMPRESS_OVERHEAD (EB_MEMCMPR_HSIZ + EB_DEFLAT_EXTRA) + +local int add_Be_ef( struct zlist far *z ) +{ + char *l_ef = NULL; + char *c_ef = NULL; + char *attrbuff = NULL; + off_t attrsize = 0; + char *compbuff = NULL; + ush compsize = 0; + uch flags = 0; + + /* Check to make sure we've got enough room in the extra fields. */ + if( z->ext + EB_L_BE_SIZE > USHRT_MAX || + z->cext + EB_C_BE_SIZE > USHRT_MAX ) { + return ZE_MEM; + } + + /* Attempt to load up a buffer full of the file's attributes. */ + { + int retval; + + retval = get_attr_dir( z->name, &attrbuff, &attrsize ); + if( retval != EOK ) { + return ZE_OPEN; + } + if( attrsize == 0 ) { + return ZE_OK; + } + if( attrbuff == NULL ) { + return ZE_LOGIC; + } + + /* Check for way too much data. */ + if( attrsize > (off_t)ULONG_MAX ) { + zipwarn( "uncompressed attributes truncated", "" ); + attrsize = (off_t)(ULONG_MAX - MEMCOMPRESS_OVERHEAD); + } + } + + if( verbose ) { + printf( "\t[in=%lu]", (unsigned long)attrsize ); + } + + /* Try compressing the data */ + compbuff = (char *)malloc( (size_t)attrsize + MEMCOMPRESS_OVERHEAD ); + if( compbuff == NULL ) { + return ZE_MEM; + } + compsize = memcompress( compbuff, + (size_t)attrsize + MEMCOMPRESS_OVERHEAD, + attrbuff, + (size_t)attrsize ); + if( verbose ) { + printf( " [out=%u]", compsize ); + } + + /* Attempt to optimise very small attributes. */ + if( compsize > attrsize ) { + free( compbuff ); + compsize = (ush)attrsize; + compbuff = attrbuff; + + flags = EB_BE_FL_NATURAL; + } + + /* Check to see if we really have enough room in the EF for the data. */ + if( ( z->ext + compsize + EB_L_BE_LEN ) > USHRT_MAX ) { + compsize = USHRT_MAX - EB_L_BE_LEN - z->ext; + } + + /* Allocate memory for the local and central extra fields. */ + if( z->extra && z->ext != 0 ) { + l_ef = (char *)realloc( z->extra, z->ext + EB_L_BE_SIZE + compsize ); + } else { + l_ef = (char *)malloc( EB_L_BE_SIZE + compsize ); + z->ext = 0; + } + if( l_ef == NULL ) { + return ZE_MEM; + } + z->extra = l_ef; + l_ef += z->ext; + + if( z->cextra && z->cext != 0 ) { + c_ef = (char *)realloc( z->cextra, z->cext + EB_C_BE_SIZE ); + } else { + c_ef = (char *)malloc( EB_C_BE_SIZE ); + z->cext = 0; + } + if( c_ef == NULL ) { + return ZE_MEM; + } + z->cextra = c_ef; + c_ef += z->cext; + + /* Now add the local version of the field. */ + *l_ef++ = 'B'; + *l_ef++ = 'e'; + *l_ef++ = (char)(compsize + EB_L_BE_LEN); + *l_ef++ = (char)((compsize + EB_L_BE_LEN) >> 8); + *l_ef++ = (char)((unsigned long)attrsize); + *l_ef++ = (char)((unsigned long)attrsize >> 8); + *l_ef++ = (char)((unsigned long)attrsize >> 16); + *l_ef++ = (char)((unsigned long)attrsize >> 24); + *l_ef++ = flags; + memcpy( l_ef, compbuff, (size_t)compsize ); + + z->ext += EB_L_BE_SIZE + compsize; + + /* And the central version. */ + *c_ef++ = 'B'; + *c_ef++ = 'e'; + *c_ef++ = (char)(EB_C_BE_LEN); + *c_ef++ = (char)(EB_C_BE_LEN >> 8); + *c_ef++ = (char)compsize; + *c_ef++ = (char)(compsize >> 8); + *c_ef++ = (char)(compsize >> 16); + *c_ef++ = (char)(compsize >> 24); + *c_ef++ = flags; + + z->cext += EB_C_BE_SIZE; + + return ZE_OK; +} + +/* Extra field info: + - 'UT' - UNIX time extra field + - 'Ux' - UNIX uid/gid extra field + - 'Be' - BeOS file attributes extra field + + This is done the same way ../unix/unix.c stores the 'UT'/'Ux' fields + (full data in local header, only modification time in central header), + with the 'Be' field added to the end and the size of the 'Be' field + in the central header. + + See the end of beos/osdep.h for a simple explanation of the 'Be' EF + layout. + */ +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; + /* store full data in local header but just modification time stamp info + in central header */ +{ + int retval; + + /* Tell picky compilers to shut up about unused variables. */ + z_utim = z_utim; + + /* Check to make sure z is valid. */ + if( z == NULL ) { + return ZE_LOGIC; + } + + /* This function is much simpler now that I've moved the extra fields */ + /* out... it simplified the 'Be' code, too. */ + retval = add_UT_ef( z ); + if( retval != ZE_OK ) { + return retval; + } + + retval = add_Ux_ef( z ); + if( retval != ZE_OK ) { + return retval; + } + + retval = add_Be_ef( z ); + if( retval != ZE_OK ) { + return retval; + } + + return ZE_OK; +} + +/* ---------------------------------------------------------------------- */ +/* Set a file's MIME type. */ +void setfiletype( const char *file, const char *type ) +{ + int fd; + attr_info fa; + ssize_t wrote_bytes; + + fd = open( file, O_RDWR ); + if( fd < 0 ) { + zipwarn( "can't open zipfile to write file type", "" ); + return; + } + + fa.type = B_MIME_STRING_TYPE; + fa.size = (off_t)(strlen( type ) + 1); + + wrote_bytes = fs_write_attr( fd, BE_FILE_TYPE_NAME, fa.type, 0, + type, fa.size ); + if( wrote_bytes != (ssize_t)fa.size ) { + zipwarn( "couldn't write complete file type", "" ); + } + + close( fd ); +} + +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]). + */ +{ +# ifdef NO_RMDIR + /* code from Greg Roelofs, who horked it from Mark Edwards (unzip) */ + int r, len; + char *s; /* malloc'd string for system command */ + + len = strlen(d); + if ((s = malloc(len + 34)) == NULL) + return 127; + + sprintf(s, "IFS=\" \t\n\" /bin/rmdir %s 2>/dev/null", d); + r = system(s); + free(s); + return r; +# else /* !NO_RMDIR */ + return rmdir(d); +# endif /* ?NO_RMDIR */ +} + +#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 __MWERKS__ + "Metrowerks CodeWarrior", "", +#else +# ifdef __GNUC__ + "gcc ", __VERSION__, +# endif +#endif + + "BeOS", + +#ifdef __POWERPC__ + " (PowerPC)", +#else +# ifdef __INTEL__ + " (x86)", +# else + " (UNKNOWN!)", +# endif +#endif + +#ifdef __DATE__ + " on ", __DATE__ +#else + "", "" +#endif + ); + +} /* end function version_local() */ diff --git a/beos/osdep.h b/beos/osdep.h new file mode 100644 index 0000000..0197903 --- /dev/null +++ b/beos/osdep.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 +*/ +#include +#include +#include + +#include /* for B_NO_ERROR */ + +#define USE_EF_UT_TIME /* Enable use of "UT" extra field time info */ + +#define EB_L_BE_LEN 5 /* min size is an unsigned long and flag */ +#define EB_C_BE_LEN 5 /* Length of data in local EF and flag. */ + +#define EB_BE_FL_NATURAL 0x01 /* data is 'natural' (not compressed) */ +#define EB_BE_FL_BADBITS 0xfe /* bits currently undefined */ + +#ifndef ZP_NEED_MEMCOMPR +# define ZP_NEED_MEMCOMPR +#endif + +/* Set a file's MIME type. */ +#define BE_FILE_TYPE_NAME "BEOS:TYPE" +void setfiletype( const char *file, const char *type ); + +/* +DR9 'Be' extra-field layout: + +'Be' - signature +ef_size - size of data in this EF (little-endian unsigned short) +full_size - uncompressed data size (little-endian unsigned long) +flag - flags (byte) + flags & EB_BE_FL_NATURAL = the data is not compressed + flags & EB_BE_FL_BADBITS = the data is corrupted or we + can't handle it properly +data - compressed or uncompressed file attribute data + +If flag & EB_BE_FL_NATURAL, the data is not compressed; this optimisation is +necessary to prevent wasted space for files with small attributes (which +appears to be quite common on the Advanced Access DR9 release). In this +case, there should be ( ef_size - EB_L_BE_LEN ) bytes of data, and full_size +should equal ( ef_size - EB_L_BE_LEN ). + +If the data is compressed, there will be ( ef_size - EB_L_BE_LEN ) bytes of +compressed data, and full_size bytes of uncompressed data. + +If a file has absolutely no attributes, there will not be a 'Be' extra field. + +The uncompressed data is arranged like this: + +attr_name\0 - C string +struct attr_info (big-endian) +attr_data (length in attr_info.size) +*/ diff --git a/beos/zipup.h b/beos/zipup.h new file mode 100644 index 0000000..40c79eb --- /dev/null +++ b/beos/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 +# include +#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 diff --git a/bzip2/install.txt b/bzip2/install.txt new file mode 100644 index 0000000..87d45ad --- /dev/null +++ b/bzip2/install.txt @@ -0,0 +1,258 @@ +HOW TO ADD BZIP2 SUPPORT TO ZIP + +This document describes how to add bzip2 support to Zip. + +Compiling or linking in the bzip2 library adds an additional bzip2 +compression method to Zip. This new method can be selected instead +of the Zip traditional compression method deflation to compress files +and often gives a better compression ratio (perhaps at the cost of +greater CPU time). The compression method is specified using the +"-Z method" command-line option, where "method" may be either "deflate" +(the default), or "bzip2" (if Zip is built with bzip2 support). Zip +has been tested with bzip2 library 1.0.5 and earlier. + +Notes + +Compression method bzip2 requires a modern unzip. Before using bzip2 +compression in Zip, verify that a modern UnZip program with bzip2 support +will be used to read the resulting zip archive so that entries compressed +with bzip2 (compression method 12) can be read. Older unzips probably +won't recognize the compression method and will skip those entries. + +The Zip source kit does not include the bzip2 library or source files, but +these can be found at "http://www.bzip.org/" for example. See below for +how to add bzip2 to Zip for various operating systems. + +Zip using bzip2 compression is not compatible with the bzip2 application, +but instead provides an additional way to compress files before adding +them to a Zip archive. It does not replace the bzip2 program itself, +which creates bzip2 archives in a different format that are not +compatible with zip or unzip. + +The bzip2 code and algorithms are provided under the bzip2 license +(provided in the bzip2 source kit) and what is not covered by that license +is covered under the Info-ZIP license. Info-ZIP will look at issues +involving the use of bzip2 compression in Zip, but any questions about +the bzip2 code and algorithms or bzip2 licensing, for example, should be +directed to the bzip2 maintainer. + + +Installation + +To build Zip with bzip2 support, Zip generally needs one bzip2 header +file, "bzlib.h", and the object library, typically "libbz2.a", except +in cases where the source files are compiled in directly. If you +are either compiling the bzip2 library or compiling in the bzip2 +source files, we recommend defining the C macro BZ_NO_STDIO, which +excludes a lot of standalone error code (not used when bzip2 is +used as a library and makes the library smaller) and provides hooks +that Zip can use to provide better error handling. However, a +standard bzip2 object library will work, though any errors that bzip2 +generates may be more cryptic. + +Building the bzip2 library from the bzip2 source files (recommended): + + Download the latest bzip2 package (from "http://www.bzip.org/", for + example). + + Unpack the bzip2 source kit (bzip2-1.0.5.tar.gz was current as of + this writing, but the latest should work). + + Read the README file in the bzip2 source kit. + + Compile the bzip2 library for your OS, preferably defining + BZ_NO_STDIO. Note: On UNIX systems, this may be done automatically + when building Zip, as explained below. + + +Installation on UNIX (see below for installation on other systems): + + Note: Zip on UNIX uses the "bzlib.h" include file and the compiled + "libbz2.a" library to static link to bzip2. Currently we do not + support using the shared library (patches welcome). + + The easiest approach may be to drop the two above files in the + bzip2 directory of the Zip source tree and build Zip using the + "generic" target, that is, using a command like + make -f unix/Makefile generic + If all goes well, make should confirm that it found the files and + will be compiling in bzip2 by setting the BZIP2_SUPPORT flag and + then including the libraries while compiling and linking Zip. + + To use bzlib.h and libbz2.a from somewhere else on your system, + define the "make" macro IZ_BZIP2 to point to that directory. For + example: + make -f unix/Makefile generic IZ_BZIP2=/mybz2 + where /mybz2 might be "/usr/local/src/bzip2/bzip2-1.0.5" on some + systems. Only a compiled bzip2 library can be pointed to using + IZ_BZIP2 and Zip will not compile bzip2 source in other than the + bzip2 directory. + + If IZ_BZIP2 is not defined, Zip will look for the bzip2 files in + the "bzip2" directory in the Zip source directory. The bzip2 + directory is empty in the Zip source distribution (except for + this install.txt file) and is provided as a place to put the + bzip2 files. To use this directory, either drop bzlib.h and + libbz2.a in it to use the compiled library as noted above or drop + the contents of the bzip2 source kit in this directory so that + bzlib.h is directly in the bzip2 directory and Zip will try to + compile it if no compiled library is already there. + + + Unpacking bzip2 so Zip compiles it: + + To make this work, the bzip2 source kit must be unpacked directly + into the Zip "bzip2" directory. For example: + + # Unpack the Zip source kit. + gzip -cd zip30.tar-gz | tar xfo - + # Move down to the Zip kit's "bzip2" directory, ... + cd zip30/bzip2 + # ... and unpack the bzip2 source kit there. + gzip -cd ../../bzip2-1.0.5.tar.gz | tar xfo - + # Move the bzip2 source files up to the Zip kit's bzip2 directory. + cd bzip2-1.0.5 + mv * .. + # Return to the Zip source kit directory, ready to build. + cd ../.. + # Build Zip. + make -f unix/Makefile generic + + + Using a system bzip2 library: + + If IZ_BZIP2 is not defined and both a compiled library and the bzip2 + source files are missing from the Zip bzip2 directory, Zip will test + to see if bzip2 is globally defined on the system in the default + include and library paths and, if found, link in the system bzip2 + library. This is automatic. + + + Preventing inclusion of bzip2: + + To build Zip with _no_ bzip2 support on a system where the automatic + bzip2 detection scheme will find bzip2, you can specify a bad + IZ_BZIP2 directory. For example: + + make -f unix/Makefile generic IZ_BZIP2=no_such_directory + + You can also define NO_BZIP2_SUPPORT to exclude bzip2. + + + Verifying bzip2 support in Zip: + + When the Zip build is complete, verify that bzip2 support has been + enabled by checking the feature list: + + ./zip -v + + If all went well, bzip2 (and its library version) should be listed. + + +Installation on other systems + + MSDOS: + + Thanks to Robert Riebisch, the DJGPP 2.x Zip port now supports bzip2. + To include bzip2, first install bzip2. The new msdos/makebz2.dj2 + makefile then looks in the standard bzip2 installation directories + for the needed files. As he says: + It doesn't try to be clever about finding libbz2.a. It just + expects bzip2 stuff installed to the default include and library + folders, e.g., "C:\DJGPP\include" and "C:\DJGPP\lib" on DOS. + + Given a standard DJGPP 2.x installation, this should create a + version of Zip 3.0 with bzip2 support. + + The bzip2 library for DJGPP can be found on any DJGPP mirror in + "current/v2apps" (or "beta/v2apps/" for the latest beta). This + library has been ported to MSDOS/DJGPP by Juan Manuel Guerrero. + + + WIN32 (Windows NT/2K/XP/2K3/... and Windows 95/98/ME): + + For Windows there seems to be two approaches, either use bzip2 + as a dynamic link library or compile the bzip2 source in directly. + I have not gotten the static library libbz2.lib to work, but that + may be me. + + Using bzip2 as a dynamic link library: + + Building bzip2: + + If you have the needed bzlib.h, libbz2.lib, and libbz2.dll files + you can skip building bzip2. If not, open the libbz2.dsp project + and build libbz2.dll + + This creates + debug/libbz2.lib + and + libbz2.dll + + + Building Zip: + + Copy libbz2.lib to the bzip2 directory in the Zip source tree. This + is needed to compile Zip with bzip2 support. Also copy the matching + bzlib.h from the bzip2 source to the same directory. + + Add libbz2.lib to the link list for whatever you are building. Also + define the compiler define BZIP2_SUPPORT. + + Build Zip. + + + Using Zip with bzip2 as dll: + + Put libbz2.dll in your command path. This is needed to run Zip with + bzip2 support. + + Verify that bzip2 is enabled with the command + + zip -v + + You should see bzip2 listed. + + Compiling in bzip2 from the bzip2 source: + + This approach compiles in the bzip2 code directly. No external + library is needed. + + Get a copy of the bzip2 source and copy the contents to the bzip2 + directory in the Zip source tree so that bzlib.h is directly in + the bzip2 directory. + + Use the vc6bz2 project to build Zip. This project knows of the + added bzip2 files. + + Verify that bzip2 is enabled with the command + + zip -v + + + Windows DLL (WIN32): + + Nothing yet. + + + Mac OS X: + + Follow the standard UNIX build procedure. Mac OS X includes bzip2 + and the UNIX builders should find the bzip2 files in the standard + places. Note that the version of bzip2 on your OS may not be + current and you can instead specify a different library or compile + your own bzip2 library as noted in the Unix procedures above. + + + OS/2: + + Nothing yet. + + + VMS (OpenVMS): + + See [.vms]install_vms.txt for how to enable bzip2 support on VMS. + + +Last updated 26 March 2007, 15 July 2007, 9 April 2008, 27 June 2008 +S. Schweda, E. Gordon diff --git a/cmsmvs/README.CMS b/cmsmvs/README.CMS new file mode 100644 index 0000000..a4425da --- /dev/null +++ b/cmsmvs/README.CMS @@ -0,0 +1,434 @@ +Using ZIP and UNZIP on VM/CMS +============================= + + +Installing executables +---------------------- + +The following CMS MODULEs are available: + ZIP + ZIPNOTE + ZIPCLOAK + ZIPSPLIT + UNZIP + +In addition to these, each MODULE file also has an EXEC with the same +name. These EXECs are front-ends to the MODULES that will attempt to +set up the required runtime libraries before running the MODULE. +All the EXECs are identical. Only their names are different. +They are stored as plain text files. + +The CMS MODULE files have been packed using the COPYFILE command to +allow their file format to be properly restored, since variable length +binary files will not currently unzip properly (see below for details). +The MODULEs are shipped with a filetype or extension of CMO (for CMS +MODULE). Their names may vary on the distribution disk to indicate +their level, etc. + +To restore them to executable MODULEs on CMS, do the following: + 1. Upload them to CMS with a Fixed record length with LRECL 1024. + Example, from a DOS or OS/2 window, type this: + SEND unzip.cmo A:unzip module a (RECFM F LRECL 1024 + + Example, using FTP from CMS, type this: + BINARY FIXED 1024 + GET unzip.cmo unzip.module.a + + Note: Replace "unzip.cmo" with the actual name. + + 2. Use COPYFILE to unpack the file. + Example, in CMS type this: + COPYFILE UNZIP MODULE A (UNPACK REPLACE OLDDATE + + 3. Repeat steps 1-2 for each of the programs. + + 4. Build the ZIPINFO module by typing this: + COPYFILE UNZIP MODULE A ZIPINFO MODULE A (OLDDATE + + 5. Upload the EXECs to CMS as text files (with ASCII-to-EBCDIC + translation). + Example, from a DOS or OS/2 window, type this: + SEND unzip.exc A:unzip exec a (CRLF + + Example, using FTP from CMS, type this: + GET unzip.exc unzip.exec.a + + 6. Repeat steps 4 for each of the EXECs. + + +Preparing the environment +------------------------- + +The executables provided were compiled with IBM C 3.1.0 and +require the the Language Environment (LE) runtime libraries. + +To provide access to the runtime libraries: + 1. Link to the disk containing the Language Environment files, + if necessary. + + 2. Use the command "GLOBAL LOADLIB SCEERUN" + + These commands can be placed in your PROFILE EXEC. + + Note: EXECs have been provided called ZIP, UNZIP, etc. that + issue the GLOBAL LOADLIB statement. This was done to alleviate + frustration of users that don't have the GLOBAL LOADLIB statement + in their PROFILE EXEC. These EXECs may require changing for + your system. + + Unfortunately, there is no way, using IBM C, to produce a MODULE + that doesn't require a runtime library. + + +Testing +------- + +To test the MODULEs, just type ZIP or UNZIP. They should +show help information on using the commands. + +If you see something like this: + DMSLIO201W The following names are undefined: + CEEEV003 + DMSABE155T User abend 4093 called from 00DCD298 reason code 000003EB + +Then you don't have access to the proper runtime libraries, as +described above. + +Here is additional information on the ZIP and UNZIP programs that +may assist support personnel: + - Compiled with IBM C V3R1M0 on VM/ESA 2.2.0 with + CMS level 13 Service Level 702. + + - Require the SCEERUN LOADLIB runtime library. This is + part of the Language Environment (LE). + + - Linked with options RMODE ANY AMODE ANY RLDSAVE. + +If you continue to have trouble, report the problem to Zip-Bugs +(see the bottom of this document). + + + +Compiling the source on VM/CMS +------------------------------ + +The source has been successfully compiled previously using +C/370 2.1 and 2.2. The source has been recently compiled using +IBM C 3.1.0 on VM/ESA 2.2.0 with CMS level 13. I don't have +access to an MVS system so the code hasn't been tested there +in a while. + + 1. Unzip the source files required for CMS. The root-level files + inside the ZIP file and the files in the CMSMVS subdirectory are + needed. Example (use both commands): + unzip -aj zip23.zip -x */* -dc + unzip -aj zip23.zip cmsmvs/* -dc + + This example unzips the files to the C-disk, while translating + character data and ignoring paths. + + If you don't already have a working UNZIP MODULE on CMS you will + have to unzip the files on another system and transport them + to CMS. All the required files are plain text so they can + be transferred with ASCII-to-EBCDIC translations. + + 2. Repeat step 1 with the zip file containing the UNZIP code. + Unzip the files to a different disk than the disk used for the ZIP + code. + + 3. To compile the ZIP code, run the supplied CCZIP EXEC. + To compile the UNZIP code, run the supplied CCUNZIP EXEC. + +NOTE: +Some of the ZIP and UNZIP source files have the same name. It is +recommended that you keep the source from each on separate disks and +move the disk you are building from ahead of the other in the search +order. + +For example, you may have a 192 disk with the ZIP source code and +a 193 disk with the UNZIP source code. To compile ZIP, access +the 192 disk as B, then run CCZIP. This will create the following +modules: ZIP, ZIPNOTE, ZIPSPLIT, ZIPCLOAK. + +To compile UNZIP, access 193 as B, then run CCUNZIP. This will create +the following modules: UNZIP, ZIPINFO (a copy of UNZIP). + + +========================================================================= + + +Using ZIP/UNZIP +--------------- + +Documentation for the commands is in MANUAL NONAME (for ZIP) and in +UNZIP DOC UNZIP. INFOZIP DOC describes the use of the -Z option of +UNZIP. + +The rest of this section explains special notes concerning the VM/CMS +version of ZIP and UNZIP. + + +Filenames and directories +------------------------- + + 1. Specifying filenames + + a. When specifying CMS files, use filename.filetype.filemode format + (separate the three parts of the name with a period and use no + spaces). Example: profile.exec.a + + Unfortunately, this prevents you from using ZIP from + FILELIST. To unzip a zip file, however, you can type something + like this next to it in FILELIST: + unzip /n -d c + + This will unzip the contents of the current file to a C-disk. + + b. It is possible to use DD names with ZIP and UNZIP on CMS, though + it can be cumbersome. Example: + filedef out disk myzip zip a + zip dd:out file1.txt file2.txt + + While you can also use a DD name for the input files, ZIP + currently does not correctly resolve the filename and will + store something like "dd:in" inside the ZIP file. A file stored + in this manor cannot easily be unzipped, as "dd:in" is an invalid + filename. + + c. In places where a directory name would be used on a PC, such as + for the ZIP -b (work path) option or the UNZIP -d (destination + path) options, use a filemode letter for CMS. For example, + to unzip files onto a C-disk, you might type something like this: + unzip myzip.zip -d c + + Currently, ZIP uses the A-disk for work files. When zipping + large files, you may want to specify a larger disk for work files. + This example will use a C-disk for work files. + zip -b C myzip.zip.c test.dat.a + + + 2. Filename conversions + + a. Filemode letters are never stored into the zip file or take from + a zip file. Only the filename and filetype are used. + ZIP removes the filemode when storing the filename into the + zip file. UNZIP assumes "A" for the filemode unless the -d + option is used. + + b. When unzipping, any path names are removed from the fileid + and the last two period-separated words are used as the + filename and filetype. These are truncated to a maximum of + eight characters, if necessary. If the filetype (extension) + is missing, then UNZIP uses "NONAME" for the filetype. + Any '(' or ')' characters are removed from the fileid. + + c. All files are created in upper-case. Files in mixed-case + cannot currently be stored into a ZIP file. + + d. Shared File System (SFS) directories are not supported. + Files are always accessed by fn.ft.fm. To use an SFS disk, + Assign it a filemode, then it can be used. + + + 3. Wildcards in file names + + a. Wildcards are not supported in the zip filename. The full + filename of the zip file must be given (but the .zip is not + necessary). So, you can't do this: + unzip -t *.zip + + b. Wildcards CAN be used with UNZIP to select (or exclude) files + inside a zip file. Examples: + unzip myzip *.c - Unzip all .c files. + unzip myzip *.c -x z*.c - Unzip all .c files but those + starting with Z. + + c. Wildcards cannot currently be used to select files with ZIP. + So, you can't do this: + zip -a myzip *.exec + + I expect to fix this for CMS in the future. + + + 4. File timestamps + + a. The dates and times of files being zipped or unzipped are not + currently read or set. When a file is zipped, the timestamp + inside the zip file will always be the current system date and + time. Likewise, when unzipping, the date and time of files + being unzipped will always be the current system date/time. + + b. Existing files are assumed to be newer than files inside a zip + file when using the -f freshen option of UNZIP. This will prevent + overwriting files that may be newer than the files inside the + zip file, but also effectively prevents the -f option from working. + + + 5. ASCII, EBCDIC, and binary data + + Background + ---------- + Most systems create data files as just a stream of bytes. Record + breaks happen when certain characters (new line and/or carriage + return characters) are encountered in the data. How to interpret + the data in a file is up to the user. The system must be told + to either notice new line characters in the data or to assume + that the data in the file is binary data and should be read or + written as-is. + + CMS and MVS are record-based systems. All files are composed + of data records. These can be stored in fixed-length files or + in variable length files. With fixed-length files, each record + is the same length. The record breaks are implied by the + LRECL (logical record length) attribute associated with the file. + With variable-length files, each record contains the length of + that record. The separation of records are not part of the + data, but part of the file structure. + + This means you can store any type of data in either type of file + structure without having to worry about the data being interpreted + as a record break. Fixed-length files may have padding at the + end of the file to make up a full record. Variable-length files + have no padding, but require extra record length data be stored + with the file data. + + Storing fixed-length files into a zip file is simple, because all + the data can just be dumped into the zip file and the record + format (RECFM) and logical record length (LRECL) can be stored + in the extra data area of the zip file so they can be restored + when UNZIP is used. + + Storing variable-length data is harder. There is no place to put + the record length data needed for each record of the file. This + data could be written to the zip file as the first two bytes of + each record and interpreted that way by UNZIP. That would make + the data unusable on systems other than CMS and MVS, though. + + Currently, there isn't a solution to this problem. Each record is + written to the zip file and the record length information is + discarded. Binary data stored in variable-length files can't be put + into a zip file then later unzipped back into the proper records. + This is fine for binary data that will be read as a stream of bytes + but not OK where the records matter, such as with CMS MODULEs. + + If the data is text (character data), there is a solution. + This data can be converted into ASCII when it's stored into + a zip file. The end of each record is now marked in the file + by new line characters. Another advantage of this method is + that the data is now accessible to non-EBCDIC systems. When + the data is unzipped on CMS or MVS, it is converted back into + EBCDIC and the records are recreated into a variable-length file. + + + So, here's what we have... + + a. To store readable text data into a zip file that can be used + on other platforms, use the -a option with ZIP to convert the + data to ASCII. These files will unzip into variable-length + files on CMS and should not contain binary data or corruption + may occur. + + b. Files that were zipped on an ASCII-based system will be + automatically translated to EBCDIC when unzipped. To prevent + this (to unzip binary data on CMS that was sent from an + ASCII-based system), use the -B option with UNZIP to force Binary + mode. To zip binary files on CMS, use the -B option with ZIP to + force Binary mode. This will prevent any data conversions from + taking place. + + c. When using the ZIP program without specifying the "-a" or "-B" + option, ZIP defaults to "native" (EBCDIC) mode and tries to + preserve the file information (RECFM, LRECL, and BLKSIZE). So + when you unzip a file zipped with ZIP under CMS or MVS, UNZIP + restores the file info. The output will be fixed-length if the + original was fixed and variable-length if the original was + variable. + + If UNZIP gives a "write error (disk full?)" message, you may be + trying to unzip a binary file that was zipped as a text file + (without using the -B option) + + + Summary + ------- + Here's how to ZIP the different types of files. + + RECFM F text + Use the -a option with ZIP to convert to ASCII for use with other + platforms or no options for use on EBCDIC systems only. + + RECFM V text + Use the -a option with ZIP to convert to ASCII for use with other + platforms or no options for use on EBCDIC systems only. + + + RECFM F binary + Use the -B option with ZIP (upper-case "B"). + + RECFM V binary + Use the -B option with ZIP. Can be zipped OK but the record + structure is destroyed when unzipped. This is OK for data files + read as binary streams but not OK for files such as CMS MODULEs. + + + 6. Character Sets + + If you are used to running UNZIP on systems like UNIX, DOS, OS/2 or + Windows, you will may have some problems with differences in the + character set. + + There are a number of different EBCDIC code pages, like there are a + number of different ASCII code pages. For example, there is a US + EBCDIC, a German EBCDIC, and a Swedish EBCDIC. As long as you are + working with other people who use the same EBCDIC code page, you + will have no trouble. If you work with people who use ASCII, or who + use a different EBCDIC code page, you may need to do some + translation. + + UNZIP translates ASCII text files to and from Open Systems EBCDIC + (IBM-1047), which may not be the EBCDIC that you are using. For + example, US EBCDIC (IBM-037) uses different character codes for + square brackets. In such cases, you can use the ICONV utility + (supplied with IBM C) to translate between your EBCDIC character set + and IBM-1047. + + If your installation does not use IBM-1047 EBCDIC, messages from + UNZIP may look a little odd. For example, in a US EBCDIC + installation, an opening square bracket will become an i-acute and a + closing square bracket will become a u-grave. + + The supplied ZIP and UNZIP EXECs attempt to correct this by setting + CMS INPUT and OUTPUT translations to adjust the display of left and + right brackets. You may need to change this if brackets don't + display correctly on your system. + + + 7. You can unzip using VM/CMS PIPELINES so unzip can be used as + a pipeline filter. Example: + 'PIPE COMMAND UNZIP -p test.zip george.test | Count Lines | Cons' + + + + +Please report all bugs and problems to: + Zip-Bugs@lists.wku.edu + + +----------------------------------------------------------------------- +Original CMS/MVS port by George Petrov. +e-mail: c888090@nlevdpsb.snads.philips.nl +tel: +31-40-781155 + +Philips C&P +Eindhoven +The Netherlands + +----------------------------------------------------------------------- +Additional fixes and README re-write (4/98) by Greg Hartwig. +e-mail: ghartwig@ix.netcom.com + ghartwig@vnet.ibm.com + +----------------------------------------------------------------------- +Additional notes from Ian E. Gorman. +e-mail: ian@iosphere.net + diff --git a/cmsmvs/README.MVS b/cmsmvs/README.MVS new file mode 100644 index 0000000..4d451db --- /dev/null +++ b/cmsmvs/README.MVS @@ -0,0 +1,92 @@ +Thank you for trying this first port of ZIP for VM/CMS and MVS! + + + Using under MVS: + --------------------------- + +1. To use the Info-ZIP's ZIP under MVS you need: + + - C/370 ver 2.1 compiler or another compatible compiler supporting + long names for function/variable names. + +2. To compile the program under MVS do : + + - unzip all the files from zip22.zip file. They are stored as + ASCII format so you have to unzip them first on PC or other + system that already have UNZIP, and then upload them to the + mainframe with ASCII to EBCDIC conversion. + + - Copy all the .C files in the PDS called youruserid.ZIP.C + + - Copy all the .H files in the PDS called youruserid.ZIP.H + + - adjust the job ZIPMVSC.JOB to work on your size. Change my + userid - C888090 to yours + + - execute the job ZIPMVSC to compile and link all the sources. + + - maybe you have to preallocate PDS datasets named: + youruserid.ZIP.OBJ and youruserid.ZIP.LOAD + + - execute ZIPVMC to compile and link all the sources. + + - if everything is ok you will get an ZIP MODULE + + - the warnings about the duplicated ASCII and EBCDIC symbols + are OK :-) + +3. Using ZIP + + - Just read MANUAL + + - A few exceptions concerning MVS + + 3.1. if you want to make a portable zip file that is to be unzipped + on ASCII based systems use the -a option + + 3.2. If you want to zip the input files as binary ebcdic files + use the -B (capital letter) option + + 3.3. The date/end the time of the input files is set in the zip's + dir to the current system date/time + + 3.4. Without specifying the "-a" or "-B" option, the ZIP program + defaults to "native" (EBCDIC) mode and tries to preserve the + file information (LRECL,BLKSIZE..) + So when you UNZIP a file zipped with ZIP under VM/MVS it + restores the file info. + + There currently some problems with file with RECFM=V* + I don't save the length of each record yet :-) + + 3.5. No wildcards are supported as input file names: + + So you CAN'T use things like: zip myzip *.c + + 3.6. You can use DD names for zipfilename for example: + + under tso/rexx: + + "alloc fi(input) da('myzip.zip')" + "zip dd:input file1.txt file2.txt ..." + + under Batch: + + //MYZIP JOB (account) + //STEP1 EXEC PGM=ZIP,PARM='dd:input file1.txt file2.txt' + //STEPLIB DD DSN=userid.UNZIP.LOAD,DISP=SHR + //INPUT DD DSN=userid.MYZIP.ZIP,DISP=NEW, + // SPACE=(15000,(15000,10000),RLSE), + // DCB=(LRECL=80,RECFM=F) + //SYSPRINT DD SYSOUT=* + + +Please report all bugs and problems to : + zip-bugs@lists.wku.edu + +That's all for now. + +Have fun! + + +George Petrov diff --git a/cmsmvs/README.MVS.LE b/cmsmvs/README.MVS.LE new file mode 100644 index 0000000..f7dcb8a --- /dev/null +++ b/cmsmvs/README.MVS.LE @@ -0,0 +1,286 @@ +Notes on Zip under MVS Language Environment (LE). + +First see README.MVS. This note describes just one beta test on OS/390 +V2R5 using IBM's C compiler (5647A01), V2R4. The major difference is +the use of LE on the beta site, together with some MVS native mode +fixes. Changes have not been tested on CMS. + +Some of the notes are to clarify things that were not clear from the +MANUAL or README.MVS. + +1. By default, IBM C generates the same csect name for each input + source. The prelink stage does not rename them and the linkage + editor throws away all but the first occurrence of each duplicate. + Oops, my code just disappeared :(. + + To get around this "feature", compile with the CSECT option to + force sensible names on the code and data sections of each csect. + The name of the static data csect defaults to the source name in + lower case, the code csect defaults to the source name in upper + case. These csect names still have to be unique, they cannot be + the same as function names. Of course, several csects have a + function which is the same name as the source in lower case, not + exactly an unusual occurrence. Therefore to make the csect name + unique, some of the sources have + + #ifdef MVS + # pragma csect(STATIC,xxxx_s) + #endif + + Where xxxx is an abbreviation of the source name. There has to be + a better way! + +2. The prelink step always gets cond code 4. It complains about + unresolved references, ignore it unless the linker also complains. + Prelink also complains about duplicate @@PPA2 sections and so does + the linker, but it seems to do no harm. Compile and link steps + should get 0, just prelink gets 4. See JCL at the bottom. + +3. Under MVS native mode (not Open Edition), tmpnam() returns a quoted + name of 5 qualifiers. The first is a HLQ chosen according to the + MVS LE algorithm (see below), the other qualifiers are time stamps. + If running on MVS and tmpnam() returns a quoted name with at leat + one '.', it is only safe to let the user change the high level + qualifier. Therefore -b insists on a single qualifier without '.' + in the MVS native environment. + +4. In Open Edition (OE) mode, the manual says that tmpnam() returns a + fully qualified name in directory TMPDIR or /tmp if TMPDIR is not + set. There is no point in zip trying to override that name so -b + is ignored in MVS OE mode (untested). The user should specify + environment variable TMPDIR instead. + +5. The MVS LE algorithm for choosing the high level qualifier for + native filenames is interesting, as in "May you live in interesting + times". The HLQ varies according to the environment the program is + running in, sometimes it is userid, sometimes it is TSO prefix. + See OS/390 C/C++ Programming Guide, Using a Data Set Name, + somewhere around section 2.9. + + If in doubt, use fully qualified and quoted names. Instead of + archive.zip, use 'prefix.archive.zip'. For input files, instead of + filename, use 'prefix.filename'. For PARM= in JCL, double up the + quotes. You even have to quote filenames in stdin. + +6. If your PARM includes any '/', make sure the PARM starts with '/'. + LE assumes anything before the first '/' is LE run time parameters. + It does no harm to always code a leading '/' for LE parms. + +7. JCL limits a PARM= to 100 characters total with approx. 65 on a + single line. Alas the syntax for continuing PARM= always embeds an + extra ',' somewhere in the parameters that the program finally + gets. No workaround, limit your PARM to a single line. With the + extra quotes around filenames, that does not leave much room. In + most cases, you will have to use '-@' to read the list of filenames + from SYSIN (stdin), it will not fit on a single PARM line. + +8. Filenames can be dataset names or you can refer to a ddname with + 'DD:name', case insensitive for external files, case sensitive for + OE files. You can even specify 'dd:name(mem)'. No wildcards, to + zip a complete pds you have to specify each member individually. + Directory recursion in OE does not appear to work at the moment. + +9. Zip attempts to map MVS filenames to Unix style names. It did not + work correctly for quoted names, fixed. Although you can pick up + an external (non-OE) file with a name using any case, be aware that + the mapping to a Unix style name faithfully follows the case you + supply. + +10. The archive file was being created with recfm=V and lrecl=32760. + 32760 is not valid for recfm=V under MVS, I originally changed it + to lrecl=32756. Then zip broke trying to fseek() over a record + boundary, I do not know whether this was a zip or LE bug. Trial + and error showed that recfm=U with byteseek seems to work on MVS. + No BDW or RDW, just a byte stream. The blocksize is always 6144. + + NOTE: This is an incompatible change from the previous beta, + archive files used to be recfm=V. That should not matter + because we just transfer the data, ignoring BDW and RDW + anyway. + +11. Zip used to complain about preallocated but empty archives, wrong + length records, no signature etc. The usual IBM/360 problem of no + end of file marker in a new, unopened dataset. Fixed, see routine + readzipfile in zipfile.c for the gory details. PARM= works fine. + +12. Several source files have records that are more than 80 bytes long. + It works if you transfer to mainframe datasets with a larger lrecl, + I used recfm=fb,lrecl=120 for the .C and .H files. To compile with + anything longer than 72 bytes, you need MVS C options NOMARGINS and + NOSEQUENCE (NOMAR,NOSEQ). + +13. cmsmvs was still using zname instead of name for open. Fixed. + +14. zip has to jump through a lot of hoops to see if an existing + zipfile actually contains data. A side effect of this is that + creating a zipfile with the RLSE parameter is a waste of time. + +Keith Owens . Not a maintainer, just a beta tester. +Mon Sep 14 19:31:30 EST 1998 + + +Sample JCL to compile Zip under MVS LE. You might need a large region, +I used REGION=128M on the job card. Also watch the output lines, +75,000 with OPT(2), 100,000+ with OPT(2) replaced with DEF(DEBUG). You +need to allocate prefix.ZIP.C.OBJ (recfm=FB, lrecl=80) and +prefix.ZIP.LOAD (recfm=U, blksize is site defined). + +//CBC JCLLIB ORDER=CBC.SCBCPRC +//ZIP EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(ZIP)', +// OUTFILE='prefix.ZIP.C.OBJ(ZIP),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//CRYPT EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(CRYPT)', +// OUTFILE='prefix.ZIP.C.OBJ(CRYPT),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//TTYIO EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(TTYIO)', +// OUTFILE='prefix.ZIP.C.OBJ(TTYIO),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//TREES EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(TREES)', +// OUTFILE='prefix.ZIP.C.OBJ(TREES),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//DEFLATE EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(DEFLATE)', +// OUTFILE='prefix.ZIP.C.OBJ(DEFLATE),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//FILEIO EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(FILEIO)', +// OUTFILE='prefix.ZIP.C.OBJ(FILEIO),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//GLOBALS EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(GLOBALS)', +// OUTFILE='prefix.ZIP.C.OBJ(GLOBALS),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//UTIL EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(UTIL)', +// OUTFILE='prefix.ZIP.C.OBJ(UTIL),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//CRC32 EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(CRC32)', +// OUTFILE='prefix.ZIP.C.OBJ(CRC32),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//CRCTAB EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(CRCTAB)', +// OUTFILE='prefix.ZIP.C.OBJ(CRCTAB),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//ZIPFILE EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(ZIPFILE)', +// OUTFILE='prefix.ZIP.C.OBJ(ZIPFILE),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//ZIPUP EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(ZIPUP)', +// OUTFILE='prefix.ZIP.C.OBJ(ZIPUP),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//CMSMVS EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(CMSMVS)', +// OUTFILE='prefix.ZIP.C.OBJ(CMSMVS),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//MVS EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(MVS)', +// OUTFILE='prefix.ZIP.C.OBJ(MVS),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//PLINK EXEC PROC=EDCPL, +// OUTFILE='prefix.ZIP.LOAD(ZIP),DISP=SHR', +// PREGSIZ=6M, +// PPARM='NONCAL,MAP,MEMORY', +// LPARM='LIST,MAP,XREF' +//PLKED.SYSIN DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(ZIP) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(CRYPT) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(TREES) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(DEFLATE) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(FILEIO) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(GLOBALS) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(UTIL) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(CRC32) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(CRCTAB) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(ZIPFILE) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(ZIPUP) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(MVS) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(CMSMVS) +//LKED.SYSLIB DD DISP=SHR,DSN=CEE.SCEELKED +//SYSUT1 DD UNIT=SYSDA,SPACE=(CYL,(2,2)) +// + +Sample JCL to zip the mainframe .C and .H files as ASCII (-a). Delete +any existing archive first, point the temporary file at a particular +prefix (-b), use 'prefix.ARCHIVE.ZIP' for the archive file, read the +list of files to zip from stdin (SYSIN). + +//DELETE EXEC PGM=IDCAMS +//SYSPRINT DD SYSOUT=* +//SYSIN DD * + DELETE prefix.ARCHIVE.ZIP + SET MAXCC = 0 +//ZIP EXEC PGM=ZIP, +// PARM='/-a -v -b temppref ''prefix.ARCHIVE.ZIP'' -@' +//STEPLIB DD DSN=prefix.ZIP.LOAD,DISP=SHR +//SYSPRINT DD SYSOUT=* +//SYSOUT DD SYSOUT=* +//CEEDUMP DD SYSOUT=* +//ZIPC DD DISP=SHR,DSN=prefix.ZIP.C +//ZIPH DD DISP=SHR,DSN=prefix.ZIP.H +//SYSIN DD * +dd:zipc(api) +dd:zipc(cms) +dd:zipc(cmsmvs) +dd:zipc(crctab) +dd:zipc(crc32) +dd:zipc(crypt) +dd:zipc(deflate) +dd:zipc(fileio) +dd:zipc(globals) +dd:zipc(mktime) +dd:zipc(mvs) +dd:zipc(trees) +dd:zipc(ttyio) +dd:zipc(util) +dd:zipc(zip) +dd:zipc(zipcloak) +dd:zipc(zipfile) +dd:zipc(zipnote) +dd:zipc(zipsplit) +dd:zipc(zipup) +dd:ziph(api) +dd:ziph(cmsmvs) +dd:ziph(crypt) +dd:ziph(cstat) +dd:ziph(ebcdic) +dd:ziph(mvs) +dd:ziph(revision) +dd:ziph(stat) +dd:ziph(tailor) +dd:ziph(ttyio) +dd:ziph(zip) +dd:ziph(ziperr) +dd:ziph(zipup) diff --git a/cmsmvs/cczip.exec b/cmsmvs/cczip.exec new file mode 100644 index 0000000..86edb59 --- /dev/null +++ b/cmsmvs/cczip.exec @@ -0,0 +1,123 @@ +/* CCZIP EXEC Compile zip for VM/CMS */ +/* Author: George Petrov, 11 Apr 1995 (VMCOMPIL EXEC) */ +/* Modified for IBM C V3R1 by Ian E. Gorman, 2 Nov 1998 + Facilities for compiling and testing were provided by + OmniMark Technologies Corporation, Ottawa, Canada +*/ +Address Command +Signal On Error + +/* Allow longnames, compile re-entrant code. + globals.c and cmsmvs.c require EXTENDED features */ +CCopts = 'LONGNAME RENT LANGLVL(EXTENDED) NOEXECOPS' + +/* ZIP options -- VM_CMS, REENTRANT */ +CCopts = CCopts 'DEFINE(VM_CMS,REENTRANT)' + +/* Link the load module to run in more or less than 16MB memory */ +LINKopts = 'AMODE ANY RMODE ANY RLDSAVE' + +/* resources needed to build */ +'GLOBAL TXTLIB SCEELKED CMSLIB' +'GLOBAL LOADLIB SCEERUN' + +/* produce the TEXT (object) files */ +linklist='' +modname='ZIP' +Say 'Building' modname 'MODULE...' +Call Compile 'ZIP' +Call Compile 'CRC32' +Call Compile 'CRYPT' +Call Compile 'DEFLATE' +Call Compile 'FILEIO' +Call Compile 'GLOBALS' +Call Compile 'TREES' +Call Compile 'TTYIO' +Call Compile 'UTIL' +Call Compile 'ZIPUP' +Call Compile 'ZIPFILE' +Call Compile 'CMSMVS' +Call Compile 'CMS' + +Say 'Linking...' +'EXEC CMOD' linklist '(MODNAME' modname LINKopts +Say modname 'built successfully.' + + +/*---------------------------------------------------------------------*/ +/* Build utility programs */ +/*---------------------------------------------------------------------*/ +CCopts = CCopts 'DEFINE(UTIL)' + + +linklist='' +modname='ZIPNOTE' +Say +Say 'Building' modname 'MODULE...' +Call Compile 'ZIPNOTE' +Call Compile 'ZIPFILE' +Call Compile 'FILEIO' +Call Compile 'UTIL' +Call Compile 'GLOBALS' +Call Compile 'CMSMVS' + +Say 'Linking...' +'EXEC CMOD' linklist '(MODNAME' modname LINKopts +Say modname 'built successfully.' + + +linklist='' +modname='ZIPSPLIT' +Say +Say 'Building' modname 'MODULE...' +Call Compile 'ZIPSPLIT' +Call Compile 'ZIPFILE' +Call Compile 'FILEIO' +Call Compile 'UTIL' +Call Compile 'GLOBALS' +Call Compile 'CMSMVS' + +Say 'Linking...' +'EXEC CMOD' linklist '(MODNAME' modname LINKopts +Say modname 'built successfully.' + + +linklist='' +modname='ZIPCLOAK' +Say +Say 'Building' modname 'MODULE...' +Call Compile 'ZIPCLOAK' +Call Compile 'ZIPFILE' +Call Compile 'FILEIO' +Call Compile 'UTIL' +Call Compile 'GLOBALS' +Call Compile 'CRC32' +Call Compile 'CRYPT' +Call Compile 'TTYIO' +Call Compile 'CMSMVS' + +Say 'Linking...' +'EXEC CMOD' linklist '(MODNAME' modname LINKopts +Say modname 'built successfully.' +Say 'Done.' + +Exit rc + + + +error: + Say 'Error' rc 'during compilation!' + Say 'Error in line' sigl':' + Say ' 'Sourceline(sigl) + Exit rc + + + +Compile: Procedure Expose CCopts LINKopts linklist + Parse arg filename filetype filemode . + If filetype='' Then filetype='C' + linklist = linklist filename + + Say 'Compiling' filename filetype filemode '...' + 'EXEC CC' filename filetype filemode '('CCopts + Return rc diff --git a/cmsmvs/cms.c b/cmsmvs/cms.c new file mode 100644 index 0000000..e69f5cb --- /dev/null +++ b/cmsmvs/cms.c @@ -0,0 +1,34 @@ +/* + 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 +*/ +/* + * VM/CMS specific things. + */ + +#include "zip.h" + +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. */ +{ + FILE *stream; + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0, caseflag); + else { + if ((stream = fopen(n, "r")) != (FILE *)NULL) + { + fclose(stream); + return newname(n, 0, caseflag); + } + else return ZE_MISS; + } + return ZE_OK; +} diff --git a/cmsmvs/cmsmvs.c b/cmsmvs/cmsmvs.c new file mode 100644 index 0000000..9c56de7 --- /dev/null +++ b/cmsmvs/cmsmvs.c @@ -0,0 +1,442 @@ +/* + 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 +*/ +/* + * routines common to VM/CMS and MVS + */ + +#include "zip.h" + +#include +#include +#include + +#ifndef MVS /* MVS has perfectly good definitions of the following */ +int stat(const char *path, struct stat *buf) +{ + if ((buf->fp = fopen(path, "r")) != NULL) { + fldata_t fdata; + if (fldata( buf->fp, buf->fname, &fdata ) == 0) { + buf->st_dev = fdata.__device; + buf->st_mode = *(short *)(&fdata); + } + strcpy( buf->fname, path ); + fclose(buf->fp); + } + return (buf->fp != NULL ? 0 : 1); +} +#endif /* MVS */ + + +#ifndef UTIL /* the companion #endif is a bit of ways down ... */ + +#define PAD 0 +#define PATH_END '/' + +/* Library functions not in (most) header files */ + +#ifdef USE_ZIPMAIN +int main OF((void)); +#endif + +int utime OF((char *, ztimbuf *)); + +extern char *label; +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +#ifndef MVS /* MVS has perfectly good definitions of the following */ +int fstat(int fd, struct stat *buf) +{ + fldata_t fdata; + + if ((fd != -1) && (fldata( (FILE *)fd, buf->fname, &fdata ) == 0)) { + buf->st_dev = fdata.__device; + buf->st_mode = *(short *)(&fdata); + buf->fp = (FILE *)fd; + return 0; + } + return -1; +} +#endif /* MVS */ + + +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; + char mem[10] = ""; /* member name */ + char ext[10] = ""; /* extension name */ + + dosflag = dosify; /* default for non-DOS non-OS/2 */ + + /* Find starting point in name before doing malloc */ + for (t = x; *t == '/'; t++) + ; + + /* Make changes, if any, to the copied name (leave original intact) */ + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + +#ifdef MVS + /* strip quotes from name, non-OE format */ + if (*n == '\'' && (t = strrchr(n, '\'')) != n) { + if (!*(t+1)) { + /* yes, it is a quoted name */ + int l = strlen(n) - 2; + memmove(n, n+1, l); + *(n+l) = '\0'; + } + } + /* Change member names to fn.ext */ + if (t = strrchr(n, '(')) { + *t = '\0'; + strcpy(mem,t+1); /* Save member name */ + if (t = strchr(mem, ')')) *t = '\0'; /* Set end of mbr */ + /* Save extension */ + if (t = strrchr(n, '.')) t++; + else t = n; + strcpy(ext,t); + /* Build name as "member.ext" */ + strcpy(t,mem); + strcat(t,"."); + strcat(t,ext); + } + + /* Change all but the last '.' to '/' */ + if (t = strrchr(n, '.')) { + while (--t > n) + if (*t == '.') + *t = '/'; + } +#else + /* On CMS, remove the filemode (all past 2nd '.') */ + if (t = strchr(n, '.')) + if (t = strchr(t+1, '.')) + *t = '\0'; + t = n; +#endif + + strcpy(n, t); + + if (isdir == 42) return n; /* avoid warning on unused variable */ + + if (dosify) + msname(n); /* msname() needs string in native charset */ + + strtoasc(n, 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; + strtoebc(x, n); + return x; +} + + +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ + ztimbuf u; /* argument for utime() */ + + /* Convert DOS time to time_t format in u.actime and u.modtime */ + 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 */ +{ + FILE *stream; + time_t ltime; + + if (strcmp(f, "-") != 0) { /* if not compressing stdin */ + Trace((mesg, "opening file '%s' with '%s'\n", f, FOPR)); + if ((stream = fopen(f, FOPR)) == (FILE *)NULL) { + return 0; + } else { + if (n != NULL) { + /* With byteseek, this will work */ + fseek(stream, 0L, SEEK_END); + *n = ftell(stream); + Trace((mesg, "file size = %lu\n", *((ulg *)n))); + } + fclose(stream); + } + } + else { + /* Reading from stdin */ + if (n != NULL) { + *n = -1L; + } + } + + /* Return current time for all the times -- for now */ + time(<ime); + if (t != NULL) + t->atime = t->mtime = t->ctime = ltime; + + /* Set attributes (always a file) */ + if (a != NULL) + *a = 0; + + return unix2dostime(<ime); +} + + + +int set_extra_field(z, z_utim) +struct zlist far *z; +iztimes *z_utim; +/* create extra field and change z->att if desired */ +{ + fldata_t fdata; + FILE *stream; + char *eb_ptr; +#ifdef USE_EF_UT_TIME + extent ef_l_len = (EB_HEADSIZE+EB_UT_LEN(1)); +#else /* !USE_EF_UT_TIME */ + extent ef_l_len = 0; +#endif /* ?USE_EF_UT_TIME */ + int set_cmsmvs_eb = 0; + +/*translate_eol = 0;*/ + if (aflag == ASCII) { + z->att = ASCII; + } else { + if (bflag) + z->att = BINARY; + else + z->att = __EBCDIC; + ef_l_len += sizeof(fdata)+EB_HEADSIZE; + set_cmsmvs_eb = 1; + } + + if (ef_l_len > 0) { + z->extra = (char *)malloc(ef_l_len); + if (z->extra == NULL) { + printf("\nFLDATA : Unable to allocate memory !\n"); + return ZE_MEM; + } + z->cext = z->ext = ef_l_len; + eb_ptr = z->cextra = z->extra; + + if (set_cmsmvs_eb) { + if (bflag) +/*** stream = fopen(z->zname,"rb,type=record"); $RGH$ ***/ + stream = fopen(z->name,"rb"); + else + stream = fopen(z->name,"r"); + if (stream == NULL) { + printf("\nFLDATA : Could not open file : %s !\n",z->name); + printf("Error %d: '%s'\n", errno, strerror(errno)); + return ZE_NONE; + } + + fldata(stream,z->name,&fdata); + /*put the system ID */ +#ifdef VM_CMS + *(eb_ptr) = EF_VMCMS & 0xFF; + *(eb_ptr+1) = EF_VMCMS >> 8; +#else + *(eb_ptr) = EF_MVS & 0xFF; + *(eb_ptr+1) = EF_MVS >> 8; +#endif + *(eb_ptr+2) = sizeof(fdata) & 0xFF; + *(eb_ptr+3) = sizeof(fdata) >> 8; + + memcpy(eb_ptr+EB_HEADSIZE,&fdata,sizeof(fdata)); + fclose(stream); +#ifdef USE_EF_UT_TIME + eb_ptr += (sizeof(fdata)+EB_HEADSIZE); +#endif /* USE_EF_UT_TIME */ + } +#ifdef USE_EF_UT_TIME + eb_ptr[0] = 0x55; /* ascii[(unsigned)('U')] */ + eb_ptr[1] = 0x54; /* ascii[(unsigned)('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); +#endif /* USE_EF_UT_TIME */ + } + + return ZE_OK; +} + +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 0; +} + +#ifdef USE_ZIPMAIN +/* This function is called as main() to parse arguments */ +/* into argc and argv. This is required for stand-alone */ +/* execution. This calls the "real" main() when done. */ + +int main(void) + { + int argc=0; + char *argv[50]; + + int iArgLen; + char argstr[256]; + char **pEPLIST, *pCmdStart, *pArgStart, *pArgEnd; + + /* Get address of extended parameter list from S/370 Register 0 */ + pEPLIST = (char **)__xregs(0); + + /* Null-terminate the argument string */ + pCmdStart = *(pEPLIST+0); + pArgStart = *(pEPLIST+1); + pArgEnd = *(pEPLIST+2); + iArgLen = pArgEnd - pCmdStart + 1; + + /* Make a copy of the command string */ + memcpy(argstr, pCmdStart, iArgLen); + argstr[iArgLen] = '\0'; /* Null-terminate */ + + /* Store first token (cmd) */ + argv[argc++] = strtok(argstr, " "); + + /* Store the rest (args) */ + while (argv[argc-1]) + argv[argc++] = strtok(NULL, " "); + argc--; /* Back off last NULL entry */ + + /* Call "real" main() function */ + return zipmain(argc, argv); + +} +#endif /* USE_ZIPMAIN */ + +#endif /* !UTIL */ + + +/******************************/ +/* Function version_local() */ +/******************************/ + +void version_local() +{ + char liblvlmsg [50+1]; + char *compiler = "?"; + char *platform = "?"; + char complevel[64]; + + /* Map the runtime library level information */ + union { + unsigned int iVRM; + struct { + unsigned int pd:4; /* Product designation */ + unsigned int vv:4; /* Version */ + unsigned int rr:8; /* Release */ + unsigned int mm:16; /* Modification level */ + } xVRM; + } VRM; + + + /* Break down the runtime library level */ + VRM.iVRM = __librel(); + sprintf(liblvlmsg, "Using runtime library level %s V%dR%dM%d", + (VRM.xVRM.pd==1 ? "LE" : "CE"), + VRM.xVRM.vv, VRM.xVRM.rr, VRM.xVRM.mm); + /* Note: LE = Language Environment, CE = Common Env. (C/370). */ + /* This refers ONLY to the current runtimes, not the compiler. */ + + +#ifdef VM_CMS + platform = "VM/CMS"; + #ifdef __IBMC__ + compiler = "IBM C"; + #else + compiler = "C/370"; + #endif +#endif + +#ifdef MVS + platform = "MVS"; + #ifdef __IBMC__ + compiler = "IBM C/C++"; + #else + compiler = "C/370"; + #endif +#endif + +#ifdef __COMPILER_VER__ + VRM.iVRM = __COMPILER_VER__; + sprintf(complevel," V%dR%dM%d", + VRM.xVRM.vv, VRM.xVRM.rr, VRM.xVRM.mm); +#else +#ifdef __IBMC__ + sprintf(complevel," V%dR%d", __IBMC__ / 100, (__IBMC__ % 100)/10); +#else + complevel[0] = '\0'; +#endif +#endif + + + printf("Compiled with %s%s for %s%s%s.\n\n", + + /* Add compiler name and level */ + compiler, complevel, + + /* Add platform */ + platform, + + /* Add timestamp */ +#ifdef __DATE__ + " on " __DATE__ +#ifdef __TIME__ + " at " __TIME__ +#endif +#endif + ".\n", + liblvlmsg + ); +} /* end function version_local() */ diff --git a/cmsmvs/cmsmvs.h b/cmsmvs/cmsmvs.h new file mode 100644 index 0000000..e2adb31 --- /dev/null +++ b/cmsmvs/cmsmvs.h @@ -0,0 +1,123 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/* Include file for VM/CMS and MVS */ + +/* This is normally named osdep.h on most systems. Since CMS */ +/* generally doesn't support directories, it's been given a unique */ +/* name to avoid confusion. */ + + +#ifndef __cmsmvs_h /* prevent multiple inclusions */ +#define __cmsmvs_h + +#ifdef MVS +# define _POSIX_SOURCE /* tell MVS we want full definitions */ +# include +#endif /* MVS */ + +#include /* the usual non-BSD time functions */ +/* cstat.h is not required for MVS and actually gets in the way. Is it + * needed for CMS? + */ +#ifdef MVS +# include +# include +#else /* !MVS */ +# include "cstat.h" +#endif + + +/* Newer compiler version defines something for us */ +#if defined(__VM__) && !defined(VM_CMS) +# define VM_CMS +#endif + +#define CMS_MVS +#define EBCDIC + +#ifndef MVS /* MVS has perfectly good definitions for the following */ +# define NO_UNISTD_H +# define NO_FCNTL_H +#endif /*MVS */ + +/* If we're generating a stand-alone CMS module, patch in */ +/* a new main() function before the real main() for arg parsing. */ +#ifdef CMS_STAND_ALONE +# define USE_ZIPMAIN +#endif + +#ifndef NULL +# define NULL 0 +#endif + +#define PASSWD_FROM_STDIN + /* Kludge until we know how to open a non-echo tty channel */ + +/* definition for ZIP */ +#define getch() getc(stdin) +#define MAXPATHLEN 128 +#define NO_RMDIR +#define NO_MKTEMP +#define USE_CASE_MAP +#define isatty(t) 1 + +#ifndef MVS /* MVS has perfectly good definitions for the following */ +# define fileno(x) (char *)(x) +# define fdopen fopen +# define unlink remove +# define link rename +# define utime(f,t) +#endif /*MVS */ +#ifdef ZCRYPT_INTERNAL +# define ZCR_SEED2 (unsigned)3141592654L /* use PI as seed pattern */ +#endif + +#ifdef MVS +# if defined(__CRC32_C) +# pragma csect(STATIC,"crc32_s") +# elif defined(__DEFLATE_C) +# pragma csect(STATIC,"deflat_s") +# elif defined(__ZIPFILE_C) +# pragma csect(STATIC,"zipfil_s") +# elif defined(__ZIPUP_C) +# pragma csect(STATIC,"zipup_s") +# endif +#endif /* MVS */ + +/* end defines for ZIP */ + + + +#if 0 /*$RGH$*/ +/* RECFM=F, LRECL=1 works for sure */ +#define FOPR "rb,recfm=fb" +#define FOPM "r+" +#define FOPW "wb,recfm=fb,lrecl=1" +#define FOPWT "w" +#endif + +/* Try allowing ZIP files to be RECFM=V with "byteseek" for CMS, recfm=U for MVS */ +#define FOPR "rb,byteseek" +#define FOPM "r+,byteseek" +#ifdef MVS + #define FOPW "wb,recfm=u,byteseek" +#else /* !MVS */ + #define FOPW "wb,recfm=v,lrecl=32760,byteseek" +#endif /* MVS */ + +#if 0 +#define FOPW_TMP "w,byteseek" +#else +#define FOPW_TMP "w,type=memory(hiperspace)" +#endif + +#define CBSZ 0x40000 +#define ZBSZ 0x40000 + +#endif /* !__cmsmvs_h */ diff --git a/cmsmvs/cstat.h b/cmsmvs/cstat.h new file mode 100644 index 0000000..f02a5c3 --- /dev/null +++ b/cmsmvs/cstat.h @@ -0,0 +1,53 @@ +/* + 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 +*/ +/* cstat.h + + Definitions used for file status functions + +*/ + +#ifndef __STAT_H +#define __STAT_H + +#include + +#define S_IFMT 0xF000 /* file type mask */ +#define S_IFDIR 0x4000 /* directory */ +#define S_IFIFO 0x1000 /* FIFO special */ +#define S_IFCHR 0x2000 /* character special */ +#define S_IFBLK 0x3000 /* block special */ +#define S_IFREG 0x8000 /* or just 0x0000, regular */ +#define S_IREAD 0x0100 /* owner may read */ +#define S_IWRITE 0x0080 /* owner may write */ +#define S_IEXEC 0x0040 /* owner may execute */ + +struct stat +{ + short st_dev; /* Drive number of disk containing the */ + /* file or file handle if the file is */ + /* on device */ + short st_ino; /* Not meaningfull for VM/CMS */ + short st_mode; /* Bit mask giving information about */ + /* the file's mode */ + short st_nlink; /* Set to the integer constant 1 */ + int st_uid; /* Not meaningfull for VM/CMS */ + int st_gid; /* Not meaningfull for VM/CMS */ + short st_rdev; /* Same as st_dev */ + long st_size; /* Size of the file in bytes */ + long st_atime; /* Most recent access */ + long st_mtime; /* Same as st_atime */ + long st_ctime; /* Same as st_atime */ + FILE *fp; + char fname[FILENAME_MAX]; +}; + +int stat(const char *path, struct stat *sb); +int fstat(int fd, struct stat *sb); + +#endif /* __STAT_H */ diff --git a/cmsmvs/mc.exec b/cmsmvs/mc.exec new file mode 100644 index 0000000..ca22a18 --- /dev/null +++ b/cmsmvs/mc.exec @@ -0,0 +1,95 @@ +/* MAKECPIP EXEC Make program to build a C/370 module */ +/* Author: George Petrov, 29 Sep 1994 */ + +arg fn . '(' cparms /* Filter name */ +'pipe (end ?) < 'fn' makefile', /* get all source files from */ + '| frlab GLOBALS:'||, + '| drop', + '| strip', + '| var globals' +cparms = cparms globals +say '' +say 'Compile options : 'cparms +say '' +if pos('REB',cparms) > 0 then do +parse var cparms cp1 'REB' . ' ' cp2 /* REBuild options specified ? */ +cparms = cp1||cp2 +pipe1=, +'pipe (end ?) < 'fn' makefile', /* get all source files from */ + '| nfind *'||, /* the makefile and compile */ + '| frlab TEXT:'||, /* only the those who are */ + '| r: tolab MODULE:'||, /* changed or never compiled */ + '| drop', + '| o: fanout', + '| chop before str /(/', + '| statew', + '| c: fanout', /* compiled */ + '| specs /Compiling / 1 w1-3 n / .../ n', + '| cons' +end +else do +pipe1=, +'pipe (end ?) < 'fn' makefile', /* get all source files from */ + '| nfind *'||, /* the makefile and compile */ + '| frlab TEXT:'||, /* only the those who are */ + '| r: tolab MODULE:'||, /* changed or never compiled */ + '| drop', + '| o: fanout', + '| specs w1 1 /C/ nw w3 nw write w1 1 /TEXT A/ nw', + '| chop before str /(/', + '| statew', + '| change (57 66) / /0/', + '| sort 1.8 d', /* sort the date and time */ + '| uniq 1-17 singles', /* if the first is a source */ + '| sort 1.8 d 64.2 d 57.2 d 60.2 d 66.8 d', /* sort the date */ + '| uniq 1-8 first', /* if the first is a source */ + '| locate 9.8 /C /', /* program then it has to be */ + '| c: fanout', /* compiled */ + '| specs /Compiling / 1 w1-3 n / .../ n', + '| cons' +end +pipe2= '?', + 'r:', + '| drop', + '| specs w1 1', /* save the module name in var */ + '| var module', + '?', + 'o:', + '| specs w1 1', + '| join * / /', + '| var texts', /* save all the text file names */ + '?', /* for later include */ + 'c:', + '| specs /CC / 1 w1-3 n /(NOTERM 'cparms'/ nw', /* compile! */ + '| err: cms | cons', + '?', + 'err:', + '| strip both', + '| nfind 0'||, + '| var err', + '| specs /----> Errors found! RC=/ 1 1-* n', + '| cons' +/* '| g: gate'*/ +pipe1 pipe2 +say '' +if symbol('err') = 'VAR' & err ^= 0 then do + say 'Errors found in source files - link aborted! RC = 'err + exit err +end +say 'Generating module 'module +'pipe cms cmod' fn texts' DMSCSL | > 'fn' LINK A' +'set cmstype ht' +'state 'fn' LINK A' +rcc = rc +'set cmstype rt' +if rcc = 0 then do + say '' + say 'ERRORS discovered during linking!' + say 'See: 'fn' LINK A for more info' +end +exit rc +error: +say 'Error in REXX detected!' +Say 'Syntax error on line' Sigl':' Sourceline(Sigl) +Say 'Error was:' Errortext(RC) +return rc diff --git a/cmsmvs/mvs.c b/cmsmvs/mvs.c new file mode 100644 index 0000000..d7f7437 --- /dev/null +++ b/cmsmvs/mvs.c @@ -0,0 +1,221 @@ +/* + 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 +*/ +/* + * MVS specific things + */ +#include "zip.h" +#include "mvs.h" +#include + +static int gen_node( DIR *dirp, RECORD *recptr ) +{ + char *ptr, *name, ttr[TTRLEN]; + int skip, count = 2; + unsigned int info_byte, alias, ttrn; + struct dirent *new; + + ptr = recptr->rest; + while (count < recptr->count) { + if (!memcmp( ptr, endmark, NAMELEN )) + return 1; + name = ptr; /* member name */ + ptr += NAMELEN; + memcpy( ttr, ptr, TTRLEN ); /* ttr name */ + ptr += TTRLEN; + info_byte = (unsigned int) (*ptr); /* info byte */ + if ( !(info_byte & ALIAS_MASK) ) { /* no alias */ + new = malloc( sizeof(struct dirent) ); + if (dirp->D_list == NULL) + dirp->D_list = dirp->D_curpos = new; + else + dirp->D_curpos = (dirp->D_curpos->d_next = new); + new->d_next = NULL; + memcpy( new->d_name, name, NAMELEN ); + new->d_name[NAMELEN] = '\0'; + if ((name = strchr( new->d_name, ' ' )) != NULL) + *name = '\0'; /* skip trailing blanks */ + } + skip = (info_byte & SKIP_MASK) * 2 + 1; + ptr += skip; + count += (TTRLEN + NAMELEN + skip); + } + return 0; +} + +DIR *opendir(const char *dirname) +{ + int bytes, list_end = 0; + DIR *dirp; + FILE *fp; + RECORD rec; + + fp = fopen( dirname, "rb" ); + if (fp != NULL) { + dirp = malloc( sizeof(DIR) ); + if (dirp != NULL) { + dirp->D_list = dirp->D_curpos = NULL; + strcpy( dirp->D_path, dirname ); + do { + bytes = fread( &rec, 1, sizeof(rec), fp ); + if (bytes == sizeof(rec)) + list_end = gen_node( dirp, &rec ); + } while (!feof(fp) && !list_end); + fclose( fp ); + dirp->D_curpos = dirp->D_list; + return dirp; + } + fclose( fp ); + } + return NULL; +} + +struct dirent *readdir(DIR *dirp) +{ + struct dirent *cur; + + cur = dirp->D_curpos; + dirp->D_curpos = dirp->D_curpos->d_next; + return cur; +} + +void rewinddir(DIR *dirp) +{ + dirp->D_curpos = dirp->D_list; +} + +int closedir(DIR *dirp) +{ + struct dirent *node; + + while (dirp->D_list != NULL) { + node = dirp->D_list; + dirp->D_list = dirp->D_list->d_next; + free( node ); + } + free( dirp ); + return 0; +} + +local char *readd(d) +DIR *d; /* directory stream to read from */ +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e; + + e = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; +} + +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 */ + int exists; /* 1 if file exists */ + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0, caseflag); + else if (!(exists = (LSSTAT(n, &s) == 0))) + { +#ifdef MVS + /* special case for MVS. stat does not work on non-HFS files so if + * stat fails with ENOENT, try to open the file for reading anyway. + * If the user has no OMVS segment, stat gets an initialization error, + * even on external files. + */ + if (errno == ENOENT || errno == EMVSINITIAL) { + FILE *f = fopen(n, "r"); + if (f) { + /* stat got ENOENT but fopen worked, external file */ + fclose(f); + exists = 1; + memset(&s, '\0', sizeof(s)); /* stat data is unreliable for externals */ + s.st_mode = S_IFREG; /* fudge it */ + } + } +#endif /* MVS */ + } + if (! exists) { + /* 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_ISDIR(s.st_mode)) + { + /* 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; +} diff --git a/cmsmvs/mvs.h b/cmsmvs/mvs.h new file mode 100644 index 0000000..b2f9760 --- /dev/null +++ b/cmsmvs/mvs.h @@ -0,0 +1,40 @@ +/* + 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 +*/ +/* definitions */ + +#define NAMELEN 8 + +struct dirent { + struct dirent *d_next; + char d_name[NAMELEN+1]; +}; + +typedef struct _DIR { + struct dirent *D_list; + struct dirent *D_curpos; + char D_path[FILENAME_MAX]; +} DIR; + +DIR * opendir(const char *dirname); +struct dirent *readdir(DIR *dirp); +void rewinddir(DIR *dirp); +int closedir(DIR *dirp); +char * readd(DIR *dirp); + +#define ALIAS_MASK (unsigned int) 0x80 +#define SKIP_MASK (unsigned int) 0x1F +#define TTRLEN 3 +#define RECLEN 254 + +typedef _Packed struct { + unsigned short int count; + char rest[RECLEN]; +} RECORD; + +char *endmark = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; diff --git a/cmsmvs/mvs.mki b/cmsmvs/mvs.mki new file mode 100644 index 0000000..316d064 --- /dev/null +++ b/cmsmvs/mvs.mki @@ -0,0 +1,125 @@ +# Makefile for the MVS (OS/390 Base) version of ZIP 2.3 +# Produced for C/C++ V3R2 in OS/390 1.2.0 by Ian E. Gorman, 2 Nov 1998 +# Facilities for compiling and testing were made available by +# OmniMark Technologies Corporation, Ottawa, Canada + +# NOTES +# +# The only tabs in this file are in the first character of each recipe +# line, where they are required by make. +# +# Run this makefile in OpenMVS (OS/390 POSIX) using source files in the +# HFS file system. You can write the load module to either HFS file +# system or to a PDS in the native MVS file system. The PDS must have +# sufficient free space to hold the load module. +# +# To compile to a member of a PDS: +# make +# or +# make zip.mvs +# +# To compile a test version into the HFS file system: +# make hfs + +# ZIP options -- MVS, REENTRANT +ZIPOPTS=-DMVS -DREENTRANT + +# directories + +# generic source code +SRC=.. +SRC_P=$(SRC)/ + +# source code for MVS +CMSMVS=../cmsmvs +CMSMVS_P=$(CMSMVS)/ + +# include files +INCLS=-I$(SRC) -I$(CMSMVS) + +# object files and load modules +BLD_P=../mvs/ + +# Other options + +# Suffixes (E and O must be different) +E= +O=.o + +# Need EXTENDED features for global.c and vmvms.c, so not using c89 +CC=cc +CFLAGS=-D_OPEN_SYS $(ZIPOPTS) $(INCLS) + +LD=cc +LDFLAGS= + +# Files + +# object (TEXT) files +OBJECTS= $(BLD_P)zip$(O) $(BLD_P)trees$(O) \ + $(BLD_P)crypt$(O) $(BLD_P)ttyio$(O) $(BLD_P)deflate$(O) \ + $(BLD_P)fileio$(O) $(BLD_P)globals$(O) $(BLD_P)util$(O) \ + $(BLD_P)crc32$(O) $(BLD_P)zipfile$(O) \ + $(BLD_P)zipup$(O) $(BLD_P)cmsmvs$(O) $(BLD_P)mvs$(O) + +# Header files +HFILES= $(SRC_P)api.h $(SRC_P)crc32.h $(SRC_P)crypt.h $(SRC_P)ebcdic.h \ + $(SRC_P)revision.h $(SRC_P)tailor.h $(SRC_P)ttyio.h \ + $(SRC_P)zip.h $(SRC_P)ziperr.h $(CMSMVS_P)cmsmvs.h \ + $(CMSMVS_P)cstat.h $(CMSMVS_P)mvs.h $(CMSMVS_P)zipup.h + +# Rules + +all: $(BLD_P)zip.mvs$(E) +hfs: $(BLD_P)zip$(E) + +# link + +$(BLD_P)zip.mvs$(E): $(OBJECTS) + $(LD) -o "//INFOZIP.LOAD(ZIP)" $(LDFLAGS) $^ + echo "tso call \"infozip(zip)\" \"'\"\"""$$""@""\"\"'\"" > $% + chmod a+x $% + +$(BLD_P)zip$(E): $(OBJECTS) + $(LD) -o $% $(LDFLAGS) $^ + +# compile + +$(BLD_P)trees$(O): $(SRC_P)trees.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)trees.c + +$(BLD_P)crypt$(O): $(SRC_P)crypt.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)crypt.c + +$(BLD_P)ttyio$(O): $(SRC_P)ttyio.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)ttyio.c + +$(BLD_P)deflate$(O): $(SRC_P)deflate.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)deflate.c + +$(BLD_P)fileio$(O): $(SRC_P)fileio.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)fileio.c + +$(BLD_P)globals$(O): $(SRC_P)globals.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)globals.c + +$(BLD_P)zip$(O): $(SRC_P)zip.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)zip.c + +$(BLD_P)util$(O): $(SRC_P)util.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)util.c + +$(BLD_P)crc32$(O): $(SRC_P)crc32.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)crc32.c + +$(BLD_P)zipfile$(O): $(SRC_P)zipfile.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)zipfile.c + +$(BLD_P)zipup$(O): $(SRC_P)zipup.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)zipup.c + +$(BLD_P)cmsmvs$(O): $(CMSMVS_P)cmsmvs.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(CMSMVS_P)cmsmvs.c + +$(BLD_P)mvs$(O): $(CMSMVS_P)mvs.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(CMSMVS_P)mvs.c diff --git a/cmsmvs/pipzip.rexx b/cmsmvs/pipzip.rexx new file mode 100644 index 0000000..4249ded --- /dev/null +++ b/cmsmvs/pipzip.rexx @@ -0,0 +1,27 @@ +/* PIPZIP REXX Rexx filter to use ZIP */ +/* Author : George Petrov, 8 May 1995 */ + +parse arg opts +'callpipe *:', + '| specs w1 1 /./ n w2 n', + '| join * / /', + '| specs /zip 'opts'/ 1 1-* nw', + '| cms', + '| *:' + +exit rc + + + + + + + + + + + + + + + diff --git a/cmsmvs/zip.exec b/cmsmvs/zip.exec new file mode 100644 index 0000000..0b9de97 --- /dev/null +++ b/cmsmvs/zip.exec @@ -0,0 +1,66 @@ +/***********************************************************************/ +/* */ +/* Front-end EXEC to set up linkage to the C runtime libraries */ +/* before executing a MODULE generated from C code. */ +/* */ +/* Copy this file as an EXEC with a filename matching the C MODULE. */ +/* */ +/* Greg Hartwig (ghartwig@vnet.ibm.com) 7/31/97, 4/24/98. */ +/* */ +/***********************************************************************/ +Address Command +Parse Arg argstring +Parse Source . . myname . + +/* Set output and input character translation so brackets show up */ +'SET OUTPUT AD' 'BA'x +'SET OUTPUT BD' 'BB'x +'SET INPUT BA AD' +'SET INPUT BB BD' + +Call CLIB +If rc<>0 Then Do + Say 'The required C runtime libraries don''t appear to be available.' + Say myname 'can not run.' + Exit 12 +End + +/* Run the command */ +myname argstring +Exit rc + + + + +/* Contents of the CLIB EXEC, modified for RC checking. */ +/* Removed TXTLIB setting. Only LOADLIB needed for execution. */ +CLIB: +/***************************************************/ +/* SET UP LIBRARIES FOR LE for MVS & VM */ +/***************************************************/ +Address COMMAND + +loadlib ='EDCLINK' /* C/370 runtime */ +loadlib ='SCEERUN' /* LE runtime */ + + +theirs=queued() /* old stack contentsM068*/ + 'QUERY LOADLIB ( LIFO' /* old setting M068*/ + LoadlibList='' /* init list M068*/ +rc=0 + Do while queued()^=theirs /* all lines from cmdM068*/ + Parse upper pull 'LOADLIB' '=' Ltemp /* get one line M068*/ + LoadlibList= Ltemp Loadliblist /* was stacked LIFO M068*/ + End /*M068*/ + If loadlibList='NONE' , + Then Do + 'GLOBAL LOADLIB' Loadlib /* enforce what we need */ + End + Else Do + Do xx=1 to Words(loadlib) + If Find(loadliblist,word(loadlib,xx)) = 0 , + then loadliblist = loadliblist word(loadlib,xx) + End + 'GLOBAL LOADLIB' loadliblist /* enforce what we need */ + End +Return diff --git a/cmsmvs/zip.makefile b/cmsmvs/zip.makefile new file mode 100644 index 0000000..85bef22 --- /dev/null +++ b/cmsmvs/zip.makefile @@ -0,0 +1,21 @@ +* This is a comment +* this makefile compiles filter ZIPME + +GLOBALS: + long def(VM_CMS) +TEXT: + trees c + crypt c + ttyio c + deflate c + fileio c + globals c + zip c + util c + crc32.c + zipfile c + zipup c + cmsmvs c + cms c +MODULE: + zip module diff --git a/cmsmvs/zipcloak.exec b/cmsmvs/zipcloak.exec new file mode 100644 index 0000000..0b9de97 --- /dev/null +++ b/cmsmvs/zipcloak.exec @@ -0,0 +1,66 @@ +/***********************************************************************/ +/* */ +/* Front-end EXEC to set up linkage to the C runtime libraries */ +/* before executing a MODULE generated from C code. */ +/* */ +/* Copy this file as an EXEC with a filename matching the C MODULE. */ +/* */ +/* Greg Hartwig (ghartwig@vnet.ibm.com) 7/31/97, 4/24/98. */ +/* */ +/***********************************************************************/ +Address Command +Parse Arg argstring +Parse Source . . myname . + +/* Set output and input character translation so brackets show up */ +'SET OUTPUT AD' 'BA'x +'SET OUTPUT BD' 'BB'x +'SET INPUT BA AD' +'SET INPUT BB BD' + +Call CLIB +If rc<>0 Then Do + Say 'The required C runtime libraries don''t appear to be available.' + Say myname 'can not run.' + Exit 12 +End + +/* Run the command */ +myname argstring +Exit rc + + + + +/* Contents of the CLIB EXEC, modified for RC checking. */ +/* Removed TXTLIB setting. Only LOADLIB needed for execution. */ +CLIB: +/***************************************************/ +/* SET UP LIBRARIES FOR LE for MVS & VM */ +/***************************************************/ +Address COMMAND + +loadlib ='EDCLINK' /* C/370 runtime */ +loadlib ='SCEERUN' /* LE runtime */ + + +theirs=queued() /* old stack contentsM068*/ + 'QUERY LOADLIB ( LIFO' /* old setting M068*/ + LoadlibList='' /* init list M068*/ +rc=0 + Do while queued()^=theirs /* all lines from cmdM068*/ + Parse upper pull 'LOADLIB' '=' Ltemp /* get one line M068*/ + LoadlibList= Ltemp Loadliblist /* was stacked LIFO M068*/ + End /*M068*/ + If loadlibList='NONE' , + Then Do + 'GLOBAL LOADLIB' Loadlib /* enforce what we need */ + End + Else Do + Do xx=1 to Words(loadlib) + If Find(loadliblist,word(loadlib,xx)) = 0 , + then loadliblist = loadliblist word(loadlib,xx) + End + 'GLOBAL LOADLIB' loadliblist /* enforce what we need */ + End +Return diff --git a/cmsmvs/zipmvsc.job b/cmsmvs/zipmvsc.job new file mode 100644 index 0000000..3c786d7 --- /dev/null +++ b/cmsmvs/zipmvsc.job @@ -0,0 +1,89 @@ +//CCZIP JOB (BI09255), +// MSGLEVEL=(1,1),MSGCLASS=C,CLASS=D,NOTIFY=C888090 +//PROCLIB JCLLIB ORDER=(SYS1.C370.PROCLIB.M24) +//ZIP EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(ZIP)', +// OUTFILE='C888090.ZIP.C.OBJ(ZIP),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//CRYPT EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(CRYPT)', +// OUTFILE='C888090.ZIP.C.OBJ(CRYPT),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//TTYIO EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(TTYIO)', +// OUTFILE='C888090.ZIP.C.OBJ(TTYIO),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//TREES EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(TREES)', +// OUTFILE='C888090.ZIP.C.OBJ(TREES),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//DEFLATE EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(DEFLATE)', +// OUTFILE='C888090.ZIP.C.OBJ(DEFLATE),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//FILEIO EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(FILEIO)', +// OUTFILE='C888090.ZIP.C.OBJ(FILEIO),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//GLOBALS EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(GLOBALS)', +// OUTFILE='C888090.ZIP.C.OBJ(GLOBALS),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//UTIL EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(UTIL)', +// OUTFILE='C888090.ZIP.C.OBJ(UTIL),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//CRC32 EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(CRC32)', +// OUTFILE='C888090.ZIP.C.OBJ(CRC32),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//ZIPFILE EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(ZIPFILE)', +// OUTFILE='C888090.ZIP.C.OBJ(ZIPFILE),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//ZIPUP EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(ZIPUP)', +// OUTFILE='C888090.ZIP.C.OBJ(ZIPUP),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//CMSMVS EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(CMSMVS)', +// OUTFILE='C888090.ZIP.C.OBJ(CMSMVS),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//MVS EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(MVS)', +// OUTFILE='C888090.ZIP.C.OBJ(MVS),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//PLINK EXEC PROC=EDCPL,COND=(12,LE), +// OUTFILE='C888090.ZIP.LOAD(ZIP),DISP=SHR', +// PPARM='NONCAL,MAP', +// LPARM='LIST,MAP,XREF' +//SYSPRINT DD SYSOUT=* +//PLKED.SYSIN DD DSN=C888090.ZIP.C.OBJ(ZIP),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(BITS),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(CRYPT),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(TREES),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(DEFLATE),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(FILEIO),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(GLOBALS),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(UTIL),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(CRC32),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(ZIPFILE),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(ZIPUP),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(CMSMVS),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(MVS),DISP=SHR +//PLKED.SYSLIB DD DSN=SYS1.C370.SEDCBASE,DISP=SHR +// DD DSN=SYS1.PL1.SIBMBASE,DISP=SHR +//SYSUT1 DD UNIT=SYSDA,SPACE=(CYL,(2,2)),DISP=NEW diff --git a/cmsmvs/zipname.conven b/cmsmvs/zipname.conven new file mode 100644 index 0000000..e17fe9c --- /dev/null +++ b/cmsmvs/zipname.conven @@ -0,0 +1,200 @@ + + Zip file/directories name convention under MVS + --------------------------------------------------- + Draft 1.1 + + +1. Translating native file names to Zip filenames. + +1.1 Zipping a PDS + +On MVS there are directories called PDS (Partition Data Set) which have +the following format : name1.name2.name3(mname) +for example: myuserid.unzip.c(unzip) + +So as you see the path delimiter is '.'. Each dir name can be max 8 +chars long beginning with a number. + +Between '(' and ')' there is the so called member name - it is also 8 +chars long. This is the actual file name. + + +1.1.1 Converting MVS PDS name to zip path/filename (status: not implemented) + +The PDS name is converted to zippath as follows: +in the zip : name1/name2/mname.name3 +becomes on MVS: name1.name2.name3(mname) + + +1.2 Unzipping as PDS (status: implemented) + +When you unzip the file name myuserid/unzip/unzip.c the same process +is done backwards, so you get : myuserid.unzip.c(unzip) + +Notice that the file extension is used as last dirname! + + +1.2 Unzipping to a different PDS (status: implemented) + +You can also use -d option while unzipping for example: +unzip mytest myuserid/unzip/unzip.c -dnewdest.test + +then the new name will become: +newdest.test.myuserid.unzip.c(unzip) + + Second example: + +unzip mytest myuserid/unzip/*.c -dnewdest.test + +then you get a PDS: +newdest.test.myuserid.unzip.c(...) + +with all *.c files in it. + + +1.3 Zipping a Sequential Dataset (status: not implemented) + + Sequential dataset is a dataset with NO members. +Such a dataset is translated from native MVS to zip format by replacing +the '.' (points) with '/' (backslash). + +Example: +on MVS: name1.name2.name3 +becomes in the zip : name1/name2/name3 + +NOTE : The new filename in the zip has NO extension this way it can be + recognised as a Sequential dataset and not a PDS. + But this also means that all files in the zip archive that have + no extension will be unzipped as Sequential datasets! + + +1.4 Using a DDNAMES for input. (status: not implemented) + +To use DDNAMES as input file names put a 'dd:' before the ddname: +example: zip myzip dd:name1 dd:name2 dd:sales + +In the Zip archive the ddnames are saved as name.DDNAME so if you try +the example above you will get in your zip file (when listing it) : + +..size .. date time .. crc .. NAME1.DDNAME +..size .. date time .. crc .. NAME2.DDNAME +..size .. date time .. crc .. SALES.DDNAME + + +1.4 Using a DDNAMES as zip name (status: implemented) + +It is allowed to use a DDNAME as zipfile, just put dd: before it +example: unzip dd:myzip *.c + this will unzip all .c files from ddname myzip + +example2: ZIP DD:MYZIP DD:MANE1 MYSOURCE.C MYDOC.TEXT(ZIPPING) + this will zip ddname name1 file mysource.c and PDS mydoc.text(zipping) + into as a zip file in the ddname myzip + + +2. Converting longer path names (unix like) (status: not implemented) + to native MVS names. + +When in the zip archive there are dirnames longer that 8 chars they are +chopped at the 8 position. For example + MyLongZippath/WithLongFileName.text +is translated to: + MYLONGZI.TEXT(WITHLONG) + +Notice that all chars are converted to uppercase. + + +2.1 Using special characters (status: implemented) + +Also all '_' (underscore), '+' (plus), '-' (minus), '(' and ')' +from the file name/path in the zip archive are skipped because they +are not valid in the MVS filenames. + + +2.2 Numeric file names (status: not implemented) + +On MVS no name can begin with a number, so when a dir/file name begins with +one, a leading letter 'N' is inserted. For example: + Contents.512 +becomes: + CONTENTS.N512 + + + + + Zip file/directories name convention under VM/CMS + --------------------------------------------------- + +1. Translating native file names to Zip filenames. + +On VM/CMS (not ESA ) there are NO directories so you got only disks +and files. + +The file names are delimited with spaces. But for use with unzip/zip +you have to use '.' points as delimiters. + +For example on your A disk you have file called PROFILE EXEC +if you want to zip it type : zip myzip profile.exec + +If the same file is on your F disk you have to type: +zip myzip profile.exec.f + +So as you can see the general format is fname.ftype.fmode + +In the zipfile the disk from which the file comes is not saved! +So only the fname.ftype is saved. + +If you unzip and you want to give a different destination disk just use +the -d option like: + + unzip mytest *.c -df + +This will unzip all *.c files to your F disk. + + +2. Converting longer path names (unix like) to native VM/CMS names. + +When in the zip archive there are dirnames longer that 8 chars they are +chopped at the 8 position. Also the path is removed. For example + Zippath/WithLongFileName.text +is translated to: + WITHLONG.TEXT + +Notice that all chars are converted to uppercase. + +Also all '+' (plus), '-' (minus), '(' and ')' +from the file name/path in the zip archive are skipped because they +are not valid in the VM/CMS filenames. + +If there is no extension for the file name in the zip archive, unzip +will add .NONAME for example: + mypath/dir1/testfile +becomes: + TESTFILE.NONAME + +3. Future? + +There is also discussion for a new option on ZIP that you can give +a virtual directory to be added before each file name that is zipped. + +For example you want to zip a few .c file and put them in the zip +structure under the directory 'mydir/test', but you can't create dirs on +VM/CMS so you have to the something like: + +ZIP myzip file1.c file2.c -dmydir/test + +and you get in the zip archive files: + + mydir/test/file1.c + mydir/test/file2.c + +------------------------------------------------------------------------- + + +NOTE: Not all of those functions are implemented in the first beta + release of VM/MVS UNZIP/ZIP. + +Every ideas/corrections/bugs will be appreciated. +Mail to maillist: Info-ZIP@LISTS.WKU.EDU + +George Petrov diff --git a/cmsmvs/zipnote.exec b/cmsmvs/zipnote.exec new file mode 100644 index 0000000..0b9de97 --- /dev/null +++ b/cmsmvs/zipnote.exec @@ -0,0 +1,66 @@ +/***********************************************************************/ +/* */ +/* Front-end EXEC to set up linkage to the C runtime libraries */ +/* before executing a MODULE generated from C code. */ +/* */ +/* Copy this file as an EXEC with a filename matching the C MODULE. */ +/* */ +/* Greg Hartwig (ghartwig@vnet.ibm.com) 7/31/97, 4/24/98. */ +/* */ +/***********************************************************************/ +Address Command +Parse Arg argstring +Parse Source . . myname . + +/* Set output and input character translation so brackets show up */ +'SET OUTPUT AD' 'BA'x +'SET OUTPUT BD' 'BB'x +'SET INPUT BA AD' +'SET INPUT BB BD' + +Call CLIB +If rc<>0 Then Do + Say 'The required C runtime libraries don''t appear to be available.' + Say myname 'can not run.' + Exit 12 +End + +/* Run the command */ +myname argstring +Exit rc + + + + +/* Contents of the CLIB EXEC, modified for RC checking. */ +/* Removed TXTLIB setting. Only LOADLIB needed for execution. */ +CLIB: +/***************************************************/ +/* SET UP LIBRARIES FOR LE for MVS & VM */ +/***************************************************/ +Address COMMAND + +loadlib ='EDCLINK' /* C/370 runtime */ +loadlib ='SCEERUN' /* LE runtime */ + + +theirs=queued() /* old stack contentsM068*/ + 'QUERY LOADLIB ( LIFO' /* old setting M068*/ + LoadlibList='' /* init list M068*/ +rc=0 + Do while queued()^=theirs /* all lines from cmdM068*/ + Parse upper pull 'LOADLIB' '=' Ltemp /* get one line M068*/ + LoadlibList= Ltemp Loadliblist /* was stacked LIFO M068*/ + End /*M068*/ + If loadlibList='NONE' , + Then Do + 'GLOBAL LOADLIB' Loadlib /* enforce what we need */ + End + Else Do + Do xx=1 to Words(loadlib) + If Find(loadliblist,word(loadlib,xx)) = 0 , + then loadliblist = loadliblist word(loadlib,xx) + End + 'GLOBAL LOADLIB' loadliblist /* enforce what we need */ + End +Return diff --git a/cmsmvs/zipsplit.exec b/cmsmvs/zipsplit.exec new file mode 100644 index 0000000..0b9de97 --- /dev/null +++ b/cmsmvs/zipsplit.exec @@ -0,0 +1,66 @@ +/***********************************************************************/ +/* */ +/* Front-end EXEC to set up linkage to the C runtime libraries */ +/* before executing a MODULE generated from C code. */ +/* */ +/* Copy this file as an EXEC with a filename matching the C MODULE. */ +/* */ +/* Greg Hartwig (ghartwig@vnet.ibm.com) 7/31/97, 4/24/98. */ +/* */ +/***********************************************************************/ +Address Command +Parse Arg argstring +Parse Source . . myname . + +/* Set output and input character translation so brackets show up */ +'SET OUTPUT AD' 'BA'x +'SET OUTPUT BD' 'BB'x +'SET INPUT BA AD' +'SET INPUT BB BD' + +Call CLIB +If rc<>0 Then Do + Say 'The required C runtime libraries don''t appear to be available.' + Say myname 'can not run.' + Exit 12 +End + +/* Run the command */ +myname argstring +Exit rc + + + + +/* Contents of the CLIB EXEC, modified for RC checking. */ +/* Removed TXTLIB setting. Only LOADLIB needed for execution. */ +CLIB: +/***************************************************/ +/* SET UP LIBRARIES FOR LE for MVS & VM */ +/***************************************************/ +Address COMMAND + +loadlib ='EDCLINK' /* C/370 runtime */ +loadlib ='SCEERUN' /* LE runtime */ + + +theirs=queued() /* old stack contentsM068*/ + 'QUERY LOADLIB ( LIFO' /* old setting M068*/ + LoadlibList='' /* init list M068*/ +rc=0 + Do while queued()^=theirs /* all lines from cmdM068*/ + Parse upper pull 'LOADLIB' '=' Ltemp /* get one line M068*/ + LoadlibList= Ltemp Loadliblist /* was stacked LIFO M068*/ + End /*M068*/ + If loadlibList='NONE' , + Then Do + 'GLOBAL LOADLIB' Loadlib /* enforce what we need */ + End + Else Do + Do xx=1 to Words(loadlib) + If Find(loadliblist,word(loadlib,xx)) = 0 , + then loadliblist = loadliblist word(loadlib,xx) + End + 'GLOBAL LOADLIB' loadliblist /* enforce what we need */ + End +Return diff --git a/cmsmvs/zipup.h b/cmsmvs/zipup.h new file mode 100644 index 0000000..0ea8962 --- /dev/null +++ b/cmsmvs/zipup.h @@ -0,0 +1,18 @@ +/* + 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,byteseek" +#define fhowb "rb,byteseek" + +#define fbad NULL +typedef FILE *ftype; +#define zopen(n,p) (ftype)fopen((n),(p)) +#define zread(f,b,n) fread((b),1,(n),(FILE*)(f)) +#define zclose(f) fclose((FILE*)(f)) +#define zerr(f) ferror((FILE*)(f)) +#define zstdin stdin diff --git a/cmsmvs/zipvmc.exec b/cmsmvs/zipvmc.exec new file mode 100644 index 0000000..3fdd800 --- /dev/null +++ b/cmsmvs/zipvmc.exec @@ -0,0 +1,48 @@ +/* VMCOMPIL EXEC Unzip compile for VM/CMS */ +/* Author : George Petrov, 11 Apr 1995 */ + +signal on error + +parms = '(long def(VM_CMS)' + +/* Add local parms */ +parms = parms 'TARGET(COMPAT) SOURCE' + + +say 'Compiling TREES C...' +'cc trees c 'parms +say 'Compiling CRYPT C...' +'cc crypt c 'parms +say 'Compiling TTYIO C...' +'cc ttyio c 'parms +say 'Compiling DEFLATE C...' +'cc deflate c 'parms +say 'Compiling FILEIO C...' +'cc fileio c 'parms +say 'Compiling GLOBALS C...' +'cc globals c 'parms +say 'Compiling ZIP C...' +'cc zip c 'parms +say 'Compiling UTIL C...' +'cc util c 'parms +say 'Compiling CRC32 C...' +'cc crc32 c 'parms +say 'Compiling ZIPFILE C...' +'cc zipfile c 'parms +say 'Compiling ZIPUP C...' +'cc zipup c 'parms +say 'Compiling CMSMVS C...' +'cc cmsmvs c 'parms +say 'Compiling CMS C...' +'cc cms c 'parms + +say 'Linking all files...' +'cmod zip zip trees crypt deflate fileio globals ttyio', + 'util crc32 zipfile zipup cmsmvs cms' +say 'All Done!' +say "To run enter : ZIP parms" +exit rc + +error: +say 'Error durring compilation!' +exit rc diff --git a/crc32.c b/crc32.c new file mode 100644 index 0000000..6b2403b --- /dev/null +++ b/crc32.c @@ -0,0 +1,732 @@ +/* + Copyright (c) 1990-2008 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 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 +*/ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results about a factor + * of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* $Id: crc32.c,v 2.0 2007/01/07 05:20:36 spc Exp $ */ + +#define __CRC32_C /* identifies this source module */ + +#include "zip.h" + +#if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB)) + +#ifndef ZCONST +# define ZCONST const +#endif + +#include "crc32.h" + +/* When only the table of precomputed CRC values is needed, only the basic + system-independent table containing 256 entries is created; any support + for "unfolding" optimization is disabled. + */ +#if (defined(USE_ZLIB) || defined(CRC_TABLE_ONLY)) +# ifdef IZ_CRCOPTIM_UNFOLDTBL +# undef IZ_CRCOPTIM_UNFOLDTBL +# endif +#endif /* (USE_ZLIB || CRC_TABLE_ONLY) */ + +#if defined(IZ_CRCOPTIM_UNFOLDTBL) +# define CRC_TBLS 4 +#else +# define CRC_TBLS 1 +#endif + + +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first (or only) table is simply the CRC of all possible eight bit values. + This is all the information needed to generate CRC's on data a byte-at-a-time + for all combinations of CRC register values and incoming bytes. + The remaining 3 tables (if IZ_CRCOPTIM_UNFOLDTBL is enabled) allow for + word-at-a-time CRC calculation, where a word is four bytes. +*/ + +#ifdef DYNAMIC_CRC_TABLE + +/* ========================================================================= + * Make the crc table. This function is needed only if you want to compute + * the table dynamically. + */ + +local void make_crc_table OF((void)); + +#if (defined(DYNALLOC_CRCTAB) && defined(REENTRANT)) + error: Dynamic allocation of CRC table not safe with reentrant code. +#endif /* DYNALLOC_CRCTAB && REENTRANT */ + +#ifdef DYNALLOC_CRCTAB + local ulg near *crc_table = NULL; +# if 0 /* not used, since sizeof("near *") <= sizeof(int) */ + /* Use this section when access to a "local int" is faster than access to + a "local pointer" (e.g.: i86 16bit code with far pointers). */ + local int crc_table_empty = 1; +# define CRC_TABLE_IS_EMPTY (crc_table_empty != 0) +# define MARK_CRCTAB_FILLED crc_table_empty = 0 +# define MARK_CRCTAB_EMPTY crc_table_empty = 1 +# else + /* Use this section on systems where the size of pointers and ints is + equal (e.g.: all 32bit systems). */ +# define CRC_TABLE_IS_EMPTY (crc_table == NULL) +# define MARK_CRCTAB_FILLED crc_table = crctab_p +# define MARK_CRCTAB_EMPTY crc_table = NULL +# endif +#else /* !DYNALLOC_CRCTAB */ + local ulg near crc_table[CRC_TBLS*256]; + local int crc_table_empty = 1; +# define CRC_TABLE_IS_EMPTY (crc_table_empty != 0) +# define MARK_CRCTAB_FILLED crc_table_empty = 0 +#endif /* ?DYNALLOC_CRCTAB */ + + +local void make_crc_table() +{ + ulg c; /* crc shift register */ + int n; /* counter for all possible eight bit values */ + int k; /* byte being shifted into crc apparatus */ +#ifdef DYNALLOC_CRCTAB + ulg near *crctab_p; /* temporary pointer to allocated crc_table area */ +#else /* !DYNALLOC_CRCTAB */ +# define crctab_p crc_table +#endif /* DYNALLOC_CRCTAB */ + +#ifdef COMPUTE_XOR_PATTERN + /* This piece of code has been left here to explain how the XOR pattern + * used in the creation of the crc_table values can be recomputed. + * For production versions of this function, it is more efficient to + * supply the resultant pattern at compile time. + */ + ulg xor; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static ZCONST uch p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* make exclusive-or pattern from polynomial (0xedb88320L) */ + xor = 0L; + for (n = 0; n < sizeof(p)/sizeof(uch); n++) + xor |= 1L << (31 - p[n]); +#else +# define xor 0xedb88320L +#endif + +#ifdef DYNALLOC_CRCTAB + crctab_p = (ulg near *) nearmalloc (CRC_TBLS*256*sizeof(ulg)); + if (crctab_p == NULL) { + ziperr(ZE_MEM, "crc_table allocation"); + } +#endif /* DYNALLOC_CRCTAB */ + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (ulg)n; + for (k = 8; k; k--) + c = c & 1 ? xor ^ (c >> 1) : c >> 1; + crctab_p[n] = REV_BE(c); + } + +#ifdef IZ_CRCOPTIM_UNFOLDTBL + /* generate crc for each value followed by one, two, and three zeros */ + for (n = 0; n < 256; n++) { + c = crctab_p[n]; + for (k = 1; k < 4; k++) { + c = CRC32(c, 0, crctab_p); + crctab_p[k*256+n] = c; + } + } +#endif /* IZ_CRCOPTIM_UNFOLDTBL */ + + MARK_CRCTAB_FILLED; +} + +#else /* !DYNAMIC_CRC_TABLE */ + +#ifdef DYNALLOC_CRCTAB + error: Inconsistent flags, DYNALLOC_CRCTAB without DYNAMIC_CRC_TABLE. +#endif + +/* ======================================================================== + * Table of CRC-32's of all single-byte values (made by make_crc_table) + */ +local ZCONST ulg near crc_table[CRC_TBLS*256] = { +# ifdef IZ_CRC_BE_OPTIMIZ + 0x00000000L, 0x96300777L, 0x2c610eeeL, 0xba510999L, 0x19c46d07L, + 0x8ff46a70L, 0x35a563e9L, 0xa395649eL, 0x3288db0eL, 0xa4b8dc79L, + 0x1ee9d5e0L, 0x88d9d297L, 0x2b4cb609L, 0xbd7cb17eL, 0x072db8e7L, + 0x911dbf90L, 0x6410b71dL, 0xf220b06aL, 0x4871b9f3L, 0xde41be84L, + 0x7dd4da1aL, 0xebe4dd6dL, 0x51b5d4f4L, 0xc785d383L, 0x56986c13L, + 0xc0a86b64L, 0x7af962fdL, 0xecc9658aL, 0x4f5c0114L, 0xd96c0663L, + 0x633d0ffaL, 0xf50d088dL, 0xc8206e3bL, 0x5e10694cL, 0xe44160d5L, + 0x727167a2L, 0xd1e4033cL, 0x47d4044bL, 0xfd850dd2L, 0x6bb50aa5L, + 0xfaa8b535L, 0x6c98b242L, 0xd6c9bbdbL, 0x40f9bcacL, 0xe36cd832L, + 0x755cdf45L, 0xcf0dd6dcL, 0x593dd1abL, 0xac30d926L, 0x3a00de51L, + 0x8051d7c8L, 0x1661d0bfL, 0xb5f4b421L, 0x23c4b356L, 0x9995bacfL, + 0x0fa5bdb8L, 0x9eb80228L, 0x0888055fL, 0xb2d90cc6L, 0x24e90bb1L, + 0x877c6f2fL, 0x114c6858L, 0xab1d61c1L, 0x3d2d66b6L, 0x9041dc76L, + 0x0671db01L, 0xbc20d298L, 0x2a10d5efL, 0x8985b171L, 0x1fb5b606L, + 0xa5e4bf9fL, 0x33d4b8e8L, 0xa2c90778L, 0x34f9000fL, 0x8ea80996L, + 0x18980ee1L, 0xbb0d6a7fL, 0x2d3d6d08L, 0x976c6491L, 0x015c63e6L, + 0xf4516b6bL, 0x62616c1cL, 0xd8306585L, 0x4e0062f2L, 0xed95066cL, + 0x7ba5011bL, 0xc1f40882L, 0x57c40ff5L, 0xc6d9b065L, 0x50e9b712L, + 0xeab8be8bL, 0x7c88b9fcL, 0xdf1ddd62L, 0x492dda15L, 0xf37cd38cL, + 0x654cd4fbL, 0x5861b24dL, 0xce51b53aL, 0x7400bca3L, 0xe230bbd4L, + 0x41a5df4aL, 0xd795d83dL, 0x6dc4d1a4L, 0xfbf4d6d3L, 0x6ae96943L, + 0xfcd96e34L, 0x468867adL, 0xd0b860daL, 0x732d0444L, 0xe51d0333L, + 0x5f4c0aaaL, 0xc97c0dddL, 0x3c710550L, 0xaa410227L, 0x10100bbeL, + 0x86200cc9L, 0x25b56857L, 0xb3856f20L, 0x09d466b9L, 0x9fe461ceL, + 0x0ef9de5eL, 0x98c9d929L, 0x2298d0b0L, 0xb4a8d7c7L, 0x173db359L, + 0x810db42eL, 0x3b5cbdb7L, 0xad6cbac0L, 0x2083b8edL, 0xb6b3bf9aL, + 0x0ce2b603L, 0x9ad2b174L, 0x3947d5eaL, 0xaf77d29dL, 0x1526db04L, + 0x8316dc73L, 0x120b63e3L, 0x843b6494L, 0x3e6a6d0dL, 0xa85a6a7aL, + 0x0bcf0ee4L, 0x9dff0993L, 0x27ae000aL, 0xb19e077dL, 0x44930ff0L, + 0xd2a30887L, 0x68f2011eL, 0xfec20669L, 0x5d5762f7L, 0xcb676580L, + 0x71366c19L, 0xe7066b6eL, 0x761bd4feL, 0xe02bd389L, 0x5a7ada10L, + 0xcc4add67L, 0x6fdfb9f9L, 0xf9efbe8eL, 0x43beb717L, 0xd58eb060L, + 0xe8a3d6d6L, 0x7e93d1a1L, 0xc4c2d838L, 0x52f2df4fL, 0xf167bbd1L, + 0x6757bca6L, 0xdd06b53fL, 0x4b36b248L, 0xda2b0dd8L, 0x4c1b0aafL, + 0xf64a0336L, 0x607a0441L, 0xc3ef60dfL, 0x55df67a8L, 0xef8e6e31L, + 0x79be6946L, 0x8cb361cbL, 0x1a8366bcL, 0xa0d26f25L, 0x36e26852L, + 0x95770cccL, 0x03470bbbL, 0xb9160222L, 0x2f260555L, 0xbe3bbac5L, + 0x280bbdb2L, 0x925ab42bL, 0x046ab35cL, 0xa7ffd7c2L, 0x31cfd0b5L, + 0x8b9ed92cL, 0x1daede5bL, 0xb0c2649bL, 0x26f263ecL, 0x9ca36a75L, + 0x0a936d02L, 0xa906099cL, 0x3f360eebL, 0x85670772L, 0x13570005L, + 0x824abf95L, 0x147ab8e2L, 0xae2bb17bL, 0x381bb60cL, 0x9b8ed292L, + 0x0dbed5e5L, 0xb7efdc7cL, 0x21dfdb0bL, 0xd4d2d386L, 0x42e2d4f1L, + 0xf8b3dd68L, 0x6e83da1fL, 0xcd16be81L, 0x5b26b9f6L, 0xe177b06fL, + 0x7747b718L, 0xe65a0888L, 0x706a0fffL, 0xca3b0666L, 0x5c0b0111L, + 0xff9e658fL, 0x69ae62f8L, 0xd3ff6b61L, 0x45cf6c16L, 0x78e20aa0L, + 0xeed20dd7L, 0x5483044eL, 0xc2b30339L, 0x612667a7L, 0xf71660d0L, + 0x4d476949L, 0xdb776e3eL, 0x4a6ad1aeL, 0xdc5ad6d9L, 0x660bdf40L, + 0xf03bd837L, 0x53aebca9L, 0xc59ebbdeL, 0x7fcfb247L, 0xe9ffb530L, + 0x1cf2bdbdL, 0x8ac2bacaL, 0x3093b353L, 0xa6a3b424L, 0x0536d0baL, + 0x9306d7cdL, 0x2957de54L, 0xbf67d923L, 0x2e7a66b3L, 0xb84a61c4L, + 0x021b685dL, 0x942b6f2aL, 0x37be0bb4L, 0xa18e0cc3L, 0x1bdf055aL, + 0x8def022dL +# ifdef IZ_CRCOPTIM_UNFOLDTBL + , + 0x00000000L, 0x41311b19L, 0x82623632L, 0xc3532d2bL, 0x04c56c64L, + 0x45f4777dL, 0x86a75a56L, 0xc796414fL, 0x088ad9c8L, 0x49bbc2d1L, + 0x8ae8effaL, 0xcbd9f4e3L, 0x0c4fb5acL, 0x4d7eaeb5L, 0x8e2d839eL, + 0xcf1c9887L, 0x5112c24aL, 0x1023d953L, 0xd370f478L, 0x9241ef61L, + 0x55d7ae2eL, 0x14e6b537L, 0xd7b5981cL, 0x96848305L, 0x59981b82L, + 0x18a9009bL, 0xdbfa2db0L, 0x9acb36a9L, 0x5d5d77e6L, 0x1c6c6cffL, + 0xdf3f41d4L, 0x9e0e5acdL, 0xa2248495L, 0xe3159f8cL, 0x2046b2a7L, + 0x6177a9beL, 0xa6e1e8f1L, 0xe7d0f3e8L, 0x2483dec3L, 0x65b2c5daL, + 0xaaae5d5dL, 0xeb9f4644L, 0x28cc6b6fL, 0x69fd7076L, 0xae6b3139L, + 0xef5a2a20L, 0x2c09070bL, 0x6d381c12L, 0xf33646dfL, 0xb2075dc6L, + 0x715470edL, 0x30656bf4L, 0xf7f32abbL, 0xb6c231a2L, 0x75911c89L, + 0x34a00790L, 0xfbbc9f17L, 0xba8d840eL, 0x79dea925L, 0x38efb23cL, + 0xff79f373L, 0xbe48e86aL, 0x7d1bc541L, 0x3c2ade58L, 0x054f79f0L, + 0x447e62e9L, 0x872d4fc2L, 0xc61c54dbL, 0x018a1594L, 0x40bb0e8dL, + 0x83e823a6L, 0xc2d938bfL, 0x0dc5a038L, 0x4cf4bb21L, 0x8fa7960aL, + 0xce968d13L, 0x0900cc5cL, 0x4831d745L, 0x8b62fa6eL, 0xca53e177L, + 0x545dbbbaL, 0x156ca0a3L, 0xd63f8d88L, 0x970e9691L, 0x5098d7deL, + 0x11a9ccc7L, 0xd2fae1ecL, 0x93cbfaf5L, 0x5cd76272L, 0x1de6796bL, + 0xdeb55440L, 0x9f844f59L, 0x58120e16L, 0x1923150fL, 0xda703824L, + 0x9b41233dL, 0xa76bfd65L, 0xe65ae67cL, 0x2509cb57L, 0x6438d04eL, + 0xa3ae9101L, 0xe29f8a18L, 0x21cca733L, 0x60fdbc2aL, 0xafe124adL, + 0xeed03fb4L, 0x2d83129fL, 0x6cb20986L, 0xab2448c9L, 0xea1553d0L, + 0x29467efbL, 0x687765e2L, 0xf6793f2fL, 0xb7482436L, 0x741b091dL, + 0x352a1204L, 0xf2bc534bL, 0xb38d4852L, 0x70de6579L, 0x31ef7e60L, + 0xfef3e6e7L, 0xbfc2fdfeL, 0x7c91d0d5L, 0x3da0cbccL, 0xfa368a83L, + 0xbb07919aL, 0x7854bcb1L, 0x3965a7a8L, 0x4b98833bL, 0x0aa99822L, + 0xc9fab509L, 0x88cbae10L, 0x4f5def5fL, 0x0e6cf446L, 0xcd3fd96dL, + 0x8c0ec274L, 0x43125af3L, 0x022341eaL, 0xc1706cc1L, 0x804177d8L, + 0x47d73697L, 0x06e62d8eL, 0xc5b500a5L, 0x84841bbcL, 0x1a8a4171L, + 0x5bbb5a68L, 0x98e87743L, 0xd9d96c5aL, 0x1e4f2d15L, 0x5f7e360cL, + 0x9c2d1b27L, 0xdd1c003eL, 0x120098b9L, 0x533183a0L, 0x9062ae8bL, + 0xd153b592L, 0x16c5f4ddL, 0x57f4efc4L, 0x94a7c2efL, 0xd596d9f6L, + 0xe9bc07aeL, 0xa88d1cb7L, 0x6bde319cL, 0x2aef2a85L, 0xed796bcaL, + 0xac4870d3L, 0x6f1b5df8L, 0x2e2a46e1L, 0xe136de66L, 0xa007c57fL, + 0x6354e854L, 0x2265f34dL, 0xe5f3b202L, 0xa4c2a91bL, 0x67918430L, + 0x26a09f29L, 0xb8aec5e4L, 0xf99fdefdL, 0x3accf3d6L, 0x7bfde8cfL, + 0xbc6ba980L, 0xfd5ab299L, 0x3e099fb2L, 0x7f3884abL, 0xb0241c2cL, + 0xf1150735L, 0x32462a1eL, 0x73773107L, 0xb4e17048L, 0xf5d06b51L, + 0x3683467aL, 0x77b25d63L, 0x4ed7facbL, 0x0fe6e1d2L, 0xccb5ccf9L, + 0x8d84d7e0L, 0x4a1296afL, 0x0b238db6L, 0xc870a09dL, 0x8941bb84L, + 0x465d2303L, 0x076c381aL, 0xc43f1531L, 0x850e0e28L, 0x42984f67L, + 0x03a9547eL, 0xc0fa7955L, 0x81cb624cL, 0x1fc53881L, 0x5ef42398L, + 0x9da70eb3L, 0xdc9615aaL, 0x1b0054e5L, 0x5a314ffcL, 0x996262d7L, + 0xd85379ceL, 0x174fe149L, 0x567efa50L, 0x952dd77bL, 0xd41ccc62L, + 0x138a8d2dL, 0x52bb9634L, 0x91e8bb1fL, 0xd0d9a006L, 0xecf37e5eL, + 0xadc26547L, 0x6e91486cL, 0x2fa05375L, 0xe836123aL, 0xa9070923L, + 0x6a542408L, 0x2b653f11L, 0xe479a796L, 0xa548bc8fL, 0x661b91a4L, + 0x272a8abdL, 0xe0bccbf2L, 0xa18dd0ebL, 0x62defdc0L, 0x23efe6d9L, + 0xbde1bc14L, 0xfcd0a70dL, 0x3f838a26L, 0x7eb2913fL, 0xb924d070L, + 0xf815cb69L, 0x3b46e642L, 0x7a77fd5bL, 0xb56b65dcL, 0xf45a7ec5L, + 0x370953eeL, 0x763848f7L, 0xb1ae09b8L, 0xf09f12a1L, 0x33cc3f8aL, + 0x72fd2493L + , + 0x00000000L, 0x376ac201L, 0x6ed48403L, 0x59be4602L, 0xdca80907L, + 0xebc2cb06L, 0xb27c8d04L, 0x85164f05L, 0xb851130eL, 0x8f3bd10fL, + 0xd685970dL, 0xe1ef550cL, 0x64f91a09L, 0x5393d808L, 0x0a2d9e0aL, + 0x3d475c0bL, 0x70a3261cL, 0x47c9e41dL, 0x1e77a21fL, 0x291d601eL, + 0xac0b2f1bL, 0x9b61ed1aL, 0xc2dfab18L, 0xf5b56919L, 0xc8f23512L, + 0xff98f713L, 0xa626b111L, 0x914c7310L, 0x145a3c15L, 0x2330fe14L, + 0x7a8eb816L, 0x4de47a17L, 0xe0464d38L, 0xd72c8f39L, 0x8e92c93bL, + 0xb9f80b3aL, 0x3cee443fL, 0x0b84863eL, 0x523ac03cL, 0x6550023dL, + 0x58175e36L, 0x6f7d9c37L, 0x36c3da35L, 0x01a91834L, 0x84bf5731L, + 0xb3d59530L, 0xea6bd332L, 0xdd011133L, 0x90e56b24L, 0xa78fa925L, + 0xfe31ef27L, 0xc95b2d26L, 0x4c4d6223L, 0x7b27a022L, 0x2299e620L, + 0x15f32421L, 0x28b4782aL, 0x1fdeba2bL, 0x4660fc29L, 0x710a3e28L, + 0xf41c712dL, 0xc376b32cL, 0x9ac8f52eL, 0xada2372fL, 0xc08d9a70L, + 0xf7e75871L, 0xae591e73L, 0x9933dc72L, 0x1c259377L, 0x2b4f5176L, + 0x72f11774L, 0x459bd575L, 0x78dc897eL, 0x4fb64b7fL, 0x16080d7dL, + 0x2162cf7cL, 0xa4748079L, 0x931e4278L, 0xcaa0047aL, 0xfdcac67bL, + 0xb02ebc6cL, 0x87447e6dL, 0xdefa386fL, 0xe990fa6eL, 0x6c86b56bL, + 0x5bec776aL, 0x02523168L, 0x3538f369L, 0x087faf62L, 0x3f156d63L, + 0x66ab2b61L, 0x51c1e960L, 0xd4d7a665L, 0xe3bd6464L, 0xba032266L, + 0x8d69e067L, 0x20cbd748L, 0x17a11549L, 0x4e1f534bL, 0x7975914aL, + 0xfc63de4fL, 0xcb091c4eL, 0x92b75a4cL, 0xa5dd984dL, 0x989ac446L, + 0xaff00647L, 0xf64e4045L, 0xc1248244L, 0x4432cd41L, 0x73580f40L, + 0x2ae64942L, 0x1d8c8b43L, 0x5068f154L, 0x67023355L, 0x3ebc7557L, + 0x09d6b756L, 0x8cc0f853L, 0xbbaa3a52L, 0xe2147c50L, 0xd57ebe51L, + 0xe839e25aL, 0xdf53205bL, 0x86ed6659L, 0xb187a458L, 0x3491eb5dL, + 0x03fb295cL, 0x5a456f5eL, 0x6d2fad5fL, 0x801b35e1L, 0xb771f7e0L, + 0xeecfb1e2L, 0xd9a573e3L, 0x5cb33ce6L, 0x6bd9fee7L, 0x3267b8e5L, + 0x050d7ae4L, 0x384a26efL, 0x0f20e4eeL, 0x569ea2ecL, 0x61f460edL, + 0xe4e22fe8L, 0xd388ede9L, 0x8a36abebL, 0xbd5c69eaL, 0xf0b813fdL, + 0xc7d2d1fcL, 0x9e6c97feL, 0xa90655ffL, 0x2c101afaL, 0x1b7ad8fbL, + 0x42c49ef9L, 0x75ae5cf8L, 0x48e900f3L, 0x7f83c2f2L, 0x263d84f0L, + 0x115746f1L, 0x944109f4L, 0xa32bcbf5L, 0xfa958df7L, 0xcdff4ff6L, + 0x605d78d9L, 0x5737bad8L, 0x0e89fcdaL, 0x39e33edbL, 0xbcf571deL, + 0x8b9fb3dfL, 0xd221f5ddL, 0xe54b37dcL, 0xd80c6bd7L, 0xef66a9d6L, + 0xb6d8efd4L, 0x81b22dd5L, 0x04a462d0L, 0x33cea0d1L, 0x6a70e6d3L, + 0x5d1a24d2L, 0x10fe5ec5L, 0x27949cc4L, 0x7e2adac6L, 0x494018c7L, + 0xcc5657c2L, 0xfb3c95c3L, 0xa282d3c1L, 0x95e811c0L, 0xa8af4dcbL, + 0x9fc58fcaL, 0xc67bc9c8L, 0xf1110bc9L, 0x740744ccL, 0x436d86cdL, + 0x1ad3c0cfL, 0x2db902ceL, 0x4096af91L, 0x77fc6d90L, 0x2e422b92L, + 0x1928e993L, 0x9c3ea696L, 0xab546497L, 0xf2ea2295L, 0xc580e094L, + 0xf8c7bc9fL, 0xcfad7e9eL, 0x9613389cL, 0xa179fa9dL, 0x246fb598L, + 0x13057799L, 0x4abb319bL, 0x7dd1f39aL, 0x3035898dL, 0x075f4b8cL, + 0x5ee10d8eL, 0x698bcf8fL, 0xec9d808aL, 0xdbf7428bL, 0x82490489L, + 0xb523c688L, 0x88649a83L, 0xbf0e5882L, 0xe6b01e80L, 0xd1dadc81L, + 0x54cc9384L, 0x63a65185L, 0x3a181787L, 0x0d72d586L, 0xa0d0e2a9L, + 0x97ba20a8L, 0xce0466aaL, 0xf96ea4abL, 0x7c78ebaeL, 0x4b1229afL, + 0x12ac6fadL, 0x25c6adacL, 0x1881f1a7L, 0x2feb33a6L, 0x765575a4L, + 0x413fb7a5L, 0xc429f8a0L, 0xf3433aa1L, 0xaafd7ca3L, 0x9d97bea2L, + 0xd073c4b5L, 0xe71906b4L, 0xbea740b6L, 0x89cd82b7L, 0x0cdbcdb2L, + 0x3bb10fb3L, 0x620f49b1L, 0x55658bb0L, 0x6822d7bbL, 0x5f4815baL, + 0x06f653b8L, 0x319c91b9L, 0xb48adebcL, 0x83e01cbdL, 0xda5e5abfL, + 0xed3498beL + , + 0x00000000L, 0x6567bcb8L, 0x8bc809aaL, 0xeeafb512L, 0x5797628fL, + 0x32f0de37L, 0xdc5f6b25L, 0xb938d79dL, 0xef28b4c5L, 0x8a4f087dL, + 0x64e0bd6fL, 0x018701d7L, 0xb8bfd64aL, 0xddd86af2L, 0x3377dfe0L, + 0x56106358L, 0x9f571950L, 0xfa30a5e8L, 0x149f10faL, 0x71f8ac42L, + 0xc8c07bdfL, 0xada7c767L, 0x43087275L, 0x266fcecdL, 0x707fad95L, + 0x1518112dL, 0xfbb7a43fL, 0x9ed01887L, 0x27e8cf1aL, 0x428f73a2L, + 0xac20c6b0L, 0xc9477a08L, 0x3eaf32a0L, 0x5bc88e18L, 0xb5673b0aL, + 0xd00087b2L, 0x6938502fL, 0x0c5fec97L, 0xe2f05985L, 0x8797e53dL, + 0xd1878665L, 0xb4e03addL, 0x5a4f8fcfL, 0x3f283377L, 0x8610e4eaL, + 0xe3775852L, 0x0dd8ed40L, 0x68bf51f8L, 0xa1f82bf0L, 0xc49f9748L, + 0x2a30225aL, 0x4f579ee2L, 0xf66f497fL, 0x9308f5c7L, 0x7da740d5L, + 0x18c0fc6dL, 0x4ed09f35L, 0x2bb7238dL, 0xc518969fL, 0xa07f2a27L, + 0x1947fdbaL, 0x7c204102L, 0x928ff410L, 0xf7e848a8L, 0x3d58149bL, + 0x583fa823L, 0xb6901d31L, 0xd3f7a189L, 0x6acf7614L, 0x0fa8caacL, + 0xe1077fbeL, 0x8460c306L, 0xd270a05eL, 0xb7171ce6L, 0x59b8a9f4L, + 0x3cdf154cL, 0x85e7c2d1L, 0xe0807e69L, 0x0e2fcb7bL, 0x6b4877c3L, + 0xa20f0dcbL, 0xc768b173L, 0x29c70461L, 0x4ca0b8d9L, 0xf5986f44L, + 0x90ffd3fcL, 0x7e5066eeL, 0x1b37da56L, 0x4d27b90eL, 0x284005b6L, + 0xc6efb0a4L, 0xa3880c1cL, 0x1ab0db81L, 0x7fd76739L, 0x9178d22bL, + 0xf41f6e93L, 0x03f7263bL, 0x66909a83L, 0x883f2f91L, 0xed589329L, + 0x546044b4L, 0x3107f80cL, 0xdfa84d1eL, 0xbacff1a6L, 0xecdf92feL, + 0x89b82e46L, 0x67179b54L, 0x027027ecL, 0xbb48f071L, 0xde2f4cc9L, + 0x3080f9dbL, 0x55e74563L, 0x9ca03f6bL, 0xf9c783d3L, 0x176836c1L, + 0x720f8a79L, 0xcb375de4L, 0xae50e15cL, 0x40ff544eL, 0x2598e8f6L, + 0x73888baeL, 0x16ef3716L, 0xf8408204L, 0x9d273ebcL, 0x241fe921L, + 0x41785599L, 0xafd7e08bL, 0xcab05c33L, 0x3bb659edL, 0x5ed1e555L, + 0xb07e5047L, 0xd519ecffL, 0x6c213b62L, 0x094687daL, 0xe7e932c8L, + 0x828e8e70L, 0xd49eed28L, 0xb1f95190L, 0x5f56e482L, 0x3a31583aL, + 0x83098fa7L, 0xe66e331fL, 0x08c1860dL, 0x6da63ab5L, 0xa4e140bdL, + 0xc186fc05L, 0x2f294917L, 0x4a4ef5afL, 0xf3762232L, 0x96119e8aL, + 0x78be2b98L, 0x1dd99720L, 0x4bc9f478L, 0x2eae48c0L, 0xc001fdd2L, + 0xa566416aL, 0x1c5e96f7L, 0x79392a4fL, 0x97969f5dL, 0xf2f123e5L, + 0x05196b4dL, 0x607ed7f5L, 0x8ed162e7L, 0xebb6de5fL, 0x528e09c2L, + 0x37e9b57aL, 0xd9460068L, 0xbc21bcd0L, 0xea31df88L, 0x8f566330L, + 0x61f9d622L, 0x049e6a9aL, 0xbda6bd07L, 0xd8c101bfL, 0x366eb4adL, + 0x53090815L, 0x9a4e721dL, 0xff29cea5L, 0x11867bb7L, 0x74e1c70fL, + 0xcdd91092L, 0xa8beac2aL, 0x46111938L, 0x2376a580L, 0x7566c6d8L, + 0x10017a60L, 0xfeaecf72L, 0x9bc973caL, 0x22f1a457L, 0x479618efL, + 0xa939adfdL, 0xcc5e1145L, 0x06ee4d76L, 0x6389f1ceL, 0x8d2644dcL, + 0xe841f864L, 0x51792ff9L, 0x341e9341L, 0xdab12653L, 0xbfd69aebL, + 0xe9c6f9b3L, 0x8ca1450bL, 0x620ef019L, 0x07694ca1L, 0xbe519b3cL, + 0xdb362784L, 0x35999296L, 0x50fe2e2eL, 0x99b95426L, 0xfcdee89eL, + 0x12715d8cL, 0x7716e134L, 0xce2e36a9L, 0xab498a11L, 0x45e63f03L, + 0x208183bbL, 0x7691e0e3L, 0x13f65c5bL, 0xfd59e949L, 0x983e55f1L, + 0x2106826cL, 0x44613ed4L, 0xaace8bc6L, 0xcfa9377eL, 0x38417fd6L, + 0x5d26c36eL, 0xb389767cL, 0xd6eecac4L, 0x6fd61d59L, 0x0ab1a1e1L, + 0xe41e14f3L, 0x8179a84bL, 0xd769cb13L, 0xb20e77abL, 0x5ca1c2b9L, + 0x39c67e01L, 0x80fea99cL, 0xe5991524L, 0x0b36a036L, 0x6e511c8eL, + 0xa7166686L, 0xc271da3eL, 0x2cde6f2cL, 0x49b9d394L, 0xf0810409L, + 0x95e6b8b1L, 0x7b490da3L, 0x1e2eb11bL, 0x483ed243L, 0x2d596efbL, + 0xc3f6dbe9L, 0xa6916751L, 0x1fa9b0ccL, 0x7ace0c74L, 0x9461b966L, + 0xf10605deL +# endif /* IZ_CRCOPTIM_UNFOLDTBL */ +# else /* !IZ_CRC_BE_OPTIMIZ */ + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +# ifdef IZ_CRCOPTIM_UNFOLDTBL + , + 0x00000000L, 0x191b3141L, 0x32366282L, 0x2b2d53c3L, 0x646cc504L, + 0x7d77f445L, 0x565aa786L, 0x4f4196c7L, 0xc8d98a08L, 0xd1c2bb49L, + 0xfaefe88aL, 0xe3f4d9cbL, 0xacb54f0cL, 0xb5ae7e4dL, 0x9e832d8eL, + 0x87981ccfL, 0x4ac21251L, 0x53d92310L, 0x78f470d3L, 0x61ef4192L, + 0x2eaed755L, 0x37b5e614L, 0x1c98b5d7L, 0x05838496L, 0x821b9859L, + 0x9b00a918L, 0xb02dfadbL, 0xa936cb9aL, 0xe6775d5dL, 0xff6c6c1cL, + 0xd4413fdfL, 0xcd5a0e9eL, 0x958424a2L, 0x8c9f15e3L, 0xa7b24620L, + 0xbea97761L, 0xf1e8e1a6L, 0xe8f3d0e7L, 0xc3de8324L, 0xdac5b265L, + 0x5d5daeaaL, 0x44469febL, 0x6f6bcc28L, 0x7670fd69L, 0x39316baeL, + 0x202a5aefL, 0x0b07092cL, 0x121c386dL, 0xdf4636f3L, 0xc65d07b2L, + 0xed705471L, 0xf46b6530L, 0xbb2af3f7L, 0xa231c2b6L, 0x891c9175L, + 0x9007a034L, 0x179fbcfbL, 0x0e848dbaL, 0x25a9de79L, 0x3cb2ef38L, + 0x73f379ffL, 0x6ae848beL, 0x41c51b7dL, 0x58de2a3cL, 0xf0794f05L, + 0xe9627e44L, 0xc24f2d87L, 0xdb541cc6L, 0x94158a01L, 0x8d0ebb40L, + 0xa623e883L, 0xbf38d9c2L, 0x38a0c50dL, 0x21bbf44cL, 0x0a96a78fL, + 0x138d96ceL, 0x5ccc0009L, 0x45d73148L, 0x6efa628bL, 0x77e153caL, + 0xbabb5d54L, 0xa3a06c15L, 0x888d3fd6L, 0x91960e97L, 0xded79850L, + 0xc7cca911L, 0xece1fad2L, 0xf5facb93L, 0x7262d75cL, 0x6b79e61dL, + 0x4054b5deL, 0x594f849fL, 0x160e1258L, 0x0f152319L, 0x243870daL, + 0x3d23419bL, 0x65fd6ba7L, 0x7ce65ae6L, 0x57cb0925L, 0x4ed03864L, + 0x0191aea3L, 0x188a9fe2L, 0x33a7cc21L, 0x2abcfd60L, 0xad24e1afL, + 0xb43fd0eeL, 0x9f12832dL, 0x8609b26cL, 0xc94824abL, 0xd05315eaL, + 0xfb7e4629L, 0xe2657768L, 0x2f3f79f6L, 0x362448b7L, 0x1d091b74L, + 0x04122a35L, 0x4b53bcf2L, 0x52488db3L, 0x7965de70L, 0x607eef31L, + 0xe7e6f3feL, 0xfefdc2bfL, 0xd5d0917cL, 0xcccba03dL, 0x838a36faL, + 0x9a9107bbL, 0xb1bc5478L, 0xa8a76539L, 0x3b83984bL, 0x2298a90aL, + 0x09b5fac9L, 0x10aecb88L, 0x5fef5d4fL, 0x46f46c0eL, 0x6dd93fcdL, + 0x74c20e8cL, 0xf35a1243L, 0xea412302L, 0xc16c70c1L, 0xd8774180L, + 0x9736d747L, 0x8e2de606L, 0xa500b5c5L, 0xbc1b8484L, 0x71418a1aL, + 0x685abb5bL, 0x4377e898L, 0x5a6cd9d9L, 0x152d4f1eL, 0x0c367e5fL, + 0x271b2d9cL, 0x3e001cddL, 0xb9980012L, 0xa0833153L, 0x8bae6290L, + 0x92b553d1L, 0xddf4c516L, 0xc4eff457L, 0xefc2a794L, 0xf6d996d5L, + 0xae07bce9L, 0xb71c8da8L, 0x9c31de6bL, 0x852aef2aL, 0xca6b79edL, + 0xd37048acL, 0xf85d1b6fL, 0xe1462a2eL, 0x66de36e1L, 0x7fc507a0L, + 0x54e85463L, 0x4df36522L, 0x02b2f3e5L, 0x1ba9c2a4L, 0x30849167L, + 0x299fa026L, 0xe4c5aeb8L, 0xfdde9ff9L, 0xd6f3cc3aL, 0xcfe8fd7bL, + 0x80a96bbcL, 0x99b25afdL, 0xb29f093eL, 0xab84387fL, 0x2c1c24b0L, + 0x350715f1L, 0x1e2a4632L, 0x07317773L, 0x4870e1b4L, 0x516bd0f5L, + 0x7a468336L, 0x635db277L, 0xcbfad74eL, 0xd2e1e60fL, 0xf9ccb5ccL, + 0xe0d7848dL, 0xaf96124aL, 0xb68d230bL, 0x9da070c8L, 0x84bb4189L, + 0x03235d46L, 0x1a386c07L, 0x31153fc4L, 0x280e0e85L, 0x674f9842L, + 0x7e54a903L, 0x5579fac0L, 0x4c62cb81L, 0x8138c51fL, 0x9823f45eL, + 0xb30ea79dL, 0xaa1596dcL, 0xe554001bL, 0xfc4f315aL, 0xd7626299L, + 0xce7953d8L, 0x49e14f17L, 0x50fa7e56L, 0x7bd72d95L, 0x62cc1cd4L, + 0x2d8d8a13L, 0x3496bb52L, 0x1fbbe891L, 0x06a0d9d0L, 0x5e7ef3ecL, + 0x4765c2adL, 0x6c48916eL, 0x7553a02fL, 0x3a1236e8L, 0x230907a9L, + 0x0824546aL, 0x113f652bL, 0x96a779e4L, 0x8fbc48a5L, 0xa4911b66L, + 0xbd8a2a27L, 0xf2cbbce0L, 0xebd08da1L, 0xc0fdde62L, 0xd9e6ef23L, + 0x14bce1bdL, 0x0da7d0fcL, 0x268a833fL, 0x3f91b27eL, 0x70d024b9L, + 0x69cb15f8L, 0x42e6463bL, 0x5bfd777aL, 0xdc656bb5L, 0xc57e5af4L, + 0xee530937L, 0xf7483876L, 0xb809aeb1L, 0xa1129ff0L, 0x8a3fcc33L, + 0x9324fd72L + , + 0x00000000L, 0x01c26a37L, 0x0384d46eL, 0x0246be59L, 0x0709a8dcL, + 0x06cbc2ebL, 0x048d7cb2L, 0x054f1685L, 0x0e1351b8L, 0x0fd13b8fL, + 0x0d9785d6L, 0x0c55efe1L, 0x091af964L, 0x08d89353L, 0x0a9e2d0aL, + 0x0b5c473dL, 0x1c26a370L, 0x1de4c947L, 0x1fa2771eL, 0x1e601d29L, + 0x1b2f0bacL, 0x1aed619bL, 0x18abdfc2L, 0x1969b5f5L, 0x1235f2c8L, + 0x13f798ffL, 0x11b126a6L, 0x10734c91L, 0x153c5a14L, 0x14fe3023L, + 0x16b88e7aL, 0x177ae44dL, 0x384d46e0L, 0x398f2cd7L, 0x3bc9928eL, + 0x3a0bf8b9L, 0x3f44ee3cL, 0x3e86840bL, 0x3cc03a52L, 0x3d025065L, + 0x365e1758L, 0x379c7d6fL, 0x35dac336L, 0x3418a901L, 0x3157bf84L, + 0x3095d5b3L, 0x32d36beaL, 0x331101ddL, 0x246be590L, 0x25a98fa7L, + 0x27ef31feL, 0x262d5bc9L, 0x23624d4cL, 0x22a0277bL, 0x20e69922L, + 0x2124f315L, 0x2a78b428L, 0x2bbade1fL, 0x29fc6046L, 0x283e0a71L, + 0x2d711cf4L, 0x2cb376c3L, 0x2ef5c89aL, 0x2f37a2adL, 0x709a8dc0L, + 0x7158e7f7L, 0x731e59aeL, 0x72dc3399L, 0x7793251cL, 0x76514f2bL, + 0x7417f172L, 0x75d59b45L, 0x7e89dc78L, 0x7f4bb64fL, 0x7d0d0816L, + 0x7ccf6221L, 0x798074a4L, 0x78421e93L, 0x7a04a0caL, 0x7bc6cafdL, + 0x6cbc2eb0L, 0x6d7e4487L, 0x6f38fadeL, 0x6efa90e9L, 0x6bb5866cL, + 0x6a77ec5bL, 0x68315202L, 0x69f33835L, 0x62af7f08L, 0x636d153fL, + 0x612bab66L, 0x60e9c151L, 0x65a6d7d4L, 0x6464bde3L, 0x662203baL, + 0x67e0698dL, 0x48d7cb20L, 0x4915a117L, 0x4b531f4eL, 0x4a917579L, + 0x4fde63fcL, 0x4e1c09cbL, 0x4c5ab792L, 0x4d98dda5L, 0x46c49a98L, + 0x4706f0afL, 0x45404ef6L, 0x448224c1L, 0x41cd3244L, 0x400f5873L, + 0x4249e62aL, 0x438b8c1dL, 0x54f16850L, 0x55330267L, 0x5775bc3eL, + 0x56b7d609L, 0x53f8c08cL, 0x523aaabbL, 0x507c14e2L, 0x51be7ed5L, + 0x5ae239e8L, 0x5b2053dfL, 0x5966ed86L, 0x58a487b1L, 0x5deb9134L, + 0x5c29fb03L, 0x5e6f455aL, 0x5fad2f6dL, 0xe1351b80L, 0xe0f771b7L, + 0xe2b1cfeeL, 0xe373a5d9L, 0xe63cb35cL, 0xe7fed96bL, 0xe5b86732L, + 0xe47a0d05L, 0xef264a38L, 0xeee4200fL, 0xeca29e56L, 0xed60f461L, + 0xe82fe2e4L, 0xe9ed88d3L, 0xebab368aL, 0xea695cbdL, 0xfd13b8f0L, + 0xfcd1d2c7L, 0xfe976c9eL, 0xff5506a9L, 0xfa1a102cL, 0xfbd87a1bL, + 0xf99ec442L, 0xf85cae75L, 0xf300e948L, 0xf2c2837fL, 0xf0843d26L, + 0xf1465711L, 0xf4094194L, 0xf5cb2ba3L, 0xf78d95faL, 0xf64fffcdL, + 0xd9785d60L, 0xd8ba3757L, 0xdafc890eL, 0xdb3ee339L, 0xde71f5bcL, + 0xdfb39f8bL, 0xddf521d2L, 0xdc374be5L, 0xd76b0cd8L, 0xd6a966efL, + 0xd4efd8b6L, 0xd52db281L, 0xd062a404L, 0xd1a0ce33L, 0xd3e6706aL, + 0xd2241a5dL, 0xc55efe10L, 0xc49c9427L, 0xc6da2a7eL, 0xc7184049L, + 0xc25756ccL, 0xc3953cfbL, 0xc1d382a2L, 0xc011e895L, 0xcb4dafa8L, + 0xca8fc59fL, 0xc8c97bc6L, 0xc90b11f1L, 0xcc440774L, 0xcd866d43L, + 0xcfc0d31aL, 0xce02b92dL, 0x91af9640L, 0x906dfc77L, 0x922b422eL, + 0x93e92819L, 0x96a63e9cL, 0x976454abL, 0x9522eaf2L, 0x94e080c5L, + 0x9fbcc7f8L, 0x9e7eadcfL, 0x9c381396L, 0x9dfa79a1L, 0x98b56f24L, + 0x99770513L, 0x9b31bb4aL, 0x9af3d17dL, 0x8d893530L, 0x8c4b5f07L, + 0x8e0de15eL, 0x8fcf8b69L, 0x8a809decL, 0x8b42f7dbL, 0x89044982L, + 0x88c623b5L, 0x839a6488L, 0x82580ebfL, 0x801eb0e6L, 0x81dcdad1L, + 0x8493cc54L, 0x8551a663L, 0x8717183aL, 0x86d5720dL, 0xa9e2d0a0L, + 0xa820ba97L, 0xaa6604ceL, 0xaba46ef9L, 0xaeeb787cL, 0xaf29124bL, + 0xad6fac12L, 0xacadc625L, 0xa7f18118L, 0xa633eb2fL, 0xa4755576L, + 0xa5b73f41L, 0xa0f829c4L, 0xa13a43f3L, 0xa37cfdaaL, 0xa2be979dL, + 0xb5c473d0L, 0xb40619e7L, 0xb640a7beL, 0xb782cd89L, 0xb2cddb0cL, + 0xb30fb13bL, 0xb1490f62L, 0xb08b6555L, 0xbbd72268L, 0xba15485fL, + 0xb853f606L, 0xb9919c31L, 0xbcde8ab4L, 0xbd1ce083L, 0xbf5a5edaL, + 0xbe9834edL + , + 0x00000000L, 0xb8bc6765L, 0xaa09c88bL, 0x12b5afeeL, 0x8f629757L, + 0x37def032L, 0x256b5fdcL, 0x9dd738b9L, 0xc5b428efL, 0x7d084f8aL, + 0x6fbde064L, 0xd7018701L, 0x4ad6bfb8L, 0xf26ad8ddL, 0xe0df7733L, + 0x58631056L, 0x5019579fL, 0xe8a530faL, 0xfa109f14L, 0x42acf871L, + 0xdf7bc0c8L, 0x67c7a7adL, 0x75720843L, 0xcdce6f26L, 0x95ad7f70L, + 0x2d111815L, 0x3fa4b7fbL, 0x8718d09eL, 0x1acfe827L, 0xa2738f42L, + 0xb0c620acL, 0x087a47c9L, 0xa032af3eL, 0x188ec85bL, 0x0a3b67b5L, + 0xb28700d0L, 0x2f503869L, 0x97ec5f0cL, 0x8559f0e2L, 0x3de59787L, + 0x658687d1L, 0xdd3ae0b4L, 0xcf8f4f5aL, 0x7733283fL, 0xeae41086L, + 0x525877e3L, 0x40edd80dL, 0xf851bf68L, 0xf02bf8a1L, 0x48979fc4L, + 0x5a22302aL, 0xe29e574fL, 0x7f496ff6L, 0xc7f50893L, 0xd540a77dL, + 0x6dfcc018L, 0x359fd04eL, 0x8d23b72bL, 0x9f9618c5L, 0x272a7fa0L, + 0xbafd4719L, 0x0241207cL, 0x10f48f92L, 0xa848e8f7L, 0x9b14583dL, + 0x23a83f58L, 0x311d90b6L, 0x89a1f7d3L, 0x1476cf6aL, 0xaccaa80fL, + 0xbe7f07e1L, 0x06c36084L, 0x5ea070d2L, 0xe61c17b7L, 0xf4a9b859L, + 0x4c15df3cL, 0xd1c2e785L, 0x697e80e0L, 0x7bcb2f0eL, 0xc377486bL, + 0xcb0d0fa2L, 0x73b168c7L, 0x6104c729L, 0xd9b8a04cL, 0x446f98f5L, + 0xfcd3ff90L, 0xee66507eL, 0x56da371bL, 0x0eb9274dL, 0xb6054028L, + 0xa4b0efc6L, 0x1c0c88a3L, 0x81dbb01aL, 0x3967d77fL, 0x2bd27891L, + 0x936e1ff4L, 0x3b26f703L, 0x839a9066L, 0x912f3f88L, 0x299358edL, + 0xb4446054L, 0x0cf80731L, 0x1e4da8dfL, 0xa6f1cfbaL, 0xfe92dfecL, + 0x462eb889L, 0x549b1767L, 0xec277002L, 0x71f048bbL, 0xc94c2fdeL, + 0xdbf98030L, 0x6345e755L, 0x6b3fa09cL, 0xd383c7f9L, 0xc1366817L, + 0x798a0f72L, 0xe45d37cbL, 0x5ce150aeL, 0x4e54ff40L, 0xf6e89825L, + 0xae8b8873L, 0x1637ef16L, 0x048240f8L, 0xbc3e279dL, 0x21e91f24L, + 0x99557841L, 0x8be0d7afL, 0x335cb0caL, 0xed59b63bL, 0x55e5d15eL, + 0x47507eb0L, 0xffec19d5L, 0x623b216cL, 0xda874609L, 0xc832e9e7L, + 0x708e8e82L, 0x28ed9ed4L, 0x9051f9b1L, 0x82e4565fL, 0x3a58313aL, + 0xa78f0983L, 0x1f336ee6L, 0x0d86c108L, 0xb53aa66dL, 0xbd40e1a4L, + 0x05fc86c1L, 0x1749292fL, 0xaff54e4aL, 0x322276f3L, 0x8a9e1196L, + 0x982bbe78L, 0x2097d91dL, 0x78f4c94bL, 0xc048ae2eL, 0xd2fd01c0L, + 0x6a4166a5L, 0xf7965e1cL, 0x4f2a3979L, 0x5d9f9697L, 0xe523f1f2L, + 0x4d6b1905L, 0xf5d77e60L, 0xe762d18eL, 0x5fdeb6ebL, 0xc2098e52L, + 0x7ab5e937L, 0x680046d9L, 0xd0bc21bcL, 0x88df31eaL, 0x3063568fL, + 0x22d6f961L, 0x9a6a9e04L, 0x07bda6bdL, 0xbf01c1d8L, 0xadb46e36L, + 0x15080953L, 0x1d724e9aL, 0xa5ce29ffL, 0xb77b8611L, 0x0fc7e174L, + 0x9210d9cdL, 0x2aacbea8L, 0x38191146L, 0x80a57623L, 0xd8c66675L, + 0x607a0110L, 0x72cfaefeL, 0xca73c99bL, 0x57a4f122L, 0xef189647L, + 0xfdad39a9L, 0x45115eccL, 0x764dee06L, 0xcef18963L, 0xdc44268dL, + 0x64f841e8L, 0xf92f7951L, 0x41931e34L, 0x5326b1daL, 0xeb9ad6bfL, + 0xb3f9c6e9L, 0x0b45a18cL, 0x19f00e62L, 0xa14c6907L, 0x3c9b51beL, + 0x842736dbL, 0x96929935L, 0x2e2efe50L, 0x2654b999L, 0x9ee8defcL, + 0x8c5d7112L, 0x34e11677L, 0xa9362eceL, 0x118a49abL, 0x033fe645L, + 0xbb838120L, 0xe3e09176L, 0x5b5cf613L, 0x49e959fdL, 0xf1553e98L, + 0x6c820621L, 0xd43e6144L, 0xc68bceaaL, 0x7e37a9cfL, 0xd67f4138L, + 0x6ec3265dL, 0x7c7689b3L, 0xc4caeed6L, 0x591dd66fL, 0xe1a1b10aL, + 0xf3141ee4L, 0x4ba87981L, 0x13cb69d7L, 0xab770eb2L, 0xb9c2a15cL, + 0x017ec639L, 0x9ca9fe80L, 0x241599e5L, 0x36a0360bL, 0x8e1c516eL, + 0x866616a7L, 0x3eda71c2L, 0x2c6fde2cL, 0x94d3b949L, 0x090481f0L, + 0xb1b8e695L, 0xa30d497bL, 0x1bb12e1eL, 0x43d23e48L, 0xfb6e592dL, + 0xe9dbf6c3L, 0x516791a6L, 0xccb0a91fL, 0x740cce7aL, 0x66b96194L, + 0xde0506f1L +# endif /* IZ_CRCOPTIM_UNFOLDTBL */ +# endif /* ? IZ_CRC_BE_OPTIMIZ */ +}; +#endif /* ?DYNAMIC_CRC_TABLE */ + +/* use "OF((void))" here to work around a Borland TC++ 1.0 problem */ +#ifdef USE_ZLIB +ZCONST uLongf *get_crc_table OF((void)) +#else +ZCONST ulg near *get_crc_table OF((void)) +#endif +{ +#ifdef DYNAMIC_CRC_TABLE + if (CRC_TABLE_IS_EMPTY) + make_crc_table(); +#endif +#ifdef USE_ZLIB + return (ZCONST uLongf *)crc_table; +#else + return crc_table; +#endif +} + +#ifdef DYNALLOC_CRCTAB +void free_crc_table() +{ + if (!CRC_TABLE_IS_EMPTY) + { + nearfree((ulg near *)crc_table); + MARK_CRCTAB_EMPTY; + } +} +#endif + +#ifndef USE_ZLIB +#ifndef CRC_TABLE_ONLY +#ifndef ASM_CRC + +#define DO1(crc, buf) crc = CRC32(crc, *buf++, crc_32_tab) +#define DO2(crc, buf) DO1(crc, buf); DO1(crc, buf) +#define DO4(crc, buf) DO2(crc, buf); DO2(crc, buf) +#define DO8(crc, buf) DO4(crc, buf); DO4(crc, buf) + +#if (defined(IZ_CRC_BE_OPTIMIZ) || defined(IZ_CRC_LE_OPTIMIZ)) + +# ifdef IZ_CRCOPTIM_UNFOLDTBL +# ifdef IZ_CRC_BE_OPTIMIZ +# define DO_OPT4(c, buf4) c ^= *(buf4)++; \ + c = crc_32_tab[c & 0xff] ^ crc_32_tab[256+((c>>8) & 0xff)] ^ \ + crc_32_tab[2*256+((c>>16) & 0xff)] ^ crc_32_tab[3*256+(c>>24)] +# else /* !IZ_CRC_BE_OPTIMIZ */ +# define DO_OPT4(c, buf4) c ^= *(buf4)++; \ + c = crc_32_tab[3*256+(c & 0xff)] ^ crc_32_tab[2*256+((c>>8) & 0xff)] \ + ^ crc_32_tab[256+((c>>16) & 0xff)] ^ crc_32_tab[c>>24] +# endif /* ?IZ_CRC_BE_OPTIMIZ */ +# else /* !IZ_CRCOPTIM_UNFOLDTBL */ +# define DO_OPT4(c, buf4) c ^= *(buf4)++; \ + c = CRC32UPD(c, crc_32_tab); \ + c = CRC32UPD(c, crc_32_tab); \ + c = CRC32UPD(c, crc_32_tab); \ + c = CRC32UPD(c, crc_32_tab) +# endif /* ?IZ_CRCOPTIM_UNFOLDTBL */ + +# define DO_OPT16(crc, buf4) DO_OPT4(crc, buf4); DO_OPT4(crc, buf4); \ + DO_OPT4(crc, buf4); DO_OPT4(crc, buf4); + +#endif /* (IZ_CRC_BE_OPTIMIZ || IZ_CRC_LE_OPTIMIZ) */ + + +/* ========================================================================= */ +ulg crc32(crc, buf, len) + ulg crc; /* crc shift register */ + register ZCONST uch *buf; /* pointer to bytes to pump through */ + extent len; /* number of bytes in buf[] */ +/* Run a set of bytes through the crc shift register. If buf is a NULL + pointer, then initialize the crc shift register contents instead. + Return the current crc in either case. */ +{ + register z_uint4 c; + register ZCONST ulg near *crc_32_tab; + + if (buf == NULL) return 0L; + + crc_32_tab = get_crc_table(); + + c = (REV_BE((z_uint4)crc) ^ 0xffffffffL); + +#if (defined(IZ_CRC_BE_OPTIMIZ) || defined(IZ_CRC_LE_OPTIMIZ)) + /* Align buf pointer to next DWORD boundary. */ + while (len && ((ptrdiff_t)buf & 3)) { + DO1(c, buf); + len--; + } + { + ZCONST z_uint4 *buf4 = (ZCONST z_uint4 *)buf; + while (len >= 16) { + DO_OPT16(c, buf4); + len -= 16; + } + while (len >= 4) { + DO_OPT4(c, buf4); + len -= 4; + } + buf = (ZCONST uch *)buf4; + } +#else /* !(IZ_CRC_BE_OPTIMIZ || IZ_CRC_LE_OPTIMIZ) */ +#ifndef NO_UNROLLED_LOOPS + while (len >= 8) { + DO8(c, buf); + len -= 8; + } +#endif /* !NO_UNROLLED_LOOPS */ +#endif /* ?(IZ_CRC_BE_OPTIMIZ || IZ_CRC_LE_OPTIMIZ) */ + if (len) do { + DO1(c, buf); + } while (--len); + + return REV_BE(c) ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ +} +#endif /* !ASM_CRC */ +#endif /* !CRC_TABLE_ONLY */ +#endif /* !USE_ZLIB */ +#endif /* !USE_ZLIB || USE_OWN_CRCTAB */ diff --git a/crc32.h b/crc32.h new file mode 100644 index 0000000..83af240 --- /dev/null +++ b/crc32.h @@ -0,0 +1,60 @@ +/* + Copyright (c) 1990-2008 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* crc32.h -- compute the CRC-32 of a data stream + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef __crc32_h +#define __crc32_h /* identifies this source module */ + +/* This header should be read AFTER zip.h resp. unzip.h + * (the latter with UNZIP_INTERNAL defined...). + */ + +#ifndef OF +# define OF(a) a +#endif +#ifndef ZCONST +# define ZCONST const +#endif + +#ifdef DYNALLOC_CRCTAB + void free_crc_table OF((void)); +#endif +#ifndef USE_ZLIB + ZCONST ulg near *get_crc_table OF((void)); +#endif +#if (defined(USE_ZLIB) || defined(CRC_TABLE_ONLY)) +# ifdef IZ_CRC_BE_OPTIMIZ +# undef IZ_CRC_BE_OPTIMIZ +# endif +#else /* !(USE_ZLIB || CRC_TABLE_ONLY) */ + ulg crc32 OF((ulg crc, ZCONST uch *buf, extent len)); +#endif /* ?(USE_ZLIB || CRC_TABLE_ONLY) */ + +#ifndef CRC_32_TAB +# define CRC_32_TAB crc_32_tab +#endif + +#ifdef CRC32 +# undef CRC32 +#endif +#ifdef IZ_CRC_BE_OPTIMIZ +# define CRC32UPD(c, crctab) (crctab[((c) >> 24)] ^ ((c) << 8)) +# define CRC32(c, b, crctab) (crctab[(((int)(c) >> 24) ^ (b))] ^ ((c) << 8)) +# define REV_BE(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ + (((w)&0xff00)<<8)+(((w)&0xff)<<24)) +#else +# define CRC32UPD(c, crctab) (crctab[((int)(c)) & 0xff] ^ ((c) >> 8)) +# define CRC32(c, b, crctab) (crctab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8)) +# define REV_BE(w) w +#endif + +#endif /* !__crc32_h */ diff --git a/crc_i386.S b/crc_i386.S new file mode 100644 index 0000000..38dbc86 --- /dev/null +++ b/crc_i386.S @@ -0,0 +1,304 @@ +/* + Copyright (c) 1990-2007 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + * crc_i386.S, optimized CRC calculation function for Zip and UnZip, + * created by Paul Kienitz and Christian Spieler. Last revised 07 Jan 2007. + * + * GRR 961110: incorporated Scott Field optimizations from win32/crc_i386.asm + * => overall 6% speedup in "unzip -tq" on 9MB zipfile (486-66) + * + * SPC 970402: revised for Rodney Brown's optimizations (32-bit-wide + * aligned reads for most of the data from buffer), can be + * disabled by defining the macro NO_32_BIT_LOADS + * + * SPC 971012: added Rodney Brown's additional tweaks for 32-bit-optimized + * CPUs (like the Pentium Pro, Pentium II, and probably some + * Pentium clones). This optimization is controlled by the + * preprocessor switch "__686" and is disabled by default. + * (This default is based on the assumption that most users + * do not yet work on a Pentium Pro or Pentium II machine ...) + * + * COS 050116: Enabled the 686 build by default, because there are hardly any + * pre-686 CPUs in serious use nowadays. (See SPC 970402 above.) + * + * SPC 060103: Updated code to incorporate newer optimizations found in zlib. + * + * SPC 070107: Added conditional switch to deactivate crc32() compilation. + * + * FLAT memory model assumed. Calling interface: + * - args are pushed onto the stack from right to left, + * - return value is given in the EAX register, + * - all other registers (with exception of EFLAGS) are preserved. (With + * GNU C 2.7.x, %edx and %ecx are `scratch' registers, but preserving + * them nevertheless adds only 4 single byte instructions.) + * + * This source generates the function + * ulg crc32(ulg crc, ZCONST uch *buf, extent len). + * + * Loop unrolling can be disabled by defining the macro NO_UNROLLED_LOOPS. + * This results in shorter code at the expense of reduced performance. + */ + +/* This file is NOT used in conjunction with zlib, or when only creation of + * the basic CRC_32_Table (for other purpose) is requested. + */ +#if !defined(USE_ZLIB) && !defined(CRC_TABLE_ONLY) + +/* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix + * external symbols with an underline character '_'. + */ +#if defined(NO_UNDERLINE) || defined(__ELF__) +# define _crc32 crc32 +# define _get_crc_table get_crc_table +#endif +/* Use 16-byte alignment if your assembler supports it. Warning: gas + * uses a log(x) parameter (.align 4 means 16-byte alignment). On SVR4 + * the parameter is a number of bytes. + */ +#ifndef ALIGNMENT +# define ALIGNMENT .align 4,0x90 +#endif + +#if defined(i386) || defined(_i386) || defined(_I386) || defined(__i386) + +/* This version is for 386 Unix, OS/2, MSDOS in 32 bit mode (gcc & gas). + * Warning: it uses the AT&T syntax: mov source,dest + * This file is only optional. If you want to use the C version, + * remove -DASM_CRC from CFLAGS in Makefile and set OBJA to an empty string. + */ + + .file "crc_i386.S" + +#if !defined(PRE_686) && !defined(__686) + /* Optimize for Pentium Pro and compatible CPUs by default. */ +# define __686 +#endif + +#if defined(NO_STD_STACKFRAME) && defined(USE_STD_STACKFRAME) +# undef USE_STACKFRAME +#else + /* The default is to use standard stack frame entry, because it + * results in smaller code! + */ +# ifndef USE_STD_STACKFRAME +# define USE_STD_STACKFRAME +# endif +#endif + +#ifdef USE_STD_STACKFRAME +# define _STD_ENTRY pushl %ebp ; movl %esp,%ebp +# define arg1 8(%ebp) +# define arg2 12(%ebp) +# define arg3 16(%ebp) +# define _STD_LEAVE popl %ebp +#else /* !USE_STD_STACKFRAME */ +# define _STD_ENTRY +# define arg1 24(%esp) +# define arg2 28(%esp) +# define arg3 32(%esp) +# define _STD_LEAVE +#endif /* ?USE_STD_STACKFRAME */ + +/* + * These two (three) macros make up the loop body of the CRC32 cruncher. + * registers modified: + * eax : crc value "c" + * esi : pointer to next data byte (or lword) "buf++" + * registers read: + * edi : pointer to base of crc_table array + * scratch registers: + * ebx : index into crc_table array + * (requires upper three bytes = 0 when __686 is undefined) + */ +#ifndef __686 /* optimize for 386, 486, Pentium */ +#define Do_CRC /* c = (c >> 8) ^ table[c & 0xFF] */\ + movb %al, %bl ;/* tmp = c & 0xFF */\ + shrl $8, %eax ;/* c = (c >> 8) */\ + xorl (%edi, %ebx, 4), %eax ;/* c ^= table[tmp] */ +#else /* __686 : optimize for Pentium Pro and compatible CPUs */ +#define Do_CRC /* c = (c >> 8) ^ table[c & 0xFF] */\ + movzbl %al, %ebx ;/* tmp = c & 0xFF */\ + shrl $8, %eax ;/* c = (c >> 8) */\ + xorl (%edi, %ebx, 4), %eax ;/* c ^=table[tmp] */ +#endif /* ?__686 */ + +#define Do_CRC_byte /* c = (c >> 8) ^ table[(c^*buf++)&0xFF] */\ + xorb (%esi), %al ;/* c ^= *buf */\ + incl %esi ;/* buf++ */\ + Do_CRC + +#define Do_CRC_byteof(ofs) /* c = (c >> 8) ^ table[(c^*buf++)&0xFF] */\ + xorb ofs(%esi), %al ;/* c ^= *buf */\ + incl %esi ;/* buf++ */\ + Do_CRC + +#ifndef NO_32_BIT_LOADS +# ifdef IZ_CRCOPTIM_UNFOLDTBL + /* the edx register is needed in crc calculation */ +# define SavLen arg3 +# define UpdCRC_lword \ + movzbl %al, %ebx ; \ + movl 3072(%edi,%ebx,4), %edx ; \ + movzbl %ah, %ebx ; \ + shrl $16, %eax ; \ + xor 2048(%edi,%ebx,4), %edx ; \ + movzbl %al, %ebx ; \ + shrl $8,%eax ; \ + xorl 1024(%edi,%ebx,4), %edx ; \ + movl (%edi,%eax,4), %eax ; \ + xorl %edx,%eax ; +# define UpdCRC_lword_sh(dwPtrIncr) \ + movzbl %al, %ebx ; \ + movl 3072(%edi,%ebx,4), %edx ; \ + movzbl %ah, %ebx ; \ + shrl $16, %eax ; \ + xor 2048(%edi,%ebx,4), %edx ; \ + movzbl %al, %ebx ; \ + addl $4*(dwPtrIncr), %esi ;/* ((ulg *)buf)+=dwPtrIncr */\ + shrl $8,%eax ; \ + xorl 1024(%edi,%ebx,4), %edx ; \ + movl (%edi,%eax,4),%eax ; \ + xorl %edx,%eax ; +# else /* !IZ_CRCOPTIM_UNFOLDTBL */ + /* the edx register is not needed anywhere else */ +# define SavLen %edx +# define UpdCRC_lword \ + Do_CRC \ + Do_CRC \ + Do_CRC \ + Do_CRC +# define UpdCRC_lword_sh(dwPtrIncr) \ + Do_CRC \ + Do_CRC \ + addl $4*(dwPtrIncr), %esi ;/* ((ulg *)buf)++ */\ + Do_CRC \ + Do_CRC +# endif /* ?IZ_CRCOPTIM_UNFOLDTBL */ +#define Do_CRC_lword \ + xorl (%esi), %eax ;/* c ^= *(ulg *)buf */\ + UpdCRC_lword_sh(1) /* ... ((ulg *)buf)++ */ +#define Do_CRC_4lword \ + xorl (%esi), %eax ;/* c ^= *(ulg *)buf */\ + UpdCRC_lword \ + xorl 4(%esi), %eax ;/* c ^= *((ulg *)buf+1) */\ + UpdCRC_lword \ + xorl 8(%esi), %eax ;/* c ^= *((ulg *)buf+2) */\ + UpdCRC_lword \ + xorl 12(%esi), %eax ;/* c ^= *((ulg *)buf]+3 */\ + UpdCRC_lword_sh(4) /* ... ((ulg *)buf)+=4 */ +#endif /* !NO_32_BIT_LOADS */ + + + .text + + .globl _crc32 + +_crc32: /* ulg crc32(ulg crc, uch *buf, extent len) */ + _STD_ENTRY + pushl %edi + pushl %esi + pushl %ebx + pushl %edx + pushl %ecx + + movl arg2, %esi /* 2nd arg: uch *buf */ + subl %eax, %eax /* > if (!buf) */ + testl %esi, %esi /* > return 0; */ + jz .L_fine /* > else { */ + call _get_crc_table + movl %eax, %edi + movl arg1, %eax /* 1st arg: ulg crc */ +#ifndef __686 + subl %ebx, %ebx /* ebx=0; bl usable as dword */ +#endif + movl arg3, %ecx /* 3rd arg: extent len */ + notl %eax /* > c = ~crc; */ + + testl %ecx, %ecx +#ifndef NO_UNROLLED_LOOPS + jz .L_bail +# ifndef NO_32_BIT_LOADS + /* Assert now have positive length */ +.L_align_loop: + testl $3, %esi /* Align buf on lword boundary */ + jz .L_aligned_now + Do_CRC_byte + decl %ecx + jnz .L_align_loop +.L_aligned_now: +# endif /* !NO_32_BIT_LOADS */ + movl %ecx, SavLen /* save current value of len */ + shrl $4, %ecx /* ecx = len / 16 */ + jz .L_No_Sixteens +/* align loop head at start of 486 internal cache line !! */ + ALIGNMENT +.L_Next_Sixteen: +# ifndef NO_32_BIT_LOADS + Do_CRC_4lword +# else /* NO_32_BIT_LOADS */ + Do_CRC_byteof(0) + Do_CRC_byteof(1) + Do_CRC_byteof(2) + Do_CRC_byteof(3) + Do_CRC_byteof(4) + Do_CRC_byteof(5) + Do_CRC_byteof(6) + Do_CRC_byteof(7) + Do_CRC_byteof(8) + Do_CRC_byteof(9) + Do_CRC_byteof(10) + Do_CRC_byteof(11) + Do_CRC_byteof(12) + Do_CRC_byteof(13) + Do_CRC_byteof(14) + Do_CRC_byteof(15) + addl $16,%esi ;/* buf += 16 */ +# endif /* ?NO_32_BIT_LOADS */ + decl %ecx + jnz .L_Next_Sixteen + +.L_No_Sixteens: + movl SavLen, %ecx + andl $15, %ecx /* ecx = len % 16 */ +# ifndef NO_32_BIT_LOADS + shrl $2,%ecx /* ecx = len / 4 */ + jz .L_No_Fours +.L_Next_Four: + Do_CRC_lword + decl %ecx + jnz .L_Next_Four +.L_No_Fours: + movl SavLen,%ecx + andl $3,%ecx /* ecx = len % 4 */ +# endif /* !NO_32_BIT_LOADS */ +#endif /* !NO_UNROLLED_LOOPS */ + jz .L_bail /* > if (len) */ +/* align loop head at start of 486 internal cache line !! */ + ALIGNMENT +.L_loupe: /* > do { */ + Do_CRC_byte /* c = CRC32(c,*buf++,crctab);*/ + decl %ecx /* > } while (--len); */ + jnz .L_loupe + +.L_bail: /* > } */ + notl %eax /* > return ~c; */ +.L_fine: + popl %ecx + popl %edx + popl %ebx + popl %esi + popl %edi + _STD_LEAVE + ret + +#else + error: this asm version is for 386 only +#endif /* i386 || _i386 || _I386 || __i386 */ + +#endif /* !USE_ZLIB && !CRC_TABLE_ONLY */ diff --git a/crypt.c b/crypt.c new file mode 100644 index 0000000..cc974ec --- /dev/null +++ b/crypt.c @@ -0,0 +1,690 @@ +/* + Copyright (c) 1990-2008 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 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 +*/ +/* + crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] + + The main encryption/decryption source code for Info-Zip software was + originally written in Europe. To the best of our knowledge, it can + be freely distributed in both source and object forms from any country, + including the USA under License Exception TSU of the U.S. Export + Administration Regulations (section 740.13(e)) of 6 June 2002. + + NOTE on copyright history: + Previous versions of this source package (up to version 2.8) were + not copyrighted and put in the public domain. If you cannot comply + with the Info-Zip LICENSE, you may want to look for one of those + public domain versions. + */ + +/* + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + */ + +#define ZCRYPT_INTERNAL +#include "zip.h" +#include "crypt.h" +#include "ttyio.h" + +#if CRYPT + +#ifndef FALSE +# define FALSE 0 +#endif + +#ifdef ZIP + /* For the encoding task used in Zip (and ZipCloak), we want to initialize + the crypt algorithm with some reasonably unpredictable bytes, see + the crypthead() function. The standard rand() library function is + used to supply these `random' bytes, which in turn is initialized by + a srand() call. The srand() function takes an "unsigned" (at least 16bit) + seed value as argument to determine the starting point of the rand() + pseudo-random number generator. + This seed number is constructed as "Seed = Seed1 .XOR. Seed2" with + Seed1 supplied by the current time (= "(unsigned)time()") and Seed2 + as some (hopefully) nondeterministic bitmask. On many (most) systems, + we use some "process specific" number, as the PID or something similar, + but when nothing unpredictable is available, a fixed number may be + sufficient. + NOTE: + 1.) This implementation requires the availability of the following + standard UNIX C runtime library functions: time(), rand(), srand(). + On systems where some of them are missing, the environment that + incorporates the crypt routines must supply suitable replacement + functions. + 2.) It is a very bad idea to use a second call to time() to set the + "Seed2" number! In this case, both "Seed1" and "Seed2" would be + (almost) identical, resulting in a (mostly) "zero" constant seed + number passed to srand(). + + The implementation environment defined in the "zip.h" header should + supply a reasonable definition for ZCR_SEED2 (an unsigned number; for + most implementations of rand() and srand(), only the lower 16 bits are + significant!). An example that works on many systems would be + "#define ZCR_SEED2 (unsigned)getpid()". + The default definition for ZCR_SEED2 supplied below should be regarded + as a fallback to allow successful compilation in "beta state" + environments. + */ +# include /* time() function supplies first part of crypt seed */ + /* "last resort" source for second part of crypt seed pattern */ +# ifndef ZCR_SEED2 +# define ZCR_SEED2 (unsigned)3141592654L /* use PI as default pattern */ +# endif +# ifdef GLOBAL /* used in Amiga system headers, maybe others too */ +# undef GLOBAL +# endif +# define GLOBAL(g) g +#else /* !ZIP */ +# define GLOBAL(g) G.g +#endif /* ?ZIP */ + + +#ifdef UNZIP + /* char *key = (char *)NULL; moved to globals.h */ +# ifndef FUNZIP + local int testp OF((__GPRO__ ZCONST uch *h)); + local int testkey OF((__GPRO__ ZCONST uch *h, ZCONST char *key)); +# endif +#else /* def UNZIP */ /* moved to globals.h for UnZip */ + local z_uint4 keys[3]; /* keys defining the pseudo-random sequence */ +#endif /* def UNZIP [else] */ + +#ifndef Trace +# ifdef CRYPT_DEBUG +# define Trace(x) fprintf x +# else +# define Trace(x) +# endif +#endif + +#include "crc32.h" + +#ifdef IZ_CRC_BE_OPTIMIZ + local z_uint4 near crycrctab[256]; + local z_uint4 near *cry_crctb_p = NULL; + local z_uint4 near *crytab_init OF((__GPRO)); +# define CRY_CRC_TAB cry_crctb_p +# undef CRC32 +# define CRC32(c, b, crctab) (crctab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8)) +#else +# define CRY_CRC_TAB CRC_32_TAB +#endif /* ?IZ_CRC_BE_OPTIMIZ */ + +/*********************************************************************** + * Return the next byte in the pseudo-random sequence + */ +int decrypt_byte(__G) + __GDEF +{ + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an + * unpredictable manner on 16-bit systems; not a problem + * with any known compiler so far, though */ + + temp = ((unsigned)GLOBAL(keys[2]) & 0xffff) | 2; + return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); +} + +/*********************************************************************** + * Update the encryption keys with the next byte of plain text + */ +int update_keys(__G__ c) + __GDEF + int c; /* byte of plain text */ +{ + GLOBAL(keys[0]) = CRC32(GLOBAL(keys[0]), c, CRY_CRC_TAB); + GLOBAL(keys[1]) = (GLOBAL(keys[1]) + + (GLOBAL(keys[0]) & 0xff)) + * 134775813L + 1; + { + register int keyshift = (int)(GLOBAL(keys[1]) >> 24); + GLOBAL(keys[2]) = CRC32(GLOBAL(keys[2]), keyshift, CRY_CRC_TAB); + } + return c; +} + + +/*********************************************************************** + * Initialize the encryption keys and the random header according to + * the given password. + */ +void init_keys(__G__ passwd) + __GDEF + ZCONST char *passwd; /* password string with which to modify keys */ +{ +#ifdef IZ_CRC_BE_OPTIMIZ + if (cry_crctb_p == NULL) { + cry_crctb_p = crytab_init(__G); + } +#endif + GLOBAL(keys[0]) = 305419896L; + GLOBAL(keys[1]) = 591751049L; + GLOBAL(keys[2]) = 878082192L; + while (*passwd != '\0') { + update_keys(__G__ (int)*passwd); + passwd++; + } +} + + +/*********************************************************************** + * Initialize the local copy of the table of precomputed crc32 values. + * Whereas the public crc32-table is optimized for crc32 calculations + * on arrays of bytes, the crypt code needs the crc32 values in an + * byte-order-independent form as 32-bit unsigned numbers. On systems + * with Big-Endian byte order using the optimized crc32 code, this + * requires inverting the byte-order of the values in the + * crypt-crc32-table. + */ +#ifdef IZ_CRC_BE_OPTIMIZ +local z_uint4 near *crytab_init(__G) + __GDEF +{ + int i; + + for (i = 0; i < 256; i++) { + crycrctab[i] = REV_BE(CRC_32_TAB[i]); + } + return crycrctab; +} +#endif + + +#ifdef ZIP + +/*********************************************************************** + * Write encryption header to file zfile using the password passwd + * and the cyclic redundancy check crc. + */ +void crypthead(passwd, crc) + ZCONST char *passwd; /* password string */ + ulg crc; /* crc of file being encrypted */ +{ + int n; /* index in random header */ + int t; /* temporary */ + int c; /* random byte */ + uch header[RAND_HEAD_LEN]; /* random header */ + static unsigned calls = 0; /* ensure different random header each time */ + + /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the + * output of rand() to get less predictability, since rand() is + * often poorly implemented. + */ + if (++calls == 1) { + srand((unsigned)time(NULL) ^ ZCR_SEED2); + } + init_keys(passwd); + for (n = 0; n < RAND_HEAD_LEN-2; n++) { + c = (rand() >> 7) & 0xff; + header[n] = (uch)zencode(c, t); + } + /* Encrypt random header (last two bytes is high word of crc) */ + init_keys(passwd); + for (n = 0; n < RAND_HEAD_LEN-2; n++) { + header[n] = (uch)zencode(header[n], t); + } + header[RAND_HEAD_LEN-2] = (uch)zencode((int)(crc >> 16) & 0xff, t); + header[RAND_HEAD_LEN-1] = (uch)zencode((int)(crc >> 24) & 0xff, t); + bfwrite(header, 1, RAND_HEAD_LEN, BFWRITE_DATA); +} + + +#ifdef UTIL + +/*********************************************************************** + * Encrypt the zip entry described by z from file in_file to file y + * using the password passwd. Return an error code in the ZE_ class. + */ +int zipcloak(z, passwd) + struct zlist far *z; /* zip entry to encrypt */ + ZCONST char *passwd; /* password string */ +{ + int c; /* input byte */ + int res; /* result code */ + zoff_t n; /* holds offset and counts size */ + int t; /* temporary */ + struct zlist far *localz; /* local header */ + uch buf[1024]; /* write buffer */ + int b; /* bytes in buffer */ + + /* Set encrypted bit, clear extended local header bit and write local + header to output file */ + if ((n = (zoff_t)zftello(y)) == (zoff_t)-1L) return ZE_TEMP; + + /* assume this archive is one disk and the file is open */ + + /* read the local header */ + res = readlocal(&localz, z); + + /* update disk and offset */ + z->dsk = 0; + z->off = n; + + /* Set encryption and unset any extended local header */ + z->flg |= 1, z->flg &= ~8; + localz->lflg |= 1, localz->lflg &= ~8; + + /* Add size of encryption header */ + localz->siz += RAND_HEAD_LEN; + z->siz = localz->siz; + + /* Put the local header */ + if ((res = putlocal(localz, PUTLOCAL_WRITE)) != ZE_OK) return res; + + /* Initialize keys with password and write random header */ + crypthead(passwd, localz->crc); + + /* Encrypt data */ + b = 0; + for (n = z->siz - RAND_HEAD_LEN; n; n--) { + if ((c = getc(in_file)) == EOF) { + return ferror(in_file) ? ZE_READ : ZE_EOF; + } + buf[b] = (uch)zencode(c, t); + b++; + if (b >= 1024) { + /* write the buffer */ + bfwrite(buf, 1, b, BFWRITE_DATA); + b = 0; + } + } + if (b) { + /* write the buffer */ + bfwrite(buf, 1, b, BFWRITE_DATA); + b = 0; + } + + /* Since we seek to the start of each local header can skip + reading any extended local header */ + /* + if ((flag & 8) != 0 && zfseeko(in_file, 16L, SEEK_CUR)) { + return ferror(in_file) ? ZE_READ : ZE_EOF; + } + if (fflush(y) == EOF) return ZE_TEMP; + */ + + /* Update number of bytes written to output file */ + tempzn += (4 + LOCHEAD) + localz->nam + localz->ext + localz->siz; + + /* Free local header */ + if (localz->ext) free(localz->extra); + if (localz->nam) free(localz->iname); + if (localz->nam) free(localz->name); +#ifdef UNICODE_SUPPORT + if (localz->uname) free(localz->uname); +#endif + free(localz); + + return ZE_OK; +} + +/*********************************************************************** + * Decrypt the zip entry described by z from file in_file to file y + * using the password passwd. Return an error code in the ZE_ class. + */ +int zipbare(z, passwd) + struct zlist far *z; /* zip entry to encrypt */ + ZCONST char *passwd; /* password string */ +{ +#ifdef ZIP10 + int c0 /* byte preceding the last input byte */ +#endif + int c1; /* last input byte */ + /* all file offset and size now zoff_t - 8/28/04 EG */ + zoff_t size; /* size of input data */ + struct zlist far *localz; /* local header */ + uch buf[1024]; /* write buffer */ + int b; /* bytes in buffer */ + zoff_t n; + int r; /* size of encryption header */ + int res; /* return code */ + + /* Save position */ + if ((n = (zoff_t)zftello(y)) == (zoff_t)-1L) return ZE_TEMP; + + /* Read local header */ + res = readlocal(&localz, z); + + /* Update disk and offset */ + z->dsk = 0; + z->off = n; + + /* Initialize keys with password */ + init_keys(passwd); + + /* Decrypt encryption header, save last two bytes */ + c1 = 0; + for (r = RAND_HEAD_LEN; r; r--) { +#ifdef ZIP10 + c0 = c1; +#endif + if ((c1 = getc(in_file)) == EOF) { + return ferror(in_file) ? ZE_READ : ZE_EOF; + } + Trace((stdout, " (%02x)", c1)); + zdecode(c1); + Trace((stdout, " %02x", c1)); + } + Trace((stdout, "\n")); + + /* If last two bytes of header don't match crc (or file time in the + * case of an extended local header), back up and just copy. For + * pkzip 2.0, the check has been reduced to one byte only. + */ +#ifdef ZIP10 + if ((ush)(c0 | (c1<<8)) != + (z->flg & 8 ? (ush) z->tim & 0xffff : (ush)(z->crc >> 16))) { +#else + if ((ush)c1 != (z->flg & 8 ? (ush) z->tim >> 8 : (ush)(z->crc >> 24))) { +#endif + if (zfseeko(in_file, n, SEEK_SET)) { + return ferror(in_file) ? ZE_READ : ZE_EOF; + } + if ((res = zipcopy(z)) != ZE_OK) { + ziperr(res, "was copying an entry"); + } + return ZE_MISS; + } + + z->siz -= RAND_HEAD_LEN; + localz->siz = z->siz; + + localz->flg = z->flg &= ~9; + z->lflg = localz->lflg &= ~9; + + if ((res = putlocal(localz, PUTLOCAL_WRITE)) != ZE_OK) return res; + + /* Decrypt data */ + b = 0; + for (size = z->siz; size; size--) { + if ((c1 = getc(in_file)) == EOF) { + return ferror(in_file) ? ZE_READ : ZE_EOF; + } + zdecode(c1); + buf[b] = c1; + b++; + if (b >= 1024) { + /* write the buffer */ + bfwrite(buf, 1, b, BFWRITE_DATA); + b = 0; + } + } + if (b) { + /* write the buffer */ + bfwrite(buf, 1, b, BFWRITE_DATA); + b = 0; + } + /* Since we seek to the start of each local header can skip + reading any extended local header */ + + /* Update number of bytes written to output file */ + tempzn += (4 + LOCHEAD) + localz->nam + localz->ext + localz->siz; + + /* Free local header */ + if (localz->ext) free(localz->extra); + if (localz->nam) free(localz->iname); + if (localz->nam) free(localz->name); +#ifdef UNICODE_SUPPORT + if (localz->uname) free(localz->uname); +#endif + free(localz); + + return ZE_OK; +} + + +#else /* !UTIL */ + +/*********************************************************************** + * If requested, encrypt the data in buf, and in any case call fwrite() + * with the arguments to zfwrite(). Return what fwrite() returns. + * + * now write to global y + * + * A bug has been found when encrypting large files that don't + * compress. See trees.c for the details and the fix. + */ +unsigned zfwrite(buf, item_size, nb) + zvoid *buf; /* data buffer */ + extent item_size; /* size of each item in bytes */ + extent nb; /* number of items */ +#if 0 + FILE *f; /* file to write to */ +#endif +{ + int t; /* temporary */ + + if (key != (char *)NULL) { /* key is the global password pointer */ + ulg size; /* buffer size */ + char *p = (char *)buf; /* steps through buffer */ + + /* Encrypt data in buffer */ + for (size = item_size*(ulg)nb; size != 0; p++, size--) { + *p = (char)zencode(*p, t); + } + } + /* Write the buffer out */ + return bfwrite(buf, item_size, nb, BFWRITE_DATA); +} + +#endif /* ?UTIL */ +#endif /* ZIP */ + + +#if (defined(UNZIP) && !defined(FUNZIP)) + +/*********************************************************************** + * Get the password and set up keys for current zipfile member. + * Return PK_ class error. + */ +int decrypt(__G__ passwrd) + __GDEF + ZCONST char *passwrd; +{ + ush b; + int n, r; + uch h[RAND_HEAD_LEN]; + + Trace((stdout, "\n[incnt = %d]: ", GLOBAL(incnt))); + + /* get header once (turn off "encrypted" flag temporarily so we don't + * try to decrypt the same data twice) */ + GLOBAL(pInfo->encrypted) = FALSE; + defer_leftover_input(__G); + for (n = 0; n < RAND_HEAD_LEN; n++) { + b = NEXTBYTE; + h[n] = (uch)b; + Trace((stdout, " (%02x)", h[n])); + } + undefer_input(__G); + GLOBAL(pInfo->encrypted) = TRUE; + + if (GLOBAL(newzip)) { /* this is first encrypted member in this zipfile */ + GLOBAL(newzip) = FALSE; + if (passwrd != (char *)NULL) { /* user gave password on command line */ + if (!GLOBAL(key)) { + if ((GLOBAL(key) = (char *)malloc(strlen(passwrd)+1)) == + (char *)NULL) + return PK_MEM2; + strcpy(GLOBAL(key), passwrd); + GLOBAL(nopwd) = TRUE; /* inhibit password prompting! */ + } + } else if (GLOBAL(key)) { /* get rid of previous zipfile's key */ + free(GLOBAL(key)); + GLOBAL(key) = (char *)NULL; + } + } + + /* if have key already, test it; else allocate memory for it */ + if (GLOBAL(key)) { + if (!testp(__G__ h)) + return PK_COOL; /* existing password OK (else prompt for new) */ + else if (GLOBAL(nopwd)) + return PK_WARN; /* user indicated no more prompting */ + } else if ((GLOBAL(key) = (char *)malloc(IZ_PWLEN+1)) == (char *)NULL) + return PK_MEM2; + + /* try a few keys */ + n = 0; + do { + r = (*G.decr_passwd)((zvoid *)&G, &n, GLOBAL(key), IZ_PWLEN+1, + GLOBAL(zipfn), GLOBAL(filename)); + if (r == IZ_PW_ERROR) { /* internal error in fetch of PW */ + free (GLOBAL(key)); + GLOBAL(key) = NULL; + return PK_MEM2; + } + if (r != IZ_PW_ENTERED) { /* user replied "skip" or "skip all" */ + *GLOBAL(key) = '\0'; /* We try the NIL password, ... */ + n = 0; /* and cancel fetch for this item. */ + } + if (!testp(__G__ h)) + return PK_COOL; + if (r == IZ_PW_CANCELALL) /* User replied "Skip all" */ + GLOBAL(nopwd) = TRUE; /* inhibit any further PW prompt! */ + } while (n > 0); + + return PK_WARN; + +} /* end function decrypt() */ + + + +/*********************************************************************** + * Test the password. Return -1 if bad, 0 if OK. + */ +local int testp(__G__ h) + __GDEF + ZCONST uch *h; +{ + int r; + char *key_translated; + + /* On systems with "obscure" native character coding (e.g., EBCDIC), + * the first test translates the password to the "main standard" + * character coding. */ + +#ifdef STR_TO_CP1 + /* allocate buffer for translated password */ + if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL) + return -1; + /* first try, test password translated "standard" charset */ + r = testkey(__G__ h, STR_TO_CP1(key_translated, GLOBAL(key))); +#else /* !STR_TO_CP1 */ + /* first try, test password as supplied on the extractor's host */ + r = testkey(__G__ h, GLOBAL(key)); +#endif /* ?STR_TO_CP1 */ + +#ifdef STR_TO_CP2 + if (r != 0) { +#ifndef STR_TO_CP1 + /* now prepare for second (and maybe third) test with translated pwd */ + if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL) + return -1; +#endif + /* second try, password translated to alternate ("standard") charset */ + r = testkey(__G__ h, STR_TO_CP2(key_translated, GLOBAL(key))); +#ifdef STR_TO_CP3 + if (r != 0) + /* third try, password translated to another "standard" charset */ + r = testkey(__G__ h, STR_TO_CP3(key_translated, GLOBAL(key))); +#endif +#ifndef STR_TO_CP1 + free(key_translated); +#endif + } +#endif /* STR_TO_CP2 */ + +#ifdef STR_TO_CP1 + free(key_translated); + if (r != 0) { + /* last resort, test password as supplied on the extractor's host */ + r = testkey(__G__ h, GLOBAL(key)); + } +#endif /* STR_TO_CP1 */ + + return r; + +} /* end function testp() */ + + +local int testkey(__G__ h, key) + __GDEF + ZCONST uch *h; /* decrypted header */ + ZCONST char *key; /* decryption password to test */ +{ + ush b; +#ifdef ZIP10 + ush c; +#endif + int n; + uch *p; + uch hh[RAND_HEAD_LEN]; /* decrypted header */ + + /* set keys and save the encrypted header */ + init_keys(__G__ key); + memcpy(hh, h, RAND_HEAD_LEN); + + /* check password */ + for (n = 0; n < RAND_HEAD_LEN; n++) { + zdecode(hh[n]); + Trace((stdout, " %02x", hh[n])); + } + + /* use fzofft to format zoff_t as strings - 10/19/04 from SMS */ + Trace((stdout, + "\n lrec.crc= %08lx crec.crc= %08lx pInfo->ExtLocHdr= %s\n", + GLOBAL(lrec.crc32), GLOBAL(pInfo->crc), + GLOBAL(pInfo->ExtLocHdr) ? "true":"false")); + Trace((stdout, " incnt = %d unzip offset into zipfile = %s\n", + GLOBAL(incnt), + fzofft(GLOBAL(cur_zipfile_bufstart)+(GLOBAL(inptr)-GLOBAL(inbuf)), + NULL, NULL))); + + /* same test as in zipbare(): */ + +#ifdef ZIP10 /* check two bytes */ + c = hh[RAND_HEAD_LEN-2], b = hh[RAND_HEAD_LEN-1]; + Trace((stdout, + " (c | (b<<8)) = %04x (crc >> 16) = %04x lrec.time = %04x\n", + (ush)(c | (b<<8)), (ush)(GLOBAL(lrec.crc32) >> 16), + ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff)))); + if ((ush)(c | (b<<8)) != (GLOBAL(pInfo->ExtLocHdr) ? + ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff) : + (ush)(GLOBAL(lrec.crc32) >> 16))) + return -1; /* bad */ +#else + b = hh[RAND_HEAD_LEN-1]; + Trace((stdout, " b = %02x (crc >> 24) = %02x (lrec.time >> 8) = %02x\n", + b, (ush)(GLOBAL(lrec.crc32) >> 24), + ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff)); + if (b != (GLOBAL(pInfo->ExtLocHdr) ? + ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff : + (ush)(GLOBAL(lrec.crc32) >> 24))) + return -1; /* bad */ +#endif + /* password OK: decrypt current buffer contents before leaving */ + for (n = (zoff_t)GLOBAL(incnt) > GLOBAL(csize) ? + (int)GLOBAL(csize) : GLOBAL(incnt), + p = GLOBAL(inptr); n--; p++) + zdecode(*p); + return 0; /* OK */ + +} /* end function testkey() */ + +#endif /* UNZIP && !FUNZIP */ + +#else /* !CRYPT */ + +/* something "externally visible" to shut up compiler/linker warnings */ +int zcr_dummy; + +#endif /* ?CRYPT */ diff --git a/crypt.h b/crypt.h new file mode 100644 index 0000000..61f3234 --- /dev/null +++ b/crypt.h @@ -0,0 +1,169 @@ +/* + Copyright (c) 1990-2007 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 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 +*/ +/* + crypt.h (full version) by Info-ZIP. Last revised: [see CR_VERSION_DATE] + + The main encryption/decryption source code for Info-Zip software was + originally written in Europe. To the best of our knowledge, it can + be freely distributed in both source and object forms from any country, + including the USA under License Exception TSU of the U.S. Export + Administration Regulations (section 740.13(e)) of 6 June 2002. + + NOTE on copyright history: + Previous versions of this source package (up to version 2.8) were + not copyrighted and put in the public domain. If you cannot comply + with the Info-Zip LICENSE, you may want to look for one of those + public domain versions. + */ + +#ifndef __crypt_h /* don't include more than once */ +#define __crypt_h + +#ifdef CRYPT +# undef CRYPT +#endif +/* + Logic of selecting "full crypt" code: + a) default behaviour: + - dummy crypt code when compiling UnZipSFX stub, to minimize size + - full crypt code when used to compile Zip, UnZip and fUnZip + b) USE_CRYPT defined: + - always full crypt code + c) NO_CRYPT defined: + - never full crypt code + NO_CRYPT takes precedence over USE_CRYPT + */ +#if defined(NO_CRYPT) +# define CRYPT 0 /* dummy version */ +#else +#if defined(USE_CRYPT) +# define CRYPT 1 /* full version */ +#else +#if !defined(SFX) +# define CRYPT 1 /* full version for zip and main unzip */ +#else +# define CRYPT 0 /* dummy version for unzip sfx */ +#endif +#endif /* ?USE_CRYPT */ +#endif /* ?NO_CRYPT */ + +#if CRYPT +/* full version */ + +#ifdef CR_BETA +# undef CR_BETA /* this is not a beta release */ +#endif + +#define CR_MAJORVER 2 +#define CR_MINORVER 91 +#ifdef CR_BETA +# define CR_BETA_VER "c BETA" +# define CR_VERSION_DATE "05 Jan 2007" /* last real code change */ +#else +# define CR_BETA_VER "" +# define CR_VERSION_DATE "05 Jan 2007" /* last public release date */ +# define CR_RELEASE +#endif + +#ifndef __G /* UnZip only, for now (DLL stuff) */ +# define __G +# define __G__ +# define __GDEF +# define __GPRO void +# define __GPRO__ +#endif + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) +# ifndef DOS_OS2_W32 +# define DOS_OS2_W32 +# endif +#endif + +#if defined(DOS_OS2_W32) || defined(__human68k__) +# ifndef DOS_H68_OS2_W32 +# define DOS_H68_OS2_W32 +# endif +#endif + +#if defined(VM_CMS) || defined(MVS) +# ifndef CMS_MVS +# define CMS_MVS +# endif +#endif + +/* To allow combining of Zip and UnZip static libraries in a single binary, + * the Zip and UnZip versions of the crypt core functions have to be named + * differently. + */ +#ifdef ZIP +# ifdef REALLY_SHORT_SYMS +# define decrypt_byte zdcrby +# else +# define decrypt_byte zp_decrypt_byte +# endif +# define update_keys zp_update_keys +# define init_keys zp_init_keys +#else /* !ZIP */ +# ifdef REALLY_SHORT_SYMS +# define decrypt_byte dcrbyt +# endif +#endif /* ?ZIP */ + +#define IZ_PWLEN 80 /* input buffer size for reading encryption key */ +#ifndef PWLEN /* for compatibility with previous zcrypt release... */ +# define PWLEN IZ_PWLEN +#endif +#define RAND_HEAD_LEN 12 /* length of encryption random header */ + +/* the crc_32_tab array has to be provided externally for the crypt calculus */ + +/* encode byte c, using temp t. Warning: c must not have side effects. */ +#define zencode(c,t) (t=decrypt_byte(__G), update_keys(c), t^(c)) + +/* decode byte c in place */ +#define zdecode(c) update_keys(__G__ c ^= decrypt_byte(__G)) + +int decrypt_byte OF((__GPRO)); +int update_keys OF((__GPRO__ int c)); +void init_keys OF((__GPRO__ ZCONST char *passwd)); + +#ifdef ZIP + void crypthead OF((ZCONST char *, ulg)); +# ifdef UTIL + int zipcloak OF((struct zlist far *, ZCONST char *)); + int zipbare OF((struct zlist far *, ZCONST char *)); +# else + unsigned zfwrite OF((zvoid *, extent, extent)); + extern char *key; +# endif +#endif /* ZIP */ + +#if (defined(UNZIP) && !defined(FUNZIP)) + int decrypt OF((__GPRO__ ZCONST char *passwrd)); +#endif + +#ifdef FUNZIP + extern int encrypted; +# ifdef NEXTBYTE +# undef NEXTBYTE +# endif +# define NEXTBYTE \ + (encrypted? update_keys(__G__ getc(G.in)^decrypt_byte(__G)) : getc(G.in)) +#endif /* FUNZIP */ + +#else /* !CRYPT */ +/* dummy version */ + +#define zencode +#define zdecode + +#define zfwrite(b,s,c) bfwrite(b,s,c,BFWRITE_DATA) + +#endif /* ?CRYPT */ +#endif /* !__crypt_h */ diff --git a/deflate.c b/deflate.c new file mode 100644 index 0000000..c830854 --- /dev/null +++ b/deflate.c @@ -0,0 +1,929 @@ +/* + deflate.c - Zip 3 + + Copyright (c) 1990-2007 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2005-Feb-10 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + * deflate.c by Jean-loup Gailly. + * + * PURPOSE + * + * Identify new text as repetitions of old text within a fixed- + * length sliding window trailing behind the new text. + * + * DISCUSSION + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many info-zippers for bug reports and testing. + * + * REFERENCES + * + * APPNOTE.TXT documentation file in PKZIP 1.93a distribution. + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + * INTERFACE + * + * void lm_init (int pack_level, ush *flags) + * Initialize the "longest match" routines for a new file + * + * ulg deflate (void) + * Processes a new input file and return its compressed length. Sets + * the compressed length, crc, deflate flags and internal file + * attributes. + */ + +#define __DEFLATE_C + +#include "zip.h" + +#ifndef USE_ZLIB + +/* =========================================================================== + * Configuration parameters + */ + +/* Compile with MEDIUM_MEM to reduce the memory requirements or + * with SMALL_MEM to use as little memory as possible. Use BIG_MEM if the + * entire input file can be held in memory (not possible on 16 bit systems). + * Warning: defining these symbols affects HASH_BITS (see below) and thus + * affects the compression ratio. The compressed output + * is still correct, and might even be smaller in some cases. + */ + +#ifdef SMALL_MEM +# define HASH_BITS 13 /* Number of bits used to hash strings */ +#endif +#ifdef MEDIUM_MEM +# define HASH_BITS 14 +#endif +#ifndef HASH_BITS +# define HASH_BITS 15 + /* For portability to 16 bit machines, do not use values above 15. */ +#endif + +#define HASH_SIZE (unsigned)(1<= HASH_BITS + */ + +unsigned int near prev_length; +/* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + unsigned near strstart; /* start of string to insert */ + unsigned near match_start; /* start of matching string */ +local int eofile; /* flag set at end of input file */ +local unsigned lookahead; /* number of valid bytes ahead in window */ + +unsigned near max_chain_length; +/* To speed up deflation, hash chains are never searched beyond this length. + * A higher limit improves compression ratio but degrades the speed. + */ + +local unsigned int max_lazy_match; +/* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +#define max_insert_length max_lazy_match +/* Insert new strings in the hash table only if the match length + * is not greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + +unsigned near good_match; +/* Use a faster search when the previous match is longer than this */ + +#ifdef FULL_SEARCH +# define nice_match MAX_MATCH +#else + int near nice_match; /* Stop searching when current match exceeds this */ +#endif + + +/* Values for max_lazy_match, good_match, nice_match and max_chain_length, + * depending on the desired pack level (0..9). The values given below have + * been tuned to exclude worst case performance for pathological files. + * Better values may be found for specific files. + */ + +typedef struct config { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; +} config; + +local config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0}, /* store only */ +/* 1 */ {4, 4, 8, 4}, /* maximum speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8}, +/* 3 */ {4, 6, 32, 32}, + +/* 4 */ {4, 4, 16, 16}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32}, +/* 6 */ {8, 16, 128, 128}, +/* 7 */ {8, 32, 128, 256}, +/* 8 */ {32, 128, 258, 1024}, +/* 9 */ {32, 258, 258, 4096}}; /* maximum compression */ + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +/* =========================================================================== + * Prototypes for local functions. + */ + +local void fill_window OF((void)); + +local uzoff_t deflate_fast OF((void)); /* now use uzoff_t 7/24/04 EG */ + + int longest_match OF((IPos cur_match)); +#if defined(ASMV) && !defined(RISCOS) + void match_init OF((void)); /* asm code initialization */ +#endif + +#ifdef DEBUG +local void check_match OF((IPos start, IPos match, int length)); +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(h,c) (h = (((h)< 0 if the input file is already read or + * mmap'ed in the window[] array, 0 otherwise. In the first case, + * window_size is sufficient to contain the whole input file plus + * MIN_LOOKAHEAD bytes (to avoid referencing memory beyond the end + * of window[] when looking for matches towards the end). + */ +void lm_init (pack_level, flags) + int pack_level; /* 0: store, 1: best speed, 9: best compression */ + ush *flags; /* general purpose bit flag */ +{ + register unsigned j; + + if (pack_level < 1 || pack_level > 9) error("bad pack level"); + + /* Do not slide the window if the whole input is already in memory + * (window_size > 0) + */ + sliding = 0; + if (window_size == 0L) { + sliding = 1; + window_size = (ulg)2L*WSIZE; + } + + /* Use dynamic allocation if compiler does not like big static arrays: */ +#ifdef DYN_ALLOC + if (window == NULL) { + window = (uch far *) zcalloc(WSIZE, 2*sizeof(uch)); + if (window == NULL) ziperr(ZE_MEM, "window allocation"); + } + if (prev == NULL) { + prev = (Pos far *) zcalloc(WSIZE, sizeof(Pos)); + head = (Pos far *) zcalloc(HASH_SIZE, sizeof(Pos)); + if (prev == NULL || head == NULL) { + ziperr(ZE_MEM, "hash table allocation"); + } + } +#endif /* DYN_ALLOC */ + + /* Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ + head[HASH_SIZE-1] = NIL; + memset((char*)head, NIL, (unsigned)(HASH_SIZE-1)*sizeof(*head)); + + /* Set the default configuration parameters: + */ + max_lazy_match = configuration_table[pack_level].max_lazy; + good_match = configuration_table[pack_level].good_length; +#ifndef FULL_SEARCH + nice_match = configuration_table[pack_level].nice_length; +#endif + max_chain_length = configuration_table[pack_level].max_chain; + if (pack_level <= 2) { + *flags |= FAST; + } else if (pack_level >= 8) { + *flags |= SLOW; + } + /* ??? reduce max_chain_length for binary files */ + + strstart = 0; + block_start = 0L; +#if defined(ASMV) && !defined(RISCOS) + match_init(); /* initialize the asm code */ +#endif + + j = WSIZE; +#ifndef MAXSEG_64K + if (sizeof(int) > 2) j <<= 1; /* Can read 64K in one step */ +#endif + lookahead = (*read_buf)((char*)window, j); + + if (lookahead == 0 || lookahead == (unsigned)EOF) { + eofile = 1, lookahead = 0; + return; + } + eofile = 0; + /* Make sure that we always have enough lookahead. This is important + * if input comes from a device such as a tty. + */ + if (lookahead < MIN_LOOKAHEAD) fill_window(); + + ins_h = 0; + for (j=0; j= 1 + */ +#ifndef ASMV +/* For 80x86 and 680x0 and ARM, an optimized version is in match.asm or + * match.S. The code is functionally equivalent, so you can use the C version + * if desired. + */ +int longest_match(cur_match) + IPos cur_match; /* current match */ +{ + unsigned chain_length = max_chain_length; /* max hash chain length */ + register uch far *scan = window + strstart; /* current string */ + register uch far *match; /* matched string */ + register int len; /* length of current match */ + int best_len = prev_length; /* best match length so far */ + IPos limit = strstart > (IPos)MAX_DIST ? strstart - (IPos)MAX_DIST : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + +/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ +#if HASH_BITS < 8 || MAX_MATCH != 258 + error: Code too clever +#endif + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register uch far *strend = window + strstart + MAX_MATCH - 1; + register ush scan_start = *(ush far *)scan; + register ush scan_end = *(ush far *)(scan+best_len-1); +#else + register uch far *strend = window + strstart + MAX_MATCH; + register uch scan_end1 = scan[best_len-1]; + register uch scan_end = scan[best_len]; +#endif + + /* Do not waste too much time if we already have a good match: */ + if (prev_length >= good_match) { + chain_length >>= 2; + } + + Assert(strstart <= window_size-MIN_LOOKAHEAD, "insufficient lookahead"); + + do { + Assert(cur_match < strstart, "no future"); + match = window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2: + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ush far *)(match+best_len-1) != scan_end || + *(ush far *)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + scan++, match++; + do { + } while (*(ush far *)(scan+=2) == *(ush far *)(match+=2) && + *(ush far *)(scan+=2) == *(ush far *)(match+=2) && + *(ush far *)(scan+=2) == *(ush far *)(match+=2) && + *(ush far *)(scan+=2) == *(ush far *)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= window+(unsigned)(window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= window+(unsigned)(window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ush far *)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & WMASK]) > limit + && --chain_length != 0); + + return best_len; +} +#endif /* ASMV */ + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(start, match, length) + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (memcmp((char*)window + match, + (char*)window + start, length) != EQUAL) { + fprintf(mesg, + " start %d, match %d, length %d\n", + start, match, length); + error("invalid match"); + } + if (verbose > 1) { + fprintf(mesg,"\\[%d,%d]", start-match, length); +#ifndef WINDLL + do { putc(window[start++], mesg); } while (--length != 0); +#else + do { fprintf(stdout,"%c",window[start++]); } while (--length != 0); +#endif + } +} +#else +# define check_match(start, match, length) +#endif + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK(eof) \ + flush_block(block_start >= 0L ? (char*)&window[(unsigned)block_start] : \ + (char*)NULL, (ulg)strstart - (ulg)block_start, (eof)) + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead, and sets eofile if end of input file. + * + * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0 + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or eofile is set; file reads are + * performed for at least two bytes (required for the translate_eol option). + */ +local void fill_window() +{ + register unsigned n, m; + unsigned more; /* Amount of free space at the end of the window. */ + + do { + more = (unsigned)(window_size - (ulg)lookahead - (ulg)strstart); + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (more == (unsigned)EOF) { + /* Very unlikely, but possible on 16 bit machine if strstart == 0 + * and lookahead == 1 (input done one byte at time) + */ + more--; + + /* For MMAP or BIG_MEM, the whole input file is already in memory so + * we must not perform sliding. We must however call (*read_buf)() in + * order to compute the crc, update lookahead and possibly set eofile. + */ + } else if (strstart >= WSIZE+MAX_DIST && sliding) { + +#ifdef FORCE_METHOD + /* When methods "stored" or "store_block" are requested, the + * current block must be flushed before sliding the window. + */ + if (level <= 2) FLUSH_BLOCK(0), block_start = strstart; +#endif + /* By the IN assertion, the window is not empty so we can't confuse + * more == 0 with more == 64K on a 16 bit machine. + */ + memcpy((char*)window, (char*)window+WSIZE, (unsigned)WSIZE); + match_start -= WSIZE; + strstart -= WSIZE; /* we now have strstart >= MAX_DIST: */ + + block_start -= (long) WSIZE; + + for (n = 0; n < HASH_SIZE; n++) { + m = head[n]; + head[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL); + } + for (n = 0; n < WSIZE; n++) { + m = prev[n]; + prev[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } + more += WSIZE; + if (dot_size > 0 && !display_globaldots) { + /* initial space */ + if (noisy && dot_count == -1) { +#ifndef WINDLL + putc(' ', mesg); + fflush(mesg); +#else + fprintf(stdout,"%c",' '); +#endif + dot_count++; + } + dot_count++; + if (dot_size <= (dot_count + 1) * WSIZE) dot_count = 0; + } + if ((verbose || noisy) && dot_size && !dot_count) { +#ifndef WINDLL + putc('.', mesg); + fflush(mesg); +#else + fprintf(stdout,"%c",'.'); +#endif + mesg_line_started = 1; + } + } + if (eofile) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the MMAP or BIG_MEM case (not yet supported in gzip), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = (*read_buf)((char*)window+strstart+lookahead, more); + if (n == 0 || n == (unsigned)EOF) { + eofile = 1; + } else { + lookahead += n; + } + } while (lookahead < MIN_LOOKAHEAD && !eofile); +} + +/* =========================================================================== + * Processes a new input file and return its compressed length. This + * function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local uzoff_t deflate_fast() +{ + IPos hash_head = NIL; /* head of the hash chain */ + int flush; /* set if current block must be flushed */ + unsigned match_length = 0; /* length of best match */ + + prev_length = MIN_MATCH-1; + while (lookahead != 0) { + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ +#ifndef DEFL_UNDETERM + if (lookahead >= MIN_MATCH) +#endif + INSERT_STRING(strstart, hash_head); + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && strstart - hash_head <= MAX_DIST) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ +#ifndef HUFFMAN_ONLY +# ifndef DEFL_UNDETERM + /* Do not look for matches beyond the end of the input. + * This is necessary to make deflate deterministic. + */ + if ((unsigned)nice_match > lookahead) nice_match = (int)lookahead; +# endif + match_length = longest_match (hash_head); + /* longest_match() sets match_start */ + if (match_length > lookahead) match_length = lookahead; +#endif + } + if (match_length >= MIN_MATCH) { + check_match(strstart, match_start, match_length); + + flush = ct_tally(strstart-match_start, match_length - MIN_MATCH); + + lookahead -= match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (match_length <= max_insert_length +#ifndef DEFL_UNDETERM + && lookahead >= MIN_MATCH +#endif + ) { + match_length--; /* string at strstart already in hash table */ + do { + strstart++; + INSERT_STRING(strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ +#ifdef DEFL_UNDETERM + /* If lookahead < MIN_MATCH these bytes are garbage, + * but it does not matter since the next lookahead bytes + * will be emitted as literals. + */ +#endif + } while (--match_length != 0); + strstart++; + } else { + strstart += match_length; + match_length = 0; + ins_h = window[strstart]; + UPDATE_HASH(ins_h, window[strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c",window[strstart])); + flush = ct_tally (0, window[strstart]); + lookahead--; + strstart++; + } + if (flush) FLUSH_BLOCK(0), block_start = strstart; + + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (lookahead < MIN_LOOKAHEAD) fill_window(); + } + return FLUSH_BLOCK(1); /* eof */ +} + +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +uzoff_t deflate() +{ + IPos hash_head = NIL; /* head of hash chain */ + IPos prev_match; /* previous match */ + int flush; /* set if current block must be flushed */ + int match_available = 0; /* set if previous match exists */ + register unsigned match_length = MIN_MATCH-1; /* length of best match */ +#ifdef DEBUG + extern uzoff_t isize; /* byte length of input file, for debug only */ +#endif + + if (level <= 3) return deflate_fast(); /* optimized for speed */ + + /* Process the input block. */ + while (lookahead != 0) { + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ +#ifndef DEFL_UNDETERM + if (lookahead >= MIN_MATCH) +#endif + INSERT_STRING(strstart, hash_head); + + /* Find the longest match, discarding those <= prev_length. + */ + prev_length = match_length, prev_match = match_start; + match_length = MIN_MATCH-1; + + if (hash_head != NIL && prev_length < max_lazy_match && + strstart - hash_head <= MAX_DIST) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ +#ifndef HUFFMAN_ONLY +# ifndef DEFL_UNDETERM + /* Do not look for matches beyond the end of the input. + * This is necessary to make deflate deterministic. + */ + if ((unsigned)nice_match > lookahead) nice_match = (int)lookahead; +# endif + match_length = longest_match (hash_head); + /* longest_match() sets match_start */ + if (match_length > lookahead) match_length = lookahead; +#endif + +#ifdef FILTERED + /* Ignore matches of length <= 5 */ + if (match_length <= 5) { +#else + /* Ignore a length 3 match if it is too distant: */ + if (match_length == MIN_MATCH && strstart-match_start > TOO_FAR){ +#endif + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (prev_length >= MIN_MATCH && match_length <= prev_length) { +#ifndef DEFL_UNDETERM + unsigned max_insert = strstart + lookahead - MIN_MATCH; + +#endif + check_match(strstart-1, prev_match, prev_length); + + flush = ct_tally(strstart-1-prev_match, prev_length - MIN_MATCH); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. + */ + lookahead -= prev_length-1; + prev_length -= 2; +#ifndef DEFL_UNDETERM + do { + if (++strstart <= max_insert) { + INSERT_STRING(strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } + } while (--prev_length != 0); + strstart++; +#else /* DEFL_UNDETERM */ + do { + strstart++; + INSERT_STRING(strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH + * these bytes are garbage, but it does not matter since the + * next lookahead bytes will always be emitted as literals. + */ + } while (--prev_length != 0); + strstart++; +#endif /* ?DEFL_UNDETERM */ + match_available = 0; + match_length = MIN_MATCH-1; + + if (flush) FLUSH_BLOCK(0), block_start = strstart; + + } else if (match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c",window[strstart-1])); + if (ct_tally (0, window[strstart-1])) { + FLUSH_BLOCK(0), block_start = strstart; + } + strstart++; + lookahead--; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + match_available = 1; + strstart++; + lookahead--; + } + Assert(strstart <= isize && lookahead <= isize, "a bit too far"); + + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (lookahead < MIN_LOOKAHEAD) fill_window(); + } + if (match_available) ct_tally (0, window[strstart-1]); + + return FLUSH_BLOCK(1); /* eof */ +} +#endif /* !USE_ZLIB */ diff --git a/ebcdic.h b/ebcdic.h new file mode 100644 index 0000000..a52de1e --- /dev/null +++ b/ebcdic.h @@ -0,0 +1,328 @@ +/* + ebcdic.h + + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2005-Feb-10 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/licen +*/ +/*--------------------------------------------------------------------------- + + ebcdic.h + + The CECP 1047 (Extended de-facto EBCDIC) <-> ISO 8859-1 conversion tables, + from ftp://aix1.segi.ulg.ac.be/pub/docs/iso8859/iso8859.networking + + NOTES: + (OS/390 port 12/97) + These table no longer represent the standard mappings (for example in the + OS/390 iconv utility). In order to follow current standards I remapped + ebcdic x0a to ascii x15 and + ebcdic x85 to ascii x25 (and vice-versa) + Without these changes, newlines in auto-convert text files appeared + as literal \045. + I'm not sure what effect this remap would have on the MVS and CMS ports, so + I ifdef'd these changes. Hopefully these ifdef's can be removed when the + MVS/CMS folks test the new mappings. + + Christian Spieler , 27-Apr-1998 + The problem mentioned by Paul von Behren was already observed previously + on VM/CMS, during the preparation of the CMS&MVS port of UnZip 5.20 in + 1996. At that point, the ebcdic tables were not changed since they seemed + to be an adopted standard (to my knowledge, these tables are still used + as presented in mainfraime KERMIT). Instead, the "end-of-line" conversion + feature of Zip's and UnZip's "text-translation" mode was used to force + correct mappings between ASCII and EBCDIC newline markers. + Before interchanging the ASCII mappings of the EBCDIC control characters + "NL" 0x25 and "LF" 0x15 according to the OS/390 setting, we have to + make sure that EBCDIC 0x15 is never used as line termination. + + ---------------------------------------------------------------------------*/ + +#ifndef __ebcdic_h /* prevent multiple inclusions */ +#define __ebcdic_h + + +#ifndef ZCONST +# define ZCONST const +#endif + +#ifdef EBCDIC +#ifndef MTS /* MTS uses a slightly "special" EBCDIC code page */ + +ZCONST uch ebcdic[] = { + 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, /* 00 - 07 */ +#ifdef OS390 + 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 08 - 0F */ +#else + 0x16, 0x05, 0x25, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 08 - 0F */ +#endif + 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, /* 10 - 17 */ + 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F, /* 18 - 1F */ + 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, /* 20 - 27 */ + 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, /* 28 - 2F */ + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, /* 30 - 37 */ + 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, /* 38 - 3F */ + 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, /* 40 - 47 */ + 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, /* 48 - 4F */ + 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, /* 50 - 57 */ + 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D, /* 58 - 5F */ + 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 60 - 67 */ + 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* 68 - 6F */ + 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, /* 70 - 77 */ + 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07, /* 78 - 7F */ +#ifdef OS390 + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x06, 0x17, /* 80 - 87 */ +#else + 0x20, 0x21, 0x22, 0x23, 0x24, 0x15, 0x06, 0x17, /* 80 - 87 */ +#endif + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x09, 0x0A, 0x1B, /* 88 - 8F */ + 0x30, 0x31, 0x1A, 0x33, 0x34, 0x35, 0x36, 0x08, /* 90 - 97 */ + 0x38, 0x39, 0x3A, 0x3B, 0x04, 0x14, 0x3E, 0xFF, /* 98 - 9F */ + 0x41, 0xAA, 0x4A, 0xB1, 0x9F, 0xB2, 0x6A, 0xB5, /* A0 - A7 */ + 0xBB, 0xB4, 0x9A, 0x8A, 0xB0, 0xCA, 0xAF, 0xBC, /* A8 - AF */ + 0x90, 0x8F, 0xEA, 0xFA, 0xBE, 0xA0, 0xB6, 0xB3, /* B0 - B7 */ + 0x9D, 0xDA, 0x9B, 0x8B, 0xB7, 0xB8, 0xB9, 0xAB, /* B8 - BF */ + 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9E, 0x68, /* C0 - C7 */ + 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* C8 - CF */ + 0xAC, 0x69, 0xED, 0xEE, 0xEB, 0xEF, 0xEC, 0xBF, /* D0 - D7 */ + 0x80, 0xFD, 0xFE, 0xFB, 0xFC, 0xBA, 0xAE, 0x59, /* D8 - DF */ + 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9C, 0x48, /* E0 - E7 */ + 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* E8 - EF */ + 0x8C, 0x49, 0xCD, 0xCE, 0xCB, 0xCF, 0xCC, 0xE1, /* F0 - F7 */ + 0x70, 0xDD, 0xDE, 0xDB, 0xDC, 0x8D, 0x8E, 0xDF /* F8 - FF */ +}; + +#if (defined(ZIP) || CRYPT) +ZCONST uch ascii[] = { + 0x00, 0x01, 0x02, 0x03, 0x9C, 0x09, 0x86, 0x7F, /* 00 - 07 */ + 0x97, 0x8D, 0x8E, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 08 - 0F */ +#ifdef OS390 + 0x10, 0x11, 0x12, 0x13, 0x9D, 0x0A, 0x08, 0x87, /* 10 - 17 */ +#else + 0x10, 0x11, 0x12, 0x13, 0x9D, 0x85, 0x08, 0x87, /* 10 - 17 */ +#endif + 0x18, 0x19, 0x92, 0x8F, 0x1C, 0x1D, 0x1E, 0x1F, /* 18 - 1F */ +#ifdef OS390 + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x17, 0x1B, /* 20 - 27 */ +#else + 0x80, 0x81, 0x82, 0x83, 0x84, 0x0A, 0x17, 0x1B, /* 20 - 27 */ +#endif + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x05, 0x06, 0x07, /* 28 - 2F */ + 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30 - 37 */ + 0x98, 0x99, 0x9A, 0x9B, 0x14, 0x15, 0x9E, 0x1A, /* 38 - 3F */ + 0x20, 0xA0, 0xE2, 0xE4, 0xE0, 0xE1, 0xE3, 0xE5, /* 40 - 47 */ + 0xE7, 0xF1, 0xA2, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, /* 48 - 4F */ + 0x26, 0xE9, 0xEA, 0xEB, 0xE8, 0xED, 0xEE, 0xEF, /* 50 - 57 */ + 0xEC, 0xDF, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E, /* 58 - 5F */ + 0x2D, 0x2F, 0xC2, 0xC4, 0xC0, 0xC1, 0xC3, 0xC5, /* 60 - 67 */ + 0xC7, 0xD1, 0xA6, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, /* 68 - 6F */ + 0xF8, 0xC9, 0xCA, 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, /* 70 - 77 */ + 0xCC, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, /* 78 - 7F */ + 0xD8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80 - 87 */ + 0x68, 0x69, 0xAB, 0xBB, 0xF0, 0xFD, 0xFE, 0xB1, /* 88 - 8F */ + 0xB0, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, /* 90 - 97 */ + 0x71, 0x72, 0xAA, 0xBA, 0xE6, 0xB8, 0xC6, 0xA4, /* 98 - 9F */ + 0xB5, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* A0 - A7 */ + 0x79, 0x7A, 0xA1, 0xBF, 0xD0, 0x5B, 0xDE, 0xAE, /* A8 - AF */ + 0xAC, 0xA3, 0xA5, 0xB7, 0xA9, 0xA7, 0xB6, 0xBC, /* B0 - B7 */ + 0xBD, 0xBE, 0xDD, 0xA8, 0xAF, 0x5D, 0xB4, 0xD7, /* B8 - BF */ + 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* C0 - C7 */ + 0x48, 0x49, 0xAD, 0xF4, 0xF6, 0xF2, 0xF3, 0xF5, /* C8 - CF */ + 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, /* D0 - D7 */ + 0x51, 0x52, 0xB9, 0xFB, 0xFC, 0xF9, 0xFA, 0xFF, /* D8 - DF */ + 0x5C, 0xF7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* E0 - E7 */ + 0x59, 0x5A, 0xB2, 0xD4, 0xD6, 0xD2, 0xD3, 0xD5, /* E8 - EF */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* F0 - F7 */ + 0x38, 0x39, 0xB3, 0xDB, 0xDC, 0xD9, 0xDA, 0x9F /* F8 - FF */ +}; +#endif /* ZIP || CRYPT */ + +#else /* MTS */ + +/* + * This is the MTS ASCII->EBCDIC translation table. It provides a 1-1 + * translation from ISO 8859/1 8-bit ASCII to IBM Code Page 37 EBCDIC. + */ + +ZCONST uch ebcdic[] = { + 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, /* 00 - 07 */ + 0x16, 0x05, 0x25, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 08 - 0F */ + 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, /* 10 - 17 */ + 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F, /* 18 - 1F */ + 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, /* 20 - 27 */ + 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, /* 28 - 2F */ + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, /* 30 - 37 */ + 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, /* 38 - 3F */ + 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, /* 40 - 47 */ + 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, /* 48 - 4F */ + 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, /* 50 - 57 */ + 0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D, /* 58 - 5F */ + 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 60 - 67 */ + 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* 68 - 6F */ + 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, /* 70 - 77 */ + 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07, /* 78 - 7F */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x15, 0x06, 0x17, /* 80 - 87 */ + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x09, 0x0A, 0x1B, /* 88 - 8F */ + 0x30, 0x31, 0x1A, 0x33, 0x34, 0x35, 0x36, 0x08, /* 90 - 97 */ + 0x38, 0x39, 0x3A, 0x3B, 0x04, 0x14, 0x3E, 0xFF, /* 98 - 9F */ + 0x41, 0xAA, 0x4A, 0xB1, 0x9F, 0xB2, 0x6A, 0xB5, /* A0 - A7 */ + 0xBD, 0xB4, 0x9A, 0x8A, 0x5F, 0xCA, 0xAF, 0xBC, /* A8 - AF */ + 0x90, 0x8F, 0xEA, 0xFA, 0xBE, 0xA0, 0xB6, 0xB3, /* B0 - B7 */ + 0x9D, 0xDA, 0x9B, 0x8B, 0xB7, 0xB8, 0xB9, 0xAB, /* B8 - BF */ + 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9E, 0x68, /* C0 - C7 */ + 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* C8 - CF */ + 0xAC, 0x69, 0xED, 0xEE, 0xEB, 0xEF, 0xEC, 0xBF, /* D0 - D7 */ + 0x80, 0xFD, 0xFE, 0xFB, 0xFC, 0xAD, 0xAE, 0x59, /* D8 - DF */ + 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9C, 0x48, /* E0 - E7 */ + 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* E8 - EF */ + 0x8C, 0x49, 0xCD, 0xCE, 0xCB, 0xCF, 0xCC, 0xE1, /* F0 - F7 */ + 0x70, 0xDD, 0xDE, 0xDB, 0xDC, 0x8D, 0x8E, 0xDF /* F8 - FF */ +}; + +#if (defined(ZIP) || CRYPT) +ZCONST uch ascii[] = { + 0x00, 0x01, 0x02, 0x03, 0x9C, 0x09, 0x86, 0x7F, /* 00 - 07 */ + 0x97, 0x8D, 0x8E, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 08 - 0F */ + 0x10, 0x11, 0x12, 0x13, 0x9D, 0x85, 0x08, 0x87, /* 10 - 17 */ + 0x18, 0x19, 0x92, 0x8F, 0x1C, 0x1D, 0x1E, 0x1F, /* 18 - 1F */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x0A, 0x17, 0x1B, /* 20 - 27 */ + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x05, 0x06, 0x07, /* 28 - 2F */ + 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30 - 37 */ + 0x98, 0x99, 0x9A, 0x9B, 0x14, 0x15, 0x9E, 0x1A, /* 38 - 3F */ + 0x20, 0xA0, 0xE2, 0xE4, 0xE0, 0xE1, 0xE3, 0xE5, /* 40 - 47 */ + 0xE7, 0xF1, 0xA2, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, /* 48 - 4F */ + 0x26, 0xE9, 0xEA, 0xEB, 0xE8, 0xED, 0xEE, 0xEF, /* 50 - 57 */ + 0xEC, 0xDF, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAC, /* 58 - 5F */ + 0x2D, 0x2F, 0xC2, 0xC4, 0xC0, 0xC1, 0xC3, 0xC5, /* 60 - 67 */ + 0xC7, 0xD1, 0xA6, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, /* 68 - 6F */ + 0xF8, 0xC9, 0xCA, 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, /* 70 - 77 */ + 0xCC, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, /* 78 - 7F */ + 0xD8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80 - 87 */ + 0x68, 0x69, 0xAB, 0xBB, 0xF0, 0xFD, 0xFE, 0xB1, /* 88 - 8F */ + 0xB0, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, /* 90 - 97 */ + 0x71, 0x72, 0xAA, 0xBA, 0xE6, 0xB8, 0xC6, 0xA4, /* 98 - 9F */ + 0xB5, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* A0 - A7 */ + 0x79, 0x7A, 0xA1, 0xBF, 0xD0, 0xDD, 0xDE, 0xAE, /* A8 - AF */ + 0x5E, 0xA3, 0xA5, 0xB7, 0xA9, 0xA7, 0xB6, 0xBC, /* B0 - B7 */ + 0xBD, 0xBE, 0x5B, 0x5D, 0xAF, 0xA8, 0xB4, 0xD7, /* B8 - BF */ + 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* C0 - C7 */ + 0x48, 0x49, 0xAD, 0xF4, 0xF6, 0xF2, 0xF3, 0xF5, /* C8 - CF */ + 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, /* D0 - D7 */ + 0x51, 0x52, 0xB9, 0xFB, 0xFC, 0xF9, 0xFA, 0xFF, /* D8 - DF */ + 0x5C, 0xF7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* E0 - E7 */ + 0x59, 0x5A, 0xB2, 0xD4, 0xD6, 0xD2, 0xD3, 0xD5, /* E8 - EF */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* F0 - F7 */ + 0x38, 0x39, 0xB3, 0xDB, 0xDC, 0xD9, 0xDA, 0x9F /* F8 - FF */ +}; +#endif /* ZIP || CRYPT */ + +#endif /* ?MTS */ +#endif /* EBCDIC */ + +/*--------------------------------------------------------------------------- + + The following conversion tables translate between IBM PC CP 850 + (OEM codepage) and the "Western Europe & America" Windows codepage 1252. + The Windows codepage 1252 contains the ISO 8859-1 "Latin 1" codepage, + with some additional printable characters in the range (0x80 - 0x9F), + that is reserved to control codes in the ISO 8859-1 character table. + + The ISO <--> OEM conversion tables were constructed with the help + of the WIN32 (Win16?) API's OemToAnsi() and AnsiToOem() conversion + functions and have been checked against the CP850 and LATIN1 tables + provided in the MS-Kermit 3.14 distribution. + + ---------------------------------------------------------------------------*/ + +#ifdef IZ_ISO2OEM_ARRAY +#ifdef OEM_RUSS +ZCONST uch Far iso2oem[] = { + 0x3F, 0x3F, 0x27, 0x9F, 0x22, 0x2E, 0xC5, 0xCE, /* 80 - 87 */ + 0xFD, 0x25, 0x53, 0x3C, 0x4F, 0x3F, 0x3F, 0x3F, /* 88 - 8F */ + 0x3F, 0x27, 0x27, 0x22, 0x22, 0xF9, 0x2D, 0x2D, /* 90 - 97 */ + 0x7E, 0x54, 0x73, 0x3E, 0x6F, 0x3F, 0x3F, 0x59, /* 98 - 9F */ + 0xFF, 0xF6, 0xF7, 0x9C, 0xCF, 0xBE, 0xFE, 0xF5, /* A0 - A7 */ + 0xF0, 0xB8, 0xF2, 0xAE, 0xAA, 0xF0, 0xA9, 0xEE, /* A8 - AF */ + 0xF8, 0xFB, 0xF4, 0xF5, 0xEF, 0xE6, 0xF4, 0xFA, /* B0 - B7 */ + 0xF1, 0xFC, 0xF3, 0xAF, 0xAC, 0xAB, 0xF3, 0xA8, /* B8 - BF */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x86, 0x86, 0x87, /* C0 - C7 */ + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, /* C8 - CF */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* D0 - D7 */ + 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, /* D8 - DF */ + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, /* E0 - E7 */ + 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, /* E8 - EF */ + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, /* F0 - F7 */ + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF /* F8 - FF */ +}; +#else /* OEM_RUS */ +ZCONST uch Far iso2oem[] = { + 0x3F, 0x3F, 0x27, 0x9F, 0x22, 0x2E, 0xC5, 0xCE, /* 80 - 87 */ + 0x5E, 0x25, 0x53, 0x3C, 0x4F, 0x3F, 0x3F, 0x3F, /* 88 - 8F */ + 0x3F, 0x27, 0x27, 0x22, 0x22, 0x07, 0x2D, 0x2D, /* 90 - 97 */ + 0x7E, 0x54, 0x73, 0x3E, 0x6F, 0x3F, 0x3F, 0x59, /* 98 - 9F */ + 0xFF, 0xAD, 0xBD, 0x9C, 0xCF, 0xBE, 0xDD, 0xF5, /* A0 - A7 */ + 0xF9, 0xB8, 0xA6, 0xAE, 0xAA, 0xF0, 0xA9, 0xEE, /* A8 - AF */ + 0xF8, 0xF1, 0xFD, 0xFC, 0xEF, 0xE6, 0xF4, 0xFA, /* B0 - B7 */ + 0xF7, 0xFB, 0xA7, 0xAF, 0xAC, 0xAB, 0xF3, 0xA8, /* B8 - BF */ + 0xB7, 0xB5, 0xB6, 0xC7, 0x8E, 0x8F, 0x92, 0x80, /* C0 - C7 */ + 0xD4, 0x90, 0xD2, 0xD3, 0xDE, 0xD6, 0xD7, 0xD8, /* C8 - CF */ + 0xD1, 0xA5, 0xE3, 0xE0, 0xE2, 0xE5, 0x99, 0x9E, /* D0 - D7 */ + 0x9D, 0xEB, 0xE9, 0xEA, 0x9A, 0xED, 0xE8, 0xE1, /* D8 - DF */ + 0x85, 0xA0, 0x83, 0xC6, 0x84, 0x86, 0x91, 0x87, /* E0 - E7 */ + 0x8A, 0x82, 0x88, 0x89, 0x8D, 0xA1, 0x8C, 0x8B, /* E8 - EF */ + 0xD0, 0xA4, 0x95, 0xA2, 0x93, 0xE4, 0x94, 0xF6, /* F0 - F7 */ + 0x9B, 0x97, 0xA3, 0x96, 0x81, 0xEC, 0xE7, 0x98 /* F8 - FF */ +}; +#endif /* OEM_RUS */ +#endif /* IZ_ISO2OEM_ARRAY */ + +#ifdef IZ_OEM2ISO_ARRAY +#ifdef OEM_RUSS +ZCONST uch Far oem2iso[] = { + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, /* 80 - 87 */ + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, /* 88 - 8F */ + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, /* 90 - 97 */ + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, /* 98 - 9F */ + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, /* A0 - A7 */ + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, /* A8 - AF */ + 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xC1, 0xC2, 0xC0, /* B0 - B7 */ + 0xA9, 0xA6, 0xA6, 0x2B, 0x2B, 0xA2, 0xA5, 0x2B, /* B8 - BF */ + 0x2B, 0x2D, 0x2D, 0x2B, 0x2D, 0x2B, 0xE3, 0xC3, /* C0 - C7 */ + 0x2B, 0x2B, 0x2D, 0x2D, 0xA6, 0x2D, 0x2B, 0xA4, /* C8 - CF */ + 0xF0, 0xD0, 0xCA, 0xCB, 0xC8, 0x69, 0xCD, 0xCE, /* D0 - D7 */ + 0xCF, 0x2B, 0x2B, 0xA6, 0x5F, 0xA6, 0xCC, 0xAF, /* D8 - DF */ + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, /* E0 - E7 */ + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, /* E8 - EF */ + 0xA8, 0xB8, 0xAA, 0xBA, 0xB2, 0xB3, 0xA1, 0xA2, /* F0 - F7 */ + 0xB0, 0x95, 0xB7, 0xB1, 0xB9, 0x88, 0xA6, 0xA0 /* F8 - FF */ +}; +#else /* OEM_RUS */ +ZCONST uch Far oem2iso[] = { + 0xC7, 0xFC, 0xE9, 0xE2, 0xE4, 0xE0, 0xE5, 0xE7, /* 80 - 87 */ + 0xEA, 0xEB, 0xE8, 0xEF, 0xEE, 0xEC, 0xC4, 0xC5, /* 88 - 8F */ + 0xC9, 0xE6, 0xC6, 0xF4, 0xF6, 0xF2, 0xFB, 0xF9, /* 90 - 97 */ + 0xFF, 0xD6, 0xDC, 0xF8, 0xA3, 0xD8, 0xD7, 0x83, /* 98 - 9F */ + 0xE1, 0xED, 0xF3, 0xFA, 0xF1, 0xD1, 0xAA, 0xBA, /* A0 - A7 */ + 0xBF, 0xAE, 0xAC, 0xBD, 0xBC, 0xA1, 0xAB, 0xBB, /* A8 - AF */ + 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xC1, 0xC2, 0xC0, /* B0 - B7 */ + 0xA9, 0xA6, 0xA6, 0x2B, 0x2B, 0xA2, 0xA5, 0x2B, /* B8 - BF */ + 0x2B, 0x2D, 0x2D, 0x2B, 0x2D, 0x2B, 0xE3, 0xC3, /* C0 - C7 */ + 0x2B, 0x2B, 0x2D, 0x2D, 0xA6, 0x2D, 0x2B, 0xA4, /* C8 - CF */ + 0xF0, 0xD0, 0xCA, 0xCB, 0xC8, 0x69, 0xCD, 0xCE, /* D0 - D7 */ + 0xCF, 0x2B, 0x2B, 0xA6, 0x5F, 0xA6, 0xCC, 0xAF, /* D8 - DF */ + 0xD3, 0xDF, 0xD4, 0xD2, 0xF5, 0xD5, 0xB5, 0xFE, /* E0 - E7 */ + 0xDE, 0xDA, 0xDB, 0xD9, 0xFD, 0xDD, 0xAF, 0xB4, /* E8 - EF */ + 0xAD, 0xB1, 0x3D, 0xBE, 0xB6, 0xA7, 0xF7, 0xB8, /* F0 - F7 */ + 0xB0, 0xA8, 0xB7, 0xB9, 0xB3, 0xB2, 0xA6, 0xA0 /* F8 - FF */ +}; +#endif /* OEM_RUS */ +#endif /* IZ_OEM2ISO_ARRAY */ + +#if defined(THEOS) || defined(THEOS_SUPPORT) +# include "theos/charconv.h" +#endif + +#endif /* __ebcdic_h */ diff --git a/file_id.diz b/file_id.diz new file mode 100644 index 0000000..5e3f34e --- /dev/null +++ b/file_id.diz @@ -0,0 +1,15 @@ +Info-ZIP's Zip 3.0: generic C sources. + Complete C source code for Info-ZIP's + PKZIP-compatible .zip archiver, for + all supported compilers and platforms + (Unix, OS/2, MS-DOS, NT, VMS, Amiga, + Atari, Mac, Acorn, VM/CMS, etc.), plus + lots of pretty decent documentation. + Includes Info-ZIP's ZCrypt 2.9 for + PKWARE-compatible standard encryption + and decryption support for Info-ZIP's + Zip 2.32, Zip 3.0, UnZip 5.52, + UnZip 6.0, and WiZ 5.02 (and later). +This is FREE (but copyrighted) software. +See LICENSE for details on distribution +and reuse. diff --git a/fileio.c b/fileio.c new file mode 100644 index 0000000..1847e62 --- /dev/null +++ b/fileio.c @@ -0,0 +1,4903 @@ +/* + fileio.c - Zip 3 + + Copyright (c) 1990-2008 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 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 +*/ +/* + * fileio.c by Mark Adler + */ +#define __FILEIO_C + +#include "zip.h" +#include "crc32.h" + +#ifdef MACOS +# include "helpers.h" +#endif + +#ifdef VMS +# include "vms/vms.h" +#endif /* def VMS */ + +#include + +#ifdef NO_MKTIME +time_t mktime OF((struct tm *)); +#endif + +#ifdef OSF +#define EXDEV 18 /* avoid a bug in the DEC OSF/1 header files. */ +#else +#include +#endif + +#ifdef NO_ERRNO +extern int errno; +#endif + +/* ----------------------- + For long option support + ----------------------- */ +#include + + +#if defined(VMS) || defined(TOPS20) +# define PAD 5 +#else +# define PAD 0 +#endif + +#ifdef NO_RENAME +int rename OF((ZCONST char *, ZCONST char *)); +#endif + + +/* Local functions */ +local int optionerr OF((char *, ZCONST char *, int, int)); +local unsigned long get_shortopt OF((char **, int, int *, int *, char **, int *, int)); +local unsigned long get_longopt OF((char **, int, int *, int *, char **, int *, int)); + +#ifdef UNICODE_SUPPORT +local int utf8_char_bytes OF((ZCONST char *utf8)); +local long ucs4_char_from_utf8 OF((ZCONST char **utf8 )); +local int utf8_from_ucs4_char OF((char *utf8buf, ulg ch)); +local int utf8_to_ucs4_string OF((ZCONST char *utf8, ulg *usc4buf, + int buflen)); +local int ucs4_string_to_utf8 OF((ZCONST ulg *ucs4, char *utf8buf, + int buflen)); +#if 0 + local int utf8_chars OF((ZCONST char *utf8)); +#endif +#endif /* UNICODE_SUPPORT */ + +#ifndef UTIL /* the companion #endif is a bit of ways down ... */ + +local int fqcmp OF((ZCONST zvoid *, ZCONST zvoid *)); +local int fqcmpz OF((ZCONST zvoid *, ZCONST zvoid *)); + + +/* Local module level variables. */ +char *label = NULL; /* global, but only used in `system'.c */ +local z_stat zipstatb; /* now use z_stat globally - 7/24/04 EG */ +#if defined(UNICODE_SUPPORT) && defined(WIN32) + local zw_stat zipstatbw; +#endif +#if (!defined(MACOS) && !defined(WINDLL)) +local int zipstate = -1; +#else +int zipstate; +#endif +/* -1 unknown, 0 old zip file exists, 1 new zip file */ + +#if 0 +char *getnam(n, fp) +char *n; /* where to put name (must have >=FNMAX+1 bytes) */ +#endif + +/* converted to return string pointer from malloc to avoid + size limitation - 11/8/04 EG */ +#define GETNAM_MAX 9000 /* hopefully big enough for now */ +char *getnam(fp) + FILE *fp; + /* Read a \n or \r delimited name from stdin into n, and return + n. If EOF, then return NULL. Also, if problem return NULL. */ +{ + char name[GETNAM_MAX + 1]; + int c; /* last character read */ + char *p; /* pointer into name area */ + + + p = name; + while ((c = getc(fp)) == '\n' || c == '\r') + ; + if (c == EOF) + return NULL; + do { + if (p - name >= GETNAM_MAX) + return NULL; + *p++ = (char) c; + c = getc(fp); + } while (c != EOF && (c != '\n' && c != '\r')); +#ifdef WIN32 +/* + * WIN32 strips off trailing spaces and periods in filenames + * XXX what about a filename that only consists of spaces ? + * Answer: on WIN32, a filename must contain at least one non-space char + */ + while (p > name) { + if ((c = p[-1]) != ' ' && c != '.') + break; + --p; + } +#endif + *p = 0; + /* malloc a copy */ + if ((p = malloc(strlen(name) + 1)) == NULL) { + return NULL; + } + strcpy(p, name); + return p; +} + +struct flist far *fexpel(f) +struct flist far *f; /* entry to delete */ +/* Delete the entry *f in the doubly-linked found list. Return pointer to + next entry to allow stepping through list. */ +{ + struct flist far *t; /* temporary variable */ + + t = f->nxt; + *(f->lst) = t; /* point last to next, */ + if (t != NULL) + t->lst = f->lst; /* and next to last */ + if (f->name != NULL) /* free memory used */ + free((zvoid *)(f->name)); + if (f->zname != NULL) + free((zvoid *)(f->zname)); + if (f->iname != NULL) + free((zvoid *)(f->iname)); +#ifdef UNICODE_SUPPORT + if (f->uname) + free((zvoid *)f->uname); +# ifdef WIN32 + if (f->namew) + free((zvoid *)f->namew); + if (f->inamew) + free((zvoid *)f->inamew); + if (f->znamew) + free((zvoid *)f->znamew); +# endif +#endif + farfree((zvoid far *)f); + fcount--; /* decrement count */ + return t; /* return pointer to next */ +} + +local int fqcmp(a, b) + ZCONST zvoid *a, *b; /* pointers to pointers to found entries */ +/* Used by qsort() to compare entries in the found list by name. */ +{ + return strcmp((*(struct flist far **)a)->name, + (*(struct flist far **)b)->name); +} + +local int fqcmpz(a, b) + ZCONST zvoid *a, *b; /* pointers to pointers to found entries */ +/* Used by qsort() to compare entries in the found list by iname. */ +{ + return strcmp((*(struct flist far **)a)->iname, + (*(struct flist far **)b)->iname); +} + +char *last(p, c) + char *p; /* sequence of path components */ + int c; /* path components separator character */ +/* Return a pointer to the start of the last path component. For a directory + * name terminated by the character in c, the return value is an empty string. + */ +{ + char *t; /* temporary variable */ + + if ((t = strrchr(p, c)) != NULL) + return t + 1; + else +#ifndef AOS_VS + return p; +#else +/* We want to allow finding of end of path in either AOS/VS-style pathnames + * or Unix-style pathnames. This presents a few little problems ... + */ + { + if (*p == '=' || *p == '^') /* like ./ and ../ respectively */ + return p + 1; + else + return p; + } +#endif +} + +#if defined(UNICODE_SUPPORT) && defined(WIN32) +wchar_t *lastw(pw, c) + wchar_t *pw; /* sequence of path components */ + wchar_t c; /* path components separator character */ +/* Return a pointer to the start of the last path component. For a directory + * name terminated by the character in c, the return value is an empty string. + */ +{ + wchar_t *tw; /* temporary variable */ + + if ((tw = wcsrchr(pw, c)) != NULL) + return tw + 1; + else +# ifndef AOS_VS + return pw; +# else +/* We want to allow finding of end of path in either AOS/VS-style pathnames + * or Unix-style pathnames. This presents a few little problems ... + */ + { + if (*pw == (wchar_t)'=' || *pw == (wchar_t)'^') /* like ./ and ../ respectively */ + return pw + 1; + else + return pw; + } +# endif +} +#endif + + +char *msname(n) + char *n; +/* Reduce all path components to MSDOS upper case 8.3 style names. */ +{ + int c; /* current character */ + int f; /* characters in current component */ + char *p; /* source pointer */ + char *q; /* destination pointer */ + + p = q = n; + f = 0; + while ((c = (unsigned char)*POSTINCSTR(p)) != 0) + if (c == ' ' || c == ':' || c == '"' || c == '*' || c == '+' || + c == ',' || c == ';' || c == '<' || c == '=' || c == '>' || + c == '?' || c == '[' || c == ']' || c == '|') + continue; /* char is discarded */ + else if (c == '/') + { + *POSTINCSTR(q) = (char)c; + f = 0; /* new component */ + } +#ifdef __human68k__ + else if (ismbblead(c) && *p) + { + if (f == 7 || f == 11) + f++; + else if (*p && f < 12 && f != 8) + { + *q++ = c; + *q++ = *p++; + f += 2; + } + } +#endif /* __human68k__ */ + else if (c == '.') + { + if (f == 0) + continue; /* leading dots are discarded */ + else if (f < 9) + { + *POSTINCSTR(q) = (char)c; + f = 9; /* now in file type */ + } + else + f = 12; /* now just excess characters */ + } + else + if (f < 12 && f != 8) + { + f += CLEN(p); /* do until end of name or type */ + *POSTINCSTR(q) = (char)(to_up(c)); + } + *q = 0; + return n; +} + +#ifdef UNICODE_SUPPORT +wchar_t *msnamew(nw) + wchar_t *nw; +/* Reduce all path components to MSDOS upper case 8.3 style names. */ +{ + wchar_t c; /* current character */ + int f; /* characters in current component */ + wchar_t *pw; /* source pointer */ + wchar_t *qw; /* destination pointer */ + + pw = qw = nw; + f = 0; + while ((c = (unsigned char)*pw++) != 0) + if (c == ' ' || c == ':' || c == '"' || c == '*' || c == '+' || + c == ',' || c == ';' || c == '<' || c == '=' || c == '>' || + c == '?' || c == '[' || c == ']' || c == '|') + continue; /* char is discarded */ + else if (c == '/') + { + *qw++ = c; + f = 0; /* new component */ + } +#ifdef __human68k__ + else if (ismbblead(c) && *pw) + { + if (f == 7 || f == 11) + f++; + else if (*pw && f < 12 && f != 8) + { + *qw++ = c; + *qw++ = *pw++; + f += 2; + } + } +#endif /* __human68k__ */ + else if (c == '.') + { + if (f == 0) + continue; /* leading dots are discarded */ + else if (f < 9) + { + *qw++ = c; + f = 9; /* now in file type */ + } + else + f = 12; /* now just excess characters */ + } + else + if (f < 12 && f != 8) + { + f++; /* do until end of name or type */ + *qw++ = towupper(c); + } + *qw = 0; + return nw; +} +#endif + + +int proc_archive_name(n, caseflag) + char *n; /* name to process */ + int caseflag; /* true to force case-sensitive match */ +/* Process a name or sh expression in existing archive to operate + on (or exclude). Return an error code in the ZE_ class. */ +{ + int m; /* matched flag */ + char *p; /* path for recursion */ + struct zlist far *z; /* steps through zfiles list */ + + if (strcmp(n, "-") == 0) { /* if compressing stdin */ + zipwarn("Cannot select stdin when selecting archive entries", ""); + return ZE_MISS; + } + else + { + /* 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->oname); + m = 0; + } + } +#ifdef UNICODE_SUPPORT + /* also check escaped Unicode names */ + for (z = zfiles; z != NULL; z = z->nxt) { + if (z->zuname) { +#ifdef WIN32 + /* It seems something is lost in going from a listed + name from zip -su in a console window to using that + name in a command line. This kluge may fix it + and just takes zuname, converts to oem (i.e. ouname), + then converts it back which ends up not the same as + started with. + */ + char *zuname = z->wuname; +#else + char *zuname = z->zuname; +#endif + if (MATCH(p, zuname, caseflag)) + { + z->mark = pcount ? filter(zuname, caseflag) : 1; + if (verbose) { + fprintf(mesg, "zip diagnostic: %scluding %s\n", + z->mark ? "in" : "ex", z->oname); + fprintf(mesg, " Escaped Unicode: %s\n", + z->ouname); + } + m = 0; + } + } + } +#endif + free((zvoid *)p); + return m ? ZE_MISS : ZE_OK; + } +} + + +int check_dup() +/* Sort the found list and remove duplicates. + Return an error code in the ZE_ class. */ +{ + struct flist far *f; /* steps through found linked list */ + extent j, k; /* indices for s */ + struct flist far **s; /* sorted table */ + struct flist far **nodup; /* sorted table without duplicates */ + + /* sort found list, remove duplicates */ + if (fcount) + { + extent fl_size = fcount * sizeof(struct flist far *); + if ((fl_size / sizeof(struct flist far *)) != fcount || + (s = (struct flist far **)malloc(fl_size)) == NULL) + return ZE_MEM; + for (j = 0, f = found; f != NULL; f = f->nxt) + s[j++] = f; + /* Check names as given (f->name) */ + qsort((char *)s, fcount, sizeof(struct flist far *), fqcmp); + for (k = j = fcount - 1; j > 0; j--) + if (strcmp(s[j - 1]->name, s[j]->name) == 0) + /* remove duplicate entry from list */ + fexpel(s[j]); /* fexpel() changes fcount */ + else + /* copy valid entry into destination position */ + s[k--] = s[j]; + s[k] = s[0]; /* First entry is always valid */ + nodup = &s[k]; /* Valid entries are at end of array s */ + + /* sort only valid items and check for unique internal names (f->iname) */ + qsort((char *)nodup, fcount, sizeof(struct flist far *), fqcmpz); + for (j = 1; j < fcount; j++) + if (strcmp(nodup[j - 1]->iname, nodup[j]->iname) == 0) + { + char tempbuf[FNMAX+4081]; + + sprintf(errbuf, " first full name: %s\n", nodup[j - 1]->name); + sprintf(tempbuf, " second full name: %s\n", nodup[j]->name); + strcat(errbuf, " "); + strcat(errbuf, tempbuf); +#ifdef EBCDIC + strtoebc(nodup[j]->iname, nodup[j]->iname); +#endif + sprintf(tempbuf, "name in zip file repeated: %s", nodup[j]->iname); + strcat(errbuf, " "); + strcat(errbuf, tempbuf); + if (pathput == 0) { + strcat(errbuf, "\n this may be a result of using -j"); + } +#ifdef EBCDIC + strtoasc(nodup[j]->iname, nodup[j]->iname); +#endif + zipwarn(errbuf, ""); + return ZE_PARMS; + } + free((zvoid *)s); + } + return ZE_OK; +} + +int filter(name, casesensitive) + char *name; + int casesensitive; + /* Scan the -R, -i and -x lists for matches to the given name. + Return TRUE if the name must be included, FALSE otherwise. + Give precedence to -x over -i and -R. + Note that if both R and i patterns are given then must + have a match for both. + This routine relies on the following global variables: + patterns array of match pattern structures + pcount total number of patterns + icount number of -i patterns + Rcount number of -R patterns + These data are set up by the command line parsing code. + */ +{ + unsigned int n; + int slashes; + char *p, *q; + /* without -i patterns, every name matches the "-i select rules" */ + int imatch = (icount == 0); + /* without -R patterns, every name matches the "-R select rules" */ + int Rmatch = (Rcount == 0); + + if (pcount == 0) return TRUE; + + for (n = 0; n < pcount; n++) { + if (!patterns[n].zname[0]) /* it can happen... */ + continue; + p = name; + switch (patterns[n].select) { + case 'R': + if (Rmatch) + /* one -R match is sufficient, skip this pattern */ + continue; + /* With -R patterns, if the pattern has N path components (that is, + N-1 slashes), then we test only the last N components of name. + */ + slashes = 0; + for (q = patterns[n].zname; (q = MBSCHR(q, '/')) != NULL; MB_NEXTCHAR(q)) + slashes++; + /* The name may have M path components (M-1 slashes) */ + for (q = p; (q = MBSCHR(q, '/')) != NULL; MB_NEXTCHAR(q)) + slashes--; + /* Now, "slashes" contains the difference "N-M" between the number + of path components in the pattern (N) and in the name (M). + */ + if (slashes < 0) + /* We found "M > N" + --> skip the first (M-N) path components of the name. + */ + for (q = p; (q = MBSCHR(q, '/')) != NULL; MB_NEXTCHAR(q)) + if (++slashes == 0) { + p = q + 1; /* q points at '/', mblen("/") is 1 */ + break; + } + break; + case 'i': + if (imatch) + /* one -i match is sufficient, skip this pattern */ + continue; + break; + } + if (MATCH(patterns[n].zname, p, casesensitive)) { + switch (patterns[n].select) { + case 'x': + /* The -x match takes precedence over everything else */ + return FALSE; + case 'R': + Rmatch = TRUE; + break; + default: + /* this must be a type -i match */ + imatch = TRUE; + break; + } + } + } + return imatch && Rmatch; +} + + +#ifdef UNICODE_SUPPORT +# ifdef WIN32 + +int newnamew(namew, isdir, casesensitive) + wchar_t *namew; /* name to add (or exclude) */ + int isdir; /* true for a directory */ + int casesensitive; /* true for case-sensitive matching */ +/* Add (or exclude) the name of an existing disk file. Return an error + code in the ZE_ class. */ +{ + wchar_t *inamew = NULL; /* internal name */ + wchar_t *znamew = NULL; /* external version of iname */ + wchar_t *undosmw = NULL; /* zname version with "-j" and "-k" options disabled */ + char *oname = NULL; /* iname converted for display */ + char *name = NULL; + char *iname = NULL; + char *zname = NULL; + char *zuname = NULL; + char *undosm = NULL; + struct flist far *f; /* where in found, or new found entry */ + struct zlist far *z; /* where in zfiles (if found) */ + int dosflag; + + /* Scanning files ... + * + * After 5 seconds output Scanning files... + * then a dot every 2 seconds + */ + if (noisy) { + /* If find files then output message after delay */ + if (scan_count == 0) { + time_t current = time(NULL); + scan_start = current; + } + scan_count++; + if (scan_count % 100 == 0) { + time_t current = time(NULL); + + if (current - scan_start > scan_delay) { + if (scan_last == 0) { + zipmessage_nl("Scanning files ", 0); + scan_last = current; + } + if (current - scan_last > scan_dot_time) { + scan_last = current; + fprintf(mesg, "."); + fflush(mesg); + } + } + } + } + + /* Search for name in zip file. If there, mark it, else add to + list of new names to do (or remove from that list). */ + if ((inamew = ex2inw(namew, isdir, &dosflag)) == NULL) + return ZE_MEM; + + /* Discard directory names with zip -rj */ + if (*inamew == (wchar_t)'\0') { + + /* If extensions needs to be swapped, we will have empty directory names + instead of the original directory. For example, zipping 'c.', 'c.main' + should zip only 'main.c' while 'c.' will be converted to '\0' by ex2in. */ + + if (pathput && !recurse) error("empty name without -j or -r"); + free((zvoid *)inamew); + return ZE_OK; + } + + if (dosflag || !pathput) { + int save_dosify = dosify, save_pathput = pathput; + dosify = 0; + pathput = 1; + /* zname is temporarly mis-used as "undosmode" iname pointer */ + if ((znamew = ex2inw(namew, isdir, NULL)) != NULL) { + undosmw = in2exw(znamew); + free(znamew); + } + dosify = save_dosify; + pathput = save_pathput; + } + if ((znamew = in2exw(inamew)) == NULL) + return ZE_MEM; + + /* Convert names from wchar_t to char */ + + name = wchar_to_local_string(namew); + iname = wchar_to_local_string(inamew); + zname = wchar_to_local_string(znamew); + + oname = local_to_display_string(zname); + + zuname = wchar_to_local_string(znamew); + + if (undosmw == NULL) + undosmw = znamew; + undosm = wchar_to_local_string(undosmw); + + if ((z = zsearch(zuname)) != NULL) { + if (pcount && !filter(undosm, casesensitive)) { + /* Do not clear z->mark if "exclude", because, when "dosify || !pathput" + * is in effect, two files with different filter options may hit the + * same z entry. + */ + if (verbose) + fprintf(mesg, "excluding %s\n", oname); + } else { + z->mark = 1; + if ((z->name = malloc(strlen(name) + 1 + PAD)) == NULL) { + if (undosmw != znamew) + free(undosmw); + if (undosm) free(undosm); + if (inamew) free(inamew); + if (znamew) free(znamew); + if (name) free(name); + if (iname) free(iname); + if (zname) free(zname); + if (oname) free(oname); + if (zuname) free(zuname); + return ZE_MEM; + } + strcpy(z->name, name); + z->oname = oname; + oname = NULL; + z->dosflag = dosflag; + +#ifdef FORCE_NEWNAME + free((zvoid *)(z->iname)); + z->iname = iname; + iname = NULL; +#else + /* Better keep the old name. Useful when updating on MSDOS a zip file + * made on Unix. + */ +#endif /* ? FORCE_NEWNAME */ + } + + if ((z->namew = (wchar_t *)malloc((wcslen(namew) + 1) * sizeof(wchar_t))) == NULL) { + if (undosmw != znamew) + free(undosmw); + if (undosm) free(undosm); + if (inamew) free(inamew); + if (znamew) free(znamew); + if (name) free(name); + if (iname) free(iname); + if (zname) free(zname); + if (oname) free(oname); + if (zuname) free(zuname); + return ZE_MEM; + } + wcscpy(z->namew, namew); + z->inamew = inamew; + inamew = NULL; + z->znamew = znamew; + znamew = NULL; + z->uname = wchar_to_utf8_string(z->inamew); + if (name == label) { + label = z->name; + } + } else if (pcount == 0 || filter(undosm, casesensitive)) { + + /* Check that we are not adding the zip file to itself. This + * catches cases like "zip -m foo ../dir/foo.zip". + */ +/* Version of stat() for CMS/MVS isn't complete enough to see if */ +/* files match. Just let ZIP.C compare the filenames. That's good */ +/* enough for CMS anyway since there aren't paths to worry about. */ + zw_stat statbw; /* need for wide stat */ + wchar_t *zipfilew = local_to_wchar_string(zipfile); + + if (zipstate == -1) + zipstate = strcmp(zipfile, "-") != 0 && + zwstat(zipfilew, &zipstatbw) == 0; + free(zipfilew); + + if (zipstate == 1 && (statbw = zipstatbw, zwstat(namew, &statbw) == 0 + && zipstatbw.st_mode == statbw.st_mode + && zipstatbw.st_ino == statbw.st_ino + && zipstatbw.st_dev == statbw.st_dev + && zipstatbw.st_uid == statbw.st_uid + && zipstatbw.st_gid == statbw.st_gid + && zipstatbw.st_size == statbw.st_size + && zipstatbw.st_mtime == statbw.st_mtime + && zipstatbw.st_ctime == statbw.st_ctime)) { + /* Don't compare a_time since we are reading the file */ + if (verbose) + fprintf(mesg, "file matches zip file -- skipping\n"); + if (undosmw != znamew) + free(undosmw); + if (undosm) free(undosm); + if (inamew) free(inamew); + if (znamew) free(znamew); + if (name) free(name); + if (iname) free(iname); + if (zname) free(zname); + if (oname) free(oname); + if (zuname) free(zuname); + return ZE_OK; + } + + /* allocate space and add to list */ + if ((f = (struct flist far *)farmalloc(sizeof(struct flist))) == NULL || + fcount + 1 < fcount || + (f->name = malloc(strlen(name) + 1 + PAD)) == NULL) + { + if (f != NULL) + farfree((zvoid far *)f); + if (undosmw != znamew) + free(undosmw); + if (undosm) free(undosm); + if (inamew) free(inamew); + if (znamew) free(znamew); + if (name) free(name); + if (iname) free(iname); + if (zname) free(zname); + if (oname) free(oname); + if (zuname) free(zuname); + return ZE_MEM; + } + if (undosmw != znamew) + free((zvoid *)undosmw); + strcpy(f->name, name); + f->iname = iname; + iname = NULL; + f->zname = zname; + zname = NULL; + /* Unicode */ + if ((f->namew = (wchar_t *)malloc((wcslen(namew) + 1) * sizeof(wchar_t))) == NULL) { + if (f != NULL) + farfree((zvoid far *)f); + if (undosmw != znamew) + free(undosmw); + if (undosm) free(undosm); + if (inamew) free(inamew); + if (znamew) free(znamew); + if (name) free(name); + if (iname) free(iname); + if (zname) free(zname); + if (oname) free(oname); + if (zuname) free(zuname); + return ZE_MEM; + } + wcscpy(f->namew, namew); + f->znamew = znamew; + znamew = NULL; + f->uname = wchar_to_utf8_string(inamew); + f->inamew = inamew; + inamew = NULL; + f->oname = oname; + oname = NULL; + f->dosflag = dosflag; + *fnxt = f; + f->lst = fnxt; + f->nxt = NULL; + fnxt = &f->nxt; + fcount++; + if (name == label) { + label = f->name; + } + } + if (undosm) free(undosm); + if (inamew) free(inamew); + if (znamew) free(znamew); + if (name) free(name); + if (iname) free(iname); + if (zname) free(zname); + if (oname) free(oname); + if (zuname) free(zuname); + return ZE_OK; +} + +# endif +#endif + +int newname(name, isdir, casesensitive) + char *name; /* name to add (or exclude) */ + int isdir; /* true for a directory */ + int casesensitive; /* true for case-sensitive matching */ +/* Add (or exclude) the name of an existing disk file. Return an error + code in the ZE_ class. */ +{ + char *iname, *zname; /* internal name, external version of iname */ + char *undosm; /* zname version with "-j" and "-k" options disabled */ + char *oname; /* iname converted for display */ + struct flist far *f; /* where in found, or new found entry */ + struct zlist far *z; /* where in zfiles (if found) */ + int dosflag; + + /* Scanning files ... + * + * After 5 seconds output Scanning files... + * then a dot every 2 seconds + */ + if (noisy) { + /* If find files then output message after delay */ + if (scan_count == 0) { + time_t current = time(NULL); + scan_start = current; + } + scan_count++; + if (scan_count % 100 == 0) { + time_t current = time(NULL); + + if (current - scan_start > scan_delay) { + if (scan_last == 0) { + zipmessage_nl("Scanning files ", 0); + scan_last = current; + } + if (current - scan_last > scan_dot_time) { + scan_last = current; + fprintf(mesg, "."); + fflush(mesg); + } + } + } + } + + /* Search for name in zip file. If there, mark it, else add to + list of new names to do (or remove from that list). */ + if ((iname = ex2in(name, isdir, &dosflag)) == NULL) + return ZE_MEM; + + /* Discard directory names with zip -rj */ + if (*iname == '\0') { +#ifndef AMIGA +/* A null string is a legitimate external directory name in AmigaDOS; also, + * a command like "zip -r zipfile FOO:" produces an empty internal name. + */ +# ifndef RISCOS + /* If extensions needs to be swapped, we will have empty directory names + instead of the original directory. For example, zipping 'c.', 'c.main' + should zip only 'main.c' while 'c.' will be converted to '\0' by ex2in. */ + + if (pathput && !recurse) error("empty name without -j or -r"); + +# endif /* !RISCOS */ +#endif /* !AMIGA */ + free((zvoid *)iname); + return ZE_OK; + } + undosm = NULL; + if (dosflag || !pathput) { + int save_dosify = dosify, save_pathput = pathput; + dosify = 0; + pathput = 1; + /* zname is temporarly mis-used as "undosmode" iname pointer */ + if ((zname = ex2in(name, isdir, NULL)) != NULL) { + undosm = in2ex(zname); + free(zname); + } + dosify = save_dosify; + pathput = save_pathput; + } + if ((zname = in2ex(iname)) == NULL) + return ZE_MEM; +#ifdef UNICODE_SUPPORT + /* Convert name to display or OEM name */ + oname = local_to_display_string(iname); +#else + if ((oname = malloc(strlen(zname) + 1)) == NULL) + return ZE_MEM; + strcpy(oname, zname); +#endif + if (undosm == NULL) + undosm = zname; + if ((z = zsearch(zname)) != NULL) { + if (pcount && !filter(undosm, casesensitive)) { + /* Do not clear z->mark if "exclude", because, when "dosify || !pathput" + * is in effect, two files with different filter options may hit the + * same z entry. + */ + if (verbose) + fprintf(mesg, "excluding %s\n", oname); + free((zvoid *)iname); + free((zvoid *)zname); + } else { + z->mark = 1; + if ((z->name = malloc(strlen(name) + 1 + PAD)) == NULL) { + if (undosm != zname) + free((zvoid *)undosm); + free((zvoid *)iname); + free((zvoid *)zname); + return ZE_MEM; + } + strcpy(z->name, name); + z->oname = oname; + z->dosflag = dosflag; + +#ifdef FORCE_NEWNAME + free((zvoid *)(z->iname)); + z->iname = iname; +#else + /* Better keep the old name. Useful when updating on MSDOS a zip file + * made on Unix. + */ + free((zvoid *)iname); + free((zvoid *)zname); +#endif /* ? FORCE_NEWNAME */ + } +#if defined(UNICODE_SUPPORT) && defined(WIN32) + z->namew = NULL; + z->inamew = NULL; + z->znamew = NULL; +#endif + if (name == label) { + label = z->name; + } + } else if (pcount == 0 || filter(undosm, casesensitive)) { + + /* Check that we are not adding the zip file to itself. This + * catches cases like "zip -m foo ../dir/foo.zip". + */ +#ifndef CMS_MVS +/* Version of stat() for CMS/MVS isn't complete enough to see if */ +/* files match. Just let ZIP.C compare the filenames. That's good */ +/* enough for CMS anyway since there aren't paths to worry about. */ + z_stat statb; /* now use structure z_stat and function zstat globally 7/24/04 EG */ + + if (zipstate == -1) + zipstate = strcmp(zipfile, "-") != 0 && + zstat(zipfile, &zipstatb) == 0; + + if (zipstate == 1 && (statb = zipstatb, zstat(name, &statb) == 0 + && zipstatb.st_mode == statb.st_mode +#ifdef VMS + && memcmp(zipstatb.st_ino, statb.st_ino, sizeof(statb.st_ino)) == 0 + && strcmp(zipstatb.st_dev, statb.st_dev) == 0 + && zipstatb.st_uid == statb.st_uid +#else /* !VMS */ + && zipstatb.st_ino == statb.st_ino + && zipstatb.st_dev == statb.st_dev + && zipstatb.st_uid == statb.st_uid + && zipstatb.st_gid == statb.st_gid +#endif /* ?VMS */ + && zipstatb.st_size == statb.st_size + && zipstatb.st_mtime == statb.st_mtime + && zipstatb.st_ctime == statb.st_ctime)) { + /* Don't compare a_time since we are reading the file */ + if (verbose) + fprintf(mesg, "file matches zip file -- skipping\n"); + if (undosm != zname) + free((zvoid *)zname); + if (undosm != iname) + free((zvoid *)undosm); + free((zvoid *)iname); + free(oname); + return ZE_OK; + } +#endif /* CMS_MVS */ + + /* allocate space and add to list */ + if ((f = (struct flist far *)farmalloc(sizeof(struct flist))) == NULL || + fcount + 1 < fcount || + (f->name = malloc(strlen(name) + 1 + PAD)) == NULL) + { + if (f != NULL) + farfree((zvoid far *)f); + if (undosm != zname) + free((zvoid *)undosm); + free((zvoid *)iname); + free((zvoid *)zname); + free(oname); + return ZE_MEM; + } + strcpy(f->name, name); + f->iname = iname; + f->zname = zname; +#ifdef UNICODE_SUPPORT + /* Unicode */ + f->uname = local_to_utf8_string(iname); +#ifdef WIN32 + f->namew = NULL; + f->inamew = NULL; + f->znamew = NULL; + if (strcmp(f->name, "-") == 0) { + f->namew = local_to_wchar_string(f->name); + } +#endif + +#endif + f->oname = oname; + f->dosflag = dosflag; + + *fnxt = f; + f->lst = fnxt; + f->nxt = NULL; + fnxt = &f->nxt; + fcount++; + if (name == label) { + label = f->name; + } + } + if (undosm != zname) + free((zvoid *)undosm); + return ZE_OK; +} + +ulg dostime(y, n, d, h, m, s) +int y; /* year */ +int n; /* month */ +int d; /* day */ +int h; /* hour */ +int m; /* minute */ +int s; /* second */ +/* Convert the date y/n/d and time h:m:s to a four byte DOS date and + time (date in high two bytes, time in low two bytes allowing magnitude + comparison). */ +{ + return y < 1980 ? DOSTIME_MINIMUM /* dostime(1980, 1, 1, 0, 0, 0) */ : + (((ulg)y - 1980) << 25) | ((ulg)n << 21) | ((ulg)d << 16) | + ((ulg)h << 11) | ((ulg)m << 5) | ((ulg)s >> 1); +} + + +ulg unix2dostime(t) +time_t *t; /* unix time to convert */ +/* Return the Unix time t in DOS format, rounded up to the next two + second boundary. */ +{ + time_t t_even; + struct tm *s; /* result of localtime() */ + + t_even = (time_t)(((unsigned long)(*t) + 1) & (~1)); + /* Round up to even seconds. */ + s = localtime(&t_even); /* Use local time since MSDOS does. */ + if (s == (struct tm *)NULL) { + /* time conversion error; use current time as emergency value + (assuming that localtime() does at least accept this value!) */ + t_even = (time_t)(((unsigned long)time(NULL) + 1) & (~1)); + s = localtime(&t_even); + } + return dostime(s->tm_year + 1900, s->tm_mon + 1, s->tm_mday, + s->tm_hour, s->tm_min, s->tm_sec); +} + +int issymlnk(a) +ulg a; /* Attributes returned by filetime() */ +/* Return true if the attributes are those of a symbolic link */ +{ +#ifndef QDOS +#ifdef S_IFLNK +#ifdef __human68k__ + int *_dos_importlnenv(void); + + if (_dos_importlnenv() == NULL) + return 0; +#endif + return ((a >> 16) & S_IFMT) == S_IFLNK; +#else /* !S_IFLNK */ + return (int)a & 0; /* avoid warning on unused parameter */ +#endif /* ?S_IFLNK */ +#else + return 0; +#endif +} + +#endif /* !UTIL */ + + +#if (!defined(UTIL) && !defined(ZP_NEED_GEN_D2U_TIME)) + /* There is no need for dos2unixtime() in the ZipUtils' code. */ +# define ZP_NEED_GEN_D2U_TIME +#endif +#if ((defined(OS2) || defined(VMS)) && defined(ZP_NEED_GEN_D2U_TIME)) + /* OS/2 and VMS use a special solution to handle time-stams of files. */ +# undef ZP_NEED_GEN_D2U_TIME +#endif +#if (defined(W32_STATROOT_FIX) && !defined(ZP_NEED_GEN_D2U_TIME)) + /* The Win32 stat()-bandaid to fix stat'ing root directories needs + * dos2unixtime() to calculate the time-stamps. */ +# define ZP_NEED_GEN_D2U_TIME +#endif + +#ifdef ZP_NEED_GEN_D2U_TIME + +time_t dos2unixtime(dostime) +ulg dostime; /* DOS time to convert */ +/* Return the Unix time_t value (GMT/UTC time) for the DOS format (local) + * time dostime, where dostime is a four byte value (date in most significant + * word, time in least significant word), see dostime() function. + */ +{ + struct tm *t; /* argument for mktime() */ + ZCONST time_t clock = time(NULL); + + t = localtime(&clock); + t->tm_isdst = -1; /* let mktime() determine if DST is in effect */ + /* Convert DOS time to UNIX time_t format */ + t->tm_sec = (((int)dostime) << 1) & 0x3e; + t->tm_min = (((int)dostime) >> 5) & 0x3f; + t->tm_hour = (((int)dostime) >> 11) & 0x1f; + t->tm_mday = (int)(dostime >> 16) & 0x1f; + t->tm_mon = ((int)(dostime >> 21) & 0x0f) - 1; + t->tm_year = ((int)(dostime >> 25) & 0x7f) + 80; + + return mktime(t); +} + +#undef ZP_NEED_GEN_D2U_TIME +#endif /* ZP_NEED_GEN_D2U_TIME */ + + +#ifndef MACOS +int destroy(f) + char *f; /* file to delete */ +/* Delete the file *f, returning non-zero on failure. */ +{ + return unlink(f); +} + + +int replace(d, s) +char *d, *s; /* destination and source file names */ +/* Replace file *d by file *s, removing the old *s. Return an error code + in the ZE_ class. This function need not preserve the file attributes, + this will be done by setfileattr() later. + */ +{ + z_stat t; /* results of stat() */ +#if defined(CMS_MVS) + /* cmsmvs.h defines FOPW_TEMP as memory(hiperspace). Since memory is + * lost at end of run, always do copy instead of rename. + */ + int copy = 1; +#else + int copy = 0; +#endif + int d_exists; + +#if defined(VMS) || defined(CMS_MVS) + /* stat() is broken on VMS remote files (accessed through Decnet). + * This patch allows creation of remote zip files, but is not sufficient + * to update them or compress remote files */ + unlink(d); +#else /* !(VMS || CMS_MVS) */ + d_exists = (LSTAT(d, &t) == 0); + if (d_exists) + { + /* + * respect existing soft and hard links! + */ + if (t.st_nlink > 1 +# ifdef S_IFLNK + || (t.st_mode & S_IFMT) == S_IFLNK +# endif + ) + copy = 1; + else if (unlink(d)) + return ZE_CREAT; /* Can't erase zip file--give up */ + } +#endif /* ?(VMS || CMS_MVS) */ +#ifndef CMS_MVS + if (!copy) { + if (rename(s, d)) { /* Just move s on top of d */ + copy = 1; /* failed ? */ +#if !defined(VMS) && !defined(ATARI) && !defined(AZTEC_C) +#if !defined(CMS_MVS) && !defined(RISCOS) && !defined(QDOS) + /* For VMS, ATARI, AMIGA Aztec, VM_CMS, MVS, RISCOS, + always assume that failure is EXDEV */ + if (errno != EXDEV +# ifdef THEOS + && errno != EEXIST +# else +# ifdef ENOTSAM + && errno != ENOTSAM /* Used at least on Turbo C */ +# endif +# endif + ) return ZE_CREAT; +#endif /* !CMS_MVS && !RISCOS */ +#endif /* !VMS && !ATARI && !AZTEC_C */ + } + } +#endif /* !CMS_MVS */ + + if (copy) { + FILE *f, *g; /* source and destination files */ + int r; /* temporary variable */ + +#ifdef RISCOS + if (SWI_OS_FSControl_26(s,d,0xA1)!=NULL) { +#endif + + /* Use zfopen for almost all opens where fopen is used. For + most OS that support large files we use the 64-bit file + environment and zfopen maps to fopen, but this allows + tweeking ports that don't do that. 7/24/04 */ + if ((f = zfopen(s, FOPR)) == NULL) { + fprintf(mesg," replace: can't open %s\n", s); + return ZE_TEMP; + } + if ((g = zfopen(d, FOPW)) == NULL) + { + fclose(f); + return ZE_CREAT; + } + + r = fcopy(f, g, (ulg)-1L); + fclose(f); + if (fclose(g) || r != ZE_OK) + { + unlink(d); + return r ? (r == ZE_TEMP ? ZE_WRITE : r) : ZE_WRITE; + } + unlink(s); +#ifdef RISCOS + } +#endif + } + return ZE_OK; +} +#endif /* !MACOS */ + + +int getfileattr(f) +char *f; /* file path */ +/* Return the file attributes for file f or 0 if failure */ +{ +#ifdef __human68k__ + struct _filbuf buf; + + return _dos_files(&buf, f, 0xff) < 0 ? 0x20 : buf.atr; +#else + z_stat s; + + return SSTAT(f, &s) == 0 ? (int) s.st_mode : 0; +#endif +} + + +int setfileattr(f, a) +char *f; /* file path */ +int a; /* attributes returned by getfileattr() */ +/* Give the file f the attributes a, return non-zero on failure */ +{ +#if defined(TOPS20) || defined (CMS_MVS) + return 0; +#else +#ifdef __human68k__ + return _dos_chmod(f, a) < 0 ? -1 : 0; +#else + return chmod(f, a); +#endif +#endif +} + + +/* tempname */ + +#ifndef VMS /* VMS-specific function is in VMS.C. */ + +char *tempname(zip) + char *zip; /* path name of zip file to generate temp name for */ + +/* Return a temporary file name in its own malloc'ed space, using tempath. */ +{ + char *t = zip; /* malloc'ed space for name (use zip to avoid warning) */ + +# ifdef CMS_MVS + if ((t = malloc(strlen(tempath) + L_tmpnam + 2)) == NULL) + return NULL; + +# ifdef VM_CMS + tmpnam(t); + /* Remove filemode and replace with tempath, if any. */ + /* Otherwise A-disk is used by default */ + *(strrchr(t, ' ')+1) = '\0'; + if (tempath!=NULL) + strcat(t, tempath); + return t; +# else /* !VM_CMS */ + /* For MVS */ + tmpnam(t); + if (tempath != NULL) + { + int l1 = strlen(t); + char *dot; + if (*t == '\'' && *(t+l1-1) == '\'' && (dot = strchr(t, '.'))) + { + /* MVS and not OE. tmpnam() returns quoted string of 5 qualifiers. + * First is HLQ, rest are timestamps. User can only replace HLQ. + */ + int l2 = strlen(tempath); + if (strchr(tempath, '.') || l2 < 1 || l2 > 8) + ziperr(ZE_PARMS, "On MVS and not OE, tempath (-b) can only be HLQ"); + memmove(t+1+l2, dot, l1+1-(dot-t)); /* shift dot ready for new hlq */ + memcpy(t+1, tempath, l2); /* insert new hlq */ + } + else + { + /* MVS and probably OE. tmpnam() returns filename based on TMPDIR, + * no point in even attempting to change it. User should modify TMPDIR + * instead. + */ + zipwarn("MVS, assumed to be OE, change TMPDIR instead of option -b: ", + tempath); + } + } + return t; +# endif /* !VM_CMS */ + +# else /* !CMS_MVS */ + +# ifdef TANDEM + char cur_subvol [FILENAME_MAX]; + char temp_subvol [FILENAME_MAX]; + char *zptr; + char *ptr; + char *cptr = &cur_subvol[0]; + char *tptr = &temp_subvol[0]; + short err; + FILE *tempf; + int attempts; + + t = (char *)malloc(NAMELEN); /* malloc here as you cannot free */ + /* tmpnam allocated storage later */ + + zptr = strrchr(zip, TANDEM_DELIMITER); + + if (zptr != NULL) { + /* ZIP file specifies a Subvol so make temp file there so it can just + be renamed at end */ + + *tptr = *cptr = '\0'; + strcat(cptr, getenv("DEFAULTS")); + + strncat(tptr, zip, _min(FILENAME_MAX, (zptr - zip)) ); /* temp subvol */ + strncat(t, zip, _min(NAMELEN, ((zptr - zip) + 1)) ); /* temp stem */ + + err = chvol(tptr); + ptr = t + strlen(t); /* point to end of stem */ + } + else + ptr = t; + + /* If two zips are running in same subvol then we can get contention problems + with the temporary filename. As a work around we attempt to create + the file here, and if it already exists we get a new temporary name */ + + attempts = 0; + do { + attempts++; + tmpnam(ptr); /* Add filename */ + tempf = zfopen(ptr, FOPW_TMP); /* Attempt to create file */ + } while (tempf == NULL && attempts < 100); + + if (attempts >= 100) { + ziperr(ZE_TEMP, "Could not get unique temp file name"); + } + + fclose(tempf); + + if (zptr != NULL) { + err = chvol(cptr); /* Put ourself back to where we came in */ + } + + return t; + +# else /* !CMS_MVS && !TANDEM */ +/* + * Do something with TMPDIR, TMP, TEMP ???? + */ + if (tempath != NULL) + { + if ((t = malloc(strlen(tempath) + 12)) == NULL) + return NULL; + strcpy(t, tempath); + +# if (!defined(VMS) && !defined(TOPS20)) +# ifdef MSDOS + { + char c = (char)lastchar(t); + if (c != '/' && c != ':' && c != '\\') + strcat(t, "/"); + } +# else + +# ifdef AMIGA + { + char c = (char)lastchar(t); + if (c != '/' && c != ':') + strcat(t, "/"); + } +# else /* !AMIGA */ +# ifdef RISCOS + if (lastchar(t) != '.') + strcat(t, "."); +# else /* !RISCOS */ + +# ifdef QDOS + if (lastchar(t) != '_') + strcat(t, "_"); +# else + if (lastchar(t) != '/') + strcat(t, "/"); +# endif /* ?QDOS */ +# endif /* ?RISCOS */ +# endif /* ?AMIGA */ +# endif /* ?MSDOS */ +# endif /* !VMS && !TOPS20 */ + } + else + { + if ((t = malloc(12)) == NULL) + return NULL; + *t = 0; + } +# ifdef NO_MKTEMP + { + char *p = t + strlen(t); + sprintf(p, "%08lx", (ulg)time(NULL)); + return t; + } +# else + strcat(t, "ziXXXXXX"); /* must use lowercase for Linux dos file system */ +# if defined(UNIX) && !defined(NO_MKSTEMP) + /* tempname should not be called */ + return t; +# else + return mktemp(t); +# endif +# endif /* NO_MKTEMP */ +# endif /* TANDEM */ +# endif /* CMS_MVS */ +} +#endif /* !VMS */ + +int fcopy(f, g, n) + FILE *f, *g; /* source and destination files */ + /* now use uzoff_t for all file sizes 5/14/05 CS */ + uzoff_t n; /* number of bytes to copy or -1 for all */ +/* Copy n bytes from file *f to file *g, or until EOF if (zoff_t)n == -1. + Return an error code in the ZE_ class. */ +{ + char *b; /* malloc'ed buffer for copying */ + extent k; /* result of fread() */ + uzoff_t m; /* bytes copied so far */ + + if ((b = malloc(CBSZ)) == NULL) + return ZE_MEM; + m = 0; + while (n == (uzoff_t)(-1L) || m < n) + { + if ((k = fread(b, 1, n == (uzoff_t)(-1) ? + CBSZ : (n - m < CBSZ ? (extent)(n - m) : CBSZ), f)) == 0) + { + if (ferror(f)) + { + free((zvoid *)b); + return ZE_READ; + } + else + break; + } + if (fwrite(b, 1, k, g) != k) + { + free((zvoid *)b); + fprintf(mesg," fcopy: write error\n"); + return ZE_TEMP; + } + m += k; + } + free((zvoid *)b); + return ZE_OK; +} + + +/* from zipfile.c */ + +#ifdef THEOS + /* Macros cause stack overflow in compiler */ + ush SH(uch* p) { return ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8)); } + ulg LG(uch* p) { return ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16)); } +#else /* !THEOS */ + /* Macros for converting integers in little-endian to machine format */ +# define SH(a) ((ush)(((ush)(uch)(a)[0]) | (((ush)(uch)(a)[1]) << 8))) +# define LG(a) ((ulg)SH(a) | ((ulg)SH((a)+2) << 16)) +# ifdef ZIP64_SUPPORT /* zip64 support 08/31/2003 R.Nausedat */ +# define LLG(a) ((zoff_t)LG(a) | ((zoff_t)LG((a)+4) << 32)) +# endif +#endif /* ?THEOS */ + + +/* always copies from global in_file to global output file y */ +int bfcopy(n) + /* now use uzoff_t for all file sizes 5/14/05 CS */ + uzoff_t n; /* number of bytes to copy or -1 for all */ +/* Copy n bytes from in_file to out_file, or until EOF if (zoff_t)n == -1. + + Normally we have the compressed size from either the central directory + entry or the local header. + + If n != -1 and EOF, close current split and open next and continue + copying. + + If n == -2, copy until find the extended header (data descriptor). Only + used for -FF when no size available. + + If fix == 1 calculate CRC of input entry and verify matches. + + If fix == 2 and this entry using data descriptor keep a sliding + window in the buffer for looking for signature. + + Return an error code in the ZE_ class. */ +{ + char *b; /* malloc'ed buffer for copying */ + extent k; /* result of fread() */ + uzoff_t m; /* bytes copied so far */ + extent brd; /* bytes to read */ + zoff_t data_start = 0; + zoff_t des_start = 0; + char *split_path; + extent kk; + int i; + char sbuf[4]; /* buffer for sliding signature window for fix = 2 */ + int des = 0; /* this entry has data descriptor to find */ + + if ((b = malloc(CBSZ)) == NULL) + return ZE_MEM; + + if (copy_only && !display_globaldots) { + /* initialize dot count */ + dot_count = -1; + } + + if (fix == 2 && n == (uzoff_t) -2) { + data_start = zftello(in_file); + for (kk = 0; kk < 4; kk++) + sbuf[kk] = 0; + des = 1; + } + + des_good = 0; + + m = 0; + while (des || n == (uzoff_t)(-1L) || m < n) + { + if (des || n == (uzoff_t)(-1)) + brd = CBSZ; + else + brd = (n - m < CBSZ ? (extent)(n - m) : CBSZ); + + des_start = zftello(in_file); + + if ((k = fread(b, 1, brd, in_file)) == 0) + { + if (fix == 2 && k < brd) { + free((zvoid *)b); + return ZE_READ; + } + else if (ferror(in_file)) + { + free((zvoid *)b); + return ZE_READ; + } + else { + break; + } + } + + + /* end at extended local header (data descriptor) signature */ + if (des) { + des_crc = 0; + des_csize = 0; + des_usize = 0; + + /* If first 4 bytes in buffer are data descriptor signature then + try to read the data descriptor. + If not, scan for signature and break if found, let bfwrite flush + the data and then next read should put the data descriptor at + the beginning of the buffer. + */ + + if ( + (b[0] != 0x50 /*'P' except EBCDIC*/ || + b[1] != 0x4b /*'K' except EBCDIC*/ || + b[2] != '\07' || + b[3] != '\010')) { + /* buffer is not start of data descriptor */ + + for (kk = 0; kk < k; kk++) { + /* add byte to end of sbuf */ + for (i = 0; i < 3; i++) + sbuf[i] = sbuf[i + 1]; + sbuf[3] = b[kk]; + + /* see if this is signature */ + if ( + (sbuf[0] == 0x50 /*'P' except EBCDIC*/ && + sbuf[1] == 0x4b /*'K' except EBCDIC*/ && + sbuf[2] == '\07' && + sbuf[3] == '\010')) { + kk -= 3; + if (zfseeko(in_file, bytes_this_split + kk, SEEK_SET) != 0) { + /* seek error */ + ZIPERR(ZE_READ, "seek failed reading descriptor"); + } + des_start = zftello(in_file); + k = kk; + break; + } + } + } + else + + /* signature at start of buffer */ + { + des_good = 0; + +#ifdef ZIP64_SUPPORT + if (zip64_entry) { + + /* read Zip64 data descriptor */ + if (k < 24) { + /* not enough bytes, so can't be data descriptor + as data descriptors can't be split across splits + */ + } + else + { + /* read the Zip64 descriptor */ + + des_crc = LG(b + 4); + des_csize = LLG(b + 8); + des_usize = LLG(b + 16); + + /* if this is the right data descriptor then the sizes should match */ + if ((uzoff_t)des_start - (uzoff_t)data_start != des_csize) { + /* apparently this signature does not go with this data so skip */ + + /* write out signature as data */ + k = 4; + if (zfseeko(in_file, des_start + k, SEEK_SET) != 0) { + /* seek error */ + ZIPERR(ZE_READ, "seek failed reading descriptor"); + } + if (bfwrite(b, 1, k, BFWRITE_DATA) != k) + { + free((zvoid *)b); + fprintf(mesg," fcopy: write error\n"); + return ZE_TEMP; + } + m += k; + continue; + } + else + { + /* apparently this is the correct data descriptor */ + + /* we should check the CRC but would need to inflate + the data */ + + /* skip descriptor as will write out later */ + des_good = 1; + k = 24; + data_start = zftello(in_file); + if (zfseeko(in_file, des_start + k, SEEK_SET) != 0) { + /* seek error */ + ZIPERR(ZE_READ, "seek failed reading descriptor"); + } + data_start = zftello(in_file); + } + } + + } + else +#endif + { + /* read standard data descriptor */ + + if (k < 16) { + /* not enough bytes, so can't be data descriptor + as data descriptors can't be split across splits + */ + } + else + { + /* read the descriptor */ + + des_crc = LG(b + 4); + des_csize = LG(b + 8); + des_usize = LG(b + 12); + + /* if this is the right data descriptor then the sizes should match */ + if ((uzoff_t)des_start - (uzoff_t)data_start != des_csize) { + /* apparently this signature does not go with this data so skip */ + + /* write out signature as data */ + k = 4; + if (zfseeko(in_file, des_start + k, SEEK_SET) != 0) { + /* seek error */ + ZIPERR(ZE_READ, "seek failed reading descriptor"); + } + if (bfwrite(b, 1, k, BFWRITE_DATA) != k) + { + free((zvoid *)b); + fprintf(mesg," fcopy: write error\n"); + return ZE_TEMP; + } + m += k; + continue; + } + else + { + /* apparently this is the correct data descriptor */ + + /* we should check the CRC but this does not work for + encrypted data */ + + /* skip descriptor as will write out later */ + des_good = 1; + data_start = zftello(in_file); + k = 16; + if (zfseeko(in_file, des_start + k, SEEK_SET) != 0) { + /* seek error */ + ZIPERR(ZE_READ, "seek failed reading descriptor"); + } + data_start = zftello(in_file); + } + } + + + } + } + } + + + if (des_good) { + /* skip descriptor as will write out later */ + } else { + /* write out apparently wrong descriptor as data */ + if (bfwrite(b, 1, k, BFWRITE_DATA) != k) + { + free((zvoid *)b); + fprintf(mesg," fcopy: write error\n"); + return ZE_TEMP; + } + m += k; + } + + if (copy_only && !display_globaldots) { + if (dot_size > 0) { + /* initial space */ + if (noisy && dot_count == -1) { +#ifndef WINDLL + putc(' ', mesg); + fflush(mesg); +#else + fprintf(stdout,"%c",' '); +#endif + dot_count++; + } + dot_count += k; + if (dot_size <= dot_count) dot_count = 0; + } + if ((verbose || noisy) && dot_size && !dot_count) { +#ifndef WINDLL + putc('.', mesg); + fflush(mesg); +#else + fprintf(stdout,"%c",'.'); +#endif + mesg_line_started = 1; + } + } + + if (des_good) + break; + + if (des) + continue; + + if ((des || n != (uzoff_t)(-1L)) && m < n && feof(in_file)) { + /* open next split */ + current_in_disk++; + + if (current_in_disk >= total_disks) { + /* done */ + break; + + } else if (current_in_disk == total_disks - 1) { + /* last disk is archive.zip */ + if ((split_path = malloc(strlen(in_path) + 1)) == NULL) { + zipwarn("reading archive: ", in_path); + return ZE_MEM; + } + strcpy(split_path, in_path); + } else { + /* other disks are archive.z01, archive.z02, ... */ + split_path = get_in_split_path(in_path, current_in_disk); + } + + fclose(in_file); + + /* open the split */ + while ((in_file = zfopen(split_path, FOPR)) == NULL) { + int r = 0; + + /* could not open split */ + + if (fix == 1 && skip_this_disk) { + free(split_path); + free((zvoid *)b); + return ZE_FORM; + } + + /* Ask for directory with split. Updates in_path */ + r = ask_for_split_read_path(current_in_disk); + if (r == ZE_ABORT) { + zipwarn("could not find split: ", split_path); + free(split_path); + free((zvoid *)b); + return ZE_ABORT; + } + if (r == ZE_EOF) { + zipmessage_nl("", 1); + zipwarn("user ended reading - closing archive", ""); + free(split_path); + free((zvoid *)b); + return ZE_EOF; + } + if (fix == 2 && skip_this_disk) { + /* user asked to skip this disk */ + zipwarn("skipping split file: ", split_path); + current_in_disk++; + } + + if (current_in_disk == total_disks - 1) { + /* last disk is archive.zip */ + if ((split_path = malloc(strlen(in_path) + 1)) == NULL) { + zipwarn("reading archive: ", in_path); + return ZE_MEM; + } + strcpy(split_path, in_path); + } else { + /* other disks are archive.z01, archive.z02, ... */ + split_path = get_in_split_path(zipfile, current_in_disk); + } + } + if (fix == 2 && skip_this_disk) { + /* user asked to skip this disk */ + free(split_path); + free((zvoid *)b); + return ZE_FORM; + } + free(split_path); + } + } + free((zvoid *)b); + return ZE_OK; +} + + + +#ifdef NO_RENAME +int rename(from, to) +ZCONST char *from; +ZCONST char *to; +{ + unlink(to); + if (link(from, to) == -1) + return -1; + if (unlink(from) == -1) + return -1; + return 0; +} + +#endif /* NO_RENAME */ + + +#ifdef ZMEM + +/************************/ +/* Function memset() */ +/************************/ + +/* + * memset - for systems without it + * bill davidsen - March 1990 + */ + +char * +memset(buf, init, len) +register char *buf; /* buffer loc */ +register int init; /* initializer */ +register unsigned int len; /* length of the buffer */ +{ + char *start; + + start = buf; + while (len--) *(buf++) = init; + return(start); +} + + +/************************/ +/* Function memcpy() */ +/************************/ + +char * +memcpy(dst,src,len) /* v2.0f */ +register char *dst, *src; +register unsigned int len; +{ + char *start; + + start = dst; + while (len--) + *dst++ = *src++; + return(start); +} + + +/************************/ +/* Function memcmp() */ +/************************/ + +int +memcmp(b1,b2,len) /* jpd@usl.edu -- 11/16/90 */ +register char *b1, *b2; +register unsigned int len; +{ + + if (len) do { /* examine each byte (if any) */ + if (*b1++ != *b2++) + return (*((uch *)b1-1) - *((uch *)b2-1)); /* exit when miscompare */ + } while (--len); + + return(0); /* no miscompares, yield 0 result */ +} + +#endif /* ZMEM */ + + +/*------------------------------------------------------------------ + * Split archives + */ + + +/* ask_for_split_read_path + * + * If the next split file is not in the current directory, ask + * the user where it is. + * + * in_path is the base path for reading splits and is usually + * the same as zipfile. The path in in_path must be the archive + * file ending in .zip as this is assumed by get_in_split_path(). + * + * Updates in_path if changed. Returns ZE_OK if OK or ZE_ABORT if + * user cancels reading archive. + * + * If fix = 1 then allow skipping disk (user may not have it). + */ + +#define SPLIT_MAXPATH (FNMAX + 4010) + +int ask_for_split_read_path(current_disk) + ulg current_disk; +{ + FILE *f; + int is_readable = 0; + int i; + char *split_dir = NULL; + char *archive_name = NULL; + char *split_name = NULL; + char *split_path = NULL; + char buf[SPLIT_MAXPATH + 100]; + + /* get split path */ + split_path = get_in_split_path(in_path, current_disk); + + /* get the directory */ + if ((split_dir = malloc(strlen(in_path) + 40)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + strcpy(split_dir, in_path); + + /* remove any name at end */ + for (i = strlen(split_dir) - 1; i >= 0; i--) { + if (split_dir[i] == '/' || split_dir[i] == '\\' + || split_dir[i] == ':') { + split_dir[i + 1] = '\0'; + break; + } + } + if (i < 0) + split_dir[0] = '\0'; + + /* get the name of the archive */ + if ((archive_name = malloc(strlen(in_path) + 1)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + if (strlen(in_path) == strlen(split_dir)) { + archive_name[0] = '\0'; + } else { + strcpy(archive_name, in_path + strlen(split_dir)); + } + + /* get the name of the split */ + if ((split_name = malloc(strlen(split_path) + 1)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + if (strlen(in_path) == strlen(split_dir)) { + split_name[0] = '\0'; + } else { + strcpy(split_name, split_path + strlen(split_dir)); + } + if (i < 0) { + strcpy(split_dir, "(current directory)"); + } + + fprintf(mesg, "\n\nCould not find:\n"); + fprintf(mesg, " %s\n", split_path); + /* + fprintf(mesg, "Please enter the path directory (. for cur dir) where\n"); + fprintf(mesg, " %s\n", split_name); + fprintf(mesg, "is located\n"); + */ + for (;;) { + if (is_readable) { + fprintf(mesg, "\nHit c (change path to where this split file is)"); + fprintf(mesg, "\n q (abort archive - quit)"); + fprintf(mesg, "\n or ENTER (continue with this split): "); + } else { + if (fix == 1) { + fprintf(mesg, "\nHit c (change path to where this split file is)"); + fprintf(mesg, "\n s (skip this split)"); + fprintf(mesg, "\n q (abort archive - quit)"); + fprintf(mesg, "\n or ENTER (try reading this split again): "); + } else if (fix == 2) { + fprintf(mesg, "\nHit c (change path to where this split file is)"); + fprintf(mesg, "\n s (skip this split)"); + fprintf(mesg, "\n q (abort archive - quit)"); + fprintf(mesg, "\n e (end this archive - no more splits)"); + fprintf(mesg, "\n z (look for .zip split - the last split)"); + fprintf(mesg, "\n or ENTER (try reading this split again): "); + } else { + fprintf(mesg, "\nHit c (change path to where this split file is)"); + fprintf(mesg, "\n q (abort archive - quit)"); + fprintf(mesg, "\n or ENTER (try reading this split again): "); + } + } + fflush(mesg); + fgets(buf, SPLIT_MAXPATH, stdin); + /* remove any newline */ + for (i = 0; buf[i]; i++) { + if (buf[i] == '\n') { + buf[i] = '\0'; + break; + } + } + if (toupper(buf[0]) == 'Q') { + return ZE_ABORT; + } else if ((fix == 1 || fix == 2) && toupper(buf[0]) == 'S') { + /* + fprintf(mesg, "\nSkip this split/disk? (files in this split will not be recovered) [n/y] "); + fflush(mesg); + fgets(buf, SPLIT_MAXPATH, stdin); + if (buf[0] == 'y' || buf[0] == 'Y') { + */ + skip_this_disk = current_in_disk + 1; + return ZE_FORM; + } else if (toupper(buf[0]) == 'C') { + fprintf(mesg, "\nEnter path where this split is (ENTER = same dir, . = current dir)"); + fprintf(mesg, "\n: "); + fflush(mesg); + fgets(buf, SPLIT_MAXPATH, stdin); + is_readable = 0; + /* remove any newline */ + for (i = 0; buf[i]; i++) { + if (buf[i] == '\n') { + buf[i] = '\0'; + break; + } + } + if (buf[0] == '\0') { + /* Hit ENTER so try old path again - could be removable media was changed */ + strcpy(buf, split_path); + } + } else if (fix == 2 && toupper(buf[0]) == 'E') { + /* no more splits to read */ + return ZE_EOF; + } else if (fix == 2 && toupper(buf[0]) == 'Z') { + total_disks = current_disk + 1; + free(split_path); + split_path = get_in_split_path(in_path, current_disk); + buf[0] = '\0'; + strncat(buf, split_path, SPLIT_MAXPATH); + } + if (strlen(buf) > 0) { + /* changing path */ + + /* check if user wants current directory */ + if (buf[0] == '.' && buf[1] == '\0') { + buf[0] = '\0'; + } + /* remove any name at end */ + for (i = strlen(buf); i >= 0; i--) { + if (buf[i] == '/' || buf[i] == '\\' + || buf[i] == ':') { + buf[i + 1] = '\0'; + break; + } + } + /* update base_path to newdir/split_name - in_path is the .zip file path */ + free(in_path); + if (i < 0) { + /* just name so current directory */ + strcpy(buf, "(current directory)"); + if (archive_name == NULL) { + i = 0; + } else { + i = strlen(archive_name); + } + if ((in_path = malloc(strlen(archive_name) + 40)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + strcpy(in_path, archive_name); + } else { + /* not the current directory */ + /* remove any name at end */ + for (i = strlen(buf); i >= 0; i--) { + if (buf[i] == '/') { + buf[i + 1] = '\0'; + break; + } + } + if (i < 0) { + buf[0] = '\0'; + } + if ((in_path = malloc(strlen(buf) + strlen(archive_name) + 40)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + strcpy(in_path, buf); + strcat(in_path, archive_name); + } + + free(split_path); + + /* get split path */ + split_path = get_in_split_path(in_path, current_disk); + + free(split_dir); + if ((split_dir = malloc(strlen(in_path) + 40)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + strcpy(split_dir, in_path); + /* remove any name at end */ + for (i = strlen(split_dir); i >= 0; i--) { + if (split_dir[i] == '/') { + split_dir[i + 1] = '\0'; + break; + } + } + + /* try to open it */ + if ((f = fopen(split_path, "r")) == NULL) { + fprintf(mesg, "\nCould not find or open\n"); + fprintf(mesg, " %s\n", split_path); + /* + fprintf(mesg, "Please enter the path (. for cur dir) where\n"); + fprintf(mesg, " %s\n", split_name); + fprintf(mesg, "is located\n"); + */ + continue; + } + fclose(f); + is_readable = 1; + fprintf(mesg, "Found: %s\n", split_path); + } else { + /* try to open it */ + if ((f = fopen(split_path, "r")) == NULL) { + fprintf(mesg, "\nCould not find or open\n"); + fprintf(mesg, " %s\n", split_path); + /* + fprintf(mesg, "Please enter the path (. for cur dir) where\n"); + fprintf(mesg, " %s\n", split_name); + fprintf(mesg, "is located\n"); + */ + continue; + } + fclose(f); + is_readable = 1; + fprintf(mesg, "\nFound: %s\n", split_path); + break; + } + } + free(archive_name); + free(split_dir); + free(split_name); + + return ZE_OK; +} + + +/* ask_for_split_write_path + * + * Verify the directory for the next split. Called + * when -sp is used to pause between writing splits. + * + * Updates out_path and return 1 if OK or 0 if cancel + */ +int ask_for_split_write_path(current_disk) + ulg current_disk; +{ + unsigned int num = (unsigned int)current_disk + 1; + int i; + char *split_dir = NULL; + char *split_name = NULL; + char buf[FNMAX + 40]; + + /* get the directory */ + if ((split_dir = malloc(strlen(out_path) + 40)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + strcpy(split_dir, out_path); + + /* remove any name at end */ + for (i = strlen(split_dir); i >= 0; i--) { + if (split_dir[i] == '/' || split_dir[i] == '\\' + || split_dir[i] == ':') { + split_dir[i + 1] = '\0'; + break; + } + } + + /* get the name of the split */ + if ((split_name = malloc(strlen(out_path) + 1)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + if (strlen(out_path) == strlen(split_dir)) { + split_name[0] = '\0'; + } else { + strcpy(split_name, out_path + strlen(split_dir)); + } + if (i < 0) { + strcpy(split_dir, "(current directory)"); + } + if (mesg_line_started) + fprintf(mesg, "\n"); + fprintf(mesg, "\nOpening disk %d\n", num); + fprintf(mesg, "Hit ENTER to write to default path of\n"); + fprintf(mesg, " %s\n", split_dir); + fprintf(mesg, "or enter a new directory path (. for cur dir) and hit ENTER\n"); + for (;;) { + fprintf(mesg, "\nPath (or hit ENTER to continue): "); + fflush(mesg); + fgets(buf, FNMAX, stdin); + /* remove any newline */ + for (i = 0; buf[i]; i++) { + if (buf[i] == '\n') { + buf[i] = '\0'; + break; + } + } + if (strlen(buf) > 0) { + /* changing path */ + + /* current directory */ + if (buf[0] == '.' && buf[1] == '\0') { + buf[0] = '\0'; + } + /* remove any name at end */ + for (i = strlen(buf); i >= 0; i--) { + if (buf[i] == '/' || buf[i] == '\\' + || buf[i] == ':') { + buf[i + 1] = '\0'; + break; + } + } + /* update out_path to newdir/split_name */ + free(out_path); + if (i < 0) { + /* just name so current directory */ + strcpy(buf, "(current directory)"); + if (split_name == NULL) { + i = 0; + } else { + i = strlen(split_name); + } + if ((out_path = malloc(strlen(split_name) + 40)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + strcpy(out_path, split_name); + } else { + /* not the current directory */ + /* remove any name at end */ + for (i = strlen(buf); i >= 0; i--) { + if (buf[i] == '/') { + buf[i + 1] = '\0'; + break; + } + } + if (i < 0) { + buf[0] = '\0'; + } + if ((out_path = malloc(strlen(buf) + strlen(split_name) + 40)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + strcpy(out_path, buf); + strcat(out_path, split_name); + } + fprintf(mesg, "Writing to:\n %s\n", buf); + free(split_name); + free(split_dir); + if ((split_dir = malloc(strlen(out_path) + 40)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + strcpy(split_dir, out_path); + /* remove any name at end */ + for (i = strlen(split_dir); i >= 0; i--) { + if (split_dir[i] == '/') { + split_dir[i + 1] = '\0'; + break; + } + } + if ((split_name = malloc(strlen(out_path) + 1)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + strcpy(split_name, out_path + strlen(split_dir)); + } else { + break; + } + } + free(split_dir); + free(split_name); + + /* for now no way out except Ctrl C */ + return 1; +} + + +/* split_name + * + * get name of split being read + */ +char *get_in_split_path(base_path, disk_number) + char *base_path; + ulg disk_number; +{ + char *split_path = NULL; + int base_len = 0; + int path_len = 0; + ulg num = disk_number + 1; + char ext[6]; +#ifdef VMS + int vers_len; /* File version length. */ + char *vers_ptr; /* File version string. */ +#endif /* def VMS */ + + /* + * A split has extension z01, z02, ..., z99, z100, z101, ... z999 + * We currently support up to .z99999 + * WinZip will also read .100, .101, ... but AppNote 6.2.2 uses above + * so use that. Means on DOS can only have 100 splits. + */ + + if (num == total_disks) { + /* last disk is base path */ + if ((split_path = malloc(strlen(base_path) + 1)) == NULL) { + ZIPERR(ZE_MEM, "base path"); + } + strcpy(split_path, base_path); + + return split_path; + } else { + if (num > 99999) { + ZIPERR(ZE_BIG, "More than 99999 splits needed"); + } + sprintf(ext, "z%02lu", num); + } + + /* create path for this split - zip.c checked for .zip extension */ + base_len = strlen(base_path) - 3; + path_len = base_len + strlen(ext); + +#ifdef VMS + /* On VMS, locate the file version, and adjust base_len accordingly. + Note that path_len is correct, as-is. + */ + vers_ptr = vms_file_version( base_path); + vers_len = strlen( vers_ptr); + base_len -= vers_len; +#endif /* def VMS */ + + if ((split_path = malloc(path_len + 1)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + /* copy base_path except for end zip */ + strcpy(split_path, base_path); + split_path[base_len] = '\0'; + /* add extension */ + strcat(split_path, ext); + +#ifdef VMS + /* On VMS, append (preserve) the file version. */ + strcat(split_path, vers_ptr); +#endif /* def VMS */ + + return split_path; +} + + +/* split_name + * + * get name of split being written + */ +char *get_out_split_path(base_path, disk_number) + char *base_path; + ulg disk_number; +{ + char *split_path = NULL; + int base_len = 0; + int path_len = 0; + ulg num = disk_number + 1; + char ext[6]; +#ifdef VMS + int vers_len; /* File version length. */ + char *vers_ptr; /* File version string. */ +#endif /* def VMS */ + + /* + * A split has extension z01, z02, ..., z99, z100, z101, ... z999 + * We currently support up to .z99999 + * WinZip will also read .100, .101, ... but AppNote 6.2.2 uses above + * so use that. Means on DOS can only have 100 splits. + */ + + if (num > 99999) { + ZIPERR(ZE_BIG, "More than 99999 splits needed"); + } + sprintf(ext, "z%02lu", num); + + /* create path for this split - zip.c checked for .zip extension */ + base_len = strlen(base_path) - 3; + path_len = base_len + strlen(ext); + +#ifdef VMS + /* On VMS, locate the file version, and adjust base_len accordingly. + Note that path_len is correct, as-is. + */ + vers_ptr = vms_file_version( base_path); + vers_len = strlen( vers_ptr); + base_len -= vers_len; +#endif /* def VMS */ + + if ((split_path = malloc(path_len + 1)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + /* copy base_path except for end zip */ + strcpy(split_path, base_path); + split_path[base_len] = '\0'; + /* add extension */ + strcat(split_path, ext); + +#ifdef VMS + /* On VMS, append (preserve) the file version. */ + strcat(split_path, vers_ptr); +#endif /* def VMS */ + + return split_path; +} + +/* close_split + * + * close a split - assume that the paths needed for the splits are + * available. + */ +int close_split(disk_number, tempfile, temp_name) + ulg disk_number; + FILE *tempfile; + char *temp_name; +{ + char *split_path = NULL; + + split_path = get_out_split_path(out_path, disk_number); + + if (noisy_splits) { + zipmessage("\tClosing split ", split_path); + } + + fclose(tempfile); + + rename_split(temp_name, split_path); + set_filetype(split_path); + + return ZE_OK; +} + +/* bfwrite + Does the fwrite but also counts bytes and does splits */ +size_t bfwrite(buffer, size, count, mode) + ZCONST void *buffer; + size_t size; + size_t count; + int mode; +{ + size_t bytes_written = 0; + size_t r; + size_t b = size * count; + uzoff_t bytes_left_in_split = 0; + size_t bytes_to_write = b; + + + /* -------------------------------- */ + /* local header */ + if (mode == BFWRITE_LOCALHEADER) { + /* writing local header - reset entry data count */ + bytes_this_entry = 0; + /* save start of local header so we can rewrite later */ + current_local_file = y; + current_local_disk = current_disk; + current_local_offset = bytes_this_split; + } + + if (split_size == 0) + bytes_left_in_split = bytes_to_write; + else + bytes_left_in_split = split_size - bytes_this_split; + + if (bytes_to_write > bytes_left_in_split) { + if (mode == BFWRITE_HEADER || + mode == BFWRITE_LOCALHEADER || + mode == BFWRITE_CENTRALHEADER) { + /* if can't write entire header save for next split */ + bytes_to_write = 0; + } else { + /* normal data so fill the split */ + bytes_to_write = (size_t)bytes_left_in_split; + } + } + + /* -------------------------------- */ + /* central header */ + if (mode == BFWRITE_CENTRALHEADER) { + /* set start disk for CD */ + if (cd_start_disk == (ulg)-1) { + cd_start_disk = current_disk; + cd_start_offset = bytes_this_split; + } + cd_entries_this_disk++; + total_cd_entries++; + } + + /* -------------------------------- */ + if (bytes_to_write > 0) { + /* write out the bytes for this split */ + r = fwrite(buffer, size, bytes_to_write, y); + bytes_written += r; + bytes_to_write = b - r; + bytes_this_split += r; + if (mode == BFWRITE_DATA) + /* if data descriptor do not include in count */ + bytes_this_entry += r; + } else { + bytes_to_write = b; + } + + if (bytes_to_write > 0) { + if (split_method) { + /* still bytes to write so close split and open next split */ + bytes_prev_splits += bytes_this_split; + + if (split_method == 1 && ferror(y)) { + /* if writing all splits to same place and have problem then bad */ + ZIPERR(ZE_WRITE, "Could not write split"); + } + + if (split_method == 2 && ferror(y)) { + /* A split must be at least 64K except last .zip split */ + if (bytes_this_split < 64 * (uzoff_t)0x400) { + ZIPERR(ZE_WRITE, "Not enough space to write split"); + } + } + + /* close this split */ + if (split_method == 1 && current_local_disk == current_disk) { + /* keep split open so can update it */ + current_local_tempname = tempzip; + } else { + /* close split */ + close_split(current_disk, y, tempzip); + y = NULL; + free(tempzip); + tempzip = NULL; + } + cd_entries_this_disk = 0; + bytes_this_split = 0; + + /* increment disk - disks are numbered 0, 1, 2, ... and + splits are 01, 02, ... */ + current_disk++; + + if (split_method == 2 && split_bell) { + /* bell when pause to ask for next split */ + putc('\007', mesg); + fflush(mesg); + } + + for (;;) { + /* if method 2 pause and allow changing path */ + if (split_method == 2) { + if (ask_for_split_write_path(current_disk) == 0) { + ZIPERR(ZE_ABORT, "could not write split"); + } + } + + /* open next split */ +#if defined(UNIX) && !defined(NO_MKSTEMP) + { + int yd; + int i; + + /* use mkstemp to avoid race condition and compiler warning */ + + if (tempath != NULL) + { + /* if -b used to set temp file dir use that for split temp */ + if ((tempzip = malloc(strlen(tempath) + 12)) == NULL) { + ZIPERR(ZE_MEM, "allocating temp filename"); + } + strcpy(tempzip, tempath); + if (lastchar(tempzip) != '/') + strcat(tempzip, "/"); + } + else + { + /* create path by stripping name and appending template */ + if ((tempzip = malloc(strlen(zipfile) + 12)) == NULL) { + ZIPERR(ZE_MEM, "allocating temp filename"); + } + strcpy(tempzip, zipfile); + for(i = strlen(tempzip); i > 0; i--) { + if (tempzip[i - 1] == '/') + break; + } + tempzip[i] = '\0'; + } + strcat(tempzip, "ziXXXXXX"); + + if ((yd = mkstemp(tempzip)) == EOF) { + ZIPERR(ZE_TEMP, tempzip); + } + if ((y = fdopen(yd, FOPW_TMP)) == NULL) { + ZIPERR(ZE_TEMP, tempzip); + } + } +#else + if ((tempzip = tempname(zipfile)) == NULL) { + ZIPERR(ZE_MEM, "allocating temp filename"); + } + if ((y = zfopen(tempzip, FOPW_TMP)) == NULL) { + ZIPERR(ZE_TEMP, tempzip); + } +#endif + + r = fwrite((char *)buffer + bytes_written, 1, bytes_to_write, y); + bytes_written += r; + bytes_this_split += r; + if (!(mode == BFWRITE_HEADER || + mode == BFWRITE_LOCALHEADER || + mode == BFWRITE_CENTRALHEADER)) { + bytes_this_entry += r; + } + if (bytes_to_write > r) { + /* buffer bigger than split */ + if (split_method == 2) { + /* let user choose another disk */ + zipwarn("Not enough room on disk", ""); + continue; + } else { + ZIPERR(ZE_WRITE, "Not enough room on disk"); + } + } + if (mode == BFWRITE_LOCALHEADER || + mode == BFWRITE_HEADER || + mode == BFWRITE_CENTRALHEADER) { + if (split_method == 1 && current_local_file && + current_local_disk != current_disk) { + /* We're opening a new split because the next header + did not fit on the last split. We need to now close + the last split and update the pointers for + the current split. */ + close_split(current_local_disk, current_local_file, + current_local_tempname); + free(current_local_tempname); + } + current_local_tempname = tempzip; + current_local_file = y; + current_local_offset = 0; + current_local_disk = current_disk; + } + break; + } + } + else + { + /* likely have more than fits but no splits */ + + /* probably already have error "no space left on device" */ + /* could let flush_outbuf() handle error but bfwrite() is called for + headers also */ + if (ferror(y)) + ziperr(ZE_WRITE, "write error on zip file"); + } + } + + + /* display dots for archive instead of for each file */ + if (display_globaldots) { + if (dot_size > 0) { + /* initial space */ + if (dot_count == -1) { +#ifndef WINDLL + putc(' ', mesg); + fflush(mesg); +#else + fprintf(stdout,"%c",' '); +#endif + /* assume a header will be written first, so avoid 0 */ + dot_count = 1; + } + /* skip incrementing dot count for small buffers like for headers */ + if (size * count > 1000) { + dot_count++; + if (dot_size <= dot_count * (zoff_t)size * (zoff_t)count) dot_count = 0; + } + } + if (dot_size && !dot_count) { + dot_count++; +#ifndef WINDLL + putc('.', mesg); + fflush(mesg); +#else + fprintf(stdout,"%c",'.'); +#endif + mesg_line_started = 1; + } + } + + + return bytes_written; +} + + +#ifdef UNICODE_SUPPORT + +/*--------------------------------------------- + * Unicode conversion functions + * + * Provided by Paul Kienitz + * + * Some modifications to work with Zip + * + *--------------------------------------------- + */ + +/* + NOTES APPLICABLE TO ALL STRING FUNCTIONS: + + All of the x_to_y functions take parameters for an output buffer and + its available length, and return an int. The value returned is the + length of the string that the input produces, which may be larger than + the provided buffer length. If the returned value is less than the + buffer length, then the contents of the buffer will be null-terminated; + otherwise, it will not be terminated and may be invalid, possibly + stopping in the middle of a multibyte sequence. + + In all cases you may pass NULL as the buffer and/or 0 as the length, if + you just want to learn how much space the string is going to require. + + The functions will return -1 if the input is invalid UTF-8 or cannot be + encoded as UTF-8. +*/ + +/* utility functions for managing UTF-8 and UCS-4 strings */ + + +/* utf8_char_bytes + * + * Returns the number of bytes used by the first character in a UTF-8 + * string, or -1 if the UTF-8 is invalid or null. + */ +local int utf8_char_bytes(utf8) + ZCONST char *utf8; +{ + int t, r; + unsigned lead; + + if (!utf8) + return -1; /* no input */ + lead = (unsigned char) *utf8; + if (lead < 0x80) + r = 1; /* an ascii-7 character */ + else if (lead < 0xC0) + return -1; /* error: trailing byte without lead byte */ + else if (lead < 0xE0) + r = 2; /* an 11 bit character */ + else if (lead < 0xF0) + r = 3; /* a 16 bit character */ + else if (lead < 0xF8) + r = 4; /* a 21 bit character (the most currently used) */ + else if (lead < 0xFC) + r = 5; /* a 26 bit character (shouldn't happen) */ + else if (lead < 0xFE) + r = 6; /* a 31 bit character (shouldn't happen) */ + else + return -1; /* error: invalid lead byte */ + for (t = 1; t < r; t++) + if ((unsigned char) utf8[t] < 0x80 || (unsigned char) utf8[t] >= 0xC0) + return -1; /* error: not enough valid trailing bytes */ + return r; +} + + +/* ucs4_char_from_utf8 + * + * Given a reference to a pointer into a UTF-8 string, returns the next + * UCS-4 character and advances the pointer to the next character sequence. + * Returns ~0 and does not advance the pointer when input is ill-formed. + * + * Since the Unicode standard says 32-bit values won't be used (just + * up to the current 21-bit mappings) changed this to signed to allow -1 to + * be returned. + */ +long ucs4_char_from_utf8(utf8) + ZCONST char **utf8; +{ + ulg ret; + int t, bytes; + + if (!utf8) + return -1; /* no input */ + bytes = utf8_char_bytes(*utf8); + if (bytes <= 0) + return -1; /* invalid input */ + if (bytes == 1) + ret = **utf8; /* ascii-7 */ + else + ret = **utf8 & (0x7F >> bytes); /* lead byte of a multibyte sequence */ + (*utf8)++; + for (t = 1; t < bytes; t++) /* consume trailing bytes */ + ret = (ret << 6) | (*((*utf8)++) & 0x3F); + return (long) ret; +} + + +/* utf8_from_ucs4_char - Convert UCS char to UTF-8 + * + * Returns the number of bytes put into utf8buf to represent ch, from 1 to 6, + * or -1 if ch is too large to represent. utf8buf must have room for 6 bytes. + */ +local int utf8_from_ucs4_char(utf8buf, ch) + char *utf8buf; + ulg ch; +{ + int trailing = 0; + int leadmask = 0x80; + int leadbits = 0x3F; + ulg tch = ch; + int ret; + + if (ch > 0x7FFFFFFF) + return -1; /* UTF-8 can represent 31 bits */ + if (ch < 0x7F) + { + *utf8buf++ = (char) ch; /* ascii-7 */ + return 1; + } + do { + trailing++; + leadmask = (leadmask >> 1) | 0x80; + leadbits >>= 1; + tch >>= 6; + } while (tch & ~leadbits); + ret = trailing + 1; + /* produce lead byte */ + *utf8buf++ = (char) (leadmask | (ch >> (6 * trailing))); + /* produce trailing bytes */ + while (--trailing >= 0) + *utf8buf++ = (char) (0x80 | ((ch >> (6 * trailing)) & 0x3F)); + return ret; +} + + +/*===================================================================*/ + +/* utf8_to_ucs4_string - convert UTF-8 string to UCS string + * + * Return UCS count. Now returns int so can return -1. + */ +local int utf8_to_ucs4_string(utf8, ucs4buf, buflen) + ZCONST char *utf8; + ulg *ucs4buf; + int buflen; +{ + int count = 0; + + for (;;) + { + long ch = ucs4_char_from_utf8(&utf8); + if (ch == -1) + return -1; + else + { + if (ucs4buf && count < buflen) + ucs4buf[count] = ch; + if (ch == 0) + return count; + count++; + } + } +} + + +/* ucs4_string_to_utf8 + * + * + */ +local int ucs4_string_to_utf8(ucs4, utf8buf, buflen) + ZCONST ulg *ucs4; + char *utf8buf; + int buflen; +{ + char mb[6]; + int count = 0; + + if (!ucs4) + return -1; + for (;;) + { + int mbl = utf8_from_ucs4_char(mb, *ucs4++); + int c; + if (mbl <= 0) + return -1; + /* We could optimize this a bit by passing utf8buf + count */ + /* directly to utf8_from_ucs4_char when buflen >= count + 6... */ + c = buflen - count; + if (mbl < c) + c = mbl; + if (utf8buf && count < buflen) + strncpy(utf8buf + count, mb, c); + if (mbl == 1 && !mb[0]) + return count; /* terminating nul */ + count += mbl; + } +} + + +#if 0 /* currently unused */ +/* utf8_chars + * + * Wrapper: counts the actual unicode characters in a UTF-8 string. + */ +local int utf8_chars(utf8) + ZCONST char *utf8; +{ + return utf8_to_ucs4_string(utf8, NULL, 0); +} +#endif + + +/* --------------------------------------------------- */ +/* Unicode Support + * + * These functions common for all Unicode ports. + * + * These functions should allocate and return strings that can be + * freed with free(). + * + * 8/27/05 EG + * + * Use zwchar for wide char which is unsigned long + * in zip.h and 32 bits. This avoids problems with + * different sizes of wchar_t. + */ + +#ifdef WIN32 + +zwchar *wchar_to_wide_string(wchar_string) + wchar_t *wchar_string; +{ + int i; + int wchar_len; + zwchar *wide_string; + + wchar_len = wcslen(wchar_string); + + if ((wide_string = malloc((wchar_len + 1) * sizeof(zwchar))) == NULL) { + ZIPERR(ZE_MEM, "wchar to wide conversion"); + } + for (i = 0; i <= wchar_len; i++) { + wide_string[i] = wchar_string[i]; + } + + return wide_string; +} + +/* is_ascii_stringw + * Checks if a wide string is all ascii + */ +int is_ascii_stringw(wstring) + wchar_t *wstring; +{ + wchar_t *pw; + wchar_t cw; + + if (wstring == NULL) + return 0; + + for (pw = wstring; (cw = *pw) != '\0'; pw++) { + if (cw > 0x7F) { + return 0; + } + } + return 1; +} + +#endif + +/* is_ascii_string + * Checks if a string is all ascii + */ +int is_ascii_string(mbstring) + char *mbstring; +{ + char *p; + uch c; + + if (mbstring == NULL) + return 0; + + for (p = mbstring; (c = (uch)*p) != '\0'; p++) { + if (c > 0x7F) { + return 0; + } + } + return 1; +} + +/* local to UTF-8 */ +char *local_to_utf8_string(local_string) + char *local_string; +{ + zwchar *wide_string = local_to_wide_string(local_string); + char *utf8_string = wide_to_utf8_string(wide_string); + + free(wide_string); + return utf8_string; +} + +/* wide_char_to_escape_string + provides a string that represents a wide char not in local char set + + An initial try at an algorithm. Suggestions welcome. + + If not an ASCII char, probably need 2 bytes at least. So if + a 2-byte wide encode it as 4 hex digits with a leading #U. + Since the Unicode standard has been frozen, it looks like 3 bytes + should be enough for any large Unicode character. In these cases + prefix the string with #L. + So + #U1234 + is a 2-byte wide character with bytes 0x12 and 0x34 while + #L123456 + is a 3-byte wide with bytes 0x12, 0x34, and 0x56. + On Windows, wide that need two wide characters as a surrogate pair + to represent them need to be converted to a single number. + */ + + /* set this to the max bytes an escape can be */ +#define MAX_ESCAPE_BYTES 8 + +char *wide_char_to_escape_string(wide_char) + zwchar wide_char; +{ + int i; + zwchar w = wide_char; + uch b[9]; + char e[7]; + int len; + char *r; + + /* fill byte array with zeros */ + for (len = 0; len < sizeof(zwchar); len++) { + b[len] = 0; + } + /* get bytes in right to left order */ + for (len = 0; w; len++) { + b[len] = (char)(w % 0x100); + w /= 0x100; + } + + if ((r = malloc(MAX_ESCAPE_BYTES + 8)) == NULL) { + ZIPERR(ZE_MEM, "wide_char_to_escape_string"); + } + strcpy(r, "#"); + /* either 2 bytes or 4 bytes */ + if (len < 3) { + len = 2; + strcat(r, "U"); + } else { + len = 3; + strcat(r, "L"); + } + for (i = len - 1; i >= 0; i--) { + sprintf(e, "%02x", b[i]); + strcat(r, e); + } + return r; +} + +#if 0 +/* returns the wide character represented by the escape string */ +zwchar escape_string_to_wide(escape_string) + char *escape_string; +{ + int i; + zwchar w; + char c; + char u; + int len; + char *e = escape_string; + + if (e == NULL) { + return 0; + } + if (e[0] != '#') { + /* no leading # */ + return 0; + } + len = strlen(e); + /* either #U1234 or #L123456 format */ + if (len != 6 && len != 8) { + return 0; + } + w = 0; + if (e[1] == 'L') { + if (len != 8) { + return 0; + } + /* 3 bytes */ + for (i = 2; i < 8; i++) { + c = e[i]; + u = toupper(c); + if (u >= 'A' && u <= 'F') { + w = w * 0x10 + (zwchar)(u + 10 - 'A'); + } else if (c >= '0' && c <= '9') { + w = w * 0x10 + (zwchar)(c - '0'); + } else { + return 0; + } + } + } else if (e[1] == 'U') { + /* 2 bytes */ + for (i = 2; i < 6; i++) { + c = e[i]; + u = toupper(c); + if (u >= 'A' && u <= 'F') { + w = w * 0x10 + (zwchar)(u + 10 - 'A'); + } else if (c >= '0' && c <= '9') { + w = w * 0x10 + (zwchar)(c - '0'); + } else { + return 0; + } + } + } + return w; +} +#endif + + +char *local_to_escape_string(local_string) + char *local_string; +{ + zwchar *wide_string = local_to_wide_string(local_string); + char *escape_string = wide_to_escape_string(wide_string); + + free(wide_string); + return escape_string; +} + +#ifdef WIN32 +char *wchar_to_local_string(wstring) + wchar_t *wstring; +{ + zwchar *wide_string = wchar_to_wide_string(wstring); + char *local_string = wide_to_local_string(wide_string); + + free(wide_string); + + return local_string; +} +#endif + + +#ifndef WIN32 /* The Win32 port uses a system-specific variant. */ +/* convert wide character string to multi-byte character string */ +char *wide_to_local_string(wide_string) + zwchar *wide_string; +{ + int i; + wchar_t wc; + int b; + int state_dependent; + int wsize = 0; + int max_bytes = MB_CUR_MAX; + char buf[9]; + char *buffer = NULL; + char *local_string = NULL; + + for (wsize = 0; wide_string[wsize]; wsize++) ; + + if (MAX_ESCAPE_BYTES > max_bytes) + max_bytes = MAX_ESCAPE_BYTES; + + if ((buffer = (char *)malloc(wsize * max_bytes + 1)) == NULL) { + ZIPERR(ZE_MEM, "wide_to_local_string"); + } + + /* convert it */ + buffer[0] = '\0'; + /* set initial state if state-dependent encoding */ + wc = (wchar_t)'a'; + b = wctomb(NULL, wc); + if (b == 0) + state_dependent = 0; + else + state_dependent = 1; + for (i = 0; i < wsize; i++) { + if (sizeof(wchar_t) < 4 && wide_string[i] > 0xFFFF) { + /* wchar_t probably 2 bytes */ + /* could do surrogates if state_dependent and wctomb can do */ + wc = zwchar_to_wchar_t_default_char; + } else { + wc = (wchar_t)wide_string[i]; + } + b = wctomb(buf, wc); + if (unicode_escape_all) { + if (b == 1 && (uch)buf[0] <= 0x7f) { + /* ASCII */ + strncat(buffer, buf, b); + } else { + /* use escape for wide character */ + char *e = wide_char_to_escape_string(wide_string[i]); + strcat(buffer, e); + free(e); + } + } else if (b > 0) { + /* multi-byte char */ + strncat(buffer, buf, b); + } else { + /* no MB for this wide */ + if (use_wide_to_mb_default) { + /* default character */ + strcat(buffer, wide_to_mb_default_string); + } else { + /* use escape for wide character */ + char *e = wide_char_to_escape_string(wide_string[i]); + strcat(buffer, e); + free(e); + } + } + } + if ((local_string = (char *)malloc(strlen(buffer) + 1)) == NULL) { + free(buffer); + ZIPERR(ZE_MEM, "wide_to_local_string"); + } + strcpy(local_string, buffer); + free(buffer); + + return local_string; +} +#endif /* !WIN32 */ + + +/* convert wide character string to escaped string */ +char *wide_to_escape_string(wide_string) + zwchar *wide_string; +{ + int i; + int wsize = 0; + char buf[9]; + char *buffer = NULL; + char *escape_string = NULL; + + for (wsize = 0; wide_string[wsize]; wsize++) ; + + if ((buffer = (char *)malloc(wsize * MAX_ESCAPE_BYTES + 1)) == NULL) { + ZIPERR(ZE_MEM, "wide_to_escape_string"); + } + + /* convert it */ + buffer[0] = '\0'; + for (i = 0; i < wsize; i++) { + if (wide_string[i] <= 0x7f && isprint((char)wide_string[i])) { + /* ASCII */ + buf[0] = (char)wide_string[i]; + buf[1] = '\0'; + strcat(buffer, buf); + } else { + /* use escape for wide character */ + char *e = wide_char_to_escape_string(wide_string[i]); + strcat(buffer, e); + free(e); + } + } + if ((escape_string = (char *)malloc(strlen(buffer) + 1)) == NULL) { + ZIPERR(ZE_MEM, "wide_to_escape_string"); + } + strcpy(escape_string, buffer); + free(buffer); + + return escape_string; +} + + +/* convert local string to display character set string */ +char *local_to_display_string(local_string) + char *local_string; +{ + char *temp_string; + char *display_string; + + /* For Windows, OEM string should never be bigger than ANSI string, says + CharToOem description. + On UNIX, non-printable characters (0x00 - 0xFF) will be replaced by + "^x", so more space may be needed. Note that "^" itself is a valid + name character, so this leaves an ambiguity, but UnZip displays + names this way, too. (0x00 is not possible, I hope.) + For all other ports, just make a copy of local_string. + */ + +#ifdef UNIX + char *cp_dst; /* Character pointers used in the */ + char *cp_src; /* copying/changing procedure. */ +#endif + + if ((temp_string = (char *)malloc(2 * strlen(local_string) + 1)) == NULL) { + ZIPERR(ZE_MEM, "local_to_display_string"); + } + +#ifdef WIN32 + /* convert to OEM display character set */ + local_to_oem_string(temp_string, local_string); +#else +# ifdef UNIX + /* Copy source string, expanding non-printable characters to "^x". */ + cp_dst = temp_string; + cp_src = local_string; + while (*cp_src != '\0') { + if ((unsigned char)*cp_src < ' ') { + *cp_dst++ = '^'; + *cp_dst++ = '@'+ *cp_src++; + } + else { + *cp_dst++ = *cp_src++; + } + } + *cp_dst = '\0'; +# else /* not UNIX */ + strcpy(temp_string, local_string); +# endif /* UNIX */ +#endif + +#ifdef EBCDIC + { + char *ebc; + + if ((ebc = malloc(strlen(display_string) + 1)) == NULL) { + ZIPERR(ZE_MEM, "local_to_display_string"); + } + strtoebc(ebc, display_string); + free(display_string); + display_string = ebc; + } +#endif + + if ((display_string = (char *)malloc(strlen(temp_string) + 1)) == NULL) { + ZIPERR(ZE_MEM, "local_to_display_string"); + } + strcpy(display_string, temp_string); + free(temp_string); + + return display_string; +} + +/* UTF-8 to local */ +char *utf8_to_local_string(utf8_string) + char *utf8_string; +{ + zwchar *wide_string = utf8_to_wide_string(utf8_string); + char *loc = wide_to_local_string(wide_string); + if (wide_string) + free(wide_string); + return loc; +} + +/* UTF-8 to local */ +char *utf8_to_escape_string(utf8_string) + char *utf8_string; +{ + zwchar *wide_string = utf8_to_wide_string(utf8_string); + char *escape_string = wide_to_escape_string(wide_string); + free(wide_string); + return escape_string; +} + +#ifndef WIN32 /* The Win32 port uses a system-specific variant. */ +/* convert multi-byte character string to wide character string */ +zwchar *local_to_wide_string(local_string) + char *local_string; +{ + int wsize; + wchar_t *wc_string; + zwchar *wide_string; + + /* for now try to convert as string - fails if a bad char in string */ + wsize = mbstowcs(NULL, local_string, MB_CUR_MAX ); + if (wsize == (size_t)-1) { + /* could not convert */ + return NULL; + } + + /* convert it */ + if ((wc_string = (wchar_t *)malloc((wsize + 1) * sizeof(wchar_t))) == NULL) { + ZIPERR(ZE_MEM, "local_to_wide_string"); + } + wsize = mbstowcs(wc_string, local_string, strlen(local_string) + 1); + wc_string[wsize] = (wchar_t) 0; + + /* in case wchar_t is not zwchar */ + if ((wide_string = (zwchar *)malloc((wsize + 1) * sizeof(zwchar))) == NULL) { + ZIPERR(ZE_MEM, "local_to_wide_string"); + } + for (wsize = 0; (wide_string[wsize] = (zwchar)wc_string[wsize]); wsize++) ; + wide_string[wsize] = (zwchar)0; + free(wc_string); + + return wide_string; +} +#endif /* !WIN32 */ + + +#if 0 +/* All wchar functions are only used by Windows and are + now in win32zip.c so that the Windows functions can + be used and multiple character wide characters can + be handled easily. */ +# ifndef WIN32 +char *wchar_to_utf8_string(wstring) + wchar_t *wstring; +{ + zwchar *wide_string = wchar_to_wide_string(wstring); + char *local_string = wide_to_utf8_string(wide_string); + + free(wide_string); + + return local_string; +} +# endif +#endif + + +/* convert wide string to UTF-8 */ +char *wide_to_utf8_string(wide_string) + zwchar *wide_string; +{ + int mbcount; + char *utf8_string; + + /* get size of utf8 string */ + mbcount = ucs4_string_to_utf8(wide_string, NULL, 0); + if (mbcount == -1) + return NULL; + if ((utf8_string = (char *) malloc(mbcount + 1)) == NULL) { + ZIPERR(ZE_MEM, "wide_to_utf8_string"); + } + mbcount = ucs4_string_to_utf8(wide_string, utf8_string, mbcount + 1); + if (mbcount == -1) + return NULL; + + return utf8_string; +} + +/* convert UTF-8 string to wide string */ +zwchar *utf8_to_wide_string(utf8_string) + char *utf8_string; +{ + int wcount; + zwchar *wide_string; + + wcount = utf8_to_ucs4_string(utf8_string, NULL, 0); + if (wcount == -1) + return NULL; + if ((wide_string = (zwchar *) malloc((wcount + 2) * sizeof(zwchar))) == NULL) { + ZIPERR(ZE_MEM, "utf8_to_wide_string"); + } + wcount = utf8_to_ucs4_string(utf8_string, wide_string, wcount + 1); + + return wide_string; +} + + +#endif /* UNICODE_SUPPORT */ + + +/*--------------------------------------------------------------- + * Long option support + * 8/23/2003 + * + * Defines function get_option() to get and process the command + * line options and arguments from argv[]. The caller calls + * get_option() in a loop to get either one option and possible + * value or a non-option argument each loop. + * + * This version does not include argument file support and can + * work directly on argv. The argument file code complicates things and + * it seemed best to leave it out for now. If argument file support (reading + * in command line arguments stored in a file and inserting into + * command line where @filename is found) is added later the arguments + * can change and a freeable copy of argv will be needed and can be + * created using copy_args in the left out code. + * + * Supports short and long options as defined in the array options[] + * in zip.c, multiple short options in an argument (like -jlv), long + * option abbreviation (like --te for --temp-file if --te unique), + * short and long option values (like -b filename or --temp-file filename + * or --temp-file=filename), optional and required values, option negation + * by trailing - (like -S- to not include hidden and system files in MSDOS), + * value lists (like -x a b c), argument permuting (returning all options + * and values before any non-option arguments), and argument files (where any + * non-option non-value argument in form @path gets substituted with the + * white space separated arguments in the text file at path). In this + * version argument file support has been removed to simplify development but + * may be added later. + * + * E. Gordon + */ + + +/* message output - char casts are needed to handle constants */ +#define oWARN(message) zipwarn((char *) message, "") +#define oERR(err,message) ZIPERR(err, (char *) message) + + +/* Although the below provides some support for multibyte characters + the proper thing to do may be to use wide characters and support + Unicode. May get to it soon. EG + */ + +/* For now stay with muti-byte characters. May support wide characters + in Zip 3.1. + */ + +/* multibyte character set support + Multibyte characters use typically two or more sequential bytes + to represent additional characters than can fit in a single byte + character set. The code used here is based on the ANSI mblen function. */ +#ifdef MULTIBYTE_GETOPTNS + int mb_clen(ptr) + ZCONST char *ptr; + { + /* return the number of bytes that the char pointed to is. Return 1 if + null character or error like not start of valid multibyte character. */ + int cl; + + cl = mblen(ptr, MB_CUR_MAX); + return (cl > 0) ? cl : 1; + } +#endif + + + /* moved to zip.h */ +#if 0 +#ifdef UNICODE_SUPPORT +# define MB_CLEN(ptr) (1) +# define MB_NEXTCHAR(ptr) ((ptr)++) +# ifdef MULTIBYTE_GETOPTNS +# undef MULTIBYTE_GETOPTNS +# endif +#else +# ifdef _MBCS +# ifndef MULTIBYTE_GETOPTNS +# define MULTIBYTE_GETOPTNS +# endif +# endif +/* multibyte character set support + Multibyte characters use typically two or more sequential bytes + to represent additional characters than can fit in a single byte + character set. The code used here is based on the ANSI mblen function. */ +# ifdef MULTIBYTE_GETOPTNS + local int mb_clen OF((ZCONST char *)); /* declare proto first */ + local int mb_clen(ptr) + ZCONST char *ptr; + { + /* return the number of bytes that the char pointed to is. Return 1 if + null character or error like not start of valid multibyte character. */ + int cl; + + cl = mblen(ptr, MB_CUR_MAX); + return (cl > 0) ? cl : 1; + } +# define MB_CLEN(ptr) mb_clen(ptr) +# define MB_NEXTCHAR(ptr) ((ptr) += MB_CLEN(ptr)) +# else +# define MB_CLEN(ptr) (1) +# define MB_NEXTCHAR(ptr) ((ptr)++) +# endif +#endif +#endif + + +/* constants */ + +/* function get_args_from_arg_file() can return this in depth parameter */ +#define ARG_FILE_ERR -1 + +/* internal settings for optchar */ +#define SKIP_VALUE_ARG -1 +#define THIS_ARG_DONE -2 +#define START_VALUE_LIST -3 +#define IN_VALUE_LIST -4 +#define NON_OPTION_ARG -5 +#define STOP_VALUE_LIST -6 +/* 7/25/04 EG */ +#define READ_REST_ARGS_VERBATIM -7 + + +/* global veriables */ + +int enable_permute = 1; /* yes - return options first */ +/* 7/25/04 EG */ +int doubledash_ends_options = 1; /* when -- what follows are not options */ + +/* buffer for error messages (this sizing is a guess but must hold 2 paths) */ +#define OPTIONERR_BUF_SIZE (FNMAX * 2 + 4000) +local char Far optionerrbuf[OPTIONERR_BUF_SIZE + 1]; + +/* error messages */ +static ZCONST char Far op_not_neg_err[] = "option %s not negatable"; +static ZCONST char Far op_req_val_err[] = "option %s requires a value"; +static ZCONST char Far op_no_allow_val_err[] = "option %s does not allow a value"; +static ZCONST char Far sh_op_not_sup_err[] = "short option '%c' not supported"; +static ZCONST char Far oco_req_val_err[] = "option %s requires one character value"; +static ZCONST char Far oco_no_mbc_err[] = "option %s does not support multibyte values"; +static ZCONST char Far num_req_val_err[] = "option %s requires number value"; +static ZCONST char Far long_op_ambig_err[] = "long option '%s' ambiguous"; +static ZCONST char Far long_op_not_sup_err[] = "long option '%s' not supported"; + +static ZCONST char Far no_arg_files_err[] = "argument files not enabled\n"; + + +/* below removed as only used for processing argument files */ + +/* get_nextarg */ +/* get_args_from_string */ +/* insert_args */ +/* get_args_from_arg_file */ + + +/* copy error, option name, and option description if any to buf */ +local int optionerr(buf, err, optind, islong) + char *buf; + ZCONST char *err; + int optind; + int islong; +{ + char optname[50]; + + if (options[optind].name && options[optind].name[0] != '\0') { + if (islong) + sprintf(optname, "'%s' (%s)", options[optind].longopt, options[optind].name); + else + sprintf(optname, "'%s' (%s)", options[optind].shortopt, options[optind].name); + } else { + if (islong) + sprintf(optname, "'%s'", options[optind].longopt); + else + sprintf(optname, "'%s'", options[optind].shortopt); + } + sprintf(buf, err, optname); + return 0; +} + + +/* copy_args + * + * Copy arguments in args, allocating storage with malloc. + * Copies until a NULL argument is found or until max_args args + * including args[0] are copied. Set max_args to 0 to copy + * until NULL. Always terminates returned args[] with NULL arg. + * + * Any argument in the returned args can be freed with free(). Any + * freed argument should be replaced with either another string + * allocated with malloc or by NULL if last argument so that free_args + * will properly work. + */ +char **copy_args(args, max_args) + char **args; + int max_args; +{ + int j; + char **new_args; + + if (args == NULL) { + return NULL; + } + + /* count args */ + for (j = 0; args[j] && (max_args == 0 || j < max_args); j++) ; + + if ((new_args = (char **) malloc((j + 1) * sizeof(char *))) == NULL) { + oERR(ZE_MEM, "ca"); + } + + for (j = 0; args[j] && (max_args == 0 || j < max_args); j++) { + if (args[j] == NULL) { + /* null argument is end of args */ + new_args[j] = NULL; + break; + } + if ((new_args[j] = malloc(strlen(args[j]) + 1)) == NULL) { + free_args(new_args); + oERR(ZE_MEM, "ca"); + } + strcpy(new_args[j], args[j]); + } + new_args[j] = NULL; + + return new_args; +} + + +/* free args - free args created with one of these functions */ +int free_args(args) + char **args; +{ + int i; + + if (args == NULL) { + return 0; + } + + for (i = 0; args[i]; i++) { + free(args[i]); + } + free(args); + return i; +} + + +/* insert_arg + * + * Insert the argument arg into the array args before argument at_arg. + * Return the new count of arguments (argc). + * + * If free_args is true, this function frees the old args array + * (but not the component strings). DO NOT set free_args on original + * argv but only on args allocated with malloc. + */ + +int insert_arg(pargs, arg, at_arg, free_args) + char ***pargs; + ZCONST char *arg; + int at_arg; + int free_args; +{ + char *newarg = NULL; + char **args; + char **newargs = NULL; + int argnum; + int newargnum; + int argcnt; + int newargcnt; + + if (pargs == NULL) { + return 0; + } + args = *pargs; + + /* count args */ + if (args == NULL) { + argcnt = 0; + } else { + for (argcnt = 0; args[argcnt]; argcnt++) ; + } + if (arg == NULL) { + /* done */ + return argcnt; + } + newargcnt = argcnt + 1; + + /* get storage for new args */ + if ((newargs = (char **) malloc((newargcnt + 1) * sizeof(char *))) == NULL) { + oERR(ZE_MEM, "ia"); + } + + /* copy argument pointers from args to position at_arg, copy arg, then rest args */ + argnum = 0; + newargnum = 0; + if (args) { + for (; args[argnum] && argnum < at_arg; argnum++) { + newargs[newargnum++] = args[argnum]; + } + } + /* copy new arg */ + if ((newarg = (char *) malloc(strlen(arg) + 1)) == NULL) { + oERR(ZE_MEM, "ia"); + } + strcpy(newarg, arg); + + newargs[newargnum++] = newarg; + if (args) { + for ( ; args[argnum]; argnum++) { + newargs[newargnum++] = args[argnum]; + } + } + newargs[newargnum] = NULL; + + /* free old args array but not component strings - this assumes that + args was allocated with malloc as copy_args does. DO NOT DO THIS + on the original argv. + */ + if (free_args) + free(args); + + *pargs = newargs; + + return newargnum; +} + +/* ------------------------------------- */ + + + + +/* get_shortopt + * + * Get next short option from arg. The state is stored in argnum, optchar, and + * option_num so no static storage is used. Returns the option_ID. + * + * parameters: + * args - argv array of arguments + * argnum - index of current arg in args + * optchar - pointer to index of next char to process. Can be 0 or + * const defined at top of this file like THIS_ARG_DONE + * negated - on return pointer to int set to 1 if option negated or 0 otherwise + * value - on return pointer to string set to value of option if any or NULL + * if none. If value is returned then the caller should free() + * it when not needed anymore. + * option_num - pointer to index in options[] of returned option or + * o_NO_OPTION_MATCH if none. Do not change as used by + * value lists. + * depth - recursion depth (0 at top level, 1 or more in arg files) + */ +local unsigned long get_shortopt(args, argnum, optchar, negated, value, + option_num, depth) + char **args; + int argnum; + int *optchar; + int *negated; + char **value; + int *option_num; + int depth; +{ + char *shortopt; + int clen; + char *nextchar; + char *s; + char *start; + int op; + char *arg; + int match = -1; + + + /* get arg */ + arg = args[argnum]; + /* current char in arg */ + nextchar = arg + (*optchar); + clen = MB_CLEN(nextchar); + /* next char in arg */ + (*optchar) += clen; + /* get first char of short option */ + shortopt = arg + (*optchar); + /* no value */ + *value = NULL; + + if (*shortopt == '\0') { + /* no more options in arg */ + *optchar = 0; + *option_num = o_NO_OPTION_MATCH; + return 0; + } + + /* look for match in options */ + clen = MB_CLEN(shortopt); + for (op = 0; options[op].option_ID; op++) { + s = options[op].shortopt; + if (s && s[0] == shortopt[0]) { + if (s[1] == '\0' && clen == 1) { + /* single char match */ + match = op; + } else { + /* 2 wide short opt. Could support more chars but should use long opts instead */ + if (s[1] == shortopt[1]) { + /* match 2 char short opt or 2 byte char */ + match = op; + if (clen == 1) (*optchar)++; + break; + } + } + } + } + + if (match > -1) { + /* match */ + clen = MB_CLEN(shortopt); + nextchar = arg + (*optchar) + clen; + /* check for trailing dash negating option */ + if (*nextchar == '-') { + /* negated */ + if (options[match].negatable == o_NOT_NEGATABLE) { + if (options[match].value_type == o_NO_VALUE) { + optionerr(optionerrbuf, op_not_neg_err, match, 0); + if (depth > 0) { + /* unwind */ + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + } else { + *negated = 1; + /* set up to skip negating dash */ + (*optchar) += clen; + clen = 1; + } + } + + /* value */ + clen = MB_CLEN(arg + (*optchar)); + /* optional value, one char value, and number value must follow option */ + if (options[match].value_type == o_ONE_CHAR_VALUE) { + /* one char value */ + if (arg[(*optchar) + clen]) { + /* has value */ + if (MB_CLEN(arg + (*optchar) + clen) > 1) { + /* multibyte value not allowed for now */ + optionerr(optionerrbuf, oco_no_mbc_err, match, 0); + if (depth > 0) { + /* unwind */ + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + if ((*value = (char *) malloc(2)) == NULL) { + oERR(ZE_MEM, "gso"); + } + (*value)[0] = *(arg + (*optchar) + clen); + (*value)[1] = '\0'; + *optchar += clen; + clen = 1; + } else { + /* one char values require a value */ + optionerr(optionerrbuf, oco_req_val_err, match, 0); + if (depth > 0) { + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + } else if (options[match].value_type == o_NUMBER_VALUE) { + /* read chars until end of number */ + start = arg + (*optchar) + clen; + if (*start == '+' || *start == '-') { + start++; + } + s = start; + for (; isdigit(*s); MB_NEXTCHAR(s)) ; + if (s == start) { + /* no digits */ + optionerr(optionerrbuf, num_req_val_err, match, 0); + if (depth > 0) { + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + start = arg + (*optchar) + clen; + if ((*value = (char *) malloc((int)(s - start) + 1)) == NULL) { + oERR(ZE_MEM, "gso"); + } + *optchar += (int)(s - start); + strncpy(*value, start, (int)(s - start)); + (*value)[(int)(s - start)] = '\0'; + clen = MB_CLEN(s); + } else if (options[match].value_type == o_OPTIONAL_VALUE) { + /* optional value */ + /* This seemed inconsistent so now if no value attached to argument look + to the next argument if that argument is not an option for option + value - 11/12/04 EG */ + if (arg[(*optchar) + clen]) { + /* has value */ + /* add support for optional = - 2/6/05 EG */ + if (arg[(*optchar) + clen] == '=') { + /* skip = */ + clen++; + } + if (arg[(*optchar) + clen]) { + if ((*value = (char *)malloc(strlen(arg + (*optchar) + clen) + 1)) + == NULL) { + oERR(ZE_MEM, "gso"); + } + strcpy(*value, arg + (*optchar) + clen); + } + *optchar = THIS_ARG_DONE; + } else if (args[argnum + 1] && args[argnum + 1][0] != '-') { + /* use next arg for value */ + if ((*value = (char *)malloc(strlen(args[argnum + 1]) + 1)) == NULL) { + oERR(ZE_MEM, "gso"); + } + /* using next arg as value */ + strcpy(*value, args[argnum + 1]); + *optchar = SKIP_VALUE_ARG; + } + } else if (options[match].value_type == o_REQUIRED_VALUE || + options[match].value_type == o_VALUE_LIST) { + /* see if follows option */ + if (arg[(*optchar) + clen]) { + /* has value following option as -ovalue */ + /* add support for optional = - 6/5/05 EG */ + if (arg[(*optchar) + clen] == '=') { + /* skip = */ + clen++; + } + if ((*value = (char *)malloc(strlen(arg + (*optchar) + clen) + 1)) + == NULL) { + oERR(ZE_MEM, "gso"); + } + strcpy(*value, arg + (*optchar) + clen); + *optchar = THIS_ARG_DONE; + } else { + /* use next arg for value */ + if (args[argnum + 1]) { + if ((*value = (char *)malloc(strlen(args[argnum + 1]) + 1)) == NULL) { + oERR(ZE_MEM, "gso"); + } + strcpy(*value, args[argnum + 1]); + if (options[match].value_type == o_VALUE_LIST) { + *optchar = START_VALUE_LIST; + } else { + *optchar = SKIP_VALUE_ARG; + } + } else { + /* no value found */ + optionerr(optionerrbuf, op_req_val_err, match, 0); + if (depth > 0) { + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + } + } + + *option_num = match; + return options[match].option_ID; + } + sprintf(optionerrbuf, sh_op_not_sup_err, *shortopt); + if (depth > 0) { + /* unwind */ + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + return 0; +} + + +/* get_longopt + * + * Get the long option in args array at argnum. + * Parameters same as for get_shortopt. + */ + +local unsigned long get_longopt(args, argnum, optchar, negated, value, + option_num, depth) + char **args; + int argnum; + int *optchar; + int *negated; + char **value; + int *option_num; + int depth; +{ + char *longopt; + char *lastchr; + char *valuestart; + int op; + char *arg; + int match = -1; + *value = NULL; + + if (args == NULL) { + *option_num = o_NO_OPTION_MATCH; + return 0; + } + if (args[argnum] == NULL) { + *option_num = o_NO_OPTION_MATCH; + return 0; + } + /* copy arg so can chop end if value */ + if ((arg = (char *)malloc(strlen(args[argnum]) + 1)) == NULL) { + oERR(ZE_MEM, "glo"); + } + strcpy(arg, args[argnum]); + + /* get option */ + longopt = arg + 2; + /* no value */ + *value = NULL; + + /* find = */ + for (lastchr = longopt, valuestart = longopt; + *valuestart && *valuestart != '='; + lastchr = valuestart, MB_NEXTCHAR(valuestart)) ; + if (*valuestart) { + /* found =value */ + *valuestart = '\0'; + valuestart++; + } else { + valuestart = NULL; + } + + if (*lastchr == '-') { + /* option negated */ + *negated = 1; + *lastchr = '\0'; + } else { + *negated = 0; + } + + /* look for long option match */ + for (op = 0; options[op].option_ID; op++) { + if (options[op].longopt && strcmp(options[op].longopt, longopt) == 0) { + /* exact match */ + match = op; + break; + } + if (options[op].longopt && strncmp(options[op].longopt, longopt, strlen(longopt)) == 0) { + if (match > -1) { + sprintf(optionerrbuf, long_op_ambig_err, longopt); + free(arg); + if (depth > 0) { + /* unwind */ + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + match = op; + } + } + + if (match == -1) { + sprintf(optionerrbuf, long_op_not_sup_err, longopt); + free(arg); + if (depth > 0) { + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + + /* one long option an arg */ + *optchar = THIS_ARG_DONE; + + /* if negated then see if allowed */ + if (*negated && options[match].negatable == o_NOT_NEGATABLE) { + optionerr(optionerrbuf, op_not_neg_err, match, 1); + free(arg); + if (depth > 0) { + /* unwind */ + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + /* get value */ + if (options[match].value_type == o_OPTIONAL_VALUE) { + /* optional value in form option=value */ + if (valuestart) { + /* option=value */ + if ((*value = (char *)malloc(strlen(valuestart) + 1)) == NULL) { + free(arg); + oERR(ZE_MEM, "glo"); + } + strcpy(*value, valuestart); + } + } else if (options[match].value_type == o_REQUIRED_VALUE || + options[match].value_type == o_NUMBER_VALUE || + options[match].value_type == o_ONE_CHAR_VALUE || + options[match].value_type == o_VALUE_LIST) { + /* handle long option one char and number value as required value */ + if (valuestart) { + /* option=value */ + if ((*value = (char *)malloc(strlen(valuestart) + 1)) == NULL) { + free(arg); + oERR(ZE_MEM, "glo"); + } + strcpy(*value, valuestart); + } else { + /* use next arg */ + if (args[argnum + 1]) { + if ((*value = (char *)malloc(strlen(args[argnum + 1]) + 1)) == NULL) { + free(arg); + oERR(ZE_MEM, "glo"); + } + /* using next arg as value */ + strcpy(*value, args[argnum + 1]); + if (options[match].value_type == o_VALUE_LIST) { + *optchar = START_VALUE_LIST; + } else { + *optchar = SKIP_VALUE_ARG; + } + } else { + /* no value found */ + optionerr(optionerrbuf, op_req_val_err, match, 1); + free(arg); + if (depth > 0) { + /* unwind */ + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + } + } else if (options[match].value_type == o_NO_VALUE) { + /* this option does not accept a value */ + if (valuestart) { + /* --option=value */ + optionerr(optionerrbuf, op_no_allow_val_err, match, 1); + free(arg); + if (depth > 0) { + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + } + free(arg); + + *option_num = match; + return options[match].option_ID; +} + + + +/* get_option + * + * Main interface for user. Use this function to get options, values and + * non-option arguments from a command line provided in argv form. + * + * To use get_option() first define valid options by setting + * the global variable options[] to an array of option_struct. Also + * either change defaults below or make variables global and set elsewhere. + * Zip uses below defaults. + * + * Call get_option() to get an option (like -b or --temp-file) and any + * value for that option (like filename for -b) or a non-option argument + * (like archive name) each call. If *value* is not NULL after calling + * get_option() it is a returned value and the caller should either store + * the char pointer or free() it before calling get_option() again to avoid + * leaking memory. If a non-option non-value argument is returned get_option() + * returns o_NON_OPTION_ARG and value is set to the entire argument. + * When there are no more arguments get_option() returns 0. + * + * The parameters argnum (after set to 0 on initial call), + * optchar, first_nonopt_arg, option_num, and depth (after initial + * call) are set and maintained by get_option() and should not be + * changed. The parameters argc, negated, and value are outputs and + * can be used by the calling program. get_option() returns either the + * option_ID for the current option, a special value defined in + * zip.h, or 0 when no more arguments. + * + * The value returned by get_option() is the ID value in the options + * table. This value can be duplicated in the table if different + * options are really the same option. The index into the options[] + * table is given by option_num, though the ID should be used as + * option numbers change when the table is changed. The ID must + * not be 0 for any option as this ends the table. If get_option() + * finds an option not in the table it calls oERR to post an + * error and exit. Errors also result if the option requires a + * value that is missing, a value is present but the option does + * not take one, and an option is negated but is not + * negatable. Non-option arguments return o_NON_OPTION_ARG + * with the entire argument in value. + * + * For Zip, permuting is on and all options and their values are + * returned before any non-option arguments like archive name. + * + * The arguments "-" alone and "--" alone return as non-option arguments. + * Note that "-" should not be used as part of a short option + * entry in the table but can be used in the middle of long + * options such as in the long option "a-long-option". Now "--" alone + * stops option processing, returning any arguments following "--" as + * non-option arguments instead of options. + * + * Argument file support is removed from this version. It may be added later. + * + * After each call: + * argc is set to the current size of args[] but should not change + * with argument file support removed, + * argnum is the index of the current arg, + * value is either the value of the returned option or non-option + * argument or NULL if option with no value, + * negated is set if the option was negated by a trailing dash (-) + * option_num is set to either the index in options[] for the option or + * o_NO_OPTION_MATCH if no match. + * Negation is checked before the value is read if the option is negatable so + * that the - is not included in the value. If the option is not negatable + * but takes a value then the - will start the value. If permuting then + * argnum and first_nonopt_arg are unreliable and should not be used. + * + * Command line is read from left to right. As get_option() finds non-option + * arguments (arguments not starting with - and that are not values to options) + * it moves later options and values in front of the non-option arguments. + * This permuting is turned off by setting enable_permute to 0. Then + * get_option() will return options and non-option arguments in the order + * found. Currently permuting is only done after an argument is completely + * processed so that any value can be moved with options they go with. All + * state information is stored in the parameters argnum, optchar, + * first_nonopt_arg and option_num. You should not change these after the + * first call to get_option(). If you need to back up to a previous arg then + * set argnum to that arg (remembering that args may have been permuted) and + * set optchar = 0 and first_nonopt_arg to the first non-option argument if + * permuting. After all arguments are returned the next call to get_option() + * returns 0. The caller can then call free_args(args) if appropriate. + * + * get_option() accepts arguments in the following forms: + * short options + * of 1 and 2 characters, e.g. a, b, cc, d, and ba, after a single + * leading -, as in -abccdba. In this example if 'b' is followed by 'a' + * it matches short option 'ba' else it is interpreted as short option + * b followed by another option. The character - is not legal as a + * short option or as part of a 2 character short option. + * + * If a short option has a value it immediately follows the option or + * if that option is the end of the arg then the next arg is used as + * the value. So if short option e has a value, it can be given as + * -evalue + * or + * -e value + * and now + * -e=value + * but now that = is optional a leading = is stripped for the first. + * This change allows optional short option values to be defaulted as + * -e= + * Either optional or required values can be specified. Optional values + * now use both forms as ignoring the later got confusing. Any + * non-value short options can preceed a valued short option as in + * -abevalue + * Some value types (one_char and number) allow options after the value + * so if oc is an option that takes a character and n takes a number + * then + * -abocVccn42evalue + * returns value V for oc and value 42 for n. All values are strings + * so programs may have to convert the "42" to a number. See long + * options below for how value lists are handled. + * + * Any short option can be negated by following it with -. Any - is + * handled and skipped over before any value is read unless the option + * is not negatable but takes a value and then - starts the value. + * + * If the value for an optional value is just =, then treated as no + * value. + * + * long options + * of arbitrary length are assumed if an arg starts with -- but is not + * exactly --. Long options are given one per arg and can be abbreviated + * if the abbreviation uniquely matches one of the long options. + * Exact matches always match before partial matches. If ambiguous an + * error is generated. + * + * Values are specified either in the form + * --longoption=value + * or can be the following arg if the value is required as in + * --longoption value + * Optional values to long options must be in the first form. + * + * Value lists are specified by o_VALUE_LIST and consist of an option + * that takes a value followed by one or more value arguments. + * The two forms are + * --option=value + * or + * -ovalue + * for a single value or + * --option value1 value2 value3 ... --option2 + * or + * -o value1 value2 value3 ... + * for a list of values. The list ends at the next option, the + * end of the command line, or at a single "@" argument. + * Each value is treated as if it was preceeded by the option, so + * --option1 val1 val2 + * with option1 value_type set to o_VALUE_LIST is the same as + * --option1=val1 --option1=val2 + * + * Long options can be negated by following the option with - as in + * --longoption- + * Long options with values can also be negated if this makes sense for + * the caller as: + * --longoption-=value + * If = is not followed by anything it is treated as no value. + * + * @path + * When an argument in the form @path is encountered, the file at path + * is opened and white space separated arguments read from the file + * and inserted into the command line at that point as if the contents + * of the file were directly typed at that location. The file can + * have options, files to zip, or anything appropriate at that location + * in the command line. Since Zip has permuting enabled, options and + * files will propagate to the appropriate locations in the command + * line. + * + * Argument files support has been removed from this version. It may + * be added back later. + * + * non-option argument + * is any argument not given above. If enable_permute is 1 then + * these are returned after all options, otherwise all options and + * args are returned in order. Returns option ID o_NON_OPTION_ARG + * and sets value to the argument. + * + * + * Arguments to get_option: + * char ***pargs - pointer to arg array in the argv form + * int *argc - returns the current argc for args incl. args[0] + * int *argnum - the index of the current argument (caller + * should set = 0 on first call and not change + * after that) + * int *optchar - index of next short opt in arg or special + * int *first_nonopt_arg - used by get_option to permute args + * int *negated - option was negated (had trailing -) + * char *value - value of option if any (free when done with it) or NULL + * int *option_num - the index in options of the last option returned + * (can be o_NO_OPTION_MATCH) + * int recursion_depth - current depth of recursion + * (always set to 0 by caller) + * (always 0 with argument files support removed) + * + * Caller should only read the returned option ID and the value, negated, + * and option_num (if required) parameters after each call. + * + * Ed Gordon + * 24 August 2003 (last updated 2 April 2008 EG) + * + */ + +unsigned long get_option(pargs, argc, argnum, optchar, value, + negated, first_nonopt_arg, option_num, recursion_depth) + char ***pargs; + int *argc; + int *argnum; + int *optchar; + char **value; + int *negated; + int *first_nonopt_arg; + int *option_num; + int recursion_depth; +{ + char **args; + unsigned long option_ID; + + int argcnt; + int first_nonoption_arg; + char *arg = NULL; + int h; + int optc; + int argn; + int j; + int v; + int read_rest_args_verbatim = 0; /* 7/25/04 - ignore options and arg files for rest args */ + + /* value is outdated. The caller should free value before + calling get_option again. */ + *value = NULL; + + /* if args is NULL then done */ + if (pargs == NULL) { + *argc = 0; + return 0; + } + args = *pargs; + if (args == NULL) { + *argc = 0; + return 0; + } + + /* count args */ + for (argcnt = 0; args[argcnt]; argcnt++) ; + + /* if no provided args then nothing to do */ + if (argcnt < 1 || (recursion_depth == 0 && argcnt < 2)) { + *argc = argcnt; + /* return 0 to note that no args are left */ + return 0; + } + + *negated = 0; + first_nonoption_arg = *first_nonopt_arg; + argn = *argnum; + optc = *optchar; + + if (optc == READ_REST_ARGS_VERBATIM) { + read_rest_args_verbatim = 1; + } + + if (argn == -1 || (recursion_depth == 0 && argn == 0)) { + /* first call */ + /* if depth = 0 then args[0] is argv[0] so skip */ + *option_num = o_NO_OPTION_MATCH; + optc = THIS_ARG_DONE; + first_nonoption_arg = -1; + } + + /* if option_num is set then restore last option_ID in case continuing value list */ + option_ID = 0; + if (*option_num != o_NO_OPTION_MATCH) { + option_ID = options[*option_num].option_ID; + } + + /* get next option if any */ + for (;;) { + if (read_rest_args_verbatim) { + /* rest of args after "--" are non-option args if doubledash_ends_options set */ + argn++; + if (argn > argcnt || args[argn] == NULL) { + /* done */ + option_ID = 0; + break; + } + arg = args[argn]; + if ((*value = (char *)malloc(strlen(arg) + 1)) == NULL) { + oERR(ZE_MEM, "go"); + } + strcpy(*value, arg); + *option_num = o_NO_OPTION_MATCH; + option_ID = o_NON_OPTION_ARG; + break; + + /* permute non-option args after option args so options are returned first */ + } else if (enable_permute) { + if (optc == SKIP_VALUE_ARG || optc == THIS_ARG_DONE || + optc == START_VALUE_LIST || optc == IN_VALUE_LIST || + optc == STOP_VALUE_LIST) { + /* moved to new arg */ + if (first_nonoption_arg > -1 && args[first_nonoption_arg]) { + /* do the permuting - move non-options after this option */ + /* if option and value separate args or starting list skip option */ + if (optc == SKIP_VALUE_ARG || optc == START_VALUE_LIST) { + v = 1; + } else { + v = 0; + } + for (h = first_nonoption_arg; h < argn; h++) { + arg = args[first_nonoption_arg]; + for (j = first_nonoption_arg; j < argn + v; j++) { + args[j] = args[j + 1]; + } + args[j] = arg; + } + first_nonoption_arg += 1 + v; + } + } + } else if (optc == NON_OPTION_ARG) { + /* if not permuting then already returned arg */ + optc = THIS_ARG_DONE; + } + + /* value lists */ + if (optc == STOP_VALUE_LIST) { + optc = THIS_ARG_DONE; + } + + if (optc == START_VALUE_LIST || optc == IN_VALUE_LIST) { + if (optc == START_VALUE_LIST) { + /* already returned first value */ + argn++; + optc = IN_VALUE_LIST; + } + argn++; + arg = args[argn]; + /* if end of args and still in list and there are non-option args then + terminate list */ + if (arg == NULL && (optc == START_VALUE_LIST || optc == IN_VALUE_LIST) + && first_nonoption_arg > -1) { + /* terminate value list with @ */ + /* this is only needed for argument files */ + /* but is also good for show command line so command lines with lists + can always be read back in */ + argcnt = insert_arg(&args, "@", first_nonoption_arg, 1); + argn++; + if (first_nonoption_arg > -1) { + first_nonoption_arg++; + } + } + + arg = args[argn]; + if (arg && arg[0] == '@' && arg[1] == '\0') { + /* inserted arguments terminator */ + optc = STOP_VALUE_LIST; + continue; + } else if (arg && arg[0] != '-') { /* not option */ + /* - and -- are not allowed in value lists unless escaped */ + /* another value in value list */ + if ((*value = (char *)malloc(strlen(args[argn]) + 1)) == NULL) { + oERR(ZE_MEM, "go"); + } + strcpy(*value, args[argn]); + break; + + } else { + argn--; + optc = THIS_ARG_DONE; + } + } + + /* move to next arg */ + if (optc == SKIP_VALUE_ARG) { + argn += 2; + optc = 0; + } else if (optc == THIS_ARG_DONE) { + argn++; + optc = 0; + } + if (argn > argcnt) { + break; + } + if (args[argn] == NULL) { + /* done unless permuting and non-option args */ + if (first_nonoption_arg > -1 && args[first_nonoption_arg]) { + /* return non-option arguments at end */ + if (optc == NON_OPTION_ARG) { + first_nonoption_arg++; + } + /* after first pass args are permuted but skipped over non-option args */ + /* swap so argn points to first non-option arg */ + j = argn; + argn = first_nonoption_arg; + first_nonoption_arg = j; + } + if (argn > argcnt || args[argn] == NULL) { + /* done */ + option_ID = 0; + break; + } + } + + /* after swap first_nonoption_arg points to end which is NULL */ + if (first_nonoption_arg > -1 && (args[first_nonoption_arg] == NULL)) { + /* only non-option args left */ + if (optc == NON_OPTION_ARG) { + argn++; + } + if (argn > argcnt || args[argn] == NULL) { + /* done */ + option_ID = 0; + break; + } + if ((*value = (char *)malloc(strlen(args[argn]) + 1)) == NULL) { + oERR(ZE_MEM, "go"); + } + strcpy(*value, args[argn]); + optc = NON_OPTION_ARG; + option_ID = o_NON_OPTION_ARG; + break; + } + + arg = args[argn]; + + /* is it an option */ + if (arg[0] == '-') { + /* option */ + if (arg[1] == '\0') { + /* arg = - */ + /* treat like non-option arg */ + *option_num = o_NO_OPTION_MATCH; + if (enable_permute) { + /* permute args to move all non-option args to end */ + if (first_nonoption_arg < 0) { + first_nonoption_arg = argn; + } + argn++; + } else { + /* not permute args so return non-option args when found */ + if ((*value = (char *)malloc(strlen(arg) + 1)) == NULL) { + oERR(ZE_MEM, "go"); + } + strcpy(*value, arg); + optc = NON_OPTION_ARG; + option_ID = o_NON_OPTION_ARG; + break; + } + + } else if (arg[1] == '-') { + /* long option */ + if (arg[2] == '\0') { + /* arg = -- */ + if (doubledash_ends_options) { + /* Now -- stops permuting and forces the rest of + the command line to be read verbatim - 7/25/04 EG */ + + /* never permute args after -- and return as non-option args */ + if (first_nonoption_arg < 1) { + /* -- is first non-option argument - 8/7/04 EG */ + argn--; + } else { + /* go back to start of non-option args - 8/7/04 EG */ + argn = first_nonoption_arg - 1; + } + + /* disable permuting and treat remaining arguments as not + options */ + read_rest_args_verbatim = 1; + optc = READ_REST_ARGS_VERBATIM; + + } else { + /* treat like non-option arg */ + *option_num = o_NO_OPTION_MATCH; + if (enable_permute) { + /* permute args to move all non-option args to end */ + if (first_nonoption_arg < 0) { + first_nonoption_arg = argn; + } + argn++; + } else { + /* not permute args so return non-option args when found */ + if ((*value = (char *)malloc(strlen(arg) + 1)) == NULL) { + oERR(ZE_MEM, "go"); + } + strcpy(*value, arg); + optc = NON_OPTION_ARG; + option_ID = o_NON_OPTION_ARG; + break; + } + } + + } else { + option_ID = get_longopt(args, argn, &optc, negated, value, option_num, recursion_depth); + if (option_ID == o_ARG_FILE_ERR) { + /* unwind as only get this if recursion_depth > 0 */ + return option_ID; + } + break; + } + + } else { + /* short option */ + option_ID = get_shortopt(args, argn, &optc, negated, value, option_num, recursion_depth); + + if (option_ID == o_ARG_FILE_ERR) { + /* unwind as only get this if recursion_depth > 0 */ + return option_ID; + } + + if (optc == 0) { + /* if optc = 0 then ran out of short opts this arg */ + optc = THIS_ARG_DONE; + } else { + break; + } + } + +#if 0 + /* argument file code left out + so for now let filenames start with @ + */ + + } else if (allow_arg_files && arg[0] == '@') { + /* arg file */ + oERR(ZE_PARMS, no_arg_files_err); +#endif + + } else { + /* non-option */ + if (enable_permute) { + /* permute args to move all non-option args to end */ + if (first_nonoption_arg < 0) { + first_nonoption_arg = argn; + } + argn++; + } else { + /* no permute args so return non-option args when found */ + if ((*value = (char *)malloc(strlen(arg) + 1)) == NULL) { + oERR(ZE_MEM, "go"); + } + strcpy(*value, arg); + *option_num = o_NO_OPTION_MATCH; + optc = NON_OPTION_ARG; + option_ID = o_NON_OPTION_ARG; + break; + } + + } + } + + *pargs = args; + *argc = argcnt; + *first_nonopt_arg = first_nonoption_arg; + *argnum = argn; + *optchar = optc; + + return option_ID; +} diff --git a/globals.c b/globals.c new file mode 100644 index 0000000..e73392a --- /dev/null +++ b/globals.c @@ -0,0 +1,253 @@ +/* + globals.c - Zip 3 + + Copyright (c) 1990-2008 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 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 +*/ +/* + * globals.c by Mark Adler + */ +#define __GLOBALS_C + +#define GLOBALS /* include definition of errors[] in zip.h */ +#ifndef UTIL +#define UTIL /* do not declare the read_buf variable */ +#endif + +#include "zip.h" + + +/* Handy place to build error messages */ +char errbuf[FNMAX+4081]; + +/* Argument processing globals */ +int recurse = 0; /* 1=recurse into directories encountered */ +int dispose = 0; /* 1=remove files after put in zip file */ +int pathput = 1; /* 1=store path with name */ +#ifdef RISCOS +int scanimage = 1; /* 1=scan through image files */ +#endif +int method = BEST; /* one of BEST, DEFLATE (only), or STORE (only) */ +int dosify = 0; /* 1=make new entries look like MSDOS */ +int verbose = 0; /* 1=report oddities in zip file structure */ +int fix = 0; /* 1=fix the zip file, 2=FF, 3=ZipNote */ +int filesync = 0; /* 1=file sync, delete entries not on file system */ +int adjust = 0; /* 1=adjust offsets for sfx'd file (keep preamble) */ +int level = 6; /* 0=fastest compression, 9=best compression */ +int translate_eol = 0; /* Translate end-of-line LF -> CR LF */ +#ifdef VMS + int vmsver = 0; /* 1=append VMS version number to file names */ + int vms_native = 0; /* 1=store in VMS format */ + int vms_case_2 = 0; /* ODS2 file name case in VMS. -1: down. */ + int vms_case_5 = 0; /* ODS5 file name case in VMS. +1: preserve. */ +#endif /* VMS */ +#if defined(OS2) || defined(WIN32) + int use_longname_ea = 0; /* 1=use the .LONGNAME EA as the file's name */ +#endif +/* 9/26/04 */ +int no_wild = 0; /* 1 = wildcards are disabled */ +int allow_regex = 0; /* 1 = allow [list] matching */ +#ifdef WILD_STOP_AT_DIR + int wild_stop_at_dir = 1; /* default wildcards do not include / in matches */ +#else + int wild_stop_at_dir = 0; /* default wildcards do include / in matches */ +#endif + +#ifdef UNICODE_SUPPORT + int using_utf8 = 0; /* 1 if current character set UTF-8 */ +# ifdef WIN32 + int no_win32_wide = -1; /* 1 = no wide functions, like GetFileAttributesW() */ +# endif +#endif + +ulg skip_this_disk = 0; +int des_good = 0; /* Good data descriptor found */ +ulg des_crc = 0; /* Data descriptor CRC */ +uzoff_t des_csize = 0; /* Data descriptor csize */ +uzoff_t des_usize = 0; /* Data descriptor usize */ + +/* dots 10/20/04 */ +zoff_t dot_size = 0; /* bytes processed in deflate per dot, 0 = no dots */ +zoff_t dot_count = 0; /* buffers seen, recyles at dot_size */ +/* status 10/30/04 */ +int display_counts = 0; /* display running file count */ +int display_bytes = 0; /* display running bytes remaining */ +int display_globaldots = 0; /* display dots for archive instead of each file */ +int display_volume = 0; /* display current input and output volume (disk) numbers */ +int display_usize = 0; /* display uncompressed bytes */ +ulg files_so_far = 0; /* files processed so far */ +ulg bad_files_so_far = 0; /* bad files skipped so far */ +ulg files_total = 0; /* files total to process */ +uzoff_t bytes_so_far = 0; /* bytes processed so far (from initial scan) */ +uzoff_t good_bytes_so_far = 0;/* good bytes read so far */ +uzoff_t bad_bytes_so_far = 0; /* bad bytes skipped so far */ +uzoff_t bytes_total = 0; /* total bytes to process (from initial scan) */ + +/* logfile 6/5/05 */ +int logall = 0; /* 0 = warnings/errors, 1 = all */ +FILE *logfile = NULL; /* pointer to open logfile or NULL */ +int logfile_append = 0; /* append to existing logfile */ +char *logfile_path = NULL; /* pointer to path of logfile */ + +int hidden_files = 0; /* process hidden and system files */ +int volume_label = 0; /* add volume label */ +int dirnames = 1; /* include directory entries by default */ +int filter_match_case = 1; /* 1=match case when filter() */ +int diff_mode = 0; /* 1=require --out and only store changed and add */ +#if defined(WIN32) +int only_archive_set = 0; /* include only files with DOS archive bit set */ +int clear_archive_bits = 0; /* clear DOS archive bit of included files */ +#endif +int linkput = 0; /* 1=store symbolic links as such */ +int noisy = 1; /* 0=quiet operation */ +int extra_fields = 1; /* 0=create minimum, 1=don't copy old, 2=keep old */ +int use_descriptors = 0; /* 1=use data descriptors 12/29/04 */ +int zip_to_stdout = 0; /* output zipfile to stdout 12/30/04 */ +int allow_empty_archive = 0; /* if no files, create empty archive anyway 12/28/05 */ +int copy_only = 0; /* 1=copying archive entries only */ +int allow_fifo = 0; /* 1=allow reading Unix FIFOs, waiting if pipe open */ +int show_files = 0; /* show files to operate on and exit (=2 log only) */ + +int output_seekable = 1; /* 1 = output seekable 3/13/05 EG */ + +#ifdef ZIP64_SUPPORT /* zip64 support 10/4/03 */ + int force_zip64 = -1; /* if 1 force entries to be zip64, 0 force not zip64 */ + /* mainly for streaming from stdin */ + int zip64_entry = 0; /* current entry needs Zip64 */ + int zip64_archive = 0; /* if 1 then at least 1 entry needs zip64 */ +#endif + +#ifdef NTSD_EAS + int use_privileges = 0; /* 1=use security privilege overrides */ +#endif +#ifndef RISCOS +#ifndef QDOS +#ifndef TANDEM +char *special = ".Z:.zip:.zoo:.arc:.lzh:.arj"; /* List of special suffixes */ +#else /* TANDEM */ +char *special = " Z: zip: zoo: arc: lzh: arj"; /* List of special suffixes */ +#endif +#else /* QDOS */ +char *special = "_Z:_zip:_zoo:_arc:_lzh:_arj"; /* List of special suffixes */ +#endif +#else /* RISCOS */ +char *special = "DDC:D96:68E"; +#endif /* ?RISCOS */ +char *key = NULL; /* Scramble password if scrambling */ +char *tempath = NULL; /* Path for temporary files */ +FILE *mesg; /* stdout by default, stderr for piping */ + +#ifdef UNICODE_SUPPORT + int utf8_force = 0; /* 1=force storing UTF-8 as standard per AppNote bit 11 */ +#endif +int unicode_escape_all = 0; /* 1=escape all non-ASCII characters in paths */ +int unicode_mismatch = 1; /* unicode mismatch is 0=error, 1=warn, 2=ignore, 3=no */ + +time_t scan_delay = 5; /* seconds before display Scanning files message */ +time_t scan_dot_time = 2; /* time in seconds between Scanning files dots */ +time_t scan_start = 0; /* start of scan */ +time_t scan_last = 0; /* time of last message */ +int scan_started = 0; /* scan has started */ +uzoff_t scan_count = 0; /* Used for Scanning files ... message */ + +ulg before = 0; /* 0=ignore, else exclude files before this time */ +ulg after = 0; /* 0=ignore, else exclude files newer than this time */ + +/* Zip file globals */ +char *zipfile; /* New or existing zip archive (zip file) */ + +/* zip64 support 08/31/2003 R.Nausedat */ +/* all are across splits - subtract bytes_prev_splits to get offsets for current disk */ +uzoff_t zipbeg; /* Starting offset of zip structures */ +uzoff_t cenbeg; /* Starting offset of central dir */ +uzoff_t tempzn; /* Count of bytes written to output zip files */ + +/* 10/28/05 */ +char *tempzip = NULL; /* name of temp file */ +FILE *y = NULL; /* output file now global so can change in splits */ +FILE *in_file = NULL; /* current input file for splits */ +char *in_path = NULL; /* base name of input archive file */ +char *in_split_path = NULL; /* in split path */ +char *out_path = NULL; /* base name of output file, usually same as zipfile */ +int zip_attributes = 0; + +/* in split globals */ + +ulg total_disks = 0; /* total disks in archive */ +ulg current_in_disk = 0; /* current read split disk */ +uzoff_t current_in_offset = 0; /* current offset in current read disk */ +ulg skip_current_disk = 0; /* if != 0 and fix then skip entries on this disk */ + + +/* out split globals */ + +ulg current_local_disk = 0; /* disk with current local header */ + +ulg current_disk = 0; /* current disk number */ +ulg cd_start_disk = (ulg)-1; /* central directory start disk */ +uzoff_t cd_start_offset = 0; /* offset of start of cd on cd start disk */ +uzoff_t cd_entries_this_disk = 0; /* cd entries this disk */ +uzoff_t total_cd_entries = 0; /* total cd entries in new/updated archive */ +ulg zip64_eocd_disk = 0; /* disk with Zip64 End Of Central Directory Record */ +uzoff_t zip64_eocd_offset = 0; /* offset for Zip64 EOCD Record */ + +/* for split method 1 (keep split with local header open and update) */ +char *current_local_tempname = NULL; /* name of temp file */ +FILE *current_local_file = NULL; /* file pointer for current local header */ +uzoff_t current_local_offset = 0; /* offset to start of current local header */ + +/* global */ +uzoff_t bytes_this_split = 0; /* bytes written to the current split */ +int read_split_archive = 0; /* 1=scanzipf_reg detected spanning signature */ +int split_method = 0; /* 0=no splits, 1=seekable, 2=data desc, -1=no */ +uzoff_t split_size = 0; /* how big each split should be */ +int split_bell = 0; /* when pause for next split ring bell */ +uzoff_t bytes_prev_splits = 0; /* total bytes written to all splits before this */ +uzoff_t bytes_this_entry = 0; /* bytes written for this entry across all splits */ +int noisy_splits = 0; /* note when splits are being created */ +int mesg_line_started = 0; /* 1=started writing a line to mesg */ +int logfile_line_started = 0; /* 1=started writing a line to logfile */ + +#ifdef WIN32 + int nonlocal_name = 0; /* Name has non-local characters */ + int nonlocal_path = 0; /* Path has non-local characters */ +#endif +#ifdef UNICODE_SUPPORT + int use_wide_to_mb_default = 0; +#endif + +struct zlist far *zfiles = NULL; /* Pointer to list of files in zip file */ +/* The limit for number of files using the Zip64 format is 2^64 - 1 (8 bytes) + but extent is used for many internal sorts and other tasks and is generally + long on 32-bit systems. Because of that, but more because of various memory + utilization issues limiting the practical number of central directory entries + that can be sorted, the number of actual entries that can be stored probably + can't exceed roughly 2^30 on 32-bit systems so extent is probably sufficient. */ +extent zcount; /* Number of files in zip file */ +int zipfile_exists = 0; /* 1 if zipfile exists */ +ush zcomlen; /* Length of zip file comment */ +char *zcomment = NULL; /* Zip file comment (not zero-terminated) */ +struct zlist far **zsort; /* List of files sorted by name */ +#ifdef UNICODE_SUPPORT + struct zlist far **zusort; /* List of files sorted by zuname */ +#endif + +/* Files to operate on that are not in zip file */ +struct flist far *found = NULL; /* List of names found */ +struct flist far * far *fnxt = &found; + /* Where to put next name in found list */ +extent fcount; /* Count of files in list */ + +/* Patterns to be matched */ +struct plist *patterns = NULL; /* List of patterns to be matched */ +unsigned pcount = 0; /* number of patterns */ +unsigned icount = 0; /* number of include only patterns */ +unsigned Rcount = 0; /* number of -R include patterns */ + +#ifdef IZ_CHECK_TZ +int zp_tz_is_valid; /* signals "timezone info is available" */ +#endif diff --git a/human68k/Makefile b/human68k/Makefile new file mode 100644 index 0000000..be1a8b7 --- /dev/null +++ b/human68k/Makefile @@ -0,0 +1,95 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for human68k +# Written by NIIMI Satoshi +# +# 1999/09/23: Modified by Shimazaki Ryo. + +ifeq "$(TARGET)" "X68030" +COPT = -m68020-40 +AOPT = -m68020 -sCPU020 +LDFLAGS = -L/usr/local/lib/lib060 +endif + +VPATH = human68k + +CC = gcc2 +CFLAGS = $(COPT) -I. -Wall -O2 -fomit-frame-pointer -fstrength-reduce \ + -DASM_CRC -D__DOS_INLINE__ +#LDFLAGS = -Wl,-x +LIBS = -lhmem -lttyi -lsignal + +AS = g2as +ASFLAGS = $(AOPT) -1 -c4 -y -w2 + +# object file lists +OBJZ = zip.o zipfile.o zipup.o fileio.o util.o globals.o crypt.o ttyio.o \ + crc32.o human68k.o crc_68.o +OBJI = deflate.o trees.o +OBJA = +OBJU = zipfile_.o fileio_.o util_.o globals.o human68k_.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o $(OBJU) crc32_.o crypt_.o ttyio.o +OBJS = zipsplit.o $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h human68k/osdep.h + +all: zips + +.SUFFIXES: _.o .o .c +.c_.o: + $(CC) $(CFLAGS) -DUTIL -c $< -o $@ +.c.o: + $(CC) $(CFLAGS) -c $< -o $@ + +ZIPS = zip.x zipnote.x zipsplit.x zipcloak.x + +zips: $(ZIPS) + +zip.x: $(OBJZ) $(OBJI) $(OBJA) + $(CC) $(LDFLAGS) -o $@ $(OBJZ) $(OBJI) $(OBJA) $(LIBS) +zipnote.x: $(OBJN) + $(CC) $(LDFLAGS) -o $@ $(OBJN) $(LIBS) +zipcloak.x: $(OBJC) + $(CC) $(LDFLAGS) -o $@ $(OBJC) $(LIBS) +zipsplit.x: $(OBJS) + $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + + +human68k.o: human68k/human68k.c + $(CC) $(CFLAGS) -c -o $@ $< + +human68k_.o: human68k/human68k.c + $(CC) $(CFLAGS) -c -o $@ $< -DUTIL + +#match.o: human68k/match.s +# $(AS) $(ASFLAGS) -o $@ $< + +deflate.o: human68k/deflate.s + $(AS) $(ASFLAGS) -o $@ $< + +crc_68.o: human68k/crc_68.s + $(AS) $(ASFLAGS) -o $@ $< + + +clean: + rm -f *.o $(ZIPS) + +zip.bfd: $(ZIPS) + rm -f $@ + for file in $(ZIPS); do \ + bdif -A -R uploaded/$$file $$file $@; \ + done + +# rules for zip, zipnote, zipcloak, zipsplit. +$(OBJZ): $(ZIP_H) +$(OBJI): $(ZIP_H) +$(OBJN): $(ZIP_H) +$(OBJS): $(ZIP_H) +$(OBJC): $(ZIP_H) +zip.o crc32.o crypt.o fileio.o zipfile.o zipup.o: crc32.h +zipcloak.o crc32_.o crypt_.o fileio_.o zipfile_.o: crc32.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: human68k/zipup.h + +# EOF diff --git a/human68k/Makefile.gcc b/human68k/Makefile.gcc new file mode 100644 index 0000000..edf2989 --- /dev/null +++ b/human68k/Makefile.gcc @@ -0,0 +1,78 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for human68k +# Written by NIIMI Satoshi + +VPATH = human68k + +CC = gcc +AS = as + +# if you are using mc68030 (or higher) based X68000, +# uncomment following defines +#CC = gcc -DUNALIGNED_OK +#AS = as -s UNALIGNED_OK + +CFLAGS = -Wall -O -fomit-frame-pointer -fstrength-reduce -DASMV +LDFLAGS = -s +LIBS = -lsignal -lmb -ldos + +# object file lists +OBJZ = zip.o zipfile.o zipup.o fileio.o util.o crc32.o globals.o \ + crypt.o ttyio.o + +OBJI = deflate.o trees.o +OBJA = match.o human68k.o +OBJU = zipfile_.o fileio_.o util_.o globals.o human68_.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o $(OBJU) crc32_.o crypt_.o ttyio.o +OBJS = zipsplit.o $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h human68k/osdep.h + +all: zips + +.SUFFIXES: _.o .o .c +.c_.o: + $(CC) $(CFLAGS) -DUTIL -c $< -o $@ +.c.o: + $(CC) $(CFLAGS) -c $< -o $@ + +ZIPS = zip.x zipnote.x zipsplit.x zipcloak.x + +zips: $(ZIPS) + +zip.x: $(OBJZ) $(OBJI) $(OBJA) + $(CC) -o zip.x $(LDFLAGS) $(OBJZ) $(OBJI) $(OBJA) $(LIBS) +zipnote.x: $(OBJN) + $(CC) -o zipnote.x $(LDFLAGS) $(OBJN) $(LIBS) +zipcloak.x: $(OBJC) + $(CC) -o zipcloak.x $(LDFLAGS) $(OBJC) $(LIBS) +zipsplit.x: $(OBJS) + $(CC) -o zipsplit.x $(LDFLAGS) $(OBJS) $(LIBS) + +match.o: human68k/match.s + $(AS) -o $@ $< + +human68_.o: human68k/human68k.c + $(CC) $(CFLAGS) -DUTIL -c -o $@ $< + +clean: + rm -f *.o $(ZIPS) + +zip.bfd: $(ZIPS) + rm -f $@ + for file in $(ZIPS); do \ + bdif -A -R uploaded/$$file $$file $@; \ + done + +# rules for zip, zipnote, zipcloak, zipsplit. +$(OBJZ): $(ZIP_H) +$(OBJI): $(ZIP_H) +$(OBJN): $(ZIP_H) +$(OBJS): $(ZIP_H) +$(OBJC): $(ZIP_H) +zip.o crc32.o crypt.o fileio.o zipfile.o zipup.o: crc32.h +zipcloak.o crc32_.o crypt_.o fileio_.o zipfile_.o: crc32.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: human68k/zipup.h diff --git a/human68k/crc_68.s b/human68k/crc_68.s new file mode 100644 index 0000000..9ce78d8 --- /dev/null +++ b/human68k/crc_68.s @@ -0,0 +1,144 @@ +;=========================================================================== +; Copyright (c) 1990-2000 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 2000-Apr-09 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, all these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +;=========================================================================== +; crc_68 created by Paul Kienitz, last modified 04 Jan 96. +; +; Return an updated 32 bit CRC value, given the old value and a block of data. +; The CRC table used to compute the value is gotten by calling get_crc_table(). +; This replaces the older updcrc() function used in Zip and fUnZip. The +; prototype of the function is: +; +; ulg crc32(ulg crcval, uch *text, extent textlen); +; +; On the Amiga, type extent is always unsigned long, not unsigned int, because +; int can be short or long at whim, but size_t is long. +; +; If using this source on a non-Amiga 680x0 system, note that we treat +; a0/a1/d0/d1 as scratch registers not preserved across function calls. +; We do not bother to support registerized arguments for crc32() -- the +; textlen parm is usually large enough so that savings outside the loop +; are pointless. +; +; Define NO_UNROLLED_LOOPS to use a simple short loop which might be more +; efficient on certain machines with dinky instruction caches ('020?), or for +; processing short strings. If loops are unrolled, the textlen parm must be +; less than 512K; if not unrolled, it must be less than 64K. +; +; 1999/09/23: for Human68k: Modified by Shimazaki Ryo. + + xdef _crc32 ; (ulg val, uch *buf, extent bufsize) + +DO_CRC0 MACRO + moveq #0,ltemp + move.b (textbuf)+,ltemp + eor.b crcval,ltemp + lsl.w #2,ltemp + move.l (crc_table,ltemp.w),ltemp + lsr.l #8,crcval + eor.l ltemp,crcval + ENDM + + +DO_CRC2 MACRO + move.b (textbuf)+,btemp + eor.b crcval,btemp + lsr.l #8,crcval + move.l (crc_table,btemp.w*4),ltemp + eor.l ltemp,crcval + ENDM + +crc_table reg a0 array of unsigned long +crcval reg d0 unsigned long initial value +textbuf reg a1 array of unsigned char +textbufsize reg d1 unsigned long (count of bytes in textbuf) +btemp reg d2 +ltemp reg d3 + + + xref _get_crc_table ; ulg *get_crc_table(void) + + + + quad +_crc32: + move.l 8(sp),d0 + bne.s valid +;;;;; moveq #0,d0 + rts +valid: movem.l btemp/ltemp,-(sp) + jsr _get_crc_table + movea.l d0,crc_table + move.l 12(sp),crcval + move.l 16(sp),textbuf + move.l 20(sp),textbufsize + not.l crcval + + ifdef NO_UNROLLED_LOOPS + + if CPU==68000 + bra.s decr +loop: DO_CRC0 +decr: dbra textbufsize,loop + bra.s done + + else +twenty: moveq #0,btemp + bra.s decr2 +loop2: DO_CRC2 +decr2: dbra textbufsize,loop2 + endif + + ELSE ; !NO_UNROLLED_LOOPS + + if CPU==68000 + moveq #7,btemp + and textbufsize,btemp + lsr.l #3,textbufsize + bra decr8 +loop8: DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 +decr8: dbra textbufsize,loop8 + bra.s decr1 +loop1: DO_CRC0 +decr1: dbra btemp,loop1 + bra done + + else +twenty: moveq #0,btemp + move.l textbufsize,-(sp) + lsr.l #3,textbufsize + bra decr82 + quad +loop82: DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 +decr82: dbra textbufsize,loop82 + moveq #7,textbufsize + and.l (sp)+,textbufsize + bra.s decr12 +loop12: DO_CRC2 +decr12: dbra textbufsize,loop12 + endif + + ENDC ; ?NO_UNROLLED_LOOPS + +done: movem.l (sp)+,btemp/ltemp + not.l crcval +;;;;; move.l crcval,d0 ; crcval already is d0 + rts diff --git a/human68k/deflate.s b/human68k/deflate.s new file mode 100644 index 0000000..246962c --- /dev/null +++ b/human68k/deflate.s @@ -0,0 +1,1076 @@ +;=========================================================================== +; Copyright (c) 1990-1999 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 1999-Oct-05 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, both of these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +;=========================================================================== +; This is a 680x0 assembly language translation of the Info-ZIP source file +; deflate.c, by Paul Kienitz. No rights reserved. The function longest_match +; is based in part on match.a by Carsten Steger, which in turn is partly based +; on match.s for 386 by Jean-loup Gailly and Kai Uwe Rommel. Mostly, however, +; this material is based on deflate.c, by Gailly, Rommel, and Igor Mandrichenko. +; This code is not commented very much; see deflate.c for comments that explain +; what the functions are doing. +; +; The symbols that can be used to select different versions are as follows: +; +; CPU020 if defined, use 68020 instructions always. +; +; CPUTEST if defined, check at runtime for CPU type. Another symbol +; specifying the platform-specific test must be used with this. +; If neither of these is defined, use 68000 instructions only. +; Runtime test is nonportable; it is different for each OS. +; +; AMIGA use Amiga-specific test for 68020, if CPUTEST defined. Also +; tells it that registers d0/a0/d1/a1 are not preserved by +; function calls. At present, if AMIGA is not defined, it +; causes functions to preserve all registers. ALL OF THIS CODE +; CURRENTLY ASSUMES THAT REGISTERS D2-D7/A2-A6 WILL BE PRESERVED +; BY ANY FUNCTIONS THAT IT CALLS. +; +; DYN_ALLOC should be defined here if it is defined for C source; tells us +; that big arrays are allocated instead of static. +; +; WSIZE must be defined as the same number used for WSIZE in the C +; source, and must be a power of two <= 32768. As elsewhere, +; the default value is 32768. +; +; INT16 define this if ints are 16 bits; otherwise 32 bit ints assumed. +; +; SMALL_MEM define this if it is defined in the C source; otherwise it uses +; the MEDIUM_MEM model. BIG_MEM and MMAP are *not* supported. +; The FULL_SEARCH option in deflate.c is also not supported. +; +; DEBUG activates some tracing output, as in the C source. +; +; QUADLONG this selects a different version of the innermost longest_match +; loop code for 68020 operations, comparing bytes four at a time +; instead of two at a time. It seems to be a tiny bit faster on +; average, but it's slower often enough that one can't generalize. +; +; This code currently assumes that function results are returned in D0 for +; all platforms. It assumes that args to functions are pushed onto the stack, +; last arg first. It also currently assumes that all C symbols have an +; underscore prepended when referenced from assembly. +; +; 1999/09/23: for Human68k: Modified by Shimazaki Ryo. + + IFNDEF CPU020 + IFNDEF CPUTEST +CPU000 equ 1 + ENDC + ENDC + +; Use these macros for accessing variables of type int: + IFDEF INT16 +MOVINT MACRO _1,_2 + move.w _1,_2 + ENDM +CLRINT MACRO _1 + clr.w _1 + ENDM +INTSIZE equ 2 + ELSE ; !INT16 +MOVINT MACRO _1,_2 + move.l _1,_2 + ENDM +CLRINT MACRO _1 + clr.l _1 + ENDM +INTSIZE equ 4 + ENDC + + IFDEF DYN_ALLOC +BASEPTR MACRO _1,_2 + move.l _1,_2 + ENDM + ELSE +BASEPTR MACRO _1,_2 + lea _1,_2 + ENDM + ENDC + +; constants we use, many of them adjustable: + +MAX_MATCH equ 258 +MIN_MATCH equ 3 +TOO_FAR equ 4096 + IFNDEF WSIZE +WSIZE equ 32768 + ENDC +WMASK equ WSIZE-1 +MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1 +MIN_LOOKAHEAD equ MAX_MATCH+MIN_MATCH+1 +; IFD BIG_MEM ; NOT supported -- type Pos needs to be 32 bits +;HASH_BITS equ 15 +; ELSE + IFDEF SMALL_MEM +HASH_BITS equ 13 + ELSE +HASH_BITS equ 14 ; default -- MEDIUM_MEM + ENDC +; ENDC ; BIG_MEM +HASH_SIZE equ 1< + MOVINT Strst,_strstart ; ct_tally reads this variable + moveq #0,d0 + move.b -1(Window,Strst.l),d0 + movem.l d2/a2,-(sp) + MOVINT d0,-(sp) + CLRINT -(sp) + jsr _ct_tally + addq #2*INTSIZE,sp + movem.l (sp)+,d2/a2 + tst.w d0 + beq.s skipliteral + FLUSH_B 0 + move.l Strst,_block_start +skipliteral: + addq.w #1,Strst + subq.w #1,Look + +refill: + cmp.w #MIN_LOOKAHEAD,Look + bhs look_loop + bsr fill_window + bra look_loop + +last_tally: + tst.w Avail + beq last_flush + MOVINT Strst,_strstart ; ct_tally reads this variable + moveq #0,d0 + move.b -1(Window,Strst.l),d0 + movem.l d2/a2,-(sp) + MOVINT d0,-(sp) + CLRINT -(sp) + jsr _ct_tally + addq #2*INTSIZE,sp + movem.l (sp)+,d2/a2 +last_flush: + FLUSH_B 1 + bra deflate_exit + +; ================== This is another version used for low compression levels: + +deflate_fast: + moveq #0,MatchL + moveq #MIN_MATCH-1,PrevL +flook_loop: + tst.w Look + beq flast_flush + + IN_STR a0,d0 + tst.w Head + beq.s fno_new_match + move.w Strst,d0 + sub.w Head,d0 + cmp.w #MAX_DIST,d0 + bhi.s fno_new_match + move.w PrevL,prev_length ; longest_match reads these variables + MOVINT Strst,_strstart + MOVINT Head,d0 ; parm for longest_match + bsr longest_match ; sets match_start + cmp.w Look,d0 ; does length exceed valid data? + bls.s fstml + move.w Look,d0 +fstml: move.w d0,MatchL ; valid length of match + +fno_new_match: + cmp.w #MIN_MATCH,MatchL + blo fliteral + ; CHECK_MATCH Strst,match_start,MatchL + MOVINT Strst,_strstart ; ct_tally reads this variable + move.l MatchL,d0 + subq.w #MIN_MATCH,d0 + movem.l d2/a2,-(sp) + MOVINT d0,-(sp) + move.l Strst,d0 + sub.w (match_start,pc),d0 + MOVINT d0,-(sp) + jsr _ct_tally ; sets d0 true if we have to flush + addq #2*INTSIZE,sp + movem.l (sp)+,d2/a2 + sub.w MatchL,Look + cmp.w (max_lazy_match,pc),MatchL + bhi ftoolong + subq.w #2,MatchL +finsertmatch: + addq.w #1,Strst + IN_STR a0,d1 ; preserve d0 + dbra MatchL,finsertmatch + moveq #0,MatchL ; not needed? + addq.w #1,Strst + bra.s flushfill + +ftoolong: + add.w MatchL,Strst + moveq #0,MatchL + moveq #0,d1 ; preserve d0 + move.b (Window,Strst.l),d1 + move.w d1,ins_h +; My assembler objects to passing <1(Window,Strst.l)> directly to UP_HASH... + move.b 1(Window,Strst.l),Avail ; Avail is not used in deflate_fast + UP_HASH d1,Avail ; preserve d0 + IFNE MIN_MATCH-3 + FAIL needs to UP_HASH another MIN_MATCH-3 times, but with what arg? + ENDC + bra.s flushfill + +fliteral: + TRACE_C <(Window,Strst.l)> + MOVINT Strst,_strstart ; ct_tally reads this variable + moveq #0,d0 + move.b (Window,Strst.l),d0 + movem.l d2/a2,-(sp) + MOVINT d0,-(sp) + CLRINT -(sp) + jsr _ct_tally ; d0 set if we need to flush + addq #2*INTSIZE,sp + movem.l (sp)+,d2/a2 + addq.w #1,Strst + subq.w #1,Look + +flushfill: + tst.w d0 + beq.s frefill + FLUSH_B 0 + move.l Strst,_block_start +frefill: + cmp.w #MIN_LOOKAHEAD,Look + bhs flook_loop + bsr fill_window + bra flook_loop + +flast_flush: + FLUSH_B 1 ; sets our return value + +deflate_exit: + MOVINT Strst,_strstart ; save back cached values + move.w PrevL,prev_length + move.w Look,lookahead + movem.l (sp)+,DEFREGS + rts + + +; ========================================================================= +; void fill_window(void) calls the input function to refill the sliding +; window that we use to find substring matches in. + +More reg Head ; local variable in fill_window +WindTop reg Prev ; local variable used for sliding +SlidIx reg PrevL ; local variable used for sliding + +FWREGS reg d2-d5/a2-a6 ; does NOT include Look and Strst +; all registers available to be clobbered by the sliding operation: +; we exclude More, WindTop, SlidIx, Look, Strst, Window, a4 and a7. +SPAREGS reg d0-d3/a0-a1/a5-a6 +SPCOUNT equ 8 ; number of registers in SPAREGS + + +_fill_window: ; C-callable entry point + movem.l Look/Strst,-(sp) + IFDEF INT16 + moveq #0,Strst ; Strst must be valid as a long + ENDC + MOVINT (_strstart,pc),Strst + move.w (lookahead,pc),Look + BASEPTR _window,Window + bsr.s fill_window + MOVINT Strst,_strstart + move.w Look,lookahead + movem.l (sp)+,Look/Strst + rts + +; strstart, lookahead, and window must be cached in Strst, Look, and Window: +fill_window: ; asm-callable entry point + movem.l FWREGS,-(sp) + move.w (eofile,pc),d0 ; we put this up here for speed + bne fwdone + and.l #$FFFF,Look ; make sure Look is valid as long +fw_refill: + move.l (_window_size,pc),More ; <= 64K + sub.l Look,More + sub.l Strst,More ; Strst is already valid as long + cmp.w #EOF,More + bne.s notboundary + subq.w #1,More + bra checkend + +notboundary: + move.w (sliding,pc),d0 + beq checkend + cmp.w #WSIZE+MAX_DIST,Strst + blo checkend + IF (32768-WSIZE)>0 + lea WSIZE(Window),WindTop ; WindTop is aligned when Window is + ELSE + move.l Window,WindTop + add.l #WSIZE,WindTop + ENDC + move.l Window,d0 + and.w #3,d0 + beq.s isaligned + subq.w #1,d0 +align: move.b (WindTop)+,(Window)+ ; copy up to a longword boundary + dbra d0,align +isaligned: +; This is faster than a simple move.l (WindTop)+,(Window)+ / dbra loop: + move.w #(WSIZE-1)/(4*SPCOUNT),SlidIx +slide: movem.l (WindTop)+,SPAREGS ; copy, 32 bytes at a time! + movem.l SPAREGS,(Window) ; a slight overshoot doesn't matter. + lea 4*SPCOUNT(Window),Window ; can't use (aN)+ as movem.l dest + dbra SlidIx,slide + BASEPTR _window,Window ; restore cached value + sub.w #WSIZE,match_start + sub.w #WSIZE,Strst + sub.l #WSIZE,_block_start + add.w #WSIZE,More + BASEPTR _head,a0 + move.w #HASH_SIZE-1,d0 +fixhead: + move.w (a0),d1 + sub.w #WSIZE,d1 + bpl.s headok + moveq #0,d1 +headok: move.w d1,(a0)+ + dbra d0,fixhead + BASEPTR _prev,a0 + move.w #WSIZE-1,d0 +fixprev: + move.w (a0),d1 + sub.w #WSIZE,d1 + bpl.s prevok + moveq #0,d1 +prevok: move.w d1,(a0)+ + dbra d0,fixprev + TRACE_C #'.' + + move _verbose+INTSIZE-2,d0 + beq checkend + movem.l d2/a2,-(sp) + xref _print_period + jsr _print_period + movem.l (sp)+,d2/a2 + +checkend: ; assert eofile is false + movem.l d2/a2,-(sp) + MOVINT More,-(sp) ; assert More's upper word is zero + move.l Strst,d0 + add.w Look,d0 + add.l Window,d0 + move.l d0,-(sp) + move.l _read_buf,a0 + jsr (a0) ; refill the upper part of the window + addq #4+INTSIZE,sp + movem.l (sp)+,d2/a2 + tst.w d0 + beq.s iseof + cmp.w #EOF,d0 + beq.s iseof + add.w d0,Look + cmp.w #MIN_LOOKAHEAD,Look + blo fw_refill ; eofile is still false + + bra.s fwdone +iseof: move.w #1,eofile +fwdone: movem.l (sp)+,FWREGS + rts + + +; ========================================================================= +; void lm_free(void) frees dynamic arrays in the DYN_ALLOC version. + +;;; xdef _lm_free ; the entry point + +_lm_free: + IFDEF DYN_ALLOC + move.l _window,d0 + beq.s lf_no_window + movem.l d2/a2,-(sp) + move.l d0,-(sp) + jsr _free + addq #4,sp + movem.l (sp)+,d2/a2 + clr.l _window +lf_no_window: + move.l _prev,d0 + beq.s lf_no_prev + movem.l d2/a2,-(sp) + move.l d0,-(sp) + jsr _free + move.l _head,(sp) ; reuse the same stack arg slot + jsr _free + addq #4,sp + movem.l (sp)+,d2/a2 + clr.l _prev + clr.l _head +lf_no_prev: + ENDC + rts + +; ============================================================================ +; void lm_init(int pack_level, unsigned short *flags) allocates dynamic arrays +; if any, and initializes all variables so that deflate() is ready to go. + +;;; xdef _lm_init ; the entry point + +Level reg d2 +;Window reg a2 ; as in deflate() + +_lm_init: + MOVINT 4(sp),d0 + move.l 4+INTSIZE(sp),a0 + move.w d0,Level + cmp.w #1,Level + blt.s levelerr + bgt.s try9 + bset.b #B_FAST,1(a0) +try9: cmp.w #9,Level + bgt.s levelerr + blt.s levelok + bset.b #B_SLOW,1(a0) + bra.s levelok +levelerr: + pea (level_message,pc) + jsr _error ; never returns +levelok: + clr.w sliding + move.l (_window_size,pc),d0 + bne.s gotawindowsize + move.w #1,sliding + move.l #2*WSIZE,_window_size +gotawindowsize: + + BASEPTR _window,Window + IFDEF DYN_ALLOC + move.l Window,d0 ; fake tst.l + bne.s gotsomewind + CAL_SH WSIZE + move.l d0,Window + move.l d0,_window + bne.s gotsomewind + pea (window_message,pc) + bra error +gotsomewind: + tst.l _prev + bne.s gotsomehead + CAL_SH WSIZE + move.l d0,_prev + beq.s nohead + CAL_SH HASH_SIZE + move.l d0,_head + bne.s gotfreshhead ; newly calloc'd memory is zeroed +nohead: pea (hash_message,pc) +error: MOVINT #ZE_MEM,-(sp) + jsr _ziperr ; never returns +gotsomehead: + ENDC ; DYN_ALLOC + + move.w #(HASH_SIZE/2)-1,d0 ; two shortwords per loop + BASEPTR _head,a0 +wipeh: clr.l (a0)+ + dbra d0,wipeh +gotfreshhead: + move.l Level,d0 + IFEQ Sizeof_config-8 + asl.l #3,d0 + ELSE + mulu #Sizeof_config,d0 + ENDC + lea (config_table,pc),a0 + add.l d0,a0 + move.w Max_lazy(a0),max_lazy_match + move.w Good_length(a0),good_match + move.w Nice_length(a0),nice_match + move.w Max_chain(a0),max_chain_len + CLRINT _strstart + clr.l _block_start + bsr match_init + + clr.w eofile + movem.l d2/a2,-(sp) + MOVINT #WSIZE,-(sp) ; We read only 32K because lookahead is short + move.l Window,-(sp) ; even when int size is long, as if deflate.c + move.l _read_buf,a0 ; were compiled with MAXSEG_64K defined. + jsr (a0) + addq #4+INTSIZE,sp + movem.l (sp)+,d2/a2 + move.w d0,lookahead + beq.s noread + cmp.w #EOF,d0 + bne.s irefill +noread: move.w #1,eofile + clr.w lookahead + bra.s init_done + +irefill: + move.w (lookahead,pc),d0 + cmp.w #MIN_LOOKAHEAD,d0 + bhs.s hashify + bsr _fill_window ; use the C-callable version +hashify: + clr.w ins_h + moveq #MIN_MATCH-2,d0 +hash1: move.b (Window)+,d1 + UP_HASH Level,d1 + dbra d0,hash1 + +init_done: + rts + +; strings for error messages: + IFDEF DYN_ALLOC +hash_message dc.b 'hash table allocation',0 +window_message dc.b 'window allocation',0 + ENDC +level_message dc.b 'bad pack level',0 + + end diff --git a/human68k/human68k.c b/human68k/human68k.c new file mode 100644 index 0000000..be47b57 --- /dev/null +++ b/human68k/human68k.c @@ -0,0 +1,371 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#include "zip.h" + +#include +#include +#include +#ifndef UTIL +#include +#endif + +#define MATCH shmatch + +#define PAD 0 + + +#ifndef UTIL + +/* Library functions not in (most) header files */ + +int utime OF((char *, ztimbuf *)); + +/* Local functions */ +local char *readd OF((DIR *)); + +local char *readd(DIR* d) +{ + struct dirent* e = readdir(d); + + return e == NULL ? NULL : e->d_name; +} + +int wild(char* w) +{ + struct _filbuf inf; + /* convert FNAMX to malloc - 11/08/04 EG */ + char *name; + char *p; + + if (strcmp(w, "-") == 0) /* if compressing stdin */ + return newname(w, 0, 0); + if ((name = malloc(strlen(w) + 1)) == NULL) { + ZIPERR(ZE_MEM, "wild"); + } + strcpy(name, w); + _toslash(name); + + if ((p = strrchr(name, '/')) == NULL && (p = strrchr(name, ':')) == NULL) + p = name; + else + p++; + if (_dos_lfiles (&inf, w, 0xff) < 0) { + free(name); + return ZE_MISS; + } + do { + int r; + + strcpy(p, inf.name); + r = procname(name, 0); + if (r != ZE_OK) { + free(name); + return r; + } + } while (_dos_nfiles(&inf) >= 0); + free(name); + + return ZE_OK; +} + +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 */ + _toslash(n); + 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 */ + + /* Find starting point in name before doing malloc */ + t = (x[0] && x[1] == (char)':') ? x + 2 : x; + while (*t == (char)'/') + t++; + + /* Make changes, if any, to the copied name (leave original intact) */ + _toslash(t); + + if (!pathput) + t = last(t, '/'); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + + if (dosify) + msname(n); + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosify; + 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; + return strcpy(x, n); +} + +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. */ +{ + ztimbuf u; /* argument for utime() */ + + /* Convert DOS time to time_t format in u */ + u.actime = u.modtime = dos2unixtime(d); + + /* Set updated and accessed times of f */ + utime(f, &u); +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + /* convert FNMAX to malloc - 11/8/04 EG */ + char *name; + int len = strlen(f); + isstdin = !strcmp(f, "-"); + + 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 (isstdin) { + 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) { + int atr = _dos_chmod(name, -1); + + if (atr < 0) + atr = 0x20; + *a = ((ulg)s.st_mode << 16) | (isstdin ? 0L : (ulg)atr); + } + free(name); + if (n != NULL) + *n = S_ISVOL(s.st_mode) ? -2L : S_ISREG(s.st_mode) ? s.st_size : -1L; + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_ctime; + } + + return unix2dostime(&s.st_mtime); +} + +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; + /* create extra field and change z->att if desired */ +{ +#ifdef USE_EF_UT_TIME + if ((z->extra = (char *)malloc(EB_HEADSIZE+EB_UT_LEN(1))) == NULL) + return ZE_MEM; + + z->extra[0] = 'U'; + z->extra[1] = 'T'; + z->extra[2] = EB_UT_LEN(1); /* length of data part of e.f. */ + z->extra[3] = 0; + z->extra[4] = EB_UT_FL_MTIME; + z->extra[5] = (char)(z_utim->mtime); + z->extra[6] = (char)(z_utim->mtime >> 8); + z->extra[7] = (char)(z_utim->mtime >> 16); + z->extra[8] = (char)(z_utim->mtime >> 24); + + z->cext = z->ext = (EB_HEADSIZE+EB_UT_LEN(1)); + z->cextra = z->extra; + + return ZE_OK; +#else /* !USE_EF_UT_TIME */ + return (int)(z-z); +#endif /* ?USE_EF_UT_TIME */ +} + +int deletedir(d) +char *d; /* directory to delete */ +/* Delete the directory *d if it is empty, do nothing otherwise. + Return the result of rmdir(), delete(), or system(). + For VMS, d must be in format [x.y]z.dir;1 (not [x.y.z]). + */ +{ + return rmdir(d); +} + +void print_period(void) +{ + fputc('.', stderr); +} + +#endif /* !UTIL */ + + +/******************************/ +/* Function version_local() */ +/******************************/ + +void version_local() +{ + static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n"; +#if 0 + char buf[40]; +#endif + + printf(CompiledWith, + +#ifdef __GNUC__ + "gcc ", __VERSION__, +#else +# if 0 + "cc ", (sprintf(buf, " version %d", _RELEASE), buf), +# else + "unknown compiler", "", +# endif +#endif + + "Human68k", +#ifdef __MC68020__ + " (X68030)", +#else + " (X680x0)", +#endif + +#ifdef __DATE__ + " on ", __DATE__ +#else + "", "" +#endif + ); + +} /* end function version_local() */ diff --git a/human68k/match.s b/human68k/match.s new file mode 100644 index 0000000..4e6bc1c --- /dev/null +++ b/human68k/match.s @@ -0,0 +1,163 @@ +*=========================================================================== +* 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 -- optional optimized asm version of longest match in deflate.c +* Written by Jean-loup Gailly +* +* Adapted for X68000 by NIIMI Satoshi +* Adapted for the Amiga by Carsten Steger +* using the code in match.S. +* The major change in this code consists of removing all unaligned +* word accesses, because they cause 68000-based machines to crash. +* For maximum speed, UNALIGNED_OK can be defined. +* The program will then only run on 68020-based machines, though. + + +Cur_Match reg d0 ; Must be in d0! +Best_Len reg d1 +Loop_Counter reg d2 +Scan_Start reg d3 +Scan_End reg d4 +Limit reg d5 +Chain_Length reg d6 +Scan_Test reg d7 +Scan reg a0 +Match reg a1 +Prev_Address reg a2 +Scan_Ini reg a3 +Match_Ini reg a4 + +MAX_MATCH equ 258 +MIN_MATCH equ 3 +WSIZE equ 32768 +MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1 + + + .xref _max_chain_length + .xref _prev_length + .xref _prev + .xref _window + .xref _strstart + .xref _good_match + .xref _match_start + .xref _nice_match + + + .xdef _match_init + .xdef _longest_match + + .text + .even + + +_match_init: + rts + + +_longest_match: + move.l 4(sp),Cur_Match +.ifdef UNALIGNED_OK + movem.l d2-d6/a2-a4,-(sp) +.else + movem.l d2-d7/a2-a4,-(sp) +.endif + move.l _max_chain_length,Chain_Length + move.l _prev_length,Best_Len + lea _prev,Prev_Address + lea _window+MIN_MATCH,Match_Ini + move.l _strstart,Limit + move.l Match_Ini,Scan_Ini + add.l Limit,Scan_Ini + subi.w #MAX_DIST,Limit + bhi.b limit_ok + moveq #0,Limit +limit_ok: + cmp.l _good_match,Best_Len + bcs.b length_ok + lsr.l #2,Chain_Length +length_ok: + subq.l #1,Chain_Length + +.ifdef UNALIGNED_OK + move.w -MIN_MATCH(Scan_Ini),Scan_Start + move.w -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End +.else + move.b -MIN_MATCH(Scan_Ini),Scan_Start + lsl.w #8,Scan_Start + move.b -MIN_MATCH+1(Scan_Ini),Scan_Start + move.b -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End + lsl.w #8,Scan_End + move.b -MIN_MATCH(Scan_Ini,Best_Len.w),Scan_End +.endif + + bra.b do_scan + +long_loop: + +.ifdef UNALIGNED_OK + move.w -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End +.else + move.b -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End + lsl.w #8,Scan_End + move.b -MIN_MATCH(Scan_Ini,Best_Len.w),Scan_End +.endif + +short_loop: + lsl.w #1,Cur_Match + move.w 0(Prev_Address,Cur_Match.l),Cur_Match + cmp.w Limit,Cur_Match + dbls Chain_Length,do_scan + bra.b return + +do_scan: + move.l Match_Ini,Match + add.l Cur_Match,Match + +.ifdef UNALIGNED_OK + cmp.w -MIN_MATCH-1(Match,Best_Len.w),Scan_End + bne.b short_loop + cmp.w -MIN_MATCH(Match),Scan_Start + bne.b short_loop +.else + move.b -MIN_MATCH-1(Match,Best_Len.w),Scan_Test + lsl.w #8,Scan_Test + move.b -MIN_MATCH(Match,Best_Len.w),Scan_Test + cmp.w Scan_Test,Scan_End + bne.b short_loop + move.b -MIN_MATCH(Match),Scan_Test + lsl.w #8,Scan_Test + move.b -MIN_MATCH+1(Match),Scan_Test + cmp.w Scan_Test,Scan_Start + bne.b short_loop +.endif + + move.w #(MAX_MATCH-MIN_MATCH),Loop_Counter + move.l Scan_Ini,Scan +scan_loop: + cmpm.b (Match)+,(Scan)+ + dbne Loop_Counter,scan_loop + + sub.l Scan_Ini,Scan + addq.l #(MIN_MATCH-1),Scan + cmp.l Best_Len,Scan + bls.b short_loop + move.l Scan,Best_Len + move.l Cur_Match,_match_start + cmp.l _nice_match,Best_Len + bcs.b long_loop +return: + move.l Best_Len,d0 +.ifdef UNALIGNED_OK + movem.l (sp)+,d2-d6/a2-a4 +.else + movem.l (sp)+,d2-d7/a2-a4 +.endif + rts + + end diff --git a/human68k/osdep.h b/human68k/osdep.h new file mode 100644 index 0000000..088a9ac --- /dev/null +++ b/human68k/osdep.h @@ -0,0 +1,28 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#include +#include +#include + +#ifdef ZCRYPT_INTERNAL +# include /* getpid() declaration for srand seed */ +#endif + +#define USE_CASE_MAP + +#define ROUNDED_TIME(time) (((time) + 1) & (~1)) + +#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \ + procname(n, 1)) + +#ifdef HAVE_MBCTYPE_H +# include +#else +# define ismbblead(c) (0x80 <= (c) && ((c) < 0xa0 || 0xe0 <= (c))) +#endif diff --git a/human68k/zipup.h b/human68k/zipup.h new file mode 100644 index 0000000..592cff8 --- /dev/null +++ b/human68k/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 (O_RDONLY|O_BINARY) +#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 diff --git a/macos/Contents b/macos/Contents new file mode 100644 index 0000000..3aec069 --- /dev/null +++ b/macos/Contents @@ -0,0 +1,63 @@ +Contents of the "macos" sub-archive for Zip 2.3 and later: + + +MacOS: + + Contents this file + readme.1st Instruction to unpack mac specific files + README.TXT Dirk Haase's infos on updated MacIntosh ports of Zip/UnZip + HISTORY.TXT Dirk Haase's MacOS specific ChangeLog + + zipup.h MacOS + osdep.h MacOS specific configuration and declarations + + ZipLib.h used to build a static library, global to the project + ZipSx.h used to build a standalone App with MW Sioux, global + to the project + ZpPrj.hqx Metrowerks CodeWarrior pro3 project file (BinHex) + + + source/ subdirectory containing all sources: + a) Zip specific code + extrafld.c contains all code related to the mac extra field + extrafld.h + macglob.h + macopen.c replaces fopen() and open() + macopen.h + macos.c Macintosh-specific routines for use with Info-ZIP's Zip + MatWild.c Pattern matching function + recurse.c Functions to go through the directories + recurse.h + unixlike.c This file provides a unix like file-stat routine + unixlike.h + VolWarn.h contains the warning message, about volumes with the + same name + zip_rc.hqx resource file for Macintosh unzip (BinHex) + + + b) general utilities shared between Zip and UnZip + charmap.h character mapping tables ISO 8859-1 <--> MacRoman + helpers.c some helper functions + helpers.h + macstuff.c Mac filemanager routines copied from MoreFiles 1.4.8 + macstuff.h + mactime.c replacement for broken Metrowerks RTL time functions + pathname.c functions for handling MacOS HFS path- /filenames + pathname.h + +The new ZpPrj.hqx project file should be "un-BinHex'ed" into ZpPrj, +which builds the following targets: + - Zip Lib (68K) -> static library 68k + - Zip Lib (PPC) -> static library PPC + - Zip Sioux (68K) -> MW Sioux standalone App, good for debugging + - Zip Sioux (PPC) -> MW Sioux standalone App, good for debugging + + +The resource files and the compiler project files are in BinHex form because +they contain Macintosh resource forks. The resource info cannot be +maintained when handling (e.g. repacking) the master source collection on +non-Macintosh systems. The BinHex form is the traditional way for +transferring such files via non-Macintosh systems. +It's also the safest since it uses only printable characters. The ".hqx" +files must be converted with StuffitExpander or BinHex 4.0 (or equivalent) +on a Macintosh system before using them. diff --git a/macos/HISTORY.TXT b/macos/HISTORY.TXT new file mode 100644 index 0000000..3a14a02 --- /dev/null +++ b/macos/HISTORY.TXT @@ -0,0 +1,600 @@ +A free Macintosh Port of Info-ZIP's +Zip and UnZip +By Dirk Haase, d_haase@sitec.net +Home page: www.sitec.net/maczip +Mirror page: +www.haase-online.de/dirk/maczip +================================ + + + + + +Release MacZip ver1.07 beta 1 +22. Februray 2001 +----------------- + +1) CHG: {unzip} switch to latest final release + unzip 5.42 + +2) CHG: {zip} switch to latest beta release + zip 2.40a + + + + + +Release MacZip ver1.06 final +22. Februray 2001 +----------------- + +1) CHG: {unzip} switch to latest final release + unzip 5.42 + +2) CHG: switch to latest release of Apples + Universal Interfaces 3.3.2 + +3) CHG: switch to latest release of + Morefiles 1.5 + + + + +Release MacZip ver1.06 beta 2 +02. August 2000 +--------------- + +1) CHG: {unzip} switch to latest beta release + unzip 5.42d + + + + + +Release MacZip ver1.06 beta 1 +27. July 2000 +------------- + +1) CHG: {zip} switch to latest beta release + unzip 2.30 + +2) CHG: {unzip} switch to latest beta release + unzip 5.42c + + + + + +Release MacZip ver1.05 final +27. July 2000 +------------- + +1) CHG: {unzip} switch to latest final release + unzip 5.41 + +2) FIX: {unzip} Fixed "unique unzip folder" foldername handling + +3) FIX: {unzip} added prototype crc32() in macbin3.c + +4) CHG: {unzip/zip} added exported Codewarrior project-file in xml-format + +5) ADD: {unzip} added extra-field recognition for Mac SmartZip in + zipinfo.c and unzpriv.h. + + + + + +Release MacZip ver1.04 final +25. January 2000 +---------------- + + +Final release of MacZip. All parts now +in final release state !! + +1) Switch to MW Codewarrior pro 5.3 + +2) CHG: {zip} switch (back) to latest final release + unzip 2.30 + +3) CHG: {unzip} switch (back) to latest final release + unzip 5.40 + + + + +Release MacZip ver1.04 beta 3 +05. October 1999 +---------------- + +1) CHG: {zip} switch to latest source level + unzip 2.30o beta release + +2) CHG: {unzip} switch to latest source level + unzip 5.41c beta release + +3) ADD: {console} added menu to print the license + + + + +Release MacZip ver1.04 beta 2 +02. June 1999 +-------------- + +1) FIX: {unzip} added one more criteria to make the recognition + of macbinary more save. + +2) FIX: {unzip} sometimes, archive entries without any extra field + caused problems; the default setting of the extra field + was not set back to 'unknown' properly. + +3) FIX: {zip} Archive filename with invalid characters like '/' gets + renamed. However, I do not check the complete path - needs + some more work here. + +4) FIX: {zip} Filename match was case sensitive. + +6) CHG: {zip} switch to latest source level + unzip 2.30m beta release + +7) CHG: {unzip} switch to latest source level + unzip 5.41b beta release + +8) FIX: {zip/unzip 68k only) I have found a wrong compiler setting + for the 68k version. Because of this wrong setting the 68k + version crashed. + + + + +Release MacZip ver1.04 beta 1 +30. March 1999 +-------------- + +1) CHG: {unzip) switch to latest source level + unzip 5.41a beta release + +2) ADD: {all} Added message logging support for Syslogd + by Brian Bergstrand. Syslogd can be found at + http://www.classicalguitar.net/brian/apps/syslogd/ + This feature is 'under construction'. + +3) FIX: {all} many small fixes and code cleanups + + + + +Release MacZip ver1.03 +27. March 1999 +-------------- + +1) CHG: {console} Like Stuffit Expander MacZip quits automatically when + used with drag'n drop or as Helper App (Web-Browser). + +2) CHG: {console} Since Macintosh users are used to be guided by their + software in order not to do something stupid, I added a check + to post an extra warning if the options -m and data fork only + are both checked. + This behavior can be disabled: See Applescript example and + "maczip.env". + +3) CHG: {zip} switch from immediate deletion to moving to the + trash. Immediate deletion is now an option in "maczip.env". + +4) CHG: {zip} enhanced progress display. + +5) CHG: {zip) switch to latest source level + zip 2.3l beta release + +6) CHG: {unzip} The zip archive contains file names greater than + 31 characters. When MacZip tries to unzip the file, the + FSpCreate command fails because the filename length is to + long. MacZip correct this problem by trying to truncate + the file names to the 31 character limit. + +7) FIX: {zip/console} A couple of minor fixes + +8) CHG: {zip} Switched file-globbing to the Info-ZIP version. + + + + +Release MacZip ver1.02 +14. February 1999 +----------------- + +1) CHG: {zip} Changed the rule of file inclusion if switch '-X' + is set. Following conditions are checked: + a) if length of resource-fork is equal zero *and* the + length of data-fork is equal zero include the file. + b) if length of resource-fork greater zero *and* the + length of data-fork is equal zero don't include the file. + c) if length of data-fork greater zero include the file. + +2) CHG: {Console} Some users are very confused by the buttons "START PATH" + and "ZIP ARCHIVE". Somehow, it wasn't clear what the intended + meaning was. I changed the buttons to more clear labels on + them like: "file or folder to compress" and "location of + compressed file" + +3) CHG: {Console} I changed the menu structure to be more intuitive. + +4) FIX: {Console} Found a nasty bug which sometimes caused crashes + when the Zip / Unzip Dialogbox was used. + +5) CHG: {Console} Handling of file dialog is now a bit more restricted: + e.g: it's not possible to select a file if you have to select + a folder. + + + + +Release MacZip ver1.01 +30. January 1999 +---------------------- + +1) CHG: {console} The use of the "Current App" mechanism was clumsy + and forces the user into the Zip or Unzip modes. This kind + of modality is not so good for the command line. It's now + neccessary to enter zip or unzip to choose the action. + +2) FIX: {console} When Applescript sends quit to MacZip the script + that is running shows a spinning cursor and MacZip + does not quit. + +3) FIX: {console} MacZip gots accidentally the wrong creator code + (from BBedit) + + + + +Final Release MacZip ver1.0 +--------------------------- + +Released 21. January 1999 + + + + +9. Beta release 06.December.1998 +--------------------------------- + +1) CHG: {console} The checkbox of Filedialog (for extract path and file path) + "Show all files" is now selected by default. + +2) CHG: {unzip/standalone} changed prototypes of mac[f]printf() to return + an int number (better ANSI conformance); + +3) FIX: {unzip} repaired "stdout/stderr" mode of macwrite(). So func + MacMessagePrnt() is now obsolete and removed. + +4) ADD: {zip/unzip} Compressed Mac3 extra-fields are now supported + (Thanks to Christian Spieler) + +5) ADD: {unzip} Extraction of ZipIt archive are now supported. This support + is not complete: Filenames are correct but folder names are only + restored with the public directory names. + +6) ADD: {zip/unzip} Improved documentation. + +7) FIX: {unzip} Function isZipfile() is completely rewritten. + +8) CHG: {zip/unzip) switch to latest source level + zip 2.3i beta and unzip 5.4 final release + +9) ADD: Applescript event "do_cmd". + +Unless there are big bugs found, this release will be the last +beta release. The final release will come out in January 1999. + + + + +8. Beta release 20.November.1998 +--------------------------------- + +1) CHG: {zip/unzip) switch to latest source level + zip 2.3h beta and unzip 5.4 final release + +2) ADD: {zip} Zip finds "namelocked" files also, if switch "-S" + is set. + +3) FIX: {unzip} Function isZipfile() fails if the zip archive + has a comment. + +4) CHG: {zip} added some small speed improvements to pattern matching and + isZipFile() function. + +5) FIX: {unzip} Display of comments is fixed. + UzpMessagePrnt() is replaced by MacMessagePrnt(). I do not care + about ansi-bombs. I'm not sure, so this fix may be changed later. + +6) RMV: {unzip} Buildin More capability is removed since it's already built + into the GUI-App. + + + +7. Beta release 09.November.1998 +--------------------------------- + +1) CHG: {all} switched to Metrowerks Codewarrior Pro 4 + +2) FIX: {unzip} Display of comments stored in the zip-file is + now fixed + +3) FIX: {zip} Fixed display of the zip help-screen. + +4) CHG: {zip/unzip} Changed special dir 'Re$0urce.Fk' to 'XtraStuf.mac' + (see entry at 13.June.1998 item 3). I found it more descriptive for + users outside the mac-community. + +5) CHG: {all} switched to MoreFiles 1.4.9. + +6) CHG: {console} changed behaivor of the file open dialog: The select + button is now always enabled. + +7) ADD: {all} Environment variables are now supported. + Basically, it is possible to add timezone (= TZ environment variable) + support here, but it's not yet implemented. + See "MacZip.Env" for further info. + +8) RMV: {console} Targets "zip only" and "unzip only" are removed. + + + +6. Beta release 09.September.1998 +--------------------------------- + + +1) CHG: {Zip/Unzip} Metrowerks Standardlibrary time funktions are + rather broken and incomplete so I was forced to rewrite the + funktions: mktime(), localtime(), gmtime() and time(). + +2) ADD: {Console} Added Pause Funktion for screen output. + The Pause-Function is selfadjusting: Count of lines is depending + on the window size. + +3) CHG: Extra-Field layout is changed: All datas are now in little-endian + format (see appnote) + +4) ADD: {Console} Added an option to test the archive automatically + after zipping. This option is only via Zip-Dialogbox available + because it needs the unzip-module also. + +5) CHG: {Zip} code is now up to date with the latest beta 2.3f. + +6) ADD: {Console} Added (drag'n) drop support. Drop on the MacZip icon. + The following situations are supported: + 1. drop of one or more zipfiles (action = unzip) + each archive will be extracted in a separate folder + 2. drop of a folder (action = zip -r ) + The complete folder (inclusive sub-folders) + will be zipped + Not (yet) supported is currently: dropping more than one file + to compress. Workaround: Put all your files in one folder and + drop that folder on MacZip. + MacZip recognize zip-archives automatically. + + +5. Beta release 21.Aug.1998 +---------------------------- + + +1) ADD: {Console} Userinterface has now a Statusbar to show the + Progress. + +2) ADD: {Console} It's now possible to stop the run of Zip/Unzip + with the well known shortcut [Command] + [.] + +3) CHG: {Console} Improved user-entry routine. + +4) ADD: {Zip/Unzip} Crypt-code added. It's now possible to + encrypt/decrypt archives. + +5) RMV: {Unzip} Removed the warning of PKZip/Mac archive. + Unzip gets confused with the extra field of PKZip/Mac. So I assume + the extra field isn't compatible with Info-ZIP's definition. + +6) CHG: switched to Metrowerks Codewarrior Pro 3 + this includes: + - new Universal Interfaces 3.1 Headers + - improved codegeneration + +7) CHG: {Zip} code is now up to date with the latest beta 2.3e. + +8) CHG: {Unzip} changed function names wprintf, wgets .. to macprintf, macgets .. + to avoid naming conflict standart library. + +9) ADD: {Zip/Unzip} FXinfo, Mac-Pathname, file-dates and Finder-Comments + are now stored in the extra-field. Extra-field layout is + changed accordingly. Unzip uses now the filename stored in the + extra-field when unzipping. + +10) CHG: {Unzip} code is now up to date with the latest beta 5.33g. + +11) CHG: {Unzip} code is (again) up to date with the latest beta 5.33h. + +12) ADD: {Unzip} following switches were added: + -J [MacOS only] ignore mac extra info. All macintosh + info are not restored. Datafork and resource-fork + are restored separatly. + + -i [MacOS only] ignore filenames stored in mac extra + field. Use the most compatible filename stored in + the public field. + + -E [MacOS only] show mac extra field during restoring + +13) ADD: {Zip/Unzip} Charset MacRoman to ISO8859 Latin and vice versa + +14) RMV: {Zip} -N option removed. This MacZip crashes using this option. + I will fix it later. + + +I think I'm very close for a final release of "MacZip 1.0" :-) + + + +4. Beta release 27.June.1998 +---------------------------- + +26.June.1998 +------------ + +1) FIX: {Zip} extra field size value was wrong. + + + +25.June.1998 +------------ + +1) CHG: {Zip} code is now up to date with the latest beta 2.3d. + So both modules, zip & unzip, uses now latest beta. + +2) ADD: {Zip} added a UT extra-field for better compatibility. + +3) CHG: {Unzip} changed the code to find the mac extra-field. + Unzip has to look for a mac extra-field because + mac-archives has now two extra-fields (UT + M3). + +4) CHG: {Unzip} changed the method to move extra-field data to + the internal extra-structure. + Old method was just BlockMove of the ef_structptr to ef_memptr. + This method was dangerous because not all members of the + structure seamless aligned. There are may be some fill + bytes in the structure depending on the compiler setting. + +5) ADD: {Unzip} added a warning if unzipping a ZipIt/PKZip archive. + ZipIt/PKZip archives are usually additionally coded somehow. + InfoZip's Unzip will *not* decode the files. So extracted + files are may be not decoded. (see also 6. and 7.) + +6) ADD: ZipIt (the Shareware Tool) has now a new extra-field signature: + 0x2705. Found in "ZipIt 1.3.8". I added a new macro: EF_ZIPIT2 + +7) ADD: Added PKWare's extra-field signature: 0xCF77. + Found in "PKZIP v2.03". I added a new macro: EF_PKMAC + +8) ADD: {console} It's now possible to save all screen outputs + to the disk. + +9) RMV: {console} this is the first beta without expire-date. + + +16.June.1998 +------------ + +1) FIX: {Unzip/console} Extract path now defaults to current-dir if + no path is given. + +2> CHG: {Unzip} creates now a extract-folder by default. This behavior + differs to the commandline tool of Unzip on other platforms. + However, for a mac-user is this behavior more convenient. + + +3. Beta release 15.June.1998 +---------------------------- + +15.June.1998 +------------ + +1) CHG: {unzip/zip} I changed the layout of the extra field + to support more data. + + +14.June.1998 +------------ + +1) FIX: {Unzip} adjusted time_t value with an correct offset value. + +2) FIX: {Unzip} removed all unused code based on unfinished ideas by + former porter(s). + +3) CHG: use of shared code izshr 032. + +13.June.1998 +------------ + +1) FIX: {Unzip} Filenames are only converted when needed. When zipping + with the switch 'datafork only' the filenames are shorted which + was wrong. + +2) CHG: {Unzip} code is now up to date with the latest beta 5.33f. + +3) CHG: {Zip} Changed the naming rule of filenames from old Johnny Lee's + to my implementation. Johnny Lee's idea is based on change of the + filenames which cases several problems when unziping on a non mac + plattform. My idea is to add a special directory: 'Re$0urce.Fk'. + For the future: Zip will create archives according the new nameing + rule. However unzip will be compatible with old nameing rule. + See also 4. + +4} ADD: {Unzip} Added a new nameing rule for resource forks filename. + Resource forks are now stored in a special directory: 'Re$0urce.Fk'. + This naming rule make it easier to for other platforms to use + mac zip-files. + + + +11.June.1998 +------------ +1) FIX: {Zip} Internal file attribute is set to BINARY by default + when zipping resource forks otherwise Unzip will create + sometimes wrong resource-forks. + +2) CHG: {Unzip} code is now up to date with the latest beta 5.33e. + + + + +2. Beta release 10.June.1998 +-------------------------- + +1) FIX: {Unzip} Long pathname fix solved. Unzip is now able to extract + archives with path longer than 256 chars. + +2) CHG: {Unzip} removed all conversion from c-style string to + pascal-string (see fix 1) + +3) ADD: {Unzip} Finderinfo of folders are also restored. + +4) ADD: {Console} Added info about current path in the command-line box. + +5) FIX: {Console} Construction of the command-line of the unzip-dialog + box fixed. + + + +First beta release 06.June.1998 +----------------------------- + +no history. +Just to many code was neccessary to build the first mac-port. + + +Start of the port MacZip +February 1998 + + +-------------------------------------------------------------------------------- +Legende: + +FIX: fixes a bug +CHG: inform about changed items. +ADD: added feature +RMV: removed Item + +{Unzip} -> only related to the Unzip-module +{Zip} -> only related to the Zip-module + These are just libraries and are linked into the console-app. + +{Console} -> only related to the Userinterface (not SIOUX) + MacOS has no tool like a command-line. So it's neccessary + to write wrapper around the command-line tools. + + + + +Dirk Haase diff --git a/macos/README.TXT b/macos/README.TXT new file mode 100644 index 0000000..839658d --- /dev/null +++ b/macos/README.TXT @@ -0,0 +1,569 @@ +A free Macintosh Port of Info-ZIP's +Zip and UnZip +By Dirk Haase, d_haase@sitec.net +Home page: www.sitec.net/maczip +Mirror page: +www.haase-online.de/dirk/maczip +================================ + + + +Abstract: +--------- +MacZip is a cross-platform compatible tool that includes +both Zip (for compression) and UnZip (for extraction). + +Zip is a compression and file packaging utility for Unix, +VMS, MSDOS, OS/2, Windows 9x, Windows NT, Atari, Macintosh, +Amiga, Acorn RISC OS, and other systems. + +UnZip unpacks zip archives. The Zip and UnZip programs can +process archives produced by PKZIP, and PKZIP and PKUNZIP +can work with archives produced by zip. Zip version 2.2 is +compatible with PKZIP 2.04. + +If you are new to MacZip please read first the file +"ReadMe.1st". + + + +License: +-------- + Copyright (c) 1990-2001 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in unzip.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 + + + +Requirements +------------ +MacZip requires at least System 7 and a Macintosh with a +minimum of a Motorola 68020 or PowerPC 601 processor. Other +configurations may work but it is not tested at all. + +The application is distributed as a fat binary with both +regular 68K and native PowerPC versions included. + + + +Installation +------------ +Move the executable(s) somewhere--for example, drag it (or +them) to your Applications folder. For easy access, make an +alias in the Launcher Control Panel or directly on your +desktop. The GUI is very simple. It was not my intention to +make a full-blown GUI, however I think it is comfortable +enough to use it as regular tool. + +This port supports also Apple-event. So you can install it +in your WWW-Browser as a helper app. + +For more Info about the contents of this package, take a +look into the "macos/Contents" (or :macos:Contents) file. +Some notes on how to rebuild the Macintosh applications can +be found in INSTALL. + + + +Usage: +------ + +Basically there are four ways to start MacZip: + +a) Drag'n Drop +b) using the Dialog box (Menu: File -> Zip/Unzip): + +Please read the file "ReadMe.1st" +for the description of the items a and b. + +c) Using the Command line (Menu: File->Command Line): + The Zip & UnZip tools are command line tools. So the + behavior is exactly the same like the Zip & UnZip tools on + Unix or Windows/DOS. This means, if you want to zip some + files, you have to write a command line like this: "zip + [switches] path_to_zip_archive path_to_files_folders" + + - Go to "File", select "Command Line" and the + "MacZip Entry box" Dialog Box appears. + + An example: + + a: your zip may be created at + Macintosh HD:applications:archive.zip + + b: your files may be found at + Macintosh HD:somewhere:my_folder_to_archive:* + + Note: At the end of the path there must be a filename or + a wild card ! + (see Footnotes: 1 wild card, 2 Mac path names) + + So the command line should look like (one line!): + + zip "Macintosh HD:applications:archive.zip" "Macintosh HD:somewhere:my_folder_to_archive:*" + + - Click on "Enter" to start the task. + + Since you can not set a default folder you have to enter + always a full qualified path names. Full-qualified path + names are path names including the Volume name ! (see + Footnote: 2 Mac path names) + + + +d) Using Applescript: + +There is only one additional event defined: "do_cmd". You +can enter every valid command line. The first word must be +"zip" or "unzip" to select the action (compress or +extraction). + +See sample Applescript: + + tell application "MacZip (PPC)" + activate + with timeout of 90000 seconds + do_cmd "zip -rjjN Volume:archive \"My Volume:*\" " + end timeout + end tell + +This script opens MacZip, brings it to the foreground on the +Mac, starts the zip action with the command line: zip -rjjN +Volume:archive "My Volume:*" . + + +A short introduction is also available online: +http://www.sitec.net/maczip/How-To-Do/ + +It's possible to stop the run of Zip/Unzip with the well +known shortcut [Command] + [.]. + + +--------------------------------------------------------------------------- + +There are some Mac-specific switches available. +Zip Module: + -df [MacOS] Include only data-fork of files zipped into + the archive. Good for exporting files to foreign + operating-systems. Resource-forks will be ignored + at all. + + -jj [MacOS] record Fullpath (+ Volname). The complete + path including volume will be stored. By default + the relative path will be stored. + + -S [MSDOS, OS/2, WIN32 and ATARI] Include system and + hidden files. + [MacOS] Includes finder invisible files, which are + ignored otherwise. + +Unzip Module: + -E [MacOS only] display contents of MacOS extra field + during restore operation. + + -i [MacOS only] ignore filenames stored in MacOS extra + fields. Instead, the most compatible filename + stored in the generic part of the entry's header is + used. + + -J [MacOS only] ignore MacOS extra fields. All Macin- + tosh specific info is skipped. Data-fork and + resource-fork are restored as separate files. + + +Select [File]->[Get Help on Zip/Unzip] for a complete list +of switches. + + + +Limitations / Problems: +----------------------- + + - Aliases are not supported. I tried, but I got broken + aliases. This port will silently ignore all aliases. + It's on my to-do list for future releases. + + - Zip needs much memory to compress many files: You may need + to increase the 'Preferred Size' in 'Get Info'. Values of 12 + Megabytes or more are possible + + - Unzip needs about 500 Kbytes of memory to unzip no matter + how many files were compressed and expanded. + + - and finally one big macintosh-related problem: + This port has one weak point: It's based on path names. + As you may be already know: Path names are not unique on a Mac ! + The main reason is that an attempt to implement support exact + saving of the MacOS specific internal file structures would + require a throughout rewrite of major parts of shared code, + probably sacrifying compatibility with other systems. I have + no solution at the moment. The port will just warn you if you + try zip from / to a volume which has a duplicate name. + MacZip has problems to find the archive or the files. My + (Big) recommendation: Name all your volumes with a unique + name and MacZip will run without any problem. + + +Known Bugs: + + - crypted files in a zip archive are sometimes corrupt: + I get an error message: invalid compressed data to inflate. + Appearance of this error is purely be chance: I did a small + test: Unzipping an archive containing 3589 files 56 files + fails to unzip, so about 1.5%. Root cause is completely + unclear to me :( + +I strongly recommend to test your archive (e.g. unzip -t archive). + + + + + +Zip Programs / Macintosh Extra-Data: +----------------------------------------- +A brief overview: +Currently, as far as I know, there are 6 Zip programs +available for the Macintosh platform. These programs build +(of course) different variants of Zip files: + + - Info-ZIP's first Port of Zip. Ported by Johnny Lee + This port is rather outdated and no longer supported (since 1992). + 68K only. Only minimal Mac-info is stored + (Creator/Type, Finder attributes). Creator/Type: '????' / '????' + Until year 1998, only UnZip 5.32 survived. + + - ZipIt by Tom Brown. This is Shareware and still supported I think. + ZipIt has a nice GUI, but I found it can't handle large Zip files + quite well. ZipIt compresses Macintosh files using the Mac Binary + format. So, transferring files to other platforms is not so easy. + Only minimal Mac-info is stored (Creator/Type, Finder attributes). + Mac filenames are changed to a most compatible filename. + Creator/Type: 'ZIP ' / 'ZIP ' + + - PKZIP/mac v2.03/210d. This is Shareware. + This Zip implementation for the Mac can be found on ASI's web site + (http://www.asizip.com/products/products.htm). The name of this + program is misleading, it is NOT a product from PKWARE. ASI's last + release version is v2.03, and they also offer a newer beta version + PKZIP/mac 210d. But even the Beta version is rather outdated (1995). + Only minimal Mac-info is stored (Creator/Type, Finder attributes). + The Zipfile format looks like incompatible to other platforms. + (More details about the compatibility issue can be found in + proginfo/3rdparty.bug!). Type: 'PKz1' + Mac filenames are restored without any change. + + - Aladdin DropZip 1999, This is Shareware. Aladdin chose + the format of ZipIt. Therefore, it has the some drawbacks + like ZipIt. + Creator/Type: 'SITx' / 'ZIP ' + + - SmartZip 1.0 1999 - by Marco Bambini Vampire Software. + This is Shareware. SmartZip compresses Macintosh files using the + Mac Binary. Therefore, it has the same drawbacks like ZipIt. + Creator/Type: 'dZIP' / 'ZIP ' + +and finally: + - Info-ZIP's latest Port of Zip. MacZip 1.0. Ported by me :-) + It is supported (of course) and up to date. Full set of macintosh + info is stored: Creator/Type, Finder attributes, Finder comments, + MacOS 8.0 Folder settings, Icon/Folder Positions ... + Mac filenames are restored without any change. + Creator/Type: 'IZip' / 'ZIP ' + + +Compatibility of my port; Extraction: + - Archives from Info-ZIP's first port (by Johnny Lee) are + still compatible. + - Extraction of ZipIt archives is supported. This support + is not complete: Filenames are correct but Directory names + are sometimes mangled to a DOS compatible form. Segmented + archives are not supported. + - PKZiP/mac archive files are extracted without resource-forks + and without any Finder info. I have no information about + that zip format. + +Compatibility of my port; Compression: + - My port supports only the new Info-ZIP format (introduced + with this port). Therefore archives created by MacZip 1.0 + (March 1999) must be extracted with this version or later + releases of Info-ZIP's UnZip to restore the complete set of + Macintosh attributes. + +Note: This port is complete unrelated to the shareware ZipIt. +Even more, handling of special Macintosh attributes is +incompatible with ZipIt. This port (MacZip) may be used to +extract archives created by ZipIt, but make sure that you +get the result as you expected. + + + +Macintosh Files; File Forks: +---------------------------- + +All Macintosh files comprise two forks, known as the data +fork and the resource fork. Unlike the bytes stored in the +resource fork, the bytes in the data fork do not have to +exhibit any particular internal structure. The application +is responsible for interpreting the bytes in the data fork +in whatever manner is appropriate. The bytes in the resource +fork usually have a defined internal structure and contain +data object like menus, dialog boxes, icons and pictures. +Although all Macintosh files contain both a data fork and a +resource fork, one or both of these forks may be empty. + +MacZip stores data-forks and resource-forks separately. The +Zipfile format does not allow to store two archive entries +using exactly the same name. My solution is to modify the +Path name of the resource-fork. All resource-fork names are +prepended with a leading special directory named +"XtraStuf.mac". So, when extracting on a Mac, you should +never see this directory "XtraStuf.mac" on your *disk*. + +On all foreign systems that support directories in filenames +(e.g.: OS/2, Unix, DOS/Windows, VMS) you will get a +directory "XtraStuf.mac" when extracting MacZip archives. +You can delete the complete directory "XtraStuf.mac" since +Mac resources do not make much sense outside the MacOS +world. + + + +Text encoding; Charsets of the Filenames: +----------------------------------------- + +The following information is only important if you plan to +transfer archives across different platforms/language systems: + +A typical Zip archive does not support different charsets. +All filenames stored in the public area (= accessible by +foreign systems other than MacOS) must be coded in the +charset ISO-8859-1 (CP1252 in the Microsoft Windows world) +or CP850 (DOSLatin1). The latter should only be used by Zip +programs that mark the archive entries as "created under +DOS". Apart from Macs, the commonly used platforms either +support ISO-8859-1 directly, or are compatible with it. To +achieve maximum compatibility, MacZip convert filenames from +the Mac OS Roman character set to ISO-8859-1 and vice versa. +But not every char of the charset MacRoman has their +equivalent in ISO-8859-1. To make the mapping in most cases +possible, I chose most similar chars or at least the MIDDLE +DOT. + +Mac OS Roman character set is used for at least the +following Mac OS localizations: U.S., British, Canadian +French, French, Swiss French, German, Swiss German, Italian, +Swiss Italian, Dutch, Swedish, Norwegian, Danish, Finnish, +Spanish, Catalan, Portuguese, Brazilian, and the default +International system. + +In all Mac OS encodings, character codes 0x00-0x7F are +identical to ASCII, except that + - in Mac OS Japanese, yen sign replaces reverse solidus + - in Mac OS Arabic, Farsi, and Hebrew, some of the + punctuation in this range is treated as having strong + left-right directionality, although the corresponding + Unicode characters have neutral directionality +So, for best compatibility, confine filenames to the standard +7-bit ASCII character set. + +If you generate a filename list of your archive (unzip -l), +you will see the converted filenames. Your can also extract +the archive with the switch '-i' (= ignore mac filenames), +and test your result. + +This MacZip port uses its own filename stored in the +archive. At the moment, the filename will be not converted. +However, I'm planning to add support for Unicode. + +Currently, the following Mac OS encodings are NOT supported: +Japanese, ChineseTrad, Korean, Arabic, Hebrew, Greek, +Cyrillic, Devanagari, Gurmukhi, Gujarati, Oriya, Bengali, +Tamil, Telugu Kannada, Malayalam, Sinhalese, Burmese, Khmer, +Thai, Laotian, Georgian, Armenian, ChineseSimp, Tibetan, +Mongolian, Ethiopic, Vietnamese, ExtArabic and finally: +Symbol - this is the encoding for the font named "Symbol". +Dingbats - this is the encoding for the font named "Zapf Dingbats". +If you extract an archive coded with one of these +charsets you will probably get filenames with funny +characters. + +These problems apply only to filenames and NOT to the file +content. +of course: The content of the files will NEVER be converted !! + + + +File-/Creator Type: +------------- + +This port uses the creator type 'IZip' and it is registered +at Apple (since 08. March 1998). File types can not be +registered any more. This port uses 'ZIP ' for Zip archive +files. The creator 'IZip' type should be used for all future +versions of MacZip. + + + +Hints for proper restoration of file-time stamps: +------------------------------------------------- + +UnZip requires the host computer to have proper time zone +information in order to handle certain tasks correctly (see +unzip.txt). To set the time zone on the Macintosh, go to +the Map Control Panel and enter the correct number of hours +(and, in a few locales, minutes) offset from Universal +Time/Greenwich Mean Time. For example, the US Pacific time +zone is -8 hours from UTC/GMT during standard (winter) time +and -7 hours from UTC/GMT during Daylight Savings Time. The +US Eastern time zone is -5 hours during the winter and -4 +hours during the summer. + +Discussion of Daylight Savings Time +----------------------------------- +The setting in the Date & Time control panel for Daylight +Savings time is a universal setting. That is, it assumes +everybody in the world is observing Daylight Savings time +when its check box is selected. + +If other areas of the world are not observing Daylight +Savings time when the check box is selected in the Date & +Time control panel, then the Map control panel will be off +by an hour for all areas that are not recognizing Daylight +Savings time. + +Conversely, if you set the Map control panel to an area that +does not observe Daylight Savings time and deselect/uncheck +the check box for Daylight Savings time in the Date & Time +control panel, then time in all areas celebrating Daylight +Savings time will be off by an hour in the Map control +panel. + +Example: + In the case of Hawaiians, sometimes they are three hours + behind Pacific Standard Time (PST) and sometimes two hours + behind Pacific Daylight Time (PDT). The Map control panel + can only calculate differences between time zones relative + to Greenwich Mean Time (GMT). Hawaii will always show up as + three hours past the Pacific time zone and five hours past + the Central time zone. + + When Hawaiians are not observing Daylight Savings time, but + the rest of the country is, there is no combination of + settings in Map and Date & Time control panels which will + enable you to display Hawaiian local time correctly AND + concurrently display the correct time in other places that + do observe Daylight Savings time. + + The knowledge about which countries observe Daylight Savings + time and which do not is not built into the Map control + panel, so it does not allow for such a complex calculation. + + This same situation also occurs in other parts of the world + besides Hawaii. Phoenix, Arizona is an example of an area of + the U.S. which also does not observe Daylight Savings time. + +Conclusion: +MacZip only knows the GMT and DST offsets of the +current time, not for the time in question. + + +Projects & Packages: +-------------------- + +A Note to version numbers: Version of MacZip is currently +1.06 and is based on the zip code version 2.3 and unzip code +version 5.42. See About Box for current version and compiler +build date. + +Because of the amount of sources I splitted this port into +several projects. See http://www.sitec.net/maczip for +updates. + +- core source parts: + unzxxx.zip + zipxxx.zip + These archives contains the main parts of the port. You can + build libraries and a standalone App with Metrowerks + standard console SIOUX. They contain only sources, no + executables. These archives are exact copies of the standard + Info-ZIP source distributions; they were only repackaged + under MacOS using MacZip, with one minor addition: For those + files that are stored in BinHex'ed format in the Info-ZIP + reference source archives, unpacked version that are ready + for use have been added. + +- additional source part: + MacZipxxx.zip: contains all the GUI stuff and the project + files to build the main-app. Only sources of the GUI, no + zip or unzip code. To build MacZip successfully you will + need to also download the zip and unzip packages. + +- executables: + MacZipxxxnc.hqx: contains only executables and 'README.TXT', + This version is without en-/decryption support ! + MacZipxxxc.hqx: contains only executables and 'README.TXT', + This version supports en-/decryption ! + +- encryption sources: + zcryptxx.zip: To build crypt versions of MacZip. + download from ftp://ftp.icce.rug.nl/infozip/ (and subdirectories) + +- documentation: + MacZipDocu.zip: contains some further docus about the algorithm, + limits, Info-ZIP's appnote and a How-to-do Webpage. + + +Credits: +-------- + +Macstuff.c and recurse.c: All the functions are from More Files. +More Files fixes many of the broken or underfunctional parts of +the file system. Thanks to Jim Luther. (see morefiles.doc) + + + + +--------------------------------------------------------------------------- +Footnotes: + +1. wild card: + The '*' is a wild card and means 'all files' + Just in case you don't know wild cards: + '*' is a place holder for any character. + e.g.: + "this*" matches with "this_file" or "this_textfile" but it + doesn't match with "only_this_file" or "first_this_textfile" + "*this*" matches with "this_file" or "this_textfile" AND + matches with "only_this_file" or "first_this_textfile" + + +2. Mac pathnames: +The following characteristics of Macintosh pathnames should +be noted: + + A full pathname never begins with a colon, but must contain + at least one colon. + A partial pathname always begins with a colon separator except + in the case where the file partial pathname is a simple file or + directory name. + Single trailing separator colons in full or partial pathnames + are ignored except in the case of full pathnames to volumes. + In full pathnames to volumes, the trailing separator colon is + required. + Consecutive separator colons can be used to ascend a level + from a directory to its parent directory. Two consecutive + separator colons will ascend one level, three consecutive + separator colons will ascend two levels, and so on. Ascending + can only occur from a directory; not a file. + + + + + +--------------------------------------------------------------------------- + +Dirk Haase +========== diff --git a/macos/ZipLib.h b/macos/ZipLib.h new file mode 100644 index 0000000..e3dacf3 --- /dev/null +++ b/macos/ZipLib.h @@ -0,0 +1,166 @@ +/* + 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 +*/ +/*--------------------------------------------------------------------------- + + ZipLib.h + + This header-files is global to the project ZipLib. + + ---------------------------------------------------------------------------*/ + + + +/*****************************************************************************/ +/* Macros, typedefs */ +/*****************************************************************************/ + +#define MACOS +#define MACZIP + +#define OLDROUTINENAMES 0 /* use new function names only */ +#define OLDROUTINELOCATIONS 0 /* use new headerlocations only */ +#define SystemSevenOrLater 1 /* Runs only on System 7.0 or later */ + +/* These functions are defined as a macro instead of a function. +so we have to undefine them for replacing (see printf.c) */ +#undef getc +#undef getchar +#undef putchar +#undef putc + +#ifndef ZCONST +# define ZCONST const +#endif + +#define NAME_MAX 1024 + + +/*****************************************************************************/ +/* Includes standard headers */ +/*****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Many things are different for mac-users, so we need + special mac functions :-) */ +int Zmacstat (const char *path, struct stat *buf); +#define stat(path, bufPtr) Zmacstat(path, bufPtr) +#define lstat(path, bufPtr) Zmacstat(path, bufPtr) + +int fprintf(FILE *file, const char *format, ...); +int printf(const char *format, ...); +void perror(const char *parm1); + + + +/* +#define MAC_DEBUG 1 +#define DEBUG 1 + */ + + +#ifdef MAC_DEBUG +#define LOG_DEBUG 7 /* debug-level messages */ +int Print2Syslog(UInt8 priority, const char *format, ...); +#include + + +#define Notify(msg) \ + { \ + (void)Print2Syslog(LOG_DEBUG, "%s (file: %s line: %d)", \ + msg, __FILE__, __LINE__); \ + } + + + + +#define Assert_it(cond,msg,kind) \ + { \ + if (!(cond)) \ + { \ + (void)Print2Syslog(LOG_DEBUG,"%s failed: [%s] cond: [%s] (file: %s line: %d)", \ + kind, msg, #cond, __FILE__, __LINE__); \ + } \ + } + + + + + +#define AssertBool(b,msg) Assert_it (((b) == TRUE) || ((b) == FALSE),(msg),("AssertBool ")) + + + +#define AssertStr(s,msg) \ + { \ + int s_i = 0; \ + Assert_it ((s),(msg),("1. AssertStr ")); \ + while ((s)[s_i]) { \ + Assert_it ((!iscntrl((s)[s_i]) || ((s)[s_i] == 0x0A) || \ + ((s)[s_i] == 0x0D)),(s),("2. AssertStr ")); \ + s_i++; \ + } \ + } + + + +#define AssertTime(t,msg) Assert_it (((t).tm_sec >= 0) && ((t).tm_sec < 62) && \ + ((t).tm_min >= 0) && ((t).tm_min < 60) && \ + ((t).tm_hour >= 0) && ((t).tm_hour < 24) && \ + ((t).tm_mday >= 1) && ((t).tm_mday < 32) && \ + ((t).tm_mon >= 0) && ((t).tm_mon < 12) && \ + ((t).tm_wday >= 0) && ((t).tm_wday < 7) && \ + ((t).tm_yday >= 0) && ((t).tm_yday < 366),(msg),("AssertStr ")) + + + +#define AssertIntRange(myvalue,minimum,maximum, msg) Assert_it ( \ + ((myvalue) >= (minimum)) && ((myvalue) <= (maximum)), msg,("AssertIntRange ")) + + + + +#define AssertStrNoOverlap(str1,str2,msg) \ + { \ + long s_i = 0; \ + AssertStr((str1),(msg)) \ + AssertStr((str2),(msg)) \ + if ((str1) < (str2)) \ + { \ + s_i = strlen((str2)); \ + Assert_it ( (((str1) + s_i) < (str2)),(msg),("AssertStrNoOverlap ")); \ + } \ + else \ + { \ + s_i = strlen((str1)); \ + Assert_it ( (((str2) + s_i) < (str1)),(msg),("AssertStrNoOverlap ")); \ + } \ + } \ + + + + +#else +#define Assert_it(cond,msg,kind) +#define AssertBool(b,msg) +#define AssertStr(s,msg) +#define AssertTime(t,msg) +#define AssertIntRange(myvalue,minimum,maximum,msg) +#define AssertStrNoOverlap(str1,str2,msg) +#endif + diff --git a/macos/ZipSx.h b/macos/ZipSx.h new file mode 100644 index 0000000..d2b9ae8 --- /dev/null +++ b/macos/ZipSx.h @@ -0,0 +1,167 @@ +/* + 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 +*/ +/*--------------------------------------------------------------------------- + + ZipSx.h + + This header-files is global to the project ZipSioux. + + ---------------------------------------------------------------------------*/ + + +/*****************************************************************************/ +/* Macros, typedefs */ +/*****************************************************************************/ + +#define MACOS +#define USE_SIOUX +#define MACZIP + +#define OLDROUTINENAMES 0 /* use new function names only */ +#define OLDROUTINELOCATIONS 0 /* use new headerlocations only */ +#define SystemSevenOrLater 1 /* Runs only on System 7.0 or later */ + +/* These functions are defined as a macro instead of a function. +so we have to undefine them for replacing (see printf.c) */ +#undef getc +#undef getchar +#undef putchar + +#ifndef ZCONST +# define ZCONST const +#endif + +#define NAME_MAX 1024 + + +/*****************************************************************************/ +/* Includes standard headers */ +/*****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Many things are different for mac-users, so we need + special mac functions :-) */ +int Zmacstat (const char *path, struct stat *buf); +#define stat(path, bufPtr) Zmacstat(path, bufPtr) +#define lstat(path, bufPtr) Zmacstat(path, bufPtr) + +int fprintf(FILE *file, const char *format, ...); +int printf(const char *format, ...); +void perror(const char *parm1); + + + +/* +#define MAC_DEBUG 1 + */ + + + + + + +#ifdef MAC_DEBUG +#define LOG_DEBUG 7 /* debug-level messages */ +int Print2Syslog(UInt8 priority, const char *format, ...); +#include + + +#define Notify(msg) \ + { \ + (void)Print2Syslog(LOG_DEBUG, "%s (file: %s line: %d)", \ + msg, __FILE__, __LINE__); \ + } + + + + +#define Assert_it(cond,msg,kind) \ + { \ + if (!(cond)) \ + { \ + (void)Print2Syslog(LOG_DEBUG,"%s failed: [%s] cond: [%s] (file: %s line: %d)", \ + kind, msg, #cond, __FILE__, __LINE__); \ + } \ + } + + + + +#define AssertBool(b,msg) Assert_it (((b) == TRUE) || ((b) == FALSE),(msg),("AssertBool ")) + + + +#define AssertStr(s,msg) \ + { \ + int s_i = 0; \ + Assert_it ((s),(msg),("1. AssertStr ")); \ + while ((s)[s_i]) { \ + Assert_it ((!iscntrl((s)[s_i]) || ((s)[s_i] == 0x0A) || \ + ((s)[s_i] == 0x0D)),(s),("2. AssertStr ")); \ + s_i++; \ + } \ + } + + + +#define AssertTime(t,msg) Assert_it (((t).tm_sec >= 0) && ((t).tm_sec < 62) && \ + ((t).tm_min >= 0) && ((t).tm_min < 60) && \ + ((t).tm_hour >= 0) && ((t).tm_hour < 24) && \ + ((t).tm_mday >= 1) && ((t).tm_mday < 32) && \ + ((t).tm_mon >= 0) && ((t).tm_mon < 12) && \ + ((t).tm_wday >= 0) && ((t).tm_wday < 7) && \ + ((t).tm_yday >= 0) && ((t).tm_yday < 366),(msg),("AssertStr ")) + + + +#define AssertIntRange(myvalue,minimum,maximum, msg) Assert_it ( \ + ((myvalue) >= (minimum)) && ((myvalue) <= (maximum)), msg,("AssertIntRange ")) + + + + +#define AssertStrNoOverlap(str1,str2,msg) \ + { \ + long s_i = 0; \ + AssertStr((str1),(msg)) \ + AssertStr((str2),(msg)) \ + if ((str1) < (str2)) \ + { \ + s_i = strlen((str2)); \ + Assert_it ( (((str1) + s_i) < (str2)),(msg),("AssertStrNoOverlap ")); \ + } \ + else \ + { \ + s_i = strlen((str1)); \ + Assert_it ( (((str2) + s_i) < (str1)),(msg),("AssertStrNoOverlap ")); \ + } \ + } \ + + + + +#else +#define Assert_it(cond,msg,kind) +#define AssertBool(b,msg) +#define AssertStr(s,msg) +#define AssertTime(t,msg) +#define AssertIntRange(myvalue,minimum,maximum,msg) +#define AssertStrNoOverlap(str1,str2,msg) +#endif + diff --git a/macos/ZpPrj.hqx b/macos/ZpPrj.hqx new file mode 100644 index 0000000..5bb3da0 --- /dev/null +++ b/macos/ZpPrj.hqx @@ -0,0 +1,455 @@ +(This file must be converted with BinHex 4.0) +:#9T`8(*U,R0TG!"6594%8dP8)3#3"&66!*!%Ip96593K!!%!!&66FNaKG3)!N!3 +@!*!$$39DF&"bDJ#3!aEf1!,VX93!6&MU!*!$J!#3"!,cIF3NA3#3'[q3"%e08(* +$9dP&!3b[H&ZZXklEb3#3"3,E[3#3"P40!!$hQ!#3"L8D"RMDS*NlIS6ISVG-[(8 +R+hBY21RaEd$i`XJbN!"bQK8YHRN,mmTE("$HbP6f+lXeRq'lH*3I@AbbH%Ef3E+ +Yif3KHp54hE%@hq8Fj,%GAml1RLpN-E,i(GQARdH@0q0,K(GffT%p5)X[RVFF@D4 +BKrHBaXd@6VD,AXpZB5d!C#'6K@abQi`@mJ[Cj$MPC!8iDT2X[EaXE0rjRCHM[$` +Ej#4Rp[RPjG6VcFj"ITHAR9DQepPe(-SAiAji1arZ(-5ApPP[lbMciLAdmP)if0m +4Z#m[-q'q["cNPGI1p`,!!JLip@eQPi2X'farqH4p"**I)T!!,ckH3A`!+i#AjfI +6V9BMbl,P@GDh0P[fhKZcCArkf5`lka2F0rFYkb28qpDfD[R@DP(8@d9PSQMYcUH +l#l&K+CqqV@b6b'8EXQaE[)pm16Za$2kVE&Ajrhr50p-icq)mQh-k-9rKr#ThirR +rPjaIiecK!m`jJh-@jcQFFcJAF-lMl1)dliLFcVQ"F`IR*Xk0R"GcEZCFalQ0mbl +1fcR[i$c+q@,1jh$HcAQBm`MR4C`2FElF9MERGNj6amLPR&XjIj*c$@F2jmXiAm$ +j*XlAFlk"mi@FrjhcMcNrbIN*cSpcISVc6cMr,HHpR$r0q3#eRXTrcYrLI$mR'2- +,R+rKI"hRIH3Bb9R2#IC-iM3GT%lK(-,CcQPUVdlJ(-lCbMQ1Xi(6p)BkME10Xj% +c+PDCdr561TN6d2S-jjpa'Lb,I*!!mcpbrKVR@cNIiIaPcSFjIjhc9cKrNI2GR'r +Mr#$RKcMIc[R[1Aq9mbfFlq6m*Fi,1*Ga,Z@mKI0IFGl*#5!Dh)bmK[09R,GaAX, +j"jarb2RI1(q(FaIR4cJrb[Nqc[Gb(Z#mQA-Ijhl1Jp4a$2rr-qGri@idr`pa2Tr +c#j`c1@GcRXXjPh-Kjha1dcX4X#IbK!KDTSmLi&#%2SXmRI-QcLq9Z!9QHAK&RJp +`lZ(FbhNGjrfFi0ZA1@rJr$6RRh*qP[1jR(r"H68Rb4GarLERAh1H6mK%r[mHjqp +bAXYTHM*b(ZI2F2iXj`61[`QF)`)'4&l"HCccMCcrM[2R16r(qAR1Rq!dI4jj2HF +pR$r&qmEbrbAmTmDmG5@R`BL)@2XZiLEchf"#j+Fj$@j%`)h)-cJ0YN6%B*!!fZ" +0"!b*Q-YJ5Z6l13f@4"l,H6RRrq,m"ZHMR,r0#FVclQpbISXh8X0[Fcl'q6MRDNj +kp$ZFEqEm1FlAFVk)df"Bj'l1*Cc,1EXjRmhj4Fi(1@rN[*lcMcMr0HFV1DrKT2p +IcEQEmcpaIScc2h$Zj2`0c[G`AX&j+HFl*#EQK*KF5AfSiiFjrbYhe2BUcZFYQ8# +8`"SqHK"mJ1I3kr3C28Brd%[d&(J&2Y#Ep#9p$1pa'!D(S)I"!2UBIUI2k&ekQ$k +NTkNhA)PD1m`$$m!AqJL1"DHLhq&FB#FB#Zm#3m%Rq0Hr%%46EGlDqbRHVF#K%H! +jCH(Hi#JG!5E6*4lH8SZ90Sij`3pl6lJjll@6MSXbZAq0&J$qBllBSmf01Ffr4[l +C`lkV[XcL4ASG'Uq6pdGP+lLTLlHfZ[CGhY-)T@1p"c3qUpkHR1ZA["4,,hRFkea +YBX@*hcX-dG"#+9Im%9i"mj8`IdC`pR"ZifcRl1$Xj"c&1CTc$1GBcR'FNcQl1'G +`VZ*FcEQ@Fb2R*XiYR$GclZHmKI0@cJ1F"cN2F4lQ[)hc+1IYR(G`2Src(Xjl19r +!q41F@f-(QGk,(-FjM(-iCbXRM$VH@aj#JTLJCcJ!8S+3!+!HU!JLJMDJ)qJ*@MT +N"$e"8C!!&83&)8&+Kk"K"%KC3E!i)0$PJemF2ha%-$h8ZV&k4A@S8HedmNlrlUV +k4r+lI'5L-VEe@@SUj"`H)5q"0Af[ML&D&MAMJ*Q(BUqXb8H5K0BVJkB$kF&FTK+ +E1,G`MZBF`cQ@Fa,R+-j1cKXiEq5mQA-NjdE1rCbhF0l+HC!!Xiec'fF2Cc[R#-j +9R$GacZ$FblQDFbhR2Xl*R)FjEq-mbRNAjpfFcq0m2ZFpR&XjQcLE1BG`YR!1j4` +QQE%pEq+fM@mD("[Z(pkQ6*ArB1m@(2NMrbrTZlE[a'9UA)NZ-1G*h2#q2MlNie# +FlAKr`'(q0ph`MVp(96SX3dYqJ(B)h'F3ShNX,hEQPI(CraA+,q4E26%a@U*4G2h +S*GZQpp4VDZqA6Ni-IBGlai[LEVbSIX8L6)&*mGBRF[Cp'P`'R8-#ZKG'%!T3Na# +3!-m)-8N-L68ZIi`Zd6(CV9@'cMfh-Y4UGPU0[2,dLj`Tq,X[KR+QI5p6KIl4ahY +LPcQ1D'%LG1"lQRGkkX`5C4jc2[L!DZG,#8B,5U,`Fq[1G#3r8(Mci'9Ud,jSF#T +ciQZmAjrirRI0jCeZYIacC+Q'iD#62CM9E%`2YX+JZLEVVGQjbYU*LD&c+[cadf` +LhS-SY$AS24*%1!"B$AaU%FbHEZBiI&Le*&2dm*m[h!(MBQeX&DQ`Q-m4dY!$bD8 +kHP%6%rda"hqX)Y,(1*GLV%NarU3BRe1-mLR'G"6MGiV4*m@3!)"LY%a"B48MHSS +40SAJU"bI-b0DLV%IaELIFKb+X6Xc5U8Bhe115CP42-9iN@)m66&kT4ME8S`!+ND +`&'1!bP%MmhBlHQAHENIq6!ilBQEHEJF8c*[YH+'TL4e&-HqfSf(QcBaJ-HTRalI +-QaR0XZ0rjXefp0#0fM&5apJFihD-d6&kamJGih@-",S41aQYXQ09M1SaQXGB%f0 +hCUc,MZFamX5i(102M-iaYZG'X%`IfUkLVScJ-8E&'"jMCi`p-N,'Q#)M9BcX-BV +'Q"BMLBaU-CE)q"NMMibJ-IE)5"TMN!#-G$%qb@JJif#-"c++a@JM)f+-p6(ZaTJ +KSh#-26)#akJG)cf-J$+'b"JAii#-CXPS(b0DGM63M36#+mfiD'a8e)cUfE&(4Kd +CKh5MMSa1-LV*b#0MNk!-Sj!!M&'kN8P'*"Q9G118M&bD)4$'`aJTC265MR%bcZP +'1aP9C066MABbqXIS'D10M!$+f+!Gph0MPS`&-QVTa[BB(@4-N4%h4J8CE@2Ncih +9-3l(i)SE-Q%iaBfmqX-Q$+-`f-)J#i-SE[L%N8I'C"PjC'5@m8FcHQK(%4PcC%5 +6F6X'BaM6C151N8h'laK*C-54N6Y'(XfiR"fhBr5488I'm4LVBlb4F8Q898Bc'FY +Nh*049XBecBLQ(FQ%Kc2UL6M+q#hFJh%l0j,,+#lMSCR"(KP@53lhm0'6rT!!Ma[ +UBD#(34i'HKMHBCL(34i'HK"a'44#hN"HmSGk'1Y&cf"FQ2N+aL@4LKMrCE5BN@, +'N4QbB-5Bd@)h&X`i-#2'M!XMmM*kc2JK)kb-*6,HbYJK+J9ML)`I-YTS4LJ91+[ +!9`@q+["9JFF+r&AJV!*R&6LV`'N&,L[`9S(h#Xa9B+i#Fa@iVm"G"8G3F!F&eLZ +iJS*$+,L&JPXSZ)@#@bK`AX%V&,a#`5Z8I)+4BS-IGPcBi!!MbBb1-Tl+q'Cb60[ +d$q2CGJcCi*%Ge6-iT-!K"3iTm%H"2`Vm8H#2!Rm8q+2!(`Aq+2$(MLFcrQS`5)& +"#Ja5i)S#Ea4iSm!E4@mSX%%jSQQ`4i%j#Xa4p)d#Fa5BSm!I"HiSF%H"1`VF8H# +1!RF8Z+-F$6DiSm!G"HiSF%H"1mUH-pLM`"d&lLK`4p'AM"`UqPf"!`SX925k!JF +9Q+$!"!8Q+,"5JBm+E&$JJJ)A&,LJ`!-&(LM`3)%(#Ma3i)%#$a4iS-!$"4iSm%# +"X3T-8'##!K-8H+$J&!T1SH!5#LkKY"8`A%2"+44F3X%I&0a!`8%82%,")a3m3X% +M&$a#`5-82%,")a3m3X'R&(a+`DH8)r@')bNiNS+[+(Q5i5E+N@E$663pT1NK63p +THNM6EjVHd[55TTFd[D6T58hrDAT+de1DRY,dP+DR0$fPk5G02fRk5G02'KcAm'% +06dC@e["L63pVkUDTQkCZQVTTq,1'2f[iS)C$DlLcKQYV1,D'3fXiY)C$DlLfT[i +D,00`F!fHDALeKMYUZ,@'-fViYBCIDrLeKPpVq,@'[fTiVBD6DMLPKXYUH+@'9fT +iTBE[DRL`"PmeZ+[Kq"UFe'#N"L-eA&1$NaUFe25LTKFe[DMT3Dd8ErTF`fXe[Dl +TG3d@D$"!dr1DRYId[!BM0&a4Jp%DM0$JY!B(0"aCJ`-DRUc"!Jd@D,"!Jh%Dr02 +JP!EV0"LSiG%D204`D3f(eR"S$3CUF&1$QaVFe'#3!!Er0IL[`Am09pC`!#d(-"U +!JQmVH,L#0bXd!S8fS1$IL[STDU%F#6HDJD)HL[FUhUTiUq+YL[j8p*ULca4pT1J +K43mTHNJjGXriY(Q[3RG3p)b#RbZiX,,Z"XXdZ+2",JfQDEL!KJYSY!X0(p"`!3e +Id2!%$5I3F!)0*p$`#-dl0*a&`b-dr%H$[aVqSm&RMHDK`9)0(QY`@S2A'Pc@B,N +'bc9BVZ&''McAe&C6Fdep0(LZ`A-0RQX`A-060(a,`m-d2%a66`dAdh!a$5jVF&Q +$baTFe[")$Br8p)Q'#fPiNSCVDMLQKYGSZ*''-fNiU+Eq'JkRiD!D(UIK8jUHdh! +R66pU1*H'FfNiPiCcDAL@KQGTH*D'@fRk9F1[0$fVk9P0VfUiPSCVDEL@KQYT1+k +'(fTiSBB6D[T3``Ze[*!!mAZM%5Pd(iAZSp!8&0U43[qaNaMS)%CV8'J-QJ!0RpE +`E!hre["[$Ir@m'm0lpE`EJh[e["Y$Gr@m'd0hpEU*ZJ8B3GIH-fNB'1B3JRj'%8 +aRe@'`bJ'fdl93qCGKdIr(k0G&iF0[#%M-bGm-JqU9h[+JqSeiaYjr%&'P,'fP!I +eE&M+JlTf@5p2X8P-&!VFXe-H9,V,8aj8[#Y6(T5qUe)He-#V8ai8`fY5(P6&De- +H9-IV8Ki8h4Y6(Y6JQe)HP12l8Kl8cGHP2#LMVdTj8&6IP2+JVViQj8&jI8A+Jc, +l`T3(pIDG[6c*-6!Ipe"iVdM[339qIXU$8[lbP!FerD'8"mApH-U$+[r6+3r+rBG +5(Y6p$kBm6!$X6AQB%VJKj@'5i2U8KdQ$25N28`L[6hQB9(K$bX-Nd'G5(UDD4U8 +m6$f05hQBL*U8mM#jp2k8KmNUjfrAPiGTUkRIb12M+00CAFIbK"Kqp3Y@*5%[Rr2 +%D'*LHfYpqd1Q'%8rU[TPTCU9!ZrB&'H)J%d0cjQiHAcFqDRB&leNmjEJSQ'UecM +CQLfQFbPHr@*FabPMeHRc*Y[jG(e(hFQek)D4d@'j&[q0Q2c#a@3MMkmhTaZc05I +D'Q*m6rbr,IjI&Iq[MIpAarm[@Ra(jh'GXKM83X+ha2rhaIpharmEirp0LqRE9p+ ++ebL#f'+Ck)liId6m2b2qEer-fV*LI2YZEIKFj6VMre(arqMiIdcm2cEq(lIiL+% +q!PP&aq$*mArABT+aChCf9BZm9TR'hl5,@R8pUE+P'BEVKm9m,ieYpS,irfL-Zcr +H(iVr$mIr0mIrpmErqq2r@q,r@q2r!r(r`F9kk-F-ETSFU3"H4kT&[B5!ZXA`qZA +"AU-ZTQk0riI(rif,Z4U@"am$Q`X(*[RI&2rEmX+B%cR9+L!QqAUp'"dpr(VhhhD +Tq6pX-9IMiGF2MIq(a2mYLlQ'R,!jAd!C&4qcGAjq[ZpAGXmfpecHfH(mT08%'lH +MKZq)!"i#`hK'VKNDAcqmTV*QrH$8)(phM!a0+BL'U(aQTLGV3*0flr!0CV`6RKD +ki0la6eC+49ZBd)TjNY!!CKar%am6&-kZK6RZZZ9Mch%qRrR`k,*p'r84B-kl2PX +jV[V,2,2PlqCM2YNce[6Q[CXDkY+HUZXC0R[cfUi,m$j`mpI-q60rcBFRJ*P)DG) +I!4m#TNliQ1e[rGV0jF`imqpYfhGlCEd)4Q3ri%JrmrTf@S3lTLJk-KL00dmF1D0 +9*Q3fedk!N!#$'@ZQ2,KM*Ye-FYKm+19MXTHeR"p'(4lE,LHDm)H`8aIFiA(!c$G +hq"G-D&3P8ma'-`1q`RPL2"-Q26Bl9DN)$i2*`IQ,qGY)KBHD'M&V5kpCc`J6BQI +[D82QckGP0kiQMPR!b1Vjq6ZG'fAqRKPqFY"rdaR5CDD1qINC38KKKYEdE11ERB2 +%0i,CIZBBm@%i9e6dCP-Mj`C2'qC1lD`rZI%LB1DI1fScKrFaPiL2`0b!&(91$-d +,MKpeeSZDF-Im2pi!h$(PJ%F!GbJRH!9`"kpF&0K"R6i@LhAm-(Gi3P`3H%5G1,0 +Nf6lEUNlI"r`%$"1Ydb-"A`(Lm(GBPYei0VQLBYCbqX2d@p4T('EVJ5`m$&C52p0 +,8AR"KF("*5T@@A`dG`K@6+"`"c)bZmmGRKV#DU*k5c$,cahH$!+j8AZ#(J35`8& +QqlPMAKm"KMY`%NQ%1l`pQ2AR$Qm-XHfUelH$k4(Z!$*kKcZm+*J#!@EaD3#[Z+- +(K-Nhk!H#4`"hH(2`GZl`bU$1h1&p)GTAJpL$K`"hH%hJ*F!GrK(i#A$(Zr%9i)i +DibrJi"f0L$X`(FcKMNNZm*-lqJm["ZlJ%(JkF!F'iIR!(4J"4q#1hXBEJM[k$Bm +)lZJ0F)-lkQM"hYcaCN3,lSM"1i)lH!EH%G`a@5&#C+2H+Ki6L4b[M`VBcKfq+8b +kF)GR#Ah+(6iN6+a`KhF+lq)1la3Q6lM$"d@mS"VY-cJ#GhL,#-YXe,X$0BFlq)V +-4$EU6m+%#(IiH9!Vl["6`EF#kX58UUHr4%k3!*2K"m-GrK,iaA#(PiF`Z5Ca6Ub +QQm4FDXiGrK[icA!(IZ%l`adi!VrLMMk(Lh&(2m&aZ+2ZBTMEC)h!,ZjiJaK`0ZN +PJcm0Gr3(rF8GILc`$ZlS$haVZ-0r"EcL$Jm8m*ml2%c`Xq%1(aCmEEM$Xi3q09q +c&"C-jJjZK*m-Gr!aZ"Khm#+i*(IiPH!h`aeiL4m0Gr3"IMAFd3IieR!(VZ&I`af +B!LC`4fq$eGc49rMCF%HYi92Fm@CmEEMM2A!ClZ$1q0a`"jE!EER$CiGBlP"&)$V +F`A("(ql`Im%2KcY`'PmFl["h`4q(1caKm-RK$Zj)2jT[L2L"p`phm'&i!AId"pi +rh)'le)3lZ!FFK$Y`'3mKlX![[)5iSmrKM0c4*h!dlRJRhN,Fi4-%$R"(Vq-*`Kf +H0IJ,FBFR$I8hAiXF!VmKlZKMq$jhm!EmKlL$@q*$a"eiKKm4Gr!LhXXGh!1Zc4f +B$Mjc"fk#4Gb"4hJ(F3F@L"V9BKhKGp`4!aIQ$Tk(pa"hq1R!hlQMcq#NjKZUPJ' +qFBH4-jj%h+%hi%h%(AS*(NAF`62TFHlJBrJ6F3F[`UH)1hS1[b,Z`'@i'hIJ(6h +&(4J%eq!1,)!cFNFIiQ[%(If![a&h["1I)ql`(!*EZ--R#El2(9J,0c6I-2%$rX) +G@![[jJj0"GcQMKVMBF3G(MqmLc[k%NmMlUJVRNEF`CI!-HlJ'23AGr3L(NIFJBP +J"AGJ%lb*1rS5[b2ZU#1q4pca(VJ$GhJNiB0N[Z&b"IJXGfJpk"MFJArJ*hG`82U +D1cJr[)`lH$9p`4dm&Tf"1cJKh)3lF!@[+1lJ-r"PlZ!9V(R!(CK16EJ$Bm"UlX! +JH"phB!Gib"hp$0IQM[i4,i6KeS,Hj!kY#mmZml@+2AKhFBH'KBFAGiM4j1'1'X- +VZB-$@IFdFiIIM(F9q6jpC15bPAVMFfA[m,U4dHe@*rGNR,99rb"C0k"9Mb$4reV +eqa$pVe92$h&DD0@$4[5r9[eM42r$q"SI,AZ(4jESIfek"(Q,A841eGG(p,mfrA' +B,1F1hae`L6[mHG!IZ'1b8I5r0MhAi-lFi@&KhQM[m$J5rDp0,a,4rpVd(8'li!j +[($(TEG-M"pcM$KmFdIrDp-!3r@m%pEAV+A#(Ra%H80cK833[i!lr(bDaZF26KfP +Vl[!KNY8K4ZJj*2VI#,hMd(bi`fF1[XmG[NkLrih3I`N[,qlS[j!!P8'%N!#!ch5 +Zld9UKQh3UIlaLhZ90LfCB+HE04Mpm4GQjPMU'f(#A*C+bmcjdR*"KRLhZmQ08,H +[Ch*Nq,54CMF[QRQh-McAEV5+r0pRT[Ur6AP)1bHILaTp'0X(QAcISH&iEi$ZScF +mlc8)0G[Md%K)frGH9Emd,R`-A'LIRcm3"c&#fVlId9NjM3XIZD(i+B6ERML)&Y, +frD(ZffPFq+-ELX(2N!0r1!irK,&p''UB[j[90TPU,PNEQM`-RQb*HFS@L#B23bP +EBakcfP!j$`-V25N2`bcE8Ki'AEDRqM$XXMrQDAM31X[NB4$QPT5()CPE8ak'CJk +Q2!c8(%Tj',BjR2)`L(0EbX13!-k4P)F"RU-T$m-kGkBm$2,FPI)`N!"cImT$ql2 +pLMH9AXQ$UAKGbS24H%[+Jq&i8mU$+IQ3!*3(dr,QP!GMmk'p2%@V4*1(3IJ$k6d +-(Gk6mQ!!-5cP`FKKH-U$FAaVbS-C4&[+J`(pL*3(NrVfP)GKpcX5rM!dqjb8Kb( +jBbN2`q1hTc`-'ADN1Q+k2c,P`C5r)H9KkBXa+3p,B)a2H9JJBh,+``$j"hTmVj` +(+mI1p"i'(UI&2%1qPBGP0kBFHdq)i4H'X#E+2fr"9&SEjIYlr)6!I@'"`h2@5$@ +XVIAp,b53!%`d$*`dZh&N+M[`fHJ8C,BRr2`AhD$'h(AM3,CdGYQ"6pqFII`(Vqi +krM+"V@0DaSBhE8%[[(kU@ZLPGYrNe1BRF[r3a)4HL*&hEklAp)TkY*Th4C82%iq +2bFIE4DjReZFf0+VQrIV8Q(iBNDpGN4FG&*8KkiZ@8Zr8dQe2[QLp((qaRR$4hHA +)KqGhG@rTUfMpEp565cp'kX-@1$-VjIicGLXF['%mMl&l5cA9mjfk9hqpPZKCC6h +[6NY#rZjHS44HRrA9rYB4iH`*Vmmc#!5CUV+8f6pZ!a"Ep$)@PCJ$HhV$[hmbHml +YhaU[c1RhKTR3a&4,B%(QHX@DbarGGB)p"0dhPY!2ZK)B9TMe*`h@Y!r&JV*KSYl +8KKClZmEU4%[l9@chQXC'P!fX09ac&`0kX5`E-TBhAD%+Qpb@,UELh[T9N91i-[9 +NrEE)UPBRjrfXU49j6,h4m!j,aYE*A5hAVX)HX1fCGCF[X$E+)mCD9h$('N4Qci% +EZZ4MIDE)k9bCfV#H915-Ur)K9j!!`TkdXe'h0U`&&APXc)GYiZMZd"6eBmfSb&R +GaQ9BeGCTIcHfhKbL0R9DXBdEkMDB$+l6&RKmBcCRkVK1'@4#im4*hP5RGHE%UEa +M2Q`m*kd[P%RUY*HF2&98XEQYdj+aka3#c4f@J&K#QqQZU"1i8jZeR0k+ZQVCY,V +2L+a3fMKVfEihB+-B&H[%%XlD&SXPA&3l5,'%LfSTLBdhGr3L0QG'ZUNAJE"bT)A +j2f[C[YFbE9b[*H,Xl,JDr91[*DKB3YFl`5Dlb0CVIcShi%'ppTlc!Kl8Db-j2q" +"[6,1JS!($8lK,Jaid1$+D1F(2'M3i@&4`)-'LlXii%'$0V!A"$aSd,Cd5F#$"Ud +eP`BmD,![Z`-H0'T&Z#cJ3D1iY6cJ3D0fDLX#(M4U&ESbp,He"Vi`i%'MY9`9m+" +4kd`QE8hr0@TaZ5EQ`iCaEF#$*LHCe`8mD0,fqU+!"dhfjIU!"deDafi)H0#N4Hh +'J!G0pZ@QJ!G0@S0Z$RM3T(hPPS!(eZjfDm#$CLd"QB3e&U$0@U!bl@TUhDbe-KD +fc&GKb`XZQhkfYV2)C)DR0@Z&#KBE'd9V)iZ9XTN5EpBpJ9SCI"NLaQ!*E55i)GU +YBJR08$a[`a,D@"X1dIlbXN[c+qR4)IDPXB51JK0$l-[,4fEDp-d3mIk+LDd9F(b +)eTeAATTG62eDV199MEBeE,'@9iHG&PVN%pFd@&r6h#%[AVZK-X)l@qJl,+(T[aD +YG+m2q0HLGHDHJ(mYpZAH)&1fL$&Q1I)ZV(f(1K&qif6H*FP3qr+Q#TIQMYlBPdp +@i5e$R8k&NaJq0&3,BV'%(UT0VPK#$p8'9LbKKfSh+TE3`m5BJjplRQX3$"0E$l( +&P*%kKr(f52YMChH`A"dQ0lTYjlS+9Uc@k[3)2U1Q"iD*-8GG0X,FB@plM0+Ep`l +6J[9fHX[JeM"Y3ZmBBE-#dl,djA2fV"X%$iEEPhIZkSK,`m@#Zpbl`0a4ZqHLjCL +q(QjIhKhH0e`Hmlc`2QXYq[afZdlGKfY9HSpl'aMUK&[!mBYRkp5j94jhEdCbF`F +ZL#9dUpa#,+&Ea6#aK'l9fPFXS9[P,Q)*MF@RXi4Zdkj6,+(EY(mA5qJf-88XSGZ +dXaC,k$CYPX85ZNhF%N[S0RYG,+(Ej%CL#6e#e`'aK"iK0a*,k"&LQ9K#Mp"'@bb +K4fMT,*E3f'8k5qJ4@YH+*I3)E96&LDKG'9SXSG[P%')*hDiYV&K#YfZl,CE3l9S +pLb9dZdD3!')*hDjPVPK#Yf[I+TE3(ES)L#9dKha,,+%lP0A%%VV$(K0,k!kYPX8 +5ZN1X&8[S$Zeca4,DZTb+*I4)TAQaK"iTpaG,k*(DUSXPp%Ml@5bK4jTA,+&(DQ8 +XPY!Mj59L#GdTrSQmhLPI&%[S6ZhZa4+k8qiVPY#GpVPB3RIk0V'%lY4#@5bK1m9 +AXB3H*4m95qK4FNkaK"iPISXPp#KYf-85HT6p,*E3Shbc@%+2dNjC,+&(DI-VPY# +MGI!35qM4fUD,*I4ShbIQRD2&2,'%(QhrLbAdD0mTPY#Ma3baK"kYhDjB3Sq4GiS +Pp"MjM9K#Me%E%8[S-H+J@%+2XFI%%RU-m@)*28D1,TE3Bm9TXB3H+fm@5qLa1UQ +**I4BF8J'2FD+&f)*2GEDL5Ad@2QI@%*E&eZaK"iR*a0,k((b','%(LG(%N[SFH+ +b@%+2Xmr&%RUFla&,k((D'SXPp(MjX9K#MpFH@LbKamZra4*k[2aE,+((LhGL#6h +HAK*,k2(q&d[S#GUML#Ad",&(,+%Rb&2&%RU#j&!XS5H)k@)*28&F%%[S#GC),+% +Rb"h&%RULqS4B3Nq8CiXPp%6aALbK*fUR,jE3%m9VXB5H+,k)*I4%DbD@d1`$l5b +K*pPRBJNp5@`35qK*BS0B3Nq51iNPp#5aALbK*iNMBJNpb6U+*I4NY65aK*kXTL1 +Z5*2&Bl'%RU`++jE3Nm9lXB5H,'F35qM*B*Q6r#E6Efk5QT@pR59dPfXDLN90&qp +cFQfA&XaL#GhP'K0L#GhP@SJbG0)&6MK,k#jUjbbKTp"ccK*kLZX-LLAd&0Fb&%[ +S+DlP+CE38l3r&N[S+DkI*jE38qKcC`NpPEc1%RUUkb++*I48ebB85qLTV[JTPY" +6A@94,+'RZK+M@%*2"3HG*I48HXpC3Npcl85aK*lQqSCL#6h0e42&%RSDIHBXSDI +4Cmi5HTUVm)NPp$4`bPP#RdAr1%[SXeb285bKch)94,'%2N[A$l'%2X[e3m85qLc +AmK2plbcAk"2plba`c9P#RdeIX9kM[@1e4V%j2PXR&Y(rcYCp"%l%(DZ-bNSBCp[ +(S[qGE8q)rRFf1-9DMRc6U6[V1GSlqPK@`TMZ@SUb%XCd9f58P6#QZjUNV)3ahA8 +"iHrFXDSL()FlJf@Xp-Jh`jj$cq'1pl'q!(IJK+b%-81A#h#E1pDDK(G`a`U#XK, +'$([1p#cI6(#+G4hY(6dR+f(-G$e(@3PMTUY!bNSB-qdj@3PMTUY4bNSB-eeM8&E +#Q+R&ZDb%F3kiaPU2pSkHNj8`cY%P4eE#1-F9)f8PM(0F+e9@`MM(05YP*BacA)G +39X)iajk6P6$1"DIX#L2FQEUc(U5p`ajG9X)iejk6P6$1eETG9X)i9aYd@3RMA&H +%P*8`cVARC#@-@IDdV)3abji6*ljC[Np@`TLP8iQXK$(,062&hA1@Db$+5KLcA#p +59X+BEFr*5KLcj41b%XCXHdj@`TLYKLmVBFc@qPa@`TKYcmP+',1eETH9-'DlSU5 +-)ThR#UDb%XCji"TVAGSlHNkQ8Fl6CPe@`MM2e9e&rcY21h[4rmjc*8A4rmjcc8R +4rqEBFl)5aKa`LV8`lCfT1qYKfMZXff8PM$RfR-bLc(&e@&N*BiiV@-UXaKbjKDb +%-GHHNj8`jYV6XK,'A(Y19X+BkrYN*BbjmL&C#@1Z+cR+*-GFEHYP*BajFJYC#@1 +H25FVBFac$3"C#@1H25%VBFbcjd6rQqIkRk,rcG2@Ar5rHDk"+IVII,Q&k(rcAGP +6p,rjFJ[4rqE,%8ArQbq1L[ihhe9#4IqE,dF8r@qqp[ULrbe`E9E4raCSSbrkh`* +l6[5r"Fk!L2kh3'iKqYm#ZBASI`YF@92d[`@ZXbMkhd*A%aApEk%p*rVI3YmRqYp +#ZBASI`YGT96d[iAbCY(r&XSY42mlhp9K4Imlhp9'4Imlhji3rHpmHdld[r1T1bZ +DfMZ`Ar5rmee,325rmm8jdIm@ZA+Xk(q,A*&8p,p&VJSUqYmLZB[SIi[NjD,r,A+ +PAG(r&SRpS[mY%SG%re[XbUDLrbffjd6r@qbk!U,r,CC$LrkhQ(jJ(94laqU@S[m +YGK94dIm@ZckNk(mAf(1LrehJqd6rZd!q*rVI"ESELIjh!E9QV8alaaUCS[pGi&U +MS[pGJ)E#fTPm5q`2dIq@Z&+#k(p,A,Y8p,mPpU,SId[N(+,r,E'ZS[mYN4q)rVG +%6LRkha*V,2VI%VQ)k(p,A,Y8p,mPVN8UqKqqkkbrDHrS,G(rPMV',2VI8PFm&Ie +[UBjKS[mY&AY%re[U@JZLrbf9pi[qYe6X&re[+6'Xd@R[i!'Lrbfe[dArklBr42r +VGL9AdIqkl3r4rlVP6+,rGDYYL2lA,GD+rYGYIiMqeff2L[lAEAq)rYGY286rklB +HS[peLm'Lrbf6YiRqYmaq&Ie[QEa6p,pPVViUqYmb9h`9r@qCXf1Lrbd64dAr@bB +I&Ie[QCJRqYmbqEVSIm[%E0(rPVRDTZKrbq9jS[mYPdH+rVIFZ624rjDVEBMqYe` +R10(rPX[242pElMV)S[mYYcp%re[ZZJkLrbfh2d6r@klf*[VIFVQqk(mVe"*%reX +K4a6pEi9VdBVqYm+C*G(r9UKeLIkh`M@'42pEBHq+rVI#PCC&re[KfUVH9H3RAIY +8p,m9VKNUJ5[!-PElY(F'#eMadpkCrQ(96hYRDX(+Rh`VAI06p,q9VLJUqYp+-)p +931dGUkD+rVI5Y94&re[TUV#LrkedY9I4reDkJU[SIbYGV96d[j@ZmbVkhdVA(4A +pEb@pa9UPpXld-'Z1mPe),9LRe0ka)URSIaHkiURSIaGD$p(r,U4[@028hY%VS[p +Gk)U[S[pGk1UaS[pG#+k`[LRI+RU'P8hYRAN$Dj[D1eC@&Ie[P5ZrL[khbRP$dIp +@ZFUXk(qVA-e8p,p9VJSVqYmUed)5r@m9[Fh+ThbVID[SIkYGJeAd[p@Z&#[khfT +`La93l4hVd)VqYpS99NAr@qekV+,rVAD09Y(r9S0pV02+YiEqC1e@HfIHCYG8iSl +e@%Ar@q1DXD,rVA%0@p(reYK2S[qYF9eDdIr@Z&kYk(pVa"M4rpD!@DcYbVH@hQ0 +e9hYRmV,#UlfMaU,rVAApA0(reVVUVHKrDm8jdIr@LQfLrkeeV9c4rpEk9Y(reY' +hV2aUlqJRdIr@ZEUYk(rVA)&Ap,peiTESIq[%+Y(reVNqV1KrkebY9[5rGI!+9Vl +PBpNeeX+eG`B,@!rAhTQkXb+Z[@20@p(r,K)[4Iqlb09h4Iqlb(9K4Iqlb&9M4Iq +lb,9e4Iqlb29j4IpE$qkc2Ukp-aM('VRfc[3`kq6D1r0qeXUeGkce+rVIHYIV&Ie +[[D[$L[khAJiKqYpkelF9r@mpI)QeFrNfZ#kXk(mE`%h@d,9hF!A4rcEiEY(r0[K +ZdImfZ0U[k(mEd%&B1GMHXHDXk(mEA,p@p,m0m#T@&1EEk,UeS[pY"0GB9GMHQ9j +PC@&lCpl'kX,fMTi@r@qMDrk+rVI4eAj&rpYSEiRqYa(1b@V$I*[N!D,rEE+R4Ir +E"0D`mV#p-rh!kX2f$S`8r@q6EaApEj0i,2VI*[Q0k(qEa#h4rcD*@k,rE4BM4Ir +EE$q*rVFCM'"0BAYRHS"eL1dGka+,rVGCr"$pEl1i*IVICYI$&Ie[XlJPqYm@9li +9r@q,DqU+rVI&GAY&rpX#"YQCDqlJ(k,rED%@V&jXleM49r5r,Dj2,2VI&YFd&[e +[Laa,p,qYiSISIeYGK9Id[kfZmb[kheE`MV@0lChT6eBfYRIJPZKr@ehE9r5rVDi +9,2VI9VQ)k(pEIEISIcfq@r5r(R&,p,mHF9Vd[alV,ITI$lh01X$fcY51YAlY(9a +%p,mHZBMSIcfZ#LckA`pmRY9mqEDj2V$SIpYmUqKrfjaY&re[QaJTqYmfDbckhcE +HcfV(pSkH&[e[QcdYqYmf0![@2HEElYUqS[pY&lG%rp[ZQX5LrffhaU,rE3FI@AR +ChS%PS[pYTaDX[fc[i1LLrfehY@24rlDl3V$SIc[N(k,rlA!eBp(rGXJM4IrE)@D +)rVH$AQ+GBR[(UX1Lrqe`c@E4rbjf2@(4rbjf4@,4rbjfY@E4rbjfK@R4rbkfEd6 +rZjMqBG9QH`IA&rh[B[Q6k(mlAA9Bp,qGVPJXqYp1hbIkhdljK1Kr1m&69SqfGh! +QdIpfbZp&rpYTr86rfb@(%2e[PkXHLrkh5b0ddIpff4qLrqebr@R4rhEj2Y(rGP% +[9Q+fGq#Ck(qla@r4rhEE(k,rlCDML2khfrH*rVGEc8$d[peb"G(rGSXVS[rYMUX +[fc[d#G(r,T&2LrjhLAaDp,p,A&GDp,p,A2YDp,p,`&r@TEChk#kLree#h9N&fpl +"+8ArHjDV*B[qpbaAB4Ep,r6Q-`KQ0P,F2ZP@IfB[aB0l[QX3&!Eka6G#-KJB+AG +F$&YT!11#*+*UL0YR"d$-'%Km(8V-im,H--&Bk"cVYYF0$1c'Dfe1ClEC2pfD'@J +AVGVXG,FcX,ZfCq##rJX'DUhTcN#eABqc)5%MAh&&Mj!!PXqbJ[!DZfUfq3L&@E- +K$'(eJhT(&G1pPQimQGZcBF`b-KX)MM1rb0`LmiV-+9TI3R-bMmM-),1)c!XbHmJ +X)[1#GJPkFc*hb'`JXi,-!M)rb"bJc2q&+Rb0#j`NJcFRh62rH@q'TpdjRmU6UQS +)h"F@D&CX#&efAfA2Ir,[2RqIjE#%$3rr$f1UIBdPaIZAa9rX2S2K$NX0"N5h8Y" +-T-NGqZ,XE0FFGa$B-p[SeYF0cADkVCQ+hU1(LKVZSVN8UkGCLreSCD,DeAdd&im +(+rkMaR,ejZE1"e+XVhYeR3kNa34iN!$ZKH%G+kS2a"Zm0K&lmd[bjS2KkqSGVEm +2E'p!%AYcb$"EEc5+NR'4,E6*h-!H$V5TC1%"ASC,UdAc`4U[h6!QlFK(EYTF'@p +hkc2eUrlME4LE)jmG"J*+iGALfIKRMAdpe*[cmr5j(G9Qh[KkNKh9cR5eFD6kNU+ +[r!`69PZBm-%@6X`MpNE['0l`8'LP38cikXl-0aYJChl9NHTILVXeaDeNZ21LThq +lq)4A#NZdUjlmlbS4GDY@b-Q%aZkh(p**8!&dSQY`6S)UQ"0HJA+Lbd$ZJLXBi$) +%MH*L#deZQk)+i2(i)RlCq$ai%eH"EU,,`"d,,KHX!0S%$N!f+@U!R8K3+AFCV&e +`IjZ@J0V&CQ%k&PKUK`T%%ed"D+,li*Ri-MLli&)TI@"1"TYUpF-`#5S`6(30KNP +3K@(#+c"-G"Q'AA#P[ef'S#PFE+8TUM!FMbrLNSh2`c"a&4JQZJc$XH"b`3S`61! +!$*1L"X1*"*9bPf(B"IHhD3Q'A@`@KQ1"TADS`$$4&4JQZJq'L5r$X!XZPE)-`qX +(Til#-!NU-%ad$BC*8)9K`LX`6(3CKPe`TEpGKU!TA'bP+DS`()m[iT+0cm-`F48 +B*VS-`l(JFX%+-%cJ!!b6SJE$L359FTGKf!AhYfN*KPeX&SCMJD9fU-!`d48B*VS +2KSN[`l!,,T8b"m1RC+P"BHU80(9#R"U8T`B%UY-59Ep)05"6R45U6NT9&E&U8+l +kVVKd5Pik*6!05%bR4DCqQDNU0!e)6B0Ldk$FG%Vk'44r6XNr*`5J33PS3!3k,32 +e#d%$8Y"*-HLN(&34K!BPSHm+1+FNR&-LcS#-FeV)kCGbUQ,1J*`c+1J-5MURj*9 +"JH@8a(*#C"Q8@3D%PY055lrB-L#hR"4F6NSZ&G&P8(EjVNKb5LBj*C3-5#@RaC* +qZD3UQ!a)*S1LbD"XNT`B,8NBk54jZ%YR+!*H1NN!HHN8HG",CmM"AMj"[Krc@C) +GQBp209kQF3,i+q4)BdXQK`q"kGJm#+BcP'!`RDB)K-8NrHA+J@%q`FRfb`*L2Mi +1L8&`AfrQB6'GS4mB+i*(1NNr-&C%Mh55!@$X&6l5'@V!@"8rmPP+R9N83$+0-`# +-C4%NNk-A'(Z&N!"dKP2!@"&$LNRkbe8$aUSNNXr5ehjPB#`+)lN%9@$X&8I5d*N +EH3J5e2!j0IU3!!iZL2RT($P"2jqJMerNK2ed(p5Uh$YM&@3)UPbH(%VRU&@j-%' +8MkqU"lND$ik[9!GB6JjN$)aNp!pP$)aP*!TINI$55IV*@dA'5bFC)'qp8Pik3if +m9H@mI*B5)"3P[8cM$*!!Yl+XPmR45pjkTEedKP2NV5,[&C2dPkY'hUSLAcj,ArZ +9b9Y4kXXPU*+hV0bApiI*iQ+3!#-*Ld'#$#S'19+J''4)BQ)K`FfG9M0@Zr$%@h1 +XE-[K2U+@iT-GA8SL$9d+GbeED,F8QPC5a0#TN!$#`p)J0!QP33+IiTAMqdVS5&i +3Qi2T)%X'TDXjDQhJBh3TrN4$*a#k&!j!Pf1VRC+%jb$"#A41XqBJK8qE5r(9q[V +%14-IL*j"MKSr##62)%Fr2mJ+RS8%9AjJReMK"aQjY"4IJj1d@&S+Vl9E2cr)+k@ +&&%9qN!$95B-%II`JUh+9%q6j39'$$E)-mS0!J5hNU2+$J[jD5P*Yk")rb)L[[I% +9IT!!P9k$"!2m)#-CPZ+VpHhM"i'Z&Z5SmB0!93Ybp21$V+C@5&$P"rD*&Ak3!&( +N5[%e1%RVFDA`@V[emi1m'&G)8H3(@5NZ50$($l)DF6P"RKm8CEiJbb!r#%5q3Si +U2bK)I+8NeBBZmB1-[YFEAq%(*p5p[1SHT1MM"fRG[46ZDJKiTA0Nq8'3!#2*$i) +%'Ai3j%MaJb"$NKm%#Ab!,m8RmD#842UP&&lVPa6!9e,%N!#YN!$#!rJJ0!R`33) +Ii-[aI59d!"r%jJ!qb*)"q'U1@K[i!&q+2p(3#B![K32`jGKUTb3"2NL3!!6i)%% +Di)-82X#AiU[e6IVbQAS1!Rb3!#-*m%'#$-!(19)!(f4)!Rb3!-!(q&*m%Jp+5D4 +I5Z'eINN"I#9&$0N++6b!$d+6!"mNm!'q(0pA3JI`3@`1i)-X'B#[jULeJ3r`TIJ +6$Cd!q&)i!&q1VAC+%Z#$"%Q!$a+N!6j)i30m+EjDhd%'ElYpDl@jFlDk-rmQ(X3 +bP0k`VMAp-+Vi1GK1*CK!F(&*8Z'#-N6#aDA)JiY+%JBAj*-%2bD*)hkJp*BINUe +K#[46B6'%Li9ji1kZNi$ZJP)pPi`5D%r'C!T5DVBFI,[)$'5Ril*&p+(CMbQd83+ +#r4"J0hQIVPB5APe3%P*G8"T'ACJ2RAj-ZKBq4")6f'5iZ#`X"@BB,Li(5eR,#aH +8JD@#XB8IQ+KKaViL9X-F,190+Q*KF9M+@P'iS"`XC3E%Nc'CJJ5`9$5eF*%",!A +@&E'i0#`9$#Vm`(3EqE#8FCj)a+4J+HX[iB,bX*3CC[GMdV9)`e)!59Ni#U!S"d0 +C#-V!6`&kdV#6JC`mh15K*J%c@BM*`8X'@V+`%N"+%8i#+!PJ*!-K"IK)3iF2'aR +)b-*&$LTL5aS9@%Fm1XXpiU%"!iP(jhK)2$E,4Z+K'8k5LXa#DLSm!@DT3"p1%jA +2FC9-F",X%m&ahK)2bV+AH'L1`k4M%d`Q(9NXAF"UiY&&EK12$aK10VUhp"QfNiU +X0QLDqD3#(Ip*4a@UQq9#mG"HQ#Z4khKd,mb9L(BmZJ4c"G)G$bh#A*Q!Tm+cA45 +3!2&%j8X`ed[-%m%CQ#Z3!24iD!RQ!X+HMLb@VJ*c&3SIMkr!A)R1*k),-&HQpUR +`3S2QB#iJqmR)!1B+a(pVIIY$A-l&CL(1"3B!jf*cm1BLXq$Q!M23jXGPqmB26R5 +0(qCh4kc118K,K5Dl1KBDKc-ANJ8c&jL$XQ4N!XL5F8'a!K"cX88)Fp%"J+9M#iA +1J*FI9fl"0($jB3kfNM(jDQBKb`9Q!@[Gk'KP,C(R2!"CmHJXD-9$!pL+4qH!+ak +EKDjiD!Dm8T(ChNQ&*lSR&HMh5U,b14$,"#Hl1a%F"l*i8"E+iU%j-%[(*Z!X(9N +XA3"TmHJLU-AM!eM,4[H@2J0YUFKUJkEK,4AS!#iG9DKZ&Z6LS39H9K)IA'b"Pj@ +%"aGEj'8&dF%&"VbX,$Mi`@P5%)J0X6SAH9Q[d"!,6I'bJXMJ!SZm,"!BNR&"X8U +mV#)YZ1J5,b[*#V(B2#mV5`TqF,i&-l`X%"-5F6PH9K!5iKV$ZRcll-kGH9%*-*5 +1AMmemB!bNCmqL!GRCK"5N4I06HHd["RG+V`X2Db3!!SX#S@9%K)GP,"hVLFHA#b +KLkb@-$m'P!S-q(433"HE+Tq,bKI2K@C+jmF9#ZFRb!X$3G&+`"'M,GQLpB+'#`f ++9J--2d%H0BYJi5M0KNCV1pKGNcG0Q3j8Qc8I9j!!1$hQd+X@!p!$Mb5&HF1qmmD +rT6p+JV,1+2%&h"XSG%c+kLed,,jFD+F3$6bb9ZKdJ[,F3+l3[R4BU%"5VmX@14Q +G,l%[JG@Hee[HI(L[k&BXE3fUNT5h80SqQ2*CC1ejeG*@!#SIA@#@)23!FT46q05 +N9X'"4bCTc-lC*KNb%&J)cr+f62$!``LI[k"ZP%M%JV,VZQLl'iUUr#FG[r$"QBE +c+i1e@Yf-8RG$RG*PlAmp'ITH6hcKp35@AqqkT[4f&epmZBY1[pZ&e9lGefmZ[[, +UI+qjX-+V`lbqh'j4N3heSU-fHp0-hZaQkm+DBE6rTTPfUqL@Ll,e6'bpjhT0YG& +Si4Df-@qdXl'YPD#)fN5ASQ"BfC!!@b2+49$fr05C$BV-CYAQ,CHfLNDYIjTellC +@K[TPKHZVDjpD[rbLfMRpP-,'#FN``9k)8CR0reLZZIIN-Z8)AJ&6R01)1AD0M'r +CCKBEQeNT*l,Z[SK-Aj!!*&ClZC6DFqXTPC&Y3q-E&KV!aXAl`5D9D[(!@29LYhE +c[4ZVdrPLaIeQm,0kpA34UI+C4V2PbfcX%PRA@m`aPG%%jc)@RZ&D)p13!,'fNiF +PZciINNP$Gq4$-QQSBMl%KjA$"j1QA-d,9ZIj92&#T)0bUH,&5!GYU-lN*IXb3AI +N"9eYeLE(81p)cZUNM%dF+V*S`HH(G(ppEEdJ*TZ)!J8af858*iM*@jAi26lc`[V +pH*X+5SANE8dLk`Jm8LhUH@GG4$6hhh2-cF&q)U-Rr-5FG5f`'a[$JfAD&,Th(iD +$iL0FE40AA@[(k0TE+j[bDZ%i8+lmX4GRHb!H@BT,i(iL@5`N8b9dX%20GBG)35Q +*)`[9$V06HcNZN@kKFM91p-ck`bf6CJ@C[LQ&ji2&HL5blZ#&Q$ji!F$KFq[YrU* +66*FAqrah3e&`FDaDCa9)Fh'S8mYMT1'GjYq0+2EHcHe'F(ecLi[EZr8'IfmU0ED +Mh1`TVQahqAqXHf@CB%marC3,`rpMeHeFl-eh0+TG(h1Xb(06APr[qVGlS5VfCPr +jekY,pd*KZJp@aZE`8NPYZ,,&k9kS6RFX6hH[2Yd(#p4pX%)Q`LX4&ek0ZRY&kMj +BTHjBTKZVHmSiqHmpfUZ([6K3RHjdChIX)0CFlDfA98X%FHG&QBY$jFYL&h%3-E- +,92&)8)RPdS(0NIb+HJHTLCFPlVc+QKKhBGj&!ab0&A"h8S"i+@bP[2ViY6*iF+M +9f0kD+pXJGV82@H1'SUaAr-VGQ2caUpZEpEP'2E4,iLjfCC)PlZblVbX,',mbL'A ++[@Hfk*5[L&qj'pX#lST'1TbcFkrA8pk9Zr(H*9IQ"Nb3!##j1Pc8Qpfb4q-hZeU +c"@`cNGS2L6@0LdQ8aBAijABaLAC*[-C9a)A%X-i&a-!Q8j98S@*3NkP+)X6[c8a +9dQ8R`'*c)NlZ$AqjP$&%2f-m*,8MYL8ImHZNBZd(`dr@6lB[hh'`X0!F`kRNJGh +ha1i*4(N1"Eqq,&Xk9bEq-(6V)&U$Akp%61`Ud@'*Q)6Fl"A-A@l)ZaYDphC"2)3 +E#)VI2BQBj'#TpkciYHQbJke!3e*A4pZ0ZL3QF4@V51)PANI0T+95!6C$3XG1*,H +j2'S%lh)APY6k!1%&q"#BM["ca&Sj'4$,kEGP1Q*IPM[KZQF([54hA#9kbBp2"AQ +*BPG"q,kib(YLr$@lfAYfr3YrMMFcZjZDedh1k'EQj6+@X9NhdB5cTKYP5mrGTQG +YCEif2RbAmR2-'#HQ"eLcIS+q-@$@#6(K#ZJF$K-1II%Te$flUX9-p4"T@8Z)DC& +i5*iLq5hU3V,FbQpc&j*P*$Rb%qIEQHFR8k6BQ'-mlMV,i(,X+8r&mTc4alTXL%P +mY&Fc3G&dK%NV%I&H-h#qDblm0kK1#KI"K4GLmL0XT9iN%BA*Xm+mQ%'b'jTA,$i +L&R"J@X3i8K*kpm"ib!'(*2CFAK-824DH[!qQGA)61SQTR0#a5Cc3KUq*A@,VbSf +RSb`-fl*dh*Ehhq'c#q5#"k&[J*!!`)1'J!IGpDXkZiUJ+R4RJHQ'XH'"q9[(AXZ ++QF&M4H[jHE'R`d#A'FbrVR!fRm'1ZdTpfNb`l3Nbfej'4+qVjF85BfL4i!Ierid +(4X)00k-,#6aJ(ra6H""f4Ki6H+!#(RJ1,EHhRAS2Ba1A%RMJk3FKE!K3a!0lUE- +60l@`GHVlkXE'*ST(ASfk[AYife4rifLHR#e$kV[hi$[Z1[U1[*P$pKfH"D3hCeE +i4Je16)`q8[PV19HhfrpCpbIHXAEmQMh(mKJI&!TEbl'fdAPiH1Rd1cE[,REdFcj +6elEbV@[A,`h3(cXR0`mY$I!1Lc$AlcU+-,i,6qpRhh(6p*&hj,e*NPm-1IGeCai +"%IZ1r8HlqR6IK``JqB([`8Hm(J-F"6HNlliM&)"CA$ib86RfeX%qSqr0,1Ak4pl +"YlFe2IY)Mi',eMdM&1!GI(1Q'`aVrV#ZpKhlUppMThEZLRHB!G`IpePff$[cG5d +p`5KlaNB[2TBRl8C@V2b1dBH4kV[[#!eJJYX[h[KI#*bb95Ym1dCEfjF'U%G)"6- +G`2+NY9cY(E21A5VJ(Id&qIYhe)$mIlpMN!!422'1'qD1&Z68&cDJ*2b`le&X3JB +8J)(Z5,ND9[[M-#iB)3([f(1N3`El)elA2EZqMBarril$4pMlB&eMl`J28%L1jMZ +A#-#c8!#P*Aa#f6LkUr%`AdalFKBq()A#!Gl"0iFQHDDZ1`kqidG0B[@'q$i%a54 +$PTj35%*101A`!!BA+U'pKLXJqHN[krH8q5BYqD%*QY,f9[jT6E$bMR#6kC!!Tc5 +iFRGm6i-lmBiR0EJ6lhK5Jc[jMLFdZ-&hK&*SF29lEpR2"&iNHrc@ekeF1hBUpar +)([r'IGRM2RA0SET1ZR9p0VlbcK9hR2abiq[hhPCEU%F)J`CADE5R0EM"GcbT`I8 +qi`FDh)Ph2+A"&4m54U$"pHF3rr16l`J&B0bBV!r@,'[%R[p#2l5m-U"p6mZV-TQ +`!#f[jb%T3VlfSG%YNipd%%`RI'+k+$aJ+LMXC(VQeU--cKKh-VNApr*-I6'Q%ci +aK@-mYhq-DGilISM!XHQCJ5QF[kY(q-hdc,'P!(`kc@)j#bqX,+k#NrP'ISF4Q)I +81[ST4R$L(8mbJK2[H",*6llM#53II%Gi!*+(,mc6pGBec''HVY*S6c1#`AFmb3K +kRr%$4R$L(8pTHF@(a0ia)$1CGpL0P%lJd*(m5*raL"Xk8C6SHdFSJ*E(&b)`,mC ++'08[SGK8%Gqmip$fhGpqarEYZapqKdc[XkCANF)0r4p[&I1+5Sjrm&DT[H2dY-U +J@Ka#-+hb)`q5'00j`S1NeKrK!@Vk2hKeP1[a2Dq1@Pe2UpHRqjl[5Bq0@MhX1jl +`aULp3hCeUJc#G5cj-3IR&6LSr02UGH8Gi44cF%pTAP5eGl,K(c@[%qpi8[-kmBi +R0Dq6lhK#maTm4hM!r0T6@P9[2@)-lLP0TrFG2p"d"YpaNJP@J&@qN!!+Pk4`!#d +QYAA!d%H")&X(0#DRj0$6,l@HR,H1BmM+&`ShJf5r-lL,$65L0chhr0,pHY+CFbZ +ZZI[*h+r+6RrarZa(VQXFUZ[%keGRQfjrdiTRAhfAmG'EUTpCU-FCIm8''Xr80Fc +"YIS-h@8$M4#iVfGbC2LdN5BDpX'm@aQHDcGDaAGpIcI"38KVZ%MSLPeUD-cA-($ +5l-D4UHc!THH(!'-frrR*Di1rG$IFDHRXXJ22I%Efm4qmZ[0f3LEdEFa1(K[HY!@ +RSHZRUS@Z-IG06Qeq)[F268b8cPV[f&b[UISm@XflSXU(L8H2qhLl++Fm2VHK86A +[ekH3!&(-rmHCa$LDpI@GY,jS`BM9MkjBj+(4HVD+[pH8GrZc-rRlKM,`hZb(q2H +0XQDcpF&@*j9hFl+ePDc[CmUlml+RmHr&-4p@qQq2GjZcl14ha#IZjY6Bjr,C!*! +!0A`-k,lrlHYffqX'"P5ejh4QQrhXiM'A)BZpXp2GcX$ZfTk"#rS[')$*(afSYZX +$5j)dJ%CS-+"SIk%[hmJe3q2VKpG8eU`IR"VNlik4SDNe5kXd3#-l*hKI$![-mN- +)KrZP60k1-d@B-(P'm2H@P+HG[lHQ2#2jHc$PkH6[SC4R&(m2Tca`cpY5RM(m2C, +bM1A[dC4R%Rr[6(NQmrHZP!ISZMrPJ5rAaccQUTaR0F&e+Fp'JTY5RNebq90jc)b +`1M(PkH([JC4R'hr[5AQB+AX6JS'(Kj8mGa2HN!$HFar"Be1HPa!m-Z9jJ1#1P1H +Pr,dqeI&"`M[6Hhk+i#NTcrd%Mcq@j``)i8[YF0EbD"*NKl2UAJ'KTamlR1'D9E2 +,$MIj3Z0QN!$1j#jf1(ZQVQ%11bHFD96XF&DrpjEpj4k9NlHqEZADX91jrd$fq$I +ZbalhU@X1eAA5VHZcmC9hVVMMj*FEAlrhYYT#2Fk-AhBiLpiA&3kd#FXePhHkeBI +dZ*!!K)qp3N*N2SYTCb!)fmVpMiq'!,D9q`UEbrREbRhQCVH91qBfF'(UfmU&ebJ +-pGRb93GYp@FLe*jcIiS,iaI#8"Zeq1T`Z@hckS'!8"JT[2NHk$E6p(RS([c#"k! +pqCC,qUlY1h%C5mkj,k5JCbZ2!L8F8X6%N!"5eH`3'cQLkdF[f6DpTekE+&UlYdi +bZK*G%U"`q[jKM[pAm1+kK6fFQcLhFDlLA-fjNA-,jpfFScR(F)lPR-3jQA-8CbG +R1fFEj`M1NC`c1'rK[)rc*C`2F,k8md&i01XDARCX,6b6Kh80RjhbG2$hmT5(G3f +[6(PBer#UP!IalHU8Kh80VdPj@0I`fT4R((q[5hPBer$'P!FamUD8"ijiAmV$91c +V8KkceQ(NG5N2`emReL%dHFckKj%hT$aQrF2)De)Hl%9HQ2+`rZ%9+3rV(cirjB( +aI#EPH5(KSe1H&r(h$5Q2@4-aFPh+BpBV2,R@SFPMeMp8I5N2DbGf(FYcjSh`SA2 +!$H&pjQcRl1$Xj"c&1CTcM*`I2JpAKiI$XH(2F'0i,j`@[JSAK4I#qH"cF$9iQ19 +BU686KckD"&NcXES19HMTjiEU&erdX,0`@-NA#MH$C,m`932+-&V$Y-B!KXm`2XY +d3L(S6ZScQaX0f65qDA"XZ(pifcG`hNlH@[CVrXMrV*d4,hRb`C%$R(rqD1jLEG2 +S6Fmp[p3"*jdjYq+DZjr-rDVXp"I[chlNZXDKZNkmIR@fkIBhVAMfeAFC(lfTqTQ +&HTca9kaYqNaG`aa@[6XMGeREp!`%BCR0,5b`bFFbQlZZ[AHCcBh2F*R0SfmR*,a +NQFd`Qp8G)kG2GQYZmm,-c0&@)lp[QM@ffCieRq+NdbllNb83DK0HYlTM+!`'K-4 +mBET,iRA'T461l"1B8qN,SpMX08aJ1BNcq35qH(+YNc2["8BCEX)+``MH-j(c#h& +$V5r'kGqrF#mpmhdTX[-[Pa[c4V)[aXlkDScrbh#[IMM'I5h'ICeYfIRqUTaBMQ4 +ha[ar(E[UEf+qEf52+IrrEAcR0m0rY6UqkqciIhVm2b2Qr9CmclGMh-3BpeKmrq1 +aMYm*HEb1#G9P8Q&RAi`(0@qmZ$AEV'%T9NaNA38`46*XLSdP[c1rG@66qZCXB`N +!"l,3d!r"+DA6%f#$E(4LU6FAP2P#!0Ce-kqUVrDhC[r[%H"mcf$T31-@KJSGk*2 +HZc1lK1q-*81&5Ba0Kq'S-'Gf#9p)mIa,b)ZbmVekrYqlm,E[c(3"!cc"4B`(*55 +FaVR90SPDJ3fI$!,92Y4HqDVf`#@a+a`#&d*PqMl4UfG5%MJCl`SDZCd6Kfq'mh( +%EZ$%+4ZAl$'FZ(@c-eJ(j`M1PSJ&Z(HhFJlPC0q`8C`iGSrN(-[Cb6PZ+BIb[Qf +1lESL-jhZi9hIM[eUPUdf,MdK1KERmk('(6cF*M2j-j1iQqm0Dq"p)q2lkQlV"AD +r`VE`hZI(+4E5Uir[mq0QdLI0qfHkjHD1#D4U)&rN,Z,BBM)4erK-rR60G$Z(mc@ +k$CV8bArIX"qMc@I2Y$Z(ihEF4)[[RHRZ2&bR4VCDLjc+ZkPhiRe0lqI2Vmed'ke +liaEZ*IqULG&10e[q"AGIQacL1Rq$2h2+AGEU2[3HlXi,F3HI$p4X#R([(65(&cI +bAm8J,qjAAX$Gh""hP(k0V!jahcR("T2hI8aFmZ)qi@k$bf+q4rRc8"NAIHSRZ9X +Hqjlpe6D(I!ql41D+%0IbjX9q5K#ECc1('1[,4&bcZ9eI*Z)Dpbhf65+ZjAf,IC1 +)fr2V[IlirFZiNeeqphbdeam(a9AC$(1IQ#Vpm4XIjUiRa"e`efhTM`FrapeP-Hj +RH[eal58@91*H[G!IGDqmNl[,Ber5Rejr4+IXb5Y#A)Fpj08TqT+riNj`m"G@,p3 +THVUB)CZUYPqd8+IS#phD8RC,I35mP$T&Alk&ZcXLlKVmN!!k45rl-qi-2YKm2pI +Vil2&0[+$kp4'k[4+0d58h9mll$q[6[T*Rq)12+&pIRDK6VV2A[pfL"[bSB8kkCF +kFrTBL*Yaad+Gp-@rc0hMXBrT6kp1H[LVh*PGk[L@[R1K6ZV2k5d(MGeLQeFRYCq +P&Kh$(Q+0Qd,rIH9hL9XCFAU5A-UVklV2%bFlZcA*2b6IPrqCZ+YM(*[SHIRUAJY +h8qAZGbD1hHfmI0'9p*EbAB5mTjI[VKF6*cMG4"p,(far#RdJHq"&6KBc[,KYY3Z +)Hh1Xhk[i-cA8pHh'I65q!kiRrG&XAF&R)2'qKIl3,`*Ve0q%Z+%Z-1ReKci$6U6 +q0[)!qY*lRck0RPIr&2[l&EhhcB5R+V',IUAZdRm["`m82@*j#FZmbIZ@`@r99b* +1rc*raT9aNAH!P9VqDm,(mGDfDd2FErdLFI"Gmld+rY%3qLEb02L`PYqDI,2Jah0 +[$A&AITBiq+lj4T!!3adIiUk&HfKj-Hrq2B[VaGh`am5"lF4pDU'ZN5IF5KbFQcJ +ifA$MMXrrfpR%JIrJUhQ61LlNqp3r%LFFZdQHXc,%(3*lY([rm3lUEYpKS28"iLC +%r[3R[%0f$A`aNp[DA4piKmNK1"(jrp4'4r`B$BG6TiDii@ka*rJa",i5Z6$%IC' +HeR'Rf(fmThiLe1qVD!Mk#5(ZY@q&,lD(I!rF6Gc8%0FU"lSqa+hm#q+Q44b#-bd +*F4I6NeUmSNlS&F0Lhm`Qc[5)M3-RT-q@fdr6Babm6ITXrkZ*NfA[4UTcr(D)H`p +[dq+YqFj'$e"RKEK4p,D@Hj)2h(mia!eP0d)0[lCi4RpErR&mrN[`84ehqecm,Zk +NRbDq4#iZIB-Z)6Md+*a@"hkXR[A&(Jlp+9a,"hkXpVb`Kd26fDT9"hkXpY+[$SI +Qd%-kEUJi(plTF1J&Vb,1B,AY*lLAp-HGRb"Z3Dc(bhVpd3'2e%q*G@9h4-'26R" +D2cA%E8,RF$Kd%Ea(Xd1LlH0hpA$SCA"F(IF5(UDZ*1qiiUA%A4$L0X06(3jp4*b +!2e)RH+h8qe*Lp)q(Z0Ir83q(ERdpFD)(Y)Q$JN-cl$p2$e$Ai4cLiC!!@9'$r[$ +d!(8pQaFk(2ShD"XkkJ&M`"k(3epq*A(#cpVNiB*$M@#"M[bXaIF,$Mh(ZSTr3E[ +i+(dfrAELi)1d'$a-qZc2i-BkEPSl(ClUF1Kcm%XGYdImHIL3!-1KYlfE10Q%GXQ +024cDLGDLikSI(El(im'4#ATBK`eXe9XqeX1Kc3HiJpp42rLcdcqmc6PX[VGm'Fc +m303riR'40kZ2I6VU(iQi$KeDR2i4Mp1VA(GiAp3r%[R'LSq#IbhL)VU@HIH[`9m +GrVd@(Up(3Yb(U+Z(ImIRri%lc@k5a2hqTKlqADA@*6V+'cl6`lpAQdpdP!jjTr6 +P#ML%MMV+-(QGlF[MmhI"QcA[XR@LVi5(I84H*AZd[J9mF[MhN!$i,FXr,j!![`V +qAB9fSXXG+mdlf#YIm1qem'1p1G6[@q#T`lqAL+qbIhi,f1EKhr(j[r`)FHKA*Y9 +MD+`1rqTrMMM`h(a,h5&6m'mY'S'@6jP8Mm2I(!rl@lL3!0iDqV*1(9,`le+iVik +kdI9I1SKraqFr)$m6h@L2pE,iGhcqGM"H4peS*(c&iGp9k-3kkNB,ZA0pGJ303$m +RpJ&i)(hfQ(Km9BKlUhJLq(H*20[61I4ap+Z(ImIRhb0HHMU(2PiG3["[S4a,&SF +p+Mm8([B&qEfhEV-q!9cfm1rir#I4)(6Fd,VeAaEa,llITPi&$fLk,H*I)Zj4GCc +24[b,ad9'hD$@i9mLhbKU%m1r4,iMERlTi9rG(iKcKYq4Ec3mAr![qMbd62fL%$I +M,3[mVqjkZ)F15f[VTi'TJRpe0mK6Aa$LKS"hJRr4Xq`ESrPBR(MP3Pp'XlmMcQ# +[VCr*iI6#0m+9pG8acR!D`DhSFm3RlXhI&R"+m#pk$KLKeAQS+hUKKhr4&k$&k*G +&r%"AN!"hX$QT$MU62NqYb-1rZLqK9HMr&h%DMG29qeH*)cqdefJcJRr4R`!l0$c +8pMhij1&Ip!`d"5fI0Arh`Q@&rp@pPEN'$DFMEYk[,H"Ih4[T-Id,i4e[**r`[qK +b0!r0HrRHl2XprKGYJR&DcC0hdbFHrNA24[[3kUl`*(L&p0RH$a,h81`$F%[dc[2 +3ZE@m$lS06RMi&jeKGe-0CbGZ2ca@q&rGAm1400S&FEI)%ccmLfk&BfYe$qU%rLf +kmLr"bEAp6MkMK`VrUrX!ZE9e-(m2fK1HAKKj#4LQj4hQlf&Q1qSLRhL1ld!,jAe +SXCiq&aN&Fl9kX[NHNFm,hSpr'h(SYm6"ai6RAI%QiPi6hMId$rRRkAD4[@J6@Th +Ir$hI2[0dZmLBZSlT8q+1bVfN6S[S#DhHDrlH$MpdGET'r[(kq!jd5DR6@,LG9Qq +(ek+h5CfDj8RHRUakcXehT%j[KPYVDQAMk$HTdb'iR9C$0Rr[kZQ,NBYqM`"2(p9 +AbKfP6K2JkYSj#22hERLfUe1RrIe`L,Z(A[(UC2LCd@)d1'rj4a`r)Um'1c5kQFh +h"ldkGGe-!2Q*-jcHeHQ2k@hY,!Ed!Aj[kh4mrJjjfb-alS1p1Vd0E8@(29reci0 +9VNl23S28kY[d2Ea3k[40Z,j@4b81RLae@Lm2"XISEhLMe1R6B)%11mAUUpACT8k +[&+F0YK2h)R&@qZNAdBVdlm3q0K`dFXS-HjV(Z40apkR(I@QQHYr'fir)JcfFDhi +E'V5'Aj!!lhki8AfSGr-Pe%kMT4$h-R6+ZX!2QRm*,926bm3pf01IQYk2VUc9YBL +MRlak0rmQ'V4fYS8iH-A9)@kRZLNk$h(`L6H'Z!I%!h!2qN#pjAh[rJ)"4YHbF3C +2ACeZG6NKG"jJhf#'e+RTYp'U0"SbFDp5(jGk2b`rH(q-3kH81Xf#NqL`DDaq[EU +fe1P+HPZr0mBaKq(9UHNVmM0i",#2VLh[Hm"h'pb`F8E2P6SeI36Xdmie!0HQ,ed +rrD5D%r-[`#pp)rAq1*U)GTk)12LN9kHQVm)9p3GL($c%Ue26qq3I[a[MQ,f3!$T +p5pd4[3iHKQiZGCU#4U$9Bi(hH$mel9HI0[K'h-1pIQVq@IX!hBCh`0qN6Tm8bm& +Em!bq,rh8U2i02`9qk6qTdjqM9@Zd'Z,HUZiMIIm+Z)K@*`GqdF'ppcAHBTfBU5% +1r9IH[3*ZS1NG'iIZ+A'2q1k24(k*VL&a9cPRi-eKk0qbYlbjMBEIK`2V-)HKhiP +1*('0Tk(Yk6#(SGmPGjGmAd-ld'%13pmJYjDicm*&0&SaFEr1ZpAji4hhUQ-C$B' +iGpJhZd2F,(NB1J"aCMBLmUS3plKkkLG#h$["!q(aM4H+LfBHMEKh`IrGqckYR[( +*%2GZF9EHph*a&ai(c$+(+1qE3UpUjKTXR1'"lRdcl32$PBKl,rc%[HpCkVl-#J' +rr*IhVD8(p+G$h2[8YH9pCm%4p5dacZ#1Hpm'iicH50a[dJrZIBqTVe0ri*Fj5RR +I+p&H0E-*0Jlp5plh#E"!bq1)-h0)lRd2b*rXM0lr"`#3!edP!!!: diff --git a/macos/osdep.h b/macos/osdep.h new file mode 100644 index 0000000..5a69033 --- /dev/null +++ b/macos/osdep.h @@ -0,0 +1,118 @@ +/* + Copyright (c) 1990-2007 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#ifndef __MACOS_OSDEP_H +#define __MACOS_OSDEP_H 1 + +#ifndef MACOS +# define MACOS +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "unixlike.h" +#include "macglob.h" + +#define NO_MKTEMP 1 +#define PASSWD_FROM_STDIN 1 +#define NO_SYMLINKS 1 + +#define USE_ZIPMAIN 1 + +#define USE_CASE_MAP 1 /* case_map is used to ignore case in comparisons */ + + + + +/* +#define DEBUG_TIME + */ + +#if (!defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME)) +# define USE_EF_UT_TIME +#endif + +#undef IZ_CHECK_TZ + +#ifndef ZP_NEED_MEMCOMPR +# define ZP_NEED_MEMCOMPR +#endif + + +#define EXDEV 18 + +#define PATHCUT ':' + + +/* file operations use "b" for binary */ +#define FOPR "rb" +#define FOPM "r+b" +#define FOPW "wb" + +/* +#define DEBUG +*/ + +/* These functions are defined as a macro instead of a function. +so we have to undefine them for replacing (see printf.c) */ +#undef getc +#undef getchar +#undef putchar + + + +void setfiletype(char *file, unsigned long Creator, unsigned long Type); + +char *GetZipVersionsInfo(void); +char *GetZipVersionLocal(void); +char *GetZipCopyright(void); + +void InitAllVars(void); + +void PrintFileInfo(void); + + + +int fprintf(FILE *file, const char *format, ...); +int printf(const char *format, ...); +void perror(const char *parm1); +int macgetch(void); + + +int MacOpen(const char *path,int oflag,...); +FILE *MacFopen(const char *path,const char *mode); +#define fopen(path, mode) MacFopen(path, mode) +#define open(path, oflag) MacOpen(path, oflag) + + +char *GetComment(char *filename); +int readlink(char *path, char *buf, int size); + +void PrintStatProgress(char *msg); +void InformProgress(const long progressMax, const long progressSoFar ); +void ShowCounter(Boolean reset); +void leftStatusString(char *status); + + + + +#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \ + procname(n, 1)) + +#endif /* __MACOS_OSDEP_H */ diff --git a/macos/readme.1st b/macos/readme.1st new file mode 100644 index 0000000..6182756 --- /dev/null +++ b/macos/readme.1st @@ -0,0 +1,16 @@ +This port is for Mac versions before Mac OS X. As Mac OS X is build on Unix, +use the Unix port for Mac OS X. - 7 June 2008 + + +Before you start: + +Extract "*.hqx" and "source:*.hqx" first and read the Readme.txt. + +The resource file and the compiler project files are in BinHex form because +they contain Macintosh resource forks and as such can not be simply +stored a normal file on a non-Macintosh system. BinHex form is the +traditional way for transferring such files via non-Macintosh systems. +It's also the safest since it uses only printable characters. The ".hqx" +files must be converted with StuffitExpander or BinHex 4.0 (or equivalent) +on a Macintosh system before using them. + diff --git a/macos/source/VolWarn.h b/macos/source/VolWarn.h new file mode 100644 index 0000000..2d921eb --- /dev/null +++ b/macos/source/VolWarn.h @@ -0,0 +1,69 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/* + +This is an Important note about pathnames + +*/ + +static char DuplicVolumeNote[] = { + "\rIMPORTANT NOTE:" \ + "\r" \ + "\r This port has one weak point: It is based on pathnames !! " \ + "\r Because it's a port !! Unlike MacOS: As far as I know all other "\ + "\r Operatingsystems (eg.: Unix, DOS, OS/2, ...) are based on pathnames" \ + "\r " \ + /* a short quote from "Inside Macintintosh, Files"; slightly modified by me */ + "\r On a Mac: Files and directories located in the same directory " \ + "\r must all have unique names. However, there is no requirement " \ + "\r that volumes have unique names. It is perfectly acceptable for two mounted" \ + "\r volumes to have the same name. This is one reason why a application should " \ + "\r use volume reference numbers rather than volume names to specify volumes," \ + "\r but for this Zip-Port I can't use reference numbers. " \ + "\r " \ + /* end quote */ + "\r" \ + "\r From the developers point of view:"\ + "\r The use of pathnames, however, is highly discouraged. If the user changes"\ + "\r names or moves things around, they are worthless." \ + "\r Full pathnames are particularly unreliable as a means of identifying files," \ + "\r directories or volumes within your application," \ + "\r for two primary reasons:" \ + "\r" \ + "\r* The user can change the name of any element in the path at" \ + "\r virtually any time." \ + "\r* Volume names on the Macintosh are *not* unique. Multiple" \ + "\r mounted volumes can have the same name. For this reason, the use of" \ + "\r a full pathname to identify a specific volume may not produce the" \ + "\r results you expect. If more than one volume has the same name and" \ + "\r a full pathname is used, the File Manager currently uses the first" \ + "\r mounted volume it finds with a matching name in the volume queue." \ + "\r" \ + "\r" \ + "\r The main reason is that an attempt to implement support exact saving of" \ + "\r the MacOS specific internal file-structures would require a throughout" \ + "\r rewrite of major parts of shared code, probably sacrifying compatibility" \ + "\r with other systems." \ + "\r I have no solution at the moment. The port will just warn you if you try" \ + "\r zip from / to a volume which has a duplicate name." \ + "\r MacZip has problems to find the archives and files." \ + "\r" \ + "\r" \ + "\r ... and the moral of this story:" \ + "\r" \ + "\r Don't mount multiple volumes with the same " \ + "\r name while zip/unzip is running" \ + "\r and "\ + "\r My (Big) recommendation: Name all your volumes with a unique name "\ + "\r (e.g: add a space character to the name) and" \ + "\r MacZip will run without any problem." \ + "\r" \ + "\r" \ + "\r Dirk Haase" \ + }; diff --git a/macos/source/charmap.h b/macos/source/charmap.h new file mode 100644 index 0000000..5656b63 --- /dev/null +++ b/macos/source/charmap.h @@ -0,0 +1,380 @@ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#ifndef __macos_charmap_h +#define __macos_charmap_h + +/* + +Conversion table from MacOS Roman to +"Western Europe & America" Windows codepage 1252 + + Notes on Mac OS Roman: + ---------------------- + + Mac OS Roman character set is used for at least the following Mac OS + localizations: U.S., British, Canadian French, French, Swiss + French, German, Swiss German, Italian, Swiss Italian, Dutch, + Swedish, Norwegian, Danish, Finnish, Spanish, Catalan, + Portuguese, Brazilian, and the default International system. + + Not every char of the charset MacRoman has their equivalent + in Windows CodePage1252. + To make the mapping in most cases possible, I choosed + most similar chars or at least the BULLET. Chars that + do not have a direct match are marked with '***' + + The Windows codepage 1252 contains the ISO 8859-1 "Latin 1" codepage, + with some additional printable characters in the range (0x80 - 0x9F), + that is reserved to control codes in the ISO 8859-1 character table. + +In all Mac OS encodings, character codes 0x00-0x7F are identical to ASCII + +*/ + + + +ZCONST unsigned char MacRoman_to_WinCP1252[128] = { +/* Win CP1252 UniCode UniCode Names */ + 0xC4 , /* 0x00C4 #LATIN CAPITAL LETTER A WITH DIAERESIS */ + 0xC5 , /* 0x00C5 #LATIN CAPITAL LETTER A WITH RING ABOVE */ + 0xC7 , /* 0x00C7 #LATIN CAPITAL LETTER C WITH CEDILLA */ + 0xC9 , /* 0x00C9 #LATIN CAPITAL LETTER E WITH ACUTE */ + 0xD1 , /* 0x00D1 #LATIN CAPITAL LETTER N WITH TILDE */ + 0xD6 , /* 0x00D6 #LATIN CAPITAL LETTER O WITH DIAERESIS */ + 0xDC , /* 0x00DC #LATIN CAPITAL LETTER U WITH DIAERESIS */ + 0xE1 , /* 0x00E1 #LATIN SMALL LETTER A WITH ACUTE */ + 0xE0 , /* 0x00E0 #LATIN SMALL LETTER A WITH GRAVE */ + 0xE2 , /* 0x00E2 #LATIN SMALL LETTER A WITH CIRCUMFLEX */ + 0xE4 , /* 0x00E4 #LATIN SMALL LETTER A WITH DIAERESIS */ + 0xE3 , /* 0x00E3 #LATIN SMALL LETTER A WITH TILDE */ + 0xE5 , /* 0x00E5 #LATIN SMALL LETTER A WITH RING ABOVE */ + 0xE7 , /* 0x00E7 #LATIN SMALL LETTER C WITH CEDILLA */ + 0xE9 , /* 0x00E9 #LATIN SMALL LETTER E WITH ACUTE */ + 0xE8 , /* 0x00E8 #LATIN SMALL LETTER E WITH GRAVE */ + 0xEA , /* 0x00EA #LATIN SMALL LETTER E WITH CIRCUMFLEX */ + 0xEB , /* 0x00EB #LATIN SMALL LETTER E WITH DIAERESIS */ + 0xED , /* 0x00ED #LATIN SMALL LETTER I WITH ACUTE */ + 0xEC , /* 0x00EC #LATIN SMALL LETTER I WITH GRAVE */ + 0xEE , /* 0x00EE #LATIN SMALL LETTER I WITH CIRCUMFLEX */ + 0xEF , /* 0x00EF #LATIN SMALL LETTER I WITH DIAERESIS */ + 0xF1 , /* 0x00F1 #LATIN SMALL LETTER N WITH TILDE */ + 0xF3 , /* 0x00F3 #LATIN SMALL LETTER O WITH ACUTE */ + 0xF2 , /* 0x00F2 #LATIN SMALL LETTER O WITH GRAVE */ + 0xF4 , /* 0x00F4 #LATIN SMALL LETTER O WITH CIRCUMFLEX */ + 0xF6 , /* 0x00F6 #LATIN SMALL LETTER O WITH DIAERESIS */ + 0xF5 , /* 0x00F5 #LATIN SMALL LETTER O WITH TILDE */ + 0xFA , /* 0x00FA #LATIN SMALL LETTER U WITH ACUTE */ + 0xF9 , /* 0x00F9 #LATIN SMALL LETTER U WITH GRAVE */ + 0xFB , /* 0x00FB #LATIN SMALL LETTER U WITH CIRCUMFLEX */ + 0xFC , /* 0x00FC #LATIN SMALL LETTER U WITH DIAERESIS */ + 0x86 , /* 0x2020 #DAGGER */ + 0xB0 , /* 0x00B0 #DEGREE SIGN */ + 0xA2 , /* 0x00A2 #CENT SIGN */ + 0xA3 , /* 0x00A3 #POUND SIGN */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 #BULLET */ + 0xB6 , /* 0x00B6 #PILCROW SIGN */ + 0xDF , /* 0x00DF #LATIN SMALL LETTER SHARP S */ + 0xAE , /* 0x00AE #REGISTERED SIGN */ + 0xA9 , /* 0x00A9 #COPYRIGHT SIGN */ + 0x99 , /* 0x2122 #TRADE MARK SIGN */ + 0xB4 , /* 0x00B4 #ACUTE ACCENT */ + 0xA8 , /* 0x00A8 #DIAERESIS */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xC6 , /* 0x00C6 #LATIN CAPITAL LETTER AE */ + 0xD8 , /* 0x00D8 #LATIN CAPITAL LETTER O WITH STROKE */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xB1 , /* 0x00B1 #PLUS-MINUS SIGN */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x00A5 #YEN SIGN */ + 0xB5 , /* 0x00B5 #MICRO SIGN */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xAA , /* 0x00AA #FEMININE ORDINAL INDICATOR */ + 0xBA , /* 0x00BA #MASCULINE ORDINAL INDICATOR */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xE6 , /* 0x00E6 #LATIN SMALL LETTER AE */ + 0xF8 , /* 0x00F8 #LATIN SMALL LETTER O WITH STROKE */ + 0xBF , /* 0x00BF #INVERTED QUESTION MARK */ + 0xA1 , /* 0x00A1 #INVERTED EXCLAMATION MARK */ + 0xAC , /* 0x00AC #NOT SIGN */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x83 , /* 0x0192 #LATIN SMALL LETTER F WITH HOOK */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xAB , /* 0x00AB #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ + 0xBB , /* 0x00BB #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ + 0x85 , /* 0x2026 #HORIZONTAL ELLIPSIS */ + 0xA0 , /* 0x00A0 #NO-BREAK SPACE */ + 0xC0 , /* 0x00C0 #LATIN CAPITAL LETTER A WITH GRAVE */ + 0xC3 , /* 0x00C3 #LATIN CAPITAL LETTER A WITH TILDE */ + 0xD5 , /* 0x00D5 #LATIN CAPITAL LETTER O WITH TILDE */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x96 , /* 0x2013 #EN DASH */ + 0x97 , /* 0x2014 #EM DASH */ + 0x93 , /* 0x201C #LEFT DOUBLE QUOTATION MARK */ + 0x94 , /* 0x201D #RIGHT DOUBLE QUOTATION MARK */ + 0x91 , /* 0x2018 #LEFT SINGLE QUOTATION MARK */ + 0x92 , /* 0x2019 #RIGHT SINGLE QUOTATION MARK */ + 0xF7 , /* 0x00F7 #DIVISION SIGN */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xFF , /* 0x00FF #LATIN SMALL LETTER Y WITH DIAERESIS */ + 0x9F , /* 0x0178 #LATIN CAPITAL LETTER Y WITH DIAERESIS */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xA4 , /* 0x00A4 #CURRENCY SIGN */ + 0x8B , /* 0x2039 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK */ + 0x9B , /* 0x203A #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x87 , /* 0x2021 #DOUBLE DAGGER */ + 0xB7 , /* 0x00B7 #MIDDLE DOT */ + 0x82 , /* 0x201A #SINGLE LOW-9 QUOTATION MARK */ + 0x84 , /* 0x201E #DOUBLE LOW-9 QUOTATION MARK */ + 0x89 , /* 0x2030 #PER MILLE SIGN */ + 0xC2 , /* 0x00C2 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ + 0xCA , /* 0x00CA #LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ + 0xC1 , /* 0x00C1 #LATIN CAPITAL LETTER A WITH ACUTE */ + 0xCB , /* 0x00CB #LATIN CAPITAL LETTER E WITH DIAERESIS */ + 0xC8 , /* 0x00C8 #LATIN CAPITAL LETTER E WITH GRAVE */ + 0xCD , /* 0x00CD #LATIN CAPITAL LETTER I WITH ACUTE */ + 0xCE , /* 0x00CE #LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ + 0xCF , /* 0x00CF #LATIN CAPITAL LETTER I WITH DIAERESIS */ + 0xCC , /* 0x00CC #LATIN CAPITAL LETTER I WITH GRAVE */ + 0xD3 , /* 0x00D3 #LATIN CAPITAL LETTER O WITH ACUTE */ + 0xD4 , /* 0x00D4 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xD2 , /* 0x00D2 #LATIN CAPITAL LETTER O WITH GRAVE */ + 0xDA , /* 0x00DA #LATIN CAPITAL LETTER U WITH ACUTE */ + 0xDB , /* 0x00DB #LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ + 0xD9 , /* 0x00D9 #LATIN CAPITAL LETTER U WITH GRAVE */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x88 , /* 0x02C6 #MODIFIER LETTER CIRCUMFLEX ACCENT */ + 0x98 , /* 0x02DC #SMALL TILDE */ + 0xAF , /* 0x00AF #MACRON */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xB8 , /* 0x00B8 #CEDILLA */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 /* 0x2022 # *** BULLET */ + }; + + + +ZCONST unsigned char WinCP1252_to_MacRoman[128] = { +/* Mac Roman UniCode UniCode Names */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xE2 , /* 0x201A # SINGLE LOW-9 QUOTATION MARK */ + 0xC4 , /* 0x0192 # LATIN SMALL LETTER F WITH HOOK */ + 0xE3 , /* 0x201E # DOUBLE LOW-9 QUOTATION MARK */ + 0xC9 , /* 0x2026 # HORIZONTAL ELLIPSIS */ + 0xA0 , /* 0x2020 # DAGGER */ + 0xE0 , /* 0x2021 # DOUBLE DAGGER */ + 0xF6 , /* 0x02C6 # MODIFIER LETTER CIRCUMFLEX ACCENT */ + 0xE4 , /* 0x2030 # PER MILLE SIGN */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xDC , /* 0x2039 # SINGLE LEFT-POINTING ANGLE QUOTATION MARK */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xD4 , /* 0x2018 # LEFT SINGLE QUOTATION MARK */ + 0xD5 , /* 0x2019 # RIGHT SINGLE QUOTATION MARK */ + 0xD2 , /* 0x201C # LEFT DOUBLE QUOTATION MARK */ + 0xD3 , /* 0x201D # RIGHT DOUBLE QUOTATION MARK */ + 0xA5 , /* 0x2022 # BULLET */ + 0xD0 , /* 0x2013 # EN DASH */ + 0xD1 , /* 0x2014 # EM DASH */ + 0xF7 , /* 0x02DC # SMALL TILDE */ + 0xAA , /* 0x2122 # TRADE MARK SIGN */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xDD , /* 0x203A # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xD9 , /* 0x0178 # LATIN CAPITAL LETTER Y WITH DIAERESIS */ + 0xCA , /* 0x00A0 # NO-BREAK SPACE */ + 0xC1 , /* 0x00A1 # INVERTED EXCLAMATION MARK */ + 0xA2 , /* 0x00A2 # CENT SIGN */ + 0xA3 , /* 0x00A3 # POUND SIGN */ + 0xDB , /* 0x00A4 # CURRENCY SIGN */ + 0xB4 , /* 0x00A5 # YEN SIGN */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xAC , /* 0x00A8 # DIAERESIS */ + 0xA9 , /* 0x00A9 # COPYRIGHT SIGN */ + 0xBB , /* 0x00AA # FEMININE ORDINAL INDICATOR */ + 0xC7 , /* 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ + 0xC2 , /* 0x00AC # NOT SIGN */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA8 , /* 0x00AE # REGISTERED SIGN */ + 0xF8 , /* 0x00AF # MACRON */ + 0xA1 , /* 0x00B0 # DEGREE SIGN */ + 0xB1 , /* 0x00B1 # PLUS-MINUS SIGN */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xAB , /* 0x00B4 # ACUTE ACCENT */ + 0xB5 , /* 0x00B5 # MICRO SIGN */ + 0xA6 , /* 0x00B6 # PILCROW SIGN */ + 0xE1 , /* 0x00B7 # MIDDLE DOT */ + 0xFC , /* 0x00B8 # CEDILLA */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xBC , /* 0x00BA # MASCULINE ORDINAL INDICATOR */ + 0xC8 , /* 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xC0 , /* 0x00BF # INVERTED QUESTION MARK */ + 0xCB , /* 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE */ + 0xE7 , /* 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE */ + 0xE5 , /* 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ + 0xCC , /* 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE */ + 0x80 , /* 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS */ + 0x81 , /* 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE */ + 0xAE , /* 0x00C6 # LATIN CAPITAL LETTER AE */ + 0x82 , /* 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA */ + 0xE9 , /* 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE */ + 0x83 , /* 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE */ + 0xE6 , /* 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ + 0xE8 , /* 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS */ + 0xED , /* 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE */ + 0xEA , /* 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE */ + 0xEB , /* 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ + 0xEC , /* 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0x84 , /* 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE */ + 0xF1 , /* 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE */ + 0xEE , /* 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE */ + 0xEF , /* 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ + 0xCD , /* 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE */ + 0x85 , /* 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xAF , /* 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE */ + 0xF4 , /* 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE */ + 0xF2 , /* 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE */ + 0xF3 , /* 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ + 0x86 , /* 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA7 , /* 0x00DF # LATIN SMALL LETTER SHARP S */ + 0x88 , /* 0x00E0 # LATIN SMALL LETTER A WITH GRAVE */ + 0x87 , /* 0x00E1 # LATIN SMALL LETTER A WITH ACUTE */ + 0x89 , /* 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX */ + 0x8B , /* 0x00E3 # LATIN SMALL LETTER A WITH TILDE */ + 0x8A , /* 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS */ + 0x8C , /* 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE */ + 0xBE , /* 0x00E6 # LATIN SMALL LETTER AE */ + 0x8D , /* 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA */ + 0x8F , /* 0x00E8 # LATIN SMALL LETTER E WITH GRAVE */ + 0x8E , /* 0x00E9 # LATIN SMALL LETTER E WITH ACUTE */ + 0x90 , /* 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX */ + 0x91 , /* 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS */ + 0x93 , /* 0x00EC # LATIN SMALL LETTER I WITH GRAVE */ + 0x92 , /* 0x00ED # LATIN SMALL LETTER I WITH ACUTE */ + 0x94 , /* 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX */ + 0x95 , /* 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0x96 , /* 0x00F1 # LATIN SMALL LETTER N WITH TILDE */ + 0x98 , /* 0x00F2 # LATIN SMALL LETTER O WITH GRAVE */ + 0x97 , /* 0x00F3 # LATIN SMALL LETTER O WITH ACUTE */ + 0x99 , /* 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX */ + 0x9B , /* 0x00F5 # LATIN SMALL LETTER O WITH TILDE */ + 0x9A , /* 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS */ + 0xD6 , /* 0x00F7 # DIVISION SIGN */ + 0xBF , /* 0x00F8 # LATIN SMALL LETTER O WITH STROKE */ + 0x9D , /* 0x00F9 # LATIN SMALL LETTER U WITH GRAVE */ + 0x9C , /* 0x00FA # LATIN SMALL LETTER U WITH ACUTE */ + 0x9E , /* 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX */ + 0x9F , /* 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xD8 /* 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS */ + }; + + +/* + +The following characters has no equivalent +to each other: + +MacCodes +164 0xA4 0x00A7 # SECTION SIGN +253 0xFD 0x02DD # DOUBLE ACUTE ACCENT +189 0xBD 0x03A9 # GREEK CAPITAL LETTER OMEGA +185 0xB9 0x03C0 # GREEK SMALL LETTER PI +255 0xFF 0x02C7 # CARON +249 0xF9 0x02D8 # BREVE +250 0xFA 0x02D9 # DOT ABOVE +251 0xFB 0x02DA # RING ABOVE +254 0xFE 0x02DB # OGONEK +218 0xDA 0x2044 # FRACTION SLASH +182 0xB6 0x2202 # PARTIAL DIFFERENTIAL +198 0xC6 0x2206 # INCREMENT +184 0xB8 0x220F # N-ARY PRODUCT +183 0xB7 0x2211 # N-ARY SUMMATION +195 0xC3 0x221A # SQUARE ROOT +176 0xB0 0x221E # INFINITY +186 0xBA 0x222B # INTEGRAL +197 0xC5 0x2248 # ALMOST EQUAL TO +173 0xAD 0x2260 # NOT EQUAL TO +178 0xB2 0x2264 # LESS-THAN OR EQUAL TO +179 0xB3 0x2265 # GREATER-THAN OR EQUAL TO +215 0xD7 0x25CA # LOZENGE +240 0xF0 0xF8FF # Apple logo +222 0xDE 0xFB01 # LATIN SMALL LIGATURE FI +223 0xDF 0xFB02 # LATIN SMALL LIGATURE FL +245 0xF5 0x0131 # LATIN SMALL LETTER DOTLESS I +206 0xCE 0x0152 # LATIN CAPITAL LIGATURE OE +207 0xCF 0x0153 # LATIN SMALL LIGATURE OE + +WinCodes +129 0x81 #UNDEFINED +141 0x8D #UNDEFINED +143 0x8F #UNDEFINED +144 0x90 #UNDEFINED +157 0x9D #UNDEFINED +167 0xA7 0x00A7 #SECTION SIGN +173 0xAD 0x00AD #SOFT HYPHEN +178 0xB2 0x00B2 #SUPERSCRIPT TWO +179 0xB3 0x00B3 #SUPERSCRIPT THREE +185 0xB9 0x00B9 #SUPERSCRIPT ONE +188 0xBC 0x00BC #VULGAR FRACTION ONE QUARTER +189 0xBD 0x00BD #VULGAR FRACTION ONE HALF +190 0xBE 0x00BE #VULGAR FRACTION THREE QUARTERS +208 0xD0 0x00D0 #LATIN CAPITAL LETTER ETH +215 0xD7 0x00D7 #MULTIPLICATION SIGN +221 0xDD 0x00DD #LATIN CAPITAL LETTER Y WITH ACUTE +222 0xDE 0x00DE #LATIN CAPITAL LETTER THORN +240 0xF0 0x00F0 #LATIN SMALL LETTER ETH +253 0xFD 0x00FD #LATIN SMALL LETTER Y WITH ACUTE +254 0xFE 0x00FE #LATIN SMALL LETTER THORN +140 0x8C 0x0152 #LATIN CAPITAL LIGATURE OE +156 0x9C 0x0153 #LATIN SMALL LIGATURE OE +138 0x8A 0x0160 #LATIN CAPITAL LETTER S WITH CARON +154 0x9A 0x0161 #LATIN SMALL LETTER S WITH CARON +142 0x8E 0x017D #LATIN CAPITAL LETTER Z WITH CARON +158 0x9E 0x017E #LATIN SMALL LETTER Z WITH CARON +128 0x80 0x20AC #EURO SIGN +166 0xA6 0x00A6 #BROKEN BAR + + +*/ + + + + +#endif /* !__macos_charmap_h */ diff --git a/macos/source/extrafld.c b/macos/source/extrafld.c new file mode 100644 index 0000000..a2efcdb --- /dev/null +++ b/macos/source/extrafld.c @@ -0,0 +1,920 @@ +/* + Copyright (c) 1990-2002 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/*--------------------------------------------------------------------------- + + extrafld.c + + contains functions to build extra-fields. + + ---------------------------------------------------------------------------*/ + +/*****************************************************************************/ +/* Includes */ +/*****************************************************************************/ + +#include +#include "zip.h" +#include "unixlike.h" +#include "helpers.h" +#include "pathname.h" + + +/*****************************************************************************/ +/* Macros, typedefs */ +/*****************************************************************************/ + +/* ---------------------------------------------------------------------- */ +/* Add a 'MAC3' extra field to the zlist data pointed to by z. */ +/* This is the (new) Info-zip extra block for Macintosh */ +#define EB_MAC3_HLEN 14 /* fixed length part of MAC3's header */ +#define EB_L_MAC3_FINFO_LEN 52 /* fixed part of MAC3 compressible data */ + +#define EB_MAX_OF_VARDATA 1300 /* max possible datasize */ + +#define EB_L_MAC3_SIZE (EB_HEADSIZE + EB_MAC3_HLEN) +#define EB_C_MAC3_SIZE (EB_HEADSIZE + EB_MAC3_HLEN) + +/* maximum memcompress overhead is the sum of the compression header length */ +/* (6 = ush compression type, ulg CRC) and the worstcase deflate overhead */ +/* when uncompressible data are kept in 2 "stored" blocks (5 per block = */ +/* byte blocktype + 2 * ush blocklength) */ +#define MEMCOMPRESS_OVERHEAD (EB_MEMCMPR_HSIZ + EB_DEFLAT_EXTRA) + +#define EB_M3_FL_COMPRESS 0x00 +#define EB_M3_FL_DATFRK 0x01 /* data is data-fork */ +#define EB_M3_FL_NOCHANGE 0x02 /* filename will be not changed */ +#define EB_M3_FL_UNCMPR 0x04 /* data is 'natural' (not compressed) */ +#define EB_M3_FL_TIME64 0x08 /* time is coded in 64 bit */ +#define EB_M3_FL_NOUTC 0x10 /* only 'local' time-stamps are stored */ + + +#define EB_L_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(2)) +#define EB_C_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(1)) + +/* disable compressing of extra field +#define MAC_EXTRAFLD_UNCMPR */ + +/* ---------------------------------------------------------------------- */ +/* Add a 'JLEE' extra field to the zlist data pointed to by z. */ +/* This is the (old) Info-zip resource-fork extra block for Macintosh +(last Revision 1996-09-22) Layout made by Johnny Lee, Code made by me :-) */ +#define EB_L_JLEE_LEN 40 /* fixed length of JLEE's header */ +#define EB_C_JLEE_LEN 40 /* fixed length of JLEE's header */ + +#define EB_L_JLEE_SIZE (EB_HEADSIZE + EB_L_JLEE_LEN) +#define EB_C_JLEE_SIZE (EB_HEADSIZE + EB_C_JLEE_LEN) + + + +/*****************************************************************************/ +/* Global Vars */ +/*****************************************************************************/ + +extern MacZipGlobals MacZip; +extern unsigned long count_of_Zippedfiles; + + + +/*****************************************************************************/ +/* Prototypes */ +/*****************************************************************************/ + +static int add_UT_ef(struct zlist far *z, iztimes *z_utim); +static int add_JLEE_ef(struct zlist far *z); /* old mac extra field */ +static int add_MAC3_ef(struct zlist far *z); /* new mac extra field */ + +static void make_extrafield_JLEE(char *l_ef); +static unsigned make_extrafield_MAC3(char *ef); +static char *make_EF_Head_MAC3(char *ef, unsigned compsize, ulg attrsize, + unsigned flag); + +static void print_extra_info(void); +void UserStop(void); + + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ + + +/* +* Set the extra-field's for each compressed file +*/ +int set_extra_field(struct zlist far *z, iztimes *z_utim) + /* store full data in local header but just modification time stamp info + in central header */ +{ + int retval; + + Assert_it(z, "set_extra_field","") + Assert_it(z_utim, "set_extra_field","") + + z_utim = z_utim; + + /* Check to make sure z is valid. */ + if( z == NULL ) { + return ZE_LOGIC; + } + + /* Resource forks are always binary */ + if (MacZip.CurrentFork == ResourceFork) z->att = BINARY; + + if (noisy) + { + count_of_Zippedfiles++; + InformProgress(MacZip.RawCountOfItems, count_of_Zippedfiles ); + } + + /* + PrintFileInfo(); + */ + switch (MacZip.MacZipMode) + { + case JohnnyLee_EF: + { + retval = add_JLEE_ef( z ); + if (retval != ZE_OK) return retval; + break; + } + case NewZipMode_EF: + { /* */ +#ifdef USE_EF_UT_TIME + retval = add_UT_ef(z, z_utim); + if (retval != ZE_OK) return retval; +#endif + + retval = add_MAC3_ef( z ); + if (retval != ZE_OK) return retval; + break; + } + default: + { + printerr("Unknown Extrafieldmode", -1, -1, __LINE__, __FILE__, ""); + return ZE_LOGIC; /* function should never reach this point */ + } + } + + /* MacStat information is now outdated and + must be refreshed for the next file */ + MacZip.isMacStatValid = false; + + return ZE_OK; +} + + + + +#ifdef USE_EF_UT_TIME +/* +* Build and add the Unix time extra-field. This extra field +* will be included be default. Johnny Lee's implementation does +* not use this kind of extra-field. +* All datas are in Intel (=little-endian) format + + Extra field info: + - 'UT' - UNIX time extra field + + This is done the same way ../unix/unix.c stores the 'UT'/'Ux' fields + (full data in local header, only modification time in central header), + with the 'M3' field added to the end and the size of the 'M3' field + in the central header. + */ + +static int add_UT_ef(struct zlist far *z, iztimes *z_utim) +{ + char *l_ef = NULL; + char *c_ef = NULL; + + Assert_it(z, "add_UT_ef","") + +#ifdef IZ_CHECK_TZ + if (!zp_tz_is_valid) + return ZE_OK; /* skip silently if no valid TZ info */ +#endif + + /* We can't work if there's no entry to work on. */ + if( z == NULL ) { + return ZE_LOGIC; + } + + /* Check to make sure we've got enough room in the extra fields. */ + if( z->ext + EB_L_UT_SIZE > EF_SIZE_MAX || + z->cext + EB_C_UT_SIZE > EF_SIZE_MAX ) { + return ZE_MEM; + } + + /* Allocate memory for the local and central extra fields. */ + if( z->extra && z->ext != 0 ) { + l_ef = (char *)realloc( z->extra, z->ext + EB_L_UT_SIZE ); + } else { + l_ef = (char *)malloc( EB_L_UT_SIZE ); + z->ext = 0; + } + if( l_ef == NULL ) { + return ZE_MEM; + } + z->extra = l_ef; + l_ef += z->ext; + + if( z->cextra && z->cext != 0 ) { + c_ef = (char *)realloc( z->cextra, z->cext + EB_C_UT_SIZE ); + } else { + c_ef = (char *)malloc( EB_C_UT_SIZE ); + z->cext = 0; + } + if( c_ef == NULL ) { + return ZE_MEM; + } + z->cextra = c_ef; + c_ef += z->cext; + + /* Now add the local version of the field. */ + *l_ef++ = 'U'; + *l_ef++ = 'T'; + *l_ef++ = (char)(EB_UT_LEN(2)); /* length of data in local EF */ + *l_ef++ = (char)0; + *l_ef++ = (char)(EB_UT_FL_MTIME | EB_UT_FL_CTIME); + *l_ef++ = (char)(z_utim->mtime); + *l_ef++ = (char)(z_utim->mtime >> 8); + *l_ef++ = (char)(z_utim->mtime >> 16); + *l_ef++ = (char)(z_utim->mtime >> 24); + *l_ef++ = (char)(z_utim->ctime); + *l_ef++ = (char)(z_utim->ctime >> 8); + *l_ef++ = (char)(z_utim->ctime >> 16); + *l_ef++ = (char)(z_utim->ctime >> 24); + + z->ext += EB_L_UT_SIZE; + + /* Now add the central version. */ + memcpy(c_ef, l_ef-EB_L_UT_SIZE, EB_C_UT_SIZE); + c_ef[EB_LEN] = (char)(EB_UT_LEN(1)); /* length of data in central EF */ + + z->cext += EB_C_UT_SIZE; + + return ZE_OK; +} +#endif /* USE_EF_UT_TIME */ + + +/* +* Build and add the old 'Johnny Lee' Mac extra field +* All native datas are in Motorola (=big-endian) format +*/ + +static int add_JLEE_ef( struct zlist far *z ) +{ + char *l_ef = NULL; + char *c_ef = NULL; + + Assert_it(z, "add_JLEE_ef","") + + /* Check to make sure we've got enough room in the extra fields. */ + if ( z->ext + EB_L_JLEE_SIZE > EF_SIZE_MAX || + z->cext + EB_C_JLEE_SIZE > EF_SIZE_MAX ) { + return ZE_MEM; + } + + + /* Allocate memory for the local extra fields. */ + if ( z->extra && z->ext != 0 ) { + l_ef = (char *)realloc( z->extra, z->ext + EB_L_JLEE_SIZE ); + } else { + l_ef = (char *)malloc( EB_L_JLEE_SIZE ); + z->ext = 0; + } + if ( l_ef == NULL ) { + return ZE_MEM; + } + z->extra = l_ef; + l_ef += z->ext; + + /* Allocate memory for the central extra fields. */ + if ( z->cextra && z->cext != 0 ) { + c_ef = (char *)realloc( z->cextra, z->cext + EB_C_JLEE_SIZE ); + } else { + c_ef = (char *)malloc( EB_C_JLEE_SIZE ); + z->cext = 0; + } + if ( c_ef == NULL ) { + return ZE_MEM; + } + z->cextra = c_ef; + c_ef += z->cext; + + + if ( verbose ) { + print_extra_info(); + } + + + /** + ** + ** Now add the local version of the field. + **/ + make_extrafield_JLEE(l_ef); + z->ext += EB_L_JLEE_SIZE; + + + /** + ** + ** Now add the central version of the field. + ** It's identical to the local header. I wonder why ?? + * the first two fields are in Intel little-endian format */ + make_extrafield_JLEE(c_ef); + z->cext += EB_C_JLEE_SIZE; + + return ZE_OK; +} + + + +/* +* This is an implementation of Johnny Lee's extra field. +* I never saw Johnny Lee's code. My code is based on the extra-field +* definition mac (see latest appnote 1997-03-11) +* and on some experiments with Johnny Lee's Zip-app version 1.0, 1992 +* +* Unfortunately I cannot agree with his extra-field layout. +* - it wasted space +* - and holds not all mac-specific information +* +* I coded this extra-field only for testing purposes. +* I don't want support this extra-field. Please use my implementation. +* +* This is old implementation of Johnny Lee's extra field. +* All native datas are in Motorola (=big-endian) format +*/ + +static void make_extrafield_JLEE(char *ef) +{ + + Assert_it(ef, "make_extrafield_JLEE","") + + if (MacZip.isMacStatValid == false) + { + fprintf(stderr,"Internal Logic Error: [%d/%s] MacStat is out of sync !", + __LINE__,__FILE__); + exit(-1); + } + + + /* the first two fields are in Intel little-endian format */ + *ef++ = 0xC8; /* tag for this extra block */ + *ef++ = 0x07; + + *ef++ = (char)(EB_L_JLEE_LEN); /* total data size this block */ + *ef++ = (char)((EB_L_JLEE_LEN) >> 8); + + /* the following fields are in motorola big-endian format */ + *ef++ = 'J'; /* extra field signature: 4 Bytes */ + *ef++ = 'L'; /* the old style extra field */ + *ef++ = 'E'; + *ef++ = 'E'; + + /* Start Macintosh Finder FInfo structure 16 Bytes overall */ + /* Type: 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 24); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType); + + /* Creator: 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 24); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator); + + /* file Finder Flags: 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags); + + /* Finders Icon position of a file*/ + /* V/Y-Position: 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v); + /* H/X-Position: 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h); + + /* fdFldr Folder containing file 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFldr >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFldr); + /* End Macintosh Finder FInfo structure */ + + + /* Creation-time 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 24); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat); + + /* Modification-time 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 24); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat); + + /* info Bits 4 Bytes */ + *ef++ = 0x00; + *ef++ = 0x00; + *ef++ = 0x00; + if (MacZip.DataForkOnly) + { /* don't convert filename for unzipping */ + /* 0x01 = data-fork; 0x00 = resource-fork */ + *ef++ = (char) (MacZip.CurrentFork == DataFork) | 2; + } + else + { + *ef++ = (char) (MacZip.CurrentFork == DataFork); + } + + /* file's location folder ID 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlParID >> 24); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlParID >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlParID >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlParID); + /* ============ */ + /* 40 Bytes */ +} + + + +/* +* Build and add the new mac extra field +* All native data are stored in Intel (=little-endian) format +*/ + +static int add_MAC3_ef( struct zlist far *z ) +{ + char *l_ef = NULL; + char *c_ef = NULL; + char *attrbuff = NULL; + off_t attrsize = (EB_L_MAC3_FINFO_LEN + EB_MAX_OF_VARDATA); + char *compbuff = NULL; + unsigned compsize = 0; + unsigned m3_compr; + Boolean compress_data = true; + + Assert_it(z, "add_MAC3_ef","") + + UserStop(); /* do event handling and let the user stop */ + + if( verbose ) { + print_extra_info(); + } + + /* allocate temporary buffer to collect the Mac extra field info */ + attrbuff = (char *)malloc( (size_t)attrsize ); + if( attrbuff == NULL ) { + return ZE_MEM; + } + + /* fill the attribute buffer, to get its (uncompressed) size */ + attrsize = make_extrafield_MAC3(attrbuff); + + if (compress_data && + ((compbuff = (char *)malloc((size_t)attrsize + MEMCOMPRESS_OVERHEAD)) + != NULL)) + { + /* Try compressing the data */ + compsize = memcompress( compbuff, + (size_t)attrsize + MEMCOMPRESS_OVERHEAD, + attrbuff, + (size_t)attrsize ); +#ifdef MAC_EXTRAFLD_UNCMPR + compsize = attrsize; +#endif + } + else + { + compsize = attrsize; + } + + if ((compsize) < attrsize) { + /* compression gained some space ... */ + free(attrbuff); /* no longer needed ... */ + m3_compr = EB_M3_FL_COMPRESS; + } else { + /* compression does not help, store data in uncompressed mode */ + if (compbuff != NULL) free(compbuff); + compbuff = attrbuff; + compsize = attrsize; + m3_compr = EB_M3_FL_UNCMPR; + } + + /* Check to make sure we've got enough room in the extra fields. */ + if( z->ext + (EB_L_MAC3_SIZE + compsize) > EF_SIZE_MAX || + z->cext + EB_C_MAC3_SIZE > EF_SIZE_MAX ) { + if (compbuff != NULL) free(compbuff); + return ZE_MEM; + } + + /* Allocate memory for the local extra fields. */ + if( z->extra && z->ext != 0 ) { + l_ef = (char *)realloc( z->extra, z->ext + + EB_L_MAC3_SIZE + compsize); + } else { + l_ef = (char *)malloc( EB_L_MAC3_SIZE + compsize); + z->ext = 0; + } + if( l_ef == NULL ) { + return ZE_MEM; + } + z->extra = l_ef; + l_ef += z->ext; + + /* Allocate memory for the central extra fields. */ + if( z->cextra && z->cext != 0 ) { + c_ef = (char *)realloc( z->cextra, z->cext + EB_C_MAC3_SIZE); + } else { + c_ef = (char *)malloc( EB_C_MAC3_SIZE ); + z->cext = 0; + } + if( c_ef == NULL ) { + return ZE_MEM; + } + z->cextra = c_ef; + c_ef += z->cext; + + /** + ** Now add the local version of the field. + **/ + l_ef = make_EF_Head_MAC3(l_ef, compsize, (ulg)attrsize, m3_compr); + memcpy(l_ef, compbuff, (size_t)compsize); + l_ef += compsize; + z->ext += EB_L_MAC3_SIZE + compsize; + free(compbuff); + /* And the central version. */ + c_ef = make_EF_Head_MAC3(c_ef, 0, (ulg)attrsize, m3_compr); + z->cext += EB_C_MAC3_SIZE; + + return ZE_OK; +} + + + + +/* +* Build the new mac local extra field header. +* It's identical with the central extra field. +* All native data are in Intel (=little-endian) format +*/ +static char *make_EF_Head_MAC3(char *ef, unsigned compsize, ulg attrsize, + unsigned flag) +{ + unsigned info_flag = flag; + + Assert_it(ef, "make_EF_Head_MAC3","") + + /* the first four fields are in Intel little-endian format */ + *ef++ = 'M'; /* tag for this extra block 2 Bytes */ + *ef++ = '3'; + + /* total data size this block 2 Bytes */ + *ef++ = (char) (EB_MAC3_HLEN + compsize); + *ef++ = (char)((EB_MAC3_HLEN + compsize) >> 8); + + *ef++ = (char)(attrsize); + *ef++ = (char)(attrsize >> 8); + *ef++ = (char)(attrsize >> 16); + *ef++ = (char)(attrsize >> 24); + + /* info Bits (flags) 2 Bytes */ + + if (MacZip.DataForkOnly) info_flag |= (EB_M3_FL_DATFRK | + EB_M3_FL_NOCHANGE); + if (MacZip.CurrentFork == DataFork) info_flag |= EB_M3_FL_DATFRK; + if (!MacZip.HaveGMToffset) info_flag |= EB_M3_FL_NOUTC; + + *ef++ = (char)info_flag; + *ef++ = (char)0x00; /* reserved at the moment */ + + /* Note: Apple defined File-Type/-Creator as OSType ( =unsigned long, + see Universal Headers 3.1). However, File-Type/-Creator are a + unique four-character sequence. Therefore the byteorder of the + File-Type/-Creator are NOT changed. The native format is used. */ + + /* Type: 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 24); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType); + + /* Creator: 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 24); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator); + + return ef; +} + + + + + +/* +* Build the new mac local extra field header. +* All native data are in Intel (=little-endian) format +*/ +unsigned make_extrafield_MAC3(char *ef) +{ + char *ef_m3_begin = ef; + char *temp_Pathname; + char tmp_buffer[NAME_MAX]; + unsigned char comment[257]; + unsigned short FLength = 0; + unsigned short CLength = 0; + short tempFork; + OSErr err; + + Assert_it(ef, "make_extrafield_MAC3","") + + if (MacZip.isMacStatValid == false) + { + fprintf(stderr, + "Internal Logic Error: [%d/%s] MacStat is out of sync !", + __LINE__, __FILE__); + exit(-1); + } + + /* Start Macintosh Finder FInfo structure except Type/Creator + (see make_EF_Head_MAC3()) 8 Bytes overall */ + + /* file Finder Flags: 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags >> 8); + + /* Finders Icon position of a file*/ + /* V/Y-Position: 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v >> 8); + + /* H/X-Position: 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h >> 8); + + /* fdFldr Folder containing file 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFldr); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFldr >> 8); + + /* End Macintosh Finder FInfo structure */ + + /* 8 Bytes so far ... */ + + /* Start Macintosh Finder FXInfo structure 16 Bytes overall */ + /* Icon ID: 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdIconID); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdIconID >> 8); + + /* unused: 6 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[0]); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[0] >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[1]); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[1] >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[2]); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[2] >> 8); + /* Script flag: 1 Byte */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdScript); + /* More flag bits: 1 Byte */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdXFlags); + /* Comment ID 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdComment); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdComment >> 8); + + /* Home Dir ID: 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdPutAway); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdPutAway >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdPutAway >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdPutAway >> 24); + /* End Macintosh Finder FXInfo structure */ + + /* 24 Bytes so far ... */ + + /* file version number 1 Byte */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFVersNum); + + /* directory access rights 1 Byte */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioACUser); + + /* Creation-time 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 24); + /* Modification-time 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 24); + /* Backup-time 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlBkDat); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlBkDat >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlBkDat >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlBkDat >> 24); + + /* 38 Bytes so far ... */ +#ifdef USE_EF_UT_TIME + if (MacZip.HaveGMToffset) { + /* GMT-Offset times 12 Bytes */ + *ef++ = (char)(MacZip.Cr_UTCoffs); + *ef++ = (char)(MacZip.Cr_UTCoffs >> 8); + *ef++ = (char)(MacZip.Cr_UTCoffs >> 16); + *ef++ = (char)(MacZip.Cr_UTCoffs >> 24); + *ef++ = (char)(MacZip.Md_UTCoffs); + *ef++ = (char)(MacZip.Md_UTCoffs >> 8); + *ef++ = (char)(MacZip.Md_UTCoffs >> 16); + *ef++ = (char)(MacZip.Md_UTCoffs >> 24); + *ef++ = (char)(MacZip.Bk_UTCoffs); + *ef++ = (char)(MacZip.Bk_UTCoffs >> 8); + *ef++ = (char)(MacZip.Bk_UTCoffs >> 16); + *ef++ = (char)(MacZip.Bk_UTCoffs >> 24); + } + /* 50 Bytes so far ... */ +#endif + + /* Text Encoding Base (charset) 2 Bytes */ + *ef++ = (char)(MacZip.CurrTextEncodingBase); + *ef++ = (char)(MacZip.CurrTextEncodingBase >> 8); + /* 52 Bytes so far ... */ + + /* MacZip.CurrentFork will be changed, so we have to save it */ + tempFork = MacZip.CurrentFork; + if (!MacZip.StoreFullPath) { + temp_Pathname = StripPartialDir(tmp_buffer, MacZip.SearchDir, + MacZip.FullPath); + } else { + temp_Pathname = MacZip.FullPath; + } + MacZip.CurrentFork = tempFork; + + FLength = strlen(temp_Pathname) + 1; + memcpy( ef, temp_Pathname, (size_t)FLength ); + ef += FLength; /* make room for the string - variable length */ + + err = FSpLocationFromFullPath(strlen(MacZip.FullPath), MacZip.FullPath, + &MacZip.fileSpec); + printerr("FSpLocationFromFullPath:", err, err, + __LINE__, __FILE__, tmp_buffer); + + err = FSpDTGetComment(&MacZip.fileSpec, comment); + printerr("FSpDTGetComment:", (err != -5012) && (err != 0), err, + __LINE__, __FILE__, ""); + PToCCpy(comment,tmp_buffer); + + CLength = strlen(tmp_buffer) + 1; + memcpy( ef, tmp_buffer, (size_t)CLength ); + ef += CLength; /* make room for the string - variable length */ + + if (verbose) printf("\n comment: [%s]", tmp_buffer); + + return (unsigned)(ef - ef_m3_begin); +} + + + + + + +/* +* Print all native data of the new mac local extra field. +* It's for debugging purposes and disabled by default. +*/ + +static void PrintFileInfo(void) +{ +DateTimeRec MacTime; + +printf("\n\n---------------------------------------------"\ + "----------------------------------"); +printf("\n FullPath Name = [%s]", MacZip.FullPath); +printf("\n File Attributes = %s 0x%x %d", + sBit2Str(MacZip.fpb.hFileInfo.ioFlAttrib), + MacZip.fpb.hFileInfo.ioFlAttrib, + MacZip.fpb.hFileInfo.ioFlAttrib); +printf("\n Enclosing Folder ID# = 0x%x %d", + MacZip.fpb.hFileInfo.ioFlParID, + MacZip.fpb.hFileInfo.ioFlParID); + +if (!MacZip.isDirectory) +{ +printf("\n File Type = [%c%c%c%c] 0x%lx", + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 24, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 16, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 8, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType); + +printf("\n File Creator = [%c%c%c%c] 0x%lx", + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 24, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 16, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 8, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator); + +printf("\n Data Fork :" ); +printf("\n Actual (Logical) Length = %d 0x%x ", + MacZip.fpb.hFileInfo.ioFlLgLen, + MacZip.fpb.hFileInfo.ioFlLgLen); +printf("\n Allocated (Physical) Length = %d 0x%x", + MacZip.fpb.hFileInfo.ioFlPyLen, + MacZip.fpb.hFileInfo.ioFlPyLen); +printf("\n Resource Fork :" ); +printf("\n Actual (Logical) Length = %d 0x%x", + MacZip.fpb.hFileInfo.ioFlRLgLen, + MacZip.fpb.hFileInfo.ioFlRLgLen ); +printf("\n Allocated (Physical) Length = %d 0x%x", + MacZip.fpb.hFileInfo.ioFlRPyLen, + MacZip.fpb.hFileInfo.ioFlRPyLen ); +} + +printf("\n Dates : "); + +SecondsToDate (MacZip.CreatDate, &MacTime); +printf("\n Created = %4d/%2d/%2d %2d:%2d:%2d ", + MacTime.year, + MacTime.month, + MacTime.day, + MacTime.hour, + MacTime.minute, + MacTime.second); + +SecondsToDate (MacZip.BackDate, &MacTime); +printf("\n Backup = %4d/%2d/%2d %2d:%2d:%2d ", + MacTime.year, + MacTime.month, + MacTime.day, + MacTime.hour, + MacTime.minute, + MacTime.second); + +SecondsToDate (MacZip.ModDate, &MacTime); +printf("\n Modified = %4d/%2d/%2d %2d:%2d:%2d ", + MacTime.year, + MacTime.month, + MacTime.day, + MacTime.hour, + MacTime.minute, + MacTime.second); + +if (!MacZip.isDirectory) +{ +printf("\n Finder Flags : %s 0x%x %d", + sBit2Str(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags), + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags); +printf("\n Finder Icon Position = X: %d 0x%x ", + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h); +printf("\n Y: %d 0x%x ", + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v); +} +else +{ +printf("\n Finder Flags : %s 0x%x %d", + sBit2Str(MacZip.fpb.dirInfo.ioDrUsrWds.frFlags), + MacZip.fpb.dirInfo.ioDrUsrWds.frFlags, + MacZip.fpb.dirInfo.ioDrUsrWds.frFlags); +printf("\n Finder Icon Position = X: %d 0x%x ", + MacZip.fpb.dirInfo.ioDrUsrWds.frLocation.h, + MacZip.fpb.dirInfo.ioDrUsrWds.frLocation.h); +printf("\n Y: %d 0x%x ", + MacZip.fpb.dirInfo.ioDrUsrWds.frLocation.v, + MacZip.fpb.dirInfo.ioDrUsrWds.frLocation.v); +} + +printf("\n----------------------------------------------------"\ + "---------------------------\n"); +} + + + +/* +* If the switch '-v' is used, print some more info. +*/ + +static void print_extra_info(void) +{ +char Fork[20]; + +if (MacZip.CurrentFork == DataFork) sstrcpy(Fork,""); +else sstrcpy(Fork,""); + +printf("\n%16s [%c%c%c%c] [%c%c%c%c]",Fork, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 24, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 16, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 8, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType, + + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 24, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 16, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 8, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator); +} diff --git a/macos/source/getenv.c b/macos/source/getenv.c new file mode 100644 index 0000000..3b22327 --- /dev/null +++ b/macos/source/getenv.c @@ -0,0 +1,398 @@ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + +This file implements the getenv() function. + +# Background: +# Under Unix: Each Process (= running Program) has a set of +# associated variables. The variables are called enviroment +# variables and, together, constitute the process environment. +# These variables include the search path, the terminal type, +# and the user's login name. + +# Unfortunatelly the MacOS has no equivalent. So we need +# a file to define the environment variables. +# Name of this file is "MacZip.Env". It can be placed +# in the current folder of MacZip or in the +# preference folder of the system disk. +# If MacZip founds the "MacZip.Env" file in the current +# the folder of MacZip the "MacZip.Env" file in the +# preference folder will be ignored. + +# An environment variable has a name and a value: +# Name=Value +# Note: Spaces are significant: +# ZIPOPT=-r and +# ZIPOPT = -r are different !!! + + + */ + +/*****************************************************************************/ +/* Includes */ +/*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include "pathname.h" +#include "helpers.h" + +/*****************************************************************************/ +/* Module level Vars */ +/*****************************************************************************/ + +static char ListAllKeyValues = 0; +static unsigned LineNumber = 0; +static char CompletePath[NAME_MAX]; +Boolean IgnoreEnvironment = false; /* used by dialog.c and initfunc.c + of the Mainapp */ + +/*****************************************************************************/ +/* Macros, typedefs */ +/*****************************************************************************/ + +typedef struct _EnviromentPair { + char *key; + char *value; +} EnviromentPair; + + +#define MAX_COMMAND 1024 + + +/*****************************************************************************/ +/* Prototypes */ +/*****************************************************************************/ + + +int get_char(FILE *file); +void unget_char(int ch,FILE *file); +int get_string(char *string,int size, FILE *file, char *terms); +void skip_comments(FILE *file); +char *load_entry(FILE *file); +char *getenv(const char *name); +EnviromentPair *ParseLine(char *line); +OSErr FSpFindFolder_Name(short vRefNum, OSType folderType, + Boolean createFolder,FSSpec *spec, unsigned char *name); +FILE * FSp_fopen(ConstFSSpecPtr spec, const char * open_mode); +void ShowAllKeyValues(void); +void Set_LineNum(unsigned ln); + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ + + +/* get_string(str, max, file, termstr) : like fgets() but + * (1) has terminator string which should include \n + * (2) will always leave room for the null + * (3) uses get_char() so LineNumber will be accurate + * (4) returns EOF or terminating character, whichever + */ +int get_string(char *string, int size, FILE *file, char *terms) +{ + int ch; + + while (EOF != (ch = get_char(file)) && !strchr(terms, ch)) { + if (size > 1) { + *string++ = (char) ch; + size--; + } + } + + if (size > 0) + { + *string = '\0'; + } + + return ch; +} + + + + +void Set_LineNum(unsigned ln) +{ + LineNumber = ln; +} + + + +/* get_char(file) : like getc() but increment LineNumber on newlines + */ +int get_char(FILE *file) +{ + int ch; + + ch = getc(file); + if (ch == '\n') + { + Set_LineNum(LineNumber + 1); + } + + return ch; +} + + + + +/* skip_comments(file) : read past comment (if any) + */ +void skip_comments(FILE *file) +{ + int ch; + + while (EOF != (ch = get_char(file))) + { + /* ch is now the first character of a line. + */ + + while (ch == ' ' || ch == '\t') + { + ch = get_char(file); + } + + if (ch == EOF) + { + break; + } + + /* ch is now the first non-blank character of a line. + */ + + if (ch != '\n' && ch != '#') + { + break; + } + + /* ch must be a newline or comment as first non-blank + * character on a line. + */ + + while (ch != '\n' && ch != EOF) + { + ch = get_char(file); + } + + /* ch is now the newline of a line which we're going to + * ignore. + */ + } + + if (ch != EOF) + { + unget_char(ch, file); + } +} + + + + +/* unget_char(ch, file) : like ungetc but do LineNumber processing + */ +void unget_char(int ch, FILE *file) +{ + ungetc(ch, file); + if (ch == '\n') + { + Set_LineNum(LineNumber - 1); + } +} + + +/* this function reads one file entry -- the next -- from a file. +* it skips any leading blank lines, ignores comments, and returns +* NULL if for any reason the entry can't be read and parsed. +*/ + +char *load_entry(FILE *file) +{ + int ch; + static char cmd[MAX_COMMAND]; + + skip_comments(file); + + ch = get_string(cmd, MAX_COMMAND, file, "\n"); + + if (ch == EOF) + { + return NULL; + } + + return cmd; +} + + + + + +EnviromentPair *ParseLine(char *line) +{ +char *tmpPtr; +static EnviromentPair *Env; +unsigned short length = strlen(line); + +Env->key = ""; +Env->value = ""; + +for (tmpPtr = line; *tmpPtr; tmpPtr++) + { + if (*tmpPtr == '=') + { + *tmpPtr = 0; + Env->key = line; + if (strlen(Env->key) < length) + { + Env->value = ++tmpPtr; + } + return Env; + } + } +return Env; +} + + + + + +char *getenv(const char *name) +{ +FILE *fp; +char *LineStr = NULL; +EnviromentPair *Env1; +FSSpec spec; +OSErr err; + +if (IgnoreEnvironment) + return NULL; /* user wants to ignore the environment vars */ + +if (name == NULL) + return NULL; + +GetCompletePath(CompletePath,"MacZip.Env",&spec,&err); + +/* try open the file in the current folder */ +fp = FSp_fopen(&spec,"r"); +if (fp == NULL) + { /* Okey, lets try open the file in the preference folder */ + FSpFindFolder_Name( + kOnSystemDisk, + kPreferencesFolderType, + kDontCreateFolder, + &spec, + "\pMacZip.Env"); + fp = FSp_fopen(&spec,"r"); + if (fp == NULL) + { + return NULL; /* there is no enviroment-file */ + } + } + +LineStr = load_entry(fp); +while (LineStr != NULL) + { /* parse the file line by line */ + Env1 = ParseLine(LineStr); + if (strlen(Env1->value) > 0) + { /* we found a key/value pair */ + if (ListAllKeyValues) + printf("\n Line:%3d [%s] = [%s]",LineNumber,Env1->key,Env1->value); + if (stricmp(name,Env1->key) == 0) + { /* we found the value of a given key */ + return Env1->value; + } + } + LineStr = load_entry(fp); /* read next line */ + } +fclose(fp); + +return NULL; +} + + + + + +OSErr FSpFindFolder_Name( + short vRefNum, /* Volume reference number. */ + OSType folderType, /* Folder type taken by FindFolder. */ + Boolean createFolder, /* Should we create it if non-existant. */ + FSSpec *spec, /* Pointer to resulting directory. */ + unsigned char *name) /* Name of the file in the folder */ +{ + short foundVRefNum; + long foundDirID; + OSErr err; + + err = FindFolder(vRefNum, folderType, createFolder, + &foundVRefNum, &foundDirID); + if (err != noErr) + { + return err; + } + + err = FSMakeFSSpec(foundVRefNum, foundDirID, name, spec); + return err; +} + + + + +void ShowAllKeyValues(void) +{ +OSErr err; +FSSpec spec; +Boolean tmpIgnoreEnvironment = IgnoreEnvironment; + +ListAllKeyValues = 1; +IgnoreEnvironment = false; + +GetCompletePath(CompletePath,"MacZip.Env",&spec,&err); +if (err != 0) + { /* Okey, lets try open the file in the preference folder */ + FSpFindFolder_Name( + kOnSystemDisk, + kPreferencesFolderType, + kDontCreateFolder, + &spec, + "\pMacZip.Env"); + GetFullPathFromSpec(CompletePath,&spec, &err); + if (err != 0) + { + return; /* there is no enviroment-file */ + } + } + +printf("\nLocation of the current \"MacZip.Env\" file:\n [%s]",CompletePath); + +printf("\n\nList of all environment variables\n"); +getenv(" "); +printf("\n\nEnd\n\n"); + +/* restore used variables */ +ListAllKeyValues = 0; +LineNumber = 0; +IgnoreEnvironment = tmpIgnoreEnvironment; +} + + + + + + + + + + diff --git a/macos/source/helpers.c b/macos/source/helpers.c new file mode 100644 index 0000000..36b5bef --- /dev/null +++ b/macos/source/helpers.c @@ -0,0 +1,479 @@ +/* + Copyright (c) 1990-2001 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/*--------------------------------------------------------------------------- + + helpers.c + + Some useful functions Used by unzip and zip. + + ---------------------------------------------------------------------------*/ + +/*****************************************************************************/ +/* Includes */ +/*****************************************************************************/ + +#include "zip.h" +#include +#include +#include + +#include "macstuff.h" +#include "helpers.h" +#include "pathname.h" + + +/*****************************************************************************/ +/* Global Vars */ +/*****************************************************************************/ + + +extern int noisy; +extern char MacPathEnd; +extern char *zipfile; /* filename of the Zipfile */ +extern char *tempzip; /* Temporary zip file name */ +extern ZCONST unsigned char MacRoman_to_WinCP1252[128]; + + +static char argStr[1024]; +static char *argv[MAX_ARGS + 1]; + + + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ + + +/* +** Copy a C string to a Pascal string +** +*/ + +unsigned char *CToPCpy(unsigned char *pstr, char *cstr) +{ + register char *dptr; + register unsigned len; + + len=0; + dptr=(char *)pstr+1; + while (len<255 && (*dptr++ = *cstr++)!='\0') ++len; + *pstr= (unsigned char)len; + return pstr; +} + + +/* +** Copy a Pascal string to a C string +** +*/ + +char *PToCCpy(unsigned char *pstr, char *cstr) +{ +strncpy(cstr, (char *) &pstr[1], *pstr); + cstr[pstr[0]] = '\0'; /* set endmarker for c-string */ +return cstr; +} + + +/* +** strcpy() and strcat() work-alikes which allow overlapping buffers. +*/ + +char *sstrcpy(char *to,const char *from) +{ + memmove(to, from, 1+strlen(from)); + return to; +} + +char *sstrcat(char *to,const char *from) +{ + sstrcpy(to + strlen(to), from); + return to; +} + + + +/* +** Alloc memory and init it +** +*/ + +char *StrCalloc(unsigned short size) +{ +char *strPtr = NULL; + +if ((strPtr = calloc(size, sizeof(char))) == NULL) + printerr("StrCalloc failed:", -1, size, __LINE__, __FILE__, ""); + +Assert_it(strPtr,"strPtr == NULL","") +return strPtr; +} + + + +/* +** Release only non NULL pointers +** +*/ + +char *StrFree(char *strPtr) +{ + +if (strPtr != NULL) + { + free(strPtr); + } + +return NULL; +} + + + + +/* +** Return a value in a binary string +** +*/ + +char *sBit2Str(unsigned short value) +{ + static char str[sizeof(value)*8]; + int biz = 16; + int strwid = 16; + int i, j; + char *tempPtr = str; + + j = strwid - (biz + (biz >> 2)- (biz % 4 ? 0 : 1)); + + for (i = 0; i < j; i++) { + *tempPtr++ = ' '; + } + while (--biz >= 0) + { + *tempPtr++ = ((value >> biz) & 1) + '0'; + if (!(biz % 4) && biz) { + *tempPtr++ = ' '; + } + } + *tempPtr = '\0'; + + return str; +} + + + + +/* +** Parse commandline style arguments +** +*/ + +int ParseArguments(char *s, char ***arg) +{ + int n = 1, Quote = 0; + char *p = s, *p1, c; + + argv[0] = GetAppName(); + + *arg = argv; + + p1 = (char *) argStr; + while ((c = *p++) != 0) { + if (c==' ') continue; + argv[n++] = p1; + if (n > MAX_ARGS) + return (n-1); + do { + if (c=='\\' && *p++) + c = *p++; + else + if ((c=='"') || (c == '\'')) { + if (!Quote) { + Quote = c; + continue; + } + if (c == Quote) { + Quote = 0; + continue; + } + } + *p1++ = c; + } while (*p && ((c = *p++) != ' ' || Quote)); + *p1++ = '\0'; + } + return n; +} + + + +/* +** Print commandline style arguments +** +*/ + +void PrintArguments(int argc, char **argv) +{ + +printf("\n Arguments:"); +printf("\n --------------------------"); + +while(--argc >= 0) + printf("\n argc: %d argv: [%s]", argc, &*argv[argc]); + +printf("\n --------------------------\n\n"); +return; +} + + + +/* +** return some error-msg on file-system +** +*/ + +int PrintUserHFSerr(int cond, int err, char *msg2) +{ +char *msg; + +if (cond != 0) + { + switch (err) + { + case -35: + msg = "No such Volume"; + break; + + case -56: + msg = "No such Drive"; + break; + + case -37: + msg = "Bad Volume Name"; + break; + + case -49: + msg = "File is already open for writing"; + break; + + case -43: + msg = "Directory/File not found"; + break; + + case -120: + msg = "Directory/File not found or incomplete pathname"; + break; + + default: return err; + } + fprintf(stderr, "\n\n Error: %s ->%s", msg, msg2); + exit(err); + } + +return 0; +} + + + +/* +** Check mounted volumes and return number of volumes +** with the same name. +*/ + +short CheckMountedVolumes(char *FullPath) +{ +FSSpec volumes[50]; /* 50 Volumes should be enough */ +char VolumeName[257], volume[257]; +short actVolCount, volIndex = 1, VolCount = 0; +OSErr err; +int i; + +GetVolumeFromPath(FullPath, VolumeName); + +err = OnLine(volumes, 50, &actVolCount, &volIndex); +printerr("OnLine:", (err != -35) && (err != 0), err, __LINE__, __FILE__, ""); + +for (i=0; i < actVolCount; i++) + { + PToCCpy(volumes[i].name,volume); + if (stricmp(volume, VolumeName) == 0) VolCount++; + } +printerr("OnLine: ", (VolCount == 0), VolCount, __LINE__, __FILE__, FullPath); + +return VolCount; +} + + + + + + + + +/* +** compares strings, ignoring differences in case +** +*/ + +int stricmp(const char *p1, const char *p2) +{ +int diff; + +while (*p1 && *p2) + { + if (*p1 != *p2) + { + if (isalpha(*p1) && isalpha(*p2)) + { + diff = toupper(*p1) - toupper(*p2); + if (diff) return diff; + } + else break; + } + p1++; + p2++; + } +return *p1 - *p2; +} + + + +/* +** Convert the MacOS-Strings (Filenames/Findercomments) to a most compatible. +** These strings will be stored in the public area of the zip-archive. +** Every foreign platform (outside macos) will access these strings +** for extraction. +*/ + +void MakeCompatibleString(char *MacOS_Str, + const char SpcChar1, const char SpcChar2, + const char SpcChar3, const char SpcChar4, + short CurrTextEncodingBase) +{ + char *tmpPtr; + register uch curch; + + Assert_it(MacOS_Str,"MakeCompatibleString MacOS_Str == NULL","") + for (tmpPtr = MacOS_Str; (curch = *tmpPtr) != '\0'; tmpPtr++) + { + if (curch == SpcChar1) + *tmpPtr = SpcChar2; + else + if (curch == SpcChar3) + *tmpPtr = SpcChar4; + else /* default */ + /* now convert from MacRoman to ISO-8859-1 */ + /* but convert only if MacRoman is activ */ + if ((CurrTextEncodingBase == kTextEncodingMacRoman) && + (curch > 127)) + { + *tmpPtr = (char)MacRoman_to_WinCP1252[curch - 128]; + } + } /* end for */ +} + + + + +Boolean CheckForSwitch(char *Switch, int argc, char **argv) +{ + char *p; /* steps through option arguments */ + int i; /* arg counter, root directory flag */ + + for (i = 1; i < argc; i++) + { + if (argv[i][0] == '-') + { + if (argv[i][1]) + { + for (p = argv[i]+1; *p; p++) + { + if (*p == Switch[0]) + { + return true; + } + if ((Switch[1] != NULL) && + ((*p == Switch[0]) && (*p == Switch[1]))) + { + return true; + } + } + } + } + } + +return false; +} + + + + + + + +#if (defined(USE_SIOUX) || defined(MACUNZIP_STANDALONE)) + +/* +** checks the condition and returns an error-msg +** this function is for internal use only +*/ + +OSErr printerr(const char *msg, int cond, int err, int line, char *file, + const char *msg2) +{ + +if (cond != 0) + { + fprintf(stderr, "\nint err: %d: %s %d [%d/%s] {%s}\n", clock(), msg, err, + line, file, msg2); + } + +return cond; +} + + +/* +fake-functions: +Not Implemented for metrowerks SIOUX +*/ + +void leftStatusString(char *status) +{ +status = status; +} + + +void rightStatusString(char *status) +{ +status = status; +} + + + +void DoWarnUserDupVol( char *FullPath ) +{ + char VolName[257]; + GetVolumeFromPath(FullPath, VolName); + + printf("\n There are more than one volume that has the same name !!\n"); + + printf("\n Volume: %s\n",VolName); + + printf("\n This port has one weak point:"); + printf("\n It is based on pathnames. As you may be already know:"); + printf("\n Pathnames are not unique on a Mac !"); + printf("\n MacZip has problems to find the correct location of"); + printf("\n the archive or the files.\n"); + + printf("\n My (Big) recommendation: Name all your volumes with an"); + printf("\n unique name and MacZip will run without any problem."); +} + + + +#endif diff --git a/macos/source/helpers.h b/macos/source/helpers.h new file mode 100644 index 0000000..a9df5d8 --- /dev/null +++ b/macos/source/helpers.h @@ -0,0 +1,57 @@ +/* + Copyright (c) 1990-2001 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#ifndef HELPERS_H +#define HELPERS_H 1 + + /* Convert a C string to a Pascal string */ +unsigned char *CToPCpy(unsigned char *pstr, char *cstr); + + /* Convert a Pascal string to a C string */ +char *PToCCpy(unsigned char *pstr, char *cstr); + +char *sstrcpy(char *to,const char *from); +char *sstrcat(char *to,const char *from); + +char *StrCalloc(unsigned short size); +char *StrFree(char *strPtr); + +char *sBit2Str(unsigned short value); + +void print_extra_info(void); + +int ParseArguments(char *s, char ***arg); +void PrintArguments(int argc, char **argv); + +Boolean IsZipFile(char *name); +OSErr printerr(const char *msg, int cond, int err, int line, char *file, + const char *msg2); +int PrintUserHFSerr(int cond, int err, char *msg2); + +short CheckMountedVolumes(char *FullPath); +void DoWarnUserDupVol(char *path); + +void PrintFileInfo(void); + +int stricmp(const char *p1, const char *p2); +void leftStatusString(char *status); +void rightStatusString(char *status); + +Boolean isZipFile(FSSpec *fileToOpen); + +unsigned long MacFileDate_to_UTime(unsigned long mactime); +Boolean CheckForSwitch(char *Switch, int argc, char **argv); + +void MakeCompatibleString(char *MacOS_Str, + const char SpcChar1, const char SpcChar2, + const char SpcChar3, const char SpcChar4, + short CurrTextEncodingBase); + +#define MAX_ARGS 25 + +#endif /* HELPERS_H */ diff --git a/macos/source/macglob.h b/macos/source/macglob.h new file mode 100644 index 0000000..17415e1 --- /dev/null +++ b/macos/source/macglob.h @@ -0,0 +1,86 @@ +/* + 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 _MACGLOBAL_ +#define _MACGLOBAL_ + +#include + +/* +all my Global vars are defined here. +*/ + +#define ResourceFork -1 +#define DataFork 1 +#define NoFork 0 + +/* +all my Global vars are defined here. +*/ +typedef struct { + short CurrentFork; + short MacZipMode; + + Boolean isMacStatValid; + Boolean HaveGMToffset; + + short CurrTextEncodingBase; + + /* info about the current file */ + Boolean isDirectory; + char FullPath[NAME_MAX]; + char FileName[NAME_MAX]; + FSSpec fileSpec; + + long dirID; + CInfoPBRec fpb; + + /* time infos about the current file */ + time_t CreatDate; + time_t ModDate; + time_t BackDate; + long Cr_UTCoffs; /* offset "local time - UTC" for CreatDate */ + long Md_UTCoffs; /* offset "local time - UTC" for ModDate */ + long Bk_UTCoffs; /* offset "local time - UTC" for BackDate */ + + /* some statistics over all*/ + unsigned long FoundFiles; + unsigned long FoundDirectories; + unsigned long RawCountOfItems; + unsigned long BytesOfData; + + unsigned long attrsize; + + /* some switches and user parameters */ + Boolean DataForkOnly; + Boolean StoreFullPath; + Boolean StoreFoldersAlso; /* internal switch is true if '-r' is set */ + unsigned short SearchLevels; + char Pattern[NAME_MAX]; + Boolean IncludeInvisible; + Boolean StatingProgress; + + char SearchDir[NAME_MAX]; + char CurrentPath[NAME_MAX]; + + /* current zip / tempzip file info */ + char ZipFullPath[NAME_MAX]; + + FSSpec ZipFileSpec; + unsigned long ZipFileType; + char TempZipFullPath[NAME_MAX]; + FSSpec TempZipFileSpec; + +} MacZipGlobals; + + + +void UserStop(void); + + +#endif diff --git a/macos/source/macopen.c b/macos/source/macopen.c new file mode 100644 index 0000000..9e18730 --- /dev/null +++ b/macos/source/macopen.c @@ -0,0 +1,363 @@ +/* + 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 +*/ +/*** macopen.c; stuff only required for the Mac port ***/ + +#include "zip.h" + +#include +#include +#include +#include + +#include "helpers.h" +#include "pathname.h" +#include "macopen.h" +#include "macstuff.h" + +#ifdef MACZIP +#include "macglob.h" + +extern char *zipfile; /* filename of the Zipfile */ +extern char *tempzip; /* Temporary zip file name */ + +extern MacZipGlobals MacZip; + + +/* don't include "osdep.h" otherwise we will trap into endless loop */ +#undef open +#undef fopen + + + +FILE *MacFopen(const char *path, const char *mode) +{ +static char TruncPath[NAME_MAX]; +OSErr err = 0; + +AssertStr(path,path) + + /* open zipfile or tempzip */ +if (strcmp(zipfile,path) == 0) + { + GetCompletePath(MacZip.ZipFullPath,path,&MacZip.ZipFileSpec,&err); + err = PrintUserHFSerr((err != -43) && (err != 0), err, path); + printerr("GetCompletePath:",err,err,__LINE__,__FILE__,path); + if (CheckMountedVolumes(MacZip.ZipFullPath) > 1) + DoWarnUserDupVol(MacZip.ZipFullPath); + + /* tempfile should appear in the same directory of the zipfile + -> save path of zipfile */ + TruncFilename(TruncPath, MacZip.ZipFullPath); + return fopen(MacZip.ZipFullPath, mode); + } + +if (strcmp(tempzip,path) == 0) + { /* add path of zipfile */ + sstrcat(TruncPath,tempzip); + GetCompletePath(MacZip.TempZipFullPath,TruncPath,&MacZip.TempZipFileSpec,&err); + err = PrintUserHFSerr((err != -43) && (err != 0), err, path); + printerr("GetCompletePath:",err,err,__LINE__,__FILE__,path); + + return fopen(MacZip.TempZipFullPath, mode); + } + +printerr("MacFopen:",err,err,__LINE__,__FILE__,path); +return NULL; +} + + + + +int MacOpen(const char *path,int oflag, ...) +{ +char RealFname[NAME_MAX]; + +AssertStr(path,path) + +RfDfFilen2Real(RealFname,path, MacZip.MacZipMode, MacZip.DataForkOnly, &MacZip.CurrentFork); +/* convert to real fname and init global var MacZip.CurrentFork !! */ + +switch (MacZip.CurrentFork) + { + case DataFork: + { + return my_open(RealFname, oflag); + break; + } + case ResourceFork: + { + return my_open( RealFname, oflag | O_RSRC); + break; + } + default: /* for now (Zip ver 2.3b) MacOpen should never reach this point */ + { /* however, this may change in the future ... */ + printerr("open: no resource / datafork ",-1,-1,__LINE__,__FILE__,path); + return -1; + } + } +} + + +#ifdef muell + /* file to delete */ +int destroy(char *path) +{ +static char lastpath[NAME_MAX]; +char currpath[NAME_MAX]; +static Boolean FirstCall = true; +long rc; + +AssertStr(path,path) + +RfDfFilen2Real(currpath, path, MacZip.MacZipMode, MacZip.DataForkOnly, &MacZip.CurrentFork); + +if (FirstCall == true) + { + FirstCall = false; + rc = remove(currpath); + } +else if (strcmp(currpath,lastpath) == 0) return 0; /* ignore, file is already deleted */ + else rc = remove(currpath); /* we are removeing all the files only by their + pathname this is dangerous on a mac but there is no other way without + a complete rewrite of the port */ + +strcpy(lastpath,currpath); + +return rc; +} +#endif + + + + +/* this function replaces the function "replace()" defined in fileio.c */ +int replace(char *new_f, char *temp_f) /* destination and source file names */ +{ +OSErr err = 0; +char newfname[NAME_MAX]; + +AssertStr(new_f,new_f) +AssertStr(temp_f,temp_f) + +UserStop(); + +GetFilename(newfname, new_f); + +/* check zipfile name and tempfile name */ +/* we are using this function only for replacing the tempfile with the zipfile */ +if ((strcmp(zipfile,new_f) == 0) || (strcmp(tempzip,temp_f) == 0)) + { + remove(MacZip.ZipFullPath); + + /* rename the temp file to the zip file */ + err = rename(MacZip.TempZipFullPath,MacZip.ZipFullPath); + printerr("rename:",err,err,__LINE__,__FILE__,MacZip.TempZipFullPath); +if (err != 0) return ZE_CREAT; + else return ZE_OK; + } +else return ZE_CREAT; +} + + + + /* file to delete */ + /* we are removeing all the files only by their + pathname this is dangerous on a mac but there is no + other way without a complete rewrite of the port */ + +int destroy(char *path) +{ +static char lastpath[NAME_MAX]; +static FSSpec trashfolder; +static Boolean FirstCall = true; +static char Num = 0; +static Boolean Immediate_File_Deletion = false; +char currpath[NAME_MAX], *envptr; +FSSpec fileToDelete; +OSErr err; + +/* init this function */ +if ((path == NULL) || + (strlen(path) == 0)) + { + FirstCall = true; + Num = 0; + return -1; + } + +UserStop(); + +RfDfFilen2Real(currpath, path, MacZip.MacZipMode, + MacZip.DataForkOnly, &MacZip.CurrentFork); +GetCompletePath(currpath,currpath,&fileToDelete, &err); + +if (FirstCall == true) + { + FirstCall = false; + sstrcpy(lastpath,currpath); + err = FSpFindFolder(fileToDelete.vRefNum, kTrashFolderType, + kDontCreateFolder,&trashfolder); + printerr("FSpFindFolder:",err,err,__LINE__,__FILE__,path); + + envptr = getenv("Immediate_File_Deletion"); + if (!(envptr == (char *)NULL || *envptr == '\0')) + { + if (stricmp(envptr,"yes") == 0) + Immediate_File_Deletion = true; + else + Immediate_File_Deletion = false; + } + + if (Immediate_File_Deletion) + { + err = FSpDelete(&fileToDelete); + return err; + } + + err = CatMove (fileToDelete.vRefNum, fileToDelete.parID, + fileToDelete.name, trashfolder.parID, trashfolder.name); + return err; + } + +if (strcmp(currpath,lastpath) == 0) + { + return 0; /* ignore, file is already deleted */ + } +else + { + + if (Immediate_File_Deletion) + { + err = FSpDelete(&fileToDelete); + sstrcpy(lastpath,path); + return err; + } + + err = CatMove (fileToDelete.vRefNum, fileToDelete.parID, + fileToDelete.name, trashfolder.parID, trashfolder.name); + + /* -48 = file is already existing so we have to rename it before + moving the file */ + if (err == -48) + { + Num++; + if (fileToDelete.name[0] >= 28) /* cut filename if to long */ + fileToDelete.name[0] = 28; + P2CStr(fileToDelete.name); + sprintf(currpath,"%s~%d",(char *)fileToDelete.name,Num); + C2PStr(currpath); + C2PStr((char *)fileToDelete.name); + err = HRename (fileToDelete.vRefNum, fileToDelete.parID, + fileToDelete.name, (unsigned char *) currpath); + err = CatMove (fileToDelete.vRefNum, fileToDelete.parID, + (unsigned char *) currpath, trashfolder.parID, + trashfolder.name); + } + } + +sstrcpy(lastpath,currpath); +return err; +} + + + +#endif /* #ifdef MACZIP */ + + + + +/* + * int open(const char *path, int oflag) + * + * Opens a file stream. + */ +int my_open(char *path, int oflag) +{ + FSSpec spec; + char permission; + HParamBlockRec hpb; + OSErr err, errno; + Boolean targetIsFolder, wasAliased; + + AssertStr(path,path) + + /* Setup permission */ + if ((oflag & 0x03) == O_RDWR) + permission = fsRdWrPerm; + else + permission = (oflag & O_RDONLY) ? fsRdPerm : 0 + (oflag & O_WRONLY) ? fsWrPerm : 0; + + FSpLocationFromFullPath(strlen(path),path, &spec); + if ((oflag & (O_ALIAS | O_NRESOLVE)) == 0) + ResolveAliasFile(&spec, true, &targetIsFolder, &wasAliased); + hpb.fileParam.ioNamePtr = spec.name; + hpb.fileParam.ioVRefNum = spec.vRefNum; + hpb.fileParam.ioDirID = spec.parID; + hpb.ioParam.ioPermssn = permission; + + if (oflag & O_RSRC) /* open the resource fork of the file */ + err = PBHOpenRFSync(&hpb); + else /* open the data fork of the file */ + err = PBHOpenDFSync(&hpb); + + if ((err == fnfErr) && (oflag & O_CREAT)) { + hpb.fileParam.ioFlVersNum = 0; + err = PBHCreateSync(&hpb); + if (err == noErr) { + /* Set the finder info */ + unsigned long secs; + unsigned long isbinary = oflag & O_BINARY; + + hpb.fileParam.ioFlFndrInfo.fdType = '\?\?\?\?'; + hpb.fileParam.ioFlFndrInfo.fdCreator = '\?\?\?\?'; + hpb.fileParam.ioFlFndrInfo.fdFlags = 0; + if (oflag & O_ALIAS) /* set the alias bit */ + hpb.fileParam.ioFlFndrInfo.fdFlags = kIsAlias; + else /* clear all flags */ + hpb.fileParam.ioFlFndrInfo.fdFlags = 0; + + GetDateTime(&secs); + hpb.fileParam.ioFlCrDat = hpb.fileParam.ioFlMdDat = secs; + PBHSetFInfoSync(&hpb); + } + + if (err && (err != dupFNErr)) { + errno = err; return -1; + } + + if (oflag & O_RSRC) /* open the resource fork of the file */ + err = PBHOpenRFSync(&hpb); + else /* open the data fork of the file */ + err = PBHOpenDFSync(&hpb); + } + + if (err && (err != dupFNErr) && (err != opWrErr)) { + errno = err; return -1; + } + + if (oflag & O_TRUNC) { + IOParam pb; + + pb.ioRefNum = hpb.ioParam.ioRefNum; + pb.ioMisc = 0L; + err = PBSetEOFSync((ParmBlkPtr)&pb); + if (err != noErr) { + errno = err; return -1; + } + } + + if (oflag & O_APPEND) lseek(hpb.ioParam.ioRefNum,0,SEEK_END); + + return (hpb.ioParam.ioRefNum); +} + + + + + diff --git a/macos/source/macopen.h b/macos/source/macopen.h new file mode 100644 index 0000000..152bceb --- /dev/null +++ b/macos/source/macopen.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#ifndef __MACOPEN_H__ +#define __MACOPEN_H__ + +#include +#include + + +FILE *MacFopen(const char *path, const char *mode); +int MacOpen(const char *path, int oflag, ...); + +int my_open(char *path, int oflag); + +#endif /* __MACOPEN_H__ */ diff --git a/macos/source/macos.c b/macos/source/macos.c new file mode 100644 index 0000000..935c9a1 --- /dev/null +++ b/macos/source/macos.c @@ -0,0 +1,1079 @@ +/* + 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 +*/ +/*--------------------------------------------------------------------------- + + macos.c + + Macintosh-specific routines for use with Info-ZIP's Zip 2.3 and later. + + ---------------------------------------------------------------------------*/ + + +/*****************************************************************************/ +/* Includes */ +/*****************************************************************************/ + +#include "zip.h" + +#include "revision.h" +#include "crypt.h" + +#include +#include +#include +#include + +#include + +#include +#include + +/* #include "charmap.h" */ +#include "helpers.h" +#include "macstuff.h" +#include "pathname.h" +#include "recurse.h" + + +/*****************************************************************************/ +/* Macros, typedefs */ +/*****************************************************************************/ + +#define PATH_END MacPathEnd + +/*****************************************************************************/ +/* Global Vars */ +/*****************************************************************************/ + +int error_level; /* used only in ziperr() */ + + +/* Note: sizeof() returns the size of this allusion + 13 is current length of "XtraStuf.mac:" */ +extern const char ResourceMark[13]; /* var is initialized in file pathname.c */ + + +extern jmp_buf EnvForExit; +MacZipGlobals MacZip; + +unsigned long count_of_Zippedfiles = 0; + + +/*****************************************************************************/ +/* Module level Vars */ +/*****************************************************************************/ + +static const char MacPathEnd = ':'; /* the Macintosh dir separator */ + +/* Inform Progress vars */ +long estTicksToFinish; +long createTime; +long updateTicks; + +static char *Time_Est_strings[] = { + "Zipping Files; Items done:", + "More than 24 hours", + "More than %s hours", + "About %s hours, %s minutes", + "About an hour", + "Less than an hour", + "About %s minutes, %s seconds", + "About a minute", + "Less than a minute", + "About %s seconds", + "About a second", + "About 1 minute, %s seconds"}; + + + +/*****************************************************************************/ +/* Prototypes */ +/*****************************************************************************/ + +int DoCurrentDir(void); + +void DoAboutBox(void); +void DoQuit(void); +void DoEventLoop(void); + +void ZipInitAllVars(void); +void UserStop(void); +Boolean IsZipFile(char *name); + +static long EstimateCompletionTime(const long progressMax, + const long progressSoFar, unsigned char percent); +static void UpdateTimeToComplete(void); + + + + +#ifdef USE_SIOUX +#include +void DoWarnUserDupVol( char *FullPath ); + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ + +/* +** Standalone Unzip with Metrowerks SIOUX starts here +** +*/ +int main(int argc, char **argv) +{ + int return_code; + + SIOUXSettings.asktosaveonclose = FALSE; + SIOUXSettings.showstatusline = TRUE; + + SIOUXSettings.columns = 100; + SIOUXSettings.rows = 40; + + /* 30 = MacZip Johnny Lee's; 40 = new (my) MacZip */ + MacZip.MacZipMode = NewZipMode_EF; + + argc = ccommand(&argv); + if (verbose) PrintArguments(argc, argv); + + ZipInitAllVars(); + + return_code = zipmain(argc, argv); + + if (verbose) printf("\n\n Finish"); + return return_code; +} + + + +/* +** SIOUX needs no extra event handling +** +*/ + +void UserStop(void) +{ +}; + + + + +/* +** Password enter function '*' printed for each char +** +*/ + +int macgetch(void) +{ + WindowPtr whichWindow; + EventRecord theEvent; + char c; /* one-byte buffer for read() to use */ + + do { + SystemTask(); + if (!GetNextEvent(everyEvent, &theEvent)) + theEvent.what = nullEvent; + else { + switch (theEvent.what) { + case keyDown: + c = theEvent.message & charCodeMask; + break; + case mouseDown: + if (FindWindow(theEvent.where, &whichWindow) == + inSysWindow) + SystemClick(&theEvent, whichWindow); + break; + case updateEvt: + break; + } + } + } while (theEvent.what != keyDown); + + printf("*"); + fflush(stdout); + + return (int)c; +} + +#endif + + + + +/******************************/ +/* Function version_local() */ +/******************************/ + +/* +** Print Compilers version and compile time/date +** +*/ + +void version_local() +{ +/* prints e.g: +Compiled with Metrowerks CodeWarrior version 2000 for PowerPC Processor + compile time: Feb 4 1998 17:49:49. +*/ + +static ZCONST char CompiledWith[] = + "\n\nCompiled with %s %x for %s \n %s %s %s.\n\n"; + + printf(CompiledWith, + + +#ifdef __MWERKS__ + " Metrowerks CodeWarrior version", __MWERKS__, +#endif + + +#ifdef __MC68K__ + " MC68K Processor", +#else + " PowerPC Processor", +#endif + +#ifdef __DATE__ + "compile time: ", __DATE__, __TIME__ +#else + "", "", "" +#endif + ); +} /* end function version_local() */ + + + + + +/* +** Deletes a dir if the switch '-m' is used +** +*/ + +int deletedir(char *path) +{ +static char Num = 0; +static FSSpec trashfolder; +static Boolean FirstCall = true; +static Boolean Immediate_File_Deletion = false; +OSErr err; +FSSpec dirToDelete; +char currpath[NAME_MAX], *envptr; +CInfoPBRec fpb; + +/* init this function */ +if ((path == NULL) || + (strlen(path) == 0)) + { + Num = 0; + FirstCall = true; + return -1; + } + +UserStop(); + +GetCompletePath(currpath,path,&dirToDelete, &err); + +if (FirstCall == true) + { + FirstCall = false; + envptr = getenv("Immediate_File_Deletion"); + if (!(envptr == (char *)NULL || *envptr == '\0')) + { + if (stricmp(envptr,"yes") == 0) + Immediate_File_Deletion = true; + else + Immediate_File_Deletion = false; + } + err = FSpFindFolder(dirToDelete.vRefNum, kTrashFolderType, + kDontCreateFolder,&trashfolder); + printerr("FSpFindFolder:",err,err,__LINE__,__FILE__,path); + } + + fpb.dirInfo.ioNamePtr = dirToDelete.name; + fpb.dirInfo.ioVRefNum = dirToDelete.vRefNum; + fpb.dirInfo.ioDrDirID = dirToDelete.parID; + fpb.dirInfo.ioFDirIndex = 0; + + err = PBGetCatInfoSync(&fpb); + printerr("PBGetCatInfo deletedir ", err, err, + __LINE__, __FILE__, ""); + +if (fpb.dirInfo.ioDrNmFls > 0) + { + return 0; /* do not move / delete folders which are not empty */ + } + +if (Immediate_File_Deletion) + { + err = FSpDelete(&dirToDelete); + return err; + } + +err = CatMove (dirToDelete.vRefNum, dirToDelete.parID, + dirToDelete.name, trashfolder.parID, trashfolder.name); + +/* -48 = file is already existing so we have to rename it before + moving the file */ +if (err == -48) + { + Num++; + if (dirToDelete.name[0] >= 28) /* cut foldername if to long */ + dirToDelete.name[0] = 28; + P2CStr(dirToDelete.name); + sprintf(currpath,"%s~%d",(char *)dirToDelete.name,Num); + C2PStr(currpath); + C2PStr((char *)dirToDelete.name); + err = HRename (dirToDelete.vRefNum, dirToDelete.parID, + dirToDelete.name, (unsigned char *) currpath); + + err = CatMove (dirToDelete.vRefNum, dirToDelete.parID, + (unsigned char *) currpath, trashfolder.parID, + trashfolder.name); + } + +return err; +} + + + + +/* +** Set the file-type so the archive will get the correct icon, type +** and creator code. +*/ + +void setfiletype(char *new_f, unsigned long Creator, unsigned long Type) +{ +OSErr err; + +if (strcmp(zipfile, new_f) == 0) + err = FSpChangeCreatorType(&MacZip.ZipFileSpec, Creator, Type); +printerr("FSpChangeCreatorType:", err, err, __LINE__, __FILE__, new_f); + +return; +} + + + + + +/* +** Convert the external (native) filename into Zip's internal Unix compatible +** name space. +*/ + +char *ex2in(char *externalFilen, int isdir, int *pdosflag) +/* char *externalFilen external file name */ +/* int isdir input: externalFilen 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 *internalFilen; /* internal file name (malloc'ed) */ + char *t; /* shortened name */ + char *Pathname; + char buffer[NAME_MAX]; + int dosflag; + + AssertStr(externalFilen, externalFilen) + AssertBool(isdir,"") + + dosflag = dosify; /* default for non-DOS and non-OS/2 */ + + /* Find starting point in name before doing malloc */ + for (t = externalFilen; *t == PATH_END; t++) + ; + + if (!MacZip.StoreFullPath) + { + Pathname = StripPartialDir(buffer, MacZip.SearchDir,t); + } + else + { + Pathname = t; + } + + /* Make changes, if any, to the copied name (leave original intact) */ + if (!pathput) + { + t = last(Pathname, PATH_END); + } + else t = Pathname; + + /* Malloc space for internal name and copy it */ + if ((internalFilen = malloc(strlen(t) + 10 + strlen(ResourceMark) )) == NULL) + return NULL; + + sstrcpy(internalFilen, t); + + /* we have to eliminate illegal chars: + * The name space for Mac filenames and Zip filenames (unix style names) + * do both include all printable extended-ASCII characters. The only + * difference we have to take care of is the single special character + * used as path delimiter: + * ':' on MacOS and '/' on Unix and '\' on Dos. + * So, to convert between Mac filenames and Unix filenames without any + * loss of information, we simply interchange ':' and '/'. Additionally, + * we try to convert the coding of the extended-ASCII characters into + * InfoZip's standard ISO 8859-1 codepage table. + */ + MakeCompatibleString(internalFilen, ':', '/', '/', ':', + MacZip.CurrTextEncodingBase); + + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + + if (isdir) + { + return internalFilen; /* avoid warning on unused variable */ + } + + if (dosify) + { + msname(internalFilen); + printf("\n ex2in: %s",internalFilen); + } + + return internalFilen; +} + + + +/* +** Collect all filenames. Go through all directories +** +*/ + +int wild(char *Pathpat) + /* path/pattern to match */ +/* If not in exclude mode, expand the pattern based on the contents of the + file system. Return an error code in the ZE_ class. */ +{ +FSSpec Spec; +char fullpath[NAME_MAX]; +OSErr err; + +AssertStr(Pathpat, Pathpat); + +if (noisy) printf("%s \n\n",GetZipVersionsInfo()); + +if (extra_fields == 0) + { + MacZip.DataForkOnly = true; + } + +/* for switch '-R' -> '.' means current dir */ +if (strcmp(Pathpat,".") == 0) sstrcpy(Pathpat,"*"); + +sstrcpy(MacZip.Pattern,Pathpat); + +if (recurse) + { + MacZip.StoreFoldersAlso = true; + MacZip.SearchLevels = 0; /* if 0 we aren't checking levels */ + } +else + { + MacZip.StoreFoldersAlso = false; + MacZip.SearchLevels = 1; + } + +/* make complete path */ +GetCompletePath(fullpath, MacZip.Pattern, &Spec,&err); +err = PrintUserHFSerr((err != -43) && (err != 0), err, MacZip.Pattern); +printerr("GetCompletePath:", err, err, __LINE__, __FILE__, fullpath); + +/* extract the filepattern */ +GetFilename(MacZip.Pattern, fullpath); + +/* extract Path and get FSSpec of search-path */ +/* get FSSpec of search-path ; we need a dir to start + searching for filenames */ +TruncFilename(MacZip.SearchDir, fullpath); +GetCompletePath(MacZip.SearchDir, MacZip.SearchDir, &Spec,&err); + +if (noisy) { + if (MacZip.SearchLevels == 0) + { + printf("\nSearch Pattern: [%s] Levels: all", MacZip.Pattern); + } + else + { + printf("\nSearch Pattern: [%s] Levels: %d", MacZip.Pattern, + MacZip.SearchLevels); + } + printf("\nSearch Path: [%s]", MacZip.SearchDir); + printf("\nZip-File: [%s] \n",MacZip.ZipFullPath); + +} + +/* we are working only with pathnames; + * this can cause big problems on a mac ... + */ +if (CheckMountedVolumes(MacZip.SearchDir) > 1) + DoWarnUserDupVol(MacZip.SearchDir); + +/* start getting all filenames */ +err = FSpRecurseDirectory(&Spec, MacZip.SearchLevels); +printerr("FSpRecurseDirectory:", err, err, __LINE__, __FILE__, ""); + +return ZE_OK; +} + + + +/* +** Convert the internal filename into a external (native). +** The user will see this modified filename. +** For more performance: +** I do not completly switch back to the native macos filename. +** The user will still see directory separator '/' and the converted +** charset. +*/ + +char *in2ex(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 */ + + AssertStr(n,n) + + if ((x = malloc(strlen(n) + 1)) == NULL) + return NULL; + + RfDfFilen2Real(x, n, MacZip.MacZipMode, MacZip.DataForkOnly, + &MacZip.CurrentFork); + + return x; +} + + + + +/* +** Process on filenames. This function will be called to collect +** the filenames. +*/ + +int procname(char *filename, /* name to process */ + int caseflag) /* true to force case-sensitive match + (always false on a Mac) */ +/* Process a name . Return + an error code in the ZE_ class. */ +{ + int rc; /* matched flag */ + +AssertBool(caseflag,"caseflag") +AssertStr(filename,filename) + + /* add or remove name of file */ +rc = newname(filename, MacZip.isDirectory, caseflag); + +return rc; +} + + + + +ulg filetime( +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() */ + + AssertStr(f,f) + + if (strlen(f) == 0) return 0; + + if (SSTAT(f, &s) != 0) + /* Accept about any file kind including directories + * (stored with trailing : with -r option) + */ + return 0; + + if (a != NULL) { + *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE); + if (MacZip.isDirectory) { + *a |= MSDOS_DIR_ATTR; + } + } + if (n != NULL) + *n = (s.st_mode & UNX_IFMT) == UNX_IFREG ? s.st_size : -1L; + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_ctime; /* on Mac, st_ctime contains creation time! */ + } + + return unix2dostime(&s.st_mtime); +} + + + +void stamp(char *f, ulg d) +/* char *f; name of file to change */ +/* ulg d; dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ + time_t u[2]; /* argument for utime() */ + +f = f; + + /* Convert DOS time to time_t format in u */ + + u[0] = u[1] = dos2unixtime(d); +/* utime(f, u); */ +} + + + + +/* +** return only the longest part of the path: +** second parameter: Volume:test folder:second folder: +** third parameter: Volume:test folder:second folder:third folder:file +** result will be: third folder:file +** first parameter: contains string buffer that will be used to prepend +** the "resource mark" part in front of the result when +** a resource fork is processed in "M3" mode. +** +*/ + +char *StripPartialDir(char *CompletePath, + const char *PartialPath, const char *FullPath) +{ +const char *tmpPtr1 = PartialPath; +const char *tmpPtr2 = FullPath; +int result; + +Assert_it(CompletePath,"StripPartialDir","") +AssertStrNoOverlap(FullPath,PartialPath,PartialPath) + +if (MacZip.DataForkOnly) + { + tmpPtr2 += strlen(tmpPtr1); + return (char *)tmpPtr2; + } + +switch (MacZip.MacZipMode) + { + case JohnnyLee_EF: + { + tmpPtr2 += strlen(tmpPtr1); + return (char *)tmpPtr2; + break; + } + + case NewZipMode_EF: + { /* determine Fork type */ + result = strncmp(FullPath, ResourceMark, sizeof(ResourceMark)-2); + if (result != 0) + { /* data fork */ + MacZip.CurrentFork = DataFork; + tmpPtr2 += strlen(tmpPtr1); + return (char *)tmpPtr2; + } + else + { /* resource fork */ + MacZip.CurrentFork = ResourceFork; + sstrcpy(CompletePath, ResourceMark); + tmpPtr2 += strlen(tmpPtr1); + tmpPtr2 += sizeof(ResourceMark); + sstrcat(CompletePath, tmpPtr2); + return (char *)CompletePath; + } + break; + } + } + + return NULL; /* function should never reach this point */ +} + + + + +/* +** Init all global variables +** Must be called for each zip-run +*/ + +void ZipInitAllVars(void) +{ +getcwd(MacZip.CurrentPath, sizeof(MacZip.CurrentPath)); +/* MacZip.MacZipMode = JohnnyLee_EF; */ +MacZip.MacZipMode = NewZipMode_EF; + +MacZip.DataForkOnly = false; +MacZip.CurrentFork = NoFork; + +MacZip.StoreFoldersAlso = false; + +MacZip.FoundFiles = 0; +MacZip.FoundDirectories = 0; +MacZip.RawCountOfItems = 0; +MacZip.BytesOfData = 0; + +MacZip.StoreFullPath = false; +MacZip.StatingProgress = false; +MacZip.IncludeInvisible = false; + +MacZip.isMacStatValid = false; + +MacZip.CurrTextEncodingBase = FontScript(); + +MacZip.HaveGMToffset = false; + +createTime = TickCount(); +estTicksToFinish = -1; +updateTicks = 0; + +/* init some functions */ +IsZipFile(NULL); + +destroy(NULL); +deletedir(NULL); +ShowCounter(true); + +extra_fields = 1; +error_level = 0; +count_of_Zippedfiles = 0; +} + + + + +/* +** Get the findercomment and store it as file-comment in the Zip-file +** +*/ +char *GetComment(char *filename) +{ +OSErr err; +static char buffer[NAME_MAX]; +char buffer2[NAME_MAX]; +char *tmpPtr; + +if (filename == NULL) return NULL; + + /* now we can convert Unix-Path in HFS-Path */ +for (tmpPtr = filename; *tmpPtr; tmpPtr++) + if (*tmpPtr == '/') + *tmpPtr = ':'; + +if (MacZip.StoreFullPath) + { /* filename is already a fullpath */ + sstrcpy(buffer,filename); + } +else + { /* make a fullpath */ + sstrcpy(buffer,MacZip.SearchDir); + sstrcat(buffer,filename); + } + +/* make fullpath and get FSSpec */ +/* Unfortunately: I get only the converted filename here */ +/* so filenames with extended characters can not be found */ +GetCompletePath(buffer2,buffer, &MacZip.fileSpec, &err); +printerr("GetCompletePath:",(err != -43) && (err != -120) && (err != 0) , + err,__LINE__,__FILE__,buffer); + +err = FSpDTGetComment(&MacZip.fileSpec, (unsigned char *) buffer); +printerr("FSpDTGetComment:", (err != -5012) && (err != 0), err, + __LINE__, __FILE__, filename); +P2CStr((unsigned char *) buffer); +if (err == -5012) return NULL; /* no finder-comments found */ + +if (noisy) printf("\n%32s -> %s",filename, buffer); +/* +Beside the script change we need only to change 0x0d in 0x0a +so the last two arguments are not needed and does nothing. +*/ +MakeCompatibleString(buffer, 0x0d, 0x0a, ' ', ' ', + MacZip.CurrTextEncodingBase); + +return buffer; +} + + + + +/* +** Print a progress indicator for stating the files +** +*/ + +void PrintStatProgress(char *msg) +{ + +if (!noisy) return; /* do no output if noisy is false */ + +MacZip.StatingProgress = true; + +if (strcmp(msg,"done") == 0) + { + MacZip.StatingProgress = false; + printf("\n ... done \n\n"); + } +else printf("\n %s",msg); + +} + + + + +void InformProgress(const long progressMax, const long progressSoFar ) +{ +int curr_percent; +char no_time[5] = "..."; + +curr_percent = percent(progressMax, progressSoFar); + +if (curr_percent < 95) + { + estTicksToFinish = EstimateCompletionTime(progressMax, + progressSoFar, curr_percent); + } +else + { + rightStatusString(no_time); + leftStatusString(no_time); + } + +updateTicks = TickCount() + 60; +return; +} + + +void ShowCounter(Boolean reset) +{ +static char statusline[100]; +static unsigned long filecount = 0; + +if (reset) + { + filecount = 0; + return; + } + +if (noisy) + { + sprintf(statusline, "%6d", filecount++); + rightStatusString(statusline); + } +} + + +static long EstimateCompletionTime(const long progressMax, + const long progressSoFar, + unsigned char curr_percent) +{ + long max = progressMax, value = progressSoFar; + static char buf[100]; + unsigned long ticksTakenSoFar = TickCount() - createTime; + float currentRate = (float) ticksTakenSoFar / (float) value; + long newEst = (long)( currentRate * (float)( max - value )); + + sprintf(buf, "%d [%d%%]",progressSoFar, curr_percent); + rightStatusString(buf); + + estTicksToFinish = newEst; + + UpdateTimeToComplete(); + +return estTicksToFinish; +} + + + + + +static void UpdateTimeToComplete(void) +{ + short days, hours, minutes, seconds; + char estStr[255]; + Str15 xx, yy; + short idx = 0; + + if ( estTicksToFinish == -1 ) + return; + + days = estTicksToFinish / 5184000L; + hours = ( estTicksToFinish - ( days * 5184000L )) / 216000L; + minutes = ( estTicksToFinish - ( days * 5184000L ) - + ( hours * 216000L )) / 3600L; + seconds = ( estTicksToFinish - ( days * 5184000L ) - + ( hours * 216000L ) - ( minutes * 3600L )) / 60L; + + xx[0] = 0; + yy[0] = 0; + + if ( days ) + { + /* "more than 24 hours" */ + + idx = 1; + goto setEstTimeStr; + } + + if ( hours >= 8 ) + { + /* "more than x hours" */ + + NumToString( hours, xx ); + idx = 2; + goto setEstTimeStr; + } + + if ( estTicksToFinish > 252000L ) /* > 1hr, 10 minutes */ + { + /* "about x hours, y minutes" */ + + NumToString( hours, xx ); + NumToString( minutes, yy ); + idx = 3; + goto setEstTimeStr; + } + + if ( estTicksToFinish > 198000L ) /* > 55 minutes */ + { + /* "about an hour" */ + idx = 4; + goto setEstTimeStr; + } + + if ( estTicksToFinish > 144000L ) /* > 40 minutes */ + { + /* "less than an hour" */ + + idx = 5; + goto setEstTimeStr; + } + + if ( estTicksToFinish > 4200L ) /* > 1 minute, 10 sec */ + { + /* "about x minutes, y seconds */ + + NumToString( minutes, xx ); + NumToString( seconds, yy ); + + if ( minutes == 1 ) + idx = 11; + else + idx = 6; + goto setEstTimeStr; + } + + if ( estTicksToFinish > 3000L ) /* > 50 seconds */ + { + /* "about a minute" */ + + idx = 7; + goto setEstTimeStr; + } + + if ( estTicksToFinish > 1500L ) /* > 25 seconds */ + { + /* "less than a minute" */ + + idx = 8; + goto setEstTimeStr; + } + + if ( estTicksToFinish > 120L ) /* > 2 seconds */ + { + NumToString( seconds, xx ); + idx = 9; + goto setEstTimeStr; + } + + idx = 10; + + setEstTimeStr: + sprintf(estStr,Time_Est_strings[idx],P2CStr(xx),P2CStr(yy)); + leftStatusString((char *)estStr); +} + + + + + +/* +** Just return the zip version +** +*/ + +char *GetZipVersionsInfo(void) +{ +static char ZipVersion[100]; + +sprintf(ZipVersion, "Zip Module\n%d.%d%d%s of %s", Z_MAJORVER, Z_MINORVER, + Z_PATCHLEVEL, Z_BETALEVEL, REVDATE); + +return ZipVersion; +} + + + + +#ifndef USE_SIOUX + +/* +** Just return the copyright message +** +*/ + +char *GetZipCopyright(void) +{ +static char CopyR[300]; + +sstrcpy(CopyR, copyright[0]); +sstrcat(CopyR, copyright[1]); +sstrcat(CopyR, "\r\rPlease send bug reports to the authors at\r"\ + "Zip-Bugs@lists.wku.edu"); + +return CopyR; +} + + + + +/* +** Just return the compilers date/time +** +*/ + +char *GetZipVersionLocal(void) +{ +static char ZipVersionLocal[50]; + +sprintf(ZipVersionLocal, "[%s %s]", __DATE__, __TIME__); + +return ZipVersionLocal; +} + +#endif /* #ifndef USE_SIOUX */ + + + + diff --git a/macos/source/macstuff.c b/macos/source/macstuff.c new file mode 100644 index 0000000..0323607 --- /dev/null +++ b/macos/source/macstuff.c @@ -0,0 +1,1724 @@ +/* +These Functions were originally part of More Files version 1.4.8 + +More Files fixes many of the broken or underfunctional +parts of the file system. + +More Files + +A collection of File Manager and related routines + +by Jim Luther (Apple Macintosh Developer Technical Support Emeritus) +with significant code contributions by Nitin Ganatra +(Apple Macintosh Developer Technical Support Emeritus) +Copyright 1992-1998 Apple Computer, Inc. +Portions copyright 1995 Jim Luther +All rights reserved. + +The Package "More Files" is distributed under the following +license terms: + + "You may incorporate this sample code into your + applications without restriction, though the + sample code has been provided "AS IS" and the + responsibility for its operation is 100% yours. + However, what you are not permitted to do is to + redistribute the source as "DSC Sample Code" after + having made changes. If you're going to + redistribute the source, we require that you make + it clear in the source that the code was descended + from Apple Sample Code, but that you've made + changes." + + +The following changes are made by Info-ZIP: + +- The only changes are made by pasting the functions + (mostly found in MoreFilesExtras.c / MoreFiles.c) + directly into macstuff.c / macstuff.h and slightly + reformatting the text (replacement of TABs by spaces, + removal/replacement of non-ASCII characters). + The code itself is NOT changed. + +This file has been modified by Info-ZIP for use in MacZip. +This file is NOT part of the original package More Files. + +More Files can be found on the MetroWerks CD and Developer CD from +Apple. You can also download the latest version from: + + http://members.aol.com/JumpLong/#MoreFiles + +Jim Luther's Home-page: + http://members.aol.com/JumpLong/ + + +*/ + +#include + + +#include "macstuff.h" + + + +extern int errno; + +static OSErr GetCommentFromDesktopFile(short vRefNum, + long dirID, + ConstStr255Param name, + Str255 comment); + +static OSErr GetCommentID(short vRefNum, + long dirID, + ConstStr255Param name, + short *commentID); + +static OSErr GetDesktopFileName(short vRefNum, + Str255 desktopName); + + +enum +{ + kBNDLResType = 'BNDL', + kFREFResType = 'FREF', + kIconFamResType = 'ICN#', + kFCMTResType = 'FCMT', + kAPPLResType = 'APPL' +}; + + +/*****************************************************************************/ + +/* +** File Manager FSp calls +*/ + +/*****************************************************************************/ + +pascal OSErr FSMakeFSSpecCompat(short vRefNum, + long dirID, + ConstStr255Param fileName, + FSSpec *spec) +{ + OSErr result; + +#if !__MACOSSEVENORLATER + if ( !FSHasFSSpecCalls() && !QTHasFSSpecCalls() ) + { + Boolean isDirectory; + + result = GetObjectLocation(vRefNum, dirID, fileName, + &(spec->vRefNum), &(spec->parID), spec->name, + &isDirectory); + } + else +#endif /* !__MACOSSEVENORLATER */ + { + /* Let the file system create the FSSpec if it can since it does the job */ + /* much more efficiently than I can. */ + result = FSMakeFSSpec(vRefNum, dirID, fileName, spec); + + /* Fix a bug in Macintosh PC Exchange's MakeFSSpec code where 0 is */ + /* returned in the parID field when making an FSSpec to the volume's */ + /* root directory by passing a full pathname in MakeFSSpec's */ + /* fileName parameter. Fixed in Mac OS 8.1 */ + if ( (result == noErr) && (spec->parID == 0) ) + spec->parID = fsRtParID; + } + return ( result ); +} + + +/*****************************************************************************/ +/* FSHasFSSpecCalls returns true if the file system provides FSSpec calls. */ + +#if !__MACOSSEVENORLATER +static Boolean FSHasFSSpecCalls(void) +{ + long response; +#if !GENERATENODATA + static Boolean tested = false; + static Boolean result = false; +#else + Boolean result = false; +#endif + +#if !GENERATENODATA + if ( !tested ) + { + tested = true; +#endif + if ( Gestalt(gestaltFSAttr, &response) == noErr ) + { + result = ((response & (1L << gestaltHasFSSpecCalls)) != 0); + } +#if !GENERATENODATA + } +#endif + return ( result ); +} +#endif /* !__MACOSSEVENORLATER */ + + + +/*****************************************************************************/ +/* QTHasFSSpecCalls returns true if QuickTime provides FSSpec calls */ +/* except for FSpExchangeFiles. */ + +#if !__MACOSSEVENORLATER +static Boolean QTHasFSSpecCalls(void) +{ + long response; +#if !GENERATENODATA + static Boolean tested = false; + static Boolean result = false; +#else + Boolean result = false; +#endif + +#if !GENERATENODATA + if ( !tested ) + { + tested = true; +#endif + result = (Gestalt(gestaltQuickTimeVersion, &response) == noErr); +#if !GENERATENODATA + } +#endif + return ( result ); +} +#endif /* !__MACOSSEVENORLATER */ + + + + +/* + *---------------------------------------------------------------------- + * + * FSpGetDefaultDir -- + * + * This function gets the current default directory. + * + * Results: + * The provided FSSpec is changed to point to the "default" + * directory. The function returns what ever errors + * FSMakeFSSpecCompat may encounter. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int FSpGetDefaultDir(FSSpecPtr dirSpec) /* On return the default directory. */ +{ + OSErr err; + short vRefNum = 0; + long int dirID = 0; + + err = HGetVol(NULL, &vRefNum, &dirID); + + if (err == noErr) { + err = FSMakeFSSpecCompat(vRefNum, dirID, (ConstStr255Param) NULL, + dirSpec); + } + + return err; +} + +/* + *---------------------------------------------------------------------- + * + * FSpSetDefaultDir -- + * + * This function sets the default directory to the directory + * pointed to by the provided FSSpec. + * + * Results: + * The function returns what ever errors HSetVol may encounter. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int FSpSetDefaultDir(FSSpecPtr dirSpec) /* The new default directory. */ +{ + OSErr err; + + /* + * The following special case is needed to work around a bug + * in the Macintosh OS. (Acutally PC Exchange.) + */ + + if (dirSpec->parID == fsRtParID) { + err = HSetVol(NULL, dirSpec->vRefNum, fsRtDirID); + } else { + err = HSetVol(dirSpec->name, dirSpec->vRefNum, dirSpec->parID); + } + + return err; +} + +/* + *---------------------------------------------------------------------- + * + * FSpFindFolder -- + * + * This function is a version of the FindFolder function that + * returns the result as a FSSpec rather than a vRefNum and dirID. + * + * Results: + * Results will be simaler to that of the FindFolder function. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +OSErr +FSpFindFolder( + short vRefNum, /* Volume reference number. */ + OSType folderType, /* Folder type taken by FindFolder. */ + Boolean createFolder, /* Should we create it if non-existant. */ + FSSpec *spec) /* Pointer to resulting directory. */ +{ + short foundVRefNum; + long foundDirID; + OSErr err; + + err = FindFolder(vRefNum, folderType, createFolder, + &foundVRefNum, &foundDirID); + if (err != noErr) { + return err; + } + + err = FSMakeFSSpecCompat(foundVRefNum, foundDirID, "\p", spec); + return err; +} + + + +/* + *---------------------------------------------------------------------- + * + * FSpPathFromLocation -- + * + * This function obtains a full path name for a given macintosh + * FSSpec. Unlike the More Files function FSpGetFullPath, this + * function will return a C string in the Handle. It also will + * create paths for FSSpec that do not yet exist. + * + * Results: + * OSErr code. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +OSErr +FSpPathFromLocation( + FSSpec *spec, /* The location we want a path for. */ + int *length, /* Length of the resulting path. */ + Handle *fullPath) /* Handle to path. */ +{ + OSErr err; + FSSpec tempSpec; + CInfoPBRec pb; + + *fullPath = NULL; + + /* + * Make a copy of the input FSSpec that can be modified. + */ + BlockMoveData(spec, &tempSpec, sizeof(FSSpec)); + + if (tempSpec.parID == fsRtParID) { + /* + * The object is a volume. Add a colon to make it a full + * pathname. Allocate a handle for it and we are done. + */ + tempSpec.name[0] += 2; + tempSpec.name[tempSpec.name[0] - 1] = ':'; + tempSpec.name[tempSpec.name[0]] = '\0'; + + err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); + } else { + /* + * The object isn't a volume. Is the object a file or a directory? + */ + pb.dirInfo.ioNamePtr = tempSpec.name; + pb.dirInfo.ioVRefNum = tempSpec.vRefNum; + pb.dirInfo.ioDrDirID = tempSpec.parID; + pb.dirInfo.ioFDirIndex = 0; + err = PBGetCatInfoSync(&pb); + + if ((err == noErr) || (err == fnfErr)) { + /* + * If the file doesn't currently exist we start over. If the + * directory exists everything will work just fine. Otherwise we + * will just fail later. If the object is a directory, append a + * colon so full pathname ends with colon. + */ + if (err == fnfErr) { + BlockMoveData(spec, &tempSpec, sizeof(FSSpec)); + } else if ( (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0 ) { + tempSpec.name[0] += 1; + tempSpec.name[tempSpec.name[0]] = ':'; + } + + /* + * Create a new Handle for the object - make it a C string. + */ + tempSpec.name[0] += 1; + tempSpec.name[tempSpec.name[0]] = '\0'; + err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); + if (err == noErr) { + /* + * Get the ancestor directory names - loop until we have an + * error or find the root directory. + */ + pb.dirInfo.ioNamePtr = tempSpec.name; + pb.dirInfo.ioVRefNum = tempSpec.vRefNum; + pb.dirInfo.ioDrParID = tempSpec.parID; + do { + pb.dirInfo.ioFDirIndex = -1; + pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID; + err = PBGetCatInfoSync(&pb); + if (err == noErr) { + /* + * Append colon to directory name and add + * directory name to beginning of fullPath. + */ + ++tempSpec.name[0]; + tempSpec.name[tempSpec.name[0]] = ':'; + + (void) Munger(*fullPath, 0, NULL, 0, &tempSpec.name[1], + tempSpec.name[0]); + err = MemError(); + } + } while ( (err == noErr) && + (pb.dirInfo.ioDrDirID != fsRtDirID) ); + } + } + } + + /* + * On error Dispose the handle, set it to NULL & return the err. + * Otherwise, set the length & return. + */ + if (err == noErr) { + *length = GetHandleSize(*fullPath) - 1; + } else { + if ( *fullPath != NULL ) { + DisposeHandle(*fullPath); + } + *fullPath = NULL; + *length = 0; + } + + return err; +} + + + +/*****************************************************************************/ + +pascal OSErr FSpGetDirectoryID(const FSSpec *spec, + long *theDirID, + Boolean *isDirectory) +{ + return ( GetDirectoryID(spec->vRefNum, spec->parID, spec->name, + theDirID, isDirectory) ); +} + + +/*****************************************************************************/ + +pascal OSErr GetDirectoryID(short vRefNum, + long dirID, + ConstStr255Param name, + long *theDirID, + Boolean *isDirectory) +{ + CInfoPBRec pb; + OSErr error; + + error = GetCatInfoNoName(vRefNum, dirID, name, &pb); + if ( error == noErr ) + { + *isDirectory = (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0; + if ( *isDirectory ) + { + *theDirID = pb.dirInfo.ioDrDirID; + } + else + { + *theDirID = pb.hFileInfo.ioFlParID; + } + } + + return ( error ); +} + + +/*****************************************************************************/ + +pascal OSErr GetCatInfoNoName(short vRefNum, + long dirID, + ConstStr255Param name, + CInfoPBPtr pb) +{ + Str31 tempName; + OSErr error; + + /* Protection against File Sharing problem */ + if ( (name == NULL) || (name[0] == 0) ) + { + tempName[0] = 0; + pb->dirInfo.ioNamePtr = tempName; + pb->dirInfo.ioFDirIndex = -1; /* use ioDirID */ + } + else + { + pb->dirInfo.ioNamePtr = (StringPtr)name; + pb->dirInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */ + } + pb->dirInfo.ioVRefNum = vRefNum; + pb->dirInfo.ioDrDirID = dirID; + error = PBGetCatInfoSync(pb); + pb->dirInfo.ioNamePtr = NULL; + return ( error ); +} + + + +/*****************************************************************************/ + +pascal OSErr GetObjectLocation(short vRefNum, + long dirID, + ConstStr255Param pathname, + short *realVRefNum, + long *realParID, + Str255 realName, + Boolean *isDirectory) +{ + OSErr error; + CInfoPBRec pb; + Str255 tempPathname; + + /* clear results */ + *realVRefNum = 0; + *realParID = 0; + realName[0] = 0; + + /* + ** Get the real vRefNum + */ + error = DetermineVRefNum(pathname, vRefNum, realVRefNum); + if ( error == noErr ) + { + /* + ** Determine if the object already exists and if so, + ** get the real parent directory ID if it's a file + */ + + /* Protection against File Sharing problem */ + if ( (pathname == NULL) || (pathname[0] == 0) ) + { + tempPathname[0] = 0; + pb.hFileInfo.ioNamePtr = tempPathname; + pb.hFileInfo.ioFDirIndex = -1; /* use ioDirID */ + } + else + { + pb.hFileInfo.ioNamePtr = (StringPtr)pathname; + pb.hFileInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */ + } + pb.hFileInfo.ioVRefNum = vRefNum; + pb.hFileInfo.ioDirID = dirID; + error = PBGetCatInfoSync(&pb); + if ( error == noErr ) + { + /* + ** The file system object is present and we have the file's + ** real parID + */ + + /* Is it a directory or a file? */ + *isDirectory = (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0; + if ( *isDirectory ) + { + /* + ** It's a directory, get its name and parent dirID, and then + ** we're done + */ + + pb.dirInfo.ioNamePtr = realName; + pb.dirInfo.ioVRefNum = *realVRefNum; + /* pb.dirInfo.ioDrDirID already contains the dirID of the + directory object */ + pb.dirInfo.ioFDirIndex = -1; /* get information about ioDirID */ + error = PBGetCatInfoSync(&pb); + + /* get the parent ID here, because the file system can return the */ + /* wrong parent ID from the last call. */ + *realParID = pb.dirInfo.ioDrParID; + } + else + { + /* + ** It's a file - use the parent directory ID from the last call + ** to GetCatInfoparse, get the file name, and then we're done + */ + *realParID = pb.hFileInfo.ioFlParID; + error = GetFilenameFromPathname(pathname, realName); + } + } + else if ( error == fnfErr ) + { + /* + ** The file system object is not present - see if its parent is present + */ + + /* + ** Parse to get the object name from end of pathname + */ + error = GetFilenameFromPathname(pathname, realName); + + /* if we can't get the object name from the end, we can't continue */ + if ( error == noErr ) + { + /* + ** What we want now is the pathname minus the object name + ** for example: + ** if pathname is 'vol:dir:file' tempPathname becomes 'vol:dir:' + ** if pathname is 'vol:dir:file:' tempPathname becomes 'vol:dir:' + ** if pathname is ':dir:file' tempPathname becomes ':dir:' + ** if pathname is ':dir:file:' tempPathname becomes ':dir:' + ** if pathname is ':file' tempPathname becomes ':' + ** if pathname is 'file or file:' tempPathname becomes '' + */ + + /* get a copy of the pathname */ + BlockMoveData(pathname, tempPathname, pathname[0] + 1); + + /* remove the object name */ + tempPathname[0] -= realName[0]; + /* and the trailing colon (if any) */ + if ( pathname[pathname[0]] == ':' ) + { + --tempPathname[0]; + } + + /* OK, now get the parent's directory ID */ + + /* Protection against File Sharing problem */ + pb.hFileInfo.ioNamePtr = (StringPtr)tempPathname; + if ( tempPathname[0] != 0 ) + { + pb.hFileInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */ + } + else + { + pb.hFileInfo.ioFDirIndex = -1; /* use ioDirID */ + } + pb.hFileInfo.ioVRefNum = vRefNum; + pb.hFileInfo.ioDirID = dirID; + error = PBGetCatInfoSync(&pb); + *realParID = pb.dirInfo.ioDrDirID; + + *isDirectory = false; /* we don't know what the object is + really going to be */ + } + + if ( error != noErr ) + { + error = dirNFErr; /* couldn't find parent directory */ + } + else + { + error = fnfErr; /* we found the parent, but not the file */ + } + } + } + + return ( error ); +} + + + +/*****************************************************************************/ + +pascal OSErr DetermineVRefNum(ConstStr255Param pathname, + short vRefNum, + short *realVRefNum) +{ + HParamBlockRec pb; + OSErr error; + + error = GetVolumeInfoNoName(pathname,vRefNum, &pb); + if ( error == noErr ) + { + *realVRefNum = pb.volumeParam.ioVRefNum; + } + return ( error ); +} + + +/*****************************************************************************/ + +pascal OSErr GetFilenameFromPathname(ConstStr255Param pathname, + Str255 filename) +{ + short index; + short nameEnd; + OSErr error; + + /* default to no filename */ + filename[0] = 0; + + /* check for no pathname */ + if ( pathname != NULL ) + { + /* get string length */ + index = pathname[0]; + + /* check for empty string */ + if ( index != 0 ) + { + /* skip over last trailing colon (if any) */ + if ( pathname[index] == ':' ) + { + --index; + } + + /* save the end of the string */ + nameEnd = index; + + /* if pathname ends with multiple colons, then this pathname refers */ + /* to a directory, not a file */ + if ( pathname[index] != ':' ) + { + /* parse backwards until we find a colon or hit the beginning + of the pathname */ + while ( (index != 0) && (pathname[index] != ':') ) + { + --index; + } + + /* if we parsed to the beginning of the pathname and the + pathname ended */ + /* with a colon, then pathname is a full pathname to a volume, + not a file */ + if ( (index != 0) || (pathname[pathname[0]] != ':') ) + { + /* get the filename and return noErr */ + filename[0] = (char)(nameEnd - index); + BlockMoveData(&pathname[index+1], &filename[1], nameEnd - index); + error = noErr; + } + else + { + /* pathname to a volume, not a file */ + error = notAFileErr; + } + } + else + { + /* directory, not a file */ + error = notAFileErr; + } + } + else + { + /* empty string isn't a file */ + error = notAFileErr; + } + } + else + { + /* NULL pathname isn't a file */ + error = notAFileErr; + } + + return ( error ); +} + + + +/*****************************************************************************/ + +/* +** GetVolumeInfoNoName uses pathname and vRefNum to call PBHGetVInfoSync +** in cases where the returned volume name is not needed by the caller. +** The pathname and vRefNum parameters are not touched, and the pb +** parameter is initialized by PBHGetVInfoSync except that ioNamePtr in +** the parameter block is always returned as NULL (since it might point +** to the local tempPathname). +** +** I noticed using this code in several places, so here it is once. +** This reduces the code size of MoreFiles. +*/ +pascal OSErr GetVolumeInfoNoName(ConstStr255Param pathname, + short vRefNum, + HParmBlkPtr pb) +{ + Str255 tempPathname; + OSErr error; + + /* Make sure pb parameter is not NULL */ + if ( pb != NULL ) + { + pb->volumeParam.ioVRefNum = vRefNum; + if ( pathname == NULL ) + { + pb->volumeParam.ioNamePtr = NULL; + pb->volumeParam.ioVolIndex = 0; /* use ioVRefNum only */ + } + else + { /* make a copy of the string and */ + BlockMoveData(pathname, tempPathname, pathname[0] + 1); + /* use the copy so original isn't trashed */ + pb->volumeParam.ioNamePtr = (StringPtr)tempPathname; + /* use ioNamePtr/ioVRefNum combination */ + pb->volumeParam.ioVolIndex = -1; + } + error = PBHGetVInfoSync(pb); + pb->volumeParam.ioNamePtr = NULL; /* ioNamePtr may point to local + tempPathname, so don't return it */ + } + else + { + error = paramErr; + } + return ( error ); +} + + + + +/*****************************************************************************/ + +pascal OSErr FSpGetFullPath(const FSSpec *spec, + short *fullPathLength, + Handle *fullPath) +{ + OSErr result; + OSErr realResult; + FSSpec tempSpec; + CInfoPBRec pb; + + *fullPathLength = 0; + *fullPath = NULL; + + /* Default to noErr */ + realResult = noErr; + + /* Make a copy of the input FSSpec that can be modified */ + BlockMoveData(spec, &tempSpec, sizeof(FSSpec)); + + if ( tempSpec.parID == fsRtParID ) + { + /* The object is a volume */ + + /* Add a colon to make it a full pathname */ + ++tempSpec.name[0]; + tempSpec.name[tempSpec.name[0]] = ':'; + + /* We're done */ + result = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); + } + else + { + /* The object isn't a volume */ + + /* Is the object a file or a directory? */ + pb.dirInfo.ioNamePtr = tempSpec.name; + pb.dirInfo.ioVRefNum = tempSpec.vRefNum; + pb.dirInfo.ioDrDirID = tempSpec.parID; + pb.dirInfo.ioFDirIndex = 0; + result = PBGetCatInfoSync(&pb); + /* Allow file/directory name at end of path to not exist. */ + realResult = result; + if ( (result == noErr) || (result == fnfErr) ) + { + /* if the object is a directory, append a colon so full pathname + ends with colon */ + if ( (result == noErr) && (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0 ) + { + ++tempSpec.name[0]; + tempSpec.name[tempSpec.name[0]] = ':'; + } + + /* Put the object name in first */ + result = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); + if ( result == noErr ) + { + /* Get the ancestor directory names */ + pb.dirInfo.ioNamePtr = tempSpec.name; + pb.dirInfo.ioVRefNum = tempSpec.vRefNum; + pb.dirInfo.ioDrParID = tempSpec.parID; + do /* loop until we have an error or find the root directory */ + { + pb.dirInfo.ioFDirIndex = -1; + pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID; + result = PBGetCatInfoSync(&pb); + if ( result == noErr ) + { + /* Append colon to directory name */ + ++tempSpec.name[0]; + tempSpec.name[tempSpec.name[0]] = ':'; + + /* Add directory name to beginning of fullPath */ + (void) Munger(*fullPath, 0, NULL, 0, &tempSpec.name[1], + tempSpec.name[0]); + result = MemError(); + } + } while ( (result == noErr) && (pb.dirInfo.ioDrDirID != fsRtDirID) ); + } + } + } + if ( result == noErr ) + { + /* Return the length */ + *fullPathLength = InlineGetHandleSize(*fullPath); + result = realResult; /* return realResult in case it was fnfErr */ + } + else + { + /* Dispose of the handle and return NULL and zero length */ + if ( *fullPath != NULL ) + { + DisposeHandle(*fullPath); + } + *fullPath = NULL; + *fullPathLength = 0; + } + + return ( result ); +} + + + +/*****************************************************************************/ + +pascal OSErr FSpLocationFromFullPath(short fullPathLength, + const void *fullPath, + FSSpec *spec) +{ + AliasHandle alias; + OSErr result; + Boolean wasChanged; + Str32 nullString; + + /* Create a minimal alias from the full pathname */ + nullString[0] = 0; /* null string to indicate no zone or server name */ + result = NewAliasMinimalFromFullPath(fullPathLength, fullPath, nullString, + nullString, &alias); + + if ( result == noErr ) + { + /* Let the Alias Manager resolve the alias. */ + result = ResolveAlias(NULL, alias, spec, &wasChanged); + + DisposeHandle((Handle)alias); /* Free up memory used */ + } + + return ( result ); +} + + + +/*****************************************************************************/ + +pascal OSErr GetFullPath(short vRefNum, + long dirID, + ConstStr255Param name, + short *fullPathLength, + Handle *fullPath) +{ + OSErr result; + FSSpec spec; + + *fullPathLength = 0; + *fullPath = NULL; + + result = FSMakeFSSpecCompat(vRefNum, dirID, name, &spec); + if ( (result == noErr) || (result == fnfErr) ) + { + result = FSpGetFullPath(&spec, fullPathLength, fullPath); + } + + return ( result ); +} + + + +/*****************************************************************************/ + +pascal OSErr ChangeCreatorType(short vRefNum, + long dirID, + ConstStr255Param name, + OSType creator, + OSType fileType) +{ + CInfoPBRec pb; + OSErr error; + short realVRefNum; + long parID; + + pb.hFileInfo.ioNamePtr = (StringPtr)name; + pb.hFileInfo.ioVRefNum = vRefNum; + pb.hFileInfo.ioDirID = dirID; + pb.hFileInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */ + error = PBGetCatInfoSync(&pb); + if ( error == noErr ) + { + if ( (pb.hFileInfo.ioFlAttrib & ioDirMask) == 0 ) /* if file */ + { /* save parent dirID for BumpDate call */ + parID = pb.hFileInfo.ioFlParID; + + /* If creator not 0x00000000, change creator */ + if ( creator != (OSType)0x00000000 ) + { + pb.hFileInfo.ioFlFndrInfo.fdCreator = creator; + } + + /* If fileType not 0x00000000, change fileType */ + if ( fileType != (OSType)0x00000000 ) + { + pb.hFileInfo.ioFlFndrInfo.fdType = fileType; + } + + pb.hFileInfo.ioDirID = dirID; + error = PBSetCatInfoSync(&pb); /* now, save the new information + back to disk */ + + if ( (error == noErr) && (parID != fsRtParID) ) /* can't + bump fsRtParID */ + { + /* get the real vRefNum in case a full pathname was passed */ + error = DetermineVRefNum(name, vRefNum, &realVRefNum); + if ( error == noErr ) + { + error = BumpDate(realVRefNum, parID, NULL); + /* and bump the parent directory's mod date to wake + up the Finder */ + /* to the change we just made */ + } + } + } + else + { + /* it was a directory, not a file */ + error = notAFileErr; + } + } + + return ( error ); +} + +/*****************************************************************************/ + +pascal OSErr FSpChangeCreatorType(const FSSpec *spec, + OSType creator, + OSType fileType) +{ + return ( ChangeCreatorType(spec->vRefNum, spec->parID, spec->name, + creator, fileType) ); +} + +/*****************************************************************************/ + +pascal OSErr BumpDate(short vRefNum, + long dirID, + ConstStr255Param name) +/* Given a file or directory, change its modification date to the + current date/time. */ +{ + CInfoPBRec pb; + Str31 tempName; + OSErr error; + unsigned long secs; + + /* Protection against File Sharing problem */ + if ( (name == NULL) || (name[0] == 0) ) + { + tempName[0] = 0; + pb.hFileInfo.ioNamePtr = tempName; + pb.hFileInfo.ioFDirIndex = -1; /* use ioDirID */ + } + else + { + pb.hFileInfo.ioNamePtr = (StringPtr)name; + pb.hFileInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */ + } + pb.hFileInfo.ioVRefNum = vRefNum; + pb.hFileInfo.ioDirID = dirID; + error = PBGetCatInfoSync(&pb); + if ( error == noErr ) + { + GetDateTime(&secs); + /* set mod date to current date, or one second into the future + if mod date = current date */ + pb.hFileInfo.ioFlMdDat = + (secs == pb.hFileInfo.ioFlMdDat) ? (++secs) : (secs); + if ( pb.dirInfo.ioNamePtr == tempName ) + { + pb.hFileInfo.ioDirID = pb.hFileInfo.ioFlParID; + } + else + { + pb.hFileInfo.ioDirID = dirID; + } + error = PBSetCatInfoSync(&pb); + } + + return ( error ); +} + +/*****************************************************************************/ + +pascal OSErr FSpBumpDate(const FSSpec *spec) +{ + return ( BumpDate(spec->vRefNum, spec->parID, spec->name) ); +} + + +/*****************************************************************************/ + +pascal OSErr OnLine(FSSpecPtr volumes, + short reqVolCount, + short *actVolCount, + short *volIndex) +{ + HParamBlockRec pb; + OSErr error = noErr; + FSSpec *endVolArray; + + if ( *volIndex > 0 ) + { + *actVolCount = 0; + for ( endVolArray = volumes + reqVolCount; + (volumes < endVolArray) && (error == noErr); ++volumes ) + { + pb.volumeParam.ioNamePtr = (StringPtr) & volumes->name; + pb.volumeParam.ioVolIndex = *volIndex; + error = PBHGetVInfoSync(&pb); + if ( error == noErr ) + { + volumes->parID = fsRtParID; /* the root directory's + parent is 1 */ + volumes->vRefNum = pb.volumeParam.ioVRefNum; + ++*volIndex; + ++*actVolCount; + } + } + } + else + { + error = paramErr; + } + + return ( error ); +} + + +/*****************************************************************************/ + +pascal OSErr DTGetComment(short vRefNum, + long dirID, + ConstStr255Param name, + Str255 comment) +{ + DTPBRec pb; + OSErr error; + short dtRefNum; + Boolean newDTDatabase; + + if (comment != NULL) + { + comment[0] = 0; /* return nothing by default */ + + /* attempt to open the desktop database */ + error = DTOpen(name, vRefNum, &dtRefNum, &newDTDatabase); + if ( error == noErr ) + { + /* There was a desktop database and it's now open */ + + if ( !newDTDatabase ) + { + pb.ioDTRefNum = dtRefNum; + pb.ioNamePtr = (StringPtr)name; + pb.ioDirID = dirID; + pb.ioDTBuffer = (Ptr)&comment[1]; + /* + ** IMPORTANT NOTE #1: Inside Macintosh says that comments + ** are up to 200 characters. While that may be correct for + ** the HFS file system's Desktop Manager, other file + ** systems (such as Apple Photo Access) return up to + ** 255 characters. Make sure the comment buffer is a Str255 + ** or you'll regret it. + ** + ** IMPORTANT NOTE #2: Although Inside Macintosh doesn't + ** mention it, ioDTReqCount is a input field to + ** PBDTGetCommentSync. Some file systems (like HFS) ignore + ** ioDTReqCount and always return the full comment -- + ** others (like AppleShare) respect ioDTReqCount and only + ** return up to ioDTReqCount characters of the comment. + */ + pb.ioDTReqCount = sizeof(Str255) - 1; + error = PBDTGetCommentSync(&pb); + if (error == noErr) + { + comment[0] = (unsigned char)pb.ioDTActCount; + } + } + } + else + { + /* There is no desktop database - try the Desktop file */ + error = GetCommentFromDesktopFile(vRefNum, dirID, name, comment); + if ( error != noErr ) + { + error = afpItemNotFound; /* return an expected error */ + } + } + } + else + { + error = paramErr; + } + + return (error); +} + +/*****************************************************************************/ + +pascal OSErr FSpDTGetComment(const FSSpec *spec, + Str255 comment) +{ + return (DTGetComment(spec->vRefNum, spec->parID, spec->name, comment)); +} + + +/*****************************************************************************/ + +pascal OSErr DTSetComment(short vRefNum, + long dirID, + ConstStr255Param name, + ConstStr255Param comment) +{ + DTPBRec pb; + OSErr error; + short dtRefNum; + Boolean newDTDatabase; + + error = DTOpen(name, vRefNum, &dtRefNum, &newDTDatabase); + if ( error == noErr ) + { + pb.ioDTRefNum = dtRefNum; + pb.ioNamePtr = (StringPtr)name; + pb.ioDirID = dirID; + pb.ioDTBuffer = (Ptr)&comment[1]; + /* Truncate the comment to 200 characters just in case */ + /* some file system doesn't range check */ + if ( comment[0] <= 200 ) + { + pb.ioDTReqCount = comment[0]; + } + else + { + pb.ioDTReqCount = 200; + } + error = PBDTSetCommentSync(&pb); + } + return (error); +} + +/*****************************************************************************/ + +pascal OSErr FSpDTSetComment(const FSSpec *spec, + ConstStr255Param comment) +{ + return (DTSetComment(spec->vRefNum, spec->parID, spec->name, comment)); +} + + +/*****************************************************************************/ + +pascal OSErr DTOpen(ConstStr255Param volName, + short vRefNum, + short *dtRefNum, + Boolean *newDTDatabase) +{ + OSErr error; + GetVolParmsInfoBuffer volParmsInfo; + long infoSize; + DTPBRec pb; + + /* Check for volume Desktop Manager support before calling */ + infoSize = sizeof(GetVolParmsInfoBuffer); + error = HGetVolParms(volName, vRefNum, &volParmsInfo, &infoSize); + if ( error == noErr ) + { + if ( hasDesktopMgr(volParmsInfo) ) + { + pb.ioNamePtr = (StringPtr)volName; + pb.ioVRefNum = vRefNum; + error = PBDTOpenInform(&pb); + /* PBDTOpenInform informs us if the desktop was just created */ + /* by leaving the low bit of ioTagInfo clear (0) */ + *newDTDatabase = ((pb.ioTagInfo & 1L) == 0); + if ( error == paramErr ) + { + error = PBDTGetPath(&pb); + /* PBDTGetPath doesn't tell us if the database is new */ + /* so assume it is not new */ + *newDTDatabase = false; + } + *dtRefNum = pb.ioDTRefNum; + } + else + { + error = paramErr; + } + } + return ( error ); +} + +/*****************************************************************************/ + +/* +** GetCommentFromDesktopFile +** +** Get a file or directory's Finder comment field (if any) from the +** Desktop file's 'FCMT' resources. +*/ +static OSErr GetCommentFromDesktopFile(short vRefNum, + long dirID, + ConstStr255Param name, + Str255 comment) +{ + OSErr error; + short commentID; + short realVRefNum; + Str255 desktopName; + short savedResFile; + short dfRefNum; + StringHandle commentHandle; + + /* Get the comment ID number */ + error = GetCommentID(vRefNum, dirID, name, &commentID); + if ( error == noErr ) + { + if ( commentID != 0 ) /* commentID == 0 means there's no comment */ + { + error = DetermineVRefNum(name, vRefNum, &realVRefNum); + if ( error == noErr ) + { + error = GetDesktopFileName(realVRefNum, desktopName); + if ( error == noErr ) + { + savedResFile = CurResFile(); + /* + ** Open the 'Desktop' file in the root directory. (because + ** opening the resource file could preload unwanted resources, + ** bracket the call with SetResLoad(s)) + */ + SetResLoad(false); + dfRefNum = HOpenResFile(realVRefNum, fsRtDirID, desktopName, + fsRdPerm); + SetResLoad(true); + + if ( dfRefNum != -1) + { + /* Get the comment resource */ + commentHandle = (StringHandle)Get1Resource(kFCMTResType, + commentID); + if ( commentHandle != NULL ) + { + if ( InlineGetHandleSize((Handle)commentHandle) > 0 ) + { + BlockMoveData(*commentHandle, comment, + *commentHandle[0] + 1); + } + else + { /* no comment available */ + error = afpItemNotFound; + } + } + else + { /* no comment available */ + error = afpItemNotFound; + } + + /* restore the resource chain and close + the Desktop file */ + UseResFile(savedResFile); + CloseResFile(dfRefNum); + } + else + { + error = afpItemNotFound; + } + } + else + { + error = afpItemNotFound; + } + } + } + else + { + error = afpItemNotFound; /* no comment available */ + } + } + + return ( error ); +} + +/*****************************************************************************/ + +pascal OSErr HGetVolParms(ConstStr255Param volName, + short vRefNum, + GetVolParmsInfoBuffer *volParmsInfo, + long *infoSize) +{ + HParamBlockRec pb; + OSErr error; + + pb.ioParam.ioNamePtr = (StringPtr)volName; + pb.ioParam.ioVRefNum = vRefNum; + pb.ioParam.ioBuffer = (Ptr)volParmsInfo; + pb.ioParam.ioReqCount = *infoSize; + error = PBHGetVolParmsSync(&pb); + if ( error == noErr ) + { + *infoSize = pb.ioParam.ioActCount; + } + return ( error ); +} + +/*****************************************************************************/ +/* +** GetCommentID +** +** Get the comment ID number for the Desktop file's 'FCMT' resource ID from +** the file or folders fdComment (frComment) field. +*/ +static OSErr GetCommentID(short vRefNum, + long dirID, + ConstStr255Param name, + short *commentID) +{ + CInfoPBRec pb; + OSErr error; + + error = GetCatInfoNoName(vRefNum, dirID, name, &pb); + *commentID = pb.hFileInfo.ioFlXFndrInfo.fdComment; + return ( error ); +} + +/*****************************************************************************/ + +/* +** GetDesktopFileName +** +** Get the name of the Desktop file. +*/ +static OSErr GetDesktopFileName(short vRefNum, + Str255 desktopName) +{ + OSErr error; + HParamBlockRec pb; + short index; + Boolean found; + + pb.fileParam.ioNamePtr = desktopName; + pb.fileParam.ioVRefNum = vRefNum; + pb.fileParam.ioFVersNum = 0; + index = 1; + found = false; + do + { + pb.fileParam.ioDirID = fsRtDirID; + pb.fileParam.ioFDirIndex = index; + error = PBHGetFInfoSync(&pb); + if ( error == noErr ) + { + if ( (pb.fileParam.ioFlFndrInfo.fdType == 'FNDR') && + (pb.fileParam.ioFlFndrInfo.fdCreator == 'ERIK') ) + { + found = true; + } + } + ++index; + } while ( (error == noErr) && !found ); + + return ( error ); +} + + +/*****************************************************************************/ + +pascal OSErr XGetVInfo(short volReference, + StringPtr volName, + short *vRefNum, + UnsignedWide *freeBytes, + UnsignedWide *totalBytes) +{ + OSErr result; + long response; + XVolumeParam pb; + + /* See if large volume support is available */ + if ( ( Gestalt(gestaltFSAttr, &response) == noErr ) && ((response & (1L << gestaltFSSupports2TBVols)) != 0) ) + { + /* Large volume support is available */ + pb.ioVRefNum = volReference; + pb.ioNamePtr = volName; + pb.ioXVersion = 0; /* this XVolumeParam version (0) */ + pb.ioVolIndex = 0; /* use ioVRefNum only, return volume name */ + result = PBXGetVolInfoSync(&pb); + if ( result == noErr ) + { + /* The volume name was returned in volName (if not NULL) and */ + /* we have the volume's vRefNum and allocation block size */ + *vRefNum = pb.ioVRefNum; + + /* return the freeBytes and totalBytes */ + *totalBytes = pb.ioVTotalBytes; + *freeBytes = pb.ioVFreeBytes; + } + } + else + { + /* No large volume support */ + + /* Use HGetVInfo to get the results */ + result = HGetVInfo(volReference, volName, vRefNum, &freeBytes->lo, &totalBytes->lo); + if ( result == noErr ) + { + /* zero the high longs of totalBytes and freeBytes */ + totalBytes->hi = 0; + freeBytes->hi = 0; + } + } + return ( result ); +} + + + +/*****************************************************************************/ + +pascal OSErr HGetVInfo(short volReference, + StringPtr volName, + short *vRefNum, + unsigned long *freeBytes, + unsigned long *totalBytes) +{ + HParamBlockRec pb; + unsigned long allocationBlockSize; + unsigned short numAllocationBlocks; + unsigned short numFreeBlocks; + VCB *theVCB; + Boolean vcbFound; + OSErr result; + + /* Use the File Manager to get the real vRefNum */ + pb.volumeParam.ioVRefNum = volReference; + pb.volumeParam.ioNamePtr = volName; + pb.volumeParam.ioVolIndex = 0; /* use ioVRefNum only, return volume name */ + result = PBHGetVInfoSync(&pb); + + if ( result == noErr ) + { + /* The volume name was returned in volName (if not NULL) and */ + /* we have the volume's vRefNum and allocation block size */ + *vRefNum = pb.volumeParam.ioVRefNum; + allocationBlockSize = (unsigned long)pb.volumeParam.ioVAlBlkSiz; + + /* System 7.5 (and beyond) pins the number of allocation blocks and */ + /* the number of free allocation blocks returned by PBHGetVInfo to */ + /* a value so that when multiplied by the allocation block size, */ + /* the volume will look like it has $7fffffff bytes or less. This */ + /* was done so older applications that use signed math or that use */ + /* the GetVInfo function (which uses signed math) will continue to work. */ + /* However, the unpinned numbers (which we want) are always available */ + /* in the volume's VCB so we'll get those values from the VCB if possible. */ + + /* Find the volume's VCB */ + vcbFound = false; + theVCB = (VCB *)(GetVCBQHdr()->qHead); + while ( (theVCB != NULL) && !vcbFound ) + { + /* Check VCB signature before using VCB. Don't have to check for */ + /* MFS (0xd2d7) because they can't get big enough to be pinned */ + if ( theVCB->vcbSigWord == 0x4244 ) + { + if ( theVCB->vcbVRefNum == *vRefNum ) + { + vcbFound = true; + } + } + + if ( !vcbFound ) + { + theVCB = (VCB *)(theVCB->qLink); + } + } + + if ( theVCB != NULL ) + { + /* Found a VCB we can use. Get the un-pinned number of allocation blocks */ + /* and the number of free blocks from the VCB. */ + numAllocationBlocks = (unsigned short)theVCB->vcbNmAlBlks; + numFreeBlocks = (unsigned short)theVCB->vcbFreeBks; + } + else + { + /* Didn't find a VCB we can use. Return the number of allocation blocks */ + /* and the number of free blocks returned by PBHGetVInfoSync. */ + numAllocationBlocks = (unsigned short)pb.volumeParam.ioVNmAlBlks; + numFreeBlocks = (unsigned short)pb.volumeParam.ioVFrBlk; + } + + /* Now, calculate freeBytes and totalBytes using unsigned values */ + *freeBytes = numFreeBlocks * allocationBlockSize; + *totalBytes = numAllocationBlocks * allocationBlockSize; + } + + return ( result ); +} + + +/* +** PBXGetVolInfoSync is the glue code needed to make PBXGetVolInfoSync +** File Manager requests from CFM-based programs. At some point, Apple +** will get around to adding this to the standard libraries you link with +** and you'll get a duplicate symbol link error. At that time, just delete +** this code (or comment it out). +** +** Non-CFM 68K programs don't needs this glue (and won't get it) because +** they instead use the inline assembly glue found in the Files.h interface +** file. +*/ + +#if __WANTPASCALELIMINATION +#undef pascal +#endif + +#if GENERATINGCFM +pascal OSErr PBXGetVolInfoSync(XVolumeParamPtr paramBlock) +{ + enum + { + kXGetVolInfoSelector = 0x0012, /* Selector for XGetVolInfo */ + + uppFSDispatchProcInfo = kRegisterBased + | REGISTER_RESULT_LOCATION(kRegisterD0) + | RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) + | REGISTER_ROUTINE_PARAMETER(1, kRegisterD1, SIZE_CODE(sizeof(long))) /* trap word */ + | REGISTER_ROUTINE_PARAMETER(2, kRegisterD0, SIZE_CODE(sizeof(long))) /* selector */ + | REGISTER_ROUTINE_PARAMETER(3, kRegisterA0, SIZE_CODE(sizeof(XVolumeParamPtr))) + }; + + return ( CallOSTrapUniversalProc(NGetTrapAddress(_FSDispatch, OSTrap), + uppFSDispatchProcInfo, + _FSDispatch, + kXGetVolInfoSelector, + paramBlock) ); +} +#endif + +#if __WANTPASCALELIMINATION +#define pascal +#endif + +/*****************************************************************************/ + +pascal OSErr GetDirName(short vRefNum, + long dirID, + Str31 name) +{ + CInfoPBRec pb; + OSErr error; + + if ( name != NULL ) + { + pb.dirInfo.ioNamePtr = name; + pb.dirInfo.ioVRefNum = vRefNum; + pb.dirInfo.ioDrDirID = dirID; + pb.dirInfo.ioFDirIndex = -1; /* get information about ioDirID */ + error = PBGetCatInfoSync(&pb); + } + else + { + error = paramErr; + } + + return ( error ); +} + + +/*****************************************************************************/ + +pascal OSErr GetVolFileSystemID(ConstStr255Param pathname, + short vRefNum, + short *fileSystemID) +{ + HParamBlockRec pb; + OSErr error; + + error = GetVolumeInfoNoName(pathname,vRefNum, &pb); + if ( error == noErr ) + { + *fileSystemID = pb.volumeParam.ioVFSID; + } + + return ( error ); +} + +/*****************************************************************************/ + +pascal OSErr GetDInfo(short vRefNum, + long dirID, + ConstStr255Param name, + DInfo *fndrInfo) +{ + CInfoPBRec pb; + OSErr error; + + error = GetCatInfoNoName(vRefNum, dirID, name, &pb); + if ( error == noErr ) + { + if ( (pb.dirInfo.ioFlAttrib & ioDirMask) != 0 ) + { + /* it's a directory, return the DInfo */ + *fndrInfo = pb.dirInfo.ioDrUsrWds; + } + else + { + /* oops, a file was passed */ + error = dirNFErr; + } + } + + return ( error ); +} + +/*****************************************************************************/ + +pascal OSErr FSpGetDInfo(const FSSpec *spec, + DInfo *fndrInfo) +{ + return ( GetDInfo(spec->vRefNum, spec->parID, spec->name, fndrInfo) ); +} + + diff --git a/macos/source/macstuff.h b/macos/source/macstuff.h new file mode 100644 index 0000000..9e92dce --- /dev/null +++ b/macos/source/macstuff.h @@ -0,0 +1,18 @@ +/* + Copyright (c) 1990-2001 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#ifndef _MACSTUFF_H +#define _MACSTUFF_H 1 + +#include "MoreFilesExtras.h" +#include "MoreDesktopMgr.h" +#include "MoreFiles.h" +#include "FSpCompat.h" +#include "FullPath.h" + +#endif /* _MACSTUFF_H */ diff --git a/macos/source/mactime.c b/macos/source/mactime.c new file mode 100644 index 0000000..af9ad5e --- /dev/null +++ b/macos/source/mactime.c @@ -0,0 +1,451 @@ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* ----------------------------------------------------------------------------- + +The original functions (Metrowerks Codewarrior pro 3.0) gmtime, localtime, +mktime and time do not work correctly. The supplied link library mactime.c +contains replacement functions for them. + + * Caveat: On a Mac, we only know the GMT and DST offsets for + * the current time, not for the time in question. + * Mac has no support for DST handling. + * DST changeover is all manually set by the user. + + +------------------------------------------------------------------------------*/ + +/*****************************************************************************/ +/* Includes */ +/*****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "mactime.h" + + +/* +The MacOS function GetDateTime returns the +number of seconds elapsed since midnight, January 1, 1904. +*/ +const unsigned long MacOS_2_Unix = 2082844800L; + + +/*****************************************************************************/ +/* Macros, typedefs */ +/*****************************************************************************/ + + +#ifndef TEST_TIME_LIB +#define my_gmtime gmtime +#define my_localtime localtime +#define my_mktime mktime +#define my_time time +#endif + + +/*****************************************************************************/ +/* Prototypes */ +/*****************************************************************************/ +/* internal prototypes */ +static void clear_tm(struct tm * tm); +static long GMTDelta(void); +static Boolean DaylightSaving(void); +static time_t GetTimeMac(void); +static time_t Mactime(time_t *timer); +static void normalize(int *i,int *j,int norm); +static struct tm *time2tm(const time_t *timer); +static time_t tm2time(struct tm *tp); + +/* Because serial port and SLIP conflict with ReadXPram calls, + we cache the call here so we don't hang on calling ReadLocation() */ +static void myReadLocation(MachineLocation * loc); + + +/* prototypes for STD lib replacement functions */ +struct tm *my_gmtime(const time_t *t); +struct tm *my_localtime(const time_t *t); +time_t my_mktime(struct tm *tp); +time_t my_time(time_t *t); + + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ + + /* + * Mac file times are based on 1904 Jan 1 00:00 local time, + * not 1970 Jan 1 00:00 UTC. + * So we have to convert the time stamps into UNIX UTC + * compatible values. + */ +time_t MacFtime2UnixFtime(unsigned long macftime) +{ + long UTCoffset; + + GetGMToffsetMac(macftime, &UTCoffset); + MACOS_TO_UNIX(macftime); + macftime -= UTCoffset; + + return macftime; +} + + + /* + * Mac file times are based on 1904 Jan 1 00:00 local time, + * not 1970 Jan 1 00:00 UTC. + * So we have to convert the time stamps into MacOS local + * compatible values. + */ +unsigned long UnixFtime2MacFtime(time_t unxftime) +{ + long UTCoffset; + unsigned long macftime = unxftime; + + UNIX_TO_MACOS(macftime); + GetGMToffsetMac(macftime, &UTCoffset); + macftime += UTCoffset; + + return macftime; +} + + + + + +/* +* This function convert a file-localtime to an another +* file-localtime. +*/ +time_t AdjustForTZmoveMac(unsigned long macloctim, long s_gmtoffs) +{ + time_t MacGMTTime; + long UTCoffset; + + /* convert macloctim into corresponding UTC value */ + MacGMTTime = macloctim - s_gmtoffs; + GetGMToffsetMac(macloctim, &UTCoffset); + + return (MacGMTTime + UTCoffset); +} /* AdjustForTZmove() */ + + + + +/* + * This function calculates the difference between the supplied Mac + * ftime value (local time) and the corresponding UTC time in seconds. + */ +Boolean GetGMToffsetMac(unsigned long mactime, long *UTCoffset) +{ + +mactime = mactime; +/* + * Caveat: On a Mac, we only know the GMT and DST offsets for + * the current time, not for the time in question. + * Mac has no support for DST handling. + * DST changeover is all manually set by the user. + + May be later I can include a support of GMT offset calculation for the + time in question here. +*/ + *UTCoffset = GMTDelta(); + + return true; +} + + + + + + + +/***************************************************************************** + * Standard Library Replacement Functions + * gmtime(), mktime(), localtime(), time() + * + * The unix epoch is used here. + * These functions gmtime(), mktime(), localtime() and time() + * expects and returns unix times. + * + * At midnight Jan. 1, 1970 GMT, the local time was + * midnight Jan. 1, 1970 + GMTDelta(). + * + * + *****************************************************************************/ + + +struct tm *my_gmtime(const time_t *timer) +{ + return time2tm(timer); +} + + + + +struct tm *my_localtime(const time_t *timer) +{ + time_t maclocal; + + maclocal = *timer; + maclocal += GMTDelta(); + + return time2tm(&maclocal); +} + + + + +time_t my_mktime(struct tm *tp) +{ + time_t maclocal; + + maclocal = tm2time(tp); + maclocal -= GMTDelta(); + + return maclocal; +} + + + + + + +time_t my_time(time_t *time) +{ +time_t tmp_time; + +GetDateTime(&tmp_time); + +MACOS_TO_UNIX(tmp_time); + +if (time) + { + *time = tmp_time; + } + +return tmp_time; +} + + + +/*****************************************************************************/ +/* static module level functions +/*****************************************************************************/ + + +/* + * The geographic location and time zone information of a Mac + * are stored in extended parameter RAM. The ReadLocation + * produdure uses the geographic location record, MachineLocation, + * to read the geographic location and time zone information in + * extended parameter RAM. + * + * Because serial port and SLIP conflict with ReadXPram calls, + * we cache the call here. + * + * Caveat: this caching will give the wrong result if a session + * extend across the DST changeover time, but + * this function resets itself every 2 hours. + */ +static void myReadLocation(MachineLocation * loc) +{ + static MachineLocation storedLoc; /* InsideMac, OSUtilities, page 4-20 */ + static time_t first_call = 0, last_call = 86400; + + if ((last_call - first_call) > 7200) + { + GetDateTime(&first_call); + ReadLocation(&storedLoc); + } + + GetDateTime(&last_call); + *loc = storedLoc; +} + + + + +static Boolean DaylightSaving(void) +{ + MachineLocation loc; + unsigned char dlsDelta; + + myReadLocation(&loc); + dlsDelta = loc.u.dlsDelta; + + return (dlsDelta != 0); +} + + + + +/* current local time = GMTDelta() + GMT + GMT = local time - GMTDelta() */ +static long GMTDelta(void) +{ + MachineLocation loc; + long gmtDelta; + + myReadLocation(&loc); + + /* + * On a Mac, the GMT value is in seconds east of GMT. For example, + * San Francisco is at -28,800 seconds (8 hours * 3600 seconds per hour) + * east of GMT. The gmtDelta field is a 3-byte value contained in a + * long word, so you must take care to get it properly. + */ + gmtDelta = loc.u.gmtDelta & 0x00FFFFFF; + if ((gmtDelta & 0x00800000) != 0) + { + gmtDelta |= 0xFF000000; + } + + return gmtDelta; +} + + + +/* This routine simulates stdclib time(), time in seconds since 1.1.1970 + The time is in GMT */ +static time_t GetTimeMac(void) +{ + unsigned long maclocal; + + + /* + * Get the current time expressed as the number of seconds + * elapsed since the Mac epoch, midnight, Jan. 1, 1904 (local time). + * On a Mac, current time accuracy is up to a second. + */ + + GetDateTime(&maclocal); /* Get Mac local time */ + maclocal -= GMTDelta(); /* Get Mac GMT */ + MACOS_TO_UNIX(maclocal); + + return maclocal; /* return unix GMT */ +} + + + + +/* + * clear_tm - sets a broken-down time to the equivalent of 1970/1/1 00:00:00 + */ + +static void clear_tm(struct tm * tm) +{ + tm->tm_sec = 0; + tm->tm_min = 0; + tm->tm_hour = 0; + tm->tm_mday = 1; + tm->tm_mon = 0; + tm->tm_year = 0; + tm->tm_wday = 1; + tm->tm_yday = 0; + tm->tm_isdst = -1; +} + + +static void normalize(int *i,int *j,int norm) +{ + while(*i < 0) + { + *i += norm; + (*j)--; + } + + while(*i >= norm) + { + *i -= norm; + (*j)++; + } +} + + + +/* Returns the GMT times */ +static time_t Mactime(time_t *timer) +{ + time_t t = GetTimeMac(); + + if (timer != NULL) + *timer = t; + + return t; +} + + + + +static struct tm *time2tm(const time_t *timer) +{ + DateTimeRec dtr; + MachineLocation loc; + time_t macLocal = *timer; + + static struct tm statictime; + static const short monthday[12] = + {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; + + UNIX_TO_MACOS(macLocal); + SecondsToDate(macLocal, &dtr); + + statictime.tm_sec = dtr.second; /* second, from 0 to 59 */ + statictime.tm_min = dtr.minute; /* minute, from 0 to 59 */ + statictime.tm_hour = dtr.hour; /* hour, from 0 to 23 */ + statictime.tm_mday = dtr.day; /* day of the month, from 1 to 31 */ + statictime.tm_mon = dtr.month - 1; /* month, 1= January and 12 = December */ + statictime.tm_year = dtr.year - 1900; /* year, ranging from 1904 to 2040 */ + statictime.tm_wday = dtr.dayOfWeek - 1; /* day of the week, 1 = Sun, 7 = Sat */ + + statictime.tm_yday = monthday[statictime.tm_mon] + + statictime.tm_mday - 1; + + if (2 < statictime.tm_mon && !(statictime.tm_year & 3)) + { + ++statictime.tm_yday; + } + + myReadLocation(&loc); + statictime.tm_isdst = DaylightSaving(); + + return(&statictime); +} + + + + + +static time_t tm2time(struct tm *tp) +{ +time_t intMacTime; +DateTimeRec dtr; + + normalize(&tp->tm_sec, &tp->tm_min, 60); + normalize(&tp->tm_min, &tp->tm_hour,60); + normalize(&tp->tm_hour,&tp->tm_mday,24); + normalize(&tp->tm_mon, &tp->tm_year,12); + + dtr.year = tp->tm_year + 1900; /* years since 1900 */ + dtr.month = tp->tm_mon + 1; /* month, 0 = January and 11 = December */ + dtr.day = tp->tm_mday; /* day of the month, from 1 to 31 */ + dtr.hour = tp->tm_hour; /* hour, from 0 to 23 */ + dtr.minute = tp->tm_min; /* minute, from 0 to 59 */ + dtr.second = tp->tm_sec; /* second, from 0 to 59 */ + + DateToSeconds(&dtr, &intMacTime); + + MACOS_TO_UNIX(intMacTime); + + return intMacTime; +} diff --git a/macos/source/mactime.h b/macos/source/mactime.h new file mode 100644 index 0000000..cb76aa4 --- /dev/null +++ b/macos/source/mactime.h @@ -0,0 +1,61 @@ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#ifndef _MACTIME_H_ +#define _MACTIME_H_ +/* ----------------------------------------------------------------------------- + +The original functions (Metrowerks Codewarrior pro 3.0) gmtime, localtime, +mktime and time do not work correctly. The supplied link library mactime.c +contains replacement functions for them. + + * Caveat: On a Mac, we only know the GMT and DST offsets for + * the current time, not for the time in question. + * Mac has no support for DST handling. + * DST changeover is all manually set by the user. + + +------------------------------------------------------------------------------*/ + +#include +#include + +/*****************************************************************************/ +/* Macros, typedefs */ +/*****************************************************************************/ + + + /* + * ARGH. Mac times are based on 1904 Jan 1 00:00, not 1970 Jan 1 00:00. + * So we have to diddle time_t's appropriately: add or subtract 66 years' + * worth of seconds == number of days times 86400 == (66*365 regular days + + * 17 leap days ) * 86400 == (24090 + 17) * 86400 == 2082844800L seconds. + * We hope time_t is an unsigned long (ulg) on the Macintosh... + */ +/* +This Offset is only used by MacFileDate_to_UTime() +*/ + +#define MACOS_TO_UNIX(x) (x) -= (unsigned long)MacOS_2_Unix +#define UNIX_TO_MACOS(x) (x) += (unsigned long)MacOS_2_Unix + +/* +The MacOS function GetDateTime returns the +number of seconds elapsed since midnight, January 1, 1904. +*/ +extern const unsigned long MacOS_2_Unix; + + +/* prototypes for public utility functions */ +time_t MacFtime2UnixFtime(unsigned long macftime); +unsigned long UnixFtime2MacFtime(time_t unxftime); +time_t AdjustForTZmoveMac(unsigned long macloctim, long s_gmtoffs); +Boolean GetGMToffsetMac(unsigned long macftime, long *UTCoffset); + + +#endif diff --git a/macos/source/pathname.c b/macos/source/pathname.c new file mode 100644 index 0000000..6bf1003 --- /dev/null +++ b/macos/source/pathname.c @@ -0,0 +1,726 @@ +/* + Copyright (c) 1990-2003 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/*--------------------------------------------------------------------------- + + pathname.c + + Function dealing with the pathname. Mostly C-string work. + + ---------------------------------------------------------------------------*/ + +/*****************************************************************************/ +/* Includes */ +/*****************************************************************************/ + +#include +#include +#include +#include + +#include "pathname.h" +#include "helpers.h" +#include "macstuff.h" + + +/*****************************************************************************/ +/* Global Vars */ +/*****************************************************************************/ + +const char ResourceMark[] = "XtraStuf.mac:"; /* see also macos.c */ + + +#include "zip.h" + + + + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ + + +/* + *---------------------------------------------------------------------- + * + * FSpFindFolder -- + * + * This function is a version of the FindFolder function that + * returns the result as a FSSpec rather than a vRefNum and dirID. + * + * Results: + * Results will be simaler to that of the FindFolder function. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +OSErr +FSpFindFolder( + short vRefNum, /* Volume reference number. */ + OSType folderType, /* Folder type taken by FindFolder. */ + Boolean createFolder, /* Should we create it if non-existant. */ + FSSpec *spec) /* Pointer to resulting directory. */ +{ + short foundVRefNum; + long foundDirID; + OSErr err; + + err = FindFolder(vRefNum, folderType, createFolder, + &foundVRefNum, &foundDirID); + if (err != noErr) { + return err; + } + + err = FSMakeFSSpecCompat(foundVRefNum, foundDirID, "\p", spec); + return err; +} + + +/* +** return volumename from pathname +** +*/ + +unsigned short GetVolumeFromPath(const char *FullPath, char *VolumeName) +{ +const char *VolEnd, *tmpPtr1; +char *tmpPtr2 = VolumeName; + +AssertStr(FullPath,"GetVolumeFromPath") + +for (VolEnd = FullPath; *VolEnd != '\0' && *VolEnd != ':'; VolEnd++) + ; +if (*VolEnd == '\0') return 0; + +for (tmpPtr1 = FullPath; tmpPtr1 != VolEnd;) + { + *tmpPtr2++ = *tmpPtr1++; + } + +*tmpPtr2 = '\0'; + +return (unsigned short) strlen(VolumeName); +} + + + +/***********************************/ +/* Function FindNewExtractFolder() */ +/***********************************/ + +char *FindNewExtractFolder(char *ExtractPath, Boolean uniqueFolder) +{ +char buffer[NAME_MAX], *tmpPtr, *namePtr; +char *last_dotpos = ExtractPath; +short count = 0, folderCount = 0; +OSErr err; +FSSpec Spec; +long theDirID; +Boolean isDirectory; +unsigned short namelen, pathlen = strlen(ExtractPath); +unsigned long ext_length = 0; +unsigned long num_to_cut = 0; +long firstpart_length = pathlen; + +AssertStr(ExtractPath,"FindNewExtractFolder ExtractPath == NULL") + +for (tmpPtr = ExtractPath; *tmpPtr; tmpPtr++) + if (*tmpPtr == ':') + { + folderCount++; + namePtr = tmpPtr; + } + +if (folderCount > 1) { + namelen = strlen(namePtr); +} else { + namelen = strlen(ExtractPath); +} + +if (uniqueFolder) { + for (count = 0; count < 99; count++) + { + memset(buffer,0,sizeof(buffer)); + + if (namelen >= 28) + ExtractPath[pathlen-2] = 0x0; + else + ExtractPath[pathlen-1] = 0x0; + + sprintf(buffer,"%s%d",ExtractPath,count); + GetCompletePath(ExtractPath, buffer, &Spec,&err); + err = FSpGetDirectoryID(&Spec, &theDirID, &isDirectory); + if (err == -43) break; + } +} else { + /* Look for the last extension pos */ + for (tmpPtr = ExtractPath; *tmpPtr; tmpPtr++) + if (*tmpPtr == '.') last_dotpos = tmpPtr; + + ext_length = strlen(last_dotpos); + + if (ext_length < 6) { /* up to 5 chars are treated as a */ + /* normal extension like ".html" or ".class" */ + int nameLength = last_dotpos - ExtractPath; + if (nameLength > 1) { + ExtractPath[nameLength] = 0x0; + } else { + ExtractPath[pathlen-1] = 0x0; + } + } else { + ExtractPath[pathlen-1] = 0x0; + } + + GetCompletePath(ExtractPath, ExtractPath, &Spec,&err); +} + +/* Foldernames must always end with a colon */ +sstrcat(ExtractPath,":"); +return ExtractPath; +} + + + +/* +** creates an archive file name +** +*/ + +void createArchiveName(char *thePath) +{ +char *tmpPtr, *namePtr; +short folderCount = 0; +unsigned short namelen, pathlen = strlen(thePath); + +if (thePath[pathlen-1] == ':') thePath[pathlen-1] = 0x0; + +for (tmpPtr = thePath; *tmpPtr; tmpPtr++) + if (*tmpPtr == ':') + { + folderCount++; + namePtr = tmpPtr; + } + +namelen = strlen(namePtr); + + /* we have to eliminate illegal chars: + * The name space for Mac filenames and Zip filenames (unix style names) + * do both include all printable extended-ASCII characters. The only + * difference we have to take care of is the single special character + * used as path delimiter: + * ':' on MacOS and '/' on Unix and '\\' on Dos. + * So, to convert between Mac filenames and Unix filenames without any + * loss of information, we simply interchange ':' and '/'. Additionally, + * we try to convert the coding of the extended-ASCII characters into + * InfoZip's standard ISO 8859-1 codepage table. + */ + MakeCompatibleString(namePtr, '/', '_', '.', '-', -1); + + /* Avoid filenames like: "Archive..zip" */ +if (thePath[pathlen-1] == '.') + { + thePath[pathlen-1] = 0; + } + +if (folderCount >= 1) + { /* path contains at least one folder */ + + if (namelen >= 28) + { + pathlen = pathlen-4; + } + + thePath[pathlen] = '.'; + thePath[pathlen+1] = 'z'; + thePath[pathlen+2] = 'i'; + thePath[pathlen+3] = 'p'; + thePath[pathlen+4] = 0x0; + return; + } +else + { /* path contains no folder */ + FindDesktopFolder(thePath); + createArchiveName(thePath); + } +} + + + +/* +** finds the desktop-folder on a volume with +** largest amount of free-space. +*/ + +void FindDesktopFolder(char *Path) +{ +char buffer[255]; +FSSpec volumes[50]; /* 50 Volumes should be enough */ +short actVolCount, volIndex = 1, VolCount = 0; +OSErr err; +short i, foundVRefNum; +FSSpec spec; +UInt64 freeBytes; +UInt64 totalBytes; +UInt64 MaxFreeBytes; + +err = OnLine(volumes, 50, &actVolCount, &volIndex); +printerr("OnLine:", (err != -35) && (err != 0), err, __LINE__, __FILE__, ""); + +MaxFreeBytes = 0; + +for (i=0; i < actVolCount; i++) + { + XGetVInfo(volumes[i].vRefNum, + volumes[i].name, + &volumes[i].vRefNum, + &freeBytes, + &totalBytes); + + if (MaxFreeBytes < freeBytes) { + MaxFreeBytes = freeBytes; + foundVRefNum = volumes[i].vRefNum; + } + + if ((freeBytes == 0) && (MaxFreeBytes < freeBytes)) { + MaxFreeBytes = freeBytes; + foundVRefNum = volumes[i].vRefNum; + } + +} + + FSpFindFolder(foundVRefNum, kDesktopFolderType, + kDontCreateFolder,&spec); + + GetFullPathFromSpec(buffer, &spec , &err); + sstrcat(buffer,Path); + sstrcpy(Path,buffer); +} + + +/* +** return the path without the filename +** +*/ + +char *TruncFilename(char *DirPath, const char *FilePath) +{ +char *tmpPtr; +char *dirPtr = NULL; + +AssertStr(DirPath,"TruncFilename") +Assert_it(Spec,"TruncFilename","") + +sstrcpy(DirPath, FilePath); + +for (tmpPtr = DirPath; *tmpPtr; tmpPtr++) + if (*tmpPtr == ':') + dirPtr = tmpPtr; + +if (dirPtr) + *++dirPtr = '\0'; +else + printerr("TruncFilename: FilePath has no Folders", -1, + -1, __LINE__, __FILE__, FilePath); + +return DirPath; +} + + + +/* +** return only filename +** +*/ + +char *GetFilename(char *FileName, const char *FilePath) +{ +const char *tmpPtr; +const char *dirPtr = NULL; + +Assert_it(FileName,"GetFilename","") +Assert_it(FilePath,"GetFilename","") + +for (tmpPtr = FilePath; *tmpPtr; tmpPtr++) + { + if (*tmpPtr == ':') + { + dirPtr = tmpPtr; + } + } + +if (dirPtr) + { + ++dirPtr; /* jump over the ':' */ + } +else + { + return strcpy(FileName, FilePath); /* FilePath has no Folders */ + } + +return strcpy(FileName, dirPtr); +} + + + +/* +** return fullpathname from folder/dir-id +** +*/ + +char *GetFullPathFromID(char *CompletePath, short vRefNum, long dirID, + ConstStr255Param name, OSErr *err) +{ +FSSpec spec; + + *err = FSMakeFSSpecCompat(vRefNum, dirID, name, &spec); + printerr("FSMakeFSSpecCompat:", (*err != -43) && (*err != 0), *err, + __LINE__, __FILE__, ""); + if ( (*err == noErr) || (*err == fnfErr) ) + { + return GetFullPathFromSpec(CompletePath, &spec, err); + } + +return NULL; +} + + + +/* +** convert real-filename to archive-filename +** +*/ + +char *Real2RfDfFilen(char *RfDfFilen, const char *RealPath, + short CurrentFork, short MacZipMode, Boolean DataForkOnly) +{ + +AssertStr(RealPath,"Real2RfDfFilen") +AssertStr(RfDfFilen,"Real2RfDfFilen") + +if (DataForkOnly) /* make no changes */ + { + return sstrcpy(RfDfFilen, RealPath); + } + +switch (MacZipMode) + { + case JohnnyLee_EF: + { + sstrcpy(RfDfFilen, RealPath); + if (CurrentFork == DataFork) /* data-fork */ + return sstrcat(RfDfFilen, "d"); + if (CurrentFork == ResourceFork) /* resource-fork */ + return sstrcat(RfDfFilen, "r"); + break; + } + + case NewZipMode_EF: + { + switch (CurrentFork) + { + case DataFork: + { + sstrcpy(RfDfFilen, RealPath); + return RfDfFilen; /* data-fork */ + break; + } + case ResourceFork: + { + sstrcpy(RfDfFilen, ResourceMark); + sstrcat(RfDfFilen, RealPath); /* resource-fork */ + return RfDfFilen; + break; + } + default: + { + printerr("Real2RfDfFilen:", -1, -1, + __LINE__, __FILE__, RealPath); + return NULL; /* function should never reach this point */ + } + } + break; + } + default: + { + printerr("Real2RfDfFilen:", -1, -1, __LINE__, __FILE__, RealPath); + return NULL; /* function should never reach this point */ + } + } + +printerr("Real2RfDfFilen:", -1, -1, __LINE__, __FILE__, RealPath); +return NULL; /* function should never come reach this point */ +} + + + +/* +** convert archive-filename into a real filename +** +*/ + +char *RfDfFilen2Real(char *RealFn, const char *RfDfFilen, short MacZipMode, + Boolean DataForkOnly, short *CurrentFork) +{ +short length; +int result; + +AssertStr(RfDfFilen,"RfDfFilen2Real") + +if (DataForkOnly || + (MacZipMode == UnKnown_EF) || + (MacZipMode < JohnnyLee_EF)) + { + *CurrentFork = DataFork; + return sstrcpy(RealFn,RfDfFilen); + } + +result = strncmp(RfDfFilen, ResourceMark, sizeof(ResourceMark)-2); +if (result == 0) + { + MacZipMode = NewZipMode_EF; + } + +switch (MacZipMode) + { + case JohnnyLee_EF: + { + sstrcpy(RealFn, RfDfFilen); + length = strlen(RealFn); /* determine Fork type */ + if (RealFn[length-1] == 'd') *CurrentFork = DataFork; + else *CurrentFork = ResourceFork; + RealFn[length-1] = '\0'; /* simply cut one char */ + return RealFn; + break; + } + + case NewZipMode_EF: + { /* determine Fork type */ + result = strncmp(RfDfFilen, ResourceMark, sizeof(ResourceMark)-2); + if (result != 0) + { + *CurrentFork = DataFork; + sstrcpy(RealFn, RfDfFilen); + return RealFn; /* data-fork */ + } + else + { + *CurrentFork = ResourceFork; + if (strlen(RfDfFilen) > (sizeof(ResourceMark) - 1)) + { + sstrcpy(RealFn, &RfDfFilen[sizeof(ResourceMark)-1]); + } + else RealFn[0] = '\0'; + return RealFn; /* resource-fork */ + } + break; + } + default: + { + *CurrentFork = NoFork; + printerr("RfDfFilen2Real():", -1, MacZipMode, + __LINE__, __FILE__, RfDfFilen); + return NULL; /* function should never reach this point */ + } + } + +printerr("RfDfFilen2Real():", -1, MacZipMode, __LINE__, __FILE__, RfDfFilen); +return NULL; /* function should never reach this point */ +} + + + +/* +** return the applications name (argv[0]) +** +*/ + +char *GetAppName(void) +{ +ProcessSerialNumber psn; +static Str255 AppName; +ProcessInfoRec pinfo; +OSErr err; + +GetCurrentProcess(&psn); +pinfo.processName = AppName; +pinfo.processInfoLength = sizeof(pinfo); +pinfo.processAppSpec = NULL; + +err = GetProcessInformation(&psn,&pinfo); +AppName[AppName[0]+1] = 0x00; + +return (char *)&AppName[1]; +} + + + +/* +** return fullpathname from FSSpec +** +*/ + +char *GetFullPathFromSpec(char *FullPath, FSSpec *Spec, OSErr *err) +{ +Handle hFullPath; +short len; + +Assert_it(Spec,"GetFullPathFromSpec","") + +*err = FSpGetFullPath(Spec, &len, &hFullPath); +printerr("FSpGetFullPath:", (*err != -43) && (*err != 0), *err, + __LINE__, __FILE__, ""); + +memmove(FullPath, (Handle) *hFullPath, len); +FullPath[len] = '\0'; /* make c-string */ + +DisposeHandle((Handle)hFullPath); /* we don't need it any more */ + +printerr("Warning path length exceeds limit: ", len >= NAME_MAX, len, + __LINE__, __FILE__, " chars "); + +return FullPath; +} + + + + +/* +* This function expands a given partial path to a complete path. +* Path expansions are relative to the running app. +* This function follows the notation: +* 1. relative path: +* a: ":subfolder:filename" -> ":current folder:subfolder:filename" +* b: "::folder2:filename" -> folder2 is beside the current +* folder on the same level +* c: "filename" -> in current folder +* +* An absolute path will be returned. + +The following characteristics of Macintosh pathnames should be noted: + + A full pathname never begins with a colon, but must contain at + least one colon. + A partial pathname always begins with a colon separator except in + the case where the file partial pathname is a simple file or + directory name. + Single trailing separator colons in full or partial pathnames are + ignored except in the case of full pathnames to volumes. + In full pathnames to volumes, the trailing separator colon is required. + Consecutive separator colons can be used to ascend a level from a + directory to its parent directory. Two consecutive separator colons + will ascend one level, three consecutive separator colons will ascend + two levels, and so on. Ascending can only occur from a directory; + not a file. +*/ + +char *GetCompletePath(char *CompletePath, const char *name, FSSpec *Spec, + OSErr *err) +{ +Boolean hasDirName = false; +char currentdir[NAME_MAX]; +char *tmpPtr; +unsigned short pathlen; + +AssertStr(name,"GetCompletePath") +Assert_it(Spec,"GetCompletePath","") +Assert_it((CompletePath != name),"GetCompletePath","") + +for (tmpPtr = name; *tmpPtr; tmpPtr++) + if (*tmpPtr == ':') hasDirName = true; + +if (name[0] != ':') /* case c: path including volume name or only filename */ + { + if (hasDirName) + { /* okey, starts with volume name, so it must be a complete path */ + sstrcpy(CompletePath, name); + } + else + { /* only filename: add cwd and return */ + getcwd(currentdir, NAME_MAX); + sstrcat(currentdir, name); + sstrcpy(CompletePath, currentdir); + } + } +else if (name[1] == ':') /* it's case b: "::folder2:filename" */ + { + printerr("GetCompletePath ", -1, *err, __LINE__, __FILE__, "not implemented"); + /* it's not yet implemented; do we really need this case ?*/ + return NULL; + } +else /* it's case a: ":subfolder:filename" */ + { + getcwd(CompletePath, NAME_MAX); /* we don't need a second colon */ + CompletePath[strlen(CompletePath)-1] = '\0'; + sstrcat(CompletePath, name); + } + +pathlen = strlen(CompletePath); +*err = FSpLocationFromFullPath(pathlen, CompletePath, Spec); + +return CompletePath; +} + + + +char *MakeFilenameShorter(const char *LongFilename) +{ +static char filename[35]; /* contents should be never longer than 32 chars */ +static unsigned char Num = 0; /* change the number for every call */ + /* this var will rollover without a problem */ +char tempLongFilename[1024], charnum[5]; +char *last_dotpos = tempLongFilename; +unsigned long full_length = strlen(LongFilename); +unsigned long ext_length = 0; +unsigned long num_to_cut = 0; +long firstpart_length; +char *tmpPtr; +short MaxLength = 31; + +if (full_length <= MaxLength) /* filename is not long */ + { + return strcpy(filename,LongFilename); + } + +Num++; +strcpy(tempLongFilename,LongFilename); + +/* Look for the last extension pos */ +for (tmpPtr = tempLongFilename; *tmpPtr; tmpPtr++) + if (*tmpPtr == '.') last_dotpos = tmpPtr; + +ext_length = strlen(last_dotpos); +firstpart_length = last_dotpos - tempLongFilename; + +if (ext_length > 6) /* up to 5 chars are treated as a */ + { /* normal extension like ".html" or ".class" */ + firstpart_length = 0; + } + +num_to_cut = full_length - MaxLength; + +/* number the files to make the names unique */ +sprintf(charnum,"~%x", Num); +num_to_cut += strlen(charnum); + +if (firstpart_length == 0) + { + firstpart_length = full_length; + tempLongFilename[firstpart_length - num_to_cut] = 0; + sprintf(filename,"%s%s", tempLongFilename, charnum); + } +else + { + tempLongFilename[firstpart_length - num_to_cut] = 0; + sprintf(filename,"%s%s%s", tempLongFilename, charnum, last_dotpos); + } + +return filename; +} diff --git a/macos/source/pathname.h b/macos/source/pathname.h new file mode 100644 index 0000000..1a39ed3 --- /dev/null +++ b/macos/source/pathname.h @@ -0,0 +1,64 @@ +/* + Copyright (c) 1990-2001 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#ifndef PATHNAME_H +#define PATHNAME_H 1 + + +char *StripPartialDir(char *CompletePath, + const char *PartialPath, const char *FullPath); + +char *Real2RfDfFilen(char *RfDfFilen, const char *RealPath, short CurrentFork, + short MacZipMode, Boolean DataForkOnly); +char *RfDfFilen2Real(char *RealFn, const char *RfDfFilen, short MacZipMode, + Boolean DataForkOnly, short *CurrentFork); + +unsigned short GetVolumeFromPath(const char *FullPath, char *VolumeName); +char *GetCompletePath(char *CompletePath, const char *name, FSSpec *Spec, + OSErr *err); +char *TruncFilename(char *DirPath, const char *FilePath); +char *GetFilename(char *CompletePath, const char *name); +char *GetFullPathFromSpec(char *CompletePath, FSSpec *Spec, OSErr *err); +char *GetFullPathFromID(char *CompletePath, short vRefNum, long dirID, + ConstStr255Param name, OSErr *err); + +char *GetAppName(void); +void createArchiveName(char *Path); +void FindDesktopFolder(char *Path); +char *FindNewExtractFolder(char *ExtractPath, Boolean uniqueFolder); +OSErr FSpFindFolder( + short vRefNum, /* Volume reference number. */ + OSType folderType, /* Folder type taken by FindFolder. */ + Boolean createFolder, /* Should we create it if non-existant. */ + FSSpec *spec); /* Pointer to resulting directory. */ + +char *MakeFilenameShorter(const char *LongFilename); + +/* +Rule: UnKnown_EF should always be zero. + JohnnyLee_EF, NewZipMode_EF should always greater than all + other definitions +*/ +#define UnKnown_EF 0 +#define TomBrownZipIt1_EF 10 +#define TomBrownZipIt2_EF 20 +#define JohnnyLee_EF 30 +#define NewZipMode_EF 40 + + + +#define ResourceFork -1 +#define DataFork 1 +#define NoFork 0 + + +#ifndef NAME_MAX +#define NAME_MAX 1024 +#endif + +#endif /* PATHNAME_H */ diff --git a/macos/source/recurse.c b/macos/source/recurse.c new file mode 100644 index 0000000..e87db3c --- /dev/null +++ b/macos/source/recurse.c @@ -0,0 +1,442 @@ +/* +These functions are based on Jim Luther's IterateDirectory() found in MoreFiles +However, it's heavily modified by Dirk Haase +*/ + +/* +** IterateDirectory: File Manager directory iterator routines. +** +** by Jim Luther +** +** File: IterateDirectory.c +** +** Copyright (c) 1995-1998 Jim Luther and Apple Computer, Inc. +** All rights reserved. +** +** You may incorporate this sample code into your applications without +** restriction, though the sample code has been provided "AS IS" and the +** responsibility for its operation is 100% yours. +** +** IterateDirectory is designed to drop into the MoreFiles sample code +** library I wrote while in Apple Developer Technical Support +*/ + +/*****************************************************************************/ +/* Includes */ +/*****************************************************************************/ + +#include +#include +#include +#include +#include + + +#include "zip.h" +#include "macstuff.h" +#include "helpers.h" +#include "recurse.h" +#include "macglob.h" +#include "pathname.h" + + + + +/*****************************************************************************/ +/* Macros, typedefs */ +/*****************************************************************************/ + +/* The RecurseGlobals structure is used to minimize the amount of +** stack space used when recursively calling RecurseDirectoryLevel +** and to hold global information that might be needed at any time. +*/ +struct RecurseGlobals +{ + short vRefNum; + CInfoPBRec cPB; /* the parameter block used for + PBGetCatInfo calls */ + unsigned char *itemName; /* the name of the current item */ + char *FullPath; + short FullPathLen; + OSErr result; /* temporary holder of results - + saves 2 bytes of stack each level */ + Boolean quitFlag; /* set to true if filter wants to + kill interation */ + unsigned short maxLevels; /* Maximum levels to + iterate through */ + unsigned short currentLevel; /* The current level + IterateLevel is on */ +}; + +typedef struct RecurseGlobals RecurseGlobals; +typedef RecurseGlobals *RecurseGlobalsPtr; + + +/*****************************************************************************/ +/* Global Vars */ +/*****************************************************************************/ + +extern MacZipGlobals MacZip; +extern const char ResourceMark[13]; /* "XtraStuf.mac:" var is initialized in file pathname.c */ +extern int extra_fields; /* do not create extra fields if false */ + +static RecurseGlobals theGlobals; + +static unsigned long DirLevels = 0; +static char *buffer; +extern int verbose; /* 1=report oddities in zip file structure */ + +/*****************************************************************************/ +/* Prototypes */ +/*****************************************************************************/ + +int procname(char *filename, int caseflag); +int MatchWild( char *pPat, char *pStr, int case_sens); +Boolean IsZipFile(char *name); + +static void RecurseDirectoryLevel(long DirID, RecurseGlobals *Globals); +static Boolean isRegularItem( RecurseGlobals *Globals); +static void ProcessFiles(RecurseGlobals *Globals, + Boolean hasDataFork, Boolean hasResourceFork); +static void ProcessDirectory(RecurseGlobals *Globals, + Boolean IncludeItem, long DirID); +static void ProcessItem(RecurseGlobals *Globals, long DirID); + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ + +static void RecurseDirectoryLevel(long DirID, RecurseGlobals *Globals) +{ +char buffer2[23]; + + /* if maxLevels is zero, we aren't checking levels */ + if ( (Globals->maxLevels == 0) || + /* if currentLevel < maxLevels, look at this level */ + (Globals->currentLevel < Globals->maxLevels) ) + { + short index = 1; + + ++Globals->currentLevel; /* go to next level */ + if (DirLevels < Globals->currentLevel) DirLevels = Globals->currentLevel; + sprintf(buffer2,"Globals->currentLevel: %d",Globals->currentLevel); + + do + { /* Isn't C great... What I'd give for a "WITH + theGlobals DO" about now... */ + + /* Get next source item at the current directory level */ + Globals->cPB.dirInfo.ioFDirIndex = index; + Globals->cPB.dirInfo.ioDrDirID = DirID; + Globals->result = PBGetCatInfoSync((CInfoPBPtr)&Globals->cPB); + + ShowCounter(false); + + if ( Globals->result == noErr ) + { + ProcessItem(Globals, DirID); + } /* if ( Globals->result == noErr ) */ + + ++index; /* prepare to get next item */ + /* time to fall back a level? */ + } while ( (Globals->result == noErr) && (!Globals->quitFlag) ); + + if ( (Globals->result == fnfErr) || /* fnfErr is OK - + it only means we hit + the end of this level */ + (Globals->result == afpAccessDenied) ) /* afpAccessDenied is OK, + too - it only means we cannot see inside a directory */ + { + Globals->result = noErr; + } + + --Globals->currentLevel; /* return to previous level as we leave */ + } +} + + + +/*****************************************************************************/ + +pascal OSErr RecurseDirectory(short vRefNum, + long thedirID, + ConstStr255Param name, + unsigned short maxLevels) +{ + OSErr result; + short theVRefNum; + Boolean isDirectory; + long DirID; + + /* Get the real directory ID and make sure it is a directory */ + result = GetDirectoryID(vRefNum, thedirID, name, &DirID, &isDirectory); + if ( result == noErr ) + { + if ( isDirectory == true ) + { + /* Get the real vRefNum */ + result = DetermineVRefNum(name, vRefNum, &theVRefNum); + if ( result == noErr ) + { + /* Set up the globals we need to access from + the recursive routine. */ + theGlobals.cPB.hFileInfo.ioNamePtr = theGlobals.itemName; + theGlobals.cPB.hFileInfo.ioVRefNum = theVRefNum; + theGlobals.itemName[0] = 0; + theGlobals.result = noErr; + theGlobals.quitFlag = false; + theGlobals.maxLevels = maxLevels; + theGlobals.currentLevel = 0; /* start at level 0 */ + + /* Here we go into recursion land... */ + RecurseDirectoryLevel(DirID, &theGlobals); + + result = theGlobals.result; /* set the result */ + } + } + else + { + result = dirNFErr; /* a file was passed instead + of a directory */ + } + } + + return ( result ); +} + + + +/*****************************************************************************/ + +pascal OSErr FSpRecurseDirectory(const FSSpec *spec, + unsigned short maxLevels) +{ + OSErr rc; + + theGlobals.vRefNum = spec->vRefNum; + + /* make room for pathnames */ + theGlobals.itemName = (unsigned char *) StrCalloc(NAME_MAX); + theGlobals.FullPath = StrCalloc(NAME_MAX); + buffer = StrCalloc(NAME_MAX); + + + if ((noisy) && (MacZip.DataForkOnly)) + printf("\n Warning: Datafork only \n"); + + /* reset the count to zero */ + ShowCounter(true); + + if (noisy) leftStatusString("Build File List; Items done:"); + if (noisy) printf("\n Collecting Filenames ..."); + rc = RecurseDirectory(spec->vRefNum, spec->parID, spec->name,maxLevels); + printerr("RecurseDirectory:",rc,rc,__LINE__,__FILE__,""); + + if (noisy) printf("\n... done \n\n %6d matched files found \n", + MacZip.FoundFiles); + if (noisy) printf(" %6d folders found in %d Levels \n", + MacZip.FoundDirectories,DirLevels); + + if (MacZip.BytesOfData > (1024*1024)) + if (noisy) printf(" %4.3f MBytes unzipped size\n\n", + (float) MacZip.BytesOfData/(1024*1024)); + else + if (noisy) printf(" %4.3f KBytes unzipped size\n\n", + (float) MacZip.BytesOfData/1024); + + /* free all memory of pathnames */ + theGlobals.itemName = (unsigned char *) StrFree((char *)theGlobals.itemName); + theGlobals.FullPath = StrFree(theGlobals.FullPath); + buffer = StrFree(buffer); + + return rc; +} + + + + +/* +* Return true if filename == zipfile +* After the first match no further check will be done ! +* +*/ +Boolean IsZipFile(char *filen) +{ +static firstMatch = false; + +if (filen == NULL) + firstMatch = false; + +if (!firstMatch) + { + if (stricmp(filen, MacZip.ZipFullPath) == 0) + { + firstMatch = true; + return true; + } + } + +return false; +} + + + +static Boolean isRegularItem( RecurseGlobals *Globals) +{ +Boolean isInvisible = false, + isAlias = false, + isSystem = false; + +isSystem = !((Globals->cPB.hFileInfo.ioFlFndrInfo.fdFlags & + (1 << 12)) == 0 ); +isInvisible = !((Globals->cPB.hFileInfo.ioFlFndrInfo.fdFlags & + (1 << 14)) == 0 ); +isAlias = !((Globals->cPB.hFileInfo.ioFlFndrInfo.fdFlags & + (1 << 15)) == 0); + +if (isAlias == true) + { + return false; + } + +if (MacZip.IncludeInvisible == true) + { + return true; + } + +if ((isSystem == true) || + (isInvisible == true)) + { + return false; + } + +return true; +} + + + + +static void ProcessFiles(RecurseGlobals *Globals, + Boolean hasDataFork, Boolean hasResourceFork) +{ + /* some file statistics */ +MacZip.FoundFiles++; + +if (hasDataFork == true) + { + MacZip.BytesOfData = + Globals->cPB.hFileInfo.ioFlLgLen + + MacZip.BytesOfData; + MacZip.CurrentFork = DataFork; + MacZip.RawCountOfItems++; + + if (MacZip.DataForkOnly == true) + { + procname(Globals->FullPath, false); + hasResourceFork = false; + } + else + { + procname(Real2RfDfFilen(buffer,Globals->FullPath, + DataFork, MacZip.MacZipMode, + MacZip.DataForkOnly), false); + } + } + +if (hasResourceFork == true) + { + MacZip.BytesOfData = + Globals->cPB.hFileInfo.ioFlRLgLen + + MacZip.BytesOfData; + MacZip.CurrentFork = ResourceFork; + MacZip.RawCountOfItems++; + + procname(Real2RfDfFilen(buffer, Globals->FullPath, + ResourceFork, MacZip.MacZipMode, + MacZip.DataForkOnly), false); + } +} + + + + +static void ProcessDirectory(RecurseGlobals *Globals, + Boolean IncludeItem, long DirID) +{ +OSErr rc; + +MacZip.isDirectory = true; + +GetFullPathFromID(Globals->FullPath,Globals->vRefNum, DirID, + Globals->itemName, &rc); + +MacZip.RawCountOfItems++; +MacZip.FoundDirectories++; + +if (MacZip.StoreFoldersAlso) + { + procname(Globals->FullPath, false); + } + + /* We have a directory */ + if ( !Globals->quitFlag && IncludeItem) + { + /* Dive again if the IterateFilterProc didn't say "quit" and dir is + not an alias */ + RecurseDirectoryLevel(Globals->cPB.dirInfo.ioDrDirID, + Globals); + } +} + + + +static void ProcessItem(RecurseGlobals *Globals, long DirID) +{ +OSErr rc; +Boolean IncludeItem = false, hasDataFork = false; +Boolean hasResourceFork = false; + +IncludeItem = isRegularItem(Globals); + +/* Is it a File? */ +if ( (Globals->cPB.hFileInfo.ioFlAttrib & ioDirMask) == 0 ) + { + PToCCpy(Globals->itemName,MacZip.FileName); + MacZip.isDirectory = false; + + hasDataFork = (Globals->cPB.hFileInfo.ioFlLgLen != 0); + hasResourceFork = (Globals->cPB.hFileInfo.ioFlRLgLen != 0); + + /* include also files with zero recource- and data-fork */ + if ((hasDataFork == 0) && (hasResourceFork == 0)) + hasDataFork = true; + + if ((hasDataFork == 0) && + (hasResourceFork != 0) && + (extra_fields == false)) + { + IncludeItem = false; + } + + GetFullPathFromID(Globals->FullPath,Globals->vRefNum, + DirID, Globals->itemName, &rc); + printerr("GetFullPathFromID:",rc,rc,__LINE__, + __FILE__,MacZip.FileName); + + if (IncludeItem && /* don't include the zipfile itself */ + (!IsZipFile(Globals->FullPath)) ) + { + if (MATCH(MacZip.Pattern, MacZip.FileName, false) == true) + { + ProcessFiles(Globals, hasDataFork, hasResourceFork); + } /* if (MatchWild( MacZip.FileName,MacZip.Pattern ) == + true) */ + } /* if (!IsZipFile(Globals->FullPath)) */ + } /* Is it a File? */ + +/* Is it a directory? */ +if ( (Globals->cPB.hFileInfo.ioFlAttrib & ioDirMask) != 0 ) + { + ProcessDirectory(Globals,IncludeItem, DirID); + } /* Is it a directory? */ +} diff --git a/macos/source/recurse.h b/macos/source/recurse.h new file mode 100644 index 0000000..cfbc4b0 --- /dev/null +++ b/macos/source/recurse.h @@ -0,0 +1,129 @@ +/* +** IterateDirectory: File Manager directory iterator routines. +** +** by Jim Luther +** +** File: IterateDirectory.h +** +** Copyright (c) 1995-1998 Jim Luther and Apple Computer, Inc. +** All rights reserved. +** +** You may incorporate this sample code into your applications without +** restriction, though the sample code has been provided "AS IS" and the +** responsibility for its operation is 100% yours. +** +** IterateDirectory is designed to drop into the MoreFiles sample code +** library I wrote while in Apple Developer Technical Support +*/ + +#ifndef __RECURSEDIRECTORY__ +#define __RECURSEDIRECTORY__ + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*****************************************************************************/ + +pascal OSErr RecurseDirectory(short vRefNum, + long dirID, + ConstStr255Param name, + unsigned short maxLevels ); +/* Iterate (scan) through a directory's content. + The IterateDirectory function performs a recursive iteration (scan) of + the specified directory and calls your IterateFilterProc function once + for each file and directory found. + + The maxLevels parameter lets you control how deep the recursion goes. + If maxLevels is 1, IterateDirectory only scans the specified directory; + if maxLevels is 2, IterateDirectory scans the specified directory and + one subdirectory below the specified directory; etc. Set maxLevels to + zero to scan all levels. + + The yourDataPtr parameter can point to whatever data structure you might + want to access from within the IterateFilterProc. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID + specifies a directory that's the object. + maxLevels input: Maximum number of directory levels to scan or + zero to scan all directory levels. + iterateFilter input: A pointer to the routine you want called once + for each file and directory found by + IterateDirectory. + yourDataPtr input: A pointer to whatever data structure you might + want to access from within the IterateFilterProc. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + paramErr -50 No default volume or iterateFilter was NULL + dirNFErr -120 Directory not found or incomplete pathname + or a file was passed instead of a directory + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: RecurseFilterProcPtr, FSpRecurseDirectory +*/ + +/*****************************************************************************/ + +pascal OSErr FSpRecurseDirectory(const FSSpec *spec, + unsigned short maxLevels); +/* Iterate (scan) through a directory's content. + The FSpIterateDirectory function performs a recursive iteration (scan) + of the specified directory and calls your IterateFilterProc function once + for each file and directory found. + + The maxLevels parameter lets you control how deep the recursion goes. + If maxLevels is 1, FSpIterateDirectory only scans the specified directory; + if maxLevels is 2, FSpIterateDirectory scans the specified directory and + one subdirectory below the specified directory; etc. Set maxLevels to + zero to scan all levels. + + The yourDataPtr parameter can point to whatever data structure you might + want to access from within the IterateFilterProc. + + spec input: An FSSpec record specifying the directory to scan. + maxLevels input: Maximum number of directory levels to scan or + zero to scan all directory levels. + iterateFilter input: A pointer to the routine you want called once + for each file and directory found by + FSpIterateDirectory. + yourDataPtr input: A pointer to whatever data structure you might + want to access from within the IterateFilterProc. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + paramErr -50 No default volume or iterateFilter was NULL + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: RecurseFilterProcPtr, RecurseDirectory +*/ + + + +/*****************************************************************************/ + + + +#endif /* __RECURSEDIRECTORY__ */ diff --git a/macos/source/unixlike.c b/macos/source/unixlike.c new file mode 100644 index 0000000..4eb55da --- /dev/null +++ b/macos/source/unixlike.c @@ -0,0 +1,313 @@ +/* + 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 +*/ +/*--------------------------------------------------------------------------- + + unixlike.c + + Macintosh-specific routines to emulate unixfunctions. + + ---------------------------------------------------------------------------*/ + +/*****************************************************************************/ +/* Includes */ +/*****************************************************************************/ + +#include "zip.h" + +#include +#include +#include + +#include "unixlike.h" +#include "helpers.h" +#include "pathname.h" +#include "macstuff.h" +#include "macglob.h" +#include "mactime.h" + +/*****************************************************************************/ +/* Global Vars */ +/*****************************************************************************/ + +extern MacZipGlobals MacZip; +extern int errno; + + +/*****************************************************************************/ +/* Prototypes */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ + + + + +/* + *---------------------------------------------------------------------- + * + * MacStat -- + * + * This function replaces the library version of stat. The stat + * function provided by most Mac compiliers is rather broken and + * incomplete. + * + * Results: + * See stat documentation. + * + * Side effects: + * See stat documentation. + * + *---------------------------------------------------------------------- + */ + +int Zmacstat(const char *Fname, struct stat *buf) +{ + OSErr err, rc; + short fullPathLength; + Handle hFullPath; + char path[NAME_MAX], path2[NAME_MAX]; + HVolumeParam vpb; + static unsigned long count_of_files = 0; + + AssertStr(Fname,Fname) + Assert_it(buf,"","") + + UserStop(); + + memset(buf, 0, sizeof(buf)); /* zero out all fields */ + + RfDfFilen2Real(path2, Fname, MacZip.MacZipMode, MacZip.DataForkOnly, + &MacZip.CurrentFork); + GetCompletePath(path, path2, &MacZip.fileSpec, &err); + err = PrintUserHFSerr((err != -43) && (err != 0), err, path); + printerr("GetCompletePath:", err, err, __LINE__, __FILE__, path); + + if (err != noErr) { + errno = err; + return -1; + } + + /* Collect here some more information, it's not related to Macstat. + (note: filespec gets changed later in this function) */ + /* clear string-buffer */ + memset(MacZip.FullPath, 0x00, sizeof(MacZip.FullPath)); + rc = FSpGetFullPath(&MacZip.fileSpec, &fullPathLength, &hFullPath); + strncpy(MacZip.FullPath, *hFullPath, fullPathLength); + DisposeHandle(hFullPath); /* we don't need it any more */ + /* Collect some more information not related to Macstat */ + + + /* + * Fill the fpb & vpb struct up with info about file or directory. + */ + + FSpGetDirectoryID(&MacZip.fileSpec, &MacZip.dirID, &MacZip.isDirectory); + vpb.ioVRefNum = MacZip.fpb.hFileInfo.ioVRefNum = MacZip.fileSpec.vRefNum; + vpb.ioNamePtr = MacZip.fpb.hFileInfo.ioNamePtr = MacZip.fileSpec.name; + + if (MacZip.isDirectory) { + MacZip.fpb.hFileInfo.ioDirID = MacZip.fileSpec.parID; + /* + * Directories are executable by everyone. + */ + buf->st_mode |= UNX_IXUSR | UNX_IXGRP | UNX_IXOTH | UNX_IFDIR; + } else { + MacZip.fpb.hFileInfo.ioDirID = MacZip.dirID; + } + + MacZip.fpb.hFileInfo.ioFDirIndex = 0; + err = PBGetCatInfoSync((CInfoPBPtr)&MacZip.fpb); + + if (err == noErr) { + vpb.ioVolIndex = 0; + err = PBHGetVInfoSync((HParmBlkPtr)&vpb); + if (err == noErr && buf != NULL) { + /* + * Files are always readable by everyone. + */ + buf->st_mode |= UNX_IRUSR | UNX_IRGRP | UNX_IROTH; + + /* + * Use the Volume Info & File Info to fill out stat buf. + */ + if (MacZip.fpb.hFileInfo.ioFlAttrib & 0x10) { + buf->st_mode |= UNX_IFDIR; + buf->st_nlink = 2; + } else { + buf->st_nlink = 1; + if (MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags & 0x8000) { + buf->st_mode |= UNX_IFLNK; + } else { + buf->st_mode |= UNX_IFREG; + } + } + + if (MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType == 'APPL') { + /* + * Applications are executable by everyone. + */ + buf->st_mode |= UNX_IXUSR | UNX_IXGRP | UNX_IXOTH; + } + if ((MacZip.fpb.hFileInfo.ioFlAttrib & 0x01) == 0){ + /* + * If not locked, then everyone has write acces. + */ + buf->st_mode |= UNX_IWUSR | UNX_IWGRP | UNX_IWOTH; + } + + buf->st_ino = MacZip.fpb.hFileInfo.ioDirID; + buf->st_dev = MacZip.fpb.hFileInfo.ioVRefNum; + buf->st_uid = -1; + buf->st_gid = -1; + buf->st_rdev = 0; + + if (MacZip.CurrentFork == ResourceFork) + buf->st_size = MacZip.fpb.hFileInfo.ioFlRLgLen; + else + buf->st_size = MacZip.fpb.hFileInfo.ioFlLgLen; + + buf->st_blksize = vpb.ioVAlBlkSiz; + buf->st_blocks = (buf->st_size + buf->st_blksize - 1) + / buf->st_blksize; + + /* + * The times returned by the Mac file system are in the + * local time zone. We convert them to GMT so that the + * epoch starts from GMT. This is also consistent with + * what is returned from "clock seconds". + */ + if (!MacZip.isDirectory) { + MacZip.CreatDate = MacZip.fpb.hFileInfo.ioFlCrDat; + MacZip.ModDate = MacZip.fpb.hFileInfo.ioFlMdDat; + MacZip.BackDate = MacZip.fpb.hFileInfo.ioFlBkDat; + } else { + MacZip.CreatDate = MacZip.fpb.dirInfo.ioDrCrDat; + MacZip.ModDate = MacZip.fpb.dirInfo.ioDrMdDat; + MacZip.BackDate = MacZip.fpb.dirInfo.ioDrBkDat; + } + +#ifdef IZ_CHECK_TZ + if (!zp_tz_is_valid) + { + MacZip.HaveGMToffset = false; + MacZip.Md_UTCoffs = 0L; + MacZip.Cr_UTCoffs = 0L; + MacZip.Bk_UTCoffs = 0L; + } + else +#endif + { + /* Do not use GMT offsets when Md_UTCoffs calculation + * fails, since this time stamp is used for time + * comparisons in Zip and UnZip operations. + * We do not bother when GMT offset calculation fails for + * any other time stamp value. Instead we simply assume + * a default value of 0. + */ + MacZip.HaveGMToffset = + GetGMToffsetMac(MacZip.ModDate, &MacZip.Md_UTCoffs); + if (MacZip.HaveGMToffset) { + GetGMToffsetMac(MacZip.CreatDate, &MacZip.Cr_UTCoffs); + GetGMToffsetMac(MacZip.BackDate, &MacZip.Bk_UTCoffs); + } else { + MacZip.Cr_UTCoffs = 0L; + MacZip.Bk_UTCoffs = 0L; + } + } +#ifdef DEBUG_TIME + { + printf("\nZmacstat: MacZip.HaveGMToffset: %d", + MacZip.HaveGMToffset); + printf("\nZmacstat: Mac modif: %lu local -> UTOffset: %d", + MacZip.ModDate, MacZip.Md_UTCoffs); + printf("\nZmacstat: Mac creat: %lu local -> UTOffset: %d", + MacZip.CreatDate, MacZip.Cr_UTCoffs); + printf("\nZmacstat: Mac back: %lu local -> UTOffset: %d", + MacZip.BackDate, MacZip.Bk_UTCoffs); + } +#endif /* DEBUG_TIME */ + + + buf->st_mtime = MacFtime2UnixFtime(MacZip.ModDate); + buf->st_ctime = MacFtime2UnixFtime(MacZip.CreatDate); + buf->st_atime = buf->st_mtime; + +#ifdef DEBUG_TIME + { + printf("\nZmacstat: Unix modif: %lu UTC; Mac: %lu local", + buf->st_mtime, MacZip.ModDate); + printf("\nZmacstat: Unix creat: %lu UTC; Mac: %lu local\n", + buf->st_ctime, MacZip.CreatDate); + } +#endif /* DEBUG_TIME */ + + if (noisy) + { + if (MacZip.StatingProgress) + { + count_of_files++; + InformProgress(MacZip.RawCountOfItems, count_of_files ); + } + else + count_of_files = 0; + } + } + } + + if (err != noErr) { + errno = err; + } + + MacZip.isMacStatValid = true; + return (err == noErr ? 0 : -1); +} + + + + + +/* + *---------------------------------------------------------------------- + * + * chmod -- + * + * Results: + * See chmod documentation. + * + * Side effects: + * See chmod documentation. + * + *---------------------------------------------------------------------- + */ + +int chmod(char *path, int mode) +{ + HParamBlockRec hpb; + OSErr err; + + hpb.fileParam.ioNamePtr = C2PStr(path); + hpb.fileParam.ioVRefNum = 0; + hpb.fileParam.ioDirID = 0; + + if (mode & 0200) { + err = PBHRstFLockSync(&hpb); + } else { + err = PBHSetFLockSync(&hpb); + } + + if (err != noErr) { + errno = err; + return -1; + } + + return 0; +} diff --git a/macos/source/unixlike.h b/macos/source/unixlike.h new file mode 100644 index 0000000..e61a354 --- /dev/null +++ b/macos/source/unixlike.h @@ -0,0 +1,86 @@ +/* + 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 +*/ +/* + * Directory Operations for Mac based on BSD 4.3 + * By Jason Linhart, January 1997 + */ + +#ifndef _UNIXLIKE_H +#define _UNIXLIKE_H 1 + +#include + +#ifndef NAME_MAX +#define NAME_MAX 2048 +#endif + +#define UNX_IFMT 0170000 /* Unix file type mask */ +#define UNX_IFSOCK 0140000 /* Unix socket (BSD, not SysV or Amiga) */ +#define UNX_IFLNK 0120000 /* Unix symbolic link (not SysV, Amiga) */ +#define UNX_IFREG 0100000 /* Unix regular file */ +#define UNX_IFBLK 0060000 /* Unix block special (not Amiga) */ +#define UNX_IFDIR 0040000 /* Unix directory */ +#define UNX_IFCHR 0020000 /* Unix character special (not Amiga) */ +#define UNX_IFIFO 0010000 /* Unix fifo (BCC, not MSC or Amiga) */ + +#define UNX_ISUID 04000 /* Unix set user id on execution */ +#define UNX_ISGID 02000 /* Unix set group id on execution */ +#define UNX_ISVTX 01000 /* Unix directory permissions control */ +#define UNX_ENFMT UNX_ISGID /* Unix record locking enforcement flag */ + +#define UNX_IRWXU 00700 /* Unix read, write, execute: owner */ +#define UNX_IRUSR 00400 /* Unix read permission: owner */ +#define UNX_IWUSR 00200 /* Unix write permission: owner */ +#define UNX_IXUSR 00100 /* Unix execute permission: owner */ + +#define UNX_IRWXG 00070 /* Unix read, write, execute: group */ +#define UNX_IRGRP 00040 /* Unix read permission: group */ +#define UNX_IWGRP 00020 /* Unix write permission: group */ +#define UNX_IXGRP 00010 /* Unix execute permission: group */ + +#define UNX_IRWXO 00007 /* Unix read, write, execute: other */ +#define UNX_IROTH 00004 /* Unix read permission: other */ +#define UNX_IWOTH 00002 /* Unix write permission: other */ +#define UNX_IXOTH 00001 /* Unix execute permission: other */ + +/* historical file modes */ +#define S_IREAD 0x100 +#define S_IWRITE 0x80 +#define S_IEXEC 0x40 + + +#define isatty(arg) 1 + + +#define EINVAL 22 /* Invalid argument */ +#define ENAMETOOLONG 63 /* File name too long */ + + +struct dirent { + char d_name[NAME_MAX]; +}; + +/* + * The following definitions are usually found in fcntl.h. + * However, MetroWerks has screwed that file up a couple of times + * and all we need are the defines. + */ +#define O_APPEND 0x0100 /* open the file in append mode */ +#define O_CREAT 0x0200 /* create the file if it doesn't exist */ +#define O_EXCL 0x0400 /* if the file exists don't create it again */ +#define O_TRUNC 0x0800 /* truncate the file after opening it */ + + +int Zmacstat (const char *path, struct stat *buf); +int chmod(char *path, int mode); + + +#include "macstuff.h" + +#endif /* _UNIXLIKE_H */ diff --git a/macos/source/zip_rc.hqx b/macos/source/zip_rc.hqx new file mode 100644 index 0000000..99e0d25 --- /dev/null +++ b/macos/source/zip_rc.hqx @@ -0,0 +1,43 @@ +(This file must be converted with BinHex 4.0) +:#RTTF#jbBbjcDA3!8dP84&0*9#%!N!3([`#3"&(E8dP8)3!"!!!([h*-BA8#Q3# +3!aDCQ3d!"RTTF#jbB`!!&[Bi"2[rG!"-5QS!N!1!!*!%"32,j+m2!*!Drj!%8P0 +53e*6483"",#mXHDaqlGG!!!GmJ#3"JFj!*!%6Mi!N!MGc!`!P@6pq1R*k4&+Z,d +p"5$(b(-Upcc#j%EiHCfjPTq%8h+X8d)MR$`rF[b9Vh`pTLc2jqZ9r'RNq9VN1'& +'MMmj6Sk6#5HFc0J4lN8iHFU2--,*K%Z1NIR+#1XNR("#bE-)2I+FF$*G@H6BL+` +*!&6IV1ml1d+22#-$4UEm*#01"T`m*4`Ji(03ThM'$-EBilf-V8-e6Q8bXEVD@Xi +2bilcmGEY"lV6QGjZrK)I1CKZ$BfR4pSbLD'f`F'qVPKb+*(-*V2CPLfaGj1CE+a +Z+-$kpr4hpHrCf@d%f66E!A2P-rA6phmUj)QrdYP4r[6)H+cZF"hRV``NHSG5`b! +F6-0YBZ$!JH&%#frIb,2TmH4`LVGN4c1(%U1Q8#cf)P44dU"#-`D)I($H4I5qc[j +NJLI5)qpN5)Ic[S(-`-&1H(U2L*U'-H`1Y1p&qc#*YVk4(RNUbp(ae(#'R,B[d%B +(Nd40$id1C`FhmUlKNBmbkAf$Sra8qpDYcm0,H%GIhbiej(!EESbmC+a*'3dqdlC +j)%*H#+!,D!K4#J#3!$9H-J)mB*6L!50R"%"&hi6DD*61[-qq22%f1hkXPq@r)'` +(1hjQJ19cKP'bY0#60RQ3!&kd,r))mj-X,LBCCa&CeiX#f`ibZ$9##+[1HUJ34G5 +584+#&@p9i[UDj-&PD2rAi0qYdMpMQ""M8FLBT`#FUMje-i6rVXl2qI`jK@XY#eH ++%JH[5(`6,qEcH@K,(FfA4rZDNG,4mp60fALH@TT,SC!!5Sf0$HHP31&mP"AfKN) +K-!N[&XjM@##`1I,(a"V"#L%@#U9'*'lT-5CaU8GqpLTFkUP"%klmfMLJ1QpH5r2 +djNdfhIXJFIqqN!!&1QHe$jUlHF`jZ2I41X8k$@ZbKF1C2"Cq6YZaF(Z+5Yra&63 +"alCh62Vm6N(RqR90&)#m`cE3mILqV`@qBmcQkf0"9Ei%#**RRRpcS0DmV!N6DB- +&#R112Ym4-1d)GJ(R0,i,0!TEJ!%$#Mj$SFqp80)XU4&"+j!!DmFJk)S2*[(KNMR +mHApd)4Im@I2aqEBrpd,EVi3ehd@qETI[eprhmmlp0UGjqhe`q#[[Ljk#GDclAll +[P91j$d[[ir`4X1LcbmVcI$8cCd49rY*`E2l+F1l-Uk0CV,edY8%d('d@pD*qVRk +L@64FE9KlU9Q%E`3$i@+cD"BSp)'26f,8K%[iL[#3!$-h&aDPY5L2CJBBpF5Kh5k ++ASJVqckQ9kG`*C95rEka+29B5U+f"eYIqF&ZC()P-%GbHXQ44)a!l[Z9q3[c5Z! +aN!!pGHT"X#q,IJ$8lG#i224dkNXMhd,#3I"ap4JkEk@YlrKEp1r14erRqIYVJY@ +RbX4G0GVTc4A5A20`[E`GcX60GGI#0@$KHMqfFB9BIV4&%kr6+kH*J`(FR3lKcJj +pNqpN!JiZ-`'&1jQ!a*e-31RCQB$%R8c!dY1CJ19(C`+@AjGIa[qCCq8qH,K8FA% +LH$LpGbZiFpp0ehUR[lZTL-[HU3T8q*FVkd5&AaDBjrX##ha2S$UImK6,r-Z9MDM +#PaVqNfUH+VqmXplAGpG!G`k,I&I!i[ZC`J,Iba3@rEQC`J,Iba5@rFQGIhNq5h` +r-lM2ArAJIYjp(jEjYX!5he+i`cIhZRrjYq)%rjNh@"K4Ej!!V8&p!,8@0C*$l3L +bk#`f"%i9DMaRk,i*YC&aj0dFH6G(hXf4Gh2Nh4ajYp5aY(5[I@a#hBBDeh9E'*X +Kq3q,)QS*99$0SCj&R68Va[9Ie6lJ9444KDk%dDE9%CrPQhJ,hbD#)RJ8936RJK1 +bjb%HMTILXr&#r&Um++SIZ#*1fAP1hM-c'CG*VekG*BkGApkj'DZA13GkPA1JPcN +(iC4c%*m@1&[2l0@LLCK%pFUBG%kj4M@2,@pY&UjA+*Y2#Zil5%pF&GI[LBAVh-2 +$3I"aCG,5ekC[qL[MlZ1QRP32Ga5YQFY`Cf-[rZ!JX+GrCir-1R)J6J!jdY[ekRU +IXFT6',*jNmH[B69Hq&&6$N-NlS3K8Xm03mM2+VTKb253!iSqNDRHIKqNq$hqV6$ +%pVF8KPMc@68N$0Q#[KXH1UJL$1P'',*PpB``C"5M'eXG)JbTfDal(BB!AfdN$-' +cjq2P-%6bli8Kq,pej"NCErJr%NGk[[Pkpa44M+pBl4Mq$SC![ij'pZ[3j20d)N[ +i$qR%J5hSI`01r3hJcl+!m54`kMY9f'+N1PrYaRqe4SCq@E8Hr)$%dK,,5@`LdR2 +b$cBKPr+"5-q*AH`)BBm-4AUqlG-DHk"a9QQ`Yi"0+Beefb-pTlj6'Z(2`,ZS0"j ++!KY9'SpQ-0f,5U2Q'(Lr+Sd(h`3fV65DpX2VT0+)[!EHKdUMS4ABTdVMX4IJG8T +T'*pJ6K'P8IXk0+iTMFB8I'L[i9r!Qp6c`!dlH9,2idGJTp9PD'b(MjH9AZ0cQ02 +TqYdI$#8c2*2-$Kr+**,r!`#3!dm4!!!: diff --git a/macos/zipup.h b/macos/zipup.h new file mode 100644 index 0000000..ce2af4a --- /dev/null +++ b/macos/zipup.h @@ -0,0 +1,25 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#ifndef O_RDONLY +# include +#endif + +#define fhow (O_RDONLY|O_BINARY) +#define fbad (-1) + +typedef int ftype; + + +#define zopen(n,p) MacOpen(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 + + diff --git a/man/zip.1 b/man/zip.1 new file mode 100644 index 0000000..0c2fce0 --- /dev/null +++ b/man/zip.1 @@ -0,0 +1,2840 @@ +.\" ========================================================================= +.\" Copyright (c) 1990-2008 Info-ZIP. All rights reserved. +.\" +.\" See the accompanying file LICENSE, version 2007-Mar-4 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 +.\" ========================================================================== +.\" +.\" zip.1 by Mark Adler, Jean-loup Gailly and R. P. C. Rodgers +.\" updated by E. Gordon for Zip 3.0 (8 May 2005, 24 December 2006, +.\" 4 February 2007, 27 May 2007, 4 June 2007 by EG; 12 June 2007 by CS; +.\" 30 August 2007, 27 April 2008, 25 May 2008, 27 May 2008 by EG, +.\" 7 June 2008 by SMS and EG; 12 June 2008 by EG) +.\" +.TH ZIP 1L "16 June 2008 (v3.0)" Info-ZIP +.SH NAME +zip \- package and compress (archive) files +.SH SYNOPSIS +.B zip +.RB [\- aABcdDeEfFghjklLmoqrRSTuvVwXyz!@$ ] +[\-\-longoption ...] +.RB [\- b " path]" +.RB [\- n " suffixes]" +.RB [\- t " date]" +.RB [\- tt " date]" +[\fIzipfile\fR [\fIfile\fR \.\|.\|.]] +[\fB-xi\fR list] +.PP +.B zipcloak +(see separate man page) +.PP +.B zipnote +(see separate man page) +.PP +.B zipsplit +(see separate man page) +.PP +Note: Command line processing in +.I zip +has been changed to support long options and handle all +options and arguments more consistently. Some old command +lines that depend on command line inconsistencies may no longer +work. +.SH DESCRIPTION +.I zip +is a compression and file packaging utility for Unix, VMS, MSDOS, +OS/2, Windows 9x/NT/XP, Minix, Atari, Macintosh, Amiga, and Acorn +RISC OS. It is analogous to a combination of the Unix commands +.IR tar (1) +and +.IR compress (1) +and is compatible with PKZIP (Phil Katz's ZIP for MSDOS systems). +.LP +A companion program +.RI ( unzip (1L)) +unpacks +.I zip +archives. +The +.I zip +and +.IR unzip (1L) +programs can work with archives produced by PKZIP (supporting +most PKZIP features up to PKZIP version 4.6), +and PKZIP and PKUNZIP can work with archives produced by +\fIzip\fP (with some exceptions, notably streamed archives, +but recent changes in the zip file standard may facilitate +better compatibility). +.I zip +version 3.0 is compatible with PKZIP 2.04 and also supports +the Zip64 extensions of PKZIP 4.5 which allow archives +as well as files to exceed the previous 2 GB limit (4 GB in +some cases). \fIzip\fP also now supports \fBbzip2\fP compression +if the \fBbzip2\fP library is included when \fIzip\fP is compiled. +Note that PKUNZIP 1.10 cannot extract files produced by +PKZIP 2.04 or +\fIzip\ 3.0\fP. You must use PKUNZIP 2.04g or +\fIunzip\ 5.0p1\fP (or later versions) to extract them. +.PP +See the \fBEXAMPLES\fP section at the bottom of this page +for examples of some typical uses of \fIzip\fP. +.PP +\fBLarge\ Archives\ and\ Zip64.\fP +.I zip +automatically uses the Zip64 extensions when files larger than 4 GB are +added to an archive, an archive containing Zip64 entries is updated +(if the resulting archive still needs Zip64), +the size of the archive will exceed 4 GB, or when the +number of entries in the archive will exceed about 64K. +Zip64 is also used for archives streamed from standard input as the size +of such archives are not known in advance, but the option \fB\-fz\-\fP can +be used to force \fIzip\fP to create PKZIP 2 compatible archives (as long +as Zip64 extensions are not needed). You must use a PKZIP 4.5 +compatible unzip, such as \fIunzip\ 6.0\fP or later, to extract files +using the Zip64 extensions. +.PP +In addition, streamed archives, entries encrypted with standard encryption, +or split archives created with the pause option may not be compatible with +PKZIP as data descriptors are used +and PKZIP at the time of this writing does not support data descriptors +(but recent changes in the PKWare published zip standard now include some +support for the data descriptor format \fIzip\fP uses). + +.PP +\fBMac OS X.\fP Though previous Mac versions had their own \fIzip\fP port, +\fIzip\fP supports Mac OS X as part of the Unix port and most Unix features +apply. References to "MacOS" below generally refer to MacOS versions older +than OS X. Support for some Mac OS features in the Unix Mac OS X port, such +as resource forks, is expected in the next \fIzip\fP release. + +.PP +For a brief help on \fIzip\fP and \fIunzip\fP, +run each without specifying any parameters on the command line. + +.SH "USE" +.PP +The program is useful for packaging a set of files for distribution; +for archiving files; +and for saving disk space by temporarily +compressing unused files or directories. +.LP +The +.I zip +program puts one or more compressed files into a single +.I zip +archive, +along with information about the files +(name, path, date, time of last modification, protection, +and check information to verify file integrity). +An entire directory structure can be packed into a +.I zip +archive with a single command. +Compression ratios of 2:1 to 3:1 are common for text files. +.I zip +has one compression method (deflation) and can also store files without +compression. (If \fBbzip2\fP support is added, \fIzip\fP can also +compress using \fBbzip2\fP compression, but such entries require a +reasonably modern unzip to decompress. When \fBbzip2\fP compression +is selected, it replaces deflation as the default method.) +.I zip +automatically chooses the better of the two (deflation or store or, if +\fBbzip2\fP is selected, \fBbzip2\fP or store) for each file to be +compressed. +.LP +\fBCommand\ format.\fP The basic command format is +.IP +\fBzip\fR options archive inpath inpath ... +.LP +where \fBarchive\fR is a new or existing \fIzip\fR archive +and \fBinpath\fR is a directory or file path optionally including wildcards. +When given the name of an existing +.I zip +archive, +.I zip +will replace identically named entries in the +.I zip +archive (matching the relative names as stored in +the archive) or add entries for new names. +For example, +if +.I foo.zip +exists and contains +.I foo/file1 +and +.IR foo/file2 , +and the directory +.I foo +contains the files +.I foo/file1 +and +.IR foo/file3 , +then: +.IP +\fCzip -r foo.zip foo\fP +.LP +or more concisely +.IP +\fCzip -r foo foo\fP +.LP +will replace +.I foo/file1 +in +.I foo.zip +and add +.I foo/file3 +to +.IR foo.zip . +After this, +.I foo.zip +contains +.IR foo/file1 , +.IR foo/file2 , +and +.IR foo/file3 , +with +.I foo/file2 +unchanged from before. +.LP +So if before the zip command is executed \fIfoo.zip\fP has: +.IP +\fC foo/file1 foo/file2 +.LP +and directory foo has: +.IP +\fC file1 file3\fP +.LP +then \fIfoo.zip\fP will have: +.IP +\fC foo/file1 foo/file2 foo/file3\fP +.LP +where \fIfoo/file1\fP is replaced and +\fIfoo/file3\fP is new. +.LP +\fB\-@\ file\ lists.\fP If a file list is specified as +\fB\-@\fP +[Not on MacOS], +.I zip +takes the list of input files from standard input instead of from +the command line. For example, +.IP +\fCzip -@ foo\fP +.LP +will store the files listed one per line on stdin in \fIfoo.zip\fP. +.LP +Under Unix, +this option can be used to powerful effect in conjunction with the +\fIfind\fP\ (1) +command. +For example, +to archive all the C source files in the current directory and +its subdirectories: +.IP +\fCfind . -name "*.[ch]" -print | zip source -@\fP +.LP +(note that the pattern must be quoted to keep the shell from expanding it). +.LP +\fBStreaming\ input\ and\ output.\fP +.I zip +will also accept a single dash ("-") as the zip file name, in which case it +will write the zip file to standard output, allowing the output to be piped +to another program. For example: +.IP +\fCzip -r - . | dd of=/dev/nrst0 obs=16k\fP +.LP +would write the zip output directly to a tape with the specified block size +for the purpose of backing up the current directory. +.LP +.I zip +also accepts a single dash ("-") as the name of a file to be compressed, in +which case it will read the file from standard input, allowing zip to take +input from another program. For example: +.IP +\fCtar cf - . | zip backup -\fP +.LP +would compress the output of the tar command for the purpose of backing up +the current directory. This generally produces better compression than +the previous example using the -r option because +.I zip +can take advantage of redundancy between files. The backup can be restored +using the command +.IP +\fCunzip -p backup | tar xf -\fP +.LP +When no zip file name is given and stdout is not a terminal, +.I zip +acts as a filter, compressing standard input to standard output. +For example, +.IP +\fCtar cf - . | zip | dd of=/dev/nrst0 obs=16k\fP +.LP +is equivalent to +.IP +\fCtar cf - . | zip - - | dd of=/dev/nrst0 obs=16k\fP +.LP +.I zip +archives created in this manner can be extracted with the program +.I funzip +which is provided in the +.I unzip +package, or by +.I gunzip +which is provided in the +.I gzip +package (but some +.I gunzip +may not support this if +.I zip +used the Zip64 extensions). For example: +.IP +\fPdd if=/dev/nrst0 ibs=16k | funzip | tar xvf -\fC +.LP +The stream can also be saved to a file and +.I unzip +used. +.LP +If Zip64 support for large files and archives is enabled and +\fIzip\fR is used as a filter, \fIzip\fR creates a Zip64 archive +that requires a PKZIP 4.5 or later compatible unzip to read it. This is +to avoid amgibuities in the zip file structure as defined in the current +zip standard (PKWARE AppNote) where the decision to use Zip64 needs to +be made before data is written for the entry, but for a stream the size +of the data is not known at that point. If the data is known to be smaller +than 4 GB, the option \fB\-fz\-\fP can be used to prevent use of Zip64, +but \fIzip\fP will exit with an error if Zip64 was in fact needed. +\fIzip\ 3\fR and \fIunzip\ 6\fR and later can read archives with Zip64 +entries. Also, \fIzip\fP removes the Zip64 extensions if not needed +when archive entries are copied (see the \fB\-U\fP (\fB\-\-copy\fP) +option). +.LP +When directing the output to another file, note that all options should be +before the redirection including \fB-x\fP. For example: +.IP +\fPzip archive "*.h" "*.c" -x donotinclude.h orthis.h > tofile\fC +.LP +\fBZip\ files.\fP When changing an existing +.I zip +archive, +.I zip +will write a temporary file with the new contents, +and only replace the old one when the process of creating the new version +has been completed without error. +.LP +If the name of the +.I zip +archive does not contain an extension, the extension +\fB.zip\fP +is added. If the name already contains an extension other than +\fB.zip\fP, +the existing extension is kept unchanged. However, split archives +(archives split over multiple files) require the \fB.zip\fP extension +on the last split. +.PP +\fBScanning\ and\ reading\ files.\fP +When \fIzip\fP starts, it scans for files to process (if needed). If +this scan takes longer than about 5 seconds, \fIzip\fP will display +a "Scanning files" message and start displaying progress dots every 2 seconds +or every so many entries processed, whichever takes longer. If there is more +than 2 seconds between dots it could indicate that finding each file is taking +time and could mean a slow network connection for example. +(Actually the initial file scan is +a two-step process where the directory scan is followed by a sort and these +two steps are separated with a space in the dots. If updating an existing +archive, a space also appears between the existing file scan and the new +file scan.) The scanning files dots are not controlled by the \fB\-ds\fP +dot size option, but the dots are turned off by the \fB\-q\fP quiet option. The +\fB\-sf\fP show files option can be used to scan for files and get the list of +files scanned without actually processing them. +.LP +If \fIzip\fR is not able to read a file, it +issues a warning but +continues. See the \fB\-MM\fP option below for more on how \fIzip\fP handles +patterns that are not matched and files that are not readable. +If some files were skipped, a +warning is issued at the end of the zip operation noting how many files +were read and how many skipped. +.PP +\fBCommand\ modes.\fP \fIzip\fP now supports two distinct types of command +modes, \fBexternal\fP and \fBinternal\fP. The \fBexternal\fP modes +(add, update, and freshen) read files from the file system (as well as from an +existing archive) while the \fBinternal\fP modes (delete and copy) operate +exclusively on entries in an existing archive. +.LP +.TP +.BI add\ \ \ \ \ \ +Update existing entries and add new files. If the archive does not exist +create it. This is the default mode. +.TP +.BI update\ \fP(\fB\-u\fP) +Update existing entries if newer on the file system and add new files. If +the archive does not exist issue warning then create a new archive. +.TP +.BI freshen\ \fP(\fB\-f\fP) +Update existing entries of an archive if newer on the file system. +Does not add new files to the archive. +.TP +.BI delete\ \fP(\fB\-d\fP) +Select entries in an existing archive and delete them. +.TP +.BI copy\ \fP(\fB\-U\fP) +Select entries in an existing archive and copy them to a new archive. +This new mode is similar to \fBupdate\fP but command line patterns +select entries in the existing archive rather than files from +the file system and it uses the \fB\-\-out\fP option to write the +resulting archive to a new file rather than update the existing +archive, leaving the original archive unchanged. +.LP +The new File Sync option (\fB\-FS\fP) is also considered a new mode, +though it is similar to \fBupdate\fP. This mode synchronizes the +archive with the files on the OS, only replacing files in the +archive if the file time or size of the OS file is different, adding +new files, and deleting entries from the archive where there is +no matching file. As this mode can delete entries from the archive, +consider making a backup copy of the archive. + +Also see \fB\-DF\fP for creating difference archives. + +See each option description below for details and the \fBEXAMPLES\fP section +below for examples. +.PP +\fBSplit\ archives.\fP \fIzip\fP version 3.0 and later can create split +archives. A +\fBsplit archive\fP is a standard zip archive split over multiple +files. (Note that split archives are not just archives split in to +pieces, as the offsets of entries are now based on the start of each +split. Concatenating the pieces together will invalidate these offsets, +but \fIunzip\fP can usually deal with it. \fIzip\fP will usually refuse +to process such a spliced archive unless the \fB\-FF\fP fix option is +used to fix the offsets.) +.LP +One use of split archives is storing a large archive on multiple +removable media. +For a split archive with 20 split files the files are typically named (replace +ARCHIVE with the name of your archive) ARCHIVE.z01, ARCHIVE.z02, ..., ARCHIVE.z19, +ARCHIVE.zip. Note that the last file is the \fB.zip\fP file. In contrast, +\fBspanned archives\fP are the original multi-disk archive generally requiring +floppy disks and using volume labels to store disk numbers. \fIzip\fP supports +split archives but not spanned archives, though a procedure exists for converting +split archives of the right size to spanned archives. The reverse is also true, +where each file of a spanned archive can be copied in order to files with the +above names to create a split archive. +.LP +Use \fB\-s\fP to set the split size and create a split archive. The size is +given as a number followed optionally by one of k (kB), m (MB), g (GB), or t (TB) +(the default is m). The \fB\-sp\fP option can be used to pause \fIzip\fP between +splits to allow changing removable media, for example, but read the descriptions +and warnings for both \fB\-s\fP and \fB\-sp\fP below. +.LP +Though \fIzip\fP does not update split archives, \fIzip\fP provides the new +option \fB\-O\fP (\fB\-\-output\-file\fP or \fB\-\-out\fP) to allow split archives +to be updated and saved in a new archive. For example, +.IP +\fCzip inarchive.zip foo.c bar.c \-\-out outarchive.zip\fP +.LP +reads archive \fBinarchive.zip\fP, even if split, adds the files \fBfoo.c\fP and +\fBbar.c\fP, and writes the resulting archive to \fBoutarchive.zip\fP. If +\fBinarchive.zip\fP is split then \fBoutarchive.zip\fP defaults to the same +split size. Be aware that if \fBoutarchive.zip\fP and any split files that are +created with it already exist, these are always overwritten as needed without +warning. This may be changed in the future. +.PP +\fBUnicode.\fP Though the zip standard requires storing paths in an archive using +a specific character set, in practice zips have stored paths in archives in whatever +the local character set is. This creates problems when an archive is created or +updated on a system using one character set and then extracted on another system +using a different character set. When compiled with Unicode support enabled on +platforms that support wide characters, \fIzip\fP now stores, in addition to the +standard local path for backward compatibility, the UTF-8 translation of the path. +This provides a common universal character set for storing paths that allows these +paths to be fully extracted on other systems that support Unicode and to match as +close as possible on systems that don't. + +On Win32 systems where paths are internally stored as Unicode but represented in +the local character set, it's possible that some paths will be skipped during a +local character set directory scan. \fIzip\fP with Unicode support now can read +and store these paths. Note that Win 9x systems and FAT file systems don't fully +support Unicode. + +Be aware that console windows on Win32 and Unix, for example, sometimes don't +accurately show all characters due to how each operating system switches in +character sets for display. However, directory navigation tools should show the +correct paths if the needed fonts are loaded. +.PP +\fBCommand line format.\fP This version of +.I zip +has updated command line processing and support for long options. +.PP +Short options take the form +.IP +\fC-s[-][s[-]...][value][=value][\ value]\fP +.LP +where s is a one or two character short option. A short option +that takes a value is last in an argument and anything after it is +taken as the value. If the option can be negated and "-" immediately +follows the option, the option is negated. +Short options can also be given as separate arguments +.IP +\fC-s[-][value][=value][\ value]\ -s[-][value][=value][\ value]\ ...\fP +.LP +Short options in general take values either as part of the same +argument or as the following argument. An optional = is also supported. +So +.IP +\fC-ttmmddyyyy\fP +.LP +and +.IP +\fC-tt=mmddyyyy\fP +.LP +and +.IP +\fC-tt mmddyyyy\fP +.LP +all work. The \fB\-x\fP and \fB\-i\fP options accept lists of values +and use a slightly different format described below. See the +\fB\-x\fP and \fB\-i\fP options. +.PP +Long options take the form +.IP +\fC--longoption[-][=value][ value]\fP +.LP +where the option starts with --, has a multicharacter name, can +include a trailing dash to negate the option (if the option +supports it), and can have a value (option argument) specified by +preceeding it with = (no spaces). Values can also follow the +argument. So +.IP +\fC--before-date=mmddyyyy\fP +.LP +and +.IP +\fC--before-date mmddyyyy\fP +.LP +both work. + +Long option names can be shortened to the shortest unique +abbreviation. See the option descriptions below for which +support long options. To avoid confusion, avoid abbreviating +a negatable option with an embedded dash ("-") at the dash +if you plan to negate it (the parser would consider +a trailing dash, such as for the option \fB\-\-some\-option\fP using +\fB\-\-some\-\fP as the option, as part of the name rather +than a negating dash). This may be changed to force the last +dash in \fB\-\-some\-\fP to be negating in the future. +.SH "OPTIONS" +.TP +.PD 0 +.BI \-a +.TP +.PD +.B \-\-ascii +[Systems using EBCDIC] Translate file to ASCII format. + +.TP +.PD 0 +.B \-A +.TP +.PD +.B \-\-adjust-sfx +Adjust self-extracting executable archive. +A self-extracting executable archive is created by prepending +the SFX stub to an existing archive. The +.B \-A +option tells +.I zip +to adjust the entry offsets stored +in the archive to take into account this "preamble" data. +.LP +Note: self-extracting archives for the Amiga are a special case. +At present, only the Amiga port of \fIzip\fP is capable of adjusting +or updating these without corrupting them. -J can be used to remove +the SFX stub if other updates need to be made. + +.TP +.PD 0 +.B \-AC +.TP +.PD +.B \-\-archive-clear +[WIN32] Once archive is created (and tested if \fB\-T\fP is used, +which is recommended), clear the archive bits of files processed. WARNING: +Once the bits are cleared they are cleared. You may want to use the +\fB\-sf\fP show files option to store the list of files processed in case +the archive operation must be repeated. Also consider using +the \fB\-MM\fP must match option. Be sure to check out \fB\-DF\fP as a +possibly better way to do incremental backups. + +.TP +.PD 0 +.B \-AS +.TP +.PD +.B \-\-archive-set +[WIN32] Only include files that have the archive bit set. Directories +are not stored when \fB\-AS\fP is used, though by default the paths +of entries, including directories, are stored as usual and can be used +by most unzips to recreate directories. + +The archive bit is set by the operating system when a file is modified +and, if used with \fB\-AC\fP, \fB\-AS\fP can provide an +incremental backup capability. However, other applications can +modify the archive bit and it may not be a reliable indicator of +which files have changed since the last archive operation. Alternative +ways to create incremental backups are using \fB\-t\fP to use file dates, +though this won't catch old files copied to directories being archived, +and \fB\-DF\fP to create a differential archive. + +.TP +.PD 0 +.B \-B +.TP +.PD +.B \-\-binary +[VM/CMS and MVS] force file to be read binary (default is text). + +.TP +.B \-B\fRn +[TANDEM] set Edit/Enscribe formatting options with n defined as +.RS +bit 0: Don't add delimiter (Edit/Enscribe) +.RE +.RS +bit 1: Use LF rather than CR/LF as delimiter (Edit/Enscribe) +.RE +.RS +bit 2: Space fill record to maximum record length (Enscribe) +.RE +.RS +bit 3: Trim trailing space (Enscribe) +.RE +.RS +bit 8: Force 30K (Expand) large read for unstructured files +.RE + +.TP +.PD 0 +.BI \-b\ \fRpath +.TP +.PD +.B \-\-temp-path\ \fRpath +Use the specified +.I path +for the temporary +.I zip +archive. For example: +.RS +.IP +\fCzip -b /tmp stuff *\fP +.RE +.IP +will put the temporary +.I zip +archive in the directory +.IR /tmp , +copying over +.I stuff.zip +to the current directory when done. This option is useful when +updating an existing archive and the file system containing this +old archive does not have enough space to hold both old and new archives +at the same time. It may also be useful when streaming in some +cases to avoid the need for data descriptors. Note that using +this option may require \fIzip\fP take additional time to copy +the archive file when done to the destination file system. + +.TP +.PD 0 +.B \-c +.TP +.PD +.B \-\-entry-comments +Add one-line comments for each file. +File operations (adding, updating) are done first, +and the user is then prompted for a one-line comment for each file. +Enter the comment followed by return, or just return for no comment. + +.TP +.PD 0 +.B \-C +.TP +.PD +.B \-\-preserve-case +[VMS] Preserve case all on VMS. Negating this option +(\fB\-C-\fP) downcases. + +.TP +.PD 0 +.B \-C2 +.TP +.PD +.BI \-\-preserve-case-2 +[VMS] Preserve case ODS2 on VMS. Negating this option +(\fB\-C2-\fP) downcases. + +.TP +.PD 0 +.B \-C5 +.TP +.PD +.B \-\-preserve-case-5 +[VMS] Preserve case ODS5 on VMS. Negating this option +(\fB\-C5-\fP) downcases. + +.TP +.PD 0 +.B \-d +.TP +.PD +.B \-\-delete +Remove (delete) entries from a +.I zip +archive. +For example: +.RS +.IP +\fCzip -d foo foo/tom/junk foo/harry/\\* \\*.o\fP +.RE +.IP +will remove the entry +.IR foo/tom/junk , +all of the files that start with +.IR foo/harry/ , +and all of the files that end with +.B \&.o +(in any path). +Note that shell pathname expansion has been inhibited with backslashes, +so that +.I zip +can see the asterisks, +enabling +.I zip +to match on the contents of the +.I zip +archive instead of the contents of the current directory. +(The backslashes are not used on MSDOS-based platforms.) +Can also use quotes to escape the asterisks as in +.RS +.IP +\fCzip -d foo foo/tom/junk "foo/harry/*" "*.o"\fP +.RE +.IP +Not escaping the asterisks on a system where the shell expands +wildcards could result in the asterisks being converted to a +list of files in the current directory and that list used to +delete entries from the archive. +.IP +Under MSDOS, +.B \-d +is case sensitive when it matches names in the +.I zip +archive. +This requires that file names be entered in upper case if they were +zipped by PKZIP on an MSDOS system. (We considered making this +case insensitive on systems where paths were case insensitive, +but it is possible the archive came from a system where case does +matter and the archive could include both \fBBar\fP and \fBbar\fP +as separate files in the archive.) But see the new option \fB\-ic\fP +to ignore case in the archive. + +.TP +.PD 0 +.B \-db +.TP +.PD +.B \-\-display-bytes +Display running byte counts showing the bytes zipped and the bytes to go. + +.TP +.PD 0 +.B \-dc +.TP +.PD +.B \-\-display-counts +Display running count of entries zipped and entries to go. + +.TP +.PD 0 +.B \-dd +.TP +.PD +.B \-\-display-dots +Display dots while each entry is zipped (except on ports that have their own +progress indicator). See \fB-ds\fR below for setting dot size. The default is +a dot every 10 MB of input file processed. The \fB-v\fR option +also displays dots (previously at a much higher rate than this but now \fB\-v\fP +also defaults to 10 MB) and this rate is also controlled by \fB-ds\fR. + +.TP +.PD 0 +.B \-df +.TP +.PD +.B \-\-datafork +[MacOS] Include only data-fork of files zipped into the archive. +Good for exporting files to foreign operating-systems. +Resource-forks will be ignored at all. + +.TP +.PD 0 +.B \-dg +.TP +.PD +.B \-\-display-globaldots +Display progress dots for the archive instead of for each file. The command +.RS +.IP + zip -qdgds 10m +.RE +.IP +will turn off most output except dots every 10 MB. + +.TP +.PD 0 +.B \-ds\ \fRsize +.TP +.PD +.B \-\-dot-size\ \fRsize +Set amount of input file processed for each dot displayed. See \fB-dd\fR to +enable displaying dots. Setting this option implies \fB-dd\fR. Size is +in the format nm where n is a number and m is a multiplier. Currently m can +be k (KB), m (MB), g (GB), or t (TB), so if n is 100 and m is k, size would be +100k which is 100 KB. The default is 10 MB. +.IP +The \fB-v\fR option also displays dots and now defaults to +10 MB also. This rate is also controlled by this option. A size of 0 turns dots off. +.IP +This option does not control the dots from the "Scanning files" message as +\fIzip\fP scans for input files. The dot size for that is fixed at 2 seconds +or a fixed number of entries, whichever is longer. + +.TP +.PD 0 +.B \-du +.TP +.PD +.B \-\-display-usize +Display the uncompressed size of each entry. + +.TP +.PD 0 +.B \-dv +.TP +.PD +.B \-\-display-volume +Display the volume (disk) number each entry is being read from, +if reading an existing archive, and being written to. + +.TP +.PD 0 +.B \-D +.TP +.PD +.B \-\-no-dir-entries +Do not create entries in the +.I zip +archive for directories. Directory entries are created by default so that +their attributes can be saved in the zip archive. +The environment variable ZIPOPT can be used to change the default options. For +example under Unix with sh: +.RS +.IP +ZIPOPT="-D"; export ZIPOPT +.RE +.IP +(The variable ZIPOPT can be used for any option, including \fB\-i\fP and \fB\-x\fP +using a new option format detailed below, and can include several options.) The option +.B \-D +is a shorthand +for +.B \-x +"*/" but the latter previously could not be set as default in the ZIPOPT +environment variable as the contents of ZIPOPT gets inserted near the beginning +of the command line and the file list had to end at the end of the line. +.IP +This version of +.I zip +does allow +.B \-x +and +.B \-i +options in ZIPOPT if the form +.IP +\fC +.BR \-x \ file\ file\ ... \ @\fP +.IP +is used, where the @ (an argument that is just @) terminates +the list. + +.TP +.PD 0 +.B \-DF +.TP +.PD +.B \-\-difference-archive +Create an archive that contains all new and changed files since +the original archive was created. For this to work, the input +file list and current directory must be the same as during the +original \fIzip\fP operation. +.IP +For example, if the existing archive was created using +.RS +.IP +\fCzip -r foofull . +.RE +.IP +from the \fIbar\fP directory, then the command +.RS +.IP +\fCzip -r foofull . -DF --out foonew +.RE +.IP +also from the \fIbar\fP directory creates the archive \fIfoonew\fP +with just the files not in \fIfoofull\fP and the files where +the size or file time of the files do not match those in \fIfoofull\fP. + +Note that the timezone environment variable TZ should be set according to +the local timezone in order for this option to work correctly. A +change in timezone since the original archive was created could +result in no times matching and all files being included. + +A possible approach to backing up a directory might be to create +a normal archive of the contents of the directory as a full +backup, then use this option to create incremental backups. + +.TP +.PD 0 +.B \-e +.TP +.PD +.B \-\-encrypt +Encrypt the contents of the +.I zip +archive using a password which is entered on the terminal in response +to a prompt +(this will not be echoed; if standard error is not a tty, +.I zip +will exit with an error). +The password prompt is repeated to save the user from typing errors. + +.TP +.PD 0 +.B \-E +.TP +.PD +.B \-\-longnames +[OS/2] Use the .LONGNAME Extended Attribute (if found) as filename. + +.TP +.PD 0 +.B \-f +.TP +.PD +.B \-\-freshen +Replace (freshen) an existing entry in the +.I zip +archive only if it has been modified more recently than the +version already in the +.I zip +archive; +unlike the update option +.RB ( \-u ) +this will not add files that are not already in the +.I zip +archive. +For example: +.RS +.IP +\fCzip -f foo\fP +.RE +.IP +This command should be run from the same directory from which the original +.I zip +command was run, since paths stored in +.I zip +archives are always relative. +.IP +Note that the timezone environment variable TZ should be set according to +the local timezone in order for the +\fB\-f\fP, \fB\-u\fP and \fB\-o\fP +options to work correctly. +.IP +The reasons behind this are somewhat subtle but have to do with the differences +between the Unix-format file times (always in GMT) and most of the other +operating systems (always local time) and the necessity to compare the two. +A typical TZ value is ``MET-1MEST'' (Middle European time with automatic +adjustment for ``summertime'' or Daylight Savings Time). +.IP +The format is TTThhDDD, where TTT is the time zone such as MET, hh is the +difference between GMT and local time such as -1 above, and DDD is +the time zone when daylight savings time is in effect. Leave off +the DDD if there is no daylight savings time. For the US Eastern +time zone EST5EDT. + +.TP +.PD 0 +.B \-F +.TP +.B \-\-fix\ \ \ \ \ \ +.TP +.B \-FF +.TP +.PD +.B \-\-fixfix\ \ +Fix the +.I zip +archive. The \fB\-F\fP option can be used if some portions of the archive +are missing, but requires a reasonably intact central directory. +The input archive is scanned as usual, but \fIzip\fP will ignore +some problems. The resulting archive should be valid, but any +inconsistent entries will be left out. +.IP +When doubled as in +\fB\-FF\fP, +the archive is scanned from the beginning and \fIzip\fP scans for special +signatures to identify the limits between the archive members. The +single +.B \-F +is more reliable if the archive is not too much damaged, so try this +option first. +.IP +If the archive is too damaged or the end has been truncated, you +must use \fB\-FF\fP. This is a change from \fIzip\ 2.32\fP, where +the \fB\-F\fP option is able to read a truncated archive. The +\fB\-F\fP option now more reliably fixes archives with minor +damage and the \fB\-FF\fP option is needed to fix archives where +\fB\-F\fP might have been sufficient before. +.IP +Neither option will recover archives that have been incorrectly +transferred in ascii mode instead of binary. After the repair, the +.B \-t +option of +.I unzip +may show that some files have a bad CRC. Such files cannot be recovered; +you can remove them from the archive using the +.B \-d +option of +\fIzip\fP. +.IP +Note that \fB\-FF\fP may have trouble fixing archives that include an +embedded zip archive that was stored (without compression) in the archive +and, depending on the damage, it may find the entries in the embedded +archive rather than the archive itself. Try \fB\-F\fP first as it +does not have this problem. +.IP +The format of the fix commands have changed. For example, to fix +the damaged archive \fIfoo.zip\fP, +.RS +.IP +\fCzip -F foo --out foofix +.RE +.IP +tries to read the entries normally, copying good entries to the +new archive \fIfoofix.zip\fP. If this doesn't work, as when the +archive is truncated, or if some entries you know are in the archive +are missed, then try +.RS +.IP +\fCzip -FF foo --out foofixfix +.RE +.IP +and compare the resulting archive to the archive created by \fB\-F\fP. The +\fB\-FF\fP option may create an inconsistent archive. Depending on +what is damaged, you can then use the \fB\-F\fP option to fix that archive. +.IP +A split archive with missing split files can be fixed using +\fB\-F\fP if you have the last split of the archive (the \fB\.zip\fP file). +If this file is missing, you must use \fB\-FF\fP to fix the archive, +which will prompt you for the splits you have. +.IP +Currently the fix options can't recover entries that have a bad checksum +or are otherwise damaged. + +.TP +.PD 0 +.B \-FI +.TP +.PD +.B \-\-fifo +[Unix] Normally \fIzip\fP skips reading any FIFOs (named pipes) encountered, as +\fIzip\fP can hang if the FIFO is not being fed. This option tells \fIzip\fP to +read the contents of any FIFO it finds. + +.TP +.PD 0 +.B \-FS +.TP +.PD +.B \-\-filesync +Synchronize the contents of an archive with the files on the OS. +Normally when an archive is updated, new files are added and changed +files are updated but files that no longer exist on the OS are not +deleted from the archive. This option enables a new mode that checks +entries in the archive against the file system. If the file time and +file size of the entry matches that of the OS file, the entry is +copied from the old archive instead of being read from the file system +and compressed. If the OS file has changed, the entry is read and +compressed as usual. If the entry in the archive does not match a +file on the OS, the entry is deleted. Enabling this option should +create archives that are the same as new archives, but since existing +entries are copied instead of compressed, updating an existing archive +with \fB\-FS\fP can be much faster than creating a new archive. Also +consider using \fB\-u\fP for updating an archive. +.IP +For this option to work, the archive should be updated from the same +directory it was created in so the relative paths match. If few files +are being copied from the old archive, it may be faster to create a +new archive instead. +.IP +Note that the timezone environment variable TZ should be set according to +the local timezone in order for this option to work correctly. A +change in timezone since the original archive was created could +result in no times matching and recompression of all files. +.IP +This option deletes files from the archive. If you need to preserve +the original archive, make a copy of the archive first or use the +\fB\-\-out\fP option to output the updated archive to a new file. +Even though it may be slower, creating a new archive with a new archive +name is safer, avoids mismatches between archive and OS paths, and +is preferred. + +.TP +.PD 0 +.B \-g +.TP +.PD +.B \-\-grow \ \ \ \ \ \ +Grow (append to) the specified +.I zip +archive, instead of creating a new one. If this operation fails, +.I zip +attempts to restore the archive to its original state. If the restoration +fails, the archive might become corrupted. This option is ignored when +there's no existing archive or when at least one archive member must be +updated or deleted. + +.TP +.PD 0 +.B \-h +.TP +.PD 0 +.B \-? +.TP +.PD +.B \-\-help \ \ \ \ \ \ +Display the +.I zip +help information (this also appears if +.I zip +is run with no arguments). + +.TP +.PD 0 +.B \-h2 +.TP +.PD +.B \-\-more-help +Display extended help including more on command line format, pattern matching, and +more obscure options. + +.TP +.PD 0 +.B \-i\ \fRfiles +.TP +.PD +.B \-\-include\ \fRfiles +Include only the specified files, as in: +.RS +.IP +\fCzip -r foo . -i \\*.c\fP +.RE +.IP +which will include only the files that end in +.IR \& .c +in the current directory and its subdirectories. (Note for PKZIP +users: the equivalent command is +.RS +.IP +\fCpkzip -rP foo *.c\fP +.RE +.IP +PKZIP does not allow recursion in directories other than the current one.) +The backslash avoids the shell filename substitution, so that the +name matching is performed by +.I zip +at all directory levels. +[This is for Unix and other systems where \\ escapes the +next character. For other systems where the shell does not +process * do not use \\ and the above is +.RS +.IP +\fCzip -r foo . -i *.c\fP +.RE +.IP +Examples are for Unix unless otherwise specified.] So to include dir, +a directory directly under the current directory, use +.RS +.IP +\fCzip -r foo . -i dir/\\* +.RE +.IP +or +.RS +.IP +\fCzip -r foo . -i "dir/*" +.RE +.IP +to match paths such as dir/a and dir/b/file.c [on +ports without wildcard expansion in the shell such as MSDOS and Windows +.RS +.IP +\fCzip -r foo . -i dir/* +.RE +.IP +is used.] Note that currently the trailing / is needed +for directories (as in +.RS +.IP +\fCzip -r foo . -i dir/ +.RE +.IP +to include directory dir). +.IP +The long option form of the first example is +.RS +.IP +\fCzip -r foo . --include \\*.c +.RE +.IP +and does the same thing as the short option form. +.IP +Though the command syntax used to require \fB-i\fR at +the end of the command line, this version actually +allows \fB\-i\fP (or \fB\-\-include\fP) anywhere. The +list of files terminates at the next argument starting +with \fB-\fR, the end of the command line, or the list +terminator \fB@\fR (an argument that is just @). So +the above can be given as +.RS +.IP +zip -i \\*.c @ -r foo .\fP +.RE +.IP +for example. There must be a space between +the option and the first file of a list. For just +one file you can use the single value form +.RS +.IP +\fCzip -i\\*.c -r foo .\fP +.RE +.IP +(no space between option and value) or +.RS +.IP +\fCzip --include=\\*.c -r foo .\fP +.RE +.IP +as additional examples. The single value forms are +not recommended because they can be confusing and, +in particular, the \fB\-ifile\fP format can cause +problems if the first letter of \fBfile\fP combines with +\fBi\fP to form a two-letter option starting with +\fBi\fP. Use \fB\-sc\fP to see how your command line +will be parsed. +.IP +Also possible: +.RS +.IP +\fCzip -r foo . -i@include.lst\fP +.RE +.IP +which will only include the files in the current directory and its +subdirectories that match the patterns in the file include.lst. +.IP +Files to \fB\-i\fR and \fB\-x\fR are patterns matching internal archive paths. See +\fB-R\fR for more on patterns. + +.TP +.PD 0 +.B \-I +.TP +.PD +.B \-\-no-image +[Acorn RISC OS] Don't scan through Image files. When used, \fIzip\fP will not +consider Image files (eg. DOS partitions or Spark archives when SparkFS +is loaded) as directories but will store them as single files. + +For example, if you have 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. + +.TP +.PD 0 +.B \-ic +.TP +.PD +.B \-\-ignore-case +[VMS, WIN32] Ignore case when matching archive entries. This option is +only available on systems where the case of files is ignored. On systems +with case-insensitive file systems, case is normally ignored when matching files +on the file system but is not ignored for -f (freshen), -d (delete), -U (copy), +and similar modes when matching against archive entries (currently -f +ignores case on VMS) because archive entries can be from systems where +case does matter and names that are the same except for case can exist +in an archive. The \fB\-ic\fR option makes all matching case insensitive. +This can result in multiple archive entries matching a command line pattern. + +.TP +.PD 0 +.B \-j +.TP +.PD +.B \-\-junk-paths +Store just the name of a saved file (junk the path), and do not store +directory names. By default, +.I zip +will store the full path (relative to the current directory). + +.TP +.PD 0 +.B \-jj +.TP +.PD +.B \-\-absolute-path +[MacOS] record Fullpath (+ Volname). The complete path including +volume will be stored. By default the relative path will be stored. + +.TP +.PD 0 +.B \-J +.TP +.PD +.B \-\-junk-sfx +Strip any prepended data (e.g. a SFX stub) from the archive. +.TP +.PD 0 +.B \-k +.TP +.PD +.B \-\-DOS-names +Attempt to convert the names and paths to conform to MSDOS, +store only the MSDOS attribute (just the user write attribute from Unix), +and mark the entry as made under MSDOS (even though it was not); +for compatibility with PKUNZIP under MSDOS which cannot handle certain +names such as those with two dots. +.TP +.PD 0 +.B \-l +.TP +.PD +.B \-\-to-crlf +Translate the Unix end-of-line character LF into the +MSDOS convention CR LF. This option should not be used on binary files. +This option can be used on Unix if the zip file is intended for PKUNZIP +under MSDOS. If the input files already contain CR LF, this option adds +an extra CR. This is to ensure that +\fBunzip -a\fP +on Unix will get back an exact copy of the original file, +to undo the effect of +\fBzip -l\fP. See \fB-ll\fR for how binary files are handled. +.TP +.PD 0 +.B \-la +.TP +.PD +.B \-\-log-append +Append to existing logfile. Default is to overwrite. +.TP +.PD 0 +.B \-lf\ \fPlogfilepath +.TP +.PD +.B \-\-logfile-path\ \fPlogfilepath +Open a logfile at the given path. By default any existing file at that location +is overwritten, but the \fB\-la\fP option will result in an existing file being +opened and the new log information appended to any existing information. +Only warnings and errors are written to the log unless the \fB\-li\fP option is +also given, then all information messages are also written to the log. +.TP +.PD 0 +.B \-li +.TP +.PD +.B \-\-log-info +Include information messages, such as file names being zipped, in the log. +The default is to only include the command line, any warnings and errors, and +the final status. +.TP +.PD 0 +.B \-ll +.TP +.PD +.B \-\-from-crlf +Translate the MSDOS end-of-line CR LF into Unix LF. +This option should not be used on binary files. +This option can be used on MSDOS if the zip file is intended for unzip +under Unix. If the file is converted and the file is later determined +to be binary a warning is issued and the file is probably +corrupted. In this release if \fB-ll\fR detects binary in the first buffer +read from a file, \fIzip\fR now issues a warning and skips line end +conversion on the file. This check seems to catch all binary files +tested, but the original check remains and if a converted file is +later determined to be binary that warning is still issued. A new algorithm +is now being used for binary detection that should allow line end conversion +of text files in \fBUTF-8\fR and similar encodings. +.TP +.PD 0 +.B \-L +.TP +.PD +.B \-\-license +Display the +.I zip +license. +.TP +.PD 0 +.B \-m +.TP +.PD +.B \-\-move \ \ \ +Move the specified files into the +.I zip +archive; actually, +this deletes the target directories/files after making the specified +.I zip +archive. If a directory becomes empty after removal of the files, the +directory is also removed. No deletions are done until +.I zip +has created the archive without error. +This is useful for conserving disk space, +but is potentially dangerous so it is recommended to use it in +combination with +.B \-T +to test the archive before removing all input files. +.TP +.PD 0 +.B \-MM +.TP +.PD +.B \-\-must-match +All input patterns must match at least one file and all input files +found must be readable. Normally when an input pattern does not match +a file the "name not matched" warning is issued and when an input file +has been found but later is missing or not readable a missing or not +readable warning is issued. In either case +.I zip +continues creating the archive, with missing or unreadable new files +being skipped and files already in the archive remaining unchanged. +After the archive is created, if any files were not readable +.I zip +returns the OPEN error code (18 on most systems) instead of the normal +success return (0 on most systems). With \fB\-MM\fP set, +.I zip +exits as soon as an input pattern is not matched (whenever the +"name not matched" warning would be issued) or when an input file is +not readable. In either case \fIzip\fR exits with an OPEN error +and no archive is created. +.IP +This option is useful when a known list of files is to be zipped so +any missing or unreadable files will result in an error. It is less +useful when used with wildcards, but \fIzip\fR will still exit with an +error if any input pattern doesn't match at least one file and if any +matched files are unreadable. If you want to create the archive +anyway and only need to know if files were skipped, don't use +.B \-MM +and just check the return code. Also \fB\-lf\fP could be useful. +.TP +.PD 0 +.BI \-n\ \fRsuffixes +.TP +.PD +.B \-\-suffixes\ \fRsuffixes +Do not attempt to compress files named with the given +\fBsuffixes\fR. +Such files are simply stored (0% compression) in the output zip file, +so that +.I zip +doesn't waste its time trying to compress them. +The suffixes are separated by +either colons or semicolons. For example: +.RS +.IP +\fCzip -rn .Z:.zip:.tiff:.gif:.snd foo foo\fP +.RE +.IP +will copy everything from +.I foo +into +.IR foo.zip , +but will store any files that end in +.IR .Z , +.IR .zip , +.IR .tiff , +.IR .gif , +or +.I .snd +without trying to compress them +(image and sound files often have their own specialized compression methods). +By default, +.I zip +does not compress files with extensions in the list +.I .Z:.zip:.zoo:.arc:.lzh:.arj. +Such files are stored directly in the output archive. +The environment variable ZIPOPT can be used to change the default options. For +example under Unix with csh: +.RS +.IP +setenv ZIPOPT "-n .gif:.zip" +.RE +.IP +To attempt compression on all files, use: +.RS +.IP +zip -n : foo +.RE +.IP +The maximum compression option +.B \-9 +also attempts compression on all files regardless of extension. +.IP +On Acorn RISC OS systems the suffixes are actually filetypes (3 hex digit +format). By default, \fIzip\fP does not compress files with filetypes in the list +DDC:D96:68E (i.e. Archives, CFS files and PackDir files). +.TP +.PD 0 +.B \-nw +.TP +.PD +.B \-\-no-wild +Do not perform internal wildcard processing (shell processing of wildcards is still done +by the shell unless the arguments are escaped). Useful if a list of paths is being +read and no wildcard substitution is desired. +.TP +.PD 0 +.B \-N +.TP +.PD +.B \-\-notes +[Amiga, MacOS] Save Amiga or MacOS filenotes as zipfile comments. They can be +restored by using the -N option of \fIunzip\fP. If -c is used also, you are +prompted for comments only for those files that do not have filenotes. +.TP +.PD 0 +.B \-o +.TP +.PD +.B \-\-latest-time +Set the "last modified" time of the +.I zip +archive to the latest (oldest) "last modified" time +found among the entries in the +.I zip +archive. +This can be used without any other operations, if desired. +For example: +.IP +\fCzip -o foo\fP +.IP +will change the last modified time of +\fBfoo.zip\fP +to the latest time of the entries in +.BR foo.zip . +.TP +.PD 0 +.B \-O \fPoutput-file +.TP +.PD +.B \-\-output-file \fPoutput-file +Process the archive changes as usual, but instead of updating the existing archive, +output the new archive to output-file. Useful for updating an archive +without changing the existing archive and the input archive must be a different file +than the output archive. + +This option can be used to create updated split archives. +It can also be used with \fB\-U\fP to copy entries from an existing archive to a new +archive. See the \fBEXAMPLES\fP section below. + +Another use is converting \fIzip\fP files from one split size to another. For instance, +to convert an archive with 700 MB CD splits to one with 2 GB DVD splits, can use: +.RS +.IP +zip -s 2g cd-split.zip --out dvd-split.zip +.RE +.IP +which uses copy mode. See \fB\-U\fP below. Also: +.RS +.IP +zip -s 0 split.zip --out unsplit.zip +.RE +.IP +will convert a split archive to a single-file archive. + +Copy mode will convert stream entries (using data descriptors and which +should be compatible with most unzips) to normal entries (which should +be compatible +with all unzips), except if standard encryption was used. For archives +with encrypted entries, \fIzipcloak\fP will decrypt the entries and convert +them to normal entries. +.TP +.PD 0 +.B \-p +.TP +.PD +.B \-\-paths +Include relative file paths as part of the names of files stored in the archive. +This is the default. The \fB\-j\fP option junks the paths and just stores the +names of the files. +.TP +.PD 0 +.B \-P\ \fRpassword +.TP +.PD +.B \-\-password\ \fRpassword +Use \fIpassword\fP to encrypt zipfile entries (if any). \fBTHIS IS +INSECURE!\fP Many multi-user operating systems provide ways for any user to +see the current command line of any other user; even on stand-alone systems +there is always the threat of over-the-shoulder peeking. Storing the plaintext +password as part of a command line in an automated script is even worse. +Whenever possible, use the non-echoing, interactive prompt to enter passwords. +(And where security is truly important, use strong encryption such as Pretty +Good Privacy instead of the relatively weak standard encryption provided by +zipfile utilities.) +.TP +.PD 0 +.B \-q +.TP +.PD +.B \-\-quiet +Quiet mode; +eliminate informational messages and comment prompts. +(Useful, for example, in shell scripts and background tasks). +.TP +.PD 0 +.BI \-Q\fRn +.TP +.PD +.B \-\-Q\-flag\ \fRn +[QDOS] store information about the file in the file header with n defined as +.RS +bit 0: Don't add headers for any file +.RE +.RS +bit 1: Add headers for all files +.RE +.RS +bit 2: Don't wait for interactive key press on exit +.RE +.TP +.PD 0 +.B \-r +.TP +.PD +.B \-\-recurse\-paths +Travel the directory structure recursively; +for example: +.RS +.IP +zip -r foo.zip foo +.RE +.IP +or more concisely +.RS +.IP +zip -r foo foo +.RE +.IP +In this case, all the files and directories in +.B foo +are saved in a +.I zip +archive named \fBfoo.zip\fP, +including files with names starting with \fB"."\fP, +since the recursion does not use the shell's file-name substitution mechanism. +If you wish to include only a specific subset of the files in directory +\fBfoo\fP +and its subdirectories, use the +\fB\-i\fP +option to specify the pattern of files to be included. +You should not use +\fB\-r\fP +with the name \fB".*"\fP, +since that matches \fB".."\fP +which will attempt to zip up the parent directory +(probably not what was intended). +.IP +Multiple source directories are allowed as in +.RS +.IP +\fCzip -r foo foo1 foo2\fP +.RE +.IP +which first zips up \fBfoo1\fP and then \fBfoo2\fP, going down each directory. +.IP +Note that while wildcards to \fB-r\fR are typically resolved while recursing down +directories in the file system, any \fB-R\fN, \fB-x\fR, and \fB-i\fR wildcards +are applied to internal archive pathnames once the directories are scanned. +To have wildcards apply to files in subdirectories when recursing on +Unix and similar systems where the shell does wildcard substitution, either +escape all wildcards or put all arguments with wildcards in quotes. This lets +\fIzip\fR see the wildcards and match files in subdirectories using them as +it recurses. +.TP +.PD 0 +.B \-R +.TP +.PD +.B \-\-recurse\-patterns +Travel the directory structure recursively starting at the +current directory; +for example: +.RS +.IP +\fCzip -R foo "*.c"\fP +.RE +.IP +In this case, all the files matching \fB*.c\fP in the tree starting at the +current directory are stored into a +.I zip +archive named +\fBfoo.zip\fP. +Note that \fB*.c\fP will match \fBfile.c\fP, \fBa/file.c\fP +and \fBa/b/.c\fP. More than one pattern can be listed as separate +arguments. +Note for PKZIP users: the equivalent command is +.RS +.IP +\fCpkzip -rP foo *.c\fP +.RE +.IP +Patterns are relative file paths as they appear in the archive, or will after +zipping, and can have optional wildcards in them. For example, given +the current directory is \fBfoo\fP and under it are directories \fBfoo1\fP and \fBfoo2\fP +and in \fBfoo1\fP is the file \fBbar.c\fP, +.RS +.IP +\fCzip -R foo/*\fP +.RE +.IP +will zip up \fBfoo\fP, \fBfoo/foo1\fP, \fBfoo/foo1/bar.c\fP, and \fBfoo/foo2\fP. +.RS +.IP +\fCzip -R */bar.c\fP +.RE +.IP +will zip up \fBfoo/foo1/bar.c\fP. See the note for \fB-r\fR on escaping wildcards. + +.TP +.PD 0 +.B \-RE +.TP +.PD +.B \-\-regex +[WIN32] Before \fIzip\fP \fI3.0\fP, regular expression list matching was +enabled by default on Windows platforms. Because of confusion resulting +from the need to escape "[" and "]" in names, it is now off by default for +Windows so "[" and "]" are just normal characters in names. This option +enables [] matching again. + +.TP +.PD 0 +.B \-s\ \fPsplitsize +.TP +.PD +.B \-\-split\-size\ \fPsplitsize +Enable creating a split archive and set the split size. A split archive is an archive +that could be split over many files. As the archive is created, if the size of the +archive reaches the specified split size, that split is closed and the next split +opened. In general all splits but the last will be the split size and the last +will be whatever is left. If the entire archive is smaller than the split size a +single-file archive is created. + +Split archives are stored in numbered files. For example, if the output +archive is named \fBarchive\fP and three splits are required, the resulting +archive will be in the three files \fBarchive.z01\fP, \fBarchive.z02\fP, and +\fBarchive.zip\fP. Do not change the numbering of these files or the archive +will not be readable as these are used to determine the order the splits are read. + +Split size is a number optionally followed by a multiplier. Currently the +number must be an integer. The multiplier can currently be one of +\fBk\fP (kilobytes), \fBm\fP (megabytes), \fBg\fP (gigabytes), or \fBt\fP +(terabytes). As 64k is the minimum split size, numbers without multipliers +default to megabytes. For example, to create a split archive called \fBfoo\fP +with the contents of the \fBbar\fP directory with splits of 670 MB that might +be useful for burning on CDs, the command: +.RS +.IP +zip -s 670m -r foo bar +.RE +.IP +could be used. + +Currently the old splits of a split archive are not excluded from a new +archive, but they can be specifically excluded. If possible, keep +the input and output archives out of the path being zipped when creating +split archives. + +Using \fB\-s\fP without \fB\-sp\fP as above creates all the splits where +\fBfoo\fP is being written, in this case the current directory. This split +mode updates the splits as the archive is being created, requiring all +splits to remain writable, but creates split archives that are readable by +any unzip that supports split archives. See \fB\-sp\fP below for enabling +split pause mode which allows splits to be written directly to removable +media. + +The option \fB\-sv\fP can be used to enable verbose splitting and provide details of +how the splitting is being done. The \fB\-sb\fP option can be used to ring the bell +when \fIzip\fP pauses for the next split destination. + +Split archives cannot be updated, but see the \fB\-O\fP (\fB\-\-out\fP) option for +how a split archive can be updated as it is copied to a new archive. +A split archive can also be converted into a single-file archive using a +split size of 0 or negating the \fB\-s\fP option: +.RS +.IP +zip -s 0 split.zip --out single.zip +.RE +.IP +Also see \fB\-U\fP (\fB\-\-copy\fP) for more on using copy mode. +.TP +.PD 0 +.B \-sb +.TP +.PD +.B \-\-split\-bell +If splitting and using split pause mode, ring the bell when \fIzip\fP pauses +for each split destination. +.TP +.PD 0 +.B \-sc +.TP +.PD +.B \-\-show\-command +Show the command line starting \fIzip\fP as processed and exit. The new command parser +permutes the arguments, putting all options and any values associated with them +before any non-option arguments. This allows an option to appear anywhere in the +command line as long as any values that go with the option go with it. This option +displays the command line as \fIzip\fP sees it, including any arguments from +the environment such as from the \fBZIPOPT\fP variable. Where allowed, options later +in the command line can override options earlier in the command line. +.TP +.PD 0 +.B \-sf +.TP +.PD +.B \-\-show\-files +Show the files that would be operated on, then exit. For instance, if creating +a new archive, this will list the files that would be added. If the option is +negated, \fB\-sf\-\fP, output only to an open log file. Screen display is +not recommended for large lists. +.TP +.PD 0 +.B \-so +.TP +.PD +.B \-\-show\-options +Show all available options supported by \fIzip\fP as compiled on the current system. +As this command reads the option table, it should include all options. Each line +includes the short option (if defined), the long option (if defined), the format +of any value that goes with the option, if the option can be negated, and a +small description. The value format can be no value, required value, optional +value, single character value, number value, or a list of values. The output of +this option is not intended to show how to use any option but only +show what options are available. +.TP +.PD 0 +.B \-sp +.TP +.PD +.B \-\-split\-pause +If splitting is enabled with \fB\-s\fP, enable split pause mode. This +creates split archives as \fB\-s\fP does, but stream writing is used so each +split can be closed as soon as it is written and \fIzip\fP will pause between each +split to allow changing split destination or media. + +Though this split mode allows writing splits directly to removable media, it +uses stream archive format that may not be readable by some unzips. Before +relying on splits created with \fB\-sp\fP, test a split archive with the unzip +you will be using. + +To convert a stream split archive (created with \fB\-sp\fP) to a standard archive +see the \fB\-\-out\fP option. +.TP +.PD 0 +.B \-su +.TP +.PD +.B \-\-show\-unicode +As \fB\-sf\fP, but also show Unicode version of the path if exists. +.TP +.PD 0 +.B \-sU +.TP +.PD +.B \-\-show\-just\-unicode +As \fB\-sf\fP, but only show Unicode version of the path if exists, otherwise show +the standard version of the path. +.TP +.PD 0 +.B \-sv +.TP +.PD +.B \-\-split\-verbose +Enable various verbose messages while splitting, showing how the splitting is being +done. +.TP +.PD 0 +.B \-S +.TP +.PD +.B \-\-system-hidden +[MSDOS, OS/2, WIN32 and ATARI] Include system and hidden files. +.RS +[MacOS] Includes finder invisible files, which are ignored otherwise. +.RE +.TP +.PD 0 +.BI \-t\ \fRmmddyyyy +.TP +.PD +.B \-\-from\-date\ \fRmmddyyyy +Do not operate on files modified prior to the specified date, +where +.B mm +is the month (00-12), +.B dd +is the day of the month (01-31), +and +.B yyyy +is the year. +The +.I ISO\ 8601 +date format +.B yyyy\-mm\-dd +is also accepted. +For example: +.RS +.IP +\fCzip -rt 12071991 infamy foo\fP + +\fCzip -rt 1991-12-07 infamy foo\fP +.RE +.IP +will add all the files in +.B foo +and its subdirectories that were last modified on or after 7 December 1991, +to the +.I zip +archive +.BR infamy.zip . +.TP +.PD 0 +.BI \-tt\ \fRmmddyyyy +.TP +.PD +.B \-\-before\-date\ \fRmmddyyyy +Do not operate on files modified after or at the specified date, +where +.B mm +is the month (00-12), +.B dd +is the day of the month (01-31), +and +.B yyyy +is the year. +The +.I ISO\ 8601 +date format +.B yyyy\-mm\-dd +is also accepted. +For example: +.RS +.IP +\fCzip -rtt 11301995 infamy foo\fP + +\fCzip -rtt 1995-11-30 infamy foo\fP +.RE +.IP +will add all the files in +.B foo +and its subdirectories that were last modified before 30 November 1995, +to the +.I zip +archive +.BR infamy.zip . +.TP +.PD 0 +.B \-T +.TP +.PD +.B \-\-test\ \ \ \ +Test the integrity of the new zip file. If the check fails, the old zip file +is unchanged and (with the +.B -m +option) no input files are removed. +.TP +.PD 0 +.B \-TT\ \fPcmd +.TP +.PD +.B \-\-unzip-command\ \fPcmd +Use command cmd instead of 'unzip -tqq' to test an archive when the \fB\-T\fP +option is used. On Unix, to use a copy of unzip in the current directory instead +of the standard system unzip, could use: +.IP +\fC zip archive file1 file2 -T -TT "./unzip -tqq"\fP +.IP +In cmd, {} is replaced by the name of the temporary archive, otherwise the name +of the archive is appended to the end of the command. +The return code is checked for success (0 on Unix). +.TP +.PD 0 +.B \-u +.TP +.PD +.B \-\-update +Replace (update) an existing entry in the +.I zip +archive only if it has been modified more recently +than the version already in the +.I zip +archive. +For example: +.RS +.IP +\fCzip -u stuff *\fP +.RE +.IP +will add any new files in the current directory, +and update any files which have been modified since the +.I zip +archive +.I stuff.zip +was last created/modified (note that +.I zip +will not try to pack +.I stuff.zip +into itself when you do this). +.IP +Note that the +.B \-u +option with no input file arguments acts like the +.B \-f +(freshen) option. +.TP +.PD 0 +.B \-U +.TP +.PD +.B \-\-copy\-entries +Copy entries from one archive to another. Requires the \fB\-\-out\fP +option to specify a different output file than the input archive. Copy +mode is the reverse of \fB\-d\fP delete. When delete is being used +with \fB\-\-out\fP, the selected entries are deleted from the archive +and all other entries are copied to the new archive, while copy mode +selects the files to include in the new archive. Unlike \fB\-u\fP +update, input patterns on the command line are matched against archive +entries only and not the file system files. For instance, +.RS +.IP +\fCzip inarchive "*.c" --copy --out outarchive\fP +.RE +.IP +copies entries with names ending in \fB\.c\fP from \fBinarchive\fP +to \fBoutarchive\fP. The wildcard must be escaped on some systems +to prevent the shell from substituting names of files from the +file system which may have no relevance to the entries in the archive. + +If no input files appear on the command line and \fB\-\-out\fP is +used, copy mode is assumed: +.RS +.IP +\fCzip inarchive --out outarchive\fP +.RE +.IP +This is useful for changing split size for instance. Encrypting +and decrypting entries is not yet supported using copy mode. Use +\fIzipcloak\fP for that. +.TP +.PD 0 +.B \-UN\ \fRv +.TP +.PD +.B \-\-unicode\ \fRv +Determine what \fIzip\fP should do with Unicode file names. +\fIzip\ 3.0\fP, in addition to the standard file path, now +includes the UTF\-8 translation of the path if the entry path +is not entirely 7-bit ASCII. When an entry +is missing the Unicode path, \fIzip\fP reverts back to the +standard file path. The problem with using the standard path +is this path is in the local character set of the zip that created +the entry, which may contain characters that are not valid in +the character set being used by the unzip. When \fIzip\fP is +reading an archive, if an entry also has a Unicode path, +\fIzip\fP now defaults to using the Unicode path to recreate +the standard path using the current local character set. + +This option can be used to determine what \fIzip\fP should do +with this path if there is a mismatch between the stored standard path +and the stored UTF-8 path (which can happen if the standard path was +updated). In all cases, if there is a mismatch it is +assumed that the standard path is more current and +\fIzip\fP uses that. Values for \fBv\fP are +.RS +.IP +q \- quit if paths do not match +.IP +w \- warn, continue with standard path +.IP +i \- ignore, continue with standard path +.IP +n \- no Unicode, do not use Unicode paths +.RE +.IP +The default is to warn and continue. + +Characters that are not valid in the current character set are +escaped as \fB#Uxxxx\fP and \fB#Lxxxxxx\fP, where x is an +ASCII character for a hex digit. The first is used if a 16-bit +character number is sufficient to represent the Unicode character +and the second if the character needs more than 16 bits to +represent it's Unicode character code. Setting \fB\-UN\fP to +.RS +.IP +e \- escape +.RE +.IP +as in +.RS +.IP +\fCzip archive -sU -UN=e\fP +.RE +.IP +forces \fIzip\fP to escape all characters that are not printable 7-bit +ASCII. + +Normally \fIzip\fP stores UTF\-8 directly in the standard path field +on systems where UTF\-8 is the current character set and stores the +UTF\-8 in the new extra fields otherwise. The option +.RS +.IP +u \- UTF\-8 +.RE +.IP +as in +.RS +.IP +\fCzip archive dir -r -UN=UTF8\fP +.RE +.IP +forces \fIzip\fP to store UTF\-8 as native in the archive. Note that +storing UTF\-8 directly is the default on Unix systems that support it. +This option could be useful on Windows systems where the escaped +path is too large to be a valid path and the UTF\-8 version of the +path is smaller, but native UTF\-8 is not backward compatible on +Windows systems. + +.TP +.PD 0 +.B \-v +.TP +.PD +.B \-\-verbose +Verbose mode or print diagnostic version info. +.IP +Normally, when applied to real operations, this option enables the display of a +progress indicator during compression (see \fB-dd\fR for more on dots) and +requests verbose diagnostic info about zipfile structure oddities. +.IP +However, when +.B \-v +is the only command line argument a diagnostic screen is printed instead. This +should now work even if stdout is redirected to a file, allowing easy saving +of the information for sending with bug reports to Info-ZIP. The version +screen provides the help screen header with program name, version, and release +date, some pointers to the Info-ZIP home and distribution sites, and shows +information about the target environment (compiler type and version, OS +version, compilation date and the enabled optional features used to create the +.I zip +executable). +.TP +.PD 0 +.B \-V +.TP +.PD +.B \-\-VMS\-portable +[VMS] Save VMS file attributes. +(Files are truncated at EOF.) When a -V archive is unpacked on a +non-VMS system, some file types (notably Stream_LF +text files and pure binary files like fixed-512) +should be extracted intact. Indexed files and file +types with embedded record sizes (notably variable-length record types) +will probably be seen as corrupt elsewhere. +.TP +.PD 0 +.B \-VV +.TP +.PD +.B \-\-VMS\-specific +[VMS] Save VMS file attributes, and all allocated +blocks in a file, including any data beyond EOF. +Useful for moving ill-formed files among VMS systems. When a -VV archive is +unpacked on a non-VMS system, almost all files will appear corrupt. +.TP +.PD 0 +.B \-w +.TP +.PD +.B \-\-VMS\-versions +[VMS] Append the version number of the files to the name, +including multiple versions of files. Default is to use only +the most recent version of a specified file. +.TP +.PD 0 +.B \-ww +.TP +.PD +.B \-\-VMS\-dot\-versions +[VMS] Append the version number of the files to the name, +including multiple versions of files, using the \.nnn format. +Default is to use only the most recent version of a specified +file. +.TP +.PD 0 +.BI \-ws +.TP +.PD +.B \-\-wild\-stop\-dirs +Wildcards match only at a directory level. Normally \fIzip\fP handles +paths as strings and given the paths +.RS +.IP +/foo/bar/dir/file1.c +.IP +/foo/bar/file2.c +.RE +.IP +an input pattern such as +.RS +.IP +/foo/bar/* +.RE +.IP +normally would match both paths, the * matching \fBdir/file1.c\fP +and \fBfile2.c\fP. Note that in the first case a directory +boundary (/) was crossed in the match. With \fB\-ws\fP no +directory bounds will be included in the match, making +wildcards local to a specific directory level. So, with +\fB\-ws\fP enabled, only the second path would be matched. + +When using \fB\-ws\fP, use ** to match across directory boundaries as +* does normally. +.TP +.PD 0 +.BI \-x\ \fRfiles +.TP +.PD +.B \-\-exclude\ \fRfiles +Explicitly exclude the specified files, as in: +.RS +.IP +\fCzip -r foo foo -x \\*.o\fP +.RE +.IP +which will include the contents of +.B foo +in +.B foo.zip +while excluding all the files that end in +\fB.o\fP. +The backslash avoids the shell filename substitution, so that the +name matching is performed by +.I zip +at all directory levels. +.IP +Also possible: +.RS +.IP +\fCzip -r foo foo -x@exclude.lst\fP +.RE +.IP +which will include the contents of +.B foo +in +.B foo.zip +while excluding all the files that match the patterns in the file +\fBexclude.lst\fP. +.IP +The long option forms of the above are +.RS +.IP +\fCzip -r foo foo --exclude \\*.o\fP +.RE +.IP +and +.RS +.IP +\fCzip -r foo foo --exclude @exclude.lst\fP +.RE +.IP +Multiple patterns can be specified, as in: +.RS +.IP +\fCzip -r foo foo -x \\*.o \\*.c\fP +.RE +.IP +If there is no space between \fB\-x\fP and +the pattern, just one value is assumed (no list): +.RS +.IP +\fCzip -r foo foo -x\\*.o\fP +.RE +.IP +.IP +See \fB-i\fR for more on include and exclude. +.TP +.PD 0 +.B \-X +.TP +.PD +.B \-\-no\-extra +Do not save extra file attributes (Extended Attributes on OS/2, uid/gid +and file times on Unix). The zip format uses extra fields to include +additional information for each entry. Some extra fields are specific +to particular systems while others are applicable to all systems. +Normally when \fIzip\fP reads entries from an existing archive, it +reads the extra fields it knows, strips the rest, and adds +the extra fields applicable to that system. With \fB\-X\fP, \fIzip\fP strips +all old fields and only includes the Unicode and Zip64 extra fields +(currently these two extra fields cannot be disabled). + +Negating this option, \fB\-X\-\fP, includes all the default extra fields, +but also copies over any unrecognized extra fields. +.TP +.PD 0 +.B \-y +.TP +.PD +.B \-\-symlinks +For UNIX and VMS (V8.3 and later), store symbolic links as such in the +.I zip +archive, instead of compressing and storing the file referred to by +the link. This can avoid multiple copies of files being included in +the archive as \fIzip\fP recurses the directory trees and accesses +files directly and by links. +.TP +.PD 0 +.B \-z +.TP +.PD +.B \-\-archive\-comment +Prompt for a multi-line comment for the entire +.I zip +archive. +The comment is ended by a line containing just a period, +or an end of file condition (^D on Unix, ^Z on MSDOS, OS/2, and VMS). +The comment can be taken from a file: +.RS +.IP +\fCzip -z foo < foowhat\fP +.RE +.TP +.PD 0 +.B \-Z\ \fRcm +.TP +.PD +.B \-\-compression\-method\ \fRcm +Set the default compression method. Currently the main methods supported +by \fIzip\fP are \fBstore\fP and \fBdeflate\fP. Compression method +can be set to: + +\fBstore\fP \- Setting the compression method to \fBstore\fP forces +\fIzip\fP to store entries with no compression. This is generally +faster than compressing entries, but results in no space savings. +This is the same as using \fB\-0\fP (compression level zero). + +\fBdeflate\fP \- This is the default method for \fIzip\fP. If \fIzip\fP +determines that storing is better than deflation, the entry will be +stored instead. + +\fBbzip2\fP \- If \fBbzip2\fP support is compiled in, this compression +method also becomes available. Only some modern unzips currently support +the \fBbzip2\fP compression method, so test the unzip you will be using +before relying on archives using this method (compression method 12). + +For example, to add \fBbar.c\fP to archive \fBfoo\fP using \fBbzip2\fP +compression: +.RS +.IP +zip -Z bzip2 foo bar.c +.RE +.IP +The compression method can be abbreviated: +.RS +.IP +zip -Zb foo bar.c +.RE +.IP +.TP +.PD 0 +.BI \-# +.TP +.PD +.B (\-0, \-1, \-2, \-3, \-4, \-5, \-6, \-7, \-8, \-9) +Regulate the speed of compression using the specified digit +.BR # , +where +.B \-0 +indicates no compression (store all files), +.B \-1 +indicates the fastest compression speed (less compression) +and +.B \-9 +indicates the slowest compression speed (optimal compression, ignores +the suffix list). The default compression level is +.BR \-6. + +Though still being worked, the intention is this setting will control +compression speed for all compression methods. Currently only +deflation is controlled. +.TP +.PD 0 +.B \-! +.TP +.PD +.B \-\-use\-privileges +[WIN32] Use priviliges (if granted) to obtain all aspects of WinNT security. +.TP +.PD 0 +.B \-@ +.TP +.PD +.B \-\-names\-stdin +Take the list of input files from standard input. Only one filename per line. +.TP +.PD 0 +.B \-$ +.TP +.PD +.B \-\-volume\-label +[MSDOS, OS/2, WIN32] Include the volume label for the drive holding +the first file to be compressed. If you want to include only the volume +label or to force a specific drive, use the drive name as first file name, +as in: +.RS +.IP +\fCzip -$ foo a: c:bar\fP +.RE +.IP +.SH "EXAMPLES" +The simplest example: +.IP +\fCzip stuff *\fP +.LP +creates the archive +.I stuff.zip +(assuming it does not exist) +and puts all the files in the current directory in it, in compressed form +(the +\fB\&.zip\fP +suffix is added automatically, unless the archive name contains +a dot already; +this allows the explicit specification of other suffixes). +.LP +Because of the way the shell on Unix does filename substitution, +files starting with "." are not included; +to include these as well: +.IP +\fCzip stuff .* *\fP +.LP +Even this will not include any subdirectories from the current directory. +.LP +To zip up an entire directory, the command: +.IP +\fCzip -r foo foo\fP +.LP +creates the archive +.IR foo.zip , +containing all the files and directories in the directory +.I foo +that is contained within the current directory. +.LP +You may want to make a +.I zip +archive that contains the files in +.IR foo , +without recording the directory name, +.IR foo . +You can use the +.B \-j +option to leave off the paths, +as in: +.IP +\fCzip -j foo foo/*\fP +.LP +If you are short on disk space, +you might not have enough room to hold both the original directory +and the corresponding compressed +.I zip +archive. +In this case, you can create the archive in steps using the +.B \-m +option. +If +.I foo +contains the subdirectories +.IR tom , +.IR dick , +and +.IR harry , +you can: +.IP +\fCzip -rm foo foo/tom\fP +.br +\fCzip -rm foo foo/dick\fP +.br +\fCzip -rm foo foo/harry\fP +.LP +where the first command creates +.IR foo.zip , +and the next two add to it. +At the completion of each +.I zip +command, +the last created archive is deleted, +making room for the next +.I zip +command to function. + + + +.LP +Use \fB\-s\fP to set the split size and create a split archive. The size is given as +a number followed optionally by one of k (kB), m (MB), g (GB), or t (TB). +The command +.IP +\fCzip -s 2g -r split.zip foo\fP +.LP +creates a split archive of the directory foo with splits no bigger than 2\ GB each. If +foo contained 5\ GB of contents and the contents were stored in the split archive without +compression (to make this example simple), this would create three splits, split.z01 at 2\ GB, +split.z02 at 2\ GB, and split.zip at a little over 1\ GB. +.LP +The \fB\-sp\fP option can be used to pause \fIzip\fP between splits to allow changing +removable media, for example, but read the descriptions and warnings for both \fB\-s\fP +and \fB\-sp\fP below. +.LP +Though \fIzip\fP does not update split archives, \fIzip\fP provides the new option \fB\-O\fP +(\fB\-\-output\-file\fP) to allow split archives to be updated and saved in a new archive. For example, +.IP +\fCzip inarchive.zip foo.c bar.c \-\-out outarchive.zip\fP +.LP +reads archive \fBinarchive.zip\fP, even if split, adds the files \fBfoo.c\fP and +\fBbar.c\fP, and writes the resulting archive to \fBoutarchive.zip\fP. If +\fBinarchive.zip\fP is split then \fBoutarchive.zip\fP defaults +to the same split size. Be aware that \fBoutarchive.zip\fP and any split files +that are created with it are always overwritten without warning. This may be changed +in the future. + + + + +.SH "PATTERN MATCHING" +This section applies only to Unix. +Watch this space for details on MSDOS and VMS operation. +However, the special wildcard characters \fB*\fR and \fB[]\fR below apply +to at least MSDOS also. +.LP +The Unix shells (\fIsh\fP, \fIcsh\fP, \fIbash\fP, and others) normally +do filename substitution (also called "globbing") on command arguments. +Generally the special characters are: +.TP +.B ? +match any single character +.TP +.B * +match any number of characters (including none) +.TP +.B [] +match any character in the range indicated within the brackets +(example: [a\-f], [0\-9]). This form of wildcard matching +allows a user to specify a list of characters between square brackets and +if any of the characters match the expression matches. For example: +.RS +.IP +\fCzip archive "*.[hc]"\fP +.RE +.IP +would archive all files in the current directory that end in +\fB.h\fP or \fB.c\fP. + +Ranges of characters are supported: +.RS +.IP +\fCzip archive "[a\-f]*"\fP +.RE +.IP +would add to the archive all files starting with "a" through "f". + +Negation is also supported, where any character in that position not in +the list matches. Negation is supported by adding \fB!\fP or \fB^\fP +to the beginning of the list: +.RS +.IP +\fCzip archive "*.[!o]"\fP +.RE +.IP +matches files that don't end in ".o". + +On WIN32, [] matching needs to be turned on with the -RE option to avoid +the confusion that names with [ or ] have caused. + +.LP +When these characters are encountered +(without being escaped with a backslash or quotes), +the shell will look for files relative to the current path +that match the pattern, +and replace the argument with a list of the names that matched. +.LP +The +.I zip +program can do the same matching on names that are in the +.I zip +archive being modified or, +in the case of the +.B \-x +(exclude) or +.B \-i +(include) options, on the list of files to be operated on, by using +backslashes or quotes to tell the shell not to do the name expansion. +In general, when +.I zip +encounters a name in the list of files to do, it first looks for the name in +the file system. If it finds it, it then adds it to the list of files to do. +If it does not find it, it looks for the name in the +.I zip +archive being modified (if it exists), using the pattern matching characters +described above, if present. For each match, it will add that name to the +list of files to be processed, unless this name matches one given +with the +.B \-x +option, or does not match any name given with the +.B \-i +option. +.LP +The pattern matching includes the path, +and so patterns like \\*.o match names that end in ".o", +no matter what the path prefix is. +Note that the backslash must precede every special character (i.e. ?*[]), +or the entire argument must be enclosed in double quotes (""). +.LP +In general, use backslashes or double quotes for paths +that have wildcards to make +.I zip +do the pattern matching for file paths, and always for +paths and strings that have spaces or wildcards for +\fB\-\i\fP, \fB\-x\fP, \fB\-R\fP, \fB\-d\fP, and \fB\-U\fP +and anywhere \fIzip\fP needs to process the wildcards. +.SH "ENVIRONMENT" +.LP +The following environment variables are read and used by +.I zip +as described. +.TP +.B ZIPOPT\ \ +contains default options that will be used when running +\fIzip\fR. The contents of this environment variable will get +added to the command line just after the \fBzip\fR command. +.TP +.B ZIP\ \ \ \ \ +[Not on RISC OS and VMS] see ZIPOPT +.TP +.B Zip$Options +[RISC OS] see ZIPOPT +.TP +.B Zip$Exts +[RISC OS] contains extensions separated by a : that will cause +native filenames with one of the specified extensions to +be added to the zip file with basename and extension swapped. +.TP +.B ZIP_OPTS +[VMS] see ZIPOPT +.SH "SEE ALSO" +compress(1), +shar(1L), +tar(1), +unzip(1L), +gzip(1L) +.SH DIAGNOSTICS +The exit status (or error level) approximates the exit codes defined by PKWARE +and takes on the following values, except under VMS: +.RS +.IP 0 +normal; no errors or warnings detected. +.IP 2 +unexpected end of zip file. +.IP 3 +a generic error in the zipfile format was detected. Processing may have +completed successfully anyway; some broken zipfiles created by other +archivers have simple work-arounds. +.IP 4 +\fIzip\fP was unable to allocate memory for one or more buffers during +program initialization. +.IP 5 +a severe error in the zipfile format was detected. Processing probably +failed immediately. +.IP 6 +entry too large to be processed (such as input files larger than 2 GB when +not using Zip64 or trying to read an existing archive that is too large) or +entry too large to be split with \fIzipsplit\fP +.IP 7 +invalid comment format +.IP 8 +\fIzip\fP -T failed or out of memory +.IP 9 +the user aborted \fIzip\fP prematurely with control-C (or similar) +.IP 10 +\fIzip\fP encountered an error while using a temp file +.IP 11 +read or seek error +.IP 12 +\fIzip\fP has nothing to do +.IP 13 +missing or empty zip file +.IP 14 +error writing to a file +.IP 15 +\fIzip\fP was unable to create a file to write to +.IP 16 +bad command line parameters +.IP 18 +\fIzip\fP could not open a specified file to read +.IP 19 +\fIzip\fP was compiled with options not supported on this system +.RE +.PP +VMS interprets standard Unix (or PC) return values as other, scarier-looking +things, so \fIzip\fP instead maps them into VMS-style status codes. In +general, \fIzip\fP sets VMS Facility = 1955 (0x07A3), Code = 2* Unix_status, +and an appropriate Severity (as specified in ziperr.h). More details are +included in the VMS-specific documentation. See [.vms]NOTES.TXT and +[.vms]vms_msg_gen.c. +.PD +.SH BUGS +.I zip +3.0 is not compatible with PKUNZIP 1.10. Use +.I zip +1.1 to produce +.I zip +files which can be extracted by PKUNZIP 1.10. +.PP +.I zip +files produced by +.I zip +3.0 must not be +.I updated +by +.I zip +1.1 or PKZIP 1.10, if they contain +encrypted members or if they have been produced in a pipe or on a non-seekable +device. The old versions of +.I zip +or PKZIP would create an archive with an incorrect format. +The old versions can list the contents of the zip file +but cannot extract it anyway (because of the new compression algorithm). +If you do not use encryption and use regular disk files, you do +not have to care about this problem. +.LP +Under VMS, +not all of the odd file formats are treated properly. +Only stream-LF format +.I zip +files are expected to work with +.IR zip . +Others can be converted using Rahul Dhesi's BILF program. +This version of +.I zip +handles some of the conversion internally. +When using Kermit to transfer zip files from VMS to MSDOS, type "set +file type block" on VMS. When transfering from MSDOS to VMS, type +"set file type fixed" on VMS. In both cases, type "set file type +binary" on MSDOS. +.LP +Under some older VMS versions, \fIzip\fP may hang for file +specifications that use DECnet syntax +.I foo::*.*. +.LP +On OS/2, zip cannot match some names, such as those including an +exclamation mark or a hash sign. This is a bug in OS/2 itself: the +32-bit DosFindFirst/Next don't find such names. Other programs such +as GNU tar are also affected by this bug. +.LP +Under OS/2, the amount of Extended Attributes displayed by DIR is (for +compatibility) the amount returned by the 16-bit version of +DosQueryPathInfo(). Otherwise OS/2 1.3 and 2.0 would report different +EA sizes when DIRing a file. +However, the structure layout returned by the 32-bit DosQueryPathInfo() +is a bit different, it uses extra padding bytes and link pointers (it's +a linked list) to have all fields on 4-byte boundaries for portability +to future RISC OS/2 versions. Therefore the value reported by +.I zip +(which uses this 32-bit-mode size) differs from that reported by DIR. +.I zip +stores the 32-bit format for portability, even the 16-bit +MS-C-compiled version running on OS/2 1.3, so even this one shows the +32-bit-mode size. +.SH AUTHORS +Copyright (C) 1997-2008 Info-ZIP. +.LP +Currently distributed under the Info-ZIP license. +.LP +Copyright (C) 1990-1997 Mark Adler, Richard B. Wales, Jean-loup Gailly, +Onno van der Linden, Kai Uwe Rommel, Igor Mandrichenko, John Bush and +Paul Kienitz. +.LP +Original copyright: +.LP +Permission is granted to any individual or institution to use, copy, or +redistribute this software so long as all of the original files are included, +that it is not sold for profit, and that this copyright notice +is retained. +.LP +LIKE ANYTHING ELSE THAT'S FREE, ZIP AND ITS ASSOCIATED UTILITIES ARE +PROVIDED AS IS AND COME WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED OR +IMPLIED. IN NO EVENT WILL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES +RESULTING FROM THE USE OF THIS SOFTWARE. +.LP +Please send bug reports and comments using the web page at: +.IR www.info-zip.org . +For bug reports, please include the version of +.IR zip +(see \fIzip\ \-h\fR), +the make options used to compile it (see \fIzip\ \-v\fR), +the machine and operating system in use, +and as much additional information as possible. +.SH ACKNOWLEDGEMENTS +Thanks to R. P. Byrne for his +.I Shrink.Pas +program, which inspired this project, +and from which the shrink algorithm was stolen; +to Phil Katz for placing in the public domain the +.I zip +file format, compression format, and .ZIP filename extension, and for +accepting minor changes to the file format; to Steve Burg for +clarifications on the deflate format; to Haruhiko Okumura and Leonid +Broukhis for providing some useful ideas for the compression +algorithm; to Keith Petersen, Rich Wales, Hunter Goatley and Mark +Adler for providing a mailing list and +.I ftp +site for the Info-ZIP group to use; and most importantly, to the +Info-ZIP group itself (listed in the file +.IR infozip.who ) +without whose tireless testing and bug-fixing efforts a portable +.I zip +would not have been possible. +Finally we should thank (blame) the first Info-ZIP moderator, +David Kirschbaum, +for getting us into this mess in the first place. +The manual page was rewritten for Unix by R. P. C. Rodgers and +updated by E. Gordon for \fIzip\fR 3.0. +.\" end of file diff --git a/man/zipcloak.1 b/man/zipcloak.1 new file mode 100644 index 0000000..8260b98 --- /dev/null +++ b/man/zipcloak.1 @@ -0,0 +1,111 @@ +.TH zipcloak 1 "v3.0 of 8 May 2008" +.SH NAME +zipcloak \- encrypt entries in a zipfile + +.SH SYNOPSIS +.I zipcloak +.RB [ \-d ] +.RB [ \-b\ path ] +.RB [ \-h ] +.RB [ \-v ] +.RB [ \-L ] +zipfile + +.SH ARGUMENTS +.in +13 +.ti -13 +zipfile Zipfile to encrypt entries in + +.SH OPTIONS +.TP +.PD 0 +.B \-b\ \fPpath +.TP +.PD +.B \-\-temp\-path \fPpath +Use the directory given by path for the temporary zip file. + +.TP +.PD 0 +.B \-d +.TP +.PD +.B \-\-decrypt +Decrypt encrypted entries (copy if given wrong password). + +.TP +.PD 0 +.B \-h +.TP +.PD +.B \-\-help\ +Show a short help. + +.TP +.PD 0 +.B \-L +.TP +.PD +.B \-\-license +Show software license. + +.TP +.PD 0 +.B \-O\ \fPpath +.TP +.PD +.B \-\-output\-file\ \fPzipfile +Write output to new archive zipfile, leaving original archive as is. + +.TP +.PD 0 +.B \-q +.TP +.PD +.B \-\-quiet +Quiet operation. Suppresses some informational messages. + +.TP +.PD 0 +.B \-v +.TP +.PD +.B \-\-version +Show version information. + +.SH DESCRIPTION +.I zipcloak +encrypts all unencrypted entries in the zipfile. This is the default action. + +.TP +The \-d option is used to decrypt encrypted entries in the zipfile. + +.TP +\fIzipcloak \fBuses original zip encryption which is considered weak. + +.TP +Note: +The encryption code of this program is not copyrighted and is put in +the public domain. It was originally written in Europe and can be freely +distributed from any country including the U.S.A. (Previously if this +program was imported into the U.S.A, it could not be re-exported from +the U.S.A to another country.) See the file README.CR included in the +source distribution for more on this. Otherwise, the Info-ZIP license +applies. + +.SH EXAMPLES +To be added. + +.SH BUGS +Large files (> 2 GB) and large archives not yet supported. + +Split archives not yet supported. A work around is to convert the +split archive to a single-file archive using \fIzip\fP and then +use \fIzipcloak\fP on the single-file archive. If needed, the +resulting archive can then be split again using \fIzip\fP. + + +.SH SEE ALSO +zip(1), unzip(1) +.SH AUTHOR +Info-ZIP diff --git a/man/zipnote.1 b/man/zipnote.1 new file mode 100644 index 0000000..fb4d18b --- /dev/null +++ b/man/zipnote.1 @@ -0,0 +1,85 @@ +.TH zipnote 1 "v3.0 of 8 May 2008" +.SH NAME +zipnote \- write the comments in zipfile to stdout, edit comments and rename files in zipfile + +.SH SYNOPSIS +.I zipnote +.RB [ \-w ] +.RB [ \-b\ path ] +.RB [ \-h ] +.RB [ \-v ] +.RB [ \-L ] +zipfile + +.SH ARGUMENTS +.in +13 +.ti -13 +zipfile Zipfile to read comments from or edit. + +.SH OPTIONS +.TP +.BI \-w +Write comments to a zipfile from stdin (see below). +.TP +.BI \-b\ \fRpath +Use path for the temporary zip file. +.TP +.BI \-h +Show a short help. +.TP +.BI \-v +Show version information. +.TP +.BI \-L +Show software license. + +.SH DESCRIPTION +.I zipnote +writes the comments in a zipfile to stdout. This is the default mode. A second mode +allows updating the comments in a zipfile as well as allows changing the names +of the files in the zipfile. These modes are described below. + +.SH EXAMPLES +To write all comments in a zipfile to stdout use for example +.LP +.nf + zipnote foo.zip > foo.tmp +.fi +.LP +This writes all comments in the zipfile +.I foo.zip +to the file +.I foo.tmp +in a specific format. + +.LP +If desired, this file can then be edited to change the comments and then used +to update the zipfile. +.LP +.nf + zipnote -w foo.zip < foo.tmp +.fi +.LP +The names of the files in the zipfile can also be changed in this way. This is done by +following lines like +.nf + "@ name" +.fi +in the created temporary file (called +.I foo.tmp +here) with lines like +.nf + "@=newname" +.fi +and then using the -w option as above. + +.SH BUGS +The temporary file format is rather specific and zipnote is rather picky about it. +It should be easier to change file names in a script. + +Does not yet support large (> 2 GB) or split archives. + +.SH SEE ALSO +zip(1), unzip(1) +.SH AUTHOR +Info-ZIP diff --git a/man/zipsplit.1 b/man/zipsplit.1 new file mode 100644 index 0000000..4a4de64 --- /dev/null +++ b/man/zipsplit.1 @@ -0,0 +1,69 @@ +.TH zipnote 1 "v3.0 of 8 May 2008" +.SH NAME +zipsplit \- split a zipfile into smaller zipfiles + +.SH SYNOPSIS +.I zipsplit +.RB [ \-t ] +.RB [ \-i ] +.RB [ \-p ] +.RB [ \-s ] +.RB [ \-n\ size ] +.RB [ \-r\ room ] +.RB [ \-b\ path ] +.RB [ \-h ] +.RB [ \-v ] +.RB [ \-L ] +zipfile + +.SH ARGUMENTS +.in +13 +.ti -13 +zipfile Zipfile to split. + +.SH OPTIONS +.TP +.BI \-t +Report how many files it will take, but don't make them. +.TP +.BI \-i +Make index (zipsplit.idx) and count its size against first zip file. +.TP +.BI \-n\ \fRsize +Make zip files no larger than "size" (default = 36000). +.TP +.BI \-r\ \fRroom +Leave room for "room" bytes on the first disk (default = 0). +.TP +.BI \-b\ \fRpath +Use path for the output zip files. +.TP +.BI \-p +Pause between output zip files. +.TP +.BI \-s +Do a sequential split even if it takes more zip files. +.TP +.BI \-h +Show a short help. +.TP +.BI \-v +Show version information. +.TP +.BI \-L +Show software license. + +.SH DESCRIPTION +.I zipsplit +reads a zipfile and splits it into smaller zipfiles. + +.SH EXAMPLES +To be filled in. + +.SH BUGS +Does not yet support large (> 2 GB) or split archives. + +.SH SEE ALSO +zip(1), unzip(1) +.SH AUTHOR +Info-ZIP diff --git a/match.S b/match.S new file mode 100644 index 0000000..eb8f735 --- /dev/null +++ b/match.S @@ -0,0 +1,407 @@ +/* + 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 +*/ + +/* + * match.s by Jean-loup Gailly. Translated to 32 bit code by Kai Uwe Rommel. + * The 68020 version has been written by Francesco Potorti` + * with adaptations by Carsten Steger , + * Andreas Schwab and + * Kristoffer Eriksson + */ + +/* This file is NOT used in conjunction with zlib. */ +#ifndef USE_ZLIB + +/* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix + * external symbols with an underline character '_'. + */ +#if defined(NO_UNDERLINE) || defined(__ELF__) +# define _prev prev +# define _window window +# define _match_start match_start +# define _prev_length prev_length +# define _good_match good_match +# define _nice_match nice_match +# define _strstart strstart +# define _max_chain_length max_chain_length + +# define _match_init match_init +# define _longest_match longest_match +#endif + +#ifdef DYN_ALLOC + error: DYN_ALLOC not yet supported in match.s +#endif + +/* Use 16-bytes alignment if your assembler supports it. Warning: gas + * uses a log(x) parameter (.align 4 means 16-bytes alignment). On SVR4 + * the parameter is a number of bytes. + */ +#ifndef ALIGNMENT +# define ALIGNMENT 4 +#endif + + +#ifndef WSIZE +# define WSIZE 32768 +#endif +#define MIN_MATCH 3 +#define MAX_MATCH 258 +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) +#define MAX_DIST (WSIZE - MIN_LOOKAHEAD) + +#if defined(i386) || defined(_I386) || defined(_i386) || defined(__i386) + +/* This version is for 386 Unix or OS/2 in 32 bit mode. + * Warning: it uses the AT&T syntax: mov source,dest + * This file is only optional. If you want to force the C version, + * add -DNO_ASM to CFLAGS in Makefile and set OBJA to an empty string. + * If you have reduced WSIZE in (g)zip.h, then make sure this is + * assembled with an equivalent -DWSIZE=. + * This version assumes static allocation of the arrays (-DDYN_ALLOC not used). + */ + + .file "match.S" + + .globl _match_init + .globl _longest_match + + .text + +_match_init: + ret + +/*----------------------------------------------------------------------- + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + */ + + .align ALIGNMENT + +_longest_match: /* int longest_match(cur_match) */ + +#define cur_match 20(%esp) + /* return address */ /* esp+16 */ + push %ebp /* esp+12 */ + push %edi /* esp+8 */ + push %esi /* esp+4 */ + push %ebx /* esp */ + +/* + * match equ esi + * scan equ edi + * chain_length equ ebp + * best_len equ ebx + * limit equ edx + */ + mov cur_match,%esi + mov _strstart,%edx + mov _max_chain_length,%ebp /* chain_length = max_chain_length */ + mov %edx,%edi + sub $(MAX_DIST),%edx /* limit = strstart-MAX_DIST */ + cld /* string ops increment si and di */ + jae limit_ok + sub %edx,%edx /* limit = NIL */ +limit_ok: + add $2+_window,%edi /* edi = offset(window+strstart+2) */ + mov _prev_length,%ebx /* best_len = prev_length */ + movw -2(%edi),%cx /* cx = scan[0..1] */ + movw -3(%ebx,%edi),%ax /* ax = scan[best_len-1..best_len] */ + cmp _good_match,%ebx /* do we have a good match already? */ + jb do_scan + shr $2,%ebp /* chain_length >>= 2 */ + jmp do_scan + + .align ALIGNMENT +long_loop: +/* at this point, edi == scan+2, esi == cur_match */ + movw -3(%ebx,%edi),%ax /* ax = scan[best_len-1..best_len] */ + movw -2(%edi),%cx /* cx = scan[0..1] */ +short_loop: +/* + * at this point, di == scan+2, si == cur_match, + * ax = scan[best_len-1..best_len] and cx = scan[0..1] + */ + and $(WSIZE-1), %esi + dec %ebp /* --chain_length */ + movw _prev(,%esi,2),%si /* cur_match = prev[cur_match] */ + /* top word of esi is still 0 */ + jz the_end + cmp %edx,%esi /* cur_match <= limit ? */ + jbe the_end +do_scan: + cmpw _window-1(%ebx,%esi),%ax/* check match at best_len-1 */ + jne short_loop + cmpw _window(%esi),%cx /* check min_match_length match */ + jne short_loop + + add $2+_window,%esi /* si = match */ + mov $((MAX_MATCH>>1)-1),%ecx/* scan for at most MAX_MATCH bytes */ + mov %edi,%eax /* ax = scan+2 */ + repe; cmpsw /* loop until mismatch */ + je maxmatch /* match of length MAX_MATCH? */ +mismatch: + movb -2(%edi),%cl /* mismatch on first or second byte? */ + xchg %edi,%eax /* edi = scan+2, eax = end of scan */ + subb -2(%esi),%cl /* cl = 0 if first bytes equal */ + sub %edi,%eax /* eax = len */ + sub $2+_window,%esi /* esi = cur_match + len */ + sub %eax,%esi /* esi = cur_match */ + subb $1,%cl /* set carry if cl == 0 (cannot use DEC) */ + adc $0,%eax /* eax = carry ? len+1 : len */ + cmp %ebx,%eax /* len > best_len ? */ + jle long_loop + mov %esi,_match_start /* match_start = cur_match */ + mov %eax,%ebx /* ebx = best_len = len */ +#ifdef FULL_SEARCH + cmp $(MAX_MATCH),%eax /* len >= MAX_MATCH ? */ +#else + cmp _nice_match,%eax /* len >= nice_match ? */ +#endif + jl long_loop +the_end: + mov %ebx,%eax /* result = eax = best_len */ + pop %ebx + pop %esi + pop %edi + pop %ebp + ret + .align ALIGNMENT +maxmatch: + cmpsb + jmp mismatch + +#else /* !(i386 || _I386 || _i386 || __i386) */ + +/* ======================== 680x0 version ================================= */ + +#if defined(m68k)||defined(mc68k)||defined(__mc68000__)||defined(__MC68000__) +# ifndef mc68000 +# define mc68000 +# endif +#endif + +#if defined(__mc68020__) || defined(__MC68020__) || defined(sysV68) +# ifndef mc68020 +# define mc68020 +# endif +#endif + +#if defined(mc68020) || defined(mc68000) + +#if (defined(mc68020) || defined(NeXT)) && !defined(UNALIGNED_OK) +# define UNALIGNED_OK +#endif + +#ifdef sysV68 /* Try Motorola Delta style */ + +# define GLOBAL(symbol) global symbol +# define TEXT text +# define FILE(filename) file filename +# define invert_maybe(src,dst) dst,src +# define imm(data) &data +# define reg(register) %register + +# define addl add.l +# define addql addq.l +# define blos blo.b +# define bhis bhi.b +# define bras bra.b +# define clrl clr.l +# define cmpmb cmpm.b +# define cmpw cmp.w +# define cmpl cmp.l +# define lslw lsl.w +# define lsrl lsr.l +# define movel move.l +# define movew move.w +# define moveb move.b +# define moveml movem.l +# define subl sub.l +# define subw sub.w +# define subql subq.l + +# define IndBase(bd,An) (bd,An) +# define IndBaseNdxl(bd,An,Xn) (bd,An,Xn.l) +# define IndBaseNdxw(bd,An,Xn) (bd,An,Xn.w) +# define predec(An) -(An) +# define postinc(An) (An)+ + +#else /* default style (Sun 3, NeXT, Amiga, Atari) */ + +# define GLOBAL(symbol) .globl symbol +# define TEXT .text +# define FILE(filename) .even +# define invert_maybe(src,dst) src,dst +# if defined(sun) || defined(mc68k) +# define imm(data) #data +# else +# define imm(data) \#data +# endif +# define reg(register) register + +# define blos bcss +# if defined(sun) || defined(mc68k) +# define movel movl +# define movew movw +# define moveb movb +# endif +# define IndBase(bd,An) An@(bd) +# define IndBaseNdxl(bd,An,Xn) An@(bd,Xn:l) +# define IndBaseNdxw(bd,An,Xn) An@(bd,Xn:w) +# define predec(An) An@- +# define postinc(An) An@+ + +#endif /* styles */ + +#define Best_Len reg(d0) /* unsigned */ +#define Cur_Match reg(d1) /* Ipos */ +#define Loop_Counter reg(d2) /* int */ +#define Scan_Start reg(d3) /* unsigned short */ +#define Scan_End reg(d4) /* unsigned short */ +#define Limit reg(d5) /* IPos */ +#define Chain_Length reg(d6) /* unsigned */ +#define Scan_Test reg(d7) +#define Scan reg(a0) /* *uch */ +#define Match reg(a1) /* *uch */ +#define Prev_Address reg(a2) /* *Pos */ +#define Scan_Ini reg(a3) /* *uch */ +#define Match_Ini reg(a4) /* *uch */ +#define Stack_Pointer reg(sp) + + GLOBAL (_match_init) + GLOBAL (_longest_match) + + TEXT + + FILE ("match.S") + +_match_init: + rts + +/*----------------------------------------------------------------------- + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + */ + +/* int longest_match (cur_match) */ + +#ifdef UNALIGNED_OK +# define pushreg 15928 /* d2-d6/a2-a4 */ +# define popreg 7292 +#else +# define pushreg 16184 /* d2-d7/a2-a4 */ +# define popreg 7420 +#endif + +_longest_match: + movel IndBase(4,Stack_Pointer),Cur_Match + moveml imm(pushreg),predec(Stack_Pointer) + movel _max_chain_length,Chain_Length + movel _prev_length,Best_Len + movel imm(_prev),Prev_Address + movel imm(_window+MIN_MATCH),Match_Ini + movel _strstart,Limit + movel Match_Ini,Scan_Ini + addl Limit,Scan_Ini + subw imm(MAX_DIST),Limit + bhis L__limit_ok + clrl Limit +L__limit_ok: + cmpl invert_maybe(_good_match,Best_Len) + blos L__length_ok + lsrl imm(2),Chain_Length +L__length_ok: + subql imm(1),Chain_Length +#ifdef UNALIGNED_OK + movew IndBase(-MIN_MATCH,Scan_Ini),Scan_Start + movew IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End +#else + moveb IndBase(-MIN_MATCH,Scan_Ini),Scan_Start + lslw imm(8),Scan_Start + moveb IndBase(-MIN_MATCH+1,Scan_Ini),Scan_Start + moveb IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End + lslw imm(8),Scan_End + moveb IndBaseNdxw(-MIN_MATCH,Scan_Ini,Best_Len),Scan_End +#endif + bras L__do_scan + +L__long_loop: +#ifdef UNALIGNED_OK + movew IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End +#else + moveb IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End + lslw imm(8),Scan_End + moveb IndBaseNdxw(-MIN_MATCH,Scan_Ini,Best_Len),Scan_End +#endif + +L__short_loop: + lslw imm(1),Cur_Match + movew IndBaseNdxl(0,Prev_Address,Cur_Match),Cur_Match + cmpw invert_maybe(Limit,Cur_Match) + dbls Chain_Length,L__do_scan + bras L__return + +L__do_scan: + movel Match_Ini,Match + addl Cur_Match,Match +#ifdef UNALIGNED_OK + cmpw invert_maybe(IndBaseNdxw(-MIN_MATCH-1,Match,Best_Len),Scan_End) + bne L__short_loop + cmpw invert_maybe(IndBase(-MIN_MATCH,Match),Scan_Start) + bne L__short_loop +#else + moveb IndBaseNdxw(-MIN_MATCH-1,Match,Best_Len),Scan_Test + lslw imm(8),Scan_Test + moveb IndBaseNdxw(-MIN_MATCH,Match,Best_Len),Scan_Test + cmpw invert_maybe(Scan_Test,Scan_End) + bne L__short_loop + moveb IndBase(-MIN_MATCH,Match),Scan_Test + lslw imm(8),Scan_Test + moveb IndBase(-MIN_MATCH+1,Match),Scan_Test + cmpw invert_maybe(Scan_Test,Scan_Start) + bne L__short_loop +#endif + + movew imm((MAX_MATCH-MIN_MATCH+1)-1),Loop_Counter + movel Scan_Ini,Scan +L__scan_loop: + cmpmb postinc(Match),postinc(Scan) + dbne Loop_Counter,L__scan_loop + + subl Scan_Ini,Scan + addql imm(MIN_MATCH-1),Scan + cmpl invert_maybe(Best_Len,Scan) + bls L__short_loop + movel Scan,Best_Len + movel Cur_Match,_match_start +#ifdef FULL_SEARCH + cmpl invert_maybe(imm(MAX_MATCH),Best_Len) +#else + cmpl invert_maybe(_nice_match,Best_Len) +#endif + blos L__long_loop +L__return: + moveml postinc(Stack_Pointer),imm(popreg) + rts + +#else + error: this asm version is for 386 or 680x0 only +#endif /* mc68000 || mc68020 */ +#endif /* i386 || _I386 || _i386 || __i386 */ + +#endif /* !USE_ZLIB */ diff --git a/msdos/README.DOS b/msdos/README.DOS new file mode 100644 index 0000000..0b9a57b --- /dev/null +++ b/msdos/README.DOS @@ -0,0 +1,132 @@ +README.DOS + +Some notes about the supplied MSDOS executables and their compilers: + +A) The 32-bit DOS executables "zip.exe" and the auxilary utilities + "zipnote.exe", "zipsplit.exe", "zipcloak.exe" (crypt-enabled distribution + only) were compiled with DJGPP v 2.03, using gcc 2.95.3 as compiler. + They require a DPMI server to run, e.g.: a DOS command prompt window + under WINDOWS 3.x or Windows 9x. To use this program under plain DOS, + you should install the free (GPL'ed) DPMI server CWSDPMI.EXE. Look + for "csdpmi5b.zip" under "simtelnet/gnu/djgpp/v2misc/" on the SimTelNet + home site "ftp.cdrom.com" or any mirror site of the SimtelNet archive. + + We have decided to provide 32-bit rather than 16-bit executables of + the auxilary tools for the following reasons: + - Nowadays, it has become quite unlikely to find PC computers "in action" + that do not at least have an i386 CPU. + - the 32-bit versions do not impose additional archive handling limits + beyond those defined by the Zip archive format + - the 32-bit DJGPP executables can handle long filenames on systems running + Windows 95/98/Me and Windows 2K/XP. + +B) There are two 16-bit MSDOS executables provided in zcr2?x.zip: + zip16.exe regular Zip program, requires ca. 455 KBytes of contiguous + free DOS memory or more. + zip16-sm.exe a variant that was compiled with the SMALL_MEM option + for minimal memory consumption; requires at minimum + 322 KBytes of contiguous free DOS memory. + + The SMALL_MEM variant requires much less space for the compression + buffers, but at the cost of some compression efficiency. + Therefore, we recommend to use the "SMALL_MEM" 16-bit "zip16-sm.exe" only + in case of "out of memory" problems (DOS memory is low and/or very large + number of archive entries), when the 32-bit program cannot be used for + some reason (286 or older; no DPMI server; ...). + +C) Hard limits of the Zip archive format: + Number of entries in Zip archive: 64 k (2^16 - 1 entries) + Compressed size of archive entry: 4 GByte (2^32 - 1 Bytes) + Uncompressed size of entry: 4 GByte (2^32 - 1 Bytes) + Size of single-volume Zip archive: 4 GByte (2^32 - 1 Bytes) + Per-volume size of multi-volume archives: 4 GByte (2^32 - 1 Bytes) + Number of parts for multi-volume archives: 64 k (1^16 - 1 parts) + Total size of multi-volume archive: 256 TByte (4G * 64k) + + The number of archive entries and of multivolume parts are limited by + the structure of the "end-of-central-directory" record, where the these + numbers are stored in 2-Byte fields. + Some Zip and/or UnZip implementations (for example Info-ZIP's) allow + handling of archives with more than 64k entries. (The information + from "number of entries" field in the "end-of-central-directory" record + is not really neccessary to retrieve the contents of a Zip archive; + it should rather be used for consistency checks.) + + Length of an archive entry name: 64 kByte (2^16 - 1) + Length of archive member comment: 64 kByte (2^16 - 1) + Total length of "extra field": 64 kByte (2^16 - 1) + Length of a single e.f. block: 64 kByte (2^16 - 1) + Length of archive comment: 64 KByte (2^16 - 1) + + Additional limitation claimed by PKWARE: + Size of local-header structure (fixed fields of 30 Bytes + filename + local extra field): < 64 kByte + Size of central-directory structure (46 Bytes + filename + + central extra field + member comment): < 64 kByte + +D) Implementation limits of the Zip executables: + + 1. Size limits caused by file I/O and compression handling: + Size of Zip archive: 2 GByte (2^31 - 1 Bytes) + Compressed size of archive entry: 2 GByte (2^31 - 1 Bytes) + Uncompressed size of entry: 2 GByte (2^31 - 1 Bytes), + (could/should be 4 GBytes...) + Multi-volume archive creation is not supported. + + 2. Limits caused by handling of archive contents lists + + 2.1. Number of archive entries (freshen, update, delete) + a) 16-bit executable: 64k (2^16 -1) or 32k (2^15 - 1), + (unsigned vs. signed type of size_t) + a1) 16-bit executable: <16k ((2^16)/4) + (The smaller limit a1) results from the array size limit of + the "qsort()" function.) + 32-bit executables <1G ((2^32)/4) + (usual system limit of the "qsort()" function on 32-bit systems) + + b) stack space needed by qsort to sort list of archive entries + + NOTE: In the current executables, overflows of limits a) and b) are NOT + checked! + + c) amount of free memory to hold "central directory information" of + all archive entries; one entry needs: + 96 bytes (32-bit) resp. 80 bytes (16-bit) + + 3 * length of entry name + + length of zip entry comment (when present) + + length of extra field(s) (when present, e.g.: UT needs 9 bytes) + + some bytes for book-keeping of memory allocation + + Conclusion: + For systems with limited memory space (MSDOS, small AMIGAs, other + environments without virtual memory), the number of archive entries + is most often limited by condition c). + For example, with approx. 100 kBytes of free memory after loading and + initializing the program, a 16-bit DOS Zip cannot process more than 600 + to 1000 (+) archive entries. (For the 16-bit Windows DLL or the 16-bit + OS/2 port, limit c) is less important because Windows or OS/2 executables + are not restricted to the 1024k area of real mode memory. These 16-bit + ports are limited by conditions a1) and b), say: at maximum approx. + 16000 entries!) + + + 2.2. Number of "new" entries (add operation) + In addition to the restrictions above (2.1.), the following limits + caused by the handling of the "new files" list apply: + + a) 16-bit executable: <16k ((2^64)/4) + + b) stack size required for "qsort" operation on "new entries" list. + + NOTE: In the current executables, the overflow checks for these limits + are missing! + + c) amount of free memory to hold the directory info list for new entries; + one entry needs: + 24 bytes (32-bit) resp. 22 bytes (16-bit) + + 3 * length of filename + + +Please report any problems to: Zip-Bugs@lists.wku.edu + +Last updated: 07 July 2001 diff --git a/msdos/crc_i86.asm b/msdos/crc_i86.asm new file mode 100644 index 0000000..3ad0349 --- /dev/null +++ b/msdos/crc_i86.asm @@ -0,0 +1,497 @@ +;=========================================================================== +; Copyright (c) 1990-2007 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 2000-Apr-09 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, all these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +;=========================================================================== +; Created by Christian Spieler, last modified 07 Jan 2007. +; + TITLE crc_i86.asm + NAME crc_i86 +; +; Optimized 8086 assembler version of the CRC32 calculation loop, intended +; for real mode Info-ZIP programs (Zip 2.1, UnZip 5.2, and later versions). +; Supported compilers are Microsoft C (DOS real mode) and Borland C(++) +; (Turbo C). Watcom C (16bit) should also work. +; This module was inspired by a similar module for the Amiga (Paul Kienitz). +; +; It replaces the `ulg crc32(ulg crc, ZCONST uch *buf, extent len)' function +; in crc32.c. +; +; In March/April 1997, the code has been revised to incorporate Rodney Brown's +; ideas for optimized access to the data buffer. For 8086 real mode code, +; the data buffer is now accessed by aligned word-wide read operations. +; This new optimization may be turned off by defining the macro switch +; NO_16_BIT_LOADS. +; +; In December 1998, the loop branch commands were changed from "loop dest" +; into "dec cx; jnz dest". On modern systems (486 and newer), the latter +; code is usually much faster (e.g. 1 clock cycle compared to 5 for "loop" +; on Pentium MMX). For the 286, the penalty of "dec cx; jnz" is one clock +; cycle (12 vs. 11 cycles); on an 8088 the cycle counts are 22 (dec cx; jnz) +; vs. 18 (loop). I decided to optimize for newer CPU models by default, because +; I expect that old 80286 or 8088 dinosaurier machines may be rarely used +; nowadays. In case you want optimum performance for these old CPU models +; you should define the OPTIMIZE_286_88 macro switch on the assembler's +; command line. +; Likewise, "jcxz" was replaced by "jz", because the latter is faster on +; 486 and newer CPUs (without any penalty on 80286 and older CPU models). +; +; In January 2007, the "hand-made" memory model setup section has been guarded +; against redefinition of @CodeSize and @DataSize symbols, to work around a +; problem with current Open Watcom (version 1.6) wasm assembler. +; +; The code in this module should work with all kinds of C memory models +; (except Borland's __HUGE__ model), as long as the following +; restrictions are not violated: +; +; - The implementation assumes that the char buffer is confined to a +; 64k segment. The pointer `s' to the buffer must be in a format that +; all bytes can be accessed by manipulating the offset part, only. +; This means: +; + no huge pointers +; + char buffer size < 64 kByte +; +; - Since the buffer size argument `n' is of type `size_t' (= unsigned short) +; for this routine, the char buffer size is limited to less than 64 kByte, +; anyway. So, the assumption above should be easily fulfilled. +; +;============================================================================== +; +; Do NOT assemble this source if external crc32 routine from zlib gets used, +; or only the precomputed CRC_32_Table is needed. +; +ifndef USE_ZLIB +ifndef CRC_TABLE_ONLY +; +; Setup of amount of assemble time informational messages: +; +ifdef DEBUG + VERBOSE_INFO EQU 1 +else + ifdef _AS_MSG_ + VERBOSE_INFO EQU 1 + else + VERBOSE_INFO EQU 0 + endif +endif +; +; Selection of memory model, and initialization of memory model +; related macros: +; +ifndef __SMALL__ + ifndef __COMPACT__ + ifndef __MEDIUM__ + ifndef __LARGE__ + ifndef __HUGE__ +; __SMALL__ EQU 1 + endif + endif + endif + endif +endif + +ifdef __HUGE__ +; .MODEL Huge + ifndef @CodeSize + @CodeSize EQU 1 + endif + ifndef @DataSize + @DataSize EQU 1 + endif + Save_DS EQU 1 + if VERBOSE_INFO + if1 + %out Assembling for C, Huge memory model + endif + endif +else + ifdef __LARGE__ +; .MODEL Large + ifndef @CodeSize + @CodeSize EQU 1 + endif + ifndef @DataSize + @DataSize EQU 1 + endif + if VERBOSE_INFO + if1 + %out Assembling for C, Large memory model + endif + endif + else + ifdef __COMPACT__ +; .MODEL Compact + ifndef @CodeSize + @CodeSize EQU 0 + endif + ifndef @DataSize + @DataSize EQU 1 + endif + if VERBOSE_INFO + if1 + %out Assembling for C, Compact memory model + endif + endif + else + ifdef __MEDIUM__ +; .MODEL Medium + ifndef @CodeSize + @CodeSize EQU 1 + endif + ifndef @DataSize + @DataSize EQU 0 + endif + if VERBOSE_INFO + if1 + %out Assembling for C, Medium memory model + endif + endif + else +; .MODEL Small + ifndef @CodeSize + @CodeSize EQU 0 + endif + ifndef @DataSize + @DataSize EQU 0 + endif + if VERBOSE_INFO + if1 + %out Assembling for C, Small memory model + endif + endif + endif + endif + endif +endif + +if @CodeSize + LCOD_OFS EQU 2 +else + LCOD_OFS EQU 0 +endif + +IF @DataSize + LDAT_OFS EQU 2 +else + LDAT_OFS EQU 0 +endif + +ifdef Save_DS +; (di,si,ds)+(size, return address) + SAVE_REGS EQU 6+(4+LCOD_OFS) +else +; (di,si)+(size, return address) + SAVE_REGS EQU 4+(4+LCOD_OFS) +endif + +; +; Selection of the supported CPU instruction set and initialization +; of CPU type related macros: +; +ifdef __686 + Use_286_code EQU 1 + Align_Size EQU 4 ; dword alignment on Pentium II/III/IV + Alig_PARA EQU 1 ; paragraph aligned code segment +else +ifdef __586 + Use_286_code EQU 1 + Align_Size EQU 4 ; dword alignment on Pentium + Alig_PARA EQU 1 ; paragraph aligned code segment +else +ifdef __486 + Use_286_code EQU 1 + Align_Size EQU 4 ; dword alignment on 32 bit processors + Alig_PARA EQU 1 ; paragraph aligned code segment +else +ifdef __386 + Use_286_code EQU 1 + Align_Size EQU 4 ; dword alignment on 32 bit processors + Alig_PARA EQU 1 ; paragraph aligned code segment +else +ifdef __286 + Use_286_code EQU 1 + Align_Size EQU 2 ; word alignment on 16 bit processors + Alig_PARA EQU 0 ; word aligned code segment +else +ifdef __186 + Use_186_code EQU 1 + Align_Size EQU 2 ; word alignment on 16 bit processors + Alig_PARA EQU 0 ; word aligned code segment +else + Align_Size EQU 2 ; word alignment on 16 bit processors + Alig_PARA EQU 0 ; word aligned code segment +endif ;?__186 +endif ;?__286 +endif ;?__386 +endif ;?__486 +endif ;?__586 +endif ;?__686 + +ifdef Use_286_code + .286 + Have_80x86 EQU 1 +else +ifdef Use_186_code + .186 + Have_80x86 EQU 1 +else + .8086 + Have_80x86 EQU 0 +endif ;?Use_186_code +endif ;?Use_286_code + +; +; Declare the segments used in this module: +; +if @CodeSize +if Alig_PARA +CRC32_TEXT SEGMENT PARA PUBLIC 'CODE' +else +CRC32_TEXT SEGMENT WORD PUBLIC 'CODE' +endif +CRC32_TEXT ENDS +else ;!@CodeSize +if Alig_PARA +_TEXT SEGMENT PARA PUBLIC 'CODE' +else +_TEXT SEGMENT WORD PUBLIC 'CODE' +endif +_TEXT ENDS +endif ;?@CodeSize +_DATA SEGMENT WORD PUBLIC 'DATA' +_DATA ENDS +_BSS SEGMENT WORD PUBLIC 'BSS' +_BSS ENDS +DGROUP GROUP _BSS, _DATA +if @DataSize + ASSUME DS: nothing, SS: DGROUP +else + ASSUME DS: DGROUP, SS: DGROUP +endif + +if @CodeSize +EXTRN _get_crc_table:FAR +else +EXTRN _get_crc_table:NEAR +endif + + +Do_CRC MACRO + mov bl,al + sub bh,bh +if Have_80x86 + shl bx,2 +else + shl bx,1 + shl bx,1 +endif + mov al,ah + mov ah,dl + mov dl,dh + sub dh,dh + xor ax,WORD PTR [bx][si] + xor dx,WORD PTR [bx+2][si] + ENDM +; +Do_1 MACRO +if @DataSize + xor al,BYTE PTR es:[di] +else + xor al,BYTE PTR [di] +endif + inc di + Do_CRC + ENDM +; +Do_2 MACRO +ifndef NO_16_BIT_LOADS +if @DataSize + xor ax,WORD PTR es:[di] +else + xor ax,WORD PTR [di] +endif + add di,2 + Do_CRC + Do_CRC +else + Do_1 + Do_1 +endif + ENDM +; +Do_4 MACRO + Do_2 + Do_2 + ENDM +; + +IF @CodeSize +CRC32_TEXT SEGMENT + ASSUME CS: CRC32_TEXT +else +_TEXT SEGMENT + ASSUME CS: _TEXT +endif +; Line 37 + +; +;ulg crc32(ulg crc, +; ZCONST uch *buf, +; extent len) +; + PUBLIC _crc32 +if @CodeSize +_crc32 PROC FAR +else +_crc32 PROC NEAR +endif +if Have_80x86 + enter WORD PTR 0,0 +else + push bp + mov bp,sp +endif + push di + push si +if @DataSize +; crc = 4+LCOD_OFS DWORD (unsigned long) +; buf = 8+LCOD_OFS DWORD PTR BYTE (uch *) +; len = 12+LCOD_OFS WORD (unsigned int) +else +; crc = 4+LCOD_OFS DWORD (unsigned long) +; buf = 8+LCOD_OFS WORD PTR BYTE (uch *) +; len = 10+LCOD_OFS WORD (unsigned int) +endif +; +if @DataSize + mov ax,WORD PTR [bp+8+LCOD_OFS] ; buf + or ax,WORD PTR [bp+10+LCOD_OFS] ; == NULL ? +else + cmp WORD PTR [bp+8+LCOD_OFS],0 ; buf == NULL ? +endif + jne crc_update + sub ax,ax ; crc = 0 + cwd +ifndef NO_UNROLLED_LOOPS + jmp fine +else + jmp SHORT fine +endif +; +crc_update: + call _get_crc_table +; When used with compilers that conform to the Microsoft/Borland standard +; C calling convention, model-dependent handling is not needed, because +; _get_crc_table returns NEAR pointer. +; But Watcom C is different and does not allow one to assume DS pointing to +; DGROUP. So, we load DS with DGROUP, to be safe. +;if @DataSize +; push ds +; mov ds,dx +; ASSUME DS: nothing +;endif + mov si,ax ;crc_table +if @DataSize + push ds + mov ax,SEG DGROUP + mov ds,ax + ASSUME DS: DGROUP +endif +; + mov ax,WORD PTR [bp+4+LCOD_OFS] ;crc + mov dx,WORD PTR [bp+6+LCOD_OFS] + not ax + not dx +if @DataSize + les di,DWORD PTR [bp+8+LCOD_OFS] ;buf + mov cx,WORD PTR [bp+12+LCOD_OFS] ;len +else + mov di,WORD PTR [bp+8+LCOD_OFS] ;buf + mov cx,WORD PTR [bp+10+LCOD_OFS] ;len +endif +; +ifndef NO_UNROLLED_LOOPS +ifndef NO_16_BIT_LOADS + test cx,cx + jnz start + jmp done +start: test di,1 + jz is_wordaligned + dec cx + Do_1 + mov WORD PTR [bp+10+LDAT_OFS+LCOD_OFS],cx +is_wordaligned: +endif ; !NO_16_BIT_LOADS +if Have_80x86 + shr cx,2 +else + shr cx,1 + shr cx,1 +endif + jz No_Fours +; + align Align_Size ; align destination of branch +Next_Four: + Do_4 +ifndef OPTIMIZE_286_88 + dec cx ; on 286, "loop Next_Four" needs 11 + jnz Next_Four ; clocks, one less than this code +else + loop Next_Four +endif +; +No_Fours: +if @DataSize + mov cx,WORD PTR [bp+12+LCOD_OFS] ;len +else + mov cx,WORD PTR [bp+10+LCOD_OFS] ;len +endif + and cx,00003H +endif ; !NO_UNROLLED_LOOPS + jz done +; + align Align_Size ; align destination of branch +Next_Byte: + Do_1 +ifndef OPTIMIZE_286_88 + dec cx ; on 286, "loop Next_Four" needs 11 + jnz Next_Byte ; clocks, one less than this code +else + loop Next_Four +endif +; +done: +if @DataSize + pop ds +; ASSUME DS: DGROUP + ASSUME DS: nothing +endif + not ax + not dx +; +fine: + pop si + pop di +if Have_80x86 + leave +else + mov sp,bp + pop bp +endif + ret + +_crc32 ENDP + +if @CodeSize +CRC32_TEXT ENDS +else +_TEXT ENDS +endif +; +endif ;!CRC_TABLE_ONLY +endif ;!USE_ZLIB +; +END diff --git a/msdos/makebz2.dj2 b/msdos/makebz2.dj2 new file mode 100644 index 0000000..161f1e3 --- /dev/null +++ b/msdos/makebz2.dj2 @@ -0,0 +1,148 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for +# djgpp 2.x +# +# This simple modified version of makefile.dj2 adds bzip2 support +# to Zip for djgpp 2.x and was donated by Robert Riebisch. +# +# Given standard djgpp 2.x and bzip2 installations, this should create a +# version of Zip 3.0 with bzip2 support. Additional information is in +# bzip2/install.txt. +# +# 27 June 2008 + +VPATH=.;msdos +# ------------- djgpp ------------- +CPPFLAGS=-I. -DDOS -DASM_CRC -DBZIP2_SUPPORT $(LOCAL_ZIP) +ASFLAGS=$(CPPFLAGS) +CFLAGS=-Wall -O2 $(CPPFLAGS) +UTILFLAGS=-c -DUTIL $(CFLAGS) -o +CC=gcc +LD=gcc +LDFLAGS=-s + +# ------------- file packer -------- +# Laszlo Molnar who wrote DJ Packer and Markus F. X. J. Oberhumer who wrote +# the compression library used by the DJ Packer have collaborated on the +# Ultimate Packer for eXecutables, which has recently been released. Look +# for upx???d.zip at http://upx.sourceforge.net +# As an alternative, look for "djp.exe", now two years old, in the archive +# mlp107[b,s].zip, found in the same location as csdpmi?[b,s].zip (see below). +# If you have got an executable packer in your PATH, you may reduce the +# size of the disk image of the zip*.exe's by uncommenting the lines +# containing $(DJP) below where the exe's are built. +#DJP=djp -q +DJP=upx -qq --best + +# variables + +#set CRC32 to crc_gcc.o or nothing, depending on whether ASM_CRC is defined: +CRCA_O = crc_gcc.o + +OBJZ = zip.o crypt.o ttyio.o zipfile.o zipup.o fileio.o util.o \ + crc32.o $(CRCA_O) globals.o +OBJI = deflate.o trees.o match.o msdos.o +OBJU = zipfile_.o fileio_.o util_.o globals.o msdos_.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o crc32_.o crypt_.o ttyio.o $(OBJU) +OBJS = zipsplit.o $(OBJU) +LIBS = -lbz2 + +ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h + +# rules + +.SUFFIXES: # Delete make's default suffix list +.SUFFIXES: .exe .out .a .ln .o .c .cc .C .p .f .F .y .l .s .S .h + +.c.o: + $(CC) -c $(CFLAGS) $< -o $@ + +zips: zip.exe zipnote.exe zipsplit.exe zipcloak.exe + +zip.o: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + +zipfile.o: zipfile.c $(ZIP_H) crc32.h + +zipup.o: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h + +fileio.o: fileio.c $(ZIP_H) crc32.h + +util.o: util.c $(ZIP_H) + +globals.o: globals.c $(ZIP_H) + +deflate.o: deflate.c $(ZIP_H) + +trees.o: trees.c $(ZIP_H) + +crc_gcc.o: crc_i386.S + $(CC) $(ASFLAGS) -x assembler-with-cpp -c -o $@ crc_i386.S + +crc32.o: crc32.c $(ZIP_H) crc32.h + +crypt.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + +ttyio.o: ttyio.c $(ZIP_H) crypt.h ttyio.h + +msdos.o: msdos/msdos.c $(ZIP_H) + +zipcloak.o: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + +zipnote.o: zipnote.c $(ZIP_H) revision.h + +zipsplit.o: zipsplit.c $(ZIP_H) revision.h + +zipfile_.o: zipfile.c $(ZIP_H) crc32.h + $(CC) $(UTILFLAGS) $@ zipfile.c + +fileio_.o: fileio.c $(ZIP_H) crc32.h + $(CC) $(UTILFLAGS) $@ fileio.c + +util_.o: util.c $(ZIP_H) + $(CC) $(UTILFLAGS) $@ util.c + +crc32_.o: crc32.c $(ZIP_H) crc32.h + $(CC) $(UTILFLAGS) $@ crc32.c + +crypt_.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) $(UTILFLAGS) $@ crypt.c + +msdos_.o: msdos/msdos.c $(ZIP_H) + $(CC) $(UTILFLAGS) $@ msdos/msdos.c + + +match.o: match.S + $(CC) $(ASFLAGS) -x assembler-with-cpp -c -o $@ match.S + +zip.exe: $(OBJZ) $(OBJI) + echo $(OBJZ) > zip.rsp + echo $(OBJI) >> zip.rsp + echo $(LIBS) >> zip.rsp + $(LD) $(LDFLAGS) -o $@ @zip.rsp + del zip.rsp +# stubedit $@ dpmi=cwsdpmi.exe +# $(DJP) $@ + +zipcloak.exe: $(OBJC) + $(LD) $(LDFLAGS) $(OBJC) -o $@ +# stubedit $@ dpmi=cwsdpmi.exe +# $(DJP) $@ + +zipnote.exe: $(OBJN) + $(LD) $(LDFLAGS) $(OBJN) -o $@ +# stubedit $@ dpmi=cwsdpmi.exe +# $(DJP) $@ + +zipsplit.exe: $(OBJS) + $(LD) $(LDFLAGS) $(OBJS) -o $@ +# stubedit $@ dpmi=cwsdpmi.exe +# $(DJP) $@ + +# These stand alone executables require dpmi services to run. When +# running in a DOS window under windows 3.1 or later, the dpmi server +# is automatically present. Under DOS, if a dpmi server is not installed, +# by default the program will look for "cwsdpmi.exe." If found, it will +# be loaded for the duration of the program. +# cwsdpmi is a "free" dpmi server written by Charles W. Sandmann +# (sandman@clio.rice.edu). It may be found, among other sites, on SimTel +# and its mirrors in the .../vendors/djgpp/v2misc directory. diff --git a/msdos/makefile.bor b/msdos/makefile.bor new file mode 100644 index 0000000..88ecde4 --- /dev/null +++ b/msdos/makefile.bor @@ -0,0 +1,197 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for +# Borland (Turbo) C++ 1.0 or 2.0. +# Warning: this file is not suitable for Turbo C 2.0. Use makefile.tc instead. + +# To use, do "make -fmakefile.bor" + +# WARNING: the small model is not supported. +# Add -DSMALL_MEM or -DMEDIUM_MEM to the LOC macro if you wish to reduce +# the memory requirements. +# Add -DNO_ASM to CFLAGS and comment out the ASMOBJS definition if +# you do not have tasm. + +# Optional nonstandard preprocessor flags (as -DMEDIUM_MEM or -DNO_ASM) +# should be added to the environment via "set LOCAL_ZIP=-DFOO" or added +# to the declaration of LOC here: +LOC = -DDOS -DNO_SECURE_TESTS $(LOCAL_ZIP) + +# Zip requires compact or large memory model. +# with 2.1, compact model exceeds 64k code segment; use large model +ZIPMODEL=l # large model for Zip and ZipUtils + +# name of Flag to select memory model for assembler compiles, supported +# values are __SMALL__ , __MEDIUM__ , __COMPACT__ , __LARGE__ : +ASMODEL=__LARGE__ # keep in sync with ZIPMODEL definition !! + +# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc. +CPU_TYP = 0 + +# Uncomment the following macro to use the optimized assembler +# routines in Zip: +CRCA_O = crc_i86.obj +ASMOBJS = match.obj $(CRCA_O) + +ASCPUFLAG = __$(CPU_TYP)86 +!if $(CPU_TYP) != 0 +CC_CPUFLG = -$(CPU_TYP) +!endif + +VPATH=.;msdos +# ------------- Turbo C++, Borland C++ ------------- +!if $(CC_REV) == 1 +CC = tcc +!else +! if !$(CC_REV) +CC_REV = 3 +! endif +CC = bcc +!endif + +MODEL=-m$(ZIPMODEL) +!if $(CC_REV) == 1 +CFLAGS=-w -w-eff -w-def -w-sig -w-cln -a -d -G -O -Z $(CC_CPUFLG) $(MODEL) $(LOC) +!else +CFLAGS=-w -w-cln -O2 -Z $(CC_CPUFLG) $(MODEL) $(LOC) +!endif +UTILFLAGS=-DUTIL $(CFLAGS) -o +# for Turbo C++ 1.0, replace bcc with tcc and use the upper version of CFLAGS + +AS=tasm +ASFLAGS=-ml -t -m2 -DDYN_ALLOC -DSS_NEQ_DS -D$(ASCPUFLAG) -D$(ASMODEL) $(LOC) + +LD=$(CC) +LDFLAGS=$(MODEL) + +# ------------- Common declarations: +STRIP=@rem +# If you don't have UPX, LZEXE, or PKLITE, get one of them. Then define: +# (NOTE: upx needs a 386 or higher system to run the exe compressor) +#STRIP=upx --8086 --best +# or +#STRIP=lzexe +# or (if you've registered PKLITE) +#STRIP=pklite +# This makes a big difference in .exe size (and possibly load time) + +# ------------- Used by install rule +# set BIN to the directory you want to install the executables to +BIN = c:\util + +# variables +OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \ + crc32.obj globals.obj + +OBJI = deflate.obj trees.obj $(ASMOBJS) msdos.obj + +OBJU = zipfile_.obj fileio_.obj util_.obj globals.obj msdos_.obj +OBJN = zipnote.obj $(OBJU) +OBJC = zipcloak.obj crc32_.obj crypt_.obj ttyio.obj $(OBJU) +OBJS = zipsplit.obj $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h + +ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe + +zips: $(ZIPS) + +zip.obj: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +zipfile.obj: zipfile.c $(ZIP_H) crc32.h + $(CC) -c $(CFLAGS) $*.c + +zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h + $(CC) -c $(CFLAGS) $*.c + +fileio.obj: fileio.c $(ZIP_H) crc32.h + $(CC) -c $(CFLAGS) $*.c + +util.obj: util.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +globals.obj: globals.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c $(ZIP_H) crc32.h + $(CC) -c $(CFLAGS) $*.c + +crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +msdos.obj: msdos/msdos.c $(ZIP_H) + $(CC) -c $(CFLAGS) msdos/$*.c + +zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +zipnote.obj: zipnote.c $(ZIP_H) revision.h + $(CC) -c $(CFLAGS) $*.c + +zipsplit.obj: zipsplit.c $(ZIP_H) revision.h + $(CC) -c $(CFLAGS) $*.c + +zipfile_.obj: zipfile.c $(ZIP_H) crc32.h + $(CC) -c $(UTILFLAGS)$* zipfile.c + +fileio_.obj: fileio.c $(ZIP_H) crc32.h + $(CC) -c $(UTILFLAGS)$* fileio.c + +util_.obj: util.c $(ZIP_H) + $(CC) -c $(UTILFLAGS)$* util.c + +crc32_.obj: crc32.c $(ZIP_H) crc32.h + $(CC) -c $(UTILFLAGS) crc32.c + +crypt_.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) -c $(UTILFLAGS)$* crypt.c + +msdos_.obj: msdos/msdos.c $(ZIP_H) + $(CC) -c $(UTILFLAGS)$* msdos/msdos.c + +crc_i86.obj: msdos/crc_i86.asm + $(AS) $(ASFLAGS) msdos\crc_i86.asm ; + +match.obj: msdos/match.asm + $(AS) $(ASFLAGS) msdos\match.asm ; + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +zip.exe: $(OBJZ) $(OBJI) + echo $(OBJZ) > zip.rsp + echo $(OBJI) >> zip.rsp + $(LD) $(LDFLAGS) @zip.rsp + del zip.rsp + $(STRIP) zip.exe + +zipcloak.exe: $(OBJC) + echo $(OBJC) > zipc.rsp + $(LD) $(LDFLAGS) @zipc.rsp + del zipc.rsp + $(STRIP) zipcloak.exe + +zipnote.exe: $(OBJN) + echo $(OBJN) > zipn.rsp + $(LD) $(LDFLAGS) @zipn.rsp + del zipn.rsp + $(STRIP) zipnote.exe + +zipsplit.exe: $(OBJS) + echo $(OBJS) > zips.rsp + $(LD) $(LDFLAGS) @zips.rsp + del zips.rsp + $(STRIP) zipsplit.exe + +install: $(ZIPS) + copy /b *.exe $(BIN) + +clean: + del *.obj + del *.exe diff --git a/msdos/makefile.dj1 b/msdos/makefile.dj1 new file mode 100644 index 0000000..05137cc --- /dev/null +++ b/msdos/makefile.dj1 @@ -0,0 +1,126 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for +# djgpp 1.x +VPATH=.;msdos +# ------------- djgpp ------------- +CPPFLAGS=-I. -DDOS -DASM_CRC $(LOCAL_ZIP) +ASFLAGS=$(CPPFLAGS) +CFLAGS=-Wall -O2 -m486 $(CPPFLAGS) +UTILFLAGS=-c -DUTIL $(CFLAGS) -o +CC=gcc +LD=gcc +LDFLAGS=-s + +STRIP=strip + +# Change the STUBIFY definition to the upper version if you want to create +# executables which can be used without any external extender file. +# >>> NOTE: Either copy the go32 extender into your build directory, or +# >>> edit the STUBIFY macro and add the correct path to "go32.exe". +#STUBIFY=coff2exe -s go32.exe +STUBIFY=coff2exe + +# variables + +#set CRCA_O to crc_gcc.o or nothing, depending on whether ASM_CRC is defined: +CRCA_O = crc_gcc.o + +OBJZ = zip.o crypt.o ttyio.o zipfile.o zipup.o fileio.o util.o \ + crc32.o $(CRCA_O) globals.o +OBJI = deflate.o trees.o match.o msdos.o +OBJU = zipfile_.o fileio_.o util_.o globals.o msdos_.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o crc32_.o crypt_.o ttyio.o $(OBJU) +OBJS = zipsplit.o $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h + +# rules + +.SUFFIXES: # Delete make's default suffix list +.SUFFIXES: .exe .out .a .ln .o .c .cc .C .p .f .F .y .l .s .S .h + +.c.o: + $(CC) -c $(CFLAGS) $< -o $@ + +zips: zip.exe zipnote.exe zipsplit.exe zipcloak.exe + +zip.o: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + +zipfile.o: zipfile.c $(ZIP_H) crc32.h + +zipup.o: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h + +fileio.o: fileio.c $(ZIP_H) + +util.o: util.c $(ZIP_H) + +globals.o: globals.c $(ZIP_H) + +deflate.o: deflate.c $(ZIP_H) + +trees.o: trees.c $(ZIP_H) + +crc_gcc.o: crc_i386.S + $(CC) $(ASFLAGS) -x assembler-with-cpp -c -o $@ crc_i386.S + +crc32.o: crc32.c $(ZIP_H) crc32.h + +crypt.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + +ttyio.o: ttyio.c $(ZIP_H) crypt.h ttyio.h + +msdos.o: msdos/msdos.c $(ZIP_H) + +zipcloak.o: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + +zipnote.o: zipnote.c $(ZIP_H) revision.h + +zipsplit.o: zipsplit.c $(ZIP_H) revision.h + +zipfile_.o: zipfile.c $(ZIP_H) crc32.h + $(CC) $(UTILFLAGS) $@ zipfile.c + +fileio_.o: fileio.c $(ZIP_H) crc32.h + $(CC) $(UTILFLAGS) $@ fileio.c + +util_.o: util.c $(ZIP_H) + $(CC) $(UTILFLAGS) $@ util.c + +crc32_.o: crc32.c $(ZIP_H) crc32.h + $(CC) $(UTILFLAGS) $@ crc32.c + +crypt_.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) $(UTILFLAGS) $@ crypt.c + +msdos_.o: msdos/msdos.c $(ZIP_H) + $(CC) $(UTILFLAGS) $@ msdos/msdos.c + +match.o: match.S + $(CC) $(ASFLAGS) -x assembler-with-cpp -c -o $@ match.S + +zip.exe: $(OBJZ) $(OBJI) + echo $(OBJZ) > zip.rsp + echo $(OBJI) >> zip.rsp + $(LD) $(LDFLAGS) -o zip @zip.rsp + del zip.rsp + $(STRIP) zip + $(STUBIFY) zip + del zip + +zipcloak.exe: $(OBJC) + $(LD) $(LDFLAGS) $(OBJC) -o zipcloak + $(STRIP) zipcloak + $(STUBIFY) zipcloak + del zipcloak + +zipnote.exe: $(OBJN) + $(LD) $(LDFLAGS) $(OBJN) -o zipnote + $(STRIP) zipnote + $(STUBIFY) zipnote + del zipnote + +zipsplit.exe: $(OBJS) + $(LD) $(LDFLAGS) $(OBJS) -o zipsplit + $(STRIP) zipsplit + $(STUBIFY) zipsplit + del zipsplit diff --git a/msdos/makefile.dj2 b/msdos/makefile.dj2 new file mode 100644 index 0000000..39192ee --- /dev/null +++ b/msdos/makefile.dj2 @@ -0,0 +1,136 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for +# djgpp 2.x +VPATH=.;msdos +# ------------- djgpp ------------- +CPPFLAGS=-I. -DDOS -DASM_CRC $(LOCAL_ZIP) +ASFLAGS=$(CPPFLAGS) +CFLAGS=-Wall -O2 $(CPPFLAGS) +UTILFLAGS=-c -DUTIL $(CFLAGS) -o +CC=gcc +LD=gcc +LDFLAGS=-s + +# ------------- file packer -------- +# Laszlo Molnar who wrote DJ Packer and Markus F. X. J. Oberhumer who wrote +# the compression library used by the DJ Packer have collaborated on the +# Ultimate Packer for eXecutables, which has recently been released. Look +# for upx???d.zip at http://upx.sourceforge.net +# As an alternative, look for "djp.exe", now two years old, in the archive +# mlp107[b,s].zip, found in the same location as csdpmi?[b,s].zip (see below). +# If you have got an executable packer in your PATH, you may reduce the +# size of the disk image of the zip*.exe's by uncommenting the lines +# containing $(DJP) below where the exe's are built. +#DJP=djp -q +DJP=upx -qq --best + +# variables + +#set CRC32 to crc_gcc.o or nothing, depending on whether ASM_CRC is defined: +CRCA_O = crc_gcc.o + +OBJZ = zip.o crypt.o ttyio.o zipfile.o zipup.o fileio.o util.o \ + crc32.o $(CRCA_O) globals.o +OBJI = deflate.o trees.o match.o msdos.o +OBJU = zipfile_.o fileio_.o util_.o globals.o msdos_.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o crc32_.o crypt_.o ttyio.o $(OBJU) +OBJS = zipsplit.o $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h + +# rules + +.SUFFIXES: # Delete make's default suffix list +.SUFFIXES: .exe .out .a .ln .o .c .cc .C .p .f .F .y .l .s .S .h + +.c.o: + $(CC) -c $(CFLAGS) $< -o $@ + +zips: zip.exe zipnote.exe zipsplit.exe zipcloak.exe + +zip.o: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + +zipfile.o: zipfile.c $(ZIP_H) crc32.h + +zipup.o: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h + +fileio.o: fileio.c $(ZIP_H) crc32.h + +util.o: util.c $(ZIP_H) + +globals.o: globals.c $(ZIP_H) + +deflate.o: deflate.c $(ZIP_H) + +trees.o: trees.c $(ZIP_H) + +crc_gcc.o: crc_i386.S + $(CC) $(ASFLAGS) -x assembler-with-cpp -c -o $@ crc_i386.S + +crc32.o: crc32.c $(ZIP_H) crc32.h + +crypt.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + +ttyio.o: ttyio.c $(ZIP_H) crypt.h ttyio.h + +msdos.o: msdos/msdos.c $(ZIP_H) + +zipcloak.o: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + +zipnote.o: zipnote.c $(ZIP_H) revision.h + +zipsplit.o: zipsplit.c $(ZIP_H) revision.h + +zipfile_.o: zipfile.c $(ZIP_H) crc32.h + $(CC) $(UTILFLAGS) $@ zipfile.c + +fileio_.o: fileio.c $(ZIP_H) crc32.h + $(CC) $(UTILFLAGS) $@ fileio.c + +util_.o: util.c $(ZIP_H) + $(CC) $(UTILFLAGS) $@ util.c + +crc32_.o: crc32.c $(ZIP_H) crc32.h + $(CC) $(UTILFLAGS) $@ crc32.c + +crypt_.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) $(UTILFLAGS) $@ crypt.c + +msdos_.o: msdos/msdos.c $(ZIP_H) + $(CC) $(UTILFLAGS) $@ msdos/msdos.c + + +match.o: match.S + $(CC) $(ASFLAGS) -x assembler-with-cpp -c -o $@ match.S + +zip.exe: $(OBJZ) $(OBJI) + echo $(OBJZ) > zip.rsp + echo $(OBJI) >> zip.rsp + $(LD) $(LDFLAGS) -o $@ @zip.rsp + del zip.rsp +# stubedit $@ dpmi=cwsdpmi.exe +# $(DJP) $@ + +zipcloak.exe: $(OBJC) + $(LD) $(LDFLAGS) $(OBJC) -o $@ +# stubedit $@ dpmi=cwsdpmi.exe +# $(DJP) $@ + +zipnote.exe: $(OBJN) + $(LD) $(LDFLAGS) $(OBJN) -o $@ +# stubedit $@ dpmi=cwsdpmi.exe +# $(DJP) $@ + +zipsplit.exe: $(OBJS) + $(LD) $(LDFLAGS) $(OBJS) -o $@ +# stubedit $@ dpmi=cwsdpmi.exe +# $(DJP) $@ + +# These stand alone executables require dpmi services to run. When +# running in a DOS window under windows 3.1 or later, the dpmi server +# is automatically present. Under DOS, if a dpmi server is not installed, +# by default the program will look for "cwsdpmi.exe." If found, it will +# be loaded for the duration of the program. +# cwsdpmi is a "free" dpmi server written by Charles W. Sandmann +# (sandman@clio.rice.edu). It may be found, among other sites, on SimTel +# and its mirrors in the .../vendors/djgpp/v2misc directory. diff --git a/msdos/makefile.emx b/msdos/makefile.emx new file mode 100644 index 0000000..3a50b5b --- /dev/null +++ b/msdos/makefile.emx @@ -0,0 +1,169 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit +# using emx 0.9c for DOS. +# By Kai-Uwe Rommel, Chr. Spieler, E-Yen Tan (and others). +# Last updated 7th January 2007. +# +# This Makefile is a stripped down version of win32/Makefile.emx that +# builds executables applying the default MSDOS emx setup. For variant +# targets (using zlib), and cross-compilation for WIN32 or OS/2, take a +# look into "win32/makefile.emx" resp. "os2/makefile.os2". +# +# Supported Make utilities: +# - Microsoft/IBM nmake (e.g. from MSC 6.0 or newer) +# - dmake 3.8 or higher +# - GNU make, at least version 3.68 (GNUish 16-bit port, RSXNT Make 3.75 in a +# Win95/WinNT DOS box, DJGPP v1.12 Make 3.71, some versions of DJGPP v2.x +# 32-bit Make; current DJGPP v2.01 Make 3.76.1 does NOT work) +# - NOT watcom make +# The "smart" Make utilities mentioned below are Christian Spieler's +# enhanced version of GNUish 16-bit Make (3.74) and his adaption of these +# GNU Make sources to EMX (32-bit). + +# Supported 32-bit C Compilers for MSDOS: +# - GNU gcc (emx kit 0.9c or newer, 32-bit) + +# Supported Assemblers: +# - GNU as with GNU gcc + + +# To use, enter "make/nmake/dmake -f msdos/makefile.emx" +# (this makefile depends on its name being "msdos/makefile.emx"). + +# emx 0.9c, gcc, a.out format, for MS-DOS +CC=gcc -O2 -m486 -Wall +CFLAGS=-DDOS -DMSDOS -DASM_CRC +AS=gcc +ASFLAGS=-Di386 +LDFLAGS=-o ./ +LDFLAGS2=-s -Zsmall-conv +OUT=-o +OBJ=.o +CRCA_O=crc_gcc.o +OBJA=matchgcc.o +OBJZS=msdos.o +OBJUS=msdos_.o +OSDEP_H=msdos/osdep.h +ZIPUP_H=msdos/zipup.h + +#default settings for target dependent macros: +DIRSEP = / +AS_DIRSEP = / +RM = del +LOCAL_OPTS = $(LOCAL_ZIP) +CCFLAGS = $(CFLAGS) $(LOCAL_OPTS) + + +OBJZ1 = zip$(OBJ) zipfile$(OBJ) zipup$(OBJ) fileio$(OBJ) util$(OBJ) \ + crc32$(OBJ) $(CRCA_O) +OBJZ2 = globals$(OBJ) deflate$(OBJ) trees$(OBJ) crypt$(OBJ) \ + ttyio$(OBJ) +OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZS) $(OBJA) + +OBJU1 = zipfile_$(OBJ) fileio_$(OBJ) util_$(OBJ) globals$(OBJ) +OBJU = $(OBJU1) $(OBJUS) + +OBJN = zipnote$(OBJ) $(OBJU) +OBJS = zipsplit$(OBJ) $(OBJU) +OBJC1 = zipcloak$(OBJ) crc32_$(OBJ) crypt_$(OBJ) ttyio$(OBJ) +OBJC = $(OBJC1) $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h $(OSDEP_H) + +# rules + +.SUFFIXES: .c $(OBJ) + +.c$(OBJ): + $(CC) -c -I. $(CCFLAGS) $(OUT)$@ $< + +# targets + +all: zip.exe zipnote.exe zipsplit.exe zipcloak.exe + +zip$(OBJ): zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +zipfile$(OBJ): zipfile.c $(ZIP_H) crc32.h +zipup$(OBJ): zipup.c $(ZIP_H) revision.h crc32.h crypt.h $(ZIPUP_H) +fileio$(OBJ): fileio.c $(ZIP_H) crc32.h +util$(OBJ): util.c $(ZIP_H) +globals$(OBJ): globals.c $(ZIP_H) +deflate$(OBJ): deflate.c $(ZIP_H) +trees$(OBJ): trees.c $(ZIP_H) +crc32$(OBJ): crc32.c $(ZIP_H) crc32.h +crypt$(OBJ): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h +ttyio$(OBJ): ttyio.c $(ZIP_H) crypt.h ttyio.h + +msdos$(OBJ): msdos/msdos.c $(ZIP_H) + $(CC) -c -I. $(CCFLAGS) msdos$(DIRSEP)msdos.c + +win32zip$(OBJ): win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h + $(CC) -c -I. $(CCFLAGS) win32$(DIRSEP)win32zip.c + +win32$(OBJ): win32/win32.c $(ZIP_H) win32/win32zip.h + $(CC) -c -I. $(CCFLAGS) win32$(DIRSEP)win32.c + +nt$(OBJ): win32/nt.c $(ZIP_H) win32/nt.h + $(CC) -c -I. $(CCFLAGS) win32$(DIRSEP)nt.c + +crc_gcc$(OBJ): crc_i386.S # 32bit, GNU AS + $(AS) $(ASFLAGS) -x assembler-with-cpp -c -o $@ crc_i386.S + +matchgcc$(OBJ): match.S + $(AS) $(ASFLAGS) -x assembler-with-cpp -c -o $@ match.S + +zipcloak$(OBJ): zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +zipnote$(OBJ): zipnote.c $(ZIP_H) revision.h +zipsplit$(OBJ): zipsplit.c $(ZIP_H) revision.h + +zipfile_$(OBJ): zipfile.c $(ZIP_H) crc32.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ zipfile.c + +fileio_$(OBJ): fileio.c $(ZIP_H) crc32.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ fileio.c + +util_$(OBJ): util.c $(ZIP_H) + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ util.c + +crc32_$(OBJ): crc32.c $(ZIP_H) crc32.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ crc32.c + +crypt_$(OBJ): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ crypt.c + +msdos_$(OBJ): msdos/msdos.c $(ZIP_H) + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ msdos$(DIRSEP)msdos.c + +win32_$(OBJ): win32/win32.c $(ZIP_H) win32/win32zip.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ win32$(DIRSEP)win32.c + +# This next bit is nasty, but is needed to overcome the MS-DOS command +# line limit as response files for emx's gcc seem to only work if each +# file is on a different line. DJGPP doesn't do this (if you are at all +# interested). + +zip.exe: $(OBJZ) +# for DUMB make utilities, uncomment the following commands: + -@$(RM) zip.rsp + @for %%f in ($(OBJZ1)) do echo %%f >> zip.rsp + @for %%f in ($(OBJZ2)) do echo %%f >> zip.rsp + @for %%f in ($(OBJZS) $(OBJA)) do echo %%f >> zip.rsp + $(CC) $(LDFLAGS)$@ @zip.rsp $(LDFLAGS2) + @$(RM) zip.rsp +# smart make utilities (like well done ports of GNU Make) can use this: +# $(CC) $(LDFLAGS)$@ $(OBJZ) $(LDFLAGS2) + +zipcloak.exe: $(OBJC) +# for DUMB make utilities, uncomment the following commands: + -@$(RM) zipcloak.rsp + @for %%f in ($(OBJC1)) do echo %%f >> zipcloak.rsp + @for %%f in ($(OBJU1)) do echo %%f >> zipcloak.rsp + @for %%f in ($(OBJUS)) do echo %%f >> zipcloak.rsp + $(CC) $(LDFLAGS)$@ @zipcloak.rsp $(LDFLAGS2) + @$(RM) zipcloak.rsp +# smart make utilities (like well done ports of GNU Make) can use this: +# $(CC) $(LDFLAGS)$@ $(OBJC) $(LDFLAGS2) + +zipnote.exe: $(OBJN) + $(CC) $(LDFLAGS)$@ $(OBJN) $(LDFLAGS2) + +zipsplit.exe: $(OBJS) + $(CC) $(LDFLAGS)$@ $(OBJS) $(LDFLAGS2) diff --git a/msdos/makefile.msc b/msdos/makefile.msc new file mode 100644 index 0000000..a7ec9c9 --- /dev/null +++ b/msdos/makefile.msc @@ -0,0 +1,209 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for +# Microsoft C 5.1 and above. + +# To use, do "make makefile.msc" + +# Add -DSMALL_MEM or -DMEDIUM_MEM to the LOC macro if you wish to reduce +# the memory requirements. +# Add -DNO_ASM to CFLAGS and comment out the ASMOBJS definition if +# you do not have masm. +# +# If you want link Zip against zlib to replace the built-in deflate routines, +# the following changes are required: +# - in the definition of "LOC", add "-DUSE_ZLIB" and remove "-DNO_SECURE_TESTS" +# - comment out the "ASMOBJS" symbol definition +# - modify the linking command blocks for zip and zipcloak according to +# the following scheme: +# add a command line "echo ,,,zlib_$(ZIPMODEL); >> zip[c].rsp" just +# before the "$(LD)..." line; and remove the semicolon character from the +# "echo ..." line immediately preceding the just inserted command + + +# Optional nonstandard preprocessor flags (as -DMEDIUM_MEM or -DNO_ASM) +# should be added to the environment via "set LOCAL_ZIP=-DFOO" or added +# to the declaration of LOC here: +LOC = -DDOS -DDYN_ALLOC -DNO_SECURE_TESTS $(LOCAL_ZIP) + +# Zip requires compact or large memory model. +# with 2.1, compact model exceeds 64k code segment; use large model +ZIPMODEL=L # large model for Zip and ZipUtils + +# name of Flag to select memory model for assembler compiles, supported +# values are __SMALL__ , __MEDIUM__ , __COMPACT__ , __LARGE__ : +ASMODEL=__LARGE__ # keep in sync with ZIPMODEL definition !! + +# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc. +CPU_TYP = 0 + +# Uncomment the following macro to use the optimized assembler +# routines in Zip: +ASMOBJS = match.obj crc_i86.obj + +ASCPUFLAG = __$(CPU_TYP)86 + +# ------------- Microsoft C 5.1, 6.0, 7.0 and VC++ Pro 1.0 ------------- +CC=cl +MODEL=-A$(ZIPMODEL) +FP= +# With the feature additions of Zip 3, the default data segment gets occupied +# with too much initialized data to fit into 64k. As a workaround, for some +# source files with large amount of message strings, -Gt is used to +# force data items of size or larger into their own data segments. +COMMON_CFLAGS=-nologo -I. $(MODEL) $(FP) -DMSC $(LOC) -W3 -G$(CPU_TYP) +CFLAGS=$(COMMON_CFLAGS) -Ox +SPECFLAGS=$(COMMON_CFLAGS) -Oaict -Gs +# For MSC/C++ 7.0 and VC++ no special flags are needed: +# SPECFLAGS=$(CFLAGS) +UTILFLAGS=-DUTIL $(CFLAGS) -Fo + +AS=masm +ASFLAGS=-ml -t -D$(ASCPUFLAG) -D$(ASMODEL) $(LOC) +# For MSC 6.0, use: +#AS=ml +#ASFLAGS=-c -D$(ASCPUFLAG) -D$(ASMODEL) $(LOC) +# Supress -DDYN_ALLOC in ASFLAGS if you have suppressed it in CFLAGS + +LD=link +LDFLAGS=/noi/farcall/packcode/e/st:0x1400/m +# If you use an exe packer as recommended below, remove /e from LDFLAGS + +# ------------- Common declarations: +STRIP=rem +# If you don't have UPX, LZEXE, or PKLITE, get one of them. Then define: +# (NOTE: upx needs a 386 or higher system to run the exe compressor) +#STRIP=upx --8086 --best +# or +#STRIP=lzexe +# or (if you've registered PKLITE) +#STRIP=pklite +# and remove /e from LDFLAGS. +# This makes a big difference in .exe size (and possibly load time) + +# ------------- Used by install rule +# set BIN to the directory you want to install the executables to +BIN = c:\util + +# variables +OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \ + crc32.obj globals.obj + +OBJI = deflate.obj trees.obj $(ASMOBJS) msdos.obj + +OBJU = zipfile_.obj fileio_.obj util_.obj globals.obj msdos_.obj +OBJN = zipnote.obj $(OBJU) +OBJC = zipcloak.obj crc32_.obj crypt_.obj ttyio.obj $(OBJU) +OBJS = zipsplit.obj $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h + +ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe + +zips: $(ZIPS) + +zip.obj: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + $(CC) -c $(CFLAGS) -Gt65 $*.c + +# MSC 5.1 generates bad code on zipfile with -Ox +zipfile.obj: zipfile.c $(ZIP_H) crc32.h + $(CC) -c $(SPECFLAGS) $*.c + +zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h + $(CC) -c $(CFLAGS) $*.c + +fileio.obj: fileio.c $(ZIP_H) crc32.h + $(CC) -c $(CFLAGS) $*.c + +util.obj: util.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +globals.obj: globals.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c $(ZIP_H) crc32.h + $(CC) -c $(CFLAGS) $*.c + +crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +msdos.obj: msdos/msdos.c $(ZIP_H) + $(CC) -c $(CFLAGS) msdos/$*.c + +zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +zipnote.obj: zipnote.c $(ZIP_H) revision.h + $(CC) -c $(CFLAGS) $*.c + +# MSC 5.1 dies on zipsplit with -Ox +zipsplit.obj: zipsplit.c $(ZIP_H) revision.h + $(CC) -c $(SPECFLAGS) $*.c + +# MSC 5.1 generates bad code on zipfile with -Ox +zipfile_.obj: zipfile.c $(ZIP_H) crc32.h + $(CC) -c $(SPECFLAGS) -DUTIL -Fo$@ zipfile.c + +fileio_.obj: fileio.c $(ZIP_H) crc32.h + $(CC) -c $(UTILFLAGS)$@ fileio.c + +util_.obj: util.c $(ZIP_H) + $(CC) -c $(UTILFLAGS)$@ util.c + +crc32_.obj: crc32.c $(ZIP_H) crc32.h + $(CC) -c $(UTILFLAGS)$@ crc32.c + +crypt_.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) -c $(UTILFLAGS)$@ crypt.c + +msdos_.obj: msdos/msdos.c $(ZIP_H) + $(CC) -c $(UTILFLAGS)$@ msdos/msdos.c + +crc_i86.obj: msdos/crc_i86.asm + $(AS) $(ASFLAGS) msdos\crc_i86.asm ; + +match.obj: msdos/match.asm + $(AS) $(ASFLAGS) msdos\match.asm ; + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +zip.exe: $(OBJZ) $(OBJI) + echo $(OBJZ)+ > zip.rsp + echo $(OBJI); >> zip.rsp + $(LD) $(LDFLAGS) @zip.rsp + del zip.rsp + $(STRIP) zip.exe + +zipcloak.exe: $(OBJC) + echo $(OBJC); > zipc.rsp + $(LD) $(LDFLAGS) @zipc.rsp + del zipc.rsp + $(STRIP) zipcloak.exe + +zipnote.exe: $(OBJN) + echo $(OBJN); > zipn.rsp + $(LD) $(LDFLAGS) @zipn.rsp + del zipn.rsp + $(STRIP) zipnote.exe + +zipsplit.exe: $(OBJS) + echo $(OBJS); > zips.rsp + $(LD) $(LDFLAGS) @zips.rsp + del zips.rsp + $(STRIP) zipsplit.exe + +# No `install' and `clean' target possible as long as MSC's old MAKE utility +# is supported (MSC 5.1 Make always tries to update ALL targets. The result +# is that install and clean are always executed, unless an error occured.) +#install: $(ZIPS) +# copy /b *.exe $(BIN) +# +#clean: +# del *.obj +# del *.exe diff --git a/msdos/makefile.tc b/msdos/makefile.tc new file mode 100644 index 0000000..9ce3e32 --- /dev/null +++ b/msdos/makefile.tc @@ -0,0 +1,177 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for +# Turbo C 2.0. (Thanks to Andrew Cadach ) + +# To use, do "make -fmakefile.tc" + +# WARNING: the small model is not supported. You must use the large model. +# Add -DSMALL_MEM or -DMEDIUM_MEM to the LOC macro if you wish to reduce +# the memory requirements. +# Add -DNO_ASM to CFLAGS and comment out the ASMOBJS definition if +# you do not have tasm. + +# Optional nonstandard preprocessor flags (as -DMEDIUM_MEM or -DNO_ASM) +# should be added to the environment via "set LOCAL_ZIP=-DFOO" or added +# to the declaration of LOC here: +LOC = -DDOS -DNO_SECURE_TESTS $(LOCAL_ZIP) + +# Zip requires compact or large memory model. +# with 2.1, compact model exceeds 64k code segment; use large model +ZIPMODEL=l # large model for Zip and ZipUtils + +# name of Flag to select memory model for assembler compiles, supported +# values are __SMALL__ , __MEDIUM__ , __COMPACT__ , __LARGE__ : +ASMODEL=__LARGE__ # keep in sync with ZIPMODEL definition !! + +# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc. +CPU_TYP = 0 + +# Uncomment the following macro to use the optimized assembler +# routines in Zip: +ASMOBJS = match.obj crc_i86.obj + +ASCPUFLAG = __$(CPU_TYP)86 + +# ------------- Turbo C 2.0 ------------- +MODEL=-m$(ZIPMODEL) +CFLAGS=-w -w-eff -w-def -w-sig -w-cln -a -d -G -O -Z $(MODEL) $(LOC) +UTILFLAGS=-DUTIL $(CFLAGS) -o +CC=tcc + +# Old versions of tasm (prior to 2.01) may not like the "-m2" option... +AS=tasm +ASFLAGS=-ml -t -m2 -DDYN_ALLOC -DSS_NEQ_DS -D$(ASCPUFLAG) -D$(ASMODEL) $(LOC) + +LD=tcc +LDFLAGS=$(MODEL) + +# ------------- Common declarations: +STRIP=rem +# If you don't have UPX, LZEXE, or PKLITE, get one of them. Then define: +# (NOTE: upx needs a 386 or higher system to run the exe compressor) +#STRIP=upx --8086 --best +# or +#STRIP=lzexe +# or (if you've registered PKLITE) +#STRIP=pklite +# This makes a big difference in .exe size (and possibly load time) + +# ------------- Used by install rule +# set BIN to the directory you want to install the executables to +BIN = c:\util + +# variables +OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \ + crc32.obj globals.obj + +OBJI = deflate.obj trees.obj $(ASMOBJS) msdos.obj + +OBJU = _zipfile.obj _fileio.obj _util.obj globals.obj _msdos.obj +OBJN = zipnote.obj $(OBJU) +OBJC = zipcloak.obj _crc32.obj _crypt.obj ttyio.obj $(OBJU) +OBJS = zipsplit.obj $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h + +ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe + +zips: $(ZIPS) + +zip.obj: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +zipfile.obj: zipfile.c $(ZIP_H) crc32.h + $(CC) -c $(CFLAGS) $*.c + +zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h + $(CC) -c $(CFLAGS) $*.c + +fileio.obj: fileio.c $(ZIP_H) crc32.h + $(CC) -c $(CFLAGS) $*.c + +util.obj: util.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +globals.obj: globals.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c $(ZIP_H) crc32.h + $(CC) -c $(CFLAGS) $*.c + +crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +msdos.obj: msdos/msdos.c $(ZIP_H) + $(CC) -c $(CFLAGS) msdos/$*.c + +zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + $(CC) -c $(CFLAGS) -o$* $*.c + +zipnote.obj: zipnote.c $(ZIP_H) revision.h + $(CC) -c $(CFLAGS) -o$* $*.c + +zipsplit.obj: zipsplit.c $(ZIP_H) revision.h + $(CC) -c $(CFLAGS) -o$* $*.c + +_zipfile.obj: zipfile.c $(ZIP_H) crc32.h + $(CC) -c $(UTILFLAGS)$* zipfile.c + +_fileio.obj: fileio.c $(ZIP_H) crc32.h + $(CC) -c $(UTILFLAGS)$* fileio.c + +_util.obj: util.c $(ZIP_H) + $(CC) -c $(UTILFLAGS)$* util.c + +_crc32.obj: crc32.c $(ZIP_H) crc32.h + $(CC) -c $(UTILFLAGS)$* crc32.c + +_crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) -c $(UTILFLAGS)$* crypt.c + +_msdos.obj: msdos/msdos.c $(ZIP_H) + $(CC) -c $(UTILFLAGS)$* msdos/msdos.c + +crc_i86.obj: msdos/crc_i86.asm + $(AS) $(ASFLAGS) msdos\crc_i86.asm ; + +match.obj: msdos/match.asm + $(AS) $(ASFLAGS) msdos\match.asm ; + +# make sure the command line fits in the MS/DOS 128 byte limit: +zip.exe: $(OBJZ) $(OBJI) + rem ignore any warnings in the following renaming commands: + ren _*.obj _*.ob + ren zipcloak.obj *.ob + ren zipnote.obj *.ob + ren zipsplit.obj *.ob + $(LD) $(LDFLAGS) -ezip.exe *.obj + ren _*.ob _*.obj + ren zip???*.ob *.obj + $(STRIP) zip.exe + +zipcloak.exe: $(OBJC) + $(LD) $(LDFLAGS) -ezipcloak.exe $(OBJC) + $(STRIP) zipcloak.exe + +zipnote.exe: $(OBJN) + $(LD) $(LDFLAGS) -ezipnote.exe $(OBJN) + $(STRIP) zipnote.exe + +zipsplit.exe: $(OBJS) + $(LD) $(LDFLAGS) -ezipsplit.exe $(OBJS) + $(STRIP) zipsplit.exe + +install: $(ZIPS) + copy /b *.exe $(BIN) + +clean: + del *.obj + del *.exe diff --git a/msdos/makefile.wat b/msdos/makefile.wat new file mode 100644 index 0000000..dd4d8cd --- /dev/null +++ b/msdos/makefile.wat @@ -0,0 +1,256 @@ +# WMAKE makefile for 16 bit MSDOS or 32 bit DOS extender (PMODE/W or DOS/4GW) +# using Watcom C/C++ v11.0+, by Paul Kienitz, last revised 07 Aug 2005. +# Makes Zip.exe, ZipNote.exe, ZipCloak.exe, and ZipSplit.exe. +# +# Invoke from Zip source dir with "WMAKE -F MSDOS\MAKEFILE.WAT [targets]" +# To build with debug info use "WMAKE DEBUG=1 ..." +# To build with no assembly modules use "WMAKE NOASM=1 ..." +# To make the PMODE/W version use "WMAKE PM=1 ..." +# To make the DOS/4GW version use "WMAKE GW=1 ..." (overrides PM=1) +# Note: specifying PM or GW without NOASM requires that the win32 source +# directory be present, so it can access the 32 bit assembly sources. +# PMODE/W is recommended over DOS/4GW for best performance. +# To create a low memory usage version of Zip, use "WMAKE WSIZE=8192 ..." +# (or whatever power of two less than 32768 you wish) -- this also causes +# SMALL_MEM to be defined. Compression performance will be reduced. +# This currently is not supported with PM=1 or GW=1. +# +# Other options to be fed to the compiler and assembler can be specified in +# an environment variable called LOCAL_ZIP. + +variation = $(%LOCAL_ZIP) + +# Stifle annoying "Delete this file?" questions when errors occur: +.ERASE + +.EXTENSIONS: +.EXTENSIONS: .exe .obj .c .h .asm + +# We maintain multiple sets of object files in different directories so that +# we can compile msdos, dos/4gw or pmode/w, and win32 versions of Zip without +# their object files interacting. The following var must be a directory name +# ending with a backslash. All object file names must include this macro +# at the beginning, for example "$(O)foo.obj". + +!ifdef GW +PM = 1 # both protected mode formats use the same object files +!endif + +!ifdef DEBUG +! ifdef PM +OBDIR = od32d +! else +! ifdef WSIZE +OBDIR = od16l +size = -DWSIZE=$(WSIZE) -DSMALL_MEM +! else +OBDIR = od16d +size = -DMEDIUM_MEM +! endif +! endif +!else +! ifdef PM +OBDIR = ob32d +! else +! ifdef WSIZE +OBDIR = ob16l +size = -DWSIZE=$(WSIZE) -DSMALL_MEM +! else +OBDIR = ob16d +size = -DMEDIUM_MEM +! endif +! endif +!endif +O = $(OBDIR)\ # comment here so backslash won't continue the line + +# The assembly hot-spot code in crc_i[3]86.asm and match[32].asm is +# optional. This section controls its usage. + +!ifdef NOASM + # C source +asmob = +cvars = $+$(cvars)$- -DDYN_ALLOC -DNO_ASM # or ASM_CRC might default on! +# "$+$(foo)$-" means expand foo as it has been defined up to now; normally, +# this make defers inner expansion until the outer macro is expanded. +!else # !NOASM +asmob = $(O)crc.obj $(O)match.obj +! ifdef PM +cvars = $+$(cvars)$- -DASM_CRC -DASMV # no DYN_ALLOC with match32.asm +crc_s = win32\crc_i386.asm # requires that the win32 directory be present +mat_s = win32\match32.asm # ditto +! else +cvars = $+$(cvars)$- -DDYN_ALLOC -DASM_CRC -DASMV +avars = $+$(avars)$- -DDYN_ALLOC +crc_s = msdos\crc_i86.asm +mat_s = msdos\match.asm +! endif +!endif + +# Now we have to pick out the proper compiler and options for it. This gets +# pretty complicated with the PM, GW, DEBUG, and NOASM options... + +link = wlink +asm = wasm + +!ifdef PM +cc = wcc386 +# Use Pentium Pro timings, register args, static strings in code: +cflags = -bt=DOS -mf -6r -zt -zq +aflags = -bt=DOS -mf -3 -zq +cvars = $+$(cvars)$- -DDOS $(variation) +avars = $+$(avars)$- -DWATCOM_DSEG $(variation) + +! ifdef GW +lflags = sys DOS4G +! else +# THIS REQUIRES THAT PMODEW.EXE BE FINDABLE IN THE COMMAND PATH. +# It does NOT require you to add a pmodew entry to wlink.lnk or wlsystem.lnk. +defaultlibs = libpath %WATCOM%\lib386 libpath %WATCOM%\lib386\dos +lflags = format os2 le op osname='PMODE/W' op stub=pmodew.exe $(defaultlibs) +! endif + +!else # plain 16-bit DOS: + +cc = wcc +# Use plain 8086 instructions, large memory model, static strings in code: +cflags = -bt=DOS -ml -0 -zt -zq +aflags = -bt=DOS -ml -0 -zq +cvars = $+$(cvars)$- -DDOS $(size) $(variation) +avars = $+$(avars)$- $(size) $(variation) +lflags = sys DOS +!endif # !PM + +# Specify optimizations, or a nonoptimized debugging version: + +!ifdef DEBUG +cdebug = -od -d2 +ldebug = d w all op symf +!else +! ifdef PM +cdebug = -s -obhikl+rt -oe=100 -zp8 +# -oa helps slightly but might be dangerous. +! else +cdebug = -s -oehiklrt +! endif +ldebug = op el +!endif + +# How to compile most sources: +.c.obj: + $(cc) $(cdebug) $(cflags) $(cvars) $[@ -fo=$@ + +# Our object files. OBJZ is for Zip, OBJC is for ZipCloak, OBJN is for +# ZipNote, and OBJS is for ZipSplit: + +OBJZ2 = $(O)zip.obj $(O)crypt.obj $(O)ttyio.obj $(O)zipfile.obj $(O)zipup.obj +OBJZA = $(OBJZ2) $(O)util.obj $(O)fileio.obj $(O)deflate.obj +OBJZB = $(O)trees.obj $(O)globals.obj $(O)crc32.obj $(asmob) $(O)msdos.obj + +OBJU2 = $(O)zipfile_.obj $(O)fileio_.obj $(O)util_.obj $(O)globals.obj +OBJ_U = $(OBJU2) $(O)msdos_.obj + +OBJC = $(O)zipcloak.obj $(O)crc32_.obj $(O)crypt_.obj $(O)ttyio.obj $(OBJ_U) + +OBJN = $(O)zipnote.obj $(OBJ_U) + +OBJS = $(O)zipsplit.obj $(OBJ_U) + +# Common header files included by all C sources: + +ZIP_H = zip.h ziperr.h tailor.h msdos\osdep.h + + +# HERE WE GO! By default, make all targets: +all: Zip.exe ZipNote.exe ZipCloak.exe ZipSplit.exe + +# Convenient shorthand options for single targets: +z: Zip.exe .SYMBOLIC +n: ZipNote.exe .SYMBOLIC +c: ZipCloak.exe .SYMBOLIC +s: ZipSplit.exe .SYMBOLIC + +Zip.exe: $(OBDIR) $(OBJZA) $(OBJZB) $(OBJV) + set WLK_VA=file {$(OBJZA)} + set WLK_VB=file {$(OBJZB) $(OBJV)} + $(link) $(lflags) $(ldebug) name $@ @WLK_VA @WLK_VB + set WLK_VA= + set WLK_VB= +# We use WLK_VA and WLK_VB to keep the size of each command under 256 chars. + +ZipNote.exe: $(OBDIR) $(OBJN) + set WLK_VAR=file {$(OBJN)} + $(link) $(lflags) $(ldebug) name $@ @WLK_VAR + set WLK_VAR= + +ZipCloak.exe: $(OBDIR) $(OBJC) + set WLK_VAR=file {$(OBJC)} + $(link) $(lflags) $(ldebug) name $@ @WLK_VAR + set WLK_VAR= + +ZipSplit.exe: $(OBDIR) $(OBJS) + set WLK_VAR=file {$(OBJS)} + $(link) $(lflags) $(ldebug) name $@ @WLK_VAR + set WLK_VAR= + +# Source dependencies: + +$(O)crc32.obj: crc32.c $(ZIP_H) crc32.h +$(O)crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h +$(O)deflate.obj: deflate.c $(ZIP_H) +$(O)fileio.obj: fileio.c $(ZIP_H) crc32.h +$(O)globals.obj: globals.c $(ZIP_H) +$(O)trees.obj: trees.c $(ZIP_H) +$(O)ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h +$(O)util.obj: util.c $(ZIP_H) +$(O)zip.obj: zip.c $(ZIP_H) crc32.h crypt.h revision.h ttyio.h +$(O)zipfile.obj: zipfile.c $(ZIP_H) crc32.h +$(O)zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos\zipup.h +$(O)zipnote.obj: zipnote.c $(ZIP_H) revision.h +$(O)zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +$(O)zipsplit.obj: zipsplit.c $(ZIP_H) revision.h + +# Special case object files: + +$(O)msdos.obj: msdos\msdos.c $(ZIP_H) + $(cc) $(cdebug) $(cflags) $(cvars) msdos\msdos.c -fo=$@ + +$(O)match.obj: $(mat_s) + $(asm) $(aflags) $(avars) $(mat_s) -fo=$@ + +$(O)crc.obj: $(crc_s) + $(asm) $(aflags) $(avars) $(crc_s) -fo=$@ + +# Variant object files for ZipNote, ZipCloak, and ZipSplit: + +$(O)zipfile_.obj: zipfile.c $(ZIP_H) crc32.h + $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL zipfile.c -fo=$@ + +$(O)fileio_.obj: fileio.c $(ZIP_H) crc32.h + $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL fileio.c -fo=$@ + +$(O)util_.obj: util.c $(ZIP_H) + $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL util.c -fo=$@ + +$(O)crc32_.obj: crc32.c $(ZIP_H) crc32.h + $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL crc32.c -fo=$@ + +$(O)crypt_.obj: crypt.c $(ZIP_H) crc32.h crypt.h ttyio.h + $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL crypt.c -fo=$@ + +$(O)msdos_.obj: msdos\msdos.c $(ZIP_H) + $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL msdos\msdos.c -fo=$@ + +# Creation of subdirectory for intermediate files +$(OBDIR): + -mkdir $@ + +# Unwanted file removal: + +clean: .SYMBOLIC + del $(O)*.obj + +cleaner: clean .SYMBOLIC + del Zip.exe + del ZipNote.exe + del ZipCloak.exe + del ZipSplit.exe diff --git a/msdos/match.asm b/msdos/match.asm new file mode 100644 index 0000000..998881e --- /dev/null +++ b/msdos/match.asm @@ -0,0 +1,477 @@ +;=========================================================================== +; Copyright (c) 1990-2008 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 2007-Mar-04 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 +;=========================================================================== +; +; match.asm by Jean-loup Gailly. + +; match.asm, optimized version of longest_match() in deflate.c +; Must be assembled with masm -ml. To be used only with C compact model +; or large model. (For large model, assemble with -D__LARGE__). +; This file is only optional. If you don't have masm or tasm, use the +; C version (add -DNO_ASM to CFLAGS in makefile.msc and remove match.obj +; from OBJI). If you have reduced WSIZE in zip.h, then make sure this is +; assembled with an equivalent -DWSIZE=. +; +; The code has been prepared for two different C compiler calling conventions +; and contains some support for dynamically allocated working space. +; The different environments are selected by two conditional flags: +; DYN_ALLOC : select support for malloc'ed working space +; SS_NEQ_DS : relaxes assumption that stack and default data segments +; are identical +; When SS_NEQ_DS is defined, the code segment is used to store some +; local variables. This (bad) coding practice is very likely to break any +; `segment protection scheme', it will most probably only work for real +; mode programs. +; +; Turbo C 2.0 does not support static allocation of more than 64K bytes per +; file, and does not have SS == DS. So TC and BC++ users must use: +; tasm -ml -DDYN_ALLOC -DSS_NEQ_DS match; +; +; To simplify the code, the option -DDYN_ALLOC is supported for OS/2 +; only if the arrays are guaranteed to have zero offset (allocated by +; halloc). We also require SS==DS. This is satisfied for MSC but not Turbo C. +; +; Per default, test code is included to check if the above requirements are +; fulfilled. This test code can be disabled by defining the compile time +; option flag NO_SECURE_TESTS when compiling for a production executable. +; This shortens the code size (but the performance gain is neglectable). +; The security tests should remain enabled, when a new C compiler +; and/or a new set of compilation options is tried. + + name match + +; Do NOT assemble this source if external crc32 routine from zlib gets used. +; +ifndef USE_ZLIB + +ifdef DEBUG + VERBOSE_INFO EQU 1 +else + ifdef _AS_MSG_ + VERBOSE_INFO EQU 1 + else + VERBOSE_INFO EQU 0 + endif +endif + +ifndef __SMALL__ + ifndef __COMPACT__ + ifndef __MEDIUM__ + ifndef __LARGE__ + ifndef __HUGE__ +; __SMALL__ EQU 1 + endif + endif + endif + endif +endif + +ifdef __HUGE__ +; .MODEL Huge + ifndef @CodeSize + @CodeSize EQU 1 + endif + ifndef @DataSize + @DataSize EQU 1 + endif + Save_DS EQU 1 + if VERBOSE_INFO + if1 + %out Assembling for C, Huge memory model + endif + endif +else + ifdef __LARGE__ +; .MODEL Large + ifndef @CodeSize + @CodeSize EQU 1 + endif + ifndef @DataSize + @DataSize EQU 1 + endif + if VERBOSE_INFO + if1 + %out Assembling for C, Large memory model + endif + endif + else + ifdef __COMPACT__ +; .MODEL Compact + ifndef @CodeSize + @CodeSize EQU 0 + endif + ifndef @DataSize + @DataSize EQU 1 + endif + if VERBOSE_INFO + if1 + %out Assembling for C, Compact memory model + endif + endif + else + ifdef __MEDIUM__ +; .MODEL Medium + ifndef @CodeSize + @CodeSize EQU 1 + endif + ifndef @DataSize + @DataSize EQU 0 + endif + if VERBOSE_INFO + if1 + %out Assembling for C, Medium memory model + endif + endif + else +; .MODEL Small + ifndef @CodeSize + @CodeSize EQU 0 + endif + ifndef @DataSize + @DataSize EQU 0 + endif + if VERBOSE_INFO + if1 + %out Assembling for C, Small memory model + endif + endif + endif + endif + endif +endif + +if @CodeSize + LCOD_OFS EQU 2 +else + LCOD_OFS EQU 0 +endif + +IF @DataSize + LDAT_OFS EQU 2 +else + LDAT_OFS EQU 0 +endif + +ifdef Save_DS +; (di,si,ds)+(size, return address) + SAVE_REGS EQU 6+(4+LCOD_OFS) +else +; (di,si)+(size, return address) + SAVE_REGS EQU 4+(4+LCOD_OFS) +endif + +; +; Selection of the supported CPU instruction set and initialization +; of CPU type related macros: +; +ifdef __586 + Use_286_code EQU 1 + Align_Size EQU 16 ; paragraph alignment on Pentium + Alig_PARA EQU 1 ; paragraph aligned code segment +else +ifdef __486 + Use_286_code EQU 1 + Align_Size EQU 4 ; dword alignment on 32 bit processors + Alig_PARA EQU 1 ; paragraph aligned code segment +else +ifdef __386 + Use_286_code EQU 1 + Align_Size EQU 4 ; dword alignment on 32 bit processors + Alig_PARA EQU 1 ; paragraph aligned code segment +else +ifdef __286 + Use_286_code EQU 1 + Align_Size EQU 2 ; word alignment on 16 bit processors + Alig_PARA EQU 0 ; word aligned code segment +else +ifdef __186 + Use_186_code EQU 1 + Align_Size EQU 2 ; word alignment on 16 bit processors + Alig_PARA EQU 0 ; word aligned code segment +else + Align_Size EQU 2 ; word alignment on 16 bit processors + Alig_PARA EQU 0 ; word aligned code segment +endif ;?__186 +endif ;?__286 +endif ;?__386 +endif ;?__486 +endif ;?__586 + +ifdef Use_286_code + .286 + Have_80x86 EQU 1 +else +ifdef Use_186_code + .186 + Have_80x86 EQU 1 +else + .8086 + Have_80x86 EQU 0 +endif ;?Use_186_code +endif ;?Use_286_code + +ifndef DYN_ALLOC + extrn _prev : word + extrn _window : byte + prev equ _prev ; offset part + window equ _window +endif + +_DATA segment word public 'DATA' + extrn _nice_match : word + extrn _match_start : word + extrn _prev_length : word + extrn _good_match : word + extrn _strstart : word + extrn _max_chain_length : word +ifdef DYN_ALLOC + extrn _prev : word + extrn _window : word + prev equ 0 ; offset forced to zero + window equ 0 + window_seg equ _window[2] + window_off equ 0 +else + wseg dw seg _window + window_seg equ wseg + window_off equ offset _window +endif +_DATA ends + +DGROUP group _DATA + +if @CodeSize +if Alig_PARA +MATCH_TEXT SEGMENT PARA PUBLIC 'CODE' +else +MATCH_TEXT SEGMENT WORD PUBLIC 'CODE' +endif + assume cs: MATCH_TEXT, ds: DGROUP +else ;!@CodeSize +if Alig_PARA +_TEXT segment para public 'CODE' +else +_TEXT segment word public 'CODE' +endif + assume cs: _TEXT, ds: DGROUP +endif ;?@CodeSize + + public _match_init + public _longest_match + +ifndef WSIZE + WSIZE equ 32768 ; keep in sync with zip.h ! +endif + MIN_MATCH equ 3 + MAX_MATCH equ 258 + MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1) + MAX_DIST equ (WSIZE-MIN_LOOKAHEAD) + +ifdef DYN_ALLOC + ifdef SS_NEQ_DS + prev_ptr dw seg _prev ; pointer to the prev array + endif +else + prev_ptr dw seg _prev ; pointer to the prev array +endif +ifdef SS_NEQ_DS + match_start dw 0 ; copy of _match_start if SS != DS + nice_match dw 0 ; copy of _nice_match if SS != DS +endif + +; initialize or check the variables used in match.asm. + +if @CodeSize +_match_init proc far ; 'proc far' for large model +else +_match_init proc near ; 'proc near' for compact model +endif +ifdef SS_NEQ_DS + ma_start equ cs:match_start ; does not work on OS/2 + nice equ cs:nice_match +else + assume ss: DGROUP + ma_start equ ss:_match_start + nice equ ss:_nice_match + ifndef NO_SECURE_TESTS + mov ax,ds + mov bx,ss + cmp ax,bx ; SS == DS? + jne fatal_err + endif +endif +ifdef DYN_ALLOC + ifndef NO_SECURE_TESTS + cmp _prev[0],0 ; verify zero offset + jne fatal_err + cmp _window[0],0 + jne fatal_err + endif + ifdef SS_NEQ_DS + mov ax,_prev[2] ; segment value + mov cs:prev_ptr,ax ; ugly write to code, crash on OS/2 + prev_seg equ cs:prev_ptr + else + prev_seg equ ss:_prev[2] ; works on OS/2 if SS == DS + endif +else + prev_seg equ cs:prev_ptr +endif + ret +ifndef NO_SECURE_TESTS +if @CodeSize + extrn _exit : far ; 'far' for large model +else + extrn _exit : near ; 'near' for compact model +endif +fatal_err: ; (quiet) emergency stop: + call _exit ; incompatible "global vars interface" +endif + +_match_init endp + +; ----------------------------------------------------------------------- +; Set match_start to the longest match starting at the given string and +; return its length. Matches shorter or equal to prev_length are discarded, +; in which case the result is equal to prev_length and match_start is +; garbage. +; IN assertions: cur_match is the head of the hash chain for the current +; string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + +; int longest_match(cur_match) + + align Align_Size + +if @CodeSize +_longest_match proc far ; 'proc far' for large model +else +_longest_match proc near ; 'proc near' for compact model +endif + push bp + mov bp,sp + push di + push si + push ds + +if @CodeSize + cur_match equ word ptr [bp+6] ; [bp+6] for large model +else + cur_match equ word ptr [bp+4] ; [bp+4] for compact model +endif + +; window equ es:window (es:0 for DYN_ALLOC) +; prev equ ds:prev +; match equ es:si +; scan equ es:di +; chain_length equ bp +; best_len equ bx +; limit equ dx + + mov si,cur_match ; use bp before it is destroyed +ifdef SS_NEQ_DS + mov ax,_nice_match + mov nice,ax ; ugly write to code, crash on OS/2 +endif + mov dx,_strstart + mov bp,_max_chain_length ; chain_length = max_chain_length + mov di,dx + sub dx,MAX_DIST ; limit = strstart-MAX_DIST + cld ; string ops increment si and di + jae limit_ok + sub dx,dx ; limit = NIL +limit_ok: + add di,2+window_off ; di = offset(window + strstart + 2) + mov bx,_prev_length ; best_len = prev_length + mov es,window_seg + mov ax,es:[bx+di-3] ; ax = scan[best_len-1..best_len] + mov cx,es:[di-2] ; cx = scan[0..1] + cmp bx,_good_match ; do we have a good match already? + mov ds,prev_seg ; (does not destroy the flags) + assume ds: nothing + jb do_scan ; good match? +if Have_80x86 + shr bp,2 ; chain_length >>= 2 +else + shr bp,1 ; chain_length >>= 2 + shr bp,1 +endif + jmp short do_scan + + align Align_Size ; align destination of branch +long_loop: +; at this point, ds:di == scan+2, ds:si == cur_match + mov ax,[bx+di-3] ; ax = scan[best_len-1..best_len] + mov cx,[di-2] ; cx = scan[0..1] + mov ds,prev_seg ; reset ds to address the prev array +short_loop: +; at this point, di == scan+2, si = cur_match, +; ax = scan[best_len-1..best_len] and cx = scan[0..1] +if (WSIZE-32768) + and si,WSIZE-1 ; not needed if WSIZE=32768 +endif + shl si,1 ; cur_match as word index + dec bp ; --chain_length + mov si,prev[si] ; cur_match = prev[cur_match] + jz the_end + cmp si,dx ; cur_match <= limit ? + jbe the_end +do_scan: + cmp ax,word ptr es:window[bx+si-1] ; check match at best_len-1 + jne short_loop + cmp cx,word ptr es:window[si] ; check min_match_length match + jne short_loop + + mov cx,es + add si,2+window_off ; si = match + mov ds,cx ; ds = es = window + mov cx,(MAX_MATCH-2)/2 ; scan for at most MAX_MATCH bytes + mov ax,di ; ax = scan+2 + repe cmpsw ; loop until mismatch + je maxmatch ; match of length MAX_MATCH? +mismatch: + mov cl,[di-2] ; mismatch on first or second byte? + xchg ax,di ; di = scan+2, ax = end of scan + sub cl,[si-2] ; cl = 0 if first bytes equal + sub ax,di ; ax = len + sub si,2+window_off ; si = cur_match + len + sub si,ax ; si = cur_match + sub cl,1 ; set carry if cl == 0 (can't use DEC) + adc ax,0 ; ax = carry ? len+1 : len + cmp ax,bx ; len > best_len ? + jle long_loop + mov ma_start,si ; match_start = cur_match + mov bx,ax ; bx = best_len = len + cmp ax,nice ; len >= nice_match ? + jl long_loop +the_end: + pop ds + assume ds: DGROUP +ifdef SS_NEQ_DS + mov ax,ma_start ; garbage if no match found + mov ds:_match_start,ax +endif + pop si + pop di + pop bp + mov ax,bx ; result = ax = best_len + ret +maxmatch: ; come here if maximum match + cmpsb ; increment si and di + jmp mismatch ; force match_length = MAX_LENGTH + +_longest_match endp + +if @CodeSize +MATCH_TEXT ENDS +else +_TEXT ENDS +endif +; +endif ;!USE_ZLIB +; +end diff --git a/msdos/msdos.c b/msdos/msdos.c new file mode 100644 index 0000000..4f71397 --- /dev/null +++ b/msdos/msdos.c @@ -0,0 +1,1126 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2005-Feb-10 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#include "zip.h" + +#ifndef UTIL /* little or no material in this file is used by UTIL */ + +#include +#include + + +#if defined(__GO32__) || defined(__TURBOC__) +# include /* prototypes of find*() */ + typedef struct ffblk ff_dir; +# define FATTR (hidden_files ? FA_HIDDEN+FA_SYSTEM+FA_DIREC : FA_DIREC) +# define FFIRST(n,d,a) findfirst(n,(struct ffblk *)d,a) +# define FNEXT(d) findnext((struct ffblk *)d) +# if (defined(__TURBOC__) || (defined(__DJGPP__) && (__DJGPP__ >=2))) +# if (defined(__DJGPP__) && (__DJGPP__ == 2) && (__DJGPP_MINOR__ == 0)) +# include +# endif +# define GetFileMode(name) _chmod(name, 0) +# define SetFileMode(name, attr) _chmod(name, 1, attr) +# else /* DJGPP v1.x */ +# define GetFileMode(name) bdosptr(0x43, (name), 0) +# endif +#endif /* __GO32__ || __TURBOC__ */ + +#if defined(MSC) || defined(__WATCOMC__) + typedef struct find_t ff_dir; +# define FATTR (hidden_files ? _A_HIDDEN+_A_SYSTEM+_A_SUBDIR : _A_SUBDIR) +# ifndef FA_LABEL +# define FA_LABEL _A_VOLID +# endif +# define FFIRST(n,d,a) _dos_findfirst(n,a,(struct find_t *)d) +# define FNEXT(d) _dos_findnext((struct find_t *)d) +# define ff_name name +# define ff_fdate wr_date +# define ff_ftime wr_time +# define ff_attrib attrib +#endif /* MSC || __WATCOMC__ */ + +#ifdef __EMX__ +# ifdef EMX_OBSOLETE /* emx 0.9b or earlier */ +# define size_t xxx_size_t +# define wchar_t xxx_wchar_t +# define tm xxx_tm +# include +# undef size_t +# undef wchar_t +# undef tm +# else /* !EMX_OBSOLETE */ /* emx 0.9c or newer */ +# include +# endif /* ?EMX_OBSOLETE */ + typedef struct _find ff_dir; +# define FATTR (hidden_files ? _A_HIDDEN+_A_SYSTEM+_A_SUBDIR : _A_SUBDIR) +# define FA_LABEL _A_VOLID +# define FFIRST(n,d,a) __findfirst(n,a,d) +# define FNEXT(d) __findnext(d) +# define ff_name name +# define ff_fdate date +# define ff_ftime time +# define ff_attrib attr +# define GetFileMode(name) __chmod(name, 0, 0) +# define SetFileMode(name, attr) __chmod(name, 1, attr) +#endif /* __EMX__ */ + +#ifndef SetFileMode +# define SetFileMode(name, attr) _dos_setfileattr(name, attr) +#endif + + +#define PAD 0 +#define PATH_END '/' + +/* Library functions not in (most) header files */ +int rmdir OF((const char *)); +int utime OF((char *, ztimbuf *)); + +/* Local functions */ +#ifndef GetFileMode +int GetFileMode OF((char *name)); +#endif /* !GetFileMode */ + +local int initDirSearch OF((char *name, ff_dir *ff_context_p)); +local char *getVolumeLabel OF((int, ulg *, ulg *, time_t *)); +local int wild_recurse OF((char *, char *)); +local int procname_dos OF((char *n, int caseflag, unsigned attribs)); +local int is_running_on_windows OF((void)); + +#define MSDOS_INVALID_ATTR 0xFF +#define getDirEntryAttr(d) ((d)->ff_attrib) + +/* Module level variables */ +extern char *label; +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +/* Module level constants */ +local ZCONST char wild_match_all[] = "*.*"; + + +#ifndef GetFileMode +int GetFileMode(char *name) +{ + unsigned int attr = 0; + return (_dos_getfileattr(name, &attr) ? -1 : attr); +} +#endif /* !GetFileMode */ + +local int initDirSearch(name, ff_context_p) + char *name; /* name of directory to scan */ + ff_dir *ff_context_p; /* pointer to FFIRST/FNEXT context structure */ +{ + int r; /* FFIRST return value */ + char *p, *q; /* temporary copy of name, and aux pointer */ + + if ((p = malloc(strlen(name) + (2 + sizeof(wild_match_all)))) == NULL) + return ZE_MEM; + + strcpy(p, name); + q = p + strlen(p); + if (q[-1] == ':') + *q++ = '.'; + if ((q - p) > 0 && *(q - 1) != '/') + *q++ = '/'; + strcpy(q, wild_match_all); + r = FFIRST(p, ff_context_p, FATTR); + free((zvoid *)p); + + return (r ? ZE_MISS : ZE_OK); +} + +local char *getVolumeLabel(drive, vtime, vmode, vutim) + int drive; /* drive name: 'A' .. 'Z' or '\0' for current drive */ + ulg *vtime; /* volume label creation time (DOS format) */ + ulg *vmode; /* volume label file mode */ + time_t *vutim;/* volume label creation time (UNIX format) */ + +/* If a volume label exists for the given drive, return its name and + set its time and mode. The returned name must be static data. */ +{ + static char vol[14]; + ff_dir d; + char *p; + + if (drive) { + vol[0] = (char)drive; + strcpy(vol+1, ":/"); + } else { + strcpy(vol, "/"); + } + strcat(vol, wild_match_all); + if (FFIRST(vol, &d, FA_LABEL) == 0) { + strncpy(vol, d.ff_name, sizeof(vol)-1); + vol[sizeof(vol)-1] = '\0'; /* just in case */ + if ((p = strchr(vol, '.')) != NULL) /* remove dot, though PKZIP doesn't */ + strcpy(p, p + 1); + *vtime = ((ulg)d.ff_fdate << 16) | ((ulg)d.ff_ftime & 0xffff); + *vmode = (ulg)d.ff_attrib; + *vutim = dos2unixtime(*vtime); + return vol; + } + return NULL; +} + + +#ifdef MSDOS16 +#define ONENAMELEN 12 /* no 16-bit compilers supports LFN */ +#else +#define ONENAMELEN 255 +#endif + +/* 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; +{ + ff_dir dir; + char *subwild, *name, *newwhole = NULL, *glue = NULL, plug = 0, plug2; + ush newlen, amatch = 0; + int e = ZE_MISS; + + if (!isshexp(wildtail)) { + struct stat s; /* dummy buffer for stat() */ + + if (!LSSTAT(whole, &s)) /* file exists ? */ + return procname(whole, 0); + else + return ZE_MISS; /* woops, no wildcards! */ + } + + /* back up thru path components till existing dir found */ + do { + name = wildtail + strlen(wildtail) - 1; + for (;;) + if (name-- <= wildtail || *name == PATH_END) { + subwild = name + 1; + plug2 = *subwild; + *subwild = 0; + break; + } + if (glue) + *glue = plug; + glue = subwild; + plug = plug2; + e = initDirSearch(whole, &dir); + } while (e == ZE_MISS && subwild > wildtail); + wildtail = subwild; /* skip past non-wild components */ + if (e != ZE_OK) { + if (glue) + *glue = plug; + goto ohforgetit; + } + subwild = strchr(wildtail + 1, PATH_END); + /* this "+ 1" dodges the ^^^ hole left by *glue == 0 */ + if (subwild != NULL) { + *(subwild++) = 0; /* wildtail = one component pattern */ + newlen = strlen(whole) + strlen(subwild) + (ONENAMELEN + 2); + } else + newlen = strlen(whole) + (ONENAMELEN + 1); + if ((newwhole = malloc(newlen)) == NULL) { + if (glue) + *glue = plug; + e = ZE_MEM; + 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; + } + + do { + if (strcmp(dir.ff_name, ".") && strcmp(dir.ff_name, "..") + && MATCH(wildtail, dir.ff_name, 0)) { + strcpy(newwhole + newlen, dir.ff_name); + if (subwild) { + name = newwhole + strlen(newwhole); + *(name++) = PATH_END; + strcpy(name, subwild); + e = wild_recurse(newwhole, name); + } else + e = procname_dos(newwhole, 0, getDirEntryAttr(&dir)); + newwhole[newlen] = 0; + if (e == ZE_OK) + amatch = 1; + else if (e != ZE_MISS) + break; + } + } while (FNEXT(&dir) == 0); + + ohforgetit: + if (subwild) + *--subwild = PATH_END; + if (newwhole) + free(newwhole); + if (e == ZE_MISS && amatch) + e = ZE_OK; + return e; +} + +int wild(w) +char *w; /* path/pattern to match */ +/* If not in exclude mode, expand the pattern based on the contents of the + file system. Return an error code in the ZE_ class. */ +{ + char *p; /* path */ + char *q; /* diskless path */ + int e; /* result */ + + if (volume_label == 1) { + volume_label = 2; + label = getVolumeLabel((w != NULL && w[1] == ':') ? to_up(w[0]) : '\0', + &label_time, &label_mode, &label_utim); + if (label != NULL) + (void)newname(label, 0, 0); + if (w == NULL || (w[1] == ':' && w[2] == '\0')) return ZE_OK; + /* "zip -$ foo a:" can be used to force drive name */ + } + /* special handling of stdin request */ + if (strcmp(w, "-") == 0) /* if compressing stdin */ + return newname(w, 0, 0); + + /* Allocate and copy pattern, leaving room to add "." if needed */ + if ((p = malloc(strlen(w) + 2)) == NULL) + return ZE_MEM; + strcpy(p, w); + + /* Normalize path delimiter as '/' */ + for (q = p; *q; q++) /* use / consistently */ + if (*q == '\\') + *q = '/'; + + /* Separate the disk part of the path */ + q = strchr(p, ':'); + if (q != NULL) { + if (strchr(++q, ':')) /* sanity check for safety of wild_recurse */ + return ZE_MISS; + } else + q = p; + + /* Normalize bare disk names */ + if (q > p && !*q) + strcpy(q, "."); + + /* Here we go */ + e = wild_recurse(p, q); + free((zvoid *)p); + return e; +} + +local int procname_dos(n, caseflag, attribs) +char *n; /* name to process */ +int caseflag; /* true to force case-sensitive match */ +unsigned attribs; /* file attributes, if available */ +/* 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 */ + ff_dir *d; /* control structure for FFIRST/FNEXT */ + char *e; /* pointer to name from readd() */ + int m; /* matched flag */ + int ff_status; /* return value of FFIRST/FNEXT */ + char *p; /* path for recursion */ + struct stat s; /* result of stat() */ + struct zlist far *z; /* steps through zfiles list */ + + if (n == NULL) /* volume_label request in freshen|delete mode ?? */ + return ZE_OK; + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0, caseflag); + else if (*n == '\0') return ZE_MISS; + else if (attribs != MSDOS_INVALID_ATTR) + { + /* Avoid calling stat() for performance reasons when it is already known + (from a previous directory scan) that the passed name corresponds to + a "real existing" file. The only information needed further down in + this function is the distinction between directory entries and other + (typically normal file) entries. This distinction can be derived from + the file's attributes that the directory lookup has already provided + "for free". + */ + s.st_mode = ((attribs & MSDOS_DIR_ATTR) ? S_IFDIR : S_IFREG); + } + else if (LSSTAT(n, &s) +#ifdef __TURBOC__ + /* For this compiler, stat() succeeds on wild card names! */ + || isshexp(n) +#endif + ) + { + /* Not a file or directory--search for shell expression in zip file */ + if (caseflag) { + p = malloc(strlen(n) + 1); + if (p != NULL) + strcpy(p, n); + } else + 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 (z->mark) z->dosflag = 1; /* force DOS attribs for incl. names */ + 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 */ + for (p = n; *p; p++) /* use / consistently */ + if (*p == '\\') + *p = '/'; + 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 || 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) + { + if ((d = malloc(sizeof(ff_dir))) == NULL || + (m = initDirSearch(n, d)) == ZE_MEM) + { + if (d != NULL) + free((zvoid *)d); + free((zvoid *)p); + return ZE_MEM; + } + for (e = d->ff_name, ff_status = m; + ff_status == 0; + ff_status = FNEXT(d)) + { + if (strcmp(e, ".") && strcmp(e, "..")) + { + if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL) + { + free((zvoid *)d); + free((zvoid *)p); + return ZE_MEM; + } + strcat(strcpy(a, p), e); + if ((m = procname_dos(a, caseflag, getDirEntryAttr(d))) + != ZE_OK) /* recurse on name */ + { + if (m == ZE_MISS) + zipwarn("name not matched: ", a); + else + ziperr(m, a); + } + free((zvoid *)a); + } + } + free((zvoid *)d); + } + free((zvoid *)p); + } /* (s.st_mode & S_IFDIR) == 0) */ + return ZE_OK; +} + +int procname(n, caseflag) +char *n; /* name to process */ +int caseflag; /* true to force case-sensitive match */ +{ + return procname_dos(n, caseflag, MSDOS_INVALID_ATTR); +} + +char *ex2in(x, isdir, pdosflag) +char *x; /* external file name */ +int isdir; /* input: x is a directory */ +int *pdosflag; /* output: force MSDOS file attributes? */ +/* Convert the external file name to a zip file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *n; /* internal file name (malloc'ed) */ + char *t; /* shortened name */ + int dosflag; + + dosflag = 1; + + /* Find starting point in name before doing malloc */ + /* Strip drive specification */ + t = *x && *(x + 1) == ':' ? x + 2 : x; + /* Strip "//host/share/" part of a UNC name */ + if ((!strncmp(x,"//",2) || !strncmp(x,"\\\\",2)) && + (x[2] != '\0' && x[2] != '/' && x[2] != '\\')) { + n = x + 2; + while (*n != '\0' && *n != '/' && *n != '\\') + n++; /* strip host name */ + if (*n != '\0') { + n++; + while (*n != '\0' && *n != '/' && *n != '\\') + n++; /* strip `share' name */ + } + if (*n != '\0') + t = n + 1; + } + /* Strip leading "/" to convert an absolute path into a relative path */ + while (*t == '/' || *t == '\\') + t++; + /* Skip leading "./" as well */ + while (*t == '.' && (t[1] == '/' || t[1] == '\\')) + t += 2; + + /* Make changes, if any, to the copied name (leave original intact) */ + for (n = t; *n; n++) + if (*n == '\\') + *n = '/'; + + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + + if (isdir == 42) return n; /* avoid warning on unused variable */ + + if (dosify) + msname(n); + else +#if defined(__DJGPP__) && __DJGPP__ >= 2 + if (_USE_LFN == 0) +#endif + strlwr(n); + if (pdosflag) + *pdosflag = dosflag; + return n; +} + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + + return x; +} + +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ +#if defined(__TURBOC__) || defined(__GO32__) + int h; /* file handle */ + + if ((h = open(f, 0)) != -1) + { + setftime(h, (struct ftime *)(void *)&d); + close(h); + } +#else /* !__TURBOC__ && !__GO32__ */ + ztimbuf u; /* argument for utime() */ + + /* Convert DOS time to time_t format in u.actime and u.modtime */ + u.actime = u.modtime = dos2unixtime(d); + + /* Set updated and accessed times of f */ + utime(f, &u); +#endif /* ?(__TURBOC__ || __GO32__) */ +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + /* convert FNMAX to malloc - 11/8/04 EG */ + char *name; + int len = strlen(f); + int isstdin = !strcmp(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 (isstdin) { + if (fstat(fileno(stdin), &s) != 0) { + free(name); + error("fstat(stdin)"); + } + time((time_t *)&s.st_mtime); /* some fstat()s return time zero */ + } 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) | (isstdin ? 0L : (ulg)GetFileMode(name)); +#if (S_IFREG != 0x8000) + /* kludge to work around non-standard S_IFREG flag used in DJGPP V2.x */ + if ((s.st_mode & S_IFMT) == S_IFREG) *a |= 0x80000000L; +#endif + } + free(name); + if (n != NULL) + *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_ctime; + } + + return unix2dostime((time_t *)&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(). + */ +{ + return rmdir(d); +} + +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; + /* create extra field and change z->att if desired */ +{ +#ifdef USE_EF_UT_TIME +#ifdef IZ_CHECK_TZ + if (!zp_tz_is_valid) return ZE_OK; /* skip silently if no valid TZ info */ +#endif + + if ((z->extra = (char *)malloc(EB_HEADSIZE+EB_UT_LEN(1))) == NULL) + return ZE_MEM; + + z->extra[0] = 'U'; + z->extra[1] = 'T'; + z->extra[2] = EB_UT_LEN(1); /* length of data part of e.f. */ + z->extra[3] = 0; + z->extra[4] = EB_UT_FL_MTIME; + z->extra[5] = (char)(z_utim->mtime); + z->extra[6] = (char)(z_utim->mtime >> 8); + z->extra[7] = (char)(z_utim->mtime >> 16); + z->extra[8] = (char)(z_utim->mtime >> 24); + + z->cext = z->ext = (EB_HEADSIZE+EB_UT_LEN(1)); + z->cextra = z->extra; + + return ZE_OK; +#else /* !USE_EF_UT_TIME */ + return (int)(z-z); +#endif /* ?USE_EF_UT_TIME */ +} + + +#ifdef MY_ZCALLOC /* Special zcalloc function for MEMORY16 (MSDOS/OS2) */ + +#if defined(__TURBOC__) && !defined(OS2) +/* Small and medium model are for now limited to near allocation with + * reduced MAX_WBITS and MAX_MEM_LEVEL + */ + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + zvoid far *org_ptr; + zvoid far *new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +zvoid far *zcalloc (unsigned items, unsigned size) +{ + zvoid far *buf; + ulg bsize = (ulg)items*size; + + if (bsize < (65536L-16L)) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-NULL) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +zvoid zcfree (zvoid far *ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = next_ptr - 1; n >= 0; n--) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ziperr(ZE_MEM, "zcfree: ptr not found"); +} +#endif /* __TURBOC__ */ + +#if defined(MSC) || defined(__WATCOMC__) +#if (!defined(_MSC_VER) || (_MSC_VER < 700)) +# define _halloc halloc +# define _hfree hfree +#endif + +zvoid far *zcalloc (unsigned items, unsigned size) +{ + return (zvoid far *)_halloc((long)items, size); +} + +zvoid zcfree (zvoid far *ptr) +{ + _hfree((void huge *)ptr); +} +#endif /* MSC || __WATCOMC__ */ + +#endif /* MY_ZCALLOC */ + +#if (defined(__WATCOMC__) && defined(ASMV) && !defined(__386__)) +/* This is a hack to connect "call _exit" in match.asm to exit() */ +#pragma aux xit "_exit" parm caller [] +void xit(void) +{ + exit(20); +} +#endif + +local int is_running_on_windows(void) +{ + char * var = getenv("OS"); + + /* if the OS env.var says 'Windows_NT' then */ + /* we're likely running on a variant of WinNT */ + + if ((NULL != var) && (0 == strcmp("Windows_NT", var))) + { + return 1; + } + + /* if the windir env.var is non-null then */ + /* we're likely running on a variant of Win9x */ + /* DOS mode of Win9x doesn't define windir, only winbootdir */ + /* NT's command.com can't see lowercase env. vars */ + + var = getenv("windir"); + if ((NULL != var) && (0 != var[0])) + { + return 1; + } + + return 0; +} + +void check_for_windows(char *app) +{ + /* Print a warning for users running under Windows */ + /* to reduce bug reports due to running DOS version */ + /* under Windows, when Windows version usually works correctly */ + + /* This is only called from the DOS version */ + + if (is_running_on_windows()) + { + printf("\nzip warning: You are running MSDOS %s on Windows.\n" + "Try the Windows version before reporting any problems.\n", + app); + } +} + +#endif /* !UTIL */ + + +#ifndef WINDLL +/******************************/ +/* Function version_local() */ +/******************************/ + +static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s.\n\n"; + /* At module level to keep Turbo C++ 1.0 happy !! */ + +void version_local() +{ +#if defined(__DJGPP__) || defined(__WATCOMC__) || \ + (defined(_MSC_VER) && (_MSC_VER != 800)) + char buf[80]; +#endif + +/* Define the compiler name and version strings */ +#if defined(__GNUC__) +# if defined(__DJGPP__) + sprintf(buf, "djgpp v%d.%02d / gcc ", __DJGPP__, __DJGPP_MINOR__); +# define COMPILER_NAME1 buf +# elif defined(__GO32__) /* __GO32__ is defined as "1" only (sigh) */ +# define COMPILER_NAME1 "djgpp v1.x / gcc " +# elif defined(__EMX__) /* ...so is __EMX__ (double sigh) */ +# define COMPILER_NAME1 "emx+gcc " +# else +# define COMPILER_NAME1 "gcc " +# endif +# define COMPILER_NAME2 __VERSION__ +#elif defined(__WATCOMC__) +# if (__WATCOMC__ % 10 > 0) +/* We do this silly test because __WATCOMC__ gives two digits for the */ +/* minor version, but Watcom packaging prefers to show only one digit. */ + sprintf(buf, "Watcom C/C++ %d.%02d", __WATCOMC__ / 100, + __WATCOMC__ % 100); +# else + sprintf(buf, "Watcom C/C++ %d.%d", __WATCOMC__ / 100, + (__WATCOMC__ % 100) / 10); +# endif +# define COMPILER_NAME1 buf +# define COMPILER_NAME2 "" +#elif defined(__TURBOC__) +# ifdef __BORLANDC__ +# define COMPILER_NAME1 "Borland C++" +# if (__BORLANDC__ < 0x0200) +# define COMPILER_NAME2 " 1.0" +# elif (__BORLANDC__ == 0x0200) /* James: __TURBOC__ = 0x0297 */ +# define COMPILER_NAME2 " 2.0" +# elif (__BORLANDC__ == 0x0400) +# define COMPILER_NAME2 " 3.0" +# elif (__BORLANDC__ == 0x0410) /* __BCPLUSPLUS__ = 0x0310 */ +# define COMPILER_NAME2 " 3.1" +# elif (__BORLANDC__ == 0x0452) /* __BCPLUSPLUS__ = 0x0320 */ +# define COMPILER_NAME2 " 4.0 or 4.02" +# elif (__BORLANDC__ == 0x0460) /* __BCPLUSPLUS__ = 0x0340 */ +# define COMPILER_NAME2 " 4.5" +# elif (__BORLANDC__ == 0x0500) /* __TURBOC__ = 0x0500 */ +# define COMPILER_NAME2 " 5.0" +# else +# define COMPILER_NAME2 " later than 5.0" +# endif +# else +# define COMPILER_NAME1 "Turbo C" +# if (__TURBOC__ > 0x0401) +# define COMPILER_NAME2 "++ later than 3.0" +# elif (__TURBOC__ == 0x0401) /* Kevin: 3.0 -> 0x0401 */ +# define COMPILER_NAME2 "++ 3.0" +# elif (__TURBOC__ == 0x0296) /* [662] checked by SPC */ +# define COMPILER_NAME2 "++ 1.01" +# elif (__TURBOC__ == 0x0295) /* [661] vfy'd by Kevin */ +# define COMPILER_NAME2 "++ 1.0" +# elif (__TURBOC__ == 0x0201) /* Brian: 2.01 -> 0x0201 */ +# define COMPILER_NAME2 " 2.01" +# elif ((__TURBOC__ >= 0x018d) && (__TURBOC__ <= 0x0200)) /* James: 0x0200 */ +# define COMPILER_NAME2 " 2.0" +# elif (__TURBOC__ > 0x0100) +# define COMPILER_NAME2 " 1.5" /* James: 0x0105? */ +# else +# define COMPILER_NAME2 " 1.0" /* James: 0x0100 */ +# endif +# endif +#elif defined(MSC) +# if defined(_QC) && !defined(_MSC_VER) +# define COMPILER_NAME1 "Microsoft Quick C" +# define COMPILER_NAME2 "" /* _QC is defined as 1 */ +# else +# define COMPILER_NAME1 "Microsoft C " +# ifdef _MSC_VER +# if (_MSC_VER == 800) +# define COMPILER_NAME2 "8.0/8.0c (Visual C++ 1.0/1.5)" +# else +# define COMPILER_NAME2 \ + (sprintf(buf, "%d.%02d", _MSC_VER/100, _MSC_VER%100), buf) +# endif +# else +# define COMPILER_NAME2 "5.1 or earlier" +# endif +# endif +#else +# define COMPILER_NAME1 "unknown compiler" +# define COMPILER_NAME2 "" +#endif + +/* Define the OS name and memory environment strings */ +#if defined(__WATCOMC__) || defined(__TURBOC__) || defined(MSC) || \ + defined(__GNUC__) +# define OS_NAME1 "\nMS-DOS" +#else +# define OS_NAME1 "MS-DOS" +#endif + +#if (defined(__GNUC__) || (defined(__WATCOMC__) && defined(__386__))) +# define OS_NAME2 " (32-bit)" +#elif defined(M_I86HM) || defined(__HUGE__) +# define OS_NAME2 " (16-bit, huge)" +#elif defined(M_I86LM) || defined(__LARGE__) +# define OS_NAME2 " (16-bit, large)" +#elif defined(M_I86MM) || defined(__MEDIUM__) +# define OS_NAME2 " (16-bit, medium)" +#elif defined(M_I86CM) || defined(__COMPACT__) +# define OS_NAME2 " (16-bit, compact)" +#elif defined(M_I86SM) || defined(__SMALL__) +# define OS_NAME2 " (16-bit, small)" +#elif defined(M_I86TM) || defined(__TINY__) +# define OS_NAME2 " (16-bit, tiny)" +#else +# define OS_NAME2 " (16-bit)" +#endif + +/* Define the compile date string */ +#ifdef __DATE__ +# define COMPILE_DATE " on " __DATE__ +#else +# define COMPILE_DATE "" +#endif + + printf(CompiledWith, COMPILER_NAME1, COMPILER_NAME2, + OS_NAME1, OS_NAME2, COMPILE_DATE); + +} /* end function version_local() */ +#endif /* !WINDLL */ + + +#if 0 /* inserted here for future use (clearing of archive bits) */ +#if (defined(__GO32__) && (!defined(__DJGPP__) || (__DJGPP__ < 2))) + +#include +int volatile _doserrno; + +unsigned _dos_setfileattr(char *name, unsigned attr) +{ +#if 0 /* stripping of trailing '/' is not needed for zip-internal use */ + unsigned namlen = strlen(name); + char *i_name = alloca(namlen + 1); + + strcpy(i_name, name); + if (namlen > 1 && i_name[namlen-1] == '/' && i_name[namlen-2] != ':') + i_name[namlen-1] = '\0'; + asm("movl %0, %%edx": : "g" (i_name)); +#else + asm("movl %0, %%edx": : "g" (name)); +#endif + asm("movl %0, %%ecx": : "g" (attr)); + asm("movl $0x4301, %eax"); + asm("int $0x21": : : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi"); + _doserrno = 0; + asm("jnc 1f"); + asm("movl %%eax, %0": "=m" (_doserrno)); + switch (_doserrno) { + case 2: + case 3: + errno = ENOENT; + break; + case 5: + errno = EACCES; + break; + } + asm("1:"); + return (unsigned)_doserrno; +} + +#endif /* DJGPP v1.x */ +#endif /* never (not yet used) */ + + +#if (defined(__DJGPP__) && (__DJGPP__ >= 2)) + +/* Disable determination of "x" bit in st_mode field for [f]stat() calls. */ +int _is_executable (const char *path, int fhandle, const char *ext) +{ + return 0; +} + +/* Prevent globbing of filenames. This gives the same functionality as + * "stubedit globbing=no" did with DJGPP v1. + */ +#ifndef USE_DJGPP_GLOB +char **__crt0_glob_function(char *_arg) +{ + return NULL; +} +#endif + +/* Reduce the size of the executable and remove the functionality to read + * the program's environment from whatever $DJGPP points to. + */ +#if !defined(USE_DJGPP_ENV) || defined(UTIL) +void __crt0_load_environment_file(char *_app_name) +{ +} +#endif + +#endif /* __DJGPP__ >= 2 */ + + +#if defined(_MSC_VER) && _MSC_VER == 700 + +/* + * ARGH. MSC 7.0 libraries think times are based on 1899 Dec 31 00:00, not + * 1970 Jan 1 00:00. So we have to diddle time_t's appropriately: add + * 70 years' worth of seconds for localtime() wrapper function; + * (70*365 regular days + 17 leap days + 1 1899 day) * 86400 == + * (25550 + 17 + 1) * 86400 == 2209075200 seconds. + * Let time() and stat() return seconds since 1970 by using our own + * _dtoxtime() which is the routine that is called by these two functions. + */ + + +#ifdef UTIL +# include +#endif + +#ifndef UTIL +#undef localtime +struct tm *localtime(const time_t *); + +struct tm *msc7_localtime(const time_t *clock) +{ + time_t t = *clock; + + t += 2209075200L; + return localtime(&t); +} +#endif /* !UTIL */ + + +void __tzset(void); +int _isindst(struct tm *); + +extern int _days[]; + +/* Nonzero if `y' is a leap year, else zero. */ +#define leap(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0) + +/* Number of leap years from 1970 to `y' (not including `y' itself). */ +#define nleap(y) (((y) - 1969) / 4 - ((y) - 1901) / 100 + ((y) - 1601) / 400) + +time_t _dtoxtime(year, month, mday, hour, min, sec) +int year, month, mday, year, hour, min, sec; +{ + struct tm tm; + time_t t; + int days; + + days = _days[month - 1] + mday; + year += 1980; + if (leap(year) && month > 2) + ++days; + tm.tm_yday = days; + tm.tm_mon = month - 1; + tm.tm_year = year - 1900; + tm.tm_hour = hour; + __tzset(); + days += 365 * (year - 1970) + nleap (year); + t = 86400L * days + 3600L * hour + 60 * min + sec + _timezone; + if (_daylight && _isindst(&tm)) + t -= 3600; + return t; +} + +#endif /* _MSC_VER && _MSC_VER == 700 */ + + +#ifdef __WATCOMC__ + +/* This papers over a bug in Watcom 10.6's standard library... sigh */ +/* Apparently it applies to both the DOS and Win32 stat()s. */ + +int stat_bandaid(const char *path, struct stat *buf) +{ + char newname[4]; + if (!stat(path, buf)) + return 0; + else if (!strcmp(path, ".") || (path[0] && !strcmp(path + 1, ":."))) { + strcpy(newname, path); + newname[strlen(path) - 1] = '\\'; /* stat(".") fails for root! */ + return stat(newname, buf); + } else + return -1; +} + +#endif diff --git a/msdos/osdep.h b/msdos/osdep.h new file mode 100644 index 0000000..0e0f23f --- /dev/null +++ b/msdos/osdep.h @@ -0,0 +1,218 @@ +/* + Copyright (c) 1990-2008 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 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 +*/ +/* The symbol DOS is used throughout the Zip source to identify code portions + * specific to the MSDOS port. + * Just to make sure, we check that it is set. + * (Currently, this should should not be neccessary, since currently it has + * to be set on the compiler command line to get this file read in.) + */ +#ifndef DOS +# define DOS +#endif + +/* The symbol MSDOS is consistently used in the generic source files + * to identify code to support for MSDOS (and MSDOS related) stuff. + * e.g: FAT or (FAT like) file systems, + * '\\' as directory separator in paths, + * "\r\n" as record (line) terminator in text files, ... + * + * IMPORTANT Note: + * This symbol is not unique for the MSDOS port !!!!!! + * It is also defined by ports to some other OS which are (to some extend) + * considered DOS compatible. + * Examples are: OS/2 (OS2), Windows NT and Windows 95 (WIN32). + * + */ +#ifndef MSDOS +# define MSDOS +#endif + +/* Power C is similar to Turbo C */ +#ifdef __POWERC +# define __TURBOC__ +#endif /* __POWERC */ + +/* Automatic setting of the common Microsoft C idenfifier MSC. + * NOTE: Watcom also defines M_I*86 ! + */ +#if defined(_MSC_VER) || (defined(M_I86) && !defined(__WATCOMC__)) +# ifndef MSC +# define MSC /* This should work for older MSC, too! */ +# endif +#endif + +#if !defined(__GO32__) && !defined(__EMX__) +# define NO_UNISTD_H +#endif + +#if defined(__WATCOMC__) && defined(__386__) +# define WATCOMC_386 +#endif + +#ifdef WINDLL +# define MSWIN +# define MEMORY16 +#endif + + +#if !defined(__EMX__) && !defined(__GO32__) && !defined(WATCOMC_386) +#if !defined(WINDLL) +# define MSDOS16 /* 16 bit MSDOS only */ +# define MEMORY16 +#endif +#endif + +#if !defined(NO_ASM) && !defined(ASMV) +# define ASMV +#endif + +/* enable creation of UTC time fields unless explicitely suppressed */ +#if !defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME) +# define USE_EF_UT_TIME +#endif + +/* check that TZ environment variable is defined before using UTC times */ +#if (!defined(NO_IZ_CHECK_TZ) && !defined(IZ_CHECK_TZ)) +# define IZ_CHECK_TZ +#endif + +#ifdef MEMORY16 +# ifndef NO_ASM +# define ASM_CRC 1 +# endif /* ?NO_ASM */ +# ifdef __TURBOC__ +# include +# if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__) +# if defined(DYNAMIC_CRC_TABLE) && defined(DYNALLOC_CRCTAB) + error: No dynamic CRC table allocation with Borland C far data models. +# endif /* DYNAMIC_CRC_TABLE */ +# endif /* Turbo/Borland C far data memory models */ +# define nearmalloc malloc +# define nearfree free +# define DYN_ALLOC +# else /* !__TURBOC__ */ +# include +# define nearmalloc _nmalloc +# define nearfree _nfree +# define farmalloc _fmalloc +# define farfree _ffree +# endif /* ?__TURBOC__ */ +# define MY_ZCALLOC 1 +# ifdef SMALL_MEM +# define CBSZ 2048 +# define ZBSZ 2048 +# endif +# ifdef MEDIUM_MEM +# define CBSZ 4096 +# define ZBSZ 4096 +# endif +# ifndef CBSZ +# define CBSZ 8192 +# define ZBSZ 8192 +# endif +#endif /* MEMORY16 */ + + +/* Symbolic links are not supported, but some compilers may define S_IFLNK. */ +#ifndef NO_SYMLINKS +# define NO_SYMLINKS +#endif + +#ifdef MATCH +# undef MATCH +#endif +#define MATCH dosmatch /* use DOS style wildcard matching */ + +#define USE_CASE_MAP + +#define ROUNDED_TIME(time) (((time) + 1) & (~1)) +#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \ + procname(n, 1)) + +#define FOPR "rb" +#define FOPM "r+b" +#define FOPW "wb" + +#include +#include +#include + +#ifdef ZCRYPT_INTERNAL +# ifdef WINDLL +# define ZCR_SEED2 (unsigned)3141592654L /* use PI as seed pattern */ +# else +# ifndef __GO32__ +# include /* getpid() declaration for srand seed */ +# endif +# endif +#endif + +/* + * djgpp 1.x did not declare these + */ +#if defined(__GO32__) && !defined(__DJGPP__) +char *strlwr(char *); +int setmode(int, int); +#endif + +#ifdef __WATCOMC__ +# define NO_MKTEMP +# define HAS_OPENDIR +# define SSTAT stat_bandaid + int stat_bandaid(const char *path, struct stat *buf); + +/* Get asm routines to link properly without using "__cdecl": */ +# ifdef __386__ +# ifdef ASMV +# pragma aux match_init "_*" parm caller [] modify [] +# pragma aux longest_match "_*" parm caller [] value [eax] \ + modify [eax ecx edx] +# endif +# ifndef USE_ZLIB +# pragma aux crc32 "_*" parm caller [] value [eax] modify [eax] +# pragma aux get_crc_table "_*" parm caller [] value [eax] \ + modify [eax ecx edx] +# endif /* !USE_ZLIB */ +# else /* !__386__ */ +# ifdef ASMV +# pragma aux match_init "_*" parm caller [] loadds modify [ax bx] +# pragma aux longest_match "_*" parm caller [] loadds value [ax] \ + modify [ax bx cx dx es] +# endif /* ASMV */ +# ifndef USE_ZLIB +# pragma aux crc32 "_*" parm caller [] value [ax dx] \ + modify [ax bx cx dx es] +# pragma aux get_crc_table "_*" parm caller [] value [ax] \ + modify [ax bx cx dx] +# endif /* !USE_ZLIB */ +# endif /* ?__386__ */ +#endif /* __WATCOMC__ */ + +/* + * Wrapper function to get around the MSC7 00:00:00 31 Dec 1899 time base, + * see msdos.c for more info + */ + +#if defined(_MSC_VER) && _MSC_VER == 700 +# define localtime(t) msc7_localtime(t) +#endif + +#ifdef __TURBOC__ +# ifdef __FILEIO_C +# include /* supplies mktemp() prototype */ +# endif +#endif + +#if (defined(__TURBOC__) && !defined(__BORLANDC__) && __TURBOC__ <= 0x0201) +# ifndef NO_MKTIME +# define NO_MKTIME /* TC 2.01 and earlier do not supply mktime() */ +# endif +#endif + +void check_for_windows(char *app); diff --git a/msdos/zipup.h b/msdos/zipup.h new file mode 100644 index 0000000..78b428a --- /dev/null +++ b/msdos/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 (O_RDONLY|O_BINARY) +#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 diff --git a/novell/MAKEINIT b/novell/MAKEINIT new file mode 100644 index 0000000..f9929e7 --- /dev/null +++ b/novell/MAKEINIT @@ -0,0 +1,71 @@ +# +# makeinit file for makefiles created with QMK386 +# +# Novell's NetWare SDK - Release 15 +# +# Directories for both the WATCOM and NOVELL tools +# +wat386loc = e:\watcom\ +nlm386loc = c:\novell\ndk\nwsdk\ +nlm386hdr = $(nlm386loc)INCLUDE\NLM;$(nlm386loc)INCLUDE;. +nlm386imp = $(nlm386loc)IMPORTS +nlm386lib = $(wat386loc)LIB386;$(wat386loc)LIB386\NETWARE +# +# Define this macro with your copyright statement +# +#copyright = (C) Copyright 199x NONAME, INC. All Rights Reserved +# +# Macros that point to various tools we'll need to compile +# +wcc386r = WCC386 # location of 386 real mode compiler +wcc386p = WCC386P # protected compiler (last avail on Watcom v9.5 +wcc386 = $(wcc386r) # version we want to use + +linkr = WLINK # location of real mode linker +linkp = WLINKP # protected linker (last avail on Watcom v9.5 +linker = $(linkr) # version we want to use +nlmlinkr = $(nlm386loc)TOOLS\NLMLINKR # location of real mode Novell linker +nlmlinkp = $(nlm386loc)TOOLS\NLMLINKX # location of protected Novell linker +nlmlinker = $(nlmlinkr) # version we want to use + +nlmpackr = $(nlm386loc)TOOLS\NLMPACK # location of real mode NLM compression utility +nlmpackp = $(nlm386loc)TOOLS\NLMPACKP # location of protected NLM compression utility +nlmpack = $(nlmpackr) # location of NLM compression utility + +inc_386 = $(nlm386hdr) +lib_386 = $(nlm386lib) +code_386 = $(wat386loc)BIN\386WCGL.EXE # code generator (last avail on Watcom v9.01 +librarian = $(wat386loc)BINB\WLIB # location of librarian +# +# NLM Import Files +# +startup = $(nlm386imp)\PRELUDE.OBJ # other option is nwpre.obj +allimp = $(nlm386imp)\ALL.IMP # import to include all imports +clibimp = $(nlm386imp)\CLIB.IMP # the clib import file +tliimp = $(nlm386imp)\TLI.IMP # the tli import file +aioimp = $(nlm386imp)\AIO.IMP # the aio import file +socklibimp = $(nlm386imp)\SOCKLIB.IMP # the socket import file +mathlibimp = $(nlm386imp)\MATHLIB.IMP # the math library import file +dsapiimp = $(nlm386imp)\DSAPI.IMP # the NDS import file +nutimp = $(nlm386imp)\NWSNUT.IMP # the NWSNUT import file +appleimp = $(nlm386imp)\APPLTLK.IMP # the AppleTalk import file +nitimp = $(nlm386imp)\NIT.IMP # the legacy NLM import file +nlmlibimp = $(nlm386imp)\NLMLIB.IMP # the NLM-specific import file +requesterimp = $(nlm386imp)\REQUESTR.IMP # the Requester import file +fpsmimp = $(nlm386imp)\FPSM.IMP # floating point support import file +threadsimp = $(nlm386imp)\THREADS.IMP # the threads import file +dseventimp = $(nlm386imp)\DSEVENT.IMP # DS Events import file +psrvimp = $(nlm386imp)\NWPSRV.IMP # print services import file +psrv3ximp = $(nlm386imp)\NWPSRV3X.IMP # 3.x print services import file +streamsimp = $(nlm386imp)\STREAMS.IMP # streams import file +unicodeimp = $(nlm386imp)\UNICODE.IMP # unicode import file +agentimp = $(nlm386imp)\agent.imp # SNMP Agent import file +smileimp = $(nlm386imp)\smile.imp # SMILE (SNMP) import file +# +# Cross-platform Import Files +# +audnlm32imp = $(nlm386imp)\AUDNLM32.IMP # auditing import file +calnlm32imp = $(nlm386imp)\CALNLM32.IMP # NWCALLS import file +clxnlm32imp = $(nlm386imp)\CLXNLM32.IMP # NWCLIENT import file +locnlm32imp = $(nlm386imp)\LOCNLM32.IMP # NWLOCALE import file +netnlm32imp = $(nlm386imp)\NETNLM32.IMP # NWNET import file diff --git a/novell/Makefile b/novell/Makefile new file mode 100644 index 0000000..c88bf86 --- /dev/null +++ b/novell/Makefile @@ -0,0 +1,142 @@ +# +# This makefile was generated by QMK386 v2.14 +# +# Program: unzip.NLM +# This makefile rebuilds the zip NetWare Loadable Module +# +# Created: Sun Jan 03 03:54:03 1999 +# +# MAKEINIT defines many of the macros used herein +# The following macros can be set via your environment: +# CCF386 : Set compile options +# QMKVER : Set to 'd' or 'p' to define VERSION +# SILENT : If defined, .SILENT will be set +# +# The following macros are defined for your program: +# vMAJ : Major version number +# vMIN : Minor version number +# vREV : Revision number + +!ifdef %SILENT +.silent +!endif + +program = zip + +pvmaj = 1 # major version number +pvmin = 00 # minor version number +pvrev = 3 # revision number e.g. 0,1,2, ... + +!ifndef %qmkver +! define version p # use 'd' or 'p' here +!else +! define version $(%qmkver) +!endif +!ifeq version d +! define lversion DEBUG +! define debug /dDEBUG +!else +! define lversion PRODUCTION +! define debug +!endif + +nlm_TYPE = Form Novell NLM '$(program)' +nlm_NAME = Name $^& +nlm_SCREEN = Op ScreenName '$(program)' +nlm_THREAD = Op ThreadName '$^&__P ' +nlm_STACK = Op Stack = 8k +nlm_NLMVER = Op Version = $(pvmaj).$(pvmin).$(pvrev) +nlm_COPYRIGHT = Op Copyright '$(copyright)' +linkop = $+$(linkop)$- Caseexact +linkop = $+$(linkop)$- Nod +!ifeq version d +! define linkop $+$(linkop)$- Map +! define linkop $+$(linkop)$- Verbose +! define ldebug debug all debug novell +!endif + +objlst = BITS.OBJ +objlst = $+$(objlst)$- CRC32.OBJ +objlst = $+$(objlst)$- CRYPT.OBJ +objlst = $+$(objlst)$- DEFLATE.OBJ +objlst = $+$(objlst)$- FILEIO.OBJ +objlst = $+$(objlst)$- GLOBALS.OBJ +objlst = $+$(objlst)$- MKTIME.OBJ +objlst = $+$(objlst)$- NETWARE.OBJ +objlst = $+$(objlst)$- SIGNAL.OBJ +objlst = $+$(objlst)$- TREES.OBJ +objlst = $+$(objlst)$- TTYIO.OBJ +objlst = $+$(objlst)$- UTIL.OBJ +objlst = $+$(objlst)$- ZIP.OBJ +objlst = $+$(objlst)$- ZIPFILE.OBJ +objlst = $+$(objlst)$- ZIPUP.OBJ +objlst = $+$(objlst)$- $(startup) + +import = $(allimp) + +module = CLib + +build_msg = Building a $(lversion) version of $(program) + +pgm_ver = /dvMAJ="$(pvmaj)" /dvMIN="$(pvmin)" /dvREV="$(pvrev)" + +!ifndef %ccf386 +! define d_wcc386opt /ms /w4 /e99 /zp1 /3s /ot /d2 /dN_PLAT_NLM /d_FIND_OLD_HEADERS -dNO_ASM -dNLM $(debug) +! define p_wcc386opt /ms /w4 /s /zp1 /3s /oaxt /dN_PLAT_NLM /d_FIND_OLD_HEADERS -dNO_ASM -dNLM +! define x_wcc386opt $($(version)_wcc386opt) $(pgm_ver) +!else +! define x_wcc386opt $(%ccf386) +!endif + +compiler_cmd = $(wcc386) $(x_wcc386opt) $[*.c + +.BEFORE + echo $(build_msg) + set inc386=$(inc_386) + set lib386=$(lib_386) + set wcg386=$(code_386) + +.c.obj: + $(compiler_cmd) + +zip.nlm : $(objlst) zip.LNK + $(linker) @zip + +zip.LNK : MAKEFILE + if exist $^&.LNK del $^&.LNK + %append $^&.LNK $(nlm_TYPE) + %append $^&.LNK $(nlm_NAME) + %append $^&.LNK $(nlm_SCREEN) + %append $^&.LNK $(nlm_THREAD) + %append $^&.LNK $(nlm_STACK) + %append $^&.LNK $(nlm_NLMVER) +!ifdef copyright + %append $^&.LNK $(nlm_COPYRIGHT) +!endif +!ifdef ldebug + %append $^&.LNK $(ldebug) +!endif + for %i in ($(linkop)) do %append $^&.LNK Op %i + for %i in ($(objlst)) do %append $^&.LNK File %i + for %i in ($(import)) do %append $^&.LNK Import @%i + for %i in ($(export)) do %append $^&.LNK Export @%i + for %i in ($(module)) do %append $^&.LNK Module %i + for %i in ($(library)) do %append $^&.LNK Library %i + +clean : .symbolic + del *.MAP + del *.OBJ + del *.ERR + del *.LNK + del *.NLM + +zip : .symbolic + -pkzip -u zip MAKEFILE *.c *.h + +unzip : .symbolic + -pkunzip -n -d zip + +save : .symbolic + %make zip + %make clean + diff --git a/novell/Netware.c b/novell/Netware.c new file mode 100644 index 0000000..20efa16 --- /dev/null +++ b/novell/Netware.c @@ -0,0 +1,970 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void UseAccurateCaseForPaths(int); + +#include "zip.h" + + /*------------------------------------------------------------------ + ** Global Variables + */ + +#define skipspace( x ) while( isspace( *x ) ) ++x +#define nextspace( x ) while( *x && !isspace( *x ) ) ++x +#define CWS 0 +#define CWV 1 +#define CWP 2 +#define ALL 99 + +/* Globals */ +extern char *GetWorkArea(void); +extern char *next_arg(char *); +extern int NLM_exiting; +char fid[100]; +static breakkey = FALSE; + +#define MATCH shmatch + +extern char *label; +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +#define PAD 0 +#define PATH_END '/' + +local char *readd(d) +DIR *d; /* directory stream to read from */ +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e; + + e = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; +} + +void findzip(char *s) +{ + dowhereis(s); +} + +void dowhereis(char *s) +{ + char dir[_MAX_PATH]; + char fsv[_MAX_SERVER+_MAX_VOLUME+1]; + char fdir[_MAX_PATH]; + char fname[_MAX_FNAME],fext[_MAX_EXT], both[_MAX_FNAME+_MAX_EXT]; + char *p = next_arg(s); /* point at argument */ + + if(!*p) + { + printf("No filename specified!"); + return; + } + + //setlocale (LC_ALL, "NORWAY"); + NWLsetlocale (LC_ALL, "NORWAY"); + + strcpy(dir,GetWorkArea()); + + /* get the file name specification */ + _splitpath(p,fsv,fdir,fname,fext); + + //printf ("p %s, fsv %s, fdir %s, fname %s, fext %s\n", p,fsv,fdir,fname,fext); + //getch(); + + sprintf(both,"%s%s",strupr(fname),strupr(fext)); + + breakkey = FALSE; + + /* startup the recursive file find operation */ + chdir(fsv); + UseAccurateCaseForPaths(1); + SetCurrentNameSpace (NW_NS_LONG); + chdir(fdir); + findit(both); +} + +char *GetWorkArea(void) +{ + static char cwd[_MAX_PATH]; + static char serverName[_MAX_SERVER]; + static char volumeName[_MAX_VOLUME + 1]; + static char dirName[_MAX_DIR]; + + if(getcwd(cwd,_MAX_PATH) == NULL) + return NULL; + + ParsePath(cwd,serverName,volumeName,dirName); /* shouldn't fail! */ + + return cwd; +} + +char *next_arg(char *s) +{ + char *p; + + skipspace(s); /* ignore white */ + p = s; + nextspace(s); /* find next blank */ + *s = NULL; + return(p); +} + +static void findit(char *what) +{ + char dir[_MAX_PATH]; + char zipdir[_MAX_PATH]; + char szzipfile[_MAX_PATH]; + char *psz; + DIR *dirStructPtr; + DIR *dirStructPtrSave; + int r; + + getcwd(dir,_MAX_PATH); + + psz = dir; + + while (*psz) + { + if (*psz == ':') + { + strcpy (zipdir, psz + 1); + break; + } + psz++; + } + + dirStructPtrSave = dirStructPtr = opendir(what); + + /* + _A_NORMAL Normal file; read/write permitted + _A_RDONLY Read-only file + _A_HIDDEN Hidden file + _A_SYSTEM System file + _A_VOLID Volume ID entry + _A_SUBDIR Subdirectory + _A_ARCH Archive file + */ + + if (hidden_files) + SetReaddirAttribute (dirStructPtr, _A_NORMAL | _A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_ARCH); + else + SetReaddirAttribute (dirStructPtr, _A_NORMAL | _A_ARCH); + + //while(dirStructPtr && !breakkey) + while(dirStructPtr && !NLM_exiting) + { + //printf ("\n NLM_exiting test Line 167.... \n"); + + dirStructPtr = readdir(dirStructPtr); + if((dirStructPtr == NULL) || (dirStructPtr == -1)) + break; + + /* Filen er funnet */ + if(dirStructPtr->d_attr & _A_SUBDIR) + continue; + + strcpy (szzipfile, zipdir); + strcat (szzipfile, "/"); + strcat (szzipfile, dirStructPtr->d_name); + procnamehho (szzipfile); + + //ThreadSwitchWithDelay(); + + //if(kbhit() && getch() == 3) + // printf("^C\n",breakkey = TRUE); + } + + if(dirStructPtrSave) + closedir(dirStructPtrSave); + + if (!recurse) + return; + + /* Now traverse the directories in this path */ + + dirStructPtrSave = dirStructPtr = opendir("*.*"); + if(dirStructPtr == NULL) + return; + + if (hidden_files) + SetReaddirAttribute (dirStructPtr, _A_NORMAL | _A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_ARCH | _A_SUBDIR); + else + SetReaddirAttribute (dirStructPtr, _A_NORMAL | _A_ARCH | _A_SUBDIR); + + //ThreadSwitchWithDelay(); + + while(!NLM_exiting) + { + //printf ("\n NLM_exiting test Line 204.... \n"); getch (); + + dirStructPtr = readdir(dirStructPtr); + if((dirStructPtr == NULL) || (dirStructPtr == -1)) + break; + + if(dirStructPtr->d_attr & _A_SUBDIR) + { + strcpy (szzipfile, zipdir); + strcat (szzipfile, "/"); + strcat (szzipfile, dirStructPtr->d_name); + procnamehho (szzipfile); + + chdir(dirStructPtr->d_name); + findit(what); + chdir(".."); + } + + //if(kbhit() && getch() == 3) + // printf("^C\n",breakkey = TRUE); + } + + if(dirStructPtrSave) + closedir(dirStructPtrSave); +} + + +int wild(w) +char *w; /* path/pattern to match */ +/* If not in exclude mode, expand the pattern based on the contents of the + file system. Return an error code in the ZE_ class. */ +{ + DIR *d; /* stream for reading directory */ + char *e; /* name found in directory */ + int r; /* temporary variable */ + char *n; /* constructed name from directory */ + int f; /* true if there was a match */ + char *a; /* alloc'ed space for name */ + //char *p; /* path */ + char *q; /* name */ + char v[5]; /* space for device current directory */ + + + char dir[_MAX_PATH]; + char fsv[_MAX_SERVER+_MAX_VOLUME+1]; + char fdir[_MAX_PATH]; + char fname[_MAX_FNAME],fext[_MAX_EXT], both[_MAX_FNAME+_MAX_EXT]; + char *p; /* point at argument */ + + p = w; + + + /* Test HHO */ + findzip(p); + + return ZE_OK; + + + strcpy(dir,GetWorkArea()); + + /* get the file name specification */ + + _splitpath(p,fsv,fdir,fname,fext); + sprintf(both,"%s%s",strupr(fname),strupr(fext)); + + /* startup the recursive file find operation */ + + chdir(fsv); + + /* Search that level for matching names */ + if ((d = opendir(both)) == NULL) + { + free((zvoid *)a); + return ZE_MISS; + } + + f = 0; + while ((e = readd(d)) != NULL) { + if (strcmp(e, ".") && strcmp(e, "..") && MATCH(q, e)) + { + f = 1; + if (strcmp(p, ".") == 0) { /* path is . */ + r = procname(e); /* name is name */ + if (r) { + f = 0; + break; + } + } else + { + if ((n = malloc(strlen(p) + strlen(e) + 2)) == NULL) + { + free((zvoid *)a); + closedir(d); + return ZE_MEM; + } + n = strcpy(n, p); + if (n[r = strlen(n) - 1] != '/' && n[r] != ':') + strcat(n, "/"); + r = procname(strcat(n, e)); /* name is path/name */ + free((zvoid *)n); + if (r) { + f = 0; + break; + } + } + } + } + closedir(d); + + /* Done */ + free((zvoid *)a); + return f ? ZE_OK : ZE_MISS; +} + +int procnamehho (char *n) +{ + int m; /* matched flag */ + char *p; /* path for recursion */ + struct stat s; /* result of stat() */ + struct zlist far *z; /* steps through zfiles list */ + + char *a; + + if (n == NULL) /* volume_label request in freshen|delete mode ?? */ + return ZE_OK; + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0); + else if (stat(n, &s) +#if defined(__TURBOC__) || defined(__WATCOMC__) + /* For these 2 compilers, stat() succeeds on wild card names! */ + || isshexp(n) +#endif + ) + { + /* 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)) + { + z->mark = pcount ? filter(z->zname) : 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 */ + for (p = n; *p; p++) /* use / consistently */ + if (*p == '\\') + *p = '/'; + + //printf ("\nHHO %s\n", n); + if ((s.st_mode & S_IFDIR) == 0) + { + //printf ("\nHHO1 %s\n", n); + /* add or remove name of file */ + //printf ("\nAdding name %s to list.\n", n); + if ((m = newname(n, 0)) != 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 || 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)) != ZE_OK) { + if ((m = newname(p, 1)) != ZE_OK) { + free((zvoid *)p); + return m; + } + free ((zvoid *)p); + } + + return ZE_OK; + } + return ZE_OK; +} + +int procname(n) +char *n; /* name to process */ +/* 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 (n == NULL) /* volume_label request in freshen|delete mode ?? */ + return ZE_OK; + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0); + else if (stat(n, &s) +#if defined(__TURBOC__) || defined(__WATCOMC__) + /* For these 2 compilers, stat() succeeds on wild card names! */ + || isshexp(n) +#endif + ) + { + /* 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)) + { + z->mark = pcount ? filter(z->zname) : 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 */ + for (p = n; *p; p++) /* use / consistently */ + if (*p == '\\') + *p = '/'; + if ((s.st_mode & S_IFDIR) == 0) + { + /* add or remove name of file */ + if ((m = newname(n, 0)) != 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 || 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)) != 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)) != 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 *szRelativParameter; +char szRelativ[512]; +int iRelativOK = FALSE; +int iRelativPakking = FALSE; + +int fixRelativpath () +{ + char *szp; + + szp = szRelativParameter; + + if (szRelativParameter[0] == '/' || szRelativParameter[0] == '\\') + szp++; + + while (*szp) { + if (*szp == '\\') + *szp = '/'; + szp++; + } + + szp = szRelativParameter; + if (szRelativParameter[0] == '/') + szp++; + + strcpy (szRelativ, szp); + + if (strlen(szp) == 0) { + szRelativ[0] = '\0'; + return FALSE; + } + return TRUE; +} + + +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; + char *sztUpper; + + + /* Find starting point in name before doing malloc */ + t = *x && *(x + 1) == ':' ? x + 2 : x; + while (*t == '/' || *t == '\\') + t++; + + /* Make changes, if any, to the copied name (leave original intact) */ + for (n = t; *n; n++) + if (*n == '\\') + *n = '/'; + + if (iRelativPakking) { + //printf ("\n LINE 516 *ex2ex Internt navn %s external name %s.\n", t, x); getch (); + if (!iRelativOK) { + if (!fixRelativpath()) { + iRelativOK = FALSE; + iRelativPakking = FALSE; + } + else { + sztUpper = malloc (strlen(t) + 10); + strcpy (sztUpper, t); + NWLstrupr (sztUpper); + NWLstrupr (szRelativ); + if (strncmp (sztUpper, szRelativ, strlen(szRelativ)) == 0) { + t = t + strlen(szRelativ); + iRelativPakking = TRUE; + iRelativOK = TRUE; + } + else { + iRelativOK = FALSE; + iRelativPakking = FALSE; + } + free (sztUpper); + } + } + else + { + t = t + strlen(szRelativ); + } + } + + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + + if (dosify) + msname(n); + + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + + return n; +} + + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + + //if ( !IsFileNameValid(x) ) + //ChangeNameForFAT(x); + + //printf ("\n *in2ex Internt navn %s external name %s.\n", n, x); getch (); + + 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. */ +{ + //SetFileTime(f, d); +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + /* convert FNMAX to malloc - 11/8/04 EG */ + char *name; + int len = strlen(f); + + if (f == label) { + if (a != NULL) + *a = label_mode; + if (n != NULL) + *n = -2L; /* convention for a label name */ + if (t != NULL) + t->atime = t->mtime = t->ctime = label_utim; + return label_time; + } + if ((name = malloc(len + 1)) == NULL) { + ZIPERR(ZE_MEM, "filetime"); + } + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + if (strcmp(f, "-") == 0) { + if (fstat(fileno(stdin), &s) != 0) + error("fstat(stdin)"); + } + else if (stat(name, &s) != 0) { + /* Accept about any file kind including directories + * (stored with trailing / with -r option) + */ + free(name); + return 0; + } + free(name); + + if (a != NULL) { + *a = s.st_attr; // << 16) | !(s.st_mode & S_IWRITE); + //*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 = t->mtime; /* best guess, (s.st_ctime: last status change!!) */ + } + return unix2dostime(&s.st_mtime); +} + + +ulg filetimeHHO(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; + int len = strlen(f), isstdin = !strcmp(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, "filetimeHHO"); + } + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + + if (isstdin) { + /* it is common for some PC based compilers to + fail with fstat() on devices or pipes */ + if (fstat(fileno(stdin), &s) != 0) { + s.st_mode = S_IFREG; s.st_size = -1L; + } + time(&s.st_ctime); + s.st_atime = s.st_mtime = s.st_ctime; + } else if (stat(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) | (isstdin ? 0L : (ulg)GetFileMode(name)); + //*a = (ulg)s.st_mode; + *a = s.st_attr; + } + + printf ("\nDette er en test LINE : 721 \n"); getch(); + + if (n != NULL) + *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; +#ifdef __WATCOMC__ + /* of course, Watcom always has to make an exception */ + if (s.st_atime == 312764400) + s.st_atime = s.st_mtime; + if (s.st_ctime == 312764400) + s.st_ctime = s.st_mtime; +#endif + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_ctime; + } + + printf ("\nDette er en test LINE : 735 \n"); getch(); + + //return GetFileTime(name); + free(name); + return t->atime; +} + +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(). + */ +{ + return rmdir(d); +} + +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; + /* create extra field and change z->att if desired */ +{ +#ifdef USE_EF_UT_TIME + if ((z->extra = (char *)malloc(EB_HEADSIZE+EB_UT_LEN(1))) == NULL) + return ZE_MEM; + + z->extra[0] = 'U'; + z->extra[1] = 'T'; + z->extra[2] = EB_UT_LEN(1); /* length of data part of e.f. */ + z->extra[3] = 0; + z->extra[4] = EB_UT_FL_MTIME; + z->extra[5] = (char)(z_utim->mtime); + z->extra[6] = (char)(z_utim->mtime >> 8); + z->extra[7] = (char)(z_utim->mtime >> 16); + z->extra[8] = (char)(z_utim->mtime >> 24); + + z->cext = z->ext = (EB_HEADSIZE+EB_UT_LEN(1)); + z->cextra = z->extra; + + return ZE_OK; +#else /* !USE_EF_UT_TIME */ + return (int)(z-z); +#endif /* ?USE_EF_UT_TIME */ +} + + +/******************************/ +/* Function version_local() */ +/******************************/ + +static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n"; + /* At module level to keep Turbo C++ 1.0 happy !! */ + +void version_local() +{ +#if defined(__DJGPP__) || defined(__WATCOMC__) || \ + (defined(_MSC_VER) && (_MSC_VER != 800)) + char buf[80]; +#endif + + printf(CompiledWith, + +#ifdef __GNUC__ +# if defined(__DJGPP__) + (sprintf(buf, "djgpp v%d / gcc ", __DJGPP__), buf), +# elif defined(__GO32__) + "djgpp v1.x / gcc ", +# elif defined(__EMX__) /* ...so is __EMX__ (double sigh) */ + "emx+gcc ", +# else + "gcc ", +# endif + __VERSION__, +#elif defined(__WATCOMC__) +# if (__WATCOMC__ % 10 > 0) +/* We do this silly test because __WATCOMC__ gives two digits for the */ +/* minor version, but Watcom packaging prefers to show only one digit. */ + (sprintf(buf, "Watcom C/C++ %d.%02d", __WATCOMC__ / 100, + __WATCOMC__ % 100), buf), "", +# else + (sprintf(buf, "Watcom C/C++ %d.%d", __WATCOMC__ / 100, + (__WATCOMC__ % 100) / 10), buf), "", +# endif +#elif defined(__TURBOC__) +# ifdef __BORLANDC__ + "Borland C++", +# if (__BORLANDC__ < 0x0200) + " 1.0", +# elif (__BORLANDC__ == 0x0200) /* James: __TURBOC__ = 0x0297 */ + " 2.0", +# elif (__BORLANDC__ == 0x0400) + " 3.0", +# elif (__BORLANDC__ == 0x0410) /* __BCPLUSPLUS__ = 0x0310 */ + " 3.1", +# elif (__BORLANDC__ == 0x0452) /* __BCPLUSPLUS__ = 0x0320 */ + " 4.0 or 4.02", +# elif (__BORLANDC__ == 0x0460) /* __BCPLUSPLUS__ = 0x0340 */ + " 4.5", +# elif (__BORLANDC__ == 0x0500) /* __TURBOC__ = 0x0500 */ + " 5.0", +# else + " later than 5.0", +# endif +# else + "Turbo C", +# if (__TURBOC__ > 0x0401) + "++ later than 3.0" +# elif (__TURBOC__ == 0x0401) /* Kevin: 3.0 -> 0x0401 */ + "++ 3.0", +# elif (__TURBOC__ == 0x0295) /* [661] vfy'd by Kevin */ + "++ 1.0", +# elif ((__TURBOC__ >= 0x018d) && (__TURBOC__ <= 0x0200)) /* James: 0x0200 */ + " 2.0", +# elif (__TURBOC__ > 0x0100) + " 1.5", /* James: 0x0105? */ +# else + " 1.0", /* James: 0x0100 */ +# endif +# endif +#elif defined(MSC) + "Microsoft C ", +# ifdef _MSC_VER +# if (_MSC_VER == 800) + "(Visual C++ v1.1)", +# elif (_MSC_VER == 850) + "(Windows NT v3.5 SDK)", +# elif (_MSC_VER == 900) + "(Visual C++ v2.0/v2.1)", +# elif (_MSC_VER > 900) + (sprintf(buf2, "(Visual C++ v%d.%d)", _MSC_VER/100 - 6, + _MSC_VER%100/10), buf2), +# else + (sprintf(buf, "%d.%02d", _MSC_VER/100, _MSC_VER%100), buf), +# endif +# else + "5.1 or earlier", +# endif +#else + "unknown compiler", "", +#endif + + "MS-DOS", + +#if (defined(__GNUC__) || (defined(__WATCOMC__) && defined(__386__))) + " (32-bit)", +#elif defined(M_I86HM) || defined(__HUGE__) + " (16-bit, huge)", +#elif defined(M_I86LM) || defined(__LARGE__) + " (16-bit, large)", +#elif defined(M_I86MM) || defined(__MEDIUM__) + " (16-bit, medium)", +#elif defined(M_I86CM) || defined(__COMPACT__) + " (16-bit, compact)", +#elif defined(M_I86SM) || defined(__SMALL__) + " (16-bit, small)", +#elif defined(M_I86TM) || defined(__TINY__) + " (16-bit, tiny)", +#else + " (16-bit)", +#endif + +#ifdef __DATE__ + " on ", __DATE__ +#else + "", "" +#endif + ); + +} /* end function version_local() */ + + +#ifdef __WATCOMC__ + +/* This papers over a bug in Watcom 10.6's standard library... sigh */ +/* Apparently it applies to both the DOS and Win32 stat()s. */ + +int stat_bandaid(const char *path, struct stat *buf) +{ + char newname[4]; + if (!stat(path, buf)) + return 0; + else if (!strcmp(path, ".") || (path[0] && !strcmp(path + 1, ":."))) { + strcpy(newname, path); + newname[strlen(path) - 1] = '\\'; /* stat(".") fails for root! */ + return stat(newname, buf); + } else + return -1; +} + +#endif + + diff --git a/novell/README b/novell/README new file mode 100644 index 0000000..a620c1b --- /dev/null +++ b/novell/README @@ -0,0 +1,9 @@ +Unfinished integration into zip 2.4 of novell port to zip 2.2. + +TODO: + +Too much novell specific stuff via ifdef into the main sourcecode, +use atexit() and setjmp()/longjmp() constructions instead. + +If a function doesn't exist (e.g. isatty), just write a wrapper +and put it in Netware.c diff --git a/novell/m.cmd b/novell/m.cmd new file mode 100644 index 0000000..04084b3 --- /dev/null +++ b/novell/m.cmd @@ -0,0 +1,9 @@ +wmake + +copy zip.nlm f: + +attrib -r -h -s g:\hho\*.* /s +del g:\hho\Attrib\*.* +del g:\hho\Attrib\*.* +rmdir g:\hho\Attrib + diff --git a/novell/osdep.h b/novell/osdep.h new file mode 100644 index 0000000..f7b463c --- /dev/null +++ b/novell/osdep.h @@ -0,0 +1,205 @@ +/* + 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 +*/ +/* The symbol DOS is used throughout the Zip source to identify code portions + * specific to the MSDOS port. + * Just to make sure, we check that it is set. + * (Currently, this should should not be neccessary, since currently it has + * to be set on the compiler command line to get this file read in.) + */ +#ifndef DOS +# define DOS +#endif + +/* The symbol MSDOS is consistently used in the generic source files + * to identify code to support for MSDOS (and MSDOS related) stuff. + * e.g: FAT or (FAT like) file systems, + * '\\' as directory separator in paths, + * "\r\n" as record (line) terminator in text files, ... + * + * IMPORTANT Note: + * This symbol is not unique for the MSDOS port !!!!!! + * It is also defined by ports to some other OS which are (to some extend) + * considered DOS compatible. + * Examples are: OS/2 (OS2), Windows NT and Windows 95 (WIN32). + * + */ +#ifndef MSDOS +# define MSDOS +#endif + +/* Power C is similar to Turbo C */ +#ifdef __POWERC +# define __TURBOC__ +#endif /* __POWERC */ + +/* Automatic setting of the common Microsoft C idenfifier MSC. + * NOTE: Watcom also defines M_I*86 ! + */ +#if defined(_MSC_VER) || (defined(M_I86) && !defined(__WATCOMC__)) +# ifndef MSC +# define MSC /* This should work for older MSC, too! */ +# endif +#endif + +#if !defined(__GO32__) && !defined(__EMX__) +# define NO_UNISTD_H +#endif + +#if defined(__WATCOMC__) && defined(__386__) +# define WATCOMC_386 +#endif + +#ifdef WINDLL +# define MSWIN +# define MEMORY16 +#endif + + +#if !defined(__EMX__) && !defined(__GO32__) && !defined(WATCOMC_386) +#if !defined(WINDLL) +# define MSDOS16 /* 16 bit MSDOS only */ +# define MEMORY16 +#endif +#endif + +#if !defined(NO_ASM) && !defined(ASMV) +# define ASMV +#endif + +/* enable creation of UTC time fields unless explicitely suppressed */ +#if !defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME) +# define USE_EF_UT_TIME +#endif + +/* check that TZ environment variable is defined before using UTC times */ +#if (!defined(NO_IZ_CHECK_TZ) && !defined(IZ_CHECK_TZ)) +# define IZ_CHECK_TZ +#endif + +#ifdef MEMORY16 +# ifndef NO_ASM +# define ASM_CRC 1 +# endif /* ?NO_ASM */ +# ifdef __TURBOC__ +# include +# if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__) +# if defined(DYNAMIC_CRC_TABLE) && defined(DYNALLOC_CRCTAB) + error: No dynamic CRC table allocation with Borland C far data models. +# endif /* DYNAMIC_CRC_TABLE */ +# endif /* Turbo/Borland C far data memory models */ +# define nearmalloc malloc +# define nearfree free +# define DYN_ALLOC +# else /* !__TURBOC__ */ +# include +# define nearmalloc _nmalloc +# define nearfree _nfree +# define farmalloc _fmalloc +# define farfree _ffree +# endif /* ?__TURBOC__ */ +# define MY_ZCALLOC 1 +# ifdef SMALL_MEM +# define CBSZ 2048 +# define ZBSZ 2048 +# endif +# ifdef MEDIUM_MEM +# define CBSZ 4096 +# define ZBSZ 4096 +# endif +# ifndef CBSZ +# define CBSZ 8192 +# define ZBSZ 8192 +# endif +#endif /* MEMORY16 */ + + +#ifdef MATCH +# undef MATCH +#endif +#define MATCH dosmatch /* use DOS style wildcard matching */ + +#define USE_CASE_MAP + +#define ROUNDED_TIME(time) (((time) + 1) & (~1)) +#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \ + procname(n, 1)) + +#define FOPR "rb" +#define FOPM "r+b" +#define FOPW "wb" + +#include +#include +#include + +#ifdef ZCRYPT_INTERNAL +# ifdef WINDLL +# define ZCR_SEED2 (unsigned)3141592654L /* use PI as seed pattern */ +# else +# ifndef __GO32__ +# include /* getpid() declaration for srand seed */ +# endif +# endif +#endif + +/* + * djgpp 1.x did not declare these + */ +#if defined(__GO32__) && !defined(__DJGPP__) +char *strlwr(char *); +int setmode(int, int); +#endif + +#ifdef __WATCOMC__ +# define NO_MKTEMP +# define HAS_OPENDIR +# define SSTAT stat_bandaid + int stat_bandaid(const char *path, struct stat *buf); + +/* Get asm routines to link properly without using "__cdecl": */ +# ifdef __386__ +# ifdef ASMV +# pragma aux match_init "_*" parm caller [] modify [] +# pragma aux longest_match "_*" parm caller [] value [eax] \ + modify [eax ecx edx] +# endif +# ifndef USE_ZLIB +# pragma aux crc32 "_*" parm caller [] value [eax] modify [eax] +# pragma aux get_crc_table "_*" parm caller [] value [eax] \ + modify [eax ecx edx] +# endif /* !USE_ZLIB */ +# else /* !__386__ */ +# ifdef ASMV +# pragma aux match_init "_*" parm caller [] loadds modify [ax bx] +# pragma aux longest_match "_*" parm caller [] loadds value [ax] \ + modify [ax bx cx dx es] +# endif /* ASMV */ +# ifndef USE_ZLIB +# pragma aux crc32 "_*" parm caller [] value [ax dx] \ + modify [ax bx cx dx es] +# pragma aux get_crc_table "_*" parm caller [] value [ax] \ + modify [ax bx cx dx] +# endif /* !USE_ZLIB */ +# endif /* ?__386__ */ +#endif /* __WATCOMC__ */ + +/* + * Wrapper function to get around the MSC7 00:00:00 31 Dec 1899 time base, + * see msdos.c for more info + */ + +#if defined(_MSC_VER) && _MSC_VER == 700 +# define localtime(t) msc7_localtime(t) +#endif + +#if (defined(__TURBOC__) && !defined(__BORLANDC__) && __TURBOC__ <= 0x0201) +# ifndef NO_MKTIME +# define NO_MKTIME /* TC 2.01 and earlier do not supply mktime() */ +# endif +#endif diff --git a/novell/signal.c b/novell/signal.c new file mode 100644 index 0000000..a092bd3 --- /dev/null +++ b/novell/signal.c @@ -0,0 +1,49 @@ +#include +#include + +/*******************************/ +/* Interupt handler */ +/*******************************/ + +int NLM_mainThreadGroupID; +int NLM_threadCnt = 0; +int NLM_exiting = FALSE; + +#pragma off(unreferenced); +void NLM_SignalHandler(int sig) +#pragma on(unreferenced); +{ + int handlerThreadGroupID; + + switch(sig) + { + case SIGTERM: + NLM_exiting = TRUE; + handlerThreadGroupID = GetThreadGroupID(); + SetThreadGroupID(NLM_mainThreadGroupID); + + /* NLM SDK functions may be called here */ + + while (NLM_threadCnt != 0) + ThreadSwitchWithDelay(); + SetThreadGroupID(handlerThreadGroupID); + break; + case SIGINT: + signal(SIGINT, NLM_SignalHandler); + break; + } + return; +} + +void NLMsignals(void) +{ + ++NLM_threadCnt; + NLM_mainThreadGroupID = GetThreadGroupID(); + signal(SIGTERM, NLM_SignalHandler); + signal(SIGINT, NLM_SignalHandler); +} + +void NLMexit(void) +{ + --NLM_threadCnt; +} diff --git a/novell/zip.lnk b/novell/zip.lnk new file mode 100644 index 0000000..19626c7 --- /dev/null +++ b/novell/zip.lnk @@ -0,0 +1,25 @@ +Form Novell NLM 'zip' +Name zip +Op ScreenName 'zip' +Op ThreadName 'zip__P ' +Op Stack = 8k +Op Version = 1.00.3 +Op Caseexact +Op Nod +File BITS.OBJ +File CRC_i386.OBJ +File CRYPT.OBJ +File DEFLATE.OBJ +File FILEIO.OBJ +File GLOBALS.OBJ +File MKTIME.OBJ +File NETWARE.OBJ +File TREES.OBJ +File TTYIO.OBJ +File UTIL.OBJ +File ZIP.OBJ +File ZIPFILE.OBJ +File ZIPUP.OBJ +File c:\novell\ndk\nwsdk\IMPORTS\PRELUDE.OBJ +Import @c:\novell\ndk\nwsdk\IMPORTS\ALL.IMP +Module CLib diff --git a/novell/zipup.h b/novell/zipup.h new file mode 100644 index 0000000..78b428a --- /dev/null +++ b/novell/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 (O_RDONLY|O_BINARY) +#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 diff --git a/os2/makefile.os2 b/os2/makefile.os2 new file mode 100644 index 0000000..a008ea5 --- /dev/null +++ b/os2/makefile.os2 @@ -0,0 +1,563 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit + +# Supported Make utilities: +# - Microsoft/IBM nmake +# - dmake 3.8 or higher +# - GNU make, at least version 3.68 +# - NOT watcom make +# For Microsoft and Watcom C, better use NMAKE, +# otherwise it doesn't matter. + +# Supported 16-bit C Compilers (created programs run under OS/2 1.x and 2.x): +# - Microsoft C 6.00A +# - Watcom C/C++ 16-bit + +# Supported 32-bit C Compilers (created programs run under OS/2 2.x only): +# - GNU gcc (emx kit 0.9c or newer) +# - IBM C Set/2 or C Set++ - does not yet work with ASM code +# - Watcom C/C++ 32-bit - does not yet work with ASM code +# - Borland C++ - no ASM code yet +# - MetaWare High C/C++ - no ASM code yet + +# Supported Cross-Compilers for MS-DOS: +# - Microsoft C 6.00A (16-bit) +# - Watcom C/C++ (16- and 32-bit) +# - GNU gcc (emx kit 0.9c or newer, 32-bit) + +# Supported Cross-Compilers for Win32 (WinNT/Win95): +# - GNU gcc (emx kit 0.9c or newer, with RSXNT 1.4 or newer) + +# Supported Assemblers: +# - Microsoft MASM 6.00 with Microsoft C, IBM C +# - Watcom WASM with Watcom C/C++ +# - GNU as with GNU gcc + +# To use MASM 5.x instead of MASM 6.00: +# - set AS="masm -T -Ml" +# - set ASEOL=";" + + +# To use, enter "make/nmake/dmake -f os2/makefile.os2" +# (this makefile depends on its name being "os2/makefile.os2"). + +# Add -DNO_ASM to CFLAGS and define OBJA to `nothing' if you do not have +# masm or ml. +# Add -DDYN_ALLOC to ASFLAGS if you have defined it in tailor.h or CFLAGS + +# Note: assembly language modules are really only supported for +# Microsoft 16-bit and GNU gcc 32-bit compilation. + +# Notes on 16-bit (Microsoft C 6.00) compilation: + +# The resulting programs can be used under OS/2 protected mode only. +# A larger stack has to be used for OS/2 because system calls +# use more stack than under DOS, 8k is recommended by Microsoft. +# Note that __STDC__ has to be defined explicitly with C 6.00 when -Ze +# is given, because Microsoft disables __STDC__ when their extensions +# are enabled. This is different from the C 5.10 behaviour. + +# Notes on 32-bit OS/2 compilation: + +# The resulting programs can be used under OS/2 protected +# mode of OS/2 2.x only, not under 1.x and not under DOS. +# It makes no difference if __STDC__ is defined or not. +# Borland C++ works with DYN_ALLOC only. + +# Special Notes on IBM C/C++ compilation: + +# The older C compiler (C Set/2) breaks, while optimizing, on deflate.c +# and trees.c (generates incorrect code). The newer C++ compiler (C Set++) +# doesn't but instead breaks on crypt.c in the initial version and up to +# CSD level 003. Starting with CSD level 004, it doesn't break any longer. + +# Notes on Watcom C/C++ compilation for DOS with the PMODE/W extender: +# +# You need to add the following section to your \watcom\binb\wlsystem.lnk +# file and also need to copy pmodew.exe to the same directory: +# +# system begin pmodew +# option osname='PMODE/W' +# libpath %WATCOM%\lib386 +# libpath %WATCOM%\lib386\dos +# op stub=pmodew.exe +# format os2 le +# end +# +# PMODE/W 1.16 or higher is required. + + +default: + @echo "Enter $(MAKE) -f os2/makefile.os2 target" + @echo "where target is one of:" + @echo " msc mscdos ibm ibmdyn ibmdebug ibmprof metaware borland" + @echo " gcc gccdyn gcczlib gccdebug gccdos gccwin32 gccw32dyn" + @echo " watcom watcom16 watcomdos watcom16dos pmodew" + +# MS C 6.00 for OS/2, 16-bit +msc: + $(MAKE) -f os2/makefile.os2 zips \ + CC="cl -nologo -AL -Ocegit -Gs $(FP)" \ + CFLAGS="-W1 -Zep -J -G2 -D__STDC__ -DOS2 -DASM_CRC" \ + AS="ml -nologo -c -Zm -Cp" \ + ASFLAGS="-D__LARGE__ -D__286" \ + LDFLAGS="-F 2000 -Lp -Fe" \ + LDFLAGS2="-link /noe /pm:vio" \ + OUT="-Fo" \ + OBJ=".obj" \ + CRCA_O="crc_i86.obj" \ + OBJA="match.obj" \ + DEF="os2\zip.def" + +# MS C 6.00 for OS/2, 16-bit, debug +mscdebug: + $(MAKE) -f os2/makefile.os2 zips \ + CC="cl -nologo -AL -Zi -Od $(FP)" \ + CFLAGS="-W1 -Zep -J -G2 -D__STDC__ -DOS2 -DASM_CRC" \ + AS="ml -nologo -c -Zim -Cp" \ + ASFLAGS="-D__LARGE__ -D__286" \ + LDFLAGS="-F 2000 -Lp -Fe" \ + LDFLAGS2="-link /noe /pm:vio" \ + OUT="-Fo" \ + OBJ=".obj" \ + CRCA_O="crc_i86.obj" \ + OBJA="match.obj" \ + DEF="os2\zip.def" + +# crosscompilation for MS-DOS with MS C 6.00 +mscdos: + $(MAKE) -f os2/makefile.os2 zips \ + CC="cl -nologo -AL -Ocegit -Gs $(FP)" \ + CFLAGS="-W1 -Zep -J -D__STDC__ -DDOS -DASM_CRC -DDYN_ALLOC" \ + AS="ml -nologo -c -Zm -Cp" \ + ASFLAGS="-D__LARGE__ -DDYN_ALLOC" \ + LDFLAGS="-F 2000 -Lr -Fe" \ + LDFLAGS2="-link /noe /exe" \ + OUT="-Fo" \ + OBJ=".obj" \ + CRCA_O="crc_i86.obj" \ + OBJA="match.obj" \ + OBJ2="msdos.obj" OBJU2="msdos_.obj" \ + OSDEP_H="msdos/osdep.h" ZIPUP_H="msdos/zipup.h" + + +# IBM C Set/2, statically linked runtime +ibm: + $(MAKE) -f os2/makefile.os2 zips \ + CC="icc -Q -O -Gs" \ + CFLAGS="-Sm -Sp1 -DOS2 -DNO_ASM" \ + AS="ml -nologo -c -Zm -Cp" \ + ASFLAGS="" \ + LDFLAGS="-B/ST:0x50000 -Fe" \ + LDFLAGS2="" \ + OUT="-Fo" \ + OBJ=".obj" \ + OBJA="" \ + DEF="os2/zip.def" + +# IBM C Set/2, dynamically linked runtime +ibmdyn: + $(MAKE) -f os2/makefile.os2 zips \ + CC="icc -Q -O -Gd -Gs" \ + CFLAGS="-Sm -Sp1 -DOS2 -DNO_ASM" \ + AS="ml -nologo -c -Zm -Cp" \ + ASFLAGS="" \ + LDFLAGS="-B/ST:0x50000 -Fe" \ + LDFLAGS2="" \ + OUT="-Fo" \ + OBJ=".obj" \ + OBJA="" \ + DEF="os2/zip.def" + +# IBM C Set/2, debug version +ibmdebug: + $(MAKE) -f os2/makefile.os2 zips \ + CC="icc -Q -Ti" \ + CFLAGS="-Sm -Sp1 -DOS2 -DNO_ASM -Tm" \ + AS="ml -nologo -c -Zim -Cp" \ + ASFLAGS="" \ + LDFLAGS="-B/ST:0x50000 -Fe" \ + LDFLAGS2="" \ + OUT="-Fo" \ + OBJ=".obj" \ + OBJA="" \ + DEF="os2/zip.def" + +# IBM C Set/2, profiling version for PROFIT +ibmprof: + $(MAKE) -f os2/makefile.os2 zips \ + CC="icc -Q -O -Gs -Gh -Ti" \ + CFLAGS="-Sm -Sp1 -DOS2 -DNO_ASM" \ + AS="ml -nologo -c -Zm -Cp" \ + ASFLAGS="" \ + LDFLAGS="-B/ST:0x50000 -Fe" \ + LDFLAGS2="profit.obj" \ + OUT="-Fo" \ + OBJ=".obj" \ + OBJA="" \ + DEF="os2/zip.def" + +# Watcom C/386 9.0 or higher +watcom: + $(MAKE) -f os2/makefile.os2 zips \ + CC="wcl386 -bt=os2v2 -zq -Ox -s" \ + CFLAGS="-Zp1 -DOS2 -DNO_ASM" \ + AS="wasm -zq -bt=os2v2 -3p" \ + ASFLAGS="" \ + LDFLAGS="-k0x50000 -x -l=os2v2 -Fe=" \ + LDFLAGS2="" \ + OUT="-Fo" \ + OBJ=".obj" \ + OBJA="" \ + DIRSEP="\\" \ + AS_DIRSEP="\\" + +# Watcom C/286 9.0 or higher +watcom16: + $(MAKE) -f os2/makefile.os2 zips \ + CC="wcl -bt=os2 -zq -ml -Ox -s" \ + CFLAGS="-Zp1 -DOS2 -DNO_ASM" \ + AS="wasm -zq -bt=os2 -2p -ml" \ + ASFLAGS="" \ + LDFLAGS="/\"option newfiles\" -k0x3000 -x -l=os2 -Fe=" \ + LDFLAGS2="" \ + OUT="-Fo" \ + OBJ=".obj" \ + OBJA="" \ + DIRSEP="\\" \ + AS_DIRSEP="\\" + +# Watcom C/386 9.0 or higher, crosscompilation for DOS, DOS4GW extender +watcomdos: + $(MAKE) -f os2/makefile.os2 zips \ + CC="wcl386 -bt=dos4g -zq -Ox -s" \ + CFLAGS="-Zp1 -DDOS -DMSDOS -DASM_CRC" \ + AS="wasm -zq -bt=dos4g -3p" \ + ASFLAGS="-DWATCOM_DSEG" \ + LDFLAGS="-k0x50000 -x -l=dos4g -Fe=" \ + LDFLAGS2="" \ + OUT="-Fo" \ + OBJ=".obj" \ + CRCA_O="crc_i386.obj" \ + OBJA="match32.obj" \ + OBJ2="msdos.obj" \ + OBJU2="msdos_.obj" \ + OSDEP_H="msdos/osdep.h" \ + ZIPUP_H="msdos/zipup.h" \ + DIRSEP="\\" \ + AS_DIRSEP="\\" + +# Watcom C/386 9.0 or higher, crosscompilation for DOS, PMODE/W extender +pmodew: + $(MAKE) -f os2/makefile.os2 zips \ + CC="wcl386 -bt=dos4g -zq -Ox -s" \ + CFLAGS="-Zp1 -DDOS -DMSDOS -DASM_CRC" \ + AS="wasm -zq -bt=dos4g -3p" \ + ASFLAGS="-DWATCOM_DSEG" \ + LDFLAGS="-k0x50000 -x -l=pmodew -Fe=" \ + LDFLAGS2="" \ + OUT="-Fo" \ + OBJ=".obj" \ + CRCA_O="crc_i386.obj" \ + OBJA="match32.obj" \ + OBJ2="msdos.obj" \ + OBJU2="msdos_.obj" \ + OSDEP_H="msdos/osdep.h" \ + ZIPUP_H="msdos/zipup.h" \ + DIRSEP="\\" \ + AS_DIRSEP="\\" + +# Watcom C/286 9.0 or higher, crosscompilation for DOS +watcom16dos: + $(MAKE) -f os2/makefile.os2 zips \ + CC="wcl -bt=dos -zq -ml -Ox -s" \ + CFLAGS="-Zp1 -DDOS -DMSDOS -DDYN_ALLOC -DNO_ASM" \ + AS="wasm -zq -bt=dos -2 -ml" \ + ASFLAGS="-DDYN_ALLOC" \ + LDFLAGS="-k0x2000 -x -l=dos -Fe=" \ + LDFLAGS2="" \ + OUT="-Fo" \ + OBJ=".obj" \ + OBJA="" \ + OBJ2="msdos.obj" \ + OBJU2="msdos_.obj" \ + OSDEP_H="msdos/osdep.h" \ + ZIPUP_H="msdos/zipup.h" \ + DIRSEP="\\" \ + AS_DIRSEP="\\" + +# MetaWare High C/C++ 3.2 +metaware: + $(MAKE) -f os2/makefile.os2 zips \ + CC="hc -O2" \ + CFLAGS="-D__32BIT__ -DOS2 -DNO_ASM" \ + AS="ml -nologo -c -Zm -Cp" \ + ASFLAGS="" \ + LDFLAGS="-o " \ + LDFLAGS2="" \ + OUT="-o ./" \ + OBJ=".obj" \ + DEF="-Hdef=os2/zip.def" + +# Borland C++ +borland: + $(MAKE) -f os2/makefile.os2 zips \ + CC="bcc -O" \ + CFLAGS="-w- -DOS2 -DDYN_ALLOC -DNO_ASM" \ + AS="ml -nologo -c -Zm -Cp" \ + ASFLAGS="" \ + LDFLAGS="-e" \ + LDFLAGS2="" \ + OUT="-o" \ + OBJ=".obj" \ + OBJA="" \ + DEF="-sDos2/zip.def" + +# emx 0.9c, gcc, OMF format, statically linked C runtime and emx +gcc: + $(MAKE) -f os2/makefile.os2 zips \ + CC="gcc -Zomf -O -Wimplicit" \ + CFLAGS="-DOS2 -DASM_CRC" \ + AS="gcc -Zomf" \ + ASFLAGS="-Di386" \ + LDFLAGS="-o ./" \ + LDFLAGS2="-Zsys -Zstack 320 -s -Zsmall-conv" \ + OUT="-o" \ + OBJ=".obj" \ + CRCA_O="crc_gcc.obj" \ + OBJA="matchgcc.obj" \ + DEF="os2/zip.def" + +# emx 0.9c, gcc, OMF format, dynamically linked C runtime and emx +gccdyn: + $(MAKE) -f os2/makefile.os2 zips \ + CC="gcc -Zomf -O -Wimplicit" \ + CFLAGS="-DOS2 -DASM_CRC" \ + AS="gcc -Zomf" \ + ASFLAGS="-Di386" \ + LDFLAGS="-o ./" \ + LDFLAGS2="-Zcrtdll -Zstack 320 -s" \ + OUT="-o" \ + OBJ=".obj" \ + CRCA_O="crc_gcc.obj" \ + OBJA="matchgcc.obj" \ + DEF="os2/zip.def" + +# emx 0.9c, gcc, OMF format, statically linked zlib, C runtime, and emx +gcczlib: + $(MAKE) -f os2/makefile.os2 zips \ + CC="gcc -Zomf -O -Wimplicit" \ + CFLAGS="-DOS2 -DUSE_ZLIB" \ + AS="gcc -Zomf" \ + ASFLAGS="-Di386 -DUSE_ZLIB" \ + LDFLAGS="-o ./" \ + LDFLAGS2="-L. -lzlib -Zsys -Zstack 320 -s -Zsmall-conv" \ + OUT="-o" \ + OBJ=".obj" \ + CRCA_O="" \ + OBJA="" \ + DEF="os2/zip.def" + +# emx 0.9c, gcc, a.out format, with debug info for gdb +gccdebug: + $(MAKE) -f os2/makefile.os2 zips \ + CC="gcc -g -Wimplicit" \ + CFLAGS="-DOS2 -DASM_CRC" \ + AS="gcc" \ + ASFLAGS="-Di386" \ + LDFLAGS="-o ./" \ + LDFLAGS2="" \ + OUT="-o" \ + OBJ=".o" \ + CRCA_O="crc_gcc.o" \ + OBJA="matchgcc.o" \ + DEF="os2/zip.def" + +# emx 0.9c, gcc, a.out format, for MS-DOS +gccdos: + $(MAKE) -f os2/makefile.os2 zips \ + CC="gcc -O -Wimplicit" \ + CFLAGS="-DDOS -DMSDOS -DASM_CRC" \ + AS="gcc" \ + ASFLAGS="-Di386" \ + LDFLAGS="-o ./" \ + LDFLAGS2="-s -Zsmall-conv" \ + OUT="-o" \ + OBJ=".o" \ + CRCA_O="crc_gcc.o" \ + OBJA="matchgcc.o" \ + OBJ2="msdos.o" \ + OBJU2="msdos_.o" \ + OSDEP_H="msdos/osdep.h" \ + ZIPUP_H="msdos/zipup.h" + +# emx 0.9c, gcc, RSXNT 1.4, cross-compilation for Win32 +gccwin32: + $(MAKE) -f os2/makefile.os2 zips \ + CC="gcc -Zwin32 -O -m486 -Wall" \ + CFLAGS="-DWIN32 -DASM_CRC" \ + AS="gcc -Zwin32" \ + ASFLAGS="-Di386" \ + LDFLAGS="-o ./" \ + LDFLAGS2="-ladvapi32 -Zsys -Zsmall-conv -s" \ + OUT="-o" \ + OBJ=".o" \ + CRCA_O="crc_gcc.o" \ + OBJA="matchgcc.o" \ + OBJ2="win32zip.o win32.o nt.o" \ + OBJU2="win32_.o" \ + OSDEP_H="win32/osdep.h" \ + ZIPUP_H="win32/zipup.h" \ + DEF="win32/zip.def" + +# emx 0.9c, gcc, RSXNT 1.4, cross-compilation for Win32, use emx C rtl DLL +gccw32dyn: + $(MAKE) -f os2/makefile.os2 zips \ + CC="gcc -Zwin32 -Zcrtdll=crtrsxnt -O -m486 -Wall" \ + CFLAGS="-DWIN32 -DASM_CRC" \ + AS="gcc -Zwin32" \ + ASFLAGS="-Di386" \ + LDFLAGS="-o ./" \ + LDFLAGS2="-ladvapi32 -s" \ + OUT="-o" \ + OBJ=".o" \ + CRCA_O="crc_gcc.o" \ + OBJA="matchgcc.o" \ + OBJ2="win32zip.o win32.o nt.o" \ + OBJU2="win32_.o" \ + OSDEP_H="win32/osdep.h" \ + ZIPUP_H="win32/zipup.h" \ + DEF="win32/zip.def" + +# VPATH = .;os2 + +# variables + +#default settings for target dependent macros: +DIRSEP = / +AS_DIRSEP = / +# LOCAL_OPTS = +CCFLAGS = $(CFLAGS) $(LOCAL_OPTS) + +OSDEP_H = os2/osdep.h +ZIPUP_H = os2/os2zip.h os2/zipup.h +CRCA_O = + + +OBJZ = zip$(OBJ) zipfile$(OBJ) zipup$(OBJ) fileio$(OBJ) util$(OBJ) \ + crc32$(OBJ) $(CRCA_O) globals$(OBJ) \ + deflate$(OBJ) trees$(OBJ) crypt$(OBJ) ttyio$(OBJ) +OBJ2 = os2zip$(OBJ) os2$(OBJ) os2acl$(OBJ) + +OBJU = zipfile_$(OBJ) fileio_$(OBJ) util_$(OBJ) globals$(OBJ) +OBJU2 = os2zip_$(OBJ) + +OBJN = zipnote$(OBJ) $(OBJU) $(OBJU2) +OBJS = zipsplit$(OBJ) $(OBJU) $(OBJU2) +OBJC = zipcloak$(OBJ) crc32_$(OBJ) crypt_$(OBJ) ttyio$(OBJ) $(OBJU) $(OBJU2) + +ZIP_H = zip.h ziperr.h tailor.h $(OSDEP_H) + +# rules + +.SUFFIXES: .c $(OBJ) + +.c$(OBJ): + $(CC) -c -I. $(CCFLAGS) $< + +.asm$(OBJ): + $(AS) $(ASFLAGS) $< $(ASEOL) + +# targets + +zips: zip.exe zipnote.exe zipsplit.exe zipcloak.exe + +zip$(OBJ): zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +zipfile$(OBJ): zipfile.c $(ZIP_H) crc32.h +zipup$(OBJ): zipup.c $(ZIP_H) revision.h crc32.h crypt.h $(ZIPUP_H) +fileio$(OBJ): fileio.c $(ZIP_H) crc32.h +util$(OBJ): util.c $(ZIP_H) +globals$(OBJ): globals.c $(ZIP_H) +deflate$(OBJ): deflate.c $(ZIP_H) +trees$(OBJ): trees.c $(ZIP_H) +crc32$(OBJ): crc32.c $(ZIP_H) crc32.h +crypt$(OBJ): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h +ttyio$(OBJ): ttyio.c $(ZIP_H) crypt.h ttyio.h + +os2zip$(OBJ): os2/os2zip.c $(ZIP_H) os2/os2zip.h os2/os2acl.h + $(CC) -c -I. $(CCFLAGS) os2$(DIRSEP)os2zip.c + +os2$(OBJ): os2/os2.c $(ZIP_H) os2/os2zip.h + $(CC) -c -I. $(CCFLAGS) os2$(DIRSEP)os2.c + +os2acl$(OBJ): os2/os2acl.c os2/os2acl.h + $(CC) -c -I. $(CCFLAGS) os2$(DIRSEP)os2acl.c + +msdos$(OBJ): msdos/msdos.c $(ZIP_H) + $(CC) -c -I. $(CCFLAGS) msdos$(DIRSEP)msdos.c + +win32zip$(OBJ): win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h + $(CC) -c -I. $(CCFLAGS) win32$(DIRSEP)win32zip.c + +win32$(OBJ): win32/win32.c $(ZIP_H) win32/win32zip.h + $(CC) -c -I. $(CCFLAGS) win32$(DIRSEP)win32.c + +nt$(OBJ): win32/nt.c win32/nt.h + $(CC) -c -I. $(CCFLAGS) win32$(DIRSEP)nt.c + +crc_i86$(OBJ): msdos/crc_i86.asm # 16bit only + $(AS) $(ASFLAGS) msdos$(AS_DIRSEP)crc_i86.asm $(ASEOL) + +crc_i386$(OBJ): win32/crc_i386.asm # 32bit, MASM + $(AS) $(ASFLAGS) win32$(AS_DIRSEP)crc_i386.asm $(ASEOL) + +crc_gcc$(OBJ): crc_i386.S # 32bit, GNU AS + $(AS) $(ASFLAGS) -x assembler-with-cpp -c -o $@ crc_i386.S + +match$(OBJ): msdos/match.asm + $(AS) $(ASFLAGS) msdos$(AS_DIRSEP)match.asm $(ASEOL) + +match32$(OBJ): win32/match32.asm + $(AS) $(ASFLAGS) win32$(AS_DIRSEP)match32.asm + +matchgcc$(OBJ): match.S + $(AS) $(ASFLAGS) -x assembler-with-cpp -c -o $@ match.S + +zipcloak$(OBJ): zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +zipnote$(OBJ): zipnote.c $(ZIP_H) revision.h +zipsplit$(OBJ): zipsplit.c $(ZIP_H) revision.h + +zipfile_$(OBJ): zipfile.c $(ZIP_H) crc32.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ zipfile.c + +fileio_$(OBJ): fileio.c $(ZIP_H) crc32.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ fileio.c + +util_$(OBJ): util.c $(ZIP_H) os2/os2zip.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ util.c + +crc32_$(OBJ): crc32.c $(ZIP_H) crc32.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ crc32.c + +crypt_$(OBJ): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ crypt.c + +os2zip_$(OBJ): os2/os2zip.c $(ZIP_H) os2/os2zip.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ os2$(DIRSEP)os2zip.c + +msdos_$(OBJ): msdos/msdos.c $(ZIP_H) + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ msdos$(DIRSEP)msdos.c + +win32_$(OBJ): win32/win32.c $(ZIP_H) win32/win32zip.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ win32$(DIRSEP)win32.c + +zip.exe: $(OBJZ) $(OBJ2) $(OBJA) + $(CC) $(LDFLAGS)$@ $(DEF) $(OBJZ) $(OBJ2) $(OBJA) $(LDFLAGS2) + +zipcloak.exe: $(OBJC) + $(CC) $(LDFLAGS)$@ $(DEF) $(OBJC) $(LDFLAGS2) + +zipnote.exe: $(OBJN) + $(CC) $(LDFLAGS)$@ $(DEF) $(OBJN) $(LDFLAGS2) + +zipsplit.exe: $(OBJS) + $(CC) $(LDFLAGS)$@ $(DEF) $(OBJS) $(LDFLAGS2) diff --git a/os2/match32.asm b/os2/match32.asm new file mode 100644 index 0000000..4797a73 --- /dev/null +++ b/os2/match32.asm @@ -0,0 +1,175 @@ +;=========================================================================== +; Copyright (c) 1990-2005 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 2005-Feb-10 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, all these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +;=========================================================================== +; +; match32.asm by Jean-loup Gailly. + +; match32.asm, optimized version of longest_match() in deflate.c +; To be used only with 32 bit flat model. To simplify the code, the option +; -DDYN_ALLOC is not supported. +; This file is only optional. If you don't have an assembler, use the +; C version (add -DNO_ASM to CFLAGS in makefile and remove match.o +; from OBJI). If you have reduced WSIZE in zip.h, then make sure this is +; assembled with an equivalent -DWSIZE=. + +; Caution: this module works for IBM's C/C++ compiler versions 2 and 3 +; and for Watcom's 32-bit C/C++ compiler. Both pass the first (and only) +; argument for longest_match in the EAX register, not on the stack, with +; the default calling conventions (_System would use the stack). +; +;============================================================================== +; +; Do NOT assemble this source if external crc32 routine from zlib gets used. +; + IFNDEF USE_ZLIB +; + .386 + + name match + +BSS32 segment dword USE32 public 'BSS' + extrn window : byte + extrn prev : word + extrn prev_length : dword + extrn strstart : dword + extrn match_start : dword + extrn max_chain_length : dword + extrn good_match : dword + extrn nice_match : dword +BSS32 ends + +CODE32 segment dword USE32 public 'CODE' + assume cs:CODE32, ds:FLAT, ss:FLAT + + public match_init + public longest_match + + ifndef WSIZE + WSIZE equ 32768 ; keep in sync with zip.h ! + endif + MIN_MATCH equ 3 + MAX_MATCH equ 258 + MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1) + MAX_DIST equ (WSIZE-MIN_LOOKAHEAD) + +; initialize or check the variables used in match.asm. + +match_init proc near + ret +match_init endp + +; ----------------------------------------------------------------------- +; Set match_start to the longest match starting at the given string and +; return its length. Matches shorter or equal to prev_length are discarded, +; in which case the result is equal to prev_length and match_start is +; garbage. +; IN assertions: cur_match is the head of the hash chain for the current +; string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + +; int longest_match(cur_match) + +longest_match proc near + + ; return address ; esp+16 + push ebp ; esp+12 + push edi ; esp+8 + push esi ; esp+4 + + lea ebx,window + add ebx,2 + window_off equ dword ptr [esp] + push ebx ; esp + +; match equ esi +; scan equ edi +; chain_length equ ebp +; best_len equ ebx +; limit equ edx + + mov esi,eax ; cur_match + mov edx,strstart + mov ebp,max_chain_length ; chain_length = max_chain_length + mov edi,edx + sub edx,MAX_DIST ; limit = strstart-MAX_DIST + cld ; string ops increment esi and edi + jae short limit_ok + sub edx,edx ; limit = NIL +limit_ok: + add edi,window_off ; edi = offset(window + strstart + 2) + mov ebx,prev_length ; best_len = prev_length + mov cx,[edi-2] ; cx = scan[0..1] + mov ax,[ebx+edi-3] ; ax = scan[best_len-1..best_len] + cmp ebx,good_match ; do we have a good match already? + jb do_scan + shr ebp,2 ; chain_length >>= 2 + jmp short do_scan + + align 4 ; align destination of branch +long_loop: +; at this point, edi == scan+2, esi == cur_match + mov ax,[ebx+edi-3] ; ax = scan[best_len-1..best_len] + mov cx,[edi-2] ; cx = scan[0..1] +short_loop: +; at this point, edi == scan+2, esi == cur_match, +; ax = scan[best_len-1..best_len] and cx = scan[0..1] + and esi,WSIZE-1 ; not needed if WSIZE=32768 + dec ebp ; --chain_length + shl esi,1 ; cur_match as word index + mov si,prev[esi] ; cur_match = prev[cur_match] + ; top word of esi is still 0 + jz the_end + cmp esi,edx ; cur_match <= limit ? + jbe short the_end +do_scan: + cmp ax,word ptr window[ebx+esi-1] ; check match at best_len-1 + jne short_loop + cmp cx,word ptr window[esi] ; check min_match_length match + jne short_loop + + add esi,window_off ; esi = match + mov ecx,(MAX_MATCH-2)/2 ; scan for at most MAX_MATCH bytes + mov eax,edi ; eax = scan+2 + repe cmpsw ; loop until mismatch + je maxmatch ; match of length MAX_MATCH? +mismatch: + mov cl,[edi-2] ; mismatch on first or second byte? + xchg eax,edi ; edi = scan+2, eax = end of scan + sub cl,[esi-2] ; cl = 0 if first bytes equal + sub eax,edi ; eax = len + sub esi,window_off ; esi = match - (2 + offset(window)) + sub esi,eax ; esi = cur_match (= match - len) + sub cl,1 ; set carry if cl == 0 (can't use DEC) + adc eax,0 ; eax = carry ? len+1 : len + cmp eax,ebx ; len > best_len ? + jle long_loop + mov match_start,esi ; match_start = cur_match + mov ebx,eax ; ebx = best_len = len + ifdef FULL_SEARCH + cmp eax,MAX_MATCH ; len >= MAX_MATCH ? + else + cmp eax,nice_match ; len >= nice_match ? + endif + jl long_loop +the_end: + mov eax,ebx ; result = eax = best_len + pop ebx + pop esi + pop edi + pop ebp + ret +maxmatch: ; come here if maximum match + cmpsb ; increment esi and edi + jmp mismatch ; force match_length = MAX_LENGTH + +longest_match endp + +CODE32 ends +; + ENDIF ; !USE_ZLIB +; + end diff --git a/os2/os2.c b/os2/os2.c new file mode 100644 index 0000000..b44fe2e --- /dev/null +++ b/os2/os2.c @@ -0,0 +1,481 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2005-Feb-10 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#include "zip.h" + +#ifndef UTIL /* the companion #endif is a bit of ways down ... */ + +#include +#if defined(__IBMC__) || defined(MSC) +#include +#endif + +/* Extra malloc() space in names for cutpath() */ +#define PAD 0 +#define PATH_END '/' + + +#include "os2zip.h" + +/* Library functions not in (most) header files */ + +extern char *label; +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +/* Local functions */ +local char *readd OF((DIR *)); + + +local char *readd(d) +DIR *d; /* directory stream to read from */ +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e; + + e = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; +} + +int wild(w) +char *w; /* path/pattern to match */ +/* If not in exclude mode, expand the pattern based on the contents of the + file system. Return an error code in the ZE_ class. */ +{ + DIR *d; /* stream for reading directory */ + char *e; /* name found in directory */ + int r; /* temporary variable */ + char *n; /* constructed name from directory */ + int f; /* true if there was a match */ + char *a; /* alloc'ed space for name */ + char *p; /* path */ + char *q; /* name */ + char v[5]; /* space for device current directory */ + + if (volume_label == 1) { + volume_label = 2; + label = getVolumeLabel((w != NULL && w[1] == ':') ? to_up(w[0]) : '\0', + &label_time, &label_mode, &label_utim); + if (label != NULL) { + newname(label, 0, 0); + } + if (w == NULL || (w[1] == ':' && w[2] == '\0')) return ZE_OK; + /* "zip -$ foo a:" can be used to force drive name */ + } + + if (w == NULL) + return ZE_OK; + + /* special handling of stdin request */ + if (strcmp(w, "-") == 0) /* if compressing stdin */ + return newname(w, 0, 0); + + /* Allocate and copy pattern */ + if ((p = a = malloc(strlen(w) + 1)) == NULL) + return ZE_MEM; + strcpy(p, w); + + /* catch special case: treat "*.*" as "*" for DOS-impaired people */ + r = strlen(p); + if (strcmp(p + r - 3, "*.*") == 0) + p[r - 2] = '\0'; + + /* Normalize path delimiter as '/'. */ + for (q = p; *q; q++) /* use / consistently */ + if (*q == '\\') + *q = '/'; + + /* Only name can have special matching characters */ + if ((q = isshexp(p)) != NULL && + (strrchr(q, '/') != NULL || strrchr(q, ':') != NULL)) + { + free((zvoid *)a); + return ZE_PARMS; + } + + /* Separate path and name into p and q */ + if ((q = strrchr(p, '/')) != NULL && (q == p || q[-1] != ':')) + { + *q++ = '\0'; /* path/name -> path, name */ + if (*p == '\0') /* path is just / */ + p = strcpy(v, "/."); + } + else if ((q = strrchr(p, ':')) != NULL) + { /* has device and no or root path */ + *q++ = '\0'; + p = strcat(strcpy(v, p), ":"); /* copy device as path */ + if (*q == '/') /* -> device:/., name */ + { + strcat(p, "/"); + q++; + } + strcat(p, "."); + } + else if (recurse && (strcmp(p, ".") == 0 || strcmp(p, "..") == 0)) + { /* current or parent directory */ + /* I can't understand Mark's code so I am adding a hack here to get + * "zip -r foo ." to work. Allow the dubious "zip -r foo .." but + * reject "zip -rm foo ..". + */ + if (dispose && strcmp(p, "..") == 0) + ziperr(ZE_PARMS, "cannot remove parent directory"); + q = "*"; + } + else /* no path or device */ + { + q = p; + p = strcpy(v, "."); + } + if (recurse && *q == '\0') { + q = "*"; + } + /* Search that level for matching names */ + if ((d = opendir(p)) == NULL) + { + free((zvoid *)a); + return ZE_MISS; + } + if ((r = strlen(p)) > 1 && + (strcmp(p + r - 2, ":.") == 0 || strcmp(p + r - 2, "/.") == 0)) + *(p + r - 1) = '\0'; + f = 0; + while ((e = readd(d)) != NULL) { + if (strcmp(e, ".") && strcmp(e, "..") && MATCH(q, e, 0)) + { + f = 1; + if (strcmp(p, ".") == 0) { /* path is . */ + r = procname(e, 0); /* name is name */ + if (r) { + f = 0; + break; + } + } else + { + if ((n = malloc(strlen(p) + strlen(e) + 2)) == NULL) + { + free((zvoid *)a); + closedir(d); + return ZE_MEM; + } + n = strcpy(n, p); + if (n[r = strlen(n) - 1] != '/' && n[r] != ':') + strcat(n, "/"); + r = procname(strcat(n, e), 0); /* name is path/name */ + free((zvoid *)n); + if (r) { + f = 0; + break; + } + } + } + } + closedir(d); + + /* Done */ + free((zvoid *)a); + return f ? ZE_OK : ZE_MISS; +} + +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 (n == NULL) /* volume_label request in freshen|delete mode ?? */ + return ZE_OK; + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0, caseflag); + else if (LSSTAT(n, &s) +#if defined(__TURBOC__) || defined(__WATCOMC__) + /* For these 2 compilers, stat() succeeds on wild card names! */ + || isshexp(n) +#endif + ) + { + /* 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 */ + for (p = n; *p; p++) /* use / consistently */ + if (*p == '\\') + *p = '/'; + 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 || 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 */ + int dosflag; + + dosflag = dosify || IsFileSystemFAT(x) || (x == label); + if (!dosify && use_longname_ea && (t = GetLongPathEA(x)) != NULL) + { + x = t; + dosflag = 0; + } + + /* Find starting point in name before doing malloc */ + /* Strip drive specification */ + t = *x && *(x + 1) == ':' ? x + 2 : x; + /* Strip "//host/share/" part of a UNC name */ + if ((!strncmp(x,"//",2) || !strncmp(x,"\\\\",2)) && + (x[2] != '\0' && x[2] != '/' && x[2] != '\\')) { + n = x + 2; + while (*n != '\0' && *n != '/' && *n != '\\') + n++; /* strip host name */ + if (*n != '\0') { + n++; + while (*n != '\0' && *n != '/' && *n != '\\') + n++; /* strip `share' name */ + } + if (*n != '\0') + t = n + 1; + } + /* Strip leading "/" to convert an absolute path into a relative path */ + while (*t == '/' || *t == '\\') + t++; + /* Strip leading "./" as well as drive letter */ + while (*t == '.' && (t[1] == '/' || t[1] == '\\')) + t += 2; + + /* Make changes, if any, to the copied name (leave original intact) */ + for (n = t; *n; n++) + if (*n == '\\') + *n = '/'; + + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + + if (dosify) + msname(n); + + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + return n; +} + + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + + return x; +} + + +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ + SetFileTime(f, d); +} + +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; + ulg r; + unsigned int len = strlen(f); + int isstdin = !strcmp(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 (isstdin) { + /* it is common for some PC based compilers to + fail with fstat() on devices or pipes */ + if (fstat(fileno(stdin), &s) != 0) { + s.st_mode = S_IFREG; s.st_size = -1L; + } + time(&s.st_ctime); + s.st_atime = s.st_mtime = s.st_ctime; + } 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) | (isstdin ? 0L : (ulg)GetFileMode(name)); + } + if (n != NULL) + *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; +#ifdef __WATCOMC__ + /* of course, Watcom always has to make an exception */ + if (s.st_atime == 312764400) + s.st_atime = s.st_mtime; + if (s.st_ctime == 312764400) + s.st_ctime = s.st_mtime; +#endif + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_ctime; + } + + r = GetFileTime(name); + free(name); + + return r; +} + +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(). + */ +{ + return rmdir(d); +} + + +#if defined MY_ZCALLOC /* Special zcalloc function for MEMORY16 (MSDOS/OS2) */ + +#ifdef MSC /* Microsoft C */ + +zvoid far *zcalloc (unsigned items, unsigned size) +{ + return (zvoid far *)halloc((long)items, size); +} + +zvoid zcfree (zvoid far *ptr) +{ + hfree((void huge *)ptr); +} + +#endif /* MSC */ + +#endif /* MY_ZCALLOC */ + +#endif /* !UTIL */ diff --git a/os2/os2acl.c b/os2/os2acl.c new file mode 100644 index 0000000..4f88643 --- /dev/null +++ b/os2/os2acl.c @@ -0,0 +1,385 @@ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* os2acl.c - access to OS/2 (LAN Server) ACLs + * + * Author: Kai Uwe Rommel + * Created: Mon Aug 08 1994 + * + */ + +/* + * supported 32-bit compilers: + * - emx+gcc + * - IBM C Set++ 2.1 or newer + * - Watcom C/C++ 10.0 or newer + * + * supported 16-bit compilers: + * - MS C 6.00A + * - Watcom C/C++ 10.0 or newer + * + * supported OS/2 LAN environments: + * - IBM LAN Server/Requester 3.0, 4.0 and 5.0 (Warp Server) + * - IBM Peer 1.0 (Warp Connect) + */ + +#ifdef KUR + static char *rcsid = + "$Id: os2acl.c,v 1.3 1996/04/03 19:18:27 rommel Exp rommel $"; + static char *rcsrev = "$Revision: 1.3 $"; +#endif + +/* + * $Log: os2acl.c,v $ + * Revision 1.3 1996/04/03 19:18:27 rommel + * minor fixes + * + * Revision 1.2 1996/03/30 22:03:52 rommel + * avoid frequent dynamic allocation for every call + * streamlined code + * + * Revision 1.1 1996/03/30 09:35:00 rommel + * Initial revision + * + */ + +#include +#include +#include +#include +#include + +#define INCL_NOPM +#define INCL_DOS +#define INCL_DOSERRORS +#include + +#include "os2/os2acl.h" + +#define UNLEN 20 + +#if defined(__WATCOMC__) && defined(__386__) && !defined(__32BIT__) +#define __32BIT__ +#endif + +#ifdef __32BIT__ +typedef ULONG U_INT; +#ifdef __EMX__ +#define PSTR16 _far16ptr +#define PTR16(x) _emx_32to16(x) +#else /* other 32-bit */ +#define PSTR16 PCHAR16 +#define PTR16(x) ((PCHAR16)(x)) +#endif +#else /* 16-bit */ +typedef USHORT U_INT; +#define PSTR16 PSZ +#define PTR16(x) (x) +#endif + +typedef struct access_list +{ + char acl_ugname[UNLEN+1]; + char acl_pad; + USHORT acl_access; +} +ACCLIST; + +typedef struct access_info +{ + PSTR16 acc_resource_name; + USHORT acc_attr; + USHORT acc_count; +} +ACCINFO; + +static ACCINFO *ai; +static char *path, *data; + +#ifdef __32BIT__ + +#ifdef __EMX__ + +static USHORT (APIENTRY *_NetAccessGetInfo)(PSZ pszServer, PSZ pszResource, + USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, PUSHORT pcbTotalAvail); +static USHORT (APIENTRY *_NetAccessSetInfo)(PSZ pszServer, PSZ pszResource, + USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, USHORT sParmNum); +static USHORT (APIENTRY *_NetAccessAdd)(PSZ pszServer, + USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer); + +USHORT NetAccessGetInfo(PSZ pszServer, PSZ pszResource, USHORT sLevel, + PVOID pbBuffer, USHORT cbBuffer, PUSHORT pcbTotalAvail) +{ + return (USHORT) + (_THUNK_PROLOG (4+4+2+4+2+4); + _THUNK_FLAT (pszServer); + _THUNK_FLAT (pszResource); + _THUNK_SHORT (sLevel); + _THUNK_FLAT (pbBuffer); + _THUNK_SHORT (cbBuffer); + _THUNK_FLAT (pcbTotalAvail); + _THUNK_CALLI (_emx_32to16(_NetAccessGetInfo))); +} + +USHORT NetAccessSetInfo(PSZ pszServer, PSZ pszResource, USHORT sLevel, + PVOID pbBuffer, USHORT cbBuffer, USHORT sParmNum) +{ + return (USHORT) + (_THUNK_PROLOG (4+4+2+4+2+2); + _THUNK_FLAT (pszServer); + _THUNK_FLAT (pszResource); + _THUNK_SHORT (sLevel); + _THUNK_FLAT (pbBuffer); + _THUNK_SHORT (cbBuffer); + _THUNK_SHORT (sParmNum); + _THUNK_CALLI (_emx_32to16(_NetAccessSetInfo))); +} + +USHORT NetAccessAdd(PSZ pszServer, USHORT sLevel, + PVOID pbBuffer, USHORT cbBuffer) +{ + return (USHORT) + (_THUNK_PROLOG (4+2+4+2); + _THUNK_FLAT (pszServer); + _THUNK_SHORT (sLevel); + _THUNK_FLAT (pbBuffer); + _THUNK_SHORT (cbBuffer); + _THUNK_CALLI (_emx_32to16(_NetAccessAdd))); +} + +#else /* other 32-bit */ + +APIRET16 (* APIENTRY16 NetAccessGetInfo)(PCHAR16 pszServer, PCHAR16 pszResource, + USHORT sLevel, PVOID16 pbBuffer, USHORT cbBuffer, PVOID16 pcbTotalAvail); +APIRET16 (* APIENTRY16 NetAccessSetInfo)(PCHAR16 pszServer, PCHAR16 pszResource, + USHORT sLevel, PVOID16 pbBuffer, USHORT cbBuffer, USHORT sParmNum); +APIRET16 (* APIENTRY16 NetAccessAdd)(PCHAR16 pszServer, + USHORT sLevel, PVOID16 pbBuffer, USHORT cbBuffer); + +#define _NetAccessGetInfo NetAccessGetInfo +#define _NetAccessSetInfo NetAccessSetInfo +#define _NetAccessAdd NetAccessAdd + +#if !defined(__IBMC__) || !defined(__TILED__) +#define _tmalloc malloc +#define _tfree free +#endif + +#endif +#else /* 16-bit */ + +USHORT (APIENTRY *NetAccessGetInfo)(PSZ pszServer, PSZ pszResource, + USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, PUSHORT pcbTotalAvail); +USHORT (APIENTRY *NetAccessSetInfo)(PSZ pszServer, PSZ pszResource, + USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, USHORT sParmNum); +USHORT (APIENTRY *NetAccessAdd)(PSZ pszServer, + USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer); + +#define _NetAccessGetInfo NetAccessGetInfo +#define _NetAccessSetInfo NetAccessSetInfo +#define _NetAccessAdd NetAccessAdd + +#define _tmalloc malloc +#define _tfree free + +#define DosQueryProcAddr(handle, ord, name, funcptr) \ + DosGetProcAddr(handle, name, funcptr) +#define DosQueryCurrentDir DosQCurDir +#define DosQueryCurrentDisk DosQCurDisk + +#endif + + +static BOOL acl_init(void) +{ + static BOOL initialized, netapi_avail; + HMODULE netapi; + char buf[256]; + + if (initialized) + return netapi_avail; + + initialized = TRUE; + + if (DosLoadModule(buf, sizeof(buf), "NETAPI", &netapi)) + return FALSE; + + if (DosQueryProcAddr(netapi, 0, "NETACCESSGETINFO", (PFN *) &_NetAccessGetInfo) || + DosQueryProcAddr(netapi, 0, "NETACCESSSETINFO", (PFN *) &_NetAccessSetInfo) || + DosQueryProcAddr(netapi, 0, "NETACCESSADD", (PFN *) &_NetAccessAdd)) + return FALSE; + +#if defined(__WATCOMC__) && defined(__386__) + NetAccessGetInfo = (PVOID) (ULONG) (PVOID16) NetAccessGetInfo; + NetAccessSetInfo = (PVOID) (ULONG) (PVOID16) NetAccessSetInfo; + NetAccessAdd = (PVOID) (ULONG) (PVOID16) NetAccessAdd; +#endif + + if ((path = _tmalloc(CCHMAXPATH)) == NULL) + return FALSE; + if ((data = _tmalloc(ACL_BUFFERSIZE)) == NULL) + return FALSE; + if ((ai = _tmalloc(sizeof(ACCINFO))) == NULL) + return -1; + + netapi_avail = TRUE; + + return netapi_avail; +} + +static void acl_mkpath(char *buffer, const char *source) +{ + char *ptr; + static char cwd[CCHMAXPATH]; + static U_INT cwdlen; + U_INT cdrive; + ULONG drivemap; + + if (isalpha((int)source[0]) && source[1] == ':') + buffer[0] = 0; /* fully qualified names */ + else + { + if (cwd[0] == 0) + { + DosQueryCurrentDisk(&cdrive, &drivemap); + cwd[0] = (char)(cdrive + '@'); + cwd[1] = ':'; + cwd[2] = '\\'; + cwdlen = sizeof(cwd) - 3; + DosQueryCurrentDir(0, cwd + 3, &cwdlen); + cwdlen = strlen(cwd); + } + + if (source[0] == '/' || source[0] == '\\') + { + if (source[1] == '/' || source[1] == '\\') + buffer[0] = 0; /* UNC names */ + else + { + strncpy(buffer, cwd, 2); + buffer[2] = 0; + } + } + else + { + strcpy(buffer, cwd); + if (cwd[cwdlen - 1] != '\\' && cwd[cwdlen - 1] != '/') + strcat(buffer, "/"); + } + } + + strcat(buffer, source); + + for (ptr = buffer; *ptr; ptr++) + if (*ptr == '/') + *ptr = '\\'; + + if (ptr[-1] == '\\') + ptr[-1] = 0; + + strupr(buffer); +} + +static int acl_bin2text(char *data, char *text) +{ + ACCINFO *ai; + ACCLIST *al; + U_INT cnt, offs; + + ai = (ACCINFO *) data; + al = (ACCLIST *) (data + sizeof(ACCINFO)); + + offs = sprintf(text, "ACL1:%X,%d\n", + ai -> acc_attr, ai -> acc_count); + + for (cnt = 0; cnt < ai -> acc_count; cnt++) + offs += sprintf(text + offs, "%s,%X\n", + al[cnt].acl_ugname, al[cnt].acl_access); + + return strlen(text); +} + +int acl_get(char *server, const char *resource, char *buffer) +{ + USHORT datalen; + PSZ srv = NULL; + int rc; + + if (!acl_init()) + return -1; + + if (server) + srv = server; + + acl_mkpath(path, resource); + datalen = 0; + + rc = NetAccessGetInfo(srv, path, 1, data, ACL_BUFFERSIZE, &datalen); + + if (rc == 0) + acl_bin2text(data, buffer); + + return rc; +} + +static int acl_text2bin(char *data, char *text, char *path) +{ + ACCINFO *ai; + ACCLIST *al; + char *ptr, *ptr2; + U_INT cnt; + + ai = (ACCINFO *) data; + ai -> acc_resource_name = PTR16(path); + + if (sscanf(text, "ACL1:%hX,%hd", + &ai -> acc_attr, &ai -> acc_count) != 2) + return ERROR_INVALID_PARAMETER; + + al = (ACCLIST *) (data + sizeof(ACCINFO)); + ptr = strchr(text, '\n') + 1; + + for (cnt = 0; cnt < ai -> acc_count; cnt++) + { + ptr2 = strchr(ptr, ','); + strncpy(al[cnt].acl_ugname, ptr, ptr2 - ptr); + al[cnt].acl_ugname[ptr2 - ptr] = 0; + sscanf(ptr2 + 1, "%hx", &al[cnt].acl_access); + ptr = strchr(ptr, '\n') + 1; + } + + return sizeof(ACCINFO) + ai -> acc_count * sizeof(ACCLIST); +} + +int acl_set(char *server, const char *resource, char *buffer) +{ + USHORT datalen; + PSZ srv = NULL; + + if (!acl_init()) + return -1; + + if (server) + srv = server; + + acl_mkpath(path, resource); + + ai -> acc_resource_name = PTR16(path); + ai -> acc_attr = 0; + ai -> acc_count = 0; + + NetAccessAdd(srv, 1, ai, sizeof(ACCINFO)); + /* Ignore any errors, most probably because ACL already exists. */ + /* In any such case, try updating the existing ACL. */ + + datalen = acl_text2bin(data, buffer, path); + + return NetAccessSetInfo(srv, path, 1, data, datalen, 0); +} + +/* end of os2acl.c */ diff --git a/os2/os2acl.h b/os2/os2acl.h new file mode 100644 index 0000000..03bb8a2 --- /dev/null +++ b/os2/os2acl.h @@ -0,0 +1,34 @@ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* os2acl.h + * + * Author: Kai Uwe Rommel + * Created: Fri Mar 29 1996 + */ + +/* $Id: os2acl.h,v 1.1 1996/03/30 09:35:00 rommel Exp rommel $ */ + +/* + * $Log: os2acl.h,v $ + * Revision 1.1 1996/03/30 09:35:00 rommel + * Initial revision + * + */ + +#ifndef _OS2ACL_H +#define _OS2ACL_H + +#define ACL_BUFFERSIZE 4096 + +int acl_get(char *server, const char *resource, char *buffer); +int acl_set(char *server, const char *resource, char *buffer); + +#endif /* _OS2ACL_H */ + +/* end of os2acl.h */ diff --git a/os2/os2zip.c b/os2/os2zip.c new file mode 100644 index 0000000..83bc3bc --- /dev/null +++ b/os2/os2zip.c @@ -0,0 +1,1213 @@ +/* + * @(#)dir.c 1.4 87/11/06 Public Domain. + * + * A public domain implementation of BSD directory routines for + * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield), + * August 1987 + * + * Ported to OS/2 by Kai Uwe Rommel + * Addition of other OS/2 file system specific code + * Placed into the public domain + */ + +/* does also contain EA access code for use in ZIP */ + + +#ifdef OS2 + + +#if defined(__EMX__) && !defined(__32BIT__) +# define __32BIT__ +#endif + +#include "zip.h" + +#include +#include +#include +#ifndef __BORLANDC__ +#include +#endif + +#define INCL_NOPM +#define INCL_DOSNLS +#define INCL_DOSERRORS +#include + +#include "os2zip.h" +#include "os2acl.h" + + +#ifndef max +#define max(a, b) ((a) < (b) ? (b) : (a)) +#endif + + +#ifdef __32BIT__ +#define DosFindFirst(p1, p2, p3, p4, p5, p6) \ + DosFindFirst(p1, p2, p3, p4, p5, p6, 1) +#else +#define DosQueryCurrentDisk DosQCurDisk +#define DosQueryFSAttach(p1, p2, p3, p4, p5) \ + DosQFSAttach(p1, p2, p3, p4, p5, 0) +#define DosQueryFSInfo(d, l, b, s) \ + DosQFSInfo(d, l, b, s) +#define DosQueryPathInfo(p1, p2, p3, p4) \ + DosQPathInfo(p1, p2, p3, p4, 0) +#define DosSetPathInfo(p1, p2, p3, p4, p5) \ + DosSetPathInfo(p1, p2, p3, p4, p5, 0) +#define DosEnumAttribute(p1, p2, p3, p4, p5, p6, p7) \ + DosEnumAttribute(p1, p2, p3, p4, p5, p6, p7, 0) +#define DosFindFirst(p1, p2, p3, p4, p5, p6) \ + DosFindFirst(p1, p2, p3, p4, p5, p6, 0) +#define DosMapCase DosCaseMap +#endif + + +#ifndef UTIL + +extern int noisy; + +#ifndef S_IFMT +#define S_IFMT 0xF000 +#endif + +static int attributes = _A_DIR | _A_HIDDEN | _A_SYSTEM; + +static char *getdirent(char *); +static void free_dircontents(struct _dircontents *); + +#ifdef __32BIT__ +static HDIR hdir; +static ULONG count; +static FILEFINDBUF3 find; +#else +static HDIR hdir; +static USHORT count; +static FILEFINDBUF find; +#endif + +DIR *opendir(const char *name) +{ + struct stat statb; + DIR *dirp; + char c; + char *s; + struct _dircontents *dp; + char nbuf[MAXPATHLEN + 1]; + int len; + + attributes = hidden_files ? (_A_DIR | _A_HIDDEN | _A_SYSTEM) : _A_DIR; + + strcpy(nbuf, name); + if ((len = strlen(nbuf)) == 0) + return NULL; + + if (((c = nbuf[len - 1]) == '\\' || c == '/') && (len > 1)) + { + nbuf[len - 1] = 0; + --len; + + if (nbuf[len - 1] == ':') + { + strcpy(nbuf+len, "\\."); + len += 2; + } + } + else + if (nbuf[len - 1] == ':') + { + strcpy(nbuf+len, "."); + ++len; + } + +#ifndef __BORLANDC__ + /* when will we ever see a Borland compiler that can properly stat !!! */ + if (stat(nbuf, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR) + return NULL; +#endif + + if ((dirp = malloc(sizeof(DIR))) == NULL) + return NULL; + + if (nbuf[len - 1] == '.' && (len == 1 || nbuf[len - 2] != '.')) + strcpy(nbuf+len-1, "*.*"); + else + if (((c = nbuf[len - 1]) == '\\' || c == '/') && (len == 1)) + strcpy(nbuf+len, "*"); + else + strcpy(nbuf+len, "\\*"); + + /* len is no longer correct (but no longer needed) */ + + dirp -> dd_loc = 0; + dirp -> dd_contents = dirp -> dd_cp = NULL; + + if ((s = getdirent(nbuf)) == NULL) + return dirp; + + do + { + if (((dp = malloc(sizeof(struct _dircontents))) == NULL) || + ((dp -> _d_entry = malloc(strlen(s) + 1)) == NULL) ) + { + if (dp) + free(dp); + free_dircontents(dirp -> dd_contents); + + return NULL; + } + + if (dirp -> dd_contents) + { + dirp -> dd_cp -> _d_next = dp; + dirp -> dd_cp = dirp -> dd_cp -> _d_next; + } + else + dirp -> dd_contents = dirp -> dd_cp = dp; + + strcpy(dp -> _d_entry, s); + dp -> _d_next = NULL; + + dp -> _d_size = find.cbFile; + dp -> _d_mode = find.attrFile; + dp -> _d_time = *(unsigned *) &(find.ftimeLastWrite); + dp -> _d_date = *(unsigned *) &(find.fdateLastWrite); + } + while ((s = getdirent(NULL)) != NULL); + + dirp -> dd_cp = dirp -> dd_contents; + + return dirp; +} + +void closedir(DIR * dirp) +{ + free_dircontents(dirp -> dd_contents); + free(dirp); +} + +struct dirent *readdir(DIR * dirp) +{ + static struct dirent dp; + + if (dirp -> dd_cp == NULL) + return NULL; + + dp.d_namlen = dp.d_reclen = + strlen(strcpy(dp.d_name, dirp -> dd_cp -> _d_entry)); + + dp.d_ino = 0; + + dp.d_size = dirp -> dd_cp -> _d_size; + dp.d_mode = dirp -> dd_cp -> _d_mode; + dp.d_time = dirp -> dd_cp -> _d_time; + dp.d_date = dirp -> dd_cp -> _d_date; + + dirp -> dd_cp = dirp -> dd_cp -> _d_next; + dirp -> dd_loc++; + + return &dp; +} + +void seekdir(DIR * dirp, long off) +{ + long i = off; + struct _dircontents *dp; + + if (off >= 0) + { + for (dp = dirp -> dd_contents; --i >= 0 && dp; dp = dp -> _d_next); + + dirp -> dd_loc = off - (i + 1); + dirp -> dd_cp = dp; + } +} + +long telldir(DIR * dirp) +{ + return dirp -> dd_loc; +} + +static void free_dircontents(struct _dircontents * dp) +{ + struct _dircontents *odp; + + while (dp) + { + if (dp -> _d_entry) + free(dp -> _d_entry); + + dp = (odp = dp) -> _d_next; + free(odp); + } +} + +static char *getdirent(char *dir) +{ + int done; + static int lower; + + if (dir != NULL) + { /* get first entry */ + hdir = HDIR_SYSTEM; + count = 1; + done = DosFindFirst(dir, &hdir, attributes, &find, sizeof(find), &count); + lower = IsFileSystemFAT(dir); + } + else /* get next entry */ + done = DosFindNext(hdir, &find, sizeof(find), &count); + + if (done == 0) + { + if (lower) + StringLower(find.achName); + return find.achName; + } + else + { + DosFindClose(hdir); + return NULL; + } +} + +/* FAT / HPFS detection */ + +int IsFileSystemFAT(char *dir) +{ + static USHORT nLastDrive = -1, nResult; + ULONG lMap; + BYTE bData[64]; + char bName[3]; +#ifdef __32BIT__ + ULONG nDrive, cbData; + PFSQBUFFER2 pData = (PFSQBUFFER2) bData; +#else + USHORT nDrive, cbData; + PFSQBUFFER pData = (PFSQBUFFER) bData; +#endif + + /* We separate FAT and HPFS+other file systems here. + at the moment I consider other systems to be similar to HPFS, + i.e. support long file names and being case sensitive */ + + if (isalpha(dir[0]) && (dir[1] == ':')) + nDrive = to_up(dir[0]) - '@'; + else + DosQueryCurrentDisk(&nDrive, &lMap); + + if (nDrive == nLastDrive) + return nResult; + + bName[0] = (char) (nDrive + '@'); + bName[1] = ':'; + bName[2] = 0; + + nLastDrive = nDrive; + cbData = sizeof(bData); + + if (!DosQueryFSAttach(bName, 0, FSAIL_QUERYNAME, (PVOID) pData, &cbData)) + nResult = !strcmp((char *) pData -> szFSDName + pData -> cbName, "FAT"); + else + nResult = FALSE; + + /* End of this ugly code */ + return nResult; +} + +/* access mode bits and time stamp */ + +int GetFileMode(char *name) +{ +#ifdef __32BIT__ + FILESTATUS3 fs; + return DosQueryPathInfo(name, 1, &fs, sizeof(fs)) ? -1 : fs.attrFile; +#else + USHORT mode; + return DosQFileMode(name, &mode, 0L) ? -1 : mode; +#endif +} + +ulg GetFileTime(char *name) +{ +#ifdef __32BIT__ + FILESTATUS3 fs; +#else + FILESTATUS fs; +#endif + USHORT nDate, nTime; + DATETIME dtCurrent; + + if (strcmp(name, "-") == 0) + { + DosGetDateTime(&dtCurrent); + fs.fdateLastWrite.day = dtCurrent.day; + fs.fdateLastWrite.month = dtCurrent.month; + fs.fdateLastWrite.year = dtCurrent.year - 1980; + fs.ftimeLastWrite.hours = dtCurrent.hours; + fs.ftimeLastWrite.minutes = dtCurrent.minutes; + fs.ftimeLastWrite.twosecs = dtCurrent.seconds / 2; + } + else + if (DosQueryPathInfo(name, 1, (PBYTE) &fs, sizeof(fs))) + return -1; + + nDate = * (USHORT *) &fs.fdateLastWrite; + nTime = * (USHORT *) &fs.ftimeLastWrite; + + return ((ULONG) nDate) << 16 | nTime; +} + +void SetFileTime(char *path, ulg stamp) +{ + FILESTATUS fs; + USHORT fd, ft; + + if (DosQueryPathInfo(path, FIL_STANDARD, (PBYTE) &fs, sizeof(fs))) + return; + + fd = (USHORT) (stamp >> 16); + ft = (USHORT) stamp; + fs.fdateLastWrite = fs.fdateCreation = * (FDATE *) &fd; + fs.ftimeLastWrite = fs.ftimeCreation = * (FTIME *) &ft; + + DosSetPathInfo(path, FIL_STANDARD, (PBYTE) &fs, sizeof(fs), 0); +} + +/* read volume label */ + +char *getVolumeLabel(int drive, unsigned long *vtime, unsigned long *vmode, + time_t *utim) +{ + static FSINFO fi; + + if (DosQueryFSInfo(drive ? drive - 'A' + 1 : 0, + FSIL_VOLSER, (PBYTE) &fi, sizeof(fi))) + return NULL; + + time(utim); + *vtime = unix2dostime(utim); + *vmode = _A_VOLID | _A_ARCHIVE; + + return (fi.vol.cch > 0) ? fi.vol.szVolLabel : NULL; +} + +/* FAT / HPFS name conversion stuff */ + +int IsFileNameValid(char *name) +{ + HFILE hf; +#ifdef __32BIT__ + ULONG uAction; +#else + USHORT uAction; +#endif + + switch(DosOpen(name, &hf, &uAction, 0, 0, FILE_OPEN, + OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, 0)) + { + case ERROR_INVALID_NAME: + case ERROR_FILENAME_EXCED_RANGE: + return FALSE; + case NO_ERROR: + DosClose(hf); + default: + return TRUE; + } +} + +void ChangeNameForFAT(char *name) +{ + char *src, *dst, *next, *ptr, *dot, *start; + static char invalid[] = ":;,=+\"[]<>| \t"; + + if (isalpha(name[0]) && (name[1] == ':')) + start = name + 2; + else + start = name; + + src = dst = start; + if ((*src == '/') || (*src == '\\')) + src++, dst++; + + while (*src) + { + for (next = src; *next && (*next != '/') && (*next != '\\'); next++); + + for (ptr = src, dot = NULL; ptr < next; ptr++) + if (*ptr == '.') + { + dot = ptr; /* remember last dot */ + *ptr = '_'; + } + + if (dot == NULL) + for (ptr = src; ptr < next; ptr++) + if (*ptr == '_') + dot = ptr; /* remember last _ as if it were a dot */ + + if (dot && (dot > src) && + ((next - dot <= 4) || + ((next - src > 8) && (dot - src > 3)))) + { + if (dot) + *dot = '.'; + + for (ptr = src; (ptr < dot) && ((ptr - src) < 8); ptr++) + *dst++ = *ptr; + + for (ptr = dot; (ptr < next) && ((ptr - dot) < 4); ptr++) + *dst++ = *ptr; + } + else + { + if (dot && (next - src == 1)) + *dot = '.'; /* special case: "." as a path component */ + + for (ptr = src; (ptr < next) && ((ptr - src) < 8); ptr++) + *dst++ = *ptr; + } + + *dst++ = *next; /* either '/' or 0 */ + + if (*next) + { + src = next + 1; + + if (*src == 0) /* handle trailing '/' on dirs ! */ + *dst = 0; + } + else + break; + } + + for (src = start; *src != 0; ++src) + if ((strchr(invalid, *src) != NULL) || (*src == ' ')) + *src = '_'; +} + +/* .LONGNAME EA code */ + +typedef struct +{ + ULONG cbList; /* length of value + 22 */ +#ifdef __32BIT__ + ULONG oNext; +#endif + BYTE fEA; /* 0 */ + BYTE cbName; /* length of ".LONGNAME" = 9 */ + USHORT cbValue; /* length of value + 4 */ + BYTE szName[10]; /* ".LONGNAME" */ + USHORT eaType; /* 0xFFFD for length-preceded ASCII */ + USHORT eaSize; /* length of value */ + BYTE szValue[CCHMAXPATH]; +} +FEALST; + +typedef struct +{ + ULONG cbList; +#ifdef __32BIT__ + ULONG oNext; +#endif + BYTE cbName; + BYTE szName[10]; /* ".LONGNAME" */ +} +GEALST; + +char *GetLongNameEA(const char *name) +{ + EAOP eaop; + GEALST gealst; + static FEALST fealst; + char *ptr; + + eaop.fpGEAList = (PGEALIST) &gealst; + eaop.fpFEAList = (PFEALIST) &fealst; + eaop.oError = 0; + + strcpy((char *) gealst.szName, ".LONGNAME"); + gealst.cbName = (BYTE) strlen((char *) gealst.szName); +#ifdef __32BIT__ + gealst.oNext = 0; +#endif + + gealst.cbList = sizeof(gealst); + fealst.cbList = sizeof(fealst); + + if (DosQueryPathInfo(name, FIL_QUERYEASFROMLIST, + (PBYTE) &eaop, sizeof(eaop))) + return NULL; + + if (fealst.cbValue > 4 && fealst.eaType == 0xFFFD) + { + fealst.szValue[fealst.eaSize] = 0; + + for (ptr = fealst.szValue; *ptr; ptr++) + if (*ptr == '/' || *ptr == '\\') + *ptr = '!'; + + return (char *) fealst.szValue; + } + + return NULL; +} + +char *GetLongPathEA(const char *name) +{ + static char nbuf[CCHMAXPATH + 1]; + char tempbuf[CCHMAXPATH + 1]; + char *comp, *next, *ea, sep; + BOOL bFound = FALSE; + + nbuf[0] = 0; + strncpy(tempbuf, name, CCHMAXPATH); + tempbuf[CCHMAXPATH] = '\0'; + next = tempbuf; + + while (*next) + { + comp = next; + + while (*next != '\\' && *next != '/' && *next != 0) + next++; + + sep = *next; + *next = 0; + + ea = GetLongNameEA(tempbuf); + strcat(nbuf, ea ? ea : comp); + bFound = bFound || (ea != NULL); + + if (sep) + { + strcat(nbuf, "\\"); + *next++ = sep; + } + } + + return (nbuf[0] != 0) && bFound ? nbuf : NULL; +} + +/* general EA code */ + +typedef struct +{ + USHORT nID; + USHORT nSize; + ULONG lSize; +} +EFHEADER, *PEFHEADER; + +#ifdef __32BIT__ + +/* Perhaps due to bugs in the current OS/2 2.0 kernel, the success or + failure of the DosEnumAttribute() and DosQueryPathInfo() system calls + depends on the area where the return buffers are allocated. This + differs for the various compilers, for some alloca() works, for some + malloc() works, for some, both work. We'll have to live with that. */ + +/* The use of malloc() is not very convenient, because it requires + backtracking (i.e. free()) at error returns. We do that for system + calls that may fail, but not for malloc() calls, because they are VERY + unlikely to fail. If ever, we just leave some memory allocated + over the usually short lifetime of a zip process ... */ + +#ifdef __GNUC__ +#define alloc(x) alloca(x) +#define unalloc(x) +#else +#define alloc(x) malloc(x) +#define unalloc(x) free(x) +#endif + +void GetEAs(char *path, char **bufptr, size_t *size, + char **cbufptr, size_t *csize) +{ + FILESTATUS4 fs; + PDENA2 pDENA, pFound; + EAOP2 eaop; + PGEA2 pGEA; + PGEA2LIST pGEAlist; + PFEA2LIST pFEAlist; + PEFHEADER pEAblock; + ULONG ulAttributes, ulMemoryBlock; + ULONG nLength; + ULONG nBlock; + char szName[CCHMAXPATH]; + + *size = *csize = 0; + + strcpy(szName, path); + nLength = strlen(szName); + if (szName[nLength - 1] == '/') + szName[nLength - 1] = 0; + + if (DosQueryPathInfo(szName, FIL_QUERYEASIZE, (PBYTE) &fs, sizeof(fs))) + return; + nBlock = max(fs.cbList, 65535); + if ((pDENA = alloc((size_t) nBlock)) == NULL) + return; + + ulAttributes = -1; + + if (DosEnumAttribute(ENUMEA_REFTYPE_PATH, szName, 1, pDENA, nBlock, + &ulAttributes, ENUMEA_LEVEL_NO_VALUE) + || ulAttributes == 0 + || (pGEAlist = alloc((size_t) nBlock)) == NULL) + { + unalloc(pDENA); + return; + } + + pGEA = pGEAlist -> list; + memset(pGEAlist, 0, nBlock); + pFound = pDENA; + + while (ulAttributes--) + { + if (!(strcmp(pFound -> szName, ".LONGNAME") == 0 && use_longname_ea)) + { + pGEA -> cbName = pFound -> cbName; + strcpy(pGEA -> szName, pFound -> szName); + + nLength = sizeof(GEA2) + strlen(pGEA -> szName); + nLength = ((nLength - 1) / sizeof(ULONG) + 1) * sizeof(ULONG); + + pGEA -> oNextEntryOffset = ulAttributes ? nLength : 0; + pGEA = (PGEA2) ((PCH) pGEA + nLength); + } + + pFound = (PDENA2) ((PCH) pFound + pFound -> oNextEntryOffset); + } + + if (pGEA == pGEAlist -> list) /* no attributes to save */ + { + unalloc(pDENA); + unalloc(pGEAlist); + return; + } + + pGEAlist -> cbList = (PCH) pGEA - (PCH) pGEAlist; + + pFEAlist = (PVOID) pDENA; /* reuse buffer */ + pFEAlist -> cbList = nBlock; + + eaop.fpGEA2List = pGEAlist; + eaop.fpFEA2List = pFEAlist; + eaop.oError = 0; + + if (DosQueryPathInfo(szName, FIL_QUERYEASFROMLIST, + (PBYTE) &eaop, sizeof(eaop))) + { + unalloc(pDENA); + unalloc(pGEAlist); + return; + } + + /* The maximum compressed size is (in case of STORE type) the + uncompressed size plus the size of the compression type field + plus the size of the CRC field + 2*5 deflate overhead bytes + for uncompressable data. + (5 bytes per 32Kb block, max compressed size = 2 blocks) */ + + ulAttributes = pFEAlist -> cbList; + ulMemoryBlock = ulAttributes + + sizeof(USHORT) + sizeof(ULONG) + EB_DEFLAT_EXTRA; + pEAblock = (PEFHEADER) malloc(sizeof(EFHEADER) + ulMemoryBlock); + + if (pEAblock == NULL) + { + unalloc(pDENA); + unalloc(pGEAlist); + return; + } + + *bufptr = (char *) pEAblock; + *size = sizeof(EFHEADER); + + pEAblock -> nID = EF_OS2EA; + pEAblock -> nSize = sizeof(pEAblock -> lSize); + pEAblock -> lSize = ulAttributes; /* uncompressed size */ + + nLength = memcompress((char *) (pEAblock + 1), ulMemoryBlock, + (char *) pFEAlist, ulAttributes); + *size += nLength; + pEAblock -> nSize += nLength; + + if ((pEAblock = (PEFHEADER) malloc(sizeof(EFHEADER))) == NULL) + { + unalloc(pDENA); + unalloc(pGEAlist); + return; + } + + *cbufptr = (char *) pEAblock; + *csize = sizeof(EFHEADER); + + pEAblock -> nID = EF_OS2EA; + pEAblock -> nSize = sizeof(pEAblock -> lSize); + pEAblock -> lSize = ulAttributes; + + if (noisy) + printf(" (%ld bytes EA's)", ulAttributes); + + unalloc(pDENA); + unalloc(pGEAlist); +} + +#else /* !__32BIT__ */ + +typedef struct +{ + ULONG oNextEntryOffset; + BYTE fEA; + BYTE cbName; + USHORT cbValue; + CHAR szName[1]; +} +FEA2, *PFEA2; + +typedef struct +{ + ULONG cbList; + FEA2 list[1]; +} +FEA2LIST, *PFEA2LIST; + +void GetEAs(char *path, char **bufptr, size_t *size, + char **cbufptr, size_t *csize) +{ + FILESTATUS2 fs; + PDENA1 pDENA, pFound; + EAOP eaop; + PGEALIST pGEAlist; + PGEA pGEA; + PFEALIST pFEAlist; + PFEA pFEA; + PFEA2LIST pFEA2list; + PFEA2 pFEA2; + EFHEADER *pEAblock; + ULONG ulAttributes; + USHORT nLength, nMaxSize; + char szName[CCHMAXPATH]; + + *size = *csize = 0; + + strcpy(szName, path); + nLength = strlen(szName); + if (szName[nLength - 1] == '/') + szName[nLength - 1] = 0; + + if (DosQueryPathInfo(szName, FIL_QUERYEASIZE, (PBYTE) &fs, sizeof(fs)) + || fs.cbList <= 2 * sizeof(ULONG)) + return; + + ulAttributes = -1; + nMaxSize = (USHORT) min(fs.cbList * 2, 65520L); + + if ((pDENA = malloc((size_t) nMaxSize)) == NULL) + return; + + if (DosEnumAttribute(ENUMEA_REFTYPE_PATH, szName, 1, pDENA, fs.cbList, + &ulAttributes, ENUMEA_LEVEL_NO_VALUE) + || ulAttributes == 0 + || (pGEAlist = malloc(nMaxSize)) == NULL) + { + free(pDENA); + return; + } + + pGEA = pGEAlist -> list; + pFound = pDENA; + + while (ulAttributes--) + { + nLength = strlen(pFound -> szName); + + if (!(strcmp(pFound -> szName, ".LONGNAME") == 0 && use_longname_ea)) + { + pGEA -> cbName = pFound -> cbName; + strcpy(pGEA -> szName, pFound -> szName); + + pGEA++; + pGEA = (PGEA) (((PCH) pGEA) + nLength); + } + + pFound++; + pFound = (PDENA1) (((PCH) pFound) + nLength); + } + + if (pGEA == pGEAlist -> list) + { + free(pDENA); + free(pGEAlist); + return; + } + + pGEAlist -> cbList = (PCH) pGEA - (PCH) pGEAlist; + + pFEAlist = (PFEALIST) pDENA; /* reuse buffer */ + pFEAlist -> cbList = fs.cbList; + pFEA = pFEAlist -> list; + + eaop.fpGEAList = pGEAlist; + eaop.fpFEAList = pFEAlist; + eaop.oError = 0; + + if (DosQueryPathInfo(szName, FIL_QUERYEASFROMLIST, + (PBYTE) &eaop, sizeof(eaop))) + { + free(pDENA); + free(pGEAlist); + return; + } + + /* now convert into new OS/2 2.0 32-bit format */ + + pFEA2list = (PFEA2LIST) pGEAlist; /* reuse buffer */ + pFEA2 = pFEA2list -> list; + + while ((PCH) pFEA - (PCH) pFEAlist < pFEAlist -> cbList) + { + nLength = sizeof(FEA) + pFEA -> cbName + 1 + pFEA -> cbValue; + memcpy((PCH) pFEA2 + sizeof(pFEA2 -> oNextEntryOffset), pFEA, nLength); + memset((PCH) pFEA2 + sizeof(pFEA2 -> oNextEntryOffset) + nLength, 0, 3); + pFEA = (PFEA) ((PCH) pFEA + nLength); + + nLength = sizeof(FEA2) + pFEA2 -> cbName + 1 + pFEA2 -> cbValue; + nLength = ((nLength - 1) / sizeof(ULONG) + 1) * sizeof(ULONG); + /* rounded up to 4-byte boundary */ + pFEA2 -> oNextEntryOffset = + ((PCH) pFEA - (PCH) pFEAlist < pFEAlist -> cbList) ? nLength : 0; + pFEA2 = (PFEA2) ((PCH) pFEA2 + nLength); + } + + pFEA2list -> cbList = (PCH) pFEA2 - (PCH) pFEA2list; + ulAttributes = pFEA2list -> cbList; + + pEAblock = (PEFHEADER) pDENA; /* reuse buffer */ + + *bufptr = (char *) pEAblock; + *size = sizeof(EFHEADER); + + pEAblock -> nID = EF_OS2EA; + pEAblock -> nSize = sizeof(pEAblock -> lSize); + pEAblock -> lSize = ulAttributes; /* uncompressed size */ + + nLength = (USHORT) memcompress((char *) (pEAblock + 1), + nMaxSize - sizeof(EFHEADER), (char *) pFEA2list, ulAttributes); + + *size += nLength; + pEAblock -> nSize += nLength; + + pEAblock = (PEFHEADER) pGEAlist; + + *cbufptr = (char *) pEAblock; + *csize = sizeof(EFHEADER); + + pEAblock -> nID = EF_OS2EA; + pEAblock -> nSize = sizeof(pEAblock -> lSize); + pEAblock -> lSize = ulAttributes; + + if (noisy) + printf(" (%ld bytes EA's)", ulAttributes); +} + +#endif /* __32BIT__ */ + +void GetACL(char *path, char **bufptr, size_t *size, + char **cbufptr, size_t *csize) +{ + static char *buffer; + char *cbuffer; + long bytes, cbytes; + PEFHEADER pACLblock; + + if (buffer == NULL) /* avoid frequent allocation (for every file) */ + if ((buffer = malloc(ACL_BUFFERSIZE)) == NULL) + return; + + if (acl_get(NULL, path, buffer)) + return; /* this will be the most likely case */ + + bytes = strlen(buffer); + + /* The maximum compressed size is (in case of STORE type) the + uncompressed size plus the size of the compression type field + plus the size of the CRC field + 2*5 deflate overhead bytes + for uncompressable data. + (5 bytes per 32Kb block, max compressed size = 2 blocks) */ + + cbytes = bytes + sizeof(USHORT) + sizeof(ULONG) + EB_DEFLAT_EXTRA; + if ((*bufptr = realloc(*bufptr, *size + sizeof(EFHEADER) + cbytes)) == NULL) + return; + + pACLblock = (PEFHEADER) (*bufptr + *size); + + cbuffer = (char *) (pACLblock + 1); + cbytes = memcompress(cbuffer, cbytes, buffer, bytes); + + *size += sizeof(EFHEADER) + cbytes; + + pACLblock -> nID = EF_ACL; + pACLblock -> nSize = sizeof(pACLblock -> lSize) + cbytes; + pACLblock -> lSize = bytes; /* uncompressed size */ + + if ((*cbufptr = realloc(*cbufptr, *csize + sizeof(EFHEADER))) == NULL) + return; + + pACLblock = (PEFHEADER) (*cbufptr + *csize); + *csize += sizeof(EFHEADER); + + pACLblock -> nID = EF_ACL; + pACLblock -> nSize = sizeof(pACLblock -> lSize); + pACLblock -> lSize = bytes; + + if (noisy) + printf(" (%ld bytes ACL)", bytes); +} + +#ifdef USE_EF_UT_TIME + +int GetExtraTime(struct zlist far *z, iztimes *z_utim) +{ + int eb_c_size = EB_HEADSIZE + EB_UT_LEN(1); + int eb_l_size = eb_c_size; + char *eb_c_ptr; + char *eb_l_ptr; + unsigned long ultime; + +#ifdef IZ_CHECK_TZ + if (!zp_tz_is_valid) return ZE_OK; /* skip silently no correct tz info */ +#endif + + eb_c_ptr = realloc(z->cextra, (z->cext + eb_c_size)); + if (eb_c_ptr == NULL) + return ZE_MEM; + z->cextra = eb_c_ptr; + eb_c_ptr += z->cext; + z->cext += eb_c_size; + + eb_c_ptr[0] = 'U'; + eb_c_ptr[1] = 'T'; + eb_c_ptr[2] = EB_UT_LEN(1); /* length of data part of e.f. */ + eb_c_ptr[3] = 0; + eb_c_ptr[4] = EB_UT_FL_MTIME; + ultime = (unsigned long) z_utim->mtime; + eb_c_ptr[5] = (char)(ultime); + eb_c_ptr[6] = (char)(ultime >> 8); + eb_c_ptr[7] = (char)(ultime >> 16); + eb_c_ptr[8] = (char)(ultime >> 24); + + if (z_utim->mtime != z_utim->atime || z_utim->mtime != z_utim->ctime) + { + eb_c_ptr[4] = EB_UT_FL_MTIME | EB_UT_FL_ATIME | EB_UT_FL_CTIME; + eb_l_size = EB_HEADSIZE + EB_UT_LEN(3); /* only on HPFS they can differ */ + /* so only then it makes sense to store all three time stamps */ + } + + eb_l_ptr = realloc(z->extra, (z->ext + eb_l_size)); + if (eb_l_ptr == NULL) + return ZE_MEM; + z->extra = eb_l_ptr; + eb_l_ptr += z->ext; + z->ext += eb_l_size; + + memcpy(eb_l_ptr, eb_c_ptr, eb_c_size); + + if (eb_l_size > eb_c_size) + { + eb_l_ptr[2] = EB_UT_LEN(3); + ultime = (unsigned long) z_utim->atime; + eb_l_ptr[9] = (char)(ultime); + eb_l_ptr[10] = (char)(ultime >> 8); + eb_l_ptr[11] = (char)(ultime >> 16); + eb_l_ptr[12] = (char)(ultime >> 24); + ultime = (unsigned long) z_utim->ctime; + eb_l_ptr[13] = (char)(ultime); + eb_l_ptr[14] = (char)(ultime >> 8); + eb_l_ptr[15] = (char)(ultime >> 16); + eb_l_ptr[16] = (char)(ultime >> 24); + } + + return ZE_OK; +} + +#endif /* USE_EF_UT_TIME */ + +int set_extra_field(struct zlist far *z, iztimes *z_utim) +{ + /* store EA data in local header, and size only in central headers */ + GetEAs(z->name, &z->extra, &z->ext, &z->cextra, &z->cext); + + /* store ACL data in local header, and size only in central headers */ + GetACL(z->name, &z->extra, &z->ext, &z->cextra, &z->cext); + +#ifdef USE_EF_UT_TIME + /* store extended time stamps in both headers */ + return GetExtraTime(z, z_utim); +#else /* !USE_EF_UT_TIME */ + return ZE_OK; +#endif /* ?USE_EF_UT_TIME */ +} + +#endif /* !UTIL */ + +/* Initialize the table of uppercase characters including handling of + country dependent characters. */ + +void init_upper() +{ + COUNTRYCODE cc; + unsigned nCnt, nU; + + for (nCnt = 0; nCnt < sizeof(upper); nCnt++) + upper[nCnt] = lower[nCnt] = (unsigned char) nCnt; + + cc.country = cc.codepage = 0; + DosMapCase(sizeof(upper), &cc, (PCHAR) upper); + + for (nCnt = 0; nCnt < 256; nCnt++) + { + nU = upper[nCnt]; + if (nU != nCnt && lower[nU] == (unsigned char) nU) + lower[nU] = (unsigned char) nCnt; + } + + for (nCnt = 'A'; nCnt <= 'Z'; nCnt++) + lower[nCnt] = (unsigned char) (nCnt - 'A' + 'a'); +} + +char *StringLower(char *szArg) +{ + unsigned char *szPtr; + for (szPtr = (unsigned char *) szArg; *szPtr; szPtr++) + *szPtr = lower[*szPtr]; + return szArg; +} + +#if defined(__IBMC__) && defined(__DEBUG_ALLOC__) +void DebugMalloc(void) +{ + _dump_allocated(0); /* print out debug malloc memory statistics */ +} +#endif + + +/******************************/ +/* Function version_local() */ +/******************************/ + +void version_local() +{ + static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n"; +#if defined(__IBMC__) || defined(__WATCOMC__) || defined(_MSC_VER) + char buf[80]; +#endif + + printf(CompiledWith, + +#ifdef __GNUC__ +# ifdef __EMX__ /* __EMX__ is defined as "1" only (sigh) */ + "emx+gcc ", __VERSION__, +# else + "gcc/2 ", __VERSION__, +# endif +#elif defined(__IBMC__) + "IBM ", +# if (__IBMC__ < 200) + (sprintf(buf, "C Set/2 %d.%02d", __IBMC__/100,__IBMC__%100), buf), +# elif (__IBMC__ < 300) + (sprintf(buf, "C Set++ %d.%02d", __IBMC__/100,__IBMC__%100), buf), +# else + (sprintf(buf, "Visual Age C++ %d.%02d", __IBMC__/100,__IBMC__%100), buf), +# endif +#elif defined(__WATCOMC__) + "Watcom C", (sprintf(buf, " (__WATCOMC__ = %d)", __WATCOMC__), buf), +#elif defined(__TURBOC__) +# ifdef __BORLANDC__ + "Borland C++", +# if (__BORLANDC__ < 0x0460) + " 1.0", +# elif (__BORLANDC__ == 0x0460) + " 1.5", +# else + " 2.0", +# endif +# else + "Turbo C", +# if (__TURBOC__ >= 661) + "++ 1.0 or later", +# elif (__TURBOC__ == 661) + " 3.0?", +# elif (__TURBOC__ == 397) + " 2.0", +# else + " 1.0 or 1.5?", +# endif +# endif +#elif defined(MSC) + "Microsoft C ", +# ifdef _MSC_VER + (sprintf(buf, "%d.%02d", _MSC_VER/100, _MSC_VER%100), buf), +# else + "5.1 or earlier", +# endif +#else + "unknown compiler", "", +#endif /* __GNUC__ */ + + "OS/2", + +/* GRR: does IBM C/2 identify itself as IBM rather than Microsoft? */ +#if (defined(MSC) || (defined(__WATCOMC__) && !defined(__386__))) +# if defined(M_I86HM) || defined(__HUGE__) + " (16-bit, huge)", +# elif defined(M_I86LM) || defined(__LARGE__) + " (16-bit, large)", +# elif defined(M_I86MM) || defined(__MEDIUM__) + " (16-bit, medium)", +# elif defined(M_I86CM) || defined(__COMPACT__) + " (16-bit, compact)", +# elif defined(M_I86SM) || defined(__SMALL__) + " (16-bit, small)", +# elif defined(M_I86TM) || defined(__TINY__) + " (16-bit, tiny)", +# else + " (16-bit)", +# endif +#else + " 2.x/3.x (32-bit)", +#endif + +#ifdef __DATE__ + " on ", __DATE__ +#else + "", "" +#endif + ); + + /* temporary debugging code for Borland compilers only */ +#ifdef __TURBOC__ + printf("\t(__TURBOC__ = 0x%04x = %d)\n", __TURBOC__, __TURBOC__); +#ifdef __BORLANDC__ + printf("\t(__BORLANDC__ = 0x%04x)\n",__BORLANDC__); +#else + printf("\tdebug(__BORLANDC__ not defined)\n"); +#endif +#ifdef __TCPLUSPLUS__ + printf("\t(__TCPLUSPLUS__ = 0x%04x)\n", __TCPLUSPLUS__); +#else + printf("\tdebug(__TCPLUSPLUS__ not defined)\n"); +#endif +#ifdef __BCPLUSPLUS__ + printf("\t(__BCPLUSPLUS__ = 0x%04x)\n\n", __BCPLUSPLUS__); +#else + printf("\tdebug(__BCPLUSPLUS__ not defined)\n\n"); +#endif +#endif /* __TURBOC__ */ + +} /* end function version_local() */ + +#endif /* OS2 */ diff --git a/os2/os2zip.h b/os2/os2zip.h new file mode 100644 index 0000000..06d0a02 --- /dev/null +++ b/os2/os2zip.h @@ -0,0 +1,84 @@ +/* + * @(#) dir.h 1.4 87/11/06 Public Domain. + * + * A public domain implementation of BSD directory routines for + * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield), + * August 1987 + * + * Ported to OS/2 by Kai Uwe Rommel + * Addition of other OS/2 file system specific code + * Placed into the public domain + */ + + +#define MAXNAMLEN 256 +#define MAXPATHLEN 256 + +#define _A_RONLY 0x01 +#define _A_HIDDEN 0x02 +#define _A_SYSTEM 0x04 +#define _A_VOLID 0x08 +#define _A_DIR 0x10 +#define _A_ARCHIVE 0x20 + + +struct dirent +{ + ino_t d_ino; /* a bit of a farce */ + int d_reclen; /* more farce */ + int d_namlen; /* length of d_name */ + char d_name[MAXNAMLEN + 1]; /* null terminated */ + /* nonstandard fields */ + long d_size; /* size in bytes */ + unsigned d_mode; /* DOS or OS/2 file attributes */ + unsigned d_time; + unsigned d_date; +}; + +/* The fields d_size and d_mode are extensions by me (Kai Uwe Rommel). + * The find_first and find_next calls deliver this data without any extra cost. + * If this data is needed, these fields save a lot of extra calls to stat() + * (each stat() again performs a find_first call !). + */ + +struct _dircontents +{ + char *_d_entry; + long _d_size; + unsigned _d_mode, _d_time, _d_date; + struct _dircontents *_d_next; +}; + +typedef struct _dirdesc +{ + int dd_id; /* uniquely identify each open directory */ + long dd_loc; /* where we are in directory entry is this */ + struct _dircontents *dd_contents; /* pointer to contents of dir */ + struct _dircontents *dd_cp; /* pointer to current position */ +} +DIR; + + +extern DIR *opendir(const char *); +extern struct dirent *readdir(DIR *); +extern void seekdir(DIR *, long); +extern long telldir(DIR *); +extern void closedir(DIR *); +#define rewinddir(dirp) seekdir(dirp, 0L) + +int GetFileMode(char *name); +ulg GetFileTime(char *name); +void SetFileTime(char *path, ulg stamp); +char *getVolumeLabel(int drive, unsigned long *time, unsigned long *mode, + time_t *utim); + +int IsFileNameValid(char *name); +int IsFileSystemFAT(char *dir); +void ChangeNameForFAT(char *name); + +char *GetLongNameEA(const char *name); +char *GetLongPathEA(const char *name); +void GetEAs(char *name, char **bufptr, size_t *size, + char **cbufptr, size_t *csize); + +char *StringLower(char *); diff --git a/os2/osdep.h b/os2/osdep.h new file mode 100644 index 0000000..ea2c3f9 --- /dev/null +++ b/os2/osdep.h @@ -0,0 +1,173 @@ +/* + 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 +*/ +#if defined(__OS2__) && !defined(OS2) +# define OS2 +#endif + +/* Automatic setting of the common Microsoft C idenfifier MSC. + * NOTE: Watcom also defines M_I*86 ! + */ +#if defined(_MSC_VER) || (defined(M_I86) && !defined(__WATCOMC__)) +# ifndef MSC +# define MSC /* This should work for older MSC, too! */ +# endif +#endif + +#if defined(__WATCOMC__) && defined(__386__) +# define WATCOMC_386 +#endif + +#if defined(__EMX__) || defined(WATCOMC_386) || defined(__BORLANDC__) +# if (defined(OS2) && !defined(__32BIT__)) +# define __32BIT__ +# endif +#endif + +#if defined(OS2) && !defined(__32BIT__) +# define MEMORY16 +#endif + +#ifndef NO_ASM +# define ASMV +/* # define ASM_CRC */ +#endif + +/* enable creation of UTC time fields unless explicitely suppressed */ +#if (!defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME)) +# define USE_EF_UT_TIME +#endif + +/* check that TZ environment variable is defined before using UTC times */ +#if (!defined(NO_IZ_CHECK_TZ) && !defined(IZ_CHECK_TZ)) +# define IZ_CHECK_TZ +#endif + +#ifndef ZP_NEED_MEMCOMPR +# define ZP_NEED_MEMCOMPR +#endif + +#ifdef MEMORY16 +# ifdef __TURBOC__ +# include +# if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__) +# if defined(DYNAMIC_CRC_TABLE) && defined(DYNALLOC_CRCTAB) + error: No dynamic CRC table allocation with Borland C far data models. +# endif /* DYNAMIC_CRC_TABLE */ +# endif /* Turbo/Borland C far data memory models */ +# define nearmalloc malloc +# define nearfree free +# define DYN_ALLOC +# else /* !__TURBOC__ */ +# include +# define nearmalloc _nmalloc +# define nearfree _nfree +# define farmalloc _fmalloc +# define farfree _ffree +# endif /* ?__TURBOC__ */ +# define MY_ZCALLOC 1 +#endif /* MEMORY16 */ + + +/* The symbol MSDOS is consistently used in the generic source files + * to identify code to support for MSDOS (and MSDOS related) stuff. + * e.g: FAT or (FAT like) file systems, + * '\\' as directory separator in paths, + * "\r\n" as record (line) terminator in text files, ... + * + * MSDOS is defined anyway with MS C 16-bit. So the block above works. + * For the 32-bit compilers, MSDOS must not be defined in the block above. + */ +#if (defined(OS2) && !defined(MSDOS)) +# define MSDOS +/* inherit MS-DOS file system etc. stuff */ +#endif + +#define USE_CASE_MAP +#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \ + procname(n, 1)) + +/* time stamp resolution of file system is 2 seconds */ +#define ROUNDED_TIME(time) ((time_t)(((unsigned long)(time) + 1) & (~1))) + +#define FOPR "rb" +#define FOPM "r+b" +#define FOPW "wb" + +#ifdef __32BIT__ +# define CBSZ 0x40000 +# define ZBSZ 0x40000 +#else +# define CBSZ 0xE000 +# define ZBSZ 0x7F00 /* Some libraries do not allow a buffer size > 32K */ +#endif + +#include +#include +#include + +#ifdef ZCRYPT_INTERNAL +# ifndef __GO32__ +# include /* getpid() declaration for srand seed */ +# endif +#endif + +/* for some (all ?) versions of IBM C Set/2 and IBM C Set++ */ +#ifndef S_IFMT +# define S_IFMT 0xF000 +#endif /* !S_IFMT */ + +#ifdef MSC +# define NO_UNISTD_H +#endif + +#ifdef __WATCOMC__ +# define NO_MKTEMP +/* Get asm routines to link properly without using "__cdecl": */ +# ifdef __386__ +# ifdef ASMV +# pragma aux window "*"; +# pragma aux prev "*"; +# pragma aux prev_length "*"; +# pragma aux strstart "*"; +# pragma aux match_start "*"; +# pragma aux max_chain_length "*"; +# pragma aux good_match "*"; +# pragma aux nice_match "*"; +# pragma aux match_init "*"; +# pragma aux longest_match "*"; +# endif +# ifndef USE_ZLIB +# pragma aux crc32 "_*" parm caller [] value [eax] modify [eax] +# pragma aux get_crc_table "_*" parm caller [] value [eax] \ + modify [eax ecx edx] +# endif /* !USE_ZLIB */ +# else /* !__386__ */ +# if defined(ASMV) || defined(ASM_CRC) +/*# error 16 bit assembly modules currently DO NOT WORK with Watcom C. */ +# endif +# ifdef ASMV +# pragma aux match_init "_*" parm caller [] loadds modify [ax bx] +# pragma aux longest_match "_*" parm caller [] loadds value [ax] \ + modify [ax bx cx dx es] +# endif +# ifndef USE_ZLIB +# pragma aux crc32 "_*" parm caller [] value [ax dx] \ + modify [ax bx cx dx es] +# pragma aux get_crc_table "_*" parm caller [] value [ax] \ + modify [ax bx cx dx] +# endif /* !USE_ZLIB */ +# endif /* ?__386__ */ +#endif + +#ifdef __IBMC__ +# define NO_UNISTD_H +# define NO_MKTEMP +# define timezone _timezone /* (underscore names work with */ +# define tzset _tzset /* all versions of C Set) */ +#endif diff --git a/os2/zip.def b/os2/zip.def new file mode 100644 index 0000000..7404eee --- /dev/null +++ b/os2/zip.def @@ -0,0 +1,3 @@ +NAME WINDOWCOMPAT NEWFILES +DESCRIPTION 'The world-famous zip utilities from Info-ZIP' +; STACKSIZE 0x50000 diff --git a/os2/zipup.h b/os2/zipup.h new file mode 100644 index 0000000..592cff8 --- /dev/null +++ b/os2/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 (O_RDONLY|O_BINARY) +#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 diff --git a/packaging/zip.spec b/packaging/zip.spec new file mode 100644 index 0000000..6d71d4b --- /dev/null +++ b/packaging/zip.spec @@ -0,0 +1,53 @@ +Summary: A file compression and packaging utility compatible with PKZIP. +Name: zip +Version: 3.0 +Release: 1.0.1 +License: distributable +Group: Applications/Archiving +Source:%{name}-%{version}.tar.gz +URL: http://www.info-zip.org/pub/infozip/Zip.html + +%description +The zip program is a compression and file packaging utility. Zip is +analogous to a combination of the UNIX tar and compress commands and +is compatible with PKZIP (a compression and file packaging utility for +MS-DOS systems). + +Install the zip package if you need to compress files using the zip +program. + +%prep +%setup -q +%build +make -f unix/Makefile prefix=/usr "CFLAGS=$RPM_OPT_FLAGS -I. -DUNIX -D_LARGEFILE64_SOURCE" generic_gcc + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT/usr/bin +mkdir -p $RPM_BULD_ROOT%{_mandir}/man1 + +make -f unix/Makefile prefix=$RPM_BUILD_ROOT/usr \ + MANDIR=$RPM_BUILD_ROOT%{_mandir}/man1 install + +pushd $RPM_BUILD_ROOT +for n in zipnote zipsplit zip zipcloak ; do + chmod 755 ./usr/bin/$n +done +popd + +mkdir -p %{buildroot}/usr/share/license +cp LICENSE %{buildroot}/usr/share/license/%{name} + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root) +%doc README BUGS CHANGES TODO WHATSNEW WHERE LICENSE +%doc proginfo/algorith.txt +/usr/bin/zipnote +/usr/bin/zipsplit +/usr/bin/zip +/usr/bin/zipcloak +%{_mandir}/man1/zip*1* +/usr/share/license/%{name} diff --git a/proginfo/3rdparty.bug b/proginfo/3rdparty.bug new file mode 100644 index 0000000..32e7823 --- /dev/null +++ b/proginfo/3rdparty.bug @@ -0,0 +1,114 @@ +Known, current PKZIP bugs/limitations: +------------------------------------- + + - PKUNZIP 2.04g is reported to corrupt some files when compressing them with + the -ex option; when tested, the files fail the CRC check, and comparison + with the original file shows bogus data (6K in one case) embedded in the + middle. PKWARE apparently characterized this as a "known problem." + + - PKUNZIP 2.04g considers volume labels valid only if originated on a FAT + file system, but other OSes and file systems (e.g., Amiga and OS/2 HPFS) + support volume labels, too. + + - PKUNZIP 2.04g can restore volume labels created by Zip 2.x but not by + PKZIP 2.04g (OS/2 DOS box only??). + + - PKUNZIP 2.04g gives an error message for stored directory entries created + under other OSes (although it creates the directory anyway), and PKZIP -vt + does not report the directory attribute bit as being set, even if it is. + + - PKZIP 2.04g mangles unknown extra fields (especially OS/2 extended attri- + butes) when adding new files to an existing zipfile [example: Walnut Creek + Hobbes March 1995 CD-ROM, FILE_ID.DIZ additions]. + + - PKUNZIP 2.04g is unable to detect or deal with prepended junk in a zipfile, + reporting CRC errors in valid compressed data. + + - PKUNZIP 2.04g (registered version) incorrectly updates/freshens the AV extra + field in authenticated archives. The resultant extra block length and total + extra field length are inconsistent. + + - [Windows version 2.01] Win95 long filenames (VFAT) are stored OK, but the + file system is always listed as ordinary DOS FAT. + + - [Windows version 2.50] NT long filenames (NTFS) are stored OK, but the + file system is always listed as ordinary DOS FAT. + + - PKZIP 2.04 for DOS encrypts using the OEM code page for 8-bit passwords, + while PKZIP 2.50 for Windows uses Latin-1 (ISO 8859-1). This means an + archive encrypted with an 8-bit password with one of the two PKZIP versions + cannot be decrypted with the other version. + + - PKZIP for Windows GUI (v 2.60), PKZIP for Windows command line (v 2.50) and + PKZIP for Unix (v 2.51) save the host's native file timestamps, but + only in a local extra field. Thus, timestamp-related selections (update + or freshen, both in extraction or archiving operations) use the DOS-format + localtime records in the Zip archives for comparisons. This may result + in wrong decisions of the program when updating archives that were + previously created in a different local time zone. + + - PKZIP releases newer than PKZIP for DOS 2.04g (PKZIP for Windows, both + GUI v 2.60 and console v 2.50; PKZIP for Unix v 2.51; probably others too) + use different code pages for storing filenames in central (OEM Codepage) + and local (ANSI / ISO 8859-1 Codepage) headers. When a stored filename + contains extended-ASCII characters, the local and central filename fields + do not match. As a consequence, Info-ZIP's Zip program considers such + archives as being corrupt and does not allow to modify them. Beginning + with release 5.41, Info-ZIP's UnZip contains a workaround to list AND + extract such archives with the correct filenames. + Maybe PKWARE has implemented this "feature" to allow extraction of their + "made-by-PKZIP for Unix/Windows" archives using old (v5.2 and earlier) + versions of Info-ZIP's UnZip for Unix/WinNT ??? (UnZip versions before + v 5.3 assumed that all archive entries were encoded in the codepage of + the UnZip program's host system.) + + - PKUNZIP 2.04g is reported to have problems with archives created on and/or + copied from Iomega ZIP drives (irony, eh?). + +Known, current WinZip bugs/limitations: +-------------------------------------- + + - [16-bit version 6.1a] NT short filenames (FAT) are stored OK, but the + file system is always listed as NTFS. + + - WinZip doesn't allow 8-bit passwords, which means it cannot decrypt an + archive created with an 8-bit password (by PKZIP or Info-ZIP's Zip). + + - WinZip (at least Versions 6.3 PL1, 7.0 SR1) fails to remove old extra + fields when freshening existing archive entries. When updating archives + created by Info-ZIP's Zip that contain UT time stamp extra field blocks, + UnZip cannot display or restore the updated (DOS) time stamps of the + freshened archive members. + +Known, current other third-party Zip utils bugs/limitations: +------------------------------------------------------------ + + - Asi's PKZip clones for Macintosh (versions 2.3 and 2.10d) are thoroughly + broken. They create invalid Zip archives! + a) For the first entry, both compressed size and uncompressed length + are recorded as 0, despite the fact that compressed data of non-zero + length has been added. + b) Their program creates extra fields with an (undocumented) internal + structure that violates the requirements of PKWARE's Zip format + specification document "appnote.txt": Their extra field seems to + contain pure data; the 4-byte block header consisting of block ID + and data length is missing. + +Possibly current PKZIP bugs: +--------------------------- + + - PKZIP (2.04g?) can silently ignore read errors on network drives, storing + the correct CRC and compressed length but an incorrect and inconsistent + uncompressed length. + + - PKZIP (2.04g?), when deleting files from within a zipfile on a Novell + drive, sometimes only zeros out the data while failing to shrink the + zipfile. + +Other limitations: +----------------- + + - PKZIP 1.x and 2.x encryption has been cracked (known-plaintext approach; + see http://www.cryptography.com/ for details). + +[many other bugs in PKZIP 1.0, 1.1, 1.93a, 2.04c and 2.04e] diff --git a/proginfo/ZipPorts b/proginfo/ZipPorts new file mode 100644 index 0000000..2d946d3 --- /dev/null +++ b/proginfo/ZipPorts @@ -0,0 +1,285 @@ +__________________________________________________________________________ + + This is the Info-ZIP file ZipPorts, last updated on 17 February 1996. +__________________________________________________________________________ + + +This document defines a set of rules and guidelines for those who wish to +contribute patches to Zip and UnZip (or even entire ports to new operating +systems). The list below is something between a style sheet and a "Miss +Manners" etiquette guide. While Info-ZIP encourages contributions and +fixes from anyone who finds something worth changing, we are also aware +of the fact that no two programmers have the programming style and that +unrestrained changes by a few dozen contributors would result in hideously +ugly (and unmaintainable) Frankenstein code. So consider the following an +attempt by the maintainers to maintain sanity as well as useful code. + +(The first version of this document was called either "ZipRules" or the +"No Feelthy ..." file and was compiled by David Kirschbaum in consulta- +tion with Mark Adler, Cave McNewt and others. The current incarnation +expands upon the original with insights gained from a few more years of +happy hacking...) + + +Summary: + + (0) The Platinum Rule: DON'T BREAK EXISTING PORTS +(0.1) The Golden Rule: DO UNTO THE CODE AS OTHERS HAVE DONE BEFORE +(0.2) The Silver Rule: DO UNTO THE LATEST BETA CODE +(0.3) The Bronze Rule: NO FEELTHY PIGGYBACKS + + (1) NO FEELTHY TABS + (2) NO FEELTHY CARRIAGE RETURNS + (3) NO FEELTHY 8-BIT CHARS + (4) NO FEELTHY LEFT-JUSTIFIED DASHES + (5) NO FEELTHY FANCY_FILENAMES + (6) NO FEELTHY NON-ZIPFILES AND NO FEELTHY E-MAIL BETAS + (7) NO FEELTHY E-MAIL BINARIES + + +Explanations: + + (0) The Platinum Rule: DON'T BREAK EXISTING PORTS + + No doubt about it, this is the one which really pisses us off and + pretty much guarantees that your port or patch will be ignored and/ + or laughed at. Examples range from the *really* severe cases which + "port" by ripping out all of the existing multi-OS code, to more + subtle oopers like relying on a local capability which doesn't exist + on other OSes or in older compilers (e.g., the use of ANSI "#elif" + or "#pragma" or "##" constructs, C++ comments, GNU extensions, etc.). + As to the former, use #ifdefs for your new code (see rule 0.3). And + as to the latter, trust us--there are few things we'd like better + than to be able to use some of the elegant "new" features out there + (many of which have been around for a decade or more). But our code + still compiles on machines dating back even longer, at least in spirit + --e.g., the AT&T 3B1 family and Dynix/ptx. Until we say otherwise, + dinosaurs are supported. + + +(0.1) The Golden Rule: DO UNTO THE CODE AS OTHERS HAVE DONE BEFORE + + In other words, try to fit into the local style of programming--no + matter how painful it may be. This includes cosmetic aspects like + indenting the same amount (both in the main C code and in the in- + clude files), using braces and comments similarly, NO TABS (see rule + #1), etc.; but also more substantive things like (for UnZip) putting + character strings into static (far) variables and using the LoadFar- + String macros to avoid overflowing limited MS-DOS data segments, and + using the ugly Info() macro instead of the more usual *printf() + functions so that dynamic-link-library ports are simpler. NEVER put + single-OS code (e.g., OS/2) of more than two or three lines into the + main (generic) modules; those are shared by everybody, and nobody else + cares about it or wants to see it. + + Note that not only do Zip and UnZip differ in these respects, so do + individual parts of each program. While it would be nice to have + global consistency, cosmetic changes are not a high priority; for + now we'll settle for local consistency--i.e., don't make things any + worse than they already are. + + Exception (BIG exception): single-letter variable names. Despite + the prevailing practice in much of Zip and parts of UnZip, and de- + spite the fact that one-letter variables allow you to pack really + cool, compact and complicated expressions onto one line, they also + make the code very difficult to maintain and are therefore *strongly* + discouraged. Don't ask us who is responsible in the first place; + while this sort of brain damage is not uncommon among former BASIC + programmers, it is nevertheless a lifelong embarrassment, and we do + try to pity the poor sod (that is, when we're not chasing bugs and + cursing him). :-) + + +(0.2) The Silver Rule: DO UNTO THE LATEST BETA CODE + + Few things are as annoying as receiving a large patch which obviously + represents a lot of time and careful work but which is relative to + an old version of Info-ZIP code. As wonderful as Larry Wall's patch + program is at applying context diffs to modified code, we regularly + make near-global changes and/or reorganize big chunks of the sources + (particularly in UnZip), and "patch" can't work miracles--big changes + invariably break any patch which is relative to an old version of the + code. + + Bottom line: contact the Info-ZIP core team FIRST (via the zip-bugs + e-mail address) and get up to date with the latest code before begin- + ning a big new port. And try to *stay* up to date while working on + your port--at least, as much as possible. + + +(0.3) The Bronze Rule: NO FEELTHY PIGGYBACKS + + UnZip is currently ported to something like 12 operating systems + (a few more or less depending on how one counts), and each of these, + with the possible exception of VM/CMS, has a unique macro identifying + it: AMIGA, ATARI_ST, __human68k__, MACOS, MSDOS, MVS, OS2, TOPS20, + UNIX, VMS, WIN32. Zip is moving in the same direction. New ports + should NOT piggyback one of the existing ports unless they are sub- + stantially similar--for example, Minix and Coherent are basically Unix + and therefore are included in the UNIX macro, but DOS djgpp ports and + OS/2 emx ports (both of which use the Unix-originated GNU C compiler + and often have "unix" defined by default) are obviously *not* Unix. + [The existing MTS port is a special exception; basically only one per- + son knows what MTS really is, and he's not telling. Presumably it's + not very close to Unix, but it's not worth arguing about it now.] + Along the same lines, neither OS/2 nor Human68K is the same as (or + even close to) MS-DOS. MVS and VM/CMS, on the other hand, are quite + similar to each other and are therefore combined in most places. + + Bottom line: when adding a new port (e.g., QDOS), create a new macro + for it ("QDOS"), a new subdirectory ("qdos") and a new source file for + OS-specific code ("qdos/qdos.c"). Use #ifdefs to fit any OS-specific + changes into the existing code (e.g., unzpriv.h). If it's close enough + to an existing port that piggybacking is a temptation, define a new + "combination macro" (e.g., "CMS_MVS") and replace the old macros as + required. (This last applies to UnZip, at least; the old preference + in Zip was fewer macros and long #ifdef lines, so talk to Onno or Jean- + loup about that.) See also rule 0.1. + + (Note that, for UnZip, new ports need not attempt to deal with all + features. Among other things, the wildcard-zipfile code in do_wild() + may be replaced with a supplied dummy version, since opendir/readdir/ + closedir() or the equivalent can be difficult to implement.) + + + (1) NO FEELTHY TABS + + Some editors and e-mail systems either have no capability to use + and/or display tab characters (ASCII 9) correctly, or they use non- + standard or variable-width tab columns, or other horrors. Some edi- + tors auto-convert spaces to tabs, after which the blind use of "diff + -c" results in a huge and mostly useless patch. Yes, *we* know about + diff's "-b" option, but not everyone does. And yes, we also know this + makes the source files bigger, even after compression; so be it. If + we *really* cared that much about the size of the sources, we'd still + be writing Unix-only utilities. + + Bottom line: use spaces, not tabs. + + Exception: some of the makefiles (the Unix one in particular) require + tabs as part of the syntax. + + Related utility programs: + Unix, OS/2 and MS-DOS: expand, unexpand. + MS-DOS: Buerg's TABS; Toad Hall's TOADSOFT. + And some editors have the conversion built-in. + + + (2) NO FEELTHY CARRIAGE RETURNS + + All source, documentation and other text files shall have Unix style + line endings (LF only, a.k.a. ctrl-J), not the DOS/OS2/NT CR+LF or Mac + CR-only line endings. + + Reason: "real programmers" in any environment can convert back and + forth between Unix and DOS/Mac style. All PC compilers but a few old + Borland versions can use either Unix or MS-DOS end-of-lines. Buerg's + LIST (file-display utility) for MS-DOS can use Unix or MS-DOS EOLs. + Both Zip and UnZip can convert line-endings as appropriate. But Unix + utilities like diff and patch die a horrible death (or produce horrible + output) if the target files have CRs. + + Related utilities: flip for Unix, OS/2 and MS-DOS; Unix "tr". + + Exceptions: documentation in pre-compiled binary distributions should + be in the local (target) format. + + + (3) NO FEELTHY 8-BIT CHARS + + Do all your editing in a plain-text ASCII editor. No WordPerfect, MS + Word, WordStar document mode, or other word processor files, thenkyew. + No desktop publishing. *Especially* no EBCDIC. No TIFFs, no GIFs, no + embedded pictures or dancing ladies (too bad, Cave Newt). [Sigh... -CN] + + Reason: compatibility with different consoles. My old XT clone is + the most limited! + + Exceptions: some Macintosh makefiles apparently require some 8-bit + characters; the Human68k port uses 8-bit characters for Kanji or Kana + comments (I think); etc. + + Related utilities: vi, emacs, EDLIN, Turbo C editor, other programmers' + editors, various word processor -> text conversion utilities. + + + (4) NO FEELTHY LEFT-JUSTIFIED DASHES + + Always precede repeated dashes (------) with one or more leading non- + dash characters: spaces, tabs, pound signs (#), comments (/*), what- + ever. + + Reason: sooner or later your source file will be e-mailed through an + undigestifier utility, most of which treat leading dashes as end-of- + message separators. We'd rather not have your code broken up into a + dozen separate untitled messages, thank you. + + + (5) NO FEELTHY FANCY_FILENAMES + + Assume the worst: that someone on a brain-damaged DOS system has to + work with everything your magic fingers produced. Keep the filenames + unimaginative and within MS-DOS limits (i.e., ordinary A..Z, 1..9, + "-$_!"-type characters, in the 8.3 "filename.ext" format). Mac and + Unix users, giggle all you want, but no spaces or multiple dots. + + Reason: compatibility with different file systems. MS-DOS FAT is the + most limited, with the exception of CompuServe (6.3, argh). + + Exceptions: slightly longer names are occasionally acceptable within + OS-specific subdirectories, but don't do that unless there's a good + reason for it. + + + (6) NO FEELTHY NON-ZIPFILES AND NO FEELTHY E-MAIL BETAS + + Beta testers and developers are in general expected to have both + ftp capability and the ability to deal with zipfiles. Those without + should either find a friend who does or else learn about ftp-mailers. + + Reason: the core development team barely has time to work on the + code, much less prepare oddball formats and/or mail betas out (and + the situation is getting worse, sigh). + + Exceptions: anyone seriously proposing to do a new port will be + given special treatment, particularly with respect to UnZip; we + obviously realize that bootstrapping a completely new port can be + quite difficult and have no desire to make it even harder due to + lack of access to the latest code (rule 0.2). + + Public releases of UnZip, on the other hand, will be available in + two formats: .tar.Z (16-bit compress'd tar) and .zip (either "plain" + or self-extracting). Zip sources and executables will generally only + be distributed in .zip format, since Zip is pretty much useless without + UnZip. + + + (7) NO FEELTHY E-MAIL BINARIES + + Binary files (e.g., executables, test zipfiles, etc.) should NEVER + be mailed raw. Where possible, they should be uploaded via ftp in + BINARY mode; if that's impossible, Mark's "ship" ASCII-encoder should + be used; and if that's unavailable, uuencode or xxencode should be + used. Weirdo NeXTmail, mailtool and MIME formats are also Right Out. + + Files larger than 50KB may need to be broken into pieces for mailing + (be sure to label them in order!), unless "ship" is used (it can + auto-split, label and mail files if told to do so). If Down Under + is involved, files must be broken into under-20KB chunks. + + Reasons: to prevent sounds of gagging mailers from resounding through- + out the land. To be relatively efficient in the binary->ASCII conver- + sion. (Yeah, yeah, I know, there's better conversions out there. But + not as widely known, and they often break on BITNET gateways.) + + Related utilities: ship, uuencode, uudecode, uuxfer20, quux, others. + Just make sure they don't leave embedded or trailing spaces (that is, + they should use the "`" character in place of ASCII 32). Otherwise + mailers are prone to truncate or whatever. + + +Greg Roelofs (a.k.a. Cave Newt) +Info-ZIP UnZip maintainer + +David Kirschbaum +former Info-ZIP Coordinator diff --git a/proginfo/algorith.txt b/proginfo/algorith.txt new file mode 100644 index 0000000..867e30b --- /dev/null +++ b/proginfo/algorith.txt @@ -0,0 +1,68 @@ +Zip's deflation algorithm is a variation of LZ77 (Lempel-Ziv 1977, see +reference below). It finds duplicated strings in the input data. The +second occurrence of a string is replaced by a pointer to the previous +string, in the form of a pair (distance, length). Distances are +limited to 32K bytes, and lengths are limited to 258 bytes. When a +string does not occur anywhere in the previous 32K bytes, it is +emitted as a sequence of literal bytes. (In this description, +'string' must be taken as an arbitrary sequence of bytes, and is not +restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when zip determines that it +would be useful to start another block with fresh trees. (This is +somewhat similar to compress.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (zip -1 +to -9). So zip does not always find the longest possible match but +generally finds a match which is long enough. + +zip also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, zip searches for a +longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the longer match is emitted afterwards. Otherwise, +the original match is kept, and the next match search is attempted only +N steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, zip reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, zip attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (speed options -1 to -3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + +Jean-loup Gailly +jloup@chorus.fr + +References: + +[LZ77] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data +Compression", IEEE Transactions on Information Theory", Vol. 23, No. 3, +pp. 337-343. + +APPNOTE.TXT documentation file in PKZIP 1.93a. It is available by +ftp in ftp.cso.uiuc.edu:/pc/exec-pc/pkz193a.exe [128.174.5.59] + +'Deflate' Compressed Data Format Specification: +ftp://ftp.uu.net/pub/archiving/zip/doc/deflate-1.1.doc diff --git a/proginfo/ebcdic.msg b/proginfo/ebcdic.msg new file mode 100644 index 0000000..1a7bbad --- /dev/null +++ b/proginfo/ebcdic.msg @@ -0,0 +1,63 @@ +From dima@mitrah.ru Mon Nov 10 02:25:38 2003 +Return-Path: +Received: from b.mx.sonic.net (eth0.b.mx.sonic.net [209.204.159.4]) + by eth0.a.lds.sonic.net (8.12.10/8.12.9) with ESMTP id hAAAPccT025257 + for ; Mon, 10 Nov 2003 02:25:38 -0800 +Received: from icicle.pobox.com (icicle.pobox.com [207.8.214.2]) + by b.mx.sonic.net (8.12.10/8.12.7) with ESMTP id hAAAPar9007141 + for ; Mon, 10 Nov 2003 02:25:37 -0800 +Received: from icicle.pobox.com (localhost[127.0.0.1]) + by icicle.pobox.com (Postfix) with ESMTP id 9BA347A96B + for ; Sat, 8 Nov 2003 06:15:13 -0500 (EST) +Delivered-To: newt@pobox.com +Received: from mail.ropnet.ru (mail.ropnet.ru[212.42.37.90]) + by icicle.pobox.com (Postfix) with ESMTP id A96817A8F7 + for ; Sat, 8 Nov 2003 06:15:04 -0500 (EST) +Received: from d34-67.ropnet.ru (d34-67.ropnet.ru [212.42.34.67]) + by mail.ropnet.ru (8.11.7/8.11.7) with ESMTP id hA8BEjF76200 + for ; Sat, 8 Nov 2003 14:14:46 +0300 (MSK) +Resent-Date: Sat, 8 Nov 2003 14:14:46 +0300 (MSK) +Resent-Message-Id: <200311081114.hA8BEjF76200@mail.ropnet.ru> +Date: Sat, 8 Nov 2003 14:18:18 +0300 +From: Dmitri Koulikov +X-Mailer: The Bat! (v1.62r) Personal +Reply-To: Dmitri Koulikov +X-Priority: 3 (Normal) +Message-ID: <815640011.20031108141818@mitrah.ru> +To: newt@pobox.com +Subject: unzip and zip lack NLS - 2 +Resent-From: Dmitri Koulikov +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="----------EB1581C42AB86662" +Status: R + +------------EB1581C42AB86662 +Content-Type: text/plain; charset=us-ascii +Content-Transfer-Encoding: 7bit + +Hello Greg Roelofs, + + By mistake I sent you wrong version of ebcdic.h. Now it is as it +have to. + Additionally I found that zip works with Russian filenames good. +But fails to process -D switch. So I have to chahge zipfile.c. Most +probably this is not good but it works. + +-- +Best regards, + Dmitri + +mailto:dima@mitrah.ru +------------EB1581C42AB86662 +Content-Type: application/octet-stream; name="ebcdic.h" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename="ebcdic.h" + +------------EB1581C42AB86662 +Content-Type: application/octet-stream; name="zipfile.c" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename="zipfile.c" + +------------EB1581C42AB86662-- + + diff --git a/proginfo/extrafld.txt b/proginfo/extrafld.txt new file mode 100644 index 0000000..624e05c --- /dev/null +++ b/proginfo/extrafld.txt @@ -0,0 +1,1372 @@ +The following are the known types of zipfile extra fields as of this +writing. Extra fields are documented in PKWARE's appnote.txt and are +intended to allow for backward- and forward-compatible extensions to +the zipfile format. Multiple extra-field types may be chained together, +provided that the total length of all extra-field data is less than 64KB. +(In fact, PKWARE requires that the total length of the entire file header, +including timestamp, file attributes, filename, comment, extra field, etc., +be no more than 64KB.) + +Each extra-field type (or subblock) must contain a four-byte header con- +sisting of a two-byte header ID and a two-byte length (little-endian) for +the remaining data in the subblock. If there are additional subblocks +within the extra field, the header for each one will appear immediately +following the data for the previous subblock (i.e., with no padding for +alignment). + +All integer fields in the descriptions below are in little-endian (Intel) +format unless otherwise specified. Note that "Short" means two bytes, +"Long" means four bytes, and "Long-Long" means eight bytes, regardless +of their native sizes. Unless specifically noted, all integer fields should +be interpreted as unsigned (non-negative) numbers. + +Christian Spieler, 20010517 + +Updated to include the Unicode extra fields. Added new Unix extra field. + +Ed Gordon, 20060819, 20070607, 20070909, 20080426, 20080509 + + ------------------------- + + Header ID's of 0 thru 31 are reserved for use by PKWARE. + The remaining ID's can be used by third party vendors for + proprietary usage. + + The current Header ID mappings defined by PKWARE are: + + 0x0001 ZIP64 extended information extra field + 0x0007 AV Info + 0x0009 OS/2 extended attributes (also Info-ZIP) + 0x000a NTFS (Win9x/WinNT FileTimes) + 0x000c OpenVMS (also Info-ZIP) + 0x000d Unix + 0x000f Patch Descriptor + 0x0014 PKCS#7 Store for X.509 Certificates + 0x0015 X.509 Certificate ID and Signature for + individual file + 0x0016 X.509 Certificate ID for Central Directory + + The Header ID mappings defined by Info-ZIP and third parties are: + + 0x0065 IBM S/390 attributes - uncompressed + 0x0066 IBM S/390 attributes - compressed + 0x07c8 Info-ZIP Macintosh (old, J. Lee) + 0x2605 ZipIt Macintosh (first version) + 0x2705 ZipIt Macintosh v 1.3.5 and newer (w/o full filename) + 0x334d Info-ZIP Macintosh (new, D. Haase's 'Mac3' field ) + 0x4154 Tandem NSK + 0x4341 Acorn/SparkFS (David Pilling) + 0x4453 Windows NT security descriptor (binary ACL) + 0x4704 VM/CMS + 0x470f MVS + 0x4854 Theos, old inofficial port + 0x4b46 FWKCS MD5 (see below) + 0x4c41 OS/2 access control list (text ACL) + 0x4d49 Info-ZIP OpenVMS (obsolete) + 0x4d63 Macintosh SmartZIP, by Macro Bambini + 0x4f4c Xceed original location extra field + 0x5356 AOS/VS (binary ACL) + 0x5455 extended timestamp + 0x5855 Info-ZIP Unix (original; also OS/2, NT, etc.) + 0x554e Xceed unicode extra field + 0x6375 Info-ZIP Unicode Comment + 0x6542 BeOS (BeBox, PowerMac, etc.) + 0x6854 Theos + 0x7075 Info-ZIP Unicode Path + 0x756e ASi Unix + 0x7855 Info-ZIP Unix (previous new) + 0x7875 Info-ZIP Unix (new) + 0xfb4a SMS/QDOS + +The following are detailed descriptions of the known extra-field block types: + + -OS/2 Extended Attributes Extra Field: + ==================================== + + The following is the layout of the OS/2 extended attributes "extra" + block. (Last Revision 19960922) + + Note: all fields stored in Intel low-byte/high-byte order. + + Local-header version: + + Value Size Description + ----- ---- ----------- + (OS/2) 0x0009 Short tag for this extra block type + TSize Short total data size for this block + BSize Long uncompressed EA data size + CType Short compression type + EACRC Long CRC value for uncompressed EA data + (var.) variable compressed EA data + + Central-header version: + + Value Size Description + ----- ---- ----------- + (OS/2) 0x0009 Short tag for this extra block type + TSize Short total data size for this block (4) + BSize Long size of uncompressed local EA data + + The value of CType is interpreted according to the "compression + method" section above; i.e., 0 for stored, 8 for deflated, etc. + + The OS/2 extended attribute structure (FEA2LIST) is compressed and + then stored in its entirety within this structure. There will only + ever be one block of data in the variable-length field. + + + -OS/2 Access Control List Extra Field: + ==================================== + + The following is the layout of the OS/2 ACL extra block. + (Last Revision 19960922) + + Local-header version: + + Value Size Description + ----- ---- ----------- + (ACL) 0x4c41 Short tag for this extra block type ("AL") + TSize Short total data size for this block + BSize Long uncompressed ACL data size + CType Short compression type + EACRC Long CRC value for uncompressed ACL data + (var.) variable compressed ACL data + + Central-header version: + + Value Size Description + ----- ---- ----------- + (ACL) 0x4c41 Short tag for this extra block type ("AL") + TSize Short total data size for this block (4) + BSize Long size of uncompressed local ACL data + + The value of CType is interpreted according to the "compression + method" section above; i.e., 0 for stored, 8 for deflated, etc. + + The uncompressed ACL data consist of a text header of the form + "ACL1:%hX,%hd\n", where the first field is the OS/2 ACCINFO acc_attr + member and the second is acc_count, followed by acc_count strings + of the form "%s,%hx\n", where the first field is acl_ugname (user + group name) and the second acl_access. This block type will be + extended for other operating systems as needed. + + + -Windows NT Security Descriptor Extra Field: + ========================================== + + The following is the layout of the NT Security Descriptor (another + type of ACL) extra block. (Last Revision 19960922) + + Local-header version: + + Value Size Description + ----- ---- ----------- + (SD) 0x4453 Short tag for this extra block type ("SD") + TSize Short total data size for this block + BSize Long uncompressed SD data size + Version Byte version of uncompressed SD data format + CType Short compression type + EACRC Long CRC value for uncompressed SD data + (var.) variable compressed SD data + + Central-header version: + + Value Size Description + ----- ---- ----------- + (SD) 0x4453 Short tag for this extra block type ("SD") + TSize Short total data size for this block (4) + BSize Long size of uncompressed local SD data + + The value of CType is interpreted according to the "compression + method" section above; i.e., 0 for stored, 8 for deflated, etc. + Version specifies how the compressed data are to be interpreted + and allows for future expansion of this extra field type. Currently + only version 0 is defined. + + For version 0, the compressed data are to be interpreted as a single + valid Windows NT SECURITY_DESCRIPTOR data structure, in self-relative + format. + + + -PKWARE Win95/WinNT Extra Field: + ============================== + + The following description covers PKWARE's "NTFS" attributes + "extra" block, introduced with the release of PKZIP 2.50 for + Windows. (Last Revision 20001118) + + (Note: At this time the Mtime, Atime and Ctime values may + be used on any WIN32 system.) + [Info-ZIP note: In the current implementations, this field has + a fixed total data size of 32 bytes and is only stored as local + extra field.] + + Value Size Description + ----- ---- ----------- + (NTFS) 0x000a Short Tag for this "extra" block type + TSize Short Total Data Size for this block + Reserved Long for future use + Tag1 Short NTFS attribute tag value #1 + Size1 Short Size of attribute #1, in bytes + (var.) SubSize1 Attribute #1 data + . + . + . + TagN Short NTFS attribute tag value #N + SizeN Short Size of attribute #N, in bytes + (var.) SubSize1 Attribute #N data + + For NTFS, values for Tag1 through TagN are as follows: + (currently only one set of attributes is defined for NTFS) + + Tag Size Description + ----- ---- ----------- + 0x0001 2 bytes Tag for attribute #1 + Size1 2 bytes Size of attribute #1, in bytes (24) + Mtime 8 bytes 64-bit NTFS file last modification time + Atime 8 bytes 64-bit NTFS file last access time + Ctime 8 bytes 64-bit NTFS file creation time + + The total length for this block is 28 bytes, resulting in a + fixed size value of 32 for the TSize field of the NTFS block. + + The NTFS filetimes are 64-bit unsigned integers, stored in Intel + (least significant byte first) byte order. They determine the + number of 1.0E-07 seconds (1/10th microseconds!) past WinNT "epoch", + which is "01-Jan-1601 00:00:00 UTC". + + + -PKWARE OpenVMS Extra Field: + ========================== + + The following is the layout of PKWARE's OpenVMS attributes "extra" + block. (Last Revision 12/17/91) + + Note: all fields stored in Intel low-byte/high-byte order. + + Value Size Description + ----- ---- ----------- + (VMS) 0x000c Short Tag for this "extra" block type + TSize Short Total Data Size for this block + CRC Long 32-bit CRC for remainder of the block + Tag1 Short OpenVMS attribute tag value #1 + Size1 Short Size of attribute #1, in bytes + (var.) Size1 Attribute #1 data + . + . + . + TagN Short OpenVMS attribute tage value #N + SizeN Short Size of attribute #N, in bytes + (var.) SizeN Attribute #N data + + Rules: + + 1. There will be one or more of attributes present, which + will each be preceded by the above TagX & SizeX values. + These values are identical to the ATR$C_XXXX and + ATR$S_XXXX constants which are defined in ATR.H under + OpenVMS C. Neither of these values will ever be zero. + + 2. No word alignment or padding is performed. + + 3. A well-behaved PKZIP/OpenVMS program should never produce + more than one sub-block with the same TagX value. Also, + there will never be more than one "extra" block of type + 0x000c in a particular directory record. + + + -Info-ZIP VMS Extra Field: + ======================== + + The following is the layout of Info-ZIP's VMS attributes extra + block for VAX or Alpha AXP. The local-header and central-header + versions are identical. (Last Revision 19960922) + + Value Size Description + ----- ---- ----------- + (VMS2) 0x4d49 Short tag for this extra block type ("JM") + TSize Short total data size for this block + ID Long block ID + Flags Short info bytes + BSize Short uncompressed block size + Reserved Long (reserved) + (var.) variable compressed VMS file-attributes block + + The block ID is one of the following unterminated strings: + + "VFAB" struct FAB + "VALL" struct XABALL + "VFHC" struct XABFHC + "VDAT" struct XABDAT + "VRDT" struct XABRDT + "VPRO" struct XABPRO + "VKEY" struct XABKEY + "VMSV" version (e.g., "V6.1"; truncated at hyphen) + "VNAM" reserved + + The lower three bits of Flags indicate the compression method. The + currently defined methods are: + + 0 stored (not compressed) + 1 simple "RLE" + 2 deflated + + The "RLE" method simply replaces zero-valued bytes with zero-valued + bits and non-zero-valued bytes with a "1" bit followed by the byte + value. + + The variable-length compressed data contains only the data corre- + sponding to the indicated structure or string. Typically multiple + VMS2 extra fields are present (each with a unique block type). + + + -Info-ZIP Macintosh Extra Field: + ============================== + + The following is the layout of the (old) Info-ZIP resource-fork extra + block for Macintosh. The local-header and central-header versions + are identical. (Last Revision 19960922) + + Value Size Description + ----- ---- ----------- + (Mac) 0x07c8 Short tag for this extra block type + TSize Short total data size for this block + "JLEE" beLong extra-field signature + FInfo 16 bytes Macintosh FInfo structure + CrDat beLong HParamBlockRec fileParam.ioFlCrDat + MdDat beLong HParamBlockRec fileParam.ioFlMdDat + Flags beLong info bits + DirID beLong HParamBlockRec fileParam.ioDirID + VolName 28 bytes volume name (optional) + + All fields but the first two are in native Macintosh format + (big-endian Motorola order, not little-endian Intel). The least + significant bit of Flags is 1 if the file is a data fork, 0 other- + wise. In addition, if this extra field is present, the filename + has an extra 'd' or 'r' appended to indicate data fork or resource + fork. The 28-byte VolName field may be omitted. + + + -ZipIt Macintosh Extra Field (long): + ================================== + + The following is the layout of the ZipIt extra block for Macintosh. + The local-header and central-header versions are identical. + (Last Revision 19970130) + + Value Size Description + ----- ---- ----------- + (Mac2) 0x2605 Short tag for this extra block type + TSize Short total data size for this block + "ZPIT" beLong extra-field signature + FnLen Byte length of FileName + FileName variable full Macintosh filename + FileType Byte[4] four-byte Mac file type string + Creator Byte[4] four-byte Mac creator string + + + -ZipIt Macintosh Extra Field (short): + =================================== + + The following is the layout of a shortened variant of the + ZipIt extra block for Macintosh (without "full name" entry). + This variant is used by ZipIt 1.3.5 and newer for entries that + do not need a "full Mac filename" record. + The local-header and central-header versions are identical. + (Last Revision 19980903) + + Value Size Description + ----- ---- ----------- + (Mac2b) 0x2705 Short tag for this extra block type + TSize Short total data size for this block (12) + "ZPIT" beLong extra-field signature + FileType Byte[4] four-byte Mac file type string + Creator Byte[4] four-byte Mac creator string + + + -Info-ZIP Macintosh Extra Field (new): + ==================================== + + The following is the layout of the (new) Info-ZIP extra + block for Macintosh, designed by Dirk Haase. + All values are in little-endian. + (Last Revision 19981005) + + Local-header version: + + Value Size Description + ----- ---- ----------- + (Mac3) 0x334d Short tag for this extra block type ("M3") + TSize Short total data size for this block + BSize Long uncompressed finder attribute data size + Flags Short info bits + fdType Byte[4] Type of the File (4-byte string) + fdCreator Byte[4] Creator of the File (4-byte string) + (CType) Short compression type + (CRC) Long CRC value for uncompressed MacOS data + Attribs variable finder attribute data (see below) + + + Central-header version: + + Value Size Description + ----- ---- ----------- + (Mac3) 0x334d Short tag for this extra block type ("M3") + TSize Short total data size for this block + BSize Long uncompressed finder attribute data size + Flags Short info bits + fdType Byte[4] Type of the File (4-byte string) + fdCreator Byte[4] Creator of the File (4-byte string) + + The third bit of Flags in both headers indicates whether + the LOCAL extra field is uncompressed (and therefore whether CType + and CRC are omitted): + + Bits of the Flags: + bit 0 if set, file is a data fork; otherwise unset + bit 1 if set, filename will be not changed + bit 2 if set, Attribs is uncompressed (no CType, CRC) + bit 3 if set, date and times are in 64 bit + if zero date and times are in 32 bit. + bit 4 if set, timezone offsets fields for the native + Mac times are omitted (UTC support deactivated) + bits 5-15 reserved; + + + Attributes: + + Attribs is a Mac-specific block of data in little-endian format with + the following structure (if compressed, uncompress it first): + + Value Size Description + ----- ---- ----------- + fdFlags Short Finder Flags + fdLocation.v Short Finder Icon Location + fdLocation.h Short Finder Icon Location + fdFldr Short Folder containing file + + FXInfo 16 bytes Macintosh FXInfo structure + FXInfo-Structure: + fdIconID Short + fdUnused[3] Short unused but reserved 6 bytes + fdScript Byte Script flag and number + fdXFlags Byte More flag bits + fdComment Short Comment ID + fdPutAway Long Home Dir ID + + FVersNum Byte file version number + may be not used by MacOS + ACUser Byte directory access rights + + FlCrDat ULong date and time of creation + FlMdDat ULong date and time of last modification + FlBkDat ULong date and time of last backup + These time numbers are original Mac FileTime values (local time!). + Currently, date-time width is 32-bit, but future version may + support be 64-bit times (see flags) + + CrGMTOffs Long(signed!) difference "local Creat. time - UTC" + MdGMTOffs Long(signed!) difference "local Modif. time - UTC" + BkGMTOffs Long(signed!) difference "local Backup time - UTC" + These "local time - UTC" differences (stored in seconds) may be + used to support timestamp adjustment after inter-timezone transfer. + These fields are optional; bit 4 of the flags word controls their + presence. + + Charset Short TextEncodingBase (Charset) + valid for the following two fields + + FullPath variable Path of the current file. + Zero terminated string (C-String) + Currently coded in the native Charset. + + Comment variable Finder Comment of the current file. + Zero terminated string (C-String) + Currently coded in the native Charset. + + + -SmartZIP Macintosh Extra Field: + ==================================== + + The following is the layout of the SmartZIP extra + block for Macintosh, designed by Marco Bambini. + + Local-header version: + + Value Size Description + ----- ---- ----------- + 0x4d63 Short tag for this extra block type ("cM") + TSize Short total data size for this block (64) + "dZip" beLong extra-field signature + fdType Byte[4] Type of the File (4-byte string) + fdCreator Byte[4] Creator of the File (4-byte string) + fdFlags beShort Finder Flags + fdLocation.v beShort Finder Icon Location + fdLocation.h beShort Finder Icon Location + fdFldr beShort Folder containing file + CrDat beLong HParamBlockRec fileParam.ioFlCrDat + MdDat beLong HParamBlockRec fileParam.ioFlMdDat + frScroll.v Byte vertical pos. of folder's scroll bar + fdScript Byte Script flag and number + frScroll.h Byte horizontal pos. of folder's scroll bar + fdXFlags Byte More flag bits + FileName Byte[32] full Macintosh filename (pascal string) + + All fields but the first two are in native Macintosh format + (big-endian Motorola order, not little-endian Intel). + The extra field size is fixed to 64 bytes. + The local-header and central-header versions are identical. + + + -Acorn SparkFS Extra Field: + ========================= + + The following is the layout of David Pilling's SparkFS extra block + for Acorn RISC OS. The local-header and central-header versions are + identical. (Last Revision 19960922) + + Value Size Description + ----- ---- ----------- + (Acorn) 0x4341 Short tag for this extra block type ("AC") + TSize Short total data size for this block (20) + "ARC0" Long extra-field signature + LoadAddr Long load address or file type + ExecAddr Long exec address + Attr Long file permissions + Zero Long reserved; always zero + + The following bits of Attr are associated with the given file + permissions: + + bit 0 user-writable ('W') + bit 1 user-readable ('R') + bit 2 reserved + bit 3 locked ('L') + bit 4 publicly writable ('w') + bit 5 publicly readable ('r') + bit 6 reserved + bit 7 reserved + + + -VM/CMS Extra Field: + ================== + + The following is the layout of the file-attributes extra block for + VM/CMS. The local-header and central-header versions are + identical. (Last Revision 19960922) + + Value Size Description + ----- ---- ----------- + (VM/CMS) 0x4704 Short tag for this extra block type + TSize Short total data size for this block + flData variable file attributes data + + flData is an uncompressed fldata_t struct. + + + -MVS Extra Field: + =============== + + The following is the layout of the file-attributes extra block for + MVS. The local-header and central-header versions are identical. + (Last Revision 19960922) + + Value Size Description + ----- ---- ----------- + (MVS) 0x470f Short tag for this extra block type + TSize Short total data size for this block + flData variable file attributes data + + flData is an uncompressed fldata_t struct. + + + -PKWARE Unix Extra Field: + ======================== + + The following is the layout of PKWARE's Unix "extra" block. + It was introduced with the release of PKZIP for Unix 2.50. + Note: all fields are stored in Intel low-byte/high-byte order. + (Last Revision 19980901) + + This field has a minimum data size of 12 bytes and is only stored + as local extra field. + + Value Size Description + ----- ---- ----------- + (Unix0) 0x000d Short Tag for this "extra" block type + TSize Short Total Data Size for this block + AcTime Long time of last access (UTC/GMT) + ModTime Long time of last modification (UTC/GMT) + UID Short Unix user ID + GID Short Unix group ID + (var) variable Variable length data field + + The variable length data field will contain file type + specific data. Currently the only values allowed are + the original "linked to" file names for hard or symbolic + links, and the major and minor device node numbers for + character and block device nodes. Since device nodes + cannot be either symbolic or hard links, only one set of + variable length data is stored. Link files will have the + name of the original file stored. This name is NOT NULL + terminated. Its size can be determined by checking TSize - + 12. Device entries will have eight bytes stored as two 4 + byte entries (in little-endian format). The first entry + will be the major device number, and the second the minor + device number. + + [Info-ZIP note: The fixed part of this field has the same layout as + Info-ZIP's abandoned "Unix1 timestamps & owner ID info" extra field; + only the two tag bytes are different.] + + + -PATCH Descriptor Extra Field: + ============================ + + The following is the layout of the Patch Descriptor "extra" + block. + + Note: all fields stored in Intel low-byte/high-byte order. + + Value Size Description + ----- ---- ----------- + (Patch) 0x000f Short Tag for this "extra" block type + TSize Short Size of the total "extra" block + Version Short Version of the descriptor + Flags Long Actions and reactions (see below) + OldSize Long Size of the file about to be patched + OldCRC Long 32-bit CRC of the file about to be patched + NewSize Long Size of the resulting file + NewCRC Long 32-bit CRC of the resulting file + + + Actions and reactions + + Bits Description + ---- ---------------- + 0 Use for autodetection + 1 Treat as selfpatch + 2-3 RESERVED + 4-5 Action (see below) + 6-7 RESERVED + 8-9 Reaction (see below) to absent file + 10-11 Reaction (see below) to newer file + 12-13 Reaction (see below) to unknown file + 14-15 RESERVED + 16-31 RESERVED + + Actions + + Action Value + ------ ----- + none 0 + add 1 + delete 2 + patch 3 + + Reactions + + Reaction Value + -------- ----- + ask 0 + skip 1 + ignore 2 + fail 3 + + + -PKCS#7 Store for X.509 Certificates: + =================================== + + This field is contains the information about each + certificate a file is signed with. This field should only + appear in the first central directory record, and will be + ignored in any other record. + + Note: all fields stored in Intel low-byte/high-byte order. + + Value Size Description + ----- ---- ----------- + (Store) 0x0014 2 bytes Tag for this "extra" block type + SSize 2 bytes Size of the store data + SData (variable) Data about the store + + SData + Value Size Description + ----- ---- ----------- + Version 2 bytes Version number, 0x0001 for now + StoreD (variable) Actual store data + + The StoreD member is suitable for passing as the pbData + member of a CRYPT_DATA_BLOB to the CertOpenStore() function + in Microsoft's CryptoAPI. The SSize member above will be + cbData + 6, where cbData is the cbData member of the same + CRYPT_DATA_BLOB. The encoding type to pass to + CertOpenStore() should be + PKCS_7_ANS_ENCODING | X509_ASN_ENCODING. + + + -X.509 Certificate ID and Signature for individual file: + ====================================================== + + This field contains the information about which certificate + in the PKCS#7 Store was used to sign the particular file. + It also contains the signature data. This field can appear + multiple times, but can only appear once per certificate. + + Note: all fields stored in Intel low-byte/high-byte order. + + Value Size Description + ----- ---- ----------- + (CID) 0x0015 2 bytes Tag for this "extra" block type + CSize 2 bytes Size of Method + Method (variable) + + Method + Value Size Description + ----- ---- ----------- + Version 2 bytes Version number, for now 0x0001 + AlgID 2 bytes Algorithm ID used for signing + IDSize 2 bytes Size of Certificate ID data + CertID (variable) Certificate ID data + SigSize 2 bytes Size of Signature data + Sig (variable) Signature data + + CertID + Value Size Description + ----- ---- ----------- + Size1 4 bytes Size of CertID, should be (IDSize - 4) + Size1 4 bytes A bug in version one causes this value + to appear twice. + IssSize 4 bytes Issuer data size + Issuer (variable) Issuer data + SerSize 4 bytes Serial Number size + Serial (variable) Serial Number data + + The Issuer and IssSize members are suitable for creating a + CRYPT_DATA_BLOB to be the Issuer member of a CERT_INFO + struct. The Serial and SerSize members would be the + SerialNumber member of the same CERT_INFO struct. This + struct would be used to find the certificate in the store + the file was signed with. Those structures are from the MS + CryptoAPI. + + Sig and SigSize are the actual signature data and size + generated by signing the file with the MS CryptoAPI using a + hash created with the given AlgID. + + + -X.509 Certificate ID and Signature for central directory: + ======================================================== + + This field contains the information about which certificate + in the PKCS#7 Store was used to sign the central directory. + It should only appear with the first central directory + record, along with the store. The data structure is the + same as the CID, except that SigSize will be 0, and there + will be no Sig member. + + This field is also kept after the last central directory + record, as the signature data (ID 0x05054b50, it looks like + a central directory record of a different type). This + second copy of the data is the Signature Data member of the + record, and will have a SigSize that is non-zero, and will + have Sig data. + + Note: all fields stored in Intel low-byte/high-byte order. + + Value Size Description + ----- ---- ----------- + (CDID) 0x0016 2 bytes Tag for this "extra" block type + CSize 2 bytes Size of Method + Method (variable) + + + -ZIP64 Extended Information Extra Field: + ====================================== + + The following is the layout of the ZIP64 extended + information "extra" block. If one of the size or + offset fields in the Local or Central directory + record is too small to hold the required data, + a ZIP64 extended information record is created. + The order of the fields in the ZIP64 extended + information record is fixed, but the fields will + only appear if the corresponding Local or Central + directory record field is set to 0xFFFF or 0xFFFFFFFF. + + Note: all fields stored in Intel low-byte/high-byte order. + + Value Size Description + ----- ---- ----------- + (ZIP64) 0x0001 2 bytes Tag for this "extra" block type + Size 2 bytes Size of this "extra" block + Original + Size 8 bytes Original uncompresseed file size + Compressed + Size 8 bytes Size of compressed data + Relative Header + Offset 8 bytes Offset of local header record + Disk Start + Number 4 bytes Number of the disk on which + this file starts + + This entry in the Local header must include BOTH original + and compressed file sizes. + + + -Extended Timestamp Extra Field: + ============================== + + The following is the layout of the extended-timestamp extra block. + (Last Revision 19970118) + + Local-header version: + + Value Size Description + ----- ---- ----------- + (time) 0x5455 Short tag for this extra block type ("UT") + TSize Short total data size for this block + Flags Byte info bits + (ModTime) Long time of last modification (UTC/GMT) + (AcTime) Long time of last access (UTC/GMT) + (CrTime) Long time of original creation (UTC/GMT) + + Central-header version: + + Value Size Description + ----- ---- ----------- + (time) 0x5455 Short tag for this extra block type ("UT") + TSize Short total data size for this block + Flags Byte info bits (refers to local header!) + (ModTime) Long time of last modification (UTC/GMT) + + The central-header extra field contains the modification time only, + or no timestamp at all. TSize is used to flag its presence or + absence. But note: + + If "Flags" indicates that Modtime is present in the local header + field, it MUST be present in the central header field, too! + This correspondence is required because the modification time + value may be used to support trans-timezone freshening and + updating operations with zip archives. + + The time values are in standard Unix signed-long format, indicating + the number of seconds since 1 January 1970 00:00:00. The times + are relative to Coordinated Universal Time (UTC), also sometimes + referred to as Greenwich Mean Time (GMT). To convert to local time, + the software must know the local timezone offset from UTC/GMT. + + The lower three bits of Flags in both headers indicate which time- + stamps are present in the LOCAL extra field: + + bit 0 if set, modification time is present + bit 1 if set, access time is present + bit 2 if set, creation time is present + bits 3-7 reserved for additional timestamps; not set + + Those times that are present will appear in the order indicated, but + any combination of times may be omitted. (Creation time may be + present without access time, for example.) TSize should equal + (1 + 4*(number of set bits in Flags)), as the block is currently + defined. Other timestamps may be added in the future. + + + -Info-ZIP Unix Extra Field (type 1): + ================================== + + The following is the layout of the old Info-ZIP extra block for + Unix. It has been replaced by the extended-timestamp extra block + (0x5455) and the Unix type 2 extra block (0x7855). + (Last Revision 19970118) + + Local-header version: + + Value Size Description + ----- ---- ----------- + (Unix1) 0x5855 Short tag for this extra block type ("UX") + TSize Short total data size for this block + AcTime Long time of last access (UTC/GMT) + ModTime Long time of last modification (UTC/GMT) + UID Short Unix user ID (optional) + GID Short Unix group ID (optional) + + Central-header version: + + Value Size Description + ----- ---- ----------- + (Unix1) 0x5855 Short tag for this extra block type ("UX") + TSize Short total data size for this block + AcTime Long time of last access (GMT/UTC) + ModTime Long time of last modification (GMT/UTC) + + The file access and modification times are in standard Unix signed- + long format, indicating the number of seconds since 1 January 1970 + 00:00:00. The times are relative to Coordinated Universal Time + (UTC), also sometimes referred to as Greenwich Mean Time (GMT). To + convert to local time, the software must know the local timezone + offset from UTC/GMT. The modification time may be used by non-Unix + systems to support inter-timezone freshening and updating of zip + archives. + + The local-header extra block may optionally contain UID and GID + info for the file. The local-header TSize value is the only + indication of this. Note that Unix UIDs and GIDs are usually + specific to a particular machine, and they generally require root + access to restore. + + This extra field type is obsolete, but it has been in use since + mid-1994. Therefore future archiving software should continue to + support it. Some guidelines: + + An archive member should either contain the old "Unix1" + extra field block or the new extra field types "time" and/or + "Unix2". + + If both the old "Unix1" block type and one or both of the new + block types "time" and "Unix2" are found, the "Unix1" block + should be considered invalid and ignored. + + Unarchiving software should recognize both old and new extra + field block types, but the info from new types overrides the + old "Unix1" field. + + Archiving software should recognize "Unix1" extra fields for + timestamp comparison but never create it for updated, freshened + or new archive members. When copying existing members to a new + archive, any "Unix1" extra field blocks should be converted to + the new "time" and/or "Unix2" types. + + + -Info-ZIP Unix Extra Field (type 2): + ================================== + + The following is the layout of the new Info-ZIP extra block for + Unix. (Last Revision 19960922) + + Local-header version: + + Value Size Description + ----- ---- ----------- + (Unix2) 0x7855 Short tag for this extra block type ("Ux") + TSize Short total data size for this block (4) + UID Short Unix user ID + GID Short Unix group ID + + Central-header version: + + Value Size Description + ----- ---- ----------- + (Unix2) 0x7855 Short tag for this extra block type ("Ux") + TSize Short total data size for this block (0) + + The data size of the central-header version is zero; it is used + solely as a flag that UID/GID info is present in the local-header + extra field. If additional fields are ever added to the local + version, the central version may be extended to indicate this. + + Note that Unix UIDs and GIDs are usually specific to a particular + machine, and they generally require root access to restore. + + + -ASi Unix Extra Field: + ==================== + + The following is the layout of the ASi extra block for Unix. The + local-header and central-header versions are identical. + (Last Revision 19960916) + + Value Size Description + ----- ---- ----------- + (Unix3) 0x756e Short tag for this extra block type ("nu") + TSize Short total data size for this block + CRC Long CRC-32 of the remaining data + Mode Short file permissions + SizDev Long symlink'd size OR major/minor dev num + UID Short user ID + GID Short group ID + (var.) variable symbolic link filename + + Mode is the standard Unix st_mode field from struct stat, containing + user/group/other permissions, setuid/setgid and symlink info, etc. + + If Mode indicates that this file is a symbolic link, SizDev is the + size of the file to which the link points. Otherwise, if the file + is a device, SizDev contains the standard Unix st_rdev field from + struct stat (includes the major and minor numbers of the device). + SizDev is undefined in other cases. + + If Mode indicates that the file is a symbolic link, the final field + will be the name of the file to which the link points. The file- + name length can be inferred from TSize. + + [Note that TSize may incorrectly refer to the data size not counting + the CRC; i.e., it may be four bytes too small.] + + + -BeOS Extra Field: + ================ + + The following is the layout of the file-attributes extra block for + BeOS. (Last Revision 19970531) + + Local-header version: + + Value Size Description + ----- ---- ----------- + (BeOS) 0x6542 Short tag for this extra block type ("Be") + TSize Short total data size for this block + BSize Long uncompressed file attribute data size + Flags Byte info bits + (CType) Short compression type + (CRC) Long CRC value for uncompressed file attribs + Attribs variable file attribute data + + Central-header version: + + Value Size Description + ----- ---- ----------- + (BeOS) 0x6542 Short tag for this extra block type ("Be") + TSize Short total data size for this block (5) + BSize Long size of uncompr. local EF block data + Flags Byte info bits + + The least significant bit of Flags in both headers indicates whether + the LOCAL extra field is uncompressed (and therefore whether CType + and CRC are omitted): + + bit 0 if set, Attribs is uncompressed (no CType, CRC) + bits 1-7 reserved; if set, assume error or unknown data + + Currently the only supported compression types are deflated (type 8) + and stored (type 0); the latter is not used by Info-ZIP's Zip but is + supported by UnZip. + + Attribs is a BeOS-specific block of data in big-endian format with + the following structure (if compressed, uncompress it first): + + Value Size Description + ----- ---- ----------- + Name variable attribute name (null-terminated string) + Type Long attribute type (32-bit unsigned integer) + Size Long Long data size for this sub-block (64 bits) + Data variable attribute data + + The attribute structure is repeated for every attribute. The Data + field may contain anything--text, flags, bitmaps, etc. + + + -SMS/QDOS Extra Field: + ==================== + + The following is the layout of the file-attributes extra block for + SMS/QDOS. The local-header and central-header versions are identical. + (Last Revision 19960929) + + Value Size Description + ----- ---- ----------- + (QDOS) 0xfb4a Short tag for this extra block type + TSize Short total data size for this block + LongID Long extra-field signature + (ExtraID) Long additional signature/flag bytes + QDirect 64 bytes qdirect structure + + LongID may be "QZHD" or "QDOS". In the latter case, ExtraID will + be present. Its first three bytes are "02\0"; the last byte is + currently undefined. + + QDirect contains the file's uncompressed directory info (qdirect + struct). Its elements are in native (big-endian) format: + + d_length beLong file length + d_access byte file access type + d_type byte file type + d_datalen beLong data length + d_reserved beLong unused + d_szname beShort size of filename + d_name 36 bytes filename + d_update beLong time of last update + d_refdate beLong file version number + d_backup beLong time of last backup (archive date) + + + -AOS/VS Extra Field: + ================== + + The following is the layout of the extra block for Data General + AOS/VS. The local-header and central-header versions are identical. + (Last Revision 19961125) + + Value Size Description + ----- ---- ----------- + (AOSVS) 0x5356 Short tag for this extra block type ("VS") + TSize Short total data size for this block + "FCI\0" Long extra-field signature + Version Byte version of AOS/VS extra block (10 = 1.0) + Fstat variable fstat packet + AclBuf variable raw ACL data ($MXACL bytes) + + Fstat contains the file's uncompressed fstat packet, which is one of + the following: + + normal fstat packet (P_FSTAT struct) + DIR/CPD fstat packet (P_FSTAT_DIR struct) + unit (device) fstat packet (P_FSTAT_UNIT struct) + IPC file fstat packet (P_FSTAT_IPC struct) + + AclBuf contains the raw ACL data; its length is $MXACL. + + + -Tandem NSK Extra Field: + ====================== + + The following is the layout of the file-attributes extra block for + Tandem NSK. The local-header and central-header versions are + identical. (Last Revision 19981221) + + Value Size Description + ----- ---- ----------- + (TA) 0x4154 Short tag for this extra block type ("TA") + TSize Short total data size for this block (20) + NSKattrs 20 Bytes NSK attributes + + + -THEOS Extra Field: + ================= + + The following is the layout of the file-attributes extra block for + Theos. The local-header and central-header versions are identical. + (Last Revision 19990206) + + Value Size Description + ----- ---- ----------- + (Theos) 0x6854 Short 'Th' signature + size Short size of extra block + flags Byte reserved for future use + filesize Long file size + fileorg Byte type of file (see below) + keylen Short key length for indexed and keyed files, + data segment size for 16 bits programs + reclen Short record length for indexed,keyed and direct, + text segment size for 16 bits programs + filegrow Byte growing factor for indexed,keyed and direct + protect Byte protections (see below) + reserved Short reserved for future use + + File types + ========== + + 0x80 library (keyed access list of files) + 0x40 directory + 0x10 stream file + 0x08 direct file + 0x04 keyed file + 0x02 indexed file + 0x0e reserved + 0x01 16 bits real mode program (obsolete) + 0x21 16 bits protected mode program + 0x41 32 bits protected mode program + + Protection codes + ================ + + User protection + --------------- + 0x01 non readable + 0x02 non writable + 0x04 non executable + 0x08 non erasable + + Other protection + ---------------- + 0x10 non readable + 0x20 non writable + 0x40 non executable Theos before 4.0 + 0x40 modified Theos 4.x + 0x80 not hidden + + + -THEOS old inofficial Extra Field: + ================================ + + The following is the layout of an inoffical former version of a + Theos file-attributes extra blocks. This layout was never published + and is no longer created. However, UnZip can optionally support it + when compiling with the option flag OLD_THEOS_EXTRA defined. + Both the local-header and central-header versions are identical. + (Last Revision 19990206) + + Value Size Description + ----- ---- ----------- + (THS0) 0x4854 Short 'TH' signature + size Short size of extra block + flags Short reserved for future use + filesize Long file size + reclen Short record length for indexed,keyed and direct, + text segment size for 16 bits programs + keylen Short key length for indexed and keyed files, + data segment size for 16 bits programs + filegrow Byte growing factor for indexed,keyed and direct + reserved 3 Bytes reserved for future use + + + -FWKCS MD5 Extra Field: + ===================== + + The FWKCS Contents_Signature System, used in automatically + identifying files independent of filename, optionally adds + and uses an extra field to support the rapid creation of + an enhanced contents_signature. + There is no local-header version; the following applies + only to the central header. (Last Revision 19961207) + + Central-header version: + + Value Size Description + ----- ---- ----------- + (MD5) 0x4b46 Short tag for this extra block type ("FK") + TSize Short total data size for this block (19) + "MD5" 3 bytes extra-field signature + MD5hash 16 bytes 128-bit MD5 hash of uncompressed data + (low byte first) + + When FWKCS revises a .ZIP file central directory to add + this extra field for a file, it also replaces the + central directory entry for that file's uncompressed + file length with a measured value. + + FWKCS provides an option to strip this extra field, if + present, from a .ZIP file central directory. In adding + this extra field, FWKCS preserves .ZIP file Authenticity + Verification; if stripping this extra field, FWKCS + preserves all versions of AV through PKZIP version 2.04g. + + FWKCS, and FWKCS Contents_Signature System, are + trademarks of Frederick W. Kantor. + + (1) R. Rivest, RFC1321.TXT, MIT Laboratory for Computer + Science and RSA Data Security, Inc., April 1992. + ll.76-77: "The MD5 algorithm is being placed in the + public domain for review and possible adoption as a + standard." + + + -Info-ZIP Unicode Path Extra Field: + ================================= + + Stores the UTF-8 version of the entry path as stored in the + local header and central directory header. + (Last Revision 20070912) + + Value Size Description + ----- ---- ----------- + (UPath) 0x7075 Short tag for this extra block type ("up") + TSize Short total data size for this block + Version 1 byte version of this extra field, currently 1 + NameCRC32 4 bytes File Name Field CRC32 Checksum + UnicodeName Variable UTF-8 version of the entry File Name + + Currently Version is set to the number 1. If there is a need + to change this field, the version will be incremented. Changes + may not be backward compatible so this extra field should not be + used if the version is not recognized. + + The NameCRC32 is the standard zip CRC32 checksum of the File Name + field in the header. This is used to verify that the header + File Name field has not changed since the Unicode Path extra field + was created. This can happen if a utility renames the entry but + does not update the UTF-8 path extra field. If the CRC check fails, + this UTF-8 Path Extra Field should be ignored and the File Name field + in the header used instead. + + The UnicodeName is the UTF-8 version of the contents of the File Name + field in the header. As UnicodeName is defined to be UTF-8, no UTF-8 + byte order mark (BOM) is used. The length of this field is determined + by subtracting the size of the previous fields from TSize. If both + the File Name and Comment fields are UTF-8, the new General Purpose + Bit Flag, bit 11 (Language encoding flag (EFS)), can be used to + indicate that both the header File Name and Comment fields are UTF-8 + and, in this case, the Unicode Path and Unicode Comment extra fields + are not needed and should not be created. Note that, for backward + compatibility, bit 11 should only be used if the native character set + of the paths and comments being zipped up are already in UTF-8. The + same method, either bit 11 or extra fields, should be used in both + the local and central directory headers. + + + -Info-ZIP Unicode Comment Extra Field: + ==================================== + + Stores the UTF-8 version of the entry comment as stored in the + central directory header. + (Last Revision 20070912) + + Value Size Description + ----- ---- ----------- + (UCom) 0x6375 Short tag for this extra block type ("uc") + TSize Short total data size for this block + Version 1 byte version of this extra field, currently 1 + ComCRC32 4 bytes Comment Field CRC32 Checksum + UnicodeCom Variable UTF-8 version of the entry comment + + Currently Version is set to the number 1. If there is a need + to change this field, the version will be incremented. Changes + may not be backward compatible so this extra field should not be + used if the version is not recognized. + + The ComCRC32 is the standard zip CRC32 checksum of the Comment + field in the central directory header. This is used to verify that + the comment field has not changed since the Unicode Comment extra field + was created. This can happen if a utility changes the Comment field + but does not update the UTF-8 Comment extra field. If the CRC check + fails, this Unicode Comment extra field should be ignored and the + Comment field in the header used. + + The UnicodeCom field is the UTF-8 version of the entry comment field + in the header. As UnicodeCom is defined to be UTF-8, no UTF-8 byte + order mark (BOM) is used. The length of this field is determined by + subtracting the size of the previous fields from TSize. If both the + File Name and Comment fields are UTF-8, the new General Purpose Bit + Flag, bit 11 (Language encoding flag (EFS)), can be used to indicate + both the header File Name and Comment fields are UTF-8 and, in this + case, the Unicode Path and Unicode Comment extra fields are not + needed and should not be created. Note that, for backward + compatibility, bit 11 should only be used if the native character set + of the paths and comments being zipped up are already in UTF-8. The + same method, either bit 11 or extra fields, should be used in both + the local and central directory headers. + + + -Info-ZIP New Unix Extra Field: + ==================================== + + Currently stores Unix UIDs/GIDs up to 32 bits. + (Last Revision 20080509) + + Value Size Description + ----- ---- ----------- + (UnixN) 0x7875 Short tag for this extra block type ("ux") + TSize Short total data size for this block + Version 1 byte version of this extra field, currently 1 + UIDSize 1 byte Size of UID field + UID Variable UID for this entry + GIDSize 1 byte Size of GID field + GID Variable GID for this entry + + Currently Version is set to the number 1. If there is a need + to change this field, the version will be incremented. Changes + may not be backward compatible so this extra field should not be + used if the version is not recognized. + + UIDSize is the size of the UID field in bytes. This size should + match the size of the UID field on the target OS. + + UID is the UID for this entry in standard little endian format. + + GIDSize is the size of the GID field in bytes. This size should + match the size of the GID field on the target OS. + + GID is the GID for this entry in standard little endian format. + + If both the old 16-bit Unix extra field (tag 0x7855, Info-ZIP Unix) + and this extra field are present, the values in this extra field + supercede the values in that extra field. diff --git a/proginfo/fileinfo.cms b/proginfo/fileinfo.cms new file mode 100644 index 0000000..9d21935 --- /dev/null +++ b/proginfo/fileinfo.cms @@ -0,0 +1,231 @@ +[Quoting from a C/370 manual, courtesy of Carl Forde.] + + C/370 supports three types of input and output: text streams, binary + streams, and record I/O. Text and binary streams are both ANSI + standards; record I/O is a C/370 extension. + +[...] + + Record I/O is a C/370 extension to the ANSI standard. For files + opened in record format, C/370 reads and writes one record at a + time. If you try to write more data to a record than the record + can hold, the data is truncated. For record I/O, C/370 only allows + the use of fread() and fwrite() to read and write to the files. Any + other functions (such as fprintf(), fscanf(), getc(), and putc()) + fail. For record-orientated files, records do not change size when + you update them. If the new data has fewer characters than the + original record, the new data fills the first n characters, where + n is the number of characters of the new data. The record will + remain the same size, and the old characters (those after) n are + left unchanged. A subsequent update begins at the next boundary. + For example, if you have the string "abcdefgh": + + abcdefgh + + and you overwrite it with the string "1234", the record will look + like this: + + 1234efgh + + C/370 record I/O is binary. That is, it does not interpret any of + the data in a record file and therefore does not recognize control + characters. + + + The record model consists of: + + * A record, which is the unit of data transmitted to and from a + program + * A block, which is the unit of data transmitted to and from a + device. Each block may contain one or more records. + + In the record model of I/O, records and blocks have the following + attributes: + + RECFM Specifies the format of the data or how the data is organized + on the physical device. + LRECL Specifies the length of logical records (as opposed to + physical ones). + + BLKSIZE Specifies the length of physical records (blocks on the + physical device). + + + Opening a File by Filename + + The filename that you specify on the call to fopen() or freopen() + must be in the following format: + + >> ----filename---- ----filetype-------------------- + | | | | + --.-- -- --filemode-- + | | + --.-- + where + + filename is a 1- to 8-character string of any of the characters, + A-Z, a-z, 0-9, and +, -, $, #, @, :, and _. You can separate it + from the filetype with one or more spaces, or with a period. + [Further note: filenames are fully case-sensitive, as in Unix.] + + filetype is a 1- to 8-character string of any of the characters, + A-Z, a-z, 0-9, and +, -, $, #, @, :, and _. You can separate it + from the filemode with one or more spaces, or with a period. The + separator between filetype and filemode must be the same as the + one between filename and filetype. + + filemode is a 1- to 2-character string. The first must be any of + the characters A-Z, a-z, or *. If you use the asis parameter on + the fopen() or freopen() call, the first character of the filemode + must be a capital letter or an asterisk. Otherwise, the function + call fails. The second character of filemode is optional; if you + specify it, it must be any of the digits 0-6. You cannot specify + the second character if you have specified * for the first one. + + If you do not use periods as separators, there is no limit to how + much whitespace you can have before and after the filename, the + filetype, and filemode. + + + Opening a File without a File Mode Specified + + If you omit the file mode or specify * for it, C/370 does one + of the following when you call fopen() or freopen(): + + * If you have specified a read mode, C/370 looks for the named file + on all the accessed readable disks, in order. If it does not find + the file, the fopen() or freopen() call fails. + * If you have specified any of the write modes, C/370 writes the file + on the first writable disk you have accessed. Specifying a write + mode on an fopen() or freopen() call that contains the filename of + an existing file destroys that file. If you do not have any + writable disks accessed, the call fails. + + + fopen() and freopen() parameters + + recfm + CMS supports only two RECFMs, V and F. [note that MVS supports + 27(!) different RECFMs.] If you do not specify the RECFM for a + file, C/370 determines whether is is in fixed or variable format. + + lrecl and blksize + For files in fixed format, CMS allows records to be read and + written in blocks. To have a fixed format CMS file treated as a + fixed blocked CMS file, you can open the file with recfm=fb and + specify the lrecl and blksize. If you do not specify a recfm on + the open, the blksize can be a multiple of the lrecl, and the + file is treated as if it were blocked. + + For files in variable format, the CMS LRECL is different from the + LRECL for the record model. In the record model, the LRECL is + equal to the data length plus 4 bytes (for the record descriptor + word), and the BLKSIZE is equal to the LRECL plus 4 bytes (for + the block descriptor word). In CMS, BDWs and RDWs do not exist, + but because CMS follows the record model, you must still account + for them. When you specify V, you must still allocate the record + descriptor word and block descriptor word. That is, if you want + a maximum of n bytes per record, you must specify a minimum LRECL + of n+4 and a minimum BLKSIZE of n+8. + + When you are appending to V files, you can enlarge the record size + dynamically, but only if you have not specified LRECL or BLKSIZE + on the fopen() or freopen() command that opened the file. + + type + If you specify this parameter, the only valid value for CMS disk + files is type =record. This opens a file for record I/O. + + asis + If you use this parameter, you can open files with mixed-case + filenames such as JaMeS dAtA or pErCy.FILE. If you specify this + parameter, the file mode that you specify must be a capital letter + (if it is not an asterisk); otherwise; the function call fails and + the value returned is NULL. + + + Reading from Record I/O Files + fread() is the only interface allowed for reading record I/O files. + Each time you call fread() for a record I/O file, fread() reads + one record from the system. If you call fread() with a request for + less than a complete record, the requested bytes are copied to your + buffer, and the file position is set to the start fo the next + record. If the request is for more bytes that are in the record, + one record is read and the position is set to the start of the next + record. C/370 does not strip any blank characters or interpret any + data. + + fread() returns the number of items read successfully, so if you + pass a size argument equal to 1 and a count argument equal to the + maximum expected length of the record, fread() returns the length, + in bytes, of the record read. If you pass a size argument equal + to the maximum expected length of the record, and a count argument + equal to 1, fread() returns either 0 or 1, indicating whether a + record of length size read. If a record is read successfully but + is less than size bytes long, fread() returns 0. + + + Writing to Record I/O Files + fwrite() is the only interface allowed for writing to a file + opened for record I/O. Only one record is written at a time. If + you attempt to write more new data than a full record can hold or + try to update a record with more data than it currently has, C/370 + truncates your output at the record boundary. When C/370 performs + a truncation, it sets errno and raises SIGIOERR, if SIGIOERR is not + set to SIG_IGN. + + When you are writing new records to a fixed-record I/O file, if you + try to write a short record, C/370 pads the record with nulls out + to LRECL. + + At the completion of an fwrite(), the file position is at the start + of the next record. For new data, the block is flushed out to the + system as soon as it is full. + + + fldata() Behavior + When you call the fldata() function for an open CMS minidisk file, + it returns a data structure that looks like this: + + struct __filedata { + unsigned int __recfmF : 1, /* fixed length records */ + __recfmV : 1, /* variable length records */ + __recfmU : 1, /* n/a */ + __recfmS : 1, /* n/a */ + __recfmBlk : 1, /* n/a */ + __recfmASA : 1, /* text mode and ASA */ + __recfmM : 1, /* n/a */ + __dsorgPO : 1, /* n/a */ + __dsorgPDSmem : 1, /* n/a */ + __dsorgPDSdir : 1, /* n/a */ + __dsorgPS : 1, /* sequential data set */ + __dsorgConcat : 1, /* n/a */ + __dsorgMem : 1, /* n/a */ + __dsorgHiper : 1, /* n/a */ + __dsorgTemp : 1, /* created with tmpfile() */ + __dsorgVSAM : 1, /* n/a */ + __reserve1 : 1, /* n/a */ + __openmode : 2, /* see below 1 */ + __modeflag : 4, /* see below 2 */ + __reserve2 : 9, /* n/a */ + + char __device; __DISK + unsigned long __blksize, /* see below 3 */ + __maxreclen; /* see below 4 */ + unsigned short __vsamtype; /* n/a */ + unsigned long __vsamkeylen; /* n/a */ + unsigned long __vsamRKP; /* n/a */ + char * __dsname; /* fname ftype fmode */ + unsigned int __reserve4; /* n/a */ + + /* note 1: values are: __TEXT, __BINARY, __RECORD + note 2: values are: __READ, __WRITE, __APPEND, __UPDATE + these values can be added together to determine + the return value; for example, a file opened with + a+ will have the value __READ + __APPEND. + note 3: total block size of the file, including ASA + characters as well as RDW information + note 4: maximum record length of the data only (includes + ASA characters but excludes RDW information). + */ + }; diff --git a/proginfo/infozip.who b/proginfo/infozip.who new file mode 100644 index 0000000..994851c --- /dev/null +++ b/proginfo/infozip.who @@ -0,0 +1,242 @@ +These members of the Info-ZIP group contributed to the development and +testing of portable Zip. They are responsible for whatever works in +Zip. Whatever doesn't work is solely the fault of the authors of Zip +(Mark Adler, Rich Wales, Jean-loup Gailly, Kai Uwe Rommel, Igor Mandrichenko, +Onno van der Linden, Christian Spieler, John Bush, Paul Kienitz, Sergio Monesi +and Karl Davis, but see the license for the latest list). If you have +contributed and your name has been forgotten, please send a reminder to us +using the contact information in the Readme file. The names are given here +in alphabetical order, because it's impossible to classify them by importance +of the contribution. Some have made a complete port to a new target, some +have provided a one line fix. All are to be thanked. + + +Mark Adler madler@tybalt.caltech.edu NeXT 2.x, Mac + alan@spri.levels.unisa.edu.au Linux +Jeffrey Altman jaltman@watsun.cc.columbia.edu fseek bug on NT +Glenn J. Andrews oper1%drcv06.decnet@drcvax.af.mil VAX VMS +James Van Artsdalen james@raid.dell.com bug report +Eric Backus ericb@lsid.hp.com bug report +Quentin Barnes qbarnes@urbana.css.mot.com unix/Makefile mode of + installed files +Elmar Bartel bartel@informatik.tu-muenchen.de +Mark E. Becker mbecker@cs.uml.edu bug report +Paul von Behren Paul_von_Behren@stortek.com OS/390 port +Jon Bell swy@wsdot.wa.gov Intergraph/CLIX +Myles Bennett - Initial UnZip 6.0 large + files beta +Michael Bernardi mike@childsoc.demon.co.uk RS6000 +Tom Betz marob!upaya!tbetz@phri.nyu.edu SCO Xenix 2.3.1 +James Birdsall jwbirdsa@picarefy.com AT&T 3B1 +George boer@fwi.uva.nl OS/2 +Michael Bolton bolton@vaxc.erim.org VAX/VMS +Wim Bonner 27313853@WSUVM1.CSC.WSU.EDU HP 9000/840a HPUX +Paul Borman prb@cray.com Cray-X/YMP,2 UNICOS 6-8 +Kurt Van den Branden kvd2@bipsy.se.bel.alcatel.be VAX VMS +Scott Briggs briggs@nashua.progress.com Windows NT +Leslie C. Brown lbrown@BRL.MIL Pyramid MIS-4 +Ralf Brown ralf@b.gp.cs.cmu.edu Pyramid MIS-4 +Rodney Brown rdb@cmutual.com.au SunOS 4.1.3 DGUX OSF/1 + HP-UX CRC optimization +Jeremy Daniel Buhler jbuhler@owlnet.rice.edu BC++ +John Bush john.bush@east.sun.com Amiga (SAS/C) +Pietro Caselli zaphod@petruz.sublink.org Minix 1.5.10 +Andrew A. Chernov ache@astral.msk.su FreeBSD +Jeff Coffler jeffcof@microsoft.com Windows NT +David Dachtera David.Dachtera@advocatehealth.com VMS + link_zip.com bug +Bill Davidsen davidsen@crdos1.crd.ge.com Xenix (on what?) +Karl Davis riscman@geko.com.au Acorn +Daniel Deimert daniel@pkmab.se zeus3.21 Zilog S8000 +David Denholm denholm@sotona.physics.southampton.ac.uk VMS +Harald Denker harry@hal.westfalen.de ATARI +Matthew J. D'Errico doc@magna.com Bull +L. Peter Deutsch ghost@aladdin.com Linux +Uwe Doering gemini@geminix.in-berlin.de 386 Unix +Jean-Michel Dubois jmdubois@ibcfrance.fr Theos support +James P. Dugal jpd@usl.edu Pyramid 90X OSx4.1 +"Evil Ed" esaffle@gmuvax2.gmu.edu Ultrix-32 V3.1 (Rev. 9) +Patrick Ellis pellis@aic.mdc.com VMS zip -h appearance +Thomas Esken esken@uni-muenster.de Acorn fix +Dwight Estep estep@dlo10.enet.dec.com MSDOS +David A. Feinleib t-davefe@microsoft.com Windows NT +Joshua Felsteiner joshua@phys1.technion.ac.il Linux +Greg Flint afc@klaatu.cc.purdue.edu ETA-10P* hybrid Sys V +Carl Forde cforde@bcsc02.gov.bc.ca VM/CMS +Jeff Foy jfoy@glia.biostr.washington.edu IRIX Sys V Rel 3.3.1 +Mike Freeman mikef@pacifier.com Vax VMS +Kevin M. Fritz kmfritz@apgea.army.mil Turbo C++ 1.0 + Pyramid +Jean-loup Gailly jloup@chorus.fr MS-DOS Microsoft C 5.1 +Scott D. Galloway sgallowa@letterkenn-emh1.army.mil Sperry 5000 SysV.3 +Rainer Gerling gerling@faupt101.physik.uni-erlangen.de HPUX, MSDOS +Henry Gessau henryg@kullmar.kullmar.se Windows NT +Ed Gordon - Zip 3.0, VB, Unicode, + large files, splits, DLLs +Ian E. Gorman ian@iosphere.net ported zip 2.2 to VM/CMS +Wayne R. Graves graves@csa2.lbl.gov Vax VMS +George Grimes grimes@netcom.com Apollo Domain SR10.4 +Hunter Goatley goathunter@MadGoat.com VMS (VAX & Alpha), + web and ftp sites +Arnt Gulbrandsen agulbra@pvv.unit.no Linux +David Gundlach david@rolf.stat.uga.edu Sun SS1+ SunOS 4.1 +Peter Gutmann pgut1@cs.aukuni.ac.nz bug report +Dirk Haase d_haase@sitec.de MacOS port +Mark Hanning-Lee markhl@iris-355.jpl.nasa.gov SGI +Walter Haidinger e9225662@student.tuwien.ac.at Amiga and general fixes +Charles Hannum mycroft@ai.mit.edu bug report +Greg Hartwig ghartwig@ix.netcom.com VM/CMS cleanup +Tanvir Hassan tanvir.hassan@autodesk.com NT +Bob Hardy hardy@lucid.com Power C on MSDOS +Zachary Heilig heilig@plains.nodak.edu Turbo C++ 3.0 +Chris Herborth chrish@pobox.com BeOS port +Jonathan Hudson jrhudson@bigfoot.com QDOS port +Mark William Jacobs mark@mensch.stanford.edu MSDOS +Aubrey Jaffer jaffer@martigny.ai.mit.edu Pixel +Peter Jones jones.peter@uqam.ca MIPS UMIPS 4.0 + +Onolimit fix for HP-UX +Kjetil W. J{\o}rgensen jorgens@lise.unit.no OSF/1, DJGPP v2 +Bruce Kahn bkahn@archive.webo.dg.com MS-DOS Microsoft C 5.1 +Jonathan I. Kamens jik@pit-manager.mit.edu ultrix on DECstation +Dave Kapalko d.kapalko@att.com bug report +Bob Kemp Robert.V.Kemp@att.com AT&T 3B2 SysV 3.2v2 +Vivek Khera khera@cs.duke.edu SunOS +Earl Kiech KIECH@utkvx.utk.edu VAX VMS V5.4-1A +Paul Kienitz Paul.Kienitz@shelter.sf.ca.us Amiga, Watcom C +David Kirschbaum kirsch@usasoc.soc.mil He got us all in this + mess in the first place +Thomas Klausner wiz@danbala.tuwien.ac.at cygwin32 and -k fix +D. Krumbholz krumbh00@marvin.informatik.uni-dortmund.de + Acorn filetype and + timestamp bug report + +Bo Kullmar bk@kullmar.se DNIX 5.3, SunOS 4.1 +Baden Kudrenecky baden@unixg.ubc.ca OS/2 +Giuseppe La Sala lasala@mail.esa.esrin.it VMS +Jean-Marc Lasgouttes jean-marc.lasgouttes@inria.fr Bug report +Harry Langenbacher harry@neuron6.Jpl.Nasa.Gov Sun SS1+ SunOS 4.1 +Michael D. Lawler mdlawler@gwmicro.com Mt.Xinu BSD 4.3 on VAX + Borland C++ 4.51 +Johnny Lee johnnyl@microsoft.com Microsoft C 7.0 +Michael Lemke michael@io.as.utexas.edu VMS +David Lemson lemson@ux1.cso.uiuc.edu Sequent Dynix 3.0.17 +Tai-Shan Lin tlin@snakeyes.eecs.wsu.edu OS/2 +Onno van der Linden onno@simplex.nl NetBSD, Borland C++, + MSC 7.0, DJGPP 2 + +Michel loehden%mv13.decnet@vax.hrz.uni-marburg.de VMS +Warner Losh imp@Solbourne.COM packing algorithm help +Dave Lovelace davel@grex.cyberspace.org DG AOS/VS +Erik Luijten erik@tntnhb3.tn.tudelft.nl problem report +John Lundin lundin@urvax.urich.edu VAX VMS +Igor Mandrichenko mandrichenko@m10.ihep.su VAX VMS +Cliff Manis root@csoftec.csf.com SCO 2.3.1 (386) +Fulvio Marino fulvio@iconet.ico.olivetti.it X/OS 2.3 & 2.4 +Bill Marsh bmarsh@cod.nosc.mil SGI Iris 4D35 +Michael Mauch mauch@gmx.de djgpp LFN attribute fix +Peter Mauzey ptm@mtdcr.mt.lucent.com AT&T 6300, 7300 +Rafal Z. Maszkowski rzm@mat.torun.edu.pl Convex +Robert McBroom (?) rm3@ornl.gov DECsystem 5810 +Tom McConnell tmcconne@sedona.intel.com NCR SVR4 +Frank P. McIngvale frankm@eng.auburn.edu Bug report +Conor McMenamin C.S.McMenamin@sussex.ac.uk MSDOS +Will Menninger Win32, MinGW +John Messenger jlm@proteon.com Bug report +Michael kuch@mailserv.zdv.uni-tuebingen.de SGI +Dan Mick dmick@pongo.west.sun.com Solaris +Alan Modra alan@spri.levels.unisa.edu.au Linux +Laszlo Molnar lmolnar@goliat.eik.bme.hu DJGPP v2 +Jim Mollmann jmq@nccibm1.bitnet OS/2 & MVS +Sergio Monesi pel0015@cdc8g5.cdc.polimi.it Acorn +J. Mukherjee jmukherj@ringer.cs.utsa.edu OS/2 +Anthony Naggs amn@ubik.demon.co.uk bug report +Matti Narkia matti.narkia@ntc.nokia.com VAX VMS +Rainer Nausedat Zip 3.0, large files +Robert E. Newman Jr. newmanr@ssl.msfc.nasa.gov bug report +Robert Nielsen NielsenRJ@ems.com 2.2 -V VMS bug report +Christian Michel cmichel@de.ibm.com 2.2 check_dup OS/2 bug + report +Thomas S. Opheys opheys@kirk.fmi.uni-passau.de OS/2 +Humberto Ortiz-Zuazaga zuazaga@ucunix.san.uc.edu Linux +James E. O'Dell jim@fpr.com MacOS +William O'Shaughnessy williamo@hpcupt1.cup.hp.com HPUX +Neil Parks neil.parks@pcohio.com MSDOS +Enrico Renato Palmerini palmer@vxscaq.cineca.it UNISYS 7000 Sys 5 r2.3 +Geoff Pennington Geoff.Pennington@sgcs.co.uk -q output bug +Keith Petersen w8sdz@simtel20.army.mil Pyramid UCB OSx4.4c +George Petrov VM/CMS, MVS +Alan Phillips postmaster@lancaster.ac.uk Dynix/ptx 1.3 +Bruno Pillard bp@chorus.fr SunOS 4.1 +Piet W. Plomp piet@icce.rug.nl MSC 7.0, SCO 3.2v4.0 +John Poltorak j.poltorak@bradford.ac.uk problem report +Kenneth Porter 72420.2436@compuserve.com OS/2 +Norbert Pueschel pueschel@imsdd.meb.uni-bonn.de Amiga time.lib +Yuval Rakavy yuval@cs.huji.ac.il MSDOS +David A Rasmussen dave@convex.csd.uwm.edu Convex C220 with 9.0 OS +Eric Raymond esr@snark.thyrsus.com Unix +Jim Read 74312.3103@compuserve.com OS/2 +Michael Regoli mr@cica.indiana.edu Ultrix 3.1 VAX 8650 + BSD 4.3 IBM RT/125 + BSD 4.3 MicroVAX 3500 + SunOS 4.0.3 Sun 4/330 +Jochen Roderburg roderburg@rrz.uni-koeln.de Digital Unix with + AFS/NFS converter +Rick Rodgers rodgers@maxwell.mmwb.ucsf.EDU Unix man page +Greg Roelofs roe2@midway.uchicago.edu SunOS 4.1.1,4.1.2 Sun 4 + Unicos 5.1--6.1.5 Cray + OS/2 1.3 MS C 6.0 + Ultrix 4.1,4.2 DEC 5810 + VMS 5.2, 5.4 VAX 8600 + Irix 3.3.2, SGI Iris 4D + UTS 1.2.4 Amdahl 5880 +Phil Ritzenthaler phil@cgrg.ohio-state.edu SYSV +Kai Uwe Rommel rommel@ars.de or rommel@leo.org OS/2 +Markus Ruppel m.ruppel@imperial.ac.uk OS/2 +Shimazaki Ryo eririn@ma.mailbank.ne.jp human68k +Jon Saxton jrs@panix.com Microsoft C 6.0 +Steve Salisbury stevesa@msn.com Microsoft C 8.0 +Timo Salmi ts@uwasa.fi bug report +Darren Salt ds@youmustbejoking.demon.co.uk RISC OS +NIIMI Satoshi a01309@cfi.waseda.ac.jp Human68K +Tom Schmidt tschmidt@micron.com SCO 286 +Martin Schulz martin.schulz@isltd.insignia.com Windows NT, Atari +Steven Schweda VMS, Unix, large files +Dan Seyb dseyb@halnet.com AIX +Mark Shadley shadcat@catcher.com unix fixes +Timur Shaporev tim@rd.relcom.msk.su MSDOS +W. T. Sidney sidney@picard.med.ge.com bug report +Dave Sisson daves@vtcosy.cns.vt.edu AIX 1.1.1 PS/2 & 3090 +Dave Smith smithdt@bp.com Tandem port +Fred Smith fredex@fcshome.stoneham.ma.us Coherent +Christian Spieler spieler@ikp.tu-darmstadt.de VMS, MSDOS, emx, djgpp, + WIN32, Linux +Ron Srodawa srodawa@vela.acs.oakland.edu SCO Xenix/386 2.3.3 +Adam Stanley astanley@winternet.com MSDOS +Bertil Stenstr|m stenis@heron.dafa.se HP-UX 7.0 HP9000/835 +Carl Streeter streeter@oshkoshw.bitnet OS/2 +Reuben Sumner rasumner@undergrad.math.uwaterloo.ca Suggestions +E-Yen Tan e-yen.tan@brasenose.oxford.ac.uk Borland C++ win32 +Yoshioka Tsuneo tsuneo-y@is.aist-nara.ac.jp Multibyte charset + support +Paul Telles paul@pubnet.com SCO Xenix +Julian Thompson jrt@oasis.icl.co.uk bug report +Christopher C. Tjon tjon@plains.nodak.edu bug report +Robert F Tobler rft@cs.stanford.edu bug report +Eric Tomio tomio@acri.fr bug report +Cosmin Truta cosmint@cs.ubbcluj.ro win32 gcc based + asm +Anthony R. Venson cevens@unix1.sncc.lsu.edu MSDOS/emx +Antoine Verheijen antoine@sysmail.ucs.ualberta.ca envargs fix +Arjan de Vet devet@info.win.tue.nl SunOS 4.1, MSC 5.1 +Santiago Vila Doncel sanvila@ba.unex.es MSDOS +Johan Vromans jv@mh.nl bug report +Rich Wales wales@cs.ucla.edu SunOS 4.0.3 Sun-3/50 +Scott Walton scottw@io.com BSD/386 +Frank J. Wancho wancho@wsmr-simtel20.army.mil TOPS-20 + oyvind@stavanger.sgp.slb.com Bug report. +Takahiro Watanabe wata@first.tsukuba.ac.jp fixes for INSTALL +Mike White mwhite@pumatech.com wizzip DLL +Ray Wickert wickert@dc-srv.pa-x.dec.com MSDOS/DJGPP +Winfried Winkler willi@wap0109.chem.tu-berlin.de AIX +Norman J. Wong as219@freenet.carleton.ca MSDOS +Martin Zinser m.zinser@gsi.de VMS 7.x + diff --git a/proginfo/ntsd.txt b/proginfo/ntsd.txt new file mode 100644 index 0000000..8ac31ba --- /dev/null +++ b/proginfo/ntsd.txt @@ -0,0 +1,111 @@ +Info-ZIP portable Zip/UnZip Windows NT security descriptor support +================================================================== +Scott Field (sfield@microsoft.com), 8 October 1996 + + +This version of Info-ZIP's Win32 code allows for processing of Windows +NT security descriptors if they were saved in the .zip file using the +appropriate Win32 Zip running under Windows NT. This also requires +that the file system that Zip/UnZip operates on supports persistent +Acl storage. When the operating system is not Windows NT and the +target file system does not support persistent Acl storage, no security +descriptor processing takes place. + +A Windows NT security descriptor consists of any combination of the +following components: + + an owner (Sid) + a primary group (Sid) + a discretionary ACL (Dacl) + a system ACL (Sacl) + qualifiers for the preceding items + +By default, Zip will save all aspects of the security descriptor except +for the Sacl. The Sacl contains information pertaining to auditing of +the file, and requires a security privilege be granted to the calling +user in addition to being enabled by the calling application. In order +to save the Sacl during Zip, the user must specify the -! switch on the +Zip commandline. The user must also be granted either the SeBackupPrivilege +"Backup files and directories" or the SeSystemSecurityPrivilege "Manage +auditing and security log". + +By default, UnZip will not restore any aspects of the security descriptor. +If the -X option is specified to UnZip, the Dacl is restored to the file. +The other items in the security descriptor on the new file will receive +default values. If the -XX option is specified to UnZip, as many aspects +of the security descriptor as possible will be restored. If the calling +user is granted the SeRestorePrivilege "Restore files and directories", +all aspects of the security descriptor will be restored. If the calling +user is only granted the SeSystemSecurityPrivilege "Manage auditing and +security log", only the Dacl and Sacl will be restored to the new file. + +Note that when operating on files that reside on remote volumes, the +privileges specified above must be granted to the calling user on that +remote machine. Currently, there is no way to directly test what privileges +are present on a remote machine, so Zip and UnZip make a remote privilege +determination based on an indirect method. + +UnZip considerations +-------------------- + +In order for file security to be processed correctly, any directory entries +that have a security descriptor will be processed at the end of the unzip +cycle. This allows for unzip to process files within the newly created +directory regardless of the security descriptor associated with the directory +entry. This also prevents security inheritance problems that can occur as +a result of creating a new directory and then creating files in that directory +that will inherit parent directory permissions; such inherited permissions may +prevent the security descriptor taken from the zip file from being applied +to the new file. + +If directories exist which match directory/extract paths in the .zip file, +file security is not updated on the target directory. It is assumed that if +the target directory already exists, then appropriate security has already +been applied to that directory. + +"unzip -t" will test the integrity of stored security descriptors when +present and the operating system is Windows NT. + +ZipInfo (unzip -Z) will display information on stored security descriptor +when "unzip -Zv" is specifed. + + +Potential uses +============== + +The obvious use for this new support is to better support backup and restore +operations in a Windows NT environment where NTFS file security is utilized. +This allows individuals and organizations to archive files in a portable +fashion and transport these files across the organization. + +Another potential use of this support is setup and installation. This +allows for distribution of Windows NT based applications that have preset +security on files and directories. For example, prior to creation of the +.zip file, the user can set file security via File Manager or Explorer on +the files to be contained in the .zip file. In many cases, it is appropriate +to only grant Everyone Read access to .exe and .dll files, while granting +Administrators Full control. Using this support in conjunction with the +unzipsfx.exe self-extractor stub can yield a useful and powerful way to +install software with preset security (note that -X or -XX should be +specified on the self-extractor commandline). + +When creating .zip files with security which are intended for transport +across systems, it is important to take into account the relevance of +access control entries and the associated Sid of each entry. For example, +if a .zip file is created on a Windows NT workstation, and file security +references local workstation user accounts (like an account named Fred), +this access entry will not be relevant if the .zip file is transported to +another machine. Where possible, take advantage of the built-in well-known +groups, like Administrators, Everyone, Network, Guests, etc. These groups +have the same meaning on any Windows NT machine. Note that the names of +these groups may differ depending on the language of the installed Windows +NT, but this isn't a problem since each name has well-known ID that, upon +restore, translates to the correct group name regardless of locale. + +When access control entries contain Sid entries that reference Domain +accounts, these entries will only be relevant on systems that recognize +the referenced domain. Generally speaking, the only side effects of +irrelevant access control entries is wasted space in the stored security +descriptor and loss of complete intended access control. Such irrelevant +access control entries will show up as "Account Unknown" when viewing file +security with File Manager or Explorer. diff --git a/proginfo/perform.dos b/proginfo/perform.dos new file mode 100644 index 0000000..98744ee --- /dev/null +++ b/proginfo/perform.dos @@ -0,0 +1,183 @@ +Date: Wed, 27 Mar 1996 01:31:50 CET +0100 +From: Christian Spieler (IKDA, THD, D-64289 Darmstadt) +Subject: More detailed comparison of MSDOS Info-ZIP programs' performance + +Hello all, + +In response to some additional questions and requests concerning +my previous message about DOS performance of 16/32-bit Info-ZIP programs, +I have produced a more detailed comparison: + +System: +Cx486DX-40, VL-bus, 8MB; IDE hard disk; +DOS 6.2, HIMEM, EMM386 NOEMS NOVCPI, SMARTDRV 3MB, write back. + +I have used the main directory of UnZip 5.20p as source, including the +objects and executable of an EMX compile for unzip.exe (to supply some +binary test files). + +Tested programs were (my current updated sources!) Zip 2.0w and UnZip 5.20p +- 16-bit MSC 5.1, compressed with LZEXE 0.91e +- 32-bit Watcom C 10.5, as supplied by Kai Uwe Rommel (PMODE 1.22) +- 32-bit EMX 0.9b +- 32-bit DJGPP v2 +- 32-bit DJGPP v1.12m4 + +The EMX and DJ1 (GO32) executables were bound with the full extender, to +create standalone executables. + +A) Tests of Zip + Command : "\zip.exe -q<#> tes.zip unz/*" (unz/*.* for Watcom!!) + where <#> was: 0, 1, 6, 9. + The test archive "tes.zip" was never deleted, this test + measured "time to update archive". + + The following table contains average execution seconds (averaged over + at least 3 runs, with the first run discarted to fill disk cache); + numbers in parenteses specify the standard deviation of the last + digits. + + cmpr level| 0 | 1 | 6 | 9 + =============================================================== + EMX win95 | 7.77 | 7.97 | 12.82 | 22.31 + --------------------------------------------------------------- + EMX | 7.15(40) | 8.00(6) | 12.52(25) | 20.93 + DJ2 | 13.50(32) | 14.20(7) | 19.05 | 28.48(9) + DJ1 | 13.56(30) | 14.48(3) | 18.70 | 27.43(13) + WAT | 6.94(22) | 8.93 | 15.73(34) | 30.25(6) + MSC | 5.99(82) | 9.40(4) | 13.59(9) | 20.77(4) + =============================================================== + + The "EMX win95" line was created for comparison, to check the performance + of emx 0.9 with the RSX extender in a DPMI environment. (This line was + produced by applying the "stubbed" EMX executable in a full screen DOS box.) + + +B) Tests of UnZip + Commands : \unzip.exe -qt tes.zip (testing performance) + \unzip.exe -qo tes.zip -dtm (extracting performance) + + The tes.zip archive created by maximum compression with the Zip test + was used as example archive. Contents (archive size was 347783 bytes): + 1028492 bytes uncompressed, 337235 bytes compressed, 67%, 85 files + + The extraction directory tm was not deleted between the individual runs, + thus this measurement checks the "overwrite all" time. + + | testing | extracting + =================================================================== + EMX | 1.98 | 6.43(8) + DJ2 | 2.09 | 11.85(39) + DJ1 | 2.09 | 7.46(9) + WAT | 2.42 | 7.10(27) + MSC | 4.94 | 9.57(31) + +Remarks: + +The executables compiled by me were generated with all "performance" +options enabled (ASM_CRC, and ASMV for Zip), and with full crypt support. +For DJ1 and DJ2, the GCC options were "-O2 -m486", for EMX "-O -m486". + +The Watcom UnZip was compiled with ASM_CRC code enabled as well, +but the Watcom Zip example was made without any optional assembler code! + + + +Discussion of the results: + +In overall performance, the EMX executables clearly win. +For UnZip, emx is by far the fastest program, and the Zip performance is +comparable to the 16-bit "reference". + +Whenever "real" work including I/O is requested, the DJGPP versions +lose badly because of poor I/O performance, this is the case especially +for the "newer" DJGPP v2 !!! +(I tried to tweak with the transfer buffer size, but without any success.) +An interesting result is that DJ v1 UnZip works remarkably better than +DJ v2 (in contrast to Zip, where both executables' performance is +approximately equal). + +The Watcom C programs show a clear performance deficit in the "computational +part" (Watcom C compiler produces code that is far from optimal), but +the extender (which is mostly responsible for the I/O throughput) seems +to be quite fast. + +The "natural" performance deficit of the 16-bit MSC code, which can be +clearly seen in the "testing task" comparison for UnZip, is (mostly, +for Zip more than) compensated by the better I/O throughput (due to the +"direct interface" between "C RTL" and "DOS services", without any mode +switching). + +But performance is only one aspect when choosing which compiler should +be used for official distribution: + +Sizes of the executables: + | Zip || UnZip + | standalone stub || standalone | stub +====================================================================== +EMX | 143,364 (1) | 94,212 || 159,748 (1) | 110,596 +DJ2 | 118,272 (2) | -- || 124,928 (2) | -- +DJ1 | 159,744 | 88,064 || 177,152 | 105,472 +WAT | 140,073 | -- || 116,231 | -- +MSC | 49,212 (3) | -- || 45,510 (3) | -- + +(1) does not run in "DPMI only" environment (Windows DOS box) +(2) requires externally supplied DPMI server +(3) compressed with LZexe 0.91 + +Caveats/Bugs/Problems of the different extenders: + +EMX: +- requires two different extenders to run in all DOS-compatible environments, + EMX for "raw/himem/vcpi" and RSX for "dpmi" (Windows). +- does not properly support time zones (no daylight savings time) + +DJv2: +- requires an external (freely available) DPMI extender when run on plain + DOS; this extender cannot (currently ??) be bound into the executable. + +DJv1: +- uses up large amount of "low" dos memory (below 1M) when spawning + another program, each instance of a DJv1 program requires its private + GO32 extender copy in low dos memory (may be problem for the zip + "-T" feature) + +Watcom/PMODE: +- extended memory is allocated statically (default: ALL available memory) + This means that a spawned program does not get any extended memory. + You can work around this problem by setting a hard limit on the amount + of extended memory available to the PMODE program, but this limit is + "hard" and restricts the allocatable memory for the program itself. + In detail: + The Watcom zip.exe as distributed did not allow the "zip -T" feature; + there was no extended memory left to spawn unzip. + I could work around this problem by applying PMSETUP to change the + amount of allocated extended memory to 2.0 MByte (I had 4MB free extended + memory on my test system). But, this limit cannot be enlarged at + runtime, when zip needs more memory to store "header info" while + zipping up a huge drive, and on a system with less free memory, this + method is not applicable, either. + +Summary: + +For Zip: +Use the 16-bit executable whenever possible (unless you need the +larger memory capabilities when zipping up a huge amount of files) + +As 32-bit executable, we may distribute Watcom C (after we have confirmed +that enabling ASMV and ASM_CRC give us some better computational +performance.) +The alternative for 32-bit remains DJGPP v1, which shows the least problems +(to my knowledge); v2 and EMX cannot be used because of their lack of +"universality". + +For UnZip: +Here, the Watcom C 32-bit executable is probably the best compromise, +but DJ v1 could be used as well. +And, after all, the 16-bit version does not lose badly when doing +"real" extraction! For the SFX stub, the 16-bit version remains first +choice because of its much smaller size! + +Best regards + +Christian Spieler diff --git a/proginfo/timezone.txt b/proginfo/timezone.txt new file mode 100644 index 0000000..7868093 --- /dev/null +++ b/proginfo/timezone.txt @@ -0,0 +1,85 @@ +Timezone strings: +----------------- +This is a description of valid timezone strings for ENV[ARC]:TZ: +"XPG3TZ - time zone information" +The form of the time zone information is based on the XPG3 specification of +the TZ environment variable. Spaces are allowed only in timezone +designations, where they are significant. The following description +closely follows the XPG3 specification, except for the paragraphs starting +**CLARIFICATION**. + +[[],[/