summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjk7744.park <jk7744.park@samsung.com>2015-09-09 02:36:42 +0900
committerjk7744.park <jk7744.park@samsung.com>2015-09-09 02:36:42 +0900
commitcb9021933010823e97114e40c02cd2cef8d78d8f (patch)
tree0bca7e85536a30aaeaf4254c557583d72296bd79
parent5396c5e853e76507fac47181b14b25adb725f628 (diff)
downloadzip-tizen_2.3.1.tar.gz
zip-tizen_2.3.1.tar.bz2
zip-tizen_2.3.1.zip
-rw-r--r--Betas_Readme.txt17
-rw-r--r--CHANGES2927
-rw-r--r--INSTALL316
-rw-r--r--LICENSE55
-rw-r--r--MANUAL804
-rw-r--r--README257
-rw-r--r--README.CR20
-rw-r--r--TODO122
-rw-r--r--WHATSNEW334
-rw-r--r--WHERE3
-rw-r--r--acorn/GMakefile28
-rw-r--r--acorn/ReadMe.GMakefile2
-rw-r--r--acorn/acornzip.c9
-rw-r--r--acorn/makefile8
-rw-r--r--acorn/osdep.h6
-rw-r--r--acorn/riscos.c4
-rw-r--r--acorn/riscos.h8
-rw-r--r--acorn/zipsfx9
-rw-r--r--amiga/LMKfile17
-rw-r--r--amiga/amiga.c19
-rw-r--r--amiga/amigazip.c17
-rw-r--r--amiga/crc_68.a8
-rw-r--r--amiga/filedate.c321
-rw-r--r--amiga/makefile.azt176
-rw-r--r--amiga/osdep.h44
-rw-r--r--amiga/smakefile77
-rw-r--r--amiga/stat.c8
-rw-r--r--amiga/time_lib.c541
-rw-r--r--amiga/z-stat.h10
-rw-r--r--amiga/z-time.h76
-rw-r--r--aosvs/aosvs.c17
-rw-r--r--aosvs/make.cli2
-rw-r--r--api.c740
-rw-r--r--api.h58
-rw-r--r--atari/Makefile8
-rw-r--r--atari/atari.c13
-rw-r--r--atheos/Contents11
-rw-r--r--atheos/Makefile12
-rw-r--r--atheos/README6
-rw-r--r--atheos/atheos.c12
-rw-r--r--atheos/osdep.h11
-rw-r--r--atheos/zipup.h8
-rw-r--r--beos/Makefile6
-rw-r--r--beos/beos.c11
-rw-r--r--bzip2/install.txt258
-rw-r--r--cmsmvs/cczip.exec3
-rw-r--r--cmsmvs/cms.c6
-rw-r--r--cmsmvs/cmsmvs.c6
-rw-r--r--cmsmvs/cmsmvs.h15
-rw-r--r--cmsmvs/mvs.c6
-rw-r--r--cmsmvs/mvs.mki7
-rw-r--r--cmsmvs/zip.makefile1
-rw-r--r--cmsmvs/zipmvsc.job6
-rw-r--r--cmsmvs/zipvmc.exec4
-rw-r--r--crc32.c710
-rw-r--r--crc32.h60
-rw-r--r--crc_i386.S158
-rw-r--r--crctab.c227
-rw-r--r--crypt.c304
-rw-r--r--crypt.h42
-rw-r--r--deflate.c67
-rw-r--r--ebcdic.h48
-rw-r--r--file_id.diz6
-rw-r--r--fileio.c4101
-rw-r--r--globals.c203
-rw-r--r--human68k/Makefile6
-rw-r--r--human68k/Makefile.gcc12
-rw-r--r--human68k/crc_68.s8
-rw-r--r--human68k/human68k.c29
-rw-r--r--macos/HISTORY.TXT117
-rw-r--r--macos/README.TXT513
-rw-r--r--macos/osdep.h10
-rw-r--r--macos/readme.1st4
-rw-r--r--macos/source/charmap.h8
-rw-r--r--macos/source/extrafld.c28
-rw-r--r--macos/source/getenv.c6
-rw-r--r--macos/source/helpers.c10
-rw-r--r--macos/source/helpers.h8
-rw-r--r--macos/source/macopen.c6
-rw-r--r--macos/source/macos.c6
-rw-r--r--macos/source/macstuff.h1116
-rw-r--r--macos/source/mactime.c8
-rw-r--r--macos/source/mactime.h8
-rw-r--r--macos/source/pathname.c121
-rw-r--r--macos/source/pathname.h15
-rw-r--r--macos/source/unixlike.c6
-rw-r--r--man/zip.12102
-rw-r--r--man/zipcloak.1111
-rw-r--r--man/zipnote.185
-rw-r--r--man/zipsplit.169
-rw-r--r--mktime.c257
-rw-r--r--msdos/README.DOS51
-rw-r--r--msdos/crc_i86.asm67
-rw-r--r--msdos/makebz2.dj2148
-rw-r--r--msdos/makefile.bor33
-rw-r--r--msdos/makefile.dj131
-rw-r--r--msdos/makefile.dj233
-rw-r--r--msdos/makefile.emx32
-rw-r--r--msdos/makefile.msc38
-rw-r--r--msdos/makefile.tc30
-rw-r--r--msdos/makefile.wat35
-rw-r--r--msdos/match.asm48
-rw-r--r--msdos/msdos.c87
-rw-r--r--msdos/osdep.h21
-rw-r--r--novell/MAKEINIT71
-rw-r--r--novell/Makefile142
-rw-r--r--novell/Netware.c970
-rw-r--r--novell/README9
-rw-r--r--novell/m.cmd9
-rw-r--r--novell/osdep.h205
-rw-r--r--novell/signal.c49
-rw-r--r--novell/zip.lnk25
-rw-r--r--novell/zipup.h16
-rw-r--r--os2/makefile.os271
-rw-r--r--os2/match32.asm10
-rw-r--r--os2/os2.c4
-rw-r--r--os2/os2acl.c8
-rw-r--r--os2/os2acl.h4
-rw-r--r--packaging/exec-shield.patch19
-rw-r--r--packaging/zcrypt29.tar.gzbin17484 -> 0 bytes
-rw-r--r--packaging/zip-2.3-currdir.patch11
-rw-r--r--packaging/zip-2.31-configure.patch213
-rw-r--r--packaging/zip-2.31-install.patch11
-rw-r--r--packaging/zip-2.31-near-4GB.patch293
-rw-r--r--packaging/zip.spec157
-rw-r--r--packaging/zip23-umask.patch23
-rw-r--r--packaging/zip23.patch93
-rw-r--r--proginfo/ebcdic.msg63
-rw-r--r--proginfo/extrafld.txt (renamed from proginfo/extra.fld)513
-rw-r--r--proginfo/infozip.who26
-rw-r--r--proginfo/ntsd.txt (renamed from proginfo/nt.sd)0
-rw-r--r--proginfo/timezone.txt (renamed from amiga/timezone.doc)0
-rw-r--r--proginfo/ziplimit.txt97
-rw-r--r--qdos/Makefile.qdos8
-rw-r--r--qdos/Makefile.qlzip6
-rw-r--r--qdos/crc68.s8
-rw-r--r--qdos/qdos.c8
-rw-r--r--qdos/qfileio.c20
-rw-r--r--revision.h112
-rw-r--r--tailor.h459
-rw-r--r--tandem/HISTORY6
-rw-r--r--tandem/README1
-rw-r--r--tandem/commacs25
-rw-r--r--tandem/doit (renamed from tandem/DOIT)6
-rw-r--r--tandem/macros247
-rw-r--r--tandem/make34
-rw-r--r--tandem/tandem.c239
-rw-r--r--tandem/tandem.h128
-rw-r--r--tandem/tannsk.h8
-rw-r--r--tandem/tanzip.c128
-rw-r--r--tandem/tanzip.h36
-rw-r--r--tandem/zipup.h4
-rw-r--r--theos/Makefile53
-rw-r--r--theos/_fprintf.c8
-rw-r--r--theos/_isatty.c8
-rw-r--r--theos/charconv.h8
-rw-r--r--theos/stat.h8
-rw-r--r--theos/theos.c14
-rw-r--r--timezone.c815
-rw-r--r--timezone.h83
-rw-r--r--tops20/make.mic3
-rw-r--r--tops20/osdep.h10
-rw-r--r--tops20/tops20.c16
-rw-r--r--trees.c127
-rw-r--r--ttyio.c151
-rw-r--r--ttyio.h15
-rw-r--r--unix/Makefile165
-rw-r--r--unix/Packaging/pkginfo.in4
-rw-r--r--[-rwxr-xr-x]unix/Packaging/postinstall41
-rw-r--r--[-rwxr-xr-x]unix/Packaging/preinstall.in39
-rw-r--r--unix/Packaging/prototype17
-rw-r--r--[-rwxr-xr-x]unix/configure450
-rw-r--r--unix/osdep.h73
-rw-r--r--unix/unix.c395
-rw-r--r--unix/zipup.h4
-rw-r--r--util.c906
-rw-r--r--vms/00binary.vms87
-rw-r--r--vms/00readme.txt126
-rw-r--r--vms/NOTES.TXT382
-rw-r--r--vms/VMS_ZIP.RNH1467
-rw-r--r--vms/build_zip.com690
-rw-r--r--vms/bzlib.h21
-rw-r--r--vms/cmdline.c890
-rw-r--r--vms/collect_deps.com89
-rw-r--r--vms/cvthelp.tpu16
-rw-r--r--vms/descrip.mms639
-rw-r--r--vms/descrip_deps.mms207
-rw-r--r--vms/descrip_mkdeps.mms247
-rw-r--r--vms/descrip_src.mms373
-rw-r--r--vms/find_bzip2_lib.com71
-rw-r--r--vms/hlp_lib_next.com17
-rw-r--r--vms/install_vms.txt158
-rwxr-xr-xvms/link_zip.com204
-rwxr-xr-xvms/make_zip.com287
-rw-r--r--vms/makefile.vms251
-rw-r--r--vms/mod_dep.com33
-rw-r--r--vms/osdep.h90
-rw-r--r--vms/stream_lf.fdl3
-rw-r--r--vms/unixio_gcc.h27
-rw-r--r--vms/unixlib_gcc.h16
-rw-r--r--vms/vms.c464
-rw-r--r--vms/vms.h89
-rw-r--r--vms/vms_im.c130
-rw-r--r--vms/vms_msg_gen.c91
-rw-r--r--vms/vms_pk.c168
-rw-r--r--vms/vms_zip.rnh548
-rw-r--r--vms/vmsdefs.h6
-rw-r--r--vms/vmsmunch.c92
-rw-r--r--vms/vmsmunch.h6
-rw-r--r--vms/vmszip.c1097
-rw-r--r--vms/zip.opt1
-rw-r--r--vms/zip_cli.cld117
-rw-r--r--vms/zip_cli.help1673
-rw-r--r--vms/zip_msg.msg57
-rw-r--r--vms/zipup.h40
-rw-r--r--win32/README.txt10
-rw-r--r--win32/crc_i386.asm183
-rw-r--r--win32/crc_i386.c152
-rw-r--r--win32/crc_lcc.asm71
-rw-r--r--win32/lm32_lcc.asm6
-rw-r--r--win32/makefile.a6430
-rw-r--r--win32/makefile.bor102
-rw-r--r--win32/makefile.dj32
-rw-r--r--win32/makefile.emx57
-rw-r--r--win32/makefile.gcc63
-rw-r--r--win32/makefile.ibm30
-rw-r--r--win32/makefile.lcc36
-rw-r--r--win32/makefile.w1062
-rw-r--r--win32/makefile.w32205
-rw-r--r--win32/makefile.wat58
-rw-r--r--win32/makenoas.w32219
-rw-r--r--win32/match32.asm12
-rw-r--r--win32/nt.c20
-rw-r--r--win32/nt.h6
-rw-r--r--win32/osdep.h372
-rw-r--r--win32/rsxntwin.h13
-rw-r--r--win32/vc6/ReadmeVC.txt10
-rw-r--r--win32/vc6/zip.dsp31
-rw-r--r--win32/vc6/zipcloak.dsp110
-rw-r--r--win32/vc6/zipnote.dsp114
-rw-r--r--win32/vc6/zipsplit.dsp112
-rw-r--r--win32/vc6bz2/ReadVCBZ.txt19
-rw-r--r--win32/vc6bz2/zip.dsp381
-rw-r--r--win32/vc6bz2/zip.dsw65
-rw-r--r--win32/win32.c671
-rw-r--r--win32/win32i64.c115
-rw-r--r--win32/win32zip.c1380
-rw-r--r--win32/win32zip.h27
-rw-r--r--win32/zip.rc53
-rw-r--r--win32/zipup.h17
-rw-r--r--windll/VBz64/VBZIP.VBP33
-rw-r--r--windll/VBz64/VBZIP.vbw2
-rw-r--r--windll/VBz64/VBZipBas.bas737
-rw-r--r--windll/VBz64/Vbzipfrm.frm183
-rw-r--r--windll/VBz64/readVB64.txt25
-rw-r--r--windll/Vb/VBZIP.vbw2
-rw-r--r--windll/Vb/VBZipBas.bas (renamed from windll/vb/VBZipBas.bas)19
-rw-r--r--windll/Vb/Vbzip.vbp (renamed from windll/vb/Vbzip.vbp)0
-rw-r--r--windll/Vb/Vbzipfrm.frm (renamed from windll/vb/Vbzipfrm.frm)0
-rw-r--r--windll/Vb/readmeVB.txt (renamed from windll/vb/readmeVB.txt)21
-rw-r--r--windll/contents35
-rw-r--r--windll/example.c6
-rw-r--r--windll/example.h6
-rw-r--r--windll/resource.h16
-rw-r--r--windll/structs.h8
-rw-r--r--windll/vb/VBZIP.vbw2
-rw-r--r--windll/visualc/dll/zip32.mak858
-rw-r--r--windll/visualc/dll/zip32z64.dsp (renamed from windll/visualc/dll/zip32.dsp)30
-rw-r--r--windll/visualc/dll/zip32z64.dsw (renamed from windll/visualc/dll/zip32.dsw)2
-rw-r--r--windll/visualc/lib/zip32.mak586
-rw-r--r--windll/visualc/lib/zip32z64.dsp (renamed from windll/visualc/lib/zip32.dsp)24
-rw-r--r--windll/visualc/lib/zip32z64.dsw (renamed from windll/visualc/lib/zip32.dsw)2
-rw-r--r--windll/windll.apsbin0 -> 1652 bytes
-rw-r--r--windll/windll.c12
-rw-r--r--windll/windll.h12
-rw-r--r--windll/windll.rc106
-rw-r--r--windll/windll.txt75
-rw-r--r--windll/windll32.def7
-rw-r--r--windll/ziplib.def4
-rw-r--r--windll/zipver.h15
-rw-r--r--zbz2err.c61
-rw-r--r--zip.c5174
-rw-r--r--zip.h686
-rw-r--r--zip.txt2027
-rw-r--r--zip30.ann95
-rw-r--r--zip30f.ann61
-rw-r--r--zip30g.ann33
-rw-r--r--zip30h.ann47
-rw-r--r--zipcloak.c444
-rw-r--r--zipcloak.txt75
-rw-r--r--ziperr.h104
-rw-r--r--zipfile.c5813
-rw-r--r--zipnote.c264
-rw-r--r--zipnote.txt63
-rw-r--r--zipsplit.c312
-rw-r--r--zipsplit.txt53
-rw-r--r--zipup.c1082
297 files changed, 48047 insertions, 13716 deletions
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
index b033871..751695f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -769,245 +769,2692 @@
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)
------------------------- December 10th 2004 version 2.31a ------------------
-This is a patch to Zip 2.3 including various bug fixes.
-See Zip 3.0 for the latest additional features.
- 1. Crypt added to source by default now that export restrictions have been
- relaxed (Ed Gordon)
- 2. Debian patch 001 for bug 99659 - Converted quoted strings in version compile
- information to defines (Debian patch 001, Ed)
- 3. Debian patch 002 - Sets the "normal" unix permissions in the Makefile, so
- don't have to change them in debian/rules (Debian patch 002, Ed)
- 4. Debian patch 003 - to support DEB_BUILD_OPTIONS as required by latest
- policy. The LFLAGS1 thing could be considered debian-specific, but
- INSTALL_PROGRAM thing should be in the upstream version (Debian patch 003, Ed)
- 5. Debian patch 004 - Make gcc happy (probably gcc 3.x) - apply 2.4i configure
- changes to remove need for -fno-builtin in unix/configure (Onno, Ed)
- 6. Debian patch 005 for bug 279867 - Fix for FNMAX path bug that could crash
- on large paths and create security problem (Greg)
------------------------- December 17th 2004 version 2.31b ------------------
- 1. File cleanup (Ed)
------------------------- December 30th 2004 version 2.31c ------------------
- 1. Add VMS tempname (Steven Schweda (SMS))
- 2. Add VMS option -VV for archiving most all file types on VMS and fix -V to create
- more portable archives (SMS)
- 3. Update VMS command line interface
- 4. Update README (Ed)
------------------------- January 1st 2005 version 2.31d ------------------
- 1. Delete duplicate free(name) in filetime in unix/unix.c (Johnny Lee)
------------------------- January 8th 2005 version 2.31e ------------------
- 1. Change zfstat to fstat in unix/unix.c (Ed)
------------------------- January 22nd 2005 version 2.31f ------------------
- 1. Update file_id.diz (Cosmin Truta)
- 2. Initialize use_longname_ea under both OS2 and WIN32. zip.c (Cosmin)
- 3. Enclose option -! and use_privileges under NTSD_EAS guard. api.c,
- zip.c (Cosmin)
- 4. Implement partial support for Cygwin inside the Unix port (Cosmin)
- 5. Add i586, i686 and Cygwin to version_local(). unix/unix.c (Cosmin)
- 6. Ensure stat'ing always works on file names with trailing '/' in
- set_extra_field(). unix/unix.c (Cosmin)
- 7. Define ASM_CRC by default. win32/osdep.h (Cosmin)
- 8. Update from zip24h. win32/makefile.bor, win32/makefile.w32 (Cosmin)
- 9. Enable the i686-optimized code by default. crc_i386.S,
+-------------------------- 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)
-10. Replaced win32/VC6.dsp with a complete Visual C++ 6.0 project to build
- zip, zipnote, zipsplit and zipcloak, with both ASM and non-ASM settings.
- (Note that win32/VC6.dsp was a new addition since Zip 2.3 and at this
- point won't be released since this new workspace is better. Ed)
- win32/vc6/zip.dsw (new) (Cosmin)
-11. Add AtheOS port (Ruslan Nickolaev, Ed)
-12. Formatting and consistency fixes (Johnny Lee, Ed)
-13. Add kluge to api.c so zip32.dll supports string parameters in Visual
- Basic. See VB project files (Ed)
------------------------- January 28th 2005 version 2.31g ------------------
- 1. Adjust binary detection in trees.c by changing 20% binary (4 out of 5
- ascii) to 2% (64 out of 65) (Ed)
- 2. Update license and license headers (Ed)
- 3. Update Install and Readme.cr (Ed)
- 4. Update windll.rc (Ed)
- 5. Update Readme (Ed)
- 6. Update Manual (Ed)
------------------------- February 5th 2005 version 2.31h ------------------
- 1. Add error return for filetime() FXMAX bug fix where missed in acornzip.c,
- atari.c, beos.c, human68k.c, msdos.c, os2.c, theos.c, tops20.c, and
- win32zip.c (Ed)
- 2. Move -r and -R code in api.c lower down to avoid -R bug (Ed)
- 3. Update VB project ReadmeVB files and notes in new VB project (Ed)
- 4. Update license. revision.h (Ed)
- 5. Update Readme.cr with updated encryption information and update zip.c
- to include encryption notice in version information (Ed)
- 6. Remove win32/VC6-old.dsp (Cosmin)
- 7. Check for symlink support in procname(). unix/unix.c (Cosmin)
- 8. Define (again) ASM_CRC by default. win32/osdep.h (Cosmin)
- 9. Use the right type (DWORD) for volSerNo, maxCompLen and fileSysFlags
- in FSusesLocalTime(). win32/win32.c (Cosmin)
-10. Update win32/makefile.bor, win32/makefile.gcc, win32/makefile.w32 (Cosmin)
-11. Update Readme (Ed)
------------------------- February 15th 2005 version 2.31i ------------------
- 1. WHERE updated (Cosmin, Christian)
- 2. Allow for reverting to Win32 time handling using NO_W32TIMES_IZFIX.
- win32/win32.c, win32/win32zip.h, zip.c (Christian)
- 3. Update crypt comments and default behavior. crypt.h
- 4. Kludge to work around non-standard S_IFREG flag used in DJGPP V2.x,
- compiler version strings changes. msdos/msdos.c (Christian)
- 5. Changes to MS rtl function declarations. win32/osdep.h (Christian)
- 6. Time changes including GetPlatformLocalTimezone; force use of registry
- to get timezone info with MS C rtl. win32/win32.c (Christian)
- 7. Compiler version string changes. win32/win32.c (Christian, Brad Clarke)
- 8. Changes to extra field bytes to compress. win32/win32zip.c (Christian)
- 9. Changes to get_filters(), changes to help and version option detection
- (allow redirection of version screen to file), add set dosflag for DOS to
- force the use of msdos style when updating zip entries originally created
- under non-DOS OS. zip.c (Christian)
-10. License update. zip.h (Christian)
-11. Rename errors array to ziperrors to avoid MacOSX library clash.
- ziperr.h (Mark)
-12. Updates to zipcloak.c for crypt and other changes. (Christian)
-13. Updates to zipsplit.c (use ZCONST in prototypes where appropiate).
+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 <wctype.h> 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)
-14. Update version. windll/zipver.h (Mike)
-15. Makefile updates (use UPX compressor and ...). msdos/makefile.bor,
- msdos/makefile.dj2, msdos/makefile.msc, msdos/makefile.tc (Christian)
-16. Detect Turbo C 2.01 in msdos/osdep.h NO_MKTIME definition. (Brian Lindholm)
-17. Readme update. msdos/README.DOS (Christian, Ed)
-18. Change Zip limits description. msdos/README.DOS (Christian)
-19. Fixed ASFLAGS for watcom16dos. os2/makefile.os2 (Christian)
-20. Changes to GetLongPathEA(); fix OS/2's ACL compression code.
- os2/os2zip.c, os2/os2zip.h (Christian, Kai Uwe)
-21. Changes to acorn. acorn/acornzip.c, acorn/GMakefile, acorn/makefile,
- acorn/osdep.h, acorn/ReadMe.GMakefile, acorn/riscos.c, acorn/riscos.h,
- acorn/RunMe1st (Darren Salt, Andy Wingate, Christian)
-22. Update proginfo/extra.fld (and appnote.iz). (Christian)
-23. Correct translation of EBCDIC passwords to ASCII. (Christian)
------------------------- February 19th 2005 version 2.31j ------------------
- 1. Data corruption, buffer size, type cast and other fixes for VMS.
- vms/vms_pk.c, vms/vmsmunch.c (SMS)
- 2. Update version in file_id.diz. (Cosmin)
- 3. Update file version. readme.cr (Cosmin)
- 4. Put mktemp() declaration inside the NO_PROTO guard. tailor.h (Cosmin)
- 5. Remove getenv() declaration. util.c (Cosmin)
- 6. Document and implement a new text detection scheme in set_file_type().
- proginfo/txtvsbin.txt, trees.c (Cosmin)
- 7. Set the "zip Debug" configuration as default. win32/vc6/zip.dsp (Cosmin)
- 8. Move new encryption notice from zip.c into revision.h where the other
- notice texts reside. (Cosmin)
- 9. Change USE_ZLIB compiler message from -v to show version. zip.c (Cosmin)
-10. Removed change of Zip 2.31i to MS rtl function declarations.
- win32/osdep.h (Cosmin, Christian)
-11. Don't use mmap for stored entries. zipup.c (Christian)
-12. msdos/msdos.c, corrected missing change in version_local. (Christian)
-13. BIG_MEM and MMAP cannot be defined at the same time. tailor.h (Christian)
-14. Update LICENSE to include the new Zip maintainer Ed Gordon and
- Cosmin Truta. LICENSE, revision.h (Christian)
-15. Format changes. LICENSE, revision.h (Cosmin, Christian, Ed)
-16. WHERE: URLs updated, removed last zcrXXX references. (Christian)
-17. Note that ZIP64 enhancements will (probably) never be applicable for
- MSDOS. msdos/README.DOS (Christian, Ed)
-18. msdos/makefile.wat, win32/makefile.wat: bug-fixes (added creation of
- intermediate object directories). (Christian)
-19. win32/win32.c, minor indentation and code format changes. (Christian)
-20. Modified zipnote.c to handle line widths of at least 2047 characters in
- write mode. (Christian)
------------------------- February 20th 2005 version 2.31k ------------------
- 1. Update to msdos/README.DOS noting splits can support some Zip64 features
- but we may not get to most Zip64 features for MSDOS. (Christian, Ed)
- 2. Move encryption notice in revision.h and delete blank line. (Christian)
- 3. Change old binary detection to new black list version. Provided by
- Cosmin. trees.c (Cosmin, Johnny, Christian)
- 4. Update documentation for new binary detection. trees.c (Christian, Ed)
- 5. Set debug directory to od32w. win32/makefile.wat (Christian, Ed)
- 6. Allow -@ and - (stdout) at same time. The check for -@ and - was
- intended to prevent having both file contents and file names from stdin
- at the same time but prevented this case instead. The case where both
- -@ and - (stdin) is used at the same time was not trapped before and
- is still not trapped in Zip 2.31. It apparently results in an empty
- file called "-" in the archive. (This may be fixed in a later Zip 2.x
- release. It is fixed in the Zip 3.0 beta. Ed) (Christian)
- 7. Update zip.h with new license (Christian)
- 8. Update version. revision.h (Ed)
- 9. Add check for file size beyond 4 GB limit to file_read but should only
- get used for OS that support large files but Zip was not compiled with
- large file support. zipup.c (Christian)
-10. Allow store method in memcompress. zipup.c (Christian)
-11. Add note to ToDo (Ed)
-12. Update ZE_BIG to include reading and writing. ziperr.h (Ed)
-13. Update Whatsnew (Ed)
------------------------- February 26th 2005 version 2.31l ------------------
- 1. License date change, ftp site change from ftp.uu.net to ftp.info-zip.org,
- and other minor changes in Readme (Ed)
- 2. Update windll/VB-orig/readmeVB.txt, windll/VB/readmeVB.txt (Ed)
- 3. Update man page including updating the date, notes about wildcard
- escaping on various ports, add a note to -ll about binary detection,
- note on -v now allowing stdin to print version, and update error code 6
- (ZE_BIG) to include read and written files. man/zip.1 (Ed)
- 4. Remove zip32-old.dsp from windll/visualc/dll and windll/visualc/lib (Ed)
- 5. Update notes on crypt, TZ, WIN32, and WINDLL. INSTALL (Christian)
- 6. Update indentation and add Steven Schweda to LICENSE (Christian)
- 7. Add Steven Schweda to license. zip.h (Ed)
- 8. Update copyright and version in atheos/Makefile (Christian)
- 9. Format changes. atheos/README, athoes/atheos.c, atheos/osdep.h (Christian)
-10. Update header and error 6 in ziperr.h (Christian)
-11. Change 64k entries note, add Zip64 note, and add Zip 3 and UnZip 6 note.
- proginfo/ziplimit.txt (Christian)
-11. Update report problems address. proginfo/ziplimit.txt (Ed)
-12. Add Steven Schweda to license. revision.h (Ed)
-13. Add directory for files. makefile.w10 (Christian)
-14. Change ob32w to od32w for debugging. makefile.wat (Christian)
-15. Remove Borland and Win16 support. windll/contents (Christian)
-16. Update formatting of license. zip.h (Christian)
------------------------- February 28th 2005 version 2.31m ------------------
- 1. Update txtvsbin.txt. proginfo/txtvsbin.txt (Cosmin)
- 2. Changes to comments for binary detection. trees.c (Cosmin)
- 3. Add USE_ZLIB note. zip.c (Cosmin)
- 4. Update zipcloak.c to use new crypto notice (Cosmin)
- 5. Remove duplicate license copyright note. zipnote.c (Cosmin)
- 6. Remove duplicate license copyright note. zipsplit.c (Cosmin)
- 7. Format change in LICENSE (Christian)
- 8. Update copyright. atheos/zipup.h (Christian)
- 9. Update license to match final official version. revision.h (Christian)
-10. Update license to match final official version. zip.h (Christian)
-11. Update version to Zip 2.31 for release. revision.h (Ed)
-12. Update notes in VB files. windll/vb/vbzipfrm.frm,
- windll/vb/readmeVB.txt (Ed)
-13. Formatting fixes for Manual to get dashes to be consistent and other
- changes. man/zip.1 (Cosmin)
-14. Change Makefile to filter out tabs using col -bx to create MANUAL to
- avoid problems with spacing on WIN32. unix/Makefile (Ed)
-15. Additional formatting and other changes to manual (Ed)
-16. Recompile MANUAL from man/zip.1 (Ed)
-17. Fix ZipCloak to remove old crypt comment and get encryption notice off
- front page and move to the version page. zipcloak.c (Ed)
-18. Update file times on unchanged files that somehow became off 6 hours
- to match times in Zip 2.3 release. Bugs, USexport.msg, and many files
- in acorn, amiga, aosvs, atari, beos, cmsmvs, human68k, macos, msdos,
- os2, proginfo, qdos, tandem, theos, tops20, unix, vms, win32, and
- windll (Cosmin)
-19. Add new longest_match in WIN64 assembler. Must use the new makefile
- to compile it. Also change win32/osdep.h to allow use of assembler
- for longest_match without using assembler for CRC. THIS IS UNTESTED.
- win32/gvmat64.asm, win32/readme.x64, win32/makefile.asm64,
- win32/osdep.h (Gilles Vollant)
-20. Add note WIN64 assembler not completely tested. win32/readme.x64 (Ed)
-21. Minor change of wording on regulations involving crypt. readme.cr (Ed)
-22. Update release date to 28 Feb 2005 (Ed)
-23. Update USexport.msg (Greg)
-24. Rename makefile.asm64 to makefile.a64 to stay in 8.3 name restriction
- if someone unpacks all this on MSDOS and rename readme.x64 to
- readme.a64 to match. win32/readme.a64, win32/makefile.a64 (Ed)
------------------------- March 4th 2005 version 2.31n ------------------
- 1. Fix byte counts on exit in zipcloak() and zipbare() to fix zipcloak bug.
- crypt.c (Paul, Christian)
- 2. Fix swlicense size from 40 to 50. revision.h (Cosmin)
- 3. For ZLIB use www.zlib.net instead of www.zlib.org. WHERE (Cosmin)
- 4. Remove windll/windll.aps as it is not needed (Cosmin)
- 5. Update version date. revision.h (Ed)
- 6. Remove windll/vb-orig project (Ed)
- 7. Changes to VB project comments. readmeVB.txt, VBZipBas.bas (Ed)
- 8. Change to ZCONST. amiga/amiga.c (Paul)
- 9. Update Atheos port to most recent changes. zipup.c, zipnote.c, zip.h,
- ttyio.c, tailor.h, atheos/atheos.c, atheos/contents, atheos/Makefile,
- atheos/osdep.h, atheos/Readme, atheos/zipup.h (Ruslan Nickolaev, Ed)
------------------------- March 8th 2005 version 2.31 ------------------
- 1. Update gvmat64.asm (Gilles)
- 2. Update version. revision.h (Ed)
- 3. Update WhatsNew (Ed)
+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
index 7549e8d..be3e0c5 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,46 +1,85 @@
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 (under any system) or
- PKUNZIP 2.04g or later (under MSDOS) to unpack the distribution
- file, zip231.zip. But since you read this, you have unpacked it
- already, or you cheated and got a tar.Z file...
+ 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...
-Installation on Unix
+ 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.
- Let's assume that you start from scratch and have not yet
- unpacked the sources. First, unpack the source as follows,
- assuming that you have zip231.zip in the current directory.
+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
- unzip ../zip231
-
- This extracts all source files and documentation in the
- directory called "zipsrc". This release now includes the standard
- encryption code previously in the separate package zcrypt29.zip,
- but you still can decide wether 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
+ 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.
+ makefile). See README.CR for more on crypt.
You then do:
make -f unix/Makefile system
- where "system" is one of: generic, generic_gcc,
+ where "system" is one of: generic, generic_gcc,
att6300, coherent, cray_v3, minix, sco_x286, xenix, zilog.
- Try "make -f unix/Makefile generic" first, this works on many systems.
- If this fails, then use one of the special targets given above.
+ 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.
- If you get error messages "constant expected" in deflate.c, add
- -DDYN_ALLOC to CFLAGS in your makefile entry.
+ 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
@@ -48,35 +87,33 @@ Installation on Unix
entry mmap_gcc for an example.
If none of these compiles, links, and functions properly on
- your Unix system, see the file README for how to get help.
+ 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 and zipsplit will be created. You can copy them
- to an appropriate directory in the search path using:
+ 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 page. Change the macros
- BINDIR and MANDIR in makefile if appropriate.
-
- You can use the command "set" to see the current search
- path. If you are using the C-Shell (csh), enter the com-
- mand:
+ /usr/local/man/man1 for the manual pages. Change the macros
+ BINDIR and MANDIR in makefile to change these if needed.
- rehash
+ 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.
- so csh can find the new command in the path. You are now
- ready to use Zip.
-
- You can get rid of the now unnecessary source and object
- files with:
+ You can get rid of the now unnecessary source and object files
+ with:
cd ..
- rm -r zipsrc
+ rm -r zip30
- This will remove the directory zip and its contents created
- by unzip. You should keep the zip231.zip file around though,
+ 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.
@@ -94,17 +131,18 @@ Installation on Unix
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 dependant files are
+ 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
+ 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 and -o 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.
+ 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:
@@ -122,9 +160,8 @@ Installation on other systems
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
+ free GNU C implementations, respectively. More detailed instructions
can be found in the respective makefiles.
@@ -166,23 +203,166 @@ Installation on other systems
VMS (OpenVMS):
- Apply
-
- @[.vms]make_zip
-
- or use DEC's MMS make utility (or the MMK clone) if available:
-
- mms /descr=[.vms]descrip.mms /macro=(__ALPHA__=1) for Alpha AXP
- mms /descr=[.vms]descrip.mms /macro=(__DECC__=1) for DEC C on VAX
- mms /descr=[.vms]descrip.mms /macro=(__VAXC__=1) for VAX C
- mms /descr=[.vms]descrip.mms /macro=(__GNUC__=1) for GNU C on VAX
-
- (If you have installed both DEC C and VAX C on your VAX and want to use
- the latter compiler, you should define the macro "__FORCE_VAXC__"
- instead of "__VAXC__".)
+ 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 further information please consult 00readme.txt in the vms/
- subdirectory.
For command help on any of the zip* utilities, simply enter
the name with no arguments.
diff --git a/LICENSE b/LICENSE
index 9cc83dc..bcfe47e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,9 +1,10 @@
-This is version 2005-Feb-10 of the Info-ZIP copyright and license.
+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.
+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-2005 Info-ZIP. All rights reserved.
+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:
@@ -15,7 +16,7 @@ the following set of individuals:
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
+ 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
@@ -24,31 +25,35 @@ 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 following restrictions:
+freely, subject to the above disclaimer and the following restrictions:
- 1. Redistributions of source code must retain the above copyright notice,
- definition, disclaimer, and this list of conditions.
+ 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) 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.
+ 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, and dynamic,
- shared, or static library versions--must be plainly marked as such
- and must not be misrepresented as being 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 of the Info-ZIP URL(s).
+ 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
diff --git a/MANUAL b/MANUAL
deleted file mode 100644
index 6b6f88b..0000000
--- a/MANUAL
+++ /dev/null
@@ -1,804 +0,0 @@
-ZIP(1L) ZIP(1L)
-
-NAME
- zip, zipcloak, zipnote, zipsplit - package and compress (archive) files
-
-SYNOPSIS
- zip [-aABcdDeEfFghjklLmoqrRSTuvVwXyz!@$] [-b path] [-n suffixes]
- [-t mmddyyyy] [-tt mmddyyyy] [ zipfile [ file1 file2 ...]] [-xi list]
-
- zipcloak [-dhL] [-b path] zipfile
-
- zipnote [-hwL] [-b path] zipfile
-
- zipsplit [-hiLpst] [-n size] [-b path] zipfile
-
-DESCRIPTION
- zip is a compression and file packaging utility for Unix, VMS, MSDOS,
- OS/2, Windows NT, Minix, Atari and Macintosh, Amiga and Acorn RISC OS.
-
- It is analogous to a combination of the UNIX commands tar(1) and com-
- press(1) and is compatible with PKZIP (Phil Katz's ZIP for MSDOS sys-
- tems).
-
- A companion program (unzip(1L)), unpacks zip archives. The zip and
- unzip(1L) programs can work with archives produced by PKZIP, and PKZIP
- and PKUNZIP can work with archives produced by zip. zip version 2.31
- is compatible with PKZIP 2.04. Note that PKUNZIP 1.10 cannot extract
- files produced by PKZIP 2.04 or zip 2.31. You must use PKUNZIP 2.04g or
- unzip 5.0p1 (or later versions) to extract them.
-
- For a brief help on zip and unzip, run each without specifying any
- parameters on the command line.
-
- The program is useful for packaging a set of files for distribution;
- for archiving files; and for saving disk space by temporarily compress-
- ing unused files or directories.
-
- The zip program puts one or more compressed files into a single 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 zip
- archive with a single command. Compression ratios of 2:1 to 3:1 are
- common for text files. zip has one compression method (deflation) and
- can also store files without compression. zip automatically chooses
- the better of the two for each file to be compressed.
-
- When given the name of an existing zip archive, zip will replace iden-
- tically named entries in the zip archive or add entries for new names.
- For example, if foo.zip exists and contains foo/file1 and foo/file2,
- and the directory foo contains the files foo/file1 and foo/file3, then:
-
- zip -r foo foo
-
- will replace foo/file1 in foo.zip and add foo/file3 to foo.zip. After
- this, foo.zip contains foo/file1, foo/file2, and foo/file3, with
- foo/file2 unchanged from before.
-
- If the file list is specified as -@, [Not on MacOS] zip takes the list
- of input files from standard input. Under UNIX, this option can be
- used to powerful effect in conjunction with the find(1) command. For
- example, to archive all the C source files in the current directory and
- its subdirectories:
-
- find . -name "*.[ch]" -print | zip source -@
-
- (note that the pattern must be quoted to keep the shell from expanding
- it). 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:
-
- zip -r - . | dd of=/dev/nrst0 obs=16k
-
- would write the zip output directly to a tape with the specified block
- size for the purpose of backing up the current directory.
-
- zip also accepts a single dash ("-") as the name of a file to be com-
- pressed, in which case it will read the file from standard input,
- allowing zip to take input from another program. For example:
-
- tar cf - . | zip backup -
-
- 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 zip can take
- advantage of redundancy between files. The backup can be restored using
- the command
-
- unzip -p backup | tar xf -
-
- When no zip file name is given and stdout is not a terminal, zip acts
- as a filter, compressing standard input to standard output. For exam-
- ple,
-
- tar cf - . | zip | dd of=/dev/nrst0 obs=16k
-
- is equivalent to
-
- tar cf - . | zip - - | dd of=/dev/nrst0 obs=16k
-
- zip archives created in this manner can be extracted with the program
- funzip which is provided in the unzip package, or by gunzip which is
- provided in the gzip package. For example:
-
- dd if=/dev/nrst0 ibs=16k | funzip | tar xvf -
-
- When changing an existing zip archive, 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.
-
- If the name of the zip archive does not contain an extension, the
- extension .zip is added. If the name already contains an extension
- other than .zip the existing extension is kept unchanged.
-
-OPTIONS
- -a [Systems using EBCDIC] Translate file to ASCII format.
-
- -A Adjust self-extracting executable archive. A self-extracting
- executable archive is created by prepending the SFX stub to an
- existing archive. The -A option tells zip to adjust the entry
- offsets stored in the archive to take into account this "pream-
- ble" data.
-
- Note: self-extracting archives for the Amiga are a special case. At
- present, only the Amiga port of Zip 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.
-
- -B [VM/CMS and MVS] force file to be read binary (default is text).
-
- -Bn [TANDEM] set Edit/Enscribe formatting options with n defined as
- bit 0: Don't add delimiter (Edit/Enscribe)
- bit 1: Use LF rather than CR/LF as delimiter (Edit/Enscribe)
- bit 2: Space fill record to maximum record length (Enscribe)
- bit 3: Trim trailing space (Enscribe)
- bit 8: Force 30K (Expand) large read for unstructured files
-
- -b path
- Use the specified path for the temporary zip archive. For exam-
- ple:
-
- zip -b /tmp stuff *
-
- will put the temporary zip archive in the directory /tmp, copy-
- ing over stuff.zip to the current directory when done. This
- option is only 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.
-
- -c 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.
-
- -d Remove (delete) entries from a zip archive. For example:
-
- zip -d foo foo/tom/junk foo/harry/\* \*.o
-
- will remove the entry foo/tom/junk, all of the files that start
- with foo/harry/, and all of the files that end with .o (in any
- path). Note that shell pathname expansion has been inhibited
- with backslashes, so that zip can see the asterisks, enabling
- zip to match on the contents of the zip archive instead of the
- contents of the current directory.
-
- Under systems where the shell does not expand wildcards, such as
- MSDOS, the backslashes are not needed. The above would then be
-
- zip -d foo foo/tom/junk foo/harry/* *.o
-
- Under MSDOS, -d is case sensitive when it matches names in the
- zip archive. This requires that file names be entered in upper
- case if they were zipped by PKZIP on an MSDOS system.
-
- -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.
-
- -D Do not create entries in the 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:
-
- ZIPOPT="-D"; export ZIPOPT
-
- (The variable ZIPOPT can be used for any option except -i and -x
- and can include several options.) The option -D is a shorthand
- for -x "*/" but the latter cannot be set as default in the
- ZIPOPT environment variable.
-
- -e Encrypt the contents of the 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, zip will exit
- with an error). The password prompt is repeated to save the
- user from typing errors.
-
- -E [OS/2] Use the .LONGNAME Extended Attribute (if found) as file-
- name.
-
- -f Replace (freshen) an existing entry in the zip archive only if
- it has been modified more recently than the version already in
- the zip archive; unlike the update option (-u) this will not add
- files that are not already in the zip archive. For example:
-
- zip -f foo
-
- This command should be run from the same directory from which
- the original zip command was run, since paths stored in zip
- archives are always relative.
-
- Note that the timezone environment variable TZ should be set
- according to the local timezone in order for the -f , -u and -o
- options to work correctly.
-
- 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).
-
- -F Fix the zip archive. This option can be used if some portions of
- the archive are missing. It is not guaranteed to work, so you
- MUST make a backup of the original archive first.
-
- When doubled as in -FF the compressed sizes given inside the
- damaged archive are not trusted and zip scans for special signa-
- tures to identify the limits between the archive members. The
- single -F is more reliable if the archive is not too much dam-
- aged, for example if it has only been truncated, so try this
- option first.
-
- Neither option will recover archives that have been incorrectly
- transferred in ascii mode instead of binary. After the repair,
- the -t option of unzip may show that some files have a bad CRC.
- Such files cannot be recovered; you can remove them from the
- archive using the -d option of zip.
-
- -g Grow (append to) the specified zip archive, instead of creating
- a new one. If this operation fails, 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.
-
- -h Display the zip help information (this also appears if zip is
- run with no arguments).
-
- -i files
- Include only the specified files, as in:
-
- zip -r foo . -i \*.c
-
- which will include only the files that end in .c in the current
- directory and its subdirectories. (Note for PKZIP users: the
- equivalent command is
-
- pkzip -rP foo *.c
-
- PKZIP does not allow recursion in directories other than the
- current one.) The backslash avoids the shell filename substitu-
- tion, so that the name matching is performed by zip at all
- directory levels. Not escaping wildcards on shells that do
- wildcard substitution before zip gets the command line may seem
- to work but files in subdirectories matching the pattern will
- never be checked and so not matched. For shells, such as Win32
- command prompts, that do not replace file patterns containing
- wildcards with the respective file names, zip will do the recur-
- sion and escaping the wildcards is not needed.
-
- Also possible:
-
- zip -r foo . -i@include.lst
-
- which will only include the files in the current directory and
- its subdirectories that match the patterns in the file
- include.lst.
-
- -I [Acorn RISC OS] Don't scan through Image files. When used, 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.
-
- For example, if you have SparkFS loaded, zipping a Spark archive
- will result in a zipfile containing a directory (and its con-
- tent) while using the 'I' option will result in a zipfile con-
- taining a Spark archive. Obviously this second case will also be
- obtained (without the 'I' option) if SparkFS isn't loaded.
-
- -j Store just the name of a saved file (junk the path), and do not
- store directory names. By default, zip will store the full path
- (relative to the current path).
-
- -jj [MacOS] record Fullpath (+ Volname). The complete path including
- volume will be stored. By default the relative path will be
- stored.
-
- -J Strip any prepended data (e.g. a SFX stub) from the archive.
-
- -k 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.
-
- -l Translate the Unix end-of-line character LF into the MSDOS con-
- vention 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 ensures that unzip -a on Unix
- will get back an exact copy of the original file, to undo the
- effect of zip -l. See the note on binary detection for -ll
- below.
-
- -ll Translate the MSDOS end-of-line CR LF into Unix LF. This option
- should not be used on binary files and a warning will be issued
- when a file is converted that later is detected to be binary.
- This option can be used on MSDOS if the zip file is intended for
- unzip under Unix.
-
- In Zip 2.31 binary detection has been changed from a simple per-
- centage of binary characters being considered binary to a more
- selective method that should consider files in many character
- sets, including UTF-8, that only include text characters in that
- character set to be text. This allows unzip -a to convert these
- files.
-
- -L Display the zip license.
-
- -m Move the specified files into the zip archive; actually, this
- deletes the target directories/files after making the specified
- zip archive. If a directory becomes empty after removal of the
- files, the directory is also removed. No deletions are done
- until 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 -T to test the archive
- before removing all input files.
-
- -n suffixes
- Do not attempt to compress files named with the given suffixes.
- Such files are simply stored (0% compression) in the output zip
- file, so that zip doesn't waste its time trying to compress
- them. The suffixes are separated by either colons or semi-
- colons. For example:
-
- zip -rn .Z:.zip:.tiff:.gif:.snd foo foo
-
- will copy everything from foo into foo.zip, but will store any
- files that end in .Z, .zip, .tiff, .gif, or .snd without trying
- to compress them (image and sound files often have their own
- specialized compression methods). By default, zip does not com-
- press files with extensions in the list
- .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:
-
- setenv ZIPOPT "-n .gif:.zip"
-
- To attempt compression on all files, use:
-
- zip -n : foo
-
- The maximum compression option -9 also attempts compression on
- all files regardless of extension.
-
- On Acorn RISC OS systems the suffixes are actually filetypes (3
- hex digit format). By default, zip does not compress files with
- filetypes in the list DDC:D96:68E (i.e. Archives, CFS files and
- PackDir files).
-
- -N [Amiga, MacOS] Save Amiga or MacOS filenotes as zipfile com-
- ments. They can be restored by using the -N option of unzip. If
- -c is used also, you are prompted for comments only for those
- files that do not have filenotes.
-
- -o Set the "last modified" time of the zip archive to the latest
- (oldest) "last modified" time found among the entries in the zip
- archive. This can be used without any other operations, if
- desired. For example:
-
- zip -o foo
-
- will change the last modified time of foo.zip to the latest time
- of the entries in foo.zip.
-
- -P password
- use password to encrypt zipfile entries (if any). THIS IS INSE-
- CURE! 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 pass-
- words. (And where security is truly important, use strong
- encryption such as Pretty Good Privacy instead of the relatively
- weak encryption provided by standard zipfile utilities.)
-
- -q Quiet mode; eliminate informational messages and comment
- prompts. (Useful, for example, in shell scripts and background
- tasks).
-
- -Qn [QDOS] store information about the file in the file header with
- n defined as
- bit 0: Don't add headers for any file
- bit 1: Add headers for all files
- bit 2: Don't wait for interactive key press on exit
-
- -r Travel the directory structure recursively; for example:
-
- zip -r foo foo
-
- In this case, all the files and directories in foo are saved in
- a zip archive named foo.zip, including files with names starting
- with ".", 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 foo and its subdirectories, use
- the -i option to specify the pattern of files to be included.
- You should not use -r with the name ".*", since that matches
- ".." which will attempt to zip up the parent directory (proba-
- bly not what was intended).
-
- -R Travel the directory structure recursively starting at the cur-
- rent directory; for example:
-
- zip -R foo '*.c'
-
- In this case, all the files matching *.c in the tree starting at
- the current directory are stored into a zip archive named
- foo.zip. Note for PKZIP users: the equivalent command is
-
- pkzip -rP foo *.c
-
- -S [MSDOS, OS/2, WIN32 and ATARI] Include system and hidden files.
- [MacOS] Includes finder invisible files, which are ignored oth-
- erwise.
-
- -t mmddyyyy
- Do not operate on files modified prior to the specified date,
- where mm is the month (0-12), dd is the day of the month (1-31),
- and yyyy is the year. The ISO 8601 date format yyyy-mm-dd is
- also accepted. For example:
-
- zip -rt 12071991 infamy foo
-
- zip -rt 1991-12-07 infamy foo
-
- will add all the files in foo and its subdirectories that were
- last modified on or after 7 December 1991, to the zip archive
- infamy.zip.
-
- -tt mmddyyyy
- Do not operate on files modified after or at the specified date,
- where mm is the month (0-12), dd is the day of the month (1-31),
- and yyyy is the year. The ISO 8601 date format yyyy-mm-dd is
- also accepted. For example:
-
- zip -rtt 11301995 infamy foo
-
- zip -rtt 1995-11-30 infamy foo
-
- will add all the files in foo and its subdirectories that were
- last modified before the 30 November 1995, to the zip archive
- infamy.zip.
-
- -T Test the integrity of the new zip file. If the check fails, the
- old zip file is unchanged and (with the -m option) no input
- files are removed.
-
- -u Replace (update) an existing entry in the zip archive only if it
- has been modified more recently than the version already in the
- zip archive. For example:
-
- zip -u stuff *
-
- will add any new files in the current directory, and update any
- files which have been modified since the zip archive stuff.zip
- was last created/modified (note that zip will not try to pack
- stuff.zip into itself when you do this).
-
- Note that the -u option with no arguments acts like the -f
- (freshen) option.
-
- -v Verbose mode or print diagnostic version info.
-
- Normally, when applied to real operations, this option enables
- the display of a progress indicator during compression and
- requests verbose diagnostic info about zipfile structure oddi-
- ties.
-
- When -v is the only command line argument, and either stdin or
- stdout is not redirected to a file, a diagnostic screen is
- printed. In addition to the help screen header with program
- name, version, and release date, some pointers to the Info-ZIP
- home and distribution sites are given. Then, it shows informa-
- tion about the target environment (compiler type and version, OS
- version, compilation date and the enabled optional features used
- to create the zip executable.
-
- -V [VMS] Save VMS file attributes and use portable form. zip
- archives created with this option are truncated at EOF but still
- may not be usable on other systems depending on the file types
- being zipped.
-
- -VV [VMS] Save VMS file attributes. zip archives created with this
- option include the entire file and should be able to recreate
- most VMS files on VMS systems but these archives will generally
- not be usable on other systems.
-
- -w [VMS] Append the version number of the files to the name,
- including multiple versions of files. (default: use only the
- most recent version of a specified file).
-
- -x files
- Explicitly exclude the specified files, as in:
-
- zip -r foo foo -x \*.o
-
- which will include the contents of foo in foo.zip while exclud-
- ing all the files that end in .o. The backslash avoids the
- shell filename substitution, so that the name matching is per-
- formed by zip at all directory levels. If you do not escape
- wildcards in patterns it may seem to work but files in subdirec-
- tories will not be checked for matches.
-
- Also possible:
-
- zip -r foo foo -x@exclude.lst
-
- which will include the contents of foo in foo.zip while exclud-
- ing all the files that match the patterns in the file
- exclude.lst (each file pattern on a separate line).
-
- -X Do not save extra file attributes (Extended Attributes on OS/2,
- uid/gid and file times on Unix).
-
- -y Store symbolic links as such in the zip archive, instead of com-
- pressing and storing the file referred to by the link (UNIX
- only).
-
- -z Prompt for a multi-line comment for the entire 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 VAX/VMS).
- The comment can be taken from a file:
-
- zip -z foo < foowhat
-
- -# Regulate the speed of compression using the specified digit #,
- where -0 indicates no compression (store all files), -1 indi-
- cates the fastest compression method (less compression) and -9
- indicates the slowest compression method (optimal compression,
- ignores the suffix list). The default compression level is -6.
-
- -! [WIN32] Use priviliges (if granted) to obtain all aspects of
- WinNT security.
-
- -@ Take the list of input files from standard input. Only one file-
- name per line.
-
- -$ [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:
-
- zip -$ foo a: c:bar
-
-EXAMPLES
- The simplest example:
-
- zip stuff *
-
- creates the archive stuff.zip (assuming it does not exist) and puts all
- the files in the current directory in it, in compressed form (the .zip
- suffix is added automatically, unless that archive name given contains
- a dot already; this allows the explicit specification of other suf-
- fixes).
-
- Because of the way the shell does filename substitution, files starting
- with "." are not included; to include these as well:
-
- zip stuff .* *
-
- Even this will not include any subdirectories from the current direc-
- tory.
-
- To zip up an entire directory, the command:
-
- zip -r foo foo
-
- creates the archive foo.zip, containing all the files and directories
- in the directory foo that is contained within the current directory.
-
- You may want to make a zip archive that contains the files in foo,
- without recording the directory name, foo. You can use the -j option
- to leave off the paths, as in:
-
- zip -j foo foo/*
-
- If you are short on disk space, you might not have enough room to hold
- both the original directory and the corresponding compressed zip
- archive. In this case, you can create the archive in steps using the
- -m option. If foo contains the subdirectories tom, dick, and harry,
- you can:
-
- zip -rm foo foo/tom
- zip -rm foo foo/dick
- zip -rm foo foo/harry
-
- where the first command creates foo.zip, and the next two add to it.
- At the completion of each zip command, the last created archive is
- deleted, making room for the next zip command to function.
-
-PATTERN MATCHING
- This section applies only to UNIX, though the ?, *, and [] special
- characters are implemented on other systems including MSDOS and Win32.
- Watch this space for details on MSDOS and VMS operation.
-
- The UNIX shells (sh(1) and csh(1)) do filename substitution on command
- arguments. The special characters are:
-
- ? match any single character
-
- * match any number of characters (including none)
-
- [] match any character in the range indicated within the brackets
- (example: [a-f], [0-9]).
-
- 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.
-
- The zip program can do the same matching on names that are in the zip
- archive being modified or, in the case of the -x (exclude) or -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 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 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 -x option, or does not
- match any name given with the -i option.
-
- 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 ("").
-
- In general, use backslash to make zip do the pattern matching with the
- -f (freshen) and -d (delete) options, and sometimes after the -x
- (exclude) option when used with an appropriate operation (add, -u, -f,
- or -d).
-
-ENVIRONMENT
- ZIPOPT contains default options that will be used when running zip
-
- ZIP [Not on RISC OS and VMS] see ZIPOPT
-
- Zip$Options
- [RISC OS] see ZIPOPT
-
- 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. zip
-
- ZIP_OPTS
- [VMS] see ZIPOPT
-
-SEE ALSO
- compress(1), shar(1L), tar(1), unzip(1L), gzip(1L)
-
-DIAGNOSTICS
- The exit status (or error level) approximates the exit codes defined by
- PKWARE and takes on the following values, except under VMS:
-
- 0 normal; no errors or warnings detected.
-
- 2 unexpected end of zip file.
-
- 3 a generic error in the zipfile format was detected. Pro-
- cessing may have completed successfully anyway; some bro-
- ken zipfiles created by other archivers have simple work-
- arounds.
-
- 4 zip was unable to allocate memory for one or more buffers
- during program initialization.
-
- 5 a severe error in the zipfile format was detected. Pro-
- cessing probably failed immediately.
-
- 6 entry too large to split (with zipsplit), read, or write
-
- 7 invalid comment format
-
- 8 zip -T failed or out of memory
-
- 9 the user aborted zip prematurely with control-C (or simi-
- lar)
-
- 10 zip encountered an error while using a temp file
-
- 11 read or seek error
-
- 12 zip has nothing to do
-
- 13 missing or empty zip file
-
- 14 error writing to a file
-
- 15 zip was unable to create a file to write to
-
- 16 bad command line parameters
-
- 18 zip could not open a specified file to read
-
- VMS interprets standard Unix (or PC) return values as other, scarier-
- looking things, so zip instead maps them into VMS-style status codes.
- The current mapping is as follows: 1 (success) for normal exit,
- and (0x7fff000? + 16*normal_zip_exit_status) for all errors, where the
- `?' is 0 (warning) for zip value 12, 2 (error) for the zip values 3, 6,
- 7, 9, 13, 16, 18, and 4 (fatal error) for the remaining ones.
-
-BUGS
- zip 2.31 is not compatible with PKUNZIP 1.10. Use zip 1.1 to produce
- zip files which can be extracted by PKUNZIP 1.10.
-
- zip files produced by zip 2.31 must not be updated by 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 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.
-
- Under VMS, not all of the odd file formats are treated properly. Only
- stream-LF format zip files are expected to work with zip. Others can
- be converted using Rahul Dhesi's BILF program. This version of zip
- handles some of the conversion internally. When using Kermit to trans-
- fer zip files from Vax to MSDOS, type "set file type block" on the Vax.
- When transfering from MSDOS to Vax, type "set file type fixed" on the
- Vax. In both cases, type "set file type binary" on MSDOS.
-
- Under VMS, zip hangs for file specification that uses DECnet syntax
- foo::*.*.
-
- On OS/2, zip cannot match some names, such as those including an excla-
- mation 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.
-
- Under OS/2, the amount of Extended Attributes displayed by DIR is (for
- compatibility) the amount returned by the 16-bit version of DosQuery-
- PathInfo(). 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. There-
- fore the value reported by zip (which uses this 32-bit-mode size) dif-
- fers from that reported by DIR. 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.
-
- Development of Zip 3.0 is underway. See that source distribution for
- many new features and the latest bug fixes.
-
-AUTHORS
- Copyright (C) 1997-2005 Info-ZIP.
-
- 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. Permission is granted to any individual or institution
- to use, copy, or redistribute this software so long as all of the orig-
- inal files are included, that it is not sold for profit, and that this
- copyright notice is retained.
-
- 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.
-
- Please send bug reports and comments to: zip-bugs at www.info-zip.org.
- For bug reports, please include the version of zip (see zip -h), the
- make options used to compile it (see zip -v), the machine and operating
- system in use, and as much additional information as possible.
-
-ACKNOWLEDGEMENTS
- Thanks to R. P. Byrne for his 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 zip file format, compression for-
- mat, and .ZIP filename extension, and for accepting minor changes to
- the file format; to Steve Burg for clarifications on the deflate for-
- mat; 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 ftp site
- for the Info-ZIP group to use; and most importantly, to the Info-ZIP
- group itself (listed in the file infozip.who) without whose tireless
- testing and bug-fixing efforts a portable zip would not have been pos-
- sible. 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.
-
-Info-ZIP 27 February 2005 (v2.31) ZIP(1L)
diff --git a/README b/README
index 3cd10c3..a559425 100644
--- a/README
+++ b/README
@@ -1,92 +1,170 @@
-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/license.html
-
-This is Zip 2.31, a maintenance update for Zip 2.3. Changes include a
-few bug fixes for Debian and SourceForge bugs, inclusion of the standard
-zip encryption code in the main code, some VMS updates, some changes to
-the Win32 projects, and some other bug fixes. We are also working on
-the new Zip 3.0 and companion UnZip 6.00 that finally support files and
-archives larger than 4 GB on systems that support large files and include
-other new features. See the latest betas for details and the new releases
-when available.
-
-Zip 2.31 is a compression and file packaging utility. It is compatible with
+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 the same place
-you got zip. See the file 'WHERE' for details on ftp sites and mail
+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.
-This version of zip has been ported to a wide array of Unix and other
-mainframes, minis, and micros including VMS, OS/2, Minix, MSDOS, Windows NT,
-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 WhatsNew for a summary of new features and the file 'CHANGES' for
-a detailed list of all changes.
-
-This version does not support multi-volume archives as in pkzip 2.04g.
-This is currently being looked at and may be provided in the release of
-Zip 3.0 if time permits.
-
-Please read the file INSTALL for information on how to compile and install
-zip, zipsplit, zipcloak, and zipnote. Please read the file MANUAL for
-information on how to use them. The file "contents" is a complete list
-of the files you should have in this distribution. Also, if you are
-using MSDOS, you should read the note on file formats at the end of the
-contents file. (The contents file somehow got misplaced apparently in
-the Zip 2.3 distribution. If time permits we will create a new one.)
-
-This version supports standard zip encryption. The encryption code was
-distributed separately before this version because of US export regulations but
-recent relaxing of export restrictions now allow the code to be included. Note
-that standard zip encryption is considered weak by today's standards. We are
-looking at adding strong encryption to a later release. Decryption can be made
-with unzip 5.0p1 or later, or with zipcloak.
-
-All bug reports should go to zip-bugs using the web form at www.info-zip.org,
-and suggestions for new features can be sent using the same form (although
-we don't promise to use all suggestions). Contact us to send patches as we
-currently don't have a standard way to do that. Patches should be sent as
-context diffs only (diff -c).
-
-If you're considering a port, please check in with zip-bugs FIRST,
+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.
-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 con-
-tributions, etc., send a two-line mail message containing the commands HELP
-and LIST (on separate lines in the body of the message, not on the subject
-line) to mxserver@lists.wku.edu. You'll receive two messages listing the
-various Info-ZIP mailing-list formats which are available (and also various
-unrelated lists) and instructions on how to subscribe to one or more of them
-(courtesy of Hunter Goatley). (Currently these are all discontinued but
-we are considering implementing new versions. However, a discussion
-group for Info-ZIP issues is at http://www.quicktopic.com/27/H/V6ZQZ54uKNL
-and can be used to discuss issues, request features, and is one place new
-betas and releases are announced.)
+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. Please get the latest version of unzip. See the file 'WHERE' for details.
+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
+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
+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
@@ -114,9 +192,11 @@ A. Zip is not a PKZIP clone and is not intended to be one. In some
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 singled quotes are needed to let the shell know that it should
- not expand the *.c argument but instead pass it on to the program)
+ 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?
@@ -125,9 +205,9 @@ 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
- zip-bugs at www.info-zip.org first. You must not distribute beta versions.
- The latest official distributions are on ftp.info-zip.org in directory
- /pub/archiving/zip and subdirectories as well as on mirror sites.
+ 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?
@@ -135,21 +215,20 @@ 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. Here is
- an example of a suitable notice:
+ 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: <Product> 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
- free and can be obtained as source code or executables from various
- anonymous-ftp sites, including ftp.info-zip.org:/pub/archiving/zip/*.
+ 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, so long as you include in your product an acknowledgment and an
- offer of the original compression sources for free or for a small
- copying fee, and make clear that there are no extra or hidden charges
- resulting from the use of the compression code by your product. In other
- words, you are allowed to sell only your own work, not ours. If you have
- special requirements contact us at zip-bugs at www.info-zip.org.
+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
index 79d4ca7..c777d19 100644
--- a/README.CR
+++ b/README.CR
@@ -1,14 +1,15 @@
_____________________________________________________________________________
- This is Info-ZIP's README.CR for zcrypt29.zip, last updated 28 February 2005.
+ 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 for all of these. This file both describes the history of this package
-and notes the current conditions for use. Check the comments at the top
-of crypt.c and crypt.h for additional information.
+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-
@@ -44,13 +45,15 @@ 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 written was 6.5, although older versions are still widespread.
+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 are compatible with PKZIP 2.04g. (Thanks to Phil
-Katz for accepting our suggested minor changes to the zipfile format.)
+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:
@@ -86,7 +89,8 @@ 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).
-To update previous versions using the zcrypt sources:
+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.
diff --git a/TODO b/TODO
index a3510a7..8d51732 100644
--- a/TODO
+++ b/TODO
@@ -1,72 +1,142 @@
-This is old. See Changes and WhatsNew for what has been implemented.
+Todo list (last updated 12 June 2008).
-(See the latest Zip 3.0 beta for an update to this list.)
+Features for next official version:
-Main features still missing 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)
+- 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()) ?
+- what to do with zip -F and zip -FF (readzipfile2()) ? (done?)
- profiling of the code
-- multi disk zip files
+- multi disk zip files (could be done)
- zipfile modification tool (Greg)
-- Implement -- option (Thomas Klauser, wiz@danbala.tuwien.ac.at)
-- don't add files with "Archive bit "
- or add files with "Archive bit " (uwe.becher@metronet.de)
+- 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
+- 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.
+ 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.
+ 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.
+ (as pkzip on Unix). This requires unzip support.
- zip -l should do ebcdic->ascii translation on CMS and MVS
-- zip as subroutine (zdig/241)
+- 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.
+ 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).
+ 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).
+ (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.
+ 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]!)
+ (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 "*".)
+ 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)
+ of new files allowed)
diff --git a/WHATSNEW b/WHATSNEW
index a0c1a2d..9e8d52b 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -1,29 +1,310 @@
-WhatsNew file for Zip 2.31
-
-(See Changes for details)
-
-New things in Zip 2.31
-
-- Crypt now part of source distribution (see Readme.cr)
-- Bug fixes:
- - Debian patch 001 - Converted quoted strings
- - Debian patch 002 - Makefile changes
- - Debian patch 003 - Build changes
- - Debian patch 004 - Changes to unix/configure
- - Debian patch 005 - Fix for FNMAX path bug
-- Split VMS -V into -V and -VV (see Manual)
-- New VC6 project files thanks to Cosmin
-- AtheOS port (thanks to Ruslan Nickolaev)
-- Add api.c kluge for zip32.dll to support Visual Basic
-- Binary detection changed from 20% binary to new algorithm
- that should better detect word processing files as binary
- and should accept UTF-8 files as text. This flags the file
- in the archive as TEXT or BINARY for use by UnZip for line
- end conversion (see proginfo/txtvsbin.txt)
-- License update
-- DJGPP fixes
-- Many Makefile updates
-- Fixes to ZipSplit, ZipNotes, and ZipCloak
+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 = <big> 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
@@ -34,6 +315,7 @@ New things in Zip 2.3
- 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
diff --git a/WHERE b/WHERE
index c5f6c0b..94a0d55 100644
--- a/WHERE
+++ b/WHERE
@@ -3,6 +3,9 @@ __________________________________________________________________________
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
diff --git a/acorn/GMakefile b/acorn/GMakefile
index e9f02bc..01842c4 100644
--- a/acorn/GMakefile
+++ b/acorn/GMakefile
@@ -25,14 +25,14 @@ LFLAGS2 = $(LIB)
#CFLAGS = $(CFLAGS) -DUSE_EF_UT_TIME
# object file lists
-OBJZ = o.zip o.zipfile o.zipup o.fileio o.util o.globals o.crc32 o.crctab \
+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.crctab o.crypt_ o.ttyio
+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
@@ -51,15 +51,13 @@ install: %.zip %.zipnote %.zipsplit %.zipcloak %.acorn.zipsfx \
o.api: c.api
$(CC) $(CFLAGS) -c c.api -o o.api
-o.crc32: c.crc32 $(ZIP_H)
+o.crc32: c.crc32 $(ZIP_H) h.crc32
$(CC) $(CFLAGS) -c c.crc32 -o o.crc32
-o.crctab: c.crctab $(ZIP_H)
- $(CC) $(CFLAGS) -c c.crctab -o o.crctab
-o.crypt: c.crypt $(ZIP_H) h.crypt h.ttyio
+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)
+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
@@ -71,26 +69,28 @@ o.ttyio: c.ttyio $(ZIP_H) h.crypt
$(CC) $(CFLAGS) -c c.ttyio -o o.ttyio
o.util: c.util $(ZIP_H)
$(CC) $(CFLAGS) -c c.util -o o.util
-o.zip: c.zip $(ZIP_H) h.crypt h.revision h.ttyio
+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.crypt h.revision h.ttyio
+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)
+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.crypt h.revision
+o.zipup: c.zipup $(ZIP_H) h.crc32 h.crypt h.revision
$(CC) $(CFLAGS) -c c.zipup -o o.zipup
-o.crypt_: c.crypt $(ZIP_H) h.crypt h.ttyio
+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)
+o.fileio_: c.fileio $(ZIP_H) h.crc32
$(CC) $(CFLAGS) -DUTIL -c c.fileio -o o.fileio_
-o.zipfile_: c.zipfile $(ZIP_H)
+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_
diff --git a/acorn/ReadMe.GMakefile b/acorn/ReadMe.GMakefile
index 714fe2d..8762cdb 100644
--- a/acorn/ReadMe.GMakefile
+++ b/acorn/ReadMe.GMakefile
@@ -12,3 +12,5 @@ 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/acornzip.c b/acorn/acornzip.c
index 8de308c..40debc0 100644
--- a/acorn/acornzip.c
+++ b/acorn/acornzip.c
@@ -1,7 +1,7 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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
@@ -425,6 +425,7 @@ iztimes *t; /* return value: access, modific. and creation times */
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);
@@ -437,7 +438,6 @@ iztimes *t; /* return value: access, modific. and creation times */
t->atime = t->mtime = t->ctime = label_utim;
return label_time;
}
-
if ((name = malloc(len + 1)) == NULL) {
ZIPERR(ZE_MEM, "filetime");
}
@@ -458,6 +458,7 @@ iztimes *t; /* return value: access, modific. and creation times */
free(name);
return 0;
}
+ free(name);
if (a != NULL) {
*a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE);
@@ -473,8 +474,6 @@ iztimes *t; /* return value: access, modific. and creation times */
t->ctime = s.st_ctime;
}
- free(name);
-
return unix2dostime((time_t *) &s.st_mtime);
}
diff --git a/acorn/makefile b/acorn/makefile
index 5aa1c5c..323ffca 100644
--- a/acorn/makefile
+++ b/acorn/makefile
@@ -26,14 +26,14 @@ LFLAGS2 = $(LIB) C:o.Stubs
#CFLAGS = $(CFLAGS) -DUSE_EF_UT_TIME
# object file lists
-OBJZ = zip.o zipfile.o zipup.o fileio.o util.o globals.o crc32.o crctab.o \
+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) crctab.o crypt_.o ttyio.o
+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
@@ -64,10 +64,14 @@ $(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
diff --git a/acorn/osdep.h b/acorn/osdep.h
index ea002ef..9f7783e 100644
--- a/acorn/osdep.h
+++ b/acorn/osdep.h
@@ -1,7 +1,7 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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
@@ -9,7 +9,7 @@
#include "riscos.h"
#define RISCOS
-#define NO_SYMLINK
+#define NO_SYMLINKS
#define NO_FCNTL_H
#define NO_UNISTD_H
#define NO_MKTEMP
diff --git a/acorn/riscos.c b/acorn/riscos.c
index eb1b897..84dd2d3 100644
--- a/acorn/riscos.c
+++ b/acorn/riscos.c
@@ -1,7 +1,7 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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
diff --git a/acorn/riscos.h b/acorn/riscos.h
index 2bbd72e..c45a148 100644
--- a/acorn/riscos.h
+++ b/acorn/riscos.h
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.htmlse.html
+ 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 */
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 |<archive> |<SEA>
+If "%0" = "" Then Error 220 Syntax: zipsfx |<archive> |<SEA>
+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/amiga/LMKfile b/amiga/LMKfile
index 6b6aa40..8c838ea 100644
--- a/amiga/LMKfile
+++ b/amiga/LMKfile
@@ -1,7 +1,7 @@
# 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: Jun 25, 1998
+# Last update: Jan 07, 2007
# -John Bush, <J.Bush@MD-B.Prime.COM>, <JBush@BIX.COM>
@@ -39,18 +39,19 @@ TMPFILE = ram:MakeZip.tmp
# object file macrough lists
-HFILES = zip.h ziperr.h tailor.h revision.h crypt.h ttyio.h amiga/amiga.h \
- amiga/zipup.h amiga/osdep.h
+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 crctab.o crypt.o \
- ttyio.o amiga.o amigazip.o time_lib.o
+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 amiga.o amigazip.oo time_lib.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) crctab.o crypt.oo ttyio.o
+OBJC = zipcloak.o $(OBJU) crc32.oo crypt.oo ttyio.o
OBJS = zipsplit.o $(OBJU)
ZIPS = zip zipnote zipcloak zipsplit
@@ -104,6 +105,7 @@ 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)
@@ -111,6 +113,5 @@ globals.o: globals.c $(HFILES)
# Amiga specific objects
amiga.o: amiga/amiga.c $(HFILES)
amigazip.o: amiga/amigazip.c $(HFILES)
-time_lib.o: amiga/time_lib.c
# end of Makefile
diff --git a/amiga/amiga.c b/amiga/amiga.c
index 93bd495..797d6d8 100644
--- a/amiga/amiga.c
+++ b/amiga/amiga.c
@@ -1,9 +1,9 @@
/*
Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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
+ 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.
@@ -43,6 +43,9 @@
* 26Aug97 PaulK Added ClearIOErr_exit()
*
* 2Jan98 HWalt Adapted for SAS/C using stat.c replacement functions
+ *
+ * 6Jun00 PaulK Removed references to time_lib, since new filedate.c
+ * supercedes it
*/
#include <exec/memory.h>
@@ -58,19 +61,11 @@
# include <proto/dos.h>
#endif
#include <stdlib.h>
-
-#ifndef ZCONST
-# define ZCONST const
-#endif
#include "ziperr.h"
-void ziperr(int c, ZCONST char *h);
-
-#if defined(AZTEC_C) || defined(__SASC)
-# define USE_TIME_LIB
-#endif
+void ziperr(int c, const char *h);
#define ZIP
-#if !defined(UTIL) && !defined(USE_TIME_LIB)
+#if !defined(UTIL)
# define NO_MKTIME
#endif
diff --git a/amiga/amigazip.c b/amiga/amigazip.c
index f72f27d..4e69d62 100644
--- a/amiga/amigazip.c
+++ b/amiga/amigazip.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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.info-zip.org/pub/infozip/license.html
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
#include "zip.h"
#include "amiga/amiga.h"
@@ -320,8 +320,9 @@ iztimes *t; /* return value: access, modific. and creation times */
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);
+ int len = strlen(f);
if (f == label) {
if (a != NULL)
@@ -332,7 +333,6 @@ iztimes *t; /* return value: access, modific. and creation times */
t->atime = t->mtime = t->ctime = label_utim;
return label_time;
}
-
if ((name = malloc(len + 1)) == NULL) {
ZIPERR(ZE_MEM, "filetime");
}
@@ -342,10 +342,8 @@ iztimes *t; /* return value: access, modific. and creation times */
/* not all systems allow stat'ing a file with / appended */
if (strcmp(f, "-") == 0) {
- if (fstat(fileno(stdin), &s) != 0) {
- free(name);
+ 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)
@@ -353,6 +351,7 @@ iztimes *t; /* return value: access, modific. and creation times */
free(name);
return 0;
}
+ free(name);
if (a != NULL) {
*a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE);
@@ -368,8 +367,6 @@ iztimes *t; /* return value: access, modific. and creation times */
t->ctime = s.st_ctime;
}
- free(name);
-
return unix2dostime(&s.st_mtime);
}
diff --git a/amiga/crc_68.a b/amiga/crc_68.a
index 809a0ba..4cc2a25 100644
--- a/amiga/crc_68.a
+++ b/amiga/crc_68.a
@@ -1,10 +1,10 @@
;===========================================================================
-; Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+; Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
;
-; See the accompanying file LICENSE, version 1999-Oct-05 or later
+; 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, both of these files are missing, the Info-ZIP license
-; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+; 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.
;
diff --git a/amiga/filedate.c b/amiga/filedate.c
index 84c7bed..9ccbdda 100644
--- a/amiga/filedate.c
+++ b/amiga/filedate.c
@@ -1,29 +1,27 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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()
- * locale_TZ()
- * getenv() [Aztec C only; replaces bad C library versions]
- * setenv() [ditto]
- * tzset() [ditto]
- * gmtime() [ditto]
- * localtime() [ditto]
- * time() [ditto]
+ * 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 nine are used by all Info-ZIP programs except fUnZip.
+ * 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 windowheight() in
- * amiga/amiga.c (UnZip). time() is used only by Zip.
+ * sendpkt() is used by Agetch() and FileDate(), and by screensize() in
+ * amiga/amiga.c (UnZip); time() is used only by Zip.
*/
@@ -89,6 +87,22 @@
* 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
@@ -102,6 +116,7 @@
#include <exec/types.h>
#include <exec/execbase.h>
#include <exec/memory.h>
+#include <dos/dosextens.h>
#ifdef AZTEC_C
# include <libraries/dos.h>
@@ -138,8 +153,9 @@
#include "crypt.h" /* just so we can tell if CRYPT is supported */
+#if (!defined(FUNZIP) && !defined(UTIL))
-#ifndef FUNZIP
+#include "timezone.h" /* for AMIGA-specific timezone callbacks */
#ifndef SUCCESS
# define SUCCESS (-1L)
@@ -151,39 +167,39 @@
extern struct ExecBase *SysBase;
-#ifndef USE_TIME_LIB
-#ifdef AZTEC_C /* should be pretty safe for reentrancy */
- long timezone = 0; /* already declared SAS/C external */
- int daylight = 0; /* likewise */
+#ifndef min
+# define min(a, b) ((a) < (b) ? (a) : (b))
+# define max(a, b) ((a) < (b) ? (b) : (a))
#endif
-int real_timezone_is_set = FALSE; /* set by tzset() */
-#endif /* !USE_TIME_LIB */
+
+#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);
-/* !!!! We have really got to find a way to operate without this. */
+void set_TZ(long time_zone, int day_light);
#endif
-LONG FileDate (char *filename, time_t u[]);
+LONG FileDate(char *filename, time_t u[]);
LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs);
int Agetch(void);
-/* prototypes for time replacement functions */
-#ifndef USE_TIME_LIB
- void tzset(void);
- int locale_TZ(void);
- struct tm *gmtime(const time_t *when);
- struct tm *localtime(const time_t *when);
-# ifdef __SASC
- extern void set_TZ(long time_zone, int day_light); /* in time_lib.c */
-# endif
-# ifdef ZIP
- time_t time(time_t *tp);
-# endif
-#endif /* !USE_TIME_LIB */
-
/* =============================================================== */
/***********************/
@@ -213,20 +229,6 @@ int Agetch(void);
* date modified.
*/
-/* 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)
-
-/* Accumulated number of days from 01-Jan up to start of current month. */
-#ifdef ZIP
-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
-
LONG FileDate(filename, u)
char *filename;
time_t u[];
@@ -244,7 +246,7 @@ LONG FileDate(filename, u)
struct tm *ltm;
int years;
- /* tzset(); */
+ tzset();
/* Amiga file date is based on 01-Jan-1978 00:00:00 (local time):
* 8 years and 2 leapdays difference from Unix time.
*/
@@ -253,9 +255,8 @@ LONG FileDate(filename, u)
if (years < 1978)
pDate.ds_Days = pDate.ds_Minute = pDate.ds_Tick = 0;
else {
- pDate.ds_Days = (years - 1978) * 365L + (nleap(years) - 2) +
- ((ltm->tm_mon > 1 && leap(years)) ? 1 : 0) +
- ydays[ltm->tm_mon] + (ltm->tm_mday - 1);
+ 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;
}
@@ -327,7 +328,7 @@ char *getenv(const char *var) /* not reentrant! */
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)
+ 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;
@@ -358,7 +359,7 @@ int setenv(const char *var, const char *value, int overwrite)
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);
+ ret = !SetVar((char *)var, (char *)value, -1, GVF_GLOBAL_ONLY | LV_VAR);
else {
BPTR hand, foot, spine;
long len = value ? strlen(value) : 0;
@@ -377,13 +378,39 @@ int setenv(const char *var, const char *value, int overwrite)
me->pr_WindowPtr = old_window;
return ret;
}
-#endif /* __SASC */
-
-#ifndef USE_TIME_LIB
+/* 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 timezone and daylight to settings found in locale.library */
-int locale_TZ(void)
+/* 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;
@@ -396,17 +423,59 @@ int locale_TZ(void)
me->pr_WindowPtr = (void *) -1; /* suppress any "Please insert" popups */
if (LocaleBase = OpenLibrary("locale.library", 0)) {
if (ll = OpenLocale(NULL)) {
- z = ll->loc_GMTOffset;
+ z = ll->loc_GMTOffset; /* in minutes */
if (z == -300) {
- if (eh = Lock("ENV:sys/locale.prefs", ACCESS_READ))
+ if (eh = Lock("ENV:sys/locale.prefs", ACCESS_READ)) {
UnLock(eh);
- else
- z = 300; /* bug: locale not initialized, default is bogus! */
+ valid = TRUE;
+ } else
+ z = 300; /* bug: locale not initialized, default bogus! */
} else
- real_timezone_is_set = TRUE;
- timezone = z * 60;
- daylight = (z >= 4*60 && z <= 9*60); /* apply in the Americas */
- valid = TRUE;
+ 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);
@@ -415,128 +484,22 @@ int locale_TZ(void)
return valid;
}
-void tzset(void)
-{
- char *p,*TZstring;
- int z,valid = FALSE;
-
- if (real_timezone_is_set)
- return;
- timezone = 0; /* default is GMT0 which means no offsets */
- daylight = 0; /* from local system time */
- TZstring = getenv("TZ"); /* read TZ envvar */
- if (TZstring && TZstring[0]) { /* TZ exists and has contents? */
- z = 3600;
- for (p = TZstring; *p && !isdigit(*p) && *p != '-'; p++) ;
- if (*p == '-')
- z = -3600, p++;
- if (*p) {
- timezone = 0;
- do {
- while (isdigit(*p))
- timezone = timezone * 10 + z * (*p++ - '0'), valid = TRUE;
- if (*p == ':') p++;
- } while (isdigit(*p) && (z /= 60) > 0);
- }
- while (isspace(*p)) p++; /* probably not needed */
- if (valid) {
- real_timezone_is_set = TRUE;
- daylight = !!*p; /* a DST name part exists */
- }
- }
- if (!valid)
- locale_TZ(); /* read locale.library */
-#ifdef __SASC
- /* Some SAS/C library functions, e.g. stat(), call library */
- /* __tzset() themselves. So envvar TZ *must* exist in order to */
- /* to get the right offset from GMT. XXX WE SHOULD TRY HARD */
- /* find and replace any remaining functions that need this! */
- set_TZ(timezone, daylight);
-#endif /* __SASC */
-}
-
-
-struct tm *gmtime(const time_t *when)
-{
- static struct tm tbuf; /* this function is intrinsically non-reentrant */
- static short smods[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- long days = *when / 86400;
- long secs = *when % 86400;
- short yell, yday;
-
- tbuf.tm_wday = (days + 4) % 7; /* 1/1/70 is a Thursday */
- tbuf.tm_year = 70 + 4 * (days / 1461);
- yday = days % 1461;
- while (yday >= (yell = (tbuf.tm_year & 3 ? 365 : 366)))
- yday -= yell, tbuf.tm_year++;
- smods[1] = (tbuf.tm_year & 3 ? 28 : 29);
- tbuf.tm_mon = 0;
- tbuf.tm_yday = yday;
- while (yday >= smods[tbuf.tm_mon])
- yday -= smods[tbuf.tm_mon++];
- tbuf.tm_mday = yday + 1;
- tbuf.tm_isdst = 0;
- tbuf.tm_sec = secs % 60;
- tbuf.tm_min = (secs / 60) % 60;
- tbuf.tm_hour = secs / 3600;
-#ifdef AZTEC_C
- tbuf.tm_hsec = 0; /* this field exists for Aztec only */
-#endif
- return &tbuf;
-}
-
-struct tm *localtime(const time_t *when)
-{
- struct tm *t;
- time_t localwhen;
- int dst = FALSE, sundays, lastweekday;
-
- tzset();
- localwhen = *when - timezone;
- t = gmtime(&localwhen);
- /* So far we support daylight savings correction by the USA rule only: */
- if (daylight && t->tm_mon >= 3 && t->tm_mon <= 9) {
- if (t->tm_mon > 3 && t->tm_mon < 9) /* May Jun Jul Aug Sep: yes */
- dst = TRUE;
- else {
- sundays = (t->tm_mday + 6 - t->tm_wday) / 7;
- if (t->tm_wday == 0 && t->tm_hour < 2 && sundays)
- sundays--; /* a Sunday does not count until 2:00am */
- if (t->tm_mon == 3 && sundays > 0) /* first sunday in April */
- dst = TRUE;
- else if (t->tm_mon == 9) {
- lastweekday = (t->tm_wday + 31 - t->tm_mday) % 7;
- if (sundays < (37 - lastweekday) / 7)
- dst = TRUE; /* last sunday in October */
- }
- }
- if (dst) {
- localwhen += 3600;
- t = gmtime(&localwhen); /* crude but effective */
- t->tm_isdst = 1;
- }
- }
- return t;
-}
-
-
-# ifdef ZIP
+#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) * 86400;
+ + (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 /* !USE_TIME_LIB */
+#endif /* ZIP */
-#endif /* !FUNZIP */
+#endif /* !FUNZIP && !UTIL */
#if CRYPT || !defined(FUNZIP)
diff --git a/amiga/makefile.azt b/amiga/makefile.azt
index 08f1cee..d9390c8 100644
--- a/amiga/makefile.azt
+++ b/amiga/makefile.azt
@@ -1,37 +1,41 @@
# 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 25 Jun 98
+# -- 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
-# ASM_CRC now serves only as a notation for "Zip -L".
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
+# -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
-# used for compiling a low-memory-use version of Zip
-
-LOWFLAGD = $(CFLAGD) -d $(WSIZ) -d SMALL_MEM
-# for the debuggable low-memory-use version
-
-ASOPTS = -n -eAMIGA -eDYN_ALLOC -eCPUTEST -eINT16
LOWASOPTS = $(ASOPTS) -e$(WSIZ) -eSMALL_MEM
# Options used for assembling amiga/deflate.a; must generally match the
-# settings in DEFINES. LOWASOPTS are for the low-memory version.
+# settings in DEFINES.
-LD = ln
-LDLIBS = -lc16
-LDFLAGS = -m +q
+# -------- MINIMUM MEMORY USAGE DEBUG VERSION:
+LOWFLAGD = $(CFLAGD) -d $(WSIZ) -d SMALL_MEM
-LDFLAGD = -m +q -g -w
+# the directory where we stick all the object files:
+O = obA/
# default C rules
@@ -55,7 +59,7 @@ LDFLAGD = -m +q -g -w
.c.dd :
$(CC) $(CFLAGD) -d UTIL -o $@ $*.c
-# rules for the low-memory version:
+# rules for the debugging low-memory version:
.c.dl :
$(CC) $(LOWFLAGD) -o $@ $*.c
@@ -63,43 +67,49 @@ LDFLAGD = -m +q -g -w
# object file lists
-ZIP_H = zip.h ziperr.h tailor.h amiga/osdep.h amiga/z-stat.h amiga/z-time.h
+ZIP_H = zip.h ziperr.h tailor.h amiga/osdep.h amiga/z-stat.h
-OBJZ = zip.o deflate.o trees.o zipfile.o zipup.o util.o \
- fileio.o globals.o amiga/amiga.o amiga/amigazip.o amiga/crc_68.o \
- amiga/time_lib.o crctab.o crypt.o ttyio.o
+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 = zip.ol deflate.ol trees.ol zipfile.ol \
- zipup.ol util.ol fileio.ol globals.ol crypt.ol ttyio.ol crctab.ol \
- amiga/amiga.ol amiga/amigazip.ol amiga/crc_68.o amiga/time_lib.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 = zipfile.oo fileio.oo util.oo globals.o amiga/amiga.oo \
- amiga/amigazip.oo amiga/time_lib.o
-OBJN = zipnote.o $(OBJU)
-OBJC = zipcloak.o $(OBJU) crctab.o crypt.oo ttyio.o
-OBJS = zipsplit.o $(OBJU)
+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 = zip.od deflate.od trees.od zipfile.od zipup.od \
- util.od fileio.od globals.od amiga/amiga.od amiga/amigazip.od \
- amiga/crc_68.o amiga/time_lib.od crctab.od crypt.od ttyio.od
+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 = zip.dl deflate.dl trees.dl zipfile.dl zipup.dl util.dl \
- fileio.dl globals.dl amiga/amiga.dl amiga/amigazip.dl amiga/crc_68.o \
- amiga/time_lib.od crctab.dl crypt.dl ttyio.dl
+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 = zipfile.dd fileio.dd util.dd globals.od amiga/amiga.dd \
- amiga/amigazip.dd amiga/time_lib.od
-DBJN = zipnote.od $(DBJU)
-DBJC = zipcloak.od $(DBJU) crctab.od crypt.dd ttyio.od
-DBJS = zipsplit.od $(DBJU)
+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
+all : Zip ZipNote ZipSplit ZipCloak ZipLM
z : Zip
@@ -113,7 +123,7 @@ l : ZipLM
# Debug versions:
-dall : Zip.dbg ZipNote.dbg ZipSplit.dbg ZipCloak.dbg
+dall : Zip.dbg ZipNote.dbg ZipSplit.dbg ZipCloak.dbg ZipLM.dbg
dz : Zip.dbg
@@ -166,14 +176,14 @@ ZipLM.dbg : $(DBJL) $(ZIP_H)
clean : bugclean
-delete quiet $(OBJZ)
-delete quiet $(OBJL)
- -delete quiet zipnote.o zipcloak.o zipsplit.o \
- crypt.oo $(OBJU)
+ -delete quiet $(O)zipnote.o $(O)zipcloak.o $(O)zipsplit.o \
+ $(O)crypt.oo $(OBJU)
bugclean :
-delete quiet $(DBJZ)
-delete quiet $(DBJL)
- -delete quiet zipnote.od zipcloak.od zipsplit.od \
- crypt.dd $(DBJU)
+ -delete quiet $(O)zipnote.od $(O)zipcloak.od $(O)zipsplit.od \
+ $(O)crypt.dd $(DBJU)
cleaner : clean
-delete quiet Zip ZipNote ZipSplit ZipCloak ZipLM
@@ -182,101 +192,113 @@ cleaner : clean
# header dependencies:
-zip.o zipnote.o zipcloak.o zipsplit.o crypt.o ttyio.o deflate.o \
- trees.o zipfile.o zipup.o fileio.o util.o crctab.o \
- globals.o amiga/amiga.o : $(ZIP_H)
+$(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)
-zip.ol zipnote.ol zipcloak.ol zipsplit.ol crypt.ol ttyio.ol deflate.ol \
- trees.ol zipfile.ol zipup.ol fileio.ol util.ol crctab.ol \
- globals.ol amiga/amiga.ol : $(ZIP_H)
+$(O)amigazip.o $(O)amigazip.ol $(O)amigazip.oo : amiga/amiga.h $(ZIP_H)
-crypt.oo zipfile.oo fileio.oo util.oo : $(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
-amiga/amigazip.o amiga/amigazip.ol amiga/amigazip.oo : amiga/amiga.h $(ZIP_H)
+$(O)amiga.o $(O)amiga.ol : crypt.h
-zip.o zipnote.o zipcloak.o zipsplit.o zipup.o \
- zip.ol zipnote.ol zipcloak.ol zipsplit.ol zipup.ol : revision.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
-amiga/amiga.o amiga/amiga.ol : crypt.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
-crypt.o crypt.oo crypt.ol ttyio.o ttyio.ol zipcloak.o zipcloak.ol \
- zip.o zip.ol zipup.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
-zipup.o zipup.ol : amiga/zipup.h
+$(O)zipup.o $(O)zipup.ol : amiga/zipup.h
# SPECIAL CASES:
# -mr changes expression parsing; avoids a bogus "expression too complex" error:
-trees.o : trees.c
+$(O)trees.o : trees.c
$(CC) $(CFLAGS) -mr -o $@ trees.c
-trees.ol : trees.c
+$(O)trees.ol : trees.c
$(CC) $(LOWFLAGS) -mr -o $@ trees.c
-trees.od : trees.c
+$(O)trees.od : trees.c
$(CC) $(CFLAGD) -mr -o $@ trees.c
-trees.ld : 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)
-deflate.o : amiga/deflate.a
+$(O)deflate.o : amiga/deflate.a
$(AS) $(ASOPTS) -o $@ amiga/deflate.a
-deflate.ol : amiga/deflate.a
+$(O)deflate.ol : amiga/deflate.a
$(AS) $(LOWASOPTS) -o $@ amiga/deflate.a
# The assembly CRC function:
-amiga/crc_68.o : amiga/crc_68.a
+$(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:
-amiga/amiga.o : amiga/amiga.c amiga/filedate.c amiga/stat.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
-amiga/amiga.ol : amiga/amiga.c amiga/filedate.c amiga/stat.c
+$(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
-amiga/amiga.od : amiga/amiga.c amiga/filedate.c amiga/stat.c
+$(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
-amiga/amiga.ld : amiga/amiga.c amiga/filedate.c amiga/stat.c
+$(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
-amiga/amiga.oo : amiga/amiga.c amiga/filedate.c amiga/stat.c
+$(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
-amiga/amiga.dd : amiga/amiga.c amiga/filedate.c amiga/stat.c
+$(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:
-amiga/amigazip.o : amiga/amigazip.c
+$(O)amigazip.o : amiga/amigazip.c
$(CC) $(CFLAGS) -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c
-amiga/amigazip.ol : amiga/amigazip.c
+$(O)amigazip.ol : amiga/amigazip.c
$(CC) $(LOWFLAGS) -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c
-amiga/amigazip.od : amiga/amigazip.c
+$(O)amigazip.od : amiga/amigazip.c
$(CC) $(CFLAGD) -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c
-amiga/amigazip.ld : amiga/amigazip.c
+$(O)amigazip.ld : amiga/amigazip.c
$(CC) $(LOWFLAGD) -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c
-amiga/amigazip.oo : amiga/amigazip.c
+$(O)amigazip.oo : amiga/amigazip.c
$(CC) $(CFLAGS) -d UTIL -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c
-amiga/amigazip.dd : 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/osdep.h b/amiga/osdep.h
index a5851e3..c573cf8 100644
--- a/amiga/osdep.h
+++ b/amiga/osdep.h
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 1999-Oct-05 or later
+ 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.cdrom.com/pub/infozip/license.html
+ 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
@@ -19,6 +19,16 @@
# 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
@@ -28,9 +38,6 @@
void ClearIOErr_exit(int e);
#include "amiga/z-stat.h"
-#ifndef USE_TIME_LIB
-# define NO_MKTIME
-#endif
#ifdef __SASC
# include <sys/types.h>
@@ -53,9 +60,10 @@ void ClearIOErr_exit(int e);
# ifdef DEBUG
# include <sprof.h> /* profiler header file */
# endif
- /* define USE_TIME_LIB if replacement functions of time_lib are available */
- /* replaced are: tzset(), time(), localtime() and gmtime() */
-# define USE_TIME_LIB
+# 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?)
@@ -75,20 +83,22 @@ void ClearIOErr_exit(int e);
# 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
-# define USE_TIME_LIB
+# ifndef IZTZ_DEFINESTDGLOBALS
+# define IZTZ_DEFINESTDGLOBALS
+# endif
#endif
-#ifdef USE_TIME_LIB
extern int real_timezone_is_set;
-# define VALID_TIMEZONE(tempvar) (tzset(), real_timezone_is_set)
-#else
-# define VALID_TIMEZONE(tempvar) ((tempvar = getenv("TZ")) && tempvar[0])
-#endif
+void tzset(void);
+#define VALID_TIMEZONE(tempvar) (tzset(), real_timezone_is_set)
#ifdef ZCRYPT_INTERNAL
# ifndef CLIB_EXEC_PROTOS_H
diff --git a/amiga/smakefile b/amiga/smakefile
index a772fcb..ce1317d 100644
--- a/amiga/smakefile
+++ b/amiga/smakefile
@@ -1,6 +1,6 @@
#===========================================================================
# Makefile for Zip, ZipNote, ZipCloak, ZipSplit AMIGA SAS/C Version 6.58
-# Version: 2.3 last revised: 24 Aug 98
+# Version: 2.3 last revised: 07 Jan 2007
#===========================================================================
# -John Bush, <John.Bush@East.Sun.COM>
# or: <JBush@Bix.COM>
@@ -359,15 +359,15 @@ ASMOPTSL = $(AFLAGS) $(ALOWMEM) # Zip low-mem version asm flags
# Zip objects
OBJZ1 = zip$(O) zipfile$(O) zipup$(O) fileio$(O) util$(O) globals$(O)
-OBJZ2 = crc32$(O) crctab$(O) crypt$(O) ttyio$(O)
+OBJZ2 = crc32$(O) crypt$(O) timezone$(O) ttyio$(O)
OBJZI = deflate$(O) trees$(O)
-OBJZA = amiga$(O) amigazip$(O) time_lib$(O) stat$(O) filedate$(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) util$(OU)
-OBJUA = amigazip$(OU) amiga$(O) time_lib$(O) stat$(O) filedate$(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
@@ -377,7 +377,7 @@ OBJN = $(OBJN1) $(OBJU)
# ZipCloak objects
OBJC1 = zipcloak$(O)
OBJCU = $(OBJU) crypt$(OU)
-OBJCS = crctab$(O) ttyio$(O)
+OBJCS = crc32$(OU) ttyio$(O)
OBJC = $(OBJC1) $(OBJCU) $(OBJCS)
#ZipSplit objects
@@ -386,14 +386,14 @@ OBJS = $(OBJS1) $(OBJU)
# ZipLM objects
OBJL1 = zip$(OL) zipfile$(OL) zipup$(OL) fileio$(OL) util$(OL) globals$(OL)
-OBJL2 = crc32$(OL) crctab$(OL) crypt$(OL) ttyio$(OL)
+OBJL2 = crc32$(OL) crypt$(OL) timezone$(OL) ttyio$(OL)
OBJLI = deflate$(OL) trees$(OL)
-OBJLA = amiga$(OL) amigazip$(OL) time_lib$(O) stat$(O) filedate$(O)
+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 amiga/z-time.h
+ZIP_HA = amiga/osdep.h amiga/z-stat.h
ZIP_H = $(ZIP_H1) $(ZIP_HA)
# Output targets
@@ -429,14 +429,6 @@ all: request flush $(ZIPS)
$(CC) WITH=$(CFILE) $(CUSEMEM) DEF=UTIL LISTFILE=$>$(LISTEXTU) OBJNAME=$@ $*.c
-########################
-# Special target rules #
-########################
-
-# Special rule to build time_lib.o for Zip (requires NO_MKTIME define)
-time_lib$(O):
- $(CC) WITH=$(CFILE) $(CUSEMEM) DEF=ZIP LISTFILE=$>$(LISTEXTZ) OBJNAME=$@ $*.c
-
#########################
# Final output targets. #
#########################
@@ -511,22 +503,21 @@ spotless: clean
# Zip dependencies:
#
-zip$(O): zip.c $(ZIP_H) revision.h crypt.h ttyio.h
-zipup$(O): zipup.c $(ZIP_H) revision.h crypt.h amiga/zipup.h
-zipfile$(O): zipfile.c $(ZIP_H) revision.h
-crypt$(O): crypt.c $(ZIP_H) crypt.h ttyio.h
+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)
-util$(O): util.c $(ZIP_H) mktime.c
-crc32$(O): crc32.c $(ZIP_H)
-crctab$(O): crctab.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 amiga/z-time.h
-filedate$(O): amiga/filedate.c amiga/z-time.h crypt.h
-time_lib$(O): amiga/time_lib.c amiga/z-time.h
+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:
@@ -537,33 +528,33 @@ amigazip$(O): amiga/amigazip.c $(ZIP_H) amiga/amiga.h env:Workbench
# Utility (ZipNote, ZipCloak, ZipSplit) dependencies:
#
zipnote$(O): zipnote.c $(ZIP_H) revision.h
-zipcloak$(O): zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.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
-fileio$(OU): fileio.c $(ZIP_H)
-util$(OU): util.c $(ZIP_H) mktime.c
-crypt$(OU): crypt.c $(ZIP_H) crypt.h ttyio.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 crypt.h ttyio.h
-zipup$(OL): zipup.c $(ZIP_H) revision.h crypt.h amiga/zipup.h
-zipfile$(OL): zipfile.c $(ZIP_H) revision.h
-crypt$(OL): crypt.c $(ZIP_H) crypt.h ttyio.h
+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)
-util$(OL): util.c $(ZIP_H) mktime.c
+fileio$(OL): fileio.c $(ZIP_H) crc32.h
+util$(OL): util.c $(ZIP_H)
crc32$(OL): crc32.c $(ZIP_H)
-crctab$(OL): crctab.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 amiga/z-time.h
-filedate$(OL): amiga/filedate.c amiga/z-time.h crypt.h
-time_lib$(OL): amiga/time_lib.c amiga/z-time.h
+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
diff --git a/amiga/stat.c b/amiga/stat.c
index c453273..6075c21 100644
--- a/amiga/stat.c
+++ b/amiga/stat.c
@@ -1,9 +1,9 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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() */
@@ -114,7 +114,7 @@ struct stat *buf;
(86400 * 8 * 365 ) +
(86400 * 2 ); /* two leap years */
- tzset();
+ /* tzset(); */ /* this should be handled by mktime(), instead */
/* ftime += timezone; */
local_tm = *gmtime(&ftime);
local_tm.tm_isdst = -1;
diff --git a/amiga/time_lib.c b/amiga/time_lib.c
deleted file mode 100644
index 2804c05..0000000
--- a/amiga/time_lib.c
+++ /dev/null
@@ -1,541 +0,0 @@
-#define __amiga_time_lib_c
-
-/* -----------------------------------------------------------------------------
-This source is copyrighted by Norbert Pueschel <pueschel@imsdd.meb.uni-bonn.de>
-From 'clockdaemon.readme':
-(available from Aminet, main site is ftp.wustl.edu:/pub/aminet/ under
- util/time/clockdaemon.lha)
-"The original SAS/C functions gmtime, localtime, mktime and time do not
-work correctly. The supplied link library time.lib contains replacement
-functions for them."
-The time.lib library consists of three parts (time.c, timezone.c and version.c),
-all included here. [time.lib 1.2 (1997-04-02)]
-Permission is granted to the Info-ZIP group to redistribute the time.lib source.
-The use of time.lib functions in own, noncommercial programs is permitted.
-It is only required to add the timezone.doc to such a distribution.
-Using the time.lib library in commercial software (including Shareware) is only
-permitted after prior consultation of the author.
-------------------------------------------------------------------------------*/
-/* History */
-/* 30 Mar 1997, Haidinger Walter, added AVAIL_GETVAR macro to support OS <V36 */
-/* 24 May 1997, Haidinger Walter, added NO_MKTIME macro to allow use of Zip's */
-/* mktime.c. NO_MKTIME must be defined in the makefile, though. */
-/* 25 May 1997, Haidinger Walter, moved set_TZ() here from filedate.c */
-/* 20 Jul 1997, Paul Kienitz, adapted for Aztec C, added mkgmtime(), */
-/* debugged, and made New York settings default, as is common. */
-/* 30 Sep 1997, Paul Kienitz, restored real_timezone_is_set flag */
-/* 19 Oct 1997, Paul Kienitz, corrected 16 bit multiply overflow bug */
-/* 21 Oct 1997, Chr. Spieler, shortened long lines, removed more 16 bit stuff */
-/* (n.b. __stdoffset and __dstoffset now have to be long ints) */
-/* 25 Oct 1997, Paul Kienitz, cleanup, make tzset() not redo work needlessly */
-/* 29 Oct 1997, Chr. Spieler, initialized globals _TZ, real_timezone_is_set */
-/* 31 Dec 1997, Haidinger Walter, created z-time.h to overcome sas/c header */
-/* dependencies. TZ_ENVVAR macro added. Happy New Year! */
-/* 25 Apr 1998, Chr. Spieler, __timezone must always contain __stdoffset */
-/* 28 Apr 1998, Chr. Spieler, P. Kienitz, changed __daylight to standard usage */
-
-#ifdef __SASC
-# include <proto/dos.h>
-# include <proto/locale.h>
-# include <proto/exec.h>
- /* this setenv() is in amiga/filedate.c */
- extern int setenv(const char *var, const char *value, int overwrite);
-#else
-# include <clib/dos_protos.h>
-# include <clib/locale_protos.h>
-# include <clib/exec_protos.h>
-# include <pragmas/exec_lib.h>
-# include <pragmas/dos_lib.h>
-# include <pragmas/locale_lib.h>
-/* Info-ZIP accesses these by their standard names: */
-# define __timezone timezone
-# define __daylight daylight
-# define __tzset tzset
-#endif
-#define NO_TIME_H
-#include "amiga/z-time.h"
-#include <exec/execbase.h>
-#include <clib/alib_stdio_protos.h>
-#include <string.h>
-#include <stdlib.h>
-
-extern struct ExecBase *SysBase;
-extern char *getenv(const char *var);
-
-typedef unsigned long time_t;
-struct tm {
- int tm_sec; /* seconds after the minute */
- int tm_min; /* minutes after the hour */
- int tm_hour; /* hours since midnight */
- int tm_mday; /* day of the month */
- int tm_mon; /* months since January */
- int tm_year; /* years since 1900 */
- int tm_wday; /* days since Sunday */
- int tm_yday; /* days since January 1 */
- int tm_isdst; /* Daylight Savings Time flag */
-};
-struct dstdate {
- enum { JULIAN0, JULIAN, MWD } dd_type;
- int dd_day;
- int dd_week;
- int dd_month;
- int dd_secs;
-};
-static struct dstdate __dststart;
-static struct dstdate __dstend;
-
-#define isleapyear(y) (((y)%4==0&&(!((y)%100==0)||((y)%400==0)))?1:0)
-#define yearlen(y) (isleapyear(y)?366:365)
-#define weekday(d) (((d)+4)%7)
-#define jan1ofyear(y) (((y)-70)*365+((y)-69)/4-((y)-1)/100+((y)+299)/400)
-#define wdayofyear(y) weekday(jan1ofyear(y))
-#define AMIGA2UNIX 252460800 /* seconds between 1.1.1970 and 1.1.1978 */
-#define CHECK 300 /* min. time between checks of IXGMTOFFSET */
-#define GETVAR_REQVERS 36L /* required OS version for GetVar() */
-#define AVAIL_GETVAR (SysBase->LibNode.lib_Version >= GETVAR_REQVERS)
-#ifndef TZ_ENVVAR
-# define TZ_ENVVAR "TZ" /* environment variable to parse */
-#endif
-
-#ifdef __SASC
- extern int __daylight;
- extern long __timezone;
- extern char *__tzname[2];
- extern char *_TZ;
-#else
- int __daylight;
- long __timezone;
- char *__tzname[2];
- char *_TZ = NULL;
-#endif
-int real_timezone_is_set = FALSE; /* globally visible TZ_is_valid signal */
-char __tzstn[MAXTIMEZONELEN];
-char __tzdtn[MAXTIMEZONELEN];
-/* the following 4 variables are only used internally; make them static ? */
-int __isdst;
-time_t __nextdstchange;
-long __stdoffset;
-long __dstoffset;
-#define TZLEN 64
-static char TZ[TZLEN];
-static struct tm TM;
-static const unsigned short days[2][13] = {
- { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
- { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
-};
-#ifndef NO_MKTIME /* only used by mktime() */
-static const unsigned short monlen[2][12] = {
- { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
- { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
-};
-#endif
-
-/* internal prototypes */
-static time_t dst2time(int year,struct dstdate *dst);
-static void time2tm(time_t time);
-static int checkdst(time_t time);
-#ifndef NO_MKTIME
-static void normalize(int *i,int *j,int norm);
-#endif
-static long gettime(char **s);
-static void getdstdate(char **s,struct dstdate *dst);
-#ifdef __SASC
-void set_TZ(long time_zone, int day_light);
-#endif
-
-/* prototypes for sc.lib replacement functions */
-struct tm *gmtime(const time_t *t);
-struct tm *localtime(const time_t *t);
-#ifndef NO_MKTIME
-time_t mkgmtime(struct tm *tm);
-time_t mktime(struct tm *tm);
-#endif
-time_t time(time_t *tm);
-void __tzset(void);
-
-
-static time_t dst2time(int year,struct dstdate *dst)
-{
- int isleapyear,week,mon,mday;
- mon = 0;
- mday = dst->dd_day;
- isleapyear = isleapyear(year);
- switch(dst->dd_type) {
- case JULIAN:
- if(!isleapyear || dst->dd_day <= 59) break;
- default:
- mday++;
- break;
- case MWD:
- mon = dst->dd_month-1;
- week = dst->dd_week;
- if(week == 5) {
- mon++;
- week = 0;
- }
- mday = dst->dd_day - weekday(jan1ofyear(year)+days[isleapyear][mon]);
- if(mday < 0) mday += 7;
- mday += (week - 1) * 7 + 1;
- break;
- }
- return((time_t)(jan1ofyear(year)+days[isleapyear][mon]+mday-1)*(time_t)86400L+
- (time_t)dst->dd_secs);
-}
-
-static void time2tm(time_t time)
-{
- int isleapyear;
- TM.tm_sec = time % 60;
- time /= 60;
- TM.tm_min = time % 60;
- time /= 60;
- TM.tm_hour = time % 24;
- time /= 24;
- TM.tm_year = time/365 + 70; /* guess year */
- while((TM.tm_yday = time - jan1ofyear(TM.tm_year)) < 0) TM.tm_year--;
- isleapyear = isleapyear(TM.tm_year);
- for(TM.tm_mon = 0;
- TM.tm_yday >= days[isleapyear][TM.tm_mon+1];
- TM.tm_mon++);
- TM.tm_mday = TM.tm_yday - days[isleapyear][TM.tm_mon] + 1;
- TM.tm_wday = (time+4)%7;
-}
-
-static int checkdst(time_t time)
-{
- int year,day;
- time_t t,u;
- day = time / 86400L;
- year = day / 365 + 70; /* guess year */
- while(day - jan1ofyear(year) < 0) year--;
- t = dst2time(year,&__dststart) + __stdoffset;
- u = dst2time(year,&__dstend) + __dstoffset;
- if(u > t) {
- return((time >= t && time < u)?1:0);
- }
- else {
- return((time < u || time >= t)?1:0);
- }
-}
-
-struct tm *gmtime(const time_t *t)
-{
- TM.tm_isdst = 0;
- time2tm(*t);
- return(&TM);
-}
-
-struct tm *localtime(const time_t *t)
-{
- if(!_TZ) __tzset();
- TM.tm_isdst = checkdst(*t);
- time2tm(*t - (TM.tm_isdst ? __dstoffset : __stdoffset));
- return(&TM);
-}
-
-#ifndef NO_MKTIME /* normalize() only used by mktime() */
-static void normalize(int *i,int *j,int norm)
-{
- while(*i < 0) {
- *i += norm;
- (*j)--;
- }
- while(*i >= norm) {
- *i -= norm;
- (*j)++;
- }
-}
-
-time_t mkgmtime(struct tm *tm)
-{
- time_t t;
- normalize(&tm->tm_sec,&tm->tm_min,60);
- normalize(&tm->tm_min,&tm->tm_hour,60);
- normalize(&tm->tm_hour,&tm->tm_mday,24);
- normalize(&tm->tm_mon,&tm->tm_year,12);
- while(tm->tm_mday > monlen[isleapyear(tm->tm_year)][tm->tm_mon]) {
- tm->tm_mday -= monlen[isleapyear(tm->tm_year)][tm->tm_mon];
- tm->tm_mon++;
- if(tm->tm_mon == 12) {
- tm->tm_mon = 0;
- tm->tm_year++;
- }
- }
- while(tm->tm_mday < 0) {
- tm->tm_mon--;
- if(tm->tm_mon == -1) {
- tm->tm_mon = 11;
- tm->tm_year--;
- }
- tm->tm_mday += monlen[isleapyear(tm->tm_year)][tm->tm_mon];
- }
- tm->tm_yday = tm->tm_mday + days[isleapyear(tm->tm_year)][tm->tm_mon] - 1;
- t = jan1ofyear(tm->tm_year) + tm->tm_yday;
- tm->tm_wday = weekday(t);
- if(tm->tm_year < 70) return((time_t)0);
- t = t * 86400L + tm->tm_hour * 3600L + tm->tm_min * 60L + (time_t)tm->tm_sec;
- return(t);
-}
-
-time_t mktime(struct tm *tm)
-{
- time_t t;
- if(!_TZ) __tzset();
- t = mkgmtime(tm);
- if(tm->tm_isdst < 0) tm->tm_isdst = checkdst(t);
- t += tm->tm_isdst ? __dstoffset : __stdoffset;
- return(t);
-}
-#endif /* !NO_MKTIME */
-
-static long gettime(char **s)
-{
- long num,time;
- for(num = 0;**s >= '0' && **s <= '9';(*s)++) {
- num = 10*num + (**s - '0');
- }
- time = 3600L * num;
- if(**s == ':') {
- (*s)++;
- for(num = 0;**s >= '0' && **s <= '9';(*s)++) {
- num = 10*num + (**s - '0');
- }
- time += 60 * num;
- if(**s == ':') {
- (*s)++;
- for(num = 0;**s >= '0' && **s <= '9';(*s)++) {
- num = 10*num + (**s - '0');
- }
- time += num;
- }
- }
- return(time);
-}
-
-static void getdstdate(char **s,struct dstdate *dst)
-{
- switch(**s) {
- case 'J':
- case 'j':
- (*s)++;
- dst->dd_type = JULIAN;
- for(dst->dd_day = 0;**s >= '0' && **s <= '9';(*s)++) {
- dst->dd_day = 10*dst->dd_day + (**s - '0');
- }
- break;
- case 'M':
- case 'm':
- (*s)++;
- dst->dd_type = MWD;
- for(dst->dd_month = 0;**s >= '0' && **s <= '9';(*s)++) {
- dst->dd_month = 10*dst->dd_month + (**s - '0');
- }
- if(**s != '.') return;
- (*s)++;
- for(dst->dd_week = 0;**s >= '0' && **s <= '9';(*s)++) {
- dst->dd_week = 10*dst->dd_week + (**s - '0');
- }
- if(**s != '.') return;
- (*s)++;
- for(dst->dd_day = 0;**s >= '0' && **s <= '9';(*s)++) {
- dst->dd_day = 10*dst->dd_day + (**s - '0');
- }
- break;
- default:
- dst->dd_type = JULIAN0;
- for(dst->dd_day = 0;**s >= '0' && **s <= '9';(*s)++) {
- dst->dd_day = 10*dst->dd_day + (**s - '0');
- }
- break;
- }
- if(**s == '/') {
- (*s)++;
- dst->dd_secs = gettime(s);
- }
-}
-
-void __tzset(void)
-{
- char *s,*t;
- int minus = 0;
- time_t tm;
- struct Library *LocaleBase;
- struct Locale *loc = NULL;
- if (real_timezone_is_set)
- return;
- real_timezone_is_set = TRUE;
- __dststart.dd_secs = __dstend.dd_secs = 7200;
- __dststart.dd_type = __dstend.dd_type = MWD;
- __dststart.dd_month = 4;
- __dststart.dd_week = 1;
- __dstend.dd_month = 10;
- __dstend.dd_week = 5;
- __dststart.dd_day = __dstend.dd_day = 0; /* sunday */
- _TZ = NULL;
- if (AVAIL_GETVAR) { /* GetVar() available? */
- if(GetVar(TZ_ENVVAR,TZ,TZLEN,GVF_GLOBAL_ONLY) > 0)
- _TZ = TZ;
- } else
- _TZ = getenv(TZ_ENVVAR);
- if (_TZ == NULL || !_TZ[0]) {
- static char gmt[MAXTIMEZONELEN] = DEFAULT_TZ_STR;
- LocaleBase = OpenLibrary("locale.library",0);
- if(LocaleBase) {
- loc = OpenLocale(0); /* cannot return null */
- if (loc->loc_GMTOffset == -300 || loc->loc_GMTOffset == 300) {
- BPTR eh;
- if (eh = Lock("ENV:sys/locale.prefs", ACCESS_READ))
- UnLock(eh);
- else {
- real_timezone_is_set = FALSE;
- loc->loc_GMTOffset = 300; /* Amigados bug: default when locale is */
- } /* not initialized can have wrong sign */
- }
- sprintf(gmt, "GMT%ld:%02ld", loc->loc_GMTOffset / 60L,
- labs(loc->loc_GMTOffset) % 60L);
- CloseLocale(loc);
- CloseLibrary(LocaleBase);
- } else
- real_timezone_is_set = FALSE;
- _TZ = gmt;
- }
- for(s = _TZ,t = __tzstn;*s && *s != '+' && *s != '-' && *s != ',' &&
- (*s < '0' || *s > '9');s++) {
- if(t-__tzstn < MAXTIMEZONELEN-1) *(t++) = *s;
- }
- *t = '\0';
- if(*s == '+') {
- s++;
- }
- else {
- if(*s == '-') {
- minus = 1;
- s++;
- }
- }
- __stdoffset = gettime(&s);
- if(minus) {
- __stdoffset *= -1;
- }
- if(*s) {
- minus = 0;
- for(t = __tzdtn;*s && *s != '+' && *s != '-' && *s != ',' &&
- (*s < '0' || *s > '9');s++) {
- if(t-__tzdtn < MAXTIMEZONELEN-1) *(t++) = *s;
- }
- *t = '\0';
- if(*s == '+') {
- s++;
- }
- else {
- if(*s == '-') {
- minus = 1;
- s++;
- }
- }
- if(*s && *s != ',') {
- __dstoffset = gettime(&s);
- if(minus) {
- __dstoffset *= -1;
- }
- }
- else {
- __dstoffset = __stdoffset - 3600L;
- }
- if(*s == ',') {
- s++;
- getdstdate(&s,&__dststart);
- if(*s == ',') {
- s++;
- getdstdate(&s,&__dstend);
- }
- }
- }
- else {
- __dstoffset = __stdoffset;
- }
- time2tm(time(&tm));
- __isdst = checkdst(tm);
- __daylight = (__dstoffset != __stdoffset);
- __timezone = __stdoffset;
- __nextdstchange = dst2time(TM.tm_year, __isdst ? &__dstend : &__dststart);
- if(tm >= __nextdstchange) {
- __nextdstchange = dst2time(TM.tm_year+1,
- __isdst ? &__dstend : &__dststart);
- }
- __tzname[0] = __tzstn;
- __tzname[1] = __tzdtn;
-#ifdef __SASC
- if (loc) /* store TZ envvar if data read from locale */
- set_TZ(__timezone, __daylight);
-#endif
-}
-
-time_t time(time_t *tm)
-{
- static time_t last_check = 0;
- static struct _ixgmtoffset {
- LONG Offset;
- UBYTE DST;
- UBYTE Null;
- } ixgmtoffset;
- static char *envvarstr; /* ptr to environm. string (used if !AVAIL_GETVAR) */
- struct DateStamp ds;
- time_t now;
- DateStamp(&ds);
- now = ds.ds_Days * 86400L + ds.ds_Minute * 60L +
- ds.ds_Tick / TICKS_PER_SECOND;
- if(now - last_check > CHECK) {
- last_check = now;
- if (AVAIL_GETVAR) /* GetVar() available? */
- if(GetVar("IXGMTOFFSET",(STRPTR)&ixgmtoffset,6,
- GVF_BINARY_VAR|GVF_GLOBAL_ONLY) == -1) {
- __tzset();
- ixgmtoffset.Offset = __isdst ? __dstoffset : __stdoffset;
- }
- else
- if (envvarstr=getenv("IXGMTOFFSET")) {
- ixgmtoffset = *((struct _ixgmtoffset *)envvarstr); /* copy to struct */
- __tzset();
- ixgmtoffset.Offset = __isdst ? __dstoffset : __stdoffset;
- }
- }
- now += AMIGA2UNIX;
- now += ixgmtoffset.Offset;
- if(tm) *tm = now;
- return(now);
-}
-
-#ifdef __SASC
-
-/* 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 */
- if (AVAIL_GETVAR)
- exists = (void *)FindVar(TZ_ENVVAR,GVF_GLOBAL_ONLY); /* OS V36+ */
- else
- 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");
- if (AVAIL_GETVAR) /* store TZ to ENV:TZ. */
- SetVar(TZ_ENVVAR,put_tz,-1,GVF_GLOBAL_ONLY); /* OS V36+ */
- else
- setenv(TZ_ENVVAR,put_tz, 1);
- }
-}
-#endif /* __SASC */
diff --git a/amiga/z-stat.h b/amiga/z-stat.h
index bb33b34..53d6cd1 100644
--- a/amiga/z-stat.h
+++ b/amiga/z-stat.h
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 1999-Oct-05 or later
+ 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, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+ 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
@@ -33,7 +33,7 @@
# include <dos.h>
#endif
#include <libraries/dos.h>
-#include "amiga/z-time.h"
+#include <time.h>
struct stat {
diff --git a/amiga/z-time.h b/amiga/z-time.h
deleted file mode 100644
index 53c01bf..0000000
--- a/amiga/z-time.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- 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_z_time_h
-#define __amiga_z_time_h
-
-/* A <time.h> replacement for use with time_lib.c */
-/* Usage: * Define (or Undefine) USE_TIME_LIB below */
-/* * Replace any <time.h> includes by "amiga/z-time.h" */
-
-/* First of all: Select whether to use time_lib functions or not */
-#if 1
-# ifndef USE_TIME_LIB
-# define USE_TIME_LIB
-# endif
-#else
-# ifdef USE_TIME_LIB
-# undef USE_TIME_LIB
-# endif
-#endif
-
-#ifdef USE_TIME_LIB
- /* constants needed everywhere */
-# define MAXTIMEZONELEN 16
-# ifndef DEFAULT_TZ_STR
-# define DEFAULT_TZ_STR "EST5EDT" /* US East Coast is the usual default */
-# endif
-
- /* define time_t where needed (everywhere but amiga/time_lib.c) */
-# if defined(__SASC) && defined(NO_TIME_H) && !defined(__amiga_time_lib_c)
- typedef unsigned long time_t; /* override sas/c's time_t */
-# define _TIME_T 1 /* mark it as already defined */
-# define _COMMTIME_H /* do not include sys/commtime.h */
-# endif
-
-# ifndef NO_TIME_H
-# include <time.h> /* time_lib.c uses NO_TIME_H */
-# endif
-
- /* adjust included time.h */
-# ifdef __SASC
- /* tz[sd]tn arrays have different length now: need different names */
-# define __tzstn tzstn
-# define __tzdtn tzdtn
- /* prevent other possible name conflicts */
-# define __nextdstchange nextdstchange
-# define __stdoffset stdoffset
-# define __dstoffset dstoffset
-
-# ifndef __amiga_time_lib_c
-# ifdef TZ
-# undef TZ /* defined in sas/c time.h */
-# endif TZ
-# define TZ DEFAULT_TZ_STR /* redefine TZ to default timezone */
- extern char __tzstn[MAXTIMEZONELEN];
- extern char __tzdtn[MAXTIMEZONELEN];
-# endif
-# endif /* __SASC */
-
-# ifdef AZTEC_C
- void tzset(void);
-# endif
-
-#else /* ?USE_TIME_LIB */
-
-# ifndef NO_TIME_H
-# include <time.h>
-# endif
-#endif /* !USE_TIME_LIB */
-
-#endif /* __amiga_z_time_h */
diff --git a/aosvs/aosvs.c b/aosvs/aosvs.c
index 3add126..f944ad1 100644
--- a/aosvs/aosvs.c
+++ b/aosvs/aosvs.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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.info-zip.org/pub/infozip/license.html
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
#include <dirent.h>
#include <time.h>
@@ -294,8 +294,9 @@ iztimes *t; /* return value: access, modific. and creation times */
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);
+ int len = strlen(f);
if (f == label) {
if (a != NULL)
@@ -306,7 +307,6 @@ iztimes *t; /* return value: access, modific. and creation times */
t->atime = t->mtime = t->ctime = label_utim;
return label_time;
}
-
if ((name = malloc(len + 1)) == NULL) {
ZIPERR(ZE_MEM, "filetime");
}
@@ -316,10 +316,8 @@ iztimes *t; /* return value: access, modific. and creation times */
/* not all systems allow stat'ing a file with / appended */
if (strcmp(f, "-") == 0) {
- if (fstat(fileno(stdin), &s) != 0) {
- free(name);
+ 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)
@@ -327,6 +325,7 @@ iztimes *t; /* return value: access, modific. and creation times */
free(name);
return 0;
}
+ free(name);
if (a != NULL) {
*a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE);
@@ -342,8 +341,6 @@ iztimes *t; /* return value: access, modific. and creation times */
t->ctime = s.st_ctime;
}
- free(name);
-
return unix2dostime(&s.st_ctime);
}
diff --git a/aosvs/make.cli b/aosvs/make.cli
index 304e799..32b2624 100644
--- a/aosvs/make.cli
+++ b/aosvs/make.cli
@@ -1,5 +1,5 @@
push
prompt pop
sea :c_4.10 :c_4.10:lang_rt [!sea]
-cc%0/%/link/NOUNX AOS_VS/DEFINE NODIR/DEFINE <ZIP CRC32 CRCTAB CRYPT DEFLATE FILEIO GLOBALS MKTIME TREES TTYIO UTIL ZIPFILE ZIPUP AOSVS>.C
+cc%0/%/link/NOUNX AOS_VS/DEFINE NODIR/DEFINE <ZIP CRC32 CRYPT DEFLATE FILEIO GLOBALS MKTIME TREES TTYIO UTIL ZIPFILE ZIPUP AOSVS>.C
pop
diff --git a/api.c b/api.c
index fc35b60..b6f57e7 100644
--- a/api.c
+++ b/api.c
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ api.c - Zip 3
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*---------------------------------------------------------------------------
@@ -17,9 +19,7 @@
ZpVer *ZpVersion(void);
int EXPENTRY ZpInit(LPZIPUSERFUNCTIONS lpZipUserFunc);
- BOOL EXPENTRY ZpSetOptions(LPZPOPT Opts);
- ZPOPT EXPENTRY ZpGetOptions(void);
- int EXPENTRY ZpArchive(ZCL C);
+ 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
@@ -28,6 +28,7 @@
---------------------------------------------------------------------------*/
#define __API_C
+#include <malloc.h>
#ifdef WINDLL
# include <windows.h>
# include "windll/windll.h"
@@ -57,62 +58,200 @@ extern DLLCOMMENT *lpComment;
ZIPUSERFUNCTIONS ZipUserFunctions, far * lpZipUserFunctions;
int ZipRet;
-
-/* ------------------------------------------------- */
-/* Visual Basic converts strings from VB native Unicode to
- byte strings when passing to dlls. It seems that any
- strings pointed to in structures are converted and the
- conversion passed to the dll, but when the dll call
- returns the converted strings are garbage collected
- unless the debugger prevents it. This leaves the
- pointers going to memory that may have been reused
- by the time the following dll call is made. This
- affects the strings in the Options stucture.
-
- The following kluge stores the strings locally in
- the dll between calls. A better fix is to redesign
- the api interface so that strings in structures are
- removed or are passed in the same call they are used. EG
-
-/* oversized to be sure */
-#define MAX_ZIP_DATE_LEN 50
-#define MAX_ZIP_DIR_PATH_LEN 4098
-
-char szDate[MAX_ZIP_DATE_LEN + 1];
-char szRootDir[MAX_ZIP_DIR_PATH_LEN + 1];
-char szTempDir[MAX_ZIP_DIR_PATH_LEN + 1];
-/* ------------------------------------------------- */
+char szOrigDir[PATH_MAX];
+BOOL fNo_int64 = FALSE; /* flag for DLLSERVICE_NO_INT64 */
/* Local forward declarations */
extern int zipmain OF((int, char **));
-int AllocMemory(int, char *, char *);
+int AllocMemory(unsigned int, char *, char *, BOOL);
+int ParseString(LPSTR, unsigned int);
+void FreeArgVee(void);
ZPOPT Options;
char **argVee;
-int argCee;
+unsigned int argCee;
/*---------------------------------------------------------------------------
Local functions
---------------------------------------------------------------------------*/
-int AllocMemory(int i, char *cmd, char *str)
+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)
{
-int j;
if ((argVee[i] = (char *) malloc( sizeof(char) * strlen(cmd)+1 )) == NULL)
{
- for (j = 0; j < i; j++)
- {
- free (argVee[j]);
- argVee[j] = NULL;
- }
- free(argVee);
+ 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
---------------------------------------------------------------------------*/
@@ -129,52 +268,43 @@ if (!lpZipUserFunctions->print ||
return TRUE;
}
-BOOL EXPENTRY ZpSetOptions(LPZPOPT Opts)
+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 */
{
-/* copy the structure including pointers to strings */
-Options = *Opts;
-
-/* fix for calling dll from VB - 2002-11-25 */
-/* make copies of strings in structure if not NULL passed for empty string */
-if (Options.Date) {
- szDate[0] = '\0';
- strncat(szDate, Options.Date, MAX_ZIP_DATE_LEN);
- Options.Date = szDate;
-}
-if (Options.szRootDir) {
- szRootDir[0] = '\0';
- strncat(szRootDir, Options.szRootDir, MAX_ZIP_DIR_PATH_LEN);
- Options.szRootDir = szRootDir;
-}
-if (Options.szTempDir) {
- szTempDir[0] = '\0';
- strncat(szTempDir, Options.szTempDir, MAX_ZIP_DIR_PATH_LEN);
- Options.szTempDir = szTempDir;
-}
+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);
-return TRUE;
-}
+getcwd(szOrigDir, PATH_MAX); /* Save current drive and directory */
-ZPOPT EXPENTRY ZpGetOptions(void)
-{
-#if CRYPT
-Options.fEncryption = TRUE;
-#else
-Options.fEncryption = FALSE;
-#endif
-return Options;
-}
+if ((szRootDir != NULL) && (szRootDir[0] != '\0'))
+ {
+ /* Make sure there isn't a trailing slash */
+ if (szRootDir[lstrlen(szRootDir)-1] == '\\')
+ szRootDir[lstrlen(szRootDir)-1] = '\0';
-int EXPENTRY ZpArchive(ZCL C)
-/* Add, update, freshen, or delete zip entries in a zip file. See the
- command help in help() zip.c */
-{
-int i, k, j, m;
-char szOrigDir[PATH_MAX];
+ chdir(szRootDir);
+#ifdef __BORLANDC__
+ setdisk(toupper(szRootDir[0]) - 'A');
+#endif
+ }
argCee = 0;
-/* malloc additional 26 to allow for additional command line arguments */
-if ((argVee = (char **)malloc((C.argc+26)*sizeof(char *))) == NULL)
+
+/* 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;
@@ -188,279 +318,363 @@ if ((argVee[argCee] = (char *) malloc( sizeof(char) * strlen("wiz.exe")+1 )) ==
strcpy( argVee[argCee], "wiz.exe" );
argCee++;
+
/* Set compression level efficacy -0...-9 */
-if (AllocMemory(argCee, "-0", "Compression") != ZE_OK)
- return ZE_MEM;
-argVee[argCee][1] = Options.fLevel;
-argCee++;
+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") != ZE_OK)
- return ZE_MEM;
- argCee++;
- }
+ 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") != ZE_OK)
- return ZE_MEM;
- argCee++;
+ 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") != ZE_OK)
- return ZE_MEM;
- argCee++;
+ 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") != ZE_OK)
- return ZE_MEM;
- argCee++;
+ 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") != ZE_OK)
- return ZE_MEM;
+ if (AllocMemory(argCee, "-F", "Repair", FALSE) != ZE_OK)
+ return ZE_MEM;
}
else
{
- if (AllocMemory(argCee, "-FF", "Repair") != ZE_OK)
- return ZE_MEM;
+ if (AllocMemory(argCee, "-FF", "Repair", FALSE) != ZE_OK)
+ return ZE_MEM;
}
- argCee++;
}
if (Options.fGrow) /* Allow appending to a zip file -g */
{
- if (AllocMemory(argCee, "-g", "Appending") != ZE_OK)
- return ZE_MEM;
- argCee++;
+ 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") != ZE_OK)
- return ZE_MEM;
- argCee++;
+ if (AllocMemory(argCee, "-j", "Junk Dir Names", FALSE) != ZE_OK)
+ return ZE_MEM;
}
if (Options.fEncrypt) /* encrypt -e */
{
- if (AllocMemory(argCee, "-e", "Encrypt") != ZE_OK)
- return ZE_MEM;
- argCee++;
+ if (AllocMemory(argCee, "-e", "Encrypt", FALSE) != ZE_OK)
+ return ZE_MEM;
}
if (Options.fJunkSFX) /* Junk sfx prefix */
{
- if (AllocMemory(argCee, "-J", "Junk SFX") != ZE_OK)
- return ZE_MEM;
- argCee++;
+ 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") != ZE_OK)
- return ZE_MEM;
- argCee++;
+ 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") != ZE_OK)
- return ZE_MEM;
- argCee++;
+ 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") != ZE_OK)
- return ZE_MEM;
- argCee++;
+ 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") != ZE_OK)
- return ZE_MEM;
- argCee++;
+ 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") != ZE_OK)
- return ZE_MEM;
- argCee++;
+ if (AllocMemory(argCee, "-o", "Time", FALSE) != ZE_OK)
+ return ZE_MEM;
}
if (Options.fComment) /* Add archive comment "-z" */
{
- if (AllocMemory(argCee, "-z", "Comment") != ZE_OK)
- return ZE_MEM;
- argCee++;
+ if (AllocMemory(argCee, "-z", "Comment", FALSE) != ZE_OK)
+ return ZE_MEM;
}
if (Options.fQuiet) /* quiet operation -q */
{
- if (AllocMemory(argCee, "-q", "Quiet") != ZE_OK)
- return ZE_MEM;
- argCee++;
+ 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") != ZE_OK)
- return ZE_MEM;
- argCee++;
+ 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") != ZE_OK)
- return ZE_MEM;
- argCee++;
- if (AllocMemory(argCee, Options.Date, "Date") != ZE_OK)
- return ZE_MEM;
- argCee++;
- }
+ 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") != ZE_OK)
- return ZE_MEM;
- argCee++;
- if (AllocMemory(argCee, Options.Date, "Date") != ZE_OK)
- return ZE_MEM;
- argCee++;
- }
+ 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") != ZE_OK)
- return ZE_MEM;
- argCee++;
- }
+ {
+ 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") != ZE_OK)
- return ZE_MEM;
- argCee++;
- }
+ {
+ if (AllocMemory(argCee, "-v", "Verbose", FALSE) != ZE_OK)
+ return ZE_MEM;
+ }
if (Options.fVolume) /* Include volume label -$ */
- {
- if (AllocMemory(argCee, "-$", "Volume") != ZE_OK)
- return ZE_MEM;
- argCee++;
- }
-#ifdef NTSD_EAS /* was WIN32 1/22/2005 EG */
+ {
+ 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") != ZE_OK)
- return ZE_MEM;
- argCee++;
+ if (AllocMemory(argCee, "-!", "Privileges", FALSE) != ZE_OK)
+ return ZE_MEM;
}
#endif
if (Options.fExtra) /* Exclude extra attributes -X */
- {
- if (AllocMemory(argCee, "-X", "Extra") != ZE_OK)
- return ZE_MEM;
- argCee++;
- }
-if ((Options.szTempDir != NULL) && (Options.szTempDir[0] != '\0')
- && Options.fTemp) /* Use temporary directory -b */
- {
- if (AllocMemory(argCee, "-b", "Temp dir switch command") != ZE_OK)
- return ZE_MEM;
- argCee++;
- if (AllocMemory(argCee, Options.szTempDir, "Temporary directory") != ZE_OK)
- return ZE_MEM;
- argCee++;
- }
-/* -r and -R moved down here to avoid VB problem 1/31/2005 EG */
-if (Options.fRecurse == 1) /* recurse into subdirectories -r */
- {
- if (AllocMemory(argCee, "-r", "Recurse -r") != ZE_OK)
- return ZE_MEM;
- argCee++;
- }
-else if (Options.fRecurse == 2) /* recurse into subdirectories -R */
- {
- if (AllocMemory(argCee, "-R", "Recurse -R") != ZE_OK)
- return ZE_MEM;
- argCee++;
- }
-if (AllocMemory(argCee, C.lpszZipFN, "Zip file name") != ZE_OK)
- return ZE_MEM;
-argCee++;
-
-getcwd(szOrigDir, PATH_MAX); /* Save current drive and directory */
+ {
+ 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 ((Options.szRootDir != NULL) && (Options.szRootDir[0] != '\0'))
- {
- chdir(Options.szRootDir);
-#ifdef __BORLANDC__
- setdisk(toupper(Options.szRootDir[0]) - 'A');
-#endif
- lstrcat(Options.szRootDir, "\\"); /* append trailing \\ */
- if (C.FNV != NULL)
- {
- for (k = 0; k < C.argc; k++)
- {
- if (AllocMemory(argCee, C.FNV[k], "Making argv") != ZE_OK)
- return ZE_MEM;
- if ((strncmp(Options.szRootDir, C.FNV[k], lstrlen(Options.szRootDir))) == 0)
+ 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))
{
- m = 0;
- for (j = lstrlen(Options.szRootDir); j < lstrlen(C.FNV[k]); j++)
- argVee[argCee][m++] = C.FNV[k][j];
- argVee[argCee][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(argCee, Options.ExcludeList[k], "Exclude file list array", TRUE) != ZE_OK)
+ return ZE_MEM;
+ k++;
}
- argCee++;
- }
- }
- }
+ 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") != ZE_OK)
+ 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;
- argCee++;
- }
+ }
+
+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);
-chdir(szOrigDir);
-#ifdef __BORLANDC__
-setdisk(toupper(szOrigDir[0]) - 'A');
-#endif
-
-/* 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);
+/* 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) ?
+ {
+ 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
@@ -468,6 +682,11 @@ void EXPENTRY ZpVersion(ZpVer far * p) /* should be pointer to const struct */
#else
p->flag = 0;
#endif
+#ifdef CRYPT
+ p->fEncryption = TRUE;
+#else
+ p->fEncryption = FALSE;
+#endif
lstrcpy(p->betalevel, Z_BETALEVEL);
lstrcpy(p->date, REVDATE);
@@ -478,17 +697,22 @@ void EXPENTRY ZpVersion(ZpVer far * p) /* should be pointer to const struct */
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
index c2c0e8c..f609633 100644
--- a/api.h
+++ b/api.h
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ api.h - Zip 3
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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 */
@@ -60,6 +62,7 @@ typedef struct _ZpVer {
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;
@@ -73,8 +76,14 @@ typedef struct _ZpVer {
#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 */
@@ -110,31 +119,54 @@ 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 */
+ 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;
-DLLSERVICE *ServiceApplication;
+ 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);
-BOOL EXPENTRY ZpSetOptions(LPZPOPT Opts);
-ZPOPT EXPENTRY ZpGetOptions(void);
-int EXPENTRY ZpArchive(ZCL C);
+int EXPENTRY ZpArchive(ZCL C, LPZPOPT Opts);
#if defined(ZIPLIB) || defined(COM_OBJECT)
# define ydays zp_ydays
diff --git a/atari/Makefile b/atari/Makefile
index 96b6ff5..2c86196 100644
--- a/atari/Makefile
+++ b/atari/Makefile
@@ -27,14 +27,14 @@ LFLAGS1 =
LFLAGS2 = -s
# object file lists
-OBJZ = zip.o zipfile.o zipup.o fileio.o util.o crc32.o crctab.o globals.o \
+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) crctab.o crypt_.o ttyio.o
+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
@@ -58,7 +58,9 @@ $(OBJI): $(ZIP_H)
$(OBJN): $(ZIP_H)
$(OBJS): $(ZIP_H)
$(OBJC): $(ZIP_H)
-zip.o zipup.o crypt.o ttyio.o zipcloak.o crypt_.o: crypt.h
+zip.o 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
diff --git a/atari/atari.c b/atari/atari.c
index 9bfb5d1..ce5196c 100644
--- a/atari/atari.c
+++ b/atari/atari.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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.info-zip.org/pub/infozip/license.html
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
#include "zip.h"
@@ -532,8 +532,9 @@ iztimes *t; /* return value: access, modific. and creation times */
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);
+ int len = strlen(f);
if (f == label) {
if (a != NULL)
@@ -544,7 +545,6 @@ iztimes *t; /* return value: access, modific. and creation times */
t->atime = t->mtime = t->ctime = label_utim;
return label_time;
}
-
if ((name = malloc(len + 1)) == NULL) {
ZIPERR(ZE_MEM, "filetime");
}
@@ -570,6 +570,7 @@ iztimes *t; /* return value: access, modific. and creation times */
/* *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) {
@@ -578,8 +579,6 @@ iztimes *t; /* return value: access, modific. and creation times */
t->ctime = s.st_ctime;
}
- free(name);
-
return unix2dostime(&s.st_mtime);
}
diff --git a/atheos/Contents b/atheos/Contents
deleted file mode 100644
index 3ffaba6..0000000
--- a/atheos/Contents
+++ /dev/null
@@ -1,11 +0,0 @@
-Contents of the "atheos" sub-directory for Zip 2.3 and later:
-
- Contents this file
- README Notes from the author of the AtheOS port
- Makefile makefile for building
- atheos.c AtheOS-specific routines (similar to the BeOS/UNIX ones)
- osdep.h AtheOS-specific includes and whatnot
- zipup.h Definitions for zip routines
-
-- Ruslan Nickolaev (nruslan@hotbox.ru)
- Sep 06/2004
diff --git a/atheos/Makefile b/atheos/Makefile
index 265ff42..91df1c8 100644
--- a/atheos/Makefile
+++ b/atheos/Makefile
@@ -2,7 +2,7 @@
#
# Makefile for Info-ZIP's zip, zipcloak, zipnote, and zipsplit on AtheOS
#
-# Copyright (C) 1999-2005 Info-ZIP
+# Copyright (C) 1999-2007 Info-ZIP
# Chris Herborth (chrish@pobox.com)
# Ruslan Nickolaev (nruslan@hotbox.ru)
#
@@ -28,7 +28,7 @@ manext = 1
MANDIR = $(prefix)/man/man$(manext)
ZIPMANUAL = MANUAL
-VERSION = Version 2.31 of __DATE__
+VERSION = Version 2.3 of __DATE__
######################################################################
@@ -49,13 +49,13 @@ all:
# 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 \
- atheos.o crctab.o
+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) crctab.o crypt_.o ttyio.o
+OBJC = zipcloak.o $(OBJU) crc32_.o crypt_.o ttyio.o
OBJS = zipsplit.o $(OBJU)
# Headers
@@ -84,6 +84,8 @@ $(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
diff --git a/atheos/README b/atheos/README
index e9731fe..a96fffc 100644
--- a/atheos/README
+++ b/atheos/README
@@ -6,12 +6,10 @@ FEATURES
TODO
----
There is only one thing to be fixed:
- write_attr() should return count of bytes written. However that's a bug
- related with AFS only.
+ 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.
+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
diff --git a/atheos/atheos.c b/atheos/atheos.c
index dac3ef8..6f1c915 100644
--- a/atheos/atheos.c
+++ b/atheos/atheos.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2005-Feb-10 or later
+ 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, all these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+ 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)
@@ -458,7 +458,7 @@ int get_attr_dir( const char *name, char **attr_buff, off_t *total_size )
strcpy( ptr, fa_ent->d_name );
ptr += entname_size;
- memcpy( ptr, &fa_info, sizeof( struct attr_info ) );
+ memcpy( ptr, &fa_info, sizeof( struct attr_info ) );
ptr += sizeof( struct attr_info );
if( fa_info.ai_size > 0 ) {
@@ -840,7 +840,7 @@ void setfiletype(const char *file, const char *type)
else
{
nLen = strlen( type );
- /* FIXME: write_attr() should return count of bytes written */
+ /* 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", "" );
diff --git a/atheos/osdep.h b/atheos/osdep.h
index 69fd5b2..0869f94 100644
--- a/atheos/osdep.h
+++ b/atheos/osdep.h
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2005-Feb-10 or later
+ 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, all these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+ 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_
@@ -23,7 +23,7 @@
#define EB_AT_FL_BADBITS 0xfe /* bits currently undefined */
#ifndef ZP_NEED_MEMCOMPR
-# define ZP_NEED_MEMCOMPR
+ define ZP_NEED_MEMCOMPR
#endif
#define deletedir(d) rmdir(d);
@@ -61,3 +61,4 @@ attr_data (length in attr_info.ai_size)
*/
#endif
+
diff --git a/atheos/zipup.h b/atheos/zipup.h
index 6cbc806..d3d39a3 100644
--- a/atheos/zipup.h
+++ b/atheos/zipup.h
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2005-Feb-10 or later
+ 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, all these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+ 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_
diff --git a/beos/Makefile b/beos/Makefile
index 0dc31e1..1b9e613 100644
--- a/beos/Makefile
+++ b/beos/Makefile
@@ -90,12 +90,12 @@ all:
# Object file lists
OBJZ = zip.o zipfile.o zipup.o fileio.o util.o globals.o crypt.o ttyio.o \
- beos.o crc32.o crctab.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) crctab.o crypt_.o ttyio.o
+OBJC = zipcloak.o $(OBJU) crc32_.o crypt_.o ttyio.o
OBJS = zipsplit.o $(OBJU)
# Headers
@@ -124,6 +124,8 @@ $(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
diff --git a/beos/beos.c b/beos/beos.c
index d64cbb3..d8d16df 100644
--- a/beos/beos.c
+++ b/beos/beos.c
@@ -1,7 +1,7 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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
@@ -283,8 +283,9 @@ iztimes *t; /* return value: access, modific. and creation times */
a file size of -1 */
{
struct stat s; /* results of stat() */
+ /* convert FNAMX to malloc - 11/8/04 EG */
char *name;
- unsigned int len = strlen(f);
+ int len = strlen(f);
if (f == label) {
if (a != NULL)
@@ -295,7 +296,6 @@ iztimes *t; /* return value: access, modific. and creation times */
t->atime = t->mtime = t->ctime = label_utim;
return label_time;
}
-
if ((name = malloc(len + 1)) == NULL) {
ZIPERR(ZE_MEM, "filetime");
}
@@ -315,6 +315,7 @@ iztimes *t; /* return value: access, modific. and creation times */
free(name);
return 0;
}
+ free(name);
if (a != NULL) {
*a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE);
@@ -330,8 +331,6 @@ iztimes *t; /* return value: access, modific. and creation times */
t->ctime = s.st_mtime; /* best guess (s.st_ctime: last status change!) */
}
- free(name);
-
return unix2dostime(&s.st_mtime);
}
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/cczip.exec b/cmsmvs/cczip.exec
index afa97d0..86edb59 100644
--- a/cmsmvs/cczip.exec
+++ b/cmsmvs/cczip.exec
@@ -26,7 +26,6 @@ linklist=''
modname='ZIP'
Say 'Building' modname 'MODULE...'
Call Compile 'ZIP'
-Call Compile 'CRCTAB'
Call Compile 'CRC32'
Call Compile 'CRYPT'
Call Compile 'DEFLATE'
@@ -92,7 +91,7 @@ Call Compile 'ZIPFILE'
Call Compile 'FILEIO'
Call Compile 'UTIL'
Call Compile 'GLOBALS'
-Call Compile 'CRCTAB'
+Call Compile 'CRC32'
Call Compile 'CRYPT'
Call Compile 'TTYIO'
Call Compile 'CMSMVS'
diff --git a/cmsmvs/cms.c b/cmsmvs/cms.c
index e8dfa34..e69f5cb 100644
--- a/cmsmvs/cms.c
+++ b/cmsmvs/cms.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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.info-zip.org/pub/infozip/license.html
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
/*
* VM/CMS specific things.
diff --git a/cmsmvs/cmsmvs.c b/cmsmvs/cmsmvs.c
index 5297908..9c56de7 100644
--- a/cmsmvs/cmsmvs.c
+++ b/cmsmvs/cmsmvs.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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.info-zip.org/pub/infozip/license.html
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
/*
* routines common to VM/CMS and MVS
diff --git a/cmsmvs/cmsmvs.h b/cmsmvs/cmsmvs.h
index 8fca61b..e2adb31 100644
--- a/cmsmvs/cmsmvs.h
+++ b/cmsmvs/cmsmvs.h
@@ -61,18 +61,18 @@
/* definition for ZIP */
#define getch() getc(stdin)
-#define native(c) ebcdic[(c)]
#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)
-# define isatty(t) 1
#endif /*MVS */
#ifdef ZCRYPT_INTERNAL
# define ZCR_SEED2 (unsigned)3141592654L /* use PI as seed pattern */
@@ -94,17 +94,6 @@
-/* definitions for UNZIP */
-#ifdef UNZIP
-#define INBUFSIZ 8192
-
-#define USE_STRM_INPUT
-#define USE_FWRITE
-
-#define PATH_MAX 128
-#endif /* UNZIP */
-
-
#if 0 /*$RGH$*/
/* RECFM=F, LRECL=1 works for sure */
#define FOPR "rb,recfm=fb"
diff --git a/cmsmvs/mvs.c b/cmsmvs/mvs.c
index fabc4f0..d7f7437 100644
--- a/cmsmvs/mvs.c
+++ b/cmsmvs/mvs.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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.info-zip.org/pub/infozip/license.html
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
/*
* MVS specific things
diff --git a/cmsmvs/mvs.mki b/cmsmvs/mvs.mki
index 7990902..316d064 100644
--- a/cmsmvs/mvs.mki
+++ b/cmsmvs/mvs.mki
@@ -59,11 +59,11 @@ LDFLAGS=
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)crctab$(O) $(BLD_P)zipfile$(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)crypt.h $(SRC_P)ebcdic.h \
+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
@@ -112,9 +112,6 @@ $(BLD_P)util$(O): $(SRC_P)util.c $(HFILES)
$(BLD_P)crc32$(O): $(SRC_P)crc32.c $(HFILES)
$(CC) -c -o $% $(CFLAGS) $(SRC_P)crc32.c
-$(BLD_P)crctab$(O): $(SRC_P)crctab.c $(HFILES)
- $(CC) -c -o $% $(CFLAGS) $(SRC_P)crctab.c
-
$(BLD_P)zipfile$(O): $(SRC_P)zipfile.c $(HFILES)
$(CC) -c -o $% $(CFLAGS) $(SRC_P)zipfile.c
diff --git a/cmsmvs/zip.makefile b/cmsmvs/zip.makefile
index b183367..85bef22 100644
--- a/cmsmvs/zip.makefile
+++ b/cmsmvs/zip.makefile
@@ -13,7 +13,6 @@ TEXT:
zip c
util c
crc32.c
- crctab.c
zipfile c
zipup c
cmsmvs c
diff --git a/cmsmvs/zipmvsc.job b/cmsmvs/zipmvsc.job
index 6b4b1ca..3c786d7 100644
--- a/cmsmvs/zipmvsc.job
+++ b/cmsmvs/zipmvsc.job
@@ -46,11 +46,6 @@
// 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
-//CRCTAB EXEC EDCC,COND=(12,LE),CREGSIZ='4M',
-// INFILE='C888090.ZIP.C(CRCTAB)',
-// OUTFILE='C888090.ZIP.C.OBJ(CRCTAB),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',
@@ -85,7 +80,6 @@
// 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(CRCTAB),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
diff --git a/cmsmvs/zipvmc.exec b/cmsmvs/zipvmc.exec
index 3232649..3fdd800 100644
--- a/cmsmvs/zipvmc.exec
+++ b/cmsmvs/zipvmc.exec
@@ -27,8 +27,6 @@ say 'Compiling UTIL C...'
'cc util c 'parms
say 'Compiling CRC32 C...'
'cc crc32 c 'parms
-say 'Compiling CRCTAB C...'
-'cc crctab c 'parms
say 'Compiling ZIPFILE C...'
'cc zipfile c 'parms
say 'Compiling ZIPUP C...'
@@ -40,7 +38,7 @@ say 'Compiling CMS C...'
say 'Linking all files...'
'cmod zip zip trees crypt deflate fileio globals ttyio',
- 'util crc32 crctab zipfile zipup cmsmvs cms'
+ 'util crc32 zipfile zipup cmsmvs cms'
say 'All Done!'
say "To run enter : ZIP parms"
exit rc
diff --git a/crc32.c b/crc32.c
index aaebb40..6b2403b 100644
--- a/crc32.c
+++ b/crc32.c
@@ -1,64 +1,732 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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 <rbrown64@csc.com.au> 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 1.5 1996/01/13 14:55:12 spc Exp $ */
+/* $Id: crc32.c,v 2.0 2007/01/07 05:20:36 spc Exp $ */
#define __CRC32_C /* identifies this source module */
#include "zip.h"
-#ifndef USE_ZLIB
-#ifndef ASM_CRC
+#if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
#ifndef ZCONST
# define ZCONST const
#endif
-#ifdef CRC32
-# undef CRC32
+#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
-#define CRC32(c, b) (crc_table[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
-#define DO1(buf) crc = CRC32(crc, *buf++)
-#define DO2(buf) DO1(buf); DO1(buf)
-#define DO4(buf) DO2(buf); DO2(buf)
-#define DO8(buf) DO4(buf); DO4(buf)
+{
+#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)
- register ulg crc; /* crc shift register */
+ 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 ZCONST ulg near *crc_table;
+ register z_uint4 c;
+ register ZCONST ulg near *crc_32_tab;
if (buf == NULL) return 0L;
- crc_table = get_crc_table();
+ crc_32_tab = get_crc_table();
- crc = crc ^ 0xffffffffL;
+ 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(buf);
+ DO8(c, buf);
len -= 8;
}
-#endif
+#endif /* !NO_UNROLLED_LOOPS */
+#endif /* ?(IZ_CRC_BE_OPTIMIZ || IZ_CRC_LE_OPTIMIZ) */
if (len) do {
- DO1(buf);
+ DO1(c, buf);
} while (--len);
- return crc ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */
+
+ 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
index d23967b..38dbc86 100644
--- a/crc_i386.S
+++ b/crc_i386.S
@@ -1,14 +1,14 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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.
+ * 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)
@@ -27,6 +27,10 @@
* 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,
@@ -41,8 +45,10 @@
* This results in shorter code at the expense of reduced performance.
*/
-/* This file is NOT used in conjunction with zlib. */
-#ifndef USE_ZLIB
+/* 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 '_'.
@@ -122,19 +128,70 @@
xorl (%edi, %ebx, 4), %eax ;/* c ^=table[tmp] */
#endif /* ?__686 */
-#define Do_CRC_byte /* c = (c >> 8) ^ table[(c^*buf++)&0xFF] */\
+#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
-#define Do_CRC_lword \
- xorl (%esi), %eax ;/* c ^= *(ulg *)buf */\
- addl $4, %esi ;/* ((ulg *)buf)++ */\
+# 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 */
@@ -176,54 +233,61 @@ _crc32: /* ulg crc32(ulg crc, uch *buf, extent len) */
jnz .L_align_loop
.L_aligned_now:
# endif /* !NO_32_BIT_LOADS */
- movl %ecx, %edx /* save len in edx */
- shrl $3, %ecx /* ecx = len / 8 */
- jz .L_No_Eights
+ 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_Eight:
+.L_Next_Sixteen:
# ifndef NO_32_BIT_LOADS
- /* Do_CRC_lword */
- xorl (%esi), %eax ;/* c ^= *(ulg *)buf */
- addl $4, %esi ;/* ((ulg *)buf)++ */
- Do_CRC
- Do_CRC
- Do_CRC
- Do_CRC
- /* Do_CRC_lword */
- xorl (%esi), %eax ;/* c ^= *(ulg *)buf */
- addl $4, %esi ;/* ((ulg *)buf)++ */
- Do_CRC
- Do_CRC
- Do_CRC
- Do_CRC
+ Do_CRC_4lword
# else /* NO_32_BIT_LOADS */
- Do_CRC_byte
- Do_CRC_byte
- Do_CRC_byte
- Do_CRC_byte
- Do_CRC_byte
- Do_CRC_byte
- Do_CRC_byte
- Do_CRC_byte
+ 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_Eight
+ jnz .L_Next_Sixteen
-.L_No_Eights:
- movl %edx, %ecx
- andl $7, %ecx /* ecx = len % 8 */
+.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) */
+ 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++); */
- decl %ecx /* > } while (--len); */
+.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_bail: /* > } */
+ notl %eax /* > return ~c; */
.L_fine:
popl %ecx
popl %edx
@@ -237,4 +301,4 @@ _crc32: /* ulg crc32(ulg crc, uch *buf, extent len) */
error: this asm version is for 386 only
#endif /* i386 || _i386 || _I386 || __i386 */
-#endif /* !USE_ZLIB */
+#endif /* !USE_ZLIB && !CRC_TABLE_ONLY */
diff --git a/crctab.c b/crctab.c
deleted file mode 100644
index f47fda4..0000000
--- a/crctab.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- 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
-*/
-/* crctab.c -- supply the CRC table needed for CRC-32 calculations.
- * Copyright (C) 1995 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* $Id: crctab.c,v 1.4 1996/01/08 14:55:12 jloup Exp $ */
-
-/*
- Generate a table 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 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.
-*/
-
-#define __CRCTAB_C /* identifies this source module */
-
-#include "zip.h"
-
-#if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
-
-#ifndef ZCONST
-# define ZCONST const
-#endif
-
-#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[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 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 (i = 0; i < sizeof(p)/sizeof(uch); i++)
- xor |= 1L << (31 - p[i]);
-#else
-# define xor 0xedb88320L
-#endif
-
-#ifdef DYNALLOC_CRCTAB
- crctab_p = (ulg near *) nearmalloc (256*sizeof(ulg));
- if (crctab_p == NULL) {
- ziperr(ZE_MEM, "crc_table allocation");
- }
-#endif /* DYNALLOC_CRCTAB */
-
- 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] = c;
- }
- 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[256] = {
- 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
-};
-#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 (ZCONST ulg near *)crc_table;
-#endif
-}
-
-#ifdef DYNALLOC_CRCTAB
-void free_crc_table()
-{
- if (!CRC_TABLE_IS_EMPTY)
- {
- nearfree((ulg near *)crc_table);
- MARK_CRCTAB_EMPTY;
- }
-}
-#endif
-
-#endif /* !USE_ZLIB || USE_OWN_CRCTAB */
diff --git a/crypt.c b/crypt.c
index 377d4fb..cc974ec 100644
--- a/crypt.c
+++ b/crypt.c
@@ -1,18 +1,25 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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 encryption/decryption parts of this source code (as opposed to the
- non-echoing password parts) were originally written in Europe. The
- whole source package can be freely distributed, including from the USA.
- (Prior to January 2000, re-export from the US was a violation of US law.)
+ 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.
*/
/*
@@ -87,11 +94,9 @@
local int testp OF((__GPRO__ ZCONST uch *h));
local int testkey OF((__GPRO__ ZCONST uch *h, ZCONST char *key));
# endif
-#endif /* UNZIP */
-
-#ifndef UNZIP /* moved to globals.h for UnZip */
- local ulg keys[3]; /* keys defining the pseudo-random sequence */
-#endif /* !UNZIP */
+#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
@@ -101,11 +106,18 @@
# endif
#endif
-#ifndef CRC_32_TAB
-# define CRC_32_TAB crc_32_tab
-#endif
+#include "crc32.h"
-#define CRC32(c, b) (CRC_32_TAB[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8))
+#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
@@ -128,12 +140,13 @@ int update_keys(__G__ c)
__GDEF
int c; /* byte of plain text */
{
- GLOBAL(keys[0]) = CRC32(GLOBAL(keys[0]), c);
- GLOBAL(keys[1]) += GLOBAL(keys[0]) & 0xff;
- GLOBAL(keys[1]) = GLOBAL(keys[1]) * 134775813L + 1;
+ 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);
+ GLOBAL(keys[2]) = CRC32(GLOBAL(keys[2]), keyshift, CRY_CRC_TAB);
}
return c;
}
@@ -147,6 +160,11 @@ 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;
@@ -157,22 +175,43 @@ void init_keys(__G__ 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, zfile)
+void crypthead(passwd, crc)
ZCONST char *passwd; /* password string */
ulg crc; /* crc of file being encrypted */
- FILE *zfile; /* where to write header */
{
int n; /* index in random header */
int t; /* temporary */
int c; /* random byte */
- int ztemp; /* temporary for zencoded value */
- uch header[RAND_HEAD_LEN-2]; /* random header */
+ 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
@@ -190,104 +229,145 @@ void crypthead(passwd, crc, zfile)
/* Encrypt random header (last two bytes is high word of crc) */
init_keys(passwd);
for (n = 0; n < RAND_HEAD_LEN-2; n++) {
- ztemp = zencode(header[n], t);
- putc(ztemp, zfile);
+ header[n] = (uch)zencode(header[n], t);
}
- ztemp = zencode((int)(crc >> 16) & 0xff, t);
- putc(ztemp, zfile);
- ztemp = zencode((int)(crc >> 24) & 0xff, t);
- putc(ztemp, zfile);
+ 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 source to file dest
+ * 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, source, dest, passwd)
+int zipcloak(z, passwd)
struct zlist far *z; /* zip entry to encrypt */
- FILE *source, *dest; /* source and destination files */
ZCONST char *passwd; /* password string */
{
int c; /* input byte */
int res; /* result code */
- ulg n; /* holds offset and counts size */
- ush flag; /* previous flags */
+ zoff_t n; /* holds offset and counts size */
int t; /* temporary */
- int ztemp; /* temporary storage for zencode value */
+ 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 = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
+ 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;
- flag = z->flg;
+
+ /* Set encryption and unset any extended local header */
z->flg |= 1, z->flg &= ~8;
- z->lflg |= 1, z->lflg &= ~8;
- z->siz += RAND_HEAD_LEN;
- if ((res = putlocal(z, dest)) != ZE_OK) return res;
+ localz->lflg |= 1, localz->lflg &= ~8;
- /* Initialize keys with password and write random header */
- crypthead(passwd, z->crc, dest);
+ /* Add size of encryption header */
+ localz->siz += RAND_HEAD_LEN;
+ z->siz = localz->siz;
- /* Skip local header in input file */
- if (fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext),
- SEEK_CUR)) {
- return ferror(source) ? ZE_READ : ZE_EOF;
- }
+ /* 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(source)) == EOF) {
- return ferror(source) ? ZE_READ : ZE_EOF;
- }
- ztemp = zencode(c, t);
- putc(ztemp, dest);
+ 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;
}
- /* Skip extended local header in input file if there is one */
- if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
- return ferror(source) ? ZE_READ : ZE_EOF;
+
+ /* 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(dest) == EOF) return ZE_TEMP;
+ if (fflush(y) == EOF) return ZE_TEMP;
+ */
/* Update number of bytes written to output file */
- tempzn += (4 + LOCHEAD) + z->nam + z->ext + z->siz;
+ 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 source to file dest
+ * 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, source, dest, passwd)
+int zipbare(z, passwd)
struct zlist far *z; /* zip entry to encrypt */
- FILE *source, *dest; /* source and destination files */
ZCONST char *passwd; /* password string */
{
- int c0, c1; /* last two input bytes */
- ulg offset; /* used for file offsets */
- ulg size; /* size of input data */
+#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 */
- ush flag; /* previous flags */
- /* Save position and skip local header in input file */
- if ((offset = (ulg)ftell(source)) == (ulg)-1L ||
- fseek(source, (long)(4 + LOCHEAD + (ulg)z->nam + (ulg)z->ext),
- SEEK_CUR)) {
- return ferror(source) ? ZE_READ : ZE_EOF;
- }
+ /* 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;
- if ((c1 = getc(source)) == EOF) {
- return ferror(source) ? ZE_READ : ZE_EOF;
+#endif
+ if ((c1 = getc(in_file)) == EOF) {
+ return ferror(in_file) ? ZE_READ : ZE_EOF;
}
Trace((stdout, " (%02x)", c1));
zdecode(c1);
@@ -303,42 +383,59 @@ int zipbare(z, source, dest, passwd)
if ((ush)(c0 | (c1<<8)) !=
(z->flg & 8 ? (ush) z->tim & 0xffff : (ush)(z->crc >> 16))) {
#else
- c0++; /* avoid warning on unused variable */
if ((ush)c1 != (z->flg & 8 ? (ush) z->tim >> 8 : (ush)(z->crc >> 24))) {
#endif
- if (fseek(source, offset, SEEK_SET)) {
- return ferror(source) ? ZE_READ : ZE_EOF;
+ 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");
}
- if ((res = zipcopy(z, source, dest)) != ZE_OK) return res;
return ZE_MISS;
}
- /* Clear encrypted bit and local header bit, and write local header to
- output file */
- if ((offset = (ulg)ftell(dest)) == (ulg)-1L) return ZE_TEMP;
- z->off = offset;
- flag = z->flg;
- z->flg &= ~9;
- z->lflg &= ~9;
z->siz -= RAND_HEAD_LEN;
- if ((res = putlocal(z, dest)) != ZE_OK) return res;
+ 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(source)) == EOF) {
- return ferror(source) ? ZE_READ : ZE_EOF;
+ if ((c1 = getc(in_file)) == EOF) {
+ return ferror(in_file) ? ZE_READ : ZE_EOF;
}
zdecode(c1);
- putc(c1, dest);
+ buf[b] = c1;
+ b++;
+ if (b >= 1024) {
+ /* write the buffer */
+ bfwrite(buf, 1, b, BFWRITE_DATA);
+ b = 0;
+ }
}
- /* Skip extended local header in input file if there is one */
- if ((flag & 8) != 0 && fseek(source, 16L, SEEK_CUR)) {
- return ferror(source) ? ZE_READ : ZE_EOF;
+ if (b) {
+ /* write the buffer */
+ bfwrite(buf, 1, b, BFWRITE_DATA);
+ b = 0;
}
- if (fflush(dest) == EOF) return ZE_TEMP;
+ /* 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) + z->nam + z->ext + z->siz;
+ 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;
}
@@ -349,18 +446,25 @@ int zipbare(z, source, dest, passwd)
/***********************************************************************
* 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, f)
+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 */
+ char *p = (char *)buf; /* steps through buffer */
/* Encrypt data in buffer */
for (size = item_size*(ulg)nb; size != 0; p++, size--) {
@@ -368,7 +472,7 @@ unsigned zfwrite(buf, item_size, nb, f)
}
}
/* Write the buffer out */
- return fwrite(buf, item_size, nb, f);
+ return bfwrite(buf, item_size, nb, BFWRITE_DATA);
}
#endif /* ?UTIL */
@@ -535,13 +639,15 @@ local int testkey(__G__ h, key)
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 = %ld\n",
+ Trace((stdout, " incnt = %d unzip offset into zipfile = %s\n",
GLOBAL(incnt),
- GLOBAL(cur_zipfile_bufstart)+(GLOBAL(inptr)-GLOBAL(inbuf))));
+ fzofft(GLOBAL(cur_zipfile_bufstart)+(GLOBAL(inptr)-GLOBAL(inbuf)),
+ NULL, NULL)));
/* same test as in zipbare(): */
@@ -566,7 +672,7 @@ local int testkey(__G__ h, key)
return -1; /* bad */
#endif
/* password OK: decrypt current buffer contents before leaving */
- for (n = (long)GLOBAL(incnt) > GLOBAL(csize) ?
+ for (n = (zoff_t)GLOBAL(incnt) > GLOBAL(csize) ?
(int)GLOBAL(csize) : GLOBAL(incnt),
p = GLOBAL(inptr); n--; p++)
zdecode(*p);
diff --git a/crypt.h b/crypt.h
index af8a069..61f3234 100644
--- a/crypt.h
+++ b/crypt.h
@@ -1,18 +1,19 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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]
- This encryption/decryption source code for Info-Zip software was
- originally written in Europe. The whole source package can be
- freely distributed, including from the USA. (Prior to January 2000,
- re-export from the US was a violation of US law.)
+ 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
@@ -45,7 +46,7 @@
# define CRYPT 1 /* full version */
#else
#if !defined(SFX)
-# define CRYPT 1 /* full version for zip and main unzip*/
+# define CRYPT 1 /* full version for zip and main unzip */
#else
# define CRYPT 0 /* dummy version for unzip sfx */
#endif
@@ -60,13 +61,13 @@
#endif
#define CR_MAJORVER 2
-#define CR_MINORVER 9
+#define CR_MINORVER 91
#ifdef CR_BETA
-# define CR_BETA_VER "a BETA"
-# define CR_VERSION_DATE "05 May 2000" /* last real code change */
+# 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 May 2000" /* last public release date */
+# define CR_VERSION_DATE "05 Jan 2007" /* last public release date */
# define CR_RELEASE
#endif
@@ -121,13 +122,6 @@
#define RAND_HEAD_LEN 12 /* length of encryption random header */
/* the crc_32_tab array has to be provided externally for the crypt calculus */
-#ifndef CRC_32_TAB /* UnZip provides this in globals.h */
-# if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
- extern ZCONST ulg near *crc_32_tab;
-# else
- extern ZCONST ulg Far *crc_32_tab;
-# endif
-#endif /* !CRC_32_TAB */
/* 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))
@@ -140,12 +134,12 @@ int update_keys OF((__GPRO__ int c));
void init_keys OF((__GPRO__ ZCONST char *passwd));
#ifdef ZIP
- void crypthead OF((ZCONST char *, ulg, FILE *));
+ void crypthead OF((ZCONST char *, ulg));
# ifdef UTIL
- int zipcloak OF((struct zlist far *, FILE *, FILE *, ZCONST char *));
- int zipbare OF((struct zlist far *, FILE *, FILE *, ZCONST char *));
+ int zipcloak OF((struct zlist far *, ZCONST char *));
+ int zipbare OF((struct zlist far *, ZCONST char *));
# else
- unsigned zfwrite OF((zvoid *, extent, extent, FILE *));
+ unsigned zfwrite OF((zvoid *, extent, extent));
extern char *key;
# endif
#endif /* ZIP */
@@ -169,7 +163,7 @@ void init_keys OF((__GPRO__ ZCONST char *passwd));
#define zencode
#define zdecode
-#define zfwrite fwrite
+#define zfwrite(b,s,c) bfwrite(b,s,c,BFWRITE_DATA)
#endif /* ?CRYPT */
#endif /* !__crypt_h */
diff --git a/deflate.c b/deflate.c
index 96abbb1..c830854 100644
--- a/deflate.c
+++ b/deflate.c
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ deflate.c - Zip 3
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*
@@ -256,7 +258,8 @@ local config configuration_table[10] = {
*/
local void fill_window OF((void));
-local ulg deflate_fast 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)
@@ -550,15 +553,15 @@ local void check_match(start, match, length)
/* check that the match is indeed a match */
if (memcmp((char*)window + match,
(char*)window + start, length) != EQUAL) {
- fprintf(stderr,
+ fprintf(mesg,
" start %d, match %d, length %d\n",
start, match, length);
error("invalid match");
}
if (verbose > 1) {
- fprintf(stderr,"\\[%d,%d]", start-match, length);
+ fprintf(mesg,"\\[%d,%d]", start-match, length);
#ifndef WINDLL
- do { putc(window[start++], stderr); } while (--length != 0);
+ do { putc(window[start++], mesg); } while (--length != 0);
#else
do { fprintf(stdout,"%c",window[start++]); } while (--length != 0);
#endif
@@ -569,6 +572,14 @@ local void 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.
*
@@ -600,6 +611,12 @@ local void fill_window()
*/
} 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.
*/
@@ -621,11 +638,29 @@ local void fill_window()
*/
}
more += WSIZE;
+ if (dot_size > 0 && !display_globaldots) {
+ /* initial space */
+ if (noisy && dot_count == -1) {
#ifndef WINDLL
- if (verbose) putc('.', stderr);
+ putc(' ', mesg);
+ fflush(mesg);
#else
- if (verbose) fprintf(stdout,"%c",'.');
+ 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;
@@ -652,20 +687,12 @@ local void fill_window()
}
/* ===========================================================================
- * 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, (long)strstart - block_start, (eof))
-
-/* ===========================================================================
* 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 ulg deflate_fast()
+local uzoff_t deflate_fast()
{
IPos hash_head = NIL; /* head of the hash chain */
int flush; /* set if current block must be flushed */
@@ -764,7 +791,7 @@ local ulg deflate_fast()
* evaluation for matches: a match is finally adopted only if there is
* no better match at the next window position.
*/
-ulg deflate()
+uzoff_t deflate()
{
IPos hash_head = NIL; /* head of hash chain */
IPos prev_match; /* previous match */
@@ -772,7 +799,7 @@ ulg deflate()
int match_available = 0; /* set if previous match exists */
register unsigned match_length = MIN_MATCH-1; /* length of best match */
#ifdef DEBUG
- extern ulg isize; /* byte length of input file, for debug only */
+ extern uzoff_t isize; /* byte length of input file, for debug only */
#endif
if (level <= 3) return deflate_fast(); /* optimized for speed */
diff --git a/ebcdic.h b/ebcdic.h
index c22307e..a52de1e 100644
--- a/ebcdic.h
+++ b/ebcdic.h
@@ -1,10 +1,12 @@
/*
+ ebcdic.h
+
Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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/license.html
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/licen
*/
/*---------------------------------------------------------------------------
@@ -236,6 +238,26 @@ ZCONST uch ascii[] = {
---------------------------------------------------------------------------*/
#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 */
@@ -254,9 +276,30 @@ ZCONST uch Far iso2oem[] = {
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 */
@@ -275,6 +318,7 @@ ZCONST uch Far oem2iso[] = {
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)
diff --git a/file_id.diz b/file_id.diz
index 5420e59..5e3f34e 100644
--- a/file_id.diz
+++ b/file_id.diz
@@ -1,4 +1,4 @@
-Info-ZIP's Zip 2.31: generic C sources.
+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
@@ -8,8 +8,8 @@ Info-ZIP's Zip 2.31: generic C sources.
Includes Info-ZIP's ZCrypt 2.9 for
PKWARE-compatible standard encryption
and decryption support for Info-ZIP's
- Zip 2.31, UnZip 5.52, and WiZ 5.02 (and
- later).
+ 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
index e59011c..1847e62 100644
--- a/fileio.c
+++ b/fileio.c
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ fileio.c - Zip 3
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*
@@ -12,11 +14,16 @@
#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 <time.h>
#ifdef NO_MKTIME
@@ -33,6 +40,12 @@ time_t mktime OF((struct tm *));
extern int errno;
#endif
+/* -----------------------
+ For long option support
+ ----------------------- */
+#include <ctype.h>
+
+
#if defined(VMS) || defined(TOPS20)
# define PAD 5
#else
@@ -44,15 +57,36 @@ 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 functions */
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 struct stat zipstatb;
+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
@@ -60,23 +94,31 @@ 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) */
-FILE *fp;
-/* Read a \n or \r delimited name from stdin into n, and return
- n. If EOF, then return NULL. Also, if the name read is too big, return
- NULL. */
+#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 = n;
+
+ p = name;
while ((c = getc(fp)) == '\n' || c == '\r')
;
if (c == EOF)
return NULL;
do {
- if (p - n >= FNMAX)
+ if (p - name >= GETNAM_MAX)
return NULL;
*p++ = (char) c;
c = getc(fp);
@@ -87,14 +129,19 @@ FILE *fp;
* 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 > n) {
+ while (p > name) {
if ((c = p[-1]) != ' ' && c != '.')
break;
--p;
}
#endif
*p = 0;
- return n;
+ /* malloc a copy */
+ if ((p = malloc(strlen(name) + 1)) == NULL) {
+ return NULL;
+ }
+ strcpy(p, name);
+ return p;
}
struct flist far *fexpel(f)
@@ -114,33 +161,42 @@ struct flist far *f; /* entry to delete */
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 */
+ 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 */
+ 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 */
+ 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.
*/
@@ -165,9 +221,38 @@ int c; /* path components separator character */
#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;
+ char *n;
/* Reduce all path components to MSDOS upper case 8.3 style names. */
{
int c; /* current character */
@@ -222,6 +307,130 @@ char *n;
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. */
@@ -257,15 +466,25 @@ int check_dup()
for (j = 1; j < fcount; j++)
if (strcmp(nodup[j - 1]->iname, nodup[j]->iname) == 0)
{
- zipwarn(" first full name: ", nodup[j - 1]->name);
- zipwarn(" second full name: ", nodup[j]->name);
+ 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
- zipwarn("name in zip file repeated: ", nodup[j]->iname);
+ 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);
@@ -276,58 +495,402 @@ int check_dup()
int filter(name, casesensitive)
char *name;
int casesensitive;
- /* Scan the -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.
+ /* 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;
- int include = icount ? 0 : 1;
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 1;
+ if (pcount == 0) return TRUE;
for (n = 0; n < pcount; n++) {
if (!patterns[n].zname[0]) /* it can happen... */
- continue;
+ continue;
p = name;
- if (patterns[n].select == 'R') {
- /* 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. */
+ 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; INCSTR(q))
+ for (q = patterns[n].zname; (q = MBSCHR(q, '/')) != NULL; MB_NEXTCHAR(q))
slashes++;
- for (q = p; (q = MBSCHR(q, '/')) != NULL; INCSTR(q))
+ /* 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)
- for (q = p; (q = MBSCHR(q, '/')) != NULL; INCSTR(q))
- if (slashes++ == 0) {
- p = q + CLEN(q);
+ /* 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)) {
- if (patterns[n].select == 'x') return 0;
- include = 1;
+ 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 include;
+ 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 */
+ 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)
@@ -366,6 +929,14 @@ int casesensitive; /* true for case-sensitive matching */
}
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) {
@@ -375,7 +946,7 @@ int casesensitive; /* true for case-sensitive matching */
* same z entry.
*/
if (verbose)
- fprintf(mesg, "excluding %s\n", zname);
+ fprintf(mesg, "excluding %s\n", oname);
free((zvoid *)iname);
free((zvoid *)zname);
} else {
@@ -388,6 +959,7 @@ int casesensitive; /* true for case-sensitive matching */
return ZE_MEM;
}
strcpy(z->name, name);
+ z->oname = oname;
z->dosflag = dosflag;
#ifdef FORCE_NEWNAME
@@ -401,6 +973,11 @@ int casesensitive; /* true for case-sensitive matching */
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;
}
@@ -413,13 +990,13 @@ int casesensitive; /* true for case-sensitive matching */
/* 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. */
- struct stat statb;
+ z_stat statb; /* now use structure z_stat and function zstat globally 7/24/04 EG */
if (zipstate == -1)
zipstate = strcmp(zipfile, "-") != 0 &&
- stat(zipfile, &zipstatb) == 0;
+ zstat(zipfile, &zipstatb) == 0;
- if (zipstate == 1 && (statb = zipstatb, stat(name, &statb) == 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
@@ -442,6 +1019,7 @@ int casesensitive; /* true for case-sensitive matching */
if (undosm != iname)
free((zvoid *)undosm);
free((zvoid *)iname);
+ free(oname);
return ZE_OK;
}
#endif /* CMS_MVS */
@@ -457,12 +1035,28 @@ int casesensitive; /* true for case-sensitive matching */
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;
@@ -477,7 +1071,6 @@ int casesensitive; /* true for case-sensitive matching */
return ZE_OK;
}
-
ulg dostime(y, n, d, h, m, s)
int y; /* year */
int n; /* month */
@@ -585,7 +1178,7 @@ ulg dostime; /* DOS time to convert */
#ifndef MACOS
int destroy(f)
-char *f; /* file to delete */
+ char *f; /* file to delete */
/* Delete the file *f, returning non-zero on failure. */
{
return unlink(f);
@@ -599,7 +1192,7 @@ char *d, *s; /* destination and source file names */
this will be done by setfileattr() later.
*/
{
- struct stat t; /* results of stat() */
+ 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.
@@ -663,15 +1256,20 @@ char *d, *s; /* destination and source file names */
if (SWI_OS_FSControl_26(s,d,0xA1)!=NULL) {
#endif
- if ((f = fopen(s, FOPR)) == NULL) {
- fprintf(stderr," replace: can't open %s\n", s);
+ /* 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 = fopen(d, FOPW)) == NULL)
+ 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)
@@ -698,7 +1296,7 @@ char *f; /* file path */
return _dos_files(&buf, f, 0xff) < 0 ? 0x20 : buf.atr;
#else
- struct stat s;
+ z_stat s;
return SSTAT(f, &s) == 0 ? (int) s.st_mode : 0;
#endif
@@ -721,18 +1319,22 @@ int a; /* attributes returned by getfileattr() */
#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 */
+ 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)
+# 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. */
@@ -771,8 +1373,10 @@ char *zip; /* path name of zip file to generate temp name for */
}
return t;
# endif /* !VM_CMS */
-#else /* !CMS_MVS */
-#ifdef TANDEM
+
+# else /* !CMS_MVS */
+
+# ifdef TANDEM
char cur_subvol [FILENAME_MAX];
char temp_subvol [FILENAME_MAX];
char *zptr;
@@ -780,6 +1384,8 @@ char *zip; /* path name of zip file to generate temp name for */
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 */
@@ -794,57 +1400,79 @@ char *zip; /* path name of zip file to generate temp name for */
strcat(cptr, getenv("DEFAULTS"));
strncat(tptr, zip, _min(FILENAME_MAX, (zptr - zip)) ); /* temp subvol */
- strncat(t,zip, _min(NAMELEN, ((zptr - zip) + 1)) ); /* temp stem */
+ strncat(t, zip, _min(NAMELEN, ((zptr - zip) + 1)) ); /* temp stem */
err = chvol(tptr);
ptr = t + strlen(t); /* point to end of stem */
- tmpnam(ptr); /* Add filename part to temp subvol */
- err = chvol(cptr);
}
else
- t = tmpnam(t);
+ 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 */
+# else /* !CMS_MVS && !TANDEM */
/*
* Do something with TMPDIR, TMP, TEMP ????
*/
if (tempath != NULL)
{
- if ((t = malloc(strlen(tempath)+12)) == NULL)
+ if ((t = malloc(strlen(tempath) + 12)) == NULL)
return NULL;
strcpy(t, tempath);
-#if (!defined(VMS) && !defined(TOPS20))
-# ifdef MSDOS
+
+# if (!defined(VMS) && !defined(TOPS20))
+# ifdef MSDOS
{
char c = (char)lastchar(t);
if (c != '/' && c != ':' && c != '\\')
strcat(t, "/");
}
-# else
-# ifdef AMIGA
+# else
+
+# ifdef AMIGA
{
char c = (char)lastchar(t);
if (c != '/' && c != ':')
strcat(t, "/");
}
-# else /* !AMIGA */
+# else /* !AMIGA */
# ifdef RISCOS
if (lastchar(t) != '.')
strcat(t, ".");
# else /* !RISCOS */
-# ifdef QDOS
+
+# ifdef QDOS
if (lastchar(t) != '_')
strcat(t, "_");
-# else
+# else
if (lastchar(t) != '/')
strcat(t, "/");
-# endif /* ?QDOS */
+# endif /* ?QDOS */
# endif /* ?RISCOS */
-# endif /* ?AMIGA */
-# endif /* ?MSDOS */
-#endif /* !VMS && !TOPS20 */
+# endif /* ?AMIGA */
+# endif /* ?MSDOS */
+# endif /* !VMS && !TOPS20 */
}
else
{
@@ -852,38 +1480,43 @@ char *zip; /* path name of zip file to generate temp name for */
return NULL;
*t = 0;
}
-#ifdef NO_MKTEMP
+# ifdef NO_MKTEMP
{
char *p = t + strlen(t);
sprintf(p, "%08lx", (ulg)time(NULL));
return t;
}
-#else
+# 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 /* NO_MKTEMP */
-#endif /* TANDEM */
-#endif /* CMS_MVS */
+# endif
+# endif /* NO_MKTEMP */
+# endif /* TANDEM */
+# endif /* CMS_MVS */
}
-
-#endif /* ndef VMS */
+#endif /* !VMS */
int fcopy(f, g, n)
-FILE *f, *g; /* source and destination files */
-ulg n; /* number of bytes to copy or -1 for all */
-/* Copy n bytes from file *f to file *g, or until EOF if n == -1. Return
- an error code in the ZE_ class. */
+ 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() */
- ulg m; /* bytes copied so far */
+ uzoff_t m; /* bytes copied so far */
if ((b = malloc(CBSZ)) == NULL)
return ZE_MEM;
m = 0;
- while (n == (ulg)(-1L) || m < n)
+ while (n == (uzoff_t)(-1L) || m < n)
{
- if ((k = fread(b, 1, n == (ulg)(-1) ?
+ if ((k = fread(b, 1, n == (uzoff_t)(-1) ?
CBSZ : (n - m < CBSZ ? (extent)(n - m) : CBSZ), f)) == 0)
{
if (ferror(f))
@@ -897,7 +1530,7 @@ ulg n; /* number of bytes to copy or -1 for all */
if (fwrite(b, 1, k, g) != k)
{
free((zvoid *)b);
- fprintf(stderr," fcopy: write error\n");
+ fprintf(mesg," fcopy: write error\n");
return ZE_TEMP;
}
m += k;
@@ -906,6 +1539,395 @@ ulg n; /* number of bytes to copy or -1 for all */
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;
@@ -984,3 +2006,2898 @@ register unsigned int len;
}
#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
index c76e5a0..e73392a 100644
--- a/globals.c
+++ b/globals.c
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ globals.c - Zip 3
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*
@@ -20,7 +22,7 @@
/* Handy place to build error messages */
-char errbuf[FNMAX+81];
+char errbuf[FNMAX+4081];
/* Argument processing globals */
int recurse = 0; /* 1=recurse into directories encountered */
@@ -32,25 +34,95 @@ int scanimage = 1; /* 1=scan through image files */
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 */
+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 */
+ 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
-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 linkput = 0; /* 1=store symbolic links as such */
-int noisy = 1; /* 0=quiet operation */
-int extra_fields = 1; /* 0=do not create extra fields */
+
#ifdef NTSD_EAS
- int use_privileges = 0; /* 1=use security privilege overrides */
+ int use_privileges = 0; /* 1=use security privilege overrides */
#endif
#ifndef RISCOS
#ifndef QDOS
@@ -69,27 +141,112 @@ 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) */
-ulg zipbeg; /* Starting offset of zip structures */
-ulg cenbeg; /* Starting offset of central directory */
+
+/* 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 */
-extent zcount; /* Number of files in zip file */
-extent 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 */
-ulg tempzn; /* Count of bytes written to output 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 *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 */
+ /* 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" */
diff --git a/human68k/Makefile b/human68k/Makefile
index e50e429..be1a8b7 100644
--- a/human68k/Makefile
+++ b/human68k/Makefile
@@ -22,12 +22,12 @@ 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 \
- human68k.o crc_68.o crctab.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) crctab.o crypt_.o ttyio.o
+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
@@ -85,6 +85,8 @@ $(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
diff --git a/human68k/Makefile.gcc b/human68k/Makefile.gcc
index 07864bb..edf2989 100644
--- a/human68k/Makefile.gcc
+++ b/human68k/Makefile.gcc
@@ -16,14 +16,14 @@ LDFLAGS = -s
LIBS = -lsignal -lmb -ldos
# object file lists
-OBJZ = zip.o zipfile.o zipup.o fileio.o util.o crc32.o crctab.o globals.o \
+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) crctab.o crypt_.o ttyio.o
+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
@@ -70,7 +70,9 @@ $(OBJI): $(ZIP_H)
$(OBJN): $(ZIP_H)
$(OBJS): $(ZIP_H)
$(OBJC): $(ZIP_H)
-zip.o zipup.o crypt.o ttyio.o zipcloak.o crypt_.o: crypt.h
+zip.o 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
+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
index cc7c36c..9ce78d8 100644
--- a/human68k/crc_68.s
+++ b/human68k/crc_68.s
@@ -1,10 +1,10 @@
;===========================================================================
-; Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+; Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
;
-; See the accompanying file LICENSE, version 1999-Oct-05 or later
+; 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, both of these files are missing, the Info-ZIP license
-; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+; 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.
;
diff --git a/human68k/human68k.c b/human68k/human68k.c
index 5e489e1..be47b57 100644
--- a/human68k/human68k.c
+++ b/human68k/human68k.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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.info-zip.org/pub/infozip/license.html
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
#include "zip.h"
@@ -39,11 +39,15 @@ local char *readd(DIR* d)
int wild(char* w)
{
struct _filbuf inf;
- char name[FNMAX];
+ /* 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);
@@ -51,16 +55,21 @@ int wild(char* w)
p = name;
else
p++;
- if (_dos_lfiles (&inf, w, 0xff) < 0)
+ 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)
+ if (r != ZE_OK) {
+ free(name);
return r;
+ }
} while (_dos_nfiles(&inf) >= 0);
+ free(name);
return ZE_OK;
}
@@ -231,9 +240,10 @@ iztimes *t; /* return value: access, modific. and creation times */
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);
- int isstdin = !strcmp(f, "-");
+ int len = strlen(f);
+ isstdin = !strcmp(f, "-");
if ((name = malloc(len + 1)) == NULL) {
ZIPERR(ZE_MEM, "filetime");
@@ -263,6 +273,7 @@ iztimes *t; /* return value: access, modific. and creation times */
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) {
@@ -271,8 +282,6 @@ iztimes *t; /* return value: access, modific. and creation times */
t->ctime = s.st_ctime;
}
- free(name);
-
return unix2dostime(&s.st_mtime);
}
diff --git a/macos/HISTORY.TXT b/macos/HISTORY.TXT
index 2720e55..3a14a02 100644
--- a/macos/HISTORY.TXT
+++ b/macos/HISTORY.TXT
@@ -1,4 +1,5 @@
-Macintosh Port of Info-ZIP's Zip
+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:
@@ -8,6 +9,116 @@ 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
--------------
@@ -25,10 +136,10 @@ Release MacZip ver1.04 beta 2
4) FIX: {zip} Filename match was case sensitive.
-6) CHG: {zip) switch to latest source level
+6) CHG: {zip} switch to latest source level
unzip 2.30m beta release
-7) CHG: {unzip) switch to latest source level
+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
diff --git a/macos/README.TXT b/macos/README.TXT
index bd69b3d..839658d 100644
--- a/macos/README.TXT
+++ b/macos/README.TXT
@@ -1,5 +1,5 @@
-Macintosh Port of Info-ZIP's Zip
-and UnZip
+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:
@@ -10,46 +10,61 @@ www.haase-online.de/dirk/maczip
Abstract:
---------
-MacZip is a cross-platform compatible tool that
-includes both Zip (for compression) and UnZip (for extraction).
+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 pro-
-duced by PKZIP, and PKZIP and PKUNZIP can work with
-archives produced by zip. Zip version 2.2 is compatible
-with PKZIP 2.04.
+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.
+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.
+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.
+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.
+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.
+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.
@@ -59,57 +74,20 @@ Usage:
Basically there are four ways to start MacZip:
a) Drag'n Drop
- To extract an archive, drop an archive on MacZip.
- To compress files drop a file, folder or volume on MacZip.
- Note: You cannot drop more than one item at the same time.
-
-
-
b) using the Dialog box (Menu: File -> Zip/Unzip):
- * Compression (Zip):
- - Go to "File -> Zip"and the "Zip Options" Dialog Box appears.
- - Click on "Location of the compressed File"
- - The "Select an archive" dialog box appears
- a) select a existing zip archive
- -> Your files will be added to that zip archive.
- b) select a folder and name your new zip archive
- -> a new zip archive will be created with your files.
- - Select one or more check boxes if you want.
- see Zip.txt for more information.
- - Click on "File or Folder to Compress"
- - The "Select a File or Folder" dialog box appears
- a) select a file
- -> This file will be compressed.
- b) select a folder
- -> the contents of the folder will be compressed.
- - Click on "Start Zip" to start the task.
-
- * Extraction (Unzip):
- - Go to "File -> Unzip"and the "Unzip Options" Dialog Box appears.
- - Click on "Location of the compressed File"
- - The "Select an archive" dialog box appears
- - select a existing zip archive
- - Select one or more check boxes if you want.
- see Unzip.txt for more information.
- - Click on "Location of the extracted Files"
- - The "Select a Folder" dialog box appears
- a) select a file
- -> This file will be compressed.
- b) select a folder
- -> the contents of the archive will be extracted
- into this folder.
- - Click on "Start Unzip" to start the task.
-
+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"
+ 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" and select "Command Line" and the "MacZip Entry box"
- Dialog Box appears.
+ - Go to "File", select "Command Line" and the
+ "MacZip Entry box" Dialog Box appears.
An example:
@@ -119,8 +97,9 @@ c) Using the Command line (Menu: File->Command Line):
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 Footnote: 1 wild card, 2 Mac path names)
+ 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!):
@@ -128,31 +107,32 @@ c) Using the Command line (Menu: File->Command Line):
- 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)
+ 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).
+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:*" .
-
+ 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:
@@ -202,13 +182,13 @@ of switches.
Limitations / Problems:
-----------------------
- - Aliases are not supported. I tried, but I got broken aliases
- This port will silently ignore all aliases.
+ - 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
+ - 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.
@@ -216,25 +196,25 @@ Limitations / Problems:
- 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.
+ 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 :(
+ 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).
@@ -245,14 +225,14 @@ 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 4 Zip programs available
-for the Macintosh platform.
-These programs build (of course) different variants of Zip files:
+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: '????' / '????'
+ 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.
@@ -275,6 +255,16 @@ These programs build (of course) different variants of Zip files:
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
@@ -285,108 +275,120 @@ and finally:
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.
+ - 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.
+ 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.
+ - 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.
+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.
+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
+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
+ - 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.
+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.
+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:
+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.
+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.
@@ -397,41 +399,47 @@ 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.
+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.doc). 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.
+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.
+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
@@ -458,37 +466,40 @@ Example:
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.
+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.03 and
-is based on the zip code version 2.3 and unzip code version 5.4.
-See About Box for current version and compiler build date.
+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.
+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.
+ 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.
+ 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',
@@ -509,12 +520,8 @@ 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)
-
-
-
+More Files fixes many of the broken or underfunctional parts of
+the file system. Thanks to Jim Luther. (see morefiles.doc)
@@ -534,21 +541,23 @@ Footnotes:
2. Mac pathnames:
-The following characteristics of Macintosh pathnames should be noted:
+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
+ 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.
+ 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.
diff --git a/macos/osdep.h b/macos/osdep.h
index 3627016..5a69033 100644
--- a/macos/osdep.h
+++ b/macos/osdep.h
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 1999-Oct-05 or later
+ 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, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+ 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
@@ -31,7 +31,7 @@
#define NO_MKTEMP 1
#define PASSWD_FROM_STDIN 1
-#define NO_SYMLINK 1
+#define NO_SYMLINKS 1
#define USE_ZIPMAIN 1
diff --git a/macos/readme.1st b/macos/readme.1st
index 012d512..6182756 100644
--- a/macos/readme.1st
+++ b/macos/readme.1st
@@ -1,3 +1,7 @@
+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.
diff --git a/macos/source/charmap.h b/macos/source/charmap.h
index 70f041d..5656b63 100644
--- a/macos/source/charmap.h
+++ b/macos/source/charmap.h
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 1999-Oct-05 or later
+ 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, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+ 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
diff --git a/macos/source/extrafld.c b/macos/source/extrafld.c
index 83e00a3..a2efcdb 100644
--- a/macos/source/extrafld.c
+++ b/macos/source/extrafld.c
@@ -1,9 +1,9 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*---------------------------------------------------------------------------
@@ -40,11 +40,11 @@
#define EB_L_MAC3_SIZE (EB_HEADSIZE + EB_MAC3_HLEN)
#define EB_C_MAC3_SIZE (EB_HEADSIZE + EB_MAC3_HLEN)
-#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)
-
-#define EXTRAFLD_MAX (unsigned)0xFFFF
+/* 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 */
@@ -204,8 +204,8 @@ static int add_UT_ef(struct zlist far *z, iztimes *z_utim)
}
/* Check to make sure we've got enough room in the extra fields. */
- if( z->ext + EB_L_UT_SIZE > EXTRAFLD_MAX ||
- z->cext + EB_C_UT_SIZE > EXTRAFLD_MAX ) {
+ if( z->ext + EB_L_UT_SIZE > EF_SIZE_MAX ||
+ z->cext + EB_C_UT_SIZE > EF_SIZE_MAX ) {
return ZE_MEM;
}
@@ -275,8 +275,8 @@ static int add_JLEE_ef( struct zlist far *z )
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 > EXTRAFLD_MAX ||
- z->cext + EB_C_JLEE_SIZE > EXTRAFLD_MAX ) {
+ if ( z->ext + EB_L_JLEE_SIZE > EF_SIZE_MAX ||
+ z->cext + EB_C_JLEE_SIZE > EF_SIZE_MAX ) {
return ZE_MEM;
}
@@ -509,8 +509,8 @@ static int add_MAC3_ef( struct zlist far *z )
}
/* Check to make sure we've got enough room in the extra fields. */
- if( z->ext + (EB_L_MAC3_SIZE + compsize) > EXTRAFLD_MAX ||
- z->cext + EB_C_MAC3_SIZE > EXTRAFLD_MAX ) {
+ 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;
}
diff --git a/macos/source/getenv.c b/macos/source/getenv.c
index 586815d..3b22327 100644
--- a/macos/source/getenv.c
+++ b/macos/source/getenv.c
@@ -1,9 +1,9 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*
diff --git a/macos/source/helpers.c b/macos/source/helpers.c
index a7df558..36b5bef 100644
--- a/macos/source/helpers.c
+++ b/macos/source/helpers.c
@@ -1,9 +1,9 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*---------------------------------------------------------------------------
@@ -54,6 +54,7 @@ static char *argv[MAX_ARGS + 1];
** Copy a C string to a Pascal string
**
*/
+
unsigned char *CToPCpy(unsigned char *pstr, char *cstr)
{
register char *dptr;
@@ -67,7 +68,6 @@ unsigned char *CToPCpy(unsigned char *pstr, char *cstr)
}
-
/*
** Copy a Pascal string to a C string
**
@@ -103,6 +103,7 @@ char *sstrcat(char *to,const char *from)
** Alloc memory and init it
**
*/
+
char *StrCalloc(unsigned short size)
{
char *strPtr = NULL;
@@ -120,6 +121,7 @@ return strPtr;
** Release only non NULL pointers
**
*/
+
char *StrFree(char *strPtr)
{
diff --git a/macos/source/helpers.h b/macos/source/helpers.h
index 86aa178..a9df5d8 100644
--- a/macos/source/helpers.h
+++ b/macos/source/helpers.h
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 1999-Oct-05 or later
+ 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, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+ 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
diff --git a/macos/source/macopen.c b/macos/source/macopen.c
index 0f65741..9e18730 100644
--- a/macos/source/macopen.c
+++ b/macos/source/macopen.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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.info-zip.org/pub/infozip/license.html
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
/*** macopen.c; stuff only required for the Mac port ***/
diff --git a/macos/source/macos.c b/macos/source/macos.c
index 3cfee7b..935c9a1 100644
--- a/macos/source/macos.c
+++ b/macos/source/macos.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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.info-zip.org/pub/infozip/license.html
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
/*---------------------------------------------------------------------------
diff --git a/macos/source/macstuff.h b/macos/source/macstuff.h
index 27c481d..9e92dce 100644
--- a/macos/source/macstuff.h
+++ b/macos/source/macstuff.h
@@ -1,1108 +1,18 @@
-#ifndef _MACSTUFF_H
-#define _MACSTUFF_H 1
-
-/*
-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/
-
-
-*/
-
-
-#define __MACOSSEVENFIVEONEORLATER 1
-#define __MACOSSEVENFIVEORLATER 1
-#define __MACOSSEVENORLATER 1
-
-#include <Errors.h>
-#include <Files.h>
-
-
/*
- * Like the MoreFiles routines these fix problems in the standard
- * Mac calls.
- */
-
-int FSpLocationFromPath (int length,const char *path, FSSpecPtr theSpec);
-OSErr FSpPathFromLocation (FSSpecPtr theSpec,int *length, Handle *fullPath);
-
-#define hasDesktopMgr(volParms) (((volParms).vMAttrib & (1L << bHasDesktopMgr)) != 0)
-
-/*
- * The following routines are utility functions. They are exported
- * here because they are needed and they are not officially supported,
- * however. The first set are from the MoreFiles package.
- */
-int FSpGetDefaultDir (FSSpecPtr theSpec);
-int FSpSetDefaultDir (FSSpecPtr dirSpec);
-pascal OSErr FSpGetDirectoryID(const FSSpec *spec,long *theDirID,
- Boolean *isDirectory);
-pascal short FSpOpenResFileCompat(const FSSpec *spec, SignedByte permission);
-pascal void FSpCreateResFileCompat(const FSSpec *spec,OSType creator,
- OSType fileType,
- ScriptCode scriptTag);
-OSErr FSpFindFolder (short vRefNum, OSType folderType,
- Boolean createFolder,
- FSSpec *spec);
-
-/*****************************************************************************/
-
-pascal OSErr GetVolumeInfoNoName(ConstStr255Param pathname,
- short vRefNum,
- HParmBlkPtr pb);
-/* Call PBHGetVInfoSync ignoring returned name.
- 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 GetVolumeInfoNoName's local variable tempPathname).
-
- I noticed using this code in several places, so here it is once.
- This reduces the code size of MoreFiles.
-
- pathName input: Pointer to a full pathname or nil. If you pass in a
- partial pathname, it is ignored. A full pathname to a
- volume must end with a colon character (:).
- vRefNum input: Volume specification (volume reference number, working
- directory number, drive number, or 0).
- pb input: A pointer to HParamBlockRec.
- output: The parameter block as filled in by PBHGetVInfoSync
- except that ioNamePtr will always be NULL.
-
- Result Codes
- noErr 0 No error
- nsvErr -35 No such volume
- paramErr -50 No default volume, or pb was NULL
-*/
-
-
-/*****************************************************************************/
-
-pascal OSErr GetFilenameFromPathname(ConstStr255Param pathname,
- Str255 filename);
-/* Get the object name from the end of a full or partial pathname.
- The GetFilenameFromPathname function gets the file (or directory) name
- from the end of a full or partial pathname. Returns notAFileErr if the
- pathname is nil, the pathname is empty, or the pathname cannot refer to
- a filename (with a noErr result, the pathname could still refer to a
- directory).
-
- pathname input: A full or partial pathname.
- filename output: The file (or directory) name.
-
- Result Codes
- noErr 0 No error
- notAFileErr -1302 The pathname is nil, the pathname
- is empty, or the pathname cannot refer
- to a filename
-
- __________
-
- See also: GetObjectLocation.
-*/
-
-
-
-/*****************************************************************************/
-
-pascal OSErr FSMakeFSSpecCompat(short vRefNum, long dirID,
- ConstStr255Param fileName,
- FSSpec *spec);
-/* Initialize a FSSpec record.
- The FSMakeFSSpecCompat function fills in the fields of an FSSpec record.
- If the file system can't create the FSSpec, then the compatibility code
- creates a FSSpec that is exactly like an FSSpec except that spec.name
- for a file may not have the same capitalization as the file's catalog
- entry on the disk volume. That is because fileName is parsed to get the
- name instead of getting the name back from the file system. This works
- fine with System 6 where FSMakeSpec isn't available.
-
- vRefNum input: Volume specification.
- dirID input: Directory ID.
- fileName input: Pointer to object name, or nil when dirID specifies
- a directory that's the object.
- spec output: A file system specification to be filled in by
- FSMakeFSSpecCompat.
-
- Result Codes
- noErr 0 No error
- nsvErr -35 Volume doesnt exist
- fnfErr -43 File or directory does not exist
- (FSSpec is still valid)
-*/
-
-
-#if !SystemSevenOrLater
-static Boolean FSHasFSSpecCalls(void);
-
-static Boolean QTHasFSSpecCalls(void);
-#endif /* !SystemSevenOrLater */
-
-
-
-/*****************************************************************************/
-
-pascal OSErr GetObjectLocation(short vRefNum,
- long dirID,
- ConstStr255Param pathname,
- short *realVRefNum,
- long *realParID,
- Str255 realName,
- Boolean *isDirectory);
-/* Get a file system object's location.
- The GetObjectLocation function gets a file system object's location -
- that is, its real volume reference number, real parent directory ID,
- and name. While we're at it, determine if the object is a file or directory.
- If GetObjectLocation returns fnfErr, then the location information
- returned is valid, but it describes an object that doesn't exist.
- You can use the location information for another operation, such as
- creating a file or directory.
-
- vRefNum input: Volume specification.
- dirID input: Directory ID.
- pathname input: Pointer to object name, or nil when dirID specifies
- a directory that's the object.
- realVRefNum output: The real volume reference number.
- realParID output: The parent directory ID of the specified object.
- realName output: The name of the specified object (the case of the
- object name may not be the same as the object's
- catalog entry on disk - since the Macintosh file
- system is not case sensitive, it shouldn't matter).
- isDirectory output: True if object is a directory; false if object
- is a file.
-
- 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
- dirNFErr -120 Directory not found or incomplete pathname
- notAFileErr -1302 The pathname is nil, the pathname
- is empty, or the pathname cannot refer
- to a filename
- afpAccessDenied -5000 User does not have the correct access
- afpObjectTypeErr -5025 Directory not found or incomplete pathname
-
- __________
+ Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
- See also: FSMakeFSSpecCompat
-*/
-
-pascal OSErr FSpGetDirectoryID(const FSSpec *spec, long *theDirID,
- Boolean *isDirectory);
-
-pascal OSErr GetDirectoryID(short vRefNum,long dirID,ConstStr255Param name,
- long *theDirID,Boolean *isDirectory);
-
-
-
-/*****************************************************************************/
-
-pascal OSErr GetCatInfoNoName(short vRefNum,
- long dirID,
- ConstStr255Param name,
- CInfoPBPtr pb);
-/* Call PBGetCatInfoSync ignoring returned name.
- GetCatInfoNoName uses vRefNum, dirID and name to call PBGetCatInfoSync
- in cases where the returned object is not needed by the caller.
- The vRefNum, dirID and name parameters are not touched, and the pb
- parameter is initialized by PBGetCatInfoSync except that ioNamePtr in
- the parameter block is always returned as NULL (since it might point
- to GetCatInfoNoName's local variable tempName).
-
- I noticed using this code in several places, so here it is once.
- This reduces the code size of MoreFiles.
-
- 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.
- pb input: A pointer to CInfoPBRec.
- output: The parameter block as filled in by
- PBGetCatInfoSync except that ioNamePtr will
- always be NULL.
-
- 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
- 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
-
-*/
-
-
-/*****************************************************************************/
-
-
-pascal OSErr DetermineVRefNum(ConstStr255Param pathname,
- short vRefNum,
- short *realVRefNum);
-/* Determine the real volume reference number.
- The DetermineVRefNum function determines the volume reference number of
- a volume from a pathname, a volume specification, or a combination
- of the two.
- WARNING: Volume names on the Macintosh are *not* unique -- Multiple
- mounted volumes can have the same name. For this reason, the use of a
- volume name or full pathname to identify a specific volume may not
- produce the results you expect. If more than one volume has the same
- name and a volume name or full pathname is used, the File Manager
- currently uses the first volume it finds with a matching name in the
- volume queue.
-
- pathName input: Pointer to a full pathname or nil. If you pass in a
- partial pathname, it is ignored. A full pathname to a
- volume must end with a colon character (:).
- vRefNum input: Volume specification (volume reference number, working
- directory number, drive number, or 0).
- realVRefNum output: The real volume reference number.
-
- Result Codes
- noErr 0 No error
- nsvErr -35 No such volume
- paramErr -50 No default volume
-*/
-
-
-/*****************************************************************************/
-
-pascal OSErr FSpGetFullPath(const FSSpec *spec,
- short *fullPathLength,
- Handle *fullPath);
-/* Get a full pathname to a volume, directory or file.
- The GetFullPath function builds a full pathname to the specified
- object. The full pathname is returned in the newly created handle
- fullPath and the length of the full pathname is returned in
- fullPathLength. Your program is responsible for disposing of the
- fullPath handle.
-
- spec input: An FSSpec record specifying the object.
- fullPathLength output: The number of characters in the full pathname.
- If the function fails to create a full pathname,
- it sets fullPathLength to 0.
- fullPath output: A handle to the newly created full pathname
- buffer. If the function fails to create a
- full pathname, it sets fullPath to NULL.
-
- Result Codes
- noErr 0 No error
- nsvErr -35 No such volume
- ioErr -36 I/O error
- bdNamErr -37 Bad filename
- fnfErr -43 File or directory does not exist
- paramErr -50 No default volume
- memFullErr -108 Not enough memory
- 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: GetFullPath
-*/
-
-/*****************************************************************************/
-
-pascal OSErr FSpLocationFromFullPath(short fullPathLength,
- const void *fullPath,
- FSSpec *spec);
-/* Get a FSSpec from a full pathname.
- The FSpLocationFromFullPath function returns a FSSpec to the object
- specified by full pathname. This function requires the Alias Manager.
-
- fullPathLength input: The number of characters in the full pathname
- of the target.
- fullPath input: A pointer to a buffer that contains the full
- pathname of the target. The full pathname
- starts with the name of the volume, includes
- all of the directory names in the path to the
- target, and ends with the target name.
- spec output: An FSSpec record specifying the object.
-
- Result Codes
- noErr 0 No error
- nsvErr -35 The volume is not mounted
- fnfErr -43 Target not found, but volume and parent
- directory found
- paramErr -50 Parameter error
- usrCanceledErr -128 The user canceled the operation
-
- __________
-
- See also: LocationFromFullPath
-*/
-
-
-/*****************************************************************************/
-
-pascal OSErr GetFullPath(short vRefNum,
- long dirID,
- ConstStr255Param name,
- short *fullPathLength,
- Handle *fullPath);
-/* Get a full pathname to a volume, directory or file.
- The GetFullPath function builds a full pathname to the specified
- object. The full pathname is returned in the newly created handle
- fullPath and the length of the full pathname is returned in
- fullPathLength. Your program is responsible for disposing of the
- fullPath handle.
-
- Note that a full pathname can be made to a file/directory that does not
- yet exist if all directories up to that file/directory exist. In this case,
- GetFullPath will return a fnfErr.
-
- 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.
- fullPathLength output: The number of characters in the full pathname.
- If the function fails to create a full
- pathname, it sets fullPathLength to 0.
- fullPath output: A handle to the newly created full pathname
- buffer. If the function fails to create a
- full pathname, it sets fullPath to NULL.
-
- Result Codes
- noErr 0 No error
- nsvErr -35 No such volume
- ioErr -36 I/O error
- bdNamErr -37 Bad filename
- fnfErr -43 File or directory does not exist (fullPath
- and fullPathLength are still valid)
- paramErr -50 No default volume
- memFullErr -108 Not enough memory
- 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: FSpGetFullPath
-*/
-
-
-
-/*****************************************************************************/
-
-pascal OSErr ChangeCreatorType(short vRefNum,
- long dirID,
- ConstStr255Param name,
- OSType creator,
- OSType fileType);
-/* Change the creator or file type of a file.
- The ChangeCreatorType function changes the creator or file type of a file.
-
- vRefNum input: Volume specification.
- dirID input: Directory ID.
- name input: The name of the file.
- creator input: The new creator type or 0x00000000 to leave
- the creator type alone.
- fileType input: The new file type or 0x00000000 to leave the
- file type alone.
-
- 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
- fLckdErr -45 File is locked
- vLckdErr -46 Volume is locked or read-only
- paramErr -50 No default volume
- dirNFErr -120 Directory not found or incomplete pathname
- notAFileErr -1302 Name was not a file
- afpAccessDenied -5000 User does not have the correct access
- afpObjectTypeErr -5025 Directory not found or incomplete pathname
-
- __________
-
- See also: FSpChangeCreatorType
-*/
-
-/*****************************************************************************/
-
-pascal OSErr FSpChangeCreatorType(const FSSpec *spec,
- OSType creator,
- OSType fileType);
-/* Change the creator or file type of a file.
- The FSpChangeCreatorType function changes the creator or file type of a file.
-
- spec input: An FSSpec record specifying the file.
- creator input: The new creator type or 0x00000000 to leave
- the creator type alone.
- fileType input: The new file type or 0x00000000 to leave the
- file type alone.
-
- 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
- fLckdErr -45 File is locked
- vLckdErr -46 Volume is locked or read-only
- paramErr -50 No default volume
- dirNFErr -120 Directory not found or incomplete pathname
- notAFileErr -1302 Name was not a file
- afpAccessDenied -5000 User does not have the correct access
- afpObjectTypeErr -5025 Directory not found or incomplete pathname
-
- __________
-
- See also: ChangeCreatorType
-*/
-
-
-/*****************************************************************************/
-
-pascal OSErr BumpDate(short vRefNum,
- long dirID,
- ConstStr255Param name);
-/* Update the modification date of a file or directory.
- The BumpDate function changes the modification date of a file or
- directory to the current date/time. If the modification date is already
- equal to the current date/time, then add one second to the
- modification date.
-
- 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.
-
- 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
- fLckdErr -45 File is locked
- vLckdErr -46 Volume is locked or read-only
- paramErr -50 No default volume
- 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: FSpBumpDate
-*/
-
-/*****************************************************************************/
-
-pascal OSErr FSpBumpDate(const FSSpec *spec);
-/* Update the modification date of a file or directory.
- The FSpBumpDate function changes the modification date of a file or
- directory to the current date/time. If the modification date is already
- equal to the current date/time, then add one second to the
- modification date.
-
- spec input: An FSSpec record specifying the object.
-
- 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
- fLckdErr -45 File is locked
- vLckdErr -46 Volume is locked or read-only
- paramErr -50 No default volume
- 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: BumpDate
-*/
-
-/*****************************************************************************/
-
-pascal OSErr OnLine(FSSpecPtr volumes,
- short reqVolCount,
- short *actVolCount,
- short *volIndex);
-/* Return the list of volumes currently mounted.
- The OnLine function returns the list of volumes currently mounted in
- an array of FSSpec records.
-
- A noErr result indicates that the volumes array was filled
- (actVolCount == reqVolCount) and there may be additional volumes
- mounted. A nsvErr result indicates that the end of the volume list
- was found and actVolCount volumes were actually found this time.
-
- volumes input: Pointer to array of FSSpec where the volume list
- is returned.
- reqVolCount input: Maximum number of volumes to return (the number of
- elements in the volumes array).
- actVolCount output: The number of volumes actually returned.
- volIndex input: The current volume index position. Set to 1 to
- start with the first volume.
- output: The volume index position to get the next volume.
- Pass this value the next time you call OnLine to
- start where you left off.
-
- Result Codes
- noErr 0 No error, but there are more volumes
- to list
- nsvErr -35 No more volumes to be listed
- paramErr -50 volIndex was <= 0
-*/
-
-/*****************************************************************************/
-
-pascal OSErr DTGetComment(short vRefNum,
- long dirID,
- ConstStr255Param name,
- Str255 comment);
-/* Get a file or directory's Finder comment field (if any).
- The DTGetComment function gets a file or directory's Finder comment
- field (if any) from the Desktop Manager or if the Desktop Manager is
- not available, from the Finder's Desktop file.
-
- IMPORTANT NOTE: 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.
-
- 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.
- comment output: A Str255 where the comment is to be returned.
-
- Result Codes
- noErr 0 No error
- nsvErr -35 Volume not found
- ioErr -36 I/O error
- fnfErr -43 File not found
- paramErr -50 Volume doesn't support this function
- rfNumErr -51 Reference number invalid
- extFSErr -58 External file system error - no file
- system claimed this call.
- desktopDamagedErr -1305 The desktop database has become corrupted -
- the Finder will fix this, but if your
- application is not running with the
- Finder, use PBDTReset or PBDTDelete
- afpItemNotFound -5012 Information not found
-
- __________
-
- Also see: DTCopyComment, FSpDTCopyComment, DTSetComment, FSpDTSetComment,
- FSpDTGetComment
-*/
-
-/*****************************************************************************/
-
-pascal OSErr FSpDTGetComment(const FSSpec *spec,
- Str255 comment);
-/* Get a file or directory's Finder comment field (if any).
- The FSpDTGetComment function gets a file or directory's Finder comment
- field (if any) from the Desktop Manager or if the Desktop Manager is
- not available, from the Finder's Desktop file.
-
- IMPORTANT NOTE: 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.
-
- spec input: An FSSpec record specifying the file or directory.
- comment output: A Str255 where the comment is to be returned.
-
- Result Codes
- noErr 0 No error
- nsvErr -35 Volume not found
- ioErr -36 I/O error
- fnfErr -43 File not found
- paramErr -50 Volume doesn't support this function
- rfNumErr -51 Reference number invalid
- extFSErr -58 External file system error - no file
- system claimed this call.
- desktopDamagedErr -1305 The desktop database has become corrupted -
- the Finder will fix this, but if your
- application is not running with the
- Finder, use PBDTReset or PBDTDelete
- afpItemNotFound -5012 Information not found
-
- __________
-
- Also see: DTCopyComment, FSpDTCopyComment, DTSetComment, FSpDTSetComment,
- DTGetComment
-*/
-
-/*****************************************************************************/
-
-pascal OSErr DTOpen(ConstStr255Param volName,
- short vRefNum,
- short *dtRefNum,
- Boolean *newDTDatabase);
-/* Open a volume's desktop database and return the desktop database refNum.
- The DTOpen function opens a volume's desktop database. It returns
- the reference number of the desktop database and indicates if the
- desktop database was created as a result of this call (if it was created,
- then it is empty).
-
- volName input: A pointer to the name of a mounted volume
- or nil.
- vRefNum input: Volume specification.
- dtRefNum output: The reference number of Desktop Manager's
- desktop database on the specified volume.
- newDTDatabase output: true if the desktop database was created as a
- result of this call and thus empty.
- false if the desktop database was already created,
- or if it could not be determined if it was already
- created.
-
- Result Codes
- noErr 0 No error
- nsvErr -35 Volume not found
- ioErr -36 I/O error
- paramErr -50 Volume doesn't support this function
- extFSErr -58 External file system error - no file
- system claimed this call.
- desktopDamagedErr -1305 The desktop database has become corrupted -
- the Finder will fix this, but if your
- application is not running with the
- Finder, use PBDTReset or PBDTDelete
-*/
-
-/*****************************************************************************/
-
-pascal OSErr HGetVolParms(ConstStr255Param volName,
- short vRefNum,
- GetVolParmsInfoBuffer *volParmsInfo,
- long *infoSize);
-/* Determine the characteristics of a volume.
- The HGetVolParms function returns information about the characteristics
- of a volume. A result of paramErr usually just means the volume doesn't
- support PBHGetVolParms and the feature you were going to check
- for isn't available.
-
- volName input: A pointer to the name of a mounted volume
- or nil.
- vRefNum input: Volume specification.
- volParmsInfo input: Pointer to GetVolParmsInfoBuffer where the
- volume attributes information is returned.
- output: Atributes information.
- infoSize input: Size of buffer pointed to by volParmsInfo.
- output: Size of data actually returned.
-
- Result Codes
- noErr 0 No error
- nsvErr -35 Volume not found
- paramErr -50 Volume doesn't support this function
-
- __________
-
- Also see the macros for checking attribute bits in MoreFilesExtras.h
-*/
-
-/*****************************************************************************/
-
-pascal OSErr DeleteDirectoryContents(short vRefNum,
- long dirID,
- ConstStr255Param name);
-/* Delete the contents of a directory.
- The DeleteDirectoryContents function deletes the contents of a directory.
- All files and subdirectories in the specified directory are deleted.
- If a locked file or directory is encountered, it is unlocked and then
- deleted. If any unexpected errors are encountered,
- DeleteDirectoryContents quits and returns to the caller.
-
- vRefNum input: Volume specification.
- dirID input: Directory ID.
- name input: Pointer to directory name, or nil when dirID specifies
- a directory that's the object.
-
- 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
- wPrErr -44 Hardware volume lock
- fLckdErr -45 File is locked
- vLckdErr -46 Software volume lock
- fBsyErr -47 File busy, directory not empty, or working
- directory control block open
- paramErr -50 No default volume
- 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
-
- __________
-
- Also see: DeleteDirectory
-*/
-
-/*****************************************************************************/
-
-pascal OSErr DeleteDirectory(short vRefNum,
- long dirID,
- ConstStr255Param name);
-/* Delete a directory and its contents.
- The DeleteDirectory function deletes a directory and its contents.
- All files and subdirectories in the specified directory are deleted.
- If a locked file or directory is encountered, it is unlocked and then
- deleted. After deleting the directories contents, the directory is
- deleted. If any unexpected errors are encountered, DeleteDirectory
- quits and returns to the caller.
-
- vRefNum input: Volume specification.
- dirID input: Directory ID.
- name input: Pointer to directory name, or nil when dirID specifies
- a directory that's the object.
-
- 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
- wPrErr -44 Hardware volume lock
- fLckdErr -45 File is locked
- vLckdErr -46 Software volume lock
- fBsyErr -47 File busy, directory not empty, or working
- directory control block open
- paramErr -50 No default volume
- 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
-
- __________
-
- Also see: DeleteDirectoryContents
-*/
-
-/*****************************************************************************/
-
-pascal OSErr DTSetComment(short vRefNum,
- long dirID,
- ConstStr255Param name,
- ConstStr255Param comment);
-/* Set a file or directory's Finder comment field.
- The DTSetComment function sets a file or directory's Finder comment
- field. The volume must support the Desktop Manager because you only
- have read access to the Desktop file.
-
- 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.
- comment input: The comment to add. Comments are limited to 200 characters;
- longer comments are truncated.
-
- Result Codes
- noErr 0 No error
- nsvErr -35 Volume not found
- ioErr -36 I/O error
- fnfErr -43 File or directory doesnt exist
- paramErr -50 Volume doesn't support this function
- wPrErr -44 Volume is locked through hardware
- vLckdErr -46 Volume is locked through software
- rfNumErr -51 Reference number invalid
- extFSErr -58 External file system error - no file
- system claimed this call.
- desktopDamagedErr -1305 The desktop database has become corrupted -
- the Finder will fix this, but if your
- application is not running with the
- Finder, use PBDTReset or PBDTDelete
-
- __________
-
- Also see: DTCopyComment, FSpDTCopyComment, FSpDTSetComment, DTGetComment,
- FSpDTGetComment
-*/
-
-/*****************************************************************************/
-
-pascal OSErr FSpDTSetComment(const FSSpec *spec,
- ConstStr255Param comment);
-/* Set a file or directory's Finder comment field.
- The FSpDTSetComment function sets a file or directory's Finder comment
- field. The volume must support the Desktop Manager because you only
- have read access to the Desktop file.
-
- spec input: An FSSpec record specifying the file or directory.
- comment input: The comment to add. Comments are limited to 200 characters;
- longer comments are truncated.
-
- Result Codes
- noErr 0 No error
- nsvErr -35 Volume not found
- ioErr -36 I/O error
- fnfErr -43 File or directory doesnt exist
- wPrErr -44 Volume is locked through hardware
- vLckdErr -46 Volume is locked through software
- rfNumErr -51 Reference number invalid
- paramErr -50 Volume doesn't support this function
- extFSErr -58 External file system error - no file
- system claimed this call.
- desktopDamagedErr -1305 The desktop database has become corrupted -
- the Finder will fix this, but if your
- application is not running with the
- Finder, use PBDTReset or PBDTDelete
-
- __________
-
- Also see: DTCopyComment, FSpDTCopyComment, DTSetComment, DTGetComment,
- FSpDTGetComment
-*/
-
-/*****************************************************************************/
-
-pascal OSErr XGetVInfo(short volReference,
- StringPtr volName,
- short *vRefNum,
- UnsignedWide *freeBytes,
- UnsignedWide *totalBytes);
-/* Get extended information about a mounted volume.
- The XGetVInfo function returns the name, volume reference number,
- available space (in bytes), and total space (in bytes) for the
- specified volume. You can specify the volume by providing its drive
- number, volume reference number, or 0 for the default volume.
- This routine is compatible with volumes up to 2 terabytes.
-
- volReference input: The drive number, volume reference number,
- or 0 for the default volume.
- volName input: A pointer to a buffer (minimum Str27) where
- the volume name is to be returned or must
- be nil.
- output: The volume name.
- vRefNum output: The volume reference number.
- freeBytes output: The number of free bytes on the volume.
- freeBytes is an UnsignedWide value.
- totalBytes output: The total number of bytes on the volume.
- totalBytes is an UnsignedWide value.
-
- Result Codes
- noErr 0 No error
- nsvErr -35 No such volume
- paramErr -50 No default volume
-
- __________
-
- Also see: HGetVInfo
-*/
-
-/*****************************************************************************/
-
-pascal OSErr HGetVInfo(short volReference,
- StringPtr volName,
- short *vRefNum,
- unsigned long *freeBytes,
- unsigned long *totalBytes);
-/* Get information about a mounted volume.
- The HGetVInfo function returns the name, volume reference number,
- available space (in bytes), and total space (in bytes) for the
- specified volume. You can specify the volume by providing its drive
- number, volume reference number, or 0 for the default volume.
- This routine is compatible with volumes up to 4 gigabytes.
-
- volReference input: The drive number, volume reference number,
- or 0 for the default volume.
- volName input: A pointer to a buffer (minimum Str27) where
- the volume name is to be returned or must
- be nil.
- output: The volume name.
- vRefNum output: The volume reference number.
- freeBytes output: The number of free bytes on the volume.
- freeBytes is an unsigned long value.
- totalBytes output: The total number of bytes on the volume.
- totalBytes is an unsigned long value.
-
- Result Codes
- noErr 0 No error
- nsvErr -35 No such volume
- paramErr -50 No default volume
-
- __________
-
- Also see: XGetVInfo
-*/
-
-/*****************************************************************************/
-
-pascal OSErr GetDirName(short vRefNum,
- long dirID,
- Str31 name);
-/* Get the name of a directory from its directory ID.
- The GetDirName function gets the name of a directory from its
- directory ID.
-
- vRefNum input: Volume specification.
- dirID input: Directory ID.
- name output: Points to a Str31 where the directory name is to be
- returned.
-
- 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
- name parameter 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
-*/
-
-
-/*****************************************************************************/
-
-pascal OSErr GetVolFileSystemID(ConstStr255Param pathname,
- short vRefNum,
- short *fileSystemID);
-/* Get a volume's file system ID.
- The GetVolFileSystemID function returned the file system ID of
- a mounted volume. The file system ID identifies the file system
- that handles requests to a particular volume. Here's a partial list
- of file system ID numbers (only Apple's file systems are listed):
- FSID File System
- ----- -----------------------------------------------------
- $0000 Macintosh HFS or MFS
- $0100 ProDOS File System
- $0101 PowerTalk Mail Enclosures
- $4147 ISO 9660 File Access (through Foreign File Access)
- $4242 High Sierra File Access (through Foreign File Access)
- $464D QuickTake File System (through Foreign File Access)
- $4953 Macintosh PC Exchange (MS-DOS)
- $4A48 Audio CD Access (through Foreign File Access)
- $4D4B Apple Photo Access (through Foreign File Access)
-
- See the Technical Note "FL 35 - Determining Which File System
- Is Active" and the "Guide to the File System Manager" for more
- information.
-
- pathName input: Pointer to a full pathname or nil. If you pass
- in a partial pathname, it is ignored. A full
- pathname to a volume must contain at least
- one colon character (:) and must not start with
- a colon character.
- vRefNum input: Volume specification (volume reference number,
- working directory number, drive number, or 0).
- fileSystemID output: The volume's file system ID.
-
- Result Codes
- noErr 0 No error
- nsvErr -35 No such volume
- paramErr -50 No default volume, or pb was NULL
-*/
-
-/*****************************************************************************/
-
-pascal OSErr GetDInfo(short vRefNum,
- long dirID,
- ConstStr255Param name,
- DInfo *fndrInfo);
-/* Get the finder information for a directory.
- The GetDInfo function gets the finder information for a directory.
-
- 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.
- fndrInfo output: If the object is a directory, then its DInfo.
-
- 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
- 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
-
- __________
-
- Also see: FSpGetDInfo, FSpGetFInfoCompat
-*/
-
-/*****************************************************************************/
-
-pascal OSErr FSpGetDInfo(const FSSpec *spec,
- DInfo *fndrInfo);
-/* Get the finder information for a directory.
- The FSpGetDInfo function gets the finder information for a directory.
-
- spec input: An FSSpec record specifying the directory.
- fndrInfo output: If the object is a directory, then its DInfo.
-
- 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
- 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
-
- __________
-
- Also see: FSpGetFInfoCompat, GetDInfo
+ 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 */
+#endif /* _MACSTUFF_H */
diff --git a/macos/source/mactime.c b/macos/source/mactime.c
index fcdd440..af9ad5e 100644
--- a/macos/source/mactime.c
+++ b/macos/source/mactime.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.htmlhtml
+ 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
*/
/* -----------------------------------------------------------------------------
diff --git a/macos/source/mactime.h b/macos/source/mactime.h
index fa70c7f..cb76aa4 100644
--- a/macos/source/mactime.h
+++ b/macos/source/mactime.h
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 1999-Oct-05 or later
+ 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, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+ 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_
diff --git a/macos/source/pathname.c b/macos/source/pathname.c
index 166d872..6bf1003 100644
--- a/macos/source/pathname.c
+++ b/macos/source/pathname.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2003 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.htmlhtml
+ 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
*/
/*---------------------------------------------------------------------------
@@ -45,6 +45,43 @@ const char ResourceMark[] = "XtraStuf.mac:"; /* see also macos.c */
/*****************************************************************************/
+/*
+ *----------------------------------------------------------------------
+ *
+ * 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;
+}
/*
@@ -79,15 +116,19 @@ return (unsigned short) strlen(VolumeName);
/* Function FindNewExtractFolder() */
/***********************************/
-char *FindNewExtractFolder(char *ExtractPath)
+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")
@@ -98,26 +139,49 @@ for (tmpPtr = ExtractPath; *tmpPtr; tmpPtr++)
namePtr = tmpPtr;
}
-if (folderCount > 1)
+if (folderCount > 1) {
namelen = strlen(namePtr);
-else
+} else {
namelen = strlen(ExtractPath);
+}
-for (count = 0; count < 99; count++)
- {
- memset(buffer,0,sizeof(buffer));
+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;
+ 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;
+ 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;
@@ -152,7 +216,7 @@ namelen = strlen(namePtr);
* 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.
+ * ':' 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
@@ -203,15 +267,14 @@ short actVolCount, volIndex = 1, VolCount = 0;
OSErr err;
short i, foundVRefNum;
FSSpec spec;
-UnsignedWide freeBytes;
-UnsignedWide totalBytes;
-UnsignedWide MaxFreeBytes;
+UInt64 freeBytes;
+UInt64 totalBytes;
+UInt64 MaxFreeBytes;
err = OnLine(volumes, 50, &actVolCount, &volIndex);
printerr("OnLine:", (err != -35) && (err != 0), err, __LINE__, __FILE__, "");
-MaxFreeBytes.hi = 0;
-MaxFreeBytes.lo = 0;
+MaxFreeBytes = 0;
for (i=0; i < actVolCount; i++)
{
@@ -221,15 +284,13 @@ for (i=0; i < actVolCount; i++)
&freeBytes,
&totalBytes);
- if (MaxFreeBytes.hi < freeBytes.hi) {
- MaxFreeBytes.hi = freeBytes.hi;
- MaxFreeBytes.lo = freeBytes.lo;
+ if (MaxFreeBytes < freeBytes) {
+ MaxFreeBytes = freeBytes;
foundVRefNum = volumes[i].vRefNum;
}
- if ((freeBytes.hi == 0) && (MaxFreeBytes.lo < freeBytes.lo)) {
- MaxFreeBytes.hi = freeBytes.hi;
- MaxFreeBytes.lo = freeBytes.lo;
+ if ((freeBytes == 0) && (MaxFreeBytes < freeBytes)) {
+ MaxFreeBytes = freeBytes;
foundVRefNum = volumes[i].vRefNum;
}
diff --git a/macos/source/pathname.h b/macos/source/pathname.h
index 05a9078..1a39ed3 100644
--- a/macos/source/pathname.h
+++ b/macos/source/pathname.h
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 1999-Oct-05 or later
+ 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, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+ 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
@@ -30,7 +30,12 @@ char *GetFullPathFromID(char *CompletePath, short vRefNum, long dirID,
char *GetAppName(void);
void createArchiveName(char *Path);
void FindDesktopFolder(char *Path);
-char *FindNewExtractFolder(char *ExtractPath);
+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);
diff --git a/macos/source/unixlike.c b/macos/source/unixlike.c
index 017d3fa..4eb55da 100644
--- a/macos/source/unixlike.c
+++ b/macos/source/unixlike.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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.info-zip.org/pub/infozip/license.html
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
/*---------------------------------------------------------------------------
diff --git a/man/zip.1 b/man/zip.1
index 15814d4..0c2fce0 100644
--- a/man/zip.1
+++ b/man/zip.1
@@ -1,57 +1,59 @@
.\" =========================================================================
-.\" Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+.\" Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
.\"
-.\" See the accompanying file LICENSE, version 2005-Feb-10 or later
+.\" 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 "27 February 2005 (v2.31)" Info-ZIP
+.TH ZIP 1L "16 June 2008 (v3.0)" Info-ZIP
.SH NAME
-zip, zipcloak, zipnote, zipsplit \- package and compress (archive) files
+zip \- package and compress (archive) files
.SH SYNOPSIS
.B zip
-.RB [ \-aABcdDeEfFghjklLmoqrRSTuvVwXyz!@$ ]
-.RB [ \-b\ path ]
-.RB [ \-n\ suffixes ]
-.RB [ \-t\ mmddyyyy ]
-.RB [ \-tt\ mmddyyyy ]
-.I [ zipfile
-.I [ file1
-.IR file2 " .\|.\|." ]]
-.RB [ \-xi\ list ]
+.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
-.RB [ \-dhL ]
-.RB [ \-b\ path ]
-.I zipfile
+(see separate man page)
.PP
.B zipnote
-.RB [ \-hwL ]
-.RB [ \-b\ path ]
-.I zipfile
+(see separate man page)
.PP
.B zipsplit
-.RB [ \-hiLpst ]
-.RB [ \-n\ size ]
-.RB [ \-b\ path ]
-.I zipfile
+(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 NT, Minix, Atari and Macintosh, Amiga and Acorn RISC OS.
-.LP
-It is analogous to a combination of the UNIX commands
+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)),
+.RI ( unzip (1L))
unpacks
.I zip
archives.
@@ -59,23 +61,59 @@ The
.I zip
and
.IR unzip (1L)
-programs can work with archives produced by PKZIP,
+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
-.IR zip .
-.I zip
-version 2.31 is compatible with PKZIP 2.04.
-Note that PKUNZIP 1.10 cannot extract files produced by PKZIP 2.04
-or
-.I zip
-2.31. You must use PKUNZIP 2.04g or
-.I unzip
-5.0p1 (or later versions) to extract them.
+\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
-For a brief help on
-.I zip
-and
-.I unzip,
+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;
@@ -96,17 +134,29 @@ 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.
-.I zip
-automatically chooses the better of the two for each file to be compressed.
+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 or add entries for new names.
+archive (matching the relative names as stored in
+the archive) or add entries for new names.
For example,
if
.I foo.zip
@@ -122,6 +172,10 @@ 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
@@ -143,14 +197,35 @@ with
.I foo/file2
unchanged from before.
.LP
-If the file list is specified as
-.BR \-@ ,
-[Not on MacOS]
+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.
-Under UNIX,
+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
-.IR find (1)
+\fIfind\fP\ (1)
command.
For example,
to archive all the C source files in the current directory and
@@ -159,6 +234,8 @@ its subdirectories:
\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
@@ -178,9 +255,7 @@ input from another program. For example:
.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
-.B \-r
-option, because
+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
@@ -207,11 +282,38 @@ package, or by
.I gunzip
which is provided in the
.I gzip
-package. For example:
+package (but some
+.I gunzip
+may not support this if
+.I zip
+used the Zip64 extensions). For example:
.IP
-\fCdd if=/dev/nrst0 ibs=16k | funzip | tar xvf -\fP
+\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 changing an existing
+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
@@ -222,16 +324,219 @@ has been completed without error.
If the name of the
.I zip
archive does not contain an extension, the extension
-.IR .zip
+\fB.zip\fP
is added. If the name already contains an extension other than
-.IR .zip
-the existing extension is kept unchanged.
+\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
-.BI \-A
+.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
@@ -242,21 +547,60 @@ 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 Zip is capable of adjusting
-or updating these without corrupting them.
-.B \-J
-can be used to remove the SFX stub if other updates need to be made.
+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
-.BI \-B
+.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
-.BI \-Bn
+.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)
+bit 1: Use LF rather than CR/LF as delimiter (Edit/Enscribe)
.RE
.RS
bit 2: Space fill record to maximum record length (Enscribe)
@@ -265,10 +609,15 @@ bit 2: Space fill record to maximum record length (Enscribe)
bit 3: Trim trailing space (Enscribe)
.RE
.RS
-bit 8: Force 30K (Expand) large read for unstructured files
+bit 8: Force 30K (Expand) large read for unstructured files
.RE
+
.TP
-.BI \-b\ path
+.PD 0
+.BI \-b\ \fRpath
+.TP
+.PD
+.B \-\-temp-path\ \fRpath
Use the specified
.I path
for the temporary
@@ -285,18 +634,58 @@ archive in the directory
.IR /tmp ,
copying over
.I stuff.zip
-to the current directory when done. This option is only useful when
-updating an existing archive, and the file system containing this
+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.
+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.
@@ -311,7 +700,7 @@ will remove the entry
all of the files that start with
.IR foo/harry/ ,
and all of the files that end with
-.I \&.o
+.B \&.o
(in any path).
Note that shell pathname expansion has been inhibited with backslashes,
so that
@@ -322,28 +711,125 @@ enabling
to match on the contents of the
.I zip
archive instead of the contents of the current directory.
-.IP
-Under systems where the shell does not expand wildcards, such as MSDOS,
-the backslashes are not needed. The above would then be
+(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
+\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.
+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
@@ -355,19 +841,72 @@ example under Unix with sh:
ZIPOPT="-D"; export ZIPOPT
.RE
.IP
-(The variable ZIPOPT can be used for any option except
-.B \-i
-and
-.B \-x
-and can include several options.) The option
+(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 cannot be set as default in the ZIPOPT environment
-variable.
+"*/" 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
@@ -376,11 +915,21 @@ to a prompt
.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
@@ -400,18 +949,13 @@ For example:
.IP
This command should be run from the same directory from which the original
.I zip
-command was run,
-since paths stored in
+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
-.B \-f
-,
-.B \-u
-and
-.B \-o
+\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
@@ -419,22 +963,46 @@ 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. This option can be used if some portions of the archive
-are missing. It is not guaranteed to work, so you MUST make a backup
-of the original archive first.
+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
-.B \-FF
-the compressed sizes given inside the damaged archive are not trusted
-and zip scans for special signatures to identify the limits between
-the archive members. The single
+\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, for example
-if it has only been truncated, so try this option first.
+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
@@ -445,9 +1013,96 @@ 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
-.I zip.
+\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,
@@ -456,15 +1111,37 @@ 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
-.BI \-i\ files
+.PD
+.B \-\-include\ \fRfiles
Include only the specified files, as in:
.RS
.IP
@@ -484,14 +1161,85 @@ 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. Not escaping wildcards on shells that do
-wildcard substitution before zip gets the command line may seem to
-work but files in subdirectories matching the pattern will never be
-checked and so not matched. For shells, such as Win32 command
-prompts, that do not replace file patterns containing wildcards
-with the respective file names,
-.I zip
-will do the recursion and escaping the wildcards is not needed.
+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
@@ -501,75 +1249,155 @@ Also possible:
.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
-[Acorn RISC OS] Don't scan through Image files. When used,
-.I zip
-will not
+.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.
-.IP
+
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 path).
+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),
+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 ensures that
-.I unzip \-a
+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
-.I zip \-l.
-See the note on binary detection for
-.B \-ll
-below.
+\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 and a warning will be
-issued when a file is converted that later is detected to be binary.
+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.
-.IP
-In Zip 2.31 binary detection has been changed from a simple percentage
-of binary characters being considered binary to a more selective method
-that should consider files in many character sets, including \fIUTF-8\fP,
-that only include text characters in that character set to be text.
-This allows
-.I unzip -a
-to convert these files.
+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,
@@ -585,9 +1413,45 @@ combination with
.B \-T
to test the archive before removing all input files.
.TP
-.BI \-n\ suffixes
+.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
-.I suffixes.
+\fBsuffixes\fR.
Such files are simply stored (0% compression) in the output zip file,
so that
.I zip
@@ -621,13 +1485,13 @@ The environment variable ZIPOPT can be used to change the default options. For
example under Unix with csh:
.RS
.IP
-\fCsetenv ZIPOPT "-n .gif:.zip"\fP
+setenv ZIPOPT "-n .gif:.zip"
.RE
.IP
To attempt compression on all files, use:
.RS
.IP
-\fCzip -n : foo\fP
+zip -n : foo
.RE
.IP
The maximum compression option
@@ -635,19 +1499,32 @@ The maximum compression option
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, zip does not compress files with filetypes in the list
+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
-.B \-N
-option of unzip. If
-.B \-c
-is used also, you are prompted for comments only for those files that do not
-have filenotes.
+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
@@ -656,33 +1533,88 @@ found among the entries in the
archive.
This can be used without any other operations, if desired.
For example:
-.RS
.IP
\fCzip -o foo\fP
-.RE
.IP
will change the last modified time of
-.I foo.zip
+\fBfoo.zip\fP
to the latest time of the entries in
-.IR foo.zip .
+.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
-\fB\-P\fP\ \fIpassword\fP
-use \fIpassword\fP to encrypt zipfile entries (if any). \fBTHIS IS
+.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 encryption provided by standard
+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
-.BI \-Qn
+.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
@@ -694,129 +1626,373 @@ bit 1: Add headers for all files
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
-\fCzip -r foo foo\fP
+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
-.I foo
+.B foo
are saved in a
.I zip
-archive named
-.IR foo.zip ,
-including files with names starting with ".",
+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
-.I foo
+\fBfoo\fP
and its subdirectories, use the
-.B \-i
+\fB\-i\fP
option to specify the pattern of files to be included.
You should not use
-.B \-r
-with the name ".*",
-since that matches ".."
+\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
+\fCzip -R foo "*.c"\fP
.RE
.IP
-In this case, all the files matching *.c in the tree starting at the
+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
-.IR foo.zip .
+\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
-.BI \-t\ mmddyyyy
+.PD 0
+.BI \-t\ \fRmmddyyyy
+.TP
+.PD
+.B \-\-from\-date\ \fRmmddyyyy
Do not operate on files modified prior to the specified date,
where
-.I mm
-is the month (0-12),
-.I dd
-is the day of the month (1-31),
+.B mm
+is the month (00-12),
+.B dd
+is the day of the month (01-31),
and
-.I yyyy
+.B yyyy
is the year.
The
-.I ISO 8601
+.I ISO\ 8601
date format
-.I yyyy-mm-dd
+.B yyyy\-mm\-dd
is also accepted.
For example:
.RS
.IP
\fCzip -rt 12071991 infamy foo\fP
-.IP
+
\fCzip -rt 1991-12-07 infamy foo\fP
.RE
.IP
will add all the files in
-.I foo
+.B foo
and its subdirectories that were last modified on or after 7 December 1991,
to the
.I zip
archive
-.IR infamy.zip .
+.BR infamy.zip .
.TP
-.BI \-tt\ mmddyyyy
+.PD 0
+.BI \-tt\ \fRmmddyyyy
+.TP
+.PD
+.B \-\-before\-date\ \fRmmddyyyy
Do not operate on files modified after or at the specified date,
where
-.I mm
-is the month (0-12),
-.I dd
-is the day of the month (1-31),
+.B mm
+is the month (00-12),
+.B dd
+is the day of the month (01-31),
and
-.I yyyy
+.B yyyy
is the year.
The
-.I ISO 8601
+.I ISO\ 8601
date format
-.I yyyy-mm-dd
+.B yyyy\-mm\-dd
is also accepted.
For example:
.RS
.IP
\fCzip -rtt 11301995 infamy foo\fP
-.IP
+
\fCzip -rtt 1995-11-30 infamy foo\fP
.RE
.IP
will add all the files in
-.I foo
-and its subdirectories that were last modified before the 30 November 1995,
+.B foo
+and its subdirectories that were last modified before 30 November 1995,
to the
.I zip
archive
-.IR infamy.zip .
+.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
+.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
@@ -842,48 +2018,223 @@ into itself when you do this).
.IP
Note that the
.B \-u
-option with no arguments acts like the
+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 and requests verbose diagnostic
-info about zipfile structure oddities.
+progress indicator during compression (see \fB-dd\fR for more on dots) and
+requests verbose diagnostic info about zipfile structure oddities.
.IP
-When
+However, when
.B \-v
-is the only command line argument, and either stdin or stdout is
-not redirected to a file,
-a diagnostic screen is printed. In addition to the help screen header
-with program name, version, and release date, some pointers to the Info-ZIP
-home and distribution sites are given. Then, it 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.
+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
-[VMS] Save VMS file attributes and use portable form.
-.I zip
-archives created with this option are truncated at EOF but still may not be
-usable on other systems depending on the file types being zipped.
.TP
-.B \-VV
+.PD
+.B \-\-VMS\-portable
[VMS] Save VMS file attributes.
-.I zip
-archives created with this option include the entire file and should be able
-to recreate most VMS files on VMS systems but these archives will generally
-not be usable on other systems.
+(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. (default: use only
-the most recent version of a specified file).
+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
-.BI \-x\ files
+.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
@@ -891,16 +2242,15 @@ Explicitly exclude the specified files, as in:
.RE
.IP
which will include the contents of
-.I foo
+.B foo
in
-.I foo.zip
-while excluding all the files that end in \fI.o\fP.
+.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. If you do not escape wildcards in patterns
-it may seem to work but files in subdirectories will not be checked
-for matches.
+at all directory levels.
.IP
Also possible:
.RS
@@ -909,56 +2259,164 @@ Also possible:
.RE
.IP
which will include the contents of
-.I foo
+.B foo
in
-.I foo.zip
-while excluding all the files that match the patterns in the file exclude.lst
-(each file pattern on a separate line).
+.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).
+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
-Store symbolic links as such in the
+.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
-(UNIX only).
+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 VAX/VMS).
+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
-.IR # ,
+.BR # ,
where
.B \-0
indicates no compression (store all files),
.B \-1
-indicates the fastest compression method (less compression)
+indicates the fastest compression speed (less compression)
and
.B \-9
-indicates the slowest compression method (optimal compression, ignores
+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,
@@ -978,12 +2436,12 @@ creates the archive
(assuming it does not exist)
and puts all the files in the current directory in it, in compressed form
(the
-.I \&.zip
-suffix is added automatically,
-unless that archive name given contains a dot already;
+\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 does filename substitution,
+Because of the way the shell on Unix does filename substitution,
files starting with "." are not included;
to include these as well:
.IP
@@ -1047,17 +2505,49 @@ 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, though the ?, *, and [] special
-characters are implemented on other systems including MSDOS and Win32.
+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
-.RI ( sh (1)
-and
-.IR csh (1))
-do filename substitution on command arguments.
-The special characters are:
+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
@@ -1067,7 +2557,38 @@ match any number of characters (including none)
.TP
.B []
match any character in the range indicated within the brackets
-(example: [a\-f], [0\-9]).
+(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),
@@ -1107,27 +2628,25 @@ 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 backslash to make
+In general, use backslashes or double quotes for paths
+that have wildcards to make
.I zip
-do the pattern matching with the
-.B \-f
-(freshen) and
-.B \-d
-(delete) options,
-and sometimes after the
-.B \-x
-(exclude) option when used with an appropriate operation (add,
-.BR \-u ,
-.BR \-f ,
-or
-.BR \-d ).
+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
+.B ZIPOPT\ \
contains default options that will be used when running
-.I zip
+\fIzip\fR. The contents of this environment variable will get
+added to the command line just after the \fBzip\fR command.
.TP
-.B ZIP
+.B ZIP\ \ \ \ \
[Not on RISC OS and VMS] see ZIPOPT
.TP
.B Zip$Options
@@ -1137,7 +2656,6 @@ contains default options that will be used when running
[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.
-.I zip
.TP
.B ZIP_OPTS
[VMS] see ZIPOPT
@@ -1166,12 +2684,13 @@ program initialization.
a severe error in the zipfile format was detected. Processing probably
failed immediately.
.IP 6
-entry too large to split (with \fIzipsplit\fP), read, or write
+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
-.I zip \-T
-failed or out of memory
+\fIzip\fP -T failed or out of memory
.IP 9
the user aborted \fIzip\fP prematurely with control-C (or similar)
.IP 10
@@ -1190,19 +2709,20 @@ error writing to a file
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. The
-current mapping is as follows: 1 (success) for normal exit,
- and (0x7fff000? + 16*normal_zip_exit_status) for all errors, where the
-`?' is 0 (warning) for \fIzip\fP value 12, 2 (error) for the
-\fIzip\fP values 3, 6, 7, 9, 13, 16, 18,
-and 4 (fatal error) for the remaining ones.
+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
-2.31 is not compatible with PKUNZIP 1.10. Use
+3.0 is not compatible with PKUNZIP 1.10. Use
.I zip
1.1 to produce
.I zip
@@ -1211,7 +2731,7 @@ files which can be extracted by PKUNZIP 1.10.
.I zip
files produced by
.I zip
-2.31 must not be
+3.0 must not be
.I updated
by
.I zip
@@ -1235,12 +2755,13 @@ 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 Vax to MSDOS, type "set
-file type block" on the Vax. When transfering from MSDOS to Vax, type
-"set file type fixed" on the Vax. In both cases, type "set file type
+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 VMS, zip hangs for file specification that uses DECnet syntax
+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
@@ -1262,15 +2783,17 @@ to future RISC OS/2 versions. Therefore the value reported by
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.
-.LP
-Development of Zip 3.0 is underway. See that source distribution for
-many new features and the latest bug fixes.
.SH AUTHORS
-Copyright (C) 1997-2005 Info-ZIP.
+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
@@ -1281,14 +2804,12 @@ 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 to:
-.IR zip-bugs
-at
+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\fP),
-the make options used to compile it (see \fIzip\ \-v\fP),
+(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
@@ -1314,5 +2835,6 @@ 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.
+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/mktime.c b/mktime.c
deleted file mode 100644
index 0f1edc5..0000000
--- a/mktime.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/* free mktime function
- Copyright 1988, 1989 by David MacKenzie <djm@ai.mit.edu>
- and Michael Haertel <mike@ai.mit.edu>
- Unlimited distribution permitted provided this copyright notice is
- retained and any functional modifications are prominently identified. */
-
-/* Revised 1997 by Christian Spieler:
- The code was changed to get more conformance with ANSI's (resp. modern
- UNIX releases) definition for mktime():
- - Added adjustment for out-of-range values in the fields of struct tm.
- - Added iterations to get the correct UTC result for input values at
- the gaps when daylight saving time is switched on or off.
- - Allow forcing of DST "on" or DST "off" by setting `tm_isdst' field in
- the tm struct to positive number resp. zero. The `tm_isdst' field must
- be negative on entrance of mktime() to enable automatic determination
- if DST is in effect for the requested local time.
- - Added optional check for overflowing the time_t range. */
-
-/* Note: This version of mktime is ignorant of the tzfile.
- When the tm structure passed to mktime represents a local time that
- is valid both as DST time and as standard time (= time value in the
- gap when switching from DST back to standard time), the behaviour
- for `tm_isdst < 0' depends on the current timezone: TZ east of GMT
- assumes winter time, TZ west of GMT assumes summer time.
- Although mktime() (resp. mkgmtime()) tries to adjust for invalid values
- of struct tm members, this may fail for input values that are far away
- from the valid ranges. The adjustment process does not check for overflows
- or wrap arounds in the struct tm components. */
-
-#ifndef OF
-# ifdef __STDC__
-# define OF(a) a
-# else
-# define OF(a) ()
-# endif
-#endif
-
-#ifndef ZCONST
-# define ZCONST const
-#endif
-
-#include <time.h>
-
-time_t mkgmtime OF((struct tm *));
-time_t mktime OF((struct tm *));
-
-/* Return the equivalent in seconds past 12:00:00 a.m. Jan 1, 1970 GMT
- of the local time and date in the exploded time structure `tm',
- adjust out of range fields in `tm' and set `tm->tm_yday', `tm->tm_wday'.
- If `tm->tm_isdst < 0' was passed to mktime(), the correct setting of
- tm_isdst is determined and returned. Otherwise, mktime() assumes this
- field as valid; its information is used when converting local time
- to UTC.
- Return -1 if time in `tm' cannot be represented as time_t value. */
-
-time_t
-mktime(tm)
- struct tm *tm;
-{
- struct tm *ltm; /* Local time. */
- time_t loctime; /* The time_t value of local time. */
- time_t then; /* The time to return. */
- long tzoffset_adj; /* timezone-adjustment `remainder' */
- int bailout_cnt; /* counter of tries for tz correction */
- int save_isdst; /* Copy of the tm->isdst input value */
-
- save_isdst = tm->tm_isdst;
- loctime = mkgmtime(tm);
- if (loctime == -1) {
- tm->tm_isdst = save_isdst;
- return (time_t)-1;
- }
-
- /* Correct for the timezone and any daylight savings time.
- The correction is verified and repeated when not correct, to
- take into account the rare case that a change to or from daylight
- savings time occurs between when it is the time in `tm' locally
- and when it is that time in Greenwich. After the second correction,
- the "timezone & daylight" offset should be correct in all cases. To
- be sure, we allow a third try, but then the loop is stopped. */
- bailout_cnt = 3;
- then = loctime;
- do {
- ltm = localtime(&then);
- if (ltm == (struct tm *)NULL ||
- (tzoffset_adj = loctime - mkgmtime(ltm)) == 0L)
- break;
- then += tzoffset_adj;
- } while (--bailout_cnt > 0);
-
- if (ltm == (struct tm *)NULL || tzoffset_adj != 0L) {
- /* Signal failure if timezone adjustment did not converge. */
- tm->tm_isdst = save_isdst;
- return (time_t)-1;
- }
-
- if (save_isdst >= 0) {
- if (ltm->tm_isdst && !save_isdst)
- {
- if (then + 3600 < then)
- then = (time_t)-1;
- else
- then += 3600;
- }
- else if (!ltm->tm_isdst && save_isdst)
- {
- if (then - 3600 > then)
- then = (time_t)-1;
- else
- then -= 3600;
- }
- ltm->tm_isdst = save_isdst;
- }
-
- if (tm != ltm) /* `tm' may already point to localtime's internal storage */
- *tm = *ltm;
-
- return then;
-}
-
-
-#ifndef NO_TIME_T_MAX
- /* Provide default values for the upper limit of the time_t range.
- These are the result of the decomposition into a `struct tm' for
- the time value 0xFFFFFFFEL ( = (time_t)-2 ).
- Note: `(time_t)-1' is reserved for "invalid time"! */
-# ifndef TM_YEAR_MAX
-# define TM_YEAR_MAX 2106
-# endif
-# ifndef TM_MON_MAX
-# define TM_MON_MAX 1 /* February */
-# endif
-# ifndef TM_MDAY_MAX
-# define TM_MDAY_MAX 7
-# endif
-# ifndef TM_HOUR_MAX
-# define TM_HOUR_MAX 6
-# endif
-# ifndef TM_MIN_MAX
-# define TM_MIN_MAX 28
-# endif
-# ifndef TM_SEC_MAX
-# define TM_SEC_MAX 14
-# endif
-#endif /* NO_TIME_T_MAX */
-
-/* Adjusts out-of-range values for `tm' field `tm_member'. */
-#define ADJUST_TM(tm_member, tm_carry, modulus) \
- if ((tm_member) < 0) { \
- tm_carry -= (1 - ((tm_member)+1) / (modulus)); \
- tm_member = (modulus-1) + (((tm_member)+1) % (modulus)); \
- } else if ((tm_member) >= (modulus)) { \
- tm_carry += (tm_member) / (modulus); \
- tm_member = (tm_member) % (modulus); \
- }
-
-/* 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)
-
-/* Additional leapday in February of leap years. */
-#define leapday(m, y) ((m) == 1 && leap (y))
-
-/* Length of month `m' (0 .. 11) */
-#define monthlen(m, y) (ydays[(m)+1] - ydays[m] + leapday (m, y))
-
-/* Accumulated number of days from 01-Jan up to start of current month. */
-static ZCONST short ydays[] =
-{
- 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
-};
-
-/* Return the equivalent in seconds past 12:00:00 a.m. Jan 1, 1970 GMT
- of the Greenwich Mean time and date in the exploded time structure `tm'.
- This function does always put back normalized values into the `tm' struct,
- parameter, including the calculated numbers for `tm->tm_yday',
- `tm->tm_wday', and `tm->tm_isdst'.
- Returns -1 if the time in the `tm' parameter cannot be represented
- as valid `time_t' number. */
-
-time_t
-mkgmtime(tm)
- struct tm *tm;
-{
- int years, months, days, hours, minutes, seconds;
-
- years = tm->tm_year + 1900; /* year - 1900 -> year */
- months = tm->tm_mon; /* 0..11 */
- days = tm->tm_mday - 1; /* 1..31 -> 0..30 */
- hours = tm->tm_hour; /* 0..23 */
- minutes = tm->tm_min; /* 0..59 */
- seconds = tm->tm_sec; /* 0..61 in ANSI C. */
-
- ADJUST_TM(seconds, minutes, 60)
- ADJUST_TM(minutes, hours, 60)
- ADJUST_TM(hours, days, 24)
- ADJUST_TM(months, years, 12)
- if (days < 0)
- do {
- if (--months < 0) {
- --years;
- months = 11;
- }
- days += monthlen(months, years);
- } while (days < 0);
- else
- while (days >= monthlen(months, years)) {
- days -= monthlen(months, years);
- if (++months >= 12) {
- ++years;
- months = 0;
- }
- }
-
- /* Restore adjusted values in tm structure */
- tm->tm_year = years - 1900;
- tm->tm_mon = months;
- tm->tm_mday = days + 1;
- tm->tm_hour = hours;
- tm->tm_min = minutes;
- tm->tm_sec = seconds;
-
- /* Set `days' to the number of days into the year. */
- days += ydays[months] + (months > 1 && leap (years));
- tm->tm_yday = days;
-
- /* Now calculate `days' to the number of days since Jan 1, 1970. */
- days = (unsigned)days + 365 * (unsigned)(years - 1970) +
- (unsigned)(nleap (years));
- tm->tm_wday = ((unsigned)days + 4) % 7; /* Jan 1, 1970 was Thursday. */
- tm->tm_isdst = 0;
-
- if (years < 1970)
- return (time_t)-1;
-
-#if (defined(TM_YEAR_MAX) && defined(TM_MON_MAX) && defined(TM_MDAY_MAX))
-#if (defined(TM_HOUR_MAX) && defined(TM_MIN_MAX) && defined(TM_SEC_MAX))
- if (years > TM_YEAR_MAX ||
- (years == TM_YEAR_MAX &&
- (tm->tm_yday > ydays[TM_MON_MAX] + (TM_MDAY_MAX - 1) +
- (TM_MON_MAX > 1 && leap (TM_YEAR_MAX)) ||
- (tm->tm_yday == ydays[TM_MON_MAX] + (TM_MDAY_MAX - 1) +
- (TM_MON_MAX > 1 && leap (TM_YEAR_MAX)) &&
- (hours > TM_HOUR_MAX ||
- (hours == TM_HOUR_MAX &&
- (minutes > TM_MIN_MAX ||
- (minutes == TM_MIN_MAX && seconds > TM_SEC_MAX) )))))))
- return (time_t)-1;
-#endif
-#endif
-
- return (time_t)(86400L * (unsigned long)(unsigned)days +
- 3600L * (unsigned long)hours +
- (unsigned long)(60 * minutes + seconds));
-}
diff --git a/msdos/README.DOS b/msdos/README.DOS
index a9b5ccb..0b9a57b 100644
--- a/msdos/README.DOS
+++ b/msdos/README.DOS
@@ -4,7 +4,7 @@ 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 3.4.3 as compiler.
+ 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
@@ -18,9 +18,9 @@ A) The 32-bit DOS executables "zip.exe" and the auxilary utilities
- 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/2K3.
+ Windows 95/98/Me and Windows 2K/XP.
-B) There are two 16-bit MSDOS executables provided in zip2?x.zip:
+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
@@ -46,23 +46,11 @@ C) Hard limits of the Zip archive format:
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.) Also note that the
- latest Info-ZIP versions (currently in beta) now support Zip64 which
- extends all these limits, though these versions require file system
- support of large files. MSDOS stores file sizes in 32-bit numbers
- internally. So, for MSDOS, the Zip64 features extending file sizes
- beyond the 32-bit barrier are not applicable. It is possible to
- support Zip64 archives (for listing/testing, but not fully for
- creation/extraction to disk) on MSDOS using splits, but currently
- we are not planning on doing it. The Zip64 extensions concerning
- "more than 64k archive entries" may be supported on MSDOS (at least
- up to the limit of 2^32 - 1 entries), unless we decide to drop support
- for the MSDOS port completely.
+ 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)
@@ -112,25 +100,14 @@ D) Implementation limits of the Zip executables:
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!)
-
- Note that the Win32 versions in general support greater limits than
- the MSDOS versions. If you are using zip from the command line in
- Windows then you are usually better off using the Win32 versions.
- Also, we are currently working on betas for UnZip 6.00 and Zip 3.0
- that support Zip64 which extends these limits. However, the Zip64
- features (with exception of the "more than 64k archive entries"
- extension) may never be supported on MSDOS (or any DOS emulation)
- because of its hard file size limit at 4 GByte. It is possible
- to support some of the Zip64 features in split archives but we are
- currently not planning to do it.
+ 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)
@@ -150,6 +127,6 @@ D) Implementation limits of the Zip executables:
+ 3 * length of filename
-Please report any problems at: www.info-zip.org
+Please report any problems to: Zip-Bugs@lists.wku.edu
-Last updated: 19 February 2005
+Last updated: 07 July 2001
diff --git a/msdos/crc_i86.asm b/msdos/crc_i86.asm
index 12e85ee..3ad0349 100644
--- a/msdos/crc_i86.asm
+++ b/msdos/crc_i86.asm
@@ -1,12 +1,12 @@
;===========================================================================
-; Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+; Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
;
-; See the accompanying file LICENSE, version 1999-Oct-05 or later
+; 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, both of these files are missing, the Info-ZIP license
-; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+; 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 24 Dec 1998.
+; Created by Christian Spieler, last modified 07 Jan 2007.
;
TITLE crc_i86.asm
NAME crc_i86
@@ -39,6 +39,10 @@
; 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:
@@ -56,9 +60,11 @@
;
;==============================================================================
;
-; Do NOT assemble this source if external crc32 routine from zlib gets used.
+; 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:
;
@@ -89,8 +95,12 @@ endif
ifdef __HUGE__
; .MODEL Huge
- @CodeSize EQU 1
- @DataSize EQU 1
+ ifndef @CodeSize
+ @CodeSize EQU 1
+ endif
+ ifndef @DataSize
+ @DataSize EQU 1
+ endif
Save_DS EQU 1
if VERBOSE_INFO
if1
@@ -100,8 +110,12 @@ ifdef __HUGE__
else
ifdef __LARGE__
; .MODEL Large
- @CodeSize EQU 1
- @DataSize EQU 1
+ ifndef @CodeSize
+ @CodeSize EQU 1
+ endif
+ ifndef @DataSize
+ @DataSize EQU 1
+ endif
if VERBOSE_INFO
if1
%out Assembling for C, Large memory model
@@ -110,8 +124,12 @@ else
else
ifdef __COMPACT__
; .MODEL Compact
- @CodeSize EQU 0
- @DataSize EQU 1
+ ifndef @CodeSize
+ @CodeSize EQU 0
+ endif
+ ifndef @DataSize
+ @DataSize EQU 1
+ endif
if VERBOSE_INFO
if1
%out Assembling for C, Compact memory model
@@ -120,8 +138,12 @@ else
else
ifdef __MEDIUM__
; .MODEL Medium
- @CodeSize EQU 1
- @DataSize EQU 0
+ ifndef @CodeSize
+ @CodeSize EQU 1
+ endif
+ ifndef @DataSize
+ @DataSize EQU 0
+ endif
if VERBOSE_INFO
if1
%out Assembling for C, Medium memory model
@@ -129,8 +151,12 @@ else
endif
else
; .MODEL Small
- @CodeSize EQU 0
- @DataSize EQU 0
+ ifndef @CodeSize
+ @CodeSize EQU 0
+ endif
+ ifndef @DataSize
+ @DataSize EQU 0
+ endif
if VERBOSE_INFO
if1
%out Assembling for C, Small memory model
@@ -165,6 +191,11 @@ 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
@@ -197,6 +228,7 @@ endif ;?__286
endif ;?__386
endif ;?__486
endif ;?__586
+endif ;?__686
ifdef Use_286_code
.286
@@ -308,7 +340,7 @@ endif
;
;ulg crc32(ulg crc,
; ZCONST uch *buf,
-; extend len)
+; extent len)
;
PUBLIC _crc32
if @CodeSize
@@ -459,6 +491,7 @@ 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
index 0190ba0..88ecde4 100644
--- a/msdos/makefile.bor
+++ b/msdos/makefile.bor
@@ -28,7 +28,8 @@ CPU_TYP = 0
# Uncomment the following macro to use the optimized assembler
# routines in Zip:
-ASMOBJS = match.obj crc_i86.obj
+CRCA_O = crc_i86.obj
+ASMOBJS = match.obj $(CRCA_O)
ASCPUFLAG = __$(CPU_TYP)86
!if $(CPU_TYP) != 0
@@ -78,13 +79,13 @@ BIN = c:\util
# variables
OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \
- crc32.obj crctab.obj globals.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 crctab.obj crypt_.obj ttyio.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
@@ -93,16 +94,16 @@ ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe
zips: $(ZIPS)
-zip.obj: zip.c $(ZIP_H) revision.h crypt.h ttyio.h
+zip.obj: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
$(CC) -c $(CFLAGS) $*.c
-zipfile.obj: zipfile.c $(ZIP_H)
+zipfile.obj: zipfile.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
-zipup.obj: zipup.c $(ZIP_H) revision.h crypt.h msdos/zipup.h
+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)
+fileio.obj: fileio.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
util.obj: util.c $(ZIP_H)
@@ -117,13 +118,10 @@ deflate.obj: deflate.c $(ZIP_H)
trees.obj: trees.c $(ZIP_H)
$(CC) -c $(CFLAGS) $*.c
-crc32.obj: crc32.c $(ZIP_H)
+crc32.obj: crc32.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
-crctab.obj: crctab.c $(ZIP_H)
- $(CC) -c $(CFLAGS) $*.c
-
-crypt.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+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
@@ -132,7 +130,7 @@ ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h
msdos.obj: msdos/msdos.c $(ZIP_H)
$(CC) -c $(CFLAGS) msdos/$*.c
-zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+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
@@ -141,16 +139,19 @@ zipnote.obj: zipnote.c $(ZIP_H) revision.h
zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
$(CC) -c $(CFLAGS) $*.c
-zipfile_.obj: zipfile.c $(ZIP_H)
+zipfile_.obj: zipfile.c $(ZIP_H) crc32.h
$(CC) -c $(UTILFLAGS)$* zipfile.c
-fileio_.obj: fileio.c $(ZIP_H)
+fileio_.obj: fileio.c $(ZIP_H) crc32.h
$(CC) -c $(UTILFLAGS)$* fileio.c
util_.obj: util.c $(ZIP_H)
$(CC) -c $(UTILFLAGS)$* util.c
-crypt_.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+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)
diff --git a/msdos/makefile.dj1 b/msdos/makefile.dj1
index b513359..05137cc 100644
--- a/msdos/makefile.dj1
+++ b/msdos/makefile.dj1
@@ -21,15 +21,15 @@ STUBIFY=coff2exe
# variables
-#set CRC32 to crc_gcc.o or crc32.o, depending on whether ASM_CRC is defined:
-CRC32 = crc_gcc.o
+#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) crctab.o globals.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 crctab.o crypt_.o ttyio.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
@@ -44,11 +44,11 @@ ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h
zips: zip.exe zipnote.exe zipsplit.exe zipcloak.exe
-zip.o: zip.c $(ZIP_H) revision.h crypt.h ttyio.h
+zip.o: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
-zipfile.o: zipfile.c $(ZIP_H)
+zipfile.o: zipfile.c $(ZIP_H) crc32.h
-zipup.o: zipup.c $(ZIP_H) revision.h crypt.h msdos/zipup.h
+zipup.o: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h
fileio.o: fileio.c $(ZIP_H)
@@ -63,32 +63,33 @@ 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.o: crc32.c $(ZIP_H) crc32.h
-crctab.o: crctab.c $(ZIP_H)
-
-crypt.o: crypt.c $(ZIP_H) crypt.h ttyio.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 crypt.h ttyio.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)
+zipfile_.o: zipfile.c $(ZIP_H) crc32.h
$(CC) $(UTILFLAGS) $@ zipfile.c
-fileio_.o: fileio.c $(ZIP_H)
+fileio_.o: fileio.c $(ZIP_H) crc32.h
$(CC) $(UTILFLAGS) $@ fileio.c
util_.o: util.c $(ZIP_H)
$(CC) $(UTILFLAGS) $@ util.c
-crypt_.o: crypt.c $(ZIP_H) crypt.h ttyio.h
+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)
diff --git a/msdos/makefile.dj2 b/msdos/makefile.dj2
index 3ea98ae..39192ee 100644
--- a/msdos/makefile.dj2
+++ b/msdos/makefile.dj2
@@ -25,15 +25,15 @@ DJP=upx -qq --best
# variables
-#set CRC32 to crc_gcc.o or crc32.o, depending on whether ASM_CRC is defined:
-CRC32 = crc_gcc.o
+#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) crctab.o globals.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 crctab.o crypt_.o ttyio.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
@@ -48,13 +48,13 @@ ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h
zips: zip.exe zipnote.exe zipsplit.exe zipcloak.exe
-zip.o: zip.c $(ZIP_H) revision.h crypt.h ttyio.h
+zip.o: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
-zipfile.o: zipfile.c $(ZIP_H)
+zipfile.o: zipfile.c $(ZIP_H) crc32.h
-zipup.o: zipup.c $(ZIP_H) revision.h crypt.h msdos/zipup.h
+zipup.o: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h
-fileio.o: fileio.c $(ZIP_H)
+fileio.o: fileio.c $(ZIP_H) crc32.h
util.o: util.c $(ZIP_H)
@@ -67,32 +67,33 @@ 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.o: crc32.c $(ZIP_H) crc32.h
-crctab.o: crctab.c $(ZIP_H)
-
-crypt.o: crypt.c $(ZIP_H) crypt.h ttyio.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 crypt.h ttyio.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)
+zipfile_.o: zipfile.c $(ZIP_H) crc32.h
$(CC) $(UTILFLAGS) $@ zipfile.c
-fileio_.o: fileio.c $(ZIP_H)
+fileio_.o: fileio.c $(ZIP_H) crc32.h
$(CC) $(UTILFLAGS) $@ fileio.c
util_.o: util.c $(ZIP_H)
$(CC) $(UTILFLAGS) $@ util.c
-crypt_.o: crypt.c $(ZIP_H) crypt.h ttyio.h
+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)
diff --git a/msdos/makefile.emx b/msdos/makefile.emx
index f66b31c..3a50b5b 100644
--- a/msdos/makefile.emx
+++ b/msdos/makefile.emx
@@ -1,7 +1,7 @@
# 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 30th June 1998.
+# 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
@@ -38,7 +38,7 @@ LDFLAGS=-o ./
LDFLAGS2=-s -Zsmall-conv
OUT=-o
OBJ=.o
-CRC32=crc_gcc
+CRCA_O=crc_gcc.o
OBJA=matchgcc.o
OBJZS=msdos.o
OBJUS=msdos_.o
@@ -54,7 +54,7 @@ CCFLAGS = $(CFLAGS) $(LOCAL_OPTS)
OBJZ1 = zip$(OBJ) zipfile$(OBJ) zipup$(OBJ) fileio$(OBJ) util$(OBJ) \
- $(CRC32)$(OBJ) crctab$(OBJ)
+ crc32$(OBJ) $(CRCA_O)
OBJZ2 = globals$(OBJ) deflate$(OBJ) trees$(OBJ) crypt$(OBJ) \
ttyio$(OBJ)
OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZS) $(OBJA)
@@ -64,7 +64,7 @@ OBJU = $(OBJU1) $(OBJUS)
OBJN = zipnote$(OBJ) $(OBJU)
OBJS = zipsplit$(OBJ) $(OBJU)
-OBJC1 = zipcloak$(OBJ) crctab$(OBJ) crypt_$(OBJ) ttyio$(OBJ)
+OBJC1 = zipcloak$(OBJ) crc32_$(OBJ) crypt_$(OBJ) ttyio$(OBJ)
OBJC = $(OBJC1) $(OBJU)
ZIP_H = zip.h ziperr.h tailor.h $(OSDEP_H)
@@ -80,17 +80,16 @@ ZIP_H = zip.h ziperr.h tailor.h $(OSDEP_H)
all: zip.exe zipnote.exe zipsplit.exe zipcloak.exe
-zip$(OBJ): zip.c $(ZIP_H) revision.h crypt.h ttyio.h
-zipfile$(OBJ): zipfile.c $(ZIP_H)
-zipup$(OBJ): zipup.c $(ZIP_H) revision.h crypt.h $(ZIPUP_H)
-fileio$(OBJ): fileio.c $(ZIP_H)
+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)
-crctab$(OBJ): crctab.c $(ZIP_H)
-crypt$(OBJ): crypt.c $(ZIP_H) crypt.h ttyio.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)
@@ -111,20 +110,23 @@ crc_gcc$(OBJ): crc_i386.S # 32bit, GNU AS
matchgcc$(OBJ): match.S
$(AS) $(ASFLAGS) -x assembler-with-cpp -c -o $@ match.S
-zipcloak$(OBJ): zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+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)
+zipfile_$(OBJ): zipfile.c $(ZIP_H) crc32.h
$(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ zipfile.c
-fileio_$(OBJ): fileio.c $(ZIP_H)
+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
-crypt_$(OBJ): crypt.c $(ZIP_H) crypt.h ttyio.h
+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)
diff --git a/msdos/makefile.msc b/msdos/makefile.msc
index 89f0d42..a7ec9c9 100644
--- a/msdos/makefile.msc
+++ b/msdos/makefile.msc
@@ -45,6 +45,10 @@ ASCPUFLAG = __$(CPU_TYP)86
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<num> is used to
+# force data items of size <num> 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
@@ -60,7 +64,7 @@ ASFLAGS=-ml -t -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:0x1000/m
+LDFLAGS=/noi/farcall/packcode/e/st:0x1400/m
# If you use an exe packer as recommended below, remove /e from LDFLAGS
# ------------- Common declarations:
@@ -81,13 +85,13 @@ BIN = c:\util
# variables
OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \
- crc32.obj crctab.obj globals.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 crctab.obj crypt_.obj ttyio.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
@@ -96,17 +100,17 @@ ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe
zips: $(ZIPS)
-zip.obj: zip.c $(ZIP_H) revision.h crypt.h ttyio.h
- $(CC) -c $(CFLAGS) $*.c
+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)
+zipfile.obj: zipfile.c $(ZIP_H) crc32.h
$(CC) -c $(SPECFLAGS) $*.c
-zipup.obj: zipup.c $(ZIP_H) revision.h crypt.h msdos/zipup.h
+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)
+fileio.obj: fileio.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
util.obj: util.c $(ZIP_H)
@@ -121,13 +125,10 @@ deflate.obj: deflate.c $(ZIP_H)
trees.obj: trees.c $(ZIP_H)
$(CC) -c $(CFLAGS) $*.c
-crc32.obj: crc32.c $(ZIP_H)
- $(CC) -c $(CFLAGS) $*.c
-
-crctab.obj: crctab.c $(ZIP_H)
+crc32.obj: crc32.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
-crypt.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+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
@@ -136,7 +137,7 @@ ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h
msdos.obj: msdos/msdos.c $(ZIP_H)
$(CC) -c $(CFLAGS) msdos/$*.c
-zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+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
@@ -147,16 +148,19 @@ 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)
+zipfile_.obj: zipfile.c $(ZIP_H) crc32.h
$(CC) -c $(SPECFLAGS) -DUTIL -Fo$@ zipfile.c
-fileio_.obj: fileio.c $(ZIP_H)
+fileio_.obj: fileio.c $(ZIP_H) crc32.h
$(CC) -c $(UTILFLAGS)$@ fileio.c
util_.obj: util.c $(ZIP_H)
$(CC) -c $(UTILFLAGS)$@ util.c
-crypt_.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+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)
diff --git a/msdos/makefile.tc b/msdos/makefile.tc
index 86d6b91..9ce3e32 100644
--- a/msdos/makefile.tc
+++ b/msdos/makefile.tc
@@ -61,13 +61,13 @@ BIN = c:\util
# variables
OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \
- crc32.obj crctab.obj globals.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 crctab.obj _crypt.obj ttyio.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
@@ -76,16 +76,16 @@ ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe
zips: $(ZIPS)
-zip.obj: zip.c $(ZIP_H) revision.h crypt.h ttyio.h
+zip.obj: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
$(CC) -c $(CFLAGS) $*.c
-zipfile.obj: zipfile.c $(ZIP_H)
+zipfile.obj: zipfile.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
-zipup.obj: zipup.c $(ZIP_H) revision.h crypt.h msdos/zipup.h
+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)
+fileio.obj: fileio.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
util.obj: util.c $(ZIP_H)
@@ -100,13 +100,10 @@ deflate.obj: deflate.c $(ZIP_H)
trees.obj: trees.c $(ZIP_H)
$(CC) -c $(CFLAGS) $*.c
-crc32.obj: crc32.c $(ZIP_H)
+crc32.obj: crc32.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
-crctab.obj: crctab.c $(ZIP_H)
- $(CC) -c $(CFLAGS) $*.c
-
-crypt.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+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
@@ -115,7 +112,7 @@ ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h
msdos.obj: msdos/msdos.c $(ZIP_H)
$(CC) -c $(CFLAGS) msdos/$*.c
-zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+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
@@ -124,16 +121,19 @@ zipnote.obj: zipnote.c $(ZIP_H) revision.h
zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
$(CC) -c $(CFLAGS) -o$* $*.c
-_zipfile.obj: zipfile.c $(ZIP_H)
+_zipfile.obj: zipfile.c $(ZIP_H) crc32.h
$(CC) -c $(UTILFLAGS)$* zipfile.c
-_fileio.obj: fileio.c $(ZIP_H)
+_fileio.obj: fileio.c $(ZIP_H) crc32.h
$(CC) -c $(UTILFLAGS)$* fileio.c
_util.obj: util.c $(ZIP_H)
$(CC) -c $(UTILFLAGS)$* util.c
-_crypt.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+_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)
diff --git a/msdos/makefile.wat b/msdos/makefile.wat
index d73fa7f..dd4d8cd 100644
--- a/msdos/makefile.wat
+++ b/msdos/makefile.wat
@@ -1,5 +1,5 @@
# 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 17 Feb 2005.
+# 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]"
@@ -67,7 +67,8 @@ O = $(OBDIR)\ # comment here so backslash won't continue the line
# optional. This section controls its usage.
!ifdef NOASM
-asmob = $(O)crc32.obj # C source
+ # 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.
@@ -97,7 +98,7 @@ cc = wcc386
cflags = -bt=DOS -mf -6r -zt -zq
aflags = -bt=DOS -mf -3 -zq
cvars = $+$(cvars)$- -DDOS $(variation)
-avars = $+$(avars)$- $(variation)
+avars = $+$(avars)$- -DWATCOM_DSEG $(variation)
! ifdef GW
lflags = sys DOS4G
@@ -143,12 +144,12 @@ ldebug = op el
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)crctab.obj $(asmob) $(O)msdos.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)crctab.obj $(O)crypt_.obj $(O)ttyio.obj $(OBJ_U)
+OBJC = $(O)zipcloak.obj $(O)crc32_.obj $(O)crypt_.obj $(O)ttyio.obj $(OBJ_U)
OBJN = $(O)zipnote.obj $(OBJ_U)
@@ -193,20 +194,19 @@ ZipSplit.exe: $(OBDIR) $(OBJS)
# Source dependencies:
-$(O)crctab.obj: crctab.c $(ZIP_H)
-$(O)crc32.obj: crc32.c $(ZIP_H) # only used if NOASM
-$(O)crypt.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+$(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)
+$(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) crypt.h revision.h ttyio.h
-$(O)zipfile.obj: zipfile.c $(ZIP_H)
-$(O)zipup.obj: zipup.c $(ZIP_H) revision.h crypt.h msdos\zipup.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 crypt.h ttyio.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:
@@ -222,16 +222,19 @@ $(O)crc.obj: $(crc_s)
# Variant object files for ZipNote, ZipCloak, and ZipSplit:
-$(O)zipfile_.obj: zipfile.c $(ZIP_H)
+$(O)zipfile_.obj: zipfile.c $(ZIP_H) crc32.h
$(cc) $(cdebug) $(cflags) $(cvars) -DUTIL zipfile.c -fo=$@
-$(O)fileio_.obj: fileio.c $(ZIP_H)
+$(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)crypt_.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+$(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)
diff --git a/msdos/match.asm b/msdos/match.asm
index f126cd7..998881e 100644
--- a/msdos/match.asm
+++ b/msdos/match.asm
@@ -1,10 +1,10 @@
;===========================================================================
-; Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+; Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
;
-; See the accompanying file LICENSE, version 1999-Oct-05 or later
+; 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, both of these files are missing, the Info-ZIP license
-; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+; 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.
@@ -73,8 +73,12 @@ endif
ifdef __HUGE__
; .MODEL Huge
- @CodeSize EQU 1
- @DataSize EQU 1
+ ifndef @CodeSize
+ @CodeSize EQU 1
+ endif
+ ifndef @DataSize
+ @DataSize EQU 1
+ endif
Save_DS EQU 1
if VERBOSE_INFO
if1
@@ -84,8 +88,12 @@ ifdef __HUGE__
else
ifdef __LARGE__
; .MODEL Large
- @CodeSize EQU 1
- @DataSize EQU 1
+ ifndef @CodeSize
+ @CodeSize EQU 1
+ endif
+ ifndef @DataSize
+ @DataSize EQU 1
+ endif
if VERBOSE_INFO
if1
%out Assembling for C, Large memory model
@@ -94,8 +102,12 @@ else
else
ifdef __COMPACT__
; .MODEL Compact
- @CodeSize EQU 0
- @DataSize EQU 1
+ ifndef @CodeSize
+ @CodeSize EQU 0
+ endif
+ ifndef @DataSize
+ @DataSize EQU 1
+ endif
if VERBOSE_INFO
if1
%out Assembling for C, Compact memory model
@@ -104,8 +116,12 @@ else
else
ifdef __MEDIUM__
; .MODEL Medium
- @CodeSize EQU 1
- @DataSize EQU 0
+ ifndef @CodeSize
+ @CodeSize EQU 1
+ endif
+ ifndef @DataSize
+ @DataSize EQU 0
+ endif
if VERBOSE_INFO
if1
%out Assembling for C, Medium memory model
@@ -113,8 +129,12 @@ else
endif
else
; .MODEL Small
- @CodeSize EQU 0
- @DataSize EQU 0
+ ifndef @CodeSize
+ @CodeSize EQU 0
+ endif
+ ifndef @DataSize
+ @DataSize EQU 0
+ endif
if VERBOSE_INFO
if1
%out Assembling for C, Small memory model
diff --git a/msdos/msdos.c b/msdos/msdos.c
index 77094bf..4f71397 100644
--- a/msdos/msdos.c
+++ b/msdos/msdos.c
@@ -1,9 +1,9 @@
/*
Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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
+ 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"
@@ -90,6 +90,11 @@ int GetFileMode OF((char *name));
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;
@@ -247,7 +252,7 @@ char *wildtail;
strcpy(name, subwild);
e = wild_recurse(newwhole, name);
} else
- e = procname(newwhole, 0);
+ e = procname_dos(newwhole, 0, getDirEntryAttr(&dir));
newwhole[newlen] = 0;
if (e == ZE_OK)
amatch = 1;
@@ -316,9 +321,10 @@ char *w; /* path/pattern to match */
return e;
}
-int procname(n, caseflag)
+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. */
{
@@ -337,6 +343,18 @@ int caseflag; /* true to force case-sensitive match */
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! */
@@ -416,7 +434,8 @@ int caseflag; /* true to force case-sensitive match */
return ZE_MEM;
}
strcat(strcpy(a, p), e);
- if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */
+ if ((m = procname_dos(a, caseflag, getDirEntryAttr(d)))
+ != ZE_OK) /* recurse on name */
{
if (m == ZE_MISS)
zipwarn("name not matched: ", a);
@@ -433,6 +452,13 @@ int caseflag; /* true to force case-sensitive match */
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 */
@@ -553,8 +579,9 @@ iztimes *t; /* return value: access, modific. and creation times */
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);
+ int len = strlen(f);
int isstdin = !strcmp(f, "-");
if (f == label) {
@@ -566,7 +593,6 @@ iztimes *t; /* return value: access, modific. and creation times */
t->atime = t->mtime = t->ctime = label_utim;
return label_time;
}
-
if ((name = malloc(len + 1)) == NULL) {
ZIPERR(ZE_MEM, "filetime");
}
@@ -596,16 +622,15 @@ iztimes *t; /* return value: access, modific. and creation times */
if ((s.st_mode & S_IFMT) == S_IFREG) *a |= 0x80000000L;
#endif
}
+ free(name);
if (n != NULL)
- *n = (s.st_mode & S_IFREG) != 0 ? s.st_size : -1L;
+ *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L;
if (t != NULL) {
t->atime = s.st_atime;
t->mtime = s.st_mtime;
t->ctime = s.st_ctime;
}
- free(name);
-
return unix2dostime((time_t *)&s.st_mtime);
}
@@ -753,6 +778,48 @@ void xit(void)
}
#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 */
diff --git a/msdos/osdep.h b/msdos/osdep.h
index 380cd84..0e0f23f 100644
--- a/msdos/osdep.h
+++ b/msdos/osdep.h
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.htmlhtml
+ 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.
@@ -119,6 +119,11 @@
#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
@@ -198,8 +203,16 @@ int setmode(int, int);
# define localtime(t) msc7_localtime(t)
#endif
+#ifdef __TURBOC__
+# ifdef __FILEIO_C
+# include <dir.h> /* 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/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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ntypes.h>
+#include <nwconio.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <nit\nwdir.h>
+#include <dirent.h>
+#include <nwnamspc.h>
+#include <locale.h>
+#include <nwlocale.h>
+#include <time.h>
+
+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 <alloc.h>
+# 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 <malloc.h>
+# 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 <sys/types.h>
+#include <sys/stat.h>
+#include <io.h>
+
+#ifdef ZCRYPT_INTERNAL
+# ifdef WINDLL
+# define ZCR_SEED2 (unsigned)3141592654L /* use PI as seed pattern */
+# else
+# ifndef __GO32__
+# include <process.h> /* 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 <nwthread.h>
+#include <nwerrno.h>
+
+/*******************************/
+/* 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
index 8e5e7cf..a008ea5 100644
--- a/os2/makefile.os2
+++ b/os2/makefile.os2
@@ -104,7 +104,7 @@ msc:
LDFLAGS2="-link /noe /pm:vio" \
OUT="-Fo" \
OBJ=".obj" \
- CRC32="crc_i86" \
+ CRCA_O="crc_i86.obj" \
OBJA="match.obj" \
DEF="os2\zip.def"
@@ -119,7 +119,7 @@ mscdebug:
LDFLAGS2="-link /noe /pm:vio" \
OUT="-Fo" \
OBJ=".obj" \
- CRC32="crc_i86" \
+ CRCA_O="crc_i86.obj" \
OBJA="match.obj" \
DEF="os2\zip.def"
@@ -134,7 +134,7 @@ mscdos:
LDFLAGS2="-link /noe /exe" \
OUT="-Fo" \
OBJ=".obj" \
- CRC32="crc_i86" \
+ CRCA_O="crc_i86.obj" \
OBJA="match.obj" \
OBJ2="msdos.obj" OBJU2="msdos_.obj" \
OSDEP_H="msdos/osdep.h" ZIPUP_H="msdos/zipup.h"
@@ -201,7 +201,7 @@ watcom:
$(MAKE) -f os2/makefile.os2 zips \
CC="wcl386 -bt=os2v2 -zq -Ox -s" \
CFLAGS="-Zp1 -DOS2 -DNO_ASM" \
- AS="wasm -bt=os2v2 -3p" \
+ AS="wasm -zq -bt=os2v2 -3p" \
ASFLAGS="" \
LDFLAGS="-k0x50000 -x -l=os2v2 -Fe=" \
LDFLAGS2="" \
@@ -216,7 +216,7 @@ watcom16:
$(MAKE) -f os2/makefile.os2 zips \
CC="wcl -bt=os2 -zq -ml -Ox -s" \
CFLAGS="-Zp1 -DOS2 -DNO_ASM" \
- AS="wasm -bt=os2 -2p -ml" \
+ AS="wasm -zq -bt=os2 -2p -ml" \
ASFLAGS="" \
LDFLAGS="/\"option newfiles\" -k0x3000 -x -l=os2 -Fe=" \
LDFLAGS2="" \
@@ -230,14 +230,15 @@ watcom16:
watcomdos:
$(MAKE) -f os2/makefile.os2 zips \
CC="wcl386 -bt=dos4g -zq -Ox -s" \
- CFLAGS="-Zp1 -DDOS -DMSDOS -DNO_ASM" \
- AS="wasm -bt=dos4g -3p" \
- ASFLAGS="" \
+ 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" \
- OBJA="" \
+ CRCA_O="crc_i386.obj" \
+ OBJA="match32.obj" \
OBJ2="msdos.obj" \
OBJU2="msdos_.obj" \
OSDEP_H="msdos/osdep.h" \
@@ -250,13 +251,13 @@ pmodew:
$(MAKE) -f os2/makefile.os2 zips \
CC="wcl386 -bt=dos4g -zq -Ox -s" \
CFLAGS="-Zp1 -DDOS -DMSDOS -DASM_CRC" \
- AS="wasm -bt=dos4g -3p" \
- ASFLAGS="" \
+ AS="wasm -zq -bt=dos4g -3p" \
+ ASFLAGS="-DWATCOM_DSEG" \
LDFLAGS="-k0x50000 -x -l=pmodew -Fe=" \
LDFLAGS2="" \
OUT="-Fo" \
OBJ=".obj" \
- CRC32="crc_i386" \
+ CRCA_O="crc_i386.obj" \
OBJA="match32.obj" \
OBJ2="msdos.obj" \
OBJU2="msdos_.obj" \
@@ -270,7 +271,7 @@ 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 -bt=dos -2p -ml" \
+ AS="wasm -zq -bt=dos -2 -ml" \
ASFLAGS="-DDYN_ALLOC" \
LDFLAGS="-k0x2000 -x -l=dos -Fe=" \
LDFLAGS2="" \
@@ -322,7 +323,7 @@ gcc:
LDFLAGS2="-Zsys -Zstack 320 -s -Zsmall-conv" \
OUT="-o" \
OBJ=".obj" \
- CRC32="crc_gcc" \
+ CRCA_O="crc_gcc.obj" \
OBJA="matchgcc.obj" \
DEF="os2/zip.def"
@@ -337,7 +338,7 @@ gccdyn:
LDFLAGS2="-Zcrtdll -Zstack 320 -s" \
OUT="-o" \
OBJ=".obj" \
- CRC32="crc_gcc" \
+ CRCA_O="crc_gcc.obj" \
OBJA="matchgcc.obj" \
DEF="os2/zip.def"
@@ -352,7 +353,7 @@ gcczlib:
LDFLAGS2="-L. -lzlib -Zsys -Zstack 320 -s -Zsmall-conv" \
OUT="-o" \
OBJ=".obj" \
- CRC32="crc32" \
+ CRCA_O="" \
OBJA="" \
DEF="os2/zip.def"
@@ -367,7 +368,7 @@ gccdebug:
LDFLAGS2="" \
OUT="-o" \
OBJ=".o" \
- CRC32="crc_gcc" \
+ CRCA_O="crc_gcc.o" \
OBJA="matchgcc.o" \
DEF="os2/zip.def"
@@ -382,7 +383,7 @@ gccdos:
LDFLAGS2="-s -Zsmall-conv" \
OUT="-o" \
OBJ=".o" \
- CRC32="crc_gcc" \
+ CRCA_O="crc_gcc.o" \
OBJA="matchgcc.o" \
OBJ2="msdos.o" \
OBJU2="msdos_.o" \
@@ -400,7 +401,7 @@ gccwin32:
LDFLAGS2="-ladvapi32 -Zsys -Zsmall-conv -s" \
OUT="-o" \
OBJ=".o" \
- CRC32="crc_gcc" \
+ CRCA_O="crc_gcc.o" \
OBJA="matchgcc.o" \
OBJ2="win32zip.o win32.o nt.o" \
OBJU2="win32_.o" \
@@ -419,7 +420,7 @@ gccw32dyn:
LDFLAGS2="-ladvapi32 -s" \
OUT="-o" \
OBJ=".o" \
- CRC32="crc_gcc" \
+ CRCA_O="crc_gcc.o" \
OBJA="matchgcc.o" \
OBJ2="win32zip.o win32.o nt.o" \
OBJU2="win32_.o" \
@@ -439,11 +440,11 @@ CCFLAGS = $(CFLAGS) $(LOCAL_OPTS)
OSDEP_H = os2/osdep.h
ZIPUP_H = os2/os2zip.h os2/zipup.h
-CRC32 = crc32
+CRCA_O =
OBJZ = zip$(OBJ) zipfile$(OBJ) zipup$(OBJ) fileio$(OBJ) util$(OBJ) \
- $(CRC32)$(OBJ) crctab$(OBJ) globals$(OBJ) \
+ crc32$(OBJ) $(CRCA_O) globals$(OBJ) \
deflate$(OBJ) trees$(OBJ) crypt$(OBJ) ttyio$(OBJ)
OBJ2 = os2zip$(OBJ) os2$(OBJ) os2acl$(OBJ)
@@ -452,7 +453,7 @@ OBJU2 = os2zip_$(OBJ)
OBJN = zipnote$(OBJ) $(OBJU) $(OBJU2)
OBJS = zipsplit$(OBJ) $(OBJU) $(OBJU2)
-OBJC = zipcloak$(OBJ) crctab$(OBJ) crypt_$(OBJ) ttyio$(OBJ) $(OBJU) $(OBJU2)
+OBJC = zipcloak$(OBJ) crc32_$(OBJ) crypt_$(OBJ) ttyio$(OBJ) $(OBJU) $(OBJU2)
ZIP_H = zip.h ziperr.h tailor.h $(OSDEP_H)
@@ -470,17 +471,16 @@ ZIP_H = zip.h ziperr.h tailor.h $(OSDEP_H)
zips: zip.exe zipnote.exe zipsplit.exe zipcloak.exe
-zip$(OBJ): zip.c $(ZIP_H) revision.h crypt.h ttyio.h
-zipfile$(OBJ): zipfile.c $(ZIP_H)
-zipup$(OBJ): zipup.c $(ZIP_H) revision.h crypt.h $(ZIPUP_H)
-fileio$(OBJ): fileio.c $(ZIP_H)
+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)
-crctab$(OBJ): crctab.c $(ZIP_H)
-crypt$(OBJ): crypt.c $(ZIP_H) crypt.h ttyio.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
@@ -522,20 +522,23 @@ match32$(OBJ): win32/match32.asm
matchgcc$(OBJ): match.S
$(AS) $(ASFLAGS) -x assembler-with-cpp -c -o $@ match.S
-zipcloak$(OBJ): zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+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)
+zipfile_$(OBJ): zipfile.c $(ZIP_H) crc32.h
$(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ zipfile.c
-fileio_$(OBJ): fileio.c $(ZIP_H)
+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
-crypt_$(OBJ): crypt.c $(ZIP_H) crypt.h ttyio.h
+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
diff --git a/os2/match32.asm b/os2/match32.asm
index ef9a541..4797a73 100644
--- a/os2/match32.asm
+++ b/os2/match32.asm
@@ -1,10 +1,10 @@
;===========================================================================
-; Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+; 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/licen; Copyright (c) 1990-1999 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.
diff --git a/os2/os2.c b/os2/os2.c
index 355eea8..b44fe2e 100644
--- a/os2/os2.c
+++ b/os2/os2.c
@@ -1,9 +1,9 @@
/*
Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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
+ 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"
diff --git a/os2/os2acl.c b/os2/os2acl.c
index 7c5b1fd..4f88643 100644
--- a/os2/os2acl.c
+++ b/os2/os2acl.c
@@ -1,9 +1,9 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
@@ -240,7 +240,7 @@ static void acl_mkpath(char *buffer, const char *source)
U_INT cdrive;
ULONG drivemap;
- if (isalpha(source[0]) && source[1] == ':')
+ if (isalpha((int)source[0]) && source[1] == ':')
buffer[0] = 0; /* fully qualified names */
else
{
diff --git a/os2/os2acl.h b/os2/os2acl.h
index dd34b2d..03bb8a2 100644
--- a/os2/os2acl.h
+++ b/os2/os2acl.h
@@ -1,7 +1,7 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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
diff --git a/packaging/exec-shield.patch b/packaging/exec-shield.patch
deleted file mode 100644
index 3d2a1eb..0000000
--- a/packaging/exec-shield.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-diff -ur zip-2.3/crc_i386.S zip-2.3-lhh/crc_i386.S
---- zip-2.3/crc_i386.S 1999-10-09 16:10:26.000000000 -0400
-+++ zip-2.3-lhh/crc_i386.S 2003-10-24 16:15:52.000000000 -0400
-@@ -230,3 +230,6 @@
- #endif /* i386 || _i386 || _I386 || __i386 */
-
- #endif /* !USE_ZLIB */
-+
-+.section .note.GNU-stack, "", @progbits
-+.previous
-diff -ur zip-2.3/match.S zip-2.3-lhh/match.S
---- zip-2.3/match.S 1999-07-27 17:18:14.000000000 -0400
-+++ zip-2.3-lhh/match.S 2003-10-24 16:15:38.000000000 -0400
-@@ -405,3 +405,5 @@
- #endif /* i386 || _I386 || _i386 || __i386 */
-
- #endif /* !USE_ZLIB */
-+.section .note.GNU-stack, "", @progbits
-+.previous
diff --git a/packaging/zcrypt29.tar.gz b/packaging/zcrypt29.tar.gz
deleted file mode 100644
index 44de3cf..0000000
--- a/packaging/zcrypt29.tar.gz
+++ /dev/null
Binary files differ
diff --git a/packaging/zip-2.3-currdir.patch b/packaging/zip-2.3-currdir.patch
deleted file mode 100644
index 1ff00f6..0000000
--- a/packaging/zip-2.3-currdir.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- zip-2.3/util.c.pom 1999-11-07 11:29:38.000000000 +0100
-+++ zip-2.3/util.c 2005-01-17 13:46:26.165396792 +0100
-@@ -190,6 +190,8 @@
- /* Compare the sh pattern p with the string s and return true if they match,
- false if they don't or if there is a syntax error in the pattern. */
- {
-+ while (s[0] == '.' && s[1] == '/')
-+ s += 2; /* strip redundant leading "./" sections */
- return recmatch((ZCONST uch *) p, (ZCONST uch *) s, cs) == 1;
- }
-
diff --git a/packaging/zip-2.31-configure.patch b/packaging/zip-2.31-configure.patch
deleted file mode 100644
index 00b09d1..0000000
--- a/packaging/zip-2.31-configure.patch
+++ /dev/null
@@ -1,213 +0,0 @@
---- zip-2.31/unix/configure.lhh 2005-11-10 13:25:26.000000000 +0100
-+++ zip-2.31/unix/configure 2005-11-10 13:40:44.311641648 +0100
-@@ -76,14 +76,20 @@
- done
- fi
-
--echo Check for prototypes
-+echo -n Check for prototypes...
- echo "int main(int argc, char *argv[]) { return 0; }" > conftest.c
- $CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
--[ $? -ne 0 ] && CFLAGS="${CFLAGS} -DNO_PROTO"
-+if [ $? -ne 0 ]; then
-+ echo no
-+ CFLAGS="${CFLAGS} -DNO_PROTO"
-+else
-+ echo yes
-+fi
-+
-
- # const check currently handles mips cc and non ANSI compilers.
- # does it need more ?
--echo Check the handling of const
-+echo -n Check the handling of const...
- cat > conftest.c << _EOF_
- typedef int charset[2];
- int main()
-@@ -94,9 +100,15 @@
- }
- _EOF_
- $CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
--[ $? -ne 0 ] && CFLAGS="${CFLAGS} -DNO_CONST"
-+if [ $? -ne 0 ]; then
-+ echo no
-+ CFLAGS="${CFLAGS} -DNO_CONST"
-+else
-+ echo yes
-+fi
-+
-
--echo Check for time_t
-+echo -n Check for time_t...
- cat > conftest.c << _EOF_
- #include <sys/types.h>
- #include <time.h>
-@@ -107,9 +119,15 @@
- }
- _EOF_
- $CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
--[ $? -ne 0 ] && CFLAGS="${CFLAGS} -DNO_TIME_T"
-+if [ $? -ne 0 ]; then
-+ echo no
-+ CFLAGS="${CFLAGS} -DNO_TIME_T"
-+else
-+ echo yes
-+fi
-+
-
--echo Check for size_t
-+echo -n Check for size_t...
- cat > conftest.c << _EOF_
- #include <sys/types.h>
- int main()
-@@ -119,7 +137,13 @@
- }
- _EOF_
- $CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
--[ $? -ne 0 ] && CFLAGS="${CFLAGS} -DNO_SIZE_T"
-+if [ $? -ne 0 ]; then
-+ echo no
-+ CFLAGS="${CFLAGS} -DNO_SIZE_T"
-+else
-+ echo yes
-+fi
-+
-
- echo Check for gcc no-builtin flag
- # -fno-builtin since version 2
-@@ -140,18 +164,29 @@
- # add NO_'function_name' to flags if missing
- for func in rmdir strchr strrchr rename mktemp mktime mkstemp
- do
-- echo Check for $func
-- echo "int main(){ $func(); return 0; }" > conftest.c
-+ echo -n Check for $func...
-+ echo "char $func(void); int main(){ $func(); return 0; }" > conftest.c
- $CC $BFLAG -o conftest conftest.c >/dev/null 2>/dev/null
-- [ $? -ne 0 ] && CFLAGS="${CFLAGS} -DNO_`echo $func | tr '[a-z]' '[A-Z]'`"
-+ if [ $? -ne 0 ]; then
-+ echo no
-+ CFLAGS="${CFLAGS} -DNO_`echo $func | tr '[a-z]' '[A-Z]'`"
-+ else
-+ echo yes
-+ fi
- done
-
--echo Check for memset
-+echo -n Check for memset...
- echo "int main(){ char k; memset(&k,0,0); return 0; }" > conftest.c
- $CC -o conftest conftest.c >/dev/null 2>/dev/null
--[ $? -ne 0 ] && CFLAGS="${CFLAGS} -DZMEM"
-+if [ $? -ne 0 ]; then
-+ echo no
-+ CFLAGS="${CFLAGS} -DZMEM"
-+else
-+ echo yes
-+fi
-+
-
--echo Check for errno declaration
-+echo -n Check for errno declaration...
- cat > conftest.c << _EOF_
- #include <errno.h>
- main()
-@@ -161,9 +196,14 @@
- }
- _EOF_
- $CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
--[ $? -ne 0 ] && CFLAGS="${CFLAGS} -DNO_ERRNO"
-+if [ $? -ne 0 ]; then
-+ echo no
-+ CFLAGS="${CFLAGS} -DNO_ERRNO"
-+else
-+ echo yes
-+fi
-
--echo Check for directory libraries
-+echo -n Check for directory libraries...
- cat > conftest.c << _EOF_
- int main() { return closedir(opendir(".")); }
- _EOF_
-@@ -178,21 +218,30 @@
- done
- if [ ${OPT} ]; then
- LFLAGS2="${LFLAGS2} ${OPT}"
-+ echo yes, ${OPT}
- else
- CFLAGS="${CFLAGS} -DNO_DIR"
-+ echo no
- fi
- fi
-
- # Dynix/ptx 1.3 needed this
--echo Check for readlink
-+echo -n Check for readlink...
- echo "int main(){ return readlink(); }" > conftest.c
- $CC -o conftest conftest.c >/dev/null 2>/dev/null
- if [ $? -ne 0 ]; then
- $CC -o conftest conftest.c -lseq >/dev/null 2>/dev/null
-- [ $? -eq 0 ] && LFLAGS2="${LFLAGS2} -lseq"
-+ if [ $? -eq 0 ]; then
-+ LFLAGS2="${LFLAGS2} -lseq"
-+ echo yes, -lseq
-+ else
-+ echo no
-+ fi
-+else
-+ echo yes
- fi
-
--echo Check for directory include file
-+echo -n Check for directory include file...
- OPT=""
- for inc in dirent.h sys/ndir.h ndir.h sys/dir.h
- do
-@@ -200,17 +249,19 @@
- $CPP conftest.c > /dev/null 2>/dev/null
- [ $? -eq 0 ] && OPT="-DHAVE_`echo $inc | tr '[a-z]./' '[A-Z]__'`" && break
- done
-+echo "${OPT}"
- CFLAGS="${CFLAGS} ${OPT}"
-
--echo Check for non existent include files
-+echo -n Check for non existent include files...
- for inc in stdlib.h stddef.h unistd.h fcntl.h string.h
- do
- echo "#include <$inc>" > conftest.c
- $CPP conftest.c >/dev/null 2>/dev/null
- [ $? -ne 0 ] && CFLAGS="${CFLAGS} -DNO_`echo $inc | tr '[a-z]./' '[A-Z]__'`"
- done
-+echo ok
-
--echo Check for terminal I/O include file
-+echo -n Check for terminal I/O include file...
- OPT=""
- for inc in termios.h termio.h sgtty.h
- do
-@@ -219,9 +270,10 @@
- [ $? -eq 0 ] && OPT="-DHAVE_`echo $inc | tr '[a-z]./' '[A-Z]__'`" && break
- done
- CFLAGS="${CFLAGS} ${OPT}"
-+echo $OPT
-
- # needed for AIX (and others ?) when mmap is used
--echo Check for valloc
-+echo -n Check for valloc...
- cat > conftest.c << _EOF_
- main()
- {
-@@ -231,7 +283,13 @@
- }
- _EOF_
- $CC ${CFLAGS} conftest.c > /dev/null 2>/dev/null
--[ $? -ne 0 ] && CFLAGS="${CFLAGS} -DNO_VALLOC"
-+if [ $? -ne 0 ]; then
-+ echo no
-+ CFLAGS="${CFLAGS} -DNO_VALLOC"
-+else
-+ echo yes
-+fi
-+
-
- echo Check for 64bit fseek
- for func in fseeko fseek64
diff --git a/packaging/zip-2.31-install.patch b/packaging/zip-2.31-install.patch
deleted file mode 100644
index 7a1f69f..0000000
--- a/packaging/zip-2.31-install.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- zip-2.31/unix/Makefile.install 2005-02-28 08:33:50.000000000 +0100
-+++ zip-2.31/unix/Makefile 2005-11-10 12:58:33.221425848 +0100
-@@ -129,7 +129,7 @@
- $(INSTALL_PROGRAM) $(ZIPS) $(BINDIR)
- -cd $(BINDIR); $(CHMOD) $(BINFLAGS) $(ZIPS)
- -$(INSTALL_D) $(MANDIR)
-- $(INSTALL) man/zip.1 $(MANDIR)/zip.$(manext)
-+ $(INSTALL_PROGRAM) man/zip.1 $(MANDIR)/zip.$(manext)
- $(CHMOD) $(MANFLAGS) $(MANDIR)/zip.$(manext)
-
- uninstall:
diff --git a/packaging/zip-2.31-near-4GB.patch b/packaging/zip-2.31-near-4GB.patch
deleted file mode 100644
index 210b183..0000000
--- a/packaging/zip-2.31-near-4GB.patch
+++ /dev/null
@@ -1,293 +0,0 @@
---- zip-2.31/unix/zipup.h.4GB 2005-01-29 07:47:58.000000000 +0100
-+++ zip-2.31/unix/zipup.h 2005-11-10 13:18:02.990593904 +0100
-@@ -6,13 +6,19 @@
- If, for some reason, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
- */
-+#include <features.h>
-+#include <fcntl.h>
- #ifndef O_RDONLY
- # define O_RDONLY 0
- #endif
- #ifndef O_BINARY
- # define O_BINARY 0
- #endif
--#define fhow (O_RDONLY|O_BINARY)
-+#ifdef _LARGEFILE64_SOURCE
-+#define fhow (O_RDONLY | O_LARGEFILE)
-+#else
-+#define fhow O_RDONLY
-+#endif
- #define fbad (-1)
- typedef int ftype;
- #define zopen(n,p) open(n,p)
---- zip-2.31/unix/unix.c.4GB 2005-02-11 03:35:02.000000000 +0100
-+++ zip-2.31/unix/unix.c 2005-11-10 13:24:19.573344624 +0100
-@@ -113,7 +113,11 @@
- char *e; /* pointer to name from readd() */
- int m; /* matched flag */
- char *p; /* path for recursion */
-+#ifdef _LARGEFILE64_SOURCE
-+ struct stat64 s; /* result of stat() */
-+#else
- struct stat s; /* result of stat() */
-+#endif
- struct zlist far *z; /* steps through zfiles list */
-
- if (strcmp(n, "-") == 0) /* if compressing stdin */
-@@ -202,6 +206,15 @@
- } /* (s.st_mode & S_IFDIR) */
- else
- zipwarn("ignoring special file: ", n);
-+
-+ /* Zip uses negative error codes (IIRC, to -3). Make sure file size
-+ doesn't collide with error values. 2^32 - 8193 should be plenty until
-+ info-zip supports zip64. */
-+ if (s.st_size > MAX_ZIP_SIZE) {
-+ zipwarn("file too large: ", a);
-+ return ZE_MISS;
-+ }
-+
- return ZE_OK;
- }
-
-@@ -321,7 +334,12 @@
- 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() */
-+#ifdef _LARGEFILE64_SOURCE
-+ struct stat64 s; /* results of stat() */
-+#else
-+ struct stat s;
-+#endif
-+
- /* converted to pointer from using FNMAX - 11/8/04 EG */
- char *name;
- int len = strlen(f);
-@@ -343,7 +361,11 @@
- name[len - 1] = '\0';
- /* not all systems allow stat'ing a file with / appended */
- if (strcmp(f, "-") == 0) {
-+#ifdef _LARGEFILE64_SOURCE
-+ if (fstat64(fileno(stdin), &s) != 0) {
-+#else
- if (fstat(fileno(stdin), &s) != 0) {
-+#endif
- free(name);
- error("fstat(stdin)");
- }
-@@ -422,7 +444,11 @@
- /* store full data in local header but just modification time stamp info
- in central header */
- {
-+#ifdef _LARGEFILE64_SOURCE
-+ struct stat64 s;
-+#else
- struct stat s;
-+#endif
- char *name;
- int len = strlen(z->name);
-
---- zip-2.31/unix/configure.4GB 2004-12-05 09:51:18.000000000 +0100
-+++ zip-2.31/unix/configure 2005-11-10 13:12:47.010630160 +0100
-@@ -12,7 +12,7 @@
- trap "rm -f conftest* core a.out; exit 1" 1 2 3 15
-
- CC=${1-cc}
--CFLAGS=${2-"-O2 -I. -DUNIX"}
-+CFLAGS=${2-"-O2 -I. -DUNIX -g -D_LARGEFILE64_SOURCE"}
- LFLAGS1=""
- LN="ln -s"
-
---- zip-2.31/fileio.c.4GB 2005-11-10 12:59:43.000000000 +0100
-+++ zip-2.31/fileio.c 2005-11-10 13:07:13.190378552 +0100
-@@ -599,7 +599,11 @@
- this will be done by setfileattr() later.
- */
- {
-+#ifdef _LARGEFILE64_SOURCE
-+ struct stat64 t; /* results of stat64() */
-+#else
- struct stat t; /* results of stat() */
-+#endif
- #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.
-@@ -698,8 +702,11 @@
-
- return _dos_files(&buf, f, 0xff) < 0 ? 0x20 : buf.atr;
- #else
-+#ifdef _LARGEFILE64_SOURCE
-+ struct stat64 s;
-+#else
- struct stat s;
--
-+#endif
- return SSTAT(f, &s) == 0 ? (int) s.st_mode : 0;
- #endif
- }
-@@ -920,3 +927,108 @@
- }
-
- #endif /* NO_RENAME */
-+
-+/*
-+ Wrapper functions for fopen/fseek/ftell for >2GB files.
-+
-+ So, what we do here is add support for 4GB seeks. More appropriately,
-+ 2^32 - 8193 bytes. This is tailored to the way zip uses fseek; it never
-+ seeks backwards more than 8192 bytes.
-+ */
-+#ifdef _LARGEFILE64_SOURCE
-+FILE *
-+lfopen(const char *path, const char *mode)
-+{
-+ int fd;
-+ FILE *f;
-+ int flags;
-+ int x;
-+ char prev;
-+
-+ if (!path || !mode | !strlen(mode))
-+ return NULL;
-+
-+ for (x = 0; x < strlen(mode); x++) {
-+ switch (mode[x]) {
-+ case 'r':
-+ flags = O_RDONLY | O_LARGEFILE;
-+ break;
-+ case 'w':
-+ flags = O_WRONLY | O_LARGEFILE | O_CREAT | O_TRUNC;
-+ break;
-+ case 'a':
-+ flags = O_RDWR | O_LARGEFILE;
-+ break;
-+ case 'b': /* b has no effect */
-+ continue;
-+ case '+':
-+ if (prev == 'r') {
-+ flags = O_RDWR | O_LARGEFILE;
-+ } else if (prev == 'w') {
-+ flags = O_RDWR | O_LARGEFILE | O_CREAT |
-+ O_TRUNC;
-+ } else if (prev == 'a') {
-+ flags = O_RDWR | O_LARGEFILE | O_CREAT;
-+ } else
-+ return NULL;
-+ break;
-+ }
-+ prev = mode[x];
-+ }
-+
-+ fd = open(path, flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-+ if (fd == -1)
-+ return NULL;
-+
-+ f = fdopen(fd, mode);
-+ return f;
-+}
-+
-+int
-+lfseek(FILE *f, ulg pos, int whence)
-+{
-+ struct stat64 sb;
-+ ulg o, delta;
-+ int ret;
-+
-+ /* Hurts performance */
-+ fflush(f);
-+
-+ if (pos <= MAX_ZIP_SIZE) {
-+ return (lseek64(fileno(f), pos, whence) == (off64_t)-1);
-+ }
-+
-+ delta = ~((off64_t)pos - 1);
-+ if (whence == SEEK_CUR) {
-+ o = lseek64(fileno(f), 0, SEEK_CUR);
-+ if (o < delta)
-+ return -1;
-+
-+ o -= delta;
-+ return (lseek64(fileno(f), o, SEEK_SET) == (off64_t)-1);
-+ }
-+
-+ if (whence == SEEK_END) {
-+ fstat64(fileno(f), &sb);
-+
-+ if ((ulg)sb.st_size < delta)
-+ return -1;
-+
-+ o = (off64_t)((sb.st_size) - delta);
-+ return (lseek64(fileno(f), o, SEEK_SET) == (off64_t)-1);
-+ }
-+
-+ return -1;
-+}
-+
-+
-+ulg
-+lftell(FILE *f)
-+{
-+ /* Hurts performance */
-+ fflush(f);
-+ return (ulg)lseek64(fileno(f), 0, SEEK_CUR);
-+}
-+
-+#endif /* _LARGEFILE64_SOURCE */
-+
---- zip-2.31/zip.h.4GB 2005-11-10 12:59:43.000000000 +0100
-+++ zip-2.31/zip.h 2005-11-10 13:18:57.653283912 +0100
-@@ -236,6 +236,7 @@
- #define DOSTIME_MINIMUM ((ulg)0x00210000L)
- #define DOSTIME_2038_01_18 ((ulg)0x74320000L)
-
-+#define MAX_ZIP_SIZE 0xffffdffe /* Max archive / archive member size */
-
- /* Public globals */
- extern uch upper[256]; /* Country dependent case map table */
-@@ -411,6 +412,11 @@
- int putcentral OF((struct zlist far *, FILE *));
- int putend OF((int, ulg, ulg, extent, char *, FILE *));
- int zipcopy OF((struct zlist far *, FILE *, FILE *));
-+#ifdef _LARGEFILE64_SOURCE
-+int lfseek OF((FILE *, ulg, int));
-+ulg lftell OF((FILE *));
-+FILE *lfopen OF((const char *, const char *));
-+#endif /* LF64 */
-
- /* in fileio.c */
- #ifndef UTIL
---- zip-2.31/tailor.h.4GB 2005-03-04 08:45:26.000000000 +0100
-+++ zip-2.31/tailor.h 2005-11-10 13:11:18.909023640 +0100
-@@ -368,12 +368,27 @@
- # define DYN_ALLOC
- #endif
-
-+#ifdef _LARGEFILE64_SOURCE
-+#define fopen lfopen
-+#define fseek lfseek
-+#define ftell lftell
-+#endif /* LF64 */
-+
- #ifndef SSTAT
--# define SSTAT stat
-+# ifdef _LARGEFILE64_SOURCE
-+# define SSTAT stat64
-+# else
-+# define SSTAT stat
-+# endif /* LF64 */
- #endif
- #ifdef S_IFLNK
--# define LSTAT lstat
--# define LSSTAT(n, s) (linkput ? lstat((n), (s)) : SSTAT((n), (s)))
-+# ifdef _LARGEFILE64_SOURCE
-+# define LSTAT lstat64
-+# define LSSTAT(n, s) (linkput ? lstat64((n), (s)) : SSTAT((n), (s)))
-+# else
-+# define LSTAT lstat64
-+# define LSSTAT(n, s) (linkput ? lstat64((n), (s)) : SSTAT((n), (s)))
-+# endif /* LF64 */
- #else
- # define LSTAT SSTAT
- # define LSSTAT SSTAT
diff --git a/packaging/zip.spec b/packaging/zip.spec
index 19846da..c107d49 100644
--- a/packaging/zip.spec
+++ b/packaging/zip.spec
@@ -1,20 +1,11 @@
-Summary: A file compression and packaging utility compatible with PKZIP.
-Name: zip
-Version: 2.31
-Release: 1.2.2
-License: distributable
-Group: Applications/Archiving
-Source: http://ftp.info-zip.org/pub/infozip/src/zip-2.31.tar.gz
-Source1: ftp://ftp.freesoftware.com/pub/infozip/src/zcrypt29.tar.gz
-URL: http://www.info-zip.org/pub/infozip/Zip.html
-Patch0: zip23.patch
-Patch1: exec-shield.patch
-Patch2: zip23-umask.patch
-Patch5: zip-2.3-currdir.patch
-Patch6: zip-2.31-install.patch
-Patch7: zip-2.31-near-4GB.patch
-Patch8: zip-2.31-configure.patch
-BuildRoot: %{_tmppath}/%{name}-%{version}-root
+Summary: A file compression and packaging utility compatible with PKZIP.
+Name: zip
+Version: 3.0
+Release: 1.0.1
+License: BSD-2.0
+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
@@ -26,15 +17,7 @@ Install the zip package if you need to compress files using the zip
program.
%prep
-%setup -q -a 1
-%patch0 -p1 -b .zip
-%patch1 -p1 -b .zip
-%patch2 -p1 -b .umask
-%patch5 -p1 -b .currdir
-%patch6 -p1 -b .install
-%patch7 -p1 -b .4gb
-%patch8 -p1 -b .lhh
-
+%setup -q
%build
make -f unix/Makefile prefix=/usr "CFLAGS=$RPM_OPT_FLAGS -I. -DUNIX -D_LARGEFILE64_SOURCE" generic_gcc
@@ -52,129 +35,19 @@ for n in zipnote zipsplit zip zipcloak ; do
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 MANUAL TODO WHATSNEW WHERE LICENSE
+%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*
-
-%changelog
-* Wed Jul 12 2006 Jesse Keating <jkeating@redhat.com> - 2.31-1.2.2
-- rebuild
-
-* Fri Feb 10 2006 Jesse Keating <jkeating@redhat.com> - 2.31-1.2.1
-- bump again for double-long bug on ppc(64)
-
-* Tue Feb 07 2006 Jesse Keating <jkeating@redhat.com> - 2.31-1.2
-- rebuilt for new gcc4.1 snapshot and glibc changes
-
-* Fri Dec 09 2005 Jesse Keating <jkeating@redhat.com>
-- rebuilt
-
-* Thu Nov 10 2005 Ivana Varekova <varekova@redhat.com> 2.31-1
-- update to 2.31
-
-* Mon Mar 7 2005 Ivana Varekova <varekova@redhat.com> 2.3-30
-- rebuilt
-
-* Mon Jan 17 2005 Ivana Varekova <varekova@redhat.com> 2.3-29
-- Fix bug #142237 - problem with -d and ./files containing archives
-
-* Mon Jun 21 2004 Lon Hohberger <lhh@redhat.com> 2.3-24
-- Extend max file/archive size to 2^32-8193 (4294959103) bytes
-- Include better debugging output for configure script
-
-* Tue Jun 15 2004 Elliot Lee <sopwith@redhat.com>
-- rebuilt
-
-* Fri Mar 19 2004 Lon Hohberger <lhh@redhat.com> 2.3-22
-- Fix typos
-
-* Tue Feb 17 2004 Lon Hohberger <lhh@redhat.com> 2.3-21
-- Include LICENSE file per bugzilla #116004
-
-* Fri Feb 13 2004 Elliot Lee <sopwith@redhat.com>
-- rebuilt
-
-* Mon Dec 22 2003 Lon Hohberger <lhh@redhat.com> 2.3-19
-- Make temp file have umask 0066 mode (#112516)
-
-* Fri Oct 24 2003 Lon Hohberger <lhh@redhat.com> 2.3-18
-- Incorporate Arjan's exec-shield patch for i386
-
-* Wed Jun 04 2003 Elliot Lee <sopwith@redhat.com>
-- rebuilt
-
-* Wed Jan 22 2003 Tim Powers <timp@redhat.com>
-- rebuilt
-
-* Thu Dec 19 2002 Tim Powers <timp@redhat.com>
-- bump and rebuild
-
-* Fri Jun 21 2002 Tim Powers <timp@redhat.com>
-- automated rebuild
-
-* Thu May 23 2002 Tim Powers <timp@redhat.com>
-- automated rebuild
-
-* Tue Apr 2 2002 Trond Eivind Glomsrød <teg@redhat.com>
-- Don't strip explicitly
-
-* Wed Mar 13 2002 Trond Eivind Glomsrød <teg@redhat.com> 2.3-11
-- Add URL
-
-* Sun Jun 24 2001 Elliot Lee <sopwith@redhat.com>
-- Bump release + rebuild.
-
-* Thu Aug 25 2000 Bill Nottingham <notting@redhat.com>
-- add encryption code (#16878)
-
-* Thu Jul 13 2000 Prospector <bugzilla@redhat.com>
-- automatic rebuild
-
-* Sun Jun 11 2000 Bill Nottingham <notting@redhat.com>
-- rebuild in new environment
-
-* Mon Mar 13 2000 Bill Nottingham <notting@redhat.com>
-- spec file cleanups (#10143)
-
-* Mon Feb 7 2000 Bill Nottingham <notting@redhat.com>
-- fix some perms
-
-* Wed Feb 02 2000 Cristian Gafton <gafton@redhat.com>
-- fix description
-- man pages are compressed
-
-* Tue Jan 11 2000 Bill Nottingham <notting@redhat.com>
-- update to 2.3
-
-* Fri Jul 30 1999 Bill Nottingham <notting@redhat.com>
-- update to 2.2
-
-* Sun Mar 21 1999 Cristian Gafton <gafton@redhat.com>
-- auto rebuild in the new build environment (release 8)
-
-* Thu Mar 18 1999 Cristian Gafton <gafton@redhat.com>
-- updated text in the spec file
-
-* Fri Jan 15 1999 Cristian Gafton <gafton@redhat.com>
-- patch top build on the arm
-
-* Mon Dec 21 1998 Michael Maher <mike@redhat.com>
-- built package for 6.0
-
-* Mon Aug 10 1998 Jeff Johnson <jbj@redhat.com>
-- build root
-
-* Fri May 08 1998 Prospector System <bugs@redhat.com>
-- translations modified for de, fr, tr
-
-* Thu Jul 10 1997 Erik Troan <ewt@redhat.com>
-- built against glibc
+%{_mandir}/man1/zip*1*
+/usr/share/license/%{name}
diff --git a/packaging/zip23-umask.patch b/packaging/zip23-umask.patch
deleted file mode 100644
index 7ab6005..0000000
--- a/packaging/zip23-umask.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-diff -ur zip-2.3/zip.c zip-2.3-lhh/zip.c
---- zip-2.3/zip.c 1999-11-16 15:08:10.000000000 -0500
-+++ zip-2.3-lhh/zip.c 2003-12-22 09:32:56.000000000 -0500
-@@ -849,6 +849,7 @@
- /* Add, update, freshen, or delete zip entries in a zip file. See the
- command help in help() above. */
- {
-+ mode_t old_umask; /* umask prior to temp file creation */
- int a; /* attributes of zip file */
- ulg c; /* start of central directory */
- int d; /* true if just adding to a zip file */
-@@ -1830,9 +1831,11 @@
- if ((tempzip = tempname(zipfile)) == NULL) {
- ZIPERR(ZE_MEM, "allocating temp filename");
- }
-+ old_umask = umask(0066);
- if ((tempzf = y = fopen(tempzip, FOPW_TMP)) == NULL) {
- ZIPERR(ZE_TEMP, tempzip);
- }
-+ umask(old_umask);
- }
-
- #if (!defined(VMS) && !defined(CMS_MVS))
diff --git a/packaging/zip23.patch b/packaging/zip23.patch
deleted file mode 100644
index 690630c..0000000
--- a/packaging/zip23.patch
+++ /dev/null
@@ -1,93 +0,0 @@
---- zip-2.3/zip.h.zip Mon Nov 8 14:36:51 1999
-+++ zip-2.3/zip.h Tue Jan 11 11:46:06 2000
-@@ -60,6 +60,7 @@
-
- /* Set up portability */
- #include "tailor.h"
-+#include <strings.h>
-
- #ifdef USE_ZLIB
- # include "zlib.h"
-@@ -433,12 +434,6 @@
- int setfileattr OF((char *, int));
- char *tempname OF((char *));
- int fcopy OF((FILE *, FILE *, ulg));
--
--#ifdef ZMEM
-- char *memset OF((char *, int, unsigned int));
-- char *memcpy OF((char *, char *, unsigned int));
-- int memcmp OF((char *, char *, unsigned int));
--#endif /* ZMEM */
-
- /* in system dependent fileio code (<system>.c) */
- #ifndef UTIL
---- zip-2.3/fileio.c.zip Sun Nov 7 05:29:03 1999
-+++ zip-2.3/fileio.c Tue Jan 11 11:46:43 2000
-@@ -918,67 +918,3 @@
- }
-
- #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 */
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: <dima@mitrah.ru>
+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 <roelofs@lds.sonic.net>; 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 <roelofs@sonic.net>; 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 <roelofs@sonic.net>; 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 <newt@pobox.com>; 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 <newt@pobox.com>; 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 <dima@mitrah.ru>
+X-Mailer: The Bat! (v1.62r) Personal
+Reply-To: Dmitri Koulikov <dima@mitrah.ru>
+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 <dima@mitrah.ru>
+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/extra.fld b/proginfo/extrafld.txt
index 769fef1..624e05c 100644
--- a/proginfo/extra.fld
+++ b/proginfo/extrafld.txt
@@ -20,7 +20,11 @@ format unless otherwise specified. Note that "Short" means two bytes,
of their native sizes. Unless specifically noted, all integer fields should
be interpreted as unsigned (non-negative) numbers.
-Christian Spieler, 20040507
+Christian Spieler, 20010517
+
+Updated to include the Unicode extra fields. Added new Unix extra field.
+
+Ed Gordon, 20060819, 20070607, 20070909, 20080426, 20080509
-------------------------
@@ -32,32 +36,24 @@ Christian Spieler, 20040507
0x0001 ZIP64 extended information extra field
0x0007 AV Info
- 0x0008 Reserved for future Unicode file name data (PFS)
0x0009 OS/2 extended attributes (also Info-ZIP)
0x000a NTFS (Win9x/WinNT FileTimes)
0x000c OpenVMS (also Info-ZIP)
0x000d Unix
- 0x000e Reserved for file stream and fork descriptors
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
- 0x0017 Strong Encryption Header
- 0x0018 Record Management Controls
- 0x0019 PKCS#7 Encryption Recipient Certificate List
- 0x0065 IBM S/390 (Z390), AS/400 (I400) attributes
- - uncompressed
- 0x0066 Reserved for IBM S/390 (Z390), AS/400 (I400)
- attributes - compressed
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)
- 0x2805 ZipIt Macintosh 1.3.5+
- 0x334d Info-ZIP Macintosh (new, D. Haase's 'Mac3' field)
+ 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)
@@ -71,52 +67,21 @@ Christian Spieler, 20040507
0x4f4c Xceed original location extra field
0x5356 AOS/VS (binary ACL)
0x5455 extended timestamp
- 0x554e Xceed unicode extra field
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
- 0x7441 AtheOS (AtheOS/Syllable attributes)
+ 0x7075 Info-ZIP Unicode Path
0x756e ASi Unix
- 0x7855 Info-ZIP Unix (new)
+ 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:
- -ZIP64 Extended Information Extra Field (0x0001):
- ===============================================
-
- 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 uncompressed 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.
-
-
- -OS/2 Extended Attributes Extra Field (0x0009):
- =============================================
+ -OS/2 Extended Attributes Extra Field:
+ ====================================
The following is the layout of the OS/2 extended attributes "extra"
block. (Last Revision 19960922)
@@ -145,10 +110,9 @@ The following are detailed descriptions of the known extra-field block types:
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.
+ 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:
@@ -187,8 +151,8 @@ The following are detailed descriptions of the known extra-field block types:
extended for other operating systems as needed.
- -Windows NT Security Descriptor Extra Field (0x4453):
- ===================================================
+ -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)
@@ -224,8 +188,8 @@ The following are detailed descriptions of the known extra-field block types:
format.
- -PKWARE Win95/WinNT Extra Field (0x000a):
- =======================================
+ -PKWARE Win95/WinNT Extra Field:
+ ==============================
The following description covers PKWARE's "NTFS" attributes
"extra" block, introduced with the release of PKZIP 2.50 for
@@ -250,7 +214,7 @@ The following are detailed descriptions of the known extra-field block types:
.
TagN Short NTFS attribute tag value #N
SizeN Short Size of attribute #N, in bytes
- (var.) SubSizeN Attribute #N data
+ (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)
@@ -272,11 +236,11 @@ The following are detailed descriptions of the known extra-field block types:
which is "01-Jan-1601 00:00:00 UTC".
- -PKWARE OpenVMS Extra Field (0x000c):
- ===================================
+ -PKWARE OpenVMS Extra Field:
+ ==========================
- The following is the layout of PKWARE's OpenVMS attributes
- "extra" block. (Last Revision 12/17/91)
+ 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.
@@ -401,53 +365,23 @@ The following are detailed descriptions of the known extra-field block types:
Creator Byte[4] four-byte Mac creator string
- -ZipIt Macintosh Extra Field (short, for files):
- ==============================================
+ -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 of
- files (not directories) that do not have a MacBinary encoded
- file. The local-header and central-header versions are identical.
- (Last Revision 20030602)
+ 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 (min. 12)
+ 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
- fdFlags beShort attributes from FInfo.frFlags,
- may be omitted
- 0x0000 beShort reserved, may be omitted
-
-
- -ZipIt Macintosh Extra Field (short, for directories):
- ====================================================
-
- The following is the layout of a shortened variant of the
- ZipIt extra block for Macintosh used only for directory
- entries. This variant is used by ZipIt 1.3.5 and newer to
- save some optional Mac-specific information about directories.
- The local-header and central-header versions are identical.
-
- Value Size Description
- ----- ---- -----------
- (Mac2c) 0x2805 Short tag for this extra block type
- TSize Short total data size for this block (12)
- "ZPIT" beLong extra-field signature
- frFlags beShort attributes from DInfo.frFlags, may
- be omitted
- View beShort ZipIt view flag, may be omitted
-
-
- The View field specifies ZipIt-internal settings as follows:
-
- Bits of the Flags:
- bit 0 if set, the folder is shown expanded (open)
- when the archive contents are viewed in ZipIt.
- bits 1-15 reserved, zero;
-Info-ZIP Macintosh Extra Field (new):
@@ -646,8 +580,8 @@ The following are detailed descriptions of the known extra-field block types:
flData is an uncompressed fldata_t struct.
- -PKWARE Unix Extra Field (0x000d):
- ================================
+ -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.
@@ -686,8 +620,8 @@ The following are detailed descriptions of the known extra-field block types:
only the two tag bytes are different.]
- -PATCH Descriptor Extra Field (0x000f):
- =====================================
+ -PATCH Descriptor Extra Field:
+ ============================
The following is the layout of the Patch Descriptor "extra"
block.
@@ -710,8 +644,8 @@ The following are detailed descriptions of the known extra-field block types:
Bits Description
---- ----------------
- 0 Use for auto detection
- 1 Treat as a self-patch
+ 0 Use for autodetection
+ 1 Treat as selfpatch
2-3 RESERVED
4-5 Action (see below)
6-7 RESERVED
@@ -739,33 +673,28 @@ The following are detailed descriptions of the known extra-field block types:
ignore 2
fail 3
- Patch support is provided by PKPatchMaker(tm) technology and is
- covered under U.S. Patents and Patents Pending.
-
- -PKCS#7 Store for X.509 Certificates (0x0014):
- ============================================
+ -PKCS#7 Store for X.509 Certificates:
+ ===================================
- This field contains information about each of the certificates
- files may be signed with. When the Central Directory Encryption
- feature is enabled for a ZIP file, this record will appear in
- the Archive Extra Data Record, otherwise it will appear in the
- first central directory record and will be ignored in any
- other record.
+ 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
- TSize 2 bytes Size of the store data
- SData TSize Data about the store
+ 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
+ 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
@@ -776,13 +705,13 @@ The following are detailed descriptions of the known extra-field block types:
PKCS_7_ANS_ENCODING | X509_ASN_ENCODING.
- -X.509 Certificate ID and Signature for individual file (0x0015):
- ===============================================================
+ -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 a particular file. It also
- contains the signature data. This field can appear multiple
- times, but can only appear once per certificate.
+ 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.
@@ -826,15 +755,13 @@ The following are detailed descriptions of the known extra-field block types:
hash created with the given AlgID.
- -X.509 Certificate ID and Signature for central directory (0x0016):
- =================================================================
+ -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 structure.
- When the Central Directory Encryption feature is enabled for a
- ZIP file, this record will appear in the Archive Extra Data Record,
- otherwise it will appear in the first central directory record,
- along with the store. The data structure is the
+ 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.
@@ -847,105 +774,44 @@ The following are detailed descriptions of the known extra-field block types:
Note: all fields stored in Intel low-byte/high-byte order.
- Value Size Description
- ----- ---- -----------
- (CDID) 0x0016 2 bytes Tag for this "extra" block type
- TSize 2 bytes Size of data that follows
- TData TSize Data
-
-
- -Strong Encryption Header (0x0017) (EFS):
- ===============================
-
- Value Size Description
- ----- ---- -----------
- 0x0017 2 bytes Tag for this "extra" block type
- TSize 2 bytes Size of data that follows
- Format 2 bytes Format definition for this record
- AlgID 2 bytes Encryption algorithm identifier
- Bitlen 2 bytes Bit length of encryption key
- Flags 2 bytes Processing flags
- CertData TSize-8 Certificate decryption extra field data
- (refer to the explanation for CertData
- in the section describing the
- Certificate Processing Method under
- the Strong Encryption Specification)
+ Value Size Description
+ ----- ---- -----------
+ (CDID) 0x0016 2 bytes Tag for this "extra" block type
+ CSize 2 bytes Size of Method
+ Method (variable)
- -Record Management Controls (0x0018):
- ===================================
+ -ZIP64 Extended Information Extra Field:
+ ======================================
- Value Size Description
- ----- ---- -----------
-(Rec-CTL) 0x0018 2 bytes Tag for this "extra" block type
- CSize 2 bytes Size of total extra block data
- Tag1 2 bytes Record control attribute 1
- Size1 2 bytes Size of attribute 1, in bytes
- Data1 Size1 Attribute 1 data
- .
- .
- .
- TagN 2 bytes Record control attribute N
- SizeN 2 bytes Size of attribute N, in bytes
- DataN SizeN Attribute N data
-
-
- -PKCS#7 Encryption Recipient Certificate List (0x0019): (EFS)
- =====================================================
-
- This field contains the information about each of the certificates
- that files may be encrypted with. This field should only appear
- in the archive extra data record. This field is not required and
- serves only to aide archive modifications by preserving public
- encryption data. Individual security requirements may dictate
- that this data be omitted to deter information exposure.
+ 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
- ----- ---- -----------
- (CStore) 0x0019 2 bytes Tag for this "extra" block type
- TSize 2 bytes Size of the store data
- TData TSize Data about the store
-
- TData:
-
- Value Size Description
- ----- ---- -----------
- Version 2 bytes Format version number - must 0x0001 at this time
- CStore (var) PKCS#7 data blob
-
-
- -MVS Extra Field (PKWARE, 0x0065):
- ================================
-
- The following is the layout of the MVS "extra" block.
- Note: Some fields are stored in Big Endian format.
- All text is in EBCDIC format unless otherwise specified.
-
- Value Size Description
- ----- ---- -----------
- (MVS) 0x0065 2 bytes Tag for this "extra" block type
- TSize 2 bytes Size for the following data block
- ID 4 bytes EBCDIC "Z390" 0xE9F3F9F0 or
- "T4MV" for TargetFour
- (var) TSize-4 Attribute data
-
-
- -OS/400 Extra Field (0x0065):
- ===========================
-
- The following is the layout of the OS/400 "extra" block.
- Note: Some fields are stored in Big Endian format.
- All text is in EBCDIC format unless otherwise specified.
+ 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
- Value Size Description
- ----- ---- -----------
- (OS400) 0x0065 2 bytes Tag for this "extra" block type
- TSize 2 bytes Size for the following data block
- ID 4 bytes EBCDIC "I400" 0xC9F4F0F0 or
- "T4MV" for TargetFour
- (var) TSize-4 Attribute data
+ This entry in the Local header must include BOTH original
+ and compressed file sizes.
-Extended Timestamp Extra Field:
@@ -1189,63 +1055,6 @@ The following are detailed descriptions of the known extra-field block types:
field may contain anything--text, flags, bitmaps, etc.
- -AtheOS Extra Field:
- ==================
-
- The following is the layout of the file-attributes extra block for
- AtheOS. This field is a very close spin-off from the BeOS e.f.
- The only differences are:
- - a new extra field signature
- - numeric field in the attributes data are stored in little-endian
- format ("i386" was initial hardware for AtheOS)
- (Last Revision 20040908)
-
- Local-header version:
-
- Value Size Description
- ----- ---- -----------
- (AtheOS) 0x7441 Short tag for this extra block type ("At")
- 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
- ----- ---- -----------
- (AtheOS) 0x7441 Short tag for this extra block type ("At")
- 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 AtheOS-specific block of data in little-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:
====================
@@ -1400,8 +1209,8 @@ The following are detailed descriptions of the known extra-field block types:
reserved 3 Bytes reserved for future use
- -FWKCS MD5 Extra Field (0x4b46):
- ==============================
+ -FWKCS MD5 Extra Field:
+ =====================
The FWKCS Contents_Signature System, used in automatically
identifying files independent of filename, optionally adds
@@ -1439,3 +1248,125 @@ The following are detailed descriptions of the known extra-field block types:
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/infozip.who b/proginfo/infozip.who
index 242cd95..994851c 100644
--- a/proginfo/infozip.who
+++ b/proginfo/infozip.who
@@ -3,14 +3,15 @@ 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). If you have contributed and your name
-has been forgotten, please send a reminder to the zip-bugs address given
-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.
+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
+
+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
@@ -22,6 +23,8 @@ 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
@@ -68,10 +71,13 @@ 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)
+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
@@ -134,6 +140,7 @@ 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
@@ -144,6 +151,7 @@ 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
@@ -192,6 +200,7 @@ 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
@@ -230,3 +239,4 @@ 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/nt.sd b/proginfo/ntsd.txt
index 8ac31ba..8ac31ba 100644
--- a/proginfo/nt.sd
+++ b/proginfo/ntsd.txt
diff --git a/amiga/timezone.doc b/proginfo/timezone.txt
index 7868093..7868093 100644
--- a/amiga/timezone.doc
+++ b/proginfo/timezone.txt
diff --git a/proginfo/ziplimit.txt b/proginfo/ziplimit.txt
index e72d917..feacabb 100644
--- a/proginfo/ziplimit.txt
+++ b/proginfo/ziplimit.txt
@@ -1,5 +1,7 @@
ziplimit.txt
+Zip 3 and UnZip 6 now support many of the extended limits of Zip64.
+
A) Hard limits of the Zip archive format:
Number of entries in Zip archive: 64 k (2^16 - 1 entries)
@@ -35,17 +37,17 @@ A) Hard limits of the Zip archive format:
In 2001, PKWARE has published version 4.5 of the Zip format specification
(together with the release of PKZIP for Windows 4.5). This specification
defines new extra field blocks that allow to break the size limits of the
- standard zipfile structures. In this extended "Zip64" format, the limits
- on the size of zip entries and the size of the complete zip archive are
- extended to (2^64 - 1) Bytes; the maximum number of archive entries and
- split volumes are enlarged to (2^64 - 1) respective (2^32 - 1).
- Currently, these extensions are not yet supported by the released Info-ZIP
- software. However, new major releases (Zip 3.0 and UnZip 6.0) are under
- development and will support Zip64 archives on selected environments.
- (Beta releases are already available for Unix, VMS and Win32.)
+ standard zipfile structures. In this extended Zip format, the size limits
+ of zip entries (and the complete zip archive) have been extended to
+ (2^64 - 1) Bytes and the maximum number of archive entries to (2^32-1).
+ Zip 3.0 supports these Zip64 extensions and should be released shortly.
+ UnZip 6.0 should support these standards.
B) Implementation limits of UnZip:
+ Note:
+ This section should be updated when UnZip 6.0 is near release.
+
1. Size limits caused by file I/O and decompression handling:
Size of Zip archive: 2 GByte (2^31 - 1 Bytes)
Compressed size of archive entry: 2 GByte (2^31 - 1 Bytes)
@@ -95,12 +97,22 @@ B) Implementation limits of UnZip:
C) Implementation limits of the Zip executables:
+ Note:
+ This section has been updated to reflect Zip 3.0.
+
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.
+ Without Zip64 extensions:
+ 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...)
+ Using Zip64 extensions:
+ Size of Zip archive: 2^63 - 1 Bytes
+ Compressed size of archive entry: 2^63 - 1 Bytes
+ Uncompressed size of entry: 2^63 - 1 Bytes
+
+ Multi-volume archive creation now supported in the form of split
+ archvies. Currently up to 99,999 splits are supported.
2. Limits caused by handling of archive contents lists
@@ -110,7 +122,8 @@ C) Implementation limits of the Zip executables:
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)
+
+ 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
@@ -155,19 +168,29 @@ C) Implementation limits of the Zip executables:
24 bytes (32-bit) resp. 22 bytes (16-bit)
+ 3 * length of filename
+ NOTE: For larger systems, the actual limits may be more performance
+ issues (how long you want to wait) rather than available memory and other
+ resources.
+
D) Some technical remarks:
- 1. The 2GByte size limit on archive files is a consequence of the portable
- C implementation of the Info-ZIP programs.
- Zip archive processing requires random access to the archive file for
- jumping between different parts of the archive's structure.
- In standard C, this is done via stdio functions fseek()/ftell() resp.
- unix-io functions lseek()/tell(). In many (most?) C implementations,
- these functions use "signed long" variables to hold offset pointers
- into sequential files. In most cases, this is a signed 32-bit number,
- which is limited to ca. 2E+09. There may be specific C runtime library
- implementations that interpret the offset numbers as unsigned, but for
- us, this is not reliable in the context of portable programming.
+ 1. For executables compiled without LARGE_FILE_SUPPORT and ZIP64_SUPPORT
+ enabled, the 2GByte size limit on archive files is a consequence of
+ the portable C implementation of the Info-ZIP programs. Zip archive
+ processing requires random access to the archive file for jumping
+ between different parts of the archive's structure. In standard C,
+ this is done via stdio functions fseek()/ftell() resp. unix-io functions
+ lseek()/tell(). In many (most?) C implementations, these functions use
+ "signed long" variables to hold offset pointers into sequential files.
+ In most cases, this is a signed 32-bit number, which is limited to
+ ca. 2E+09. There may be specific C runtime library implementations
+ that interpret the offset numbers as unsigned, but for us, this is not
+ reliable in the context of portable programming.
+
+ If LARGE_FILE_SUPPORT and ZIP64_SUPPORT are defined and supported by
+ the system, 64-bit off_t file offsets are supported and the above
+ larger limits are supported. As off_t is signed, the maximum offset
+ is usually limited to 2^63 - 1.
2. The 2GByte limit on the size of a single compressed archive member
is again a consequence of the implementation in C.
@@ -203,16 +226,18 @@ D) Some technical remarks:
performance, stability and maintainability. Therefore, it is
quite unlikely that this will ever happen for Zip/UnZip.
- The argumentation above is somewhat out-dated. The new releases
- Zip 3 and UnZip 6 will support archive sizes larger than 4GB on
- systems where the required underlying support for 64-bit file offsets
- and file sizes is available from the OS (and the C runtime environment).
- However, this new support will partially break compatibility with
- older "legacy" systems. And it should be expected that the portability
- and readability of the UnZip and Zip code may be reduced due to the
- extensive use of non-standard language extension needed for 64-bit
- support on the major target systems.
+ With LARGE_FILE_SUPPORT and ZIP64_SUPPORT enabled and supported,
+ the above arguments still apply, but the limits are based on 64 bits
+ instead of 32 and should allow most large files and archives to be
+ processed.
+
+ Anyway, the Zip archive format is more and more showing its age...
+ The effort to lift the 2GByte limits should be better invested in
+ creating a successor for the Zip archive format and tools. But given
+ the latest improvements to the format and the wide acceptance of zip
+ files, the format will probably be around for awhile more.
-Please report any problems to: Zip-Bugs at www.info-zip.org
+Please report any problems using the web contact form at: www.Info-ZIP.org
-Last updated: 22 February 2005, Christian Spieler
+Last updated: 26 January 2002, Christian Spieler
+ 25 May 2008, Ed Gordon
diff --git a/qdos/Makefile.qdos b/qdos/Makefile.qdos
index 1028273..df68aad 100644
--- a/qdos/Makefile.qdos
+++ b/qdos/Makefile.qdos
@@ -29,13 +29,13 @@ all: zip
# object file lists
OBJZ = zip.o zipfile.o zipup.o fileio.o util.o globals.o crypt.o qdos.o ttyio.o
-OBJI = deflate.o trees.o qfileio.o crctab.o
+OBJI = deflate.o trees.o qfileio.o crc32.o
OBJA = config.o crc68.o match.o
# crc32.o
OBJQ = qdos_.o config.o qfileio_.o
-OBJU = zipfile_.o zipup_.o fileio_.o util_.o globals.o $(OBJQ)
+OBJU = zipfile_.o fileio_.o util_.o globals.o $(OBJQ)
OBJN = zipnote.o $(OBJU)
-OBJC = zipcloak.o $(OBJU) crctab.o crypt_.o
+OBJC = zipcloak.o $(OBJU) crc32_.o crypt_.o
OBJS = zipsplit.o $(OBJU)
@@ -58,6 +58,8 @@ $(OBJI): zip.h ziperr.h tailor.h
$(OBJN): zip.h ziperr.h tailor.h
$(OBJS): zip.h ziperr.h tailor.h
$(OBJC): zip.h ziperr.h tailor.h
+zip.o zipup.o crc32.o crypt.o fileio.o zipfile.o: crc32.h
+zipcloak.o crc32_.o crypt_.o fileio_.o zipfile_.o: crc32.h
zip.o zipup.o crypt.o zipup_.o zipcloak.o crypt_.o: crypt.h
qfileio.o: qdos/qfileio.c
diff --git a/qdos/Makefile.qlzip b/qdos/Makefile.qlzip
index e12f004..d69009a 100644
--- a/qdos/Makefile.qlzip
+++ b/qdos/Makefile.qlzip
@@ -33,12 +33,12 @@ LFLAGS2 = -s
# object file lists
OBJZ = zip.o zipfile.o zipup.o fileio.o util.o globals.o crypt.o ttyio.o \
- unix.o crc_gcc.o crctab.o qdos.o
+ unix.o crc_gcc.o crc32.o qdos.o
OBJI = deflate.o trees.o
OBJA =
OBJU = zipfile_.o fileio_.o util_.o globals.o unix_.o
OBJN = zipnote.o $(OBJU)
-OBJC = zipcloak.o $(OBJU) crctab.o crypt_.o ttyio.o
+OBJC = zipcloak.o $(OBJU) crc32_.o crypt_.o ttyio.o
OBJS = zipsplit.o $(OBJU)
ZIP_H = zip.h ziperr.h tailor.h unix/osdep.h
@@ -62,6 +62,8 @@ $(OBJI): $(ZIP_H)
$(OBJN): $(ZIP_H)
$(OBJS): $(ZIP_H)
$(OBJC): $(ZIP_H)
+zip.o zipup.o crypt.o fileio.o zipfile.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
diff --git a/qdos/crc68.s b/qdos/crc68.s
index cf74e47..9ee9df3 100644
--- a/qdos/crc68.s
+++ b/qdos/crc68.s
@@ -1,10 +1,10 @@
;===========================================================================
-; Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+; Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
;
-; See the accompanying file LICENSE, version 1999-Oct-05 or later
+; 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, both of these files are missing, the Info-ZIP license
-; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+; 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
;===========================================================================
.text
diff --git a/qdos/qdos.c b/qdos/qdos.c
index f07f56e..906519a 100644
--- a/qdos/qdos.c
+++ b/qdos/qdos.c
@@ -1,9 +1,11 @@
/*
+ qdos/qdos.c
+
Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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
+ 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
*/
/*
@@ -185,7 +187,7 @@ void QDOSexit(void)
}
}
}
- exit(0);
+ exit(ZE_OK);
}
/* Access seems to be *always* broken in c68 */
diff --git a/qdos/qfileio.c b/qdos/qfileio.c
index 07a6bd8..0029b8f 100644
--- a/qdos/qfileio.c
+++ b/qdos/qfileio.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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.info-zip.org/pub/infozip/license.html
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
#include "zip.h"
@@ -162,8 +162,9 @@ iztimes *t; /* return value: access, modific. and creation times */
a file size of -1 */
{
struct stat s; /* results of stat() */
+ /* from FNMAX to malloc - 11/8/04 EG */
char *name;
- unsigned int len = strlen(f);
+ int len = strlen(f);
if (f == label) {
if (a != NULL)
@@ -174,11 +175,9 @@ iztimes *t; /* return value: access, modific. and creation times */
t->atime = t->mtime = t->ctime = label_utim;
return label_time;
}
-
- name = malloc(len+1);
- if (!name)
- return 0; /* ideally, would like to report alloc-failure warning/error */
-
+ if ((name = malloc(len + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "filetime");
+ }
strcpy(name, f);
if (name[len - 1] == '/')
name[len - 1] = '\0';
@@ -195,6 +194,7 @@ iztimes *t; /* return value: access, modific. and creation times */
free(name);
return 0;
}
+ free(name);
if (a != NULL) {
*a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE);
@@ -210,8 +210,6 @@ iztimes *t; /* return value: access, modific. and creation times */
t->ctime = s.st_ctime;
}
- free(name);
-
return unix2dostime(&s.st_mtime);
}
diff --git a/revision.h b/revision.h
index d0f4353..7348cb7 100644
--- a/revision.h
+++ b/revision.h
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ revision.h - Zip 3
- See the accompanying file LICENSE, version 2005-Feb-10 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*
@@ -14,49 +16,59 @@
#define __revision_h 1
/* For api version checking */
-#define Z_MAJORVER 2
-#define Z_MINORVER 3
-#define Z_PATCHLEVEL 1
-#define Z_BETALEVEL ""
+#define Z_MAJORVER 3
+#define Z_MINORVER 0
+#define Z_PATCHLEVEL 0
+#define Z_BETALEVEL "i BETA"
-#define VERSION "2.31"
-#define REVDATE "March 8th 2005"
+#define VERSION "3.0"
+#define REVDATE "July 5th 2008"
#define DW_MAJORVER Z_MAJORVER
#define DW_MINORVER Z_MINORVER
#define DW_PATCHLEVEL Z_PATCHLEVEL
-#ifndef WINDLL
+#ifndef IZ_COMPANY_NAME /* might be already defined... */
+# define IZ_COMPANY_NAME "Info-ZIP"
+#endif
+
+#if !defined(WINDLL) && !defined(IZ_VERSION_SYMBOLS_ONLY)
/* Copyright notice for binary executables--this notice only applies to
* those (zip, zipcloak, zipsplit, and zipnote), not to this file
* (revision.h).
*/
-#ifndef DEFCPYRT /* copyright[] gets defined only once ! */
-extern ZCONST char *copyright[2]; /* keep array sizes in sync with number */
-extern ZCONST char *swlicense[50]; /* of text line in definition below !! */
-extern ZCONST char *versinfolines[7];
-extern ZCONST char *cryptnote[7];
+#ifndef DEFCPYRT
+/* copyright[] et.al. get defined only once ! */
+/* keep array sizes in sync with number of text */
+/* lines in the array definitions below !! */
+extern ZCONST char *copyright[1];
+extern ZCONST char * far swlicense[50];
+extern ZCONST char * far versinfolines[7];
+extern ZCONST char * far cryptnote[7];
#else /* DEFCPYRT */
ZCONST char *copyright[] = {
-"Copyright (C) 1990-2005 Info-ZIP",
-"Type '%s \"-L\"' for software license."
+"Copyright (c) 1990-2008 Info-ZIP - Type '%s \"-L\"' for software license."
+/* XXX still necessary ???? */
+#ifdef AZTEC_C
+, /* extremely lame compiler bug workaround */
+#endif
};
-ZCONST char *versinfolines[] = {
+ZCONST char * far versinfolines[] = {
"This is %s %s (%s), by Info-ZIP.",
-"Currently maintained by Onno van der Linden. Please send bug reports to",
-"the authors using http://www.info-zip.org/zip-bug.html; see README for details.",
+"Currently maintained by E. Gordon. Please send bug reports to",
+"the authors using the web page at www.info-zip.org; see README for details.",
"",
-"Latest sources and executables are at ftp://ftp.info-zip.org/pub/infozip, as of",
-"above date; see http://www.info-zip.org for other sites.",
+"Latest sources and executables are at ftp://ftp.info-zip.org/pub/infozip,",
+"as of above date; see http://www.info-zip.org/ for other sites.",
""
};
-/* new notice - 2/2/2005 EG */
-ZCONST char *cryptnote[] = {
+/* new notice - 4 March 2007 */
+ZCONST char * far cryptnote[] = {
"Encryption notice:",
"\tThe encryption code of this program is not copyrighted and is",
"\tput in the public domain. It was originally written in Europe",
@@ -66,8 +78,8 @@ ZCONST char *cryptnote[] = {
"\tAdministration Regulations (section 740.13(e)) of 6 June 2002."
};
-ZCONST char *swlicense[] = {
-"Copyright (c) 1990-2005 Info-ZIP. All rights reserved.",
+ZCONST char * far swlicense[] = {
+"Copyright (c) 1990-2008 Info-ZIP. All rights reserved.",
"",
"For the purposes of this copyright and license, \"Info-ZIP\" is defined as",
"the following set of individuals:",
@@ -88,36 +100,40 @@ ZCONST char *swlicense[] = {
"",
"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 following restrictions:",
+"freely, subject to the above disclaimer and the following restrictions:",
"",
-" 1. Redistributions of source code must retain the above copyright notice,",
-" definition, disclaimer, and this list of conditions.",
+" 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) 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.",
+" 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, and dynamic,",
-" shared, or static library versions--must be plainly marked as such",
-" and must not be misrepresented as being 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 of the Info-ZIP URL(s).",
+" 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."
};
#endif /* DEFCPYRT */
-#endif /* !WINDLL */
+#endif /* !WINDLL && !IZ_VERSION_SYMBOLS_ONLY */
#endif /* !__revision_h */
diff --git a/tailor.h b/tailor.h
index 38afdcd..272f979 100644
--- a/tailor.h
+++ b/tailor.h
@@ -1,11 +1,41 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ tailor.h - Zip 3
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
+
+/* Some compiler distributions for Win32/i386 systems try to emulate
+ * a Unix (POSIX-compatible) environment.
+ */
+#if (defined(WIN32) && defined(UNIX))
+ /* Zip does not support merging both ports in a single executable. */
+# if (defined(FORCE_WIN32_OVER_UNIX) && defined(FORCE_UNIX_OVER_WIN32))
+ /* conflicting choice requests -> we prefer the Win32 environment */
+# undef FORCE_UNIX_OVER_WIN32
+# endif
+# ifdef FORCE_WIN32_OVER_UNIX
+ /* native Win32 support was explicitely requested... */
+# undef UNIX
+# else
+ /* use the POSIX (Unix) emulation features by default... */
+# undef WIN32
+# endif
+#endif
+
+
+/* UNICODE */
+#ifdef NO_UNICODE_SUPPORT
+# ifdef UNICODE_SUPPORT
+# undef UNICODE_SUPPORT
+# endif
+#endif
+
+
#ifdef AMIGA
#include "amiga/osdep.h"
#endif
@@ -18,14 +48,14 @@
#include "atari/osdep.h"
#endif
-#ifdef __BEOS__
-#include "beos/osdep.h"
-#endif
-
#ifdef __ATHEOS__
#include "atheos/osdep.h"
#endif
+#ifdef __BEOS__
+#include "beos/osdep.h"
+#endif
+
#ifdef DOS
#include "msdos/osdep.h"
#endif
@@ -38,6 +68,10 @@
#include "macos/osdep.h"
#endif
+#ifdef NLM
+#include "novell/osdep.h"
+#endif
+
#ifdef OS2
#include "os2/osdep.h"
#endif
@@ -79,6 +113,53 @@
#include "theos/osdep.h"
#endif
+
+/* generic LARGE_FILE_SUPPORT defines
+ These get used if not defined above.
+ 7/21/2004 EG
+*/
+/* If a port hasn't defined ZOFF_T_FORMAT_SIZE_PREFIX
+ then probably need to define all of these. */
+#ifndef ZOFF_T_FORMAT_SIZE_PREFIX
+
+# ifdef LARGE_FILE_SUPPORT
+ /* Probably passed in from command line instead of in above
+ includes if get here. Assume large file support and hope. 8/14/04 EG */
+
+ /* Set the Large File Summit (LFS) defines to turn on large file support
+ in case it helps. */
+
+# define _LARGEFILE_SOURCE /* some OSes need this for fseeko */
+# define _LARGEFILE64_SOURCE
+# define _FILE_OFFSET_BITS 64 /* select default interface as 64 bit */
+# define _LARGE_FILES /* some OSes need this for 64-bit off_t */
+
+ typedef off_t zoff_t;
+ typedef unsigned long long uzoff_t; /* unsigned zoff_t (12/29/04 EG) */
+
+ /* go with common prefix */
+# define ZOFF_T_FORMAT_SIZE_PREFIX "ll"
+
+# else
+ /* Default type for offsets and file sizes was ulg but reports
+ of using ulg to create files from 2 GB to 4 GB suggest
+ it doesn't work well. Now just switch to Zip64 or not
+ support over 2 GB. 7/24/04 EG */
+ /* Now use uzoff_t for unsigned things. 12/29/04 EG */
+ typedef long zoff_t;
+ typedef unsigned long uzoff_t;
+
+# define ZOFF_T_FORMAT_SIZE_PREFIX "l"
+
+# endif
+
+ typedef struct stat z_stat;
+
+ /* flag that we are defaulting */
+# define USING_DEFAULT_LARGE_FILE_SUPPORT
+#endif
+
+
#if (defined(USE_ZLIB) && defined(ASM_CRC))
# undef ASM_CRC
#endif
@@ -95,8 +176,10 @@
/* Used to remove arguments in function prototypes for non-ANSI C */
#ifndef NO_PROTO
# define OF(a) a
+# define OFT(a) a
#else /* NO_PROTO */
# define OF(a) ()
+# define OFT(a)
#endif /* ?NO_PROTO */
/* If the compiler can't handle const define ZCONST in osdep.h */
@@ -111,6 +194,16 @@
#endif
/*
+ * Some compiler environments may require additional attributes attached
+ * to declarations of runtime libary functions (e.g. to prepare for
+ * linking against a "shared dll" version of the RTL). Here, we provide
+ * the "empty" default for these attributes.
+ */
+#ifndef IZ_IMP
+# define IZ_IMP
+#endif
+
+/*
* case mapping functions. case_map is used to ignore case in comparisons,
* to_up is used to force upper case even on Unix (for dosify option).
*/
@@ -171,28 +264,27 @@
* not supply C runtime library prototypes.
*/
#ifdef NO_PROTO
-char *strcpy();
-char *strcat();
-char *strrchr();
+IZ_IMP char *strcpy();
+IZ_IMP char *strcat();
+IZ_IMP char *strrchr();
/* XXX use !defined(ZMEM) && !defined(__hpux__) ? */
#if !defined(ZMEM) && defined(NO_STRING_H)
-char *memset();
-char *memcpy();
+IZ_IMP char *memset();
+IZ_IMP char *memcpy();
#endif /* !ZMEM && NO_STRING_H */
/* XXX use !defined(__hpux__) ? */
#ifdef NO_STDLIB_H
-char *calloc();
-char *malloc();
-char *getenv();
-long atol();
+IZ_IMP char *calloc();
+IZ_IMP char *malloc();
+IZ_IMP char *getenv();
+IZ_IMP long atol();
#endif /* NO_STDLIB_H */
#ifndef NO_MKTEMP
-char *mktemp();
+IZ_IMP char *mktemp();
#endif /* !NO_MKTEMP */
-/* moved to include mktemp - Cosmin 2/18/05 */
#endif /* NO_PROTO */
/*
@@ -217,6 +309,8 @@ char *mktemp();
#ifdef NO_SIZE_T
typedef unsigned int extent;
+ /* define size_t 3/17/05 EG */
+ typedef unsigned int size_t;
#else
typedef size_t extent;
#endif
@@ -229,6 +323,20 @@ char *mktemp();
* by Yoshioka Tsuneo (QWF00133@nifty.ne.jp,tsuneo-y@is.aist-nara.ac.jp)
* This code is public domain! Date: 1998/12/20
*/
+
+/* 2007-07-29 SMS.
+ * Include <locale.h> here if it will be needed later for Unicode.
+ * Otherwise, SETLOCALE may be defined here, and then defined again
+ * (differently) when <locale.h> is read later.
+ */
+#ifdef UNICODE_SUPPORT
+# if defined( UNIX) || defined( VMS)
+# include <locale.h>
+# endif /* defined( UNIX) || defined( VMS) */
+# include <wchar.h>
+# include <wctype.h>
+#endif /* def UNICODE_SUPPORT */
+
#ifdef _MBCS
# include <locale.h>
@@ -236,13 +344,15 @@ char *mktemp();
extern char *___tmp_ptr;
unsigned char *zmbschr OF((ZCONST unsigned char *, unsigned int));
unsigned char *zmbsrchr OF((ZCONST unsigned char *, unsigned int));
-# define CLEN(ptr) mblen(ptr, MB_CUR_MAX)
+# define CLEN(ptr) mblen((ZCONST char *)ptr, MB_CUR_MAX)
# define PREINCSTR(ptr) (ptr += CLEN(ptr))
# define POSTINCSTR(ptr) (___tmp_ptr=(char *)ptr,ptr += CLEN(ptr),___tmp_ptr)
int lastchar OF((ZCONST char *ptr));
# define MBSCHR(str,c) (char *)zmbschr((ZCONST unsigned char *)(str), c)
# define MBSRCHR(str,c) (char *)zmbsrchr((ZCONST unsigned char *)(str), (c))
-# define SETLOCALE(category, locale) setlocale(category, locale)
+# ifndef SETLOCALE
+# define SETLOCALE(category, locale) setlocale(category, locale)
+# endif /* ndef SETLOCALE */
#else /* !_MBCS */
# define CLEN(ptr) 1
# define PREINCSTR(ptr) (++(ptr))
@@ -250,7 +360,9 @@ char *mktemp();
# define lastchar(ptr) ((*(ptr)=='\0') ? '\0' : ptr[strlen(ptr)-1])
# define MBSCHR(str, c) strchr(str, c)
# define MBSRCHR(str, c) strrchr(str, c)
-# define SETLOCALE(category, locale)
+# ifndef SETLOCALE
+# define SETLOCALE(category, locale)
+# endif /* ndef SETLOCALE */
#endif /* ?_MBCS */
#define INCSTR(ptr) PREINCSTR(ptr)
@@ -269,10 +381,33 @@ typedef struct ztimbuf {
#endif
/* Some systems define S_IFLNK but do not support symbolic links */
-#if defined (S_IFLNK) && defined(NO_SYMLINK)
+#if defined (S_IFLNK) && defined(NO_SYMLINKS)
# undef S_IFLNK
#endif
+#ifndef Z_UINT4_DEFINED
+# if !defined(NO_LIMITS_H)
+# if (defined(UINT_MAX) && (UINT_MAX == 0xffffffffUL))
+ typedef unsigned int z_uint4;
+# define Z_UINT4_DEFINED
+# else
+# if (defined(ULONG_MAX) && (ULONG_MAX == 0xffffffffUL))
+ typedef unsigned long z_uint4;
+# define Z_UINT4_DEFINED
+# else
+# if (defined(USHRT_MAX) && (USHRT_MAX == 0xffffffffUL))
+ typedef unsigned short z_uint4;
+# define Z_UINT4_DEFINED
+# endif
+# endif
+# endif
+# endif /* !defined(NO_LIMITS_H) */
+#endif /* ndef Z_UINT4_DEFINED */
+#ifndef Z_UINT4_DEFINED
+ typedef ulg z_uint4;
+# define Z_UINT4_DEFINED
+#endif
+
#ifndef FOPR /* fallback default definitions for FOPR, FOPM, FOPW: */
# define FOPR "r"
# define FOPM "r+"
@@ -368,17 +503,288 @@ typedef struct ztimbuf {
# define DYN_ALLOC
#endif
-#ifndef SSTAT
-# define SSTAT stat
+
+/* LARGE_FILE_SUPPORT
+ *
+ * Types are in osdep.h for each port
+ *
+ * LARGE_FILE_SUPPORT and ZIP64_SUPPORT are automatically
+ * set in osdep.h (for some ports) based on the port and compiler.
+ *
+ * Function prototypes are below as OF is defined earlier in this file
+ * but after osdep.h is included. In the future ANSI prototype
+ * support may be required and the OF define may then go away allowing
+ * the function defines to be in the port osdep.h.
+ *
+ * E. Gordon 9/21/2003
+ * Updated 7/24/04 EG
+ */
+#ifdef LARGE_FILE_SUPPORT
+ /* 64-bit Large File Support */
+
+ /* Arguments for all functions are assumed to match the actual
+ arguments of the various port calls. As such only the
+ function names are mapped below. */
+
+/* ---------------------------- */
+# ifdef UNIX
+
+ /* Assume 64-bit file environment is defined. The below should all
+ be set to their 64-bit versions automatically. Neat. 7/20/2004 EG */
+
+ /* 64-bit stat functions */
+# define zstat stat
+# define zfstat fstat
+# define zlstat lstat
+
+# if defined(__alpha) && defined(__osf__) /* support for osf4.0f */
+ /* 64-bit fseek */
+# define zfseeko fseek
+
+ /* 64-bit ftell */
+# define zftello ftell
+
+# else
+ /* 64-bit fseeko */
+# define zfseeko fseeko
+
+ /* 64-bit ftello */
+# define zftello ftello
+# endif /* __alpha && __osf__ */
+
+ /* 64-bit fopen */
+# define zfopen fopen
+# define zfdopen fdopen
+
+# endif /* UNIX */
+
+/* ---------------------------- */
+# ifdef VMS
+
+ /* 64-bit stat functions */
+# define zstat stat
+# define zfstat fstat
+# define zlstat lstat
+
+ /* 64-bit fseeko */
+# define zfseeko fseeko
+
+ /* 64-bit ftello */
+# define zftello ftello
+
+ /* 64-bit fopen */
+# define zfopen fopen
+# define zfdopen fdopen
+
+# endif /* def VMS */
+
+/* ---------------------------- */
+# ifdef WIN32
+
+# if defined(__MINGW32__)
+ /* GNU C, linked against "msvcrt.dll" */
+
+ /* 64-bit stat functions */
+# define zstat _stati64
+# ifdef UNICODE_SUPPORT
+# define zwfstat _fstati64
+# define zwstat _wstati64
+# define zw_stat struct _stati64
+# endif
+# define zfstat _fstati64
+# define zlstat lstat
+
+ /* 64-bit fseeko */
+ /* function in win32.c */
+ int zfseeko OF((FILE *, zoff_t, int));
+
+ /* 64-bit ftello */
+ /* function in win32.c */
+ zoff_t zftello OF((FILE *));
+
+ /* 64-bit fopen */
+# define zfopen fopen
+# define zfdopen fdopen
+
+# endif
+
+# if defined(__CYGWIN__)
+ /* GNU C, CygWin with its own POSIX compatible runtime library */
+
+ /* 64-bit stat functions */
+# define zstat stat
+# define zfstat fstat
+# define zlstat lstat
+
+ /* 64-bit fseeko */
+# define zfseeko fseeko
+
+ /* 64-bit ftello */
+# define zftello ftello
+
+ /* 64-bit fopen */
+# define zfopen fopen
+# define zfdopen fdopen
+
+# endif
+
+# ifdef __WATCOMC__
+ /* WATCOM C */
+
+ /* 64-bit stat functions */
+# define zstat _stati64
+# ifdef UNICODE_SUPPORT
+# define zwfstat _fstati64
+# define zwstat _wstati64
+# define zw_stat struct _stati64
+# endif
+# define zfstat _fstati64
+# define zlstat lstat
+
+ /* 64-bit fseeko */
+ /* function in win32.c */
+ int zfseeko OF((FILE *, zoff_t, int));
+
+ /* 64-bit ftello */
+ /* function in win32.c */
+ zoff_t zftello OF((FILE *));
+
+ /* 64-bit fopen */
+# define zfopen fopen
+# define zfdopen fdopen
+
+# endif
+
+# ifdef _MSC_VER
+ /* MS C and VC */
+
+ /* 64-bit stat functions */
+# define zstat _stati64
+# ifdef UNICODE_SUPPORT
+# define zwfstat _fstati64
+# define zwstat _wstati64
+# define zw_stat struct _stati64
+# endif
+# define zfstat _fstati64
+# define zlstat lstat
+
+ /* 64-bit fseeko */
+ /* function in win32.c */
+ int zfseeko OF((FILE *, zoff_t, int));
+
+ /* 64-bit ftello */
+ /* function in win32.c */
+ zoff_t zftello OF((FILE *));
+
+ /* 64-bit fopen */
+# define zfopen fopen
+# define zfdopen fdopen
+
+# endif
+
+# ifdef __IBMC__
+ /* IBM C */
+
+ /* 64-bit stat functions */
+
+ /* 64-bit fseeko */
+ /* function in win32.c */
+ int zfseeko OF((FILE *, zoff_t, int));
+
+ /* 64-bit ftello */
+ /* function in win32.c */
+ zoff_t zftello OF((FILE *));
+
+ /* 64-bit fopen */
+
+# endif
+
+# endif /* WIN32 */
+
+#else
+ /* No Large File Support or default for 64-bit environment */
+
+# define zstat stat
+# define zfstat fstat
+# define zlstat lstat
+# define zfseeko fseek
+# define zftello ftell
+# define zfopen fopen
+# define zfdopen fdopen
+# ifdef UNICODE_SUPPORT
+# define zwfstat _fstat
+# define zwstat _wstat
+# define zw_stat struct _stat
+# endif
+
#endif
-#ifdef S_IFLNK
+
+#ifdef LARGE_FILE_SUPPORT /* E. Gordon 9/12/2003 */
+
+# ifndef SSTAT
+# define SSTAT zstat
+# ifdef UNICODE_SUPPORT
+# define SSTATW zwstat
+# endif
+# endif
+# ifdef S_IFLNK
+# define LSTAT zlstat
+# define LSSTAT(n, s) (linkput ? zlstat((n), (s)) : SSTAT((n), (s)))
+# else
+# define LSTAT SSTAT
+# define LSSTAT SSTAT
+# ifdef UNICODE_SUPPORT
+# define LSSTATW SSTATW
+# endif
+# endif
+
+#else /* no LARGE_FILE_SUPPORT */
+
+# ifndef SSTAT
+# define SSTAT stat
+# endif
+# ifdef S_IFLNK
# define LSTAT lstat
# define LSSTAT(n, s) (linkput ? lstat((n), (s)) : SSTAT((n), (s)))
-#else
+# else
# define LSTAT SSTAT
# define LSSTAT SSTAT
+# ifdef UNICODE_SUPPORT
+# define LSSTATW SSTATW
+# endif
+# endif
+
#endif
+
+/*---------------------------------------------------------------------*/
+
+
+/* 2004-12-01 SMS.
+ * Added fancy zofft() macros, et c.
+ */
+
+/* Default fzofft() format selection.
+ * Modified 2004-12-27 EG
+ */
+
+#ifndef FZOFFT_FMT
+# define FZOFFT_FMT ZOFF_T_FORMAT_SIZE_PREFIX /* printf for zoff_t values */
+
+# ifdef LARGE_FILE_SUPPORT
+# define FZOFFT_HEX_WID_VALUE "16" /* width of 64-bit hex values */
+# else
+# define FZOFFT_HEX_WID_VALUE "8" /* digits in 32-bit hex values */
+# endif
+
+#endif /* ndef FZOFFT_FMT */
+
+#define FZOFFT_HEX_WID ((char *) -1)
+#define FZOFFT_HEX_DOT_WID ((char *) -2)
+
+
+
+
/* The following default definition of the second input for the crypthead()
* random seed computation can be used on most systems (all those that
* supply a UNIX compatible getpid() function).
@@ -438,6 +844,7 @@ typedef struct ztimbuf {
#ifdef THEOS
# define OS_CODE 0x1200
#endif
+/* Yes, there is a gap here. */
#ifdef __ATHEOS__
# define OS_CODE 0x1E00
#endif
diff --git a/tandem/HISTORY b/tandem/HISTORY
index fc74776..59d3429 100644
--- a/tandem/HISTORY
+++ b/tandem/HISTORY
@@ -91,7 +91,7 @@ To Do UNZIP
Current Versions on Website
===========================
-ZIP 2.2
-UNZIP 5.32
+ZIP 2.3
+UNZIP 5.5
-As of December 21 1998
+As of February 17th 2002
diff --git a/tandem/README b/tandem/README
index 54dd357..f877aeb 100644
--- a/tandem/README
+++ b/tandem/README
@@ -46,6 +46,7 @@ History:
Assume not DST if can't resolve time (no DST table available)
27/09/99 2.3o Fixed bug in -B0 option causing files to be stored rather than
deflated. Created TANZIPH
+29/04/02 2.4g Fixed contention on temporary file when multiple ZIPs run
A few notes about the files on this subvol
diff --git a/tandem/commacs b/tandem/commacs
index 1acb068..31e91a1 100644
--- a/tandem/commacs
+++ b/tandem/commacs
@@ -1,26 +1,32 @@
?section CC ROUTINE
#FRAME
-[#PUSH stem src obj htime file prev time stime otime
+[#PUSH file stem src obj htime file prev time stime otime
comp out options sup buf col locn group
]
-[#IF [#ARGUMENT /VALUE src/ WORD /SPACE/ END]]
-[#IF [#EMPTYV src] |THEN|
+[#IF [#ARGUMENT /VALUE file/ WORD /SPACE/ END]]
+[#IF [#EMPTYV file] |THEN|
#OUTPUT Syntax: CC <file> <collector> <comp-options>
#RESET FRAMES
#RETURN
]
-[#IF NOT [#FILEINFO /EXISTENCE/ [src]]
+[#IF NOT [#FILEINFO /EXISTENCE/ [file]]
|THEN|
- #OUTPUT [src] does not exist !
+ #OUTPUT [file] does not exist !
#RESET FRAMES
#RETURN
]
-#SETV stem src
+#PUSH #DEFAULTS vol subvol
+#SETMANY vol subvol src, [#FILEINFO /VOLUME, SUBVOL, FILE/ [file]]
+VOLUME [vol].[subvol]
+
+#SETV stem file
#CHARDEL stem [#CHARCOUNT stem]
#SET obj [stem]O
+#SETV stem src
+#CHARDEL stem [#CHARCOUNT stem]
[#IF [#ARGUMENT /VALUE out/ DEVICE END]]
[#IF [#EMPTYV out] |THEN| #SET out $T.#C]
@@ -29,7 +35,6 @@
#SET locn [group].[stem]
#SET sup [#LOOKUPPROCESS /ANCESTOR/ [col]]
-
#SET options [#REST]
== Find newest Header file
@@ -64,7 +69,7 @@
[#IF comp
|THEN|
SPOOLCOM /OUTV buf/ OPEN [sup];JOB (OWNER, LOC [locn]),STATUS,DELETE !
- #OUTPUTV buf
+ #SET buf
#OUTPUT Compiling [src]... [options]
C /IN [src], OUT [out].[stem]/[obj];SYMBOLS,HIGHPIN [options]
[#CASE [tacl^completioncode]
@@ -74,8 +79,12 @@
#SET _completion:completioncode 0
| 1 |
#OUTPUT [src]: Compile Warnings
+ SPOOLCOM /OUTV buf/ OPEN [sup];JOB (OWNER, LOC [locn]),STATUS
+ #OUTPUTV buf
|OTHERWISE|
#OUTPUT [src]: Compile FAILED !
+ SPOOLCOM /OUTV buf/ OPEN [sup];JOB (OWNER, LOC [locn]),STATUS
+ #OUTPUTV buf
]
|ELSE|
#OUTPUT Object file [obj] is up to date
diff --git a/tandem/DOIT b/tandem/doit
index 901f879..1388730 100644
--- a/tandem/DOIT
+++ b/tandem/doit
@@ -1,12 +1,12 @@
?tacl macro
#frame
#push zipfile
-#SET zipfile ZIP23
+#SET zipfile [#FILEINFO /SUBVOL/ A]
unzip -a [zipfile] *.c -x */*
== Following not required
-RENAME apic apicz
-RENAME mktimec mktimecz == use Tandem mktime()
+RENAME apic apicz
+RENAME timezonc timezonz
unzip -a [zipfile] *.h -x */*
== Following not required
diff --git a/tandem/macros b/tandem/macros
index 5db5a7d..ab1505b 100644
--- a/tandem/macros
+++ b/tandem/macros
@@ -12,7 +12,6 @@
#OUTPUT Building [lib]
#APPEND bin CLEAR
add^list CRC32O
-add^list CRCTABO
add^list CRYPTO
add^list DEFLATEO
add^list FILEIOO
@@ -135,7 +134,6 @@ add^list ZIPUPO
#OUTPUT Building [lib]
#APPEND bin CLEAR
add^list CRC32O
-add^list CRCTABO
add^list CRYPTO
add^list ENVARGSO
add^list EXPLODEO
@@ -219,16 +217,15 @@ add^list ZIPINFOO
#OUTPUT Building [lib]
#APPEND bin CLEAR
add^list CRC32O
-add^list CRCTABO
add^list EXTRACTX
-add^list FILEIOO
-add^list GLOBALSO
-add^list INFLATEO
-add^list MATCHO
+add^list FILEIOX
+add^list GLOBALSX
+add^list INFLATEX
+add^list MATCHX
add^list PROCESSX
-add^list TANDEMO
+add^list TANDEMX
add^list TANUNZX
-add^list TTYIOO
+add^list TTYIOX
#APPEND bin INFO UNRESOLVED *
#APPEND bin BUILD [lib] ! , LIST * OFF
@@ -297,7 +294,7 @@ add^list TTYIOO
|THEN|
#OUTPUT %2% is older than %1%
#OUTPUT Accelerating %1% to %2%
- AXCEL /IN [general_seg_subvol].DUMMY, OUTV buf/ %1%,%2%
+ AXCEL /OUTV buf/ %1%,%2%
#OUTPUTV buf
[#CASE [tacl^completioncode]
| 0 | #OUTPUT Accelerated %2% OK
@@ -342,3 +339,233 @@ add^list TTYIOO
]
#UNFRAME
+
+
+?section CODE routine
+#FRAME
+#PUSH delta arg
+
+#SET /TYPE delta/ DELTA
+
+[#LOOP |WHILE| [#COMPUTE [#ARGUMENT /VALUE arg/ NUMBER END] = 1 ]
+|DO|
+ #APPEND DELTA [arg]I
+]
+
+#RESULT [#DELTA /COMMANDS DELTA/]
+
+#UNFRAME
+
+
+?section TACL^COMPLETIONCODE routine
+#RESULT [_completion:completioncode]
+
+?SECTION INCREMENT routine
+#FRAME
+#PUSH increment_variable increment_value
+
+[#IF [#ARGUMENT /VALUE increment_variable/ VARIABLE]]
+[#IF [#EMPTYV [increment_variable]]|THEN|#SET [increment_variable] 0]
+[#IF [#MORE]
+ |THEN|
+ [#IF [#ARGUMENT /VALUE increment_value/ NUMBER]]
+ |ELSE|
+ #SET increment_value 1
+]
+[#IF [#ARGUMENT END]]
+
+#SET [increment_variable] [#COMPUTE [increment_variable] + [increment_value]]
+
+#UNFRAME
+
+?section ERROR^IN^FUP^OUTPUT routine
+#FRAME
+#PUSH err output last line type
+
+#SETMANY err output, 0 0
+
+[#LOOP |WHILE| NOT [#EMPTYV fup^out]
+|DO|
+ #EXTRACTV fup^out line
+ [#SETMANY type, [#CHARGET line 1 TO 7] .]
+ [#CASE [type]
+ | ERROR | #SETMANY output err, -1 -1
+ | WARNING | #SET output -1
+ | OTHERWISE |
+ ]
+ [#IF output |THEN|
+ #OUTPUTV last
+ #OUTPUTV line
+ #SET output 0
+ #EXTRACTV fup^out line
+ ]
+ #SETV last line
+]
+
+#RESULT [err]
+
+#UNFRAME
+
+?section SECURE^FILE routine
+#FRAME
+
+[#DEF fup^out TEXT |BODY|]
+[#DEF fup^buf TEXT |BODY|]
+
+[#DEF fup^cmd MACRO |BODY|
+ FUP /OUTV fup^out/ %*%
+ #SETV fup^buf fup^out
+ [#IF [error^in^fup^output]
+ |THEN|
+ #OUTPUT Error detected in FUP output, ABORTING !!
+ #OUTPUT ..............................................................
+ #OUTPUTV fup^buf
+ #OUTPUT ..............................................................
+ #RAISE _BREAK
+ ]
+]
+
+[#DEF display^action MACRO |BODY|
+ [#IF NOT action |THEN|
+ #OUTPUT /HOLD/ Updating [file] ...
+ #SET action -1
+ #SET count 0
+ ]
+ #OUTPUT /COLUMN 3/ ... %*%
+]
+
+[#DEF display^noaction MACRO |BODY|
+ [#IF count
+ |THEN|
+ increment count
+ |ELSE|
+ #OUTPUT
+ #SET count 1
+ ]
+ [#IF count |THEN|
+ #OUTPUT /COLUMN [count]/ [code 27]A.
+ [#IF count > 75
+ |THEN|
+ #SET count 0
+ ]
+ ]
+]
+
+[#DEF process^file TEXT |BODY|
+ #SET action 0
+ #SETMANY cur^owner cur^security cur^license cur^progid, &
+ [#FILEINFO /OWNER, SECURITY, LICENSED, PROGID/ [file]]
+
+ #SET cur^owner [#USERNAME [cur^owner]]
+
+ [#IF NOT [#EMPTYV owner]
+ |THEN|
+ [#IF owner '<>' cur^owner
+ |THEN|
+ display^action giving to [owner] (was [cur^owner])
+ fup^cmd GIVE [file], [owner]
+ [#IF cur^progid
+ |THEN|
+ #OUTPUT /COLUMN 3/... WARNING! Loss of PROGID flag
+ #SET cur^progid 0
+ ]
+ ]
+ ]
+ [#IF NOT [#EMPTYV security]
+ |THEN|
+ [#IF security '<>' cur^security
+ |THEN|
+ display^action securing to [security] (was [cur^security])
+ fup^cmd SECURE [file], [security]
+ ]
+ ]
+ [#IF license |THEN|
+ [#IF NOT cur^license
+ |THEN|
+ display^action licensed
+ fup^cmd LICENSE [file]
+ ]
+ ]
+ [#IF progid |THEN|
+ [#IF NOT cur^progid
+ |THEN|
+ display^action PROGID flag set
+ fup^cmd SECURE [file],, PROGID
+ ]
+ ]
+ [#IF action
+ |THEN|
+ fup^cmd INFO [file]
+ |ELSE|
+ [#IF tflag
+ |THEN|
+ display^noaction
+ |ELSE|
+ #OUTPUT /HOLD/ Unchanged : [file]
+ [#IF cur^progid |THEN| #OUTPUT /COLUMN 39,HOLD/ P]
+ [#IF cur^license |THEN| #OUTPUT /COLUMN 40,HOLD/ L]
+ #OUTPUTV /COLUMN 43,HOLD/ cur^security
+ #OUTPUTV /COLUMN 50,HOLD/ cur^owner
+ #OUTPUT
+ ]
+ ]
+]
+
+#PUSH arg template file security owner progid license prev action count tflag
+#PUSH cur^security cur^owner cur^license cur^progid
+
+#SETMANY license progid, 0 0
+#SET count 0
+#SET tflag 0
+
+[#LOOP |WHILE| [#MORE]
+|DO|
+ [#CASE [#ARGUMENT /VALUE arg/ FILENAME
+ USER /USERNAME/
+ USER
+ SECURITY
+ KEYWORD /WORDLIST LICENSE/
+ KEYWORD /WORDLIST PROGID/
+ TEMPLATE
+ ]
+ | 1 | #SETV file arg
+ | 2 | #SETV owner arg
+ | 3 | #SET owner [#USERNAME [arg]]
+ | 4 | #SETV security arg
+ | 5 | #SET license -1
+ | 6 | #SET progid -1
+ | 7 | #SETV template arg
+ ]
+]
+[#IF [#ARGUMENT END]]
+
+
+[#IF [#EMPTYV template]
+|THEN|
+ #SETV template file
+|ELSE|
+ #SET tflag -1
+ #OUTPUT /HOLD/ Template : [template]
+ [#IF progid |THEN| #OUTPUT /COLUMN 39,HOLD/ P]
+ [#IF license |THEN| #OUTPUT /COLUMN 40,HOLD/ L]
+ [#IF NOT [#EMPTYV security] |THEN| #OUTPUTV /HOLD/ " "[security]""]
+ [#IF NOT [#EMPTYV owner] |THEN| #OUTPUTV /HOLD/ " [owner]"]
+ #OUTPUT
+]
+
+[#IF [#EMPTYV template]
+|THEN|
+ #OUTPUT ERROR! No filename specified
+ #RESET FRAMES
+ #RETURN
+|ELSE|
+ #SET file [#FILENAMES /MAXIMUM 1/ [template]]
+ [#LOOP |WHILE| NOT [#EMPTYV file]
+ |DO|
+ process^file
+ #SETV prev file
+ #SET file [#FILENAMES /MAXIMUM 1, PREVIOUS [prev]/ [template]]
+ ]
+]
+
+#UNFRAME
diff --git a/tandem/make b/tandem/make
index f8a78ce..84efb4d 100644
--- a/tandem/make
+++ b/tandem/make
@@ -1,21 +1,30 @@
?tacl routine
#FRAME
-load /keep 1/ commacs
+SINK [#LOAD /keep 1/ commacs]
+SINK [#LOAD /keep 1/ macros]
-#PUSH file prev memory OK model zip lib accel unlicensed licensed options
+[#PUSH file prev memory clib OK model zip lib accel unlicensed licensed
+ options fileset nocrypt crypt
+]
#PUSH #DEFAULTS
-load /keep 1/ macros
#SET OK -1
[#IF [#ARGUMENT /VALUE memory/ KEYWORD /WORDLIST LARGE SMALL/ OTHERWISE ]]
[#IF [#ARGUMENT /VALUE model/ KEYWORD /WORDLIST NOWIDE WIDE/ OTHERWISE ]]
[#IF [#ARGUMENT /VALUE unlicensed/ KEYWORD /WORDLIST UNLICENSED/ OTHERWISE ]]
+[#IF [#ARGUMENT /VALUE nocrypt/ KEYWORD /WORDLIST NOCRYPT/ OTHERWISE ]]
+[#IF [#ARGUMENT /VALUE fileset/ TEMPLATE FILENAME OTHERWISE ]]
[#IF [#EMPTYV memory] |THEN| #SET memory LARGE]
[#IF [#EMPTYV model] |THEN| #SET model NOWIDE]
[#IF model '=' "WIDE"
+ |THEN| #SETV clib model
+ |ELSE| #SETV clib memory
+]
+
+[#IF model '=' "WIDE"
|THEN|
#SET zip ZIPW
|ELSE|
@@ -35,21 +44,32 @@ load /keep 1/ macros
#SET options [options], define [licensed]
]
+[#IF nocrypt '=' "NOCRYPT"
+|THEN|
+|ELSE|
+ #SET crypt USE_CRYPT
+ #SET options [options], define [crypt]
+]
+
+[#IF [#EMPTYV fileset] |THEN| #SET fileset *C]
+
+#OUTPUT Files to compile: [fileset]
#OUTPUT Pointer Model : [model]
#OUTPUT Memory Model : [memory]
+#OUTPUT C Library : [clib]
#OUTPUT Axcel Object : [accel]
#OUTPUT Run Object : [zip]
#OUTPUT Library Object : [lib]
#OUTPUT Compile Options : [options]
#OUTPUT
-#SET file [#FILENAMES /MAXIMUM 1/ *C]
+#SET file [#FILENAMES /MAXIMUM 1/ [fileset]]
[#loop |while| NOT [#EMPTYV file]
|do|
#SETV prev file
CC [file] $T.#ZIP [options]
[#IF [tacl^completioncode] > 1 |THEN| #set OK 0 ]
- #SET file [#FILENAMES /MAXIMUM 1, PREVIOUS [prev]/ *C]
+ #SET file [#FILENAMES /MAXIMUM 1, PREVIOUS [prev]/ [fileset]]
]
[#IF OK |THEN|
@@ -61,7 +81,7 @@ load /keep 1/ macros
VOLUME ,"NUNU"
[#IF OK |THEN|
- BBZIP [zip] [memory]
+ BBZIP [zip] [clib]
[#IF [tacl^completioncode] > 0 |THEN| #SET OK 0]
]
@@ -98,7 +118,7 @@ CC ZIPNOTEC $T.#ZIP [options]
#SET zip ZIPNOTE
#SET accel ZIPNOTE
[#IF OK |THEN|
- BBANY [zip] [memory]
+ BBANY [zip] [clib]
[#IF [tacl^completioncode] > 0 |THEN| #SET OK 0]
]
[#IF OK |THEN|
diff --git a/tandem/tandem.c b/tandem/tandem.c
index 291b9a0..0aa1e06 100644
--- a/tandem/tandem.c
+++ b/tandem/tandem.c
@@ -1,9 +1,9 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*
@@ -17,6 +17,8 @@
#include <cextdecs> nolist
#include "tannsk.h"
+static time_t gmt_to_time_t (long long *);
+
int isatty (fnum)
int fnum;
{
@@ -27,19 +29,30 @@ int fnum;
/* Function in2ex() */
/********************/
+#ifdef UNZIP
+char *in2ex(__G__ n)
+ __GDEF
+#else
char *in2ex(n)
+#endif
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; /* pointer to internal */
- char *p; /* pointer to internal */
- char *e; /* pointer to internal */
+ char *x; /* external file name buffer */
+ char *y; /* pointer to external buffer */
+ char *max; /* pointer to max end of next file part */
+ char *t; /* pointer to internal - start of substring */
+ char *p; /* pointer to internal - TANDEM delimiter */
+ char *e; /* pointer to internal - DOS extension delimiter */
+ char *z; /* pointer to internal - end of substring */
+ int len; /* length of substring to copy to external name */
+ int allow_dollar; /* $ symbol allowed as next character */
if ((x = malloc(strlen(n) + 4)) == NULL) /* + 4 for safety */
return NULL;
- *x= '\0';
+
+ *x = '\0';
/* Junk pathname as requested */
#ifdef UNZIP
@@ -55,6 +68,8 @@ char *in2ex(n)
t = n;
#endif /* ZIP */
+ allow_dollar = TRUE;
+
while (*t != '\0') { /* File part could be sys, vol, subvol or file */
if (*t == INTERNAL_DELIMITER) { /* System, Volume or Subvol Name */
t++;
@@ -62,27 +77,74 @@ char *in2ex(n)
strcat(x, TANDEM_NODE_STR);
t++;
}
- else
+ else {
strcat(x, TANDEM_DELIMITER_STR);
+ allow_dollar = FALSE;
+ }
}
+ /* Work out where end of current external string is */
+ y = x + strlen(x);
+
+ /* Work out substring to copy and externalise */
p = strchr(t, INTERNAL_DELIMITER);
- if (p == NULL)
- break;
- if ((e = strchr(t, DOS_EXTENSION)) == NULL)
- e = p;
- else
- e = _min(e, p);
+ e = strchr(t, DOS_EXTENSION);
+ if (p != NULL) {
+ if (e > p)
+ e = NULL;
+ }
+
+ z = e;
+ if (z == NULL)
+ z = p;
+ if (z == NULL)
+ z = t + strlen(t);
+
/* can't have Tandem name longer than 8 characters */
- strncat(x, t, _min(MAXFILEPARTLEN, (e - t)));
+ max = y + MAXFILEPARTLEN;
+
+ /* Allow $ symbol as first character in some cases */
+ if (*t == '$') {
+ if (allow_dollar)
+ *y++ = *t++;
+ else;
+ *t++;
+ }
+
+ /* Make sure first real character is alpha */
+ if (! isalpha(*t) )
+ *y++ = 'A';
+
+ /* Characters left to process */
+ len = z - t;
+
+ while ( len > 0 ) {
+ if ( isalnum(*t) ) {
+ *y++ = toupper(*t++);
+ if (y >= max)
+ break;
+ }
+ else
+ t++;
+ len--;
+ }
+ *y = '\0';
t = p;
- }
- if ((e = strchr(t, DOS_EXTENSION)) == NULL)
- strncat(x, t, _min(MAXFILEPARTLEN, strlen(t)));
- else {
- strncat(x, t, _min(MAXFILEPARTLEN, (e - t)));
- strcat(x, TANDEM_EXTENSION_STR);
- strcat(x, e+1); /* no restriction on extension length as its virtual*/
+ if (p == NULL) {
+ /* Last part of filename, store pseudo extension if available */
+ if (e != NULL) {
+ strcat(x, TANDEM_EXTENSION_STR);
+ y = x + strlen(x);
+
+ /* no restriction on extension length as its virtual */
+ z = e + 1;
+ while ( *z != '\0' ) {
+ *y++ = toupper(*z++);
+ }
+ *y = '\0';
+ }
+ break;
+ }
}
return x;
@@ -91,50 +153,13 @@ char *in2ex(n)
void zexit(status)
int status;
{
- terminate_program (0,0,status,,,); /* Exit(>0) creates saveabend files */
+ /* Exit(>0) creates saveabend files */
+ terminate_program (0,0,(short)status,,,);
}
-
-#ifdef fopen
-# undef fopen
-#endif
-
-FILE *zipopen(fname, opt)
-const char *fname;
-const char *opt;
-{
- int fdesc,fnum,err;
-
-#ifdef ZIP
- #define alist_items 1
- #define vlist_bytes 2
- short alist[alist_items]={42};
- unsigned short vlist[alist_items]={NSK_ZIPFILECODE};
- short extra, *err_item=&extra;
-#endif /* ZIP */
-
- if (strcmp(opt,FOPW) == 0)
- if ((fdesc = creat(fname,,100,500)) != -1){
- fnum = fdtogfn (fdesc);
- err = (SETMODE (fnum, SET_FILE_BUFFERSIZE, TANDEM_BLOCKSIZE) != CCE);
- err = (SETMODE (fnum, SET_FILE_BUFFERED, 0, 0) != CCE);
- err = (SETMODE (fnum, SET_FILE_BUFFERED, 0, 1) != CCE);
- err = close(fdesc);
-#ifdef ZIP
- err = FILE_ALTERLIST_((char *)fname,
- (short)(strlen(fname)),
- alist,
- alist_items,
- vlist,
- vlist_bytes,
- ,
- err_item);
-#endif /* ZIP */
- };
-
- return fopen(fname,opt);
-}
-#define fopen zipopen
+/************************/
+/* Function zputc() */
+/************************/
#ifdef putc
# undef putc
@@ -385,11 +410,10 @@ int chown(file, uid, gid)
int zgetch(void)
{
char ch;
- int f,fnum,count, rlen,wlen, err;
+ short f, err, count, fnum, rlen;
rlen = 1;
- wlen = 0;
- f = fileno(stdin);
+ f = (short)fileno(stdin);
fnum = fdtogfn (f);
#define ECHO_MODE 20
err = (SETMODE(fnum, ECHO_MODE, 0) != CCE);
@@ -408,9 +432,42 @@ int zgetch(void)
return (int)ch;
}
-/* TANDEM version of stat() function */
+short parsename(srce, fname, ext)
+ const char *srce;
+ char *fname;
+ char *ext;
+{
+ /* As a way of supporting DOS extensions from Tandem we look for a space
+ separated extension string after the Guardian filename
+ e.g. ZIP ZIPFILE "$DATA4.TESTING.INVOICE TXT"
+ */
-time_t gmt_to_time_t (gmt)
+ char *fstart;
+ char *fptr;
+ short extension = 0;
+
+ *fname = *ext = '\0'; /* set to null string */
+
+ fstart = (char *) srce;
+
+ if ((fptr = strrchr(fstart, TANDEM_EXTENSION)) != NULL) {
+ extension = 1;
+
+ fptr++;
+ strncat(ext, fptr, _min(EXTENSION_MAX, strlen(fptr)));
+
+ fptr = strchr(fstart, TANDEM_EXTENSION); /* End of filename */
+ strncat(fname, fstart, _min(FILENAME_MAX, (fptr - fstart)));
+ }
+ else {
+ /* just copy string */
+ strncat(fname, srce, _min(FILENAME_MAX, strlen(srce)));
+ }
+
+ return extension;
+}
+
+static time_t gmt_to_time_t (gmt)
long long *gmt;
{
#define GMT_TO_LCT 0
@@ -447,41 +504,7 @@ time_t gmt_to_time_t (gmt)
return (mktime(&temp_tm));
}
-short parsename(srce, fname, ext)
- const char *srce;
- char *fname;
- char *ext;
-{
- /* As a way of supporting DOS extensions from Tandem we look for a space
- separated extension string after the Guardian filename
- e.g. ZIP ZIPFILE "$DATA4.TESTING.INVOICE TXT"
- */
-
- char *fstart;
- char *fptr;
- short extension = 0;
-
- *fname = *ext = '\0'; /* set to null string */
-
- fstart = (char *) srce;
-
- if ((fptr = strrchr(fstart, TANDEM_EXTENSION)) != NULL) {
- extension = 1;
-
- fptr++;
- strncat(ext, fptr, _min(EXTENSION_MAX, strlen(fptr)));
-
- fptr = strchr(fstart, TANDEM_EXTENSION); /* End of filename */
- strncat(fname, fstart, _min(FILENAME_MAX, (fptr - fstart)));
- }
- else {
- /* just copy string */
- strncat(fname, srce, _min(FILENAME_MAX, strlen(srce)));
- }
-
- return extension;
-}
-
+/* TANDEM version of stat() function */
int stat(n, s)
const char *n;
struct stat *s;
@@ -547,7 +570,7 @@ int stat(n, s)
s->st_reserved[1] = 0;
s->st_reserved[2] = 0;
nsk_ov = (nsk_stat_ov *)&s->st_reserved[0];
- nsk_attr = (nsk_file_attrs *)&nsk_ov->ov.nsk_ef_start;
+ nsk_attr = (nsk_file_attrs *)&nsk_ov->ov.nsk_ef_region;
/* Check to see if name contains a (pseudo) file extension */
extension = parsename (n,fname,ext);
@@ -654,7 +677,7 @@ int stat(n, s)
nsk_attr->filetype = (unsigned) flist[ioff[7]];
nsk_attr->filecode = (unsigned) flist[ioff[8]];
nsk_attr->block = (unsigned short) flist[ioff[9]];
- nsk_attr->primext = (unsigned short) flist[ioff[10]];
+ nsk_attr->priext = (unsigned short) flist[ioff[10]];
nsk_attr->secext = (unsigned short) flist[ioff[11]];
nsk_attr->maxext = (unsigned short) flist[ioff[12]];
nsk_attr->flags.clearonpurge = (unsigned) flist[ioff[13]];
@@ -731,7 +754,7 @@ int stat(n, s)
koff[0] = 0;
/* Build up table of offets into result list */
- for (i=1; i < slist_items; i++)
+ for (i=1; i < klist_items; i++)
koff[i] = koff[i-1] + klen[i-1];
nsk_attr->keyoff = (unsigned) flist[koff[0]];
diff --git a/tandem/tandem.h b/tandem/tandem.h
index 7868fdd..7296d26 100644
--- a/tandem/tandem.h
+++ b/tandem/tandem.h
@@ -1,25 +1,32 @@
/*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2006 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 1999-Oct-05 or later
+ 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, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+ 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 __tandem_h /* prevent multiple inclusions */
#define __tandem_h
-#define TANDEM /* better than __TANDEM */
+#ifndef TANDEM
+# define TANDEM /* better than __TANDEM */
+#endif
/* LICENSED define now supplied by compile time option (MAKE) */
#define NO_UNISTD_H
#define NO_RMDIR
#define NO_MKTEMP
-#ifdef ZIP
-# define USE_CASE_MAP
+
+/* TANDEM supplies proper UTC vs. local time conversion, so enable Info-ZIP's
+ UT e.f. support unless explicitly suppressed by a compilation option. */
+#if (!defined(USE_EF_UT_TIME) && !defined(NO_EF_UT_TIME))
# define USE_EF_UT_TIME
-#endif /* ZIP */
+#endif
+#if (defined(NO_EF_UT_TIME) && defined(USE_EF_UT_TIME))
+# undef USE_EF_UT_TIME
+#endif
/* Include file for TANDEM */
@@ -32,6 +39,7 @@
#include <sysstat.h>
#include <unistd.h>
#include <errno.h>
+#include <ctype.h>
#define PASSWD_FROM_STDIN
/* Kludge until we know how to open a non-echo tty channel */
@@ -54,39 +62,9 @@
#define EXTENSION_MAX 3
/* FILENAME_MAX is defined in stdio.h */
-#define EXIT zexit /* To stop creation of Abend files */
-#define RETURN zexit /* To stop creation of Abend files */
-#define fopen zipopen /* To allow us to set extent sizes */
-#define putc zputc /* To allow us to auto flush */
-
-
-/* Prototype function declarations */
-
-void zexit (int);
-
-FILE *zipopen(
-const char *,
-const char *
-);
-
-int zputc(
-int,
-FILE *
-);
-
-int zgetch (void);
-
-short parsename(
- const char *,
- char *,
- char *
-);
-
-int islicensed (void);
-
-time_t gmt_to_time_t (long long *);
-
-/* End of prototype function declarations */
+#define EXIT zexit /* To stop creation of Abend files */
+#define RETURN zexit /* To stop creation of Abend files */
+#define putc zputc /* To allow us to auto flush */
#define FOPR "rb"
@@ -94,24 +72,6 @@ time_t gmt_to_time_t (long long *);
#define FOPW "wb"
#define FOPWT "w"
-#define CBSZ 0x10000 /* Was used for both fcopy and file_read. */
- /* Created separate define (SBSZ) for file_read */
- /* fcopy param is type size_t (unsigned long) */
- /* For Guardian we choose a multiple of 4K */
-
-#define ZBSZ 0x10000 /* This is used in call to setvbuf, 64K seems to work */
- /* in all memory models. Again it is an unsigned long */
- /* For Guardian we choose a multiple of 4K */
-
-#ifndef __INT32
-#define SBSZ 0x0e000 /* Maximum of size unsigned (int). Only used in STORE */
- /* method. We can use up to 56K bytes thanks to large */
- /* transfer mode. Note WSIZE is limited to 32K, which */
- /* limits the DEFLATE read size to same value. */
-#else
-#define SBSZ 0x10000 /* WIDE model so we can use 64K */
-#endif /* __INT32 */
-
#define NAMELEN FILENAME_MAX+1+EXTENSION_MAX /* allow for space extension */
struct dirent {
@@ -137,6 +97,7 @@ char * readd(DIR *dirp);
#define SET_FILE_SECURITY 1
#define SET_FILE_OWNER 2
#define SET_FILE_BUFFERED 90
+#define SET_FILE_MAXEXTENTS 92
#define SET_FILE_BUFFERSIZE 93
#define SET_LARGE_TRANSFERS 141
@@ -183,13 +144,15 @@ struct nsk_stat_reserved
int64_t spare[3];
};
-typedef struct
+#pragma FIELDALIGN SHARED8 nsk_owner
+struct nsk_owner
{
unsigned group : 8;
unsigned user : 8;
-} nsk_owner;
+};
-typedef struct
+#pragma FIELDALIGN SHARED8 nsk_file_flags
+struct nsk_file_flags
{
unsigned buffered : 1;
unsigned audited : 1;
@@ -207,15 +170,16 @@ typedef struct
unsigned crashopen : 1;
unsigned rollforward : 1;
unsigned clearonpurge: 1;
-} nsk_file_flags;
+};
-typedef struct
+#pragma FIELDALIGN SHARED8 nsk_file_attrs_def
+struct nsk_file_attrs_def
{
unsigned short filecode; /* 16 */
unsigned short block; /* 16 */ /* Allow of block > 4096 one day ! */
- nsk_file_flags flags; /* 16 */
- nsk_owner owner; /* 16 */
- unsigned short primext; /* 16 */
+ struct nsk_file_flags flags; /* 16 */
+ struct nsk_owner owner; /* 16 */
+ unsigned short priext; /* 16 */
unsigned short secext; /* 16 */
unsigned maxext : 10;
unsigned read : 3;
@@ -231,12 +195,15 @@ typedef struct
unsigned filetype : 2;
unsigned fileopen : 1;
unsigned reclen : 12;
-} nsk_file_attrs;
+};
+typedef struct nsk_file_attrs_def nsk_file_attrs;
+#pragma FIELDALIGN SHARED8 nsk_stat_overlay
struct nsk_stat_overlay
{
- time_t creation_time; /* 32 */
- char nsk_ef_start; /* Start of ef region */
+ time_t creation_time; /* 32 bits */
+ nsk_file_attrs nsk_ef_region;
+ /* char nsk_ef_region[20]; *//* EF region */
};
typedef union
@@ -245,4 +212,25 @@ typedef union
struct nsk_stat_overlay ov;
} nsk_stat_ov;
+/* Prototype function declarations */
+
+void zexit (int);
+
+int zputc(
+ int,
+ FILE *
+);
+
+int zgetch (void);
+
+short parsename(
+ const char *,
+ char *,
+ char *
+);
+
+int islicensed (void);
+
+/* End of prototype function declarations */
+
#endif /* !__tandem_h */
diff --git a/tandem/tannsk.h b/tandem/tannsk.h
index 122d8ed..34ad49c 100644
--- a/tandem/tannsk.h
+++ b/tandem/tannsk.h
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 1999-Oct-05 or later
+ 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, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+ 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
*/
/*
* Header declaration(s) which are forced to go after earlier includes
diff --git a/tandem/tanzip.c b/tandem/tanzip.c
index dbd7233..5985b33 100644
--- a/tandem/tanzip.c
+++ b/tandem/tanzip.c
@@ -1,9 +1,9 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*
@@ -11,6 +11,7 @@
*/
#include "zip.h"
+#include "crypt.h"
#include <tal.h>
#include "$system.zsysdefs.zsysc" nolist
#include <cextdecs> nolist
@@ -32,14 +33,10 @@ void version_local()
#ifdef __GNUC__
"gcc ", __VERSION__,
#else
-# if 0
- "cc ", (sprintf(buf, " version %d", _RELEASE), buf),
-# else
- "unknown compiler", "",
-# endif
+ "C ", "T9255D44 - (16OCT98)",
#endif
- "Tandem/NSK", "",
+ "NonStop ", "(Tandem/NSK)",
#ifdef __DATE__
" on ", __DATE__
@@ -50,6 +47,74 @@ void version_local()
} /* end function version_local() */
+
+/************************/
+/* Function nskopen() */
+/************************/
+
+#ifdef fopen
+# undef fopen
+#endif
+
+FILE *nskopen(fname, opt)
+const char *fname;
+const char *opt;
+{
+ int fdesc;
+ short fnum, err, len;
+ int priext, secext;
+ short maxext, filecode, blocksize;
+
+ #define alist_items 1
+ #define vlist_bytes 2
+ short alist[alist_items]={42};
+ unsigned short vlist[alist_items];
+ short extra, *err_item=&extra;
+
+ char nsk_work[FILENAME_MAX + 1], *nsk_fname=&nsk_work[0];
+
+ /* See if we want to create a new file */
+ if ((strcmp(opt,FOPW) == 0) || (strcmp(opt,FOPWT) == 0)) {
+ blocksize = TANDEM_BLOCKSIZE;
+ priext = 100;
+ secext = 500;
+ maxext = 978;
+ filecode = NSK_ZIPFILECODE;
+
+ if ((fdesc = creat(fname,,priext,secext)) != -1){
+ fnum = fdtogfn ((short)fdesc);
+ err = (SETMODE (fnum, SET_FILE_BUFFERSIZE, blocksize) != CCE);
+ err = (SETMODE (fnum, SET_FILE_BUFFERED, 0, 0) != CCE);
+ err = (SETMODE (fnum, SET_FILE_BUFFERED, 0, 1) != CCE);
+ err = (SETMODE (fnum, SET_FILE_MAXEXTENTS, maxext) != CCE);
+ err = close(fdesc);
+
+ vlist[0] = filecode;
+
+ /* Note that FILE_ALTERLIST_ expects uppercase names */
+ /* Need to call strlen and upshift */
+ len = strlen(fname);
+ err = STRING_UPSHIFT_((char *)fname,
+ len,
+ nsk_fname,
+ len);
+
+ err = FILE_ALTERLIST_(nsk_fname,
+ len,
+ alist,
+ alist_items,
+ vlist,
+ vlist_bytes,
+ ,
+ err_item);
+ };
+ };
+
+ return fopen(fname,opt);
+}
+#define fopen nskopen
+
+
int Bflag = 0; /* Special formatting options for Tandem */
/* Bit 0 = Add delimiter (0 = Yes, 1 = No) */
/* Bit 1 = Delimiter Type (0 = CR/LF, 1 = LF) */
@@ -67,7 +132,8 @@ void version_local()
struct stat znsk_stat;
nsk_stat_ov *znsk_ov = (nsk_stat_ov *)&znsk_stat.st_reserved[0];
nsk_file_attrs *znsk_attr = (nsk_file_attrs *)
- ((char *) (&znsk_stat.st_reserved[0]) + 4);
+ ( (char *)(&znsk_stat.st_reserved[0]) +
+ offsetof (struct nsk_stat_overlay, nsk_ef_region) );
/* Following items used by zread to avoid overwriting window */
char zreadbuf[MAX_LARGE_READ]; /* Buffer as large as biggest read */
@@ -260,22 +326,16 @@ void version_local()
return (err != 0);
}
+/* modified to work with get_option which returns
+ a string with the number value without leading option */
void nskformatopt(p)
-char **p;
+char *p;
{
-char *q;
-
/* set up formatting options for ZIP */
- q = *p; /* make a note of where we are */
-
Bflag = 0; /* default option */
- Bflag = strtoul((*p + 1), p, 10);
-
- /* need to go back one character if we've got a result */
- if (q != *p)
- (*p)--;
+ Bflag = strtoul(p, NULL, 10);
if (Bflag & NSK_SPACE_FILL)
nsk_space_fill = 1;
@@ -530,7 +590,7 @@ char *q;
{
struct stat s;
nsk_stat_ov *nsk_ov = (nsk_stat_ov *)&s.st_reserved[0];
- nsk_file_attrs *nsk_attr = (nsk_file_attrs *)&nsk_ov->ov.nsk_ef_start;
+ nsk_file_attrs *nsk_attr = (nsk_file_attrs *)&nsk_ov->ov.nsk_ef_region;
char *ext, *cext;
int lsize, csize;
#ifdef USE_EF_UT_TIME
@@ -635,3 +695,29 @@ char *q;
return ZE_OK;
}
+
+#if CRYPT
+ /* getpid() only available on OSS so make up dummy version using NSK PID */
+ unsigned zgetpid (void)
+ {
+ short myphandle[ZSYS_VAL_PHANDLE_WLEN];
+ short err;
+ unsigned retval;
+
+ err = PROCESSHANDLE_NULLIT_(myphandle);
+
+ if (!err)
+ err = PROCESS_GETINFO_(myphandle);
+
+ if (!err)
+ retval = (unsigned) myphandle[ZSYS_VAL_PHANDLE_WLEN - 3];
+ else
+#ifndef __INT32
+ retval = (unsigned) 31415;
+#else
+ retval = (unsigned) 3141592654L;
+#endif /* __INT32 */
+
+ return retval;
+ }
+#endif /* CRYPT */
diff --git a/tandem/tanzip.h b/tandem/tanzip.h
index f6cd6bb..528337d 100644
--- a/tandem/tanzip.h
+++ b/tandem/tanzip.h
@@ -1,17 +1,43 @@
/*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 1999-Oct-05 or later
+ 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, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+ 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 __tanzip_h /* prevent multiple inclusions */
#define __tanzip_h
+# define fopen nskopen /* To allow us to set extent sizes */
+
+# define USE_CASE_MAP
+
+ FILE *nskopen(const char *, const char *);
int zopen (const char *, int);
int zclose (int);
unsigned zread (int, char *, unsigned);
- void nskformatopt(char **);
+ void nskformatopt(char *);
+
+ #define getpid zgetpid
+ unsigned zgetpid (void);
+
+#define CBSZ 0x10000 /* Was used for both fcopy and file_read. */
+ /* Created separate define (SBSZ) for file_read */
+ /* fcopy param is type size_t (unsigned long) */
+ /* For Guardian we choose a multiple of 4K */
+
+#define ZBSZ 0x10000 /* This is used in call to setvbuf, 64K seems to work */
+ /* in all memory models. Again it is an unsigned long */
+ /* For Guardian we choose a multiple of 4K */
+
+#ifndef __INT32
+#define SBSZ 0x0e000 /* Maximum of size unsigned (int). Only used in STORE */
+ /* method. We can use up to 56K bytes thanks to large */
+ /* transfer mode. Note WSIZE is limited to 32K, which */
+ /* limits the DEFLATE read size to same value. */
+#else
+#define SBSZ 0x10000 /* WIDE model so we can use 64K */
+#endif /* __INT32 */
#endif /* !__tanzip_h */
diff --git a/tandem/zipup.h b/tandem/zipup.h
index dd7e24d..19d92ad 100644
--- a/tandem/zipup.h
+++ b/tandem/zipup.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2002 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.
@@ -14,7 +14,7 @@
typedef int ftype;
/* Now we create Guardian versions of zopen, zread, zclose instead
- moved prototypes to tandem.h as they are no coded in tandem.c
+ moved prototypes to tanzip.h as they are now coded in tanzip.c
#define zopen(n,p) open(n,p)
#define zread(f,b,n) read(f,b,n)
#define zclose(f) close(f)
diff --git a/theos/Makefile b/theos/Makefile
index cb3d6da..acdbb12 100644
--- a/theos/Makefile
+++ b/theos/Makefile
@@ -20,54 +20,54 @@ UTILFLAGS=-DUTIL $(CFLAGS) -Fo
# object file lists
OBJZ = zip.o zipfile.o zipup.o fileio.o util.o globals.o crypt.o ttyio.o \
- theos.o crc32.o crctab.o _fprintf.o _stat.o _chmod.o _isatty.o \
+ theos.o crc32.o _fprintf.o _stat.o _chmod.o _isatty.o \
_setargv.o _rename.o
OBJI = deflate.o trees.o
OBJA =
OBJU = zipfile_.o fileio_.o util_.o globals.o theos_.o _rename.o _stat.o \
_chmod.o _fprintf.o
OBJN = zipnote.o $(OBJU)
-OBJC = zipcloak.o $(OBJU) crctab.o crypt_.o ttyio.o
+OBJC = zipcloak.o $(OBJU) crc32_.o crypt_.o ttyio.o
OBJS = zipsplit.o $(OBJU)
+OSDEP_H = theos/osdep.h
+ZIP_H = zip.h ziperr.h tailor.h $(OSDEP_H)
+
ZIPS = zip.command zipnote.command zipsplit.command zipcloak.command
zips: $(ZIPS)
-zip.o: zip.h theos/osdep.h ziperr.h tailor.h ttyio.h revision.h zip.c
- $(CC) -c $(CFLAGS) $*.c
-
-zipfile.o: zip.h theos/osdep.h ziperr.h tailor.h zipfile.c
+zip.o: zip.c $(ZIP_H) crc32.h crypt.h ttyio.h revision.h
$(CC) -c $(CFLAGS) $*.c
-zipup.o: zip.h theos/osdep.h ziperr.h tailor.h revision.h zipup.c
+zipfile.o: zipfile.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
-fileio.o: zip.h theos/osdep.h ziperr.h tailor.h fileio.c
+zipup.o: zipup.c $(ZIP_H) revision.h crc32.h crypt.h
$(CC) -c $(CFLAGS) $*.c
-util.o: zip.h theos/osdep.h theos/charconv.h ziperr.h tailor.h util.c
+fileio.o: fileio.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
-globals.o: zip.h theos/osdep.h ziperr.h tailor.h globals.c
+util.o: util.c $(ZIP_H) theos/charconv.h
$(CC) -c $(CFLAGS) $*.c
-crc32.o: zip.h theos/osdep.h ziperr.h tailor.h crc32.c
+globals.o: globals.c $(ZIP_H)
$(CC) -c $(CFLAGS) $*.c
-crctab.o: zip.h theos/osdep.h ziperr.h tailor.h crctab.c
+crc32.o: crc32.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
-deflate.o: zip.h theos/osdep.h ziperr.h tailor.h deflate.c
+deflate.o: deflate.c $(ZIP_H)
$(CC) -c $(CFLAGS) $*.c
-trees.o: zip.h theos/osdep.h ziperr.h tailor.h trees.c
+trees.o: trees.c $(ZIP_H)
$(CC) -c $(CFLAGS) $*.c
-crypt.o: zip.h theos/osdep.h ziperr.h tailor.h crypt.c
+crypt.o: crypt.c $(ZIP_H) crc32.h crypt.h
$(CC) -c $(CFLAGS) $*.c
-theos.o: zip.h theos/osdep.h ziperr.h tailor.h theos/theos.c
+theos.o: theos/theos.c $(ZIP_H)
$(CC) -c $(CFLAGS) -Fo$@ theos/theos.c
_fprintf.o: theos/_fprintf.c
@@ -88,31 +88,34 @@ _rename.o: theos/_rename.c
_setargv.o: theos/_setargv.c
$(CC) -c $(CFLAGS) -Fo$@ theos/_setargv.c
-ttyio.o: zip.h theos/osdep.h ziperr.h tailor.h ttyio.h ttyio.c
+ttyio.o: $(ZIP_H) ttyio.h ttyio.c
$(CC) -c $(CFLAGS) $*.c
-zipcloak.o: zip.h theos/osdep.h ziperr.h tailor.h ttyio.h revision.h zipcloak.c
+zipcloak.o: zipcloak.c $(ZIP_H) crc32.h crypt.h ttyio.h revision.h
$(CC) -c $(CFLAGS) $*.c
-zipnote.o: zip.h theos/osdep.h ziperr.h tailor.h revision.h zipnote.c
+zipnote.o: zipnote.c $(ZIP_H) revision.h
$(CC) -c $(CFLAGS) $*.c
-zipsplit.o: zipsplit.c zip.h theos/osdep.h ziperr.h tailor.h revision.h
+zipsplit.o: $(ZIP_H) revision.h
$(CC) -c $(CFLAGS) $*.c
-zipfile_.o: zipfile.c zip.h theos/osdep.h ziperr.h tailor.h
+zipfile_.o: zipfile.c $(ZIP_H) crc32.h
$(CC) -c $(UTILFLAGS)$@ zipfile.c
-fileio_.o: fileio.c zip.h theos/osdep.h ziperr.h tailor.h
+fileio_.o: fileio.c $(ZIP_H) crc32.h
$(CC) -c $(UTILFLAGS)$@ fileio.c
-theos_.o: zip.h theos/osdep.h ziperr.h tailor.h theos/theos.c
+theos_.o: theos/theos.c $(ZIP_H)
$(CC) -c $(UTILFLAGS)$@ theos/theos.c
-util_.o: util.c zip.h theos/osdep.h ziperr.h tailor.h
+util_.o: util.c $(ZIP_H)
$(CC) -c $(UTILFLAGS)$@ util.c
-crypt_.o: zip.h theos/osdep.h ziperr.h tailor.h crypt.c
+crc32_.o: crc32.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS)$@ $*.c
+
+crypt_.o: crypt.c $(ZIP_H) crc32.h crypt.h
$(CC) -c $(UTILFLAGS)$@ crypt.c
zip.command: $(OBJZ) $(OBJI)
diff --git a/theos/_fprintf.c b/theos/_fprintf.c
index 5c8c927..36a21a6 100644
--- a/theos/_fprintf.c
+++ b/theos/_fprintf.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 1999-Oct-05 or later
+ 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, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+ 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 <stdio.h>
#include <stdarg.h>
diff --git a/theos/_isatty.c b/theos/_isatty.c
index 26f177b..3283e90 100644
--- a/theos/_isatty.c
+++ b/theos/_isatty.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 1999-Oct-05 or later
+ 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, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+ 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
*/
/* replace standard library function who needs a FILE* */
diff --git a/theos/charconv.h b/theos/charconv.h
index a2d8dfa..3189170 100644
--- a/theos/charconv.h
+++ b/theos/charconv.h
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 1999-Oct-05 or later
+ 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, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+ 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
*/
#ifdef IZ_THS2ISO_ARRAY
diff --git a/theos/stat.h b/theos/stat.h
index 3a716f8..ffcec0f 100644
--- a/theos/stat.h
+++ b/theos/stat.h
@@ -1,12 +1,12 @@
#ifndef __theos_stat_h
#define __theos_stat_h
/*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 1999-Oct-05 or later
+ 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, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+ 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
*/
/* extended stat structure for stat, fstat, chmod */
diff --git a/theos/theos.c b/theos/theos.c
index 17db108..5da3f8b 100644
--- a/theos/theos.c
+++ b/theos/theos.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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.info-zip.org/pub/infozip/license.html
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
/*---------------------------------------------------------------------------
@@ -409,8 +409,9 @@ iztimes *t; /* return value: access, modific. and creation times */
a device, return a file size of -1 */
{
struct stat s; /* results of stat() */
+ /* from FNMAX to malloc - 11/8/04 EG */
char *name;
- unsigned int len = strlen(f);
+ int len = strlen(f);
if (f == label) {
if (a != NULL)
@@ -421,7 +422,6 @@ iztimes *t; /* return value: access, modific. and creation times */
t->atime = t->mtime = t->ctime = label_utim;
return label_time;
}
-
if ((name = malloc(len + 1)) == NULL) {
ZIPERR(ZE_MEM, "filetime");
}
@@ -443,6 +443,7 @@ iztimes *t; /* return value: access, modific. and creation times */
free(name);
return 0;
}
+ free(name);
if (a != NULL) {
*a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE);
@@ -462,9 +463,6 @@ iztimes *t; /* return value: access, modific. and creation times */
t->mtime = s.st_mtime;
t->ctime = t->mtime; /* best guess, (s.st_ctime: last status change!!) */
}
-
- free(name);
-
return unix2dostime(&s.st_mtime);
}
/*
diff --git a/timezone.c b/timezone.c
new file mode 100644
index 0000000..485ec02
--- /dev/null
+++ b/timezone.c
@@ -0,0 +1,815 @@
+/*
+ timezone.c - Zip 3
+
+ Copyright (c) 1990-2004 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2003-May-08 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
+*/
+/* Replacement time library functions, based on platform independent public
+ * domain timezone code from ftp://elsie.nci.nih.gov/pub, with mktime and
+ * mkgmtime from our own mktime.c in Zip.
+ *
+ * Contains: tzset()
+ * __tzset()
+ * gmtime()
+ * localtime()
+ * mktime()
+ * mkgmtime()
+ * GetPlatformLocalTimezone() [different versions]
+ */
+
+/* HISTORY/CHANGES
+ * 17 Jun 00, Paul Kienitz, added the PD-based tzset(), localtime(), and so on
+ * to amiga/filedate.c, replacing GNU-based functions which had
+ * replaced time_lib.c, both having been rejected for licensing
+ * reasons. Support for timezone files and leap seconds was removed.
+ *
+ * 23 Aug 00, Paul Kienitz, split into separate timezone.c file, made platform
+ * independent, copied in mktime() and mkgmtime() from Zip, renamed
+ * locale_TZ as GetPlatformLocalTimezone(), for use as a generic
+ * hook by other platforms.
+ */
+
+#ifndef __timezone_c
+#define __timezone_c
+
+
+#include "zip.h"
+#include "timezone.h"
+#include <ctype.h>
+#include <errno.h>
+
+#ifdef IZTZ_DEFINESTDGLOBALS
+long timezone = 0;
+int daylight = 0;
+char *tzname[2];
+#endif
+
+#ifndef IZTZ_GETLOCALETZINFO
+# define IZTZ_GETLOCALETZINFO(ptzstruct, pgenrulefunct) (FALSE)
+#endif
+
+int real_timezone_is_set = FALSE; /* set by tzset() */
+
+
+#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
+#define TZDEFAULT "EST5EDT"
+
+#define SECSPERMIN 60
+#define MINSPERHOUR 60
+#define HOURSPERDAY 24
+#define DAYSPERWEEK 7
+#define DAYSPERNYEAR 365
+#define DAYSPERLYEAR 366
+#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
+#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
+#define MONSPERYEAR 12
+
+#define EPOCH_WDAY 4 /* Jan 1, 1970 was thursday */
+#define EPOCH_YEAR 1970
+#define TM_YEAR_BASE 1900
+#define FIRST_GOOD_YEAR ((time_t) -1 < (time_t) 1 ? EPOCH_YEAR-68 : EPOCH_YEAR)
+#define LAST_GOOD_YEAR (EPOCH_YEAR + ((time_t) -1 < (time_t) 1 ? 67 : 135))
+
+#define YDAYS(month, year) yr_days[leap(year)][month]
+
+/* 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 EPOCH_YEAR to `y' (not including `y' itself). */
+#define _P4 ((EPOCH_YEAR / 4) * 4 + 1)
+#define _P100 ((EPOCH_YEAR / 100) * 100 + 1)
+#define _P400 ((EPOCH_YEAR / 400) * 400 + 1)
+#define nleap(y) (((y) - _P4) / 4 - ((y) - _P100) / 100 + ((y) - _P400) / 400)
+
+/* Length of month `m' (0 .. 11) */
+#define monthlen(m, y) (yr_days[0][(m)+1] - yr_days[0][m] + \
+ ((m) == 1 && leap(y)))
+
+/* internal module-level constants */
+#ifndef IZ_MKTIME_ONLY
+static ZCONST char gmt[] = "GMT";
+static ZCONST int mon_lengths[2][MONSPERYEAR] = {
+ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+ { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+};
+#endif /* !IZ_MKTIME_ONLY */
+static ZCONST int yr_days[2][MONSPERYEAR+1] = {
+ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
+ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
+};
+#ifndef IZ_MKTIME_ONLY
+static ZCONST int year_lengths[2] = {
+ DAYSPERNYEAR, DAYSPERLYEAR
+};
+
+/* internal variables */
+static struct state statism;
+
+
+/* prototypes of static functions */
+static time_t transtime OF((ZCONST time_t janfirst, ZCONST int year,
+ ZCONST struct rule * ZCONST rulep,
+ ZCONST long offset));
+static void generate_transitions OF((register struct state * ZCONST sp,
+ ZCONST struct rule * ZCONST start,
+ ZCONST struct rule * ZCONST end));
+static ZCONST char *getzname OF((ZCONST char *strp));
+static ZCONST char *getnum OF((ZCONST char *strp, int * ZCONST nump,
+ ZCONST int min, ZCONST int max));
+static ZCONST char *getsecs OF((ZCONST char *strp, long * ZCONST secsp));
+static ZCONST char *getoffset OF((ZCONST char *strp, long * ZCONST offsetp));
+static ZCONST char *getrule OF((ZCONST char *strp, struct rule * ZCONST rulep));
+static int Parse_TZ OF((ZCONST char *name, register struct state * ZCONST sp));
+
+
+static time_t transtime(janfirst, year, rulep, offset)
+ ZCONST time_t janfirst;
+ ZCONST int year;
+ ZCONST struct rule * ZCONST rulep;
+ ZCONST long offset;
+{
+ register int leapyear;
+ register time_t value;
+ register int i;
+ int d, m1, yy0, yy1, yy2, dow;
+
+ value = 0;
+ leapyear = leap(year);
+ switch (rulep->r_type) {
+
+ case JULIAN_DAY:
+ /*
+ ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
+ ** years.
+ ** In non-leap years, or if the day number is 59 or less, just
+ ** add SECSPERDAY times the day number-1 to the time of
+ ** January 1, midnight, to get the day.
+ */
+ value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
+ if (leapyear && rulep->r_day >= 60)
+ value += SECSPERDAY;
+ break;
+
+ case DAY_OF_YEAR:
+ /*
+ ** n - day of year.
+ ** Just add SECSPERDAY times the day number to the time of
+ ** January 1, midnight, to get the day.
+ */
+ value = janfirst + rulep->r_day * SECSPERDAY;
+ break;
+
+ case MONTH_NTH_DAY_OF_WEEK:
+ /*
+ ** Mm.n.d - nth "dth day" of month m.
+ */
+ value = janfirst;
+/*
+ for (i = 0; i < rulep->r_mon - 1; ++i)
+ value += mon_lengths[leapyear][i] * SECSPERDAY;
+*/
+ value += yr_days[leapyear][rulep->r_mon - 1] * SECSPERDAY;
+
+ /*
+ ** Use Zeller's Congruence to get day-of-week of first day of
+ ** month.
+ */
+ m1 = (rulep->r_mon + 9) % 12 + 1;
+ yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
+ yy1 = yy0 / 100;
+ yy2 = yy0 % 100;
+ dow = ((26 * m1 - 2) / 10 +
+ 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
+ if (dow < 0)
+ dow += DAYSPERWEEK;
+
+ /*
+ ** "dow" is the day-of-week of the first day of the month. Get
+ ** the day-of-month (zero-origin) of the first "dow" day of the
+ ** month.
+ */
+ d = rulep->r_day - dow;
+ if (d < 0)
+ d += DAYSPERWEEK;
+ for (i = 1; i < rulep->r_week; ++i) {
+ if (d + DAYSPERWEEK >= mon_lengths[leapyear][rulep->r_mon - 1])
+ break;
+ d += DAYSPERWEEK;
+ }
+
+ /*
+ ** "d" is the day-of-month (zero-origin) of the day we want.
+ */
+ value += d * SECSPERDAY;
+ break;
+ }
+
+ /*
+ ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
+ ** question. To get the Epoch-relative time of the specified local
+ ** time on that day, add the transition time and the current offset
+ ** from UTC.
+ */
+ return value + rulep->r_time + offset;
+}
+
+static void generate_transitions(sp, start, end)
+ register struct state * ZCONST sp;
+ ZCONST struct rule * ZCONST start;
+ ZCONST struct rule * ZCONST end;
+{
+ register int year;
+ register time_t janfirst;
+ time_t starttime;
+ time_t endtime;
+ long stdoffset = -sp->ttis[0].tt_gmtoff;
+ long dstoffset = -sp->ttis[1].tt_gmtoff;
+ register time_t * atp;
+ register unsigned char * typep;
+
+ /*
+ ** Two transitions per year, from EPOCH_YEAR to LAST_GOOD_YEAR.
+ */
+ sp->timecnt = 2 * (LAST_GOOD_YEAR - EPOCH_YEAR + 1);
+ atp = sp->ats;
+ typep = sp->types;
+ janfirst = 0;
+ for (year = EPOCH_YEAR; year <= LAST_GOOD_YEAR; ++year) {
+ starttime = transtime(janfirst, year, start, stdoffset);
+ endtime = transtime(janfirst, year, end, dstoffset);
+ if (starttime > endtime) {
+ *atp++ = endtime;
+ *typep++ = 0; /* DST ends */
+ *atp++ = starttime;
+ *typep++ = 1; /* DST begins */
+ } else {
+ *atp++ = starttime;
+ *typep++ = 1; /* DST begins */
+ *atp++ = endtime;
+ *typep++ = 0; /* DST ends */
+ }
+ janfirst += year_lengths[leap(year)] * SECSPERDAY;
+ }
+}
+
+static ZCONST char *getzname(strp)
+ ZCONST char *strp;
+{
+ register char c;
+
+ while ((c = *strp) != '\0' && !isdigit(c) && c != ',' && c != '-' &&
+ c != '+')
+ ++strp;
+ return strp;
+}
+
+static ZCONST char *getnum(strp, nump, min, max)
+ ZCONST char *strp;
+ int * ZCONST nump;
+ ZCONST int min;
+ ZCONST int max;
+{
+ register char c;
+ register int num;
+
+ if (strp == NULL || !isdigit(c = *strp))
+ return NULL;
+ num = 0;
+ do {
+ num = num * 10 + (c - '0');
+ if (num > max)
+ return NULL; /* illegal value */
+ c = *++strp;
+ } while (isdigit(c));
+ if (num < min)
+ return NULL; /* illegal value */
+ *nump = num;
+ return strp;
+}
+
+static ZCONST char *getsecs(strp, secsp)
+ ZCONST char *strp;
+ long * ZCONST secsp;
+{
+ int num;
+
+ /*
+ ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
+ ** "M10.4.6/26", which does not conform to Posix,
+ ** but which specifies the equivalent of
+ ** ``02:00 on the first Sunday on or after 23 Oct''.
+ */
+ strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
+ if (strp == NULL)
+ return NULL;
+ *secsp = num * (long) SECSPERHOUR;
+ if (*strp == ':') {
+ ++strp;
+ strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
+ if (strp == NULL)
+ return NULL;
+ *secsp += num * SECSPERMIN;
+ if (*strp == ':') {
+ ++strp;
+ /* `SECSPERMIN' allows for leap seconds. */
+ strp = getnum(strp, &num, 0, SECSPERMIN);
+ if (strp == NULL)
+ return NULL;
+ *secsp += num;
+ }
+ }
+ return strp;
+}
+
+static ZCONST char *getoffset(strp, offsetp)
+ ZCONST char *strp;
+ long * ZCONST offsetp;
+{
+ register int neg = 0;
+
+ if (*strp == '-') {
+ neg = 1;
+ ++strp;
+ } else if (*strp == '+')
+ ++strp;
+ strp = getsecs(strp, offsetp);
+ if (strp == NULL)
+ return NULL; /* illegal time */
+ if (neg)
+ *offsetp = -*offsetp;
+ return strp;
+}
+
+static ZCONST char *getrule(strp, rulep)
+ ZCONST char *strp;
+ struct rule * ZCONST rulep;
+{
+ if (*strp == 'J') {
+ /*
+ ** Julian day.
+ */
+ rulep->r_type = JULIAN_DAY;
+ ++strp;
+ strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
+ } else if (*strp == 'M') {
+ /*
+ ** Month, week, day.
+ */
+ rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
+ ++strp;
+ strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
+ if (strp == NULL)
+ return NULL;
+ if (*strp++ != '.')
+ return NULL;
+ strp = getnum(strp, &rulep->r_week, 1, 5);
+ if (strp == NULL)
+ return NULL;
+ if (*strp++ != '.')
+ return NULL;
+ strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
+ } else if (isdigit(*strp)) {
+ /*
+ ** Day of year.
+ */
+ rulep->r_type = DAY_OF_YEAR;
+ strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
+ } else return NULL; /* invalid format */
+ if (strp == NULL)
+ return NULL;
+ if (*strp == '/') {
+ /*
+ ** Time specified.
+ */
+ ++strp;
+ strp = getsecs(strp, &rulep->r_time);
+ } else
+ rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
+ return strp;
+}
+
+static int Parse_TZ(name, sp)
+ ZCONST char *name;
+ register struct state * ZCONST sp;
+{
+ ZCONST char * stdname;
+ ZCONST char * dstname;
+ size_t stdlen;
+ size_t dstlen;
+ long stdoffset;
+ long dstoffset;
+ register char * cp;
+
+ dstname = NULL;
+ stdname = name;
+ name = getzname(name);
+ stdlen = name - stdname;
+ if (stdlen < 3)
+ return -1;
+ if (*name == '\0')
+ return -1;
+ name = getoffset(name, &stdoffset);
+ if (name == NULL)
+ return -1;
+ if (*name != '\0') {
+ dstname = name;
+ name = getzname(name);
+ dstlen = name - dstname; /* length of DST zone name */
+ if (dstlen < 3)
+ return -1;
+ if (*name != '\0' && *name != ',' && *name != ';') {
+ name = getoffset(name, &dstoffset);
+ if (name == NULL)
+ return -1;
+ } else
+ dstoffset = stdoffset - SECSPERHOUR;
+ if (*name == '\0')
+ name = TZDEFRULESTRING;
+ if (*name == ',' || *name == ';') {
+ struct rule start;
+ struct rule end;
+
+ ++name;
+ if ((name = getrule(name, &start)) == NULL)
+ return -1;
+ if (*name++ != ',')
+ return -1;
+ if ((name = getrule(name, &end)) == NULL)
+ return -1;
+ if (*name != '\0')
+ return -1;
+ sp->typecnt = 2; /* standard time and DST */
+ sp->ttis[0].tt_gmtoff = -stdoffset;
+ sp->ttis[0].tt_isdst = 0;
+ sp->ttis[0].tt_abbrind = 0;
+ sp->ttis[1].tt_gmtoff = -dstoffset;
+ sp->ttis[1].tt_isdst = 1;
+ sp->ttis[1].tt_abbrind = stdlen + 1;
+ generate_transitions(sp, &start, &end);
+ }
+ } else {
+ dstlen = 0;
+ sp->typecnt = 1; /* only standard time */
+ sp->timecnt = 0;
+ sp->ttis[0].tt_gmtoff = -stdoffset;
+ sp->ttis[0].tt_isdst = 0;
+ sp->ttis[0].tt_abbrind = 0;
+ }
+ sp->charcnt = stdlen + 1;
+ if (dstlen != 0)
+ sp->charcnt += dstlen + 1;
+ if ((size_t) sp->charcnt > sizeof(sp->chars))
+ return -1;
+ cp = sp->chars;
+ (void) strncpy(cp, stdname, stdlen);
+ cp += stdlen;
+ *cp++ = '\0';
+ if (dstlen != 0) {
+ (void) strncpy(cp, dstname, dstlen);
+ *(cp + dstlen) = '\0';
+ }
+ return 0;
+}
+
+void tzset()
+{
+ char *TZstring;
+ int dstfirst;
+ static char *old_TZstring = NULL;
+
+ TZstring = getenv("TZ"); /* read TZ envvar */
+ if (old_TZstring && TZstring && !strcmp(old_TZstring, TZstring))
+ /* do not repeatedly parse an unchanged TZ specification */
+ return;
+ if ((TZstring && TZstring[0] && Parse_TZ(TZstring, &statism) == 0)
+ || IZTZ_GETLOCALETZINFO(&statism, generate_transitions)
+ || Parse_TZ(gmt, &statism) == 0) {
+ daylight = statism.typecnt > 1;
+ dstfirst = daylight && statism.ttis[0].tt_isdst && !statism.ttis[1].tt_isdst;
+ timezone = -statism.ttis[dstfirst].tt_gmtoff;
+ tzname[0] = statism.chars + statism.ttis[dstfirst].tt_abbrind;
+ tzname[1] = statism.chars + statism.ttis[!dstfirst].tt_abbrind;
+ real_timezone_is_set = TRUE;
+ if (TZstring) {
+ if (old_TZstring)
+ old_TZstring = realloc(old_TZstring, strlen(TZstring) + 1);
+ else
+ old_TZstring = malloc(strlen(TZstring) + 1);
+ if (old_TZstring)
+ strcpy(old_TZstring, TZstring);
+ }
+ } else {
+ timezone = 0; /* default is GMT0 which means no offsets */
+ daylight = 0; /* from local system time */
+ real_timezone_is_set = FALSE;
+ if (old_TZstring) {
+ free(old_TZstring);
+ old_TZstring = NULL;
+ }
+ }
+#ifdef IZTZ_SETLOCALTZINFO
+ /* Some SAS/C library functions, e.g. stat(), call library */
+ /* __tzset() themselves. So envvar TZ *must* exist in order to */
+ /* to get the right offset from GMT. XXX TRY HARD to fix this! */
+ set_TZ(timezone, daylight);
+#endif /* IZTZ_SETLOCALTZINFO */
+}
+
+/* XXX Does this also help SAS/C library work? */
+void __tzset()
+{
+ if (!real_timezone_is_set) tzset();
+}
+
+static struct tm _tmbuf;
+
+struct tm *gmtime(when)
+ ZCONST time_t *when;
+{
+ long days = *when / SECSPERDAY;
+ long secs = *when % SECSPERDAY;
+ int isleap;
+
+ memset(&_tmbuf, 0, sizeof(_tmbuf)); /* get any nonstandard fields */
+ _tmbuf.tm_wday = (days + EPOCH_WDAY) % 7;
+ _tmbuf.tm_year = EPOCH_YEAR - TM_YEAR_BASE;
+ isleap = leap(_tmbuf.tm_year + TM_YEAR_BASE);
+ while (days >= year_lengths[isleap]) {
+ days -= year_lengths[isleap];
+ _tmbuf.tm_year++;
+ isleap = leap(_tmbuf.tm_year + TM_YEAR_BASE);
+ }
+ _tmbuf.tm_mon = 0;
+ _tmbuf.tm_yday = days;
+ while (days >= mon_lengths[isleap][_tmbuf.tm_mon])
+ days -= mon_lengths[isleap][_tmbuf.tm_mon++];
+ _tmbuf.tm_mday = days + 1;
+ _tmbuf.tm_isdst = 0;
+ _tmbuf.tm_sec = secs % SECSPERMIN;
+ _tmbuf.tm_min = (secs / SECSPERMIN) % SECSPERMIN;
+ _tmbuf.tm_hour = secs / SECSPERHOUR;
+ return &_tmbuf;
+}
+
+struct tm *localtime(when)
+ ZCONST time_t *when;
+{
+ time_t localwhen = *when;
+ int timetype;
+ struct tm *ret;
+
+ __tzset();
+ if (statism.timecnt == 0 || localwhen < statism.ats[0])
+ timetype = statism.ttis[0].tt_isdst && statism.typecnt > 1 &&
+ !statism.ttis[1].tt_isdst;
+ else {
+ for (timetype = 1; timetype < statism.timecnt; ++timetype)
+ if (localwhen < statism.ats[timetype])
+ break;
+ timetype = statism.types[timetype - 1];
+ }
+ localwhen += statism.ttis[timetype].tt_gmtoff;
+ ret = gmtime(&localwhen);
+ ret->tm_isdst = statism.ttis[timetype].tt_isdst;
+ return ret;
+}
+
+#ifdef NEED__ISINDST
+int _isindst(tb)
+ struct tm *tb;
+{
+ time_t localt; /* time_t equivalent of given tm struct */
+ time_t univt; /* assumed UTC value of given time */
+ long tzoffset_adj; /* timezone-adjustment `remainder' */
+ int bailout_cnt; /* counter of tries for tz correction */
+ int timetype;
+
+ __tzset();
+
+ /* when DST is unsupported in current timezone, DST is always off */
+ if (statism.typecnt <= 1) return FALSE;
+
+ localt = mkgmtime(tb);
+ if (localt == (time_t)-1)
+ /* specified time is out-of-range, default to FALSE */
+ return FALSE;
+
+ univt = localt - statism.ttis[0].tt_gmtoff;
+ bailout_cnt = 3;
+ do {
+ if (statism.timecnt == 0 || univt < statism.ats[0])
+ timetype = statism.ttis[0].tt_isdst && statism.typecnt > 1 &&
+ !statism.ttis[1].tt_isdst;
+ else {
+ for (timetype = 1; timetype < statism.timecnt; ++timetype)
+ if (univt < statism.ats[timetype])
+ break;
+ timetype = statism.types[timetype - 1];
+ }
+ if ((tzoffset_adj = localt - univt - statism.ttis[timetype].tt_gmtoff)
+ == 0L)
+ break;
+ univt += tzoffset_adj;
+ } while (--bailout_cnt > 0);
+
+ /* return TRUE when DST is active at given time */
+ return (statism.ttis[timetype].tt_isdst);
+}
+#endif /* NEED__ISINDST */
+#endif /* !IZ_MKTIME_ONLY */
+
+/* Return the equivalent in seconds past 12:00:00 a.m. Jan 1, 1970 GMT
+ of the local time and date in the exploded time structure `tm',
+ adjust out of range fields in `tm' and set `tm->tm_yday', `tm->tm_wday'.
+ If `tm->tm_isdst < 0' was passed to mktime(), the correct setting of
+ tm_isdst is determined and returned. Otherwise, mktime() assumes this
+ field as valid; its information is used when converting local time
+ to UTC.
+ Return -1 if time in `tm' cannot be represented as time_t value. */
+
+time_t mktime(tm)
+ struct tm *tm;
+{
+ struct tm *ltm; /* Local time. */
+ time_t loctime; /* The time_t value of local time. */
+ time_t then; /* The time to return. */
+ long tzoffset_adj; /* timezone-adjustment `remainder' */
+ int bailout_cnt; /* counter of tries for tz correction */
+ int save_isdst; /* Copy of the tm->isdst input value */
+
+ save_isdst = tm->tm_isdst;
+ loctime = mkgmtime(tm);
+ if (loctime == -1) {
+ tm->tm_isdst = save_isdst;
+ return (time_t)-1;
+ }
+
+ /* Correct for the timezone and any daylight savings time.
+ The correction is verified and repeated when not correct, to
+ take into account the rare case that a change to or from daylight
+ savings time occurs between when it is the time in `tm' locally
+ and when it is that time in Greenwich. After the second correction,
+ the "timezone & daylight" offset should be correct in all cases. To
+ be sure, we allow a third try, but then the loop is stopped. */
+ bailout_cnt = 3;
+ then = loctime;
+ do {
+ ltm = localtime(&then);
+ if (ltm == (struct tm *)NULL ||
+ (tzoffset_adj = loctime - mkgmtime(ltm)) == 0L)
+ break;
+ then += tzoffset_adj;
+ } while (--bailout_cnt > 0);
+
+ if (ltm == (struct tm *)NULL || tzoffset_adj != 0L) {
+ /* Signal failure if timezone adjustment did not converge. */
+ tm->tm_isdst = save_isdst;
+ return (time_t)-1;
+ }
+
+ if (save_isdst >= 0) {
+ if (ltm->tm_isdst && !save_isdst)
+ {
+ if (then + 3600 < then)
+ then = (time_t)-1;
+ else
+ then += 3600;
+ }
+ else if (!ltm->tm_isdst && save_isdst)
+ {
+ if (then - 3600 > then)
+ then = (time_t)-1;
+ else
+ then -= 3600;
+ }
+ ltm->tm_isdst = save_isdst;
+ }
+
+ if (tm != ltm) /* `tm' may already point to localtime's internal storage */
+ *tm = *ltm;
+
+ return then;
+}
+
+
+#ifndef NO_TIME_T_MAX
+ /* Provide default values for the upper limit of the time_t range.
+ These are the result of the decomposition into a `struct tm' for
+ the time value 0xFFFFFFFEL ( = (time_t)-2 ).
+ Note: `(time_t)-1' is reserved for "invalid time"! */
+# ifndef TM_YEAR_MAX
+# define TM_YEAR_MAX 2106
+# endif
+# ifndef TM_MON_MAX
+# define TM_MON_MAX 1 /* February */
+# endif
+# ifndef TM_MDAY_MAX
+# define TM_MDAY_MAX 7
+# endif
+# ifndef TM_HOUR_MAX
+# define TM_HOUR_MAX 6
+# endif
+# ifndef TM_MIN_MAX
+# define TM_MIN_MAX 28
+# endif
+# ifndef TM_SEC_MAX
+# define TM_SEC_MAX 14
+# endif
+#endif /* NO_TIME_T_MAX */
+
+/* Adjusts out-of-range values for `tm' field `tm_member'. */
+#define ADJUST_TM(tm_member, tm_carry, modulus) \
+ if ((tm_member) < 0) { \
+ tm_carry -= (1 - ((tm_member)+1) / (modulus)); \
+ tm_member = (modulus-1) + (((tm_member)+1) % (modulus)); \
+ } else if ((tm_member) >= (modulus)) { \
+ tm_carry += (tm_member) / (modulus); \
+ tm_member = (tm_member) % (modulus); \
+ }
+
+/* Return the equivalent in seconds past 12:00:00 a.m. Jan 1, 1970 GMT
+ of the Greenwich Mean time and date in the exploded time structure `tm'.
+ This function does always put back normalized values into the `tm' struct,
+ parameter, including the calculated numbers for `tm->tm_yday',
+ `tm->tm_wday', and `tm->tm_isdst'.
+ Returns -1 if the time in the `tm' parameter cannot be represented
+ as valid `time_t' number. */
+
+time_t mkgmtime(tm)
+ struct tm *tm;
+{
+ int years, months, days, hours, minutes, seconds;
+
+ years = tm->tm_year + TM_YEAR_BASE; /* year - 1900 -> year */
+ months = tm->tm_mon; /* 0..11 */
+ days = tm->tm_mday - 1; /* 1..31 -> 0..30 */
+ hours = tm->tm_hour; /* 0..23 */
+ minutes = tm->tm_min; /* 0..59 */
+ seconds = tm->tm_sec; /* 0..61 in ANSI C. */
+
+ ADJUST_TM(seconds, minutes, 60)
+ ADJUST_TM(minutes, hours, 60)
+ ADJUST_TM(hours, days, 24)
+ ADJUST_TM(months, years, 12)
+ if (days < 0)
+ do {
+ if (--months < 0) {
+ --years;
+ months = 11;
+ }
+ days += monthlen(months, years);
+ } while (days < 0);
+ else
+ while (days >= monthlen(months, years)) {
+ days -= monthlen(months, years);
+ if (++months >= 12) {
+ ++years;
+ months = 0;
+ }
+ }
+
+ /* Restore adjusted values in tm structure */
+ tm->tm_year = years - TM_YEAR_BASE;
+ tm->tm_mon = months;
+ tm->tm_mday = days + 1;
+ tm->tm_hour = hours;
+ tm->tm_min = minutes;
+ tm->tm_sec = seconds;
+
+ /* Set `days' to the number of days into the year. */
+ days += YDAYS(months, years);
+ tm->tm_yday = days;
+
+ /* Now calculate `days' to the number of days since Jan 1, 1970. */
+ days = (unsigned)days + 365 * (unsigned)(years - EPOCH_YEAR) +
+ (unsigned)(nleap (years));
+ tm->tm_wday = ((unsigned)days + EPOCH_WDAY) % 7;
+ tm->tm_isdst = 0;
+
+ if (years < EPOCH_YEAR)
+ return (time_t)-1;
+
+#if (defined(TM_YEAR_MAX) && defined(TM_MON_MAX) && defined(TM_MDAY_MAX))
+#if (defined(TM_HOUR_MAX) && defined(TM_MIN_MAX) && defined(TM_SEC_MAX))
+ if (years > TM_YEAR_MAX ||
+ (years == TM_YEAR_MAX &&
+ (tm->tm_yday > (YDAYS(TM_MON_MAX, TM_YEAR_MAX) + (TM_MDAY_MAX - 1)) ||
+ (tm->tm_yday == (YDAYS(TM_MON_MAX, TM_YEAR_MAX) + (TM_MDAY_MAX - 1)) &&
+ (hours > TM_HOUR_MAX ||
+ (hours == TM_HOUR_MAX &&
+ (minutes > TM_MIN_MAX ||
+ (minutes == TM_MIN_MAX && seconds > TM_SEC_MAX) )))))))
+ return (time_t)-1;
+#endif
+#endif
+
+ return (time_t)(SECSPERDAY * (unsigned long)(unsigned)days +
+ SECSPERHOUR * (unsigned long)hours +
+ (unsigned long)(SECSPERMIN * minutes + seconds));
+}
+
+#endif /* __timezone_c */
diff --git a/timezone.h b/timezone.h
new file mode 100644
index 0000000..f4f46f2
--- /dev/null
+++ b/timezone.h
@@ -0,0 +1,83 @@
+/*
+ timezone.h - Zip 3
+
+ Copyright (c) 1990-2004 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2003-May-08 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 __timezone_h
+#define __timezone_h
+
+#ifndef IZ_MKTIME_ONLY
+
+/* limits for our timezone info data:
+ * we support only basic standard and daylight time, with max 2 transitions
+ * per year, but for the maximum range of years a 32-bit second counter
+ * can cover (these are 136 years plus a bit more than one month)
+ */
+#define TZ_MAX_TIMES 272 /* (=2*(LastGoodYr + 1 - FirstGoodYr) */
+#define TZ_MAX_TYPES 2 /* We only support basic standard and daylight */
+#ifdef WIN32 /* Win32 tzinfo supplies at max (2 * 32) chars of tz names */
+#define TZ_MAX_CHARS 64 /* Maximum number of abbreviation characters */
+#else
+#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
+#endif
+
+/* supported types of transition rules */
+#define JULIAN_DAY 0 /* Jn - Julian day */
+#define DAY_OF_YEAR 1 /* n - day of year */
+#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
+
+
+struct ttinfo {
+ long tt_gmtoff; /* UTC offset in seconds */
+ int tt_isdst; /* used to set tm_isdst */
+ int tt_abbrind; /* abbreviation list index */
+};
+
+struct state {
+ int timecnt;
+ int typecnt;
+ int charcnt;
+ time_t ats[TZ_MAX_TIMES];
+ unsigned char types[TZ_MAX_TIMES];
+ struct ttinfo ttis[TZ_MAX_TYPES];
+ char chars[TZ_MAX_CHARS];
+};
+
+struct rule {
+ int r_type; /* type of rule--JULIAN_DAY etc */
+ int r_day; /* day number of rule */
+ int r_week; /* week number of rule */
+ int r_mon; /* month number of rule */
+ long r_time; /* transition time of rule */
+};
+
+extern int real_timezone_is_set; /* set by tzset() */
+
+
+/* prototypes of functions not in time.h */
+
+void __tzset OF((void));
+
+#ifdef NEED__ISINDST
+int _isindst OF((struct tm *tb));
+#endif
+
+/* callback function to be supplied by the program that uses this library */
+int GetPlatformLocalTimezone OF((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)));
+#ifdef IZTZ_SETLOCALTZINFO
+void set_TZ OF((long time_zone, int day_light));
+#endif
+
+#endif /* !IZ_MKTIME_ONLY */
+
+time_t mkgmtime OF((struct tm *tm));
+
+#endif
diff --git a/tops20/make.mic b/tops20/make.mic
index f93fa77..5930847 100644
--- a/tops20/make.mic
+++ b/tops20/make.mic
@@ -5,14 +5,13 @@
@cc -c -q fileio
@cc -c -q util
@cc -c -q crc32
-@cc -c -q crctab
@cc -c -q global
@cc -c -q deflat
@cc -c -q trees
@cc -c -q crypt
@cc -c -q ttyio
@cc -c -q tops20
-@cc -i -o zip zip.rel zipfil.rel zipup.rel fileio.rel util.rel crc32.rel crctab.rel global.rel deflat.rel trees.rel crypt.rel ttyio.rel tops20.rel
+@cc -i -o zip zip.rel zipfil.rel zipup.rel fileio.rel util.rel crc32.rel global.rel deflat.rel trees.rel crypt.rel ttyio.rel tops20.rel
@cc -c -q zipnot
@rename zipfil.c zipfix.c
@rename fileio.c filiox.c
diff --git a/tops20/osdep.h b/tops20/osdep.h
index 1f84496..c750c2d 100644
--- a/tops20/osdep.h
+++ b/tops20/osdep.h
@@ -1,17 +1,17 @@
/*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 1999-Oct-05 or later
+ 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, both of these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+ 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 TOPS20
#define TOPS20
#endif
#define NO_PROTO
-#define NO_SYMLINK
+#define NO_SYMLINKS
#define NO_TERMIO
#define DIRENT
#define BIG_MEM
diff --git a/tops20/tops20.c b/tops20/tops20.c
index 7230ed3..a2b63e7 100644
--- a/tops20/tops20.c
+++ b/tops20/tops20.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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.info-zip.org/pub/infozip/license.html
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
#include "zip.h"
@@ -422,8 +422,9 @@ iztimes *t; /* return value: access, modific. and creation times */
a file size of -1 */
{
struct stat s; /* results of stat() */
+ /* converted from FNAMX to malloc - 11/8/04 EG */
char *name;
- unsigned int len = strlen(f);
+ int len = strlen(f);
if (f == label) {
if (a != NULL)
@@ -434,11 +435,9 @@ iztimes *t; /* return value: access, modific. and creation times */
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';
@@ -449,13 +448,14 @@ iztimes *t; /* return value: access, modific. and creation times */
free(name);
error("fstat(stdin)");
}
- } else if (LSSTAT(name, &s) != 0)
+ } 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);
@@ -471,8 +471,6 @@ iztimes *t; /* return value: access, modific. and creation times */
t->ctime = s.st_ctime;
}
- free(name);
-
return unix2dostime(&s.st_mtime);
}
diff --git a/trees.c b/trees.c
index 094b2bf..aefe639 100644
--- a/trees.c
+++ b/trees.c
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ trees.h - Zip 3
- See the accompanying file LICENSE, version 2005-February-10 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*
@@ -79,7 +81,7 @@
* void ct_tally (int dist, int lc);
* Save the match info and tally the frequency counts.
*
- * ulg flush_block (char *buf, ulg stored_len, int eof)
+ * uzoff_t flush_block (char *buf, ulg stored_len, int eof)
* Determine the best encoding for the current block: dynamic trees,
* static trees or store, and output the encoded block to the zip
* file. Returns the total compressed length for the file so far.
@@ -115,8 +117,12 @@
*/
#define __TREES_C
-#include <ctype.h>
+/* Put zip.h first as when using 64-bit file environment in unix ctype.h
+ defines off_t and then while other files are using an 8-byte off_t this
+ file gets a 4-byte off_t. Once zip.h sets the large file defines can
+ then include ctype.h and get 8-byte off_t. 8/14/04 EG */
#include "zip.h"
+#include <ctype.h>
#ifndef USE_ZLIB
@@ -327,11 +333,13 @@ local uch flag_bit; /* current bit used in flags */
local ulg opt_len; /* bit length of current block with optimal trees */
local ulg static_len; /* bit length of current block with static trees */
-local ulg cmpr_bytelen; /* total byte length of compressed file */
-local ulg cmpr_len_bits; /* number of bits past 'cmpr_bytelen' */
+/* zip64 support 08/29/2003 R.Nausedat */
+/* now all file sizes and offsets are zoff_t 7/24/04 EG */
+local uzoff_t cmpr_bytelen; /* total byte length of compressed file */
+local ulg cmpr_len_bits; /* number of bits past 'cmpr_bytelen' */
#ifdef DEBUG
-local ulg input_len; /* total byte length of input file */
+local uzoff_t input_len; /* total byte length of input file */
/* input_len is for debugging only since we can get it by other means. */
#endif
@@ -405,8 +413,8 @@ unsigned out_size;
}
#ifdef DEBUG
-local ulg bits_sent; /* bit length of the compressed data */
-extern ulg isize; /* byte length of input file */
+local uzoff_t bits_sent; /* bit length of the compressed data */
+extern uzoff_t isize; /* byte length of input file */
#endif
extern long block_start; /* window offset of current block */
@@ -442,7 +450,7 @@ local void copy_block OF((char *buf, unsigned len, int header));
#else /* DEBUG */
# define send_code(c, tree) \
- { if (verbose>1) fprintf(stderr,"\ncd %3d ",(c)); \
+ { if (verbose>1) fprintf(mesg,"\ncd %3d ",(c)); \
send_bits(tree[c].Code, tree[c].Len); }
#endif
@@ -473,9 +481,10 @@ void ct_init(attr, method)
file_type = attr;
file_method = method;
- cmpr_bytelen = cmpr_len_bits = 0L;
+ cmpr_len_bits = 0L;
+ cmpr_bytelen = (uzoff_t)0;
#ifdef DEBUG
- input_len = 0L;
+ input_len = (uzoff_t)0;
#endif
if (static_dtree[0].Len != 0) return; /* ct_init already called */
@@ -813,7 +822,7 @@ local void build_tree(desc)
tree[n].Dad = tree[m].Dad = (ush)node;
#ifdef DUMP_BL_TREE
if (tree == bl_tree) {
- fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+ fprintf(mesg,"\nnode %d(%d), sons %d(%d) %d(%d)",
node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
}
#endif
@@ -984,13 +993,16 @@ local void send_all_trees(lcodes, dcodes, blcodes)
Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
send_bits(bl_tree[bl_order[rank]].Len, 3);
}
- Tracev((stderr, "\nbl tree: sent %ld", bits_sent));
+ Tracev((stderr, "\nbl tree: sent %s",
+ zip_fuzofft(bits_sent, NULL, NULL)));
send_tree((ct_data near *)dyn_ltree, lcodes-1); /* send the literal tree */
- Tracev((stderr, "\nlit tree: sent %ld", bits_sent));
+ Tracev((stderr, "\nlit tree: sent %s",
+ zip_fuzofft(bits_sent, NULL, NULL)));
send_tree((ct_data near *)dyn_dtree, dcodes-1); /* send the distance tree */
- Tracev((stderr, "\ndist tree: sent %ld", bits_sent));
+ Tracev((stderr, "\ndist tree: sent %ld",
+ zip_fuzofft(bits_sent, NULL, NULL)));
}
/* ===========================================================================
@@ -998,7 +1010,8 @@ local void send_all_trees(lcodes, dcodes, blcodes)
* trees or store, and output the encoded block to the zip file. This function
* returns the total compressed length (in bytes) for the file so far.
*/
-ulg flush_block(buf, stored_len, eof)
+/* zip64 support 08/29/2003 R.Nausedat */
+uzoff_t flush_block(buf, stored_len, eof)
char *buf; /* input block, or NULL if too old */
ulg stored_len; /* length of input block */
int eof; /* true if this is the last block for a file */
@@ -1045,10 +1058,12 @@ ulg flush_block(buf, stored_len, eof)
*/
#ifdef FORCE_METHOD
if (level == 1 && eof && file_method != NULL &&
- cmpr_bytelen == 0L && cmpr_len_bits == 0L) { /* force stored file */
+ cmpr_bytelen == (uzoff_t)0 && cmpr_len_bits == 0L
+ ) { /* force stored file */
#else
if (stored_len <= opt_lenb && eof && file_method != NULL &&
- cmpr_bytelen == 0L && cmpr_len_bits == 0L && seekable()) {
+ cmpr_bytelen == (uzoff_t)0 && cmpr_len_bits == 0L &&
+ seekable() && !use_descriptors) {
#endif
/* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */
if (buf == NULL) error ("block vanished");
@@ -1114,8 +1129,9 @@ ulg flush_block(buf, stored_len, eof)
bi_windup();
cmpr_len_bits += 7; /* align on byte boundary */
}
- Tracev((stderr,"\ncomprlen %lu(%lu) ", cmpr_bytelen + (cmpr_len_bits>>3),
- (cmpr_bytelen << 3) + cmpr_len_bits - 7*eof));
+ Tracev((stderr,"\ncomprlen %s(%s) ",
+ zip_fuzofft( cmpr_bytelen + (cmpr_len_bits>>3), NULL, NULL),
+ zip_fuzofft( (cmpr_bytelen << 3) + cmpr_len_bits - 7*eof, NULL, NULL)));
Trace((stderr, "\n"));
return cmpr_bytelen + (cmpr_len_bits >> 3);
@@ -1252,7 +1268,7 @@ local void set_file_type()
* set bits 0..6, 14..25, and 28..31
* 0xf3ffc07f = binary 11110011111111111100000001111111
*/
- unsigned long mask = 0xf3ffc07fUL;
+ unsigned long mask = 0xf3ffc07fL;
int n;
/* Check for non-textual ("black-listed") bytes. */
@@ -1295,7 +1311,7 @@ void bi_init (tgt_buf, tgt_size, flsh_allowed)
bi_buf = 0;
bi_valid = 0;
#ifdef DEBUG
- bits_sent = 0L;
+ bits_sent = (uzoff_t)0;
#endif
}
@@ -1311,7 +1327,7 @@ local void send_bits(value, length)
#ifdef DEBUG
Tracevv((stderr," l %2d v %4x ", length, value));
Assert(length > 0 && length <= 15, "invalid length");
- bits_sent += (ulg)length;
+ bits_sent += (uzoff_t)length;
#endif
/* If not enough room in bi_buf, use (bi_valid) bits from bi_buf and
* (Buf_size - bi_valid) bits from value to flush the filled bi_buf,
@@ -1368,6 +1384,43 @@ local void bi_windup()
/* ===========================================================================
* Copy a stored block to the zip file, storing first the length and its
* one's complement if requested.
+ *
+ * Buffer Overwrite fix
+ *
+ * A buffer flush has been added to fix a bug when encrypting deflated files
+ * with embedded "copied blocks". When encrypting, the flush_out() routine
+ * modifies its data buffer because encryption is done "in-place" in
+ * zfwrite(), whereas without encryption, the flush_out() data buffer is
+ * left unaltered. This can be a problem as noted below by the submitter.
+ *
+ * "But an exception comes when a block of stored data (data that could not
+ * be compressed) is being encrypted. In this case, the data that is passed
+ * to zfwrite (and is therefore encrypted-in-place) is actually a block of
+ * data from within the sliding input window that is being managed by
+ * deflate.c.
+ *
+ * "Since part of the sliding input window has now been overwritten by
+ * encrypted (and essentially random) data, deflate.c's search for previous
+ * text that matches the current text will usually fail but on rare
+ * occasions will find a match with something in the encrypted data. This
+ * incorrect match then causes incorrect information to be placed in the
+ * ZIP file."
+ *
+ * The problem results in the zip file having bad data and so a bad CRC.
+ * This does not happen often and to recreate the problem a large file
+ * with non-compressable data is needed so that deflate chooses to store the
+ * data. A test file of 400 MB seems large enough to recreate the problem
+ * using a command such as
+ * zip -1 -e crcerror.zip testfile.dat
+ * maybe half the time.
+ *
+ * This problem has been fixed by copying the data into the deflate output
+ * buffer before calling flush_outbuf(), when encryption is enabled.
+ *
+ * Thanks to the nice people at WinZip for identifying the problem and
+ * passing it on. Also see Changes.
+ *
+ * 2006-03-06 EG, CS
*/
local void copy_block(block, len, header)
char *block; /* the input data */
@@ -1385,8 +1438,28 @@ local void copy_block(block, len, header)
}
if (flush_flg) {
flush_outbuf(out_buf, &out_offset);
- out_offset = len;
- flush_outbuf(block, &out_offset);
+ if (key != (char *)NULL) { /* key is the global password pointer */
+ /* Encryption modifies the data in the output buffer. But the
+ * copied input data must remain intact for further deflate
+ * string matching lookups. Therefore, the input data is
+ * copied into the compression output buffer for flushing
+ * to the compressed/encrypted output stream.
+ */
+ while(len > 0) {
+ out_offset = (len < out_size ? len : out_size);
+ memcpy(out_buf, block, out_offset);
+ block += out_offset;
+ len -= out_offset;
+ flush_outbuf(out_buf, &out_offset);
+ }
+ } else {
+ /* Without encryption, the output routines do not touch the
+ * written data, so there is no need for an additional copy
+ * operation.
+ */
+ out_offset = len;
+ flush_outbuf(block, &out_offset);
+ }
} else if (out_offset + len > out_size) {
error("output buffer too small for in-memory compression");
} else {
diff --git a/ttyio.c b/ttyio.c
index e40fade..5899fdc 100644
--- a/ttyio.c
+++ b/ttyio.c
@@ -1,9 +1,11 @@
/*
+ ttyio.c - Zip 3
+
Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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
+ 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
*/
/*---------------------------------------------------------------------------
@@ -18,8 +20,8 @@
Contains: echo() (VMS only)
Echon() (Unix only)
Echoff() (Unix only)
- screenlines() (Unix only)
- zgetch() (Unix and non-Unix versions)
+ screensize() (Unix only)
+ zgetch() (Unix, VMS, and non-Unix/VMS versions)
getp() ("PC," Unix/Atari/Be, VMS/VMCMS/MVS)
---------------------------------------------------------------------------*/
@@ -50,11 +52,7 @@
# define GLOBAL(g) G.g
#endif
-#ifdef __BEOS__ /* why yes, we do */
-# define HAVE_TERMIOS_H
-#endif
-
-#ifdef __ATHEOS__
+#if (defined(__ATHEOS__) || defined(__BEOS__)) /* why yes, we do */
# define HAVE_TERMIOS_H
#endif
@@ -182,6 +180,10 @@
#ifndef HAVE_WORKING_GETCH
#ifdef VMS
+static struct dsc$descriptor_s DevDesc =
+ {11, DSC$K_DTYPE_T, DSC$K_CLASS_S, "SYS$COMMAND"};
+ /* {dsc$w_length, dsc$b_dtype, dsc$b_class, dsc$a_pointer}; */
+
/*
* Turn keyboard echoing on or off (VMS). Loosely based on VMSmunch.c
* and hence on Joe Meadows' file.c code.
@@ -200,13 +202,9 @@ int echo(opt)
* Greg Roelofs, 15 Aug 91
*/
- /* SKM: make global? */
- static struct dsc$descriptor_s DevDesc =
- {11, DSC$K_DTYPE_T, DSC$K_CLASS_S, "SYS$COMMAND"};
- /* {dsc$w_length, dsc$b_dtype, dsc$b_class, dsc$a_pointer}; */
- static short DevChan, iosb[4];
- static long status;
- static unsigned long oldmode[2], newmode[2]; /* each = 8 bytes */
+ short DevChan, iosb[4];
+ long status;
+ unsigned long ttmode[2]; /* space for 8 bytes */
/* assign a channel to standard input */
@@ -219,26 +217,24 @@ int echo(opt)
* instead, but echo on/off will be more general)
*/
status = sys$qiow(0, DevChan, IO$_SENSEMODE, &iosb, 0, 0,
- oldmode, 8, 0, 0, 0, 0);
+ ttmode, 8, 0, 0, 0, 0);
if (!(status & 1))
return status;
status = iosb[0];
if (!(status & 1))
return status;
- /* copy old mode into new-mode buffer, then modify to be either NOECHO or
- * ECHO (depending on function argument opt)
+ /* modify mode buffer to be either NOECHO or ECHO
+ * (depending on function argument opt)
*/
- newmode[0] = oldmode[0];
- newmode[1] = oldmode[1];
if (opt == 0) /* off */
- newmode[1] |= TT$M_NOECHO; /* set NOECHO bit */
+ ttmode[1] |= TT$M_NOECHO; /* set NOECHO bit */
else
- newmode[1] &= ~((unsigned long) TT$M_NOECHO); /* clear NOECHO bit */
+ ttmode[1] &= ~((unsigned long) TT$M_NOECHO); /* clear NOECHO bit */
/* use the IO$_SETMODE function to change the tty status */
status = sys$qiow(0, DevChan, IO$_SETMODE, &iosb, 0, 0,
- newmode, 8, 0, 0, 0, 0);
+ ttmode, 8, 0, 0, 0, 0);
if (!(status & 1))
return status;
status = iosb[0];
@@ -255,6 +251,42 @@ int echo(opt)
} /* end function echo() */
+/*
+ * Read a single character from keyboard in non-echoing mode (VMS).
+ * (returns EOF in case of errors)
+ */
+int tt_getch()
+{
+ short DevChan, iosb[4];
+ long status;
+ char kbbuf[16]; /* input buffer with - some - excess length */
+
+ /* assign a channel to standard input */
+ status = sys$assign(&DevDesc, &DevChan, 0, 0);
+ if (!(status & 1))
+ return EOF;
+
+ /* read a single character from SYS$COMMAND (no-echo) and
+ * wait for completion
+ */
+ status = sys$qiow(0,DevChan,
+ IO$_READVBLK|IO$M_NOECHO|IO$M_NOFILTR,
+ &iosb, 0, 0,
+ &kbbuf, 1, 0, 0, 0, 0);
+ if ((status&1) == 1)
+ status = iosb[0];
+
+ /* deassign the sys$input channel by way of clean-up
+ * (for this step, we do not need to check the completion status)
+ */
+ sys$dassgn(DevChan);
+
+ /* return the first char read, or EOF in case the read request failed */
+ return (int)(((status&1) == 1) ? (uch)kbbuf[0] : EOF);
+
+} /* end function tt_getch() */
+
+
#else /* !VMS: basically Unix */
@@ -302,7 +334,7 @@ void Echon(__G)
#if (defined(UNZIP) && !defined(FUNZIP))
-#if (defined(UNIX) || defined(__BEOS__) || defined(__ATHEOS__))
+#ifdef ATH_BEO_UNX
#ifdef MORE
/*
@@ -315,7 +347,9 @@ void Echon(__G)
#if (defined(TIOCGWINSZ) && !defined(M_UNIX))
-int screenlines()
+int screensize(tt_rows, tt_cols)
+ int *tt_rows;
+ int *tt_cols;
{
struct winsize wsz;
#ifdef DEBUG_WINSZ
@@ -327,40 +361,69 @@ int screenlines()
#ifdef DEBUG_WINSZ
if (firsttime) {
firsttime = FALSE;
- fprintf(stderr, "ttyio.c screenlines(): ws_row = %d\n",
+ fprintf(stderr, "ttyio.c screensize(): ws_row = %d\n",
wsz.ws_row);
+ fprintf(stderr, "ttyio.c screensize(): ws_col = %d\n",
+ wsz.ws_col);
}
#endif
- /* number of columns = ws_col */
- return (wsz.ws_row > 0)? wsz.ws_row : 24; /* number of rows */
-
+ /* number of rows */
+ if (tt_rows != NULL)
+ *tt_rows = (int)((wsz.ws_row > 0) ? wsz.ws_row : 24);
+ /* number of columns */
+ if (tt_cols != NULL)
+ *tt_cols = (int)((wsz.ws_col > 0) ? wsz.ws_col : 80);
+ return 0; /* signal success */
} else { /* this happens when piping to more(1), for example */
#ifdef DEBUG_WINSZ
if (firsttime) {
firsttime = FALSE;
fprintf(stderr,
- "ttyio.c screenlines(): ioctl(TIOCGWINSZ) failed\n"));
+ "ttyio.c screensize(): ioctl(TIOCGWINSZ) failed\n"));
}
#endif
- return 24; /* VT-100 assumed to be minimal hardware */
+ /* VT-100 assumed to be minimal hardware */
+ if (tt_rows != NULL)
+ *tt_rows = 24;
+ if (tt_cols != NULL)
+ *tt_cols = 80;
+ return 1; /* signal failure */
}
}
#else /* !TIOCGWINSZ: service not available, fall back to semi-bogus method */
-int screenlines()
+int screensize(tt_rows, tt_cols)
+ int *tt_rows;
+ int *tt_cols;
{
char *envptr, *getenv();
int n;
+ int errstat = 0;
/* GRR: this is overly simplistic, but don't have access to stty/gtty
* system anymore
*/
- envptr = getenv("LINES");
- if (envptr == (char *)NULL || (n = atoi(envptr)) < 5)
- return 24; /* VT-100 assumed to be minimal hardware */
- else
- return n;
+ if (tt_rows != NULL) {
+ envptr = getenv("LINES");
+ if (envptr == (char *)NULL || (n = atoi(envptr)) < 5) {
+ /* VT-100 assumed to be minimal hardware */
+ *tt_rows = 24;
+ errstat = 1; /* signal failure */
+ } else {
+ *tt_rows = n;
+ }
+ }
+ if (tt_cols != NULL) {
+ envptr = getenv("COLUMNS");
+ if (envptr == (char *)NULL || (n = atoi(envptr)) < 5) {
+ *tt_cols = 80;
+ errstat = 1; /* signal failure */
+ } else {
+ *tt_cols = n;
+ }
+ }
+ return errstat;
}
#endif /* ?(TIOCGWINSZ && !M_UNIX) */
@@ -407,11 +470,12 @@ int zgetch(__G__ f)
STTY(f, &sg); /* restore canonical mode */
GLOBAL(echofd) = -1;
- return (int)c;
+ return (int)(uch)c;
}
-#else /* !UNIX && !__BEOS__ */
+#else /* !ATH_BEO_UNX */
+#ifndef VMS /* VMS supplies its own variant of getch() */
int zgetch(__G__ f)
@@ -436,7 +500,8 @@ int zgetch(__G__ f)
return (int)c;
}
-#endif /* ?(UNIX || __BEOS__) */
+#endif /* !VMS */
+#endif /* ?ATH_BEO_UNX */
#endif /* UNZIP && !FUNZIP */
#endif /* !HAVE_WORKING_GETCH */
@@ -521,7 +586,7 @@ char *getp(__G__ m, p, n)
#else /* !HAVE_WORKING_GETCH */
-#if (defined(UNIX) || defined(__MINT__) || defined(__BEOS__) || defined(__ATHEOS__))
+#if (defined(ATH_BEO_UNX) || defined(__MINT__))
#ifndef _PATH_TTY
# ifdef __MINT__
@@ -578,7 +643,7 @@ char *getp(__G__ m, p, n)
} /* end function getp() */
-#endif /* UNIX || __MINT__ || __BEOS__ || __ATHEOS__ */
+#endif /* ATH_BEO_UNX || __MINT__ */
diff --git a/ttyio.h b/ttyio.h
index ba281cf..df6a4ed 100644
--- a/ttyio.h
+++ b/ttyio.h
@@ -1,9 +1,11 @@
/*
+ ttyio.h - Zip 3
+
Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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
+ 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
*/
/*
@@ -58,6 +60,12 @@
# endif
#endif
+#if (defined(__ATHEOS__) || defined(__BEOS__) || defined(UNIX))
+# ifndef ATH_BEO_UNX
+# define ATH_BEO_UNX
+# endif
+#endif
+
#if (defined(VM_CMS) || defined(MVS))
# ifndef CMS_MVS
# define CMS_MVS
@@ -176,7 +184,10 @@
#ifdef VMS
# define echoff(f) echo(0)
# define echon() echo(1)
+# define getch() tt_getch()
+# define FGETCH(f) tt_getch()
int echo OF((int));
+ int tt_getch OF((void));
#endif
/* For all other systems, ttyio.c supplies the two functions Echoff() and
diff --git a/unix/Makefile b/unix/Makefile
index e1780a0..abd0c44 100644
--- a/unix/Makefile
+++ b/unix/Makefile
@@ -4,24 +4,29 @@
all:
@echo ''
@echo 'Make what? You must say what system to make Zip for--e.g.'
- @echo '"make generic". Choices: generic, generic_gcc,'
- @echo 'att6300nodir, coherent, cray_v3, cygwin, lynx, minix,'
- @echo 'os390, qnx, qnxnto, solaris, solaris_gcc'
+ @echo '"make generic".'
+ @echo 'Choices: generic, generic_gcc, att6300nodir,'
+ @echo 'coherent, cray_v3, cygwin, lynx, minix, os390,'
+ @echo 'qnx, qnxnto, solaris, solaris_gcc'
+ @echo 'Try first "make -f unix/Makefile generic" as'
+ @echo 'it should autodetect and set the proper flags.'
+ @echo 'To make the manuals use "make zipsman" after Zip is made.'
@echo 'See the files INSTALL and zip.txt for more information.'
@echo ''
list: all
-MAKE = make -f unix/Makefile
+#MAKE = make -f unix/Makefile
+MAKEF = -f unix/Makefile
SHELL = /bin/sh
LN = ln -s
-# (to use the Gnu compiler, change cc to gcc in CC)
+# (to use the GNU compiler, change cc to gcc in CC)
CC = cc
BIND = $(CC)
AS = $(CC) -c
CPP = /lib/cpp
-EXE =
+E =
# probably can change this to 'install' if you have it
INSTALL_PROGRAM = cp
@@ -35,28 +40,38 @@ MANFLAGS = 644
# target directories - where to install executables and man pages to
prefix = /usr/local
BINDIR = $(prefix)/bin
-manext=1
-MANDIR = $(prefix)/man/man$(manext)
-ZIPMANUAL = MANUAL
+MANEXT=1
+MANDIR = $(prefix)/man/man$(MANEXT)
+ZIPMANUAL = zip.txt
+ZIPMANUALcloak = zipcloak.txt
+ZIPMANUALnote = zipnote.txt
+ZIPMANUALsplit = zipsplit.txt
+ZIPMANUALs = zip.txt zipcloak.txt zipnote.txt zipsplit.txt
PKGDIR = IZzip
-VERSION = Version 2.31
+VERSION = Version 3.0
+
+# Our bzip2 directory
+IZ_OUR_BZIP2_DIR = bzip2
# flags
# CFLAGS flags for C compile
# LFLAGS1 flags after output file spec, before obj file list
# LFLAGS2 flags after obj file list (libraries, etc)
-CFLAGS = -O2 -I. -DUNIX $(LOCAL_ZIP)
+CFLAGS_NOOPT = -I. -DUNIX $(LOCAL_ZIP)
+CFLAGS = -O2 $(CFLAGS_NOOPT)
LFLAGS1 =
LFLAGS2 = -s
# object file lists
OBJZ = zip.o zipfile.o zipup.o fileio.o util.o globals.o crypt.o ttyio.o \
- unix.o crc32.o crctab.o
+ unix.o crc32.o zbz2err.o
OBJI = deflate.o trees.o
OBJA =
-OBJU = zipfile_.o fileio_.o util_.o globals.o unix_.o
+OCRCU8 =
+OCRCTB = crc32_.o
+OBJU = zipfile_.o fileio_.o util_.o globals.o unix_.o $(OCRCU8)
OBJN = zipnote.o $(OBJU)
-OBJC = zipcloak.o $(OBJU) crctab.o crypt_.o ttyio.o
+OBJC = zipcloak.o $(OBJU) $(OCRCTB) crypt_.o ttyio.o
OBJS = zipsplit.o $(OBJU)
ZIP_H = zip.h ziperr.h tailor.h unix/osdep.h
@@ -65,21 +80,22 @@ ZIP_H = zip.h ziperr.h tailor.h unix/osdep.h
.SUFFIXES:
.SUFFIXES: _.o .o .c .doc .1
.c_.o:
- rm -f $*_.c; $(LN) $< $*_.c
- $(CC) -c $(CFLAGS) -DUTIL $*_.c
- rm -f $*_.c
+ $(CC) -c $(CFLAGS) -DUTIL -o $@ $<
+
.c.o:
$(CC) -c $(CFLAGS) $<
.1.doc:
nroff -man $< | col -bx | uniq > $@
-# rules for zip, zipnote, zipcloak, zipsplit, and the Zip MANUAL.
+# rules for zip, zipnote, zipcloak, zipsplit, and the Zip MANUALs.
$(OBJZ): $(ZIP_H)
$(OBJI): $(ZIP_H)
$(OBJN): $(ZIP_H)
$(OBJS): $(ZIP_H)
$(OBJC): $(ZIP_H)
+zip.o zipup.o zipfile.o fileio.o crc32.o crypt.o: crc32.h
+zipcloak.o zipfile_.o fileio_.o crc32_.o crypt_.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
@@ -101,27 +117,43 @@ unix.o: unix/unix.c
$(CC) -c $(CFLAGS) unix/unix.c
unix_.o: unix/unix.c
- rm -f unix_.c; $(LN) unix/unix.c unix_.c
- $(CC) -c $(CFLAGS) -DUTIL unix_.c
- rm -f unix_.c
+ $(CC) -c $(CFLAGS) -DUTIL -o $@ unix/unix.c
-ZIPS = zip$(EXE) zipnote$(EXE) zipsplit$(EXE) zipcloak$(EXE)
+ZIPS = zip$E zipcloak$E zipnote$E zipsplit$E
zips: $(ZIPS)
-zipsman: $(ZIPS) $(ZIPMANUAL)
+zipsman: $(ZIPS) $(ZIPMANUALs)
-zip$(EXE): $(OBJZ) $(OBJI) $(OBJA)
- $(BIND) -o zip$(EXE) $(LFLAGS1) $(OBJZ) $(OBJI) $(OBJA) $(LFLAGS2)
-zipnote$(EXE): $(OBJN)
- $(BIND) -o zipnote$(EXE) $(LFLAGS1) $(OBJN) $(LFLAGS2)
-zipcloak$(EXE): $(OBJC)
- $(BIND) -o zipcloak$(EXE) $(LFLAGS1) $(OBJC) $(LFLAGS2)
-zipsplit$(EXE): $(OBJS)
- $(BIND) -o zipsplit$(EXE) $(LFLAGS1) $(OBJS) $(LFLAGS2)
+zip$E: $(OBJZ) $(OBJI) $(OBJA) $(LIB_BZ)
+ $(BIND) -o zip$E $(LFLAGS1) $(OBJZ) $(OBJI) $(OBJA) $(LFLAGS2)
+zipnote$E: $(OBJN)
+ $(BIND) -o zipnote$E $(LFLAGS1) $(OBJN) $(LFLAGS2)
+zipcloak$E: $(OBJC) $(OCRCTB)
+ $(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 -bx | uniq > $(ZIPMANUAL)
+$(ZIPMANUALcloak): man/zipcloak.1
+ nroff -man man/zipcloak.1 | col -bx | uniq > $(ZIPMANUALcloak)
+
+$(ZIPMANUALnote): man/zipnote.1
+ nroff -man man/zipnote.1 | col -bx | uniq > $(ZIPMANUALnote)
+
+$(ZIPMANUALsplit): man/zipsplit.1
+ nroff -man man/zipsplit.1 | col -bx | uniq > $(ZIPMANUALsplit)
+
+
+# bzip2 object library
+
+$(IZ_OUR_BZIP2_DIR)/libbz2.a : $(IZ_OUR_BZIP2_DIR)/Makefile
+ @echo "Building bzip2 object library..."
+ ( cd $(IZ_OUR_BZIP2_DIR); \
+ $(MAKE) CC="$(CC_BZ)" CFLAGS="$(CFLAGS_BZ)" libbz2.a )
+ @echo " bzip2 object library created."
+
# install
install: $(ZIPS)
@@ -129,15 +161,23 @@ install: $(ZIPS)
$(INSTALL_PROGRAM) $(ZIPS) $(BINDIR)
-cd $(BINDIR); $(CHMOD) $(BINFLAGS) $(ZIPS)
-$(INSTALL_D) $(MANDIR)
- $(INSTALL) man/zip.1 $(MANDIR)/zip.$(manext)
- $(CHMOD) $(MANFLAGS) $(MANDIR)/zip.$(manext)
+ $(INSTALL_PROGRAM) man/zip.1 $(MANDIR)/zip.$(MANEXT)
+ $(CHMOD) $(MANFLAGS) $(MANDIR)/zip.$(MANEXT)
+ $(INSTALL_PROGRAM) man/zipcloak.1 $(MANDIR)/zipcloak.$(MANEXT)
+ $(CHMOD) $(MANFLAGS) $(MANDIR)/zipcloak.$(MANEXT)
+ $(INSTALL_PROGRAM) man/zipnote.1 $(MANDIR)/zipnote.$(MANEXT)
+ $(CHMOD) $(MANFLAGS) $(MANDIR)/zipnote.$(MANEXT)
+ $(INSTALL_PROGRAM) man/zipsplit.1 $(MANDIR)/zipsplit.$(MANEXT)
+ $(CHMOD) $(MANFLAGS) $(MANDIR)/zipsplit.$(MANEXT)
uninstall:
-cd $(BINDIR); rm -f $(ZIPS)
- -cd $(MANDIR); rm -f zip.$(manext)
+ -cd $(MANDIR); rm -f \
+ zip.$(MANEXT) zipcloak.$(MANEXT) zipnote.$(MANEXT) zipsplit.$(MANEXT)
+
flags: unix/configure
- sh unix/configure "${CC}" "${CFLAGS}"
+ sh unix/configure "${CC}" "${CFLAGS_NOOPT}" "${IZ_BZIP2}"
# These symbols, when #defined using -D have these effects on compilation:
# ZMEM - includes C language versions of memset(), memcpy(),
@@ -151,18 +191,22 @@ flags: unix/configure
# NO_RMDIR - remove directories using a system("rmdir ...") call.
# NO_PROTO - cannot handle ANSI prototypes
# NO_CONST - cannot handle ANSI const
+# NO_LARGE_FILE_SUPPORT - do not enable Large File support even if available.
+# NO_ZIP64_SUPPORT - do not enable Zip64 archive support even if available.
+# NO_UNICODE_SUPPORT - do not enable Unicode support even if available.
+# NO_BZIP2_SUPPORT - do not compile in bzip2 code even if available.
# Generic targets:
generic: flags
- eval $(MAKE) zips `cat flags`
+ eval $(MAKE) $(MAKEF) zips `cat flags`
generic_gcc:
- $(MAKE) generic CC=gcc CPP="gcc -E"
+ $(MAKE) $(MAKEF) generic CC=gcc CPP="gcc -E"
# AT&T 6300 PLUS (don't know yet how to allocate 64K bytes):
att6300nodir:
- $(MAKE) zips LFLAGS1="-Ml -s" \
+ $(MAKE) $(MAKEF) zips LFLAGS1="-Ml -s" \
CFLAGS="-DUNIX -I. -O -Ml -DNO_RMDIR -DDYN_ALLOC -DMEDIUM_MEM \
-DWSIZE=16384 -DNO_STDLIB_H -DNO_STDDEF_H -DNO_RENAME \
-DNO_MKTIME -DNO_SIZE_T -DNO_VOID -DNO_PROTO -DNO_DIR \
@@ -171,38 +215,41 @@ att6300nodir:
# Coherent (AS definition not needed for gcc)
coherent:
- $(MAKE) zips CFLAGS="-DUNIX -I. -O -DDIRENT -DASMV" AS="as -gx" \
- OBJA=match.o
+ $(MAKE) $(MAKEF) zips CFLAGS="-DUNIX -I. -O -DDIRENT -DASMV" \
+ AS="as -gx" OBJA=match.o
# Cray Unicos 6.1, Standard C compiler 3.0 (all routines except trees.c
# may be compiled with vector3; internal compiler bug in 3.0.2.3 and
# earlier requires vector2 for trees.c)
cray_v3:
- $(MAKE) zips CC="scc" \
+ $(MAKE) $(MAKEF) zips CC="scc" \
CFLAGS="-DUNIX -I. -O -h vector2 -h scalar3 -DHAVE_DIRENT_H"
# Cygwin
cygwin:
- $(MAKE) generic CC="gcc" CPP="gcc -E" EXE=".exe"
+ $(MAKE) $(MAKEF) generic CC="gcc" CPP="gcc -E" EXE=".exe"
# LynxOS
lynx:
- $(MAKE) generic CC=gcc CPP="gcc -E" CFLAGS="$(CFLAGS) -DNO_UNDERLINE -DLynx -DLYNX LFLAGS2="$LFLAGS2 -lc_p"
+ $(MAKE) $(MAKEF) generic CC=gcc CPP="gcc -E" CFLAGS="$(CFLAGS) \
+ -DNO_UNDERLINE -DLynx -DLYNX LFLAGS2="$LFLAGS2 -lc_p"
# MINIX 1.5.10 with Bruce Evans 386 patches and gcc/GNU make
minix:
- $(MAKE) zips CFLAGS="-DUNIX -I. -O -DDIRENT -DMINIX" CC=gcc
+ $(MAKE) $(MAKEF) zips CFLAGS="-DUNIX -I. -O -DDIRENT -DMINIX" CC=gcc
chmem =262144 zip
# IBM OS/390 (formerly MVS) compiled under "OpenEdition" shell
# You can make the zip executable with IBM's make, but you will
# get errors dealing with the _.o targets for the other executables
# (zipcloak, etc). GNU make will build all the executables.
-# If you have GNU make in your path as gmake, uncomment the following:
-#MAKE = gmake -f unix/Makefile
+# If you have GNU make in your path as gmake, you can uncomment
+# the following, but it shouldn't be needed:
+#MAKE = gmake
+
os390:
- ${MAKE} zips CFLAGS="$(CF) -I. -DUNIX -DOS390 -DEBCDIC -DSYSV \
--DSYSV -DNO_PARAM_H" LFLAGS2=""
+ $(MAKE) $(MAKEF) zips CFLAGS="$(CF) -I. -DUNIX -DOS390 -DEBCDIC \
+ -DSYSV -DNO_PARAM_H" LFLAGS2=""
# QNX is "special" because out /bin/sh is ksh and it doesn't grok the
# configure script properly, generating a bad flags file. D'oh! [cjh]
@@ -212,20 +259,20 @@ os390:
# to produce x86, PowerPC (big- or little-endian) and MIPS (big-
# or little-endian) using gcc. [cjh]
qnx:
- $(MAKE) zips LN=ln CC=cc CFLAGS="-DUNIX -I. -O -DHAVE_DIRENT_H \
--DHAVE_TERMIOS_H -DNO_MKTEMP"
+ $(MAKE) $(MAKEF) zips LN=ln CC=cc CFLAGS="-DUNIX -I. -O \
+ -DHAVE_DIRENT_H -DHAVE_TERMIOS_H -DNO_MKTEMP"
qnxnto:
@if [ "$(ARCH)" = "" ] ; then \
echo "You didn't set ARCH; I'll assume you meant ARCH=x86..." ; \
echo "" ; \
- $(MAKE) zips LN=ln CC="qcc -Vgcc_ntox86" \
+ $(MAKE) $(MAKEF) zips LN=ln CC="qcc -Vgcc_ntox86" \
CFLAGS="-g -DUNIX -I. -O -DHAVE_DIRENT_H -DHAVE_TERMIOS_H -DNO_MKTEMP" \
LFLAGS2=-g ; \
else \
echo "Making zip for $(ARCH)..." ; \
echo "" ; \
- $(MAKE) zips LN=ln CC="qcc -Vgcc_nto$(ARCH)" \
+ $(MAKE) $(MAKEF) zips LN=ln CC="qcc -Vgcc_nto$(ARCH)" \
CFLAGS="-g -DUNIX -I. -O -DHAVE_DIRENT_H -DHAVE_TERMIOS_H -DNO_MKTEMP" \
LFLAGS2=-g ; \
fi
@@ -266,3 +313,17 @@ clean:
rm -f *.o $(ZIPS) flags
rm -rf $(PKGDIR)
+clean_bzip2 :
+ @if test -f "$(IZ_OUR_BZIP2_DIR)/Makefile"; then \
+ ( cd $(IZ_OUR_BZIP2_DIR); make clean ); \
+ else \
+ if test -z "$(IZ_OUR_BZIP2_DIR)"; then \
+ echo "No bzip2 directory (\"IZ_OUR_BZIP2_DIR\") specified."; \
+ else \
+ echo "No bzip2 make file found: $(IZ_OUR_BZIP2_DIR)/Makefile."; \
+ fi; \
+ fi
+
+clean_exe :
+ rm -f $(ZIPS)
+#
diff --git a/unix/Packaging/pkginfo.in b/unix/Packaging/pkginfo.in
index 875e144..c31395d 100644
--- a/unix/Packaging/pkginfo.in
+++ b/unix/Packaging/pkginfo.in
@@ -2,8 +2,8 @@ PKG=IZzip
NAME=Info-ZIP Zip Utilities
CATEGORY=application
VENDOR=Info-ZIP
-EMAIL=Zip-Bugs@lists.wku.edu
-HOTLINE=Zip-Bugs@lists.wku.edu
+EMAIL=http://info-zip.org/zip-bug.html
+HOTLINE=http://info-zip.org/zip-bug.html
DESC=Copyrighted FREEWARE. See README, WHERE, and docs in pkg's doc dir.
CLASSES=none
BASEDIR=/opt/Info-ZIP
diff --git a/unix/Packaging/postinstall b/unix/Packaging/postinstall
index 030067d..086ec26 100755..100644
--- a/unix/Packaging/postinstall
+++ b/unix/Packaging/postinstall
@@ -1,22 +1,29 @@
#!/bin/sh
#
+# Info-ZIP Zip post-installation script.
+#
+# Last revised: 2007-09-29 SMS. Zip 3.0.
+#
# Post installation script (simply inform installer about PATH etc)
#
-echo " "
-echo " "
-echo "Installation is complete. Now, you should add the following"
-echo "(or equivalnet) commands to the appropriate initial user shell"
-echo "scripts (such as .profile, .login, etc) -- "
-echo " "
-echo " For korn or bourne shell:"
-echo " PATH=\${PATH}:${BASEDIR}/${PKG}/bin"
-echo " MANPATH=\${MANPATH}:${BASEDIR}/${PKG}/man"
-echo " export PATH MANPATH"
-echo " "
-echo " For C shell:"
-echo " set path=(\$path ${BASEDIR}/${PKG}/bin)"
-echo " setenv MANPATH \$MANPATH:${BASEDIR}/${PKG}/man"
-echo " "
-echo " See the files under ${BASEDIR}/${PKG}/doc for more information."
-echo " "
+echo ''
+echo 'Installation is complete. Users should adjust their environment'
+echo 'variables to include these directories:'
+echo " PATH: ${BASEDIR}/${PKG}/bin"
+echo " MANPATH: ${BASEDIR}/${PKG}/man"
+echo ''
+echo "Commands like the following may be added to a user's shell start-up"
+echo 'file (.cshrc, .login, .profile, ...) to do this:'
+echo ''
+echo ' For a Bourne-like shell:'
+echo " PATH=\"\${PATH}:${BASEDIR}/${PKG}/bin\""
+echo " MANPATH=\"\${MANPATH}:${BASEDIR}/${PKG}/man\""
+echo ' export PATH MANPATH'
+echo ''
+echo ' For a C shell:'
+echo " setenv PATH \"\${PATH}:${BASEDIR}/${PKG}/bin\""
+echo " setenv MANPATH \"\${MANPATH}:${BASEDIR}/${PKG}/man\""
+echo ''
+echo "See the files under ${BASEDIR}/${PKG}/doc for more information."
+echo ''
exit 0
diff --git a/unix/Packaging/preinstall.in b/unix/Packaging/preinstall.in
index 86c4b93..de1961b 100755..100644
--- a/unix/Packaging/preinstall.in
+++ b/unix/Packaging/preinstall.in
@@ -1,26 +1,29 @@
#!/bin/sh
-echo " "
-echo "REPORT ALL BUGS, PROBLEMS, AND ACCOLADES TO:"
-echo " "
-echo " Zip-Bugs@lists.wku.edu"
-echo " "
-echo "Checking architecture platform for .ARCH. ..."
+#
+# Info-ZIP Zip pre-installation script.
+#
+# Last revised: 2007-09-29 SMS. Zip 3.0.
+#
+# pkgadd should set a good PATH, but just in case, ...
+PATH="/sbin:/usr/bin:${PATH}"
+export PATH
+echo ''
+echo 'Please report problems to Info-ZIP using:'
+echo ''
+echo ' http://info-zip.org/zip-bug.html'
+echo ''
arch=`uname -p`
if [ "arch_${arch}" != "arch_.ARCH." ]; then
- echo " "
- echo "This product MUST be installed on a Solaris .ARCH. platform."
- echo "Your machine looks like it is a ${arch} platform."
- echo "Please install the version for the .ARCH. architecture."
- echo "Aborting the installation because of this. "
- echo " "
+ echo "This product MUST be installed on a Solaris \".ARCH.\" system."
+ echo "This system appears to have \"${arch}\" architecture, not \".ARCH.\"."
+ echo "Please install the version for the \".ARCH.\" architecture."
+ echo 'Aborting installation...'
returncode=1
- else
- echo " "
- echo "This product works on .ARCH., which you happen to have!"
- echo " "
+else
+ echo "Installing on \".ARCH.\" architecture..."
returncode=0
fi
-echo " "
-/usr/bin/sleep 4
+echo ''
+sleep 4
exit ${returncode:-1}
#
diff --git a/unix/Packaging/prototype b/unix/Packaging/prototype
index 10e48d8..002eaf6 100644
--- a/unix/Packaging/prototype
+++ b/unix/Packaging/prototype
@@ -1,22 +1,27 @@
d none $BASEDIR 0755 root bin
-d none $BASEDIR/$PKG 0755 root bin
+d none $PKG 0755 root bin
d none $PKG/doc 0755 root bin
f none $PKG/doc/BUGS=BUGS 0644 root bin
+f none $PKG/doc/CHANGES=CHANGES 0644 root bin
+f none $PKG/doc/INSTALL=INSTALL 0644 root bin
+f none $PKG/doc/LICENSE=LICENSE 0644 root bin
f none $PKG/doc/README=README 0644 root bin
f none $PKG/doc/TODO=TODO 0644 root bin
-f none $PKG/doc/WHERE=WHERE 0644 root bin
-f none $PKG/doc/CHANGES=CHANGES 0644 root bin
+f none $PKG/doc/USexport.msg=USexport.msg 0644 root bin
f none $PKG/doc/WHATSNEW=WHATSNEW 0644 root bin
-f none $PKG/doc/INSTALL=INSTALL 0644 root bin
-f none $PKG/doc/MANUAL=MANUAL 0644 root bin
+f none $PKG/doc/WHERE=WHERE 0644 root bin
+f none $PKG/doc/zip.txt=zip.txt 0644 root bin
d none $PKG/man 0755 root bin
d none $PKG/man/man1 0755 root bin
f none $PKG/man/man1/zip.1=man/zip.1 0644 root bin
+f none $PKG/man/man1/zipcloak.1=man/zipcloak.1 0644 root bin
+f none $PKG/man/man1/zipnote.1=man/zipnote.1 0644 root bin
+f none $PKG/man/man1/zipsplit.1=man/zipsplit.1 0644 root bin
d none $PKG/bin 0755 root bin
f none $PKG/bin/zip=zip 0755 root bin
+f none $PKG/bin/zipcloak=zipcloak 0755 root bin
f none $PKG/bin/zipnote=zipnote 0755 root bin
f none $PKG/bin/zipsplit=zipsplit 0755 root bin
-f none $PKG/bin/zipcloak=zipcloak 0755 root bin
i README
i pkginfo
i prototype
diff --git a/unix/configure b/unix/configure
index 35ccbb7..73ba803 100755..100644
--- a/unix/configure
+++ b/unix/configure
@@ -1,10 +1,15 @@
:
-#!/bin/sh
+#!/bin/sh -x
# The above : is necessary on some buggy systems.
# configure: Guess values for system-dependent variables
# Output the flag definitions to the file "flags".
-# Parameters: $1 = $CC, $2 = $CFLAGS
+#
+# Parameters: $1 = $CC, $2 = $CFLAGS, $3 = $IZ_BZIP2
+#
+# This file is typically called from Makefile rather than executed
+# from the command line.
+#
# To construct zip automatically using this file, type
# "make -f unix/Makefile generic".
# If this fails, then type "make list" to get a list of special targets.
@@ -12,10 +17,206 @@
trap "rm -f conftest* core a.out; exit 1" 1 2 3 15
CC=${1-cc}
-CFLAGS=${2-"-O2 -I. -DUNIX"}
-LFLAGS1=""
+CFLAGS=${2-"-I. -DUNIX"}
+LFLAGS1=''
+LFLAGS2=''
LN="ln -s"
+CFLAGS_OPT=''
+
+# bzip2
+IZ_BZIP2=${3-}
+CFLAGS_BZ=''
+
+
+echo 'Check C compiler type (optimization options)'
+# Sun C?
+cat > conftest.c << _EOF_
+int main()
+{
+#ifndef __SUNPRO_C
+ bad code
+#endif
+ return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
+if test $? -eq 0; then
+ CFLAGS_OPT='-xO3'
+ echo " Sun C ($CFLAGS_OPT)"
+else
+ # Tru64 DEC/Compaq/HP C?
+ cat > conftest.c << _EOF_
+int main()
+{
+#ifndef __DECC
+ bad code
+#endif
+ return 0;
+}
+_EOF_
+ $CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
+ if test $? -eq 0; then
+ CFLAGS_OPT='-O3'
+ echo " DEC C ($CFLAGS_OPT)"
+ else
+ # HP-UX HP C?
+ cat > conftest.c << _EOF_
+int main()
+{
+#ifdef __GNUC__
+ bad code
+#endif
+#ifndef __hpux
+ bad code
+#endif
+ return 0;
+}
+_EOF_
+ $CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
+ if test $? -eq 0; then
+ # HP-UX, not GCC. Lame bundled or real ANSI compiler?
+ CFLAGS_OPT_TRY="+O3 +Onolimit"
+ $CC $CFLAGS $CFLAGS_OPT_TRY -c conftest.c 2>&1 | \
+ grep '(Bundled)' > /dev/null
+ if test $? -ne 0; then
+ CFLAGS_OPT="$CFLAGS_OPT_TRY"
+ echo " HP-UX ANSI C ($CFLAGS_OPT)"
+ else
+ echo ' HP-UX Bundled C (no opt)'
+ fi
+ else
+ # GNU C?
+ cat > conftest.c << _EOF_
+int main()
+{
+#ifndef __GNUC__
+ bad code
+#endif
+ return 0;
+}
+_EOF_
+ $CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
+ if test $? -eq 0; then
+ CFLAGS_OPT='-O3'
+ echo " GNU C ($CFLAGS_OPT)"
+ # Special Mac OS X shared library "ld" option?
+ if test ` uname -s 2> /dev/null ` = 'Darwin'; then
+ lf='-Wl,-search_paths_first'
+ $CC $CFLAGS $lf conftest.c > /dev/null 2>/dev/null
+ if test $? -eq 0; then
+ LFLAGS2="${LFLAGS2} ${lf}"
+ fi
+ rm -f conftest
+ fi
+ else
+ CFLAGS_OPT='-O'
+ echo " Other-unknown C ($CFLAGS_OPT)"
+ fi
+ fi
+ fi
+fi
+
+# optimization flags
+if test -n "${CFLAGS_OPT}"; then
+ CFLAGS="${CFLAGS} ${CFLAGS_OPT}"
+ CFLAGS_BZ="${CFLAGS_BZ} ${CFLAGS_OPT}"
+fi
+
+
+# bzip2
+
+echo "Check bzip2 support"
+CC_BZ="${CC}"
+LIB_BZ=''
+if test -n "${IZ_BZIP2}"; then
+ echo " Check for bzip2 compiled library in IZ_BZIP2 (${IZ_BZIP2})"
+ if test -f "${IZ_BZIP2}/libbz2.a"; then
+#
+# A bzip2 library built with BZ_NO_STDIO should have an
+# unresolved external, "bz_internal_error". The default,
+# full-function library will not mention it.
+#
+ nm ${IZ_BZIP2}/libbz2.a | grep bz_internal_error > /dev/null
+ if test $? -eq 0; then
+ echo " Found bzip2 BZ_NO_STDIO library, ${IZ_BZIP2}/libbz2.a"
+ else
+ echo " Found bzip2 library, ${IZ_BZIP2}/libbz2.a,"
+ echo " but library not compiled with BZ_NO_STDIO"
+ echo " WARNING: We recommend using a bzip2 library compiled"
+ echo " with BZ_NO_STDIO defined for proper error handling"
+ echo " Please see the Zip installation instructions in bzip2/install.txt"
+ echo " Continuing anyway with standard bzip2 library..."
+ fi
+ if test -f "${IZ_BZIP2}/bzlib.h"; then
+ CFLAGS="${CFLAGS} -I${IZ_BZIP2} -DBZIP2_SUPPORT"
+ LFLAGS2="${LFLAGS2} -L${IZ_BZIP2} -lbz2"
+ echo "-- Found bzip2 library - linking in bzip2"
+ else
+ echo " ${IZ_BZIP2}/bzlib.h not found"
+ echo "-- Since IZ_BZIP2 defined, skipping OS and bzip2 dir checks - no bzip2"
+ fi
+ else
+ echo " ${IZ_BZIP2}/libbz2.a not found"
+ echo "-- Since IZ_BZIP2 defined, skipping OS and bzip2 checks - no bzip2"
+ fi
+else
+ echo " Check for bzip2 in bzip2 directory"
+ IZ_BZIP2=bzip2
+ if test -f "${IZ_BZIP2}/libbz2.a"; then
+ nm ${IZ_BZIP2}/libbz2.a | grep bz_internal_error > /dev/null
+ if test $? -eq 0; then
+ echo " Found bzip2 BZ_NO_STDIO library in bzip2 directory"
+ else
+ echo " Found bzip2 library in bzip2 directory,"
+ echo " but not built with the BZ_NO_STDIO option"
+ echo " WARNING: We recommend using a bzip2 library compiled"
+ echo " with BZ_NO_STDIO defined for proper error handling"
+ echo " Please see the Zip installation instructions"
+ echo " Continuing anyway with standard bzip2 library..."
+ fi
+ fi
+ if test -f "bzip2/bzlib.h" -a -f "bzip2/libbz2.a"; then
+ CFLAGS="${CFLAGS} -I${IZ_BZIP2} -DBZIP2_SUPPORT"
+ LFLAGS2="${LFLAGS2} -Lbzip2 -lbz2"
+ echo "-- Found bzip2 library - linking in bzip2"
+ else
+ if test -f "bzip2/bzlib.c" -a -f "bzip2/bzlib.h"; then
+ echo "-- No library, but found bzip2 source in bzip2 directory"
+ echo "-- Will try to build bzip2 library from source and link in"
+#
+# Arrange to build a BZ_NO_STDIO bzip2 object library using the
+# same compiler and optimization options as used for Zip, and
+# to compile and link Zip with bzip2.
+#
+ CFLAGS_BZ="${CFLAGS_BZ} -DBZ_NO_STDIO"
+ LIB_BZ="bzip2/libbz2.a"
+ CFLAGS="${CFLAGS} -Ibzip2 -DBZIP2_SUPPORT"
+ LFLAGS2="${LFLAGS2} -Lbzip2 -lbz2"
+ else
+ echo " Check if OS already has bzip2 library installed"
+ cat > conftest.c << _EOF_
+#include "bzlib.h"
+int main()
+{
+ bz_stream strm;
+ BZ2_bzCompressEnd(&strm);
+ return 0;
+}
+_EOF_
+ $CC $CFLAGS -o conftest conftest.c -lbz2 > /dev/null 2>/dev/null
+ if test $? -eq 0; then
+ echo "-- OS supports bzip2 - linking in bzip2"
+ CFLAGS="${CFLAGS} -DBZIP2_SUPPORT"
+ LFLAGS2="${LFLAGS2} -lbz2"
+ else
+ echo "-- Either bzlib.h or libbz2.a not found - no bzip2"
+ fi
+ fi
+ fi
+fi
+
+
echo Check for the C preprocessor
# on SVR4, cc -E does not produce correct assembler files. Need /lib/cpp.
CPP="${CC} -E"
@@ -30,8 +231,10 @@ CPP="${CC} -E"
echo "#include <stdio.h>" > conftest.c
$CPP conftest.c >/dev/null 2>/dev/null || CPP="${CC} -E"
+
echo Check if we can use asm code
OBJA=""
+OCRCU8=""
if eval "$CPP match.S > _match.s 2>/dev/null"; then
if test ! -s _match.s || grep error < _match.s > /dev/null; then
:
@@ -47,6 +250,7 @@ if eval "$CPP match.S > _match.s 2>/dev/null"; then
if eval "$CC -c _crc_i386.s >/dev/null 2>/dev/null" && [ -f _crc_i386.o ]
then
OBJA="$OBJA crc_i386.o"
+ OCRCU8="crc_i386.o"
CFLAGS="${CFLAGS} -DASM_CRC"
fi
fi
@@ -54,6 +258,7 @@ if eval "$CPP match.S > _match.s 2>/dev/null"; then
fi
rm -f _match.s _match.o _crc_i386.s _crc_i386.o
+
# ANSI options for compilers that don't have __STDC__ defined by default
# Currently HPUX, pyramid, Dynix, AIX, OSF/1 and ultrix
@@ -69,13 +274,14 @@ int main()
_EOF_
$CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
if [ $? -ne 0 ]; then
- for OPT in "-Aa -D_HPUX_SOURCE" -Xa -qlanglvl=ansi -std1 -std
+ for OPT in -Ae -Xa -qlanglvl=ansi -std1 -std
do
$CC $CFLAGS $OPT -c conftest.c > /dev/null 2>/dev/null
[ $? -eq 0 ] && CFLAGS="${CFLAGS} ${OPT}" && break
done
fi
+
echo Check for prototypes
echo "int main(int argc, char *argv[]) { return 0; }" > conftest.c
$CC $CFLAGS -c conftest.c > /dev/null 2>/dev/null
@@ -96,6 +302,7 @@ _EOF_
$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
[ $? -ne 0 ] && CFLAGS="${CFLAGS} -DNO_CONST"
+
echo Check for time_t
cat > conftest.c << _EOF_
#include <sys/types.h>
@@ -109,6 +316,7 @@ _EOF_
$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
[ $? -ne 0 ] && CFLAGS="${CFLAGS} -DNO_TIME_T"
+
echo Check for size_t
cat > conftest.c << _EOF_
#include <sys/types.h>
@@ -121,6 +329,167 @@ _EOF_
$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
[ $? -ne 0 ] && CFLAGS="${CFLAGS} -DNO_SIZE_T"
+
+echo Check for off_t
+cat > conftest.c << _EOF_
+#include <sys/types.h>
+int main()
+{
+ off_t s;
+ return 0;
+}
+_EOF_
+$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGS="${CFLAGS} -DNO_OFF_T"
+
+
+echo Check size of UIDs and GIDs
+echo "(Now zip stores variable size UIDs/GIDs using a new extra field. This"
+echo " tests if this OS uses 16-bit UIDs/GIDs and so if the old 16-bit storage"
+echo " should also be used for backward compatibility.)"
+# Added 2008-04-15 CS
+cat > conftest.c << _EOF_
+# define _LARGEFILE_SOURCE /* some OSes need this for fseeko */
+# define _LARGEFILE64_SOURCE
+# define _FILE_OFFSET_BITS 64 /* select default interface as 64 bit */
+# define _LARGE_FILES /* some OSes need this for 64-bit off_t */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+int main()
+{
+ struct stat s;
+
+ printf(" s.st_uid is %u bytes\n", sizeof(s.st_uid));
+ printf(" s.st_gid is %u bytes\n", sizeof(s.st_gid));
+
+ /* see if have 16-bit UID */
+ if (sizeof(s.st_uid) != 2) {
+ return 1;
+ }
+ /* see if have 16-bit GID */
+ if (sizeof(s.st_gid) != 2) {
+ return 2;
+ }
+ return 3;
+}
+_EOF_
+# compile it
+$CC -o conftest conftest.c >/dev/null 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo -- UID/GID test failed on compile - disabling old 16-bit UID/GID support
+ CFLAGS="${CFLAGS} -DUIDGID_NOT_16BIT"
+else
+# run it
+ ./conftest
+ r=$?
+ if [ $r -eq 1 ]; then
+ echo -- UID not 2 bytes - disabling old 16-bit UID/GID support
+ CFLAGS="${CFLAGS} -DUIDGID_NOT_16BIT"
+ elif [ $r -eq 2 ]; then
+ echo -- GID not 2 bytes - disabling old 16-bit UID/GID support
+ CFLAGS="${CFLAGS} -DUIDGID_NOT_16BIT"
+ elif [ $r -eq 3 ]; then
+ echo -- 16-bit UIDs and GIDs - keeping old 16-bit UID/GID support
+ else
+ echo -- test failed - conftest returned $r - disabling old 16-bit UID/GID support
+ CFLAGS="${CFLAGS} -DUIDGID_NOT_16BIT"
+ fi
+fi
+
+
+# Now we set the 64-bit file environment and check the size of off_t
+# Added 11/4/2003 EG
+# Revised 8/12/2004 EG
+
+echo Check for Large File Support
+cat > conftest.c << _EOF_
+# define _LARGEFILE_SOURCE /* some OSes need this for fseeko */
+# define _LARGEFILE64_SOURCE
+# define _FILE_OFFSET_BITS 64 /* select default interface as 64 bit */
+# define _LARGE_FILES /* some OSes need this for 64-bit off_t */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+int main()
+{
+ off_t offset;
+ struct stat s;
+ /* see if have 64-bit off_t */
+ if (sizeof(offset) < 8)
+ return 1;
+ printf(" off_t is %d bytes\n", sizeof(off_t));
+ /* see if have 64-bit stat */
+ if (sizeof(s.st_size) < 8) {
+ printf(" s.st_size is %d bytes\n", sizeof(s.st_size));
+ return 2;
+ }
+ return 3;
+}
+_EOF_
+# compile it
+$CC -o conftest conftest.c >/dev/null 2>/dev/null
+if [ $? -ne 0 ]; then
+ echo -- no Large File Support
+else
+# run it
+ ./conftest
+ r=$?
+ if [ $r -eq 1 ]; then
+ echo -- no Large File Support - no 64-bit off_t
+ elif [ $r -eq 2 ]; then
+ echo -- no Large File Support - no 64-bit stat
+ elif [ $r -eq 3 ]; then
+ echo -- yes we have Large File Support!
+ CFLAGS="${CFLAGS} -DLARGE_FILE_SUPPORT"
+ else
+ echo -- no Large File Support - conftest returned $r
+ fi
+fi
+
+
+# Check for wide char for Unicode support
+# Added 11/24/2005 EG
+
+echo Check for wide char support
+cat > conftest.c << _EOF_
+#include <stdlib.h>
+#include <stdio.h>
+int main()
+{
+ int wsize;
+ wchar_t *wide_string;
+
+ if ((wide_string = (wchar_t *)malloc(4 * sizeof(wchar_t))) == NULL) {
+ return 0;
+ }
+ /* get wide string */
+ wsize = mbstowcs(wide_string, "foo", 3);
+ wide_string[wsize] = (wchar_t) NULL;
+ return 1;
+}
+_EOF_
+# compile it
+$CC -o conftest conftest.c >/dev/null 2>/dev/null
+# OCRCU8 is used by all utilities if Unicode is enabled
+# OCRCTB is only used by zipcloak
+if [ $? -ne 0 ]; then
+ echo -- no Unicode support
+ OCRCU8=""
+ OCRCTB="crc32_.o"
+else
+# have wide char support
+ echo -- have wchar_t - enabling Unicode support
+ CFLAGS="${CFLAGS} -DUNICODE_SUPPORT"
+ OCRCU8="crc32_.o ${OCRCU8}"
+ OCRCTB=""
+fi
+
+
+# from configure 2.4i (Onno) 12/5/04
+
echo Check for gcc no-builtin flag
# -fno-builtin since version 2
cat > conftest.c << _EOF_
@@ -136,8 +505,10 @@ _EOF_
$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
[ $? -eq 0 ] && BFLAG="-fno-builtin"
+
# Check for missing functions
# add NO_'function_name' to flags if missing
+
for func in rmdir strchr strrchr rename mktemp mktime mkstemp
do
echo Check for $func
@@ -146,11 +517,30 @@ do
[ $? -ne 0 ] && CFLAGS="${CFLAGS} -DNO_`echo $func | tr '[a-z]' '[A-Z]'`"
done
+
echo Check for memset
echo "int main(){ char k; memset(&k,0,0); return 0; }" > conftest.c
$CC -o conftest conftest.c >/dev/null 2>/dev/null
[ $? -ne 0 ] && CFLAGS="${CFLAGS} -DZMEM"
+
+echo Check for memmove
+cat > conftest.c << _EOF_
+#include <string.h>
+int main() { int a; int b = 0; memmove( &a, &b, sizeof( a)); return a; }
+_EOF_
+$CC -o conftest conftest.c >/dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGS="${CFLAGS} -DNEED_MEMMOVE"
+
+
+echo Check for strerror
+cat > conftest.c << _EOF_
+#include <string.h>
+int main() { strerror( 0); return 0; }
+_EOF_
+$CC -o conftest conftest.c >/dev/null 2>/dev/null
+[ $? -ne 0 ] && CFLAGS="${CFLAGS} -DNEED_STRERROR"
+
echo Check for errno declaration
cat > conftest.c << _EOF_
#include <errno.h>
@@ -163,6 +553,7 @@ _EOF_
$CC $CFLAGS -c conftest.c >/dev/null 2>/dev/null
[ $? -ne 0 ] && CFLAGS="${CFLAGS} -DNO_ERRNO"
+
echo Check for directory libraries
cat > conftest.c << _EOF_
int main() { return closedir(opendir(".")); }
@@ -183,7 +574,9 @@ if [ $? -ne 0 ]; then
fi
fi
+
# Dynix/ptx 1.3 needed this
+
echo Check for readlink
echo "int main(){ return readlink(); }" > conftest.c
$CC -o conftest conftest.c >/dev/null 2>/dev/null
@@ -192,6 +585,7 @@ if [ $? -ne 0 ]; then
[ $? -eq 0 ] && LFLAGS2="${LFLAGS2} -lseq"
fi
+
echo Check for directory include file
OPT=""
for inc in dirent.h sys/ndir.h ndir.h sys/dir.h
@@ -202,7 +596,8 @@ do
done
CFLAGS="${CFLAGS} ${OPT}"
-echo Check for non existent include files
+
+echo Check for nonexistent include files
for inc in stdlib.h stddef.h unistd.h fcntl.h string.h
do
echo "#include <$inc>" > conftest.c
@@ -210,7 +605,8 @@ do
[ $? -ne 0 ] && CFLAGS="${CFLAGS} -DNO_`echo $inc | tr '[a-z]./' '[A-Z]__'`"
done
-echo Check for terminal I/O include file
+
+echo Check for term I/O include file
OPT=""
for inc in termios.h termio.h sgtty.h
do
@@ -220,7 +616,9 @@ do
done
CFLAGS="${CFLAGS} ${OPT}"
+
# needed for AIX (and others ?) when mmap is used
+
echo Check for valloc
cat > conftest.c << _EOF_
main()
@@ -230,23 +628,9 @@ main()
#endif
}
_EOF_
-$CC ${CFLAGS} conftest.c > /dev/null 2>/dev/null
+$CC ${CFLAGS} -c conftest.c > /dev/null 2>/dev/null
[ $? -ne 0 ] && CFLAGS="${CFLAGS} -DNO_VALLOC"
-echo Check for 64bit fseek
-for func in fseeko fseek64
-do
-cat > conftest.c << _EOF_
-#include <stdio.h>
-main()
-{
-$func(stdin, 0, 0);
-}
-_EOF_
-$CC ${CFLAGS} conftest.c > /dev/null 2>/dev/null
-[ $? -eq 0 ] && OPT="-DHAVE_`echo $func | tr '[a-z]' '[A-Z]'`" && break
-done
-CFLAGS="${CFLAGS} ${OPT}"
echo Check for /usr/local/bin and /usr/local/man
BINDIR=$HOME/bin
@@ -257,6 +641,7 @@ MANDIR=manl
[ -d /usr/local/man/manl ] && MANDIR=/usr/local/man/manl
[ -d /usr/local/man/man1 ] && MANDIR=/usr/local/man/man1
+
echo Check for OS-specific flags
if [ -f /usr/bin/hostinfo ]; then
if /usr/bin/hostinfo | grep NeXT > /dev/null; then
@@ -283,19 +668,28 @@ else
$CC ${CFLAGS} -Olimit 1000 -o conftest conftest.c >/dev/null 2>/dev/null
[ $? -eq 0 ] && CFLAGS="${CFLAGS} -Olimit 1000"
;;
- HP-UX)
- echo Check for +Onolimit option
- $CC ${CFLAGS} +Onolimit -o conftest conftest.c >/dev/null 2>/dev/null
- [ $? -eq 0 ] && CFLAGS="${CFLAGS} +Onolimit"
- ;;
+### HP-UX)
+### echo Check for +Onolimit option
+### $CC ${CFLAGS} +Onolimit -o conftest conftest.c >/dev/null 2>/dev/null
+### [ $? -eq 0 ] && CFLAGS="${CFLAGS} +Onolimit"
+### ;;
+### SunOS)
+### CFLAGS="${CFLAGS} -D_FILE_OFFSET_BITS=64"
+### ;;
esac
fi
+
echo Check for symbolic links
ln -s /dev/null null > /dev/null 2>/dev/null || LN=ln
+
rm -f a.out conftest.c conftest.o conftest null
echo CC=\"${CC}\" CFLAGS=\"${CFLAGS}\" CPP=\"${CPP}\" OBJA=\"${OBJA}\" \
+ OCRCU8=\"${OCRCU8}\" OCRCTB=\"${OCRCTB}\" \
BINDIR=${BINDIR} MANDIR=${MANDIR} LFLAGS1=\"${LFLAGS1}\" \
- LFLAGS2=\"${LFLAGS2}\" LN=\"${LN}\" > flags
+ LFLAGS2=\"${LFLAGS2}\" LN=\"${LN}\" \
+ CC_BZ=\"${CC_BZ}\" CFLAGS_BZ=\"${CFLAGS_BZ}\" \
+ IZ_BZIP2=\"${IZ_BZIP2}\" LIB_BZ=\"${LIB_BZ}\" > flags
+
diff --git a/unix/osdep.h b/unix/osdep.h
index bfb5d4d..10f8ee9 100644
--- a/unix/osdep.h
+++ b/unix/osdep.h
@@ -1,30 +1,77 @@
/*
+ unix/osdep.h - Zip 3
+
Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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/license.html
*/
+
+#ifdef NO_LARGE_FILE_SUPPORT
+# ifdef LARGE_FILE_SUPPORT
+# undef LARGE_FILE_SUPPORT
+# endif
+#endif
+
+#ifdef LARGE_FILE_SUPPORT
+ /* 64-bit Large File Support */
+
+ /* The following Large File Summit (LFS) defines turn on large file support on
+ Linux (probably 2.4 or later kernel) and many other unixen */
+
+# define _LARGEFILE_SOURCE /* some OSes need this for fseeko */
+# define _LARGEFILE64_SOURCE
+# define _FILE_OFFSET_BITS 64 /* select default interface as 64 bit */
+# define _LARGE_FILES /* some OSes need this for 64-bit off_t */
+#endif
+
#include <sys/types.h>
#include <sys/stat.h>
+/* printf format size prefix for zoff_t values */
+#ifdef LARGE_FILE_SUPPORT
+# define ZOFF_T_FORMAT_SIZE_PREFIX "ll"
+#else
+# define ZOFF_T_FORMAT_SIZE_PREFIX "l"
+#endif
+
+#ifdef NO_OFF_T
+ typedef long zoff_t;
+ typedef unsigned long uzoff_t;
+#else
+ typedef off_t zoff_t;
+# if defined(LARGE_FILE_SUPPORT) && !(defined(__alpha) && defined(__osf__))
+ typedef unsigned long long uzoff_t;
+# else
+ typedef unsigned long uzoff_t;
+# endif
+#endif
+ typedef struct stat z_stat;
-#ifdef __CYGWIN__
-/* File operations:
- * use "b" for binary;
- * use "S" for sequential access on NT to prevent the NT file cache
- * eating up memory with large .zip files.
- */
-# define FOPR "rb"
-# define FOPM "r+b"
-# define FOPW "wbS"
+/* Automatically set ZIP64_SUPPORT if LFS */
-/* Cygwin is not Win32. */
-# undef WIN32
+#ifdef LARGE_FILE_SUPPORT
+# ifndef NO_ZIP64_SUPPORT
+# ifndef ZIP64_SUPPORT
+# define ZIP64_SUPPORT
+# endif
+# else
+# ifdef ZIP64_SUPPORT
+# undef ZIP64_SUPPORT
+# endif
+# endif
+#endif
-#endif /* ?__CYGWIN__ */
+
+/* Process files in binary mode */
+#if defined(__DJGPP__) || defined(__CYGWIN__)
+# define FOPR "rb"
+# define FOPM "r+b"
+# define FOPW "wb"
+#endif
/* Enable the "UT" extra field (time info) */
diff --git a/unix/unix.c b/unix/unix.c
index 024b735..f4d655d 100644
--- a/unix/unix.c
+++ b/unix/unix.c
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ unix/unix.c - Zip 3
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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"
@@ -113,7 +115,7 @@ int caseflag; /* true to force case-sensitive match */
char *e; /* pointer to name from readd() */
int m; /* matched flag */
char *p; /* path for recursion */
- struct stat s; /* result of stat() */
+ z_stat s; /* result of stat() */
struct zlist far *z; /* steps through zfiles list */
if (strcmp(n, "-") == 0) /* if compressing stdin */
@@ -200,6 +202,24 @@ int caseflag; /* true to force case-sensitive match */
}
free((zvoid *)p);
} /* (s.st_mode & S_IFDIR) */
+#ifdef OS390
+ else if (S_ISFIFO(s.st_mode))
+#else
+ else if ((s.st_mode & S_IFIFO) == S_IFIFO)
+#endif
+ {
+ if (allow_fifo) {
+ /* FIFO (Named Pipe) - handle as normal file */
+ /* add or remove name of FIFO */
+ /* zip will stop if FIFO is open and wait for pipe to be fed and closed */
+ if (noisy) zipwarn("Reading FIFO (Named Pipe): ", n);
+ if ((m = newname(n, 0, caseflag)) != ZE_OK)
+ return m;
+ } else {
+ zipwarn("ignoring FIFO (Named Pipe) - use -FI to read: ", n);
+ return ZE_OK;
+ }
+ } /* S_IFIFO */
else
zipwarn("ignoring special file: ", n);
return ZE_OK;
@@ -216,7 +236,7 @@ int *pdosflag; /* output: force MSDOS file attributes? */
char *t = NULL; /* shortened name */
int dosflag;
- dosflag = dosify; /* default for non-DOS and non-OS/2 */
+ 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 */
@@ -247,18 +267,18 @@ int *pdosflag; /* output: force MSDOS file attributes? */
return NULL;
strcpy(n, t);
- if (isdir == 42) return n; /* avoid warning on unused variable */
-
if (dosify)
msname(n);
#ifdef EBCDIC
- strtoasc(n, n); /* here because msname() needs native coding */
+ strtoasc(n, n); /* here because msname() needs native coding */
#endif
/* Returned malloc'ed name */
if (pdosflag)
*pdosflag = dosflag;
+
+ if (isdir) return n; /* avoid warning on unused variable */
return n;
}
@@ -307,7 +327,7 @@ ulg d; /* dos-style time to change it to */
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 */
+ zoff_t *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
@@ -321,7 +341,7 @@ ulg filetime(f, a, n, t)
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() */
+ z_stat s; /* results of stat() */
/* converted to pointer from using FNMAX - 11/8/04 EG */
char *name;
int len = strlen(f);
@@ -343,7 +363,7 @@ ulg filetime(f, a, n, t)
name[len - 1] = '\0';
/* not all systems allow stat'ing a file with / appended */
if (strcmp(f, "-") == 0) {
- if (fstat(fileno(stdin), &s) != 0) {
+ if (zfstat(fileno(stdin), &s) != 0) {
free(name);
error("fstat(stdin)");
}
@@ -409,20 +429,146 @@ ulg filetime(f, a, n, t)
t->mtime = s.st_mtime;
t->ctime = t->mtime; /* best guess, (s.st_ctime: last status change!!) */
}
-
return unix2dostime(&s.st_mtime);
}
#ifndef QLZIP /* QLZIP Unix2QDOS cross-Zip supplies an extended variant */
+int set_new_unix_extra_field(z, s)
+ struct zlist far *z;
+ z_stat *s;
+ /* New unix extra field.
+ Currently only UIDs and GIDs are stored. */
+{
+ int uid_size;
+ int gid_size;
+ int ef_data_size;
+ char *extra;
+ char *cextra;
+ ulg id;
+ int b;
+
+ uid_size = sizeof(s->st_uid);
+ gid_size = sizeof(s->st_gid);
+
+/* New extra field
+ tag (2 bytes)
+ size (2 bytes)
+ version (1 byte)
+ uid_size (1 byte - size in bytes)
+ uid (variable)
+ gid_size (1 byte - size in bytes)
+ gid (variable)
+ */
+
+ ef_data_size = 1 + 1 + uid_size + 1 + gid_size;
+
+ if ((extra = (char *)malloc(z->ext + 4 + ef_data_size)) == NULL)
+ return ZE_MEM;
+ if ((cextra = (char *)malloc(z->ext + 4 + ef_data_size)) == NULL)
+ return ZE_MEM;
+
+ if (z->ext)
+ memcpy(extra, z->extra, z->ext);
+ if (z->cext)
+ memcpy(cextra, z->cextra, z->cext);
+
+ free(z->extra);
+ z->extra = extra;
+ free(z->cextra);
+ z->cextra = cextra;
+
+ z->extra[z->ext + 0] = 'u';
+ z->extra[z->ext + 1] = 'x';
+ z->extra[z->ext + 2] = (char)ef_data_size; /* length of data part */
+ z->extra[z->ext + 3] = 0;
+ z->extra[z->ext + 4] = 1; /* version */
+
+ /* UID */
+ z->extra[z->ext + 5] = (char)(uid_size); /* uid size in bytes */
+ b = 6;
+ id = (ulg)(s->st_uid);
+ z->extra[z->ext + b] = (char)(id & 0xFF);
+ if (uid_size > 1) {
+ b++;
+ id = id >> 8;
+ z->extra[z->ext + b] = (char)(id & 0xFF);
+ if (uid_size > 2) {
+ b++;
+ id = id >> 8;
+ z->extra[z->ext + b] = (char)(id & 0xFF);
+ b++;
+ id = id >> 8;
+ z->extra[z->ext + b] = (char)(id & 0xFF);
+ if (uid_size == 8) {
+ b++;
+ id = id >> 8;
+ z->extra[z->ext + b] = (char)(id & 0xFF);
+ b++;
+ id = id >> 8;
+ z->extra[z->ext + b] = (char)(id & 0xFF);
+ b++;
+ id = id >> 8;
+ z->extra[z->ext + b] = (char)(id & 0xFF);
+ b++;
+ id = id >> 8;
+ z->extra[z->ext + b] = (char)(id & 0xFF);
+ }
+ }
+ }
+
+ /* GID */
+ b++;
+ z->extra[z->ext + b] = (char)(gid_size); /* gid size in bytes */
+ b++;
+ id = (ulg)(s->st_gid);
+ z->extra[z->ext + b] = (char)(id & 0xFF);
+ if (gid_size > 1) {
+ b++;
+ id = id >> 8;
+ z->extra[z->ext + b] = (char)(id & 0xFF);
+ if (gid_size > 2) {
+ b++;
+ id = id >> 8;
+ z->extra[z->ext + b] = (char)(id & 0xFF);
+ b++;
+ id = id >> 8;
+ z->extra[z->ext + b] = (char)(id & 0xFF);
+ if (gid_size == 8) {
+ b++;
+ id = id >> 8;
+ z->extra[z->ext + b] = (char)(id & 0xFF);
+ b++;
+ id = id >> 8;
+ z->extra[z->ext + b] = (char)(id & 0xFF);
+ b++;
+ id = id >> 8;
+ z->extra[z->ext + b] = (char)(id & 0xFF);
+ b++;
+ id = id >> 8;
+ z->extra[z->ext + b] = (char)(id & 0xFF);
+ }
+ }
+ }
+
+ /* copy local extra field to central directory extra field */
+ memcpy((z->cextra) + z->cext, (z->extra) + z->ext, 4 + ef_data_size);
+
+ z->ext = z->ext + 4 + ef_data_size;
+ z->cext = z->cext + 4 + ef_data_size;
+
+ return ZE_OK;
+}
+
+
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 */
{
- struct stat s;
+ z_stat s;
char *name;
int len = strlen(z->name);
@@ -444,10 +590,33 @@ int set_extra_field(z, z_utim)
#define EB_L_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(2))
#define EB_C_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(1))
-#define EB_L_UX2_SIZE (EB_HEADSIZE + EB_UX2_MINLEN)
-#define EB_C_UX2_SIZE EB_HEADSIZE
-#define EF_L_UNIX_SIZE (EB_L_UT_SIZE + EB_L_UX2_SIZE)
-#define EF_C_UNIX_SIZE (EB_C_UT_SIZE + EB_C_UX2_SIZE)
+
+/* The flag UIDGID_NOT_16BIT should be set by the pre-compile configuration
+ script when it detects st_uid or st_gid sizes differing from 16-bit.
+ */
+#ifndef UIDGID_NOT_16BIT
+ /* The following "second-level" check for st_uid and st_gid members being
+ 16-bit wide is only added as a safety precaution in case the "first-level"
+ check failed to define the UIDGID_NOT_16BIT symbol.
+ The first-level check should have been implemented in the automatic
+ compile configuration process.
+ */
+# ifdef UIDGID_ARE_16B
+# undef UIDGID_ARE_16B
+# endif
+ /* The following expression is a compile-time constant and should (hopefully)
+ get optimized away by any sufficiently intelligent compiler!
+ */
+# define UIDGID_ARE_16B (sizeof(s.st_uid) == 2 && sizeof(s.st_gid) == 2)
+
+# define EB_L_UX2_SIZE (EB_HEADSIZE + EB_UX2_MINLEN)
+# define EB_C_UX2_SIZE EB_HEADSIZE
+# define EF_L_UNIX_SIZE (EB_L_UT_SIZE + (UIDGID_ARE_16B ? EB_L_UX2_SIZE : 0))
+# define EF_C_UNIX_SIZE (EB_C_UT_SIZE + (UIDGID_ARE_16B ? EB_C_UX2_SIZE : 0))
+#else
+# define EF_L_UNIX_SIZE EB_L_UT_SIZE
+# define EF_C_UNIX_SIZE EB_C_UT_SIZE
+#endif /* !UIDGID_NOT_16BIT */
if ((z->extra = (char *)malloc(EF_L_UNIX_SIZE)) == NULL)
return ZE_MEM;
@@ -467,20 +636,33 @@ int set_extra_field(z, z_utim)
z->extra[10] = (char)(s.st_atime >> 8);
z->extra[11] = (char)(s.st_atime >> 16);
z->extra[12] = (char)(s.st_atime >> 24);
- z->extra[13] = 'U';
- z->extra[14] = 'x';
- z->extra[15] = (char)EB_UX2_MINLEN; /* length of data part of local e.f. */
- z->extra[16] = 0;
- z->extra[17] = (char)(s.st_uid);
- z->extra[18] = (char)(s.st_uid >> 8);
- z->extra[19] = (char)(s.st_gid);
- z->extra[20] = (char)(s.st_gid >> 8);
+
+#ifndef UIDGID_NOT_16BIT
+ /* Only store the UID and GID in the old Ux extra field if the runtime
+ system provides them in 16-bit wide variables. */
+ if (UIDGID_ARE_16B) {
+ z->extra[13] = 'U';
+ z->extra[14] = 'x';
+ z->extra[15] = (char)EB_UX2_MINLEN; /* length of data part of local e.f. */
+ z->extra[16] = 0;
+ z->extra[17] = (char)(s.st_uid);
+ z->extra[18] = (char)(s.st_uid >> 8);
+ z->extra[19] = (char)(s.st_gid);
+ z->extra[20] = (char)(s.st_gid >> 8);
+ }
+#endif /* !UIDGID_NOT_16BIT */
+
z->ext = EF_L_UNIX_SIZE;
memcpy(z->cextra, z->extra, EB_C_UT_SIZE);
z->cextra[EB_LEN] = (char)EB_UT_LEN(1);
- memcpy(z->cextra+EB_C_UT_SIZE, z->extra+EB_L_UT_SIZE, EB_C_UX2_SIZE);
- z->cextra[EB_LEN+EB_C_UT_SIZE] = 0;
+#ifndef UIDGID_NOT_16BIT
+ if (UIDGID_ARE_16B) {
+ /* Copy header of Ux extra field from local to central */
+ memcpy(z->cextra+EB_C_UT_SIZE, z->extra+EB_L_UT_SIZE, EB_C_UX2_SIZE);
+ z->cextra[EB_LEN+EB_C_UT_SIZE] = 0;
+ }
+#endif
z->cext = EF_C_UNIX_SIZE;
#if 0 /* UID/GID presence is now signaled by central EF_IZUNIX2 field ! */
@@ -494,6 +676,10 @@ int set_extra_field(z, z_utim)
*/
z->atx |= 0x4000;
#endif /* never */
+
+ /* new unix extra field */
+ set_new_unix_extra_field(z, &s);
+
return ZE_OK;
}
@@ -548,8 +734,21 @@ void version_local()
char compiler_name[80];
# endif
#else
-# if ((defined(CRAY) || defined(cray)) && defined(_RELEASE))
+# if (defined( __SUNPRO_C))
+ char compiler_name[33];
+# else
+# if (defined( __HP_cc) || defined( __IBMC__))
+ char compiler_name[33];
+# else
+# if (defined( __DECC_VER))
+ char compiler_name[33];
+ int compiler_typ;
+# else
+# if ((defined(CRAY) || defined(cray)) && defined(_RELEASE))
char compiler_name[40];
+# endif
+# endif
+# endif
# endif
#endif
@@ -573,21 +772,55 @@ void version_local()
#ifdef __GNUC__
# ifdef NX_CURRENT_COMPILER_RELEASE
sprintf(compiler_name, "NeXT DevKit %d.%02d (gcc " __VERSION__ ")",
- NX_CURRENT_COMPILER_RELEASE/100, NX_CURRENT_COMPILER_RELEASE%100);
+ NX_CURRENT_COMPILER_RELEASE/100, NX_CURRENT_COMPILER_RELEASE%100);
# define COMPILER_NAME compiler_name
# else
# define COMPILER_NAME "gcc " __VERSION__
# endif
#else /* !__GNUC__ */
-# if ((defined(CRAY) || defined(cray)) && defined(_RELEASE))
- sprintf(compiler_name, "cc version %d", _RELEASE);
+# if defined(__SUNPRO_C)
+ sprintf( compiler_name, "Sun C version %x", __SUNPRO_C);
# define COMPILER_NAME compiler_name
# else
-# ifdef __VERSION__
-# define COMPILER_NAME "cc " __VERSION__
-# else
-# define COMPILER_NAME "cc "
-# endif
+# if (defined( __HP_cc))
+ if ((__HP_cc% 100) == 0)
+ {
+ sprintf( compiler_name, "HP C version A.%02d.%02d",
+ (__HP_cc/ 10000), ((__HP_cc% 10000)/ 100));
+ }
+ else
+ {
+ sprintf( compiler_name, "HP C version A.%02d.%02d.%02d",
+ (__HP_cc/ 10000), ((__HP_cc% 10000)/ 100), (__HP_cc% 100));
+ }
+# define COMPILER_NAME compiler_name
+# else
+# if (defined( __DECC_VER))
+ sprintf( compiler_name, "DEC C version %c%d.%d-%03d",
+ ((compiler_typ = (__DECC_VER / 10000) % 10) == 6 ? 'T' :
+ (compiler_typ == 8 ? 'S' : 'V')),
+ __DECC_VER / 10000000,
+ (__DECC_VER % 10000000) / 100000, __DECC_VER % 1000);
+# define COMPILER_NAME compiler_name
+# else
+# if ((defined(CRAY) || defined(cray)) && defined(_RELEASE))
+ sprintf(compiler_name, "cc version %d", _RELEASE);
+# define COMPILER_NAME compiler_name
+# else
+# ifdef __IBMC__
+ sprintf( compiler_name, "IBM C version %d.%d.%d",
+ (__IBMC__/ 100), ((__IBMC__/ 10)% 10), (__IBMC__% 10));
+# define COMPILER_NAME compiler_name
+# else
+# ifdef __VERSION__
+# define COMPILER_NAME "cc " __VERSION__
+# else
+# define COMPILER_NAME "cc "
+# endif
+# endif
+# endif
+# endif
+# endif
# endif
#endif /* ?__GNUC__ */
@@ -599,9 +832,9 @@ void version_local()
#ifdef sun
# ifdef sparc
# ifdef __SVR4
-# define OS_NAME "Sun Sparc/Solaris"
+# define OS_NAME "Sun SPARC/Solaris"
# else /* may or may not be SunOS */
-# define OS_NAME "Sun Sparc"
+# define OS_NAME "Sun SPARC"
# endif
# else
# if defined(sun386) || defined(i386)
@@ -616,7 +849,7 @@ void version_local()
# endif
#else
#ifdef __hpux
-# define OS_NAME "HP/UX"
+# define OS_NAME "HP-UX"
#else
#ifdef __osf__
# define OS_NAME "DEC OSF/1"
@@ -742,7 +975,19 @@ void version_local()
# define OS_NAME "QNX Neutrino"
#else
#ifdef __APPLE__
-# define OS_NAME "Mac OS X"
+# ifdef __i386__
+# define OS_NAME "Mac OS X Intel"
+# else /* __i386__ */
+# ifdef __ppc__
+# define OS_NAME "Mac OS X PowerPC"
+# else /* __ppc__ */
+# ifdef __ppc64__
+# define OS_NAME "Mac OS X PowerPC64"
+# else /* __ppc64__ */
+# define OS_NAME "Mac OS X"
+# endif /* __ppc64__ */
+# endif /* __ppc__ */
+# endif /* __i386__ */
#else
# define OS_NAME "Unknown"
#endif /* Apple */
@@ -769,7 +1014,7 @@ void version_local()
#endif /* RT/AIX */
#endif /* AIX */
#endif /* OSF/1 */
-#endif /* HP/UX */
+#endif /* HP-UX */
#endif /* Sun */
#endif /* SGI */
@@ -785,3 +1030,71 @@ void version_local()
COMPILER_NAME, OS_NAME, COMPILE_DATE);
} /* end function version_local() */
+
+
+/* 2006-03-23 SMS.
+ * Emergency replacement for strerror(). (Useful on SunOS 4.*.)
+ * Enable by specifying "LOCAL_UNZIP=-DNEED_STRERROR=1" on the "make"
+ * command line.
+ */
+
+#ifdef NEED_STRERROR
+
+char *strerror( err)
+ int err;
+{
+ extern char *sys_errlist[];
+ extern int sys_nerr;
+
+ static char no_msg[ 64];
+
+ if ((err >= 0) && (err < sys_nerr))
+ {
+ return sys_errlist[ err];
+ }
+ else
+ {
+ sprintf( no_msg, "(no message, code = %d.)", err);
+ return no_msg;
+ }
+}
+
+#endif /* def NEED_STRERROR */
+
+
+/* 2006-03-23 SMS.
+ * Emergency replacement for memmove(). (Useful on SunOS 4.*.)
+ * Enable by specifying "LOCAL_UNZIP=-DNEED_MEMMOVE=1" on the "make"
+ * command line.
+ */
+
+#ifdef NEED_MEMMOVE
+
+/* memmove.c -- copy memory.
+ Copy LENGTH bytes from SOURCE to DEST. Does not null-terminate.
+ In the public domain.
+ By David MacKenzie <djm@gnu.ai.mit.edu>.
+ Adjusted by SMS.
+*/
+
+void *memmove(dest0, source0, length)
+ void *dest0;
+ void const *source0;
+ size_t length;
+{
+ char *dest = dest0;
+ char const *source = source0;
+ if (source < dest)
+ /* Moving from low mem to hi mem; start at end. */
+ for (source += length, dest += length; length; --length)
+ *--dest = *--source;
+ else if (source != dest)
+ {
+ /* Moving from hi mem to low mem; start at beginning. */
+ for (; length; --length)
+ *dest++ = *source++;
+ }
+ return dest0;
+}
+
+#endif /* def NEED_MEMMOVE */
diff --git a/unix/zipup.h b/unix/zipup.h
index fbec842..0fc3f89 100644
--- a/unix/zipup.h
+++ b/unix/zipup.h
@@ -1,7 +1,9 @@
/*
+ unix/zipup.h - Zip 3
+
Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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/license.html
diff --git a/util.c b/util.c
index dca2eae..73317da 100644
--- a/util.c
+++ b/util.c
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ util.c
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*
@@ -19,37 +21,74 @@
# include <dos.h>
#endif
+#ifdef NO_MKTIME
+# ifndef IZ_MKTIME_ONLY
+# define IZ_MKTIME_ONLY /* only mktime() related code is pulled in */
+# endif
+# include "timezone.c"
+#endif
+
uch upper[256], lower[256];
/* Country-dependent case map table */
#ifndef UTIL /* UTIL picks out namecmp code (all utils) */
+/* RISC OS uses # as its single-character wildcard */
+#ifdef RISCOS
+# define WILDCHR_SINGLE '#'
+# define WILDCHR_MULTI '*'
+# define DIRSEP_CHR '.'
+#endif
+
+#ifdef VMS
+# define WILDCHR_SINGLE '%'
+# define WILDCHR_MULTI '*'
+# define DIRSEP_CHR '.'
+#endif
+
+#ifndef WILDCHR_SINGLE
+# define WILDCHR_SINGLE '?'
+#endif
+#ifndef WILDCHR_MULTI
+# define WILDCHR_MULTI '*'
+#endif
+#ifndef DIRSEP_CHR
+# define DIRSEP_CHR '/'
+#endif
+
/* Local functions */
-local int recmatch OF((ZCONST uch *, ZCONST uch *, int));
+local int recmatch OF((ZCONST char *, ZCONST char *, int));
+#if defined(UNICODE_SUPPORT) && defined(WIN32)
+ local long recmatchw OF((ZCONST wchar_t *, ZCONST wchar_t *, int));
+#endif
local int count_args OF((char *s));
#ifdef MSDOS16
local unsigned ident OF((unsigned chr));
#endif
-#ifdef NO_MKTIME
-#include "mktime.c"
-#endif
-
#ifndef HAVE_FSEEKABLE
-int fseekable(fp)
+
+/* 2004-11-12 SMS.
+ Changed to use z*o() functions, and ftell() test from >= 0 to != -1.
+ This solves problems with negative 32-bit offsets, even on small-file
+ products.
+*/
+int fseekable( fp)
FILE *fp;
{
- long x;
+ zoff_t x;
- return (fp == NULL || (fseek(fp, -1L, SEEK_CUR) == 0 &&
- (x = ftell(fp)) >= 0 &&
- fseek(fp, 1L, SEEK_CUR) == 0 &&
- ftell(fp) == x + 1));
+ return (fp == NULL ||
+ ((zfseeko( fp, ((zoff_t) -1), SEEK_CUR) == 0) && /* Seek ok. */
+ ((x = zftello( fp)) != ((zoff_t) -1)) && /* Tell ok. */
+ (zfseeko( fp, ((zoff_t) 1), SEEK_CUR) == 0) && /* Seek ok. */
+ (zftello( fp) == x+ 1))); /* Tells agree. */
}
#endif /* HAVE_FSEEKABLE */
+
char *isshexp(p)
char *p; /* candidate sh expression */
/* If p is a sh expression, a pointer to the first special character is
@@ -59,31 +98,208 @@ char *p; /* candidate sh expression */
if (*p == '\\' && *(p+1))
p++;
#ifdef VMS
- else if (*p == '%' || *p == '*')
+ else if (*p == WILDCHR_SINGLE || *p == WILDCHR_MULTI)
#else /* !VMS */
-# ifdef RISCOS
- /* RISC OS uses # as its single-character wildcard */
- else if (*p == '#' || *p == '*' || *p == '[')
-# else /* !RISC OS */
- else if (*p == '?' || *p == '*' || *p == '[')
-# endif
+ else if (*p == WILDCHR_SINGLE || *p == WILDCHR_MULTI || *p == '[')
#endif /* ?VMS */
return p;
return NULL;
}
+#ifdef UNICODE_SUPPORT
+# ifdef WIN32
+
+wchar_t *isshexpw(pw)
+ wchar_t *pw; /* candidate sh expression */
+/* If pw is a sh expression, a pointer to the first special character is
+ returned. Otherwise, NULL is returned. */
+{
+ for (; *pw; pw++)
+ if (*pw == (wchar_t)'\\' && *(pw+1))
+ pw++;
+ else if (*pw == (wchar_t)WILDCHR_SINGLE || *pw == (wchar_t)WILDCHR_MULTI ||
+ *pw == (wchar_t)'[')
+ return pw;
+ return NULL;
+}
+
+# endif
+#endif
+
+
+#ifdef UNICODE_SUPPORT
+# ifdef WIN32
+
+local long recmatchw(pw, sw, cs)
+ZCONST wchar_t *pw; /* sh pattern to match */
+ZCONST wchar_t *sw; /* string to match it to */
+int cs; /* flag: force case-sensitive matching */
+/* Recursively compare the sh pattern p with the string s and return 1 if
+ they match, and 0 or 2 if they don't or if there is a syntax error in the
+ pattern. This routine recurses on itself no deeper than the number of
+ characters in the pattern. */
+{
+ long c; /* pattern char or start of range in [-] loop */
+ /* Get first character, the pattern for new recmatch calls follows */
+
+ c = (long)*(pw++);
+
+ /* If that was the end of the pattern, match if string empty too */
+ if (c == 0)
+ return *sw == 0;
+
+ /* '?' matches any character (but not an empty string) */
+ if ((wchar_t)c == (wchar_t)WILDCHR_SINGLE) {
+ if (wild_stop_at_dir)
+ return (*sw && *sw != (wchar_t)DIRSEP_CHR) ? recmatchw(pw, sw + 1, cs) : 0;
+ else
+ return *sw ? recmatchw(pw, sw + 1, cs) : 0;
+ }
+
+ /* WILDCHR_MULTI ('*') matches any number of characters, including zero */
+ if (!no_wild && (wchar_t)c == (wchar_t)WILDCHR_MULTI)
+ {
+ if (wild_stop_at_dir) {
+ /* Check for an immediately following WILDCHR_MULTI */
+ if (*pw != (wchar_t)WILDCHR_MULTI) {
+ /* Single WILDCHR_MULTI ('*'): this doesn't match slashes */
+ for (; *sw && *sw != (wchar_t)DIRSEP_CHR; sw++)
+ if ((c = recmatchw(pw, sw, cs)) != 0)
+ return c;
+ /* end of pattern: matched if at end of string, else continue */
+ if (*pw == 0)
+ return (*sw == 0);
+ /* continue to match if at DIRSEP_CHR in pattern, else give up */
+ return (*pw == (wchar_t)DIRSEP_CHR || (*pw == (wchar_t)'\\' &&
+ pw[1] == (wchar_t)DIRSEP_CHR))
+ ? recmatchw(pw, sw, cs) : 2;
+ }
+ /* Two consecutive WILDCHR_MULTI ("**"): this matches DIRSEP_CHR ('/') */
+ pw++; /* move p past the second WILDCHR_MULTI */
+ /* continue with the normal non-WILD_STOP_AT_DIR code */
+ } /* wild_stop_at_dir */
+
+ /* Not wild_stop_at_dir */
+ if (*pw == 0)
+ return 1;
+ if (!isshexpw((wchar_t *)pw))
+ {
+ /* optimization for rest of pattern being a literal string */
+
+ /* optimization to handle patterns like *.txt */
+ /* if the first char in the pattern is '*' and there */
+ /* are no other shell expression chars, i.e. a literal string */
+ /* then just compare the literal string at the end */
+
+ ZCONST wchar_t *swrest;
+
+ swrest = sw + (wcslen(sw) - wcslen(pw));
+ if (swrest - sw < 0)
+ /* remaining literal string from pattern is longer than rest of
+ test string, there can't be a match
+ */
+ return 0;
+ else
+ /* compare the remaining literal pattern string with the last bytes
+ of the test string to check for a match */
+ return ((cs ? wcscmp(pw, swrest) : _wcsicmp(pw, swrest)) == 0);
+ }
+ else
+ {
+ /* pattern contains more wildcards, continue with recursion... */
+ for (; *sw; sw++)
+ if ((c = recmatchw(pw, sw, cs)) != 0)
+ return c;
+ return 2; /* 2 means give up--shmatch will return false */
+ }
+ }
+
+ /* Parse and process the list of characters and ranges in brackets */
+ if (!no_wild && allow_regex && (wchar_t)c == '[')
+ {
+ int e; /* flag true if next char to be taken literally */
+ ZCONST wchar_t *qw; /* pointer to end of [-] group */
+ int r; /* flag true to match anything but the range */
+
+ if (*sw == 0) /* need a character to match */
+ return 0;
+ pw += (r = (*pw == (wchar_t)'!' || *pw == (wchar_t)'^')); /* see if reverse */
+ for (qw = pw, e = 0; *qw; qw++) /* find closing bracket */
+ if (e)
+ e = 0;
+ else
+ if (*qw == (wchar_t)'\\')
+ e = 1;
+ else if (*qw == (wchar_t)']')
+ break;
+ if (*qw != (wchar_t)']') /* nothing matches if bad syntax */
+ return 0;
+ for (c = 0, e = *pw == (wchar_t)'-'; pw < qw; pw++) /* go through the list */
+ {
+ if (e == 0 && *pw == (wchar_t)'\\') /* set escape flag if \ */
+ e = 1;
+ else if (e == 0 && *pw == (wchar_t)'-') /* set start of range if - */
+ c = *(pw-1);
+ else
+ {
+ wchar_t cc = (cs ? *sw : towupper(*sw));
+ wchar_t uc = (wchar_t) c;
+
+ if (*(pw+1) != (wchar_t)'-')
+ for (uc = uc ? uc : *pw; cc <= *pw; uc++)
+ /* compare range */
+ if ((cs ? uc : towupper(uc)) == cc)
+ return r ? 0 : recmatchw(qw + 1, sw + 1, cs);
+ c = e = 0; /* clear range, escape flags */
+ }
+ }
+ return r ? recmatchw(qw + 1, sw + 1, cs) : 0;
+ /* bracket match failed */
+ }
+
+ /* If escape ('\'), just compare next character */
+ if (!no_wild && (wchar_t)c == (wchar_t)'\\')
+ if ((c = *pw++) == '\0') /* if \ at end, then syntax error */
+ return 0;
+
+ /* Just a character--compare it */
+ return (cs ? (wchar_t)c == *sw : towupper((wchar_t)c) == towupper(*sw)) ?
+ recmatchw(pw, sw + 1, cs) : 0;
+}
+
+# endif
+#endif
+
local int recmatch(p, s, cs)
-ZCONST uch *p; /* sh pattern to match */
-ZCONST uch *s; /* string to match it to */
-int cs; /* flag: force case-sensitive matching */
+ZCONST char *p; /* sh pattern to match */
+ZCONST char *s; /* string to match it to */
+int cs; /* flag: force case-sensitive matching */
/* Recursively compare the sh pattern p with the string s and return 1 if
they match, and 0 or 2 if they don't or if there is a syntax error in the
pattern. This routine recurses on itself no deeper than the number of
characters in the pattern. */
{
- unsigned int c; /* pattern char or start of range in [-] loop */
+ int c; /* pattern char or start of range in [-] loop */
/* Get first character, the pattern for new recmatch calls follows */
+
+ /* This fix provided by akt@m5.dion.ne.jp for Japanese.
+ See 21 July 2006 mail.
+ It only applies when p is pointing to a doublebyte character and
+ things like / and wildcards are not doublebyte. This probably
+ should not be needed. */
+
+#ifdef _MBCS
+ if (CLEN(p) == 2) {
+ if (CLEN(s) == 2) {
+ return (*p == *s && *(p+1) == *(s+1)) ?
+ recmatch(p + 2, s + 2, cs) : 0;
+ } else {
+ return 0;
+ }
+ }
+#endif /* ?_MBCS */
+
c = *POSTINCSTR(p);
/* If that was the end of the pattern, match if string empty too */
@@ -91,50 +307,108 @@ int cs; /* flag: force case-sensitive matching */
return *s == 0;
/* '?' (or '%' or '#') matches any character (but not an empty string) */
-#ifdef VMS
- if (c == '%')
-#else /* !VMS */
-# ifdef RISCOS
- if (c == '#')
-# else /* !RISC OS */
- if (c == '?')
-# endif
-#endif /* ?VMS */
-#ifdef WILD_STOP_AT_DIR
- return (*s && *s != '/') ? recmatch(p, s + CLEN(s), cs) : 0;
-#else
- return *s ? recmatch(p, s + CLEN(s), cs) : 0;
-#endif
+ if (c == WILDCHR_SINGLE) {
+ if (wild_stop_at_dir)
+ return (*s && *s != DIRSEP_CHR) ? recmatch(p, s + CLEN(s), cs) : 0;
+ else
+ return *s ? recmatch(p, s + CLEN(s), cs) : 0;
+ }
- /* '*' matches any number of characters, including zero */
+ /* WILDCHR_MULTI ('*') matches any number of characters, including zero */
#ifdef AMIGA
- if (c == '#' && *p == '?') /* "#?" is Amiga-ese for "*" */
- c = '*', p++;
+ if (!no_wild && c == '#' && *p == '?') /* "#?" is Amiga-ese for "*" */
+ c = WILDCHR_MULTI, p++;
#endif /* AMIGA */
- if (c == '*')
+ if (!no_wild && c == WILDCHR_MULTI)
{
+ if (wild_stop_at_dir) {
+ /* Check for an immediately following WILDCHR_MULTI */
+# ifdef AMIGA
+ if ((c = p[0]) == '#' && p[1] == '?') /* "#?" is Amiga-ese for "*" */
+ c = WILDCHR_MULTI, p++;
+ if (c != WILDCHR_MULTI) {
+# else /* !AMIGA */
+ if (*p != WILDCHR_MULTI) {
+# endif /* ?AMIGA */
+ /* Single WILDCHR_MULTI ('*'): this doesn't match slashes */
+ for (; *s && *s != DIRSEP_CHR; INCSTR(s))
+ if ((c = recmatch(p, s, cs)) != 0)
+ return c;
+ /* end of pattern: matched if at end of string, else continue */
+ if (*p == 0)
+ return (*s == 0);
+ /* continue to match if at DIRSEP_CHR in pattern, else give up */
+ return (*p == DIRSEP_CHR || (*p == '\\' && p[1] == DIRSEP_CHR))
+ ? recmatch(p, s, cs) : 2;
+ }
+ /* Two consecutive WILDCHR_MULTI ("**"): this matches DIRSEP_CHR ('/') */
+ p++; /* move p past the second WILDCHR_MULTI */
+ /* continue with the normal non-WILD_STOP_AT_DIR code */
+ } /* wild_stop_at_dir */
+
+ /* Not wild_stop_at_dir */
if (*p == 0)
return 1;
-#ifdef WILD_STOP_AT_DIR
- for (; *s && *s != '/'; INCSTR(s))
- if ((c = recmatch(p, s, cs)) != 0)
- return (int)c;
- return (*p == '/' || (*p == '\\' && p[1] == '/'))
- ? recmatch(p, s, cs) : 2;
-#else /* !WILD_STOP_AT_DIR */
- for (; *s; INCSTR(s))
- if ((c = recmatch(p, s, cs)) != 0)
- return (int)c;
- return 2; /* 2 means give up--shmatch will return false */
-#endif /* ?WILD_STOP_AT_DIR */
+ if (!isshexp((char *)p))
+ {
+ /* optimization for rest of pattern being a literal string */
+
+ /* optimization to handle patterns like *.txt */
+ /* if the first char in the pattern is '*' and there */
+ /* are no other shell expression chars, i.e. a literal string */
+ /* then just compare the literal string at the end */
+
+ ZCONST char *srest;
+
+ srest = s + (strlen(s) - strlen(p));
+ if (srest - s < 0)
+ /* remaining literal string from pattern is longer than rest of
+ test string, there can't be a match
+ */
+ return 0;
+ else
+ /* compare the remaining literal pattern string with the last bytes
+ of the test string to check for a match */
+#ifdef _MBCS
+ {
+ ZCONST char *q = s;
+
+ /* MBCS-aware code must not scan backwards into a string from
+ * the end.
+ * So, we have to move forward by character from our well-known
+ * character position s in the test string until we have advanced
+ * to the srest position.
+ */
+ while (q < srest)
+ INCSTR(q);
+ /* In case the byte *srest is a trailing byte of a multibyte
+ * character, we have actually advanced past the position (srest).
+ * For this case, the match has failed!
+ */
+ if (q != srest)
+ return 0;
+ return ((cs ? strcmp(p, q) : namecmp(p, q)) == 0);
+ }
+#else /* !_MBCS */
+ return ((cs ? strcmp(p, srest) : namecmp(p, srest)) == 0);
+#endif /* ?_MBCS */
+ }
+ else
+ {
+ /* pattern contains more wildcards, continue with recursion... */
+ for (; *s; INCSTR(s))
+ if ((c = recmatch(p, s, cs)) != 0)
+ return c;
+ return 2; /* 2 means give up--shmatch will return false */
+ }
}
#ifndef VMS /* No bracket matching in VMS */
/* Parse and process the list of characters and ranges in brackets */
- if (c == '[')
+ if (!no_wild && allow_regex && c == '[')
{
int e; /* flag true if next char to be taken literally */
- ZCONST uch *q; /* pointer to end of [-] group */
+ ZCONST char *q; /* pointer to end of [-] group */
int r; /* flag true to match anything but the range */
if (*s == 0) /* need a character to match */
@@ -158,11 +432,12 @@ int cs; /* flag: force case-sensitive matching */
c = *(p-1);
else
{
- uch cc = (cs ? *s : case_map(*s));
+ uch cc = (cs ? (uch)*s : case_map((uch)*s));
+ uch uc = (uch) c;
if (*(p+1) != '-')
- for (c = c ? c : (unsigned)*p; c <= (unsigned)*p; c++)
+ for (uc = uc ? uc : (uch)*p; uc <= (uch)*p; uc++)
/* compare range */
- if ((cs ? c : case_map(c)) == cc)
+ if ((cs ? uc : case_map(uc)) == cc)
return r ? 0 : recmatch(q + CLEN(q), s + CLEN(s), cs);
c = e = 0; /* clear range, escape flags */
}
@@ -173,12 +448,40 @@ int cs; /* flag: force case-sensitive matching */
#endif /* !VMS */
/* If escape ('\'), just compare next character */
- if (c == '\\')
+ if (!no_wild && c == '\\')
if ((c = *p++) == '\0') /* if \ at end, then syntax error */
return 0;
+#ifdef VMS
+ /* 2005-11-06 SMS.
+ Handle "..." wildcard in p with "." or "]" in s.
+ */
+ if ((c == '.') && (*p == '.') && (*(p+ CLEN( p)) == '.') &&
+ ((*s == '.') || (*s == ']')))
+ {
+ /* Match "...]" with "]". Continue after "]" in both. */
+ if ((*(p+ 2* CLEN( p)) == ']') && (*s == ']'))
+ return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), cs);
+
+ /* Else, look for a reduced match in s, until "]" in or end of s. */
+ for (; *s && (*s != ']'); INCSTR(s))
+ if (*s == '.')
+ /* If reduced match, then continue after "..." in p, "." in s. */
+ if ((c = recmatch( (p+ CLEN( p)), s, cs)) != 0)
+ return (int)c;
+
+ /* Match "...]" with "]". Continue after "]" in both. */
+ if ((*(p+ 2* CLEN( p)) == ']') && (*s == ']'))
+ return recmatch( (p+ 3* CLEN( p)), (s+ CLEN( s)), cs);
+
+ /* No reduced match. Quit. */
+ return 2;
+ }
+
+#endif /* def VMS */
+
/* Just a character--compare it */
- return (cs ? c == *s : case_map(c) == case_map(*s)) ?
+ return (cs ? c == *s : case_map((uch)c) == case_map((uch)*s)) ?
recmatch(p, s + CLEN(s), cs) : 0;
}
@@ -190,11 +493,43 @@ int cs; /* force case-sensitive match if TRUE */
/* Compare the sh pattern p with the string s and return true if they match,
false if they don't or if there is a syntax error in the pattern. */
{
- return recmatch((ZCONST uch *) p, (ZCONST uch *) s, cs) == 1;
+ return recmatch(p, s, cs) == 1;
}
#if defined(DOS) || defined(WIN32)
+
+#ifdef UNICODE_SUPPORT
+
+int dosmatchw(pw, sw, cs)
+ZCONST wchar_t *pw; /* dos pattern to match */
+ZCONST wchar_t *sw; /* string to match it to */
+int cs; /* force case-sensitive match if TRUE */
+/* Treat filenames without periods as having an implicit trailing period */
+{
+ wchar_t *sw1; /* revised string to match */
+ int r; /* result */
+
+ if (wcschr(pw, (wchar_t)'.') && !wcschr(sw, (wchar_t)'.') &&
+ ((sw1 = (wchar_t *)malloc((wcslen(sw) + 2) * sizeof(wchar_t))) != NULL))
+ {
+ wcscpy(sw1, sw);
+ wcscat(sw1, L".");
+ }
+ else
+ {
+ /* will usually be OK */
+ sw1 = (wchar_t *)sw;
+ }
+
+ r = recmatchw(pw, sw1, cs) == 1;
+ if (sw != sw1)
+ free((zvoid *)sw1);
+ return r == 1;
+}
+
+#endif
+
/* XXX also suitable for OS2? Atari? Human68K? TOPS-20?? */
int dosmatch(p, s, cs)
@@ -206,14 +541,21 @@ int cs; /* force case-sensitive match if TRUE */
char *s1; /* revised string to match */
int r; /* result */
- if ((s1 = malloc(strlen(s) + 2)) == NULL)
- /* will usually be OK */
- return recmatch((ZCONST uch *) p, (ZCONST uch *) s, cs) == 1;
- strcpy(s1, s);
- if (strchr(p, '.') && !strchr(s1, '.'))
+ if (strchr(p, '.') && !strchr(s, '.') &&
+ ((s1 = malloc(strlen(s) + 2)) != NULL))
+ {
+ strcpy(s1, s);
strcat(s1, ".");
- r = recmatch((ZCONST uch *)p, (ZCONST uch *)s1, cs);
- free((zvoid *)s1);
+ }
+ else
+ {
+ /* will usually be OK */
+ s1 = (char *)s;
+ }
+
+ r = recmatch(p, s1, cs) == 1;
+ if (s != s1)
+ free((zvoid *)s1);
return r == 1;
}
@@ -287,7 +629,7 @@ void init_upper()
lower[c] = (uch) c;
}
for (c = 0; c < sizeof(upper); c++ ) {
- int u = upper[c];
+ unsigned int u = upper[c];
if (u != c && lower[u] == (uch) u) {
lower[u] = (uch)c;
}
@@ -425,7 +767,7 @@ unsigned char *zmbschr(str, c)
unsigned int c;
{
while(*str != '\0'){
- if (*str == c) {return (char*)str;}
+ if (*str == c) {return (unsigned char *)str;}
INCSTR(str);
}
return NULL;
@@ -437,7 +779,7 @@ unsigned char *zmbsrchr(str, c)
{
unsigned char *match = NULL;
while(*str != '\0'){
- if (*str == c) {match = (char*)str;}
+ if (*str == c) {match = (unsigned char*)str;}
INCSTR(str);
}
return match;
@@ -562,7 +904,7 @@ void envargs(Pargc, Pargv, envstr, envstr2)
*Pargc = argc;
}
-static int count_args(s)
+local int count_args(s)
char *s;
{
int count = 0;
@@ -665,8 +1007,40 @@ void expand_args(argcp, argvp)
#endif /* ?DOS */
}
+
+/* Fast routine for detection of plain text
+ * (ASCII or an ASCII-compatible extension such as ISO-8859, UTF-8, etc.)
+ * Author: Cosmin Truta.
+ * See "proginfo/txtvsbin.txt" for more information.
+ *
+ * This function returns the same result as set_file_type() in "trees.c".
+ * Unlike in set_file_type(), however, the speed depends on the buffer size,
+ * so the optimal implementation is different.
+ */
+int is_text_buf(buf_ptr, buf_size)
+ ZCONST char *buf_ptr;
+ unsigned buf_size;
+{
+ int result = 0;
+ unsigned i;
+ unsigned char c;
+
+ for (i = 0; i < buf_size; ++i)
+ {
+ c = (unsigned char)buf_ptr[i];
+ if (c >= 32) /* speed up the loop by checking this first */
+ result = 1; /* white-listed character found; keep looping */
+ else /* speed up the loop by inlining the following check */
+ if ((c <= 6) || (c >= 14 && c <= 25) || (c >= 28 && c <= 31))
+ return 0; /* black-listed character found; stop */
+ }
+
+ return result;
+}
+
#endif /* UTIL */
+
#ifdef DEBUGNAMES
#undef free
int Free(x)
@@ -683,7 +1057,7 @@ int printnames()
struct zlist far *z;
for (z = zfiles; z != NULL; z = z->nxt)
- fprintf(stderr, "%s %s %s %p %p %p %08x %08x %08x\n",
+ fprintf(mesg, "%s %s %s %p %p %p %08x %08x %08x\n",
z->name, z->zname, z->iname,
z->name, z->zname, z->iname,
*((int *) z->name), *((int *) z->zname),
@@ -692,3 +1066,385 @@ int printnames()
}
#endif /* DEBUGNAMES */
+
+
+/* Below is used to format zoff_t values, which can be either long or long long
+ depending on if LARGE FILES are supported. Function provided by SMS.
+ 10/17/04 EG */
+
+/* 2004-12-01 SMS.
+ * Brought in fancy fzofft() from UnZip.
+ */
+
+/* This implementation assumes that no more than FZOFF_NUM values will be
+ needed in any printf using it. */
+
+/* zip_fzofft(): Format a zoff_t value in a cylindrical buffer set.
+ This version renamed from fzofft because of name conflict in unzip
+ when combined in WiZ. */
+
+/* 2004-12-19 SMS.
+ * I still claim than the smart move would have been to disable one or
+ * the other instance with #if for Wiz. But fine. We'll change the
+ * name.
+ */
+
+/* This is likely not thread safe. Needs to be done without static storage.
+ 12/29/04 EG */
+
+/* zip_fzofft(): Format a zoff_t value in a cylindrical buffer set. */
+
+#define FZOFFT_NUM 4 /* Number of chambers. */
+#define FZOFFT_LEN 24 /* Number of characters/chamber. */
+
+
+/* Format a zoff_t value in a cylindrical buffer set. */
+
+char *zip_fzofft( val, pre, post)
+ zoff_t val;
+ char *pre;
+ char *post;
+{
+ /* Storage cylinder. */
+ static char fzofft_buf[ FZOFFT_NUM][ FZOFFT_LEN];
+ static int fzofft_index = 0;
+
+ /* Temporary format string storage. */
+ static char fmt[ 16] = "%";
+
+ /* Assemble the format string. */
+ fmt[ 1] = '\0'; /* Start after initial "%". */
+ if (pre == FZOFFT_HEX_WID) /* Special hex width. */
+ {
+ strcat( fmt, FZOFFT_HEX_WID_VALUE);
+ }
+ else if (pre == FZOFFT_HEX_DOT_WID) /* Special hex ".width". */
+ {
+ strcat( fmt, ".");
+ strcat( fmt, FZOFFT_HEX_WID_VALUE);
+ }
+ else if (pre != NULL) /* Caller's prefix (width). */
+ {
+ strcat( fmt, pre);
+ }
+
+ strcat( fmt, FZOFFT_FMT); /* Long or long-long or whatever. */
+
+ if (post == NULL)
+ strcat( fmt, "d"); /* Default radix = decimal. */
+ else
+ strcat( fmt, post); /* Caller's radix. */
+
+ /* Advance the cylinder. */
+ fzofft_index = (fzofft_index+ 1)% FZOFFT_NUM;
+
+ /* Write into the current chamber. */
+ sprintf( fzofft_buf[ fzofft_index], fmt, val);
+
+ /* Return a pointer to this chamber. */
+ return fzofft_buf[ fzofft_index];
+}
+
+
+/* Format a uzoff_t value in a cylindrical buffer set. */
+/* Added to support uzoff_t type. 12/29/04 */
+
+char *zip_fuzofft( val, pre, post)
+ uzoff_t val;
+ char *pre;
+ char *post;
+{
+ /* Storage cylinder. */
+ static char fuzofft_buf[ FZOFFT_NUM][ FZOFFT_LEN];
+ static int fuzofft_index = 0;
+
+ /* Temporary format string storage. */
+ static char fmt[ 16] = "%";
+
+ /* Assemble the format string. */
+ fmt[ 1] = '\0'; /* Start after initial "%". */
+ if (pre == FZOFFT_HEX_WID) /* Special hex width. */
+ {
+ strcat( fmt, FZOFFT_HEX_WID_VALUE);
+ }
+ else if (pre == FZOFFT_HEX_DOT_WID) /* Special hex ".width". */
+ {
+ strcat( fmt, ".");
+ strcat( fmt, FZOFFT_HEX_WID_VALUE);
+ }
+ else if (pre != NULL) /* Caller's prefix (width). */
+ {
+ strcat( fmt, pre);
+ }
+
+ strcat( fmt, FZOFFT_FMT); /* Long or long-long or whatever. */
+
+ if (post == NULL)
+ strcat( fmt, "u"); /* Default radix = decimal. */
+ else
+ strcat( fmt, post); /* Caller's radix. */
+
+ /* Advance the cylinder. */
+ fuzofft_index = (fuzofft_index+ 1)% FZOFFT_NUM;
+
+ /* Write into the current chamber. */
+ sprintf( fuzofft_buf[ fuzofft_index], fmt, val);
+
+ /* Return a pointer to this chamber. */
+ return fuzofft_buf[ fuzofft_index];
+}
+
+
+/* Display number to mesg stream
+ 5/15/05 EG */
+
+int DisplayNumString(file, i)
+ FILE *file;
+ uzoff_t i;
+{
+ char tempstrg[100];
+ int j;
+ char *s = tempstrg;
+
+ WriteNumString(i, tempstrg);
+ /* skip spaces */
+ for (j = 0; j < 3; j++) {
+ if (*s != ' ') break;
+ s++;
+ }
+ fprintf(file, "%s", s);
+
+ return 0;
+}
+
+/* Read numbers with trailing size multiplier (like 10M) and return number.
+ 10/30/04 EG */
+
+uzoff_t ReadNumString( numstring )
+ char *numstring;
+{
+ zoff_t num = 0;
+ char multchar = ' ';
+ int i;
+ uzoff_t mult = 1;
+
+ /* check if valid number (currently no negatives) */
+ if (numstring == NULL) {
+ zipwarn("Unable to read empty number in ReadNumString", "");
+ return (uzoff_t)-1;
+ }
+ if (numstring[0] < '0' || numstring[0] > '9') {
+ zipwarn("Unable to read number (must start with digit): ", numstring);
+ return (uzoff_t)-1;
+ }
+ if (strlen(numstring) > 8) {
+ zipwarn("Number too long to read (8 characters max): ", numstring);
+ return (uzoff_t)-1;
+ }
+
+ /* get the number part */
+ num = atoi(numstring);
+
+ /* find trailing multiplier */
+ for (i = 0; numstring[i] && isdigit(numstring[i]); i++) ;
+
+ /* return if no multiplier */
+ if (numstring[i] == '\0') {
+ return (uzoff_t)num;
+ }
+
+ /* nothing follows multiplier */
+ if (numstring[i + 1]) {
+ return (uzoff_t)-1;
+ }
+
+ /* get multiplier */
+ multchar = toupper(numstring[i]);
+
+ if (multchar == 'K') {
+ mult <<= 10;
+ } else if (multchar == 'M') {
+ mult <<= 20;
+ } else if (multchar == 'G') {
+ mult <<= 30;
+#ifdef LARGE_FILE_SUPPORT
+ } else if (multchar == 'T') {
+ mult <<= 40;
+#endif
+ } else {
+ return (uzoff_t)-1;
+ }
+
+ return (uzoff_t)num * mult;
+}
+
+
+/* Write the number as a string with a multiplier (like 10M) to outstring.
+ Always writes no more than 3 digits followed maybe by a multiplier and
+ returns the characters written or -1 if error.
+ 10/30/04 EG */
+
+int WriteNumString( num, outstring )
+ uzoff_t num;
+ char *outstring;
+{
+ int mult;
+ int written = 0;
+ int i;
+ int j;
+ char digits[4];
+ int dig;
+
+ *outstring = '\0';
+
+ /* shift number 1 K until less than 10000 */
+ for (mult = 0; num >= 10240; mult++) {
+ num >>= 10;
+ }
+
+ /* write digits as " 0" */
+ for (i = 1; i < 4; i++) {
+ digits[i] = ' ';
+ }
+ digits[0] = '0';
+
+ if (num >= 1000) {
+ i = 3;
+ num *= 10;
+ num >>= 10;
+ mult++;
+ digits[0] = (char) (num % 10) + '0';
+ digits[1] = '.';
+ digits[2] = (char) (num / 10) + '0';
+ } else {
+ for (i = 0; num; i++) {
+ dig = (int) (num % 10);
+ num /= 10;
+ digits[i] = dig + '0';
+ }
+ }
+ if (i == 0) i = 1;
+ for (j = i; j > 0; j--) {
+ *outstring = digits[j - 1];
+ outstring++;
+ written++;
+ }
+
+ /* output multiplier */
+ if (mult == 0) {
+ } else if (mult == 1) {
+ *outstring = 'K';
+ outstring++;
+ written++;
+ } else if (mult == 2) {
+ *outstring = 'M';
+ outstring++;
+ written++;
+ } else if (mult == 3) {
+ *outstring = 'G';
+ outstring++;
+ written++;
+ } else if (mult == 4) {
+ *outstring = 'T';
+ outstring++;
+ written++;
+ } else {
+ *outstring = '?';
+ outstring++;
+ written++;
+ }
+
+ *outstring = '\0';
+
+ return written;
+}
+
+
+#if 0 /* not used anywhere, should get removed by next release... */
+
+/* Apply the Adler-16 checksum to a set of bytes.
+ * Use this function as you would use crc32():
+ * - First call this function by passing a NULL pointer instead of buf
+ * OR initialize the checksum register with ADLERVAL_INITIAL.
+ * - Iteratively call this function for each buffer fragment.
+ * This function returns the updated checksum.
+ *
+ * IN assertion: chksum is a valid Adler-16 checksum:
+ * (chksum & 0xffU) < ADLER16_BASE && ((chksum >> 8) & 0xffU) < ADLER16_BASE
+ *
+ * Author: Cosmin Truta.
+ * See "proginfo/adler16.txt" for more information.
+ */
+
+#define ADLER16_BASE 251 /* The largest prime smaller than 256 */
+
+unsigned int adler16(chksum, buf, len)
+ unsigned int chksum;
+ ZCONST uch *buf;
+ extent len;
+{
+ unsigned int sum1 = chksum & 0xff;
+ unsigned int sum2 = (chksum >> 8) & 0xff;
+ extent i;
+
+ Assert((sum1 < ADLER16_BASE) && (sum2 < ADLER16_BASE),
+ "adler16: invalid checksum");
+
+ if (buf == NULL)
+ return 1;
+
+ for (i = 0; i < len; ++i)
+ {
+ sum1 += buf[i];
+ if (sum1 >= ADLER16_BASE) /* this is faster than modulo ADLER16_BASE */
+ sum1 -= ADLER16_BASE;
+ sum2 += sum1;
+ if (sum2 >= ADLER16_BASE) /* ditto */
+ sum2 -= ADLER16_BASE;
+ }
+
+ return (sum2 << 8) | sum1;
+}
+
+#endif /* 0, not used anywhere */
+
+
+/* returns true if abbrev is abbreviation for matchstring */
+int abbrevmatch (matchstring, abbrev, case_sensitive, minmatch)
+ char *matchstring;
+ char *abbrev;
+ int case_sensitive;
+ int minmatch;
+{
+ int cnt = 0;
+ char *m;
+ char *a;
+
+ m = matchstring;
+ a = abbrev;
+
+ for (; *m && *a; m++, a++) {
+ cnt++;
+ if (case_sensitive) {
+ if (*m != *a) {
+ /* mismatch */
+ return 0;
+ }
+ } else {
+ if (toupper(*m) != toupper(*a)) {
+ /* mismatch */
+ return 0;
+ }
+ }
+ }
+ if (cnt < minmatch) {
+ /* not big enough string */
+ return 0;
+ }
+ if (*a != '\0') {
+ /* abbreviation longer than match string */
+ return 0;
+ }
+ /* either abbreviation or match */
+ return 1;
+}
diff --git a/vms/00binary.vms b/vms/00binary.vms
deleted file mode 100644
index aa0dc41..0000000
--- a/vms/00binary.vms
+++ /dev/null
@@ -1,87 +0,0 @@
-First information about the binary distribution of VMS Zip 2.3
---------------------------------------------------------------
-This archive comes in different variations:
-
- "zip22x-vms-<cpu-compiler>-{obj|exe}.zip",
-
- where <cpu-compiler> is "axp", "vax-decc", or "vax-vaxc", depending on
- the environment used for creating the binaries.
-
- ...-obj.zip denotes object library distributions which require
- a link step on the local machine.
-
- ...-exe.zip denotes "ready-to-run" executable distributions, that do
- not require additional work but do not run on VMS versions which are
- older than the system used for building the executables.
-
-Contents of the "vms" executables archives for Zip 2.3:
-
-a) common files (documentation etc.):
- 00binary.vms this file
- 00readme.txt additional VMS info about compiling Zip
- readme what Zip is; general information
- changes list of changes against the previous official version
- algorith.txt description of the deflation algorithm
- infozip.who list of contributors to the "portable Zip" project
- manual Zip manual page, human-readable format
- whatsnew list of important changes and new features
- where pointer to Zip/UnZip support archives
- zip.hlp VMS help module, for Zip's default command interface
- zip_cli.hlp VMS help module, for Zip's VMSCLI command interface
-
-b) object library distributions:
- link_zip.com command procedure for the linking step
- vms/ auxiliary directory, required for link step
-
- zip.<cpu_compiler>_olb object library for Zip (both command interfaces)
- zipcli.<cpu_compiler>_olb additional object library (Zip CLI interface)
- zipcloak.<cpu_compiler>_obj main object file for ZipCloak
- zipnote.<cpu_compiler>_obj main object file for ZipNote
- zipsplit.<cpu_compiler>_obj main object file for ZipSplit
- ziputils.<cpu_compiler>_olb object library for the Zip Utilities
-
-c) executable distributions:
- zip.exe Zip executable, default (UNIX style) command interface
- zipcloak.exe Utility for encrypting and decrypting zip archives
- zipnote.exe Utility for editing entry names and comments
- zipsplit.exe Utility for splitting large zip archives
- zip_cli.exe Zip executable, VMSCLI command interface
-
-
-In case you decided to fetch the object library distribution, you
-have to link the executables on your local site. This requires
-installed runtime support for the C runtime library, which may not be
-present on older VAX systems (prior to VMS 6).
-To create the executables, just invoke the "link_zip.com" command procedure.
-This will generate all executables (both zip with UNIX style command syntax
-and zip_cli with VMSCLI command interface), but note that the executable's
-extension is ".<cpu_compiler>_exe"!
-In case your are on a VAX and your current working directory carries
-both the DECC and the VAXC object distributions, you have to specify
-either "VAXC" or "DECC" to tell link_zip.com which binaries you want
-to build.
-
-Additionally, link_zip.com defines foreign commands for the just created
-executables, so you can test them straight ahead.
-If you want to use the default (UNIX like) command interface, you can
-proceed straight ahead after unpacking the distribution.
-When you rather prefer to use the VMSCLI interface, you have to specify
-the option "VMSCLI" (or just "CLI") to the command starting link_zip.com.
-
-The executables (object libraries) in this archive have been compiled
-with the following options enabled:
- * VMS_PK_EXTRA (this is the default option)
- * [decription support]
-
-The environment used for compilation was:
-
-a) On Alpha AXP : OpenVMS(AXP) 6.2; DEC C V 5.6-003
-b1) On VAX : OpenVMS(VAX) 6.2; DEC C V 4.0
-b2) alternatively VAX C V 3.2
-
-One final note:
-The binary files of the distribution have been archived with "saving all VMS
-attributes" enabled. Please do not repack the binary part of the archives on
-a non-VMS system, to prevent corruption of the files.
-
-02-Feb-1999, Christian Spieler
diff --git a/vms/00readme.txt b/vms/00readme.txt
deleted file mode 100644
index 020d8ae..0000000
--- a/vms/00readme.txt
+++ /dev/null
@@ -1,126 +0,0 @@
-*****************************************
-************ vms/00readme.txt ***********
-*****************************************
-
-Additional information for compiling Zip for VMS:
-
-A) Support for storing VMS specific file attributes
- ================================================
-
-The current version of Zip comes with two different types of support
-to store VMS file attributes in extra blocks:
-
- -- the traditional Info-ZIP format in vms/vms_im.c
-and
-
- -- a new PKware (ASI) type extra field structure in vms/vms_pk.c
-
-Both versions should supply exactly the same functionality.
-Up to Zip 2.1, the default configuration was to use the traditional IM style,
-since it was well tested and known to be stable.
-==> NEW <==
-As of Zip 2.2, this default has been changed to use PK style extra field
-format. This change is needed to support indexed VMS files. The
-IM style code in UnZip (!!) has a known problem that prevents the correct
-restoring operation for some (but not all) indexed VMS files.
-
-IMPORTANT: To extract new PK style extra fields, Info-ZIP's
- UnZip version 5.2 or newer is required, previous
- versions will crash with an access violation !!!!
-
-If you want to use the old IM style support (to achieve compatibility
-with older versions of UnZip), the preprocessor symbol VMS_IM_EXTRA
-has to be defined at compile time.
-
-MMS (MMK) users have to edit vms/descrip.mms and add this symbol to
-the definition of the COMMON_DEFS macro; for example:
-
-COMMON_DEFS = VMS_IM_EXTRA,
-
-if VMS_IM_EXTRA is the only option. (NOTE the trailing comma!)
-
-Users of the DCL make procedure can select the PK style support by defining
-the DCL symbol LOCAL_ZIP as a list of user specific compilation options
-(do not forget the trailing comma!!). Example:
-$ LOCAL_ZIP == "VMS_IM_EXTRA,"
-
-
-B) Notes on the compiler switches used on VMS:
- ===========================================
-
-The source has been successfully compiled on VMS 6.1 (VMS 6.2 for AXP), using
- - DEC C 5.2 and 5.6 for Alpha AXP
- - DEC C 4.0 for VMS VAX
- - VAX C 3.2
-
-1. Discussion of the /STANDARD switch:
-
-With the exception of some few rough spots in the VMS specific sources,
-the code is fully compatible with the "RELAXED_ANSI" mode of the DEC C
-compilers. The problems found in vmsmunch.c and vms_pk.c are caused
-by incompatibles between the system include headers supplied for DEC C
-(AXP) and DEC C (VAX) which cannot get worked around. (Some system
-service structure members have type "unsigned int" in the VAX version,
-but "pointer to [miscellanous]" in the AXP headers.)
-I consider the AXP headers to show the direction of `future developement'
-and have adapted the sources to match the AXP's header files.
-This means:
-On Alpha AXP, we can equally well use "/STANDARD=RELAXED" instead of
-"/STANDARD=VAXC" without getting any warnings.
-With the current release of DEC C on VAX, the /STANDARD=VAXC switch is
-required to suppress the "assignment to incompatible type" warnings.
-Beginning with the Zip 2.1 release, the compiler mode for Alpha AXP has
-been changed to "/STANDARD=RELAX", since the "ANSI mode" executables are
-slightly smaller.
-
-2. The /PREFIX_LIBRARY_ENTRIES switch:
-
-In (strict and relaxed) ANSI mode on Alpha AXP, only the standard ANSI
-RTL function names get prefixed with "DECC$" by the compiler per default.
-This results in unresolved references to such functions as "read()", "open()"
-"lseek()" at link step. (The same might be true for earlier releases of DEC C
-on VAX.) To resolve this problem, one has to explicitely request prefixing
-of all DEC C RTL function by applying the "/PREFIX=ALL" switch.
-Although this switch is not needed in "VAXC" mode, it does not hurt either.
-Therefore, "/PREFIX=ALL" is applied regardless of the compilation mode,
-to avoid any problems when switching over to ANSI standard mode in the future.
-
-C) Support for UT extra field UTC time stamps
- ==========================================
-Beginning with Zip 2.1 and UnZip 5.2, the Info-ZIP compression utilities
-do principally support saving and restoring the modification time of
-Zipfile entries as UTC (GMT) universal time. This new information is
-stored in an "extra field" labeled "UT" (Unix style GMT modification/access
-times, ...).
-Previous version of Zip and UnZip used local time, stored in MSDOS compatible
-format (as specified by PKware for the Zip file format). This practice caused
-a lot of "time synchronization" trouble when transporting Zip archives world
-wide between largely different time zones.
-
-Unfortunately, VMS (and the VMS C runtime environment) up to VMS 6.x does not
-contain support for timezone handling and assumes "local time == UTC time".
-This has changed with the release of VMS 7.0, which does (finally) support
-the concept of "universal world time" that is required for time synchronization
-in intercontinental networks...
-
-For this reason, the UTC time stamp support is disabled in VMS Zip by default,
-otherwise users would experience annoying time stamp deviations when
-locally transfering Zip archives between VMS nodes and other (UNIX, OS/2,
-WinNT/Win95, MSDOS) systems.
-But when compiled on a VMS 7.x system, the UTC "UT extra field" support is
-automatically enabled.
-
-For users located in the GMT time zone (or a nearby timezone, like CET),
-it might be worthwhile to enable UTC support by hand.
-
-The default configuration can be overridden by defining one of the
-following preprocessor macro:
-
- USE_EF_UT_TIME includes "UT" time stamp support
- NO_EF_UT_TIME disables "UT" time stamp support
-
-When using MMS/MMK, you should add the appropiate symbol to the "COMMON_DEFS"
-list in vms/descrip.mms; if the command procedure is used for compiling,
-you can add the macro to the "LOCAL_ZIP" DCL symbol.
-
-14-Oct-1997 Christian Spieler
diff --git a/vms/NOTES.TXT b/vms/NOTES.TXT
new file mode 100644
index 0000000..4f94ec3
--- /dev/null
+++ b/vms/NOTES.TXT
@@ -0,0 +1,382 @@
+ VMS Notes for Info-ZIP Zip 3.0 and UnZip 6.0
+ ============================================
+
+ This document describes some VMS-specific behavior and implementation
+details of the Info-ZIP Zip and UnZip programs.
+
+ Last modified: 2008-04-10.
+
+
+ Command-line Case
+ -----------------
+
+ Zip and UnZip now include code which can preserve the case of
+command-line parameters and options, which obviates quoting upper-case
+options like "-V" or "-Z". This works on non-VAX systems with a
+sufficiently recent C RTL, and SET PROCESS /PARSE_STYLE = EXTENDED.
+(Sufficiently recent here means __CRTL_VER >= 70301000, which includes
+VMS V7.3-1 with a C Run Time Library ECO, or V7.3-2 or newer.) This
+code uses the decc$feature_set_value() function to enable the
+DECC$ARGV_PARSE_STYLE feature. There is a small range of C RTL versions
+where this function is unavailable, but where manually setting the
+logical name DECC$ARGV_PARSE_STYLE to "ENABLE" will work. HELP CRTL
+leads to some additional information on these features.
+
+
+ File Name Case (ODS5)
+ ---------------------
+
+ In general, Zip 3.0 and UnZip 6.0 should handle file name case (and
+extended file names) in reasonable ways on ODS5 disks.
+
+ Zip offers a variety of "-C" (/PRESERVE_CASE) options to control how
+case is handled when adding files to an archive. The default settings
+("-C2-", /PRESERVE_CASE = NOODS2, down-case ODS2 file names; "-C5",
+/PRESERVE_CASE = ODS5, preserve case of ODS5 file names) should be
+consistent with previous Zip versions for files on ODS2 disks, and
+reasonable for files on ODS5 disks.
+
+ UnZip should preserve case when it extracts to an ODS5 destination
+disk (unless "-2" (/ODS2) is specified). (Note that previous UnZip
+versions, including version 5.52, did not properly preserve case for
+directories, which were always up-cased.)
+
+ The Zip and UnZip builders should work properly on ODS2 and ODS5
+disks, with old (pre-ODS5) and new (case-conscious) versions of MMS (or
+MMK). All testing was done with SET PROCESS /CASE_LOOKUP = BLIND.
+Various problems may be expected with /CASE_LOOKUP = SENSITIVE.
+
+ For consistency, the builders should always create product files
+(.OBJ, .EXE, .HLB, and so on) with upper-case names, whether the build
+is done on an ODS2 or ODS5 disk. Note, however, that in a world with
+both ODS2 and ODS5 disks, and old and new Zip and UnZip versions, it's
+possible to encounter lower-case product file names. For example, a VMS
+binary kit could be created on an ODS2 disk, and a Zip archive created
+from that (using Zip 2.x, or Zip 3.x with default settings). Such a Zip
+archive would contain down-cased names for those product files, and
+those lower-case names would then normally be preserved when UnZip was
+used to extract that archive onto an ODS5 destination. Normally, things
+will work regardless of such case changes, but there may be some
+untested combinations of unexpected name cases and quirky MMS (or MMK)
+behavior, where something goes wrong. Complaints are always welcome,
+but it may not be possible to get everything to work as expected with
+every version of VMS, MMS (or MMK), Zip, and UnZip, on every file
+system.
+
+ It might help matters if _all_ VMS binary kits were produced on ODS5
+disks, and packaged using (case-preserving) Zip version 3.x, but this
+would certainly be different from the way things have been done before,
+and maintaining control over this process is essentially impossible.
+
+
+ Symbolic Links (ODS5)
+ ---------------------
+
+ VMS V8.3 offers support for symbolic links (symlinks) on ODS5 disks.
+In previous Zip and UnZip versions, the generic code for symlinks was
+disabled, and there was no VMS-specific code for symlinks. Now, by
+default, Zip and UnZip attempt to support symlinks wherever the C
+headers and C run-time library include the functions needed for symlink
+support. This means non-VAX systems with __CRTL_VER >= 70301000, so
+this includes VMS V7.3-1 and up, and thus symlink-capable Zip and UnZip
+programs may be built on systems which do not themselves offer symlink
+support. (Various run-time failures may be expected if symlinks are
+encountered on pre-V8.3 systems, either in a file system or in a Zip
+archive.)
+
+ Symlink support can be disabled at build-time, if desired, by
+defining the C macro NO_SYMLINKS. (See comments in the builder
+regarding LOCAL_UNZIP or LOCAL_ZIP, as appropriate.) For example, using
+MMS to build UnZip:
+
+ MMS /DESCRIP = [.VMS] /MACRO = ("LOCAL_UNZIP=NO_SYMLINKS=1")
+
+or, using the command procedure to build Zip:
+
+ LOCAL_ZIP == "NO_SYMLINKS=1"
+ @ [.VMS]BUILD_ZIP.COM
+ DELETE /SYMBOL /GLOBAL LOCAL_ZIP
+
+ The Zip "-v" (/VERBOSE) report should include SYMLINK_SUPPORT in its
+list of "Zip special compilation options" if Zip was built with symlink
+support. Currently, UnZip is less convenient, but searching the UnZip
+executable (or EXTRACT.OBJ) for "symlink" should fail if symlink support
+is missing (or succeed if it's present):
+
+ $ SEARCH /NOOUTPUT UNZIP.EXE SYMLINK ! No symlink support.
+ %SEARCH-I-NOMATCHES, no strings matched
+or:
+ $ SEARCH /NOOUTPUT EXTRACT.OBJ SYMLINK ! Symlink support.
+ $ SHOW SYMBOL $STATUS
+ $STATUS == "%X00000001"
+
+
+ File I/O Performance
+ --------------------
+
+ When compiled using DEC/Compaq/HP C (not GNU C or VAX C), the Zip and
+UnZip file I/O code now includes access callback functions which are
+used to try to set some RMS parameters to non-default values, with the
+intention of improving file I/O speed. This affects reading an archive
+file in UnZip and writing one in Zip. (Reading and writing the
+individual data files are handled in more exotic ways, making these
+parameters less important for them.)
+
+ Currently, the built-in default parameters enable read-ahead and
+write-behind, using a multi-buffer count of 2, and a multi-block count
+of 127 (the maximum). For writing the archive, the default extend
+quantity is 16384 blocks (8MB), with truncation enabled. This
+combination is believed to be, at worst, fairly harmless for most
+situations, and, in most cases, to provide a substantial speed
+improvement, especially with large archives.
+
+ This code allows SET RMS_DEFAULT parameters to override the built-in
+default values. On some old VMS versions, sys$getjpi() can not provide
+the SET RMS_DEFAULT values, and in this situation, the callback function
+will not try to use its improved parameter values. Users on such old
+VMS versions who seek improved I/O speed may wish to bypass this check,
+which requires changing the code in the get_rms_defaults() function in
+[.VMS]VMS.C. The "-vv" (/VERBOSE = MORE) option on both programs
+enables diagnostic messages which show the operation of the callback
+function. A message showing a failure status from sys$getjpi()
+indicates this problem.
+
+ Sample results (UnZip shown, Zip similar):
+
+ VMS VAX V5.4, VAX C. Callback code disabled, no messages:
+ WIMP $ unzip -tvv TESTMAKE.ZIP
+ Archive: SYS$SYSDEVICE:[UTILITY.SOURCE.ZIP.UNZIP60C]TESTMAKE.ZIP;1
+ [...]
+
+ VMS VAX V5.5-2, DEC C. SYS$GETJPI() fails (%SYSTEM-F-BADPARAM):
+ WEAK $ unzip -tvv TESTMAKE.ZIP
+ Get RMS defaults. getjpi sts = %x00000014.
+ Archive: DUA1:[UTILITY.SOURCE.ZIP.UNZIP60C]TESTMAKE.ZIP;1
+ [...]
+
+ VMS VAX V7.3, DEC/Compaq C. Callback code works:
+ WUSS $ unzip -tvv TESTMAKE.ZIP
+ Get RMS defaults. getjpi sts = %x00000001.
+ Default: deq = 0, mbc = 0, mbf = 0.
+ Open callback. ID = 1, deq = 16384, mbc = 127, mbf = 2.
+ Archive: ALP$DKA0:[UTILITY.SOURCE.ZIP.UNZIP60C]TESTMAKE.ZIP;1
+ [...]
+
+ VMSV5.5-2 is too old. V7.3 is new enough. Anyone with more precise
+information is invited to contribute it.
+
+ Users who find other parameter sets more beneficial, or who find
+particular problems with this set are welcome to comment.
+
+ In this version, as in previous versions, when UnZip expands a -V
+archive, it allocates the entire extent of a data file before writing
+any of its data. In some previous versions, this could cause the
+destination disk to be locked for a considerable time (minutes), if
+highwater marking was enabled on that disk. Now, the FAB SQO
+("sequential access only") flag (or equivalent) is set, which prevents
+this troublesome disk locking.
+
+ In some previous versions, when UnZip expanded a non-V archive, it
+did no pre-allocation, and used the default extension quantity. This
+could slow file creation significantly for large files. Now, space for
+extracted files is pre-allocated, and the same SQO ("sequential access
+only") flag is set, as with a -V archive.
+
+
+ Changes to the "-V" (/VMS) Option
+ ---------------------------------
+
+ The intent of the "-V" (/VMS) option was to store VMS file attributes
+in a Zip archive, allowing UnZip to extract an exact copy of a file on a
+VMS system, including all its VMS attributes.
+
+ In Zip before version 2.31, using the "-V" (/VMS) option created an
+archive which usually contained data from beyond the EOF (End-of-File)
+marker in a data file, but generally not all the disk blocks allocated
+for the file. When extracted on a VMS system, the result was usually
+acceptable (because the data from beyond the EOF marker were usually
+ignored). However, when extracted on a non-VMS system, the resulting
+file was usually corrupted by being NUL-padded to the next larger 16KB
+multiple in size.
+
+ Now (Zip 2.31 and later), with "-V" (/VMS), Zip truncates a data file
+at EOF, and portable-format files (Stream_LF, fixed-512) should be
+extracted properly on a non-VMS system. On a VMS system, well-formed
+files (that is, those with no valid data beyond EOF) should also be
+restored correctly.
+
+ With the new "-VV" (/VMS = ALL) option, the archive includes all
+allocated blocks for the file (including those beyond EOF). When
+extracted on a VMS system, the original file should be reproduced with
+as much fidelity as possible, but on a non-VMS system, most files will
+be seen as corrupt because of the data from beyond EOF.
+
+
+ Changes to Program Exit Status Values
+ -------------------------------------
+
+ Zip and UnZip exit with 32-bit VMS status values which are formed
+from their internal OS-independent status values. In previous program
+versions, this was done by converting the internal success code (0) into
+%x00000001 (SS$_NORMAL), and converting the other internal warning and
+error codes using an artificial control/facility code, 0x7FFF (which
+includes some reserved bits), and a severity value which was determined
+according to rules specified in the VMS-specific exit function.
+Curiously, the internal status codes were left-shifted by 4 bits instead
+of 3, so all the resulting VMS message codes (bits 13:3) were even.
+
+ Zip and UnZip now have facility names and codes assigned by HP
+(UnZip: IZ_UNZIP, 1954; Zip: IZ_ZIP, 1955). Now, by default, the
+programs exit with standard 32-bit VMS status values which differ from
+the old ones in several ways: The official facility code is used, and
+the facility-specific bit is set. (For compatibility with older
+versions, the internal status codes are still left-shifted by 4 bits.
+This also makes it easier to extract the internal status code from a
+hexadecimal representation of the VMS status code.) The builders also
+create non-executable message files (UNZIP_MSG.EXE and ZIP_MSG.EXE) so
+that, after a suitable SET MESSAGE command, the program messages will be
+available from DCL. For example:
+
+ $ SET MESSAGE dev:[dir]ZIP_MSG.EXE
+ $ ZIP FRED.ZIP no_such_file
+ zip warning: name not matched: no_such_file
+
+ zip error: Nothing to do!
+ (dev:[dir]FRED.ZIP;)
+
+ ALP $ WRITE SYS$OUTPUT F$MESSAGE( $STATUS)
+ %IZ_ZIP-W-NONE, Nothing to do
+
+The message files may be copied into SYS$MESSAGE to make them generally
+available, although this could cause some confusion if multiple versions
+of the programs are used on the system, and their error message source
+files differ. Each different destination directory will get its own
+UNZIP_MSG.EXE or ZIP_MSG.EXE ([.ALPHA], [.ALPHAL], [.VAX], and so on),
+but all of the same-architecture files are equivalent to each other.
+That is, on an Alpha system, any of the [.ALPHA*]ZIP_MSG.EXE files could
+be used; on an IA64 system, any of the [.IA64*]ZIP_MSG.EXE files could
+be used; and on a VAX system, any of the [.VAX*]ZIP_MSG.EXE files could
+be used. (Similar for UNZIP_MSG.EXE, of course.)
+
+ If desired, the programs may be built to use the old exit status values
+by defining a C macro with the old facility value:
+"CTL_FAC_IZ_UNZIP=0x7FFF" (UnZip) or "CTL_FAC_IZ_ZIP=0x7FFF" (Zip).
+(See comments in the builder regarding LOCAL_UNZIP or LOCAL_ZIP, as
+appropriate.) This will maintain compatibility with older program
+versions, but will make the programs incompatible with the new error
+message files.
+
+
+ VMS File Attribute Schemes
+ --------------------------
+
+ Zip's "-V" (/VMS) option causes VMS file attributes to be stored in
+an archive. Since Zip version 2.2 (released in 1996), Zip has, by
+default, stored VMS file attributes using a scheme ("PK") which is
+compatible with the one used by PKWARE in their PKZIP product. Before
+that, a different scheme ("IM") was used. UnZip versions before 5.2
+support only the older IM scheme, but since UnZip version 5.2, both
+schemes have been supported by UnZip.
+
+ The IM scheme has not been well tested recently, but it is still
+available. Some problems were seen when the IM scheme was used with
+symbolic links on VMS V8.3. Details on how build Zip to use the IM
+scheme instead of the PK scheme are included in comments in the main
+builder files. Look for VMS_IM_EXTRA in [.VMS]BUILD_ZIP.COM or IM in
+[.VMS]DESCRIP.MMS.
+
+ The "special compilation options" section of a "zip -v" ("zip
+/verbose") report should show either VMS_PK_EXTRA or VMS_IM_EXTRA,
+according to how Zip was built.
+
+
+ UTC Date-Times
+ --------------
+
+ Zip archives traditionally include local (MS-DOS compatible)
+date-time information for files. Since Zip version 2.1, it has also
+been possible to store UTC date-time information in the archive, and
+since UnZip version 5.2, UnZip has been able to use this UTC date-time
+information when extracting files.
+
+ On VMS, support in the C run-time environment for UTC became
+available with VMS V7.0. UTC support in Zip and UnZip is automatically
+enabled at compile time, if it is available on the system where the code
+is compiled (__CRTL_VER >= 70000000). It may be disabled at compile
+time by defining the C macro NO_EF_UT_TIME. Details on how build Zip
+and UnZip with additional C macros defined are included in comments in
+the main builder files. Look for LOCAL_[UN]ZIP in
+[.VMS]BUILD_[UN]ZIP.COM or in [.VMS]DESCRIP.MMS. For example, using MMS
+to build UnZip:
+
+ MMS /DESCRIP = [.VMS] /MACRO = ("LOCAL_UNZIP=NO_EF_UT_TIME=1")
+
+or, using the command procedure to build Zip:
+
+ LOCAL_ZIP == "NO_EF_UT_TIME=1"
+ @ [.VMS]BUILD_ZIP.COM
+ DELETE /SYMBOL /GLOBAL LOCAL_ZIP
+
+ The "special compilation options" section of a "zip -v" ("zip
+/verbose") or "unzip -v" ("unzip /verbose") report should show
+USE_EF_UT_TIME if the program was built with UTC support.
+
+
+ Building with the LIST option using MMK or MMS
+ ----------------------------------------------
+
+ Currently, building with MMK or MMS using the LIST option (as in
+"/MACRO = LIST=1") may cause a failure for some old versions of the DEC
+C compiler. The LIST option currently adds "/show = (all, nomessages)"
+to the CC command line, and some old DEC C compilers do not support the
+"nomessages" keyword. When VAX C is used, this keyword is omitted, but
+the builder does not distinguish between the various DEC/Compaq/HP C
+versions. The work-arounds are to use BUILD_[UN]ZIP.COM, or edit
+[.VMS]DESCRIP_SRC.MMS to remove the troublesome keyword.
+
+
+ GNU C
+ -----
+
+ Zip and UnZip have been built using GNU C (VAX) version 2.3, mostly
+for fun, but serious users are encouraged to report any interest in
+continuing this activity. The GNU C 2.3 header files were missing some
+things, including definitions of SEEK_CUR, SEEK_END, and SEEK_SET. The
+VMS-specific code now expects to find unixio.h and unixlib.h, which were
+absent from the GNU C 2.3 distribution.
+
+ To work around these difficulties, the Zip and UnZip kits include
+some emergency replacement unixio.h and unixlib.h files which appear to
+work for these programs, at least. To install them, use commands like
+the following:
+
+ COPY [.VMS]UNIXIO_GCC.H GNU_CC_INCLUDE:[000000]UNIXIO.H
+ COPY [.VMS]UNIXLIB_GCC.H GNU_CC_INCLUDE:[000000]UNIXLIB.H
+ SET PROTECTION W:RE GNU_CC_INCLUDE:[000000]UNIXIO.H, UNIXLIB.H
+
+ There may be an error in the GNU C header file ATRDEF.H which can
+cause Zip to fail, when making a "-V" archive, with a spurious "could
+not open for reading" error message, followed by more bad behavior. It
+probably also causes trouble of some kind in UnZip. To check the
+questionable macro definition, use a command like the following:
+
+ SEARCH GNU_CC_INCLUDE:[000000]ATRDEF.H ATR$S_JOURNAL
+
+This should show something equivalent to this:
+
+ #define ATR$S_JOURNAL 0x001
+
+If you see "0x002" (or equivalent) instead of "0x001" (or equivalent),
+then this value must be corrected in the file before building Zip or
+UnZip.
+
+ You may also see several warnings from the compiler caused by other
+defects in the GNU C header files, such as:
+
+<various>: warning: passing arg 4 of `qsort' from incompatible pointer type
+
+[...]rab.h:134: warning: unnamed struct/union that defines no instances
+[...]rab.h:143: warning: unnamed struct/union that defines no instances
+
+These warnings appear to be harmless.
+
diff --git a/vms/VMS_ZIP.RNH b/vms/VMS_ZIP.RNH
new file mode 100644
index 0000000..183ceea
--- /dev/null
+++ b/vms/VMS_ZIP.RNH
@@ -0,0 +1,1467 @@
+.!
+.! File: ZIP.RNH
+.!
+.! Author: Hunter Goatley
+.!
+.! Date: October 22, 1991
+.!
+.! Description:
+.!
+.! RUNOFF source file for portable ZIP on-line help for VMS.
+.! Adapted from MANUAL, distributed with ZIP.
+.!
+.! To build: $ RUNOFF ZIP.RNH
+.! $ LIBR/HELP/INSERT libr ZIP
+.!
+.! Modification history:
+.!
+.! Hunter Goatley 22-OCT-1991 20:45
+.! Genesis.
+.! Jean-loup Gailly 25 March 92
+.! Adaptation to zip 1.6.
+.! Igor Mandrichenko 9-JUN-1992
+.! Added explanation of -V option.
+.! Jean-loup Gailly 14 June 92
+.! Adaptation to zip 1.8.
+.! Jean-loup Gailly 20 Aug 92
+.! Adaptation to zip 1.9.
+.! Jean-loup Gailly 31 Aug 93
+.! Adaptation to zip 2.0.
+.! Christian Spieler 20 Sep 93
+.! Adaptation to zip 2.0 and OpenVMS completed.
+.! Christian Spieler 05 Dec 95
+.! Adaptation to zip 2.1, new options.
+.! Christian Spieler 20 Jan 96
+.! Changed -L and -v descriptions.
+.! Christian Spieler 11 Feb 96
+.! Added -X option.
+.! Onno van der Linden,
+.! Christian Spieler 13 Mar 96
+.! Removed -ee option.
+.! Christian Spieler 09 Feb 96
+.! Updated copyright notice, Zip version.
+.! Christian Spieler 21 Jul 97
+.! Added -P, -R, -i@, -x@ and -tt options, modified for Zip 2.2.
+.! Christian Spieler 14 Oct 97
+.! unified spelling of "Info-ZIP", final cleanups for 2.2.
+.! Steven Schweda 10 May 2007
+.! General update for version 3.0.
+.! Ed Gordon 12 May 2007
+.! Minor updates for version 3.0.
+.!
+.noflags
+.lm4 .rm72
+.indent -4
+1 ZIP
+.br
+Zip is a compression and file packaging utility for several operating
+systems, including UNIX, VMS, MSDOS, OS/2, Windows 9x/NT/XP, Minix, Atari,
+Macintosh, Amiga, and Acorn RISC OS. It is analogous to a combination of
+tar and compress and is compatible with PKZIP (Phil Katz's ZIP) for
+MSDOS systems.
+.sk
+Zip 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. A companion program, UnZip, unpacks Zip
+archives.
+.sk
+For brief help on Zip or UnZip, run the program without specifying any
+parameters on the command line.
+.sk
+This description covers the Zip program which uses a UNIX-style command
+line. A separate program is available which provides a VMS-style CLI
+command line, and it has its own documentation. Refer to the Zip
+installation instructions for details.
+.sk
+Format
+.sk;.lm+2;.literal
+ZIP [-options] archive inpath inpath ...
+.end literal;.lm-2
+.!------------------------------------------------------------------------------
+.indent -4
+2 Basic_Usage
+.br
+Format
+.sk;.lm+2;.literal
+ZIP [-options] archive inpath inpath ...
+.end literal;.lm-2
+.sk
+The default action of Zip is to add or replace entries in "archive" from
+the list of "inpath" file specifications, which can include directories
+and file names with VMS-style wildcards, or the special name -@ to read
+file specifications from SYS$INPUT (stdin).
+.sk
+With SET PROCESS /PARSE_STYLE = EXTENDED (available on recent non-VAX
+systems), Zip preserves the case of the command line. Otherwise, mixed-
+or upper-case options and arguments must be quoted. For example,
+"-V". Examples in this document generally do not show this quotation,
+so VAX and /PARSE_STYLE = TRADITIONAL users (that is, troglodytes) will
+need to add quotation where needed when working with these examples.
+.sk
+General
+.sk
+Zip reads one or more files, compresses the data (normally), and stores
+the compressed information into a single Zip archive file, along with
+information about each file (name, path, date and time of last
+modification, protection, and check information to verify file
+integrity). On a VMS system, Zip can also save VMS/RMS file attributes,
+allowing UnZip to restore the files without loss of important file
+attributes. Zip can pack an entire directory structure into a Zip
+archive with a single command.
+.sk
+Compression
+.sk
+Compression ratios of 2:1 to 3:1 are common for text files. Zip has one
+standard compression method ("deflate") and can also store files without
+compression. Zip (and UnZip) may be built with optional support for the
+bzip2 compression method. Then, the user may select bzip2 compression
+instead of the default "deflate" method. Zip automatically chooses
+simple storage over compression for a file, if the specified compression
+method does not actually compress the data in that file.
+.sk
+Compatibility
+.sk
+Zip and UnZip 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 Zip (with some exceptions, notably streamed
+archives, but recent changes in the .ZIP file standard may facilitate
+better compatibility). Zip version 3.0 is compatible with PKZIP 2.04
+and also supports the Zip64 extensions of PKZIP 4.5 which allows
+archives as well as files to exceed the previous 2 GB limit (4 GB in
+some cases). Zip also supports bzip2 compression if the bzip2 library
+is included when Zip is built. Note that PKUNZIP 1.10 cannot extract
+files produced by PKZIP 2.04 or Zip 3.0. You must use PKUNZIP 2.04g or
+UnZip 5.0p1 (or later versions) to extract them.
+.sk
+Large Archives and Zip64
+.sk
+Where the operating system and C run-time support allow, Zip 3.0 and
+UnZip 6.0 (and later versions) support large files (input and archive),
+using the Zip64 extensions to the original .ZIP file format. On VMS,
+this genarally means non-VAX systems with VMS V7.2 or later (perhaps
+requiring a C RTL ECO before VMS V7.3-2).
+.sk
+Zip automatically uses the Zip64 extensions when a file larger than 2 GB
+is added to an archive, an archive containing a Zip64 entry 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 to a
+non-seekable output device. You must use a 4.5 compatible UnZip to
+extract files using the Zip64 extensions such as UnZip 6.0 or later.
+.sk
+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 file standard now include some
+support for the data descriptor format Zip uses).
+.!------------------------------------------------------------------------------
+.indent -4
+2 More_Usage
+.br
+Here is a very simple example of Zip use:
+.sk;.indent 10;
+$ zip stuff.zip *.*
+.sk
+This will create the Zip archive "stuff.zip" (assuming it does not
+already exist) and put all the (non-directory) files (";0") from the
+current default directory into "stuff.zip" in a compressed form. The
+archive is opened using a default file specification of
+"SYS$DISK:[].zip", so specifying "stuff" as the archive name would also
+create (or use an existing) "stuff.zip", but specifying "stuff.other"
+would give you that name. In general, Zip doesn't care about the type
+in the file specification, but for split archives (archives split over
+multiple files), the user should normally specify a type-less name,
+because Zip will normally generate sequentially numbered types ".z01",
+".z02", and so on for the early splits, and then the required ".zip" for
+the last split. These file types are required by the Zip standard for
+split archives.
+.sk
+Standard VMS wildcard expansion ($SEARCH) is used to interpret the
+"inpath" file and directory specifications, like the "*.*" in this
+example.
+.sk
+On VMS, the most natural way to archive an entire directory tree is to
+use a directory-depth wildcard ("[...]"). For example:
+.sk;.indent 10
+zip foo [...]*.*
+.sk
+This will create the file "foo.zip" containing all the files (";0") and
+directories in and below the current default directory. A more
+UNIX-like way to do this would be to use the -r (--recurse-paths)
+option:
+.sk;.indent 10
+$ zip -r foo *.*
+.sk
+Zip avoids including its own output files when selecting files to
+include in the archive, so it should be safe, as in this case, to create
+the archive in the same drectory as the input files.
+.sk
+One or more specific files, directories, or subdirectories may also be
+specified:
+.lm +10;.literal
+zip foo.zip readme.txt [www...]*.* [.ftp...]*.* -
+ [.src]*.h [.src]*.c
+.end literal;.lm -10
+.sk
+For security reasons, paths in Zip archives are always stored as
+relative paths, so some care is needed when creating an archive so that
+it will create the intended directory structure when UnZip is used to
+unpack it.
+.sk
+To use -r with a specific directory, the name of the directory file
+itself must be specified:
+.sk;.indent 10
+zip -r foo.zip [000000]www.dir ftp.dir
+.sk
+You may want to make an archive that contains the files in [.foo], but not
+record the directory name, "foo". You can use the -j (junk path) option
+to leave off the path:
+.sk;.indent 10
+$ zip -j foo [.foo]*.*
+.sk
+If you are short on disk space, you might not have enough room to hold
+both the original directory and the corresponding compressed Zip
+archive. In this case, you can create the archive in steps, and use the
+-m option. For example, if [.foo] contains the subdirectories [.tom],
+[.dick], and [.harry], you could:
+.sk
+.lm +10;.literal
+zip -m foo [.foo.tom...]*.*
+zip -m foo [.foo.dick...]*.*
+zip -m foo [.foo.harry...]*.*
+.end literal;.lm -10
+.sk
+The first command would create foo.zip, and the next two would add to
+it. The -m option means "move", and it will cause Zip to delete all
+files added to the archive after making or updating foo.zip. No
+deletions will be done until the Zip operation has completed with no
+errors. This option is obviously dangerous and should be used with
+care, but it does reduce the need for free disk space. When -m is
+used, the -T option is recommended and will test the resulting archive
+before deleting the input files.
+.sk
+If a file specification list is too long to fit conveniently on the Zip
+command line, the -@ option can be used to cause Zip to read a list of
+file specifications from SYS$INPUT (stdin). If a DCL command procedure
+is used, the names can be specified in the procedure:
+.sk;
+.lm +10;.literal
+$ zip foo -@
+$ deck
+file_spec_1
+file_spec_2
+file_spec_3
+$ eod
+.end literal;.lm -10
+.sk
+The file specifications can also be put into a separate file, and fed
+into Zip by explicitly defining SYS$INPUT, or by using PIPE. For
+example, with the list in foo.zfl:
+.sk;
+.lm +10;.literal
+$ define /user_mode sys$input foo.zfl
+$ zip foo -@
+.end literal;.lm -10;
+or:
+.lm +10;.literal
+$ pipe type foo.zfl | zip foo -@
+.end literal;.lm -10
+.sk
+If Zip is not able to read a file, it issues a warning but continues.
+See the -MM option for more on how Zip 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.
+.!------------------------------------------------------------------------------
+.indent -4
+2 Comments
+.br
+One-line comments may be included in the archive for each file added,
+using the -c (--entry-comments) option. File operations (adding,
+updating) are done first, and the user is then prompted for a one-line
+comment for each file added or updated. Enter the comment followed by
+<Return>, or just <Return> for no comment.
+.sk
+A single multi-line comment may be included for the archive as a whole,
+using the -z (--archive-comment) option. UnZip (including UnZip SFX)
+will display this comment when it expands the archive. The comment is
+read from SYS$INPUT (stdin), and is terminated by the usual end-of-file
+character, CTRL/Z. As usual, in a DCL command procedure, these data can
+be included in-line in the procedure, or a user may DEFINE SYS$INPUT to
+a file to get the comment from that file. Where supported, the DCL PIPE
+command can also be used to redirect SYS$INPUT from a file.
+.sk
+Note that -z (--archive-comment) and -@ (read file specifications from
+SYS$INPUT (stdin)) can't be used together (successfully).
+.!------------------------------------------------------------------------------
+.indent -4
+2 Compression
+.br
+Zip can archive files with or without compression. The standard
+compression method ("deflate") is compatible with all UnZip versions
+(except really old ones that only understand the "store" method).
+Current Zip and UnZip versions may be built with optional support for
+the bzip2 compression method. (The bzip2 method can compress better,
+especially when compressing smaller files, but uses more CPU time, and
+requires an UnZip which includes the optional bzip2 support. See the
+installation instructions for details on adding bzip2 compression
+support at build time.)
+.sk
+Numeric compression level options control the effort put into data
+compression, with -1 being the fastest, and -9 giving the most
+compression.
+.sk
+Compression control options:
+.sk;.lm +10;.literal
+-Z mthd use compress method "mthd",
+--compression-method mthd "bzip2" or "deflate" (default)
+
+-0 (--store) no compression
+-1 (--compress-1) compression level 1
+-2 (--compress-2) compression level 2
+-3 (--compress-3) compression level 3
+-4 (--compress-4) compression level 4
+-5 (--compress-5) compression level 5
+-6 (--compress-6) compression level 6
+-7 (--compress-7) compression level 7
+-8 (--compress-8) compression level 8
+-9 (--compress-9) compression level 9
+.end literal;.lm -10
+.sk
+Normally, a file which is already compressed will not be compressed much
+further (if at all) by Zip, and trying to do it can waste considerable
+CPU time. Zip can suppress compression on files with particular types,
+specified as a colon- or semi-colon-separated list of file types:
+.sk;.indent 10
+-n type1[:type2[...]] (--suffixes type1[:type2[...]])
+.sk
+For example:
+.sk;.indent 10
+zip -n .bz2:.gz:.jpeg:.jpg:.mp3:.zip foo [.foo]*.*
+.sk
+will put everything (";0") from [.foo] into foo.zip, but will store any
+files that end in .bz2, .gz, .jpeg, .jpg, .mp3, or .zip, without trying
+to compress them.
+.sk
+The default type list is .Z:.zip:.zoo:.arc:.lzh:.arj, and the comparison
+is case-insensitive.
+.sk
+-9 (--compress-9) will override -n (--suffixes), causing compression to
+be attempted for all files.
+.!------------------------------------------------------------------------------
+.indent -4
+2 Encryption
+.br
+Zip offers optional encryption, using a method which by modern standards
+is generally considered to be weak.
+.sk;.literal
+-e --encrypt
+.end literal;.br
+Encrypt new or updated archive entries using a password which is
+supplied by the user interactively on the terminal in response to a
+prompt. (The password will not be echoed.) If SYS$COMMAND is not a
+terminal, Zip will exit with an error. The password is verified before
+being accepted.
+.sk;.literal
+-P password --password password
+.end literal;.br
+Use "password" to encrypt new or updated archive entries (if any).
+USING -P IS INSECURE! Many multi-user operating systems provide ways
+for any user (or a privileged user) to see the current command line of
+any other user. Even on more secure systems, there is always the threat
+of over-the-shoulder peeking. Storing the plaintext password as part of
+a command line in a command procedure is even less secure. Whenever
+possible, use the non-echoing, interactive password entry method.
+.sk
+Because standard Zip encryption is weak, where security is truly
+important, use a strong encryption program, such as Pretty Good Privacy
+(PGP) or GNU Privacy Guard (GnuPG), on an archive instead of standard
+Zip encryption. A stronger encryption method, such as AES, is planned
+for Zip 3.1.
+.!------------------------------------------------------------------------------
+.indent -4
+2 Exit_Status
+.br
+On VMS, Zip's UNIX-style exit values are mapped into VMS-style status
+codes with facility code 1955 = %x7A3, and with the inhibit-message
+(%x10000000) and facility-specific (%x00008000) bits set:
+.sk
+.literal
+ %x17A38001 normal exit
+ %x17A38000+ 16* Zip_error_code warnings
+ %x17A38002+ 16* Zip_error_code normal errors
+ %x17A38004+ 16* Zip_error_code fatal errors
+.end literal
+.sk
+Note that multiplying the UNIX-style Zip error code by 16 places it
+conveniently in the hexadecimal representation of the VMS exit code,
+"__" in %x17A38__s, where "s" is the severity code. For example, a
+truncated archive might cause Zip error code 2, which would be
+transformed into the VMS exit status %x17A38024.
+.sk
+The Zip VMS exit codes include severity values which approximate those
+defined by PKWARE, as shown in the following table:
+.literal
+
+ VMS Zip err
+ severity code Error description
+ ----------+---------+----------------------------------------------
+ Success 0 Normal; no errors or warnings detected.
+ Fatal 2 Unexpected end of archive.
+ Error 3 A generic error in the archive format was
+ detected. Processing may have completed
+ successfully anyway; some broken archives
+ created by other archivers have simple work-
+ arounds.
+ Fatal 4 Zip was unable to allocate memory for one or
+ more buffers during program initialization.
+ Fatal 5 A severe error in the archive format was
+ detected. Processing probably failed imme-
+ diately.
+ Error 6 Entry too large to be split with zipsplit.
+ Error 7 Invalid comment format.
+ Fatal 8 Zip -T failed or out of memory.
+ Error 9 The user aborted zip prematurely with con-
+ trol-C (or equivalent).
+ Fatal 10 Zip encountered an error while using a temp
+ file.
+ Fatal 11 Read or seek error.
+ Warning 12 Zip has nothing to do.
+ Error 13 Missing or empty zip file.
+ Fatal 14 Error writing to a file.
+ Fatal 15 Zip was unable to create a file to write to.
+ Error 16 Bad command line parameters.
+ Error 18 Zip could not open a specified file to read.
+ Fatal 19 Zip was built with options not supported on
+ this system
+ Fatal 20 Attempt to read unsupported Zip64 archive
+.end literal
+.!------------------------------------------------------------------------------
+.indent -4
+2 Extra_Fields
+.br
+The .ZIP file format allows some extra data to be stored with a file in
+the archive. For example, where local time zone information is
+available, Zip can store UTC date-time data for files. (Look for
+USE_EF_UT_TIME in a "zip -v" report.) On VMS, with -V or -VV, Zip will
+also store VMS-specific file attributes. These data are packaged as
+"extra fields" in the archive. Some extra fields are specific to a
+particular operating system (like VMS file attributes). Large files
+(bigger than 4GB) on any OS require an extra field to hold their 64-bit
+size data. Depending on the capabilities of the UnZip program used to
+expand the archive, these extra fields may be used or ignored when files
+are extracted from the archive.
+.sk
+Some extra fields, like UTC date-times or VMS file attributes, are
+optional. Others, like the Zip64 extra field which holds 64-bit sizes
+for a large file, are required.
+.sk
+The -X (--strip-extra) option suppresses the saving of any optional
+extra fields in the archive. (Thus, -X conflicts with -V or -VV.)
+.!------------------------------------------------------------------------------
+.indent -4
+2 Environment
+.br
+A user can specify default command-line options and arguments by
+defining an "environment variable" (that is, a logical name or DCL
+symbol), "ZIP_OPTS" or "ZIPOPT", to specify them. If both "ZIP_OPTS" and
+"ZIPOPT" are specified, the definition of "ZIPOPT" prevails.
+.sk
+The C RTL function getenv() is used to sense these variables, so its
+behavior determines what happens if both a logical name and a symbol are
+defined. As of VMS V7.3, a logical name supercedes a symbol.
+.sk
+The "zip -v" report should show the perceived settings of these
+variables.
+.!------------------------------------------------------------------------------
+.indent -4
+2 File_Names
+.br
+Zip deals with file names in the system file system and with file names
+in Zip archives. File names in a Zip archive are stored in a UNIX-like
+path-name format. For example, a VMS file specification like this:
+.sk;.indent 10
+[.zip30.vms]descrip.mms
+.sk
+could appear in a Zip archive as:
+.sk;.indent 10
+zip30/vms/descrip.mms
+.sk
+For security reasons, paths in Zip archives are always stored as
+relative paths, so an absolute VMS directory specification will be
+transformed to a relative path in the archive (that is, no leading "/").
+For example, the following absolute directory specification would give
+the same archive path as the previous (relative) example:
+.sk;.indent 10
+[zip30.vms]descrip.mms
+.sk
+Also, device names are dropped, so the following file specification
+would also give the same archive path:
+.sk;.indent 10
+sys$sysdevice:[zip30.vms]descrip.mms
+.sk
+If an archive is intended for use with PKUNZIP under MSDOS, then the -k
+(for "Katz", --DOS-names) option should be used to attempt to adjust the
+names and paths to conform to MSDOS character-set and length
+limitations, to store only the MSDOS file attributes (just the
+owner:write attribute from VMS), and to mark the entry as made under
+MSDOS (even though it wasn't).
+.sk
+Note that file specifications in the file system must be specified using
+VMS notation, but file names in an archive must be specified using the
+UNIX-like notation used in the archive. For example, where a BACKUP
+command might look like this:
+.sk.indent 10
+$ back [.zip30...]*.* /excl = [...vms]*.c stuff.bck /save
+.sk
+a corresponding Zip command might look like this:
+.sk;.indent 10;
+$ zip stuff.zip [.zip30...]*.* -x */vms/*.c
+.sk
+because the files to be added to the Zip archive are specified using VMS
+file specifications, but the -x (--exclude) option excludes names based
+on their archive path/file names. Options dealing with archive names
+include -R (--recurse-patterns), -d (--delete), -i (--include), -x
+(--exclude), and -U (--copy-entries).
+.sk
+Note: By default, on VMS, archive name pattern matching (-R, -d, -i, -x,
+and -U) is case sensitive, even when the file system is not case
+sensitive (or even case preserving). This allows accurate matching of
+mixed-case names in an archive which may have been created on a system
+with a case sensitive file system, but it can involve extra effort on
+VMS, where it may be necessary to use unnatural case names (or the same
+names in multiple cases, like "*.obj *.OBJ") for this kind of pattern
+matching to give the desired behavior. If completely case-blind pattern
+matching behavior is desired, specify the -ic (--ignore-case) option.
+.!------------------------------------------------------------------------------
+.indent -4
+3 Case
+.br
+For better compatibility with UNIX-like systems, Zip, by default,
+down-cases ODS2 file names. For example, the following file on an ODS2
+file system:
+.sk;.indent 10
+[.ZIP30.VMS]DESCRIP.MMS
+.sk
+would appear in an archive as:
+.sk;.indent 10
+zip30/vms/descrip.mms
+.sk
+Zip versions before 3.0 down-cased all VMS file names. Now, various
+options give the user control over these conversions:
+.sk
+.lm +10;.literal
+-C preserve case of all file names
+-C- down-case all file names
+-C2 preserve case of ODS2 names
+-C2- down-case ODS2 file names (default)
+-C5 preserve case of ODS5 names (default)
+-C5- down-case ODS5 file names
+.end literal;.lm -10
+.sk
+Case is handled differently for archive member names, which the user
+specifies with the -R, -d, -i, -x, and -U options. By default, on VMS,
+archive name pattern matching is case sensitive, even when the file
+system is not case sensitive (or even case preserving). This allows
+accurate matching of mixed-case names in an archive which may have been
+created on a system with a case sensitive file system, but it can
+involve extra effort on VMS, where it may be necessary to use unnatural
+case names (or the same names in multiple cases, like "*.obj *.OBJ") for
+this kind of pattern matching to give the desired behavior. If
+completely case-blind pattern matching behavior is desired, specify the
+-ic (--ignore-case) option.
+.!------------------------------------------------------------------------------
+.indent -4
+2 Fixing_Damage
+.br
+Two options can be used to fix a damaged Zip archive.
+.sk;.literal
+-F --fix
+-FF --fixfix
+.end literal;.sk
+The -F (--fix) option can be used if some portions of the archive are
+missing, but it requires a reasonably intact central directory. The
+input archive is scanned as usual, but zip will ignore some problems.
+The resulting archive should be valid, but any inconsistent entries
+will be left out.
+.sk
+If the archive is too damaged or the end (where the central directory is
+situated) has been truncated, you must use -FF (--fixfix). This is a
+change from zip 2.32, where the -F option is able to read a truncated
+archive. The -F option now more reliably fixes archives with minor
+damage, and the -FF option is needed to fix archives where -F and -FF
+was used before.
+.sk
+With -FF, the archive is scanned from the beginning and Zip scans for
+special signatures to identify the limits between the archive members.
+The -F option is more reliable if the archive is not too much damaged,
+so try this option first.
+.sk
+Neither option will recover archives that have been incorrectly
+transferred, such as by FTP in ASCII mode instead of binary. After the
+repair, the -t option of UnZip may show that some files have a bad CRC.
+Such files cannot be recovered; you can remove them from the archive
+using the -d option of Zip.
+.sk
+Because of the uncertainty of the "fixing" process, it's required
+to specify an output archive, rather than risking further damage to the
+original damaged archive. For example, to fix the damaged archive
+foo.zip,
+.sk;.indent 10
+zip -F foo --out foo_fix
+.sk
+tries to read the entries normally, copying good entries to the new
+archive foo_fix.zip. If this doesn't work, as when the archive is
+truncated, or if some entries are missed because of bad central
+directory entries, try -FF:
+.sk;.indent 10
+zip -FF foo --out foo_fixfix
+.sk
+and compare the resulting archive to the archive created using -F. The
+-FF option may create an inconsistent archive. Depending on what is
+damaged, you can then use the -F option to fix that archive.
+.sk
+A split archive with missing split files can be fixed using -F if you
+have the last split of the archive (the ".zip" file). If this file is
+missing, you must use -FF to fix the archive, which will prompt you for
+the splits you have.
+.sk
+Currently, the fix options can't recover an entry which has a bad
+checksum or is otherwise damaged.
+.!------------------------------------------------------------------------------
+.indent -4
+2 Log_File
+.br
+Zip normally sends messages to the user's terminal, but these may be
+also directed to a log file.
+.sk;.literal
+-la --log-append
+.end literal;.br
+Append to an existing log file. Default is to create a new version.
+.sk;.literal
+-lf logfilepath --logfile-path logfilepath
+.end literal;.br
+Open a logfile at the given path. By default, a new version will be
+created, but with the -la option an existing file will be opened and the
+new log information appended to any existing information. Only
+warnings and errors are written to the log unless the -li option is also
+given, then all information messages are also written to the log.
+.sk;.literal
+-li --log-info
+.end literal;.br
+Include information messages, such as file names being zipped, in the
+log. The default is to include only the command line, any warnings
+and errors, and the final status.
+.!------------------------------------------------------------------------------
+.indent -4
+2 Modes_of_Operation
+.br
+Zip supports two distinct types of command modes, external and
+internal. The external modes (update, grow, and freshen) read files
+from the file system (as well as from an existing archive) while the
+internal modes (delete and copy) operate exclusively on entries in an
+existing archive.
+.sk;.literal
+-u --update
+.end literal;.br
+Update existing entries and add new files. If the archive does not
+exist, create it. This is the default mode, so -u is optional.
+.sk;.literal
+-g --grow
+.end literal;.br
+Grow (append to) the specified Zip archive, instead of creating a new
+one. If this operation fails, 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.
+.sk;.literal
+-f --freshen
+.end literal;.br
+Update existing entries in an existing archive. Does not add new files
+to the archive.
+.sk;.literal
+-d --delete
+.end literal;.br
+Delete entries from an existing archive.
+.sk;.literal
+-DF --difference-archive
+.end literal;.br
+Create an incremental backup-style archive, where the resulting archive
+will contain 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 Zip operation.
+.sk
+For example, if the existing archive was created using
+.sk;.indent 10
+zip foo_full.zip [.foo...]*.*
+.sk
+from just above the foo directory, then the command (also from just
+above the foo directory):
+.sk;.indent 10
+zip foo_full.zip [.foo...]*.* -DF -O foo_incr.zip
+.sk
+creates the archive foo_incr.zip with just the files not in foo_full.zip
+and the files where the size or date-time of the files does not match
+that in foo_full.zip. Note that in the "zip -DF" operation, the
+original full archive is specified as the input archive, and the -O
+(--output-file) option is used to specify the new (incremental) output
+archive.
+.sk;.literal
+-FS --filesync
+.end literal;.br
+Delete entries in the archive that do not match 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 deleting of entries that
+are not matched on the OS. 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 -FS can be much
+faster than creating a new archive. If few files are being copied from
+the old archive, it may be faster to create a new archive instead.
+.sk
+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 -O
+(--output) option to output the new archive to a new file. Even though
+it's slower, creating a new archive with a new archive name is safer,
+avoids mismatches between archive and OS paths, and is preferred.
+.sk;.literal
+-U --copy-entries
+.end literal;.br
+Select entries in an existing archive and copy them to a new archive.
+Copy mode is like update mode, but entries in the existing archive are
+selected by command line patterns rather than files from the file system
+and it uses the -O (--output-file) option to write the resulting archive
+to a new file rather than updating the existing archive, leaving the
+original archive unchanged.
+.sk
+Normally, when updating an archive using relative file specifications
+("[]", "[.xxx]", and so on), it helps to have the same default directory
+as when the archive was created, but this is not a strict requirement.
+.sk
+Date-time information in a Zip archive may be influenced by time zone.
+.!------------------------------------------------------------------------------
+.indent -4
+3 Examples
+.br
+When given the name of an existing archive, Zip will replace identically
+named entries in the archive or add entries for new names. For example,
+if foo.zip exists and contains foo/file1 and foo/file2, and the
+directory [.foo] contains the files file1 and file3, then:
+.sk;.indent 10
+$ zip foo [.foo...]*.*
+.sk
+will replace foo/file1 in foo.zip and add foo/file3 to foo.zip. After
+this, foo.zip contains foo/file1, foo/file2, and foo/file3, with foo/file2
+unchanged from before. This is the default mode -u (update).
+.sk
+Update will add new entries to the archive and will replace
+existing entries only if the modified date of the file is more recent than
+the date recorded for that name in the archive. For example:
+.sk;.indent 10
+$ zip -u stuff *.*
+.sk
+will add any new files in the current directory, and update any changed
+files in the archive stuff.zip. Note that Zip will not try to pack
+stuff.zip into itself when you do this. Zip avoids including its own
+output files when selecting files to include in the archive, so it
+should be safe, as in this case, to have the archive included in the
+list of input files.
+.sk
+A second mode, -f (freshen), like update will only
+replace entries with newer files. Unlike update, however, it will not
+add files that are not already in the archive. For example:
+.sk;.indent 10
+$ zip -f foo
+.sk
+Note that the -f option with no arguments freshens all the entries in the
+archive. The same is true of -u, so "zip -u foo" and "zip -f foo" do
+the same thing.
+.sk
+When these options are used, Zip should be run from the same directory
+as when the original Zip command was run, so that the path names in the
+archive will continue to agree with the path names in the file system.
+Normally, it's also a good idea to keep the other options the same (-V,
+-w, and the like), to keep the archive contents consistent.
+.sk
+The -t (--from-date) and -tt (--before-date) options can also be used
+with adding, updating, or freshening to restrict further the files to be
+included in the archive. For example:
+.sk;.indent 10
+$ zip -rt 12071991 infamy [.FOO]*.*
+.sk
+will add all the files in [.FOO] and its subdirectories that were last
+modified on December 7, 1991, or later to the achive infamy.zip. Dates
+can be in format mmddyyyy or yyyy-mm-dd.
+.sk
+Also, files can be explicitly excluded using the -x option:
+.sk;.indent 10
+$ zip -r foo [.FOO] -x *.obj
+.sk
+which will zip up the contents of [.FOO] into foo.zip but exclude all the
+files that end in ".obj".
+.sk
+The -d (delete) mode will remove entries from an
+archive. An example might be:
+.sk;.indent 10
+$ zip -d foo foo/harry/*.* *.obj
+.sk
+which will remove all of the files that start with "foo/harry/" and all of
+the files that end with ".obj" (in any path).
+.sk
+The last mode, -U (--copy-entries), selects entries from an existing
+archive and copies them to a new archive.
+.sk;.indent 10
+$ zip -U foo *.obj --out fooobj
+.sk
+will copy all .obj entries from foo.zip and put them in the new archive
+fooobj.zip.
+.sk
+Note: By default, on VMS, archive name pattern matching (-R, -d, -i, -x,
+and -U) is case sensitive, even when the file system is not case
+sensitive (or even case preserving). This allows accurate matching of
+mixed-case names in an archive which may have been created on a system
+with a case sensitive file system, but it can involve extra effort on
+VMS, where it may be necessary to use unnatural case names (or the same
+names in multiple cases, like "*.obj *.OBJ") for this kind of pattern
+matching to give the desired behavior. If completely case-blind pattern
+matching behavior is desired, specify the -ic (--ignore-case) option.
+.!------------------------------------------------------------------------------
+.indent -4
+2 Options_List
+.br
+"zip -h" provides a concise list of common command-line options. "zip
+-h2" provides more details. "zip -so" provides a list of all available
+options. "zip -v" shows the program version and available features.
+(The list below was derived from a "zip -so" listing.)
+.sk
+Short-form options begin with a single hyphen ("-"). Long-form option
+begin with a double hyphen ("--"), and may be abbreviated to any
+unambiguous shorter string. For example:
+.lm +10;.literal
+-v
+--verbose
+--verb
+.end literal;.lm -10
+.sk
+To avoid confusion, if a negatable option contains an embedded hyphen
+("-"), then avoid abbreviating it at the hyphen if you plan to negate
+it. For example, if an option like --some-option were abbreviated to
+--some-, the parser would consider that trailing hyphen to be part of
+the option name, rather than as a negating trailing hyphen. This
+behavior may change in the future, to interpret the trailing hyphen in
+--some- to be negating. (So don't do it.)
+.sk
+Some options may be negated (or modified) by appending a "-":
+.lm +10;.literal
+-la-
+--show-files-
+.end literal;.lm -10
+.sk
+Some options take a value, which may immediately follow the option, or
+be separated by a space or "=". For example:
+.lm +10;.literal
+-ttmmddyyyy
+-tt mmddyyyy
+-tt=mmddyyyy
+.end literal;.lm -10
+.sk
+.lm -4;.literal
+ Sh Long Description
+----+-------------------+--------------------------------------------------
+ 0 store store (instead of compress)
+ 1 compress-1 compress faster (-2, -3, -4, ...)
+ 9 compress-9 compress better
+ ? show the Zip help screen
+ @ names-stdin read input file patterns from SYS$INPUT (1/line)
+ A adjust-sfx adjust self-extracting executable
+ b temp-path path use "path" directory for temporary files
+ C preserve-case preserve case of all file names added to archive
+ C- preserve-case- down-case all file names added to archive
+ C2 preserve-case-2 preserve case of ODS2 names added to archive
+ C2- preserve-case-2- down-case ODS2 file added to archive (default)
+ C5 preserve-case-5 preserve case of ODS5 names added to archive (dflt)
+ C5- preserve-case-5- down-case ODS5 names added to archive
+ c entry-comments add a comment for each entry added to archive
+ D no-dir-entries do not add archive entries for directories
+ DF difference-archive difference archive: add only changed or new files
+ d delete delete entries in archive
+ db display-bytes display running byte counts
+ dc display-counts display running file counts
+ dd display-dots display progress dots for files (dflt size = 10MB)
+ dg display-globaldots display progress dots for archive, not each file
+ ds dot-size size set progress dot interval to "size" (MB)
+ du display-usize display original uncompressed size for entries
+ dv display-volume display volume (disk) number as in_disk>out_disk
+ e encrypt encrypt entries, ask for password
+ F fix fix mostly intact archive (try F before FF)
+ FF fixfix salvage what can be salvaged (not as reliable)
+ FS filesync remove archive entries unmatched in file system
+ f freshen update existing entries (only changed files)
+ fd force-descriptors force data descriptors as if streaming
+ fz force-zip64 force use of Zip64 format
+ g grow grow existing archive (unless updating or deleting)
+ H show the Zip help screen
+ h help show the Zip help screen
+ h2 more-help show extended Zip help
+ i include pat1 [pat2 [...]] include only names matching the patterns
+ ic ignore-case ignore case (case-blind archive entry name matching)
+ J junk-sfx junk (remove) archive preamble (unzipsfx)
+ j junk-paths junk (don't store) directory names, only file names
+ k DOS-names simulate PKZIP-made archive (DOS 8.3 names)
+ L license show software license
+ l to-crlf translate end-of-lines (LF -> CRLF)
+ la log-append append to existing log file
+ lf logfile-path lfile log to log file at lfile (default: new version)
+ li log-info include informational messages in log
+ ll from-crlf translate end-of-lines (CRLF -> LF)
+ MM must-match input file spec must exist (wildcards must match)
+ m move delete files added to archive
+ n suffixes sfx1[:sfx2[...]] don't compress files with these suffixes
+ nw no-wild no wildcards during add or update
+ O output-file ozf use "ozf" as the output archive (dflt = inp archive)
+ o latest-time set archive date-time to match oldest entry
+ P password password encrypt with supplied "password" string
+ q quiet quiet operation (no info messages)
+ R recurse-patterns recurse into subdirs from cur dir, match names only
+ r recurse-paths recurse into directories from specified path pats
+ s split-size size split archive at "size" (K/MB) (0: don't split)
+ sb split-bell ring terminal bell at pause for split medium change
+ sc show-command show command line
+ sd show-debug show debug messages
+ sf show-files show files to process (only)
+ so show-options show list of all command-line options
+ sp split-pause pause to select split destination(s)
+ sv split-verbose be verbose about creating splits
+ T test test archive integrity (runs UnZip -T)
+ t from-date mmddyyyy only do files since (at or after) "mmddyyyy"
+ tt before-date mmddyyyy only do files before "mmddyyyy"
+ u update update changed files, add new files (default mode)
+ V VMS-portable save VMS file attributes
+ VV VMS-specific save VMS file attributes and all allocated blocks
+ v verbose verbose messages (print version info if only arg)
+ w VMS-versions save VMS version numbers in archive
+ ww VMS-dot-versions save VMS version numbers as ".nnn", not ";nnn"
+ X strip-extra strip all but critical extra fields
+ X- strip-extra- keep all extra fields
+ x exclude pat1 [pat2 [...]] exclude all names matching the patterns
+ Z compression-method mthd use compress method "mthd" (bzip2 or deflate)
+ z archive-comment ask for archive comment
+.end literal;.lm +4
+.!------------------------------------------------------------------------------
+.indent -4
+2 Miscellaneous_Options
+.sk;.literal
+-D --no-dir-entries
+.end literal;.br
+Do not create entries in the archive for directories. By default,
+directory entries are added to an archive, so that their attributes can
+be saved in the archive. When an archive is created using -D, UnZip
+will still create directories as needed (subject to user control), but
+they will get the default attributes (date-time, permissions, ...) on
+the destination system, rather than their original atributes.
+.sk;.literal
+-MM --must-match
+.end literal;.br
+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 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 zip returns the OPEN
+error code (18 on most systems) instead of the normal success return (0
+on most systems). With -MM, 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 Zip exits with
+an OPEN error and no archive is created.
+.sk
+This option is useful when a known list of files is to be zipped so any
+missing or unreadable files should result in an error. It may be less
+useful when used with wildcards, but Zip will still exit with an error
+if any input pattern doesn't match at least one file or if any
+matched files are unreadable. If you want to create the archive anyway
+and only need to know if files were skipped, then don't use -MM and just
+check the exit status. Also, a log file (see -lf (--logfile-path))
+could be useful.
+.sk;.literal
+-O out_file --output-file out_file
+.end literal;.br
+Process the archive changes as usual, but instead of updating the
+existing archive, send the output to a new archive, "out_file". The
+output archive specified must be a different file from the input
+archive.
+.sk
+This option can be used to create updated split archives. It can
+also be used with -U to copy entries from an existing archive to
+a new archive. See the EXAMPLES section below.
+.sk
+Another use is converting zip files from one split size to
+another. For instance, to convert an archive with 700MB CD splits
+to one with 2GB DVD splits, can use:
+.sk;.indent 10
+zip -s 2g cd-split.zip --out dvd-split.zip
+.sk
+which uses copy mode. See -U below. Also:
+.sk;.indent 10
+zip -s 0 split.zip --out unsplit.zip
+.sk
+will convert a split archive to a single-file archive.
+.sk
+Copy mode will convert stream entries (using data descriptors and which
+may be incompatible with some unzip programs) to normal entries (which
+should be compatible with all unzip programs), except if standard
+encryption was used. For archives with encrypted entries, zipcloak
+will decrypt the entries and convert them to normal entries.
+.sk;.literal
+-o --latest-time
+.end literal;.br
+Set the modification date-time of the Zip archive file to the latest
+(newest) modification date-time found among the entries in the zip
+archive. This can be used without any other operations, if
+desired. For example:
+.sk;.indent 10
+zip -o foo
+.sk
+will change the modification date-time of foo.zip to the latest time of
+the entries in foo.zip.
+.sk;.literal
+-q --quiet
+.end literal;.br
+Quiet mode. Eliminates informational messages and comment prompts.
+This mode may be useful in command procedures, or if the Zip operation
+is being performed as a background task ("$ spawn/nowait zip -q foo
+*.c").
+.sk
+.sk;.literal
+-T --test
+.end literal;.br
+Test the integrity of a zip archive (the new one, if -O (--output-file)
+is specified). If the check fails, the old zip file is unchanged and
+(with the -m option) no input files are removed.
+.sk
+Implementation
+.br
+"zip -T" actually runs an "unzip -t" command to do the testing, so UnZip
+must be installed properly for this to work.
+.sk;.literal
+-TT unzip_cmd --unzip-command unzip_cmd
+.end literal;.br
+Specify the actual UnZip command, "unzip_cmd" (normally a DCL symbol) to
+use for "zip -T". This can be useful if multiple versions of UnZip are
+installed on a system, and the default DCL symbol "UNZIP" would run the
+wrong one (or the logical name DCL$PATH would lead to the wrong one).
+.sk
+In "unzip_cmd", the string "{}" is replaced by the temporary name of the
+archive to be tested, otherwise the name of the archive is appended
+to the end of the command. The exit status is checked for success severity.
+.sk;.literal
+-v --verbose
+.end literal;.br
+Verbose mode or print diagnostic version info.
+.sk
+Normally, when applied to real operations, this option enables the
+display of a progress indicator during compression (see -dd for more on
+dots) and requests verbose diagnostic info about archive structure
+oddities.
+.sk
+When -v is the only command line argument, a diagnostic report is
+displayed, showing:
+.lm +3;.br;.indent -2
+o Copyright and other legal notices
+.br;.indent -2
+o Program name, version, and release date
+.br;.indent -2
+o Pointers to Info-ZIP FTP and Web sites
+.br;.indent -2
+o Program build information (compiler type and version, OS version, and
+the compilation date
+.br;.indent -2
+o Optional features enabled at compile-time
+.br;.indent -2
+o Environment variable definitions (ZIP_OPTS, ZIPOPT)
+.lm -3;.br
+.sk
+This information should be included in bug reports.
+.sk;.literal
+-y --symlinks
+.end literal;.br
+Store symbolic links as such in the Zip archive, instead of compressing
+and storing the file referred to by the link. A symbolic link normally
+requires less storage than the actual file, both in the archive, and on
+the destination file system.
+.sk
+On VMS, symbolic links are supported on ODS5 disks where the C RTL
+supports symbolic links. Full support for symbolic links seems to
+require VMS V8.3, but a Zip program supporting symbolic links may be
+built on VMS V7.3-2.
+.!------------------------------------------------------------------------------
+.indent -4
+2 Progress_Display
+.br
+Various options control the display of progress messages during Zip
+operation.
+.sk;.literal
+-db --display-bytes
+.end literal;.br
+Display running byte counts showing the bytes processed and the bytes to
+go.
+.sk;.literal
+-dc --display-counts
+.end literal;.br
+Display running count of entries processed and entries to go.
+.sk;.literal
+-dd --display-dots
+.end literal;.br
+Display dots while each entry is processed (except on ports that have
+their own progress indicator). See -ds below for setting dot size. The
+default is a dot every 10 MB of input file processed. The -v
+(--verbose) option also displays dots and used to at a higher rate than
+this (at the same rate as in previous versions of Zip) but this rate has
+been changed to the new 10 MB default, and is also controlled by -ds.
+.sk;.literal
+-dg --display-globaldots
+.end literal;.br
+Display progress dots for the archive instead of for each file. The
+command
+.sk;.indent 10
+zip -qdgds 10m
+.sk
+will turn off most output except dots every 10 MB.
+.sk;.literal
+-ds size --dot-size size
+.end literal;.br
+Set amount of input file processed for each dot displayed. See -dd to
+enable displaying dots. Setting this option implies -dd. "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 100KB. The default is 10MB.
+.sk
+The -v (--verbose) option also displays dots and used to default to a
+higher rate than this (at the same rate as in previous versions of Zip)
+but now the default is 10 MB and the -v dots are also controlled by this
+option. A "size" of 0 turns dots off.
+.sk
+This option does not control the dots from the "Scanning files" message
+as Zip scans for input files. The dot size for that is fixed at 2
+seconds or a fixed number of entries, whichever is longer.
+.sk;.literal
+-du --display-usize
+.end literal;.br
+Display the uncompressed size of each entry.
+.sk;.literal
+-dv --display-volume
+.end literal;.br
+Display the volume (disk) number each entry is being written to.
+.!------------------------------------------------------------------------------
+.indent -4
+2 Self_Extracting_Archives
+.br
+A self-extracting archive (SFX) comprises a normal Zip archive appended
+to a special UnZip program (such as UNZIPSFX.EXE) for the intended
+target system.
+.sk
+The UnZip distribution includes a VMS command procedure,
+[,vms]makesfx.com, which can be used directly or adapted to create an
+SFX archive from a normal Zip archive.
+.sk
+The .ZIP file format includes offsets to data structures in the archive,
+and these offsets are measured from the start of the archive file.
+Appending an archive to an UnZip SFX executable effectively moves the
+start of the archive file. That makes the original offsets wrong, and
+that will cause the UnZip SFX program to emit warning messages when it
+tries to unpack the archive. Zip -A can be used to adjust these offsets
+in a self-extracting archive. For example, to adjust the offsets in
+foo.sfx_exe:
+.sk;.indent 10
+zip -A foo.sfx_exe
+.sk
+Similarly, the UnZip SFX program can be removed from a self-extracting
+archive (and the offsets in the archive restored) using the -J
+(--junk-sfx) option. For example:
+.sk;.indent 10
+zip -J foo.sfx_exe
+.sk
+Note that a self-extracting archive contains a normal Zip archive, and a
+normal UnZip program can be used to expand it in the normal way. You
+may get a warning about extra bytes at the beginning of the archive (the
+UnZip SFX program), but UnZip should work properly after that. This
+allows data in a self-extracting archive to be accessed on any system,
+not just the target system where its embedded UnZip SFX program runs.
+.!------------------------------------------------------------------------------
+.indent -4
+2 Split_Archives
+.br
+Beginning with version 3.0, Zip supports split archives. A split
+archive is one which is divided into multiple files, usually to allow it
+to be stored on multiple storage media (floppy diskettes, CD-ROMs, or
+the like) when a single medium would be too small to contain the whole
+archive. (Note that split archives are not just unitary archives split
+into pieces, as the .ZIP file format includes offsets to data structures
+in the archive, and for a split archive these are based on the start of
+each split, not on the start of the whole archive. Concatenating the
+pieces will invalidate these offsets, but UnZip can usually deal with
+it. Zip will usually refuse to process such a spliced archive unless
+the -FF fix option is used to fix the offsets.)
+.sk
+For a split archive with, say, 20 split files, the files are typically
+named ARCHIVE.z01, ARCHIVE.z02, ..., ARCHIVE.z19, ARCHIVE.zip, where
+"ARCHIVE" is the archive name specified by the user on the Zip command
+line. Note that the last split file is the ".zip" file. In contrast,
+"spanned" archives are the original multi-disk archive generally
+requiring floppy disks and using volume labels to store disk numbers.
+Zip 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.
+.!------------------------------------------------------------------------------
+.indent -4
+3 Options
+.br
+Use "-s size" to create a split archive (and to set the split size).
+The size is given as a number followed optionally by a multiplier suffix
+of k (KB), m (MB, the default if no suffix is specified), g (GB), or t
+(TB). (All are powers of 1024, not 1000). 64K is the minimum split
+size. For example, the following command could be used to create a
+split archive called "foo" from the contents of the "bar" directory with
+splits of 670MB, which might be useful for burning on CDs:
+.sk;.indent 10
+zip -s 670m foo [.bar...]*.*
+.sk
+Using -s without -sp as above creates all the splits in the directory
+specified by "foo", in this case the current default 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 -sp below for
+enabling split pause mode which allows splits to be written directly to
+removable media.
+.sk
+The -sv option can be used to enable verbose splitting and display
+details of how the splitting is being done. The -sb option can be used
+to ring the terminal bell when Zip pauses for the next split
+destination.
+.sk
+The -sp option can be used to pause Zip between splits to allow
+changing removable media, for example, but read the descriptions and
+warnings for both -s and -sp below.
+.sk
+Though Zip does not update split archives, Zip provides the option
+-O (--output-file) to allow split archives to be updated and saved in a
+new archive. For example:
+.sk;.indent 10
+zip inarchive.zip foo.c bar.c -O outarchive.zip
+.sk
+reads archive inarchive.zip, even if split, adds the files foo.c and
+bar.c, and writes the resulting archive to outarchive.zip. If
+inarchive.zip is split, then outarchive.zip defaults to the same split
+size. Be aware that outarchive.zip and any split files that are created
+with it are always overwritten without warning. This may be changed in
+the future.
+.!------------------------------------------------------------------------------
+.indent -4
+2 Temporary_Files
+.br
+When creating a new archive or normally when changing an existing
+archive, Zip will write a temporary file in the archive destination
+directory ("ZIxxxxxxxx", where "xxxxxxxx" is the hexadecimal process ID)
+with the new contents. Then, if and when the Zip job has completed with
+no errors, it will rename the temporary file to the specified archive
+name (replacing the old archive, if any).
+.sk
+You can use the -b (--temp-path) option to specify a different path
+(device and/or directory) for the temporary file, but specifying a
+different device will force Zip to copy the temporary file to its final
+destination instead of simply renaming it, and that copying will take
+more time than renaming, especially for a large archive. For example:
+.sk;.indent 10
+$ zip -b disk$scratch:[tmp] stuff *
+.sk
+will cause Zip to put its temporary files in the directory
+"disk$scratch:[tmp]", copying the temporary file back to the current
+directory as stuff.zip when it's complete.
+.!------------------------------------------------------------------------------
+.indent -4
+2 Text_Files
+.br
+Zip offers some options to help deal with line endings in text files.
+These may have limited utility on VMS.
+.sk;.literal
+-l --to-crlf
+.end literal;.br
+Translate the UNIX end-of-line character LF (CR on MAC) 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 ensure that "unzip -a" on Unix will get back an exact
+copy of the original file, to undo the effect of "zip -l". See -ll
+below for the binary checks.
+.sk;.literal
+-ll --from-crlf
+.end literal;.br
+Translate the MSDOS end-of-line CR LF into UNIX LF (CR on MAC). This
+option should not be used on binary files. This option can be used on
+MSDOS if the Zip archive is intended for UnZip under UNIX.
+.sk
+For both -l and -ll, if the file is converted and the file is later
+determined to be binary, a warning is issued and the file is probably
+corrupted. If Zip with -l or -ll detects binary (non-text) in the first
+buffer read from a file, it issues a warning and skips line-ending
+conversion on the file, avoiding corruption. 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. The algorithm now being used for binary detection should allow
+line-ending conversion of text files in UTF-8 and similar encodings.
+.!------------------------------------------------------------------------------
+.indent -4
+2 VMS_Specifics
+.br
+VMS File Attributes
+.sk;.literal
+-V --VMS-portable
+-VV --VMS-specific
+.end literal;.br
+The -V and -VV options cause Zip to store VMS file atributes (such as
+file organization, record format, carriage control, and so on) in
+VMS-specific "extra fields" in an archive along with the usual data.
+These extra fields are ignored on non-VMS systems, but on a VMS system,
+they allow UnZip to restore the files with their VMS attributes intact.
+.sk
+With -V, Zip ignores any data in the file after the end-of-file (EOF)
+point (defined by FAT$L_EFBLK and FAT$W_FFBYTE), which works well for
+well-formed files (that is, those with no valid data beyond EOF).
+Portable-format files (Stream_LF, fixed-512) archived with -V should be
+extracted properly on a non-VMS system. Files with more complex
+structures, such as indexed files and files with embedded byte counts
+or other such data may be of limited use on other systems. (UnZip on
+non-VMS systems may be able to extract various VMS-format text files,
+however.)
+.sk
+With -VV, Zip processes all allocated blocks for the file (including
+those beyond EOF). When extracted on a VMS system, the original file
+should be reproduced with as much fidelity as possible, but on a non-VMS
+system, most files will be seen as corrupt because of the data from
+beyond EOF.
+.sk
+VMS File Version Numbers
+.sk;.literal
+-w --VMS-versions
+-ww --VMS-dot-versions
+.end literal;.br
+By default, for compatibility with non-VMS systems, Zip strips VMS file
+version numbers from the names stored in an archive. The -w
+(--VMS-versions) option causes Zip to retain file version numbers on
+names in an archive. Without -w, a version number wildcard (";*") can
+cause errors when multiple versions of a single file are treated as
+multiple files with the same name.
+.sk
+For better compatibility with non-VMS systems where semi-colons are less
+popular in file names, the -ww (--VMS-dot-versions) option stores the
+file version numbers with a dot (".nnn") instead of a semi-colon
+(";nnn").
+.!------------------------------------------------------------------------------
+.indent -4
+2 Copyright_and_License
+.br
+Zip has an option to display its copyright and license.
+.sk;.literal
+-L --license
+.end literal;.br
+The license is reproduced below.
+.sk.lm +3
+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.
+.lm -3;.sk
+--------------------------------------------------------
+.sk
+Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
+.sk
+For the purposes of this copyright and license, "Info-ZIP" is defined as
+the following set of individuals:
+.sk;.lm +3
+ 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.
+.lm -3;.sk
+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.
+.sk
+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:
+.sk;.lm +7;.indent -4
+ 1. Redistributions of source code (in whole or in part) must retain
+ the above copyright notice, definition, disclaimer, and this list
+ of conditions.
+.sk;.indent -4
+ 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.
+.sk;.indent -4
+ 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.
+.sk;.indent -4
+ 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.
+.lm -7;.sk
+.!------------------------------------------------------------------------------
+.indent -4
+2 Acknowledgements
+.br
+ Thanks to R. P. Byrne for his 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 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 ftp site for the Info-ZIP
+ group to use; and most importantly, to the Info-ZIP group
+ itself (listed in the file infozip.who) without whose
+ tireless testing and bug-fixing efforts a portable 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.
+.!------------------------------------------------------------------------------
+.indent -4
+2 Bugs
+.br
+All bug reports, patches, or suggestions should go to zip-bugs via the
+web site contact form at http://www.Info-ZIP.org. Patches should be
+sent as unified or context diffs only (diff -u or diff -c).
+.sk
+Any bug report should include the Zip version, any special compilation
+options (see "zip -v" report), the host system type and operating system
+version, and any other relevant information (compiler version, lunar
+phase, ...).
+.!------------------------------------------------------------------------------
diff --git a/vms/build_zip.com b/vms/build_zip.com
new file mode 100644
index 0000000..7bbe13d
--- /dev/null
+++ b/vms/build_zip.com
@@ -0,0 +1,690 @@
+$! BUILD_ZIP.COM
+$!
+$! Build procedure for VMS versions of Zip.
+$!
+$! last revised: 2007-03-15 SMS.
+$!
+$! Command arguments:
+$! - suppress help file processing: "NOHELP"
+$! - suppress message file processing: "NOMSG"
+$! - select link-only: "LINK"
+$! - select compiler environment: "VAXC", "DECC", "GNUC"
+$! - select large-file support: "LARGE"
+$! - select compiler listings: "LIST" Note that the whole argument
+$! is added to the compiler command, so more elaborate options
+$! like "LIST/SHOW=ALL" (quoted or space-free) may be specified.
+$! - supply additional compiler options: "CCOPTS=xxx" Allows the
+$! user to add compiler command options like /ARCHITECTURE or
+$! /[NO]OPTIMIZE. For example, CCOPTS=/ARCH=HOST/OPTI=TUNE=HOST
+$! or CCOPTS=/DEBUG/NOOPTI. These options must be quoted or
+$! space-free.
+$! - supply additional linker options: "LINKOPTS=xxx" Allows the
+$! user to add linker command options like /DEBUG or /MAP. For
+$! example: LINKOPTS=/DEBUG or LINKOPTS=/MAP/CROSS. These options
+$! must be quoted or space-free. Default is
+$! LINKOPTS=/NOTRACEBACK, but if the user specifies a LINKOPTS
+$! string, /NOTRACEBACK will not be included unless specified by
+$! the user.
+$! - select installation of CLI interface version of zip:
+$! "VMSCLI" or "CLI"
+$! - force installation of UNIX interface version of zip
+$! (override LOCAL_ZIP environment): "NOVMSCLI" or "NOCLI"
+$! - select BZIP2 support: "IZ_BZIP2=dev:[dir]", where "dev:[dir]"
+$! (or a suitable logical name) tells where to find "bzlib.h".
+$! The BZIP2 object library (LIBBZ2_NS.OLB) is expected to be in
+$! a "[.dest]" directory under that one ("dev:[dir.ALPHAL]", for
+$! example), or in that directory itself.
+$!
+$! To specify additional options, define the global symbol
+$! LOCAL_ZIP as a comma-separated list of the C macros to be
+$! defined, and then run BUILD_ZIP.COM. For example:
+$!
+$! $ LOCAL_ZIP == "VMS_IM_EXTRA"
+$! $ @ [.VMS]BUILD_ZIP.COM
+$!
+$! Valid VMS-specific options include VMS_PK_EXTRA and VMS_IM_EXTRA.
+$! See the INSTALL file for other options. (VMS_PK_EXTRA is the
+$! default.)
+$!
+$! If editing this procedure to set LOCAL_ZIP, be sure to use only
+$! one "=", to avoid affecting other procedures. For example:
+$! $ LOCAL_ZIP = "VMS_IM_EXTRA"
+$!
+$! Note: This command procedure always generates both the "default"
+$! Zip having the UNIX style command interface and the "VMSCLI" Zip
+$! having the CLI compatible command interface. There is no need to
+$! add "VMSCLI" to the LOCAL_ZIP symbol. (The only effect of
+$! "VMSCLI" now is the selection of the CLI style Zip executable in
+$! the foreign command definition.)
+$!
+$!
+$ on error then goto error
+$ on control_y then goto error
+$ OLD_VERIFY = f$verify( 0)
+$!
+$ edit := edit ! override customized edit commands
+$ say := write sys$output
+$!
+$!##################### Read settings from environment ########################
+$!
+$ if (f$type( LOCAL_ZIP) .eqs. "")
+$ then
+$ LOCAL_ZIP = ""
+$ else ! Trim blanks and append comma if missing
+$ LOCAL_ZIP = f$edit( LOCAL_ZIP, "TRIM")
+$ if (f$extract( f$length( LOCAL_ZIP)- 1, 1, LOCAL_ZIP) .nes. ",")
+$ then
+$ LOCAL_ZIP = LOCAL_ZIP + ","
+$ endif
+$ endif
+$!
+$! Check for the presence of "VMSCLI" in LOCAL_ZIP. If yes, we will
+$! define the foreign command for "zip" to use the executable
+$! containing the CLI interface.
+$!
+$ len_local_zip = f$length( LOCAL_ZIP)
+$!
+$ pos_cli = f$locate( "VMSCLI", LOCAL_ZIP)
+$ if (pos_cli .ne. len_local_zip)
+$ then
+$ CLI_IS_DEFAULT = 1
+$ ! Remove "VMSCLI" macro from LOCAL_ZIP. The Zip executable
+$ ! including the CLI interface is now created unconditionally.
+$ LOCAL_ZIP = f$extract( 0, pos_cli, LOCAL_ZIP)+ -
+ f$extract( pos_cli+7, len_local_zip- (pos_cli+ 7), LOCAL_ZIP)
+$ else
+$ CLI_IS_DEFAULT = 0
+$ endif
+$ delete /symbol /local pos_cli
+$!
+$! Check for the presence of "VMS_IM_EXTRA" in LOCAL_ZIP. If yes, we
+$! will (later) add "I" to the destination directory name.
+$!
+$ desti = ""
+$ pos_im = f$locate( "VMS_IM_EXTRA", LOCAL_ZIP)
+$ if (pos_im .ne. len_local_zip)
+$ then
+$ desti = "I"
+$ endif
+$!
+$ delete /symbol /local len_local_zip
+$!
+$!##################### Customizing section #############################
+$!
+$ zipx_unx = "ZIP"
+$ zipx_cli = "ZIP_CLI"
+$!
+$ CCOPTS = ""
+$ IZ_BZIP2 = ""
+$ LINKOPTS = "/notraceback"
+$ LINK_ONLY = 0
+$ LISTING = " /nolist"
+$ LARGE_FILE = 0
+$ MAKE_HELP = 1
+$ MAKE_MSG = 1
+$ MAY_USE_DECC = 1
+$ MAY_USE_GNUC = 0
+$!
+$! Process command line parameters requesting optional features.
+$!
+$ arg_cnt = 1
+$ argloop:
+$ current_arg_name = "P''arg_cnt'"
+$ curr_arg = f$edit( 'current_arg_name', "UPCASE")
+$ if (curr_arg .eqs. "") then goto argloop_out
+$!
+$ if (f$extract( 0, 5, curr_arg) .eqs. "CCOPT")
+$ then
+$ opts = f$edit( curr_arg, "COLLAPSE")
+$ eq = f$locate( "=", opts)
+$ CCOPTS = f$extract( (eq+ 1), 1000, opts)
+$ goto argloop_end
+$ endif
+$!
+$ if f$extract( 0, 7, curr_arg) .eqs. "IZ_BZIP"
+$ then
+$ opts = f$edit( curr_arg, "COLLAPSE")
+$ eq = f$locate( "=", opts)
+$ IZ_BZIP2 = f$extract( (eq+ 1), 1000, opts)
+$ goto argloop_end
+$ endif
+$!
+$ if (f$extract( 0, 5, curr_arg) .eqs. "LARGE")
+$ then
+$ LARGE_FILE = 1
+$ goto argloop_end
+$ endif
+$!
+$ if (f$extract( 0, 7, curr_arg) .eqs. "LINKOPT")
+$ then
+$ opts = f$edit( curr_arg, "COLLAPSE")
+$ eq = f$locate( "=", opts)
+$ LINKOPTS = f$extract( (eq+ 1), 1000, opts)
+$ goto argloop_end
+$ endif
+$!
+$! Note: LINK test must follow LINKOPTS test.
+$!
+$ if (f$extract( 0, 4, curr_arg) .eqs. "LINK")
+$ then
+$ LINK_ONLY = 1
+$ goto argloop_end
+$ endif
+$!
+$ if (f$extract( 0, 4, curr_arg) .eqs. "LIST")
+$ then
+$ LISTING = "/''curr_arg'" ! But see below for mods.
+$ goto argloop_end
+$ endif
+$!
+$ if (curr_arg .eqs. "NOHELP")
+$ then
+$ MAKE_HELP = 0
+$ goto argloop_end
+$ endif
+$!
+$ if (curr_arg .eqs. "NOMSG")
+$ then
+$ MAKE_MSG = 0
+$ goto argloop_end
+$ endif
+$!
+$ if (curr_arg .eqs. "VAXC")
+$ then
+$ MAY_USE_DECC = 0
+$ MAY_USE_GNUC = 0
+$ goto argloop_end
+$ endif
+$!
+$ if (curr_arg .eqs. "DECC")
+$ then
+$ MAY_USE_DECC = 1
+$ MAY_USE_GNUC = 0
+$ goto argloop_end
+$ endif
+$!
+$ if (curr_arg .eqs. "GNUC")
+$ then
+$ MAY_USE_DECC = 0
+$ MAY_USE_GNUC = 1
+$ goto argloop_end
+$ endif
+$!
+$ if ((curr_arg .eqs. "VMSCLI") .or. (curr_arg .eqs. "CLI"))
+$ then
+$ CLI_IS_DEFAULT = 1
+$ goto argloop_end
+$ endif
+$!
+$ if ((curr_arg .eqs. "NOVMSCLI") .or. (curr_arg .eqs. "NOCLI"))
+$ then
+$ CLI_IS_DEFAULT = 0
+$ goto argloop_end
+$ endif
+$!
+$ say "Unrecognized command-line option: ''curr_arg'"
+$ goto error
+$!
+$ argloop_end:
+$ arg_cnt = arg_cnt + 1
+$ goto argloop
+$ argloop_out:
+$!
+$ if (CLI_IS_DEFAULT)
+$ then
+$ ZIPEXEC = zipx_cli
+$ else
+$ ZIPEXEC = zipx_unx
+$ endif
+$!
+$!#######################################################################
+$!
+$! Find out current disk, directory, compiler and options
+$!
+$ workdir = f$environment( "default")
+$ here = f$parse( workdir, , , "device")+ f$parse( workdir, , , "directory")
+$!
+$! Sense the host architecture (Alpha, Itanium, or VAX).
+$!
+$ if (f$getsyi( "HW_MODEL") .lt. 1024)
+$ then
+$ arch = "VAX"
+$ else
+$ if (f$getsyi( "ARCH_TYPE") .eq. 2)
+$ then
+$ arch = "ALPHA"
+$ else
+$ if (f$getsyi( "ARCH_TYPE") .eq. 3)
+$ then
+$ arch = "IA64"
+$ else
+$ arch = "unknown_arch"
+$ endif
+$ endif
+$ endif
+$!
+$ dest = arch
+$ cmpl = "DEC/Compaq/HP C"
+$ opts = ""
+$ if (arch .nes. "VAX")
+$ then
+$ HAVE_DECC_VAX = 0
+$ USE_DECC_VAX = 0
+$!
+$ if (MAY_USE_GNUC)
+$ then
+$ say "GNU C is not supported for ''arch'."
+$ say "You must use DEC/Compaq/HP C to build Zip."
+$ goto error
+$ endif
+$!
+$ if (.not. MAY_USE_DECC)
+$ then
+$ say "VAX C is not supported for ''arch'."
+$ say "You must use DEC/Compaq/HP C to build Zip."
+$ goto error
+$ endif
+$!
+$ cc = "cc /standard = relax /prefix = all /ansi"
+$ defs = "''LOCAL_ZIP' VMS"
+$ if (LARGE_FILE .ne. 0)
+$ then
+$ defs = "LARGE_FILE_SUPPORT, ''defs'"
+$ endif
+$ else
+$ if (LARGE_FILE .ne. 0)
+$ then
+$ say "LARGE_FILE_SUPPORT is not available on VAX."
+$ LARGE_FILE = 0
+$ endif
+$ HAVE_DECC_VAX = (f$search( "SYS$SYSTEM:DECC$COMPILER.EXE") .nes. "")
+$ HAVE_VAXC_VAX = (f$search( "SYS$SYSTEM:VAXC.EXE") .nes. "")
+$ MAY_HAVE_GNUC = (f$trnlnm( "GNU_CC") .nes. "")
+$ if (HAVE_DECC_VAX .and. MAY_USE_DECC)
+$ then
+$ ! We use DECC:
+$ USE_DECC_VAX = 1
+$ cc = "cc /decc /prefix = all"
+$ defs = "''LOCAL_ZIP' VMS"
+$ else
+$ ! We use VAXC (or GNU C):
+$ USE_DECC_VAX = 0
+$ defs = "''LOCAL_ZIP' VMS"
+$ if ((.not. HAVE_VAXC_VAX .and. MAY_HAVE_GNUC) .or. MAY_USE_GNUC)
+$ then
+$ cc = "gcc"
+$ opts = "GNU_CC:[000000]GCCLIB.OLB /LIBRARY,"
+$ dest = "''dest'G"
+$ cmpl = "GNU C"
+$ else
+$ if (HAVE_DECC_VAX)
+$ then
+$ cc = "cc /vaxc"
+$ else
+$ cc = "cc"
+$ endif
+$ dest = "''dest'V"
+$ cmpl = "VAC C"
+$ endif
+$ opts = "''opts' SYS$DISK:[.''dest']VAXCSHR.OPT /OPTIONS,"
+$ endif
+$ endif
+$!
+$! Change the destination directory, according to the VMS_IM_EXTRA and
+$! large-file options. Set the bzip2 directory.
+$!
+$ dest = dest+ desti
+$ seek_bz = arch
+$ if (LARGE_FILE .ne. 0)
+$ then
+$ dest = dest+ "L"
+$ seek_bz = seek_bz+ "L"
+$ endif
+$!
+$! If BZIP2 support was selected, find the object library.
+$! Complain if things fail.
+$!
+$ cc_incl = "[]"
+$ incl_bzip2_m = ""
+$ lib_bzip2_opts = ""
+$ if (IZ_BZIP2 .nes. "")
+$ then
+$ bz2_olb = "LIBBZ2_NS.OLB"
+$ define incl_bzip2 'IZ_BZIP2'
+$ defs = "''defs', BZIP2_SUPPORT"
+$ @ [.VMS]FIND_BZIP2_LIB.COM 'IZ_BZIP2' 'seek_bz' 'bz2_olb' lib_bzip2
+$ if (f$trnlnm( "lib_bzip2") .eqs. "")
+$ then
+$ say "Can't find BZIP2 object library. Can't link."
+$ goto error
+$ else
+$ say "BZIP2 dir = ''f$trnlnm( "lib_bzip2")'"
+$ incl_bzip2_m = ", ZBZ2ERR"
+$ lib_bzip2_opts = "lib_bzip2:''bz2_olb' /library, "
+$ cc_incl = cc_incl+ ", [.VMS]"
+$ endif
+$ endif
+$!
+$! Reveal the plan. If compiling, set some compiler options.
+$!
+$ if (LINK_ONLY)
+$ then
+$ say "Linking on ''arch' for ''cmpl'."
+$ else
+$ say "Compiling on ''arch' using ''cmpl'."
+$!
+$ DEF_UNX = "/define = (''defs')"
+$ DEF_CLI = "/define = (''defs', VMSCLI)"
+$ DEF_UTIL = "/define = (''defs', UTIL)"
+$ endif
+$!
+$! If [.'dest'] does not exist, either complain (link-only) or make it.
+$!
+$ if (f$search( "''dest'.DIR;1") .eqs. "")
+$ then
+$ if (LINK_ONLY)
+$ then
+$ say "Can't find directory ""[.''dest']"". Can't link."
+$ goto error
+$ else
+$ create /directory [.'dest']
+$ endif
+$ endif
+$!
+$ if (.not. LINK_ONLY)
+$ then
+$!
+$! Arrange to get arch-specific list file placement, if LISTING, and if
+$! the user didn't specify a particular "/LIST =" destination.
+$!
+$ L = f$edit( LISTING, "COLLAPSE")
+$ if ((f$extract( 0, 5, L) .eqs. "/LIST") .and. -
+ (f$extract( 4, 1, L) .nes. "="))
+$ then
+$ LISTING = " /LIST = [.''dest']"+ f$extract( 5, 1000, LISTING)
+$ endif
+$!
+$! Define compiler command.
+$!
+$ cc = cc+ " /include = (''cc_incl')"+ LISTING+ CCOPTS
+$!
+$ endif
+$!
+$! Define linker command.
+$!
+$ link = "link ''LINKOPTS'"
+$!
+$! Make a VAXCRTL options file for GNU C or VAC C, if needed.
+$!
+$ if ((opts .nes. "") .and. -
+ (f$locate( "VAXCSHR", f$edit( opts, "UPCASE")) .lt. f$length( opts)) .and. -
+ (f$search( "[.''dest']VAXCSHR.OPT") .eqs. ""))
+$ then
+$ open /write opt_file_ln [.'dest']VAXCSHR.OPT
+$ write opt_file_ln "SYS$SHARE:VAXCRTL.EXE /SHARE"
+$ close opt_file_ln
+$ endif
+$!
+$! Show interesting facts.
+$!
+$ say " architecture = ''arch' (destination = [.''dest'])"
+$ if (.not. LINK_ONLY)
+$ then
+$ say " cc = ''cc'"
+$ endif
+$ say " link = ''link'"
+$ if (.not. MAKE_HELP)
+$ then
+$ say " Not making new help files."
+$ endif
+$ say ""
+$ if (.not. MAKE_MSG)
+$ then
+$ say " Not making new message files."
+$ endif
+$ say ""
+$!
+$ tmp = f$verify( 1) ! Turn echo on to see what's happening.
+$!
+$!-------------------------------- Zip section -------------------------------
+$!
+$ if (.not. LINK_ONLY)
+$ then
+$!
+$! Process the help file, if desired.
+$!
+$ if (MAKE_HELP)
+$ then
+$ runoff /out = ZIP.HLP [.VMS]VMS_ZIP.RNH
+$ endif
+$!
+$! Process the message file, if desired.
+$!
+$ if (MAKE_MSG)
+$ then
+$!
+$! Create the message source file first, if it's not found.
+$!
+$ if (f$search( "[.VMS]ZIP_MSG.MSG") .eqs. "")
+$ then
+$ cc /include = [] /object = [.'dest']VMS_MSG_GEN.OBJ -
+ [.VMS]VMS_MSG_GEN.C
+$ link /executable = [.'dest']VMS_MSG_GEN.EXE -
+ [.'dest']VMS_MSG_GEN.OBJ
+$ create /fdl = [.VMS]STREAM_LF.FDL [.VMS]ZIP_MSG.MSG
+$ define /user_mode sys$output [.VMS]ZIP_MSG.MSG
+$ run [.'dest']VMS_MSG_GEN.EXE
+$ purge [.VMS]ZIP_MSG.MSG
+$ delete [.'dest']VMS_MSG_GEN.EXE;*, -
+ [.'dest']VMS_MSG_GEN.OBJ;*
+$ endif
+$!
+$ message /object = [.'dest']ZIP_MSG.OBJ /nosymbols -
+ [.VMS]ZIP_MSG.MSG
+$ link /shareable = [.'dest']ZIP_MSG.EXE [.'dest']ZIP_MSG.OBJ
+$ endif
+$!
+$! Compile the sources.
+$!
+$ cc 'DEF_UNX' /object = [.'dest']ZIP.OBJ ZIP.C
+$ cc 'DEF_UNX' /object = [.'dest']CRC32.OBJ CRC32.C
+$ cc 'DEF_UNX' /object = [.'dest']CRYPT.OBJ CRYPT.C
+$ cc 'DEF_UNX' /object = [.'dest']DEFLATE.OBJ DEFLATE.C
+$ cc 'DEF_UNX' /object = [.'dest']FILEIO.OBJ FILEIO.C
+$ cc 'DEF_UNX' /object = [.'dest']GLOBALS.OBJ GLOBALS.C
+$ cc 'DEF_UNX' /object = [.'dest']TREES.OBJ TREES.C
+$ cc 'DEF_UNX' /object = [.'dest']TTYIO.OBJ TTYIO.C
+$ cc 'DEF_UNX' /object = [.'dest']UTIL.OBJ UTIL.C
+$ cc 'DEF_UNX' /object = [.'dest']ZBZ2ERR.OBJ ZBZ2ERR.C
+$ cc 'DEF_UNX' /object = [.'dest']ZIPFILE.OBJ ZIPFILE.C
+$ cc 'DEF_UNX' /object = [.'dest']ZIPUP.OBJ ZIPUP.C
+$ cc /include = [] 'DEF_UNX' /object = [.'dest']VMS.OBJ -
+ [.VMS]VMS.C
+$ cc /include = [] 'DEF_UNX' /object = [.'dest']VMSMUNCH.OBJ -
+ [.VMS]VMSMUNCH.C
+$ cc /include = [] 'DEF_UNX' /object = [.'dest']VMSZIP.OBJ -
+ [.VMS]VMSZIP.C
+$!
+$! Create the object library.
+$!
+$ if (f$search( "[.''dest']ZIP.OLB") .eqs. "") then -
+ libr /object /create [.'dest']ZIP.OLB
+$!
+$ libr /object /replace [.'dest']ZIP.OLB -
+ [.'dest']CRC32.OBJ, -
+ [.'dest']CRYPT.OBJ, -
+ [.'dest']DEFLATE.OBJ, -
+ [.'dest']FILEIO.OBJ, -
+ [.'dest']GLOBALS.OBJ, -
+ [.'dest']TREES.OBJ, -
+ [.'dest']TTYIO.OBJ, -
+ [.'dest']UTIL.OBJ, -
+ [.'dest']ZBZ2ERR.OBJ, -
+ [.'dest']ZIPFILE.OBJ, -
+ [.'dest']ZIPUP.OBJ, -
+ [.'dest']VMS.OBJ, -
+ [.'dest']VMSMUNCH.OBJ, -
+ [.'dest']VMSZIP.OBJ
+$!
+$ endif
+$!
+$! Link the executable.
+$!
+$ link /executable = [.'dest']'ZIPX_UNX'.EXE -
+ [.'dest']ZIP.OBJ, -
+ [.'dest']ZIP.OLB /include = (GLOBALS 'incl_bzip2_m') /library, -
+ 'lib_bzip2_opts' -
+ 'opts' -
+ SYS$DISK:[.VMS]ZIP.OPT /options
+$!
+$!------------------------ Zip (CLI interface) section -----------------------
+$!
+$ if (.not. LINK_ONLY)
+$ then
+$!
+$! Process the CLI help file, if desired.
+$!
+$ if (MAKE_HELP)
+$ then
+$ set default [.VMS]
+$ edit /tpu /nosection /nodisplay /command = cvthelp.tpu -
+ zip_cli.help
+$ set default [-]
+$ runoff /output = ZIP_CLI.HLP [.VMS]ZIP_CLI.RNH
+$ endif
+$!
+$! Compile the CLI sources.
+$!
+$ cc 'DEF_CLI' /object = [.'dest']ZIPCLI.OBJ ZIP.C
+$ cc /include = [] 'DEF_CLI' /object = [.'dest']CMDLINE.OBJ -
+ [.VMS]CMDLINE.C
+$!
+$! Create the command definition object file.
+$!
+$ set command /object = [.'dest']ZIP_CLI.OBJ [.VMS]ZIP_CLI.CLD
+$!
+$! Create the CLI object library.
+$!
+$ if (f$search( "[.''dest']ZIPCLI.OLB") .eqs. "") then -
+ libr /object /create [.'dest']ZIPCLI.OLB
+$!
+$ libr /object /replace [.'dest']ZIPCLI.OLB -
+ [.'dest']ZIPCLI.OBJ, -
+ [.'dest']CMDLINE.OBJ, -
+ [.'dest']ZIP_CLI.OBJ
+$!
+$ endif
+$!
+$! Link the CLI executable.
+$!
+$ link /executable = [.'dest']'ZIPX_CLI'.EXE -
+ [.'dest']ZIPCLI.OBJ, -
+ [.'dest']ZIPCLI.OLB /library, -
+ [.'dest']ZIP.OLB /include = (GLOBALS 'incl_bzip2_m') /library, -
+ 'lib_bzip2_opts' -
+ 'opts' -
+ SYS$DISK:[.VMS]ZIP.OPT /options
+$!
+$!--------------------------- Zip utilities section --------------------------
+$!
+$ if (.not. LINK_ONLY)
+$ then
+$!
+$! Compile the variant Zip utilities library sources.
+$!
+$ cc 'DEF_UTIL' /object = [.'dest']CRC32_.OBJ CRC32.C
+$ cc 'DEF_UTIL' /object = [.'dest']CRYPT_.OBJ CRYPT.C
+$ cc 'DEF_UTIL' /object = [.'dest']FILEIO_.OBJ FILEIO.C
+$ cc 'DEF_UTIL' /object = [.'dest']UTIL_.OBJ UTIL.C
+$ cc 'DEF_UTIL' /object = [.'dest']ZIPFILE_.OBJ ZIPFILE.C
+$ cc 'DEF_UTIL' /include = [] /object = [.'dest']VMS_.OBJ [.VMS]VMS.C
+$!
+$! Create the Zip utilities object library.
+$!
+$ if f$search( "[.''dest']ZIPUTILS.OLB") .eqs. "" then -
+ libr /object /create [.'dest']ZIPUTILS.OLB
+$!
+$ libr /object /replace [.'dest']ZIPUTILS.OLB -
+ [.'dest']CRC32_.OBJ, -
+ [.'dest']CRYPT_.OBJ, -
+ [.'dest']FILEIO_.OBJ, -
+ [.'dest']GLOBALS.OBJ, -
+ [.'dest']TTYIO.OBJ, -
+ [.'dest']UTIL_.OBJ, -
+ [.'dest']ZIPFILE_.OBJ, -
+ [.'dest']VMS_.OBJ, -
+ [.'dest']VMSMUNCH.OBJ
+$!
+$! Compile the Zip utilities main program sources.
+$!
+$ cc 'DEF_UTIL' /object = [.'dest']ZIPCLOAK.OBJ ZIPCLOAK.C
+$ cc 'DEF_UTIL' /object = [.'dest']ZIPNOTE.OBJ ZIPNOTE.C
+$ cc 'DEF_UTIL' /object = [.'dest']ZIPSPLIT.OBJ ZIPSPLIT.C
+$!
+$ endif
+$!
+$! Link the Zip utilities executables.
+$!
+$ link /executable = [.'dest']ZIPCLOAK.EXE -
+ [.'dest']ZIPCLOAK.OBJ, -
+ [.'dest']ZIPUTILS.OLB /include = (GLOBALS) /library, -
+ 'opts' -
+ SYS$DISK:[.VMS]ZIP.OPT /options
+$!
+$ link /executable = [.'dest']ZIPNOTE.EXE -
+ [.'dest']ZIPNOTE.OBJ, -
+ [.'dest']ZIPUTILS.OLB /include = (GLOBALS) /library, -
+ 'opts' -
+ SYS$DISK:[.VMS]ZIP.OPT /OPTIONS
+$!
+$ LINK /EXECUTABLE = [.'DEST']ZIPSPLIT.EXE -
+ [.'DEST']ZIPSPLIT.OBJ, -
+ [.'DEST']ZIPUTILS.OLB /INCLUDE = (globals) /LIBRARY, -
+ 'opts' -
+ SYS$DISK:[.VMS]ZIP.OPT /options
+$!
+$!----------------------- Logical name removal section -----------------------
+$!
+$ if (IZ_BZIP2 .nes. "")
+$ then
+$ if (f$trnlnm( "incl_bzip2", "LNM$PROCESS_TABLE") .nes. "")
+$ then
+$ deassign incl_bzip2
+$ endif
+$ if (f$trnlnm( "lib_bzip2", "LNM$PROCESS_TABLE") .nes. "")
+$ then
+$ deassign lib_bzip2
+$ endif
+$ endif
+$!
+$!------------------------------ Symbols section -----------------------------
+$!
+$ there = here- "]"+ ".''dest']"
+$!
+$! Define the foreign command symbols. Similar commands may be useful
+$! in SYS$MANAGER:SYLOGIN.COM and/or users' LOGIN.COM.
+$!
+$ zip == "$''there'''ZIPEXEC'.exe"
+$ zipcloak == "$''there'zipcloak.exe"
+$ zipnote == "$''there'zipnote.exe"
+$ zipsplit == "$''there'zipsplit.exe"
+$!
+$! Restore the original default directory and DCL verify status.
+$!
+$ error:
+$!
+$ if (f$type( here) .nes. "")
+$ then
+$ if (here .nes. "")
+$ then
+$ set default 'here'
+$ endif
+$ endif
+$!
+$ if (f$type( OLD_VERIFY) .nes. "")
+$ then
+$ tmp = f$verify( OLD_VERIFY)
+$ endif
+$!
+$ exit
+$!
diff --git a/vms/bzlib.h b/vms/bzlib.h
new file mode 100644
index 0000000..20488ea
--- /dev/null
+++ b/vms/bzlib.h
@@ -0,0 +1,21 @@
+/* 2007-01-13 SMS.
+ * VMS-specific BZLIB.H jacket header file to ensure compatibility with
+ * BZIP2 code compiled using /NAMES = AS_IS.
+ *
+ * The logical name INCL_BZIP2 must point to the BZIP2 source directory.
+ *
+ * A "names as_is" prototype for bz_internal_error() is included for the
+ * same reason. See bzip2 "bzlib_private.h". Note that this "names
+ * as_is" prototype must be the first to be read by the compiler, but
+ * one or more other prototypes (perhaps with the default "names"
+ * attributes) should cause no trouble.
+ */
+
+#pragma names save
+#pragma names as_is
+
+#include "INCL_BZIP2:BZLIB.H"
+
+extern void bz_internal_error ( int errcode );
+
+#pragma names restore
diff --git a/vms/cmdline.c b/vms/cmdline.c
index cae91b3..9816bd5 100644
--- a/vms/cmdline.c
+++ b/vms/cmdline.c
@@ -1,13 +1,39 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
-#define module_name VMS_ZIP_CMDLINE
-#define module_ident "02-006"
+
+/*
+ Test procedure:
+
+ Compile and link (in [.VMS] directory):
+
+ define vms SYS$DISK:[]
+ set command /object ZIP_CLI.CLD
+ cc /define = (TEST, VMSCLI) /include = [-] CMDLINE
+ link link CMDLINE.OBJ, ZIP_CLI.OBJ
+
+ Run:
+
+ exec*ute == "$SYS$DISK:[]'"
+ exec cmdline [options ...]
+
+*/
+
+/* 2004-12-13 SMS.
+ * Disabled the module name macro to accommodate old GNU C which didn't
+ * obey the directive, and thus confused MMS/MMK where the object
+ * library dependencies need to have the correct module name.
+ */
+#if 0
+# define module_name VMS_ZIP_CMDLINE
+# define module_ident "02-006"
+#endif /* 0 */
+
/*
**
** Facility: ZIP
@@ -24,6 +50,8 @@
**
** Modified by:
**
+** 02-007 Steven Schweda 09-FEB-2005
+** Added /PRESERVE_CASE.
** 02-006 Onno van der Linden,
** Christian Spieler 07-JUL-1998 23:03
** Support GNU CC 2.8 on Alpha AXP (vers-num unchanged).
@@ -53,11 +81,29 @@
*/
-#if defined(__DECC) || defined(__GNUC__)
-#pragma module module_name module_ident
-#else
-#module module_name module_ident
-#endif
+/* 2004-12-13 SMS.
+ * Disabled the module name macro to accommodate old GNU C which didn't
+ * obey the directive, and thus confused MMS/MMK where the object
+ * library dependencies need to have the correct module name.
+ */
+#if 0
+# if defined(__DECC) || defined(__GNUC__)
+# pragma module module_name module_ident
+# else
+# module module_name module_ident
+# endif
+#endif /* 0 */
+
+/* Accomodation for /NAMES = AS_IS with old header files. */
+
+#define lib$establish LIB$ESTABLISH
+#define lib$get_foreign LIB$GET_FOREIGN
+#define lib$get_input LIB$GET_INPUT
+#define lib$sig_to_ret LIB$SIG_TO_RET
+#define ots$cvt_tu_l OTS$CVT_TU_L
+#define str$concat STR$CONCAT
+#define str$find_first_substring STR$FIND_FIRST_SUBSTRING
+#define str$free1_dx STR$FREE1_DX
#include "zip.h"
#ifndef TEST
@@ -121,49 +167,103 @@ $DESCRIPTOR(cli_append, "APPEND"); /* -g */
$DESCRIPTOR(cli_batch, "BATCH"); /* -@ */
$DESCRIPTOR(cli_before, "BEFORE"); /* -tt */
$DESCRIPTOR(cli_comments, "COMMENTS"); /* -c,-z */
+$DESCRIPTOR(cli_comment_archive,"COMMENTS.ARCHIVE"); /* -z */
$DESCRIPTOR(cli_comment_zipfile,"COMMENTS.ZIP_FILE"); /* -z */
$DESCRIPTOR(cli_comment_files, "COMMENTS.FILES"); /* -c */
+$DESCRIPTOR(cli_compression, "COMPRESSION"); /* -Z */
+$DESCRIPTOR(cli_compression_b, "COMPRESSION.BZIP2"); /* -Zb */
+$DESCRIPTOR(cli_compression_d, "COMPRESSION.DEFLATE"); /* -Zd */
+$DESCRIPTOR(cli_compression_s, "COMPRESSION.STORE"); /* -Zs */
+$DESCRIPTOR(cli_copy_entries, "COPY_ENTRIES"); /* -U */
+$DESCRIPTOR(cli_descriptors, "DESCRIPTORS"); /* -fd */
+$DESCRIPTOR(cli_difference, "DIFFERENCE"); /* -DF */
$DESCRIPTOR(cli_dirnames, "DIRNAMES"); /* -D */
+$DESCRIPTOR(cli_display, "DISPLAY"); /* -d? */
+$DESCRIPTOR(cli_display_bytes, "DISPLAY.BYTES"); /* -db */
+$DESCRIPTOR(cli_display_counts, "DISPLAY.COUNTS"); /* -dc */
+$DESCRIPTOR(cli_display_dots, "DISPLAY.DOTS"); /* -dd,-ds */
+$DESCRIPTOR(cli_display_globaldots, "DISPLAY.GLOBALDOTS"); /* -dg */
+$DESCRIPTOR(cli_display_usize, "DISPLAY.USIZE"); /* -du */
+$DESCRIPTOR(cli_display_volume, "DISPLAY.VOLUME"); /* -dv */
+$DESCRIPTOR(cli_dot_version, "DOT_VERSION"); /* -ww */
$DESCRIPTOR(cli_encrypt, "ENCRYPT"); /* -e,-P */
-$DESCRIPTOR(cli_extra_fields, "EXTRA_FIELDS"); /* -X */
+$DESCRIPTOR(cli_extra_fields, "EXTRA_FIELDS"); /* -X [/NO] */
+$DESCRIPTOR(cli_extra_fields_normal, "EXTRA_FIELDS.NORMAL"); /* no -X */
+$DESCRIPTOR(cli_extra_fields_keep, "EXTRA_FIELDS.KEEP_EXISTING"); /* -X- */
+$DESCRIPTOR(cli_filesync, "FILESYNC"); /* -FS */
$DESCRIPTOR(cli_fix_archive, "FIX_ARCHIVE"); /* -F[F] */
$DESCRIPTOR(cli_fix_normal, "FIX_ARCHIVE.NORMAL"); /* -F */
$DESCRIPTOR(cli_fix_full, "FIX_ARCHIVE.FULL"); /* -FF */
$DESCRIPTOR(cli_full_path, "FULL_PATH"); /* -p */
+$DESCRIPTOR(cli_grow, "GROW"); /* -g */
$DESCRIPTOR(cli_help, "HELP"); /* -h */
+$DESCRIPTOR(cli_help_normal, "HELP.NORMAL"); /* -h */
+$DESCRIPTOR(cli_help_extended, "HELP.EXTENDED"); /* -h2 */
$DESCRIPTOR(cli_junk, "JUNK"); /* -j */
$DESCRIPTOR(cli_keep_version, "KEEP_VERSION"); /* -w */
$DESCRIPTOR(cli_latest, "LATEST"); /* -o */
$DESCRIPTOR(cli_level, "LEVEL"); /* -[0-9] */
$DESCRIPTOR(cli_license, "LICENSE"); /* -L */
+$DESCRIPTOR(cli_log_file, "LOG_FILE"); /* -la,-lf,-li */
+$DESCRIPTOR(cli_log_file_append, "LOG_FILE.APPEND"); /* -la */
+$DESCRIPTOR(cli_log_file_file, "LOG_FILE.FILE"); /* -lf */
+$DESCRIPTOR(cli_log_file_info, "LOG_FILE.INFORMATIONAL"); /* -li */
+$DESCRIPTOR(cli_must_match, "MUST_MATCH"); /* -MM */
+$DESCRIPTOR(cli_output, "OUTPUT"); /* -O */
+$DESCRIPTOR(cli_patt_case, "PATTERN_CASE"); /* -ic[-] */
+$DESCRIPTOR(cli_patt_case_blind, "PATTERN_CASE.BLIND"); /* -ic */
+$DESCRIPTOR(cli_patt_case_sensitive, "PATTERN_CASE.SENSITIVE"); /* -ic- */
$DESCRIPTOR(cli_pkzip, "PKZIP"); /* -k */
+$DESCRIPTOR(cli_pres_case, "PRESERVE_CASE"); /* -C */
+$DESCRIPTOR(cli_pres_case_no2, "PRESERVE_CASE.NOODS2");/* -C2- */
+$DESCRIPTOR(cli_pres_case_no5, "PRESERVE_CASE.NOODS5");/* -C5- */
+$DESCRIPTOR(cli_pres_case_ods2, "PRESERVE_CASE.ODS2"); /* -C2 */
+$DESCRIPTOR(cli_pres_case_ods5, "PRESERVE_CASE.ODS5"); /* -C5 */
$DESCRIPTOR(cli_quiet, "QUIET"); /* -q */
$DESCRIPTOR(cli_recurse, "RECURSE"); /* -r,-R */
$DESCRIPTOR(cli_recurse_path, "RECURSE.PATH"); /* -r */
$DESCRIPTOR(cli_recurse_fnames, "RECURSE.FILENAMES"); /* -R */
+$DESCRIPTOR(cli_show, "SHOW"); /* -s? */
+$DESCRIPTOR(cli_show_command, "SHOW.COMMAND"); /* -sc */
+$DESCRIPTOR(cli_show_debug, "SHOW.DEBUG"); /* -sd */
+$DESCRIPTOR(cli_show_files, "SHOW.FILES"); /* -sf */
+$DESCRIPTOR(cli_show_options, "SHOW.OPTIONS"); /* -so */
$DESCRIPTOR(cli_since, "SINCE"); /* -t */
+$DESCRIPTOR(cli_split, "SPLIT"); /* -s,-sb,-sp,-sv */
+$DESCRIPTOR(cli_split_bell, "SPLIT.BELL"); /* -sb */
+$DESCRIPTOR(cli_split_pause, "SPLIT.PAUSE"); /* -sp */
+$DESCRIPTOR(cli_split_size, "SPLIT.SIZE"); /* -s */
+$DESCRIPTOR(cli_split_verbose, "SPLIT.VERBOSE"); /* -sv */
$DESCRIPTOR(cli_store_types, "STORE_TYPES"); /* -n */
+$DESCRIPTOR(cli_sverbose, "SVERBOSE"); /* -sv */
+$DESCRIPTOR(cli_symlinks, "SYMLINKS"); /* -y */
$DESCRIPTOR(cli_temp_path, "TEMP_PATH"); /* -b */
$DESCRIPTOR(cli_test, "TEST"); /* -T */
+$DESCRIPTOR(cli_test_unzip, "TEST.UNZIP"); /* -TT */
$DESCRIPTOR(cli_translate_eol, "TRANSLATE_EOL"); /* -l[l] */
$DESCRIPTOR(cli_transl_eol_lf, "TRANSLATE_EOL.LF"); /* -l */
$DESCRIPTOR(cli_transl_eol_crlf,"TRANSLATE_EOL.CRLF"); /* -ll */
$DESCRIPTOR(cli_unsfx, "UNSFX"); /* -J */
-$DESCRIPTOR(cli_verbose, "VERBOSE"); /* -v */
+$DESCRIPTOR(cli_verbose, "VERBOSE"); /* -v (?) */
+$DESCRIPTOR(cli_verbose_normal, "VERBOSE.NORMAL"); /* -v */
$DESCRIPTOR(cli_verbose_more, "VERBOSE.MORE"); /* -vv */
$DESCRIPTOR(cli_verbose_debug, "VERBOSE.DEBUG"); /* -vvv */
+$DESCRIPTOR(cli_verbose_command,"VERBOSE.COMMAND"); /* (none) */
$DESCRIPTOR(cli_vms, "VMS"); /* -V */
$DESCRIPTOR(cli_vms_all, "VMS.ALL"); /* -VV */
+$DESCRIPTOR(cli_wildcard, "WILDCARD"); /* -nw */
+$DESCRIPTOR(cli_wildcard_nospan,"WILDCARD.NOSPAN"); /* -W */
$DESCRIPTOR(cli_yyz, "YYZ_ZIP");
+$DESCRIPTOR(cli_zip64, "ZIP64"); /* -fz */
$DESCRIPTOR(cli_zipfile, "ZIPFILE");
$DESCRIPTOR(cli_infile, "INFILE");
$DESCRIPTOR(zip_command, "zip ");
static int show_VMSCLI_help;
-#if (defined(__GNUC__) && !defined(zip_clitable))
+#if !defined(zip_clitable)
# define zip_clitable ZIP_CLITABLE
#endif
#if defined(__DECC) || defined(__GNUC__)
@@ -203,15 +303,28 @@ static unsigned long get_list (struct dsc$descriptor_s *,
char **, unsigned long *, unsigned long *);
static unsigned long get_time (struct dsc$descriptor_s *qual, char *timearg);
static unsigned long check_cli (struct dsc$descriptor_s *);
+static int verbose_command = 0;
#ifdef TEST
+
+char errbuf[ FNMAX+ 81]; /* Error message buffer. */
+
+void ziperr( int c, char *h) /* Error message display function. */
+{
+/* int c: error code from the ZE_ class */
+/* char *h: message about how it happened */
+
+printf( "%d: %s\n", c, h);
+}
+
int
-main(int argc, char **argv)
+main(int argc, char **argv) /* Main program. */
{
return (vms_zip_cmdline(&argc, &argv));
}
-#endif /* TEST */
+
+#endif /* def TEST */
unsigned long
@@ -245,7 +358,7 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
**
*/
register unsigned long status;
- char options[48];
+ char options[ 64];
char *the_cmd_line; /* buffer for argv strings */
unsigned long cmdl_size; /* allocated size of buffer */
unsigned long cmdl_len; /* used size of buffer */
@@ -307,10 +420,19 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
ptr = &options[1]; /* Point to temporary buffer */
/*
+ ** Copy entries.
+ */
+ status = cli$present(&cli_copy_entries);
+ if (status & 1)
+ /* /COPY_ENTRIES */
+ *ptr++ = 'U';
+
+ /*
** Delete the specified files from the zip file?
*/
status = cli$present(&cli_delete);
if (status & 1)
+ /* /DELETE */
*ptr++ = 'd';
/*
@@ -318,6 +440,7 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_freshen);
if (status & 1)
+ /* /FRESHEN */
*ptr++ = 'f';
/*
@@ -325,6 +448,7 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_move);
if (status & 1)
+ /* /MOVE */
*ptr++ = 'm';
/*
@@ -332,6 +456,7 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_update);
if (status & 1)
+ /* /UPDATE */
*ptr++ = 'u';
/*
@@ -339,6 +464,7 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_level);
if (status & 1) {
+ /* /LEVEL = value */
unsigned long binval;
@@ -355,30 +481,187 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_adjust);
if (status & 1)
+ /* /ADJUST_OFFSETS */
*ptr++ = 'A';
/*
** Add comments?
*/
status = cli$present(&cli_comments);
- if (status & 1) {
-/* while ((status = cli$get_value(&cli_comments, &work_str)) & 1) {
- if (strncmp(work_str.dsc$a_pointer,"ZIP",3) == 0)
- *ptr++ = 'z';
- if (strncmp(work_str.dsc$a_pointer,"FIL",3) == 0)
- *ptr++ = 'c';
- } */
+ if (status & 1)
+ {
+ int archive_or_zip_file = 0;
+
+ if ((status = cli$present(&cli_comment_archive)) & 1)
+ /* /COMMENTS = ARCHIVE */
+ archive_or_zip_file = 1;
if ((status = cli$present(&cli_comment_zipfile)) & 1)
+ /* /COMMENTS = ZIP_FILE */
+ archive_or_zip_file = 1;
+ if (archive_or_zip_file != 0)
+ /* /COMMENTS = ARCHIVE */
*ptr++ = 'z';
if ((status = cli$present(&cli_comment_files)) & 1)
+ /* /COMMENTS = FILES */
*ptr++ = 'c';
}
/*
+ ** Preserve case in file names.
+ */
+#define OPT_C "-C" /* Preserve case all. */
+#define OPT_CN "-C-" /* Down-case all. */
+#define OPT_C2 "-C2" /* Preserve case ODS2. */
+#define OPT_C2N "-C2-" /* Down-case ODS2. */
+#define OPT_C5 "-C5" /* Preserve case ODS5. */
+#define OPT_C5N "-C5-" /* Down-case ODS5. */
+
+ status = cli$present( &cli_pres_case);
+ if ((status & 1) || (status == CLI$_NEGATED))
+ {
+ /* /[NO]PRESERVE_CASE */
+ char *opt;
+ int ods2 = 0;
+ int ods5 = 0;
+
+ if (status == CLI$_NEGATED)
+ {
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_CN)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_CN);
+ }
+ else
+ {
+ if (cli$present( &cli_pres_case_no2) & 1)
+ {
+ /* /PRESERVE_CASE = NOODS2 */
+ ods2 = -1;
+ }
+ if (cli$present( &cli_pres_case_no5) & 1)
+ {
+ /* /PRESERVE_CASE = NOODS5 */
+ ods5 = -1;
+ }
+ if (cli$present( &cli_pres_case_ods2) & 1)
+ {
+ /* /PRESERVE_CASE = ODS2 */
+ ods2 = 1;
+ }
+ if (cli$present( &cli_pres_case_ods5) & 1)
+ {
+ /* /PRESERVE_CASE = ODS5 */
+ ods5 = 1;
+ }
+
+ if (ods2 == ods5)
+ {
+ /* Plain "-C[-]". */
+ if (ods2 < 0)
+ opt = OPT_CN;
+ else
+ opt = OPT_C;
+
+ x = cmdl_len;
+ cmdl_len += strlen( opt)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], opt);
+ }
+ else
+ {
+ if (ods2 != 0)
+ {
+ /* "-C2[-]". */
+ if (ods2 < 0)
+ opt = OPT_C2N;
+ else
+ opt = OPT_C2;
+
+ x = cmdl_len;
+ cmdl_len += strlen( opt)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], opt);
+ }
+
+ if (ods5 != 0)
+ {
+ /* "-C5[-]". */
+ if (ods5 < 0)
+ opt = OPT_C5N;
+ else
+ opt = OPT_C5;
+
+ x = cmdl_len;
+ cmdl_len += strlen( opt)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], opt);
+ }
+ }
+ }
+ }
+
+ /*
+ ** Pattern case sensitivity.
+ */
+#define OPT_IC "-ic" /* Case-insensitive pattern matching. */
+#define OPT_ICN "-ic-" /* Case-sensitive pattern matching. */
+
+ status = cli$present( &cli_patt_case);
+ if (status & 1)
+ {
+ if (cli$present( &cli_patt_case_blind) & 1)
+ {
+ /* "-ic". */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_IC)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_IC);
+ }
+ else if (cli$present( &cli_patt_case_sensitive) & 1)
+ {
+ /* "-ic-". */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_ICN)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_ICN);
+ }
+ }
+
+ /*
+ ** Data descriptors.
+ */
+#define OPT_FD "-fd"
+
+ status = cli$present( &cli_descriptors);
+ if (status & 1)
+ {
+ /* /DESCRIPTORS */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_FD)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_FD);
+ }
+
+ /*
+ ** Difference archive. Add only new or changed files.
+ */
+#define OPT_DF "-DF" /* Difference archive. */
+
+ if ((status = cli$present( &cli_difference)) & 1)
+ {
+ /* /DIFFERENCE */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_DF)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_DF);
+ }
+
+ /*
** Do not add/modify directory entries.
*/
status = cli$present(&cli_dirnames);
if (!(status & 1))
+ /* /DIRNAMES */
*ptr++ = 'D';
/*
@@ -387,6 +670,7 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
status = cli$present(&cli_encrypt);
if (status & 1)
if ((status = cli$get_value(&cli_encrypt, &work_str)) & 1) {
+ /* /ENCRYPT = value */
x = cmdl_len;
cmdl_len += work_str.dsc$w_length + 4;
CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len)
@@ -395,6 +679,7 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
work_str.dsc$w_length);
the_cmd_line[cmdl_len-1] = '\0';
} else {
+ /* /ENCRYPT */
*ptr++ = 'e';
}
@@ -404,30 +689,71 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
status = cli$present(&cli_fix_archive);
if (status & 1) {
*ptr++ = 'F';
+ /* /FIX_ARCHIVE = NORMAL */
if ((status = cli$present(&cli_fix_full)) & 1) {
+ /* /FIX_ARCHIVE = FULL */
*ptr++ = 'F';
}
}
/*
+ ** Filesync. Delete archive entry if no such file.
+ */
+#define OPT_FS "-FS" /* Filesync. */
+
+ if ((status = cli$present( &cli_filesync)) & 1)
+ {
+ /* /FILESYNC */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_FS)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_FS);
+ }
+
+ /*
** Append (allow growing of existing zip file).
*/
status = cli$present(&cli_append);
if (status & 1)
+ /* /APPEND */
+ *ptr++ = 'g';
+
+ status = cli$present(&cli_grow);
+ if (status & 1)
+ /* /GROW */
*ptr++ = 'g';
/*
** Show the help.
*/
+#define OPT_H2 "-h2"
+
status = cli$present(&cli_help);
if (status & 1)
- *ptr++ = 'h';
+ {
+ status = cli$present( &cli_help_normal);
+ if (status & 1)
+ {
+ /* /HELP [= NORMAL] */
+ *ptr++ = 'h';
+ }
+ status = cli$present( &cli_help_extended);
+ if (status & 1)
+ {
+ /* /HELP = EXTENDED */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_H2)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_H2);
+ }
+ }
/*
** Junk path names (directory specs).
*/
status = cli$present(&cli_junk);
if (status & 1)
+ /* /JUNK */
*ptr++ = 'j';
/*
@@ -435,6 +761,7 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_pkzip);
if (status & 1)
+ /* /KEEP_VERSION */
*ptr++ = 'k';
/*
@@ -442,8 +769,10 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_translate_eol);
if (status & 1) {
+ /* /TRANSLATE_EOL [= LF]*/
*ptr++ = 'l';
if ((status = cli$present(&cli_transl_eol_crlf)) & 1) {
+ /* /TRANSLATE_EOL = CRLF */
*ptr++ = 'l';
}
}
@@ -453,6 +782,7 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_license);
if (status & 1)
+ /* /LICENSE */
*ptr++ = 'L';
/*
@@ -460,6 +790,7 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_latest);
if (status & 1)
+ /* /LATEST */
*ptr++ = 'o';
/*
@@ -467,8 +798,10 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_full_path);
if (status == CLI$_PRESENT)
+ /* /FULL_PATH */
*ptr++ = 'p';
else if (status == CLI$_NEGATED)
+ /* /NOFULL_PATH */
*ptr++ = 'j';
/*
@@ -476,6 +809,7 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_unsfx);
if (status & 1)
+ /* /UNSFX */
*ptr++ = 'J';
/*
@@ -484,23 +818,52 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
status = cli$present(&cli_recurse);
if (status & 1) {
if ((status = cli$present(&cli_recurse_fnames)) & 1)
+ /* /RECURSE [= PATH] */
*ptr++ = 'R';
else
+ /* /RECURSE [= FILENAMES] */
*ptr++ = 'r';
}
/*
+ ** Test Zipfile.
+ */
+ status = cli$present(&cli_test);
+ if (status & 1) {
+ /* /TEST */
+ *ptr++ = 'T';
+ }
+
+ /*
** Be verbose.
*/
status = cli$present(&cli_verbose);
if (status & 1) {
- *ptr++ = 'v';
+ int i;
+ int verbo = 0;
+
+ /* /VERBOSE */
+ if ((status = cli$present(&cli_verbose_command)) & 1)
+ {
+ /* /VERBOSE = COMMAND */
+ verbose_command = 1;
+ }
+
+ /* Note that any or all of the following options may be
+ specified, and the maximum one is used.
+ */
+ if ((status = cli$present(&cli_verbose_normal)) & 1)
+ /* /VERBOSE [ = NORMAL ] */
+ verbo = 1;
if ((status = cli$present(&cli_verbose_more)) & 1)
- *ptr++ = 'v';
+ /* /VERBOSE = MORE */
+ verbo = 2;
if ((status = cli$present(&cli_verbose_debug)) & 1) {
- *ptr++ = 'v';
- *ptr++ = 'v';
+ /* /VERBOSE = DEBUG */
+ verbo = 3;
}
+ for (i = 0; i < verbo; i++)
+ *ptr++ = 'v';
}
/*
@@ -510,16 +873,10 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_quiet);
if (status & 1)
+ /* /QUIET */
*ptr++ = 'q';
/*
- ** Suppress creation of any extra field.
- */
- status = cli$present(&cli_extra_fields);
- if (!(status & 1))
- *ptr++ = 'X';
-
- /*
** Save the VMS file attributes (and all allocated blocks?).
*/
status = cli$present(&cli_vms);
@@ -537,16 +894,27 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_keep_version);
if (status & 1)
+ /* /KEEP_VERSION */
*ptr++ = 'w';
/*
+ ** Store symlinks as symlinks.
+ */
+ status = cli$present(&cli_symlinks);
+ if (status & 1)
+ /* /SYMLINKS */
+ *ptr++ = 'y';
+
+ /*
** `Batch' processing: read filenames to archive from stdin
** or the specified file.
*/
status = cli$present(&cli_batch);
if (status & 1) {
+ /* /BATCH */
status = cli$get_value(&cli_batch, &work_str);
if (status & 1) {
+ /* /BATCH = value */
work_str.dsc$a_pointer[work_str.dsc$w_length] = '\0';
if ((stdin = freopen(work_str.dsc$a_pointer, "r", stdin)) == NULL)
{
@@ -573,12 +941,14 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
/*
**
** OK. We've done all the regular options, so check for -b (temporary
- ** file path), -t (exclude before time), -n (special suffixes), zipfile,
+ ** file path), -n (special suffixes), -O (output atchive file),
+ ** -t (exclude before time), -Z (compression method), zipfile,
** files to zip, and exclude list.
**
*/
status = cli$present(&cli_temp_path);
if (status & 1) {
+ /* /TEMP_PATH = value */
status = cli$get_value(&cli_temp_path, &work_str);
x = cmdl_len;
cmdl_len += work_str.dsc$w_length + 4;
@@ -589,11 +959,378 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
the_cmd_line[cmdl_len-1] = '\0';
}
+ status = cli$present(&cli_output);
+ if (status & 1) {
+ /* /OUTPUT = value */
+ status = cli$get_value(&cli_output, &work_str);
+ x = cmdl_len;
+ cmdl_len += work_str.dsc$w_length + 4;
+ CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len)
+ strcpy(&the_cmd_line[x], "-O");
+ strncpy(&the_cmd_line[x+3], work_str.dsc$a_pointer,
+ work_str.dsc$w_length);
+ the_cmd_line[cmdl_len-1] = '\0';
+ }
+
+ /*
+ ** Handle "-db", "-dc", "-dd", "-ds".
+ */
+#define OPT_DB "-db"
+#define OPT_DC "-dc"
+#define OPT_DD "-dd"
+#define OPT_DG "-dg"
+#define OPT_DS "-ds="
+#define OPT_DU "-du"
+#define OPT_DV "-dv"
+
+ status = cli$present( &cli_display);
+ if (status & 1)
+ {
+ if ((status = cli$present( &cli_display_bytes)) & 1)
+ {
+ /* /DISPLAY = BYTES */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_DB)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_DB);
+ }
+
+ if ((status = cli$present( &cli_display_counts)) & 1)
+ {
+ /* /DISPLAY = COUNTS */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_DC)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_DC);
+ }
+
+ if ((status = cli$present( &cli_display_dots)) & 1)
+ {
+ /* /DISPLAY = DOTS [= value] */
+ status = cli$get_value( &cli_display_dots, &work_str);
+
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_DD)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_DD);
+
+ /* -dd[=value] now -dd -ds=value - 5/8/05 EG */
+ if (work_str.dsc$w_length > 0) {
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_DS);
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_DS);
+
+ x = cmdl_len;
+ cmdl_len += work_str.dsc$w_length+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strncpy( &the_cmd_line[ x],
+ work_str.dsc$a_pointer, work_str.dsc$w_length);
+ }
+ }
+
+ if ((status = cli$present( &cli_display_globaldots)) & 1)
+ {
+ /* /DISPLAY = GLOBALDOTS */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_DG)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_DG);
+ }
+
+ if ((status = cli$present( &cli_display_usize)) & 1)
+ {
+ /* /DISPLAY = USIZE */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_DU)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_DU);
+ }
+
+ if ((status = cli$present( &cli_display_volume)) & 1)
+ {
+ /* /DISPLAY = VOLUME */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_DV)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_DV);
+ }
+ }
+
+ /*
+ ** Handle "-la", "-lf", "-li".
+ */
+#define OPT_LA "-la"
+#define OPT_LF "-lf"
+#define OPT_LI "-li"
+
+ status = cli$present( &cli_log_file);
+ if (status & 1)
+ {
+ /* /SHOW */
+ if ((status = cli$present( &cli_log_file_append)) & 1)
+ {
+ /* /LOG_FILE = APPEND */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_LA)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_LA);
+ }
+
+ status = cli$present(&cli_log_file_file);
+ if (status & 1) {
+ /* /LOG_FILE = FILE = file */
+ status = cli$get_value(&cli_log_file_file, &work_str);
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_LF)+ 2+ work_str.dsc$w_length;
+ CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len)
+ strcpy(&the_cmd_line[x], OPT_LF);
+ strncpy(&the_cmd_line[x+strlen( OPT_LF)+ 1], work_str.dsc$a_pointer,
+ work_str.dsc$w_length);
+ the_cmd_line[cmdl_len-1] = '\0';
+ }
+
+ if ((status = cli$present( &cli_log_file_info)) & 1)
+ {
+ /* /LOG = INFO */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_LI)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_LI);
+ }
+ }
+
+ /*
+ ** Handle "-s", "-sb", "-sp", "-sv".
+ */
+#define OPT_S "-s"
+#define OPT_SB "-sb"
+#define OPT_SP "-sp"
+#define OPT_SV "-sv"
+
+ status = cli$present( &cli_split);
+ if (status & 1)
+ {
+ status = cli$present( &cli_split_bell);
+ if (status & 1)
+ {
+ /* /SPLIT = BELL */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_SB)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_SB);
+ }
+
+ status = cli$present( &cli_split_pause);
+ if (status & 1)
+ {
+ /* /SPLIT = PAUSE */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_SP)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_SP);
+ }
+
+ status = cli$present( &cli_split_size);
+ if (status & 1)
+ {
+ /* /SPLIT = SIZE = size */
+ status = cli$get_value( &cli_split_size, &work_str);
+
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_S)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_S);
+
+ x = cmdl_len;
+ cmdl_len += work_str.dsc$w_length+ 1;
+ strncpy( &the_cmd_line[ x],
+ work_str.dsc$a_pointer, work_str.dsc$w_length);
+ }
+
+ status = cli$present( &cli_split_verbose);
+ if (status & 1)
+ {
+ /* /SPLIT = VERBOSE */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_SV)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_SV);
+ }
+ }
+
+ /*
+ ** Handle "-sc", "-sd", "-sf", "-so".
+ */
+#define OPT_SC "-sc"
+#define OPT_SD "-sd"
+#define OPT_SF "-sf"
+#define OPT_SO "-so"
+
+ status = cli$present( &cli_show);
+ if (status & 1)
+ {
+ /* /SHOW */
+ if ((status = cli$present( &cli_show_command)) & 1)
+ {
+ /* /SHOW = COMMAND */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_SC)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_SC);
+ }
+
+ if ((status = cli$present( &cli_show_debug)) & 1)
+ {
+ /* /SHOW = DEBUG */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_SD)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_SD);
+ }
+
+ if ((status = cli$present( &cli_show_files)) & 1)
+ {
+ /* /SHOW = FILES */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_SF)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_SF);
+ }
+
+ if ((status = cli$present( &cli_show_options)) & 1)
+ {
+ /* /SHOW = OPTIONS */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_SO)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_SO);
+ }
+ }
+
+ /*
+ ** Handle "-fz".
+ */
+#define OPT_FZ "-fz"
+
+ status = cli$present( &cli_zip64);
+ if (status & 1)
+ {
+ /* /ZIP64 */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_FZ)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_FZ);
+ }
+
+ /*
+ ** Handle "-nw" and "-W".
+ */
+#define OPT_NW "-nw"
+#define OPT_W "-W"
+
+ status = cli$present( &cli_wildcard);
+ if (status & 1)
+ {
+ if ((status = cli$present( &cli_wildcard_nospan)) & 1)
+ {
+ /* /WILDCARD = NOSPAN */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_W)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_W);
+ }
+ }
+ else if (status == CLI$_NEGATED)
+ {
+ /* /NOWILDCARD */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_NW)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_NW);
+ }
+
+ /*
+ ** Handle "-MM".
+ */
+#define OPT_MM "-MM"
+
+ status = cli$present( &cli_must_match);
+ if (status & 1)
+ {
+ /* /MUST_MATCH */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_MM)+ 1;
+ CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_MM);
+ }
+
+ /*
+ ** UnZip command for archive test.
+ */
+#define OPT_TT "-TT"
+
+ status = cli$present(&cli_test);
+ if (status & 1) {
+ /* /TEST */
+ status = cli$present(&cli_test_unzip);
+ if (status & 1) {
+ /* /TEST = UNZIP = value */
+ status = cli$get_value(&cli_test_unzip, &work_str);
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_TT)+ 2+ work_str.dsc$w_length;
+ CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len)
+ strcpy(&the_cmd_line[x], OPT_TT);
+ strncpy(&the_cmd_line[x+strlen( OPT_TT)+ 1], work_str.dsc$a_pointer,
+ work_str.dsc$w_length);
+ the_cmd_line[cmdl_len-1] = '\0';
+ }
+ }
+
+ /*
+ ** Handle "-Z".
+ */
+#define OPT_ZB "-Zb"
+#define OPT_ZD "-Zd"
+#define OPT_ZS "-Zs"
+
+ status = cli$present( &cli_compression);
+ if (status & 1)
+ {
+ if ((status = cli$present( &cli_compression_b)) & 1)
+ {
+ /* /COMPRESSION = BZIP2 */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_ZB)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_ZB);
+ }
+
+ if ((status = cli$present( &cli_compression_d)) & 1)
+ {
+ /* /COMPRESSION = DEFLATE */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_ZD)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_ZD);
+ }
+
+ if ((status = cli$present( &cli_compression_s)) & 1)
+ {
+ /* /COMPRESSION = STORE */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_ZS)+ 1;
+ CHECK_BUFFER_ALLOCATION( the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_ZS);
+ }
+ }
+
/*
** Handle "-t mmddyyyy".
*/
status = cli$present(&cli_since);
if (status & 1) {
+ /* /SINCE = value */
char since_time[9];
status = get_time(&cli_since, &since_time[0]);
@@ -614,6 +1351,7 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_before);
if (status & 1) {
+ /* /BEFORE = value */
char before_time[9];
status = get_time(&cli_before, &before_time[0]);
@@ -634,6 +1372,7 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_store_types);
if (status & 1) {
+ /* /STORE_TYPES = value_list */
x = cmdl_len;
cmdl_len += 3;
CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len)
@@ -645,9 +1384,35 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
}
/*
+ ** Handle "-X", keep or strip extra fields.
+ */
+#define OPT_X "-X"
+#define OPT_XN "-X-"
+
+ status = cli$present(&cli_extra_fields);
+ if (status & 1) {
+ /* /EXTRA_FIELDS */
+ if ((status = cli$present( &cli_extra_fields_keep)) & 1) {
+ /* /EXTRA_FIELDS = KEEP_EXISTING */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_XN)+ 1;
+ CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_XN);
+ }
+ }
+ else if (status == CLI$_NEGATED) {
+ /* /NOEXTRA_FIELDS */
+ x = cmdl_len;
+ cmdl_len += strlen( OPT_X)+ 1;
+ CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len)
+ strcpy( &the_cmd_line[ x], OPT_X);
+ }
+
+ /*
** Now get the specified zip file name.
*/
status = cli$present(&cli_zipfile);
+ /* zipfile */
if (status & 1) {
status = cli$get_value(&cli_zipfile, &work_str);
@@ -665,6 +1430,7 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_infile);
if (status & 1) {
+ /* infile_list */
status = get_list(&cli_infile, &foreign_cmdline, '\0',
&the_cmd_line, &cmdl_size, &cmdl_len);
if (!(status & 1)) return (status);
@@ -675,6 +1441,7 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_exlist);
if (status & 1) {
+ /* /EXLIST = list */
status = cli$get_value(&cli_exlist, &work_str);
x = cmdl_len;
cmdl_len += work_str.dsc$w_length + 4;
@@ -690,6 +1457,7 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_exclude);
if (status & 1) {
+ /* /EXCLUDE = list */
x = cmdl_len;
cmdl_len += 3;
CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len)
@@ -705,6 +1473,7 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_inlist);
if (status & 1) {
+ /* /INLIST = list */
status = cli$get_value(&cli_inlist, &work_str);
x = cmdl_len;
cmdl_len += work_str.dsc$w_length + 4;
@@ -720,6 +1489,7 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
*/
status = cli$present(&cli_include);
if (status & 1) {
+ /* /INCLUDE = list */
x = cmdl_len;
cmdl_len += 3;
CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len)
@@ -769,6 +1539,15 @@ vms_zip_cmdline (int *argc_p, char ***argv_p)
printf("new_argv[%d] = %s\n", x, new_argv[x]);
#endif /* TEST || DEBUG */
+ /* Show the complete UNIX command line, if requested. */
+ if (verbose_command != 0)
+ {
+ printf( " UNIX command line args (argc = %d):\n", new_argc);
+ for (x = 0; x < new_argc; x++)
+ printf( "%s\n", new_argv[ x]);
+ printf( "\n");
+ }
+
/*
** All finished. Return the new argc and argv[] addresses to Zip.
*/
@@ -967,27 +1746,40 @@ void VMSCLI_help(void) /* VMSCLI version */
/* help array */
static char *text[] = {
-"Zip %s (%s). Usage: zip==\"$disk:[dir]zip.exe\"",
-"zip zipfile[.zip] [list] [/EXCL=(xlist)] /options /modifiers",
-" The default action is to add or replace zipfile entries from list, except",
-" those in xlist. The include file list may contain the special name - to",
-" compress standard input. If both zipfile and list are omitted, zip",
+"Zip %s (%s). Usage: (zip :== $ dev:[dir]zip_cli.exe)",
+"zip archive[.zip] [list] [/EXCL=(xlist)] /options /modifiers",
+" The default action is to add or replace archive entries from list, except",
+" those in xlist. The include file list may contain the special name \"-\" to",
+" compress standard input. If both archive and list are omitted, Zip",
" compresses stdin to stdout.",
-" Type zip -h for Unix style flags.",
+" Type zip -h for Unix-style flags.",
" Major options include:",
-" /FRESHEN, /UPDATE, /DELETE, /[NO]MOVE, /COMMENTS[={ZIP_FILE|FILES}],",
-" /LATEST, /TEST, /ADJUST_OFFSETS, /FIX_ARCHIVE[=FULL], /UNSFX",
+" /COPY, /DELETE, /DIFFERENCE, /FILESYNC, /FRESHEN, /GROW, /MOVE, /UPDATE,",
+" /ADJUST_OFFSETS, /FIX_ARCHIVE[={NORMAL|FULL}], /TEST[=UNZIP=cmd], /UNSFX,",
" Modifiers include:",
-" /EXCLUDE=(file list), /INCLUDE=(file list), /SINCE=\"creation time\",",
+" /BATCH[=list_file], /BEFORE=creation_time, /COMMENTS[={ARCHIVE|FILES}],",
+" /EXCLUDE=(file_list), /EXLIST=file, /INCLUDE=(file_list), /INLIST=file,",
+" /LATEST, /OUTPUT=out_archive, /SINCE=creation_time, /TEMP_PATH=directory,",
+" /LOG_FILE=(FILE=log_file[,APPEND][,INFORMATIONAL]), /MUST_MATCH,",
+" /PATTERN_CASE={BLIND|SENSITIVE}, /NORECURSE|/RECURSE[={PATH|FILENAMES}],",
+" /STORE_TYPES=(type_list),",
#if CRYPT
"\
- /QUIET,/VERBOSE[=MORE],/[NO]RECURSE,/[NO]DIRNAMES,/JUNK,/ENCRYPT[=\"pwd\"],\
+ /QUIET, /VERBOSE[={MORE|DEBUG}], /[NO]DIRNAMES, /JUNK, /ENCRYPT[=\"pwd\"],\
",
#else /* !CRYPT */
-" /QUIET, /VERBOSE[=MORE], /[NO]RECURSE, /[NO]DIRNAMES, /JUNK,",
+" /QUIET, /VERBOSE[={MORE|DEBUG}], /[NO]DIRNAMES, /JUNK,",
#endif /* ?CRYPT */
-" /[NO]KEEP_VERSION, /[NO]VMS, /[NO]PKZIP, /TRANSLATE_EOL[={LF|CRLF}],",
-" /[NO]EXTRA_FIELDS /LEVEL=[0-9], /TEMP_PATH=directory, /BATCH[=list file]"
+" /COMPRESSION = {BZIP2|DEFLATE|STORE}, /LEVEL=[0-9], /NOVMS|/VMS[=ALL],",
+" /STORE_TYPES=(type_list), /[NO]PRESERVE_CASE[=([NO]ODS{2|5}[,...])],",
+" /[NO]PKZIP, /[NO]KEEP_VERSION, /DOT_VERSION, /TRANSLATE_EOL[={LF|CRLF}],",
+" /DISPLAY=([BYTES][,COUNTS][,DOTS=mb_per_dot][,GLOBALDOTS][,USIZE]",
+" [,VOLUME]), /DESCRIPTORS, /[NO]EXTRA_FIELDS, /ZIP64,",
+#ifdef S_IFLNK
+" /SPLIT = (SIZE=ssize [,BELL] [,PAUSE] [,VERBOSE]), /SYMLINKS"
+#else /* S_IFLNK */
+" /SPLIT = (SIZE=ssize [,BELL] [,PAUSE] [,VERBOSE])"
+#endif /* S_IFLNK [else] */
};
if (!show_VMSCLI_help) {
diff --git a/vms/collect_deps.com b/vms/collect_deps.com
new file mode 100644
index 0000000..349307c
--- /dev/null
+++ b/vms/collect_deps.com
@@ -0,0 +1,89 @@
+$! 1 December 2006. SMS.
+$!
+$! Info-ZIP VMS accessory procedure.
+$!
+$! For the product named by P1,
+$! collect all source file dependencies specified by P3,
+$! and add P4 prefix.
+$! Convert absolute dependencies to relative from one level above P5.
+$! P2 = output file specification.
+$!
+$! MMS /EXTENDED_SYNTAX can't easily pass a macro invocation for P4, so
+$! we remove any internal spaces which might have been added to prevent
+$! immediate evaluation of a macro invocation.
+$!
+$ prefix = f$edit( p4, "COLLAPSE")
+$!
+$ dev_lose = f$edit( f$parse( p5, , , "DEVICE", "SYNTAX_ONLY"), "UPCASE")
+$ dir_lose = f$edit( f$parse( p5, , , "DIRECTORY", "SYNTAX_ONLY"), "UPCASE")
+$ suffix = ".VMS]"
+$ suffix_loc = f$locate( suffix, dir_lose)
+$ if (suffix_loc .lt f$length( dir_lose))
+$ then
+$ dev_dir_lose = dev_lose+ dir_lose- suffix
+$ else
+$ dev_dir_lose = dev_lose+ dir_lose- "]"
+$ endif
+$!
+$! For portability, make the output file record format Stream_LF.
+$!
+$ create /fdl = sys$input 'p2'
+RECORD
+ Carriage_Control carriage_return
+ Format stream_lf
+$!
+$ open /read /write /error = end_main deps_out 'p2'
+$ on error then goto loop_main_end
+$!
+$! Include proper-inclusion-check preface.
+$!
+$ incl_macro = "INCL_"+ f$parse( p2, , , "NAME", "SYNTAX_ONLY")
+$ write deps_out "#"
+$ write deps_out "# ''p1' for VMS - MMS (or MMK) Source Dependency File."
+$ write deps_out "#"
+$ write deps_out ""
+$ write deps_out -
+ "# This description file is included by other description files. It is"
+$ write deps_out -
+ "# not intended to be used alone. Verify proper inclusion."
+$ write deps_out ""
+$ write deps_out ".IFDEF ''incl_macro'"
+$ write deps_out ".ELSE"
+$ write deps_out -
+ "$$$$ THIS DESCRIPTION FILE IS NOT INTENDED TO BE USED THIS WAY."
+$ write deps_out ".ENDIF"
+$ write deps_out ""
+$!
+$! Actual dependencies from individual dependency files.
+$!
+$ loop_main_top:
+$ file = f$search( p3)
+$ if (file .eqs. "") then goto loop_main_end
+$!
+$ open /read /error = end_subs deps_in 'file'
+$ loop_subs_top:
+$ read /error = loop_subs_end deps_in line
+$ line_reduced = f$edit( line, "COMPRESS, TRIM, UPCASE")
+$ colon = f$locate( " : ", line_reduced)
+$ d_d_l_loc = f$locate( dev_dir_lose, -
+ f$extract( (colon+ 3), 1000, line_reduced))
+$ if (d_d_l_loc .eq. 0)
+$ then
+$ front = f$extract( 0, (colon+ 3), line_reduced)
+$ back = f$extract( (colon+ 3+ f$length( dev_dir_lose)), -
+ 1000, line_reduced)
+$ line = front+ "["+ back
+$ endif
+$ write deps_out "''prefix'"+ "''line'"
+$ goto loop_subs_top
+$!
+$ loop_subs_end:
+$ close deps_in
+$!
+$ goto loop_main_top
+$!
+$ loop_main_end:
+$ close deps_out
+$!
+$ end_main:
+$!
diff --git a/vms/cvthelp.tpu b/vms/cvthelp.tpu
index 2324d60..8c60369 100644
--- a/vms/cvthelp.tpu
+++ b/vms/cvthelp.tpu
@@ -1,13 +1,13 @@
! TITLE CVTHELP.TPU
-! IDENT 01-000
+! IDENT 01-001
!
!++
-! Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+! Copyright (c) 1990-2001 Info-ZIP. All rights reserved.
!
-! See the accompanying file LICENSE, version 1999-Oct-05 or later
+! 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, both of these files are missing, the Info-ZIP license
-! also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+! 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
!
!++
!
@@ -26,6 +26,9 @@
!
! Modified by:
!
+! 01-001 Hunter Goatley 7-FEB-2001 15:40
+! Added <NEXT> for qualifier separators.
+!
! 01-000 Hunter Goatley 12-JAN-1992 15:15
! Original version.
!
@@ -50,6 +53,8 @@ Local temp
hg$substitute_comment(current_buffer,"<INIT>",".noflags;.lm3;.rm70");
hg$substitute_comment(current_buffer,"<LITERAL>",".lm+4;.literal");
hg$substitute_comment(current_buffer,"<LARETIL>",".end literal;.lm-4");
+ hg$substitute_comment(current_buffer,"<LITERAL0>",".literal");
+ hg$substitute_comment(current_buffer,"<0LARETIL>",".end literal");
hg$substitute_comment(current_buffer,"<DOT1LIST>",'.list 1,"o"');
hg$substitute_comment(current_buffer,"<DOT0LIST>",'.list 0,"o"');
hg$substitute_comment(current_buffer,"<ENTRY>",".le");
@@ -60,6 +65,7 @@ Local temp
hg$substitute_comment(current_buffer,"<ETON>",".end note");
hg$substitute_comment(current_buffer, LINE_BEGIN & LINE_END,".sk");
hg$substitute_comment(current_buffer, LINE_BEGIN & "|", "");
+ hg$substitute_comment(current_buffer,"<NEXT>",".br");
EndProcedure; ! eve_convert_help
diff --git a/vms/descrip.mms b/vms/descrip.mms
index b44c413..ae2bc04 100644
--- a/vms/descrip.mms
+++ b/vms/descrip.mms
@@ -1,315 +1,358 @@
-# VMS Makefile for Zip, ZipNote, ZipCloak and ZipSplit
-
-#
-# Modified to support both AXP and VAX by Hunter Goatley, 10-SEP-1993 06:43
-# Modified (DECC VAX, Zip 2.1) by Christian Spieler, 16-SEP-1995
-# Modified (Addition of VMS CLI) by Christian Spieler, 10-OCT-1995
-# Modified (fixed VAXC, changed compiler opts) by C. Spieler, 10-DEC-1995
-# Modified (removed zipup_.obj from Zip utils) by C. Spieler, 08-JAN-1996
-# Modified (cmdline$O depends on crypt.h) by C. Spieler, 09-JAN-1996
-# Modified (split crypt -> crypt, ttyio) by C. Spieler, 16-JAN-1996
-# Modified (modified VMSCLI compilation) by C. Spieler, 25-JUL-1997
-# Modified (comment concerning online help) by C. Spieler, 14-OCT-1997
-# Last modified (removed bits.c source file) by C. Spieler, 25-JUN-1998
-#
-# To build Zip and the Ziputils, use one of the following commands,
-# depending on your system:
-#
-# $ MMS/MACRO=(__ALPHA__=1) ! Alpha AXP, (DEC C)
-# $ MMS/MACRO=(__DECC__=1) ! VAX, using DEC C
-# $ MMS/MACRO=(__FORCE_VAXC__=1) ! VAX, prefering VAXC over DECC
-# $ MMS/MACRO=(__VAXC__=1) ! VAX, where VAXC is default
-# $ MMS/MACRO=(__GNUC__=1) ! VAX, using GNU C
-#
-# Other MMS macros intended for use on the MMS' command line are:
-# __DEBUG__=1 ! compile for debugging
-# For some discussion on the compiler switches used, see documentation
-# in 00readme.vms.
-#
-.IFDEF __ALPHA__
-E = .AXP_EXE
-O = .AXP_OBJ
-A = .AXP_OLB
-.ELSE
-.IFDEF __DECC__
-E = .VAX_DECC_EXE
-O = .VAX_DECC_OBJ
-A = .VAX_DECC_OLB
-.ENDIF
-.IFDEF __FORCE_VAXC__
-__VAXC__ = 1
-.ENDIF
-.IFDEF __VAXC__
-E = .VAX_VAXC_EXE
-O = .VAX_VAXC_OBJ
-A = .VAX_VAXC_OLB
-.ENDIF
-.IFDEF __GNUC__
-E = .VAX_GNUC_EXE
-O = .VAX_GNUC_OBJ
-A = .VAX_GNUC_OLB
-.ENDIF
-.ENDIF
-.IFDEF O
-.ELSE
-!If EXE and OBJ extensions aren't defined, define them
-E = .EXE
-O = .OBJ
-A = .OLB
-.ENDIF
+# 23 February 2007. SMS.
+#
+# Zip 3.0 for VMS - MMS (or MMK) Description File.
+#
+# Usage:
+#
+# MMS /DESCRIP = [.VMS]DESCRIP.MMS [/MACRO = (<see_below>)] [target]
+#
+# Note that this description file must be used from the main
+# distribution directory, not from the [.VMS] subdirectory.
+#
+# Optional macros:
+#
+# CCOPTS=xxx Compile with CC options xxx. For example:
+# CCOPTS=/ARCH=HOST
+#
+# DBG=1 Compile with /DEBUG /NOOPTIMIZE.
+# Link with /DEBUG /TRACEBACK.
+# (Default is /NOTRACEBACK.)
+#
+# IM=1 Use the old "IM" scheme for storing VMS/RMS file
+# atributes, instead of the newer "PK" scheme.
+#
+# IZ_BZIP2=dev:[dir] Add optional BZIP2 support. The valus of the
+# MMS macro IZ_BZIP2 ("dev:[dir]", or a suitable
+# logical name) tells where to find "bzlib.h". The
+# BZIP2 object library (LIBBZ2_NS.OLB) is expected to
+# be in a "[.dest]" directory under that one
+# ("dev:[dir.ALPHAL]", for example), or in that
+# directory itself.
+#
+# LARGE=1 Enable large-file (>2GB) support. Non-VAX only.
+#
+# LINKOPTS=xxx Link with LINK options xxx. For example:
+# LINKOPTS=/NOINFO
+#
+# LIST=1 Compile with /LIST /SHOW = (ALL, NOMESSAGES).
+# Link with /MAP /CROSS_REFERENCE /FULL.
+#
+# "LOCAL_ZIP=c_macro_1=value1 [, c_macro_2=value2 [...]]"
+# Compile with these additional C macros defined.
+#
+# VAX-specific optional macros:
+#
+# VAXC=1 Use the VAX C compiler, assuming "CC" runs it.
+# (That is, DEC C is not installed, or else DEC C is
+# installed, but VAX C is the default.)
+#
+# FORCE_VAXC=1 Use the VAX C compiler, assuming "CC /VAXC" runs it.
+# (That is, DEC C is installed, and it is the
+# default, but you want VAX C anyway, you fool.)
+#
+# GNUC=1 Use the GNU C compiler. (Seriously under-tested.)
+#
+#
+# The default target, ALL, builds the selected product executables and
+# help files.
+#
+# Other targets:
+#
+# CLEAN deletes architecture-specific files, but leaves any
+# individual source dependency files and the help files.
+#
+# CLEAN_ALL deletes all generated files, except the main (collected)
+# source dependency file.
+#
+# CLEAN_EXE deletes only the architecture-specific executables.
+# Handy if all you wish to do is re-link the executables.
+#
+# Example commands:
+#
+# To build the conventional small-file product using the DEC/Compaq/HP C
+# compiler (Note: DESCRIP.MMS is the default description file name.):
+#
+# MMS /DESCRIP = [.VMS]
+#
+# To get the large-file executables (on a non-VAX system):
+#
+# MMS /DESCRIP = [.VMS] /MACRO = (LARGE=1)
+#
+# To delete the architecture-specific generated files for this system
+# type:
+#
+# MMS /DESCRIP = [.VMS] /MACRO = (LARGE=1) CLEAN ! Large-file.
+# or
+# MMS /DESCRIP = [.VMS] CLEAN ! Small-file.
+#
+# To build a complete small-file product for debug with compiler
+# listings and link maps:
+#
+# MMS /DESCRIP = [.VMS] CLEAN
+# MMS /DESCRIP = [.VMS] /MACRO = (DBG=1, LIST=1)
+#
+########################################################################
+
+# Include primary product description file.
+
+INCL_DESCRIP_SRC = 1
+.INCLUDE [.VMS]DESCRIP_SRC.MMS
+
+# Object library names.
+
+LIB_ZIP = [.$(DEST)]ZIP.OLB
+LIB_ZIPCLI = [.$(DEST)]ZIPCLI.OLB
+LIB_ZIPUTILS = [.$(DEST)]ZIPUTILS.OLB
+
+# Help file names.
+
+ZIP_HELP = ZIP.HLP ZIP_CLI.HLP
+
+# Message file names.
+
+ZIP_MSG_MSG = [.VMS]ZIP_MSG.MSG
+ZIP_MSG_EXE = [.$(DEST)]ZIP_MSG.EXE
+ZIP_MSG_OBJ = [.$(DEST)]ZIP_MSG.OBJ
+
+
+# TARGETS.
+
+# Default target, ALL. Build All Zip executables, utility executables,
+# and help files.
+
+ALL : $(ZIP) $(ZIP_CLI) $(ZIPUTILS) $(ZIP_HELP) $(ZIP_MSG_EXE)
+ @ write sys$output "Done."
+
+# CLEAN target. Delete the [.$(DEST)] directory and everything in it.
+
+CLEAN :
+ if (f$search( "[.$(DEST)]*.*") .nes. "") then -
+ delete /noconfirm [.$(DEST)]*.*;*
+ if (f$search( "$(DEST).DIR") .nes. "") then -
+ set protection = w:d $(DEST).DIR;*
+ if (f$search( "$(DEST).DIR") .nes. "") then -
+ delete /noconfirm $(DEST).DIR;*
-!The following preprocessor macros are set to enable the VMS CLI$ interface:
-CLI_DEFS = VMSCLI,
-
-!!!!!!!!!!!!!!!!!!!!!!!!!!! USER CUSTOMIZATION !!!!!!!!!!!!!!!!!!!!!!!!!!!!
-! add any other optional preprocessor flags (macros) except VMSCLI to the
-! following line for a custom version (do not forget a trailing comma!!):
-COMMON_DEFS =
-!
-! WARNING: Do not use VMSCLI here!! The creation of a Zip executable
-! utilizing the VMS CLI$ command interface is handled differently.
-!!!!!!!!!!!!!!!!!!!!!!!! END OF USER CUSTOMIZATION !!!!!!!!!!!!!!!!!!!!!!!!
-
-.IFDEF __GNUC__
-CC = gcc
-LIBS = ,GNU_CC:[000000]GCCLIB.OLB/LIB
-.ELSE
-CC = cc
-LIBS =
-.ENDIF
+# CLEAN_ALL target. Delete:
+# The [.$(DEST)] directories and everything in them.
+# All help-related derived files,
+# All individual C dependency files.
+# Also mention:
+# Comprehensive dependency file.
-CFLAGS = /NOLIST/INCL=(SYS$DISK:[])
-
-OPTFILE = sys$disk:[.vms]vaxcshr.opt
-
-.IFDEF __ALPHA__ !Under OpenVMS AXP, we must use /PREFIX=ALL
-CFLG_ARCH = /STANDARD=RELAX/PREFIX=ALL/ANSI_ALIAS
-OPTFILE_LIST =
-OPTIONS = $(LIBS)
-.ELSE
-.IFDEF __DECC__ !Under DECC VAX, we must use /PREFIX=ALL
-CFLG_ARCH = /DECC/STANDARD=VAXC/PREFIX=ALL
-OPTFILE_LIST =
-OPTIONS = $(LIBS)
-.ELSE !VAXC, or GNU C on VAX
-.IFDEF __FORCE_VAXC__ !Select VAXC on systems where DEC C exists
-CFLG_ARCH = /VAXC
-.ELSE !No flag allowed/needed on a pure VAXC system
-CFLG_ARCH =
-.ENDIF
-OPTFILE_LIST = ,$(OPTFILE)
-OPTIONS = $(LIBS),$(OPTFILE)/OPT
-.ENDIF
-.ENDIF
+CLEAN_ALL :
+ if (f$search( "[.ALPHA*]*.*") .nes. "") then -
+ delete /noconfirm [.ALPHA*]*.*;*
+ if (f$search( "ALPHA*.DIR", 1) .nes. "") then -
+ set protection = w:d ALPHA*.DIR;*
+ if (f$search( "ALPHA*.DIR", 2) .nes. "") then -
+ delete /noconfirm ALPHA*.DIR;*
+ if (f$search( "[.IA64*]*.*") .nes. "") then -
+ delete /noconfirm [.IA64*]*.*;*
+ if (f$search( "IA64*.DIR", 1) .nes. "") then -
+ set protection = w:d IA64*.DIR;*
+ if (f$search( "IA64*.DIR", 2) .nes. "") then -
+ delete /noconfirm IA64*.DIR;*
+ if (f$search( "[.VAX*]*.*") .nes. "") then -
+ delete /noconfirm [.VAX*]*.*;*
+ if (f$search( "VAX*.DIR", 1) .nes. "") then -
+ set protection = w:d VAX*.DIR;*
+ if (f$search( "VAX*.DIR", 2) .nes. "") then -
+ delete /noconfirm VAX*.DIR;*
+ if (f$search( "[.vms]ZIP_CLI.RNH") .nes. "") then -
+ delete /noconfirm [.vms]ZIP_CLI.RNH;*
+ if (f$search( "ZIP_CLI.HLP") .nes. "") then -
+ delete /noconfirm ZIP_CLI.HLP;*
+ if (f$search( "ZIP.HLP") .nes. "") then -
+ delete /noconfirm ZIP.HLP;*
+ if (f$search( "*.MMSD") .nes. "") then -
+ delete /noconfirm *.MMSD;*
+ if (f$search( "[.vms]*.MMSD") .nes. "") then -
+ delete /noconfirm [.vms]*.MMSD;*
+ @ write sys$output ""
+ @ write sys$output "Note: This procedure will not"
+ @ write sys$output " DELETE [.VMS]DESCRIP_DEPS.MMS;*"
+ @ write sys$output -
+ "You may choose to, but a recent version of MMS (V3.5 or newer?) is"
+ @ write sys$output -
+ "needed to regenerate it. (It may also be recovered from the original"
+ @ write sys$output -
+ "distribution kit.) See [.VMS]DESCRIP_MKDEPS.MMS for instructions on"
+ @ write sys$output -
+ "generating [.VMS]DESCRIP_DEPS.MMS."
+ @ write sys$output ""
+ @ write sys$output -
+ "It also does not delete the error message source file:"
+ @ write sys$output " DELETE [.VMS]ZIP_MSG.MSG;*"
+ @ write sys$output -
+ "but it can regenerate it if needed."
+ @ write sys$output ""
-.IFDEF __DEBUG__
-CDEB = /DEBUG/NOOPTIMIZE
-LDEB = /DEBUG
-.ELSE
-CDEB =
-LDEB = /NOTRACE
-.ENDIF
+# CLEAN_EXE target. Delete the executables in [.$(DEST)].
-CFLAGS_ALL = $(CFLG_ARCH) $(CFLAGS) $(CDEB) -
- /def=($(COMMON_DEFS) VMS)
-CFLAGS_CLI = $(CFLG_ARCH) $(CFLAGS) $(CDEB) -
- /def=($(COMMON_DEFS) $(CLI_DEFS) VMS)
-CFLAGS_UTIL = $(CFLG_ARCH) $(CFLAGS) $(CDEB) -
- /def=($(COMMON_DEFS) UTIL, VMS)
+CLEAN_EXE :
+ if (f$search( "[.$(DEST)]*.EXE") .nes. "") then -
+ delete /noconfirm [.$(DEST)]*.EXE;*
-LINKFLAGS = $(LDEB)
+# Object library module dependencies.
-OBJM = zip$(O), zipcli$(O)
-OBJZ = crc32$(O), crctab$(O), crypt$(O), ttyio$(O), -
- zipfile$(O), zipup$(O), fileio$(O), globals$(O), util$(O)
-OBJV = vmszip$(O), vms$(O), vmsmunch$(O)
-OBJI = deflate$(O), trees$(O)
-OBJU = ZIPFILE=zipfile_$(O), FILEIO=fileio_$(O), globals$(O), -
- UTIL=util_$(O), VMS=vms_$(O), vmsmunch$(O)
-OBJR = crctab$(O), CRYPT=crypt_$(O), ttyio$(O)
-OBJC = zipcloak$(O)
-OBJN = zipnote$(O)
-OBJS = zipsplit$(O)
+$(LIB_ZIP) : $(LIB_ZIP)($(MODS_OBJS_LIB_ZIP))
+ @ write sys$output "$(MMS$TARGET) updated."
-ZIPX_UNX = zip
-ZIPX_CLI = zip_cli
-OBJSZIPLIB = $(OBJZ), $(OBJI), $(OBJV)
-OBJSZIP = zip$(O), $(OBJSZIPLIB)
-OBJSCLI = ZIP=zipcli$(O), -
- ZIP_CLITABLE=zip_cli$(O), VMS_ZIP_CMDLINE=cmdline$(O)
-ZIPHELP_UNX_RNH = [.vms]vms_zip.rnh
-ZIPHELP_CLI_RNH = [.vms]zip_cli.rnh
+$(LIB_ZIPCLI) : $(LIB_ZIPCLI)($(MODS_OBJS_LIB_ZIPCLI))
+ @ write sys$output "$(MMS$TARGET) updated."
-OLBZIP = zip$(A)
-OLBCLI = zipcli$(A)
-OLBUTI = ziputils$(A)
+$(LIB_ZIPUTILS) : $(LIB_ZIPUTILS)($(MODS_OBJS_LIB_ZIPUTILS))
+ @ write sys$output "$(MMS$TARGET) updated."
-ZIP_H = zip.h,ziperr.h,tailor.h,[.vms]osdep.h
+# Module ID options file.
-ZIPS = $(ZIPX_UNX)$(E), $(ZIPX_CLI)$(E),-
- zipcloak$(E), zipnote$(E), zipsplit$(E)
-ZIPHELPS = $(ZIPX_UNX).hlp, $(ZIPX_CLI).hlp
+OPT_ID = SYS$DISK:[.VMS]ZIP.OPT
-#
-# Define our new suffixes list
-#
-.SUFFIXES :
-.SUFFIXES : $(E) $(A) $(O) .C .MAR .CLD .HLP .RNH
+# Default C compile rule.
+
+.C.OBJ :
+ $(CC) $(CFLAGS) $(CDEFS_UNX) $(MMS$SOURCE)
+
+
+# Normal sources in [.VMS].
+
+[.$(DEST)]VMS.OBJ : [.VMS]VMS.C
+[.$(DEST)]VMSMUNCH.OBJ : [.VMS]VMSMUNCH.C
+[.$(DEST)]VMSZIP.OBJ : [.VMS]VMSZIP.C
+
+# Command-line interface files.
+
+[.$(DEST)]CMDLINE.OBJ : [.VMS]CMDLINE.C
+ $(CC) $(CFLAGS) $(CDEFS_CLI) $(MMS$SOURCE)
+
+[.$(DEST)]ZIPCLI.OBJ : ZIP.C
+ $(CC) $(CFLAGS) $(CDEFS_CLI) $(MMS$SOURCE)
+
+[.$(DEST)]ZIP_CLI.OBJ : [.VMS]ZIP_CLI.CLD
+
+# Utility variant sources.
+
+[.$(DEST)]CRC32_.OBJ : CRC32.C
+ $(CC) $(CFLAGS) $(CDEFS_UTIL) $(MMS$SOURCE)
+
+[.$(DEST)]CRYPT_.OBJ : CRYPT.C
+ $(CC) $(CFLAGS) $(CDEFS_UTIL) $(MMS$SOURCE)
+
+[.$(DEST)]FILEIO_.OBJ : FILEIO.C
+ $(CC) $(CFLAGS) $(CDEFS_UTIL) $(MMS$SOURCE)
+
+[.$(DEST)]UTIL_.OBJ : UTIL.C
+ $(CC) $(CFLAGS) $(CDEFS_UTIL) $(MMS$SOURCE)
-$(O)$(E) :
- $(LINK) $(LINKFLAGS) /EXE=$(MMS$TARGET) $(MMS$SOURCE)
+[.$(DEST)]ZIPFILE_.OBJ : ZIPFILE.C
+ $(CC) $(CFLAGS) $(CDEFS_UTIL) $(MMS$SOURCE)
-$(O)$(A) :
- If "''F$Search("$(MMS$TARGET)")'" .EQS. "" Then $(LIBR)/Create $(MMS$TARGET)
- $(LIBR)$(LIBRFLAGS) $(MMS$TARGET) $(MMS$SOURCE)
+[.$(DEST)]VMS_.OBJ : [.VMS]VMS.C
+ $(CC) $(CFLAGS) $(CDEFS_UTIL) $(MMS$SOURCE)
-.CLD$(O) :
- SET COMMAND /OBJECT=$(MMS$TARGET) $(CLDFLAGS) $(MMS$SOURCE)
+# Utility main sources.
+
+[.$(DEST)]ZIPCLOAK.OBJ : ZIPCLOAK.C
+ $(CC) $(CFLAGS) $(CDEFS_UTIL) $(MMS$SOURCE)
+
+[.$(DEST)]ZIPNOTE.OBJ : ZIPNOTE.C
+ $(CC) $(CFLAGS) $(CDEFS_UTIL) $(MMS$SOURCE)
+
+[.$(DEST)]ZIPSPLIT.OBJ : ZIPSPLIT.C
+ $(CC) $(CFLAGS) $(CDEFS_UTIL) $(MMS$SOURCE)
+
+# VAX C LINK options file.
+
+.IFDEF OPT_FILE
+$(OPT_FILE) :
+ open /write opt_file_ln $(OPT_FILE)
+ write opt_file_ln "SYS$SHARE:VAXCRTL.EXE /SHARE"
+ close opt_file_ln
+.ENDIF
-.c$(O) :
- $(CC) $(CFLAGS_ALL) /OBJ=$(MMS$TARGET) $(MMS$SOURCE)
+# Normal Zip executable.
+
+$(ZIP) : [.$(DEST)]ZIP.OBJ $(LIB_ZIP) $(OPT_FILE)
+ $(LINK) $(LINKFLAGS) $(MMS$SOURCE), -
+ $(LIB_ZIP) /include = (GLOBALS $(INCL_BZIP2_M)) /library, -
+ $(LIB_BZIP2_OPTS) -
+ $(LFLAGS_ARCH) -
+ $(OPT_ID) /options
+
+# CLI Zip executable.
+
+$(ZIP_CLI) : [.$(DEST)]ZIPCLI.OBJ \
+ $(LIB_ZIPCLI) $(OPT_ID) $(OPT_FILE)
+ $(LINK) $(LINKFLAGS) $(MMS$SOURCE), -
+ $(LIB_ZIPCLI) /library, -
+ $(LIB_ZIP) /include = (GLOBALS $(INCL_BZIP2_M)) /library, -
+ $(LIB_BZIP2_OPTS) -
+ $(LFLAGS_ARCH) -
+ $(OPT_ID) /options
+
+# Utility executables.
+
+[.$(DEST)]ZIPCLOAK.EXE : [.$(DEST)]ZIPCLOAK.OBJ \
+ $(LIB_ZIPUTILS) \
+ $(OPT_ID) $(OPT_FILE)
+ $(LINK) $(LINKFLAGS) $(MMS$SOURCE), -
+ $(LIB_ZIPUTILS) /include = (GLOBALS) /library, -
+ $(LFLAGS_ARCH) -
+ $(OPT_ID) /options
+
+[.$(DEST)]ZIPNOTE.EXE : [.$(DEST)]ZIPNOTE.OBJ \
+ $(LIB_ZIPUTILS) \
+ $(OPT_ID) $(OPT_FILE)
+ $(LINK) $(LINKFLAGS) $(MMS$SOURCE), -
+ $(LIB_ZIPUTILS) /include = (GLOBALS) /library, -
+ $(LFLAGS_ARCH) -
+ $(OPT_ID) /options
+
+[.$(DEST)]ZIPSPLIT.EXE : [.$(DEST)]ZIPSPLIT.OBJ \
+ $(LIB_ZIPUTILS) \
+ $(OPT_ID) $(OPT_FILE)
+ $(LINK) $(LINKFLAGS) $(MMS$SOURCE), -
+ $(LIB_ZIPUTILS) /include = (GLOBALS) /library, -
+ $(LFLAGS_ARCH) -
+ $(OPT_ID) /options
+
+# Help files.
+
+ZIP.HLP : [.VMS]VMS_ZIP.RNH
+ runoff /output = $(MMS$TARGET) $(MMS$SOURCE)
+
+ZIP_CLI.HLP : [.VMS]ZIP_CLI.HELP [.VMS]CVTHELP.TPU
+ edit := edit
+ edit /tpu /nosection /nodisplay /command = [.VMS]CVTHELP.TPU -
+ $(MMS$SOURCE)
+ rename /noconfirm ZIP_CLI.RNH; [.VMS];
+ purge /noconfirm /nolog /keep = 1 [.VMS]ZIP_CLI.RNH
+ runoff /output = $(MMS$TARGET) [.VMS]ZIP_CLI.RNH
+
+# Message file.
+
+$(ZIP_MSG_EXE) : $(ZIP_MSG_OBJ)
+ link /shareable = $(MMS$TARGET) $(ZIP_MSG_OBJ)
+
+$(ZIP_MSG_OBJ) : $(ZIP_MSG_MSG)
+ message /object = $(MMS$TARGET) /nosymbols $(ZIP_MSG_MSG)
+
+$(ZIP_MSG_MSG) : ZIPERR.H [.VMS]STREAM_LF.FDL [.VMS]VMS_MSG_GEN.C
+ $(CC) /include = [] /object = [.$(DEST)]VMS_MSG_GEN.OBJ -
+ [.VMS]VMS_MSG_GEN.C
+ $(LINK) /executable = [.$(DEST)]VMS_MSG_GEN.EXE -
+ $(LFLAGS_ARCH) -
+ [.$(DEST)]VMS_MSG_GEN.OBJ
+ create /fdl = [.VMS]STREAM_LF.FDL $(MMS$TARGET)
+ define /user_mode sys$output $(MMS$TARGET)
+ run [.$(DEST)]VMS_MSG_GEN.EXE
+ purge $(MMS$TARGET)
+ delete [.$(DEST)]VMS_MSG_GEN.EXE;*, [.$(DEST)]VMS_MSG_GEN.OBJ;*
+
+# Include generated source dependencies.
+
+INCL_DESCRIP_DEPS = 1
+.INCLUDE [.VMS]DESCRIP_DEPS.MMS
-.RNH.HLP :
- runoff /out=$@ $<
-
-
-# rules for zip, zipnote, zipsplit, and VMS online help file.
-
-default : $(ZIPS), $(ZIPHELPS)
- @ !
-
-vmszip$(O) : [.vms]vmszip.c
-vmsmunch$(O) : [.vms]vmsmunch.c
-vms$(O) : [.vms]vms.c [.vms]vms_im.c [.vms]vms_pk.c [.vms]vms.h
-zipcli$(O) : zip.c
- $(CC) $(CFLAGS_CLI) /OBJ=$(MMS$TARGET) $<
-cmdline$(O) : [.vms]cmdline.c $(ZIP_H) crypt.h revision.h
- $(CC) $(CFLAGS_CLI) /OBJ=$(MMS$TARGET) $<
-zip_cli$(O) : [.vms]zip_cli.cld
-
-
-zipfile_$(O) : zipfile.c,[.vms]vmsmunch.h,[.vms]vmsdefs.h
- $(CC) $(CFLAGS_UTIL) /OBJECT=$(MMS$TARGET) $<
-fileio_$(O) : fileio.c
- $(CC) $(CFLAGS_UTIL) /OBJECT=$(MMS$TARGET) $<
-util_$(O) : util.c
- $(CC) $(CFLAGS_UTIL) /OBJECT=$(MMS$TARGET) $<
-crypt_$(O) : crypt.c,crypt.h,ttyio.h
- $(CC) $(CFLAGS_UTIL) /OBJECT=$(MMS$TARGET) $<
-vms_$(O) : [.vms]vms.c,[.vms]vms_im.c,[.vms]vms_pk.c, -
- [.vms]vms.h,[.vms]vmsdefs.h
- $(CC) $(CFLAGS_UTIL) /OBJECT=$(MMS$TARGET) $<
-
-$(OBJM),zipcloak$(O),zipnote$(O),zipsplit$(O),zipup$(O) : revision.h
-
-$(OBJM),zipcloak$(O),zipup$(O),crypt$(O),ttyio$(O) : crypt.h
-
-$(OBJM),zipcloak$(O),crypt$(O),ttyio$(O) : ttyio.h
-
-zipup$(O) : [.vms]zipup.h
-
-$(OBJM), zipfile$(O), vmszip$(O), vmsmunch$(O) : [.vms]vmsmunch.h
-
-zipfile$(O), vms$(O), vmsmunch$(O) : [.vms]vmsdefs.h
-
-$(OBJM) : $(ZIP_H)
-$(OBJZ) : $(ZIP_H)
-$(OBJV) : $(ZIP_H)
-$(OBJI) : $(ZIP_H)
-$(OBJU) : $(ZIP_H)
-$(OBJR) : $(ZIP_H)
-$(OBJC) : $(ZIP_H)
-$(OBJN) : $(ZIP_H)
-$(OBJS) : $(ZIP_H)
-
-
-$(ZIPX_UNX)$(E) : $(OLBZIP)($(OBJSZIP))$(OPTFILE_LIST)
- $(LINK)$(LINKFLAGS) /EXE=$@ -
- $(OLBZIP)/inc=(zip,globals)/lib$(OPTIONS)
-
-$(ZIPX_CLI)$(E) : $(OLBCLI)($(OBJSCLI)),$(OLBZIP)($(OBJSZIPLIB))$(OPTFILE_LIST)
- $(LINK)$(LINKFLAGS) /EXE=$@ -
- $(OLBCLI)/inc=(zip)/lib, $(OLBZIP)/inc=(globals)/lib$(OPTIONS)
-
-zipcloak$(E) : $(OBJC),$(OLBUTI)($(OBJR),$(OBJU))$(OPTFILE_LIST)
- $(LINK)$(LINKFLAGS) /EXE=$@ $<, -
- $(OLBUTI)/inc=(globals)/lib$(OPTIONS)
-
-zipnote$(E) : $(OBJN),$(OLBUTI)($(OBJU))$(OPTFILE_LIST)
- $(LINK)$(LINKFLAGS) /EXE=$@ $<, -
- $(OLBUTI)/inc=(globals)/lib$(OPTIONS)
-
-zipsplit$(E) : $(OBJS),$(OLBUTI)($(OBJU))$(OPTFILE_LIST)
- $(LINK)$(LINKFLAGS) /EXE=$@ $<, -
- $(OLBUTI)/inc=(globals)/lib$(OPTIONS)
-
-$(OPTFILE) :
- @ open/write tmp $(OPTFILE)
- @ write tmp "SYS$SHARE:VAXCRTL.EXE/SHARE"
- @ close tmp
-
-$(ZIPHELP_CLI_RNH) : [.vms]zip_cli.help
- @ set default [.vms]
- edit/tpu/nosection/nodisplay/command=cvthelp.tpu zip_cli.help
- @ set default [-]
-
-$(ZIPX_UNX).hlp : $(ZIPHELP_UNX_RNH)
- runoff /out=$@ $<
-
-$(ZIPX_CLI).hlp : $(ZIPHELP_CLI_RNH)
-
-clean.com :
- @ open/write tmp $(MMS$TARGET)
- @ write tmp "$!"
- @ write tmp "$! Clean.com -- procedure to delete files. It always returns success"
- @ write tmp "$! status despite any error or warnings. Also it extracts"
- @ write tmp "$! filename from MMS ""module=file"" format."
- @ write tmp "$!"
- @ write tmp "$ on control_y then goto ctly"
- @ write tmp "$ if p1.eqs."""" then exit 1"
- @ write tmp "$ i = -1"
- @ write tmp "$scan_list:"
- @ write tmp "$ i = i+1"
- @ write tmp "$ item = f$elem(i,"","",p1)"
- @ write tmp "$ if item.eqs."""" then goto scan_list"
- @ write tmp "$ if item.eqs."","" then goto done ! End of list"
- @ write tmp "$ item = f$edit(item,""trim"") ! Clean of blanks"
- @ write tmp "$ wild = f$elem(1,""="",item)"
- @ write tmp "$ show sym wild"
- @ write tmp "$ if wild.eqs.""="" then wild = f$elem(0,""="",item)"
- @ write tmp "$ vers = f$parse(wild,,,""version"",""syntax_only"")"
- @ write tmp "$ if vers.eqs."";"" then wild = wild - "";"" + "";*"""
- @ write tmp "$scan:"
- @ write tmp "$ f = f$search(wild)"
- @ write tmp "$ if f.eqs."""" then goto scan_list"
- @ write tmp "$ on error then goto err"
- @ write tmp "$ on warning then goto warn"
- @ write tmp "$ delete/log 'f'"
- @ write tmp "$warn:"
- @ write tmp "$err:"
- @ write tmp "$ goto scan"
- @ write tmp "$done:"
- @ write tmp "$ctly:"
- @ write tmp "$ exit 1"
- @ close tmp
-
-clean : clean.com
- @clean "$(OBJM)"
- @clean "$(OBJZ)"
- @clean "$(OBJI)"
- @clean "$(OBJV)"
- @clean "$(OBJU)"
- @clean "$(OBJR)"
- @clean "$(OBJN)"
- @clean "$(OBJS)"
- @clean "$(OBJC)"
- @clean "$(OBJSCLI)"
- @clean "$(OLBZIP)"
- @clean "$(OLBCLI)"
- @clean "$(OLBUTI)"
- @clean "$(OPTFILE)"
- @clean "$(ZIPS)"
- @clean "$(ZIPHELP_CLI_RNH)"
- @clean "$(ZIPHELPS)"
- - delete/noconfirm/nolog clean.com;*
diff --git a/vms/descrip_deps.mms b/vms/descrip_deps.mms
new file mode 100644
index 0000000..cf8f9b1
--- /dev/null
+++ b/vms/descrip_deps.mms
@@ -0,0 +1,207 @@
+#
+# Zip for VMS - MMS (or MMK) Source Dependency File.
+#
+
+# This description file is included by other description files. It is
+# not intended to be used alone. Verify proper inclusion.
+
+.IFDEF INCL_DESCRIP_DEPS
+.ELSE
+$$$$ THIS DESCRIPTION FILE IS NOT INTENDED TO BE USED THIS WAY.
+.ENDIF
+
+[.$(DEST)]CRC32.OBJ : []CRC32.C
+[.$(DEST)]CRC32.OBJ : []ZIP.H
+[.$(DEST)]CRC32.OBJ : []TAILOR.H
+[.$(DEST)]CRC32.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]CRC32.OBJ : []ZIPERR.H
+[.$(DEST)]CRC32.OBJ : []CRC32.H
+[.$(DEST)]CRC32_.OBJ : []CRC32.C
+[.$(DEST)]CRC32_.OBJ : []ZIP.H
+[.$(DEST)]CRC32_.OBJ : []TAILOR.H
+[.$(DEST)]CRC32_.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]CRC32_.OBJ : []ZIPERR.H
+[.$(DEST)]CRC32_.OBJ : []CRC32.H
+[.$(DEST)]CRYPT.OBJ : []CRYPT.C
+[.$(DEST)]CRYPT.OBJ : []ZIP.H
+[.$(DEST)]CRYPT.OBJ : []TAILOR.H
+[.$(DEST)]CRYPT.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]CRYPT.OBJ : []ZIPERR.H
+[.$(DEST)]CRYPT.OBJ : []CRYPT.H
+[.$(DEST)]CRYPT.OBJ : []TTYIO.H
+[.$(DEST)]CRYPT.OBJ : []CRC32.H
+[.$(DEST)]CRYPT_.OBJ : []CRYPT.C
+[.$(DEST)]CRYPT_.OBJ : []ZIP.H
+[.$(DEST)]CRYPT_.OBJ : []TAILOR.H
+[.$(DEST)]CRYPT_.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]CRYPT_.OBJ : []ZIPERR.H
+[.$(DEST)]CRYPT_.OBJ : []CRYPT.H
+[.$(DEST)]CRYPT_.OBJ : []TTYIO.H
+[.$(DEST)]CRYPT_.OBJ : []CRC32.H
+[.$(DEST)]DEFLATE.OBJ : []DEFLATE.C
+[.$(DEST)]DEFLATE.OBJ : []ZIP.H
+[.$(DEST)]DEFLATE.OBJ : []TAILOR.H
+[.$(DEST)]DEFLATE.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]DEFLATE.OBJ : []ZIPERR.H
+[.$(DEST)]FILEIO.OBJ : []FILEIO.C
+[.$(DEST)]FILEIO.OBJ : []ZIP.H
+[.$(DEST)]FILEIO.OBJ : []TAILOR.H
+[.$(DEST)]FILEIO.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]FILEIO.OBJ : []ZIPERR.H
+[.$(DEST)]FILEIO.OBJ : []CRC32.H
+[.$(DEST)]FILEIO.OBJ : [.VMS]VMS.H
+[.$(DEST)]FILEIO_.OBJ : []FILEIO.C
+[.$(DEST)]FILEIO_.OBJ : []ZIP.H
+[.$(DEST)]FILEIO_.OBJ : []TAILOR.H
+[.$(DEST)]FILEIO_.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]FILEIO_.OBJ : []ZIPERR.H
+[.$(DEST)]FILEIO_.OBJ : []CRC32.H
+[.$(DEST)]FILEIO_.OBJ : [.VMS]VMS.H
+[.$(DEST)]GLOBALS.OBJ : []GLOBALS.C
+[.$(DEST)]GLOBALS.OBJ : []ZIP.H
+[.$(DEST)]GLOBALS.OBJ : []TAILOR.H
+[.$(DEST)]GLOBALS.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]GLOBALS.OBJ : []ZIPERR.H
+[.$(DEST)]TREES.OBJ : []TREES.C
+[.$(DEST)]TREES.OBJ : []ZIP.H
+[.$(DEST)]TREES.OBJ : []TAILOR.H
+[.$(DEST)]TREES.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]TREES.OBJ : []ZIPERR.H
+[.$(DEST)]TTYIO.OBJ : []TTYIO.C
+[.$(DEST)]TTYIO.OBJ : []ZIP.H
+[.$(DEST)]TTYIO.OBJ : []TAILOR.H
+[.$(DEST)]TTYIO.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]TTYIO.OBJ : []ZIPERR.H
+[.$(DEST)]TTYIO.OBJ : []CRYPT.H
+[.$(DEST)]TTYIO.OBJ : []TTYIO.H
+[.$(DEST)]UTIL.OBJ : []UTIL.C
+[.$(DEST)]UTIL.OBJ : []ZIP.H
+[.$(DEST)]UTIL.OBJ : []TAILOR.H
+[.$(DEST)]UTIL.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]UTIL.OBJ : []ZIPERR.H
+[.$(DEST)]UTIL.OBJ : []EBCDIC.H
+[.$(DEST)]UTIL_.OBJ : []UTIL.C
+[.$(DEST)]UTIL_.OBJ : []ZIP.H
+[.$(DEST)]UTIL_.OBJ : []TAILOR.H
+[.$(DEST)]UTIL_.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]UTIL_.OBJ : []ZIPERR.H
+[.$(DEST)]UTIL_.OBJ : []EBCDIC.H
+[.$(DEST)]ZBZ2ERR.OBJ : []ZBZ2ERR.C
+[.$(DEST)]ZBZ2ERR.OBJ : []ZIP.H
+[.$(DEST)]ZBZ2ERR.OBJ : []TAILOR.H
+[.$(DEST)]ZBZ2ERR.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]ZBZ2ERR.OBJ : []ZIPERR.H
+[.$(DEST)]ZIP.OBJ : []ZIP.C
+[.$(DEST)]ZIP.OBJ : []ZIP.H
+[.$(DEST)]ZIP.OBJ : []TAILOR.H
+[.$(DEST)]ZIP.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]ZIP.OBJ : []ZIPERR.H
+[.$(DEST)]ZIP.OBJ : []REVISION.H
+[.$(DEST)]ZIP.OBJ : []CRC32.H
+[.$(DEST)]ZIP.OBJ : []CRYPT.H
+[.$(DEST)]ZIP.OBJ : []TTYIO.H
+[.$(DEST)]ZIP.OBJ : [.VMS]VMSMUNCH.H
+[.$(DEST)]ZIP.OBJ : [.VMS]VMS.H
+[.$(DEST)]ZIPCLI.OBJ : []ZIP.C
+[.$(DEST)]ZIPCLI.OBJ : []ZIP.H
+[.$(DEST)]ZIPCLI.OBJ : []TAILOR.H
+[.$(DEST)]ZIPCLI.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]ZIPCLI.OBJ : []ZIPERR.H
+[.$(DEST)]ZIPCLI.OBJ : []REVISION.H
+[.$(DEST)]ZIPCLI.OBJ : []CRC32.H
+[.$(DEST)]ZIPCLI.OBJ : []CRYPT.H
+[.$(DEST)]ZIPCLI.OBJ : []TTYIO.H
+[.$(DEST)]ZIPCLI.OBJ : [.VMS]VMSMUNCH.H
+[.$(DEST)]ZIPCLI.OBJ : [.VMS]VMS.H
+[.$(DEST)]ZIPCLOAK.OBJ : []ZIPCLOAK.C
+[.$(DEST)]ZIPCLOAK.OBJ : []ZIP.H
+[.$(DEST)]ZIPCLOAK.OBJ : []TAILOR.H
+[.$(DEST)]ZIPCLOAK.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]ZIPCLOAK.OBJ : []ZIPERR.H
+[.$(DEST)]ZIPCLOAK.OBJ : []REVISION.H
+[.$(DEST)]ZIPCLOAK.OBJ : []CRC32.H
+[.$(DEST)]ZIPCLOAK.OBJ : []CRYPT.H
+[.$(DEST)]ZIPCLOAK.OBJ : []TTYIO.H
+[.$(DEST)]ZIPFILE.OBJ : []ZIPFILE.C
+[.$(DEST)]ZIPFILE.OBJ : []ZIP.H
+[.$(DEST)]ZIPFILE.OBJ : []TAILOR.H
+[.$(DEST)]ZIPFILE.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]ZIPFILE.OBJ : []ZIPERR.H
+[.$(DEST)]ZIPFILE.OBJ : []REVISION.H
+[.$(DEST)]ZIPFILE.OBJ : [.VMS]VMS.H
+[.$(DEST)]ZIPFILE.OBJ : [.VMS]VMSMUNCH.H
+[.$(DEST)]ZIPFILE.OBJ : [.VMS]VMSDEFS.H
+[.$(DEST)]ZIPFILE_.OBJ : []ZIPFILE.C
+[.$(DEST)]ZIPFILE_.OBJ : []ZIP.H
+[.$(DEST)]ZIPFILE_.OBJ : []TAILOR.H
+[.$(DEST)]ZIPFILE_.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]ZIPFILE_.OBJ : []ZIPERR.H
+[.$(DEST)]ZIPFILE_.OBJ : []REVISION.H
+[.$(DEST)]ZIPFILE_.OBJ : [.VMS]VMS.H
+[.$(DEST)]ZIPFILE_.OBJ : [.VMS]VMSMUNCH.H
+[.$(DEST)]ZIPFILE_.OBJ : [.VMS]VMSDEFS.H
+[.$(DEST)]ZIPNOTE.OBJ : []ZIPNOTE.C
+[.$(DEST)]ZIPNOTE.OBJ : []ZIP.H
+[.$(DEST)]ZIPNOTE.OBJ : []TAILOR.H
+[.$(DEST)]ZIPNOTE.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]ZIPNOTE.OBJ : []ZIPERR.H
+[.$(DEST)]ZIPNOTE.OBJ : []REVISION.H
+[.$(DEST)]ZIPSPLIT.OBJ : []ZIPSPLIT.C
+[.$(DEST)]ZIPSPLIT.OBJ : []ZIP.H
+[.$(DEST)]ZIPSPLIT.OBJ : []TAILOR.H
+[.$(DEST)]ZIPSPLIT.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]ZIPSPLIT.OBJ : []ZIPERR.H
+[.$(DEST)]ZIPSPLIT.OBJ : []REVISION.H
+[.$(DEST)]ZIPUP.OBJ : []ZIPUP.C
+[.$(DEST)]ZIPUP.OBJ : []ZIP.H
+[.$(DEST)]ZIPUP.OBJ : []TAILOR.H
+[.$(DEST)]ZIPUP.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]ZIPUP.OBJ : []ZIPERR.H
+[.$(DEST)]ZIPUP.OBJ : []REVISION.H
+[.$(DEST)]ZIPUP.OBJ : []CRC32.H
+[.$(DEST)]ZIPUP.OBJ : []CRYPT.H
+[.$(DEST)]ZIPUP.OBJ : [.VMS]ZIPUP.H
+[.$(DEST)]CMDLINE.OBJ : [.VMS]CMDLINE.C
+[.$(DEST)]CMDLINE.OBJ : []ZIP.H
+[.$(DEST)]CMDLINE.OBJ : []TAILOR.H
+[.$(DEST)]CMDLINE.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]CMDLINE.OBJ : []ZIPERR.H
+[.$(DEST)]CMDLINE.OBJ : []CRYPT.H
+[.$(DEST)]CMDLINE.OBJ : []REVISION.H
+[.$(DEST)]VMS.OBJ : [.VMS]VMS.C
+[.$(DEST)]VMS.OBJ : []ZIP.H
+[.$(DEST)]VMS.OBJ : []TAILOR.H
+[.$(DEST)]VMS.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]VMS.OBJ : []ZIPERR.H
+[.$(DEST)]VMS.OBJ : [.VMS]ZIPUP.H
+[.$(DEST)]VMS.OBJ : [.VMS]VMS_PK.C
+[.$(DEST)]VMS.OBJ : []CRC32.H
+[.$(DEST)]VMS.OBJ : [.VMS]VMS.H
+[.$(DEST)]VMS.OBJ : [.VMS]VMSDEFS.H
+[.$(DEST)]VMS.OBJ : [.VMS]VMS_IM.C
+[.$(DEST)]VMSMUNCH.OBJ : [.VMS]VMSMUNCH.C
+[.$(DEST)]VMSMUNCH.OBJ : []ZIP.H
+[.$(DEST)]VMSMUNCH.OBJ : []TAILOR.H
+[.$(DEST)]VMSMUNCH.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]VMSMUNCH.OBJ : []ZIPERR.H
+[.$(DEST)]VMSMUNCH.OBJ : [.VMS]VMS.H
+[.$(DEST)]VMSMUNCH.OBJ : [.VMS]VMSMUNCH.H
+[.$(DEST)]VMSMUNCH.OBJ : [.VMS]VMSDEFS.H
+[.$(DEST)]VMSZIP.OBJ : [.VMS]VMSZIP.C
+[.$(DEST)]VMSZIP.OBJ : []ZIP.H
+[.$(DEST)]VMSZIP.OBJ : []TAILOR.H
+[.$(DEST)]VMSZIP.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]VMSZIP.OBJ : []ZIPERR.H
+[.$(DEST)]VMSZIP.OBJ : [.VMS]VMSMUNCH.H
+[.$(DEST)]VMSZIP.OBJ : [.VMS]VMS.H
+[.$(DEST)]VMS_.OBJ : [.VMS]VMS.C
+[.$(DEST)]VMS_.OBJ : []ZIP.H
+[.$(DEST)]VMS_.OBJ : []TAILOR.H
+[.$(DEST)]VMS_.OBJ : [.VMS]OSDEP.H
+[.$(DEST)]VMS_.OBJ : []ZIPERR.H
+[.$(DEST)]VMS_.OBJ : [.VMS]ZIPUP.H
+[.$(DEST)]VMS_.OBJ : [.VMS]VMS_PK.C
+[.$(DEST)]VMS_.OBJ : []CRC32.H
+[.$(DEST)]VMS_.OBJ : [.VMS]VMS.H
+[.$(DEST)]VMS_.OBJ : [.VMS]VMSDEFS.H
+[.$(DEST)]VMS_.OBJ : [.VMS]VMS_IM.C
diff --git a/vms/descrip_mkdeps.mms b/vms/descrip_mkdeps.mms
new file mode 100644
index 0000000..9bf5add
--- /dev/null
+++ b/vms/descrip_mkdeps.mms
@@ -0,0 +1,247 @@
+# 1 February 2008. SMS.
+#
+# Zip 3.0 for VMS - MMS Dependency Description File.
+#
+# MMS /EXTENDED_SYNTAX description file to generate a C source
+# dependencies file. Unsightly errors result when /EXTENDED_SYNTAX
+# is not specified. Typical usage:
+#
+# $ MMS /EXTEND /DESCRIP = [.VMS]DESCRIP_MKDEPS.MMS /SKIP
+#
+# Note that this description file must be used from the main
+# distribution directory, not from the [.VMS] subdirectory.
+#
+# This description file uses these command procedures:
+#
+# [.VMS]MOD_DEP.COM
+# [.VMS]COLLECT_DEPS.COM
+#
+# MMK users without MMS will be unable to generate the dependencies file
+# using this description file, however there should be one supplied in
+# the kit. If this file has been deleted, users in this predicament
+# will need to recover it from the original distribution kit.
+#
+# Note: This dependency generation scheme assumes that the dependencies
+# do not depend on host architecture type or other such variables.
+# Therefore, no "#include" directive in the C source itself should be
+# conditional on such variables.
+#
+# The default target is the comprehensive source dependency file,
+# DEPS_FILE = [.VMS]DESCRIP_DEPS.MMS.
+#
+# Other targets:
+#
+# CLEAN deletes the individual source dependency files,
+# *.MMSD;*, but leaves the comprehensive source dependency
+# file.
+#
+# CLEAN_ALL deletes all source dependency files, including the
+# individual *.MMSD;* files and the comprehensive file,
+# DESCRIP_DEPS.MMS.*.
+#
+
+# Required command procedures.
+
+COMS = [.VMS]MOD_DEP.COM [.VMS]COLLECT_DEPS.COM
+
+# Include the source file lists (among other data).
+
+INCL_DESCRIP_SRC = 1
+.INCLUDE [.VMS]DESCRIP_SRC.MMS
+
+# The ultimate product, a comprehensive dependency list.
+
+DEPS_FILE = [.VMS]DESCRIP_DEPS.MMS
+
+# Detect valid qualifier and/or macro options.
+
+.IF $(FINDSTRING Skip, $(MMSQUALIFIERS)) .eq Skip
+DELETE_MMSD = 1
+.ELSIF NOSKIP
+PURGE_MMSD = 1
+.ELSE
+UNK_MMSD = 1
+.ENDIF
+
+# Dependency suffixes and rules.
+#
+# .FIRST is assumed to be used already, so the MMS qualifier/macro check
+# is included in each rule (one way or another).
+
+.SUFFIXES_BEFORE .C .MMSD
+
+.C.MMSD :
+.IF UNK_MMSD
+ @ write sys$output -
+ " /SKIP_INTERMEDIATES is expected on the MMS command line."
+ @ write sys$output -
+ " For normal behavior (delete .MMSD files), specify ""/SKIP""."
+ @ write sys$output -
+ " To retain the .MMSD files, specify ""/MACRO = NOSKIP=1""."
+ @ exit %x00000004
+.ENDIF
+ $(CC) $(CFLAGS_INCL) $(MMS$SOURCE) /NOLIST /NOOBJECT -
+ /MMS_DEPENDENCIES = (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES)
+
+# List of MMS dependency files.
+
+# In case it's not obvious...
+# To extract module name lists from object library module=object lists:
+# 1. Transform "module=[.dest]name.OBJ" into "module=[.dest] name".
+# 2. For [.VMS], add [.VMS] to name.
+# 3. Delete "*]" words.
+#
+# A similar scheme works for executable lists.
+
+MODS_LIB_ZIP_N = $(FILTER-OUT *], \
+ $(PATSUBST *]*.OBJ, *] *, $(MODS_OBJS_LIB_ZIP_N)))
+
+MODS_LIB_ZIP_V = $(FILTER-OUT *], \
+ $(PATSUBST *]*.OBJ, *] [.VMS]*, $(MODS_OBJS_LIB_ZIP_V)))
+
+MODS_LIB_ZIPUTILS_N = $(FILTER-OUT *], \
+ $(PATSUBST *]*.OBJ, *] *, $(MODS_OBJS_LIB_ZIPUTILS_N)))
+
+MODS_LIB_ZIPUTILS_N_V = $(FILTER-OUT *], \
+ $(PATSUBST *]*.OBJ, *] [.VMS]*, $(MODS_OBJS_LIB_ZIPUTILS_N_V)))
+
+MODS_LIB_ZIPUTILS_U = $(FILTER-OUT *], \
+ $(PATSUBST *]*.OBJ, *] *, $(MODS_OBJS_LIB_ZIPUTILS_U)))
+
+MODS_LIB_ZIPUTILS_U_V = $(FILTER-OUT *], \
+ $(PATSUBST *]*.OBJ, *] [.VMS]*, $(MODS_OBJS_LIB_ZIPUTILS_U_V)))
+
+MODS_LIB_ZIPCLI_V = $(FILTER-OUT *], \
+ $(PATSUBST *]*.OBJ, *] [.VMS]*, $(MODS_OBJS_LIB_ZIPCLI_C_V)))
+
+MODS_ZIP = $(FILTER-OUT *], \
+ $(PATSUBST *]*.EXE, *] *, $(ZIP)))
+
+MODS_ZIPUTILS = $(FILTER-OUT *], \
+ $(PATSUBST *]*.EXE, *] *, $(ZIPUTILS)))
+
+# Complete list of C object dependency file names.
+# Note that the CLI Zip main program object file is a special case.
+
+DEPS = $(FOREACH NAME, \
+ $(MODS_LIB_ZIP_N) $(MODS_LIB_ZIP_V) \
+ $(MODS_ZIPUTILS_N) $(MODS_ZIPUTILS_N_V) \
+ $(MODS_LIB_ZIPUTILS_U) $(MODS_LIB_ZIPUTILS_U_V) \
+ $(MODS_LIB_ZIPCLI_V) \
+ $(MODS_ZIP) ZIPCLI $(MODS_ZIPUTILS), \
+ $(NAME).MMSD)
+
+# Default target is the comprehensive dependency list.
+
+$(DEPS_FILE) : $(DEPS) $(COMS)
+.IF UNK_MMSD
+ @ write sys$output -
+ " /SKIP_INTERMEDIATES is expected on the MMS command line."
+ @ write sys$output -
+ " For normal behavior (delete individual .MMSD files), specify ""/SKIP""."
+ @ write sys$output -
+ " To retain the individual .MMSD files, specify ""/MACRO = NOSKIP=1""."
+ @ exit %x00000004
+.ENDIF
+#
+# Note that the space in P3, which prevents immediate macro
+# expansion, is removed by COLLECT_DEPS.COM.
+#
+ @[.VMS]COLLECT_DEPS.COM "Zip" -
+ "$(MMS$TARGET)" "[...]*.MMSD" "[.$ (DEST)]" $(MMSDESCRIPTION_FILE)
+ @ write sys$output -
+ "Created a new dependency file: $(MMS$TARGET)"
+.IF DELETE_MMSD
+ @ write sys$output -
+ "Deleting intermediate .MMSD files..."
+ delete /log *.MMSD;*, [.VMS]*.MMSD;*
+.ELSE
+ @ write sys$output -
+ "Purging intermediate .MMSD files..."
+ purge /log *.MMSD, [.VMS]*.MMSD
+.ENDIF
+
+# CLEAN target. Delete the individual C dependency files.
+
+CLEAN :
+ if (f$search( "*.MMSD") .nes. "") then -
+ delete /log *.MMSD;*
+ if (f$search( "[.VMS]*.MMSD") .nes. "") then -
+ delete /log [.VMS]*.MMSD;*
+
+# CLEAN_ALL target. Delete:
+# The individual C dependency files.
+# The collected source dependency file.
+
+CLEAN_ALL :
+ if (f$search( "*.MMSD") .nes. "") then -
+ delete /log *.MMSD;*
+ if (f$search( "[.VMS]*.MMSD") .nes. "") then -
+ delete /log [.VMS]*.MMSD;*
+ if (f$search( "[.VMS]DESCRIP_DEPS.MMS") .nes. "") then -
+ delete /log [.VMS]DESCRIP_DEPS.MMS;*
+
+# Explicit dependencies and rules for utility variant modules.
+#
+# The extra dependency on the normal dependency file obviates including
+# the /SKIP warning code in each rule here.
+
+CRC32_.MMSD : CRC32.C CRC32.MMSD
+ $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(MMS$SOURCE) -
+ /NOLIST /NOOBJECT /MMS_DEPENDENCIES = -
+ (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES)
+ @[.VMS]MOD_DEP.COM $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET)
+
+CRYPT_.MMSD : CRYPT.C CRYPT.MMSD
+ $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(MMS$SOURCE) -
+ /NOLIST /NOOBJECT /MMS_DEPENDENCIES = -
+ (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES)
+ @[.VMS]MOD_DEP.COM $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET)
+
+FILEIO_.MMSD : FILEIO.C FILEIO.MMSD
+ $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(MMS$SOURCE) -
+ /NOLIST /NOOBJECT /MMS_DEPENDENCIES = -
+ (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES)
+ @[.VMS]MOD_DEP.COM $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET)
+
+UTIL_.MMSD : UTIL.C UTIL.MMSD
+ $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(MMS$SOURCE) -
+ /NOLIST /NOOBJECT /MMS_DEPENDENCIES = -
+ (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES)
+ @[.VMS]MOD_DEP.COM $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET)
+
+ZIPFILE_.MMSD : ZIPFILE.C ZIPFILE.MMSD
+ $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(MMS$SOURCE) -
+ /NOLIST /NOOBJECT /MMS_DEPENDENCIES = -
+ (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES)
+ @[.VMS]MOD_DEP.COM $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET)
+
+[.VMS]VMS_.MMSD : [.VMS]VMS.C [.VMS]VMS.MMSD
+ $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(MMS$SOURCE) -
+ /NOLIST /NOOBJECT /MMS_DEPENDENCIES = -
+ (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES)
+ @[.VMS]MOD_DEP.COM $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET)
+
+ZIPCLI.MMSD : ZIP.C ZIP.MMSD
+ $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(MMS$SOURCE) -
+ /NOLIST /NOOBJECT /MMS_DEPENDENCIES = -
+ (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES)
+ @[.VMS]MOD_DEP.COM $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET)
+
+# Special case. No normal (non-CLI) version.
+
+[.VMS]CMDLINE.MMSD : [.VMS]CMDLINE.C
+.IF UNK_MMSD
+ @ write sys$output -
+ " /SKIP_INTERMEDIATES is expected on the MMS command line."
+ @ write sys$output -
+ " For normal behavior (delete .MMSD files), specify ""/SKIP""."
+ @ write sys$output -
+ " To retain the .MMSD files, specify ""/MACRO = NOSKIP=1""."
+ @ exit %x00000004
+.ENDIF
+ $(CC) $(CFLAGS_INCL) $(CFLAGS_CLI) $(MMS$SOURCE) -
+ /NOLIST /NOOBJECT /MMS_DEPENDENCIES = -
+ (FILE = $(MMS$TARGET), NOSYSTEM_INCLUDE_FILES)
+ @[.VMS]MOD_DEP.COM $(MMS$TARGET) $(MMS$TARGET_NAME).OBJ $(MMS$TARGET)
+
diff --git a/vms/descrip_src.mms b/vms/descrip_src.mms
new file mode 100644
index 0000000..33f3281
--- /dev/null
+++ b/vms/descrip_src.mms
@@ -0,0 +1,373 @@
+# 23 February 2007. SMS.
+#
+# Zip 3.0 for VMS - MMS (or MMK) Source Description File.
+#
+
+# This description file is included by other description files. It is
+# not intended to be used alone. Verify proper inclusion.
+
+.IFDEF INCL_DESCRIP_SRC
+.ELSE
+$$$$ THIS DESCRIPTION FILE IS NOT INTENDED TO BE USED THIS WAY.
+.ENDIF
+
+
+# Define MMK architecture macros when using MMS.
+
+.IFDEF __MMK__ # __MMK__
+.ELSE # __MMK__
+ALPHA_X_ALPHA = 1
+IA64_X_IA64 = 1
+VAX_X_VAX = 1
+.IFDEF $(MMS$ARCH_NAME)_X_ALPHA # $(MMS$ARCH_NAME)_X_ALPHA
+__ALPHA__ = 1
+.ENDIF # $(MMS$ARCH_NAME)_X_ALPHA
+.IFDEF $(MMS$ARCH_NAME)_X_IA64 # $(MMS$ARCH_NAME)_X_IA64
+__IA64__ = 1
+.ENDIF # $(MMS$ARCH_NAME)_X_IA64
+.IFDEF $(MMS$ARCH_NAME)_X_VAX # $(MMS$ARCH_NAME)_X_VAX
+__VAX__ = 1
+.ENDIF # $(MMS$ARCH_NAME)_X_VAX
+.ENDIF # __MMK__
+
+# Combine command-line VAX C compiler macros.
+
+.IFDEF VAXC # VAXC
+VAXC_OR_FORCE_VAXC = 1
+.ELSE # VAXC
+.IFDEF FORCE_VAXC # FORCE_VAXC
+VAXC_OR_FORCE_VAXC = 1
+.ENDIF # FORCE_VAXC
+.ENDIF # VAXC
+
+# Analyze architecture-related and option macros.
+
+.IFDEF __ALPHA__ # __ALPHA__
+DECC = 1
+DESTM = ALPHA
+.ELSE # __ALPHA__
+.IFDEF __IA64__ # __IA64__
+DECC = 1
+DESTM = IA64
+.ELSE # __IA64__
+.IFDEF __VAX__ # __VAX__
+.IFDEF VAXC_OR_FORCE_VAXC # VAXC_OR_FORCE_VAXC
+DESTM = VAXV
+.ELSE # VAXC_OR_FORCE_VAXC
+.IFDEF GNUC # GNUC
+CC = GCC
+DESTM = VAXG
+.ELSE # GNUC
+DECC = 1
+DESTM = VAX
+.ENDIF # GNUC
+.ENDIF # VAXC_OR_FORCE_VAXC
+.ELSE # __VAX__
+DESTM = UNK
+UNK_DEST = 1
+.ENDIF # __VAX__
+.ENDIF # __IA64__
+.ENDIF # __ALPHA__
+
+.IFDEF IM # IM
+DESTI = I
+.ELSE # IM
+DESTI =
+.ENDIF # IM
+
+.IFDEF LARGE # LARGE
+.IFDEF __VAX__ # __VAX__
+DESTL =
+.ELSE # __VAX__
+DESTL = L
+.ENDIF # __VAX__
+.ELSE # LARGE
+DESTL =
+.ENDIF # LARGE
+
+DEST = $(DESTM)$(DESTI)$(DESTL)
+SEEK_BZ = $(DESTM)$(DESTL)
+
+# Library module name suffix for XXX_.OBJ with GNU C.
+
+.IFDEF GNUC # GNUC
+GCC_ = _
+.ELSE # GNUC
+GCC_ =
+.ENDIF # GNUC
+
+# Check for option problems.
+
+.IFDEF __VAX__ # __VAX__
+.IFDEF LARGE # LARGE
+LARGE_VAX = 1
+.ENDIF # LARGE
+.IFDEF VAXC_OR_FORCE_VAXC # VAXC_OR_FORCE_VAXC
+.IFDEF GNUC # GNUC
+VAX_MULTI_CMPL = 1
+.ENDIF # GNUC
+.ENDIF # VAXC_OR_FORCE_VAXC
+.ELSE # __VAX__
+.IFDEF VAXC_OR_FORCE_VAXC # VAXC_OR_FORCE_VAXC
+NON_VAX_CMPL = 1
+.ELSE # VAXC_OR_FORCE_VAXC
+.IFDEF GNUC # GNUC
+NON_VAX_CMPL = 1
+.ENDIF # GNUC
+.ENDIF # VAXC_OR_FORCE_VAXC
+.ENDIF # __VAX__
+
+# Complain if warranted. Otherwise, show destination directory.
+# Make the destination directory, if necessary.
+
+.IFDEF UNK_DEST # UNK_DEST
+.FIRST
+ @ write sys$output -
+ " Unknown system architecture."
+.IFDEF __MMK__ # __MMK__
+ @ write sys$output -
+ " MMK on IA64? Try adding ""/MACRO = __IA64__""."
+.ELSE # __MMK__
+ @ write sys$output -
+ " MMS too old? Try adding ""/MACRO = MMS$ARCH_NAME=ALPHA"","
+ @ write sys$output -
+ " or ""/MACRO = MMS$ARCH_NAME=IA64"", or ""/MACRO = MMS$ARCH_NAME=VAX"","
+ @ write sys$output -
+ " as appropriate. (Or try a newer version of MMS.)"
+.ENDIF # __MMK__
+ @ write sys$output ""
+ I_WILL_DIE_NOW. /$$$$INVALID$$$$
+.ELSE # UNK_DEST
+.IFDEF VAX_MULTI_CMPL # VAX_MULTI_CMPL
+.FIRST
+ @ write sys$output -
+ " Macro ""GNUC"" is incompatible with ""VAXC"" or ""FORCE_VAXC""."
+ @ write sys$output ""
+ I_WILL_DIE_NOW. /$$$$INVALID$$$$
+.ELSE # VAX_MULTI_CMPL
+.IFDEF NON_VAX_CMPL # NON_VAX_CMPL
+.FIRST
+ @ write sys$output -
+ " Macros ""GNUC"", ""VAXC"", and ""FORCE_VAXC"" are valid only on VAX."
+ @ write sys$output ""
+ I_WILL_DIE_NOW. /$$$$INVALID$$$$
+.ELSE # NON_VAX_CMPL
+.IFDEF LARGE_VAX # LARGE_VAX
+.FIRST
+ @ write sys$output -
+ " Macro ""LARGE"" is invalid on VAX."
+ @ write sys$output ""
+ I_WILL_DIE_NOW. /$$$$INVALID$$$$
+.ELSE # LARGE_VAX
+.IFDEF IZ_BZIP2 # IZ_BZIP2
+CDEFS_BZ = , BZIP2_SUPPORT
+CFLAGS_INCL = /INCLUDE = ([], [.VMS])
+INCL_BZIP2_M = , ZBZ2ERR
+LIB_BZIP2_OPTS = LIB_BZIP2:LIBBZ2_NS.OLB /library,
+.FIRST
+ @ define incl_bzip2 $(IZ_BZIP2)
+ @ @[.VMS]FIND_BZIP2_LIB.COM $(IZ_BZIP2) $(SEEK_BZ) -
+ LIBBZ2_NS.OLB lib_bzip2
+ @ write sys$output ""
+ @ if (f$trnlnm( "lib_bzip2") .nes. "") then -
+ write sys$output " BZIP2 dir: ''f$trnlnm( "lib_bzip2")'"
+ @ if (f$trnlnm( "lib_bzip2") .eqs. "") then -
+ write sys$output " Can not find BZIP2 object library."
+ @ write sys$output ""
+ @ if (f$trnlnm( "lib_bzip2") .eqs. "") then -
+ I_WILL_DIE_NOW. /$$$$INVALID$$$$
+ @ write sys$output " Destination: [.$(DEST)]"
+ @ write sys$output ""
+ if (f$search( "$(DEST).DIR;1") .eqs. "") then -
+ create /directory [.$(DEST)]
+.ELSE # IZ_BZIP2
+CDEFS_BZ =
+CFLAGS_INCL = /include = []
+INCL_BZIP2_M = , ZBZ2ERR
+LIB_BZIP2_OPTS =
+.FIRST
+ @ write sys$output " Destination: [.$(DEST)]"
+ @ write sys$output ""
+ if (f$search( "$(DEST).DIR;1") .eqs. "") then -
+ create /directory [.$(DEST)]
+.ENDIF # IZ_BZIP2
+.ENDIF # LARGE_VAX
+.ENDIF # NON_VAX_CMPL
+.ENDIF # VAX_MULTI_CMPL
+.ENDIF # UNK_DEST
+
+# DBG options.
+
+.IFDEF DBG # DBG
+CFLAGS_DBG = /debug /nooptimize
+LINKFLAGS_DBG = /debug /traceback
+.ELSE # DBG
+CFLAGS_DBG =
+LINKFLAGS_DBG = /notraceback
+.ENDIF # DBG
+
+# "IM" scheme for storing VMS/RMS file attributes.
+
+.IFDEF IM # IM
+CDEFS_IM = , VMS_IM_EXTRA
+.ELSE # IM
+CDEFS_IM =
+.ENDIF # IM
+
+# Large-file options.
+
+.IFDEF LARGE # LARGE
+CDEFS_LARGE = , LARGE_FILE_SUPPORT
+.ELSE # LARGE
+CDEFS_LARGE =
+.ENDIF # LARGE
+
+# C compiler defines.
+
+.IFDEF LOCAL_ZIP
+C_LOCAL_ZIP = , $(LOCAL_ZIP)
+.ELSE
+C_LOCAL_ZIP =
+.ENDIF
+
+CDEFS = VMS $(CDEFS_BZ) $(CDEFS_IM) $(CDEFS_LARGE) $(C_LOCAL_ZIP)
+
+CDEFS_UNX = /define = ($(CDEFS))
+
+CDEFS_CLI = /define = ($(CDEFS), VMSCLI)
+
+CDEFS_UTIL = /define = ($(CDEFS), UTIL)
+
+# Other C compiler options.
+
+.IFDEF DECC # DECC
+CFLAGS_ARCH = /decc /prefix = (all)
+.ELSE # DECC
+.IFDEF FORCE_VAXC # FORCE_VAXC
+CFLAGS_ARCH = /vaxc
+.IFDEF VAXC # VAXC
+.ELSE # VAXC
+VAXC = 1
+.ENDIF # VAXC
+.ELSE # FORCE_VAXC
+CFLAGS_ARCH =
+.ENDIF # FORCE_VAXC
+.ENDIF # DECC
+
+.IFDEF VAXC_OR_FORCE_VAXC # VAXC_OR_FORCE_VAXC
+OPT_FILE = [.$(DEST)]VAXCSHR.OPT
+LFLAGS_ARCH = $(OPT_FILE) /options,
+.ELSE # VAXC_OR_FORCE_VAXC
+.IFDEF GNUC # GNUC
+OPT_FILE = [.$(DEST)]VAXCSHR.OPT
+LFLAGS_GNU = GNU_CC:[000000]GCCLIB.OLB /LIBRARY
+LFLAGS_ARCH = $(LFLAGS_GNU), SYS$DISK:$(OPT_FILE) /options,
+.ELSE # GNUC
+OPT_FILE =
+LFLAGS_ARCH =
+.ENDIF # GNUC
+.ENDIF # VAXC_OR_FORCE_VAXC
+
+# LIST options.
+
+.IFDEF LIST # LIST
+.IFDEF DECC # DECC
+CFLAGS_LIST = /list = $*.LIS /show = (all, nomessages)
+.ELSE # DECC
+CFLAGS_LIST = /list = $*.LIS /show = (all)
+.ENDIF # DECC
+LINKFLAGS_LIST = /map = $*.MAP /cross_reference /full
+.ELSE # LIST
+CFLAGS_LIST =
+LINKFLAGS_LIST =
+.ENDIF # LIST
+
+# Common CFLAGS and LINKFLAGS.
+
+CFLAGS = \
+ $(CFLAGS_ARCH) $(CFLAGS_DBG) $(CFLAGS_INCL) $(CFLAGS_LIST) $(CCOPTS) \
+ /object = $(MMS$TARGET)
+
+LINKFLAGS = \
+ $(LINKFLAGS_DBG) $(LINKFLAGS_LIST) $(LINKOPTS) \
+ /executable = $(MMS$TARGET)
+
+# Object library module=object lists.
+
+# Primary object library, [].
+
+MODS_OBJS_LIB_ZIP_N = \
+ CRC32=[.$(DEST)]CRC32.OBJ \
+ CRYPT=[.$(DEST)]CRYPT.OBJ \
+ DEFLATE=[.$(DEST)]DEFLATE.OBJ \
+ FILEIO=[.$(DEST)]FILEIO.OBJ \
+ GLOBALS=[.$(DEST)]GLOBALS.OBJ \
+ TREES=[.$(DEST)]TREES.OBJ \
+ TTYIO=[.$(DEST)]TTYIO.OBJ \
+ UTIL=[.$(DEST)]UTIL.OBJ \
+ ZBZ2ERR=[.$(DEST)]ZBZ2ERR.OBJ \
+ ZIPFILE=[.$(DEST)]ZIPFILE.OBJ \
+ ZIPUP=[.$(DEST)]ZIPUP.OBJ
+
+# Primary object library, [.VMS].
+
+MODS_OBJS_LIB_ZIP_V = \
+ VMS=[.$(DEST)]VMS.OBJ \
+ VMSMUNCH=[.$(DEST)]VMSMUNCH.OBJ \
+ VMSZIP=[.$(DEST)]VMSZIP.OBJ
+
+MODS_OBJS_LIB_ZIP = $(MODS_OBJS_LIB_ZIP_N) $(MODS_OBJS_LIB_ZIP_V)
+
+# Utility object library, normal, [].
+
+MODS_OBJS_LIB_ZIPUTILS_N = \
+ GLOBALS=[.$(DEST)]GLOBALS.OBJ \
+ TTYIO=[.$(DEST)]TTYIO.OBJ
+
+# Utility object library, variant, [].
+
+MODS_OBJS_LIB_ZIPUTILS_U = \
+ CRC32$(GCC_)=[.$(DEST)]CRC32_.OBJ \
+ CRYPT$(GCC_)=[.$(DEST)]CRYPT_.OBJ \
+ FILEIO$(GCC_)=[.$(DEST)]FILEIO_.OBJ \
+ UTIL$(GCC_)=[.$(DEST)]UTIL_.OBJ \
+ ZIPFILE$(GCC_)=[.$(DEST)]ZIPFILE_.OBJ
+
+# Utility object library, normal, [.VMS].
+
+MODS_OBJS_LIB_ZIPUTILS_N_V = \
+ VMSMUNCH=[.$(DEST)]VMSMUNCH.OBJ
+
+# Utility object library, variant, [.VMS].
+
+MODS_OBJS_LIB_ZIPUTILS_U_V = \
+ VMS$(GCC_)=[.$(DEST)]VMS_.OBJ
+
+MODS_OBJS_LIB_ZIPUTILS = $(MODS_OBJS_LIB_ZIPUTILS_N) \
+ $(MODS_OBJS_LIB_ZIPUTILS_U) \
+ $(MODS_OBJS_LIB_ZIPUTILS_N_V) \
+ $(MODS_OBJS_LIB_ZIPUTILS_U_V) \
+
+# CLI object library, [.VMS].
+
+MODS_OBJS_LIB_ZIPCLI_C_V = \
+ CMDLINE=[.$(DEST)]CMDLINE.OBJ
+
+MODS_OBJS_LIB_ZIPCLI_CLD_V = \
+ ZIP_CLITABLE=[.$(DEST)]ZIP_CLI.OBJ
+
+MODS_OBJS_LIB_ZIPCLI = \
+ $(MODS_OBJS_LIB_ZIPCLI_C_V) \
+ $(MODS_OBJS_LIB_ZIPCLI_CLD_V)
+
+# Executables.
+
+ZIP = [.$(DEST)]ZIP.EXE
+
+ZIP_CLI = [.$(DEST)]ZIP_CLI.EXE
+
+ZIPUTILS = \
+ [.$(DEST)]ZIPCLOAK.EXE \
+ [.$(DEST)]ZIPNOTE.EXE \
+ [.$(DEST)]ZIPSPLIT.EXE
+
diff --git a/vms/find_bzip2_lib.com b/vms/find_bzip2_lib.com
new file mode 100644
index 0000000..21ebf7b
--- /dev/null
+++ b/vms/find_bzip2_lib.com
@@ -0,0 +1,71 @@
+$! 28 December 2006. SMS.
+$!
+$! Info-ZIP VMS accessory procedure.
+$!
+$! Find the BZIP2 object library under P1, starting in the [.'P2']
+$! destination directory. (We assume, initially, that the BZIP2
+$! directory has a destination directory structure like ours.)
+$!
+$! Set the P4 logical name to the directory where it was found.
+$! P5 and P6 may be used for qualifiers on the DEFINE command.
+$!
+$ bz_orig = p1
+$ dest = p2
+$ libbz2 = p3
+$!
+$! Remove any trailing colon, to allow logical name translation.
+$!
+$ bz_dev_dir = ""
+$ bz_base = bz_orig
+$ if (f$extract( (f$length( bz_base)- 1), 1, bz_base) .eqs. ":")
+$ then
+$ bz_base = bz_base- ":"
+$ endif
+$!
+$ bz_base_eqv = f$trnlnm( bz_base)
+$ if (bz_base_eqv .nes. "")
+$ then
+$ bz_orig = bz_base_eqv
+$ bz_base = bz_base_eqv
+$ endif
+$ bz_base = bz_base- "]"
+$!
+$! Candidate 1 = the actual analogue destination directory.
+$!
+$ bz_dev_dir_cand = bz_base+ "."+ dest+ "]"
+$ lib_cand = bz_dev_dir_cand+ libbz2
+$ if (f$search( lib_cand) .nes. "")
+$ then
+$ bz_dev_dir = bz_dev_dir_cand
+$ else
+$!
+$! Candidate 2 = the actual analogue destination directory + "L".
+$!
+$ bz_dev_dir_cand = bz_base+ "."+ dest+ "L]"
+$ lib_cand = bz_dev_dir_cand+ libbz2
+$ if (f$search( lib_cand) .nes. "")
+$ then
+$ bz_dev_dir = bz_dev_dir_cand
+$ else
+$!
+$! Candidate 3 = the actual user-specified directory.
+$!
+$ bz_dev_dir_cand = bz_orig
+$ lib_cand = bz_dev_dir_cand+ libbz2
+$ if (f$search( lib_cand) .nes. "")
+$ then
+$ bz_dev_dir = bz_dev_dir_cand
+$ endif
+$ endif
+$ endif
+$!
+$ if (bz_dev_dir .nes. "")
+$ then
+$ if (p4 .eqs. "")
+$ then
+$ write sys$output bz_dev_dir
+$ else
+$ define 'p5' 'p4' 'bz_dev_dir' 'p6'
+$ endif
+$ endif
+$!
diff --git a/vms/hlp_lib_next.com b/vms/hlp_lib_next.com
new file mode 100644
index 0000000..f9b14a5
--- /dev/null
+++ b/vms/hlp_lib_next.com
@@ -0,0 +1,17 @@
+$! 21 November 2004. SMS.
+$!
+$! HLP_LIB_NEXT.COM
+$!
+$! Find the next available HLP$LIBRARY[_*] logical name.
+$!
+$ base = "HLP$LIBRARY"
+$ candidate = base
+$ i = 0
+$!
+$ loop_top:
+$ if (i .gt. 0) then candidate = base+ "_"+ f$string( i)
+$ i = i+ 1
+$ if (f$trnlnm( candidate) .nes. "") then goto loop_top
+$!
+$ write sys$output candidate
+$!
diff --git a/vms/install_vms.txt b/vms/install_vms.txt
new file mode 100644
index 0000000..47dfebb
--- /dev/null
+++ b/vms/install_vms.txt
@@ -0,0 +1,158 @@
+
+ VMS (OpenVMS):
+
+ Building:
+
+ On VMS, two build methods are provided: a command procedure, and
+ description files for MMS or MMK. Both methods must be run from
+ the main directory, not the [.VMS] subdirectory.
+
+ A simple build using the command procedure looks like this:
+ @ [.VMS]BUILD_ZIP.COM
+
+ A simple build using MMS or MMK looks like this:
+ MMS /DESCRIP = [.VMS]DESCRIP.MMS ! Or, with MMK, ...
+ MMK /DESCRIP = [.VMS]DESCRIP.MMS
+
+ Various options for each build method are explained in comments in
+ the main builder file, either BUILD_ZIP.COM or DESCRIP.MMS.
+
+ Note that on non-VAX systems with VMS V7.2 or later (and with a
+ sufficiently new C compiler), Zip 3.0 can support files (both data
+ files and Zip archives) larger than 2GB. For the greatest
+ compatibility with previous Zip versions, the builders by default
+ create old-style small-file programs. The user must specify the
+ appropriate builder command-line option to create
+ large-file-capable programs.
+
+ Here are some more complex build examples:
+
+ o Build with the large-file option enabled (non-VAX only):
+
+ @ [.VMS]BUILD_ZIP LARGE
+ or:
+ MMS /DESC = [.VMS] /MACRO = LARGE=1
+
+ o Re-link the executables (small-file and large-file):
+
+ @ [.VMS]BUILD_ZIP LINK
+ @ [.VMS]BUILD_ZIP LARGE LINK
+ or
+ MMK /DESC = [.VMS] CLEAN_EXE ! Deletes existing executables.
+ MMK /DESC = [.VMS] ! Builds new executables.
+ MMK /DESC = [.VMS] /MACRO = LARGE=1 CLEAN_EXE
+ MMK /DESC = [.VMS] /MACRO = LARGE=1
+
+ o Build a large-file product from scratch, for debug, getting
+ compiler listings and link maps:
+
+ MMS /DESC = [.VMS] CLEAN
+ MMS /DESC = [.VMS] /MACRO = (DBG=1, LARGE=1. LIST=1)
+
+ On VAX, the builders attempt to cope with the various available C
+ compilers, DEC/Compaq/HP C, VAX C, or GNU C. If DEC/Compaq/HP C is
+ not available or not desired, comments in the relevant builder file
+ explain the command-line options used to select a different
+ compiler.
+
+ By default, Zip uses the "deflate" compression method. To add
+ support for the optional "bzip2" compression method, first obtain
+ and build the bzip2 software (http://www.bzip.org/ or, for a more
+ VMS-friendly kit, http://antinode.info/dec/sw/bzip2.html). Then,
+ define the macro IZ_BZIP2 on the BUILD_ZIP.COM or MMS/MMK command
+ line to specify the directory where the bzip2 files may be found.
+ For example:
+
+ @ [.VMS]BUILD_ZIP LARGE -
+ IZ_BZIP2=SYS$SYSDEVICE:[UTILITY.SOURCE.BZIP2.BZIP2-1_0_3C_VMS]
+ or:
+ MMS /DESC = [.VMS] /MACRO = (LARGE=1, -
+ IZ_BZIP2=SYS$SYSDEVICE:[UTILITY.SOURCE.BZIP2.BZIP2-1_0_3C_VMS])
+
+ Note that historically, Zip has been built with the default
+ compiler option, /NAMES = UPPERCASE, while bzip2 is normally built
+ with /NAMES = AS_IS, to avoid name collisions. With modern
+ compilers, the "#pragma names" directives in [.VMS]BZLIB.H will
+ handle these differences without user intervention. An old
+ compiler (for example, DEC C V4.0-000) will emit complaints
+ %CC-I-UNKNOWNPRAGMA, and will mishandle the bzip2 library function
+ names, which will cause the link to fail. To solve this problem,
+ either build the bzip2 BZ_NO_STDIO object library with /NAMES =
+ UPPERCASE, or else build Zip with /NAMES = AS_IS. For example:
+
+ @ [.VMS]BUILD_ZIP LARGE "CCOPTS=/NAMES=AS_IS" -
+ IZ_BZIP2=SYS$SYSDEVICE:[UTILITY.SOURCE.BZIP2.BZIP2-1_0_3C_VMS]
+ or:
+ MMS /DESC = [.VMS] /MACRO = (LARGE=1, "CCOPTS=/NAMES=AS_IS", -
+ IZ_BZIP2=SYS$SYSDEVICE:[UTILITY.SOURCE.BZIP2.BZIP2-1_0_3C_VMS])
+
+ System-architecture-specific files (like objects and executables)
+ are placed in separate directories, such as [.ALPHA], [.IA64], or
+ [.VAX]. Large-file products get their own directories, [.ALPHAL]
+ or [.IA64L]. On VAX, VAX C products are placed in [.VAXV], GNU C
+ products in [.VAXG]. Each product builder announces what the
+ destination directory will be when it is run.
+
+ Common files, such as the help libraries (ZIP.HLP for the default
+ UNIX-like command-line interface, ZIP_CLI.HLP for the VMS-like
+ command-line interface), are placed in the main directory. With a
+ mixed-architecture VMS cluster, the same main directory on a shared
+ disk may be used by all system types. (Using the NOHELP option
+ with BUILD_ZIP.COM can keep it from making the same help files
+ repeatedly.) Building the help files is detailed below.
+
+ Completing installation:
+
+ To complete the installation, the executables may be left in place,
+ or moved (or copied) to a convenient place. While other methods
+ (like DCL$PATH) exist, most users define symbols to make the Zip
+ executables available as foreign commands. These symbol definitions
+ may be placed in a user's SYS$LOGIN:LOGIN.COM, or in a more central
+ location, like SYS$MANAGER:SYLOGIN.COM. Typical symbol definitions
+ might look like these:
+
+ ZIP :== $ dev:[dir]ZIP.EXE ! UNIX-like command line.
+ or:
+ ZIP :== $ dev:[dir]ZIP_CLI.EXE ! VMS-like command line.
+
+ On a non-VAX system, different symbols could be defined for the
+ small-file and large-file programs. For example:
+
+ ZIPS :== $ dev:[dir.ALPHA]ZIP.EXE ! ZIPS = small-file Zip.
+ ZIP*L :== $ dev:[dir.ALPHAL]ZIP.EXE ! ZIP[L] = large-file Zip.
+
+ The builders create help text files, ZIP.HLP and ZIP_CLI.HLP.
+ These may be incorporated into an existing help library, or a separate
+ Zip help library may be created using commands like these, using
+ either ZIP.HLP (as shown) or ZIP_CLI.HLP:
+
+ $ LIBRARY /HELP dev:[dir]existing_library.HLB ZIP.HLP
+
+ $ LIBRARY /CREATE /HELP ZIP.HLB ZIP.HLP
+
+ Zip help may then be accessed from a separate Zip help library
+ using a command like:
+
+ $ HELP /LIBRARY = device:[directory]ZIP.HLB
+
+ For greater ease, the user (or system manager) may define a
+ HLP$LIBRARY logical name to allow the HELP utility to find the Zip
+ help library automatically. See HELP HELP /USERLIBRARY for more
+ details. The command procedure HLP_LIB_NEXT.COM may be used to
+ determine the next available HLP$LIBRARY logical name, and could be
+ adapted to define a HLP$LIBRARY logical name for a Zip help library.
+
+ The builders also create VMS message files, ZIP_MSG.EXE, in the
+ destination directory with the program executables. A user may
+ gain DCL access to the Zip error messages using a command like:
+
+ $ SET MESSAGE device:[directory]ZIP_MSG.EXE
+
+ For system-wide access, the system manager may move or copy this
+ file to SYS$MESSAGE, although this could cause some confusion if
+ multiple versions of Zip are used on the system, and their error
+ message source files differ.
+
+ Some further information may be found in the files
+ [.VMS]00README.TXT and [.VMS]00BINARY.VMS, though much of what's
+ there is now obsolete.
diff --git a/vms/link_zip.com b/vms/link_zip.com
deleted file mode 100755
index 54149a3..0000000
--- a/vms/link_zip.com
+++ /dev/null
@@ -1,204 +0,0 @@
-$ ! LINK_ZIP.COM
-$ !
-$ ! Command procedure to (re)link the VMS versions of
-$ ! Zip, ZipCloak, ZipNote, and ZipSplit
-$ !
-$ ! Command args:
-$ ! - select compiler environment: "VAXC", "DECC", "GNUC"
-$ ! - select installation of CLI interface version of zip:
-$ ! "VMSCLI" or "CLI"
-$ ! - force installation of UNIX interface version of zip
-$ ! (override LOCAL_ZIP environment): "NOVMSCLI" or "NOCLI"
-$ !
-$ on error then goto error
-$ on control_y then goto error
-$ OLD_VERIFY = f$verify(0)
-$!
-$ say := write sys$output
-$!##################### Read settings from environment ########################
-$!
-$ if f$type(LOCAL_ZIP).eqs.""
-$ then
-$ local_zip = ""
-$ else ! Trim blanks and append comma if missing
-$ local_zip = f$edit(local_zip, "TRIM")
-$ if f$extract(f$length(local_zip)-1, 1, local_zip).nes."," then -
- local_zip = local_zip + ","
-$ endif
-$! Check for the presence of "VMSCLI" in local_zip. If yes, we will define
-$! the foreign command for "zip" to use the executable containing the
-$! CLI interface.
-$ pos_cli = f$locate("VMSCLI",local_zip)
-$ len_local_zip = f$length(local_zip)
-$ if pos_cli.ne.len_local_zip
-$ then
-$ CLI_IS_DEFAULT = 1
-$ ! Remove "VMSCLI" macro from local_zip. The Zip executable including
-$ ! the CLI interface is now created unconditionally.
-$ local_zip = f$extract(0, pos_cli, local_zip) + -
-$ f$extract(pos_cli+7, len_local_zip-(pos_cli+7), local_zip)
-$ else
-$ CLI_IS_DEFAULT = 0
-$ endif
-$ delete/symbol/local pos_cli
-$ delete/symbol/local len_local_zip
-$!##################### Customizing section #############################
-$!
-$ zipx_unx = "zip"
-$ zipx_cli = "zip_cli"
-$!
-$ MAY_USE_DECC = 1 ! Use DEC C when its presence is detected
-$ MAY_USE_GNUC = 0 ! Do not prefer GNUC over DEC or VAX C
-$!
-$! Process command line parameters requesting optional features:
-$ arg_cnt = 1
-$ argloop:
-$ current_arg_name = "P''arg_cnt'"
-$ curr_arg = f$edit('current_arg_name',"UPCASE")
-$ IF curr_arg .eqs. "" THEN GOTO argloop_out
-$ IF curr_arg .eqs. "VAXC"
-$ THEN MAY_USE_DECC = 0
-$ MAY_USE_GNUC = 0
-$ ENDIF
-$ IF curr_arg .eqs. "DECC"
-$ THEN MAY_USE_DECC = 1
-$ MAY_USE_GNUC = 0
-$ ENDIF
-$ IF curr_arg .eqs. "GNUC"
-$ THEN MAY_USE_DECC = 0
-$ MAY_USE_GNUC = 1
-$ ENDIF
-$ IF (curr_arg .eqs. "VMSCLI") .or. (curr_arg .eqs. "CLI")
-$ THEN
-$ CLI_IS_DEFAULT = 1
-$ ENDIF
-$ IF (curr_arg .eqs. "NOVMSCLI") .or. (curr_arg .eqs. "NOCLI")
-$ THEN
-$ CLI_IS_DEFAULT = 0
-$ ENDIF
-$ arg_cnt = arg_cnt + 1
-$ GOTO argloop
-$ argloop_out:
-$!
-$ if CLI_IS_DEFAULT
-$ then
-$ ZIPEXEC = zipx_cli
-$ else
-$ ZIPEXEC = zipx_unx
-$ endif
-$!
-$!#######################################################################
-$!
-$ ! Find out current disk, directory, compiler and options
-$ !
-$ my_name = f$env("procedure")
-$ workdir = f$env("default")
-$ here = f$parse(workdir,,,"device") + f$parse(workdir,,,"directory")
-$ axp = f$getsyi("HW_MODEL").ge.1024
-$ if axp
-$ then
-$ ! Alpha AXP
-$ ARCH_NAME == "Alpha"
-$ ARCH_PREF = "AXP_"
-$ HAVE_DECC_VAX = 0
-$ USE_DECC_VAX = 0
-$ IF (f$search("SYS$DISK:[]ZIP.''ARCH_PREF'OLB").eqs."")
-$ THEN
-$ say "Cannot find any AXP object library for Zip."
-$ say " You must keep all binary files of the object distribution"
-$ say " in the current directory !"
-$ goto error
-$ ENDIF
-$ if MAY_USE_GNUC
-$ then say "Up to now, the GNU C ports available on OpenVMS AXP"
-$ say "contain so many nasty bugs and lack support for a number of"
-$ say "required VMS specific features."
-$ say "These design flaws make it impossible to compile Zip
-$ say "using GCC, sorry."
-$ goto error
-$ endif
-$ ARCH_CC_P = ARCH_PREF
-$ opts = ""
-$ say "Linking on AXP using DEC C"
-$ else
-$ ! VAX
-$ ARCH_NAME == "VAX"
-$ ARCH_PREF = "VAX_"
-$ ! check which object libraries are present:
-$ HAVE_DECC_VAX =(f$search("SYS$DISK:[]ZIP.''ARCH_PREF'DECC_OLB").nes."")
-$ HAVE_VAXC_VAX =(f$search("SYS$DISK:[]ZIP.''ARCH_PREF'VAXC_OLB").nes."")
-$ HAVE_GNUC_VAX =(f$search("SYS$DISK:[]ZIP.''ARCH_PREF'GNUC_OLB").nes."")
-$ IF .not.HAVE_DECC_VAX .and. .not.HAVE_VAXC_VAX .and. .not.HAVE_GNUC_VAX
-$ THEN
-$ say "Cannot find any VAX object library for Zip."
-$ say " You must keep all binary files of the object distribution"
-$ say " in the current directory !"
-$ goto error
-$ ENDIF
-$ IF HAVE_DECC_VAX .AND. MAY_USE_DECC
-$ THEN
-$ ! We use DECC:
-$ USE_DECC_VAX = 1
-$ ARCH_CC_P = "''ARCH_PREF'DECC_"
-$ opts = ""
-$ say "Linking on VAX using DEC C"
-$ ELSE
-$ ! We use VAXC (or GNU C):
-$ USE_DECC_VAX = 0
-$ opts = ",SYS$DISK:[.VMS]VAXCSHR.OPT/OPTIONS"
-$ if HAVE_GNUC_VAX .and. (.not.HAVE_VAXC_VAX .or. MAY_USE_GNUC)
-$ then
-$ ARCH_CC_P = "''ARCH_PREF'GNUC_"
-$ opts = ",GNU_CC:[000000]GCCLIB.OLB/LIB ''opts'"
-$ say "Linking on VAX using GNU C"
-$ else
-$ ARCH_CC_P = "''ARCH_PREF'VAXC_"
-$ say "Linking on VAX using VAX C"
-$ endif
-$ ENDIF
-$ endif
-$ LFLAGS = "/notrace"
-$ if (opts .nes. "") .and. -
- (f$locate("VAXCSHR",f$edit(opts,"UPCASE")) .lt. f$length(opts)) .and. -
- (f$search("[.vms]vaxcshr.opt") .eqs. "")
-$ then create [.vms]vaxcshr.opt
-$ open/append tmp [.vms]vaxcshr.opt
-$ write tmp "SYS$SHARE:VAXCRTL.EXE/SHARE"
-$ close tmp
-$ endif
-$ set verify ! like "echo on", eh?
-$ !
-$ !------------------------------- Zip section --------------------------------
-$ !
-$ link'LFLAGS'/exe='zipx_unx'.'ARCH_CC_P'exe -
- zip.'ARCH_CC_P'olb;/incl=(zip,globals)/lib 'opts'
-$ !
-$ !------------------------ Zip (CLI interface) section -----------------------
-$ !
-$ link'LFLAGS'/exe='zipx_cli'.'ARCH_CC_P'exe -
- zipcli.'ARCH_CC_P'olb;/incl=(zip)/lib, -
- zip.'ARCH_CC_P'olb;/incl=(globals)/lib 'opts'
-$ !
-$ !-------------------------- Zip utilities section ---------------------------
-$ !
-$ link'LFLAGS'/exe=zipcloak.'ARCH_CC_P'exe zipcloak.'ARCH_CC_P'obj, -
- ziputils.'ARCH_CC_P'olb;/incl=(globals)/lib 'opts'
-$ link'LFLAGS'/exe=zipnote.'ARCH_CC_P'exe zipnote.'ARCH_CC_P'obj, -
- ziputils.'ARCH_CC_P'olb;/incl=(globals)/lib 'opts'
-$ link'LFLAGS'/exe=zipsplit.'ARCH_CC_P'exe zipsplit.'ARCH_CC_P'obj, -
- ziputils.'ARCH_CC_P'olb;/incl=(globals)/lib 'opts'
-$ !
-$ !----------------------------- Symbols section ------------------------------
-$ !
-$ ! Set up symbols for the various executables. Edit the example below,
-$ ! changing "disk:[directory]" as appropriate.
-$ !
-$ zip == "$''here'''ZIPEXEC'.''ARCH_CC_P'exe"
-$ zipcloak == "$''here'zipcloak.''ARCH_CC_P'exe"
-$ zipnote == "$''here'zipnote.''ARCH_CC_P'exe"
-$ zipsplit == "$''here'zipsplit.''ARCH_CC_P'exe"
-$ !
-$error:
-$ if here .nes. "" then set default 'here'
-$ dummy = f$verify(OLD_VERIFY)
-$ exit
diff --git a/vms/make_zip.com b/vms/make_zip.com
deleted file mode 100755
index cb7358b..0000000
--- a/vms/make_zip.com
+++ /dev/null
@@ -1,287 +0,0 @@
-$ ! MAKE_ZIP.COM
-$ !
-$ ! "Makefile" for VMS versions of Zip, ZipCloak, ZipNote,
-$ ! and ZipSplit (stolen from Unzip)
-$ !
-$ ! Command args:
-$ ! - select compiler environment: "VAXC", "DECC", "GNUC"
-$ ! - select installation of CLI interface version of zip:
-$ ! "VMSCLI" or "CLI"
-$ ! - force installation of UNIX interface version of zip
-$ ! (override LOCAL_ZIP environment): "NOVMSCLI" or "NOCLI"
-$ !
-$ ! To define additional options, define the global symbol
-$ ! LOCAL_ZIP prior to executing MAKE_ZIP.COM, e.g.:
-$ !
-$ ! $ LOCAL_ZIP == "VMS_IM_EXTRA,"
-$ ! $ @MAKE_ZIP
-$ !
-$ ! The trailing "," may be omitted. Valid VMS-specific options
-$ ! include VMS_PK_EXTRA and VMS_IM_EXTRA; see the INSTALL file
-$ ! for other options.
-$ ! NOTE: This command procedure does always generate both the
-$ ! "default" Zip containing the UNIX style command interface
-$ ! and the "VMSCLI" Zip containing the CLI compatible command
-$ ! interface. There is no need to add "VMSCLI" to the LOCAL_ZIP
-$ ! symbol. (The only effect of "VMSCLI" is now the selection of the
-$ ! CLI style Zip executable in the foreign command definition.)
-$ !
-$ !
-$ on error then goto error
-$ on control_y then goto error
-$ OLD_VERIFY = f$verify(0)
-$!
-$ edit := edit ! override customized edit commands
-$ say := write sys$output
-$!##################### Read settings from environment ########################
-$!
-$ if f$type(LOCAL_ZIP).eqs.""
-$ then
-$ local_zip = ""
-$ else ! Trim blanks and append comma if missing
-$ local_zip = f$edit(local_zip, "TRIM")
-$ if f$extract(f$length(local_zip)-1, 1, local_zip).nes."," then -
- local_zip = local_zip + ","
-$ endif
-$! Check for the presence of "VMSCLI" in local_zip. If yes, we will define
-$! the foreign command for "zip" to use the executable containing the
-$! CLI interface.
-$ pos_cli = f$locate("VMSCLI",local_zip)
-$ len_local_zip = f$length(local_zip)
-$ if pos_cli.ne.len_local_zip
-$ then
-$ CLI_IS_DEFAULT = 1
-$ ! Remove "VMSCLI" macro from local_zip. The Zip executable including
-$ ! the CLI interface is now created unconditionally.
-$ local_zip = f$extract(0, pos_cli, local_zip) + -
-$ f$extract(pos_cli+7, len_local_zip-(pos_cli+7), local_zip)
-$ else
-$ CLI_IS_DEFAULT = 0
-$ endif
-$ delete/symbol/local pos_cli
-$ delete/symbol/local len_local_zip
-$!##################### Customizing section #############################
-$!
-$ zipx_unx = "zip"
-$ zipx_cli = "zip_cli"
-$!
-$ MAY_USE_DECC = 1 ! Use DEC C when its presence is detected
-$ MAY_USE_GNUC = 0 ! Do not prefer GNUC over DEC or VAX C
-$!
-$! Process command line parameters requesting optional features:
-$ arg_cnt = 1
-$ argloop:
-$ current_arg_name = "P''arg_cnt'"
-$ curr_arg = f$edit('current_arg_name',"UPCASE")
-$ IF curr_arg .eqs. "" THEN GOTO argloop_out
-$ IF curr_arg .eqs. "VAXC"
-$ THEN MAY_USE_DECC = 0
-$ MAY_USE_GNUC = 0
-$ ENDIF
-$ IF curr_arg .eqs. "DECC"
-$ THEN MAY_USE_DECC = 1
-$ MAY_USE_GNUC = 0
-$ ENDIF
-$ IF curr_arg .eqs. "GNUC"
-$ THEN MAY_USE_DECC = 0
-$ MAY_USE_GNUC = 1
-$ ENDIF
-$ IF (curr_arg .eqs. "VMSCLI") .or. (curr_arg .eqs. "CLI")
-$ THEN
-$ CLI_IS_DEFAULT = 1
-$ ENDIF
-$ IF (curr_arg .eqs. "NOVMSCLI") .or. (curr_arg .eqs. "NOCLI")
-$ THEN
-$ CLI_IS_DEFAULT = 0
-$ ENDIF
-$ arg_cnt = arg_cnt + 1
-$ GOTO argloop
-$ argloop_out:
-$!
-$ if CLI_IS_DEFAULT
-$ then
-$ ZIPEXEC = zipx_cli
-$ else
-$ ZIPEXEC = zipx_unx
-$ endif
-$!
-$!#######################################################################
-$!
-$ ! Find out current disk, directory, compiler and options
-$ !
-$ my_name = f$env("procedure")
-$ workdir = f$env("default")
-$ here = f$parse(workdir,,,"device") + f$parse(workdir,,,"directory")
-$ axp = f$getsyi("HW_MODEL").ge.1024
-$ if axp
-$ then
-$ ! Alpha AXP
-$ ARCH_NAME == "Alpha"
-$ ARCH_PREF = "AXP_"
-$ HAVE_DECC_VAX = 0
-$ USE_DECC_VAX = 0
-$ HAVE_DECC_AXP = (f$search("SYS$SYSTEM:DECC$COMPILER.EXE").nes."")
-$ MAY_HAVE_GNUC = (f$trnlnm("GNU_CC_VERSION").nes."")
-$ IF (.not.HAVE_DECC_AXP .and. MAY_HAVE_GNUC) .or. (MAY_USE_GNUC)
-$ THEN say "Up to now, the GNU C ports available on OpenVMS AXP"
-$ say "contain so many nasty bugs and lack support for a number of"
-$ say "required VMS specific features."
-$ say "These design flaws make it impossible to compile Zip
-$ say "using GCC, sorry."
-$ goto error
-$ ENDIF
-$ ! We use DECC:
-$ USE_DECC_AXP = 1
-$ ARCH_CC_P = ARCH_PREF
-$ cc = "cc/standard=relax/prefix=all/ansi"
-$ defs = "''local_zip'VMS"
-$ opts = ""
-$ say "Compiling on AXP using DEC C"
-$ else
-$ ! VAX
-$ ARCH_NAME == "VAX"
-$ ARCH_PREF = "VAX_"
-$ HAVE_DECC_VAX = (f$search("SYS$SYSTEM:DECC$COMPILER.EXE").nes."")
-$ HAVE_VAXC_VAX = (f$search("SYS$SYSTEM:VAXC.EXE").nes."")
-$ MAY_HAVE_GNUC = (f$trnlnm("GNU_CC").nes."")
-$ IF HAVE_DECC_VAX .AND. MAY_USE_DECC
-$ THEN
-$ ! We use DECC:
-$ USE_DECC_VAX = 1
-$ cc = "cc/decc/standard=vaxc/prefix=all"
-$ ARCH_CC_P = "''ARCH_PREF'DECC_"
-$ defs = "''local_zip'VMS"
-$ opts = ""
-$ say "Compiling on VAX using DEC C"
-$ ELSE
-$ ! We use VAXC (or GNU C):
-$ USE_DECC_VAX = 0
-$ defs = "''local_zip'VMS"
-$ opts = ",SYS$DISK:[.VMS]VAXCSHR.OPT/OPTIONS"
-$ if (.not.HAVE_VAXC_VAX .and. MAY_HAVE_GNUC) .or. (MAY_USE_GNUC)
-$ then
-$ ARCH_CC_P = "''ARCH_PREF'GNUC_"
-$ cc = "gcc"
-$ opts = ",GNU_CC:[000000]GCCLIB.OLB/LIB ''opts'"
-$ say "Compiling on VAX using GNU C"
-$ else
-$ ARCH_CC_P = "''ARCH_PREF'VAXC_"
-$ if HAVE_DECC_VAX
-$ then
-$ cc = "cc/vaxc"
-$ else
-$ cc = "cc"
-$ endif
-$ say "Compiling on VAX using VAX C"
-$ endif
-$ ENDIF
-$ endif
-$ DEF_UNX = "/def=(''DEFS')"
-$ DEF_CLI = "/def=(''DEFS',VMSCLI)"
-$ DEF_UTIL = "/def=(''DEFS',UTIL)"
-$ LFLAGS = "/notrace"
-$ if (opts .nes. "") .and. -
- (f$locate("VAXCSHR",f$edit(opts,"UPCASE")) .lt. f$length(opts)) .and. -
- (f$search("[.vms]vaxcshr.opt") .eqs. "")
-$ then create [.vms]vaxcshr.opt
-$ open/append tmp [.vms]vaxcshr.opt
-$ write tmp "SYS$SHARE:VAXCRTL.EXE/SHARE"
-$ close tmp
-$ endif
-$ set verify ! like "echo on", eh?
-$ !
-$ !------------------------------- Zip section --------------------------------
-$ !
-$ runoff/out=zip.hlp [.vms]vms_zip.rnh
-$ !
-$ cc 'DEF_UNX' /obj=zip.'ARCH_CC_P'obj zip.c
-$ cc 'DEF_UNX' /obj=crc32.'ARCH_CC_P'obj crc32.c
-$ cc 'DEF_UNX' /obj=crctab.'ARCH_CC_P'obj crctab.c
-$ cc 'DEF_UNX' /obj=crypt.'ARCH_CC_P'obj crypt.c
-$ cc 'DEF_UNX' /obj=ttyio.'ARCH_CC_P'obj ttyio.c
-$ cc 'DEF_UNX' /obj=zipfile.'ARCH_CC_P'obj zipfile.c
-$ cc 'DEF_UNX' /obj=zipup.'ARCH_CC_P'obj zipup.c
-$ cc 'DEF_UNX' /obj=fileio.'ARCH_CC_P'obj fileio.c
-$ cc 'DEF_UNX' /obj=globals.'ARCH_CC_P'obj globals.c
-$ cc 'DEF_UNX' /obj=util.'ARCH_CC_P'obj util.c
-$ cc 'DEF_UNX' /obj=deflate.'ARCH_CC_P'obj deflate.c
-$ cc 'DEF_UNX' /obj=trees.'ARCH_CC_P'obj trees.c
-$ cc 'DEF_UNX' /obj=vmszip.'ARCH_CC_P'obj/inc=SYS$DISK:[] [.vms]vmszip.c
-$ cc 'DEF_UNX' /obj=vms.'ARCH_CC_P'obj/inc=SYS$DISK:[] [.vms]vms.c
-$ cc 'DEF_UNX' /obj=vmsmunch.'ARCH_CC_P'obj/inc=SYS$DISK:[] [.vms]vmsmunch.c
-$ !
-$ if f$search("zip.''ARCH_CC_P'olb") .eqs. "" then -
- lib/obj/create zip.'ARCH_CC_P'olb
-$ lib/obj/replace zip.'ARCH_CC_P'olb -
- zip.'ARCH_CC_P'obj;, -
- crc32.'ARCH_CC_P'obj;, crctab.'ARCH_CC_P'obj;, -
- crypt.'ARCH_CC_P'obj;, ttyio.'ARCH_CC_P'obj;, -
- zipfile.'ARCH_CC_P'obj;, zipup.'ARCH_CC_P'obj;, -
- fileio.'ARCH_CC_P'obj;, util.'ARCH_CC_P'obj;, globals.'ARCH_CC_P'obj;,-
- deflate.'ARCH_CC_P'obj;, trees.'ARCH_CC_P'obj;, -
- vmszip.'ARCH_CC_P'obj;, vms.'ARCH_CC_P'obj;, -
- vmsmunch.'ARCH_CC_P'obj;
-$ !
-$ link'LFLAGS'/exe='zipx_unx'.'ARCH_CC_P'exe -
- zip.'ARCH_CC_P'olb;/incl=(zip,globals)/lib 'opts'
-$ !
-$ !------------------------ Zip (CLI interface) section -----------------------
-$ !
-$ set default [.vms]
-$ edit/tpu/nosection/nodisplay/command=cvthelp.tpu zip_cli.help
-$ set default [-]
-$ runoff/out=zip_cli.hlp [.vms]zip_cli.rnh
-$ !
-$ cc 'DEF_CLI' /obj=zipcli.'ARCH_CC_P'obj zip.c
-$ cc 'DEF_CLI'/INCLUDE=SYS$DISK:[] /OBJ=cmdline.'ARCH_CC_P'obj -
- [.vms]cmdline.c
-$ set command/obj=zip_cli.'ARCH_CC_P'obj [.vms]zip_cli.cld
-$ !
-$ if f$search("zipcli.''ARCH_CC_P'olb") .eqs. "" then -
- lib/obj/create zipcli.'ARCH_CC_P'olb
-$ lib/obj/replace zipcli.'ARCH_CC_P'olb -
- zipcli.'ARCH_CC_P'obj;, -
- cmdline.'ARCH_CC_P'obj;, zip_cli.'ARCH_CC_P'obj;
-$ !
-$ link'LFLAGS'/exe='zipx_cli'.'ARCH_CC_P'exe -
- zipcli.'ARCH_CC_P'olb;/incl=(zip)/lib, -
- zip.'ARCH_CC_P'olb;/incl=(globals)/lib 'opts'
-$ !
-$ !-------------------------- Zip utilities section ---------------------------
-$ !
-$ cc 'DEF_UTIL' /obj=zipfile_.'ARCH_CC_P'obj zipfile.c
-$ cc 'DEF_UTIL' /obj=fileio_.'ARCH_CC_P'obj fileio.c
-$ cc 'DEF_UTIL' /obj=util_.'ARCH_CC_P'obj util.c
-$ cc 'DEF_UTIL' /obj=crypt_.'ARCH_CC_P'obj crypt.c
-$ cc 'DEF_UTIL'/incl=SYS$DISK:[] /obj=vms_.'ARCH_CC_P'obj [.vms]vms.c
-$ if f$search("ziputils.''ARCH_CC_P'olb") .eqs. "" then -
- lib/obj/create ziputils.'ARCH_CC_P'olb
-$ lib/obj/replace ziputils.'ARCH_CC_P'olb -
- zipfile_.'ARCH_CC_P'obj;, fileio_.'ARCH_CC_P'obj;, -
- util_.'ARCH_CC_P'obj;, globals.'ARCH_CC_P'obj;, -
- crctab.'ARCH_CC_P'obj;, crypt_.'ARCH_CC_P'obj;, ttyio.'ARCH_CC_P'obj;,-
- vms_.'ARCH_CC_P'obj;, vmsmunch.'ARCH_CC_P'obj;
-$ cc 'DEF_UNX' /obj=zipcloak.'ARCH_CC_P'obj zipcloak.c
-$ cc 'DEF_UNX' /obj=zipnote.'ARCH_CC_P'obj zipnote.c
-$ cc 'DEF_UNX' /obj=zipsplit.'ARCH_CC_P'obj zipsplit.c
-$ link'LFLAGS'/exe=zipcloak.'ARCH_CC_P'exe zipcloak.'ARCH_CC_P'obj, -
- ziputils.'ARCH_CC_P'olb;/incl=(globals)/lib 'opts'
-$ link'LFLAGS'/exe=zipnote.'ARCH_CC_P'exe zipnote.'ARCH_CC_P'obj, -
- ziputils.'ARCH_CC_P'olb;/incl=(globals)/lib 'opts'
-$ link'LFLAGS'/exe=zipsplit.'ARCH_CC_P'exe zipsplit.'ARCH_CC_P'obj, -
- ziputils.'ARCH_CC_P'olb;/incl=(globals)/lib 'opts'
-$ !
-$ !----------------------------- Symbols section ------------------------------
-$ !
-$ ! Set up symbols for the various executables. Edit the example below,
-$ ! changing "disk:[directory]" as appropriate.
-$ !
-$ zip == "$''here'''ZIPEXEC'.''ARCH_CC_P'exe"
-$ zipcloak == "$''here'zipcloak.''ARCH_CC_P'exe"
-$ zipnote == "$''here'zipnote.''ARCH_CC_P'exe"
-$ zipsplit == "$''here'zipsplit.''ARCH_CC_P'exe"
-$ !
-$error:
-$ if here .nes. "" then set default 'here'
-$ dummy = f$verify(OLD_VERIFY)
-$ exit
diff --git a/vms/makefile.vms b/vms/makefile.vms
deleted file mode 100644
index 99eb179..0000000
--- a/vms/makefile.vms
+++ /dev/null
@@ -1,251 +0,0 @@
-#============================================================================
-# Makefile for VMS Zip, ZipCloak, ZipNote and ZipSplit Greg Roelofs
-# Version: 2.0 [for use with Todd Aven's MAKE/VMS 3.4] 25-JUN-1998
-#============================================================================
-
-# ChangeLog: 10-SEP-1993 08:53 by Hunter Goatley (add AXP support)
-# 15-OCT-1995 22:40 by Chr. Spieler (Zip 2.1)
-# 11-DEC-1995 12:09 by Chr. Spieler (AXP uses RELAXED_ANSI mode)
-# 08-JAN-1996 19:08 by Chr. Spieler (updated header dependencies)
-# 16-JAN-1996 19:08 by Chr. Spieler (crypt -> crypt & ttyio)
-# 25-JUL-1997 22:25 by Chr. Spieler (syncronized with descrip.mms)
-# 25-JUN-1998 23:53 by Chr. Spieler (removed bits.c source)
-
-
-########################### USER CUSTOMIZATION ############################
-# add any optional preprocessor flags (macros) to the following line
-# for a custom version (do not forget a trailing comma##):
-COMMON_DEFS =
-######################## END OF USER CUSTOMIZATION ########################
-
-#####################
-# MACRO DEFINITIONS #
-#####################
-
-CFLAGS = /NOLIST/INCL=(SYS$DISK:[])
-CC = cc
-LIB =
-# Define the macro __GNUC__ to use the GNU compiler (also add /undef=__STDC__
-# to CFLAGS, and possibly replace /obj=$@ [below] with copy/rename/delete
-# setup). NOT TESTED.
-
-OPTFILE = sys$disk:[.vms]vaxcshr.opt
-
-%IFDEF __ALPHA
-CC = CC/STANDARD=RELAX/PREFIX=ALL/ANSI
-E = .AXP_EXE
-O = .AXP_OBJ
-OPTFILE_LIST =
-OPTIONS =
-%ELSE
-%IFDEF __DECC__
-CC = CC/DECC/STANDARD=VAXC/PREFIX=ALL
-E = .VAX_DECC_exe
-O = .VAX_DECC_obj
-OPTFILE_LIST =
-OPTIONS =
-%ELSE
-%IFDEF __GNUC__
-CC = gcc
-E = .VAX_GNUC_exe
-O = .VAX_GNUC_obj
-LIB = gnu_cc:[000000]gcclib.olb/lib,
-%ELSE
-E = .VAX_VAXC_exe
-O = .VAX_VAXC_obj
-%ENDIF
-OPTFILE_LIST = ,$(OPTFILE)
-OPTIONS = ,$(OPTFILE)/OPTIONS
-%ENDIF
-%ENDIF
-
-CFLAGS_ALL = $(CFLAGS) /def=($(COMMON_DEFS) VMS)
-CFLAGS_CLI = $(CFLAGS) /def=($(COMMON_DEFS) VMSCLI, VMS)
-CFLAGS_UTIL = $(CFLAGS) /def=($(COMMON_DEFS) UTIL, VMS)
-LD = LINK
-LDFLAGS = /NOTRACE
-
-# object file lists
-OBJM = zip$O, zipcli$O
-OBJZ = crc32$O, crctab$O, crypt$O, ttyio$O,-
- zipfile$O, zipup$O, fileio$O, globals$O, util$O
-OBJV = vmszip$O, vms$O, vmsmunch$O
-OBJI = deflate$O, trees$O
-OBJU = zipfile_$O, fileio_$O, globals$O,-
- util_$O, vms_$O, vmsmunch$O
-OBJR = crctab$O, crypt_$O, ttyio$O
-OBJC = zipcloak$O, $(OBJR), $(OBJU)
-OBJN = zipnote$O, $(OBJU)
-OBJS = zipsplit$O, $(OBJU)
-
-ZIPX_UNX = zip
-ZIPX_CLI = zip_cli
-OBJSZIPLIB = $(OBJZ), $(OBJI), $(OBJV)
-OBJSZIP = zip$O, $(OBJSZIPLIB)
-OBJSCLI = zipcli$O, zip_cli$O, cmdline$O
-OBJSZIP_CLI = $(OBJSCLI), $(OBJSZIPLIB)
-ZIPHELP_UNX_RNH = [.vms]vms_zip.rnh
-ZIPHELP_CLI_RNH = [.vms]zip_cli.rnh
-
-ZIP_H = zip.h ziperr.h tailor.h [.vms]osdep.h
-
-ZIPS = $(ZIPX_UNX)$E $(ZIPX_CLI)$E zipcloak$E zipnote$E zipsplit$E
-ZIPHELPS = $(ZIPX_UNX).hlp $(ZIPX_CLI).hlp
-
-###############################################
-# BASIC COMPILE INSTRUCTIONS AND DEPENDENCIES #
-###############################################
-
-default : $(ZIPS) $(ZIPHELPS)
-
-
-# suffix rules
-*$O: *.c # `*.c' necessary?
- $(CC)$(CFLAGS_ALL)/OBJECT=$@ $<
-
-*.hlp: *.rnh
- runoff /out=$@ $<
-
-
-# executables makerules (trailing `$' makes line a data line)
-$(ZIPX_UNX)$E : $(OBJSZIP) $(OPTFILE_LIST)
- $(LD) $(LDFLAGS)/EXEC=$(ZIPX_UNX)$E $(OBJSZIP) $(LIB) $(OPTIONS)
-
-$(ZIPX_CLI)$E : $(OBJSZIP_CLI) $(OPTFILE_LIST)
- $(LD) $(LDFLAGS)/EXEC=$(ZIPX_CLI)$E $(OBJSZIP_CLI) $(LIB) $(OPTIONS)
-
-zipcloak$E : $(OBJC) $(OPTFILE_LIST)
- $(LD) $(LDFLAGS)/EXEC=ZIPCLOAK$E $(OBJC) $(LIB) $(OPTIONS)
-
-zipnote$E : $(OBJN) $(OPTFILE_LIST)
- $(LD) $(LDFLAGS)/EXEC=ZIPNOTE$E $(OBJN) $(LIB) $(OPTIONS)
-
-zipsplit$E : $(OBJS) $(OPTFILE_LIST)
- $(LD) $(LDFLAGS)/EXEC=ZIPSPLIT$E $(OBJS) $(LIB) $(OPTIONS)
-
-$(OPTFILE) :
- open/write tmp $(OPTFILE)
- write tmp "SYS$SHARE:VAXCRTL.EXE/SHARE"
- close tmp
-
-$(ZIPHELP_CLI_RNH) : [.vms]zip_cli.help
- set default [.vms]
- edit/tpu/nosection/nodisplay/command=cvthelp.tpu zip_cli.help
- set default [-]
-
-$(ZIPX_UNX).hlp : $(ZIPHELP_UNX_RNH)
- runoff /out=$@ $<
-
-$(ZIPX_CLI).hlp : $(ZIPHELP_CLI_RNH)
-
-# dependencies for zip, zipnote, zipcloak, and zipsplit
-vmszip$O : [.vms]vmszip.c [.vms]vmsmunch.h
- $(CC)$(CFLAGS_ALL)/OBJECT=vmszip$O [.vms]vmszip.c
-vms$O : [.vms]vms.c [.vms]vms_im.c [.vms]vms_pk.c \
- [.vms]vms.h [.vms]vmsdefs.h
- $(CC)$(CFLAGS_ALL)/OBJECT=vms$O [.vms]vms.c
-vmsmunch$O : [.vms]vmsmunch.c [.vms]vmsmunch.h [.vms]vmsdefs.h
- $(CC)$(CFLAGS_ALL)/OBJECT=vmsmunch$O [.vms]vmsmunch.c
-zipcli$O : zip.c [.vms]vmsmunch.h
- $(CC) $(CFLAGS_CLI) /OBJ=$(MMS$TARGET) $<
-cmdline$O : [.vms]cmdline.c $(ZIP_H) crypt.h revision.h
- $(CC) $(CFLAGS_CLI) /OBJ=$(MMS$TARGET) $<
-zip_cli$O : [.vms]zip_cli.cld
-
-crypt_$O : crypt.c crypt.h ttyio.h
- $(CC)$(CFLAGS_UTIL)/OBJECT=crypt_$O crypt.c
-zipfile_$O : zipfile.c [.vms]vmsmunch.h [.vms]vmsdefs.h
- $(CC)$(CFLAGS_UTIL)/OBJECT=zipfile_$O zipfile.c
-fileio_$O : fileio.c
- $(CC)$(CFLAGS_UTIL)/OBJECT=fileio_$O fileio.c
-util_$O : util.c
- $(CC)$(CFLAGS_UTIL)/OBJECT=util_$O util.c
-vms_$O : [.vms]vms.c [.vms]vms_im.c [.vms]vms_pk.c \
- [.vms]vms.h [.vms]vmsdefs.h
- $(CC)$(CFLAGS_UTIL)/OBJECT=vms_$O [.vms]vms.c
-
-$(OBJM) zipcloak$O zipnote$O zipsplit$O zipup$O : revision.h
-$(OBJM) zipcloak$O zipup$O crypt$O ttyio$O : crypt.h
-$(OBJM) zipcloak$O crypt$O ttyio$O : ttyio.h
-zipup$O : [.vms]zipup.h
-zipfile$O : [.vms]vmsmunch.h [.vms]vmsdefs.h
-zip$O : [.vms]vmsmunch.h
-$(OBJM) : $(ZIP_H)
-$(OBJZ) : $(ZIP_H)
-$(OBJI) : $(ZIP_H)
-$(OBJN) : $(ZIP_H)
-$(OBJS) : $(ZIP_H)
-$(OBJC) : $(ZIP_H)
-
-clean.com :
- @ open/write tmp $@
- @ write tmp "$!"
- @ write tmp "$! Clean.com -- procedure to delete files. It always returns success"
- @ write tmp "$! status despite any error or warnings. Also it extracts"
- @ write tmp "$! filename from MMS ""module=file"" format."
- @ write tmp "$!"
- @ write tmp "$ on control_y then goto ctly"
- @ write tmp "$ if p1.eqs."""" then exit 1"
- @ write tmp "$ i = -1"
- @ write tmp "$scan_list:"
- @ write tmp "$ i = i+1"
- @ write tmp "$ item = f$elem(i,"","",p1)"
- @ write tmp "$ if item.eqs."""" then goto scan_list"
- @ write tmp "$ if item.eqs."","" then goto done ! End of list"
- @ write tmp "$ item = f$edit(item,""trim"") ! Clean of blanks"
- @ write tmp "$ wild = f$elem(1,""="",item)"
- @ write tmp "$ show sym wild"
- @ write tmp "$ if wild.eqs.""="" then wild = f$elem(0,""="",item)"
- @ write tmp "$ vers = f$parse(wild,,,""version"",""syntax_only"")"
- @ write tmp "$ if vers.eqs."";"" then wild = wild - "";"" + "";*"""
- @ write tmp "$scan:"
- @ write tmp "$ f = f$search(wild)"
- @ write tmp "$ if f.eqs."""" then goto scan_list"
- @ write tmp "$ on error then goto err"
- @ write tmp "$ on warning then goto warn"
- @ write tmp "$ delete/log 'f'"
- @ write tmp "$warn:"
- @ write tmp "$err:"
- @ write tmp "$ goto scan"
- @ write tmp "$done:"
- @ write tmp "$ctly:"
- @ write tmp "$ exit 1"
- @ close tmp
-
-clean : clean.com
- @clean "$(OBJM)"
- @clean "$(OBJZ)"
- @clean "$(OBJI)"
- @clean "$(OBJV)"
- @clean "$(OBJU)"
- @clean "$(OBJR)"
- @clean "$(OBJN)"
- @clean "$(OBJS)"
- @clean "$(OBJC)"
- @clean "$(ZIPS)"
- @clean "$(ZIPHELP_CLI_RNH)"
- @clean "$(ZIPHELPS)"
- - delete/noconfirm/nolog clean.com;*
-
-
-# the backslash '\' is the continuation character if it occurs as
-# the last non-white character on the line.
-# the hyphen '-' is the DCL continuation character, so if it occurs
-# as the last non-white character on the line, the next line will
-# not have the dollar sign '$' prepended.
-
-
-################################
-# INDIVIDUAL MACHINE MAKERULES #
-################################
-
-generic : default # first try if unknown
-generic2 : default # second try if unknown
-vax : default
-vms : default
-
-all : $(ZIPS)
-zip : zip$E
-zipcloak : zipcloak$E
-zipnote : zipnote$E
-zipsplit : zipsplit$E
diff --git a/vms/mod_dep.com b/vms/mod_dep.com
new file mode 100644
index 0000000..bbc6d2d
--- /dev/null
+++ b/vms/mod_dep.com
@@ -0,0 +1,33 @@
+$! 3 March 2005. SMS.
+$!
+$! Info-ZIP VMS accessory procedure.
+$!
+$! Modify a dependencies file (P1), changing the object file name to
+$! P2.
+$! P3 = output file specification.
+$!
+$!
+$ prefix = f$edit( p3, "COLLAPSE")
+$!
+$! Strip any device:[directory] from P2.
+$!
+$ obj_name = f$parse( P2, , , "NAME", "SYNTAX_ONLY")+ -
+ f$parse( P2, , , "TYPE", "SYNTAX_ONLY")
+$!
+$ open /read /error = end_main deps_in 'p1'
+$ open /write /error = end_main deps_out 'p3'
+$ on error then goto loop_main_end
+$ loop_main_top:
+$ read /error = loop_main_end deps_in line
+$ line_reduced = f$edit( line, "COMPRESS, TRIM")
+$ colon = f$locate( " : ", line_reduced)
+$ line = obj_name+ f$extract( colon, 2000, line)
+$ write deps_out "''line'"
+$ goto loop_main_top
+$!
+$ loop_main_end:
+$ close deps_in
+$ close deps_out
+$!
+$ end_main:
+$!
diff --git a/vms/osdep.h b/vms/osdep.h
index 77aee44..d7a07a4 100644
--- a/vms/osdep.h
+++ b/vms/osdep.h
@@ -1,9 +1,9 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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 VMS
@@ -27,14 +27,61 @@
# define NO_FCNTL_H /* VAXC does not supply fcntl.h. */
#endif /* VAX C */
-#define NO_UNISTD_H
-
#define USE_CASE_MAP
-#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \
- procname(n, 1))
+#define PROCNAME(n) \
+ (((action == ADD) || (action == UPDATE) || (action == FRESHEN)) ? \
+ wild(n) : procname(n, filter_match_case))
+
+/* 2004-11-09 SMS.
+ Large file support.
+*/
+#ifdef LARGE_FILE_SUPPORT
+
+# define _LARGEFILE /* Define the pertinent macro. */
+
+/* LARGE_FILE_SUPPORT implies ZIP64_SUPPORT,
+ unless explicitly disabled by NO_ZIP64_SUPPORT.
+*/
+# ifdef NO_ZIP64_SUPPORT
+# ifdef ZIP64_SUPPORT
+# undef ZIP64_SUPPORT
+# endif /* def ZIP64_SUPPORT */
+# else /* def NO_ZIP64_SUPPORT */
+# ifndef ZIP64_SUPPORT
+# define ZIP64_SUPPORT
+# endif /* ndef ZIP64_SUPPORT */
+# endif /* def NO_ZIP64_SUPPORT */
+
+# define ZOFF_T_FORMAT_SIZE_PREFIX "ll"
+
+#else /* def LARGE_FILE_SUPPORT */
+
+# define ZOFF_T_FORMAT_SIZE_PREFIX "l"
+
+#endif /* def LARGE_FILE_SUPPORT */
+
+/* Need _LARGEFILE for types.h. */
#include <types.h>
+
+#ifdef __GNUC__
+#include <sys/types.h>
+#endif /* def __GNUC__ */
+
+/* Need types.h for off_t. */
+
+#ifdef LARGE_FILE_SUPPORT
+ typedef off_t zoff_t;
+ typedef unsigned long long uzoff_t;
+#else /* def LARGE_FILE_SUPPORT */
+ typedef long zoff_t;
+ typedef unsigned long uzoff_t;
+#endif /* def LARGE_FILE_SUPPORT */
+
#include <stat.h>
+
+typedef struct stat z_stat;
+
#include <unixio.h>
#if defined(__GNUC__) && !defined(ZCRYPT_INTERNAL)
@@ -48,6 +95,18 @@
# undef _MBCS /* Zip on VMS does not support MBCS */
#endif
+/* VMS is run on little-endian processors with 4-byte ints:
+ * enable the optimized CRC-32 code */
+#ifdef IZ_CRC_BE_OPTIMIZ
+# undef IZ_CRC_BE_OPTIMIZ
+#endif
+#if !defined(IZ_CRC_LE_OPTIMIZ) && !defined(NO_CRC_OPTIMIZ)
+# define IZ_CRC_LE_OPTIMIZ
+#endif
+#if !defined(IZ_CRCOPTIM_UNFOLDTBL) && !defined(NO_CRC_OPTIMIZ)
+# define IZ_CRCOPTIM_UNFOLDTBL
+#endif
+
#if !defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME)
# if (defined(__CRTL_VER) && (__CRTL_VER >= 70000000))
# define USE_EF_UT_TIME
@@ -61,12 +120,25 @@
# define VMS_PK_EXTRA 1 /* PK style VMS support is default */
#endif
-#define unlink delete
-#define NO_SYMLINK
+/* 2007-02-22 SMS.
+ * <unistd.h> is needed for symbolic link functions, so use it when the
+ * symbolic link criteria are met.
+ */
+#if defined(__VAX) || __CRTL_VER < 70301000
+# define NO_UNISTD_H
+# define NO_SYMLINKS
+#endif /* defined(__VAX) || __CRTL_VER < 70301000 */
+
+/* 2007-02-22 SMS. Use delete() when unlink() is not available. */
+#if defined(NO_UNISTD_H) || (__CRTL_VER < 70000000)
+# define unlink delete
+#endif /* defined(NO_UNISTD_H) || __CRTL_VER < 70000000) */
+
#define SSTAT vms_stat
#define EXIT(exit_code) vms_exit(exit_code)
#define RETURN(exit_code) return (vms_exit(exit_code), 1)
+
#ifdef __DECC
/* File open callback ID values. */
diff --git a/vms/stream_lf.fdl b/vms/stream_lf.fdl
new file mode 100644
index 0000000..ab0f907
--- /dev/null
+++ b/vms/stream_lf.fdl
@@ -0,0 +1,3 @@
+RECORD
+ Carriage_Control carriage_return
+ Format stream_lf
diff --git a/vms/unixio_gcc.h b/vms/unixio_gcc.h
new file mode 100644
index 0000000..05bc421
--- /dev/null
+++ b/vms/unixio_gcc.h
@@ -0,0 +1,27 @@
+/* 2004-12-12 SMS.
+ *
+ * Emergency replacement UNIXIO.H for GNU C, for use as needed.
+ * Install as GNU_CC_INCLUDE:[000000]UNIXIO.H
+ */
+
+#ifndef __UNIXIO_LOADED
+#define __UNIXIO_LOADED 1
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+
+#ifndef SEEK_SET
+# define SEEK_SET 0
+#endif /* ndef SEEK_SET */
+
+#ifndef SEEK_CUR
+# define SEEK_CUR 1
+#endif /* ndef SEEK_CUR */
+
+#ifndef SEEK_END
+# define SEEK_END 2
+#endif /* ndef SEEK_END */
+
+#endif /* ndef __UNIXIO_LOADED */
+
diff --git a/vms/unixlib_gcc.h b/vms/unixlib_gcc.h
new file mode 100644
index 0000000..eda4ed9
--- /dev/null
+++ b/vms/unixlib_gcc.h
@@ -0,0 +1,16 @@
+/* 2004-12-12 SMS.
+ *
+ * Emergency replacement UNIXLIB.H for GNU C, for use as needed.
+ * Install as GNU_CC_INCLUDE:[000000]UNIXLIB.H
+ */
+
+#ifndef __UNIXLIB_LOADED
+#define __UNIXLIB_LOADED 1
+
+#include <sys/types.h>
+#include <stdlib.h>
+
+typedef struct stat stat_t;
+
+#endif /* ndef __UNIXLIB_LOADED */
+
diff --git a/vms/vms.c b/vms/vms.c
index 440b866..1b194c6 100644
--- a/vms/vms.c
+++ b/vms/vms.c
@@ -1,9 +1,9 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*
@@ -15,7 +15,7 @@
* vms_stat() added - version of stat() that handles special
* case when end-of-file-block == 0
*
- * 2.3.1 11-oct-2004 SMS
+ * 3.0 11-oct-2004 SMS
* It would be nice to know why vms_stat() is needed. If EOF can't
* be trusted for a zero-length file, why trust it for any file?
* Anyway, I removed the (int) cast on ->st_size, which may now be
@@ -28,9 +28,10 @@
#ifdef VMS /* For VMS only ! */
-#define NO_ZIPUP_H /* prevent inclusion of vms/zipup.h */
+#define NO_ZIPUP_H /* Prevent full inclusion of vms/zipup.h. */
#include "zip.h"
+#include "zipup.h" /* Only partial. */
#include <stdio.h>
#include <string.h>
@@ -39,6 +40,7 @@
#include <fab.h> /* Needed only in old environments. */
#include <nam.h> /* Needed only in old environments. */
#include <starlet.h>
+#include <ssdef.h>
#include <stsdef.h>
/* On VAX, define Goofy VAX Type-Cast to obviate /standard = vaxc.
@@ -64,7 +66,7 @@
# include "vms.h"
-#else /* def UTIL */
+#else /* not UTIL */
/* Include the `VMS attributes' preserving file-io code. We distinguish
between two incompatible flavours of storing VMS attributes in the
@@ -84,7 +86,7 @@
#include "vms_pk.c"
#include "vms_im.c"
-#endif /* def UTIL */
+#endif /* not UTIL [else] */
#ifndef ERR
#define ERR(x) (((x)&1)==0)
@@ -94,13 +96,12 @@
#define NULL (void*)(0L)
#endif
-int vms_stat(file,s)
-char *file;
-stat_t *s;
+int vms_stat( char *file, stat_t *s)
{
int status;
int staterr;
struct FAB fab;
+ struct NAM_STRUCT nam;
struct XABFHC fhc;
/*
@@ -123,11 +124,21 @@ stat_t *s;
*/
fab = cc$rms_fab;
+ nam = CC_RMS_NAM;
fhc = cc$rms_xabfhc;
- fab.fab$l_fna = file;
- fab.fab$b_fns = strlen(file);
+ fab.FAB_NAM = &nam;
fab.fab$l_xab = (char*)(&fhc);
+#ifdef NAML$C_MAXRSS
+
+ fab.fab$l_dna = (char *) -1; /* Using NAML for default name. */
+ fab.fab$l_fna = (char *) -1; /* Using NAML for file name. */
+
+#endif /* def NAML$C_MAXRSS */
+
+ FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNA = file;
+ FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNS = strlen( file);
+
fab.fab$b_fac = FAB$M_GET;
status = sys$open(&fab);
@@ -151,49 +162,105 @@ stat_t *s;
return status;
}
+
+/*
+ * 2007-01-29 SMS.
+ *
+ * VMS Status Code Summary (See STSDEF.H for details.)
+ *
+ * Bits: 31:28 27:16 15:3 2:0
+ * Field: Control Facility Message Severity
+ *
+ * In the Control field, bits 31:29 are reserved. Bit 28 inhibits
+ * printing the message. In the Facility field, bit 27 means
+ * customer-defined (not HP-assigned, like us). In the Message field,
+ * bit 15 means facility-specific (which our messages are). The
+ * Severity codes are 0 = Warning, 1 = Success, 2 = Error, 3 = Info,
+ * 4 = Severe (fatal).
+ *
+ * Previous versions of Info-ZIP programs used a generic ("chosen (by
+ * experimentation)") Control+Facility code of 0x7FFF, which included
+ * some reserved control bits, the inhibit-printing bit, and the
+ * customer-defined bit.
+ *
+ * HP has now assigned official Facility names and corresponding
+ * Facility codes for the Info-ZIP products:
+ *
+ * Facility Name Facility Code
+ * IZ_UNZIP 1954 = 0x7A2
+ * IZ_ZIP 1955 = 0x7A3
+ *
+ * Now, unless the CTL_FAC_IZ_ZIP macro is defined at build-time, we
+ * will use the official Facility code.
+ *
+ */
+
+/* Official HP-assigned Info-ZIP Zip Facility code. */
+#define FAC_IZ_ZIP 1955 /* 0x7A3 */
+
+#ifndef CTL_FAC_IZ_ZIP
+ /*
+ * Default is inhibit-printing with the official Facility code.
+ */
+# define CTL_FAC_IZ_ZIP ((0x1 << 12)| FAC_IZ_ZIP)
+# define MSG_FAC_SPEC 0x8000 /* Facility-specific code. */
+#else /* ndef CTL_FAC_IZ_ZIP */
+ /* Use the user-supplied Control+Facility code for err or warn. */
+# define OLD_STATUS
+# ifndef MSG_FAC_SPEC /* Old default is not Facility-specific. */
+# define MSG_FAC_SPEC 0x0 /* Facility-specific code. Or 0x8000. */
+# endif /* ndef MSG_FAC_SPEC */
+#endif /* ndef CTL_FAC_IZ_ZIP [else] */
+
+
+/* Return an intelligent status/severity code. */
+
void vms_exit(e)
int e;
{
-/*---------------------------------------------------------------------------
- Return an intelligent status/severity level if RETURN_SEVERITY defined:
-
- $STATUS $SEVERITY = $STATUS & 7
- 31 .. 16 15 .. 3 2 1 0
- -----
- VMS 0 0 0 0 Warning
- FACILITY 0 0 1 1 Success
- Number 0 1 0 2 Error
- MESSAGE 0 1 1 3 Information
- Number 1 0 0 4 Severe (fatal) error
-
- 0x7FFF0000 was chosen (by experimentation) to be outside the range of
- VMS FACILITYs that have dedicated message numbers. Hopefully this will
- always result in silent exits--it does on VMS 5.4. Note that the C li-
- brary translates exit arguments of zero to a $STATUS value of 1 (i.e.,
- exit is both silent and has a $SEVERITY of "success").
- ---------------------------------------------------------------------------*/
{
- int severity;
-
- switch (e) { /* $SEVERITY: */
- case ZE_NONE:
- severity = 0; break; /* warning */
- case ZE_FORM:
- case ZE_BIG:
- case ZE_NOTE:
- case ZE_ABORT:
- case ZE_NAME:
- case ZE_PARMS:
- case ZE_OPEN:
- severity = 2; break; /* error */
- default:
- severity = 4; break; /* fatal */
- }
+#ifndef OLD_STATUS
- exit( /* $SEVERITY: */
- (e == ZE_OK) ? 1 : /* success */
- (0x7FFF0000 | (e << 4) | severity) /* warning, error, fatal */
+ /*
+ * Exit with code comprising Control, Facility, (facility-specific)
+ * Message, and Severity.
+ */
+ exit( (CTL_FAC_IZ_ZIP << 16) | /* Facility */
+ MSG_FAC_SPEC | /* Facility-specific */
+ (e << 4) | /* Message code */
+ (ziperrors[ e].severity & 0x07) /* Severity */
+ );
+
+#else /* ndef OLD_STATUS */
+
+ /* 2007-01-17 SMS.
+ * Defining OLD_STATUS provides the same behavior as in Zip versions
+ * before an official VMS Facility code had been assigned, which
+ * means that Success (ZE_OK) gives a status value of 1 (SS$_NORMAL)
+ * with no Facility code, while any error or warning gives a status
+ * value which includes a Facility code. (Curiously, under the old
+ * scheme, message codes were left-shifted by 4 instead of 3,
+ * resulting in all-even message codes.) I don't like this, but I
+ * was afraid to remove it, as someone, somewhere may be depending
+ * on it. Define CTL_FAC_IZ_ZIP as 0x7FFF to get the old behavior.
+ * Define only OLD_STATUS to get the old behavior for Success
+ * (ZE_OK), but using the official HP-assigned Facility code for an
+ * error or warning. Define MSG_FAC_SPEC to get the desired
+ * behavior.
+ *
+ * Exit with simple SS$_NORMAL for ZE_OK. Otherwise, exit with code
+ * comprising Control, Facility, Message, and Severity.
+ */
+ exit(
+ (e == ZE_OK) ? SS$_NORMAL : /* Success (others below) */
+ ((CTL_FAC_IZ_ZIP << 16) | /* Facility */
+ MSG_FAC_SPEC | /* Facility-specific (?) */
+ (e << 4) | /* Message code */
+ (ziperrors[ e].severity & 0x07) /* Severity */
+ )
);
+
+#endif /* ndef OLD_STATUS */
}
}
@@ -209,7 +276,7 @@ void version_local()
char *chrp1;
char *chrp2;
char buf[40];
- char vms_vers[16];
+ char vms_vers[ 16];
int ver_maj;
#endif
#ifdef __DECC_VER
@@ -226,10 +293,10 @@ void version_local()
/* Determine the major version number. */
ver_maj = 0;
- chrp1 = strchr( &vms_vers[1], '.');
- for (chrp2 = &vms_vers[1];
- chrp2 < chrp1;
- ver_maj = ver_maj * 10 + *(chrp2++) - '0');
+ chrp1 = strchr( &vms_vers[ 1], '.');
+ for (chrp2 = &vms_vers[ 1];
+ chrp2 < chrp1;
+ ver_maj = ver_maj* 10+ *(chrp2++)- '0');
#endif /* def VMS_VERSION */
@@ -265,7 +332,7 @@ void version_local()
# if defined( __alpha)
"OpenVMS",
(sprintf( buf, " (%s Alpha)", vms_vers), buf),
-# elif defined( __IA64) /* defined( __alpha) */
+# elif defined( __ia64) /* defined( __alpha) */
"OpenVMS",
(sprintf( buf, " (%s IA64)", vms_vers), buf),
# else /* defined( __alpha) */
@@ -304,51 +371,9 @@ void version_local()
* actually uses the directory part of the argument or "tempath".
*/
-/* Define macros for use with either NAM or NAML. */
-
-#ifdef NAML$C_MAXRSS /* NAML is available. Use it. */
-
-#define NAM_STRUCT NAML
-
-#define CC_RMS_NAM cc$rms_naml
-#define FAB_NAM fab$l_naml
-#define NAME nam
-#define NAME_DNA naml$l_long_defname
-#define NAME_DNS naml$l_long_defname_size
-#define NAME_FNA naml$l_long_filename
-#define NAME_FNS naml$l_long_filename_size
-#define NAM_ESA naml$l_long_expand
-#define NAM_ESL naml$l_long_expand_size
-#define NAM_ESS naml$l_long_expand_alloc
-#define NAM_MAXRSS NAML$C_MAXRSS
-#define NAM_NOP naml$b_nop
-#define NAM_TYPE naml$l_long_type
-#define NAM_M_SYNCHK NAML$M_SYNCHK
-
-#else /* def NAML$C_MAXRSS */ /* NAML is not available. Use NAM. */
-
-#define NAM_STRUCT NAM
-
-#define CC_RMS_NAM cc$rms_nam
-#define FAB_NAM fab$l_nam
-#define NAME fab
-#define NAME_DNA fab$l_dna
-#define NAME_DNS fab$b_dns
-#define NAME_FNA fab$l_fna
-#define NAME_FNS fab$b_fns
-#define NAM_ESA nam$l_esa
-#define NAM_ESL nam$l_esl
-#define NAM_ESS nam$b_ess
-#define NAM_MAXRSS NAM$C_MAXRSS
-#define NAM_NOP nam$b_nop
-#define NAM_TYPE nam$l_type
-#define NAM_M_SYNCHK NAM$M_SYNCHK
-
-#endif /* def NAML$C_MAXRSS */
-
-char *tempname( zip)
-char *zip; /* Path name of Zip archive. */
+char *tempname( char *zip)
+/* char *zip; */ /* Path name of Zip archive. */
{
char *temp_name; /* Return value. */
int sts; /* System service status. */
@@ -366,23 +391,23 @@ char *zip; /* Path name of Zip archive. */
} jpi_itm_lst = { sizeof( pid), JPI$_PID, &pid, &pid_len };
/* ZI<UNIQUE> name storage. */
- static char zip_tmp_nam[16] = "ZI<unique>.;";
+ static char zip_tmp_nam[ 16] = "ZI<unique>.;";
struct FAB fab; /* FAB structure. */
struct NAM_STRUCT nam; /* NAM[L] structure. */
- char exp_str[ NAM_MAXRSS + 1]; /* Expanded name storage. */
+ char exp_str[ NAM_MAXRSS+ 1]; /* Expanded name storage. */
#ifdef VMS_UNIQUE_TEMP_BY_TIME
/* Use alternate time-based scheme to generate a unique temporary name. */
- sprintf( &zip_tmp_nam[2], "%08X", time( NULL));
+ sprintf( &zip_tmp_nam[ 2], "%08X", time( NULL));
#else /* def VMS_UNIQUE_TEMP_BY_TIME */
/* Use the process ID to generate a unique temporary name. */
sts = sys$getjpiw( 0, 0, 0, &jpi_itm_lst, 0, 0, 0);
- sprintf( &zip_tmp_nam[2], "%08X", pid);
+ sprintf( &zip_tmp_nam[ 2], "%08X", pid);
#endif /* def VMS_UNIQUE_TEMP_BY_TIME */
@@ -407,11 +432,13 @@ char *zip; /* Path name of Zip archive. */
#endif /* def NAML$C_MAXRSS */
- NAME.NAME_DNA = zip; /* Default name = Zip archive name. */
- NAME.NAME_DNS = strlen( NAME.NAME_DNA);
+ /* Default name = Zip archive name. */
+ FAB_OR_NAML( fab, nam).FAB_OR_NAML_DNA = zip;
+ FAB_OR_NAML( fab, nam).FAB_OR_NAML_DNS = strlen( zip);
- NAME.NAME_FNA = zip_tmp_nam; /* File name = "ZI<unique>,;". */
- NAME.NAME_FNS = strlen( NAME.NAME_FNA);
+ /* File name = "ZI<unique>,;". */
+ FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNA = zip_tmp_nam;
+ FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNS = strlen( zip_tmp_nam);
nam.NAM_ESA = exp_str; /* Expanded name (result) storage. */
nam.NAM_ESS = NAM_MAXRSS; /* Size of expanded name storage. */
@@ -424,12 +451,12 @@ char *zip; /* Path name of Zip archive. */
if ((sts& STS$M_SEVERITY) == STS$M_SUCCESS)
{
/* Overlay any resulting file type (typically ".ZIP") with none. */
- strcpy( nam.NAM_TYPE, ".;");
+ strcpy( nam.NAM_L_TYPE, ".;");
/* Allocate temp name storage (as caller expects), and copy the
(truncated) temp name into the new location.
*/
- temp_name = malloc( strlen( nam.NAM_ESA) + 1);
+ temp_name = malloc( strlen( nam.NAM_ESA)+ 1);
if (temp_name != NULL)
{
@@ -437,7 +464,174 @@ char *zip; /* Path name of Zip archive. */
}
}
return temp_name;
-} /* tempname() for VMS */
+} /* tempname() for VMS. */
+
+
+/* 2005-02-17 SMS.
+ *
+ * ziptyp() for VMS.
+ *
+ * Generate a real Zip archive file name (exact, if it exists), using
+ * a default file name.
+ *
+ * 2005-02-17 SMS. Moved to here from [-]ZIPFILE.C, to segregate
+ * better the RMS stuff.
+ *
+ * Before 2005-02-17, if sys$parse() failed, ziptyp() returned a null
+ * string ("&zero", where "static char zero = '\0';"). This
+ * typically caused Zip to proceed, but then the final rename() of
+ * the temporary archive would (silently) fail (null file name, after
+ * all), leaving only the temporary archive file, and providing no
+ * warning message to the victim. Now, when sys$parse() fails,
+ * ziptyp() returns the original string, so a later open() fails, and
+ * a relatively informative message is provided. (A VMS-specific
+ * message could also be provided here, if desired.)
+ *
+ * 2005-09-16 SMS.
+ * Changed name parsing in ziptyp() to solve a problem with a
+ * search-list logical name device-directory spec for the zipfile.
+ * Previously, when the zipfile did not exist (so sys$search()
+ * failed), the expanded name was used, but as it was
+ * post-sys$search(), it was based on the _last_ member of the search
+ * list instead of the first. Now, the expanded name from the
+ * original sys$parse() (pre-sys$search()) is retained, and it is
+ * used if sys$search() fails. This name is based on the first
+ * member of the search list, as a user might expect.
+ */
+
+/* Default Zip archive file spec. */
+#define DEF_DEVDIRNAM "SYS$DISK:[].zip"
+
+char *ziptyp( char *s)
+{
+ int status;
+ int exp_len;
+ struct FAB fab;
+ struct NAM_STRUCT nam;
+ char result[ NAM_MAXRSS+ 1];
+ char exp[ NAM_MAXRSS+ 1];
+ char *p;
+
+ fab = cc$rms_fab; /* Initialize FAB. */
+ nam = CC_RMS_NAM; /* Initialize NAM[L]. */
+ fab.FAB_NAM = &nam; /* FAB -> NAM[L] */
+
+#ifdef NAML$C_MAXRSS
+
+ fab.fab$l_dna =(char *) -1; /* Using NAML for default name. */
+ fab.fab$l_fna = (char *) -1; /* Using NAML for file name. */
+
+#endif /* def NAML$C_MAXRSS */
+
+ /* Argument file name and length. */
+ FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNA = s;
+ FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNS = strlen( s);
+
+ /* Default file spec and length. */
+ FAB_OR_NAML( fab, nam).FAB_OR_NAML_DNA = DEF_DEVDIRNAM;
+ FAB_OR_NAML( fab, nam).FAB_OR_NAML_DNS = sizeof( DEF_DEVDIRNAM)- 1;
+
+ nam.NAM_ESA = exp; /* Expanded name, */
+ nam.NAM_ESS = NAM_MAXRSS; /* storage size. */
+ nam.NAM_RSA = result; /* Resultant name, */
+ nam.NAM_RSS = NAM_MAXRSS; /* storage size. */
+
+ status = sys$parse(&fab);
+ if ((status & 1) == 0)
+ {
+ /* Invalid file name. Return (re-allocated) original, and hope
+ for a later error message.
+ */
+ if ((p = malloc( strlen( s)+ 1)) != NULL )
+ {
+ strcpy( p, s);
+ }
+ return p;
+ }
+
+ /* Save expanded name length from sys$parse(). */
+ exp_len = nam.NAM_ESL;
+
+ /* Leave expanded name as-is, in case of search failure. */
+ nam.NAM_ESA = NULL; /* Expanded name, */
+ nam.NAM_ESS = 0; /* storage size. */
+
+ status = sys$search(&fab);
+ if (status & 1)
+ { /* Zip file exists. Use resultant (complete, exact) name. */
+ if ((p = malloc( nam.NAM_RSL+ 1)) != NULL )
+ {
+ result[ nam.NAM_RSL] = '\0';
+ strcpy( p, result);
+ }
+ }
+ else
+ { /* New Zip file. Use pre-search expanded name. */
+ if ((p = malloc( exp_len+ 1)) != NULL )
+ {
+ exp[ exp_len] = '\0';
+ strcpy( p, exp);
+ }
+ }
+ return p;
+} /* ziptyp() for VMS. */
+
+
+/* 2005-12-30 SMS.
+ *
+ * vms_file_version().
+ *
+ * Return the ";version" part of a VMS file specification.
+ */
+
+char *vms_file_version( char *s)
+{
+ int status;
+ struct FAB fab;
+ struct NAM_STRUCT nam;
+ char *p;
+
+ static char exp[ NAM_MAXRSS+ 1]; /* Expanded name storage. */
+
+
+ fab = cc$rms_fab; /* Initialize FAB. */
+ nam = CC_RMS_NAM; /* Initialize NAM[L]. */
+ fab.FAB_NAM = &nam; /* FAB -> NAM[L] */
+
+#ifdef NAML$C_MAXRSS
+
+ fab.fab$l_dna =(char *) -1; /* Using NAML for default name. */
+ fab.fab$l_fna = (char *) -1; /* Using NAML for file name. */
+
+#endif /* def NAML$C_MAXRSS */
+
+ /* Argument file name and length. */
+ FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNA = s;
+ FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNS = strlen( s);
+
+ nam.NAM_ESA = exp; /* Expanded name, */
+ nam.NAM_ESS = NAM_MAXRSS; /* storage size. */
+
+ nam.NAM_NOP = NAM_M_SYNCHK; /* Syntax-only analysis. */
+
+ status = sys$parse(&fab);
+
+ if ((status & 1) == 0)
+ {
+ /* Invalid file name. Return "". */
+ exp[ 0] = '\0';
+ p = exp;
+ }
+ else
+ {
+ /* Success. NUL-terminate, and return a pointer to the ";" in
+ the expanded name storage buffer.
+ */
+ p = nam.NAM_L_VER;
+ p[ nam.NAM_B_VER] = '\0';
+ }
+ return p;
+} /* vms_file_version(). */
/* 2004-11-23 SMS.
@@ -452,7 +646,7 @@ char *zip; /* Path name of Zip archive. */
* rab$b_mbf multi-buffer count (used with rah and wbh).
*/
-#define DIAG_FLAG verbose
+#define DIAG_FLAG (verbose >= 2)
/* Default RMS parameter values. */
@@ -608,6 +802,8 @@ int fopm_id = FOPM_ID; /* Callback id storage, modify. */
int fopr_id = FOPR_ID; /* Callback id storage, read. */
int fopw_id = FOPW_ID; /* Callback id storage, write. */
+int fhow_id = FHOW_ID; /* Callback id storage, in read. */
+
/* acc_cb() */
int acc_cb( int *id_arg, struct FAB *fab, struct RAB *rab)
@@ -707,8 +903,6 @@ decc_feat_t decc_feat_array[] = {
/* Preserve command-line case with SET PROCESS/PARSE_STYLE=EXTENDED */
{ "DECC$ARGV_PARSE_STYLE", 1 },
-#if 0 /* Possibly useful in the future. */
-
/* Preserve case for file names on ODS5 disks. */
{ "DECC$EFS_CASE_PRESERVE", 1 },
@@ -716,8 +910,6 @@ decc_feat_t decc_feat_array[] = {
while preserving VMS-ness of ";version". */
{ "DECC$EFS_CHARSET", 1 },
-#endif /* 0 */
-
/* List terminator. */
{ (char *)NULL, 0 } };
@@ -738,10 +930,10 @@ decc_init_done = 1;
/* Loop through all items in the decc_feat_array[]. */
-for (i = 0; decc_feat_array[i].name != NULL; i++)
+for (i = 0; decc_feat_array[ i].name != NULL; i++)
{
/* Get the feature index. */
- feat_index = decc$feature_get_index( decc_feat_array[i].name);
+ feat_index = decc$feature_get_index( decc_feat_array[ i].name);
if (feat_index >= 0)
{
/* Valid item. Collect its properties. */
@@ -749,29 +941,29 @@ for (i = 0; decc_feat_array[i].name != NULL; i++)
feat_value_min = decc$feature_get_value( feat_index, 2);
feat_value_max = decc$feature_get_value( feat_index, 3);
- if ((decc_feat_array[i].value >= feat_value_min) &&
- (decc_feat_array[i].value <= feat_value_max))
+ if ((decc_feat_array[ i].value >= feat_value_min) &&
+ (decc_feat_array[ i].value <= feat_value_max))
{
/* Valid value. Set it if necessary. */
- if (feat_value != decc_feat_array[i].value)
+ if (feat_value != decc_feat_array[ i].value)
{
sts = decc$feature_set_value( feat_index,
1,
- decc_feat_array[i].value);
+ decc_feat_array[ i].value);
}
}
else
{
/* Invalid DECC feature value. */
printf( " INVALID DECC FEATURE VALUE, %d: %d <= %s <= %d.\n",
- feat_value,
- feat_value_min, decc_feat_array[i].name, feat_value_max);
+ feat_value,
+ feat_value_min, decc_feat_array[ i].name, feat_value_max);
}
}
else
{
/* Invalid DECC feature name. */
- printf( " UNKNOWN DECC FEATURE: %s.\n", decc_feat_array[i].name);
+ printf( " UNKNOWN DECC FEATURE: %s.\n", decc_feat_array[ i].name);
}
}
}
@@ -780,20 +972,28 @@ for (i = 0; decc_feat_array[i].name != NULL; i++)
#pragma nostandard
-/* Establish the LIB$INITIALIZE PSECT, with proper alignment and
- attributes.
+/* Establish the LIB$INITIALIZE PSECTs, with proper alignment and
+ other attributes. Note that "nopic" is significant only on VAX.
*/
-globaldef { "LIB$INITIALIZ" } readonly _align (LONGWORD)
- int spare[8] = { 0 };
-globaldef { "LIB$INITIALIZE" } readonly _align (LONGWORD)
- void (*x_decc_init)() = decc_init;
+#pragma extern_model save
+
+#pragma extern_model strict_refdef "LIB$INITIALIZ" 2, nopic, nowrt
+const int spare[ 8] = { 0 };
+
+#pragma extern_model strict_refdef "LIB$INITIALIZE" 2, nopic, nowrt
+void (*const x_decc_init)() = decc_init;
+
+#pragma extern_model restore
/* Fake reference to ensure loading the LIB$INITIALIZE PSECT. */
#pragma extern_model save
-int lib$initialize(void);
+
+int LIB$INITIALIZE( void);
+
#pragma extern_model strict_refdef
-int dmy_lib$initialize = (int) lib$initialize;
+int dmy_lib$initialize = (int) LIB$INITIALIZE;
+
#pragma extern_model restore
#pragma standard
diff --git a/vms/vms.h b/vms/vms.h
index 778f616..8685fdd 100644
--- a/vms/vms.h
+++ b/vms/vms.h
@@ -1,9 +1,9 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*---------------------------------------------------------------------------
@@ -69,6 +69,87 @@
#undef variant_union
+/* 2005-02-08 SMS. Moved NAM[L] macros here from VMS.C. */
+
+/* Define macros for use with either NAM or NAML. */
+
+#ifdef NAML$C_MAXRSS /* NAML is available. Use it. */
+
+# define NAM_STRUCT NAML
+
+# define FAB_OR_NAML( fab, nam) nam
+# define FAB_OR_NAML_DNA naml$l_long_defname
+# define FAB_OR_NAML_DNS naml$l_long_defname_size
+# define FAB_OR_NAML_FNA naml$l_long_filename
+# define FAB_OR_NAML_FNS naml$l_long_filename_size
+
+# define CC_RMS_NAM cc$rms_naml
+# define FAB_NAM fab$l_naml
+# define NAM_DID naml$w_did
+# define NAM_DVI naml$t_dvi
+# define NAM_ESA naml$l_long_expand
+# define NAM_ESL naml$l_long_expand_size
+# define NAM_ESS naml$l_long_expand_alloc
+# define NAM_FID naml$w_fid
+# define NAM_FNB naml$l_fnb
+# define NAM_RSA naml$l_long_result
+# define NAM_RSL naml$l_long_result_size
+# define NAM_RSS naml$l_long_result_alloc
+# define NAM_MAXRSS NAML$C_MAXRSS
+# define NAM_NOP naml$b_nop
+# define NAM_M_EXP_DEV NAML$M_EXP_DEV
+# define NAM_M_SYNCHK NAML$M_SYNCHK
+# define NAM_B_DEV naml$l_long_dev_size
+# define NAM_L_DEV naml$l_long_dev
+# define NAM_B_DIR naml$l_long_dir_size
+# define NAM_L_DIR naml$l_long_dir
+# define NAM_B_NAME naml$l_long_name_size
+# define NAM_L_NAME naml$l_long_name
+# define NAM_B_TYPE naml$l_long_type_size
+# define NAM_L_TYPE naml$l_long_type
+# define NAM_B_VER naml$l_long_ver_size
+# define NAM_L_VER naml$l_long_ver
+
+#else /* def NAML$C_MAXRSS */ /* NAML is not available. Use NAM. */
+
+# define NAM_STRUCT NAM
+
+# define FAB_OR_NAML( fab, nam) fab
+# define FAB_OR_NAML_DNA fab$l_dna
+# define FAB_OR_NAML_DNS fab$b_dns
+# define FAB_OR_NAML_FNA fab$l_fna
+# define FAB_OR_NAML_FNS fab$b_fns
+
+# define CC_RMS_NAM cc$rms_nam
+# define FAB_NAM fab$l_nam
+# define NAM_DID nam$w_did
+# define NAM_DVI nam$t_dvi
+# define NAM_ESA nam$l_esa
+# define NAM_ESL nam$b_esl
+# define NAM_ESS nam$b_ess
+# define NAM_FID nam$w_fid
+# define NAM_FNB nam$l_fnb
+# define NAM_RSA nam$l_rsa
+# define NAM_RSL nam$b_rsl
+# define NAM_RSS nam$b_rss
+# define NAM_MAXRSS NAM$C_MAXRSS
+# define NAM_NOP nam$b_nop
+# define NAM_M_EXP_DEV NAM$M_EXP_DEV
+# define NAM_M_SYNCHK NAM$M_SYNCHK
+# define NAM_B_DEV nam$b_dev
+# define NAM_L_DEV nam$l_dev
+# define NAM_B_DIR nam$b_dir
+# define NAM_L_DIR nam$l_dir
+# define NAM_B_NAME nam$b_name
+# define NAM_L_NAME nam$l_name
+# define NAM_B_TYPE nam$b_type
+# define NAM_L_TYPE nam$l_type
+# define NAM_B_VER nam$b_ver
+# define NAM_L_VER nam$l_ver
+
+#endif /* def NAML$C_MAXRSS */
+
+
struct EB_header /* Common header of extra block */
{ ush tag;
ush size;
@@ -268,4 +349,6 @@ struct PK_header
#define PK_HEADER_SIZE 8
+char *vms_file_version( char *s);
+
#endif /* !__vms_h */
diff --git a/vms/vms_im.c b/vms/vms_im.c
index da84945..001088b 100644
--- a/vms/vms_im.c
+++ b/vms/vms_im.c
@@ -1,9 +1,9 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*
@@ -32,6 +32,8 @@
* regardless of appearances. Moved the VMS_PK_EXTRA test into
* here from VMS.C to allow more general automatic dependency
* generation.
+ * 17-Feb-2005 Steven Schweda
+ * Added support for ODS5 extended names.
*/
#ifdef VMS /* For VMS only ! */
@@ -111,6 +113,7 @@ int set_extra_field(z, z_utim)
uch *scan;
extent extra_l;
static struct FAB fab;
+ static struct NAM_STRUCT nam;
static struct XABSUM xabsum;
static struct XABFHC xabfhc;
static struct XABDAT xabdat;
@@ -171,19 +174,45 @@ int set_extra_field(z, z_utim)
*/
fab = cc$rms_fab;
+ nam = CC_RMS_NAM;
xabsum = cc$rms_xabsum;
xabdat = cc$rms_xabdat;
xabfhc = cc$rms_xabfhc;
xabpro = cc$rms_xabpro;
xabrdt = cc$rms_xabrdt;
-
+ fab.FAB_NAM = &nam;
fab.fab$l_xab = (char*)&xabsum;
/*
* Open the file and read summary information.
*/
- fab.fab$b_fns = strlen(z->name);
- fab.fab$l_fna = z->name;
+
+#ifdef NAML$C_MAXRSS
+
+ fab.fab$l_dna = (char *) -1; /* Using NAML for default name. */
+ fab.fab$l_fna = (char *) -1; /* Using NAML for file name. */
+
+#endif /* def NAML$C_MAXRSS */
+
+ FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNA = z->name;
+ FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNS = strlen( z->name);
+
+#ifdef NAML$M_OPEN_SPECIAL
+ /* 2007-02-28 SMS.
+ * If processing symlinks as symlinks ("-y"), then $OPEN the
+ * link, not the target file.
+ *
+ * (nam.naml$v_open_special gets us the symlink itself instead of
+ * its target. fab.fab$v_bio is necessary to allow sys$open() to
+ * work. Without it, you get status %x0001860c, "%RMS-F-ORG,
+ * invalid file organization value".)
+ */
+ if (linkput)
+ {
+ nam.naml$v_open_special = 1;
+ fab.fab$v_bio = 1;
+ }
+#endif /* def NAML$M_OPEN_SPECIAL */
status = sys$open(&fab);
if (ERR(status))
@@ -319,10 +348,13 @@ int set_extra_field(z, z_utim)
fab.fab$b_fns = fab.fab$b_shr = fab.fab$b_dns = fab.fab$b_fac = 0;
fab.fab$w_ifi = 0;
fab.fab$l_stv = fab.fab$l_sts = fab.fab$l_ctx = 0;
+ fab.fab$l_dna = NULL;
fab.fab$l_fna = NULL;
fab.fab$l_nam = NULL;
+#ifdef NAML$C_MAXRSS
+ fab.fab$l_naml = NULL;
+#endif /* def NAML$C_MAXRSS */
fab.fab$l_xab = NULL;
- fab.fab$l_dna = NULL;
#ifdef DEBUG
dump_rms_block( (uch *)&fab );
@@ -375,10 +407,10 @@ int set_extra_field(z, z_utim)
}
/* Copy xtra[] data into cxtra[]. */
- memcpy( cxtra, xtra, (scan - xtra));
+ memcpy( cxtra, xtra, (scan- xtra));
/* Set sizes and pointers. */
- z->cext = z->ext = scan - xtra;
+ z->cext = z->ext = scan- xtra;
z->extra = (char*) xtra;
z->cextra = (char*) cxtra;
@@ -433,9 +465,10 @@ typedef struct user_context
{
ulg sig;
struct FAB *fab;
+ struct NAM_STRUCT *nam;
struct RAB *rab;
- unsigned int size;
- unsigned int rest;
+ uzoff_t size;
+ uzoff_t rest;
int status;
} Ctx, *Ctxptr;
@@ -444,6 +477,7 @@ Ctx init_ctx =
CTXSIG,
NULL,
NULL,
+ NULL,
0L,
0L,
0
@@ -465,46 +499,83 @@ Ctx init_ctx =
struct RAB *vms_open(name)
char *name;
{
- struct RAB *rab;
struct FAB *fab;
+ struct NAM_STRUCT *nam;
+ struct RAB *rab;
struct XABFHC *fhc;
Ctxptr ctx;
- if ((fab = (struct FAB *) malloc(FABL)) == (struct FAB *)NULL)
+ if ((fab = (struct FAB *) malloc(FABL)) == NULL)
return NULL;
- if ((rab = (struct RAB *) malloc(RABL)) == (struct RAB *)NULL)
+
+ if ((nam =
+ (struct NAM_STRUCT *) malloc( sizeof( struct NAM_STRUCT))) == NULL)
{
free(fab);
- return (struct RAB *)NULL;
+ return NULL;
+ }
+
+ if ((rab = (struct RAB *) malloc(RABL)) == NULL)
+ {
+ free(fab);
+ free(nam);
+ return NULL;
}
+
if ((fhc = (struct XABFHC *) malloc(XFHCL)) == (struct XABFHC *)NULL)
{
- free(rab);
free(fab);
+ free(nam);
+ free(rab);
return (struct RAB *)NULL;
}
if ((ctx = (Ctxptr) malloc(CTXL)) == (Ctxptr)NULL)
{
- free(fhc);
free(fab);
+ free(nam);
free(rab);
+ free(fhc);
return (struct RAB *)NULL;
}
*fab = cc$rms_fab;
+ *nam = CC_RMS_NAM;
*rab = cc$rms_rab;
*fhc = cc$rms_xabfhc;
- fab->fab$l_fna = name;
- fab->fab$b_fns = strlen(name);
+ fab->FAB_NAM = nam;
+
+#ifdef NAML$C_MAXRSS
+
+ fab->fab$l_dna = (char *) -1; /* Using NAML for default name. */
+ fab->fab$l_fna = (char *) -1; /* Using NAML for file name. */
+
+#endif /* def NAML$C_MAXRSS */
+
+ FAB_OR_NAML( fab, nam)->FAB_OR_NAML_FNA = name;
+ FAB_OR_NAML( fab, nam)->FAB_OR_NAML_FNS = strlen( name);
+
fab->fab$b_fac = FAB$M_GET | FAB$M_BIO;
fab->fab$l_xab = (char*)fhc;
+#ifdef NAML$M_OPEN_SPECIAL
+ /* 2007-02-28 SMS.
+ * If processing symlinks as symlinks ("-y"), then $OPEN the
+ * link, not the target file. (Note that here the required
+ * fab->fab$v_bio flag was set above.)
+ */
+ if (linkput)
+ {
+ nam->naml$v_open_special = 1;
+ }
+#endif /* def NAML$M_OPEN_SPECIAL */
+
if (ERR(sys$open(fab)))
{
sys$close(fab);
- free(fhc);
free(fab);
+ free(nam);
free(rab);
+ free(fhc);
free(ctx);
return (struct RAB *)NULL;
}
@@ -516,14 +587,16 @@ struct RAB *vms_open(name)
{
sys$close(fab);
free(fab);
+ free(nam);
free(rab);
free(ctx);
return (struct RAB *)NULL;
}
*ctx = init_ctx;
- ctx->rab = rab;
ctx->fab = fab;
+ ctx->nam = nam;
+ ctx->rab = rab;
if (fhc->xab$l_ebk == 0)
{
@@ -531,7 +604,7 @@ struct RAB *vms_open(name)
(This occurs with a zero-length file, for example.)
*/
ctx->size =
- ctx->rest = (fhc->xab$l_hbk) * BLOCK_BYTES;
+ ctx->rest = ((uzoff_t) fhc->xab$l_hbk)* BLOCK_BYTES;
}
else
{
@@ -540,11 +613,11 @@ struct RAB *vms_open(name)
If -VV, store allocated-blocks size in ->rest.
*/
ctx->size =
- ((fhc->xab$l_ebk)- 1) * BLOCK_BYTES + fhc->xab$w_ffb;
+ (((uzoff_t) fhc->xab$l_ebk)- 1)* BLOCK_BYTES+ fhc->xab$w_ffb;
if (vms_native < 2)
ctx->rest = ctx->size;
else
- ctx->rest = (fhc->xab$l_hbk) * BLOCK_BYTES;
+ ctx->rest = ((uzoff_t) fhc->xab$l_hbk)* BLOCK_BYTES;
}
free(fhc);
@@ -560,14 +633,17 @@ int vms_close(rab)
struct RAB *rab;
{
struct FAB *fab;
+ struct NAM_STRUCT *nam;
Ctxptr ctx;
if (!CHECK_RAB(rab))
return RET_ERROR;
fab = (ctx = (Ctxptr)(rab->rab$l_ctx))->fab;
+ nam = (ctx = (Ctxptr)(rab->rab$l_ctx))->nam;
sys$close(fab);
free(fab);
+ free(nam);
free(rab);
free(ctx);
@@ -600,8 +676,8 @@ int vms_rewind(rab)
}
-#define KByte (2 * BLOCK_BYTES)
-#define MAX_READ_BYTES (32 * KByte)
+#define KByte (2* BLOCK_BYTES)
+#define MAX_READ_BYTES (32* KByte)
/**************************
* Function vms_read *
@@ -647,7 +723,7 @@ size_t size;
/* Round odd-ball request up to the next whole block.
This really should never happen. (assert()?)
*/
- size = (size + BLOCK_BYTES - 1)& ~(BLOCK_BYTES - 1);
+ size = (size+ BLOCK_BYTES- 1)& ~(BLOCK_BYTES- 1);
}
/* Reduce "size" when next (last) read would overrun the EOF,
diff --git a/vms/vms_msg_gen.c b/vms/vms_msg_gen.c
new file mode 100644
index 0000000..4599cb0
--- /dev/null
+++ b/vms/vms_msg_gen.c
@@ -0,0 +1,91 @@
+/*
+ * VMS Message Source File Generator.
+ *
+ * 2007-01-29 SMS.
+ *
+ * Generates a VMS error message source file from data in "ziperr.h".
+ *
+ * On a VMS system, the standard builders should do the work. On a
+ * non-VMS system:
+ *
+ * cc -I. vms/vms_msg_gen.c -o vms_msg_gen
+ * ./vms_msg_gen > vms/zip_msg.msg
+ * rm ./vms_msg_gen
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#define GLOBALS /* Include data for ziperrors[] in ziperr.h. */
+#include "ziperr.h"
+
+main()
+{
+ int base_prev;
+ int code_vms;
+ int code_zip;
+ int i;
+
+ char *sev_str[ 8] = {
+ "/WARNING",
+ "/SUCCESS",
+ "/ERROR",
+ "/INFORMATIONAL",
+ "/FATAL",
+ "/??????",
+ "/???????",
+ "/????????"
+ };
+
+ char *text1[] = {
+"! VMS Error Message Source File for Zip",
+"!",
+"! Because the facility code was formally assigned by HP, the .FACILITY",
+"! directive below specifies /SYSTEM. Because the messages are, in",
+"! general, specific to Zip, this file is not compiled with /SHARED.",
+"! For example:",
+"!",
+"! MESSAGE /OBJECT = [.dest]ZIP_MSG.OBJ /NOSYMBOLS [.VMS]ZIP_MSG.MSG",
+"!",
+"! LINK /SHAREABLE = [.dest]ZIP_MSG.EXE [.dest]ZIP_MSG.OBJ",
+"!",
+"!-----------------------------------------------------------------------",
+"",
+".TITLE Info-ZIP Zip Error Messages",
+".FACILITY IZ_ZIP, 1955 /SYSTEM",
+NULL /* End-of-text marker. */
+};
+
+ /* Initialize the .BASE counter. */
+ base_prev = -2;
+
+ /* Put out the header text. */
+ for (i = 0; text1[ i] != NULL; i++)
+ {
+ printf( "%s\n", text1[ i]);
+ }
+ printf( ".IDENT '%s'\n", VMS_MSG_IDENT);
+ printf( "\n");
+
+ /* Put out the error messages. */
+ for (code_zip = 0; code_zip <= ZE_MAXERR; code_zip++)
+ {
+ if ((ziperrors[ code_zip].string != NULL) &&
+ (strlen(ziperrors[ code_zip].string) != 0))
+ {
+ code_vms = 2* code_zip; /* 4-bit left-shift, not 3. */
+ if (code_vms != base_prev+ 1)
+ {
+ printf( ".BASE %d\n", code_vms);
+ }
+ printf( "%-7s %-13s <%s>\n",
+ ziperrors[ code_zip].name,
+ sev_str[ ziperrors[ code_zip].severity & 0x07],
+ ziperrors[ code_zip].string);
+ base_prev = code_vms;
+ }
+ }
+ /* Put out the .END directive. */
+ printf( "\n");
+ printf( ".END\n");
+}
diff --git a/vms/vms_pk.c b/vms/vms_pk.c
index d1467d3..9aa203d 100644
--- a/vms/vms_pk.c
+++ b/vms/vms_pk.c
@@ -1,9 +1,9 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*
@@ -53,13 +53,18 @@
* version 2.2-4 26-Jan-2002, Chr. Spieler
* Modified vms_read() to handle files larger than 2GByte
* (up to size limit of "unsigned long", resp. 4GByte).
- * version 2.3.1 20-Oct-2004, Steven Schweda.
+ * version 3.0 20-Oct-2004, Steven Schweda.
* Changed vms_read() to read all the allocated
* blocks in a file, for sure. Changed the default
* chunk size from 16K to 32K. Changed to use the
* new typedef for the ioctx structure. Moved the
* VMS_PK_EXTRA test into here from VMS.C to allow
* more general automatic dependency generation.
+ * 08-Feb-2005, SMS.
+ * Changed to accomodate ODS5 extended file names:
+ * NAM structure -> NAM[L], and so on. (VMS.H.)
+ * Added some should-never-appear error messages in
+ * vms_open().
*/
#ifdef VMS /* For VMS only ! */
@@ -72,6 +77,7 @@
#define VMS_ZIP
#endif
+#include "crc32.h"
#include "vms.h"
#include "vmsdefs.h"
@@ -105,8 +111,8 @@ typedef struct
{
struct iosb iosb;
long vbn;
- unsigned int size;
- unsigned int rest;
+ uzoff_t size;
+ uzoff_t rest;
int status;
ush chan;
ush chan_pad; /* alignment member */
@@ -118,8 +124,8 @@ typedef struct
/* Forward declarations of public functions: */
ioctx_t *vms_open(char *file);
-size_t vms_read(register ioctx_t *ctx,
- register char *buf, register size_t size);
+unsigned int vms_read(register ioctx_t *ctx,
+ register char *buf, register unsigned int size);
int vms_error(ioctx_t *ctx);
int vms_rewind(ioctx_t *ctx);
int vms_get_attributes(ioctx_t *ctx, struct zlist far *z,
@@ -141,23 +147,22 @@ ioctx_t *vms_open(file)
char *file;
{
static struct atrdef Atr[VMS_MAX_ATRCNT+1];
- static struct NAM Nam;
+ static struct NAM_STRUCT Nam;
static struct fibdef Fib;
static struct dsc$descriptor FibDesc =
{sizeof(Fib),DSC$K_DTYPE_Z,DSC$K_CLASS_S,(char *)&Fib};
static struct dsc$descriptor_s DevDesc =
- {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,&Nam.nam$t_dvi[1]};
- static struct dsc$descriptor_s FileName =
- {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
- static char EName[NAM$C_MAXRSS];
- static char RName[NAM$C_MAXRSS];
+ {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,&Nam.NAM_DVI[1]};
+ static char EName[NAM_MAXRSS];
+ static char RName[NAM_MAXRSS];
- struct FAB Fab;
+ struct FAB Fab;
register ioctx_t *ctx;
register struct fatdef *fat;
int status;
int i;
- ulg efblk, hiblk;
+ ulg efblk;
+ ulg hiblk;
if ( (ctx=(ioctx_t *)malloc(sizeof(ioctx_t))) == NULL )
return NULL;
@@ -187,50 +192,95 @@ char *file;
Atr[13].atr$w_size = 0;
Atr[13].atr$l_addr = GVTC NULL;
- /* initialize RMS structures, we need a NAM to retrieve the FID */
+ /* Initialize RMS structures. We need a NAM[L] to retrieve the FID. */
Fab = cc$rms_fab;
- Fab.fab$l_fna = file ; /* name of file */
- Fab.fab$b_fns = strlen(file);
- Fab.fab$l_nam = &Nam; /* FAB has an associated NAM */
- Nam = cc$rms_nam;
- Nam.nam$l_esa = EName; /* expanded filename */
- Nam.nam$b_ess = sizeof(EName);
- Nam.nam$l_rsa = RName; /* resultant filename */
- Nam.nam$b_rss = sizeof(RName);
-
- /* do $PARSE and $SEARCH here */
+ Nam = CC_RMS_NAM;
+ Fab.FAB_NAM = &Nam; /* FAB has an associated NAM[L]. */
+
+#ifdef NAML$C_MAXRSS
+
+ Fab.fab$l_dna =(char *) -1; /* Using NAML for default name. */
+ Fab.fab$l_fna = (char *) -1; /* Using NAML for file name. */
+
+#endif /* def NAML$C_MAXRSS */
+
+ FAB_OR_NAML( Fab, Nam).FAB_OR_NAML_FNA = file ; /* File name. */
+ FAB_OR_NAML( Fab, Nam).FAB_OR_NAML_FNS = strlen(file);
+ Nam.NAM_ESA = EName; /* expanded filename */
+ Nam.NAM_ESS = sizeof(EName);
+ Nam.NAM_RSA = RName; /* resultant filename */
+ Nam.NAM_RSS = sizeof(RName);
+
+ /* Do $PARSE and $SEARCH here. */
status = sys$parse(&Fab);
- if (!(status & 1)) return NULL;
- /* search for the first file.. If none signal error */
+ if (!(status & 1))
+ {
+ fprintf( stderr,
+ " vms_open(): $parse sts = %%x%08x.\n", status);
+ return NULL;
+ }
+
+#ifdef NAML$M_OPEN_SPECIAL
+ /* 2007-02-28 SMS.
+ * If processing symlinks as symlinks ("-y"), then $SEARCH for the
+ * link, not the target file.
+ */
+ if (linkput)
+ {
+ Nam.naml$v_open_special = 1;
+ }
+#endif /* def NAML$M_OPEN_SPECIAL */
+
+ /* Search for the first file. If none, signal error. */
status = sys$search(&Fab);
- if (!(status & 1)) return NULL;
- /* initialize Device name length, note that this points into the NAM
- to get the device name filled in by the $PARSE, $SEARCH services */
- DevDesc.dsc$w_length = Nam.nam$t_dvi[0];
+ if (!(status & 1))
+ {
+ fprintf( stderr,
+ " vms_open(): $search sts = %%x%08x.\n", status);
+ return NULL;
+ }
+
+ /* Initialize Device name length. Note that this points into the
+ NAM[L] to get the device name filled in by the $PARSE, $SEARCH
+ services.
+ */
+ DevDesc.dsc$w_length = Nam.NAM_DVI[0];
status = sys$assign(&DevDesc,&ctx->chan,0,0);
- if (!(status & 1)) return NULL;
- FileName.dsc$a_pointer = Nam.nam$l_name;
- FileName.dsc$w_length = Nam.nam$b_name+Nam.nam$b_type+Nam.nam$b_ver;
+ if (!(status & 1))
+ {
+ fprintf( stderr,
+ " vms_open(): $assign sts = %%x%08x.\n", status);
+ return NULL;
+ }
- /* Initialize the FIB */
+ /* Move the FID (and not the DID) into the FIB.
+ 2005=02-08 SMS.
+ Note that only the FID is needed, not the DID, and not the file
+ name. Setting these other items causes failures on ODS5.
+ */
Fib.FIB$L_ACCTL = FIB$M_NOWRITE;
- for (i=0;i<3;i++)
- Fib.FIB$W_FID[i]=Nam.nam$w_fid[i];
- for (i=0;i<3;i++)
- Fib.FIB$W_DID[i]=Nam.nam$w_did[i];
- /* Use the IO$_ACCESS function to return info about the file */
- status = sys$qiow( 0, ctx->chan, (IO$_ACCESS| IO$M_ACCESS),
- &ctx->iosb, 0, 0, &FibDesc, &FileName, 0, 0,
- Atr, 0);
+ for (i = 0; i < 3; i++)
+ {
+ Fib.FIB$W_FID[ i] = Nam.NAM_FID[ i];
+ Fib.FIB$W_DID[ i] = 0;
+ }
+
+ /* Use the IO$_ACCESS function to return info about the file. */
+ status = sys$qiow( 0, ctx->chan,
+ (IO$_ACCESS| IO$M_ACCESS), &ctx->iosb, 0, 0,
+ &FibDesc, 0, 0, 0, Atr, 0);
if (ERR(status) || ERR(status = ctx->iosb.status))
{
vms_close(ctx);
+ fprintf( stderr,
+ " vms_open(): $qiow (access) sts = %%x%08x, iosb sts = %%x%08x.\n",
+ status, ctx->iosb.status);
return NULL;
}
@@ -247,7 +297,7 @@ char *file;
(This occurs with a zero-length file, for example.)
*/
ctx -> size =
- ctx -> rest = hiblk * BLOCK_BYTES;
+ ctx -> rest = ((uzoff_t) hiblk)* BLOCK_BYTES;
}
else
{
@@ -256,12 +306,12 @@ char *file;
If multiple -V, store allocated-blocks size in ->rest.
*/
ctx -> size =
- ((efblk) - 1) * BLOCK_BYTES + fat -> fat$w_ffbyte;
+ (((uzoff_t) efblk)- 1)* BLOCK_BYTES+ fat -> fat$w_ffbyte;
if (vms_native < 2)
ctx -> rest = ctx -> size;
else
- ctx -> rest = hiblk * BLOCK_BYTES;
+ ctx -> rest = ((uzoff_t) hiblk)* BLOCK_BYTES;
}
ctx -> status = SS$_NORMAL;
@@ -270,8 +320,8 @@ char *file;
}
-#define KByte (2 * BLOCK_BYTES)
-#define MAX_READ_BYTES (32 * KByte)
+#define KByte (2* BLOCK_BYTES)
+#define MAX_READ_BYTES (32* KByte)
/*----------------*
| vms_read() |
@@ -288,9 +338,9 @@ char *buf;
size_t size;
{
int act_cnt;
- int rest_rndup;
+ uzoff_t rest_rndup;
int status;
- unsigned int bytes_read = 0;
+ size_t bytes_read = 0;
/* If previous read hit EOF, fail early. */
if (ctx -> status == SS$_ENDOFFILE)
@@ -447,12 +497,12 @@ iztimes *z_utim;
return ZE_OK; /* skip silently if no valid TZ info */
# endif
- if ((xtra = (uch *) malloc( EB_HEADSIZE + EB_UT_LEN( 1))) == NULL)
+ if ((xtra = (uch *) malloc( EB_HEADSIZE+ EB_UT_LEN( 1))) == NULL)
return ZE_MEM;
- if ((cxtra = (uch *) malloc( EB_HEADSIZE + EB_UT_LEN( 1))) == NULL)
+ if ((cxtra = (uch *) malloc( EB_HEADSIZE+ EB_UT_LEN( 1))) == NULL)
return ZE_MEM;
-
+
/* Fill xtra[] with data. */
xtra[ 0] = 'U';
xtra[ 1] = 'T';
@@ -465,10 +515,10 @@ iztimes *z_utim;
xtra[ 8] = (byte) (z_utim->mtime >> 24);
/* Copy xtra[] data into cxtra[]. */
- memcpy( cxtra, xtra, (EB_HEADSIZE + EB_UT_LEN( 1)));
+ memcpy( cxtra, xtra, (EB_HEADSIZE+ EB_UT_LEN( 1)));
/* Set sizes and pointers. */
- z->cext = z->ext = (EB_HEADSIZE + EB_UT_LEN( 1));
+ z->cext = z->ext = (EB_HEADSIZE+ EB_UT_LEN( 1));
z->extra = (char*) xtra;
z->cextra = (char*) cxtra;
@@ -485,10 +535,10 @@ iztimes *z_utim;
if (ctx->acllen > 0)
l += PK_FLDHDR_SIZE + ctx->acllen;
- if ((xtra = (uch *) malloc(l)) == NULL)
+ if ((xtra = (uch *) malloc( l)) == NULL)
return ZE_MEM;
- if ((cxtra = (uch *) malloc(l)) == NULL)
+ if ((cxtra = (uch *) malloc( l)) == NULL)
return ZE_MEM;
/* Fill xtra[] with data. */
diff --git a/vms/vms_zip.rnh b/vms/vms_zip.rnh
deleted file mode 100644
index c9599b0..0000000
--- a/vms/vms_zip.rnh
+++ /dev/null
@@ -1,548 +0,0 @@
-.!
-.! File: ZIP.RNH
-.!
-.! Author: Hunter Goatley
-.!
-.! Date: October 22, 1991
-.!
-.! Description:
-.!
-.! RUNOFF source file for portable ZIP on-line help for VMS.
-.! Adapted from MANUAL, distributed with ZIP.
-.!
-.! To build: $ RUNOFF ZIP.RNH
-.! $ LIBR/HELP/INSERT libr ZIP
-.!
-.! Modification history:
-.!
-.! Hunter Goatley 22-OCT-1991 20:45
-.! Genesis.
-.! Jean-loup Gailly 25 March 92
-.! Adaptation to zip 1.6.
-.! Igor Mandrichenko 9-JUN-1992
-.! Added explanation of -V option.
-.! Jean-loup Gailly 14 June 92
-.! Adaptation to zip 1.8.
-.! Jean-loup Gailly 20 Aug 92
-.! Adaptation to zip 1.9.
-.! Jean-loup Gailly 31 Aug 93
-.! Adaptation to zip 2.0.
-.! Christian Spieler 20 Sep 93
-.! Adaptation to zip 2.0 and OpenVMS completed.
-.! Christian Spieler 05 Dec 95
-.! Adaptation to zip 2.1, new options.
-.! Christian Spieler 20 Jan 96
-.! Changed -L and -v descriptions.
-.! Christian Spieler 11 Feb 96
-.! Added -X option.
-.! Onno van der Linden,
-.! Christian Spieler 13 Mar 96
-.! Removed -ee option.
-.! Christian Spieler 09 Feb 96
-.! Updated copyright notice, Zip version.
-.! Christian Spieler 21 Jul 97
-.! Added -P, -R, -i@, -x@ and -tt options, modified for Zip 2.2.
-.! Christian Spieler 14 Oct 97
-.! unified spelling of "Info-ZIP", final cleanups for 2.2.
-.!
-.noflags
-.lm4 .rm72
-.indent -4
-1 ZIP
-.br
-Zip is a compression and file packaging utility for Unix, MSDOS, OS/2, and
-VMS. It is analogous to a combination of tar and compress and is
-compatible with PKZIP (Phil Katz ZIP) for MSDOS systems.
-.sk
-There is a companion to Zip called UnZip (of course). Zip and UnZip can
-work with files produced by PKZIP under MSDOS, and PKZIP and PKUNZIP can
-work with files produced by Zip.
-.sk
-Zip 2.2 is compatible with PKZIP 2.04.
-Note that PKUNZIP 1.10 cannot extract files produced by PKZIP 2.04
-or zip 2.2. You must use PKZIP 2.04g or unzip 5.0p1 (or later versions)
-to extract them.
-.sk
-For a brief help on Zip and Unzip, run each without specifying any
-parameters on the command line.
-.sk
-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.
-.sk
-Zip puts one or more compressed files into a single "zip file", along with
-information about the files (name, path, date and time of last modification,
-protection, and check information to verify file integrity). Zip can pack
-an entire directory structure in a zip file with a single command.
-Compression ratios of 2:1 to 3:1 are common for text files. Zip has
-one compression method (deflation) and can also store files without
-compression. It automatically chooses the better of the two for each file
-to be compressed.
-.sk
-Format:
-.sk;.lm+1;.literal
-ZIP [-options] [-b path] [-n suffixes] [-t mmddyyyy] [-tt mmddyyyy]
- zipfile file(s) [-x list] [-i list]
-.end literal;.lm-1
-.!------------------------------------------------------------------------------
-.indent -4
-2 Options
-.br
-The default action of Zip is to add or replace zipfile entries from list, which
-can include the special name -@ to read names from SYS$INPUT. The following
-list of options was taken from the on-line help generated when Zip is run
-without any command-line parameters:
-.sk
-.literal
- -A adjust self-extracting exe
- -b use "path" for temp files
- -c add one-line comments
- -d delete entries in zipfile
- -D do not add directory entries
- -e encrypt
- -f freshen: only changed files
- -F fix zipfile (-FF try harder)
- -g allow growing existing zipfile (unless updating or deleting)
- -h show the zip help screen
- -i include only names matching the following patterns
- -i@ include only names matching the patterns in "file"
- -j junk (don't record) directory names
- -J junk (remove) prepended (SFX) stub
- -k simulate PKZIP made zipfile
- -l translate end-of-lines (LF -> CRLF)
- -ll translate end-of-lines (CRLF -> LF)
- -L show software license
- -m move into zipfile (delete files)
- -n don't compress theses suffixes
- -o make zipfile as old as latest entry
- -P encrypt with supplied "password" string
- -q quiet operation
- -r recurse into directories from specified path patterns
- -R recurse into subdirs from current dir, match filenames only
- -t only do files after "mmddyyyy"
- -tt only do files before "mmddyyyy"
- -T test zip file integrity (calls unzip)
- -u update: only changed or new files
- -v verbose messages/print version info
- -V save VMS file attributes
- -w append the VMS version number to name stored in zip file
- -x exclude all names matching the following patterns
- -x@ exclude all names matching the patterns in "file"
- -X suppress storing of any extra file attributes
- -z add zipfile comment
- -0 store only
- -1 compress faster
- -9 compress better
- -@ read list of input files from SYS$INPUT
-.end literal
-.!------------------------------------------------------------------------------
-.indent -4
-2 How_To_Use_Zip
-.br
-The simplest use of Zip is as follows:
-.sk;.indent 10;$ zip stuff *
-.sk
-This will create the file "STUFF.ZIP" (assuming it does not exist) and put
-all the files in the current directory in STUFF.ZIP in a compressed form.
-The .ZIP suffix is added automatically, unless the zipfile name given
-contains a dot already. This allows specifying suffixes other than ".ZIP".
-.sk
-To zip up an entire directory, the command:
-.sk;.indent 10
-$ zip -r foo *.*
-.sk
-will create the file "FOO.ZIP" containing all the files and directories in
-the in the current directory. The "r" option means recurse through the
-directory structure. If you wish to recurse through the subdirectory [x.y]
-use the following syntax:
-.sk;.indent 10
-zip -r foo [x]y.dir
-.sk
-You may want to make a zip file that contains the files in [.FOO], but not
-record the directory name, FOO. You can use the -j (junk path) option to
-leave off the path:
-.sk;.indent 10
-$ zip -j foo [.foo]*.*
-.sk
-You might be zipping to save disk space, in which case you could:
-.sk;.indent 10
-$ zip -rm foo *.txt
-.sk
-where the "m" option means "move". This will delete all files matching
-*.txt after making FOO.ZIP. No deletions will be done until the zip has
-completed with no errors. This option is obviously more dangerous and
-should be used with care.
-.sk
-If the zip file already exists, these commands will replace existing or add
-new entries to the zip file. For example, if you were really short on disk
-space, you might not have enough room simultaneously to hold the directory
-[.FOO] and the compressed FOO.ZIP. In this case, you could do it in steps.
-If [.FOO] contained the subdirectories [.TOM], [.DICK], and [.HARRY], then
-you could:
-.sk;
-.indent 10;$ zip -rm foo [.foo.tom]
-.indent 10;$ zip -rm foo [.foo.dick]
-.indent 10;$ zip -rm foo [.foo.harry]
-.sk
-where the first command would create FOO.ZIP, and the next two would add to
-it. At the completion of each zip command, the files in the directory just
-zipped would be deleted, making room in which the next Zip command could
-work.
-.!------------------------------------------------------------------------------
-.indent -4
-2 Modifying_Existing_Zip_Files
-.br
-When given the name of an existing zip file with the above commands, Zip
-will replace identically named entries in the Zip file or add entries for
-new names. For example, if FOO.ZIP exists and contains foo/file1 and
-foo/file2, and the directory [.FOO] contains the files foo/file1 and
-foo/file3, then:
-.sk;.indent 10
-$ zip -r foo [.foo]
-.sk
-will replace foo/file1 in foo.zip and add foo/file3 to FOO.ZIP. After
-this, FOO.ZIP contains foo/file1, foo/file2, and foo/file3, with foo/file2
-unchanged from before.
-.sk
-When changing an existing zip file, Zip will write a temporary file with
-the new contents, and only replace the old one when the zip has completed
-with no errors. You can use
-the -b option to specify a different path (usually a different dev- ice) to
-put the temporary files in. For example:
-.sk;.indent 10
-$ zip -b scratch$:[tmp] stuff *
-.sk
-will put the temporary zip file and the temporary compression files in the
-directory "SCRATCH$:[TMP]", copying over STUFF.ZIP in the current directory
-when done.
-.sk
-If you are only adding entries to a zip file, not replacing, and the -g
-option is given, then Zip grows (appends to) the file instead of copying
-it. The danger of this is that if the operation fails, the original zip
-file is corrupted and lost.
-.sk
-There are two other ways to change or add entries in a zip file that are
-restrictions of simple addition or replacement. The first is -u (update)
-which will add new entries to the zip file as before but will replace
-existing entries only if the modified date of the file is more recent than
-the date recorded for that name in the zip file. For example:
-.sk;.indent 10
-$ zip -u stuff *
-.sk
-will add any new files in the current directory, and update any changed
-files in the zip file STUFF.ZIP. Note that Zip will not try to pack
-STUFF.ZIP into itself when you do this. Zip will always exclude the zip
-file from the files on which to be operated.
-.sk
-The second restriction is -f (freshen) which, like update, will only
-replace entries with newer files; unlike update, will not add files that
-are not already in the zip file. For this option, you may want to simply
-freshen all of the files that are in the specified zip file. To do this
-you would simply:
-.sk;.indent 10
-$ zip -f foo
-.sk
-Note that the -f option with no arguments freshens all the entries in the
-zip file. The same is true of -u, and hence "zip -u foo" and "zip -f foo"
-both do the same thing.
-.sk
-This command should be run from the same directory from which the original
-zip command was run, since paths stored in zip files are always relative.
-.sk
-Another restriction that can be used with adding, updating, or freshening
-is -t (time), which will not operate on files modified earlier than the
-specified date. For example:
-.sk;.indent 10
-$ zip -rt 12071991 infamy [.FOO]*.*
-.sk
-will add all the files in [.FOO] and its subdirectories that were last
-modified on December 7, 1991, or later to the zip file INFAMY.ZIP.
-.sk
-Also, files can be explicitly excluded using the -x option:
-.sk;.indent 10
-$ zip -r foo [.FOO] -x *.obj
-.sk
-which will zip up the contents of [.FOO] into FOO.ZIP but exclude all the
-files that end in ".OBJ".
-.sk
-The last operation is -d (delete) which will remove entries from a zip
-file. An example might be:
-.sk;.indent 10
-$ zip -d foo foo/harry/*.* *.obj
-.sk
-which will remove all of the files that start with "foo/harry/" and all of
-the files that end with ".OBJ" (in any path).
-.sk
-Under VMS, -d is case sensitive when it matches names in the zip file.
-This allows deleting names that were zipped on other systems, but requires
-that the names be entered in upper case if they were zipped on an MSDOS
-system (by PKZIP or in PKZIP compatibility mode), so that the names can be
-found in the zip file and deleted.
-.!------------------------------------------------------------------------------
-.indent -4
-2 More_Options
-.br
-As mentioned before, Zip will use the best of two methods: deflate or store.
-The option -0 will force Zip to use store on all files. For example:
-.sk;.indent 10
-zip -r0 foo foo.dir
-.sk
-will zip up the directory foo into foo.zip using only store.
-.sk
-The speed of deflation can also be controlled with options -1 (fastest
-method but less compression) to -9 (best compression but slower). The
-default value is -6. For example:
-.sk;.indent 10
-zip -r8 foo foo.dir
-.sk
-In nearly all cases, a file that is already compressed cannot be compressed
-further by Zip, or if it can, the effect is minimal. The -n option
-prevents Zip from trying to compress files that have the
-given suffixes. Such files are simply stored (0%
-compression) in the
-output zip file, so that Zip doesn't waste its time trying to compress
-them. The suffixes are separated by
-either colons or semicolons. For example, in DCL:
-.sk
-.indent 10;$ zip -rn ".Z:.zip:.tiff:.gif:.snd" foo [.FOO]*.*
-.sk
-will put everything in [.FOO] into FOO.ZIP, but will store any files that end
-in .Z, .ZIP, .TIFF, .GIF, or .SND without trying to compress them. (Image and
-sound files often have their own specialized compression methods.)
-The default suffix list is ".Z:.zip;.zoo:.arc:.lzh:.arj".
-The environment variable ZIPOPT can be used to change this default. For
-example:
-.sk
-.indent 10;$ ZIPOPT == "-n .Z:.zip:.tiff:.gif:.snd"
-.sk
-The variable ZIPOPT can be used for any option (except -i and -x)
-and can include several options.
-.sk
-For VMS Zip, the alternatively environment variable name ZIP_OPTS may
-be used, if a more "VMS-like" name is prefered. If both ZIPOPT and
-ZIP_OPTS are present (and do not equate to whitespace only),
-the content of ZIPOPT takes precedence and ZIP_OPTS is ignored.
-.sk
-Under Unix, Zip will store the full path (relative to the current path)
-and name of the file (or just the name if -j is specified) in the zip
-file along with the Unix attributes, and it will mark the entry as made
-under Unix. If the zip file is intended for PKUNZIP under MSDOS, then
-the -k (Katz) option should be used to 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 wasn't).
-.sk
-The -o (older) option will set the "last modified" time of the zip file to
-the latest "last modified" time of the entries in the zip file. This can
-be used without any other operations, if desired. For example:
-.sk;.indent 10
-$ zip -o foo
-.sk
-will change the last modified time of FOO.ZIP to the latest time of the
-entries in FOO.ZIP.
-.sk
-The -e and -c options operate on all files updated or added to the zip
-file. Encryption (-e) will prompt for a password on the terminal and will
-not echo the password as it is typed (if SYS$COMMAND is not a TTY, Zip will
-exit with an error). New zip entries will be encrypted using that password.
-For added peace of mind, Zip will prompt for the password a second time,
-checking that the two inputs are the same before using it.
-.sk
-One-line comments can be added for each file with the -c option. The zip
-file operations (adding or updating) will be done first, and you will then
-be prompted for a one-line comment for each file. You can then enter the
-comment followed by return, or just return for no comment.
-.sk
-The -z option will prompt you for a multi-line comment for the entire zip
-file. This option can be used by itself, or in combination with other
-options. 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 OpenVMS).
-.sk
-The -q (quiet) option eliminates the informational messages and comment
-prompts while Zip is operating. This might be used in shell scripts, for
-example, or if the zip operation is being performed as a background task
-("$ spawn/nowait zip -q foo *.c").
-.sk
-Zip can take a list of file names to operate on from SYS$INPUT using the
-"-@"
-option.
-.! In Unix, this option can be used with the find command to extend
-.!greatly the functionality of Zip. For example, to zip up all the C source
-.!files in the current directory and its subdirectories, you can:
-.!.sk
-.!find . -type f -name "*.[ch]" -print | zip source -@
-.!.sk
-.!Note that the pattern must be quoted to keep the shell from expanding it.
-.sk
-The -X option (remember to quote it!) suppresses saving of additional
-"extra file attributes" in the zipfile. Its effect is to disable the
-VMS only -V option (see below), and prevent storing of UNIX compatible
-GMT modification time stamps. These UNIX compatible GMT time stamps
--- which are quite useful when transporting Zip archives world wide (but
-are only recognized by Info-ZIP's UnZip 5.20 or later) --
-are included in the zipfile unless -X or -V is specified (in case your
-version of Zip has the USE_EF_UT_TIME option compiled in).
-.sk
-Under VMS only, the -w option will append the version number of the files
-to the name and zip up multiple versions of files. Without -w, Zip will
-only use the most recent version of the specified file(s).
-.sk
-One more option that valid only under VMS is -V option. This option saves
-all (hopefully) file attributes needed to make EXACT copy of the
-file after extraction from archive. To extract a file with saved attributes,
-use UnZip version 5.20 or later. Note that to specify this option you should
-quote it ("-V"). Be carefull: it's rather hard (if possible at all) to extract
-a file archived on VMS with this option specified on other systems. See
-documentation on UnZip for further information.
-.sk
-The -l option translates 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 or VMS if the zip file is intended for
-PKUNZIP under MSDOS.
-.sk
-If Zip is run with the -h option, or with no arguments and standard output is
-a terminal, the license and the command-argument and option help is shown.
-.sk
-The -L option shows the Zip license.
-.sk
-The -v option, when given as the only command line argument, directs Zip to
-display diagnostic information that shows when and how the executable was
-built and set up. This includes info on used compiler and compiler version
-(if available) as well as any optional compile time feature flags.
-Additionally, the content of the environment variables
-(logical names) read by Zip for runtime configuration are shown. This
-information is especially valuable when reporting problems or bugs.
-.!------------------------------------------------------------------------------
-.indent -4
-2 Diagnostics
-.br
- On VMS, Zip's UNIX style exit values are mapped into proper
- VMS status codes:
-.literal
- 1 (success) normal exit,
- (0x7fff0000 + 16*Zip_error_level) warnings
- (0x7fff0002 + 16*Zip_error_level) normal errors
- (0x7fff0004 + 16*Zip_error_level) fatal errors
-.end literal
-
- The Zip error level (or exit code) approximates the exit
- codes defined by PKWARE and takes on the following values:
-.literal
-
- VMS Zip Type of error
- severity errcode
- - 0 normal; no errors or warnings detected.
- F 2 unexpected end of zip file.
- E 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.
- F 4 zip was unable to allocate memory for one or
- more buffers during program initialization.
- F 5 a severe error in the zipfile format was
- detected. Processing probably failed imme-
- diately.
- E 6 entry too large to be split with zipsplit
- E 7 invalid comment format
- F 8 zip -T failed or out of memory
- E 9 the user aborted zip prematurely with con-
- trol-C (or similar)
- F 10 zip encountered an error while using a temp
- file
- F 11 read or seek error
- W 12 zip has nothing to do
- E 13 missing or empty zip file
- F 14 error writing to a file
- F 15 zip was unable to create a file to write to
- E 16 bad command line parameters
- E 18 zip could not open a specified file to read
-.end literal
-.!------------------------------------------------------------------------------
-.indent -4
-2 Copyright
-.br
- Copyright (C) 1990-1997 Mark Adler, Richard B. Wales, Jean-loup Gailly,
- Onno van der Linden, Christian Spieler and Igor Mandrichenko.
- 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.
-.sk
- 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.
-.sk
- Please send bug reports or comments by email to:
- Zip-Bugs@lists.wku.edu. For bug reports, please include
- the version of Zip (see zip -h), the make options you used to
- compile it (see zip -v), the machine and operating system you are using,
- and as much additional information as possible.
- Thank you for your support.
-.!------------------------------------------------------------------------------
-.indent -4
-2 Acknowledgements
-.br
- Thanks to R. P. Byrne for his 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 zip file format, compression format, and .ZIP filename
- extension, and for accepting minor changes to the file for-
- mat; to Steve Burg for clarifications on the deflate format;
- to Keith Petersen, Rich Wales, Hunter Goatley and Mark Adler
- for providing a mailing list and ftp site for the Info-ZIP
- group to use; and most importantly, to the Info-ZIP group
- itself (listed in the file infozip.who) without whose tire-
- less testing and bug-fixing efforts a portable 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.
-.!------------------------------------------------------------------------------
-.indent -4
-2 Bugs
-.sk
- Zip 2.2 is not compatible with PKUNZIP 1.10. Use Zip 1.1 instead
- to produce zip archives which can be extracted by PKUNZIP 1.10.
-.sk
- WARNING: zip files produced by this version of zip must not be
- *updated* by zip 1.0 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 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.
-.sk
- Under VMS, not all of the odd file formats are treated properly.
- Only zip files of format stream-LF and fixed length 512 byte are
- expected to work with Zip. Others can be converted using Rahul
- Dhesi's BILF program. This version of Zip handles some of the
- conversion internally. The use of the "-V" option to save the
- VMS attributes should work without problem for at least all types
- of sequential files. Beginning with Zip 2.2, the "-V" option uses
- a new format to store the VMS attributes that should now allow
- proper restoration of all sorts of indexed files. It has been
- approved that there are problems with VMS UnZip to restore some
- indexed files which were saved with previous versions of Zip.
-.sk
- When using Kermit to transfer zip files from VMS to MSDOS, type "set
- file type block" on the VMS side. When transfering from MSDOS to VMS,
- type "set file type fixed" on the VMS machine. In both cases, type
- "set file type binary" on MSDOS.
-.sk
- Under VMS, zip hangs for file specification that uses DECnet
- syntax (foo::*.*).
-.sk
- 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.
-.sk
- That having been said, please send any problems or comments
- via email to the Internet address Zip-Bugs@lists.wku.edu. For
- bug reports, please include the version of Zip, the make
- options you used to compile it, the machine and operating
- system you are using, and as much additional information as
- possible. Thank you for your support.
-.!------------------------------------------------------------------------------
diff --git a/vms/vmsdefs.h b/vms/vmsdefs.h
index d5ca610..73d013a 100644
--- a/vms/vmsdefs.h
+++ b/vms/vmsdefs.h
@@ -1,9 +1,9 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*---------------------------------------------------------------------------
diff --git a/vms/vmsmunch.c b/vms/vmsmunch.c
index b40ef45..8140036 100644
--- a/vms/vmsmunch.c
+++ b/vms/vmsmunch.c
@@ -1,13 +1,22 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
-#define module_name VMSMUNCH
-#define module_version "V1.3-4"
+
+/* 2004-12-13 SMS.
+ * Disabled the module name macro to accommodate old GNU C which didn't
+ * obey the directive, and thus confused MMS/MMK where the object
+ * library dependencies need to have the correct module name.
+ */
+#if 0
+# define module_name VMSMUNCH
+# define module_version "V1.3-4"
+#endif /* 0 */
+
/*
* Modified by:
*
@@ -97,24 +106,39 @@
---------------------------------------------------------------------------*/
-
-#if defined(__DECC) || defined(__GNUC__)
-#pragma module module_name module_version
-#else
-#module module_name module_version
-#endif
+/* 2004-12-13 SMS.
+ * Disabled the module name macro to accommodate old GNU C which didn't
+ * obey the directive, and thus confused MMS/MMK where the object
+ * library dependencies need to have the correct module name.
+ */
+#if 0
+# if defined(__DECC) || defined(__GNUC__)
+# pragma module module_name module_version
+# else
+# module module_name module_version
+# endif
+#endif /* 0 */
/*****************************/
/* Includes, Defines, etc. */
/*****************************/
+/* Accomodation for /NAMES = AS_IS with old header files. */
+
+#define sys$asctim SYS$ASCTIM
+#define sys$assign SYS$ASSIGN
+#define sys$bintim SYS$BINTIM
+#define sys$dassgn SYS$DASSGN
+#define sys$parse SYS$PARSE
+#define sys$qiow SYS$QIOW
+#define sys$search SYS$SEARCH
+
+#include "zip.h"
+
#include <stdio.h>
#include <string.h>
-#include <descrip.h>
-#include <rms.h>
#include <iodef.h>
#include <starlet.h>
-#include <atrdef.h> /* this gets created with the c3.0 compiler */
#include <fibdef.h> /* this gets created with the c3.0 compiler */
/*
@@ -136,6 +160,7 @@
# define FIB$L_ACCTL fib$r_acctl_overlay.fib$l_acctl
#endif
+#include "vms.h"
#include "vmsmunch.h" /* GET/SET_TIMES, RTYPE, etc. */
#include "vmsdefs.h" /* fatdef.h, etc. */
@@ -164,7 +189,6 @@ static void bintim(char *time, long int binval[2]);
#endif /* def __VAX */
-
/*************************/
/* Function VMSmunch() */
/*************************/
@@ -178,13 +202,13 @@ int VMSmunch(
/* original file.c variables */
static struct FAB Fab;
- static struct NAM Nam;
+ static struct NAM_STRUCT Nam;
static struct fibdef Fib; /* short fib */
static struct dsc$descriptor FibDesc =
{sizeof(Fib),DSC$K_DTYPE_Z,DSC$K_CLASS_S,(char *)&Fib};
static struct dsc$descriptor_s DevDesc =
- {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,&Nam.nam$t_dvi[1]};
+ {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,&Nam.NAM_DVI[1]};
static struct fatdef Fat;
static union {
struct fchdef fch;
@@ -225,8 +249,8 @@ int VMSmunch(
{0,0,0}
} ;
- static char EName[NAM$C_MAXRSS];
- static char RName[NAM$C_MAXRSS];
+ static char EName[NAM_MAXRSS];
+ static char RName[NAM_MAXRSS];
static struct dsc$descriptor_s FileName =
{0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
static struct dsc$descriptor_s string = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0};
@@ -248,16 +272,16 @@ int VMSmunch(
get the file info.
---------------------------------------------------------------------------*/
- /* initialize RMS structures, we need a NAM to retrieve the FID */
+ /* Initialize RMS structures. We need a NAM[L] to retrieve the FID. */
Fab = cc$rms_fab;
Fab.fab$l_fna = filename;
Fab.fab$b_fns = strlen(filename);
- Fab.fab$l_nam = &Nam; /* FAB has an associated NAM */
- Nam = cc$rms_nam;
- Nam.nam$l_esa = EName; /* expanded filename */
- Nam.nam$b_ess = sizeof(EName);
- Nam.nam$l_rsa = RName; /* resultant filename */
- Nam.nam$b_rss = sizeof(RName);
+ Fab.FAB_NAM = &Nam; /* FAB has an associated NAM[L]. */
+ Nam = CC_RMS_NAM;
+ Nam.NAM_ESA = EName; /* expanded filename */
+ Nam.NAM_ESS = sizeof(EName);
+ Nam.NAM_RSA = RName; /* resultant filename */
+ Nam.NAM_RSS = sizeof(RName);
/* do $PARSE and $SEARCH here */
status = sys$parse(&Fab);
@@ -268,20 +292,20 @@ int VMSmunch(
if (!(status & 1)) return(status);
while (status & 1) {
- /* initialize Device name length, note that this points into the NAM
+ /* initialize Device name length, note that this points into the NAM[L]
to get the device name filled in by the $PARSE, $SEARCH services */
- DevDesc.dsc$w_length = Nam.nam$t_dvi[0];
+ DevDesc.dsc$w_length = Nam.NAM_DVI[0];
status = sys$assign(&DevDesc,&DevChan,0,0);
if (!(status & 1)) return(status);
- FileName.dsc$a_pointer = Nam.nam$l_name;
- FileName.dsc$w_length = Nam.nam$b_name+Nam.nam$b_type+Nam.nam$b_ver;
+ FileName.dsc$a_pointer = Nam.NAM_L_NAME;
+ FileName.dsc$w_length = Nam.NAM_B_NAME+Nam.NAM_B_TYPE+Nam.NAM_B_VER;
/* Initialize the FIB */
for (i=0;i<3;i++) {
- Fib.FIB$W_FID[i]=Nam.nam$w_fid[i];
- Fib.FIB$W_DID[i]=Nam.nam$w_did[i];
+ Fib.FIB$W_FID[i]=Nam.NAM_FID[i];
+ Fib.FIB$W_DID[i]=Nam.NAM_DID[i];
}
/* Use the IO$_ACCESS function to return info about the file */
@@ -346,8 +370,8 @@ int VMSmunch(
/* note, part of the FIB was cleared by earlier QIOW, so reset it */
Fib.FIB$L_ACCTL = FIB$M_NORECORD;
for (i=0;i<3;i++) {
- Fib.FIB$W_FID[i]=Nam.nam$w_fid[i];
- Fib.FIB$W_DID[i]=Nam.nam$w_did[i];
+ Fib.FIB$W_FID[i]=Nam.NAM_FID[i];
+ Fib.FIB$W_DID[i]=Nam.NAM_DID[i];
}
/* Use the IO$_MODIFY function to change info about the file */
diff --git a/vms/vmsmunch.h b/vms/vmsmunch.h
index 53d77b4..458ad78 100644
--- a/vms/vmsmunch.h
+++ b/vms/vmsmunch.h
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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.info-zip.org/pub/infozip/license.html
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
/*---------------------------------------------------------------------------
diff --git a/vms/vmszip.c b/vms/vmszip.c
index 2221644..2dae718 100644
--- a/vms/vmszip.c
+++ b/vms/vmszip.c
@@ -1,21 +1,26 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
-/* 2004-09-25 SMS.
- Added case-insensitive file name comparisons, with the option of
- preserving case in file names. Defining VMS_PRESERVE_CASE will cause
- incompatibility with Zip 2.3 and earlier.
+/* 2005-02-14 SMS.
+ Added some ODS5 support.
+ Use longer name structures in NAML, where available.
+ Locate special characters mindful of "^" escapes.
+ Replaced compile-time case preservation (VMS_PRESERVE_CASE macro)
+ with command-line-specified case preservation (vms_case_x
+ variables).
+ Prototyped all functions.
+ Removed "#ifndef UTIL", as no one should be compiling it that way.
*/
-/* #define VMS_PRESERVE_CASE */ /* Not for general use. */
-
#include "zip.h"
+#include "vmsmunch.h"
+#include "vms.h"
#include <ctype.h>
#include <time.h>
@@ -36,22 +41,108 @@
#include <strings.h> /* str[n]casecmp() */
#endif /* def HAVE_STRCASECMP */
-#include <descrip.h>
-#include <rms.h>
+#include <dvidef.h>
+#include <lib$routines.h>
#include <ssdef.h>
+#include <stsdef.h>
#include <starlet.h>
-#define PATH_START '['
-#define PATH_END ']'
-#define PATH_START2 '<'
-#define PATH_END2 '>'
-#include "vms/vmsmunch.h"
+/* Directory file type with version, and its strlen(). */
+#define DIR_TYPE_VER ".DIR;1"
+#define DIR_TYPE_VER_LEN (sizeof( DIR_TYPE_VER)- 1)
+
+/* Extra malloc() space in names for cutpath(). (May have to change
+ ".FOO]" to "]FOO.DIR;1".)
+*/
+#define DIR_PAD (DIR_TYPE_VER_LEN- 1)
+
+/* Hex digit table. */
+
+char hex_digit[ 16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+};
+
+/* Character property table for (re-)escaping ODS5 extended file names.
+ Note that this table ignore Unicode, and does not identify invalid
+ characters.
+
+ ODS2 valid characters: 0-9 A-Z a-z $ - _
+
+ ODS5 Invalid characters:
+ C0 control codes (0x00 to 0x1F inclusive)
+ Asterisk (*)
+ Question mark (?)
+
+ ODS5 Invalid characters only in VMS V7.2 (which no one runs, right?):
+ Double quotation marks (")
+ Backslash (\)
+ Colon (:)
+ Left angle bracket (<)
+ Right angle bracket (>)
+ Slash (/)
+ Vertical bar (|)
+
+ Characters escaped by "^":
+ SP ! # % & ' ( ) + , . ; = @ [ ] ^ ` { } ~
+
+ Either "^_" or "^ " is accepted as a space. Period (.) is a special
+ case. Note that un-escaped < and > can also confuse a directory
+ spec.
+
+ Characters put out as ^xx:
+ 7F (DEL)
+ 80-9F (C1 control characters)
+ A0 (nonbreaking space)
+ FF (Latin small letter y diaeresis)
+
+ Other cases:
+ Unicode: "^Uxxxx", where "xxxx" is four hex digits.
+
+ Property table values:
+ Normal escape: 1
+ Space: 2
+ Dot: 4
+ Hex-hex escape: 8
+ -------------------
+ Hex digit: 64
+*/
+
+unsigned char char_prop[ 256] = {
+
+/* NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* SP ! " # $ % & ' ( ) * + , - . / */
+ 2, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 4, 0,
-/* Extra malloc() space in names for cutpath() */
-#define PAD 5 /* may have to change .FOO] to ]FOO.DIR;1 */
+/* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
+ 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, 1, 1, 1, 1,
+/* @ A B C D E F G H I J K L M N O */
+ 1, 64, 64, 64, 64, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-#ifndef UTIL /* the companion #endif is a bit of ways down ... */
+/* P Q R S T U V W X Y Z [ \ ] ^ _ */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0,
+
+/* ` a b c d e f g h i j k l m n o */
+ 1, 64, 64, 64, 64, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+
+/* p q r s t u v w x y z { | } ~ DEL */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 8,
+
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8
+};
/* The C RTL from OpenVMS 7.0 and newer supplies POSIX compatible versions of
* opendir() et al. Thus, we have to use other names in our private code for
@@ -65,9 +156,9 @@
typedef struct zdirent {
int d_wild; /* flag for wildcard vs. non-wild */
struct FAB fab;
- struct NAM nam;
- char d_qualwildname[NAM$C_MAXRSS + 1];
- char d_name[NAM$C_MAXRSS + 1];
+ struct NAM_STRUCT nam;
+ char d_qualwildname[ NAM_MAXRSS+ 1];
+ char d_name[ NAM_MAXRSS+ 1];
} zDIR;
extern char *label;
@@ -75,6 +166,8 @@ local ulg label_time = 0;
local ulg label_mode = 0;
local time_t label_utim = 0;
+local int relative_dir_s = 0; /* Relative directory spec. */
+
/* Local functions */
local void vms_wild OF((char *, zDIR *));
local zDIR *zopendir OF((ZCONST char *));
@@ -88,10 +181,7 @@ local char *strupper OF((char *));
*/
#ifndef HAVE_STRCASECMP
-int strncasecmp( s1, s2, n)
-char *s1;
-char *s2;
-size_t n;
+int strncasecmp( char *s1, char *s2, size_t n)
{
/* Initialization prepares for n == 0. */
char c1 = '\0';
@@ -113,7 +203,7 @@ size_t n;
s1++;
s2++;
}
-return ((unsigned int)c1 - (unsigned int)c2);
+return ((unsigned int) c1- (unsigned int) c2);
}
#ifndef UINT_MAX
@@ -127,16 +217,20 @@ return ((unsigned int)c1 - (unsigned int)c2);
/* 2004-09-27 SMS.
eat_carets().
+
Delete ODS5 extended file name escape characters ("^") in the
original buffer.
- Note that the current scheme handles only simple EFN cases, but it
+ Note that the current scheme does not handle all EFN cases, but it
could be made more complicated.
*/
-local void eat_carets( str)
-char *str; /* Source pointer. */
+local void eat_carets( char *str)
+/* char *str; Source pointer. */
{
char *strd; /* Destination pointer. */
+ char hdgt;
+ unsigned char uchr;
+ unsigned char prop;
/* Skip ahead to the first "^", if any. */
while ((*str != '\0') && (*str != '^'))
@@ -149,16 +243,50 @@ char *str; /* Source pointer. */
strd = str;
while (*str != '\0')
{
- if (*str == '^')
- {
- /* Found a caret. Skip it, and take the next character. */
- *strd = *(++str);
- }
- else
+ uchr = *str;
+ if (uchr == '^')
{
- /* Found a non-caret. Take it. */
- *strd = *str;
+ /* Found a caret. Skip it, and check the next character. */
+ uchr = *(++str);
+ prop = char_prop[ uchr];
+ if (prop& 64)
+ {
+ /* Hex digit. Get char code from this and next hex digit. */
+ if (uchr <= '9')
+ {
+ hdgt = uchr- '0'; /* '0' - '9' -> 0 - 9. */
+ }
+ else
+ {
+ hdgt = ((uchr- 'A')& 7)+ 10; /* [Aa] - [Ff] -> 10 - 15. */
+ }
+ hdgt <<= 4; /* X16. */
+ uchr = *(++str); /* Next char must be hex digit. */
+ if (uchr <= '9')
+ {
+ uchr = hdgt+ uchr- '0';
+ }
+ else
+ {
+ uchr = hdgt+ ((uchr- 'A')& 15)+ 10;
+ }
+ }
+ else if (uchr == '_')
+ {
+ /* Convert escaped "_" to " ". */
+ uchr = ' ';
+ }
+ else if (uchr == '/')
+ {
+ /* Convert escaped "/" (invalid Zip) to "?" (invalid VMS). */
+ uchr = '?';
+ }
+ /* Else, not a hex digit. Must be a simple escaped character
+ (or Unicode, which is not yet handled here).
+ */
}
+ /* Else, not a caret. Use as-is. */
+ *strd = uchr;
/* Advance destination and source pointers. */
strd++;
@@ -169,6 +297,240 @@ char *str; /* Source pointer. */
}
}
+
+/* 2007-05-22 SMS.
+ * explicit_dev().
+ *
+ * Determine if an explicit device name is present in a (VMS) file
+ * specification.
+ */
+local int explicit_dev( char *file_spec)
+{
+ int sts;
+ struct FAB fab; /* FAB. */
+ struct NAM_STRUCT nam; /* NAM[L]. */
+
+ /* Initialize the FAB and NAM[L], and link the NAM[L] to the FAB. */
+ nam = CC_RMS_NAM;
+ fab = cc$rms_fab;
+ fab.FAB_NAM = &nam;
+
+ /* Point the FAB/NAM[L] fields to the actual name and default name. */
+
+#ifdef NAML$C_MAXRSS
+
+ fab.fab$l_dna = (char *) -1; /* Using NAML for default name. */
+ fab.fab$l_fna = (char *) -1; /* Using NAML for file name. */
+
+#endif /* def NAML$C_MAXRSS */
+
+ /* File name. */
+ FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNA = file_spec;
+ FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNS = strlen( file_spec);
+
+ nam.NAM_NOP = NAM_M_SYNCHK; /* Syntax-only analysis. */
+ sts = sys$parse( &fab, 0, 0); /* Parse the file spec. */
+
+ /* Device found = $PARSE success and "device was explicit" flag. */
+ return (((sts& STS$M_SEVERITY) == STS$M_SUCCESS) &&
+ ((nam.NAM_FNB& NAM_M_EXP_DEV) != 0));
+}
+
+
+/* 2005-02-04 SMS.
+ find_dir().
+
+ Find directory boundaries in an ODS2 or ODS5 file spec.
+ Returns length (zero if no directory, negative if error),
+ and sets "start" argument to first character (typically "[") location.
+
+ No one will care about the details, but the return values are:
+
+ 0 No dir.
+ -2 [, no end. -3 <, no end.
+ -4 [, multiple start. -5 <, multiple start.
+ -8 ], no start. -9 >, no start.
+ -16 ], wrong end. -17 >, wrong end.
+ -32 ], multiple end. -33 >, multiple end.
+
+ Note that the current scheme handles only simple EFN cases, but it
+ could be made more complicated.
+*/
+int find_dir( char *file_spec, char **start)
+{
+ char *cp;
+ char chr;
+
+ char *end_tmp = NULL;
+ char *start_tmp = NULL;
+ int lenth = 0;
+
+ for (cp = file_spec; cp < file_spec+ strlen( file_spec); cp++)
+ {
+ chr = *cp;
+ if (chr == '^')
+ {
+ /* Skip ODS5 extended name escaped characters. */
+ cp++;
+ /* If escaped char is a hex digit, skip the second hex digit, too. */
+ if (char_prop[ (unsigned char) *cp]& 64)
+ cp++;
+ }
+ else if (chr == '[')
+ {
+ /* Found start. */
+ if (start_tmp == NULL)
+ {
+ /* First time. Record start location. */
+ start_tmp = cp;
+ /* Error if no end. */
+ lenth = -2;
+ }
+ else
+ {
+ /* Multiple start characters. */
+ lenth = -4;
+ break;
+ }
+ }
+ else if (chr == '<')
+ {
+ /* Found start. */
+ if (start_tmp == NULL)
+ {
+ /* First time. Record start location. */
+ start_tmp = cp;
+ /* Error if no end. */
+ lenth = -3;
+ }
+ else
+ {
+ /* Multiple start characters. */
+ lenth = -5;
+ break;
+ }
+ }
+ else if (chr == ']')
+ {
+ /* Found end. */
+ if (end_tmp == NULL)
+ {
+ /* First time. */
+ if (lenth == 0)
+ {
+ /* End without start. */
+ lenth = -8;
+ break;
+ }
+ else if (lenth != -2)
+ {
+ /* Wrong kind of end. */
+ lenth = -16;
+ break;
+ }
+ /* End ok. Record end location. */
+ end_tmp = cp;
+ lenth = end_tmp+ 1- start_tmp;
+ /* Could break here, ignoring excessive end characters. */
+ }
+ else
+ {
+ /* Multiple end characters. */
+ lenth = -32;
+ break;
+ }
+ }
+ else if (chr == '>')
+ {
+ /* Found end. */
+ if (end_tmp == NULL)
+ {
+ /* First time. */
+ if (lenth == 0)
+ {
+ /* End without start. */
+ lenth = -9;
+ break;
+ }
+ else if (lenth != -3)
+ {
+ /* Wrong kind of end. */
+ lenth = -17;
+ break;
+ }
+ /* End ok. Record end location. */
+ end_tmp = cp;
+ lenth = end_tmp+ 1- start_tmp;
+ /* Could break here, ignoring excessive end characters. */
+ }
+ else
+ {
+ /* Multiple end characters. */
+ lenth = -33;
+ break;
+ }
+ }
+ }
+
+ /* If both start and end were found,
+ then set result pointer where safe.
+ */
+ if (lenth > 0)
+ {
+ if (start != NULL)
+ {
+ *start = start_tmp;
+ }
+ }
+ return lenth;
+}
+
+
+/* 2005-02-08 SMS.
+ file_sys_type().
+
+ Determine the file system type for the (VMS) path name argument.
+*/
+local int file_sys_type( char *path)
+{
+ int acp_code;
+
+#ifdef DVI$C_ACP_F11V5
+
+/* Should know about ODS5 file system. Do actual check.
+ (This should be non-VAX with __CRTL_VER >= 70200000.)
+*/
+
+ int sts;
+
+ struct dsc$descriptor_s dev_descr =
+ { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0 };
+
+ /* Load path argument into device descriptor. */
+ dev_descr.dsc$a_pointer = path;
+ dev_descr.dsc$w_length = strlen( dev_descr.dsc$a_pointer);
+
+ /* Get filesystem type code.
+ (Text results for this item code have been unreliable.)
+ */
+ sts = lib$getdvi( &((int) DVI$_ACPTYPE), 0, &dev_descr, &acp_code, 0, 0);
+
+ if ((sts & STS$M_SUCCESS) != STS$K_SUCCESS)
+ {
+ acp_code = -1;
+ }
+
+#else /* def DVI$C_ACP_F11V5 */
+
+/* Too old for ODS5 file system. Must be ODS2. */
+
+ acp_code = DVI$C_ACP_F11V2;
+
+#endif /* def DVI$C_ACP_F11V5 */
+
+ return acp_code;
+}
+
/*---------------------------------------------------------------------------
_vms_findfirst() and _vms_findnext(), based on public-domain DECUS C
@@ -177,32 +539,45 @@ char *str; /* Source pointer. */
Roelofs and are still in the public domain. Routines approximate the
behavior of MS-DOS (MSC and Turbo C) findfirst and findnext functions.
+ 2005-01-04 SMS.
+ Changed to use NAML instead of NAM, where available.
+
---------------------------------------------------------------------------*/
static char wild_version_part[10]="\0";
-local void vms_wild(p, d)
-char *p;
-zDIR *d;
+local void vms_wild( char *p, zDIR *d)
{
/*
- * Do wildcard setup
+ * Do wildcard setup.
*/
- /* set up the FAB and NAM blocks. */
- d->fab = cc$rms_fab; /* initialize fab */
- d->nam = cc$rms_nam; /* initialize nam */
+ /* Set up the FAB and NAM[L] blocks. */
+ d->fab = cc$rms_fab; /* Initialize FAB. */
+ d->nam = CC_RMS_NAM; /* Initialize NAM[L]. */
+
+ d->fab.FAB_NAM = &d->nam; /* FAB -> NAM[L] */
- d->fab.fab$l_nam = &d->nam; /* fab -> nam */
- d->fab.fab$l_fna = p; /* argument wild name */
- d->fab.fab$b_fns = strlen(p); /* length */
+#ifdef NAML$C_MAXRSS
- d->fab.fab$l_dna = "sys$disk:[]"; /* Default fspec */
- d->fab.fab$b_dns = sizeof("sys$disk:[]")-1;
+ d->fab.fab$l_dna =(char *) -1; /* Using NAML for default name. */
+ d->fab.fab$l_fna = (char *) -1; /* Using NAML for file name. */
- d->nam.nam$l_esa = d->d_qualwildname; /* qualified wild name */
- d->nam.nam$b_ess = NAM$C_MAXRSS; /* max length */
- d->nam.nam$l_rsa = d->d_name; /* matching file name */
- d->nam.nam$b_rss = NAM$C_MAXRSS; /* max length */
+#endif /* def NAML$C_MAXRSS */
+
+ /* Argument file name and length. */
+ d->FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNA = p;
+ d->FAB_OR_NAML( fab, nam).FAB_OR_NAML_FNS = strlen(p);
+
+#define DEF_DEVDIR "SYS$DISK:[]"
+
+ /* Default file spec and length. */
+ d->FAB_OR_NAML( fab, nam).FAB_OR_NAML_DNA = DEF_DEVDIR;
+ d->FAB_OR_NAML( fab, nam).FAB_OR_NAML_DNS = sizeof( DEF_DEVDIR)- 1;
+
+ d->nam.NAM_ESA = d->d_qualwildname; /* qualified wild name */
+ d->nam.NAM_ESS = NAM_MAXRSS; /* max length */
+ d->nam.NAM_RSA = d->d_name; /* matching file name */
+ d->nam.NAM_RSS = NAM_MAXRSS; /* max length */
/* parse the file name */
if (sys$parse(&d->fab) != RMS$_NORMAL)
@@ -212,16 +587,16 @@ zDIR *d;
/* have qualified wild name (i.e., disk:[dir.subdir]*.*); null-terminate
* and set wild-flag */
- d->d_qualwildname[d->nam.nam$b_esl] = '\0';
- d->d_wild = (d->nam.nam$l_fnb & NAM$M_WILDCARD)? 1 : 0; /* not used... */
+ d->d_qualwildname[d->nam.NAM_ESL] = '\0';
+ d->d_wild = (d->nam.NAM_FNB & NAM$M_WILDCARD)? 1 : 0; /* not used... */
#ifdef DEBUG
fprintf(mesg, " incoming wildname: %s\n", p);
fprintf(mesg, " qualified wildname: %s\n", d->d_qualwildname);
#endif /* DEBUG */
}
-local zDIR *zopendir(n)
-ZCONST char *n; /* directory to open */
+local zDIR *zopendir( ZCONST char *n)
+/* ZCONST char *n; directory to open */
/* Start searching for files in the VMS directory n */
{
char *c; /* scans VMS path */
@@ -235,20 +610,27 @@ ZCONST char *n; /* directory to open */
return NULL;
}
/* Directory may be in form "[DIR.SUB1.SUB2]" or "[DIR.SUB1]SUB2.DIR;1".
- If latter, convert to former. */
- if (m > 0 && *(c = strcpy(p,n)+m-1) != ']')
+ If latter, convert to former.
+ 2005-01-31 SMS. Changed to require ";1", as VMS does, which
+ simplified the code slightly, too. Note that ODS5 allows ".DIR" in
+ any case (upper, lower, mixed).
+ */
+ if ((m > 0) && (*(c = strcpy(p,n)+m-1) != ']'))
{
- while (--c > p && *c != ';')
- ;
- if ((c- p < 5) || strncasecmp( (c- 4), ".DIR", 4))
+ if ((c- p < DIR_TYPE_VER_LEN) ||
+ strcasecmp((c+ 1- DIR_TYPE_VER_LEN), DIR_TYPE_VER))
{
free((zvoid *)d); free((zvoid *)p);
return NULL;
}
- c -= 3;
- *c-- = '\0'; /* terminate at "DIR;#" */
+ c -= 4; /* The "D". */
+ *c-- = '\0'; /* terminate at "DIR;1" */
*c = ']'; /* "." --> "]" */
- while (c > p && *--c != ']')
+
+ /* Replace the formerly last "]" with ".".
+ For ODS5, ignore "^]".
+ */
+ while ((c > p) && ((*--c != ']') || (*(c- 1) == '^')))
;
*c = '.'; /* "]" --> "." */
}
@@ -259,8 +641,8 @@ ZCONST char *n; /* directory to open */
return d;
}
-local char *readd(d)
-zDIR *d; /* directory stream to read from */
+local char *readd( zDIR *d)
+/* zDIR *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. */
{
@@ -268,30 +650,56 @@ zDIR *d; /* directory stream to read from */
do {
d->fab.fab$w_ifi = 0; /* internal file index: what does this do? */
+/*
+ 2005-02-04 SMS.
+ From the docs:
+
+ Note that you must close the file before invoking the Search
+ service (FAB$W_IFI must be 0).
+
+ The same is true for PARSE. Most likely, it's cleared by setting
+ "fab = cc$rms_fab", and left that way, so clearing it here may very
+ well be pointless. (I think it is, and I've never seen it explicitly
+ cleared elsewhere, but I haven't tested it everywhere either.)
+*/
/* get next match to possible wildcard */
if ((r = sys$search(&d->fab)) == RMS$_NORMAL)
{
- d->d_name[d->nam.nam$b_rsl] = '\0'; /* null terminate */
+ d->d_name[d->nam.NAM_RSL] = '\0'; /* null terminate */
return (char *)d->d_name; /* OK */
}
} while (r == RMS$_PRV);
return NULL;
}
-int wild(p)
-char *p; /* path/pattern to match */
-/* Expand the pattern based on the contents of the file system. Return an
- error code in the ZE_ class. */
+
+int wild( char *p)
+/* char *p; path/pattern to match */
+/* Expand the pattern based on the contents of the file system.
+ Return an error code in the ZE_ class.
+ Note that any command-line file argument may need wildcard expansion,
+ so all user-specified constituent file names pass through here.
+*/
{
zDIR *d; /* stream for reading directory */
char *e; /* name found in directory */
int f; /* true if there was a match */
+ int dir_len; /* Length of the directory part of the name. */
+ char *dir_start; /* First character of the directory part. */
+
/* special handling of stdin request */
if (strcmp(p, "-") == 0) /* if compressing stdin */
return newname(p, 0, 0);
+ /* Determine whether this name has an absolute or relative directory
+ spec. It's relative if there is no directory, or if the directory
+ has a leading dot ("[.").
+ */
+ dir_len = find_dir( p, &dir_start);
+ relative_dir_s = ((dir_len <= 0)? 1 : (dir_start[ 1] == '.'));
+
/* Search given pattern for matching names */
if ((d = (zDIR *)malloc(sizeof(zDIR))) == NULL)
return ZE_MEM;
@@ -301,8 +709,8 @@ char *p; /* path/pattern to match */
* Save version specified by user to use in recursive drops into
* subdirectories.
*/
- strncpy(wild_version_part,d->nam.nam$l_ver,d->nam.nam$b_ver);
- wild_version_part[d->nam.nam$b_ver] = '\0';
+ strncpy(wild_version_part, d->nam.NAM_L_VER, d->nam.NAM_B_VER);
+ wild_version_part[d->nam.NAM_B_VER] = '\0';
f = 0;
while ((e = readd(d)) != NULL) /* "dosmatch" is already built in */
@@ -314,9 +722,9 @@ char *p; /* path/pattern to match */
return f ? ZE_OK : ZE_MISS;
}
-int procname(n, caseflag)
-char *n; /* name to process */
-int caseflag; /* true to force case-sensitive match */
+int procname( char *n, int 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. */
{
@@ -388,8 +796,7 @@ int caseflag; /* true to force case-sensitive match */
Cuter strlower() and strupper() functions.
*/
-local char *strlower( s)
-char *s;
+local char *strlower( char *s)
/* Convert all uppercase letters to lowercase in string s */
{
for ( ; *s != '\0'; s++)
@@ -399,8 +806,7 @@ char *s;
return s;
}
-local char *strupper( s)
-char *s;
+local char *strupper( char *s)
/* Convert all lowercase letters to uppercase in string s */
{
for ( ; *s != '\0'; s++)
@@ -410,54 +816,132 @@ char *s;
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 *ex2in( char *x, int isdir, int *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.
+
+ 2005-02-09 SMS.
+ Added some ODS5 support.
+
+ Note that if we were really clever, we'd save the truncated original
+ file name for later use as "iname", instead of running the de-escaped
+ product back through in2ex() to recover it later.
+
+ 2005-11-13 SMS.
+ Changed to translate "[..." into enough "/" characters to cause
+ in2ex() to reconstruct it. This should not be needed, however, as
+ pattern matching really should avoid ex2in() and in2ex().
+*/
{
- char *n; /* internal file name (malloc'ed) */
- char *t; /* shortened name */
+ char *n; /* Internal file name (malloc'ed). */
+ char *nn; /* Temporary "n"-like pointer. */
+ char *ext_dir_and_name; /* External dir]name (less "dev:["). */
+ char chr; /* Temporary character storage. */
int dosflag;
+ int down_case; /* Resultant down-case flag. */
+ int dir_len; /* Directory spec length. */
+ int ods_level; /* File system type. */
dosflag = dosify; /* default for non-DOS and non-OS/2 */
- /* Find starting point in name before doing malloc */
- t = x;
- if ((n = strrchr(t, ':')) != NULL)
- t = n + 1;
- if ( (*t == PATH_START && (n = strrchr(t, PATH_END)) != NULL)
- || (*t == PATH_START2 && (n = strrchr(t, PATH_END2)) != NULL) )
- /* external name contains valid VMS path specification */
- if (*(++t) == '.')
- /* path is relative to current directory, skip leading '.' */
- t++;
-
- if (!pathput)
- t = last(last(t, PATH_END), PATH_END2);
-
- /* Malloc space for internal name and copy it */
- if ((n = malloc(strlen(t) + 1)) == NULL)
+ /* Locate the directory part of the external name. */
+ dir_len = find_dir( x, &ext_dir_and_name);
+ if (dir_len <= 0)
+ {
+ /* Directory not found. Use whole external name. */
+ ext_dir_and_name = x;
+ }
+ else if (pathput)
+ {
+ /* Include directory. */
+ if (ext_dir_and_name[ 1] == '.')
+ {
+ /* Relative path. If not a directory-depth wildcard, then drop
+ first "[." (or "<."). If "[..." (or "<..."), then preserve all
+ characters, including the first "[" (or "<") for special
+ handling below.
+ */
+ if ((ext_dir_and_name[ 2] != '.') || (ext_dir_and_name[ 3] != '.'))
+ {
+ /* Normal relative path. Drop first "[." (or "<."). */
+ dir_len -= 2;
+ ext_dir_and_name += 2;
+ }
+ }
+ else
+ {
+ /* Absolute path. Skip first "[" (or "<"). */
+ dir_len -= 1;
+ ext_dir_and_name += 1;
+
+ /* 2007-04-26 SMS.
+ Skip past "000000." or "000000]" (or "000000>"), which should
+ not be stored in the archive. This arises, for example, with
+ "zip -r archive [000000]foo.dir"
+ */
+#define MFD "000000"
+
+ if ((strncmp( ext_dir_and_name, MFD, strlen( MFD)) == 0) &&
+ ((ext_dir_and_name[ 6] == '.') ||
+ (ext_dir_and_name[ 6] == ']') ||
+ (ext_dir_and_name[ 6] == '>')))
+ {
+ dir_len -= 7;
+ ext_dir_and_name += 7;
+ }
+ }
+ }
+ else
+ {
+ /* Junking paths. Skip the whole directory spec. */
+ ext_dir_and_name += dir_len;
+ dir_len = 0;
+ }
+
+ /* Malloc space for internal name and copy it. */
+ if ((n = malloc(strlen( ext_dir_and_name)+ 1)) == NULL)
return NULL;
- strcpy(n, t);
+ strcpy( n, ext_dir_and_name);
- if (((t = strrchr(n, PATH_END)) != NULL) ||
- (t = strrchr(n, PATH_END2)) != NULL)
+ /* Convert VMS directory separators (".") to "/". */
+ if (dir_len > 0)
{
- *t = '/';
- while (--t > n)
- if (*t == '.')
- *t = '/';
+ for (nn = n; nn < n+ dir_len; nn++)
+ {
+ chr = *nn;
+ if (chr == '^')
+ {
+ /* Skip ODS5 extended name escaped characters. */
+ nn++;
+ /* If escaped char is a hex digit, skip the second hex digit, too. */
+ if (char_prop[ (unsigned char) *nn]& 64)
+ nn++;
+ }
+ else if ((chr == '.') || ((nn == n) && ((chr == '[') || (chr == '<'))))
+ {
+ /* Convert VMS directory separator (".", or initial "[" or "<"
+ of "[..." or "<...") to "/".
+ */
+ *nn = '/';
+ }
+ }
+ /* Replace directory end character (typically "]") with "/". */
+ n[ dir_len- 1] = '/';
}
- /* Fix from Greg Roelofs: */
- /* Get current working directory and strip from n (t now = n) */
+ /* If relative path, then strip off the current directory. */
+ if (relative_dir_s)
{
- char cwd[256], *p, *q;
- int c;
+ char cwd[ NAM_MAXRSS+ 1];
+ char *cwd_dir_only;
+ char *q;
+ int cwd_dir_only_len;
- q = getcwd( cwd, 256);
+ q = getcwd( cwd, (sizeof( cwd)- 1));
/* 2004-09-24 SMS.
With SET PROCESSS /PARSE = EXTENDED, getcwd() can return a
@@ -466,63 +950,149 @@ int *pdosflag; /* output: force MSDOS file attributes? */
comparison around here.
*/
-#if 0 /* fix by Igor */
- if ((q != NULL) && ((p = strchr(cwd, '.')) != NULL))
-#else
- if ((q != NULL) && ((p = strchr(cwd, PATH_START)) != NULL ||
- (p = strchr(cwd, PATH_START2)) != NULL))
-#endif
+ /* Locate the directory part of the external name. */
+ dir_len = find_dir( q, &cwd_dir_only);
+ if (dir_len > 0)
{
- if (*(++p) == '.')
- p++;
- if ((q = strrchr(p, PATH_END)) != NULL ||
- (q = strrchr(p, PATH_END2)) != NULL)
+ /* Skip first "[" (or "<"). */
+ cwd_dir_only++;
+ /* Convert VMS directory separators (".") to "/". */
+ for (q = cwd_dir_only; q < cwd_dir_only+ dir_len; q++)
{
- *q = '/';
- while (--q > p)
- if (*q == '.')
- *q = '/';
+ chr = *q;
+ if (chr == '^')
+ {
+ /* Skip ODS5 extended name escaped characters. */
+ q++;
+ /* If escaped char is a hex digit, skip the second hex digit, too. */
+ if (char_prop[ (unsigned char) *q]& 64)
+ q++;
+ }
+ else if (chr == '.')
+ {
+ /* Convert VMS directory separator (".") to "/". */
+ *q = '/';
+ }
+ }
+ /* Replace directory end character (typically "]") with "/". */
+ cwd_dir_only[ dir_len- 2] = '/';
+ }
+
+ /* If the slash-converted cwd matches the front of the internal
+ name, then shuffle the remainder of the internal name to the
+ beginning of the internal name storage.
+
+ Because we already know that the path is relative, this test may
+ always succeed.
+ */
+ cwd_dir_only_len = strlen( cwd_dir_only);
+ if (strncasecmp( n, cwd_dir_only, cwd_dir_only_len) == 0)
+ {
+ nn = n+ cwd_dir_only_len;
+ q = n;
+ while (*q++ = *nn++);
+ }
+ } /* (relative_dir_s) */
+
+ /* 2007-05-22 SMS.
+ * If a device name is present, assume that it's a real (VMS) file
+ * specification, and do down-casing according to the ODS2 or ODS5
+ * down-casing policy. If no device name is present, assume that it's
+ * a pattern ("-i", ...), and do no down-casing here. (Case
+ * sensitivity in patterns is handled elsewhere.)
+ */
+ if (explicit_dev( x))
+ {
+ /* If ODS5 is possible, do complicated down-case check.
- /* strip bogus path parts from n */
- if (strncasecmp( n, p, (c = strlen( p))) == 0)
+ Note that the test for ODS2/ODS5 is misleading and over-broad.
+ Here, "ODS2" includes anything from DVI$C_ACP_F11V1 (=1, ODS1) up
+ to (but not including) DVI$C_ACP_F11V5 (= 11, DVI$C_ACP_F11V5),
+ while "ODS5" includes anything from DVI$C_ACP_F11V5 on up. See
+ DVIDEF.H.
+ */
+
+#if defined( DVI$C_ACP_F11V5) && defined( NAML$C_MAXRSS)
+
+ /* Check options and/or ODS level for down-case or preserve case. */
+ down_case = 0; /* Assume preserve case. */
+ if ((vms_case_2 <= 0) && (vms_case_5 < 0))
+ {
+ /* Always down-case. */
+ down_case = 1;
+ }
+ else if ((vms_case_2 <= 0) || (vms_case_5 < 0))
+ {
+ /* Down-case depending on ODS level. (Use (full) external name.) */
+ ods_level = file_sys_type( x);
+
+ if (ods_level > 0)
+ {
+ /* Valid ODS level. (Name (full) contains device.)
+ * Down-case accordingly.
+ */
+ if (((ods_level < DVI$C_ACP_F11V5) && (vms_case_2 <= 0)) ||
+ ((ods_level >= DVI$C_ACP_F11V5) && (vms_case_5 < 0)))
{
- q = n + c;
- while (*t++ = *q++)
- ;
+ /* Down-case for this ODS level. */
+ down_case = 1;
}
}
}
- }
-#ifndef VMS_PRESERVE_CASE
- strlower( n);
-#endif /* ndef VMS_PRESERVE_CASE */
+#else /* defined( DVI$C_ACP_F11V5) && defined( NAML$C_MAXRSS) */
+
+/* No case-preserved names are possible (VAX). Do simple down-case check. */
+
+ down_case = (vms_case_2 <= 0);
+
+#endif /* defined( DVI$C_ACP_F11V5) && defined( NAML$C_MAXRSS) [else] */
+
+ /* If down-casing, convert to lower case. */
+ if (down_case != 0)
+ {
+ strlower( n);
+ }
+ }
/* Remove simple ODS5 extended file name escape characters. */
eat_carets( n);
if (isdir)
{
- if (strcasecmp( (t = n + strlen( n) - 6), ".DIR;1"))
+ if (strcasecmp( (nn = n+ strlen( n)- DIR_TYPE_VER_LEN), DIR_TYPE_VER))
error("directory not version 1");
else
if (pathput)
- strcpy(t, "/");
+ strcpy( nn, "/");
else
*n = '\0'; /* directories are discarded with zip -rj */
}
- else if (!vmsver)
- if ((t = strrchr(n, ';')) != NULL)
- *t = '\0';
+ else if (vmsver == 0)
+ {
+ /* If not keeping version numbers, truncate the name at the ";".
+ (No escaped characters are expected in the version.)
+ */
+ if ((ext_dir_and_name = strrchr( n, ';')) != NULL)
+ *ext_dir_and_name = '\0';
+ }
+ else if (vmsver > 1)
+ {
+ /* Keeping version numbers, but as ".nnn", not ";nnn". */
+ if ((ext_dir_and_name = strrchr( n, ';')) != NULL)
+ *ext_dir_and_name = '.';
+ }
- if ((t = strrchr(n, '.')) != NULL)
+ /* Remove a type-less dot. */
+ /* (Note that currently "name..ver" is not altered.) */
+ if ((ext_dir_and_name = strrchr( n, '.')) != NULL)
{
- if ( t[1] == '\0') /* "filename." -> "filename" */
- *t = '\0';
- else if (t[1] == ';') /* "filename.;vvv" -> "filename;vvv" */
+ if (ext_dir_and_name[ 1] == '\0') /* "name." -> "name" */
+ *ext_dir_and_name = '\0';
+ else if (ext_dir_and_name[ 1] == ';') /* "name.;ver" -> "name;ver" */
{
- char *f = t+1;
- while (*t++ = *f++) ;
+ char *f = ext_dir_and_name+ 1;
+ while (*ext_dir_and_name++ = *f++);
}
}
@@ -532,47 +1102,219 @@ int *pdosflag; /* output: force MSDOS file attributes? */
/* Returned malloc'ed name */
if (pdosflag)
*pdosflag = dosflag;
+
return n;
}
-char *in2ex(n)
-char *n; /* internal file name */
+char *in2ex( char *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 */
+ int i;
+ char chr;
+ char *endp;
+ char *last_slash;
+ char *versionp;
+
+#ifdef NAML$C_MAXRSS
+
+ char buf[ NAML$C_MAXRSS+ 1];
+ unsigned char prop;
+ unsigned char uchr;
+ char *last_dot;
- if ((t = strrchr(n, '/')) == NULL)
+#endif /* def NAML$C_MAXRSS */
+
+ /* Locate the last slash. */
+ last_slash = strrchr( n, '/');
+
+/* If ODS5 is possible, replace escape carets in name. */
+
+#ifdef NAML$C_MAXRSS
+
+ endp = n+ strlen( n);
+
+ /* Locate the version delimiter, if one is expected. */
+ if (vmsver == 0)
+ { /* No version expected. */
+ versionp = endp;
+ }
+ else
+ {
+ if (vmsver > 1)
+ { /* Expect a dot-version, ".nnn". Locate the version ".".
+ Temporarily terminate at this dot to allow the last-dot search
+ below to find the last non-version dot.
+ */
+ versionp = strrchr( n, '.');
+ if (versionp != NULL) /* Can't miss. */
+ {
+ *versionp = '\0';
+ }
+ }
+ else
+ { /* Expect a semi-colon-version, ";nnn". Locate the ";". */
+ versionp = strrchr( n, ';');
+ }
+ if ((versionp == NULL) || (versionp < last_slash))
+ { /* If confused, and the version delimiter was not in the name,
+ then ignore it.
+ */
+ versionp = endp;
+ }
+ }
+
+ /* No escape needed for the last dot, if it's part of the file name.
+ All dots in a directory must be escaped.
+ */
+ last_dot = strrchr( n, '.');
+
+ if ((last_dot != NULL) && (last_slash != NULL) && (last_dot < last_slash))
+ {
+ last_dot = last_slash;
+ }
+
+ /* Replace the version dot if necessary. */
+ if ((vmsver > 1) && (versionp != NULL) && (versionp < endp))
+ {
+ *versionp = '.';
+ }
+
+ /* Add ODS5 escape sequences. Leave "/" and "?" for later.
+ The name here looks (roughly) like: dir1/dir2/a.b
+ */
+ t = n;
+ x = buf;
+ while (uchr = *t++)
+ {
+ /* Characters in the version do not need escaping. */
+ if (t <= versionp)
+ {
+ prop = char_prop[ uchr]& 31;
+ if (prop)
+ {
+ if (prop& 4)
+ { /* Dot. */
+ if (t < last_dot)
+ {
+ /* Dot which must be escaped. */
+ *x++ = '^';
+ }
+ }
+ else if (prop& 8)
+ {
+ /* Character needing hex-hex escape. */
+ *x++ = '^';
+ *x++ = hex_digit[ uchr>> 4];
+ uchr = hex_digit[ uchr& 15];
+ }
+ else
+ {
+ /* Non-dot character which must be escaped (and simple works).
+ "?" gains the caret but remains "?" until later.
+ ("/" remains (unescaped) "/".)
+ */
+ *x++ = '^';
+ if (prop& 2)
+ {
+ /* Escaped space (represented as "^_"). */
+ uchr = '_';
+ }
+ }
+ }
+ }
+ *x++ = uchr;
+ }
+ *x = '\0';
+
+ /* Point "n" to altered name buffer, and re-find the last slash. */
+ n = buf;
+ last_slash = strrchr( n, '/');
+
+#endif /* def NAML$C_MAXRSS */
+
+ if ((t = last_slash) == NULL)
{
- if ((x = malloc(strlen(n) + 1 + PAD)) == NULL)
+ if ((x = malloc(strlen(n) + 1 + DIR_PAD)) == NULL)
return NULL;
strcpy(x, n);
}
else
{
- if ((x = malloc(strlen(n) + 3 + PAD)) == NULL)
+ if ((x = malloc(strlen(n) + 3 + DIR_PAD)) == NULL)
return NULL;
- x[0] = PATH_START;
- x[1] = '.';
- strcpy(x + 2, n);
- *(t = x + 2 + (t - n)) = PATH_END;
+
+ /* Begin with "[". */
+ x[ 0] = '[';
+ i = 1;
+ if (*n != '/')
+ {
+ /* Relative path. Add ".". */
+ x[ i++] = '.';
+ }
+ else
+ {
+ /* Absolute path. Skip leading "/". */
+ n++;
+ }
+ strcpy( (x+ i), n);
+
+ /* Place the final ']'. Remember where the name starts. */
+ *(t = x + i + (t - n)) = ']';
+ last_slash = t;
+
+ /* Replace "/" with ".", and "?" with (now escaped) "/", in the
+ directory part of the name.
+ */
while (--t > x)
- if (*t == '/')
+ {
+ chr = *t;
+ if (chr == '/')
+ {
*t = '.';
+ }
+ else if (chr == '?')
+ {
+ *t = '/';
+ }
+ }
+
+ /* Replace "?" with (now escaped) "/", in the non-directory part of
+ the name.
+ */
+ while ((chr = *(++last_slash)) != '\0')
+ {
+ if (chr == '?')
+ {
+ *last_slash = '/';
+ }
+ }
+ }
+
+/* If case preservation is impossible (VAX, say), and down-casing, then
+ up-case. If case preservation is possible and wasn't done, then
+ there's no way to ensure proper restoration of original case, so
+ don't try. This may differ from pre-3.0 behavior.
+*/
+#ifndef NAML$C_MAXRSS
+
+ if (vms_case_2 <= 0)
+ {
+ strupper( x);
}
-#ifndef VMS_PRESERVE_CASE
- strupper( x);
-#endif /* ndef VMS_PRESERVE_CASE */
+#endif /* ndef NAML$C_MAXRSS */
return x;
}
-void stamp(f, d)
-char *f; /* name of file to change */
-ulg d; /* dos-style time to change it to */
+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. */
{
int tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year;
@@ -601,11 +1343,11 @@ ulg d; /* dos-style time to change it to */
zipwarn("can't set zipfile time: ", f);
}
-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 */
+ulg filetime( char *f, ulg *a, zoff_t *n, iztimes *t)
+/* char *f; name of file to get info on */
+/* ulg *a; return value: file attributes */
+/* zoff_t *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
@@ -619,7 +1361,7 @@ iztimes *t; /* return value: access, modific. and creation times */
a file size of -1 */
{
struct stat s; /* results of stat() */
- /* malloc name so not dependent on FNMAX - 11/8/04 EG */
+ /* convert to a malloc string dump FNMAX - 11/8/04 EG */
char *name;
int len = strlen(f);
@@ -679,8 +1421,9 @@ iztimes *t; /* return value: access, modific. and creation times */
#endif
}
-int deletedir(d)
-char *d; /* directory to delete */
+int deletedir( char *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]).
@@ -699,5 +1442,3 @@ char *d; /* directory to delete */
free(s);
return r;
}
-
-#endif /* !UTIL */
diff --git a/vms/zip.opt b/vms/zip.opt
new file mode 100644
index 0000000..7a4a872
--- /dev/null
+++ b/vms/zip.opt
@@ -0,0 +1 @@
+Ident = "Zip 3.0"
diff --git a/vms/zip_cli.cld b/vms/zip_cli.cld
index 714b23c..38fc421 100644
--- a/vms/zip_cli.cld
+++ b/vms/zip_cli.cld
@@ -1,5 +1,5 @@
Module ZIP_CLITABLE
- Ident "02-006"
+ Ident "03-001"
Define Verb ZIP
Parameter P1, Label=ZIPFILE, Prompt="Zip file"
@@ -17,57 +17,152 @@ Define Verb ZIP
Qualifier BATCH, NonNegatable, VALUE(type=$FILE)
Qualifier BEFORE, NonNegatable, VALUE(type=$DATETIME)
Qualifier COMMENTS, NonNegatable,
- VALUE(type=COMMENTS_KEYWORDS)
+ VALUE(list,type=COMMENTS_KEYWORDS)
+ Qualifier COMPRESSION, NonNegatable, VALUE(type=COMPRESS_OPTS)
+ Qualifier COPY_ENTRIES, NonNegatable
+ Qualifier DESCRIPTORS, NonNegatable
+ Qualifier DIFFERENCE, NonNegatable
Qualifier DIRNAMES, Negatable, Default
+ Qualifier DISPLAY, NonNegatable,
+ VALUE(type=DISPLAY_KEYWORDS, required, list)
+ Qualifier DOT_VERSION, NonNegatable
Qualifier ENCRYPT, Negatable, VALUE
- Qualifier EXTRA_FIELDS, Negatable, Default
- Qualifier FIX_ARCHIVE, NonNegatable, VALUE(type=FIX_OPTIONS)
+ Qualifier EXTRA_FIELDS, Negatable, VALUE(type=EXTRA_OPTS)
+ Qualifier FILESYNC, NonNegatable
+ Qualifier FIX_ARCHIVE, NonNegatable, VALUE(type=FIX_OPTS)
Qualifier FULL_PATH, Negatable, Default
- Qualifier HELP, NonNegatable
+ Qualifier GROW, NonNegatable
+ Qualifier HELP, NonNegatable, VALUE(type=HELP_OPTS)
Qualifier JUNK, NonNegatable
Qualifier KEEP_VERSION, Negatable
Qualifier LATEST, NonNegatable
Qualifier LEVEL, VALUE(type=$NUMBER,required)
Qualifier LICENSE, NonNegatable
+ Qualifier LOG_FILE, NonNegatable,
+ VALUE(list, required, type=LOG_OPTS)
+ Qualifier MUST_MATCH, NonNegatable
+ Qualifier OUTPUT, VALUE(required,type=$FILE)
+ Qualifier PATTERN_CASE, NonNegatable, VALUE(type=PATT_CASE_OPTS)
+ Qualifier PAUSE, Negatable
Qualifier PKZIP, Negatable
+ Qualifier PRESERVE_CASE, Negatable,
+ VALUE(type=PRES_CASE_OPTS, list)
Qualifier QUIET, NonNegatable
Qualifier RECURSE, Negatable, VALUE(type=RECURSE_OPTS)
+ Qualifier SHOW, NonNegatable,
+ VALUE(type=SHOW_KEYWORDS, required, list)
Qualifier SINCE, NonNegatable, VALUE(type=$DATETIME)
+ Qualifier SPLIT, NonNegatable,
+ VALUE(list, required, type=SPLIT_OPTS)
Qualifier STORE_TYPES, NonNegatable, VALUE(required,list)
+ Qualifier SYMLINKS, NonNegatable
Qualifier TEMP_PATH, VALUE(required,type=$FILE)
- Qualifier TEST, NonNegatable
+ Qualifier TEST, NonNegatable, VALUE(type=TEST_OPTS)
Qualifier TRANSLATE_EOL, NonNegatable,
VALUE(type=EOL_KEYWORDS)
Qualifier UNSFX, NonNegatable
- Qualifier VERBOSE, NonNegatable, VALUE(type=VERBOSE_OPTS)
+ Qualifier VERBOSE, NonNegatable,
+ VALUE(type=VERBOSE_OPTS, list)
Qualifier VMS, NonNegatable, VALUE(type=VMS_OPTS)
+ Qualifier WILDCARD, VALUE(type=WILDCARD_OPTS)
Qualifier YYZ_ZIP, NonNegatable, Default
+ Qualifier ZIP64, NonNegatable
+ Disallow COPY_ENTRIES and (DELETE or FRESHEN or UPDATE)
+ Disallow DELETE and (COPY_ENTRIES or FRESHEN or UPDATE)
+ Disallow FRESHEN and (COPY_ENTRIES or DELETE or UPDATE)
+ Disallow UPDATE and (COPY_ENTRIES or DELETE or FRESHEN)
+ Disallow DIFFERENCE and (neg OUTPUT)
+ Disallow DIFFERENCE and
+ (FIX_ARCHIVE.NORMAL or FIX_ARCHIVE.FULL or
+ COPY_ENTRIES or DELETE)
+ Disallow APPEND and GROW
Disallow FIX_ARCHIVE.NORMAL and FIX_ARCHIVE.FULL
+ Disallow (FIX_ARCHIVE.NORMAL or FIX_ARCHIVE.FULL) and
+ (neg OUTPUT)
Disallow TRANSLATE_EOL.LF and TRANSLATE_EOL.CRLF
Disallow FULL_PATH and JUNK
Disallow RECURSE.PATH and RECURSE.FILENAMES
+ Disallow (neg EXTRA_FIELDS) and
+ (KEEP_EXISTING or EXTRA_FIELDS.NORMAL)
+
+Define Type PATT_CASE_OPTS
+ Keyword BLIND
+ Keyword SENSITIVE, DEFAULT
Define Type COMMENTS_KEYWORDS
- Keyword ZIP_FILE, DEFAULT
+ Keyword ARCHIVE, DEFAULT
Keyword FILES
+ Keyword ZIP_FILE
-Define Type FIX_OPTIONS
- Keyword NORMAL, DEFAULT
- Keyword FULL
+Define Type COMPRESS_OPTS
+ Keyword BZIP2
+ Keyword DEFLATE, DEFAULT
+ Keyword STORE
+
+Define Type DISPLAY_KEYWORDS
+ Keyword BYTES
+ Keyword COUNTS
+ Keyword DOTS, VALUE
+ Keyword GLOBALDOTS
+ Keyword USIZE
+ Keyword VOLUME
Define Type EOL_KEYWORDS
Keyword LF, DEFAULT
Keyword CRLF
+Define Type EXTRA_OPTS
+ Keyword NORMAL, DEFAULT
+ Keyword KEEP_EXISTING
+
+Define Type FIX_OPTS
+ Keyword NORMAL, DEFAULT
+ Keyword FULL
+
+Define Type HELP_OPTS
+ Keyword NORMAL, DEFAULT
+ Keyword EXTENDED
+
+Define Type LOG_OPTS
+ Keyword APPEND, Negatable
+ Keyword INFORMATIONAL, Negatable
+ Keyword FILE, NonNegatable, VALUE(required, type=$FILE)
+
+Define Type PRES_CASE_OPTS
+ Keyword NOODS2
+ Keyword NOODS5
+ Keyword ODS2
+ Keyword ODS5
+
Define Type RECURSE_OPTS
Keyword PATH, DEFAULT
Keyword FILENAMES
+Define Type SHOW_KEYWORDS
+ Keyword COMMAND
+ Keyword DEBUG
+ Keyword FILES
+ Keyword OPTIONS
+
+Define Type SPLIT_OPTS
+ Keyword BELL, Negatable
+ Keyword PAUSE, Negatable
+ Keyword SIZE, VALUE(required)
+ Keyword VERBOSE, Negatable
+
+Define Type TEST_OPTS
+ Keyword UNZIP, VALUE(required)
+
Define Type VERBOSE_OPTS
+ Keyword NORMAL, DEFAULT
Keyword MORE
Keyword DEBUG
+ Keyword COMMAND
Define Type VMS_OPTS
Keyword ALL
+Define Type WILDCARD_OPTS
+ Keyword NOSPAN
+
diff --git a/vms/zip_cli.help b/vms/zip_cli.help
index 3236e48..1bb39c2 100644
--- a/vms/zip_cli.help
+++ b/vms/zip_cli.help
@@ -32,77 +32,577 @@
.! Updated for new options of Zip 2.2.
.! 01-006 Christian Spieler 14-OCT-1997 22:04
.! Cleanups for Zip 2.2 release (no version change).
+.! 01-007 Steven Schweda 15-MAY-2007
+.! Zip 3.0.
+.! 01-007 Ed Gordon 15-MAY-2007
+.! Minor updates to Zip 3.0 help.
.!
<INIT>
<MAIN>
ZIP
-Zip is a compression and file packaging utility for Unix, MSDOS, OS/2, and
-VMS. It is analogous to a combination of tar and compress and is
-compatible with PKZIP (Phil Katz ZIP) for MSDOS systems.
+Zip is a compression and file packaging utility for several operating
+systems, including UNIX, VMS, MSDOS, OS/2, Windows 9x/NT/XP, Minix,
+Atari, Macintosh, Amiga, and Acorn RISC OS. It is analogous to a
+combination of tar and compress and is compatible with PKZIP (Phil
+Katz's ZIP) for MSDOS systems.
-There is a companion to Zip called UnZip (of course). Zip and UnZip can
-work with files produced by PKZIP under MSDOS, and PKZIP and PKUNZIP can
-work with files produced by Zip.
+Zip 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. A companion program, UnZip, unpacks Zip
+archives.
-Zip 2.2 is compatible with PKZIP 2.04.
-Note that PKUNZIP 1.10 cannot extract files produced by PKZIP 2.04
-or zip 2.2. You must use PKZIP 2.04g or unzip 5.0p1 (or later versions)
-to extract them.
+For brief help on Zip or UnZip, run the program without specifying any
+parameters on the command line.
-For a brief help on Zip and Unzip, run each without specifying any
-parameters on the command line. If you want to get the help screen
-describing the alternate UNIX style command interface, you must
-specify the -h option.
+This description covers the Zip program which uses a VMS-style CLI
+command line. The VMS CLI Zip program also accepts UNIX-style "-opt"
+options, but a separate Zip program is available which provides only a
+UNIX-style command line, and it has its own documentation. Refer to
+the Zip installation instructions for details.
-Zip puts one or more compressed files into a single "zip file" along with
-information about the files, including the name, path if requested, date
-and time last modified, protection, and check information to verify the
-fidelity of each entry. Zip can pack an entire directory structure in a
-zip file with a single command. Compression ratios of 2:1 to 3:1 are
-common for text files. Zip has has one compression method (deflation) and
-can also store files without compression. It automatically chooses the better
-of the two for each file to be compressed.
+<FORMAT>
+ZIP [/options] archive inpath, inpath ...
-Zip is useful for packaging a set of files to send to someone or for
-distribution; for archiving or backing up files; and for saving disk space
-by temporarily compressing unused files or directories.
+.!
+<TOPIC>
+Basic_Usage
<FORMAT>
-ZIP zipfile [file[,...]] [/qualifiers]
+ZIP [/options] archive inpath, inpath ...
+
+The default action of Zip is to add or replace entries in "archive" from
+the list of "inpath" file specifications, which can include directories
+and file names with VMS-style wildcards. If /BATCH is specified, Zip
+will read file specifications from a list file or from SYS$INPUT
+(stdin).
+
+With SET PROCESS /PARSE_STYLE = EXTENDED (available on recent non-VAX
+systems), Zip preserves the case of the command line. Otherwise, mixed-
+or upper-case arguments (file names) must be quoted. Examples in this
+document generally do not show this quotation, so VAX and /PARSE_STYLE =
+TRADITIONAL users (that is, troglodytes) will need to add quotation
+where needed when working with these examples.
+
+General
+
+Zip reads one or more files, compresses the data (normally), and stores
+the compressed information into a single Zip archive file, along with
+information about each file (name, path, date and time of last
+modification, protection, and check information to verify file
+integrity). On a VMS system, Zip can also save VMS/RMS file attributes,
+allowing UnZip to restore the files without loss of important file
+attributes. Zip can pack an entire directory structure into a Zip
+archive with a single command.
+
+Compression
+
+Compression ratios of 2:1 to 3:1 are common for text files. Zip has one
+standard compression method ("deflate") and can also store files without
+compression. Zip (and UnZip) may be built with optional support for the
+bzip2 compression method. Then, the user may select bzip2 compression
+instead of the default "deflate" method. Zip automatically chooses
+simple storage over compression for a file, if the specified compression
+method does not actually compress the data in that file.
+
+Compatibility
+
+Zip and UnZip 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 Zip (with some exceptions, notably streamed
+archives, but recent changes in the .ZIP file standard may facilitate
+better compatibility). Zip version 3.0 is compatible with PKZIP 2.04
+and also supports the Zip64 extensions of PKZIP 4.5 which allows
+archives as well as files to exceed the previous 2 GB limit (4 GB in
+some cases). Zip also supports bzip2 compression if the bzip2 library
+is included when Zip is built. Note that PKUNZIP 1.10 cannot extract
+files produced by PKZIP 2.04 or Zip 3.0. You must use PKUNZIP 2.04g or
+UnZip 5.0p1 (or later versions) to extract them.
+
+Large Archives and Zip64
+
+Where the operating system and C run-time support allow, Zip 3.0 and
+UnZip 6.0 (and later versions) support large files (input and archive),
+using the Zip64 extensions to the original .ZIP file format. On VMS,
+this genarally means non-VAX systems with VMS V7.2 or later (perhaps
+requiring a C RTL ECO before VMS V7.3-2).
+
+Zip automatically uses the Zip64 extensions when a file 4 GB or larger
+is added to an archive, an archive containing a Zip64 entry 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 to a
+non-seekable output device. You must use a 4.5 compatible UnZip to
+extract files using the Zip64 extensions such as UnZip 6.0 or later.
+
+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 file standard now include some
+support for the data descriptor format Zip uses).
+
+<TOPIC>
+More_Usage
+
+Here is a very simple example of Zip use:
+
+<LITERAL>
+| zip stuff.zip *.*
+<LARETIL>
+
+This will create the Zip archive "stuff.zip" (assuming it does not
+already exist) and put all the (non-directory) files (";0") from the
+current default directory into "stuff.zip" in a compressed form. The
+archive is opened using a default file specification of
+"SYS$DISK:[].zip", so specifying "stuff" as the archive name would also
+create (or use an existing) "stuff.zip", but specifying "stuff.other"
+would give you that name. In general, Zip doesn't care about the type
+in the file specification, but for split archives (archives split over
+multiple files), the user should normally specify a type-less name,
+because Zip will normally generate sequentially numbered types ".z01",
+".z02", and so on for the early splits, and then the required ".zip" for
+the last split. These file types are required by the Zip standard for
+split archives.
+
+Standard VMS wildcard expansion ($SEARCH) is used to interpret the
+"inpath" file and directory specifications, like the "*.*" in this
+example.
+
+On VMS, the most natural way to archive an entire directory tree is to
+use a directory-depth wildcard ("[...]"). For example:
+
+<LITERAL>
+| zip foo [...]*.*
+<LARETIL>
+
+This will create the file "foo.zip" containing all the files (";0") and
+directories in and below the current default directory. A more
+UNIX-like way to do this would be to use the /RECURSE option:
+
+<LITERAL>
+| zip /recurse foo *.*
+<LARETIL>
+
+Zip avoids including its own output files when selecting files to
+include in the archive, so it should be safe, as in this case, to create
+the archive in the same drectory as the input files.
+
+One or more specific files, directories, or subdirectories may also be
+specified:
+
+<LITERAL>
+| zip foo.zip readme.txt, [www...]*.*, [.ftp...]*.*, -
+| [.src]*.h, [.src]*.c
+<LARETIL>
+
+For security reasons, paths in Zip archives are always stored as
+relative paths, so some care is needed when creating an archive so that
+it will create the intended directory structure when UnZip is used to
+unpack it.
+
+To use /RECURSE with a specific directory, the name of the directory
+file itself must be specified:
+
+<LITERAL>
+| zip /recurse foo.zip [000000]www.dir, ftp.dir
+<LARETIL>
+
+You may want to make an archive that contains the files in [.foo], but
+not record the directory name, "foo". You can use the /JUNK (junk path)
+option to leave off the path:
+
+<LITERAL>
+| zip /junk foo [.foo]*.*
+<LARETIL>
+
+If you are short on disk space, you might not have enough room to hold
+both the original directory and the corresponding compressed Zip
+archive. In this case, you can create the archive in steps, and use the
+-m option. For example, if [.foo] contains the subdirectories [.tom],
+[.dick], and [.harry], you could:
+
+<LITERAL>
+| zip /move foo [.foo.tom...]*.*
+| zip /move foo [.foo.dick...]*.*
+| zip /move foo [.foo.harry...]*.*
+<LARETIL>
+
+The first command would create foo.zip, and the next two would add to
+it. The /MOVE option will cause Zip to delete all files added to the
+archive after making or updating foo.zip. No deletions will be done
+until the Zip operation has completed with no errors. This option is
+obviously dangerous and should be used with care, but it does reduce the
+need for free disk space. When /MOVE is used, the /TEST option is
+recommended and will test the resulting archive before deleting the
+input files.
+
+If a file specification list is too long to fit conveniently on the Zip
+command line, the /BATCH option can be used to cause Zip to read a list
+of file specifications from a file or from SYS$INPUT (stdin). If a DCL
+command procedure is used, the names can be specified in the procedure:
+
+<LITERAL>
+| $ zip foo /batch
+| $ deck
+| file_spec_1
+| file_spec_2
+| file_spec_3
+| $ eod
+<LARETIL>
+
+The file specifications can also be put into a separate file, and fed
+into Zip by specifying that file as "/BATCH = list_file", or by
+explicitly defining SYS$INPUT, or by using PIPE. For example, with the
+list in foo.zfl:
+<LITERAL>
+| zip foo /batch = foo.zfl
+<LARETIL>
+or:
+<LITERAL>
+| define /user_mode sys$input foo.zfl
+| zip foo /batch
+<LARETIL>
+or:
+<LITERAL>
+| pipe type foo.zfl | zip foo /batch
+<LARETIL>
+
+If Zip is not able to read a file, it issues a warning but continues.
+See the /MUST_MATCH option for more on how Zip 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.
+<TOPIC>
+Environment
+
+A user can specify default command-line options and arguments by
+defining an "environment variable" (that is, a logical name or DCL
+symbol), "ZIP_OPTS" or "ZIPOPT", to specify them. If both "ZIP_OPTS"
+and "ZIPOPT" are specified, the definition of "ZIPOPT" prevails.
+
+UNIX-style command-line options are required in these variables, even
+for the VMS CLI Zip program. For details, see the help topic
+UNIX_Options, or the separate Zip help for the UNIX-style command line.
+
+The C RTL function getenv() is used to sense these variables, so its
+behavior determines what happens if both a logical name and a symbol are
+defined. As of VMS V7.3, a logical name supercedes a symbol.
+
+The "zip /VERBOSE" report should show the perceived settings of these
+variables.
+
+For example, the following will cause Zip to skip directories, include
+VMS portable attribute information, and perform all operations at
+quiet-level 1 by default:
+
+<LITERAL>
+| $ define ZIP_OPTS "-qDV"
+<LARETIL>
+
+Note that the quotation marks here are required to preserve lowercase
+options (opposite of the command-line behavior).
+
+<TOPIC>
+Exit_Status
+
+On VMS, Zip's UNIX-style exit values are mapped into VMS-style status
+codes with facility code 1955 = %x7A3, and with the inhibit-message
+(%x10000000) and facility-specific (%x00008000) bits set:
+
+<LITERAL>
+| %x17A38001 normal exit
+| %x17A38000+ 16* Zip_error_code warnings
+| %x17A38002+ 16* Zip_error_code normal errors
+| %x17A38004+ 16* Zip_error_code fatal errors
+<LARETIL>
+
+Note that multiplying the UNIX-style Zip error code by 16 places it
+conveniently in the hexadecimal representation of the VMS exit code,
+"__" in %x17A38__s, where "s" is the severity code. For example, a
+truncated archive might cause Zip error code 2, which would be
+transformed into the VMS exit status %x17A38024.
+
+The Zip VMS exit codes include severity values which approximate those
+defined by PKWARE, as shown in the following table:
+
+<LITERAL0>
+| VMS Zip err
+|severity code Error description
+|---------+---------+----------------------------------------------
+|Success 0 (OK) Normal; no errors or warnings detected.
+|Fatal 2 (EOF) Unexpected end of archive.
+|Error 3 (FORM) A generic error in the archive format
+| was detected. Processing may have completed
+| successfully anyway; some broken archives
+| created by other archivers have simple work-
+| arounds.
+|Fatal 4 (MEM) Zip was unable to allocate memory for
+| one or more buffers during program initializ-
+| ation.
+|Fatal 5 (LOGIC) A severe error in the archive format
+| was detected. Processing probably failed
+| immediately.
+|Error 6 (BIG) Entry too large to split, read, or
+| write.
+|Error 7 (NOTE) Invalid comment format.
+|Fatal 8 (TEST) Zip -T failed or out of memory.
+|Error 9 (ABORT) The user aborted zip prematurely
+| with control-C (or equivalent).
+|Fatal 10 (TEMP) Zip encountered an error while using
+| a tempfile.
+|Fatal 11 (READ) Read or seek error.
+|Warning 12 (NONE) Zip has nothing to do.
+|Error 13 (NAME) Missing or empty zip file.
+|Fatal 14 (WRITE) Error writing to a file.
+|Fatal 15 (CREAT) Zip was unable to create a file to
+| write to.
+|Error 16 (PARMS) Bad command line parameters.
+|Error 18 (OPEN) Zip could not open a specified file
+| to read.
+|Fatal 19 (COMPERR) Zip was built with options not
+| supported on this system.
+|Fatal 20 (ZIP64) Attempt to read unsupported Zip64
+| archive.
+<0LARETIL>
+
+<TOPIC>
+File_Names
+
+Zip deals with file names in the system file system and with file names
+in Zip archives. File names in a Zip archive are stored in a UNIX-like
+path-name format. For example, a VMS file specification like this:
+
+<LITERAL>
+[.zip30.vms]descrip.mms
+<LARETIL>
+
+could appear in a Zip archive as:
+
+<LITERAL>
+zip30/vms/descrip.mms
+<LARETIL>
+
+For security reasons, paths in Zip archives are always stored as
+relative paths, so an absolute VMS directory specification will be
+transformed to a relative path in the archive (that is, no leading "/").
+For example, the following absolute directory specification would give
+the same archive path as the previous (relative) example:
+
+<LITERAL>
+[zip30.vms]descrip.mms
+<LARETIL>
+
+Also, device names are dropped, so the following file specification
+would also give the same archive path:
+
+<LITERAL>
+sys$sysdevice:[zip30.vms]descrip.mms
+<LARETIL>
+
+If an archive is intended for use with PKUNZIP under MSDOS, then the
+/PKZIP option should be used to attempt to adjust the names and paths to
+conform to MSDOS character-set and length limitations, to store only the
+MSDOS file attributes (just the owner:write attribute from VMS), and to
+mark the entry as made under MSDOS (even though it wasn't).
+
+Note that file specifications in the file system must be specified using
+VMS notation, but file names in an archive must be specified using the
+UNIX-like notation used in the archive. For example, where a BACKUP
+command might look like this:
+
+<LITERAL>
+$ back [.zip30...]*.* /excl = [...vms]*.c stuff.bck /save
+<LARETIL>
+
+a corresponding Zip command might look like this:
+
+<LITERAL>
+$ zip /exclude = "*/vms/*.c" stuff.zip [.zip30...]*.*
+<LARETIL>
+
+because the files to be added to the Zip archive are specified using VMS
+file specifications, but the /EXCLUDE option excludes names based
+on their archive path/file names. Options dealing with archive names
+include /COPY_ENTRIES, /DELETE, /EXCLUDE, /INCLUDE, and
+/RECURSE=FILENAMES.
+
+Note that a UNIX-like path specification must be quoted, or else the
+slashes ("/") will confuse the command-line interpreter, causing errors
+like "%CLI-W-IVQUAL, unrecognized qualifier - check validity, spelling,
+and placement".
+
+Note: By default, on VMS, archive name pattern matching (/COPY_ENTRIES,
+/DELETE, /EXCLUDE, /INCLUDE, and /RECURSE=FILENAMES) is case sensitive,
+even when the file system is not case sensitive (or even case
+preserving). This allows accurate matching of mixed-case names in an
+archive which may have been created on a system with a case sensitive
+file system, but it can involve extra effort on VMS, where it may be
+necessary to use unnatural case names (or the same names in multiple
+cases, like "*.obj *.OBJ") for this kind of pattern matching to give the
+desired behavior. If completely case-blind pattern matching behavior is
+desired, specify the /PATTERN_CASE=BLIND option.
+<TOPIC>
+Modes_of_Operation
+
+Zip supports two distinct types of command modes, external and
+internal. The external modes (update, grow, and freshen) read files
+from the file system (as well as from an existing archive) while the
+internal modes (delete and copy) operate exclusively on entries in an
+existing archive.
+
+<LITERAL>
+ /UPDATE
+<LARETIL>
+
+Update existing entries and add new files. If the archive does not
+exist, create it. This is the default mode, so /UPDATE is optional.
+
+<LITERAL>
+ /GROW
+<LARETIL>
+
+Grow (append to) the specified Zip archive, instead of creating a new
+one. If this operation fails, 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.
+
+<LITERAL>
+ /FRESHEN
+<LARETIL>
+
+Update existing entries in an existing archive. Does not add new files
+to the archive.
+
+<LITERAL>
+ /DELETE
+<LARETIL>
+
+Delete entries from an existing archive.
+
+<LITERAL>
+ /COPY_ENTRIES
+<LARETIL>
+
+Select entries in an existing archive and copy them to a new archive.
+Copy mode is like update mode, but entries in the existing archive are
+selected by command line patterns rather than files from the file system
+and it uses the /OUTPUT option to write the resulting archive to a new
+file rather than updating the existing archive, leaving the original
+archive unchanged.
+
+<LITERAL>
+ /DIFFERENCE
+<LARETIL>
+
+Create an incremental backup-style archive, where the resulting archive
+will contain 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 Zip operation.
+
+For example, if the existing archive was created using
+
+<LITERAL>
+zip foo_full.zip [.foo...]*.*
+<LARETIL>
+
+from just above the foo directory, then the command (also from just
+above the foo directory):
+
+<LITERAL>
+zip /difference /output = foo_incr.zip foo_full.zip [.foo...]*.*
+<LARETIL>
+
+creates the archive foo_incr.zip with just the files not in foo_full.zip
+and the files where the size or date-time of the files does not match
+that in foo_full.zip. Note that in the "ZIP /DIFFERENCE" operation, the
+original full archive is specified as the input archive, and the /OUTPUT
+option is used to specify the new (incremental) output archive.
+
+<LITERAL>
+ /FILESYNC
+<LARETIL>
+
+Delete entries in the archive that do not match files on the OS.
+Normally files already in an archive that are not updated remain
+in the archive unchanged. The /FILESYNC option deletes files in
+the archive that are not matched during the directory scan,
+resulting in the archive being updated having the same contents
+as a new archive would. If much of the archive will remain
+unchanged, this can be faster than creating a new archive as
+copying entries is faster than compressing and adding new files.
+
+Normally, when updating an archive using relative file specifications
+("[]", "[.xxx]", and so on), it helps to have the same default directory
+as when the archive was created, but this is not a strict requirement.
+
+<TOPIC>
+Self_Extracting_Archives
+
+A self-extracting archive (SFX) comprises a normal Zip archive appended
+to a special UnZip program (such as UNZIPSFX_CLI.EXE) for the intended
+target system.
+
+The UnZip distribution includes a VMS command procedure,
+[,vms]makesfx.com, which can be used directly or adapted to create an
+SFX archive from a normal Zip archive.
+
+The .ZIP file format includes offsets to data structures in the archive,
+and these offsets are measured from the start of the archive file.
+Appending an archive to an UnZip SFX executable effectively moves the
+start of the archive file. That makes the original offsets wrong, and
+that will cause the UnZip SFX program to emit warning messages when it
+tries to unpack the archive. Zip /ADJUST_OFFSETS can be used to adjust
+these offsets in a self-extracting archive. For example, to adjust the
+offsets in foo.sfx_exe:
+
+<LITERAL>
+| zip /adjust_offsets foo.sfx_exe
+<LARETIL>
+
+Similarly, the UnZip SFX program can be removed from a self-extracting
+archive (and the offsets in the archive restored) using the /UNSFX
+option. For example:
+
+<LITERAL>
+| zip /unsfx foo.sfx_exe
+<LARETIL>
+
+Note that a self-extracting archive contains a normal Zip archive, and a
+normal UnZip program can be used to expand it in the normal way. You
+may get a warning about extra bytes at the beginning of the archive (the
+UnZip SFX program), but UnZip should work properly after that. This
+allows data in a self-extracting archive to be accessed on any system,
+not just the target system where its embedded UnZip SFX program runs.
-.!
<TOPIC>
-Parameters
-
-<PARAMETER>
-zipfile
-
-<PTEXT>
-File specification for the ZIP archive. Zip will perform the requested action
-for every zipfile matching the specification.
-The default file specification is SYS$DISK:[].ZIP.
-
-Note that self-extracting ZIP files are supported; just specify the .EXE
-suffix yourself.
-<TXETP>
-
-<PARAMETER>
-file
-
-<PTEXT>
-An optional comma-separated list of files to be added or replaced in the
-zipfile. For unconditional add / replacement actions, a list must be
-specified. For the freshening operation, all archive members are processed
-per default; the optional file list restricts processing to the specified
-archive members.
-Expressions may be used to match multiple members. For add/update operations,
-wildcard expressions are interpreted in VMS wildcard syntax to match
-external files. In contrast, for freshening/deletion operation, wildcard
-expressions are interpreted in UNIX compatible syntax to match the
-internal names of archive members in the zipfile.
-<TXETP>
+Split_Archives
+
+Beginning with version 3.0, Zip supports split archives. A split
+archive is one which is divided into multiple files, usually to allow it
+to be stored on multiple storage media (floppy diskettes, CD-ROMs, or
+the like) when a single medium would be too small to contain the whole
+archive. (Note that split archives are not just unitary archives split
+into pieces, as the .ZIP file format includes offsets to data structures
+in the archive, and for a split archive these are based on the start of
+each split, not on the start of the whole archive. Concatenating the
+pieces will invalidate these offsets, but UnZip can usually deal with
+it. Zip will usually refuse to process such a spliced archive unless
+the /FIX = FULL option is used to fix the offsets.)
+
+For a split archive with, say, 20 split files, the files are typically
+named ARCHIVE.z01, ARCHIVE.z02, ..., ARCHIVE.z19, ARCHIVE.zip, where
+"ARCHIVE" is the archive name specified by the user on the Zip command
+line. Note that the last split file is the ".zip" file. In contrast,
+"spanned" archives are the original multi-disk archive generally
+requiring floppy disks and using volume labels to store disk numbers.
+Zip 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.
<QUALIFIERS>
<QUALIFIER>
@@ -116,52 +616,101 @@ Adjust internal offsets of the Zip archive members after some data
/APPEND
/APPEND
+/GROW
+
+Grow (append to) the specified Zip archive, instead of creating a new
+one. If this operation fails, 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.
-Try to work with the existing Zip archive. This option is ignored when
-any existing entry in the Zip archive gets updated or deleted.
-Without the /APPEND qualifier, Zip always creates a backup copy when
-modifying the archive. This is slower, but prevents corruption of the
-old archive in case of a fatal problem (power failures, program crash...).
+See also /DELETE /DIFFERENCE, /FRESHEN, /UPDATE.
<QUALIFIER>
/BATCH
-/BATCH[=listfile]
+/BATCH[=list_file]
-Read list of files to add/update to the Zip archive from the listfile.
-The listfile defaults to SYS$INPUT.
+Read input file specifications (inpaths) from "list_file" (one per
+line). The list_file defaults to SYS$INPUT.
<QUALIFIER>
/BEFORE
-/BEFORE=(VMS time specification)
+/BEFORE=VMS_date_time
-Only handle files that are older than the specified date and time.
-The specified time is compared with the files' RMS creation time.
+Restricts the files by date-time when adding, updating, or freshening an
+archive. Only files with modification date-times earlier than the
+specified date-time are accepted.
+
+See also /SINCE.
<QUALIFIER>
-/COMMENT
+/COMMENTS
-/COMMENT[=KEYWORD[,KEYWORD]]
+/COMMENTS[=KEYWORD[,KEYWORD]]
Add comments to the Zip archive.
+
<LITERAL>
-| ZIP_FILE Add/replace the multi-line archive comment. (default)
+| ARCHIVE Add/replace the multi-line archive comment. (default)
| FILES Add file comment to each updated/added archive member.
<LARETIL>
-The Zip program prompts for each comment to be added; this requires Zip
-to be run in interactive mode.
+The Zip program prompts for each comment to be added, which makes sense
+only if Zip is run interactively.
-The one-line archive member comments are terminated by typing RETURN.
-To skip a file comment, just type RETURN without entering any further
-characters.
+The one-line file (archive member) comments are terminated by typing
+<Return>. To skip a file comment, just type <Return> without entering
+any further characters.
-The zip archive comment may be multi-line. The comment is ended by a line
-containing just a period, or by supplying a ^Z.
+The Zip archive comment may be multi-line. The comment is ended by a
+line containing just a period, or by an end-of-file character (CTRL/Z).
+<QUALIFIER>
+/COMPRESSION
+
+/COMPRESSION = {BZIP2|DEFLATE|STORE}
+
+Specify the compression method to be used when adding or updating files
+in an archive. STORE disables compression (like /LEVEL = 0). Default:
+/COMPRESSION = DEFLATE.
+
+Zip can archive files with or without compression. The standard
+compression method ("deflate") is compatible with all UnZip versions
+(except really old ones that only understand the "store" method).
+Current Zip and UnZip versions may be built with optional support for
+the bzip2 compression method. (The bzip2 method can compress better,
+especially when compressing highly redundant files, but uses more CPU
+time, and requires an UnZip which includes the optional bzip2 support.
+See the installation instructions for details on adding bzip2
+compression support at build time.)
+<QUALIFIER>
+/COPY_ENTRIES
+
+/COPY_ENTRIES
+
+Select entries in an existing archive and copy them to a new archive.
+Copy mode is like update mode, but entries in the existing archive are
+selected by command line patterns rather than files from the file system
+and it uses the /OUTPUT option to write the resulting archive to a new
+file rather than updating the existing archive, leaving the original
+archive unchanged.
<QUALIFIER>
/DELETE
/DELETE
-Delete entries from zip file.
+Delete entries from archive.
+
+See also /DIFFERENCE, /FRESHEN, /GROW, /UPDATE.
+<QUALIFIER>
+/DIFFERENCE
+
+/DIFFERENCE
+
+Create an incremental backup-style archive, where the resulting archive
+will contain 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 Zip operation.
+
+See also /DELETE, /FRESHEN, /GROW, /UPDATE.
<QUALIFIER>
/DIRNAMES
@@ -170,40 +719,80 @@ Delete entries from zip file.
Store directory entries in the archive.
<QUALIFIER>
+/DISPLAY
+
+/DISPLAY=(KEYWORD[,KEYWORD[...]])
+
+Enable display of progress messages.
+<LITERAL>
+| BYTES Running count of bytes processed and bytes to go.
+| COUNTS Running count of entries done and entries to go.
+| DOTS = size Dots every <size> MB while processing files.
+| (0: no dots.)
+| GLOBALDOTS Progress dots reflect the whole archive instead of each
+| file.
+| USIZE Uncompressed size of each entry.
+| VOLUME Display the volume (disk) number each entry is being
+| written to.
+<LARETIL>
+
+The default is a dot every 10 MB of input file processed. The /VERBOSE
+option also displays dots and used to at a higher rate than this (at the
+same rate as in previous versions of Zip) but this rate has been changed
+to the new 10 MB default, and is also controlled by /DISPLAY=DOTS=size.
+<QUALIFIER>
+/DOT_VERSION
+
+/DOT_VERSION
+
+Directs Zip to retain VMS file version numbers on names in an archive,
+but as ".nnn" instead of ";nnn". By default, for compatibility
+with non-VMS systems, Zip strips VMS file version numbers from the names
+stored in an archive. Thus, without /DOT_VERSION or /KEEP_VERSION, a
+version number wildcard (";*") can cause errors when multiple versions
+of a single file are treated as multiple files with the same name.
+
+See also /KEEP_VERSION.
+<QUALIFIER>
/ENCRYPT
/ENCRYPT[="password"]
-Encrypt added and updated archive entries.
+Encrypt new or updated archive entries using a password which is
+supplied by the user interactively on the terminal in response to a
+prompt. (The password will not be echoed.) If SYS$COMMAND is not a
+terminal, Zip will exit with an error. The password is verified before
+being accepted.
You may specify the password on the command line, although we do not
-recommend it since THIS IS INSECURE. Remember to enclose the password
-string with quotes, to prevent automatic conversion to upper case or
-misinterpretation of punctuation characters by DCL.
-
-When the password was not specified, Zip prompts for it on SYS$COMMAND.
-For typing the password, terminal echo is suspended. For added user
-security, the password prompt appears twice and the two user inputs are
-checked for identity before using the password.
+recommend it because THIS IS INSECURE. Remember to enclose the password
+string with quotation marks ("pass word"), to prevent automatic
+conversion to upper case or misinterpretation of punctuation characters
+by DCL.
+
+Because standard Zip encryption is weak, where security is truly
+important, use a strong encryption program, such as Pretty Good Privacy
+(PGP) or GNU Privacy Guard (GnuPG), on an archive instead of standard
+Zip encryption. A stronger encryption method, such as AES, is planned
+for Zip 3.1.
<QUALIFIER>
/EXCLUDE
/EXCLUDE=(file[,...])
-A comma-separated list of files to exclude when deleting, updating or
-adding files in the archive.
-If multiple files are specified, the list should be included in
-parentheses.
+A comma-separated list of files to exclude when deleting, updating, or
+adding files in the archive. If multiple files are specified, the list
+should be enclosed in parentheses.
<QUALIFIER>
/EXLIST
-/EXLIST=listfile
+/EXLIST=list_file
-The files matching the filename patterns listed in "listfile" are
+The files matching the filename patterns listed in "list_file" are
excluded when deleting, updating or adding files in the archive.
-The "listfile" is a normal text file with one filename pattern entry per
-line. The name pattern entries are recognized exactly as found in
-"listfile", including leading, embedding and trailing whitespace or most
+The "list_file" is a normal text file with one filename pattern entry per
+line. The name pattern entries are recognized exactly as found in
+"list_file", including leading, embedded, and trailing whitespace or most
control characters (with exception of LineFeed and probably CarriageReturn).
<QUALIFIER>
/EXTRA_FIELDS
@@ -211,22 +800,113 @@ control characters (with exception of LineFeed and probably CarriageReturn).
/EXTRA_FIELDS (default)
/NOEXTRA_FIELDS
-Allows inclusion of extra file attributes information in the zipfile's
-entry headers.
-Examples are: the VMS attributes (enabled by the /VMS qualifier), or
-additional GMT time stamps. These GMT time stamps are quite useful when
-transporting a Zip archive world wide, but they are only recognized
-by Info-ZIP's UnZip version 5.20 and later, and take up some additional
-space.
-When /EXTRA_FIELDS is negated, the /VMS qualifier to request saving of the
-VMS RMS file attributes is ignored, too!
+Allows (or suppresses) the saving of any optional extra fields in the
+archive. (/NOEXTRA_FIELDS conflicts with /VMS[=ALL].)
+
+The .ZIP file format allows some extra data to be stored with a file in
+the archive. For example, where local time zone information is
+available, Zip can store UTC date-time data for files. (Look for
+USE_EF_UT_TIME in a "zip -v" report.) On VMS, with /VMS[=ALL], Zip will
+also store VMS-specific file attributes. These data are packaged as
+"extra fields" in the archive. Some extra fields are specific to a
+particular operating system (like VMS file attributes). Large files
+(bigger than 4GB) on any OS require an extra field to hold their 64-bit
+size data. Depending on the capabilities of the UnZip program used to
+expand the archive, these extra fields may be used or ignored when files
+are extracted from the archive.
+
+Some extra fields, like UTC date-times or VMS file attributes, are
+optional. Others, like the Zip64 extra field which holds 64-bit sizes
+for a large file, are required.
+<QUALIFIER>
+/FILESYNC
+
+/FILESYNC
+
+Delete entries in the archive that do not match 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 deleting of entries that
+are not matched on the OS. 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 /FILESYNC can
+be much faster than creating a new archive. If few files are being
+copied from the old archive, it may be faster to create a new archive
+instead.
+
+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 /OUTPUT
+option to output the new archive to a new file. Even though it's
+slower, creating a new archive with a new archive name is safer, avoids
+mismatches between archive and OS paths, and is preferred.
+<QUALIFIER>
+/FIX_ARCHIVE
+
+/FIX=_ARCHIVE={NORMAL|FULL}
+
+The /FIX_ARCHIVE=NORMAL option (NORMAL is the default) can be used if
+some portions of the archive are missing, but it requires a reasonably
+intact central directory. The input archive is scanned as usual, but
+zip will ignore some problems. The resulting archive should be valid,
+but any inconsistent entries will be left out.
+
+If the archive is too damaged or the end (where the central directory is
+situated) has been truncated, you must use /FIX_ARCHIVE=FULL. This is
+a change from zip 2.32, where the /FIX=NORMAL option was able to read a
+truncated archive. The /FIX=NORMAL option now more reliably fixes
+archives with minor damage, and the /FIX=FULL option is needed to fix
+some archives where /FIX=NORMAL was sufficient before.
+
+With /FIX=FULL, the archive is scanned from the beginning and Zip scans
+for special signatures to identify the limits between the archive
+members. The /FIX=NORMAL option is more reliable if the archive is not
+too much damaged, so try this option first.
+
+Neither option will recover archives that have been incorrectly
+transferred, such as by FTP in ASCII mode instead of binary. After the
+repair, the /TEST (-t) option of UnZip may show that some files have a
+bad CRC. Such files cannot be recovered; you can remove them from the
+archive using the /DELETE option of Zip.
+
+Because of the uncertainty of the "fixing" process, it's required
+to specify an output archive, rather than risking further damage to the
+original damaged archive. For example, to fix the damaged archive
+foo.zip:
+
+<LITERAL>
+zip /fix_archive /output=foo_fix foo
+<LARETIL>
+
+tries to read the entries normally, copying good entries to the new
+archive foo_fix.zip. If this doesn't work, as when the archive is
+truncated, or if some entries are missed because of bad central
+directory entries, try /FIX_ARCHIVE=FULL:
+
+<LITERAL>
+zip /fix_archive=full /output=foo_fixfix foo
+<LARETIL>
+
+and compare the resulting archive to the archive created using
+/FIX=NORMAL. The /FIX=FULL option may create an inconsistent archive.
+Depending on what is damaged, you can then use the /FIX=NORMAL option to
+fix that archive.
+
+A split archive with missing split files can be fixed using /FIX=NORMAL
+if you have the last split of the archive (the ".zip" file). If this
+file is missing, you must use /FIX=FULL to fix the archive, which will
+prompt you for the splits you have.
+
+Currently, the fix options can't recover an entry which has a bad
+checksum or is otherwise damaged.
<QUALIFIER>
/FRESHEN
/FRESHEN
-Freshen existing zipfile entries; replace if newer. Does not cause any new
-files to be added to the archive.
+Update existing entries in an existing archive. Does not add new files
+to the archive.
+
+See also /DELETE, /DIFFERENCE, /GROW, /UPDATE.
<QUALIFIER>
/FULL_PATH
@@ -234,32 +914,46 @@ files to be added to the archive.
/NOFULL_PATH
Directs Zip to store the directory part of the file names (relative to
-the current working directory) in the Zip archive.
+the current working directory) in the Zip archive. With /NOFULL_PATH,
+Zip stores only the file names, discarding any directory information.
<QUALIFIER>
-/HELP
+/GROW
+/GROW
+/APPEND
+
+Grow (append to) the specified Zip archive, instead of creating a new
+one. If this operation fails, 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.
+
+See also /DELETE, /DIFFERENCE, /FRESHEN, /UPDATE.
+<QUALIFIER>
/HELP
-Display Zip's help screen, including the version message.
+/HELP[=EXTENDED]
+
+Display Zip's help screen, including the version message. With
+/HELP=EXTENDED, more detailed (longer) help information is shown.
<QUALIFIER>
/INCLUDE
/INCLUDE=(file[,...])
-A comma-separated list of files to include when deleting, updating or
-adding files in the archive.
-If multiple files are specified, the list should be included in
-parentheses.
+A comma-separated list of files to include when deleting, updating, or
+adding files in the archive. If multiple files are specified, the list
+should be enclosed in parentheses.
<QUALIFIER>
/INLIST
-/INLIST=listfile
+/INLIST=list_file
-The files matching the filename patterns listed in "listfile" are
-included when deleting, updating or adding files in the archive.
-The "listfile" is a normal text file with one filename pattern entry per
+The files matching the filename patterns listed in "list_file" are
+included when deleting, updating, or adding files in the archive.
+The "list_file" is a normal text file with one filename pattern entry per
line. The name pattern entries are recognized exactly as found in
-"listfile", including leading, embedding and trailing whitespace or most
+"list_file", including leading, embedded, and trailing whitespace or most
control characters (with exception of LineFeed and probably CarriageReturn).
<QUALIFIER>
/JUNK
@@ -267,23 +961,23 @@ control characters (with exception of LineFeed and probably CarriageReturn).
/JUNK
/NOJUNK (default)
-Junk the directory part of the file names for added entries (do not
-not save the directory structure). The /JUNK qualifier is an alias for
-/NOFULL_PATH.
+Junk (discard) the directory part of the file names for added entries
+(do not not save the directory structure). The /JUNK qualifier is an
+alias for /NOFULL_PATH.
<QUALIFIER>
/KEEP_VERSION
/KEEP_VERSION
/NOKEEP_VERSION (default)
-Directs Zip to include the version number appendix in the stored file names.
-This allows to store multiple version of the same file in a single Zip
-archive.
+Directs Zip to retain VMS file version numbers on names in an archive.
+By default, for compatibility with non-VMS systems, Zip strips VMS
+file version numbers from the names stored in an archive. Thus, without
+/DOT_VERSION or /KEEP_VERSION, a version number wildcard (";*") can
+cause errors when multiple versions of a single file are treated as
+multiple files with the same name.
-The normal behaviour of Zip without /KEEP_VERSION is to use only the most
-recent version of a specified file and strip of the version number from
-the stored file name. This behaviour ensures better compatibility when
-transfering a Zip archive to non VMS systems.
+See also /DOT_VERSION.
<QUALIFIER>
/LATEST
@@ -312,31 +1006,138 @@ The default level is 6.
Displays the Zip license.
<QUALIFIER>
+/LOG_FILE
+
+/LOG_FILE=(FILE=log_file [, APPEND] [, INFORMATIONAL])
+
+Zip normally sends messages to the user's terminal, but these may be
+also directed to a log file.
+
+<LITERAL>
+ FILE=log_file
+<LARETIL>
+
+Open a logfile at the given path. By default, a new version will be
+created.
+
+<LITERAL>
+ APPEND
+<LARETIL>
+
+Append to an existing log file. Default is to create a new version.
+
+<LITERAL>
+ INFORMATIONAL
+<LARETIL>
+
+Only warnings and errors are written to the log unless the INFORMATIONAL
+option is also specified, then all information messages are also written
+to the log.
+<QUALIFIER>
/MOVE
/MOVE
-Move the specified files into the Zip archive.
-Entries which have been added (or freshened) to the zip file get removed from
-the file system. If a directory is empty afterwards, it is also removed.
+Move the specified files into the Zip archive. That is, Zip will delete
+any files which are successfully added to or updated in the archive. No
+deletions will be done until the Zip operation has completed with no
+errors. This option is obviously dangerous and should be used with
+care, but it does reduce the need for free disk space. It's recommended
+that /TEST also be used to test the archive before the input files are
+deleted.
+<QUALIFIER>
+/MUST_MATCH
+
+/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 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 zip returns the OPEN
+error code (18 on most systems) instead of the normal success return (0
+on most systems). With /MUST_MATCH, 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 Zip exits
+with an OPEN error and no archive is created.
+
+This option is useful when a known list of files is to be zipped so any
+missing or unreadable files should result in an error. It may be less
+useful when used with wildcards, but Zip will still exit with an error
+if any input pattern doesn't match at least one file or if any
+matched files are unreadable. If you want to create the archive anyway
+and only need to know if files were skipped, then don't use /MUST_MATCH
+and just check the exit status. Also, a log file (see /LOG_FILE) could
+be useful.
+<QUALIFIER>
+/PATTERN_CASE
+
+/PATTERN_CASE={BLIND|SENSITIVE}
+
+<LITERAL>
+| BLIND Use case-blind pattern matching for archive entry names.
+| SENSITIVE Use case-sensitive pattern matching for archive entry
+| names. (Default.)
+<LARETIL>
+
+By default, on VMS, archive name pattern matching (/COPY_ENTRIES,
+/DELETE, /EXCLUDE, /INCLUDE, and /RECURSE=FILENAMES) is case sensitive,
+even when the file system is not case sensitive (or even case
+preserving). This allows accurate matching of mixed-case names in an
+archive which may have been created on a system with a case sensitive
+file system, but it can involve extra effort on VMS, where it may be
+necessary to use unnatural case names (or the same names in multiple
+cases, like "*.obj *.OBJ") for this kind of pattern matching to give the
+desired behavior. If completely case-blind pattern matching behavior is
+desired, specify the /PATTERN_CASE=BLIND option.
<QUALIFIER>
/PKZIP
/PKZIP
/NOPKZIP (default)
-Create PKZIP compatible archive entries.
-The file names are truncated and converted to upper case to match the
-MSDOS 8+3 file name syntax. Only the MSDOS compatible attributes are stored;
-the file owner's write permission is mapped to the "readonly" attribute.
-The archive entry is marked as being made under MSDOS regardless of the true
-host system of Zip.
+Create PKZIP-compatible archive entries. File names and paths are
+adjusted to conform to MSDOS character-set and length
+limitations, to store only the MSDOS file attributes (just the
+owner:write attribute from VMS), and to mark the entry as made under
+MSDOS (even though it wasn't).
+<QUALIFIER>
+/PRESERVE_CASE
+
+/NOPRESERVE_CASE
+/PRESERVE_CASE[=(keyword[, ...])]
+
+Directs Zip to preserve the case of, or convert to lower-case, file names
+in the archive. Optional keywords are:
+<LITERAL>
+| NOODS2 Down-case ODS2 file names (default).
+| NOODS5 Down-case ODS5 file names.
+| ODS2 Preserve case of ODS2 file names.
+| ODS5 Preserve case of ODS5 file names (default).
+<LARETIL>
+
+By default, file names from an ODS2 file system are converted to lower
+case for storage in an archive, while the case of file names from an
+ODS5 file system is preserved.
+
+/NOPRESERVE_CASE is equivalent to /PRESERVE_CASE = (NOODS2, NOODS5),
+which causes all file names to be converted to lower-case. This is
+equivalent to the behavior of Zip before version 3.0.
+
+/PRESERVE_CASE is equivalent to /PRESERVE_CASE = (ODS2, ODS5), which
+preserves the case of all file names.
<QUALIFIER>
/QUIET
/QUIET
-Perform operations quietly.
+Quiet mode. Eliminates informational messages and comment prompts.
+This mode may be useful in command procedures, or if the Zip operation
+is being performed as a background task ("$ spawn/nowait zip /quiet foo
+*.c").
<QUALIFIER>
/RECURSE
@@ -350,268 +1151,486 @@ The optional keywords recognized are:
| FILENAMES start from current dir;
| only use filename part of file patterns (-R)
<LARETIL>
-The new FILENAMES optional keyword modifies the recursion algorithm to
-be (almost) compatible to PKZIP's behaviour on subdirectory recursion.
+The optional FILENAMES keyword modifies the recursion algorithm to be
+(almost) compatible to PKZIP's behaviour on subdirectory recursion.
+
+On VMS, directory recursion can also be requested by using the
+directory depth wildcard ("[...]") in an input file specification.
+<QUALIFIER>
+/SHOW
-On VMS, this behaviour can be alternatively archived by using
-the "subdirectory recursing wildcard" [...] in the "include files" parameter
-list.
+/SHOW=(KEYWORD[,KEYWORD[...]])
+
+Controls various diagnostic messages.
+
+The keywords recognized are:
+<LITERAL>
+| COMMAND Show command line arguments as processed (only, then exit).
+| DEBUG Show Debug information.
+| FILES Show files to process (only, then exit).
+| OPTIONS Show all available command-line options on this system.
+<LARETIL>
<QUALIFIER>
/SINCE
-/SINCE=(VMS time specification)
+/SINCE=VMS_date_time
+
+Restricts the files by date-time when adding, updating, or freshening an
+archive. Only files with modification date-times at or later than the
+specified date-time are accepted.
-Only handle files that are newer than the specified date and time.
-The specified time is compared with the files' RMS creation time.
+See also /BEFORE.
<QUALIFIER>
-/STORETYPES
+/SPLIT
+
+/SPLIT = (SIZE=size [, PAUSE [, BELL]] [, VERBOSE])
+
+Enables split archives, specifies the size of the splits, and controls
+other related behavior.
+
+SIZE=size specifies the split size. The size is given as a number
+followed optionally by a multiplier suffix of k (KB), m (MB, the default
+if no suffix is specified), g (GB), or t (TB). (All are powers of 1024,
+not 1000). 64K is the minimum split size. For example, the following
+command could be used to create a split archive called "foo" from the
+contents of the "bar" directory with splits of 670MB, which might be
+useful for burning on CDs:
+
+<LITERAL>
+| zip /split = size = 670m foo [.bar...]*.*
+<LARETIL>
+
+Using /SPLIT without PAUSE as above creates all the splits in the
+directory
+specified by "foo", in this case the current default 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 PAUSE below for
+enabling split pause mode which allows splits to be written directly to
+removable media.
+
+PAUSE causes Zip to pause between splits to allow
+changing removable media, for example. PAUSE uses stream mode to
+write splits so unzips that can't read stream mode entries may not
+be able to read some entries in the archive. Unless standard encryption
+was used, copy mode using /COPY_ENTRIES can convert stream mode entries
+to normal entries.
+
+BELL ring the terminal bell when Zip pauses for the next split
+destination.
-/STORETYPES=(.ext1,.ext2,... )
+VERBOSE enables verbose splitting and display details of how the
+splitting is being done.
-For files with the specified extensions, Zip does not try to compress the
-data but stores them verbatim. This speeds up operation on files that
-have already been compressed and where a second compression step usually
-does not gain much space.
-The default list of extensions where compression is suppressed is
-(.Z,.zip,.zoo,.arc,.arj).
+Though Zip does not update split archives, Zip provides the option
+/OUTPUT to allow split archives to be updated and saved in a new
+archive. For example:
-But note: when maximum level of compression is requested (/LEVEL=9), the
-STORETYPES heuristic is not used. In this case, Zip tries to compress ALL
-files.
+<LITERAL>
+| zip inarchive.zip foo.c bar.c /output = outarchive.zip
+<LARETIL>
+
+reads archive inarchive.zip, even if split, adds the files foo.c and
+bar.c, and writes the resulting archive to outarchive.zip. If
+inarchive.zip is split, then outarchive.zip defaults to the same split
+size. Be aware that outarchive.zip and any split files that are created
+with it are always overwritten without warning. This may be changed in
+the future.
+<QUALIFIER>
+/STORE_TYPES
+
+/STORE_TYPES=(.ext1,.ext2,... )
+
+Normally, a file which is already compressed will not be compressed much
+further (if at all) by Zip, and trying to do it can waste considerable
+CPU time. Zip can suppress compression on files with particular types,
+specified with /STORE_TYPES. The default list of types where
+compression is suppressed is /STORE_TYPES=(.Z, .zip, .zoo, .arc, .lzh,
+ .arj), and the comparison is case-insensitive.
+
+/LEVEL=9 will override /STORE_TYPES, causing compression to be attempted
+for all files.
+<QUALIFIER>
+/SYMLINKS
+
+/SYMLINKS
+
+Store symbolic links as such in the Zip archive, instead of compressing
+and storing the file referred to by the link. A symbolic link normally
+requires less storage than the actual file, both in the archive, and on
+the destination file system.
+
+On VMS, symbolic links are supported on ODS5 disks where the C RTL
+supports symbolic links. Full support for symbolic links seems to
+require VMS V8.3, but a Zip program supporting symbolic links may be
+built on VMS V7.3-2.
<QUALIFIER>
/TEMP_PATH
-/TEMP_PATH=dirspec
+/TEMP_PATH=temp_dir
+
+When creating a new archive or normally when changing an existing
+archive, Zip will write a temporary file in the archive destination
+directory ("ZIxxxxxxxx", where "xxxxxxxx" is the hexadecimal process ID)
+with the new contents. Then, if and when the Zip job has completed with
+no errors, it will rename the temporary file to the specified archive
+name (replacing the old archive, if any).
-Specifies an alternate directory where Zip creates its temporary files.
-When this qualifier is not given, Zip attempts to write to the current
-working directory.
+/TEMP_PATH=temp_dir specifies an alternate device:[directory],
+"temp_dir", for the temporary file, but specifying a different device
+will force Zip to copy the temporary file to its final destination
+instead of simply renaming it, and that copying will take more time than
+renaming, especially for a large archive. For example:
+
+<LITERAL>
+| zip /temp_path = disk$scratch:[tmp] stuff *
+<LARETIL>
+
+will cause Zip to put its temporary files in the directory
+"disk$scratch:[tmp]", copying the temporary file back to the current
+directory as stuff.zip when it's complete.
<QUALIFIER>
/TEST
-/TEST
+/TEST[=UNZIP=unzip_cmd]
+
+Test the integrity of a Zip archive (the new one, if /OUTPUT is
+specified). If the check fails, the old archive is unchanged and
+(with the /MOVE option) no input files are removed.
-Test archive integrity.
+Implementation
+"zip /TEST" actually runs an "unzip -t" command to do the testing, so
+UnZip must be installed properly for this to work.
+
+With UNZIP=unzip_cmd, Zip uses the UnZip command specified by
+"unzip_cmd" (normally a DCL symbol), instead of the default command,
+"unzip -t". This can be useful if multiple versions of UnZip are
+installed on a system, and the default DCL symbol "UNZIP" would run the
+wrong one (or the logical name DCL$PATH would lead to the wrong one).
+
+In "unzip_cmd", the string "{}" is replaced by the name of the
+(temporary) archive to be tested, otherwise the name of the archive is
+appended to the end of the command. The exit status is checked for
+success severity.
<QUALIFIER>
/TRANSLATE_EOL
/TRANSLATE_EOL[=KEYWORD]
-Selects conversion of the end-of-line markers in text files.
-The optional keywords recognized are:
+Selects conversion of the end-of-line markers in text files. This
+option should be used on text files only. The optional keywords
+recognized are:
<LITERAL>
| LF convert LF -> CRLF (UNIX to DOS) (default)
| CRLF convert CRLF -> LF, strip trailing CTRL-Z's (DOS to UNIX)
<LARETIL>
-This option should only be used with text files. The second option CRLF
-is only useful when a DOS text file has been transfered to a VMS disk
-in stream (or stream_lf) format.
+The CRLF option may be useful when a DOS text file has been transfered
+to a VMS disk in stream (or stream_lf) format.
<QUALIFIER>
/UNSFX
/UNSFX
-Strip any prepended data from the Zip archive, for example a self-extracting
-executable stub.
+Strip any prepended data from the Zip archive. ZIP /UNSFX is normally
+used to convert a self-extracting archive to a normal archive by
+removing the UnZip SFX executable from the beginning of the SFX archive.
+
+Note that a self-extracting archive contains a normal Zip archive, and a
+normal UnZip program can be used to expand it in the normal way. You
+may get a warning about extra bytes at the beginning of the archive (the
+UnZip SFX program), but UnZip should work properly after that. This
+allows data in a self-extracting archive to be accessed on any system,
+not just the target system where its embedded UnZip SFX program runs.
<QUALIFIER>
/UPDATE
/UPDATE
-Freshen existing archive entries; create new ones if needed.
-<QUALIFIER>
-/VERBOSE
-
-/VERBOSE[=MORE|DEBUG]
-
-Switch on verbose messages. This includes diagnostics on discovered
-oddities in the zipfile's structure, and a progress indicator during
-compression operation.
-
-When this qualifier is the only command line argument given, it has a special
-meaning. In this case a screen of diagnostic information about the program
-version is displayed. This display includes the Zip version number and
-release date, and it shows some information to determine when and how
-the executable was built and set up. This includes info on the used compiler's
-name and version, the date of the build (if available), and some optional
-compile time feature flags. Additionally, the contents of the environment
-variables (=logical names on VMS) that are read by Zip for runtime
-configuration are shown.
-This information is especially valuable when reporting problems or bugs.
+Update existing archive entries and add new files. If the archive does
+not exist, create it. This is the default mode, so /UPDATE is optional.
+See also /DELETE /DIFFERENCE, /GROW, /FRESHEN.
<QUALIFIER>
-/VMS
-
-/VMS[=ALL]
-
-Store VMS file attributes in Zip archive.
-
-When the optional keyword ALL is specified, all allocated blocks in a
-file are stored in the Zip archive, including data beyond the
-End-of-File (EOF) marker.
+/VERBOSE
-/VMS provides good fidelity for well-formed files (no data past EOF)
-when unpacked on a VMS system. Also, some types of file (notably
-Stream_LF text files) will be unpacked as expected on a non-VMS system.
+/VERBOSE[=NORMAL|MORE|DEBUG] [, COMMAND]]
-/VMS=ALL provides good fidelity, even for files with data past EOF, when
-unpacked on a VMS system. However, the data from beyond the EOF marker
-will typically cause a file to appear corrupted when unpacked on a
-non-VMS system.
-<TOPIC>
-Authors
+Verbose mode or print diagnostic version info.
-Info-ZIP; currently maintained by Onno van der Linden. VMS support maintained
-by Igor Mandrichenko, Christian Spieler, and Hunter Goatley. Originally based
-on a program by Samuel H. Smith.
+Normally, when applied to real operations, this option enables the
+display of a progress indicator during compression (see /DISPLAY=DOTS
+for more on dots) and requests verbose diagnostic info about archive
+structure oddities.
-VMS on-line help ported from Zip's MANUAL by Christian Spieler, using
-Hunter Goatley's work for UnZip.
+/VERBOSE with no value is equivalent to /VERBOSE=NORMAL. MORE adds more
+messages, and DEBUG adds still more messages.
-<TOPIC>
-Exit_Codes
+When /VERBOSE is the only command line argument, a diagnostic report is
+displayed, showing:
-On VMS, Zip's UNIX style exit values are mapped into proper
-VMS status codes:
<LITERAL>
-| 1 (success) normal exit,
-| (0x7fff0000 + 16*Zip_error_level) warnings
-| (0x7fff0002 + 16*Zip_error_level) normal errors
-| (0x7fff0004 + 16*Zip_error_level) fatal errors
+| o Copyright and other legal notices
+| o Program name, version, and release date
+| o Pointers to Info-ZIP FTP and Web sites
+| o Program build information (compiler type and version, OS version,
+| and the compilation date
+| o Optional features enabled at compile-time
+| o Environment variable definitions (ZIP_OPTS, ZIPOPT)
<LARETIL>
-The Zip error level (or exit code) approximates the exit
-codes defined by PKWARE and takes on the following values:
-<LITERAL>
-| VMS Zip Type of error
-| severity errcode
-| - 0 normal; no errors or warnings detected.
-| F 2 unexpected end of zip file.
-| E 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.
-| F 4 zip was unable to allocate memory for one or
-| more buffers during program initialization.
-| F 5 a severe error in the zipfile format was
-| detected. Processing probably failed imme-
-| diately.
-| E 6 entry too large to be split with zipsplit
-| E 7 invalid comment format
-| F 8 zip -T failed, or out of memory
-| E 9 the user aborted zip prematurely with con-
-| trol-C (or similar)
-| F 10 zip encountered an error while using a temp
-| file
-| F 11 read or seek error
-| W 12 zip has nothing to do
-| E 13 missing or empty zip file
-| F 14 error writing to a file
-| F 15 zip was unable to create a file for writing
-| E 16 bad command line parameters
-| E 18 zip could not open a specified file to read
-<LARETIL>
+This information should be included in bug reports.
-<TOPIC>
-Logical_Names
+/VERBOSE=COMMAND causes Zip to display the UNIX-style command-line
+argument vector which is generated from the VMS-style CLI command line
+before executing the command. This is of primary interest to program
+developers debugging the CLI.
+<QUALIFIER>
+/VMS
-Zip scans its process environment for the logical name ZIP_OPTS, which
-can be used to specify a string of default options to modify Zip's
-behaviour. For the syntax, see help topic UNIX_Options.
-With the exception of "-i" and "-x", all recognized UNIX style options
-can be used within the ZIP_OPTS equivalence string.
+/VMS[=ALL]
-For example, the following will cause Zip to skip directories, include
-VMS attribute information perform all operations at quiet-level 1 by default:
+The /VMS and /VMS=ALL options cause Zip to store VMS file atributes
+(such as file organization, record format, carriage control, and so on)
+in VMS-specific "extra fields" in an archive along with the usual data.
+These extra fields are ignored on non-VMS systems, but on a VMS system,
+they allow UnZip to restore the files with their VMS attributes intact.
+
+With /VMS, Zip ignores any data in the file after the end-of-file (EOF)
+point (defined by FAT$L_EFBLK and FAT$W_FFBYTE), which works well for
+well-formed files (that is, those with no valid data beyond EOF).
+Portable-format files (Stream_LF, fixed-512) archived with /VMS should
+be extracted properly on a non-VMS system. Files with more complex
+structures, such as indexed files and files with embedded byte counts or
+other such data may be of limited use on other systems. (UnZip on
+non-VMS systems may be able to extract various VMS-format text files,
+however.)
+
+With /VMS=ALL, Zip processes all allocated blocks for the file
+(including those beyond EOF). When extracted on a VMS system, the
+original file should be reproduced with as much fidelity as possible,
+but on a non-VMS system, most files will be seen as corrupt because of
+the data from beyond EOF.
+<QUALIFIER>
+/WILDCARD
<LITERAL>
-| $ define ZIP_OPTS "-qDV"
+/NOWILDCARD
+/WILDCARD=NOSPAN
<LARETIL>
-Note that the quotation marks here are required to preserve lowercase options
-(opposite of the command-line behavior).
+Controls wildcard processing.
+
+/NOWILDCARD Wildcard processing is disabled.
-ZIP_OPTS may be defined as a symbol rather than a logical, but if both
-are defined, the logical is used.
+/WILDCARD=NOSPAN Wildcards don't span directory boundaries in paths.
+<QUALIFIER>
+/ZIP64
-The alternative logical name ZIPOPT (more UNIX-like naming convention)
-is recognized as well. If both ZIPOPT and ZIP_OPTS are present (and do
-not equate to whitespace only), the content of ZIPOPT takes precedence
-and ZIP_OPTS is ignored.
+/ZIP64
+Forces use of Zip64 archive format, even for small files. This is
+mainly for testing and should never be used. Zip will automatically
+use Zip64 as needed without this option.
<TOPIC>
UNIX_Options
-The default action of Zip is to add or replace zipfile entries from list, which
-can include the special name -@ to read names from SYS$INPUT. The following
-list of options was taken from the on-line help generated when Zip is run
-with the -h command-line option:
+"zip -h" provides a concise list of common command-line options. "zip
+-h2" provides more details. "zip -so" provides a list of all available
+options. "zip -v" shows the program version and available features.
+(The list below was derived from a "zip -so" listing.)
+
+Short-form options begin with a single hyphen ("-"). Long-form option
+begin with a double hyphen ("--"), and may be abbreviated to any
+unambiguous shorter string. For example:
<LITERAL>
-| -A adjust self-extracting exe
-| -b use "path" for temp files
-| -c add one-line comments
-| -d delete entries in zipfile
-| -D do not add directory entries
-| -e encrypt
-| -f freshen: only changed files
-| -F fix zipfile (-FF try harder)
-| -g allow growing existing zipfile (unless updating or deleting)
-| -h show this help
-| -i include only names matching the following patterns
-| -i@ include only names matching the patterns listed in "file"
-| -j junk (don't record) directory names
-| -J junk (remove) prepended (SFX) stub
-| -k simulate PKZIP made zipfile
-| -l translate end-of-lines (LF -> CRLF)
-| -ll translate end-of-lines (CRLF -> LF)
-| -L show software license
-| -m move into zipfile (delete files)
-| -n don't compress theses suffixes
-| -o make zipfile as old as latest entry
-| -P encrypt with specified "password"
-| -q quiet operation
-| -r recurse into subdirs, match against specified paths
-| -R recurse into subdirs of current dir, match filenames only
-| -t only do files after "mmddyyyy"
-| -tt only do files before "mmddyyyy"
-| -T test zip file integrity (calls unzip)
-| -u update: only changed or new files
-| -v verbose messages/print version info
-| -V save VMS file attributes
-| -w append the VMS version number to name stored in zip file
-| -x exclude names matching the following patterns
-| -x@ exclude names matching the patterns listed in "file"
-| -X suppress storing of any extra file attributes
-| -z add zipfile comment
-| -0 store only
-| -1 compress faster
-| -9 compress better
-| -@ read list of files to process from SYS$INPUT
+| -v
+| --verbose
+| --verb
<LARETIL>
-Note that uppercase options such as -A, -D, -L, -T and -V must be specified
-in quotes. For example:
+To avoid confusion, if a negatable option contains an embedded hyphen
+("-"), then avoid abbreviating it at the hyphen if you plan to negate
+it. For example, if an option like --some-option were abbreviated to
+--some-, the parser would consider that trailing hyphen to be part of
+the option name, rather than as a negating trailing hyphen. This
+behavior may change in the future, to interpret the trailing hyphen in
+--some- to be negating. (So don't do it.)
+
+Some options may be negated (or modified) by appending a "-":
<LITERAL>
-| $ zip "-VD" -a zipfile
+| -la-
+| --show-files-
<LARETIL>
-To negate a default option on the command line, add one or more minus signs
-before the option letter, in addition to the leading switch character `-':
-
+Some options take a value, which may immediately follow the option, or
+be separated by a space or "=". For example:
<LITERAL>
-| $ zip --ql zipfile
+| -ttmmddyyyy
+| -tt mmddyyyy
+| -tt=mmddyyyy
<LARETIL>
-or
+<LITERAL0>
+| Sh Long Description
+|----+-------------------+------------------------------------------------
+| 0 store store (instead of compress)
+| 1 compress-1 compress faster (-2, -3, -4, ...)
+| 9 compress-9 compress better
+| ? show the Zip help screen
+| @ names-stdin read input file patterns from SYS$INPUT (1/line)
+| A adjust-sfx adjust self-extracting executable
+| b temp-path path use "path" directory for temporary files
+| C preserve-case preserve case of all file names added to archive
+| C- preserve-case- down-case all file names added to archive
+| C2 preserve-case-2 preserve case of ODS2 names added to archive
+| C2- preserve-case-2- down-case ODS2 file added to archive (default)
+| C5 preserve-case-5 preserve case of ODS5 names added to arcv (dflt)
+| C5- preserve-case-5- down-case ODS5 names added to archive
+| c entry-comments add a comment for each entry added to archive
+| D no-dir-entries do not add archive entries for directories
+| DF difference-archive difference archive: add only changed/new files
+| d delete delete entries in archive
+| db display-bytes display running byte counts
+| dc display-counts display running file counts
+| dd display-dots display progress dots for files (dflt sz = 10MB)
+| dg display-globaldots display progress dots for archive, not each file
+| ds dot-size size set progress dot interval to "size" (MB)
+| du display-usize display original uncompressed size for entries
+| dv display-volume display volume (disk) number as in_disk>out_disk
+| e encrypt encrypt entries, ask for password
+| F fix fix mostly intact archive (try F before FF)
+| FF fixfix salvage what can be salvaged (not as reliable)
+| FS filesync remove archive entries unmatched in file system
+| f freshen update existing entries (only changed files)
+| fd force-descriptors force data descriptors as if streaming
+| fz force-zip64 force use of Zip64 format
+| g grow grow existing archive (unless update or delete)
+| H show the Zip help screen
+| h help show the Zip help screen
+| h2 more-help show extended Zip help
+| i include pat1 [pat2 [...]] include only names matching the patterns
+| J junk-sfx junk (remove) archive preamble (unzipsfx)
+| j junk-paths junk (don't store) dir names, only file names
+| k DOS-names simulate PKZIP-made archive (DOS 8.3 names)
+| L license show software license
+| l to-crlf translate end-of-lines (LF -> CRLF)
+| la log-append append to existing log file
+| lf logfile-path lfile log to log file at lfile (default: new version)
+| li log-info include informational messages in log
+| ll from-crlf translate end-of-lines (CRLF -> LF)
+| MM must-match input file spec must exist (wildcrds must match)
+| m move delete files added to archive
+| n suffixes sfx1[:sfx2[...]] don't compress files with these suffixes
+| nw no-wild no wildcards during add or update
+| O output-file ozf use "ozf" as the output archive (dflt = inp archv)
+| o latest-time set archive date-time to match oldest entry
+| P password password encrypt with supplied "password" string
+| q quiet quiet operation (no info messages)
+| R recurse-patterns recurse subdirs from cur dir, match names only
+| r recurse-paths recurse directories from specified path pats
+| s split-size size split archive at "size" (K/MB) (0: don't split)
+| sb split-bell ring termnl bell at pause for split medium chng
+| sc show-command show command line
+| sd show-debug show debug messages
+| sf show-files show files to process (only)
+| so show-options show list of all command-line options
+| sp split-pause pause to select split destination(s)
+| sv split-verbose be verbose about creating splits
+| T test test archive integrity (runs UnZip -T)
+| t from-date mmddyyyy only do files since (at or after) "mmddyyyy"
+| tt before-date mmddyyyy only do files before "mmddyyyy"
+| u update update changed files, add new files (default)
+| V VMS-portable save VMS file attributes
+| VV VMS-specific save VMS file attributes and all allocated blks
+| v verbose verbose messages (version info if only arg)
+| w VMS-versions save VMS version numbers in archive
+| ww VMS-dot-versions save VMS version numbers as ".nnn", not ";nnn"
+| X strip-extra strip all but critical extra fields
+| X- strip-extra- keep all extra fields
+| x exclude pat1 [pat2 [...]] exclude all names matching the patterns
+| Z compression-method mthd use cmprs method "mthd" (bzip2 or deflate)
+| z archive-comment ask for archive comment
+<0LARETIL>
+
+With SET PROCESS /PARSE_STYLE = EXTENDED (available on recent non-VAX
+systems), Zip preserves the case of the command line. Otherwise, mixed-
+or upper-case options and arguments must be quoted. For example,
+"-V". Examples in this document generally do not show this quotation.
+<TOPIC>
+Copyright_and_License
+
+Zip has an option to display its copyright and license.
<LITERAL>
-| $ zip -l-q zipfile
+| /LICENSE
<LARETIL>
-At present it is not possible to decrement an option below zero--that is,
-more than a few minuses have no effect.
+The license is reproduced below.
+
+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.
+
+--------------------------------------------------------
+<LITERAL0>
+|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.
+<0LARETIL>
+
===
diff --git a/vms/zip_msg.msg b/vms/zip_msg.msg
new file mode 100644
index 0000000..8654148
--- /dev/null
+++ b/vms/zip_msg.msg
@@ -0,0 +1,57 @@
+! VMS Error Message Source File for Zip
+!
+! Because the facility code was formally assigned by HP, the .FACILITY
+! directive below specifies /SYSTEM. Because the messages are, in
+! general, specific to Zip, this file is not compiled with /SHARED.
+! For example:
+!
+! MESSAGE /OBJECT = [.dest]ZIP_MSG.OBJ /NOSYMBOLS [.VMS]ZIP_MSG.MSG
+!
+! LINK /SHAREABLE = [.dest]ZIP_MSG.EXE [.dest]ZIP_MSG.OBJ
+!
+!-----------------------------------------------------------------------
+
+.TITLE Info-ZIP Zip Error Messages
+.FACILITY IZ_ZIP, 1955 /SYSTEM
+.IDENT 'V3.0-000'
+
+.BASE 0
+OK /SUCCESS <Normal successful completion>
+.BASE 4
+EOF /FATAL <Unexpected end of zip file>
+.BASE 6
+FORM /ERROR <Zip file structure invalid>
+.BASE 8
+MEM /FATAL <Out of memory>
+.BASE 10
+LOGIC /FATAL <Internal logic error>
+.BASE 12
+BIG /ERROR <Entry too big to split, read, or write>
+.BASE 14
+NOTE /ERROR <Invalid comment format>
+.BASE 16
+TEST /FATAL <Zip file invalid, could not spawn unzip, or wrong unzip>
+.BASE 18
+ABORT /ERROR <Interrupted>
+.BASE 20
+TEMP /FATAL <Temporary file failure>
+.BASE 22
+READ /FATAL <Input file read failure>
+.BASE 24
+NONE /WARNING <Nothing to do!>
+.BASE 26
+NAME /ERROR <Missing or empty zip file>
+.BASE 28
+WRITE /FATAL <Output file write failure>
+.BASE 30
+CREAT /FATAL <Could not create output file>
+.BASE 32
+PARMS /ERROR <Invalid command arguments>
+.BASE 36
+OPEN /ERROR <File not found or no read permission>
+.BASE 38
+COMPERR /FATAL <Not supported>
+.BASE 40
+ZIP64 /FATAL <Attempt to read unsupported Zip64 archive>
+
+.END
diff --git a/vms/zipup.h b/vms/zipup.h
index eea74b6..8fe757f 100644
--- a/vms/zipup.h
+++ b/vms/zipup.h
@@ -1,12 +1,17 @@
/*
Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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
+ 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
*/
-#define fhow "r","mbc=60"
+
+#ifndef __zipup_h
+#define __zipup_h 1
+
+#ifndef NO_ZIPUP_H
+
#define fbad NULL
typedef void *ftype;
#define zopen(n,p) (vms_native?vms_open(n) :(ftype)fopen((n), p))
@@ -16,9 +21,36 @@ typedef void *ftype;
#define zstdin stdin
ftype vms_open OF((char *));
-size_t vms_read OF((ftype, char *, size_t));
+unsigned int vms_read OF((ftype, char *, unsigned int));
int vms_close OF((ftype));
int vms_error OF((ftype));
#ifdef VMS_PK_EXTRA
int vms_get_attributes OF((ftype, struct zlist far *, iztimes *));
#endif
+
+#endif /* !NO_ZIPUP_H */
+#endif /* !__zipup_h */
+
+
+#ifndef __zipup_cb_h
+#define __zipup_cb_h 1
+
+#ifdef __DECC
+
+/* File open callback ID values. (See also OSDEP.H.) */
+
+# define FHOW_ID 4
+
+/* File open callback ID storage. */
+
+extern int fhow_id;
+
+#define fhow "r", "acc", acc_cb, &fhow_id
+
+#else /* def __DECC */ /* (So, GNU C, VAX C, ...)*/
+
+#define fhow "r", "mbc=60"
+
+#endif /* def __DECC */
+
+#endif /* ndef __zipup_cb_h */
diff --git a/win32/README.txt b/win32/README.txt
new file mode 100644
index 0000000..4d56445
--- /dev/null
+++ b/win32/README.txt
@@ -0,0 +1,10 @@
+Win32/README.txt
+27 June 2008
+
+The resource files zip.rc and windll.rc must not get edited and saved from
+MS Visual Studio. MS VS automatically re-adds its specific MFC-related resource
+infrastructure to the "xx.rc" files when saved after any modification. The
+dependancies on MFC related headers break the compilation process, when you
+try to use the freely available MS Visual Studio Express Editions (2005 or 2008)
+for building Zip. And, most third-party compilers also lack support for the
+propietary MFC environment.
diff --git a/win32/crc_i386.asm b/win32/crc_i386.asm
index 7693d75..19998ff 100644
--- a/win32/crc_i386.asm
+++ b/win32/crc_i386.asm
@@ -1,13 +1,13 @@
;===========================================================================
-; Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+; Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
;
-; See the accompanying file LICENSE, version 2004-May-22 or later
+; 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.asm, optimized CRC calculation function for Zip and UnZip,
-; created by Paul Kienitz and Christian Spieler.
+; created by Paul Kienitz and Christian Spieler. Last revised 07 Jan 2007.
;
; Revised 06-Oct-96, Scott Field (sfield@microsoft.com)
; fixed to assemble with masm by not using .model directive which makes
@@ -47,6 +47,16 @@
; Enabled the 686 build by default, because there are hardly any pre-686 CPUs
; in serious use nowadays. (See the 12-Oct-97 note above.)
;
+; Revised 03-Jan-2006, Chr. Spieler
+; Enlarged unrolling loops to "do 16 bytes per turn"; optimized access to
+; data buffer in loop body (adjust pointer only once in loop body and use
+; offsets to access each item); added additional support for the "unfolded
+; tables" optimization variant (enabled by IZ_CRCOPTIM_UNFOLDTBL).
+;
+; Revised 07-Jan-2007, Chr. Spieler
+; Recognize additional conditional flag CRC_TABLE_ONLY that prevents
+; compilation of the crc32() function.
+;
; FLAT memory model assumed.
;
; Loop unrolling can be disabled by defining the macro NO_UNROLLED_LOOPS.
@@ -54,9 +64,11 @@
;
;==============================================================================
;
-; Do NOT assemble this source if external crc32 routine from zlib gets used.
+; 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
;
.386p
name crc_i386
@@ -122,24 +134,81 @@ Do_CRC MACRO
ENDM
ELSE ; __686 : optimize for Pentium Pro, Pentium II and compatible CPUs
Do_CRC MACRO
- movzx ebx,al ; tmp = c & 0xFF
- shr eax,8 ; c = (c >> 8)
- xor eax,[edi+ebx*4] ; ^ table[tmp]
+ movzx ebx,al ; tmp = c & 0xFF
+ shr eax,8 ; c = (c >> 8)
+ xor eax,[edi+ebx*4] ; ^ table[tmp]
ENDM
ENDIF ; ?__686
Do_CRC_byte MACRO
- xor al, byte ptr [esi] ; c ^= *buf
- inc esi ; buf++
- Do_CRC ; c = (c >> 8) ^ table[c & 0xFF]
+ xor al, byte ptr [esi] ; c ^= *buf
+ inc esi ; buf++
+ Do_CRC ; c = (c >> 8) ^ table[c & 0xFF]
+ ENDM
+Do_CRC_byteof MACRO ofs
+ xor al, byte ptr [esi+ofs] ; c ^= *(buf+ofs)
+ Do_CRC ; c = (c >> 8) ^ table[c & 0xFF]
ENDM
IFNDEF NO_32_BIT_LOADS
-Do_CRC_dword MACRO
- xor eax, dword ptr [esi] ; c ^= *(ulg *)buf
- add esi, 4 ; ((ulg *)buf)++
+ IFDEF IZ_CRCOPTIM_UNFOLDTBL
+ ; the edx register is needed in crc calculation
+ SavLen EQU Arg3
+
+UpdCRC_dword MACRO
+ movzx ebx,al ; tmp = c & 0xFF
+ mov edx,[edi+ebx*4+3072] ; table[256*3+tmp]
+ movzx ebx,ah ; tmp = (c>>8) & 0xFF
+ shr eax,16 ;
+ xor edx,[edi+ebx*4+2048] ; ^ table[256*2+tmp]
+ movzx ebx,al ; tmp = (c>>16) & 0xFF
+ shr eax,8 ; tmp = (c>>24)
+ xor edx,[edi+ebx*4+1024] ; ^ table[256*1+tmp]
+ mov eax,[edi+eax*4] ; ^ table[256*0+tmp]
+ xor eax,edx ; ..
+ ENDM
+UpdCRC_dword_sh MACRO dwPtrIncr
+ movzx ebx,al ; tmp = c & 0xFF
+ mov edx,[edi+ebx*4+3072] ; table[256*3+tmp]
+ movzx ebx,ah ; tmp = (c>>8) & 0xFF
+ xor edx,[edi+ebx*4+2048] ; ^ table[256*2+tmp]
+ shr eax,16 ;
+ movzx ebx,al ; tmp = (c>>16) & 0xFF
+ add esi, 4*dwPtrIncr ; ((ulg *)buf) += dwPtrIncr
+ shr eax,8 ; tmp = (c>>24)
+ xor edx,[edi+ebx*4+1024] ; ^ table[256*1+tmp]
+ mov eax,[edi+eax*4] ; ^ table[256*0+tmp]
+ xor eax,edx ; ..
+ ENDM
+ ELSE ; IZ_CRCOPTIM_UNFOLDTBL
+ ; the edx register is not needed anywhere else
+ SavLen EQU edx
+
+UpdCRC_dword MACRO
+ Do_CRC
+ Do_CRC
Do_CRC
Do_CRC
+ ENDM
+UpdCRC_dword_sh MACRO dwPtrIncr
+ Do_CRC
Do_CRC
+ add esi, 4*dwPtrIncr ; ((ulg *)buf) += dwPtrIncr
Do_CRC
+ Do_CRC
+ ENDM
+ ENDIF ; ?IZ_CRCOPTIM_UNFOLDTBL
+Do_CRC_dword MACRO
+ xor eax, dword ptr [esi] ; c ^= *(ulg *)buf
+ UpdCRC_dword_sh 1 ; ... ((ulg *)buf)++
+ ENDM
+Do_CRC_4dword MACRO
+ xor eax, dword ptr [esi] ; c ^= *(ulg *)buf
+ UpdCRC_dword
+ xor eax, dword ptr [esi+4] ; c ^= *((ulg *)buf+1)
+ UpdCRC_dword
+ xor eax, dword ptr [esi+8] ; c ^= *((ulg *)buf+2)
+ UpdCRC_dword
+ xor eax, dword ptr [esi+12] ; c ^= *((ulg *)buf]+3
+ UpdCRC_dword_sh 4 ; ... ((ulg *)buf)+=4
ENDM
ENDIF ; !NO_32_BIT_LOADS
@@ -159,71 +228,90 @@ _crc32 proc near ; ulg crc32(ulg crc, ZCONST uch *buf, extent len)
push edx
push ecx
- mov esi,Arg2 ; 2nd arg: uch *buf
- sub eax,eax ;> if (!buf)
- test esi,esi ;> return 0;
- jz fine ;> else {
+ mov esi,Arg2 ; 2nd arg: uch *buf
+ sub eax,eax ;> if (!buf)
+ test esi,esi ;> return 0;
+ jz fine ;> else {
call _get_crc_table
mov edi,eax
- mov eax,Arg1 ; 1st arg: ulg crc
+ mov eax,Arg1 ; 1st arg: ulg crc
IFNDEF __686
- sub ebx,ebx ; ebx=0; make bl usable as a dword
+ sub ebx,ebx ; ebx=0; make bl usable as a dword
ENDIF
- mov ecx,Arg3 ; 3rd arg: extent len
- not eax ;> c = ~crc;
+ mov ecx,Arg3 ; 3rd arg: extent len
+ not eax ;> c = ~crc;
test ecx,ecx
IFNDEF NO_UNROLLED_LOOPS
jz bail
IFNDEF NO_32_BIT_LOADS
align_loop:
- test esi,3 ; align buf pointer on next
- jz SHORT aligned_now ; dword boundary
+ test esi,3 ; align buf pointer on next
+ jz SHORT aligned_now ; dword boundary
Do_CRC_byte
dec ecx
jnz align_loop
aligned_now:
ENDIF ; !NO_32_BIT_LOADS
- mov edx,ecx ; save len in edx
- shr ecx,3 ; ecx = len / 8
- jz SHORT No_Eights
+ mov SavLen,ecx ; save current len for later
+ shr ecx,4 ; ecx = len / 16
+ jz No_Sixteens
IFNDEF NO_ALIGN
; align loop head at start of 486 internal cache line !!
align 16
ENDIF
-Next_Eight:
+Next_Sixteen:
IFNDEF NO_32_BIT_LOADS
- Do_CRC_dword
- Do_CRC_dword
+ Do_CRC_4dword
ELSE ; NO_32_BIT_LOADS
- Do_CRC_byte
- Do_CRC_byte
- Do_CRC_byte
- Do_CRC_byte
- Do_CRC_byte
- Do_CRC_byte
- Do_CRC_byte
- Do_CRC_byte
+ 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
+ add esi, 16 ; buf += 16
ENDIF ; ?NO_32_BIT_LOADS
dec ecx
- jnz Next_Eight
-No_Eights:
- mov ecx,edx
- and ecx,000000007H ; ecx = len % 8
+ jnz Next_Sixteen
+No_Sixteens:
+ mov ecx,SavLen
+ and ecx,00000000FH ; ecx = len % 16
+ IFNDEF NO_32_BIT_LOADS
+ shr ecx,2 ; ecx = len / 4
+ jz SHORT No_Fours
+Next_Four:
+ Do_CRC_dword
+ dec ecx
+ jnz Next_Four
+No_Fours:
+ mov ecx,SavLen
+ and ecx,000000003H ; ecx = len % 4
+ ENDIF ; !NO_32_BIT_LOADS
ENDIF ; !NO_UNROLLED_LOOPS
- jz SHORT bail ;> if (len)
+ jz SHORT bail ;> if (len)
IFNDEF NO_ALIGN
; align loop head at start of 486 internal cache line !!
align 16
ENDIF
-loupe: ;> do {
- Do_CRC_byte ; c = CRC32(c, *buf++);
- dec ecx ;> } while (--len);
+loupe: ;> do {
+ Do_CRC_byte ; c = CRC32(c,*buf++,crctab);
+ dec ecx ;> } while (--len);
jnz loupe
-bail: ;> }
- not eax ;> return ~c;
+bail: ;> }
+ not eax ;> return ~c;
fine:
pop ecx
pop edx
@@ -236,6 +324,7 @@ _crc32 endp
_TEXT ends
;
+ ENDIF ; !CRC_TABLE_ONLY
ENDIF ; !USE_ZLIB
;
end
diff --git a/win32/crc_i386.c b/win32/crc_i386.c
index e8a2faf..971ee66 100644
--- a/win32/crc_i386.c
+++ b/win32/crc_i386.c
@@ -1,13 +1,14 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-2007 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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.c -- Microsoft 32-bit C/C++ adaptation of crc_i386.asm
* Created by Rodney Brown from crc_i386.asm, modified by Chr. Spieler.
+ * Last revised: 07-Jan-2007
*
* Original coded (in crc_i386.asm) and put into the public domain
* by Paul Kienitz and Christian Spieler.
@@ -56,6 +57,16 @@
* Also enabled the 686 build by default, because there are hardly any
* pre-686 CPUs in serious use nowadays. (See the 12-Oct-97 note above.)
*
+ * Revised 03-Jan-2006, Chr. Spieler
+ * Enlarged unrolling loops to "do 16 bytes per turn"; optimized access to
+ * data buffer in loop body (adjust pointer only once in loop body and use
+ * offsets to access each item); added additional support for the "unfolded
+ * tables" optimization variant (enabled by IZ_CRCOPTIM_UNFOLDTBL).
+ *
+ * Revised 07-Jan-2007, Chr. Spieler
+ * Recognize additional conditional flag CRC_TABLE_ONLY that prevents
+ * compilation of the crc32() function.
+ *
* FLAT memory model assumed.
*
* Loop unrolling can be disabled by defining the macro NO_UNROLLED_LOOPS.
@@ -64,8 +75,9 @@
*/
#include "../zip.h"
+#include "../crc32.h"
-#if defined(ASM_CRC) && !defined(USE_ZLIB)
+#if defined(ASM_CRC) && !defined(USE_ZLIB) && !defined(CRC_TABLE_ONLY)
#if !defined(PRE_686) && !defined(__686)
# define __686
@@ -119,14 +131,64 @@
__asm { inc esi }; \
Do_CRC; }
+#define Do_CRC_byteof(ofs) { \
+ __asm { xor al, byte ptr [esi+(ofs)] }; \
+ Do_CRC; }
+
#ifndef NO_32_BIT_LOADS
+#ifdef IZ_CRCOPTIM_UNFOLDTBL
+# define SavLen len /* the edx register is needed elsewhere */
+# define UpdCRC_dword { \
+ __asm { movzx ebx,al }; \
+ __asm { mov edx,[edi+ebx*4+3072] }; \
+ __asm { movzx ebx,ah }; \
+ __asm { shr eax,16 }; \
+ __asm { xor edx,[edi+ebx*4+2048] }; \
+ __asm { movzx ebx,al }; \
+ __asm { shr eax,8 }; \
+ __asm { xor edx,[edi+ebx*4+1024] }; \
+ __asm { mov eax,[edi+eax*4] }; \
+ __asm { xor eax,edx }; }
+# define UpdCRC_dword_sh(dwPtrIncr) { \
+ __asm { movzx ebx,al }; \
+ __asm { mov edx,[edi+ebx*4+3072] }; \
+ __asm { movzx ebx,ah }; \
+ __asm { xor edx,[edi+ebx*4+2048] }; \
+ __asm { shr eax,16 }; \
+ __asm { movzx ebx,al }; \
+ __asm { add esi, 4*dwPtrIncr }; \
+ __asm { shr eax,8 }; \
+ __asm { xor edx,[edi+ebx*4+1024] }; \
+ __asm { mov eax,[edi+eax*4] }; \
+ __asm { xor eax,edx }; }
+#else /* !IZ_CRCOPTIM_UNFOLDTBL */
+# define SavLen edx /* the edx register is free for use here */
+# define UpdCRC_dword { \
+ Do_CRC; \
+ Do_CRC; \
+ Do_CRC; \
+ Do_CRC; }
+# define UpdCRC_dword_sh(dwPtrIncr) { \
+ Do_CRC; \
+ Do_CRC; \
+ __asm { add esi, 4*(dwPtrIncr) }; \
+ Do_CRC; \
+ Do_CRC; }
+#endif /* ?IZ_CRCOPTIM_UNFOLDTBL */
+
#define Do_CRC_dword { \
__asm { xor eax, dword ptr [esi] }; \
- __asm { add esi, 4 }; \
- Do_CRC; \
- Do_CRC; \
- Do_CRC; \
- Do_CRC; }
+ UpdCRC_dword_sh(1); }
+
+#define Do_CRC_4dword { \
+ __asm { xor eax, dword ptr [esi] }; \
+ UpdCRC_dword; \
+ __asm { xor eax, dword ptr [esi+4] }; \
+ UpdCRC_dword; \
+ __asm { xor eax, dword ptr [esi+8] }; \
+ UpdCRC_dword; \
+ __asm { xor eax, dword ptr [esi+12] }; \
+ UpdCRC_dword_sh(4); }
#endif /* !NO_32_BIT_LOADS */
/* ========================================================================= */
@@ -170,46 +232,66 @@ align_loop:
jnz align_loop
aligned_now:
# endif /* !NO_32_BIT_LOADS */
- mov edx,ecx ;/* save len in edx */
- shr ecx,3 ;/* ecx = len / 8 */
- jz No_Eights
+ mov SavLen,ecx ;/* save current len for later */
+ shr ecx,4 ;/* ecx = len / 16 */
+ jz No_Sixteens
; align loop head at start of 486 internal cache line !!
align 16
-Next_Eight:
+Next_Sixteen:
}
# ifndef NO_32_BIT_LOADS
- Do_CRC_dword ;
- Do_CRC_dword ;
+ Do_CRC_4dword ;
# else /* NO_32_BIT_LOADS */
- Do_CRC_byte ;
- Do_CRC_byte ;
- Do_CRC_byte ;
- Do_CRC_byte ;
- Do_CRC_byte ;
- Do_CRC_byte ;
- Do_CRC_byte ;
- Do_CRC_byte ;
+ 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) ;
+ __asm { add esi,16 };
# endif /* ?NO_32_BIT_LOADS */
__asm {
dec ecx
- jnz Next_Eight
-No_Eights:
- mov ecx,edx
- and ecx,000000007H ;/* ecx = len % 8 */
-
+ jnz Next_Sixteen
+No_Sixteens:
+ mov ecx,SavLen
+ and ecx,00000000FH ;/* ecx = len % 16 */
+# ifndef NO_32_BIT_LOADS
+ shr ecx,2
+ jz No_Fours
+Next_Four:
+ }
+ Do_CRC_dword ;
+ __asm {
+ dec ecx
+ jnz Next_Four
+No_Fours:
+ mov ecx,SavLen
+ and ecx,000000003H ;/* ecx = len % 4 */
+# endif /* !NO_32_BIT_LOADS */
#endif /* !NO_UNROLLED_LOOPS */
- jz bail ;/*> if (len) */
+ jz bail ;/*> if (len) */
; align loop head at start of 486 internal cache line !!
align 16
-loupe: ;/*> do { */
+loupe: ;/*> do { */
}
- Do_CRC_byte ;/* c = CRC32(c, *buf++); */
+ Do_CRC_byte ;/* c = CRC32(c,*buf++,crctab);*/
__asm {
- dec ecx ;/*> } while (--len); */
+ dec ecx ;/*> } while (--len); */
jnz loupe
-bail: ;/*> } */
- not eax ;/*> return ~c; */
+bail: ;/*> } */
+ not eax ;/*> return ~c; */
fine:
pop ecx
pop edx
@@ -225,4 +307,4 @@ fine:
# pragma warning( default : 4035 )
#endif
#endif
-#endif /* ASM_CRC && !USE_ZLIB */
+#endif /* ASM_CRC && !USE_ZLIB && !CRC_TABLE_ONLY */
diff --git a/win32/crc_lcc.asm b/win32/crc_lcc.asm
index 3c7a41c..1538d32 100644
--- a/win32/crc_lcc.asm
+++ b/win32/crc_lcc.asm
@@ -1,13 +1,13 @@
;===========================================================================
-; Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+; Copyright (c) 1990-2006 Info-ZIP. All rights reserved.
;
-; See the accompanying file LICENSE, version 2004-May-22 or later
+; 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, both of these files are missing, the Info-ZIP license
-; also may be found at: ftp://ftp.info-zip.org/pub/infozip/licen; Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+; 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_lcc.asm, optimized CRC calculation function for Zip and UnZip,
-; created by Paul Kienitz and Christian Spieler. Last revised 24 Dec 98.
+; created by Paul Kienitz and Christian Spieler. Last revised 02 Jan 2006.
;
; The code in this file has been copied verbatim from crc_i386.{asm|S};
; only the assembler syntax and metacommands have been adapted to
@@ -59,11 +59,10 @@ _$5:
jnz _$5
_$6:
movl %ecx,%edx
- shrl $3,%ecx
+ shrl $4,%ecx
jz _$8
_$7:
xorl (%esi),%eax
- addl $4,%esi
movzbl %al,%ebx
shrl $8,%eax
xorl (%edi,%ebx,4),%eax
@@ -76,17 +75,43 @@ _$7:
movzbl %al,%ebx
shrl $8,%eax
xorl (%edi,%ebx,4),%eax
- xorl (%esi),%eax
- addl $4,%esi
+ xorl 4(%esi),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ xorl 8(%esi),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
movzbl %al,%ebx
shrl $8,%eax
xorl (%edi,%ebx,4),%eax
+ xorl 12(%esi),%eax
movzbl %al,%ebx
shrl $8,%eax
xorl (%edi,%ebx,4),%eax
movzbl %al,%ebx
shrl $8,%eax
xorl (%edi,%ebx,4),%eax
+ addl $16,%esi
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
movzbl %al,%ebx
shrl $8,%eax
xorl (%edi,%ebx,4),%eax
@@ -94,16 +119,38 @@ _$7:
jnz _$7
_$8:
movl %edx,%ecx
- andl $7,%ecx
- jz _$4
+ andl $0x0f,%ecx
+ shrl $2,%ecx
+ jz _$10
_$9:
+ xorl (%esi),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ addl $4,%esi
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ movzbl %al,%ebx
+ shrl $8,%eax
+ xorl (%edi,%ebx,4),%eax
+ decl %ecx
+ jnz _$9
+_$10:
+ movl %edx,%ecx
+ andl $0x03,%ecx
+ jz _$4
+_$11:
xorb (%esi),%al
incl %esi
movzbl %al,%ebx
shrl $8,%eax
xorl (%edi,%ebx,4),%eax
decl %ecx
- jnz _$9
+ jnz _$11
_$4:
xorl $0xffffffff,%eax
_$3:
diff --git a/win32/lm32_lcc.asm b/win32/lm32_lcc.asm
index 2fde1a4..0450fe3 100644
--- a/win32/lm32_lcc.asm
+++ b/win32/lm32_lcc.asm
@@ -1,10 +1,10 @@
;===========================================================================
-; Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+; Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
;
-; See the accompanying file LICENSE, version 2004-May-22 or later
+; 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.info-zip.org/pub/infozip/license.html
+; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
;===========================================================================
; match32.asm by Jean-loup Gailly.
diff --git a/win32/makefile.a64 b/win32/makefile.a64
index 521950e..d2bc841 100644
--- a/win32/makefile.a64
+++ b/win32/makefile.a64
@@ -17,7 +17,7 @@ ASMOBJS = gvmat64.obj
# ------------- 32-bit Microsoft Visual C++ -------------
CC=cl -nologo
-CFLAGS=-W3 -O2 -DNO_ASM_CRC -DASMV -DWIN32 $(LOC)
+CFLAGS=-W3 -O2 -DNO_ASM_CRC -DASMV -DWIN32 $(LOC)
UTILFLAGS=$(CFLAGS) -DUTIL -Fo$@
# Remove "-coff" from ASFLAGS if you do not have MASM 6.11.
@@ -34,13 +34,13 @@ LDFLAGS=advapi32.lib
# variables
OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \
- crc32.obj crctab.obj globals.obj
+ crc32.obj globals.obj
OBJI = deflate.obj trees.obj $(ASMOBJS) win32.obj win32zip.obj nt.obj
OBJU = zipfile_.obj fileio_.obj util_.obj globals.obj win32_.obj
OBJN = zipnote.obj $(OBJU)
-OBJC = zipcloak.obj crctab.obj crypt_.obj ttyio.obj $(OBJU)
+OBJC = zipcloak.obj crc32_.obj crypt_.obj ttyio.obj $(OBJU)
OBJS = zipsplit.obj $(OBJU)
ZIP_H = zip.h ziperr.h tailor.h win32/osdep.h
@@ -49,16 +49,16 @@ ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe
zips: $(ZIPS)
-zip.obj: zip.c $(ZIP_H) revision.h crypt.h ttyio.h
+zip.obj: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
$(CC) -c $(CFLAGS) $*.c
-zipfile.obj: zipfile.c $(ZIP_H)
+zipfile.obj: zipfile.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
-zipup.obj: zipup.c $(ZIP_H) revision.h crypt.h win32/zipup.h
+zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h win32/zipup.h
$(CC) -c $(CFLAGS) $*.c
-fileio.obj: fileio.c $(ZIP_H)
+fileio.obj: fileio.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
util.obj: util.c $(ZIP_H)
@@ -73,13 +73,10 @@ deflate.obj: deflate.c $(ZIP_H)
trees.obj: trees.c $(ZIP_H)
$(CC) -c $(CFLAGS) $*.c
-crc32.obj: crc32.c $(ZIP_H)
+crc32.obj: crc32.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
-crctab.obj: crctab.c $(ZIP_H)
- $(CC) -c $(CFLAGS) $*.c
-
-crypt.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+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
@@ -103,16 +100,19 @@ zipnote.obj: zipnote.c $(ZIP_H) revision.h
zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
$(CC) -c $(CFLAGS) $*.c
-zipfile_.obj: zipfile.c $(ZIP_H)
+zipfile_.obj: zipfile.c $(ZIP_H) crc32.h
$(CC) -c $(UTILFLAGS) zipfile.c
-fileio_.obj: fileio.c $(ZIP_H)
+fileio_.obj: fileio.c $(ZIP_H) crc32.h
$(CC) -c $(UTILFLAGS) fileio.c
util_.obj: util.c $(ZIP_H)
$(CC) -c $(UTILFLAGS) util.c
-crypt_.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+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
win32_.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
diff --git a/win32/makefile.bor b/win32/makefile.bor
index 5f70b81..10b4609 100644
--- a/win32/makefile.bor
+++ b/win32/makefile.bor
@@ -1,6 +1,8 @@
# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for
-# Borland C++ for Windows 9x/NT
-# By E-Yen Tan. Last updated on 24 Jan 2005.
+# Borland C++ for Win32.
+# By E-Yen Tan.
+# Updated on 18 Dec 2005 by Cosmin Truta.
+# Last updated on 22 Jun 2008 by Christian Spieler.
# To use, do "make -fwin32\makefile.bor"
@@ -16,13 +18,14 @@ LOC = $(LOCAL_ZIP)
LOC = -DNO_ASM $(LOCAL_ZIP)
!ENDIF
-# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
+# CPU type: 3 (i386), 4 (i486), 5 (Pentium), etc.
CPU_TYP = 6
# Uncomment the following macro to use the optimized assembler
# routines in Zip:
!IF $(USEASM)
-ASMOBJS = match32.obj crc_i386.obj
+ASMOBJS = match32.obj
+CRCA_O = crc_i386.obj
!ENDIF
ASCPUFLAG = __$(CPU_TYP)86
@@ -39,19 +42,20 @@ AS=tasm32
!endif
ASFLAGS=-ml -t -m2 -D$(ASCPUFLAG) $(LOC)
-LD=$(CC)
+LD=ilink32
LDFLAGS=
# variables
OBJZ1 = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \
- crc32.obj crctab.obj globals.obj
+ crc32.obj $(CRCA_O) globals.obj
OBJZ2 = deflate.obj trees.obj $(ASMOBJS)
-OBJZS = win32zip.obj win32.obj nt.obj
+OBJZS = win32zip.obj win32.obj win32i64.obj nt.obj
OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZS)
-OBJU = zipfile_.obj fileio_.obj util_.obj globals.obj win32_.obj
+OBJU = zipfile_.obj fileio_.obj util_.obj crc32_.obj $(CRCA_O) globals.obj \
+ win32_.obj win32i64.obj
OBJN = zipnote.obj $(OBJU)
-OBJC = zipcloak.obj crctab.obj crypt_.obj ttyio.obj $(OBJU)
+OBJC = zipcloak.obj crypt_.obj ttyio.obj $(OBJU)
OBJS = zipsplit.obj $(OBJU)
ZIP_H = zip.h ziperr.h tailor.h win32/osdep.h
@@ -60,16 +64,16 @@ ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe
zips: $(ZIPS)
-zip.obj: zip.c $(ZIP_H) revision.h crypt.h ttyio.h
+zip.obj: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
$(CC) -c $(CFLAGS) $*.c
-zipfile.obj: zipfile.c $(ZIP_H)
+zipfile.obj: zipfile.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
-zipup.obj: zipup.c $(ZIP_H) revision.h crypt.h win32/zipup.h
+zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h win32/zipup.h
$(CC) -c $(CFLAGS) $*.c
-fileio.obj: fileio.c $(ZIP_H)
+fileio.obj: fileio.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
util.obj: util.c $(ZIP_H)
@@ -84,28 +88,28 @@ deflate.obj: deflate.c $(ZIP_H)
trees.obj: trees.c $(ZIP_H)
$(CC) -c $(CFLAGS) $*.c
-crc32.obj: crc32.c $(ZIP_H)
+crc32.obj: crc32.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
-crctab.obj: crctab.c $(ZIP_H)
- $(CC) -c $(CFLAGS) $*.c
-
-crypt.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+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
win32zip.obj: win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h
- $(CC) -c $(CFLAGS) win32/$*.c
+ $(CC) -c $(CFLAGS) win32/$*.c
win32.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
- $(CC) -c $(CFLAGS) win32/$*.c
+ $(CC) -c $(CFLAGS) win32/$*.c
+
+win32i64.obj: win32/win32i64.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) win32/$*.c
nt.obj: win32/nt.c $(ZIP_H) win32/nt.h
- $(CC) -c $(CFLAGS) win32/$*.c
+ $(CC) -c $(CFLAGS) win32/$*.c
-zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+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
@@ -114,16 +118,19 @@ zipnote.obj: zipnote.c $(ZIP_H) revision.h
zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
$(CC) -c $(CFLAGS) $*.c
-zipfile_.obj: zipfile.c $(ZIP_H)
+zipfile_.obj: zipfile.c $(ZIP_H) crc32.h
$(CC) -c $(UTILFLAGS)$* zipfile.c
-fileio_.obj: fileio.c $(ZIP_H)
+fileio_.obj: fileio.c $(ZIP_H) crc32.h
$(CC) -c $(UTILFLAGS)$* fileio.c
util_.obj: util.c $(ZIP_H)
$(CC) -c $(UTILFLAGS)$* util.c
-crypt_.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+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
win32_.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
@@ -137,7 +144,7 @@ crc_i386.obj: win32/crc_i386.asm
crc_i386.obj: win32/crc_i386.asm
$(AS) $(ASFLAGS) win32\crc_i386.asm, $@ ;
!else
-crc_i386.obj: win32/crc_i386.c
+crc_i386.obj: win32/crc_i386.c crc32.h
$(CC) -c $(CFLAGS) -o$@ win32/crc_i386.c
!endif
!endif
@@ -147,33 +154,36 @@ match32.obj: win32/match32.asm
masm -ml win32/match32.asm,$@;
!else
match32.obj: win32/match32.asm
- $(AS) $(ASFLAGS) win32\match32.asm, $@ ;
+ $(AS) $(ASFLAGS) win32\match32.asm, $@ ;
!endif
-# we must cut the command line to fit in the MS/DOS 128 byte limit:
-zip.exe: $(OBJZ)
- echo $(OBJZ1) > zip.rsp
- echo $(OBJZ2) >> zip.rsp
- echo $(OBJZS) >> zip.rsp
- $(LD) $(LDFLAGS) @zip.rsp
- del zip.rsp
+zip.res: win32/zip.rc revision.h
+ $(RC) /l 0x409 /fo$@ /i win32 /d WIN32 win32/zip.rc
+
+# Split the command line to fit in the MS-DOS 128 byte limit by using
+# Borland-Make specific response file syntax:
+zip.exe: $(OBJZ) zip.res
+ $(LD) -Gn -x -c -ap -Tpe @&&|
+c0x32.obj $(OBJZ),$@,,import32.lib cw32.lib,,zip.res
+|
zipcloak.exe: $(OBJC)
- echo $(OBJC) > zipc.rsp
- $(LD) $(LDFLAGS) @zipc.rsp
- del zipc.rsp
+ $(CC) $(LDFLAGS) @&&|
+$(OBJC)
+|
zipnote.exe: $(OBJN)
- echo $(OBJN) > zipn.rsp
- $(LD) $(LDFLAGS) @zipn.rsp
- del zipn.rsp
+ $(CC) $(LDFLAGS) @&&|
+$(OBJN)
+|
zipsplit.exe: $(OBJS)
- echo $(OBJS) > zips.rsp
- $(LD) $(LDFLAGS) @zips.rsp
- del zips.rsp
+ $(CC) $(LDFLAGS) @&&|
+$(OBJS)
+|
clean:
- del *.obj
- del *.exe
- del *.tds
+ -del *.obj
+ -del *.res
+ -del *.exe
+ -del *.tds
diff --git a/win32/makefile.dj b/win32/makefile.dj
index ead72e0..902c9ed 100644
--- a/win32/makefile.dj
+++ b/win32/makefile.dj
@@ -1,6 +1,6 @@
# Makefile for Zip, ZipCloak, ZipNote and ZipSplit
# for djgpp 2.01 and RSXNTDJ 1.3.1 under Windows 95 / Windows NT
-# Derived from makefile.os2 by E-Yen Tan. Last updated 22 May 1998.
+# Derived from makefile.os2 by E-Yen Tan. Last updated 07 Jan 2007.
CC = gcc -O2 -m486 -Wall -Zwin32
CFLAGS = -DWIN32 -DASM_CRC $(LOCAL_ZIP)
@@ -21,17 +21,17 @@ ADVAPI32LIB = lib$(ADVAPI32).a
L_ADVAPI32 = -l$(ADVAPI32)
OBJZ1 = zip$(OBJ) zipfile$(OBJ) zipup$(OBJ) fileio$(OBJ) util$(OBJ) \
- $(CRC32)$(OBJ) crctab$(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)
+OBJU1 = zipfile_$(OBJ) fileio_$(OBJ) util_$(OBJ) crc32$(OBJ) globals$(OBJ)
OBJU = $(OBJU1) $(OBJUS)
OBJN = zipnote$(OBJ) $(OBJU)
OBJS = zipsplit$(OBJ) $(OBJU)
-OBJC = zipcloak$(OBJ) crctab$(OBJ) crypt_$(OBJ) ttyio$(OBJ) $(OBJU)
+OBJC = zipcloak$(OBJ) crc32_$(OBJ) crypt_$(OBJ) ttyio$(OBJ) $(OBJU)
ZIP_H = zip.h ziperr.h tailor.h $(OSDEP_H)
@@ -47,17 +47,16 @@ ZIP_H = zip.h ziperr.h tailor.h $(OSDEP_H)
all: zip.exe zipnote.exe zipsplit.exe zipcloak.exe
-zip$(OBJ): zip.c $(ZIP_H) revision.h crypt.h ttyio.h
-zipfile$(OBJ): zipfile.c $(ZIP_H)
-zipup$(OBJ): zipup.c $(ZIP_H) revision.h crypt.h win32/zipup.h
-fileio$(OBJ): fileio.c $(ZIP_H)
+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 win32/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)
-crctab$(OBJ): crctab.c $(ZIP_H)
-crypt$(OBJ): crypt.c $(ZIP_H) crypt.h ttyio.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
win32zip$(OBJ): win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h
@@ -75,20 +74,23 @@ crc_gcc$(OBJ): crc_i386.S # 32bit, GNU AS
matchgcc$(OBJ): match.S
$(AS) $(ASFLAGS) -x assembler-with-cpp -c -o$@ match.S
-zipcloak$(OBJ): zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+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)
+zipfile_$(OBJ): zipfile.c $(ZIP_H) crc32.h
$(CC) -c -I. $(CFLAGS) -DUTIL -o$@ zipfile.c
-fileio_$(OBJ): fileio.c $(ZIP_H)
+fileio_$(OBJ): fileio.c $(ZIP_H) crc32.h
$(CC) -c -I. $(CFLAGS) -DUTIL -o$@ fileio.c
util_$(OBJ): util.c $(ZIP_H) os2/os2zip.h
$(CC) -c -I. $(CFLAGS) -DUTIL -o$@ util.c
-crypt_$(OBJ): crypt.c $(ZIP_H) crypt.h ttyio.h
+crc32_$(OBJ): crc32.c $(ZIP_H) crc32.h
+ $(CC) -c -I. $(CFLAGS) -DUTIL -o$@ crc32.c
+
+crypt_$(OBJ): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
$(CC) -c -I. $(CFLAGS) -DUTIL -o$@ crypt.c
win32_$(OBJ): win32/win32.c $(ZIP_H) win32/win32zip.h
diff --git a/win32/makefile.emx b/win32/makefile.emx
index 197a8ea..5f050ab 100644
--- a/win32/makefile.emx
+++ b/win32/makefile.emx
@@ -1,7 +1,7 @@
# Makefile for Zip, ZipCloak, ZipNote and ZipSplit
# using emx 0.9c+rsxnt for Windows 95/98 and Windows NT and emx 0.9c for DOS.
# By Kai-Uwe Rommel, Chr. Spieler, E-Yen Tan (and others).
-# Last updated 30th June 1998.
+# Last updated 18th February 2007.
#
# Supported Make utilities:
# - Microsoft/IBM nmake (e.g. from MSC 6.0 or newer)
@@ -55,7 +55,8 @@ gccso:
LDFLAGS2="-ladvapi32 -s" \
OUT="-o" \
OBJ=".o" \
- CRC32="crc_gcc" \
+ CRCA_O="crc_gcc.o" \
+ CRCAUO="crcgcc_.o" \
OBJA="matchgcc.o" \
DEF="win32/zip.def"
@@ -70,7 +71,8 @@ gccdyn:
LDFLAGS2="-ladvapi32 -s" \
OUT="-o" \
OBJ=".o" \
- CRC32="crc_gcc" \
+ CRCA_O="crc_gcc.o" \
+ CRCAUO="crcgcc_.o" \
OBJA="matchgcc.o" \
DEF="win32/zip.def"
@@ -85,7 +87,8 @@ gccdebug:
LDFLAGS2="-ladvapi32 -Zsmall-conv" \
OUT="-o" \
OBJ=".o" \
- CRC32="crc_gcc" \
+ CRCA_O="crc_gcc.o" \
+ CRCAUO="crcgcc_.o" \
OBJA="matchgcc.o" \
DEF="win32/zip.def"
@@ -100,7 +103,8 @@ gcczl:
LDFLAGS2="-L. -lzlib -ladvapi32 -s" \
OUT="-o" \
OBJ=".o" \
- CRC32="crc32" \
+ CRCA_O="" \
+ CRCAUO="" \
OBJA="" \
DEF="win32/zip.def"
@@ -115,7 +119,8 @@ gccdos:
LDFLAGS2="-s -Zsmall-conv" \
OUT="-o" \
OBJ=".o" \
- CRC32="crc_gcc" \
+ CRCA_O="crc_gcc.o" \
+ CRCAUO="crcgcc_.o" \
OBJA="matchgcc.o" \
OBJZS="msdos.o" \
OBJUS="msdos_.o" \
@@ -133,7 +138,8 @@ gccdoszl:
LDFLAGS2="-L. -lzlib -s -Zsmall-conv" \
OUT="-o" \
OBJ=".o" \
- CRC32="crc32" \
+ CRCA_O="" \
+ CRCAUO="" \
OBJA="" \
OBJZS="msdos.o" \
OBJUS="msdos_.o" \
@@ -155,8 +161,9 @@ LDFLAGS=-o ./
LDFLAGS2=-ladvapi32 -s -Zsmall-conv
OUT=-o
OBJ=.o
-CRC32=crc_gcc
-OBJA=matchgcc.o
+CRCA_O=crc_gcc$(OBJ)
+CRCAUO=crcgcc_$(OBJ)
+OBJA=matchgcc$(OBJ)
OSDEP_H=win32/osdep.h
ZIPUP_H=win32/zipup.h
DEF=win32/zip.def
@@ -169,19 +176,20 @@ CCFLAGS = $(CFLAGS) $(LOCAL_OPTS)
OBJZ1 = zip$(OBJ) zipfile$(OBJ) zipup$(OBJ) fileio$(OBJ) util$(OBJ) \
- $(CRC32)$(OBJ) crctab$(OBJ)
+ crc32$(OBJ) $(CRCA_O)
OBJZ2 = globals$(OBJ) deflate$(OBJ) trees$(OBJ) crypt$(OBJ) \
ttyio$(OBJ)
OBJZS = win32zip$(OBJ) win32$(OBJ) nt$(OBJ)
OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZS) $(OBJA)
-OBJU1 = zipfile_$(OBJ) fileio_$(OBJ) util_$(OBJ) globals$(OBJ)
+OBJU1 = zipfile_$(OBJ) fileio_$(OBJ) util_$(OBJ) crc32_$(OBJ) $(CRCAUO) \
+ globals$(OBJ)
OBJUS = win32_$(OBJ)
OBJU = $(OBJU1) $(OBJUS)
OBJN = zipnote$(OBJ) $(OBJU)
OBJS = zipsplit$(OBJ) $(OBJU)
-OBJC1 = zipcloak$(OBJ) crctab$(OBJ) crypt_$(OBJ) ttyio$(OBJ)
+OBJC1 = zipcloak$(OBJ) crypt_$(OBJ) ttyio$(OBJ)
OBJC = $(OBJC1) $(OBJU)
ZIP_H = zip.h ziperr.h tailor.h $(OSDEP_H)
@@ -197,17 +205,16 @@ ZIP_H = zip.h ziperr.h tailor.h $(OSDEP_H)
all: zip.exe zipnote.exe zipsplit.exe zipcloak.exe
-zip$(OBJ): zip.c $(ZIP_H) revision.h crypt.h ttyio.h
-zipfile$(OBJ): zipfile.c $(ZIP_H)
-zipup$(OBJ): zipup.c $(ZIP_H) revision.h crypt.h $(ZIPUP_H)
-fileio$(OBJ): fileio.c $(ZIP_H)
+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)
-crctab$(OBJ): crctab.c $(ZIP_H)
-crypt$(OBJ): crypt.c $(ZIP_H) crypt.h ttyio.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)
@@ -232,16 +239,19 @@ zipcloak$(OBJ): zipcloak.c $(ZIP_H) revision.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)
+zipfile_$(OBJ): zipfile.c $(ZIP_H) crc32.h
$(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ zipfile.c
-fileio_$(OBJ): fileio.c $(ZIP_H)
+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
-crypt_$(OBJ): crypt.c $(ZIP_H) crypt.h ttyio.h
+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)
@@ -250,6 +260,9 @@ msdos_$(OBJ): msdos/msdos.c $(ZIP_H)
win32_$(OBJ): win32/win32.c $(ZIP_H) win32/win32zip.h
$(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ win32$(DIRSEP)win32.c
+crcgcc_$(OBJ): crc_i386.S # 32bit, GNU AS
+ $(AS) $(ASFLAGS) -DUTIL -x assembler-with-cpp -c -o $@ crc_i386.S
+
zip.exe: $(OBJZ)
# for DUMB make utilities, uncomment the following commands:
-@$(RM) zip.rsp
diff --git a/win32/makefile.gcc b/win32/makefile.gcc
index 6e924ad..d28c447 100644
--- a/win32/makefile.gcc
+++ b/win32/makefile.gcc
@@ -2,7 +2,7 @@
# native Win32-Intel binaries. Derived from makefile.w32.
# Currently supported implementations: Cygwin and MinGW.
# Authors: Cosmin Truta, Christian Spieler, and possibly others.
-# Last updated: 2005-Jan-24.
+# Last updated: 2008-Jun-22.
#
# To use, do "make -f win32/makefile.gcc".
@@ -13,12 +13,12 @@ LOC = $(LOCAL_ZIP)
# ------------ GNU C ------------
CC=gcc
+CFLAGS=-O2 -Wall -DWIN32 -DFORCE_WIN32_OVER_UNIX
ifndef USEZLIB
-CFLAGS=-O2 -Wall -DWIN32
+CCFLAGS=$(CFLAGS) $(LOC)
else
-CFLAGS=-O2 -Wall -DWIN32 -DUSE_ZLIB
+CCFLAGS=$(CFLAGS) -DUSE_ZLIB $(LOC)
endif
-CCFLAGS=$(CFLAGS) $(LOC)
UTILFLAGS=$(CCFLAGS) -DUTIL -o$@
#AS=as
@@ -30,6 +30,8 @@ ASDEFS=-DUSE_ZLIB
endif
ASFLAGS=-c $(ASDEFS) $(LOC)
+RC=windres
+
LD=$(CC)
LDFLAGS=-o$@ -s
ifndef USEZLIB
@@ -43,25 +45,29 @@ ZIPUP_H = win32/zipup.h
# variables
ifndef USEZLIB
-OBJA = match.o crc_i386.o
+CRCA_O = crc_i386.o
+CRCAUO = crci386_.o
+OBJA = match.o $(CRCA_O)
else
+CRCA_O =
+CRCAUO =
OBJA =
endif
#use second definition for linking against libz
OBJZ1 = zip.o crypt.o ttyio.o zipfile.o zipup.o fileio.o util.o \
- crc32.o crctab.o globals.o
+ crc32.o globals.o
OBJZ2 = deflate.o trees.o $(OBJA)
-OBJZS = win32.o win32zip.o nt.o
+OBJZS = win32.o win32zip.o win32i64.o nt.o
OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZS)
-OBJU1 = zipfile_.o fileio_.o util_.o globals.o
-OBJUS = win32_.o
+OBJU1 = zipfile_.o fileio_.o util_.o crc32_.o $(CRCAUO) globals.o
+OBJUS = win32_.o win32i64.o
OBJU = $(OBJU1) $(OBJUS)
OBJN = zipnote.o $(OBJU)
OBJS = zipsplit.o $(OBJU)
-OBJC1 = zipcloak.o crctab.o crypt_.o ttyio.o
+OBJC1 = zipcloak.o crypt_.o ttyio.o
OBJC = $(OBJC1) $(OBJU)
ZIP_H = zip.h ziperr.h tailor.h $(OSDEP_H)
@@ -79,17 +85,16 @@ ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe
zips: $(ZIPS)
-zip.o: zip.c $(ZIP_H) revision.h crypt.h ttyio.h
-zipfile.o: zipfile.c $(ZIP_H)
-zipup.o: zipup.c $(ZIP_H) revision.h crypt.h $(ZIPUP_H)
-fileio.o: fileio.c $(ZIP_H)
+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 $(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)
-crc32.o: crc32.c $(ZIP_H)
-crctab.o: crctab.c $(ZIP_H)
-crypt.o: crypt.c $(ZIP_H) crypt.h ttyio.h
+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
win32zip.o: win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h
@@ -98,23 +103,29 @@ win32zip.o: win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h
win32.o: win32/win32.c $(ZIP_H) win32/win32zip.h
$(CC) -c $(CCFLAGS) -I. win32/win32.c
+win32i64.o: win32/win32i64.c $(ZIP_H)
+ $(CC) -c $(CCFLAGS) -I. win32/win32i64.c
+
nt.o: win32/nt.c $(ZIP_H) win32/nt.h
$(CC) -c $(CCFLAGS) -I. win32/nt.c
-zipcloak.o: zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.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)
+zipfile_.o: zipfile.c $(ZIP_H) crc32.h
$(CC) -c $(UTILFLAGS) zipfile.c
-fileio_.o: fileio.c $(ZIP_H)
+fileio_.o: fileio.c $(ZIP_H) crc32.h
$(CC) -c $(UTILFLAGS) fileio.c
util_.o: util.c $(ZIP_H)
$(CC) -c $(UTILFLAGS) util.c
-crypt_.o: crypt.c $(ZIP_H) crypt.h ttyio.h
+crc32_.o: crc32.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS) crc32.c
+
+crypt_.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
$(CC) -c $(UTILFLAGS) crypt.c
win32_.o: win32/win32.c $(ZIP_H) win32/win32zip.h
@@ -126,8 +137,14 @@ match.o: match.S
crc_i386.o: crc_i386.S
$(AS) $(ASFLAGS) crc_i386.S
-zip.exe: $(OBJZ)
- $(LD) $(LDFLAGS) $(OBJZ) $(LIBS)
+crci386_.o: crc_i386.S
+ $(AS) $(ASFLAGS) -DUTIL -o$@ crc_i386.S
+
+ziprc.o: win32/zip.rc revision.h
+ - $(RC) -o $@ win32/zip.rc
+
+zip.exe: $(OBJZ) ziprc.o
+ $(LD) $(LDFLAGS) $(OBJZ) ziprc.o $(LIBS)
zipcloak.exe: $(OBJC)
$(LD) $(LDFLAGS) $(OBJC) $(LIBS)
diff --git a/win32/makefile.ibm b/win32/makefile.ibm
index 74acfd9..3cd2975 100644
--- a/win32/makefile.ibm
+++ b/win32/makefile.ibm
@@ -23,13 +23,13 @@ ASFLAGS=-c -Cx
# variables
OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \
- crc32.obj crctab.obj globals.obj
+ crc32.obj globals.obj
OBJI = deflate.obj trees.obj $(ASMOBJS) win32.obj win32zip.obj nt.obj
OBJU = zipfile_.obj fileio_.obj util_.obj globals.obj win32_.obj
OBJN = zipnote.obj $(OBJU)
-OBJC = zipcloak.obj crctab.obj crypt_.obj ttyio.obj $(OBJU)
+OBJC = zipcloak.obj crc32_.obj crypt_.obj ttyio.obj $(OBJU)
OBJS = zipsplit.obj $(OBJU)
ZIP_H = zip.h ziperr.h tailor.h win32/osdep.h
@@ -38,16 +38,16 @@ ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe
zips: $(ZIPS)
-zip.obj: zip.c $(ZIP_H) revision.h crypt.h ttyio.h
+zip.obj: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
$(CC) -c $(CFLAGS) $*.c
-zipfile.obj: zipfile.c $(ZIP_H)
+zipfile.obj: zipfile.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
-zipup.obj: zipup.c $(ZIP_H) revision.h crypt.h win32/zipup.h
+zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h win32/zipup.h
$(CC) -c $(CFLAGS) $*.c
-fileio.obj: fileio.c $(ZIP_H)
+fileio.obj: fileio.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
util.obj: util.c $(ZIP_H)
@@ -62,13 +62,10 @@ deflate.obj: deflate.c $(ZIP_H)
trees.obj: trees.c $(ZIP_H)
$(CC) -c $(CFLAGS) $*.c
-crc32.obj: crc32.c $(ZIP_H)
+crc32.obj: crc32.c $(ZIP_H) crc32.h
$(CC) -c $(CFLAGS) $*.c
-crctab.obj: crctab.c $(ZIP_H)
- $(CC) -c $(CFLAGS) $*.c
-
-crypt.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+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
@@ -83,7 +80,7 @@ win32.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
nt.obj: win32/nt.c $(ZIP_H) win32/nt.h
$(CC) -c $(CFLAGS) -I. win32/nt.c
-zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+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
@@ -92,16 +89,19 @@ zipnote.obj: zipnote.c $(ZIP_H) revision.h
zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
$(CC) -c $(CFLAGS) $*.c
-zipfile_.obj: zipfile.c $(ZIP_H)
+zipfile_.obj: zipfile.c $(ZIP_H) crc32.h
$(CC) -c $(UTILFLAGS) zipfile.c
-fileio_.obj: fileio.c $(ZIP_H)
+fileio_.obj: fileio.c $(ZIP_H) crc32.h
$(CC) -c $(UTILFLAGS) fileio.c
util_.obj: util.c $(ZIP_H)
$(CC) -c $(UTILFLAGS) util.c
-crypt_.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+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
win32_.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
diff --git a/win32/makefile.lcc b/win32/makefile.lcc
index b40e77c..6c7e8b5 100644
--- a/win32/makefile.lcc
+++ b/win32/makefile.lcc
@@ -1,6 +1,6 @@
# Makefile for Zip, ZipCloak, ZipNote and ZipSplit using LCC-Win32.
# By E-Yen Tan (3 June 1998).
-# Last updated 21 December 1998 (Christian Spieler).
+# Last updated 9 February 2008 (Christian Spieler).
# This compiler evaluates #include locations relative to current working dir,
# not relative to the location of the file containing the #include directive.
@@ -10,7 +10,7 @@
CC = lcc
# -O caused a segmentation violation with previous versions of lcc, but
# now the optimizer seems to be fixed.
-CCFLAGS = -zp8 -O -DWIN32
+CCFLAGS = -Zp8 -O -DWIN32
AS = lcc
ASFLAGS =
LD = lcclnk
@@ -22,11 +22,11 @@ LOC = $(ASMFLG)
# Options to select optimized assembler code for CRC32 calculation.
#ifdef USEASM
-CRC32 = crc_lcc
+CRCA_O = crc_lcc.obj
OBJA = lm32_lcc.obj
ASMFLG = -DASM_CRC -DASMV
#else
-#CRC32 = crc32
+#CRCA_O =
#OBJA =
#ASMFLG = -DNO_ASM
#endif
@@ -37,16 +37,16 @@ OBJZS = win32.obj win32zip.obj nt.obj $(OBJA)
OBJUS = win32_.obj
OBJZ1 = zip.obj zipfile.obj zipup.obj fileio.obj util.obj
-OBJZ2 = $(CRC32).obj crctab.obj globals.obj
+OBJZ2 = crc32.obj $(CRCA_O) globals.obj
OBJZ3 = deflate.obj trees.obj crypt.obj ttyio.obj
OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZ3) $(OBJZS)
-OBJU1 = zipfile_.obj fileio_.obj util_.obj globals.obj
+OBJU1 = zipfile_.obj fileio_.obj util_.obj crc32_.obj globals.obj
OBJU = $(OBJU1) $(OBJUS)
OBJN = zipnote.obj $(OBJU)
OBJS = zipsplit.obj $(OBJU)
-OBJK = zipcloak.obj crctab.obj crypt_.obj ttyio.obj
+OBJK = zipcloak.obj crypt_.obj ttyio.obj
OBJC = $(OBJK) $(OBJU)
ZIP_H = zip.h ziperr.h tailor.h win32/osdep.h
@@ -63,17 +63,16 @@ ZIP_H = zip.h ziperr.h tailor.h win32/osdep.h
all: zip.exe zipnote.exe zipsplit.exe zipcloak.exe
-zip.obj: zip.c $(ZIP_H) revision.h crypt.h ttyio.h
-zipfile.obj: zipfile.c $(ZIP_H)
-zipup.obj: zipup.c $(ZIP_H) revision.h crypt.h win32/zipup.h
-fileio.obj: fileio.c $(ZIP_H)
+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 win32/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)
-crctab.obj: crctab.c $(ZIP_H)
-crypt.obj: crypt.c $(ZIP_H) crypt.h ttyio.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
win32.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
@@ -91,19 +90,22 @@ crc_lcc.obj: win32/crc_lcc.asm
lm32_lcc.obj: win32/lm32_lcc.asm
$(AS) $(ASFLAGS) -Fo$@ win32/lm32_lcc.asm
-zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
+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)
+zipfile_.obj: zipfile.c $(ZIP_H) crc32.h
$(CC) $(CFLAGS) -DUTIL -Fo$@ zipfile.c
-fileio_.obj: fileio.c $(ZIP_H)
+fileio_.obj: fileio.c $(ZIP_H) crc32.h
$(CC) $(CFLAGS) -DUTIL -Fo$@ fileio.c
util_.obj: util.c $(ZIP_H)
$(CC) $(CFLAGS) -DUTIL -Fo$@ util.c
+crc32_.obj: crc32.c $(ZIP_H) crc32.h
+ $(CC) $(CFLAGS) -DUTIL -Fo$@ crc32.c
+
crypt_.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
$(CC) $(CFLAGS) -DUTIL -Fo$@ crypt.c
diff --git a/win32/makefile.w10 b/win32/makefile.w10
index b5244fc..0463f3b 100644
--- a/win32/makefile.w10
+++ b/win32/makefile.w10
@@ -1,5 +1,5 @@
# WMAKE makefile for Windows 95 and Windows NT (Intel only)
-# using Watcom C/C++ v10.5+, by Paul Kienitz, last revised 22 Feb 05.
+# using Watcom C/C++ v10.5+, by Paul Kienitz, last revised 22 Jun 2008.
# Makes Zip.exe, ZipNote.exe, ZipCloak.exe, and ZipSplit.exe.
#
# Invoke from Zip source dir with "WMAKE -F WIN32\MAKEFILE.WAT [targets]"
@@ -35,12 +35,14 @@ O = $(OBDIR)\ # comment here so backslash won't continue the line
# This section controls its usage.
!ifdef NOASM
-asmob = $(O)crc32.obj # C source
+asmob =
+asmco =
cvars = $+$(cvars)$- -DNO_ASM # otherwise 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)match32.obj $(O)crc_i386.obj
+asmco = $(O)crc_i386.obj
+asmob = $(asmco) $(O)match32.obj
cvars = $+$(cvars)$- -DASMV -DASM_CRC
!endif
@@ -49,13 +51,13 @@ cvars = $+$(cvars)$- -DASMV -DASM_CRC
OBJZ3 = $(O)zip.obj $(O)crypt.obj $(O)ttyio.obj $(O)trees.obj $(O)zipup.obj
OBJZ2 = $(OBJZ3) $(O)util.obj $(O)zipfile.obj $(O)fileio.obj $(O)deflate.obj
-OBJZ1 = $(OBJZ2) $(O)globals.obj $(O)crctab.obj $(asmob)
-OBJZ = $(OBJZ1) $(O)win32zip.obj $(O)win32.obj $(O)nt.obj
+OBJZ1 = $(OBJZ2) $(O)globals.obj $(O)crc32.obj $(asmob)
+OBJZ = $(OBJZ1) $(O)win32zip.obj $(O)win32.obj $(O)win32i64.obj $(O)nt.obj
-OBJU1 = $(O)zipfile_.obj $(O)fileio_.obj $(O)util_.obj $(O)globals.obj
-OBJ_U = $(OBJU1) $(O)win32_.obj
+OBJU1 = $(O)zipfile_.obj $(O)fileio_.obj $(O)util_.obj $(O)crc32_.obj $(asmco)
+OBJ_U = $(OBJU1) $(O)globals.obj $(O)win32_.obj $(O)win32i64_.obj
-OBJC = $(O)zipcloak.obj $(O)crctab.obj $(O)crypt_.obj $(O)ttyio.obj $(OBJ_U)
+OBJC = $(O)zipcloak.obj $(O)crypt_.obj $(O)ttyio.obj $(OBJ_U)
OBJN = $(O)zipnote.obj $(OBJ_U)
@@ -70,9 +72,11 @@ ZIP_H = zip.h ziperr.h tailor.h win32\osdep.h
cc = wcc386
link = wlink
asm = wasm
-# Use Pentium timings, register args, static strings in code:
-cflags = -bt=NT -5r -zt -zq
+rc = wrc
+# Use Pentium Pro timings, register args, static strings in code:
+cflags = -bt=NT -6r -zt -zq
aflags = -bt=NT -mf -3 -zq
+rcflags= -bt=NT -DWIN32 -iwin32 -q
lflags = sys NT
cvars = $+$(cvars)$- -DWIN32 $(variation)
avars = $+$(avars)$- $(variation)
@@ -101,8 +105,9 @@ n: ZipNote.exe .SYMBOLIC
c: ZipCloak.exe .SYMBOLIC
s: ZipSplit.exe .SYMBOLIC
-Zip.exe: $(OBDIR) $(OBJZ)
- $(link) $(lflags) $(ldebug) name $@ file {$(OBJZ)}
+Zip.exe: $(OBDIR) $(OBJZ) $(O)zip.res
+ $(link) $(lflags) $(ldebug) name $@ file {$(OBJZ)}
+ $(rc) $(O)zip.res $@
ZipNote.exe: $(OBDIR) $(OBJN)
$(link) $(lflags) $(ldebug) name $@ file {$(OBJN)}
@@ -115,20 +120,19 @@ ZipSplit.exe: $(OBDIR) $(OBJS)
# Source dependencies:
-$(O)crctab.obj: crctab.c $(ZIP_H)
-$(O)crc32.obj: crc32.c $(ZIP_H) # only used if NOASM
-$(O)crypt.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+$(O)crc32.obj: crc32.c $(ZIP_H) crc32.h # only used if NOASM
+$(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)
+$(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) crypt.h revision.h ttyio.h
-$(O)zipfile.obj: zipfile.c $(ZIP_H)
-$(O)zipup.obj: zipup.c $(ZIP_H) revision.h crypt.h win32\zipup.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 win32\zipup.h
$(O)zipnote.obj: zipnote.c $(ZIP_H) revision.h
-$(O)zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.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:
@@ -136,6 +140,9 @@ $(O)zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
$(O)win32.obj: win32\win32.c $(ZIP_H) win32\win32zip.h
$(cc) $(cdebug) $(cflags) $(cvars) win32\win32.c -fo=$@
+$(O)win32i64.obj: win32\win32i64.c $(ZIP_H)
+ $(cc) $(cdebug) $(cflags) $(cvars) win32\win32i64.c -fo=$@
+
$(O)win32zip.obj: win32\win32zip.c $(ZIP_H) win32\win32zip.h win32\nt.h
$(cc) $(cdebug) $(cflags) $(cvars) win32\win32zip.c -fo=$@
@@ -150,21 +157,30 @@ $(O)crc_i386.obj: win32\crc_i386.asm
# Variant object files for ZipNote, ZipCloak, and ZipSplit:
-$(O)zipfile_.obj: zipfile.c $(ZIP_H)
+$(O)zipfile_.obj: zipfile.c $(ZIP_H) crc32.h
$(cc) $(cdebug) $(cflags) $(cvars) -DUTIL zipfile.c -fo=$@
-$(O)fileio_.obj: fileio.c $(ZIP_H)
+$(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)crypt_.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+$(O)crc32_.obj: crc32.c $(ZIP_H) crc32.h
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL crc32.c -fo=$@
+
+$(O)crypt_.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
$(cc) $(cdebug) $(cflags) $(cvars) -DUTIL crypt.c -fo=$@
$(O)win32_.obj: win32\win32.c $(ZIP_H) win32\win32zip.h
$(cc) $(cdebug) $(cflags) $(cvars) -DUTIL win32\win32.c -fo=$@
+$(O)win32i64_.obj: win32\win32i64.c $(ZIP_H)
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL win32\win32i64.c -fo=$@
+
+$(O)zip.res: win32\zip.rc revision.h
+ $(rc) -r $(rcflags) -fo=$@ win32\zip.rc
+
# Creation of subdirectory for intermediate files
$(OBDIR):
-mkdir $@
diff --git a/win32/makefile.w32 b/win32/makefile.w32
index 538a614..7afbf0e 100644
--- a/win32/makefile.w32
+++ b/win32/makefile.w32
@@ -3,21 +3,81 @@
# To use, do "nmake -f makefile.w32"
-# Add -DNO_ASM to CFLAGS and comment out the ASMOBJS definition if
-# you do not have masm 6.1X.
+# Add "NOASM=1" to the nmake command to disable usage of assembler sources
+# if you do not have masm 6.1X.
# 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 = $(LOCAL_ZIP)
-# To avoid using the optimized assembler routines in Zip, comment
-# out the ASMOBJS macro below, and add -DNO_ASM to LOC above.
-ASMOBJS = match32.obj crc_i386.obj
+!IFNDEF debug
+NODEBUG=1
+!ENDIF
+
+# Uncomment the following macro to use the optimized assembler
+# routines in Zip:
+!IFDEF NOASM
+ASMOBJS =
+CRCA_O =
+CFLG_ASM = -DNO_ASM
+!ELSE
+ASMOBJS = match32.obj
+CRCA_O = crci386c.obj
+CFLG_ASM = -DASM_CRC
+!ENDIF
+
+!IFDEF USEBZ2
+LOC=$(LOC) -DBZIP2_SUPPORT
+!IFNDEF debug
+EXTLIB=$(EXTLIB) libbz2.lib
+!ELSE
+EXTLIB=$(EXTLIB) libbz2.lib
+!ENDIF
+!ENDIF
+
+!IFDEF USEZLIB
+LOC=$(LOC) -DUSE_ZLIB
+ASMOBJS=
+!IFNDEF debug
+EXTLIB=$(EXTLIB) zlib.lib
+!ELSE
+EXTLIB=$(EXTLIB) zlib.lib
+!ENDIF
+!ENDIF
+
+!IFDEF USEZLIB
+USE_MSVCRT=1
+!ELSE
+!IFDEF USEBZIP2
+USE_MSVCRT=1
+!ELSE
+USE_MSVCRT=0
+!ENDIF
+!ENDIF # USEZLIB
+
+!IF $(USE_MSVCRT) == 1
+CRTLIB=-MD
+!ELSE
+!IF "$(VS80COMNTOOLS)" == ""
+CRTLIB=-ML
+!ELSE
+# no single-threaded CRT static lib, only multi-threaded in VC8
+CRTLIB=-MT
+!ENDIF
+!ENDIF
+
+!IFDEF NODEBUG
+cdebug = -O2
+cdbgsz = -O1
+!ELSE
+cdebug = -Od
+cdbgsz = $(cdebug)
+!ENDIF
# ------------- 32-bit Microsoft Visual C++ -------------
CC=cl -nologo
-CFLAGS=-W3 -O2 -DWIN32 $(LOC)
+CFLAGS=-W3 $(cdebug) -DWIN32 $(CFLG_ASM) $(CRTLIB) $(LOC)
UTILFLAGS=$(CFLAGS) -DUTIL -Fo$@
# Remove "-coff" from ASFLAGS if you do not have MASM 6.11.
@@ -25,123 +85,140 @@ UTILFLAGS=$(CFLAGS) -DUTIL -Fo$@
AS=ml -nologo
ASFLAGS=-c -coff -Cx
+RC=rc
+
# If you build 16-bit executables with MS Visual C++ v1.0/1.5 and link them
# with the /KNOWEAS switch, you can build dual-mode MS-DOS/Win32 executables
# by passing the -stub switch to the 32-bit linker to specify the 16-bit part.
LD=link -nologo
-#LDFLAGS=-stub:zipdos.exe
-LDFLAGS=
+LDFLAGS=user32.lib advapi32.lib /OPT:NOWIN98 /INCREMENTAL:NO /PDB:$*.pdb $(EXTLIB)
+SYMS=/DEBUG:full /DEBUGTYPE:CV
+!IFDEF debug
+LDFLAGS=$(LDFLAGS) $(SYMS)
+CFLAGS=$(CFLAGS) /Zi
+!ELSE
+LDFLAGS=$(LDFLAGS) /RELEASE
+!IFDEF sym
+LDFLAGS=$(LDFLAGS) $(SYMS)
+CFLAGS=$(CFLAGS) /Zi
+!ENDIF
+!ENDIF
# variables
OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \
- crc32.obj crctab.obj globals.obj
+ crc32.obj $(CRCA_O) globals.obj
-OBJI = deflate.obj trees.obj $(ASMOBJS) win32.obj win32zip.obj nt.obj
+OBJI = deflate.obj trees.obj $(ASMOBJS) win32.obj win32zip.obj nt.obj win32i64.obj
-OBJU = zipfile_.obj fileio_.obj util_.obj globals.obj win32_.obj
+OBJU = zipfile_.obj fileio_.obj util_.obj crc32_.obj $(CRCA_O) globals.obj \
+ win32_.obj win32i64.obj
OBJN = zipnote.obj $(OBJU)
-OBJC = zipcloak.obj crctab.obj crypt_.obj ttyio.obj $(OBJU)
+OBJC = zipcloak.obj crypt_.obj ttyio.obj $(OBJU)
OBJS = zipsplit.obj $(OBJU)
ZIP_H = zip.h ziperr.h tailor.h win32/osdep.h
-LIBS = advapi32.lib
-
ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe
zips: $(ZIPS)
-zip.obj: zip.c $(ZIP_H) revision.h crypt.h ttyio.h
- $(CC) -c $(CFLAGS) $*.c
+zip.obj: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h
+ $(CC) -c $(CFLAGS) $*.c
-zipfile.obj: zipfile.c $(ZIP_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 crypt.h win32/zipup.h
- $(CC) -c $(CFLAGS) $*.c
+zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h win32/zipup.h
+ $(CC) -c $(CFLAGS) $*.c
-fileio.obj: fileio.c $(ZIP_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
+ $(CC) -c $(CFLAGS) $*.c
globals.obj: globals.c $(ZIP_H)
- $(CC) -c $(CFLAGS) $*.c
+ $(CC) -c $(CFLAGS) $*.c
deflate.obj: deflate.c $(ZIP_H)
- $(CC) -c $(CFLAGS) $*.c
+ $(CC) -c $(CFLAGS) $*.c
trees.obj: trees.c $(ZIP_H)
- $(CC) -c $(CFLAGS) $*.c
-
-crc32.obj: crc32.c $(ZIP_H)
- $(CC) -c $(CFLAGS) $*.c
+ $(CC) -c $(CFLAGS) $*.c
-crctab.obj: crctab.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 ttyio.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
+ $(CC) -c $(CFLAGS) $*.c
+
+win32i64.obj: win32/win32i64.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) -I. win32/win32i64.c
win32zip.obj: win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h
- $(CC) -c $(CFLAGS) -I. win32/win32zip.c
+ $(CC) -c $(CFLAGS) -I. win32/win32zip.c
win32.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
- $(CC) -c $(CFLAGS) -I. win32/win32.c
+ $(CC) -c $(CFLAGS) -I. win32/win32.c
nt.obj: win32/nt.c $(ZIP_H) win32/nt.h
- $(CC) -c $(CFLAGS) -I. win32/nt.c
+ $(CC) -c $(CFLAGS) -I. win32/nt.c
-zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.h
- $(CC) -c $(CFLAGS) $*.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
+ $(CC) -c $(CFLAGS) $*.c
zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
- $(CC) -c $(CFLAGS) $*.c
+ $(CC) -c $(CFLAGS) $*.c
-zipfile_.obj: zipfile.c $(ZIP_H)
- $(CC) -c $(UTILFLAGS) zipfile.c
+zipfile_.obj: zipfile.c $(ZIP_H) crc32.h
+ $(CC) -c $(UTILFLAGS) zipfile.c
-fileio_.obj: fileio.c $(ZIP_H)
- $(CC) -c $(UTILFLAGS) fileio.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
+ $(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 ttyio.h
- $(CC) -c $(UTILFLAGS) crypt.c
+crypt_.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
+ $(CC) -c $(UTILFLAGS) crypt.c
win32_.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
- $(CC) -c $(UTILFLAGS) -I. win32/win32.c
-
-crci386c.obj: win32/crc_i386.c $(ZIP_H)
- $(CC) -c $(CFLAGS) -I. -Fo$@ win32/crc_i386.c
-
-crc_i386.obj: win32/crc_i386.c $(ZIP_H)
- $(AS) $(ASFLAGS) win32\crc_i386.asm
-
+ $(CC) -c $(UTILFLAGS) -I. win32/win32.c
+
+crci386c.obj: win32/crc_i386.c $(ZIP_H) crc32.h
+ $(CC) -c $(CFLAGS) -I. -Fo$@ win32/crc_i386.c
+
+crc_i386.obj: win32/crc_i386.asm
+ $(AS) $(ASFLAGS) win32\crc_i386.asm
+
match32.obj: win32/match32.asm
- $(AS) $(ASFLAGS) win32\match32.asm
+ $(AS) $(ASFLAGS) win32\match32.asm
+
+zip.res: win32/zip.rc revision.h
+ $(RC) /l 0x409 /fo$@ /i win32 /d WIN32 win32/zip.rc
-zip.exe: $(OBJZ) $(OBJI)
- $(LD) $(LDFLAGS) $(OBJZ) $(OBJI) $(LIBS)
+zip.exe: $(OBJZ) $(OBJI) zip.res
+ $(LD) $(LDFLAGS) $(OBJZ) $(OBJI) zip.res
zipcloak.exe: $(OBJC)
- $(LD) $(LDFLAGS) $(OBJC) $(LIBS)
+ $(LD) $(LDFLAGS) $(OBJC)
zipnote.exe: $(OBJN)
- $(LD) $(LDFLAGS) $(OBJN) $(LIBS)
+ $(LD) $(LDFLAGS) $(OBJN)
zipsplit.exe: $(OBJS)
- $(LD) $(LDFLAGS) $(OBJS) $(LIBS)
+ $(LD) $(LDFLAGS) $(OBJS)
clean:
- del *.obj
- del *.exe
+ -del *.obj
+ -del *.exe
diff --git a/win32/makefile.wat b/win32/makefile.wat
index 93b41e0..f13d580 100644
--- a/win32/makefile.wat
+++ b/win32/makefile.wat
@@ -1,5 +1,5 @@
# WMAKE makefile for Windows 95 and Windows NT (Intel only)
-# using Watcom C/C++ v11.0+, by Paul Kienitz, last revised 22 Feb 05.
+# using Watcom C/C++ v11.0+, by Paul Kienitz, last revised 22 Jun 2008.
# Makes Zip.exe, ZipNote.exe, ZipCloak.exe, and ZipSplit.exe.
#
# Invoke from Zip source dir with "WMAKE -F WIN32\MAKEFILE.WAT [targets]"
@@ -35,12 +35,14 @@ O = $(OBDIR)\ # comment here so backslash won't continue the line
# This section controls its usage.
!ifdef NOASM
-asmob = $(O)crc32.obj # C source
+asmob =
+asmco =
cvars = $+$(cvars)$- -DNO_ASM # otherwise 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)match32.obj $(O)crc_i386.obj
+asmco = $(O)crc_i386.obj
+asmob = $(asmco) $(O)match32.obj
cvars = $+$(cvars)$- -DASMV -DASM_CRC
!endif
@@ -49,13 +51,13 @@ cvars = $+$(cvars)$- -DASMV -DASM_CRC
OBJZ3 = $(O)zip.obj $(O)crypt.obj $(O)ttyio.obj $(O)trees.obj $(O)zipup.obj
OBJZ2 = $(OBJZ3) $(O)util.obj $(O)zipfile.obj $(O)fileio.obj $(O)deflate.obj
-OBJZ1 = $(OBJZ2) $(O)globals.obj $(O)crctab.obj $(asmob)
-OBJZ = $(OBJZ1) $(O)win32zip.obj $(O)win32.obj $(O)nt.obj
+OBJZ1 = $(OBJZ2) $(O)globals.obj $(O)crc32.obj $(asmob)
+OBJZ = $(OBJZ1) $(O)win32zip.obj $(O)win32.obj $(O)win32i64.obj $(O)nt.obj
-OBJU1 = $(O)zipfile_.obj $(O)fileio_.obj $(O)util_.obj $(O)globals.obj
-OBJ_U = $(OBJU1) $(O)win32_.obj
+OBJU1 = $(O)zipfile_.obj $(O)fileio_.obj $(O)util_.obj $(O)crc32_.obj $(asmco)
+OBJ_U = $(OBJU1) $(O)globals.obj $(O)win32_.obj $(O)win32i64_.obj
-OBJC = $(O)zipcloak.obj $(O)crctab.obj $(O)crypt_.obj $(O)ttyio.obj $(OBJ_U)
+OBJC = $(O)zipcloak.obj $(O)crypt_.obj $(O)ttyio.obj $(OBJ_U)
OBJN = $(O)zipnote.obj $(OBJ_U)
@@ -70,12 +72,14 @@ ZIP_H = zip.h ziperr.h tailor.h win32\osdep.h
cc = wcc386
link = wlink
asm = wasm
+rc = wrc
# Use Pentium Pro timings, register args, static strings in code:
cflags = -bt=NT -6r -zt -zq
aflags = -bt=NT -mf -3 -zq
+rcflags= -bt=NT -DWIN32 -iwin32 -q
lflags = sys NT
cvars = $+$(cvars)$- -DWIN32 $(variation)
-avars = $+$(avars)$- $(variation)
+avars = $+$(avars)$- -DWATCOM_DSEG $(variation)
# Specify optimizations, or a nonoptimized debugging version:
@@ -101,8 +105,9 @@ n: ZipNote.exe .SYMBOLIC
c: ZipCloak.exe .SYMBOLIC
s: ZipSplit.exe .SYMBOLIC
-Zip.exe: $(OBDIR) $(OBJZ)
+Zip.exe: $(OBDIR) $(OBJZ) $(O)zip.res
$(link) $(lflags) $(ldebug) name $@ file {$(OBJZ)}
+ $(rc) $(O)zip.res $@
ZipNote.exe: $(OBDIR) $(OBJN)
$(link) $(lflags) $(ldebug) name $@ file {$(OBJN)}
@@ -115,20 +120,19 @@ ZipSplit.exe: $(OBDIR) $(OBJS)
# Source dependencies:
-$(O)crctab.obj: crctab.c $(ZIP_H)
-$(O)crc32.obj: crc32.c $(ZIP_H) # only used if NOASM
-$(O)crypt.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+$(O)crc32.obj: crc32.c $(ZIP_H) crc32.h # only used if NOASM
+$(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)
+$(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) crypt.h revision.h ttyio.h
-$(O)zipfile.obj: zipfile.c $(ZIP_H)
-$(O)zipup.obj: zipup.c $(ZIP_H) revision.h crypt.h win32\zipup.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 win32\zipup.h
$(O)zipnote.obj: zipnote.c $(ZIP_H) revision.h
-$(O)zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crypt.h ttyio.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:
@@ -136,6 +140,9 @@ $(O)zipsplit.obj: zipsplit.c $(ZIP_H) revision.h
$(O)win32.obj: win32\win32.c $(ZIP_H) win32\win32zip.h
$(cc) $(cdebug) $(cflags) $(cvars) win32\win32.c -fo=$@
+$(O)win32i64.obj: win32\win32i64.c $(ZIP_H)
+ $(cc) $(cdebug) $(cflags) $(cvars) win32\win32i64.c -fo=$@
+
$(O)win32zip.obj: win32\win32zip.c $(ZIP_H) win32\win32zip.h win32\nt.h
$(cc) $(cdebug) $(cflags) $(cvars) win32\win32zip.c -fo=$@
@@ -150,21 +157,30 @@ $(O)crc_i386.obj: win32\crc_i386.asm
# Variant object files for ZipNote, ZipCloak, and ZipSplit:
-$(O)zipfile_.obj: zipfile.c $(ZIP_H)
+$(O)zipfile_.obj: zipfile.c $(ZIP_H) crc32.h
$(cc) $(cdebug) $(cflags) $(cvars) -DUTIL zipfile.c -fo=$@
-$(O)fileio_.obj: fileio.c $(ZIP_H)
+$(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)crypt_.obj: crypt.c $(ZIP_H) crypt.h ttyio.h
+$(O)crc32_.obj: crc32.c $(ZIP_H) crc32.h
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL crc32.c -fo=$@
+
+$(O)crypt_.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h
$(cc) $(cdebug) $(cflags) $(cvars) -DUTIL crypt.c -fo=$@
$(O)win32_.obj: win32\win32.c $(ZIP_H) win32\win32zip.h
$(cc) $(cdebug) $(cflags) $(cvars) -DUTIL win32\win32.c -fo=$@
+$(O)win32i64_.obj: win32\win32i64.c $(ZIP_H)
+ $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL win32\win32i64.c -fo=$@
+
+$(O)zip.res: win32\zip.rc revision.h
+ $(rc) -r $(rcflags) -fo=$@ win32\zip.rc
+
# Creation of subdirectory for intermediate files
$(OBDIR):
-mkdir $@
diff --git a/win32/makenoas.w32 b/win32/makenoas.w32
new file mode 100644
index 0000000..403b087
--- /dev/null
+++ b/win32/makenoas.w32
@@ -0,0 +1,219 @@
+# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for
+# 32-bit Microsoft Visual C++
+
+# To use, do "nmake -f makefile.w32"
+
+# This version disables assembly.
+# Add -DNO_ASM to CFLAGS and comment out the ASMOBJS definition if
+# you do not have masm 6.1X.
+
+# 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 = $(LOCAL_ZIP)
+
+!IFNDEF debug
+NODEBUG=1
+!ENDIF
+
+# Uncomment the following macro to use the optimized assembler
+# routines in Zip:
+#ASMOBJS = match32.obj
+CRCA_O = crci386c.obj
+CFLG_ASM = -DASM_CRC
+
+!IFDEF USEBZ2
+LOC=$(LOC) -DBZIP2_SUPPORT
+!IFNDEF debug
+EXTLIB=$(EXTLIB) libbz2.lib
+!ELSE
+EXTLIB=$(EXTLIB) libbz2.lib
+!ENDIF
+!ENDIF
+
+!IFDEF USEZLIB
+LOC=$(LOC) -DUSE_ZLIB
+ASMOBJS=
+!IFNDEF debug
+EXTLIB=$(EXTLIB) zlib.lib
+!ELSE
+EXTLIB=$(EXTLIB) zlib.lib
+!ENDIF
+!ENDIF
+
+!IFDEF USEZLIB
+USE_MSVCRT=1
+!ELSE
+!IFDEF USEBZIP2
+USE_MSVCRT=1
+!ELSE
+USE_MSVCRT=0
+!ENDIF
+!ENDIF # USEZLIB
+
+!IF $(USE_MSVCRT) == 1
+CRTLIB=-MD
+!ELSE
+!IF "$(VS80COMNTOOLS)" == ""
+CRTLIB=-ML
+!ELSE
+# no single-threaded CRT static lib, only multi-threaded in VC8
+CRTLIB=-MT
+!ENDIF
+!ENDIF
+
+!IFDEF NODEBUG
+cdebug = -O2
+cdbgsz = -O1
+!ELSE
+cdebug = -Od
+cdbgsz = $(cdebug)
+!ENDIF
+
+# ------------- 32-bit Microsoft Visual C++ -------------
+CC=cl -nologo
+CFLAGS=-W3 $(cdebug) -DWIN32 $(CFLG_ASM) $(CRTLIB) $(LOC) -DNO_ASM
+UTILFLAGS=$(CFLAGS) -DUTIL -Fo$@
+
+# Remove "-coff" from ASFLAGS if you do not have MASM 6.11.
+
+AS=ml -nologo
+ASFLAGS=-c -coff -Cx
+
+RC=rc
+
+# If you build 16-bit executables with MS Visual C++ v1.0/1.5 and link them
+# with the /KNOWEAS switch, you can build dual-mode MS-DOS/Win32 executables
+# by passing the -stub switch to the 32-bit linker to specify the 16-bit part.
+
+LD=link -nologo
+LDFLAGS=user32.lib advapi32.lib /OPT:NOWIN98 /INCREMENTAL:NO /PDB:$*.pdb $(EXTLIB)
+SYMS=/DEBUG:full /DEBUGTYPE:CV
+!IFDEF debug
+LDFLAGS=$(LDFLAGS) $(SYMS)
+CFLAGS=$(CFLAGS) /Zi
+!ELSE
+LDFLAGS=$(LDFLAGS) /RELEASE
+!IFDEF sym
+LDFLAGS=$(LDFLAGS) $(SYMS)
+CFLAGS=$(CFLAGS) /Zi
+!ENDIF
+!ENDIF
+
+# variables
+OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \
+ crc32.obj $(CRCA_O) globals.obj
+
+OBJI = deflate.obj trees.obj $(ASMOBJS) win32.obj win32zip.obj nt.obj win32i64.obj
+
+OBJU = zipfile_.obj fileio_.obj util_.obj crc32_.obj $(CRCA_O) globals.obj \
+ win32_.obj win32i64.obj
+OBJN = zipnote.obj $(OBJU)
+OBJC = zipcloak.obj crypt_.obj ttyio.obj $(OBJU)
+OBJS = zipsplit.obj $(OBJU)
+
+ZIP_H = zip.h ziperr.h tailor.h win32/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 win32/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
+
+win32i64.obj: win32/win32i64.c $(ZIP_H)
+ $(CC) -c $(CFLAGS) -I. win32/win32i64.c
+
+win32zip.obj: win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h
+ $(CC) -c $(CFLAGS) -I. win32/win32zip.c
+
+win32.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) -c $(CFLAGS) -I. win32/win32.c
+
+nt.obj: win32/nt.c $(ZIP_H) win32/nt.h
+ $(CC) -c $(CFLAGS) -I. win32/nt.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
+
+win32_.obj: win32/win32.c $(ZIP_H) win32/win32zip.h
+ $(CC) -c $(UTILFLAGS) -I. win32/win32.c
+
+crci386c.obj: win32/crc_i386.c $(ZIP_H) crc32.h
+ $(CC) -c $(CFLAGS) -I. -Fo$@ win32/crc_i386.c
+
+crc_i386.obj: win32/crc_i386.asm
+ $(AS) $(ASFLAGS) win32\crc_i386.asm
+
+match32.obj: win32/match32.asm
+ $(AS) $(ASFLAGS) win32\match32.asm
+
+zip.res: win32/zip.rc revision.h
+ $(RC) /l 0x409 /fo$@ /i win32 /d WIN32 win32/zip.rc
+
+zip.exe: $(OBJZ) $(OBJI) zip.res
+ $(LD) $(LDFLAGS) $(OBJZ) $(OBJI) zip.res
+
+zipcloak.exe: $(OBJC)
+ $(LD) $(LDFLAGS) $(OBJC)
+
+zipnote.exe: $(OBJN)
+ $(LD) $(LDFLAGS) $(OBJN)
+
+zipsplit.exe: $(OBJS)
+ $(LD) $(LDFLAGS) $(OBJS)
+
+clean:
+ -del *.obj
+ -del *.exe
diff --git a/win32/match32.asm b/win32/match32.asm
index 5d4e8b5..81db41f 100644
--- a/win32/match32.asm
+++ b/win32/match32.asm
@@ -1,9 +1,9 @@
;===========================================================================
; Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
;
-; See the accompanying file LICENSE, version 2004-May-22 or later
+; 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
+; 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
;===========================================================================
;
@@ -22,6 +22,10 @@
;
; Adapted to work with Borland Turbo Assembler 5.0 by Cosmin Truta, 1997
;
+; Adapted to work with OpenWatcom WASM by Chr. Spieler, 2005
+; (Define the symbol WATCOM_DSEG to activate the specific Watcom C
+; data segment naming convention.)
+;
;==============================================================================
;
; Do NOT assemble this source if external crc32 routine from zlib gets used.
@@ -52,6 +56,10 @@ _BSS segment public use32 'DATA'
extrn _window : byte
_BSS ends
+ ifdef WATCOM_DSEG
+DGROUP group _BSS
+ endif
+
ifdef ASM_NEW
_TEXT segment public use32
else
diff --git a/win32/nt.c b/win32/nt.c
index 6a757b8..aa0529f 100644
--- a/win32/nt.c
+++ b/win32/nt.c
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ win32/nt.c - Zip 3
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*++
@@ -52,6 +54,12 @@ Author:
# define FILE_SHARE_DELETE 0x00000004
#endif
+/* This macro definition is missing in old versions of MS' winbase.h. */
+#ifndef InterlockedExchangePointer
+# define InterlockedExchangePointer(Target, Value) \
+ (PVOID)InterlockedExchange((PLONG)(Target), (LONG)(Value))
+#endif
+
/* private prototypes */
static BOOL Initialize(VOID);
@@ -96,11 +104,13 @@ static BOOL Initialize(VOID)
hMutex = CreateMutex(NULL, TRUE, NULL);
if(hMutex == NULL) return FALSE;
- hOldMutex = (HANDLE)InterlockedExchange((LPLONG)&hZipInitMutex, (LONG)hMutex);
+ hOldMutex = (HANDLE)InterlockedExchangePointer((void *)&hZipInitMutex,
+ hMutex);
if(hOldMutex != NULL) {
/* somebody setup the mutex already */
- InterlockedExchange((LPLONG)&hZipInitMutex, (LONG)hOldMutex);
+ InterlockedExchangePointer((void *)&hZipInitMutex,
+ hOldMutex);
CloseHandle(hMutex); /* close new, un-needed mutex */
diff --git a/win32/nt.h b/win32/nt.h
index 72b83af..f722530 100644
--- a/win32/nt.h
+++ b/win32/nt.h
@@ -1,7 +1,9 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ win32/nt.h - Zip 3
- See the accompanying file LICENSE, version 2004-May-22 or later
+ Copyright (c) 1990-2003 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2003-May-08 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
diff --git a/win32/osdep.h b/win32/osdep.h
index a867088..eaf6507 100644
--- a/win32/osdep.h
+++ b/win32/osdep.h
@@ -1,11 +1,14 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ win32/osdep.h
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
+
/* Automatic setting of the common Microsoft C idenfifier MSC.
* NOTE: Watcom also defines M_I*86 !
*/
@@ -15,6 +18,18 @@
# endif
#endif
+/* Tell Microsoft Visual C++ 2005 to leave us alone and
+ * let us use standard C functions the way we're supposed to.
+ */
+#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+# ifndef _CRT_SECURE_NO_DEPRECATE
+# define _CRT_SECURE_NO_DEPRECATE
+# endif
+# ifndef _CRT_NONSTDC_NO_DEPRECATE
+# define _CRT_NONSTDC_NO_DEPRECATE
+# endif
+#endif
+
#if defined(__WATCOMC__) && defined(__386__)
# define WATCOMC_386
#endif
@@ -31,6 +46,11 @@
# undef _MBCS
#endif
+/* Get types and stat */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <io.h>
+
#ifndef MSDOS
/*
* Windows 95 (and Windows NT) file systems are (to some extend)
@@ -45,12 +65,203 @@
#define USE_CASE_MAP
#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \
- procname(n, 1))
+ procname(n, filter_match_case))
#define BROKEN_FSEEK
#ifndef __RSXNT__
# define HAVE_FSEEKABLE
#endif
+
+/* popen
+ *
+ * On Win32 must map to _popen() and _pclose()
+ */
+#define popen _popen
+#define pclose _pclose
+
+/* WIN32_OEM
+ *
+ * This enables storing paths in archives on WIN32 in OEM format
+ * which is more work but seems the standard now. It also enables
+ * converting paths in read DOS archives from assumed OEM to ANSI.
+ */
+#ifndef NO_WIN32_OEM
+# define WIN32_OEM
+#endif
+
+/* Large File Support
+ *
+ * If this is set it is assumed that the port
+ * supports 64-bit file calls. The types are
+ * defined here. Any local implementations are
+ * in Win32.c and the prototypes for the calls are
+ * in tailor.h. Note that a port must support
+ * these calls fully or should not set
+ * LARGE_FILE_SUPPORT.
+ */
+
+/* Note also that ZOFF_T_FORMAT_SIZE_PREFIX has to be defined here
+ or tailor.h will define defaults */
+
+/* If port has LARGE_FILE_SUPPORT then define here
+ to make large file support automatic unless overridden */
+
+
+#ifndef LARGE_FILE_SUPPORT
+# ifndef NO_LARGE_FILE_SUPPORT
+ /* MS C and VC */
+# if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)
+# define LARGE_FILE_SUPPORT
+# endif
+# if defined(__WATCOMC__)
+# define LARGE_FILE_SUPPORT
+# endif
+# endif
+#endif
+
+#ifdef LARGE_FILE_SUPPORT
+ /* 64-bit Large File Support */
+
+ /* Only types and the printf format stuff go here. Functions
+ go in tailor.h since ANSI prototypes are required and the OF define
+ is not defined here. */
+
+# if (defined(_MSC_VER) && (_MSC_VER >= 1100)) || defined(__MINGW32__)
+ /* MS C and VC, MinGW32 */
+ /* these compiler systems use the Microsoft C RTL */
+
+ /* base types for file offsets and file sizes */
+ typedef __int64 zoff_t;
+ typedef unsigned __int64 uzoff_t;
+
+ /* 64-bit stat struct */
+ typedef struct _stati64 z_stat;
+
+ /* printf format size prefix for zoff_t values */
+# define ZOFF_T_FORMAT_SIZE_PREFIX "I64"
+
+# elif (defined(__GNUC__) || defined(ULONG_LONG_MAX))
+ /* GNU C */
+
+ /* base types for file offsets and file sizes */
+ typedef long long zoff_t;
+ typedef unsigned long long uzoff_t;
+
+# ifdef __CYGWIN__
+ /* Use Cygwin's own stat struct */
+ typedef struct stat z_stat;
+# else
+ /* 64-bit stat struct */
+ typedef struct _stati64 z_stat;
+# endif
+
+ /* printf format size prefix for zoff_t values */
+# define ZOFF_T_FORMAT_SIZE_PREFIX "ll"
+
+# elif (defined(__WATCOMC__) && (__WATCOMC__ >= 1100))
+ /* WATCOM C */
+
+ /* base types for file offsets and file sizes */
+ typedef __int64 zoff_t;
+ typedef unsigned __int64 uzoff_t;
+
+ /* 64-bit stat struct */
+ typedef struct _stati64 z_stat;
+
+ /* printf format size prefix for zoff_t values */
+# define ZOFF_T_FORMAT_SIZE_PREFIX "ll"
+
+# elif (defined(__IBMC__) && (__IBMC__ >= 350))
+ /* IBM C */
+
+ /* base types for file offsets and file sizes */
+ typedef __int64 zoff_t;
+ typedef unsigned __int64 uzoff_t;
+
+ /* 64-bit stat struct */
+
+ /* printf format size prefix for zoff_t values */
+# define ZOFF_T_FORMAT_SIZE_PREFIX "I64"
+
+# else
+# undef LARGE_FILE_SUPPORT
+# endif
+
+#endif
+
+#if 0
+# ifndef ZOFF_T_FORMAT_SIZE_PREFIX
+ /* unsupported WIN32 */
+
+ /* base types for file offsets and file sizes */
+ typedef long long zoff_t;
+ typedef unsigned long long uzoff_t;
+
+ /* 64-bit stat struct */
+ typedef struct stat z_stat;
+
+ /* printf format size prefix for zoff_t values */
+# define ZOFF_T_FORMAT_SIZE_PREFIX "ll"
+# endif
+#endif
+
+
+/* Automatically set ZIP64_SUPPORT if supported */
+
+/* MS C and VC */
+#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__WATCOMC__)
+# ifdef LARGE_FILE_SUPPORT
+# ifndef NO_ZIP64_SUPPORT
+# ifndef ZIP64_SUPPORT
+# define ZIP64_SUPPORT
+# endif
+# endif
+# endif
+#endif
+
+
+#ifndef LARGE_FILE_SUPPORT
+ /* No Large File Support */
+
+ /* base type for file offsets and file sizes */
+ typedef long zoff_t;
+ typedef unsigned long uzoff_t;
+
+ /* stat struct */
+ typedef struct stat z_stat;
+
+ /* printf format size prefix for zoff_t values */
+# define ZOFF_T_FORMAT_SIZE_PREFIX "l"
+#endif
+
+
+ /* UNICODE */
+#ifdef WIN32
+ /* assume wide character conversion functions */
+# ifndef UNICODE_SUPPORT
+# ifndef NO_UNICODE_SUPPORT
+# define UNICODE_SUPPORT
+# endif
+# endif
+#endif
+
+#if 0
+ /* this is now generic */
+# ifdef UNICODE_SUPPORT
+ /* Set up Unicode support - 9/27/05 EG */
+
+ /* type of wide string characters */
+# define zchar wchar_t
+
+ /* default char string used if a wide char can't be converted */
+# define zchar_default "_"
+
+# else
+# define zchar char
+# endif
+#endif
+
+
/* File operations--use "b" for binary if allowed or fixed length 512 on VMS
* use "S" for sequential access on NT to prevent the NT
* file cache eating up memory with large .zip files
@@ -107,6 +318,30 @@
# define NO_UNISTD_H
#endif
+/* Microsoft C requires additional attributes attached to all RTL function
+ * declarations when linking against the CRTL dll.
+ */
+#ifdef MSC
+# ifdef IZ_IMP
+# undef IZ_IMP
+# endif
+# define IZ_IMP _CRTIMP
+#else
+# ifndef IZ_IMP
+# define IZ_IMP
+# endif
+#endif
+
+/* WIN32 runs solely on little-endian processors; enable support
+ * for the 32-bit optimized CRC-32 C code by default.
+ */
+#ifdef IZ_CRC_BE_OPTIMIZ
+# undef IZ_CRC_BE_OPTIMIZ
+#endif
+#if !defined(IZ_CRC_LE_OPTIMIZ) && !defined(NO_CRC_OPTIMIZ)
+# define IZ_CRC_LE_OPTIMIZ
+#endif
+
/* the following definitions are considered as "obsolete" by Microsoft and
* might be missing in some versions of <windows.h>
*/
@@ -117,14 +352,91 @@
# define OemToAnsi OemToCharA
#endif
+/* handlers for OEM <--> ANSI string conversions */
+#if defined(__RSXNT__) || defined(WIN32_CRT_OEM)
+ /* RSXNT uses OEM coded strings in functions supplied by C RTL */
+# ifdef CRTL_CP_IS_ISO
+# undef CRTL_CP_IS_ISO
+# endif
+# ifndef CRTL_CP_IS_OEM
+# define CRTL_CP_IS_OEM
+# endif
+#else
+ /* "real" native WIN32 compilers use ANSI coded strings in C RTL calls */
+# ifndef CRTL_CP_IS_ISO
+# define CRTL_CP_IS_ISO
+# endif
+# ifdef CRTL_CP_IS_OEM
+# undef CRTL_CP_IS_OEM
+# endif
+#endif
+
+#ifdef CRTL_CP_IS_ISO
+ /* C RTL's file system support assumes ANSI coded strings */
+# define ISO_TO_INTERN(src, dst) {if ((src) != (dst)) strcpy((dst), (src));}
+# define OEM_TO_INTERN(src, dst) OemToAnsi(src, dst)
+# define INTERN_TO_ISO(src, dst) {if ((src) != (dst)) strcpy((dst), (src));}
+# define INTERN_TO_OEM(src, dst) AnsiToOem(src, dst)
+# define _OEM_INTERN(str1) OEM_TO_INTERN(str1, str1)
+# define _ISO_INTERN(str1) {;}
+# define _INTERN_OEM(str1) INTERN_TO_OEM(str1, str1)
+# define _INTERN_ISO(str1) {;}
+#endif /* CRTL_CP_IS_ISO */
+#ifdef CRTL_CP_IS_OEM
+ /* C RTL's file system support assumes OEM coded strings */
+# define ISO_TO_INTERN(src, dst) AnsiToOem(src, dst)
+# define OEM_TO_INTERN(src, dst) {if ((src) != (dst)) strcpy((dst), (src));}
+# define INTERN_TO_ISO(src, dst) OemToAnsi(src, dst)
+# define INTERN_TO_OEM(src, dst) {if ((src) != (dst)) strcpy((dst), (src));}
+# define _OEM_INTERN(str1) {;}
+# define _ISO_INTERN(str1) ISO_TO_INTERN(str1, str1)
+# define _INTERN_OEM(str1) {;}
+# define _INTERN_ISO(str1) INTERN_TO_ISO(str1, str1)
+#endif /* CRTL_CP_IS_OEM */
+
+/* The following "OEM vs. ISO Zip entry names" code has been copied from UnZip.
+ * It should be applicable to the generic Zip code. However, currently only
+ * the Win32 port of Zip supplies the required charset conversion functions.
+ * (The Win32 port uses conversion functions supplied by the OS.)
+ */
+/* Convert filename (and file comment string) into "internal" charset.
+ * This macro assumes that Zip entry filenames are coded in OEM (IBM DOS)
+ * codepage when made on
+ * -> DOS (this includes 16-bit Windows 3.1) (FS_FAT_)
+ * -> OS/2 (FS_HPFS_)
+ * -> Win95/WinNT with Nico Mak's WinZip (FS_NTFS_ && hostver == "5.0")
+ * EXCEPTIONS:
+ * PKZIP for Windows 2.5, 2.6, and 4.0 flag their entries as "FS_FAT_", but
+ * the filename stored in the local header is coded in Windows ANSI (CP 1252
+ * resp. ISO 8859-1 on US and western Europe locale settings).
+ * Likewise, PKZIP for UNIX 2.51 flags its entries as "FS_FAT_", but the
+ * filenames stored in BOTH the local and the central header are coded
+ * in the local system's codepage (usually ANSI codings like ISO 8859-1,
+ * but could also be UTF-8 on "modern" setups...).
+ *
+ * All other ports are assumed to code zip entry filenames in ISO (8859-1
+ * on "Western" localisations).
+ */
+#define FS_FAT_ 0 /* filesystem used by MS-DOS, OS/2, Win32 */
+#define FS_HPFS_ 6 /* filesystem used by OS/2 (and NT 3.x) */
+#define FS_NTFS_ 11 /* filesystem used by Windows NT */
+#ifndef Ext_ASCII_TO_Native
+# define Ext_ASCII_TO_Native(string, hostnum, hostver, isuxatt, islochdr) \
+ if (((hostnum) == FS_FAT_ && \
+ !(((islochdr) || (isuxatt)) && \
+ ((hostver) == 25 || (hostver) == 26 || (hostver) == 40))) || \
+ (hostnum) == FS_HPFS_ || \
+ ((hostnum) == FS_NTFS_ && (hostver) == 50)) { \
+ _OEM_INTERN((string)); \
+ } else { \
+ _ISO_INTERN((string)); \
+ }
+#endif
+
#if (defined(__RSXNT__) && defined(__CRTRSXNT__))
# include <crtrsxnt.h>
#endif
-/* Get types and stat */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <io.h>
#ifdef _MBCS
# if (!defined(__EMX__) && !defined(__MINGW32__) && !defined(__CYGWIN__))
# include <stdlib.h>
@@ -132,15 +444,15 @@
# endif
# if (defined(__MINGW32__) && !defined(MB_CUR_MAX))
# ifdef __MSVCRT__
- extern int *__p___mb_cur_max(void);
+ IZ_IMP extern int *__p___mb_cur_max(void);
# define MB_CUR_MAX (*__p___mb_cur_max())
# else
- extern int *_imp____mb_cur_max_dll;
+ IZ_IMP extern int *_imp____mb_cur_max_dll;
# define MB_CUR_MAX (*_imp____mb_cur_max_dll)
# endif
# endif
# if (defined(__LCC__) && !defined(MB_CUR_MAX))
- extern int *_imp____mb_cur_max;
+ IZ_IMP extern int *_imp____mb_cur_max;
# define MB_CUR_MAX (*_imp____mb_cur_max)
# endif
#endif
@@ -155,7 +467,7 @@
# endif
#endif
#ifdef __MINGW32__
- extern void _tzset(void); /* this is missing in <time.h> */
+ IZ_IMP extern void _tzset(void); /* this is missing in <time.h> */
# ifndef tzset
# define tzset _tzset
# endif
@@ -193,6 +505,11 @@
# undef MATCH
#endif
#define MATCH dosmatch /* use DOS style wildcard matching */
+#ifdef UNICODE_SUPPORT
+# ifdef WIN32
+# define MATCHW dosmatchw
+# endif
+#endif
#ifdef ZCRYPT_INTERNAL
# ifdef WINDLL
@@ -213,7 +530,8 @@
* from the registry.
*/
#ifdef USE_EF_UT_TIME
-# if (defined(__WATCOMC__) || defined(W32_USE_IZ_TIMEZONE))
+# if (defined(__WATCOMC__) || defined(__CYGWIN__) || \
+ defined(W32_USE_IZ_TIMEZONE))
# define iz_w32_prepareTZenv()
# else
# define iz_w32_prepareTZenv() putenv("TZ=")
@@ -231,11 +549,25 @@
#if (defined(NT_TZBUG_WORKAROUND) || defined(W32_STATROOT_FIX))
# define W32_STAT_BANDAID
+# ifdef LARGE_FILE_SUPPORT /* E. Gordon 9/12/03 */
+ int zstat_zipwin32(const char *path, z_stat *buf);
+# else
int zstat_zipwin32(const char *path, struct stat *buf);
+# endif
+# ifdef UNICODE_SUPPORT
+# ifdef LARGE_FILE_SUPPORT
+ int zstat_zipwin32w(const wchar_t *pathw, struct _stati64 *buf);
+# else
+ int zstat_zipwin32w(const wchar_t *pathw, struct _stat *buf);
+# endif
+# endif
# ifdef SSTAT
# undef SSTAT
# endif
# define SSTAT zstat_zipwin32
+# ifdef UNICODE_SUPPORT
+# define SSTATW zstat_zipwin32w
+# endif
#endif /* NT_TZBUG_WORKAROUND || W32_STATROOT_FIX */
int getch_win32(void);
@@ -268,4 +600,18 @@ int getch_win32(void);
modify [eax ecx edx]
# endif /* ASM_CRC && !USE_ZLIB */
# endif /* __386__ */
+ /* Watcom C (like the other Win32 C compiler systems) does not support
+ * symlinks on Win32, but defines the S_IFLNK symbol nevertheless.
+ * However, the existence of this symbol is used as "symlinks supported"
+ * indicator in the generic Zip code (see tailor.h). So, for a simple
+ * work-around, this symbol is undefined here. */
+# ifdef S_IFLNK
+# undef S_IFLNK
+# endif
+# ifdef UNICODE_SUPPORT
+ /* Watcom C does not supply wide-char definitions in the "standard"
+ * headers like MSC; so we have to pull in a wchar-specific header.
+ */
+# include <wchar.h>
+# endif
#endif /* __WATCOMC__ */
diff --git a/win32/rsxntwin.h b/win32/rsxntwin.h
index 3df30e8..a710a35 100644
--- a/win32/rsxntwin.h
+++ b/win32/rsxntwin.h
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ win32/rsxntwin.h - Zip 3
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/* rsxntwin.h
@@ -162,5 +164,10 @@ VOID WINAPI InitializeCriticalSection();
#endif
#endif /* TFUNCT */
+
+#ifndef CP_UTF8
+# define CP_UTF8 65001 /* UTF-8 translation */
+#endif
+
#endif /* !defined (_RSXNTWIN_H) */
#endif /* __RSXNT__ */
diff --git a/win32/vc6/ReadmeVC.txt b/win32/vc6/ReadmeVC.txt
new file mode 100644
index 0000000..f0295cb
--- /dev/null
+++ b/win32/vc6/ReadmeVC.txt
@@ -0,0 +1,10 @@
+VC6 Readme
+
+This directory has a VC6 project list that can be used to compile Zip
+and the utilities. It does not include bzip2 support.
+
+The vc6bz2 directory provides a variant of this directory that includes
+the settings needed for including bzip2 support in Zip.
+
+Ed Gordon
+26 March 2007
diff --git a/win32/vc6/zip.dsp b/win32/vc6/zip.dsp
index f82b335..10acbe1 100644
--- a/win32/vc6/zip.dsp
+++ b/win32/vc6/zip.dsp
@@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Intermediate_Dir "zip___Win32_ASM_Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "ASM_CRC" /D "ASMV" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "ASM_CRC" /D "ASMV" /FR /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
@@ -89,7 +89,7 @@ LINK32=link.exe
# PROP Intermediate_Dir "zip___Win32_Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NO_ASM" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "NO_ASM" /D "WIN32" /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@@ -110,9 +110,10 @@ LINK32=link.exe
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "zip___Win32_Debug"
# PROP Intermediate_Dir "zip___Win32_Debug"
+# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "NO_ASM" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "NO_ASM" /FR /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
@@ -139,10 +140,6 @@ SOURCE=..\..\crc32.c
# End Source File
# Begin Source File
-SOURCE=..\..\crctab.c
-# End Source File
-# Begin Source File
-
SOURCE=..\..\crypt.c
# End Source File
# Begin Source File
@@ -179,6 +176,10 @@ SOURCE=..\win32.c
# End Source File
# Begin Source File
+SOURCE=..\win32i64.c
+# End Source File
+# Begin Source File
+
SOURCE=..\win32zip.c
# End Source File
# Begin Source File
@@ -187,6 +188,10 @@ SOURCE=..\..\zip.c
# End Source File
# Begin Source File
+SOURCE=..\zip.rc
+# End Source File
+# Begin Source File
+
SOURCE=..\..\zipfile.c
# End Source File
# Begin Source File
@@ -199,6 +204,10 @@ SOURCE=..\..\zipup.c
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
+SOURCE=..\..\crc32.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\crypt.h
# End Source File
# Begin Source File
@@ -271,6 +280,8 @@ InputName=crc_i386
"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+# End Custom Build
+
!ELSEIF "$(CFG)" == "zip - Win32 Release"
# PROP Exclude_From_Build 1
@@ -279,8 +290,6 @@ InputName=crc_i386
# PROP Exclude_From_Build 1
-# End Custom Build
-
!ENDIF
# End Source File
@@ -310,6 +319,8 @@ InputName=match32
"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+# End Custom Build
+
!ELSEIF "$(CFG)" == "zip - Win32 Release"
# PROP Exclude_From_Build 1
@@ -318,8 +329,6 @@ InputName=match32
# PROP Exclude_From_Build 1
-# End Custom Build
-
!ENDIF
# End Source File
diff --git a/win32/vc6/zipcloak.dsp b/win32/vc6/zipcloak.dsp
index dac83fa..e09ccd7 100644
--- a/win32/vc6/zipcloak.dsp
+++ b/win32/vc6/zipcloak.dsp
@@ -4,7 +4,7 @@
# TARGTYPE "Win32 (x86) Console Application" 0x0103
-CFG=zipcloak - Win32 Debug
+CFG=zipcloak - Win32 ASM Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
@@ -13,12 +13,14 @@ CFG=zipcloak - Win32 Debug
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
-!MESSAGE NMAKE /f "zipcloak.mak" CFG="zipcloak - Win32 Debug"
+!MESSAGE NMAKE /f "zipcloak.mak" CFG="zipcloak - Win32 ASM Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "zipcloak - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "zipcloak - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "zipcloak - Win32 ASM Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "zipcloak - Win32 ASM Release" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
@@ -41,7 +43,7 @@ RSC=rc.exe
# PROP Intermediate_Dir "zipcloak___Win32_Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "UTIL" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "UTIL" /D "WIN32" /D "NO_ASM" /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@@ -62,9 +64,35 @@ LINK32=link.exe
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "zipcloak___Win32_Debug"
# PROP Intermediate_Dir "zipcloak___Win32_Debug"
+# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "UTIL" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "UTIL" /D "WIN32" /D "NO_ASM" /FR /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "zipcloak - Win32 ASM Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zipcloak___Win32_ASM_Debug"
+# PROP BASE Intermediate_Dir "zipcloak___Win32_ASM_Debug"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "zipcloak___Win32_ASM_Debug"
+# PROP Intermediate_Dir "zipcloak___Win32_ASM_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "UTIL" /D "WIN32" /FR /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "UTIL" /D "WIN32" /FR /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
@@ -74,18 +102,43 @@ LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+!ELSEIF "$(CFG)" == "zipcloak - Win32 ASM Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zipcloak___Win32_ASM_Release"
+# PROP BASE Intermediate_Dir "zipcloak___Win32_ASM_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zipcloak___Win32_ASM_Release"
+# PROP Intermediate_Dir "zipcloak___Win32_ASM_Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "UTIL" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "UTIL" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
!ENDIF
# Begin Target
# Name "zipcloak - Win32 Release"
# Name "zipcloak - Win32 Debug"
+# Name "zipcloak - Win32 ASM Debug"
+# Name "zipcloak - Win32 ASM Release"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
-SOURCE=..\..\crctab.c
+SOURCE=..\..\crc32.c
# End Source File
# Begin Source File
@@ -113,6 +166,10 @@ SOURCE=..\win32.c
# End Source File
# Begin Source File
+SOURCE=..\win32i64.c
+# End Source File
+# Begin Source File
+
SOURCE=..\..\zipcloak.c
# End Source File
# Begin Source File
@@ -125,6 +182,10 @@ SOURCE=..\..\zipfile.c
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
+SOURCE=..\..\crc32.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\crypt.h
# End Source File
# Begin Source File
@@ -160,5 +221,44 @@ SOURCE=..\..\zip.h
SOURCE=..\..\ziperr.h
# End Source File
# End Group
+# Begin Group "Assembler Files"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\crc_i386.asm
+
+!IF "$(CFG)" == "zipcloak - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zipcloak - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zipcloak - Win32 ASM Debug"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zipcloak___Win32_ASM_Debug
+InputPath=..\crc_i386.asm
+InputName=crc_i386
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zipcloak - Win32 ASM Release"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zipcloak___Win32_ASM_Release
+InputPath=..\crc_i386.asm
+InputName=crc_i386
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
# End Target
# End Project
diff --git a/win32/vc6/zipnote.dsp b/win32/vc6/zipnote.dsp
index e32e2f1..a7f9f57 100644
--- a/win32/vc6/zipnote.dsp
+++ b/win32/vc6/zipnote.dsp
@@ -4,7 +4,7 @@
# TARGTYPE "Win32 (x86) Console Application" 0x0103
-CFG=zipnote - Win32 Debug
+CFG=zipnote - Win32 ASM Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
@@ -13,12 +13,14 @@ CFG=zipnote - Win32 Debug
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
-!MESSAGE NMAKE /f "zipnote.mak" CFG="zipnote - Win32 Debug"
+!MESSAGE NMAKE /f "zipnote.mak" CFG="zipnote - Win32 ASM Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "zipnote - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "zipnote - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "zipnote - Win32 ASM Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "zipnote - Win32 ASM Release" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
@@ -41,7 +43,7 @@ RSC=rc.exe
# PROP Intermediate_Dir "zipnote___Win32_Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "UTIL" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "UTIL" /D "WIN32" /D "NO_ASM" /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@@ -62,9 +64,35 @@ LINK32=link.exe
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "zipnote___Win32_Debug"
# PROP Intermediate_Dir "zipnote___Win32_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "NO_ASM" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "UTIL" /D "WIN32" /D "NO_ASM" /FR /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "zipnote - Win32 ASM Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zipnote___Win32_ASM_Debug"
+# PROP BASE Intermediate_Dir "zipnote___Win32_ASM_Debug"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "zipnote___Win32_ASM_Debug"
+# PROP Intermediate_Dir "zipnote___Win32_ASM_Debug"
+# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "UTIL" /FD /GZ /c
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "UTIL" /D "WIN32" /FR /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "UTIL" /D "WIN32" /FR /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
@@ -74,17 +102,46 @@ LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+!ELSEIF "$(CFG)" == "zipnote - Win32 ASM Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zipnote___Win32_ASM_Release"
+# PROP BASE Intermediate_Dir "zipnote___Win32_ASM_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zipnote___Win32_ASM_Release"
+# PROP Intermediate_Dir "zipnote___Win32_ASM_Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "UTIL" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "UTIL" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
!ENDIF
# Begin Target
# Name "zipnote - Win32 Release"
# Name "zipnote - Win32 Debug"
+# Name "zipnote - Win32 ASM Debug"
+# Name "zipnote - Win32 ASM Release"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
+SOURCE=..\..\crc32.c
+# End Source File
+# Begin Source File
+
SOURCE=..\..\fileio.c
# End Source File
# Begin Source File
@@ -101,6 +158,10 @@ SOURCE=..\win32.c
# End Source File
# Begin Source File
+SOURCE=..\win32i64.c
+# End Source File
+# Begin Source File
+
SOURCE=..\..\zipfile.c
# End Source File
# Begin Source File
@@ -113,6 +174,10 @@ SOURCE=..\..\zipnote.c
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
+SOURCE=..\..\crc32.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\ebcdic.h
# End Source File
# Begin Source File
@@ -140,5 +205,44 @@ SOURCE=..\..\zip.h
SOURCE=..\..\ziperr.h
# End Source File
# End Group
+# Begin Group "Assembler Files"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\crc_i386.asm
+
+!IF "$(CFG)" == "zipnote - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zipnote - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zipnote - Win32 ASM Debug"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zipnote___Win32_ASM_Debug
+InputPath=..\crc_i386.asm
+InputName=crc_i386
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zipnote - Win32 ASM Release"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zipnote___Win32_ASM_Release
+InputPath=..\crc_i386.asm
+InputName=crc_i386
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
# End Target
# End Project
diff --git a/win32/vc6/zipsplit.dsp b/win32/vc6/zipsplit.dsp
index aec7139..ae5565d 100644
--- a/win32/vc6/zipsplit.dsp
+++ b/win32/vc6/zipsplit.dsp
@@ -4,7 +4,7 @@
# TARGTYPE "Win32 (x86) Console Application" 0x0103
-CFG=zipsplit - Win32 Debug
+CFG=zipsplit - Win32 ASM Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
@@ -13,12 +13,14 @@ CFG=zipsplit - Win32 Debug
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
-!MESSAGE NMAKE /f "zipsplit.mak" CFG="zipsplit - Win32 Debug"
+!MESSAGE NMAKE /f "zipsplit.mak" CFG="zipsplit - Win32 ASM Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "zipsplit - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "zipsplit - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "zipsplit - Win32 ASM Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "zipsplit - Win32 ASM Release" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
@@ -41,7 +43,7 @@ RSC=rc.exe
# PROP Intermediate_Dir "zipsplit___Win32_Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /FD /c
-# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "UTIL" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "UTIL" /D "WIN32" /D "NO_ASM" /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@@ -62,9 +64,35 @@ LINK32=link.exe
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "zipsplit___Win32_Debug"
# PROP Intermediate_Dir "zipsplit___Win32_Debug"
+# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "UTIL" /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "UTIL" /D "WIN32" /D "NO_ASM" /FR /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "zipsplit - Win32 ASM Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zipsplit___Win32_ASM_Debug"
+# PROP BASE Intermediate_Dir "zipsplit___Win32_ASM_Debug"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "zipsplit___Win32_ASM_Debug"
+# PROP Intermediate_Dir "zipsplit___Win32_ASM_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "UTIL" /D "WIN32" /FR /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "UTIL" /D "WIN32" /FR /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
@@ -74,17 +102,46 @@ LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+!ELSEIF "$(CFG)" == "zipsplit - Win32 ASM Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zipsplit___Win32_ASM_Release"
+# PROP BASE Intermediate_Dir "zipsplit___Win32_ASM_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zipsplit___Win32_ASM_Release"
+# PROP Intermediate_Dir "zipsplit___Win32_ASM_Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "UTIL" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "UTIL" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
!ENDIF
# Begin Target
# Name "zipsplit - Win32 Release"
# Name "zipsplit - Win32 Debug"
+# Name "zipsplit - Win32 ASM Debug"
+# Name "zipsplit - Win32 ASM Release"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
+SOURCE=..\..\crc32.c
+# End Source File
+# Begin Source File
+
SOURCE=..\..\fileio.c
# End Source File
# Begin Source File
@@ -101,6 +158,10 @@ SOURCE=..\win32.c
# End Source File
# Begin Source File
+SOURCE=..\win32i64.c
+# End Source File
+# Begin Source File
+
SOURCE=..\..\zipfile.c
# End Source File
# Begin Source File
@@ -113,6 +174,10 @@ SOURCE=..\..\zipsplit.c
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
+SOURCE=..\..\crc32.h
+# End Source File
+# Begin Source File
+
SOURCE=..\..\ebcdic.h
# End Source File
# Begin Source File
@@ -140,5 +205,44 @@ SOURCE=..\..\zip.h
SOURCE=..\..\ziperr.h
# End Source File
# End Group
+# Begin Group "Assembler Files"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=..\crc_i386.asm
+
+!IF "$(CFG)" == "zipsplit - Win32 Release"
+
+!ELSEIF "$(CFG)" == "zipsplit - Win32 Debug"
+
+!ELSEIF "$(CFG)" == "zipsplit - Win32 ASM Debug"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zipsplit___Win32_ASM_Debug
+InputPath=..\crc_i386.asm
+InputName=crc_i386
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zipsplit - Win32 ASM Release"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zipsplit___Win32_ASM_Release
+InputPath=..\crc_i386.asm
+InputName=crc_i386
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
# End Target
# End Project
diff --git a/win32/vc6bz2/ReadVCBZ.txt b/win32/vc6bz2/ReadVCBZ.txt
new file mode 100644
index 0000000..3aafd6f
--- /dev/null
+++ b/win32/vc6bz2/ReadVCBZ.txt
@@ -0,0 +1,19 @@
+VC6bz2 Readme
+
+This directory has a VC6 project list that can be used to compile Zip
+and the utilities. The Zip project includes support for the bzip2
+compression method.
+
+To include bzip2 support, get a copy of the bzip2 source (bzip2-1.0.4
+or later from http://www.bzip.org/ for instance), expand the bzip2
+source into a directory, then copy the contents of the bzip2-1.0.4
+directory, for instance, into the zip bzip2 directory. Use this
+project to compile zip and bzip2 support should be included. See
+bzip2/install.txt for additional information.
+
+The vc6 directory is similar to this directory but does not include
+bzip2 support. Use that if you do not have a copy of bzip2 or do not
+need bzip2 support.
+
+Ed Gordon
+26 March 2007
diff --git a/win32/vc6bz2/zip.dsp b/win32/vc6bz2/zip.dsp
new file mode 100644
index 0000000..fee0af4
--- /dev/null
+++ b/win32/vc6bz2/zip.dsp
@@ -0,0 +1,381 @@
+# Microsoft Developer Studio Project File - Name="zip" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=zip - Win32 Debug bzip2
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "zip.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "zip.mak" CFG="zip - Win32 Debug bzip2"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "zip - Win32 ASM Release bzip2" (based on "Win32 (x86) Console Application")
+!MESSAGE "zip - Win32 ASM Debug bzip2" (based on "Win32 (x86) Console Application")
+!MESSAGE "zip - Win32 Release bzip2" (based on "Win32 (x86) Console Application")
+!MESSAGE "zip - Win32 Debug bzip2" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "zip - Win32 ASM Release bzip2"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zip___Win32_ASM_Release_bzip2"
+# PROP BASE Intermediate_Dir "zip___Win32_ASM_Release_bzip2"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zip___Win32_ASM_Release_bzip2"
+# PROP Intermediate_Dir "zip___Win32_ASM_Release_bzip2"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "ASM_CRC" /D "ASMV" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "../../bzip2" /D "ASM_CRC" /D "ASMV" /D "WIN32" /D "BZIP2_SUPPORT" /D "BZ_NO_STDIO" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "zip - Win32 ASM Debug bzip2"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zip___Win32_ASM_Debug_bzip2"
+# PROP BASE Intermediate_Dir "zip___Win32_ASM_Debug_bzip2"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "zip___Win32_ASM_Debug_bzip2"
+# PROP Intermediate_Dir "zip___Win32_ASM_Debug_bzip2"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "ASM_CRC" /D "ASMV" /FR /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../bzip2" /D "ASM_CRC" /D "ASMV" /D "WIN32" /D "BZIP2_SUPPORT" /D "BZ_NO_STDIO" /FR /FD /GZ /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "zip - Win32 Release bzip2"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zip___Win32_Release_bzip2"
+# PROP BASE Intermediate_Dir "zip___Win32_Release_bzip2"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "zip___Win32_Release_bzip2"
+# PROP Intermediate_Dir "zip___Win32_Release_bzip2"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NO_ASM" /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "../../bzip2" /D "NO_ASM" /D "WIN32" /D "BZIP2_SUPPORT" /D "BZ_NO_STDIO" /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF "$(CFG)" == "zip - Win32 Debug bzip2"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zip___Win32_Debug_bzip2"
+# PROP BASE Intermediate_Dir "zip___Win32_Debug_bzip2"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "zip___Win32_Debug_bzip2"
+# PROP Intermediate_Dir "zip___Win32_Debug_bzip2"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "NO_ASM" /D "WIN32" /FR /FD /GZ /c
+# SUBTRACT BASE CPP /WX
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../../bzip2" /D "NO_ASM" /D "WIN32" /D "BZIP2_SUPPORT" /D "BZ_NO_STDIO" /FR /FD /GZ /c
+# SUBTRACT CPP /WX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "zip - Win32 ASM Release bzip2"
+# Name "zip - Win32 ASM Debug bzip2"
+# Name "zip - Win32 Release bzip2"
+# Name "zip - Win32 Debug bzip2"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\bzip2\blocksort.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\bzip2\bzlib.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\bzip2\compress.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\crc32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\bzip2\crctable.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\crypt.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\bzip2\decompress.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\deflate.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\fileio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\globals.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\bzip2\huffman.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\nt.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\bzip2\randtable.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\trees.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\ttyio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\util.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\win32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\win32i64.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\win32zip.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zbz2err.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zip.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\zip.rc
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zipfile.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zipup.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\..\bzip2\bzlib.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\crc32.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\crypt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\ebcdic.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\nt.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\osdep.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\revision.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\tailor.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\ttyio.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\win32zip.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zip.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\ziperr.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\zipup.h
+# End Source File
+# End Group
+# Begin Group "Assembler Files"
+
+# PROP Default_Filter "asm;obj"
+# Begin Source File
+
+SOURCE=..\crc_i386.asm
+
+!IF "$(CFG)" == "zip - Win32 ASM Release bzip2"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zip___Win32_ASM_Release_bzip2
+InputPath=..\crc_i386.asm
+InputName=crc_i386
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zip - Win32 ASM Debug bzip2"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zip___Win32_ASM_Debug_bzip2
+InputPath=..\crc_i386.asm
+InputName=crc_i386
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zip - Win32 Release bzip2"
+
+# PROP BASE Exclude_From_Build 1
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zip - Win32 Debug bzip2"
+
+# PROP BASE Exclude_From_Build 1
+# PROP Exclude_From_Build 1
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\match32.asm
+
+!IF "$(CFG)" == "zip - Win32 ASM Release bzip2"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zip___Win32_ASM_Release_bzip2
+InputPath=..\match32.asm
+InputName=match32
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zip - Win32 ASM Debug bzip2"
+
+# Begin Custom Build - Assembling...
+IntDir=.\zip___Win32_ASM_Debug_bzip2
+InputPath=..\match32.asm
+InputName=match32
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zip - Win32 Release bzip2"
+
+# PROP BASE Exclude_From_Build 1
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zip - Win32 Debug bzip2"
+
+# PROP BASE Exclude_From_Build 1
+# PROP Exclude_From_Build 1
+
+!ENDIF
+
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/win32/vc6bz2/zip.dsw b/win32/vc6bz2/zip.dsw
new file mode 100644
index 0000000..bab0fdd
--- /dev/null
+++ b/win32/vc6bz2/zip.dsw
@@ -0,0 +1,65 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "zip"=.\zip.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "zipcloak"=..\vc6\zipcloak.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "zipnote"=..\vc6\zipnote.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "zipsplit"=..\vc6\zipsplit.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/win32/win32.c b/win32/win32.c
index 88bd565..5798053 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -1,11 +1,14 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ win32/win32.c - Zip 3
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
+
/*
* WIN32 specific functions for ZIP.
*
@@ -21,7 +24,11 @@
#include <limits.h>
#include <time.h>
#include <ctype.h>
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+/* for LARGE_FILE_SUPPORT but may not be needed */
+#include <io.h>
+
#ifdef __RSXNT__
# include <alloca.h>
# include "../win32/rsxntwin.h"
@@ -38,6 +45,9 @@
#define EAID 0x0009
+#if (defined(__MINGW32__) && !defined(USE_MINGW_GLOBBING))
+ int _CRT_glob = 0; /* suppress command line globbing by C RTL */
+#endif
#ifndef UTIL
@@ -45,10 +55,12 @@ extern int noisy;
#ifdef NT_TZBUG_WORKAROUND
local int FSusesLocalTime(const char *path);
+#ifdef UNICODE_SUPPORt
+local int FSusesLocalTimeW(const wchar_t *path);
+#endif
#endif
-#if (defined(USE_EF_UT_TIME) || \
- (defined(NT_TZBUG_WORKAROUND) && !defined(NO_W32TIMES_IZFIX)))
-local int NtfsFileTime2utime(const FILETIME *pft, time_t *ut);
+#if (defined(USE_EF_UT_TIME) || defined(NT_TZBUG_WORKAROUND))
+local int FileTime2utime(FILETIME *pft, time_t *ut);
#endif
#if (defined(NT_TZBUG_WORKAROUND) && defined(W32_STAT_BANDAID))
local int VFatFileTime2utime(const FILETIME *pft, time_t *ut);
@@ -57,16 +69,13 @@ local int VFatFileTime2utime(const FILETIME *pft, time_t *ut);
/* FAT / HPFS detection */
-int IsFileSystemOldFAT(const char *dir)
+int IsFileSystemOldFAT(char *dir)
{
+ static char lastDrive = '\0'; /* cached drive of last GetVolumeInformation call */
+ static int lastDriveOldFAT = 0; /* cached OldFAT value of last GetVolumeInformation call */
char root[4];
- char vname[128];
- DWORD vnamesize = sizeof(vname);
- DWORD vserial;
DWORD vfnsize;
DWORD vfsflags;
- char vfsname[128];
- DWORD vfsnamesize = sizeof(vfsname);
/*
* We separate FAT and HPFS+other file systems here.
@@ -84,33 +93,112 @@ int IsFileSystemOldFAT(const char *dir)
root[0] = '\\';
root[1] = 0;
}
+ if (lastDrive == root[0]) {
+ return lastDriveOldFAT;
+ }
- if ( !GetVolumeInformation(root, vname, vnamesize,
- &vserial, &vfnsize, &vfsflags,
- vfsname, vfsnamesize)) {
+ if ( !GetVolumeInformation(root, NULL, 0,
+ NULL, &vfnsize, &vfsflags,
+ NULL, 0)) {
fprintf(mesg, "zip diagnostic: GetVolumeInformation failed\n");
return(FALSE);
}
- return vfnsize <= 12;
+ lastDrive = root[0];
+ lastDriveOldFAT = vfnsize <= 12;
+
+ return lastDriveOldFAT;
}
+#ifdef UNICODE_SUPPORT
+int IsFileSystemOldFATW(wchar_t *dir)
+{
+ static wchar_t lastDrive = (wchar_t)'\0'; /* cached drive of last GetVolumeInformation call */
+ static int lastDriveOldFAT = 0; /* cached OldFAT value of last GetVolumeInformation call */
+ wchar_t root[4];
+ DWORD vfnsize;
+ DWORD vfsflags;
+
+ /*
+ * We separate FAT and HPFS+other file systems here.
+ * I consider other systems to be similar to HPFS/NTFS, i.e.
+ * support for long file names and being case sensitive to some extent.
+ */
+
+ wcsncpy(root, dir, 3);
+ if ( iswalpha(root[0]) && (root[1] == (wchar_t)':') ) {
+ root[0] = towupper(dir[0]);
+ root[2] = (wchar_t)'\\';
+ root[3] = 0;
+ }
+ else {
+ root[0] = (wchar_t)'\\';
+ root[1] = 0;
+ }
+ if (lastDrive == root[0]) {
+ return lastDriveOldFAT;
+ }
+
+ if ( !GetVolumeInformationW(root, NULL, 0,
+ NULL, &vfnsize, &vfsflags,
+ NULL, 0)) {
+ fprintf(mesg, "zip diagnostic: GetVolumeInformation failed\n");
+ return(FALSE);
+ }
+
+ lastDrive = root[0];
+ lastDriveOldFAT = vfnsize <= 12;
+
+ return lastDriveOldFAT;
+}
+#endif
+
/* access mode bits and time stamp */
-int GetFileMode(const char *name)
+int GetFileMode(char *name)
{
DWORD dwAttr;
-#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
char *ansi_name = (char *)alloca(strlen(name) + 1);
OemToAnsi(name, ansi_name);
- name = (const char *)ansi_name;
+ name = ansi_name;
#endif
dwAttr = GetFileAttributes(name);
if ( dwAttr == 0xFFFFFFFF ) {
- fprintf(mesg, "zip diagnostic: GetFileAttributes failed\n");
+ zipwarn("reading file attributes failed: ", name);
+ /*
+ fprintf(mesg, "zip diagnostic: GetFileAttributes failed");
+ fflush();
+ */
+ return(0x20); /* the most likely, though why the error? security? */
+ }
+ return(
+ (dwAttr&FILE_ATTRIBUTE_READONLY ? A_RONLY :0)
+ | (dwAttr&FILE_ATTRIBUTE_HIDDEN ? A_HIDDEN :0)
+ | (dwAttr&FILE_ATTRIBUTE_SYSTEM ? A_SYSTEM :0)
+ | (dwAttr&FILE_ATTRIBUTE_DIRECTORY ? A_DIR :0)
+ | (dwAttr&FILE_ATTRIBUTE_ARCHIVE ? A_ARCHIVE :0));
+}
+
+#ifdef UNICODE_SUPPORT
+int GetFileModeW(wchar_t *namew)
+{
+DWORD dwAttr;
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ wchar_t *ansi_namew = (wchar_t *)alloca((wcslen(namew) + 1) * sizeof(wchar_t));
+
+ CharToAnsiW(namew, ansi_namew);
+ namew = ansi_namew;
+#endif
+
+ dwAttr = GetFileAttributesW(namew);
+ if ( dwAttr == 0xFFFFFFFF ) {
+ char *name = wchar_to_local_string(namew);
+ zipwarn("reading file attributes failed: ", name);
+ free(name);
return(0x20); /* the most likely, though why the error? security? */
}
return(
@@ -120,6 +208,49 @@ DWORD dwAttr;
| (dwAttr&FILE_ATTRIBUTE_DIRECTORY ? A_DIR :0)
| (dwAttr&FILE_ATTRIBUTE_ARCHIVE ? A_ARCHIVE :0));
}
+#endif
+
+
+int ClearArchiveBitW(wchar_t *namew)
+{
+DWORD dwAttr;
+ dwAttr = GetFileAttributesW(namew);
+ if ( dwAttr == 0xFFFFFFFF ) {
+ fprintf(mesg, "zip diagnostic: GetFileAttributes failed\n");
+ return(0);
+ }
+
+ if (!SetFileAttributesW(namew, (DWORD)(dwAttr & ~FILE_ATTRIBUTE_ARCHIVE))) {
+ fprintf(mesg, "zip diagnostic: SetFileAttributes failed\n");
+ perror("SetFileAttributes");
+ return(0);
+ }
+ return(1);
+}
+
+int ClearArchiveBit(char *name)
+{
+DWORD dwAttr;
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_name = (char *)alloca(strlen(name) + 1);
+
+ OemToAnsi(name, ansi_name);
+ name = ansi_name;
+#endif
+
+ dwAttr = GetFileAttributes(name);
+ if ( dwAttr == 0xFFFFFFFF ) {
+ fprintf(mesg, "zip diagnostic: GetFileAttributes failed\n");
+ return(0);
+ }
+
+ if (!SetFileAttributes(name, (DWORD)(dwAttr & ~FILE_ATTRIBUTE_ARCHIVE))) {
+ fprintf(mesg, "zip diagnostic: SetFileAttributes failed\n");
+ perror("SetFileAttributes");
+ return(0);
+ }
+ return(1);
+}
#ifdef NT_TZBUG_WORKAROUND
@@ -129,11 +260,11 @@ local int FSusesLocalTime(const char *path)
char rootPathName[4];
char tmp1[MAX_PATH], tmp2[MAX_PATH];
DWORD volSerNo, maxCompLen, fileSysFlags;
-#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
char *ansi_path = (char *)alloca(strlen(path) + 1);
OemToAnsi(path, ansi_path);
- path = (const char *)ansi_path;
+ path = ansi_path;
#endif
if (isalpha((uch)path[0]) && (path[1] == ':'))
@@ -158,11 +289,49 @@ local int FSusesLocalTime(const char *path)
!strncmp(tmp2, "HPFS", 4);
} /* end function FSusesLocalTime() */
+
+# ifdef UNICODE_SUPPORT
+local int FSusesLocalTimeW(const wchar_t *path)
+{
+ wchar_t *tmp0;
+ wchar_t rootPathName[4];
+ wchar_t tmp1[MAX_PATH], tmp2[MAX_PATH];
+ DWORD volSerNo, maxCompLen, fileSysFlags;
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ wchar_t *ansi_path = (wchar_t *)alloca((wcslen(path) + 1) * sizeof(wchar_t));
+
+ CharToAnsiW(path, ansi_path);
+ path = ansi_path;
+#endif
+
+ if (iswalpha(path[0]) && (path[1] == (wchar_t)':'))
+ tmp0 = (wchar_t *)path;
+ else
+ {
+ GetFullPathNameW(path, MAX_PATH, tmp1, &tmp0);
+ tmp0 = &tmp1[0];
+ }
+ wcsncpy(rootPathName, tmp0, 3); /* Build the root path name, */
+ rootPathName[3] = (wchar_t)'\0'; /* e.g. "A:/" */
+
+ GetVolumeInformationW(rootPathName, tmp1, (DWORD)MAX_PATH,
+ &volSerNo, &maxCompLen, &fileSysFlags,
+ tmp2, (DWORD)MAX_PATH);
+
+ /* Volumes in (V)FAT and (OS/2) HPFS format store file timestamps in
+ * local time!
+ */
+ return !wcsncmp(_wcsupr(tmp2), L"FAT", 3) ||
+ !wcsncmp(tmp2, L"VFAT", 4) ||
+ !wcsncmp(tmp2, L"HPFS", 4);
+
+} /* end function FSusesLocalTimeW() */
+# endif
+
#endif /* NT_TZBUG_WORKAROUND */
-#if (defined(USE_EF_UT_TIME) || \
- (defined(NT_TZBUG_WORKAROUND) && !defined(NO_W32TIMES_IZFIX)))
+#if (defined(USE_EF_UT_TIME) || defined(NT_TZBUG_WORKAROUND))
#if (defined(__GNUC__) || defined(ULONG_LONG_MAX))
typedef long long LLONG64;
@@ -180,13 +349,11 @@ local int FSusesLocalTime(const char *path)
# define NO_INT64
#endif
-/* scale factor and offset for conversion time_t -> FILETIME */
+# define UNIX_TIME_ZERO_HI 0x019DB1DEUL
+# define UNIX_TIME_ZERO_LO 0xD53E8000UL
# define NT_QUANTA_PER_UNIX 10000000L
# define FTQUANTA_PER_UT_L (NT_QUANTA_PER_UNIX & 0xFFFF)
# define FTQUANTA_PER_UT_H (NT_QUANTA_PER_UNIX >> 16)
-# define UNIX_TIME_ZERO_HI 0x019DB1DEUL
-# define UNIX_TIME_ZERO_LO 0xD53E8000UL
-/* special FILETIME values for bound-checks */
# define UNIX_TIME_UMAX_HI 0x0236485EUL
# define UNIX_TIME_UMAX_LO 0xD4A5E980UL
# define UNIX_TIME_SMIN_HI 0x0151669EUL
@@ -194,7 +361,7 @@ local int FSusesLocalTime(const char *path)
# define UNIX_TIME_SMAX_HI 0x01E9FD1EUL
# define UNIX_TIME_SMAX_LO 0xD4A5E980UL
-local int NtfsFileTime2utime(const FILETIME *pft, time_t *ut)
+local int FileTime2utime(FILETIME *pft, time_t *ut)
{
#ifndef NO_INT64
ULLNG64 NTtime;
@@ -295,8 +462,8 @@ local int NtfsFileTime2utime(const FILETIME *pft, time_t *ut)
(time_t)(60 * w32tm.wMinute + w32tm.wSecond));
return TRUE;
#endif /* ?NO_INT64 */
-} /* end function NtfsFileTime2utime() */
-#endif /* USE_EF_UT_TIME || (NT_TZBUG_WORKAROUND && !NO_W32TIMES_IZFIX) */
+} /* end function FileTime2utime() */
+#endif /* USE_EF_UT_TIME || NT_TZBUG_WORKAROUND */
#if (defined(NT_TZBUG_WORKAROUND) && defined(W32_STAT_BANDAID))
@@ -307,10 +474,7 @@ local int VFatFileTime2utime(const FILETIME *pft, time_t *ut)
SYSTEMTIME w32tm;
struct tm ltm;
- if (!FileTimeToLocalFileTime(pft, &lft)) {
- /* if pft cannot be converted to local time, return current time */
- return time(NULL);
- }
+ FileTimeToLocalFileTime(pft, &lft);
FileTimeToSystemTime(&lft, &w32tm);
/* underflow and overflow handling */
/* TODO: The range checks are not accurate, the actual limits may
@@ -371,11 +535,11 @@ local int VFatFileTime2utime(const FILETIME *pft, time_t *ut)
#if 0 /* Currently, this is not used at all */
-long GetTheFileTime(const char *name, iztimes *z_ut)
+long GetTheFileTime(char *name, iztimes *z_ut)
{
- HANDLE h;
- FILETIME Modft, Accft, Creft, lft;
- WORD dh, dl;
+HANDLE h;
+FILETIME Modft, Accft, Creft, lft;
+WORD dh, dl;
#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
char *ansi_name = (char *)alloca(strlen(name) + 1);
@@ -383,20 +547,20 @@ long GetTheFileTime(const char *name, iztimes *z_ut)
name = ansi_name;
#endif
- h = CreateFile(name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ h = CreateFile(name, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if ( h != INVALID_HANDLE_VALUE ) {
BOOL ftOK = GetFileTime(h, &Creft, &Accft, &Modft);
CloseHandle(h);
#ifdef USE_EF_UT_TIME
if (ftOK && (z_ut != NULL)) {
- NtfsFileTime2utime(&Modft, &(z_ut->mtime));
+ FileTime2utime(&Modft, &(z_ut->mtime));
if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0)
- NtfsFileTime2utime(&Accft, &(z_ut->atime));
+ FileTime2utime(&Accft, &(z_ut->atime));
else
z_ut->atime = z_ut->mtime;
if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0)
- NtfsFileTime2utime(&Creft, &(z_ut->ctime));
+ FileTime2utime(&Creft, &(z_ut->ctime));
else
z_ut->ctime = z_ut->mtime;
}
@@ -482,21 +646,29 @@ void ChangeNameForFAT(char *name)
*src = '_';
}
-char *GetLongPathEA(const char *name)
+char *GetLongPathEA(char *name)
+{
+ return(NULL); /* volunteers ? */
+}
+
+#ifdef UNICODE_SUPPORT
+wchar_t *GetLongPathEAW(wchar_t *name)
{
return(NULL); /* volunteers ? */
}
+#endif
+
int IsFileNameValid(x)
-const char *x;
+char *x;
{
WIN32_FIND_DATA fd;
HANDLE h;
-#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
char *ansi_name = (char *)alloca(strlen(x) + 1);
OemToAnsi(x, ansi_name);
- x = (const char *)ansi_name;
+ x = ansi_name;
#endif
if ((h = FindFirstFile(x, &fd)) == INVALID_HANDLE_VALUE)
@@ -525,7 +697,7 @@ char *getVolumeLabel(drive, vtime, vmode, vutim)
rootpath[0] = (char)drive;
if (GetVolumeInformation(drive ? rootpath : NULL, vol, 13, NULL,
&fnlen, &flags, NULL, 0))
-#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
return (AnsiToOem(vol, vol), vol);
#else
return vol;
@@ -589,40 +761,25 @@ char *StringLower(char *szArg)
#ifdef W32_STAT_BANDAID
/* All currently known variants of WIN32 operating systems (Windows 95/98,
- * WinNT 3.x, 4.0, 5.x) have a nasty bug in the OS kernel concerning
+ * WinNT 3.x, 4.0, 5.0) have a nasty bug in the OS kernel concerning
* conversions between UTC and local time: In the time conversion functions
* of the Win32 API, the timezone offset (including seasonal daylight saving
* shift) between UTC and local time evaluation is erratically based on the
* current system time. The correct evaluation must determine the offset
* value as it {was/is/will be} for the actual time to be converted.
*
- * Newer versions of MS C runtime lib's stat() returns utc time-stamps so
- * that localtime(timestamp) corresponds to the (potentially false) local
+ * The C runtime lib's stat() returns utc time-stamps so that
+ * localtime(timestamp) corresponds to the (potentially false) local
* time shown by the OS' system programs (Explorer, command shell dir, etc.)
- * The RSXNT port follows the same strategy, but fails to recognize the
- * access-time attribute.
*
* For the NTFS file system (and other filesystems that store time-stamps
* as UTC values), this results in st_mtime (, st_{c|a}time) fields which
* are not stable but vary according to the seasonal change of "daylight
* saving time in effect / not in effect".
*
- * Other C runtime libs (CygWin, or the crtdll.dll supplied with Win9x/NT
- * return the unix-time equivalent of the UTC FILETIME values as got back
- * from the Win32 API call. This time, return values from NTFS are correct
- * whereas utimes from files on (V)FAT volumes vary according to the DST
- * switches.
- *
* To achieve timestamp consistency of UTC (UT extra field) values in
* Zip archives, the Info-ZIP programs require work-around code for
* proper time handling in stat() (and other time handling routines).
- *
- * However, nowadays most other programs on Windows systems use the
- * time conversion strategy of Microsofts C runtime lib "msvcrt.dll".
- * To improve interoperability in environments where a "consistent" (but
- * false) "UTC<-->LocalTime" conversion is preferred over "stable" time
- * stamps, the Info-ZIP specific time conversion handling can be
- * deactivated by defining the preprocessor flag NO_W32TIMES_IZFIX.
*/
/* stat() functions under Windows95 tend to fail for root directories. *
* Watcom and Borland, at least, are affected by this bug. Watcom made *
@@ -630,18 +787,24 @@ char *StringLower(char *szArg)
* detects the case and fills in reasonable values. Otherwise we get *
* effects like failure to extract to a root dir because it's not found. */
-int zstat_zipwin32(const char *path, struct stat *buf)
+#ifdef LARGE_FILE_SUPPORT /* E. Gordon 9/12/03 */
+ int zstat_zipwin32(const char *path, z_stat *buf)
+#else
+ int zstat_zipwin32(const char *path, struct stat *buf)
+#endif
{
+# ifdef LARGE_FILE_SUPPORT /* E. Gordon 9/12/03 */
+ if (!zstat(path, buf))
+# else
if (!stat(path, buf))
+# endif
{
-#if (!defined(UTIL) && defined(NT_TZBUG_WORKAROUND))
+#ifdef NT_TZBUG_WORKAROUND
/* stat was successful, now redo the time-stamp fetches */
-#ifndef NO_W32TIMES_IZFIX
int fs_uses_loctime = FSusesLocalTime(path);
-#endif
HANDLE h;
FILETIME Modft, Accft, Creft;
-#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
char *ansi_path = (char *)alloca(strlen(path) + 1);
OemToAnsi(path, ansi_path);
@@ -651,35 +814,31 @@ int zstat_zipwin32(const char *path, struct stat *buf)
#endif
Trace((stdout, "stat(%s) finds modtime %08lx\n", path, buf->st_mtime));
- h = CreateFile(Ansi_Path, GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ h = CreateFile(Ansi_Path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h != INVALID_HANDLE_VALUE) {
BOOL ftOK = GetFileTime(h, &Creft, &Accft, &Modft);
CloseHandle(h);
if (ftOK) {
-#ifndef NO_W32TIMES_IZFIX
if (!fs_uses_loctime) {
/* On a filesystem that stores UTC timestamps, we refill
* the time fields of the struct stat buffer by directly
* using the UTC values as returned by the Win32
* GetFileTime() API call.
*/
- NtfsFileTime2utime(&Modft, &(buf->st_mtime));
+ FileTime2utime(&Modft, &(buf->st_mtime));
if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0)
- NtfsFileTime2utime(&Accft, &(buf->st_atime));
+ FileTime2utime(&Accft, &(buf->st_atime));
else
buf->st_atime = buf->st_mtime;
if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0)
- NtfsFileTime2utime(&Creft, &(buf->st_ctime));
+ FileTime2utime(&Creft, &(buf->st_ctime));
else
buf->st_ctime = buf->st_mtime;
Tracev((stdout,"NTFS, recalculated modtime %08lx\n",
buf->st_mtime));
- } else
-#endif /* NO_W32TIMES_IZFIX */
- {
+ } else {
/* On VFAT and FAT-like filesystems, the FILETIME values
* are converted back to the stable local time before
* converting them to UTC unix time-stamps.
@@ -699,14 +858,14 @@ int zstat_zipwin32(const char *path, struct stat *buf)
}
}
# undef Ansi_Path
-#endif /* !UTIL && NT_TZBUG_WORKAROUND */
+#endif /* NT_TZBUG_WORKAROUND */
return 0;
}
#ifdef W32_STATROOT_FIX
else
{
DWORD flags;
-#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
char *ansi_path = (char *)alloca(strlen(path) + 1);
OemToAnsi(path, ansi_path);
@@ -719,7 +878,11 @@ int zstat_zipwin32(const char *path, struct stat *buf)
if (flags != 0xFFFFFFFF && flags & FILE_ATTRIBUTE_DIRECTORY) {
Trace((stderr, "\nstat(\"%s\",...) failed on existing directory\n",
path));
+#ifdef LARGE_FILE_SUPPORT /* E. Gordon 9/12/03 */
+ memset(buf, 0, sizeof(z_stat));
+#else
memset(buf, 0, sizeof(struct stat));
+#endif
buf->st_atime = buf->st_ctime = buf->st_mtime =
dos2unixtime(DOSTIME_MINIMUM);
/* !!! you MUST NOT add a cast to the type of "st_mode" here;
@@ -737,6 +900,117 @@ int zstat_zipwin32(const char *path, struct stat *buf)
return -1;
}
+
+# ifdef UNICODE_SUPPORT
+
+int zstat_zipwin32w(const wchar_t *pathw, zw_stat *buf)
+{
+ if (!zwstat(pathw, buf))
+ {
+#ifdef NT_TZBUG_WORKAROUND
+ /* stat was successful, now redo the time-stamp fetches */
+ int fs_uses_loctime = FSusesLocalTimeW(pathw);
+ HANDLE h;
+ FILETIME Modft, Accft, Creft;
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_path = (char *)alloca(strlen(pathw) + 1);
+
+ OemToAnsi(path, ansi_path);
+# define Ansi_Path ansi_path
+#else
+# define Ansi_Path pathw
+#endif
+
+ Trace((stdout, "stat(%s) finds modtime %08lx\n", pathw, buf->st_mtime));
+ h = CreateFileW(Ansi_Path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (h != INVALID_HANDLE_VALUE) {
+ BOOL ftOK = GetFileTime(h, &Creft, &Accft, &Modft);
+ CloseHandle(h);
+
+ if (ftOK) {
+ if (!fs_uses_loctime) {
+ /* On a filesystem that stores UTC timestamps, we refill
+ * the time fields of the struct stat buffer by directly
+ * using the UTC values as returned by the Win32
+ * GetFileTime() API call.
+ */
+ FileTime2utime(&Modft, &(buf->st_mtime));
+ if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0)
+ FileTime2utime(&Accft, &(buf->st_atime));
+ else
+ buf->st_atime = buf->st_mtime;
+ if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0)
+ FileTime2utime(&Creft, &(buf->st_ctime));
+ else
+ buf->st_ctime = buf->st_mtime;
+ Tracev((stdout,"NTFS, recalculated modtime %08lx\n",
+ buf->st_mtime));
+ } else {
+ /* On VFAT and FAT-like filesystems, the FILETIME values
+ * are converted back to the stable local time before
+ * converting them to UTC unix time-stamps.
+ */
+ VFatFileTime2utime(&Modft, &(buf->st_mtime));
+ if (Accft.dwLowDateTime != 0 || Accft.dwHighDateTime != 0)
+ VFatFileTime2utime(&Accft, &(buf->st_atime));
+ else
+ buf->st_atime = buf->st_mtime;
+ if (Creft.dwLowDateTime != 0 || Creft.dwHighDateTime != 0)
+ VFatFileTime2utime(&Creft, &(buf->st_ctime));
+ else
+ buf->st_ctime = buf->st_mtime;
+ Tracev((stdout, "VFAT, recalculated modtime %08lx\n",
+ buf->st_mtime));
+ }
+ }
+ }
+# undef Ansi_Path
+#endif /* NT_TZBUG_WORKAROUND */
+ return 0;
+ }
+#ifdef W32_STATROOT_FIX
+ else
+ {
+ DWORD flags;
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ char *ansi_path = (char *)alloca(strlen(pathw) + 1);
+
+ OemToAnsi(path, ansi_path);
+# define Ansi_Path ansi_path
+#else
+# define Ansi_Path pathw
+#endif
+
+ flags = GetFileAttributesW(Ansi_Path);
+ if (flags != 0xFFFFFFFF && flags & FILE_ATTRIBUTE_DIRECTORY) {
+ Trace((stderr, "\nstat(\"%s\",...) failed on existing directory\n",
+ pathw));
+#ifdef LARGE_FILE_SUPPORT /* E. Gordon 9/12/03 */
+ memset(buf, 0, sizeof(z_stat));
+#else
+ memset(buf, 0, sizeof(struct stat));
+#endif
+ buf->st_atime = buf->st_ctime = buf->st_mtime =
+ dos2unixtime(DOSTIME_MINIMUM);
+ /* !!! you MUST NOT add a cast to the type of "st_mode" here;
+ * !!! different compilers do not agree on the "st_mode" size!
+ * !!! (And, some compiler may not declare the "mode_t" type
+ * !!! identifier, so you cannot use it, either.)
+ */
+ buf->st_mode = S_IFDIR | S_IREAD |
+ ((flags & FILE_ATTRIBUTE_READONLY) ? 0 : S_IWRITE);
+ return 0;
+ } /* assumes: stat() won't fail on non-dirs without good reason */
+# undef Ansi_Path
+ }
+#endif /* W32_STATROOT_FIX */
+ return -1;
+}
+
+# endif
+
+
#endif /* W32_STAT_BANDAID */
@@ -945,7 +1219,7 @@ void version_local()
__DJGPP__, __DJGPP_MINOR__);
# define COMPILER_NAME1 buf
# elif defined(__DJGPP__)
- sprintf(buf, "rsxnt(emx+djgpp v%d.%02d) / gcc ",
+ sprintf(buf, "rsxnt(emx+djgpp v%d.%02d) / gcc ",
__DJGPP__, __DJGPP_MINOR__);
# define COMPILER_NAME1 buf
# elif (defined(__GO32__) && !defined(__EMX__))
@@ -981,9 +1255,234 @@ void version_local()
#endif
printf(CompiledWith, COMPILER_NAME1, COMPILER_NAME2,
- "\nWindows 9x / Windows NT/2K/XP/2K3", " (32-bit)", COMPILE_DATE);
+ "\nWindows 9x / Windows NT", " (32-bit)", COMPILE_DATE);
return;
} /* end function version_local() */
#endif /* !WINDLL */
+
+
+/* --------------------------------------------------- */
+/* Large File Support
+ *
+ * Moved to Win32i64.c to avoid conflicts in same name functions
+ * in WiZ using UnZip and Zip libraries.
+ * 9/25/2003
+ */
+
+
+/* --------------------------------------------------- */
+/* Unicode Support for Win32
+ *
+ */
+
+#ifdef UNICODE_SUPPORT
+# if 0
+
+ /* get the wide command line and convert to argvw */
+ /* windows ignores argv and gets argvw separately */
+ zchar **get_wide_argv(argv)
+ char **argv;
+ {
+ int i;
+ int argc;
+ int size;
+ zchar **argvw = NULL;
+ zchar *commandline = NULL;
+ zchar **a = NULL;
+
+ commandline = GetCommandLineW();
+ a = CommandLineToArgvW(commandline, &argc);
+
+ if (a == NULL) {
+ /* failed */
+ ZIPERR(ZE_COMPERR, "get_wide_argv");
+ }
+
+ /* copy args so can use free_args() */
+ if ((argvw = (zchar **)malloc((argc + 1) * sizeof(zchar *))) == NULL) {
+ ZIPERR(ZE_MEM, "get_wide_argv");
+ }
+ for (i = 0; i < argc; i++) {
+ size = zstrlen(a[i]) + 1;
+ if ((argvw[i] = (zchar *)malloc(size * sizeof(zchar))) == NULL) {
+ ZIPERR(ZE_MEM, "get_wide_argv");
+ }
+ if ((argvw[i] = copy_zstring(a[i])) == NULL) {
+ ZIPERR(ZE_MEM, "get_wide_argv");
+ }
+ }
+ argvw[argc] = L'\0';
+
+ /* free original argvw */
+ LocalFree(a);
+
+ return argvw;
+ }
+# endif
+
+
+/* convert wide character string to multi-byte character string */
+/* win32 version */
+char *wide_to_local_string(wide_string)
+ zwchar *wide_string;
+{
+ int i;
+ wchar_t wc;
+ int bytes_char;
+ int default_used;
+ int wsize = 0;
+ int max_bytes = 9;
+ char buf[9];
+ char *buffer = NULL;
+ char *local_string = NULL;
+
+ if (wide_string == NULL)
+ return NULL;
+
+ for (wsize = 0; wide_string[wsize]; wsize++) ;
+
+ if (max_bytes < MB_CUR_MAX)
+ max_bytes = MB_CUR_MAX;
+
+ if ((buffer = (char *)malloc(wsize * max_bytes + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "wide_to_local_string");
+ }
+
+ /* convert it */
+ buffer[0] = '\0';
+ 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];
+ }
+ /* Unter some vendor's C-RTL, the Wide-to-MultiByte conversion functions
+ * (like wctomb() et. al.) do not use the same codepage as the other
+ * string arguments I/O functions (fopen, mkdir, rmdir etc.).
+ * Therefore, we have to fall back to the underlying Win32-API call to
+ * achieve a consistent behaviour for all supported compiler environments.
+ * Failing RTLs are for example:
+ * Borland (locale uses OEM-CP as default, but I/O functions expect ANSI
+ * names)
+ * Watcom (only "C" locale, wctomb() always uses OEM CP)
+ * (in other words: all supported environments except the Microsoft RTLs)
+ */
+ bytes_char = WideCharToMultiByte(
+ CP_ACP, WC_COMPOSITECHECK,
+ &wc, 1,
+ (LPSTR)buf, sizeof(buf),
+ NULL, &default_used);
+ if (default_used)
+ bytes_char = -1;
+ if (unicode_escape_all) {
+ if (bytes_char == 1 && (uch)buf[0] <= 0x7f) {
+ /* ASCII */
+ strncat(buffer, buf, 1);
+ } else {
+ /* use escape for wide character */
+ char *e = wide_char_to_escape_string(wide_string[i]);
+ strcat(buffer, e);
+ free(e);
+ }
+ } else if (bytes_char > 0) {
+ /* multi-byte char */
+ strncat(buffer, buf, bytes_char);
+ } 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 *)realloc(buffer, strlen(buffer) + 1)) == NULL) {
+ free(buffer);
+ ZIPERR(ZE_MEM, "wide_to_local_string");
+ }
+
+ return local_string;
+}
+
+/* convert multi-byte character string to wide character string */
+/* win32 version */
+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 = MultiByteToWideChar(CP_ACP, 0,
+ local_string, -1, NULL, 0);
+ 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 = MultiByteToWideChar(CP_ACP, 0,
+ local_string, -1,
+ wc_string, wsize + 1);
+ wc_string[wsize] = (wchar_t) 0;
+
+ /* in case wchar_t is not zwchar */
+ if ((wide_string = (zwchar *)malloc((wsize + 1) * sizeof(zwchar))) == NULL) {
+ free(wc_string);
+ 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 /* UNICODE_SUPPORT */
+
+
+/*
+# if defined(UNICODE_SUPPORT) || defined(WIN32_OEM)
+*/
+/* convert oem to ansi character string */
+char *oem_to_local_string(local_string, oem_string)
+ char *local_string;
+ char *oem_string;
+{
+ /* convert OEM to ANSI character set */
+ OemToChar(oem_string, local_string);
+
+ return local_string;
+}
+/*
+# endif
+*/
+
+
+/*
+#if defined(UNICODE_SUPPORT) || defined(WIN32_OEM)
+*/
+/* convert local to oem character string */
+char *local_to_oem_string(oem_string, local_string)
+ char *oem_string;
+ char *local_string;
+{
+ /* convert to OEM display character set */
+ CharToOem(local_string, oem_string);
+ return oem_string;
+}
+/*
+#endif
+*/
+
diff --git a/win32/win32i64.c b/win32/win32i64.c
new file mode 100644
index 0000000..a07eb1a
--- /dev/null
+++ b/win32/win32i64.c
@@ -0,0 +1,115 @@
+/*
+ win32/win32i64.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
+*/
+
+#include "../zip.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <time.h>
+#include <ctype.h>
+#include <windows.h>
+/* for LARGE_FILE_SUPPORT but may not be needed */
+#include <io.h>
+
+
+/* --------------------------------------------------- */
+/* Large File Support
+ *
+ * Initial functions by E. Gordon and R. Nausedat
+ * 9/10/2003
+ *
+ * These implement 64-bit file support for Windows. The
+ * defines and headers are in win32/osdep.h.
+ *
+ * These moved from win32.c by Mike White to avoid conflicts
+ * in WiZ of same name functions in UnZip and Zip libraries.
+ * 9/25/04 EG
+ */
+
+#if defined(LARGE_FILE_SUPPORT) && !defined(__CYGWIN__)
+
+/* 64-bit buffered ftello
+ *
+ * Win32 does not provide a 64-bit buffered
+ * ftell (in the published api anyway) so below provides
+ * hopefully close version.
+ * We have not gotten _telli64 to work with buffered
+ * streams. Below cheats by using fgetpos improperly and
+ * may not work on other ports.
+ */
+
+zoff_t zftello(stream)
+ FILE *stream;
+{
+ fpos_t fpos = 0;
+
+ if (fgetpos(stream, &fpos) != 0) {
+ return -1L;
+ } else {
+ return fpos;
+ }
+}
+
+
+/* 64-bit buffered fseeko
+ *
+ * Win32 does not provide a 64-bit buffered
+ * fseeko so use _lseeki64 and fflush. Note
+ * that SEEK_CUR can lose track of location
+ * if fflush is done between the last buffered
+ * io and this call.
+ */
+
+int zfseeko(stream, offset, origin)
+ FILE *stream;
+ zoff_t offset;
+ int origin;
+{
+ zoff_t location;
+
+ location = zftello(stream);
+ fflush(stream);
+ if (origin == SEEK_CUR) {
+ /* instead of synching up lseek easier just to figure and
+ use an absolute offset */
+ offset = location + offset;
+ location = _lseeki64(fileno(stream), offset, SEEK_SET);
+ } else {
+ location = _lseeki64(fileno(stream), offset, origin);
+ }
+ if (location == -1L) {
+ return -1L;
+ } else {
+ return 0;
+ }
+}
+#endif /* Win32 LARGE_FILE_SUPPORT */
+
+#if 0
+FILE* zfopen(filename,mode)
+char *filename;
+char *mode;
+{
+FILE* fTemp;
+
+ fTemp = fopen(filename,mode);
+ if( fTemp == NULL )
+ return NULL;
+
+ /* sorry, could not make VC60 and its rtl work properly without setting the file buffer to NULL. the */
+ /* problem seems to be _telli64 which seems to return the max stream position, comments are welcome */
+ setbuf(fTemp,NULL);
+
+ return fTemp;
+}
+#endif
+/* --------------------------------------------------- */
diff --git a/win32/win32zip.c b/win32/win32zip.c
index b9d5e2d..07c8886 100644
--- a/win32/win32zip.c
+++ b/win32/win32zip.c
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ win32/win32zip.c - Zip 3
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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 UTIL /* this file contains nothing used by UTIL */
@@ -21,6 +23,7 @@
#else
#include <utime.h>
#endif
+#define WIN32_LEAN_AND_MEAN
#include <windows.h> /* for findfirst/findnext stuff */
#ifdef __RSXNT__
# include "../win32/rsxntwin.h"
@@ -33,32 +36,61 @@
#define HIDD_SYS_BITS (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)
-typedef struct zdirent {
- ush d_date, d_time;
- ulg d_size;
- char d_attr;
- char d_name[MAX_PATH];
+#ifdef UNICODE_SUPPORT
+typedef struct zdirscanw {
+ HANDLE d_hFindFile;
int d_first;
+ WIN32_FIND_DATAW d_fdw;
+} zDIRSCANW;
+#endif
+
+typedef struct zdirscan {
HANDLE d_hFindFile;
-} zDIR;
+ int d_first;
+ WIN32_FIND_DATA d_fd;
+} zDIRSCAN;
+
+#define INVALID_WIN32_FILE_ATTRIBS ~0
+#ifdef UNICODE_SUPPORT
+#define GetDirAttribsW(d) ((d)->d_fdw.dwFileAttributes)
+#endif
+#define GetDirAttribs(d) ((d)->d_fd.dwFileAttributes)
#include "../win32/win32zip.h"
#include "../win32/nt.h"
/* Local functions */
-local zDIR *Opendir OF((ZCONST char *n));
-local struct zdirent *Readdir OF((zDIR *d));
-local void Closedir OF((zDIR *d));
+local zDIRSCAN * OpenDirScan OF((ZCONST char *n));
+local struct zdirscan * GetNextDirEntry OF((zDIRSCAN *d));
+local void CloseDirScan OF((zDIRSCAN *d));
+
+#ifdef UNICODE_SUPPORT
+local zDIRSCANW * OpenDirScanW OF((ZCONST wchar_t *wn));
+local struct zdirscanw * GetNextDirEntryW OF((zDIRSCANW *dw));
+local void CloseDirScanW OF((zDIRSCANW *dw));
+#endif
+
+local char *readd OF((zDIRSCAN *));
+#ifdef UNICODE_SUPPORT
+local wchar_t *readdw OF((zDIRSCANW *));
+#endif
-local char *readd OF((zDIR *));
local int wild_recurse OF((char *, char *));
+#ifdef UNICODE_SUPPORT
+local int wild_recursew OF((wchar_t *, wchar_t *));
+#endif
+
#ifdef NTSD_EAS
- local void GetSD OF((char *path, char **bufptr, size_t *size,
- char **cbufptr, size_t *csize));
+ local void GetSD OF((char *path, char **bufptr, ush *size,
+ char **cbufptr, ush *csize));
#endif
#ifdef USE_EF_UT_TIME
local int GetExtraTime OF((struct zlist far *z, iztimes *z_utim));
#endif
+local int procname_win32 OF((char *n, int caseflag, DWORD attribs));
+#ifdef UNICODE_SUPPORT
+local int procname_win32w OF((wchar_t *n, int caseflag, DWORD attribs));
+#endif
/* Module level variables */
extern char *label /* = NULL */ ; /* defined in fileio.c */
@@ -69,16 +101,64 @@ local time_t label_utim = 0;
/* Module level constants */
local ZCONST char wild_match_all[] = "*.*";
-local zDIR *Opendir(n)
+
+#ifdef UNICODE_SUPPORT
+
+local zDIRSCANW *OpenDirScanW(nw)
+ZCONST wchar_t *nw; /* directory to open */
+/* Start searching for files in the MSDOS directory n */
+{
+ zDIRSCANW *dw; /* malloc'd return value */
+ wchar_t *pw; /* malloc'd temporary string */
+ wchar_t *qw;
+ size_t i;
+
+ if ((dw = (zDIRSCANW *)malloc(sizeof(zDIRSCANW))) == NULL) {
+ return NULL;
+ }
+
+ if ((pw = (wchar_t *)malloc(wcslen(nw) * sizeof(wchar_t) +
+ (2 + sizeof(wild_match_all)) * sizeof(wchar_t))) == NULL) {
+ if (dw != NULL) free((zvoid *)dw);
+ return NULL;
+ }
+ wcscpy(pw, nw);
+
+ qw = pw + wcslen(pw);
+ if ((qw - pw) > 0 && wcschr(pw, (wchar_t)':') == (qw - 1))
+ *qw++ = (wchar_t)'.';
+ if ((qw - pw) > 0 && wcschr(pw, (wchar_t)'/') != (qw - 1))
+ *qw++ = (wchar_t)'/';
+
+ for (i = 0; i < strlen(wild_match_all); i++) {
+ qw[i] = (wchar_t)wild_match_all[i];
+ }
+ qw[i] = (wchar_t)'\0';
+
+ dw->d_hFindFile = FindFirstFileW(pw, &dw->d_fdw);
+ free((zvoid *)pw);
+
+ if (dw->d_hFindFile == INVALID_HANDLE_VALUE)
+ {
+ free((zvoid *)dw);
+ return NULL;
+ }
+
+ dw->d_first = 1;
+ return dw;
+}
+
+#endif
+
+local zDIRSCAN *OpenDirScan(n)
ZCONST char *n; /* directory to open */
/* Start searching for files in the MSDOS directory n */
{
- zDIR *d; /* malloc'd return value */
+ zDIRSCAN *d; /* malloc'd return value */
char *p; /* malloc'd temporary string */
char *q;
- WIN32_FIND_DATA fd;
- if ((d = (zDIR *)malloc(sizeof(zDIR))) == NULL ||
+ if ((d = (zDIRSCAN *)malloc(sizeof(zDIRSCAN))) == NULL ||
(p = malloc(strlen(n) + (2 + sizeof(wild_match_all)))) == NULL) {
if (d != NULL) free((zvoid *)d);
return NULL;
@@ -91,10 +171,10 @@ ZCONST char *n; /* directory to open */
*q++ = '/';
strcpy(q, wild_match_all);
-#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
OemToAnsi(p, p);
#endif
- d->d_hFindFile = FindFirstFile(p, &fd);
+ d->d_hFindFile = FindFirstFile(p, &d->d_fd);
free((zvoid *)p);
if (d->d_hFindFile == INVALID_HANDLE_VALUE)
@@ -103,53 +183,433 @@ ZCONST char *n; /* directory to open */
return NULL;
}
- strcpy(d->d_name, fd.cFileName);
- d->d_attr = (unsigned char) fd.dwFileAttributes;
d->d_first = 1;
return d;
}
-local struct zdirent *Readdir(d)
-zDIR *d; /* directory stream to read from */
+
+#ifdef UNICODE_SUPPORT
+
+local struct zdirscanw *GetNextDirEntryW(dw)
+zDIRSCANW *dw; /* directory stream to read from */
+/* Return pointer to first or next directory entry, or NULL if end. */
+{
+ if (dw->d_first)
+ dw->d_first = 0;
+ else
+ {
+ if (!FindNextFileW(dw->d_hFindFile, &dw->d_fdw))
+ return NULL;
+ }
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ CharToOemW(dw->d_fdw.cFileName, dw->d_fdw.cFileName);
+#endif
+ return (struct zdirscanw *)dw;
+}
+
+#endif
+
+local struct zdirscan *GetNextDirEntry(d)
+zDIRSCAN *d; /* directory stream to read from */
/* Return pointer to first or next directory entry, or NULL if end. */
{
if (d->d_first)
d->d_first = 0;
else
{
- WIN32_FIND_DATA fd;
-
- if (!FindNextFile(d->d_hFindFile, &fd))
+ if (!FindNextFile(d->d_hFindFile, &d->d_fd))
return NULL;
- strcpy(d->d_name, fd.cFileName);
- d->d_attr = (unsigned char) fd.dwFileAttributes;
}
-#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
- AnsiToOem(d->d_name, d->d_name);
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ AnsiToOem(d->d_fd.cFileName, d->d_fd.cFileName);
#endif
- return (struct zdirent *)d;
+ return (struct zdirscan *)d;
}
-local void Closedir(d)
-zDIR *d; /* directory stream to close */
+local void CloseDirScan(d)
+zDIRSCAN *d; /* directory stream to close */
{
FindClose(d->d_hFindFile);
free((zvoid *)d);
}
+#ifdef UNICODE_SUPPORT
+
+local void CloseDirScanW(dw)
+zDIRSCANW *dw; /* directory stream to close */
+{
+ FindClose(dw->d_hFindFile);
+ free((zvoid *)dw);
+}
+
+#endif
+
+
+#ifdef UNICODE_SUPPORT
+
+local wchar_t *readdw(dw)
+ zDIRSCANW *dw; /* directory stream to read from */
+/* Return a pointer to the next name in the directory stream dw, or NULL if
+ no more entries or an error occurs. */
+{
+ struct zdirscanw *ew;
+
+ do
+ ew = GetNextDirEntryW(dw);
+ while (ew &&
+ ((!hidden_files && ew->d_fdw.dwFileAttributes & HIDD_SYS_BITS) ||
+ (only_archive_set &&
+ !(ew->d_fdw.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) &&
+ !(ew->d_fdw.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))));
+ if (ew == NULL)
+ return (wchar_t *) NULL;
+ return ew->d_fdw.cFileName;
+}
+
+#endif
local char *readd(d)
-zDIR *d; /* directory stream to read from */
+zDIRSCAN *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 zdirent *e;
+ struct zdirscan *e;
do
- e = Readdir(d);
- while (!hidden_files && e && e->d_attr & HIDD_SYS_BITS);
- return e == NULL ? (char *) NULL : e->d_name;
+ e = GetNextDirEntry(d);
+ while (e &&
+ ((!hidden_files && e->d_fd.dwFileAttributes & HIDD_SYS_BITS) ||
+ (only_archive_set &&
+ !(e->d_fd.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) &&
+ !(e->d_fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))));
+ /* When a wide character that is not supported by the current character
+ set is found, FindFirstFile and FindNextFile return a "?" in that spot.
+ A question mark is illegal in file names, so this flags that something
+ needs to be done. It seems the fix is to use the 8.3 name in
+ this case, as that allows directory scans to continue.
+ */
+ if (e == NULL)
+ return (char *) NULL;
+ if (strchr(e->d_fd.cFileName, '?') && e->d_fd.cAlternateFileName) {
+ /* Have '?' in name, assume wide character we can't handle is in
+ the name and use short name if there is one.
+ */
+ return e->d_fd.cAlternateFileName;
+ }
+ return e->d_fd.cFileName;
+}
+
+
+#if 0
+/* scan for the file in p and return Windows long name */
+char *get_win32_longpath(p, n)
+ char *p; /* path to get short name path for */
+ char **n; /* pointer to name in returned path */
+{
+ char *q; /* return string */
+ char *c;
+ int is_dir = 0;
+ char *f;
+ char *fp;
+ int nr;
+ int fplen;
+ int fplen2;
+ HANDLE d_hFindFile;
+ WIN32_FIND_DATA d_fd;
+ int slashes = 0;
+ int returnslashes = 0;
+
+ if (p == NULL)
+ return NULL;
+
+ /* count path components */
+ for (f = p; *f; f++) {
+ if (*f == '/' || *f == '\\') {
+ slashes++;
+ }
+ }
+ /* Ignore trailing slash */
+ if (*p && (*(f - 1) == '/' || *(f - 1) == '\\'))
+ slashes--;
+
+ /* get the length of the full path */
+ fplen = GetFullPathName(p, 0, NULL, NULL);
+
+ if ((fp = malloc(fplen + 1)) == NULL) {
+ return NULL;
+ }
+ /* get full path */
+ fplen2 = GetFullPathName(p, fplen, fp, &f);
+ if (fplen2 > fplen) {
+ /* something changed */
+ free(fp);
+ return NULL;
+ }
+ c = fp + strlen(fp) - 1;
+ if (*c == '\\' || *c == '/') {
+ is_dir = 1;
+ *c = '\0';
+ }
+
+ d_hFindFile = FindFirstFile(fp, &d_fd);
+ free(fp);
+
+ if (d_hFindFile == INVALID_HANDLE_VALUE)
+ {
+ return NULL;
+ }
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ AnsiToOem(d->d_fd.cFileName, d->d_fd.cFileName);
+#endif
+
+ FindClose(d_hFindFile);
+
+ if (d_fd.cFileName == NULL) {
+ return NULL;
+ }
+
+ /* get the length of the full path */
+ fplen = GetFullPathName(d_fd.cFileName, 0, NULL, NULL);
+
+ if ((fp = malloc(fplen + 1)) == NULL) {
+ return NULL;
+ }
+ /* get full path */
+ fplen2 = GetFullPathName(d_fd.cFileName, fplen, fp, &f);
+ if (fplen2 > fplen) {
+ /* something changed */
+ free(fp);
+ return NULL;
+ }
+
+ /* characters from end to start of last component */
+ nr = 0;
+
+ /* find start of relative path we came in with */
+ for (f = fp + strlen(fp); f != fp; f--) {
+ if (*f == ':')
+ break;
+ if (*f == '/' || *f == '\\') {
+ returnslashes++;
+ /* convert \ to / */
+ *f = '/';
+ if (nr == 0)
+ /* first slash from end */
+ nr = strlen(fp) - (f - fp);
+ if (returnslashes > slashes)
+ break;
+ }
+ if (*f == '\\' && *(f + 1) == '\\')
+ break;
+ }
+ if (f != fp)
+ /* on slash in middle */
+ f++;
+
+ if ((q = malloc(strlen(f) + 2)) == NULL) {
+ return NULL;
+ }
+ strcpy(q, f);
+ *n = q + (strlen(q) - nr + 1);
+ if (is_dir) {
+ strcat(q, "/");
+ }
+ free(fp);
+
+ return q;
}
+#endif
+
+
+#if 0
+/* scan for the file in p and return Windows UTF-8 name */
+char *get_win32_utf8path(p)
+ char *p; /* path to get utf-8 name for */
+{
+ char *q; /* return string */
+ char *r = NULL;
+ int is_dir = 0;
+ char *f;
+ char *fcp;
+ char *fp;
+ wchar_t *qw;
+ char *lastc = '\0';
+ int fplen;
+ int fplen2;
+ int ulen;
+ int ulenw;
+ HANDLE d_hFindFile;
+ WIN32_FIND_DATAW d_fd;
+ int pathslashes = 0;
+ int componentslashes = 0;
+ int slashes = 0;
+
+ if (p == NULL)
+ return NULL;
+
+ /* count path components */
+ for (f = p; *f; PREINCSTR(f)) {
+ if (*f == '/' || *f == '\\') {
+ slashes++;
+ }
+ lastc = f;
+ }
+ /* do not count trailing / */
+ if (*lastc == '/' || *lastc == '\\') {
+ is_dir = 1;
+ slashes--;
+ }
+
+ /* Get the short path (as a bad long path could cause FindFirstFile to fail) */
+
+ /* get the length of the short path */
+ fplen = GetShortPathName(p, NULL, 0);
+
+ if ((fp = malloc(fplen + 1)) == NULL) {
+ return NULL;
+ }
+ /* get short path */
+ fplen2 = GetShortPathName(p, fp, fplen);
+ if (fplen2 > fplen) {
+ /* something changed */
+ free(fp);
+ return NULL;
+ }
+
+ for (pathslashes = 0; pathslashes <= slashes; pathslashes++)
+ {
+
+ /* get component path */
+ if ((fcp = malloc(fplen + 1)) == NULL) {
+ return NULL;
+ }
+ strcpy(fcp, fp);
+ componentslashes = 0;
+ for (f = fcp; *f; PREINCSTR(f)) {
+ if (*f == '/' || *f == '\\') {
+ componentslashes++;
+ if (componentslashes > pathslashes)
+ break;
+ }
+ lastc = f;
+ }
+ *f = '\0';
+
+
+ /* Get information for the file, including wide path */
+
+ /* get length */
+ ulenw = MultiByteToWideChar(
+ CP_ACP, /* ANSI code page */
+ 0, /* flags for character-type options */
+ fcp, /* string to convert */
+ -1, /* string length (-1 = NULL terminated) */
+ NULL, /* buffer */
+ 0 ); /* buffer length (0 = return length) */
+ if (ulenw == 0) {
+ /* failed */
+ free(fcp);
+ free(fp);
+ return NULL;
+ }
+ ulenw++;
+ /* get length in bytes */
+ ulen = sizeof(wchar_t) * (ulenw + 1);
+ if ((qw = (wchar_t *)malloc(ulen + 1)) == NULL) {
+ free(fcp);
+ free(fp);
+ return NULL;
+ }
+ /* convert multibyte to wide */
+ ulen = MultiByteToWideChar(
+ CP_ACP, /* ANSI code page */
+ 0, /* flags for character-type options */
+ fcp, /* string to convert */
+ -1, /* string length (-1 = NULL terminated) */
+ qw, /* buffer */
+ ulenw); /* buffer length (0 = return length) */
+ if (ulen == 0) {
+ /* failed */
+ free(qw);
+ free(fcp);
+ free(fp);
+ return 0;
+ }
+
+ d_hFindFile = FindFirstFileW(qw, &d_fd);
+ /* If this Win32 platform does not support Unicode wide paths
+ this returns INVALID_HANDLE_VALUE and the OS error is
+ "No such file or directory". We return NULL and go with
+ the UTF-8 version of z->iname in f->uname.
+ */
+ free(qw);
+ free(fcp);
+ FindClose(d_hFindFile);
+
+ if (d_hFindFile == INVALID_HANDLE_VALUE)
+ {
+ return NULL;
+ }
+
+ /* Get buffer length */
+ ulen = WideCharToMultiByte(
+ CP_UTF8, /* UTF-8 code page */
+ 0, /* flags */
+ d_fd.cFileName, /* string to convert */
+ -1, /* input chars (-1 = NULL terminated) */
+ NULL, /* buffer */
+ 0, /* size of buffer (0 = return needed size) */
+ NULL, /* default char */
+ NULL); /* used default char */
+ if (ulen == 0) {
+ /* failed */
+ return NULL;
+ }
+ ulen += 2;
+ if ((q = malloc(ulen + 1)) == NULL) {
+ return NULL;
+ }
+
+ /* Convert the Unicode string to UTF-8 */
+ if ((ulen = WideCharToMultiByte(
+ CP_UTF8, /* UTF-8 code page */
+ 0, /* flags */
+ d_fd.cFileName, /* string to convert */
+ -1, /* input chars (-1 = NULL terminated) */
+ q, /* buffer */
+ ulen, /* size of buffer (0 = return needed size) */
+ NULL, /* default char */
+ NULL)) == 0) /* used default char */
+ {
+ free(fp);
+ free(q);
+ return NULL;
+ }
+
+ if (r == NULL) {
+ /* first one */
+ r = q;
+ } else {
+ if ((r = realloc(r, strlen(r) + strlen(q) + 3)) == NULL) {
+ free(fp);
+ free(q);
+ return NULL;
+ }
+ strcat(r, "/");
+ strcat(r, q);
+ free(q);
+ }
+ }
+
+ free(fp);
+
+ if (is_dir) {
+ strcat(r, "/");
+ }
+
+ return r;
+}
+#endif
#define ONENAMELEN 255
@@ -157,18 +617,254 @@ zDIR *d; /* directory stream to read from */
/* whole is a pathname with wildcards, wildtail points somewhere in the */
/* middle of it. All wildcards to be expanded must come AFTER wildtail. */
+
+#ifdef UNICODE_SUPPORT
+
+wchar_t *local_to_wchar_string(local_string)
+ char *local_string; /* path to get utf-8 name for */
+{
+ wchar_t *qw;
+ int ulen;
+ int ulenw;
+
+ if (local_string == NULL)
+ return NULL;
+
+ /* get length */
+ ulenw = MultiByteToWideChar(
+ CP_ACP, /* ANSI code page */
+ 0, /* flags for character-type options */
+ local_string, /* string to convert */
+ -1, /* string length (-1 = NULL terminated) */
+ NULL, /* buffer */
+ 0 ); /* buffer length (0 = return length) */
+ if (ulenw == 0) {
+ /* failed */
+ return NULL;
+ }
+ ulenw++;
+ /* get length in bytes */
+ ulen = sizeof(wchar_t) * (ulenw + 1);
+ if ((qw = (wchar_t *)malloc(ulen + 1)) == NULL) {
+ return NULL;
+ }
+ /* convert multibyte to wide */
+ ulen = MultiByteToWideChar(
+ CP_ACP, /* ANSI code page */
+ 0, /* flags for character-type options */
+ local_string, /* string to convert */
+ -1, /* string length (-1 = NULL terminated) */
+ qw, /* buffer */
+ ulenw); /* buffer length (0 = return length) */
+ if (ulen == 0) {
+ /* failed */
+ free(qw);
+ return NULL;
+ }
+
+ return qw;
+}
+
+
+wchar_t *utf8_to_wchar_string(utf8_string)
+ char *utf8_string; /* path to get utf-8 name for */
+{
+ wchar_t *qw;
+ int ulen;
+ int ulenw;
+
+ if (utf8_string == NULL)
+ return NULL;
+
+ /* get length */
+ ulenw = MultiByteToWideChar(
+ CP_UTF8, /* UTF-8 code page */
+ 0, /* flags for character-type options */
+ utf8_string, /* string to convert */
+ -1, /* string length (-1 = NULL terminated) */
+ NULL, /* buffer */
+ 0 ); /* buffer length (0 = return length) */
+ if (ulenw == 0) {
+ /* failed */
+ return NULL;
+ }
+ ulenw++;
+ /* get length in bytes */
+ ulen = sizeof(wchar_t) * (ulenw + 1);
+ if ((qw = (wchar_t *)malloc(ulen + 1)) == NULL) {
+ return NULL;
+ }
+ /* convert multibyte to wide */
+ ulen = MultiByteToWideChar(
+ CP_UTF8, /* UTF-8 code page */
+ 0, /* flags for character-type options */
+ utf8_string, /* string to convert */
+ -1, /* string length (-1 = NULL terminated) */
+ qw, /* buffer */
+ ulenw); /* buffer length (0 = return length) */
+ if (ulen == 0) {
+ /* failed */
+ free(qw);
+ return NULL;
+ }
+
+ return qw;
+}
+
+
+
+/* Convert wchar_t string to utf8 using Windows calls
+ so any characters needing more than one wchar_t are
+ are handled by Windows */
+char *wchar_to_utf8_string(wstring)
+ wchar_t *wstring;
+{
+ char *q; /* return string */
+ int ulen;
+
+ if (wstring == NULL)
+ return NULL;
+
+ /* Get buffer length */
+ ulen = WideCharToMultiByte(
+ CP_UTF8, /* UTF-8 code page */
+ 0, /* flags */
+ wstring, /* string to convert */
+ -1, /* input chars (-1 = NULL terminated) */
+ NULL, /* buffer */
+ 0, /* size of buffer (0 = return needed size) */
+ NULL, /* default char */
+ NULL); /* used default char */
+ if (ulen == 0) {
+ /* failed */
+ return NULL;
+ }
+ ulen += 2;
+ if ((q = malloc(ulen + 1)) == NULL) {
+ return NULL;
+ }
+
+ /* Convert the Unicode string to UTF-8 */
+ if ((ulen = WideCharToMultiByte(
+ CP_UTF8, /* UTF-8 code page */
+ 0, /* flags */
+ wstring, /* string to convert */
+ -1, /* input chars (-1 = NULL terminated) */
+ q, /* buffer */
+ ulen, /* size of buffer (0 = return needed size) */
+ NULL, /* default char */
+ NULL)) == 0) /* used default char */
+ {
+ free(q);
+ return NULL;
+ }
+
+ return q;
+}
+
+
+local int wild_recursew(whole, wildtail)
+ wchar_t *whole;
+ wchar_t *wildtail;
+{
+ zDIRSCANW *dirw;
+ wchar_t *subwild, *name, *newwhole = NULL, *glue = NULL, plug = 0, plug2;
+ extent newlen;
+ int amatch = 0, e = ZE_MISS;
+
+ if (!isshexpw(wildtail)) {
+ if (GetFileAttributesW(whole) != 0xFFFFFFFF) { /* file exists? */
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ CharToOemW(whole, whole);
+#endif
+ return procnamew(whole, 0);
+ }
+ else
+ return ZE_MISS; /* woops, no wildcards! */
+ }
+
+ /* back up thru path components till existing dir found */
+ do {
+ name = wildtail + wcslen(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;
+ dirw = OpenDirScanW(whole);
+ } while (!dirw && subwild > wildtail);
+ wildtail = subwild; /* skip past non-wild components */
+
+ if ((subwild = wcschr(wildtail + 1, PATH_END)) != NULL) {
+ /* this "+ 1" dodges the ^^^ hole left by *glue == 0 */
+ *(subwild++) = 0; /* wildtail = one component pattern */
+ newlen = wcslen(whole) + wcslen(subwild) + (ONENAMELEN + 2);
+ } else
+ newlen = wcslen(whole) + (ONENAMELEN + 1);
+ if (!dirw || ((newwhole = malloc(newlen * sizeof(wchar_t))) == NULL)) {
+ if (glue)
+ *glue = plug;
+ e = dirw ? ZE_MEM : ZE_MISS;
+ goto ohforgetit;
+ }
+ wcscpy(newwhole, whole);
+ newlen = wcslen(newwhole);
+ if (glue)
+ *glue = plug; /* repair damage to whole */
+ if (!isshexpw(wildtail)) {
+ e = ZE_MISS; /* non-wild name not found */
+ goto ohforgetit;
+ }
+
+ while ((name = readdw(dirw)) != NULL) {
+ if (wcscmp(name, L".") && wcscmp(name, L"..") &&
+ MATCHW(wildtail, name, 0)) {
+ wcscpy(newwhole + newlen, name);
+ if (subwild) {
+ name = newwhole + wcslen(newwhole);
+ *(name++) = (wchar_t)PATH_END;
+ wcscpy(name, subwild);
+ e = wild_recursew(newwhole, name);
+ } else
+ e = procname_win32w(newwhole, 0, GetDirAttribsW(dirw));
+ newwhole[newlen] = 0;
+ if (e == ZE_OK)
+ amatch = 1;
+ else if (e != ZE_MISS)
+ break;
+ }
+ }
+
+ ohforgetit:
+ if (dirw) CloseDirScanW(dirw);
+ if (subwild) *--subwild = PATH_END;
+ if (newwhole) free(newwhole);
+ if (e == ZE_MISS && amatch)
+ e = ZE_OK;
+ return e;
+}
+
+#endif
+
+
local int wild_recurse(whole, wildtail)
-char *whole;
-char *wildtail;
+ char *whole;
+ char *wildtail;
{
- zDIR *dir;
+ zDIRSCAN *dir;
char *subwild, *name, *newwhole = NULL, *glue = NULL, plug = 0, plug2;
extent newlen;
int amatch = 0, e = ZE_MISS;
if (!isshexp(wildtail)) {
if (GetFileAttributes(whole) != 0xFFFFFFFF) { /* file exists? */
-#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
AnsiToOem(whole, whole);
#endif
return procname(whole, 0);
@@ -191,7 +887,7 @@ char *wildtail;
*glue = plug;
glue = subwild;
plug = plug2;
- dir = Opendir(whole);
+ dir = OpenDirScan(whole);
} while (!dir && subwild > wildtail);
wildtail = subwild; /* skip past non-wild components */
@@ -226,7 +922,7 @@ char *wildtail;
strcpy(name, subwild);
e = wild_recurse(newwhole, name);
} else
- e = procname(newwhole, 0);
+ e = procname_win32(newwhole, 0, GetDirAttribs(dir));
newwhole[newlen] = 0;
if (e == ZE_OK)
amatch = 1;
@@ -236,7 +932,7 @@ char *wildtail;
}
ohforgetit:
- if (dir) Closedir(dir);
+ if (dir) CloseDirScan(dir);
if (subwild) *--subwild = PATH_END;
if (newwhole) free(newwhole);
if (e == ZE_MISS && amatch)
@@ -244,14 +940,53 @@ char *wildtail;
return e;
}
+
+#ifdef UNICODE_SUPPORT
+int has_win32_wide() {
+ DWORD r;
+
+ /* test if we have wide function support */
+
+ /* check if already set */
+ if (no_win32_wide != -1)
+ return !no_win32_wide;
+
+ /* assume we don't */
+ no_win32_wide = 1;
+
+ /* get attributes for this directory */
+ r = GetFileAttributes(".");
+
+ /* r should be 16 = FILE_ATTRIBUTE_DIRECTORY */
+ if (r == FILE_ATTRIBUTE_DIRECTORY) {
+ /* now see if it works for the wide version */
+ r = GetFileAttributesW(L".");
+ /* if this fails then we probably don't have wide functions */
+ if (r == 0xFFFFFFFF) {
+ /* error is probably "This function is only valid in Win32 mode." */
+ } else if (r == FILE_ATTRIBUTE_DIRECTORY) {
+ /* worked, so assume we have wide support */
+ no_win32_wide = 0;
+ }
+ }
+
+ return !no_win32_wide;
+}
+#endif
+
+
int wild(w)
-char *w; /* path/pattern to match */
+ 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 */
+ char *p; /* path */
+ char *q; /* diskless path */
+ int e; /* result */
+#ifdef UNICODE_SUPPORT
+ wchar_t *pw; /* wide path */
+ wchar_t *qw; /* wide diskless path */
+#endif
if (volume_label == 1) {
volume_label = 2;
@@ -278,6 +1013,36 @@ char *w; /* path/pattern to match */
if (*q == '\\')
*q = '/';
+#ifdef UNICODE_SUPPORT
+ if (!no_win32_wide) {
+ /* wide char version */
+ pw = local_to_wchar_string(p);
+
+ /* Separate the disk part of the path */
+ if ((qw = wcschr(pw, ':')) != NULL) {
+ if (wcschr(++qw, ':')) /* sanity check for safety of wild_recurse */
+ return ZE_MISS;
+ } else
+ qw = pw;
+
+ /* Normalize bare disk names */
+ if (qw > pw && !*qw)
+ wcscpy(qw, L".");
+ } else {
+ /* multibyte version */
+ /* Separate the disk part of the path */
+ if ((q = MBSCHR(p, ':')) != NULL) {
+ if (MBSCHR(++q, ':')) /* sanity check for safety of wild_recurse */
+ return ZE_MISS;
+ } else
+ q = p;
+
+ /* Normalize bare disk names */
+ if (q > p && !*q)
+ strcpy(q, ".");
+ }
+#else
+ /* multibyte version */
/* Separate the disk part of the path */
if ((q = MBSCHR(p, ':')) != NULL) {
if (MBSCHR(++q, ':')) /* sanity check for safety of wild_recurse */
@@ -288,29 +1053,56 @@ char *w; /* path/pattern to match */
/* Normalize bare disk names */
if (q > p && !*q)
strcpy(q, ".");
+#endif
/* Here we go */
+#ifdef UNICODE_SUPPORT
+ if (!no_win32_wide) {
+ /* use wide Unicode directory scan */
+ e = wild_recursew(pw, qw);
+
+ free(pw);
+ } else {
+ /* use multibyte directory scan */
+ e = wild_recurse(p, q);
+ }
+#else
e = wild_recurse(p, q);
+#endif
free((zvoid *)p);
return e;
}
-int procname(n, caseflag)
-char *n; /* name to process */
-int caseflag; /* true to force case-sensitive match */
+
+local int procname_win32(n, caseflag, attribs)
+ char *n; /* name to process */
+ int caseflag; /* true to force case-sensitive match */
+ DWORD attribs;
/* 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 */
- zDIR *d; /* directory stream from opendir() */
+ zDIRSCAN *d; /* directory stream from OpenDirScan() */
char *e; /* pointer to name from readd() */
int m; /* matched flag */
char *p; /* path for recursion */
- struct stat s; /* result of stat() */
+ z_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 (attribs != INVALID_WIN32_FILE_ATTRIBS)
+ {
+ /* 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 & FILE_ATTRIBUTE_DIRECTORY) ? S_IFDIR : S_IFREG);
+ }
else if (LSSTAT(n, &s)
#ifdef __TURBOC__
/* For this compiler, stat() succeeds on wild card names! */
@@ -320,6 +1112,9 @@ int caseflag; /* true to force case-sensitive match */
#endif
)
{
+#ifdef UNICODE_SUPPORT
+ char *uname = NULL;
+#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;
@@ -329,10 +1124,40 @@ int caseflag; /* true to force case-sensitive match */
z->mark = pcount ? filter(z->zname, caseflag) : 1;
if (verbose)
fprintf(mesg, "zip diagnostic: %scluding %s\n",
- z->mark ? "in" : "ex", z->name);
+ 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.
+ */
+ uname = z->wuname;
+#else
+ uname = z->zuname;
+#endif
+ if (MATCH(p, uname, caseflag))
+ {
+ z->mark = pcount ? filter(uname, 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;
}
@@ -343,12 +1168,22 @@ int caseflag; /* true to force case-sensitive match */
*p = '/';
if ((s.st_mode & S_IFDIR) == 0)
{
- /* add or remove name of file */
- if ((m = newname(n, 0, caseflag)) != ZE_OK)
- return m;
+ /* add exclusions in directory recurse but ignored for single file */
+ DWORD dwAttr;
+
+ dwAttr = GetFileMode(n);
+
+ if ((hidden_files ||
+ !(dwAttr & FILE_ATTRIBUTE_HIDDEN || dwAttr & FILE_ATTRIBUTE_SYSTEM)) &&
+ (!only_archive_set || (dwAttr & FILE_ATTRIBUTE_ARCHIVE)))
+ {
+ /* 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)
+ if ((p = (char *) 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 */
@@ -363,19 +1198,20 @@ int caseflag; /* true to force case-sensitive match */
}
}
/* recurse into directory */
- if (recurse && (d = Opendir(n)) != NULL)
+ if (recurse && (d = OpenDirScan(n)) != NULL)
{
while ((e = readd(d)) != NULL) {
if (strcmp(e, ".") && strcmp(e, ".."))
{
if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL)
{
- Closedir(d);
+ CloseDirScan(d);
free((zvoid *)p);
return ZE_MEM;
}
strcat(strcpy(a, p), e);
- if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */
+ if ((m = procname_win32(a, caseflag, GetDirAttribs(d)))
+ != ZE_OK) /* recurse on name */
{
if (m == ZE_MISS)
zipwarn("name not matched: ", a);
@@ -385,17 +1221,185 @@ int caseflag; /* true to force case-sensitive match */
free((zvoid *)a);
}
}
- Closedir(d);
+ CloseDirScan(d);
}
free((zvoid *)p);
} /* (s.st_mode & S_IFDIR) == 0) */
return ZE_OK;
}
+
+#ifdef UNICODE_SUPPORT
+local int procname_win32w(nw, caseflag, attribs)
+ wchar_t *nw; /* name to process */
+ int caseflag; /* true to force case-sensitive match */
+ DWORD attribs;
+/* Process a name or sh expression to operate on (or exclude). Return
+ an error code in the ZE_ class. */
+{
+ wchar_t *aw; /* path and name for recursion */
+ zDIRSCANW *dw; /* directory stream from OpenDirScan() */
+ wchar_t *ew; /* pointer to name from readd() */
+ int m; /* matched flag */
+ wchar_t *pw; /* path for recursion */
+ zw_stat s; /* result of stat() */
+ struct zlist far *z; /* steps through zfiles list */
+
+ if (wcscmp(nw, L"-") == 0) /* if compressing stdin */
+ return newnamew(nw, 0, caseflag);
+ else if (attribs != INVALID_WIN32_FILE_ATTRIBS)
+ {
+ /* 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 & FILE_ATTRIBUTE_DIRECTORY) ? S_IFDIR : S_IFREG);
+ }
+ else if (LSSTATW(nw, &s)
+#ifdef __TURBOC__
+ /* For this compiler, stat() succeeds on wild card names! */
+ /* Unfortunately, this causes failure on names containing */
+ /* square bracket characters, which are legal in win32. */
+ || isshexpw(nw)
+#endif
+ )
+ {
+ wchar_t *unamew = NULL;
+ /* Not a file or directory--search for shell expression in zip file */
+ pw = ex2inw(nw, 0, (int *)NULL); /* shouldn't affect matching chars */
+ m = 1;
+ for (z = zfiles; z != NULL; z = z->nxt) {
+ if (MATCHW(pw, z->znamew, 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;
+ }
+ }
+ /* also check escaped Unicode names */
+ for (z = zfiles; z != NULL; z = z->nxt) {
+ if (z->zuname) {
+ unamew = z->znamew;
+ if (MATCHW(pw, unamew, caseflag))
+ {
+ z->mark = pcount ? filter(z->iname, 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;
+ }
+ }
+ }
+ free((zvoid *)pw);
+ return m ? ZE_MISS : ZE_OK;
+ }
+
+ /* Live name--use if file, recurse if directory */
+ for (pw = nw; *pw; pw++) /* use / consistently */
+ if (*pw == (wchar_t)'\\')
+ *pw = (wchar_t)'/';
+ if ((s.st_mode & S_IFDIR) == 0)
+ {
+ /* add exclusions in directory recurse but ignored for single file */
+ DWORD dwAttr;
+
+ dwAttr = GetFileModeW(nw);
+
+ if ((hidden_files ||
+ !(dwAttr & FILE_ATTRIBUTE_HIDDEN || dwAttr & FILE_ATTRIBUTE_SYSTEM)) &&
+ (!only_archive_set || (dwAttr & FILE_ATTRIBUTE_ARCHIVE)))
+ {
+ /* add or remove name of file */
+ if ((m = newnamew(nw, 0, caseflag)) != ZE_OK)
+ return m;
+ }
+ } else {
+ /* Add trailing / to the directory name */
+ pw = (wchar_t *)malloc( (wcslen(nw)+2) * sizeof(wchar_t) );
+ if (pw == NULL)
+ return ZE_MEM;
+ if (wcscmp(nw, L".") == 0 || wcscmp(nw, L"/.") == 0) {
+ *pw = (wchar_t)'\0'; /* avoid "./" prefix and do not create zip entry */
+ } else {
+ wcscpy(pw, nw);
+ aw = pw + wcslen(pw);
+ if (pw[wcslen(pw) - 1] != (wchar_t)'/')
+ wcscpy(aw, L"/");
+ if (dirnames && (m = newnamew(pw, 1, caseflag)) != ZE_OK) {
+ free((zvoid *)pw);
+ return m;
+ }
+ }
+ /* recurse into directory */
+ if (recurse && (dw = OpenDirScanW(nw)) != NULL)
+ {
+ while ((ew = readdw(dw)) != NULL) {
+ if (wcscmp(ew, L".") && wcscmp(ew, L".."))
+ {
+ if ((aw = malloc((wcslen(pw) + wcslen(ew) + 1) * sizeof(wchar_t))) == NULL)
+ {
+ CloseDirScanW(dw);
+ free((zvoid *)pw);
+ return ZE_MEM;
+ }
+ wcscat(wcscpy(aw, pw), ew);
+ if ((m = procname_win32w(aw, caseflag, GetDirAttribsW(dw)))
+ != ZE_OK) /* recurse on name */
+ {
+ char *a;
+ char *ad;
+
+ a = wchar_to_local_string(aw);
+ ad = local_to_display_string(a);
+
+ if (m == ZE_MISS)
+ zipwarn("name not matched: ", ad);
+ else
+ ziperr(m, a);
+ free(ad);
+ free(a);
+ }
+ free((zvoid *)aw);
+ }
+ }
+ CloseDirScanW(dw);
+ }
+ free((zvoid *)pw);
+ } /* (s.st_mode & S_IFDIR) == 0) */
+ return ZE_OK;
+}
+#endif
+
+
+#ifdef UNICODE_SUPPORT
+int procnamew(nw, caseflag)
+ wchar_t *nw; /* name to process */
+ int caseflag; /* true to force case-sensitive match */
+{
+ return procname_win32w(nw, caseflag, INVALID_WIN32_FILE_ATTRIBS);
+}
+#endif
+
+int procname(n, caseflag)
+ char *n; /* name to process */
+ int caseflag; /* true to force case-sensitive match */
+{
+ return procname_win32(n, caseflag, INVALID_WIN32_FILE_ATTRIBS);
+}
+
char *ex2in(x, isdir, pdosflag)
-char *x; /* external file name */
-int isdir; /* input: x is a directory */
-int *pdosflag; /* output: force MSDOS file attributes? */
+ 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. */
{
@@ -426,7 +1430,7 @@ int *pdosflag; /* output: force MSDOS file attributes? */
INCSTR(n); /* strip `share' name */
}
if (*n != '\0')
- t = n + CLEN(n);
+ t = n + MB_CLEN(n);
}
/* Strip leading "/" to convert an absolute path into a relative path */
while (*t == '/' || *t == '\\')
@@ -454,33 +1458,121 @@ int *pdosflag; /* output: force MSDOS file attributes? */
/* Returned malloc'ed name */
if (pdosflag)
*pdosflag = dosflag;
-#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
OemToAnsi(n, n);
#endif
return n;
}
+#ifdef UNICODE_SUPPORT
+wchar_t *ex2inw(xw, isdir, pdosflag)
+ wchar_t *xw; /* 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. */
+{
+ wchar_t *nw; /* internal file name (malloc'ed) */
+ wchar_t *tw; /* shortened name */
+ int dosflag;
+
+
+ dosflag = dosify || IsFileSystemOldFATW(xw);
+ if (!dosify && use_longname_ea && (tw = GetLongPathEAW(xw)) != NULL)
+ {
+ xw = tw;
+ dosflag = 0;
+ }
+
+ /* Find starting point in name before doing malloc */
+ /* Strip drive specification */
+ tw = *xw && iswascii(*xw) && *(xw + 1) == (wchar_t)':' ? xw + 2 : xw;
+ /* Strip "//host/share/" part of a UNC name */
+ if ((!wcsncmp(xw,L"//",2) || !wcsncmp(xw,L"\\\\",2)) &&
+ (xw[2] != (wchar_t)'\0' && xw[2] != (wchar_t)'/' && xw[2] != (wchar_t)'\\')) {
+ nw = xw + 2;
+ while (*nw != (wchar_t)'\0' && *nw != (wchar_t)'/' && *nw != (wchar_t)'\\')
+ nw++; /* strip host name */
+ if (*nw != (wchar_t)'\0') {
+ nw++;
+ while (*nw != (wchar_t)'\0' && *nw != (wchar_t)'/' && *nw != (wchar_t)'\\')
+ nw++; /* strip `share' name */
+ }
+ if (*nw != (wchar_t)'\0')
+ tw = nw++;
+ }
+ /* Strip leading "/" to convert an absolute path into a relative path */
+ while (*tw == (wchar_t)'/' || *tw == (wchar_t)'\\')
+ tw++;
+ /* Strip leading "./" as well as drive letter */
+ while (*tw == (wchar_t)'.' && (tw[1] == (wchar_t)'/' || tw[1] == (wchar_t)'\\'))
+ tw += 2;
+
+ /* Make changes, if any, to the copied name (leave original intact) */
+ for (nw = tw; *nw; nw++)
+ if (*nw == '\\')
+ *nw = '/';
+
+ if (!pathput)
+ tw = lastw(tw, PATH_END);
+
+ /* Malloc space for internal name and copy it */
+ if ((nw = malloc((wcslen(tw) + 1) * sizeof(wchar_t))) == NULL)
+ return NULL;
+ wcscpy(nw, tw);
+
+ if (dosify)
+ msnamew(nw);
+
+ /* Returned malloc'ed name */
+ if (pdosflag)
+ *pdosflag = dosflag;
+#if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ CharToAnsiW(nw, nw);
+#endif
+ return nw;
+}
+#endif
+
char *in2ex(n)
-char *n; /* internal file name */
+ 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 *x; /* external file name */
if ((x = malloc(strlen(n) + 1 + PAD)) == NULL)
return NULL;
strcpy(x, n);
-#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+# if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
AnsiToOem(x, x);
-#endif
+# endif
return x;
}
+#ifdef UNICODE_SUPPORT
+wchar_t *in2exw(nw)
+ wchar_t *nw; /* internal file name */
+/* Convert the zip file name to an external file name, returning the malloc'ed
+ string or NULL if not enough memory. */
+{
+ wchar_t *xw; /* external file name */
+
+ if ((xw = malloc((wcslen(nw) + 1 + PAD) * sizeof(wchar_t))) == NULL)
+ return NULL;
+ wcscpy(xw, nw);
+# if defined(__RSXNT__) /* RSXNT/EMX C rtl uses OEM charset */
+ CharToOemW(xw, xw);
+# endif
+ return xw;
+}
+#endif
+
void stamp(f, d)
-char *f; /* name of file to change */
-ulg d; /* dos-style time to change it to */
+ 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(__BORLANDC__)
@@ -503,12 +1595,11 @@ ulg d; /* dos-style time to change it to */
#endif /* ?__TURBOC__ */
}
-
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 */
+ char *f; /* name of file to get info on */
+ ulg *a; /* return value: file attributes */
+ zoff_t *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
@@ -521,7 +1612,9 @@ iztimes *t; /* return value: access, modific. and creation times */
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() */
+ z_stat s; /* results of zstat() */
+
+ /* converted to malloc instead of using FNMAX - 11/8/04 EG */
char *name;
unsigned int len = strlen(f);
int isstdin = !strcmp(f, "-");
@@ -535,7 +1628,6 @@ iztimes *t; /* return value: access, modific. and creation times */
t->atime = t->mtime = t->ctime = label_utim;
return label_time;
}
-
if ((name = malloc(len + 1)) == NULL) {
ZIPERR(ZE_MEM, "filetime");
}
@@ -544,8 +1636,9 @@ iztimes *t; /* return value: access, modific. and creation times */
name[len - 1] = '\0';
/* not all systems allow stat'ing a file with / appended */
+ /* zip64 support 08/31/2003 R.Nausedat */
if (isstdin) {
- if (fstat(fileno(stdin), &s) != 0) {
+ if (zfstat(fileno(stdin), &s) != 0) {
free(name);
error("fstat(stdin)");
}
@@ -559,32 +1652,127 @@ iztimes *t; /* return value: access, modific. and creation times */
}
if (a != NULL) {
+#ifdef WIN32_OEM
+ /* When creating DOS-like archives with OEM-charset names, only the
+ standard FAT attributes should be used.
+ (Note: On a Win32 system, the UNIX style attributes from stat()
+ do not contain any additional information...)
+ */
+ *a = (isstdin ? 0L : (ulg)GetFileMode(name));
+#else
*a = ((ulg)s.st_mode << 16) | (isstdin ? 0L : (ulg)GetFileMode(name));
+#endif
}
if (n != NULL)
+ /* device return -1 */
*n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L;
if (t != NULL) {
t->atime = s.st_atime;
t->mtime = s.st_mtime;
t->ctime = s.st_ctime;
}
-
free(name);
return unix2dostime((time_t *)&s.st_mtime);
}
+#ifdef UNICODE_SUPPORT
+ulg filetimew(fw, a, n, t)
+ wchar_t *fw; /* name of file to get info on */
+ ulg *a; /* return value: file attributes */
+ zoff_t *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 */
+{
+ zw_stat sw; /* results of zstat() */
+
+ /* converted to malloc instead of using FNMAX - 11/8/04 EG */
+ wchar_t *namew;
+ unsigned int len = wcslen(fw);
+ int isstdin = !wcscmp(fw, L"-");
+ wchar_t *labelw = local_to_wchar_string(label);
+
+ if (labelw && wcscmp(fw, labelw) == 0) {
+ 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 ((namew = malloc((len + 1) * sizeof(wchar_t))) == NULL) {
+ ZIPERR(ZE_MEM, "filetime");
+ }
+ wcscpy(namew, fw);
+ if (wcsrchr(namew, (wchar_t)'/') == (namew + len - 1))
+ namew[len - 1] = '\0';
+ /* not all systems allow stat'ing a file with / appended */
+
+ /* zip64 support 08/31/2003 R.Nausedat */
+ if (isstdin) {
+ if (zwfstat(fileno(stdin), &sw) != 0) {
+ free(namew);
+ error("fstat(stdin)");
+ }
+ time((time_t *)&sw.st_mtime); /* some fstat()s return time zero */
+ } else if (LSSTATW(namew, &sw) != 0) {
+ /* Accept about any file kind including directories
+ * (stored with trailing / with -r option)
+ */
+ free(namew);
+ return 0;
+ }
+
+ if (a != NULL) {
+#ifdef WIN32_OEM
+ /* When creating DOS-like archives with OEM-charset names, only the
+ standard FAT attributes should be used.
+ (Note: On a Win32 system, the UNIX style attributes from stat()
+ do not contain any additional information...)
+ */
+ *a = (isstdin ? 0L : (ulg)GetFileModeW(namew));
+#else
+ *a = ((ulg)sw.st_mode << 16) | (isstdin ? 0L : (ulg)GetFileModeW(namew));
+#endif
+ }
+ if (n != NULL)
+ /* device return -1 */
+ *n = (sw.st_mode & S_IFMT) == S_IFREG ? sw.st_size : -1L;
+ if (t != NULL) {
+ t->atime = sw.st_atime;
+ t->mtime = sw.st_mtime;
+ t->ctime = sw.st_ctime;
+ }
+ free(namew);
+
+ return unix2dostime((time_t *)&sw.st_mtime);
+}
+#endif
+
+
#ifdef NTSD_EAS
-local void GetSD(char *path, char **bufptr, size_t *size,
- char **cbufptr, size_t *csize)
+/* changed size, csize from size_t to ush 3/10/2005 EG */
+local void GetSD(char *path, char **bufptr, ush *size,
+ char **cbufptr, ush *csize)
{
unsigned char stackbuffer[NTSD_BUFFERSIZE];
unsigned long bytes = NTSD_BUFFERSIZE;
unsigned char *buffer = stackbuffer;
unsigned char *DynBuffer = NULL;
- long cbytes;
+ ulg cbytes;
PEF_NTSD_L_HEADER pLocalHeader;
PEF_NTSD_C_HEADER pCentralHeader;
VOLUMECAPS VolumeCaps;
@@ -649,7 +1837,15 @@ local void GetSD(char *path, char **bufptr, size_t *size,
cbytes = memcompress(((char *)pLocalHeader + EF_NTSD_L_LEN), cbytes,
(char *)buffer, bytes);
- *size += EF_NTSD_L_LEN + cbytes;
+ if (cbytes > 0x7FFF) {
+ sprintf(errbuf, "security info too large to store (%ld bytes), %d max", bytes, 0x7FFF);
+ zipwarn(errbuf, "");
+ zipwarn("security info not stored: ", path);
+ if(DynBuffer) free(DynBuffer);
+ return;
+ }
+
+ *size += EF_NTSD_L_LEN + (ush)cbytes;
pLocalHeader->nID = EF_NTSD;
pLocalHeader->nSize = (USHORT)(EF_NTSD_L_LEN - EB_HEADSIZE
@@ -666,8 +1862,10 @@ local void GetSD(char *path, char **bufptr, size_t *size,
pCentralHeader->nSize = EF_NTSD_C_LEN - EB_HEADSIZE; /* sbz */
pCentralHeader->lSize = bytes;
- if (noisy)
- printf(" (%ld bytes security)", bytes);
+ if (noisy) {
+ sprintf(errbuf, " (%ld bytes security)", bytes);
+ zipmessage_nl(errbuf, 0);
+ }
if(DynBuffer) free(DynBuffer);
}
diff --git a/win32/win32zip.h b/win32/win32zip.h
index 8ecb74c..3d8bca5 100644
--- a/win32/win32zip.h
+++ b/win32/win32zip.h
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ win32/win32zip.h - Zip 3
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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 _WIN32ZIP_H
@@ -13,13 +15,17 @@
* NT specific functions for ZIP.
*/
-int GetFileMode(const char *name);
-#if 0 /* never used */
-long GetTheFileTime(const char *name, iztimes *z_times);
+int GetFileMode(char *name);
+#ifdef UNICODE_SUPPORT
+int GetFileModeW(wchar_t *name);
#endif
+long GetTheFileTime(char *name, iztimes *z_times);
-int IsFileNameValid(const char *name);
-int IsFileSystemOldFAT(const char *dir);
+int IsFileNameValid(char *name);
+int IsFileSystemOldFAT(char *dir);
+#ifdef UNICODE_SUPPORT
+int IsFileSystemOldFATW(wchar_t *dir);
+#endif
void ChangeNameForFAT(char *name);
char *getVolumeLabel(int drive, ulg *vtime, ulg *vmode, time_t *vutim);
@@ -28,6 +34,9 @@ char *getVolumeLabel(int drive, ulg *vtime, ulg *vmode, time_t *vutim);
char *StringLower(char *);
#endif
-char *GetLongPathEA(const char *name);
+char *GetLongPathEA(char *name);
+#ifdef UNICODE_SUPPORT
+wchar_t *GetLongPathEAW(wchar_t *name);
+#endif
#endif /* _WIN32ZIP_H */
diff --git a/win32/zip.rc b/win32/zip.rc
new file mode 100644
index 0000000..3ecb961
--- /dev/null
+++ b/win32/zip.rc
@@ -0,0 +1,53 @@
+#include <windows.h>
+#if (defined(WIN32) && !defined(__EMX__) && !defined(__MINGW32__))
+#include <winver.h>
+#endif
+#define IZ_VERSION_SYMBOLS_ONLY
+#include "../revision.h"
+#undef IZ_VERSION_SYMBOLS_ONLY
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION Z_MAJORVER,Z_MINORVER,Z_PATCHLEVEL,0
+ PRODUCTVERSION Z_MAJORVER,Z_MINORVER,Z_PATCHLEVEL,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_APP
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+#ifdef _UNICODE
+ BLOCK "040904B0"
+#else
+ BLOCK "040904E4"
+#endif
+ BEGIN
+ VALUE "CompanyName", IZ_COMPANY_NAME "\0"
+ VALUE "FileDescription", "Info-ZIP Zip for Win32 console\0"
+ VALUE "FileVersion", VERSION "\0"
+ VALUE "InternalName", "zip\0"
+ VALUE "LegalCopyright", "Copyright © Info-ZIP 1997 - 2008\0"
+ VALUE "OriginalFilename", "zip.exe\0"
+ VALUE "ProductName", "Zip\0"
+ VALUE "ProductVersion", VERSION "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+#ifdef _UNICODE
+ VALUE "Translation", 0x409, 1200
+#else
+ VALUE "Translation", 0x409, 1252
+#endif
+ END
+END
diff --git a/win32/zipup.h b/win32/zipup.h
index f65c41e..9505b56 100644
--- a/win32/zipup.h
+++ b/win32/zipup.h
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ win32/zipup.h - Zip 3
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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 __CYGWIN__
@@ -24,6 +26,7 @@
#define fhow (O_RDONLY|O_BINARY)
#define fbad (-1)
typedef int ftype;
+
#if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__EMX__)
# define zopen(n,p) sopen(n,p,SH_DENYNO)
#elif defined(__CYGWIN__) || defined(__IBMC__)
@@ -31,6 +34,14 @@ typedef int ftype;
#else
# define zopen(n,p) _sopen(n,p,_SH_DENYNO)
#endif
+#ifdef UNICODE_SUPPORT
+# if defined(__CYGWIN__) || defined(__IBMC__)
+# define zwopen(n,p) wopen(n,p)
+# else
+# define zwopen(n,p) _wsopen(n,p,_SH_DENYNO)
+# endif
+#endif
+
#define zread(f,b,n) read(f,b,n)
#define zclose(f) close(f)
#define zerr(f) (k == (extent)(-1L))
diff --git a/windll/VBz64/VBZIP.VBP b/windll/VBz64/VBZIP.VBP
new file mode 100644
index 0000000..4161be5
--- /dev/null
+++ b/windll/VBz64/VBZIP.VBP
@@ -0,0 +1,33 @@
+Type=Exe
+Form=Vbzipfrm.frm
+Module=VBZipBas; VBZipBas.bas
+IconForm="Form1"
+Startup="Form1"
+HelpFile=""
+Title="VBZIP"
+ExeName32="VBZIP.exe"
+Command32=""
+Name="Project1"
+HelpContextID="0"
+CompatibleMode="0"
+MajorVer=1
+MinorVer=0
+RevisionVer=0
+AutoIncrementVer=0
+ServerSupportFiles=0
+VersionCompanyName="Mike"
+CompilationType=-1
+OptimizationType=0
+FavorPentiumPro(tm)=0
+CodeViewDebugInfo=0
+NoAliasing=0
+BoundsCheck=0
+OverflowCheck=0
+FlPointCheck=0
+FDIVCheck=0
+UnroundedFP=0
+StartMode=0
+Unattended=0
+Retained=0
+ThreadPerObject=0
+MaxNumberOfThreads=1
diff --git a/windll/VBz64/VBZIP.vbw b/windll/VBz64/VBZIP.vbw
new file mode 100644
index 0000000..7b4e7f5
--- /dev/null
+++ b/windll/VBz64/VBZIP.vbw
@@ -0,0 +1,2 @@
+Form1 = 7, 9, 712, 539, , 22, 22, 660, 466, C
+VBZipBas = 26, -4, 716, 492,
diff --git a/windll/VBz64/VBZipBas.bas b/windll/VBz64/VBZipBas.bas
new file mode 100644
index 0000000..99547a0
--- /dev/null
+++ b/windll/VBz64/VBZipBas.bas
@@ -0,0 +1,737 @@
+Attribute VB_Name = "VBZipBas"
+
+Option Explicit
+
+'---------------------------------------------------------------
+'-- Please Do Not Remove These Comments!!!
+'---------------------------------------------------------------
+'-- Sample VB 6 code to drive zip32z64.dll
+'-- Based on the code contributed to the Info-ZIP project
+'-- by Mike Le Voi
+'--
+'-- See the original VB example in a separate directory for
+'-- more information
+'--
+'-- Use this code at your own risk. Nothing implied or warranted
+'-- to work on your machine :-)
+'---------------------------------------------------------------
+'--
+'-- The Source Code Is Freely Available From Info-ZIP At:
+'-- ftp://ftp.info-zip.org/pub/infozip/infozip.html
+'--
+'-- A Very Special Thanks To Mr. Mike Le Voi
+'-- And Mr. Mike White Of The Info-ZIP
+'-- For Letting Me Use And Modify His Orginal
+'-- Visual Basic 5.0 Code! Thank You Mike Le Voi.
+'---------------------------------------------------------------
+
+'---------------------------------------------------------------
+' This example is redesigned to work with Zip32z64.dll compiled from
+' Zip 3.0 with Zip64 enabled. This allows for archives with more
+' and larger files than allowed in previous versions.
+'
+' Modified 4/24/2004, 12/4/2007 by Ed Gordon
+'---------------------------------------------------------------
+
+'---------------------------------------------------------------
+' Usage notes:
+'
+' This code uses Zip32z64.dll. You DO NOT need to register the
+' DLL to use it. You also DO NOT need to reference it in your
+' VB project. You DO have to copy the DLL to your SYSTEM
+' directory, your VB project directory, or place it in a directory
+' on your command PATH.
+'
+' Note that Zip32z64 is probably not thread safe so you should avoid
+' using the dll in multiple threads at the same time without first
+' testing for interaction.
+'
+' All code provided under the Info-Zip license. If you have
+' any questions please contact Info-Zip.
+'
+' April 24 2004 EG
+'
+'---------------------------------------------------------------
+
+'-- C Style argv
+'-- Holds The Zip Archive Filenames
+'
+' Max for zFiles just over 8000 as each pointer takes up 4 bytes and
+' VB only allows 32 kB of local variables and that includes function
+' parameters. - 3/19/2004 EG
+'
+' Can put names in strZipFileNames instead of using this array,
+' which avoids this limit. File names are separated by spaces.
+' Enclose names in quotes if include spaces.
+Public Type ZIPnames
+ zFiles(1 To 100) As String
+End Type
+
+'-- Call Back "String"
+Public Type ZipCBChar
+ ch(4096) As Byte
+End Type
+
+'-- Version Structure
+Public Type VerType
+ Major As Byte
+ Minor As Byte
+ PatchLevel As Byte
+ NotUsed As Byte
+End Type
+Public Type ZipVerType
+ structlen As Long ' Length Of The Structure Being Passed
+ flag As Long ' Bit 0: is_beta bit 1: uses_zlib
+ Beta As String * 10 ' e.g., "g BETA" or ""
+ date As String * 20 ' e.g., "4 Sep 95" (beta) or "4 September 1995"
+ ZLIB As String * 10 ' e.g., "1.0.5" or NULL
+ encryption As Long ' 0 if encryption not available
+ ZipVersion As VerType
+ os2dllVersion As VerType
+ windllVersion As VerType
+End Type
+
+'-- ZPOPT Is Used To Set The Options In The ZIP32z64.DLL
+Public Type ZpOpt
+ date As String ' Date in either US 12/31/98 or 1998-12-31 format
+ szRootDir As String ' Root Directory Pathname (Up To 256 Bytes Long)
+ szTempDir As String ' Temp Directory Pathname (Up To 256 Bytes Long)
+ fTemp As Long ' 1 If Temp dir Wanted, Else 0
+ fSuffix As Long ' Include Suffixes (Not Yet Implemented!)
+ fEncrypt As Long ' 1 If Encryption Wanted, Else 0
+ fSystem As Long ' 1 To Include System/Hidden Files, Else 0
+ fVolume As Long ' 1 If Storing Volume Label, Else 0
+ fExtra As Long ' 1 If Excluding Extra Attributes, Else 0
+ fNoDirEntries As Long ' 1 If Ignoring Directory Entries (end with /), Else 0
+ fExcludeDate As Long ' 1 If Excluding Files After Specified Date, Else 0
+ fIncludeDate As Long ' 1 If Including Files After Specified Date, Else 0
+ fVerbose As Long ' 1 If Full Messages Wanted, Else 0
+ fQuiet As Long ' 1 If Minimum Messages Wanted, Else 0
+ fCRLF_LF As Long ' 1 If Translate CR/LF To LF, Else 0
+ fLF_CRLF As Long ' 1 If Translate LF To CR/LF, Else 0
+ fJunkDir As Long ' 1 If Junking Directory Names on entries, Else 0
+ fGrow As Long ' 1 If Allow Appending To Zip File, Else 0
+ fForce As Long ' 1 If Making Entries Using DOS File Names, Else 0
+ fMove As Long ' 1 If Deleting Files Added Or Updated, Else 0
+ fDeleteEntries As Long ' 1 If Files Passed Have To Be Deleted, Else 0
+ fUpdate As Long ' 1 If Updating Zip File-Overwrite Only If Newer, Else 0
+ fFreshen As Long ' 1 If Freshing Zip File-Overwrite Only, Else 0
+ fJunkSFX As Long ' 1 If Junking SFX Prefix, Else 0
+ fLatestTime As Long ' 1 If Setting Zip File Time To Time Of Latest File In Archive, Else 0
+ fComment As Long ' 1 If Putting Comment In Zip File, Else 0
+ fOffsets As Long ' 1 If Updating Archive Offsets For SFX Files, Else 0
+ fPrivilege As Long ' 1 If Not Saving Privileges, Else 0
+ fEncryption As Long ' Read Only Property!!!
+ szSplitSize As String ' Size of split if splitting, Else NULL (empty string)
+ ' 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.
+ szIncludeList As String ' If used, space separated list of Include filename
+ ' patterns where match includes file - put quotes
+ ' around each filename pattern.
+ IncludeListCount As Long ' place filler (not for VB) - (inits to 0) DO NOT USE
+ IncludeList As Long ' place filler (not for VB) - (inits to 0) DO NOT USE
+ szExcludeList As String ' If used, space separated list of Exclude filename
+ ' patterns where match excludes file - put quotes
+ ' around each filename pattern.
+ ExcludeListCount As Long ' place filler (not for VB) - (inits to 0) DO NOT USE
+ ExcludeList As Long ' place filler (not for VB) - (inits to 0) DO NOT USE
+ fRecurse As Long ' 1 (-r), 2 (-R) If Recursing Into Sub-Directories, Else 0
+ fRepair As Long ' 1 = Fix Archive, 2 = Try Harder To Fix, Else 0
+ flevel As Byte ' Compression Level - 0 = Stored 6 = Default 9 = Max
+End Type
+
+
+' Used by SetZipOptions
+Public Enum ZipModeType
+ Add = 0
+ Delete = 1
+ Update = 2
+ Freshen = 3
+End Enum
+Public Enum CompressionLevelType
+ c0_NoCompression = 0
+ c1_Fast = 1
+ c2_Fast = 2
+ c3_Fast = 3
+ c4_Med = 4
+ c5_Med = 5
+ c6_Default = 6
+ c7_Extra = 7
+ c8_Extra = 8
+ c9_Max = 9
+End Enum
+Public Enum Translate_LF_Type
+ No_Line_End_Trans = 0
+ LF_To_CRLF = 1
+ CRLF_To_LF = 2
+End Enum
+Public Enum RepairType
+ NoRepair = 0
+ TryFix = 1
+ TryFixHarder = 2
+End Enum
+Public Enum VerbosenessType
+ Quiet = 0
+ Normal = 1
+ Verbose = 2
+End Enum
+Public Enum RecurseType
+ NoRecurse = 0
+ r_RecurseIntoSubdirectories = 1
+ R_RecurseUsingPatterns = 2
+End Enum
+
+
+'-- This Structure Is Used For The ZIP32z64.DLL Function Callbacks
+' Assumes Zip32z64.dll with Zip64 enabled
+Public Type ZIPUSERFUNCTIONS
+ ZDLLPrnt As Long ' Callback ZIP32z64.DLL Print Function
+ ZDLLCOMMENT As Long ' Callback ZIP32z64.DLL Comment Function
+ ZDLLPASSWORD As Long ' Callback ZIP32z64.DLL Password Function
+ ZDLLSPLIT As Long ' Callback ZIP32z64.DLL Split Select Function
+ ' There are 2 versions of SERVICE, we use one does not need 64-bit data type
+ ZDLLSERVICE As Long ' Callback ZIP32z64.DLL Service Function
+ ZDLLSERVICE_NO_INT64 As Long ' Callback ZIP32z64.DLL Service Function
+End Type
+
+'-- Default encryption password (used in callback if not empty string)
+Public EncryptionPassword As String
+
+'-- For setting the archive comment
+Public ArchiveCommentText
+
+'-- version info
+Public ZipVersion As ZipVerType
+
+'-- Local Declarations
+Public ZOPT As ZpOpt
+Public ZUSER As ZIPUSERFUNCTIONS
+
+'-- This Assumes ZIP32z64.DLL Is In Your \windows\system directory
+'-- or a copy is in the program directory or in some other directory
+'-- listed in PATH
+Private Declare Function ZpInit Lib "zip32z64.dll" _
+ (ByRef Zipfun As ZIPUSERFUNCTIONS) As Long '-- Set Zip Callbacks
+
+Private Declare Function ZpArchive Lib "zip32z64.dll" _
+ (ByVal argc As Long, ByVal funame As String, _
+ ByRef argv As ZIPnames, ByVal strNames As String, ByRef Opts As ZpOpt) As Long '-- Real Zipping Action
+
+Private Declare Sub ZpVersion Lib "zip32z64.dll" _
+ (ByRef ZipVersion As ZipVerType) '-- Version of DLL
+
+
+'-------------------------------------------------------
+'-- Public Variables For Setting The ZPOPT Structure...
+'-- (WARNING!!!) You Must Set The Options That You
+'-- Want The ZIP32.DLL To Do!
+'-- Before Calling VBZip32!
+'--
+'-- NOTE: See The Above ZPOPT Structure Or The VBZip32
+'-- Function, For The Meaning Of These Variables
+'-- And How To Use And Set Them!!!
+'-- These Parameters Must Be Set Before The Actual Call
+'-- To The VBZip32 Function!
+'-------------------------------------------------------
+
+'-- Public Program Variables
+Public zArgc As Integer ' Number Of Files To Zip Up
+Public zZipArchiveName As String ' The Zip File Name ie: Myzip.zip
+Public zZipFileNames As ZIPnames ' File Names To Zip Up
+Public strZipFileNames As String ' String of names to Zip Up
+Public zZipInfo As String ' Holds The Zip File Information
+
+'-- Public Constants
+'-- For Zip & UnZip Error Codes!
+Public Const ZE_OK = 0 ' Success (No Error)
+Public Const ZE_EOF = 2 ' Unexpected End Of Zip File Error
+Public Const ZE_FORM = 3 ' Zip File Structure Error
+Public Const ZE_MEM = 4 ' Out Of Memory Error
+Public Const ZE_LOGIC = 5 ' Internal Logic Error
+Public Const ZE_BIG = 6 ' Entry Too Large To Split Error
+Public Const ZE_NOTE = 7 ' Invalid Comment Format Error
+Public Const ZE_TEST = 8 ' Zip Test (-T) Failed Or Out Of Memory Error
+Public Const ZE_ABORT = 9 ' User Interrupted Or Termination Error
+Public Const ZE_TEMP = 10 ' Error Using A Temp File
+Public Const ZE_READ = 11 ' Read Or Seek Error
+Public Const ZE_NONE = 12 ' Nothing To Do Error
+Public Const ZE_NAME = 13 ' Missing Or Empty Zip File Error
+Public Const ZE_WRITE = 14 ' Error Writing To A File
+Public Const ZE_CREAT = 15 ' Could't Open To Write Error
+Public Const ZE_PARMS = 16 ' Bad Command Line Argument Error
+Public Const ZE_OPEN = 18 ' Could Not Open A Specified File To Read Error
+
+'-- These Functions Are For The ZIP32z64.DLL
+'--
+'-- Puts A Function Pointer In A Structure
+'-- For Use With Callbacks...
+Public Function FnPtr(ByVal lp As Long) As Long
+
+ FnPtr = lp
+
+End Function
+
+'-- Callback For ZIP32z64.DLL - DLL Print Function
+Public Function ZDLLPrnt(ByRef fname As ZipCBChar, ByVal x As Long) As Long
+
+ Dim s0 As String
+ Dim xx As Long
+
+ '-- Always Put This In Callback Routines!
+ On Error Resume Next
+
+ s0 = ""
+
+ '-- Get Zip32.DLL Message For processing
+ For xx = 0 To x
+ If fname.ch(xx) = 0 Then
+ Exit For
+ Else
+ s0 = s0 + Chr(fname.ch(xx))
+ End If
+ Next
+
+ '----------------------------------------------
+ '-- This Is Where The DLL Passes Back Messages
+ '-- To You! You Can Change The Message Printing
+ '-- Below Here!
+ '----------------------------------------------
+
+ '-- Display Zip File Information
+ '-- zZipInfo = zZipInfo & s0
+ Form1.Print s0;
+
+ DoEvents
+
+ ZDLLPrnt = 0
+
+End Function
+
+'-- Callback For ZIP32z64.DLL - DLL Service Function
+Public Function ZDLLServ(ByRef mname As ZipCBChar, _
+ ByVal LowSize As Long, _
+ ByVal HighSize As Long) As Long
+
+ Dim s0 As String
+ Dim xx As Long
+ Dim FS As Currency ' for large file sizes
+
+ '-- Always Put This In Callback Routines!
+ On Error Resume Next
+
+ FS = (HighSize * &H10000 * &H10000) + LowSize
+ ' Form1.Print "ZDLLServ returned File Size High " & HighSize & _
+ ' " Low " & LowSize & " = " & FS & " bytes"
+
+ s0 = ""
+ '-- Get Zip32.DLL Message For processing
+ For xx = 0 To 4096 ' x
+ If mname.ch(xx) = 0 Then
+ Exit For
+ Else
+ s0 = s0 + Chr(mname.ch(xx))
+ End If
+ Next
+ ' At this point, s0 contains the message passed from the DLL
+ ' It is up to the developer to code something useful here :)
+ ZDLLServ = 0 ' Setting this to 1 will abort the zip!
+
+End Function
+
+'-- Callback For ZIP32z64.DLL - DLL Password Function
+Public Function ZDLLPass(ByRef p As ZipCBChar, _
+ ByVal n As Long, ByRef m As ZipCBChar, _
+ ByRef Name As ZipCBChar) As Integer
+
+ Dim filename As String
+ Dim prompt As String
+ Dim xx As Integer
+ Dim szpassword As String
+
+ '-- Always Put This In Callback Routines!
+ On Error Resume Next
+
+ ZDLLPass = 1
+
+ '-- User Entered A Password So Proccess It
+
+ '-- Enter or Verify
+ For xx = 0 To 255
+ If m.ch(xx) = 0 Then
+ Exit For
+ Else
+ prompt = prompt & Chr(m.ch(xx))
+ End If
+ Next
+
+ '-- If There Is A Password Have The User Enter It!
+ '-- This Can Be Changed
+
+ '-- Now skip asking if default password set
+ If EncryptionPassword <> "" Then
+ szpassword = EncryptionPassword
+ Else
+ szpassword = InputBox("Please Enter The Password!", prompt)
+ End If
+
+ '-- The User Did Not Enter A Password So Exit The Function
+ If szpassword = "" Then Exit Function
+
+ For xx = 0 To n - 1
+ p.ch(xx) = 0
+ Next
+
+ For xx = 0 To Len(szpassword) - 1
+ p.ch(xx) = Asc(Mid(szpassword, xx + 1, 1))
+ Next
+
+ p.ch(xx) = Chr(0) ' Put Null Terminator For C
+
+ ZDLLPass = 0
+
+End Function
+
+'-- Callback For ZIP32z64.DLL - DLL Comment Function
+Public Function ZDLLComm(ByRef s1 As ZipCBChar) As Integer
+
+ Dim comment As String
+ Dim xx%, szcomment$
+
+ '-- Always Put This In Callback Routines!
+ On Error Resume Next
+
+ ZDLLComm = 1
+ If Not IsEmpty(ArchiveCommentText) Then
+ ' use text given to SetZipOptions
+ szcomment = ArchiveCommentText
+ Else
+ For xx = 0 To 4095
+ szcomment = szcomment & Chr(s1.ch(xx))
+ If s1.ch(xx) = 0 Then
+ Exit For
+ End If
+ Next
+ comment = InputBox("Enter or edit the comment", Default:=szcomment)
+ If comment = "" Then
+ ' either empty comment or Cancel button
+ If MsgBox("Remove comment?" & Chr(13) & "Hit No to keep existing comment", vbYesNo) = vbYes Then
+ szcomment = comment
+ Else
+ Exit Function
+ End If
+ End If
+ szcomment = comment
+ End If
+ 'If szcomment = "" Then Exit Function
+ For xx = 0 To Len(szcomment) - 1
+ s1.ch(xx) = Asc(Mid$(szcomment, xx + 1, 1))
+ Next xx
+ s1.ch(xx) = 0 ' Put null terminator for C
+
+End Function
+
+' This function can be used to set options in VB
+Public Function SetZipOptions(ByRef ZipOpts As ZpOpt, _
+ Optional ByVal ZipMode As ZipModeType = Add, _
+ Optional ByVal RootDirToZipFrom As String = "", _
+ Optional ByVal CompressionLevel As CompressionLevelType = c6_Default, _
+ Optional ByVal RecurseSubdirectories As RecurseType = NoRecurse, _
+ Optional ByVal Verboseness As VerbosenessType = Normal, _
+ Optional ByVal i_IncludeFiles As String = "", _
+ Optional ByVal x_ExcludeFiles As String = "", _
+ Optional ByVal UpdateSFXOffsets As Boolean = False, Optional ByVal JunkDirNames As Boolean = False, _
+ Optional ByVal Encrypt As Boolean = False, Optional ByVal Password As String = "", _
+ Optional ByVal Repair As RepairType = NoRepair, Optional ByVal NoDirEntries As Boolean = False, _
+ Optional ByVal GrowExistingArchive As Boolean = False, _
+ Optional ByVal JunkSFXPrefix As Boolean = False, Optional ByVal ForceUseOfDOSNames As Boolean = False, _
+ Optional ByVal Translate_LF As Translate_LF_Type = No_Line_End_Trans, _
+ Optional ByVal Move_DeleteAfterAddedOrUpdated As Boolean = False, _
+ Optional ByVal SetZipTimeToLatestTime As Boolean = False, _
+ Optional ByVal IncludeSystemAndHiddenFiles As Boolean = False, _
+ Optional ByVal ExcludeEarlierThanDate As String = "", _
+ Optional ByVal IncludeEarlierThanDate As String = "", _
+ Optional ByVal IncludeVolumeLabel As Boolean = False, _
+ Optional ByVal ArchiveComment As Boolean = False, _
+ Optional ByVal ArchiveCommentTextString = Empty, _
+ Optional ByVal UsePrivileges As Boolean = False, _
+ Optional ByVal ExcludeExtraAttributes As Boolean = False, Optional ByVal SplitSize As String = "", _
+ Optional ByVal TempDirPath As String = "") As Boolean
+
+ Dim SplitNum As Long
+ Dim SplitMultS As String
+ Dim SplitMult As Long
+
+ ' set some defaults
+ ZipOpts.date = vbNullString
+ ZipOpts.szRootDir = vbNullString
+ ZipOpts.szTempDir = vbNullString
+ ZipOpts.fTemp = 0
+ ZipOpts.fSuffix = 0
+ ZipOpts.fEncrypt = 0
+ ZipOpts.fSystem = 0
+ ZipOpts.fVolume = 0
+ ZipOpts.fExtra = 0
+ ZipOpts.fNoDirEntries = 0
+ ZipOpts.fExcludeDate = 0
+ ZipOpts.fIncludeDate = 0
+ ZipOpts.fVerbose = 0
+ ZipOpts.fQuiet = 0
+ ZipOpts.fCRLF_LF = 0
+ ZipOpts.fLF_CRLF = 0
+ ZipOpts.fJunkDir = 0
+ ZipOpts.fGrow = 0
+ ZipOpts.fForce = 0
+ ZipOpts.fMove = 0
+ ZipOpts.fDeleteEntries = 0
+ ZipOpts.fUpdate = 0
+ ZipOpts.fFreshen = 0
+ ZipOpts.fJunkSFX = 0
+ ZipOpts.fLatestTime = 0
+ ZipOpts.fComment = 0
+ ZipOpts.fOffsets = 0
+ ZipOpts.fPrivilege = 0
+ ZipOpts.szSplitSize = vbNullString
+ ZipOpts.IncludeListCount = 0
+ ZipOpts.szIncludeList = vbNullString
+ ZipOpts.ExcludeListCount = 0
+ ZipOpts.szExcludeList = vbNullString
+ ZipOpts.fRecurse = 0
+ ZipOpts.fRepair = 0
+ ZipOpts.flevel = 0
+
+ If RootDirToZipFrom <> "" Then
+ ZipOpts.szRootDir = RootDirToZipFrom
+ End If
+ ZipOpts.flevel = Asc(CompressionLevel)
+ If UpdateSFXOffsets Then ZipOpts.fOffsets = 1
+
+ If i_IncludeFiles <> "" Then
+ ZipOpts.szIncludeList = i_IncludeFiles
+ End If
+ If x_ExcludeFiles <> "" Then
+ ZipOpts.szExcludeList = x_ExcludeFiles
+ End If
+
+ If ZipMode = Add Then
+ ' default
+ ElseIf ZipMode = Delete Then
+ ZipOpts.fDeleteEntries = 1
+ ElseIf ZipMode = Update Then
+ ZipOpts.fUpdate = 1
+ Else
+ ZipOpts.fFreshen = 1
+ End If
+ ZipOpts.fRepair = Repair
+ If GrowExistingArchive Then ZipOpts.fGrow = 1
+ If Move_DeleteAfterAddedOrUpdated Then ZipOpts.fMove = 1
+
+ If Verboseness = Quiet Then
+ ZipOpts.fQuiet = 1
+ ElseIf Verboseness = Verbose Then
+ ZipOpts.fVerbose = 1
+ End If
+
+ If ArchiveComment = False And Not IsEmpty(ArchiveCommentTextString) Then
+ MsgBox "Must set ArchiveComment = True to set ArchiveCommentTextString"
+ Exit Function
+ End If
+ If IsEmpty(ArchiveCommentTextString) Then
+ ArchiveCommentText = Empty
+ Else
+ ArchiveCommentText = ArchiveCommentTextString
+ End If
+ If ArchiveComment Then ZipOpts.fComment = 1
+
+ If NoDirEntries Then ZipOpts.fNoDirEntries = 1
+ If JunkDirNames Then ZipOpts.fJunkDir = 1
+ If Encrypt Then ZipOpts.fEncrypt = 1
+ EncryptionPassword = Password
+ If JunkSFXPrefix Then ZipOpts.fJunkSFX = 1
+ If ForceUseOfDOSNames Then ZipOpts.fForce = 1
+ If Translate_LF = LF_To_CRLF Then ZipOpts.fLF_CRLF = 1
+ If Translate_LF = CRLF_To_LF Then ZipOpts.fCRLF_LF = 1
+ ZipOpts.fRecurse = RecurseSubdirectories
+ If IncludeSystemAndHiddenFiles Then ZipOpts.fSystem = 1
+
+ If SetZipTimeToLatestTime Then ZipOpts.fLatestTime = 1
+ If ExcludeEarlierThanDate <> "" And IncludeEarlierThanDate <> "" Then
+ MsgBox "Both ExcludeEarlierThanDate and IncludeEarlierThanDate not " & Chr(10) & _
+ "supported at same time"
+ Exit Function
+ End If
+ If ExcludeEarlierThanDate <> "" Then
+ ZipOpts.fIncludeDate = 1
+ ZipOpts.date = ExcludeEarlierThanDate
+ End If
+ If IncludeEarlierThanDate <> "" Then
+ ZipOpts.fExcludeDate = 1
+ ZipOpts.date = IncludeEarlierThanDate
+ End If
+
+ If TempDirPath <> "" Then
+ ZipOpts.szTempDir = TempDirPath
+ ZipOpts.fTemp = 1
+ End If
+
+ If SplitSize <> "" Then
+ SplitSize = Trim(SplitSize)
+ SplitMultS = Right(SplitSize, 1)
+ SplitMultS = UCase(SplitMultS)
+ If (SplitMultS = "K") Then
+ SplitMult = 1024
+ SplitNum = Val(Left(SplitSize, Len(SplitSize) - 1))
+ ElseIf SplitMultS = "M" Then
+ SplitMult = 1024 * 1024&
+ SplitNum = Val(Left(SplitSize, Len(SplitSize) - 1))
+ ElseIf SplitMultS = "G" Then
+ SplitMult = 1024 * 1024 * 1024&
+ SplitNum = Val(Left(SplitSize, Len(SplitSize) - 1))
+ Else
+ SplitMult = 1024 * 1024&
+ SplitNum = Val(SplitSize)
+ End If
+ SplitNum = SplitNum * SplitMult
+ If SplitNum = 0 Then
+ MsgBox "SplitSize of 0 not supported"
+ Exit Function
+ ElseIf SplitNum < 64 * 1024& Then
+ MsgBox "SplitSize must be at least 64k"
+ Exit Function
+ End If
+ ZipOpts.szSplitSize = SplitSize
+ End If
+
+ If IncludeVolumeLabel Then ZipOpts.fVolume = 1
+ If UsePrivileges Then ZipOpts.fPrivilege = 1
+ If ExcludeExtraAttributes Then ZipOpts.fExtra = 1
+
+ SetZipOptions = True
+
+End Function
+
+Function ChopNulls(ByVal Str) As String
+ Dim A As Integer
+ Dim C As String
+
+ For A = 1 To Len(Str)
+ If Mid(Str, A, 1) = Chr(0) Then
+ ChopNulls = Left(Str, A - 1)
+ Exit Function
+ End If
+ Next
+ ChopNulls = Str
+
+End Function
+Sub DisplayVersion()
+
+ ' display version of DLL
+ Dim Beta As Boolean
+ Dim ZLIB As Boolean
+ Dim Zip64 As Boolean
+ Dim Flags As String
+ Dim A As Integer
+
+ ZipVersion.structlen = Len(ZipVersion)
+ ZpVersion ZipVersion
+ ' Check flag
+ If ZipVersion.flag And 1 Then
+ Flags = Flags & " Beta,"
+ Beta = True
+ Else
+ Flags = Flags & " No Beta,"
+ End If
+ If ZipVersion.flag And 2 Then
+ Flags = Flags & " ZLIB,"
+ ZLIB = True
+ Else
+ Flags = Flags & " No ZLIB,"
+ End If
+ If ZipVersion.flag And 4 Then
+ Flags = Flags & " Zip64, "
+ Zip64 = True
+ Else
+ Flags = Flags & " No Zip64, "
+ End If
+ If ZipVersion.encryption Then
+ Flags = Flags & "Encryption"
+ Else
+ Flags = Flags & " No encryption"
+ End If
+
+ Form1.Caption = "Using Zip32z64.DLL Version " & _
+ ZipVersion.ZipVersion.Major & "." & ZipVersion.ZipVersion.Minor & " " & _
+ ChopNulls(ZipVersion.Beta) & " [" & ChopNulls(ZipVersion.date) & "]" & _
+ " - FLAGS: " & Flags
+
+ If Not Zip64 Then
+ A = MsgBox("Zip32z64.dll not compiled with Zip64 enabled - continue?", _
+ vbOKCancel, _
+ "Wrong dll")
+ If A = vbCancel Then
+ End
+ End If
+ End If
+
+End Sub
+
+'-- Main ZIP32.DLL Subroutine.
+'-- This Is Where It All Happens!!!
+'--
+'-- (WARNING!) Do Not Change This Function!!!
+'--
+Public Function VBZip32() As Long
+
+ Dim retcode As Long
+ Dim FileNotFound As Boolean
+
+ ' On Error Resume Next '-- Nothing Will Go Wrong :-)
+ On Error GoTo ZipError
+
+ retcode = 0
+
+ '-- Set Address Of ZIP32.DLL Callback Functions
+ '-- (WARNING!) Do Not Change!!! (except as noted below)
+ ZUSER.ZDLLPrnt = FnPtr(AddressOf ZDLLPrnt)
+ ZUSER.ZDLLPASSWORD = FnPtr(AddressOf ZDLLPass)
+ ZUSER.ZDLLCOMMENT = FnPtr(AddressOf ZDLLComm)
+ ZUSER.ZDLLSERVICE_NO_INT64 = FnPtr(AddressOf ZDLLServ)
+
+ ' If you need to set destination of each split set this
+ 'ZUSER.ZDLLSPLIT = FnPtr(AddressOf ZDLLSplitSelect)
+
+ '-- Set ZIP32.DLL Callbacks - return 1 if DLL loaded 0 if not
+ retcode = ZpInit(ZUSER)
+ If retcode = 0 And FileNotFound Then
+ MsgBox "Probably could not find Zip32z64.DLL - have you copied" & Chr(10) & _
+ "it to the System directory, your program directory, " & Chr(10) & _
+ "or a directory on your command PATH?"
+ VBZip32 = retcode
+ Exit Function
+ End If
+
+ DisplayVersion
+
+ If strZipFileNames = "" Then
+ ' not using string of names to zip (so using array of names)
+ strZipFileNames = vbNullString
+ End If
+
+ '-- Go Zip It Them Up!
+ retcode = ZpArchive(zArgc, zZipArchiveName, zZipFileNames, strZipFileNames, ZOPT)
+
+ '-- Return The Function Code
+ VBZip32 = retcode
+
+ Exit Function
+
+ZipError:
+ MsgBox "Error: " & Err.Description
+ If Err = 48 Then
+ FileNotFound = True
+ End If
+ Resume Next
+
+End Function
+
diff --git a/windll/VBz64/Vbzipfrm.frm b/windll/VBz64/Vbzipfrm.frm
new file mode 100644
index 0000000..57c4df4
--- /dev/null
+++ b/windll/VBz64/Vbzipfrm.frm
@@ -0,0 +1,183 @@
+VERSION 5.00
+Begin VB.Form Form1
+ AutoRedraw = -1 'True
+ Caption = "Form1"
+ ClientHeight = 3150
+ ClientLeft = 60
+ ClientTop = 345
+ ClientWidth = 6570
+ BeginProperty Font
+ Name = "MS Sans Serif"
+ Size = 9.75
+ Charset = 0
+ Weight = 700
+ Underline = 0 'False
+ Italic = 0 'False
+ Strikethrough = 0 'False
+ EndProperty
+ LinkTopic = "Form1"
+ ScaleHeight = 3150
+ ScaleWidth = 6570
+ StartUpPosition = 1 'CenterOwner
+End
+Attribute VB_Name = "Form1"
+Attribute VB_GlobalNameSpace = False
+Attribute VB_Creatable = False
+Attribute VB_PredeclaredId = True
+Attribute VB_Exposed = False
+
+Option Explicit
+
+'---------------------------------------------------------------
+'-- Sample VB 6 code to drive zip32z64.dll
+'--
+'-- Based on code contributed to the Info-ZIP project by Mike Le Voi
+'--
+'-- See the Original VB example in a separate directory for
+'-- more information
+'--
+'-- Use this code at your own risk. Nothing implied or warranted
+'-- to work on your machine :-)
+'---------------------------------------------------------------
+'--
+'-- The Source Code Is Freely Available From Info-ZIP At:
+'-- ftp://ftp.info-zip.org/pub/infozip/infozip.html
+'-- and
+'-- http://sourceforge.net/projects/infozip/
+'--
+'-- A Very Special Thanks To Mr. Mike Le Voi
+'-- And Mr. Mike White Of The Info-ZIP project
+'-- For Letting Me Use And Modify His Orginal
+'-- Visual Basic 5.0 Code! Thank You Mike Le Voi.
+'---------------------------------------------------------------
+'--
+'-- Contributed To The Info-ZIP Project By Raymond L. King
+'-- Modified June 21, 1998
+'-- By Raymond L. King
+'-- Custom Software Designers
+'--
+'-- Contact Me At: king@ntplx.net
+'-- ICQ 434355
+'-- Or Visit Our Home Page At: http://www.ntplx.net/~king
+'--
+'---------------------------------------------------------------
+
+'---------------------------------------------------------------
+' Zip32z64.dll is the new Zip32.dll based on Zip 3.0 and compiled
+' with Zip64 support enabled. See windll.txt in the windll directory
+' for more on Zip32z64 and the comments in VBZipBas.bas.
+'
+' Contact Info-Zip if problems. This code is
+' provided under the Info-Zip license.
+'
+' 4/24/2004, 12/4/2007 EG
+'---------------------------------------------------------------
+
+Private Sub Form_Click()
+
+ Dim retcode As Integer ' For Return Code From ZIP32.DLL
+ Dim iFiles As String
+ Dim FilesToZip() As String
+ Dim i As Long
+
+ Cls
+
+ '-- Set Options - Only The Common Ones Are Shown Here
+ '-- These Must Be Set Before Calling The VBZip32 Function
+
+ ' In VB 6 you can see the list of possible options and the defaults
+ ' by adding a space between any parameters which should make the tip box
+ ' appear. Delete a := and retype to see a list of choices.
+
+ ' Be warned: There are bugs in the previous dll. See the Original VB
+ ' example in the VB directory for details.
+
+ If Not SetZipOptions(ZOPT, _
+ ZipMode:=Add, _
+ CompressionLevel:=c6_Default) Then
+ ' Some additional options ...
+ ' RootDirToZipFrom:="", _
+ ' strip paths and just store names:
+ ' JunkDirNames:=False, _
+ ' do not store entries for the directories themselves:
+ ' NoDirEntries:=True _
+ ' include files only if match one of these patterns:
+ ' i_IncludeFiles:="*.vbp *.frm", _
+ ' exclude files that match these patterns:
+ ' x_ExcludeFiles:="*.bas", _
+ ' Verboseness:=Verbose, _
+ ' IncludeEarlierThanDate:="2004-4-1", _
+ ' RecurseSubdirectories:=r_RecurseIntoSubdirectories, _
+ ' Encrypt:=False, _
+ ' ArchiveComment:=False
+ ' date example (format mmddyyyy or yyyy-mm-dd):
+ ' ExcludeEarlierThanDate:="2002-12-10", _
+ ' split example (can only create, can't update split archives in VB):
+ ' SplitSize:="110k", _
+' Delete
+ ' If Not SetZipOptions(ZOPT, _
+ ' ZipMode:=Delete) Then
+
+ ' a problem if get here - error message already displayed so just exit
+ Exit Sub
+ End If
+
+
+ '-- Select Some Files - Wildcards Are Supported
+ '-- Change The Paths Here To Your Directory
+ '-- And Files!!!
+
+ ' default to current (VB project) directory and zip up project files
+ zZipArchiveName = "MyFirst.zip"
+
+
+ ' Files to zip - use one of below
+
+ '---------------
+ ' Example using file name array
+
+ ' Store the file paths
+ ' Change Dim of zFiles at top of VBZipBas.bas if more than 100 files
+ ' See note at top of VBZipBas.bas for limit on number of files
+
+' zArgc = 2 ' Number Of file paths below
+' zZipFileNames.zFiles(1) = "*.bas"
+' zZipFileNames.zFiles(2) = "*.frm"
+
+ '---------------
+ ' Example using file list string
+
+ ' List of files to zip as string of names with space between
+ ' Set zArgc = 0 as not using array
+ ' Using string for file list avoids above array limit
+
+ zArgc = 0
+' ReDim FilesToZip(1) ' dim to number of files below
+' FilesToZip(1) = "x:*.*"
+ ReDim FilesToZip(2) ' dim to number of files below
+ FilesToZip(1) = "*.bas"
+ FilesToZip(2) = "*.frm"
+
+ ' Build string of file names
+ ' Best to put double quotes around each in case of spaces
+ strZipFileNames = ""
+ For i = 1 To UBound(FilesToZip)
+ strZipFileNames = strZipFileNames & """" & FilesToZip(i) & """ "
+ Next
+ '---------------
+
+ '-- Go Zip Them Up!
+ retcode = VBZip32()
+
+ '-- Display The Returned Code Or Error!
+ Print "Return code:" & Str(retcode)
+
+End Sub
+
+Private Sub Form_Load()
+
+ Me.Show
+
+ Print "Click me!"
+
+End Sub
diff --git a/windll/VBz64/readVB64.txt b/windll/VBz64/readVB64.txt
new file mode 100644
index 0000000..2876b44
--- /dev/null
+++ b/windll/VBz64/readVB64.txt
@@ -0,0 +1,25 @@
+On Windows open this file in WordPad.
+
+Contents of the "windll/vbz64" sub-archive
+
+This directory contains a Visual Basic project example for using the
+zip32z64.dll library (Zip 3.0 with Zip64 enabled). See the comments in
+the form and project files for details.
+
+This new project and the new zip32z64.dll library are not compatible
+with previous VB examples using the zip32.dll interface as this new
+interface supports more files and handles file sizes larger than 2 GB.
+It should be simple to convert a VB program using zip32.dll to
+zip32z64.dll but the program may need some changes. For a compatible
+replacement use the dll compiled from Zip 2.32 (released separately)
+and see the zip32.dll example in the VB directory of this source tree.
+
+Note that the files may be saved in unix format with carriage returns
+stripped. These must be restored before the project can be successfully
+used. This can be done by using the -a option to unzip. Another way to
+do this is to open each file in WordPad, select and cut a line, paste
+the line back, and save the file. This will force WordPad to change the
+line ends in the entire file. Newer versions of WordPad may not do this.
+
+Ed Gordon
+4/26/2008
diff --git a/windll/Vb/VBZIP.vbw b/windll/Vb/VBZIP.vbw
new file mode 100644
index 0000000..2f8339a
--- /dev/null
+++ b/windll/Vb/VBZIP.vbw
@@ -0,0 +1,2 @@
+Form1 = 0, 0, 0, 0, C, 22, 22, 563, 389, C
+VBZipBas = 44, 44, 659, 489,
diff --git a/windll/vb/VBZipBas.bas b/windll/Vb/VBZipBas.bas
index 18ec77a..2b766e9 100644
--- a/windll/vb/VBZipBas.bas
+++ b/windll/Vb/VBZipBas.bas
@@ -36,11 +36,13 @@ Option Explicit
'--
'---------------------------------------------------------------
'
-' This is the original example with some small changes. Only
-' use with the original Zip32.dll (Zip 2.3). Do not use this VB
-' example with Zip32z64.dll (Zip 3.0).
+' This is the original example with some small changes. Only
+' use with the original Zip32.dll (compiled from Zip 2.31 or
+' later). Do not use this VB example with Zip32z64.dll
+' (compiled from Zip 3.0). To check the version of a dll,
+' right click on the file and check properties.
'
-' 4/29/2004 Ed Gordon
+' 6/24/2008 Ed Gordon
'---------------------------------------------------------------
' Usage notes:
@@ -62,9 +64,10 @@ Option Explicit
' can result in unpredictable behavior. A kluge is available
' for Zip32.dll, just replacing api.c in Zip 2.3, but better to just
' use the new Zip32z64.dll where these bugs are fixed. However,
-' the kluge has been added to Zip 2.31. To determine the version
-' of the dll you have right click on it, select the Version tab,
-' and verify the Product Version is at least 2.31.
+' the kluge has been added to Zip 2.31 and later and these are
+' now stable. To determine the version of the dll you have
+' right click on it, select the Version tab, and verify the
+' Product Version is at least 2.31.
'
' Another bug is where -R is used with some other options and can
' crash the dll. This is a bug in how zip processes the command
@@ -86,7 +89,7 @@ Option Explicit
' If you have any questions please contact Info-Zip at
' http://www.info-zip.org.
'
-' 4/29/2004 EG (Updated 3/1/2005 EG)
+' 4/29/2004 EG (Updated 3/1/2005, 6/24/2008 EG)
'
'---------------------------------------------------------------
diff --git a/windll/vb/Vbzip.vbp b/windll/Vb/Vbzip.vbp
index b5e5827..b5e5827 100644
--- a/windll/vb/Vbzip.vbp
+++ b/windll/Vb/Vbzip.vbp
diff --git a/windll/vb/Vbzipfrm.frm b/windll/Vb/Vbzipfrm.frm
index de323cd..de323cd 100644
--- a/windll/vb/Vbzipfrm.frm
+++ b/windll/Vb/Vbzipfrm.frm
diff --git a/windll/vb/readmeVB.txt b/windll/Vb/readmeVB.txt
index f1fc19f..1c36949 100644
--- a/windll/vb/readmeVB.txt
+++ b/windll/Vb/readmeVB.txt
@@ -6,23 +6,22 @@ This directory contains a Visual Basic project example for
using the zip32.dll library. This project updates the Zip 2.3 VB
project example and includes some bug fixes and many additional notes
but is still compatible with zip32.dll. See the comments in the form
-and project files for details. It has been tested on VB 5 and VB6.
+and project files for details. It has been tested on VB 5 and VB 6.
-Zip 2.31 itself has bug fixes as well, including some related to the
-dll, and you should now use a version of zip32.dll from that. This
-dll includes a fix for the VB dll bug where Date, szRootDir, and
+Zip 2.31 itself had bug fixes as well, including some related to the
+dll, and you should now use a version of zip32.dll from that or later.
+This dll includes a fix for the VB dll bug where Date, szRootDir, and
szTempDir were not passed in correctly and setting these to anything
but NULL could impact the dll and maybe crash it. You can tell which
version you have by right clicking on zip32.dll in a file listing,
looking at properties, selecting the Version tab, and verifying the
Product Version is at least 2.31.
-A new dll is available as part of the new Zip 3.0 beta. A new
-VB project included with that release now supports Zip64 and large
-files and it fixes even more bugs but is not backward compatible
-with zip32.dll. You will need the new dll zip32z64.dll to use that
-VB project, which can be compiled from the Zip 3.0 source. See
-windll/VBz64 in that release for details.
+A new dll is available as part of this Zip 3.0 release and a
+new VB project is included in the VBz64 directory. This dll and
+project supports Zip64 and large files but is not backward compatible
+with Zip32.dll. You will need the new zip32z64.dll to use this project,
+which can be compiled from Zip 3.0. See windll/VBz64 for details.
Note that the files may saved in unix format with carriage returns
stripped. These must be restored before the project can be successfully
@@ -32,4 +31,4 @@ the line back, and save the file. This will force WordPad to format
the entire file.
Ed Gordon
-3/1/2005
+2/2/2007
diff --git a/windll/contents b/windll/contents
index c063c26..36da176 100644
--- a/windll/contents
+++ b/windll/contents
@@ -1,4 +1,4 @@
-Contents of the "windll" sub-archive for Zip 2.31 and later:
+Contents of the "windll" sub-archive for Zip 2.2 and later:
contents this file
windll16.def definition file for 16-bit Zip DLL
@@ -16,22 +16,27 @@ Contents of the "windll" sub-archive for Zip 2.31 and later:
a call into it.
example.h header file for example.c
- visualc\dll <dir> contains Visual C++ 6.0 project and make files for
+ borland\dll <dir> contains 16 and 32 bit make files for the zip dlls.
+ borland\lib <dir> contains 32 bit make files for the zip32 static library
+ visualc\dll <dir> contains Visual C++ 5.0 project and make files for
zip32 dll.
- visualc\lib <dir> contains Visual C++ 6.0 project and make files for
+ visualc\lib <dir> contains Visual C++ 5.0 project and make files for
zip32 static library.
- vb-orig <dir> contains old version of a Visual Basic frontend example
- using zip32.dll
- vb <dir> new version of the Visual Basic dll frontend example,
- many bugfixes and enhancements
-The dll and static library port was developed and tested under Microsoft
-Visual C++ 6.0. The former support for the Borland C++ compilers has been
-discontinued; bcc-compiled DLLs are not universally usable because of their
-requirements for special Borland runtime libs (and probably some calling
-convention specialities).
-Compilation for 16-bit Windows 3.x is no longer supported.
+The Microsoft C port has not been tested as completely as the Borland port.
+Note that Borland C++ 5.0 is full of bugs version 4.5 is recommended instead.
+If you must use Borland C++ 5.0, using the Intel optimizing compiler is
+required to avoid crashes (possibly due to a bug in the stat() function
+in the normal Borland compiler.) This does have the advantage of giving you
+a smaller code size than the 4.52 compiler.
-Last updated February 22, 2005
+Borland C++ 5.01 has resolved many of the problems seen with 5.0, and
+can now reliably be used.
+
+Note that I have been singularly unsuccessful in getting this to compile
+and run under MSVC 1.52c.
+
+Last updated October 13, 1997
+
+Mike White
-Mike White, Christian Spieler
diff --git a/windll/example.c b/windll/example.c
index 05939af..f1a1936 100644
--- a/windll/example.c
+++ b/windll/example.c
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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.info-zip.org/pub/infozip/license.html
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
/*
A very simplistic example of how to load the zip dll and make a call into it.
diff --git a/windll/example.h b/windll/example.h
index 0061d5e..da52598 100644
--- a/windll/example.h
+++ b/windll/example.h
@@ -1,10 +1,10 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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.info-zip.org/pub/infozip/license.html
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
*/
/*
Example header file
diff --git a/windll/resource.h b/windll/resource.h
deleted file mode 100644
index be10954..0000000
--- a/windll/resource.h
+++ /dev/null
@@ -1,16 +0,0 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Developer Studio generated include file.
-// Used by windll.rc
-//
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NO_MFC 1
-#define _APS_NEXT_RESOURCE_VALUE 101
-#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1000
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif
diff --git a/windll/structs.h b/windll/structs.h
index f3c11a5..0f36df6 100644
--- a/windll/structs.h
+++ b/windll/structs.h
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ windll/structs.h - Zip 3
- See the accompanying file LICENSE, version 2004-May-22 or later
+ Copyright (c) 1990-2003 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2003-May-08 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
+ 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 _ZIP_STRUCTS_H
diff --git a/windll/vb/VBZIP.vbw b/windll/vb/VBZIP.vbw
deleted file mode 100644
index 907a008..0000000
--- a/windll/vb/VBZIP.vbw
+++ /dev/null
@@ -1,2 +0,0 @@
-Form1 = 22, 22, 668, 535, , 22, 22, 456, 360, C
-VBZipBas = 68, 5, 691, 512,
diff --git a/windll/visualc/dll/zip32.mak b/windll/visualc/dll/zip32.mak
deleted file mode 100644
index c3e33a6..0000000
--- a/windll/visualc/dll/zip32.mak
+++ /dev/null
@@ -1,858 +0,0 @@
-# Microsoft Developer Studio Generated NMAKE File, Based on zip32.dsp
-!IF "$(CFG)" == ""
-CFG=zip32 - Win32 Debug
-!MESSAGE No configuration specified. Defaulting to zip32 - Win32 Debug.
-!ENDIF
-
-!IF "$(CFG)" != "zip32 - Win32 Release" && "$(CFG)" != "zip32 - Win32 Debug"
-!MESSAGE Invalid configuration "$(CFG)" specified.
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "zip32.mak" CFG="zip32 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "zip32 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "zip32 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE
-!ERROR An invalid configuration is specified.
-!ENDIF
-
-!IF "$(OS)" == "Windows_NT"
-NULL=
-!ELSE
-NULL=nul
-!ENDIF
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-OUTDIR=.\..\Release\app
-INTDIR=.\Release
-# Begin Custom Macros
-OutDir=.\..\Release\app
-# End Custom Macros
-
-!IF "$(RECURSE)" == "0"
-
-ALL : "$(OUTDIR)\zip32.dll"
-
-!ELSE
-
-ALL : "$(OUTDIR)\zip32.dll"
-
-!ENDIF
-
-CLEAN :
- -@erase "$(INTDIR)\api.obj"
- -@erase "$(INTDIR)\crc32.obj"
- -@erase "$(INTDIR)\crctab.obj"
- -@erase "$(INTDIR)\crypt.obj"
- -@erase "$(INTDIR)\deflate.obj"
- -@erase "$(INTDIR)\fileio.obj"
- -@erase "$(INTDIR)\globals.obj"
- -@erase "$(INTDIR)\nt.obj"
- -@erase "$(INTDIR)\trees.obj"
- -@erase "$(INTDIR)\ttyio.obj"
- -@erase "$(INTDIR)\util.obj"
- -@erase "$(INTDIR)\vc50.idb"
- -@erase "$(INTDIR)\win32.obj"
- -@erase "$(INTDIR)\win32zip.obj"
- -@erase "$(INTDIR)\windll.obj"
- -@erase "$(INTDIR)\windll.res"
- -@erase "$(INTDIR)\zip.obj"
- -@erase "$(INTDIR)\zipfile.obj"
- -@erase "$(INTDIR)\zipup.obj"
- -@erase "$(OUTDIR)\zip32.dll"
- -@erase "$(OUTDIR)\zip32.exp"
- -@erase "$(OUTDIR)\zip32.lib"
-
-"$(OUTDIR)" :
- if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
-
-"$(INTDIR)" :
- if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)"
-
-CPP=cl.exe
-CPP_PROJ=/nologo /Zp4 /MT /W3 /GX /O2 /I "..\..\.." /I "..\..\..\WINDLL" /I "..\..\..\WIN32" /D "NDEBUG" /D "_WINDOWS" /D "WIN32" /D "NO_ASM" /D "WINDLL" /D\
- "MSDOS" /D "USE_ZIPMAIN" /Fp"$(INTDIR)\zip32.pch" /YX\
- /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
-CPP_OBJS=.\Release/
-CPP_SBRS=.
-
-.c{$(CPP_OBJS)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cpp{$(CPP_OBJS)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cxx{$(CPP_OBJS)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.c{$(CPP_SBRS)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cpp{$(CPP_SBRS)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cxx{$(CPP_SBRS)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-MTL=midl.exe
-MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /o NUL /win32
-RSC=rc.exe
-RSC_PROJ=/l 0x409 /fo"$(INTDIR)\windll.res" /d "NDEBUG" /d "WIN32"
-BSC32=bscmake.exe
-BSC32_FLAGS=/nologo /o"$(OUTDIR)\zip32.bsc"
-BSC32_SBRS= \
-
-LINK32=link.exe
-LINK32_FLAGS=kernel32.lib user32.lib advapi32.lib\
- /nologo /subsystem:windows /dll /incremental:no\
- /pdb:"$(OUTDIR)\zip32.pdb" /machine:I386\
- /def:"..\..\..\windll\windll32.def" /out:"$(OUTDIR)\zip32.dll"\
- /implib:"$(OUTDIR)\zip32.lib"
-DEF_FILE= \
- "..\..\..\windll\windll32.def"
-LINK32_OBJS= \
- "$(INTDIR)\api.obj" \
- "$(INTDIR)\crc32.obj" \
- "$(INTDIR)\crctab.obj" \
- "$(INTDIR)\crypt.obj" \
- "$(INTDIR)\deflate.obj" \
- "$(INTDIR)\fileio.obj" \
- "$(INTDIR)\globals.obj" \
- "$(INTDIR)\nt.obj" \
- "$(INTDIR)\trees.obj" \
- "$(INTDIR)\ttyio.obj" \
- "$(INTDIR)\util.obj" \
- "$(INTDIR)\win32.obj" \
- "$(INTDIR)\win32zip.obj" \
- "$(INTDIR)\windll.obj" \
- "$(INTDIR)\windll.res" \
- "$(INTDIR)\zip.obj" \
- "$(INTDIR)\zipfile.obj" \
- "$(INTDIR)\zipup.obj"
-
-"$(OUTDIR)\zip32.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
- $(LINK32) @<<
- $(LINK32_FLAGS) $(LINK32_OBJS)
-<<
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-OUTDIR=.\..\Debug\app
-INTDIR=.\Debug
-# Begin Custom Macros
-OutDir=.\..\Debug\app
-# End Custom Macros
-
-!IF "$(RECURSE)" == "0"
-
-ALL : "$(OUTDIR)\zip32.dll"
-
-!ELSE
-
-ALL : "$(OUTDIR)\zip32.dll"
-
-!ENDIF
-
-CLEAN :
- -@erase "$(INTDIR)\api.obj"
- -@erase "$(INTDIR)\crc32.obj"
- -@erase "$(INTDIR)\crctab.obj"
- -@erase "$(INTDIR)\crypt.obj"
- -@erase "$(INTDIR)\deflate.obj"
- -@erase "$(INTDIR)\fileio.obj"
- -@erase "$(INTDIR)\globals.obj"
- -@erase "$(INTDIR)\nt.obj"
- -@erase "$(INTDIR)\trees.obj"
- -@erase "$(INTDIR)\ttyio.obj"
- -@erase "$(INTDIR)\util.obj"
- -@erase "$(INTDIR)\vc50.idb"
- -@erase "$(INTDIR)\vc50.pdb"
- -@erase "$(INTDIR)\win32.obj"
- -@erase "$(INTDIR)\win32zip.obj"
- -@erase "$(INTDIR)\windll.obj"
- -@erase "$(INTDIR)\windll.res"
- -@erase "$(INTDIR)\zip.obj"
- -@erase "$(INTDIR)\zipfile.obj"
- -@erase "$(INTDIR)\zipup.obj"
- -@erase "$(OUTDIR)\zip32.dll"
- -@erase "$(OUTDIR)\zip32.exp"
- -@erase "$(OUTDIR)\zip32.ilk"
- -@erase "$(OUTDIR)\zip32.lib"
- -@erase "$(OUTDIR)\zip32.pdb"
-
-"$(OUTDIR)" :
- if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
-
-"$(INTDIR)" :
- if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)"
-
-CPP=cl.exe
-CPP_PROJ=/nologo /Zp4 /MTd /W3 /Gm /GX /Zi /Od /I "..\..\.." /I\
- "..\..\..\WINDLL" /I "..\..\..\WIN32" /D "_DEBUG" /D "_WINDOWS" /D "WIN32" /D\
- "NO_ASM" /D "WINDLL" /D "MSDOS" /D "USE_ZIPMAIN"\
- /Fp"$(INTDIR)\zip32.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
-CPP_OBJS=.\Debug/
-CPP_SBRS=.
-
-.c{$(CPP_OBJS)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cpp{$(CPP_OBJS)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cxx{$(CPP_OBJS)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.c{$(CPP_SBRS)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cpp{$(CPP_SBRS)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cxx{$(CPP_SBRS)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-MTL=midl.exe
-MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /o NUL /win32
-RSC=rc.exe
-RSC_PROJ=/l 0x409 /fo"$(INTDIR)\windll.res" /d "_DEBUG" /d "WIN32"
-BSC32=bscmake.exe
-BSC32_FLAGS=/nologo /o"$(OUTDIR)\zip32.bsc"
-BSC32_SBRS= \
-
-LINK32=link.exe
-LINK32_FLAGS=kernel32.lib user32.lib advapi32.lib\
- /nologo /subsystem:windows /dll /incremental:yes\
- /pdb:"$(OUTDIR)\zip32.pdb" /debug /machine:I386\
- /def:"..\..\..\windll\windll32.def" /out:"$(OUTDIR)\zip32.dll"\
- /implib:"$(OUTDIR)\zip32.lib" /pdbtype:sept
-DEF_FILE= \
- "..\..\..\windll\windll32.def"
-LINK32_OBJS= \
- "$(INTDIR)\api.obj" \
- "$(INTDIR)\crc32.obj" \
- "$(INTDIR)\crctab.obj" \
- "$(INTDIR)\crypt.obj" \
- "$(INTDIR)\deflate.obj" \
- "$(INTDIR)\fileio.obj" \
- "$(INTDIR)\globals.obj" \
- "$(INTDIR)\nt.obj" \
- "$(INTDIR)\trees.obj" \
- "$(INTDIR)\ttyio.obj" \
- "$(INTDIR)\util.obj" \
- "$(INTDIR)\win32.obj" \
- "$(INTDIR)\win32zip.obj" \
- "$(INTDIR)\windll.obj" \
- "$(INTDIR)\windll.res" \
- "$(INTDIR)\zip.obj" \
- "$(INTDIR)\zipfile.obj" \
- "$(INTDIR)\zipup.obj"
-
-"$(OUTDIR)\zip32.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
- $(LINK32) @<<
- $(LINK32_FLAGS) $(LINK32_OBJS)
-<<
-
-!ENDIF
-
-
-!IF "$(CFG)" == "zip32 - Win32 Release" || "$(CFG)" == "zip32 - Win32 Debug"
-SOURCE=D:\wiz\zip\api.c
-DEP_CPP_API_C=\
- "..\..\..\api.h"\
- "..\..\..\crypt.h"\
- "..\..\..\revision.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\windll\structs.h"\
- "..\..\..\windll\windll.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\api.obj" : $(SOURCE) $(DEP_CPP_API_C) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-SOURCE=D:\wiz\zip\crc32.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_CRC32=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\crc32.obj" : $(SOURCE) $(DEP_CPP_CRC32) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_CRC32=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\crc32.obj" : $(SOURCE) $(DEP_CPP_CRC32) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=D:\wiz\zip\crctab.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_CRCTA=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\crctab.obj" : $(SOURCE) $(DEP_CPP_CRCTA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_CRCTA=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\crctab.obj" : $(SOURCE) $(DEP_CPP_CRCTA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=D:\wiz\zip\crypt.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_CRYPT=\
- "..\..\..\api.h"\
- "..\..\..\crypt.h"\
- "..\..\..\tailor.h"\
- "..\..\..\ttyio.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\crypt.obj" : $(SOURCE) $(DEP_CPP_CRYPT) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_CRYPT=\
- "..\..\..\api.h"\
- "..\..\..\crypt.h"\
- "..\..\..\tailor.h"\
- "..\..\..\ttyio.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\crypt.obj" : $(SOURCE) $(DEP_CPP_CRYPT) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=D:\wiz\zip\deflate.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_DEFLA=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\deflate.obj" : $(SOURCE) $(DEP_CPP_DEFLA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_DEFLA=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\deflate.obj" : $(SOURCE) $(DEP_CPP_DEFLA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=D:\wiz\zip\fileio.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_FILEI=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\fileio.obj" : $(SOURCE) $(DEP_CPP_FILEI) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_FILEI=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\fileio.obj" : $(SOURCE) $(DEP_CPP_FILEI) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=D:\wiz\zip\globals.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_GLOBA=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\globals.obj" : $(SOURCE) $(DEP_CPP_GLOBA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_GLOBA=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\globals.obj" : $(SOURCE) $(DEP_CPP_GLOBA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=D:\wiz\zip\Win32\nt.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_NT_C10=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\nt.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\nt.obj" : $(SOURCE) $(DEP_CPP_NT_C10) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_NT_C10=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\nt.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\nt.obj" : $(SOURCE) $(DEP_CPP_NT_C10) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=D:\wiz\zip\trees.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_TREES=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\trees.obj" : $(SOURCE) $(DEP_CPP_TREES) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_TREES=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\trees.obj" : $(SOURCE) $(DEP_CPP_TREES) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=D:\wiz\zip\ttyio.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_TTYIO=\
- "..\..\..\api.h"\
- "..\..\..\crypt.h"\
- "..\..\..\tailor.h"\
- "..\..\..\ttyio.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\ttyio.obj" : $(SOURCE) $(DEP_CPP_TTYIO) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_TTYIO=\
- "..\..\..\api.h"\
- "..\..\..\crypt.h"\
- "..\..\..\tailor.h"\
- "..\..\..\ttyio.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\ttyio.obj" : $(SOURCE) $(DEP_CPP_TTYIO) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=D:\wiz\zip\util.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_UTIL_=\
- "..\..\..\api.h"\
- "..\..\..\ebcdic.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\util.obj" : $(SOURCE) $(DEP_CPP_UTIL_) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_UTIL_=\
- "..\..\..\api.h"\
- "..\..\..\ebcdic.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\util.obj" : $(SOURCE) $(DEP_CPP_UTIL_) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=D:\wiz\zip\Win32\win32.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_WIN32=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\win32\win32zip.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\win32.obj" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_WIN32=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\win32\win32zip.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\win32.obj" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=D:\wiz\zip\Win32\win32zip.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_WIN32Z=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\nt.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\win32\win32zip.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\win32zip.obj" : $(SOURCE) $(DEP_CPP_WIN32Z) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_WIN32Z=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\nt.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\win32\win32zip.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\win32zip.obj" : $(SOURCE) $(DEP_CPP_WIN32Z) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=D:\wiz\zip\windll\windll.c
-DEP_CPP_WINDL=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\windll\structs.h"\
- "..\..\..\windll\windll.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\windll.obj" : $(SOURCE) $(DEP_CPP_WINDL) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-SOURCE=D:\wiz\zip\windll\windll.rc
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-
-"$(INTDIR)\windll.res" : $(SOURCE) "$(INTDIR)"
- $(RSC) /l 0x409 /fo"$(INTDIR)\windll.res" /i "\wiz\zip\windll" /d "NDEBUG" /d\
- "WIN32" $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-
-"$(INTDIR)\windll.res" : $(SOURCE) "$(INTDIR)"
- $(RSC) /l 0x409 /fo"$(INTDIR)\windll.res" /i "\wiz\zip\windll" /d "_DEBUG" /d\
- "WIN32" $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=D:\wiz\zip\zip.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_ZIP_C=\
- "..\..\..\api.h"\
- "..\..\..\crypt.h"\
- "..\..\..\revision.h"\
- "..\..\..\tailor.h"\
- "..\..\..\ttyio.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\windll\structs.h"\
- "..\..\..\windll\windll.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\zip.obj" : $(SOURCE) $(DEP_CPP_ZIP_C) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_ZIP_C=\
- "..\..\..\api.h"\
- "..\..\..\crypt.h"\
- "..\..\..\revision.h"\
- "..\..\..\tailor.h"\
- "..\..\..\ttyio.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\windll\structs.h"\
- "..\..\..\windll\windll.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\zip.obj" : $(SOURCE) $(DEP_CPP_ZIP_C) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=D:\wiz\zip\zipfile.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_ZIPFI=\
- "..\..\..\api.h"\
- "..\..\..\revision.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\zipfile.obj" : $(SOURCE) $(DEP_CPP_ZIPFI) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_ZIPFI=\
- "..\..\..\api.h"\
- "..\..\..\revision.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\zipfile.obj" : $(SOURCE) $(DEP_CPP_ZIPFI) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=D:\wiz\zip\zipup.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_ZIPUP=\
- "..\..\..\api.h"\
- "..\..\..\crypt.h"\
- "..\..\..\revision.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\win32\zipup.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\zipup.obj" : $(SOURCE) $(DEP_CPP_ZIPUP) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_ZIPUP=\
- "..\..\..\api.h"\
- "..\..\..\crypt.h"\
- "..\..\..\revision.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\win32\zipup.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\zipup.obj" : $(SOURCE) $(DEP_CPP_ZIPUP) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-
-!ENDIF
-
diff --git a/windll/visualc/dll/zip32.dsp b/windll/visualc/dll/zip32z64.dsp
index 91d01d8..46bea99 100644
--- a/windll/visualc/dll/zip32.dsp
+++ b/windll/visualc/dll/zip32z64.dsp
@@ -1,24 +1,24 @@
-# Microsoft Developer Studio Project File - Name="zip32" - Package Owner=<4>
+# Microsoft Developer Studio Project File - Name="zip32z64" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
-CFG=zip32 - Win32 Debug
+CFG=zip32z64 - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
-!MESSAGE NMAKE /f "zip32.mak".
+!MESSAGE NMAKE /f "zip32z64.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
-!MESSAGE NMAKE /f "zip32.mak" CFG="zip32 - Win32 Debug"
+!MESSAGE NMAKE /f "zip32z64.mak" CFG="zip32z64 - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
-!MESSAGE "zip32 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "zip32 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "zip32z64 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "zip32z64 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
@@ -29,7 +29,7 @@ CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
-!IF "$(CFG)" == "zip32 - Win32 Release"
+!IF "$(CFG)" == "zip32z64 - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
@@ -55,7 +55,7 @@ LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:windows /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:windows /dll /machine:I386
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
+!ELSEIF "$(CFG)" == "zip32z64 - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
@@ -79,15 +79,15 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"..\Debug\app/zip32z64.dll" /pdbtype:sept
# SUBTRACT LINK32 /map
!ENDIF
# Begin Target
-# Name "zip32 - Win32 Release"
-# Name "zip32 - Win32 Debug"
+# Name "zip32z64 - Win32 Release"
+# Name "zip32z64 - Win32 Debug"
# Begin Source File
SOURCE=..\..\..\api.c
@@ -98,10 +98,6 @@ SOURCE=..\..\..\crc32.c
# End Source File
# Begin Source File
-SOURCE=..\..\..\crctab.c
-# End Source File
-# Begin Source File
-
SOURCE=..\..\..\crypt.c
# End Source File
# Begin Source File
@@ -138,6 +134,10 @@ SOURCE=..\..\..\win32\win32.c
# End Source File
# Begin Source File
+SOURCE=..\..\..\win32\win32i64.c
+# End Source File
+# Begin Source File
+
SOURCE=..\..\..\win32\win32zip.c
# End Source File
# Begin Source File
diff --git a/windll/visualc/dll/zip32.dsw b/windll/visualc/dll/zip32z64.dsw
index cb9248d..4643105 100644
--- a/windll/visualc/dll/zip32.dsw
+++ b/windll/visualc/dll/zip32z64.dsw
@@ -3,7 +3,7 @@ Microsoft Developer Studio Workspace File, Format Version 6.00
###############################################################################
-Project: "zip32"=.\zip32.dsp - Package Owner=<4>
+Project: "zip32z64"=.\zip32z64.dsp - Package Owner=<4>
Package=<5>
{{{
diff --git a/windll/visualc/lib/zip32.mak b/windll/visualc/lib/zip32.mak
deleted file mode 100644
index 4ea7923..0000000
--- a/windll/visualc/lib/zip32.mak
+++ /dev/null
@@ -1,586 +0,0 @@
-# Microsoft Developer Studio Generated NMAKE File, Based on zip32.dsp
-!IF "$(CFG)" == ""
-CFG=zip32 - Win32 Debug
-!MESSAGE No configuration specified. Defaulting to zip32 - Win32 Debug.
-!ENDIF
-
-!IF "$(CFG)" != "zip32 - Win32 Release" && "$(CFG)" != "zip32 - Win32 Debug"
-!MESSAGE Invalid configuration "$(CFG)" specified.
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "zip32.mak" CFG="zip32 - Win32 Debug"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "zip32 - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "zip32 - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-!ERROR An invalid configuration is specified.
-!ENDIF
-
-!IF "$(OS)" == "Windows_NT"
-NULL=
-!ELSE
-NULL=nul
-!ENDIF
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-OUTDIR=.\..\Release\libs
-INTDIR=.\Release
-# Begin Custom Macros
-OutDir=.\..\Release\libs
-# End Custom Macros
-
-!IF "$(RECURSE)" == "0"
-
-ALL : "$(OUTDIR)\zip32.lib"
-
-!ELSE
-
-ALL : "$(OUTDIR)\zip32.lib"
-
-!ENDIF
-
-CLEAN :
- -@erase "$(INTDIR)\api.obj"
- -@erase "$(INTDIR)\crc32.obj"
- -@erase "$(INTDIR)\crctab.obj"
- -@erase "$(INTDIR)\crypt.obj"
- -@erase "$(INTDIR)\deflate.obj"
- -@erase "$(INTDIR)\fileio.obj"
- -@erase "$(INTDIR)\globals.obj"
- -@erase "$(INTDIR)\nt.obj"
- -@erase "$(INTDIR)\trees.obj"
- -@erase "$(INTDIR)\ttyio.obj"
- -@erase "$(INTDIR)\util.obj"
- -@erase "$(INTDIR)\vc50.idb"
- -@erase "$(INTDIR)\win32.obj"
- -@erase "$(INTDIR)\win32zip.obj"
- -@erase "$(INTDIR)\windll.obj"
- -@erase "$(INTDIR)\zip.obj"
- -@erase "$(INTDIR)\zipfile.obj"
- -@erase "$(INTDIR)\zipup.obj"
- -@erase "$(OUTDIR)\zip32.lib"
-
-"$(OUTDIR)" :
- if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
-
-"$(INTDIR)" :
- if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)"
-
-CPP=cl.exe
-CPP_PROJ=/nologo /ML /W3 /GX /O2 /I "..\..\.." /I "..\..\..\WIN32" /I\
- "..\..\..\WINDLL" /D "NDEBUG" /D "_WINDOWS" /D "WIN32" /D "NO_ASM" /D\
- "WINDLL" /D "MSDOS" /D "USE_ZIPMAIN" /D "ZIPLIB"\
- /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
-CPP_OBJS=.\Release/
-CPP_SBRS=.
-
-.c{$(CPP_OBJS)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cpp{$(CPP_OBJS)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cxx{$(CPP_OBJS)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.c{$(CPP_SBRS)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cpp{$(CPP_SBRS)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cxx{$(CPP_SBRS)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-BSC32=bscmake.exe
-BSC32_FLAGS=/nologo /o"$(OUTDIR)\zip32.bsc"
-BSC32_SBRS= \
-
-LIB32=link.exe -lib
-LIB32_FLAGS=/nologo /out:"$(OUTDIR)\zip32.lib"
-LIB32_OBJS= \
- "$(INTDIR)\api.obj" \
- "$(INTDIR)\crc32.obj" \
- "$(INTDIR)\crctab.obj" \
- "$(INTDIR)\crypt.obj" \
- "$(INTDIR)\deflate.obj" \
- "$(INTDIR)\fileio.obj" \
- "$(INTDIR)\globals.obj" \
- "$(INTDIR)\nt.obj" \
- "$(INTDIR)\trees.obj" \
- "$(INTDIR)\ttyio.obj" \
- "$(INTDIR)\util.obj" \
- "$(INTDIR)\win32.obj" \
- "$(INTDIR)\win32zip.obj" \
- "$(INTDIR)\windll.obj" \
- "$(INTDIR)\zip.obj" \
- "$(INTDIR)\zipfile.obj" \
- "$(INTDIR)\zipup.obj"
-
-"$(OUTDIR)\zip32.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS)
- $(LIB32) @<<
- $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS)
-<<
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-OUTDIR=.\..\Debug\libs
-INTDIR=.\Debug
-# Begin Custom Macros
-OutDir=.\..\Debug\libs
-# End Custom Macros
-
-!IF "$(RECURSE)" == "0"
-
-ALL : "$(OUTDIR)\zip32.lib"
-
-!ELSE
-
-ALL : "$(OUTDIR)\zip32.lib"
-
-!ENDIF
-
-CLEAN :
- -@erase "$(INTDIR)\api.obj"
- -@erase "$(INTDIR)\crc32.obj"
- -@erase "$(INTDIR)\crctab.obj"
- -@erase "$(INTDIR)\crypt.obj"
- -@erase "$(INTDIR)\deflate.obj"
- -@erase "$(INTDIR)\fileio.obj"
- -@erase "$(INTDIR)\globals.obj"
- -@erase "$(INTDIR)\nt.obj"
- -@erase "$(INTDIR)\trees.obj"
- -@erase "$(INTDIR)\ttyio.obj"
- -@erase "$(INTDIR)\util.obj"
- -@erase "$(INTDIR)\vc50.idb"
- -@erase "$(INTDIR)\win32.obj"
- -@erase "$(INTDIR)\win32zip.obj"
- -@erase "$(INTDIR)\windll.obj"
- -@erase "$(INTDIR)\zip.obj"
- -@erase "$(INTDIR)\zipfile.obj"
- -@erase "$(INTDIR)\zipup.obj"
- -@erase "$(OUTDIR)\zip32.lib"
-
-"$(OUTDIR)" :
- if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
-
-"$(INTDIR)" :
- if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)"
-
-CPP=cl.exe
-CPP_PROJ=/nologo /MLd /W3 /GX /Z7 /Od /I "..\..\.." /I "..\..\..\WIN32" /I\
- "..\..\..\WINDLL" /D "_DEBUG" /D "_WINDOWS" /D "WIN32" /D "NO_ASM" /D\
- "WINDLL" /D "MSDOS" /D "USE_ZIPMAIN" /D "ZIPLIB"\
- /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
-CPP_OBJS=.\Debug/
-CPP_SBRS=.
-
-.c{$(CPP_OBJS)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cpp{$(CPP_OBJS)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cxx{$(CPP_OBJS)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.c{$(CPP_SBRS)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cpp{$(CPP_SBRS)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cxx{$(CPP_SBRS)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-BSC32=bscmake.exe
-BSC32_FLAGS=/nologo /o"$(OUTDIR)\zip32.bsc"
-BSC32_SBRS= \
-
-LIB32=link.exe -lib
-LIB32_FLAGS=/nologo /out:"$(OUTDIR)\zip32.lib"
-LIB32_OBJS= \
- "$(INTDIR)\api.obj" \
- "$(INTDIR)\crc32.obj" \
- "$(INTDIR)\crctab.obj" \
- "$(INTDIR)\crypt.obj" \
- "$(INTDIR)\deflate.obj" \
- "$(INTDIR)\fileio.obj" \
- "$(INTDIR)\globals.obj" \
- "$(INTDIR)\nt.obj" \
- "$(INTDIR)\trees.obj" \
- "$(INTDIR)\ttyio.obj" \
- "$(INTDIR)\util.obj" \
- "$(INTDIR)\win32.obj" \
- "$(INTDIR)\win32zip.obj" \
- "$(INTDIR)\windll.obj" \
- "$(INTDIR)\zip.obj" \
- "$(INTDIR)\zipfile.obj" \
- "$(INTDIR)\zipup.obj"
-
-"$(OUTDIR)\zip32.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS)
- $(LIB32) @<<
- $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS)
-<<
-
-!ENDIF
-
-
-!IF "$(CFG)" == "zip32 - Win32 Release" || "$(CFG)" == "zip32 - Win32 Debug"
-SOURCE=..\..\..\api.c
-DEP_CPP_API_C=\
- "..\..\..\api.h"\
- "..\..\..\crypt.h"\
- "..\..\..\revision.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\windll\structs.h"\
- "..\..\..\windll\windll.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\api.obj" : $(SOURCE) $(DEP_CPP_API_C) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-SOURCE=..\..\..\crc32.c
-DEP_CPP_CRC32=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\crc32.obj" : $(SOURCE) $(DEP_CPP_CRC32) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-SOURCE=..\..\..\crctab.c
-DEP_CPP_CRCTA=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\crctab.obj" : $(SOURCE) $(DEP_CPP_CRCTA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-SOURCE=..\..\..\crypt.c
-DEP_CPP_CRYPT=\
- "..\..\..\api.h"\
- "..\..\..\crypt.h"\
- "..\..\..\tailor.h"\
- "..\..\..\ttyio.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\crypt.obj" : $(SOURCE) $(DEP_CPP_CRYPT) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-SOURCE=..\..\..\deflate.c
-DEP_CPP_DEFLA=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\deflate.obj" : $(SOURCE) $(DEP_CPP_DEFLA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-SOURCE=..\..\..\fileio.c
-DEP_CPP_FILEI=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\fileio.obj" : $(SOURCE) $(DEP_CPP_FILEI) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-SOURCE=..\..\..\globals.c
-DEP_CPP_GLOBA=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\globals.obj" : $(SOURCE) $(DEP_CPP_GLOBA) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-SOURCE=..\..\..\Win32\nt.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_NT_C10=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\nt.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\nt.obj" : $(SOURCE) $(DEP_CPP_NT_C10) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_NT_C10=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\nt.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\nt.obj" : $(SOURCE) $(DEP_CPP_NT_C10) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=..\..\..\trees.c
-DEP_CPP_TREES=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\trees.obj" : $(SOURCE) $(DEP_CPP_TREES) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-SOURCE=..\..\..\ttyio.c
-DEP_CPP_TTYIO=\
- "..\..\..\api.h"\
- "..\..\..\crypt.h"\
- "..\..\..\tailor.h"\
- "..\..\..\ttyio.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\ttyio.obj" : $(SOURCE) $(DEP_CPP_TTYIO) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-SOURCE=..\..\..\util.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_UTIL_=\
- "..\..\..\api.h"\
- "..\..\..\ebcdic.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\util.obj" : $(SOURCE) $(DEP_CPP_UTIL_) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_UTIL_=\
- "..\..\..\api.h"\
- "..\..\..\ebcdic.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\util.obj" : $(SOURCE) $(DEP_CPP_UTIL_) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=..\..\..\Win32\win32.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_WIN32=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\win32\win32zip.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\win32.obj" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_WIN32=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\win32\win32zip.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\win32.obj" : $(SOURCE) $(DEP_CPP_WIN32) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=..\..\..\Win32\win32zip.c
-
-!IF "$(CFG)" == "zip32 - Win32 Release"
-
-DEP_CPP_WIN32Z=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\nt.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\win32\win32zip.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\win32zip.obj" : $(SOURCE) $(DEP_CPP_WIN32Z) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
-
-DEP_CPP_WIN32Z=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\nt.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\win32\win32zip.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\win32zip.obj" : $(SOURCE) $(DEP_CPP_WIN32Z) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-!ENDIF
-
-SOURCE=..\..\..\windll\windll.c
-DEP_CPP_WINDL=\
- "..\..\..\api.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\windll\structs.h"\
- "..\..\..\windll\windll.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\windll.obj" : $(SOURCE) $(DEP_CPP_WINDL) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-SOURCE=..\..\..\zip.c
-DEP_CPP_ZIP_C=\
- "..\..\..\api.h"\
- "..\..\..\crypt.h"\
- "..\..\..\revision.h"\
- "..\..\..\tailor.h"\
- "..\..\..\ttyio.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\windll\structs.h"\
- "..\..\..\windll\windll.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\zip.obj" : $(SOURCE) $(DEP_CPP_ZIP_C) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-SOURCE=..\..\..\zipfile.c
-DEP_CPP_ZIPFI=\
- "..\..\..\api.h"\
- "..\..\..\revision.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\zipfile.obj" : $(SOURCE) $(DEP_CPP_ZIPFI) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-SOURCE=..\..\..\zipup.c
-DEP_CPP_ZIPUP=\
- "..\..\..\api.h"\
- "..\..\..\crypt.h"\
- "..\..\..\revision.h"\
- "..\..\..\tailor.h"\
- "..\..\..\win32\osdep.h"\
- "..\..\..\win32\zipup.h"\
- "..\..\..\zip.h"\
- "..\..\..\ziperr.h"\
-
-
-"$(INTDIR)\zipup.obj" : $(SOURCE) $(DEP_CPP_ZIPUP) "$(INTDIR)"
- $(CPP) $(CPP_PROJ) $(SOURCE)
-
-
-
-!ENDIF
-
diff --git a/windll/visualc/lib/zip32.dsp b/windll/visualc/lib/zip32z64.dsp
index d23896c..a610912 100644
--- a/windll/visualc/lib/zip32.dsp
+++ b/windll/visualc/lib/zip32z64.dsp
@@ -1,24 +1,24 @@
-# Microsoft Developer Studio Project File - Name="zip32" - Package Owner=<4>
+# Microsoft Developer Studio Project File - Name="zip32z64" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
-CFG=zip32 - Win32 Debug
+CFG=zip32z64 - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
-!MESSAGE NMAKE /f "zip32.mak".
+!MESSAGE NMAKE /f "zip32z64.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
-!MESSAGE NMAKE /f "zip32.mak" CFG="zip32 - Win32 Debug"
+!MESSAGE NMAKE /f "zip32z64.mak" CFG="zip32z64 - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
-!MESSAGE "zip32 - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "zip32 - Win32 Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE "zip32z64 - Win32 Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "zip32z64 - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
@@ -28,7 +28,7 @@ CFG=zip32 - Win32 Debug
CPP=cl.exe
RSC=rc.exe
-!IF "$(CFG)" == "zip32 - Win32 Release"
+!IF "$(CFG)" == "zip32z64 - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
@@ -52,7 +52,7 @@ LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
-!ELSEIF "$(CFG)" == "zip32 - Win32 Debug"
+!ELSEIF "$(CFG)" == "zip32z64 - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
@@ -80,8 +80,8 @@ LIB32=link.exe -lib
# Begin Target
-# Name "zip32 - Win32 Release"
-# Name "zip32 - Win32 Debug"
+# Name "zip32z64 - Win32 Release"
+# Name "zip32z64 - Win32 Debug"
# Begin Source File
SOURCE=..\..\..\api.c
@@ -92,10 +92,6 @@ SOURCE=..\..\..\crc32.c
# End Source File
# Begin Source File
-SOURCE=..\..\..\crctab.c
-# End Source File
-# Begin Source File
-
SOURCE=..\..\..\crypt.c
# End Source File
# Begin Source File
diff --git a/windll/visualc/lib/zip32.dsw b/windll/visualc/lib/zip32z64.dsw
index cb9248d..4643105 100644
--- a/windll/visualc/lib/zip32.dsw
+++ b/windll/visualc/lib/zip32z64.dsw
@@ -3,7 +3,7 @@ Microsoft Developer Studio Workspace File, Format Version 6.00
###############################################################################
-Project: "zip32"=.\zip32.dsp - Package Owner=<4>
+Project: "zip32z64"=.\zip32z64.dsp - Package Owner=<4>
Package=<5>
{{{
diff --git a/windll/windll.aps b/windll/windll.aps
new file mode 100644
index 0000000..73e3468
--- /dev/null
+++ b/windll/windll.aps
Binary files differ
diff --git a/windll/windll.c b/windll/windll.c
index 7da7304..f825108 100644
--- a/windll/windll.c
+++ b/windll/windll.c
@@ -1,10 +1,12 @@
/*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+ windll/windll.c - Zip 3
- See the accompanying file LICENSE, version 1999-Oct-05 or later
+ Copyright (c) 1990-2004 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2003-May-08 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, 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
*/
/*
* windll.c by Mike White loosly based on Mark Adler's zip.c
@@ -168,7 +170,7 @@ return len;
void __far __cdecl perror(const char *parm1)
{
-printf(parm1);
+printf("%s", parm1);
}
diff --git a/windll/windll.h b/windll/windll.h
index fc20027..0a45fc1 100644
--- a/windll/windll.h
+++ b/windll/windll.h
@@ -1,10 +1,12 @@
/*
- Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+ windll/windll.h - Zip 3
- See the accompanying file LICENSE, version 1999-Oct-05 or later
+ Copyright (c) 1990-2004 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2003-May-08 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, 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
*/
/*
WiZ 1.0 header file for zip dll
@@ -43,7 +45,7 @@
#define cchFilesMax 4096
-extern int WINAPI ZpArchive(ZCL C);
+extern int WINAPI ZpArchive(ZCL C, LPZPOPT Opts);
extern HWND hGetFilesDlg;
extern char szFilesToAdd[80];
extern char rgszFiles[cchFilesMax];
diff --git a/windll/windll.rc b/windll/windll.rc
index 23adef4..4fab86a 100644
--- a/windll/windll.rc
+++ b/windll/windll.rc
@@ -1,115 +1,57 @@
-//Microsoft Developer Studio generated resource script.
-//
-#include "resource.h"
-
#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
#define APSTUDIO_HIDDEN_SYMBOLS
-#include "windows.h"
+#include <windows.h>
+#if (defined(WIN32) && !defined(__EMX__) && !defined(__MINGW32__))
+#include <winver.h>
+#endif
#undef APSTUDIO_HIDDEN_SYMBOLS
-#include "zipver.h"
+#include "../revision.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
-// English (U.S.) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
-#ifdef _WIN32
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-#pragma code_page(1252)
-#endif //_WIN32
-
-#ifndef _MAC
-/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,1,0,0
- PRODUCTVERSION 2,3,1,0
+ FILEVERSION Z_MAJORVER,Z_MINORVER,Z_PATCHLEVEL,0
+ PRODUCTVERSION Z_MAJORVER,Z_MINORVER,Z_PATCHLEVEL,0
FILEFLAGSMASK 0x3L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
- FILEOS 0x1L
- FILETYPE 0x2L
+ FILEOS VOS__WINDOWS32
+ FILETYPE VFT_DLL
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
- BLOCK "040904e4"
+#ifdef _UNICODE
+ BLOCK "040904B0"
+#else
+ BLOCK "040904E4"
+#endif
BEGIN
- VALUE "Comments", "\0"
- VALUE "CompanyName", "Info-ZIP\0"
+ VALUE "CompanyName", IZ_COMPANY_NAME "\0"
VALUE "FileDescription", "Info-ZIP's Zip dll\0"
- VALUE "FileVersion", "2.31\0"
- VALUE "InternalName", "Zip32\0"
- VALUE "LegalCopyright", "Info-ZIP 2005\0"
- VALUE "LegalTrademarks", "\0"
- VALUE "OriginalFilename", "ZIP32.DLL\0"
- VALUE "PrivateBuild", "\0"
+ VALUE "FileVersion", VERSION "\0"
+ VALUE "InternalName", "Zip32z64\0"
+ VALUE "LegalCopyright", "Info-ZIP 1997 - 2008\0"
+ VALUE "OriginalFilename", "ZIP32Z64.DLL\0"
VALUE "ProductName", "Info-ZIP's WiZ\0"
- VALUE "ProductVersion", "2.31\0"
- VALUE "SpecialBuild", "\0"
+ VALUE "ProductVersion", VERSION "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
+#ifdef _UNICODE
+ VALUE "Translation", 0x409, 1200
+#else
VALUE "Translation", 0x409, 1252
+#endif
END
END
-
-#endif // !_MAC
-
-
-#ifdef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// TEXTINCLUDE
-//
-
-1 TEXTINCLUDE DISCARDABLE
-BEGIN
- "resource.h\0"
-END
-
-2 TEXTINCLUDE DISCARDABLE
-BEGIN
- "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
- "#include ""windows.h""\r\n"
- "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
- "#include ""zipver.h""\r\n"
- "\0"
-END
-
-3 TEXTINCLUDE DISCARDABLE
-BEGIN
- "\r\n"
- "\0"
-END
-
-#endif // APSTUDIO_INVOKED
-
-#endif // English (U.S.) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-
-/////////////////////////////////////////////////////////////////////////////
-#endif // not APSTUDIO_INVOKED
-
diff --git a/windll/windll.txt b/windll/windll.txt
index 2166412..8df4bae 100644
--- a/windll/windll.txt
+++ b/windll/windll.txt
@@ -2,10 +2,7 @@ The code set out below is not intended to be compiled, but is only intended as
a very simplistic pointer to how to load and call the dll. You will have to
look in the files referenced below for actual, working code.
-There are two entry points that use the structure shown below:
-
-BOOL WINAPI ZpSetOptions(ZPOPT) and
-ZPOPT WINAPI ZpGetOptions(void)
+There is one entry point that uses the structure shown below:
typedef struct {
LPSTR Date; /* Date to include after */
@@ -38,31 +35,35 @@ 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;
-BOOL WINAPI ZpSetOptions(ZPOPT);
-
-This call will simply set the options in the zip dll until such time as
-another call to this function is made. This must be made before the initial
-call to make or update an archive.
-
-ZPOPT WINAPI ZpGetOptions(void);
-
-The call will return the above structure from the dll, with the fEncryption
-flag set to the appropriate value based on whether encryption is supported
-in this dll or not. It is currently used in WiZ only to determine if
-encryption is actually supported.
-
-The main entry point is ZpArchive(ZCL) where the structure shown below
+The main entry point is ZpArchive(ZCL, *Opts) where the structure shown below
is passed to the DLL when it is called.
typedef struct {
int argc; = Count of files to zip
LPSTR lpszZipFN; = Archive file name
char **FNV; = file names to zip up. Think of this an argv
+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;
@@ -80,7 +81,7 @@ example.c and example.h. Note that this example does not implement any
command line switches at all, and is merely intended as a guide for those
brave enough to enter a new world.
-There are four additional (at the moment) entry points:
+There are three additional (at the moment) entry points:
ZpInit, defined as
@@ -100,33 +101,47 @@ typedef struct _ZpVer {
char *betalevel; /* e.g., "g BETA" or "" */
char *date; /* e.g., "4 Sep 95" (beta) or "4 September 1995" */
char *zlib_version; /* 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;
See api.c for exactly what ZpVersion does, but the short version of
-what it does is return the unzip and dll versions in the ZpVer structure.
-The structure typedef's are in api.h
+what it does is return the zip and dll versions in the ZpVer structure.
+The structure typedef's are in api.h. It will also tell you if encryption
+is enabled.
The typedef's for the function pointers in the structure ZIPUSERFUNCTIONS
are shown immediately below.
typedef int (WINAPI DLLPRNT) (LPSTR, unsigned long);
typedef int (WINAPI DLLPASSWORD) (LPSTR, int, LPCSTR, LPCSTR);
+typedef int (WINAPI DLLSPLIT) (LPSTR);
+#ifdef ZIP64_SUPPORT
+typedef int (WINAPI DLLSERVICE) (LPCSTR, __int64);
+typedef int (WINAPI DLLSERVICE_NO_INT64) (LPCSTR, unsigned long, unsigned long);
+#else
typedef int (WINAPI DLLSERVICE) (LPCSTR, unsigned long);
-typedef int (WINAPI DLLCOMMENT) (LPSTR);
+#endif
+#endif
+typedef int (WINAPI DLLCOMMENT)(LPSTR);
+
typedef struct {
-DLLPRNT *print; = pointer to application's print function.
-DLLCOMMENT *comment; = pointer to application's function for processing
- comments.
-DLLPASSWORD *password; = pointer to application's function for processing
- passwords.
-DLLSERVICE *ServiceApplication; = Optional callback function for processing
- messages, relaying information.
+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;
-Last revised January 5, 1999.
+Last revised April 26, 2004.
Mike White
diff --git a/windll/windll32.def b/windll/windll32.def
index cd2e021..f1426ee 100644
--- a/windll/windll32.def
+++ b/windll/windll32.def
@@ -1,6 +1,7 @@
;module-definition file for Windows Zip DLL -- used by link.exe
-LIBRARY ZIP32 ; Library module name
-DESCRIPTION 'Windows Info-ZIP Zip DLL 1.01 by Info-ZIP, Mike White 1997'
+
+LIBRARY ZIP32Z64 ; Library module name
+DESCRIPTION 'Windows Info-ZIP Zip DLL 3.0 by Info-ZIP, Mike White 2004'
;CODE PRELOAD FIXED
@@ -10,6 +11,4 @@ EXPORTS
ZpArchive
ZpVersion
ZpInit
- ZpSetOptions
- ZpGetOptions
diff --git a/windll/ziplib.def b/windll/ziplib.def
index 0fcd139..a768740 100644
--- a/windll/ziplib.def
+++ b/windll/ziplib.def
@@ -1,5 +1,5 @@
-;module-definition file for Windows Zip DLL -- used by link.exe
-LIBRARY ZIP32 ; Library module name
+;module-definition file for Windows Zip static library -- used by link.exe
+LIBRARY ZIP64 ; Library module name
DESCRIPTION 'Windows Info-ZIP Zip Library 1.02 by Info-ZIP, Mike White 1997'
CODE PRELOAD FIXED
diff --git a/windll/zipver.h b/windll/zipver.h
deleted file mode 100644
index c4b41f6..0000000
--- a/windll/zipver.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- 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
-*/
-#ifndef __zipver_h /* prevent multiple inclusions */
-#define __zipver_h
-
-#define ZIP_DLL_VERSION "2.31\0"
-#define COMPANY_NAME "Info-ZIP\0"
-
-#endif /* __zipver_h */
diff --git a/zbz2err.c b/zbz2err.c
new file mode 100644
index 0000000..0e4f9f1
--- /dev/null
+++ b/zbz2err.c
@@ -0,0 +1,61 @@
+/*
+ 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
+*/
+/*---------------------------------------------------------------------------
+
+ zbz2err.c
+
+ This file contains the "fatal error" callback routine required by the
+ "minimal" (silent, non-stdio) setup of the bzip2 compression library.
+
+ The fatal bzip2 error bail-out routine is provided in a separate code
+ module, so that it can be easily overridden when the Zip package is
+ used as a static link library. One example is the WinDLL static library
+ usage for building a monolithic binary of the Windows application "WiZ"
+ that supports bzip2 both in compression and decompression operations.
+
+ Contains: bz_internal_error() (BZIP2_SUPPORT only)
+
+ Adapted from UnZip ubz2err.c, with all the DLL fine print stripped
+ out.
+
+ ---------------------------------------------------------------------------*/
+
+
+#define __ZBZ2ERR_C /* identifies this source module */
+
+#include "zip.h"
+
+#ifdef BZIP2_SUPPORT
+# ifdef BZIP2_USEBZIP2DIR
+# include "bzip2/bzlib.h"
+# else
+ /* If IZ_BZIP2 is defined as the location of the bzip2 files then
+ assume the location has been added to include path. For Unix
+ this is done by the configure script. */
+ /* Also do not need path for bzip2 include if OS includes support
+ for bzip2 library. */
+# include "bzlib.h"
+# endif
+
+/**********************************/
+/* Function bz_internal_error() */
+/**********************************/
+
+/* Call-back function for the bzip2 decompression code (compiled with
+ * BZ_NO_STDIO), required to handle fatal internal bug-type errors of
+ * the bzip2 library.
+ */
+void bz_internal_error(errcode)
+ int errcode;
+{
+ sprintf(errbuf, "fatal error (code %d) in bzip2 library", errcode);
+ ziperr(ZE_LOGIC, errbuf);
+} /* end function bz_internal_error() */
+
+#endif /* def BZIP2_SUPPORT */
diff --git a/zip.c b/zip.c
index 159fb23..439821f 100644
--- a/zip.c
+++ b/zip.c
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ zip.c - Zip 3
- See the accompanying file LICENSE, version 2005-Feb-10 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*
@@ -13,17 +15,25 @@
#include "zip.h"
#include <time.h> /* for tzset() declaration */
-#ifdef WINDLL
+#if defined(WIN32) || defined(WINDLL)
+# define WIN32_LEAN_AND_MEAN
# include <windows.h>
+#endif
+#ifdef WINDLL
# include <setjmp.h>
# include "windll/windll.h"
#endif
#define DEFCPYRT /* main module: enable copyright string defines! */
#include "revision.h"
+#include "crc32.h"
#include "crypt.h"
#include "ttyio.h"
+#include <ctype.h>
+#include <errno.h>
#ifdef VMS
+# include <stsdef.h>
# include "vms/vmsmunch.h"
+# include "vms/vms.h"
#endif
#ifdef MACOS
@@ -40,6 +50,22 @@
#endif
#include <signal.h>
+#include <stdio.h>
+
+#ifdef UNICODE_TEST
+# ifdef WIN32
+# include <direct.h>
+# endif
+#endif
+
+#ifdef BZIP2_SUPPORT
+ /* If IZ_BZIP2 is defined as the location of the bzip2 files then
+ assume the location has been added to include path. For Unix
+ this is done by the configure script. */
+ /* Also do not need path for bzip2 include if OS includes support
+ for bzip2 library. */
+# include "bzlib.h"
+#endif
#define MAXCOM 256 /* Maximum one-line comment size */
@@ -51,13 +77,13 @@
#define ADD 1
#define UPDATE 2
#define FRESHEN 3
-local int action = ADD; /* one of ADD, UPDATE, FRESHEN, or DELETE */
+#define ARCHIVE 4
+local int action = ADD; /* one of ADD, UPDATE, FRESHEN, DELETE, or ARCHIVE */
local int comadd = 0; /* 1=add comments for new files */
local int zipedit = 0; /* 1=edit zip comment and all file comments */
local int latest = 0; /* 1=set zip file time to time of latest file */
-local ulg before = 0; /* 0=ignore, else exclude files before this time */
-local ulg after = 0; /* 0=ignore, else exclude files newer than this time */
local int test = 0; /* 1=test zip file with unzip -t */
+local char *unzip_path = NULL; /* where to find unzip */
local int tempdir = 0; /* 1=use temp directory (-b) */
local int junk_sfx = 0; /* 1=junk the sfx prefix */
#if defined(AMIGA) || defined(MACOS)
@@ -77,15 +103,10 @@ char _version[] = VERSION;
#ifdef WINDLL
jmp_buf zipdll_error_return;
+#ifdef ZIP64_SUPPORT
+ unsigned long low, high; /* returning 64 bit values for systems without an _int64 */
+ uzoff_t filesize64;
#endif
-
-/* Temporary zip file name and file pointer */
-#ifndef MACOS
-local char *tempzip;
-local FILE *tempzf;
-#else
-char *tempzip;
-FILE *tempzf;
#endif
#if CRYPT
@@ -106,14 +127,52 @@ local void handler OF((int));
local void license OF((void));
#ifndef VMSCLI
local void help OF((void));
+local void help_extended OF((void));
#endif /* !VMSCLI */
#endif /* !MACOS && !WINDLL */
-local int get_filters OF((int argc, char **argv));
-#if (!defined(MACOS) && !defined(WINDLL))
-local void check_zipfile OF((char *zipname, char *zippath));
+
+/* prereading of arguments is not supported in new command
+ line interpreter get_option() so read filters as arguments
+ are processed and convert to expected array later */
+local int add_filter OF((int flag, char *pattern));
+local int filterlist_to_patterns OF((void));
+/* not used
+ local int get_filters OF((int argc, char **argv));
+*/
+
+/* list to store file arguments */
+local long add_name OF((char *filearg));
+
+
+local int DisplayRunningStats OF((void));
+local int BlankRunningStats OF((void));
+
+#if !defined(WINDLL)
local void version_info OF((void));
+# if !defined(MACOS)
local void zipstdout OF((void));
-#endif /* !MACOS && !WINDLL */
+# endif /* !MACOS */
+local int check_unzip_version OF((char *unzippath));
+local void check_zipfile OF((char *zipname, char *zippath));
+#endif /* !WINDLL */
+
+/* structure used by add_filter to store filters */
+struct filterlist_struct {
+ char flag;
+ char *pattern;
+ struct filterlist_struct *next;
+};
+struct filterlist_struct *filterlist = NULL; /* start of list */
+struct filterlist_struct *lastfilter = NULL; /* last filter in list */
+
+/* structure used by add_filearg to store file arguments */
+struct filelist_struct {
+ char *name;
+ struct filelist_struct *next;
+};
+long filearg_count = 0;
+struct filelist_struct *filelist = NULL; /* start of list */
+struct filelist_struct *lastfile = NULL; /* last file in list */
local void freeup()
/* Free all allocations in the 'found' list, the 'zfiles' list and
@@ -139,6 +198,24 @@ local void freeup()
free((zvoid *)(zfiles->extra));
if (zfiles->com && zfiles->comment)
free((zvoid *)(zfiles->comment));
+ if (zfiles->oname)
+ free((zvoid *)(zfiles->oname));
+#ifdef UNICODE_SUPPORT
+ if (zfiles->uname)
+ free((zvoid *)(zfiles->uname));
+ if (zfiles->zuname)
+ free((zvoid *)(zfiles->zuname));
+ if (zfiles->ouname)
+ free((zvoid *)(zfiles->ouname));
+# ifdef WIN32
+ if (zfiles->namew)
+ free((zvoid *)(zfiles->namew));
+ if (zfiles->inamew)
+ free((zvoid *)(zfiles->inamew));
+ if (zfiles->znamew)
+ free((zvoid *)(zfiles->znamew));
+# endif
+#endif
farfree((zvoid far *)zfiles);
zfiles = z;
zcount--;
@@ -152,6 +229,11 @@ local void freeup()
free((zvoid *)patterns);
patterns = NULL;
}
+
+ /* close logfile */
+ if (logfile) {
+ fclose(logfile);
+ }
}
local int finish(e)
@@ -209,6 +291,21 @@ int e; /* exit code */
free((zvoid *)zipfile);
zipfile = NULL;
}
+ if (in_file != NULL)
+ {
+ fclose(in_file);
+ in_file = NULL;
+ }
+ if (in_path != NULL)
+ {
+ free((zvoid *)in_path);
+ in_path = NULL;
+ }
+ if (out_path != NULL)
+ {
+ free((zvoid *)out_path);
+ out_path = NULL;
+ }
if (zcomment != NULL)
{
free((zvoid *)zcomment);
@@ -241,45 +338,75 @@ ZCONST char *h; /* message about how it happened */
#endif
if (error_level++ > 0)
- EXIT(0); /* avoid recursive ziperr() */
+ /* avoid recursive ziperr() printouts (his should never happen) */
+ EXIT(ZE_LOGIC); /* ziperr recursion is an internal logic error! */
#endif /* !WINDLL */
+ if (mesg_line_started) {
+ fprintf(mesg, "\n");
+ mesg_line_started = 0;
+ }
+ if (logfile && logfile_line_started) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ }
if (h != NULL) {
if (PERR(c))
- perror("zip I/O error");
+ fprintf(mesg, "zip I/O error: %s", strerror(errno));
+ /* perror("zip I/O error"); */
fflush(mesg);
- fprintf(stderr, "\nzip error: %s (%s)\n", ziperrors[c-1], h);
+ fprintf(mesg, "\nzip error: %s (%s)\n", ZIPERRORS(c), h);
+#ifdef DOS
+ check_for_windows("Zip");
+#endif
+ if (logfile) {
+ if (PERR(c))
+ fprintf(logfile, "zip I/O error: %s\n", strerror(errno));
+ fprintf(logfile, "\nzip error: %s (%s)\n", ZIPERRORS(c), h);
+ logfile_line_started = 0;
+ }
}
if (tempzip != NULL)
{
if (tempzip != zipfile) {
- if (tempzf != NULL)
- fclose(tempzf);
+ if (current_local_file)
+ fclose(current_local_file);
+ if (y != current_local_file && y != NULL)
+ fclose(y);
#ifndef DEBUG
destroy(tempzip);
#endif
free((zvoid *)tempzip);
} else {
/* -g option, attempt to restore the old file */
- int k = 0; /* keep count for end header */
- ulg cb = cenbeg; /* get start of central */
+
+ /* zip64 support 09/05/2003 R.Nausedat */
+ uzoff_t k = 0; /* keep count for end header */
+ uzoff_t cb = cenbeg; /* get start of central */
+
struct zlist far *z; /* steps through zfiles linked list */
- fprintf(stderr, "attempting to restore %s to its previous state\n",
+ fprintf(mesg, "attempting to restore %s to its previous state\n",
zipfile);
- fseek(tempzf, cenbeg, SEEK_SET);
+ if (logfile)
+ fprintf(logfile, "attempting to restore %s to its previous state\n",
+ zipfile);
+
+ zfseeko(y, cenbeg, SEEK_SET);
+
tempzn = cenbeg;
for (z = zfiles; z != NULL; z = z->nxt)
{
- putcentral(z, tempzf);
+ putcentral(z);
tempzn += 4 + CENHEAD + z->nam + z->cext + z->com;
k++;
}
- putend(k, tempzn - cb, cb, zcomlen, zcomment, tempzf);
- fclose(tempzf);
- tempzf = NULL;
+ putend(k, tempzn - cb, cb, zcomlen, zcomment);
+ fclose(y);
+ y = NULL;
}
}
+
if (key != NULL) {
free((zvoid *)key);
key = NULL;
@@ -292,10 +419,15 @@ ZCONST char *h; /* message about how it happened */
free((zvoid *)zipfile);
zipfile = NULL;
}
+ if (out_path != NULL) {
+ free((zvoid *)out_path);
+ out_path = NULL;
+ }
if (zcomment != NULL) {
free((zvoid *)zcomment);
zcomment = NULL;
}
+
freeup();
#ifndef WINDLL
EXIT(c);
@@ -323,7 +455,7 @@ int s; /* signal number (ignored) */
#else
#if !defined(MSDOS) && !defined(__human68k__) && !defined(RISCOS)
echon();
- putc('\n', stderr);
+ putc('\n', mesg);
#endif /* !MSDOS */
#endif /* AMIGA && __SASC */
ziperr(ZE_ABORT, "aborting");
@@ -331,11 +463,84 @@ int s; /* signal number (ignored) */
}
#endif /* !MACOS && !WINDLL */
+void zipmessage_nl(a, nl)
+ZCONST char *a; /* message string to output */
+int nl; /* 1 = add nl to end */
+/* If nl false, print a message to mesg without new line.
+ If nl true, print and add new line. If logfile is
+ open then also write message to log file. */
+{
+ if (noisy) {
+ if (a && strlen(a)) {
+ fprintf(mesg, "%s", a);
+ mesg_line_started = 1;
+ }
+ if (nl) {
+ if (mesg_line_started) {
+ fprintf(mesg, "\n");
+ mesg_line_started = 0;
+ }
+ } else if (a && strlen(a)) {
+ mesg_line_started = 1;
+ }
+ fflush(mesg);
+ }
+ if (logfile) {
+ if (a && strlen(a)) {
+ fprintf(logfile, "%s", a);
+ logfile_line_started = 1;
+ }
+ if (nl) {
+ if (logfile_line_started) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ }
+ } else if (a && strlen(a)) {
+ logfile_line_started = 1;
+ }
+ fflush(logfile);
+ }
+}
+
+void zipmessage(a, b)
+ZCONST char *a, *b; /* message strings juxtaposed in output */
+/* Print a message to mesg and flush. Also write to log file if
+ open. Write new line first if current line has output already. */
+{
+ if (noisy) {
+ if (mesg_line_started)
+ fprintf(mesg, "\n");
+ fprintf(mesg, "%s%s\n", a, b);
+ mesg_line_started = 0;
+ fflush(mesg);
+ }
+ if (logfile) {
+ if (logfile_line_started)
+ fprintf(logfile, "\n");
+ fprintf(logfile, "%s%s\n", a, b);
+ logfile_line_started = 0;
+ fflush(logfile);
+ }
+}
+
void zipwarn(a, b)
ZCONST char *a, *b; /* message strings juxtaposed in output */
-/* Print a warning message to stderr and return. */
+/* Print a warning message to mesg (usually stderr) and return. */
{
- if (noisy) fprintf(stderr, "\tzip warning: %s%s\n", a, b);
+ if (noisy) {
+ if (mesg_line_started)
+ fprintf(mesg, "\n");
+ fprintf(mesg, "\tzip warning: %s%s\n", a, b);
+ mesg_line_started = 0;
+ fflush(mesg);
+ }
+ if (logfile) {
+ if (logfile_line_started)
+ fprintf(logfile, "\n");
+ fprintf(logfile, "\tzip warning: %s%s\n", a, b);
+ logfile_line_started = 0;
+ fflush(logfile);
+ }
}
#ifndef WINDLL
@@ -344,12 +549,6 @@ local void license()
{
extent i; /* counter for copyright array */
-#if 0
- for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) {
- printf(copyright[i], "zip");
- putchar('\n');
- }
-#endif
for (i = 0; i < sizeof(swlicense)/sizeof(char *); i++)
puts(swlicense[i]);
}
@@ -366,7 +565,7 @@ local void help()
/* help array */
static ZCONST char *text[] = {
#ifdef VMS
-"Zip %s (%s). Usage: zip==\"$disk:[dir]zip.exe\"",
+"Zip %s (%s). Usage: zip == \"$ disk:[dir]zip.exe\"",
#else
"Zip %s (%s). Usage:",
#endif
@@ -375,7 +574,7 @@ local void help()
" The default action is to add or replace zipfile entries from list.",
" ",
" -f freshen: only changed files -u update: only changed or new files",
-" -d delete entries in zipfile -m move into zipfile (delete files)",
+" -d delete entries in zipfile -m move into zipfile (delete OS files)",
" -r recurse into directories -j junk (don't record) directory names",
" -0 store only -l convert LF to CR LF (-ll CR LF to LF)",
" -1 compress faster -9 compress better",
@@ -389,7 +588,7 @@ local void help()
# else
" -h show this help -n don't compress these suffixes"
# endif
-," ",
+," -h2 show more help",
" Macintosh specific:",
" -jj record Fullpath (+ Volname) -N store finder-comments as comments",
" -df zip only datafork of a file -S include finder invisible/system files"
@@ -403,7 +602,7 @@ local void help()
" can include the special name - to compress standard input.",
" If zipfile and list are omitted, zip compresses stdin to stdout.",
" -f freshen: only changed files -u update: only changed or new files",
-" -d delete entries in zipfile -m move into zipfile (delete files)",
+" -d delete entries in zipfile -m move into zipfile (delete OS files)",
" -r recurse into directories -j junk (don't record) directory names",
#ifdef THEOS
" -0 store only -l convert CR to CR LF (-ll CR LF to CR)",
@@ -425,16 +624,17 @@ local void help()
#ifdef TANDEM
" -Bn set Enscribe formatting options",
#endif
-#ifdef VMS
-" \"-F\" fix zipfile(\"-FF\" try harder) \"-D\" do not add directory entries",
-" \"-A\" adjust self-extracting exe \"-J\" junk zipfile prefix (unzipsfx)",
-" \"-T\" test zipfile integrity \"-X\" eXclude eXtra file attributes",
-" \"-V\" save VMS file attributes -w append version number to stored name",
-#else /* !VMS */
" -F fix zipfile (-FF try harder) -D do not add directory entries",
" -A adjust self-extracting exe -J junk zipfile prefix (unzipsfx)",
" -T test zipfile integrity -X eXclude eXtra file attributes",
-#endif /* ?VMS */
+#ifdef VMS
+" -C preserve case of file names -C- down-case all file names",
+" -C2 preserve case of ODS2 names -C2- down-case ODS2 file names* (*=default)",
+" -C5 preserve case of ODS5 names* -C5- down-case ODS5 file names",
+" -V save VMS file attributes (-VV also save allocated blocks past EOF)",
+" -w store file version numbers\
+ -ww store file version numbers as \".nnn\"",
+#endif /* def VMS */
#ifdef NTSD_EAS
" -! use privileges (if granted) to obtain all aspects of WinNT security",
#endif /* NTSD_EAS */
@@ -444,7 +644,9 @@ local void help()
#ifdef S_IFLNK
" -y store symbolic links as the link instead of the referenced file",
#endif /* !S_IFLNK */
+/*
" -R PKZIP recursion (see manual)",
+*/
#if defined(MSDOS) || defined(OS2)
" -$ include volume label -S include system and hidden files",
#endif
@@ -463,9 +665,15 @@ local void help()
# endif
#endif /* ?AMIGA */
#ifdef RISCOS
-," -I don't scan through Image files"
+," -h2 show more help -I don't scan thru Image files"
+#else
+," -h2 show more help"
#endif
#endif /* ?MACOS */
+#ifdef VMS
+," (Must quote upper-case options, like \"-V\", unless SET PROC/PARSE=EXTEND)"
+#endif /* def VMS */
+," "
};
for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
@@ -480,6 +688,354 @@ local void help()
}
}
+#ifdef VMSCLI
+void help_extended()
+#else
+local void help_extended()
+#endif
+/* Print extended help to stdout. */
+{
+ extent i; /* counter for help array */
+
+ /* help array */
+ static ZCONST char *text[] = {
+"",
+"Extended Help for Zip",
+"",
+"See the Zip Manual for more detailed help",
+"",
+"",
+"Zip stores files in zip archives. The default action is to add or replace",
+"zipfile entries.",
+"",
+"Basic command line:",
+" zip options archive_name file file ...",
+"",
+"Some examples:",
+" Add file.txt to z.zip (create z if needed): zip z file.txt",
+" Zip all files in current dir: zip z *",
+" Zip files in current dir and subdirs also: zip -r z .",
+"",
+"Basic modes:",
+" External modes (selects files from file system):",
+" add - add new files/update existing files in archive (default)",
+" -u update - add new files/update existing files only if later date",
+" -f freshen - update existing files only (no files added)",
+" -FS filesync - update if date or size changed, delete if no OS match",
+" Internal modes (selects entries in archive):",
+" -d delete - delete files from archive (see below)",
+" -U copy - select files in archive to copy (use with --out)",
+"",
+"Basic options:",
+" -r recurse into directories (see Recursion below)",
+" -m after archive created, delete original files (move into archive)",
+" -j junk directory names (store just file names)",
+" -q quiet operation",
+" -v verbose operation (just \"zip -v\" shows version information)",
+" -c prompt for one-line comment for each entry",
+" -z prompt for comment for archive (end with just \".\" line or EOF)",
+" -@ read names to zip from stdin (one path per line)",
+" -o make zipfile as old as latest entry",
+"",
+"",
+"Syntax:",
+" The full command line syntax is:",
+"",
+" zip [-shortopts ...] [--longopt ...] [zipfile [path path ...]] [-xi list]",
+"",
+" Any number of short option and long option arguments are allowed",
+" (within limits) as well as any number of path arguments for files",
+" to zip up. If zipfile exists, the archive is read in. If zipfile",
+" is \"-\", stream to stdout. If any path is \"-\", zip stdin.",
+"",
+"Options and Values:",
+" For short options that take values, use -ovalue or -o value or -o=value",
+" For long option values, use either --longoption=value or --longoption value",
+" For example:",
+" zip -ds 10 --temp-dir=path zipfile path1 path2 --exclude pattern pattern",
+" Avoid -ovalue (no space between) to avoid confusion",
+" In particular, be aware of 2-character options. For example:",
+" -d -s is (delete, split size) while -ds is (dot size)",
+" Usually better to break short options across multiple arguments by function",
+" zip -r -dbdcds 10m -lilalf logfile archive input_directory -ll",
+"",
+" All args after just \"--\" arg are read verbatim as paths and not options.",
+" zip zipfile path path ... -- verbatimpath verbatimpath ...",
+" Use -nw to also disable wildcards, so paths are read literally:",
+" zip zipfile -nw -- \"-leadingdashpath\" \"a[path].c\" \"path*withwildcard\"",
+" You may still have to escape or quote arguments to avoid shell expansion",
+"",
+"Wildcards:",
+" Internally zip supports the following wildcards:",
+" ? (or %% or #, depending on OS) matches any single character",
+" * matches any number of characters, including zero",
+" [list] matches char in list (regex), can do range [ac-f], all but [!bf]",
+" If port supports [], must escape [ as [[] or use -nw to turn off wildcards",
+" For shells that expand wildcards, escape (\\* or \"*\") so zip can recurse",
+" zip zipfile -r . -i \"*.h\"",
+"",
+" Normally * crosses dir bounds in path, e.g. 'a*b' can match 'ac/db'. If",
+" -ws option used, * does not cross dir bounds but ** does",
+"",
+" For DOS and Windows, [list] is now disabled unless the new option",
+" -RE enable [list] (regular expression) matching",
+" is used to avoid problems with file paths containing \"[\" and \"]\":",
+" zip files_ending_with_number -RE foo[0-9].c",
+"",
+"Include and Exclude:",
+" -i pattern pattern ... include files that match a pattern",
+" -x pattern pattern ... exclude files that match a pattern",
+" Patterns are paths with optional wildcards and match paths as stored in",
+" archive. Exclude and include lists end at next option, @, or end of line.",
+" zip -x pattern pattern @ zipfile path path ...",
+"",
+"Case matching:",
+" On most OS the case of patterns must match the case in the archive, unless",
+" the -ic option is used.",
+" -ic ignore case of archive entries",
+" This option not available on case-sensitive file systems. On others, case",
+" ignored when matching files on file system but matching against archive",
+" entries remains case sensitive for modes -f (freshen), -U (archive copy),",
+" and -d (delete) because archive paths are always case sensitive. With",
+" -ic, all matching ignores case, but it's then possible multiple archive",
+" entries that differ only in case will match.",
+"",
+"End Of Line Translation (text files only):",
+" -l change CR or LF (depending on OS) line end to CR LF (Unix->Win)",
+" -ll change CR LF to CR or LF (depending on OS) line end (Win->Unix)",
+" If first buffer read from file contains binary the translation is skipped",
+"",
+"Recursion:",
+" -r recurse paths, include files in subdirs: zip -r a path path ...",
+" -R recurse current dir and match patterns: zip -R a ptn ptn ...",
+" Use -i and -x with either to include or exclude paths",
+" Path root in archive starts at current dir, so if /a/b/c/file and",
+" current dir is /a/b, 'zip -r archive .' puts c/file in archive",
+"",
+"Date filtering:",
+" -t date exclude before (include files modified on this date and later)",
+" -tt date include before (include files modified before date)",
+" Can use both at same time to set a date range",
+" Dates are mmddyyyy or yyyy-mm-dd",
+"",
+"Deletion, File Sync:",
+" -d delete files",
+" Delete archive entries matching internal archive paths in list",
+" zip archive -d pattern pattern ...",
+" Can use -t and -tt to select files in archive, but NOT -x or -i, so",
+" zip archive -d \"*\" -t 2005-12-27",
+" deletes all files from archive.zip with date of 27 Dec 2005 and later",
+" Note the * (escape as \"*\" on Unix) to select all files in archive",
+"",
+" -FS file sync",
+" Similar to update, but files updated if date or size of entry does not",
+" match file on OS. Also deletes entry from archive if no matching file",
+" on OS.",
+" zip archive_to_update -FS -r dir_used_before",
+" Result generally same as creating new archive, but unchanged entries",
+" are copied instead of being read and compressed so can be faster.",
+" WARNING: -FS deletes entries so make backup copy of archive first",
+"",
+"Compression:",
+" -0 store files (no compression)",
+" -1 to -9 compress fastest to compress best (default is 6)",
+" -Z cm set compression method to cm:",
+" store - store without compression, same as option -0",
+" deflate - original zip deflate, same as -1 to -9 (default)",
+" if bzip2 is enabled:",
+" bzip2 - use bzip2 compression (need modern unzip)",
+"",
+"Encryption:",
+" -e use standard (weak) PKZip 2.0 encryption, prompt for password",
+" -P pswd use standard encryption, password is pswd",
+"",
+"Splits (archives created as a set of split files):",
+" -s ssize create split archive with splits of size ssize, where ssize nm",
+" n number and m multiplier (kmgt, default m), 100k -> 100 kB",
+" -sp pause after each split closed to allow changing disks",
+" WARNING: Archives created with -sp use data descriptors and should",
+" work with most unzips but may not work with some",
+" -sb ring bell when pause",
+" -sv be verbose about creating splits",
+" Split archives CANNOT be updated, but see --out and Copy Mode below",
+"",
+"Using --out (output to new archive):",
+" --out oa output to new archive oa",
+" Instead of updating input archive, create new output archive oa.",
+" Result is same as without --out but in new archive. Input archive",
+" unchanged.",
+" WARNING: --out ALWAYS overwrites any existing output file",
+" For example, to create new_archive like old_archive but add newfile1",
+" and newfile2:",
+" zip old_archive newfile1 newfile2 --out new_archive",
+" Cannot update split archive, so use --out to out new archive:",
+" zip in_split_archive newfile1 newfile2 --out out_split_archive",
+" If input is split, output will default to same split size",
+" Use -s=0 or -s- to turn off splitting to convert split to single file:",
+" zip in_split_archive -s 0 --out out_single_file_archive",
+" WARNING: If overwriting old split archive but need less splits,",
+" old splits not overwritten are not needed but remain",
+"",
+"Copy Mode (copying from archive to archive):",
+" -U (also --copy) select entries in archive to copy (reverse delete)",
+" Copy Mode copies entries from old to new archive with --out and is used by",
+" zip when either no input files on command line or -U (--copy) used.",
+" zip inarchive --copy pattern pattern ... --out outarchive",
+" To copy only files matching *.c into new archive, excluding foo.c:",
+" zip old_archive --copy \"*.c\" --out new_archive -x foo.c",
+" If no input files and --out, copy all entries in old archive:",
+" zip old_archive --out new_archive",
+"",
+"Streaming and FIFOs:",
+" prog1 | zip -ll z - zip output of prog1 to zipfile z, converting CR LF",
+" zip - -R \"*.c\" | prog2 zip *.c files in current dir and stream to prog2 ",
+" prog1 | zip | prog2 zip in pipe with no in or out acts like zip - -",
+" If Zip is Zip64 enabled, streaming stdin creates Zip64 archives by default",
+" that need PKZip 4.5 unzipper like UnZip 6.0",
+" WARNING: Some archives created with streaming use data descriptors and",
+" should work with most unzips but may not work with some",
+" Can use -fz- to turn off Zip64 if input not large (< 4 GB):",
+" prog_with_small_output | zip archive -fz-",
+"",
+" Zip now can read Unix FIFO (named pipes). Off by default to prevent zip",
+" from stopping unexpectedly on unfed pipe, use -FI to enable:",
+" zip -FI archive fifo",
+"",
+"Dots, counts:",
+" -db display running count of bytes processed and bytes to go",
+" (uncompressed size, except delete and copy show stored size)",
+" -dc display running count of entries done and entries to go",
+" -dd display dots every 10 MB (or dot size) while processing files",
+" -dg display dots globally for archive instead of for each file",
+" zip -qdgds 10m will turn off most output except dots every 10 MB",
+" -ds siz each dot is siz processed where siz is nm as splits (0 no dots)",
+" -du display original uncompressed size for each entry as added",
+" -dv display volume (disk) number in format in_disk>out_disk",
+" Dot size is approximate, especially for dot sizes less than 1 MB",
+" Dot options don't apply to Scanning files dots (dot/2sec) (-q turns off)",
+"",
+"Logging:",
+" -lf path open file at path as logfile (overwrite existing file)",
+" -la append to existing logfile",
+" -li include info messages (default just warnings and errors)",
+"",
+"Testing archives:",
+" -T test completed temp archive with unzip before updating archive",
+" -TT cmd use command cmd instead of 'unzip -tqq' to test archive",
+" On Unix, to use unzip in current directory, could use:",
+" zip archive file1 file2 -T -TT \"./unzip -tqq\"",
+" In cmd, {} replaced by temp archive path, else temp appended.",
+" The return code is checked for success (0 on Unix)",
+"",
+"Fixing archives:",
+" -F attempt to fix a mostly intact archive (try this first)",
+" -FF try to salvage what can (may get more but less reliable)",
+" Fix options copy entries from potentially bad archive to new archive.",
+" -F tries to read archive normally and copy only intact entries, while",
+" -FF tries to salvage what can and may result in incomplete entries.",
+" Must use --out option to specify output archive:",
+" zip -F bad.zip --out fixed.zip",
+" Use -v (verbose) with -FF to see details:",
+" zip reallybad.zip -FF -v --out fixed.zip",
+" Currently neither option fixes bad entries, as from text mode ftp get.",
+"",
+"Difference mode:",
+" -DF (also --dif) only include files that have changed or are",
+" new as compared to the input archive",
+" Difference mode can be used to create incremental backups. For example:",
+" zip --dif full_backup.zip -r somedir --out diff.zip",
+" will store all new files, as well as any files in full_backup.zip where",
+" either file time or size have changed from that in full_backup.zip,",
+" in new diff.zip. Output archive not excluded automatically if exists,",
+" so either use -x to exclude it or put outside what is being zipped.",
+"",
+"DOS Archive bit (Windows only):",
+" -AS include only files with the DOS Archive bit set",
+" -AC after archive created, clear archive bit of included files",
+" WARNING: Once the archive bits are cleared they are cleared",
+" Use -T to test the archive before the bits are cleared",
+" Can also use -sf to save file list before zipping files",
+"",
+"Show files:",
+" -sf show files to operate on and exit (-sf- logfile only)",
+" -su as -sf but show escaped UTF-8 Unicode names also if exist",
+" -sU as -sf but show escaped UTF-8 Unicode names instead",
+" Any character not in the current locale is escaped as #Uxxxx, where x",
+" is hex digit, if 16-bit code is sufficient, or #Lxxxxxx if 24-bits",
+" are needed. If add -UN=e, Zip escapes all non-ASCII characters.",
+"",
+"Unicode:",
+" If compiled with Unicode support, Zip stores UTF-8 path of entries.",
+" This is backward compatible. Unicode paths allow better conversion",
+" of entry names between different character sets.",
+"",
+" New Unicode extra field includes checksum to verify Unicode path",
+" goes with standard path for that entry (as utilities like ZipNote",
+" can rename entries). If these do not match, use below options to",
+" set what Zip does:",
+" -UN=Quit - if mismatch, exit with error",
+" -UN=Warn - if mismatch, warn, ignore UTF-8 (default)",
+" -UN=Ignore - if mismatch, quietly ignore UTF-8",
+" -UN=No - ignore any UTF-8 paths, use standard paths for all",
+" An exception to -UN=N are entries with new UTF-8 bit set (instead",
+" of using extra fields). These are always handled as Unicode.",
+"",
+" Normally Zip escapes all chars outside current char set, but leaves",
+" as is supported chars, which may not be OK in path names. -UN=Escape",
+" escapes any character not ASCII:",
+" zip -sU -UN=e archive",
+" Can use either normal path or escaped Unicode path on command line",
+" to match files in archive.",
+"",
+" Zip now stores UTF-8 in entry path and comment fields on systems",
+" where UTF-8 char set is default, such as most modern Unix, and",
+" and on other systems in new extra fields with escaped versions in",
+" entry path and comment fields for backward compatibility.",
+" Option -UN=UTF8 will force storing UTF-8 in entry path and comment",
+" fields:",
+" -UN=UTF8 - store UTF-8 in entry path and comment fields",
+" This option can be useful for multi-byte char sets on Windows where",
+" escaped paths and comments can be too long to be valid as the UTF-8",
+" versions tend to be shorter.",
+"",
+" Only UTF-8 comments on UTF-8 native systems supported. UTF-8 comments",
+" for other systems planned in next release.",
+"",
+"Self extractor:",
+" -A Adjust offsets - a self extractor is created by prepending",
+" the extractor executable to archive, but internal offsets",
+" are then off. Use -A to fix offsets.",
+" -J Junk sfx - removes prepended extractor executable from",
+" self extractor, leaving a plain zip archive.",
+"",
+"More option highlights (see manual for additional options and details):",
+" -b dir when creating or updating archive, create the temp archive in",
+" dir, which allows using seekable temp file when writing to a",
+" write once CD, such archives compatible with more unzips",
+" (could require additional file copy if on another device)",
+" -MM input patterns must match at least one file and matched files",
+" must be readable or exit with OPEN error and abort archive",
+" (without -MM, both are warnings only, and if unreadable files",
+" are skipped OPEN error (18) returned after archive created)",
+" -nw no wildcards (wildcards are like any other character)",
+" -sc show command line arguments as processed and exit",
+" -sd show debugging as Zip does each step",
+" -so show all available options on this system",
+" -X default=strip old extra fields, -X- keep old, -X strip most",
+" -ws wildcards don't span directory boundaries in paths",
+""
+ };
+
+ for (i = 0; i < sizeof(text)/sizeof(char *); i++)
+ {
+ printf(text[i]);
+ putchar('\n');
+ }
+#ifdef DOS
+ check_for_windows("Zip");
+#endif
+}
+
/*
* XXX version_info() in a separate file
*/
@@ -490,6 +1046,14 @@ local void version_info()
extent i; /* counter in text arrays */
char *envptr;
+ /* Bzip2 option string storage (with version). */
+
+#ifdef BZIP2_SUPPORT
+ static char bz_opt_ver[81];
+ static char bz_opt_ver2[81];
+ static char bz_opt_ver3[81];
+#endif
+
/* Options info array */
static ZCONST char *comp_opts[] = {
#ifdef ASM_CRC
@@ -517,10 +1081,10 @@ local void version_info()
"DEBUG",
#endif
#ifdef USE_EF_UT_TIME
- "USE_EF_UT_TIME",
+ "USE_EF_UT_TIME (store Universal Time)",
#endif
#ifdef NTSD_EAS
- "NTSD_EAS",
+ "NTSD_EAS (store NT Security Descriptor)",
#endif
#if defined(WIN32) && defined(NO_W32TIMES_IZFIX)
"NO_W32TIMES_IZFIX",
@@ -537,8 +1101,46 @@ local void version_info()
#endif
#endif /* VMS */
#ifdef WILD_STOP_AT_DIR
- "WILD_STOP_AT_DIR",
+ "WILD_STOP_AT_DIR (wildcards do not cross directory boundaries)",
+#endif
+#ifdef WIN32_OEM
+ "WIN32_OEM (store file paths on Windows as OEM)",
+#endif
+#ifdef BZIP2_SUPPORT
+ bz_opt_ver,
+ bz_opt_ver2,
+ bz_opt_ver3,
+#endif
+#ifdef S_IFLNK
+# ifdef VMS
+ "SYMLINK_SUPPORT (symbolic links supported, if C RTL permits)",
+# else
+ "SYMLINK_SUPPORT (symbolic links supported)",
+# endif
#endif
+#ifdef LARGE_FILE_SUPPORT
+# ifdef USING_DEFAULT_LARGE_FILE_SUPPORT
+ "LARGE_FILE_SUPPORT (default settings)",
+# else
+ "LARGE_FILE_SUPPORT (can read and write large files on file system)",
+# endif
+#endif
+#ifdef ZIP64_SUPPORT
+ "ZIP64_SUPPORT (use Zip64 to store large files in archives)",
+#endif
+#ifdef UNICODE_SUPPORT
+ "UNICODE_SUPPORT (store and read UTF-8 Unicode paths)",
+#endif
+
+#ifdef UNIX
+ "STORE_UNIX_UIDs_GIDs (store UID/GID sizes/values using new extra field)",
+# ifdef UIDGID_NOT_16BIT
+ "UIDGID_NOT_16BIT (old Unix 16-bit UID/GID extra field not used)",
+# else
+ "UIDGID_16BIT (old Unix 16-bit UID/GID extra field also used)",
+# endif
+#endif
+
#if CRYPT && defined(PASSWD_FROM_STDIN)
"PASSWD_FROM_STDIN",
#endif /* CRYPT & PASSWD_FROM_STDIN */
@@ -595,6 +1197,17 @@ local void version_info()
#if WSIZE != 0x8000
printf("\tWSIZE=%u\n", WSIZE);
#endif
+
+ /* Fill in bzip2 version. (32-char limit valid as of bzip 1.0.3.) */
+#ifdef BZIP2_SUPPORT
+ sprintf( bz_opt_ver,
+ "BZIP2_SUPPORT (bzip2 library version %.32s)", BZ2_bzlibVersion());
+ sprintf( bz_opt_ver2,
+ " bzip2 code and library copyright (c) Julian R Seward");
+ sprintf( bz_opt_ver3,
+ " (See the bzip2 license for terms of use)");
+#endif
+
for (i = 0; (int)i < (int)(sizeof(comp_opts)/sizeof(char *) - 1); i++)
{
printf("\t%s\n",comp_opts[i]);
@@ -608,7 +1221,7 @@ local void version_info()
i++; /* zlib use means there IS at least one compilation option */
#endif
#if CRYPT
- printf("\t[encryption, version %d.%d%s of %s]\n",
+ printf("\t[encryption, version %d.%d%s of %s] (modified for Zip 3)\n\n",
CR_MAJORVER, CR_MINORVER, CR_BETA_VER, CR_VERSION_DATE);
for (i = 0; i < sizeof(cryptnote)/sizeof(char *); i++)
{
@@ -616,7 +1229,7 @@ local void version_info()
putchar('\n');
}
++i; /* crypt support means there IS at least one compilation option */
-#endif
+#endif /* CRYPT */
if (i == 0)
puts("\t[none]");
@@ -627,12 +1240,25 @@ local void version_info()
printf("%16s: %s\n", zipenv_names[i],
((envptr == (char *)NULL || *envptr == 0) ? "[none]" : envptr));
}
+#ifdef DOS
+ check_for_windows("Zip");
+#endif
}
#endif /* !WINDLL */
#ifndef PROCNAME
-# define PROCNAME(n) procname(n, (action == DELETE || action == FRESHEN))
+/* Default to case-sensitive matching of archive entries for the modes
+ that specifically operate on archive entries, as this archive may
+ have come from a system that allows paths in the archive to differ
+ only by case. Except for adding ARCHIVE (copy mode), this is how it
+ was done before. Note that some case-insensitive ports (WIN32, VMS)
+ define their own PROCNAME() in their respective osdep.h that use the
+ filter_match_case flag set to FALSE by the -ic option to enable
+ case-insensitive archive entry mathing. */
+# define PROCNAME(n) procname(n, (action == ARCHIVE || action == DELETE \
+ || action == FRESHEN) \
+ && filter_match_case)
#endif /* PROCNAME */
#ifndef WINDLL
@@ -640,185 +1266,519 @@ local void version_info()
local void zipstdout()
/* setup for writing zip file on stdout */
{
- int r;
mesg = stderr;
if (isatty(1))
ziperr(ZE_PARMS, "cannot write zip file to terminal");
if ((zipfile = malloc(4)) == NULL)
ziperr(ZE_MEM, "was processing arguments");
strcpy(zipfile, "-");
+ /*
if ((r = readzipfile()) != ZE_OK)
ziperr(r, zipfile);
+ */
}
#endif /* !MACOS */
+local int check_unzip_version(unzippath)
+ char *unzippath;
+{
+#ifdef ZIP64_SUPPORT
+ /* Here is where we need to check for the version of unzip the user
+ * has. If creating a Zip64 archive need UnZip 6 or may fail.
+ */
+ char cmd[4004];
+ FILE *unzip_out = NULL;
+ char buf[1001];
+ float UnZip_Version = 0.0;
+
+ cmd[0] = '\0';
+ strncat(cmd, unzippath, 4000);
+ strcat(cmd, " -v");
+
+ if ((unzip_out = popen(cmd, "r")) == NULL) {
+ perror("unzip pipe error");
+ } else {
+ if (fgets(buf, 1000, unzip_out) == NULL) {
+ zipwarn("failed to get information from UnZip", "");
+ } else {
+ /* the first line should start with the version */
+ if (sscanf(buf, "UnZip %f ", &UnZip_Version) < 1) {
+ zipwarn("unexpected output of UnZip -v", "");
+ } else {
+ /* printf("UnZip %f\n", UnZip_Version); */
+
+ while (fgets(buf, 1000, unzip_out)) {
+ }
+ }
+ }
+ pclose(unzip_out);
+ }
+ if (UnZip_Version < 6.0 && zip64_archive) {
+ sprintf(buf, "Found UnZip version %4.2f", UnZip_Version);
+ zipwarn(buf, "");
+ zipwarn("Need UnZip 6.00 or later to test this Zip64 archive", "");
+ return 0;
+ }
+#endif
+ return 1;
+}
+
local void check_zipfile(zipname, zippath)
char *zipname;
char *zippath;
/* Invoke unzip -t on the given zip file */
{
#if (defined(MSDOS) && !defined(__GO32__)) || defined(__human68k__)
- int status, len;
- char *path, *p;
+ int status, len;
+ char *path, *p;
+ char *zipnam;
- status = spawnlp(P_WAIT, "unzip", "unzip", verbose ? "-t" : "-tqq",
- zipname, NULL);
-#ifdef __human68k__
- if (status == -1)
- perror("unzip");
-#else
+ if ((zipnam = (char *)malloc(strlen(zipname) + 3)) == NULL)
+ ziperr(ZE_MEM, "was creating unzip zipnam");
+
+# ifdef MSDOS
+ /* Add quotes for MSDOS. 8/11/04 */
+ strcpy(zipnam, "\""); /* accept spaces in name and path */
+ strcat(zipnam, zipname);
+ strcat(zipnam, "\"");
+# else
+ strcpy(zipnam, zipname);
+# endif
+
+ if (unzip_path) {
+ /* if user gave us the unzip to use go with it */
+ char *here;
+ int len;
+ char *cmd;
+
+ /* Replace first {} with archive name. If no {} append name to string. */
+ here = strstr(unzip_path, "{}");
+
+ if ((cmd = (char *)malloc(strlen(unzip_path) + strlen(zipnam) + 3)) == NULL)
+ ziperr(ZE_MEM, "was creating unzip cmd");
+
+ if (here) {
+ /* have {} so replace with temp name */
+ len = here - unzip_path;
+ strcpy(cmd, unzip_path);
+ cmd[len] = '\0';
+ strcat(cmd, " ");
+ strcat(cmd, zipnam);
+ strcat(cmd, " ");
+ strcat(cmd, here + 2);
+ } else {
+ /* No {} so append temp name to end */
+ strcpy(cmd, unzip_path);
+ strcat(cmd, " ");
+ strcat(cmd, zipnam);
+ }
+
+ status = system(cmd);
+
+ free(unzip_path);
+ unzip_path = NULL;
+ free(cmd);
+ } else {
+ /* Here is where we need to check for the version of unzip the user
+ * has. If creating a Zip64 archive need UnZip 6 or may fail.
+ */
+ if (check_unzip_version("unzip") == 0)
+ ZIPERR(ZE_TEST, zipfile);
+
+ status = spawnlp(P_WAIT, "unzip", "unzip", verbose ? "-t" : "-tqq",
+ zipnam, NULL);
+# ifdef __human68k__
+ if (status == -1)
+ perror("unzip");
+# else
/*
* unzip isn't in PATH range, assume an absolute path to zip in argv[0]
* and hope that unzip is in the same directory.
*/
- if (status == -1) {
- p = MBSRCHR(zippath, '\\');
- path = MBSRCHR((p == NULL ? zippath : p), '/');
- if (path != NULL)
- p = path;
- if (p != NULL) {
- len = (int)(p - zippath) + 1;
- if ((path = malloc(len + sizeof("unzip.exe"))) == NULL)
- ziperr(ZE_MEM, "was creating unzip path");
- memcpy(path, zippath, len);
- strcpy(&path[len], "unzip.exe");
- status = spawnlp(P_WAIT, path, "unzip", verbose ? "-t" : "-tqq",
- zipname, NULL);
- free(path);
- }
- if (status == -1)
- perror("unzip");
- }
-#endif /* ?__human68k__ */
- if (status != 0) {
+ if (status == -1) {
+ p = MBSRCHR(zippath, '\\');
+ path = MBSRCHR((p == NULL ? zippath : p), '/');
+ if (path != NULL)
+ p = path;
+ if (p != NULL) {
+ len = (int)(p - zippath) + 1;
+ if ((path = malloc(len + sizeof("unzip.exe"))) == NULL)
+ ziperr(ZE_MEM, "was creating unzip path");
+ memcpy(path, zippath, len);
+ strcpy(&path[len], "unzip.exe");
+
+ if (check_unzip_version(path) == 0)
+ ZIPERR(ZE_TEST, zipfile);
+
+ status = spawnlp(P_WAIT, path, "unzip", verbose ? "-t" : "-tqq",
+ zipnam, NULL);
+ free(path);
+ }
+ if (status == -1)
+ perror("unzip");
+ }
+ }
+# endif /* ?__human68k__ */
+ free(zipnam);
+ if (status != 0) {
+
#else /* (MSDOS && !__GO32__) || __human68k__ */
- char cmd[FNMAX+16];
+ char *cmd;
+ int result;
- /* Tell picky compilers to shut up about unused variables */
- zippath = zippath;
+ /* Tell picky compilers to shut up about unused variables */
+ zippath = zippath;
- strcpy(cmd, "unzip -t ");
-#ifdef QDOS
- strcat(cmd, "-Q4 ");
-#endif
- if (!verbose) strcat(cmd, "-qq ");
- if ((int)strlen(zipname) > FNMAX) {
- error("zip filename too long");
- }
+ if (unzip_path) {
+ /* user gave us a path to some unzip (may not be UnZip) */
+ char *here;
+ int len;
+
+ /* Replace first {} with archive name. If no {} append name to string. */
+ here = strstr(unzip_path, "{}");
+
+ if ((cmd = malloc(strlen(unzip_path) + strlen(zipname) + 3)) == NULL) {
+ ziperr(ZE_MEM, "building command string for testing archive");
+ }
+
+ if (here) {
+ /* have {} so replace with temp name */
+ len = here - unzip_path;
+ strcpy(cmd, unzip_path);
+ cmd[len] = '\0';
+ strcat(cmd, " ");
# ifdef UNIX
- strcat(cmd, "'"); /* accept space or $ in name */
- strcat(cmd, zipname);
- strcat(cmd, "'");
+ strcat(cmd, "'"); /* accept space or $ in name */
+ strcat(cmd, zipname);
+ strcat(cmd, "'");
# else
- strcat(cmd, zipname);
+ strcat(cmd, zipname);
# endif
-# ifdef VMS
- if (!system(cmd)) {
+ strcat(cmd, " ");
+ strcat(cmd, here + 2);
+ } else {
+ /* No {} so append temp name to end */
+ strcpy(cmd, unzip_path);
+ strcat(cmd, " ");
+# ifdef UNIX
+ strcat(cmd, "'"); /* accept space or $ in name */
+ strcat(cmd, zipname);
+ strcat(cmd, "'");
+# else
+ strcat(cmd, zipname);
+# endif
+ }
+ free(unzip_path);
+ unzip_path = NULL;
+
+ } else {
+ if ((cmd = malloc(20 + strlen(zipname))) == NULL) {
+ ziperr(ZE_MEM, "building command string for testing archive");
+ }
+
+ strcpy(cmd, "unzip -t ");
+# ifdef QDOS
+ strcat(cmd, "-Q4 ");
+# endif
+ if (!verbose) strcat(cmd, "-qq ");
+ if (check_unzip_version("unzip") == 0)
+ ZIPERR(ZE_TEST, zipfile);
+
+# ifdef UNIX
+ strcat(cmd, "'"); /* accept space or $ in name */
+ strcat(cmd, zipname);
+ strcat(cmd, "'");
# else
- if (system(cmd)) {
+ strcat(cmd, zipname);
# endif
+ }
+
+ result = system(cmd);
+# ifdef VMS
+ /* Convert success severity to 0, others to non-zero. */
+ result = ((result & STS$M_SEVERITY) != STS$M_SUCCESS);
+# endif /* def VMS */
+ free(cmd);
+ cmd = NULL;
+ if (result) {
#endif /* ?((MSDOS && !__GO32__) || __human68k__) */
- fprintf(mesg, "test of %s FAILED\n", zipfile);
- ziperr(ZE_TEST, "original files unmodified");
- }
- if (noisy)
- fprintf(mesg, "test of %s OK\n", zipfile);
+
+ fprintf(mesg, "test of %s FAILED\n", zipfile);
+ ziperr(ZE_TEST, "original files unmodified");
+ }
+ if (noisy) {
+ fprintf(mesg, "test of %s OK\n", zipfile);
+ fflush(mesg);
+ }
+ if (logfile) {
+ fprintf(logfile, "test of %s OK\n", zipfile);
+ fflush(logfile);
+ }
}
#endif /* !WINDLL */
+/* get_filters() is replaced by the following
local int get_filters(argc, argv)
- int argc; /* number of tokens in command line */
- char **argv; /* command line tokens */
-/* Counts number of -i or -x patterns, sets patterns and pcount */
+*/
+
+/* The filter patterns for options -x, -i, and -R are
+ returned by get_option() one at a time, so use a linked
+ list to store until all args are processed. Then convert
+ to array for processing.
+ */
+
+/* add a filter to the linked list */
+local int add_filter(flag, pattern)
+ int flag;
+ char *pattern;
{
- int i;
- int flag = 0, archive_seen = 0;
char *iname, *p = NULL;
FILE *fp;
+ struct filterlist_struct *filter = NULL;
- pcount = 0;
- for (i = 1; i < argc; i++) {
- if (argv[i][0] == '-') {
- p = argv[i];
- while (*(++p) != '\0') {
- if (*p == 'i' || *p == 'x')
- break;
+ /* should never happen */
+ if (flag != 'R' && flag != 'x' && flag != 'i') {
+ ZIPERR(ZE_LOGIC, "bad flag to add_filter");
+ }
+ if (pattern == NULL) {
+ ZIPERR(ZE_LOGIC, "null pattern to add_filter");
+ }
+
+ if (pattern[0] == '@') {
+ /* read file with 1 pattern per line */
+ if (pattern[1] == '\0') {
+ ZIPERR(ZE_PARMS, "missing file after @");
+ }
+ fp = fopen(pattern + 1, "r");
+ if (fp == NULL) {
+ sprintf(errbuf, "%c pattern file '%s'", flag, pattern);
+ ZIPERR(ZE_OPEN, errbuf);
+ }
+ while ((p = getnam(fp)) != NULL) {
+ if ((filter = (struct filterlist_struct *) malloc(sizeof(struct filterlist_struct))) == NULL) {
+ ZIPERR(ZE_MEM, "adding filter");
}
- if (*p != '\0') {
- flag = *p;
- p = p[1] == '@' ? p + 2 : NULL;
- if (p != NULL && patterns == NULL) {
- fp = fopen(p, "r");
- if (fp == NULL) {
- ZIPERR(ZE_OPEN, p);
- }
- while (fgets(errbuf, FNMAX, fp) != NULL)
- pcount++;
- fclose(fp);
- }
- } else if (MBSRCHR(argv[i], 'R') != NULL) {
- p = NULL;
- flag = 'R';
- } else if (flag != 'R') {
- flag = 0;
+ if (filterlist == NULL) {
+ /* first filter */
+ filterlist = filter; /* start of list */
+ lastfilter = filter;
+ } else {
+ lastfilter->next = filter; /* link to last filter in list */
+ lastfilter = filter;
}
- }
- if (flag && (archive_seen || p != NULL)) {
- if (patterns != NULL) {
- /* second pass: create pattern entry */
- if (p != NULL) {
- fp = fopen(p, "r");
- if (fp == NULL) {
- ZIPERR(ZE_OPEN, p);
- }
- while ((p = getnam(errbuf, fp)) != NULL) {
- iname = ex2in(p, 0, (int *)NULL);
- if (iname != NULL) {
- patterns[pcount].zname = in2ex(iname);
- free(iname);
- } else {
- patterns[pcount].zname = NULL;
- }
- patterns[pcount].select = flag;
- if (flag != 'x')
- icount++;
- pcount++;
- }
- fclose(fp);
- flag = 0;
- p = NULL;
- }
- else if (argv[i][0] != '-') {
- iname = ex2in(argv[i], 0, (int *)NULL);
- patterns[pcount].zname = (iname != NULL ? in2ex(iname) : NULL);
- if (iname != NULL)
- free(iname);
- patterns[pcount].select = flag;
- if (flag != 'x')
- icount++;
- pcount++;
- }
+ iname = ex2in(p, 0, (int *)NULL);
+ free(p);
+ if (iname != NULL) {
+ lastfilter->pattern = in2ex(iname);
+ free(iname);
+ } else {
+ lastfilter->pattern = NULL;
}
- else if (p == NULL)
- pcount++;
- else
- flag = 0;
+ lastfilter->flag = flag;
+ pcount++;
+ lastfilter->next = NULL;
+ }
+ fclose(fp);
+ } else {
+ /* single pattern */
+ if ((filter = (struct filterlist_struct *) malloc(sizeof(struct filterlist_struct))) == NULL) {
+ ZIPERR(ZE_MEM, "adding filter");
+ }
+ if (filterlist == NULL) {
+ /* first pattern */
+ filterlist = filter; /* start of list */
+ lastfilter = filter;
} else {
- if (flag != 'R')
- flag = 0; /* only 'R' is allowed before zipfile arg */
- if (argv[i][0] != '-') {
- archive_seen = 1; /* first non-flag arg is archive name */
- }
+ lastfilter->next = filter; /* link to last filter in list */
+ lastfilter = filter;
}
+ iname = ex2in(pattern, 0, (int *)NULL);
+ if (iname != NULL) {
+ lastfilter->pattern = in2ex(iname);
+ free(iname);
+ } else {
+ lastfilter->pattern = NULL;
+ }
+ lastfilter->flag = flag;
+ pcount++;
+ lastfilter->next = NULL;
+ }
+
+ return pcount;
+}
+
+/* convert list to patterns array */
+local int filterlist_to_patterns()
+{
+ unsigned i;
+ struct filterlist_struct *next = NULL;
+
+ if (pcount == 0) {
+ patterns = NULL;
+ return 0;
}
- if (pcount == 0 || patterns != NULL) return ZE_OK;
- /* first pass and pattern count > 0: allocate space for pattern list */
- patterns = (struct plist*) malloc(pcount * sizeof(struct plist));
- if (patterns == NULL) {
+ if ((patterns = (struct plist *) malloc((pcount + 1) * sizeof(struct plist)))
+ == NULL) {
ZIPERR(ZE_MEM, "was creating pattern list");
}
- /* recall this function for second pass, filling the pattern list */
- return get_filters(argc, argv);
+
+ for (i = 0; i < pcount && filterlist != NULL; i++) {
+ switch (filterlist->flag) {
+ case 'i':
+ icount++;
+ break;
+ case 'R':
+ Rcount++;
+ break;
+ }
+ patterns[i].select = filterlist->flag;
+ patterns[i].zname = filterlist->pattern;
+ next = filterlist->next;
+ free(filterlist);
+ filterlist = next;
+ }
+
+ return pcount;
+}
+
+
+/* add a file argument to linked list */
+local long add_name(filearg)
+ char *filearg;
+{
+ char *name = NULL;
+ struct filelist_struct *fileentry = NULL;
+
+ if ((fileentry = (struct filelist_struct *) malloc(sizeof(struct filelist_struct))) == NULL) {
+ ZIPERR(ZE_MEM, "adding file");
+ }
+ if ((name = malloc(strlen(filearg) + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "adding file");
+ }
+ strcpy(name, filearg);
+ fileentry->next = NULL;
+ fileentry->name = name;
+ if (filelist == NULL) {
+ /* first file argument */
+ filelist = fileentry; /* start of list */
+ lastfile = fileentry;
+ } else {
+ lastfile->next = fileentry; /* link to last filter in list */
+ lastfile = fileentry;
+ }
+ filearg_count++;
+
+ return filearg_count;
+}
+
+
+/* Running Stats
+ 10/30/04 */
+
+local int DisplayRunningStats()
+{
+ char tempstrg[100];
+
+ if (mesg_line_started) {
+ fprintf(mesg, "\n");
+ mesg_line_started = 0;
+ }
+ if (logfile_line_started) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ }
+ if (display_volume) {
+ if (noisy) {
+ fprintf(mesg, "%lu>%lu: ", current_in_disk + 1, current_disk + 1);
+ mesg_line_started = 1;
+ }
+ if (logall) {
+ fprintf(logfile, "%lu>%lu: ", current_in_disk + 1, current_disk + 1);
+ logfile_line_started = 1;
+ }
+ }
+ if (display_counts) {
+ if (noisy) {
+ fprintf(mesg, "%3ld/%3ld ", files_so_far, files_total - files_so_far);
+ mesg_line_started = 1;
+ }
+ if (logall) {
+ fprintf(logfile, "%3ld/%3ld ", files_so_far, files_total - files_so_far);
+ logfile_line_started = 1;
+ }
+ }
+ if (display_bytes) {
+ /* since file sizes can change as we go, use bytes_so_far from
+ initial scan so all adds up */
+ WriteNumString(bytes_so_far, tempstrg);
+ if (noisy) {
+ fprintf(mesg, "[%4s", tempstrg);
+ mesg_line_started = 1;
+ }
+ if (logall) {
+ fprintf(logfile, "[%4s", tempstrg);
+ logfile_line_started = 1;
+ }
+ if (bytes_total >= bytes_so_far) {
+ WriteNumString(bytes_total - bytes_so_far, tempstrg);
+ if (noisy)
+ fprintf(mesg, "/%4s] ", tempstrg);
+ if (logall)
+ fprintf(logfile, "/%4s] ", tempstrg);
+ } else {
+ WriteNumString(bytes_so_far - bytes_total, tempstrg);
+ if (noisy)
+ fprintf(mesg, "-%4s] ", tempstrg);
+ if (logall)
+ fprintf(logfile, "-%4s] ", tempstrg);
+ }
+ }
+ if (noisy)
+ fflush(mesg);
+ if (logall)
+ fflush(logfile);
+
+ return 0;
+}
+
+local int BlankRunningStats()
+{
+ if (display_volume) {
+ if (noisy) {
+ fprintf(mesg, "%lu>%lu: ", current_in_disk + 1, current_disk + 1);
+ mesg_line_started = 1;
+ }
+ if (logall) {
+ fprintf(logfile, "%lu>%lu: ", current_in_disk + 1, current_disk + 1);
+ logfile_line_started = 1;
+ }
+ }
+ if (display_counts) {
+ if (noisy) {
+ fprintf(mesg, " / ");
+ mesg_line_started = 1;
+ }
+ if (logall) {
+ fprintf(logfile, " / ");
+ logfile_line_started = 1;
+ }
+ }
+ if (display_bytes) {
+ if (noisy) {
+ fprintf(mesg, " / ");
+ mesg_line_started = 1;
+ }
+ if (logall) {
+ fprintf(logfile, " / ");
+ logfile_line_started = 1;
+ }
+ }
+ if (noisy)
+ fflush(mesg);
+ if (logall)
+ fflush(logfile);
+
+ return 0;
}
#if CRYPT
@@ -857,6 +1817,304 @@ ZCONST char *zfn;
}
#endif /* CRYPT */
+
+/* rename a split
+ * A split has a tempfile name until it is closed, then
+ * here rename it as out_path the final name for the split.
+ */
+int rename_split(temp_name, out_path)
+ char *temp_name;
+ char *out_path;
+{
+ int r;
+ /* Replace old zip file with new zip file, leaving only the new one */
+ if ((r = replace(out_path, temp_name)) != ZE_OK)
+ {
+ zipwarn("new zip file left as: ", temp_name);
+ free((zvoid *)tempzip);
+ tempzip = NULL;
+ ZIPERR(r, "was replacing split file");
+ }
+ if (zip_attributes) {
+ setfileattr(out_path, zip_attributes);
+ }
+ return ZE_OK;
+}
+
+
+int set_filetype(out_path)
+ char *out_path;
+{
+#ifdef __BEOS__
+ /* Set the filetype of the zipfile to "application/zip" */
+ setfiletype( out_path, "application/zip" );
+#endif
+
+#ifdef __ATHEOS__
+ /* Set the filetype of the zipfile to "application/x-zip" */
+ setfiletype(out_path, "application/x-zip");
+#endif
+
+#ifdef MACOS
+ /* Set the Creator/Type of the zipfile to 'IZip' and 'ZIP ' */
+ setfiletype(out_path, 'IZip', 'ZIP ');
+#endif
+
+#ifdef RISCOS
+ /* Set the filetype of the zipfile to &DDC */
+ setfiletype(out_path, 0xDDC);
+#endif
+ return ZE_OK;
+}
+
+
+/*
+ -------------------------------------------------------
+ Command Line Options
+ -------------------------------------------------------
+
+ Valid command line options.
+
+ The function get_option() uses this table to check if an
+ option is valid and if it takes a value (also called an
+ option argument). To add an option to zip just add it
+ to this table and add a case in the main switch to handle
+ it. If either shortopt or longopt not used set to "".
+
+ The fields:
+ shortopt - short option name (1 or 2 chars)
+ longopt - long option name
+ value_type - see zip.h for constants
+ negatable - option is negatable with trailing -
+ ID - unsigned long int returned for option
+ name - short description of option which is
+ returned on some errors and when options
+ are listed with -so option, can be NULL
+*/
+
+/* Most option IDs are set to the shortopt char. For
+ multichar short options set to arbitrary unused constant. */
+#define o_AC 0x101
+#define o_AS 0x102
+#define o_C2 0x103
+#define o_C5 0x104
+#define o_db 0x105
+#define o_dc 0x106
+#define o_dd 0x107
+#define o_des 0x108
+#define o_df 0x109
+#define o_DF 0x110
+#define o_dg 0x111
+#define o_ds 0x112
+#define o_du 0x113
+#define o_dv 0x114
+#define o_FF 0x115
+#define o_FI 0x116
+#define o_FS 0x117
+#define o_h2 0x118
+#define o_ic 0x119
+#define o_jj 0x120
+#define o_la 0x121
+#define o_lf 0x122
+#define o_li 0x123
+#define o_ll 0x124
+#define o_mm 0x125
+#define o_MM 0x126
+#define o_nw 0x127
+#define o_RE 0x128
+#define o_sb 0x129
+#define o_sc 0x130
+#define o_sd 0x131
+#define o_sf 0x132
+#define o_so 0x133
+#define o_sp 0x134
+#define o_su 0x135
+#define o_sU 0x136
+#define o_sv 0x137
+#define o_tt 0x138
+#define o_TT 0x139
+#define o_UN 0x140
+#define o_ve 0x141
+#define o_VV 0x142
+#define o_ws 0x143
+#define o_ww 0x144
+#define o_z64 0x145
+#ifdef UNICODE_TEST
+#define o_sC 0x146
+#endif
+
+
+/* the below is mainly from the old main command line
+ switch with a few changes */
+struct option_struct far options[] = {
+ /* short longopt value_type negatable ID name */
+#ifdef EBCDIC
+ {"a", "ascii", o_NO_VALUE, o_NOT_NEGATABLE, 'a', "to ascii"},
+#endif /* EBCDIC */
+#ifdef CMS_MVS
+ {"B", "binary", o_NO_VALUE, o_NOT_NEGATABLE, 'B', "binary"},
+#endif /* CMS_MVS */
+#ifdef TANDEM
+ {"B", "", o_NUMBER_VALUE, o_NOT_NEGATABLE, 'B', "nsk"},
+#endif
+ {"0", "store", o_NO_VALUE, o_NOT_NEGATABLE, '0', "store"},
+ {"1", "compress-1", o_NO_VALUE, o_NOT_NEGATABLE, '1', "compress 1"},
+ {"2", "compress-2", o_NO_VALUE, o_NOT_NEGATABLE, '2', "compress 2"},
+ {"3", "compress-3", o_NO_VALUE, o_NOT_NEGATABLE, '3', "compress 3"},
+ {"4", "compress-4", o_NO_VALUE, o_NOT_NEGATABLE, '4', "compress 4"},
+ {"5", "compress-5", o_NO_VALUE, o_NOT_NEGATABLE, '5', "compress 5"},
+ {"6", "compress-6", o_NO_VALUE, o_NOT_NEGATABLE, '6', "compress 6"},
+ {"7", "compress-7", o_NO_VALUE, o_NOT_NEGATABLE, '7', "compress 7"},
+ {"8", "compress-8", o_NO_VALUE, o_NOT_NEGATABLE, '8', "compress 8"},
+ {"9", "compress-9", o_NO_VALUE, o_NOT_NEGATABLE, '9', "compress 9"},
+ {"A", "adjust-sfx", o_NO_VALUE, o_NOT_NEGATABLE, 'A', "adjust self extractor offsets"},
+#if defined(WIN32)
+ {"AC", "archive-clear", o_NO_VALUE, o_NOT_NEGATABLE, o_AC, "clear DOS archive bit of included files"},
+ {"AS", "archive-set", o_NO_VALUE, o_NOT_NEGATABLE, o_AS, "include only files with archive bit set"},
+#endif
+ {"b", "temp-path", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'b', "dir to use for temp archive"},
+ {"c", "entry-comments", o_NO_VALUE, o_NOT_NEGATABLE, 'c', "add comments for each entry"},
+#ifdef VMS
+ {"C", "preserve-case", o_NO_VALUE, o_NEGATABLE, 'C', "Preserve (C-: down-) case all on VMS"},
+ {"C2", "preserve-case-2", o_NO_VALUE, o_NEGATABLE, o_C2, "Preserve (C2-: down-) case ODS2 on VMS"},
+ {"C5", "preserve-case-5", o_NO_VALUE, o_NEGATABLE, o_C5, "Preserve (C5-: down-) case ODS5 on VMS"},
+#endif /* VMS */
+ {"d", "delete", o_NO_VALUE, o_NOT_NEGATABLE, 'd', "delete entries from archive"},
+ {"db", "display-bytes", o_NO_VALUE, o_NEGATABLE, o_db, "display running bytes"},
+ {"dc", "display-counts", o_NO_VALUE, o_NEGATABLE, o_dc, "display running file count"},
+ {"dd", "display-dots", o_NO_VALUE, o_NEGATABLE, o_dd, "display dots as process each file"},
+ {"dg", "display-globaldots",o_NO_VALUE, o_NEGATABLE, o_dg, "display dots for archive instead of files"},
+ {"ds", "dot-size", o_REQUIRED_VALUE, o_NOT_NEGATABLE, o_ds, "set progress dot size - default 10M bytes"},
+ {"du", "display-usize", o_NO_VALUE, o_NEGATABLE, o_du, "display uncompressed size in bytes"},
+ {"dv", "display-volume", o_NO_VALUE, o_NEGATABLE, o_dv, "display volume (disk) number"},
+#ifdef MACOS
+ {"df", "datafork", o_NO_VALUE, o_NOT_NEGATABLE, o_df, "save datafork"},
+#endif /* MACOS */
+ {"D", "no-dir-entries", o_NO_VALUE, o_NOT_NEGATABLE, 'D', "no entries for dirs themselves (-x */)"},
+ {"DF", "difference-archive",o_NO_VALUE, o_NOT_NEGATABLE, o_DF, "create diff archive with changed/new files"},
+ {"e", "encrypt", o_NO_VALUE, o_NOT_NEGATABLE, 'e', "encrypt entries, ask for password"},
+#ifdef OS2
+ {"E", "longnames", o_NO_VALUE, o_NOT_NEGATABLE, 'E', "use OS2 longnames"},
+#endif
+ {"F", "fix", o_NO_VALUE, o_NOT_NEGATABLE, 'F', "fix mostly intact archive (try first)"},
+ {"FF", "fixfix", o_NO_VALUE, o_NOT_NEGATABLE, o_FF, "try harder to fix archive (not as reliable)"},
+ {"FI", "fifo", o_NO_VALUE, o_NEGATABLE, o_FI, "read Unix FIFO (zip will wait on open pipe)"},
+ {"FS", "filesync", o_NO_VALUE, o_NOT_NEGATABLE, o_FS, "add/delete entries to make archive match OS"},
+ {"f", "freshen", o_NO_VALUE, o_NOT_NEGATABLE, 'f', "freshen existing archive entries"},
+ {"fd", "force-descriptors", o_NO_VALUE, o_NOT_NEGATABLE, o_des,"force data descriptors as if streaming"},
+#ifdef ZIP64_SUPPORT
+ {"fz", "force-zip64", o_NO_VALUE, o_NEGATABLE, o_z64,"force use of Zip64 format, negate prevents"},
+#endif
+ {"g", "grow", o_NO_VALUE, o_NOT_NEGATABLE, 'g', "grow existing archive instead of replace"},
+#ifndef WINDLL
+ {"h", "help", o_NO_VALUE, o_NOT_NEGATABLE, 'h', "help"},
+ {"H", "", o_NO_VALUE, o_NOT_NEGATABLE, 'h', "help"},
+ {"?", "", o_NO_VALUE, o_NOT_NEGATABLE, 'h', "help"},
+ {"h2", "more-help", o_NO_VALUE, o_NOT_NEGATABLE, o_h2, "extended help"},
+#endif /* !WINDLL */
+ {"i", "include", o_VALUE_LIST, o_NOT_NEGATABLE, 'i', "include only files matching patterns"},
+#if defined(VMS) || defined(WIN32)
+ {"ic", "ignore-case", o_NO_VALUE, o_NEGATABLE, o_ic, "ignore case when matching archive entries"},
+#endif
+#ifdef RISCOS
+ {"I", "no-image", o_NO_VALUE, o_NOT_NEGATABLE, 'I', "no image"},
+#endif
+ {"j", "junk-paths", o_NO_VALUE, o_NOT_NEGATABLE, 'j', "strip paths and just store file names"},
+#ifdef MACOS
+ {"jj", "absolute-path", o_NO_VALUE, o_NOT_NEGATABLE, o_jj, "MAC absolute path"},
+#endif /* ?MACOS */
+ {"J", "junk-sfx", o_NO_VALUE, o_NOT_NEGATABLE, 'J', "strip self extractor from archive"},
+ {"k", "DOS-names", o_NO_VALUE, o_NOT_NEGATABLE, 'k', "force use of 8.3 DOS names"},
+ {"l", "to-crlf", o_NO_VALUE, o_NOT_NEGATABLE, 'l', "convert text file line ends - LF->CRLF"},
+ {"ll", "from-crlf", o_NO_VALUE, o_NOT_NEGATABLE, o_ll, "convert text file line ends - CRLF->LF"},
+ {"lf", "logfile-path",o_REQUIRED_VALUE, o_NOT_NEGATABLE, o_lf, "log to log file at path (default overwrite)"},
+ {"la", "log-append", o_NO_VALUE, o_NEGATABLE, o_la, "append to existing log file"},
+ {"li", "log-info", o_NO_VALUE, o_NEGATABLE, o_li, "include informational messages in log"},
+#ifndef WINDLL
+ {"L", "license", o_NO_VALUE, o_NOT_NEGATABLE, 'L', "display license"},
+#endif
+ {"m", "move", o_NO_VALUE, o_NOT_NEGATABLE, 'm', "add files to archive then delete files"},
+ {"mm", "", o_NO_VALUE, o_NOT_NEGATABLE, o_mm, "not used"},
+ {"MM", "must-match", o_NO_VALUE, o_NOT_NEGATABLE, o_MM, "error if in file not matched/not readable"},
+ {"n", "suffixes", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'n', "suffixes to not compress: .gz:.zip"},
+ {"nw", "no-wild", o_NO_VALUE, o_NOT_NEGATABLE, o_nw, "no wildcards during add or update"},
+#if defined(AMIGA) || defined(MACOS)
+ {"N", "notes", o_NO_VALUE, o_NOT_NEGATABLE, 'N', "add notes as entry comments"},
+#endif
+ {"o", "latest-time", o_NO_VALUE, o_NOT_NEGATABLE, 'o', "use latest entry time as archive time"},
+ {"O", "output-file", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'O', "set out zipfile different than in zipfile"},
+ {"p", "paths", o_NO_VALUE, o_NOT_NEGATABLE, 'p', "store paths"},
+ {"P", "password", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'P', "encrypt entries, option value is password"},
+#if defined(QDOS) || defined(QLZIP)
+ {"Q", "Q-flag", o_NUMBER_VALUE, o_NOT_NEGATABLE, 'Q', "Q flag"},
+#endif
+ {"q", "quiet", o_NO_VALUE, o_NOT_NEGATABLE, 'q', "quiet"},
+ {"r", "recurse-paths", o_NO_VALUE, o_NOT_NEGATABLE, 'r', "recurse down listed paths"},
+ {"R", "recurse-patterns", o_NO_VALUE, o_NOT_NEGATABLE, 'R', "recurse current dir and match patterns"},
+ {"RE", "regex", o_NO_VALUE, o_NOT_NEGATABLE, o_RE, "allow [list] matching (regex)"},
+ {"s", "split-size", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 's', "do splits, set split size (-s=0 no splits)"},
+ {"sp", "split-pause", o_NO_VALUE, o_NOT_NEGATABLE, o_sp, "pause while splitting to select destination"},
+ {"sv", "split-verbose", o_NO_VALUE, o_NOT_NEGATABLE, o_sv, "be verbose about creating splits"},
+ {"sb", "split-bell", o_NO_VALUE, o_NOT_NEGATABLE, o_sb, "when pause for next split ring bell"},
+ {"sc", "show-command",o_NO_VALUE, o_NOT_NEGATABLE, o_sc, "show command line"},
+#ifdef UNICODE_TEST
+ {"sC", "create-files",o_NO_VALUE, o_NOT_NEGATABLE, o_sC, "create empty files using archive names"},
+#endif
+ {"sd", "show-debug", o_NO_VALUE, o_NOT_NEGATABLE, o_sd, "show debug"},
+ {"sf", "show-files", o_NO_VALUE, o_NEGATABLE, o_sf, "show files to operate on and exit"},
+ {"so", "show-options",o_NO_VALUE, o_NOT_NEGATABLE, o_so, "show options"},
+#ifdef UNICODE_SUPPORT
+ {"su", "show-unicode", o_NO_VALUE, o_NEGATABLE, o_su, "as -sf but also show escaped Unicode"},
+ {"sU", "show-just-unicode", o_NO_VALUE, o_NEGATABLE, o_sU, "as -sf but only show escaped Unicode"},
+#endif
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(ATARI)
+ {"S", "", o_NO_VALUE, o_NOT_NEGATABLE, 'S', "include system and hidden"},
+#endif /* MSDOS || OS2 || WIN32 || ATARI */
+ {"t", "from-date", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 't', "exclude before date"},
+ {"tt", "before-date", o_REQUIRED_VALUE, o_NOT_NEGATABLE, o_tt, "include before date"},
+ {"T", "test", o_NO_VALUE, o_NOT_NEGATABLE, 'T', "test updates before replacing archive"},
+ {"TT", "unzip-command", o_REQUIRED_VALUE,o_NOT_NEGATABLE,o_TT, "unzip command to use, name is added to end"},
+ {"u", "update", o_NO_VALUE, o_NOT_NEGATABLE, 'u', "update existing entries and add new"},
+ {"U", "copy-entries", o_NO_VALUE, o_NOT_NEGATABLE, 'U', "select from archive instead of file system"},
+#ifdef UNICODE_SUPPORT
+ {"UN", "unicode", o_REQUIRED_VALUE, o_NOT_NEGATABLE, o_UN, "UN=quit, warn, ignore, no, escape"},
+#endif
+ {"v", "verbose", o_NO_VALUE, o_NOT_NEGATABLE, 'v', "display additional information"},
+ {"", "version", o_NO_VALUE, o_NOT_NEGATABLE, o_ve, "(if no other args) show version information"},
+#ifdef VMS
+ {"V", "VMS-portable", o_NO_VALUE, o_NOT_NEGATABLE, 'V', "Store VMS attributes, portable file format"},
+ {"VV", "VMS-specific", o_NO_VALUE, o_NOT_NEGATABLE, o_VV, "Store VMS attributes, VMS specific format"},
+ {"w", "VMS-versions", o_NO_VALUE, o_NOT_NEGATABLE, 'w', "store VMS versions"},
+ {"ww", "VMS-dot-versions", o_NO_VALUE, o_NOT_NEGATABLE, o_ww, "store VMS versions as \".nnn\""},
+#endif /* VMS */
+ {"ws", "wild-stop-dirs", o_NO_VALUE, o_NOT_NEGATABLE, o_ws, "* stops at /, ** includes any /"},
+ {"x", "exclude", o_VALUE_LIST, o_NOT_NEGATABLE, 'x', "exclude files matching patterns"},
+/* {"X", "no-extra", o_NO_VALUE, o_NOT_NEGATABLE, 'X', "no extra"},
+*/
+ {"X", "strip-extra", o_NO_VALUE, o_NEGATABLE, 'X', "-X- keep all ef, -X strip but critical ef"},
+#ifdef S_IFLNK
+ {"y", "symlinks", o_NO_VALUE, o_NOT_NEGATABLE, 'y', "store symbolic links"},
+#endif /* S_IFLNK */
+ {"z", "archive-comment", o_NO_VALUE, o_NOT_NEGATABLE, 'z', "ask for archive comment"},
+ {"Z", "compression-method", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'Z', "compression method"},
+#if defined(MSDOS) || defined(OS2)
+ {"$", "volume-label", o_NO_VALUE, o_NOT_NEGATABLE, '$', "store volume label"},
+#endif
+#ifndef MACOS
+ {"@", "names-stdin", o_NO_VALUE, o_NOT_NEGATABLE, '@', "get file names from stdin, one per line"},
+#endif /* !MACOS */
+#ifdef NTSD_EAS
+ {"!", "use-privileges", o_NO_VALUE, o_NOT_NEGATABLE, '!', "use privileges"},
+#endif
+#ifdef RISCOS
+ {"/", "exts-to-swap", o_REQUIRED_VALUE, o_NOT_NEGATABLE, '/', "override Zip$Exts"},
+#endif
+ /* the end of the list */
+ {NULL, NULL, o_NO_VALUE, o_NOT_NEGATABLE, 0, NULL} /* end has option_ID = 0 */
+ };
+
+
+
#ifndef USE_ZIPMAIN
int main(argc, argv)
#else
@@ -867,42 +2125,111 @@ char **argv; /* command line tokens */
/* Add, update, freshen, or delete zip entries in a zip file. See the
command help in help() above. */
{
- int a; /* attributes of zip file */
- ulg c; /* start of central directory */
int d; /* true if just adding to a zip file */
char *e; /* malloc'd comment buffer */
struct flist far *f; /* steps through found linked list */
int i; /* arg counter, root directory flag */
- int k; /* next argument type, marked counter,
- comment size, entry count */
- ulg n; /* total of entry len's */
+ int kk; /* next arg type (formerly another re-use of "k") */
+
+ /* zip64 support 09/05/2003 R.Nausedat */
+ uzoff_t c; /* start of central directory */
+ uzoff_t t; /* length of central directory */
+ zoff_t k; /* marked counter, comment size, entry count */
+ uzoff_t n; /* total of entry len's */
+
int o; /* true if there were any ZE_OPEN errors */
char *p; /* steps through option arguments */
char *pp; /* temporary pointer */
- ulg *cmptime = NULL; /* pointer to 'before' or 'after' */
int r; /* temporary variable */
int s; /* flag to read names from stdin */
- ulg t; /* file time, length of central directory */
+ uzoff_t csize; /* compressed file size for stats */
+ uzoff_t usize; /* uncompressed file size for stats */
+ ulg tf; /* file time */
int first_listarg = 0;/* index of first arg of "process these files" list */
struct zlist far *v; /* temporary variable */
struct zlist far * far *w; /* pointer to last link in zfiles list */
- FILE *x, *y; /* input and output zip files */
+ FILE *x /*, *y */; /* input and output zip files (y global) */
struct zlist far *z; /* steps through zfiles linked list */
+ int bad_open_is_error = 0; /* if read fails, 0=warning, 1=error */
+#if 0
+ /* does not seem used */
#ifdef WINDLL
int retcode; /* return code for dll */
+#endif /* WINDLL */
#endif
#if (!defined(VMS) && !defined(CMS_MVS))
char *zipbuf; /* stdio buffer for the zip file */
#endif /* !VMS && !CMS_MVS */
FILE *comment_stream; /* set to stderr if anything is read from stdin */
+ int all_current; /* used by File Sync to determine if all entries are current */
+
+ struct filelist_struct *filearg;
+
+/* used by get_option */
+ unsigned long option; /* option ID returned by get_option */
+ int argcnt = 0; /* current argcnt in args */
+ int argnum = 0; /* arg number */
+ int optchar = 0; /* option state */
+ char *value = NULL; /* non-option arg, option value or NULL */
+ int negated = 0; /* 1 = option negated */
+ int fna = 0; /* current first non-opt arg */
+ int optnum = 0; /* index in table */
+
+ int show_options = 0; /* show options */
+ int show_what_doing = 0; /* show what doing */
+ int show_args = 0; /* show command line */
+ int seen_doubledash = 0; /* seen -- argument */
+ int key_needed = 0; /* prompt for encryption key */
+ int have_out = 0; /* if set in_path and out_path different archive */
+#ifdef UNICODE_TEST
+ int create_files = 0;
+#endif
+
+ char **args = NULL; /* could be wide argv */
+
#ifdef THEOS
/* the argument expansion from the standard library is full of bugs */
/* use mine instead */
_setargv(&argc, &argv);
- setlocale(LC_CTYPE,"I");
+ setlocale(LC_CTYPE, "I");
#else
- SETLOCALE(LC_CTYPE,"");
+ SETLOCALE(LC_CTYPE, "");
+#endif
+
+#ifdef UNICODE_SUPPORT
+# ifdef UNIX
+ /* For Unix, set the locale to UTF-8. Any UTF-8 locale is
+ OK and they should all be the same. This allows seeing,
+ writing, and displaying (if the fonts are loaded) all
+ characters in UTF-8. */
+ {
+ char *loc;
+
+ /*
+ loc = setlocale(LC_CTYPE, NULL);
+ printf(" Initial language locale = '%s'\n", loc);
+ */
+
+ loc = setlocale(LC_CTYPE, "en_US.UTF-8");
+
+ /*
+ printf("langinfo %s\n", nl_langinfo(CODESET));
+ */
+
+ if (loc != NULL) {
+ /* using UTF-8 character set so can set UTF-8 GPBF bit 11 */
+ using_utf8 = 1;
+ /*
+ printf(" Locale set to %s\n", loc);
+ */
+ } else {
+ /*
+ printf(" Could not set Unicode UTF-8 locale\n");
+ */
+ }
+ }
+# endif
#endif
#if defined(__IBMC__) && defined(__DEBUG_ALLOC__)
@@ -919,6 +2246,13 @@ char **argv; /* command line tokens */
}
#endif
+#ifdef NLM
+ {
+ extern void NLMexit(void);
+ atexit(NLMexit);
+ }
+#endif
+
#ifdef RISCOS
set_prefix();
#endif
@@ -932,20 +2266,23 @@ char **argv; /* command line tokens */
* possible that we could get away with not re-initializing all of these
* but better safe than sorry.
*/
-#if defined(MACOS) || defined(WINDLL)
- action = ADD; /* one of ADD, UPDATE, FRESHEN, or DELETE */
+#if defined(MACOS) || defined(WINDLL) || defined(USE_ZIPMAIN)
+ action = ADD; /* one of ADD, UPDATE, FRESHEN, DELETE, or ARCHIVE */
comadd = 0; /* 1=add comments for new files */
zipedit = 0; /* 1=edit zip comment and all file comments */
latest = 0; /* 1=set zip file time to time of latest file */
before = 0; /* 0=ignore, else exclude files before this time */
after = 0; /* 0=ignore, else exclude files newer than this time */
test = 0; /* 1=test zip file with unzip -t */
+ unzip_path = NULL; /* where to look for unzip command path */
tempdir = 0; /* 1=use temp directory (-b) */
junk_sfx = 0; /* 1=junk the sfx prefix */
#if defined(AMIGA) || defined(MACOS)
filenotes = 0;/* 1=take comments from AmigaDOS/MACOS filenotes */
#endif
+#ifndef USE_ZIPMAIN
zipstate = -1;
+#endif
tempzip = NULL;
fcount = 0;
recurse = 0; /* 1=recurse into directories; 2=match filenames */
@@ -962,24 +2299,171 @@ char **argv; /* command line tokens */
use_longname_ea = 0; /* 1=use the .LONGNAME EA as the file's name */
#endif
#ifdef NTSD_EAS
- use_privileges = 0; /* 1=use security privileges overrides */
-#endif
- hidden_files = 0; /* process hidden and system files */
- volume_label = 0; /* add volume label */
- dirnames = 1; /* include directory entries by default */
- linkput = 0; /* 1=store symbolic links as such */
- noisy = 1; /* 0=quiet operation */
- extra_fields = 1; /* 0=do not create extra fields */
+ use_privileges = 0; /* 1=use security privileges overrides */
+#endif
+ no_wild = 0; /* 1 = wildcards are disabled */
+#ifdef WILD_STOP_AT_DIR
+ wild_stop_at_dir = 1; /* default wildcards do not include / in matches */
+#else
+ wild_stop_at_dir = 0; /* default wildcards do include / in matches */
+#endif
+
+ skip_this_disk = 0;
+ des_good = 0; /* Good data descriptor found */
+ des_crc = 0; /* Data descriptor CRC */
+ des_csize = 0; /* Data descriptor csize */
+ des_usize = 0; /* Data descriptor usize */
+
+ dot_size = 0; /* buffers processed in deflate per dot, 0 = no dots */
+ dot_count = 0; /* buffers seen, recyles at dot_size */
+
+ display_counts = 0; /* display running file count */
+ display_bytes = 0; /* display running bytes remaining */
+ display_globaldots = 0; /* display dots for archive instead of each file */
+ display_volume = 0; /* display current input and output volume (disk) numbers */
+ display_usize = 0; /* display uncompressed bytes */
+
+ files_so_far = 0; /* files processed so far */
+ bad_files_so_far = 0; /* bad files skipped so far */
+ files_total = 0; /* files total to process */
+ bytes_so_far = 0; /* bytes processed so far (from initial scan) */
+ good_bytes_so_far = 0; /* good bytes read so far */
+ bad_bytes_so_far = 0; /* bad bytes skipped so far */
+ bytes_total = 0; /* total bytes to process (from initial scan) */
+
+ logall = 0; /* 0 = warnings/errors, 1 = all */
+ logfile = NULL; /* pointer to open logfile or NULL */
+ logfile_append = 0; /* append to existing logfile */
+ logfile_path = NULL; /* pointer to path of logfile */
+
+ hidden_files = 0; /* process hidden and system files */
+ volume_label = 0; /* add volume label */
+ dirnames = 1; /* include directory entries by default */
+#if defined(WIN32)
+ only_archive_set = 0; /* only include if DOS archive bit set */
+ clear_archive_bits = 0; /* clear DOS archive bit of included files */
+#endif
+ linkput = 0; /* 1=store symbolic links as such */
+ noisy = 1; /* 0=quiet operation */
+ extra_fields = 1; /* 0=create minimum, 1=don't copy old, 2=keep old */
+
+ use_descriptors = 0; /* 1=use data descriptors 12/29/04 */
+ zip_to_stdout = 0; /* output zipfile to stdout 12/30/04 */
+ allow_empty_archive = 0;/* if no files, create empty archive anyway 12/28/05 */
+ copy_only = 0; /* 1=copying archive entries only */
+
+ output_seekable = 1; /* 1 = output seekable 3/13/05 EG */
+
+#ifdef ZIP64_SUPPORT /* zip64 support 10/4/03 */
+ force_zip64 = -1; /* if 1 force entries to be zip64 */
+ /* mainly for streaming from stdin */
+ zip64_entry = 0; /* current entry needs Zip64 */
+ zip64_archive = 0; /* if 1 then at least 1 entry needs zip64 */
+#endif
+
+#ifdef UNICODE_SUPPORT
+ utf8_force = 0; /* 1=force storing UTF-8 as standard per AppNote bit 11 */
+#endif
+
+ unicode_escape_all = 0; /* 1=escape all non-ASCII characters in paths */
+ unicode_mismatch = 1; /* unicode mismatch is 0=error, 1=warn, 2=ignore, 3=no */
+
+ scan_delay = 5; /* seconds before display Scanning files message */
+ scan_dot_time = 2; /* time in seconds between Scanning files dots */
+ scan_start = 0; /* start of scan */
+ scan_last = 0; /* time of last message */
+ scan_started = 0; /* scan has started */
+ scan_count = 0; /* Used for Scanning files ... message */
+
+ before = 0; /* 0=ignore, else exclude files before this time */
+ after = 0; /* 0=ignore, else exclude files newer than this time */
+
special = ".Z:.zip:.zoo:.arc:.lzh:.arj"; /* List of special suffixes */
- key = NULL; /* Scramble password if scrambling */
- tempath = NULL; /* Path for temporary files */
- found = NULL; /* where in found, or new found entry */
+ key = NULL; /* Scramble password if scrambling */
+ key_needed = 0; /* Need scramble password */
+ tempath = NULL; /* Path for temporary files */
+ patterns = NULL; /* List of patterns to be matched */
+ pcount = 0; /* number of patterns */
+ icount = 0; /* number of include only patterns */
+ Rcount = 0; /* number of -R include patterns */
+
+ found = NULL; /* List of names found, or new found entry */
fnxt = &found;
- patterns = NULL; /* List of patterns to be matched */
- pcount = 0; /* number of patterns */
- icount = 0; /* number of include only patterns */
-#ifndef MACOS
+ /* used by get_option */
+ argcnt = 0; /* size of args */
+ argnum = 0; /* current arg number */
+ optchar = 0; /* option state */
+ value = NULL; /* non-option arg, option value or NULL */
+ negated = 0; /* 1 = option negated */
+ fna = 0; /* current first nonopt arg */
+ optnum = 0; /* option index */
+
+ show_options = 0; /* 1 = show options */
+ show_what_doing = 0; /* 1 = show what zip doing */
+ show_args = 0; /* 1 = show command line */
+ seen_doubledash = 0; /* seen -- argument */
+
+ zipfile = NULL; /* path of usual in and out zipfile */
+ tempzip = NULL; /* name of temp file */
+ y = NULL; /* output file now global so can change in splits */
+ in_file = NULL; /* current input file for splits */
+ in_split_path = NULL; /* current in split path */
+ in_path = NULL; /* used by splits to track changing split locations */
+ out_path = NULL; /* if set, use -O out_path as output */
+ have_out = 0; /* if set, in_path and out_path not the same archive */
+
+ total_disks = 0; /* total disks in archive */
+ current_in_disk = 0; /* current read split disk */
+ current_in_offset = 0; /* current offset in current read disk */
+ skip_current_disk = 0; /* if != 0 and fix then skip entries on this disk */
+
+ zip64_eocd_disk = 0; /* disk with Zip64 End Of Central Directory Record */
+ zip64_eocd_offset = 0; /* offset for Zip64 EOCD Record */
+
+ current_local_disk = 0; /* disk with current local header */
+
+ current_disk = 0; /* current disk number */
+ cd_start_disk = (ulg)-1; /* central directory start disk */
+ cd_start_offset = 0; /* offset of start of cd on cd start disk */
+ cd_entries_this_disk = 0; /* cd entries this disk */
+ total_cd_entries = 0; /* total cd entries in new/updated archive */
+
+ /* for split method 1 (keep split with local header open and update) */
+ current_local_tempname = NULL; /* name of temp file */
+ current_local_file = NULL; /* file pointer for current local header */
+ current_local_offset = 0; /* offset to start of current local header */
+
+ /* global */
+ bytes_this_split = 0; /* bytes written to the current split */
+ read_split_archive = 0; /* 1=scanzipf_reg detected spanning signature */
+ split_method = 0; /* 0=no splits, 1=update LHs, 2=data descriptors */
+ split_size = 0; /* how big each split should be */
+ split_bell = 0; /* when pause for next split ring bell */
+ bytes_prev_splits = 0; /* total bytes written to all splits before this */
+ bytes_this_entry = 0; /* bytes written for this entry across all splits */
+ noisy_splits = 0; /* be verbose about creating splits */
+ mesg_line_started = 0; /* 1=started writing a line to mesg */
+ logfile_line_started = 0; /* 1=started writing a line to logfile */
+
+ filelist = NULL;
+ filearg_count = 0;
+ allow_empty_archive = 0; /* if no files, allow creation of empty archive anyway */
+ bad_open_is_error = 0; /* if read fails, 0=warning, 1=error */
+ unicode_mismatch = 0; /* unicode mismatch is 0=error, 1=warn, 2=ignore, 3=no */
+ show_files = 0; /* show files to operate on and exit */
+ scan_delay = 5; /* seconds before display Scanning files message */
+ scan_dot_time = 2; /* time in seconds between Scanning files dots */
+ scan_started = 0; /* space at start of scan has been displayed */
+ scan_last = 0; /* Time last dot displayed for Scanning files message */
+ scan_start = 0; /* Time scanning started for Scanning files message */
+#ifdef UNICODE_SUPPORT
+ use_wide_to_mb_default = 0;
+#endif
+ filter_match_case = 1; /* default is to match case when matching archive entries */
+ allow_fifo = 0; /* 1=allow reading Unix FIFOs, waiting if pipe open */
+
+#if !defined(MACOS) && !defined(USE_ZIPMAIN)
retcode = setjmp(zipdll_error_return);
if (retcode) {
return retcode;
@@ -987,11 +2471,28 @@ char **argv; /* command line tokens */
#endif /* !MACOS */
#endif /* MACOS || WINDLL */
+#if !defined(ALLOW_REGEX) && (defined(MSDOS) || defined(WIN32))
+ allow_regex = 0; /* 1 = allow [list] matching (regex) */
+#else
+ allow_regex = 1;
+#endif
+
mesg = (FILE *) stdout; /* cannot be made at link time for VMS */
comment_stream = (FILE *)stdin;
init_upper(); /* build case map table */
+#ifdef LARGE_FILE_SUPPORT
+ /* test if we can support large files - 9/29/04 */
+ if (sizeof(zoff_t) < 8) {
+ ZIPERR(ZE_COMPERR, "LARGE_FILE_SUPPORT enabled but OS not supporting it");
+ }
+#endif
+ /* test if sizes are the same - 12/30/04 */
+ if (sizeof(uzoff_t) != sizeof(zoff_t)){
+ ZIPERR(ZE_COMPERR, "uzoff_t not same size as zoff_t");
+ }
+
#if (defined(WIN32) && defined(USE_EF_UT_TIME))
/* For the Win32 environment, we may have to "prepare" the environment
prior to the tzset() call, to work around tzset() implementation bugs.
@@ -1023,543 +2524,1223 @@ char **argv; /* command line tokens */
#endif
#ifdef VMSCLI
- {
- ulg status = vms_zip_cmdline(&argc, &argv);
- if (!(status & 1))
+ {
+ ulg status = vms_zip_cmdline(&argc, &argv);
+ if (!(status & 1))
return status;
- }
+ }
#endif /* VMSCLI */
+ /* Substitutes the extended command line argument list produced by
+ * the MKS Korn Shell in place of the command line info from DOS.
+ */
+
/* extract extended argument list from environment */
expand_args(&argc, &argv);
-
#ifndef WINDLL
/* Process arguments */
diag("processing arguments");
/* First, check if just the help or version screen should be displayed */
if (argc == 1 && isatty(1)) /* no arguments, and output screen available */
{ /* show help screen */
-#ifdef VMSCLI
+# ifdef VMSCLI
VMSCLI_help();
-#else
+# else
help();
-#endif
- EXIT(0);
+# endif
+ EXIT(ZE_OK);
}
+ /* Check -v here as env arg can change argc. Handle --version in main switch. */
else if (argc == 2 && strcmp(argv[1], "-v") == 0 &&
/* only "-v" as argument, and */
(isatty(1) || isatty(0)))
/* stdout or stdin is connected to console device */
{ /* show diagnostic version info */
version_info();
- EXIT(0);
+ EXIT(ZE_OK);
}
-#ifndef VMS
-# ifndef RISCOS
+# ifndef VMS
+# ifndef RISCOS
envargs(&argc, &argv, "ZIPOPT", "ZIP"); /* get options from environment */
-# else /* RISCOS */
+# else /* RISCOS */
envargs(&argc, &argv, "ZIPOPT", "Zip$Options"); /* get options from environment */
getRISCOSexts("Zip$Exts"); /* get the extensions to swap from environment */
-# endif /* ? RISCOS */
-#else /* VMS */
+# endif /* ? RISCOS */
+# else /* VMS */
envargs(&argc, &argv, "ZIPOPT", "ZIP_OPTS"); /* 4th arg for unzip compat. */
-#endif /* ?VMS */
+# endif /* ?VMS */
#endif /* !WINDLL */
zipfile = tempzip = NULL;
- tempzf = NULL;
+ y = NULL;
d = 0; /* disallow adding to a zip file */
-#if (!defined(MACOS) && !defined(WINDLL))
+#if (!defined(MACOS) && !defined(WINDLL) && !defined(NLM))
signal(SIGINT, handler);
#ifdef SIGTERM /* AMIGADOS and others have no SIGTERM */
signal(SIGTERM, handler);
#endif
-#endif /* !MACOS && !WINDLL */
- k = 0; /* Next non-option argument type */
- s = 0; /* set by -@ if -@ is early */
+# if defined(SIGABRT) && !(defined(AMIGA) && defined(__SASC))
+ signal(SIGABRT, handler);
+# endif
+# ifdef SIGBREAK
+ signal(SIGBREAK, handler);
+# endif
+# ifdef SIGBUS
+ signal(SIGBUS, handler);
+# endif
+# ifdef SIGILL
+ signal(SIGILL, handler);
+# endif
+# ifdef SIGSEGV
+ signal(SIGSEGV, handler);
+# endif
+#endif /* !MACOS && !WINDLL && !NLM */
+#ifdef NLM
+ NLMsignals();
+#endif
- r = get_filters(argc, argv); /* scan first the -x and -i patterns */
-#ifdef WINDLL
- if (r != ZE_OK)
- return r;
+
+#if defined(UNICODE_SUPPORT) && defined(WIN32)
+ /* check if this Win32 OS has support for wide character calls */
+ has_win32_wide();
#endif
- for (i = 1; i < argc; i++)
+ /* make copy of args that can use with insert_arg() used by get_option() */
+ args = copy_args(argv, 0);
+
+ kk = 0; /* Next non-option argument type */
+ s = 0; /* set by -@ */
+
+ /*
+ -------------------------------------------
+ Process command line using get_option
+ -------------------------------------------
+
+ Each call to get_option() returns either a command
+ line option and possible value or a non-option argument.
+ Arguments are permuted so that all options (-r, -b temp)
+ are returned before non-option arguments (zipfile).
+ Returns 0 when nothing left to read.
+ */
+
+ /* set argnum = 0 on first call to init get_option */
+ argnum = 0;
+
+ /* get_option returns the option ID and updates parameters:
+ args - usually same as argv if no argument file support
+ argcnt - current argc for args
+ value - char* to value (free() when done with it) or NULL if no value
+ negated - option was negated with trailing -
+ */
+
+ while ((option = get_option(&args, &argcnt, &argnum,
+ &optchar, &value, &negated,
+ &fna, &optnum, 0)))
{
- if (argv[i][0] == '-')
+ switch (option)
{
- if (argv[i][1])
- for (p = argv[i]+1; *p; p++)
- switch (*p)
- {
#ifdef EBCDIC
- case 'a':
- aflag = ASCII;
- printf("Translating to ASCII...\n");
- break;
+ case 'a':
+ aflag = ASCII;
+ printf("Translating to ASCII...\n");
+ break;
#endif /* EBCDIC */
#ifdef CMS_MVS
- case 'B':
- bflag = 1;
- printf("Using binary mode...\n");
- break;
+ case 'B':
+ bflag = 1;
+ printf("Using binary mode...\n");
+ break;
#endif /* CMS_MVS */
#ifdef TANDEM
- case 'B':
- nskformatopt(&p);
- break;
+ case 'B':
+ nskformatopt(value);
+ free(value);
+ break;
#endif
- case '0':
- method = STORE; level = 0; break;
- case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- /* Set the compression efficacy */
- level = *p - '0'; break;
- case 'A': /* Adjust unzipsfx'd zipfile: adjust offsets only */
- adjust = 1; break;
- case 'b': /* Specify path for temporary file */
- tempdir = 1;
- if (k != 0) {
- ZIPERR(ZE_PARMS, "use -b before zip file name");
- }
- else
- k = 1; /* Next non-option is path */
- break;
- case 'c': /* Add comments for new files in zip file */
- comadd = 1; break;
- case 'd': /* Delete files from zip file */
+
+ case '0':
+ method = STORE; level = 0; break;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ /* Set the compression efficacy */
+ level = (int)option - '0'; break;
+ case 'A': /* Adjust unzipsfx'd zipfile: adjust offsets only */
+ adjust = 1; break;
+#if defined(WIN32)
+ case o_AC:
+ clear_archive_bits = 1; break;
+ case o_AS:
+ /* Since some directories could be empty if no archive bits are
+ set for files in a directory, don't add directory entries (-D).
+ Just files with the archive bit set are added, including paths
+ (unless paths are excluded). All major unzips should create
+ directories for the paths as needed. */
+ dirnames = 0;
+ only_archive_set = 1; break;
+#endif /* MSDOS || OS2 || WIN32 */
+ case 'b': /* Specify path for temporary file */
+ tempdir = 1;
+ tempath = value;
+ break;
+ case 'c': /* Add comments for new files in zip file */
+ comadd = 1; break;
+
+ /* -C, -C2, and -C5 are with -V */
+
+ case 'd': /* Delete files from zip file */
+ if (action != ADD) {
+ ZIPERR(ZE_PARMS, "specify just one action");
+ }
+ action = DELETE;
+ break;
#ifdef MACOS
- if (p[1] == 'f') {
- ++p;
- MacZip.DataForkOnly = true;
- } else
+ case o_df:
+ MacZip.DataForkOnly = true;
+ break;
#endif /* MACOS */
- {
- if (action != ADD) {
- ZIPERR(ZE_PARMS, "specify just one action");
- }
- action = DELETE;
- break;
- }
- case 'D': /* Do not add directory entries */
- dirnames = 0; break;
- case 'e': /* Encrypt */
+ case o_db:
+ if (negated)
+ display_bytes = 0;
+ else
+ display_bytes = 1;
+ break;
+ case o_dc:
+ if (negated)
+ display_counts = 0;
+ else
+ display_counts = 1;
+ break;
+ case o_dd:
+ /* display dots */
+ display_globaldots = 0;
+ if (negated) {
+ dot_count = 0;
+ } else {
+ /* set default dot size if dot_size not set (dot_count = 0) */
+ if (dot_count == 0)
+ /* default to 10 MB */
+ dot_size = 10 * 0x100000;
+ dot_count = -1;
+ }
+ break;
+ case o_dg:
+ /* display dots globally for archive instead of for each file */
+ if (negated) {
+ display_globaldots = 0;
+ } else {
+ display_globaldots = 1;
+ /* set default dot size if dot_size not set (dot_count = 0) */
+ if (dot_count == 0)
+ dot_size = 10 * 0x100000;
+ dot_count = -1;
+ }
+ break;
+ case o_ds:
+ /* input dot_size is now actual dot size to account for
+ different buffer sizes */
+ if (value == NULL)
+ dot_size = 10 * 0x100000;
+ else if (value[0] == '\0') {
+ /* default to 10 MB */
+ dot_size = 10 * 0x100000;
+ free(value);
+ } else {
+ dot_size = ReadNumString(value);
+ if (dot_size == (zoff_t)-1) {
+ sprintf(errbuf, "option -ds (--dot-size) has bad size: '%s'",
+ value);
+ free(value);
+ ZIPERR(ZE_PARMS, errbuf);
+ }
+ if (dot_size < 0x400) {
+ /* < 1 KB so there is no multiplier, assume MB */
+ dot_size *= 0x100000;
+
+ } else if (dot_size < 0x400L * 32) {
+ /* 1K <= dot_size < 32K */
+ sprintf(errbuf, "dot size must be at least 32 KB: '%s'", value);
+ free(value);
+ ZIPERR(ZE_PARMS, errbuf);
+
+ } else {
+ /* 32K <= dot_size */
+ }
+ free(value);
+ }
+ dot_count = -1;
+ break;
+ case o_du:
+ if (negated)
+ display_usize = 0;
+ else
+ display_usize = 1;
+ break;
+ case o_dv:
+ if (negated)
+ display_volume = 0;
+ else
+ display_volume = 1;
+ break;
+ case 'D': /* Do not add directory entries */
+ dirnames = 0; break;
+ case o_DF: /* Create a difference archive */
+ diff_mode = 1;
+ allow_empty_archive = 1;
+ break;
+ case 'e': /* Encrypt */
#if !CRYPT
- ZIPERR(ZE_PARMS, "encryption not supported");
+ ZIPERR(ZE_PARMS, "encryption not supported");
#else /* CRYPT */
- if (key == NULL) {
- if ((key = malloc(IZ_PWLEN+1)) == NULL) {
- ZIPERR(ZE_MEM, "was getting encryption password");
- }
- r = encr_passwd(ZP_PW_ENTER, key, IZ_PWLEN+1, zipfile);
- if (r != IZ_PW_ENTERED) {
- if (r < IZ_PW_ENTERED)
- r = ZE_PARMS;
- ZIPERR(r, "was getting encryption password");
- }
- if (*key == '\0') {
- ZIPERR(ZE_PARMS, "zero length password not allowed");
- }
- if ((e = malloc(IZ_PWLEN+1)) == NULL) {
- ZIPERR(ZE_MEM, "was verifying encryption password");
- }
- r = encr_passwd(ZP_PW_VERIFY, e, IZ_PWLEN+1, zipfile);
- if (r != IZ_PW_ENTERED && r != IZ_PW_SKIPVERIFY) {
- free((zvoid *)e);
- if (r < ZE_OK) r = ZE_PARMS;
- ZIPERR(r, "was verifying encryption password");
- }
- r = ((r == IZ_PW_SKIPVERIFY) ? 0 : strcmp(key, e));
- free((zvoid *)e);
- if (r) {
- ZIPERR(ZE_PARMS, "password verification failed");
- }
- }
+ if (key)
+ free(key);
+ key_needed = 1;
#endif /* !CRYPT */
- break;
- case 'F': /* fix the zip file */
- fix++; break;
- case 'f': /* Freshen zip file--overwrite only */
- if (action != ADD) {
- ZIPERR(ZE_PARMS, "specify just one action");
- }
- action = FRESHEN;
- break;
- case 'g': /* Allow appending to a zip file */
- d = 1; break;
+ break;
+ case 'F': /* fix the zip file */
+ fix = 1; break;
+ case o_FF: /* try harder to fix file */
+ fix = 2; break;
+ case o_FI:
+ if (negated)
+ allow_fifo = 0;
+ else
+ allow_fifo = 1;
+ break;
+ case o_FS: /* delete exiting entries in archive where there is
+ no matching file on file system */
+ filesync = 1; break;
+ case 'f': /* Freshen zip file--overwrite only */
+ if (action != ADD) {
+ ZIPERR(ZE_PARMS, "specify just one action");
+ }
+ action = FRESHEN;
+ break;
+ case 'g': /* Allow appending to a zip file */
+ d = 1; break;
#ifndef WINDLL
- case 'h': case 'H': case '?': /* Help */
+ case 'h': case 'H': case '?': /* Help */
#ifdef VMSCLI
- VMSCLI_help();
+ VMSCLI_help();
#else
- help();
+ help();
#endif
- RETURN(finish(ZE_OK));
+ RETURN(finish(ZE_OK));
+#endif /* !WINDLL */
+
+#ifndef WINDLL
+ case o_h2: /* Extended Help */
+ help_extended();
+ RETURN(finish(ZE_OK));
#endif /* !WINDLL */
+ /* -i is with -x */
+#if defined(VMS) || defined(WIN32)
+ case o_ic: /* Ignore case (case-insensitive matching of archive entries) */
+ if (negated)
+ filter_match_case = 1;
+ else
+ filter_match_case = 0;
+ break;
+#endif
#ifdef RISCOS
- case 'I': /* Don't scan through Image files */
- scanimage = 0;
- break;
+ case 'I': /* Don't scan through Image files */
+ scanimage = 0;
+ break;
#endif
#ifdef MACOS
- case 'j': /* Junk path / Store absolute path */
- if (p[1] == 'j') { /* store absolute path including volname */
- ++p;
- MacZip.StoreFullPath = true;
- } else { /* junk directory names */
- pathput = 0; break;
- }
-#else /* !MACOS */
- case 'j': /* Junk directory names */
- pathput = 0; break;
+ case o_jj: /* store absolute path including volname */
+ MacZip.StoreFullPath = true;
+ break;
#endif /* ?MACOS */
- case 'J': /* Junk sfx prefix */
- junk_sfx = 1; break;
- case 'k': /* Make entries using DOS names (k for Katz) */
- dosify = 1; break;
- case 'l': /* Translate end-of-line */
- translate_eol++; break;
+ case 'j': /* Junk directory names */
+ pathput = 0; break;
+ case 'J': /* Junk sfx prefix */
+ junk_sfx = 1; break;
+ case 'k': /* Make entries using DOS names (k for Katz) */
+ dosify = 1; break;
+ case 'l': /* Translate end-of-line */
+ translate_eol = 1; break;
+ case o_ll:
+ translate_eol = 2; break;
+ case o_lf:
+ /* open a logfile */
+ /* allow multiple use of option but only last used */
+ if (logfile_path) {
+ free(logfile_path);
+ }
+ logfile_path = value;
+ break;
+ case o_la:
+ /* append to existing logfile */
+ if (negated)
+ logfile_append = 0;
+ else
+ logfile_append = 1;
+ break;
+ case o_li:
+ /* log all including informational messages */
+ if (negated)
+ logall = 0;
+ else
+ logall = 1;
+ break;
#ifndef WINDLL
- case 'L': /* Show license */
- license();
- RETURN(finish(ZE_OK));
-#endif
- case 'm': /* Delete files added or updated in zip file */
- dispose = 1; break;
- case 'n': /* Don't compress files with a special suffix */
- special = NULL; /* will be set at next argument */
- break;
+ case 'L': /* Show license */
+ license();
+ RETURN(finish(ZE_OK));
+#endif
+ case 'm': /* Delete files added or updated in zip file */
+ dispose = 1; break;
+ case o_mm: /* To prevent use of -mm for -MM */
+ ZIPERR(ZE_PARMS, "-mm not supported, Must_Match is -MM");
+ dispose = 1; break;
+ case o_MM: /* Exit with error if input file can't be read */
+ bad_open_is_error = 1; break;
+ case 'n': /* Don't compress files with a special suffix */
+ special = value;
+ /* special = NULL; */ /* will be set at next argument */
+ break;
+ case o_nw: /* no wildcards - wildcards are handled like other characters */
+ no_wild = 1;
+ break;
#if defined(AMIGA) || defined(MACOS)
- case 'N': /* Get zipfile comments from AmigaDOS/MACOS filenotes */
- filenotes = 1; break;
-#endif
- case 'o': /* Set zip file time to time of latest file in it */
- latest = 1; break;
- case 'p': /* Store path with name */
- break; /* (do nothing as annoyance avoidance) */
- case 'P': /* password for encryption */
- if (k != 0) {
- ZIPERR(ZE_PARMS, "use -P before zip file name");
- }
- if (key != NULL) {
- ZIPERR(ZE_PARMS, "can only have one -P");
- }
+ case 'N': /* Get zipfile comments from AmigaDOS/MACOS filenotes */
+ filenotes = 1; break;
+#endif
+ case 'o': /* Set zip file time to time of latest file in it */
+ latest = 1; break;
+ case 'O': /* Set output file different than input archive */
+ out_path = ziptyp(value);
+ free(value);
+ have_out = 1;
+ break;
+ case 'p': /* Store path with name */
+ break; /* (do nothing as annoyance avoidance) */
+ case 'P': /* password for encryption */
+ if (key != NULL) {
+ free(key);
+ }
#if CRYPT
- k = 7;
+ key = value;
+ key_needed = 0;
#else
- ZIPERR(ZE_PARMS, "encryption not supported");
+ ZIPERR(ZE_PARMS, "encryption not supported");
#endif /* CRYPT */
- break;
+ break;
#if defined(QDOS) || defined(QLZIP)
- case 'Q':
- qlflag = strtol((p+1), &p, 10);
- if (qlflag == 0) qlflag = 4;
- p--;
- break;
+ case 'Q':
+ qlflag = strtol(value, NULL, 10);
+ /* qlflag = strtol((p+1), &p, 10); */
+ /* p--; */
+ if (qlflag == 0) qlflag = 4;
+ free(value);
+ break;
#endif
- case 'q': /* Quiet operation */
- noisy = 0;
+ case 'q': /* Quiet operation */
+ noisy = 0;
#ifdef MACOS
- MacZip.MacZip_Noisy = false;
+ MacZip.MacZip_Noisy = false;
#endif /* MACOS */
- if (verbose) verbose--;
- break;
- case 'r': /* Recurse into subdirectories, match full path */
- if (recurse == 2) {
- ZIPERR(ZE_PARMS, "do not specify both -r and -R");
+ if (verbose) verbose--;
+ break;
+ case 'r': /* Recurse into subdirectories, match full path */
+ if (recurse == 2) {
+ ZIPERR(ZE_PARMS, "do not specify both -r and -R");
+ }
+ recurse = 1; break;
+ case 'R': /* Recurse into subdirectories, match filename */
+ if (recurse == 1) {
+ ZIPERR(ZE_PARMS, "do not specify both -r and -R");
+ }
+ recurse = 2; break;
+
+ case o_RE: /* Allow [list] matching (regex) */
+ allow_regex = 1; break;
+
+ case o_sc: /* show command line args */
+ show_args = 1; break;
+#ifdef UNICODE_TEST
+ case o_sC: /* create empty files from archive names */
+ create_files = 1;
+ show_files = 1; break;
+#endif
+ case o_sd: /* show debugging */
+ show_what_doing = 1; break;
+ case o_sf: /* show files to operate on */
+ if (!negated)
+ show_files = 1;
+ else
+ show_files = 2;
+ break;
+ case o_so: /* show all options */
+ show_options = 1; break;
+#ifdef UNICODE_SUPPORT
+ case o_su: /* -sf but also show Unicode if exists */
+ if (!negated)
+ show_files = 3;
+ else
+ show_files = 4;
+ break;
+ case o_sU: /* -sf but only show Unicode if exists or normal if not */
+ if (!negated)
+ show_files = 5;
+ else
+ show_files = 6;
+ break;
+#endif
+
+ case 's': /* enable split archives */
+ /* get the split size from value */
+ if (strcmp(value, "-") == 0) {
+ /* -s- do not allow splits */
+ split_method = -1;
+ } else {
+ split_size = ReadNumString(value);
+ if (split_size == (uzoff_t)-1) {
+ sprintf(errbuf, "bad split size: '%s'", value);
+ ZIPERR(ZE_PARMS, errbuf);
+ }
+ if (split_size == 0) {
+ /* do not allow splits */
+ split_method = -1;
+ } else {
+ if (split_method == 0) {
+ split_method = 1;
}
- recurse = 1; break;
- case 'R': /* Recurse into subdirectories, match filename */
- if (recurse == 1) {
- ZIPERR(ZE_PARMS, "do not specify both -r and -R");
+ if (split_size < 0x400) {
+ /* < 1 KB there is no multiplier, assume MB */
+ split_size *= 0x100000;
}
- recurse = 2; break;
+ /* By setting the minimum split size to 64 KB we avoid
+ not having enough room to write a header unsplit
+ which is required */
+ if (split_size < 0x400L * 64) {
+ /* split_size < 64K */
+ sprintf(errbuf, "minimum split size is 64 KB: '%s'", value);
+ free(value);
+ ZIPERR(ZE_PARMS, errbuf);
+ }
+ }
+ }
+ free(value);
+ break;
+ case o_sb: /* when pause for next split ring bell */
+ split_bell = 1;
+ break;
+ case o_sp: /* enable split select - pause splitting between splits */
+ use_descriptors = 1;
+ split_method = 2;
+ break;
+ case o_sv: /* be verbose about creating splits */
+ noisy_splits = 1;
+ break;
+
#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(ATARI)
- case 'S':
- hidden_files = 1; break;
+ case 'S':
+ hidden_files = 1; break;
#endif /* MSDOS || OS2 || WIN32 || ATARI */
#ifdef MACOS
- case 'S':
- MacZip.IncludeInvisible = true; break;
+ case 'S':
+ MacZip.IncludeInvisible = true; break;
#endif /* MACOS */
- case 't': /* Exclude files earlier than specified date */
- if (p[1] == 't') {
- ++p;
- cmptime = &after;
- } else {
- cmptime = &before;
- }
- if (*cmptime) {
- ZIPERR(ZE_PARMS, (cmptime == &after ?
- "can only have one -tt" : "can only have one -t"));
- }
- k = 2; break;
- case 'T': /* test zip file */
- test = 1; break;
- case 'u': /* Update zip file--overwrite only if newer */
- if (action != ADD) {
- ZIPERR(ZE_PARMS, "specify just one action");
- }
- action = UPDATE;
- break;
- case 'v': /* Mention oddities in zip file structure */
- noisy = 1;
- verbose++;
- break;
+ case 't': /* Exclude files earlier than specified date */
+ {
+ int yyyy, mm, dd; /* results of sscanf() */
+
+ /* Support ISO 8601 & American dates */
+ if ((sscanf(value, "%4d-%2d-%2d", &yyyy, &mm, &dd) != 3 &&
+ sscanf(value, "%2d%2d%4d", &mm, &dd, &yyyy) != 3) ||
+ mm < 1 || mm > 12 || dd < 1 || dd > 31) {
+ ZIPERR(ZE_PARMS,
+ "invalid date entered for -t option - use mmddyyyy or yyyy-mm-dd");
+ }
+ before = dostime(yyyy, mm, dd, 0, 0, 0);
+ }
+ free(value);
+ break;
+ case o_tt: /* Exclude files at or after specified date */
+ {
+ int yyyy, mm, dd; /* results of sscanf() */
+
+ /* Support ISO 8601 & American dates */
+ if ((sscanf(value, "%4d-%2d-%2d", &yyyy, &mm, &dd) != 3 &&
+ sscanf(value, "%2d%2d%4d", &mm, &dd, &yyyy) != 3) ||
+ mm < 1 || mm > 12 || dd < 1 || dd > 31) {
+ ZIPERR(ZE_PARMS,
+ "invalid date entered for -tt option - use mmddyyyy or yyyy-mm-dd");
+ }
+ after = dostime(yyyy, mm, dd, 0, 0, 0);
+ }
+ free(value);
+ break;
+ case 'T': /* test zip file */
+ test = 1; break;
+ case o_TT: /* command path to use instead of 'unzip -t ' */
+ if (unzip_path)
+ free(unzip_path);
+ unzip_path = value;
+ break;
+ case 'U': /* Select archive entries to keep or operate on */
+ if (action != ADD) {
+ ZIPERR(ZE_PARMS, "specify just one action");
+ }
+ action = ARCHIVE;
+ break;
+#ifdef UNICODE_SUPPORT
+ case o_UN: /* Unicode */
+ if (abbrevmatch("quit", value, 0, 1)) {
+ /* Unicode path mismatch is error */
+ unicode_mismatch = 0;
+ } else if (abbrevmatch("warn", value, 0, 1)) {
+ /* warn of mismatches and continue */
+ unicode_mismatch = 1;
+ } else if (abbrevmatch("ignore", value, 0, 1)) {
+ /* ignore mismatches and continue */
+ unicode_mismatch = 2;
+ } else if (abbrevmatch("no", value, 0, 1)) {
+ /* no use Unicode path */
+ unicode_mismatch = 3;
+ } else if (abbrevmatch("escape", value, 0, 1)) {
+ /* escape all non-ASCII characters */
+ unicode_escape_all = 1;
+
+ } else if (abbrevmatch("UTF8", value, 0, 1)) {
+ /* force storing UTF-8 as standard per AppNote bit 11 */
+ utf8_force = 1;
+
+ } else {
+ zipwarn("-UN must be Quit, Warn, Ignore, No, Escape, or UTF8: ", value);
+
+ free(value);
+ ZIPERR(ZE_PARMS, "-UN (unicode) bad value");
+ }
+ free(value);
+ break;
+#endif
+ case 'u': /* Update zip file--overwrite only if newer */
+ if (action != ADD) {
+ ZIPERR(ZE_PARMS, "specify just one action");
+ }
+ action = UPDATE;
+ break;
+ case 'v': /* Either display version information or */
+ case o_ve: /* Mention oddities in zip file structure */
+ if (option == o_ve || /* --version */
+ (argcnt == 2 && strlen(args[1]) == 2)) { /* -v only */
+ /* display version */
+#ifndef WINDLL
+ version_info();
+#else
+ zipwarn("version information not supported for dll", "");
+#endif
+ RETURN(finish(ZE_OK));
+ } else {
+ noisy = 1;
+ verbose++;
+ }
+ break;
#ifdef VMS
- case 'V': /* Store in VMS format. (Record multiples.) */
- vms_native++; break;
- case 'w': /* Append the VMS version number */
- vmsver = 1; break;
+ case 'C': /* Preserve case (- = down-case) all. */
+ if (negated)
+ { /* Down-case all. */
+ if ((vms_case_2 > 0) || (vms_case_5 > 0))
+ {
+ ZIPERR( ZE_PARMS, "Conflicting case directives (-C-)");
+ }
+ vms_case_2 = -1;
+ vms_case_5 = -1;
+ }
+ else
+ { /* Not negated. Preserve all. */
+ if ((vms_case_2 < 0) || (vms_case_5 < 0))
+ {
+ ZIPERR( ZE_PARMS, "Conflicting case directives (-C)");
+ }
+ vms_case_2 = 1;
+ vms_case_5 = 1;
+ }
+ break;
+ case o_C2: /* Preserve case (- = down-case) ODS2. */
+ if (negated)
+ { /* Down-case ODS2. */
+ if (vms_case_2 > 0)
+ {
+ ZIPERR( ZE_PARMS, "Conflicting case directives (-C2-)");
+ }
+ vms_case_2 = -1;
+ }
+ else
+ { /* Not negated. Preserve ODS2. */
+ if (vms_case_2 < 0)
+ {
+ ZIPERR( ZE_PARMS, "Conflicting case directives (-C2)");
+ }
+ vms_case_2 = 1;
+ }
+ break;
+ case o_C5: /* Preserve case (- = down-case) ODS5. */
+ if (negated)
+ { /* Down-case ODS5. */
+ if (vms_case_5 > 0)
+ {
+ ZIPERR( ZE_PARMS, "Conflicting case directives (-C5-)");
+ }
+ vms_case_5 = -1;
+ }
+ else
+ { /* Not negated. Preserve ODS5. */
+ if (vms_case_5 < 0)
+ {
+ ZIPERR( ZE_PARMS, "Conflicting case directives (-C5)");
+ }
+ vms_case_5 = 1;
+ }
+ break;
+ case 'V': /* Store in VMS format. (Record multiples.) */
+ vms_native = 1; break;
+ /* below does work with new parser but doesn't allow tracking
+ -VV separately, like adding a separate description */
+ /* vms_native++; break; */
+ case o_VV: /* Store in VMS specific format */
+ vms_native = 2; break;
+ case 'w': /* Append the VMS version number */
+ vmsver |= 1; break;
+ case o_ww: /* Append the VMS version number as ".nnn". */
+ vmsver |= 3; break;
#endif /* VMS */
- case 'i': /* Include only the following files */
- case 'x': /* Exclude following files */
- if (p[1] == '@' && p[2] != '\0') {
- goto nextarg;
- }
- if (zipfile == NULL) {
- ZIPERR(ZE_PARMS, "use -x or -i after name of zipfile");
- }
- k = 5;
- break;
+ case o_ws: /* Wildcards do not include directory boundaries in matches */
+ wild_stop_at_dir = 1;
+ break;
+
+ case 'i': /* Include only the following files */
+ /* if nothing matches include list then still create an empty archive */
+ allow_empty_archive = 1;
+ case 'x': /* Exclude following files */
+ add_filter((int) option, value);
+ free(value);
+ break;
#ifdef S_IFLNK
- case 'y': /* Store symbolic links as such */
- linkput = 1; break;
+ case 'y': /* Store symbolic links as such */
+ linkput = 1; break;
#endif /* S_IFLNK */
- case 'z': /* Edit zip file comment */
- zipedit = 1; break;
+ case 'z': /* Edit zip file comment */
+ zipedit = 1; break;
+ case 'Z': /* Compression method */
+ if (abbrevmatch("deflate", value, 0, 1)) {
+ /* deflate */
+ method = DEFLATE;
+ } else if (abbrevmatch("store", value, 0, 1)) {
+ /* store */
+ method = STORE;
+ } else if (abbrevmatch("bzip2", value, 0, 1)) {
+ /* bzip2 */
+#ifdef BZIP2_SUPPORT
+ method = BZIP2;
+#else
+ ZIPERR(ZE_COMPERR, "Compression method bzip2 not enabled");
+#endif
+ } else {
+#ifdef BZIP2_SUPPORT
+ zipwarn("valid compression methods are: store, deflate, bzip2", "");
+#else
+ zipwarn("valid compression methods are: store, deflate)", "");
+#endif
+ zipwarn("unknown compression method found: ", value);
+ free(value);
+ ZIPERR(ZE_PARMS, "Option -Z (--compression-method): unknown method");
+ }
+ free(value);
+ break;
#if defined(MSDOS) || defined(OS2)
- case '$': /* Include volume label */
- volume_label = 1; break;
+ case '$': /* Include volume label */
+ volume_label = 1; break;
#endif
#ifndef MACOS
- case '@': /* read file names from stdin */
- comment_stream = NULL;
- if (k < 3) /* zip file not read yet */
- s = 1; /* defer -@ until after zipfile read */
- else /* zip file read--do it now */
- while ((pp = getnam(errbuf, stdin)) != NULL)
+ case '@': /* read file names from stdin */
+ comment_stream = NULL;
+ s = 1; /* defer -@ until have zipfile name */
+ break;
+#endif /* !MACOS */
+ case 'X':
+ if (negated)
+ extra_fields = 2;
+ else
+ extra_fields = 0;
+ break;
+#ifdef OS2
+ case 'E':
+ /* use the .LONGNAME EA (if any) as the file's name. */
+ use_longname_ea = 1;
+ break;
+#endif
+#ifdef NTSD_EAS
+ case '!':
+ /* use security privilege overrides */
+ use_privileges = 1;
+ break;
+#endif
+#ifdef RISCOS
+ case '/':
+ exts2swap = value; /* override Zip$Exts */
+ break;
+#endif
+ case o_des:
+ use_descriptors = 1;
+ break;
+
+#ifdef ZIP64_SUPPORT
+ case o_z64: /* Force creation of Zip64 entries */
+ if (negated) {
+ force_zip64 = 0;
+ } else {
+ force_zip64 = 1;
+ }
+ break;
+#endif
+
+ case o_NON_OPTION_ARG:
+ /* not an option */
+ /* no more options as permuting */
+ /* just dash also ends up here */
+
+ if (recurse != 2 && kk == 0 && patterns == NULL) {
+ /* have all filters so convert filterlist to patterns array
+ as PROCNAME needs patterns array */
+ filterlist_to_patterns();
+ }
+
+ /* "--" stops arg processing for remaining args */
+ /* ignore only first -- */
+ if (strcmp(value, "--") == 0 && seen_doubledash == 0) {
+ /* -- */
+ seen_doubledash = 1;
+ if (kk == 0) {
+ ZIPERR(ZE_PARMS, "can't use -- before archive name");
+ }
+
+ /* just ignore as just marks what follows as non-option arguments */
+
+ } else if (kk == 6) {
+ /* value is R pattern */
+ add_filter((int)'R', value);
+ free(value);
+ if (first_listarg == 0) {
+ first_listarg = argnum;
+ }
+ } else switch (kk)
+ {
+ case 0:
+ /* first non-option arg is zipfile name */
+#if (!defined(MACOS) && !defined(WINDLL))
+ if (strcmp(value, "-") == 0) { /* output zipfile is dash */
+ /* just a dash */
+ zipstdout();
+ } else
+#endif /* !MACOS && !WINDLL */
+ {
+ /* name of zipfile */
+ if ((zipfile = ziptyp(value)) == NULL) {
+ ZIPERR(ZE_MEM, "was processing arguments");
+ }
+ /* read zipfile if exists */
+ /*
+ if ((r = readzipfile()) != ZE_OK) {
+ ZIPERR(r, zipfile);
+ }
+ */
+ free(value);
+ }
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Zipfile name '%s'\n", zipfile);
+ fflush(mesg);
+ }
+ /* if in_path not set, use zipfile path as usual for input */
+ /* in_path is used as the base path to find splits */
+ if (in_path == NULL) {
+ if ((in_path = malloc(strlen(zipfile) + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "was processing arguments");
+ }
+ strcpy(in_path, zipfile);
+ }
+ /* if out_path not set, use zipfile path as usual for output */
+ /* out_path is where the output archive is written */
+ if (out_path == NULL) {
+ if ((out_path = malloc(strlen(zipfile) + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "was processing arguments");
+ }
+ strcpy(out_path, zipfile);
+ }
+ kk = 3;
+ if (s)
+ {
+ /* do -@ and get names from stdin */
+ /* should be able to read names from
+ stdin and output to stdout, but
+ this was not allowed in old code.
+ This check moved to kk = 3 case to fix. */
+ /* if (strcmp(zipfile, "-") == 0) {
+ ZIPERR(ZE_PARMS, "can't use - and -@ together");
+ }
+ */
+ while ((pp = getnam(stdin)) != NULL)
{
- k = 4;
- if ((r = PROCNAME(pp)) != ZE_OK)
- {
+ kk = 4;
+ if (recurse == 2) {
+ /* reading patterns from stdin */
+ add_filter((int)'R', pp);
+ } else {
+ /* file argument now processed later */
+ add_name(pp);
+ }
+ /*
+ if ((r = PROCNAME(pp)) != ZE_OK) {
if (r == ZE_MISS)
zipwarn("name not matched: ", pp);
else {
ZIPERR(r, pp);
}
}
+ */
+ free(pp);
}
+ s = 0;
+ }
+ if (recurse == 2) {
+ /* rest are -R patterns */
+ kk = 6;
+ }
break;
-#endif /* !MACOS */
- case 'X':
- extra_fields = 0;
- break;
-#ifdef OS2
- case 'E':
- /* use the .LONGNAME EA (if any) as the file's name. */
- use_longname_ea = 1;
- break;
-#endif
-#ifdef NTSD_EAS
- case '!':
- /* use security privilege overrides */
- use_privileges = 1;
+
+ case 3: case 4:
+ /* no recurse and -r file names */
+ /* can't read filenames -@ and input - from stdin at
+ same time */
+ if (s == 1 && strcmp(value, "-") == 0) {
+ ZIPERR(ZE_PARMS, "can't read input (-) and filenames (-@) both from stdin");
+ }
+ /* add name to list for later processing */
+ add_name(value);
+ /*
+ if ((r = PROCNAME(value)) != ZE_OK) {
+ if (r == ZE_MISS)
+ zipwarn("name not matched: ", value);
+ else {
+ ZIPERR(r, value);
+ }
+ }
+ */
+ if (kk == 3) {
+ first_listarg = argnum;
+ kk = 4;
+ }
break;
-#endif
- default:
- {
- sprintf(errbuf, "no such option: %c", *p);
- ZIPERR(ZE_PARMS, errbuf);
- }
- }
- else /* just a dash */
- switch (k)
- {
-#if (!defined(MACOS) && !defined(WINDLL))
- case 0:
- zipstdout();
- k = 3;
- break;
-#endif /* !MACOS && !WINDLL */
- case 1:
- ZIPERR(ZE_PARMS, "invalid path");
- /* not reached */
- case 2:
- ZIPERR(ZE_PARMS, "invalid time");
- /* not reached */
- case 3: case 4:
- comment_stream = NULL;
- if ((r = PROCNAME(argv[i])) != ZE_OK) {
- if (r == ZE_MISS)
- zipwarn("name not matched: ", argv[i]);
- else {
- ZIPERR(r, argv[i]);
- }
- }
- if (k == 3) {
- first_listarg = i;
- k = 4;
- }
- }
+
+ } /* switch kk */
+ break;
+
+ default:
+ /* should never get here as get_option will exit if not in table */
+ sprintf(errbuf, "no such option ID: %ld", option);
+ ZIPERR(ZE_PARMS, errbuf);
+
+ } /* switch */
+ }
+
+
+ /* do processing of command line and one-time tasks */
+
+ /* Key not yet specified. If needed, get/verify it now. */
+ if (key_needed) {
+ if ((key = malloc(IZ_PWLEN+1)) == NULL) {
+ ZIPERR(ZE_MEM, "was getting encryption password");
}
- else /* not an option */
- {
- if (special == NULL)
- special = argv[i];
- else if (k == 5)
- break; /* -i and -x arguments already scanned */
- else if (k == 6) {
-#ifdef AMIGA
- if ((r = PROCNAME("")) != ZE_OK) {
-#else
- if ((r = PROCNAME(".")) != ZE_OK) {
-#endif
- if (r == ZE_MISS)
- zipwarn("name not matched: ", argv[i]);
- else {
- ZIPERR(r, argv[i]);
- }
- }
- if (first_listarg == 0)
- first_listarg = i;
- break;
- }
- else switch (k)
- {
- case 0:
- if ((zipfile = ziptyp(argv[i])) == NULL) {
- ZIPERR(ZE_MEM, "was processing arguments");
- }
- if ((r = readzipfile()) != ZE_OK) {
- ZIPERR(r, zipfile);
- }
- k = 3;
- if (recurse == 2)
- k = 6;
+ r = encr_passwd(ZP_PW_ENTER, key, IZ_PWLEN+1, zipfile);
+ if (r != IZ_PW_ENTERED) {
+ if (r < IZ_PW_ENTERED)
+ r = ZE_PARMS;
+ ZIPERR(r, "was getting encryption password");
+ }
+ if (*key == '\0') {
+ ZIPERR(ZE_PARMS, "zero length password not allowed");
+ }
+ if ((e = malloc(IZ_PWLEN+1)) == NULL) {
+ ZIPERR(ZE_MEM, "was verifying encryption password");
+ }
+ r = encr_passwd(ZP_PW_VERIFY, e, IZ_PWLEN+1, zipfile);
+ if (r != IZ_PW_ENTERED && r != IZ_PW_SKIPVERIFY) {
+ free((zvoid *)e);
+ if (r < ZE_OK) r = ZE_PARMS;
+ ZIPERR(r, "was verifying encryption password");
+ }
+ r = ((r == IZ_PW_SKIPVERIFY) ? 0 : strcmp(key, e));
+ free((zvoid *)e);
+ if (r) {
+ ZIPERR(ZE_PARMS, "password verification failed");
+ }
+ }
+ if (key) {
+ /* if -P "" could get here */
+ if (*key == '\0') {
+ ZIPERR(ZE_PARMS, "zero length password not allowed");
+ }
+ }
+
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Command line read\n");
+ fflush(mesg);
+ }
+
+ /* show command line args */
+ if (show_args) {
+ fprintf(mesg, "command line:\n");
+ for (i = 0; args[i]; i++) {
+ fprintf(mesg, "'%s' ", args[i]);
+ }
+ fprintf(mesg, "\n");
+ ZIPERR(ZE_ABORT, "show command line");
+ }
+
+ /* show all options */
+ if (show_options) {
+ printf("available options:\n");
+ printf(" %-2s %-18s %-4s %-3s %-30s\n", "sh", "long", "val", "neg", "description");
+ printf(" %-2s %-18s %-4s %-3s %-30s\n", "--", "----", "---", "---", "-----------");
+ for (i = 0; options[i].option_ID; i++) {
+ printf(" %-2s %-18s ", options[i].shortopt, options[i].longopt);
+ switch (options[i].value_type) {
+ case o_NO_VALUE:
+ printf("%-4s ", "");
break;
- case 1:
- if ((tempath = malloc(strlen(argv[i]) + 1)) == NULL) {
- ZIPERR(ZE_MEM, "was processing arguments");
- }
- strcpy(tempath, argv[i]);
- k = (zipfile != NULL ? (first_listarg > 0 ? 4 : 3) : 0);
+ case o_REQUIRED_VALUE:
+ printf("%-4s ", "req");
break;
- case 2:
- {
- int yyyy, mm, dd; /* results of sscanf() */
-
- /* Support ISO 8601 & American dates */
- if ((sscanf(argv[i], "%4d-%2d-%2d", &yyyy, &mm, &dd) != 3 &&
- sscanf(argv[i], "%2d%2d%4d", &mm, &dd, &yyyy) != 3) ||
- mm < 1 || mm > 12 || dd < 1 || dd > 31) {
- ZIPERR(ZE_PARMS, (cmptime == &after ?
- "invalid date entered for -tt option" :
- "invalid date entered for -t option"));
- }
- *cmptime = dostime(yyyy, mm, dd, 0, 0, 0);
- k = (zipfile != NULL ? (first_listarg > 0 ? 4 : 3) : 0);
+ case o_OPTIONAL_VALUE:
+ printf("%-4s ", "opt");
break;
- }
- case 3: case 4:
- if ((r = PROCNAME(argv[i])) != ZE_OK) {
- if (r == ZE_MISS)
- zipwarn("name not matched: ", argv[i]);
- else {
- ZIPERR(r, argv[i]);
- }
- }
- if (k == 3) {
- first_listarg = i;
- k = 4;
- }
+ case o_VALUE_LIST:
+ printf("%-4s ", "list");
break;
- case 7:
- if ((key = malloc(strlen(argv[i]) + 1)) == NULL) {
- ZIPERR(ZE_MEM, "was processing arguments");
- }
- strcpy(key, argv[i]);
- k = (zipfile != NULL ? (first_listarg > 0 ? 4 : 3) : 0);
+ case o_ONE_CHAR_VALUE:
+ printf("%-4s ", "char");
+ break;
+ case o_NUMBER_VALUE:
+ printf("%-4s ", "num");
+ break;
+ default:
+ printf("%-4s ", "unk");
+ }
+ switch (options[i].negatable) {
+ case o_NEGATABLE:
+ printf("%-3s ", "neg");
+ break;
+ case o_NOT_NEGATABLE:
+ printf("%-3s ", "");
+ break;
+ default:
+ printf("%-3s ", "unk");
+ }
+ if (options[i].name)
+ printf("%-30s\n", options[i].name);
+ else
+ printf("\n");
+ }
+ RETURN(finish(ZE_OK));
+ }
+
+
+ /* open log file */
+ if (logfile_path) {
+ char mode[10];
+ char *p;
+ char *lastp;
+
+ /* if no extension add .log */
+ p = logfile_path;
+ /* find last / */
+ lastp = NULL;
+ for (p = logfile_path; (p = MBSRCHR(p, '/')) != NULL; p++) {
+ lastp = p;
+ }
+ if (lastp == NULL)
+ lastp = logfile_path;
+ if (MBSRCHR(lastp, '.') == NULL) {
+ /* add .log */
+ if ((p = malloc(strlen(logfile_path) + 5)) == NULL) {
+ ZIPERR(ZE_MEM, "logpath");
}
+ strcpy(p, logfile_path);
+ strcat(p, ".log");
+ free(logfile_path);
+ logfile_path = p;
+ }
+
+ if (logfile_append) {
+ sprintf(mode, "a");
+ } else {
+ sprintf(mode, "w");
+ }
+ if ((logfile = zfopen(logfile_path, mode)) == NULL) {
+ sprintf(errbuf, "could not open logfile '%s'", logfile_path);
+ ZIPERR(ZE_PARMS, errbuf);
}
- if ((k == 3 || k == 6) && (s))
{
- while ((pp = getnam(errbuf, stdin)) != NULL)
- {
- first_listarg = i + 1;
- k = 4;
- if ((r = PROCNAME(pp)) != ZE_OK) {
- if (r == ZE_MISS)
- zipwarn("name not matched: ", pp);
- else {
- ZIPERR(r, pp);
+ /* At top put start time and command line */
+
+ /* get current time */
+ struct tm *now;
+ time_t clocktime;
+
+ time(&clocktime);
+ now = localtime(&clocktime);
+
+ fprintf(logfile, "---------\n");
+ fprintf(logfile, "Zip log opened %s", asctime(now));
+ fprintf(logfile, "command line arguments:\n ");
+ for (i = 1; args[i]; i++) {
+ size_t j;
+ int has_space = 0;
+
+ for (j = 0; j < strlen(args[i]); j++) {
+ if (isspace(args[i][j])) {
+ has_space = 1;
+ break;
}
}
+ if (has_space)
+ fprintf(logfile, "\"%s\" ", args[i]);
+ else
+ fprintf(logfile, "%s ", args[i]);
}
- s = 0;
- if (recurse == 2) k = 6;
+ fprintf(logfile, "\n\n");
+ fflush(logfile);
}
-nextarg: ;
+ } else {
+ /* only set logall if logfile open */
+ logall = 0;
+ }
+
+
+ if (split_method && out_path) {
+ /* if splitting, the archive name must have .zip extension */
+ int plen = strlen(out_path);
+ char *out_path_ext;
+
+#ifdef VMS
+ /* On VMS, adjust plen (and out_path_ext) to avoid the file version. */
+ plen -= strlen( vms_file_version( out_path));
+#endif /* def VMS */
+ out_path_ext = out_path+ plen- 4;
+
+ if (plen < 4 ||
+ out_path_ext[0] != '.' ||
+ toupper(out_path_ext[1]) != 'Z' ||
+ toupper(out_path_ext[2]) != 'I' ||
+ toupper(out_path_ext[3]) != 'P') {
+ ZIPERR(ZE_PARMS, "archive name must end in .zip for splits");
+ }
+ }
+
+
+ if (verbose && (dot_size == 0) && (dot_count == 0)) {
+ /* now default to default 10 MB dot size */
+ dot_size = 10 * 0x100000;
+ /* show all dots as before if verbose set and dot_size not set (dot_count = 0) */
+ /* maybe should turn off dots in default verbose mode */
+ /* dot_size = -1; */
}
- if (k == 7 || k == 1) {
- ZIPERR(ZE_PARMS, "missing argument for -b or -P");
+
+ /* done getting -R filters so convert filterlist if not done */
+ if (pcount && patterns == NULL) {
+ filterlist_to_patterns();
}
#if (defined(MSDOS) || defined(OS2)) && !defined(WIN32)
- if ((k == 3 || k == 4) && volume_label == 1) {
+ if ((kk == 3 || kk == 4) && volume_label == 1) {
+ /* read volume label */
PROCNAME(NULL);
- k = 4;
+ kk = 4;
}
#endif
- if (pcount && first_listarg == 0 &&
- (k < 3 || (action != UPDATE && action != FRESHEN))) {
+ if (have_out && kk == 3) {
+ copy_only = 1;
+ action = ARCHIVE;
+ }
+
+ if (have_out && namecmp(in_path, out_path) == 0) {
+ sprintf(errbuf, "--out path must be different than in path: %s", out_path);
+ ZIPERR(ZE_PARMS, errbuf);
+ }
+
+ if (fix && diff_mode) {
+ ZIPERR(ZE_PARMS, "can't use --diff (-DF) with fix (-F or -FF)");
+ }
+
+ if (action == ARCHIVE && !have_out && !show_files) {
+ ZIPERR(ZE_PARMS, "-U (--copy) requires -O (--out)");
+ }
+
+ if (fix && !have_out) {
+ zipwarn("fix options -F and -FF require --out:\n",
+ " zip -F indamagedarchive --out outfixedarchive");
+ ZIPERR(ZE_PARMS, "fix options require --out");
+ }
+
+ if (fix && !copy_only) {
+ ZIPERR(ZE_PARMS, "no other actions allowed when fixing archive (-F or -FF)");
+ }
+
+ if (!have_out && diff_mode) {
+ ZIPERR(ZE_PARMS, "-DF (--diff) requires -O (--out)");
+ }
+
+ if (diff_mode && (action == ARCHIVE || action == DELETE)) {
+ ZIPERR(ZE_PARMS, "can't use --diff (-DF) with -d or -U");
+ }
+
+ if (action != ARCHIVE && (recurse == 2 || pcount) && first_listarg == 0 &&
+ !filelist && (kk < 3 || (action != UPDATE && action != FRESHEN))) {
ZIPERR(ZE_PARMS, "nothing to select from");
}
+/*
+ -------------------------------------
+ end of new command line code
+ -------------------------------------
+*/
+
#if (!defined(MACOS) && !defined(WINDLL))
- if (k < 3) { /* zip used as filter */
+ if (kk < 3) { /* zip used as filter */
zipstdout();
comment_stream = NULL;
if ((r = procname("-", 0)) != ZE_OK) {
- if (r == ZE_MISS)
- zipwarn("name not matched: ", "-");
- else {
+ if (r == ZE_MISS) {
+ if (bad_open_is_error) {
+ zipwarn("name not matched: ", "-");
+ ZIPERR(ZE_OPEN, "-");
+ } else {
+ zipwarn("name not matched: ", "-");
+ }
+ } else {
ZIPERR(r, "-");
}
}
- k = 4;
+ kk = 4;
if (s) {
ZIPERR(ZE_PARMS, "can't use - and -@ together");
}
}
#endif /* !MACOS && !WINDLL */
- /* Clean up selections ("3 <= k <= 5" now) */
- if (k != 4 && first_listarg == 0 &&
- (action == UPDATE || action == FRESHEN)) {
- /* if -u or -f with no args, do all, but, when present, apply filters */
- for (z = zfiles; z != NULL; z = z->nxt) {
- z->mark = pcount ? filter(z->zname, 0) : 1;
-#ifdef DOS
- if (z->mark) z->dosflag = 1; /* force DOS attribs for incl. names */
-#endif
- }
- }
- if ((r = check_dup()) != ZE_OK) { /* remove duplicates in found list */
- if (r == ZE_PARMS) {
- ZIPERR(r, "cannot repeat names in zip file");
- }
- else {
- ZIPERR(r, "was processing list of files");
+ if (zipfile && !strcmp(zipfile, "-")) {
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Zipping to stdout\n");
+ fflush(mesg);
}
+ zip_to_stdout = 1;
}
- if (zcount)
- free((zvoid *)zsort);
-
/* Check option combinations */
if (special == NULL) {
ZIPERR(ZE_PARMS, "missing suffix list");
@@ -1581,21 +3762,46 @@ nextarg: ;
comadd = 0;
zipedit = 0;
}
+ if (action == ARCHIVE && (method != BEST || dispose || recurse ||
+ comadd || zipedit)) {
+ zipwarn("can't set method, move, recurse, or comments with copy mode.","");
+ /* reset flags - needed? */
+ method = BEST;
+ dispose = 0;
+ recurse = 0;
+ comadd = 0;
+ zipedit = 0;
+ }
if (linkput && dosify)
{
zipwarn("can't use -y with -k, -y ignored", "");
linkput = 0;
}
- if (fix && adjust)
+ if (fix == 1 && adjust)
{
zipwarn("can't use -F with -A, -F ignored", "");
+ fix = 0;
}
- if (test && !strcmp(zipfile, "-")) {
+ if (fix == 2 && adjust)
+ {
+ zipwarn("can't use -FF with -A, -FF ignored", "");
+ fix = 0;
+ }
+ if (test && zip_to_stdout) {
test = 0;
zipwarn("can't use -T on stdout, -T ignored", "");
}
- if ((action != ADD || d) && !strcmp(zipfile, "-")) {
- ZIPERR(ZE_PARMS, "can't use -d,-f,-u or -g on stdout\n");
+ if (split_method && (fix || adjust)) {
+ ZIPERR(ZE_PARMS, "can't create split archive while fixing or adjusting\n");
+ }
+ if (split_method && (d || zip_to_stdout)) {
+ ZIPERR(ZE_PARMS, "can't create split archive with -d or -g or on stdout\n");
+ }
+ if ((action != ADD || d) && filesync) {
+ ZIPERR(ZE_PARMS, "can't use -d, -f, -u, -U, or -g with filesync -FS\n");
+ }
+ if ((action != ADD || d) && zip_to_stdout) {
+ ZIPERR(ZE_PARMS, "can't use -d, -f, -u, -U, or -g on stdout\n");
}
#if defined(EBCDIC) && !defined(OS390)
if (aflag==ASCII && !translate_eol) {
@@ -1619,10 +3825,359 @@ nextarg: ;
if (vms_native && translate_eol)
ZIPERR(ZE_PARMS, "can't use -V with -l or -ll");
#endif
+
+ if (noisy) {
+ if (fix == 1)
+ zipmessage("Fix archive (-F) - assume mostly intact archive", "");
+ else if (fix == 2)
+ zipmessage("Fix archive (-FF) - salvage what can", "");
+ }
+
+ /* Read old archive */
+
+ /* Now read the zip file here instead of when doing args above */
+ /* Only read the central directory and build zlist */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Reading archive\n");
+ fflush(mesg);
+ }
+
+
+
+
+ /* If -FF we do it all here */
+ if (fix == 2) {
+
+ /* Open zip file and temporary output file */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Open zip file and create temp file (-FF)\n");
+ fflush(mesg);
+ }
+ diag("opening zip file and creating temporary zip file");
+ x = NULL;
+ tempzn = 0;
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Creating new zip file (-FF)\n");
+ fflush(mesg);
+ }
+#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
+
+#if (!defined(VMS) && !defined(CMS_MVS))
+ /* Use large buffer to speed up stdio: */
+#if (defined(_IOFBF) || !defined(BUFSIZ))
+ zipbuf = (char *)malloc(ZBSZ);
+#else
+ zipbuf = (char *)malloc(BUFSIZ);
+#endif
+ if (zipbuf == NULL) {
+ ZIPERR(ZE_MEM, tempzip);
+ }
+# ifdef _IOFBF
+ setvbuf(y, zipbuf, _IOFBF, ZBSZ);
+# else
+ setbuf(y, zipbuf);
+# endif /* _IOBUF */
+#endif /* !VMS && !CMS_MVS */
+
+
+ if ((r = readzipfile()) != ZE_OK) {
+ ZIPERR(r, zipfile);
+ }
+
+ /* Write central directory and end header to temporary zip */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Writing central directory (-FF)\n");
+ fflush(mesg);
+ }
+ diag("writing central directory");
+ k = 0; /* keep count for end header */
+ c = tempzn; /* get start of central */
+ n = t = 0;
+ for (z = zfiles; z != NULL; z = z->nxt)
+ {
+ if ((r = putcentral(z)) != ZE_OK) {
+ ZIPERR(r, tempzip);
+ }
+ tempzn += 4 + CENHEAD + z->nam + z->cext + z->com;
+ n += z->len;
+ t += z->siz;
+ k++;
+ }
+ if (zcount == 0)
+ zipwarn("zip file empty", "");
+ t = tempzn - c; /* compute length of central */
+ diag("writing end of central directory");
+ if ((r = putend(k, t, c, zcomlen, zcomment)) != ZE_OK) {
+ ZIPERR(r, tempzip);
+ }
+ if (fclose(y)) {
+ ZIPERR(d ? ZE_WRITE : ZE_TEMP, tempzip);
+ }
+ if (in_file != NULL) {
+ fclose(in_file);
+ in_file = NULL;
+ }
+
+ /* Replace old zip file with new zip file, leaving only the new one */
+ if (strcmp(zipfile, "-") && !d)
+ {
+ diag("replacing old zip file with new zip file");
+ if ((r = replace(out_path, tempzip)) != ZE_OK)
+ {
+ zipwarn("new zip file left as: ", tempzip);
+ free((zvoid *)tempzip);
+ tempzip = NULL;
+ ZIPERR(r, "was replacing the original zip file");
+ }
+ free((zvoid *)tempzip);
+ }
+ tempzip = NULL;
+ if (zip_attributes && strcmp(zipfile, "-")) {
+ setfileattr(out_path, zip_attributes);
+#ifdef VMS
+ /* If the zip file existed previously, restore its record format: */
+ if (x != NULL)
+ (void)VMSmunch(out_path, RESTORE_RTYPE, NULL);
+#endif
+ }
+
+ set_filetype(out_path);
+
+ /* finish logfile (it gets closed in freeup() called by finish()) */
+ if (logfile) {
+ struct tm *now;
+ time_t clocktime;
+
+ fprintf(logfile, "\nTotal %ld entries (", files_total);
+ DisplayNumString(logfile, bytes_total);
+ fprintf(logfile, " bytes)");
+
+ /* get current time */
+ time(&clocktime);
+ now = localtime(&clocktime);
+ fprintf(logfile, "\nDone %s", asctime(now));
+ fflush(logfile);
+ }
+
+ RETURN(finish(ZE_OK));
+ }
+
+
+
+ /* read zipfile if exists */
+ if ((r = readzipfile()) != ZE_OK) {
+ ZIPERR(r, zipfile);
+ }
+
+#ifndef UTIL
+ if (split_method == -1) {
+ split_method = 0;
+ } else if (!fix && split_method == 0 && total_disks > 1) {
+ /* if input archive is multi-disk and splitting has not been
+ enabled or disabled (split_method == -1), then automatically
+ set split size to same as first input split */
+ zoff_t size = 0;
+
+ in_split_path = get_in_split_path(in_path, 0);
+
+ if (filetime(in_split_path, NULL, &size, NULL) == 0) {
+ zipwarn("Could not get info for input split: ", in_split_path);
+ return ZE_OPEN;
+ }
+ split_method = 1;
+ split_size = (uzoff_t) size;
+
+ free(in_split_path);
+ in_split_path = NULL;
+ }
+
+ if (noisy_splits && split_size > 0)
+ zipmessage("splitsize = ", zip_fuzofft(split_size, NULL, NULL));
+#endif
+
+ /* so disk display starts at 1, will be updated when entries are read */
+ current_in_disk = 0;
+
+ /* no input zipfile and showing contents */
+ if (!zipfile_exists && show_files && (kk == 3 || action == ARCHIVE)) {
+ ZIPERR(ZE_OPEN, zipfile);
+ }
+
if (zcount == 0 && (action != ADD || d)) {
zipwarn(zipfile, " not found or empty");
}
+ if (have_out && kk == 3) {
+ /* no input paths so assume copy mode and match everything if --out */
+ for (z = zfiles; z != NULL; z = z->nxt) {
+ z->mark = pcount ? filter(z->zname, filter_match_case) : 1;
+ }
+ }
+
+ /* Scan for new files */
+
+ /* Process file arguments from command line */
+ if (filelist) {
+ if (action == ARCHIVE) {
+ /* find in archive */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Scanning archive entries\n");
+ fflush(mesg);
+ }
+ for (; filelist; ) {
+ if ((r = proc_archive_name(filelist->name, filter_match_case)) != ZE_OK) {
+ if (r == ZE_MISS) {
+ char *n = NULL;
+#ifdef WIN32
+ /* Win9x console always uses OEM character coding, and
+ WinNT console is set to OEM charset by default, too */
+ if ((n = malloc(strlen(filelist->name) + 1)) == NULL)
+ ZIPERR(ZE_MEM, "name not matched error");
+ INTERN_TO_OEM(filelist->name, n);
+#else
+ n = filelist->name;
+#endif
+ zipwarn("not in archive: ", n);
+#ifdef WIN32
+ free(n);
+#endif
+ }
+ else {
+ ZIPERR(r, filelist->name);
+ }
+ }
+ free(filelist->name);
+ filearg = filelist;
+ filelist = filelist->next;
+ free(filearg);
+ }
+ } else {
+ /* try find matching files on OS first then try find entries in archive */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Scanning files\n");
+ fflush(mesg);
+ }
+ for (; filelist; ) {
+ if ((r = PROCNAME(filelist->name)) != ZE_OK) {
+ if (r == ZE_MISS) {
+ if (bad_open_is_error) {
+ zipwarn("name not matched: ", filelist->name);
+ ZIPERR(ZE_OPEN, filelist->name);
+ } else {
+ zipwarn("name not matched: ", filelist->name);
+ }
+ } else {
+ ZIPERR(r, filelist->name);
+ }
+ }
+ free(filelist->name);
+ filearg = filelist;
+ filelist = filelist->next;
+ free(filearg);
+ }
+ }
+ }
+
+ /* recurse from current directory for -R */
+ if (recurse == 2) {
+#ifdef AMIGA
+ if ((r = PROCNAME("")) != ZE_OK)
+#else
+ if ((r = PROCNAME(".")) != ZE_OK)
+#endif
+ {
+ if (r == ZE_MISS) {
+ if (bad_open_is_error) {
+ zipwarn("name not matched: ", "current directory for -R");
+ ZIPERR(ZE_OPEN, "-R");
+ } else {
+ zipwarn("name not matched: ", "current directory for -R");
+ }
+ } else {
+ ZIPERR(r, "-R");
+ }
+ }
+ }
+
+
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Applying filters\n");
+ fflush(mesg);
+ }
+ /* Clean up selections ("3 <= kk <= 5" now) */
+ if (kk != 4 && first_listarg == 0 &&
+ (action == UPDATE || action == FRESHEN)) {
+ /* if -u or -f with no args, do all, but, when present, apply filters */
+ for (z = zfiles; z != NULL; z = z->nxt) {
+ z->mark = pcount ? filter(z->zname, filter_match_case) : 1;
+#ifdef DOS
+ if (z->mark) z->dosflag = 1; /* force DOS attribs for incl. names */
+#endif
+ }
+ }
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Checking dups\n");
+ fflush(mesg);
+ }
+ if ((r = check_dup()) != ZE_OK) { /* remove duplicates in found list */
+ if (r == ZE_PARMS) {
+ ZIPERR(r, "cannot repeat names in zip file");
+ }
+ else {
+ ZIPERR(r, "was processing list of files");
+ }
+ }
+
+ if (zcount)
+ free((zvoid *)zsort);
+
+
/*
* XXX make some kind of mktemppath() function for each OS.
*/
@@ -1653,7 +4208,7 @@ nextarg: ;
#endif /* QDOS */
#endif /* RISCOS */
#endif /* MSDOS || __human68k__ || AMIGA */
- if ((tempath = malloc((int)(p - zipfile) + 1)) == NULL) {
+ if ((tempath = (char *)malloc((int)(p - zipfile) + 1)) == NULL) {
ZIPERR(ZE_MEM, "was processing arguments");
}
r = *p; *p = 0;
@@ -1663,7 +4218,7 @@ nextarg: ;
#endif /* VM_CMS */
#if (defined(IZ_CHECK_TZ) && defined(USE_EF_UT_TIME))
- if (!zp_tz_is_valid && action != DELETE) {
+ if (!zp_tz_is_valid) {
zipwarn("TZ environment variable not found, cannot use UTC times!!","");
}
#endif /* IZ_CHECK_TZ && USE_EF_UT_TIME */
@@ -1671,67 +4226,472 @@ nextarg: ;
/* For each marked entry, if not deleting, check if it exists, and if
updating or freshening, compare date with entry in old zip file.
Unmark if it doesn't exist or is too old, else update marked count. */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Scanning files to update\n");
+ fflush(mesg);
+ }
#ifdef MACOS
PrintStatProgress("Getting file information ...");
#endif
diag("stating marked entries");
k = 0; /* Initialize marked count */
- for (z = zfiles; z != NULL; z = z->nxt)
+ scan_started = 0;
+ scan_count = 0;
+ all_current = 1;
+ for (z = zfiles; z != NULL; z = z->nxt) {
+ /* if already displayed Scanning files in newname() then continue dots */
+ if (noisy && scan_last) {
+ scan_count++;
+ if (scan_count % 100 == 0) {
+ time_t current = time(NULL);
+
+ if (current - scan_last > scan_dot_time) {
+ if (scan_started == 0) {
+ scan_started = 1;
+ fprintf(mesg, " ");
+ fflush(mesg);
+ }
+ scan_last = current;
+ fprintf(mesg, ".");
+ fflush(mesg);
+ }
+ }
+ }
+ z->current = 0;
+ if (!(z->mark)) {
+ /* if something excluded run through the list to catch deletions */
+ all_current = 0;
+ }
if (z->mark) {
#ifdef USE_EF_UT_TIME
iztimes f_utim, z_utim;
+ ulg z_tim;
#endif /* USE_EF_UT_TIME */
- Trace((stderr, "zip diagnostics: marked file=%s\n", z->zname));
+ Trace((stderr, "zip diagnostics: marked file=%s\n", z->oname));
- if (action != DELETE &&
+ csize = z->siz;
+ usize = z->len;
+ if (action == DELETE) {
+ /* only delete files in date range */
#ifdef USE_EF_UT_TIME
- ((t = filetime(z->name, (ulg *)NULL, (long *)NULL, &f_utim))
+ z_tim = (get_ef_ut_ztime(z, &z_utim) & EB_UT_FL_MTIME) ?
+ unix2dostime(&z_utim.mtime) : z->tim;
#else /* !USE_EF_UT_TIME */
- ((t = filetime(z->name, (ulg *)NULL, (long *)NULL, (iztimes *)NULL))
+# define z_tim z->tim
#endif /* ?USE_EF_UT_TIME */
- == 0 ||
- t < before || (after && t >= after) ||
- ((action == UPDATE || action == FRESHEN) &&
+ if (z_tim < before || (after && z_tim >= after)) {
+ /* include in archive */
+ z->mark = 0;
+ } else {
+ /* delete file */
+ files_total++;
+ /* ignore len in old archive and update to current size */
+ z->len = usize;
+ if (csize != (uzoff_t) -1 && csize != (uzoff_t) -2)
+ bytes_total += csize;
+ k++;
+ }
+ } else if (action == ARCHIVE) {
+ /* only keep files in date range */
#ifdef USE_EF_UT_TIME
- ((get_ef_ut_ztime(z, &z_utim) & EB_UT_FL_MTIME) ?
- f_utim.mtime <= ROUNDED_TIME(z_utim.mtime) : t <= z->tim)
+ z_tim = (get_ef_ut_ztime(z, &z_utim) & EB_UT_FL_MTIME) ?
+ unix2dostime(&z_utim.mtime) : z->tim;
#else /* !USE_EF_UT_TIME */
- t <= z->tim
+# define z_tim z->tim
#endif /* ?USE_EF_UT_TIME */
- )))
- {
- z->mark = comadd ? 2 : 0;
- z->trash = t && t >= before &&
- (after == 0 || t < after); /* delete if -um or -fm */
- if (verbose) {
- fprintf(mesg, "zip diagnostic: %s %s\n", z->zname,
- z->trash ? "up to date" : "missing or early");
+ if (z_tim < before || (after && z_tim >= after)) {
+ /* exclude from archive */
+ z->mark = 0;
+ } else {
+ /* keep file */
+ files_total++;
+ /* ignore len in old archive and update to current size */
+ z->len = usize;
+ if (csize != (uzoff_t) -1 && csize != (uzoff_t) -2)
+ bytes_total += csize;
+ k++;
+ }
+ } else {
+ int isdirname = 0;
+
+ if (z->name && (z->name)[strlen(z->name) - 1] == '/') {
+ isdirname = 1;
+ }
+
+# if defined(UNICODE_SUPPORT) && defined(WIN32)
+ if (!no_win32_wide) {
+ if (z->namew == NULL) {
+ if (z->uname != NULL)
+ z->namew = utf8_to_wchar_string(z->uname);
+ else
+ z->namew = local_to_wchar_string(z->name);
+ }
+ }
+# endif
+
+#ifdef USE_EF_UT_TIME
+# if defined(UNICODE_SUPPORT) && defined(WIN32)
+ if (!no_win32_wide)
+ tf = filetimew(z->namew, (ulg *)NULL, (zoff_t *)&usize, &f_utim);
+ else
+ tf = filetime(z->name, (ulg *)NULL, (zoff_t *)&usize, &f_utim);
+# else
+ tf = filetime(z->name, (ulg *)NULL, (zoff_t *)&usize, &f_utim);
+# endif
+#else /* !USE_EF_UT_TIME */
+# if defined(UNICODE_SUPPORT) && defined(WIN32)
+ if (!no_win32_wide)
+ tf = filetimew(z->namew, (ulg *)NULL, (zoff_t *)&usize, NULL);
+ else
+ tf = filetime(z->name, (ulg *)NULL, (zoff_t *)&usize, NULL);
+# else
+ tf = filetime(z->name, (ulg *)NULL, (zoff_t *)&usize, NULL);
+# endif
+#endif /* ?USE_EF_UT_TIME */
+ if (tf == 0)
+ /* entry that is not on OS */
+ all_current = 0;
+ if (tf == 0 ||
+ tf < before || (after && tf >= after) ||
+ ((action == UPDATE || action == FRESHEN) &&
+#ifdef USE_EF_UT_TIME
+ ((get_ef_ut_ztime(z, &z_utim) & EB_UT_FL_MTIME) ?
+ f_utim.mtime <= ROUNDED_TIME(z_utim.mtime) : tf <= z->tim)
+#else /* !USE_EF_UT_TIME */
+ tf <= z->tim
+#endif /* ?USE_EF_UT_TIME */
+ ))
+ {
+ z->mark = comadd ? 2 : 0;
+ z->trash = tf && tf >= before &&
+ (after ==0 || tf < after); /* delete if -um or -fm */
+ if (verbose)
+ fprintf(mesg, "zip diagnostic: %s %s\n", z->oname,
+ z->trash ? "up to date" : "missing or early");
+ if (logfile)
+ fprintf(logfile, "zip diagnostic: %s %s\n", z->oname,
+ z->trash ? "up to date" : "missing or early");
+ }
+ else if (diff_mode && tf == z->tim &&
+ ((isdirname && (zoff_t)usize == -1) || (usize == z->len))) {
+ /* if in diff mode only include if file time or size changed */
+ /* usize is -1 for directories */
+ z->mark = 0;
+ }
+ else {
+ /* usize is -1 for directories and -2 for devices */
+ if (tf == z->tim &&
+ ((z->len == 0 && (zoff_t)usize == -1)
+ || usize == z->len)) {
+ /* FileSync uses the current flag */
+ /* Consider an entry current if file time is the same
+ and entry size is 0 and a directory on the OS
+ or the entry size matches the OS size */
+ z->current = 1;
+ } else {
+ all_current = 0;
+ }
+ files_total++;
+ if (usize != (uzoff_t) -1 && usize != (uzoff_t) -2)
+ /* ignore len in old archive and update to current size */
+ z->len = usize;
+ else
+ z->len = 0;
+ if (usize != (uzoff_t) -1 && usize != (uzoff_t) -2)
+ bytes_total += usize;
+ k++;
}
}
- else
- k++;
}
+ }
/* Remove entries from found list that do not exist or are too old */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: fcount = %u\n", (unsigned)fcount);
+ fflush(mesg);
+ }
+
diag("stating new entries");
+ scan_count = 0;
+ scan_started = 0;
Trace((stderr, "zip diagnostic: fcount=%u\n", (unsigned)fcount));
for (f = found; f != NULL;) {
- Trace((stderr, "zip diagnostic: new file=%s\n", f->zname));
+ Trace((stderr, "zip diagnostic: new file=%s\n", f->oname));
+
+ if (noisy) {
+ /* if updating archive and update was quick, scanning for new files
+ can still take a long time */
+ if (!zip_to_stdout && scan_last == 0 && scan_count % 100 == 0) {
+ time_t current = time(NULL);
+
+ if (current - scan_start > scan_delay) {
+ fprintf(mesg, "Scanning files ");
+ fflush(mesg);
+ mesg_line_started = 1;
+ scan_last = current;
+ }
+ }
+ /* if already displayed Scanning files in newname() or above then continue dots */
+ if (scan_last) {
+ scan_count++;
+ if (scan_count % 100 == 0) {
+ time_t current = time(NULL);
+
+ if (current - scan_last > scan_dot_time) {
+ if (scan_started == 0) {
+ scan_started = 1;
+ fprintf(mesg, " ");
+ fflush(mesg);
+ }
+ scan_last = current;
+ fprintf(mesg, ".");
+ fflush(mesg);
+ }
+ }
+ }
+ }
+ tf = 0;
+ if (action != DELETE && action != FRESHEN) {
+#if defined(UNICODE_SUPPORT) && defined(WIN32)
+ if (!no_win32_wide)
+ tf = filetimew(f->namew, (ulg *)NULL, (zoff_t *)&usize, NULL);
+ else
+ tf = filetime(f->name, (ulg *)NULL, (zoff_t *)&usize, NULL);
+#else
+ tf = filetime(f->name, (ulg *)NULL, (zoff_t *)&usize, NULL);
+#endif
+ }
+
if (action == DELETE || action == FRESHEN ||
- (t = filetime(f->name, (ulg *)NULL, (long *)NULL, (iztimes *)NULL))
- == 0 ||
- t < before || (after && t >= after) ||
- (namecmp(f->zname, zipfile) == 0 && strcmp(zipfile, "-")))
+ tf == 0 ||
+ tf < before || (after && tf >= after) ||
+ (namecmp(f->zname, zipfile) == 0 && !zip_to_stdout)
+ )
f = fexpel(f);
- else
+ else {
+ /* ??? */
+ files_total++;
+ f->usize = 0;
+ if (usize != (uzoff_t) -1 && usize != (uzoff_t) -2) {
+ bytes_total += usize;
+ f->usize = usize;
+ }
f = f->nxt;
+ }
+ }
+ if (mesg_line_started) {
+ fprintf(mesg, "\n");
+ mesg_line_started = 0;
}
#ifdef MACOS
PrintStatProgress("done");
#endif
+ if (show_files) {
+ uzoff_t count = 0;
+ uzoff_t bytes = 0;
+
+ if (noisy) {
+ fflush(mesg);
+ }
+
+ if (noisy && (show_files == 1 || show_files == 3 || show_files == 5)) {
+ /* sf, su, sU */
+ if (mesg_line_started) {
+ fprintf(mesg, "\n");
+ mesg_line_started = 0;
+ }
+ if (kk == 3)
+ /* -sf alone */
+ fprintf(mesg, "Archive contains:\n");
+ else if (action == DELETE)
+ fprintf(mesg, "Would Delete:\n");
+ else if (action == FRESHEN)
+ fprintf(mesg, "Would Freshen:\n");
+ else if (action == ARCHIVE)
+ fprintf(mesg, "Would Copy:\n");
+ else
+ fprintf(mesg, "Would Add/Update:\n");
+ fflush(mesg);
+ }
+
+ if (logfile) {
+ if (logfile_line_started) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ }
+ if (kk == 3)
+ /* -sf alone */
+ fprintf(logfile, "Archive contains:\n");
+ else if (action == DELETE)
+ fprintf(logfile, "Would Delete:\n");
+ else if (action == FRESHEN)
+ fprintf(logfile, "Would Freshen:\n");
+ else if (action == ARCHIVE)
+ fprintf(logfile, "Would Copy:\n");
+ else
+ fprintf(logfile, "Would Add/Update:\n");
+ fflush(logfile);
+ }
+
+ for (z = zfiles; z != NULL; z = z->nxt) {
+ if (z->mark || kk == 3) {
+ count++;
+ if ((zoff_t)z->len > 0)
+ bytes += z->len;
+ if (noisy && (show_files == 1 || show_files == 3))
+ /* sf, su */
+ fprintf(mesg, " %s\n", z->oname);
+ if (logfile && !(show_files == 5 || show_files == 6))
+ /* not sU or sU- show normal name in log */
+ fprintf(logfile, " %s\n", z->oname);
+
+#ifdef UNICODE_TEST
+ if (create_files) {
+ int r;
+ int dir = 0;
+ FILE *f;
+
+#if defined(UNICODE_SUPPORT) && defined(WIN32)
+ char *fn = NULL;
+ wchar_t *fnw = NULL;
+
+ if (!no_win32_wide) {
+ if ((fnw = malloc((wcslen(z->znamew) + 120) * sizeof(wchar_t))) == NULL)
+ ZIPERR(ZE_MEM, "sC");
+ wcscpy(fnw, L"testdir/");
+ wcscat(fnw, z->znamew);
+ if (fnw[wcslen(fnw) - 1] == '/')
+ dir = 1;
+ if (dir)
+ r = _wmkdir(fnw);
+ else
+ f = _wfopen(fnw, L"w");
+ } else {
+ if ((fn = malloc(strlen(z->zname) + 120)) == NULL)
+ ZIPERR(ZE_MEM, "sC");
+ strcpy(fn, "testdir/");
+ strcat(fn, z->zname);
+ if (fn[strlen(fn) - 1] == '/')
+ dir = 1;
+ if (dir)
+ r = mkdir(fn);
+ else
+ f = fopen(fn, "w");
+ }
+#else
+ char *fn = NULL;
+ if ((fn = malloc(strlen(z->zname) + 120)) == NULL)
+ ZIPERR(ZE_MEM, "sC");
+ strcpy(fn, "testdir/");
+ if (z->uname)
+ strcat(fn, z->uname);
+ else
+ strcat(fn, z->zname);
+
+ if (fn[strlen(fn) - 1] == '/')
+ dir = 1;
+ if (dir)
+ r = mkdir(fn, 0777);
+ else
+ f = fopen(fn, "w");
+#endif
+ if (dir) {
+ if (r) {
+ if (errno != 17) {
+ printf(" - could not create directory testdir/%s\n", z->oname);
+ perror(" dir");
+ }
+ } else {
+ printf(" - created directory testdir/%s\n", z->oname);
+ }
+ } else {
+ if (f == NULL) {
+ printf(" - could not open testdir/%s\n", z->oname);
+ perror(" file");
+ } else {
+ fclose(f);
+ printf(" - created testdir/%s\n", z->oname);
+ if (z->uname)
+ printf(" u - created testdir/%s\n", z->uname);
+ }
+ }
+ }
+#endif
+#ifdef UNICODE_SUPPORT
+ if (show_files == 3 || show_files == 4) {
+ /* su, su- */
+ /* Include escaped Unicode name if exists under standard name */
+ if (z->ouname) {
+ if (noisy && show_files == 3)
+ fprintf(mesg, " Escaped Unicode: %s\n", z->ouname);
+ if (logfile)
+ fprintf(logfile, " Escaped Unicode: %s\n", z->ouname);
+ }
+ }
+ if (show_files == 5 || show_files == 6) {
+ /* sU, sU- */
+ /* Display only escaped Unicode name if exists or standard name */
+ if (z->ouname) {
+ /* Unicode name */
+ if (noisy && show_files == 5) {
+ fprintf(mesg, " %s\n", z->ouname);
+ }
+ if (logfile) {
+ fprintf(logfile, " %s\n", z->ouname);
+ }
+ } else {
+ /* No Unicode name so use standard name */
+ if (noisy && show_files == 5) {
+ fprintf(mesg, " %s\n", z->oname);
+ }
+ if (logfile) {
+ fprintf(logfile, " %s\n", z->oname);
+ }
+ }
+ }
+#endif
+ }
+ }
+ for (f = found; f != NULL; f = f->nxt) {
+ count++;
+ if ((zoff_t)f->usize > 0)
+ bytes += f->usize;
+#ifdef UNICODE_SUPPORT
+ if (unicode_escape_all) {
+ char *escaped_unicode;
+ escaped_unicode = local_to_escape_string(f->zname);
+ if (noisy && (show_files == 1 || show_files == 3 || show_files == 5))
+ /* sf, su, sU */
+ fprintf(mesg, " %s\n", escaped_unicode);
+ if (logfile)
+ fprintf(logfile, " %s\n", escaped_unicode);
+ free(escaped_unicode);
+ } else {
+#endif
+ if (noisy && (show_files == 1 || show_files == 3 || show_files == 5))
+ /* sf, su, sU */
+ fprintf(mesg, " %s\n", f->oname);
+ if (logfile)
+ fprintf(logfile, " %s\n", f->oname);
+#ifdef UNICODE_SUPPORT
+ }
+#endif
+ }
+ if (noisy || logfile == NULL)
+ fprintf(mesg, "Total %s entries (%s bytes)\n",
+ zip_fuzofft(count, NULL, NULL),
+ zip_fuzofft(bytes, NULL, NULL));
+ if (logfile)
+ fprintf(logfile, "Total %s entries (%s bytes)\n",
+ zip_fuzofft(count, NULL, NULL),
+ zip_fuzofft(bytes, NULL, NULL));
+ RETURN(finish(ZE_OK));
+ }
+
/* Make sure there's something left to do */
- if (k == 0 && found == NULL &&
+ if (k == 0 && found == NULL && !diff_mode &&
+ !(zfiles == NULL && allow_empty_archive) &&
!(zfiles != NULL &&
(latest || fix || adjust || junk_sfx || comadd || zipedit))) {
if (test && (zfiles != NULL || zipbeg != 0)) {
@@ -1751,12 +4711,12 @@ nextarg: ;
#ifdef VMS
strcpy(errbuf, "try: zip \"");
for (i = 1; i < (first_listarg - 1); i++)
- strcat(strcat(errbuf, argv[i]), "\" ");
- strcat(strcat(errbuf, argv[i]), " *.* -i");
+ strcat(strcat(errbuf, args[i]), "\" ");
+ strcat(strcat(errbuf, args[i]), " *.* -i");
#else /* !VMS */
strcpy(errbuf, "try: zip");
for (i = 1; i < first_listarg; i++)
- strcat(strcat(errbuf, " "), argv[i]);
+ strcat(strcat(errbuf, " "), args[i]);
# ifdef AMIGA
strcat(errbuf, " \"\" -i");
# else
@@ -1764,14 +4724,20 @@ nextarg: ;
# endif
#endif /* ?VMS */
for (i = first_listarg; i < argc; i++)
- strcat(strcat(errbuf, " "), argv[i]);
+ strcat(strcat(errbuf, " "), args[i]);
ZIPERR(ZE_NONE, errbuf);
}
-#endif /* !WINDLL */
else {
ZIPERR(ZE_NONE, zipfile);
}
+#endif /* !WINDLL */
}
+
+ if (filesync && all_current && fcount == 0) {
+ zipmessage("Archive is current", "");
+ RETURN(finish(ZE_OK));
+ }
+
d = (d && k == 0 && (zipbeg || zfiles != NULL)); /* d true if appending */
#if CRYPT
@@ -1785,6 +4751,11 @@ nextarg: ;
}
#endif /* CRYPT */
+ /* Just ignore the spanning signature if a multi-disk archive */
+ if (zfiles && total_disks != 1 && zipbeg == 4) {
+ zipbeg = 0;
+ }
+
/* Before we get carried away, make sure zip file is writeable. This
* has the undesired side effect of leaving one empty junk file on a WORM,
* so when the zipfile does not exist already and when -b is specified,
@@ -1793,27 +4764,31 @@ nextarg: ;
if (strcmp(zipfile, "-"))
{
if (tempdir && zfiles == NULL && zipbeg == 0) {
- a = 0;
+ zip_attributes = 0;
} else {
- x = zfiles == NULL && zipbeg == 0 ? fopen(zipfile, FOPW) :
- fopen(zipfile, FOPM);
+ x = (have_out || (zfiles == NULL && zipbeg == 0)) ? zfopen(out_path, FOPW) :
+ zfopen(out_path, FOPM);
/* Note: FOPW and FOPM expand to several parameters for VMS */
if (x == NULL) {
- ZIPERR(ZE_CREAT, zipfile);
+ ZIPERR(ZE_CREAT, out_path);
}
fclose(x);
- a = getfileattr(zipfile);
+ zip_attributes = getfileattr(out_path);
if (zfiles == NULL && zipbeg == 0)
- destroy(zipfile);
+ destroy(out_path);
}
}
else
- a = 0;
+ zip_attributes = 0;
/* Throw away the garbage in front of the zip file for -J */
if (junk_sfx) zipbeg = 0;
/* Open zip file and temporary output file */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Open zip file and create temp file\n");
+ fflush(mesg);
+ }
diag("opening zip file and creating temporary zip file");
x = NULL;
tempzn = 0;
@@ -1833,9 +4808,9 @@ nextarg: ;
# else
setmode(fileno(stdout), O_BINARY);
# endif
- tempzf = y = fdopen(fileno(stdout), FOPW);
+ y = zfdopen(fileno(stdout), FOPW);
#else
- tempzf = y = stdout;
+ y = stdout;
#endif
/* tempzip must be malloced so a later free won't barf */
tempzip = malloc(4);
@@ -1846,27 +4821,93 @@ nextarg: ;
}
else if (d) /* d true if just appending (-g) */
{
- if ((y = fopen(zipfile, FOPM)) == NULL) {
+ if (total_disks > 1) {
+ ZIPERR(ZE_PARMS, "cannot grow split archive");
+ }
+ if ((y = zfopen(zipfile, FOPM)) == NULL) {
ZIPERR(ZE_NAME, zipfile);
}
tempzip = zipfile;
+ /*
tempzf = y;
- if (fseek(y, cenbeg, SEEK_SET)) {
+ */
+
+ if (zfseeko(y, cenbeg, SEEK_SET)) {
ZIPERR(ferror(y) ? ZE_READ : ZE_EOF, zipfile);
}
+ bytes_this_split = cenbeg;
tempzn = cenbeg;
}
else
{
- if ((zfiles != NULL || zipbeg) && (x = fopen(zipfile, FOPR_EX)) == NULL) {
- ZIPERR(ZE_NAME, zipfile);
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Creating new zip file\n");
+ fflush(mesg);
+ }
+ /* See if there is something at beginning of disk 1 to copy.
+ If not, do nothing as zipcopy() will open files to read
+ as needed. */
+ if (zipbeg) {
+ in_split_path = get_in_split_path(in_path, 0);
+
+ while ((in_file = zfopen(in_split_path, FOPR_EX)) == NULL) {
+ /* could not open split */
+
+ /* Ask for directory with split. Updates in_path */
+ if (ask_for_split_read_path(0) != ZE_OK) {
+ ZIPERR(ZE_ABORT, "could not open archive to read");
+ }
+ free(in_split_path);
+ in_split_path = get_in_split_path(in_path, 1);
+ }
+ }
+#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 ((tempzf = y = fopen(tempzip, FOPW_TMP)) == NULL) {
+ if ((y = zfopen(tempzip, FOPW_TMP)) == NULL) {
ZIPERR(ZE_TEMP, tempzip);
}
+#endif
}
#if (!defined(VMS) && !defined(CMS_MVS))
@@ -1886,12 +4927,53 @@ nextarg: ;
# endif /* _IOBUF */
#endif /* !VMS && !CMS_MVS */
+ /* If not seekable set some flags 3/14/05 EG */
+ output_seekable = 1;
+ if (!is_seekable(y)) {
+ output_seekable = 0;
+ use_descriptors = 1;
+ }
+
+ /* Not needed. Only need Zip64 when input file is larger than 2 GB or reading
+ stdin and writing stdout. This is set in putlocal() for each file. */
+#if 0
+ /* If using descriptors and Zip64 enabled force Zip64 3/13/05 EG */
+# ifdef ZIP64_SUPPORT
+ if (use_descriptors && force_zip64 != 0) {
+ force_zip64 = 1;
+ }
+# endif
+#endif
+
+ /* if archive exists, not streaming and not deleting or growing, copy
+ any bytes at beginning */
if (strcmp(zipfile, "-") != 0 && !d) /* this must go *after* set[v]buf */
{
- if (zipbeg && (r = fcopy(x, y, zipbeg)) != ZE_OK) {
+ /* copy anything before archive */
+ if (in_file && zipbeg && (r = bfcopy(zipbeg)) != ZE_OK) {
ZIPERR(r, r == ZE_TEMP ? tempzip : zipfile);
- }
+ }
+ if (in_file) {
+ fclose(in_file);
+ in_file = NULL;
+ free(in_split_path);
+ }
tempzn = zipbeg;
+ if (split_method) {
+ /* add spanning signature */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Adding spanning/splitting signature at top of archive\n");
+ fflush(mesg);
+ }
+ /* write the spanning signature at the top of the archive */
+ errbuf[0] = 0x50 /*'P' except for EBCDIC*/;
+ errbuf[1] = 0x4b /*'K' except for EBCDIC*/;
+ errbuf[2] = 7;
+ errbuf[3] = 8;
+ bfwrite(errbuf, 1, 4, BFWRITE_DATA);
+ /* tempzn updated below */
+ tempzn += 4;
+ }
}
o = 0; /* no ZE_OPEN errors yet */
@@ -1902,38 +4984,148 @@ nextarg: ;
if (zfiles != NULL)
diag("going through old zip file");
#endif
+ if (zfiles != NULL && show_what_doing) {
+ fprintf(mesg, "sd: Going through old zip file\n");
+ fflush(mesg);
+ }
w = &zfiles;
while ((z = *w) != NULL) {
if (z->mark == 1)
{
+ uzoff_t len;
+ if ((zoff_t)z->len == -1)
+ /* device */
+ len = 0;
+ else
+ len = z->len;
+
/* if not deleting, zip it up */
- if (action != DELETE)
+ if (action != ARCHIVE && action != DELETE)
{
+ struct zlist far *localz; /* local header */
+
+ if (verbose || !(filesync && z->current))
+ DisplayRunningStats();
if (noisy)
{
- if (action == FRESHEN)
- fprintf(mesg, "freshening: %s", z->zname);
- else
- fprintf(mesg, "updating: %s", z->zname);
- fflush(mesg);
+ if (action == FRESHEN) {
+ fprintf(mesg, "freshening: %s", z->oname);
+ mesg_line_started = 1;
+ fflush(mesg);
+ } else if (filesync && z->current) {
+ if (verbose) {
+ fprintf(mesg, " ok: %s", z->oname);
+ mesg_line_started = 1;
+ fflush(mesg);
+ }
+ } else if (!(filesync && z->current)) {
+ fprintf(mesg, "updating: %s", z->oname);
+ mesg_line_started = 1;
+ fflush(mesg);
+ }
+ }
+ if (logall)
+ {
+ if (action == FRESHEN) {
+ fprintf(logfile, "freshening: %s", z->oname);
+ logfile_line_started = 1;
+ fflush(logfile);
+ } else if (filesync && z->current) {
+ if (verbose) {
+ fprintf(logfile, " current: %s", z->oname);
+ logfile_line_started = 1;
+ fflush(logfile);
+ }
+ } else {
+ fprintf(logfile, "updating: %s", z->oname);
+ logfile_line_started = 1;
+ fflush(logfile);
+ }
+ }
+
+ /* Get local header flags and extra fields */
+ if (readlocal(&localz, z) != ZE_OK) {
+ zipwarn("could not read local entry information: ", z->oname);
+ z->lflg = z->flg;
+ z->ext = 0;
+ } else {
+ z->lflg = localz->lflg;
+ z->ext = localz->ext;
+ z->extra = 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);
}
- if ((r = zipup(z, y)) != ZE_OK && r != ZE_OPEN && r != ZE_MISS)
+
+ if (!(filesync && z->current) &&
+ (r = zipup(z)) != ZE_OK && r != ZE_OPEN && r != ZE_MISS)
{
+ zipmessage_nl("", 1);
+ /*
if (noisy)
{
+ if (mesg_line_started) {
#if (!defined(MACOS) && !defined(WINDLL))
- putc('\n', mesg);
- fflush(mesg);
+ putc('\n', mesg);
+ fflush(mesg);
#else
- fprintf(stdout, "\n");
+ fprintf(stdout, "\n");
+ fflush(stdout);
#endif
+ mesg_line_started = 0;
+ }
+ }
+ if (logall) {
+ if (logfile_line_started) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ fflush(logfile);
+ }
}
+ */
sprintf(errbuf, "was zipping %s", z->name);
ZIPERR(r, errbuf);
}
+ if (filesync && z->current)
+ {
+ /* if filesync if entry matches OS just copy */
+ if ((r = zipcopy(z)) != ZE_OK)
+ {
+ sprintf(errbuf, "was copying %s", z->oname);
+ ZIPERR(r, errbuf);
+ }
+ zipmessage_nl("", 1);
+ /*
+ if (noisy)
+ {
+ if (mesg_line_started) {
+#if (!defined(MACOS) && !defined(WINDLL))
+ putc('\n', mesg);
+ fflush(mesg);
+#else
+ fprintf(stdout, "\n");
+ fflush(stdout);
+#endif
+ mesg_line_started = 0;
+ }
+ }
+ if (logall) {
+ if (logfile_line_started) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ fflush(logfile);
+ }
+ }
+ */
+ }
if (r == ZE_OPEN || r == ZE_MISS)
{
o = 1;
+ zipmessage_nl("", 1);
+ /*
if (noisy)
{
#if (!defined(MACOS) && !defined(WINDLL))
@@ -1942,41 +5134,254 @@ nextarg: ;
#else
fprintf(stdout, "\n");
#endif
+ mesg_line_started = 0;
}
+ if (logall) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ fflush(logfile);
+ }
+ */
if (r == ZE_OPEN) {
- perror(z->zname);
- zipwarn("could not open for reading: ", z->zname);
+ perror(z->oname);
+ zipwarn("could not open for reading: ", z->oname);
+ if (bad_open_is_error) {
+ sprintf(errbuf, "was zipping %s", z->name);
+ ZIPERR(r, errbuf);
+ }
} else {
- zipwarn("file and directory with the same name: ", z->zname);
+ zipwarn("file and directory with the same name: ", z->oname);
}
- zipwarn("will just copy entry over: ", z->zname);
- if ((r = zipcopy(z, x, y)) != ZE_OK)
+ zipwarn("will just copy entry over: ", z->oname);
+ if ((r = zipcopy(z)) != ZE_OK)
{
- sprintf(errbuf, "was copying %s", z->zname);
+ sprintf(errbuf, "was copying %s", z->oname);
ZIPERR(r, errbuf);
}
z->mark = 0;
}
+ files_so_far++;
+ good_bytes_so_far += z->len;
+ bytes_so_far += len;
w = &z->nxt;
}
+ else if (action == ARCHIVE)
+ {
+#ifdef DEBUG
+ zoff_t here = zftello(y);
+#endif
+
+ DisplayRunningStats();
+ if (skip_this_disk - 1 != z->dsk)
+ /* moved to another disk so start copying again */
+ skip_this_disk = 0;
+ if (skip_this_disk - 1 == z->dsk) {
+ /* skipping this disk */
+ if (noisy) {
+ fprintf(mesg, " skipping: %s", z->oname);
+ mesg_line_started = 1;
+ fflush(mesg);
+ }
+ if (logall) {
+ fprintf(logfile, " skipping: %s", z->oname);
+ logfile_line_started = 1;
+ fflush(logfile);
+ }
+ } else {
+ /* copying this entry */
+ if (noisy) {
+ fprintf(mesg, " copying: %s", z->oname);
+ if (display_usize) {
+ fprintf(mesg, " (");
+ DisplayNumString(mesg, z->len );
+ fprintf(mesg, ")");
+ }
+ mesg_line_started = 1;
+ fflush(mesg);
+ }
+ if (logall)
+ {
+ fprintf(logfile, " copying: %s", z->oname);
+ if (display_usize) {
+ fprintf(logfile, " (");
+ DisplayNumString(logfile, z->len );
+ fprintf(logfile, ")");
+ }
+ logfile_line_started = 1;
+ fflush(logfile);
+ }
+ }
+
+ if (skip_this_disk - 1 == z->dsk)
+ /* skip entries on this disk */
+ z->mark = 0;
+ else if ((r = zipcopy(z)) != ZE_OK)
+ {
+ if (r == ZE_ABORT) {
+ ZIPERR(r, "user requested abort");
+ } else if (fix != 1) {
+ /* exit */
+ sprintf(errbuf, "was copying %s", z->oname);
+ zipwarn("(try -F to attempt to fix)", "");
+ ZIPERR(r, errbuf);
+ }
+ else /* if (r == ZE_FORM) */ {
+#ifdef DEBUG
+ zoff_t here = zftello(y);
+#endif
+
+ /* seek back in output to start of this entry so can overwrite */
+ if (zfseeko(y, current_local_offset, SEEK_SET) != 0){
+ ZIPERR(r, "could not seek in output file");
+ }
+ zipwarn("bad - skipping: ", z->oname);
+#ifdef DEBUG
+ here = zftello(y);
+#endif
+ tempzn = current_local_offset;
+ bytes_this_split = current_local_offset;
+ }
+ }
+ if (skip_this_disk || !(fix == 1 && r != ZE_OK))
+ {
+ if (noisy && mesg_line_started) {
+ fprintf(mesg, "\n");
+ mesg_line_started = 0;
+ fflush(mesg);
+ }
+ if (logall && logfile_line_started) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ fflush(logfile);
+ }
+ }
+ /* input counts */
+ files_so_far++;
+ if (r != ZE_OK)
+ bad_bytes_so_far += z->siz;
+ else
+ good_bytes_so_far += z->siz;
+ bytes_so_far += z->siz;
+
+ if (r != ZE_OK && fix == 1) {
+ /* remove bad entry from list */
+ v = z->nxt; /* delete entry from list */
+ free((zvoid *)(z->iname));
+ free((zvoid *)(z->zname));
+ free(z->oname);
+#ifdef UNICODE_SUPPORT
+ if (z->uname) free(z->uname);
+#endif /* def UNICODE_SUPPORT */
+ if (z->ext)
+ /* don't have local extra until zipcopy reads it */
+ if (z->extra) free((zvoid *)(z->extra));
+ if (z->cext && z->cextra != z->extra)
+ free((zvoid *)(z->cextra));
+ if (z->com)
+ free((zvoid *)(z->comment));
+ farfree((zvoid far *)z);
+ *w = v;
+ zcount--;
+ } else {
+ w = &z->nxt;
+ }
+
+#ifdef WINDLL
+#ifdef ZIP64_SUPPORT
+ /* int64 support in caller */
+ if (lpZipUserFunctions->ServiceApplication64 != NULL)
+ {
+ if ((*lpZipUserFunctions->ServiceApplication64)(z->zname, z->siz))
+ ZIPERR(ZE_ABORT, "User terminated operation");
+ }
+ else
+ {
+ /* no int64 support in caller */
+ filesize64 = z->siz;
+ low = (unsigned long)(filesize64 & 0x00000000FFFFFFFF);
+ high = (unsigned long)((filesize64 >> 32) & 0x00000000FFFFFFFF);
+ if (lpZipUserFunctions->ServiceApplication64_No_Int64 != NULL) {
+ if ((*lpZipUserFunctions->ServiceApplication64_No_Int64)(z->zname, low, high))
+ ZIPERR(ZE_ABORT, "User terminated operation");
+ }
+ }
+#else
+ if (lpZipUserFunctions->ServiceApplication != NULL) {
+ if ((*lpZipUserFunctions->ServiceApplication)(z->zname, z->siz))
+ ZIPERR(ZE_ABORT, "User terminated operation");
+ }
+#endif /* ZIP64_SUPPORT - I added comments around // comments - does that help below? EG */
+/* strange but true: if I delete this and put these two endifs adjacent to
+ each other, the Aztec Amiga compiler never sees the second endif! WTF?? PK */
+#endif /* WINDLL */
+ }
else
{
+ DisplayRunningStats();
if (noisy)
{
- fprintf(mesg, "deleting: %s\n", z->zname);
+ fprintf(mesg, "deleting: %s", z->oname);
+ if (display_usize) {
+ fprintf(mesg, " (");
+ DisplayNumString(mesg, z->len );
+ fprintf(mesg, ")");
+ }
fflush(mesg);
+ fprintf(mesg, "\n");
}
+ if (logall)
+ {
+ fprintf(logfile, "deleting: %s", z->oname);
+ if (display_usize) {
+ fprintf(logfile, " (");
+ DisplayNumString(logfile, z->len );
+ fprintf(logfile, ")");
+ }
+ fprintf(logfile, "\n");
+ fflush(logfile);
+ }
+ files_so_far++;
+ good_bytes_so_far += z->siz;
+ bytes_so_far += z->siz;
#ifdef WINDLL
+#ifdef ZIP64_SUPPORT
+ /* int64 support in caller */
+ if (lpZipUserFunctions->ServiceApplication64 != NULL)
+ {
+ if ((*lpZipUserFunctions->ServiceApplication64)(z->zname, z->siz))
+ ZIPERR(ZE_ABORT, "User terminated operation");
+ }
+ else
+ {
+ /* no int64 support in caller */
+ filesize64 = z->siz;
+ low = (unsigned long)(filesize64 & 0x00000000FFFFFFFF);
+ high = (unsigned long)((filesize64 >> 32) & 0x00000000FFFFFFFF);
+ if (lpZipUserFunctions->ServiceApplication64_No_Int64 != NULL) {
+ if ((*lpZipUserFunctions->ServiceApplication64_No_Int64)(z->zname, low, high))
+ ZIPERR(ZE_ABORT, "User terminated operation");
+ }
+ }
+#else
if (lpZipUserFunctions->ServiceApplication != NULL) {
- if ((*lpZipUserFunctions->ServiceApplication)(z->zname, 0))
+ if ((*lpZipUserFunctions->ServiceApplication)(z->zname, z->siz))
ZIPERR(ZE_ABORT, "User terminated operation");
}
-#endif
+#endif /* ZIP64_SUPPORT - I added comments around // comments - does that help below? EG */
+/* strange but true: if I delete this and put these two endifs adjacent to
+ each other, the Aztec Amiga compiler never sees the second endif! WTF?? PK */
+#endif /* WINDLL */
+
v = z->nxt; /* delete entry from list */
free((zvoid *)(z->iname));
free((zvoid *)(z->zname));
+ free(z->oname);
+#ifdef UNICODE_SUPPORT
+ if (z->uname) free(z->uname);
+#endif /* def UNICODE_SUPPORT */
if (z->ext)
- free((zvoid *)(z->extra));
+ /* don't have local extra until zipcopy reads it */
+ if (z->extra) free((zvoid *)(z->extra));
if (z->cext && z->cextra != z->extra)
free((zvoid *)(z->cextra));
if (z->com)
@@ -1988,22 +5393,77 @@ nextarg: ;
}
else
{
- /* copy the original entry verbatim */
- if (!d && (r = zipcopy(z, x, y)) != ZE_OK)
+ if (action == ARCHIVE) {
+ v = z->nxt; /* delete entry from list */
+ free((zvoid *)(z->iname));
+ free((zvoid *)(z->zname));
+ free(z->oname);
+#ifdef UNICODE_SUPPORT
+ if (z->uname) free(z->uname);
+#endif /* def UNICODE_SUPPORT */
+ if (z->ext)
+ /* don't have local extra until zipcopy reads it */
+ if (z->extra) free((zvoid *)(z->extra));
+ if (z->cext && z->cextra != z->extra)
+ free((zvoid *)(z->cextra));
+ if (z->com)
+ free((zvoid *)(z->comment));
+ farfree((zvoid far *)z);
+ *w = v;
+ zcount--;
+ }
+ else
{
- sprintf(errbuf, "was copying %s", z->zname);
- ZIPERR(r, errbuf);
+ if (filesync) {
+ /* Delete entries if don't match a file on OS */
+ BlankRunningStats();
+ if (noisy)
+ {
+ fprintf(mesg, "deleting: %s", z->oname);
+ if (display_usize) {
+ fprintf(mesg, " (");
+ DisplayNumString(mesg, z->len );
+ fprintf(mesg, ")");
+ }
+ fflush(mesg);
+ fprintf(mesg, "\n");
+ mesg_line_started = 0;
+ }
+ if (logall)
+ {
+ fprintf(logfile, "deleting: %s", z->oname);
+ if (display_usize) {
+ fprintf(logfile, " (");
+ DisplayNumString(logfile, z->len );
+ fprintf(logfile, ")");
+ }
+ fprintf(logfile, "\n");
+ fflush(logfile);
+ logfile_line_started = 0;
+ }
+ }
+ /* copy the original entry */
+ else if (!d && !diff_mode && (r = zipcopy(z)) != ZE_OK)
+ {
+ sprintf(errbuf, "was copying %s", z->oname);
+ ZIPERR(r, errbuf);
+ }
+ w = &z->nxt;
}
- w = &z->nxt;
}
}
/* Process the edited found list, adding them to the zip file */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Zipping up new entries\n");
+ fflush(mesg);
+ }
diag("zipping up new entries, if any");
Trace((stderr, "zip diagnostic: fcount=%u\n", (unsigned)fcount));
for (f = found; f != NULL; f = fexpel(f))
{
+ uzoff_t len;
/* add a new zfiles entry and set the name */
if ((z = (struct zlist far *)farmalloc(sizeof(struct zlist))) == NULL) {
ZIPERR(ZE_MEM, "was adding files to zip file");
@@ -2011,22 +5471,93 @@ nextarg: ;
z->nxt = NULL;
z->name = f->name;
f->name = NULL;
+#ifdef UNICODE_SUPPORT
+ z->uname = NULL; /* UTF-8 name for extra field */
+ z->zuname = NULL; /* externalized UTF-8 name for matching */
+ z->ouname = NULL; /* display version of UTF-8 name with OEM */
+
+#if 0
+ /* New AppNote bit 11 allowing storing UTF-8 in path */
+ if (utf8_force && f->uname) {
+ if (f->iname)
+ free(f->iname);
+ if ((f->iname = malloc(strlen(f->uname) + 1)) == NULL)
+ ZIPERR(ZE_MEM, "Unicode bit 11");
+ strcpy(f->iname, f->uname);
+# ifdef WIN32
+ if (f->inamew)
+ free(f->inamew);
+ f->inamew = utf8_to_wchar_string(f->iname);
+# endif
+ }
+#endif
+
+ /* Only set z->uname if have a non-ASCII Unicode name */
+ /* The Unicode path extra field is created if z->uname is not NULL,
+ unless on a UTF-8 system, then instead of creating the extra field
+ set bit 11 in the General Purpose Bit Flag */
+ {
+ int is_ascii = 0;
+
+# ifdef WIN32
+ if (!no_win32_wide)
+ is_ascii = is_ascii_stringw(f->inamew);
+ else
+ is_ascii = is_ascii_string(f->uname);
+# else
+ is_ascii = is_ascii_string(f->uname);
+# endif
+
+ if (z->uname == NULL) {
+ if (!is_ascii)
+ z->uname = f->uname;
+ else
+ free(f->uname);
+ } else {
+ free(f->uname);
+ }
+ }
+ f->uname = NULL;
+
+#endif
z->iname = f->iname;
f->iname = NULL;
z->zname = f->zname;
f->zname = NULL;
+ z->oname = f->oname;
+ f->oname = NULL;
+#if defined(UNICODE_SUPPORT) && defined(WIN32)
+ z->namew = f->namew;
+ f->namew = NULL;
+ z->inamew = f->inamew;
+ f->inamew = NULL;
+ z->znamew = f->znamew;
+ f->znamew = NULL;
+#endif
z->ext = z->cext = z->com = 0;
z->extra = z->cextra = NULL;
z->mark = 1;
z->dosflag = f->dosflag;
/* zip it up */
+ DisplayRunningStats();
if (noisy)
{
- fprintf(mesg, " adding: %s", z->zname);
+ fprintf(mesg, " adding: %s", z->oname);
+ mesg_line_started = 1;
fflush(mesg);
}
- if ((r = zipup(z, y)) != ZE_OK && r != ZE_OPEN && r != ZE_MISS)
+ if (logall)
+ {
+ fprintf(logfile, " adding: %s", z->oname);
+ logfile_line_started = 1;
+ fflush(logfile);
+ }
+ /* initial scan */
+ len = f->usize;
+ if ((r = zipup(z)) != ZE_OK && r != ZE_OPEN && r != ZE_MISS)
{
+ zipmessage_nl("", 1);
+ /*
if (noisy)
{
#if (!defined(MACOS) && !defined(WINDLL))
@@ -2035,13 +5566,23 @@ nextarg: ;
#else
fprintf(stdout, "\n");
#endif
+ mesg_line_started = 0;
+ fflush(mesg);
+ }
+ if (logall) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ fflush(logfile);
}
- sprintf(errbuf, "was zipping %s", z->zname);
+ */
+ sprintf(errbuf, "was zipping %s", z->oname);
ZIPERR(r, errbuf);
}
if (r == ZE_OPEN || r == ZE_MISS)
{
o = 1;
+ zipmessage_nl("", 1);
+ /*
if (noisy)
{
#if (!defined(MACOS) && !defined(WINDLL))
@@ -2050,20 +5591,56 @@ nextarg: ;
#else
fprintf(stdout, "\n");
#endif
+ mesg_line_started = 0;
+ fflush(mesg);
}
+ if (logall) {
+ fprintf(logfile, "\n");
+ logfile_line_started = 0;
+ fflush(logfile);
+ }
+ */
if (r == ZE_OPEN) {
perror("zip warning");
- zipwarn("could not open for reading: ", z->zname);
+ if (logfile)
+ fprintf(logfile, "zip warning: %s\n", strerror(errno));
+ zipwarn("could not open for reading: ", z->oname);
+ if (bad_open_is_error) {
+ sprintf(errbuf, "was zipping %s", z->name);
+ ZIPERR(r, errbuf);
+ }
} else {
- zipwarn("file and directory with the same name: ", z->zname);
+ zipwarn("file and directory with the same name: ", z->oname);
}
+ files_so_far++;
+ bytes_so_far += len;
+ bad_files_so_far++;
+ bad_bytes_so_far += len;
free((zvoid *)(z->name));
free((zvoid *)(z->iname));
free((zvoid *)(z->zname));
+ free(z->oname);
+#ifdef UNICODE_SUPPORT
+ if (z->uname)
+ free(z->uname);
+# ifdef WIN32
+ if (z->namew)
+ free((zvoid *)(z->namew));
+ if (z->inamew)
+ free((zvoid *)(z->inamew));
+ if (z->znamew)
+ free((zvoid *)(z->znamew));
+# endif
+#endif
farfree((zvoid far *)z);
}
else
{
+ files_so_far++;
+ /* current size of file (just before reading) */
+ good_bytes_so_far += z->len;
+ /* size of file on initial scan */
+ bytes_so_far += len;
*w = z;
w = &z->nxt;
zcount++;
@@ -2075,8 +5652,38 @@ nextarg: ;
key = NULL;
}
+ /* final status 3/17/05 EG */
+ if (noisy && bad_files_so_far)
+ {
+ char tempstrg[100];
+
+ fprintf(mesg, "\nzip warning: Not all files were readable\n");
+ fprintf(mesg, " files/entries read: %lu", files_total - bad_files_so_far);
+ WriteNumString(good_bytes_so_far, tempstrg);
+ fprintf(mesg, " (%s bytes)", tempstrg);
+ fprintf(mesg, " skipped: %lu", bad_files_so_far);
+ WriteNumString(bad_bytes_so_far, tempstrg);
+ fprintf(mesg, " (%s bytes)\n", tempstrg);
+ fflush(mesg);
+ }
+ if (logfile && bad_files_so_far)
+ {
+ char tempstrg[100];
+
+ fprintf(logfile, "\nzip warning: Not all files were readable\n");
+ fprintf(logfile, " files/entries read: %lu", files_total - bad_files_so_far);
+ WriteNumString(good_bytes_so_far, tempstrg);
+ fprintf(logfile, " (%s bytes)", tempstrg);
+ fprintf(logfile, " skipped: %lu", bad_files_so_far);
+ WriteNumString(bad_bytes_so_far, tempstrg);
+ fprintf(logfile, " (%s bytes)", tempstrg);
+ }
/* Get one line comment for each new entry */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Get comment if any\n");
+ fflush(mesg);
+ }
#if defined(AMIGA) || defined(MACOS)
if (comadd || filenotes)
{
@@ -2123,10 +5730,10 @@ nextarg: ;
#endif /* AMIGA || MACOS */
{
if (noisy)
- fprintf(mesg, "Enter comment for %s:\n", z->zname);
+ fprintf(mesg, "Enter comment for %s:\n", z->oname);
if (fgets(e, MAXCOM+1, comment_stream) != NULL)
{
- if ((p = malloc((k = strlen(e))+1)) == NULL)
+ if ((p = malloc((extent)(k = strlen(e))+1)) == NULL)
{
free((zvoid *)e);
ZIPERR(ZE_MEM, "was reading comment lines");
@@ -2135,7 +5742,8 @@ nextarg: ;
if (p[k-1] == '\n')
p[--k] = 0;
z->comment = p;
- z->com = k;
+ /* zip64 support 09/05/2003 R.Nausedat */
+ z->com = (extent)k;
}
}
#ifdef MACOS
@@ -2230,38 +5838,75 @@ nextarg: ;
zcomlen = strlen(zcomment);
}
+ if (display_globaldots) {
+#ifndef WINDLL
+ putc('\n', mesg);
+#else
+ fprintf(stdout,"%c",'\n');
+#endif
+ mesg_line_started = 0;
+ }
/* Write central directory and end header to temporary zip */
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Writing central directory\n");
+ fflush(mesg);
+ }
diag("writing central directory");
k = 0; /* keep count for end header */
c = tempzn; /* get start of central */
n = t = 0;
for (z = zfiles; z != NULL; z = z->nxt)
{
- if ((r = putcentral(z, y)) != ZE_OK) {
- ZIPERR(r, tempzip);
+ if (z->mark || !(diff_mode || filesync)) {
+ if ((r = putcentral(z)) != ZE_OK) {
+ ZIPERR(r, tempzip);
+ }
+ tempzn += 4 + CENHEAD + z->nam + z->cext + z->com;
+ n += z->len;
+ t += z->siz;
+ k++;
}
- tempzn += 4 + CENHEAD + z->nam + z->cext + z->com;
- n += z->len;
- t += z->siz;
- k++;
}
+
if (k == 0)
zipwarn("zip file empty", "");
- if (verbose)
- fprintf(mesg, "total bytes=%lu, compressed=%lu -> %d%% savings\n",
- n, t, percent(n, t));
+ if (verbose) {
+ fprintf(mesg, "total bytes=%s, compressed=%s -> %d%% savings\n",
+ zip_fzofft(n, NULL, "u"), zip_fzofft(t, NULL, "u"), percent(n, t));
+ fflush(mesg);
+ }
+ if (logall) {
+ fprintf(logfile, "total bytes=%s, compressed=%s -> %d%% savings\n",
+ zip_fzofft(n, NULL, "u"), zip_fzofft(t, NULL, "u"), percent(n, t));
+ fflush(logfile);
+ }
t = tempzn - c; /* compute length of central */
diag("writing end of central directory");
- if ((r = putend(k, t, c, zcomlen, zcomment, y)) != ZE_OK) {
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Writing end of central directory\n");
+ fflush(mesg);
+ }
+
+ if ((r = putend(k, t, c, zcomlen, zcomment)) != ZE_OK) {
ZIPERR(r, tempzip);
}
+
+ /*
tempzf = NULL;
+ */
if (fclose(y)) {
ZIPERR(d ? ZE_WRITE : ZE_TEMP, tempzip);
}
+ y = NULL;
+ if (in_file != NULL) {
+ fclose(in_file);
+ in_file = NULL;
+ }
+ /*
if (x != NULL)
fclose(x);
+ */
/* Free some memory before spawning unzip */
#ifdef USE_ZLIB
@@ -2269,6 +5914,9 @@ nextarg: ;
#else
lm_free();
#endif
+#ifdef BZIP2_SUPPORT
+ bz_compress_free();
+#endif
#ifndef WINDLL
/* Test new zip file before overwriting old one or removing input files */
@@ -2279,7 +5927,11 @@ nextarg: ;
if (strcmp(zipfile, "-") && !d)
{
diag("replacing old zip file with new zip file");
- if ((r = replace(zipfile, tempzip)) != ZE_OK)
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Replacing old zip file\n");
+ fflush(mesg);
+ }
+ if ((r = replace(out_path, tempzip)) != ZE_OK)
{
zipwarn("new zip file left as: ", tempzip);
free((zvoid *)tempzip);
@@ -2289,34 +5941,74 @@ nextarg: ;
free((zvoid *)tempzip);
}
tempzip = NULL;
- if (a && strcmp(zipfile, "-")) {
- setfileattr(zipfile, a);
+ if (zip_attributes && strcmp(zipfile, "-")) {
+ setfileattr(out_path, zip_attributes);
#ifdef VMS
/* If the zip file existed previously, restore its record format: */
if (x != NULL)
- (void)VMSmunch(zipfile, RESTORE_RTYPE, NULL);
+ (void)VMSmunch(out_path, RESTORE_RTYPE, NULL);
#endif
}
+ if (strcmp(zipfile, "-")) {
+ if (show_what_doing) {
+ fprintf(mesg, "sd: Setting file type\n");
+ fflush(mesg);
+ }
-#ifdef __BEOS__
- /* Set the filetype of the zipfile to "application/zip" */
- setfiletype( zipfile, "application/zip" );
-#endif
+ set_filetype(out_path);
+ }
-#ifdef __ATHEOS__
- /* Set the filetype of the zipfile to "application/x-zip" */
- setfiletype(zipfile, "application/x-zip");
+#if defined(WIN32)
+ /* All looks good so, if requested, clear the DOS archive bits */
+ if (clear_archive_bits) {
+ if (noisy)
+ zipmessage("Clearing archive bits...", "");
+ for (z = zfiles; z != NULL; z = z->nxt)
+ {
+# ifdef UNICODE_SUPPORT
+ if (z->mark) {
+ if (!no_win32_wide) {
+ if (!ClearArchiveBitW(z->namew)){
+ zipwarn("Could not clear archive bit for: ", z->oname);
+ }
+ } else {
+ if (!ClearArchiveBit(z->name)){
+ zipwarn("Could not clear archive bit for: ", z->oname);
+ }
+ }
+ }
+# else
+ if (!ClearArchiveBit(z->name)){
+ zipwarn("Could not clear archive bit for: ", z->oname);
+ }
+# endif
+ }
+ }
#endif
-#ifdef MACOS
- /* Set the Creator/Type of the zipfile to 'IZip' and 'ZIP ' */
- setfiletype(zipfile, 'IZip', 'ZIP ');
-#endif
+ /* finish logfile (it gets closed in freeup() called by finish()) */
+ if (logfile) {
+ struct tm *now;
+ time_t clocktime;
-#ifdef RISCOS
- /* Set the filetype of the zipfile to &DDC */
- setfiletype(zipfile, 0xDDC);
-#endif
+ fprintf(logfile, "\nTotal %ld entries (", files_total);
+ if (good_bytes_so_far != bytes_total) {
+ fprintf(logfile, "planned ");
+ DisplayNumString(logfile, bytes_total);
+ fprintf(logfile, " bytes, actual ");
+ DisplayNumString(logfile, good_bytes_so_far);
+ fprintf(logfile, " bytes)");
+ } else {
+ DisplayNumString(logfile, bytes_total);
+ fprintf(logfile, " bytes)");
+ }
+
+ /* get current time */
+
+ time(&clocktime);
+ now = localtime(&clocktime);
+ fprintf(logfile, "\nDone %s", asctime(now));
+ }
/* Finish up (process -o, -m, clean up). Exit code depends on o. */
#if (!defined(VMS) && !defined(CMS_MVS))
diff --git a/zip.h b/zip.h
index e8b3e30..ba03160 100644
--- a/zip.h
+++ b/zip.h
@@ -1,10 +1,17 @@
/*
-This is version 2005-Feb-10 of the Info-ZIP copyright and license.
+ zip.h - Zip 3
+
+/---------------------------------------------------------------------/
+
+Info-ZIP Licence
+
+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.
+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-2005 Info-ZIP. All rights reserved.
+Copyright (c) 1990-2008 Info-ZIP. All rights reserved.
For the purposes of this copyright and license, "Info-ZIP" is defined as
the following set of individuals:
@@ -16,7 +23,7 @@ the following set of individuals:
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
+ 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
@@ -25,35 +32,42 @@ 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 following restrictions:
+freely, subject to the above disclaimer and the following restrictions:
- 1. Redistributions of source code must retain the above copyright notice,
- definition, disclaimer, and this list of conditions.
+ 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) 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.
+ 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, and dynamic,
- shared, or static library versions--must be plainly marked as such
- and must not be misrepresented as being 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 of the Info-ZIP URL(s).
+ 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.
+
+/---------------------------------------------------------------------/
+
*/
/*
@@ -64,6 +78,12 @@ freely, subject to the following restrictions:
#define ZIP /* for crypt.c: include zip password functions, not unzip */
+/* Types centralized here for easy modification */
+#define local static /* More meaningful outside functions */
+typedef unsigned char uch; /* unsigned 8-bit value */
+typedef unsigned short ush; /* unsigned 16-bit value */
+typedef unsigned long ulg; /* unsigned 32-bit value */
+
/* Set up portability */
#include "tailor.h"
@@ -71,6 +91,11 @@ freely, subject to the following restrictions:
# include "zlib.h"
#endif
+/* In the utilities, the crc32() function is only used for UNICODE_SUPPORT. */
+#if defined(UTIL) && !defined(UNICODE_SUPPORT)
+# define CRC_TABLE_ONLY
+#endif
+
#define MIN_MATCH 3
#define MAX_MATCH 258
/* The minimum and maximum match lengths */
@@ -104,13 +129,6 @@ freely, subject to the following restrictions:
# define MATCH shmatch /* Default for pattern matching: UNIX style */
#endif
-/* Types centralized here for easy modification */
-#define local static /* More meaningful outside functions */
-typedef unsigned char uch; /* unsigned 8-bit value */
-typedef unsigned short ush; /* unsigned 16-bit value */
-typedef unsigned long ulg; /* unsigned 32-bit value */
-
-
/* Structure carrying extended timestamp information */
typedef struct iztimes {
time_t atime; /* new access time */
@@ -122,23 +140,48 @@ typedef struct iztimes {
#define LOCHEAD 26
#define CENHEAD 42
#define ENDHEAD 18
+#define EC64LOC 16
+#define EC64REC 52
/* Structures for in-memory file information */
struct zlist {
/* See central header in zipfile.c for what vem..off are */
+ /* Do not rearrange these as less than smart coding in zipfile.c
+ in scanzipf_reg() depends on u being set to ver and then stepping
+ through as a byte array. Ack. Should be fixed. 5/25/2005 EG */
+ /* All the new read code does not rely on this order. */
ush vem, ver, flg, how;
- ulg tim, crc, siz, len;
- extent nam, ext, cext, com; /* offset of ext must be >= LOCHEAD */
- ush dsk, att, lflg; /* offset of lflg must be >= LOCHEAD */
- ulg atx, off;
+ ulg tim, crc;
+ uzoff_t siz, len; /* zip64 support 08/29/2003 R.Nausedat */
+ /* changed from extent to ush 3/10/2005 EG */
+ ush nam, ext, cext, com; /* offset of ext must be >= LOCHEAD */
+ ulg dsk; /* disk number was ush but now ulg */
+ ush att, lflg; /* offset of lflg must be >= LOCHEAD */
+ uzoff_t off;
+ ulg atx;
char *name; /* File name in zip file */
char *extra; /* Extra field (set only if ext != 0) */
char *cextra; /* Extra in central (set only if cext != 0) */
char *comment; /* Comment (set only if com != 0) */
- char *iname; /* Internal file name after cleanup */
+ char *iname; /* Internal file name after cleanup (stored in archive) */
char *zname; /* External version of internal name */
+ char *oname; /* Display version of name used in messages */
+#ifdef UNICODE_SUPPORT
+ /* Unicode support */
+ char *uname; /* UTF-8 version of iname */
+ /* if uname has chars not in local char set, zuname can be different than zname */
+ char *zuname; /* Escaped Unicode zname from uname */
+ char *ouname; /* Display version of zuname */
+# ifdef WIN32
+ char *wuname; /* Converted back ouname for Win32 */
+ wchar_t *namew; /* Windows wide character version of name */
+ wchar_t *inamew; /* Windows wide character version of iname */
+ wchar_t *znamew; /* Windows wide character version of zname */
+# endif
+#endif
int mark; /* Marker for files to operate on */
int trash; /* Marker for files to delete */
+ int current; /* Marker for files that are current to what is on OS (filesync) */
int dosflag; /* Set to force MSDOS file attributes */
struct zlist far *nxt; /* Pointer to next header in list */
};
@@ -146,7 +189,17 @@ struct flist {
char *name; /* Raw internal file name */
char *iname; /* Internal file name after cleanup */
char *zname; /* External version of internal name */
+ char *oname; /* Display version of internal name */
+#ifdef UNICODE_SUPPORT
+ char *uname; /* UTF-8 name */
+# ifdef WIN32
+ wchar_t *namew; /* Windows wide character version of name */
+ wchar_t *inamew; /* Windows wide character version of iname */
+ wchar_t *znamew; /* Windows wide character version of zname */
+# endif
+#endif
int dosflag; /* Set to force MSDOS file attributes */
+ uzoff_t usize; /* usize from initial scan */
struct flist far *far *lst; /* Pointer to link pointing here */
struct flist far *nxt; /* Link to next name */
};
@@ -228,8 +281,14 @@ struct plist {
#if 0 /* Optimization: use the (const) result of crc32(0L,NULL,0) */
# define CRCVAL_INITIAL crc32(0L, (uch *)NULL, 0)
+# if 00 /* not used, should be removed !! */
+# define ADLERVAL_INITIAL adler16(0U, (uch *)NULL, 0)
+# endif /* 00 */
#else
# define CRCVAL_INITIAL 0L
+# if 00 /* not used, should be removed !! */
+# define ADLERVAL_INITIAL 1
+# endif /* 00 */
#endif
#define DOSTIME_MINIMUM ((ulg)0x00210000L)
@@ -243,13 +302,21 @@ extern uch lower[256];
extern ZCONST uch ascii[256]; /* EBCDIC <--> ASCII translation tables */
extern ZCONST uch ebcdic[256];
#endif /* EBCDIC */
+#if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB))
+ extern ZCONST ulg near *crc_32_tab;
+#else
+ extern ZCONST ulg Far *crc_32_tab;
+#endif
+
+/* Are these ever used? 6/12/05 EG */
#ifdef IZ_ISO2OEM_ARRAY /* ISO 8859-1 (Win CP 1252) --> OEM CP 850 */
extern ZCONST uch Far iso2oem[128];
#endif
#ifdef IZ_OEM2ISO_ARRAY /* OEM CP 850 --> ISO 8859-1 (Win CP 1252) */
extern ZCONST uch Far oem2iso[128];
#endif
-extern char errbuf[FNMAX+81]; /* Handy place to build error messages */
+
+extern char errbuf[FNMAX+4081]; /* Handy place to build error messages */
extern int recurse; /* Recurse into directories encountered */
extern int dispose; /* Remove files after put in zip file */
extern int pathput; /* Store path with name */
@@ -261,18 +328,57 @@ extern int scanimage; /* Scan through image files */
#define BEST -1 /* Use best method (deflation or store) */
#define STORE 0 /* Store method */
#define DEFLATE 8 /* Deflation method*/
+#define BZIP2 12 /* BZIP2 method */
+#ifdef BZIP2_SUPPORT
+#define LAST_KNOWN_COMPMETHOD BZIP2
+#else
+#define LAST_KNOWN_COMPMETHOD DEFLATE
+#endif
+
extern int method; /* Restriction on compression method */
+extern ulg skip_this_disk;
+extern int des_good; /* Good data descriptor found */
+extern ulg des_crc; /* Data descriptor CRC */
+extern uzoff_t des_csize; /* Data descriptor csize */
+extern uzoff_t des_usize; /* Data descriptor usize */
extern int dosify; /* Make new entries look like MSDOS */
extern char *special; /* Don't compress special suffixes */
extern int verbose; /* Report oddities in zip file structure */
extern int fix; /* Fix the zip file */
+extern int filesync; /* 1=file sync, delete entries not on file system */
extern int adjust; /* Adjust the unzipsfx'd zip file */
extern int level; /* Compression level */
extern int translate_eol; /* Translate end-of-line LF -> CR LF */
#ifdef VMS
extern int vmsver; /* Append VMS version number to file names */
extern int vms_native; /* Store in VMS format */
+ extern int vms_case_2; /* ODS2 file name case in VMS. -1: down. */
+ extern int vms_case_5; /* ODS5 file name case in VMS. +1: preserve. */
+
+/* Accomodation for /NAMES = AS_IS with old header files. */
+# define cma$tis_errno_get_addr CMA$TIS_ERRNO_GET_ADDR
+# define lib$establish LIB$ESTABLISH
+# define lib$get_foreign LIB$GET_FOREIGN
+# define lib$get_input LIB$GET_INPUT
+# define lib$sig_to_ret LIB$SIG_TO_RET
+# define ots$cvt_tu_l OTS$CVT_TU_L
+# define str$concat STR$CONCAT
+# define str$find_first_substring STR$FIND_FIRST_SUBSTRING
+# define str$free1_dx STR$FREE1_DX
+# define sys$asctim SYS$ASCTIM
+# define sys$assign SYS$ASSIGN
+# define sys$bintim SYS$BINTIM
+# define sys$close SYS$CLOSE
+# define sys$connect SYS$CONNECT
+# define sys$dassgn SYS$DASSGN
+# define sys$display SYS$DISPLAY
+# define sys$getjpiw SYS$GETJPIW
+# define sys$open SYS$OPEN
+# define sys$parse SYS$PARSE
+# define sys$qiow SYS$QIOW
+# define sys$read SYS$READ
+# define sys$search SYS$SEARCH
#endif /* VMS */
#if defined(OS2) || defined(WIN32)
extern int use_longname_ea; /* use the .LONGNAME EA as the file's name */
@@ -280,27 +386,159 @@ extern int translate_eol; /* Translate end-of-line LF -> CR LF */
#if defined (QDOS) || defined(QLZIP)
extern short qlflag;
#endif
+/* 9/26/04 EG */
+extern int no_wild; /* wildcards are disabled */
+extern int allow_regex; /* 1 = allow [list] matching (regex) */
+extern int wild_stop_at_dir; /* wildcards do not include / in matches */
+#ifdef UNICODE_SUPPORT
+ extern int using_utf8; /* 1 if current character set is UTF-8 */
+# ifdef WIN32
+ extern int no_win32_wide; /* 1 = no wide functions, like GetFileAttributesW() */
+# endif
+#endif
+/* 10/20/04 */
+extern zoff_t dot_size; /* if not 0 then display dots every size buffers */
+extern zoff_t dot_count; /* if dot_size not 0 counts buffers */
+/* status 10/30/04 */
+extern int display_counts; /* display running file count */
+extern int display_bytes; /* display running bytes remaining */
+extern int display_globaldots; /* display dots for archive instead of for each file */
+extern int display_volume; /* display current input and output volume (disk) numbers */
+extern int display_usize; /* display uncompressed bytes */
+extern ulg files_so_far; /* files processed so far */
+extern ulg bad_files_so_far; /* files skipped so far */
+extern ulg files_total; /* files total to process */
+extern uzoff_t bytes_so_far; /* bytes processed so far (from initial scan) */
+extern uzoff_t good_bytes_so_far;/* good bytes read so far */
+extern uzoff_t bad_bytes_so_far;/* bad bytes skipped so far */
+extern uzoff_t bytes_total; /* total bytes to process (from initial scan) */
+/* logfile 6/5/05 */
+extern int logall; /* 0 = warnings/errors, 1 = all */
+extern FILE *logfile; /* pointer to open logfile or NULL */
+extern int logfile_append; /* append to existing logfile */
+extern char *logfile_path; /* pointer to path of logfile */
+#ifdef WIN32
+extern int nonlocal_name; /* Name has non-local characters */
+extern int nonlocal_path; /* Path has non-local characters */
+#endif
+#ifdef UNICODE_SUPPORT
+/* Unicode 10/12/05 */
+extern int use_wide_to_mb_default;/* use the default MB char instead of escape */
+#endif
+
extern int hidden_files; /* process hidden and system files */
extern int volume_label; /* add volume label */
extern int dirnames; /* include directory names */
+extern int filter_match_case; /* 1=match case when filter() */
+extern int diff_mode; /* 1=require --out and only store changed and add */
+#if defined(WIN32)
+extern int only_archive_set; /* only include if DOS archive bit set */
+extern int clear_archive_bits; /* clear DOS archive bit of included files */
+#endif
extern int linkput; /* Store symbolic links as such */
extern int noisy; /* False for quiet operation */
-extern int extra_fields; /* do not create extra fields */
+extern int extra_fields; /* 0=create minimum, 1=don't copy old, 2=keep old */
#ifdef NTSD_EAS
- extern int use_privileges; /* use security privilege overrides */
+ extern int use_privileges; /* use security privilege overrides */
#endif
+extern int use_descriptors; /* use data descriptors (extended headings) */
+extern int allow_empty_archive; /* if no files, create empty archive anyway */
+extern int copy_only; /* 1 = copy archive with no changes */
+extern int zip_to_stdout; /* output to stdout */
+extern int output_seekable; /* 1 = output seekable 3/13/05 EG */
+#ifdef ZIP64_SUPPORT /* zip64 globals 10/4/03 E. Gordon */
+ extern int force_zip64; /* force use of zip64 when streaming from stdin */
+ extern int zip64_entry; /* current entry needs Zip64 */
+ extern int zip64_archive; /* at least 1 entry needs zip64 */
+#endif
+extern int allow_fifo; /* Allow reading Unix FIFOs, waiting if pipe open */
+extern int show_files; /* show files to operate on and exit (=2 log only) */
+
+extern char *tempzip; /* temp file name */
+extern FILE *y; /* output file now global for splits */
+
+#ifdef UNICODE_SUPPORT
+ extern int utf8_force; /* 1=store UTF-8 as standard per AppNote bit 11 */
+#endif
+extern int unicode_escape_all; /* 1=escape all non-ASCII characters in paths */
+extern int unicode_mismatch; /* unicode mismatch is 0=error, 1=warn, 2=ignore, 3=no */
+
+extern time_t scan_delay; /* seconds before display Scanning files message */
+extern time_t scan_dot_time; /* time in seconds between Scanning files dots */
+extern time_t scan_start; /* start of file scan */
+extern time_t scan_last; /* time of last message */
+extern int scan_started; /* scan has started */
+extern uzoff_t scan_count; /* Used for "Scanning files..." message */
+
+extern ulg before; /* 0=ignore, else exclude files before this time */
+extern ulg after; /* 0=ignore, else exclude files newer than this time */
+
+/* in split globals */
+
+extern ulg total_disks;
+
+extern ulg current_in_disk;
+extern uzoff_t current_in_offset;
+extern ulg skip_current_disk;
+
+
+/* out split globals */
+
+extern ulg current_local_disk; /* disk with current local header */
+
+extern ulg current_disk; /* current disk number */
+extern ulg cd_start_disk; /* central directory start disk */
+extern uzoff_t cd_start_offset; /* offset of start of cd on cd start disk */
+extern uzoff_t cd_entries_this_disk; /* cd entries this disk */
+extern uzoff_t total_cd_entries; /* total cd entries in new/updated archive */
+extern ulg zip64_eocd_disk; /* disk with Zip64 EOCD Record */
+extern uzoff_t zip64_eocd_offset; /* offset of Zip64 EOCD Record */
+/* for split method 1 (keep split with local header open and update) */
+extern char *current_local_tempname; /* name of temp file */
+extern FILE *current_local_file; /* file pointer for current local header */
+extern uzoff_t current_local_offset; /* offset to start of current local header */
+/* global */
+extern uzoff_t bytes_this_split; /* bytes written to current split */
+extern int read_split_archive; /* 1=scanzipf_reg detected spanning signature */
+extern int split_method; /* 0=no splits, 1=seekable, 2=data descs, -1=no */
+extern uzoff_t split_size; /* how big each split should be */
+extern int split_bell; /* when pause for next split ring bell */
+extern uzoff_t bytes_prev_splits; /* total bytes written to all splits before this */
+extern uzoff_t bytes_this_entry; /* bytes written for this entry across all splits */
+extern int noisy_splits; /* note when splits are being created */
+extern int mesg_line_started; /* 1=started writing a line to mesg */
+extern int logfile_line_started; /* 1=started writing a line to logfile */
extern char *key; /* Scramble password or NULL */
extern char *tempath; /* Path for temporary files */
extern FILE *mesg; /* Where informational output goes */
extern char *zipfile; /* New or existing zip archive (zip file) */
-extern ulg zipbeg; /* Starting offset of zip structures */
-extern ulg cenbeg; /* Starting offset of central directory */
+extern FILE *in_file; /* Current input file for spits */
+extern char *in_path; /* Name of input archive, used to track reading splits */
+extern char *in_split_path; /* in split path */
+extern char *out_path; /* Name of output file, usually same as zipfile */
+extern int zip_attributes;
+
+/* zip64 support 08/31/2003 R.Nausedat */
+extern uzoff_t zipbeg; /* Starting offset of zip structures */
+extern uzoff_t cenbeg; /* Starting offset of central directory */
+extern uzoff_t tempzn; /* Count of bytes written to output zip file */
+
+/* NOTE: zcount and fcount cannot exceed "size_t" (resp. "extent") range.
+ This is an internal limitation built into Zip's action handling:
+ Zip keeps "{z|f}count * struct {z|f}list" arrays in (flat) memory,
+ for sorting, file matching, and building the central-dir structures.
+ */
+
extern struct zlist far *zfiles;/* Pointer to list of files in zip file */
extern extent zcount; /* Number of files in zip file */
-extern extent zcomlen; /* Length of zip file comment */
+extern int zipfile_exists; /* 1 if zipfile exists */
+extern ush zcomlen; /* Length of zip file comment */
extern char *zcomment; /* Zip file comment (not zero-terminated) */
+extern struct flist far **fsort;/* List of files sorted by name */
extern struct zlist far **zsort;/* List of files sorted by name */
-extern ulg tempzn; /* Count of bytes written to output zip file */
+#ifdef UNICODE_SUPPORT
+extern struct zlist far **zusort;/* List of files sorted by zuname */
+#endif
extern struct flist far *found; /* List of names found */
extern struct flist far *far *fnxt; /* Where to put next in found list */
extern extent fcount; /* Count of names in found list */
@@ -308,6 +546,7 @@ extern extent fcount; /* Count of names in found list */
extern struct plist *patterns; /* List of patterns to be matched */
extern unsigned pcount; /* number of patterns */
extern unsigned icount; /* number of include only patterns */
+extern unsigned Rcount; /* number of -R include patterns */
#ifdef IZ_CHECK_TZ
extern int zp_tz_is_valid; /* signals "timezone info is available" */
@@ -367,8 +606,10 @@ extern int aflag;
#ifdef CMS_MVS
extern int bflag;
#endif /* CMS_MVS */
-void zipwarn OF((ZCONST char *, ZCONST char *));
-void ziperr OF((int, ZCONST char *));
+void zipmessage_nl OF((ZCONST char *, int));
+void zipmessage OF((ZCONST char *, ZCONST char *));
+void zipwarn OF((ZCONST char *, ZCONST char *));
+void ziperr OF((int, ZCONST char *));
#ifdef UTIL
# define error(msg) ziperr(ZE_LOGIC, msg)
#else
@@ -381,8 +622,10 @@ void ziperr OF((int, ZCONST char *));
/* in zipup.c */
#ifndef UTIL
- int percent OF((ulg, ulg));
- int zipup OF((struct zlist far *, FILE *));
+ /* zip64 support 08/31/2003 R.Nausedat */
+ int percent OF((uzoff_t, uzoff_t));
+
+ int zipup OF((struct zlist far *));
# ifdef USE_ZLIB
void zl_deflate_free OF((void));
# else
@@ -393,6 +636,9 @@ void ziperr OF((int, ZCONST char *));
# ifdef ZP_NEED_MEMCOMPR
ulg memcompress OF((char *, ulg, char *, ulg));
# endif
+# ifdef BZIP2_SUPPORT
+ void bz_compress_free OF((void));
+# endif
#endif /* !UTIL */
/* in zipfile.c */
@@ -405,21 +651,41 @@ void ziperr OF((int, ZCONST char *));
#endif /* !UTIL */
char *ziptyp OF((char *));
int readzipfile OF((void));
-int putlocal OF((struct zlist far *, FILE *));
-int putextended OF((struct zlist far *, FILE *));
-int putcentral OF((struct zlist far *, FILE *));
-int putend OF((int, ulg, ulg, extent, char *, FILE *));
-int zipcopy OF((struct zlist far *, FILE *, FILE *));
+int putlocal OF((struct zlist far *, int));
+int putextended OF((struct zlist far *));
+int putcentral OF((struct zlist far *));
+/* zip64 support 09/05/2003 R.Nausedat */
+int putend OF((uzoff_t, uzoff_t, uzoff_t, extent, char *));
+/* moved seekable to separate function 3/14/05 EG */
+int is_seekable OF((FILE *));
+int zipcopy OF((struct zlist far *));
+int readlocal OF((struct zlist far **, struct zlist far *));
+/* made global for handling extra fields */
+char *get_extra_field OF((ush, char *, unsigned));
+char *copy_nondup_extra_fields OF((char *, unsigned, char *, unsigned, unsigned *));
/* in fileio.c */
#ifndef UTIL
- char *getnam OF((char *, FILE *));
+ char *getnam OF((FILE *));
struct flist far *fexpel OF((struct flist far *));
char *last OF((char *, int));
+# ifdef UNICODE_SUPPORT
+ wchar_t *lastw OF((wchar_t *, wchar_t));
+# endif
char *msname OF((char *));
+# ifdef UNICODE_SUPPORT
+ wchar_t *msnamew OF((wchar_t *));
+# endif
int check_dup OF((void));
int filter OF((char *, int));
int newname OF((char *, int, int));
+# ifdef UNICODE_SUPPORT
+# ifdef WIN32
+ int newnamew OF((wchar_t *, int, int));
+# endif
+# endif
+ /* used by copy mode */
+ int proc_archive_name OF((char *, int));
#endif /* !UTIL */
#if (!defined(UTIL) || defined(W32_STATROOT_FIX))
time_t dos2unixtime OF((ulg));
@@ -441,7 +707,20 @@ int replace OF((char *, char *));
int getfileattr OF((char *));
int setfileattr OF((char *, int));
char *tempname OF((char *));
-int fcopy OF((FILE *, FILE *, ulg));
+
+/* for splits */
+int close_split OF((ulg, FILE *, char *));
+int ask_for_split_read_path OF((ulg));
+int ask_for_split_write_path OF((ulg));
+char *get_in_split_path OF((char *, ulg));
+char *find_in_split_path OF((char *, ulg));
+char *get_out_split_path OF((char *, ulg));
+int rename_split OF((char *, char *));
+int set_filetype OF((char *));
+
+int bfcopy OF((uzoff_t));
+
+int fcopy OF((FILE *, FILE *, uzoff_t));
#ifdef ZMEM
char *memset OF((char *, int, unsigned int));
@@ -451,22 +730,38 @@ int fcopy OF((FILE *, FILE *, ulg));
/* in system dependent fileio code (<system>.c) */
#ifndef UTIL
-# ifdef PROCNAME
- int wild OF((char *));
-# endif
+# ifdef PROCNAME
+ int wild OF((char *));
+# endif
char *in2ex OF((char *));
char *ex2in OF((char *, int, int *));
+#if defined(UNICODE_SUPPORT) && defined(WIN32)
+ int has_win32_wide OF((void));
+ wchar_t *in2exw OF((wchar_t *));
+ wchar_t *ex2inw OF((wchar_t *, int, int *));
+ int procnamew OF((wchar_t *, int));
+#endif
int procname OF((char *, int));
void stamp OF((char *, ulg));
- ulg filetime OF((char *, ulg *, long *, iztimes *));
-#if !(defined(VMS) && defined(VMS_PK_EXTRA))
+
+ ulg filetime OF((char *, ulg *, zoff_t *, iztimes *));
+ /* Windows Unicode */
+# ifdef UNICODE_SUPPORT
+# ifdef WIN32
+ ulg filetimew OF((wchar_t *, ulg *, zoff_t *, iztimes *));
+ char *get_win32_utf8path OF((char *));
+ wchar_t *local_to_wchar_string OF ((char *));
+# endif
+# endif
+
+# if !(defined(VMS) && defined(VMS_PK_EXTRA))
int set_extra_field OF((struct zlist far *, iztimes *));
-#endif /* ?(VMS && VMS_PK_EXTRA) */
+# endif /* ?(VMS && VMS_PK_EXTRA) */
int deletedir OF((char *));
-#ifdef MY_ZCALLOC
+# ifdef MY_ZCALLOC
zvoid far *zcalloc OF((unsigned int, unsigned int));
zvoid zcfree OF((zvoid far *));
-#endif /* MY_ZCALLOC */
+# endif /* MY_ZCALLOC */
#endif /* !UTIL */
void version_local OF((void));
@@ -474,25 +769,44 @@ void version_local OF((void));
#ifndef UTIL
int fseekable OF((FILE *));
char *isshexp OF((char *));
+#ifdef UNICODE_SUPPORT
+# ifdef WIN32
+ wchar_t *isshexpw OF((wchar_t *));
+ int dosmatchw OF((ZCONST wchar_t *, ZCONST wchar_t *, int));
+# endif
+#endif
int shmatch OF((ZCONST char *, ZCONST char *, int));
-#if defined(DOS) || defined(WIN32)
+# if defined(DOS) || defined(WIN32)
int dosmatch OF((ZCONST char *, ZCONST char *, int));
-#endif /* DOS || WIN32 */
+# endif /* DOS || WIN32 */
#endif /* !UTIL */
+
+/* functions to convert zoff_t to a string */
+char *zip_fuzofft OF((uzoff_t, char *, char*));
+char *zip_fzofft OF((zoff_t, char *, char*));
+
+/* read and write number strings like 10M */
+int DisplayNumString OF ((FILE *file, uzoff_t i));
+int WriteNumString OF((uzoff_t num, char *outstring));
+uzoff_t ReadNumString OF((char *numstring));
+
+/* returns true if abbrev is abbreviation for string */
+int abbrevmatch OF((char *, char *, int, int));
+
void init_upper OF((void));
int namecmp OF((ZCONST char *string1, ZCONST char *string2));
#ifdef EBCDIC
-char *strtoasc OF((char *str1, ZCONST char *str2));
-char *strtoebc OF((char *str1, ZCONST char *str2));
-char *memtoasc OF((char *mem1, ZCONST char *mem2, unsigned len));
-char *memtoebc OF((char *mem1, ZCONST char *mem2, unsigned len));
+ char *strtoasc OF((char *str1, ZCONST char *str2));
+ char *strtoebc OF((char *str1, ZCONST char *str2));
+ char *memtoasc OF((char *mem1, ZCONST char *mem2, unsigned len));
+ char *memtoebc OF((char *mem1, ZCONST char *mem2, unsigned len));
#endif /* EBCDIC */
#ifdef IZ_ISO2OEM_ARRAY
-char *str_iso_to_oem OF((char *dst, ZCONST char *src));
+ char *str_iso_to_oem OF((char *dst, ZCONST char *src));
#endif
#ifdef IZ_OEM2ISO_ARRAY
-char *str_oem_to_iso OF((char *dst, ZCONST char *src));
+ char *str_oem_to_iso OF((char *dst, ZCONST char *src));
#endif
zvoid far **search OF((ZCONST zvoid *, ZCONST zvoid far **, extent,
@@ -500,30 +814,24 @@ zvoid far **search OF((ZCONST zvoid *, ZCONST zvoid far **, extent,
void envargs OF((int *, char ***, char *, char *));
void expand_args OF((int *, char ***));
-#ifndef USE_ZLIB
-#ifndef UTIL
- /* in crc32.c */
-ulg crc32 OF((ulg, ZCONST uch *, extent));
-#endif /* !UTIL */
-
- /* in crctab.c */
-ZCONST ulg near *get_crc_table OF((void));
-#ifdef DYNALLOC_CRCTAB
-void free_crc_table OF((void));
-#endif
-#endif /* !USE_ZLIB */
+int is_text_buf OF((ZCONST char *buf_ptr, unsigned buf_size));
+/* this is no longer used ...
+unsigned int adler16 OF((unsigned int, ZCONST uch *, extent));
+*/
+ /* crc functions are now declared in crc32.h */
#ifndef UTIL
#ifndef USE_ZLIB
/* in deflate.c */
void lm_init OF((int, ush *));
void lm_free OF((void));
-ulg deflate OF((void));
+
+uzoff_t deflate OF((void));
/* in trees.c */
void ct_init OF((ush *, int *));
int ct_tally OF((int, int));
-ulg flush_block OF((char far *, ulg, int));
+uzoff_t flush_block OF((char far *, ulg, int));
void bi_init OF((char *, unsigned int, int));
#endif /* !USE_ZLIB */
#endif /* !UTIL */
@@ -548,12 +856,21 @@ void bi_init OF((char *, unsigned int, int));
#endif /* !UTIL */
#endif /* VMS */
+/*
+#ifdef ZIP64_SUPPORT
+ update_local_Zip64_extra_field OF((struct zlist far *, FILE *));
+#endif
+*/
/*---------------------------------------------------------------------------
WIN32-only functions:
---------------------------------------------------------------------------*/
#ifdef WIN32
- int ZipIsWinNT OF((void)); /* win32.c */
+ int ZipIsWinNT OF((void)); /* win32.c */
+ int ClearArchiveBit OF((char *)); /* win32.c */
+# ifdef UNICODE_SUPPORT
+ int ClearArchiveBitW OF((wchar_t *)); /* win32.c */
+# endif
#endif /* WIN32 */
#if (defined(WINDLL) || defined(DLL_ZIPAPI))
@@ -563,5 +880,202 @@ void bi_init OF((char *, unsigned int, int));
#include "api.h"
#endif /* WINDLL || DLL_ZIPAPI */
+
+ /* WIN32_OEM */
+#ifdef WIN32
+/*
+# if defined(UNICODE_SUPPORT) || defined(WIN32_OEM)
+*/
+ /* convert oem to ansi string */
+ char *oem_to_local_string OF((char *, char *));
+/*
+# endif
+*/
+#endif
+
+#ifdef WIN32
+/*
+# if defined(UNICODE_SUPPORT) || defined(WIN32_OEM)
+*/
+ /* convert local string to oem string */
+ char *local_to_oem_string OF((char *, char *));
+/*
+# endif
+*/
+#endif
+
+
+
+/*---------------------------------------------------------------------
+ Unicode Support
+ 28 August 2005
+ ---------------------------------------------------------------------*/
+#ifdef UNICODE_SUPPORT
+
+ /* Default character when a zwchar too big for wchar_t */
+# define zwchar_to_wchar_t_default_char '_'
+
+ /* Default character string when wchar_t does not convert to mb */
+# define wide_to_mb_default_string "_"
+
+ /* wide character type */
+ typedef unsigned long zwchar;
+
+ /* check if string is all ASCII */
+ int is_ascii_string OF((char *));
+#ifdef WIN32
+ int is_ascii_stringw OF((wchar_t *));
+ zwchar *wchar_to_wide_string OF((wchar_t *));
+#endif
+
+ /* convert UTF-8 string to multi-byte string */
+ char *utf8_to_local_string OF((char *));
+ char *utf8_to_escape_string OF((char *));
+
+ /* convert UTF-8 string to wide string */
+ zwchar *utf8_to_wide_string OF((char *));
+
+ /* convert wide string to multi-byte string */
+ char *wide_to_local_string OF((zwchar *));
+ char *wide_to_escape_string OF((zwchar *));
+ char *local_to_escape_string OF((char *));
+#ifdef WIN32
+ /* convert UTF-8 to wchar */
+ wchar_t *utf8_to_wchar_string OF ((char *));
+
+ char *wchar_to_local_string OF((wchar_t *));
+#endif
+
+ /* convert local string to multi-byte display string */
+ char *local_to_display_string OF((char *));
+
+ /* convert wide character to escape string */
+ char *wide_char_to_escape_string OF((unsigned long));
+
+#if 0
+ /* convert escape string to wide character */
+ unsigned long escape_string_to_wide OF((char *));
+#endif
+
+ /* convert local to UTF-8 */
+ char *local_to_utf8_string OF ((char *));
+
+ /* convert local to wide string */
+ zwchar *local_to_wide_string OF ((char *));
+
+ /* convert wide string to UTF-8 */
+ char *wide_to_utf8_string OF((zwchar *));
+#ifdef WIN32
+ char *wchar_to_utf8_string OF((wchar_t *));
+#endif
+
+#endif /* UNICODE_SUPPORT */
+
+
+/*---------------------------------------------------
+ * Split archives
+ *
+ * 10/20/05 EG
+ */
+
+#define BFWRITE_DATA 0
+#define BFWRITE_LOCALHEADER 1
+#define BFWRITE_CENTRALHEADER 2
+#define BFWRITE_HEADER 3 /* data descriptor or end records */
+
+size_t bfwrite OF((ZCONST void *buffer, size_t size, size_t count,
+ int));
+
+/* for putlocal() */
+#define PUTLOCAL_WRITE 0
+#define PUTLOCAL_REWRITE 1
+
+
+/*--------------------------------------------------------------------
+ Long option support
+ 23 August 2003
+ See fileio.c
+ --------------------------------------------------------------------*/
+
+/* The below is for use in the caller-provided options table */
+
+/* value_type - value is always returned as a string. */
+#define o_NO_VALUE 0 /* this option does not take a value */
+#define o_REQUIRED_VALUE 1 /* this option requires a value */
+#define o_OPTIONAL_VALUE 2 /* value is optional (see get_option() for details) */
+#define o_VALUE_LIST 3 /* this option takes a list of values */
+#define o_ONE_CHAR_VALUE 4 /* next char is value (does not end short opt string) */
+#define o_NUMBER_VALUE 5 /* value is integer (does not end short opt string) */
+
+
+/* negatable - a dash following the option (but before any value) sets negated. */
+#define o_NOT_NEGATABLE 0 /* trailing '-' to negate either starts value or generates error */
+#define o_NEGATABLE 1 /* trailing '-' sets negated to TRUE */
+
+
+/* option_num can be this when option not in options table */
+#define o_NO_OPTION_MATCH -1
+
+/* special values returned by get_option - do not use these as option IDs */
+#define o_NON_OPTION_ARG ((unsigned long) 0xFFFF) /* returned for non-option
+ args */
+#define o_ARG_FILE_ERR ((unsigned long) 0xFFFE) /* internal recursion
+ return (user never sees) */
+
+/* options array is set in zip.c */
+struct option_struct {
+ char *shortopt; /* char * to sequence of char that is short option */
+ char Far *longopt; /* char * to long option string */
+ int value_type; /* from above */
+ int negatable; /* from above */
+ unsigned long option_ID; /* value returned by get_option when this option is found */
+ char Far *name; /* optional string for option returned on some errors */
+};
+extern struct option_struct far options[];
+
+
+/* moved here from fileio.c to make global - 10/6/05 EG */
+
+/* If will support wide for Unicode then need to add */
+ /* multi-byte */
+#ifdef _MBCS
+# ifndef MULTIBYTE_GETOPTNS
+# define MULTIBYTE_GETOPTNS
+# endif
+#endif
+#ifdef MULTIBYTE_GETOPTNS
+ int mb_clen OF((ZCONST char *));
+# define MB_CLEN(ptr) mb_clen(ptr)
+# define MB_NEXTCHAR(ptr) ((ptr) += MB_CLEN(ptr))
+#else
+ /* no multi-byte */
+# define MB_CLEN(ptr) (1)
+# define MB_NEXTCHAR(ptr) ((ptr)++)
+#endif
+
+
+/* function prototypes */
+
+/* get the next option from args */
+unsigned long get_option OF((char ***pargs, int *argc, int *argnum, int *optchar,
+ char **value, int *negated, int *first_nonopt_arg,
+ int *option_num, int recursion_depth));
+
+/* copy args - copy an args array, allocating space as needed */
+char **copy_args OF((char **args, int max_args));
+
+/* free args - free args created with one of these functions */
+int free_args OF ((char **args));
+
+/* insert arg - copy an arg into args */
+int insert_arg OF ((char ***args, ZCONST char *arg, int insert_at,
+ int free_args));
+
+
+/*--------------------------------------------------------------------
+ End of Long option support
+ --------------------------------------------------------------------*/
+
+
#endif /* !__zip_h */
/* end of zip.h */
diff --git a/zip.txt b/zip.txt
new file mode 100644
index 0000000..85f89b5
--- /dev/null
+++ b/zip.txt
@@ -0,0 +1,2027 @@
+ZIP(1L) ZIP(1L)
+
+NAME
+ zip - package and compress (archive) files
+
+SYNOPSIS
+ zip [-aABcdDeEfFghjklLmoqrRSTuvVwXyz!@$] [--longoption ...] [-b path]
+ [-n suffixes] [-t date] [-tt date] [zipfile [file ...]] [-xi list]
+
+ zipcloak (see separate man page)
+
+ zipnote (see separate man page)
+
+ zipsplit (see separate man page)
+
+ Note: Command line processing in 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.
+
+DESCRIPTION
+ 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 tar(1) and
+ compress(1) and is compatible with PKZIP (Phil Katz's ZIP for MSDOS
+ systems).
+
+ A companion program (unzip(1L)) unpacks zip archives. The zip and
+ 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 zip (with some exceptions, notably
+ streamed archives, but recent changes in the zip file standard may
+ facilitate better compatibility). 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). zip also now supports bzip2 compression if the bzip2
+ library is included when zip is compiled. Note that PKUNZIP 1.10 can-
+ not extract files produced by PKZIP 2.04 or zip 3.0. You must use PKUN-
+ ZIP 2.04g or unzip 5.0p1 (or later versions) to extract them.
+
+ See the EXAMPLES section at the bottom of this page for examples of
+ some typical uses of zip.
+
+ Large Archives and Zip64. zip automatically uses the Zip64 extensions
+ when files larger than 4 GB are added to an archive, an archive con-
+ taining 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 -fz- can be used to force zip 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 unzip 6.0
+ or later, to extract files using the Zip64 extensions.
+
+ In addition, streamed archives, entries encrypted with standard encryp-
+ tion, or split archives created with the pause option may not be com-
+ patible 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 zip uses).
+
+ Mac OS X. Though previous Mac versions had their own zip port, zip
+ 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 zip release.
+
+ For a brief help on zip and unzip, run each without specifying any
+ parameters on the command line.
+
+USE
+ The program is useful for packaging a set of files for distribution;
+ for archiving files; and for saving disk space by temporarily compress-
+ ing unused files or directories.
+
+ The zip program puts one or more compressed files into a single 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 zip
+ archive with a single command. Compression ratios of 2:1 to 3:1 are
+ common for text files. zip has one compression method (deflation) and
+ can also store files without compression. (If bzip2 support is added,
+ zip can also compress using bzip2 compression, but such entries require
+ a reasonably modern unzip to decompress. When bzip2 compression is
+ selected, it replaces deflation as the default method.) zip automati-
+ cally chooses the better of the two (deflation or store or, if bzip2 is
+ selected, bzip2 or store) for each file to be compressed.
+
+ Command format. The basic command format is
+
+ zip options archive inpath inpath ...
+
+ where archive is a new or existing zip archive and inpath is a direc-
+ tory or file path optionally including wildcards. When given the name
+ of an existing zip archive, zip will replace identically named entries
+ in the zip archive (matching the relative names as stored in the
+ archive) or add entries for new names. For example, if foo.zip exists
+ and contains foo/file1 and foo/file2, and the directory foo contains
+ the files foo/file1 and foo/file3, then:
+
+ zip -r foo.zip foo
+
+ or more concisely
+
+ zip -r foo foo
+
+ will replace foo/file1 in foo.zip and add foo/file3 to foo.zip. After
+ this, foo.zip contains foo/file1, foo/file2, and foo/file3, with
+ foo/file2 unchanged from before.
+
+ So if before the zip command is executed foo.zip has:
+
+ foo/file1 foo/file2
+
+ and directory foo has:
+
+ file1 file3
+
+ then foo.zip will have:
+
+ foo/file1 foo/file2 foo/file3
+
+ where foo/file1 is replaced and foo/file3 is new.
+
+ -@ file lists. If a file list is specified as -@ [Not on MacOS], zip
+ takes the list of input files from standard input instead of from the
+ command line. For example,
+
+ zip -@ foo
+
+ will store the files listed one per line on stdin in foo.zip.
+
+ Under Unix, this option can be used to powerful effect in conjunction
+ with the find (1) command. For example, to archive all the C source
+ files in the current directory and its subdirectories:
+
+ find . -name "*.[ch]" -print | zip source -@
+
+ (note that the pattern must be quoted to keep the shell from expanding
+ it).
+
+ Streaming input and output. zip will also accept a single dash ("-")
+ as the zip file name, in which case it will write the zip file to stan-
+ dard output, allowing the output to be piped to another program. For
+ example:
+
+ zip -r - . | dd of=/dev/nrst0 obs=16k
+
+ would write the zip output directly to a tape with the specified block
+ size for the purpose of backing up the current directory.
+
+ zip also accepts a single dash ("-") as the name of a file to be com-
+ pressed, in which case it will read the file from standard input,
+ allowing zip to take input from another program. For example:
+
+ tar cf - . | zip backup -
+
+ 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 zip can take
+ advantage of redundancy between files. The backup can be restored using
+ the command
+
+ unzip -p backup | tar xf -
+
+ When no zip file name is given and stdout is not a terminal, zip acts
+ as a filter, compressing standard input to standard output. For exam-
+ ple,
+
+ tar cf - . | zip | dd of=/dev/nrst0 obs=16k
+
+ is equivalent to
+
+ tar cf - . | zip - - | dd of=/dev/nrst0 obs=16k
+
+ zip archives created in this manner can be extracted with the program
+ funzip which is provided in the unzip package, or by gunzip which is
+ provided in the gzip package (but some gunzip may not support this if
+ zip used the Zip64 extensions). For example:
+
+ dd if=/dev/nrst0 ibs=16k | funzip | tar xvf -
+
+ The stream can also be saved to a file and unzip used.
+
+ If Zip64 support for large files and archives is enabled and zip is
+ used as a filter, zip 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 -fz- can be used to prevent use of Zip64, but zip will exit with
+ an error if Zip64 was in fact needed. zip 3 and unzip 6 and later can
+ read archives with Zip64 entries. Also, zip removes the Zip64 exten-
+ sions if not needed when archive entries are copied (see the -U
+ (--copy) option).
+
+ When directing the output to another file, note that all options should
+ be before the redirection including -x. For example:
+
+ zip archive "*.h" "*.c" -x donotinclude.h orthis.h > tofile
+
+ Zip files. When changing an existing zip archive, 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.
+
+ If the name of the zip archive does not contain an extension, the
+ extension .zip is added. If the name already contains an extension
+ other than .zip, the existing extension is kept unchanged. However,
+ split archives (archives split over multiple files) require the .zip
+ extension on the last split.
+
+ Scanning and reading files. When zip starts, it scans for files to
+ process (if needed). If this scan takes longer than about 5 seconds,
+ zip 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 updat-
+ ing an existing archive, a space also appears between the existing file
+ scan and the new file scan.) The scanning files dots are not con-
+ trolled by the -ds dot size option, but the dots are turned off by the
+ -q quiet option. The -sf show files option can be used to scan for
+ files and get the list of files scanned without actually processing
+ them.
+
+ If zip is not able to read a file, it issues a warning but continues.
+ See the -MM option below for more on how zip 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.
+
+ Command modes. zip now supports two distinct types of command modes,
+ external and internal. The external modes (add, update, and freshen)
+ read files from the file system (as well as from an existing archive)
+ while the internal modes (delete and copy) operate exclusively on
+ entries in an existing archive.
+
+ add
+ Update existing entries and add new files. If the archive does
+ not exist create it. This is the default mode.
+
+ update (-u)
+ 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.
+
+ freshen (-f)
+ Update existing entries of an archive if newer on the file sys-
+ tem. Does not add new files to the archive.
+
+ delete (-d)
+ Select entries in an existing archive and delete them.
+
+ copy (-U)
+ Select entries in an existing archive and copy them to a new
+ archive. This new mode is similar to update but command line
+ patterns select entries in the existing archive rather than
+ files from the file system and it uses the --out option to write
+ the resulting archive to a new file rather than update the
+ existing archive, leaving the original archive unchanged.
+
+ The new File Sync option (-FS) is also considered a new mode, though it
+ is similar to update. 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 -DF for creating difference archives.
+
+ See each option description below for details and the EXAMPLES section
+ below for examples.
+
+ Split archives. zip version 3.0 and later can create split archives.
+ A split archive 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. Con-
+ catenating the pieces together will invalidate these offsets, but unzip
+ can usually deal with it. zip will usually refuse to process such a
+ spliced archive unless the -FF fix option is used to fix the offsets.)
+
+ One use of split archives is storing a large archive on multiple remov-
+ able media. For a split archive with 20 split files the files are typ-
+ ically named (replace ARCHIVE with the name of your archive)
+ ARCHIVE.z01, ARCHIVE.z02, ..., ARCHIVE.z19, ARCHIVE.zip. Note that the
+ last file is the .zip file. In contrast, spanned archives are the
+ original multi-disk archive generally requiring floppy disks and using
+ volume labels to store disk numbers. zip 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.
+
+ Use -s 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 -sp option can be used to pause zip
+ between splits to allow changing removable media, for example, but read
+ the descriptions and warnings for both -s and -sp below.
+
+ Though zip does not update split archives, zip provides the new option
+ -O (--output-file or --out) to allow split archives to be updated and
+ saved in a new archive. For example,
+
+ zip inarchive.zip foo.c bar.c --out outarchive.zip
+
+ reads archive inarchive.zip, even if split, adds the files foo.c and
+ bar.c, and writes the resulting archive to outarchive.zip. If inar-
+ chive.zip is split then outarchive.zip defaults to the same split size.
+ Be aware that if outarchive.zip 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.
+
+ Unicode. 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 sup-
+ port wide characters, zip 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 rep-
+ resented in the local character set, it's possible that some paths will
+ be skipped during a local character set directory scan. zip with Uni-
+ code support now can read and store these paths. Note that Win 9x sys-
+ tems 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.
+
+ Command line format. This version of zip has updated command line pro-
+ cessing and support for long options.
+
+ Short options take the form
+
+ -s[-][s[-]...][value][=value][ value]
+
+ 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
+
+ -s[-][value][=value][ value] -s[-][value][=value][ value] ...
+
+ Short options in general take values either as part of the same argu-
+ ment or as the following argument. An optional = is also supported.
+ So
+
+ -ttmmddyyyy
+
+ and
+
+ -tt=mmddyyyy
+
+ and
+
+ -tt mmddyyyy
+
+ all work. The -x and -i options accept lists of values and use a
+ slightly different format described below. See the -x and -i options.
+
+ Long options take the form
+
+ --longoption[-][=value][ value]
+
+ 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
+
+ --before-date=mmddyyyy
+
+ and
+
+ --before-date mmddyyyy
+
+ 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 con-
+ sider a trailing dash, such as for the option --some-option using
+ --some- as the option, as part of the name rather than a negating
+ dash). This may be changed to force the last dash in --some- to be
+ negating in the future.
+
+OPTIONS
+ -a
+ --ascii
+ [Systems using EBCDIC] Translate file to ASCII format.
+
+ -A
+ --adjust-sfx
+ Adjust self-extracting executable archive. A self-extracting
+ executable archive is created by prepending the SFX stub to an
+ existing archive. The -A option tells zip to adjust the entry
+ offsets stored in the archive to take into account this "pream-
+ ble" data.
+
+ Note: self-extracting archives for the Amiga are a special case. At
+ present, only the Amiga port of zip 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.
+
+ -AC
+ --archive-clear
+ [WIN32] Once archive is created (and tested if -T is used,
+ which is recommended), clear the archive bits of files pro-
+ cessed. WARNING: Once the bits are cleared they are cleared.
+ You may want to use the -sf show files option to store the list
+ of files processed in case the archive operation must be
+ repeated. Also consider using the -MM must match option. Be
+ sure to check out -DF as a possibly better way to do incremental
+ backups.
+
+ -AS
+ --archive-set
+ [WIN32] Only include files that have the archive bit set.
+ Directories are not stored when -AS 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 -AC, -AS 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. Alterna-
+ tive ways to create incremental backups are using -t to use file
+ dates, though this won't catch old files copied to directories
+ being archived, and -DF to create a differential archive.
+
+ -B
+ --binary
+ [VM/CMS and MVS] force file to be read binary (default is text).
+
+ -Bn [TANDEM] set Edit/Enscribe formatting options with n defined as
+ bit 0: Don't add delimiter (Edit/Enscribe)
+ bit 1: Use LF rather than CR/LF as delimiter (Edit/Enscribe)
+ bit 2: Space fill record to maximum record length (Enscribe)
+ bit 3: Trim trailing space (Enscribe)
+ bit 8: Force 30K (Expand) large read for unstructured files
+
+ -b path
+ --temp-path path
+ Use the specified path for the temporary zip archive. For exam-
+ ple:
+
+ zip -b /tmp stuff *
+
+ will put the temporary zip archive in the directory /tmp, copy-
+ ing over 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 zip take
+ additional time to copy the archive file when done to the desti-
+ nation file system.
+
+ -c
+ --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.
+
+ -C
+ --preserve-case
+ [VMS] Preserve case all on VMS. Negating this option (-C-)
+ downcases.
+
+ -C2
+ --preserve-case-2
+ [VMS] Preserve case ODS2 on VMS. Negating this option (-C2-)
+ downcases.
+
+ -C5
+ --preserve-case-5
+ [VMS] Preserve case ODS5 on VMS. Negating this option (-C5-)
+ downcases.
+
+ -d
+ --delete
+ Remove (delete) entries from a zip archive. For example:
+
+ zip -d foo foo/tom/junk foo/harry/\* \*.o
+
+ will remove the entry foo/tom/junk, all of the files that start
+ with foo/harry/, and all of the files that end with .o (in any
+ path). Note that shell pathname expansion has been inhibited
+ with backslashes, so that zip can see the asterisks, enabling
+ zip to match on the contents of the 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
+
+ zip -d foo foo/tom/junk "foo/harry/*" "*.o"
+
+ 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.
+
+ Under MSDOS, -d is case sensitive when it matches names in the
+ zip archive. This requires that file names be entered in upper
+ case if they were zipped by PKZIP on an MSDOS system. (We con-
+ sidered 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
+ Bar and bar as separate files in the archive.) But see the new
+ option -ic to ignore case in the archive.
+
+ -db
+ --display-bytes
+ Display running byte counts showing the bytes zipped and the
+ bytes to go.
+
+ -dc
+ --display-counts
+ Display running count of entries zipped and entries to go.
+
+ -dd
+ --display-dots
+ Display dots while each entry is zipped (except on ports that
+ have their own progress indicator). See -ds below for setting
+ dot size. The default is a dot every 10 MB of input file pro-
+ cessed. The -v option also displays dots (previously at a much
+ higher rate than this but now -v also defaults to 10 MB) and
+ this rate is also controlled by -ds.
+
+ -df
+ --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.
+
+ -dg
+ --display-globaldots
+ Display progress dots for the archive instead of for each file.
+ The command
+
+ zip -qdgds 10m
+
+ will turn off most output except dots every 10 MB.
+
+ -ds size
+ --dot-size size
+ Set amount of input file processed for each dot displayed. See
+ -dd to enable displaying dots. Setting this option implies -dd.
+ Size is in the format nm where n is a number and m is a multi-
+ plier. 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.
+
+ The -v 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.
+
+ This option does not control the dots from the "Scanning files"
+ message as zip scans for input files. The dot size for that is
+ fixed at 2 seconds or a fixed number of entries, whichever is
+ longer.
+
+ -du
+ --display-usize
+ Display the uncompressed size of each entry.
+
+ -dv
+ --display-volume
+ Display the volume (disk) number each entry is being read from,
+ if reading an existing archive, and being written to.
+
+ -D
+ --no-dir-entries
+ Do not create entries in the 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:
+
+ ZIPOPT="-D"; export ZIPOPT
+
+ (The variable ZIPOPT can be used for any option, including -i
+ and -x using a new option format detailed below, and can include
+ several options.) The option -D is a shorthand for -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.
+
+ This version of zip does allow -x and -i options in ZIPOPT if
+ the form
+
+ -x file file ... @
+
+ is used, where the @ (an argument that is just @) terminates the
+ list.
+
+ -DF
+ --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 zip operation.
+
+ For example, if the existing archive was created using
+
+ zip -r foofull .
+
+ from the bar directory, then the command
+
+ zip -r foofull . -DF --out foonew
+
+ also from the bar directory creates the archive foonew with just
+ the files not in foofull and the files where the size or file
+ time of the files do not match those in foofull.
+
+ 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.
+
+ -e
+ --encrypt
+ Encrypt the contents of the 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, zip will exit
+ with an error). The password prompt is repeated to save the
+ user from typing errors.
+
+ -E
+ --longnames
+ [OS/2] Use the .LONGNAME Extended Attribute (if found) as file-
+ name.
+
+ -f
+ --freshen
+ Replace (freshen) an existing entry in the zip archive only if
+ it has been modified more recently than the version already in
+ the zip archive; unlike the update option (-u) this will not add
+ files that are not already in the zip archive. For example:
+
+ zip -f foo
+
+ This command should be run from the same directory from which
+ the original zip command was run, since paths stored in zip
+ archives are always relative.
+
+ Note that the timezone environment variable TZ should be set
+ according to the local timezone in order for the -f, -u and -o
+ options to work correctly.
+
+ 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).
+
+ 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.
+
+ -F
+ --fix
+ -FF
+ --fixfix
+ Fix the zip archive. The -F 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
+ zip will ignore some problems. The resulting archive should be
+ valid, but any inconsistent entries will be left out.
+
+ When doubled as in -FF, the archive is scanned from the begin-
+ ning and zip scans for special signatures to identify the limits
+ between the archive members. The single -F is more reliable if
+ the archive is not too much damaged, so try this option first.
+
+ If the archive is too damaged or the end has been truncated, you
+ must use -FF. This is a change from zip 2.32, where the -F
+ option is able to read a truncated archive. The -F option now
+ more reliably fixes archives with minor damage and the -FF
+ option is needed to fix archives where -F might have been suffi-
+ cient before.
+
+ Neither option will recover archives that have been incorrectly
+ transferred in ascii mode instead of binary. After the repair,
+ the -t option of unzip may show that some files have a bad CRC.
+ Such files cannot be recovered; you can remove them from the
+ archive using the -d option of zip.
+
+ Note that -FF 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 -F first as it does not have this problem.
+
+ The format of the fix commands have changed. For example, to
+ fix the damaged archive foo.zip,
+
+ zip -F foo --out foofix
+
+ tries to read the entries normally, copying good entries to the
+ new archive foofix.zip. 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
+
+ zip -FF foo --out foofixfix
+
+ and compare the resulting archive to the archive created by -F.
+ The -FF option may create an inconsistent archive. Depending on
+ what is damaged, you can then use the -F option to fix that
+ archive.
+
+ A split archive with missing split files can be fixed using -F
+ if you have the last split of the archive (the .zip file). If
+ this file is missing, you must use -FF to fix the archive, which
+ will prompt you for the splits you have.
+
+ Currently the fix options can't recover entries that have a bad
+ checksum or are otherwise damaged.
+
+ -FI
+ --fifo [Unix] Normally zip skips reading any FIFOs (named pipes)
+ encountered, as zip can hang if the FIFO is not being fed. This
+ option tells zip to read the contents of any FIFO it finds.
+
+ -FS
+ --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
+ -FS can be much faster than creating a new archive. Also con-
+ sider using -u for updating an archive.
+
+ 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.
+
+ 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.
+
+ This option deletes files from the archive. If you need to pre-
+ serve the original archive, make a copy of the archive first or
+ use the --out 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.
+
+ -g
+ --grow
+ Grow (append to) the specified zip archive, instead of creating
+ a new one. If this operation fails, 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.
+
+ -h
+ -?
+ --help
+ Display the zip help information (this also appears if zip is
+ run with no arguments).
+
+ -h2
+ --more-help
+ Display extended help including more on command line format,
+ pattern matching, and more obscure options.
+
+ -i files
+ --include files
+ Include only the specified files, as in:
+
+ zip -r foo . -i \*.c
+
+ which will include only the files that end in .c in the current
+ directory and its subdirectories. (Note for PKZIP users: the
+ equivalent command is
+
+ pkzip -rP foo *.c
+
+ PKZIP does not allow recursion in directories other than the
+ current one.) The backslash avoids the shell filename substitu-
+ tion, so that the name matching is performed by 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
+
+ zip -r foo . -i *.c
+
+ Examples are for Unix unless otherwise specified.] So to
+ include dir, a directory directly under the current directory,
+ use
+
+ zip -r foo . -i dir/\*
+
+ or
+
+ zip -r foo . -i "dir/*"
+
+ 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
+
+ zip -r foo . -i dir/*
+
+ is used.] Note that currently the trailing / is needed for
+ directories (as in
+
+ zip -r foo . -i dir/
+
+ to include directory dir).
+
+ The long option form of the first example is
+
+ zip -r foo . --include \*.c
+
+ and does the same thing as the short option form.
+
+ Though the command syntax used to require -i at the end of the
+ command line, this version actually allows -i (or --include)
+ anywhere. The list of files terminates at the next argument
+ starting with -, the end of the command line, or the list termi-
+ nator @ (an argument that is just @). So the above can be given
+ as
+
+ zip -i \*.c @ -r foo .
+
+ 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
+
+ zip -i\*.c -r foo .
+
+ (no space between option and value) or
+
+ zip --include=\*.c -r foo .
+
+ as additional examples. The single value forms are not recom-
+ mended because they can be confusing and, in particular, the
+ -ifile format can cause problems if the first letter of file
+ combines with i to form a two-letter option starting with i.
+ Use -sc to see how your command line will be parsed.
+
+ Also possible:
+
+ zip -r foo . -i@include.lst
+
+ which will only include the files in the current directory and
+ its subdirectories that match the patterns in the file
+ include.lst.
+
+ Files to -i and -x are patterns matching internal archive paths.
+ See -R for more on patterns.
+
+ -I
+ --no-image
+ [Acorn RISC OS] Don't scan through Image files. When used, 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.
+
+ For example, if you have SparkFS loaded, zipping a Spark archive
+ will result in a zipfile containing a directory (and its con-
+ tent) while using the 'I' option will result in a zipfile con-
+ taining a Spark archive. Obviously this second case will also be
+ obtained (without the 'I' option) if SparkFS isn't loaded.
+
+ -ic
+ --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 simi-
+ lar 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 -ic option makes all matching
+ case insensitive. This can result in multiple archive entries
+ matching a command line pattern.
+
+ -j
+ --junk-paths
+ Store just the name of a saved file (junk the path), and do not
+ store directory names. By default, zip will store the full path
+ (relative to the current directory).
+
+ -jj
+ --absolute-path
+ [MacOS] record Fullpath (+ Volname). The complete path including
+ volume will be stored. By default the relative path will be
+ stored.
+
+ -J
+ --junk-sfx
+ Strip any prepended data (e.g. a SFX stub) from the archive.
+
+ -k
+ --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.
+
+ -l
+ --to-crlf
+ Translate the Unix end-of-line character LF into the MSDOS con-
+ vention 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 unzip -a on
+ Unix will get back an exact copy of the original file, to undo
+ the effect of zip -l. See -ll for how binary files are handled.
+
+ -la
+ --log-append
+ Append to existing logfile. Default is to overwrite.
+
+ -lf logfilepath
+ --logfile-path logfilepath
+ Open a logfile at the given path. By default any existing file
+ at that location is overwritten, but the -la 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 -li option is also given, then
+ all information messages are also written to the log.
+
+ -li
+ --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.
+
+ -ll
+ --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 -ll detects binary in the first buffer read from a
+ file, zip 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 UTF-8 and similar
+ encodings.
+
+ -L
+ --license
+ Display the zip license.
+
+ -m
+ --move
+ Move the specified files into the zip archive; actually, this
+ deletes the target directories/files after making the specified
+ zip archive. If a directory becomes empty after removal of the
+ files, the directory is also removed. No deletions are done
+ until 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 -T to test the archive
+ before removing all input files.
+
+ -MM
+ --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 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 zip returns the OPEN error code (18
+ on most systems) instead of the normal success return (0 on most
+ systems). With -MM set, 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
+ zip exits with an OPEN error and no archive is created.
+
+ 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 zip 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 -MM and just check the return code. Also -lf
+ could be useful.
+
+ -n suffixes
+ --suffixes suffixes
+ Do not attempt to compress files named with the given suffixes.
+ Such files are simply stored (0% compression) in the output zip
+ file, so that zip doesn't waste its time trying to compress
+ them. The suffixes are separated by either colons or semi-
+ colons. For example:
+
+ zip -rn .Z:.zip:.tiff:.gif:.snd foo foo
+
+ will copy everything from foo into foo.zip, but will store any
+ files that end in .Z, .zip, .tiff, .gif, or .snd without trying
+ to compress them (image and sound files often have their own
+ specialized compression methods). By default, zip does not com-
+ press files with extensions in the list
+ .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:
+
+ setenv ZIPOPT "-n .gif:.zip"
+
+ To attempt compression on all files, use:
+
+ zip -n : foo
+
+ The maximum compression option -9 also attempts compression on
+ all files regardless of extension.
+
+ On Acorn RISC OS systems the suffixes are actually filetypes (3
+ hex digit format). By default, zip does not compress files with
+ filetypes in the list DDC:D96:68E (i.e. Archives, CFS files and
+ PackDir files).
+
+ -nw
+ --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 wild-
+ card substitution is desired.
+
+ -N
+ --notes
+ [Amiga, MacOS] Save Amiga or MacOS filenotes as zipfile com-
+ ments. They can be restored by using the -N option of unzip. If
+ -c is used also, you are prompted for comments only for those
+ files that do not have filenotes.
+
+ -o
+ --latest-time
+ Set the "last modified" time of the zip archive to the latest
+ (oldest) "last modified" time found among the entries in the zip
+ archive. This can be used without any other operations, if
+ desired. For example:
+
+ zip -o foo
+
+ will change the last modified time of foo.zip to the latest time
+ of the entries in foo.zip.
+
+ -O output-file
+ --output-file output-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 -U to copy entries from an existing
+ archive to a new archive. See the EXAMPLES section below.
+
+ Another use is converting zip 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:
+
+ zip -s 2g cd-split.zip --out dvd-split.zip
+
+ which uses copy mode. See -U below. Also:
+
+ zip -s 0 split.zip --out unsplit.zip
+
+ 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, zipcloak will decrypt the entries and convert them to
+ normal entries.
+
+ -p
+ --paths
+ Include relative file paths as part of the names of files stored
+ in the archive. This is the default. The -j option junks the
+ paths and just stores the names of the files.
+
+ -P password
+ --password password
+ Use password to encrypt zipfile entries (if any). THIS IS INSE-
+ CURE! 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 pass-
+ words. (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.)
+
+ -q
+ --quiet
+ Quiet mode; eliminate informational messages and comment
+ prompts. (Useful, for example, in shell scripts and background
+ tasks).
+
+ -Qn
+ --Q-flag n
+ [QDOS] store information about the file in the file header with
+ n defined as
+ bit 0: Don't add headers for any file
+ bit 1: Add headers for all files
+ bit 2: Don't wait for interactive key press on exit
+
+ -r
+ --recurse-paths
+ Travel the directory structure recursively; for example:
+
+ zip -r foo.zip foo
+
+ or more concisely
+
+ zip -r foo foo
+
+ In this case, all the files and directories in foo are saved in
+ a zip archive named foo.zip, including files with names starting
+ with ".", 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 foo and its subdirectories, use
+ the -i option to specify the pattern of files to be included.
+ You should not use -r with the name ".*", since that matches
+ ".." which will attempt to zip up the parent directory (proba-
+ bly not what was intended).
+
+ Multiple source directories are allowed as in
+
+ zip -r foo foo1 foo2
+
+ which first zips up foo1 and then foo2, going down each direc-
+ tory.
+
+ Note that while wildcards to -r are typically resolved while
+ recursing down directories in the file system, any -R, -x, and
+ -i 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 wild-
+ cards or put all arguments with wildcards in quotes. This lets
+ zip see the wildcards and match files in subdirectories using
+ them as it recurses.
+
+ -R
+ --recurse-patterns
+ Travel the directory structure recursively starting at the cur-
+ rent directory; for example:
+
+ zip -R foo "*.c"
+
+ In this case, all the files matching *.c in the tree starting at
+ the current directory are stored into a zip archive named
+ foo.zip. Note that *.c will match file.c, a/file.c and a/b/.c.
+ More than one pattern can be listed as separate arguments. Note
+ for PKZIP users: the equivalent command is
+
+ pkzip -rP foo *.c
+
+ 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 foo and under it are
+ directories foo1 and foo2 and in foo1 is the file bar.c,
+
+ zip -R foo/*
+
+ will zip up foo, foo/foo1, foo/foo1/bar.c, and foo/foo2.
+
+ zip -R */bar.c
+
+ will zip up foo/foo1/bar.c. See the note for -r on escaping
+ wildcards.
+
+ -RE
+ --regex
+ [WIN32] Before zip 3.0, 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.
+
+ -s splitsize
+ --split-size splitsize
+ 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 archive and three splits are
+ required, the resulting archive will be in the three files
+ archive.z01, archive.z02, and archive.zip. 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 k (kilobytes), m (megabytes), g (gigabytes),
+ or t (terabytes). As 64k is the minimum split size, numbers
+ without multipliers default to megabytes. For example, to cre-
+ ate a split archive called foo with the contents of the bar
+ directory with splits of 670 MB that might be useful for burning
+ on CDs, the command:
+
+ zip -s 670m -r foo bar
+
+ 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 -s without -sp as above creates all the splits where foo
+ 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 -sp below for enabling split pause mode which
+ allows splits to be written directly to removable media.
+
+ The option -sv can be used to enable verbose splitting and pro-
+ vide details of how the splitting is being done. The -sb option
+ can be used to ring the bell when zip pauses for the next split
+ destination.
+
+ Split archives cannot be updated, but see the -O (--out) 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 -s option:
+
+ zip -s 0 split.zip --out single.zip
+
+ Also see -U (--copy) for more on using copy mode.
+
+ -sb
+ --split-bell
+ If splitting and using split pause mode, ring the bell when zip
+ pauses for each split destination.
+
+ -sc
+ --show-command
+ Show the command line starting zip as processed and exit. The
+ new command parser permutes the arguments, putting all options
+ and any values associated with them before any non-option argu-
+ ments. 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 zip sees it, including
+ any arguments from the environment such as from the ZIPOPT vari-
+ able. Where allowed, options later in the command line can
+ override options earlier in the command line.
+
+ -sf
+ --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, -sf-, output
+ only to an open log file. Screen display is not recommended for
+ large lists.
+
+ -so
+ --show-options
+ Show all available options supported by zip 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.
+
+ -sp
+ --split-pause
+ If splitting is enabled with -s, enable split pause mode. This
+ creates split archives as -s does, but stream writing is used so
+ each split can be closed as soon as it is written and zip will
+ pause between each split to allow changing split destination or
+ media.
+
+ Though this split mode allows writing splits directly to remov-
+ able media, it uses stream archive format that may not be read-
+ able by some unzips. Before relying on splits created with -sp,
+ test a split archive with the unzip you will be using.
+
+ To convert a stream split archive (created with -sp) to a stan-
+ dard archive see the --out option.
+
+ -su
+ --show-unicode
+ As -sf, but also show Unicode version of the path if exists.
+
+ -sU
+ --show-just-unicode
+ As -sf, but only show Unicode version of the path if exists,
+ otherwise show the standard version of the path.
+
+ -sv
+ --split-verbose
+ Enable various verbose messages while splitting, showing how the
+ splitting is being done.
+
+ -S
+ --system-hidden
+ [MSDOS, OS/2, WIN32 and ATARI] Include system and hidden files.
+ [MacOS] Includes finder invisible files, which are ignored oth-
+ erwise.
+
+ -t mmddyyyy
+ --from-date mmddyyyy
+ Do not operate on files modified prior to the specified date,
+ where mm is the month (00-12), dd is the day of the month
+ (01-31), and yyyy is the year. The ISO 8601 date format
+ yyyy-mm-dd is also accepted. For example:
+
+ zip -rt 12071991 infamy foo
+
+ zip -rt 1991-12-07 infamy foo
+
+ will add all the files in foo and its subdirectories that were
+ last modified on or after 7 December 1991, to the zip archive
+ infamy.zip.
+
+ -tt mmddyyyy
+ --before-date mmddyyyy
+ Do not operate on files modified after or at the specified date,
+ where mm is the month (00-12), dd is the day of the month
+ (01-31), and yyyy is the year. The ISO 8601 date format
+ yyyy-mm-dd is also accepted. For example:
+
+ zip -rtt 11301995 infamy foo
+
+ zip -rtt 1995-11-30 infamy foo
+
+ will add all the files in foo and its subdirectories that were
+ last modified before 30 November 1995, to the zip archive
+ infamy.zip.
+
+ -T
+ --test
+ Test the integrity of the new zip file. If the check fails, the
+ old zip file is unchanged and (with the -m option) no input
+ files are removed.
+
+ -TT cmd
+ --unzip-command cmd
+ Use command cmd instead of 'unzip -tqq' to test an archive when
+ the -T option is used. On Unix, to use a copy of unzip in the
+ current directory instead of the standard system unzip, could
+ use:
+
+ zip archive file1 file2 -T -TT "./unzip -tqq"
+
+ 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).
+
+ -u
+ --update
+ Replace (update) an existing entry in the zip archive only if it
+ has been modified more recently than the version already in the
+ zip archive. For example:
+
+ zip -u stuff *
+
+ will add any new files in the current directory, and update any
+ files which have been modified since the zip archive stuff.zip
+ was last created/modified (note that zip will not try to pack
+ stuff.zip into itself when you do this).
+
+ Note that the -u option with no input file arguments acts like
+ the -f (freshen) option.
+
+ -U
+ --copy-entries
+ Copy entries from one archive to another. Requires the --out
+ option to specify a different output file than the input
+ archive. Copy mode is the reverse of -d delete. When delete is
+ being used with --out, 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 -u update, input patterns on the command line are matched
+ against archive entries only and not the file system files. For
+ instance,
+
+ zip inarchive "*.c" --copy --out outarchive
+
+ copies entries with names ending in .c from inarchive to out-
+ archive. The wildcard must be escaped on some systems to pre-
+ vent 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 --out is used,
+ copy mode is assumed:
+
+ zip inarchive --out outarchive
+
+ This is useful for changing split size for instance. Encrypting
+ and decrypting entries is not yet supported using copy mode.
+ Use zipcloak for that.
+
+ -UN v
+ --unicode v
+ Determine what zip should do with Unicode file names. zip 3.0,
+ 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, zip 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 zip is reading an archive, if an entry also has a Unicode
+ path, zip 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 zip 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 zip uses
+ that. Values for v are
+
+ q - quit if paths do not match
+
+ w - warn, continue with standard path
+
+ i - ignore, continue with standard path
+
+ n - no Unicode, do not use Unicode paths
+
+ The default is to warn and continue.
+
+ Characters that are not valid in the current character set are
+ escaped as #Uxxxx and #Lxxxxxx, 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 Uni-
+ code character code. Setting -UN to
+
+ e - escape
+
+ as in
+
+ zip archive -sU -UN=e
+
+ forces zip to escape all characters that are not printable 7-bit
+ ASCII.
+
+ Normally zip 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
+
+ u - UTF-8
+
+ as in
+
+ zip archive dir -r -UN=UTF8
+
+ forces zip to store UTF-8 as native in the archive. Note that
+ storing UTF-8 directly is the default on Unix systems that sup-
+ port 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.
+
+ -v
+ --verbose
+ Verbose mode or print diagnostic version info.
+
+ Normally, when applied to real operations, this option enables
+ the display of a progress indicator during compression (see -dd
+ for more on dots) and requests verbose diagnostic info about
+ zipfile structure oddities.
+
+ However, when -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 distribu-
+ tion 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 zip executable).
+
+ -V
+ --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.
+
+ -VV
+ --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 cor-
+ rupt.
+
+ -w
+ --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.
+
+ -ww
+ --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.
+
+ -ws
+ --wild-stop-dirs
+ Wildcards match only at a directory level. Normally zip handles
+ paths as strings and given the paths
+
+ /foo/bar/dir/file1.c
+
+ /foo/bar/file2.c
+
+ an input pattern such as
+
+ /foo/bar/*
+
+ normally would match both paths, the * matching dir/file1.c and
+ file2.c. Note that in the first case a directory boundary (/)
+ was crossed in the match. With -ws no directory bounds will be
+ included in the match, making wildcards local to a specific
+ directory level. So, with -ws enabled, only the second path
+ would be matched.
+
+ When using -ws, use ** to match across directory boundaries as *
+ does normally.
+
+ -x files
+ --exclude files
+ Explicitly exclude the specified files, as in:
+
+ zip -r foo foo -x \*.o
+
+ which will include the contents of foo in foo.zip while exclud-
+ ing all the files that end in .o. The backslash avoids the
+ shell filename substitution, so that the name matching is per-
+ formed by zip at all directory levels.
+
+ Also possible:
+
+ zip -r foo foo -x@exclude.lst
+
+ which will include the contents of foo in foo.zip while exclud-
+ ing all the files that match the patterns in the file
+ exclude.lst.
+
+ The long option forms of the above are
+
+ zip -r foo foo --exclude \*.o
+
+ and
+
+ zip -r foo foo --exclude @exclude.lst
+
+ Multiple patterns can be specified, as in:
+
+ zip -r foo foo -x \*.o \*.c
+
+ If there is no space between -x and the pattern, just one value
+ is assumed (no list):
+
+ zip -r foo foo -x\*.o
+
+ See -i for more on include and exclude.
+
+ -X
+ --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 zip 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 -X, zip strips all old fields and only includes the Unicode
+ and Zip64 extra fields (currently these two extra fields cannot
+ be disabled).
+
+ Negating this option, -X-, includes all the default extra
+ fields, but also copies over any unrecognized extra fields.
+
+ -y
+ --symlinks
+ For UNIX and VMS (V8.3 and later), store symbolic links as such
+ in the 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 zip recurses the direc-
+ tory trees and accesses files directly and by links.
+
+ -z
+ --archive-comment
+ Prompt for a multi-line comment for the entire 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:
+
+ zip -z foo < foowhat
+
+ -Z cm
+ --compression-method cm
+ Set the default compression method. Currently the main methods
+ supported by zip are store and deflate. Compression method can
+ be set to:
+
+ store - Setting the compression method to store forces zip 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 -0 (compression level zero).
+
+ deflate - This is the default method for zip. If zip determines
+ that storing is better than deflation, the entry will be stored
+ instead.
+
+ bzip2 - If bzip2 support is compiled in, this compression method
+ also becomes available. Only some modern unzips currently sup-
+ port the bzip2 compression method, so test the unzip you will be
+ using before relying on archives using this method (compression
+ method 12).
+
+ For example, to add bar.c to archive foo using bzip2 compres-
+ sion:
+
+ zip -Z bzip2 foo bar.c
+
+ The compression method can be abbreviated:
+
+ zip -Zb foo bar.c
+
+ -#
+ (-0, -1, -2, -3, -4, -5, -6, -7, -8, -9)
+ Regulate the speed of compression using the specified digit #,
+ where -0 indicates no compression (store all files), -1 indi-
+ cates the fastest compression speed (less compression) and -9
+ indicates the slowest compression speed (optimal compression,
+ ignores the suffix list). The default compression level is -6.
+
+ Though still being worked, the intention is this setting will
+ control compression speed for all compression methods. Cur-
+ rently only deflation is controlled.
+
+ -!
+ --use-privileges
+ [WIN32] Use priviliges (if granted) to obtain all aspects of
+ WinNT security.
+
+ -@
+ --names-stdin
+ Take the list of input files from standard input. Only one file-
+ name per line.
+
+ -$
+ --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:
+
+ zip -$ foo a: c:bar
+
+EXAMPLES
+ The simplest example:
+
+ zip stuff *
+
+ creates the archive stuff.zip (assuming it does not exist) and puts all
+ the files in the current directory in it, in compressed form (the .zip
+ suffix is added automatically, unless the archive name contains a dot
+ already; this allows the explicit specification of other suffixes).
+
+ Because of the way the shell on Unix does filename substitution, files
+ starting with "." are not included; to include these as well:
+
+ zip stuff .* *
+
+ Even this will not include any subdirectories from the current direc-
+ tory.
+
+ To zip up an entire directory, the command:
+
+ zip -r foo foo
+
+ creates the archive foo.zip, containing all the files and directories
+ in the directory foo that is contained within the current directory.
+
+ You may want to make a zip archive that contains the files in foo,
+ without recording the directory name, foo. You can use the -j option
+ to leave off the paths, as in:
+
+ zip -j foo foo/*
+
+ If you are short on disk space, you might not have enough room to hold
+ both the original directory and the corresponding compressed zip
+ archive. In this case, you can create the archive in steps using the
+ -m option. If foo contains the subdirectories tom, dick, and harry,
+ you can:
+
+ zip -rm foo foo/tom
+ zip -rm foo foo/dick
+ zip -rm foo foo/harry
+
+ where the first command creates foo.zip, and the next two add to it.
+ At the completion of each zip command, the last created archive is
+ deleted, making room for the next zip command to function.
+
+ Use -s 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
+
+ zip -s 2g -r split.zip foo
+
+ 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.
+
+ The -sp option can be used to pause zip between splits to allow chang-
+ ing removable media, for example, but read the descriptions and warn-
+ ings for both -s and -sp below.
+
+ Though zip does not update split archives, zip provides the new option
+ -O (--output-file) to allow split archives to be updated and saved in a
+ new archive. For example,
+
+ zip inarchive.zip foo.c bar.c --out outarchive.zip
+
+ reads archive inarchive.zip, even if split, adds the files foo.c and
+ bar.c, and writes the resulting archive to outarchive.zip. If inar-
+ chive.zip is split then outarchive.zip defaults to the same split size.
+ Be aware that outarchive.zip and any split files that are created with
+ it are always overwritten without warning. This may be changed in the
+ future.
+
+PATTERN MATCHING
+ This section applies only to Unix. Watch this space for details on
+ MSDOS and VMS operation. However, the special wildcard characters *
+ and [] below apply to at least MSDOS also.
+
+ The Unix shells (sh, csh, bash, and others) normally do filename sub-
+ stitution (also called "globbing") on command arguments. Generally the
+ special characters are:
+
+ ? match any single character
+
+ * match any number of characters (including none)
+
+ [] 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:
+
+ zip archive "*.[hc]"
+
+ would archive all files in the current directory that end in .h
+ or .c.
+
+ Ranges of characters are supported:
+
+ zip archive "[a-f]*"
+
+ 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 ! or ^
+ to the beginning of the list:
+
+ zip archive "*.[!o]"
+
+ 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.
+
+ 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.
+
+ The zip program can do the same matching on names that are in the zip
+ archive being modified or, in the case of the -x (exclude) or -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 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 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 -x option, or does not
+ match any name given with the -i option.
+
+ 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 ("").
+
+ In general, use backslashes or double quotes for paths that have wild-
+ cards to make zip do the pattern matching for file paths, and always
+ for paths and strings that have spaces or wildcards for -i, -x, -R, -d,
+ and -U and anywhere zip needs to process the wildcards.
+
+ENVIRONMENT
+ The following environment variables are read and used by zip as
+ described.
+
+ ZIPOPT
+ contains default options that will be used when running zip.
+ The contents of this environment variable will get added to the
+ command line just after the zip command.
+
+ ZIP
+ [Not on RISC OS and VMS] see ZIPOPT
+
+ Zip$Options
+ [RISC OS] see ZIPOPT
+
+ 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.
+
+ ZIP_OPTS
+ [VMS] see ZIPOPT
+
+SEE ALSO
+ compress(1), shar(1L), tar(1), unzip(1L), gzip(1L)
+
+DIAGNOSTICS
+ The exit status (or error level) approximates the exit codes defined by
+ PKWARE and takes on the following values, except under VMS:
+
+ 0 normal; no errors or warnings detected.
+
+ 2 unexpected end of zip file.
+
+ 3 a generic error in the zipfile format was detected. Pro-
+ cessing may have completed successfully anyway; some bro-
+ ken zipfiles created by other archivers have simple work-
+ arounds.
+
+ 4 zip was unable to allocate memory for one or more buffers
+ during program initialization.
+
+ 5 a severe error in the zipfile format was detected. Pro-
+ cessing probably failed immediately.
+
+ 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 zipsplit
+
+ 7 invalid comment format
+
+ 8 zip -T failed or out of memory
+
+ 9 the user aborted zip prematurely with control-C (or simi-
+ lar)
+
+ 10 zip encountered an error while using a temp file
+
+ 11 read or seek error
+
+ 12 zip has nothing to do
+
+ 13 missing or empty zip file
+
+ 14 error writing to a file
+
+ 15 zip was unable to create a file to write to
+
+ 16 bad command line parameters
+
+ 18 zip could not open a specified file to read
+
+ 19 zip was compiled with options not supported on this sys-
+ tem
+
+ VMS interprets standard Unix (or PC) return values as other, scarier-
+ looking things, so zip instead maps them into VMS-style status codes.
+ In general, zip sets VMS Facility = 1955 (0x07A3), Code = 2* Unix_sta-
+ tus, 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.
+
+BUGS
+ zip 3.0 is not compatible with PKUNZIP 1.10. Use zip 1.1 to produce zip
+ files which can be extracted by PKUNZIP 1.10.
+
+ zip files produced by zip 3.0 must not be updated by 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 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.
+
+ Under VMS, not all of the odd file formats are treated properly. Only
+ stream-LF format zip files are expected to work with zip. Others can
+ be converted using Rahul Dhesi's BILF program. This version of zip
+ handles some of the conversion internally. When using Kermit to trans-
+ fer 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.
+
+ Under some older VMS versions, zip may hang for file specifications
+ that use DECnet syntax foo::*.*.
+
+ On OS/2, zip cannot match some names, such as those including an excla-
+ mation 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.
+
+ Under OS/2, the amount of Extended Attributes displayed by DIR is (for
+ compatibility) the amount returned by the 16-bit version of DosQuery-
+ PathInfo(). 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. There-
+ fore the value reported by zip (which uses this 32-bit-mode size) dif-
+ fers from that reported by DIR. 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.
+
+AUTHORS
+ Copyright (C) 1997-2008 Info-ZIP.
+
+ Currently distributed under the Info-ZIP license.
+
+ 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.
+
+ Original copyright:
+
+ 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.
+
+ 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.
+
+ Please send bug reports and comments using the web page at: www.info-
+ zip.org. For bug reports, please include the version of zip (see
+ zip -h), the make options used to compile it (see zip -v), the machine
+ and operating system in use, and as much additional information as pos-
+ sible.
+
+ACKNOWLEDGEMENTS
+ Thanks to R. P. Byrne for his 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 zip file format, compression for-
+ mat, and .ZIP filename extension, and for accepting minor changes to
+ the file format; to Steve Burg for clarifications on the deflate for-
+ mat; 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 ftp site
+ for the Info-ZIP group to use; and most importantly, to the Info-ZIP
+ group itself (listed in the file infozip.who) without whose tireless
+ testing and bug-fixing efforts a portable zip would not have been pos-
+ sible. 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 zip 3.0.
+
+Info-ZIP 16 June 2008 (v3.0) ZIP(1L)
diff --git a/zip30.ann b/zip30.ann
new file mode 100644
index 0000000..2e8cfce
--- /dev/null
+++ b/zip30.ann
@@ -0,0 +1,95 @@
+Zip 3.0
+
+We have posted Zip 3.0, July 5th 2008. This is a major upgrade
+from Zip 2.32, the current Zip 2.x release. A quick summary of
+features is below, but see the file WhatsNew for the detailed list
+of major features and upgrades as well as what's on the list for
+Zip 3.1. Send in your feature suggestions and bug reports.
+
+Quick list of major changes in Zip 3.0:
+
+- Large files. Support for files and archives greater than 2 GB using
+ large file I/O and the Zip64 extensions. Also can now have more
+ than 64K entries in an archive.
+
+- Split archives. Zip now supports split archives, zip archives
+ split into a set of files that can then be stored on removable media
+ for instance.
+
+- Unicode. If Unicode support is enabled and supported on the system
+ Zip is run on, Zip now can read paths not in the current character
+ set and store those paths in portable UTF-8 format. These Unicode
+ paths can then be used to partially or fully recreate the paths on
+ other systems depending on the character set support provided by
+ the unzip on the receiving system. In particular, this allows
+ portability of paths between Windows and Unix. Unicode comments
+ are also supported on systems where UTF-8 is the current character
+ set. Unicode comment support for other systems is expected in
+ Zip 3.1.
+
+- New command line parser. This new parser allows for command line
+ permuting, where options can appear almost anywhere on the command
+ line. This allows adding options to the end of the command line,
+ for instance. It also supports long options, allowing for
+ more readable command lines, and also allows lists for the -x
+ exclude and -i include options to appear not just at the end of
+ the command line. And some bugs in command line processing in
+ Zip 2.32 have been fixed.
+
+- Unix 32-bit UIDs/GIDs. Now UIDs/GIDs larger than 16 bits are
+ supported, but UnZip 6.0 is needed to restore these larger
+ UIDs/GIDs. If Zip detects that the current system does not use
+ 16-bit UIDs/GIDs, the old 16-bit UID/GID storage is not used
+ as putting 32-bit UIDs/GIDs into 16-bit fields can cause
+ problems.
+
+- New modes. Additional archive modes have been added, including a
+ difference mode for supporting incremental backups, a file sync
+ mode for synchronizing an existing archive with the current file
+ system (which can be much faster than creating a new archive), and
+ a copy mode that allows copying entries from one archive to another.
+
+- Compression using bzip2. Now can add bzip2 compression as a
+ compression option in Zip. bzip2 compression can result in much
+ more compact entries in some cases, but the user should verify
+ that bzip2 is supported on the target unzip before using this new
+ compression choice.
+
+- New Windows dll. The Windows dll has been updated to support the
+ new Zip64 large file and larger number of entries limits. This
+ new dll is not backward compatible with the Zip 2.32 dll, as the
+ arguments to the dll have been updated to support the added
+ capabilities, but modifying existing programs to use the new dll
+ should be simple. See the included Visual Basic example project
+ for details.
+
+- Better streaming and piping. Zip now has better support of
+ streaming and piping and handles Unix FIFOs (named pipes) better.
+
+- Gobs of new progress information. Zip can now output progress
+ information, such as how many entries processed and to go, how
+ many bytes processed and to go, and adjustable size progress
+ dots. If the initial file scan takes longer than about 5
+ seconds, Zip now outputs dots during the scan to avoid a long
+ period of quiet. Zip can also now generate log files.
+
+- Updated archive fixing. The archive fixing capability is
+ slightly improved, and now can fix split archives.
+
+- Windows Archive bit support. The Windows archive bit is now
+ supported, though the new difference mode is probably more
+ reliable than relying on the Windows archive bit for creating
+ incremental backups.
+
+- File lists. Zip can list the files that would be added to an
+ archive as well as the files in an existing archive.
+
+- Extended help. A new extended help option lists a very terse
+ summary of the major features of Zip and how to use them.
+
+- Many bug fixes.
+
+As always, see the Zip manual page for details on what Zip has and
+how to use all features.
+
+Enjoy!
diff --git a/zip30f.ann b/zip30f.ann
new file mode 100644
index 0000000..79285e0
--- /dev/null
+++ b/zip30f.ann
@@ -0,0 +1,61 @@
+Zip 3.0f
+
+We have posted Zip Beta 3.0f, September 24th 2007. This is a beta
+release, but is more or less complete. See the file WhatsNew for
+a list of major features implemented and what's left.
+
+The archive reading and writing code in this beta has been redone to
+support split archives. We've extensively tested the code over the
+last year, but you should thoroughly test it yourself before relying
+on it. Also note that Unicode support is preliminary and may change
+before release, but currently there seems agreement between Info-ZIP
+and others on how to handle storing UTF-8 paths and that approach is
+implemented in Zip 3.0.
+
+Please test this beta and let us know if we're ready to officially
+release Zip 3.0.
+
+New things in Zip 3.0f
+- Split archives - Zip now can create and indirectly update split
+ archives
+- Unicode support - Zip now stores Unicode paths that should be more
+ portable across character sets and languages and Zip now can
+ read Windows file names in most all character sets using Unicode,
+ but this support is preliminary and may change by release
+- bzip2 - bzip2 compression is now supported
+- Console writing - Messages to the console are more consistently
+ formatted
+- Streaming - Directories are now handled better when streaming
+- Date range - Can now use -t and -tt to set a date range
+- UnZip Check - Check if UnZip 6.00 or later is available for
+ testing a Zip64 archive
+- License - minor updates to the license
+- Difference mode - A new option -DF (--dif) creates an output archive that
+ includes only files changed or added since the input archive was created,
+ and might be useful for incremental backups
+- File Sync - New option -FS synchronizes the entries in an archive with the
+ files on the file system, adding, updating, and deleting entries as needed,
+ creating an updated archive that should be the same as a new archive, but
+ since existing entries are copied and not recompressed it can be faster
+- Fix options - Options -F and -FF now fix split archives
+- Copy Mode - This new mode allows selecting archive entries to copy
+ to a new archive
+- Case matching - On Windows and VMS, option -ic (ignore case) turns off
+ case-sensitive matching of command line input patterns when matching
+ entries in an archive
+- Windows OEM - With this compile option, file names are saved on
+ Windows in the local OEM character set, as some other zips do
+- Windows Archive Bit support - On Windows can now select files
+ using the Windows archive bit
+- Global dots - Can now set quiet mode, but output progress dots every
+ so many bytes read, settable from KB to TB, allowing progress to be
+ displayed for large archives without the screen scrolling
+- Empty archives - Options -i or -i@ can now output empty archives,
+ which is useful in some scripts
+- Keep extra fields option - Option -X- allows passing through extra
+ fields that Zip does not process
+- Large file encryption bug fixed - Fix for bug that very rarely
+ results in bad data being stored when deflating and encrypting
+ uncompressable large amounts of data and resulting in CRC errors
+- Show Files option - Can list the files that would be operated on
+- Delete date bug fixed - Bug when using -d with -t or -tt is fixed
diff --git a/zip30g.ann b/zip30g.ann
new file mode 100644
index 0000000..8ec2e38
--- /dev/null
+++ b/zip30g.ann
@@ -0,0 +1,33 @@
+Zip 3.0g
+
+We have posted Zip Beta 3.0g, January 30th 2008. This is a beta
+release, but is more or less complete and is considered a release
+candidate. See the file WhatsNew for a list of major features
+implemented and what's left.
+
+The archive reading and writing code in Zip 3.0 has been redone to
+support split archives. We've extensively tested the code over the
+last year, but you should thoroughly test it yourself before relying
+on it. Also note that Unicode support has been added and should comply
+with the latest AppNote, but is still new and so may need refining.
+
+Please test this beta and let us know if we're ready to officially
+release Zip 3.0.
+
+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.
+
+- Many small bug fixes.
diff --git a/zip30h.ann b/zip30h.ann
new file mode 100644
index 0000000..48bda34
--- /dev/null
+++ b/zip30h.ann
@@ -0,0 +1,47 @@
+Zip 3.0h
+
+We have posted Zip Beta 3.0h, May 31st 2008. This is a beta
+release, but is more or less complete and is considered a release
+candidate. See the file WhatsNew for a list of major features
+implemented and what's left.
+
+The archive reading and writing code in Zip 3.0 has been redone to
+support split archives. We've extensively tested the code over the
+last year, but you should thoroughly test it yourself before relying
+on it. Also note that Unicode support has been added and should comply
+with the latest AppNote, but is still new and so may need refining.
+
+Please test this beta and let us know if we're ready to officially
+release Zip 3.0.
+
+New things in Zip 3.0h
+- Allow -@ and -x to work together.
+
+- Change long Unicode escapes from #Lxxxxxxxx to #Lxxxxxx.
+
+- Unicode code cleanup to support additional compilers and also
+ some memory leak fixes.
+
+- Update symbolic link checks.
+
+- Add support for 32-bit UIDs/GIDs.
+
+- Update VMS notes.
+
+- Fix bug where directory scan using -AS (include only files
+ with Windows archive bit set) would skip files in directories
+ with bit not set.
+
+- 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.
+
+- Additional small bug fixes.
diff --git a/zipcloak.c b/zipcloak.c
index 4b0b9e7..37bd414 100644
--- a/zipcloak.c
+++ b/zipcloak.c
@@ -1,19 +1,30 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ zipcloak.c - Zip 3
- See the accompanying file LICENSE, version 2005-Feb-10 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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 code was originally written in Europe and could be freely distributed
+ from any country except the U.S.A. If this code was imported into the U.S.A,
+ it could not be re-exported from the U.S.A to another country. (This
+ restriction might seem curious but this is what US law required.)
+
+ Now this code can be freely exported and imported. See README.CR.
+ */
#define __ZIPCLOAK_C
#ifndef UTIL
-#define UTIL
+# define UTIL
#endif
#include "zip.h"
#define DEFCPYRT /* main module: enable copyright string defines! */
#include "revision.h"
+#include "crc32.h"
#include "crypt.h"
#include "ttyio.h"
#include <signal.h>
@@ -30,8 +41,7 @@ local void license OF((void));
local void help OF((void));
local void version_info OF((void));
-/* Temporary zip file name and file pointer */
-local char *tempzip;
+/* Temporary zip file pointer */
local FILE *tempzf;
/* Pointer to CRC-32 table (used for decryption/encryption) */
@@ -41,6 +51,86 @@ ZCONST ulg near *crc_32_tab;
ZCONST uLongf *crc_32_tab;
#endif
+int set_filetype(out_path)
+ char *out_path;
+{
+#ifdef __BEOS__
+ /* Set the filetype of the zipfile to "application/zip" */
+ setfiletype( out_path, "application/zip" );
+#endif
+
+#ifdef __ATHEOS__
+ /* Set the filetype of the zipfile to "application/x-zip" */
+ setfiletype(out_path, "application/x-zip");
+#endif
+
+#ifdef MACOS
+ /* Set the Creator/Type of the zipfile to 'IZip' and 'ZIP ' */
+ setfiletype(out_path, 'IZip', 'ZIP ');
+#endif
+
+#ifdef RISCOS
+ /* Set the filetype of the zipfile to &DDC */
+ setfiletype(out_path, 0xDDC);
+#endif
+ return ZE_OK;
+}
+
+/* rename a split
+ * A split has a tempfile name until it is closed, then
+ * here rename it as out_path the final name for the split.
+ */
+int rename_split(temp_name, out_path)
+ char *temp_name;
+ char *out_path;
+{
+ int r;
+ /* Replace old zip file with new zip file, leaving only the new one */
+ if ((r = replace(out_path, temp_name)) != ZE_OK)
+ {
+ zipwarn("new zip file left as: ", temp_name);
+ free((zvoid *)tempzip);
+ tempzip = NULL;
+ ZIPERR(r, "was replacing split file");
+ }
+ if (zip_attributes) {
+ setfileattr(out_path, zip_attributes);
+ }
+ return ZE_OK;
+}
+
+void zipmessage_nl(a, nl)
+ZCONST char *a; /* message string to output */
+int nl; /* 1 = add nl to end */
+/* If nl false, print a message to mesg without new line.
+ If nl true, print and add new line. */
+{
+ if (noisy) {
+ fprintf(mesg, "%s", a);
+ if (nl) {
+ fprintf(mesg, "\n");
+ mesg_line_started = 0;
+ } else {
+ mesg_line_started = 1;
+ }
+ fflush(mesg);
+ }
+}
+
+void zipmessage(a, b)
+ZCONST char *a, *b; /* message strings juxtaposed in output */
+/* Print a message to mesg and flush. Write new line first
+ if current line has output already. */
+{
+ if (noisy) {
+ if (mesg_line_started)
+ fprintf(mesg, "\n");
+ fprintf(mesg, "%s%s\n", a, b);
+ mesg_line_started = 0;
+ fflush(mesg);
+ }
+}
+
/***********************************************************************
* Issue a message for the error, clean up files and memory, and exit.
*/
@@ -49,7 +139,7 @@ void ziperr(code, msg)
ZCONST char *msg; /* message about how it happened */
{
if (PERR(code)) perror("zipcloak error");
- fprintf(stderr, "zipcloak error: %s (%s)\n", ziperrors[code-1], msg);
+ fprintf(mesg, "zipcloak error: %s (%s)\n", ZIPERRORS(code), msg);
if (tempzf != NULL) fclose(tempzf);
if (tempzip != NULL) {
destroy(tempzip);
@@ -60,12 +150,12 @@ void ziperr(code, msg)
}
/***********************************************************************
- * Print a warning message to stderr and return.
+ * Print a warning message to mesg (usually stderr) and return.
*/
void zipwarn(msg1, msg2)
ZCONST char *msg1, *msg2; /* message strings juxtaposed in output */
{
- fprintf(stderr, "zipcloak warning: %s%s\n", msg1, msg2);
+ fprintf(mesg, "zipcloak warning: %s%s\n", msg1, msg2);
}
@@ -78,23 +168,38 @@ local void handler(sig)
{
#if (!defined(MSDOS) && !defined(__human68k__) && !defined(RISCOS))
echon();
- putc('\n', stderr);
+ putc('\n', mesg);
#endif
ziperr(ZE_ABORT +sig-sig, "aborting");
/* dummy usage of sig to avoid compiler warnings */
}
+static ZCONST char *public[] = {
+"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 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. (Prior to January 2000, re-export",
+"from the US was a violation of US law.)"
+};
+
/***********************************************************************
* Print license information to stdout.
*/
local void license()
{
- extent i;
+ extent i; /* counter for copyright array */
- for (i = 0; i < sizeof(swlicense)/sizeof(char *); i++)
+ for (i = 0; i < sizeof(swlicense)/sizeof(char *); i++) {
puts(swlicense[i]);
+ }
putchar('\n');
+ printf("Export notice:\n");
+ for (i = 0; i < sizeof(public)/sizeof(char *); i++) {
+ puts(public[i]);
+ }
}
@@ -102,18 +207,23 @@ static ZCONST char *help_info[] = {
"",
"ZipCloak %s (%s)",
#ifdef VM_CMS
-"Usage: zipcloak [-d] [-b fm] zipfile",
+"Usage: zipcloak [-dq] [-b fm] zipfile",
#else
-"Usage: zipcloak [-d] [-b path] zipfile",
+"Usage: zipcloak [-dq] [-b path] zipfile",
#endif
" the default action is to encrypt all unencrypted entries in the zip file",
-" -d decrypt--decrypt encrypted entries (copy if given wrong password)",
+"",
+" -d --decrypt decrypt encrypted entries (copy if given wrong password)",
#ifdef VM_CMS
-" -b use \"fm\" as the filemode for the temporary zip file",
+" -b --temp-mode use \"fm\" as the filemode for the temporary zip file",
#else
-" -b use \"path\" for the temporary zip file",
+" -b --temp-path use \"path\" for the temporary zip file",
#endif
-" -h show this help -v show version info -L show software license"
+" -O --output-file write output to new zip file",
+" -q --quiet quiet operation, suppress some informational messages",
+" -h --help show this help",
+" -v --version show version info",
+" -L --license show software license"
};
/***********************************************************************
@@ -152,6 +262,7 @@ local void version_info()
printf(copyright[i], "zipcloak");
putchar('\n');
}
+ putchar('\n');
for (i = 0; i < sizeof(versinfolines)/sizeof(char *); i++)
{
@@ -168,11 +279,26 @@ local void version_info()
}
printf("\t[encryption, version %d.%d%s of %s]\n",
CR_MAJORVER, CR_MINORVER, CR_BETA_VER, CR_VERSION_DATE);
-
- for (i = 0; i < sizeof(cryptnote)/sizeof(char *); i++)
- puts(cryptnote[i]);
}
+/* options for zipcloak - 3/5/2004 EG */
+struct option_struct far options[] = {
+ /* short longopt value_type negatable ID name */
+#ifdef VM_CMS
+ {"b", "temp-mode", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'b', "temp file mode"},
+#else
+ {"b", "temp-path", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'b', "path for temp file"},
+#endif
+ {"d", "decrypt", o_NO_VALUE, o_NOT_NEGATABLE, 'd', "decrypt"},
+ {"h", "help", o_NO_VALUE, o_NOT_NEGATABLE, 'h', "help"},
+ {"L", "license", o_NO_VALUE, o_NOT_NEGATABLE, 'L', "license"},
+ {"l", "", o_NO_VALUE, o_NOT_NEGATABLE, 'L', "license"},
+ {"O", "output-file", o_REQUIRED_VALUE, o_NOT_NEGATABLE, 'O', "output to new archive"},
+ {"v", "version", o_NO_VALUE, o_NOT_NEGATABLE, 'v', "version"},
+ /* the end of the list */
+ {NULL, NULL, o_NO_VALUE, o_NOT_NEGATABLE, 0, NULL} /* end has option_ID = 0 */
+ };
+
/***********************************************************************
* Encrypt or decrypt all of the entries in a zip file. See the command
@@ -184,28 +310,79 @@ int main(argc, argv)
char **argv; /* command line tokens */
{
int attr; /* attributes of zip file */
- ulg start_offset; /* start of central directory */
+ zoff_t start_offset; /* start of central directory */
int decrypt; /* decryption flag */
int temp_path; /* 1 if next argument is path for temp files */
char passwd[IZ_PWLEN+1]; /* password for encryption or decryption */
char verify[IZ_PWLEN+1]; /* password for encryption or decryption */
+#if 0
char *q; /* steps through option arguments */
int r; /* arg counter */
+#endif
int res; /* result code */
- ulg length; /* length of central directory */
+ zoff_t length; /* length of central directory */
FILE *inzip, *outzip; /* input and output zip files */
struct zlist far *z; /* steps through zfiles linked list */
+ /* used by get_option */
+ unsigned long option; /* option ID returned by get_option */
+ int argcnt = 0; /* current argcnt in args */
+ int argnum = 0; /* arg number */
+ int optchar = 0; /* option state */
+ char *value = NULL; /* non-option arg, option value or NULL */
+ int negated = 0; /* 1 = option negated */
+ int fna = 0; /* current first non-opt arg */
+ int optnum = 0; /* index in table */
+
+ char **args; /* copy of argv that can be freed */
#ifdef THEOS
setlocale(LC_CTYPE, "I");
#endif
+#ifdef UNICODE_SUPPORT
+# ifdef UNIX
+ /* For Unix, set the locale to UTF-8. Any UTF-8 locale is
+ OK and they should all be the same. This allows seeing,
+ writing, and displaying (if the fonts are loaded) all
+ characters in UTF-8. */
+ {
+ char *loc;
+
+ /*
+ loc = setlocale(LC_CTYPE, NULL);
+ printf(" Initial language locale = '%s'\n", loc);
+ */
+
+ loc = setlocale(LC_CTYPE, "en_US.UTF-8");
+
+ /*
+ printf("langinfo %s\n", nl_langinfo(CODESET));
+ */
+
+ if (loc != NULL) {
+ /* using UTF-8 character set so can set UTF-8 GPBF bit 11 */
+ using_utf8 = 1;
+ /*
+ printf(" Locale set to %s\n", loc);
+ */
+ } else {
+ /*
+ printf(" Could not set Unicode UTF-8 locale\n");
+ */
+ }
+ }
+# endif
+#endif
+
/* If no args, show help */
if (argc == 1) {
help();
- EXIT(0);
+ EXIT(ZE_OK);
}
+ /* Informational messages are written to stdout. */
+ mesg = stdout;
+
init_upper(); /* build case map table */
crc_32_tab = get_crc_table();
@@ -220,7 +397,24 @@ int main(argc, argv)
#ifdef SIGTERM /* Some don't have SIGTERM */
signal(SIGTERM, handler);
#endif
+#ifdef SIGABRT
+ signal(SIGABRT, handler);
+#endif
+#ifdef SIGBREAK
+ signal(SIGBREAK, handler);
+#endif
+#ifdef SIGBUS
+ signal(SIGBUS, handler);
+#endif
+#ifdef SIGILL
+ signal(SIGILL, handler);
+#endif
+#ifdef SIGSEGV
+ signal(SIGSEGV, handler);
+#endif
temp_path = decrypt = 0;
+#if 0
+ /* old command line */
for (r = 1; r < argc; r++) {
if (*argv[r] == '-') {
if (!argv[r][1]) ziperr(ZE_PARMS, "zip file cannot be stdin");
@@ -236,13 +430,15 @@ int main(argc, argv)
decrypt = 1; break;
case 'h': /* Show help */
help();
- EXIT(0);
+ EXIT(ZE_OK);
case 'l': case 'L': /* Show copyright and disclaimer */
license();
- EXIT(0);
+ EXIT(ZE_OK);
+ case 'q': /* Quiet operation, suppress info messages */
+ noisy = 0; break;
case 'v': /* Show version info */
version_info();
- EXIT(0);
+ EXIT(ZE_OK);
default:
ziperr(ZE_PARMS, "unknown option");
} /* switch */
@@ -261,8 +457,112 @@ int main(argc, argv)
} /* if */
} /* for */
+#else
+
+ /* new command line */
+
+ zipfile = NULL;
+ out_path = NULL;
+
+ /* make copy of args that can use with insert_arg() */
+ args = copy_args(argv, 0);
+
+ /*
+ -------------------------------------------
+ Process command line using get_option
+ -------------------------------------------
+
+ Each call to get_option() returns either a command
+ line option and possible value or a non-option argument.
+ Arguments are permuted so that all options (-r, -b temp)
+ are returned before non-option arguments (zipfile).
+ Returns 0 when nothing left to read.
+ */
+
+ /* set argnum = 0 on first call to init get_option */
+ argnum = 0;
+
+ /* get_option returns the option ID and updates parameters:
+ args - usually same as argv if no argument file support
+ argcnt - current argc for args
+ value - char* to value (free() when done with it) or NULL if no value
+ negated - option was negated with trailing -
+ */
+
+ while ((option = get_option(&args, &argcnt, &argnum,
+ &optchar, &value, &negated,
+ &fna, &optnum, 0)))
+ {
+ switch (option)
+ {
+ case 'b': /* Specify path for temporary file */
+ if (temp_path) {
+ ziperr(ZE_PARMS, "more than one temp_path");
+ }
+ temp_path = 1;
+ tempath = value;
+ break;
+ case 'd':
+ decrypt = 1; break;
+ case 'h': /* Show help */
+ help();
+ EXIT(ZE_OK);
+ case 'l': case 'L': /* Show copyright and disclaimer */
+ license();
+ EXIT(ZE_OK);
+ case 'O': /* Output to new zip file instead of updating original zip file */
+ if ((out_path = ziptyp(value)) == NULL) {
+ ziperr(ZE_MEM, "was processing arguments");
+ }
+ free(value);
+ break;
+ case 'q': /* Quiet operation, suppress info messages */
+ noisy = 0; break;
+ case 'v': /* Show version info */
+ version_info();
+ EXIT(ZE_OK);
+ case o_NON_OPTION_ARG:
+ /* not an option */
+ /* no more options as permuting */
+ /* just dash also ends up here */
+
+ if (strcmp(value, "-") == 0) {
+ ziperr(ZE_PARMS, "zip file cannot be stdin");
+ } else if (zipfile != NULL) {
+ ziperr(ZE_PARMS, "can only specify one zip file");
+ }
+
+ if ((zipfile = ziptyp(value)) == NULL) {
+ ziperr(ZE_MEM, "was processing arguments");
+ }
+ free(value);
+ break;
+
+ default:
+ ziperr(ZE_PARMS, "unknown option");
+ }
+ }
+
+ free_args(args);
+
+#endif
+
if (zipfile == NULL) ziperr(ZE_PARMS, "need to specify zip file");
+ /* in_path is the input zip file */
+ if ((in_path = malloc(strlen(zipfile) + 1)) == NULL) {
+ ziperr(ZE_MEM, "input");
+ }
+ strcpy(in_path, zipfile);
+
+ /* out_path defaults to in_path */
+ if (out_path == NULL) {
+ if ((out_path = malloc(strlen(zipfile) + 1)) == NULL) {
+ ziperr(ZE_MEM, "output");
+ }
+ strcpy(out_path, zipfile);
+ }
+
/* Read zip file */
if ((res = readzipfile()) != ZE_OK) ziperr(res, zipfile);
if (zfiles == NULL) ziperr(ZE_NAME, zipfile);
@@ -282,9 +582,50 @@ int main(argc, argv)
attr = getfileattr(zipfile);
/* Open output zip file for writing */
- if ((tempzf = outzip = fopen(tempzip = tempname(zipfile), FOPW)) == NULL) {
+#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 = tempzf = outzip = fdopen(yd, FOPW_TMP)) == NULL) {
+ ZIPERR(ZE_TEMP, tempzip);
+ }
+ }
+#else
+ if ((y = tempzf = outzip = fopen(tempzip = tempname(zipfile), FOPW)) == NULL) {
ziperr(ZE_TEMP, tempzip);
}
+#endif
/* Get password */
if (getp("Enter password: ", passwd, IZ_PWLEN+1) == NULL)
@@ -304,9 +645,10 @@ int main(argc, argv)
}
/* Open input zip file again, copy preamble if any */
- if ((inzip = fopen(zipfile, FOPR)) == NULL) ziperr(ZE_NAME, zipfile);
+ if ((in_file = fopen(zipfile, FOPR)) == NULL) ziperr(ZE_NAME, zipfile);
- if (zipbeg && (res = fcopy(inzip, outzip, zipbeg)) != ZE_OK) {
+ if (zipbeg && (res = bfcopy(zipbeg)) != ZE_OK)
+ {
ziperr(res, res == ZE_TEMP ? tempzip : zipfile);
}
tempzn = zipbeg;
@@ -316,50 +658,56 @@ int main(argc, argv)
if (decrypt && (z->flg & 1)) {
printf("decrypting: %s", z->zname);
fflush(stdout);
- if ((res = zipbare(z, inzip, outzip, passwd)) != ZE_OK) {
+ if ((res = zipbare(z, passwd)) != ZE_OK)
+ {
if (res != ZE_MISS) ziperr(res, "was decrypting an entry");
printf(" (wrong password--just copying)");
+ fflush(stdout);
}
putchar('\n');
} else if ((!decrypt) && !(z->flg & 1)) {
printf("encrypting: %s\n", z->zname);
fflush(stdout);
- if ((res = zipcloak(z, inzip, outzip, passwd)) != ZE_OK) {
+ if ((res = zipcloak(z, passwd)) != ZE_OK)
+ {
ziperr(res, "was encrypting an entry");
}
} else {
printf(" copying: %s\n", z->zname);
fflush(stdout);
- if ((res = zipcopy(z, inzip, outzip)) != ZE_OK) {
+ if ((res = zipcopy(z)) != ZE_OK)
+ {
ziperr(res, "was copying an entry");
}
} /* if */
} /* for */
- fclose(inzip);
+
+ fclose(in_file);
+
/* Write central directory and end of central directory */
/* get start of central */
- if ((start_offset = (ulg)ftell(outzip)) == (ulg)-1L)
+ if ((start_offset = zftello(outzip)) == (zoff_t)-1)
ziperr(ZE_TEMP, tempzip);
for (z = zfiles; z != NULL; z = z->nxt) {
- if ((res = putcentral(z, outzip)) != ZE_OK) ziperr(res, tempzip);
+ if ((res = putcentral(z)) != ZE_OK) ziperr(res, tempzip);
}
/* get end of central */
- if ((length = (ulg)ftell(outzip)) == (ulg)-1L)
+ if ((length = zftello(outzip)) == (zoff_t)-1)
ziperr(ZE_TEMP, tempzip);
length -= start_offset; /* compute length of central */
- if ((res = putend((int)zcount, length, start_offset, zcomlen,
- zcomment, outzip)) != ZE_OK) {
+ if ((res = putend((zoff_t)zcount, length, start_offset, zcomlen,
+ zcomment)) != ZE_OK) {
ziperr(res, tempzip);
}
tempzf = NULL;
if (fclose(outzip)) ziperr(ZE_TEMP, tempzip);
- if ((res = replace(zipfile, tempzip)) != ZE_OK) {
+ if ((res = replace(out_path, tempzip)) != ZE_OK) {
zipwarn("new zip file left as: ", tempzip);
free((zvoid *)tempzip);
tempzip = NULL;
@@ -372,6 +720,9 @@ int main(argc, argv)
/* Set the filetype of the zipfile to &DDC */
setfiletype(zipfile, 0xDDC);
#endif
+ free((zvoid *)in_path);
+ free((zvoid *)out_path);
+
free((zvoid *)zipfile);
zipfile = NULL;
@@ -380,6 +731,17 @@ int main(argc, argv)
}
#else /* !CRYPT */
+
+/* below is only used if crypt is not enabled */
+
+struct option_struct far options[] = {
+ /* short longopt value_type negatable ID name */
+ {"h", "help", o_NO_VALUE, o_NOT_NEGATABLE, 'h', "help"},
+ /* the end of the list */
+ {NULL, NULL, o_NO_VALUE, o_NOT_NEGATABLE, 0, NULL} /* end has option_ID = 0 */
+ };
+
+
int main OF((void));
void zipwarn(msg1, msg2)
@@ -399,7 +761,7 @@ ZCONST char *h;
int main()
{
- fprintf(stderr, "\
+ fprintf(mesg, "\
This version of ZipCloak does not support encryption. Get the current Zip\n\
source distribution and recompile ZipCloak after you have added an option to\n\
define the symbol USE_CRYPT to the C compiler's command arguments.\n");
diff --git a/zipcloak.txt b/zipcloak.txt
new file mode 100644
index 0000000..0f24dc0
--- /dev/null
+++ b/zipcloak.txt
@@ -0,0 +1,75 @@
+zipcloak(1) zipcloak(1)
+
+NAME
+ zipcloak - encrypt entries in a zipfile
+
+SYNOPSIS
+ zipcloak [-d] [-b path] [-h] [-v] [-L] zipfile
+
+ARGUMENTS
+ zipfile Zipfile to encrypt entries in
+
+OPTIONS
+ -b path
+ --temp-path path
+ Use the directory given by path for the temporary zip file.
+
+ -d
+ --decrypt
+ Decrypt encrypted entries (copy if given wrong password).
+
+ -h
+ --help
+ Show a short help.
+
+ -L
+ --license
+ Show software license.
+
+ -O path
+ --output-file zipfile
+ Write output to new archive zipfile, leaving original archive as
+ is.
+
+ -q
+ --quiet
+ Quiet operation. Suppresses some informational messages.
+
+ -v
+ --version
+ Show version information.
+
+DESCRIPTION
+ zipcloak encrypts all unencrypted entries in the zipfile. This is the
+ default action.
+
+ The -d option is used to decrypt encrypted entries in the zipfile.
+
+ zipcloak uses original zip encryption which is considered weak.
+
+ 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.
+
+EXAMPLES
+ To be added.
+
+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 zip and then use zipcloak
+ on the single-file archive. If needed, the resulting archive can then
+ be split again using zip.
+
+SEE ALSO
+ zip(1), unzip(1)
+
+AUTHOR
+ Info-ZIP
+
+ v3.0 of 8 May 2008 zipcloak(1)
diff --git a/ziperr.h b/ziperr.h
index 1f2ce37..19c7655 100644
--- a/ziperr.h
+++ b/ziperr.h
@@ -1,16 +1,39 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ ziperr.h - Zip 3
- See the accompanying file LICENSE, version 2005-Feb-10 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*
* ziperr.h by Mark Adler
*/
-/* Error return values. The values 0..4 and 12..18 follow the conventions
+
+/*
+ * VMS message file ident string. (The "-xxx" suffix should be
+ * incremented when messages are changed for a particular program
+ * version.) Used only when generating the VMS message source file, but
+ * that can be done on a non-VMS system.
+ */
+#define VMS_MSG_IDENT "V3.0-000"
+
+/* VMS-compatible "severity" values (bits 2:0): */
+#define ZE_S_WARNING 0x00
+#define ZE_S_SUCCESS 0x01
+#define ZE_S_ERROR 0x02
+#define ZE_S_INFO 0x03
+#define ZE_S_SEVERE 0x04
+#define ZE_S_UNUSED 0x07
+
+/* Flags: */
+#define ZE_S_PERR 0x10
+
+
+ /* Error return values. The values 0..4 and 12..18 follow the conventions
of PKZIP. The values 4..10 are all assigned to "insufficient memory"
by PKZIP, so the codes 5..10 are used here for other purposes. */
#define ZE_MISS -1 /* used by procname(), zipbare() */
@@ -31,37 +54,62 @@
#define ZE_CREAT 15 /* couldn't open to write */
#define ZE_PARMS 16 /* bad command line */
#define ZE_OPEN 18 /* could not open a specified file to read */
+#define ZE_COMPERR 19 /* error in compilation options */
+#define ZE_ZIP64 20 /* Zip64 not supported */
+
+#define ZE_MAXERR 20 /* the highest error number */
-#define ZE_MAXERR 18 /* the highest error number */
-/* Macro to determine whether to call perror() or not */
-#define PERR(e) (e==ZE_READ||e==ZE_WRITE||e==ZE_CREAT||e==ZE_TEMP||e==ZE_OPEN)
+/* Error messages for the ziperr() function in the zip programs. */
#ifdef GLOBALS
-/* Error messages for the ziperr() function in the zip programs */
-char *ziperrors[ZE_MAXERR] = {
-/* 1 */ "",
-/* 2 */ "Unexpected end of zip file",
-/* 3 */ "Zip file structure invalid",
-/* 4 */ "Out of memory",
-/* 5 */ "Internal logic error",
-/* 6 */ "Entry too big to split, read, or write",
-/* 7 */ "Invalid comment format",
-/* 8 */ "Zip file invalid or could not spawn unzip",
-/* 9 */ "Interrupted",
-/* 10 */ "Temporary file failure",
-/* 11 */ "Input file read failure",
-/* 12 */ "Nothing to do!",
-/* 13 */ "Missing or empty zip file",
-/* 14 */ "Output file write failure",
-/* 15 */ "Could not create output file",
-/* 16 */ "Invalid command arguments",
-/* 17 */ "",
-/* 18 */ "File not found or no read permission"
+struct
+{
+ char *name;
+ char *string;
+ int severity;
+} ziperrors[ZE_MAXERR + 1] = {
+/* 0 */ { "OK", "Normal successful completion", ZE_S_SUCCESS },
+/* 1 */ { "", "", ZE_S_UNUSED },
+/* 2 */ { "EOF", "Unexpected end of zip file", ZE_S_SEVERE },
+/* 3 */ { "FORM", "Zip file structure invalid", ZE_S_ERROR },
+/* 4 */ { "MEM", "Out of memory", ZE_S_SEVERE },
+/* 5 */ { "LOGIC", "Internal logic error", ZE_S_SEVERE },
+/* 6 */ { "BIG", "Entry too big to split, read, or write",
+ ZE_S_ERROR },
+/* 7 */ { "NOTE", "Invalid comment format", ZE_S_ERROR },
+/* 8 */ { "TEST", "Zip file invalid, could not spawn unzip, or wrong unzip",
+ ZE_S_SEVERE },
+/* 9 */ { "ABORT", "Interrupted", ZE_S_ERROR },
+/* 10 */ { "TEMP", "Temporary file failure", ZE_S_SEVERE | ZE_S_PERR },
+/* 11 */ { "READ", "Input file read failure", ZE_S_SEVERE | ZE_S_PERR },
+/* 12 */ { "NONE", "Nothing to do!", ZE_S_WARNING },
+/* 13 */ { "NAME", "Missing or empty zip file", ZE_S_ERROR },
+/* 14 */ { "WRITE", "Output file write failure", ZE_S_SEVERE | ZE_S_PERR },
+/* 15 */ { "CREAT", "Could not create output file", ZE_S_SEVERE | ZE_S_PERR },
+/* 16 */ { "PARMS", "Invalid command arguments", ZE_S_ERROR },
+/* 17 */ { "", "", ZE_S_UNUSED },
+/* 18 */ { "OPEN", "File not found or no read permission",
+ ZE_S_ERROR | ZE_S_PERR },
+/* 19 */ { "COMPERR", "Not supported", ZE_S_SEVERE },
+/* 20 */ { "ZIP64", "Attempt to read unsupported Zip64 archive",
+ ZE_S_SEVERE }
# ifdef AZTEC_C
, /* extremely lame compiler bug workaround */
# endif
};
#else /* !GLOBALS */
-extern char *ziperrors[ZE_MAXERR]; /* Error messages for ziperr() */
+/* Error messages for ziperr() */
+extern struct
+{
+ char *name;
+ char *string;
+ int severity;
+} ziperrors[ZE_MAXERR + 1];
#endif /* ?GLOBALS */
+
+/* Macro to determine whether to call perror() or not. */
+#define PERR(e) (ziperrors[e].severity & ZE_S_PERR)
+
+/* Macro for easy access to the message string. */
+#define ZIPERRORS(e) ziperrors[e].string
diff --git a/zipfile.c b/zipfile.c
index 647c31f..1990cde 100644
--- a/zipfile.c
+++ b/zipfile.c
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ zipfile.c - Zip 3
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*
@@ -13,15 +15,26 @@
#include "zip.h"
#include "revision.h"
+#ifdef UNICODE_SUPPORT
+# include "crc32.h"
+#endif
+
+/* for realloc 2/6/2005 EG */
+#include <stdlib.h>
+
+#include <errno.h>
+
+/* for toupper() */
+#include <ctype.h>
#ifdef VMS
-# include <rms.h>
-# include <starlet.h>
+# include "vms/vms.h"
# include "vms/vmsmunch.h"
# include "vms/vmsdefs.h"
#endif
-#ifdef __RSXNT__
+#ifdef WIN32
+# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif
@@ -29,19 +42,26 @@
* XXX start of zipfile.h
*/
#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)); }
+ /* 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))
+ /* 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 */
/* Macros for writing machine integers to little-endian format */
#define PUTSH(a,f) {putc((char)((a) & 0xff),(f)); putc((char)((a) >> 8),(f));}
#define PUTLG(a,f) {PUTSH((a) & 0xffff,(f)) PUTSH((a) >> 16,(f))}
+#ifdef ZIP64_SUPPORT /* zip64 support 08/31/2003 R.Nausedat */
+# define PUTLLG(a,f) {PUTLG((a) & 0xffffffff,(f)) PUTLG((a) >> 32,(f))}
+#endif
+
/* -- Structure of a ZIP file -- */
@@ -52,6 +72,7 @@ ulg LG(uch* p) { return ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16)); }
#define EXTLOCSIG 0x08074b50L
/* Offsets of values in headers */
+/* local header */
#define LOCVER 0 /* version needed to extract */
#define LOCFLG 2 /* encrypt, deflate flags */
#define LOCHOW 4 /* compression method */
@@ -63,10 +84,13 @@ ulg LG(uch* p) { return ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16)); }
#define LOCNAM 22 /* length of filename */
#define LOCEXT 24 /* length of extra field */
+/* extended local header (data descriptor) following file data (if bit 3 set) */
+/* if Zip64 then all are 8 byte and not below - 11/1/03 EG */
#define EXTCRC 0 /* uncompressed crc-32 for file */
#define EXTSIZ 4 /* compressed size in zip file */
#define EXTLEN 8 /* uncompressed size */
+/* central directory header */
#define CENVEM 0 /* version made by */
#define CENVER 2 /* version needed to extract */
#define CENFLG 4 /* encrypt, deflate flags */
@@ -84,6 +108,7 @@ ulg LG(uch* p) { return ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16)); }
#define CENATX 34 /* external file attributes */
#define CENOFF 38 /* relative offset of local header */
+/* end of central directory record */
#define ENDDSK 0 /* number of this disk */
#define ENDBEG 2 /* number of the starting disk */
#define ENDSUB 4 /* entries on this disk */
@@ -92,22 +117,117 @@ ulg LG(uch* p) { return ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16)); }
#define ENDOFF 12 /* offset of central on starting disk */
#define ENDCOM 16 /* length of zip file comment */
+/* zip64 support 08/31/2003 R.Nausedat */
+
+/* EOCDL_SIG used to detect Zip64 archive */
+#define ZIP64_EOCDL_SIG 0x07064b50
+/* EOCDL size is used in the empty archive check */
+#define ZIP64_EOCDL_OFS_SIZE 20
+
+#define ZIP_UWORD16_MAX 0xFFFF /* border value */
+#define ZIP_UWORD32_MAX 0xFFFFFFFF /* border value */
+#define ZIP_EF_HEADER_SIZE 4 /* size of pre-header of extra fields */
+
+#ifdef ZIP64_SUPPORT
+# define ZIP64_EXTCRC 0 /* uncompressed crc-32 for file */
+# define ZIP64_EXTSIZ 4 /* compressed size in zip file */
+# define ZIP64_EXTLEN 12 /* uncompressed size */
+# define ZIP64_EOCD_SIG 0x06064b50
+# define ZIP64_EOCD_OFS_SIZE 40
+# define ZIP64_EOCD_OFS_CD_START 48
+# define ZIP64_EOCDL_OFS_SIZE 20
+# define ZIP64_EOCDL_OFS_EOCD_START 8
+# define ZIP64_EOCDL_OFS_TOTALDISKS 16
+# define ZIP64_MIN_VER 45 /* min version to set in the CD extra records */
+# define ZIP64_CENTRAL_DIR_TAIL_SIZE (56 - 8 - 4) /* size of zip64 central dir tail, minus sig and size field bytes */
+# define ZIP64_CENTRAL_DIR_TAIL_SIG 0x06064B50L /* zip64 central dir tail signature */
+# define ZIP64_CENTRAL_DIR_TAIL_END_SIG 0x07064B50L /* zip64 end of cen dir locator signature */
+# define ZIP64_LARGE_FILE_HEAD_SIZE 32 /* total size of zip64 extra field */
+# define ZIP64_EF_TAG 0x0001 /* ID for zip64 extra field */
+# define ZIP64_EFIELD_OFS_OSIZE ZIP_EF_HEADER_SIZE /* zip64 extra field: offset to original file size */
+# define ZIP64_EFIELD_OFS_CSIZE (ZIP64_EFIELD_OFS_OSIZE + 8) /* zip64 extra field: offset to compressed file size */
+# define ZIP64_EFIELD_OFS_OFS (ZIP64_EFIELD_OFS_CSIZE + 8) /* zip64 extra field: offset to offset in archive */
+# define ZIP64_EFIELD_OFS_DISK (ZIP64_EFIELD_OFS_OFS + 8) /* zip64 extra field: offset to start disk # */
+/* -------------------------------------------------------------------------------------------------------------------------- */
+ local int adjust_zip_local_entry OF((struct zlist far *));
+ local void adjust_zip_central_entry OF((struct zlist far *));
+#if 0
+ local int remove_local_extra_field OF((struct zlist far *, ulg));
+ local int remove_central_extra_field OF((struct zlist far *, ulg));
+#endif
+ local int add_central_zip64_extra_field OF((struct zlist far *));
+ local int add_local_zip64_extra_field OF((struct zlist far *));
+#endif /* ZIP64_SUPPORT */
+#ifdef UNICODE_SUPPORT
+# define UTF8_PATH_EF_TAG 0x7075 /* ID for Unicode path (up) extra field */
+ local int add_Unicode_Path_local_extra_field OF((struct zlist far *));
+ local int add_Unicode_Path_cen_extra_field OF((struct zlist far *));
+#endif
+
+/* New General Purpose Bit Flag bit 11 flags when entry path and
+ comment are in UTF-8 */
+#define UTF8_BIT (1 << 11)
+
+/* moved out of ZIP64_SUPPORT - 2/6/2005 EG */
+local void write_ushort_to_mem OF((ush, char *)); /* little endian conversions */
+local void write_ulong_to_mem OF((ulg, char *));
+#ifdef ZIP64_SUPPORT
+ local void write_int64_to_mem OF((uzoff_t, char *));
+#endif /* def ZIP64_SUPPORT */
+#ifdef UNICODE_SUPPORT
+ local void write_string_to_mem OF((char *, char *));
+#endif
+#if 0
+local char *get_extra_field OF((ush, char *, unsigned)); /* zip64 */
+#endif
+#ifdef UNICODE_SUPPORT
+local void read_Unicode_Path_entry OF((struct zlist far *));
+local void read_Unicode_Path_local_entry OF((struct zlist far *));
+#endif
+
+/* added these self allocators - 2/6/2005 EG */
+local void append_ushort_to_mem OF((ush, char **, extent *, extent *));
+local void append_ulong_to_mem OF((ulg, char **, extent *, extent *));
+#ifdef ZIP64_SUPPORT
+ local void append_int64_to_mem OF((uzoff_t, char **, extent *, extent *));
+#endif /* def ZIP64_SUPPORT */
+local void append_string_to_mem OF((char *, int, char**, extent *, extent *));
/* Local functions */
+local int find_next_signature OF((FILE *f));
+local int find_signature OF((FILE *, ZCONST char *));
+local int is_signature OF((ZCONST char *, ZCONST char *));
+local int at_signature OF((FILE *, ZCONST char *));
+
local int zqcmp OF((ZCONST zvoid *, ZCONST zvoid *));
-local int scanzipf_reg OF((FILE *f));
+#ifdef UNICODE_SUPPORT
+local int zuqcmp OF((ZCONST zvoid *, ZCONST zvoid *));
+#endif
+#if 0
+ local int scanzipf_reg OF((FILE *f));
+#endif
+local int scanzipf_regnew OF((void));
#ifndef UTIL
- local int rqcmp OF((ZCONST zvoid *, ZCONST zvoid *));
- local int zbcmp OF((ZCONST zvoid *, ZCONST zvoid far *));
- local void zipoddities OF((struct zlist far *));
- local int scanzipf_fix OF((FILE *f));
-# ifdef USE_EF_UT_TIME
- local int ef_scan_ut_time OF((char *ef_buf, extent ef_len, int ef_is_cent,
+ local int rqcmp OF((ZCONST zvoid *, ZCONST zvoid *));
+ local int zbcmp OF((ZCONST zvoid *, ZCONST zvoid far *));
+# ifdef UNICODE_SUPPORT
+ local int zubcmp OF((ZCONST zvoid *, ZCONST zvoid far *));
+# if 0
+ local int zuebcmp OF((ZCONST zvoid *, ZCONST zvoid far *));
+# endif
+# endif /* UNICODE_SUPPORT */
+ local void zipoddities OF((struct zlist far *));
+# if 0
+ local int scanzipf_fix OF((FILE *f));
+# endif
+ local int scanzipf_fixnew OF((void));
+# ifdef USE_EF_UT_TIME
+ local int ef_scan_ut_time OF((char *ef_buf, extent ef_len, int ef_is_cent,
iztimes *z_utim));
-# endif /* USE_EF_UT_TIME */
- local void cutpath OF((char *p, int delim));
+# endif /* USE_EF_UT_TIME */
+ local void cutpath OF((char *p, int delim));
#endif /* !UTIL */
/*
@@ -120,15 +240,35 @@ local int scanzipf_reg OF((FILE *f));
ulg amiga_sfx_offset; /* place where size field needs updating */
#endif
-
local int zqcmp(a, b)
ZCONST zvoid *a, *b; /* pointers to pointers to zip entries */
/* Used by qsort() to compare entries in the zfile list.
* Compares the internal names z->iname */
{
- return namecmp((*(struct zlist far **)a)->iname,
- (*(struct zlist far **)b)->iname);
+ char *aname = (*(struct zlist far **)a)->iname;
+ char *bname = (*(struct zlist far **)b)->iname;
+
+ return namecmp(aname, bname);
+}
+
+#ifdef UNICODE_SUPPORT
+local int zuqcmp(a, b)
+ZCONST zvoid *a, *b; /* pointers to pointers to zip entries */
+/* Used by qsort() to compare entries in the zfile list.
+ * Compares the internal names z->zuname */
+{
+ char *aname = (*(struct zlist far **)a)->iname;
+ char *bname = (*(struct zlist far **)b)->iname;
+
+ /* zuname could be NULL */
+ if ((*(struct zlist far **)a)->zuname)
+ aname = (*(struct zlist far **)a)->zuname;
+ if ((*(struct zlist far **)b)->zuname)
+ bname = (*(struct zlist far **)b)->zuname;
+ return namecmp(aname, bname);
}
+#endif
+
#ifndef UTIL
@@ -150,30 +290,76 @@ ZCONST zvoid far *z; /* pointer to a pointer to a zip entry */
return namecmp((char *)n, ((struct zlist far *)z)->zname);
}
+#ifdef UNICODE_SUPPORT
+/* search unicode paths */
+local int zubcmp(n, z)
+ZCONST zvoid *n; /* string to search for */
+ZCONST zvoid far *z; /* pointer to a pointer to a zip entry */
+/* Used by search() to compare a target to an entry in the zfile list. */
+{
+ char *zuname = ((struct zlist far *)z)->zuname;
+
+ /* zuname is NULL if no UTF-8 name */
+ if (zuname == NULL)
+ zuname = ((struct zlist far *)z)->zname;
+
+ return namecmp((char *)n, zuname);
+}
+
+#if 0
+/* search escaped unicode paths */
+local int zuebcmp(n, z)
+ZCONST zvoid *n; /* string to search for */
+ZCONST zvoid far *z; /* pointer to a pointer to a zip entry */
+/* Used by search() to compare a target to an entry in the zfile list. */
+{
+ char *zuname = ((struct zlist far *)z)->zuname;
+ char *zuename;
+ int k;
+
+ /* zuname is NULL if no UTF-8 name */
+ if (zuname == NULL)
+ zuname = ((struct zlist far *)z)->zname;
+ zuename = local_to_escape_string(zuname);
+ k = namecmp((char *)n, zuename);
+ free(zuename);
+
+ return k;
+}
+#endif
+#endif
+
struct zlist far *zsearch(n)
-ZCONST char *n; /* name to find */
+ ZCONST char *n; /* name to find */
/* Return a pointer to the entry in zfile with the name n, or NULL if
not found. */
{
zvoid far **p; /* result of search() */
- if (zcount &&
- (p = search(n, (ZCONST zvoid far **)zsort, zcount, zbcmp)) != NULL)
- return *(struct zlist far **)p;
- else
- return NULL;
+ if (zcount) {
+ if ((p = search(n, (ZCONST zvoid far **)zsort, zcount, zbcmp)) != NULL)
+ return *(struct zlist far **)p;
+#ifdef UNICODE_SUPPORT
+ else if (unicode_mismatch != 3 && fix != 2 &&
+ (p = search(n, (ZCONST zvoid far **)zusort, zcount, zubcmp)) != NULL)
+ return *(struct zlist far **)p;
+#endif
+ else
+ return NULL;
+ }
+ return NULL;
}
#endif /* !UTIL */
-#ifndef VMS
+#ifndef VMS /* See [.VMS]VMS.C for VMS-specific ziptyp(). */
# ifndef PATHCUT
# define PATHCUT '/'
# endif
char *ziptyp(s)
-char *s; /* file name to force to zip */
+ char *s; /* file name to force to zip */
/* If the file name *s has a dot (other than the first char), or if
the -A option is used (adjust self-extracting file) then return
the name, otherwise append .zip to the name. Allocate the space for
@@ -182,52 +368,53 @@ char *s; /* file name to force to zip */
{
char *q; /* temporary pointer */
char *t; /* pointer to malloc'ed string */
-#ifdef THEOS
+# ifdef THEOS
char *r; /* temporary pointer */
char *disk;
-#endif
+# endif
if ((t = malloc(strlen(s) + 5)) == NULL)
return NULL;
strcpy(t, s);
-#ifdef __human68k__
+# ifdef __human68k__
_toslash(t);
-#endif
-#ifdef MSDOS
+# endif
+# ifdef MSDOS
for (q = t; *q; INCSTR(q))
if (*q == '\\')
*q = '/';
-#endif /* MSDOS */
-#ifdef __RSXNT__ /* RSXNT/EMX C rtl uses OEM charset */
+# endif /* MSDOS */
+# if defined(__RSXNT__) || defined(WIN32_CRT_OEM)
+ /* RSXNT/EMX C rtl uses OEM charset */
AnsiToOem(t, t);
-#endif
+# endif
if (adjust) return t;
-#ifndef RISCOS
-# ifndef QDOS
-# ifdef AMIGA
+# ifndef RISCOS
+# ifndef QDOS
+# ifdef AMIGA
if ((q = MBSRCHR(t, '/')) == NULL)
q = MBSRCHR(t, ':');
if (MBSRCHR((q ? q + 1 : t), '.') == NULL)
-# else /* !AMIGA */
-# ifdef THEOS
+# else /* !AMIGA */
+# ifdef THEOS
/* the argument expansion add a dot to the end of file names when
* there is no extension and at least one of a argument has wild cards.
* So check for at least one character in the extension if there is a dot
* in file name */
if ((q = MBSRCHR((q = MBSRCHR(t, PATHCUT)) == NULL ? t : q + 1, '.')) == NULL
|| q[1] == '\0') {
-# else /* !THEOS */
-# ifdef TANDEM
+# else /* !THEOS */
+# ifdef TANDEM
if (MBSRCHR((q = MBSRCHR(t, '.')) == NULL ? t : q + 1, ' ') == NULL)
-# else /* !TANDEM */
+# else /* !TANDEM */
if (MBSRCHR((q = MBSRCHR(t, PATHCUT)) == NULL ? t : q + 1, '.') == NULL)
-# endif /* ?TANDEM */
-# endif /* ?THEOS */
-# endif /* ?AMIGA */
-# ifdef CMS_MVS
+# endif /* ?TANDEM */
+# endif /* ?THEOS */
+# endif /* ?AMIGA */
+# ifdef CMS_MVS
if (strncmp(t,"dd:",3) != 0 && strncmp(t,"DD:",3) != 0)
-# endif /* CMS_MVS */
-# ifdef THEOS
+# endif /* CMS_MVS */
+# ifdef THEOS
/* insert .zip extension before disk name */
if ((r = MBSRCHR(t, ':')) != NULL) {
/* save disk name */
@@ -243,79 +430,1336 @@ char *s; /* file name to force to zip */
strcat(t, ".zip");
}
}
-# else /* !THEOS */
-# ifdef TANDEM /* Tandem can't cope with extensions */
+# else /* !THEOS */
+# ifdef TANDEM /* Tandem can't cope with extensions */
strcat(t, " ZIP");
-# else /* !TANDEM */
+# else /* !TANDEM */
strcat(t, ".zip");
-# endif /* ?TANDEM */
-# endif /* ?THEOS */
-# else /* QDOS */
+# endif /* ?TANDEM */
+# endif /* ?THEOS */
+# else /* QDOS */
q = LastDir(t);
if(MBSRCHR(q, '_') == NULL && MBSRCHR(q, '.') == NULL)
{
strcat(t, "_zip");
}
-# endif /* QDOS */
-#endif /* !RISCOS */
+# endif /* QDOS */
+# endif /* !RISCOS */
return t;
}
+#endif /* ndef VMS */
-#else /* VMS */
+/* ---------------------------------------------------- */
-# define PATHCUT ']'
+/* moved out of ZIP64_SUPPORT - 2/6/2005 EG */
-char *ziptyp(s)
-char *s;
-{ int status;
- struct FAB fab;
- struct NAM nam;
- static char zero=0;
- char result[NAM$C_MAXRSS+1],exp[NAM$C_MAXRSS+1];
- char *p;
+/* 08/31/2003 R.Nausedat */
+
+local void write_ushort_to_mem( OFT( ush) usValue,
+ OFT( char *)pPtr)
+#ifdef NO_PROTO
+ ush usValue;
+ char *pPtr;
+#endif /* def NO_PROTO */
+{
+ *pPtr++ = ((char)(usValue) & 0xff);
+ *pPtr = ((char)(usValue >> 8) & 0xff);
+}
+
+local void write_ulong_to_mem(uValue, pPtr)
+ulg uValue;
+char *pPtr;
+{
+ write_ushort_to_mem((ush)(uValue & 0xffff), pPtr);
+ write_ushort_to_mem((ush)((uValue >> 16) & 0xffff), pPtr + 2);
+}
+
+#ifdef ZIP64_SUPPORT
+
+local void write_int64_to_mem(l64Value,pPtr)
+ uzoff_t l64Value;
+ char *pPtr;
+{
+ write_ulong_to_mem((ulg)(l64Value & 0xffffffff),pPtr);
+ write_ulong_to_mem((ulg)((l64Value >> 32) & 0xffffffff),pPtr + 4);
+}
+
+#endif /* def ZIP64_SUPPORT */
+
+#ifdef UNICODE_SUPPORT
+
+/* Write a string to memory */
+local void write_string_to_mem(strValue, pPtr)
+ char *strValue;
+ char *pPtr;
+{
+ if (strValue != NULL) {
+ int ssize = strlen(strValue);
+ int i;
+
+ for (i = 0; i < ssize; i++) {
+ *(pPtr + i) = *(strValue + i);
+ }
+ }
+}
+
+#endif /* def UNICODE_SUPPORT */
+
+
+
+/* same as above but allocate memory as needed and keep track of current end
+ using offset - 2/6/05 EG */
+
+#if 0 /* ubyte version not used */
+local void append_ubyte_to_mem( OFT( unsigned char) ubValue,
+ OFT( char **) pPtr,
+ OFT( extent *) offset,
+ OFT( extent *) blocksize)
+#ifdef NO_PROTO
+ unsigned char ubValue; /* byte to append */
+ char **pPtr; /* start of block */
+ extent *offset; /* next byte to write */
+ extent *blocksize; /* current size of block */
+#endif /* def NO_PROTO */
+{
+ if (*pPtr == NULL) {
+ /* malloc a 1K block */
+ (*blocksize) = 1024;
+ *pPtr = (char *) malloc(*blocksize);
+ if (*pPtr == NULL) {
+ ziperr(ZE_MEM, "append_ubyte_to_mem");
+ }
+ }
+ /* if (*offset) + 1 > (*blocksize) - 1 */
+ else if ((*offset) > (*blocksize) - (1 + 1)) {
+ /* realloc a bigger block in 1 K increments */
+ (*blocksize) += 1024;
+ *pPtr = realloc(*pPtr, *blocksize);
+ if (*pPtr == NULL) {
+ ziperr(ZE_MEM, "append_ubyte_to_mem");
+ }
+ }
+ *(*pPtr + *offset) = ubValue;
+ (*offset)++;
+}
+#endif
+
+local void append_ushort_to_mem( OFT( ush) usValue,
+ OFT( char **) pPtr,
+ OFT( extent *) offset,
+ OFT( extent *) blocksize)
+#ifdef NO_PROTO
+ ush usValue;
+ char **pPtr;
+ extent *offset;
+ extent *blocksize;
+#endif /* def NO_PROTO */
+{
+ if (*pPtr == NULL) {
+ /* malloc a 1K block */
+ (*blocksize) = 1024;
+ *pPtr = (char *) malloc(*blocksize);
+ if (*pPtr == NULL) {
+ ziperr(ZE_MEM, "append_ushort_to_mem");
+ }
+ }
+ /* if (*offset) + 2 > (*blocksize) - 1 */
+ else if ((*offset) > (*blocksize) - (1 + 2)) {
+ /* realloc a bigger block in 1 K increments */
+ (*blocksize) += 1024;
+ *pPtr = realloc(*pPtr, (extent)*blocksize);
+ if (*pPtr == NULL) {
+ ziperr(ZE_MEM, "append_ushort_to_mem");
+ }
+ }
+ write_ushort_to_mem(usValue, (*pPtr) + (*offset));
+ (*offset) += 2;
+}
+
+local void append_ulong_to_mem(uValue, pPtr, offset, blocksize)
+ ulg uValue;
+ char **pPtr;
+ extent *offset;
+ extent *blocksize;
+{
+ if (*pPtr == NULL) {
+ /* malloc a 1K block */
+ (*blocksize) = 1024;
+ *pPtr = (char *) malloc(*blocksize);
+ if (*pPtr == NULL) {
+ ziperr(ZE_MEM, "append_ulong_to_mem");
+ }
+ }
+ else if ((*offset) > (*blocksize) - (1 + 4)) {
+ /* realloc a bigger block in 1 K increments */
+ (*blocksize) += 1024;
+ *pPtr = realloc(*pPtr, *blocksize);
+ if (*pPtr == NULL) {
+ ziperr(ZE_MEM, "append_ulong_to_mem");
+ }
+ }
+ write_ulong_to_mem(uValue, (*pPtr) + (*offset));
+ (*offset) += 4;
+}
+
+#ifdef ZIP64_SUPPORT
+
+local void append_int64_to_mem(l64Value, pPtr, offset, blocksize)
+ uzoff_t l64Value;
+ char **pPtr;
+ extent *offset;
+ extent *blocksize;
+{
+ if (*pPtr == NULL) {
+ /* malloc a 1K block */
+ (*blocksize) = 1024;
+ *pPtr = (char *) malloc(*blocksize);
+ if (*pPtr == NULL) {
+ ziperr(ZE_MEM, "append_int64_to_mem");
+ }
+ }
+ else if ((*offset) > (*blocksize) - (1 + 8)) {
+ /* realloc a bigger block in 1 K increments */
+ (*blocksize) += 1024;
+ *pPtr = realloc(*pPtr, *blocksize);
+ if (*pPtr == NULL) {
+ ziperr(ZE_MEM, "append_int64_to_mem");
+ }
+ }
+ write_int64_to_mem(l64Value, (*pPtr) + (*offset));
+ (*offset) += 8;
+}
+
+#endif /* def ZIP64_SUPPORT */
+
+/* Append a string to the memory block. */
+local void append_string_to_mem(strValue, strLength, pPtr, offset, blocksize)
+ char *strValue;
+ int strLength;
+ char **pPtr;
+ extent *offset;
+ extent *blocksize;
+{
+ if (strValue != NULL) {
+ unsigned bsize = 1024;
+ unsigned ssize = strLength;
+ unsigned i;
+
+ if (ssize > bsize) {
+ bsize = ssize;
+ }
+ if (*pPtr == NULL) {
+ /* malloc a 1K block */
+ (*blocksize) = bsize;
+ *pPtr = (char *) malloc(*blocksize);
+ if (*pPtr == NULL) {
+ ziperr(ZE_MEM, "append_string_to_mem");
+ }
+ }
+ else if ((*offset) + ssize > (*blocksize) - 1) {
+ /* realloc a bigger block in 1 K increments */
+ (*blocksize) += bsize;
+ *pPtr = realloc(*pPtr, *blocksize);
+ if (*pPtr == NULL) {
+ ziperr(ZE_MEM, "append_string_to_mem");
+ }
+ }
+ for (i = 0; i < ssize; i++) {
+ *(*pPtr + *offset + i) = *(strValue + i);
+ }
+ (*offset) += ssize;
+ }
+}
+
+/* ---------------------------------------------------- */
+
+/* zip64 support 08/31/2003 R.Nausedat */
+/* moved out of zip64 support 10/22/05 */
+
+/* Searches pExtra for extra field with specified tag.
+ * If it finds one it returns a pointer to it, else NULL.
+ * Renamed and made generic. 10/3/03
+ */
+char *get_extra_field( OFT( ush) tag,
+ OFT( char *) pExtra,
+ OFT( unsigned) iExtraLen)
+#ifdef NO_PROTO
+ ush tag; /* tag to look for */
+ char *pExtra; /* pointer to extra field in memory */
+ unsigned iExtraLen; /* length of extra field */
+#endif /* def NO_PROTO */
+{
+ char *pTemp;
+ ush usBlockTag;
+ ush usBlockSize;
- fab = cc$rms_fab;
- nam = cc$rms_nam;
+ if( pExtra == NULL )
+ return NULL;
- fab.fab$l_fna = s;
- fab.fab$b_fns = strlen(fab.fab$l_fna);
+ for (pTemp = pExtra; pTemp < pExtra + iExtraLen - ZIP_EF_HEADER_SIZE;)
+ {
+ usBlockTag = SH(pTemp); /* get tag */
+ usBlockSize = SH(pTemp + 2); /* get field data size */
+ if (usBlockTag == tag)
+ return pTemp;
+ pTemp += (usBlockSize + ZIP_EF_HEADER_SIZE);
+ }
+ return NULL;
+}
- fab.fab$l_dna = "sys$disk:[].zip"; /* Default fspec */
- fab.fab$b_dns = strlen(fab.fab$l_dna);
+/* copy_nondup_extra_fields
+ *
+ * Copy any extra fields in old that are not in new to new.
+ * Returns the new extra fields block and newLen is new length.
+ */
+char *copy_nondup_extra_fields(oldExtra, oldExtraLen, newExtra, newExtraLen, newLen)
+ char *oldExtra; /* pointer to old extra fields */
+ unsigned oldExtraLen; /* length of old extra fields */
+ char *newExtra; /* pointer to new extra fields */
+ unsigned newExtraLen; /* length of new extra fields */
+ unsigned *newLen; /* length of new extra fields after copy */
+{
+ char *returnExtra = NULL;
+ ush returnExtraLen = 0;
+ char *tempExtra;
+ char *pTemp;
+ ush tag;
+ ush blocksize;
+
+ if( oldExtra == NULL ) {
+ /* no old extra fields so return copy of newExtra */
+ if (newExtra == NULL || newExtraLen == 0) {
+ *newLen = 0;
+ return NULL;
+ } else {
+ if ((returnExtra = malloc(newExtraLen)) == NULL)
+ ZIPERR(ZE_MEM, "extra field copy");
+ memcpy(returnExtra, newExtra, newExtraLen);
+ returnExtraLen = newExtraLen;
+ *newLen = returnExtraLen;
+ return returnExtra;
+ }
+ }
- fab.fab$l_nam = &nam;
+ /* allocate block large enough for all extra fields */
+ if ((tempExtra = malloc(0xFFFF)) == NULL)
+ ZIPERR(ZE_MEM, "extra field copy");
- nam.nam$l_rsa = result; /* Put resultant name of */
- nam.nam$b_rss = sizeof(result)-1; /* existing zipfile here */
+ /* look for each old extra field in new block */
+ for (pTemp = oldExtra; pTemp < oldExtra + oldExtraLen;)
+ {
+ tag = SH(pTemp); /* get tag */
+ blocksize = SH(pTemp + 2); /* get field data size */
+ if (get_extra_field(tag, newExtra, newExtraLen) == NULL) {
+ /* tag not in new block so add it */
+ memcpy(tempExtra + returnExtraLen, pTemp, blocksize + 4);
+ returnExtraLen += blocksize + 4;
+ }
+ pTemp += blocksize + 4;
+ }
- nam.nam$l_esa = exp; /* For full spec of */
- nam.nam$b_ess = sizeof(exp)-1; /* file to create */
+ /* copy all extra fields from new block */
+ memcpy(tempExtra + returnExtraLen, newExtra, newExtraLen);
+ returnExtraLen += newExtraLen;
- status = sys$parse(&fab);
- if( (status & 1) == 0 )
- return &zero;
+ /* copy tempExtra to returnExtra */
+ if ((returnExtra = malloc(returnExtraLen)) == NULL)
+ ZIPERR(ZE_MEM, "extra field copy");
+ memcpy(returnExtra, tempExtra, returnExtraLen);
+ free(tempExtra);
- status = sys$search(&fab);
- if( status & 1 )
- { /* Existing ZIP file */
- int l;
- if( (p=malloc( (l=nam.nam$b_rsl) + 1 )) != NULL )
- { result[l] = 0;
- strcpy(p,result);
+ *newLen = returnExtraLen;
+ return returnExtra;
+}
+
+#ifdef UNICODE_SUPPORT
+
+/* The latest format is
+ 1 byte Version of Unicode Path Extra Field
+ 4 bytes Name Field CRC32 Checksum
+ variable UTF-8 Version Of Name
+ */
+
+local void read_Unicode_Path_entry(pZipListEntry)
+ struct zlist far *pZipListEntry;
+{
+ char *pTemp;
+ char *UPath;
+ char *iname;
+ ush ELen;
+ uch Version;
+ ush ULen;
+ ulg chksum = CRCVAL_INITIAL;
+ ulg iname_chksum;
+
+ /* check if we have a Unicode Path extra field ... */
+ pTemp = get_extra_field( UTF8_PATH_EF_TAG, pZipListEntry->cextra, pZipListEntry->cext );
+ pZipListEntry->uname = NULL;
+ if( pTemp == NULL ) {
+ return;
+ }
+
+ /* ... if so, update corresponding entries in struct zlist */
+
+ pTemp += 2;
+
+ /* length of this extra field */
+ ELen = SH(pTemp);
+ pTemp += 2;
+
+ /* version */
+ Version = (uch) *pTemp;
+ pTemp += 1;
+ if (Version > 1) {
+ zipwarn("Unicode Path Extra Field version > 1 - skipping", pZipListEntry->oname);
+ return;
+ }
+
+ /* iname CRC */
+ iname_chksum = LG(pTemp);
+ pTemp += 4;
+
+ /*
+ * Compute the CRC-32 checksum of iname
+ */
+/*
+ crc_16 = crc16f((uch *)(pZipListEntry->iname), strlen(pZipListEntry->iname));
+ */
+
+ if ((iname = malloc(strlen(pZipListEntry->iname) + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "write Unicode");
+ }
+ strcpy(iname, pZipListEntry->iname);
+
+ chksum = crc32(chksum, (uch *)(iname), strlen(iname));
+
+ free(iname);
+
+/* chksum = adler16(ADLERVAL_INITIAL,
+ (uch *)(pZipListEntry->iname), strlen(pZipListEntry->iname));
+*/
+
+ /* If the checksums's don't match then likely iname has been modified and
+ * the Unicode Path is no longer valid
+ */
+ if (chksum != iname_chksum) {
+ printf("unicode_mismatch = %d\n", unicode_mismatch);
+ if (unicode_mismatch == 1) {
+ /* warn and continue */
+ zipwarn("Unicode does not match path - ignoring Unicode: ", pZipListEntry->oname);
+ } else if (unicode_mismatch == 2) {
+ /* ignore and continue */
+ } else if (unicode_mismatch == 0) {
+ /* error */
+ sprintf(errbuf, "Unicode does not match path: %s\n", pZipListEntry->oname);
+ strcat(errbuf,
+ " Likely entry name changed but Unicode not updated\n");
+ strcat(errbuf,
+ " Use -UN=i to ignore errors or n for no Unicode paths");
+ zipwarn(errbuf, "");
+ ZIPERR(ZE_FORM, "Unicode path error");
+ }
+ return;
+ }
+
+ ULen = ELen - 5;
+
+ /* UTF-8 Path */
+ if (ULen == 0) {
+ /* standard path is UTF-8 so use that */
+ ULen = pZipListEntry->nam;
+ if ((UPath = malloc(ULen + 1)) == NULL) {
+ return;
+ }
+ strcpy(UPath, pZipListEntry->name);
+ } else {
+ /* use Unicode path */
+ if ((UPath = malloc(ULen + 1)) == NULL) {
+ return;
+ }
+ strncpy(UPath, pTemp, ULen);
+ UPath[ULen] = '\0';
+ }
+ pZipListEntry->uname = UPath;
+ return;
+}
+
+local void read_Unicode_Path_local_entry(pZipListEntry)
+ struct zlist far *pZipListEntry;
+{
+ char *pTemp;
+ char *UPath;
+ char *iname;
+ ush ELen;
+ uch Version;
+ ush ULen;
+ ulg chksum = CRCVAL_INITIAL;
+ ulg iname_chksum;
+
+ /* check if we have a Unicode Path extra field ... */
+ pTemp = get_extra_field( UTF8_PATH_EF_TAG, pZipListEntry->extra, pZipListEntry->ext );
+ pZipListEntry->uname = NULL;
+ if( pTemp == NULL ) {
+ return;
+ }
+
+ /* ... if so, update corresponding entries in struct zlist */
+
+ pTemp += 2;
+
+ /* length of this extra field */
+ ELen = SH(pTemp);
+ pTemp += 2;
+
+ /* version */
+ Version = (uch) *pTemp;
+ pTemp += 1;
+ if (Version > 1) {
+ zipwarn("Unicode Path Extra Field version > 1 - skipping", pZipListEntry->oname);
+ return;
+ }
+
+ /* iname CRC */
+ iname_chksum = LG(pTemp);
+ pTemp += 4;
+
+ /*
+ * Compute 32-bit crc of iname and AND halves to make 16-bit version
+ */
+ /*
+ chksum = adler16(ADLERVAL_INITIAL,
+ (uch *)(pZipListEntry->iname), strlen(pZipListEntry->iname));
+ */
+
+ if ((iname = malloc(strlen(pZipListEntry->iname) + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "write Unicode");
+ }
+ strcpy(iname, pZipListEntry->iname);
+
+ chksum = crc32(chksum, (uch *)(iname), strlen(iname));
+
+ free(iname);
+
+ /* If the checksums's don't match then likely iname has been modified and
+ * the Unicode Path is no longer valid
+ */
+ if (chksum != iname_chksum) {
+ if (unicode_mismatch == 1) {
+ /* warn and continue */
+ zipwarn("Unicode does not match path - ignoring Unicode: ", pZipListEntry->oname);
+ } else if (unicode_mismatch == 2) {
+ /* ignore and continue */
+ } else if (unicode_mismatch == 0) {
+ /* error */
+ sprintf(errbuf, "Unicode does not match path: %s\n", pZipListEntry->oname);
+ strcat(errbuf,
+ " Likely entry name changed but Unicode not updated\n");
+ strcat(errbuf,
+ " Use -UN=i to ignore errors or n for no Unicode paths");
+ zipwarn(errbuf, "");
+ ZIPERR(ZE_FORM, "Unicode path error");
+ }
+ return;
+ }
+
+ ULen = ELen - 5;
+
+ /* UTF-8 Path */
+ if (ULen == 0) {
+ /* standard path is UTF-8 so use that */
+ ULen = pZipListEntry->nam;
+ if ((UPath = malloc(ULen + 1)) == NULL) {
+ return;
+ }
+ strcpy(UPath, pZipListEntry->name);
+ } else {
+ /* use Unicode path */
+ if ((UPath = malloc(ULen + 1)) == NULL) {
+ return;
+ }
+ strncpy(UPath, pTemp, ULen);
+ UPath[ULen] = '\0';
+ }
+ pZipListEntry->uname = UPath;
+ return;
+}
+
+#endif /* def UNICODE_SUPPORT */
+
+#ifdef ZIP64_SUPPORT /* zip64 support 08/31/2003 R.Nausedat */
+
+/* searches the cextra member of zlist for a zip64 extra field. if it finds one it */
+/* updates the len, siz and off members of zlist with the corresponding values of */
+/* the zip64 extra field, that is if either the len, siz or off member of zlist is */
+/* set to its max value we have to use the corresponding value from the zip64 extra */
+/* field. as of now the dsk member of zlist is not much of interest since we should */
+/* not modify multi volume archives at all. */
+local void adjust_zip_central_entry(pZipListEntry)
+ struct zlist far *pZipListEntry;
+{
+ char *pTemp;
+
+ /* assume not using zip64 fields */
+ zip64_entry = 0;
+
+ /* check if we have a "large file" Zip64 extra field ... */
+ pTemp = get_extra_field( ZIP64_EF_TAG, pZipListEntry->cextra, pZipListEntry->cext );
+ if( pTemp == NULL )
+ return;
+
+ /* using zip64 field */
+ zip64_entry = 1;
+ pTemp += ZIP_EF_HEADER_SIZE;
+
+ /* ... if so, update corresponding entries in struct zlist */
+ if (pZipListEntry->len == ZIP_UWORD32_MAX)
+ {
+ pZipListEntry->len = LLG(pTemp);
+ pTemp += 8;
+ }
+
+ if (pZipListEntry->siz == ZIP_UWORD32_MAX)
+ {
+ pZipListEntry->siz = LLG(pTemp);
+ pTemp += 8;
+ }
+
+ if (pZipListEntry->off == ZIP_UWORD32_MAX)
+ {
+ pZipListEntry->off = LLG(pTemp);
+ pTemp += 8;
+ }
+
+ if (pZipListEntry->dsk == ZIP_UWORD16_MAX)
+ {
+ pZipListEntry->dsk = LG(pTemp);
+ }
+
+}
+
+
+/* adjust_zip_local_entry
+ *
+ * Return 1 if there is a Zip64 extra field and 0 if not
+ */
+local int adjust_zip_local_entry(pZipListEntry)
+ struct zlist far *pZipListEntry;
+{
+ char *pTemp;
+
+ /* assume not using zip64 fields */
+ zip64_entry = 0;
+
+ /* check if we have a "large file" Zip64 extra field ... */
+ pTemp = get_extra_field(ZIP64_EF_TAG, pZipListEntry->extra, pZipListEntry->ext );
+ if( pTemp == NULL )
+ return zip64_entry;
+
+ /* using zip64 field */
+ zip64_entry = 1;
+ pTemp += ZIP_EF_HEADER_SIZE;
+
+ /* ... if so, update corresponding entries in struct zlist */
+ if (pZipListEntry->len == ZIP_UWORD32_MAX)
+ {
+ pZipListEntry->len = LLG(pTemp);
+ pTemp += 8;
+ }
+
+ if (pZipListEntry->siz == ZIP_UWORD32_MAX)
+ {
+ pZipListEntry->siz = LLG(pTemp);
+ pTemp += 8;
+ }
+ return zip64_entry;
+}
+
+/* adds a zip64 extra field to the data the cextra member of zlist points to. If
+ * there is already a zip64 extra field present delete it first.
+ */
+local int add_central_zip64_extra_field(pZipListEntry)
+ struct zlist far *pZipListEntry;
+{
+ char *pExtraFieldPtr;
+ char *pTemp;
+ ush usTemp;
+ ush efsize = 0;
+ ush esize;
+ ush oldefsize;
+ extent len;
+ int used_zip64 = 0;
+
+ /* get length of ef based on which fields exceed limits */
+ /* AppNote says:
+ * 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.
+ */
+ efsize = ZIP_EF_HEADER_SIZE; /* type + size */
+ if (pZipListEntry->len > ZIP_UWORD32_MAX || force_zip64 == 1) {
+ /* compressed size */
+ efsize += 8;
+ used_zip64 = 1;
+ }
+ if (pZipListEntry->siz > ZIP_UWORD32_MAX) {
+ /* uncompressed size */
+ efsize += 8;
+ used_zip64 = 1;
+ }
+ if (pZipListEntry->off > ZIP_UWORD32_MAX) {
+ /* offset */
+ efsize += 8;
+ used_zip64 = 1;
+ }
+ if (pZipListEntry->dsk > ZIP_UWORD16_MAX) {
+ /* disk number */
+ efsize += 4;
+ used_zip64 = 1;
+ }
+
+ if (used_zip64 && force_zip64 == 0) {
+ zipwarn("Large entry support disabled using -fz- but needed", "");
+ return ZE_BIG;
+ }
+
+ /* malloc zip64 extra field? */
+ if( pZipListEntry->cextra == NULL )
+ {
+ if (efsize == ZIP_EF_HEADER_SIZE) {
+ return ZE_OK;
+ }
+ if ((pExtraFieldPtr = pZipListEntry->cextra = (char *) malloc(efsize)) == NULL) {
+ return ZE_MEM;
+ }
+ pZipListEntry->cext = efsize;
+ }
+ else
+ {
+ /* check if we have a "large file" extra field ... */
+ pExtraFieldPtr = get_extra_field(ZIP64_EF_TAG, pZipListEntry->cextra, pZipListEntry->cext);
+ if( pExtraFieldPtr == NULL )
+ {
+ /* ... we don't, so re-malloc enough memory for the old extra data plus
+ * the size of the zip64 extra field
+ */
+ if ((pExtraFieldPtr = (char *) malloc(efsize + pZipListEntry->cext)) == NULL) {
+ return ZE_MEM;
+ }
+ /* move the old extra field */
+ memmove(pExtraFieldPtr, pZipListEntry->cextra, pZipListEntry->cext);
+ free(pZipListEntry->cextra);
+ pZipListEntry->cextra = pExtraFieldPtr;
+ pExtraFieldPtr += pZipListEntry->cext;
+ pZipListEntry->cext += efsize;
+ }
+ else
+ {
+ /* ... we have. sort out the existing zip64 extra field and remove it from
+ * pZipListEntry->cextra, re-malloc enough memory for the old extra data
+ * left plus the size of the zip64 extra field
+ */
+ usTemp = SH(pExtraFieldPtr + 2);
+ /* if pZipListEntry->cextra == pExtraFieldPtr and pZipListEntry->cext == usTemp + efsize
+ * we should have only one extra field, and this is a zip64 extra field. as some
+ * zip tools seem to require fixed zip64 extra fields we have to check if
+ * usTemp + ZIP_EF_HEADER_SIZE is equal to ZIP64_LARGE_FILE_HEAD_SIZE. if it
+ * isn't, we free the old extra field and allocate memory for a new one
+ */
+ if( pZipListEntry->cext == (extent)(usTemp + ZIP_EF_HEADER_SIZE) )
+ {
+ /* just Zip64 extra field in extra field */
+ if( pZipListEntry->cext != efsize )
+ {
+ /* wrong size */
+ if ((pExtraFieldPtr = (char *) malloc(efsize)) == NULL) {
+ return ZE_MEM;
+ }
+ free(pZipListEntry->cextra);
+ pZipListEntry->cextra = pExtraFieldPtr;
+ pZipListEntry->cext = efsize;
+ }
+ }
+ else
+ {
+ /* get the old Zip64 extra field out and add new */
+ oldefsize = usTemp + ZIP_EF_HEADER_SIZE;
+ if ((pTemp = (char *) malloc(pZipListEntry->cext - oldefsize + efsize)) == NULL) {
+ return ZE_MEM;
}
+ len = (extent)(pExtraFieldPtr - pZipListEntry->cextra);
+ memcpy(pTemp, pZipListEntry->cextra, len);
+ memcpy(pTemp + len, pExtraFieldPtr + oldefsize,
+ pZipListEntry->cext - oldefsize - len);
+ pZipListEntry->cext -= oldefsize;
+ pExtraFieldPtr = pTemp + pZipListEntry->cext;
+ pZipListEntry->cext += efsize;
+ free(pZipListEntry->cextra);
+ pZipListEntry->cextra = pTemp;
+ }
+ }
+ }
+
+ /* set zip64 extra field members */
+ write_ushort_to_mem(ZIP64_EF_TAG, pExtraFieldPtr);
+ write_ushort_to_mem((ush) (efsize - ZIP_EF_HEADER_SIZE), pExtraFieldPtr + 2);
+ esize = ZIP_EF_HEADER_SIZE;
+ if (pZipListEntry->len > ZIP_UWORD32_MAX || force_zip64 == 1) {
+ write_int64_to_mem(pZipListEntry->len, pExtraFieldPtr + esize);
+ esize += 8;
+ }
+ if (pZipListEntry->siz > ZIP_UWORD32_MAX) {
+ write_int64_to_mem(pZipListEntry->siz, pExtraFieldPtr + esize);
+ esize += 8;
+ }
+ if (pZipListEntry->off > ZIP_UWORD32_MAX) {
+ write_int64_to_mem(pZipListEntry->off, pExtraFieldPtr + esize);
+ esize += 8;
+ }
+ if (pZipListEntry->dsk > ZIP_UWORD16_MAX) {
+ write_ulong_to_mem(pZipListEntry->dsk, pExtraFieldPtr + esize);
+ }
+
+ /* un' wech */
+ return ZE_OK;
+}
+
+#if 0
+/* Remove extra field in local extra field
+ * Return 1 if found, else 0
+ * 12/28/05
+ */
+local int remove_local_extra_field(pZEntry, tag)
+ struct zlist far *pZEntry;
+ ulg tag;
+{
+ char *pExtra;
+ char *pOldExtra;
+ char *pOldTemp;
+ char *pTemp;
+ ush newEFSize;
+ ush usTemp;
+ ush blocksize;
+
+ /* check if we have the extra field ... */
+ pOldExtra = get_extra_field( (ush)tag, pZEntry->extra, pZEntry->ext );
+ if (pOldExtra)
+ {
+ /* We have. Get rid of it. */
+ blocksize = SH( pOldExtra + 2 );
+ newEFSize = pZEntry->ext - blocksize;
+ pExtra = (char *) malloc( newEFSize );
+ if( pExtra == NULL )
+ ziperr(ZE_MEM, "Remove Local Extra Field");
+ /* move all before EF */
+ usTemp = (extent) (pOldExtra - pZEntry->extra);
+ pTemp = pExtra;
+ memcpy( pTemp, pZEntry->extra, usTemp );
+ /* move all after old Zip64 EF */
+ pTemp = pExtra + usTemp;
+ pOldTemp = pOldExtra + blocksize;
+ usTemp = pZEntry->ext - usTemp - blocksize;
+ memcpy( pTemp, pOldTemp, usTemp);
+ /* replace extra fields */
+ pZEntry->ext = newEFSize;
+ free(pZEntry->extra);
+ pZEntry->extra = pExtra;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/* Remove extra field in central extra field
+ * Return 1 if found, else 0
+ * 12/28/05
+ */
+local int remove_central_extra_field(pZEntry, tag)
+ struct zlist far *pZEntry;
+ ulg tag;
+{
+ char *pExtra;
+ char *pOldExtra;
+ char *pOldTemp;
+ char *pTemp;
+ ush newEFSize;
+ ush usTemp;
+ ush blocksize;
+
+ /* check if we have the extra field ... */
+ pOldExtra = get_extra_field( (ush)tag, pZEntry->cextra, pZEntry->cext );
+ if (pOldExtra)
+ {
+ /* We have. Get rid of it. */
+ blocksize = SH( pOldExtra + 2 );
+ newEFSize = pZEntry->cext - blocksize;
+ pExtra = (char *) malloc( newEFSize );
+ if( pExtra == NULL )
+ ziperr(ZE_MEM, "Remove Local Extra Field");
+ /* move all before EF */
+ usTemp = (extent) (pOldExtra - pZEntry->cextra);
+ pTemp = pExtra;
+ memcpy( pTemp, pZEntry->cextra, usTemp );
+ /* move all after old Zip64 EF */
+ pTemp = pExtra + usTemp;
+ pOldTemp = pOldExtra + blocksize;
+ usTemp = pZEntry->cext - usTemp - blocksize;
+ memcpy( pTemp, pOldTemp, usTemp);
+ /* replace extra fields */
+ pZEntry->cext = newEFSize;
+ free(pZEntry->cextra);
+ pZEntry->cextra = pExtra;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+#endif
+
+/* Add Zip64 extra field to local header
+ * 10/5/03 EG
+ */
+local int add_local_zip64_extra_field(pZEntry)
+ struct zlist far *pZEntry;
+{
+ char *pZ64Extra;
+ char *pOldZ64Extra;
+ char *pOldTemp;
+ char *pTemp;
+ ush newEFSize;
+ ush usTemp;
+ ush blocksize;
+ ush Z64LocalLen = ZIP_EF_HEADER_SIZE + /* tag + EF Data Len */
+ 8 + /* original uncompressed length of file */
+ 8; /* compressed size of file */
+
+ /* malloc zip64 extra field? */
+ /* after the below pZ64Extra should point to start of Zip64 extra field */
+ if (pZEntry->ext == 0 || pZEntry->extra == NULL)
+ {
+ /* get new extra field */
+ pZ64Extra = pZEntry->extra = (char *) malloc(Z64LocalLen);
+ if (pZEntry->extra == NULL) {
+ ziperr( ZE_MEM, "Zip64 local extra field" );
+ }
+ pZEntry->ext = Z64LocalLen;
+ }
+ else
+ {
+ /* check if we have a Zip64 extra field ... */
+ pOldZ64Extra = get_extra_field( ZIP64_EF_TAG, pZEntry->extra, pZEntry->ext );
+ if (pOldZ64Extra == NULL)
+ {
+ /* ... we don't, so re-malloc enough memory for the old extra data plus */
+ /* the size of the zip64 extra field */
+ pZ64Extra = (char *) malloc( Z64LocalLen + pZEntry->ext );
+ if (pZ64Extra == NULL)
+ ziperr( ZE_MEM, "Zip64 Extra Field" );
+ /* move old extra field and update pointer and length */
+ memmove( pZ64Extra, pZEntry->extra, pZEntry->ext);
+ free( pZEntry->extra );
+ pZEntry->extra = pZ64Extra;
+ pZ64Extra += pZEntry->ext;
+ pZEntry->ext += Z64LocalLen;
+ }
+ else
+ {
+ /* ... we have. Sort out the existing zip64 extra field and remove it
+ * from pZEntry->extra, re-malloc enough memory for the old extra data
+ * left plus the size of the zip64 extra field */
+ blocksize = SH( pOldZ64Extra + 2 );
+ /* If the right length then go with it, else get rid of it and add a new extra field
+ * to existing block. */
+ if (blocksize == Z64LocalLen - ZIP_EF_HEADER_SIZE)
+ {
+ /* looks good */
+ pZ64Extra = pOldZ64Extra;
+ }
+ else
+ {
+ newEFSize = pZEntry->ext - (blocksize + ZIP_EF_HEADER_SIZE) + Z64LocalLen;
+ pZ64Extra = (char *) malloc( newEFSize );
+ if( pZ64Extra == NULL )
+ ziperr(ZE_MEM, "Zip64 Extra Field");
+ /* move all before Zip64 EF */
+ usTemp = (extent) (pOldZ64Extra - pZEntry->extra);
+ pTemp = pZ64Extra;
+ memcpy( pTemp, pZEntry->extra, usTemp );
+ /* move all after old Zip64 EF */
+ pTemp = pZ64Extra + usTemp;
+ pOldTemp = pOldZ64Extra + ZIP_EF_HEADER_SIZE + blocksize;
+ usTemp = pZEntry->ext - usTemp - blocksize;
+ memcpy( pTemp, pOldTemp, usTemp);
+ /* replace extra fields */
+ pZEntry->ext = newEFSize;
+ free(pZEntry->extra);
+ pZEntry->extra = pZ64Extra;
+ pZ64Extra = pTemp + usTemp;
+ }
+ }
+ }
+ /* set/update zip64 extra field members */
+ write_ushort_to_mem(ZIP64_EF_TAG, pZ64Extra);
+ write_ushort_to_mem((ush) (Z64LocalLen - ZIP_EF_HEADER_SIZE), pZ64Extra + 2);
+ write_int64_to_mem(pZEntry->len, pZ64Extra + 2 + 2);
+ write_int64_to_mem(pZEntry->siz, pZ64Extra + 2 + 2 + 8);
+
+ return ZE_OK;
+}
+
+# endif /* ZIP64_SUPPORT */
+
+#ifdef UNICODE_SUPPORT
+/* Add UTF-8 path extra field
+ * 10/11/05
+ */
+local int add_Unicode_Path_local_extra_field(pZEntry)
+ struct zlist far *pZEntry;
+{
+ char *pUExtra;
+ char *pOldUExtra;
+ char *pOldTemp;
+ char *pTemp;
+#ifdef WIN32_OEM
+ char *inameLocal;
+#endif
+ ush newEFSize;
+ ush usTemp;
+ ush ULen = strlen(pZEntry->uname);
+ ush blocksize;
+ ulg chksum = CRCVAL_INITIAL;
+ ush ULocalLen = ZIP_EF_HEADER_SIZE + /* tag + EF Data Len */
+ 1 + /* version */
+ 4 + /* iname chksum */
+ ULen; /* UTF-8 path */
+
+ /* malloc Unicode Path extra field? */
+ /* after the below pUExtra should point to start of Unicode Path extra field */
+ if (pZEntry->ext == 0 || pZEntry->extra == NULL)
+ {
+ /* get new extra field */
+ pUExtra = pZEntry->extra = (char *) malloc(ULocalLen);
+ if (pZEntry->extra == NULL) {
+ ziperr( ZE_MEM, "UTF-8 Path local extra field" );
+ }
+ pZEntry->ext = ULocalLen;
+ }
+ else
+ {
+ /* check if we have a Unicode Path extra field ... */
+ pOldUExtra = get_extra_field( UTF8_PATH_EF_TAG, pZEntry->extra, pZEntry->ext );
+ if (pOldUExtra == NULL)
+ {
+ /* ... we don't, so re-malloc enough memory for the old extra data plus */
+ /* the size of the UTF-8 Path extra field */
+ pUExtra = (char *) malloc( ULocalLen + pZEntry->ext );
+ if (pUExtra == NULL)
+ ziperr( ZE_MEM, "UTF-8 Path Extra Field" );
+ /* move old extra field and update pointer and length */
+ memmove( pUExtra, pZEntry->extra, pZEntry->ext);
+ free( pZEntry->extra );
+ pZEntry->extra = pUExtra;
+ pUExtra += pZEntry->ext;
+ pZEntry->ext += ULocalLen;
}
else
- { /* New ZIP file */
- int l;
- if( (p=malloc( (l=nam.nam$b_esl) + 1 )) != NULL )
- { exp[l] = 0;
- strcpy(p,exp);
+ {
+ /* ... we have. Sort out the existing UTF-8 Path extra field and remove it
+ * from pZEntry->extra, re-malloc enough memory for the old extra data
+ * left plus the size of the UTF-8 Path extra field */
+ blocksize = SH( pOldUExtra + 2 );
+ /* If the right length then go with it, else get rid of it and add a new extra field
+ * to existing block. */
+ if (blocksize == ULocalLen - ZIP_EF_HEADER_SIZE)
+ {
+ /* looks good */
+ pUExtra = pOldUExtra;
+ }
+ else
+ {
+ newEFSize = pZEntry->ext - (blocksize + ZIP_EF_HEADER_SIZE) + ULocalLen;
+ pUExtra = (char *) malloc( newEFSize );
+ if( pUExtra == NULL )
+ ziperr(ZE_MEM, "UTF-8 Path Extra Field");
+ /* move all before UTF-8 Path EF */
+ usTemp = (extent) (pOldUExtra - pZEntry->extra);
+ pTemp = pUExtra;
+ memcpy( pTemp, pZEntry->extra, usTemp );
+ /* move all after old UTF-8 Path EF */
+ pTemp = pUExtra + usTemp;
+ pOldTemp = pOldUExtra + ZIP_EF_HEADER_SIZE + blocksize;
+ usTemp = pZEntry->ext - usTemp - blocksize;
+ memcpy( pTemp, pOldTemp, usTemp);
+ /* replace extra fields */
+ pZEntry->ext = newEFSize;
+ free(pZEntry->extra);
+ pZEntry->extra = pUExtra;
+ pUExtra = pTemp + usTemp;
+ }
+ }
+ }
+
+ /*
+ * Compute the Adler-16 checksum of iname
+ */
+/*
+ chksum = adler16(ADLERVAL_INITIAL,
+ (uch *)(pZEntry->iname), strlen(pZEntry->iname));
+*/
+
+#ifdef WIN32_OEM
+ if ((inameLocal = malloc(strlen(pZEntry->iname) + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "write Unicode");
+ }
+ /* if oem translation done convert back for checksum */
+ if ((pZEntry->vem & 0xff00) == 0) {
+ /* get original */
+ INTERN_TO_OEM(pZEntry->iname, inameLocal);
+ } else {
+ strcpy(inameLocal, pZEntry->iname);
+ }
+#else
+# define inameLocal (pZEntry->iname)
+#endif
+
+ chksum = crc32(chksum, (uch *)(inameLocal), strlen(inameLocal));
+
+#ifdef WIN32_OEM
+ free(inameLocal);
+#else
+# undef inameLocal
+#endif
+
+ /* set/update UTF-8 Path extra field members */
+ /* tag header */
+ write_ushort_to_mem(UTF8_PATH_EF_TAG, pUExtra);
+ /* data size */
+ write_ushort_to_mem((ush) (ULocalLen - ZIP_EF_HEADER_SIZE), pUExtra + 2);
+ /* version */
+ *(pUExtra + 2 + 2) = 1;
+ /* iname chksum */
+ write_ulong_to_mem(chksum, pUExtra + 2 + 2 + 1);
+ /* UTF-8 path */
+ write_string_to_mem(pZEntry->uname, pUExtra + 2 + 2 + 1 + 4);
+
+ return ZE_OK;
+}
+
+local int add_Unicode_Path_cen_extra_field(pZEntry)
+ struct zlist far *pZEntry;
+{
+ char *pUExtra;
+ char *pOldUExtra;
+ char *pOldTemp;
+ char *pTemp;
+#ifdef WIN32_OEM
+ char *inameLocal;
+#endif
+ ush newEFSize;
+ ush usTemp;
+ ush ULen = strlen(pZEntry->uname);
+ ush blocksize;
+ ulg chksum = CRCVAL_INITIAL;
+ ush UCenLen = ZIP_EF_HEADER_SIZE + /* tag + EF Data Len */
+ 1 + /* version */
+ 4 + /* checksum */
+ ULen; /* UTF-8 path */
+
+ /* malloc Unicode Path extra field? */
+ /* after the below pUExtra should point to start of Unicode Path extra field */
+ if (pZEntry->cext == 0 || pZEntry->cextra == NULL)
+ {
+ /* get new extra field */
+ pUExtra = pZEntry->cextra = (char *) malloc(UCenLen);
+ if (pZEntry->cextra == NULL) {
+ ziperr( ZE_MEM, "UTF-8 Path cen extra field" );
+ }
+ pZEntry->cext = UCenLen;
+ }
+ else
+ {
+ /* check if we have a Unicode Path extra field ... */
+ pOldUExtra = get_extra_field( UTF8_PATH_EF_TAG, pZEntry->cextra, pZEntry->cext );
+ if (pOldUExtra == NULL)
+ {
+ /* ... we don't, so re-malloc enough memory for the old extra data plus */
+ /* the size of the UTF-8 Path extra field */
+ pUExtra = (char *) malloc( UCenLen + pZEntry->cext );
+ if (pUExtra == NULL)
+ ziperr( ZE_MEM, "UTF-8 Path Extra Field" );
+ /* move old extra field and update pointer and length */
+ memmove( pUExtra, pZEntry->cextra, pZEntry->cext);
+ free( pZEntry->cextra );
+ pZEntry->cextra = pUExtra;
+ pUExtra += pZEntry->cext;
+ pZEntry->cext += UCenLen;
+ }
+ else
+ {
+ /* ... we have. Sort out the existing UTF-8 Path extra field and remove it
+ * from pZEntry->extra, re-malloc enough memory for the old extra data
+ * left plus the size of the UTF-8 Path extra field */
+ blocksize = SH( pOldUExtra + 2 );
+ /* If the right length then go with it, else get rid of it and add a new extra field
+ * to existing block. */
+ if (blocksize == UCenLen - ZIP_EF_HEADER_SIZE)
+ {
+ /* looks good */
+ pUExtra = pOldUExtra;
+ }
+ else
+ {
+ newEFSize = pZEntry->cext - (blocksize + ZIP_EF_HEADER_SIZE) + UCenLen;
+ pUExtra = (char *) malloc( newEFSize );
+ if( pUExtra == NULL )
+ ziperr(ZE_MEM, "UTF-8 Path Extra Field");
+ /* move all before UTF-8 Path EF */
+ usTemp = (extent) (pOldUExtra - pZEntry->cextra);
+ pTemp = pUExtra;
+ memcpy( pTemp, pZEntry->cextra, usTemp );
+ /* move all after old UTF-8 Path EF */
+ pTemp = pUExtra + usTemp;
+ pOldTemp = pOldUExtra + ZIP_EF_HEADER_SIZE + blocksize;
+ usTemp = pZEntry->cext - usTemp - blocksize;
+ memcpy( pTemp, pOldTemp, usTemp);
+ /* replace extra fields */
+ pZEntry->cext = newEFSize;
+ free(pZEntry->cextra);
+ pZEntry->cextra = pUExtra;
+ pUExtra = pTemp + usTemp;
+ }
+ }
+ }
+
+ /*
+ * Compute the CRC-32 checksum of iname
+ */
+#ifdef WIN32_OEM
+ if ((inameLocal = malloc(strlen(pZEntry->iname) + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "write Unicode");
+ }
+ /* if oem translation done convert back for checksum */
+ if ((pZEntry->vem & 0xff00) == 0) {
+ /* get original */
+ INTERN_TO_OEM(pZEntry->iname, inameLocal);
+ } else {
+ strcpy(inameLocal, pZEntry->iname);
+ }
+#else
+# define inameLocal (pZEntry->iname)
+#endif
+
+ chksum = crc32(chksum, (uch *)(inameLocal), strlen(inameLocal));
+
+#ifdef WIN32_OEM
+ free(inameLocal);
+#else
+# undef inameLocal
+#endif
+
+ /*
+ * Compute the Adler-16 checksum of iname
+ */
+/*
+ chksum = adler16(ADLERVAL_INITIAL,
+ (uch *)(pZEntry->iname), strlen(pZEntry->iname));
+*/
+
+ /* set/update UTF-8 Path extra field members */
+ /* tag header */
+ write_ushort_to_mem(UTF8_PATH_EF_TAG, pUExtra);
+ /* data size */
+ write_ushort_to_mem((ush) (UCenLen - ZIP_EF_HEADER_SIZE), pUExtra + 2);
+ /* version */
+ *(pUExtra + 2 + 2) = 1;
+ /* iname checksum */
+ write_ulong_to_mem(chksum, pUExtra + 2 + 2 + 1);
+ /* UTF-8 path */
+ write_string_to_mem(pZEntry->uname, pUExtra + 2 + 2 + 1 + 4);
+
+ return ZE_OK;
+}
+#endif /* def UNICODE_SUPPORT */
+
+
+zoff_t ffile_size OF((FILE *));
+
+
+/* 2004-12-06 SMS.
+ * ffile_size() returns reliable file size or EOF.
+ * May be used to detect large files in a small-file program.
+ */
+zoff_t ffile_size( file)
+FILE *file;
+{
+ int sts;
+ size_t siz;
+ zoff_t ofs;
+ char waste[ 4];
+
+ /* Seek to actual EOF. */
+ sts = zfseeko( file, 0, SEEK_END);
+ if (sts != 0)
+ {
+ /* fseeko() failed. (Unlikely.) */
+ ofs = EOF;
+ }
+ else
+ {
+ /* Get apparent offset at EOF. */
+ ofs = zftello( file);
+ if (ofs < 0)
+ {
+ /* Offset negative (overflow). File too big. */
+ ofs = EOF;
+ }
+ else
+ {
+ /* Seek to apparent EOF offset.
+ Won't be at actual EOF if offset was truncated.
+ */
+ sts = zfseeko( file, ofs, SEEK_SET);
+ if (sts != 0)
+ {
+ /* fseeko() failed. (Unlikely.) */
+ ofs = EOF;
+ }
+ else
+ {
+ /* Read a byte at apparent EOF. Should set EOF flag. */
+ siz = fread( waste, 1, 1, file);
+ if (feof( file) == 0)
+ {
+ /* Not at EOF, but should be. File too big. */
+ ofs = EOF;
}
+ }
}
- return p;
+ }
+ /* Seek to BOF.
+ *
+ * 2007-05-23 SMS.
+ * Note that a problem in a prehistoric VAX C run-time library
+ * requires that rewind() be used instead of fseek(), or else
+ * the EOF flag is not cleared properly.
+ */
+ /* As WIN32 has this same problem (EOF not being cleared) when
+ * NO_ZIP64_SUPPORT is set but LARGE_FILE_SUPPORT is set on a
+ * small file, seems no reason not to always use rewind().
+ * 8/5/07 EG
+ */
+#if 0
+#ifdef VAXC
+ sts = rewind( file);
+#else /* def VAXC */
+ sts = zfseeko( file, 0, SEEK_SET);
+#endif /* def VAXC [else] */
+#endif
+ rewind(file);
+
+ return ofs;
}
-#endif /* VMS */
#ifndef UTIL
@@ -327,82 +1771,102 @@ struct zlist far *z;
sprintf(errbuf, "made by version %d.%d on system type %d: ",
(ush)(z->vem & 0xff) / (ush)10, (ush)(z->vem & 0xff) % (ush)10,
z->vem >> 8);
- zipwarn(errbuf, z->zname);
+ zipwarn(errbuf, z->oname);
}
if (z->ver != 10 && z->ver != 11 && z->ver != 20)
{
sprintf(errbuf, "needs unzip %d.%d on system type %d: ",
(ush)(z->ver & 0xff) / (ush)10,
(ush)(z->ver & 0xff) % (ush)10, z->ver >> 8);
- zipwarn(errbuf, z->zname);
+ zipwarn(errbuf, z->oname);
}
- if (z->flg != z->lflg)
+
+ if ((fix == 2) && (z->flg != z->lflg))
+ /* The comparision between central and local version of the
+ "general purpose bit flag" cannot be used from scanzipf_regnew(),
+ because in the "regular" zipfile processing, the local header reads
+ have been postponed until the actual entry processing takes place.
+ They have not yet been read when "zipoddities()" is called.
+ This change was neccessary to support multivolume archives.
+ */
{
sprintf(errbuf, "local flags = 0x%04x, central = 0x%04x: ",
z->lflg, z->flg);
- zipwarn(errbuf, z->zname);
+ zipwarn(errbuf, z->oname);
}
- else if (z->flg & ~0xf)
+ else if (z->flg & ~0xf && (z->flg & ~0xf0) != UTF8_BIT)
+ /* Only bit in high byte we support is the new UTF-8 bit */
{
sprintf(errbuf, "undefined bits used in flags = 0x%04x: ", z->flg);
- zipwarn(errbuf, z->zname);
+ zipwarn(errbuf, z->oname);
}
- if (z->how > DEFLATE)
- {
+ if (z->how > LAST_KNOWN_COMPMETHOD) {
sprintf(errbuf, "unknown compression method %u: ", z->how);
- zipwarn(errbuf, z->zname);
+ zipwarn(errbuf, z->oname);
}
if (z->dsk)
{
- sprintf(errbuf, "starts on disk %u: ", z->dsk);
- zipwarn(errbuf, z->zname);
+ sprintf(errbuf, "starts on disk %lu: ", z->dsk);
+ zipwarn(errbuf, z->oname);
}
if (z->att!=ASCII && z->att!=BINARY && z->att!=__EBCDIC)
{
sprintf(errbuf, "unknown internal attributes = 0x%04x: ", z->att);
- zipwarn(errbuf, z->zname);
+ zipwarn(errbuf, z->oname);
}
-#if 0
+# if 0
/* This test is ridiculous, it produces an error message for almost every */
/* platform of origin other than MS-DOS, Unix, VMS, and Acorn! Perhaps */
/* we could test "if (z->dosflag && z->atx & ~0xffL)", but what for? */
if (((n = z->vem >> 8) != 3) && n != 2 && n != 13 && z->atx & ~0xffL)
{
sprintf(errbuf, "unknown external attributes = 0x%08lx: ", z->atx);
- zipwarn(errbuf, z->zname);
+ zipwarn(errbuf, z->oname);
}
-#endif
+# endif
+
+ /* This test is just annoying, as Zip itself does not write the same
+ extra fields to both the local and central headers. It's much more
+ complicated than this test implies. 3/17/05 */
+#if 0
if (z->ext || z->cext)
{
+# if 0
if (z->ext && z->cext && z->extra != z->cextra)
{
sprintf(errbuf,
"local extra (%ld bytes) != central extra (%ld bytes): ",
(ulg)z->ext, (ulg)z->cext);
- if (noisy) fprintf(stderr, "\tzip info: %s%s\n", errbuf, z->zname);
+ if (noisy) fprintf(mesg, "\tzip info: %s%s\n", errbuf, z->oname);
}
-#if (!defined(RISCOS) && !defined(CMS_MVS))
+# if (!defined(RISCOS) && !defined(CMS_MVS))
/* in noisy mode, extra field sizes are always reported */
else if (noisy)
-#else /* RISCOS || CMS_MVS */
+# else /* RISCOS || CMS_MVS */
/* avoid warnings for zipfiles created on the same type of OS system! */
/* or, was this warning really intended (eg. OS/2)? */
/* Only give info if extra bytes were added by another system */
else if (noisy && ((z->vem >> 8) != (OS_CODE >> 8)))
-#endif /* ?(RISCOS || CMS_MVS) */
+# endif /* ?(RISCOS || CMS_MVS) */
+# endif /* 0 */
{
- fprintf(stderr, "zip info: %s has %ld bytes of %sextra data\n",
- z->zname, z->ext ? (ulg)z->ext : (ulg)z->cext,
+ fprintf(mesg, "zip info: %s has %ld bytes of %sextra data\n",
+ z->oname, z->ext ? (ulg)z->ext : (ulg)z->cext,
z->ext ? (z->cext ? "" : "local ") : "central ");
}
}
+#endif
}
+
+#if 0 /* scanzipf_fix() no longer used */
/*
* scanzipf_fix is called with zip -F or zip -FF
* read the file from front to back and pick up the pieces
* NOTE: there are still checks missing to see if the header
* that was found is *VALID*
+ *
+ * Still much work to do so can handle more cases. 1/18/04 EG
*/
local int scanzipf_fix(f)
FILE *f; /* zip file */
@@ -417,28 +1881,40 @@ local int scanzipf_fix(f)
ush flg; /* general purpose bit flag */
int m; /* mismatch flag */
extent n; /* length of name */
- ulg p; /* current file offset */
- ulg s; /* size of data, start of central */
+ uzoff_t p; /* current file offset */
+ uzoff_t s; /* size of data, start of central */
struct zlist far * far *x; /* pointer last entry's link */
struct zlist far *z; /* current zip entry structure */
+#ifndef ZIP64_SUPPORT
+
+/* 2004-12-06 SMS.
+ * Check for too-big file before doing any serious work.
+ */
+ if (ffile_size( f) == EOF)
+ return ZE_ZIP64;
+
+#endif /* ndef ZIP64_SUPPORT */
+
+
/* Get any file attribute valid for this OS, to set in the central
* directory when fixing the archive:
*/
-#ifndef UTIL
- filetime(zipfile, &a, (long*)&s, NULL);
-#endif
+# ifndef UTIL
+ filetime(zipfile, &a, (zoff_t*)&s, NULL);
+# endif
x = &zfiles; /* first link */
p = 0; /* starting file offset */
-#ifdef HANDLE_AMIGA_SFX
+# ifdef HANDLE_AMIGA_SFX
amiga_sfx_offset = 0L;
-#endif
+# endif
/* Find start of zip structures */
for (;;) {
+ /* look for signature */
while ((m = getc(f)) != EOF && m != 0x50) /* 0x50 == 'P' */
{
-#ifdef HANDLE_AMIGA_SFX
+# ifdef HANDLE_AMIGA_SFX
if (p == 0 && m == 0)
amiga_sfx_offset = 1L;
else if (amiga_sfx_offset) {
@@ -446,25 +1922,33 @@ local int scanzipf_fix(f)
|| (p == 3 && (uch) m != 0xF3))
amiga_sfx_offset = 0L;
}
-#endif /* HANDLE_AMIGA_SFX */
+# endif /* HANDLE_AMIGA_SFX */
p++;
}
+ /* found a P */
b[0] = (char) m;
+ /* local - 11/2/03 EG */
+ if (fread(b+1, 3, 1, f) != 1 || (s = LG(b)) == LOCSIG)
+ break;
+ /* why search for ENDSIG if doing only local - 11/2/03 EG
if (fread(b+1, 3, 1, f) != 1 || (s = LG(b)) == LOCSIG || s == ENDSIG)
break;
- if (fseek(f, -3L, SEEK_CUR))
+ */
+ /* back up */
+ if (zfseeko(f, -3L, SEEK_CUR))
return ferror(f) ? ZE_READ : ZE_EOF;
+ /* move 1 byte forward */
p++;
}
zipbeg = p;
-#ifdef HANDLE_AMIGA_SFX
+# ifdef HANDLE_AMIGA_SFX
if (amiga_sfx_offset && zipbeg >= 12 && (zipbeg & 3) == 0
&& fseek(f, -12L, SEEK_CUR) == 0 && fread(b, 12, 1, f) == 1
&& LG(b + 4) == 0xF1030000 /* 1009 in Motorola byte order */)
amiga_sfx_offset = zipbeg - 4;
else
amiga_sfx_offset = 0L;
-#endif /* HANDLE_AMIGA_SFX */
+# endif /* HANDLE_AMIGA_SFX */
/* Read local headers */
while (LG(b) == LOCSIG)
@@ -496,10 +1980,16 @@ local int scanzipf_fix(f)
z->mark = 0;
z->trash = 0;
+ /* attention: this one breaks the VC optimizer (Release Build) */
+ /* may be fixed - 11/1/03 EG */
s = fix > 1 ? 0L : z->siz; /* discard compressed size with -FF */
/* Initialize all fields pointing to malloced data to NULL */
z->zname = z->name = z->iname = z->extra = z->cextra = z->comment = NULL;
+ z->oname = NULL;
+#ifdef UNICODE_SUPPORT
+ z->uname = z->zuname = z->ouname = NULL;
+#endif
/* Link into list */
*x = z;
@@ -511,16 +2001,28 @@ local int scanzipf_fix(f)
{
sprintf(errbuf, "%lu", (ulg)zcount + 1);
zipwarn("zero-length name for entry #", errbuf);
-#ifndef DEBUG
+# ifndef DEBUG
return ZE_FORM;
-#endif
+# endif
}
if ((z->iname = malloc(n+1)) == NULL ||
(z->ext && (z->extra = malloc(z->ext)) == NULL))
return ZE_MEM;
if (fread(z->iname, n, 1, f) != 1 ||
- (z->ext && fread(z->extra, z->ext, 1, f) != 1) ||
- (s && fseek(f, (long)s, SEEK_CUR)))
+ (z->ext && fread(z->extra, z->ext, 1, f) != 1))
+ return ferror(f) ? ZE_READ : ZE_EOF;
+
+# ifdef ZIP64_SUPPORT
+ /* adjust/update siz,len and off (to come: dsk) entries */
+ /* PKZIP does not care of the version set in a CDH: if */
+ /* there is a zip64 extra field assigned to a CDH PKZIP */
+ /* uses it, we should do so, too. */
+ zip64_entry = adjust_zip_local_entry(z);
+ /* z->siz may be updated */
+ s = fix > 1 ? 0L : z->siz; /* discard compressed size with -FF */
+# endif
+
+ if (s && zfseeko(f, (zoff_t)s, SEEK_CUR))
return ferror(f) ? ZE_READ : ZE_EOF;
/* If there is an extended local header, s is either 0 or
* the correct compressed size.
@@ -549,20 +2051,29 @@ local int scanzipf_fix(f)
b[0] = (char) m;
if (fread(b+1, 15, 1, f) != 1 || LG(b) == EXTLOCSIG)
break;
- if (fseek(f, -15L, SEEK_CUR))
+ if (zfseeko(f, -15L, SEEK_CUR))
return ferror(f) ? ZE_READ : ZE_EOF;
}
+# ifdef ZIP64_SUPPORT
+ if (zip64_entry) { /* from extra field */
+ /* all are 8 bytes */
+ s = LG(4 + ZIP64_EXTSIZ + b);
+ } else {
+ s = LG(4 + EXTSIZ + b);
+ }
+# else
s = LG(4 + EXTSIZ + b);
+# endif
p += s;
- if ((ulg) ftell(f) != p+16L) {
+ if ((uzoff_t) zftello(f) != p+16L) {
zipwarn("bad extended local header for ", z->zname);
return ZE_FORM;
}
} else {
/* compressed size non-zero, assume that it is valid: */
- Assert(p == ftell(f), "bad compressed size with extended header");
+ Assert(p == zftello(f), "bad compressed size with extended header");
- if (fseek(f, p, SEEK_SET) || fread(b, 16, 1, f) != 1)
+ if (zfseeko(f, p, SEEK_SET) || fread(b, 16, 1, f) != 1)
return ferror(f) ? ZE_READ : ZE_EOF;
if (LG(b) != EXTLOCSIG) {
zipwarn("extended local header not found for ", z->zname);
@@ -572,9 +2083,15 @@ local int scanzipf_fix(f)
/* overwrite the unknown values of the local header: */
/* already in host format */
+# ifdef ZIP64_SUPPORT
+ z->crc = LG(4 + ZIP64_EXTCRC + b);
+ z->siz = s;
+ z->len = LG(4 + ZIP64_EXTLEN + b);
+# else
z->crc = LG(4 + EXTCRC + b);
z->siz = s;
z->len = LG(4 + EXTLEN + b);
+# endif
p += 16L;
}
@@ -585,14 +2102,15 @@ local int scanzipf_fix(f)
b[0] = (char) m;
if (fread(b+1, 3, 1, f) != 1 || (s = LG(b)) == LOCSIG || s == CENSIG)
break;
- if (fseek(f, -3L, SEEK_CUR))
+ if (zfseeko(f, -3L, SEEK_CUR))
return ferror(f) ? ZE_READ : ZE_EOF;
p++;
}
s = p - (z->off + 4 + LOCHEAD + n + z->ext);
if (s != z->siz) {
- fprintf(mesg, " compressed size %ld, actual size %ld for %s\n",
- z->siz, s, z->zname);
+ fprintf(mesg, " compressed size %s, actual size %s for %s\n",
+ zip_fzofft(z->siz, NULL, "u"), zip_fzofft(s, NULL, "u"),
+ z->zname);
z->siz = s;
}
/* next LOCSIG already read at this point, don't read it again: */
@@ -620,15 +2138,181 @@ local int scanzipf_fix(f)
cenbeg = s;
if (zipbeg && noisy)
- fprintf(mesg, "%s: adjusting offsets for a preamble of %lu bytes\n",
- zipfile, zipbeg);
-
+ fprintf(mesg, "%s: adjusting offsets for a preamble of %s bytes\n",
+ zipfile, zip_fzofft(zipbeg, NULL, "u"));
return ZE_OK;
-}
+} /* end of function scanzipf_fix() */
+#endif /* never, scanzipf_fix() no longer used */
#endif /* !UTIL */
/*
+ * read_local
+ *
+ * Read the local header assumed at in_file file pointer.
+ * localz is the returned local header, z is the central directory entry.
+ *
+ * This is used by crypt.c.
+ *
+ * Return ZE code
+ */
+int readlocal(localz, z)
+ struct zlist far **localz;
+ struct zlist far *z;
+{
+ char buf[LOCHEAD + 1];
+ struct zlist far *locz;
+
+#ifndef UTIL
+ ulg start_disk = 0;
+ uzoff_t start_offset = 0;
+ char *split_path;
+
+ start_disk = z->dsk;
+ start_offset = z->off;
+
+ /* don't assume reading the right disk */
+
+ if (start_disk != current_in_disk) {
+ if (in_file) {
+ fclose(in_file);
+ in_file = NULL;
+ }
+ }
+
+ current_in_disk = start_disk;
+
+ /* disks are archive.z01, archive.z02, ..., archive.zip */
+ split_path = get_in_split_path(in_path, current_in_disk);
+
+ if (in_file == NULL) {
+ while ((in_file = zfopen(split_path, FOPR)) == NULL) {
+ /* could not open split */
+
+ /* Ask for directory with split. Updates in_path */
+ if (ask_for_split_read_path(start_disk) != ZE_OK) {
+ return ZE_ABORT;
+ }
+ free(split_path);
+ split_path = get_in_split_path(in_path, start_disk);
+ }
+ }
+#endif
+
+ /* For utilities assume archive is on one disk for now */
+
+ if (zfseeko(in_file, z->off, SEEK_SET) != 0) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("reading archive fseek: ", strerror(errno));
+ return ZE_READ;
+ }
+ if (!at_signature(in_file, "PK\03\04")) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("Did not find entry for ", z->iname);
+ return ZE_FORM;
+ }
+
+ /* read local header */
+ if (fread(buf, LOCHEAD, 1, in_file) != 1) {
+ int f = ferror(in_file);
+ zipwarn("reading local entry: ", strerror(errno));
+ fclose(in_file);
+ return f ? ZE_READ : ZE_EOF;
+ }
+
+ /* Local Header
+ local file header signature 4 bytes (0x04034b50)
+ version needed to extract 2 bytes
+ general purpose bit flag 2 bytes
+ compression method 2 bytes
+ last mod file time 2 bytes
+ last mod file date 2 bytes
+ crc-32 4 bytes
+ compressed size 4 bytes
+ uncompressed size 4 bytes
+ file name length 2 bytes
+ extra field length 2 bytes
+
+ file name (variable size)
+ extra field (variable size)
+ */
+
+ if ((locz = (struct zlist far *)farmalloc(sizeof(struct zlist))) == NULL) {
+ zipwarn("reading entry", "");
+ fclose(in_file);
+ return ZE_MEM;
+ }
+
+ locz->ver = SH(LOCVER + buf);
+ locz->lflg = SH(LOCFLG + buf);
+ locz->how = SH(LOCHOW + buf);
+ locz->tim = LG(LOCTIM + buf); /* time and date into one long */
+ locz->crc = LG(LOCCRC + buf);
+ locz->nam = SH(LOCNAM + buf);
+ locz->ext = SH(LOCEXT + buf);
+
+ /* Initialize all fields pointing to malloced data to NULL */
+ locz->zname = locz->name = locz->iname = locz->extra = NULL;
+ locz->oname = NULL;
+#ifdef UNICODE_SUPPORT
+ locz->uname = NULL;
+ locz->zuname = NULL;
+ locz->ouname = NULL;
+#endif
+
+ /* Read file name, extra field and comment field */
+ if ((locz->iname = malloc(locz->nam+1)) == NULL ||
+ (locz->ext && (locz->extra = malloc(locz->ext)) == NULL))
+ return ZE_MEM;
+ if (fread(locz->iname, locz->nam, 1, in_file) != 1 ||
+ (locz->ext && fread(locz->extra, locz->ext, 1, in_file) != 1))
+ return ferror(in_file) ? ZE_READ : ZE_EOF;
+ locz->iname[z->nam] = '\0'; /* terminate name */
+#ifdef UNICODE_SUPPORT
+ if (unicode_mismatch != 3)
+ read_Unicode_Path_local_entry(locz);
+#endif
+#ifdef WIN32
+ {
+ /* translate archive name from OEM if came from OEM-charset environment */
+ unsigned hostver = (z->vem & 0xff);
+ Ext_ASCII_TO_Native(locz->iname, (z->vem >> 8), hostver,
+ ((z->atx & 0xffff0000L) != 0), TRUE);
+ }
+#endif
+ if ((locz->name = malloc(locz->nam+1)) == NULL)
+ return ZE_MEM;
+ strcpy(locz->name, locz->iname);
+
+#ifdef ZIP64_SUPPORT
+ zip64_entry = adjust_zip_local_entry(locz);
+#endif
+
+ /* Compare localz to z */
+ if (locz->ver != z->ver) {
+ sprintf(errbuf, "Local Version Needed (%d) does not match CD (%d): ", locz->ver, z->ver);
+ zipwarn(errbuf, z->iname);
+ }
+ if (locz->lflg != z->flg) {
+ zipwarn("Local Entry Flag does not match CD: ", z->iname);
+ }
+ if (locz->crc != z->crc) {
+ zipwarn("Local Entry CRC does not match CD: ", z->iname);
+ }
+
+ /* as copying get uncompressed and compressed sizes from central directory */
+ locz->len = z->len;
+ locz->siz = z->siz;
+
+ *localz = locz;
+
+ return ZE_OK;
+} /* end function readlocal() */
+
+#if 0 /* following functions are not (no longer) used. */
+/*
* scanzipf_reg starts searching for the End Signature at the end of the file
* The End Signature points to the Central Directory Signature which points
* to the Local Directory Signature
@@ -643,8 +2327,6 @@ local int scanzipf_reg(f)
*/
{
char b[CENHEAD]; /* buffer for central headers */
- ush flg; /* general purpose bit flag */
- int m; /* mismatch flag */
extent n; /* length of name */
struct zlist far * far *x; /* pointer last entry's link */
struct zlist far *z; /* current zip entry structure */
@@ -652,7 +2334,29 @@ local int scanzipf_reg(f)
char far *u; /* temporary variable */
int found;
char *buf; /* temp buffer for reading zipfile */
- long deltaoff;
+# ifdef ZIP64_SUPPORT
+ ulg u4; /* unsigned 4 byte variable */
+ char bf[8];
+ uzoff_t u8; /* unsigned 8 byte variable */
+ uzoff_t censiz; /* size of central directory */
+ uzoff_t z64eocd; /* Zip64 End Of Central Directory record byte offset */
+# else
+ ush flg; /* general purpose bit flag */
+ int m; /* mismatch flag */
+# endif
+ zoff_t deltaoff = 0;
+
+
+#ifndef ZIP64_SUPPORT
+
+ /* 2004-12-06 SMS.
+ * Check for too-big file before doing any serious work.
+ */
+ if (ffile_size( f) == EOF)
+ return ZE_ZIP64;
+
+#endif /* ndef ZIP64_SUPPORT */
+
buf = malloc(4096 + 4);
if (buf == NULL)
@@ -662,13 +2366,19 @@ local int scanzipf_reg(f)
amiga_sfx_offset = (fread(buf, 1, 4, f) == 4 && LG(buf) == 0xF3030000);
/* == 1 if this file is an Amiga executable (presumably UnZipSFX) */
#endif
+ /* detect spanning signature */
+ zfseeko(f, 0, SEEK_SET);
+ read_split_archive = (fread(buf, 1, 4, f) == 4 && LG(buf) == 0x08074b50L);
found = 0;
t = &buf[4096];
t[1] = '\0';
t[2] = '\0';
t[3] = '\0';
- if (fseek(f, -4096L, SEEK_END) == 0) {
- zipbeg = (ulg) (ftell(f) + 4096L);
+ /* back up as much as 4k from end */
+ /* zip64 support 08/31/2003 R.Nausedat */
+ if (zfseeko(f, -4096L, SEEK_END) == 0) {
+ zipbeg = (uzoff_t) (zftello(f) + 4096L);
+ /* back up 4k blocks and look for End Of CD signature */
while (!found && zipbeg >= 4096) {
zipbeg -= 4096L;
buf[4096] = t[1];
@@ -678,22 +2388,21 @@ local int scanzipf_reg(f)
* XXX error check ??
*/
fread(buf, 1, 4096, f);
- fseek(f, -8192L, SEEK_CUR);
+ zfseeko(f, -8192L, SEEK_CUR);
t = &buf[4095];
/*
* XXX far pointer arithmetic in DOS
*/
while (t >= buf) {
- /* Check for ENDSIG the End Of Central Directory Record signature
- ("PK\5\6" in ASCII) */
+ /* Check for ENDSIG ("PK\5\6" in ASCII) */
if (LG(t) == ENDSIG) {
found = 1;
/*
* XXX error check ??
* XXX far pointer arithmetic in DOS
*/
- zipbeg += (ulg) (t - buf);
- fseek(f, (long) zipbeg + 4L, SEEK_SET);
+ zipbeg += (uzoff_t) (t - buf);
+ zfseeko(f, (zoff_t) zipbeg + 4L, SEEK_SET);
break;
}
--t;
@@ -701,16 +2410,18 @@ local int scanzipf_reg(f)
}
}
else
- zipbeg = 4096L;
+ /* file less than 4k bytes */
+ zipbeg = 4096L;
/*
* XXX warn: garbage at the end of the file ignored
*/
if (!found && zipbeg > 0) {
size_t s;
- fseek(f, 0L, SEEK_SET);
+ zfseeko(f, 0L, SEEK_SET);
clearerr(f);
s = fread(buf, 1, (size_t) zipbeg, f);
+ /* add 0 bytes at end */
buf[s] = t[1];
buf[s + 1] = t[2];
buf[s + 2] = t[3];
@@ -726,7 +2437,7 @@ local int scanzipf_reg(f)
* XXX far pointer arithmetic in DOS
*/
zipbeg = (ulg) (t - buf);
- fseek(f, (long) zipbeg + 4L, SEEK_SET);
+ zfseeko(f, (zoff_t) zipbeg + 4L, SEEK_SET);
break;
}
--t;
@@ -740,8 +2451,43 @@ local int scanzipf_reg(f)
}
/*
- * Read the End Of Central Directory Record
+ * Check for a Zip64 EOCD Locator signature - 12/10/04 EG
*/
+#ifndef ZIP64_SUPPORT
+ /* If Zip64 not enabled check if archive being read is Zip64 */
+ /* back up 24 bytes (size of Z64 EOCDL and ENDSIG) */
+ if (zfseeko(f, -24, SEEK_CUR) != 0) {
+ perror("fseek");
+ return ZE_FORM; /* XXX */
+ }
+ /* read Z64 EOCDL if there */
+ if (fread(b, 20, 1, f) != 1) {
+ return ZE_READ;
+ }
+ /* first 4 bytes are the signature if there */
+ if (LG(b) == ZIP64_EOCDL_SIG) {
+ zipwarn("found Zip64 signature - this may be a Zip64 archive", "");
+ zipwarn("PKZIP 4.5 or later needed - set ZIP64_SUPPORT in Zip 3", "");
+ return ZE_ZIP64;
+ }
+
+ /* now should be back at the EOCD signature */
+ if (fread(b, 4, 1, f) != 1) {
+ zipwarn("unable to read after relative seek", "");
+ return ZE_READ;
+ }
+ if (LG(b) != ENDSIG) {
+ zipwarn("unable to relative seek in archive", "");
+ return ZE_FORM;
+ }
+#if 0
+ if (fseek(f, -4, SEEK_CUR) != 0) {
+ perror("fseek");
+ return ZE_FORM; /* XXX */
+ }
+#endif
+#endif
+
/* Read end header */
if (fread(b, ENDHEAD, 1, f) != 1)
return ferror(f) ? ZE_READ : ZE_EOF;
@@ -764,12 +2510,93 @@ local int scanzipf_reg(f)
memtoebc(zcomment, zcomment, zcomlen);
#endif /* EBCDIC */
}
+#ifdef ZIP64_SUPPORT
+ /* account for Zip64 EOCD Record and Zip64 EOCD Locator */
+
+ /* Z64 EOCDL should be just before EOCD (unless this is an empty archive) */
+ cenbeg = zipbeg - ZIP64_EOCDL_OFS_SIZE;
+ /* check for empty archive */
+ /* changed cenbeg to uzoff_t so instead of cenbeg >= 0 use new check - 5/23/05 EG */
+ if (zipbeg >= ZIP64_EOCDL_OFS_SIZE) {
+ /* look for signature */
+ if (zfseeko(f, cenbeg, SEEK_SET)) {
+ zipwarn("end of file seeking Z64EOCDL", "");
+ return ZE_FORM;
+ }
+ if (fread(bf, 4, 1, f) != 1) {
+ ziperr(ZE_FORM, "read error");
+ }
+ u4 = LG(bf);
+ if (u4 == ZIP64_EOCDL_SIG) {
+ /* found Zip64 EOCD Locator */
+ /* check for disk information */
+ zfseeko(f, cenbeg + ZIP64_EOCDL_OFS_TOTALDISKS, SEEK_SET);
+ if (fread(bf, 4, 1, f) != 1) {
+ ziperr(ZE_FORM, "read error");
+ }
+ u4 = LG(bf);
+ if (u4 != 1) {
+ ziperr(ZE_FORM, "multiple disk archives not yet supported");
+ }
+
+ /* look for Zip64 EOCD Record */
+ zfseeko(f, cenbeg + ZIP64_EOCDL_OFS_EOCD_START, SEEK_SET);
+ if (fread(bf, 8, 1, f) != 1) {
+ ziperr(ZE_FORM, "read error");
+ }
+ z64eocd = LLG(bf);
+ if (zfseeko(f, z64eocd, SEEK_SET)) {
+ ziperr(ZE_FORM, "error searching for Z64 EOCD Record");
+ }
+ if (fread(bf, 4, 1, f) != 1) {
+ ziperr(ZE_FORM, "read error");
+ }
+ u4 = LG(bf);
+ if (u4 != ZIP64_EOCD_SIG) {
+ ziperr(ZE_FORM, "Z64 EOCD not found but Z64 EOCD Locator exists");
+ }
+ /* get size of CD */
+ zfseeko(f, z64eocd + ZIP64_EOCD_OFS_SIZE, SEEK_SET);
+ if (fread(bf, 8, 1, f) != 1) {
+ ziperr(ZE_FORM, "read error");
+ }
+ censiz = LLG(bf);
+ /* get start of CD */
+ zfseeko(f, z64eocd + ZIP64_EOCD_OFS_CD_START, SEEK_SET);
+ if (fread(bf, 8, 1, f) == (size_t) -1) {
+ ziperr(ZE_FORM, "read error");
+ }
+ cenbeg = LLG(bf);
+ u8 = z64eocd - cenbeg;
+ deltaoff = adjust ? u8 - censiz : 0L;
+ } else {
+ /* assume no Locator and no Zip64 EOCD Record */
+ censiz = LG(ENDSIZ + b);
+ cenbeg = LG(b + ENDOFF);
+ u8 = zipbeg - censiz;
+ deltaoff = adjust ? u8 - censiz : 0L;
+ }
+ }
+#else /* !ZIP64_SUPPORT */
/*
* XXX assumes central header immediately precedes end header
*/
+ /* start of central directory */
cenbeg = zipbeg - LG(ENDSIZ + b);
+/*
+printf("start of central directory cenbeg %ld\n", cenbeg);
+*/
+
+ /* offset to first entry of archive */
deltaoff = adjust ? cenbeg - LG(b + ENDOFF) : 0L;
- if (fseek(f, cenbeg, SEEK_SET) != 0) {
+#endif /* ?ZIP64_SUPPORT */
+
+ if (zipbeg < ZIP64_EOCDL_OFS_SIZE) {
+ /* zip file seems empty */
+ return ZE_OK;
+ }
+
+ if (zfseeko(f, cenbeg, SEEK_SET) != 0) {
perror("fseek");
return ZE_FORM; /* XXX */
}
@@ -802,6 +2629,12 @@ local int scanzipf_reg(f)
/* Initialize all fields pointing to malloced data to NULL */
z->zname = z->name = z->iname = z->extra = z->cextra = z->comment = NULL;
+ z->oname = NULL;
+#ifdef UNICODE_SUPPORT
+ z->uname = NULL; /* UTF-8 path */
+ z->zuname = NULL; /* Escaped local version of uname */
+ z->ouname = NULL; /* Display version of zuname */
+#endif
/* Link into list */
*x = z;
@@ -827,10 +2660,33 @@ local int scanzipf_reg(f)
(z->com && fread(z->comment, z->com, 1, f) != 1))
return ferror(f) ? ZE_READ : ZE_EOF;
z->iname[z->nam] = '\0'; /* terminate name */
+
#ifdef EBCDIC
if (z->com)
memtoebc(z->comment, z->comment, z->com);
#endif /* EBCDIC */
+
+#ifdef ZIP64_SUPPORT
+ /* zip64 support 08/31/2003 R.Nausedat */
+ /* here, we have to read the len, siz etc values from the CD */
+ /* entry as we might have to adjust them regarding their */
+ /* correspronding zip64 extra fields. */
+ /* also, we cannot compare the values from the CD entries with */
+ /* the values from the LH as they might be different. */
+ z->len = LG(CENLEN + b);
+ z->siz = LG(CENSIZ + b);
+ z->crc = LG(CENCRC + b);
+ z->tim = LG(CENTIM + b); /* time and date into one long */
+ z->how = SH(CENHOW + b);
+ z->flg = SH(CENFLG + b);
+ z->ver = SH(CENVER + b);
+ /* adjust/update siz,len and off (to come: dsk) entries */
+ /* PKZIP does not care of the version set in a CDH: if */
+ /* there is a zip64 extra field assigned to a CDH PKZIP */
+ /* uses it, we should do so, too. */
+ adjust_zip_central_entry(z);
+#endif /* ZIP64_SUPPORT */
+
/* Update zipbeg offset, prepare for next header */
if (z->off < zipbeg)
zipbeg = z->off;
@@ -844,11 +2700,12 @@ local int scanzipf_reg(f)
z = zfiles;
while (z != NULL) {
/* Read next signature */
- if (fseek(f, z->off, SEEK_SET) != 0 || fread(b, 4, 1, f) != 1)
+ if (zfseeko(f, z->off, SEEK_SET) != 0 || fread(b, 4, 1, f) != 1)
return ferror(f) ? ZE_READ : ZE_EOF;
if (LG(b) == LOCSIG) {
if (fread(b, LOCHEAD, 1, f) != 1)
return ferror(f) ? ZE_READ : ZE_EOF;
+
z->lflg = SH(LOCFLG + b);
n = SH(LOCNAM + b);
z->ext = SH(LOCEXT + b);
@@ -895,7 +2752,16 @@ local int scanzipf_reg(f)
}
}
+#ifdef ZIP64_SUPPORT /* zip64 support 09/02/2003 R.Nausedat */
+ /*
+ for now the below is left out if ZIP64_SUPPORT is defined as the fields
+ len, siz and off in struct zlist are type of int64 if ZIP64_SUPPORT
+ is defined. In either way, the values read from the central directory
+ should be valid. comments are welcome
+ */
+#else /* !ZIP64_SUPPORT */
/* Check extended local header if there is one */
+ /* bit 3 */
if ((z->lflg & 8) != 0)
{
char buf2[16];
@@ -904,14 +2770,14 @@ local int scanzipf_reg(f)
s = LG(LOCSIZ + b);
if (s == 0)
s = LG((CENSIZ-CENVER) + (char far *)(&(z->ver)));
- if (fseek(f, (z->off + (4+LOCHEAD) + z->nam + z->ext + s), SEEK_SET)
+ if (zfseeko(f, (z->off + (4+LOCHEAD) + z->nam + z->ext + s), SEEK_SET)
|| (fread(buf2, 16, 1, f) != 1))
return ferror(f) ? ZE_READ : ZE_EOF;
if (LG(buf2) != EXTLOCSIG)
{
-#ifdef EBCDIC
+# ifdef EBCDIC
strtoebc(z->iname, z->iname);
-#endif
+# endif
zipwarn("extended local header not found for ", z->iname);
return ZE_FORM;
}
@@ -923,16 +2789,18 @@ local int scanzipf_reg(f)
/* Compare local header with that part of central header (except
for the reserved bits in the general purpose flags and except
for the already checked entry name length */
+ /* If I have read this right we are stepping through the z struct
+ here as a byte array. Need to fix this. 5/25/2005 EG */
u = (char far *)(&(z->ver));
flg = SH((CENFLG-CENVER) + u); /* Save central flags word */
u[CENFLG-CENVER+1] &= 0x1f; /* Mask reserved flag bits */
b[LOCFLG+1] &= 0x1f;
- for (m = 0, n = 0; n < LOCNAM; n++)
+ for (m = 0, n = 0; n < LOCNAM; n++) {
if (b[n] != u[n])
{
if (!m)
{
- zipwarn("local and central headers differ for ", z->zname);
+ zipwarn("local and central headers differ for ", z->iname);
m = 1;
}
if (noisy)
@@ -942,6 +2810,7 @@ local int scanzipf_reg(f)
zipwarn(errbuf, "");
}
}
+ }
if (m && !adjust)
return ZE_FORM;
@@ -957,27 +2826,63 @@ local int scanzipf_reg(f)
z->how = SH((CENHOW-CENVER) + u);
z->flg = flg; /* may be different from z->lflg */
z->ver = SH((CENVER-CENVER) + u);
+#endif /* ?ZIP64_SUPPORT */
/* Clear actions */
z->mark = 0;
z->trash = 0;
-#ifdef UTIL
+#ifdef UNICODE_SUPPORT
+ if (unicode_mismatch != 3) {
+ read_Unicode_Path_entry(z);
+ if (z->uname) {
+ /* match based on converted Unicode name */
+ z->name = utf8_to_local_string(z->uname);
+# ifdef EBCDIC
+ /* z->zname is used for printing and must be coded in native charset */
+ strtoebc(z->zname, z->name);
+# else
+ if ((z->zname = malloc(strlen(z->name) + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "scanzipf_reg");
+ }
+ strcpy(z->zname, z->name);
+# endif
+ z->oname = local_to_display_string(z->zname);
+ } else {
+ /* no UTF-8 path */
+ if ((z->name = malloc(strlen(z->iname) + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "scanzipf_reg");
+ }
+ strcpy(z->name, z->iname);
+ if ((z->zname = malloc(strlen(z->iname) + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "scanzipf_reg");
+ }
+ strcpy(z->zname, z->iname);
+ z->oname = local_to_display_string(z->iname);
+ }
+ }
+#else /* !UNICODE_SUPPORT */
+# ifdef UTIL
/* We only need z->iname in the utils */
z->name = z->iname;
-#ifdef EBCDIC
+# ifdef EBCDIC
/* z->zname is used for printing and must be coded in native charset */
if ((z->zname = malloc(z->nam+1)) == NULL)
return ZE_MEM;
strtoebc(z->zname, z->iname);
-#else
+# else
z->zname = z->iname;
-#endif
-#else /* !UTIL */
+# endif
+# else /* !UTIL */
z->zname = in2ex(z->iname); /* convert to external name */
if (z->zname == NULL)
return ZE_MEM;
z->name = z->zname;
-#endif /* ?UTIL */
+# endif /* ?UTIL */
+ if ((z->oname = malloc(strlen(z->zname) + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "scanzipf_reg");
+ }
+ strcpy(z->oname, z->zname);
+#endif /* ?UNICODE_SUPPORT */
}
else {
#ifdef EBCDIC
@@ -987,16 +2892,16 @@ local int scanzipf_reg(f)
return ZE_FORM;
}
#ifndef UTIL
- if (verbose)
+ if (verbose && fix == 0)
zipoddities(z);
#endif
z = z->nxt;
}
if (zipbeg && noisy)
- fprintf(mesg, "%s: %s a preamble of %lu bytes\n",
- zipfile, adjust ? "adjusting offsets for" : "found", zipbeg);
-
+ fprintf(mesg, "%s: %s a preamble of %s bytes\n",
+ zipfile, adjust ? "adjusting offsets for" : "found",
+ zip_fzofft(zipbeg, NULL, "u"));
#ifdef HANDLE_AMIGA_SFX
if (zipbeg < 12 || (zipbeg & 3) != 0 /* must be longword aligned */)
amiga_sfx_offset = 0;
@@ -1012,9 +2917,2186 @@ local int scanzipf_reg(f)
}
#endif /* HANDLE_AMIGA_SFX */
return ZE_OK;
+} /* end of function scanzipf_reg() */
+#endif /* never */
+
+
+
+
+/* find_next_signature
+ *
+ * Scan the file forward and look for the next PK signature.
+ *
+ * Return 1 if find one and leave file pointer pointing to next char
+ * after signature and set sigbuf to signature.
+ *
+ * Return 0 if not. Will be at EOF on return unless error.
+ *
+ */
+
+local char sigbuf[4]; /* signature found */
+
+#if 0 /* currently unused */
+/* copy signature */
+char *copy_sig(copyto, copyfrom)
+ char *copyto;
+ char *copyfrom;
+{
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ copyto[i] = copyfrom[i];
+ }
+ return copyto;
+}
+#endif /* currently unused */
+
+
+local int find_next_signature(f)
+ FILE *f;
+{
+ int m;
+ /*
+ zoff_t here;
+ */
+
+ /* look for P K ? ? signature */
+
+ m = getc(f);
+
+ /*
+ here = zftello(f);
+ */
+
+ while (m != EOF)
+ {
+ if (m == 0x50 /*'P' except EBCDIC*/) {
+ /* found a P */
+ sigbuf[0] = (char) m;
+
+ if ((m = getc(f)) == EOF)
+ break;
+ if (m != 0x4b /*'K' except EBCDIC*/) {
+ /* not a signature */
+ ungetc(m, f);
+ } else {
+ /* found P K */
+ sigbuf[1] = (char) m;
+
+ if ((m = getc(f)) == EOF)
+ break;
+ if (m == 0x50 /*'P' except EBCDIC*/) {
+ /* not a signature but maybe start of new one */
+ ungetc(m, f);
+ continue;
+ } else if (m >= 16) {
+ /* last 2 chars expect < 16 for signature */
+ continue;
+ }
+ sigbuf[2] = (char) m;
+
+ if ((m = getc(f)) == EOF)
+ break;
+ if (m == 0x50 /*'P' except EBCDIC*/) {
+ /* not a signature but maybe start of new one */
+ ungetc(m, f);
+ continue;
+ } else if (m >= 16) {
+ /* last 2 chars expect < 16 */
+ continue;
+ }
+ sigbuf[3] = (char) m;
+
+ /* found possible signature */
+ return 1;
+ }
+ }
+ m = getc(f);
+ }
+ if (ferror(f)) {
+ return 0;
+ }
+
+ /* found nothing */
+ return 0;
+}
+
+/* find_signature
+ *
+ * Find signature.
+ *
+ * Return 1 if found and leave file pointing to next character
+ * after signature. Set sigbuf with signature.
+ *
+ * Return 0 if not found.
+ */
+
+local int find_signature(f, signature)
+ FILE *f;
+ ZCONST char *signature;
+{
+ int i;
+ char sig[4];
+ /*
+ zoff_t here = zftello(f);
+ */
+
+ for (i = 0; i < 4; i++)
+ sig[i] = signature[i];
+
+ /* for EBCDIC */
+ if (sig[0] == 'P')
+ sig[0] = 0x50;
+ if (sig[1] == 'K')
+ sig[1] = 0x4b;
+
+ while (!feof(f)) {
+ if (!find_next_signature(f)) {
+ return 0;
+ } else {
+ for (i = 0; i < 4; i++) {
+ if (sig[i] != sigbuf[i]) {
+ /* not a match */
+ break;
+ }
+ }
+ if (i == 4) {
+ /* found it */
+ return 1;
+ }
+ }
+ }
+ return 0;
}
+/* is_signature
+ *
+ * Compare signatures
+ *
+ * Return 1 if the signatures match.
+ */
+
+local int is_signature(sig1, sig2)
+ ZCONST char *sig1;
+ ZCONST char *sig2;
+{
+ int i;
+ char tsig1[4];
+ char tsig2[4];
+
+ for (i = 0; i < 4; i++) {
+ tsig1[i] = sig1[i];
+ tsig2[i] = sig2[i];
+ }
+
+ /* for EBCDIC */
+ if (tsig1[0] == 'P')
+ tsig1[0] = 0x50;
+ if (tsig1[1] == 'K')
+ tsig1[1] = 0x4b;
+
+ if (tsig2[0] == 'P')
+ tsig2[0] = 0x50;
+ if (tsig2[1] == 'K')
+ tsig2[1] = 0x4b;
+
+ for (i = 0; i < 4; i++) {
+ if (tsig1[i] != tsig2[i]) {
+ /* not a match */
+ break;
+ }
+ }
+ if (i == 4) {
+ /* found it */
+ return 1;
+ }
+ return 0;
+}
+
+
+/* at_signature
+ *
+ * Is at signature in file
+ *
+ * Return 1 if at the signature and leave file pointing to next character
+ * after signature.
+ *
+ * Return 0 if not.
+ */
+
+local int at_signature(f, signature)
+ FILE *f;
+ ZCONST char *signature;
+{
+ int i;
+ extent m;
+ char sig[4];
+ char b[4];
+
+ for (i = 0; i < 4; i++)
+ sig[i] = signature[i];
+
+ /* for EBCDIC */
+ if (sig[0] == 'P')
+ sig[0] = 0x50;
+ if (sig[1] == 'K')
+ sig[1] = 0x4b;
+
+ m = fread(b, 1, 4, f);
+ if (m != 4) {
+ return 0;
+ } else {
+ for (i = 0; i < 4; i++) {
+ if (sig[i] != b[i]) {
+ /* not a match */
+ break;
+ }
+ }
+ if (i == 4) {
+ /* found it */
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+#ifndef UTIL
+
+local int scanzipf_fixnew()
+/*
+ Scan an assumed broke archive from the beginning, salvaging what can.
+
+ Generally scanzipf_regnew() is used for reading archives normally and
+ for fixing archives with a readable central directory using -F. This
+ scan is used by -FF and is for an archive that is unreadable by
+ scanzipf_regnew().
+
+ Start with the first file of the archive, either .z01 or .zip, and
+ look for local entries. Read local entries found and create zlist
+ entries for them. If we find central directory entries, read them
+ and update the zlist created while reading local entries.
+
+ The input path for the .zip file is in in_path. If this is a multiple disk
+ archive get the paths for splits from in_path as we go. If a split is not in
+ the same directory as the last split we ask the user where it is and update
+ in_path.
+ */
+/*
+ This is old:
+
+ The name of the zip file is pointed to by the global "zipfile". The globals
+ zipbeg, cenbeg, zfiles, zcount, zcomlen, zcomment, and zsort are filled in.
+ Return an error code in the ZE_ class.
+*/
+{
+ /* This function only reads the standard End-of-CentralDir record and the
+ standard CentralDir-Entry records directly. To conserve stack space,
+ only a buffer of minimal size is declared.
+ */
+# if CENHEAD > ENDHEAD
+# define FIXSCAN_BUFSIZE CENHEAD
+# else
+# define FIXSCAN_BUFSIZE ENDHEAD
+# endif
+
+ char scbuf[FIXSCAN_BUFSIZE]; /* buffer big enough for headers */
+ char *split_path;
+ ulg eocdr_disk;
+ uzoff_t eocdr_offset;
+
+ uzoff_t current_offset = 0; /* offset before */
+ uzoff_t offset = 0; /* location after return from seek */
+
+ int skip_disk = 0; /* 1 if user asks to skip current disk */
+ int skipped_disk = 0; /* 1 if skipped start disk and start offset is useless */
+
+ int r = 0; /* zipcopy return */
+ uzoff_t s; /* size of data, start of central */
+ struct zlist far * far *x; /* pointer last entry's link */
+ struct zlist far *z; /* current zip entry structure */
+ int plen;
+ char *in_path_ext;
+ int in_central_directory = 0; /* found a central directory record */
+ struct zlist far *cz;
+ uzoff_t cd_total_entries = 0; /* number of entries according to EOCDR */
+ ulg in_cd_start_disk; /* central directory start disk */
+ uzoff_t in_cd_start_offset; /* offset of start of cd on cd start disk */
+
+
+ total_disks = 1000000;
+
+ /* open the zipfile */
+ /* This must be .zip file, even if it doesn't exist */
+
+ /* see if zipfile name ends in .zip */
+ plen = strlen(in_path);
+
+#ifdef VMS
+ /* On VMS, adjust plen (and in_path_ext) to avoid the file version. */
+ plen -= strlen(vms_file_version(in_path));
+#endif /* def VMS */
+ in_path_ext = zipfile + plen - 4;
+
+ if (plen >= 4 &&
+ in_path_ext[0] == '.' &&
+ toupper(in_path_ext[1]) == 'Z' &&
+ in_path_ext[2] >= '0' && in_path_ext[2] <= '9' &&
+ in_path_ext[3] >= '0' && in_path_ext[3] <= '9' &&
+ (plen == 4 || (in_path_ext[4] >= '0' && in_path_ext[4] <= '9'))) {
+ /* This may be a split but not the end split */
+ strcpy(errbuf, "if archive to fix is split archive, need to provide\n");
+ strcat(errbuf, " path of the last split with .zip extension,\n");
+ strcat(errbuf, " even if it doesn't exist (zip will ask for splits)");
+ zipwarn(errbuf, "");
+ return ZE_FORM;
+ }
+
+ if ((in_file = zfopen(in_path, FOPR)) == NULL) {
+ zipwarn("could not open input archive: ", in_path);
+ }
+ else
+ {
+
+#ifndef ZIP64_SUPPORT
+ /* 2004-12-06 SMS.
+ * Check for too-big file before doing any serious work.
+ */
+ if (ffile_size( in_file) == EOF) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("input file requires Zip64 support: ", in_path);
+ return ZE_ZIP64;
+ }
+#endif /* ndef ZIP64_SUPPORT */
+
+ /* look for End Of Central Directory Record */
+
+ /* back up 64k (the max size of the EOCDR) from end */
+ if (zfseeko(in_file, -0x40000L, SEEK_END) != 0) {
+ /* assume file is less than 64 KB so backup to beginning */
+ if (zfseeko(in_file, 0L, SEEK_SET) != 0) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("unable to seek in input file ", in_path);
+ return ZE_READ;
+ }
+ }
+
+
+ /* find EOCD Record signature */
+ if (!find_signature(in_file, "PK\05\06")) {
+ /* No End Of Central Directory Record */
+ strcpy(errbuf, "Missing end (EOCDR) signature - either this archive\n");
+ strcat(errbuf, " is not readable or the end is damaged");
+ zipwarn(errbuf, "");
+ }
+ else
+ {
+ /* at start of data after EOCDR signature */
+ eocdr_offset = (uzoff_t) zftello(in_file);
+
+ /* OK, it is possible this is not the last EOCDR signature (might be
+ EOCDR signature from a stored archive in the last 64 KB) and so not
+ the one we want.
+
+ The below assumes the signature does not appear in the assumed
+ ASCII text .ZIP file comment. Even if something like UTF-8
+ is stored in the comment, it's unlikely the binary \05 and \06
+ will be in the comment text.
+ */
+ while (find_signature(in_file, "PK\05\06")) {
+ eocdr_offset = (uzoff_t) zftello(in_file);
+ }
+
+ /* found EOCDR */
+ /* format is
+ end of central dir signature 4 bytes (0x06054b50)
+ number of this disk 2 bytes
+ number of the disk with the
+ start of the central directory 2 bytes
+ total number of entries in the
+ central directory on this disk 2 bytes
+ total number of entries in
+ the central directory 2 bytes
+ size of the central directory 4 bytes
+ offset of start of central
+ directory with respect to
+ the starting disk number 4 bytes
+ .ZIP file comment length 2 bytes
+ .ZIP file comment (variable size)
+ */
+
+ if (zfseeko(in_file, eocdr_offset, SEEK_SET) != 0) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("unable to seek in input file ", in_path);
+ return ZE_READ;
+ }
+
+ /* read the EOCDR */
+ s = fread(scbuf, 1, ENDHEAD, in_file);
+
+ /* make sure we read enough bytes */
+ if (s < ENDHEAD) {
+ sprintf(errbuf, "End record (EOCDR) only %s bytes - assume truncated",
+ zip_fzofft(s, NULL, "u"));
+ zipwarn(errbuf, "");
+ }
+ else
+ {
+ /* the first field should be number of this (the last) disk */
+ eocdr_disk = (ulg)SH(scbuf);
+ total_disks = eocdr_disk + 1;
+
+ /* assume this is this disk - if Zip64 it may not be as the
+ disk number may be bigger than this field can hold
+ */
+ current_in_disk = total_disks - 1;
+
+ /* Central Directory disk, offset, and total entries */
+ in_cd_start_disk = (ulg)SH(scbuf + 2);
+ in_cd_start_offset = (uzoff_t)LG(scbuf + 12);
+ cd_total_entries = (uzoff_t)SH(scbuf + 6);
+
+ /* the in_cd_start_disk should always be less than the total_disks,
+ unless the -1 flags are being used */
+ if (total_disks < 0x10000 && in_cd_start_disk > total_disks) {
+ zipwarn("End record (EOCDR) has bad disk numbers - ignoring EOCDR", "");
+ total_disks = 0;
+ }
+ else
+ {
+ /* length of zipfile comment */
+ zcomlen = SH(scbuf + ENDCOM);
+ if (zcomlen)
+ {
+ if ((zcomment = malloc(zcomlen + 1)) == NULL)
+ return ZE_MEM;
+ if (fread(zcomment, zcomlen, 1, in_file) != 1)
+ {
+ free((zvoid *)zcomment);
+ zcomment = NULL;
+ zipwarn("zipfile comment truncated - ignoring", "");
+ } else {
+ zcomment[zcomlen] = '\0';
+ }
+#ifdef EBCDIC
+ if (zcomment)
+ memtoebc(zcomment, zcomment, zcomlen);
+#endif /* EBCDIC */
+ }
+ }
+ if (total_disks != 1)
+ sprintf(errbuf, " Found end record (EOCDR) - says expect %lu splits", total_disks);
+ else
+ sprintf(errbuf, " Found end record (EOCDR) - says expect single disk archive");
+ zipmessage(errbuf, "");
+ if (zcomment)
+ zipmessage(" Found archive comment", "");
+ } /* good EOCDR */
+
+ } /* found EOCDR */
+
+ /* if total disks is other than 1 then this is not start disk */
+ /* if the EOCDR is bad, total_disks is 0 */
+
+ /* if total_disks = 0, then guess if this is a single-disk archive
+ by seeing if starts with local header */
+
+ if (total_disks == 0) {
+ int issig;
+ /* seek to top */
+ if (zfseeko(in_file, 0, SEEK_SET) != 0) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("unable to seek in input file ", in_path);
+ return ZE_READ;
+ }
+ /* get next signature */
+ issig = find_next_signature(in_file);
+ if (issig) {
+ current_in_offset = zftello(in_file);
+ if (current_in_offset == 4 && is_signature(sigbuf, "PK\03\03")) {
+ /* could be multi-disk aborted signature at top */
+ /* skip */
+ issig = find_next_signature(in_file);
+ } else if (current_in_offset <= 4 && is_signature(sigbuf, "PK\03\03")) {
+ /* multi-disk spanning signature */
+ total_disks = 99999;
+ }
+ }
+ if (issig && total_disks == 0) {
+ current_in_offset = zftello(in_file);
+
+ if (current_in_offset == 8 && is_signature(sigbuf, "PK\03\04")) {
+
+ /* Local Header Record at top */
+
+ printf("Is this a single-disk archive? (y/n): ");
+ fflush(stdout);
+
+ if (fgets(errbuf, 100, stdin) != NULL) {
+ if (errbuf[0] == 'y' || errbuf[0] == 'Y') {
+ total_disks = 1;
+ zipmessage(" Assuming single-disk archive", "");
+ }
+ }
+ }
+ }
+ }
+ if (!noisy)
+ /* if quiet assume single-disk archive */
+ total_disks = 1;
+
+ if (total_disks == 1000000) {
+ /* still don't know, so ask */
+ printf("Is this a single-disk archive? (y/n): ");
+ fflush(stdout);
+
+ if (fgets(errbuf, 100, stdin) != NULL) {
+ if (errbuf[0] == 'y' || errbuf[0] == 'Y') {
+ total_disks = 1;
+ zipmessage(" Assuming single-disk archive", "");
+ }
+ }
+ }
+ if (total_disks == 1000000) {
+ /* assume max */
+ total_disks = 100000;
+ }
+
+ } /* .zip file exists */
+
+ /* Skip reading the Zip64 EOCDL, Zip64 EOCDR, or central directory */
+
+ /* Now read the archive starting with first disk. Find local headers,
+ create entry in zlist, then copy entry to new archive */
+
+ /* Multi-volume file names end in .z01, .z02, ..., .z10, .zip for 11 disk archive */
+
+ /* Unless quiet, always close the in_path disk and ask user for first disk,
+ unless there is an End Of Central Directory record and that says there is
+ only one disk.
+ If quiet, assume the file pointed to is a single file archive to fix. */
+ if (noisy && in_file) {
+ fclose(in_file);
+ in_file = NULL;
+ }
+
+ /* Read the archive disks - no idea how many disks there are
+ since we can't trust the EOCDR and other end records
+ */
+ zipmessage("Scanning for entries...", "");
+
+ for (current_in_disk = 0; current_in_disk < total_disks; current_in_disk++) {
+ /* get the path for this disk */
+ split_path = get_in_split_path(in_path, current_in_disk);
+
+ /* if in_file is not NULL then in_file is already open */
+ if (in_file == NULL) {
+ /* open the split */
+ while ((in_file = zfopen(split_path, FOPR)) == NULL) {
+ int result;
+ /* could not open split */
+
+ /* Ask for directory with split. Updates global variable in_path */
+ result = ask_for_split_read_path(current_in_disk);
+ if (result == ZE_ABORT) {
+ zipwarn("could not find split: ", split_path);
+ return ZE_ABORT;
+ } else if (result == ZE_EOF) {
+ zipmessage_nl("", 1);
+ zipwarn("user ended reading - closing archive", "");
+ return ZE_EOF;
+ } else if (result == ZE_FORM) {
+ /* user asked to skip this disk */
+ zipmessage_nl("", 1);
+ sprintf(errbuf, "skipping disk %lu ...\n", current_in_disk);
+ zipwarn(errbuf, "");
+ skip_disk = 1;
+ break;
+ }
+
+ split_path = get_in_split_path(in_path, current_in_disk);
+ }
+ if (skip_disk) {
+ /* skip this current disk - this works because central directory entries
+ can't be split across splits */
+ skip_disk = 0;
+ skipped_disk = 1;
+ continue;
+ }
+ }
+
+ if (skipped_disk) {
+ /* Not much to do here as between entries. Entries are copied
+ in zipcopy() and that has to handle missing disks while
+ reading data for an entry.
+ */
+ }
+
+ /* Main loop */
+ /* Look for next signature and process it */
+ while (find_next_signature(in_file)) {
+ current_in_offset = zftello(in_file);
+
+ if (is_signature(sigbuf, "PK\05\06")) {
+
+ /* End Of Central Directory Record */
+
+ sprintf(errbuf, "EOCDR found (%2lu %6s)...",
+ current_in_disk + 1, zip_fzofft(current_in_offset - 4, NULL, "u"));
+ zipmessage_nl(errbuf, 1);
+
+
+ } else if (is_signature(sigbuf, "PK\06\06")) {
+
+ /* Zip64 End Of Central Directory Record */
+
+ sprintf(errbuf, "Zip64 EOCDR found (%2lu %6s)...",
+ current_in_disk + 1, zip_fzofft(current_in_offset - 4, NULL, "u"));
+ zipmessage_nl(errbuf, 1);
+
+
+ } else if (is_signature(sigbuf, "PK\06\07")) {
+
+ /* Zip64 End Of Central Directory Locator */
+
+ sprintf(errbuf, "Zip64 EOCDL found (%2lu %6s)...",
+ current_in_disk + 1, zip_fzofft(current_in_offset - 4, NULL, "u"));
+ zipmessage_nl(errbuf, 1);
+
+
+ } else if (is_signature(sigbuf, "PK\03\04")) {
+
+ /* Local Header Record */
+
+
+ if (verbose) {
+ sprintf(errbuf, " Local (%2lu %6s):",
+ current_in_disk + 1, zip_fzofft(current_in_offset - 4, NULL, "u"));
+ zipmessage_nl(errbuf, 0);
+ }
+
+ /* Create zlist entry. Most will be filled in by zipcopy(). */
+
+ if ((z = (struct zlist far *)farmalloc(sizeof(struct zlist))) == NULL) {
+ zipwarn("reading central directory", "");
+ return ZE_MEM;
+ }
+
+ z->vem = 0;
+ z->ver = 0;
+ z->flg = 0;
+ z->how = 0;
+ z->tim = 0; /* time and date into one long */
+ z->crc = 0;
+ z->siz = 0;
+ z->len = 0;
+ z->nam = 0; /* used before comparing cen vs. loc */
+ z->cext = 0; /* may be different from z->ext */
+ z->com = 0;
+ z->dsk = 0;
+ z->att = 0;
+ z->atx = 0;
+ z->off = 0;
+ z->dosflag = 0;
+
+ /* Initialize all fields pointing to malloced data to NULL */
+ z->zname = z->name = z->iname = z->extra = z->cextra = z->comment = NULL;
+ z->oname = NULL;
+#ifdef UNICODE_SUPPORT
+ z->uname = z->zuname = z->ouname = NULL;
+#endif
+
+ /* Attempt to copy entry */
+
+ r = zipcopy(z);
+
+ if (in_central_directory) {
+ sprintf(errbuf, "Entry after central directory found (%2lu %6s)...",
+ current_in_disk + 1, zip_fzofft(current_in_offset - 4, NULL, "u"));
+ zipmessage_nl(errbuf, 1);
+ in_central_directory = 0;
+ }
+
+ if (r == ZE_EOF)
+ /* user said no more splits */
+ break;
+ else if (r == ZE_OK) {
+ zcount++;
+ files_total++;
+ bytes_total += z->siz;
+
+ /* Link into list */
+ if (zfiles == NULL)
+ /* first link */
+ x = &zfiles;
+ /* Link into list */
+ *x = z;
+ z->nxt = NULL;
+ x = &z->nxt;
+ }
+
+ } else if (is_signature(sigbuf, "PK\01\02")) {
+
+ /* Central directory header */
+
+
+ /* sort the zlist */
+ if (in_central_directory == 0) {
+ zipmessage("Central Directory found...", "");
+ /* If one or more files, sort by name */
+ if (zcount)
+ {
+ struct zlist far * far *x; /* pointer into zsort array */
+ struct zlist far *z; /* pointer into zfiles linked list */
+ int i = 0;
+ extent zl_size = zcount * sizeof(struct zlist far *);
+
+ if (zl_size / sizeof(struct zlist far *) != zcount ||
+ (x = zsort = (struct zlist far **)malloc(zl_size)) == NULL)
+ return ZE_MEM;
+ for (z = zfiles; z != NULL; z = z->nxt)
+ x[i++] = z;
+ qsort((char *)zsort, zcount, sizeof(struct zlist far *), zqcmp);
+
+ /* Skip Unicode searching */
+ }
+ }
+
+ if (verbose) {
+ sprintf(errbuf, " Cen (%2lu %6s): ",
+ current_in_disk + 1, zip_fzofft(current_in_offset - 4, NULL, "u"));
+ zipmessage_nl(errbuf, 0);
+ }
+
+ in_central_directory = 1;
+
+ /* Read central directory entry */
+
+ /* central directory signature */
+
+ /* The format of a central directory record
+ central file header signature 4 bytes (0x02014b50)
+ version made by 2 bytes
+ version needed to extract 2 bytes
+ general purpose bit flag 2 bytes
+ compression method 2 bytes
+ last mod file time 2 bytes
+ last mod file date 2 bytes
+ crc-32 4 bytes
+ compressed size 4 bytes
+ uncompressed size 4 bytes
+ file name length 2 bytes
+ extra field length 2 bytes
+ file comment length 2 bytes
+ disk number start 2 bytes
+ internal file attributes 2 bytes
+ external file attributes 4 bytes
+ relative offset of local header 4 bytes
+
+ file name (variable size)
+ extra field (variable size)
+ file comment (variable size)
+ */
+
+ if (fread(scbuf, CENHEAD, 1, in_file) != 1) {
+ zipwarn("reading central directory: ", strerror(errno));
+ zipwarn("bad archive - error reading central directory", "");
+ zipwarn("skipping this entry...", "");
+ continue;
+ }
+
+ if ((cz = (struct zlist far *)farmalloc(sizeof(struct zlist))) == NULL) {
+ zipwarn("reading central directory", "");
+ return ZE_MEM;
+ }
+
+ cz->vem = SH(CENVEM + scbuf);
+ cz->ver = SH(CENVER + scbuf);
+ cz->flg = SH(CENFLG + scbuf);
+ cz->how = SH(CENHOW + scbuf);
+ cz->tim = LG(CENTIM + scbuf); /* time and date into one long */
+ cz->crc = LG(CENCRC + scbuf);
+ cz->siz = LG(CENSIZ + scbuf);
+ cz->len = LG(CENLEN + scbuf);
+ cz->nam = SH(CENNAM + scbuf); /* used before comparing cen vs. loc */
+ cz->cext = SH(CENEXT + scbuf); /* may be different from z->ext */
+ cz->com = SH(CENCOM + scbuf);
+ cz->dsk = SH(CENDSK + scbuf);
+ cz->att = SH(CENATT + scbuf);
+ cz->atx = LG(CENATX + scbuf);
+ cz->off = LG(CENOFF + scbuf);
+ cz->dosflag = (cz->vem & 0xff00) == 0;
+
+ /* Initialize all fields pointing to malloced data to NULL */
+ cz->zname = cz->name = cz->iname = cz->extra = cz->cextra = NULL;
+ cz->comment = cz->oname = NULL;
+#ifdef UNICODE_SUPPORT
+ cz->uname = cz->zuname = cz->ouname = NULL;
+#endif
+
+ /* Read file name, extra field and comment field */
+ if (cz->nam == 0)
+ {
+ sprintf(errbuf, "%lu", (ulg)zcount + 1);
+ zipwarn("zero-length name for entry #", errbuf);
+ zipwarn("skipping this entry...", "");
+ continue;
+ }
+ if ((cz->iname = malloc(cz->nam+1)) == NULL ||
+ (cz->cext && (cz->cextra = malloc(cz->cext + 1)) == NULL) ||
+ (cz->com && (cz->comment = malloc(cz->com + 1)) == NULL))
+ return ZE_MEM;
+ if (fread(cz->iname, cz->nam, 1, in_file) != 1 ||
+ (cz->cext && fread(cz->cextra, cz->cext, 1, in_file) != 1) ||
+ (cz->com && fread(cz->comment, cz->com, 1, in_file) != 1)) {
+ zipwarn("error reading entry: ", strerror(errno));
+ zipwarn("skipping this entry...", "");
+ continue;
+ }
+ cz->iname[cz->nam] = '\0'; /* terminate name */
+
+ /* Look up this name in zlist from local entries */
+ z = zsearch(cz->iname);
+
+
+ if (z && z->tim == cz->tim) {
+
+ /* Apparently as iname and date and time match this central
+ directory entry goes with this zlist entry */
+
+ if (verbose) {
+ /* cen dir name matches a local name */
+ sprintf(errbuf, "updating: %s", cz->iname);
+ zipmessage_nl(errbuf, 0);
+ }
+
+ if (z->crc != cz->crc) {
+ sprintf(errbuf, "local (%lu) and cen (%lu) crc mismatch", z->crc, cz->crc);
+ zipwarn(errbuf, "");
+ }
+
+ z->vem = cz->vem;
+ /* z->ver = cz->ver; */
+ /* z->flg = cz->flg; */
+ /* z->how = cz->how; */
+ /* z->tim = cz->tim; */ /* time and date into one long */
+ /* z->crc = cz->crc; */
+ /* z->siz = cz->siz; */
+ /* z->len = cz->len; */
+ /* z->nam = cz->nam; */ /* used before comparing cen vs. loc */
+ z->cext = cz->cext; /* may be different from z->ext */
+ z->com = cz->com;
+ z->cextra = cz->cextra;
+ z->comment = cz->comment;
+ /* z->dsk = cz->dsk; */
+ z->att = cz->att;
+ z->atx = cz->atx;
+ /* z->off = cz->off; */
+ z->dosflag = cz->dosflag;
+
+#ifdef UNICODE_SUPPORT
+ if (unicode_mismatch != 3 && z->uname == NULL) {
+ if (z->flg & UTF8_BIT) {
+ /* path is UTF-8 */
+ if ((z->uname = malloc(strlen(z->iname) + 1)) == NULL) {
+ ZIPERR(ZE_MEM, "reading archive");
+ }
+ strcpy(z->uname, z->iname);
+ } else {
+ /* check for UTF-8 path extra field */
+ read_Unicode_Path_entry(z);
+ }
+ }
+#endif
+
+#ifdef WIN32
+ /* Input path may be OEM */
+ {
+ unsigned hostver = (z->vem & 0xff);
+ Ext_ASCII_TO_Native(z->iname, (z->vem >> 8), hostver,
+ ((z->atx & 0xffff0000L) != 0), FALSE);
+ }
+#endif
+
+#ifdef EBCDIC
+ if (z->com)
+ memtoebc(z->comment, z->comment, z->com);
+#endif /* EBCDIC */
+#ifdef WIN32
+ /* Comment may be OEM */
+ {
+ unsigned hostver = (z->vem & 0xff);
+ Ext_ASCII_TO_Native(z->comment, (z->vem >> 8), hostver,
+ ((z->atx & 0xffff0000L) != 0), FALSE);
+ }
+#endif
+
+#ifdef ZIP64_SUPPORT
+ /* zip64 support 08/31/2003 R.Nausedat */
+ /* here, we have to read the len, siz etc values from the CD */
+ /* entry as we might have to adjust them regarding their */
+ /* correspronding zip64 extra fields. */
+ /* also, we cannot compare the values from the CD entries with */
+ /* the values from the LH as they might be different. */
+
+ /* adjust/update siz,len and off (to come: dsk) entries */
+ /* PKZIP does not care of the version set in a CDH: if */
+ /* there is a zip64 extra field assigned to a CDH PKZIP */
+ /* uses it, we should do so, too. */
+ /*
+ adjust_zip_central_entry(z);
+ */
+#endif
+
+ /* Update zipbeg beginning of archive offset, prepare for next header */
+/*
+ if (z->dsk == 0 && (!zipbegset || z->off < zipbeg)) {
+ zipbeg = z->off;
+ zipbegset = 1;
+ }
+ zcount++;
+ */
+
+#ifndef UTIL
+ if (verbose)
+ zipoddities(z);
+#endif
+
+ current_offset = zftello(y);
+
+ if (zfseeko(y, z->off, SEEK_SET) != 0) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("writing archive seek: ", strerror(errno));
+ return ZE_WRITE;
+ }
+
+ if (putlocal(z, PUTLOCAL_REWRITE) != ZE_OK)
+ zipwarn("Error rewriting local header", "");
+
+ if (zfseeko(y, current_offset, SEEK_SET) != 0) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("write archive seek: ", strerror(errno));
+ return ZE_WRITE;
+ }
+ offset = zftello(y);
+ if (current_offset != offset) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("seek after local: ", strerror(errno));
+ return ZE_WRITE;
+ }
+
+ if (verbose)
+ zipmessage_nl("", 1);
+
+ } else {
+ /* cen dir name does not match local name */
+ sprintf(errbuf, "no local entry: %s", cz->iname);
+ zipmessage_nl(errbuf, 1);
+ }
+
+ } else if (zfiles == NULL && is_signature(sigbuf, "PK\07\010")) {
+
+ /* assume spanning signature at top of archive */
+ if (total_disks == 1) {
+ zipmessage(" Found spanning marker, but did not expect split (multi-disk) archive...", "");
+
+ } else if (total_disks > 1) {
+ zipmessage(" Found spanning marker - expected as this is split (multi-disk) archive...", "");
+
+ } else {
+ zipmessage(" Found spanning marker - could be split archive...", "");
+
+ }
+
+ } else {
+
+ /* this signature shouldn't be here */
+ int c;
+ char errbuftemp[40];
+
+ strcpy(errbuf, "unexpected signature ");
+ for (c = 0; c < 4; c++) {
+ sprintf(errbuftemp, "%02x ", sigbuf[c]);
+ strcat(errbuf, errbuftemp);
+ }
+ sprintf(errbuftemp, "on disk %lu at %s\n", current_in_disk,
+ zip_fzofft(current_in_offset - 4, NULL, "u"));
+ strcat(errbuf, errbuftemp);
+ zipwarn(errbuf, "");
+ zipwarn("skipping this signature...", "");
+ }
+
+
+ } /* while reading file */
+
+ /* close disk and do next disk */
+ if (in_file)
+ fclose(in_file);
+ in_file = NULL;
+ free(split_path);
+
+ if (r == ZE_EOF)
+ /* user says no more splits */
+ break;
+
+ } /* for each disk */
+
+ return ZE_OK;
+
+} /* end of function scanzipf_fixnew() */
+
+#endif /* !UTIL */
+
+
+
+
+
+
+/* ---------------------- */
+/* New regular scan */
+
+/*
+ * scanzipf_regnew is similar to the orignal scanzipf_reg in that it
+ * reads the end of the archive and goes from there. Unlike that
+ * scan this one stops after reading the central directory and does
+ * not read the local headers. After the directory scan for new
+ * files is done in zip.c the zlist created here is used to read
+ * the old archive entries there. The local headers are read using
+ * readlocal() in zipcopy().
+ *
+ * This scan assumes the zip file is well structured. If not it may
+ * fail and the new scanzipf_fixnew should be used.
+ *
+ * 2006-2-4, 2007-12-10 EG
+ */
+
+local int scanzipf_regnew()
+/*
+ The input path for the .zip file is in in_path. If a split archive,
+ the path for each split is created from the current disk number
+ and in_path. If a split is not in the same directory as the last
+ split we ask the user where it is and update in_path.
+ */
+/*
+ This is old but more or less still applies:
+
+ The name of the zip file is pointed to by the global "zipfile". The globals
+ zipbeg, cenbeg, zfiles, zcount, zcomlen, zcomment, and zsort are filled in.
+ Return an error code in the ZE_ class.
+*/
+{
+ /* In this function, a local buffer is used to read in the following Zip
+ structures:
+ End-of-CentralDir record (EOCDR) (ENDHEAD)
+ Zip64-End-of-CentralDir-Record locator (Zip64 EOCDL) (EC64LOC)
+ Zip64-End-of-CentralDir record (Zip64 EOCDR) (EC64REC)
+ CentralDir-Entry record (CENHEAD)
+ To conserve valuable stack space, this buffer is sized to the largest
+ of these structures.
+ */
+# if CENHEAD > ENDHEAD
+# define SCAN_BUFSIZE CENHEAD /* CENHEAD should be the larger struct */
+# else
+# define SCAN_BUFSIZE ENDHEAD
+# endif
+
+#ifdef ZIP64_SUPPORT
+# if EC64REC > SCAN_BUFSIZE
+# undef SCAN_BUFSIZE
+# define SCAN_BUFSIZE EC64REC /* EC64 record should be largest struct */
+# endif
+# if EC64LOC > SCAN_BUFSIZE
+# undef SCAN_BUFSIZE
+# define SCAN_BUFSIZE EC64LOC
+# endif
+#endif
+
+ char scbuf[SCAN_BUFSIZE]; /* buffer just enough for all header types */
+ char *split_path;
+ ulg eocdr_disk;
+ uzoff_t eocdr_offset;
+# ifdef ZIP64_SUPPORT
+ ulg z64eocdr_disk;
+ uzoff_t z64eocdr_offset;
+ uzoff_t z64eocdr_size;
+ ush version_made;
+ ush version_needed = 0;
+ zoff_t zip64_eocdr_start;
+ zoff_t z64eocdl_offset;
+# endif /* def ZIP64_SUPPORT */
+ uzoff_t cd_total_entries; /* num of entries as read from (Zip64) EOCDR */
+ ulg in_cd_start_disk; /* central directory start disk */
+ uzoff_t in_cd_start_offset; /* offset of start of cd on cd start disk */
+ uzoff_t adjust_offset = 0; /* bytes before first entry (size of sfx prefix) */
+ uzoff_t cd_total_size = 0; /* total size of cd */
+
+
+ int first_CD = 1; /* looking for first CD entry */
+ int zipbegset = 0;
+
+ int skip_disk = 0; /* 1 if user asks to skip current disk */
+ int skipped_disk = 0; /* 1 if skipped start disk and start offset is useless */
+
+ uzoff_t s; /* size of data, start of central */
+ struct zlist far * far *x; /* pointer last entry's link */
+ struct zlist far *z; /* current zip entry structure */
+
+
+ /* open the zipfile */
+ if ((in_file = zfopen(in_path, FOPR)) == NULL) {
+ zipwarn("could not open input archive", in_path);
+ return ZE_OPEN;
+ }
+
+#ifndef ZIP64_SUPPORT
+ /* 2004-12-06 SMS.
+ * Check for too-big file before doing any serious work.
+ */
+ if (ffile_size( in_file) == EOF) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("input file requires Zip64 support: ", in_path);
+ return ZE_ZIP64;
+ }
+#endif /* ndef ZIP64_SUPPORT */
+
+ /* look for End Of Central Directory Record */
+
+ /* In a valid Zip archive, the EOCDR can be at most (64k-1 + ENDHEAD + 4)
+ bytes (=65557 bytes) from the end of the file.
+ We back up 128k, to allow some junk being appended to a Zip file.
+ */
+ if ((zfseeko(in_file, -0x20000L, SEEK_END) != 0) ||
+ /* Some fseek() implementations (e.g. MSC 8.0 16-bit) fail to signal
+ an error when seeking before the beginning of the file.
+ As work-around, we check the position returned by zftello()
+ for the error value -1.
+ */
+ (zftello(in_file) == (zoff_t)-1L)) {
+ /* file is less than 128 KB so back up to beginning */
+ if (zfseeko(in_file, 0L, SEEK_SET) != 0) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("unable to seek in input file ", in_path);
+ return ZE_READ;
+ }
+ }
+
+ /* find EOCD Record signature */
+ if (!find_signature(in_file, "PK\05\06")) {
+ /* No End Of Central Directory Record */
+ fclose(in_file);
+ in_file = NULL;
+ if (fix == 1) {
+ zipwarn("bad archive - missing end signature", "");
+ zipwarn("(If downloaded, was binary mode used? If not, the", "");
+ zipwarn(" archive may be scrambled and not recoverable)", "");
+ zipwarn("Can't use -F to fix (try -FF)", "");
+ } else{
+ zipwarn("missing end signature--probably not a zip file (did you", "");
+ zipwarn("remember to use binary mode when you transferred it?)", "");
+ zipwarn("(if you are trying to read a damaged archive try -F)", "");
+ }
+ return ZE_FORM;
+ }
+
+ /* at start of data after EOCDR signature */
+ eocdr_offset = (uzoff_t) zftello(in_file);
+
+ /* OK, it is possible this is not the last EOCDR signature (might be
+ EOCDR signature from a stored archive in the last 128 KB) and so not
+ the one we want.
+
+ The below assumes the signature does not appear in the assumed ASCII text
+ .ZIP file comment.
+ */
+ while (find_signature(in_file, "PK\05\06")) {
+ /* previous one was not the one */
+ eocdr_offset = (uzoff_t) zftello(in_file);
+ }
+
+ /* found EOCDR */
+ /* format is
+ end of central dir signature 4 bytes (0x06054b50)
+ number of this disk 2 bytes
+ number of the disk with the
+ start of the central directory 2 bytes
+ total number of entries in the
+ central directory on this disk 2 bytes
+ total number of entries in
+ the central directory 2 bytes
+ size of the central directory 4 bytes
+ offset of start of central
+ directory with respect to
+ the starting disk number 4 bytes
+ .ZIP file comment length 2 bytes
+ .ZIP file comment (variable size)
+ */
+
+ if (zfseeko(in_file, eocdr_offset, SEEK_SET) != 0) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("unable to seek in input file ", in_path);
+ return ZE_READ;
+ }
+
+ /* read the EOCDR */
+ s = fread(scbuf, 1, ENDHEAD, in_file);
+
+ /* the first field should be number of this (the last) disk */
+ eocdr_disk = (ulg)SH(scbuf);
+ total_disks = eocdr_disk + 1;
+
+ /* Assume EOCDR disk is this disk. If a lot of disks, the Zip64 field
+ may be needed and this EOCDR field could be set to the Zip64 flag
+ value as the disk number may be bigger than this field can hold.
+ */
+ current_in_disk = total_disks - 1;
+
+ /* Central Directory disk, offset, and total entries */
+ in_cd_start_disk = (ulg)SH(scbuf + ENDBEG);
+ in_cd_start_offset = (uzoff_t)LG(scbuf + ENDOFF);
+ cd_total_entries = (uzoff_t)SH(scbuf + ENDTOT);
+ cd_total_size = (uzoff_t)LG(scbuf + ENDSIZ);
+
+ /* length of zipfile comment */
+ zcomlen = SH(scbuf + ENDCOM);
+ if (zcomlen)
+ {
+ if ((zcomment = malloc(zcomlen + 1)) == NULL)
+ return ZE_MEM;
+ if (fread(zcomment, zcomlen, 1, in_file) != 1)
+ {
+ free((zvoid *)zcomment);
+ zcomment = NULL;
+ return ferror(in_file) ? ZE_READ : ZE_EOF;
+ }
+ zcomment[zcomlen] = '\0';
+#ifdef EBCDIC
+ if (zcomment)
+ memtoebc(zcomment, zcomment, zcomlen);
+#endif /* EBCDIC */
+ }
+
+ if (cd_total_entries == 0) {
+ /* empty archive */
+
+ fclose(in_file);
+ in_file = NULL;
+ return ZE_OK;
+ }
+
+ /* if total disks is other than 1 then multi-disk archive */
+ if (total_disks != 1) {
+ /* zipfile name must end in .zip for split archives */
+ int plen = strlen(in_path);
+ char *in_path_ext;
+
+ if (adjust) {
+ zipwarn("Adjusting split archives not yet supported", "");
+ return ZE_FORM;
+ }
+
+#ifdef VMS
+ /* On VMS, adjust plen (and in_path_ext) to avoid the file version. */
+ plen -= strlen(vms_file_version(in_path));
+#endif /* def VMS */
+ in_path_ext = zipfile + plen - 4;
+
+ if (plen < 4 ||
+ in_path_ext[0] != '.' ||
+ toupper(in_path_ext[1]) != 'Z' ||
+ toupper(in_path_ext[2]) != 'I' ||
+ toupper(in_path_ext[3]) != 'P') {
+ zipwarn("archive name must end in .zip for splits", "");
+ fclose(in_file);
+ in_file = NULL;
+ return ZE_PARMS;
+ }
+ }
+
+ /* if input or output are split archives, must be different archives */
+ if ((total_disks != 1 || split_method) && !show_files &&
+ strcmp(in_path, out_path) == 0) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("cannot update a split archive (use --out option)", "");
+ return ZE_PARMS;
+ }
+
+ /* if fixing archive, input and output must be different archives */
+ if (fix == 1 && strcmp(in_path, out_path) == 0) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("must use --out when fixing an archive", "");
+ return ZE_PARMS;
+ }
+
+
+ /* Get sfx offset if adjusting. Above we made sure not split archive. */
+ /* Also check for an offset if fix and single disk archive. */
+ if ((fix == 1 && total_disks == 1) || adjust) {
+ zoff_t cd_start;
+# ifdef ZIP64_SUPPORT
+ zoff_t zip64_eocdr_start;
+# endif
+
+ /* First attempt. If the CD start offset and size are valid in the EOCDR
+ (meaning they are not the Zip64 flag values that say the actual values
+ are in the Zip64 EOCDR), we can use them to get the offset */
+ if (in_cd_start_offset != 0xFFFFFFFF && cd_total_size != 0xFFFFFFFF) {
+ /* Search for start of central directory */
+ /* There still might be a Zip64 EOCDR. This assumes if there is
+ a Zip64 EOCDR, it's version 1 and 52 bytes */
+ cd_start = eocdr_offset - cd_total_size - 24 - 56;
+ if (zfseeko(in_file, cd_start, SEEK_SET) != 0) {
+ fclose(in_file);
+ in_file = NULL;
+ if (fix == 1) {
+ zipwarn("could not seek back to start of central directory: ", strerror(errno));
+ zipwarn("(try -FF)", "");
+ } else {
+ zipwarn("reading archive fseek: ", strerror(errno));
+ }
+ return ZE_FORM;
+ }
+ if (find_signature(in_file, "PK\01\02")) {
+ /* Should now be after first central directory header signature in archive */
+ adjust_offset = zftello(in_file) - 4 - in_cd_start_offset;
+ } else {
+ zipwarn("central dir not where expected - could not adjust offsets", "");
+ zipwarn("(try -FF)", "");
+ return ZE_FORM;
+ }
+ } else {
+
+ /* Second attempt. We need the Zip64 EOCDL to get the offset */
+
+ /*
+ * Check for a Zip64 EOCD Locator signature
+ */
+
+ /* Format of Z64EOCD Locator is
+ zip64 end of central dir locator
+ signature 4 bytes (0x07064b50)
+ number of the disk with the
+ start of the zip64 end of
+ central directory 4 bytes
+ relative offset of the zip64
+ end of central directory record 8 bytes
+ total number of disks 4 bytes
+ */
+
+ /* back up 20 bytes from EOCDR to Z64 EOCDL */
+ if (zfseeko(in_file, eocdr_offset - 24, SEEK_SET) != 0) {
+ fclose(in_file);
+ in_file = NULL;
+ if (fix == 1) {
+ zipwarn("could not seek back to Zip64 EOCDL: ", strerror(errno));
+ zipwarn("(try -FF)", "");
+ } else {
+ zipwarn("reading archive fseek: ", strerror(errno));
+ }
+ return ZE_FORM;
+ }
+ if (at_signature(in_file, "PK\06\07"))
+#ifndef ZIP64_SUPPORT
+ {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("found Zip64 signature - this may be a Zip64 archive", "");
+ zipwarn("Need PKZIP 4.5 or later compatible zip", "");
+ zipwarn("Set ZIP64_SUPPORT in Zip 3", "");
+ return ZE_ZIP64;
+ }
+#else /* ZIP64_SUPPORT */
+ {
+ z64eocdl_offset = zftello(in_file) - 4;
+
+ /* read Z64 EOCDL */
+ if (fread(scbuf, EC64LOC, 1, in_file) != 1) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("reading archive: ", strerror(errno));
+ return ZE_READ;
+ }
+ /* now should be back at the EOCD signature */
+ if (!at_signature(in_file, "PK\05\06")) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("unable to read EOCD after seek: ", in_path);
+ return ZE_READ;
+ }
+
+ /* read disk and offset to Zip64 EOCDR and total disks */
+ z64eocdr_disk = LG(scbuf);
+ z64eocdr_offset = LLG(scbuf + 4);
+ total_disks = LG(scbuf + 12);
+
+ /* For now no split archives */
+ if (total_disks != 1) {
+ zipwarn("Adjusting split archives not supported: ", in_path);
+ zipwarn("(try -FF)", "");
+ return ZE_FORM;
+ }
+
+ /* go to the Zip64 EOCDR */
+ if (zfseeko(in_file, z64eocdr_offset, SEEK_SET) != 0) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("reading archive fseek: ", strerror(errno));
+ return ZE_FORM;
+ }
+ /* Should be at Zip64 EOCDR signature */
+ if (at_signature(in_file, "PK\06\06")) {
+ /* apparently no offset */
+
+ } else {
+ /* Wasn't there, so calculate based on Zip64 EOCDL offset */
+
+ zip64_eocdr_start = z64eocdl_offset - 24 - 56;
+ if (zfseeko(in_file, zip64_eocdr_start, SEEK_SET) != 0) {
+ fclose(in_file);
+ in_file = NULL;
+ if (fix == 1) {
+ zipwarn("could not seek back to Zip64 EOCDR: ", strerror(errno));
+ zipwarn("(try -FF)", "");
+ } else {
+ zipwarn("reading archive fseek: ", strerror(errno));
+ }
+ return ZE_FORM;
+ }
+ if (find_next_signature(in_file) && is_signature(sigbuf, "PK\06\06")) {
+ /* Should now be after Zip64 EOCDR signature in archive */
+ adjust_offset = zftello(in_file) - 4 - z64eocdr_offset;
+ } else {
+ zipwarn("Could not determine offset of entries", "");
+ zipwarn("(try -FF)", "");
+ return ZE_FORM;
+ }
+ }
+ }
+#endif
+ }
+ if (noisy) {
+ if (adjust_offset) {
+ sprintf(errbuf, "Zip entry offsets appear off by %s bytes - correcting...",
+ zip_fzofft(adjust_offset, NULL, NULL));
+ } else {
+ sprintf(errbuf, "Zip entry offsets do not need adjusting");
+ }
+ zipmessage(errbuf, "");
+ }
+ }
+
+
+ /*
+ * Check for a Zip64 EOCD Locator signature
+ */
+
+ /* Format of Z64EOCD Locator is
+ zip64 end of central dir locator
+ signature 4 bytes (0x07064b50)
+ number of the disk with the
+ start of the zip64 end of
+ central directory 4 bytes
+ relative offset of the zip64
+ end of central directory record 8 bytes
+ total number of disks 4 bytes
+ */
+
+ /* back up 20 bytes from EOCDR to Z64 EOCDL */
+ if (zfseeko(in_file, eocdr_offset - 24, SEEK_SET) != 0) {
+ fclose(in_file);
+ in_file = NULL;
+ if (fix == 1) {
+ zipwarn("bad archive - could not seek back to Zip64 EOCDL: ", strerror(errno));
+ zipwarn("(try -FF)", "");
+ } else {
+ zipwarn("reading archive fseek: ", strerror(errno));
+ }
+ return ZE_FORM;
+ }
+ if (at_signature(in_file, "PK\06\07"))
+#ifndef ZIP64_SUPPORT
+ {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("found Zip64 signature - this may be a Zip64 archive", "");
+ zipwarn("Need PKZIP 4.5 or later compatible zip", "");
+ zipwarn("Set ZIP64_SUPPORT in Zip 3", "");
+ return ZE_ZIP64;
+ }
+#else /* ZIP64_SUPPORT */
+ {
+ z64eocdl_offset = zftello(in_file) - 4;
+ /* read Z64 EOCDL */
+ if (fread(scbuf, EC64LOC, 1, in_file) != 1) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("reading archive: ", strerror(errno));
+ return ZE_READ;
+ }
+ /* now should be back at the EOCD signature */
+ if (!at_signature(in_file, "PK\05\06")) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("unable to read EOCD after seek: ", in_path);
+ return ZE_READ;
+ }
+
+ /* read disk and offset to Zip64 EOCDR and total disks */
+ z64eocdr_disk = LG(scbuf);
+ z64eocdr_offset = LLG(scbuf + 4) + adjust_offset;
+ total_disks = LG(scbuf + 12);
+
+ /* set the current disk */
+ current_in_disk = total_disks - 1;
+
+ /* Now need to read the Zip64 EOCD Record to get version needed
+ to extract */
+
+ if (z64eocdr_disk != total_disks - 1) {
+ /* Zip64 EOCDR not on this disk */
+
+ /* done with this disk (since apparently there are no CD entries
+ on it) */
+ fclose(in_file);
+ in_file = NULL;
+
+ /* get the path for the disk with the Zip64 EOCDR */
+ split_path = get_in_split_path(in_path, z64eocdr_disk);
+
+ while ((in_file = zfopen(split_path, FOPR)) == NULL) {
+ /* could not open split */
+
+ /* Ask where this split is. This call also updates global in_path. */
+ if (ask_for_split_read_path(z64eocdr_disk) != ZE_OK) {
+ return ZE_ABORT;
+ }
+ free(split_path);
+ split_path = get_in_split_path(in_path, z64eocdr_disk);
+ }
+ free(split_path);
+ }
+
+ current_in_disk = z64eocdr_disk;
+
+ /* go to the Zip64 EOCDR */
+ if (zfseeko(in_file, z64eocdr_offset, SEEK_SET) != 0) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("reading archive fseek: ", strerror(errno));
+ return ZE_FORM;
+ }
+ /* Should be at Zip64 EOCDR signature */
+ if (!at_signature(in_file, "PK\06\06")) {
+ /* Wasn't there, so calculate based on Zip64 EOCDL offset */
+ zip64_eocdr_start = z64eocdl_offset - 24 - 56;
+ if (zfseeko(in_file, zip64_eocdr_start, SEEK_SET) != 0) {
+ fclose(in_file);
+ in_file = NULL;
+ if (fix == 1) {
+ zipwarn("bad archive - could not seek back to Zip64 EOCDR: ", strerror(errno));
+ zipwarn("(try -FF)", "");
+ } else {
+ zipwarn("reading archive fseek: ", strerror(errno));
+ }
+ return ZE_FORM;
+ }
+ if (find_next_signature(in_file) && is_signature(sigbuf, "PK\06\06")) {
+ /* Should now be after Zip64 EOCDR signature in archive */
+ adjust_offset = zftello(in_file) - 4 - z64eocdr_offset;
+ zipwarn("Zip64 EOCDR not found where expected - compensating", "");
+ zipwarn("(try -A to adjust offsets)", "");
+ } else {
+ fclose(in_file);
+ in_file = NULL;
+ if (fix == 1) {
+ zipwarn("bad archive - Zip64 EOCDR not found in split: ", in_path);
+ zipwarn("(try -FF)", "");
+ } else {
+ zipwarn("Zip64 End Of Central Directory Record not found: ", in_path);
+ }
+ return ZE_FORM;
+ }
+ }
+
+ /*
+ * Read the Z64 End Of Central Directory Record
+ */
+
+ /* The format of the Z64 EOCDR is
+ zip64 end of central dir
+ signature 4 bytes (0x06064b50)
+ size of zip64 end of central
+ directory record 8 bytes
+ version made by 2 bytes
+ version needed to extract 2 bytes
+ number of this disk 4 bytes
+ number of the disk with the
+ start of the central directory 4 bytes
+ total number of entries in the
+ central directory on this disk 8 bytes
+ total number of entries in the
+ central directory 8 bytes
+ size of the central directory 8 bytes
+ offset of start of central
+ directory with respect to
+ the starting disk number 8 bytes
+ (version 2 of the Zip64 EOCDR has more after this)
+ zip64 extensible data sector (variable size)
+ */
+
+ /* read the first 52 bytes of the Zip64 EOCDR (we don't support
+ version 2, which supports PKZip licensed features)
+ */
+ s = fread(scbuf, 1, EC64REC, in_file);
+ if (s < EC64REC) {
+ if (fix == 1) {
+ zipwarn("bad archive - Zip64 EOCDR bad or truncated", "");
+ zipwarn("(try -FF)", "");
+ } else {
+ zipwarn("Zip64 EOCD Record bad or truncated", "");
+ }
+ fclose(in_file);
+ in_file = NULL;
+ return ZE_FORM;
+ }
+ z64eocdr_size = LLG(scbuf);
+ version_made = SH(scbuf + 8);
+ version_needed = SH(scbuf + 10);
+ in_cd_start_disk = LG(scbuf + 16);
+ cd_total_entries = LLG(scbuf + 28);
+ in_cd_start_offset = LLG(scbuf + 44) + adjust_offset;
+
+ if (version_needed > 46) {
+ int major = version_needed / 10;
+ int minor = version_needed - (major * 10);
+ sprintf(errbuf, "This archive requires version %d.%d", major, minor);
+ zipwarn(errbuf, "");
+ zipwarn("Zip currently only supports up to version 4.6 archives", "");
+ zipwarn("(up to 4.5 if bzip2 is not compiled in)", "");
+ if (fix == 1)
+ zipwarn("If -F fails try -FF to try to salvage something", "");
+ else if (fix == 2)
+ zipwarn("Attempting to salvage what can", "");
+ else {
+ zipwarn("Try -F to attempt to read anyway", "");
+ fclose(in_file);
+ in_file = NULL;
+ return ZE_FORM;
+ }
+ }
+ }
+#endif /* ?ZIP64_SUPPORT */
+
+ /* Now read the central directory and create the zlist */
+
+ /* Multi-volume file names end in .z01, .z02, ..., .z10, .zip for 11 disk archive */
+
+ in_cd_start_offset += adjust_offset;
+ cenbeg = in_cd_start_offset;
+ zipbegset = 0;
+ zipbeg = 0;
+ first_CD = 1;
+
+ /* if the central directory starts on other than this disk, close this disk */
+ if (current_in_disk != in_cd_start_disk) {
+ /* close current disk */
+ fclose(in_file);
+ in_file = NULL;
+ }
+
+ /* Read the disks with the central directory in order - usually the
+ central directory fits on the last disk, but it doesn't have to.
+ */
+ for (current_in_disk = in_cd_start_disk;
+ current_in_disk < total_disks;
+ current_in_disk++) {
+ /* get the path for this 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(in_path, current_in_disk);
+ }
+
+ /* if in_file is not NULL then in_file is already open */
+ if (in_file == NULL) {
+ /* open the split */
+ while ((in_file = zfopen(split_path, FOPR)) == NULL) {
+ int result;
+ /* could not open split */
+
+ /* Ask for directory with split. Updates global variable in_path */
+ result = ask_for_split_read_path(current_in_disk);
+ if (result == ZE_ABORT) {
+ zipwarn("could not find split: ", split_path);
+ return ZE_ABORT;
+ } else if (result == ZE_FORM) {
+ /* user asked to skip this disk */
+ sprintf(errbuf, "skipping disk %lu ...\n", current_in_disk);
+ zipwarn(errbuf, "");
+ skip_disk = 1;
+ break;
+ }
+
+ 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 (skip_disk) {
+ /* skip this current disk - this works because central directory entries
+ can't be split across splits */
+ skip_disk = 0;
+ skipped_disk = 1;
+ continue;
+ }
+ }
+
+ if (skipped_disk) {
+ /* skipped start CD disk so start searching for CD signature at start of disk */
+ first_CD = 0;
+ } else {
+ /* seek to the first CD entry */
+ if (first_CD) {
+ if (zfseeko(in_file, in_cd_start_offset, SEEK_SET) != 0) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("unable to seek in input file ", split_path);
+ return ZE_READ;
+ }
+ first_CD = 0;
+ x = &zfiles; /* first link */
+ }
+ }
+
+ /* Main loop */
+ /* Look for next signature and process it */
+ while (find_next_signature(in_file)) {
+ current_in_offset = zftello(in_file);
+
+ if (is_signature(sigbuf, "PK\05\06")) {
+ /* End Of Central Directory Record */
+ /*
+ fprintf(mesg, "EOCDR signature at %d / %I64d\n",
+ current_in_disk, current_in_offset - 4);
+ */
+ break;
+
+ } else if (is_signature(sigbuf, "PK\06\06")) {
+ /* Zip64 End Of Central Directory Record */
+ /*
+ fprintf(mesg, "Zip64 EOCDR signature at %d / %I64d\n",
+ current_in_disk, current_in_offset - 4);
+ */
+ break;
+
+ } else if (!is_signature(sigbuf, "PK\01\02")) {
+ /* Not Central Directory Record */
+
+ /* this signature shouldn't be here */
+ if (fix == 1) {
+ int c;
+ char errbuftemp[40];
+
+ strcpy(errbuf, "bad archive - unexpected signature ");
+ for (c = 0; c < 4; c++) {
+ sprintf(errbuftemp, "%02x ", sigbuf[c]);
+ strcat(errbuf, errbuftemp);
+ }
+ sprintf(errbuftemp, "on disk %lu at %s\n", current_in_disk,
+ zip_fzofft(current_in_offset - 4, NULL, "u"));
+ strcat(errbuf, errbuftemp);
+ zipwarn(errbuf, "");
+ zipwarn("skipping this signature...", "");
+ continue;
+ } else {
+ sprintf(errbuf, "unexpected signature on disk %lu at %s\n",
+ current_in_disk, zip_fzofft(current_in_offset - 4, NULL, "u"));
+ zipwarn(errbuf, "");
+ zipwarn("archive not in correct format: ", split_path);
+ zipwarn("(try -F to attempt recovery)", "");
+ fclose(in_file);
+ in_file = NULL;
+ return ZE_FORM;
+ }
+ }
+
+ /* central directory signature */
+ if (verbose && fix == 1) {
+ fprintf(mesg, "central directory header signature on disk %lu at %s\n",
+ current_in_disk, zip_fzofft(current_in_offset - 4, NULL, "u"));
+ }
+
+ /* The format of a central directory record
+ central file header signature 4 bytes (0x02014b50)
+ version made by 2 bytes
+ version needed to extract 2 bytes
+ general purpose bit flag 2 bytes
+ compression method 2 bytes
+ last mod file time 2 bytes
+ last mod file date 2 bytes
+ crc-32 4 bytes
+ compressed size 4 bytes
+ uncompressed size 4 bytes
+ file name length 2 bytes
+ extra field length 2 bytes
+ file comment length 2 bytes
+ disk number start 2 bytes
+ internal file attributes 2 bytes
+ external file attributes 4 bytes
+ relative offset of local header 4 bytes
+
+ file name (variable size)
+ extra field (variable size)
+ file comment (variable size)
+ */
+
+ if (fread(scbuf, CENHEAD, 1, in_file) != 1) {
+ zipwarn("reading central directory: ", strerror(errno));
+ if (fix == 1) {
+ zipwarn("bad archive - error reading central directory", "");
+ zipwarn("skipping this entry...", "");
+ continue;
+ } else {
+ return ferror(in_file) ? ZE_READ : ZE_EOF;
+ }
+ }
+
+ if ((z = (struct zlist far *)farmalloc(sizeof(struct zlist))) == NULL) {
+ zipwarn("reading central directory", "");
+ return ZE_MEM;
+ }
+
+ z->vem = SH(CENVEM + scbuf);
+ z->ver = SH(CENVER + scbuf);
+ z->flg = SH(CENFLG + scbuf);
+ z->how = SH(CENHOW + scbuf);
+ z->tim = LG(CENTIM + scbuf); /* time and date into one long */
+ z->crc = LG(CENCRC + scbuf);
+ z->siz = LG(CENSIZ + scbuf);
+ z->len = LG(CENLEN + scbuf);
+ z->nam = SH(CENNAM + scbuf); /* used before comparing cen vs. loc */
+ z->cext = SH(CENEXT + scbuf); /* may be different from z->ext */
+ z->com = SH(CENCOM + scbuf);
+ z->dsk = SH(CENDSK + scbuf);
+ z->att = SH(CENATT + scbuf);
+ z->atx = LG(CENATX + scbuf);
+ z->off = LG(CENOFF + scbuf); /* adjust_offset is added below */
+ z->dosflag = (z->vem & 0xff00) == 0;
+
+ /* Initialize all fields pointing to malloced data to NULL */
+ z->zname = z->name = z->iname = z->extra = z->cextra = z->comment = NULL;
+ z->oname = NULL;
+#ifdef UNICODE_SUPPORT
+ z->uname = z->zuname = z->ouname = NULL;
+#endif
+
+ /* Read file name, extra field and comment field */
+ if (z->nam == 0)
+ {
+ sprintf(errbuf, "%lu", (ulg)zcount + 1);
+ zipwarn("zero-length name for entry #", errbuf);
+ if (fix == 1) {
+ zipwarn("skipping this entry...", "");
+ continue;
+ }
+#ifndef DEBUG
+ return ZE_FORM;
+#endif
+ }
+ if ((z->iname = malloc(z->nam+1)) == NULL ||
+ (z->cext && (z->cextra = malloc(z->cext)) == NULL) ||
+ (z->com && (z->comment = malloc(z->com)) == NULL))
+ return ZE_MEM;
+ if (fread(z->iname, z->nam, 1, in_file) != 1 ||
+ (z->cext && fread(z->cextra, z->cext, 1, in_file) != 1) ||
+ (z->com && fread(z->comment, z->com, 1, in_file) != 1)) {
+ if (fix == 1) {
+ zipwarn("error reading entry: ", strerror(errno));
+ zipwarn("skipping this entry...", "");
+ continue;
+ }
+ return ferror(in_file) ? ZE_READ : ZE_EOF;
+ }
+ z->iname[z->nam] = '\0'; /* terminate name */
+#ifdef UNICODE_SUPPORT
+ if (unicode_mismatch != 3) {
+ if (z->flg & UTF8_BIT) {
+ char *iname;
+ /* path is UTF-8 */
+ if ((z->uname = malloc(strlen(z->iname) + 1)) == NULL) {
+ zipwarn("could not allocate memory: scanzipf_reg", "");
+ return ZE_MEM;
+ }
+ strcpy(z->uname, z->iname);
+ /* Create a local name. If UTF-8 system this should also be UTF-8 */
+ iname = utf8_to_local_string(z->uname);
+ if (iname) {
+ free(z->iname);
+ z->iname = iname;
+ }
+ else
+ zipwarn("illegal UTF-8 name: ", z->uname);
+ } else {
+ /* check for UTF-8 path extra field */
+ read_Unicode_Path_entry(z);
+ }
+ }
+#endif
+
+#ifdef WIN32
+ /* Input path may be OEM */
+ {
+ unsigned hostver = (z->vem & 0xff);
+ Ext_ASCII_TO_Native(z->iname, (z->vem >> 8), hostver,
+ ((z->atx & 0xffff0000L) != 0), FALSE);
+ }
+#endif
+
+#ifdef EBCDIC
+ if (z->com)
+ memtoebc(z->comment, z->comment, z->com);
+#endif /* EBCDIC */
+#ifdef WIN32
+ /* Comment may be OEM */
+ {
+ unsigned hostver = (z->vem & 0xff);
+ Ext_ASCII_TO_Native(z->comment, (z->vem >> 8), hostver,
+ ((z->atx & 0xffff0000L) != 0), FALSE);
+ }
+#endif
+
+#ifdef ZIP64_SUPPORT
+ /* zip64 support 08/31/2003 R.Nausedat */
+ /* here, we have to read the len, siz etc values from the CD */
+ /* entry as we might have to adjust them regarding their */
+ /* correspronding zip64 extra fields. */
+ /* also, we cannot compare the values from the CD entries with */
+ /* the values from the LH as they might be different. */
+
+ /* adjust/update siz,len and off (to come: dsk) entries */
+ /* PKZIP does not care of the version set in a CDH: if */
+ /* there is a zip64 extra field assigned to a CDH PKZIP */
+ /* uses it, we should do so, too. */
+ adjust_zip_central_entry(z);
+#endif
+ /* if adjusting for sfx prefix, add the offset */
+ if ((fix ==1 && total_disks == 1) || adjust) z->off += adjust_offset;
+
+ /* Update zipbeg beginning of archive offset, prepare for next header */
+ if (z->dsk == 0 && (!zipbegset || z->off < zipbeg)) {
+ zipbeg = z->off;
+ zipbegset = 1;
+ }
+ zcount++;
+
+ /* Clear actions */
+ z->mark = 0;
+ z->trash = 0;
+#if defined(UNICODE_SUPPORT) && !defined(UTIL)
+ z->zname = in2ex(z->iname); /* convert to external name */
+ if (z->zname == NULL)
+ return ZE_MEM;
+ if ((z->name = malloc(strlen(z->zname) + 1)) == NULL) {
+ zipwarn("could not allocate memory: scanzipf_reg", "");
+ return ZE_MEM;
+ }
+ strcpy(z->name, z->zname);
+ z->oname = local_to_display_string(z->iname);
+
+# ifdef WIN32
+ z->namew = NULL;
+ z->inamew = NULL;
+ z->znamew = NULL;
+# endif
+
+ if (unicode_mismatch != 3) {
+ if (z->uname) {
+ /* create zuname which is alternate zname for matching based on
+ converted Unicode name */
+ char *name;
+
+ /* Convert UTF-8 to current local character set */
+ name = utf8_to_local_string(z->uname);
+
+ if (name == NULL) {
+ /*
+ zipwarn("illegal UTF-8 name: ", z->uname);
+ */
+ /* not able to convert name, so use iname */
+ if ((name = malloc(strlen(z->iname) + 1)) == NULL) {
+ zipwarn("could not allocate memory: scanzipf_reg", "");
+ return ZE_MEM;
+ }
+ strcpy(name, z->iname);
+ }
+
+# ifdef EBCDIC
+ /* z->zname is used for printing and must be coded in native charset */
+ strtoebc(z->zuname, name);
+# else /* !EBCDIC */
+ if ((z->zuname = malloc(strlen(name) + 1)) == NULL) {
+ zipwarn("could not allocate memory: scanzipf_reg", "");
+ return ZE_MEM;
+ }
+ strcpy(z->zuname, name);
+ /* For output to terminal */
+ if (unicode_escape_all) {
+ char *ouname;
+ /* Escape anything not 7-bit ASCII */
+ ouname = utf8_to_escape_string(z->uname);
+ if (ouname)
+ z->ouname = ouname;
+ else {
+ if ((z->ouname = malloc(strlen(name) + 1)) == NULL) {
+ zipwarn("could not allocate memory: scanzipf_reg", "");
+ return ZE_MEM;
+ }
+ strcpy(z->ouname, name);
+ }
+ } else {
+ if ((z->ouname = malloc(strlen(name) + 1)) == NULL) {
+ zipwarn("could not allocate memory: scanzipf_reg", "");
+ return ZE_MEM;
+ }
+ strcpy(z->ouname, name);
+ }
+# ifdef WIN32
+
+ if (!no_win32_wide) {
+ z->inamew = utf8_to_wchar_string(z->uname);
+ z->znamew = in2exw(z->inamew); /* convert to external name */
+ if (z->znamew == NULL)
+ return ZE_MEM;
+ }
+
+ local_to_oem_string(z->ouname, z->ouname);
+ /* For matching. There seems to be something lost
+ in the translation from displaying a name in a
+ console window using zip -su on Win32 and using
+ that name in a command line to match what's in
+ the archive. This is klugy though.
+ */
+ if ((z->wuname = malloc(strlen(z->ouname) + 1)) == NULL) {
+ zipwarn("could not allocate memory: scanzipf_reg", "");
+ return ZE_MEM;
+ }
+ strcpy(z->wuname, z->ouname);
+ oem_to_local_string(z->wuname, z->wuname);
+# endif /* WIN32 */
+# endif /* ?EBCDIC */
+ } else {
+ /* no uname */
+# ifdef WIN32
+ if (!no_win32_wide) {
+ z->inamew = local_to_wchar_string(z->iname);
+ z->znamew = in2exw(z->inamew); /* convert to external name */
+ if (z->znamew == NULL)
+ return ZE_MEM;
+ }
+# endif
+ }
+ }
+#else /* !(UNICODE_SUPPORT && !UTIL) */
+# ifdef UTIL
+/* We only need z->iname in the utils */
+ z->name = z->iname;
+# ifdef EBCDIC
+/* z->zname is used for printing and must be coded in native charset */
+ if ((z->zname = malloc(z->nam+1)) == NULL) {
+ zipwarn("could not allocate memory: scanzipf_reg", "");
+ return ZE_MEM;
+ }
+ strtoebc(z->zname, z->iname);
+# else
+ z->zname = z->iname;
+# endif
+# else /* !UTIL */
+ z->zname = in2ex(z->iname); /* convert to external name */
+ if (z->zname == NULL)
+ return ZE_MEM;
+ z->name = z->zname;
+# endif /* ?UTIL */
+ if ((z->oname = malloc(strlen(z->zname) + 1)) == NULL) {
+ zipwarn("could not allocate memory: scanzipf_reg", "");
+ return ZE_MEM;
+ }
+ strcpy(z->oname, z->zname);
+#endif /* ?(UNICODE_SUPPORT && !UTIL) */
+
+#ifndef UTIL
+ if (verbose && fix == 0)
+ zipoddities(z);
+#endif
+
+ /* Link into list */
+ *x = z;
+ z->nxt = NULL;
+ x = &z->nxt;
+
+ } /* while reading file */
+
+ /* close disk and do next disk */
+ fclose(in_file);
+ in_file = NULL;
+ free(split_path);
+
+ if (!is_signature(sigbuf, "PK\01\02")) {
+ /* if the last signature is not a CD signature and we get here then
+ hit either the Zip64 EOCDR or the EOCDR and done */
+ break;
+ }
+
+ } /* for each disk */
+
+ if (zcount != cd_total_entries) {
+ sprintf(errbuf, "expected %s entries but found %s",
+ zip_fzofft(cd_total_entries, NULL, "u"),
+ zip_fzofft(zcount, NULL, "u"));
+ zipwarn(errbuf, "");
+ return ZE_FORM;
+ }
+
+ return ZE_OK;
+
+} /* end of function scanzipf_regnew() */
+
+
+
+
+
+
+
+
+/* ---------------------- */
+
+
+
+
/*
* readzipfile initializes the global variables that hold the zipfile
* directory info and opens the zipfile. For the actual zipfile scan,
@@ -1039,6 +5121,7 @@ int readzipfile()
zcomlen = 0; /* zip file comment length */
retval = ZE_OK;
f = NULL; /* shut up some compilers */
+ zipfile_exists = 0;
/* If zip file exists, read headers and check structure */
#ifdef VMS
@@ -1049,18 +5132,34 @@ int readzipfile()
if ((VMSmunch(zipfile, GET_RTYPE, (char *)&rtype) == RMS$_NORMAL) &&
(rtype == FAT$C_VARIABLE)) {
- fprintf(stderr,
+ fprintf(mesg,
"\n Error: zipfile is in variable-length record format. Please\n\
run \"bilf b %s\" to convert the zipfile to fixed-length\n\
record format.\n\n", zipfile);
return ZE_FORM;
}
}
- readable = ((f = fopen(zipfile, FOPR)) != NULL);
+ readable = ((f = zfopen(zipfile, FOPR)) != NULL);
#else /* !VMS */
- readable = (zipfile != NULL && *zipfile && strcmp(zipfile, "-") &&
- (f = fopen(zipfile, FOPR)) != NULL);
+ readable = (zipfile != NULL && *zipfile && strcmp(zipfile, "-"));
+ if (readable) {
+ readable = ((f = zfopen(zipfile, FOPR)) != NULL);
+ }
#endif /* ?VMS */
+
+ /* skip check if streaming */
+ if (!readable) {
+ if (!zip_to_stdout && fix != 2 && strcmp(in_path, out_path)) {
+ /* If -O used then in_path must exist */
+ if (fix == 1)
+ zipwarn("No .zip file found\n ",
+ "(If all you have are splits (.z01, .z02, ...) and no .zip, try -FF)");
+ ZIPERR(ZE_OPEN, zipfile);
+ }
+ } else {
+ zipfile_exists = 1;
+ }
+
#ifdef MVS
/* Very nasty special case for MVS. Just because the zipfile has been
* opened for reading does not mean that we can actually read the data.
@@ -1094,12 +5193,12 @@ int readzipfile()
char c;
fclose(f);
/* append mode */
- if ((f = fopen(zipfile, "ab")) == NULL) {
+ if ((f = zfopen(zipfile, "ab")) == NULL) {
ZIPERR(ZE_OPEN, zipfile);
}
fclose(f);
/* read mode again */
- if ((f = fopen(zipfile, FOPR)) == NULL) {
+ if ((f = zfopen(zipfile, FOPR)) == NULL) {
ZIPERR(ZE_OPEN, zipfile);
}
if (fread(&c, 1, 1, f) != 1) {
@@ -1112,17 +5211,31 @@ int readzipfile()
}
}
#endif /* MVS */
- if (readable)
- {
+
+ /* ------------------------ */
+ /* new file read */
+
+
+
#ifndef UTIL
- retval = (fix && !adjust) ? scanzipf_fix(f) : scanzipf_reg(f);
-#else
- retval = scanzipf_reg(f);
+ if (fix == 2) {
+ scanzipf_fixnew();
+ }
+ else
#endif
-
- /* Done with zip file for now */
+ if (readable)
+ {
+ /* close file as the new scan opens the splits as needed */
fclose(f);
+# ifndef UTIL
+ retval = (fix == 2 && !adjust) ? scanzipf_fixnew() : scanzipf_regnew();
+# else
+ retval = scanzipf_regnew();
+# endif
+ }
+ if (fix != 2 && readable)
+ {
/* If one or more files, sort by name */
if (zcount)
{
@@ -1136,172 +5249,1294 @@ int readzipfile()
for (z = zfiles; z != NULL; z = z->nxt)
*x++ = z;
qsort((char *)zsort, zcount, sizeof(struct zlist far *), zqcmp);
+
+#ifdef UNICODE_SUPPORT
+ /* sort by zuname (local conversion of UTF-8 name) */
+ if (zl_size / sizeof(struct zlist far *) != zcount ||
+ (x = zusort = (struct zlist far **)malloc(zl_size)) == NULL)
+ return ZE_MEM;
+ for (z = zfiles; z != NULL; z = z->nxt)
+ *x++ = z;
+ qsort((char *)zusort, zcount, sizeof(struct zlist far *), zuqcmp);
+#endif
}
}
+
+ /* ------------------------ */
+
return retval;
-}
+} /* end of function readzipfile() */
-int putlocal(z, f)
-struct zlist far *z; /* zip entry to write local header for */
-FILE *f; /* file to write to */
+int putlocal(z, rewrite)
+ struct zlist far *z; /* zip entry to write local header for */
+ int rewrite; /* did seek to rewrite */
/* Write a local header described by *z to file *f. Return an error code
in the ZE_ class. */
{
- PUTLG(LOCSIG, f);
- PUTSH(z->ver, f);
- PUTSH(z->lflg, f);
- PUTSH(z->how, f);
- PUTLG(z->tim, f);
- PUTLG(z->crc, f);
- PUTLG(z->siz, f);
- PUTLG(z->len, f);
- PUTSH(z->nam, f);
- PUTSH(z->ext, f);
- if (fwrite(z->iname, 1, z->nam, f) != z->nam ||
- (z->ext && fwrite(z->extra, 1, z->ext, f) != z->ext))
- return ZE_TEMP;
+ /* If any of compressed size (siz), uncompressed size (len), offset(off), or
+ disk number (dsk) is larger than can fit in the below standard fields then a
+ Zip64 flag value is stored and a Zip64 extra field is created.
+ Only siz and len are in the local header while all can be in the central
+ directory header.
+
+ For the local header if the extra field is created must store both
+ uncompressed and compressed sizes.
+
+ This assumes that for large entries the compressed size won't need a
+ Zip64 extra field if the uncompressed size did not. This assumption should
+ only fail for a large file of nearly totally uncompressable data.
+
+ If streaming stdin in and use_descriptors is set then always create a Zip64
+ extra field flagging the data descriptor as being in Zip64 format. This is
+ needed as don't know if need Zip64 or not when need to set Zip64 flag in
+ local header.
+
+ If rewrite is set then don't count bytes written for splits
+ */
+ char *block = NULL; /* mem block to write to */
+ extent offset = 0; /* offset into block */
+ extent blocksize = 0; /* size of block */
+#ifdef UNICODE_SUPPORT
+ ush nam = z->nam; /* size of name to write to header */
+ int use_uname = 0; /* write uname to header */
+#endif
+#ifdef ZIP64_SUPPORT
+ int streaming_in = 0; /* streaming stdin */
+ int was_zip64 = 0;
+
+ /* If input is stdin then streaming stdin. No problem with that.
+
+ The problem is updating the local header data in the output once the sizes
+ and crc are known. If the output is not seekable, then need data descriptors
+ and also need to assume Zip64 will be needed as don't know yet. Even if the
+ output is seekable, if the input is streamed need to write the Zip64 extra field
+ before writing the data or there won't be room for it later if we need it.
+ */
+ streaming_in = (strcmp(z->name, "-") == 0);
+
+ if (!rewrite) {
+ zip64_entry = 0;
+ /* initial local header */
+ if (z->siz > ZIP_UWORD32_MAX || z->len > ZIP_UWORD32_MAX ||
+ force_zip64 == 1 || (force_zip64 != 0 && streaming_in))
+ {
+ /* assume Zip64 */
+ if (force_zip64 == 0) {
+ zipwarn("Entry too big:", z->oname);
+ ZIPERR(ZE_BIG, "Large entry support disabled with -fz- but needed");
+ }
+ zip64_entry = 1; /* header of this entry has a field needing Zip64 */
+ if (z->ver < ZIP64_MIN_VER)
+ z->ver = ZIP64_MIN_VER;
+ was_zip64 = 1;
+ }
+ } else {
+ /* rewrite */
+ was_zip64 = zip64_entry;
+ zip64_entry = 0;
+ if (z->siz > ZIP_UWORD32_MAX || z->len > ZIP_UWORD32_MAX ||
+ force_zip64 == 1 || (force_zip64 != 0 && streaming_in))
+ {
+ /* Zip64 entry */
+ zip64_entry = 1;
+ }
+ if (force_zip64 == 0 && zip64_entry) {
+ /* tried to force into standard entry but needed Zip64 entry */
+ zipwarn("Entry too big:", z->oname);
+ ZIPERR(ZE_BIG, "Large entry support disabled with -fz- but entry needs");
+ }
+ /* Normally for a large archive if the input file is less than 4 GB then
+ the compressed or stored version should be less than 4 GB. If this
+ assumption is wrong this catches it. This is a problem even if not
+ streaming as the Zip64 extra field was not written and now there's no
+ room for it. */
+ if (was_zip64 == 0 && zip64_entry == 1) {
+ /* guessed wrong and need Zip64 */
+ zipwarn("Entry too big:", z->oname);
+ if (force_zip64 == 0) {
+ ZIPERR(ZE_BIG, "Compressed/stored entry unexpectedly large - do not use -fz-");
+ } else {
+ ZIPERR(ZE_BIG, "Poor compression resulted in unexpectedly large entry - try -fz");
+ }
+ }
+ if (zip64_entry) {
+ /* Zip64 entry still */
+ /* this archive needs Zip64 (version 4.5 unzipper) */
+ zip64_archive = 1;
+ if (z->ver < ZIP64_MIN_VER)
+ z->ver = ZIP64_MIN_VER;
+ } else {
+ /* it turns out we do not need Zip64 */
+ zip64_entry = 0;
+ }
+ if (was_zip64 && zip64_entry != 1) {
+ z->ver = 20;
+ }
+ }
+
+
+#endif /* ZIP64_SUPPORT */
+
+ /* Instead of writing to the file as we go, to do splits we have to write it
+ to memory and see if it will fit before writing the entire local header.
+ If the local header doesn't fit we need to save it for the next disk.
+ */
+
+#ifdef ZIP64_SUPPORT
+ if (zip64_entry || was_zip64)
+ /* update extra field */
+ add_local_zip64_extra_field( z );
+#endif /* ZIP64_SUPPORT */
+
+#ifdef UNICODE_SUPPORT
+# if 0
+ /* if UTF-8 bit is set on an existing entry, assume it should be */
+ /* clear the UTF-8 flag */
+ z->flg &= ~UTF8_BIT;
+ z->lflg &= ~UTF8_BIT;
+# endif
+
+ if (z->uname) {
+ /* need UTF-8 name */
+ if (utf8_force || using_utf8) {
+ z->lflg |= UTF8_BIT;
+ z->flg |= UTF8_BIT;
+ }
+ if (z->flg & UTF8_BIT) {
+ /* If this flag is set, then restore UTF-8 as path name */
+ use_uname = 1;
+ nam = strlen(z->uname);
+ } else {
+ /* use extra field */
+ add_Unicode_Path_local_extra_field(z);
+ }
+ } else {
+ /* clear UTF-8 bit as not needed */
+ z->flg &= ~UTF8_BIT;
+ z->lflg &= ~UTF8_BIT;
+ }
+#endif
+
+ append_ulong_to_mem(LOCSIG, &block, &offset, &blocksize); /* local file header signature */
+ append_ushort_to_mem(z->ver, &block, &offset, &blocksize); /* version needed to extract */
+ append_ushort_to_mem(z->lflg, &block, &offset, &blocksize); /* general purpose bit flag */
+ append_ushort_to_mem(z->how, &block, &offset, &blocksize); /* compression method */
+ append_ulong_to_mem(z->tim, &block, &offset, &blocksize); /* last mod file date time */
+ append_ulong_to_mem(z->crc, &block, &offset, &blocksize); /* crc-32 */
+#ifdef ZIP64_SUPPORT /* zip64 support 09/02/2003 R.Nausedat */
+ /* changes 10/5/03 EG */
+ if (zip64_entry) {
+ append_ulong_to_mem(0xFFFFFFFF, &block, &offset, &blocksize); /* compressed size */
+ append_ulong_to_mem(0xFFFFFFFF, &block, &offset, &blocksize); /* uncompressed size */
+ } else {
+ append_ulong_to_mem((ulg)z->siz, &block, &offset, &blocksize);/* compressed size */
+ append_ulong_to_mem((ulg)z->len, &block, &offset, &blocksize);/* uncompressed size */
+ }
+#else
+ append_ulong_to_mem((ulg)z->siz, &block, &offset, &blocksize); /* compressed size */
+ append_ulong_to_mem((ulg)z->len, &block, &offset, &blocksize); /* uncompressed size */
+#endif
+#ifdef UNICODE_SUPPORT
+ append_ushort_to_mem(nam, &block, &offset, &blocksize); /* file name length */
+#else
+ append_ushort_to_mem(z->nam, &block, &offset, &blocksize); /* file name length */
+#endif
+
+ append_ushort_to_mem(z->ext, &block, &offset, &blocksize); /* extra field length */
+
+#ifdef UNICODE_SUPPORT
+ if (use_uname) {
+ /* path is UTF-8 */
+ append_string_to_mem(z->uname, nam, &block, &offset, &blocksize);
+ } else
+#endif
+#ifdef WIN32_OEM
+ /* store name in OEM character set in archive */
+ if ((z->vem & 0xff00) == 0)
+ {
+ char *oem;
+
+ if ((oem = malloc(strlen(z->iname) + 1)) == NULL)
+ ZIPERR(ZE_MEM, "putlocal oem");
+ INTERN_TO_OEM(z->iname, oem);
+ append_string_to_mem(oem, z->nam, &block, &offset, &blocksize); /* file name */
+ free(oem);
+ } else {
+ append_string_to_mem(z->iname, z->nam, &block, &offset, &blocksize); /* file name */
+ }
+#else
+ append_string_to_mem(z->iname, z->nam, &block, &offset, &blocksize); /* file name */
+#endif
+ if (z->ext) {
+ append_string_to_mem(z->extra, z->ext, &block, &offset, &blocksize); /* extra field */
+ }
+
+ /* write the header */
+ if (rewrite == PUTLOCAL_REWRITE) {
+ /* use fwrite as seeked back and not extending the archive */
+ /* also if split_method 1 write to file with local header */
+ if (split_method == 1) {
+ if (fwrite(block, 1, offset, current_local_file) != offset) {
+ free(block);
+ return ZE_TEMP;
+ }
+ /* now can close the split if local header on previous split */
+ if (current_local_disk != current_disk) {
+ close_split(current_local_disk, current_local_file, current_local_tempname);
+ current_local_file = NULL;
+ free(current_local_tempname);
+ }
+ } else {
+ /* not doing splits */
+ if (fwrite(block, 1, offset, y) != offset) {
+ free(block);
+ return ZE_TEMP;
+ }
+ }
+ } else {
+ /* do same if archive not split or split_method 2 with descriptors */
+ /* use bfwrite which counts bytes for splits */
+ if (bfwrite(block, 1, offset, BFWRITE_LOCALHEADER) != offset) {
+ free(block);
+ return ZE_TEMP;
+ }
+ }
+ free(block);
return ZE_OK;
}
-int putextended(z, f)
-struct zlist far *z; /* zip entry to write local header for */
-FILE *f; /* file to write to */
-/* Write an extended local header described by *z to file *f.
- * Return an error code in the ZE_ class. */
+int putextended(z)
+ struct zlist far *z; /* zip entry to write local header for */
+ /* This is the data descriptor.
+ * Write an extended local header described by *z to file *f.
+ * Return an error code in the ZE_ class. */
{
- PUTLG(EXTLOCSIG, f);
- PUTLG(z->crc, f);
- PUTLG(z->siz, f);
- PUTLG(z->len, f);
+ /* write to mem block then write to file 3/10/2005 */
+ char *block = NULL; /* mem block to write to */
+ extent offset = 0; /* offset into block */
+ extent blocksize = 0; /* size of block */
+
+ append_ulong_to_mem(EXTLOCSIG, &block, &offset, &blocksize); /* extended local signature */
+ append_ulong_to_mem(z->crc, &block, &offset, &blocksize); /* crc-32 */
+#ifdef ZIP64_SUPPORT
+ if (zip64_entry) {
+ /* use Zip64 entries */
+ append_int64_to_mem(z->siz, &block, &offset, &blocksize); /* compressed size */
+ append_int64_to_mem(z->len, &block, &offset, &blocksize); /* uncompressed size */
+ /* This is rather klugy as the AppNote handles this poorly. Typically
+ we don't know at this point if we are writing a Zip64 archive or not,
+ unless a file has needed Zip64. This is particularly annoying here
+ when deciding the size of the data descriptor (extended local header)
+ fields as the appnote says the uncompressed and compressed sizes
+ should be 8 bytes if the archive is Zip64 and 4 bytes if not.
+
+ One interpretation is the version of the archive is determined from
+ the Version Needed To Extract field in the Zip64 End Of Central Directory
+ record and so either an archive should start as Zip64 and write all data
+ descriptors with 8-byte fields or store everything until all the files
+ are processed and then write everything to the archive as changing the
+ sizes of the data descriptors is messy and just not feasible when
+ streaming to standard output. This is not easily workable and others
+ use the different interpretation below.
+
+ This was the old thought:
+ We always write a standard data descriptor. If the file has a large
+ uncompressed or compressed size we set the field to the max field
+ value, which we are defining as flagging the field as having a Zip64
+ value that doesn't fit. As the CRC happens before the variable size
+ fields the CRC is still valid and can be used to check the file. We
+ always use deflate if streaming so signatures should not appear in
+ the data and all local header signatures should be valid, allowing a
+ streaming unzip to find entries by local header signatures, if max size
+ values in the data descriptor sizes ignore them, and extract the file and
+ check it using the CRC. If not streaming the central directory is available
+ so just use those values which are correct.
+
+ After discussions with other groups this is the current thinking:
+
+ Apparent industry interpretation for data descriptors:
+ Data descriptor size is determined for each entry. If the local header
+ version needed to extract is 45 or higher then the entry can use Zip64
+ data descriptors but more checking is needed. If Zip64 extra field is
+ present then assume data descriptor is Zip64 and local version needed
+ to extract should be 45 or higher. If standard data descriptor then
+ local size fields are set to 0 and correct sizes are in standard data descriptor.
+ If Zip64 data descriptor then local sizes are set to -1, Zip64 extra field
+ sizes are set to 0, and the correct sizes are in the Zip64 data descriptor.
+
+ So do this:
+ If an entry is standard and the archive is updatable then seek back and
+ update the local header. No change.
+
+ If an entry is zip64 and the archive is updatable assume the Zip64 extra
+ field was created and update it. No change.
+
+ If data descriptors are needed then assume the archive is Zip64. This is
+ a change and means if ZIP64_SUPPORT is enabled that any non-updatable archive
+ will be in Zip64 format and use Zip64 data descriptors. This should be
+ compatible with other zippers that depend on the current (though not perfect)
+ AppNote description.
+
+ If anyone has some ideas on this I'd like to hear them.
+
+ 3/20/05 EG
+
+ Only assume need Zip64 if the input size is unknown. If the input size is
+ known we can assume Zip64 if the input is larger than 4 GB and assume not
+ otherwise. If the output is seekable we still need to create the Zip64
+ extra field if the input size is unknown so we can seek back and update it.
+ 12/28/05 EG
+ Updated 5/21/06 EG
+ */
+ } else {
+ /* for encryption */
+ append_ulong_to_mem((ulg)z->siz, &block, &offset, &blocksize); /* compressed size */
+ append_ulong_to_mem((ulg)z->len, &block, &offset, &blocksize); /* uncompressed size */
+ }
+#else
+ append_ulong_to_mem((ulg)z->siz, &block, &offset, &blocksize); /* compressed size */
+ append_ulong_to_mem((ulg)z->len, &block, &offset, &blocksize); /* uncompressed size */
+#endif
+ /* write the header */
+ if (bfwrite(block, 1, offset, BFWRITE_HEADER) != offset) {
+ free(block);
+ return ZE_TEMP;
+ }
+ free(block);
return ZE_OK;
}
-int putcentral(z, f)
-struct zlist far *z; /* zip entry to write central header for */
-FILE *f; /* file to write to */
+int putcentral(z)
+ struct zlist far *z; /* zip entry to write central header for */
/* Write a central header described by *z to file *f. Return an error code
in the ZE_ class. */
+/* output now uses bfwrite which writes global y */
{
- PUTLG(CENSIG, f);
- PUTSH(z->vem, f);
- PUTSH(z->ver, f);
- PUTSH(z->flg, f);
- PUTSH(z->how, f);
- PUTLG(z->tim, f);
- PUTLG(z->crc, f);
- PUTLG(z->siz, f);
- PUTLG(z->len, f);
- PUTSH(z->nam, f);
- PUTSH(z->cext, f);
- PUTSH(z->com, f);
- PUTSH(z->dsk, f);
- PUTSH(z->att, f);
- PUTLG(z->atx, f);
- PUTLG(z->off, f);
+ /* If any of compressed size (siz), uncompressed size (len), offset(off), or
+ disk number (dsk) is larger than can fit in the below standard fields then a
+ Zip64 flag value is stored and a Zip64 extra field is created.
+ Only siz and len are in the local header while all are in the central directory
+ header.
+
+ For the central directory header just store the fields required. All previous fields
+ must be stored though. So can store none (no extra field), just uncompressed size
+ (len), len then siz, len then siz then off, or len then siz then off then dsk, in
+ those orders. 10/6/03 EG
+ */
+
+ /* write to mem block then write to file 3/10/2005 EG */
+ char *block = NULL; /* mem block to write to */
+ extent offset = 0; /* offset into block */
+ extent blocksize = 0; /* size of block */
+ uzoff_t off = 0; /* offset to start of local header */
+ ush nam = z->nam; /* size of name to write to header */
+#ifdef UNICODE_SUPPORT
+ int use_uname = 0; /* write uname to header */
+#endif
+
+#ifdef ZIP64_SUPPORT /* zip64 support 09/02/2003 R.Nausedat */
+ int iRes;
+#endif
+
+#ifdef UNICODE_SUPPORT
+ if (z->uname) {
+ if (utf8_force) {
+ z->flg |= UTF8_BIT;
+ }
+ if (z->flg & UTF8_BIT) {
+ /* If this flag is set, then restore UTF-8 as path name */
+ use_uname = 1;
+ nam = strlen(z->uname);
+ } else {
+ add_Unicode_Path_cen_extra_field(z);
+ }
+ } else {
+ /* clear UTF-8 bit as not needed */
+ z->flg &= ~UTF8_BIT;
+ z->lflg &= ~UTF8_BIT;
+ }
+#endif
+
+ off = z->off;
+
+#ifdef ZIP64_SUPPORT /* zip64 support 09/02/2003 R.Nausedat */
+ if (z->siz > ZIP_UWORD32_MAX || z->len > ZIP_UWORD32_MAX ||
+ z->off > ZIP_UWORD32_MAX || z->dsk > ZIP_UWORD16_MAX || (force_zip64 == 1))
+ {
+ iRes = add_central_zip64_extra_field(z);
+ if( iRes != ZE_OK )
+ return iRes;
+ }
+
+ append_ulong_to_mem(CENSIG, &block, &offset, &blocksize); /* central file header signature */
+ append_ushort_to_mem(z->vem, &block, &offset, &blocksize); /* version made by */
+ append_ushort_to_mem(z->ver, &block, &offset, &blocksize); /* version needed to extract */
+ append_ushort_to_mem(z->flg, &block, &offset, &blocksize); /* general purpose bit flag */
+ append_ushort_to_mem(z->how, &block, &offset, &blocksize); /* compression method */
+ append_ulong_to_mem(z->tim, &block, &offset, &blocksize); /* last mod file date time */
+ append_ulong_to_mem(z->crc, &block, &offset, &blocksize); /* crc-32 */
+ if (z->siz > ZIP_UWORD32_MAX)
+ {
+ /* instead of z->siz */
+ append_ulong_to_mem(ZIP_UWORD32_MAX, &block, &offset, &blocksize); /* compressed size */
+ }
+ else
+ {
+ append_ulong_to_mem((ulg)z->siz, &block, &offset, &blocksize); /* compressed size */
+ }
+ /* if forcing Zip64 just force first ef field */
+ if (z->len > ZIP_UWORD32_MAX || (force_zip64 == 1))
+ {
+ /* instead of z->len */
+ append_ulong_to_mem(ZIP_UWORD32_MAX, &block, &offset, &blocksize); /* uncompressed size */
+ }
+ else
+ {
+ append_ulong_to_mem((ulg)z->len, &block, &offset, &blocksize); /* uncompressed size */
+ }
+ append_ushort_to_mem(nam, &block, &offset, &blocksize); /* file name length */
+ append_ushort_to_mem(z->cext, &block, &offset, &blocksize); /* extra field length */
+ append_ushort_to_mem(z->com, &block, &offset, &blocksize); /* file comment length */
+
+ if (z->dsk > ZIP_UWORD16_MAX)
+ {
+ /* instead of z->dsk */
+ append_ushort_to_mem((ush)ZIP_UWORD16_MAX, &block, &offset, &blocksize); /* Zip64 flag */
+ }
+ else
+ {
+ append_ushort_to_mem((ush)z->dsk, &block, &offset, &blocksize); /* disk number start */
+ }
+ append_ushort_to_mem(z->att, &block, &offset, &blocksize); /* internal file attributes */
+ append_ulong_to_mem(z->atx, &block, &offset, &blocksize); /* external file attributes */
+ if (off > ZIP_UWORD32_MAX)
+ {
+ /* instead of z->off */
+ append_ulong_to_mem(ZIP_UWORD32_MAX, &block, &offset, &blocksize); /* Zip64 flag */
+ }
+ else
+ {
+ append_ulong_to_mem((ulg)off, &block, &offset, &blocksize); /* offset of local header */
+ }
+
+#else /* !ZIP64_SUPPORT */
+
+ append_ulong_to_mem(CENSIG, &block, &offset, &blocksize); /* central file header signature */
+ append_ushort_to_mem(z->vem, &block, &offset, &blocksize); /* version made by */
+ append_ushort_to_mem(z->ver, &block, &offset, &blocksize); /* version needed to extract */
+ append_ushort_to_mem(z->flg, &block, &offset, &blocksize); /* general purpose bit flag */
+ append_ushort_to_mem(z->how, &block, &offset, &blocksize); /* compression method */
+ append_ulong_to_mem(z->tim, &block, &offset, &blocksize); /* last mod file date time */
+ append_ulong_to_mem(z->crc, &block, &offset, &blocksize); /* crc-32 */
+ append_ulong_to_mem((ulg)z->siz, &block, &offset, &blocksize); /* compressed size */
+ append_ulong_to_mem((ulg)z->len, &block, &offset, &blocksize); /* uncompressed size */
+ append_ushort_to_mem(nam, &block, &offset, &blocksize); /* file name length */
+ append_ushort_to_mem(z->cext, &block, &offset, &blocksize); /* extra field length */
+ append_ushort_to_mem(z->com, &block, &offset, &blocksize); /* file comment length */
+ append_ushort_to_mem((ush)z->dsk, &block, &offset, &blocksize); /* disk number start */
+ append_ushort_to_mem(z->att, &block, &offset, &blocksize); /* internal file attributes */
+ append_ulong_to_mem(z->atx, &block, &offset, &blocksize); /* external file attributes */
+ append_ulong_to_mem((ulg)off, &block, &offset, &blocksize); /* relative offset of local header */
+
+#endif /* ZIP64_SUPPORT */
+
#ifdef EBCDIC
if (z->com)
memtoasc(z->comment, z->comment, z->com);
#endif /* EBCDIC */
- if (fwrite(z->iname, 1, z->nam, f) != z->nam ||
- (z->cext && fwrite(z->cextra, 1, z->cext, f) != z->cext) ||
- (z->com && fwrite(z->comment, 1, z->com, f) != z->com))
+
+#ifdef UNICODE_SUPPORT
+ if (use_uname) {
+ /* path is UTF-8 */
+ append_string_to_mem(z->uname, nam, &block, &offset, &blocksize);
+ } else
+#endif
+#ifdef WIN32_OEM
+ /* store name in OEM character set in archive */
+ if ((z->vem & 0xff00) == 0)
+ {
+ char *oem;
+
+ if ((oem = malloc(strlen(z->iname) + 1)) == NULL)
+ ZIPERR(ZE_MEM, "putcentral oem");
+ INTERN_TO_OEM(z->iname, oem);
+ append_string_to_mem(oem, z->nam, &block, &offset, &blocksize);
+ free(oem);
+ } else {
+ append_string_to_mem(z->iname, z->nam, &block, &offset, &blocksize);
+ }
+#else
+ append_string_to_mem(z->iname, z->nam, &block, &offset, &blocksize);
+#endif
+
+ if (z->cext) {
+ append_string_to_mem(z->cextra, z->cext, &block, &offset, &blocksize);
+ }
+ if (z->com) {
+#ifdef WIN32_OEM
+ /* store comment in OEM character set in archive */
+ if ((z->vem & 0xff00) == 0)
+ {
+ char *oem;
+
+ if ((oem = malloc(strlen(z->comment) + 1)) == NULL)
+ ZIPERR(ZE_MEM, "putcentral oem comment");
+ INTERN_TO_OEM(z->comment, oem);
+ append_string_to_mem(oem, z->com, &block, &offset, &blocksize);
+ free(oem);
+ } else {
+ append_string_to_mem(z->comment, z->com, &block, &offset, &blocksize);
+ }
+#else
+ append_string_to_mem(z->comment, z->com, &block, &offset, &blocksize);
+#endif
+ }
+
+ /* write the header */
+ if (bfwrite(block, 1, offset, BFWRITE_CENTRALHEADER) != offset) {
+ free(block);
return ZE_TEMP;
+ }
+ free(block);
+
return ZE_OK;
}
-int putend(n, s, c, m, z, f)
-int n; /* number of entries in central directory */
-ulg s; /* size of central directory */
-ulg c; /* offset of central directory */
-extent m; /* length of zip file comment (0 if none) */
-char *z; /* zip file comment if m != 0 */
-FILE *f; /* file to write to */
-/* Write the end of central directory data to file *f. Return an error code
+/* Write the end of central directory data to file y. Return an error code
in the ZE_ class. */
+
+int putend( OFT( uzoff_t) n,
+ OFT( uzoff_t) s,
+ OFT( uzoff_t) c,
+ OFT( extent) m,
+ OFT( char *) z
+ )
+#ifdef NO_PROTO
+ uzoff_t n; /* number of entries in central directory */
+ uzoff_t s; /* size of central directory */
+ uzoff_t c; /* offset of central directory */
+ extent m; /* length of zip file comment (0 if none) */
+ char *z; /* zip file comment if m != 0 */
+#endif /* def NO_PROTO */
{
- PUTLG(ENDSIG, f);
- PUTSH(0, f);
- PUTSH(0, f);
- PUTSH(n, f);
- PUTSH(n, f);
- PUTLG(s, f);
- PUTLG(c, f);
- PUTSH(m, f);
-/* Write the comment, if any */
+#ifdef ZIP64_SUPPORT /* zip64 support 09/05/2003 R.Nausedat */
+ ush vem; /* version made by */
+ int iNeedZip64 = 0;
+
+ char *block = NULL; /* mem block to write to */
+ extent offset = 0; /* offset into block */
+ extent blocksize = 0; /* size of block */
+
+ /* we have to create a zip64 archive if we have more than 64k - 1 entries, */
+ /* if the CD is > 4 GB or if the offset to the CD > 4 GB. even if the CD start */
+ /* is < 4 GB and CD start + CD size > 4GB we do not need a zip64 archive since */
+ /* the offset entry in the CD tail is still valid. [note that there are other */
+ /* reasons for needing a Zip64 archive though, such as an uncompressed */
+ /* size > 4 GB for an entry but the entry compresses below 4 GB, so the archive */
+ /* is Zip64 but the CD does not need Zip64.] */
+ /* order of the zip/zip64 records in a zip64 archive: */
+ /* central directory */
+ /* zip64 end of central directory record */
+ /* zip64 end of central directory locator */
+ /* end of central directory record */
+
+ /* check zip64_archive instead of force_zip64 3/19/05 */
+
+ zip64_eocd_disk = current_disk;
+ zip64_eocd_offset = bytes_this_split;
+
+ if( n > ZIP_UWORD16_MAX || s > ZIP_UWORD32_MAX || c > ZIP_UWORD32_MAX ||
+ zip64_archive )
+ {
+ ++iNeedZip64;
+ /* write zip64 central dir tail: */
+ /* */
+ /* 4 bytes zip64 end of central dir signature (0x06064b50) */
+ append_ulong_to_mem((ulg)ZIP64_CENTRAL_DIR_TAIL_SIG, &block, &offset, &blocksize);
+ /* 8 bytes size of zip64 end of central directory record */
+ /* a fixed size unless the end zip64 extensible data sector is used. - 3/19/05 EG */
+ /* also note that AppNote 6.2 creates version 2 of this record for
+ central directory encryption - 3/19/05 EG */
+ append_int64_to_mem((zoff_t)ZIP64_CENTRAL_DIR_TAIL_SIZE, &block, &offset, &blocksize);
+
+ /* 2 bytes version made by */
+ vem = OS_CODE + Z_MAJORVER * 10 + Z_MINORVER;
+ append_ushort_to_mem(vem, &block, &offset, &blocksize);
+
+ /* APPNOTE says that zip64 archives should have at least version 4.5
+ in the "version needed to extract" field */
+ /* 2 bytes version needed to extract */
+ append_ushort_to_mem(ZIP64_MIN_VER, &block, &offset, &blocksize);
+
+ /* 4 bytes number of this disk */
+ append_ulong_to_mem(current_disk, &block, &offset, &blocksize);
+ /* 4 bytes number of the disk with the start of the central directory */
+ append_ulong_to_mem(cd_start_disk, &block, &offset, &blocksize);
+ /* 8 bytes total number of entries in the central directory on this disk */
+ append_int64_to_mem(cd_entries_this_disk, &block, &offset, &blocksize);
+ /* 8 bytes total number of entries in the central directory */
+ append_int64_to_mem(n, &block, &offset, &blocksize);
+ /* 8 bytes size of the central directory */
+ append_int64_to_mem(s, &block, &offset, &blocksize);
+ /* 8 bytes offset of start of central directory with respect to the starting disk number */
+ append_int64_to_mem(cd_start_offset, &block, &offset, &blocksize);
+ /* zip64 extensible data sector (variable size), we don't use it... */
+
+ /* write zip64 end of central directory locator: */
+ /* */
+ /* 4 bytes zip64 end of central dir locator signature (0x07064b50) */
+ append_ulong_to_mem(ZIP64_CENTRAL_DIR_TAIL_END_SIG, &block, &offset, &blocksize);
+ /* 4 bytes number of the disk with the start of the zip64 end of central directory */
+ append_ulong_to_mem(zip64_eocd_disk, &block, &offset, &blocksize);
+ /* 8 bytes relative offset of the zip64 end of central directory record, that is */
+ /* offset of CD + CD size */
+ append_int64_to_mem(zip64_eocd_offset, &block, &offset, &blocksize);
+ /* PUTLLG(l64Temp, f); */
+ /* 4 bytes total number of disks */
+ append_ulong_to_mem(current_disk + 1, &block, &offset, &blocksize);
+ }
+
+ /* end of central dir signature */
+ append_ulong_to_mem(ENDSIG, &block, &offset, &blocksize);
+ /* mv archives to come :) */
+ /* for now use n for all */
+ /* 2 bytes number of this disk */
+ if (current_disk < 0xFFFF)
+ append_ushort_to_mem((ush)current_disk, &block, &offset, &blocksize);
+ else
+ append_ushort_to_mem((ush)0xFFFF, &block, &offset, &blocksize);
+ /* 2 bytes number of the disk with the start of the central directory */
+ if (cd_start_disk == (ulg)-1)
+ cd_start_disk = 0;
+ if (cd_start_disk < 0xFFFF)
+ append_ushort_to_mem((ush)cd_start_disk, &block, &offset, &blocksize);
+ else
+ append_ushort_to_mem((ush)0xFFFF, &block, &offset, &blocksize);
+ /* 2 bytes total number of entries in the central directory on this disk */
+ if (cd_entries_this_disk < 0xFFFF)
+ append_ushort_to_mem((ush)cd_entries_this_disk, &block, &offset, &blocksize);
+ else
+ append_ushort_to_mem((ush)0xFFFF, &block, &offset, &blocksize);
+ /* 2 bytes total number of entries in the central directory */
+ if (total_cd_entries < 0xFFFF)
+ append_ushort_to_mem((ush)total_cd_entries, &block, &offset, &blocksize);
+ else
+ append_ushort_to_mem((ush)0xFFFF, &block, &offset, &blocksize);
+ if( s > ZIP_UWORD32_MAX )
+ /* instead of s */
+ append_ulong_to_mem(ZIP_UWORD32_MAX, &block, &offset, &blocksize);
+ else
+ /* 4 bytes size of the central directory */
+ append_ulong_to_mem((ulg)s, &block, &offset, &blocksize);
+ if(force_zip64 == 1 || cd_start_offset > ZIP_UWORD32_MAX)
+ /* instead of cd_start_offset */
+ append_ulong_to_mem(ZIP_UWORD32_MAX, &block, &offset, &blocksize);
+ else
+ /* 4 bytes offset of start of central directory with respect to the starting disk number */
+ append_ulong_to_mem((ulg)cd_start_offset, &block, &offset, &blocksize);
+
+#else /* !ZIP64_SUPPORT */
+ char *block = NULL; /* mem block to write to */
+ extent offset = 0; /* offset into block */
+ extent blocksize = 0; /* size of block */
+
+ /* end of central dir signature */
+ append_ulong_to_mem(ENDSIG, &block, &offset, &blocksize);
+ /* 2 bytes number of this disk */
+ append_ushort_to_mem((ush)current_disk, &block, &offset, &blocksize);
+ /* 2 bytes number of the disk with the start of the central directory */
+ append_ushort_to_mem((ush)cd_start_disk, &block, &offset, &blocksize);
+ /* 2 bytes total number of entries in the central directory on this disk */
+ append_ushort_to_mem((ush)cd_entries_this_disk, &block, &offset, &blocksize);
+ /* 2 bytes total number of entries in the central directory */
+ append_ushort_to_mem((ush)n, &block, &offset, &blocksize);
+ /* 4 bytes size of the central directory */
+ append_ulong_to_mem((ulg)s, &block, &offset, &blocksize);
+ /* 4 bytes offset of start of central directory with respect to the starting disk number */
+ append_ulong_to_mem((ulg)cd_start_offset, &block, &offset, &blocksize);
+#endif /* ZIP64_SUPPORT */
+
+ /* size of comment */
+ append_ushort_to_mem((ush)m, &block, &offset, &blocksize);
+ /* Write the comment, if any */
#ifdef EBCDIC
memtoasc(z, z, m);
#endif
- if (m && fwrite(z, 1, m, f) != m)
+ if (m) {
+ /* PKWare defines the archive comment to be ASCII only so no OEM conversion */
+ append_string_to_mem(z, m, &block, &offset, &blocksize);
+ }
+
+ /* write the block */
+ if (bfwrite(block, 1, offset, BFWRITE_HEADER) != offset) {
+ free(block);
return ZE_TEMP;
+ }
+ free(block);
#ifdef HANDLE_AMIGA_SFX
if (amiga_sfx_offset && zipbeg /* -J zeroes this */) {
- s = ftell(f);
+ s = zftello(y);
while (s & 3) s++, putc(0, f); /* final marker must be longword aligned */
PUTLG(0xF2030000 /* 1010 in Motorola byte order */, f);
c = (s - amiga_sfx_offset - 4) / 4; /* size of archive part in longwords */
- if (fseek(f, amiga_sfx_offset, SEEK_SET) != 0)
+ if (zfseeko(y, amiga_sfx_offset, SEEK_SET) != 0)
return ZE_TEMP;
c = ((c >> 24) & 0xFF) | ((c >> 8) & 0xFF00)
| ((c & 0xFF00) << 8) | ((c & 0xFF) << 24); /* invert byte order */
- PUTLG(c, f);
- fseek(f, 0, SEEK_END); /* just in case */
+ PUTLG(c, y);
+ zfseeko(y, 0, SEEK_END); /* just in case */
}
#endif
+
return ZE_OK;
-}
+} /* end function putend() */
+
/* Note: a zip "entry" includes a local header (which includes the file
name), an encryption header if encrypting, the compressed data
and possibly an extended local header. */
-int zipcopy(z, x, y)
-struct zlist far *z; /* zip entry to copy */
-FILE *x, *y; /* source and destination files */
-/* Copy the zip entry described by *z from file *x to file *y. Return an
+int zipcopy(z)
+ struct zlist far *z; /* zip entry to copy */
+/* Copy the zip entry described by *z from in_file to y. Return an
error code in the ZE_ class. Also update tempzn by the number of bytes
copied. */
+/* Now copies to global output file y */
+/* Handle entries that span disks */
+/* If fix == 2, assume in_file is pointing to a local header and fill
+ in z from local header */
{
- ulg n; /* holds local header offset */
+ uzoff_t n; /* holds local header offset */
+ ulg e = 0; /* extended local header size */
+ ulg start_disk = 0;
+ uzoff_t start_offset = 0;
+ char *split_path;
+ char buf[LOCHEAD + 1];
+ struct zlist far *localz;
+ int r;
+
Trace((stderr, "zipcopy %s\n", z->zname));
- n = (ulg)(4 + LOCHEAD) + (ulg)z->nam + (ulg)z->ext;
+ /* if fix == 2 assume in_file open and pointing at local header */
+ if (fix != 2) {
+ start_disk = z->dsk;
+ start_offset = z->off;
+
+ /* don't assume reading the right disk */
+
+ /* if start not on current disk then close current disk */
+ if (start_disk != current_in_disk) {
+ if (in_file) {
+ fclose(in_file);
+ in_file = NULL;
+ }
+ }
+
+ current_in_disk = start_disk;
+
+ /* disks are archive.z01, archive.z02, ..., archive.zip */
+ split_path = get_in_split_path(in_path, current_in_disk);
+
+ if (in_file == NULL) {
+ while ((in_file = zfopen(split_path, FOPR)) == NULL) {
+ /* could not open split */
+
+ if (!noisy) {
+ ZIPERR(ZE_OPEN, split_path);
+ }
+
+ /* Ask for directory with split. Updates global in_path */
+ r = ask_for_split_read_path(start_disk);
+ if (r == ZE_ABORT) {
+ /* user abort */
+ return ZE_ABORT;
+ } else if ((fix == 1 || fix == 2) && r == ZE_FORM) {
+ /* user asks to skip this disk */
+ return ZE_FORM;
+ }
+ free(split_path);
+ split_path = get_in_split_path(in_path, start_disk);
+ }
+ }
+
+ if (zfseeko(in_file, start_offset, SEEK_SET) != 0) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("reading archive fseek: ", strerror(errno));
+ return ZE_READ;
+ }
+ } /* fix != 2 */
+
+ if (fix != 2 && !at_signature(in_file, "PK\03\04")) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("Did not find entry for ", z->iname);
+ return ZE_FORM;
+ }
+
+ /* read local header */
+ if (fread(buf, LOCHEAD, 1, in_file) != 1) {
+ int f = ferror(in_file);
+ zipwarn("reading local entry: ", strerror(errno));
+ if (fix != 2)
+ fclose(in_file);
+ return f ? ZE_READ : ZE_EOF;
+ }
+
+ /* Local Header
+ local file header signature 4 bytes (0x04034b50)
+ version needed to extract 2 bytes
+ general purpose bit flag 2 bytes
+ compression method 2 bytes
+ last mod file time 2 bytes
+ last mod file date 2 bytes
+ crc-32 4 bytes
+ compressed size 4 bytes
+ uncompressed size 4 bytes
+ file name length 2 bytes
+ extra field length 2 bytes
+
+ file name (variable size)
+ extra field (variable size)
+ */
+
+ if ((localz = (struct zlist far *)farmalloc(sizeof(struct zlist))) == NULL) {
+ zipwarn("reading entry", "");
+ if (fix != 2)
+ fclose(in_file);
+ return ZE_MEM;
+ }
+
+ localz->ver = SH(LOCVER + buf);
+ localz->lflg = SH(LOCFLG + buf);
+ localz->how = SH(LOCHOW + buf);
+ localz->tim = LG(LOCTIM + buf); /* time and date into one long */
+ localz->crc = LG(LOCCRC + buf);
+ localz->nam = SH(LOCNAM + buf);
+ localz->ext = SH(LOCEXT + buf);
+ if (fix == 2) {
+ localz->siz = LG(LOCSIZ + buf);
+ localz->len = LG(LOCLEN + buf);
+ }
+
+ if (fix == 2) {
+ /* Do some sanity checks to make reasonably sure this is a local header */
+ ush os = localz->ver >> 8;
+ ush pkver = localz->ver - os;
+
+ /* OS - currently 0 - 18 (AppNote 6.3) and 30 (ATHEOS) */
+ if (os > 40) {
+ sprintf(errbuf, "Illegal host system mapping in local header: %d", os);
+ zipwarn(errbuf, "");
+ zipwarn("Skipping: ", z->iname);
+ return ZE_FORM;
+ }
+ /* PK Version - currently 10 - 62 (AppNote 6.2.2) */
+ /* If PKZip central directory encryption is used (62), the local header
+ values could be masked values. Specifically, as of AppNote 6.2.2
+ the time, crc-32, and uncompressed file size are masked and the
+ file name is also replaced with a hex entry count. Should
+ still be able to recover the entries, but they may be unreadable
+ without the 62 support fields. */
+ if (pkver > 100) {
+ sprintf(errbuf, "Illegal PK version mapping in local header: %d", pkver);
+ zipwarn(errbuf, "");
+ zipwarn("Skipping: ", z->iname);
+ return ZE_FORM;
+ }
+ /* Currently compression method is defined as 0 - 19 and 98 (AppNote 6.3) */
+ /* We can still copy an entry we can't read, but something over 200 is
+ probably illegal */
+ if (localz->how > 200) {
+ sprintf(errbuf, "Unrecognized compression method in local header: %d", localz->how);
+ zipwarn(errbuf, "");
+ zipwarn("Skipping: ", z->iname);
+ return ZE_FORM;
+ }
+
+ /* It's hard to make guesses on the other fields. Suggestions welcome. */
+ }
+
+ /* Initialize all fields pointing to malloced data to NULL */
+ localz->zname = localz->name = localz->iname = localz->extra = NULL;
+ localz->oname = NULL;
+#ifdef UNICODE_SUPPORT
+ localz->uname = NULL;
+#endif
+
+ /* Read file name, extra field and comment field */
+ if ((localz->iname = malloc(localz->nam+1)) == NULL ||
+ (localz->ext && (localz->extra = malloc(localz->ext)) == NULL))
+ return ZE_MEM;
+ if (fread(localz->iname, localz->nam, 1, in_file) != 1 ||
+ (localz->ext && fread(localz->extra, localz->ext, 1, in_file) != 1))
+ return ferror(in_file) ? ZE_READ : ZE_EOF;
+ localz->iname[localz->nam] = '\0'; /* terminate name */
+ if ((localz->name = malloc(localz->nam+1)) == NULL)
+ return ZE_MEM;
+ strcpy(localz->name, localz->iname);
+
+#ifdef ZIP64_SUPPORT
+ zip64_entry = adjust_zip_local_entry(localz);
+#endif
+
+ localz->vem = 0;
+ if (fix != 2) {
+ /* Need vem to determine if iname is Win32 OEM name */
+ localz->vem = z->vem;
+
+#ifdef UNICODE_SUPPORT
+ if (unicode_mismatch != 3) {
+ if (z->flg & UTF8_BIT) {
+ char *iname;
+ /* path is UTF-8 */
+ localz->uname = localz->iname;
+ iname = utf8_to_local_string(localz->uname);
+ if (iname == NULL) {
+ /* a bad UTF-8 character in name likely - go with (probably messed up) uname */
+ if ((localz->iname = malloc(strlen(localz->uname) + 1)) == NULL) {
+ return ZE_MEM;
+ }
+ strcpy(localz->iname, localz->uname);
+ } else {
+ /* go with local character set iname */
+ localz->iname = iname;
+ }
+ } else {
+ /* check for UTF-8 path extra field */
+ read_Unicode_Path_local_entry(localz);
+ }
+ }
+#endif
+
+#ifdef WIN32_OEM
+ /* If fix == 2 and reading local headers first, vem is not in the local
+ header so we don't know when to do OEM translation, as the ver field
+ is set to MSDOS (0) by all unless something specific is needed.
+ However, if local header has a Unicode path extra field, we can get
+ the real file name from there. */
+ if ((z->vem & 0xff00) == 0)
+ /* assume archive name is OEM if from DOS */
+ oem_to_local_string(localz->iname, localz->iname);
+#endif
+ }
+
+ if (fix == 2) {
+# ifdef WIN32
+# ifdef UNICODE_SUPPORT
+ localz->namew = NULL;
+ localz->inamew = NULL;
+ localz->znamew = NULL;
+ z->namew = NULL;
+ z->inamew = NULL;
+ z->znamew = NULL;
+# endif
+# endif
+ /* set z from localz */
+ z->flg = localz->lflg;
+ z->len = localz->len;
+ z->siz = localz->siz;
+
+ } else {
+ /* Compare localz to z */
+ if (localz->ver != z->ver) {
+ zipwarn("Local Version Needed To Extract does not match CD: ", z->iname);
+ }
+ if (localz->lflg != z->flg) {
+ zipwarn("Local Entry Flag does not match CD: ", z->iname);
+ }
+ if (!(z->flg & 8)) {
+ if (localz->crc != z->crc) {
+ zipwarn("Local Entry CRC does not match CD: ", z->iname);
+ }
+ }
+ if (fix != 3 && strcmp(localz->iname, z->iname) != 0) {
+ zipwarn("Local Entry name does not match CD: ", z->iname);
+ }
+
+ /* as copying get uncompressed and compressed sizes from central directory */
+ localz->len = z->len;
+ localz->siz = z->siz;
+ }
+
+#if 0
if (fix > 1) {
- if (fseek(x, z->off + n, SEEK_SET)) /* seek to compressed data */
- return ferror(x) ? ZE_READ : ZE_EOF;
+ if (zfseeko(in_file, z->off + n, SEEK_SET)) /* seek to compressed data */
+ return ferror(in_file) ? ZE_READ : ZE_EOF;
if (fix > 2) {
/* Update length of entry's name, it may have been changed. This is
needed to support the ZipNote ability to rename archive entries. */
z->nam = strlen(z->iname);
- n = (ulg)(4 + LOCHEAD) + (ulg)z->nam + (ulg)z->ext;
+ n = (uzoff_t)((LOCHEAD) + (ulg)z->nam + (ulg)z->ext);
}
/* do not trust the old compressed size */
- if (putlocal(z, y) != ZE_OK)
+ if (putlocal(z, PUTLOCAL_WRITE) != ZE_OK)
return ZE_TEMP;
z->off = tempzn;
tempzn += n;
n = z->siz;
} else {
- if (fseek(x, z->off, SEEK_SET)) /* seek to local header */
- return ferror(x) ? ZE_READ : ZE_EOF;
+ if (zfseeko(in_file, z->off, SEEK_SET)) /* seek to local header */
+ return ferror(in_file) ? ZE_READ : ZE_EOF;
z->off = tempzn;
n += z->siz;
}
+#endif
+
+ /* from zipnote */
+ if (fix == 3) {
+ /* Update length of entry's name, as it may have been changed. This is
+ needed to support the ZipNote ability to rename archive entries. */
+ localz->nam = z->nam = strlen(z->iname);
+ /* update local name */
+ free(localz->iname);
+ if ((localz->iname = malloc(strlen(z->iname) + 1)) == NULL) {
+ zipwarn("out of memory in zipcopy", "");
+ return ZE_MEM;
+ }
+ strcpy(localz->iname, z->iname);
+ }
+
+ /* update disk and offset */
+ z->dsk = current_disk;
+ z->off = bytes_this_split;
+
/* copy the compressed data and the extended local header if there is one */
- if (z->lflg & 8) n += 16;
+
+ /* copy the compressed data. We recreate the local header as the local
+ header can't be split and putlocal ensures it won't. Also, since we
+ use siz and len from the central directory, we don't need the extended
+ local header if there is one, unless the file is encrypted as then the
+ extended header is used to indicate crypt head uses file time instead
+ of crc as the password check.
+
+ If fix = 2 then we don't have the central directory yet so keep
+ any data descriptors. */
+
+ if (fix != 2 && !(z->flg & 1)) {
+ /* Not encrypted */
+ localz->flg = z->flg &= ~8;
+ z->lflg = localz->lflg &= ~8;
+ }
+
+ e = 0;
+ if (z->lflg & 8) {
+#ifdef ZIP64_SUPPORT
+ if (zip64_entry)
+ e = 24;
+ else
+#endif
+ e = 16;
+ }
+ /* 4 is signature */
+ n = 4 + (uzoff_t)((LOCHEAD) + (ulg)(localz->nam) + (ulg)(localz->ext));
+
+ n += e + z->siz;
tempzn += n;
- return fcopy(x, y, n);
+
+ /* Output name */
+ if (fix == 2) {
+ if ((z->oname = malloc(strlen(localz->iname) + 1)) == NULL) {
+ return ZE_MEM;
+ }
+ strcpy(z->oname, localz->iname);
+#ifndef UTIL
+# ifdef WIN32
+ /* Win9x console always uses OEM character coding, and
+ WinNT console is set to OEM charset by default, too */
+ _INTERN_OEM(z->oname);
+# endif
+#endif
+ sprintf(errbuf, " copying: %s ", z->oname);
+ zipmessage_nl(errbuf, 0);
+ }
+
+ if (fix == 2)
+ z->crc = localz->crc;
+ else
+ localz->crc = z->crc;
+
+ if (putlocal(localz, PUTLOCAL_WRITE) != ZE_OK)
+ return ZE_TEMP;
+
+ /*
+ if (zfseeko(in_file, start_offset, SEEK_SET) != 0) {
+ fclose(in_file);
+ in_file = NULL;
+ zipwarn("reading archive fseek: ", strerror(errno));
+ return ZE_READ;
+ }
+ */
+
+ /* copy the data */
+ if (fix == 2 && localz->lflg & 8)
+ /* read to data descriptor */
+ r = bfcopy((uzoff_t) -2);
+ else
+ r = bfcopy(localz->siz);
+
+ if (r == ZE_ABORT) {
+ 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);
+ ZIPERR(ZE_ABORT, "Could not find split");
+ }
+
+ if (r == ZE_EOF || skip_this_disk) {
+ /* missing disk */
+ zipwarn("aborting: ", z->oname);
+
+ if (r == ZE_OK)
+ r = ZE_FORM;
+
+ if (fix == 2) {
+#ifdef DEBUG
+ zoff_t here = zftello(y);
+#endif
+
+ /* fix == 2 skips right to next disk */
+ skip_this_disk = 0;
+
+ /* seek back in output to start of this entry so can overwrite */
+ if (zfseeko(y, current_local_offset, SEEK_SET) != 0) {
+ ZIPERR(ZE_WRITE, "seek failed on output file");
+ }
+ bytes_this_split = current_local_offset;
+ tempzn = current_local_offset;
+ }
+
+ /* tell scan to skip this entry */
+ 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 r;
+ }
+
+ if (fix == 2 && z->flg & 8) {
+ /* this entry should have a data descriptor */
+ /* only -FF needs to read the descriptor as other modes
+ rely on the central directory */
+ if (des_good) {
+ /* found an apparently good data descriptor */
+ localz->crc = des_crc;
+ localz->siz = des_csize;
+ localz->len = des_usize;
+ } else {
+ /* no end to this entry found */
+ zipwarn("no end of stream entry found: ", z->oname);
+ zipwarn("rewinding and scanning for later entries", "");
+
+ /* seek back in output to start of this entry so can overwrite */
+ if (zfseeko(y, current_local_offset, SEEK_SET) != 0){
+
+ }
+
+ /* tell scan to skip this entry */
+ 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_FORM;
+ }
+ }
+
+ if (z->flg & 8) {
+ putextended(localz);
+ }
+
+ /* now can close the split if local header on previous split */
+ if (split_method == 1 && current_local_disk != current_disk) {
+ close_split(current_local_disk, current_local_file, current_local_tempname);
+ current_local_file = NULL;
+ free(current_local_tempname);
+ }
+
+ /* update local header and close start split */
+ /* to use this need to seek back, do this, then come back
+ if (putlocal(localz, PUTLOCAL_REWRITE) != ZE_OK)
+ r = ZE_TEMP;
+ */
+
+ if (fix == 2) {
+ z->ver = localz->ver;
+ z->how = localz->how;
+ z->tim = localz->tim;
+ z->crc = localz->crc;
+ z->lflg = localz->lflg;
+ z->flg = localz->lflg;
+ z->len = localz->len;
+ z->siz = localz->siz;
+ z->nam = localz->nam;
+ z->ext = localz->ext;
+ z->extra = localz->extra;
+ /* copy local extra fields to central directory for now */
+ z->cext = localz->ext;
+ z->cextra = NULL;
+ if (localz->ext) {
+ if ((z->cextra = malloc(localz->ext + 1)) == NULL) {
+ return ZE_MEM;
+ }
+ strcpy(z->cextra, localz->extra);
+ }
+ z->com = 0;
+ z->att = 0;
+ z->atx = 0;
+ z->name = localz->name;
+ z->iname = localz->iname;
+#ifdef UNICODE_SUPPORT
+ z->uname = localz->uname;
+#endif
+ if ((z->zname = malloc(localz->nam + 1)) == NULL) {
+ return ZE_MEM;
+ }
+ strcpy(z->zname, z->iname);
+ } else {
+ 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);
+ }
+
+ if (fix == 2) {
+ sprintf(errbuf, " (%s bytes)", zip_fzofft(z->siz, NULL, "u"));
+ zipmessage_nl(errbuf, 1);
+
+ if (r == ZE_READ) {
+ zipwarn("entry truncated: ", z->oname);
+ sprintf(errbuf, "expected compressed/stored size %s, actual %s",
+ zip_fzofft(localz->siz, NULL, "u"), zip_fzofft(bytes_this_entry, NULL, "u"));
+ zipwarn(errbuf, "");
+ }
+ }
+
+ return r;
}
+
#ifndef UTIL
#ifdef USE_EF_UT_TIME
@@ -1333,7 +6568,7 @@ iztimes *z_utim; /* return storage: atime, mtime, ctime */
return 0;
Trace((stderr,"\nef_scan_ut_time: scanning extra field of length %u\n",
- ef_len));
+ (unsigned)ef_len));
while (ef_len >= EB_HEADSIZE) {
eb_id = SH(EB_ID + ef_buf);
eb_len = SH(EB_LEN + ef_buf);
@@ -1341,7 +6576,7 @@ iztimes *z_utim; /* return storage: atime, mtime, ctime */
if (eb_len > (ef_len - EB_HEADSIZE)) {
/* Discovered some extra field inconsistency! */
Trace((stderr,"ef_scan_ut_time: block length %u > rest ef_size %u\n",
- eb_len, ef_len - EB_HEADSIZE));
+ (unsigned)eb_len, (unsigned)(ef_len - EB_HEADSIZE)));
break;
}
@@ -1508,6 +6743,26 @@ int trash()
*/
if (!dirnames) {
cutpath(z->name, '/'); /* XXX wrong ??? */
+ /* Below apparently does not work for Russian OEM but
+ '/' should be same as 0x2f for ascii and most ports so
+ changed it. Did not trace through the mappings but
+ maybe 0x2F is mapped differently on OEM_RUSS - EG 2/28/2003 */
+ /* CS, 5/14/2005: iname is the byte array read from and written
+ to the zip archive; it MUST be ASCII (compatible)!!!
+ If something goes wrong with OEM_RUSS, there is a charcode
+ mapping error between external name (z->name) and iname somewhere
+ in the in2ex & ex2in code. The charcode translation should be
+ checked.
+ This code line is changed back to the original code. */
+ /* CS, 6/12/2005: What is handled here is the difference between
+ ASCII charsets and non-ASCII charsets like the family of EBCDIC
+ charsets. On these systems, the slash character '/' is not coded
+ as 0x2f but as 0x61 (the ASCII 'a'). The iname struct member holds
+ the name as stored in the Zip file, which are ASCII or translated
+ into ASCII for new entries, whereas the "name" struct member hold
+ the external name, coded in the native charset of the system
+ (EBCDIC on EBCDIC systems) */
+ /* cutpath(z->iname, '/'); */ /* QQQ ??? */
cutpath(z->iname, 0x2f); /* 0x2f = ascii['/'] */
z->nam = strlen(z->iname);
if (z->nam > 0) {
diff --git a/zipnote.c b/zipnote.c
index 963fe3d..5e02cb6 100644
--- a/zipnote.c
+++ b/zipnote.c
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ zipnote.c - Zip 3
- See the accompanying file LICENSE, version 2005-Feb-10 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*
@@ -32,8 +34,7 @@
#define MARKE " (comment above this line)"
#define MARKZ " (zip file comment below this line)"
-/* Temporary zip file name and file pointer */
-local char *tempzip;
+/* Temporary zip file pointer */
local FILE *tempzf;
@@ -44,10 +45,18 @@ local void help OF((void));
local void version_info OF((void));
local void putclean OF((char *, extent));
/* getline name conflicts with GNU getline() function */
-local char *_getline OF((char *, extent));
+local char *zgetline OF((char *, extent));
local int catalloc OF((char * far *, char *));
int main OF((int, char **));
+/* keep compiler happy until implement long options - 11/4/2003 EG */
+struct option_struct far options[] = {
+ /* short longopt value_type negatable ID name */
+ {"h", "help", o_NO_VALUE, o_NOT_NEGATABLE, 'h', "help"},
+ /* the end of the list */
+ {NULL, NULL, o_NO_VALUE, o_NOT_NEGATABLE, 0, NULL} /* end has option_ID = 0 */
+ };
+
#ifdef MACOS
#define ziperr(c, h) zipnoteerr(c, h)
#define zipwarn(a, b) zipnotewarn(a, b)
@@ -60,6 +69,87 @@ void zipnotewarn(ZCONST char *a, ZCONST char *b);
#define exit(p1) QDOSexit()
#endif
+int set_filetype(out_path)
+ char *out_path;
+{
+#ifdef __BEOS__
+ /* Set the filetype of the zipfile to "application/zip" */
+ setfiletype( out_path, "application/zip" );
+#endif
+
+#ifdef __ATHEOS__
+ /* Set the filetype of the zipfile to "application/x-zip" */
+ setfiletype(out_path, "application/x-zip");
+#endif
+
+#ifdef MACOS
+ /* Set the Creator/Type of the zipfile to 'IZip' and 'ZIP ' */
+ setfiletype(out_path, 'IZip', 'ZIP ');
+#endif
+
+#ifdef RISCOS
+ /* Set the filetype of the zipfile to &DDC */
+ setfiletype(out_path, 0xDDC);
+#endif
+ return ZE_OK;
+}
+
+/* rename a split
+ * A split has a tempfile name until it is closed, then
+ * here rename it as out_path the final name for the split.
+ */
+int rename_split(temp_name, out_path)
+ char *temp_name;
+ char *out_path;
+{
+ int r;
+ /* Replace old zip file with new zip file, leaving only the new one */
+ if ((r = replace(out_path, temp_name)) != ZE_OK)
+ {
+ zipwarn("new zip file left as: ", temp_name);
+ free((zvoid *)tempzip);
+ tempzip = NULL;
+ ZIPERR(r, "was replacing split file");
+ }
+ if (zip_attributes) {
+ setfileattr(out_path, zip_attributes);
+ }
+ return ZE_OK;
+}
+
+void zipmessage_nl(a, nl)
+ZCONST char *a; /* message string to output */
+int nl; /* 1 = add nl to end */
+/* If nl false, print a message to mesg without new line.
+ If nl true, print and add new line. If logfile is
+ open then also write message to log file. */
+{
+ if (noisy) {
+ fprintf(mesg, "%s", a);
+ if (nl) {
+ fprintf(mesg, "\n");
+ mesg_line_started = 0;
+ } else {
+ mesg_line_started = 1;
+ }
+ fflush(mesg);
+ }
+}
+
+void zipmessage(a, b)
+ZCONST char *a, *b; /* message strings juxtaposed in output */
+/* Print a message to mesg and flush. Also write to log file if
+ open. Write new line first if current line has output already. */
+{
+ if (noisy) {
+ if (mesg_line_started)
+ fprintf(mesg, "\n");
+ fprintf(mesg, "%s%s\n", a, b);
+ mesg_line_started = 0;
+ fflush(mesg);
+ }
+}
+
void ziperr(c, h)
int c; /* error code from the ZE_ class */
ZCONST char *h; /* message about how it happened */
@@ -67,7 +157,7 @@ ZCONST char *h; /* message about how it happened */
{
if (PERR(c))
perror("zipnote error");
- fprintf(stderr, "zipnote error: %s (%s)\n", ziperrors[c-1], h);
+ fprintf(mesg, "zipnote error: %s (%s)\n", ZIPERRORS(c), h);
if (tempzf != NULL)
fclose(tempzf);
if (tempzip != NULL)
@@ -86,7 +176,7 @@ int s; /* signal number (ignored) */
/* Upon getting a user interrupt, abort cleanly using ziperr(). */
{
#ifndef MSDOS
- putc('\n', stderr);
+ putc('\n', mesg);
#endif /* !MSDOS */
ziperr(ZE_ABORT, "aborting");
s++; /* keep some compilers happy */
@@ -95,9 +185,9 @@ int s; /* signal number (ignored) */
void zipwarn(a, b)
ZCONST char *a, *b; /* message strings juxtaposed in output */
-/* Print a warning message to stderr and return. */
+/* Print a warning message to mesg (usually stderr) and return. */
{
- fprintf(stderr, "zipnote warning: %s%s\n", a, b);
+ fprintf(mesg, "zipnote warning: %s%s\n", a, b);
}
@@ -121,9 +211,9 @@ local void help()
"",
"ZipNote %s (%s)",
#ifdef VM_CMS
-"Usage: zipnote [-w] [-b fm] zipfile",
+"Usage: zipnote [-w] [-q] [-b fm] zipfile",
#else
-"Usage: zipnote [-w] [-b path] zipfile",
+"Usage: zipnote [-w] [-q] [-b path] zipfile",
#endif
" the default action is to write the comments in zipfile to stdout",
" -w write the zipfile comments from stdin",
@@ -132,6 +222,7 @@ local void help()
#else
" -b use \"path\" for the temporary zip file",
#endif
+" -q quieter operation, suppress some informational messages",
" -h show this help -v show version info -L show software license",
"",
"Example:",
@@ -244,7 +335,7 @@ extent n; /* length of string */
}
-local char *_getline(buf, size)
+local char *zgetline(buf, size)
char *buf;
extent size;
/* Read a line of text from stdin into string buffer 'buf' of size 'size'.
@@ -298,28 +389,67 @@ int argc; /* number of tokens in command line */
char **argv; /* command line tokens */
/* Write the comments in the zipfile to stdout, or read them from stdin. */
{
- char a[WRBUFSIZ+1]; /* input line buffer */
- ulg c; /* start of central directory */
+ char abf[WRBUFSIZ+1]; /* input line buffer */
+ char *a; /* pointer to line buffer or NULL */
+ zoff_t c; /* start of central directory */
int k; /* next argument type */
char *q; /* steps through option arguments */
int r; /* arg counter, temporary variable */
- ulg s; /* length of central directory */
+ zoff_t s; /* length of central directory */
int t; /* attributes of zip file */
int w; /* true if updating zip file from stdin */
- FILE *x, *y; /* input and output zip files */
+ FILE *x; /* input file for testing if can write it */
struct zlist far *z; /* steps through zfiles linked list */
#ifdef THEOS
setlocale(LC_CTYPE, "I");
#endif
+#ifdef UNICODE_SUPPORT
+# ifdef UNIX
+ /* For Unix, set the locale to UTF-8. Any UTF-8 locale is
+ OK and they should all be the same. This allows seeing,
+ writing, and displaying (if the fonts are loaded) all
+ characters in UTF-8. */
+ {
+ char *loc;
+
+ /*
+ loc = setlocale(LC_CTYPE, NULL);
+ printf(" Initial language locale = '%s'\n", loc);
+ */
+
+ loc = setlocale(LC_CTYPE, "en_US.UTF-8");
+
+ /*
+ printf("langinfo %s\n", nl_langinfo(CODESET));
+ */
+
+ if (loc != NULL) {
+ /* using UTF-8 character set so can set UTF-8 GPBF bit 11 */
+ using_utf8 = 1;
+ /*
+ printf(" Locale set to %s\n", loc);
+ */
+ } else {
+ /*
+ printf(" Could not set Unicode UTF-8 locale\n");
+ */
+ }
+ }
+# endif
+#endif
+
/* If no args, show help */
if (argc == 1)
{
help();
- EXIT(0);
+ EXIT(ZE_OK);
}
+ /* Direct info messages to stderr; stdout is used for data output. */
+ mesg = stderr;
+
init_upper(); /* build case map table */
/* Go through args */
@@ -329,6 +459,21 @@ char **argv; /* command line tokens */
#ifdef SIGTERM /* AMIGA has no SIGTERM */
signal(SIGTERM, handler);
#endif
+#ifdef SIGABRT
+ signal(SIGABRT, handler);
+#endif
+#ifdef SIGBREAK
+ signal(SIGBREAK, handler);
+#endif
+#ifdef SIGBUS
+ signal(SIGBUS, handler);
+#endif
+#ifdef SIGILL
+ signal(SIGILL, handler);
+#endif
+#ifdef SIGSEGV
+ signal(SIGSEGV, handler);
+#endif
k = w = 0;
for (r = 1; r < argc; r++)
if (*argv[r] == '-') {
@@ -343,11 +488,13 @@ char **argv; /* command line tokens */
k = 1; /* Next non-option is path */
break;
case 'h': /* Show help */
- help(); EXIT(0);
+ help(); EXIT(ZE_OK);
case 'l': case 'L': /* Show copyright and disclaimer */
- license(); EXIT(0);
+ license(); EXIT(ZE_OK);
+ case 'q': /* Quiet operation, suppress info messages */
+ noisy = 0; break;
case 'v': /* Show version info */
- version_info(); EXIT(0);
+ version_info(); EXIT(ZE_OK);
case 'w':
w = 1; break;
default:
@@ -374,6 +521,11 @@ char **argv; /* command line tokens */
if (zipfile == NULL)
ziperr(ZE_PARMS, "need to specify zip file");
+ if ((in_path = malloc(strlen(zipfile) + 1)) == NULL) {
+ ziperr(ZE_MEM, "input");
+ }
+ strcpy(in_path, zipfile);
+
/* Read zip file */
if ((r = readzipfile()) != ZE_OK)
ziperr(r, zipfile);
@@ -402,7 +554,7 @@ char **argv; /* command line tokens */
/* Process stdin, replacing comments */
z = zfiles;
- while (_getline(a, WRBUFSIZ+1) != NULL &&
+ while ((a = zgetline(abf, WRBUFSIZ+1)) != NULL &&
(a[0] != MARK || strcmp(a + 1, MARKZ)))
{ /* while input and not file comment */
if (a[0] != MARK || a[1] != ' ') /* better be "@ name" */
@@ -411,7 +563,7 @@ char **argv; /* command line tokens */
z = z->nxt; /* allow missing entries in order */
if (z == NULL)
ziperr(ZE_NOTE, "unknown entry name");
- if (_getline(a, WRBUFSIZ+1) != NULL && a[0] == MARK && a[1] == '=')
+ if ((a = zgetline(abf, WRBUFSIZ+1)) != NULL && a[0] == MARK && a[1] == '=')
{
if (z->name != z->iname)
free((zvoid *)z->iname);
@@ -427,7 +579,7 @@ char **argv; /* command line tokens */
* Don't update z->nam here, we need the old value a little later.....
* The update is handled in zipcopy().
*/
- _getline(a, WRBUFSIZ+1);
+ a = zgetline(abf, WRBUFSIZ+1);
}
if (z->com) /* change zip entry comment */
free((zvoid *)z->comment);
@@ -435,8 +587,8 @@ char **argv; /* command line tokens */
while (a != NULL && *a != MARK)
{
if ((r = catalloc(&(z->comment), a)) != ZE_OK)
- ziperr(r, "was building new comments");
- _getline(a, WRBUFSIZ+1);
+ ziperr(r, "was building new zipentry comments");
+ a = zgetline(abf, WRBUFSIZ+1);
}
z->com = strlen(z->comment);
z = z->nxt; /* point to next entry */
@@ -444,41 +596,83 @@ char **argv; /* command line tokens */
if (a != NULL) /* change zip file comment */
{
zcomment = malloc(1); *zcomment = 0;
- while (_getline(a, WRBUFSIZ+1) != NULL)
+ while ((a = zgetline(abf, WRBUFSIZ+1)) != NULL)
if ((r = catalloc(&zcomment, a)) != ZE_OK)
- ziperr(r, "was building new comments");
+ ziperr(r, "was building new zipfile comment");
zcomlen = strlen(zcomment);
}
/* Open output zip file for writing */
+#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 ((tempzf = y = fdopen(yd, FOPW)) == NULL) {
+ ZIPERR(ZE_TEMP, tempzip);
+ }
+ }
+#else
if ((tempzf = y = fopen(tempzip = tempname(zipfile), FOPW)) == NULL)
ziperr(ZE_TEMP, tempzip);
+#endif
/* Open input zip file again, copy preamble if any */
- if ((x = fopen(zipfile, FOPR)) == NULL)
+ if ((in_file = fopen(zipfile, FOPR)) == NULL)
ziperr(ZE_NAME, zipfile);
- if (zipbeg && (r = fcopy(x, y, zipbeg)) != ZE_OK)
+
+ if (zipbeg && (r = bfcopy(zipbeg)) != ZE_OK)
ziperr(r, r == ZE_TEMP ? tempzip : zipfile);
tempzn = zipbeg;
/* Go through local entries, copying them over as is */
fix = 3; /* needed for zipcopy if name changed */
for (z = zfiles; z != NULL; z = z->nxt) {
- if ((r = zipcopy(z, x, y)) != ZE_OK)
+ if ((r = zipcopy(z)) != ZE_OK)
ziperr(r, "was copying an entry");
}
fclose(x);
/* Write central directory and end of central directory with new comments */
- if ((c = ftell(y)) == (ulg)(-1L)) /* get start of central */
+ if ((c = zftello(y)) == (zoff_t)-1) /* get start of central */
ziperr(ZE_TEMP, tempzip);
for (z = zfiles; z != NULL; z = z->nxt)
- if ((r = putcentral(z, y)) != ZE_OK)
+ if ((r = putcentral(z)) != ZE_OK)
ziperr(r, tempzip);
- if ((s = ftell(y)) == (ulg)-1L) /* get end of central */
+ if ((s = zftello(y)) == (zoff_t)-1) /* get end of central */
ziperr(ZE_TEMP, tempzip);
s -= c; /* compute length of central */
- if ((r = putend((int)zcount, s, c, zcomlen, zcomment, y)) != ZE_OK)
+ if ((r = putend((zoff_t)zcount, s, c, zcomlen, zcomment)) != ZE_OK)
ziperr(r, tempzip);
tempzf = NULL;
if (fclose(y))
diff --git a/zipnote.txt b/zipnote.txt
new file mode 100644
index 0000000..cbafd28
--- /dev/null
+++ b/zipnote.txt
@@ -0,0 +1,63 @@
+zipnote(1) zipnote(1)
+
+NAME
+ zipnote - write the comments in zipfile to stdout, edit comments and
+ rename files in zipfile
+
+SYNOPSIS
+ zipnote [-w] [-b path] [-h] [-v] [-L] zipfile
+
+ARGUMENTS
+ zipfile Zipfile to read comments from or edit.
+
+OPTIONS
+ -w Write comments to a zipfile from stdin (see below).
+
+ -b path
+ Use path for the temporary zip file.
+
+ -h Show a short help.
+
+ -v Show version information.
+
+ -L Show software license.
+
+DESCRIPTION
+ 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.
+
+EXAMPLES
+ To write all comments in a zipfile to stdout use for example
+
+ zipnote foo.zip > foo.tmp
+
+ This writes all comments in the zipfile foo.zip to the file foo.tmp in
+ a specific format.
+
+ If desired, this file can then be edited to change the comments and
+ then used to update the zipfile.
+
+ zipnote -w foo.zip < foo.tmp
+
+ The names of the files in the zipfile can also be changed in this way.
+ This is done by following lines like
+ "@ name"
+ in the created temporary file (called foo.tmp here) with lines like
+ "@=newname"
+ and then using the -w option as above.
+
+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.
+
+SEE ALSO
+ zip(1), unzip(1)
+
+AUTHOR
+ Info-ZIP
+
+ v3.0 of 8 May 2008 zipnote(1)
diff --git a/zipsplit.c b/zipsplit.c
index da38705..8db76a1 100644
--- a/zipsplit.c
+++ b/zipsplit.c
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ zipsplit.c - Zip 3
- See the accompanying file LICENSE, version 2005-Feb-10 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*
@@ -67,9 +69,9 @@ local void handler OF((int));
local void license OF((void));
local void help OF((void));
local void version_info OF((void));
-local extent simple OF((ulg *, extent, ulg, ulg));
+local extent simple OF((uzoff_t *, extent, uzoff_t, uzoff_t));
local int descmp OF((ZCONST zvoid *, ZCONST zvoid *));
-local extent greedy OF((ulg *, extent, ulg, ulg));
+local extent greedy OF((uzoff_t *, extent, uzoff_t, uzoff_t));
local int retry OF((void));
int main OF((int, char **));
@@ -91,6 +93,93 @@ zvoid *talls[TMAX]; /* malloc'ed pointers to track */
int talln = 0; /* number of entries in talls[] */
+int set_filetype(out_path)
+ char *out_path;
+{
+#ifdef __BEOS__
+ /* Set the filetype of the zipfile to "application/zip" */
+ setfiletype( out_path, "application/zip" );
+#endif
+
+#ifdef __ATHEOS__
+ /* Set the filetype of the zipfile to "application/x-zip" */
+ setfiletype(out_path, "application/x-zip");
+#endif
+
+#ifdef MACOS
+ /* Set the Creator/Type of the zipfile to 'IZip' and 'ZIP ' */
+ setfiletype(out_path, 'IZip', 'ZIP ');
+#endif
+
+#ifdef RISCOS
+ /* Set the filetype of the zipfile to &DDC */
+ setfiletype(out_path, 0xDDC);
+#endif
+ return ZE_OK;
+}
+
+/* rename a split
+ * A split has a tempfile name until it is closed, then
+ * here rename it as out_path the final name for the split.
+ *
+ * This is not used in zipsplit but is referenced by the generic split
+ * writing code. If zipsplit is made split aware (so can write splits of
+ * splits, if that makes sense) then this would get used. But if that
+ * happens these utility versions should be dropped and the main ones
+ * used.
+ */
+int rename_split(temp_name, out_path)
+ char *temp_name;
+ char *out_path;
+{
+ int r;
+ /* Replace old zip file with new zip file, leaving only the new one */
+ if ((r = replace(out_path, temp_name)) != ZE_OK)
+ {
+ zipwarn("new zip file left as: ", temp_name);
+ free((zvoid *)tempzip);
+ tempzip = NULL;
+ ZIPERR(r, "was replacing split file");
+ }
+ if (zip_attributes) {
+ setfileattr(out_path, zip_attributes);
+ }
+ return ZE_OK;
+}
+
+void zipmessage_nl(a, nl)
+ZCONST char *a; /* message string to output */
+int nl; /* 1 = add nl to end */
+/* If nl false, print a message to mesg without new line.
+ If nl true, print and add new line. If logfile is
+ open then also write message to log file. */
+{
+ if (noisy) {
+ fprintf(mesg, "%s", a);
+ if (nl) {
+ fprintf(mesg, "\n");
+ mesg_line_started = 0;
+ } else {
+ mesg_line_started = 1;
+ }
+ fflush(mesg);
+ }
+}
+
+void zipmessage(a, b)
+ZCONST char *a, *b; /* message strings juxtaposed in output */
+/* Print a message to mesg and flush. Also write to log file if
+ open. Write new line first if current line has output already. */
+{
+ if (noisy) {
+ if (mesg_line_started)
+ fprintf(mesg, "\n");
+ fprintf(mesg, "%s%s\n", a, b);
+ mesg_line_started = 0;
+ fflush(mesg);
+ }
+}
+
local zvoid *talloc(s)
extent s;
/* does a malloc() and saves the pointer to free later (does not check
@@ -139,7 +228,7 @@ ZCONST char *h; /* message about how it happened */
{
if (PERR(c))
perror("zipsplit error");
- fprintf(stderr, "zipsplit error: %s (%s)\n", ziperrors[c-1], h);
+ fprintf(mesg, "zipsplit error: %s (%s)\n", ZIPERRORS(c), h);
if (indexmade)
{
strcpy(name, INDEX);
@@ -162,7 +251,7 @@ int s; /* signal number (ignored) */
/* Upon getting a user interrupt, abort cleanly using ziperr(). */
{
#ifndef MSDOS
- putc('\n', stderr);
+ putc('\n', mesg);
#endif /* !MSDOS */
ziperr(ZE_ABORT, "aborting");
s++; /* keep some compilers happy */
@@ -171,9 +260,9 @@ int s; /* signal number (ignored) */
void zipwarn(a, b)
ZCONST char *a, *b; /* message strings juxtaposed in output */
-/* Print a warning message to stderr and return. */
+/* Print a warning message to mesg (usually stderr) and return. */
{
- fprintf(stderr, "zipsplit warning: %s%s\n", a, b);
+ fprintf(mesg, "zipsplit warning: %s%s\n", a, b);
}
@@ -197,9 +286,9 @@ local void help()
"",
"ZipSplit %s (%s)",
#ifdef VM_CMS
-"Usage: zipsplit [-tips] [-n size] [-r room] [-b fm] zipfile",
+"Usage: zipsplit [-tipqs] [-n size] [-r room] [-b fm] zipfile",
#else
-"Usage: zipsplit [-tips] [-n size] [-r room] [-b path] zipfile",
+"Usage: zipsplit [-tipqs] [-n size] [-r room] [-b path] zipfile",
#endif
" -t report how many files it will take, but don't make them",
#ifdef RISCOS
@@ -214,6 +303,7 @@ local void help()
#else
" -b use \"path\" for the output zip files",
#endif
+" -q quieter operation, suppress some informational messages",
" -p pause between output zip files",
" -s do a sequential split even if it takes more zip files",
" -h show this help -v show version info -L show software license"
@@ -245,12 +335,6 @@ local void version_info()
NULL
};
- for (i = 0; i < sizeof(copyright)/sizeof(char *); i++)
- {
- printf(copyright[i], "zipsplit");
- putchar('\n');
- }
-
for (i = 0; i < sizeof(versinfolines)/sizeof(char *); i++)
{
printf(versinfolines[i], "ZipSplit", VERSION, REVDATE);
@@ -270,17 +354,17 @@ local void version_info()
local extent simple(a, n, c, d)
-ulg *a; /* items to put in bins, return value: destination bins */
+uzoff_t *a; /* items to put in bins, return value: destination bins */
extent n; /* number of items */
-ulg c; /* capacity of each bin */
-ulg d; /* amount to deduct from first bin */
+uzoff_t c; /* capacity of each bin */
+uzoff_t d; /* amount to deduct from first bin */
/* Return the number of bins of capacity c that are needed to contain the
integers in a[0..n-1] placed sequentially into the bins. The value d
is deducted initially from the first bin (space for index). The entries
in a[] are replaced by the destination bins. */
{
extent k; /* current bin number */
- ulg t; /* space used in current bin */
+ uzoff_t t; /* space used in current bin */
t = k = 0;
while (n--)
@@ -301,28 +385,29 @@ local int descmp(a, b)
ZCONST zvoid *a, *b; /* pointers to pointers to ulg's to compare */
/* Used by qsort() in greedy() to do a descending sort. */
{
- return **(ulg **)a < **(ulg **)b ? 1 : (**(ulg **)a > **(ulg **)b ? -1 : 0);
+ return **(uzoff_t **)a < **(uzoff_t **)b ? 1 :
+ (**(uzoff_t **)a > **(uzoff_t **)b ? -1 : 0);
}
local extent greedy(a, n, c, d)
-ulg *a; /* items to put in bins, return value: destination bins */
+uzoff_t *a; /* items to put in bins, return value: destination bins */
extent n; /* number of items */
-ulg c; /* capacity of each bin */
-ulg d; /* amount to deduct from first bin */
+uzoff_t c; /* capacity of each bin */
+uzoff_t d; /* amount to deduct from first bin */
/* Return the number of bins of capacity c that are needed to contain the
items with sizes a[0..n-1] placed non-sequentially into the bins. The
value d is deducted initially from the first bin (space for index).
The entries in a[] are replaced by the destination bins. */
{
- ulg *b; /* space left in each bin (malloc'ed for each m) */
- ulg *e; /* copy of argument a[] (malloc'ed) */
+ uzoff_t *b; /* space left in each bin (malloc'ed for each m) */
+ uzoff_t *e; /* copy of argument a[] (malloc'ed) */
extent i; /* steps through items */
extent j; /* steps through bins */
extent k; /* best bin to put current item in */
extent m; /* current number of bins */
- ulg **s; /* pointers to e[], sorted descending (malloc'ed) */
- ulg t; /* space left in best bin (index k) */
+ uzoff_t **s; /* pointers to e[], sorted descending (malloc'ed) */
+ uzoff_t t; /* space left in best bin (index k) */
/* Algorithm:
1. Copy a[] to e[] and sort pointers to e[0..n-1] (in s[]), in
@@ -338,15 +423,15 @@ ulg d; /* amount to deduct from first bin */
/* Copy a[] to e[], put pointers to e[] in s[], and sort s[]. Also compute
the initial number of bins (minus 1). */
- if ((e = (ulg *)malloc(n * sizeof(ulg))) == NULL ||
- (s = (ulg **)malloc(n * sizeof(ulg *))) == NULL)
+ if ((e = (uzoff_t *)malloc(n * sizeof(uzoff_t))) == NULL ||
+ (s = (uzoff_t **)malloc(n * sizeof(uzoff_t *))) == NULL)
{
if (e != NULL)
free((zvoid *)e);
ziperr(ZE_MEM, "was trying a smart split");
return 0; /* only to make compiler happy */
}
- memcpy((char *)e, (char *)a, n * sizeof(ulg));
+ memcpy((char *)e, (char *)a, n * sizeof(uzoff_t));
for (t = i = 0; i < n; i++)
t += *(s[i] = e + i);
m = (extent)((t + c - 1) / c) - 1; /* pre-decrement for loop */
@@ -355,7 +440,7 @@ ulg d; /* amount to deduct from first bin */
/* Stuff bins until successful */
do {
/* Increment the number of bins, allocate and initialize bins */
- if ((b = (ulg *)malloc(++m * sizeof(ulg))) == NULL)
+ if ((b = (uzoff_t *)malloc(++m * sizeof(uzoff_t))) == NULL)
{
free((zvoid *)s);
free((zvoid *)e);
@@ -380,7 +465,7 @@ ulg d; /* amount to deduct from first bin */
/* Diminish that bin and save where it goes */
b[k] -= *s[i];
- a[(int)((ulg huge *)(s[i]) - (ulg huge *)e)] = k;
+ a[(int)((uzoff_t huge *)(s[i]) - (uzoff_t huge *)e)] = k;
}
/* Clean up */
@@ -395,11 +480,19 @@ ulg d; /* amount to deduct from first bin */
return m;
}
+/* keep compiler happy until implement long options - 11/4/2003 EG */
+struct option_struct far options[] = {
+ /* short longopt value_type negatable ID name */
+ {"h", "help", o_NO_VALUE, o_NOT_NEGATABLE, 'h', "help"},
+ /* the end of the list */
+ {NULL, NULL, o_NO_VALUE, o_NOT_NEGATABLE, 0, NULL} /* end has option_ID = 0 */
+ };
+
local int retry()
{
char m[10];
- fputs("Error writing to disk--redo entire disk? ", stderr);
+ fputs("Error writing to disk--redo entire disk? ", mesg);
fgets(m, 10, stdin);
return *m == 'y' || *m == 'Y';
}
@@ -416,23 +509,23 @@ char **argv; /* command line tokens */
/* Split a zip file into several zip files less than a specified size. See
the command help in help() above. */
{
- ulg *a; /* malloc'ed list of sizes, dest bins */
+ uzoff_t *a; /* malloc'ed list of sizes, dest bins */
extent *b; /* heads of bin linked lists (malloc'ed) */
- ulg c; /* bin capacity, start of central directory */
+ uzoff_t c; /* bin capacity, start of central directory */
int d; /* if true, just report the number of disks */
FILE *e; /* input zip file */
FILE *f; /* output index and zip files */
extent g; /* number of bins from greedy(), entry to write */
int h; /* how to split--true means simple split, counter */
- ulg i = 0; /* size of index file plus room to leave */
+ zoff_t i = 0; /* size of index file plus room to leave */
extent j; /* steps through zip entries, bins */
int k; /* next argument type */
extent *n = NULL; /* next item in bin list (heads in b) */
- ulg *p; /* malloc'ed list of sizes, dest bins for greedy() */
+ uzoff_t *p; /* malloc'ed list of sizes, dest bins for greedy() */
char *q; /* steps through option characters */
int r; /* temporary variable, counter */
extent s; /* number of bins needed */
- ulg t; /* total of sizes, end of central directory */
+ zoff_t t; /* total of sizes, end of central directory */
int u; /* flag to wait for user on output files */
struct zlist far **w; /* malloc'ed table for zfiles linked list */
int x; /* if true, make an index file */
@@ -440,18 +533,57 @@ char **argv; /* command line tokens */
#ifdef AMIGA
char tailchar; /* temporary variable used in name generation below */
#endif
+ char errbuf[5000];
#ifdef THEOS
setlocale(LC_CTYPE, "I");
#endif
+#ifdef UNICODE_SUPPORT
+# ifdef UNIX
+ /* For Unix, set the locale to UTF-8. Any UTF-8 locale is
+ OK and they should all be the same. This allows seeing,
+ writing, and displaying (if the fonts are loaded) all
+ characters in UTF-8. */
+ {
+ char *loc;
+
+ /*
+ loc = setlocale(LC_CTYPE, NULL);
+ printf(" Initial language locale = '%s'\n", loc);
+ */
+
+ loc = setlocale(LC_CTYPE, "en_US.UTF-8");
+
+ /*
+ printf("langinfo %s\n", nl_langinfo(CODESET));
+ */
+
+ if (loc != NULL) {
+ /* using UTF-8 character set so can set UTF-8 GPBF bit 11 */
+ using_utf8 = 1;
+ /*
+ printf(" Locale set to %s\n", loc);
+ */
+ } else {
+ /*
+ printf(" Could not set Unicode UTF-8 locale\n");
+ */
+ }
+ }
+# endif
+#endif
+
/* If no args, show help */
if (argc == 1)
{
help();
- EXIT(0);
+ EXIT(ZE_OK);
}
+ /* Informational messages are written to stdout. */
+ mesg = stdout;
+
init_upper(); /* build case map table */
/* Go through args */
@@ -459,6 +591,21 @@ char **argv; /* command line tokens */
#ifdef SIGTERM /* Amiga has no SIGTERM */
signal(SIGTERM, handler);
#endif
+#ifdef SIGABRT
+ signal(SIGABRT, handler);
+#endif
+#ifdef SIGBREAK
+ signal(SIGBREAK, handler);
+#endif
+#ifdef SIGBUS
+ signal(SIGBUS, handler);
+#endif
+#ifdef SIGILL
+ signal(SIGILL, handler);
+#endif
+#ifdef SIGSEGV
+ signal(SIGSEGV, handler);
+#endif
k = h = x = d = u = 0;
c = DEFSIZ;
for (r = 1; r < argc; r++)
@@ -475,12 +622,12 @@ char **argv; /* command line tokens */
k = 1; /* Next non-option is path */
break;
case 'h': /* Show help */
- help(); EXIT(0);
+ help(); EXIT(ZE_OK);
case 'i': /* Make an index file */
x = 1;
break;
case 'l': case 'L': /* Show copyright and disclaimer */
- license(); EXIT(0);
+ license(); EXIT(ZE_OK);
case 'n': /* Specify maximum size of resulting zip files */
if (k)
ziperr(ZE_PARMS, "options are separate and precede zip file");
@@ -490,6 +637,9 @@ char **argv; /* command line tokens */
case 'p':
u = 1;
break;
+ case 'q': /* Quiet operation, suppress info messages */
+ noisy = 0;
+ break;
case 'r':
if (k)
ziperr(ZE_PARMS, "options are separate and precede zip file");
@@ -503,7 +653,7 @@ char **argv; /* command line tokens */
d = 1;
break;
case 'v': /* Show version info */
- version_info(); EXIT(0);
+ version_info(); EXIT(ZE_OK);
default:
ziperr(ZE_PARMS, "Use option -h for help.");
}
@@ -539,6 +689,10 @@ char **argv; /* command line tokens */
if (zipfile == NULL)
ziperr(ZE_PARMS, "need to specify zip file");
+ if ((in_path = malloc(strlen(zipfile) + 1)) == NULL) {
+ ziperr(ZE_MEM, "input");
+ }
+ strcpy(in_path, zipfile);
/* Read zip file */
if ((r = readzipfile()) != ZE_OK)
@@ -549,7 +703,7 @@ char **argv; /* command line tokens */
/* Make a list of sizes and check against capacity. Also compute the
size of the index file. */
c -= ENDHEAD + 4; /* subtract overhead/zipfile */
- if ((a = (ulg *)talloc(zcount * sizeof(ulg))) == NULL ||
+ if ((a = (uzoff_t *)talloc(zcount * sizeof(uzoff_t))) == NULL ||
(w = (struct zlist far **)talloc(zcount * sizeof(struct zlist far *))) ==
NULL)
{
@@ -562,10 +716,16 @@ char **argv; /* command line tokens */
w[j] = z;
if (x)
i += z->nam + 6 + NL;
+ /* New scanzip_reg only reads central directory so use cext for ext */
t += a[j] = 8 + LOCHEAD + CENHEAD +
- 2 * (ulg)z->nam + 2 * (ulg)z->ext + z->com + z->siz;
- if (a[j] > c)
+ 2 * (zoff_t)z->nam + 2 * (zoff_t)z->cext + z->com + z->siz;
+ if (a[j] > c) {
+ sprintf(errbuf, "Entry is larger than max split size of: %s",
+ zip_fzofft(c, NULL, "u"));
+ zipwarn(errbuf, "");
+ zipwarn("use -n to set split size", "");
ziperr(ZE_BIG, z->zname);
+ }
}
/* Decide on split to use, report number of files */
@@ -573,9 +733,9 @@ char **argv; /* command line tokens */
s = simple(a, zcount, c, i);
else
{
- if ((p = (ulg *)talloc(zcount * sizeof(ulg))) == NULL)
+ if ((p = (uzoff_t *)talloc(zcount * sizeof(uzoff_t))) == NULL)
ziperr(ZE_MEM, "was computing split");
- memcpy((char *)p, (char *)a, zcount * sizeof(ulg));
+ memcpy((char *)p, (char *)a, zcount * sizeof(uzoff_t));
s = simple(a, zcount, c, i);
g = greedy(p, zcount, c, i);
if (s <= g)
@@ -587,14 +747,15 @@ char **argv; /* command line tokens */
s = g;
}
}
- printf("%ld zip files w%s be made (%ld%% efficiency)\n",
- (ulg)s, d ? "ould" : "ill", ((200 * ((t + c - 1)/c)) / s + 1) >> 1);
+ printf("%ld zip files w%s be made (%s%% efficiency)\n",
+ (ulg)s, d ? "ould" : "ill",
+ zip_fzofft( ((200 * ((t + c - 1)/c)) / s + 1) / 2, NULL, "d"));
if (d)
{
tfreeall();
free((zvoid *)zipfile);
zipfile = NULL;
- EXIT(0);
+ EXIT(ZE_OK);
}
/* Set up path for output files */
@@ -615,18 +776,20 @@ char **argv; /* command line tokens */
if (path[0] && (tailchar != '/') && (tailchar != ':'))
strcat(path, "/");
#else
-# ifdef RISCOS
+#ifdef RISCOS
if (path[0] && path[strlen(path) - 1] != '.')
strcat(path, ".");
-# else /* !RISCOS */
-# ifdef QDOS
+#else
+#ifdef QDOS
if (path[0] && path[strlen(path) - 1] != '_')
strcat(path, "_");
-# else
+#else
+#ifndef VMS
if (path[0] && path[strlen(path) - 1] != '/')
strcat(path, "/");
-# endif
-# endif
+#endif /* !VMS */
+#endif /* ?QDOS */
+#endif /* ?RISCOS */
#endif /* ?AMIGA */
name = path + strlen(path);
}
@@ -706,13 +869,17 @@ char **argv; /* command line tokens */
for (j = 0; j < s; j++)
{
/* jump here on a disk retry */
- redobin:
+ redobin:
+
+ current_disk = 0;
+ cd_start_disk = 0;
+ cd_entries_this_disk = 0;
/* prompt if requested */
if (u)
{
char m[10];
- fprintf(stderr, "Insert disk #%ld of %ld and hit return: ",
+ fprintf(mesg, "Insert disk #%ld of %ld and hit return: ",
(ulg)j + 1, (ulg)s);
fgets(m, 10, stdin);
}
@@ -729,7 +896,9 @@ char **argv; /* command line tokens */
ziperr(ZE_CREAT, path);
}
for (j = 0; j < zcount; j++)
- fprintf(f, "%5ld %s\n", a[j] + 1, w[j]->zname);
+ fprintf(f, "%5s %s\n",
+ zip_fzofft( (a[j] + 1), NULL, "d"), w[j]->zname);
+
if ((j = ferror(f)) != 0 || fclose(f))
{
if (j)
@@ -743,19 +912,21 @@ char **argv; /* command line tokens */
sprintf(name, template, j + 1L);
printf("creating: %s\n", path);
zipsmade = j + 1;
- if ((f = fopen(path, FOPW)) == NULL)
+ if ((y = f = fopen(path, FOPW)) == NULL)
{
if (u && retry()) goto redobin;
ziperr(ZE_CREAT, path);
}
+ bytes_this_split = 0;
tempzn = 0;
/* write local headers and copy compressed data */
for (g = b[j]; g != (extent)-1; g = (extent)n[g])
{
- if (fseek(e, w[g]->off, SEEK_SET))
+ if (zfseeko(e, w[g]->off, SEEK_SET))
ziperr(ferror(e) ? ZE_READ : ZE_EOF, zipfile);
- if ((r = zipcopy(w[g], e, f)) != ZE_OK)
+ in_file = e;
+ if ((r = zipcopy(w[g])) != ZE_OK)
{
if (r == ZE_TEMP)
{
@@ -768,21 +939,24 @@ char **argv; /* command line tokens */
}
/* write central headers */
- if ((c = ftell(f)) == (ulg)(-1L))
+ if ((c = zftello(f)) == (uzoff_t)-1)
{
if (u && retry()) goto redobin;
ziperr(ZE_WRITE, path);
}
for (g = b[j], k = 0; g != (extent)-1; g = n[g], k++)
- if ((r = putcentral(w[g], f)) != ZE_OK)
+ if ((r = putcentral(w[g])) != ZE_OK)
{
if (u && retry()) goto redobin;
ziperr(ZE_WRITE, path);
}
/* write end-of-central header */
- if ((t = ftell(f)) == (ulg)(-1L) ||
- (r = putend(k, t - c, c, (extent)0, (char *)NULL, f)) != ZE_OK ||
+ cd_start_offset = c;
+ total_cd_entries = k;
+ if ((t = zftello(f)) == (zoff_t)-1 ||
+ (r = putend((zoff_t)k, t - c, c, (extent)0, (char *)NULL)) !=
+ ZE_OK ||
ferror(f) || fclose(f))
{
if (u && retry()) goto redobin;
@@ -797,7 +971,7 @@ char **argv; /* command line tokens */
/* Done! */
if (u)
- fputs("Done.\n", stderr);
+ fputs("Done.\n", mesg);
tfreeall();
RETURN(0);
diff --git a/zipsplit.txt b/zipsplit.txt
new file mode 100644
index 0000000..bd78ad7
--- /dev/null
+++ b/zipsplit.txt
@@ -0,0 +1,53 @@
+zipnote(1) zipnote(1)
+
+NAME
+ zipsplit - split a zipfile into smaller zipfiles
+
+SYNOPSIS
+ zipsplit [-t] [-i] [-p] [-s] [-n size] [-r room] [-b path] [-h] [-v]
+ [-L] zipfile
+
+ARGUMENTS
+ zipfile Zipfile to split.
+
+OPTIONS
+ -t Report how many files it will take, but don't make them.
+
+ -i Make index (zipsplit.idx) and count its size against first zip
+ file.
+
+ -n size
+ Make zip files no larger than "size" (default = 36000).
+
+ -r room
+ Leave room for "room" bytes on the first disk (default = 0).
+
+ -b path
+ Use path for the output zip files.
+
+ -p Pause between output zip files.
+
+ -s Do a sequential split even if it takes more zip files.
+
+ -h Show a short help.
+
+ -v Show version information.
+
+ -L Show software license.
+
+DESCRIPTION
+ zipsplit reads a zipfile and splits it into smaller zipfiles.
+
+EXAMPLES
+ To be filled in.
+
+BUGS
+ Does not yet support large (> 2 GB) or split archives.
+
+SEE ALSO
+ zip(1), unzip(1)
+
+AUTHOR
+ Info-ZIP
+
+ v3.0 of 8 May 2008 zipnote(1)
diff --git a/zipup.c b/zipup.c
index c6883f7..39f7d9c 100644
--- a/zipup.c
+++ b/zipup.c
@@ -1,9 +1,11 @@
/*
- Copyright (c) 1990-2005 Info-ZIP. All rights reserved.
+ zipup.c - Zip 3
- See the accompanying file LICENSE, version 2004-May-22 or later
+ 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, both of these files are missing, the Info-ZIP license
+ 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
*/
/*
@@ -11,16 +13,30 @@
*/
#define __ZIPUP_C
-#include <ctype.h>
+/* Found that for at least unix port zip.h has to be first or ctype.h will
+ define off_t and when using 64-bit file environment off_t in other files
+ is 8 bytes while off_t here is 4 bytes, and this makes the zlist struct
+ different sizes and needless to say leads to segmentation faults. Putting
+ zip.h first seems to fix this. 8/14/04 EG */
#include "zip.h"
+#include <ctype.h>
+#include <errno.h>
#ifndef UTIL /* This module contains no code for Zip Utilities */
#include "revision.h"
+#include "crc32.h"
#include "crypt.h"
#ifdef USE_ZLIB
# include "zlib.h"
#endif
+#ifdef BZIP2_SUPPORT
+# ifdef BZIP2_USEBZIP2DIR
+# include "bzip2/bzlib.h"
+# else
+# include "bzlib.h"
+# endif
+#endif
#ifdef OS2
# include "os2/os2zip.h"
@@ -72,6 +88,11 @@
# include "msdos/zipup.h"
#endif /* DOS */
+#ifdef NLM
+# include "novell/zipup.h"
+# include <nwfattr.h>
+#endif
+
#ifdef OS2
# include "os2/zipup.h"
#endif /* OS2 */
@@ -126,8 +147,13 @@ local unsigned file_read OF((char *buf, unsigned size));
local unsigned mem_read OF((char *buf, unsigned size));
# endif
#endif /* ?USE_ZLIB */
-local ulg filecompress OF((struct zlist far *z_entry, FILE *zipfile,
- int *cmpr_method));
+
+/* zip64 support 08/29/2003 R.Nausedat */
+local zoff_t filecompress OF((struct zlist far *z_entry, int *cmpr_method));
+
+#ifdef BZIP2_SUPPORT
+local zoff_t bzfilecompress OF((struct zlist far *z_entry, int *cmpr_method));
+#endif
/* Deflate "internal" global data (currently not in zip.h) */
#if defined(MMAP) || defined(BIG_MEM)
@@ -147,8 +173,8 @@ local ulg filecompress OF((struct zlist far *z_entry, FILE *zipfile,
/* Local data */
-local ulg crc; /* crc on uncompressed file data */
-local ftype ifile; /* file to compress */
+local ulg crc; /* crc on uncompressed file data */
+local ftype ifile; /* file to compress */
#if defined(MMAP) || defined(BIG_MEM)
local ulg remain;
/* window bytes not yet processed.
@@ -156,12 +182,11 @@ local ftype ifile; /* file to compress */
*/
#endif /* MMAP || BIG_MEM */
#ifdef USE_ZLIB
- local int deflInit; /* flag: zlib deflate is initialized */
+ local int deflInit = FALSE; /* flag: zlib deflate is initialized */
local z_stream zstrm; /* zlib's data interface structure */
local char *f_ibuf = NULL;
local char *f_obuf = NULL;
#else /* !USE_ZLIB */
- local FILE *zfile; /* output zip file */
local char file_outbuf[1024]; /* output buffer for compression to file */
# ifdef ZP_NEED_MEMCOMPR
@@ -171,42 +196,118 @@ local ftype ifile; /* file to compress */
/* Current offset in input buffer. in_offset is used only for in-memory
* compression. On 16 bit machines, the buffer is limited to 64K.
*/
- local unsigned in_size;
- /* size of current input buffer */
+ local unsigned in_size; /* size of current input buffer */
# endif /* ZP_NEED_MEMCOMPR */
#endif /* ?USE_ZLIB */
+#ifdef BZIP2_SUPPORT
+ local int bzipInit; /* flag: bzip2lib is initialized */
+ local bz_stream bstrm; /* zlib's data interface structure */
+# if !defined(USE_ZLIB)
+ local char *f_ibuf = NULL;
+ local char *f_obuf = NULL;
+# endif /* !USE_ZLIB */
+#endif /* BZIP2_SUPPORT */
+
#ifdef DEBUG
- ulg isize; /* input file size. global only for debugging */
+ zoff_t isize; /* input file size. global only for debugging */
#else /* !DEBUG */
- local ulg isize; /* input file size. */
+ local zoff_t isize; /* input file size. global only for debugging */
#endif /* ?DEBUG */
+ /* If file_read detects binary it sets this flag - 12/16/04 EG */
+ local int file_binary = 0; /* first buf */
+ local int file_binary_final = 0; /* for bzip2 for entire file. assume text until find binary */
+
+
+/* moved check to function 3/14/05 EG */
+int is_seekable(y)
+ FILE *y;
+{
+ zoff_t pos;
+
+#ifdef BROKEN_FSEEK
+ if (!fseekable(y)) {
+ return 0;
+ }
+#endif
+
+ pos = zftello(y);
+ if (zfseeko(y, pos, SEEK_SET)) {
+ return 0;
+ }
+
+ return 1;
+}
int percent(n, m)
-ulg n;
-ulg m; /* n is the original size, m is the new size */
+ uzoff_t n;
+ uzoff_t m; /* n is the original size, m is the new size */
/* Return the percentage compression from n to m using only integer
operations */
{
+ zoff_t p;
+
+#if 0
if (n > 0xffffffL) /* If n >= 16M */
{ /* then divide n and m by 256 */
n += 0x80; n >>= 8;
m += 0x80; m >>= 8;
}
return n > m ? (int)(1 + (200 * (n - m)/n)) / 2 : 0;
+#endif
+
+/* 2004-12-01 SMS.
+ * Changed to do big-n test only for small zoff_t.
+ * Changed big-n arithmetic to accomodate apparently negative values
+ * when a small zoff_t value exceeds 2G.
+ * Increased the reduction divisor from 256 to 512 to avoid the sign bit
+ * in a reduced intermediate, allowing signed arithmetic for the final
+ * result (which is no longer artificially limited to non-negative
+ * values).
+ * Note that right shifts must be on unsigned values to avoid undesired
+ * sign extension.
+ */
+
+/* Handle n = 0 case and account for int maybe being 16-bit. 12/28/2004 EG
+ */
+
+#define PC_MAX_SAFE 0x007fffffL /* 9 clear bits at high end. */
+#define PC_MAX_RND 0xffffff00L /* 8 clear bits at low end. */
+
+ if (sizeof(uzoff_t) < 8) /* Don't fiddle with big zoff_t. */
+ {
+ if ((ulg)n > PC_MAX_SAFE) /* Reduce large values. (n > m) */
+ {
+ if ((ulg)n < PC_MAX_RND) /* Divide n by 512 with rounding, */
+ n = ((ulg)n + 0x100) >> 9; /* if boost won't overflow. */
+ else /* Otherwise, use max value. */
+ n = PC_MAX_SAFE;
+
+ if ((ulg)m < PC_MAX_RND) /* Divide m by 512 with rounding, */
+ m = ((ulg)m + 0x100) >> 9; /* if boost won't overflow. */
+ else /* Otherwise, use max value. */
+ m = PC_MAX_SAFE;
+ }
+ }
+ if (n != 0)
+ p = ((200 * ((zoff_t)n - (zoff_t)m) / (zoff_t)n) + 1) / 2;
+ else
+ p = 0;
+ return (int)p; /* Return (rounded) % reduction. */
}
+
#ifndef RISCOS
local int suffixes(a, s)
-char *a; /* name to check suffix of */
-char *s; /* list of suffixes separated by : or ; */
+ char *a; /* name to check suffix of */
+ char *s; /* list of suffixes separated by : or ; */
/* Return true if a ends in any of the suffixes in the list s. */
{
- int m; /* true if suffix matches so far */
- char *p; /* pointer into special */
- char *q; /* pointer into name a */
+ int m; /* true if suffix matches so far */
+ char *p; /* pointer into special */
+ char *q; /* pointer into name a */
#ifdef QDOS
short dlen = devlen(a);
@@ -251,12 +352,12 @@ char *s; /* list of suffixes separated by : or ; */
#else /* RISCOS */
local int filetypes(a, s)
-char *a; /* extra field of file to check filetype of */
-char *s; /* list of filetypes separated by : or ; */
+char *a; /* extra field of file to check filetype of */
+char *s; /* list of filetypes separated by : or ; */
/* Return true if a is any of the filetypes in the list s. */
{
- char *p; /* pointer into special */
- char typestr[4]; /* filetype hex string taken from a */
+ char *p; /* pointer into special */
+ char typestr[4]; /* filetype hex string taken from a */
if ((((unsigned*)a)[2] & 0xFFF00000) != 0xFFF00000) {
/* The file is not filestamped, always try to compress it */
@@ -269,7 +370,9 @@ char *s; /* list of filetypes separated by : or ; */
while (*p==':' || *p==';')
p++;
- if (typestr[0]==toupper(p[0]) && typestr[1]==toupper(p[1]) && typestr[2]==toupper(p[2]))
+ if (typestr[0] == toupper(p[0]) &&
+ typestr[1] == toupper(p[1]) &&
+ typestr[2] == toupper(p[2]))
return 1;
}
return 0;
@@ -282,12 +385,12 @@ char *s; /* list of filetypes separated by : or ; */
name), an encryption header if encrypting, the compressed data
and possibly an extended local header. */
-int zipup(z, y)
+int zipup(z)
struct zlist far *z; /* zip entry to compress */
-FILE *y; /* output file */
/* Compress the file z->name into the zip entry described by *z and write
it to the file *y. Encrypt if requested. Return an error code in the
ZE_ class. Also, update tempzn by the number of bytes written. */
+/* y is now global */
{
iztimes f_utim; /* UNIX GMT timestamps, filled by filetime() */
ulg tim; /* time returned by filetime() */
@@ -296,31 +399,103 @@ FILE *y; /* output file */
extent k = 0; /* result of zread */
int l = 0; /* true if this file is a symbolic link */
int m; /* method for this entry */
- ulg o, p; /* offsets in zip file */
- long q = -3L; /* size returned by filetime */
+
+ zoff_t o = 0, p; /* offsets in zip file */
+ zoff_t q = (zoff_t) -3; /* size returned by filetime */
+ uzoff_t uq; /* unsigned q */
+ zoff_t s = 0; /* size of compressed data */
+
int r; /* temporary variable */
- ulg s = 0L; /* size of compressed data */
int isdir; /* set for a directory name */
int set_type = 0; /* set if file type (ascii/binary) unknown */
+ zoff_t last_o; /* used to detect wrap around */
+
+ ush tempext = 0; /* temp copies of extra fields */
+ ush tempcext = 0;
+ char *tempextra = NULL;
+ char *tempcextra = NULL;
+
+
+#ifdef WINDLL
+# ifdef ZIP64_SUPPORT
+ extern _int64 filesize64;
+ extern unsigned long low;
+ extern unsigned long high;
+# endif
+#endif
z->nam = strlen(z->iname);
isdir = z->iname[z->nam-1] == (char)0x2f; /* ascii[(unsigned)('/')] */
- if ((tim = filetime(z->name, &a, &q, &f_utim)) == 0 || q == -3L)
+ file_binary = -1; /* not set, set after first read */
+ file_binary_final = 0; /* not set, set after first read */
+
+#if defined(UNICODE_SUPPORT) && defined(WIN32)
+ if (!no_win32_wide)
+ tim = filetimew(z->namew, &a, &q, &f_utim);
+ else
+ tim = filetime(z->name, &a, &q, &f_utim);
+#else
+ tim = filetime(z->name, &a, &q, &f_utim);
+#endif
+ if (tim == 0 || q == (zoff_t) -3)
return ZE_OPEN;
/* q is set to -1 if the input file is a device, -2 for a volume label */
- if (q == -2L) {
+ if (q == (zoff_t) -2) {
isdir = 1;
q = 0;
} else if (isdir != ((a & MSDOS_DIR_ATTR) != 0)) {
/* don't overwrite a directory with a file and vice-versa */
return ZE_MISS;
}
+ /* reset dot_count for each file */
+ if (!display_globaldots)
+ dot_count = -1;
+
+ /* display uncompressed size */
+ uq = ((uzoff_t) q > (uzoff_t) -3) ? 0 : (uzoff_t) q;
+ if (noisy && display_usize) {
+ fprintf(mesg, " (");
+ DisplayNumString( mesg, uq );
+ fprintf(mesg, ")");
+ mesg_line_started = 1;
+ fflush(mesg);
+ }
+ if (logall && display_usize) {
+ fprintf(logfile, " (");
+ DisplayNumString( logfile, uq );
+ fprintf(logfile, ")");
+ logfile_line_started = 1;
+ fflush(logfile);
+ }
+
+ /* initial z->len so if error later have something */
+ z->len = uq;
+
z->att = (ush)UNKNOWN; /* will be changed later */
z->atx = 0; /* may be changed by set_extra_field() */
/* Free the old extra fields which are probably obsolete */
+ /* Should probably read these and keep any we don't update. 12/30/04 EG */
+ if (extra_fields == 2) {
+ /* If keeping extra fields, make copy before clearing for set_extra_field()
+ A better approach is to modify the port code, but maybe later */
+ if (z->ext) {
+ if ((tempextra = malloc(z->ext)) == NULL) {
+ ZIPERR(ZE_MEM, "extra fields copy");
+ }
+ memcpy(tempextra, z->extra, z->ext);
+ tempext = z->ext;
+ }
+ if (z->cext) {
+ if ((tempcextra = malloc(z->cext)) == NULL) {
+ ZIPERR(ZE_MEM, "extra fields copy");
+ }
+ memcpy(tempcextra, z->cextra, z->cext);
+ tempcext = z->cext;
+ }
+ }
if (z->ext) {
free((zvoid *)(z->extra));
}
@@ -344,6 +519,24 @@ FILE *y; /* output file */
m = method;
#endif /* ?RISCOS */
+ /* For now force deflate if using descriptors. Instead zip and unzip
+ could check bytes read against compressed size in each data descriptor
+ found and skip over any that don't match. This is how at least one
+ other zipper does it. To be added later. Until then it
+ probably doesn't hurt to force deflation when streaming. 12/30/04 EG
+ */
+
+ /* Now is a good time. For now allow storing for testing. 12/16/05 EG */
+ /* By release need to force deflation based on reports some inflate
+ streamed data to find the end of the data */
+ /* Need to handle bzip2 */
+#ifdef NO_STREAMING_STORE
+ if (use_descriptors && m == STORE)
+ {
+ m = DEFLATE;
+ }
+#endif
+
/* Open file to zip up unless it is stdin */
if (strcmp(z->name, "-") == 0)
{
@@ -360,13 +553,23 @@ FILE *y; /* output file */
if (extra_fields) {
/* create extra field and change z->att and z->atx if desired */
set_extra_field(z, &f_utim);
-#ifdef QLZIP
+# ifdef QLZIP
if(qlflag)
a |= (S_IXUSR) << 16; /* Cross compilers don't set this */
-#endif
-#ifdef RISCOS
+# endif
+# ifdef RISCOS
m = special != NULL && filetypes(z->extra, special) ? STORE : method;
-#endif /* RISCOS */
+# endif /* RISCOS */
+
+ /* For now allow store for testing */
+#ifdef NO_STREAMING_STORE
+ /* For now force deflation if using data descriptors. */
+ if (use_descriptors && m == STORE)
+ {
+ m = DEFLATE;
+ }
+#endif
+
}
#endif /* !(VMS && VMS_PK_EXTRA) */
l = issymlnk(a);
@@ -394,8 +597,18 @@ FILE *y; /* output file */
}
else
#endif /* CMS_MVS */
+#if defined(UNICODE_SUPPORT) && defined(WIN32)
+ if (!no_win32_wide) {
+ if ((ifile = zwopen(z->namew, fhow)) == fbad)
+ return ZE_OPEN;
+ } else {
+ if ((ifile = zopen(z->name, fhow)) == fbad)
+ return ZE_OPEN;
+ }
+#else
if ((ifile = zopen(z->name, fhow)) == fbad)
- return ZE_OPEN;
+ return ZE_OPEN;
+#endif
}
z->tim = tim;
@@ -461,6 +674,27 @@ FILE *y; /* output file */
} /* strcmp(z->name, "-") == 0 */
+ if (extra_fields == 2) {
+ unsigned len;
+ char *p;
+
+ /* step through old extra fields and copy over any not already
+ in new extra fields */
+ p = copy_nondup_extra_fields(tempextra, tempext, z->extra, z->ext, &len);
+ free(z->extra);
+ z->ext = len;
+ z->extra = p;
+ p = copy_nondup_extra_fields(tempcextra, tempcext, z->cextra, z->cext, &len);
+ free(z->cextra);
+ z->cext = len;
+ z->cextra = p;
+
+ if (tempext)
+ free(tempextra);
+ if (tempcext)
+ free(tempcextra);
+ }
+
if (q == 0)
m = STORE;
if (m == BEST)
@@ -474,6 +708,18 @@ FILE *y; /* output file */
* ??? to be done.
*/
+ /* An alternative used by others is to allow storing but on reading do
+ * a second check when a signature is found. This is simply to check
+ * the compressed size to the bytes read since the start of the file data.
+ * If this is the right signature then the compressed size should match
+ * the size of the compressed data to that point. If not look for the
+ * next signature. We should do this. 12/31/04 EG
+ *
+ * For reading and testing we should do this, but should not write
+ * stored streamed data unless for testing as finding the end of
+ * streamed deflated data can be done by inflating. 6/26/06 EG
+ */
+
/* Fill in header information and write local header to zip file.
* This header will later be re-written since compressed length and
* crc are not yet known.
@@ -481,34 +727,50 @@ FILE *y; /* output file */
/* (Assume ext, cext, com, and zname already filled in.) */
#if defined(OS2) || defined(WIN32)
+# ifdef WIN32_OEM
+ /* When creating OEM-coded names on Win32, the entries must always be marked
+ as "created on MSDOS" (OS_CODE = 0), because UnZip needs to handle archive
+ entry names just like those created by Zip's MSDOS port.
+ */
+ z->vem = (ush)(dosify ? 20 : 0 + Z_MAJORVER * 10 + Z_MINORVER);
+# else
z->vem = (ush)(z->dosflag ? (dosify ? 20 : /* Made under MSDOS by PKZIP 2.0 */
(0 + Z_MAJORVER * 10 + Z_MINORVER))
: OS_CODE + Z_MAJORVER * 10 + Z_MINORVER);
- /* For a FAT file system, we cheat and pretend that the file
+ /* For a plain old (8+3) FAT file system, we cheat and pretend that the file
* was not made on OS2/WIN32 but under DOS. unzip is confused otherwise.
*/
+# endif
#else /* !(OS2 || WIN32) */
z->vem = (ush)(dosify ? 20 : OS_CODE + Z_MAJORVER * 10 + Z_MINORVER);
#endif /* ?(OS2 || WIN32) */
z->ver = (ush)(m == STORE ? 10 : 20); /* Need PKUNZIP 2.0 except for store */
+#ifdef BZIP2_SUPPORT
+ if (method == BZIP2)
+ z->ver = (ush)(m == STORE ? 10 : 46);
+#endif
z->crc = 0; /* to be updated later */
/* Assume first that we will need an extended local header: */
- z->flg = 8; /* to be updated later */
+ if (isdir)
+ /* If dir then q = 0 and extended header not needed */
+ z->flg = 0;
+ else
+ z->flg = 8; /* to be updated later */
#if CRYPT
- if (key != NULL) {
+ if (!isdir && key != NULL) {
z->flg |= 1;
/* Since we do not yet know the crc here, we pretend that the crc
* is the modification time:
*/
z->crc = z->tim << 16;
+ /* More than pretend. File is encrypted using crypt header with that. */
}
#endif /* CRYPT */
z->lflg = z->flg;
z->how = (ush)m; /* may be changed later */
- z->siz = (ulg)(m == STORE && q >= 0 ? q : 0); /* will be changed later */
- z->len = (ulg)(q != -1L ? q : 0); /* may be changed later */
- z->dsk = 0;
+ z->siz = (zoff_t)(m == STORE && q >= 0 ? q : 0); /* will be changed later */
+ z->len = (zoff_t)(q != -1L ? q : 0); /* may be changed later */
if (z->att == (ush)UNKNOWN) {
z->att = BINARY; /* set sensible value in header */
set_type = 1;
@@ -519,17 +781,25 @@ FILE *y; /* output file */
#else
z->atx = dosify ? a & 0xff : a | (z->atx & 0x0000ff00);
#endif /* DOS || OS2 || WIN32 */
- z->off = tempzn;
- if ((r = putlocal(z, y)) != ZE_OK) {
+
+ if ((r = putlocal(z, PUTLOCAL_WRITE)) != ZE_OK) {
if (ifile != fbad)
zclose(ifile);
return r;
}
+
+ /* now get split information set by bfwrite() */
+ z->off = current_local_offset;
+
+ /* disk local header was written to */
+ z->dsk = current_local_disk;
+
tempzn += 4 + LOCHEAD + z->nam + z->ext;
+
#if CRYPT
- if (key != NULL) {
- crypthead(key, z->crc, y);
+ if (!isdir && key != NULL) {
+ crypthead(key, z->crc);
z->siz += RAND_HEAD_LEN; /* to be updated later */
tempzn += RAND_HEAD_LEN;
}
@@ -540,24 +810,52 @@ FILE *y; /* output file */
ZIPERR(ZE_WRITE, "unexpected error on zip file");
}
- o = ftell(y); /* for debugging only, ftell can fail on pipes */
+ last_o = o;
+ o = zftello(y); /* for debugging only, ftell can fail on pipes */
if (ferror(y))
clearerr(y);
+ if (o != -1 && last_o > o) {
+ fprintf(mesg, "last %s o %s\n", zip_fzofft(last_o, NULL, NULL),
+ zip_fzofft(o, NULL, NULL));
+ ZIPERR(ZE_BIG, "seek wrap - zip file too big to write");
+ }
+
/* Write stored or deflated file to zip file */
isize = 0L;
crc = CRCVAL_INITIAL;
- if (m == DEFLATE) {
- if (set_type) z->att = (ush)UNKNOWN; /* is finally set in filecompress() */
- s = filecompress(z, y, &m);
+ if (isdir) {
+ /* nothing to write */
+ }
+ else if (m != STORE) {
+ if (set_type) z->att = (ush)UNKNOWN;
+ /* ... is finally set in file compression routine */
+#ifdef BZIP2_SUPPORT
+ if (m == BZIP2) {
+ s = bzfilecompress(z, &m);
+ }
+ else
+#endif /* BZIP2_SUPPORT */
+ {
+ s = filecompress(z, &m);
+ }
#ifndef PGP
- if (z->att == (ush)BINARY && translate_eol) {
- zipwarn("-l used on binary file", "");
+ if (z->att == (ush)BINARY && translate_eol && file_binary) {
+ if (translate_eol == 1)
+ zipwarn("has binary so -l ignored", "");
+ else
+ zipwarn("has binary so -ll ignored", "");
+ }
+ else if (z->att == (ush)BINARY && translate_eol) {
+ if (translate_eol == 1)
+ zipwarn("-l used on binary file - corrupted?", "");
+ else
+ zipwarn("-ll used on binary file - corrupted?", "");
}
#endif
}
- else if (!isdir)
+ else
{
if ((b = malloc(SBSZ)) == NULL)
return ZE_MEM;
@@ -568,7 +866,7 @@ FILE *y; /* output file */
* compute crc first because zfwrite will alter the buffer b points to !!
*/
crc = crc32(crc, (uch *) b, k);
- if (zfwrite(b, 1, k, y) != k)
+ if (zfwrite(b, 1, k) != k)
{
free((zvoid *)b);
return ZE_TEMP;
@@ -583,18 +881,38 @@ FILE *y; /* output file */
{
while ((k = file_read(b, SBSZ)) > 0 && k != (extent) EOF)
{
- if (zfwrite(b, 1, k, y) != k)
+ if (zfwrite(b, 1, k) != k)
{
if (ifile != fbad)
zclose(ifile);
free((zvoid *)b);
return ZE_TEMP;
}
+ if (!display_globaldots) {
+ if (dot_size > 0) {
+ /* initial space */
+ if (noisy && dot_count == -1) {
#ifndef WINDLL
- if (verbose) putc('.', stderr);
+ putc(' ', mesg);
+ fflush(mesg);
#else
- if (verbose) fprintf(stdout,"%c",'.');
+ fprintf(stdout,"%c",' ');
#endif
+ dot_count++;
+ }
+ dot_count++;
+ if (dot_size <= (dot_count + 1) * SBSZ) 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;
+ }
+ }
}
}
free((zvoid *)b);
@@ -602,7 +920,9 @@ FILE *y; /* output file */
}
if (ifile != fbad && zerr(ifile)) {
perror("\nzip warning");
- zipwarn("could not read input file: ", z->zname);
+ if (logfile)
+ fprintf(logfile, "\nzip warning: %s\n", strerror(errno));
+ zipwarn("could not read input file: ", z->oname);
}
if (ifile != fbad)
zclose(ifile);
@@ -622,7 +942,7 @@ FILE *y; /* output file */
* and not on MSDOS -- diet in TSR mode reports an incorrect file size)
*/
#ifndef TANDEM /* Tandem EOF does not match byte count unless Unstructured */
- if (!translate_eol && q != -1L && isize != (ulg)q)
+ if (!translate_eol && q != -1L && isize != q)
{
Trace((mesg, " i=%lu, q=%lu ", isize, q));
zipwarn(" file size changed while zipping ", z->name);
@@ -631,53 +951,122 @@ FILE *y; /* output file */
#endif /* !VMS && !CMS_MVS && !__mpexl */
#endif /* (!MSDOS || OS2) */
- /* Try to rewrite the local header with correct information */
- z->crc = crc;
- z->siz = s;
+ if (isdir)
+ {
+ /* A directory */
+ z->siz = 0;
+ z->len = 0;
+ z->how = STORE;
+ z->ver = 10;
+ /* never encrypt directory so don't need extended local header */
+ z->flg &= ~8;
+ z->lflg &= ~8;
+ }
+ else
+ {
+ /* Try to rewrite the local header with correct information */
+ z->crc = crc;
+ z->siz = s;
#if CRYPT
- if (key != NULL)
- z->siz += RAND_HEAD_LEN;
+ if (!isdir && key != NULL)
+ z->siz += RAND_HEAD_LEN;
#endif /* CRYPT */
- z->len = isize;
+ z->len = isize;
+ /* if can seek back to local header */
#ifdef BROKEN_FSEEK
- if (!fseekable(y) || fseek(y, z->off, SEEK_SET))
+ if (use_descriptors || !fseekable(y) || zfseeko(y, z->off, SEEK_SET))
#else
- if (fseek(y, z->off, SEEK_SET))
+ if (use_descriptors || zfseeko(y, z->off, SEEK_SET))
#endif
- {
- if (z->how != (ush) m)
- error("can't rewrite method");
- if (m == STORE && q < 0)
- ZIPERR(ZE_PARMS, "zip -0 not supported for I/O on pipes or devices");
- if ((r = putextended(z, y)) != ZE_OK)
- return r;
- tempzn += 16L;
- z->flg = z->lflg; /* if flg modified by inflate */
- } else {
- /* seek ok, ftell() should work, check compressed size */
-#if !defined(VMS) && !defined(CMS_MVS)
- if (p - o != s) {
- fprintf(mesg, " s=%ld, actual=%ld ", s, p-o);
- error("incorrect compressed size");
- }
-#endif /* !VMS && !CMS_MVS */
- z->how = (ush)m;
- z->ver = (ush)(m == STORE ? 10 : 20); /* Need PKUNZIP 2.0 unless STORED */
- if ((z->flg & 1) == 0)
- z->flg &= ~8; /* clear the extended local header flag */
- z->lflg = z->flg;
- /* rewrite the local header: */
- if ((r = putlocal(z, y)) != ZE_OK)
- return r;
- if (fseek(y, p, SEEK_SET))
- return ZE_READ;
- if ((z->flg & 1) != 0) {
- /* encrypted file, extended header still required */
- if ((r = putextended(z, y)) != ZE_OK)
+ {
+ if (z->how != (ush) m)
+ error("can't rewrite method");
+ if (m == STORE && q < 0)
+ ZIPERR(ZE_PARMS, "zip -0 not supported for I/O on pipes or devices");
+ if ((r = putextended(z)) != ZE_OK)
return r;
+ /* if Zip64 and not seekable then Zip64 data descriptor */
+#ifdef ZIP64_SUPPORT
+ tempzn += (zip64_entry ? 24L : 16L);
+#else
tempzn += 16L;
+#endif
+ z->flg = z->lflg; /* if z->flg modified by deflate */
+ } else {
+ /* ftell() not as useful across splits */
+ if (bytes_this_entry != (uzoff_t)(key ? s + 12 : s)) {
+ fprintf(mesg, " s=%s, actual=%s ",
+ zip_fzofft(s, NULL, NULL), zip_fzofft(bytes_this_entry, NULL, NULL));
+ error("incorrect compressed size");
+ }
+#if 0
+ /* seek ok, ftell() should work, check compressed size */
+# if !defined(VMS) && !defined(CMS_MVS)
+ if (p - o != s) {
+ fprintf(mesg, " s=%s, actual=%s ",
+ zip_fzofft(s, NULL, NULL), zip_fzofft(p-o, NULL, NULL));
+ error("incorrect compressed size");
+ }
+# endif /* !VMS && !CMS_MVS */
+#endif /* 0 */
+ z->how = (ush)m;
+ switch (m)
+ {
+ case STORE:
+ z->ver = 10; break;
+ /* Need PKUNZIP 2.0 for DEFLATE */
+ case DEFLATE:
+ z->ver = 20; break;
+#ifdef BZIP2_SUPPORT
+ case BZIP2:
+ z->ver = 46; break;
+#endif
+ }
+ /*
+ * The encryption header needs the crc, but we don't have it
+ * for a new file. The file time is used instead and the encryption
+ * header then used to encrypt the data. The AppNote standard only
+ * can be applied to a file that the crc is known, so that means
+ * either an existing entry in an archive or get the crc before
+ * creating the encryption header and then encrypt the data.
+ */
+ if ((z->flg & 1) == 0) {
+ /* not encrypting so don't need extended local header */
+ z->flg &= ~8;
+ }
+ /* deflate may have set compression level bit markers in z->flg,
+ and we can't think of any reason central and local flags should
+ be different. */
+ z->lflg = z->flg;
+
+ /* If not using descriptors, back up and rewrite local header. */
+ if (split_method == 1 && current_local_file != y) {
+ if (zfseeko(current_local_file, z->off, SEEK_SET))
+ return ZE_READ;
+ }
+
+ /* if local header in another split, putlocal will close it */
+ if ((r = putlocal(z, PUTLOCAL_REWRITE)) != ZE_OK)
+ return r;
+
+ if (zfseeko(y, bytes_this_split, SEEK_SET))
+ return ZE_READ;
+
+ if ((z->flg & 1) != 0) {
+ /* encrypted file, extended header still required */
+ if ((r = putextended(z)) != ZE_OK)
+ return r;
+#ifdef ZIP64_SUPPORT
+ if (zip64_entry)
+ tempzn += 24L;
+ else
+ tempzn += 16L;
+#else
+ tempzn += 16L;
+#endif
+ }
}
- }
+ } /* isdir */
/* Free the local extra field which is no longer needed */
if (z->ext) {
if (z->extra != z->cextra) {
@@ -690,27 +1079,73 @@ FILE *y; /* output file */
/* Display statistics */
if (noisy)
{
- if (verbose)
- fprintf(mesg, "\t(in=%lu) (out=%lu)", isize, s);
+ if (verbose) {
+ fprintf( mesg, "\t(in=%s) (out=%s)",
+ zip_fzofft(isize, NULL, "u"), zip_fzofft(s, NULL, "u"));
+ }
+#ifdef BZIP2_SUPPORT
+ if (m == BZIP2)
+ fprintf(mesg, " (bzipped %d%%)\n", percent(isize, s));
+ else
+#endif
if (m == DEFLATE)
fprintf(mesg, " (deflated %d%%)\n", percent(isize, s));
else
fprintf(mesg, " (stored 0%%)\n");
+ mesg_line_started = 0;
fflush(mesg);
}
+ if (logall)
+ {
+#ifdef BZIP2_SUPPORT
+ if (m == BZIP2)
+ fprintf(logfile, " (bzipped %d%%)\n", percent(isize, s));
+ else
+#endif
+ if (m == DEFLATE)
+ fprintf(logfile, " (deflated %d%%)\n", percent(isize, s));
+ else
+ fprintf(logfile, " (stored 0%%)\n");
+ logfile_line_started = 0;
+ fflush(logfile);
+ }
+
#ifdef WINDLL
+# ifdef ZIP64_SUPPORT
+ /* The DLL api has been updated and uses a different
+ interface. 7/24/04 EG */
+ if (lpZipUserFunctions->ServiceApplication64 != NULL)
+ {
+ if ((*lpZipUserFunctions->ServiceApplication64)(z->zname, isize))
+ ZIPERR(ZE_ABORT, "User terminated operation");
+ }
+ else
+ {
+ filesize64 = isize;
+ low = (unsigned long)(filesize64 & 0x00000000FFFFFFFF);
+ high = (unsigned long)((filesize64 >> 32) & 0x00000000FFFFFFFF);
+ if (lpZipUserFunctions->ServiceApplication64_No_Int64 != NULL) {
+ if ((*lpZipUserFunctions->ServiceApplication64_No_Int64)(z->zname, low, high))
+ ZIPERR(ZE_ABORT, "User terminated operation");
+ }
+ }
+# else
if (lpZipUserFunctions->ServiceApplication != NULL)
- {
- if ((*lpZipUserFunctions->ServiceApplication)(z->zname, isize))
- {
- ZIPERR(ZE_ABORT, "User terminated operation");
- }
- }
+ {
+ if ((*lpZipUserFunctions->ServiceApplication)(z->zname, isize))
+ {
+ ZIPERR(ZE_ABORT, "User terminated operation");
+ }
+ }
+# endif
#endif
+
return ZE_OK;
}
+
+
local unsigned file_read(buf, size)
char *buf;
unsigned size;
@@ -721,6 +1156,7 @@ local unsigned file_read(buf, size)
{
unsigned len;
char *b;
+ zoff_t isize_prev; /* Previous isize. Used for overflow check. */
#if defined(MMAP) || defined(BIG_MEM)
if (remain == 0L) {
@@ -750,77 +1186,103 @@ local unsigned file_read(buf, size)
}
#endif
} else if (translate_eol == 1) {
+ /* translate_eol == 1 */
/* Transform LF to CR LF */
size >>= 1;
b = buf+size;
size = len = zread(ifile, b, size);
if (len == (unsigned)EOF || len == 0) return len;
-#ifdef EBCDIC
- if (aflag == ASCII)
- {
- do {
- char c;
- if ((c = *b++) == '\n') {
- *buf++ = CR; *buf++ = LF; len++;
- } else {
- *buf++ = (char)ascii[(uch)c];
- }
- } while (--size != 0);
+ /* check buf for binary - 12/16/04 */
+ if (file_binary == -1) {
+ /* first read */
+ file_binary = is_text_buf(b, size) ? 0 : 1;
}
- else
+
+ if (file_binary != 1) {
+#ifdef EBCDIC
+ if (aflag == ASCII)
+ {
+ do {
+ char c;
+
+ if ((c = *b++) == '\n') {
+ *buf++ = CR; *buf++ = LF; len++;
+ } else {
+ *buf++ = (char)ascii[(uch)c];
+ }
+ } while (--size != 0);
+ }
+ else
#endif /* EBCDIC */
- {
- do {
- if ((*buf++ = *b++) == '\n') *(buf-1) = CR, *buf++ = LF, len++;
- } while (--size != 0);
+ {
+ do {
+ if ((*buf++ = *b++) == '\n') *(buf-1) = CR, *buf++ = LF, len++;
+ } while (--size != 0);
+ }
+ buf -= len;
+ } else { /* do not translate binary */
+ memcpy(buf, b, size);
}
- buf -= len;
} else {
+ /* translate_eol == 2 */
/* Transform CR LF to LF and suppress final ^Z */
b = buf;
size = len = zread(ifile, buf, size-1);
if (len == (unsigned)EOF || len == 0) return len;
- buf[len] = '\n'; /* I should check if next char is really a \n */
-#ifdef EBCDIC
- if (aflag == ASCII)
- {
- do {
- char c;
- if ((c = *b++) == '\r' && *b == '\n') {
- len--;
- } else {
- *buf++ = (char)(c == '\n' ? LF : ascii[(uch)c]);
- }
- } while (--size != 0);
+ /* check buf for binary - 12/16/04 */
+ if (file_binary == -1) {
+ /* first read */
+ file_binary = is_text_buf(b, size) ? 0 : 1;
}
- else
+
+ if (file_binary != 1) {
+ buf[len] = '\n'; /* I should check if next char is really a \n */
+#ifdef EBCDIC
+ if (aflag == ASCII)
+ {
+ do {
+ char c;
+
+ if ((c = *b++) == '\r' && *b == '\n') {
+ len--;
+ } else {
+ *buf++ = (char)(c == '\n' ? LF : ascii[(uch)c]);
+ }
+ } while (--size != 0);
+ }
+ else
#endif /* EBCDIC */
- {
- do {
- if (( *buf++ = *b++) == CR && *b == LF) buf--, len--;
- } while (--size != 0);
- }
- if (len == 0) {
- zread(ifile, buf, 1); len = 1; /* keep single \r if EOF */
+ {
+ do {
+ if (( *buf++ = *b++) == CR && *b == LF) buf--, len--;
+ } while (--size != 0);
+ }
+ if (len == 0) {
+ zread(ifile, buf, 1); len = 1; /* keep single \r if EOF */
#ifdef EBCDIC
- if (aflag == ASCII) {
- *buf = (char)(*buf == '\n' ? LF : ascii[(uch)(*buf)]);
- }
+ if (aflag == ASCII) {
+ *buf = (char)(*buf == '\n' ? LF : ascii[(uch)(*buf)]);
+ }
#endif
- } else {
- buf -= len;
- if (buf[len-1] == CTRLZ) len--; /* suppress final ^Z */
+ } else {
+ buf -= len;
+ if (buf[len-1] == CTRLZ) len--; /* suppress final ^Z */
+ }
}
}
crc = crc32(crc, (uch *) buf, len);
+ /* 2005-05-23 SMS.
+ Increment file size. A small-file program reading a large file may
+ cause isize to overflow, so complain (and abort) if it goes
+ negative or wraps around. Awful things happen later otherwise.
+ */
+ isize_prev = isize;
isize += (ulg)len;
- /* added check for file size - 2/20/05 */
- if ((isize & (ulg)0xffffffffL) < (ulg)len) {
- /* fatal error: file size exceeds Zip limit */
- ZIPERR(ZE_BIG, "file exceeds Zip's 4GB uncompressed size limit");
+ if (isize < isize_prev) {
+ ZIPERR(ZE_BIG, "overflow in byte count");
}
return len;
}
@@ -841,7 +1303,7 @@ local int zl_deflate_init(pack_level)
ZLIB_VERSION, zlib_version);
zp_err = ZE_LOGIC;
} else if (strcmp(zlib_version, ZLIB_VERSION) != 0) {
- fprintf(stderr,
+ fprintf(mesg,
"\twarning: different zlib version (expected %s, using %s)\n",
ZLIB_VERSION, zlib_version);
}
@@ -885,12 +1347,13 @@ void zl_deflate_free()
if (err != Z_OK && err !=Z_DATA_ERROR) {
ziperr(ZE_LOGIC, "zlib deflateEnd failed");
}
+ deflInit = FALSE;
}
}
#else /* !USE_ZLIB */
-#ifdef ZP_NEED_MEMCOMPR
+# ifdef ZP_NEED_MEMCOMPR
/* ===========================================================================
* In-memory read function. As opposed to file_read(), this function
* does not perform end-of-line translation, and does not update the
@@ -914,7 +1377,7 @@ local unsigned mem_read(b, bsize)
return 0; /* end of input */
}
}
-#endif /* ZP_NEED_MEMCOMPR */
+# endif /* ZP_NEED_MEMCOMPR */
/* ===========================================================================
@@ -924,13 +1387,13 @@ void flush_outbuf(o_buf, o_idx)
char *o_buf;
unsigned *o_idx;
{
- if (zfile == NULL) {
+ if (y == NULL) {
error("output buffer too small for in-memory compression");
}
/* Encrypt and write the output buffer: */
if (*o_idx != 0) {
- zfwrite(o_buf, 1, (extent)*o_idx, zfile);
- if (ferror(zfile)) ziperr(ZE_WRITE, "write error on zip file");
+ zfwrite(o_buf, 1, (extent)*o_idx);
+ if (ferror(y)) ziperr(ZE_WRITE, "write error on zip file");
}
*o_idx = 0;
}
@@ -943,7 +1406,7 @@ void flush_outbuf(o_buf, o_idx)
*/
int seekable()
{
- return fseekable(zfile);
+ return fseekable(y);
}
#endif /* ?USE_ZLIB */
@@ -951,10 +1414,8 @@ int seekable()
/* ===========================================================================
* Compression to archive file.
*/
-
-local ulg filecompress(z_entry, zipfile, cmpr_method)
+local zoff_t filecompress(z_entry, cmpr_method)
struct zlist far *z_entry;
- FILE *zipfile;
int *cmpr_method;
{
#ifdef USE_ZLIB
@@ -970,6 +1431,7 @@ local ulg filecompress(z_entry, zipfile, cmpr_method)
#ifndef OBUF_SZ
# define OBUF_SZ ZBSZ
#endif
+ unsigned u;
#if defined(MMAP) || defined(BIG_MEM)
if (remain == (ulg)-1L && f_ibuf == NULL)
@@ -1026,21 +1488,41 @@ local ulg filecompress(z_entry, zipfile, cmpr_method)
ziperr(ZE_LOGIC, errbuf);
}
if (zstrm.avail_out == 0) {
- if (zfwrite(f_obuf, 1, OBUF_SZ, zipfile) != OBUF_SZ) {
+ if (zfwrite(f_obuf, 1, OBUF_SZ) != OBUF_SZ) {
ziperr(ZE_TEMP, "error writing to zipfile");
}
zstrm.next_out = (Bytef *)f_obuf;
zstrm.avail_out = OBUF_SZ;
}
if (zstrm.avail_in == 0) {
- if (verbose)
+ if (verbose || noisy)
while((unsigned)(zstrm.total_in / (uLong)WSIZE) > mrk_cnt) {
mrk_cnt++;
+ if (!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++;
+ if (dot_size <= (dot_count + 1) * WSIZE) dot_count = 0;
+ }
+ if (noisy && dot_size && !dot_count) {
#ifndef WINDLL
- putc('.', stderr);
+ putc('.', mesg);
+ fflush(mesg);
#else
- fprintf(stdout,"%c",'.');
+ fprintf(stdout,"%c",'.');
#endif
+ mesg_line_started = 1;
+ }
+ }
}
#if defined(MMAP) || defined(BIG_MEM)
if (remain == (ulg)-1L)
@@ -1059,7 +1541,7 @@ local ulg filecompress(z_entry, zipfile, cmpr_method)
fseekable(zipfile)) {
/* deflation does not reduce size, switch to STORE method */
unsigned len_out = (unsigned)zstrm.total_in;
- if (zfwrite(f_ibuf, 1, len_out, zipfile) != len_out) {
+ if (zfwrite(f_ibuf, 1, len_out) != len_out) {
ziperr(ZE_TEMP, "error writing to zipfile");
}
zstrm.total_out = (uLong)len_out;
@@ -1071,7 +1553,7 @@ local ulg filecompress(z_entry, zipfile, cmpr_method)
}
if (zstrm.avail_out < OBUF_SZ) {
unsigned len_out = OBUF_SZ - zstrm.avail_out;
- if (zfwrite(f_obuf, 1, len_out, zipfile) != len_out) {
+ if (zfwrite(f_obuf, 1, len_out) != len_out) {
ziperr(ZE_TEMP, "error writing to zipfile");
}
zstrm.next_out = (Bytef *)f_obuf;
@@ -1094,7 +1576,6 @@ local ulg filecompress(z_entry, zipfile, cmpr_method)
#else /* !USE_ZLIB */
/* Set the defaults for file compression. */
- zfile = zipfile;
read_buf = file_read;
/* Initialize deflate's internals and execute file compression. */
@@ -1155,7 +1636,6 @@ ulg memcompress(tgt, tgtsize, src, srcsize)
if ((err = deflateReset(&zstrm)) != Z_OK)
error("zlib deflateReset failed");
#else /* !USE_ZLIB */
- zfile = NULL;
read_buf = mem_read;
in_buf = src;
in_size = (unsigned)srcsize;
@@ -1183,4 +1663,260 @@ ulg memcompress(tgt, tgtsize, src, srcsize)
return (ulg)out_total;
}
#endif /* ZP_NEED_MEMCOMPR */
+
+#ifdef BZIP2_SUPPORT
+
+local int bz_compress_init(pack_level)
+int pack_level;
+{
+ int err = BZ_OK;
+ int zp_err = ZE_OK;
+ const char *bzlibVer;
+
+ bzlibVer = BZ2_bzlibVersion();
+
+ /* $TODO - Check BZIP2 LIB version? */
+
+ bstrm.bzalloc = NULL;
+ bstrm.bzfree = NULL;
+ bstrm.opaque = NULL;
+
+ Trace((stderr, "initializing bzlib compress()\n"));
+ err = BZ2_bzCompressInit(&bstrm, pack_level, 0, 30);
+
+ if (err == BZ_MEM_ERROR) {
+ sprintf(errbuf, "cannot initialize bzlib compress");
+ zp_err = ZE_MEM;
+ } else if (err != BZ_OK) {
+ sprintf(errbuf, "bzlib bzCompressInit failure (%d)", err);
+ zp_err = ZE_LOGIC;
+ }
+
+ bzipInit = TRUE;
+ return zp_err;
+}
+
+void bz_compress_free()
+{
+ int err;
+
+ if (f_obuf != NULL) {
+ free(f_obuf);
+ f_obuf = NULL;
+ }
+ if (f_ibuf != NULL) {
+ free(f_ibuf);
+ f_ibuf = NULL;
+ }
+ if (bzipInit) {
+ err = BZ2_bzCompressEnd(&bstrm);
+ if (err != BZ_OK && err != BZ_DATA_ERROR) {
+ ziperr(ZE_LOGIC, "bzlib bzCompressEnd failed");
+ }
+ bzipInit = FALSE;
+ }
+}
+
+/* ===========================================================================
+ * BZIP2 Compression to archive file.
+ */
+
+local zoff_t bzfilecompress(z_entry, cmpr_method)
+struct zlist far *z_entry;
+int *cmpr_method;
+{
+ FILE *zipfile = y;
+
+ int err = BZ_OK;
+ unsigned mrk_cnt = 1;
+ int maybe_stored = FALSE;
+ zoff_t cmpr_size;
+#if defined(MMAP) || defined(BIG_MEM)
+ unsigned ibuf_sz = (unsigned)SBSZ;
+#else
+# define ibuf_sz ((unsigned)SBSZ)
+#endif
+#ifndef OBUF_SZ
+# define OBUF_SZ ZBSZ
+#endif
+
+#if defined(MMAP) || defined(BIG_MEM)
+ if (remain == (ulg)-1L && f_ibuf == NULL)
+#else /* !(MMAP || BIG_MEM */
+ if (f_ibuf == NULL)
+#endif /* MMAP || BIG_MEM */
+ f_ibuf = (char *)malloc(SBSZ);
+ if (f_obuf == NULL)
+ f_obuf = (char *)malloc(OBUF_SZ);
+#if defined(MMAP) || defined(BIG_MEM)
+ if ((remain == (ulg)-1L && f_ibuf == NULL) || f_obuf == NULL)
+#else /* !(MMAP || BIG_MEM */
+ if (f_ibuf == NULL || f_obuf == NULL)
+#endif /* MMAP || BIG_MEM */
+ ziperr(ZE_MEM, "allocating zlib/bzlib file-I/O buffers");
+
+ if (!bzipInit) {
+ err = bz_compress_init(level);
+ if (err != ZE_OK)
+ ziperr(err, errbuf);
+ }
+
+#if defined(MMAP) || defined(BIG_MEM)
+ if (remain != (ulg)-1L) {
+ bstrm.next_in = (Bytef *)window;
+ ibuf_sz = (unsigned)WSIZE;
+ } else
+#endif /* MMAP || BIG_MEM */
+ {
+ bstrm.next_in = (char *)f_ibuf;
+ }
+ bstrm.avail_in = file_read(bstrm.next_in, ibuf_sz);
+ if (file_binary_final == 0) {
+ /* check for binary as library does not */
+ if (!is_text_buf(bstrm.next_in, ibuf_sz))
+ file_binary_final = 1;
+ }
+ if (bstrm.avail_in < ibuf_sz) {
+ unsigned more = file_read(bstrm.next_in + bstrm.avail_in,
+ (ibuf_sz - bstrm.avail_in));
+ if (more == (unsigned) EOF || more == 0) {
+ maybe_stored = TRUE;
+ } else {
+ bstrm.avail_in += more;
+ }
+ }
+ bstrm.next_out = (char *)f_obuf;
+ bstrm.avail_out = OBUF_SZ;
+
+ if (!maybe_stored) {
+ while (bstrm.avail_in != 0 && bstrm.avail_in != (unsigned) EOF) {
+ err = BZ2_bzCompress(&bstrm, BZ_RUN);
+ if (err != BZ_RUN_OK && err != BZ_STREAM_END) {
+ sprintf(errbuf, "unexpected bzlib compress error %d", err);
+ ziperr(ZE_LOGIC, errbuf);
+ }
+ if (bstrm.avail_out == 0) {
+ if (zfwrite(f_obuf, 1, OBUF_SZ) != OBUF_SZ) {
+ ziperr(ZE_TEMP, "error writing to zipfile");
+ }
+ bstrm.next_out = (char *)f_obuf;
+ bstrm.avail_out = OBUF_SZ;
+ }
+ /* $TODO what about high 32-bits of total-in??? */
+ if (bstrm.avail_in == 0) {
+ if (verbose || noisy)
+#ifdef LARGE_FILE_SUPPORT
+ while((unsigned)((bstrm.total_in_lo32
+ + (((zoff_t)bstrm.total_in_hi32) << 32))
+ / (zoff_t)(ulg)WSIZE) > mrk_cnt) {
+#else
+ while((unsigned)(bstrm.total_in_lo32 / (ulg)WSIZE) > mrk_cnt) {
+#endif
+ mrk_cnt++;
+ if (!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++;
+ if (dot_size <= (dot_count + 1) * WSIZE) dot_count = 0;
+ }
+ if (noisy && dot_size && !dot_count) {
+#ifndef WINDLL
+ putc('.', mesg);
+ fflush(mesg);
+#else
+ fprintf(stdout,"%c",'.');
+#endif
+ mesg_line_started = 1;
+ }
+ }
+ }
+#if defined(MMAP) || defined(BIG_MEM)
+ if (remain == (ulg)-1L)
+ bstrm.next_in = (char *)f_ibuf;
+#else
+ bstrm.next_in = (char *)f_ibuf;
+#endif
+ bstrm.avail_in = file_read(bstrm.next_in, ibuf_sz);
+ if (file_binary_final == 0) {
+ /* check for binary as library does not */
+ if (!is_text_buf(bstrm.next_in, ibuf_sz))
+ file_binary_final = 1;
+ }
+ }
+ }
+ }
+
+ /* binary or text */
+ if (file_binary_final)
+ /* found binary in file */
+ z_entry->att = (ush)BINARY;
+ else
+ /* text file */
+ z_entry->att = (ush)ASCII;
+
+ do {
+ err = BZ2_bzCompress(&bstrm, BZ_FINISH);
+ if (maybe_stored) {
+ /* This code is only executed when the complete data stream fits
+ into the input buffer (see above where maybe_stored gets set).
+ So, it is safe to assume that total_in_hi32 (and total_out_hi32)
+ are 0, because the input buffer size is well below the 32-bit
+ limit.
+ */
+ if (err == BZ_STREAM_END
+ && bstrm.total_out_lo32 >= bstrm.total_in_lo32
+ && fseekable(zipfile)) {
+ /* BZIP2 compress does not reduce size,
+ switch to STORE method */
+ unsigned len_out = (unsigned)bstrm.total_in_lo32;
+ if (zfwrite(f_ibuf, 1, len_out) != len_out) {
+ ziperr(ZE_TEMP, "error writing to zipfile");
+ }
+ bstrm.total_out_lo32 = (ulg)len_out;
+ *cmpr_method = STORE;
+ break;
+ } else {
+ maybe_stored = FALSE;
+ }
+ }
+ if (bstrm.avail_out < OBUF_SZ) {
+ unsigned len_out = OBUF_SZ - bstrm.avail_out;
+ if (zfwrite(f_obuf, 1, len_out) != len_out) {
+ ziperr(ZE_TEMP, "error writing to zipfile");
+ }
+ bstrm.next_out = (char *)f_obuf;
+ bstrm.avail_out = OBUF_SZ;
+ }
+ } while (err == BZ_FINISH_OK);
+
+ if (err < BZ_OK) {
+ sprintf(errbuf, "unexpected bzlib compress error %d", err);
+ ziperr(ZE_LOGIC, errbuf);
+ }
+
+ if (z_entry->att == (ush)UNKNOWN)
+ z_entry->att = (ush)BINARY;
+#ifdef LARGE_FILE_SUPPORT
+ cmpr_size = (zoff_t)bstrm.total_out_lo32
+ + (((zoff_t)bstrm.total_out_hi32) << 32);
+#else
+ cmpr_size = (zoff_t)bstrm.total_out_lo32;
+#endif
+
+ if ((err = BZ2_bzCompressEnd(&bstrm)) != BZ_OK)
+ ziperr(ZE_LOGIC, "zlib deflateReset failed");
+ bzipInit = FALSE;
+ return cmpr_size;
+}
+
+#endif /* BZIP2_SUPPORT */
#endif /* !UTIL */