From 04664087ad66f5614f82a2cfba3ae4eda15e792b Mon Sep 17 00:00:00 2001 From: Lorry Date: Fri, 20 Jul 2012 19:30:57 +0100 Subject: Tarball conversion --- BUGS | 6 + Betas_Readme.txt | 17 + CHANGES | 3460 ++++++++++++++++++++ INSTALL | 368 +++ LICENSE | 60 + README | 234 ++ README.CR | 119 + TODO | 142 + USexport.msg | 75 + WHATSNEW | 333 ++ WHERE | 261 ++ acorn/GMakefile | 130 + acorn/ReadMe | 85 + acorn/ReadMe.GMakefile | 16 + acorn/RunMe1st | 23 + acorn/acornzip.c | 592 ++++ acorn/makefile | 115 + acorn/match.s | 217 ++ acorn/osdep.h | 28 + acorn/riscos.c | 394 +++ acorn/riscos.h | 119 + acorn/sendbits.s | 105 + acorn/srcrename | Bin 0 -> 6175 bytes acorn/swiven.h | 59 + acorn/swiven.s | 276 ++ acorn/zipsfx | 9 + acorn/zipup.h | 16 + amiga/LMKfile | 117 + amiga/README | 1 + amiga/amiga.c | 138 + amiga/amiga.h | 54 + amiga/amigazip.c | 507 +++ amiga/crc_68.a | 144 + amiga/deflate.a | 1053 ++++++ amiga/filedate.c | 599 ++++ amiga/makefile.azt | 304 ++ amiga/match.a | 182 ++ amiga/match_68.a | 273 ++ amiga/osdep.h | 119 + amiga/smakefile | 662 ++++ amiga/stat.c | 293 ++ amiga/z-stat.h | 95 + amiga/zipup.h | 25 + aosvs/aosvs.c | 659 ++++ aosvs/make.cli | 5 + api.c | 718 +++++ api.h | 184 ++ atari/Makefile | 111 + atari/README | 5 + atari/atari.c | 681 ++++ atari/make_all.mup | 7 + atari/make_zip.mup | 7 + atari/osdep.h | 20 + atari/zipup.h | 19 + atheos/Makefile | 146 + atheos/README | 21 + atheos/atheos.c | 885 +++++ atheos/osdep.h | 64 + atheos/zipup.h | 24 + beos/Contents | 14 + beos/Makefile | 182 ++ beos/README | 31 + beos/beos.c | 945 ++++++ beos/osdep.h | 59 + beos/zipup.h | 19 + bzip2/install.txt | 258 ++ cmsmvs/README.CMS | 434 +++ cmsmvs/README.MVS | 92 + cmsmvs/README.MVS.LE | 286 ++ cmsmvs/cczip.exec | 123 + cmsmvs/cms.c | 34 + cmsmvs/cmsmvs.c | 442 +++ cmsmvs/cmsmvs.h | 123 + cmsmvs/cstat.h | 53 + cmsmvs/mc.exec | 95 + cmsmvs/mvs.c | 221 ++ cmsmvs/mvs.h | 40 + cmsmvs/mvs.mki | 125 + cmsmvs/pipzip.rexx | 27 + cmsmvs/zip.exec | 66 + cmsmvs/zip.makefile | 21 + cmsmvs/zipcloak.exec | 66 + cmsmvs/zipmvsc.job | 89 + cmsmvs/zipname.conven | 200 ++ cmsmvs/zipnote.exec | 66 + cmsmvs/zipsplit.exec | 66 + cmsmvs/zipup.h | 18 + cmsmvs/zipvmc.exec | 48 + crc32.c | 732 +++++ crc32.h | 60 + crc_i386.S | 304 ++ crypt.c | 690 ++++ crypt.h | 169 + deflate.c | 929 ++++++ ebcdic.h | 328 ++ file_id.diz | 15 + fileio.c | 4903 ++++++++++++++++++++++++++++ globals.c | 253 ++ human68k/Makefile | 95 + human68k/Makefile.gcc | 78 + human68k/crc_68.s | 144 + human68k/deflate.s | 1076 ++++++ human68k/human68k.c | 371 +++ human68k/match.s | 163 + human68k/osdep.h | 28 + human68k/zipup.h | 16 + macos/Contents | 63 + macos/HISTORY.TXT | 600 ++++ macos/README.TXT | 569 ++++ macos/ZipLib.h | 166 + macos/ZipSx.h | 167 + macos/ZpPrj.hqx | 455 +++ macos/osdep.h | 118 + macos/readme.1st | 16 + macos/source/VolWarn.h | 69 + macos/source/charmap.h | 380 +++ macos/source/extrafld.c | 920 ++++++ macos/source/getenv.c | 398 +++ macos/source/helpers.c | 479 +++ macos/source/helpers.h | 57 + macos/source/macglob.h | 86 + macos/source/macopen.c | 363 +++ macos/source/macopen.h | 21 + macos/source/macos.c | 1079 +++++++ macos/source/macstuff.c | 1724 ++++++++++ macos/source/macstuff.h | 18 + macos/source/mactime.c | 451 +++ macos/source/mactime.h | 61 + macos/source/pathname.c | 726 +++++ macos/source/pathname.h | 64 + macos/source/recurse.c | 442 +++ macos/source/recurse.h | 129 + macos/source/unixlike.c | 313 ++ macos/source/unixlike.h | 86 + macos/source/zip_rc.hqx | 43 + macos/zipup.h | 25 + man/zip.1 | 2840 ++++++++++++++++ man/zipcloak.1 | 111 + man/zipnote.1 | 85 + man/zipsplit.1 | 69 + match.S | 407 +++ msdos/README.DOS | 132 + msdos/crc_i86.asm | 497 +++ msdos/makebz2.dj2 | 148 + msdos/makefile.bor | 197 ++ msdos/makefile.dj1 | 126 + msdos/makefile.dj2 | 136 + msdos/makefile.emx | 169 + msdos/makefile.msc | 209 ++ msdos/makefile.tc | 177 + msdos/makefile.wat | 256 ++ msdos/match.asm | 477 +++ msdos/msdos.c | 1126 +++++++ msdos/osdep.h | 218 ++ msdos/zipup.h | 16 + novell/MAKEINIT | 71 + novell/Makefile | 142 + novell/Netware.c | 970 ++++++ novell/README | 9 + novell/m.cmd | 9 + novell/osdep.h | 205 ++ novell/signal.c | 49 + novell/zip.lnk | 25 + novell/zipup.h | 16 + os2/makefile.os2 | 563 ++++ os2/match32.asm | 175 + os2/os2.c | 481 +++ os2/os2acl.c | 385 +++ os2/os2acl.h | 34 + os2/os2zip.c | 1213 +++++++ os2/os2zip.h | 84 + os2/osdep.h | 173 + os2/zip.def | 3 + os2/zipup.h | 16 + proginfo/3rdparty.bug | 114 + proginfo/ZipPorts | 285 ++ proginfo/algorith.txt | 68 + proginfo/ebcdic.msg | 63 + proginfo/extrafld.txt | 1372 ++++++++ proginfo/fileinfo.cms | 231 ++ proginfo/infozip.who | 242 ++ proginfo/ntsd.txt | 111 + proginfo/perform.dos | 183 ++ proginfo/timezone.txt | 85 + proginfo/txtvsbin.txt | 112 + proginfo/ziplimit.txt | 243 ++ qdos/IZREADME.SMS | 600 ++++ qdos/Makefile.qdos | 145 + qdos/Makefile.qlzip | 141 + qdos/config.s | 153 + qdos/crc68.s | 99 + qdos/match.s | 138 + qdos/osdep.h | 33 + qdos/qdos.c | 879 +++++ qdos/qfileio.c | 233 ++ qdos/zipup.h | 19 + revision.h | 139 + tailor.h | 887 +++++ tandem/HISTORY | 97 + tandem/README | 95 + tandem/commacs | 94 + tandem/doit | 21 + tandem/macros | 571 ++++ tandem/make | 130 + tandem/tandem.c | 889 +++++ tandem/tandem.h | 236 ++ tandem/tannsk.h | 19 + tandem/tanzip.c | 723 +++++ tandem/tanzip.h | 43 + tandem/zipup.h | 26 + theos/Makefile | 138 + theos/README | 34 + theos/_chmod.c | 21 + theos/_fprintf.c | 26 + theos/_isatty.c | 26 + theos/_rename.c | 83 + theos/_setargv.c | 140 + theos/_stat.c | 461 +++ theos/charconv.h | 93 + theos/osdep.h | 58 + theos/stat.h | 106 + theos/theos.c | 556 ++++ theos/zipup.h | 19 + timezone.c | 815 +++++ timezone.h | 83 + tops20/make.mic | 35 + tops20/osdep.h | 31 + tops20/rename.mic | 6 + tops20/tops20.c | 574 ++++ tops20/zipup.h | 18 + trees.c | 1474 +++++++++ ttyio.c | 702 ++++ ttyio.h | 229 ++ unix/Makefile | 329 ++ unix/Packaging/README | 44 + unix/Packaging/pkginfo.in | 13 + unix/Packaging/postinstall | 29 + unix/Packaging/preinstall.in | 29 + unix/Packaging/prototype | 29 + unix/README.OS390 | 85 + unix/configure | 695 ++++ unix/osdep.h | 80 + unix/unix.c | 1100 +++++++ unix/zipup.h | 24 + util.c | 1450 +++++++++ vms/NOTES.TXT | 382 +++ vms/VMS_ZIP.RNH | 1467 +++++++++ vms/build_zip.com | 690 ++++ vms/bzlib.h | 21 + vms/cmdline.c | 1802 +++++++++++ vms/collect_deps.com | 89 + vms/cvthelp.tpu | 182 ++ vms/descrip.mms | 358 ++ vms/descrip_deps.mms | 207 ++ vms/descrip_mkdeps.mms | 247 ++ vms/descrip_src.mms | 373 +++ vms/find_bzip2_lib.com | 71 + vms/hlp_lib_next.com | 17 + vms/install_vms.txt | 158 + vms/mod_dep.com | 33 + vms/osdep.h | 178 + vms/stream_lf.fdl | 3 + vms/unixio_gcc.h | 27 + vms/unixlib_gcc.h | 16 + vms/vms.c | 1007 ++++++ vms/vms.h | 354 ++ vms/vms_im.c | 926 ++++++ vms/vms_msg_gen.c | 91 + vms/vms_pk.c | 600 ++++ vms/vmsdefs.h | 320 ++ vms/vmsmunch.c | 434 +++ vms/vmsmunch.h | 55 + vms/vmszip.c | 1444 +++++++++ vms/zip.opt | 1 + vms/zip_cli.cld | 168 + vms/zip_cli.help | 1636 ++++++++++ vms/zip_msg.msg | 57 + vms/zipup.h | 56 + win32/README.NT | 17 + win32/README.TZ | 7 + win32/README.txt | 10 + win32/crc_i386.asm | 330 ++ win32/crc_i386.c | 310 ++ win32/crc_lcc.asm | 166 + win32/gvmat64.asm | 513 +++ win32/lm32_lcc.asm | 174 + win32/makefile.a64 | 134 + win32/makefile.bor | 189 ++ win32/makefile.dj | 112 + win32/makefile.emx | 304 ++ win32/makefile.gcc | 159 + win32/makefile.ibm | 123 + win32/makefile.lcc | 125 + win32/makefile.w10 | 197 ++ win32/makefile.w32 | 224 ++ win32/makefile.wat | 197 ++ win32/makenoas.w32 | 219 ++ win32/match32.asm | 192 ++ win32/nt.c | 492 +++ win32/nt.h | 75 + win32/osdep.h | 617 ++++ win32/readme.a64 | 42 + win32/rsxntwin.h | 173 + win32/vc6/ReadmeVC.txt | 10 + win32/vc6/zip.dsp | 337 ++ win32/vc6/zip.dsw | 65 + win32/vc6/zipcloak.dsp | 264 ++ win32/vc6/zipnote.dsp | 248 ++ win32/vc6/zipsplit.dsp | 248 ++ win32/vc6bz2/ReadVCBZ.txt | 19 + win32/vc6bz2/zip.dsp | 381 +++ win32/vc6bz2/zip.dsw | 65 + win32/win32.c | 1488 +++++++++ win32/win32i64.c | 115 + win32/win32zip.c | 1980 ++++++++++++ win32/win32zip.h | 42 + win32/zip.def | 4 + win32/zip.rc | 53 + win32/zipup.h | 48 + windll/VBz64/VBZIP.VBP | 33 + windll/VBz64/VBZIP.vbw | 2 + windll/VBz64/VBZipBas.bas | 737 +++++ windll/VBz64/Vbzipfrm.frm | 183 ++ windll/VBz64/readVB64.txt | 25 + windll/Vb/VBZIP.vbw | 2 + windll/Vb/VBZipBas.bas | 458 +++ windll/Vb/Vbzip.vbp | 34 + windll/Vb/Vbzipfrm.frm | 130 + windll/Vb/readmeVB.txt | 34 + windll/contents | 42 + windll/example.c | 375 +++ windll/example.h | 54 + windll/structs.h | 30 + windll/visualc/dll/zip32z64.dsp | 168 + windll/visualc/dll/zip32z64.dsw | 29 + windll/visualc/lib/zip32z64.dsp | 158 + windll/visualc/lib/zip32z64.dsw | 29 + windll/windll.aps | Bin 0 -> 1652 bytes windll/windll.c | 176 + windll/windll.h | 63 + windll/windll.rc | 57 + windll/windll.txt | 147 + windll/windll16.def | 15 + windll/windll32.def | 14 + windll/ziplib.def | 15 + zbz2err.c | 61 + zip.c | 6018 ++++++++++++++++++++++++++++++++++ zip.h | 1081 +++++++ zip.txt | 2027 ++++++++++++ zip30.ann | 95 + zip30f.ann | 61 + zip30g.ann | 33 + zip30h.ann | 47 + zipcloak.c | 771 +++++ zipcloak.txt | 75 + ziperr.h | 115 + zipfile.c | 6820 +++++++++++++++++++++++++++++++++++++++ zipnote.c | 699 ++++ zipnote.txt | 63 + zipsplit.c | 978 ++++++ zipsplit.txt | 53 + zipup.c | 1922 +++++++++++ 362 files changed, 119106 insertions(+) create mode 100644 BUGS create mode 100644 Betas_Readme.txt create mode 100644 CHANGES create mode 100644 INSTALL create mode 100644 LICENSE create mode 100644 README create mode 100644 README.CR create mode 100644 TODO create mode 100644 USexport.msg create mode 100644 WHATSNEW create mode 100644 WHERE create mode 100644 acorn/GMakefile create mode 100644 acorn/ReadMe create mode 100644 acorn/ReadMe.GMakefile create mode 100644 acorn/RunMe1st create mode 100644 acorn/acornzip.c create mode 100644 acorn/makefile create mode 100644 acorn/match.s create mode 100644 acorn/osdep.h create mode 100644 acorn/riscos.c create mode 100644 acorn/riscos.h create mode 100644 acorn/sendbits.s create mode 100644 acorn/srcrename create mode 100644 acorn/swiven.h create mode 100644 acorn/swiven.s create mode 100644 acorn/zipsfx create mode 100644 acorn/zipup.h create mode 100644 amiga/LMKfile create mode 100644 amiga/README create mode 100644 amiga/amiga.c create mode 100644 amiga/amiga.h create mode 100644 amiga/amigazip.c create mode 100644 amiga/crc_68.a create mode 100644 amiga/deflate.a create mode 100644 amiga/filedate.c create mode 100644 amiga/makefile.azt create mode 100644 amiga/match.a create mode 100644 amiga/match_68.a create mode 100644 amiga/osdep.h create mode 100644 amiga/smakefile create mode 100644 amiga/stat.c create mode 100644 amiga/z-stat.h create mode 100644 amiga/zipup.h create mode 100644 aosvs/aosvs.c create mode 100644 aosvs/make.cli create mode 100644 api.c create mode 100644 api.h create mode 100644 atari/Makefile create mode 100644 atari/README create mode 100644 atari/atari.c create mode 100644 atari/make_all.mup create mode 100644 atari/make_zip.mup create mode 100644 atari/osdep.h create mode 100644 atari/zipup.h create mode 100644 atheos/Makefile create mode 100644 atheos/README create mode 100644 atheos/atheos.c create mode 100644 atheos/osdep.h create mode 100644 atheos/zipup.h create mode 100644 beos/Contents create mode 100644 beos/Makefile create mode 100644 beos/README create mode 100644 beos/beos.c create mode 100644 beos/osdep.h create mode 100644 beos/zipup.h create mode 100644 bzip2/install.txt create mode 100644 cmsmvs/README.CMS create mode 100644 cmsmvs/README.MVS create mode 100644 cmsmvs/README.MVS.LE create mode 100644 cmsmvs/cczip.exec create mode 100644 cmsmvs/cms.c create mode 100644 cmsmvs/cmsmvs.c create mode 100644 cmsmvs/cmsmvs.h create mode 100644 cmsmvs/cstat.h create mode 100644 cmsmvs/mc.exec create mode 100644 cmsmvs/mvs.c create mode 100644 cmsmvs/mvs.h create mode 100644 cmsmvs/mvs.mki create mode 100644 cmsmvs/pipzip.rexx create mode 100644 cmsmvs/zip.exec create mode 100644 cmsmvs/zip.makefile create mode 100644 cmsmvs/zipcloak.exec create mode 100644 cmsmvs/zipmvsc.job create mode 100644 cmsmvs/zipname.conven create mode 100644 cmsmvs/zipnote.exec create mode 100644 cmsmvs/zipsplit.exec create mode 100644 cmsmvs/zipup.h create mode 100644 cmsmvs/zipvmc.exec create mode 100644 crc32.c create mode 100644 crc32.h create mode 100644 crc_i386.S create mode 100644 crypt.c create mode 100644 crypt.h create mode 100644 deflate.c create mode 100644 ebcdic.h create mode 100644 file_id.diz create mode 100644 fileio.c create mode 100644 globals.c create mode 100644 human68k/Makefile create mode 100644 human68k/Makefile.gcc create mode 100644 human68k/crc_68.s create mode 100644 human68k/deflate.s create mode 100644 human68k/human68k.c create mode 100644 human68k/match.s create mode 100644 human68k/osdep.h create mode 100644 human68k/zipup.h create mode 100644 macos/Contents create mode 100644 macos/HISTORY.TXT create mode 100644 macos/README.TXT create mode 100644 macos/ZipLib.h create mode 100644 macos/ZipSx.h create mode 100644 macos/ZpPrj.hqx create mode 100644 macos/osdep.h create mode 100644 macos/readme.1st create mode 100644 macos/source/VolWarn.h create mode 100644 macos/source/charmap.h create mode 100644 macos/source/extrafld.c create mode 100644 macos/source/getenv.c create mode 100644 macos/source/helpers.c create mode 100644 macos/source/helpers.h create mode 100644 macos/source/macglob.h create mode 100644 macos/source/macopen.c create mode 100644 macos/source/macopen.h create mode 100644 macos/source/macos.c create mode 100644 macos/source/macstuff.c create mode 100644 macos/source/macstuff.h create mode 100644 macos/source/mactime.c create mode 100644 macos/source/mactime.h create mode 100644 macos/source/pathname.c create mode 100644 macos/source/pathname.h create mode 100644 macos/source/recurse.c create mode 100644 macos/source/recurse.h create mode 100644 macos/source/unixlike.c create mode 100644 macos/source/unixlike.h create mode 100644 macos/source/zip_rc.hqx create mode 100644 macos/zipup.h create mode 100644 man/zip.1 create mode 100644 man/zipcloak.1 create mode 100644 man/zipnote.1 create mode 100644 man/zipsplit.1 create mode 100644 match.S create mode 100644 msdos/README.DOS create mode 100644 msdos/crc_i86.asm create mode 100644 msdos/makebz2.dj2 create mode 100644 msdos/makefile.bor create mode 100644 msdos/makefile.dj1 create mode 100644 msdos/makefile.dj2 create mode 100644 msdos/makefile.emx create mode 100644 msdos/makefile.msc create mode 100644 msdos/makefile.tc create mode 100644 msdos/makefile.wat create mode 100644 msdos/match.asm create mode 100644 msdos/msdos.c create mode 100644 msdos/osdep.h create mode 100644 msdos/zipup.h create mode 100644 novell/MAKEINIT create mode 100644 novell/Makefile create mode 100644 novell/Netware.c create mode 100644 novell/README create mode 100644 novell/m.cmd create mode 100644 novell/osdep.h create mode 100644 novell/signal.c create mode 100644 novell/zip.lnk create mode 100644 novell/zipup.h create mode 100644 os2/makefile.os2 create mode 100644 os2/match32.asm create mode 100644 os2/os2.c create mode 100644 os2/os2acl.c create mode 100644 os2/os2acl.h create mode 100644 os2/os2zip.c create mode 100644 os2/os2zip.h create mode 100644 os2/osdep.h create mode 100644 os2/zip.def create mode 100644 os2/zipup.h create mode 100644 proginfo/3rdparty.bug create mode 100644 proginfo/ZipPorts create mode 100644 proginfo/algorith.txt create mode 100644 proginfo/ebcdic.msg create mode 100644 proginfo/extrafld.txt create mode 100644 proginfo/fileinfo.cms create mode 100644 proginfo/infozip.who create mode 100644 proginfo/ntsd.txt create mode 100644 proginfo/perform.dos create mode 100644 proginfo/timezone.txt create mode 100644 proginfo/txtvsbin.txt create mode 100644 proginfo/ziplimit.txt create mode 100644 qdos/IZREADME.SMS create mode 100644 qdos/Makefile.qdos create mode 100644 qdos/Makefile.qlzip create mode 100644 qdos/config.s create mode 100644 qdos/crc68.s create mode 100644 qdos/match.s create mode 100644 qdos/osdep.h create mode 100644 qdos/qdos.c create mode 100644 qdos/qfileio.c create mode 100644 qdos/zipup.h create mode 100644 revision.h create mode 100644 tailor.h create mode 100644 tandem/HISTORY create mode 100644 tandem/README create mode 100644 tandem/commacs create mode 100644 tandem/doit create mode 100644 tandem/macros create mode 100644 tandem/make create mode 100644 tandem/tandem.c create mode 100644 tandem/tandem.h create mode 100644 tandem/tannsk.h create mode 100644 tandem/tanzip.c create mode 100644 tandem/tanzip.h create mode 100644 tandem/zipup.h create mode 100644 theos/Makefile create mode 100644 theos/README create mode 100644 theos/_chmod.c create mode 100644 theos/_fprintf.c create mode 100644 theos/_isatty.c create mode 100644 theos/_rename.c create mode 100644 theos/_setargv.c create mode 100644 theos/_stat.c create mode 100644 theos/charconv.h create mode 100644 theos/osdep.h create mode 100644 theos/stat.h create mode 100644 theos/theos.c create mode 100644 theos/zipup.h create mode 100644 timezone.c create mode 100644 timezone.h create mode 100644 tops20/make.mic create mode 100644 tops20/osdep.h create mode 100644 tops20/rename.mic create mode 100644 tops20/tops20.c create mode 100644 tops20/zipup.h create mode 100644 trees.c create mode 100644 ttyio.c create mode 100644 ttyio.h create mode 100644 unix/Makefile create mode 100644 unix/Packaging/README create mode 100644 unix/Packaging/pkginfo.in create mode 100644 unix/Packaging/postinstall create mode 100644 unix/Packaging/preinstall.in create mode 100644 unix/Packaging/prototype create mode 100644 unix/README.OS390 create mode 100644 unix/configure create mode 100644 unix/osdep.h create mode 100644 unix/unix.c create mode 100644 unix/zipup.h create mode 100644 util.c create mode 100644 vms/NOTES.TXT create mode 100644 vms/VMS_ZIP.RNH create mode 100644 vms/build_zip.com create mode 100644 vms/bzlib.h create mode 100644 vms/cmdline.c create mode 100644 vms/collect_deps.com create mode 100644 vms/cvthelp.tpu create mode 100644 vms/descrip.mms create mode 100644 vms/descrip_deps.mms create mode 100644 vms/descrip_mkdeps.mms create mode 100644 vms/descrip_src.mms create mode 100644 vms/find_bzip2_lib.com create mode 100644 vms/hlp_lib_next.com create mode 100644 vms/install_vms.txt create mode 100644 vms/mod_dep.com create mode 100644 vms/osdep.h create mode 100644 vms/stream_lf.fdl create mode 100644 vms/unixio_gcc.h create mode 100644 vms/unixlib_gcc.h create mode 100644 vms/vms.c create mode 100644 vms/vms.h create mode 100644 vms/vms_im.c create mode 100644 vms/vms_msg_gen.c create mode 100644 vms/vms_pk.c create mode 100644 vms/vmsdefs.h create mode 100644 vms/vmsmunch.c create mode 100644 vms/vmsmunch.h create mode 100644 vms/vmszip.c create mode 100644 vms/zip.opt create mode 100644 vms/zip_cli.cld create mode 100644 vms/zip_cli.help create mode 100644 vms/zip_msg.msg create mode 100644 vms/zipup.h create mode 100644 win32/README.NT create mode 100644 win32/README.TZ create mode 100644 win32/README.txt create mode 100644 win32/crc_i386.asm create mode 100644 win32/crc_i386.c create mode 100644 win32/crc_lcc.asm create mode 100644 win32/gvmat64.asm create mode 100644 win32/lm32_lcc.asm create mode 100644 win32/makefile.a64 create mode 100644 win32/makefile.bor create mode 100644 win32/makefile.dj create mode 100644 win32/makefile.emx create mode 100644 win32/makefile.gcc create mode 100644 win32/makefile.ibm create mode 100644 win32/makefile.lcc create mode 100644 win32/makefile.w10 create mode 100644 win32/makefile.w32 create mode 100644 win32/makefile.wat create mode 100644 win32/makenoas.w32 create mode 100644 win32/match32.asm create mode 100644 win32/nt.c create mode 100644 win32/nt.h create mode 100644 win32/osdep.h create mode 100644 win32/readme.a64 create mode 100644 win32/rsxntwin.h create mode 100644 win32/vc6/ReadmeVC.txt create mode 100644 win32/vc6/zip.dsp create mode 100644 win32/vc6/zip.dsw create mode 100644 win32/vc6/zipcloak.dsp create mode 100644 win32/vc6/zipnote.dsp create mode 100644 win32/vc6/zipsplit.dsp create mode 100644 win32/vc6bz2/ReadVCBZ.txt create mode 100644 win32/vc6bz2/zip.dsp create mode 100644 win32/vc6bz2/zip.dsw create mode 100644 win32/win32.c create mode 100644 win32/win32i64.c create mode 100644 win32/win32zip.c create mode 100644 win32/win32zip.h create mode 100644 win32/zip.def create mode 100644 win32/zip.rc create mode 100644 win32/zipup.h create mode 100644 windll/VBz64/VBZIP.VBP create mode 100644 windll/VBz64/VBZIP.vbw create mode 100644 windll/VBz64/VBZipBas.bas create mode 100644 windll/VBz64/Vbzipfrm.frm create mode 100644 windll/VBz64/readVB64.txt create mode 100644 windll/Vb/VBZIP.vbw create mode 100644 windll/Vb/VBZipBas.bas create mode 100644 windll/Vb/Vbzip.vbp create mode 100644 windll/Vb/Vbzipfrm.frm create mode 100644 windll/Vb/readmeVB.txt create mode 100644 windll/contents create mode 100644 windll/example.c create mode 100644 windll/example.h create mode 100644 windll/structs.h create mode 100644 windll/visualc/dll/zip32z64.dsp create mode 100644 windll/visualc/dll/zip32z64.dsw create mode 100644 windll/visualc/lib/zip32z64.dsp create mode 100644 windll/visualc/lib/zip32z64.dsw create mode 100644 windll/windll.aps create mode 100644 windll/windll.c create mode 100644 windll/windll.h create mode 100644 windll/windll.rc create mode 100644 windll/windll.txt create mode 100644 windll/windll16.def create mode 100644 windll/windll32.def create mode 100644 windll/ziplib.def create mode 100644 zbz2err.c create mode 100644 zip.c create mode 100644 zip.h create mode 100644 zip.txt create mode 100644 zip30.ann create mode 100644 zip30f.ann create mode 100644 zip30g.ann create mode 100644 zip30h.ann create mode 100644 zipcloak.c create mode 100644 zipcloak.txt create mode 100644 ziperr.h create mode 100644 zipfile.c create mode 100644 zipnote.c create mode 100644 zipnote.txt create mode 100644 zipsplit.c create mode 100644 zipsplit.txt create mode 100644 zipup.c diff --git a/BUGS b/BUGS new file mode 100644 index 0000000..21a9013 --- /dev/null +++ b/BUGS @@ -0,0 +1,6 @@ +- zip sometimes crashes on some versions of NetBSD (0.8, 0.9 and early + 0.9-current), FreeBSD (<= 1.1) and BSDI (< 1.1) . This is due to a + bug in stdio. + Upgrading the stdio package in /usr/src/lib/libc/stdio should + fix the problem. See *BSD mirrors in src/lib/libc/stdio + You must at least replace setvbuf.o in all the libc's with a newer version. diff --git a/Betas_Readme.txt b/Betas_Readme.txt new file mode 100644 index 0000000..26e965e --- /dev/null +++ b/Betas_Readme.txt @@ -0,0 +1,17 @@ +Betas are works in progress. When a beta has a seemingly stable set +of features, we may post a public beta so outside developers can see +where the code is going and make contributions or comment. + +A Release Candidate is a beta that we believe has the full feature +set that will be released. It's still being tested, and things can +still change, but we thought it close when we posted it. + +We take suggestions, bug fixes, and patches at any time, so send them in. + +We make no guarantees as to the state of betas so use at your own risk. +All code, including releases, are released under the Info-ZIP license. + +Enjoy! + +Ed Gordon +20 April 2008 diff --git a/CHANGES b/CHANGES new file mode 100644 index 0000000..751695f --- /dev/null +++ b/CHANGES @@ -0,0 +1,3460 @@ +------------------------- August 7th 1996 version 2.2a ------------------ + 1. QDOS port (Jonathan Hudson) + 2. win32 volumelabel handling (Paul) + 3. VM/CMS clean up (Greg Hartwig) + 4. leading "../" in internal filenames are allowed (Paul) + 5. System V packages support (John Bush) + 6. Fix handling of atx in zipup() (Onno, Greg) + 7. Fixed typo that caused zip -R to dump core (Onno) + 8. msdos/makefile.dj2: fix for command line too long when linking zip.exe + 9. win95 long filename support with djgpp v2 (Onno, Kimio Itoh) +------------------------- August 9th 1996 version 2.2b ------------------ + 1. windll: use wiz instead of wizip (Mike) + 2. use z->name NOT z->zname to open files (Onno, Mike) +------------------------ September 1st 1996 version 2.2c ------------------ + 1. windll: use fprintf instead of putc to send data to std{out,err} (Mike) + 2. os2: make borlandc version detection equal to unzip 5.30d (Kai Uwe) + 3. use #elif constructions for msdos,os2 and win32 compiler detection (Onno) + 4. fix for incorrect free in zip.c (Onno, Mike, Steve) + 5. BeBox port from Chris + 6. unix/{configure,Makefile} fixes for SCO Xenix 286 (Tom Schmidt) + 7. remove zilog entry from unix/Makefile (Onno) + 8. man page fixes (Tom Schmidt) + 9. SCO ODT {3,5} fixes (Bill Davidsen) +------------------------ October 8th 1996 version 2.2d ------------------ + 1. Fix bug in QDOS patch that broke zipsplit.c (Onno, Paul) + 2. Fix a couple of warnings from BorlandC (Mike) + 3. msdos/makefile.wat: Delete some more files when cleaning up (Paul) + 4. store msdos volumelabels without a dot in them (Paul) + 5. clean up of unix/{Makefile,configure,packaging} (Tom Schmidt) + 6. make QDOS port case independent (Jonathan Hudson) + 7. new amiga SASC makefile (Walter Haidinger) + 8. don't truncate filenames in win32's in2ex() (Paul) + 9. os2/makefile.os2 update for emx 0.9c (Kai Uwe) +10. password() function for QDOS (Jonathan) +11. fix the last(?) free() related bug (Mike) +12. win32: security descriptors operations (Scott Field) +13. win32: FILE_SHARE_DELETE is not defined in some win32 compilers (Onno) +14. win32: fix makefile.wat to include nt.c (Onno) +------------------------ January 17th 1997 version 2.2e ------------------ + 1. define USE_CASE_MAP in osdep.h for those ports that need it (Onno) + 2. define PROCNAME in osdep.h for those ports that need it (Onno) + 3. wild() prototype decl only if PROCNAME defined => delete MSVMS define (Onno) + 4. add DOS EMX makefile (E-Yen Tan) + 5. include a little earlier in qdos/qdos.c (Jonathan) + 6. add ttyio.o to OBJZ in qdos/Makefile.qdos (Jonathan) + 7. remove unused fprintebc define from zip.c (Onno) + 8. use the right password routine in ttyio.c for unzip (Mike) + 9. BeOS update from Chris +10. Fix for 'zip -r foo x:' (Paul) +11. Fix library bug on beos (Chris) +12. Fix calculating version number (kitoh_@mix.or.jp, Walter Haidinger) +13. IsWinNT always returned TRUE (Mike) +14. Windll update from Mike +15. Improved crc routines for x86 from Scott Field +16. Detect in unix/configure if we can use crc_i386.S (Onno) +17. Fix spurious internal logic error (Paul) +18. Fix to include directory names on the Acorn when needed (Sergio) +19. include zip.h in mvs.h (Onno, George Carr) +20. add workaround for AZTEC C compiler bug to revision.h (Paul, Walter) +21. MVS doesn't have rmdir (George Carr) +22. define and use USE_ZIPMAIN for WINDLL en VM_CMS (Onno) +23. Fixes from Greg Hartwig to make CMS standalone versions possible. +24. Move OS specific encryption stuff to the os specific directories (Christian) +25. Change password fetching interface in ttyio and crypt (Christian) +26. Update emx support for 0.9c (Christian) +27. Define WINDLL instead of MSWIN (Christian) +28. Extended time stamp extra field format support (Christian) +29. Support for rsxnt-emx 0.9c win32 compiler (Christian) +30. Use izshr017b (Christian) +------------------------ March 11th 1997 version 2.2f ------------------ + 1. Move makefile.emx, rsxwinnt.h and zip.def to win32 subdir (Kai Uwe) + 2. Add win32 target to makefile.os2 to allow cross compilation (Kai Uwe) + 3. Fix NTSD_EAS link time failures with win32 (Paul) + 4. Fix buffer freed too early in password verification code (Mike) + 5. Remove unix/zipgrep and man/zipgrep.1 (sanvila@ctv.es) + 6. Only use crc_i386.o when we're using an x86 (Onno, Mark) + 7. Remove carriage returns from amiga/crc_68.a (Paul) + 8. New windll from Mike + 9. Fix typo in os2/os2zip.c (Kai Uwe) +10. Don't use ctime (last file status change) for unix and qdos cross compile + (Greg) +11. added gccwin32 crosscompilation target (RSXNT) to os2/makefile.os2 (Kai Uwe) +12. fixed the OS/2 file attribute and time stamp generation for zipping + stdin ("-") (Kai Uwe) +13. fixed the atime and ctime stat fields for the OS/2 Watcom C library + (Kai Uwe) +14. added atime and ctime support for the UT extra field when generated under + OS/2, the atime and ctime values are only stored when zipping (Kai Uwe) +15. qdos patches from Jonathan Hudson mainly for extended time flag handling +16. amiga aztec compiler bug workaround (Paul) +17. fix -v output of zipcloak, zipnote and zipsplit (Paul) +18. new amiga/makefile.azt with targets for debug versions (Paul) +------------------------ March 31st 1997 version 2.2g ------------------ + 1. remove -I/usr/local/include from unix/Makefile (Chris) + 2. Update versinfolines in revision.h (Greg) + 3. change 1U to 0x1 to accomodate non ANSI compilers (Onno, Rodney Brown) + 4. win32zip.c: cast buffer parameter in memcompress() to char * (Mike) + 5. remove beos/zipgrep (Chris) + 6. correct the -e password verification check in zip.c (Christian) + 7. use ZCONST instead of const in the generic code. (Christian) + 8. fix mktime timezone correction when time is near to daylight/nodaylight + switch points. (Christian) + 9. correct dependencies in makefile.os2 (Christian) +10. use a more sensible default for iztime.ctime than "0" when system does not + not support creation time stamps. (Christian) +11. fix VMS_PK_EXTRA function interface declarations. (Christian) +12. implement atime/ctime support in win32. (Christian) +13. win32/win32.c: replacement getch() for Watcom. (Paul) +14. win32/makefile.wat: debug object files kept separate. (Paul) +15. msdos/makefile.wat: debug object files kept separate. (Paul) +16. Fix extended time defines for the acorn. (Sergio) +17. Define PROCNAME() in acorn/osdep.h (Sergio) +18. Ignore exit status of ${INSTALL_D} in unix/Makefile (Chris) +19. Add Metroworks and BEOS info to version() in several files (Chris) +20. Move defines for the password fetch to zip.h (Christian) +21. Support the obsolete version rsxnt 1.1 / emx 0.9b (Christian) +22. Remove obsolete "#define PROCNAME ..." from cmsmvs/cmsmvs.h (Christian) +23. Fix extended time defines for qdos (Jonathan Hudson) +24. Use watcom getch() from unz530q in win32/win32.c (Onno) +25. Don't install zipgrep via the unix package tools (John Bush) +26. use izshr021 (Onno) +27. Fix zipnote: use iname not zname in zipnote.c (Onno) +28. Create proginfo directory (Christian) +------------------------ May 5th 1997 version 2.2h -------------------- + 1. Fix vms/zipup.h: iztime --> iztimes (Onno, Mike Freeman) + 2. Remove windll/wizdll.def (Mike) + 3. Add a couple of external variable declaration to windll.h (Mike) + 4. Remove zipgrep from install in unix/Makefile (Onno) + 5. Make updating .zip files with extended time fields possible (Kai Uwe) + 6. Delete beos/Makefile.gcc, beos/Makefiles handles both compilers (Chris) + 7. Fixes for unused variables (Chris) + 8. Added very simplistic example how to load and call the windll (Mike) + 9. Updated windll documentation to note this example (Mike) +10. Removed an unused memeber of a structure in windll (Mike) +11. Add BUGS instead of infozip.who and algorith.doc with the packaging + tools (John Bush) +12. tailor.h: increment NUM_HOSTS to keep in sync with UnZip (Christian) +13. win32/osdep.h: remove NO_SECURE_TESTS define (Christian) +14. zip.h: add declaration for free_crc_table() (Christian) +15. windll: move everything that's not windows specific into api.* (Mike) +16. use iname when checking for directory names in zipfile.c (Sergio) +17. improved mktime.c with better error checking (Christian) +18. improved crc routines (Christian, Rodney Brown) +19. get the -z option working again (Onno, Brad Clarke) +20. define BROKEN_FSEEK and seekable() for those systems where fseek() + always returns 0 (== OK) (Onno, Jeffrey Altman) +------------------------ May 10th 1997 version 2.2i -------------------- + 1. win32's seekable should only check for FILE_TYPE_DISK (Onno, Jeffrey Altman) + 2. add (ulg) cast to zipbeg = ~0 in zipfile.c (Steve) + 3. seekable() *really* belongs in flush_block, keep it there (Onno) + 4. seekable() calls fseekable(FILE *) (Onno) + 5. define HAVE_FSEEKABLE if a port has their own fseekable (Onno) + 6. WatCom doesn't have _get_osfhandle, use _os_handle instead (Paul) + 7. upgrade to Mike's latest windll sources (Mike) + 8. add -P option so you can specify a password on the commandline (Onno) + 9. Get -@ working again (Onno) +10. emx+RSXNT doesn't know about _get_osfhandle() (Kai Uwe) +11. fix a couple of typos in the OS/2 makefiles (Kai Uwe) +12. fix initialization bug in windll code (Mike) +13. tweak deletedir for RISC OS (Sergio) +14. RISCOS doesn't know about fstat() (Sergio) +15. Remove acorn/acorn (Sergio) +16. Delete debugging statements from version_local() in msdos.c (Greg) +17. Fix huge bug in readzipfile() (Onno) +------------------------ May 18th 1997 version 2.2j -------------------- + 1. Add missing ';' after return ZE_PARMS in zip.c (Mike) + 2. Remove obsolete 'struct stat st' in zipfile.c (Onno) + 3. Get Amiga SFX handling working again (Paul) + 4. Get zip -A working again (Onno) + 5. Change an && to & in zipfile.c (Johnny) + 6. Fix handling of empty sfx archives (Onno, Mike) + 7. Remove experimental entries from the makefiles (Jean-loup) + 8. Add exit codes to the manual page (Onno) + 9. Remove lines from the help screen that contain lesser used options (Onno) +------------------------ June 8th 1997 version 2.2k -------------------- + 1. use zip -t ddmmyyyy for year 2000 stuff (Greg) + 2. zip -@ only handles ONE filename per line (Jean-loup) + 3. beos support for DR9 filesystem and symlinks (Chris) + 4. VB support for windll (Mike) +------------------------ June 10th 1997 version 2.2l ------------------- + 1. beos filetype support (Chris) + 2. fill the buffer in getnam() to get it working again (Onno) + 3. implement -x@filename and -i@filename (Onno) +------------------------ June 22nd 1997 version 2.2m ------------------- + 1. Add a ; after de nextarg label in main() (Onno, Erik Baatz) + 2. Initialize p to NULL in get_filters() (Onno, Frank Donahoe) + 3. Fix typo in first if statement in filetypes() (Johnny Lee) + 4. zip -A works again (Onno, Greg) + 5. don't free zipbuf for VMS and CMS_MVS in main() (Onno, Mike Freeman) + 6. fix make_zip.com, link_zip.com and vmsdefs.h for gcc 2.6.3 on VMS (Onno) + 7. clarify -g option in the man page (Jean-loup) +------------------------ July 6th 1997 version 2.2n ------------------- + 1. use local in readzipfile2() declaration (Onno, Mike Freeman) + 2. return values with windll in get_filters() (Mike) + 3. a couple of minor patches for BEOS (Chris) + 4. zip -g works again (Onno, Chris) + 5. Some more Visual Basic dll support (Mike) + 6. Fix stack overflow in readzipfile() for DOS (Onno, Michael Mauch) +------------------------ August 19th 1997 version 2.2o ------------------- + 1. beos README and Makefile tweaks from Chris. + 2. Syntax corrections for README and man/zip.1 (Frank Donahoe) + 3. Use name not iname when deleting directories in trash() (Christian) + 4. change several wkuvx1 to lists in e-mail addresses (Christian) + 5. default to PK style extra fields for VMS (Christian) + 6. use izshr023 (Christian) + 7. replace buggy time library functions (Walter Haidinger, Paul, Christian) + 8. in2ex() and stat() are needed also when UTIL isn't defined (Greg Hartwig) + 9. don't use type=record in fopen() for MVS and CMS (Greg Hartwig) +10. Change P and K literals to hex for EBCDIC systems (Greg Hartwig) +11. Add output path support for CMS and MVS (Greg Hartwig) +12. Add memtoasc and memtoebc for EBCDIC systems (Greg Hartwig) +13. Handle comments correctly to fix zipnote for CMS and MVS (Greg Hartwig) +14. Add -tt option (do not operate on files after date mmddyy) (Christian) +15. move alloc routines for DOS into the !UTIL block (Christian) +16. move UTIL blocks and version_local() functions to a more logical place + (Christian) +17. Handle -P, -R, -x@, -i@ and -tt for the VMS CLI (Christian) +18. Update VMS help file with the new options (Christian) +19. Use iname in MATCH, not zname (Jonathan Hudson) +20. windll: more Visual Basic support (Mike) +21. windll: more project makefiles (Mike) +22. windll: insert Zip in front of global variable names (Mike) +------------------------ August 25th 1997 version 2.2p ------------------- + 1. Remove unused flags from LFLAGS2 in unix/Makefile (Onno) + 2. SunOS make bug: change unix_.o rule in unix/Makefile (Onno, Mike Freeman) + 3. ZipIsWinNT() instead of IsWinNT() in zip.h (Mike) + 4. Fix -t and -tt behaviour for windll (Mike) + 5. Remove windll makefiles that are now elsewhere (Mike) + 6. BEOS: preserve file attributes associated with symbolic links (Chris) + 7. No need to use in2ex() for ziputils (Christian) + 8. Fix comment handling for EBCDIC systems (Christian) + 9. EBCDIC conversion for entry names read from zipfile in UTIL mode (Christian) +10. Fix "fatal" error messages on EBCDIC systems (Christian) +11. zipnote.c: Fix handling of entry name changes for EBCDIC systems (Christian) +12. removed a large part of "dead" code from ziputils version (Christian) +13. use z->iname in comparison functions for sorting (Christian) +14. new installation utils for the acorn (Sergio) +15. use LSSTAT in set_extra_field for unix and beos (Onno) +16. perror(z->zname) instead of perror("zip warning") (Onno, Geoff Pennington) +17. Amiga SFX should work again (Paul) +18. refer to zip22 in install.doc (Frank Donahoe) +------------------------ September 10th 1997 version 2.2q ------------------- + 1. Change .doc to .txt, these aren't MS-Word documents (John D. Mitchell) + 2. Change msdos$_(OBJ) to msdos_$(OBJ) (Kai Uwe) + 3. Fix a couple of amiga related glitches (Paul) + 4. Support for DOS packed .exe files in makefile.dj2 (Frank Donahoe) + 5. Change warning message for zip -A (Greg) +------------------------ September 29th 1997 version 2.2r ------------------- + 1. Fix make svr4package (Eric Baatz) + 2. Fix VMS warning (Mike Freeman, Christian) + 3. Clean up beos gcc port and beos README (Chris) +-------------------------- October 6th 1997 version 2.2s -------------------- + 1. Change lpPrint to lpZipPrint for windll (Mike) + 2. Change lpPassword to lpZipPassword for windll (Mike) + 3. Amiga timezone fixes (Paul) + 4. WatCom C 11.0 makefile fixes (Paul) + 5. Tandem port from Dave Smith + 6. Corrections and updates for install.txt (Christian) + 7. Minor VMS README update (Christian) +-------------------------- October 12th 1997 version 2.2t -------------------- + 1. qdos compiler bug workaround (Jonathan) + 2. prevent storing qdos specific filenames that exceed filesystem limits + (Jonathan) + 3. fix undelimited comment in fileio.c (Frank Donahoe) + 4. disable storing of symlinks in BEOS until OS support is available (Chris) + 5. Init hash_head to 0 in amiga/deflate.a (Paul) + 6. Upgrade to izshr025 (Christian) + 7. don't add ".zip" to ZIP name for TANDEM (Dave Smith) + 8. use zipup.h not tandem.h in zipup.c (Dave Smith) + 9. rename history to CHANGES (Onno) +10. rename install.txt to INSTALL (Onno) +11. rename zip.txt to ZIPMAN (Onno) +12. create WHATSNEW (Onno) +-------------------------- October 15th 1997 version 2.2u -------------------- + 1. Use Info-ZIP instead of Info-Zip (Christian) + 2. Note recent filename changes in several files (Christian) + 3. Remove a couple of items from the TODO list (Christian, Onno) + 4. Add windll port, zip -t yyyymmdd and zip -R to WHATSNEW (Christian) + 5. VMS documentation cleanups and clarifications (Christian) + 6. dist entry in unix/Makefile (Onno) + 7. remove duplicate amiga/timezone.txt (Christian) + 8. rename ZIPMAN to MANUAL and update a couple of files regarding this (Onno) +-------------------------- October 24th 1997 version 2.2v -------------------- + 1. izshr026: in WHERE wiz40 instead of wiz30 (Christian) + 2. izshr026: another couple of Info-ZIP spelling fixes (Christian) + 3. Remove zipgrep from the makefiles that still had it (Christian) + 4. Update makefiles to handle the MANUAL renaming change (Christian) + 5. Fix the last daylight savings bug on the Amiga (Paul) + 6. Fix the SCO Unix specialty detection in unix/configure (Onno, + bug reported by Bo Kullmar for Solaris 2.6 and with uname -X output + for SCO Unix from ken@apisys.com and dgsmith@vnet.ibm.com) + 7. Update WHERE and amiga/time_lib.c from unzip 5.32g (Greg) +-------------------------- October 26th 1997 version 2.2w -------------------- + 1. Additional +Onolimit check in unix/configure (Onno, Peter Jones) + 2. Use ZIPERR macro instead of ziperr (Christian) + 3. initialize z->lflg for zip entries without extra field (Christian) + 4. "local (+ locextend)" vs. "central" header consistency check (Christian) + 5. Override local header values with central header values with -A + and differences between these headers (Christain) + 6. made "deltaoff" signed long; offset adjustment may be negative (Christian) + 7. fix a number of "wild" deallocation bugs (Christian) + 8. When zipping from a FAT drive (only 8.3 DOS names) under OS/2 or + WIN32, set z->vem to "OS_DOS | ". + Mark as "made by DOS PKZIP 2.0" only when dosify was requested. (Christian) + 9. DOS port should not store fake unix style external attributes. (Christian) +10. amiga/time_lib.c from izshr028 (Christian) +-------------------------- October 31st 1997 version 2.2y -------------------- + 1. amiga/time_lib.c from izshr029 (Christian) + 2. Turbo C++ version code clarification (E-Yen Tan) + 3. Fix spelling in cmsvms/zipname.conven (Rodney Brown) + 4. Fix memset check in unix/configure for Unixware 2.1.1 (Rodney Brown) + 5. Forward declaration fixes for HP-UX bundled compiler (Rodney Brown) +-------------------------- November 3rd 1997 version 2.2 -------------------- + 1. Update WHERE (Greg). +-------------------------- January 4th 1998 version 2.21a ------------------- + 1. BSD friendly version of version_local() in unix/unix.c (Onno) + 2. No NT versions in DOS version_local() (Steve Salisbury) + 3. -t mmddyyyy instead of -t ddmmyyyy in WHATSNEW (Walter Haidinger) + 4. use generic fseekable() for rsxnt (Christian) + 5. Fix MSC 8.x warnings (Christian, Steve Salisbury) + 6. win32 Borland C++ makefile (E-Yen Tan) + 7. Tandem doesn't know about extensions like .zip,.arj, ... (Dave Smith) + 8. Use dosmatch for EMX and DJGPP too (Christian) + 9. dummy djgpp startup functions to remove command line globbing and + recognition of environment variables from djgpp.env (Christian) +10. include DJGPP_MINOR in DOS version_local() (Christian) +11. TC 2.0 doesn't have mktime() (Christian, mmp@earthling.net) +12. VMS: rename opendir() to zopendir() so avoiding name clash with + VMS 7.x POSIX libraries (Christian, Martin Zinser) +13. Add support for VMS DEC C V 5.6 features (Christian) +14. Use iname for comparison in check_dup (Christian Spieler, Christian Michel) +15. Fix access to uninitialized ioctx records in vms_get_attributes() + Christian, Robert Nielsen) +16. Parenthesis around MAX_MATCH>>1 in match.S (Greg) +17. Use strchr() not strrchr() for -i and -x to get -i@ and -x@ really + working (Onno, Kai Uwe) +18. add chmod statements to unix/Makefile (Quentin Barnes) +19. Windll: handle both -r and -R (Mike) +20. Windll: general error handler in main() via setjmp/longjmp (Mike) +21. Don't allow zip -i@x.lst foo.zip (Onno) +22. vms/link_zip.com: use .eqs. not .nes. when checking with f$search + for the zip AXP object library (David Dachtera) +23. rsxnt 1.3.1 fixes (E-Yen Tan) +-------------------------- January 20th 1998 version 2.21b ------------------- + 1. Bigger PATH_MAX for win32's windll (Mike) + 2. Update windll.txt w.r.t. PATH_MAX (Mike) + 3. Amiga SAS/C fixes (Walter, Paul) + 4. zip -i@ and -x@ should *really* work now ...... (Onno) +-------------------------- February 20th 1998 version 2.21c ------------------- + 1. make -f unix/Makefile qnx needs LN=ln in its options (Chris) + 2. Support Metroworks Codewarrior/x86 on BEOS (Chris) + 3. Add Norbert Pueschel to proginfo/infozip.who (Walter) + 4. Use big endian for Be types (Chris) + 5. zip -i and -x were broken by the -i@ fix last time around (Christian) + 6. win32 stat bandaid (Paul) + 7. acorn filetype and timestamp fixes (Sergio, D. Krumbholz) + 8. update to izshr30 (Christian) + 9. Support for NTSD in the RSXNT environment (Christian) +10. restructure readzipfile() (Christian) +11. Where needed define MATCH in osdep.h (Christian) +12. version_local() fixes for RSXNT (Christian) +13. New vmsmunch.c (Christian) +-------------------------- March 15th 1998 version 2.3a ------------------- + 1. Fixes for the windll API (Mike) + 2. Use CPUTYPE in BorlandC Makefile for DOS (E-Yen Tan) + 3. BEOS: -rostr not available for the x86 compiler (Chris) + 4. preserve file attributes of a symlink on BEOS (Chris) + 5. New VM/CMS README.CMS and version_local() (Ian Gorman) + 6. INSTALL fixes from Takahiro Watanabe + 7. OS/390 port from Paul von Behren + 8. new api.h from Mike +-------------------------- April 19th 1998 version 2.3b ------------------- + 1. Improve Tandem file I/O performance (Dave Smith) + 2. New VM/CMS README.CMS and version_local() (Ian Gorman) + 3. cygwin32 port from Cosmin Truta + 4. Workaround for tasm32 5.0 bug in win32/crc_i386.asm (Cosmin Truta) + 5. win32/match32.asm fixes for tasm 5.0 (Cosmin Truta) + 6. simplify OS/390 port (Christian) + 7. win32 timezone handling fixes (Christian) + 8. fix 40-bit time conversion on the acorn (Sergio and Christian) + 9. strip network part from UNC type filenames (Christian) +10. Makefile for OpenMVS (Ian Gorman) +11. Use the Watcom getch() for cygwin32 (Christian) +12. Borland C++ 5.x added to win32's version_local() (Cosmin Truta) +13. Borland C++ needs tzset() in win32 (Christian, Cosmin Truta) +-------------------------- May 21st 1998 version 2.3c ------------------- + 1. Better error messages for -i and -x (Christian) + 2. Win32 stat() wrapper needs dos2unixtime (Christian,Paul,Mike) + 3. DJGPP: use _chmod to handle LFN attributes correctly (Michael Mauch) + 4. Fix Borlandc warnings (Mike) + 5. win32/makefile.bor fixes from Michael Mauch + 6. win32/makefile.{dj,emx} fixes from E-Yen Tan + 7. Use izshr031 (Christian) + 8. CMS: use RECFM=V LRECL=32760 by adding "byteseek" (Greg Hartwig) + 9. Check external name for trailing "/" (Greg Hartwig) +10. More specific info in CMS version_local() (Greg Hartwig) +11. Changed usage info to refer to "fm" rather than "path" on CMS (Greg Hartwig) +12. No more "extra data" messages when using the same OS (Greg Hartwig) +13. Rewritten README.CMS, one version for ZIP and UNZIP (Greg Hartwig) +14. DOS/OS2/WIN32/UNIX: ex2in() strips off "//host/share/" from UNC names (SPC) +-------------------------- June 23rd 1998 version 2.3d ------------------- + 1. Fixed Win32's stat() bandaid handling of time stamps (SPC) + 2. General fix of file selections for DELETE and FRESHEN action (SPC) + 3. CMS_MVS: Use ASCII coding for TIME extra field ID (SPC) + 4. EBCDIC: Repaired bogus CMS_MVS fix in zipup.c; check the internal + name for trailing (ASCII) '/' to detect directory entries (SPC) + 5. Use explicit ASCII coding when comparing or setting chars in iname (SPC) + 6. Fixed win32/makefile.bor, win32/makefile.dj (support NTSD), + win32/makefile.emx (SPC) + 7. Replaced win32/makefile.cyg by win32/makefile.gcc, containing new + support for mingw32 GCC environment (SPC) + 8. Use izshr032 (SPC) + 9. Modified zipup.c to hold (un)compressed lengths in "ulg" variables, in + an attempt to support handling of huge (>2GByte) files. (SPC) +10. Removed some duplicate #defines from api.h, they are now in crypt.h (SPC) +11. Reenabled "extra data size" info messages in noisy mode for all systems + except RISCOS and CMS_MVS (SPC) +12. For EMX 0.9c, the runtime lib contains a working mktime(), use it (SPC) +13. Miscellanous cosmetic changes (SPC) +14. Move win32/makefile.emx to msdos (E-Yen Tan) +15. make api.h work with zcrypt2.8 (Mike) +16. define ydays differently in api.h to avoid linking problems (Mike) +17. New windll.txt (Mike) +18. win32 lcc patches (E-Yen Tan) +19. win32 lcc makefile (E-Yen Tan) +20. Multiple inclusion bug: no malloc.h when using lcc-win32 (E-Yen Tan) +21. New VB support files for windll (Mike Le Voi, Raymond King) +22. MacOS port by Dirk Haase +-------------------------- August 1st 1998 version 2.3e ------------------- + 1. Generalized check for validy of TZ timezone setup info, similar to + UnZip; use it on AMIGA and MSDOS, as before. (SPC) + 2. Apply TZ validy check on OS/2 and enable creation of UT e.f. (SPC) + 3. BEOS: New Makefile, updates for README and Contents (Chris Herborth) + 4. beos/beos.c: declare some private functions as "local" (SPC) + 5. Include memcompress() code only for ports that make use of it, controlled + by preprocessor symbol ZP_NEED_MEMCOMPR (SPC) + 6. cmsmvs/README.CMS fix: Zip archive entries to be extracted into var-length + records CMS files should >>NOT<< contain binary data ... (SPC) + 7. crc32.c, crctab.c: the crc polynom table is ZCONST (SPC) + 8. trees.c: fixed a bug in the deflate algorithm that limited the compressed + size of an archive member to 512 MByte (SPC) + 9. deflate.c: Integrated the changes found in zlib that are neccessary to make + the deflate algorithm deterministic; modified msdos/match.asm to take + care of the "nice_match" global no longer being constant. (SPC) +10. deflate.c, trees.c, zipup.c: Reorganized and simplified deflate's + compressed output buffer handling. I/O and compression code are now + separated more cleanly. (SPC) +11. Killed bits.c by moving its contents into trees.c resp. zipup.c; + synchronized all Makefiles and Make procedures with this change. (SPC) +12. Integrated support for optionally replacement of deflate and crc32 by + public domain zlib code. (SPC) +13. Synchronize the different variants (UNIX/GNU C, OS/2, WIN32) of i386 + assembler replacement for deflate's longest_match() (SPC) +14. Moved the EMX+rsxnt Makefile.emx from msdos/ back into win32/ (SPC) +15. Restored a separate Makefile.emx for DOS; on DOS, some make programs may + have difficulties with recursive invokation (SPC) +16. Fixed the "include header mess" of the new MACOS port and removed the + "work-around hacks" caused by these bad MACOS .h-file includes (SPC) +17. Integrated Dirk Haase's beta4 (27-Jun-98) release of MacZIP (Dirk Haase) +18. Added support for MS Quick C in the MSDOS version_local() report (SPC) +19. Added WIN32 rsxnt targets linking against the emx crtl DLL to Makefile.emx + in os2/ and win32/ (SPC) +20. Fixed typo in os2/os2.c wild() function. (Kai Uwe Rommel) +21. Removed ChangeNameForFAT() from os2/os2.c in2ex() to fix problem with + long filename support. (Kai Uwe Rommel) +22. os2/os2zip.[ch]: correct type of DOS-style timestamp data is "ulg" (SPC) +23. vms/cmdline.c: Removed wrong ';' behind if condition (Johnny Lee) +24. VMS: Preliminary preparations in C code for supporting GNU C on OpenVMS + Alpha (Onno van der Linden, Christian Spieler) +25. VMS: Fixed check against adding zipfile to itself in fileio.c (SPC) +26. WIN32: Added lcc-Win32 variants of i386 assembler code for crc32() and + longest_match(). (SPC) +27. WIN32: Removed bogus type-cast in assignment to statb st_mode member (SPC) +28. zip.c: Fixed MACOS-related typo that broke "-@" command option (SPC) +29. zipup.c: Fixed messed-up expression for assignment to z->ver (SPC) +30. MACOS extra fields: check realloc return values (Onno, Johnny Lee) +31. Fix the PUTBYTE macro in trees.c: >= instead of < (Onno) +-------------------------- September 6th 1998 version 2.3f ------------------- + 1. Add zp_tz_is_valid to globals.c (Onno, Frank Donahoe) + 2. Updated tandem files from Dave Smith + 3. Windll: allow comments to zip archive with VB (Mike) + 4. Windll: add support for -b and update the documentation (Mike) + 5. win32: use wbS for FOPW to handle large zip files better (Steve Miller) + 6. MVS fix: use fseek();clearerr() instead of rewind() (Onno, Lee Burton) + 7. Updated VB examples for windll (Mike) + 8. Tandem: use UTC timestamps and GID/UID in extra field (Dave Smith) + 9. Tandem: handle -o option (Dave Smith) +10. default for ZCONST is const in tailor.h, override in osdep.h (Onno) +11. additional Macintosh options in zip.c (Dirk Haase) +12. additional Macintosh options in zip.1 and MANUAL (Onno, Dirk Haase) +13. Integrate Beta 5 of the Macintosh Port (Dirk Haase) +-------------------------- October 27th 1998 version 2.3g ------------------- + 1. zip_tz_is_valid should be zp_tz_is_valid (Kai Uwe) + 2. MVS native (not OE) beta fixes (Keith Owens) + 3. LynxOS support from Giuseppe Guerrini + 4. MVS already has stat() and fstat() so use 'em (Keith Owens) + 5. MVS fix in readzipfile() for new, unopened dataset without EOF marker + (Keith Owens) + 6. Remove 16-bit stuff from windll/windll.rc (Mike) + 7. Windll: Use hCurrentInst not hInst (Mike) + 8. In util.c compare strchr() return value with NULL (Onno, Frank Donahoe) + 9. unix/unix.c: initialize variable t in ex2in() (Onno, Frank Danahoe) +10. Remove windll/borland subdirectory (Mike) +11. Really fix extra field realloc() for BeOS and MacOS (Christian) +12. Fix the dj2 LFN related access violation bug (Christian, Joe Forster) +13. proginfo/3rdparty.bug: Added more info about other Zip clone's bugs. +14. The global copyright definitions in revision.h now depend on DEFCPYRT + (Christian). +15. tandem/macros: removed obsolete object file references (Christian) +16. fix memory leak with the "filter" patterns (Christian, Leah Kramer) +17. zip.c: completed the support for MacOS specific -N (Christian) +18. reorganized the Mac specific help screen code (Christian) +19. zipup.c: corrected the USE_ZLIB code to emit "stored" entries under + the same conditions as the "native deflate" code (Christian) +20. A couple of vars that will never be negative should be unsigned (Christian) +-------------------------- November 18th 1998 version 2.3h ------------------- + 1. DJGPP: When compressing from stdin don't set binary mode if stdin is + a terminal (E-Yen Tan) + 2. Fix signed/unsigned comparisons in fileio.c, util.c and zipcloak.c + (Frank Donahoe) + 3. Move macgetch() prototype from macos/source/macos.c to macos/osdep.h + (Christian) + 4. _doserrno should have type int, not unsigned int (Christian) + 5. In zipfile.c init a file pointer with NULL to fix gcc warning (Christian) + 6. Upgrade to MacOS beta 7 (Dirk Haase) + 7. Move the #pragma statements from generic sources to cmsmvs.h (Christian) + 8. Support for QNX/Neutrino 2.0 (Chris) + 9. Default to -r in help screen add -R at the bottom (Chris) +10. Clean up Makefile for BeOS R4 on x86 (Chris) +11. Beos: If not storing symlinks store attributes of symlink target (Chris) +12. Use izshr037 (Christian) +13. Remove ZIPERR() macro from in {msdos,win32}/osdep.h (Christian) +14. win32/win32.c: Fix 1-day offset in non-64bit FileTime2utime() (Christian) +15. win32: enable 64-bit FileTime2utime() for MS VC++ >= 5.0 (Christian) +16. cygwin32 only has _P_WAIT (Thomas Klausner) +17. msname() should *really* ignore illegal characters (Thomas Klausner) +18. Fix a missing ')' in Opendir() from win32zip.c (Thomas Klausner) +-------------------------- December 5th 1998 version 2.3i ------------------- + 1. Remove the #pragma statements that were forgotten the first time (Ian) + 2. Remove obsolete macos/source/CharMap.h (Steve Salisbury) + 3. isatty(fileno(zstdin)) in zipup.c should be isatty(zstdin) + (Onno, E-Yen Tan) + 4. several "shut up warnings from compiler" fixes (Christian) + 5. several cosmetic source changes (Christian) + 6. win32: make NTSD handling to be robust against alignment and structure + padding problems (Christian) + 7. Apply don't set binary mode when stdin is a terminal in zipup.c for + MSDOS and human68k (Christian) + 8. Upgrade to MacOS beta 8 (Dirk Haase) + 9. Add callback for WINDLL to handle user termination (Mike) +10. Fix typo in acornzip.c (Darren Salt) +11. acorn/sendbits.s: pass correct parameters to flush_outbuf() (Darren Salt) +12. Fixes for IBM C/C++ 3.6 where time_t is a double (Kai Uwe) +13. Fixes for IBM Visual Age C++ for win32 (Douglas Hendrix) +14. man/zip.1: some version numbers in the text were still "2.2" (Christian) +15. win32/makefile.emx: added a compilation variant that generates + standalone executables (Christian) +16. change __CYGWIN32__ into __CYGWIN__ and add compatiblity definition for + B19 and older (Cosmin Truta) +17. create uniform win32 getch() replacement (Christian) +18. put back in define of USE_EF_UT_TIME in tandem.h (Dave Smith) +19. put back in define of USE_CASE_MAP in tandem.h (Dave Smith) +20. updates to make/macros to allow the object to be licensed (Dave Smith) +21. updates to macros/doit to remove mktime.c (Dave Smith) +22. updates to tandem.c for in2ex/mapname/chmod amendments to match Unzip + (Dave Smith) +23. Use izshr039.zip (Christian) +24. Init filenotes to 0 for the amiga too (Onno) +25. get_filters(): remove one flag=0 statement to make -R work again (Onno) +-------------------------- December 17th 1998 version 2.3j ------------------ + 1. FOPWT defines opening a temp file for writing (Ian) + 2. Remove handling of bits.c from a couple of tandem files (Christian) + 3. A couple of "shut up warnings from compiler" fixes (Christian) + 4. win32/osdep.h: removed duplicate "IZ_PACKED" definition (Christian) + 5. win32/zipup.h: remove invalid "elseif" preprocessor token (Christian) + 6. sync MacOS help screen with other ports (Christian) + 7. get_filters(): set flag to 0 when -R isn't used (Christian) + 8. "local extra != central extra" now has "info" status (Christian) + 9. use windll directory as "home" directory for builds (Mike) +10. CMS/MVS: define FOPWT (Ian) +11. Upgrade to MacOS beta 9 (Dirk Haase) +-------------------------- January 17th 1999 version 2.3k ------------------ + 1. Change FOPW into FOPW_TMP (Christian) + 2. win32: #include uses paths relative to the parent directory (Christian) + 3. Use forward slashes as path separator in #include statements (Christian) + 4. windll: fix descriptions of f{In,Ex}cludeDate (Christian) + 5. win32/makefile.lcc: add some -I options to find files in the + right places (Christian) + 6. Supply default empty IZ_PACKED define (Christian) + 7. windll: Fix some typos, descriptions (Christian) + 8. windll project files: use relative paths, no specific root directory + (Christian) + 9. windll project files: remove link references to import libraries that + are not used by the zip library (Christian) +10. windll: fix potential infinite loop in a VB sample (Mike) +11. windll/windll.txt: remove "may not work with VB" statement (Mike) +12. Multibyte character set support from Yoshioka Tsuneo +13. Theos port from Jean-Michel Dubois +14. Tandem: added simple handling of Enscribe files by converting them into + text type files (Dave Smith) +15. Tandem Extra Field ("TA") containing Tandem File Attributes (Dave Smith) +16. Tandem history file showing background info to (UN)ZIP ports (Dave Smith) +17. create ZIP file on tandem with special file code (1001) (Dave Smith) +18. made tandem.c & tandem.h code completely the same as UNZIP (Dave Smith) +19. unix/configure: move +Onolimit and -Olimit into the machine specific + section (Onno, John Wiersba) +-------------------------- February 21st 1999 version 2.3l ------------------ + 1. Fix qdos Makefile (Jonathan Hudson) + 2. fgets instead of gets in zipnote to fix linker warnings (Jonathan Hudson) + 3. Theos: remove _setargv.c and a reference in zip.c (Jean-Michel Dubois) + 4. Theos README (Jean-Michel Dubois) + 5. interchanged the fRecurse flag values for "-R" and "-r" (Christian) + 6. add "z" pr prefix to MBCS functions to avoid name clashes (Christian) + 7. Whenever the position of the increment operator does not matter, the + INCSTR variant is used, which has been mapped to the {PRE|POS}INCSTR + variant that is more efficient. (Christian) + 8. fixed the "-R" handling in fileio.c, filter() function (Christian) + 9. simplified some THEOS specific code additions (Christian) +10. changed the line break of the compiler version message in version_local() + for MSDOS and Win32 to take into account some verbose compilers (Christian) +11. removed the THEOS changes from ttyio.c. Instead, a THEOS specific + setup was added to ttyio.h (Christian) +12. sync vms/link_zip.com with the corresponding make_zip.com (Christian) +13. added compatibility settings for support of MBCS on Win32 with all tested + compilers to win32/osdep.h +14. added type-casts to isalpha() macro calls (Christian) +15. fixed win32's wild_match which was clobbered by the MBCS addition + (Christian) +16. finished up the "potential infinite loop" problems in the VB sample + that Mike started to repair (Christian) +17. in ziperr.h, AZTEK C might require the false comma that was removed + to satisfy THEOS C (Christian) +18. removed the bogus THEOS specific isdir check in zipup.c (Christian) +19. modified the code for line ending translation to be independent + of the local system's convention for '\n' and '\r'; this allowed + the removal of the THEOS specialities (Christian) +20. Tandem: -B option to zip Enscribe files with no record delimiters + (Dave Smith) +21. Tandem: attempt to catch Large Transfer mode failure (Dave Smith) +22. Theos: Fixed keyboard entry functions. (Jean-Michel Dubois) +23. Theos: workaround for the argument wild card expansion that is bugged + in the standard library. Managed by MAINWA_BUG flag. (Jean-Michel Dubois) +24. Theos: support for filenames and notes with accented characters. + (Jean-Michel Dubois) +25. Upgrade to MacOS final (Dirk Haase) +-------------------------- March 31st 1999 version 2.3m ------------------- + 1. Theos: for relative paths to root directory cause open, fopen and stat + failure, workaround this. (Jean-Michel Dubois) + 2. Theos: when no path is indicated in a file or directory name and the + file or directory doesn't exist in the current directory it looks for + the file or directory in the root directory, workaround this. + (Jean-Michel Dubois) + 3. Corrected some typos and spelling error in macos/HISTORY.TXT; skipped + off invisible trailing whitespace (Christian) + 4. proginfo/extra.fld: added documentation for Tandem and Theos extra + field layout (Christian with Dave D Smith resp. Jean-Michel Dubois) + 5. qdos/Makefile.qdos: The build of ZipCloak requires inclusion of + the crctab object module; qfileio_.o compilation requires the -DUTIL + flag (Christian) + 6. win32: fix incorrect MB_CUR_MAX macro for mingw32 and lcc (Christian) + 7. theos/_fprintf.c, theos/_rename.c, theos/osdep.h: Some function + parameters require the "const" attribute to achieve compatibility + with ANSI C requirements (Christian) + 8. theos/theos.c: map Theos' (No)Hidden file attribute to MSDOS Hidden + bit in the MSDOS part of zipentry header's external attribute field; + 9. theos/stat.h: prevent multiple inclusions +10. Theos: Fixed wild card management for options other than adding + (Jean-Michel Dubois) +11. Theos: Removed modifications of const strings (Jean-Michel Dubois) +12. Split tandem.c up into separate zip/unzip parts (Dave Smith, Christian) +13. Move inclusion of OS specific zipup.h files to tailor.h (Onno) +-------------------------- August 14th 1999 version 2.3n ------------------- + 1. Move inclusion of OS specific zipup.h files back to zipup.c (Onno) + 2. Remove getline() from zipnote.c and use gets() again (Onno) + 3. BeOS PowerPC R4.1 support (Chris) + 4. New DOIT and MACROS files for the tandem port (Dave Smith) + 5. Don't switch the console to binary mode (Michel de Ruiter) + 6. In some circumstances undosm could be freed twice (Mike) + 7. Also define const in tailor.h for ultrix (Onno, Foppa Uberti Massimo) + 8. Tandem: Change zopen in TANZIPC to allow opening of files with missing + alt keys (err 4) (Dave Smith) + 9. Tandem: Assume not DST if can't resolve time (no DST table available) + (Dave Smith) +10. WIN32: skip trailing dots and spaces in getnam (Onno, Dan Kegel) +11. Use ZE_NONE when nothing to freshen or update (Onno, Yuri Sidorenko) +12. Remove tabs from files that don't need them (Onno) +13. Remove tabs and spaces from the end of a text line (Onno) +14. Upgrade macos to 1.04b2 (Dirk) +15. Add -Q documentation to manual page (Jonathan Hudson) +16. Copy hiperspace files instead of renaming them (Keith Owens) +17. Disallow some more characters to appear in DOS filenames when using -k + (Onno, Thomas Klausner) +18. Document missing options and environment variables in the manual (Onno) +19. New acorn/GMakefile to compile with gcc on RISCOS (Darren Salt) +20. ISO 8601 date format support for -t and -tt (Rodney Brown) +-------------------------- September 21st 1999 version 2.3o ------------------- + 1. Sync zip.h license with LICENSE (Onno) + 2. Add copyright notice to README, os2zip.c and os2.zip.h (Onno, Greg) + 3. Fix the ASM variable in acorn/GMakefile (Darren Salt) + 4. Add another requirement to acorn/ReadMe.GMakefile (Darren Salt) + 5. Fix unbalanced parenthesis in vms_get_attributes declaration in zip.h + and move it to vms/zipup.h (Onno, Mike Freeman) + 6. Make a couple of os2 files public domain (Kai Uwe) + 7. Change and rename disclaimer array in revision.h (Onno) + 8. Change copyright array in revision.h (Onno) + 9. macstuff.c copyright is the same as macstuff.h (Christian) +10. WHATSNEW: add ISO 8601 dates supported (Christian) +11. fileio.c - msname(): strip off leading dots, these are illegal for + MSDOS compatible names (Christian) +13. fileio.c - replace(): deactivate "dead" code for CMS_MVS (Christian) +14. man/zip.1: "-$" option is also used for WIN32 ports +15. msdos/msdos.c - version_local(): break the version line for + GNU compilers too (Christian) +16. tailor.h: added typecasts to MBCS macros, to suppress "type mismatch" + warnings (Christian) +17. util.c, zip.h, zipfile.c: ZCONSTify several pointers (Christian) +18. util.c - recmatch(), zip.c - version_info(): add compile time option + WILD_STOP_AT_DIR (Christian, Darren Salt) +19. util.c - envargs(): MBCS related fixes (Christian) +20. win32/lm32_lcc.asm: add TAB characters that are required by the lcc + assembler source parser (Christian) +21. zip.c: fix the "is a console" check (Christian) +22. zipnote.c: use getline() (Christian) +23. zipup.c: use zclose() in case of I/O errors (Christian) +24. zipup.c: use ZE_WRITE when a write error occurs (Christian) +25. win32/win32.c: HAVE_INT64 is used by mingw32 (Cosmin Truta) +26. update shared sources to match izshr041 (Christian) +-------------------------- November 29th 1999 version 2.3 ------------------ + 1. Missing parenthesis in win32/win32.c (Steve Salisbury) + 2. Add Cosmin Truta to proginfo/infozip.who (Onno) + 3. Remove one parenthesis pair too many from vms_get_attributes() declaration + in vms/zipup.h (Mike Freeman) + 4. qdos .s are expected to start with a #, work around it (Jonathan Hudson) + 5. tandem: -B0 should be deflating not storing (Dave Smith) + 6. human68k updates from Shimazaki Ryo + 7. beos Makefile cleanup (Chris) + 8. workaround for fseek to negativate offset behaviour of the RISC OS + SharedCLibrary (Darren Salt) + 9. set file type for RISC OS in zipcloak.c (Darren Salt) +10. change tandem zgetch() to allow crypt version to work (Dave Smith) +11. fix a comment typo in acorn/riscos.c (Christian) +12. fileio.c: two type-cast to shut up noisy compilers (Christian) +13. human68k: fix missing case_flag argmument (Christian) +14. win32/win32.c: remove HAVE_INT64 completely (Christian) +15. zip.c: raise "cannot zip to console" error when stdout IS a tty (Christian) +16. zip.h: don't use dummy argument names in declarations (Christian) +17. Add missing semicolon in fileio.c (Shimazaki Ryo) +18. win32.c: IBMC compiler >= 3.50 have int64 (Kai Uwe) +19. Handle initialization error return value from MVS stat() in procname() + (Keith Owens) +20. Use RISC OS instead of RiscOS in the manual (Darren Salt) +21. Use # instead of ? as single character wildcard on RISC OS (Darren Salt) +22. New windll example.c (Mike) +23. Correct storage of 8-bit char filenames with RSXNT (Burkhard Hirzinger) +24. fix install in unix/Makefile (Santiago Vila, Onno) +25. Fix zip -L output (Santiago Vila, Onno) +26. Ignore unix special files (Jonathan O'Brien) +27. Upgrade to izshr042 (Onno) +28. Make copyright notice the same as in izshr042 (Onno) +29. Make copyright notice in zip.h the same as LICENSE (Christian) +30. Set tempzf to NULL _after_ it has been closed (Chris Kacher) +31. Change email address for Jonathan Hudson (Jonathan Hudson) +32. Remove win32/winzip.c.orig (Steve Salisbury) +33. Use 'Steve Salisbury' throughout the documentation (Steve Salisbury) +34. Change email address for Steve Salisbury (Steve Salisbury) +35. Change email address for Chris Herborth (Chris Herborth) +36. Use zip23 in INSTALL (Roger Cornelius) +37. Use zcrypt28 in INSTALL (Onno) +38. New acorn/srcrename (Darren Salt) +39. amiga/makefile.azt: make clean should remove some more items (Paul) +40. Change email address for Cosmin Truta (Cosmin Truta) +-------------------------- February 11th 2001 version 2.4a ------------------ + 1. Identify newer Borland compilers (Brad Clarke) + 2. Detect Turbo C 2.01 which doesn't have mktime (Brian Lindholm) + 3. Fix the use of -@ together with -i -x (Christian) + 4. Update msdos/README.DOS to match reality (Christian) + 5. win32: use assembler crc32 code (Christian) + 6. windll: _CRTIMP is needed in several function declarations (Christian) + 7. back to zip 2.2 memcompress() behaviour (Kelly Anderson) + 8. new amiga time code based on nih public domain code (Paul Kienitz) + 9. Detect some more Borland C++ builder versions (Brad Clarke) +10. Fix OS/2's extended file attributes compression code (Christian, Kai Uwe) +11. Correct translation of EBCDIC passwords to ASCII (Christian) +12. Attempt at integrating novell patches from Roger Foss (Onno) +13. Use izshr043 (Christian) +-------------------------- July 3rd 2001 version 2.4b ------------------ + 1. Fix OS/2's ACL compression code (Christian, Kai Uwe) + 2. Rename netware subdir to novell (Christian) + 3. Remove -dNETWARE -dDOS from novell Makefile (Christian) + 4. Remove defined(NETWARE) from the sources (Christian) + 5. printf is a macro in glibc 2.2, fix version_local function + (Christian, Matthew Wilcox) +-------------------------- January 13th 2002 version 2.4c ------------------ + 1. Use klist_items when initilizating koff[] in tandem.c (Dave Smith) + 2. Only call NLMsignals() in zip.c when NLM is defined (Mike, Onno) + 3. include riscos.h instead of acorn/riscos.h in acorn/osdep.h (Andy Wingate) + 4. Use izshr044 (Christian) +-------------------------- January 13th 2002 version 2.4d ------------------ + 1. Don't use mmap for stored entries (Christian) + 2. BIG_MEM and MMAP cannot be defined at the same time (Christian) + 3. Allow redirection of version screen to file (Christian) + 4. Fix for OS/2 output redirection bug (Christian, Kai Uwe) + 5. Acorn script for creating self extracting zips (Darren Salt) + 6. Update amiga makefiles to support revised timezone routines (Christian) + 7. Correct memcompress calculation for allocation size (Christian) + 8. Fix FORCE_METHOD debug option for level 1 and 2 (Christian) + 9. Whitespace cleanup in man/zip.1 (Christian) +10. Define IZ_IMP to specify compiler declaration prefixes (Christian) +11. make win32 and msdos version_local() "stdio-macro-safe" (Christian) +12. move tandem's zip specific zipopen to tanzip.c (Christian) +13. first parm is void * in external scope of vms_get_attributes() (Christian) +14. use right novell subdirectory in zipup.c (Christian) +15. update copyright for files modified in 2002 (Onno) +-------------------------- January 19th 2002 version 2.4e ------------------ + 1. Add MacOS X to version_local() (Mark) + 2. unix/configure: Init LFLAGS1 to "", MacOS X doesn't like -s (Onno, Mark) + 3. rename errors array to ziperrors to avoid MacOS X library clash (Mark) + 4. Support for the upx executable packer in DOS makefiles (Christian) + 5. remove obsolete -m486 switch from dos djgpp makefile (Christian) + 6. When using DOS, force the use of msdos style external attributes when + updating zip entries created under another OS (Christian) + 7. os2/makefile.os2: fixed ASFLAGS for watcom16dos (Christian) + 8. Update copyright and ftp address in several files (Christian) + 9. The RISCOS port uses '.' as directory separator, not '/' (Christian) +10. win32/makefile.bor: more options to compile the asm CRC code (Christian) +11. win32: use registry to handle timezones with MS C rtl (Christian) +12. acorn: use recommended practice for calling the linker (Andy Wingate) +13. unix/configure: check if CPP works else use ${CC} -E (Onno, Mark) +14. update versioninfolines in revision.h to match reality (Onno) +-------------------------- February 10th 2002 version 2.4f ------------------ + 1. vms: Zip -V is now able to handle file sizes up to 4Gb (Christian) + 2. vms: Include target environment detection for MMS/MMK (Christian) + 3. Change dummy message from zipcloak (Christian) + 4. acorn: add riscos specific -/ option (Darren) + 5. Update acorn's WILD_STOP_AT_DIR feature (Christian) + 6. acorn: Fix buffer allocation for -/ option (Christian, Darren) + 7. acorn: fix make clean (Andy Wingate) + 8. acorn: use tabs for GMakefile to make GNU make happy (Andy Wingate) + 9. tandem: use nskopen not zipopen (Dave Smith) +10. tandem: allow passing of CRYPT define (Dave Smith) +11. use izshr045 (Christian) +-------------------------- April 1st 2002 version 2.4g ------------------ + 1. acorn: fix assembler and compiler options in makefile (Darren) + 2. use izshr046 (Christian) + 3. MVS: define isatty to 1 to fix screen output (Christian) + 4. tandem: encryption really works now (Dave Smith) + 5. win32: detect Borland C++ builder 6 (Brad Clarke) +-------------------------- April 30th 2003 version 2.4h ------------------ + 1. tandem: fix temporary file contention (Dave Smith) + 2. cmsmvs: generate better filenames with -j (Owen Leibman) + 3. tandem: fix temporary file leftovers (Dave Smith) + 4. solaris: enable large file I/O to break 2G barrier (Rick Moakley, Onno) + +Note: Zip 2.4 was never released. That code was the start of the Zip 3.0 +effort below. Some changes and fixes also made it to the Zip 2.3x releases. + +---------------------- January 21st 2004 version 3.0a ---------------------- +Initial work on Zip 3.0 by Ed Gordon and Rainer Nausedat + 1. Changed some comments to update copyrights (Ed) + 2. Changed text in command line messages from zip 2.4 to zip 3.0 (Ed) + 3. Changes to many files for Zip64 wrapped in ifdef ZIP64_SUPPORT (Rainer) + 4. Attempt to fix buggy Win32 buffered 64-bit calls (Ed) + 5. Add functions to zipfile.c for Little-Endian memory writes (Rainer) + 6. Add functions to zipfile.c for writing Zip64 extra fields (Rainer) + 7. Major changes to putlocal, putcentral, and putend (Rainer) + 8. Fixing -F and -FF for Zip64 postponed (Ed and Rainer) + 9. Command line code replaced. Global table sets options, long options now + supported. Permutes so order of arguments can vary (Ed) +10. Fix bug where not allowed to use -@ with stdout but was with stdin. + Now can read filenames from stdin using -@ and output to stdout and + no longer am allowed to use -@ if reading from stdin (Ed) +11. Replace stat() with zstat(), fstat() with zfstat() and struct + stat with z_stat in Zip64 blocks. Put 64-bit file calls in ifdef + LARGE_FILE_SUPPORT blocks. Can implement Zip64 without > 4 GB + file support but for now need large files for Zip64 support (Ed) +12. Move port-specific code to osdep.h and win32.c (port specific) and + tailor.h (generic) and remove temporary os_io.c. As OF() is + not defined until after osdep.h includes in tailor.h function + prototypes for zfseeko, zftello, and zstat after that in tailor.h (Ed) +13. Settings of ZIP64_SUPPORT and LARGE_FILE_SUPPORT automatic based on + port and version of compiler. Defining NO_ZIP64_SUPPORT or + NO_LARGE_FILE_SUPPORT overrides this (Ed) +14. Bugs compiling scanzipf_fix(...) in zipfile.c and the fix functions could + use rewrite (Rainer and Ed) +15. Add prototype for zfopen for mapping to 64-bit fopen on ports using + inodes but not implemented (Ed) +16. More work on extended local headers and encypted archives (Rainer) +17. Fix DLL files so now compiles (Ed) +18. File size in dll limited to 32-bit in structure. A new DLL api is needed + to return 64-bit file sizes. Current api fixed to return max 32-bit if + more than that (Ed) +19. Add local header Zip64 support and local extra field. Fixed cast + to ulg missed previously that forced zstat to return value mod 4 GB in + zipup.c which kept local header code from seeing actual file size (Ed) +20. Add new option --force-zip64 to force use of zip64 fields. Could + be temporary (Ed) +21. Fix for VB added to api.c that just store the passed strings internally. + Should update api to optionally return file sizes as 64-bit in call back + and to accept RootDir and other strings in same call that zips (Ed) +22. Readme updated to describe new features and mention updated mail group + web links (Ed) +23. Minor bugs in output format found and fixed. Now can add + files > 4 GB to archive and unzip using major unzippers (Ed) +24. If zip used as filter (zip - -) and sizes exceed limits of extended + local header (data descriptor) then set max 32-bit values there. Major + unzippers ignore and use central directory values which are correct. Can + create Zip64 data descriptor using --force-zip64 option but seems no need + for it (Ed) +25. A few bugs in how headers are handled prevented zipping large numbers + of files. Fixed (Rainer) +26. A bit of an attempt to fix -F and -FF. Seems to work but not that + robust. More work needed (Ed) +27. After some cast and other fixes zip compiles on Linux Red Hat 9 using Unix + generic. Added automatic detection of fseeko64 and if detected + sets LARGE_FILE_SUPPORT and setting that sets ZIP64_SUPPORT. Works but + could not test large files on the small system (Ed) +28. Tried to fix bug that prevents zipnotes from compiling when ZIP64_SUPPORT + is set. Still broke. This crashes the Unix Makefile but after + zip is compiled (Ed) +---------------------- May 8th 2004 version 3.0b ---------------------- + 1. Update license headers on more files (Ed) + 2. Change many ZIP64_SUPPORT ifdefs to LARGE_FILE_SUPPORT where appropriate. + Now can test ports using three stages, compile with NO_LARGE_FILE_SUPPORT + (which disables ZIP64_SUPPORT) to test base code, compile with + NO_ZIP64_SUPPORT to test the 64-bit file calls (assuming port sets + LARGE_FILE_SUPPORT) but otherwise use the base code, and without either + to test Zip64 if enabled on port (Ed) + 3. Fix zipnotes bug by moving a ZIP64_SUPPORT block in zipfile.c (Ed) + 4. Add Large File Summit (LFS) code to Unix port to enable 64-bit calls. + Update configure to include test for all needed 64-bit file calls before + enabling LARGE_FILE_SUPPORT for unix port (Ed) + 5. Merge encryption code from zcrypt29 (files from unzip) into zip and + enable by default (Ed) + 6. New man pages for zipnote, zipsplit, and zipcloak (Greg, Ed) + 7. Add encryption notice to crypt.c comments and to version information + in zip.c (Greg, Ed) + 8. Add Russian OEM EBCDIC support when OEM_RUSS defined in ebcdic.h but + Dmitri reports that 0x2F not '/' so make recommended change in cutpath + call in zipfile.c used by -D option (Dmitri - Nov 10 2003 email) + 9. ToDo30 file added to list what's left to do in this release (Ed) +10. Change fopen to zfopen for large file code and map to fopen64 for + Unix (Ed) +11. ftello64 seems broken in zipup.c on Linux (kernel 2.4), returning + negatives past the 2 GB barrier, though ftello64 works in a test program. + Likely error in defines. For now skip ftello64 check for Unix with + LARGE_FILE_SUPPORT. +12. A few updates in Readme. Needs overhaul likely. Also verified mxserver + is gone and replaced with list addresses (Ed) +13. First iterations at updating WinDLL for Zip64 (Mike) +14. Decide to drop backward dll compatibility in favor of a cleaner + dll interface. Decide to add string interfaces for VB (Ed, Mike) +15. Add string interfaces to dll interface to bypass array limitations + imposed by VB and add -x and -i to interface (Mike) +16. Create new VB example using new Zip64 dll interface (Ed) +17. Add O_LARGEFILE define for zopen in unix/zipup.h to enable reading + large files in unix (Ed) +18. Combine ZpSetOptions and ZpArchive dll calls to allow removing all VB kluges + in api.c to work around VB garbage collecting passed strings (Mike) +19. Change new VBz64 example to use updated interface. All works without + kluges (Ed) +---------------------- August 15th 2004 version 3.0c ---------------------- + 1. Add date formats in -t and -tt date errors (Ed) + 2. Add -so to display all available options (Ed) + 3. Many fixes from Dan Nelson to fix some large file support problems and + add large file support to a few ports. Main change is rather than use + explicit 64-bit calls like fopen64 now set 64-bit environment and use + standard calls. Also add a define for 64-bit printf format used to + print 64-bit stats (Dan, Ed) + 4. Changes to Unix config based on suggestions from Dan Nelson. Check + if off_t is at least 64 bit (Dan, Ed) + 5. Add -- to get_option. Any arguments after -- on command line now + read as paths and not options (Ed) + 6. Add extended help (Ed) + 7. Change add_filter flag parameter from char to int as some compilers have + problems with char arguments (Ed) + 8. Changed filter() to do R and i separately so i has precedence over R (Ed) + 9. Split variable t in zip.c into t (off_t) and tf (ulg) (Ed) +10. Add quotes to zipname in check_zipfile for MSDOS to allow spaces in + archive path given to unzip to test ( , Ed) +11. Move zip.h include before ctype.h include in trees.c and zipup.c as + when ctype.h is first and using 64-bit environment at least on unix port + found it defines off_t as 4 bytes in those files as off_t is defined as + 8 bytes in other files and this changes the size of the zlist structure + which is not good (Ed) +12. Add default 64-bit file environment to tailor.h if LARGE_FILE_SUPPORT + is set but no port 64-bit file defines are set up earlier in the file. + Should allow other ports to set LARGE_FILE_SUPPORT on the compiler + command line to test if the standard defines work (Ed) +13. Adjust binary detection in trees.c by changing 20% binary (4 out of 5 + ascii) that used >> 2 to 2% (64 out of 65) using >> 6 instead. + trees.c (Ed) +---------------------- November 12th 2004 version 3.0d ---------------------- + 1. Add global variable for EncryptionPassword in VBz64 example and + some other password callback cleanup (Ed) + 2. Add -W option to turn on WILD_STOP_AT_DIR where wildcards will not + include directory boundaries in matches (Ed) + 3. Add -nw option "no wild" to completely disable wildcards in MATCH + function. Allows a list of files to be read in without worrying about + wildcards or escapes (Ed) + 4. Add -s option split-size but not implemented (Ed) + 5. Add -sp option split-pause but not implemented (Ed) + 6. Add changes for WiZ including moving Win32 64-bit wrappers into + win32i64.c to avoid naming conflict between libraries in WiZ (Mike, Ed) + 7. Some large file fixes in crypt.c (Ed) + 8. Add new error code ZE_UNSUP for unsupported compiler options. Add + check of size of zoff_t in zip.c when LARGE_FILE_SUPPORT enabled (Ed) + 9. Changed ZE_UNSUP to ZE_COMPERR to avoid conflict with unzip (Ed) +10. On VMS (sufficiently recent, non-VAX), DECC$ARGV_PARSE_STYLE is set + automatically to preserve case of the command line if the user has + SET PROCESS /PARSE = EXTEND. This obviates quoting upper-case + options, like -V, when enabled. VMS.C (Steven Schweda (SMS)) +11. On VMS, building with macro VMS_PRESERVE_CASE defined preserves case + of names in archive, instead of forcing lower-case (the former and + current default behavior). VMSZIP.C (SMS) +12. On VMS, in some of the simplest cases, ODS5 extended file name + escape characters ("^") are removed from names in archive. + VMSZIP.C (SMS) +13. On VMS, fixed a problem in some cases with mixed-case directory + names, where too much of the directory hierarchy was included in the + path names in the archive. VMSZIP.C (SMS) +14. On VMS, minor changes for large file support (long -> zoff_t). + VMSZIP.C (SMS) +15. On VMS, changed some structure declarations to typedefs, and + rearranged to simplify #if's and reduce potential name conflicts. + VMS.H, VMS_IM.C, VMS_PK.C (SMS) +16. On VMS, reformed -V (/VMS) processing. Added -VV (/VMS=ALL). + Removed some sign bits to accomodate files bigger than 2GB. + CMDLINE.C, VMS_IM.C, VMS_PK.C, ZIP.C, ZIP_CLI.CLD, ZIP_CLI.HELP, + ZIPUP.H (SMS) +17. Update command line options to support -VV as distinct option (Ed) +18. More VMS changes (SMS) +19. Add zoff_t format function (SMS) +20. On VMS, when -b was not used, temporary archive files were always + created in the current default directory, rather than in the archive + file destination directory. VMS now uses its own tempname() + function. FILEIO.C, VMS.C (SMS) +21. Remove using FNMAX for path size in a few places including filetime.c + to avoid exceeding limit (based on fixes from Greg and others) (Ed) +22. Add port atheos (Ruslan Nickolaev, Ed) +23. Bug fix adds different extra fields for local and central in VMS (SMS) +24. Now short options also take optional values as next argument (Ed) +25. Change -dd to control -v dots (SMS, Ed) +26. On VMS, a new open callback function senses (where supported) the + process RMS_DEFAULT values for file extend quantity (deq), + multi-block count (mbc), and multi-buffer count (mbf), and sets the + FAB/RAB parameters accordingly. The default deq is now much larger + than before (16384, was none), and the default mbc is now 127 + (up from 64), speeding creation of a large archive file. Explicitly + set RMS_DEFAULT values override built-in defaults. OSDEP.H, VMS.C + (SMS) +27. VMS CLI definitions and CLI help have been updated, and may be + approximately correct. CMDLINE.C, ZIP_CLI.CLD, ZIP_CLI.HELP (SMS) +28. The man file zip.1 updated and Makefile updated to generate manual + pages for zipcloak.1, zipnote.1, and zipsplit.1 (Ed) +---------------------- July 23rd 2005 version 3.0e ---------------------- + 1. Debian patch 004 - apply 2.4i configure changes from Onno to remove + need for -fno-builtin in unix/configure (Onno, Ed) + 2. Debian patch 005 for bug 279867 - fix bug that could crash on large paths + and create security problem. Apply patch changes from Greg (Greg, Ed) + 3. SourceForge patch 1074363 - add win32i64.c to win32/makefile.w32 (Ed) + 4. Add check when not ZIP64_SUPPORT in scanzipf_reg() in zipfile.c if + Zip64 archive being read (Ed) + 5. Renamed fzofft() used to format zoff_t values to zip_fzofft() to remove + conflict when combined with UnZip in WiZ (Mike) + 6. Add check in scanzipf_reg() in zipfile.c if Zip64 archive being read (Ed) + 7. Fixes for amiga/makefile.azt to define directory for object files (Paul) + 8. Define prototypes for local functions optionerr, get_shortopt and + get_longopt in fileio.c. Define err argument of optionerr as ZCONST (Paul) + 9. Add help_extended and DisplayRunningStats prototypes, fix other prototypes + in zip.c (Paul) +10. Split int kk off of k for argument types (Paul) +11. Aztec #endif quirk fix in zip.c for Amiga (Paul) +12. Add detection of binary in first buffer read from file in zipup.c to avoid + a -l or -ll translation on binary file. Not perfect but at least should + catch some binary files (Ed) +13. Remove check for >= 128 from binary check in zipup.c as <= 6 enough for + signed char (SMS, Ed) +14. SF Bug 1074368 - check for empty zip file in readzipfile() in zipfile.c + (Christian d'Heureuse, Ed) +15. Add error exit to prevent archive corruption when updating a large-file + archive with a small-file program. Add ZE_ZIP64 error. + ziperr.h, zipfile.c (SMS) +16. Change percent() in zipup.c to do rounding better, handle cases near limits + while rounding, and allow negative percent returns (SMS, Ed) +17. Add function ffile_size() in zipfile.c but in #if 0 block until determine + if works on all ports under all conditions. Currently only used for size + check for Zip64 archive detection if compiled without ZIP64_SUPPORT and + this check may already be handled in scanzipf_reg() and should be added to + scanzipf_fix() when that is updated (SMS, Ed) +18. Change >>1 to /2 in zipsplit.c to allow for negative percent returns (SMS) +19. Add type uzoff_t for unsigned zoff_t things. Should clean up some casting + (Ed) +20. Based on discussions with other development groups, when data descriptors + (extended local headers) are used, force to Zip64. This is compatible + with other unzips and does not require a change of the AppNote, but the + resulting archive requires Zip64 to read. Using standard data descriptors + would mean that the zip operation would fail if a Zip64 entry was + encountered. See zipfile.c (Ed) +21. Add define SPLIT_SUPPORT to enable splits. The command line options are + done and the globals are set up but nothing more. globals.c, zip.h, and + zip.c mainly (Ed) +22. Create spanning signature at beginning of archive when splitting enabled. + If reading a split archive skip the spanning signature unless creating a + split archive. zip.c, globals.c (Ed) +23. Start implementing split archives. Define two methods. split_method = 1 + updates local headers and is the most compatible but requires updating + previous splits. split_method = 2 uses data descriptors and should work + for streams and removable media but may not be as compatible with other + zip applications. (In part based on previous discussions with Rainer.) + Updated global variables to include bytes written to just the current + entry in the current split. zipfile.c (Ed) +24. Add note about output redirection to zip.1 (?, Ed) +25. Remove num < 0 check as num now unsigned. util.c (SMS, Ed) +26. Change lastchar to lastchr in fileio.c in places to avoid function by same + name (SMS, Ed) +27. Moved #endif /* !WINDLL */ in zip.c (Mike) +28. Account for vms directory version being ;1. vmszip.c (SMS) +29. Fix Zip64 check in scanzipf_reg to use the buffer. zipfile.c (Ed) +30. Default define size_t (for use by Steve's ffile_size() function). tailor.h (Ed) +31. Enable Steve's ffile_size() function and enable large file check. It + currently does not allow file sizes over 2 GB but the code is not supporting + it anyway without large file support. Should remove that part of the check + when the casts are fixed. zipfile.c (Ed) +32. Fixes for djgpp. Now compiles with djgpp 2 (Ed) +33. Add new VC6 projects for win32 and windll (Cosmin) +34. Convert some variables in zipsplit.c from ulg to zoff_t so compiles (Ed) +35. Add wildcards to extended help. zip.c (Ed) +36. For optional option value now '-' is same as missing value. fileio.c (Ed) +37. Remove extra free() from -dd option switch. zip.c (Ed) +38. Change write_unsigned_to_mem() to write_ulong_to_mem() and write_short_to_mem() + to write_ushort_to_mem(). zipfile.c (Ed) +39. Create new append to mem functions. zipfile.c (Ed) +40. Change zlist nam and ext from extent to ushort as that is what gets written. + zipfile.c (Ed) +41. Change GetSD to use ush instead of size_t. win32/win32zip.c (Ed) +42. Change PutLocal(), PutExtended(), PutCentral(), and PutEnd() to write to + memory and then write the block at once to the file. zipfile.c (Ed) +43. Change zcomlen from extent to ush, other extent conversions. zipfile.c, + globals.c, zip.h (Ed) +44. Add is_seekable() and global output_is_seekable. Do seekable check + when output file is opened. zipup.c, globals.c, zip.h, zip.c (Ed) +45. Do not increment files_so_far and bytes_so_far if file could not be read. + zip.c (Ed) +46. If force_zip64 set, only force compressed size in central directory to Zip64 + instead of all entries (csize, usize, off, disk) in Zip64 extra field. This + fixes inconsistent handling of disk numbers. zipfile.c (Ed) +47. Add end status if displaying running stats and not all files were read. + zip.c (Ed) +48. Change force_zip64 to zip64_archive in putend(). zipfile.c (Ed) +49. Enable the i686-optimized code by default. crc_i386.S, + win32/crc_i386.asm, win32/crc_i386.c (Cosmin) +50. Document and implement a new text detection scheme provided by Cosmin in + set_file_type(). Should be able to handle UTF-8 and some other character sets. + proginfo/txtvsbin.txt, trees.c (Cosmin, Johnny, Christian) +51. Update binary detection for -l and -ll to use Cosmin black list. zipup.c (Ed) +52. Change ZE_BIG to include read and write. ziperr.h (Ed) +53. If archive not seekable then use data descriptors. If ZIP64_SUPPORT always + create Zip64 data descriptors and add a Zip64 extra field to flag it is + a Zip64 data descriptor. This is klugy but should be compatible with other + unzips. See the note in zipfile.c for details. (Ed) +54. Use ush for comment length in putend(). Instead of extent use ush for + zcount and fcount same as in zip file. zip.h (Ed) +55. Update VB readme. windll/VB/readmeVB.txt (Ed) +56. Change (INSTALL) to (INSTALL_PROGRAM). unix/Makefile (, Ed) +57. During update the file and byte status counts were off. Fixed by not coun- + ting files copied from old to new as those are not in totals. zip.c (Ed) +58. Change from -b to -bx for nroff of manuals to text files. unix/Makefile (Ed) +59. Add cygwin to makefile. unix/Makefile (, Ed) +60. Fix bug where files to delete not added to list. zip.c (Ed) +61. Fix delete stats. zip.c (Ed) +62. Increment version of crypt to 2.10. Update default behavior notes. + crypt.c, crypt.h (Paul, Christian) +63. Format changes, add parentheses to zfseeko(), fix output bytes, add ifdef + blocks for ZIP10, fzofft formatting, casts. crypt.c (Christian) +64. Cast block_start to unsigned. deflate.c (Christian) +65. Let -R patterns match in subdirectories. Update filter() to use switch, + use global icount and Rcount, handle subdirectories, update icount and + RCount in filterlist_to_patterns(). fileio.c, zip.c, zip.h, globals.c + (Christian) +66. Enclose option -! and use_privileges under NTSD_EAS guard. globals.c, + zip.c, zip.h (Cosmin) +67. Updates to version, copyright, license. [I did not split the copyright + to 2 lines as it already takes up space on the help screen. Ed] + revision.h (Christian) +68. Add ZCONST to some read-only string pointer arguments in function + declarations. zipcloak.c, zipnote.c, zipsplit.c, zip.c, zip.h (Christian) +69. Fix byte counts on exit in zipcloak() and zipbare() to fix zipcloak bug + (Christian) +70. Modified zipnote.c to use WRBUFSIZ to handle line widths of at least 2047 + characters in write mode (Christian) +71. Change simple() and greedy() from zoff_t to uzoff_t. zipsplit.c (Christian) +72. Remove duplicate copyright notices. zipsplit.c (Christian) +73. Remove export notice from help page. Move notice to bottom of license + page. zipcloak.c (Ed) +74. File USexport.msg export history added. (Greg) +75. Added support for VMS ODS5 extended file names. (Eight-bit only, no + Unicode.) VMS name character "/" is mapped to Zip name character + "?". New command-line options -C[2|5][-] (/PRESERVE_CASE[=opts]) + control name case preservation and/or down-casing. globals.c, + zip.c, zip.h, vms/cmdline.c, vms/vms_im.c, vms/vms_pk.c, vms/vms.c, + vms/vmszip.c, vms/vms.h (SMS) +76. New VMS option -ww (/DOT_VERSION) stores version numbers as ".nnn" + instead of ";nnn" [changed from -Y to -ww (Ed)]. zip.c (SMS) +77. Changes to vms_open(). vms/vms_im.c, vms/vms_pk.c +78. Changes to vms_read(). vms/vms_pk.c (SMS) +79. Documentation updates. vms/vms_zip.rnh (SMS) +80. Minor updates. vms/zip_cli.help, vms/cmdline.c, vms/vms_zip.rnh (Ed) +81. Changes to vmsmunch(). vms/vmsmunch.c (SMS) +82. Do some updating of VMS options. vms/zip_cli.cld (SMS) +83. Moved the VMS-specific ziptyp() function from zipfile.c to vms/vms.c + to segregate better the RMS stuff. (SMS) +84. Put 64-bit calls in ZIP64_SUPPORT ifdef blocks, change some long parameters + for append to memory block functions to ulg, remove redundant includes, + add OFT protos to some functions with parameter types that get promoted + like ush to avoid warnings in VMS. zipfile.c (SMS) +85. Use zip_fzofft() to format number. zipsplit.c (SMS) +86. Add file_id.diz from Zip 2.31 (?, Ed) +87. Update install from Zip 2.31 (?, Ed) +88. Update license from Zip 2.31. License (?, Ed) +89. Update Readme.cr from Zip 2.31 (?, Ed) +90. Add 64-bit assembler for Win32 from Zip 2.31. win32/makefile.a64, + win32/readme.a64, win32/gvmat64.asm (?, Ed) +91. Update Readme (Ed) +92. Update headers. crctab.c, crc32.c, deflate.c, ebcdic.h, fileio.h (Ed) +93. Option for extra verbose VMS, change DIAG_FLAG from verbose to + (verbose >= 2). vms/vms.c (SMS) +94. Update copyright header. qdos/qdos.c (Christian, Ed) +95. Change exit(0) to exit(ZE_OK). qdos/qdos.c (Christian) +96. Change ulg to unsigned long. tailor.h (, Christian) +97. Default uzoff_t to unsigned long long if LARGE_FILE_SUPPORT manually + enabled for an otherwise unsupported port. tailor.h (Ed) +98. Update copyright header. tailor.h (Ed) +99. Change EXIT(0) to EXIT(ZE_LOGIC) for ziperr recursion. zip.c (Christian) +100. Change EXIT(0) to EXIT(ZE_OK) for successful returns. zip.c, + zipcloak.c (Christian) +101. Update license. zip.h (Christian) +102. Initialized mesg in zipcloak.c, zipnote.c, zipsplit.c to fix access + violation crashes. (Christian) +103. Added -q (Quiet mode) option to zipcloak, zipnote, zipsplit. (Christian) +104. Add proto of mb_clen(). fileio.c (Cosmin) +105. Synchronize ttyio.c and ttyio.h with the unzip-5.52 source. (Cosmin) +106. Control the POSIX emulation provided by some Unix-on-Windows compiler + distributions, such as Cygwin, via the FORCE_WIN32_OVER_UNIX macro. + tailor.h, win32/Makefile.gcc (Cosmin) +107. Remove getenv() declaration. util.c (Cosmin) +108. Fix definitions of zopen and zstdin. unix/zipup.h (Cosmin) +109. Enable binary file operations for DJGPP and Cygwin. unix/osdep.h (Cosmin) +110. Remove -DMSDOS from CFLAGS; use correct dependency in target crc_i386.obj. + win32/makefile.w32, win32/makenoas.w32 (Cosmin) +111. Update win32/makefile.bor and win32/makefile.gcc (Cosmin) +112. Put mktemp() declaration inside the NO_PROTO guard. tailor.h (Cosmin) +113. Use the right type (DWORD) for volSerNo, maxCompLen and fileSysFlags + in FSusesLocalTime(). win32/win32.c (Cosmin) +114. Set the "zip Debug" configuration as default. win32/vc6/zip.dsp (Cosmin) +115. Define ASM_CRC by default. win32/osdep.h (Cosmin) +116. Avoid using file names that are distinguished solely by letter case; + e.g. crc_i386.S and crc_i386.s. unix/Makefile (Cosmin) +117. Stylistic fix inside ex2in(). unix/unix.c (Cosmin) +118. Change zlist dsk from ush to ulg to support Zip64 and added casts in + zipfile.c to write ush. zip.h, zipfile.c (Christian, Ed) +119. Conditionally apply S_IFLNK to support DJGPP. unix/unix.c (Cosmin) +120. Change -dd [siz] (display dots, set optional dot size) to the options + -dd (turn dots on, use 10 MB default) and -ds siz (set dot size). + Found that using -dd with an optional value got confusing as detection + of an optional argument, when the next argument was not either an option + or the end of the line, was easy to overlook. Easier to avoid optional + values. zip.c (Ed) +121. Change text output of manual pages to zip.txt, zip.txt, zipcloak.txt, + zipnote.txt, zipsplit.txt. unix/Makefile (Christian, Ed) +122. Change comments using // to /* */ format. api.c, zip.c (Christian) +123. Add support for signals SIGABRT, SIGBREAK, SIGBUS, SIGILL, and SIGSEGV + to utilities. zipcloak.c, zipnote.c, zipsplit.c (Christian) +124. Update ToDo30.txt file (Ed) +125. Delete old Manual file (Ed) +126. Update WHERE from Zip 2.32 (Ed) +127. Change description of dot-size. zip.c (Ed) +128. Change VMS to use -ds to set dotsize. vms/cmdline.c (Ed) +129. Update manuals. man/zip.1, man/zipsplit.1, man/zipnote.1, + man/zipcloak.1 (Ed) +130. Detect i586, i686 and Cygwin in version_local(). unix/unix.c (Cosmin) +131. Add clean target. win32/makefile.w32, win32/makenoas.w32 (Cosmin) +132. Changed most 64-bit size/offset variable declarations (like zoff_t) + into "unsigned" type (like uzoff_t), for better backward compatibility + with non-ZIP64_SUPPORT setups where "ulg" was used for these variables. + deflate.c, fileio.c, globals.c, trees.c, vms/vms_pk.c, win32zip.c, + zip.c, zip.h, zipfile.c, zipup.c (Christian) +133. Add (ulg) cast to strstart in flush_block. deflate.c (Christian) +134. Updated Win32 LARGE_FILE_SUPPORT setup for Watcom and MinGW. + tailor.h, win32/osdep.h (Christian) +135. Add attempt count to tempname(). fileio.c (Christian) +136. Fixed size counter handling in debug code for Zip64. trees.c (Christian) +137. Moved cryptnote display text definition into revision.h, like was done + in Zip 2.31. zip.c, revision.h (Christian) +138. Add ZCONST. fileio.c (Christian) +139. Removed earlier change in trash() where ASCII-containing iname was + searched for native-coded '/' characters. [Added note but left as + changed 5/20/05 EG] zipfile.c (Christian) +140. Change zipup size error message to use zip_fzofft(). zipup.c (Christian) +141. Updated win32/makefile.wat to enable Zip64 support and use directory + for intermediate files. (Christian) +142. Change fcount and zcount from ulg to extent as extent is used internally, + but Zip64 standard supports up to ulg. Add note to zip.h. globals.c, + zip.h (Christian) +143. Define NO_W32TIMES_IZFIX in compile options when appropriate. Add + version information for USE_ZLIB compiler option. zip.c (Christian) +144. Add support for SIGABRT, SIGBREAK, SIGBUS, SIGILL, and SIGSEGV signals. + zip.c (Christian) +145. Add display-usize option to show uncompressed size. zip.c (Ed) +146. Add many descriptions to options table. zip.c (Ed) +147. Remove -R from help screen as on extended help screen. zip.c (Ed) +148. Add basics to extended help. zip.c (Ed) +149. Fix checks in scanzipf_reg() for empty file since cenbeg now unsigned. + Change buffer from t to b in small big check. Back up after small + zip big archive check. zipfile.c (Ed) +150. Change Zip64 not supported warning in scanzipf_reg(). zipfile.c (Ed) +151. Fix bug where local and central headers were not matching when compiled + with NO_LARGE_FILE_SUPPORT. Restored order of zlist structure elements + to match order of local header as scanzipf_reg() compares it as an + array of bytes to the local header. Gag. It needs fixing but at least + it works as intended now. zip.h, zipfile.c (Ed) +152. Minor fix from 10000 to 10 K for WriteNumString(). util.c (Ed) +153. Add overflow check to file_read(). zipup.c (SMS) +154. Add parameter p1 product specification. vms/collect_deps.com (SMS) +155. VMS changes. vms/descrip_mkdeps.mms (SMS) +156. Change zoff_t to uzoff_t and unsigned int to size_t. vms/vms_im.c, + vms/vms_pk.c (SMS) +157. Fix ; that was : at end of line. Fix DisplayNumString() prototype. + zip.h (Ed) +158. Get rid of leading blanks in DisplayNumString(). util.c (Ed) +159. Reset dot_count each file. zipup.c (Ed) +160. Minor changes to extended help. zip.c (Ed) +161. Move defines into DEFINED_ONCE block. api.h (Mike) +162. Add Still Remaining And Planned For Zip 3.0 section. WhatsNew (Ed) +163. Delete quotes around CHANGES. Readme (Ed) +164. Add -lf, open file at path and use for logging, -la, append to + existing logfile, and -li, include informational messages, options. + globals.c, zip.h, zip.c (Ed) +165. Update extended help to include logging. zip.c (Ed) +166. Add support for required short option value in form -o=value as optional + does. fileio.c (Ed) +167. If bytes_total is smaller than bytes_so_far for some reason then display + negative of bytes_to_go. This can happen if files grow in size after all + the sizes are initially added up. zip.c (Ed) +168. Use usize from filetime for adding to bytes_total when updating instead + of size in old entry. zip.c (Ed) +169. Change status counts files_so_far and bytes_so_far to include bad files + so the status counts end at the end but add bad_files_so_far and + bad_bytes_so_far to track bad files. After minor fixes it looks like + the counts remaining at the end are correct, even when some files are + not readable. Update bad file warnings. zip.c, zip.h, globals.c, + zipup.c (Ed) +170. Add uq for unsigned q in zipup(). Initialize z->len in case an error + later so have a valid size. zipup.c (Ed) +171. Check noisy in DisplayRunningStats() so logging is independent of it. + zip.c (Ed) +172. Add check in DOS for windows and if running DOS version on Windows warn + user. zip.c, msdos/msdos.c, msdos/osdep.h (Johnny) +173. Add errno.h for strerror(errno) call. zip.c, zipup.c (SMS) +174. Fix log problem if using -q option. zipup.c (Ed) +175. Change "Far char" to "char Far" as Far is a qualifier not for the char + type but the storage allocation of the array. fileio.c (Christian) +176. Update note on extent. globals.c (Christian, Ed) +177. Remove extra USE_ZLIB. zip.c (Christian) +178. Add note for the OEM_RUSS '/' bug. Need to look at later as it seems + the Russian bug remains unfixed. zipfile.c (Christian, Ed) +180. So byte counts always come out even, create good_bytes_so_far to + count bytes read in and convert bytes_so_far to use the counts + from the initial scan. If files change during the zip operation + good_bytes_so_far will change and not match bytes_so_far. + zip.h, globals.c, zip.c (Ed) +181. Changes to extended help. zip.c (Ed) +182. Update WhatsNew (Ed) +183. Update DLL resource copyright. windll.rc, windll.aps (Ed) +184. Add directory search improvements to Win32 (within recursion, reuse + attribs from directory lookup to avoid calling stat()). Add + getd_attribs(), procname_win32(). win32/win32zip.c (Johnny) +185. Cache result of IsFileSystemOldFAT() to avoid repetitive system calls + for identical information. win32/win32.c (Johnny) +186. Add optimization to dosmatch(): apply alternate shortcut code when the + pattern to match consists of one multichar wildcard ('*') followed + by a fixed string. util.c (Johnny) +187. Move DOS check_for_windows() checks to Help and Version and errors + only. Shorten message to one line. zip.c, msdos/msdos.c (Ed) +188. Define WIN32_OEM to enable oem ansi conversions for more than RSXNT. + Not yet fully implemented. win32/win32.c, win32zip.c, zip.c, + zipfile.c (Ed) +189. Directory search improvements for MSDOS. msdos/msdos.c (Johnny) +190. Add caching of directory information. If pattern is just *string no + need to recurse. win32/win32.c (Johnny) +191. If wild_stop_at_dir then do recurse to handle cases like a/b/*.txt. + win32/win32.c (Ed) +192. Additional improvements to directory search speedups, including + a) MSDOS port fixes for Turbo C++ compiler + b) In both Win32 and MSDOS, change getDirEntryAttr() into macro, + saving one function call overhead + e) Add explaining comment to optimized procname_{local} code + f) In util.c, move "*literal" pattern-matching optimization from + dosmatch() to recmatch(). Advantages: + - optimization used for all systems + - optimization applied to all occurences where a "*" is last wildcard + in pattern + - "dosmatch()" only preconditoning wrapper for matching workhorse + "recmatch()", it should not implement matching algorithms itself + - optimization not applied for WILD_STOP_AT_DIR option + g) >>>disabled<<< "*literal" optimization for all MBCS-aware environments, + because suspect that supplied optimization code is not MBCS-clean + (for details see the comment within the patch), so IS NOT USED for + win32 port! Can force activation of match optimization by specifying + conditional compilation symbol TEST_FOR_MBCS_CLEAN. + (Christian) +193. Add and move comments, implement changes for directory search improvements + in Zip 3.0 util.c (Ed) +194. In win32/win32.c, IsFileSystemOldFAT(), add declarations of static caching + variables where missing to fix win32 port compilation bug (Christian) +195. Correct changed arguments in RSXNT-only character set conversion + call. win32/win32zip.c (Christian) +196. Implement Directory Search improvements from Zip 2.32. win32/win32zip.c + (Johnny, Ed) +197. Debian Bug #312090 fix. Reworded man page to give multiple examples of + recursion, not just zip -r foo foo. man/zip.1 (Ed) +198. Change "-Aa -D_HPUX_SOURCE +e" to -Ae for HP. "HP-UX with the HP compiler + and on AIX 4.2.0. AIX 5.1 with gcc-3.4.3 (32-bit) and Darwin built fine + - though AIX 5.1 needed CC=gcc make -e ... to find gcc. According to the + HP-UX man page -Ae is equivalent to -Aa -D_HPUX_SOURCE +e it seems the + +e is needed and -Ae is more terse anyway." Expression generated before + was too long. unix/configure (Rodney Brown) +199. Add support for osf4.0f that does not have fseeko or ftello but has 64-bit + fseek and ftell though. tailor.h (Rodney) +200. Fix unsigned char to char in recmatch(), add casts for compares. util.c + (Ed) +201. Fix for alpha off_t long long. unix/osdep.h (Rodney) +202. Change shmatch() from uch to char and change parameters to recmatch(). + Change dosmatch(). util.c (SMS, Rodney, Ed) +203. Add local for DisplayRunningStats(). zip.c (Rodney, Ed) +204. Disable unused append_ubyte_to_mem(). Fix error messages in other append. + zipfile.c (Rodney, Ed) +205. Delete unused getDirEntryAttribs(). msdos/msdos.c (Christian) +206. Change warning when running msdos version on Windows. msdos/msdos.c (Ed) +207. Change recmatch() to support MBCS matching. util.c (Christian) +208. Update WhatsNew (Ed) +209. Update Readme (Ed) +210. Format Readme to fit in 80 character lines (SMS, Ed) +211. Rename install.vms to install_vms.txt. vms/install_vms.txt (SMS) +212. Add reference to vms/install_vms.txt in INSTALL (SMS) +213. Update INSTALL (Ed) +214. Remove ALT_NEXTBYTE and Building UnZip sections as no longer needed. + vms/notes.txt (SMS, Ed) +215. Add note to TODO (Ed) +216. Update Makefile message to suggest using generic. unix/Makefile (Ed) +217. Update text output of manual. zip.txt (Ed) +218. Update VMS section. INSTALL (SMS, Ed) +219. Minor changes in vms/install_vms.txt (SMS, Ed) +220. Update VMS install information. INSTALL, vms/install_vms.txt (SMS, Ed) +221. Do not use _stati64 under Cygwin. win32/osdep.h (Cosmin) +222. Add note to Makefile to use generic first. unix/Makefile (Ed) +223. Add Test option for VMS CLI. vms/cmdline.c (SMS, ?) +224. Add noconfirm to deletes, define symbol edit. vms/descrip.mms (SMS) +225. Changes to vms/install_vms.txt (SMS) +226. Add note on symbols to VMS. INSTALL (SMS) +227. Update license headers. vms/osdep.h, vms/vms.h, vms/vmsmunch.c, + vms/zipup.h, vms/vmszip.c, vms/vms.c, vms/vms_im.c, vms/vms_pk.c, + vms/command.c (Ed) +228. Add stsdef.h include for VMS and convert unzip test return to VMS + result for VMS. zip.c (SMS) +229. Add const to ziperr(). amiga/amiga.c (Paul) +230. Clean up makefile. amiga/makefile.azt (Paul) +231. Don't try Amiga large file support. amiga/osdep.h (Paul) +232. Add note on -V and -VV. vms/notes.txt (SMS) +233. Small update. vms/zip_cli.help (SMS) +234. Format Windows warning message. msdos/msdos.c (Christian) +235. Format changes. util.c (Christian) +236. Update VMS. INSTALL (SMS) +237. Add creation of intermediate object directories. msdos/makefile.wat + (Christian) +238. Add void * cast. msdos/msdos.c (Christian) +239. Add include for mktemp(). msdos/osdep.h (Christian) +240. Fix __RSXNT__ and WIN32_OEM define blocks. win32/win32.c (Christian) +241. Fix __RSXNT__ and WIN32_OEM define blocks. win32/win32zip.c (Christian) +242. Add != NULL to check. zip.c (Christian) +243. Fix WIN32_OEM. zipfile.c (Christian) +---------------------- October 11th 2005 version 3.0f01 ---------------------- +(the internal betas may be merged later) + 1. Add DSEG for Watcom data segment. msdos/makefile.wat (Christian) + 2. Add -zq and use assembler. os2/makefile.os2 (Christian) + 3. Update header. os2/match32.asm (Christian) + 4. Change len from int to unsigned int. os2/os2.c (Christian) + 5. In GetLongPathEA() limit tempbuf to CCHMAXPATH. os2/os2.c (Christian) + 6. Add DWATCOM_DSEG to use data segment. win32/makefile.wat (Christian) + 7. Update header and add DGROUP. win32/match32.asm (Christian) + 8. Add UNICODE_SUPPORT define. zip.h, zip.c (Ed) + 9. Add oname to f and z structs for the display name to use in messages. + Change z->zname to z->oname in messages. fileio.c, zip.c, win32zip.c, + zipup.c, zipfile.c, zip.h (Ed) +10. Move multi-byte defines to make global (they were needed with wide + characters but that was taken out and left them where they are). + fileio.c, zip.h +11. Add copy_args(), free_args(), and insert_arg() to create copy of argv + that can free() and to support inserting "@" in get_option for lists. + fileio.c, zip.h +12. Insert arg "@" after list if not followed by option. fileio.c +13. Add args variable and copy argv to args so can use insert_arg(). zip.c +14. Add MKS Korn Shell note. zip.c +15. Change cast of option in add_filter() calls from char to int. zip.c +16. Implement multi-byte version of Unicode support. To support Win32 NT + wide calls will require additional work not planned for this release. + Changes include (Ed): + - Add use_wide_to_mb_default flag. globals.c, zip.h + - Add compiler UNICODE_SUPPORT version information. zip.c + - Add uname to f and z structs for UTF-8 name. zip.c + - Moved some defines out of ZIP64 section. zipfile.c + - Add define UTF8_PATH_EF_TAG for Unicode Path extra field. Currently + the tag is 0x7075 which is 'u' 'p' for Unicode path and seems + free according to the AppNote. The extra field is + tag (2 bytes 'u' 'p') + size (2 bytes) + Unicode Path size (2 bytes) + unused (2 bytes set to 0) + unused (2 bytes set to 0) + Unicode path (variable) + The unused locations also serve as a check in case the tag is in + use already. + - Add add_Unicode_Path_local_extra_field() and + add_Unicode_Path_cen_extra_field() functions. zipfile.c + - Add read_Unicode_Path_entry() function. zipfile.c + - Set uname and oname in scanzipf_ref(). zipfile.c + - Add define wide_to_mb_default. Add zchar but not used. win32/osdep.h + - Add wide command line reading but don't use. win32/win32.c + - Add port functions for Unicode, including local_to_utf8_string(), + wide_to_escape_string() (for converting a wide character that can't be + converted to mb in the local character set to a reversable escape string), + escape_string_to_wide(), wide_to_local_string(), local_to_display_string() + (for creating the display version of name), utf8_to_local_string(), + local_to_wide_string(), wide_to_utf8_string() (NOT IMPLEMENTED), and + utf8_to_wide_string() (NOT IMPLEMENTED). win32/win32.c + - Implement attempt at escape function. Whenever a wide character can't + be mapped to the local character set, this function gets called. + Currently the wide character is converted to a string of hex digits. + If the wide can fit in 2 bytes then the form #1234 is used. If not, + the 4-byte form #L12345678 is used. + It compiles but needs the utf8 functions implemented. Also needs testing + in a multi-byte environment and only Windows is implemented so need to at + least do Unix. (Ed) +17. Update freeup() to include uname and oname. zip.c +18. Move define wide_to_mb_default so default for all is '_'. zip.h (Ed) +19. No changes needed to osdep.h and update unix/unix.c but not tested. (Ed) +---------------------- October 19th 2005 version 3.0f02 ---------------------- + 1. Remove null value check for split_size as get_option() already checks. + zip.c (Ed) + 2. Update f$search(). vms/descrip.mms (SMS) + 3. Save parse name before search and use that on failure. Change name parsing + in ziptyp() to solve a problem with search-list logical name device directory + specs. vms/vms.c (SMS) + 4. Compile in UNICODE_SUPPORT if have wchar_t and mbstowcs(). unix/configure (Ed) + 5. Move Unicode defines to zip.h and functions to fileio.c so generic. Create + a new OEM function for Windows. fileio.c, zip.h, tailor.h, win32/win32.c (Ed) + 6. Add UTF-8 functions. fileio.c (Paul) + 7. Convert Unicode functions to use zwchar defined as unsigned long for wide + char. fileio.c, zip.h (Ed) + 8. Add wchar_t check for Unix. unix/configure (Ed) + 9. Add default when zwchar (4 bytes) is too big for wchar_t (2 bytes). zip.h (Ed) +10. Allow for states for wide characters but surrogates not done. fileio.c (Ed) +11. Update WhatsNew (Ed) +---------------------- December 16th 2005 version 3.0f03 ---------------------- + 1. Fix broke encryption when ZIP64_SUPPORT enabled by accounting for need for + data description when encrypting. Data description is not required for + encryption (WinZip does not use one) but seems needed by Zip for some reason. + zipfile.c (Ed) + 2. Add function bfwrite() to do buffered fwrite(). Most output already is + written by zfwrite used by crypt.c which now calls bfwrite. All splitting + and new byte counts are done in bfwrite. fileio.c (Ed) + 3. Move some functions out of ZIP64_SUPPORT defines for use with UNICODE_SUPPORT. + zipfile.c, zip.h (Ed) + 4. Add is_ascii_string() and only create Unicode extra field if z->iname is + not ascii. zipfile.c, zip.h, fileio.c, (Ed) + 5. Add parameter rewrite to putlocal() to note when rewriting bytes so the bytes + rewritten are not counted in output totals. zipfile.c, zip.h (Ed) + 6. Handle VMS ... wildcard. util.c (SMS) + 7. Make tempzip file name global. zip.c, globals.c, zip.h (Ed) + 8. Add out_path global and -O path option to allow the output archive to have a + different name than the input archive, if there is one. This allows + updating a split archive, since output to the same split name would otherwise + be complicated and not user friendly. Use out_path for output. zip.h, + zip.c, globals.c (Ed) + 9. Many output functions that had output file y as parameter, such as zipup(), + zipcopy(), putlocal(), putcentral(), and putend(), now do not as y is + now global. This allows changing y as splits are created. zip.c (Ed) +10. Add function zipmessage() for writing messages like zipwarn() but are + informational. zip.c (Ed) +11. Minor changes to help. zip.c (Ed) +12. Add SPLIT_SUPPORT to version output. zip.c (Ed) +13. Add rename_split() to rename and set attributes for a split. zip.c (Ed) +14. Add set_filetype() to set attributes of split. zip.c (Ed) +15. Change variable a (holds attributes) to zipfile_attributes and make global. + zip.c, zip.h, globals.c (Ed) +16. Add key_needed flag for encryption and move setting key to after + command line processed. zip.c (SMS) +17. Initialize dot size using default only if dot_size not set. zip.c (Ed) +18. Change command line processing so that last -P or -e is used. zip.c + (Ed) +19. Fix broke writing of 4-byte spanning signature at the beginning of the archive + if splitting. zip.c (Ed) +20. Use bfcopy() instead of fcopy() to copy archive beginning. bfcopy() uses + global y. zip.c (Ed) +21. It looks like tempzf is no longer used. zip.c (Ed) +22. Account for SUNPRO_C and DECC_VER. Change SPARC to Sparc. unix/unix.c (SMS) +23. Remove GNUC. vms/cmdline.c (SMS) +24. Change case of system calls. vms/vms.c (SMS) +25. Add fix for VMS ... matching, but may change Zip to avoid ex2in() and in2ex() + for pattern matching in future. vms/vmszip.c (SMS) +26. Remove /NODIRNAMES and /DIRNAMES from VMS help. vms/zip_cli.help (SMS) +27. Define new globals zip64_eocd_disk, zip64_eocd_offset, current_local_tempname, + bytes_this_split, and bytes_this_entry for splits. globals.c, zip.h (Ed) +28. Add SUNPRO C and DEC C compile checks. unix/configure (SMS) +29. Add CFLAGS_NOOPT for removing optimization for configure. unix/Makefile (SMS) +30. Modify crypthead() to use bfwrite(). crypt.h, crypt.c (Ed) +31. Modify zfwrite() to use global output file. crypt.h, crypt.c (Ed) +32. Modify zfwrite() when no encryption to use bfwrite(). crypt.h (Ed) +33. Add bfcopy() to copy to y. fileio.c (Ed) +34. Add close_split() and bfwrite() for splits. fileio.c (Ed) +35. Add is_ascii_string() to check if UTF-8 extra field is needed. fileio.c (Ed) +36. Change Unicode escape of 2-byte wide from #1234 to #U1234. fileio.c (Ed) +37. Add read_Unicode_Path_entry() to read the UTF-8 path extra field. zipfile.c (Ed) +38. Latest Unicode Path extra field format is + 1 byte Version of Unicode Path Extra Field + 2 bytes Name Field Checksum + variable UTF-8 Version of Name +39. Use CRC-32 for Unicode Path Checksum and AND halves. zipfile.c (Paul) +40. Add Unicode Path Checksum check to make sure extra field applies to Name field + still. zipfile.c (Christian) +41. Move get_extra_field() out of Zip64 block and make available for splits. + zipfile.c (Ed) +42. Check in putlocal() using is_ascii_string() and don't create Unicode path + extra field if name is ASCII characters. zipfile.c (Ed) +43. If local header for split is on another disk and using split method 1, close + that split in putlocal() after rewrite local header. zipfile.c (Ed) +44. Fix data descriptor bug when encrypting where putextended() did not handle the + not Zip64 case, which mostly only happens now for encryption. zipfile.c (Ed) +45. Check for ASCII name using is_ascii_string() in putcentral() for Unicode path + extra field. zipfile.c (Ed) +46. Instead of single disk values, update putend() to use real split values for + current_disk, cd-start_disk, cd_entries_this_disk, cd_start_offset, + zip64_eocd_disk, zip64_eocd_offset, and current_disk and allow for + needing Zip64 if exceed standard max values for current_disk, cd_start_disk, + cd_entries_this_disk, total_cd_entries, and cd_start_offset. zipfile.c (Ed) +47. Use current_local_offset and current_local_disk for z->off and z->dsk in + zipup(). zipup.c (Ed) +48. Fix bug where force_zip64 was used to determine descriptor size but can have + Zip64 entry without force_zip64 so use zip64_entry. zipup.c (Ed) +49. Change the p - o != s compression size test for splits to bytes_this_entry + != (key ? s + 12 : s) and avoid ftell() in split. zipup.c (Ed) +50. If local header is on a previous split and split method 1 do the seek on that + split to update header. zipup.c (Ed) +51. For streaming, only force Zip64 if reading stdin and writing a non-seekable + device. In other cases can detect either the input file size and set Zip64 + if needed or seek in the output to update the local headers. zipup.c, + zipfile.c, zipup.c (Ed) +52. Allow creation of stored archives with descriptors for testing. Currently + they can't reliably be read but this is planned. zipup.c, zipfile.c, zip.c + (Ed) +53. Update help, adding in -e, -P, -s splitsize, -sp, and -sv options. zip.c (Ed) +54. Spelling fix in zipsplit man page. man/zipsplit.1, zipsplit.txt (Ed) +55. New option -sv and variable noisy_splits to enable verbose splitting. + Default is to quietly create splits, unless -sp set to pause between splits. + zip.h, zip.c, globals.c, fileio.c (Ed) +---------------------- December 23rd 2005 version 3.0f04 ---------------------- + 1. Move inlined text-vs-binary checks from file_read() into a separate, + new function named is_text_buf(). zipup.c, util.c, zip.h (Cosmin) + 2. Fix calls to putlocal to remove the removed dest parameter. crypt.c (Ed) + 3. Add get_split_path() to get the path for a split given the disk number. + fileio.c, zip.h (Ed) + 4. Change formatting of zipmessage() to remove tabbing and add formatting + to call to zipmessage(). fileio.c, zip.c (Ed) + 5. Initialize many variables such as y and tempzip. zip.c, fileio.c, + zipfile.c (Ed) + 6. Add loop to pause during split method 2 to allow changing disk or changing + the path for the next split. fileio.c (Ed) + 7. If after starting new split there is not enough room for the remaining buffer + for split method 1 display error and exit and for split method 2 we can + display a warning and user can replace disk or change path. fileio.c (Ed) + 8. Add list to store input file arguments using add_name() to add the name to + filelist_struc filelist and then process the names after the input archive + is read. zip.c (Ed) + 9. Fix infinite loop when opening a log file whose name contains multiple '/'. + zip.c (Cosmin) +10. Move split size message lower and only output if option sv sets + noisy splits. zip.c (Ed) +11. Set y to output file, remove output file from zipcopy(), putlocal(), + putcentral(), and putend(). zipsplit.c, zipnote.c, zipcloak.c (Ed) +12. Add code for not SPLIT_SUPPORT case. zipfile.c, zipup.c (Ed) +13. Prepend '-' to commands from target clean. + win32/makefile.w32, win32/makenoas.w32, win32/makefile.bor (Cosmin) +14. Must not call putenv() in iz_w32_prepareTZenv() under Cygwin. + win32/osdep.h (Cosmin) +15. Add browse info in Visual C++ 6 project. win32/vc6/zip*.dsp (Cosmin) +---------------------- December 27th 2005 version 3.0f05 ---------------------- + 1. Add proposed changes to License (Ed) + 2. Fix -l corruption bug by using memcpy() instead of wrongly changing the + buffer pointer. Fix was left out of last beta. zipup.c (Cosmin) + 3. Fix get_split_path() parameter. zip.h (SMS, Ed) + 4. Add -dg and display_globaldots to display dots globally for entire archive + instead of for each file. Is not affected by noisy flag. globals.c, + zip.h, zip.c, zipup.c, fileio.c (Ed) + 5. Make dot_count and dot_size uzoff_t, dot_count because with global dots + dot_count does not reset and with terabyte files the number of buffers + could exceed 2G, dot_size to allow use of ReadNumString() to read number. + zip.c, zip.h, globals.c (Ed) + 6. Add Deletion to help. zip.c (Ed) + 7. Fix delete date. zip.c (Ed) + 8. For streaming, need to assume Zip64 if writing a non-seekable device so + extra field for Zip64 is created if needed. zipup.c, zipfile.c, zipup.c (Ed) + 9. Add remove_local_extra_field() and remove_central_extra_field(). + zipfile.c (Ed) +10. Remove disabled copyright from license(). zip.c (Ed) +11. Clean up recent changes. zip.c, zipfile.c, fileio.c, zip.h, zipup.c (Ed) +12. Create scanzipf_regnew() for new file scan. zipfile.c (Ed) +---------------------- December 29th 2005 version 3.0f06 ---------------------- + 1. Change dot_size and dot_count from uzoff_t to zoff_t to allow use of + negative flag values. globals.c, zip.h (SMS, Ed) + 2. Remove file parameter to bfwrite() in putend(). zipfile.c (SMS, Ed) + 3. Add back code for not SPLIT_SUPPORT to putend(). zipfile.c (SMS, Ed) + 4. Change tag from ush to ulg in remove_local_extra_field() and + remove_central_extra_field() to avoid parameter problems. zipfile.c (Ed) + 5. Add allow_empty_archive to flag when want to create an empty archive. + globals.c, zip.h (Ed) + 6. Set allow_empty_archive when using -i and expecting an archive to be + created. This is in response to the 2/14/05 email. zip.c (Ed) + 7. Make before and after variables that hold the dates of files to + process or delete global so can use them in scanzipf_regnew(). zip.h, + zip.c, globals.c (Ed) + 8. Change scanzipf_regnew() to be based on scanzipf_fix() which seems closer. + Still have not coded the new regular zipfile reader. zipfile.c (Ed) + 9. For new reader first get add list and then read old archive and filter + as reading old entries. zip.c, zipfile.c (Ed) +10. Define USE_NEW_READ to turn on using new reader, which is being + created. This allows all to work while the new reader is being worked + on. zip.c, zipfile.c (Ed) +---------------------- January 9th 2006 version 3.0f07 ---------------------- + 1. Remove dest parameter from crypthead() and zipcopy(). crypt.c (SMS, Ed) + 2. Change -ds to handle dots for as small as every 32 KB. zip.c (Ed) + 3. Add ask_for_split_write_path() and ask_for_split_read_path() for + asking where to put the next write split and for locating the next + read split. zip.h, fileio.c (Ed) + 4. Add in_path to track where reading splits from. zip.h, globals.c, zip.c (Ed) + 5. Update copyright date on changed files to include 2006 (Ed) + 6. Replace stderr with mesg for most output messages. deflate.c, fileio.c, + trees.c, util.c, zip.c, zipcloak.c, zipfile.c, zipnote.c, zipsplit.c + 7. Add mesg_line_started to track if need new line on mesg output and update + zipmessage() and zipwarn() to use it. Set mesg_line_started to 1 when + newline not last character written to mesg and 0 when it is. deflate.c, + zip.h, zip.c, globals.c, zipup(), fileio.c (Ed) + 8. Include base_path as parameter for get_split_path(). fileio.c (Ed) + 9. Account for VMS version in split path. Add vms_file_version(). fileio.c, + zip.c, vms/vms.c, vms/vms.h (SMS) +10. Create crc16f() to create ANDed halves crc32 for Unicode using copy + of crc32() but may change to use main copy. zipfile.c, zip.h, + fileio.c (Ed) +11. Close in_path and out_path in finish() and ziperr(). zip.c (Ed) +12. Change perror() to strerror() and print to mesg in ziperr(). zip.c (Ed) +13. Add find_next_signature() to find the next signature when reading a + zip file. zipfile.c (Ed) +14. Add find_signature() to find a given signature from current point in + archive. zipfile.c (Ed) +15. Add at_signature() to check if at a given signature in archive. + zipfile.c (Ed) +16. Changes to scanzipf_regnew() but far from done. zipfile.c (Ed) +17. Changes to readzipfile() to close input archive file and allow new + zipfile reader to open and close files as goes through splits. + zipfile.c (Ed) +18. Change -s to default to MB and set minimum split size to 64k. + zip.c (Ed) +19. Add link to user32.lib for CharToOem(). makefile.w32, makenoas.w32 + (Cosmin) +20. Remove unused Z64_EFPos. globals.c (Ed) +---------------------- February 13th 2006 version 3.0f08 ---------------------- + 1. Move option checks before any work is done. zip.c (Ed) + 2. Update bfcopy() to handle reading splits and remove input file + parameter and use global in_file. fileio.c (Ed) + 3. Change ask_for_split_read_path() to allow user aborting. fileio.c (Ed) + 4. Change get_split_path() to use standard file extensions from most + recent AppNote of .z01, .z02, ..., .z99, .z100, .z101, ... fileio.c (Ed) + 5. Change is_ascii_string to use 0x7F for ASCII detection. fileio.c (Ed) + 6. Add copy_only global for when -O is used to change the format of an + archive without changing the contents. This allows for converting an + archive to a split archive for instance. The global copy_only is used + to output status information for copies when normally copied files + have no status messages. globals.c (Ed) + 7. Add in_file, split_path, total_disks, current_in_disk, and + current_in_offset as globals to track reading splits. zip.h, + globals.c (Ed) + 8. Update copyright date. revision.h (Ed) + 9. Close in_file if open in finish(). zip.c (Ed) +10. Add -O (big o) to extended help. zip.c (Ed) +11. Remove readzipfile() from zipstdout() and use main call later down. + zip.c (Ed) +12. Move archive reading and file scanning after command line checks. + zip.c (Ed) +13. If -O out_zip and so have_out is set then set copy_only and allow + copying instead of error message *Nothing to do*. zip.c (Ed) +14. If zipbeg is just 4 bytes and spanning then assume is spanning + signature and set zipbeg to 0 to ignore. zip.c (Ed) +15. Don't open initial write test as modify if have_out is set and so have + a separate output file. zip.c (Ed) +16. If zipbeg is 0 and nothing at beginning of archive to copy then don't + open input file until zipcopy() does. zip.c (Ed) +17. If stuff at beginning then copy and close input file. Should be able + to keep it open but easier to close it and let zipcopy() reopen it. + zip.c (Ed) +18. Add status message when copy_only set so something is displayed. + zip.c (Ed) +19. Instead of closing x at bottom close in_file. The variable x was used + inconsistently and it seemed easier to make in_file global instead. + Then again y remains the global output variable. zip.c (Ed) +20. Update copyright. zipnote.c, zipsplit.c, zipcloak.c (Ed) +21. Change adjust_zip_local_entry() to return 1 if the entry is Zip64 and + 0 if not. This is needed to know how large the extended local header + is later. zipfile.c (Ed) +22. Add read_Unicode_Path_local_entry() to read the local version of the + Unicode Path extra field. zipfile.c (Ed) +23. Handle disk in adjust_zip_central_entry(). zipfile.c (Ed) +24. Change USE_NEW_READ to SPLIT_SUPPORT as splits seems to be stable more + or less. zipfile.c (Ed) +25. Add is_signature() to compate signatures. zipfile.c (Ed) +26. Create scanzipf_fixnew(). It should look like scanzipf_regnew(). + zipfile.c (Ed) +27. Change scanzipf_regnew() to read the central directory and create zlist + and handle reading traditionally. Allows using central directory + information, in particular file sizes, in zipcopy() while reading + entries. Use global in_file instead of f for input file and set to NULL + when not a valid file so finish() only tries to close it if needed. + Check to make sure the End Of Central Directory record found is infact + the last one in case a stored archive is in the last 64 KB. Refuse + to update a split archive but recommend using -O instead. zipfile.c (Ed) +28. Change readable check in readzipfile() to require input archive to exist + if using -O out_archive. zipfile.c (Ed) +29. Change putlocal() to not create a Zip64 extra field unless needed and + on rewriting the local header to remove Zip64 extra field if was created + but not needed. Add check if assumed entry does not need Zip64 but does, + meaning probably the uncompressed size is less than 4 GB but the + compressed size is over 4 GB. zipfile.c (Ed) +30. Change zipcopy() to use the global in_file and y files and to open and + close read splits as needed. Checks the local header against the + central directory header to verify same file, which should be as using + the disk and offset values from the central directory. Update disk and + offset in central directory. zipfile.c (Ed) +31. Change out_path and out_len to base_path and base_len in + get_split_path(). fileio.c (SMS) +32. Update command line options for VMS to include verbose splitting. + vms/zip_cli.cmd, vms/cmdline.c (SMS) +33. Handle HP. unix/unix.c (SMS) +34. Add adler16() checksum function. util.c (Cosmin) +35. Use FILE_FLAG_BACKUP_SEMANTICS and a less demanding access mode + in CreateFile() when retrieving file attributes. Fixes a problem + when adding a directory entry from an NTFS or a CDFS partition + (i.e. one that stores timestamps using universal time), and the + directory timestamp is not the same daylight savings time setting. + The effect is an offset in the timestamp by one hour, if zip is + built using NT_TZBUG_WORKAROUND. The problem is not exposed, + however, if NO_W32TIMES_IZFIX is defined. win32/win32.c (Cosmin) +---------------------- March 19th 2006 version 3.0f09 ---------------------- + 1. Fix encryption problem where a large file with uncompressable data + can cause deflate to store bad data. See crypt.c for details. + Thanks to the nice people at WinZip for finding and providing the + details of this problem. crypt.c (Ed) + 2. Add note at top of Extended Help to refer to the Zip Manual. zip.c + (Ed) + 3. Update extended help for delete. zip.c (Ed) + 4. Change crypthead() to use buffer and bfwrite() which is split aware. + crypt.c (Ed) + 5. Create SPLIT_SUPPORT version of zipcloak() and zipbare() and read + local header rather than assume data using central header. crypt.c (Ed) + 6. Change zfwrite() to use global output file y. crypt.c (Ed) + 7. Remove in and out parameters from zipcloak() and zipbare() for + splits. crypt.h, zipcloak.c (Ed) + 8. Change get_split_path() to get_in_split_path() and get_out_split_path(). + zipfile.c, fileio.c, zip.h (Ed) + 9. Change crc32f() to crc32u(). fileio.c, zip.h (Ed) +10. Add encryption overwrite fix to copy_block() and remove from zfwrite(). + crypt.c, tree.c (Ed, Christian) +11. Add note on bug fix. WhatsNew (Ed) +12. Add copy_only mode. zip.c (Ed) +13. Make SPLIT_SUPPORT the default. zip.h (Ed) +14. Add set_filetype(), rename_split(), and zipmessage(). zipcloak.c, + zipnote.c, zipsplit.c (Ed) +15. Add long option support. zipcloak.c (Ed) +16. Set in_path. zipcloak.c, zipnote.c, zipsplit.c (Ed) +17. Use SPLIT_SUPPORT calls. zipcloak.c, zipnote.c, zipsplit.c (Ed) +18. Set current_disk, cd_start_disk, and cd_entries_this_disk for use + by putend() and bytes_this_split for putcentral(). zipsplit.c (Ed) +19. Include ctype.h for toupper(). zipfile.c (Ed) +20. Add readlocal() for utilities to read local header. zipfile.c (Ed) +21. Put Zip64 variables and code in ZIP64_SUPPORT ifdef in scanzipf_regnew(). + zipfile.c (Ed, SMS) +22. Use zip_fzofft() for converting offset. zipfile.c (Ed, SMS) +23. Add casts to many append to memory calls. zipfile.c (Ed) +24. Move handling of .zip split to get_in_split_path() and + get_out_split_path(). zipfile.c (Ed) +25. Handle fix = 3 case for ZipNote that renames entries in zipcopy(). + zipfile.c (Ed) +26. Restore clearing of extended local header bit when not encrypting. When + encrypting need to output extended local header using putextended() in + zipcopy(). zipfile.c (Ed) +27. Add notes on using file time for encrypting. zipup.c (Ed) +28. Remove extended local header bit separately for z->lflg (local flags) + and z->flg (central directory flags). These should be the same but + could be different. zipup.c (Ed) +29. Suppress command line globbing for MINGW. win32/win32.c (Christian) +30. Add EF UT time fix for delete. zip.c (Christian) +---------------------- April 28th 2006 version 3.0f10 ---------------------- + 1. Add note to extended help to escape [ as [[] or use -nw. zip.c (Ed) + 2. Remove local declaration of tempfile as now global. zipnote.c, + zipcloak.c (SMS) + 3. Add zip_fzofft() for outputting uzoff_t bin size c. zipsplit.c (SMS) + 4. Add only_archive_set and clear_archive_bits to do Window archive bit + selection and clearing. Add -AS option to require DOS Archive bit + be set and -AC to clear archive bits of included files. Add + ClearArchiveBit() to clear archive bits after archive created. + Only Win32. globals.c, zip.h, zip.c, win32zip.c, win32.c (Ed) + 5. Change procname_win32() and readd() to check archive bit. + win32/win32zip.c (Ed) + 6. Update copyright. win32/win32zip.h (Ed) + 7. Add mesg_line_started = 0 to stats to remove blank line when clearing + archive bits. zipup.c (Ed) + 8. Add zip_fzofft() to format split size. zipsplit.c (SMS) + 9. Update help for splits and archive bit and add note on escaping [. + zip.c (Ed) +10. Add -M option and bad_open_is_error to exit with error if any input + file unreadable. Also error if -M and would get "name not matched" + warning. zip.c (Ed) +11. Copy Zip 2.32 csharp example, though it is designed for zip32.dll and + not zip32z64.dll from Zip 3.0. Updated note. windll/csharp (Ed) +12. Change -M to -MM and define -mm to avoid accidental use of -m. + zip.c (Ed) +13. Define split_method -1 to not allow splitting, mainly used when reading + a split archive to stop automatic splitting of output with same + split size. Now -s=0 or -s- disables splitting. zip.h, globals.c, + zip.c (Ed) +14. Add fflush() after dots displayed. deflate.c, fileio.c, zipup.c (Ed) +15. Instead of assuming buffer size as 32 KB for dots, use WSIZE for + compressing and SBSZ for storing and calculate as dots are counted. + Now dot_count and dot_size are bytes instead of buffers. Add dots + to Delete and Archive modes. zip.c, zipup.c, deflate.c, fileio.c (Ed) +16. If reading a split archive and split size has not been given, get + size of first split read by zipcopy(), which should be the first + split, and set split size to that, making the output archive the same + split size as the input archive. Delay -sv split size message + if split size is 0 at first but then changed. zipfile.c (Ed) +17. Add proc_archive_name() for new archive mode to process names in old + archive only and skip looking on the file system. Easier than modifying + the various port codes. fileio.c (Ed) +18. Fix cd_start_offset bug. fileio.c (Ed) +19. Create new action ARCHIVE that looks for matches only in old archive + for Copy Mode. If no input paths and there is an output archive, + Copy Mode is assumed even without ARCHIVE. Old default Copy Mode + when no input files updated to work like -U mode and allow filters. + New global copy_only currently only used to control global dots. + zip.c, fileio.c, globals.c, zip.h (Ed) +20. Update help. Change extended help to more help. Update more help + to include internal modes delete and new Archive. Update help for + formatting options. Update help for wildcards. Remove streaming + examples from top basic section. Indent examples. Help for new + --out and Copy Mode. Add warnings that output using data descriptors + may not be compatible with some unzips. Update dots help and add + warning that dot size is approximate. Add help for new DOS archive + bit options. More help for -b and -MM. zip.c (Ed) +21. Add support for Unix FIFO (named pipe). Add set_extra_field() stat + name ending in '/' fix found in Zip 2.32. unix/unix.c (Ed) +22. Add check to not allow setting -U (internal copy) in similar cases to + -d (delete). zip.c (Ed) +23. Add counts for internal modes Delete and Archive. Byte counts for -db + remain uncompressed size for external modes, but internal modes Delete + and Archive now use compressed sizes as these copy that many bytes. + zip.c (Ed) +24. Add check for when ftell() wraps. zipup.c (Ed) +25. Add mesg_line_started = 0 to result percentage message. zipup.c (Ed) +26. Update contact information. unix/packaging/preinstall.in (SMS, Ed) +27. A few Zip64 fixes to set Zip64 correctly and fix disk and offset of + Zip64 End Of Central Directory. zipsplit.c (Ed) +28. Update comments for get_option(). fileio.c (Ed) +29. Update DLL version. windll/windll.rc (SMS, Ed) +30. New option -sf shows files that would be operated on. zip.c (Ed) +---------------------- May 5th 2006 version 3.0f11 ---------------------- + 1. Use C prototypes for Unicode functions. fileio.c (SMS) + 2. Change constant for mask in set_file_type from unsigned to signed. + trees.c (SMS) + 3. Use C prototypes for zip_fzofft() and zip_fuzofft() signed and + unsigned zoff_t formatting functions. util.c (SMS) + 4. Remove U from constants in Adler16 code. util.c, zip.h (SMS) + 5. Add spaces to VMS usage to avoid misinterpretation. zip.c (SMS) + 6. Add OF() to at_signature(). zipfile.c (SMS) + 7. Use zip_zofft() for entries error. zipfile.c (SMS) + 8. Remove U in constants in percent(). zipup.c (SMS) + 9. VMS command line updates. vms/cmdline.c, vms/descrip_deps.mms, + vms/vms_zip.rnh, zip_cli.cld, vms/zip_cli.help (SMS) +10. Update to VMS help. vms/zip_cli.help (Ed) +11. Check for memmove() and strerror(). Remove specific 64-bit support + for SunOS, as large file support now does. unix/configure (SMS) +12. Add emergency replacements for memmove() and strerror(). + unix/unix.c (SMS) +13. Remove old not SPLIT_SUPPORT code. globals.c, zipnote.c, fileio.c, + crypt.h, crypt.c, zipcloak.c, zip.h, zip.c, zipup.c, zipsplit.c, + zipfile.c (Ed) +---------------------- May 12th 2006 version 3.0f12 ---------------------- + 1. Add UNICODE_SUPPORT ifdef around uname in zipup(). zip.c (SMS) + 2. Change size from uzoff_t to zoff_t in zipcopy(). zipfile.c (SMS, Ed) + 3. Fix a bug where filetime() returns -1 for device but not handled in + byte counts. zip.c (Ed) + 4. Add check for UnZip version and exit if not 6.00 or later if + a Zip64 archive. Define popen() and pclose() in Win32 to native + _popen() and _pclose(). ziperr.h, zip.c, win32/osdep.h (Ed) + 5. Add -sb option to ring bell when pause to change disk. Use new + global split_bell. global.c, zip.h, zip.c, fileio.c (Ed) + 6. Enable crc32u() and use for Unicode extra field. fileio.c (Ed) + 7. Add -dv to display volume being written to. zip.c, zip.h, + globals.c (Ed) + 8. Update WhatsNew. WhatsNew (Ed) + 9. Help updates. zip.c (Ed) +10. Create option -X- (negated -X) to keep old extra fields and remove + -XX which is now -X. Make get_extra_field() global. Add + copy_nondup_extra_fields()to copy old extra fields not already + in new extra fields. zipup.c, zip.c, zipfile.c (Ed) +11. Use output name oname for -sf option to show files that would be + worked on. zip.c (Ed) +12. When updating or freshening old entries, read the old local header + with readlocal() to get local flags and extra fields. zip.c (Ed) +13. Add UNICODE_SUPPORT ifdefs around uname code. zip.c (SMS, Ed) +14. If WIN32_OEM set then on WIN32 store OEM name in archive. As read + DOS or WIN32 archives convert assumed OEM paths to ANSI. Remove old + WIN32_OEM code. Make oem_to_local_string() global for WIN32_OEM and + local_to_oem_string() global for WIN32_OEM and UNICODE_SUPPORT. + zip.h, zipfile.c, zipup.c, win32/win32.c, win32/win32zip.c (Ed) +15. Update error 8 to include wrong unzip. ziperr.h (Ed) +16. Change checksum for Unicode extra field to standard crc32 using + C version crc32u(). Add crctab.c. win32/vc6/zipnote.dsp, + win32/vc6/zipsplit.dsp, zipfile.c +17. Update readlocal() to handle multi-disk archives if not UTIL. + zipfile.c (Ed) +18. Convert size to signed zoff_t in zipcopy(). Update note. + zipfile.c (Ed) +19. Update Readme. Readme (Ed) +20. Add crctab.o to zipsplit and zipnote. unix/Makefile (Ed) +21. Proposed update to license. License (Ed) +---------------------- May 20th 2006 version 3.0f13 ---------------------- + 1. Reformat License file. License (Cosmin) + 2. Change %d to %lu for disk number and add cast. zip.c (Cosmin, Ed) + 3. Display Scanning files message after delay at start based on + suggestion from Greg. Currently the time is checked every 100 + entries processed. After 100 entries the start time is saved. + After 5 seconds or 100 entries after that, whichever takes + longer, the Scanning files message is displayed and every 2 seconds + or 100 entries, whichever takes longer, after that a dot is displayed. + fileio.c, zip.c, globals.c, zip.h (Greg, Ed) + 4. Add Unicode mismatch flag and option -UN. Default is now a Unicode + mismatch is an error. -UN=warn outputs warnings and continues, + -UN=ignore disables warnings, and -UN=no ignores the Unicode extra + fields. globals.c, zip.h, zipfile.c (Ed) + 5. Add options for VMS. vms/cmdline.c, vms/zip_cld.cld (SMS) + 6. Add casts to percent(). zipup.c (Ed) + 7. Minor changes to logfile formatting. zip.c (Ed) + 8. Update help. zip.c (Ed) + 9. Add -Z=compression-method option. zip.c (Ed) +10. Add sd: to -sd status messages. zip.c (Ed) +11. Instead of original argv[] use args[] for -sc show command line + to show final command line. zip.c (Ed) +12. Change argv[] to args[] for logfile. zip.c (Ed) +13. Put results of -sf show files in log file if open. zip.c (Ed) +14. Add Johnny's bzip2 patch but not tested. win32/makefile, zip.c, + zip.h, zipup.c (Johnny) +15. Minor tweeks to bzip2 to work with latest beta. zip.c, zipup.c (Ed) +16. Add -sf- to list files that would be included only in log file + and not on stdout as list can be long. Only list totals on stdout. + zip.c (Ed) +17. Create check_unzip_version(). Fix Unix check. Zip still creates + the temporary archive then does the check, and if it fails + the archive is deleted, even if the check fails because of the wrong + verion of UnZip. On Unix only 'unzip' the system version of UnZip + is checked, not './unzip' which would allow putting a local more + up to date version of UnZip in the current directory for the check. + There should be a way to override the system version of UnZip for + the -T test. zip.c (Ed) +---------------------- July 12th 2006 version 3.0f14 ---------------------- + 1. Change crypt version from 2.10 to 2.91 to match Zip 2.32 and avoid + confusion. crypt.h (Cosmin) + 2. Add abbrevmatch() to handle option values that can be abbreviated + like compression method. util.c, zip.h, zip.c (Ed) + 3. Change USE_BZIP2 to BZIP2_SUPPORT as USE_BZIP2 implies it replaces + deflation maybe. zip.c, zip.h, zipup.c (Ed) + 4. Update man page. man/zip.1, zip.txt (Ed) + 5. Add bzip2 to VMS. vms/build_zip.com, vms/bzlib.h, vms/cmdline.c, + vms/descrip.mms, vms/descrip_src.mms, vms/find_bzip2_lib.com, + vms/install_vms.txt, vms/zip_cli.cld (SMS) + 6. Remove zipfile parameter from bzfilecompress(). Add unsigned + cast for EOF in bzip2 code. Add bzip2 version information. + zipup.c, zip.c (SMS) + 7. Add bzip2 to Unix. unix/configure (SMS) + 8. Add and update bzip2 descriptions. INSTALL, README, WhatsNew, + bzip2/install.txt (SMS, Ed) + 9. Add vc6bz2 projects for compiling bzip2 code into zip (not the + best approach perhaps). win32/vc6/readmevc.txt, + win32/vc6bz2/readvcbz.txt, win32/vc6bz2/zip.dsp, win32/vc6bz2/zip.dsw, + win32/vc6bz2/zipcloak.dsp, win32/vc6bz2/zipnote.dsp, + win32/vc6bz2/zipsplit.dsp (Ed) +10. Add support for VC++ 2005 by disabling deprecation. win32/osdep.h + (Cosmin) +11. Update instructions for makefile. unix/Makefile (Ed) +12. Update todo list. todo30.txt (Ed) +13. Reduce #if 0 block to now allow extra data message. zipfile.c (Ed) +14. Add note that readlocal() reads local headers. zipfile.c (Ed) +15. Archive comment was not being read by new scanzipf_regew(). Added. + zipfile.c (Ed) +16. Handle reading and writing OEM comments. zipfile.c (Ed) +17. Update Zip64 data descriptor note. zipfile.c (Ed) +18. Format filetypes() check. zipup.c (Ed) +19. Update note to remember to force deflation for descriptors by + release. zipup.c (Ed) +20. In compression code using libraries, enable dots for noisy also. + zipup.c (Ed) +21. Update extended help to add more of the basic options and + compression method. zip.c (Ed) +22. Add additional lines bz_opt_ver2 and bz_opt_ver3 to bzip2 + version to give credit to bzip2. zip.c (Ed) +23. Add descriptions to version information for USE_EF_UT_TIME, + NTSD_EAS, WILD_STOP_AT_DIR, WIN32_OEM, LARGE_FILE_SUPPORT, + ZIP64_SUPPORT, and UNICODE_SUPPORT similar to how UnZip does. + zip.c (Ed) +24. Add note that crypt is modified in Zip 3. zip.c (Ed) +25. Use abbrevmatch() and update warnings for compression + method selection. zip.c (Ed) +26. Update config to handle either using IZ_BZIP2 to define + the location of the bzip2 files or the bzip2 directory. + unix/configure, zipup.c, zip.c (SMS, Ed) +---------------------- July 14th 2006 version 3.0f15 ---------------------- + 1. Change USE_BZIP2 to BZIP2_SUPPORT in VMS. vms/descrip_src.mms, + vms/build_zip.com (SMS) + 2. Add SYS$DISK:. vms/descrip.mms, vms/build_zip.com (SMS) + 3. Change vms/install.txt to [.vms]install.txt. bzip2/install.txt (SMS) + 4. Change VMS files to lower case. vms/mod_dep.com, vms/install_vms.txt, + vms/zip.opt, vms/hlp_lib_next.com, vms/notes.txt, vms/unixlib_gcc.h, + vms/unixio_gcc.h (SMS) + 5. Remove old VMS files. vms/descrip-old.mms (removed), + vms/link_zip.com (removed), vms/make_zip.com (removed), + vms/makefile.vms (removed) (SMS) +---------------------- July 24th 2006 version 3.0f16 ---------------------- + 1. Fix global dots so can set with dot size. deflate.c, fileio.c (Ed) + 2. Update License top line to refer only to license. License (Cosmin) + 3. Update License. License (Ed) + 4. Implement zero length UTF-8 path length as flag standard path is UTF-8 + and should use that. This allows Zip to use the standard path as + UTF-8 when the local character set is UTF-8. zipfile.c (Ed) + 5. Update WhatsNew. WhatsNew (Ed) + 6. Change case of bzip2/install.txt. INSTALL (Ed) + 7. Change MANUAL.txt to ZIP.txt and update ftp site. README (Ed) + 8. Update announcement. zip30f.ann (Ed) + 9. Now also check if OS has bzip2 library and can use that. + unix/configure, zip.c (Mark Adler, Ed) +10. Add fix from akt@m5.dion.ne.jp in Japan to recurse on doublebyte + characters without processing in recmatch(). This should not be needed + unless the rest of the code in there is broke for Japanese character + sets in some way. Need to test. util.c (Ed) +11. Add note for bzip2. zip.c (Ed) +12. Do not do seek wrap test if ftell() returns -1 as from a pipe. Add + output of last ftell() and current ftell() for zipfile too big seek + error. zipup.c (Ed) +13. Add version to the options table. Remove the check to display version + before the command line is processed. Add to option -v a check to + display the version if that is the only argument. Can still enable + verbose with piping by using zip -v - - format. zip.c (Ed) +14. Add abbrevmatch() for -UN option. zip.c (Ed) +---------------------- August 7th 2006 version 3.0f17 ---------------------- + 1. Change license modifications to retain intent of copyright holders, as + any major change in license conditions would require contacting all + copyright holders. LICENSE (Greg, Ed) + 2. Move debugging statement after zipstdout() where mesg is set to stderr. + Add mesg and fflush() to sd messages where needed so that messages go + to stderr when piping. zip.c (Ed) + 3. Update encryption comment. zipup.c (Ed) + 4. Do not use data descriptors for directories. zipup.c (Mark, Ed) + 5. Update Q & A to match license. README (Ed) + 6. Update WhatsNew. WHATSNEW (Ed) + 7. Add ifndef around version_info() for dll. zip.c (Ed) + 8. Add -TT (--unzip-path) to allow setting the unzip command to use with + -T to test the archive. zip.c (Ed) + 9. Add -DF (--difference-archive) which requires --out and turns off + copying unchanged entries to the new archive creating an archive with + just the changes and additions since the original archive was created. + zip.c, globals.c, zip.h (Ed) +10. Update help. zip.c (Ed) +---------------------- September 7th 2006 version 3.0f18 ---------------------- + 1. Split -t and -tt options and remove limitation that only one can be + used to allow setting a date range. zip.c, WhatsNew (Ed) + 2. Minor changes in comments. zipfile.c (Ed) + 3. Add entries for format of Unicode Path and Unicode Comment extra fields. + proginfo/extrafld.txt (Ed) + 4. Change note at top of infozip.who, but needs to be updated with all new + contributors. proginfo/infozip.who (Ed) + 5. Note Zip 3 and UnZip 6 now support Zip64. proginfo/ziplimit.txt (Ed) + 6. Add note on Unicode. README (Ed) + 7. Update WHATSNEW. WHATSNEW (Ed) + 8. Update help. zip.c (Ed) + 9. Add {} support to -TT option, allowing insertion of temp archive path + into the command string to -TT similar to Unix find does. zip.c (Ed) +10. Start changes for -F fix option. Add checks when reading input archive + and skip bad central directory entries and bad local entries. Currently + -F requires the central directory to be intact (except for bad CD entries + that will be skipped) and local entries and data to be where the + central directory say they are. This allows all recovered entries to + be complete with all central directory information. Calculate CRC of + input entry and compare to CRC from central directory. Allow skipping + split disks the user may not have. Store state of output archive + before each local entry and data are read, allowing seeking back and + restoring state to skip bad entries. fileio.c, global.c, zipfile.c, + zip.h (Ed) +11. Started changes for fixfix. fileio.c (Ed) +12. Update help on -t and -tt. zip.c (Ed) +13. Add note on Unicode support, but may change if add handling of names + with characters not supported in current character set. README (Ed) +14. Combined ToDo30.txt and ToDo but more to be done. TODO (Ed) +15. Update ToDo list. ToDo30.txt (Ed) +16. Add -F and -FF to help. zip.c (Ed) +17. Run fix mode in copy mode, as it is copying from one archive to + another, and use those checks. zip.c (Ed) +18. Add Try -F and Try -FF warnings in places. zipfile.c (Ed) +19. Allow reading version 4.6 (bzip2) archives. zipfile.c (Ed) +20. Add Unicode Path and Unicode Comment extra field descriptions. + proginfo/extrafld.txt (Ed) +21. First attempt at updating the Who file. proginfo/infozip.who (Ed) +22. Add note to top of ziplimit.txt. proginfo/ziplimit.txt (Ed) +23. Add possible fix for paths returned by the Win32 directory scan with + '?' in the name. These are characters in the Unicode name stored on + disk but not represented in the multi-byte character set used by zip + for the scan. In this case, return the short name in 8.3 format so + directory scan can continue. Could put the Unicode name in the Unicode + extra field, but not done. Add warning when long name is replaced + by short name. Not fully tested. win32/win32zip.c, zip.h, zip.c, + fileio.c (Ed) +24. If archive name and -sf are the only parameters, list archive contents. + zip.c (Ed) +---------------------- September 8th 2006 version 3.0f19 ---------------------- + 1. Fix error message. zipfile.c (SMS, Ed) + 2. Put crc32() in ifndef UTIL as only needed for fix. fileio.c (SMS, Ed) +---------------------- November 3rd 2006 version 3.0f20 ----------------------- + 1. Fix comment. vms/vmszip.c (SMS) + 2. Include oem_to_local_string() if UNICODE_SUPPORT. win32/win32.c, + zip.h (Ed) + 3. Modify procname_win32() to flag a path not supported by the local + character set so can get Unicode for it. Check Unicode names. + win32/win32zip.c (Ed) + 4. Add matching of escaped Unicode names to proc_archive_name() that + reads entries from an archive. Add sorted zlist zusort. + globals.c, fileio.c, zip.h, zipfile.c (Ed) + 5. Add support for non-local character set names and paths for WIN32, + getting and storing the UTF-8 path when needed. Use 8.3 name + when normal name has characters not supported in current local + character set. Note when short name used. zip.c, fileio.c (Ed) + 6. Add support for fix = 2 which reads local headers first to + bfcopy(). fileio.c, zip.h (Ed) + 7. Allow selection of .zip split in ask_for_split_read_path() when + reading a split archive that has no end records giving the total + split count. fileio.c (Ed) + 8. Add zoff_t casts to dot counts. fileio.c (Ed) + 9. Comment changes for Unicode. fileio.c (Ed) +10. Call wide_to_local_string() separately in utf8_to_local_string() + to free up temp value. fileio.c (Ed) +11. Support new AppNote bit 11 for forcing UTF-8, but needs finishing. + globals.c (Ed) +12. Add to zlist struct zuname for the escaped version of the UTF-8 + name in uname and add ouname for the display version of zuname. + zip.c, zip.h, zipfile.c (Ed) +13. Add zipmessage_nl() that can output to the screen and to the log + file like zipmessage(), but can write lines without a newline. + zip.c, zip.h, zipcloak.c, zipnote.c, zipsplit.c (Ed) +14. Update help for -FF and Unicode. zip.c (Ed) +15. Change > to >= for byte message check to avoid -0 (negative zero). + zip.c (Ed) +16. Add -su show unicode option which adds escaped unicode paths to + -sf. Also uses show_files = 3. zip.c (Ed) +17. Update comments for -UN and -X. zip.c (Ed) +18. Add support for new AppNote bit 11 that says standard path and + comment have UTF-8 when -UN=f is used. zip.c (Ed) +19. Fix zipfile name message by replacing value with zipfile. + zip.c (Ed) +20. Add new code for -FF, which processes archives by trying to read + the EOCDR to get split count, then starting with the local + entries. This option does not use the standard code but does + everything itself. Add scanzipf_fixnew(), which tries to read + the EOCDR, then the local entries, then the central directory. + zip.c, zipfile.c (Ed) +21. Update note for ZIP64_CENTRAL_DIR_TAIL_SIZE. zipfile.c (Ed) +22. Put read_Unicode_Path_entry() and read_Unicode_Path_local_entry() + into UNICODE_SUPPORT ifdef. zipfile.c (Ed) +23. Add zuqcmp() and zubcmp() to support Unicode sorted list of + paths. zipfile.c (Ed) +24. Update zsearch() to also search unicode paths. zipfile.c (Ed) +25. Split out iname in read_Unicode_Path_entry() for debugging. + Should put it back. Update Unicode mismatch warning. + zipfile.c (Ed) +26. Update Unicode in readlocal(). zipfile.c (Ed) +27. Add more Unicode support to scanzipf_regnew(). zipfile.c (Ed) +28. Add support for fix = 2 to zipcopy(). Add checks and warnings, + but allow scan to continue when can. Use local data to fill + in central directory fields in case no central directory entry + for local entry. zipfile.c (Ed) +29. Add get_win32_utf8path() to get UTF-8 from Windows if can. + zipfile.c (Ed) +---------------------- November 7th 2006 version 3.0f21 ----------------------- + 1. Add crude data descriptor support to -FF in bfcopy() that should be + updated by release. fileio.c (Ed) + 2. Change %d to %s and use zip_fzofft() to format zoff_t byte count. + zipfile.c (SMS, Ed) + 3. Call local_to_oem_string() for only WIN32 in zipcopy(). zipfile.c + (SMS, Ed) +---------------------- November 29th 2006 version 3.0f22 ----------------------- + 1. Change ' to " in extended help. zip.c (Ed) + 2. Change -dv disk number display to indisk>outdisk. zip.c (Ed) + 3. Finish -FF fix option. Move detailed output to require -v. zip.c (Ed) + 4. Add note to help to use -v with -FF to see details. zip.c (Ed) + 5. Add -sU option to view only Unicode names when exist. zip.c (Ed) + 6. Change default dot size in verbose from every buffer to 10 MB. zip.c (Ed) + 7. Exit if --out and in path same as out path. zip.c (Ed) + 8. Remove verbose information when fixing archive. zip.c (Ed) + 9. Initialize in disk to 0, but still problem with disk number of first entry + for each disk lagging by 1. zip.c (Ed) +10. Consistently use ZE error codes for exit from ask_for_split_read_path. + zipfile.c, zip.c (Ed) +11. Seek back when fix finds bad entries. Also skip last entry of split + if next split is missing. Should check if entry completed. zip.c (Ed) +12. Add messages to -sd for writing the central directory, replacing the old + zip file, and setting file type. zip.c (Ed) +13. Don't set file type on stdout. zip.c (Ed) +14. Increase errbuf from FNMAX + 81 to FNMAX + 4081. zip.h (Ed) +15. Add skip_this_disk, des_good, des_crc, des_csize, and des_usize globals + for -FF and reading data descriptors. Change note on display_volume. + Add global skip_current_disk. zip.h, globals.c (Ed) +16. BFWRITE_HEADER define now also does data descriptor. zip.h (Ed) +17. Skip zipoddities() if fix. Maybe can later add back. zipfile.c (Ed) +18. Update fix messages. zipfile.c (Ed) +19. Allow user to end archive early using ZE_EOF. zipfile.c, fileio.c (Ed) +20. Only show split numbers and offsets for -FF if verbose. zipfile.c (Ed) +21. Handle spanning signature at top of split archive. zipfile.c (Ed) +22. Only close in_file if open. zipfile.c (Ed) +23. Add note if no .zip and only splits suggest use -FF. zipfile.c (Ed) +24. In putlocal() and putcentral() only convert to OEM if z->vem == 20. + zipfile.c (Ed) +25. Do not OEM convert archive comment as PKWare says this should + be ASCII. zipfile.c (Ed) +26. Fix swap of siz and len and LOCSIZ and LOCLEN. zipfile.c (Ed) +27. Call read_Unicode_Path_local_entry() before OEM conversion so Unicode + checksum checks iname before conversion. zipfile.c (Ed) +28. Only check if local and central crc match if not stream entry. + zipfile.c (Ed) +29. Keep data descriptors if fix == 2, but need to look at this. + zipfile.c (Ed) +30. Fix bug adding up header bytes in n by adding 4 for signature. + zipfile.c (Ed) +31. If fix == 2 use local crc for central, otherwise use central crc + for local. zipfile.c (Ed) +32. In zipcopy(), check data descriptor and skip if not correct one. + zipfile.c (Ed) +33. Add SH, LG, and LLG macros from zipfile.c to allow reading the data in + the data descriptor. fileio.c (Ed) +34. In bfcopy(), read and check the data descriptor if n == -2. If + run out of bytes before find descriptor, return error. fileio.c (Ed) +35. In ask_for_split_read_path(), increase buf to SPLIT_MAX_PATH + 100, + fix bug by adding "- 1", set split_dir = "" if current directory, + and update prompts to add skip and end choices. Add skip and end + choices. fileio.c (Ed) +36. Increase buffer for fgets to SPLIT_MAXPATH. fileio.c (Ed) +37. Update WhatsNew. WhatsNew (Ed) +---------------------- December 10th 2006 version 3.0f23 ----------------------- + 1. Handle additional ODS5 issues by upper casing many symbols and file names. + vms/build_zip.com, vms/collect_deps.com, vms/descrip.mms, + vms/descrip_mkdeps.mms, vms/descrip_src.mms, vms/find_bzip2_lib.com (SMS) + 2. Update VMS Find Help Library code. vms/hlp_lib_next.com (SMS) + 3. Instead of tempname use temp_name as parameter to avoid function + tempname(). zipsplit.c, zipnote.c, zipcloak.c, zip.c (Ed) + 4. If fixing archive with -FF and no EOCDR to get disk count, see if top of + archive has spanning signature or local header and guess if it is + single-disk archive, then ask user to confirm. zipfile.c (Ed) + 5. For Unix where NO_MKSTEMP is not defined, replace mktemp() with mkstemp() + that avoids a race condition. zip.c, zipcloak.c, zipnote.c, fileio.c (Ed) + 6. Eliminate mkstemp() warning by using mkstemp() instead of mktemp() for + Unix. Only for UNIX and if NO_MKSTEMP is not defined. Many OS do not + have mkstemp(). zipcloak.c, zipnote.c, zip.c, fileio.c (Ed) + 7. If UNICODE_SUPPORT and UNIX then try to switch to UTF-8 locale to allow + displaying of Unicode, otherwise just get escapes. This results in some + characters displaying as whitespace if needed fonts, such as East Asian, + are not installed. zip.c (Ed) + 8. If new global unicode_escape_all is set, then escape all non-ASCII + characters when converting Unicode file path. This allows viewing paths + as escapes on Unix that would otherwise be white space. If not set, any + characters that map to the current locale are returned as is. Can only + display if either supported as base by the OS or fonts installed. Set + using -UN=escape option. zip.c, fileio.c, zip.h, globals.c (Ed) + 9. Update extended help for Unicode. zip.c (Ed) +10. All variables used by Win32 in global.c should now be initialized at + start so dll is initialized each call. zip.c (Ed) +---------------------- January 1st 2007 version 3.0f24 ----------------------- + 1. Fix a problem when building with (old, obsolete) IM attribute encoding + combined with bzip2 support. vms/descrip_src.mms (SMS) + 2. Update WHATSNEW. WhatsNew (Ed) + 3. Update README. ReadMe (Ed) + 4. Remove in_crc code. Too involved to implement but may look at later. + fileio.c, globals.c, zip.c (Ed) + 5. Use 0x50 and 0x4b for 'P' and 'K' in signatures to handle EBCDIC case. + zipfile.c, fileio.c (Ed) + 6. Implement new -FS file sync option that deletes entries missing on the + file system from an archive being updated. globals.c, zip.c (?, Ed) + 7. Update help. zip.h, zip.c (Ed) + 8. Include scanning files dots when update small but new file scan long. + zip.c (Ed) + 9. Ask if single-file archive when using -FF and can't tell. zipfile.c (Ed) +10. Display message when entry would be truncated. zipfile.c (Ed) +11. Check for VMS_IM_EXTRA. Update bzip2 support for VMS. Change + destination directory if large-file enabled. vms/build_zip.com, + vms/descrip_src.mms (SMS) +12. Change parameters for VMS bzip2 search. vms/find_bzip2_lib.com (SMS) +---------------------- January 12th 2007 version 3.0f25 ----------------------- + 1. Incorporate faster crc32.c including the Rodney Brown changes (originally + implemented in the zlib project) from UnZip, which includes the + IZ_CRC_BE_OPTIMIZ and IZ_CRC_LE_OPTIMIZ optimizations when those symbols + are defined. These modifications include: + - enlarge unrolling of loops to do 16 bytes per turn + - use offsets to access each item + - add support for "unfolded tables" optimization variant + crc32.c (Christian) + 2. As the crc32.c module now includes crc table generation, remove crctab.c. + crctab.c (remove) (Christian) + 3. Update crc i386 assembler code from UnZip (details see above). + win32/crc_lcc.asm, win32/crc_i386.asm, win32/crc_i386.c, crc_i386.S + (Christian) + 4. Guard against redefinition of symbols @CodeSize and @DataSize in memory + model setup section to work around Open Watcom (version 1.6) wasm + assembler problem. msdos/crc_i86.asm (Christian) + 5. Change type of keys[] array for new crc, add IZ_CRC_BE_OPTIMIZ, and + use new crypt crc table. Use header buffer instead of buf for header. + crypt.c, crypt.h (Christian) + 6. Update version and remove crc table. crypt.h (Christian) + 7. Add crc32.h, change sprintf() format for disk number from d to lu as + can go over 16-bit, remove crc32u(). fileio.c (Christian) + 8. Update to use new crc. msdos/makefile.bor, msdos/makefile.dj1, + msdos/makefile.dj2, msdos/makefile.emx, msdos/makefile.msc, + msdos/makefile.tc, msdos/makefile.wat, unix/Makefile, + vms/build_zip.com, vms/descrip_deps.mms, vms/descrip_src.mms, + vms/osdep.h, win32/makefile.bor, win32/makefile.dj, win32/makefile.emx, + win32/makefile.gcc, win32/makefile.ibm, win32/makefile.lcc, + win32/makefile.w10, win32/makefile.w32, win32/makefile.wat, + win32/makenoas.w32, win32/vc6/zip.dsp, + win32/vc6/zipcloak.dsp, win32/vc6/zipnote.dsp, win32/vc6/zipsplit.dsp, + win32/vc6bz2/zip.dsp, win32/vc6bz2/zipcloak.dsp, win32/vc6bz2/zipnote.dsp, + win32/vc6bz2/zipsplit.dsp, windll/visualc/dll/zip32.dsp, + windll/visualc/dll/zip32.mak, windll/visualc/lib/zip32.dsp, + win32/visualc/lib/zip32.mak (Christian) + 9. Include crc32.h. Make variable uname local in proc_archive_name(). + Remove unused num and new_base_path. Change %02d to %02l2 for + disk number in print format. Remove crc32u() as now use crc32(). + Add parentheses around conditions in loops. Use 0 instead of NULL + for zwchar. fileio.c (Christian) +10. Add z_uint4 defines from crypt.c to tailor.h. Move uch, ush, and ulg + typedefs before tailor.h include which needs them. tailor.h, zip.h (SMS) +11. Include crc32.h. change add_name() to return not int but long + since number of command line arguments can exceed 16 bits. Cast + variable option to (int) for subtraction. Change 0x400 to 0x400L. + Add braces to show_files print block. zip.c (Christian) +12. Add warning if use -F or -FF without --out. Change defined(NO_MKSTEMP) + to !defined(NO_MKSTEMP). zip.c (Ed) +13. Define EC64LOC and EC64REC for size of Zip64 EOCD Locator and Zip64 + EOCD Record. Add extern for crc_32_tab. Move crc32() to crc32.h. + zip.h (Christian) +14. Add crc.h. zipcloak.c (Christian) +15. Include crc32.h. Comment out scanzipf_reg() and scanzipf_fix() as + no longer used, which are left in for now for comparison. Cast + blocksize to extent for malloc(). Instead of 0x10000 malloc 0xFFFF for + extra field block so fits in 16 bits. Instead of crc32u() use crc32(). + Only do lflg != flg check for fix == 2. Add comments to various #endif. + Indent comment. Comment out copy_sig() which is not used. Reduce size + of SCAN_BUFSIZE to EC64REC for MEMORY16. Use ENDHEAD for EOCDR size. + Change %u to %lu in print formats for disk count. Use EC64LOC for size + of Zip64 EOCD Locator. Use EC64REC for size of Zip64 EOCD Record. + Add streaming and was_zip64 to ZIP64_SUPPORT. Remove lflg != flg check + in zipcopy(). zipfile.c (Christian) +16. Add note that z-flg & ~0xf check will fail if new bit 12 for UTF-8 paths + and comments is set. Update -FF warning. zipfile.c (Ed) +17. Include crc32.h. Modify tempzn update. Fix comment. Set + z->lflg = z->flg after deflate as deflate may have set bits in z->flg + [Ed, Christian]. Include BZIP2_SUPPORT block in !UTIL block. zipup.c + (Christian) +18. Changes to use crc32.c. acorn/gmakefile, acorn/makefile, amiga/lmkfile, + amiga/makefile.azt, amiga/smakefile, aosvs/make.cli, atari/makefile, + atheos/makefile, beos/makefile, cmsmvs/cczip.exec, cmsmvs/mvs.mki, + cmsmvs/zip.makefile, cmsmvs/zipmvsc.job, cmsmvs/zipvmc.exec, + human68k/makefile, human68k/makefile.gcc, novell/makefile, novell/zip.lnk, + os2/makefile.os2, qdos/makefile.qdos, qdos/makefile.qlzip, tandem/history, + tandem/macros, tandem/tandem.h, theos/makefile, tops20/make.mic, + unix/configure, unix/makefile, win32/makefile.a64 (Christian) +19. Add note to use BZ_NO_STDIO. bzip2/install.txt (Ed) +20. Remove crctab. cmsmvs/zipvmc.exec (Ed) +21. Update comment. macos/source/pathname.c (Christian) +22. Start of manual update. Zip.1 (Ed) +23. Changes to use crc32.c. vms/descrip.mms, vms/descrip_deps.mms, + vms/descrip_mkdeps.mms, vms/descrip_src.mms, vms/vms.c (SMS) +---------------------- January 17th 2007 version 3.0f26 ----------------------- + 1. Add note for UnZip. crypt.c (Christian) + 2. Change current_disk and disk_number from int to ulg. Change num from int + to unsigned int. [Even though a 16-bit system likely won't see more than + 64k disks, it probably should be ulg - Ed] Remove unused mbsize. Change + match from long to int as the number of possible options should always fit + in that. fileio.c, globals.c (Christian) + 3. Use -Gt to force some data into separate data segments so all data fits. + msdos/makefile.msc (Christian) + 4. Move some copyright constants to far to save near space. + revision.h (Christian) + 5. Change u for character from int to unsigned int. util.c (Christian) + 6. Move include of crc32.h from vms/vms.c to vms/vms_pk.c. vms/vms.c, + vms/vms_pk.c (Christian) + 7. Update crci386_.o. win32/makefile.gcc (Christian) + 8. Use NOASM=1 to disable assembler and clear variables when do not. + win32/makefile.w32 (Christian) + 9. Remove unused totalslashes and returnslashes from get_win32_utf8path(). + win32/win32zip.c (Christian) +10. Remove local versions of tempzip and tempzf. + zip.c (Christian) +11. Make options[] far. Change cd_start_disk from int to ulg. Cast -1 to + (ulg) for cd_start_disk. Put here = zftello() in DEBUG defines. + zip.h, zip.c (Christian) +12. Change length of zipfile comment parameter from ush to extent. Change + disk numbers from int to ulg in close_split(), ask_for_split_read_path(), + ask_for_split_write_path(), get_in_split_path(), find_in_split_path(), + get_out_split_path(). Add Far to longopt and name strings in + option_struct. zip.h (Christian) +13. Add far to options[]. zipcloak.c (Christian, Ed) +14. Define write_string_to_mem() only for UNICODE_SUPPORT. Change ulg to + extent for append to mem memory offset and blocksize parameters. Make + at_signature() local. Cast usValue to char. Remove unused oname in + read_Unicode_Path_local_entry(). Remove local definitions of zip64_entry + as Zip is always processing one entry at a time and this is a global + flag for the current entry. Make find_next_signature() and + find_signature() local. Add ZCONST to signature parameter. Make + is_signature() and at_signature() local. Change m, result of fread(), + from int to extent. Reduce SCAN_BUFSIZE from 0x40000 to the size of the + largest header being read. As find_next_signature() is used to scan for + the next signature and that reads a byte at a time, the scan buf is only + used to read in the found headers. Since we skip the extra parts of the + Zip64 EOCDR, all headers are a fixed size. Remove unused variables from + scanzipf_fixnew(). Use ENDCOM for end comment offset. Instead of 64 KB + seek back 128 KB to find EOCDR. Use ENDOFF and ENDTOT for offsets in + EOCDR. Remove tabs. Merge versions of putend(). Update Amiga SFX. + Remove unused offset in zipcopy(). Make size local in zipcopy(). + zipfile.c (Christian) +15. Update putend() comment. zipfile.c (Ed) +16. Add far to options[]. zipnote.c, zipsplit.c (Christian) +17. Add NO_ASM versions of Win32 zipnote, zipsplit, and zipcloak projects. + Add crc32.h and crc32.c to zipsplit and zipnote projects. + win32/vc6/zipsplit.dsp, win32/vc6/zipnote.dsp, win32/vc6/zipcloak.dsp (Ed) +18. Add NO_ASM versions of Win32 bzip2 zipnote, zipsplit, and Zipcloak + projects. Add crc32.h and crc32.c. win32/vc6bz2/zipsplit.dsp, + win32/vc6bz2/zipnote.dsp, win32/vc6bz2/zipcloak.dsp (Ed) +19. Update Win32 dll and lib projects and make files. + windll/visualc/lib/zip32.dsp, windll/visualc/lib/zip32.mak, + windll/visualc/dll/zip32.dsp, windll/visualc/dll/zip32.mak (Ed) +20. Remove space in front of #ifdef and other conditionals that slipped in. + zipfile.c, zipup.c (SMS) +21. Updates for bzip2. vms/bzlib.h, vms/install_vms.txt (SMS) +22. Updates. vms/notes.txt (SMS) +23. Update copyrights. crc32.c, deflate.c, globals.c, revision.h, ziperr.h, + trees.c, win32/nt.c, win32/win32.c, win32/win32i64.c, win32/win32zip.h, + win32/zipup.h (Ed) +24. Update WhatsNew. WHATSNEW (Ed) +---------------------- February 4th 2007 version 3.0f27 ----------------------- + 1. Fix array sizes and loop lengths in wide_to_escape_string(). fileio.c + (Johnny, Ed) + 2. Fix escape_string_to_wide() to handle hex strings, then comment out as + not used. zip.h, fileio.c (Ed) + 3. Use ZIPERRORS() macro instead of ziperrors[] array. zip.c, zipcloak.c, + zipnote.c, zipsplit.c (SMS) + 4. Add VMS-compatible "severity" values, add new ZE_SEV_PERR define to + set when perror() needs to be called, add ZIPERRORS() macro, change + PERR() to use ZE_SEV_PERR, change ziperrors[] to new structure array + to hold error strings, add new VMS facility names and severity codes + assigned by HP to ziperrors[] array, and add new official + VMS_MSG_IDENT. ziperr.h (SMS) + 5. Change ZE_SEV defines to ZE_S to save space and reformat ziperrors[]. + ziperr.h (Ed) + 6. Update install.txt to include generic Unix case. bzip2/install.txt (Ed) + 7. Add creation of message file and add NOMSG message. vms/build_zip.com, + vms/descrip.mms, vms/install_vms.txt (SMS) + 8. Update notes.txt to add changes to program exit status values and changes + to messages. vms/notes.txt (SMS) + 9. Include crc32.h, include ssdef.h, instead of FAB_OR_NAM use FAB_OR_NAML, + add status code summary note detailing old versus new error codes, and if + CTL_FAC_IZ_ZIP is 0x7FFF and OLD_STATUS is defined use old VMS error codes. + vms/vms.c (SMS) +10. Change FAB_OR_NAM to FAB_OR_NAML and remove NAME_DNA, NAME_DNS, NAME_FNA, + and NAME_FNS. vms/vms.h (SMS) +11. Change FAB_OR_NAM to FAB_OR_NAML. vms/vms_im.c, vms/vms_pk.c, + vms/vmszip.c (SMS) +12. Fix compile warning on VC 2005. win32/makefile.w32 (Johnny) +13. Update readmevb.txt and readvb64.txt. windll/vb/readmevb.txt, + windll/vbz64/readvb64.txt (Ed) +14. Change tch from int to ulg in utf8_from_ucs4_char(). Move comments to keep + line lengths to 80 characters. fileio.c (Christian) +15. Update comment for total_cd_entries. global.c, zip.c, zip.h (Christian) +16. Comment out unused Adler-16 code. util.c, zip.h (Christian) +17. Add InterlockedExchangePointer() macro if not defined. Update Initialize() + to use macro. nt.c (Christian) +18. Move zip64 eocd disk and offset variables next to input archive variables. + zip.c (Ed) +19. Remove zipbegset from scanzipf_fixnew() as offsets are ignored when this + is fixing archives. Add comment to cd_total_entries. Remove local + cd_start_disk and cd_start_offset as these are already global. Use + ZIP_UWORD16_MAX when disk number exceeds this to flag use of Zip64. + zipfile.c (Christian) +20. Some comment changes. zipfile.c (Ed) +21. Fix indentation in places. zipsplit.c (Christian) +22. Remove unused variable zfile. zipup.c (Christian) +23. Update manual. zip.1, zip.txt, zipsplit.txt (Ed) +---------------------- February 22nd 2007 version 3.0f28 ---------------------- + 1. Update notes. vms/notes.txt (SMS) + 2. Add stream_lf.fdl to specify carriage control. vms/stream_lf.fdl (SMS) + 3. Update License to also refer to www.info-zip.org and to hopefully provide + an example of misrepresentative use. LICENSE (Ed) + 4. Update Readme. README (Ed) + 5. Update WhatsNew. WHATSNEW (Ed) + 6. Change output archive cd_start_disk and cd_start_offset to input archive + local in_cd_start_disk and in_cd_start_offset in scanzipf_fixnew() and + scanzipf_regnew() to avoid mixing in and out. zipfile.c (Ed) + 7. Update copyright. Remove crc32.h include. vms/vms.c (Christian) + 8. Changes for new crc32. Remove CRC32. Add CRCA_0 and CRCAUO. Add + compiling of crc_i386.S. win32/makefile.emx. (Christian) + 9. Add handlers for better RSXNT and Windows OEM conversions. Add detailed + comments on conversions. win32/osdef.h (Christian) +10. Define CP_UTF8. win32/rsxntwin.h (Christian) +11. Define WIN32_LEAN_AND_MEAN to reduce size of Windows includes. + win32/win32.c, win32/win32zip.c, zip.c (Christian) +12. Use only standard FAT attributes if OEM. win32/win32zip.c (Christian) +13. Add use of INTERN_TO_OEM() and related OEM changes. Add console comment. + zip.c (Christian) +14. Change severity from char to int. Update macros. ziperror.h. (Christian) +15. Update Visual Basic project to clarify some of the code. + windll/vbz64/vbzip.vbp, windll/vbz64/vbzipbas.bas, + windll/vbz64/vbzipfrm.frm (Ed) +16. Update copyright. api.c (Ed) +17. Update format for duplicate entry warning. fileio.c (Ed) +18. Instead of ifdef __RSXNT__ use ifdef WIN32. Define WIN32_LEAN_AND_MEAN. + Use WIN32_CRT_OEM. Change OEM check from vem == 20 to vem & 0xff00 == 0 + and instead of local_to_oem_string() use _INTERN_OEM(). Remove unused + first_CD in scanzipf_fixnew(). Instead of oem_to_local_string() use + Ext_ASCII_TO_Native(). Instead of local_to_oem_string() use + INTERN_TO_OEM(). zipfile.c (Christian) +19. Replace escape from zipsplit man page with '. zipsplit.txt (Christian) +20. Instead of using 20 every time, account for dosify when setting vem. + Update FAT comment. zipup.c (Christian) +------------------------ March 3rd 2007 version 3.0f29 ------------------------- + 1. Remove crctab.c. vms/build_zip.com (SMS) + 2. Add LFLAGS_ARCH. vms/descrip.mms (SMS) + 3. Remove redundant includes descrip.h, rms.h, and atrdef.h. + vms/vmsmunch.c (SMS) + 4. Remove includes descrip.h and rms.h. vms/vmszip.c (SMS) + 5. Only define NO_UNISTD_H if __VAX defined or __CRTL_VER is + less than 70301000, allowing support of the new symbolic + links in VMS. Also use unlink instead of delete if version + above 70000000. vms/osdep.h (SMS) + 6. Formatting changes. vms/notes.txt, vms/install_vms.txt (Christian) + 7. Remove spaces before tabs. win32/makefile.emx (Christian) + 8. Formatting change. win32/osdep.h (Christian) + 9. If -y on VMS open the link not the target file. vms/vms_im.c (SMS) +10. If -y on VMS search for the link, not the target file. vms/vms_pk.c (SMS) +11. Change default for Unicode path mismatch from error to warning, so + processing will continue. zip.c, globals.c (Ed) +------------------------ March 12th 2007 version 3.0f30 ------------------------ + 1. Add bzip2 support for the reduced no stdio bzip2 library for VMS and Unix. + Use libbz2_ns_.olb for VMS bzip2 library which is compiled from the VMS + version of bzip2 with the BZ_NO_STDIO flag set. This flag removes most + standard bzip2 stdio support and enables using a callback routine for + errors. zbz2err.c, unix/Makefile, vms/build_zip.com, vms/descrip.mms, + vms/descrip_deps.mms, vms/descrip_src.mms (SMS) + 2. Add zbz2err.c to Win32 vc6bz2 project for support of BZ_NO_STDIO for bzip2. + Modify zbz2err.c to handle different ports. zbz2err.c (Ed) + 3. Update license. zip.h (Ed) + 4. Update copyright. zip.c, zipfile.c, zipup.c, zbz2err.c, revision.h (Ed) + 5. Fix bug where directories got set to ver 4.6 in local headers instead of + ver 1.0 when using bzip2. zipfile.c, zipup.c (Ed) + 6. Minor updates to INSTALL. INSTALL (Ed) + 7. Minor updates to README. README (Ed) + 8. Add BZ_NO_STDIO to vc6bz2 projects. Error routine seems to work. + win32/vc6bz2 (Ed) + 9. Set bit FAB$M_BIO (.fab$v_bio) in the FAB when using sys$open() on a + symlink. vms/vms_im.c (SMS) +10. Change sys$disk to SYS$DISK. vms/build_zip.com (SMS) +11. Update extended help. zip.c (Ed) +12. Update bzip2 install. bzip2/install.txt (Ed) +------------------------ March 19th 2007 version 3.0f31 ------------------------ + 1. Define bz2_olb as LIBBZ2_NS.OLB. Change LIBBZ2.OLB to bz2_olb. Use + ZZBZ2ERR.C error callback for bzip2. vms/build_zip.com (SMS) + 2. Change NO_SYMLINK to NO_SYMLINKS to be consistent with UnZip. tailor.h, + acorn/osdep.h, macos/osdep.h, tops20/osdep.h, vms/osdep.h (SMS) + 3. Minor note changes. Add section on Symbolic Links. vms/notes.txt (SMS) + 4. Update copyright. globals.c (Ed) + 5. Update License with official copy. LICENSE (Greg, Ed) + 6. Update Readme. README (Ed) + 7. Add support for NO_BZIP2_SUPPORT. tailor.h (Ed) + 8. Add common compiler flags to Install. INSTALL (Ed) + 9. Remove SPLIT_FILE define. zip.c (Ed) +10. Minor updates to extended help. zip.c (Ed) +11. Modify Makefile to also build bzip2 library if found. Split $MAKE + ("make -f unix/Makefile") into $MAKE and $MAKEF, leaving $MAKE as defined by + Make and defining $MAKEF to "-f unix/Makefile". Add clean_bzip2 target. + unix/Makefile (SMS) +12. Modify configure to handle compiling bzip2. unix/configure (SMS) +13. Remove linking bzip2 with utilities. Other changes. unix/Makefile (Ed) +14. Change bzip2 wrong library errors to warnings. Put back OS bzip2 library + check. Only compile bzip2 if in bzip2 directory. unix/configure (Ed) +15. More modifications to Makefile and configure to only allow compiling in + the bzip2 directory. unix/Makefile, unix/configure (Ed) +------------------------ March 27th 2007 version 3.0f32 ------------------------ + 1. Modify configure and Makefile to only allow compiling bzip2 in the Zip bzip2 + source directory. unix/Makefile, unix/configure (SMS, Ed) + 2. Update bzip2 installation instructions. bzip2/install.txt (SMS, Ed) + 3. Remove need for BZIP2_USEBZIP2DIR define by using an appropiate include dir + specification (-I ../../bzip2) when needed. zip.c, win32/vc6bz2/zip.dsp, + unix/configure (SMS, Ed, Christian) + 4. Update VC6 readme. win32/readmeVC.txt (Christian, Ed) + 5. Add crc32.h to VC projects. Add assembler group to zipcloak, zipnote, and + zipsplit projects. Add BZ_NO_STDIO to all configurations with bzip2 so + reduced bzip2 code is used. win32/vc6/zip.dsp, win32/vc6/zipcloak.dsp, + win32/vc6/zipnote.dsp, win32/vc6/zipsplit.dsp (Christian) + 6. Update VC6bz2 readme. win32/readVCBZ.txt (Christian, Ed) + 7. Modify bzip2 VC6 workspace to use standard zipcloak, zipnote, and zipsplit + projects as they don't need bzip2. win32/vc6bz2/zip.dsw (Christian) + 8. Fix zlib flag problem by properly setting and clearing deflInit flag to + initialize and release resources. zipup.c (Bill Brinzer, Christian) + 9. Update copyright. crypt.h, api.c, tailor.h, fileio.c, ziperr.h, + zipsplit.c, zipnote.c, zipcloak.c, util.c (Ed) +------------------------ April 25th 2007 version 3.0f33 ------------------------ + 1. Fix -dd display_dots option for VMS. Fix adding value for -ds to command + line. Fix /NAMES = AS_IS for older header files. cmdline.c (SMS) + 2. Add Win32 wide scan support. In fileio.c add Win32 wide functions lastw(), + msnamew(), newnamew(), wchar_to_wide_string(), is_ascii_stringw(), + wchar_to_local_string(), and wchar_to_utf8_string(). In globals.c + add no_win32_wide that is true if the wide versions of calls like + GetFileAttributesW() do not work as on Win9x without the Unicode kit. + In tailor.h define zwstat for stats that use wchar_t strings and + defines SSTATW and LSSTATW. In util.c add isshexpw() and recmatchw() + and dosmatchw() for matching using wchar_t strings. In win32.c add + FSusesLocalTimeW(), IsFileSystemOldFATW(), GetFileModeW(), GetLongPathEAW(), + and zstat_zipwin32w(). In win32zip.c add zdirscanw structure, + GetDirAttribsW(), zDIRSCANW, readdw(), wild_recursew(), procname_win32w(), + OpenDirScanW(), GetNextDirEntryW(), CloseDirScanW(), procnamew(), + local_to_wchar_string(), wchar_to_utf8_string(), in wild() code to + check if W versions are supported and send zip down byte or wide path, + ex2inw(), in2exw(), and filetimew(). In zipup.h define zwopen to use + wide paths. In zipup.c if supported use filetimew() and zwopen(). + In zip.h add namew, inamew, and znamew to zlist and flist. In zip.c + remove duplicate initialization of use_wide_to_mb_default, force_zip64, + zip64_entry, and zip64_archive. Use filetimew() if UNICODE_SUPPORT and + using wide paths for directory scan. Remove old 8.3 path Unicode fix as + now use wide paths and get all where the 8.3 kluge missed paths where + characters in path needed multiple code pages. Changes to bit 11 Unicode + but still not ready. fileio.c, globals.c, tailor.h, util.c, zipup.h, + win32/win32.c, win32/win32zip.c, win32/win32.h, zipup.c, zip.c (Ed) + 3. Update copyright. Don't define UNICODE_SUPPORT if already defined. + Define MATCHW and zstat_zipwin32w(). win32/osdep.h (Ed) +------------------------ April 29th 2007 version 3.0f34 ------------------------ + 1. Add temporary option -sC to test Unicode file creation enabled with + UNICODE_TEST define. zip.c, fileio.c (Ed) + 2. On Unix display control characters as ^X as UnZip. (SMS) fileio.c + 3. Update extended help. zip.c (Ed) + 4. Fix bugs in Unicode changes. zip.c, fileio.c (SMS, Ed) + 5. Add NAMES AS_IS support. Handle root dir [000000]. zip.h, + vms/install_vms.txt, vms/vmszip.c, vms/vmsmunch.c (SMS) + 6. Add global zipfile_exists to handle missing zipfile errors better. zip.h, + globals.c, zip.c (Ed) + 7. Add functions utf8_to_escape_string(), wide_to_escape_string(), + local_to_escape_string(), utf8_to_wchar_string(), and + rename wide_to_escape_string() to wide_char_to_escape_string(). fileio.c, + win32/win32zip.c, zip.h (Ed) + 9. Free f->inamew in fexpel(). Use zuname for matching. fileio.c (Ed) +10. Fix memory bug by setting z->namew, z->inamew, and z->znamew to NULL. + Set f->namew, f->inamew, and f->znamew to NULL for new file in newname(). + Free wide_string in local_to_utf8(). Other Unicode fixes. Add namew, + inamew, and znamew to freeup(). fileio.c, win32/win32zip.c, zip.h (Ed) +11. Move wchar functions only used by Windows to win32zip.c. fileio.c, + zip.h (Ed) +12. Fix spelling in manual. zip.1 (SMS, Ed) +13. Add zuebcmp() for Unicode. zipfile.c +14. Open files to read using wide name as input path. zipup.c (Ed) +15. Update help. zip.c (Ed) +16. Change -TT long option from --unzip-path to --unzip-command. zip.c (Ed) +17. Update Manual to include section on Unicode, add -TT option, make some + changes to Unicode in other sections, update copyright at bottom, and + some small changes to wording and examples. man/zip.1, zip.txt (Ed) +18. Put #ifdef WIN32 around WIN32 blocks. zipfile.c (Ed) +------------------------- May 14th 2007 version 3.0f35 ------------------------- + 1. Update VMS to include new options. vms/cmdline.c, vms/zip_cli.cld (SMS) + 2. Update VMS help. vms/vms_zip.rnh (SMS) + 3. Minor updates to VMS help. vms/vms_zip.rnh (Ed) + 4. Create global filter_match_case that defaults to 1 (case-sensitive). zip.c + zip.h, globals.c (Ed) + 5. Add option -fc to fold case for case-insensitive matching in filter(). + Currently enabled only for WIN32. zip.c, win32/osdep.h (Ed) + 6. Change (action == DELETE || action == FRESHEN) to filter_match_case in + PROCNAME() define. I just couldn't figure out what was going on here and + why the case flag was controlled by this. zip.c (Ed) + 7. Update WhatsNew. WHATSNEW (Ed) +------------------------- May 17th 2007 version 3.0f36 ------------------------- + 1. Touch date on generated file. vms/ZIP_MSG.MSG (SMS, Ed) + 2. Update Betas readme to include Release Candidates. Betas_Readme.txt (Ed) + 3. Update Zip 3.0f announcement. zip30f.ann (Ed) + 4. Minor updates to VMS help. vms/cvthelp.tpu, vms/vms_zip.rnh (SMS) + 5. Major changes to VMS CLI help. vms/zip_cli.help (SMS, Ed) + 6. Update license. revision.h (Ed) +------------------------- May 21st 2007 version 3.0f37 ------------------------- + 1. Rename -fc (fold case) to -ic (ignore case) which may be more intuitive. + zip.c (Ed) + 2. VMS CLI updates for new options. vms/cmdline.c, vms/vms_zip.rnh, + vms/zip_cli.cld, vms/zip_cli.help (SMS) + 3. Updates to support Watcom C, mingw, djgppv2 and msc-16-bit, including + supporting wide stat and compare calls and work-around for problem with + "no symlink support" detection. tailor.h, util.c, zip.c, win32/osdep.h, + win32/win32.c, win32/win32/zipup.h (Christian) +------------------------- May 29th 2007 version 3.0f38 ------------------------- + 1. Update description. file_id.diz (Ed) + 2. Handle better when not splitting and run out of disk space. Also, for split + method 1 (automatically write all splits to same place) exit if run out of + space instead of filling available space with near empty splits. For split + method 2 require splits to be at least 64K bytes (the minimum split size). + fileio.c (Ed) + 3. Add line break in ziperr() if message line has been started. zip.c (Ed) + 4. In ziperr() don't close output handle y if same as current_local_file handle + and just closed that. zip.c (Ed) + 5. Change default definition of PROCNAME() to handle new filter_match_case flag + and restore backward compatibility. zip.c (Christian, Ed) + 6. Add note detailing definition of PROCNAME(). zip.c (Ed) + 7. Remove nonlocalpath parameter from procname_win32() and procname_win32w() + and variables nonlocal_path and nonlocal_name as this is not used now that + unicode is implemented in WIN32 using the wide calls. + 8. Enable ignore case option for VMS. zip.c (SMS) + 9. Update -v and other updates in manual. man/zip.1 (Christian, Ed) +10. Updates for Watcom C and Win32 symlinks. win32/osdep.h (Christian) +11. Fix historic problem with VAX seeking. zipfile.c (SMS) +12. Add NAM_M_EXP_DEV. Add determination if device is in file specification. + If device name in file specification do ODS2 and ODS5 down-casing. + Define explicite_dev(). vms/vms.h, vms/vmszip.c (SMS) +------------------------- June 4th 2007 version 3.0f39 ------------------------- + 1. Update osdep.h to use new filter_match_case flag. vms/osdep.h (SMS) + 2. Fix unterminated string bug and trim extra allocated space in + local_to_display_string(). fileio.c (Ed) + 3. Updated extended help for -u and -ic options. zip.c (Ed) + 4. Update Manual. man/zip.1, zip.txt (Ed) +------------------------- June 15th 2007 version 3.0f40 ------------------------- + 1. Update Unicode Path and Unicode Comment descriptions based on suggestions + from WinZip. proginfo/extrafld.txt (Steve Gross, Ed) + 2. Update descriptions for Add, Update, and Freshen in the manual. man/zip.1 + (Christian) + 3. Update default definition of PROCNAME() to use filter_case_match flag to + turn off case matching in filter(). zip.c (Christian) + 4. Update WhatsNew. WHATSNEW (Ed) + 5. Update announcement. zip30f.ann (Ed) + 6. Update manual. man/zip.1, zip.txt (Ed) +------------------------- July 7th 2007 version 3.0f41 ------------------------- + 1. Use File Name as Unicode path if UTF-8 flag is set in header. zip.c, + globals.c, zipfile.c, zip.h (Ed) + 2. Update ToDo. TODO (Ed) + 3. Update WhatsNew. WHATSNEW (Ed) + 4. Update ReadMe. README (Ed) + 5. Fix problems with incompatible stat types on Win32. fileio.c, tailor.h, + zip.h, win32/win32.c, win32/win32zip.c, win32/osdep.h (Ed) + 6. Define NO_STREAMING_STORE to turn off storing while streaming. + INSTALL, zipup.c (Ed) + 7. Define UNICODE_ALLOW_FORCE to enable -UN=force option which is now + disabled and would need work. globals.c, zip.h (Ed) + 8. Add global using_utf8 to flag when OS current character set is UTF-8. + If an existing entry has the UTF-8 flag set the flag is kept. If a new + entry needs Unicode and on a UTF-8 system assume the strings are UTF-8 + and set the UTF-8 flag. globals.c, zip.h (Ed) + 9. Update Unicode extra field descriptions. proginfo/extrafld.txt (Ed) +10. Add include directory so can find bzip2 header file when using bzip2 + directory. unix/configure (Ed) +11. Fix wide character wild(), wild_recursew() and OpenDirScanW() for Win32 so + work like the regular versions. win32/win32zip.c (Ed) +12. Update Unicode in manual. Update -W description in manual zip.1 +13. Flush logfile writing. zip.c (Ed) +14. Update extended help for -UN option. Update help for Update to note it + updates files where the OS has a later date. Chance -UN=Exit to -UN=Quit + so can abbreviate to first letter. zip.c (Ed) +15. Fix a bug in readzipfile() when zip used in pipe. Other pipe fixes. zip.c, + zipfile.c (Ed) +------------------------ August 10th 2007 version 3.0f42 ----------------------- + 1. Update error message for -DF. zip.c (Ed) + 2. Add bzipped message to write to log file. zipup.c (Ed) + 3. Update bzip2 install instructions. bzip2/install.txt (Ed) + 4. Move local.h include to tailor.h to fix compiler multiple define. tailor.h, + zip.c (SMS) + 5. Add additional C compiler checks for GNU and HP. unix/configure (SMS) + 6. Fix to build libbz2.a. unix/Makefile (SMS) + 7. Update copyright. acorn/osdep.h, macos/osdep.h, tops20/osdep.h, + vms/vmszip.c, vms/vmsmunch.c, vms/vms_pk.c, vms/vms_im.c, vms/vms.h, + vms/vms.c, vms/osdep.h, win32/rsxntwin.h, win32/osdep.h, win32/nt.c (Ed) + 8. Change zfeeko(file, 0, SEEK_SET) to rewind(file) in ffile_size() so + EOF is always reset. This was creating problems in WIN32 when + NO_ZIP64_SUPPORT was set but LARGE_FILE_SUPPORT was set. zipfile.c (Ed) + 9. Update compile -v descriptions for LARGE_FILE_SUPPORT and ZIP64_SUPPORT to + be more specific as to what each does. zip.c (Ed) +10. Fix bug that added the local header size to the next entry compressed size + giving a wrong compressed size error if splitting and the split occurs when + writing a local header. fileio.c (Ed) +11. Remove UNICODE_TEST define from VC 6 projects. win32/vc6/zip.dsp, + win32/vc6/zipcloak.dsp, win32/vc6/zipnote.dsp, win32/vc6/zipsplit.dsp (Ed) +12. Update extended help. zip.c (Ed) +13. Only output -FF central directory messages in verbose mode. zipfile.c (Ed) +14. Add note about possible bug when copying entries from a split archive. + WHATSNEW (Ed) +------------------------ August 11th 2007 version 3.0f43 ----------------------- + 1. Display locale inside check to avoid NULL locale. zip.c (SMS, Ed) + 2. Add include wchar.h to tailor.h. tailor.h (SMS) +------------------------ August 21st 2007 version 3.0f44 ----------------------- + 1. Remove verbose messages when setting locale as verbose flag is not set yet. + zip.c (SMS, Ed) + 2. Change reading splits message "abort archive" to "abort archive - quit" and + change selection letter from a to q so q quits consistently. For quit, + don't confirm as more annoying than helpful. fileio.c (Ed) + 3. In bfwrite() handle case where a split ends at the end of one entry and + trying to write the next local header forces opening next split. This + caused copying entries from one archive to another to fail if this came up. + Also handle case where a new split is needed while writing central directory + entries. Now close last split and update pointers to point to the new + split. fileio.c (Ed) + 4. Update use of mesg_line_started and add new logfile_line_started to account + for line ends in logfile. fflush() output. zip.c, zip.h, globals.c (Ed) + 5. Move setting split size if input archive is split and split_size not set + to after archive is read. zipfile.c, zip.c (Ed) + 6. Update Manual to describe Unicode as implemented and note that old splits + are not automatically excluded. man/zip.1, zip.txt (Ed) + 7. Update WhatsNew to remove note that creating and copying split archives + is broke as it seems fully working now. WHATSNEW (Ed) + 8. Update announcement. zip30f.ann (Ed) +------------------------ August 31st 2007 version 3.0f45 ----------------------- + 1. Unicode fix for VMS. tailor.h (SMS) + 2. Add member current to zlist structure to flag when an archive entry is + current with the matching OS file using file time and size. This is used by + File Sync to copy current entries from archive. zip.h, zip.c (Ed) + 3. Comment out zip info verbose extra data message as this message does not + seem to add much. zipfile.c (Ed) + 4. Add local and central directory Version Needed To Extract to mismatch + warning. Update warning text. zipfile.c (Ed) + 5. Add function BlankRunningStats() to output blanks for the running stats + part of the line to use when displaying stats for entries not on the mark + list so all output lines up. zip.c + 6. Add -FS to extended help as new mode. zip.c (Ed) + 7. Update description of -FF to remove Assume Worst. zip.c (Ed) + 8. Add all_current flag that is set if all entries in archive are current and + skip updating archive if -FS and all entries are current. zip.c (Ed) + 9. Change argv[] to args[] for "try: zip" error message as message depends on + new argument order in args where options are now at beginning. zip.c (Ed) +10. For File Sync, copy entries to new archive if file time and size are the + same. If verbose, output ok when copying current entries, otherwise no + message when current_entry. Set all_current to 0 if an entry not marked or + a file not on OS as need to avoid the All Current message in these cases to + catch only deletions. zip.c (Ed) +11. Initialize variables excluding zipstate and setjmp() if USE_ZIPMAIN defined + to fix bug when recall zipmain(). zip.c (Ed) +12. Update Manual. zip.1, zip.txt (Ed) +13. Update WhatsNew. WHATSNEW (Ed) +14. Update announcement. zip30f.ann (Ed) +----------------------- September 5th 2007 version 3.0f46 ---------------------- + 1. Move write of local header after when GPB11 UTF-8 bit set in putlocal(). + zipfile.c (Ed) + 2. Change to uppercase for compatibility. vms/install_vms.txt (SMS) + 3. Set cenbeg and bytes_this_split to fix grow. Check if grow split archive. + zipfile.c, zip.c (Ed) +----------------------- September 14th 2007 version 3.0f47 -------------------- + 1. Include address for new Info-ZIP forum. Add note on 16-bit OS support. + Add note about text file line ends. README (Ed) + 2. Update WhatsNew to include latest on Unicode. Add section on plans for + Zip 3.1. WHATSNEW (Ed) + 3. Minor change in note for Unicode in extended help. zip.c (Ed) + 4. Modify definitions of Unicode extra fields based on discussions with PKWare + and WinZip. proginfo/extrafld.txt (Ed) + 5. Add note on UTF-8 flag. INSTALL (Ed) + 6. Minor updates to ToDo list. Needs more work. TODO (Ed) + 7. Update announcement. zip30f.ann (Ed) + 8. Change definition of IZ_OUR_BZIP2_DIR to be compatible with Configure and + to work with HP-UX. unix/Makefile (SMS) +------------------------ September 24th 2007 version 3.0f --------------------- + 1. Update extended help Unicode description. zip.c (Ed) + 2. Update Readme. README (Ed) + 3. Fix case of define identifying IA64. vms/vms.c (SMS) + 4. Update announcement date. zip30f.ann (Ed) + 5. Update Unicode extra field definitions based on changes proposed for + AppNote. extrafld.txt (Ed) +------------------------ October 17th 2007 version 3.0g01 --------------------- + 1. Can get stuck on open Unix FIFO so default to skip and add option -FI to + enable reading FIFO. Add global allow_fifo. zip.c, zip.h, globals.c + (Willus 0, Ed) + 2. As problems with MinGW with wide-character paths, disable wide-character + Unicode support. zip.c, unix/unix.c (Willus 0, Ed) + 3. Update manual installs to include zipcloak.1, zipnote.1, and zipsplit.1 + pages. unix/Makefile (Ed) + 4. Update Solaris packages. unix/Packaging/pkginfo.in, + unix/Packaging/postinstall, unix/Packaging/preinstall.in, + unix/Packaging/prototype (SMS) +------------------------ October 30th 2007 version 3.0g02 --------------------- + 1. Fix bug in get_in_split_path() where look for .zip split when attempting + to open archives without a .zip extension, even when a single file archive + like jar file. fileio.c (Gabriele (balducci@units.it), Ed) + 2. Fix bug where temp file got created in current working directory on Unix + by giving entire archive path to mkstemp() as template. fileio.c, zip.c + (Willus, Ed) + 3. Use 64-bit output functions for bits_sent. trees.c (SMS) + 4. Add -FF to fixfix -sd messages to make different from identical main + messages. zip.c (SMS, Ed) + 5. If quiet do not ask for splits and all splits must be in same location. + zipfile.c (Ed) + 6. Clean up making zip manuals. unix/Makefile (Ed, SMS) + 7. Add clean_exe to make. unix/Makefile (SMS) + 8. Update to VMS Notes, including adding details on symlinks, -V, and UTC + dates times. vms/notes.txt (SMS) + 9. Fix bug in wild() when calling wile_recursew() where qw should be + pointing inside pw. win32/win32zip.c (Willus, Ed) +10. Fix bug where is_ascii_string() fails when passed a NULL string. This + may fix problem where the CentOS mbstowcs() function is returning -1 when + trying to convert a file name with a bad character (0xe6), causing + local_to_wide_string() and then local_to_utf8_string() to return NULL, so + f->uname gets NULL and so is_ascii_string() fails with SIGSEGV. fileio.c + (Willus, Ed) +------------------------ October 31st 2007 version 3.0g03 --------------------- + 1. Add handling of -b temp directory when opening splits in bfwrite() using + mkstemp(). fileio.c (SMS, Ed) +------------------------ November 3rd 2007 version 3.0g04 --------------------- + 1. Move show_files to global so can avoid split warning for -sf. zip.c, + globals.c, zip.h, zipfile.c (Ed) + 2. Account for -b tempath when opening temp file. zip.c, zipnote.c, + zipcloak.c (SMS, Ed) +------------------------ November 4th 2007 version 3.0g05 --------------------- + 1. Minor fixes to fdopen calls. zipcloak.c, zipnote.c (SMS, Ed) +------------------------ November 4th 2007 version 3.0g06 --------------------- + 1. Add negation to -db, -dc, -dd, -dg, -du, -dv display options. zip.c (Ed) + 2. Put back UNICODE_SUPPORT no_win32_wide code left out in previous fix. + win32/win32zip.c (Willus, Ed) +------------------------ November 21st 2007 version 3.0g07 --------------------- + 1. Fix bug preventing newline in some cases in zipmessage(). zip.c (Ed) + 2. Update Unicode help. zip.c (Ed) + 3. Update -sd messages. zip.c (Ed) + 4. Add filetimew() for Unicode case. zip.c (Ed) + 5. Add ClearArchiveBitW() for Win32 wide. zip.c, zip.h, win32/win32.c (Ed) + 6. Only ask for .zip split if path ends in .znn or .znnn where n 0 to 9. This + allows -FF to work on .exe sfx files without adding .zip. zipfile.c (Ed) + 7. Fix bug where only backed up 20 bytes to find Z64 EOCD Locator. Now back + up 24 bytes to include size of Z64 EOCD Locator signature. This prevented + reading and updating archives greater than 4 GB. zipfile.c (Ed) + 8. If -FF on Win32 initialize wide strings namew, inamew, and znamew to NULL. + zipfile.c (Ed) + 9. Add #include to support towupper(). tailor.h (SMS) +------------------------ December 4th 2007 version 3.0g08 --------------------- + 1. Update dot_size comment. globals.c (Ed) + 2. Update Compression in extended help. zip.c (Ed) + 3. Add extended help on self extractor -A and -J. zip.c (Ed) + 4. Update VMS SYMLINK version information. zip.c (SMS) + 5. Remove not final from Unicode version information as final now. zip.c (Ed) + 6. Remove apparently not needed WINDLL variable retcode. zip.c (Ed) + 7. Fix -A to calculate sfx offset and adjust offsets as it should. zip.c (Ed) + 8. Split -F and -FF used with -A warning to separate warnings. zip.c (Ed) + 9. Add adjusting to can't to that to split archive error. zip.c (Ed) +10. Fix bug for -A that tries to open split by asking for disk 0 instead of + disk 1. Add adjust_offset and cd_total_size variables. Calculate + sfx offset by determining offset of start of central directory. Archives + larger than 4 GB are not supported as sfx archives but these don't seem + to work anyway. Add adjust_offset to Zip64 EOCDR offset and central + directory offsets. zip.c, zipfile.c (Ed) +11. Comment out here debug variable in find_next_signature(). zipfile.c (Ed) +12. Change %2x to %02x as format for parts of a signature in error messages. + zipfile.c (SMS) +13. Add warning adjusting split archives not yet supported. zipfile.c (Ed) +14. Add period to central directory comment. zipfile.c (Ed) +15. Update readme for vb Zip64 project. windll/vbz64/readvb64.txt (Ed) +16. Update comments of VB for Zip64 example. Add SplitSize to VB Zip64 + example. windll/vbz64/vbzipbas.bas, windll/vbz64/vbzipfrm.frm (Ed) +17. Add SourceForge to comment noting where can get the source code. + windll/vbz64/vbzipfrm.frm (Ed) +18. Update WhatsNew. WHATSNEW (Ed) +------------------------ December 12th 2007 version 3.0g09 -------------------- + 1. A few minor changes to extended help. zip.c (Ed) + 2. Uppercase beginning of most -sd messages. zip.c (Ed) + 3. Add spaces between options in some error messages. zip.c (Ed) + 4. Update comments in scanzipf_regnew(). zipfile.c (Ed) + 5. Update scanzipf_regnew() to figure out sfx offset. (Ed) + 6. Uppercase VMS RUNOFF file as apparently needed. VMS_ZIP.RNH (SMS) + 7. Add comments to zipmessage(). zip.c (Ed) + 8. Update extended help and option descriptions. zip.c (Ed) +------------------------ December 20th 2007 version 3.0g10 -------------------- + 1. Fix -F to include -A adjustment check. zipfile.c (Ed) + 2. Change -FF message when find EOCDR. zipfile.c (Ed) + 3. For -FF, reset first CD entry flag in_central_directory when a local entry + is found after CD entries so that another CD entry forces sorting of all + local entries to that point. This allows files with multiple archives in + them to be processed. zipfile.c (Ed) + 4. Add message when a local entry is found after a central directory. + zipfile.c (Ed) + 5. Remove word offset from disk offset location messages. zipfile.c (Ed) + 6. Make Adjust offset message more descriptive. zipfile.c (SMS, Ed) + 7. In scanzipf_regnew(), if adjustment to offsets, add it to + in_cd_start_offset. zipfile.c (Ed) + 8. Allocate cextra only if localz->ext not 0 in zipcopy(). zipfile.c (Ed) +------------------------ December 28th 2007 version 3.0g11 -------------------- + 1. Include definitions of zip64_eocdr_start and z64eocdl_offset in + ZIP64_SUPPORT ifdef block. Add comments for End Of CD Record (EOCDR). + Update comments for adjust offset detection. zipfile.c (Ed) + 2. Change ((uzoff_t)1 << 32) to 0xFFFFFFFF. zipfile.c (SMS, Ed) + 3. Leave off local header detection as not useful when searching for start + of central directory to get adjust offset. Looks like all expected cases + are now covered as long as archive is intact. zipfile.c (Ed) + 4. Update some warning messages. Simplify adjust offset information message. + zipfile.c (Ed) + 5. Add braces to unicode_mismatch if block. zipfile.c (Christian) + 6. Add (void *) cast in InterlockedExchangePointer() mutex calls to fix + compile warnings in MinGW (GCC 3.4.4). win32/nt.c (Christian) + 7. Remove unused nonlocalpath variable. win32/win32zip.c (Christian) + 8. Update betas readme file. betas_readme.txt (Ed) + 9. Partial update to Who list of contributors. proginfo/infozip.who (Ed) +10. Update ReadMe. Create Announcement. README, zip30g.ann (Ed) +11. Update WhatsNew. WHATSNEW (Ed) +------------------------ January 7th 2008 version 3.0g12 -------------------- + 1. Convert Scanning files message to use standard zipmessage_nl() so line + ends are generated when needed. fileio.c (Ed) + 2. Add line ends in DisplayRunningStats() if a display line has been + started. zip.c (Ed) + 3. For the command line listed at the top of the log file, add double + quotes around any arguments that have spaces in them. + zip.c (Ed) + 4. Instead of stdout use standard mesg output stream for show files. + Output new line for show files for display and log file if there was + output on the current line. zip.c (Ed) + 5. Comment out new line output code after zipup() and replace with + call to zipmessage_nl("", 1) to output new line if needed. + zip.c (Ed) + 6. In GetFileMode() and GetFileModeW() when get attributes fails + instead of fprintf(mesg, ...) use zipwarn() so error goes in + log file and new lines are displayed when needed. win32/win32.c (Ed) + 7. In GetSD(), change cbytes from long to ulg. Check cbytes (the + compressed size of the security descriptor) and issue warning if + the compressed security descriptor is greater than 0x7FFF (32k) + as the entire header this extra field is in needs to fit in the + 64k header. Should be a check on the running size of the header + so the actual space remaining is tracked. Maybe in Zip 3.1. If + cbytes OK cast to ush and store. win32/win32zip.c (Ed) + 8. Use zipmessage_nl() for bytes security message so new lines are + handled and message goes in log file. win32/win32zip.c (Ed) + 9. Add new option -RE to enable [list] (regex) matching in DOS and + WIN32 but disable [list] matching otherwise. Default behavior + is restored if ALLOW_REGEX is defined. globals.c, util.c, + zip.h, zip.c (Ed) +------------------------ January 20th 2008 version 3.0g13 -------------------- + 1. Update copyrights to 2008. zip.c, zipcloak.c, zipfile.c, zipnote.c, + zipsplit.c, zipup.c, README (Ed) + 2. Update Who. proginfo/infozip.who (Ed) +------------------------ January 30th 2008 version 3.0g14 -------------------- + 1. Update copyrights. fileio.c, globals.c, revision.h, util.c, zip.h, + win32/win32.c, win32/win32zip.c (Ed) + 2. Updates. README, proginfo/infozip.who (Ed) + 3. Update announcement and WhatsNew. zip30g.ann, WHATSNEW (Ed) + 4. Add ALLOW_REGEX to INSTALL define list. INSTALL (Ed) + 5. Change -sd message. zip.c (Ed) + 6. For bzip2 check for binary and set binary/text flag. Handle -l and -ll + line end conversions for bzip2. zipup.c (Ed) +------------------------ February 3rd 2008 version 3.0g -------------------- + 1. Change && to || to fix logic bug in show files. zip.c (Johnny) + 2. Add CLEAN and CLEAN_ALL VMS targets. vms/descrip_mkdeps.mms (SMS) +----------------------- February 22nd 2008 version 3.0h01 -------------------- + 1. Update some echo statements to use CFLAGS_OPT. Add GNUC check. + unix/configure (SMS) + 2. Only store UID and GID if 16 bit. unix/unix.c (Ed) +----------------------- March 21st 2008 version 3.0h02 -------------------- + 1. Change long Unicode escapes from 8 characters to 6 characters based on + change in UnZip 6.0. fileio.c (Ed) + 2. Put zuebcmp() declaration in #if 0 block as definition already is. This + function would be used to allow Unicode escapes on the command line + without using the -UN=escape option, but the utility of this is still + being determined. zipfile.c (SMS, Ed) + 3. Remove declaration for unused bz_deflate_init(). zipup.c (SMS, Ed) + 4. Add release announcement file, anticipating the long-awaited release. + zip30.ann (Ed) + 5. Update WhatsNew. WHATSNEW (Ed) +----------------------- March 24th 2008 version 3.0h03 -------------------- + 1. Update Unix configure script to better test for modern HP-UX compiler. + unix/configure (SMS) + 2. Updated Beta Readme. betas_readme.txt (Ed) + 3. Update Install. INSTALL (Ed) + 4. Update ReadMe. README (Ed) + 5. Small change to main help screen. zip.c (Ed) + 6. Small update to top of ToDo list. Actual updating of items still + needs to be done. TODO (Ed) +----------------------- April 2nd 2008 version 3.0h04 -------------------- + 1. Update copyright. crc32.h (Christian) + 2. Remove zip.h include. crc32.h (Christian) + 3. Add local prototypes for Unicode functions. Add cast for split size + check. Make many Unicode functions local. #if 0 out currently unused + utf8_chars(). Fix memory leak in wide_to_local_string() by adding + free() for buffer on error return. Fix memory leak in copy_args() on + error return by adding free-args(). Add ZCONST to arg in + insert_arg(). Shorten some lines to less than 80 characters. Add + free() to get_longopt() to fix memory leak. fileio.c (Christian) + 4. Create Win32 versions of wide_to_local_string() and + local_to_wide_string() so can use Win32 conversion functions. + fileio.c, win32/win32.c (Christian) + 5. Update comments for get_option(). fileio.c (Ed) + 6. Update encryption code readme. README.cr (Ed) + 7. Add prototype for recmatchw(). util.c (Christian) + 8. Change count_args() from static to local. util.c (Christian) + 9. Change ifdefs for includes for prototypes for version_info(), + zipstdout(), and check_zipfile() for WINDLL and MACOS and add + check_unzip_version(). zip.c (Christian) +10. Change ifndef NO_SYMLINKS to ifdef S_IFLNK for determining compiler + information. zip.c (Christian) +11. Change UTF-8 locale from en_GB.UTF-8 to .UTF-8. zip.c (Christian) +12. Change cast of -1 for dot_size from uzoff_t to zoff_t. + zip.c (Christian) +13. Change prototype for set_filetype to include parameter char *. + Change prototype of has_win32_wide to include parameter void. + zip.h (Christian) +14. Add prototypes for find_next_signature(), find_signature(), + and is_signature(). Change duplicate prototype scanzipf_regnew() + to missing prototype scanzipf_fixnew(). Change comment for Adler-16 + checksum to CRC-32 checksum as that is being used at that point in + the code. Move multiple uname assignments to common assignment. + Add inameLocal for WIN32_OEM and use define for inameLocal if not + to save memory allocation when not not using WIN32_OEM. Also + change _INTERN_OEM(str1) to INTERN_TO_OEM(src, dst) for OEM + conversion. Format comment for vem to fit in 80 character lines. + zipfile.c (Christian) +15. Change variable a from buffer to a pointer and add abf as the + buffer for zgetline() to handle NULL case. zipnote.c (Christian) +16. Change comments to zipentry comments and zipfile comment in + messages. zipnote.c (Ed) +17. Use uidgid_16bit as flag variable instead of uid_size. Modify + size check that prevents saving Unix UIDs and GIDs in the old + Unix extra field if they are not 16 bits. Change memory + allocation based on uidgid_16bit. Delete unused code for memory + copy for extra field. unix/unix.c (Christian, Ed) +18. Change compiler flag from -zp8 to -Zp8 for LCC Win32. + win32/makefile.lcc (Christian) +19. Add ifndef debug. Add bzip2 support. Add additional compiler + flags. win32/makenoas.w32 (Christian) +----------------------- April 10th 2008 version 3.0h05 -------------------- + 1. Fix bug found by forum poster where Zip stops recursing down a tree + when option -AS is set and a directory without the Windows archive + bit is reached. Now Zip continues down the tree to include files with + the bit set. win32/win32zip.c (forum poster, Ed) + 2. Update comments. win32/osdep.h (Ed) + 3. Update VMS notes to better organize and add information about file + name case. Additional small updates. vms/notes.txt (SMS) + 4. Fix bugs from previous changes to unix. unix/unix.c (SMS, Christian, + Ed) + 5. Add unix IBM support. unix/unix.c (SMS) + 6. Update INSTALL to account for new distribution structure and other + changes. INSTALL (SMS, Ed) + 7. Update bzip2 install readme. bzip2/install.txt (SMS, Ed) + 8. Fix bug noted in forum where -@ and -x generated a "nothing to + select from error" by also checking filelist variable populated by + -@ for entries. zip.c (forum poster, Ed) +----------------------- April 20th 2008 version 3.0h06 -------------------- + 1. Start announcement for Zip 3.0h public beta. zip30h.ann (Ed) + 2. Update beta readme. betas_readme.txt (Ed) + 3. Update case of README.CR. INSTALL (Ed) + 4. Change -W to -ws for option to stop wildcards from scanning directory + boundaries in path. This frees up -W for later use, maybe as extendted + option introducer. zip.c, man/zip.1 (Ed) + 5. Updated date in announcement to May 4th. zip30.ann (Ed) + 6. Added announcement for public beta Zip 3.0h. zip30h.ann (Ed) + 7. Fix large file support for MinGW by checking for compiler environments + before the check for (generic) gcc. zipup.c, win32/osdep.h + (Will, Christian) + 8. Fix large file support for bzip2. Additionally, the "dot printout" + code has also been adapted for LARGE_FILE support. zipup.c + (Will, Christian) + 9. Add comments to top of configure. unix/configure (Ed) +10. Move comment and comment out value size check for UID/GID extra field. + unix/unix.c (Ed) +11. Change case of file ToDo to TODO for consistency and to work with Unix + package. TODO (SMS, Ed) +----------------------- April 26th 2008 version 3.0h07 -------------------- + 1. For -AS, which for Windows only includes files with the archive bit + set, exclude directory entries (by setting -D) as some directories may + not have any files with the archive bit set and so the directory would + be empty. zip.c (Ed) + 2. Fix UID/GID size detection to use byte sizes and remove data fit test. + unix/unix.c (Ed) + 3. Update announcement. zip30h.ann (Ed) + 4. Add new unix extra field with tag 'ux' that stores UIDs/GIDs of 1 to 4 + bytes (8 to 32 bits). unix/unix.c (Ed) + 5. Update VB readme. windll/vbz64/readVB64.txt (Ed) + 6. For Unicode escaped output also show escape for ASCII 7-bit if + isprintable() is false. fileio.c (Ed) + 7. Use locale "en_US.UTF-8" for Unix. zip.c (Ed) + 8. Also show escaped Unicode for new files in found list. zip.c (Ed) + 9. Update manual. man/zip.1, zip.txt (Ed) +------------------------ May 4th 2008 version 3.0h08 ----------------------- + 1. Handle when a bad Unicode string in archive forces + utf8_to_wide_string() to return a NULL string. Give warning if UTF-8 + in existing archive is bad. Put WIN32 wide local header initializations + in UNICODE_SUPPORT block. fileio.c, zipfile.c (Ed) + 2. Leave out Unicode escape code if not Unicode enabled. zip.c (Ed) + 3. Enable oem_to_local_string() and local_to_oem_string() for WIN32 + even if no Unicode. zip.h, win32/win32.c (Christian, Ed) + 4. Update comment about encryption code. zipcloak.c (Ed) + 4. Update zipmessage_nl() and zipmessage() from zip.c. zipcloak.c, + zipnote.c, zipsplit.c (Ed) + 5. Add Mac OS X library check. unix/configure (SMS) + 6. Add 16-bit UID/GID check. unix/configure (Christian, Ed) + 7. Format echo and comment statements a bit. unix/configure (Ed) + 8. Only compile in old 16-bit UID/GID code if new define UIDGID_NOT_16BIT + from unix configure script is not defined. unix/unix.c (Christian) + 9. A couple changes to updated 16-bit UID/GID code. Add 64-bit + UID/GID support to new Unix extra field. unix/unix.c (Ed) +10. Remove redundant "license" from options table. zipcloak.c (Ed) +11. Remove old unix build files. unix/configure-orig, unix/Makefile-orig + (Christian) +12. Add -O (--output-file) option to ZipCloak. Fix bug by setting + out_path. zipcloak.c (Ed) +------------------------ May 8th 2008 version 3.0h09 ----------------------- + 1. Update copyright. Add check for NO_UNICODE_SUPPORT. tailor.h (Ed) + 2. Fix bug where Unicode General Purpose Bit Flag 11 should force keeping + the old name field but it was being overwritten by the escaped name + in the central directory header. Fixed some ZIPERR() calls in + putcentral() that referred to putlocal(). zipfile.c (Ed) + 3. Add comment about OCRCU8 and OCRCTB. unix/configure (Ed) + 4. Change line in instructions to note that manuals should be made after + Zip is made. Change OCRTB to OCRCTB. Add $(OCRCTB) to rule for + zipcloak$E so crc32_.o is linked in. Add comment for NO_UNICODE_SUPPORT + flag. unix/makefile (Ed) + 5. Update WhatsNew. Add additional items to the Zip 3.1 list. Add note + about Zip 2.4. WHATSNEW (Ed) + 6. Update Zip 3.0h announcement. zip30h.ann (Ed) + 7. Update manual pages. man/zip.1, man/zipsplit.1, man/zipnote.1, + man/zipcloak.1 (Ed) + 8. Add noted for UTF-8 locale. zip.c (Ed) + 9. Set UTF-8 locale for Unix in utilities if UNICODE_SUPPORT enabled + so can display and process paths in archives correctly. zipsplit.c, + zipcloak.c, zipnote.c (Ed) +------------------------ May 12th 2008 version 3.0h10 ---------------------- + 1. Add use of new Unix UID/GID extra field and of old Unix 16-bit UID/GID + extra field when system uses 16-bit UIDs/GIDs to version information. + zip.c (SMS, Ed) + 2. Add Unicode Path and Unicode Comment extra fields to extra fields list. + Update new Unix extra field revision date. proginfo/extrafld.txt (Ed) + 3. Add Mac hardware platform to version information. unix/unix.c (SMS) +------------------------ May 19th 2008 version 3.0h11 ---------------------- + 1. Initialize f->namew when streaming stdin to fix bug. fileio.c (Ed) + 2. Change force_zip64 to start as -1 as unset, then use 1 for forcing use + of Zip64 and 0 for disabling use of Zip64. Add negation of -fz to + prevent use of Zip64 during streaming from stdin to a non-seekable + output where data descriptors will be used, which allows creating + archives with the old stream format but will fail if a large file is + streamed. Default is still to force Zip64 data descriptors when + streaming, which covers all cases but requires a Zip64 compatible + unzip. zip.c, globals.c, zipfile.c (Ed) + 3. Handle case of bad Unicode in archive. zipfile.c (Ed) +------------------------ May 22nd 2008 version 3.0h12 ---------------------- + 1. Fix bug introduced last beta that prevented streaming large files. Use + separate error message depending on if -fz- was used. zipfile.c (Ed) + 2. Change non existent to nonexistent. unix/configure (SMS) + 3. Don't output blank line when zipmessage_nl() gets passed an empty + string. This removes blank lines for skipped entries when -FS used. + zip.c (Ed) +------------------------ May 27th 2008 version 3.0h13 ---------------------- + 1. Change UNICODE_ALLOW_FORCE to UNICODE_SUPPORT, -UN=force to -UN=UTF8, + and unicode_force to utf8_force. This option now standard with Unicode + support and forces Zip to save UTF-8 paths and comments, when not ASCII, + as if UTF-8 were the native character set. globals.c, zip.c, zip.h (Ed) + 2. Add note to Todo that it's out of date. TODO (Ed) + 3. Update WhatsNew. WHATSNEW (Ed) + 4. Update Unicode help in extended help. zip.c (Ed) + 5. Update announcements. zip30h.ann, zip30.ann (Ed) + 6. Fix bug with -UN=UTF8. zip.c, zipfile.c (Ed) + 7. Update Zip manual. man/zip.1, zip.txt (Ed) + 8. Attempt an update to zip limits document. proginfo/ziplimit.txt (Ed) + 9. Update README regarding forum postings. README (Ed) +10. Remove duplicate initialization lines for found and fnxt. zip.c (SMS) +------------------------ May 28th 2008 version 3.0h14 ---------------------- + 1. Remove >= 0 check from wide character check as value is unsigned. + fileio.c (SMS) + 2. In putlocal(), move nam and use_uname to UNICODE_SUPPORT block. If + no UNICODE_SUPPORT use z->nam instead of nam. zipfile.c (SMS, Ed) + 3. Update announcement date for beta. zip30h.ann (Ed) +------------------------ May 31st 2008 version 3.0h ------------------------ + 1. In putlocal() if using UTF-8 bit then also set UTF-8 bit in z->lflg so + is set in local header for streaming. zipfile.c (Ed) + 2. Update announcement date for beta. zip30h.ann (Ed) + 3. Rename lib and dll projects to zip32z64 and update project files so + project name is same as lib and dll libraries. Export make files. + windll/visualc/dll/zip32z64.dsp, windll/visualc/dll/zip32z64.dsw, + windll/visualc/dll/zip32z64.mak, windll/visualc/libzip32z64.dsp, + windll/visualc/libzip32z64.dsw, windll/visualc/libzip32z64.mak (Ed) +------------------------ June 7th 2008 version 3.0i01 ---------------------- + 1. Update Mac ReadMe to note Mac OS X uses Unix port. macos/readme.1st (Ed) + 2. Change UNIX to Unix in manual. Update dates in manual and add note + about Mac OS X. Change switch to switches. zip.1 (SMS, Ed) + 3. Add version information under Windows by adding a version resource. + win32/vc6/zip.dsp, win32/vc6bz2/zip.dsp, win32/zip.rc (Ed) +------------------------ June 15th 2008 version 3.0i02 ---------------------- + 1. Update Install instructions. INSTALL (Ed) + 2. Update ReadMe. README (Ed) + 3. Update ToDo list. TODO (Ed) + 4. Update WhatsNew. WHATSNEW (Ed) + 5. Add note to WHERE. WHERE (Ed) + 6. Update announcement. zip30.ann (Ed) + 7. Review man pages and update Zip man page. Compile text files from man + pages. man/zip.1, zip.txt, zipnote.txt, zipsplit.txt, zipcloak.txt (Ed) + 8. Update extended help. zip.c (Ed) +------------------------ June 17th 2008 version 3.0i03 ---------------------- + 1. Fix bug where UTF-8 flag was not being set when using_utf8 was set as + result of UTF-8 being current character set. zipfile.c (Ed) + 2. Update man page globbing description. man/zip.1, zip.txt (SMS, Ed) + 3. Update web address to bzip2 package for VMS. vms/install_vms.txt (SMS) +------------------------ June 21st 2008 version 3.0i04 ---------------------- + 1. Update comments. zbz2err.c (Christian) + 2. Put use_uname in UNICODE_SUPPORT block. zipfile.c (Christian) + 3. Increase st to 0x1400. msdos/makefile.msc (Christian) + 4. Update copyright and put @CodeSize and @DataSize into ifndef blocks for + Huge, Large, Compact, Medium, and Small. msdos/match.asm (Christian) + 5. Add check to disable symbolic links. msdos/osdep.h (Christian) + 6. Put Mac OS X compiler check into if Mac OS X block to avoid problems on + some other Unix ports with the check. unix/configure (SMS) + 7. Move set_extra_field() to fix compile problem. unix/unix.c (SMS) + 8. Update USEBZIP2 to USEBZ2 and -DUSE_BZIP2 to -DBZIP2_SUPPORT. Drop + -DMSDOS compile flag. win32/makefile.w32 (Christian) + 9. Change BZIP2_SUPPORT to USEBZ2. win32/makenoas.w32 (Christian) +------------------------ June 23rd 2008 version 3.0i05 ---------------------- + 1. Update and unify resources. Remove any MFC dependencies from the resource + files zip.rc and windll.rc. win32/zip.rc and windll/windll.rc now read + the version info from revision.h. windll.rc internal flags modified to + "32-bit dll". zip.rc internal flags liberated from "winnt 32-bit" + to "generic 32-bit windows". Win32 zip.exe also supported on Win9x + (32-bit). Update makefiles for Borland, MSC, GCC(mingw32), Watcom + to support inclusion of zip.rc version resources into zip.exe binary. + revision.h, msdos/osdep.h, win32/makefile.bor, win32/makefile.gcc, + win32/makefile.w10, win32/makefile.w32, win32/makefile.wat, + win32/makenoas.w32, win32/zip.rc, windll/windll.rc (Christian) + 2. Remove unused files. win32/resource.h, windll/resource.h, + windll/windll.aps, windll/zipver.h, windll/visualc/dll/zip32z64.mak, + windll/visualc/lib/zip32z64.mak (Christian) + 3. Update VMS. vms/descrip_deps.mms (SMS) +------------------------ June 26th 2008 version 3.0i06 ---------------------- + 1. Update Install and Readme in preparation for release. Update WhatsNew. + INSTALL, README, WHATSNEW (Ed) + 2. Update announcement. zip30.ann (Ed) + 3. Update original Visual Basic project comments and documentation. + windll/vb/readmevb.txt, windll/vb/vbzip.vbp, windll/vb/vbzip.vbw, + windll/vb/vbzipbas.bas, windll/vb/vbzipfrm.frm (Ed) + 4. Add bzip2 version of djgpp 2.x makefile thanks to Robert. Assumes a + standard djgpp installation. msdos/makebz2.dj2 (Robert Riebisch, Ed) +------------------------ June 27th 2008 version 3.0i07 ---------------------- + 1. Add DJGPP to bzip2 install instructions. bzip2/install.txt, + msdos/makebz2.dj2 (Robert, Ed) +------------------------- July 5th 2008 version 3.0 ------------------------- + 1. Add -sd to extended help. zip.c (Will, Ed) + 2. Fix memory bug when rebuilding Zip64 central directory extra field which + can crash MinGW and other ports when processing large files. zipfile.c + (Will) + 3. Fix -v bug preventing display of version information when options in + environment variables. zip.c (Ed) + 4. Update WhatsNew. WHATSNEW (Ed) + 5. Update announcement. zip30.ann (Ed) diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..be3e0c5 --- /dev/null +++ b/INSTALL @@ -0,0 +1,368 @@ +HOW TO INSTALL ZIP + + Zip is distributed as C source code that can be compiled on a + wide range of systems: Unix, VMS, MSDOS, OS/2, NT, Amiga, Atari, + BeOS, VM/CMS, ... You will need Unzip 5.0p1 or later (under any + system) or PKUNZIP 2.04g or later (under MSDOS) to unpack the + distribution file, in this case zip30.zip. But since you read this, + you have unpacked it already, or you cheated and got a tar.Z file... + + Note: Zip 3.0 distribution kits (unlike previously distributed + Zip 2.x kits) are created with a top-level directory ("zip30") in + the archive, making the creating of the zipsrc directory optional. + +Installation on Unix (see below for installation on other systems) + + Let's assume that you start from scratch and have not yet unpacked + the sources. First step, then, is to unpack Zip. The following + assumes that you have zip30.zip in the current directory. + + For example, to extract to a new zipsrc directory (assuming + zip30.zip is in the current directory): + + mkdir zipsrc + cd zipsrc + cp ../zip30.zip . + unzip zip30.zip + cd zip30 + + To extract in an existing directory, such as /usr/local/src/zip: + + cd /usr/local/src/zip + (copy zip30.zip here) + unzip zip30.zip + cd zip30 + + The first extracts all source files and documentation to the + directory "zipsrc/zip30". The second places the zip30 directory + in the "/usr/local/src/zip" directory. Both then cd in to the + zip30 directory where Zip will be built. + + Note: This release now includes the standard encryption code + previously in the separate package zcrypt29.zip, but you still + can decide whether to activate the crypt code or not. Crypt is + enabled by default, but you may disable it by specifying the + option -DNO_CRYPT in the LOCAL_ZIP environment variable (or by + adding this option to the compilation options in the appropiate + makefile). See README.CR for more on crypt. + + You then do: + + make -f unix/Makefile system + + where "system" is one of: generic, generic_gcc, + att6300, coherent, cray_v3, minix, sco_x286, xenix, zilog. + + For Unix systems where "cc" is the preferred C compiler command, + try + + make -f unix/Makefile generic + + first. If "gcc" is preferred, specify "generic_gcc" instead of + "generic". This should work on most systems and automatically + selects compilation options based on a set of tests (in + unix/configure), including detection of large file support + sufficient to enable Zip64 large archive features. If "generic" + (or "generic_gcc" if that is used) fail, then one of the special + targets given above may work. + + Among other special systems are Cray Unicos, Zilog Zeus and MINIX. + + The optimization settings for many systems should be close, but + if you see optimization for your system is not ideal, send in + the changes so we can improve it. + + By default, Zip uses the "deflate" compression method. To add + the additional optional "bzip2" compression method, see the file + bzip2/install.txt. Note that bzip2 support is provided by + compiling or linking in the bzip2 library. See the bzip2 site + (http://www.bzip.org/) for more on bzip2. + + If you get error messages such as "constant expected" in + deflate.c, add -DDYN_ALLOC to CFLAGS in your makefile entry. + + If you have lots of memory, try compiling with -DBIG_MEM. If your + system supports mmap(), try compiling with -DMMAP. This generally + gives faster compression but uses more memory. See the unix/Makefile + entry mmap_gcc for an example. + + If none of these compiles, links, and functions properly on + your Unix system, then your system apparently has specific + requirements we did not account for. See the file README for how + to get help. + + If the appropriate system was selected, then the executables zip, + zipnote, zipcloak, and zipsplit will be created. You can copy + them to an appropriate directory in the search path using: + + make -f unix/Makefile install + + The defaults are /usr/local/bin for the executables and + /usr/local/man/man1 for the manual pages. Change the macros + BINDIR and MANDIR in makefile to change these if needed. + + If necessary, add the directory with the Zip executables to your + shell's PATH (or "path") variable. (C-shell users may need to + use the "rehash" command so csh can find the new command in the + path.) You should now be ready to use Zip. + + You can get rid of the now unnecessary source and object files + with: + + cd .. + rm -r zip30 + + This will remove the directory zip30 and its contents created + by unzip. You should keep the zip30.zip file around though, + in case you need to build it again or want to give it to a + colleague. + + You can add the following lines to the file /etc/magic for + usage by the 'file' command: + +0 string PK Zip archive +>4 byte 011 (at least v0.9 to extract) +>4 byte 012 (at least v1.0 to extract) +>4 byte 013 (at least v1.1 to extract) +>4 byte 024 (at least v2.0 to extract) +>4 byte 025 (at least v2.1 to extract) + + +Installation on other systems + + The steps for installation under VMS, MSDOS, OS/2, NT, Amiga and + Atari are similar to the above: first unzip the distribution + files into their own directory. The system-dependent files are + stored in special subdirectories. + + For all the non-Unix ports which support the creation of "UT" extra + fields (these ports contain USE_EF_UT_TIME in the list of optional + features displayed with "zip -v"), the timezone environment variable TZ + should be set according to the local timezone in order for the -f, -u, + -o, and similar options to work correctly. This is not needed for the + WIN32 and WinDLL ports, since they get the timezone information from + the OS by other means. + + + MSDOS: + + Do one of: + + make msdos\makefile.msc (Microsoft C 5.1) + nmake -f msdos\makefile.msc (Microsoft C 6.0 and newer) + make -fmsdos\makefile.bor -DCC_REV=1 (Borland Turbo C++ 1.0) + make -fmsdos\makefile.bor (Borland C++ 2.0 and newer) + make -fmsdos\makefile.tc (Borland Turbo C 2.0x) + make -f msdos/makefile.dj1 (DJGPP v1.12m4) + make -f msdos/makefile.dj2 (DJGPP v2.01 and newer) + make -f msdos/makefile.emx (gcc/emx 0.9b and newer) + make -f os2/makefile.os2 gccdos (gcc/emx 0.9b and newer) + wmake -f msdos\makefile.wat (Watcom C 11.x 16-bit) + wmake -f msdos\makefile.wat PM=1 (Watcom C 11.x 32-bit, PMODE/W) + + for Microsoft, Borland C++ and Turbo C, Watcom C/C++ and the various + free GNU C implementations, respectively. More detailed instructions + can be found in the respective makefiles. + + + WIN32 (Windows NT/2K/XP/2K3 and Windows 95/98/ME): + + Supported compilers are Microsoft Visual C++, Borland C++, Watcom C/C++, + and miscellaneous free GNU C implementations (gcc/mingw, CygWin, ...). + The makefiles supplied in the win32/ subdirectory contain further + information. + + + Windows DLL (WIN32): + + Supported environments are Visual C++ (32-bit only, 5.x and newer). + For instructions how to build the DLLs and where find the makefiles, + look into windll/contents. + + + OS/2: + + Type + + {make} -f os2/makefile.os2 + + to get a list of supported targets/compiling environments. + (replace "{make}" with the name of your OS/2 make utility.) + + To initiate the actual compiling process, you have to specify + a system target: + + {make} -f os2/makefile.os2 {system} + + An example: type + + nmake -f os2/makefile.os2 msc + + for Microsoft C 6.00. + + + VMS (OpenVMS): + + The most complete information on building and installing Zip on VMS + is in [.vms]install_vms.txt. Optimists in a hurry may wish to try + commands like these: + + @ [.VMS]BUILD_ZIP.COM + or: + MMS /DESCRIP = [.VMS]DESCRIP.MMS CLEAN ! Or MMK ... + MMS /DESCRIP = [.VMS]DESCRIP.MMS ! Or MMK ... + + When the executables have been created (or located if already installed), + most users define foreign command symbols for the Zip executables, like + this: + + ZIP :== $ dev:[dir]ZIP.EXE ! UNIX-like command line. + or: + ZIP :== $ dev:[dir]ZIP_CLI.EXE ! VMS-like command line. + + Such symbol definitions are often added to a user's + SYS$LOGIN:LOGIN.COM procedure, or to a common, site-specific + procedure, like SYS$MANAGER:SYLOGIN.COM. + + Additional installation options are described in install_vms.txt. + + The builders create help text files, ZIP.HLP and ZIP_CLI.HLP. Also + see install_vms.txt for how to create the help libraries. + + +Mac OS: + + Mac OS X is part of the Unix port, so use the Unix installation above. + + Mac OS before Mac OS X use the Mac OS port, though little testing has + been done for that port recently. See macos/README.TXT for more on + this port. + + +Compiler Flags + + Zip should compile fine out of the box for your port. In particular, + for Unix the command + make -f unix/Makefile generic + should automatically detect the features available on your system and + set the flags appropriately. In some cases, however, you may need to + set one or more compiler flags yourself to get Zip to compile or to + add features you want or remove features that cause trouble for your + port. Below are the more common compiler macros you can set. + + LARGE_FILE_SUPPORT + Tell Zip that the OS supports large files (generally files larger + than 4 GB). Zip will try to compile in the large file calls + (typically 64-bit) for the OS instead of using the standard + (typically 32-bit) file calls. On Unix Zip tries to switch over to + the 64-bit file environment. If setting this flag causes errors + or Zip still can't handle large files on that port, then probably + either Zip doesn't have the code to support large files on your OS + (write a patch and send it in to us) or your OS doesn't support large + files. + + Note that the flag ZIP64_SUPPORT must also be set to create archives + with large files. + + This flag should be set automatically on Unix, Win32, and some + other ports. Setting NO_LARGE_FILE_SUPPORT turns this flag off. + + ZIP64_SUPPORT + Enable the Zip64 code in Zip that supports the Zip64 extensions noted + in the PKWare AppNote. These extensions allow storing files larger + than 4 GB in archives and the creating of archives larger than 4 GB. + They also allow storing more than 64K files in an archive. Currently + Zip does not handle archives of PKZip version 4.5 or later unless + this flag is set. + + To enable large file support in Zip, you generally need to set both + LARGE_FILE_SUPPORT (to read and write large files) and ZIP64_SUPPORT + (to store them in and read them from archives). Files larger than + 4 GB may be invisible to Zip (directory scans don't see them) if + LARGE_FILE_SUPPORT is not enabled. + + Keeping LARGE_FILE_SUPPORT and ZIP64_SUPPORT separate allows easier + debugging of these features. When testing large file support on an + OS, first set just LARGE_FILE_SUPPORT to test the file calls (all + should compile and work as before with small files), then turn on + ZIP64_SUPPORT to let Zip recognize and handle large files. + + This flag should be set automatically on most ports if + LARGE_FILE_SUPPORT is set. Setting NO_ZIP64_SUPPORT turns this flag + off. + + UNICODE_SUPPORT + Enable storing and using UTF-8 paths. These paths are stored in + a backward-compatible way so that archives with UTF-8 paths still + work on zips and unzips that don't support Unicode. This support + follows the recent additions to the PKWare AppNote for Unicode + support, except that Unicode comments on systems where UTF-8 is + not the current character set is not implemented in this release. + + On some ports UNICODE_SUPPORT is set automatically if wide characters + are supported. Setting NO_UNICODE_SUPPORT turns off this flag. + + USE_EF_UT_TIME + Enables storing UT time in an extra field. This becomes useful + for ports that normally store file times as local time, resulting + in problems when files are moved across time zones and when + there are daylight savings time changes. Zip and UnZip will + automatically correct for time zone changes when UT time is stored. + + This is usually set by default. Use NO_EF_UT_TIME to turn this off. + + NTSD_EAS (Win32 only) + Enable storing Windows NT file security descriptors. This allows + restoring the descriptors (file ACL's, etc.). + + This is on by default for Win32. Use NO_NTSD_EAS to turn this off. + + BZIP2_SUPPORT + Enable compressing zip entries using the bzip2 library. You must get + the bzip2 library from somewhere else as we only provide a way to + compile or link the library in and compress files using bzip2. Enables + a new compression method, bzip2, that can be used instead of the default + Zip compression method deflate. + + This flag is set on Unix, including Mac OS X, when compiling using + generic if the bzip2 library is found. Set on Win32 if the bzip2 + projects are used. See the VMS documentation for when VMS sets this + flag. Setting NO_BZIP2_SUPPORT turns this off. + + See bzip2/install.txt for more on installing bzip2 support. + + WIN32_OEM (Win32 only) + Enable saving paths on Win32 in the OEM character set. Zip has stored + paths using the standard ANSI local character set, but other zips have + used the OEM character set on MSDOS and Win32. This flag should make + Zip more compatible with other DOS and Win32 zips and unzips. It also + enables the translation of OEM paths in DOS archives to ANSI and should + eliminate some problems with funny characters showing up in path names. + + If Unicode is enabled and used, Unicode paths generally override + local paths using OEM character sets. + + This flag is on by default on most Win32 ports. Some ports apparently + have problems with OEM conversions. If your port or compiler does + funny things with file names, you may want to turn this off. Defining + NO_WIN32_OEM turns this flag off. + + NO_STREAMING_STORE + Because storing zip archives inside a zip entry adds "false" signatures + and this causes problems when using data descriptors if the archive + needs fixing, this option is provided to force deflating when streaming. + This version of Zip includes an advanced algorithm for correctly finding + these signatures, but if an archive is "broke", there is no telling + what's where. This is only a problem if an archive becomes broke for + some reason, but to be safe define this. + + ALLOW_REGEX + For MSDOS and Windows, now "[list]" wildcard matching (where any + character between [ and ] can be used to match the character at that + position) is turned off unless the new -RE option is used. Defining + this flag forces "[list]" matching to be always on as in previous + releases. + + +For command help on any of the zip* utilities, simply enter +the name with no arguments. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bcfe47e --- /dev/null +++ b/LICENSE @@ -0,0 +1,60 @@ +This is version 2007-Mar-4 of the Info-ZIP license. +The definitive version of this document should be available at +ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely and +a copy at http://www.info-zip.org/pub/infozip/license.html. + + +Copyright (c) 1990-2007 Info-ZIP. All rights reserved. + +For the purposes of this copyright and license, "Info-ZIP" is defined as +the following set of individuals: + + Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois, + Jean-loup Gailly, Hunter Goatley, Ed Gordon, Ian Gorman, Chris Herborth, + Dirk Haase, Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz, + David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko, + Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs, + Kai Uwe Rommel, Steve Salisbury, Dave Smith, Steven M. Schweda, + Christian Spieler, Cosmin Truta, Antoine Verheijen, Paul von Behren, + Rich Wales, Mike White. + +This software is provided "as is," without warranty of any kind, express +or implied. In no event shall Info-ZIP or its contributors be held liable +for any direct, indirect, incidental, special or consequential damages +arising out of the use of or inability to use this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the above disclaimer and the following restrictions: + + 1. Redistributions of source code (in whole or in part) must retain + the above copyright notice, definition, disclaimer, and this list + of conditions. + + 2. Redistributions in binary form (compiled executables and libraries) + must reproduce the above copyright notice, definition, disclaimer, + and this list of conditions in documentation and/or other materials + provided with the distribution. The sole exception to this condition + is redistribution of a standard UnZipSFX binary (including SFXWiz) as + part of a self-extracting archive; that is permitted without inclusion + of this license, as long as the normal SFX banner has not been removed + from the binary or disabled. + + 3. Altered versions--including, but not limited to, ports to new operating + systems, existing ports with new graphical interfaces, versions with + modified or added functionality, and dynamic, shared, or static library + versions not from Info-ZIP--must be plainly marked as such and must not + be misrepresented as being the original source or, if binaries, + compiled from the original source. Such altered versions also must not + be misrepresented as being Info-ZIP releases--including, but not + limited to, labeling of the altered versions with the names "Info-ZIP" + (or any variation thereof, including, but not limited to, different + capitalizations), "Pocket UnZip," "WiZ" or "MacZip" without the + explicit permission of Info-ZIP. Such altered versions are further + prohibited from misrepresentative use of the Zip-Bugs or Info-ZIP + e-mail addresses or the Info-ZIP URL(s), such as to imply Info-ZIP + will provide support for the altered versions. + + 4. Info-ZIP retains the right to use the names "Info-ZIP," "Zip," "UnZip," + "UnZipSFX," "WiZ," "Pocket UnZip," "Pocket Zip," and "MacZip" for its + own source and binary releases. diff --git a/README b/README new file mode 100644 index 0000000..a559425 --- /dev/null +++ b/README @@ -0,0 +1,234 @@ +Zip 3.0 is the first Zip update adding large file support. For now Zip 2.3x +remains available and supported, but users should switch to this new release. + +Testing for Zip 3.0 has focused mainly on Unix, VMS, Max OS X, and Win32, +and some other ports may not be fully supported yet. If you find your +favorite port is broke, send us the details or, better, send bug fixes. It's +possible that support for some older ports may be dropped in the future. + + + +Copyright (c) 1990-2008 Info-ZIP. All rights reserved. + +See the accompanying file LICENSE (the contents of which are also included +in unzip.h, zip.h and wiz.h) for terms of use. If, for some reason, all +of these files are missing, the Info-ZIP license also may be found at: +ftp://ftp.info-zip.org/pub/infozip/license.html and +http://www.info-zip.org/pub/infozip/license.html. + + +Zip 3.0 is a compression and file packaging utility. It is compatible with +PKZIP 2.04g (Phil Katz ZIP) for MSDOS systems. There is a companion to zip +called unzip (of course) which you should be able to find in the same place +you got zip. See the file 'WHERE' for details on ftp sites and mail +servers. + +So far zip has been ported to a wide array of Unix and other mainframes, +minis, and micros including VMS, OS/2, Minix, MSDOS, Windows, Atari, Amiga, +BeOS and VM/CMS. Although highly compatible with PKware's PKZIP and PKUNZIP +utilities of MSDOS fame, our primary objective has been one of portability +and other-than-MSDOS functionality. Features not found in the PKWare version +include creation of zip files in a pipe or on a device; VMS, BeOS and OS/2 +extended file attributes; conversion from Unix to MSDOS text file format; and, +of course, the ability to run on most of your favorite operating systems. And +it's free. + +See the file zip30.ann for a summary of new features in Zip 3.0 and WhatsNew +for the detailed list of new features and changes since Zip 2.32. The file +CHANGES details all day-to-day changes during development. + +Notes: + +Multi-volume support. This version does not support multi-volume spanned +archives as in pkzip 2.04g, and there is no intention at this point to support +spanned archives, but Zip 3.0 supports split archives. A split archive is an +archive split into a set of files, each file a piece of the archive and each +file using an extension, such as .z02 as in the file name archive.z02, that +provides the order of the splits. In contrast, a spanned archive is the +original multi-floppy archive supported by pkzip 2.0g where the split order +is contained in the volume labels. The contents of split and spanned archives +are mostly identical and there is a simple procedure to convert between the +formats. Many current unzips now support split archives. + +Zip64 support. This version supports Zip64 archives as described in the +PKWare AppNote. These archives use additional fields to support archives +greater than 2 GB and files in archives over the 2 GB previous limit (4 GB +on some ports). The Zip64 format also allows more than 64k entries in an +archive. Support by the OS for files larger than 4 GB is needed for Zip to +create and read large files and archives. On Unix, Win32, and some other +ports, large file and Zip64 support is automatically checked for and +compiled in if available. Use of Zip64 by Zip is automatic and to maximize +backward compatibility the Zip64 fields will only be used if needed. A +Zip64 archive requires a pkzip 4.5 compatible unzip, such as UnZip 6.0. + +Unicode support. This version has initial Unicode support. This allows +paths and names of files in other character sets to be accurately recreated +on OS that have sufficient character set support. On Win32, if wide +character calls are supported (not Win 9x unless Unicode support has been +added) all files (including paths with illegal characters in the current +character set) should now be readable by zip. Unicode support is provided +using a new set of UTF-8 path and comment extra fields and a new UTF-8 bit +for flagging when the current character set is already UTF-8. Zip 3.0 +maintains backward compatibility with older archives and is mostly compliant +with the new Unicode additions in the latest PKWare AppNote. The exception +is UTF-8 comments, which are not supported if UTF-8 is not the native +character set, but should be fully implemented in Zip 3.1. + +16-bit OS support. Though Zip 3.0 is designed to support the latest zip +standards and modern OS, some effort has been made to maintain support +for older and smaller systems. If you find Zip 3.0 does not fit on or +otherwise does not work well on a particular OS, send in the details and +we might be able to help. + +Compression methods. In addition to the standard store and deflate methods, +Zip now can use the bzip2 compression format using the bzip2 library. Though +bzip2 compression generally takes longer, in many cases using bzip2 results +in much better compression. However, many unzips may not yet support +bzip2 compressed entries in archives, so test your unzip first before using +bzip2 compression. + +Installation. Please read the file INSTALL for information on how to compile +and install zip, zipsplit, zipcloak, and zipnote and please read the manual +pages ZIP.txt, ZIPSPLIT.txt, ZIPCLOAK.txt, and ZIPNOTE.txt for information on +how to use them. Also, if you are using MSDOS or Windows, note that text +files in the distribution are generally in Unix line end format (LF only) +and Windows and DOS users will need to either convert the files as needed to +DOS line ends (CR LF) or extract the distribution contents using unzip -a. + +Utilities. At this point zipsplit, zipcloak, and zipnote should work with +large files, but they currently do not handle split archives. A work around +is to use zip to convert a split archive to a single file archive and then use +the utilities on that archive. + +Encryption. This version supports standard zip encryption. Until recently +the encryption code was distributed separately because of the US export +regulations but now is part of the main distribution. See crypt.c for +details. Decryption can be made with unzip 5.0p1 or later, or with zipcloak. + +Bug reports. All bug reports or patches should go to zip-bugs via the web +site contact form at http://www.info-zip.org/zip-bug.html (we have discontinued +the old email address zip-bugs@lists.wku.edu because of too much spam lately) +and suggestions for new features can be submitted there also (although we don't +promise to use all of them). We also are on SourceForge at +http://sourceforge.net/projects/infozip/ and now automatically get Bug Reports +and Feature Requests submitted there. In addition, a new Info-ZIP discussion +forum is available as well. See below. Though bug reports can be posted there, +we don't have automatic monitoring of all postings set up yet so you may want +to use the web form or SoureForge for a quicker response. A good approach may +be to post the details on the forum so others can benefit from the posting, +then use the web reply form to let us know you did that if you don't get a +reply in a reasonable time. + +Ports. If you're considering a port, please check in with zip-bugs FIRST, +since the code is constantly being updated behind the scenes. We'll +arrange to give you access to the latest source. + +Discussion group. If you'd like to keep up to date with our Zip (and companion +UnZip utility) development, join the ranks of BETA testers, add your own +thoughts and contributions, etc., check out the new discussion forum. This is +the latest offering, after the various Info-ZIP mailing-lists on +mxserver@lists.wku.edu (courtesy of Hunter Goatley) were no longer available +and the temporary QuickTopic discussion group for Info-ZIP issues at +http://www.quicktopic.com/27/H/V6ZQZ54uKNL died a horrible death due to large +amounts of spam. The new discussion forum is now available at +http://www.info-zip.org/board/board.pl (thanks again to Hunter Goatley) and +can be used to discuss issues, request features, and is one place new betas +and releases are announced. It also is a place to post bug reports, and +patches can be submitted as attachments. However, we don't yet get +automatic notification of all postings there so try one of the other methods +if you don't get a response. You can also post Bug Reports and Feature +Requests at Source Forge. However, the web site contact form remains +available if you would rather not post on the public forums. + +Frequently asked questions on zip and unzip: + +Q. When unzipping I get an error message about "compression method 8". + +A. This is standard deflate, which has been around for awhile. Please + get a current version of unzip. See the file 'WHERE' for details. + + +Q. How about "compression method 12"? + +A. Compression method 12 is bzip2 and requires a relatively modern unzip. + Please get the latest version of unzip. + + +Q. I can't extract this zip file that I just downloaded. I get + "zipfile is part of multi-disk archive" or some other message. + +A. Please make sure that you made the transfer in binary mode. Check + in particular that your copy has exactly the same size as the original. + Note that the above message also may actually mean you have only part + of a multi-part archive. Also note that UnZip 5.x does not and UnZip 6.0 + probably won't have multi-disk (split) archive support. A work around + is to use Zip 3.0 to convert the split archive to a single-file archive + then use UnZip on that archive. As a last result, if there's something + readable in what you have, zip -FF should be able to recover it. + + +Q. When running unzip, I get a message about "End-of-central-directory + signature not found". + +A. This usually means that your zip archive is damaged, or that you + have an uncompressed file with the same name in the same directory. + In the first case, it makes more sense to contact the person you + obtained the zip file from rather than the Info-ZIP software + developers, and to make sure that your copy is strictly identical to + the original. In the second case, use "unzip zipfile.zip" instead + of "unzip zipfile", to let unzip know which file is the zip archive + you want to extract. + + +Q. Why doesn't zip do just like PKZIP does? + +A. Zip is not a PKZIP clone and is not intended to be one. In some + cases we feel PKZIP does not do the right thing (e.g., not + including pathnames by default); in some cases the operating system + itself is responsible (e.g., under Unix it is the shell which + expands wildcards, not zip). Info-ZIP's and PKWARE's zipfiles + are interchangeable, not the programs. + + For example, if you are used to the following PKZIP command: + pkzip -rP foo *.c + you must use instead on Unix: + zip -R foo "*.c" + (the quotes are needed to let the shell know that it should + not expand the *.c argument but instead pass it on to the program, + but are not needed on ports that do not expand file paths like + MSDOS) + + +Q. Can I distribute zip and unzip sources and/or executables? + +A. You may redistribute the latest official distributions without any + modification, without even asking us for permission. You can charge + for the cost of the media (CDROM, diskettes, etc...) and a small copying + fee. If you want to distribute modified versions please contact us at + www.Info-ZIP.org first. You must not distribute beta versions. + The latest official distributions are always on ftp.Info-ZIP.org in + directory /pub/infozip and subdirectories and at SourceForge. + + +Q. Can I use the executables of zip and unzip to distribute my software? + +A. Yes, so long as it is made clear in the product documentation that + zip or unzip are not being sold, that the source code is freely + available, and that there are no extra or hidden charges resulting + from its use by or inclusion with the commercial product. See the + Info-ZIP license for more. Here is an example of a suitable notice: + + NOTE: is packaged on this CD using Info-ZIP's compression + utility. The installation program uses UnZip to read zip files from + the CD. Info-ZIP's software (Zip, UnZip and related utilities) is + freely distributed under the Info-ZIP license and can be obtained as + source code or executables from various anonymous-ftp sites, + including ftp://ftp.info-zip.org/pub/infozip. + + +Q. Can I use the source code of zip and unzip in my commercial application? + +A. Yes, as long as the conditions in the Info-ZIP license are met. We + recommend you include in your product documentation an acknowledgment + and note that the original compression sources are available at + www.Info-ZIP.org. If you have special requirements contact us. diff --git a/README.CR b/README.CR new file mode 100644 index 0000000..c777d19 --- /dev/null +++ b/README.CR @@ -0,0 +1,119 @@ +_____________________________________________________________________________ + + This is Info-ZIP's README.CR for zcrypt29.zip, last updated 27 March 2008. +_____________________________________________________________________________ + + +The files described below contain the encryption/decryption code for Zip 2.31, +UnZip 5.52, and WiZ 5.02 (and later). These files are included in the main +source distributions for all of these now, but the encryption patch is still +available for earlier versions of these. This file both describes the history +of the encryption package and notes the current conditions for use. Check +the comments at the top of crypt.c and crypt.h for additional information. + +As of version 2.9, this encryption source code is copyrighted by Info-ZIP; +see the enclosed LICENSE file for details. Older versions remain in the pub- +lic domain. Zcrypt was originally written in Europe and, as of April 2000, +can be freely distributed from the US as well as other countries. + +(The ability to export from the US is new and is due to a change in the Bureau +of Export Administration's regulations, as published in Volume 65, Number +10, of the Federal Register [14 January 2000]. Info-ZIP filed the required +notification via e-mail on 9 April 2000; see the USexport.msg file in this +archive. However, as of June 2002, it can now be freely distributed in both +source and object forms from any country, including the USA under License +Exception TSU of the U.S. Export Administration Regulations (section 740.13(e)) +of 6 June 2002.) + + LIKE ANYTHING ELSE THAT IS FREE, ZIP, UNZIP AND THEIR ASSOCIATED + UTILITIES ARE PROVIDED AS IS AND COME WITH NO WARRANTY OF ANY KIND, + EITHER EXPRESSED OR IMPLIED. IN NO EVENT WILL THE AUTHORS BE LIABLE + FOR ANY DAMAGES RESULTING FROM THE USE OF THIS SOFTWARE. + +The encryption code is a direct transcription of the algorithm from +Roger Schlafly, described by Phil Katz in the file appnote.txt. This +file is distributed with the PKZIP program (even in the version without +encryption capabilities). Note that the encryption will probably resist +attacks by amateurs if the password is well chosen and long enough (at +least 8 characters) but it will probably not resist attacks by experts. +Paul Kocher has made available information concerning a known-plaintext +attack for the PKWARE encryption scheme; see http://www.cryptography.com/ +for details.) Short passwords consisting of lowercase letters only can be +recovered in a few hours on any workstation. But for casual cryptography +designed to keep your mother from reading your mail, it's OK. + +For more serious encryption, check into PGP (Pretty Good Privacy), a +public-key-based encryption system available from various Internet sites. +PGP has Zip and UnZip built into it. The most recent version at the time +this was originally written was 6.5, although older versions were still +widespread. At the time of this writing there are now GPG, PGP Universal +2.0, and various others based on OpenPGP. + +We are looking at adding AES strong encryption to future versions of Zip and +UnZip. + +Zip 2.3x and UnZip 5.5x and later are compatible with PKZIP 2.04g. (Thanks +to Phil Katz for accepting our suggested minor changes to the zipfile format.) + +IMPORTANT NOTE: + + Zip archives produced by Zip 2.0 or later must not be *updated* by + Zip 1.1 or PKZIP 1.10 or PKZIP 1.93a, if they contain encrypted members + or if they have been produced in a pipe or on a non-seekable device. + The old versions of Zip or PKZIP would destroy the zip structure. The + old versions can list the contents of the zipfile but cannot extract + it anyway (because of the new compression algorithm). If you do not + use encryption and compress regular disk files, you need not worry about + this problem. + + +Contents that were distributed and now are part of the main source files: + + file what it is + ---- ---------- + README.CR this file + LICENSE Info-ZIP license (terms of reuse and redistribution) + USexport.msg export notice sent to US Bureau of Export Administration + WHERE where Zip/UnZip/WiZ and related utilities can be found + crypt.c code for encryption and decryption + crypt.h code for encryption and decryption + file_id.diz description file for some BBSes + +Most all of the files are in Unix (LF only) format. On MSDOS systems, you +can use the -a option of UnZip to convert the source files to CRLF +format. This is only necessary if you wish to edit the files -- they +will compile as is with Microsoft C and Turbo/Borland C++ 1.0 or +later. However, you will have to convert the files (using "unzip -a") +to the CRLF format to compile with the older Turbo C 1.0 or 2.0. You +should be able to find Zip and UnZip in the same place you found this +(see ftp://ftp.info-zip.org/pub/infozip/Info-ZIP.html or the file +"WHERE" for details). + +Current releases all have encryption built in. To update previous versions +using the zcrypt sources: + + (1) Get the main sources (e.g., Zip 2.3) and unpack into a working + directory, as usual. + + (2) Overwrite the dummy crypt.c and crypt.h from the main sources with + the versions from this package. If you want to overwrite directly + out of the zcrypt29 archive, do not use UnZip's freshen/updating + option; the dummy files may be newer than the real sources in + zcrypt29. ("unzip -o zcrypt29 -d /your/working/dir" will do the + Right Thing in most cases, although it may overwrite a newer WHERE + file under some circumstances.) + + (3) Read the main INSTALL document and compile normally! No makefile + changes are necessary on account of the zcrypt sources. You can + check that the version you just compiled has encryption or decryption + support enabled by typing "zip -v" or "unzip -v" and verifying that + the last "special compilation option" says encryption or decryption + is included. + +Encryption enables new "-e" and "-P password" options in Zip, and a new +"-P password" option in UnZip--see the normal Zip and UnZip documentation +for details. (Note that passing a plaintext password on the command line +is potentially much more insecure than being prompted for it interactively, +which is the default for UnZip and for Zip with "-e". Also note that the +interactive method allows UnZip to deal with archives that use different +passwords for different files.) diff --git a/TODO b/TODO new file mode 100644 index 0000000..8d51732 --- /dev/null +++ b/TODO @@ -0,0 +1,142 @@ +Todo list (last updated 12 June 2008). + +Features for next official version: + +- Extended attributes for Windows, Linux, and Mac OS X. +- Win32 ACL rewrite to use backup api to create new and more useful extra + field (need unzip support) (Kai). +- Allow -d@ to read in a list of names to delete (11/17/2005). +- AES encryption (3/19/05). + +Features that may make the next release: + +- Allow reading in list of files using @filename. +- When -R, -x, or -i pattern ends in a directory add / to the end + (11/5/2004 Nehal). +- Decide if -R, -i and -x should use external rather than internal patterns. + Also, change pattern matching to not do ex2in() and then in2ex() if + appropriate. (12/26/2005 SMS) +- Though Unicode paths have been implemented and tested, Unicode comments + are not yet supported (except for comments on UTF-8 native systems which + are supported). +- Verbose mode -v may still need work. + +- Add C# example for Zip 3.0 (need to be converted to new DLLs) - original + C# example added with note. +- Path Prefix maybe, so entries added to an archive can have a directory + path string prepended to each path so can zip multiple drives and avoid + name conflicts (4/17/2006). +- UNC paths like \\server\path (4/26/2005). +- Support for other languages maybe. + +- Add About page option similar to -h2 and -v but lists Info-ZIP + information (could be -sa) (4/29/2006). +- Update utilities ZipSplit, ZipNote, and ZipCloak to handle split archives. +- Update ziperr and finish if needed. +- Review memory allocation and fill in memory leaks if any. +- Enhance -FF to fix common problems such as archives ftp in text mode + and fixing checksums so entries can be extracted if that makes + sense (6/17/2007). +- Add \ to / conversion in zipsplit to fix problem in + 1/29/2004 email. +- Encryption bug with small stored file (12/27/2005) (fixed?). + +- When updating large archives with few entries being + updated maybe display something in large periods of + quiet (1/23/2006). +- Windows OEM comments (5/17/2006). +- Example of using MVS zip and unzip (3/30/2004) (Need one). +- UTF-8 comments need to be implemented (6/17/2007) +- Maybe convert ../ in archive (5/20/2006). +- Per so many buffers dll callback (12/23/2005 Ale). +- Allow rename stdin "-" to something else (12/27/2005 gregor). +- Check for possible buffer overrun weaknesses while reading zip files. +- Do Active Template Library (ATL) (4/27/2005). +- Flush Win16 support - to be determined (Mike). +- Way to convert file names on input, converting foo.c to dir/foo_bar.c + for instance (4/8/2004, 3/12/2004). +- French WiZ (not a Zip thing actually but dependent on zip and unzip). +- Then there is that wierd ^D being converted to \000 error reported + in 6/21/2003 email when Zip is outputted into a pipe on Windows ports. + +Old list: + +Main features still missing for next official version (last updated 2/11/2001): + +- what about the binary/text detection ? (seems done) +- -b and -t options in help screen (covered in -h2) +- findfirst/findnext and after that LSSTAT (performance!!) +- use IS_EXEC from djgpp stat.h +- use install in unix/Makefile instead of mkdir -p, look at install sh script. +- #elif for those ports that can handle it. +- what about zopen vs. fopen ? +- Add zcreate or zfcreate for win32. +- Assembler stuff in match.S (subexpressions) +- zipping huge files (> 2G, unsigned 32bit) (done) +- Testsuite for zip and unzip (John D. Mitchell) +- make a version.c or version.h that includes all the compiler names +- run utils with dmalloc(). +- what to do with zip -F and zip -FF (readzipfile2()) ? (done?) +- profiling of the code +- multi disk zip files (could be done) +- zipfile modification tool (Greg) +- Implement -- option (Thomas Klauser, wiz@danbala.tuwien.ac.at) (could be done) +- don't add files with "Archive bit" or add files with "Archive bit" + (uwe.becher@metronet.de) (could be done with -AS and -AC) +- 32 bit file attributes +- generate output without having to seek at all (this seems to be stream output) +- remove contractions from zip error messages, make them clearer (Steve) +- display "[text]" for ascii files when not quiet (no -q) (Timo Salmi) +- does zipnote accept names with version number? +- for a WORM, zip should create temp file only when updating; new archives + should be created directly. +- APPNOTE.TXT specifies "4) The entries in the central directory may + not necessarily be in the same order that files appear in the zipfile" + but readzipfile() relies on same order. (new read does not, and now + the read for -FF searches for central directory matches rather than + rely on the order) +- on Mac, MPW C 3.3.1 requires #if (a || b) ["#if a || b" taken as "#if a"] +- on Unix, let -S be "include non-regular files without reading from them" + (as pkzip on Unix). This requires unzip support. +- zip -l should do ebcdic->ascii translation on CMS and MVS +- zip as subroutine (zdig/241) (some work done on this) +- accept k and M in zipsplit +- store / (part of file name) as ! in OS/2 (problem only with -E ?) +- in addition to -l (LF to CR LF) and -ll (CR LF to LF) add -lc + (LF to CR LF but CR LF remains unchanged) + +Known bugs: + +- On VMS, zip fails reading some files with "byte record too large for + user's buffer". You must use the "-V" option for such files. + (many changes to VMS so may be fixed) + +- on MSDOS, zip386.exe does not like "zip -bc: foo ..." + +- on MSDOS, zip386.exe is sometimes much slower than zip.exe. This is + probably a problem with DJGPP (to be investigated). + +- on NT with C shell, zip should not do file name expansion again. + +- zip zipfile ... ignores existing zipfile if name does not have an extension + (except for the -A option, generally used on self-extracting files). + (archives should probably have extensions. Things like archive.jar work) + +- For an sfx file without extension, "zip -A sfx" works but "zip sfx -A" + doesn't. (because options were required first, but now both OK) + +- When storing files in a zipfile (-0), zip marks all of them as binary. + +- On VMS, some indexed files are not restored correctly after zip -V and unzip. + (This is now known to be a problem of UnZip. The workaround for Zip 2.2 + and newer is to use PK-style VMS extra fields; this is now the default. + NOTE that UnZip 5.32 has been fixed [971019]!) (many VMS changes so + this may be fixed) + +- zip and unzip should use the same pattern matching rules, particularly + on MSDOS and OS/2. On OS/2, "zip foo *.*" should also match files + without extension. + Partially DONE (OS/2 "*.*" matches "*".) + +- there should be a way to avoid updating archive members (only addition + of new files allowed) diff --git a/USexport.msg b/USexport.msg new file mode 100644 index 0000000..068aa9f --- /dev/null +++ b/USexport.msg @@ -0,0 +1,75 @@ +From roelofs (at) sonic.net Tue Jun 17 08:26:55 2003 +Date: Tue, 17 Jun 2003 08:26:50 -0700 +Message-Id: <200306171526.h5HFQoaw014091 (at) bolt.sonic.net> +From: Greg Roelofs +Reply-To: Greg Roelofs +To: crypt (at) bis.doc.gov, enc (at) ncsc.mil, web_site (at) bis.doc.gov +Subject: TSU NOTIFICATION - Encryption (Info-ZIP zcrypt.zip) +Cc: newt (at) pobox.com, zip-bugs (at) lists.wku.edu + + + SUBMISSION TYPE: TSU + SUBMITTED BY: Greg Roelofs + SUBMITTED FOR: the Info-ZIP group (an informal, Internet-based + collection of software developers with the contact + address given in next item) + POINT OF CONTACT: Zip-Bugs (at) lists.wku.edu + PHONE and/or FAX: n/a + MANUFACTURER: n/a + PRODUCT NAME/MODEL #: zcrypt + ECCN: 5D002 + + NOTIFICATION: + + ftp://ftp.info-zip.org/pub/infozip/src/zcrypt.zip + + +FURTHER COMMENTS: + +(1) This notice is being sent in order to ensure that we may legally + take advantage of the 6 June 2002 amendment to 740.13 regarding + "corresponding object code." The encryption code in question is + unchanged since our original notification of 9 April 2000, appended + below and also reproduced within the above zcrypt.zip archive. + (Indeed, there has been no change to the core encryption/decryption + code in well over five years.) + +(2) The (larger) source archives for Zip, UnZip, MacZip, WiZ, and + potentially other packages, currently available in the same ftp + directory given above, also contain (or may contain) copies of + the same zcrypt source code. + +(3) ftp.info-zip.org currently points to a site in Germany, so techni- + cally it is not involved in "US export" in any direct way. However, + we encourage other sites to "mirror" our software, and some of these + mirror sites may be US-based (and therefore involved in reexport of + the code in question). In addition, some Info-ZIP members reside in + the US, and www.info-zip.org currently points to a site in Kentucky. + + +ORIGINAL NOTIFICATION: + +From roelofs (at) sonic.net Sun Apr 9 15:11:45 2000 +Date: Sun, 9 Apr 2000 15:11:27 -0700 +Message-Id: <200004092211.PAA20023 (at) sonic.net> +From: Greg Roelofs +To: crypt (at) bxa.doc.gov +Subject: notice of export of unrestricted encryption source code +Cc: newt (at) pobox.com, zip-bugs (at) lists.wku.edu + +The Info-ZIP group, an informal, Internet-based collection of software +developers with contact address Zip-Bugs (at) lists.wku.edu, hereby notifies +the US Bureau of Export Administration (BXA) of the posting of freely +available encryption source code on the Internet under License Exception +TSU, to commence later today at this location: + + ftp://ftp.info-zip.org/pub/infozip/src/zcrypt.zip + +This notification is in accordance with section 740.13(e) of the amended +Export Administration Regulations, as published in the 14 January 2000 +issue of the Federal Register. + +-- +Greg Roelofs newt (at) pobox.com http://pobox.com/~newt/ +Newtware, PNG Group, Info-ZIP, Philips Research, ... + diff --git a/WHATSNEW b/WHATSNEW new file mode 100644 index 0000000..9e8d52b --- /dev/null +++ b/WHATSNEW @@ -0,0 +1,333 @@ +What's New + +Last updated 1 July 2008 + +This file is the full list of new features and major changes for Zip 3.0 +by beta release. See the announcement file zip30.ann for a quick summary +of all features and changes in Zip 3.0. Also see the file README for +release information, INSTALL for installation procedures, and the manual +pages zip.txt, zipsplit.txt, zipcloak.txt, and zipnote.txt for how to use +the new features. The file CHANGES has all the day-to-day changes made +during development. + + +Below are some of the more significant items on the list for Zip 3.1 +(see ToDo for a more complete list): + +- AES encryption. +- Extended attributes for Windows, Linux, and Mac OS X. +- Support -d@ for deleting list of files. +- Decide if -R, -i and -x should use external rather than internal patterns. +- Though Unicode paths have been implemented and tested, Unicode comments + are not yet supported (except for comments on UTF-8 native systems which + are supported). +- Verbose mode -v may still need work. +- When pattern is directory add end / automatically. +- Add C# example for Zip 3.0 (need to be converted to new DLLs) - original + C# example added with note. +- Path Prefix maybe, so entries added to an archive can have a directory + path string prepended to each path. +- UNC path support maybe. +- Support for other languages maybe. +- Send in your suggestions. +- ... + + +MAJOR CHANGES BY BETA VERSION +----------------------------- + +New things in Zip 3.0 since Zip 3.0h: + +- Unicode fixes. +- Test and fix various ports as needed. +- Update Win32 resource to support more Windows ports. +- Add djgpp 2.x makefile that includes bzip2. +- Add Win32 version resource to Win32 executable. +- Bug fixes. +- Documentation updates. +- Package for release. + + +New things in Zip 3.0h + +- Allow -@ and -x to work together. +- Unicode code cleanup. +- Allow forcing use of UTF-8 storage in standard path and comment. +- Update symbolic link checks. +- Add support for storing 32-bit UIDs/GIDs using new extra field. + Backward compatible support for the old 16-bit UID/GID extra field + remains if Zip is compiled on an OS that has 16-bit UID/GID + storage. +- Update VMS notes. +- Directory scan using -AS (include only files with Windows archive + bit set) now ignores archive bit on directories to include all files + with archive bit set in all directories. Also, to avoid empty + directories being created, -AS now does not store directory + entries. +- Add Unix IBM support. +- Change -W to -ws to free -W for later use. +- Fix large file support for MinGW. +- Fix large file support for bzip2. +- Fix compile error in ZipCloak when UNICODE_SUPPORT is not enabled. +- Fix Unicode bug in ZipCloak involving Unicode paths. +- Long Unicode escapes changed from #Lxxxxxxxx to #Lxxxxxx to shorten + paths with escaped Unicode. +- Bug fixes. + + +New things in Zip 3.0g + +- Add split support to VB project for Zip64. +- Disable reading of Unix FIFOs unless new -FI option used to avoid an + archiving operation stopping when it hits an active unfed FIFO. +- The "[list]" wildcard expression (regular expression matching of any + character or range of characters in list) is now disabled on DOS and + Windows as it has caused confusion when filenames have [ and ] in + them. The new -RE option reenables it. +- Add negation to many display options such as -dc and -db. +- Allow -FF to read and fix archives having local entries that appear + after central directory entries. +- Bug fixes. + + +New things in Zip 3.0f + +- bzip2 - The bzip2 compression method looks supported for at least + Windows, Unix, and VMS using the bzip2 library. A new option, -Z cm, + selects the compression method. + +- Split archives - Can now use -s to create a split archive. The + default is to update split files as the archive is being written, + which requires all splits to remain open until the archive is done. + This should be no problem when writing the archive to a hard drive, + for example, and this approach creates archives that should be + supported by all unzips that support splits. Adding the -sp option + enables split pause mode that instead writes splits that do not + need updating and pauses Zip after each split. This allows splits + to be written directly to removable media, however -sp archives + may not be as universally compatible. + +- Unicode support - Zip now stores Unicode paths that should be more + portable across character sets and languages. The unzip must have + Unicode support enabled or the Unicode paths are ignored. If + reading an archive with Unicode paths, unsupported characters are + replaced by #Uxxxx and #Lxxxxxxxx escapes in the file name. Option + -UN controls how Unicode is handled. Also, on systems where the + current character set is UTF-8, preliminary support for the new + General Purpose Bit Flag, bit 11, UTF-8 flag, that indicates UTF-8 + is stored in the path and comment fields is implemented for paths. +- Unicode on Win32 - On WIN32 systems that support the wide character + calls (mainly NT and later systems using NTFS), when UNICODE SUPPORT + is enabled Zip will now do directory scans using Unicode and convert + the Unicode paths to the local character set for storage in the standard + path field and store UTF-8 in the Unicode extra field. This allows + directory scans to complete successfully regardless of the character + set the path is in. On Win9x systems wide character scans are not + generally supported and Zip automatically uses a local character scan + instead. + +- Keep extra fields option - The default operation has been, and continues + to be, to read then strip old extra fields when reading entries from an + existing archive and then recreate the extra fields that Zip knows about. + Extra fields specific to each operating system get added by default also. + The new option -X- (negated -X) keeps any old extra fields, copying + them to the updated archive unchanged (unless Zip has updated them). + The unnegated -X still strips most all extra fields except Zip64, + Unicode, and UT time. + +- License - minor updates to the license. + +- Windows OEM - When compiled with WIN32_OEM (the default for WIN32), + Zip on WIN32 now stores OEM paths, which should be more compatible + with other zips and should fix some character set problems. +- Windows Archive Bit support - On Windows can now use new -AS + (include if archive bit set) option to select files with the DOS + archive bit set and use new -AC (clear archive bits) option to clear + the archive bits on files after the archive has been created. + But -DF is probably better. + +- Difference mode - A new option -DF (--dif) creates an output archive + that includes only files changed or new since the input archive was + created. Can use to create incremental backups. +- File Sync - The new option -FS enables File Sync, a new mode that + synchronizes the entries in an archive with the files on the file + system, adding updating, and deleting entries as needed. This + should create the same results as creating a new archive, but + since existing entries are copied, may be much faster. + +- Copy Mode - A new --out option allows creating a new archive with a + different name than the input archive, leaving the input archive + unchanged. This allows updating split archives. It also allows + for a new copy mode to select entries in one archive and copy them + directly to a new archive. +- Empty archives - Now an empty archive is created when -i or -i@ is used + and the file patterns given do not match anything. This has been + requested to support scripts. + +- Global dots - A new -dg option now displays progress dots as -dd does, + but instead of displaying them for each file, the dots track the total + bytes read for the archive. The -dg option also works when -q is used + to disable most output, which allows for something like zip -qdgds 100m + to be used to not display specific files but display a dot every 100 MB + as a global status. +- Date range - Can now use -t and -tt to set a date range +- Fix options - Option -F redone and can recover files from an archive + with a mostly complete central directory more reliably, but no longer + can handle truncated archives. Option -FF redone and now can salvage + files from slightly more damaged archives, including truncated archives. + In some ways -F is less powerful but more stable than it was and -FF will + be needed where -F in Zip 2.32 was enough. One big change is -F and -FF + both now support split archives. +- Console writing - Updates to how messages are written to the console have + been made including more consistent handling of line breaks. +- Show Files options - Option -sf lists the files that would be operated + on. This option can be used alone to list the files in an archive. + Also see options -su and -sU for showing Unicode paths. +- UnZip Check - Now check that UnZip 6.00 or later is being used for + unzip if testing a Zip64 archive. A new option -TT can be used to set + the unzip to use with the -T check. Currently UnZip does not support + split archives so split archives can't be tested by UnZip. +- Streaming - Directories are now handled better when streaming. +- Case matching - Normally all matching against archive entries is case + sensitive, so *.BAR will not match or find foo.bar in an archive + when deleting, copying, or freshening entries (deleting and copying + only on VMS). New option -ic (--ignore-case) enables case insensitive + matching. Currently -ic is only implemented on WIN32 and VMS. + +- Delete date bug fixed - Bug when using -d to delete files while + using -t or -tt to select the files based on date is fixed +- Large file encryption bug fixed - Fix for bug that very rarely + results in bad data being stored when deflating and encrypting + uncompressable data and resulting in CRC errors when extracting, + but the chance of error increases with file size (thanks to + WinZip for finding this bug). See CHANGES for details. + + +New things in Zip 3.0e + +- Bugs described in Debian patches 004 (unix configure script update) and + 005 (large path bug) fixed +- Various fixes +- Add optional running stats and also end stats if not all files could + be read +- Options -l and -ll now do quick binary check on first buffer and skip + formatting if first buffer has binary - still check at end to note + if formatting was done on file that was later determined to be binary, + but now potential file corruption is generally avoided +- Main binary check now uses new algorithm that should also treat UTF-8 and + other similar encodings as text, allowing proper line end translation + for UTF-8 files +- When output is not updatable by seeking back and Zip64 is enabled, output + is forced to Zip64 to avoid possible later need for Zip64 when not enabled +- More work on splits, but still not usable +- Fixes for djgpp +- Add log file capability to save all errors and optionally messages +- Add code to test for a Zip64 archive when compiled without Zip64 support +- New VC6 projects for Win32 and WinDLL +- Updates to extended help +- Changes to force-zip64 option +- ZE_BIG error now given also for files too big to read or write +- Fix file delete bug +- Update license +- Update export documentation +- Add VMS extended filename support +- Add directory traversal improvements, some for Win32 ports and some for + all ports, that can result in a 10 times increase in speed in some cases + + +New things in Zip 3.0d + +- Some large file crypt fixes +- Some updates to support WiZ +- On VMS, changed -V (/VMS) processing to truncate file at EOF, allowing + greater compatability with non-VMS systems. New -VV (/VMS=ALL) option + saves all allocated blocks in a file. (Previously, -V did neither.) +- On VMS, pushed 2GB file size limit with -V out to 4GB +- On VMS (recent, non-VAX), with SET PROCESS /PARSE = EXTEND, + command-line case is preserved. This obviates quoting upper-case + options, like -V, when enabled +- On VMS, fixed problems with mixed-case directory names. Also changed + to keep ODS5 extended file name escape characters ("^") out of the + archived names in simple cases +- Changes to the display dots +- Option -W should now force wildcard matching to not cross directory + separators. For example, a/b*r/d will match a/bar/d but not a/ba/r/d +- Option -nw should turn off all wildcard matching so foo[bar] is matched + literally and [bar] is not considered a regular expression +- Atheos port +- Debugging of Unix and VMS large file ports. Most features may work now + on these ports for large files. Still need to fix 2 GB to 4 GB when not + compiled with large file support +- On VMS, added an open callback function which (where supported) senses + the process RMS_DEFAULT values for file extend quantity (deq) + multi-block count (mbc), and multi-buffer count (mbf), and sets the + FAB/RAB parameters accordingly. The default deq is now much larger + than before (16384 blocks, was none), and the default mbc is now 127 + (up from 64), speeding creation of a large archive file. The "-v" + option shows some of the activity. On old VMS versions, RMS_DEFAULT + sensing (GETJPI) fails (silently, without "-v"), and no changes will + be made. Even there, (DCL) SET RMS /EXTEND = can help + performance. RMS_DEFAULT values override built-in default values. + + +New things in Zip 3.0c + +- Converted to using 64-bit file environment instead of transitional functions + like fseeko64 for ports that support it +- Added "--" argument to read all following arguments as paths +- Second help page added +- Binary detection adjusted from 20% binary is binary to 2% +- When -R and -i used together now -i has precedence over -R +- Archive names with spaces can now be tested on MSDOS and Win32 + + +New things in Zip 3.0b + +- Fixed ifdefs so can test base code by compiling with NO_LARGE_FILE_SUPPORT, then + compiling with NO_ZIP64_SUPPORT to test 64-bit file calls (if port enables) but + otherwise use base code, and compiling normally to enable Zip64 code +- Unix Zip64 fixes - should now be able to create and read large files +- WinDLL changes to support Zip64. Zip 3.0 dll named Zip32z64.dll +- New VB example to show use of Zip32z64.dll +- New options -sc (show final command line and exit) and -sd (show each + step zip is doing, a little different than verbose which is still there) added + to help debug but both or at least -sd might go away in the release +- Some minor posted bugs fixed (see Changes) + + +New things in Zip 3.0a + +- Initial Zip64 support allowing large files and large numbers of files +- New command line processor +- Other changes, see file Changes + + +Note: Zip 2.4 was never released. That code was the start of the Zip 3.0 +effort above. + + +New things in Zip 2.3 + +- IBM OS/390 port (Unix like, but EBCDIC) by Paul von Behren +- Apple Macintosh (MACOS) port by Dirk Haase +- Theos port by Jean-Michel Dubois +- Multibyte characterset support by Yoshioka Tsuneo +- Support for ISO 8601 date format with -t and -tt options +- Info-ZIP license + + +New things in Zip 2.2 + +- BEOS port by Chris Herborth +- QDOS port by Jonathan Hudson +- TANDEM port by Dave Smith +- WINDLL port (16-bit Win 3.x and 32-bit WinNT/Win95) by Mike White +- SYSV packages support by John Bush +- zip -P SeCrEt encrypts entries in the zip file with password SeCrEt + (WARNING: THIS IS INSECURE, use at your own risk) +- zip -R recurses into subdirectories of current dir like "PKZIP -rP" +- zip -x@exclude.lst excludes files specified in the file exclude.lst +- zip -i@include.lst includes files specified in the file include.lst +- zip -@ only handles one filename per line, but supports whitespace in names +- zip -t mmddyyyy, 4 digit year number for uniqueness of years beyond 2000 +- zip -tt mmddyyyy only includes files before a specified date diff --git a/WHERE b/WHERE new file mode 100644 index 0000000..94a0d55 --- /dev/null +++ b/WHERE @@ -0,0 +1,261 @@ +__________________________________________________________________________ + + This is the Info-ZIP file ``WHERE,'' last updated on 1 March 2005. +__________________________________________________________________________ + + This file is out of date. We plan to update the structure of the ftp + site shortly and should be updating this file as soon as that's done. + + The latest version of this file can be found online at: + + ftp://ftp.info-zip.org/pub/infozip/doc/WHERE + + Note that some ftp sites may not yet have the latest versions of Zip + and UnZip when you read this. The latest versions always appear in + ftp://ftp.info-zip.org/pub/infozip/ (and subdirectories thereof) first, + except for encryption binaries, which always appear in + ftp://ftp.icce.rug.nl/infozip/ (and subdirectories) first. + + IF YOU FIND AN ERROR: please let us know! We don't have time to + check each and every site personally (or even collectively), so any + number of the sites listed below may have moved or disappeared en- + tirely. E-mail to Zip-Bugs@lists.wku.edu and we'll update this file. +__________________________________________________________________________ + + +Info-ZIP's home WWW site is listed on Yahoo and is at: + + ftp://ftp.info-zip.org/pub/infozip/Info-ZIP.html (master version) + http://ftp.info-zip.org/pub/infozip/ (master version) + http://www.info-zip.org/ + +Note that the old sites at http://www.cdrom.com/pub/infozip/ and +http://www.freesoftware.com/pub/infozip are PERMANENTLY BROKEN. They +cannot be updated or removed, apparently. + +The Zip and UnZip pages have links to most known mirror sites carrying our +source and/or binary distributions, and they generally are more up-to-date +and have better information than what you are reading: + + ftp://ftp.info-zip.org/pub/infozip/Zip.html + ftp://ftp.info-zip.org/pub/infozip/UnZip.html + +The related zlib package by Info-ZIP's Jean-loup Gailly and Mark Adler is at: + + http://www.zlib.net/ + +Source-code archives for Info-ZIP's portable Zip, UnZip, and related +utilities: + + zip231.zip Zip 2.31 (deflation; includes zipnote/zipsplit/zipcloak) + zip231.tar.Z ditto, compress'd tar format + + zip11.zip Zip 1.1 (shrinking, implosion; compatible w. PKUNZIP 1.1) + zip11.tar.Z ditto, compress'd tar format + + unzip552.zip UnZip 5.52 (all methods[*]; unzip/funzip/unzipsfx/zipgrep) + unzip552.tar.gz ditto, gzip'd tar format + unzip552.tar.Z ditto, compress'd tar format + + unred552.zip UnZip 5.52 add-on, contains copyrighted unreduce support + + zcrypt29.zip encryption support for Zip 2.3[**] + zcrypt10.zip encryption support for Zip 1.1 + + MacZip106src.zip contains all the GUI stuff and the project files to build + the MacZip main-app. To build MacZip successfully, both + the Zip 2.31 and UnZip 5.52 sources are required, too. + + wiz502.zip WiZ 5.02, Windows 9x/NT GUI front-end for Info-ZIP DLLs + wiz502+dlls.zip WiZ 5.02, Windows 9x/NT GUI front-end plus DLL sources + +[*] Unreducing is disabled by default, but is available as add-on. + As of July 2004, Unisys's LZW patent was expired worldwide, and + unshrinking is turned on by default since the release of UnZip 5.52. + See UnZip's INSTALL file for details. + +[**] As of January 2000, US export regulations were amended to allow export + of free encryption source code from the US. As of June 2002, these + regulations were further relaxed to allow export of encryption binaries + associated with free encryption source code. The Zip 2.31, UnZip 5.52 + and Wiz 5.02 archives now include full crypto source code. As of the + Zip 2.31 release, all official binaries include encryption support; the + former "zcr" archives ceased to exist. + (Note that restrictions may still exist in other countries, of course.) + +Executables archives (and related files) for Info-ZIP's software; not all +of these will be immediately available due to lack of access to appropriate +systems on the part of Info-ZIP members. + + zip231x.zip MSDOS executables and docs + zip231x1.zip OS/2 1.x (16-bit) executables and docs + zip231x2.zip OS/2 2/3/4.x (32-bit) executables and docs + zip231xA.zip Amiga executables and docs + zip231xB.zip BeOS executables and docs + zip231xC.zip VM/CMS executable and docs + zip231xK.zip Tandem NSK executables and docs + zip231xM.xmit MVS classic executable + zip231xM-docs.zip MVS classic port, docs only + zip231dN.zip WinNT/Win9x (Intel) DLL, header files, docs + zip231xN.zip WinNT/Win9x (Intel) executables and docs + zip231xN-axp.zip WinNT (Alpha AXP) executables and docs + zip231xN-mip.zip WinNT (MIPS R4000) executables and docs + zip231xN-ppc.zip WinNT (PowerPC) executables and docs + zip231xO.zip IBM OS/390 Open Edition binaries and docs + zip231xQ.zip SMS/QDOS executables and docs + zip231xR.zip Acorn RISC OS executables and docs + zip231xT.zip Atari TOS executables and docs + zip231-vms-axp-obj.zip + VMS (Alpha AXP) object libs, link procedure and docs + zip231-vms-axp-exe.zip + VMS (Alpha AXP) executables for VMS 6.1 or later and docs + zip231-vms-vax-decc-obj.zip + VMS (VAX) object libs (new DEC C), link procedure and docs + zip231-vms-vax-decc-exe.zip + VMS (VAX) executables (DEC C) for VMS 6.1 or later; docs + zip231-vms-vax-vaxc-obj.zip + VMS (VAX) object libs (old VAX C), link procedure and docs + zip231x.hqx Macintosh BinHex'd executables and docs + + unz552x.exe MSDOS self-extracting executable (16-bit unzip, ..., docs) + unz552x3.exe MSDOS self-extracting executable (16-, 32-bit unzip, docs) + unz552x1.exe OS/2 1.x (16-bit) self-extracting executables and docs + unz552x2.exe OS/2 2/3/4.x (32-bit) self-extracting executables and docs + unz552d2.zip OS/2 2/3/4.x (32-bit) DLL, header file, demo exe and docs + unz552xA.ami Amiga self-extracting executables and docs + unz552xA.lha Amiga executables and docs, LHa archive + unz552xB.sfx BeOS self-extracting executables and docs + unz552xB.tar.gz BeOS executables and docs, gzip'd tar archive + unz552xC.mod VM/CMS executable module in "packed" format + unz552xC-docs.zip VM/CMS docs, only + unz552xF.zip FlexOS executable and docs + unz552xK.zip Tandem NSK executable and docs + unz552xM.xmit MVS classic executable + unz552xM-docs.zip MVS classic port, docs only + unz552dN.zip NT4/W2K/XP/2K3/W9x (32-bit Intel) DLL, header files, docs + unz552xN.exe NT/2K/XP/2K3/W9x self-extracting i386 executables and docs + unz552xN-axp.exe WinNT (Alpha AXP) self-extracting executables and docs + unz552xN-mip.exe WinNT (MIPS R4000) self-extracting executables and docs + unz552xN-ppc.exe WinNT (PowerPC) self-extracting executables and docs + unz552xQ.sfx SMS/QDOS self-extracting executables and docs + unz552xO.tar.Z IBM OS/390 Open edition (Unix-like), exes and docs + unz552xR.exe Acorn RISC OS self-extracting executables and docs + unz552xR.spk Acorn RISC OS Spark'd executables and docs + unz552xT.tos Atari TOS self-extracting executables and docs + unz552x-vms-axp-obj.bck VMS backup saveset, + contains UnZip (Alpha) obj libs, link procedure, docs + unz552x-vms-axp-obj.exe VMS (Alpha AXP) SFX archive (statically linked), + contains UnZip (Alpha) obj libs, link procedure, docs + unz552x-vms-axp-exe.exe VMS (Alpha AXP) SFX archive (dynamically linked), + contains UnZip (Alpha AXP, DEC C) executables and docs, + smaller than object archive, but requires VMS 6.1 + unz552x-vms-vax-decc-obj.bck VMS backup saveset, + contains UnZip (new DEC C) obj libs, link procedure, docs + unz552x-vms-vax-decc-obj.exe VMS (VAX) SFX archive (statically linked), + contains UnZip (new DEC C) obj libs, link procedure, docs + unz552x-vms-vax-decc-exe.exe VMS (VAX) SFX archive (dynamically linked), + contains UnZip (new DEC C) executables and docs, + smaller than object archive, but requires VMS 6.1 + unz552x-vms-vax-vaxc-obj.bck VMS backup saveset, + contains UnZip (old VAX C) obj libs, link procedure, docs + unz552x-vms-vax-vaxc-obj.exe VMS (VAX) SFX archive (statically linked), + contains UnZip (old VAX C) obj libs, link procedure, docs + unz552x.hqx Macintosh BinHex'd executables and docs for unzip + (unz552x.tar.{Z,gz} Unix exes/docs for Solaris 2.x, SCO Unix, Linux, etc., + depending on directory/location; generally only provided + in cases where the OS does *not* ship with a bundled C + compiler) + + MacZip106nc.hqx Macintosh combined Zip&UnZip application with GUI, + executables and docs (no encryption) + MacZip106c.hqx Macintosh combined Zip&UnZip application with GUI, + executables and docs (with encryption) + + wiz502xN.exe WiZ 5.02 32-bit (Win9x/NT/2K/XP/2K3) app+docs (self-extr.) + + UnzpHist.zip complete changes-history of UnZip and its precursors + ZipHist.zip complete changes-history of Zip + +ftp/web sites for the US-exportable sources and executables: + + NOTE: Look for the Info-ZIP file names given above (not PKWARE or third- + party stuff) in the following locations. Some sites like to use slightly + different names, such as zip-2.31.tar.gz instead of zip231.tar.Z. + + ftp://ftp.info-zip.org/pub/infozip/ [THE INFO-ZIP HOME SITE] + ftp://sunsite.doc.ic.ac.uk/packages/zip/ [MIRRORS THE INFO-ZIP HOME SITE] + ftp://unix.hensa.ac.uk/mirrors/uunet/pub/archiving/zip/ + + ftp://ftp.cmdl.noaa.gov/aerosol/doc/archiver/{all,dos,os2,mac,vax_alpha}/ + ftp://garbo.uwasa.fi/pc/arcers/ [AND OTHER GARBO MIRRORS] + ftp://garbo.uwasa.fi/unix/arcers/ [AND OTHER GARBO MIRRORS] + ftp://ftp.elf.stuba.sk/pub/pc/pack/ [AND OTHER STUBA MIRRORS] + ftp://ftp-os2.cdrom.com/pub/os2/archiver/ + ftp://ftp-os2.nmsu.edu/os2/archiver/ + ftp://ftp.informatik.tu-muenchen.de/pub/comp/os/os2/archiver/ + ftp://sumex-aim.stanford.edu/info-mac/cmp/ + ftp://ftp.wustl.edu/pub/aminet/util/arc/ [AND OTHER AMINET MIRRORS] + ftp://atari.archive.umich.edu/pub/Archivers/ [AND OTHER UMICH MIRRORS] + http://www.umich.edu/~archive/atari/Archivers/ + ftp://jake.educom.com.au/pub/infozip/acorn/ [Acorn RISC OS] + http://www.sitec.net/maczip/ [MacZip port] + +ftp/web sites for the encryption and decryption sources and/or executables: + + Outside the US: + ftp://ftp.info-zip.org/pub/infozip/ [THE INFO-ZIP HOME SITE] + ftp://ftp.icce.rug.nl/infozip/ [THE INFO-ZIP ENCRYPTION HOME SITE] + ftp://ftp.elf.stuba.sk/pub/pc/pack/ + ftp://garbo.uwasa.fi/pc/arcers/ + ftp://ftp.inria.fr/system/arch-compr/ + ftp://ftp.leo.org/pub/comp/os/os2/leo/archiver/ + (mail server at ftp-mailer@ftp.leo.org) + + ftp://ftp.win.tue.nl/pub/compression/zip/ + ftp://ftp.uni-erlangen.de/pub/pc/msdos/arc-utils/zip/ + + +The primary distribution site for the MacZip port can be found at: + + http://www.sitec.net/maczip/ + +ftp sites for VMS-format Zip and UnZip packages (sources, object files and +executables, no encryption/decryption--see also "Mail servers" section below): + + ftp.spc.edu [192.107.46.27] and ftp.wku.edu: + + [.MACRO32]AAAREADME.TXT + [.MACRO32.SAVESETS]UNZIP.BCK or UNZIP.ZIP (if already have older version) + [.MACRO32.SAVESETS]ZIP.ZIP + +To find other ftp/web sites: + + The "archie" ftp database utility can be used to find an ftp site near + you (although the command-line versions always seem to find old ver- + sions...the `FTPsearch' server at http://ftpsearch.ntnu.no/ftpsearch + --formerly `Archie 95'--is quite up-to-date, however). Or check a stan- + dard WWW search engine like AltaVista (http://www.altavista.digital.com/) + or Yahoo (http://www.yahoo.com/). If you don't know how to use these, + DON'T ASK US--read the web sites' help pages or check the Usenet groups + news.announce.newusers or news.answers or some such, or ask your system + administrator. + +Mail servers: + + To get the encryption sources by e-mail, send the following commands + to ftp-mailer@informatik.tu-muenchen.de: + + get /pub/comp/os/os2/archiver/zcrypt29.zip + quit + + To get the VMS Zip/UnZip package by e-mail, send the following + commands in the body of a mail message to fileserv@wku.edu (the + "HELP" command is also accepted): + + SEND FILESERV_TOOLS + SEND UNZIP + SEND ZIP + + To get Atari executables by e-mail, send a message to + atari@atari.archive.umich.edu for information about the mail server. +__________________________________________________________________________ diff --git a/acorn/GMakefile b/acorn/GMakefile new file mode 100644 index 0000000..01842c4 --- /dev/null +++ b/acorn/GMakefile @@ -0,0 +1,130 @@ +# Makefile for Zip, ZipNote, ZipCloak and ZipSplit + +# add -g to CC to debug +# add -d to BIND to debug +CC = gcc -mlibscl +BIND = $(CC) +AS = $(CC) -c +ASM = AS +SQUEEZE = squeeze -v +E = + +# flags +# CFLAGS flags for C compile +# LFLAGS1 flags after output file spec, before obj file list +# LFLAGS2 flags after obj file list (libraries, etc) +# +LIB = +CFLAGS = -O2 -mthrowback -DASMV +ASMFLAGS = -throwback -objasm -upper +LFLAGS1 = +LFLAGS2 = $(LIB) + +# Uncomment the following line to enable support for Unix +# Extra Field (Timezone) +#CFLAGS = $(CFLAGS) -DUSE_EF_UT_TIME + +# object file lists +OBJZ = o.zip o.zipfile o.zipup o.fileio o.util o.globals o.crc32 \ + o.crypt o.ttyio o.riscos o.acornzip o.swiven + +OBJI = o.deflate o.trees +OBJA = o.match o.sendbits +OBJU = o.zipfile_ o.fileio_ o.util_ o.globals o.riscos o.acornzip_ o.swiven +OBJN = o.zipnote $(OBJU) +OBJC = o.zipcloak $(OBJU) o.crc32_ o.crypt_ o.ttyio +OBJS = o.zipsplit $(OBJU) + +ZIP_H = h.zip h.ziperr h.tailor acorn.h.osdep acorn.h.riscos acorn.h.swiven + +all: zip zipnote zipsplit zipcloak + +install: %.zip %.zipnote %.zipsplit %.zipcloak %.acorn.zipsfx \ + zip zipnote zipsplit zipcloak acorn.zipsfx + $(SQUEEZE) zip %.zip + $(SQUEEZE) zipnote %.zipnote + $(SQUEEZE) zipsplit %.zipsplit + $(SQUEEZE) zipcloak %.zipcloak + copy acorn.zipsfx %.zipsfx ~CVF + +# rules for zip, zipnote, zipcloak and zipsplit + +o.api: c.api + $(CC) $(CFLAGS) -c c.api -o o.api +o.crc32: c.crc32 $(ZIP_H) h.crc32 + $(CC) $(CFLAGS) -c c.crc32 -o o.crc32 +o.crypt: c.crypt $(ZIP_H) h.crypt h.crc32 h.ttyio + $(CC) $(CFLAGS) -c c.crypt -o o.crypt +o.deflate: c.deflate $(ZIP_H) + $(CC) $(CFLAGS) -c c.deflate -o o.deflate +o.fileio: c.fileio $(ZIP_H) h.crc32 + $(CC) $(CFLAGS) -c c.fileio -o o.fileio +o.globals: c.globals $(ZIP_H) + $(CC) $(CFLAGS) -c c.globals -o o.globals +o.mktime: c.mktime + $(CC) $(CFLAGS) -c c.mktime -o o.mktime +o.trees: c.trees $(ZIP_H) + $(CC) $(CFLAGS) -c c.trees -o o.trees +o.ttyio: c.ttyio $(ZIP_H) h.crypt + $(CC) $(CFLAGS) -c c.ttyio -o o.ttyio +o.util: c.util $(ZIP_H) + $(CC) $(CFLAGS) -c c.util -o o.util +o.zip: c.zip $(ZIP_H) h.crc32 h.crypt h.revision h.ttyio + $(CC) $(CFLAGS) -c c.zip -o o.zip +o.zipcloak: c.zipcloak $(ZIP_H) h.crc32 h.crypt h.revision h.ttyio + $(CC) $(CFLAGS) -c c.zipcloak -o o.zipcloak +o.zipfile: c.zipfile $(ZIP_H) h.crc32 + $(CC) $(CFLAGS) -c c.zipfile -o o.zipfile +o.zipnote: c.zipnote $(ZIP_H) h.revision + $(CC) $(CFLAGS) -c c.zipnote -o o.zipnote +o.zipsplit: c.zipsplit $(ZIP_H) h.revision + $(CC) $(CFLAGS) -c c.zipsplit -o o.zipsplit +o.zipup: c.zipup $(ZIP_H) h.crc32 h.crypt h.revision + $(CC) $(CFLAGS) -c c.zipup -o o.zipup + +o.crc32_: c.crc32 $(ZIP_H) h.crc32 + $(CC) $(CFLAGS) -DUTIL -c c.crc32 -o o.crc32_ +o.crypt_: c.crypt $(ZIP_H) h.crypt h.crc32 h.ttyio + $(CC) $(CFLAGS) -DUTIL -c c.crypt -o o.crypt_ +o.util_: c.util $(ZIP_H) + $(CC) $(CFLAGS) -DUTIL -c c.util -o o.util_ +o.fileio_: c.fileio $(ZIP_H) h.crc32 + $(CC) $(CFLAGS) -DUTIL -c c.fileio -o o.fileio_ +o.zipfile_: c.zipfile $(ZIP_H) h.crc32 + $(CC) $(CFLAGS) -DUTIL -c c.zipfile -o o.zipfile_ +o.acornzip_: acorn.c.acornzip $(ZIP_H) + $(CC) $(CFLAGS) -I@ -DUTIL -c acorn.c.acornzip -o o.acornzip_ + +o.riscos: acorn.c.riscos acorn.h.riscos $(ZIP_H) + $(CC) $(CFLAGS) -I@ -c acorn.c.riscos -o o.riscos + +o.acornzip: acorn.c.acornzip $(ZIP_H) + $(CC) $(CFLAGS) -I@ -c acorn.c.acornzip -o o.acornzip + +o.match: acorn.s.match + $(ASM) $(ASMFLAGS) -I@ acorn.s.match -o o.match + +o.sendbits: acorn.s.sendbits + $(ASM) $(ASMFLAGS) -I@ acorn.s.sendbits -o o.sendbits + +o.swiven: acorn.s.swiven + $(ASM) $(ASMFLAGS) -I@ acorn.s.swiven -o o.swiven + +zip: $(OBJZ) $(OBJI) $(OBJA) + $(BIND) -o zip$(E) $(LFLAGS1) $(OBJZ) $(OBJI) $(OBJA) $(LFLAGS2) +zipnote: $(OBJN) + $(BIND) -o zipnote$(E) $(LFLAGS1) $(OBJN) $(LFLAGS2) +zipcloak: $(OBJC) + $(BIND) -o zipcloak$(E) $(LFLAGS1) $(OBJC) $(LFLAGS2) +zipsplit: $(OBJS) + $(BIND) -o zipsplit$(E) $(LFLAGS1) $(OBJS) $(LFLAGS2) + +clean: + remove zip + remove zipcloak + remove zipsplit + remove zipnote + create o.!fake! 0 + wipe o.* ~cf + +# end of Makefile diff --git a/acorn/ReadMe b/acorn/ReadMe new file mode 100644 index 0000000..41c37a5 --- /dev/null +++ b/acorn/ReadMe @@ -0,0 +1,85 @@ +Acorn-specific compile instructions +----------------------------------- + +Use the "RunMe1st" file (it is an Obey file) to convert all the files from +"filename/[chs]" to "[chs].filename" (so that zip could be easily compiled +under RISC OS). It will also set the correct makefile. + +To compile just set the CSD to the main zip directory and run 'amu'. + +Currently only the Acorn C V5 compiler has been tested but probably also +Acorn C V4 and the Acorn Assembler V2 will be able to compile zip. + +The default makefile is configured without the support for the +Extended Timestamp Extra Field. If you wan to enable it you have to +add "-DUSE_EF_UT_TIME" to CFLAGS (see makefile). Without the Extended +Timestamp Field support, zipfiles created by zip are identical to the +zipfiles created by SparkFS. However, the Extended Timestamp Field can +be useful if you are going to unzip your zipfiles on a non-RISC OS machine +since the correct time stamp will be preserved across different timezones. +Note that in this case, both the SparkFS Extra Field and the Extended +Timestamp Extra Field will be used, so the zipfiles will still be fully +compatible with SparkFS and with the RISC OS version of unzip. + +The executables-only distributions will be compiled without the support for +the Extended Timestamp Extra Field. If you need it but you can't compile zip +yourself, you can contact the authors at the Info-ZIP address who will do it +for you. + + +Acorn-specific usage instructions +--------------------------------- + +An extra option ('I') has been added to the Acorn port: if it is specified +zip will not consider Image files (eg. DOS partitions or Spark archives when +SparkFS is loaded) as directories but will store them as single files. This +means that if you have, say, SparkFS loaded, zipping a Spark archive will +result in a zipfile containing a directory (and its content) while using the +'I' option will result in a zipfile containing a Spark archive. Obviously +this second case will also be obtained (without the 'I' option) if SparkFS +isn't loaded. + +When adding files to a zipfile; to maintain FileCore compliance, all +files named "file/ext" will be added to the archive as "file.ext". +This presents no problem if you wish to use unzip to extract them on any +other machine, as the files are correctly named. This also presents no +problem if you use unzip for RISC OS, as the files are converted back to +"file/ext" format. The only problem appears when you use SparkFS to +decompress the files, as a file called "file.ext" will be extracted as +"file_ext", not what it was added as. You must be careful about this. + +Case Specific. Depending on how you type the command, files will be added +exactly as named; in this example: +*zip new/zip newfile +*zip new/zip NewFile +*zip new/zip NEWFILE +will create an archive containing 3 copies of the same Risc OS file 'newfile' +called 'newfile', 'NewFile' and 'NEWFILE'. Please be careful. + +The Acorn port conserves file attributes, including filetype, so if you +zip on an Acorn, and unzip on another Acorn, filetypes will be maintained +precisely as if you used uncompressed files. If you de-archive on another +machine (PC, Mac, Unix etc..), filetypes will be ignored, but the files +will be identical despite this. This feature is fully compatible with +SparkFS, so zipfiles created by zip will be correctly uncompressed (including +filetype, etc.) by SparkFS. + +An additional feature went into this port to cope better with C-code +and extensions. This allows the acorn files "c.foo" to be added to the +archive as "foo/c", eventually appearing in the archive as "foo.c", allowing +for better handling of C or C++ code. Example: +*Set Zip$Exts "dir1:dir2:dir3" +*zip new/zip dir1.file +*zip new/zip dir2.help +*zip new/zip dir3.textfile +Creates a zipfile new/zip, with entries file.dir1, help.dir2, textfile.dir3. +The usual settings for Zip$Exts are "h:o:s:c", allowing C code to be added +to the archive in standard form. + +A final note about the Acorn port regards the use of the 'n' option: this is +used to specify a list of suffixes that will not be compressed (eg. .ZIP, +since it is already a compressed file). Since RISC OS uses filetypes instead +of suffixes, this list of suffixes is actually considered as a list of +filetypes (3 hex digit format). By default, zip doesn't compress filetypes +DDC (Archive, Spark or Zip), D96 (CFS files) and 68E (PackDir). + diff --git a/acorn/ReadMe.GMakefile b/acorn/ReadMe.GMakefile new file mode 100644 index 0000000..8762cdb --- /dev/null +++ b/acorn/ReadMe.GMakefile @@ -0,0 +1,16 @@ +GMakefile is for use with Acorn RISC OS and the forthcoming +post-Acorn RISC OS for the compilation of both the current release and +development versions of zip. + +It is recommended that you use gcc 2.95.4 or higher and you will need a +suitable 'make' utility. Both are available from +. + +You will need the files gcc.zip and cc1.zip for the C compiler with the +documentation available in the gccdoc.zip archive. GNU make can be +found in the utils.zip archive, although most versions of 'make' should be +fine. + +When using gcc, check RunMe1st for two lines which need uncommenting. + + diff --git a/acorn/RunMe1st b/acorn/RunMe1st new file mode 100644 index 0000000..a330adb --- /dev/null +++ b/acorn/RunMe1st @@ -0,0 +1,23 @@ +| This Obey file prepares the zip port for a Desktop C re-compile. +| Run it and it will copy all the needed files into the correct +| place. + +| Set the correct type of 'srcrename' so that the only requirement +| for the user is to set 'RunMe1st' to Obey +SetType .srcrename FF8 + +| Run 'srcrename' on the main zip directory with recursion enabled +/.srcrename -r -e c:h:s:o .^ + +| Create the 'o' directory +CDir .^.o + +| Put the Makefile in its correct place and set the correct filetype +Copy .makefile .^.makefile ~C ~V F + +| Uncomment the following lines if you're using gcc +|| Put the Makefile in its correct place and set the correct filetype +|Copy .GMakefile .^.makefile ~C~VF + +SetType .^.makefile FE1 +SetType .zipsfx Obey diff --git a/acorn/acornzip.c b/acorn/acornzip.c new file mode 100644 index 0000000..40debc0 --- /dev/null +++ b/acorn/acornzip.c @@ -0,0 +1,592 @@ +/* + Copyright (c) 1990-2002 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#include +#include +#include "zip.h" + +#ifndef UTIL + +#define PAD 0 +#define PATH_END '/' + + +local int wild_recurse(char *whole, char *wildtail); +local int uxtime2acornftime(unsigned *pexadr, unsigned *pldadr, time_t ut); + +extern char *label; +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +char *readd(DIR *d) +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e; + + e = readdir(d); + return (e == NULL ? (char *) NULL : e->d_name); +} + +/* What we have here is a mostly-generic routine using opend()/readd() and */ +/* isshexp()/MATCH() to find all the files matching a multi-part filespec */ +/* using the portable pattern syntax. It shouldn't take too much fiddling */ +/* to make it usable for any other platform that has directory hierarchies */ +/* but no shell-level pattern matching. It works for patterns throughout */ +/* the pathname, such as "foo:*.?/source/x*.[ch]". */ + +/* whole is a pathname with wildcards, wildtail points somewhere in the */ +/* middle of it. All wildcards to be expanded must come AFTER wildtail. */ + +local int wild_recurse(whole, wildtail) char *whole; char *wildtail; +{ + DIR *dir; + char *subwild, *name, *newwhole = NULL, *glue = NULL, plug = 0, plug2; + ush newlen, amatch = 0; + struct stat statb; + int disk_not_mounted=0; + int e = ZE_MISS; + + if (!isshexp(wildtail)) { + if (stat(whole,&statb)==0 && (statb.st_mode & S_IREAD)!=0) { + return procname(whole, 0); + } else + return ZE_MISS; /* woops, no wildcards! */ + } + + /* back up thru path components till existing dir found */ + do { + name = wildtail + strlen(wildtail) - 1; + for (;;) + if (name-- <= wildtail || *name == '.') { + subwild = name + 1; + plug2 = *subwild; + *subwild = 0; + break; + } + if (glue) + *glue = plug; + glue = subwild; + plug = plug2; + dir = opendir(whole); + } while (!dir && !disk_not_mounted && subwild > wildtail); + wildtail = subwild; /* skip past non-wild components */ + + if ((subwild = strchr(wildtail + 1, '.')) != NULL) { + /* this "+ 1" dodges the ^^^ hole left by *glue == 0 */ + *(subwild++) = 0; /* wildtail = one component pattern */ + newlen = strlen(whole) + strlen(subwild) + 32; + } else + newlen = strlen(whole) + 31; + if (!dir || !(newwhole = malloc(newlen))) { + if (glue) + *glue = plug; + e = dir ? ZE_MEM : ZE_MISS; + goto ohforgetit; + } + strcpy(newwhole, whole); + newlen = strlen(newwhole); + if (glue) + *glue = plug; /* repair damage to whole */ + if (!isshexp(wildtail)) { + e = ZE_MISS; /* non-wild name not found */ + goto ohforgetit; + } + + while (name = readd(dir)) { + if (MATCH(wildtail, name, 0)) { + strcpy(newwhole + newlen, name); + if (subwild) { + name = newwhole + strlen(newwhole); + *(name++) = '.'; + strcpy(name, subwild); + e = wild_recurse(newwhole, name); + } else + e = procname(newwhole, 0); + newwhole[newlen] = 0; + if (e == ZE_OK) + amatch = 1; + else if (e != ZE_MISS) + break; + } + } + + ohforgetit: + if (dir) closedir(dir); + if (subwild) *--subwild = '.'; + if (newwhole) free(newwhole); + if (e == ZE_MISS && amatch) + e = ZE_OK; + return e; +} + +int wild(p) +char *p; +{ + char *path; + int toret; + + /* special handling of stdin request */ + if (strcmp(p, "-") == 0) /* if compressing stdin */ + return newname(p, 0, 0); + + path=p; + if (strchr(p, ':')==NULL && *p!='@') { + if (!(path=malloc(strlen(p)+3))) { + return ZE_MEM; + } + strcpy(path,"@."); + strcat(path,p); + } + + toret=wild_recurse(path, path); + + if (path!=p) { + free(path); + } + return toret; +} + +int procname(n, caseflag) +char *n; /* name to process */ +int caseflag; /* true to force case-sensitive match */ +/* Process a name or sh expression to operate on (or exclude). Return + an error code in the ZE_ class. */ +{ + char *a; /* path and name for recursion */ + DIR *d; /* directory stream from opendir() */ + char *e; /* pointer to name from readd() */ + int m; /* matched flag */ + char *p; /* path for recursion */ + struct stat s; /* result of stat() */ + struct zlist far *z; /* steps through zfiles list */ + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0, caseflag); + else if (LSSTAT(n, &s)) + { + /* Not a file or directory--search for shell expression in zip file */ + p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */ + m = 1; + for (z = zfiles; z != NULL; z = z->nxt) { + if (MATCH(p, z->iname, caseflag)) + { + z->mark = pcount ? filter(z->zname, caseflag) : 1; + if (verbose) + fprintf(mesg, "zip diagnostic: %scluding %s\n", + z->mark ? "in" : "ex", z->name); + m = 0; + } + } + free((zvoid *)p); + return m ? ZE_MISS : ZE_OK; + } + + /* Live name--use if file, recurse if directory */ + if ((s.st_mode & S_IFDIR) == 0) + { + /* add or remove name of file */ + if ((m = newname(n, 0, caseflag)) != ZE_OK) + return m; + } else { + /* Add trailing / to the directory name */ + if ((p = malloc(strlen(n)+2)) == NULL) + return ZE_MEM; + if (strcmp(n, ".") == 0) { + *p = '\0'; /* avoid "./" prefix and do not create zip entry */ + } else { + strcpy(p, n); + a = p + strlen(p); + if (a[-1] != '.') + strcpy(a, "."); + if (dirnames && (m = newname(p, 1, caseflag)) != ZE_OK) { + free((zvoid *)p); + return m; + } + } + /* recurse into directory */ + if (recurse && (d = opendir(n)) != NULL) + { + while ((e = readd(d)) != NULL) { + if (strcmp(e, ".") && strcmp(e, "..")) + { + if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL) + { + closedir(d); + free((zvoid *)p); + return ZE_MEM; + } + strcat(strcpy(a, p), e); + if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */ + { + if (m == ZE_MISS) + zipwarn("name not matched: ", a); + else + ziperr(m, a); + } + free((zvoid *)a); + } + } + closedir(d); + } + free((zvoid *)p); + } /* (s.st_mode & S_IFDIR) == 0) */ + return ZE_OK; +} + +char *ex2in(x, isdir, pdosflag) +char *x; /* external file name */ +int isdir; /* input: x is a directory */ +int *pdosflag; /* output: force MSDOS file attributes? */ +/* Convert the external file name to a zip file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *n; /* internal file name (malloc'ed) */ + char *t; /* shortened name */ + char *tmp; + int dosflag; + char *lastlastdir=NULL; /* pointer to 2 dirs before... */ + char *lastdir=NULL; /* pointer to last dir... */ + + /* Malloc space for internal name and copy it */ + if ((tmp = malloc(strlen(x) + 1)) == NULL) + return NULL; + strcpy(tmp, x); + + dosflag = dosify; /* default for non-DOS and non-OS/2 */ + + /* Find starting point in name before doing malloc */ + for(t=tmp;*t;t++) { + if (*t=='/') { + *t='.'; + } + else if (*t=='.') { + *t='/'; + lastlastdir=lastdir; + lastdir=t+1; + } + } + + t=strchr(tmp,'$'); /* skip FS name */ + if (t!=NULL) + t+=2; /* skip '.' after '$' */ + else + t=tmp; + if (*t=='@') /* skip @. at the beginning of filenames */ + t+=2; + + /* Make changes, if any, to the copied name (leave original intact) */ + + /* return a pointer to '\0' if the file is a directory with the same + same name as an extension to swap (eg. 'c', 'h', etc.) */ + if (isdir && exts2swap!=NULL) { + if (lastlastdir==NULL) + lastlastdir=t; + if (checkext(lastlastdir)) { + free((void *)tmp); + n=malloc(1); + if (n!=NULL) + *n='\0'; + return n; + } + } + + if (exts2swap!=NULL && lastdir!=NULL) { + if (lastlastdir==NULL) + lastlastdir=t; + if (checkext(lastlastdir)) { + if (swapext(lastlastdir,lastdir-1)) { + free((void *)tmp); + return NULL; + } + } + } + + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) { + free((void *)tmp); + return NULL; + } + strcpy(n, t); + + free((void *)tmp); + + if (dosify) + msname(n); + + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + return n; +} + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + char *t; /* scans name */ + char *lastext=NULL; /* pointer to last extension */ + char *lastdir=NULL; /* pointer to last dir */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + + for(t=x;*t;t++) { + if (*t=='.') { + *t='/'; + lastext=t+1; + } + else if (*t=='/') { + *t='.'; + lastdir=t+1; + } + } + + if (exts2swap!=NULL && (int)lastext>(int)lastdir) { + if (lastdir==NULL) + lastdir=x; + if (checkext(lastext)) { + if (swapext(lastdir,lastext-1)) { + free((void *)x); + return NULL; + } + } + } + + return x; +} + +local int uxtime2acornftime(unsigned *pexadr, unsigned *pldadr, time_t ut) +{ + unsigned timlo; /* 3 lower bytes of acorn file-time plus carry byte */ + unsigned timhi; /* 2 high bytes of acorn file-time */ + + timlo = ((unsigned)ut & 0x00ffffffU) * 100 + 0x00996a00U; + timhi = ((unsigned)ut >> 24); + timhi = timhi * 100 + 0x0000336eU + (timlo >> 24); + if (timhi & 0xffff0000U) + return 1; /* calculation overflow, do not change time */ + + /* insert the five time bytes into loadaddr and execaddr variables */ + *pexadr = (timlo & 0x00ffffffU) | ((timhi & 0x000000ffU) << 24); + *pldadr = (*pldadr & 0xffffff00U) | ((timhi >> 8) & 0x000000ffU); + + return 0; /* subject to future extension to signal overflow */ +} + +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ + time_t m_time; + unsigned int loadaddr, execaddr; + int attr; + + /* Convert DOS time to time_t format in m_time */ + m_time = dos2unixtime(d); + + /* set the file's modification time */ + SWI_OS_File_5(f,NULL,&loadaddr,NULL,NULL,&attr); + + if (uxtime2acornftime(&execaddr, &loadaddr, m_time) != 0) + return; + + SWI_OS_File_1(f,loadaddr,execaddr,attr); +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + /* convert FNMAX to malloc - 11/8/04 EG */ + char *name; + unsigned int len = strlen(f); + + if (f == label) { + if (a != NULL) + *a = label_mode; + if (n != NULL) + *n = -2L; /* convention for a label name */ + if (t != NULL) + t->atime = t->mtime = t->ctime = label_utim; + return label_time; + } + if ((name = malloc(len + 1)) == NULL) { + ZIPERR(ZE_MEM, "filetime"); + } + strcpy(name, f); + if (name[len - 1] == '.') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + + if (strcmp(f, "-") == 0) { + /* forge stat values for stdin since Amiga and RISCOS have no fstat() */ + s.st_mode = (S_IREAD|S_IWRITE|S_IFREG); + s.st_size = -1; + s.st_mtime = time(&s.st_mtime); + } else if (LSSTAT(name, &s) != 0) { + /* Accept about any file kind including directories + * (stored with trailing / with -r option) + */ + free(name); + return 0; + } + free(name); + + if (a != NULL) { + *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE); + if ((s.st_mode & S_IFDIR) != 0) { + *a |= MSDOS_DIR_ATTR; + } + } + if (n != NULL) + *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_ctime; + } + + return unix2dostime((time_t *) &s.st_mtime); +} + +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; +{ +#ifdef USE_EF_UT_TIME + char *eb_ptr; +#endif /* USE_EF_UT_TIME */ + char *name; + extra_block *block; + +#define EB_SPARK_LEN 20 +#define EB_SPARK_SIZE (EB_HEADSIZE+EB_SPARK_LEN) +#ifdef USE_EF_UT_TIME +# ifdef IZ_CHECK_TZ +# define EB_UTTIME_SIZE (zp_tz_is_valid ? EB_HEADSIZE+EB_UT_LEN(1) : 0) +# else +# define EB_UTTIME_SIZE (EB_HEADSIZE+EB_UT_LEN(1)) +# endif +#else +# define EB_UTTIME_SIZE 0 +#endif +#define EF_SPARK_TOTALSIZE (EB_SPARK_SIZE + EB_UTTIME_SIZE) + + if ((name=(char *)malloc(strlen(z->name)+1))==NULL) { + fprintf(stderr," set_extra_field: not enough memory for directory name\n"); + return ZE_MEM; + } + + strcpy(name,z->name); + + if (name[strlen(name)-1]=='.') { /* remove the last '.' in directory names */ + name[strlen(name)-1]=0; + } + + z->extra=(char *)malloc(EF_SPARK_TOTALSIZE); + if (z->extra==NULL) { + fprintf(stderr," set_extra_field: not enough memory\n"); + free(name); + return ZE_MEM; + } + z->cextra = z->extra; + z->cext = z->ext = EF_SPARK_TOTALSIZE; + + block=(extra_block *)z->extra; + block->ID=SPARKID; + block->size=EB_SPARK_LEN; + block->ID_2=SPARKID_2; + block->zero=0; + + if (SWI_OS_File_5(name,NULL,&block->loadaddr,&block->execaddr, + NULL,&block->attr) != NULL) { + fprintf(stderr," OS error while set_extra_field of %s\n",name); + } + + free(name); + +#ifdef USE_EF_UT_TIME +# ifdef IZ_CHECK_TZ + if (zp_tz_is_valid) { +# endif + eb_ptr = z->extra + EB_SPARK_SIZE; + + eb_ptr[0] = 'U'; + eb_ptr[1] = 'T'; + eb_ptr[2] = EB_UT_LEN(1); /* length of data part of e.f. */ + eb_ptr[3] = 0; + eb_ptr[4] = EB_UT_FL_MTIME; + eb_ptr[5] = (char)(z_utim->mtime); + eb_ptr[6] = (char)(z_utim->mtime >> 8); + eb_ptr[7] = (char)(z_utim->mtime >> 16); + eb_ptr[8] = (char)(z_utim->mtime >> 24); +# ifdef IZ_CHECK_TZ + } +# endif +#endif /* USE_EF_UT_TIME */ + + return ZE_OK; +} + +#endif /* !UTIL */ + + +/******************************/ +/* Function version_local() */ +/******************************/ + +void version_local() +{ + static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n"; + + printf(CompiledWith, +#ifdef __GNUC__ + "gcc ", __VERSION__, +#else +# ifdef __CC_NORCROFT + "Norcroft ", "cc", +# else + "cc", "", +# endif +#endif + + "RISC OS", + + " (Acorn Computers Ltd)", + +#ifdef __DATE__ + " on ", __DATE__ +#else + "", "" +#endif + ); + +} /* end function version_local() */ diff --git a/acorn/makefile b/acorn/makefile new file mode 100644 index 0000000..323ffca --- /dev/null +++ b/acorn/makefile @@ -0,0 +1,115 @@ +# Makefile for Zip, ZipNote, ZipCloak and ZipSplit + +# add -g to CC to debug +# add -d to BIND to debug +CC = cc +BIND = link +AS = $(CC) -c +ASM = objasm +SQUEEZE = squeeze -v +E = + +# flags +# CFLAGS flags for C compile +# LFLAGS1 flags after output file spec, before obj file list +# LFLAGS2 flags after obj file list (libraries, etc) +# +LIB = +CBASE = -throwback -wn -DASMV -apcs 3/26 +CFLAGS = $(CBASE) -IC:,@. +ASMFLAGS = -Throwback -Stamp -NoCache -CloseExec -quit -apcs 3/26 +LFLAGS1 = +LFLAGS2 = $(LIB) C:o.Stubs + +# Uncomment the following line to enable support for Unix +# Extra Field (Timezone) +#CFLAGS = $(CFLAGS) -DUSE_EF_UT_TIME + +# object file lists +OBJZ = zip.o zipfile.o zipup.o fileio.o util.o globals.o crc32.o \ + crypt.o ttyio.o riscos.o acornzip.o swiven.o + +OBJI = deflate.o trees.o +OBJA = match.o sendbits.o +OBJU = zipfile_.o fileio_.o util_.o globals.o riscos.o acornzip_.o swiven.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o $(OBJU) crc32_.o crypt_.o ttyio.o +OBJS = zipsplit.o $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h acorn/osdep.h acorn/riscos.h acorn/swiven.h + +all: zip zipnote zipsplit zipcloak + + +install: %.zip %.zipnote %.zipsplit %.zipcloak %.zipsfx \ + zip zipnote zipsplit zipcloak zipsfx + $(SQUEEZE) zip %.zip + $(SQUEEZE) zipnote %.zipnote + $(SQUEEZE) zipsplit %.zipsplit + $(SQUEEZE) zipcloak %.zipcloak + copy acorn.zipsfx %.zipsfx ~CVF + +# suffix rules +.SUFFIXES: _.o .o .c +.c_.o: + $(CC) $(CFLAGS) -DUTIL -c $*.c -o $*_.o +.c.o: + $(CC) $(CFLAGS) -c $< +.s.o: + $(ASM) $(ASMFLAGS) -from @*.s -to @*.o + +# rules for zip, zipnote, zipcloak and zipsplit +$(OBJZ): $(ZIP_H) +$(OBJI): $(ZIP_H) +$(OBJN): $(ZIP_H) +$(OBJS): $(ZIP_H) +$(OBJC): $(ZIP_H) +zip.o crc32.o crypt.o fileio.o zipfile.o zipup.o: crc32.h +zipcloak.o crc32_.o crypt_.o fileio_.o zipfile_.o: crc32.h +zip.o zipup.o crypt.o ttyio.o zipcloak.o crypt_.o: crypt.h +zip.o zipup.o zipnote.o zipcloak.o zipsplit.o: revision.h +zip.o crypt.o ttyio.o zipcloak.o crypt_.o: ttyio.h + +crc32_.o: crc32.c + $(CC) $(CFLAGS) -DUTIL -c c.crc32 -o o.crc32_ +crypt_.o: crypt.c + $(CC) $(CFLAGS) -DUTIL -c c.crypt -o o.crypt_ +util_.o: util.c + $(CC) $(CFLAGS) -DUTIL -c c.util -o o.util_ +fileio_.o: fileio.c + $(CC) $(CFLAGS) -DUTIL -c c.fileio -o o.fileio_ +zipfile_.o: zipfile.c + $(CC) $(CFLAGS) -DUTIL -c c.zipfile -o o.zipfile_ +acornzip_.o: acorn/acornzip.c $(ZIP_H) + $(CC) $(CFLAGS) -DUTIL -c acorn/acornzip.c -o o.acornzip_ + +riscos.o: acorn/riscos.c acorn/riscos.h + $(CC) $(CFLAGS) -c acorn/riscos.c + +acornzip.o: acorn/acornzip.c $(ZIP_H) + $(CC) $(CFLAGS) -c acorn/acornzip.c + +match.o: acorn/match.s + $(ASM) $(ASMFLAGS) -from acorn.s.match -to o.match + +sendbits.o: acorn/sendbits.s + $(ASM) $(ASMFLAGS) -from acorn.s.sendbits -to o.sendbits + +swiven.o: acorn/swiven.s + $(ASM) $(ASMFLAGS) -from acorn.s.swiven -to o.swiven + +zip: $(OBJZ) $(OBJI) $(OBJA) + $(BIND) -o zip$(E) $(LFLAGS1) $(OBJZ) $(OBJI) $(OBJA) $(LFLAGS2) +zipnote: $(OBJN) + $(BIND) -o zipnote$(E) $(LFLAGS1) $(OBJN) $(LFLAGS2) +zipcloak: $(OBJC) + $(BIND) -o zipcloak$(E) $(LFLAGS1) $(OBJC) $(LFLAGS2) +zipsplit: $(OBJS) + $(BIND) -o zipsplit$(E) $(LFLAGS1) $(OBJS) $(LFLAGS2) + +clean: ;remove zip; remove zipcloak; + remove zipsplit; remove zipnote; + create o.!fake! 0 + wipe o.* ~cf + +# end of Makefile diff --git a/acorn/match.s b/acorn/match.s new file mode 100644 index 0000000..ee68ce6 --- /dev/null +++ b/acorn/match.s @@ -0,0 +1,217 @@ +;=========================================================================== +; Copyright (c) 1990-1999 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 1999-Oct-05 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, both of these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +;=========================================================================== +; match.s for ARM by Sergio Monesi. + +r0 RN 0 +r1 RN 1 +r2 RN 2 +r3 RN 3 +r4 RN 4 +r5 RN 5 +r6 RN 6 +r7 RN 7 +r8 RN 8 +r9 RN 9 +sl RN 10 +fp RN 11 +ip RN 12 +sp RN 13 +lr RN 14 +pc RN 15 + +MAX_DIST EQU 32506 +WMASK EQU 32767 +MAX_MATCH EQU 258 + + AREA |C$$code|, CODE, READONLY + + +; r1 = chain_lenght +; r2 = scan +; r3 = match +; r4 = len (tmp) +; r5 = best_len +; r6 = limit +; r7 = strend +; r8 = scan_end1 +; r9 = scan_end +; lr = window +; fp = prev + +|__max_chain_length| + IMPORT max_chain_length + DCD max_chain_length +|__window| + IMPORT window + DCD window +|__prev| + IMPORT prev + DCD prev +|__prev_length| + IMPORT prev_length + DCD prev_length +|__strstart| + IMPORT strstart + DCD strstart +|__good_match| + IMPORT good_match + DCD good_match +|__nice_match| + IMPORT nice_match + DCD nice_match +|__match_start| + IMPORT match_start + DCD match_start + + DCB "longest_match" + DCB &00,&00,&00 + DCD &ff000010 + + EXPORT longest_match +longest_match + STMFD sp!, {r4-r9,fp,lr} + + LDR fp, [pc, #|__prev|-.-8] + + LDR r1, [pc, #|__max_chain_length|-.-8] + LDR r1, [r1] + LDR lr, [pc, #|__window|-.-8] + + LDR ip, [pc, #|__strstart|-.-8] + LDR ip, [ip] + ADD r2, lr, ip + LDR r5, [pc, #|__prev_length|-.-8] + LDR r5, [r5] + SUBS ip, ip, #MAX_DIST-250 ; if r6 > MAX_DIST + SUBCSS r6, ip, #250 ; r6 = r6 - MAXDIST + MOVLS r6, #0 ; else r6 = 0 + + ADD r7, r2, #MAX_MATCH-256 + ADD r7, r7, #256 ; r7 = r2 + MAX_MATCH (=258); + + SUB ip, r5, #1 + LDRB r8, [r2, ip] + LDRB r9, [r2, r5] + + LDR ip, [pc, #|__good_match|-.-8] + LDR ip, [ip] + CMP r5, ip + MOVCS r1, r1, LSR #2 + +cycle + ADD r3, lr, r0 + + LDRB ip, [r3, r5] + CMP ip, r9 + BNE cycle_end + + SUB ip, r5, #1 + LDRB ip, [r3, ip] + CMP ip, r8 + BNE cycle_end + + LDRB ip, [r2] + LDRB r4, [r3] + CMP ip, r4 + BNE cycle_end + + LDRB ip, [r3, #1] + LDRB r4, [r2, #1] + CMP ip, r4 + BNE cycle_end + + ADD r2, r2, #2 + ADD r3, r3, #2 + +inn_cycle + LDRB ip, [r2, #1]! + LDRB r4, [r3, #1]! + CMP ip, r4 + BNE exit_inn_cycle + + LDRB ip, [r2, #1]! + LDRB r4, [r3, #1]! + CMP ip, r4 + BNE exit_inn_cycle + + LDRB ip, [r2, #1]! + LDRB r4, [r3, #1]! + CMP ip, r4 + BNE exit_inn_cycle + + LDRB ip, [r2, #1]! + LDRB r4, [r3, #1]! + CMP ip, r4 + BNE exit_inn_cycle + + LDRB ip, [r2, #1]! + LDRB r4, [r3, #1]! + CMP ip, r4 + BNE exit_inn_cycle + + LDRB ip, [r2, #1]! + LDRB r4, [r3, #1]! + CMP ip, r4 + BNE exit_inn_cycle + + LDRB ip, [r2, #1]! + LDRB r4, [r3, #1]! + CMP ip, r4 + BNE exit_inn_cycle + + LDRB ip, [r2, #1]! + LDRB r4, [r3, #1]! + CMP ip, r4 + BNE exit_inn_cycle + + CMP r2, r7 + BCC inn_cycle + +exit_inn_cycle + SUB r4, r2, r7 ; len = MAX_MATCH - (int)(strend - scan); + ADD r4, r4, #MAX_MATCH-256 + ADD r4, r4, #256 + + SUB r2, r2, r4 ; scan = strend - MAX_MATCH + + CMP r4, r5 ; if (len > best_len) { + BLE cycle_end + + LDR ip, [pc, #|__match_start|-.-8] ; match_start = cur_match; + STR r0, [ip] + MOV r5, r4 ; best_len = len; + + LDR ip, [pc, #|__nice_match|-.-8] ; if (len >= nice_match) + LDR ip, [ip] + CMP r4, ip + BGE exit_match ; break; + + SUB ip, r5, #1 ; scan_end1 = scan[best_len-1]; + LDRB r8, [r2, ip] + LDRB r9, [r2, r5] ; scan_end = scan[best_len]; + +cycle_end + MOV ip, r0, LSL #17 ; cur_match & WMASK + MOV ip, ip, LSR #17 + + LDR r0, [fp, ip, ASL #1] ; cur_match = prev[cur_match & WMASK] + MOV r0, r0, ASL #16 + MOV r0, r0, LSR #16 + + CMP r0, r6 ; cur_match > limit + BLS exit_match + SUBS r1, r1, #1 ; --chain_length + BNE cycle ; chain_length != 0 + +exit_match + MOV r0, r5 + + LDMFD sp!, {r4-r9,fp,pc}^ + + END diff --git a/acorn/osdep.h b/acorn/osdep.h new file mode 100644 index 0000000..9f7783e --- /dev/null +++ b/acorn/osdep.h @@ -0,0 +1,28 @@ +/* + Copyright (c) 1990-2007 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#include "riscos.h" + +#define RISCOS +#define NO_SYMLINKS +#define NO_FCNTL_H +#define NO_UNISTD_H +#define NO_MKTEMP + +#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \ + procname(n, 1)) + +#define isatty(a) 1 +#define fseek(f,o,t) riscos_fseek((f),(o),(t)) + +#define localtime riscos_localtime +#define gmtime riscos_gmtime + +#ifdef ZCRYPT_INTERNAL +# define ZCR_SEED2 (unsigned)3141592654L /* use PI as seed pattern */ +#endif diff --git a/acorn/riscos.c b/acorn/riscos.c new file mode 100644 index 0000000..84dd2d3 --- /dev/null +++ b/acorn/riscos.c @@ -0,0 +1,394 @@ +/* + Copyright (c) 1990-2002 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* riscos.c */ + +#include +#include +#include +#include "zip.h" +#include "riscos.h" + +#define MAXEXT 256 + +/* External globals */ +extern int scanimage; + +/* Local globals (!?!?) */ +char *exts2swap = NULL; /* Extensions to swap (actually, directory names) */ + +int stat(char *filename,struct stat *res) +{ + int attr; /* object attributes */ + unsigned int load; /* load address */ + unsigned int exec; /* exec address */ + int type; /* type: 0 not found, 1 file, 2 dir, 3 image */ + + if (!res) + return -1; + + if (SWI_OS_File_5(filename,&type,&load,&exec,(int *)&res->st_size,&attr)!=NULL) + return -1; + + if (type==0) + return -1; + + res->st_dev=0; + res->st_ino=0; + res->st_nlink=0; + res->st_uid=1; + res->st_gid=1; + res->st_rdev=0; + res->st_blksize=1024; + + res->st_mode = ((attr & 0001) << 8) | ((attr & 0002) << 6) | + ((attr & 0020) >> 2) | ((attr & 0040) >> 4); + + switch (type) { + case 1: /* File */ + res->st_mode |= S_IFREG; + break; + case 2: /* Directory */ + res->st_mode |= S_IFDIR | 0700; + break; + case 3: /* Image file */ + if (scanimage) + res->st_mode |= S_IFDIR | 0700; + else + res->st_mode |= S_IFREG; + break; + } + + if ((((unsigned int) load) >> 20) == 0xfff) { /* date stamped file */ + unsigned int t1, t2, tc; + + t1 = (unsigned int) (exec); + t2 = (unsigned int) (load & 0xff); + + tc = 0x6e996a00U; + if (t1 < tc) + t2--; + t1 -= tc; + t2 -= 0x33; /* 00:00:00 Jan. 1 1970 = 0x336e996a00 */ + + t1 = (t1 / 100) + (t2 * 42949673U); /* 0x100000000 / 100 = 42949672.96 */ + t1 -= (t2 / 25); /* compensate for .04 error */ + + res->st_atime = res->st_mtime = res->st_ctime = t1; + } + else + res->st_atime = res->st_mtime = res->st_ctime = 0; + + return 0; +} + +#ifndef SFX + +DIR *opendir(char *dirname) +{ + DIR *thisdir; + int type; + int attr; + os_error *er; + + thisdir=(DIR *)malloc(sizeof(DIR)); + if (thisdir==NULL) + return NULL; + + thisdir->dirname=(char *)malloc(strlen(dirname)+1); + if (thisdir->dirname==NULL) { + free(thisdir); + return NULL; + } + + strcpy(thisdir->dirname,dirname); + if (thisdir->dirname[strlen(thisdir->dirname)-1]=='.') + thisdir->dirname[strlen(thisdir->dirname)-1]=0; + + if (er=SWI_OS_File_5(thisdir->dirname,&type,NULL,NULL,NULL,&attr),er!=NULL || + type<=1 || (type==3 && !scanimage)) + { + free(thisdir->dirname); + free(thisdir); + return NULL; + } + + thisdir->buf=malloc(DIR_BUFSIZE); + if (thisdir->buf==NULL) { + free(thisdir->dirname); + free(thisdir); + return NULL; + } + + thisdir->size=DIR_BUFSIZE; + thisdir->offset=0; + thisdir->read=0; + + return thisdir; +} + +struct dirent *readdir(DIR *d) +{ + static struct dirent dent; + + if (d->read==0) { /* no more objects read in the buffer */ + if (d->offset==-1) { /* no more objects to read */ + return NULL; + } + + d->read=255; + if (SWI_OS_GBPB_9(d->dirname,d->buf,&d->read,&d->offset,DIR_BUFSIZE,NULL)!=NULL) + return NULL; + + if (d->read==0) { + d->offset=-1; + return NULL; + } + d->read--; + d->act=(char *)d->buf; + } + else { /* some object is ready in buffer */ + d->read--; + d->act=(char *)(d->act+strlen(d->act)+1); + } + + strcpy(dent.d_name,d->act); + dent.d_namlen=strlen(dent.d_name); + + return &dent; +} + +void closedir(DIR *d) +{ + if (d->buf!=NULL) + free(d->buf); + if (d->dirname!=NULL) + free(d->dirname); + free(d); +} + +int unlink(f) +char *f; /* file to delete */ +/* Delete the file *f, returning non-zero on failure. */ +{ + os_error *er; + char canon[256]; + int size=255; + + er=SWI_OS_FSControl_37(f,canon,&size); + if (er==NULL) { + er=SWI_OS_FSControl_27(canon,0x100); + } + else { + er=SWI_OS_FSControl_27(f,0x100); + } + return (int)er; +} + +int deletedir(char *d) +{ + int objtype; + char *s; + int len; + os_error *er; + + len = strlen(d); + if ((s = malloc(len + 1)) == NULL) + return -1; + + strcpy(s,d); + if (s[len-1]=='.') + s[len-1]=0; + + if (er=SWI_OS_File_5(s,&objtype,NULL,NULL,NULL,NULL),er!=NULL) { + free(s); + return -1; + } + if (objtype<2 || (!scanimage && objtype==3)) { + /* this is a file or it doesn't exist */ + free(s); + return -1; + } + + if (er=SWI_OS_File_6(s),er!=NULL) { + /* maybe this is a problem with the DDEUtils module, try to canonicalise the path */ + char canon[256]; + int size=255; + + if (er=SWI_OS_FSControl_37(s,canon,&size),er!=NULL) { + free(s); + return -1; + } + if (er=SWI_OS_File_6(canon),er!=NULL) { + free(s); + return -1; + } + } + free(s); + return 0; +} + +#endif /* !SFX */ + +int chmod(char *file, int mode) +{ +/*************** NOT YET IMPLEMENTED!!!!!! ******************/ +/* I don't know if this will be needed or not... */ + file=file; + mode=mode; + return 0; +} + +void setfiletype(char *fname,int ftype) +{ + char str[256]; + sprintf(str,"SetType %s &%3.3X",fname,ftype); + SWI_OS_CLI(str); +} + +void getRISCOSexts(char *envstr) +{ + char *envptr; /* value returned by getenv */ + + envptr = getenv(envstr); + if (envptr == NULL || *envptr == 0) return; + + exts2swap=malloc(1+strlen(envptr)); + if (exts2swap == NULL) + return; + + strcpy(exts2swap, envptr); +} + +int checkext(char *suff) +{ + register char *extptr=exts2swap; + register char *suffptr; + register int e,s; + + if (extptr != NULL) while(*extptr) { + suffptr=suff; + e=*extptr; s=*suffptr; + while (e && e!=':' && s && s!='.' && s!='/' && e==s) { + e=*++extptr; s=*++suffptr; + } + if (e==':') e=0; + if (s=='.' || s=='/') s=0; + if (!e && !s) { + return 1; + } + while(*extptr!=':' && *extptr!='\0') /* skip to next extension */ + extptr++; + if (*extptr!='\0') + extptr++; + } + return 0; +} + +int swapext(char *name, char *exptr) +{ + char *ext; + char *p1=exptr; + char *p2; + int extchar=*exptr; + unsigned int i=0; + + while(*++p1 && *p1!='.' && *p1!='/') + ; + ext=malloc(i=p1-exptr); + if (!ext) + return 1; + memcpy(ext, exptr+1, i); + p2=exptr-1; + p1=exptr+i-1; + while(p2 >= name) + *p1--=*p2--; + strcpy(name,ext); + *p1=(extchar=='/'?'.':'/'); + free(ext); + return 0; +} + +void remove_prefix(void) +{ + SWI_DDEUtils_Prefix(NULL); +} + +void set_prefix(void) +{ + char *pref; + int size=0; + + if (SWI_OS_FSControl_37("@",pref,&size)!=NULL) + return; + + size=1-size; + + if (pref=malloc(size),pref!=NULL) { + if (SWI_OS_FSControl_37("@",pref,&size)!=NULL) { + free(pref); + return; + } + + if (SWI_DDEUtils_Prefix(pref)==NULL) { + atexit(remove_prefix); + } + + free(pref); + } +} + +#ifdef localtime +# undef localtime +#endif + +#ifdef gmtime +# undef gmtime +#endif + +/* Acorn's implementation of localtime() and gmtime() + * doesn't consider the timezone offset, so we have to + * add it before calling the library functions + */ + +struct tm *riscos_localtime(const time_t *timer) +{ + time_t localt=*timer; + + localt+=SWI_Read_Timezone()/100; + + return localtime(&localt); +} + +struct tm *riscos_gmtime(const time_t *timer) +{ + time_t localt=*timer; + + localt+=SWI_Read_Timezone()/100; + + return gmtime(&localt); +} + + +int riscos_fseek(FILE *fd, long offset, int whence) +{ + int ret; + switch (whence) + { + case SEEK_END: + ret = (fseek) (fd, 0, SEEK_END); + if (ret) + return ret; + /* fall through */ + case SEEK_CUR: + offset += ftell (fd); + /* fall through */ + default: /* SEEK_SET */ + return (fseek) (fd, offset < 0 ? 0 : offset, SEEK_SET); + } +} diff --git a/acorn/riscos.h b/acorn/riscos.h new file mode 100644 index 0000000..c45a148 --- /dev/null +++ b/acorn/riscos.h @@ -0,0 +1,119 @@ +/* + Copyright (c) 1990-2002 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* riscos.h */ + +#ifndef __riscos_h +#define __riscos_h + +#include +#include + +typedef struct { + int errnum; + char errmess[252]; +} os_error; + +#ifndef __swiven_h +# include "swiven.h" +#endif + +#define MAXPATHLEN 256 +#define MAXFILENAMELEN 64 /* should be 11 for ADFS, 13 for DOS, 64 seems a sensible value... */ +#define DIR_BUFSIZE 1024 /* this should be enough to read a whole E-Format directory */ + +struct stat { + unsigned int st_dev; + int st_ino; + unsigned int st_mode; + int st_nlink; + unsigned short st_uid; + unsigned short st_gid; + unsigned int st_rdev; + unsigned int st_size; + unsigned int st_blksize; + time_t st_atime; + time_t st_mtime; + time_t st_ctime; +}; + +typedef struct { + char *dirname; + void *buf; + int size; + char *act; + int offset; + int read; +} DIR; + +#define dstrm DIR + +struct dirent { + unsigned int d_off; /* offset of next disk directory entry */ + int d_fileno; /* file number of entry */ + size_t d_reclen; /* length of this record */ + size_t d_namlen; /* length of d_name */ + char d_name[MAXFILENAMELEN]; /* name */ +}; + +typedef struct { + unsigned int load_addr; + unsigned int exec_addr; + int lenght; + int attrib; + int objtype; + char name[13]; +} riscos_direntry; + +#define SPARKID 0x4341 /* = "AC" */ +#define SPARKID_2 0x30435241 /* = "ARC0" */ + +typedef struct { + short ID; + short size; + int ID_2; + unsigned int loadaddr; + unsigned int execaddr; + int attr; + int zero; +} extra_block; + + +#define S_IFMT 0770000 + +#define S_IFDIR 0040000 +#define S_IFREG 0100000 /* 0200000 in UnixLib !?!?!?!? */ + +#ifndef S_IEXEC +# define S_IEXEC 0000100 +# define S_IWRITE 0000200 +# define S_IREAD 0000400 +#endif + +extern char *exts2swap; /* Extensions to swap */ + +int stat(char *filename,struct stat *res); +DIR *opendir(char *dirname); +struct dirent *readdir(DIR *d); +char *readd(DIR *d); +void closedir(DIR *d); +int unlink(char *f); +int chmod(char *file, int mode); +void setfiletype(char *fname,int ftype); +void getRISCOSexts(char *envstr); +int checkext(char *suff); +int swapext(char *name, char *exptr); +void remove_prefix(void); +void set_prefix(void); +struct tm *riscos_localtime(const time_t *timer); +struct tm *riscos_gmtime(const time_t *timer); + +int riscos_fseek(FILE *fd, long offset, int whence); +/* work around broken assumption that fseek() is OK with -ve file offsets */ + +#endif /* !__riscos_h */ diff --git a/acorn/sendbits.s b/acorn/sendbits.s new file mode 100644 index 0000000..f12921a --- /dev/null +++ b/acorn/sendbits.s @@ -0,0 +1,105 @@ +;=========================================================================== +; Copyright (c) 1990-1999 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 1999-Oct-05 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, both of these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +;=========================================================================== +; sendbits.s for ARM by Sergio Monesi and Darren Salt. + +r0 RN 0 +r1 RN 1 +r2 RN 2 +r3 RN 3 +r4 RN 4 +r5 RN 5 +r6 RN 6 +r7 RN 7 +r8 RN 8 +r9 RN 9 +sl RN 10 +fp RN 11 +ip RN 12 +sp RN 13 +lr RN 14 +pc RN 15 + + AREA |Asm$$Code|, CODE, READONLY + + = "send_bits",0 + ALIGN + & &FF00000C + + IMPORT __rt_stkovf_split_small + IMPORT flush_outbuf + + IMPORT bi_valid + IMPORT bi_buf + IMPORT out_size + IMPORT out_offset + IMPORT out_buf + + EXPORT send_bits +send_bits + MOV ip,sp + STMDB sp!,{r4,r5,fp,ip,lr,pc} + SUB fp,ip,#4 + LDR r5,=bi_buf + LDR r3,=bi_valid + LDR r4,[r5] + LDR r2,[r3] + ORR r4,r4,r0,LSL r2 ; |= value<= out_size-1 + LDRHS r0,=out_buf + LDRHS r0,[r0] + BLHS flush_outbuf ; then flush the buffer + LDR r0,=out_buf + LDR r1,=out_offset + LDR r0,[r0] + LDR r2,[r1] + MOV r5,r4,LSR #8 + STRB r4,[r0,r2]! ; store 'old' bi_buf + STRB r5,[r0,#1] + ADD r2,r2,#2 + STR r2,[r1] + + LDMDB fp,{r4,r5,fp,sp,pc}^ + + +ptr_bi & bi_valid + & bi_buf + + + = "bi_reverse",0 + ALIGN + & &FF00000C + + EXPORT bi_reverse +bi_reverse + MOV r2,#0 +loop MOVS r0,r0,LSR #1 + ADCS r2,r2,r2 + SUBS r1,r1,#1 + BNE loop + MOV r0,r2 + MOVS pc,lr + + + END diff --git a/acorn/srcrename b/acorn/srcrename new file mode 100644 index 0000000..7bd6119 Binary files /dev/null and b/acorn/srcrename differ diff --git a/acorn/swiven.h b/acorn/swiven.h new file mode 100644 index 0000000..c860d7d --- /dev/null +++ b/acorn/swiven.h @@ -0,0 +1,59 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/* swiven.h */ + +#ifndef __swiven_h +#define __swiven_h + +os_error *SWI_OS_FSControl_26(char *source, char *dest, int actionmask); +/* copy */ + +os_error *SWI_OS_FSControl_27(char *filename, int actionmask); +/* wipe */ + +os_error *SWI_OS_GBPB_9(char *dirname, void *buf, int *number, + int *offset, int size, char *match); +/* read dir */ + +os_error *SWI_OS_File_1(char *filename, unsigned int loadaddr, + unsigned int execaddr, int attrib); +/* write file attributes */ + +os_error *SWI_OS_File_5(char *filename, int *objtype, unsigned int *loadaddr, + unsigned int *execaddr, int *length, int *attrib); +/* read file info */ + +os_error *SWI_OS_File_6(char *filename); +/* delete */ + +os_error *SWI_OS_File_7(char *filename, int loadaddr, int execaddr, int size); +/* create an empty file */ + +os_error *SWI_OS_CLI(char *cmd); +/* execute a command */ + +int SWI_OS_ReadC(void); +/* get a key from the keyboard buffer */ + +os_error *SWI_OS_ReadVarVal(char *var, char *buf, int len, int *bytesused); +/* reads an OS varibale */ + +os_error *SWI_OS_FSControl_54(char *buffer, int dir, char *fsname, int *size); +/* reads the path of a specified directory */ + +os_error *SWI_OS_FSControl_37(char *pathname, char *buffer, int *size); +/* canonicalise path */ + +os_error *SWI_DDEUtils_Prefix(char *dir); +/* sets the 'prefix' directory */ + +int SWI_Read_Timezone(void); +/* returns the timezone offset (centiseconds) */ + +#endif /* !__swiven_h */ diff --git a/acorn/swiven.s b/acorn/swiven.s new file mode 100644 index 0000000..1630124 --- /dev/null +++ b/acorn/swiven.s @@ -0,0 +1,276 @@ +;=========================================================================== +; Copyright (c) 1990-1999 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 1999-Oct-05 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, both of these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +;=========================================================================== +; SWI veneers used by Zip/Unzip +; + +r0 RN 0 +r1 RN 1 +r2 RN 2 +r3 RN 3 +r4 RN 4 +r5 RN 5 +r6 RN 6 +r7 RN 7 +r8 RN 8 +r9 RN 9 +r10 RN 10 +r11 RN 11 +r12 RN 12 +sp RN 13 +lr RN 14 +pc RN 15 + +sl RN 10 +fp RN 11 +ip RN 12 + + +XOS_Bit EQU &020000 + +OS_GBPB EQU &00000C +OS_File EQU &000008 +OS_FSControl EQU &000029 +OS_CLI EQU &000005 +OS_ReadC EQU &000004 +OS_ReadVarVal EQU &000023 +DDEUtils_Prefix EQU &042580 +Territory_ReadCurrentTimeZone EQU &043048 + + MACRO + STARTCODE $name + EXPORT $name +$name + MEND + + + AREA |C$$code|, CODE, READONLY + +; os_error *SWI_OS_FSControl_26(char *source, char *dest, int actionmask); + + STARTCODE SWI_OS_FSControl_26 + + MOV ip, lr + + MOV r3, r2 + MOV r2, r1 + MOV r1, r0 + MOV r0, #26 + + SWI OS_FSControl + XOS_Bit + + MOVVC r0, #0 + + MOVS pc, ip + + +; os_error *SWI_OS_FSControl_27(char *filename, int actionmask); + + STARTCODE SWI_OS_FSControl_27 + + MOV ip, lr + + MOV r3, r1 + MOV r1, r0 + MOV r0, #27 + + SWI OS_FSControl + XOS_Bit + + MOVVC r0, #0 + + MOVS pc, ip + + +; os_error *SWI_OS_GBPB_9(char *dirname, void *buf, int *number, +; int *offset, int size, char *match); + + STARTCODE SWI_OS_GBPB_9 + + MOV ip, sp + STMFD sp!, {r2-r6,lr} + LDMIA ip, {r5,r6} + LDR r4, [r3] + LDR r3, [r2] + MOV r2, r1 + MOV r1, r0 + MOV r0, #9 + SWI OS_GBPB + XOS_Bit + LDMVSFD sp!, {r2-r6,pc}^ + MOV r0, #0 + LDMFD sp, {r5,r6} + STR r3, [r5] + STR r4, [r6] + LDMFD sp!, {r2-r6,pc}^ + + +; os_error *SWI_OS_File_1(char *filename, int loadaddr, int execaddr, int attrib); + + STARTCODE SWI_OS_File_1 + + STMFD sp!, {r5,lr} + MOV r5, r3 + MOV r3, r2 + MOV r2, r1 + MOV r1, r0 + MOV r0, #1 + SWI OS_File + XOS_Bit + MOVVC r0, #0 + LDMFD sp!, {r5,pc}^ + + + +; os_error *SWI_OS_File_5(char *filename, int *objtype, int *loadaddr, +; int *execaddr, int *length, int *attrib); + + STARTCODE SWI_OS_File_5 + + STMFD sp!, {r1-r5,lr} + MOV r1, r0 + MOV r0, #5 + SWI OS_File + XOS_Bit + LDMVSFD sp!, {r1-r5,pc}^ + LDR lr, [sp] + TEQ lr, #0 + STRNE r0, [lr] + LDR lr, [sp, #4] + TEQ lr ,#0 + STRNE r2, [lr] + LDR lr, [sp, #8] + TEQ lr, #0 + STRNE r3, [lr] + LDR lr, [sp ,#24] + TEQ lr, #0 + STRNE r4, [lr] + LDR lr, [sp ,#28] + TEQ lr, #0 + STRNE r5, [lr] + MOV r0, #0 + LDMFD sp!, {r1-r5,pc}^ + + +; os_error *SWI_OS_File_6(char *filename); + + STARTCODE SWI_OS_File_6 + + STMFD sp!, {r4-r5,lr} + MOV r1, r0 + MOV r0, #6 + SWI OS_File + XOS_Bit + MOVVC r0, #0 + LDMFD sp!, {r4-r5,pc}^ + + +; os_error *SWI_OS_File_7(char *filename, int loadaddr, int execaddr, int size); + + STARTCODE SWI_OS_File_7 + + STMFD sp!, {r4-r5,lr} + MOV r5, r3 + MOV r4, #0 + MOV r3, r2 + MOV r2, r1 + MOV r1, r0 + MOV r0, #7 + SWI OS_File + XOS_Bit + MOVVC r0, #0 + LDMFD sp!, {r4-r5,pc}^ + + +; os_error *SWI_OS_CLI(char *cmd); + + STARTCODE SWI_OS_CLI + + MOV ip, lr + SWI OS_CLI + XOS_Bit + MOVVC r0, #0 + MOVS pc, ip + + +; int SWI_OS_ReadC(void); + + STARTCODE SWI_OS_ReadC + + MOV ip, lr + SWI OS_ReadC + XOS_Bit + MOVS pc, ip + + +; os_error *SWI_OS_ReadVarVal(char *var, char *buf, int len, int *bytesused); + + STARTCODE SWI_OS_ReadVarVal + + STMFD sp!, {r4,lr} + MOV ip, r3 + MOV r3, #0 + MOV r4, #0 + SWI OS_ReadVarVal + XOS_Bit + LDMVSFD sp!, {r4,pc}^ + TEQ ip, #0 + STRNE r2, [ip] + MOV r0, #0 + LDMFD sp!, {r4,pc}^ + + +; os_error *SWI_OS_FSControl_54(char *buffer, int dir, char *fsname, int *size); + + STARTCODE SWI_OS_FSControl_54 + + STMFD sp!, {r3-r6,lr} + LDR r5, [r3] + MOV r3, r2 + MOV r2, r1 + MOV r1, r0 + MOV r0, #54 + SWI OS_FSControl + XOS_Bit + LDMVSFD sp!, {r3-r6,pc}^ + MOV r0, #0 + LDMFD sp!, {r3} + STR r5, [r3] + LDMFD sp!, {r4-r6,pc}^ + + +; os_error *SWI_OS_FSControl_37(char *pathname, char *buffer, int *size); + + STARTCODE SWI_OS_FSControl_37 + + STMFD sp!, {r2,r3-r5,lr} + LDR r5, [r2] + MOV r3, #0 + MOV r4, #0 + MOV r2, r1 + MOV r1, r0 + MOV r0, #37 + SWI OS_FSControl + XOS_Bit + LDMVSFD sp!, {r2,r3-r5,pc}^ + MOV r0, #0 + LDMFD sp!, {r2} + STR r5, [r2] + LDMFD sp!, {r3-r5,pc}^ + + +; os_error *SWI_DDEUtils_Prefix(char *dir); + + STARTCODE SWI_DDEUtils_Prefix + + MOV ip, lr + SWI DDEUtils_Prefix + XOS_Bit + MOVVC r0, #0 + MOVS pc, ip + +; int SWI_Read_Timezone(void); + + STARTCODE SWI_Read_Timezone + + MOV ip, lr + SWI Territory_ReadCurrentTimeZone + XOS_Bit + MOVVC r0, r1 + MOVVS r0, #0 + MOVS pc, ip + + + END diff --git a/acorn/zipsfx b/acorn/zipsfx new file mode 100644 index 0000000..7d63492 --- /dev/null +++ b/acorn/zipsfx @@ -0,0 +1,9 @@ +| zipsfx 0.1 +| Written by Darren Salt +| Assumes that unzipsfx is on Run$Path (eg. in !Boot.Library) +| Assumes that IfThere is available as either *command or utility + +If "%1" = "" Then Error 220 Syntax: zipsfx | | +If "%0" = "" Then Error 220 Syntax: zipsfx | | +Copy Run:unzipsfx %1 A~C~D~F~L~N~R~S~T~V +Print %0 { >> %1 } \ No newline at end of file diff --git a/acorn/zipup.h b/acorn/zipup.h new file mode 100644 index 0000000..47c3536 --- /dev/null +++ b/acorn/zipup.h @@ -0,0 +1,16 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#define fhow "r" +#define fbad (NULL) +typedef FILE *ftype; +#define zopen(n,p) fopen(n,p) +#define zread(f,b,n) fread((b),1,(n),(FILE*)(f)) +#define zclose(f) fclose(f) +#define zerr(f) (k==(extent)(-1L)) +#define zstdin 0 diff --git a/amiga/LMKfile b/amiga/LMKfile new file mode 100644 index 0000000..8c838ea --- /dev/null +++ b/amiga/LMKfile @@ -0,0 +1,117 @@ +# Makefile for Zip, ZipNote, ZipCloak and ZipSplit, Amiga SAS/C 5.10b +# See the master Makefile under the top level Zip/Unzip source directory +# for more information on compiler macros and flags for this version. +# Last update: Jan 07, 2007 +# -John Bush, , + + +####################### +# MACROBE DEFINITIONS # +####################### + +# Compiler and loader debug flags. Omit comments as req'd. +# Do not set when building production version. +# CDBG = -d3 +# LDBG = ADDSYM + +DEFINES = -DNO_MKTEMP +CC = lc +OPT = -O +CFLAGS = $(OPT) $(DEFINES) $(CDBG) -v -mat -cuisf -b0 -j85i86i87i100i + +LD = blink +LDSTART = LIB:c.o +LDFLAGS = LIB LIB:lc.lib+LIB:amiga.lib + +TMPFILE = ram:MakeZip.tmp + +############################################### +# BASIC COMPILE INSTRUCTIONS AND DEPENDENCIES # +############################################### + +# default C rules +.c.o: + $(CC) $(CFLAGS) -o$@ $*.c + +# Alternate rules for routines containing entries needed by utilities +.c.oo: + $(CC) $(CFLAGS) -DUTIL -o$*.oo $*.c + +# object file macrough lists + +HFILES = zip.h ziperr.h tailor.h revision.h crc32.h crypt.h ttyio.h \ + amiga/amiga.h amiga/zipup.h amiga/osdep.h + +OBJA = zipfile.o zipup.o fileio.o util.o globals.o crc32.o crypt.o \ + timezone.o ttyio.o amiga.o amigazip.o filedate.o +OBJI = deflate.o trees.o +OBJU = zipfile.oo fileio.oo util.oo globals.o timezone.o \ + amiga.o amigazip.oo filedate.o + +OBJZ = zip.o $(OBJA) $(OBJI) + +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o $(OBJU) crc32.oo crypt.oo ttyio.o +OBJS = zipsplit.o $(OBJU) + +ZIPS = zip zipnote zipcloak zipsplit + +all: Message $(ZIPS) + +Message: + -echo " " + -echo "WARNING: Lattice 5.x HAS NOT BEEN TESTED WITH THIS ZIP VERSION" + -echo "Report problems to " + -echo " " + +zip: $(OBJZ) $(HFILES) + -echo "$(OBJZ)" > $(TMPFILE) + $(LD) TO Zip FROM $(LDSTART) WITH $(TMPFILE) $(LDFLAGS) $(LDBG) + -delete $(TMPFILE) Zip.info + +zipnote: $(OBJN) $(HFILES) + -echo "$(OBJN)" > $(TMPFILE) + $(LD) TO ZipNote FROM $(LDSTART) WITH $(TMPFILE) $(LDFLAGS) $(LDBG) + -delete $(TMPFILE) ZipNote.info + +zipcloak: $(OBJC) $(HFILES) + -echo "$(OBJC)" > $(TMPFILE) + $(LD) TO ZipCloak FROM $(LDSTART) WITH $(TMPFILE) $(LDFLAGS) $(LDBG) + -delete $(TMPFILE) ZipCloak.info + +zipsplit: $(OBJS) $(HFILES) + -echo "$(OBJS)" > $(TMPFILE) + $(LD) TO ZipSplit FROM $(LDSTART) WITH $(TMPFILE) $(LDFLAGS) $(LDBG) + -delete $(TMPFILE) ZipSplit.info + +clean: + -delete $(OBJZ) all quiet force >nil: + -delete $(OBJU) all quiet force >nil: + -delete $(OBJA) all quiet force >nil: + -delete $(OBJI) all quiet force >nil: + -delete $(OBJN) all quiet force >nil: + -delete $(OBJC) all quiet force >nil: + -delete $(OBJS) all quiet force >nil: + +zip.o: zip.c $(HFILES) +zipnote.o: zipnote.c $(HFILES) +zipcloak.o: zipcloak.c $(HFILES) +crypt.o: crypt.c $(HFILES) +ttyio.o: ttyio.c $(HFILES) +zipsplit.o: zipsplit.c $(HFILES) +deflate.o: deflate.c $(HFILES) +trees.o: trees.c $(HFILES) +zipfile.o: zipfile.c $(HFILES) +zipup.o: zipup.c $(HFILES) +fileio.o: fileio.c $(HFILES) +util.o: util.c $(HFILES) +timezone.o: timezone.c $(HFILES) timezone.h +crc32.o: crc32.c $(HFILES) +crctab.o: crctab.c $(HFILES) +globals.o: globals.c $(HFILES) + +# Amiga specific objects +amiga.o: amiga/amiga.c $(HFILES) +amigazip.o: amiga/amigazip.c $(HFILES) + +# end of Makefile diff --git a/amiga/README b/amiga/README new file mode 100644 index 0000000..861ff85 --- /dev/null +++ b/amiga/README @@ -0,0 +1 @@ +the -A option currently does not work for the amiga. diff --git a/amiga/amiga.c b/amiga/amiga.c new file mode 100644 index 0000000..797d6d8 --- /dev/null +++ b/amiga/amiga.c @@ -0,0 +1,138 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2005-Feb-10 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* OS specific routines for AMIGA platform. + * + * John Bush BIX: jbush + * Paul Kienitz + * + * History: + * + * Date DoBee Comments + * ------- -------- ----------------------------------------------- + * 21Jan93 JBush Original coding. + * Incorporated filedate.c (existing routine). + * + * 31Jan93 JBush Made filedate.c include unconditional. + * + * 18Jul93 PaulK Moved Aztec _abort() here from stat.c because we + * can't share the same one between Zip and UnZip. + * Added close_leftover_open_dirs() call to it. + * + * 17Apr95 PaulK Added Amiga internal version string so that + * installer programs can compare the version being + * installed to see if the copy the user already has + * is older or newer. Added Prestart_Hook to support + * debug tracing in deflate.a. + * + * 6May95 PaulK Added GetComment() for filenote support. + * + * 12Nov95 PaulK Added #define ZIP in front of filedate.c, for + * new options in there; removed declare of set_con() + * since echon() no longer expands to it (or anything). + * + * 12Feb96 PaulK Removed call of echon() entirely. + * + * 12Jul97 PaulK Made both Aztec and SAS define USE_TIME_LIB for filedate.c + * + * 26Aug97 PaulK Added ClearIOErr_exit() + * + * 2Jan98 HWalt Adapted for SAS/C using stat.c replacement functions + * + * 6Jun00 PaulK Removed references to time_lib, since new filedate.c + * supercedes it + */ + +#include +#ifdef AZTEC_C +# include +# include +# include +# include +# include +# include +#else +# include +# include +#endif +#include +#include "ziperr.h" +void ziperr(int c, const char *h); + +#define ZIP +#if !defined(UTIL) +# define NO_MKTIME +#endif + +#ifdef AZTEC_C + +/* ============================================================= */ +/* filedate.c is an external file, since it's shared with UnZip. */ +/* Aztec includes it here, but SAS/C now compiles it separately. */ +# include "amiga/filedate.c" + +/* the same applies to stat.c */ +# include "amiga/stat.c" + +# define setenv BOGUS_INCOMPATIBLE_setenv +# include +# undef setenv +# ifdef DEBUG +# define PRESTART_HOOK +# endif +#endif + +extern void close_leftover_open_dirs(void); + + +/* the following handles cleanup when a ^C interrupt happens: */ + +void _abort(void) /* called when ^C is pressed */ +{ + close_leftover_open_dirs(); + ziperr(ZE_ABORT, "^C"); +} + +void ClearIOErr_exit(int e) /* EXIT is defined as this */ +{ + if (!e) + ((struct Process *) FindTask(NULL))->pr_Result2 = 0; + /* we clear IoErr() since we are successful, in a 1.x-compatible way */ + exit(e); +} + + +/* Make sure the version number here matches the number in revision.h */ +/* as closely as possible in strict decimal "#.#" form: */ +const char version_id[] = "\0$VER: Zip 2.3 (" +# include "env:VersionDate" +")\r\n"; + +/* call this with an arg of NULL to free storage: */ + +char *GetComment(char *filename) +{ + BPTR lk; + static struct FileInfoBlock *fib = NULL; + + if (!filename) { + if (fib) FreeMem(fib, sizeof(*fib)); + fib = NULL; + return NULL; + } + if (!fib) { + if (!(fib = AllocMem(sizeof(*fib), MEMF_PUBLIC))) + ziperr(ZE_MEM, "was checking filenotes"); + } + if (!(lk = Lock(filename, ACCESS_READ))) + return NULL; + if (!Examine(lk, fib)) + fib->fib_Comment[0] = '\0'; + UnLock(lk); + return fib->fib_Comment[0] ? &fib->fib_Comment[0] : NULL; +} diff --git a/amiga/amiga.h b/amiga/amiga.h new file mode 100644 index 0000000..a1461d8 --- /dev/null +++ b/amiga/amiga.h @@ -0,0 +1,54 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#ifndef __amiga_amiga_h +#define __amiga_amiga_h + +/* amiga.h + * + * Globular definitions that affect all of AmigaDom. + * + * Originally included in unzip.h, extracted for simplicity and eeze of + * maintenance by John Bush. + * + * This version is for use with Zip. It is not globally included, but used + * only by functions in amiga/amigazip.c. Much material that was needed for + * UnZip is absent here. + * + */ + +#include /* O_BINARY for open() w/o CR/LF translation */ +#include "amiga/z-stat.h" /* substitute for and */ +#define direct dirent + +#ifndef MODERN +# define MODERN +#endif + +#ifdef AZTEC_C /* Manx Aztec C, 5.0 or newer only */ +# include +# include /* do inline dos.library calls */ +# define O_BINARY 0 +#endif /* AZTEC_C */ + + +#ifdef __SASC +# include +# include +# define disk_not_mounted 0 +# if ( (!defined(O_BINARY)) && defined(O_RAW)) +# define O_BINARY O_RAW +# endif +#endif /* SASC */ + + +/* Funkshine Prough Toe Taipes */ + +LONG FileDate (char *, time_t[]); + +#endif /* __amiga_amiga_h */ diff --git a/amiga/amigazip.c b/amiga/amigazip.c new file mode 100644 index 0000000..4e69d62 --- /dev/null +++ b/amiga/amigazip.c @@ -0,0 +1,507 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#include "zip.h" +#include "amiga/amiga.h" + +#ifndef UTIL /* the companion #endif is a bit of ways down ... */ + +#define utime FileDate + +#define PAD 0 +#define PATH_END '/' + +/* Local globals (kinda like "military intelligence" or "broadcast quality") */ + +extern char *label; /* still declared in fileio.c */ +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +/* Local functions */ +local char *readd OF((DIR *)); +local int wild_recurse OF((char *, char *)); + + +local char *readd(d) +DIR *d; /* directory stream to read from */ +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; +} + + +/* What we have here is a mostly-generic routine using opendir()/readd() and */ +/* isshexp()/MATCH() to find all the files matching a multi-part filespec */ +/* using the portable pattern syntax. It shouldn't take too much fiddling */ +/* to make it usable for any other platform that has directory hierarchies */ +/* but no shell-level pattern matching. It works for patterns throughout */ +/* the pathname, such as "foo:*.?/source/x*.[ch]". */ + +#define ONENAMELEN 30 +/* the length of one filename component on the Amiga */ + +/* whole is a pathname with wildcards, wildtail points somewhere in the */ +/* middle of it. All wildcards to be expanded must come AFTER wildtail. */ + +local int wild_recurse(whole, wildtail) char *whole; char *wildtail; +{ + DIR *dir; + char *subwild, *name, *newwhole = NULL, *glue = NULL, plug = 0, plug2; + ush newlen, amatch = 0; + BPTR lok; + int e = ZE_MISS; + + if (!isshexp(wildtail)) + if (lok = Lock(whole, ACCESS_READ)) { /* p exists? */ + UnLock(lok); + return procname(whole, 0); + } else + return ZE_MISS; /* woops, no wildcards! */ + + /* back up thru path components till existing dir found */ + do { + name = wildtail + strlen(wildtail) - 1; + for (;;) + if (name-- <= wildtail || *name == PATH_END) { + subwild = name + 1; + plug2 = *subwild; + *subwild = 0; + break; + } + if (glue) + *glue = plug; + glue = subwild; + plug = plug2; + dir = opendir(whole); + } while (!dir && !disk_not_mounted && subwild > wildtail); + wildtail = subwild; /* skip past non-wild components */ + + if ((subwild = strchr(wildtail + 1, PATH_END)) != NULL) { + /* this "+ 1" dodges the ^^^ hole left by *glue == 0 */ + *(subwild++) = 0; /* wildtail = one component pattern */ + newlen = strlen(whole) + strlen(subwild) + (ONENAMELEN + 2); + } else + newlen = strlen(whole) + (ONENAMELEN + 1); + if (!dir || !(newwhole = malloc(newlen))) { + if (glue) + *glue = plug; + + e = dir ? ZE_MEM : ZE_MISS; + goto ohforgetit; + } + strcpy(newwhole, whole); + newlen = strlen(newwhole); + if (glue) + *glue = plug; /* repair damage to whole */ + if (!isshexp(wildtail)) { + e = ZE_MISS; /* non-wild name not found */ + goto ohforgetit; + } + + while (name = readd(dir)) { + if (MATCH(wildtail, name, 0)) { + strcpy(newwhole + newlen, name); + if (subwild) { + name = newwhole + strlen(newwhole); + *(name++) = PATH_END; + strcpy(name, subwild); + e = wild_recurse(newwhole, name); + } else + e = procname(newwhole, 0); + newwhole[newlen] = 0; + if (e == ZE_OK) + amatch = 1; + else if (e != ZE_MISS) + break; + } + } + + ohforgetit: + if (dir) closedir(dir); + if (subwild) *--subwild = PATH_END; + if (newwhole) free(newwhole); + if (e == ZE_MISS && amatch) + e = ZE_OK; + return e; +} + +int wild(p) char *p; +{ + char *use; + + /* special handling of stdin request */ + if (strcmp(p, "-") == 0) /* if compressing stdin */ + return newname(p, 0, 0); + + /* wild_recurse() can't handle colons in wildcard part: */ + if (use = strchr(p, ':')) { + if (strchr(++use, ':')) + return ZE_PARMS; + } else + use = p; + + return wild_recurse(p, use); +} + + +int procname(n, caseflag) +char *n; /* name to process */ +int caseflag; /* true to force case-sensitive match */ +/* Process a name or sh expression to operate on (or exclude). Return + an error code in the ZE_ class. */ +{ + char *a; /* path and name for recursion */ + DIR *d; /* directory stream from opendir() */ + char *e; /* pointer to name from readd() */ + int m; /* matched flag */ + char *p; /* path for recursion */ + struct stat s; /* result of stat() */ + struct zlist far *z; /* steps through zfiles list */ + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0, caseflag); + else if (LSSTAT(n, &s)) + { + /* Not a file or directory--search for shell expression in zip file */ + p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */ + m = 1; + for (z = zfiles; z != NULL; z = z->nxt) { + if (MATCH(p, z->iname, caseflag)) + { + z->mark = pcount ? filter(z->zname, caseflag) : 1; + if (verbose) + fprintf(mesg, "zip diagnostic: %scluding %s\n", + z->mark ? "in" : "ex", z->name); + m = 0; + } + } + free((zvoid *)p); + return m ? ZE_MISS : ZE_OK; + } + + /* Live name--use if file, recurse if directory */ + if ((s.st_mode & S_IFDIR) == 0) + { + /* add or remove name of file */ + if ((m = newname(n, 0, caseflag)) != ZE_OK) + return m; + } else { + /* Add trailing / to the directory name */ + if ((p = malloc(strlen(n)+2)) == NULL) + return ZE_MEM; + strcpy(p, n); + a = p + strlen(p); + if (*p && a[-1] != '/' && a[-1] != ':') + strcpy(a, "/"); + if (dirnames && (m = newname(p, 1, caseflag)) != ZE_OK) { + free((zvoid *)p); + return m; + } + /* recurse into directory */ + if (recurse && (d = opendir(n)) != NULL) + { + while ((e = readd(d)) != NULL) { + if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL) + { + closedir(d); + free((zvoid *)p); + return ZE_MEM; + } + strcat(strcpy(a, p), e); + if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */ + { + if (m == ZE_MISS) + zipwarn("name not matched: ", a); + else + ziperr(m, a); + } + free((zvoid *)a); + } + closedir(d); + } + free((zvoid *)p); + } /* (s.st_mode & S_IFDIR) == 0) */ + return ZE_OK; +} + +char *ex2in(x, isdir, pdosflag) +char *x; /* external file name */ +int isdir; /* input: x is a directory */ +int *pdosflag; /* output: force MSDOS file attributes? */ +/* Convert the external file name to a zip file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *n; /* internal file name (malloc'ed) */ + char *t; /* shortened name */ + int dosflag; + + dosflag = dosify; /* default for non-DOS and non-OS/2 */ + + /* Find starting point in name before doing malloc */ + if ((t = strrchr(x, ':')) != NULL) /* reject ":" */ + t++; + else + t = x; + { /* reject "//" */ + char *tt = t; + while (tt = strchr(tt, '/')) + while (*++tt == '/') + t = tt; + } + while (*t == '/') /* reject leading "/" on what's left */ + t++; + + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + + if (dosify) + msname(n); + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + return n; +} + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + return x; +} + +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ + time_t u[2]; /* argument for utime() */ + + /* Convert DOS time to time_t format in u */ + u[0] = u[1] = dos2unixtime(d); + + /* Set updated and accessed times of f */ + utime(f, u); +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + /* convert FNMAX to malloc - 11/8/04 EG */ + char *name; + int len = strlen(f); + + if (f == label) { + if (a != NULL) + *a = label_mode; + if (n != NULL) + *n = -2L; /* convention for a label name */ + if (t != NULL) + t->atime = t->mtime = t->ctime = label_utim; + return label_time; + } + if ((name = malloc(len + 1)) == NULL) { + ZIPERR(ZE_MEM, "filetime"); + } + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + + if (strcmp(f, "-") == 0) { + if (fstat(fileno(stdin), &s) != 0) + error("fstat(stdin)"); + } else if (SSTAT(name, &s) != 0) { + /* Accept about any file kind including directories + * (stored with trailing / with -r option) + */ + free(name); + return 0; + } + free(name); + + if (a != NULL) { + *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE); + if ((s.st_mode & S_IFDIR) != 0) { + *a |= MSDOS_DIR_ATTR; + } + } + if (n != NULL) + *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_ctime; + } + + return unix2dostime(&s.st_mtime); +} + +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; + /* create extra field and change z->att if desired */ +{ +#ifdef USE_EF_UT_TIME +#ifdef IZ_CHECK_TZ + if (!zp_tz_is_valid) return ZE_OK; /* skip silently if no valid TZ info */ +#endif + + if ((z->extra = (char *)malloc(EB_HEADSIZE+EB_UT_LEN(1))) == NULL) + return ZE_MEM; + + z->extra[0] = 'U'; + z->extra[1] = 'T'; + z->extra[2] = EB_UT_LEN(1); /* length of data part of e.f. */ + z->extra[3] = 0; + z->extra[4] = EB_UT_FL_MTIME; + z->extra[5] = (char)(z_utim->mtime); + z->extra[6] = (char)(z_utim->mtime >> 8); + z->extra[7] = (char)(z_utim->mtime >> 16); + z->extra[8] = (char)(z_utim->mtime >> 24); + + z->cextra = z->extra; + z->cext = z->ext = (EB_HEADSIZE+EB_UT_LEN(1)); + + return ZE_OK; +#else /* !USE_EF_UT_TIME */ + return (int)(z-z); +#endif /* ?USE_EF_UT_TIME */ +} + +int deletedir(d) +char *d; /* directory to delete */ +/* Delete the directory *d if it is empty, do nothing otherwise. + Return the result of rmdir(), delete(), or system(). + For VMS, d must be in format [x.y]z.dir;1 (not [x.y.z]). + */ +{ + return rmdir(d); +} + +#endif /* !UTIL */ + + +/******************************/ +/* Function version_local() */ +/******************************/ + + +/* NOTE: the following include depends upon the environment + * variable $Workbench to be set correctly. (Set by + * default, by Version command in Startup-sequence.) + */ +int WBversion = (int) +#include "ENV:Workbench" +; + +void version_local() +{ + static ZCONST char CompiledWith[] = "Compiled with %s%s under %s%s%s%s.\n\n"; + +/* Define buffers. */ + + char buf1[16]; /* compiler name */ + char buf2[16]; /* revstamp */ + char buf3[16]; /* OS */ + char buf4[16]; /* Date */ +/* char buf5[16]; /* Time */ + +/* format "with" name strings */ + +#ifdef AMIGA +# ifdef __SASC + strcpy(buf1,"SAS/C "); +# else +# ifdef LATTICE + strcpy(buf1,"Lattice C "); +# else +# ifdef AZTEC_C + strcpy(buf1,"Manx Aztec C "); +# else + strcpy(buf1,"UNKNOWN "); +# endif +# endif +# endif +/* "under" */ + sprintf(buf3,"AmigaDOS v%d",WBversion); +#else + strcpy(buf1,"Unknown compiler "); + strcpy(buf3,"Unknown OS"); +#endif + +/* Define revision, date, and time strings. + * NOTE: Do not calculate run time, be sure to use time compiled. + * Pass these strings via your makefile if undefined. + */ + +#if defined(__VERSION__) && defined(__REVISION__) + sprintf(buf2,"version %d.%d",__VERSION__,__REVISION__); +#else +# ifdef __VERSION__ + sprintf(buf2,"version %d",__VERSION__); +# else + sprintf(buf2,"unknown version"); +# endif +#endif + +#ifdef __DATE__ + sprintf(buf4," on %s",__DATE__); +#else + strcpy(buf4," unknown date"); +#endif + +/****** +#ifdef __TIME__ + sprintf(buf5," at %s",__TIME__); +#else + strcpy(buf5," unknown time"); +#endif +******/ + +/* Print strings using "CompiledWith" mask defined above. + * ("Compiled with %s%s under %s%s%s%s.") + */ + + printf(CompiledWith, + buf1, + buf2, + buf3, + buf4, + /* buf5, */ "", + "" ); /* buf6 not used */ + +} /* end function version_local() */ diff --git a/amiga/crc_68.a b/amiga/crc_68.a new file mode 100644 index 0000000..4cc2a25 --- /dev/null +++ b/amiga/crc_68.a @@ -0,0 +1,144 @@ +;=========================================================================== +; Copyright (c) 1990-2000 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 2000-Apr-09 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, all these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +;=========================================================================== +; crc_68 created by Paul Kienitz, last modified 04 Jan 96. +; +; Return an updated 32 bit CRC value, given the old value and a block of data. +; The CRC table used to compute the value is gotten by calling get_crc_table(). +; This replaces the older updcrc() function used in Zip and fUnZip. The +; prototype of the function is: +; +; ulg crc32(ulg crcval, uch *text, extent textlen); +; +; On the Amiga, type extent is always unsigned long, not unsigned int, because +; int can be short or long at whim, but size_t is long. +; +; If using this source on a non-Amiga 680x0 system, note that we treat +; a0/a1/d0/d1 as scratch registers not preserved across function calls. +; We do not bother to support registerized arguments for crc32() -- the +; textlen parm is usually large enough so that savings outside the loop +; are pointless. +; +; Define NO_UNROLLED_LOOPS to use a simple short loop which might be more +; efficient on certain machines with dinky instruction caches ('020?), or for +; processing short strings. If loops are unrolled, the textlen parm must be +; less than 512K; if not unrolled, it must be less than 64K. + + xdef _crc32 ; (ulg val, uch *buf, extent bufsize) + +DO_CRC0 MACRO + moveq #0,ltemp + move.b (textbuf)+,ltemp + eor.b crcval,ltemp + lsl.w #2,ltemp + move.l (crc_table,ltemp.w),ltemp + lsr.l #8,crcval + eor.l ltemp,crcval + ENDM + + machine mc68020 + +DO_CRC2 MACRO + move.b (textbuf)+,btemp + eor.b crcval,btemp + lsr.l #8,crcval + move.l (crc_table,btemp.w*4),ltemp + eor.l ltemp,crcval + ENDM + +crc_table equr a0 array of unsigned long +crcval equr d0 unsigned long initial value +textbuf equr a1 array of unsigned char +textbufsize equr d1 unsigned long (count of bytes in textbuf) +btemp equr d2 +ltemp equr d3 + + + xref _get_crc_table ; ulg *get_crc_table(void) + + NOLIST + INCLUDE 'exec/execbase.i' + LIST + xref _SysBase ; struct ExecBase * + + +_crc32: + move.l 8(sp),d0 + bne.s valid + moveq #0,d0 + rts +valid: movem.l btemp/ltemp,-(sp) + jsr _get_crc_table + move.l d0,ltemp + move.l 12(sp),crcval + move.l 16(sp),textbuf + move.l 20(sp),textbufsize + not.l crcval + move.l _SysBase,crc_table + move.w AttnFlags(crc_table),btemp + move.l ltemp,crc_table + btst #AFB_68020,btemp + bne twenty + + IFD NO_UNROLLED_LOOPS + + bra.s decr +loop: DO_CRC0 +decr: dbra textbufsize,loop + bra.s done + +twenty: moveq #0,btemp + bra.s decr2 +loop2: DO_CRC2 +decr2: dbra textbufsize,loop2 + + ELSE ; !NO_UNROLLED_LOOPS + + move.l textbufsize,btemp + lsr.l #3,textbufsize + bra decr8 +loop8: DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 +decr8: dbra textbufsize,loop8 + and.w #7,btemp + bra.s decr1 +loop1: DO_CRC0 +decr1: dbra btemp,loop1 + bra done + +twenty: moveq #0,btemp + move.l textbufsize,-(sp) + lsr.l #3,textbufsize + bra decr82 +loop82: DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 +decr82: dbra textbufsize,loop82 + move.l (sp)+,textbufsize + and.w #7,textbufsize + bra.s decr12 +loop12: DO_CRC2 +decr12: dbra textbufsize,loop12 + + ENDC ; ?NO_UNROLLED_LOOPS + +done: movem.l (sp)+,btemp/ltemp + not.l crcval +;;;;; move.l crcval,d0 ; crcval already is d0 + rts diff --git a/amiga/deflate.a b/amiga/deflate.a new file mode 100644 index 0000000..b21adae --- /dev/null +++ b/amiga/deflate.a @@ -0,0 +1,1053 @@ +;=========================================================================== +; Copyright (c) 1990-1999 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 1999-Oct-05 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, both of these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +;=========================================================================== +; This is a 680x0 assembly language translation of the Info-ZIP source file +; deflate.c, by Paul Kienitz. The function longest_match is based in part +; on match.a by Carsten Steger, which in turn is partly based on match.s +; for 386 by Jean-loup Gailly and Kai Uwe Rommel. Mostly, however, this +; material is based on deflate.c, by Gailly, Rommel, and Igor Mandrichenko. +; This code is not commented very much; see deflate.c for comments that explain +; what the functions are doing. +; +; The symbols that can be used to select different versions are as follows: +; +; CPU020 if defined, use 68020 instructions always. +; +; CPUTEST if defined, check at runtime for CPU type. Another symbol +; specifying the platform-specific test must be used with this. +; If neither of these is defined, use 68000 instructions only. +; Runtime test is nonportable; it is different for each OS. +; +; AMIGA use Amiga-specific test for 68020, if CPUTEST defined. Also +; tells it that registers d0/a0/d1/a1 are not preserved by +; function calls. At present, if AMIGA is not defined, it +; causes functions to preserve all registers. ALL OF THIS CODE +; CURRENTLY ASSUMES THAT REGISTERS D2-D7/A2-A6 WILL BE PRESERVED +; BY ANY FUNCTIONS THAT IT CALLS. +; +; DYN_ALLOC should be defined here if it is defined for C source; tells us +; that big arrays are allocated instead of static. +; +; WSIZE must be defined as the same number used for WSIZE in the C +; source, and must be a power of two <= 32768. As elsewhere, +; the default value is 32768. +; +; INT16 define this if ints are 16 bits; otherwise 32 bit ints assumed. +; +; SMALL_MEM define this if it is defined in the C source; otherwise it uses +; the MEDIUM_MEM model. BIG_MEM and MMAP are *not* supported. +; The FULL_SEARCH option in deflate.c is also not supported. +; +; DEBUG activates some tracing output, as in the C source. +; +; QUADLONG this selects a different version of the innermost longest_match +; loop code for 68020 operations, comparing bytes four at a time +; instead of two at a time. It seems to be a tiny bit faster on +; average, but it's slower often enough that one can't generalize. +; +; This code currently assumes that function results are returned in D0 for +; all platforms. It assumes that args to functions are pushed onto the stack, +; last arg first. It also currently assumes that all C symbols have an +; underscore prepended when referenced from assembly. + + IFND CPU020 + IFND CPUTEST +CPU000 equ 1 + ENDC + ENDC + +; Use these macros for accessing variables of type int: + IFD INT16 +MOVINT MACRO + move.w \1,\2 + ENDM +CLRINT MACRO + clr.w \1 + ENDM +INTSIZE equ 2 + ELSE ; !INT16 +MOVINT MACRO + move.l \1,\2 + ENDM +CLRINT MACRO + clr.l \1 + ENDM +INTSIZE equ 4 + ENDC + + IFD DYN_ALLOC +BASEPTR MACRO + move.l \1,\2 + ENDM + ELSE +BASEPTR MACRO + lea \1,\2 + ENDM + ENDC + +; constants we use, many of them adjustable: + +MAX_MATCH equ 258 +MIN_MATCH equ 3 +TOO_FAR equ 4096 + IFND WSIZE +WSIZE equ 32768 + ENDC +WMASK equ WSIZE-1 +MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1 +MIN_LOOKAHEAD equ MAX_MATCH+MIN_MATCH+1 +; IFD BIG_MEM ; NOT supported -- type Pos needs to be 32 bits +;HASH_BITS equ 15 +; ELSE + IFD SMALL_MEM +HASH_BITS equ 13 + ELSE +HASH_BITS equ 14 ; default -- MEDIUM_MEM + ENDC +; ENDC ; BIG_MEM +HASH_SIZE equ 1< + MOVINT Strst,_strstart ; ct_tally reads this variable + moveq #0,d0 + move.b -1(Window,Strst.l),d0 + MOVINT d0,-(sp) + CLRINT -(sp) + jsr _ct_tally + addq #2*INTSIZE,sp + tst.w d0 + beq.s skipliteral + FLUSH_B #0 + move.l Strst,_block_start +skipliteral: + addq.w #1,Strst + subq.w #1,Look + +refill: + cmp.w #MIN_LOOKAHEAD,Look + bhs look_loop + bsr fill_window + bra look_loop + +last_tally: + tst.w Avail + beq last_flush + MOVINT Strst,_strstart ; ct_tally reads this variable + moveq #0,d0 + move.b -1(Window,Strst.l),d0 + MOVINT d0,-(sp) + CLRINT -(sp) + jsr _ct_tally + addq #2*INTSIZE,sp +last_flush: + FLUSH_B #1 + bra deflate_exit + +; ================== This is another version used for low compression levels: + +deflate_fast: + moveq #0,MatchL + moveq #MIN_MATCH-1,PrevL +flook_loop: + tst.w Look + beq flast_flush + + IN_STR a0,d0 + tst.w Head + beq.s fno_new_match + move.w Strst,d0 + sub.w Head,d0 + cmp.w #MAX_DIST,d0 + bhi.s fno_new_match + move.w PrevL,prev_length ; longest_match reads these variables + MOVINT Strst,_strstart + MOVINT Head,d0 ; parm for longest_match + bsr longest_match ; sets match_start + cmp.w Look,d0 ; does length exceed valid data? + bls.s fstml + move.w Look,d0 +fstml: move.w d0,MatchL ; valid length of match + +fno_new_match: + cmp.w #MIN_MATCH,MatchL + blo fliteral + ; CHECK_MATCH Strst,match_start,MatchL + MOVINT Strst,_strstart ; ct_tally reads this variable + move.l MatchL,d0 + subq.w #MIN_MATCH,d0 + MOVINT d0,-(sp) + move.l Strst,d0 + sub.w match_start,d0 + MOVINT d0,-(sp) + jsr _ct_tally ; sets d0 true if we have to flush + addq #2*INTSIZE,sp + sub.w MatchL,Look + cmp.w max_lazy_match,MatchL + bhi ftoolong + subq.w #2,MatchL +finsertmatch: + addq.w #1,Strst + IN_STR a0,d1 ; preserve d0 + dbra MatchL,finsertmatch + moveq #0,MatchL ; not needed? + addq.w #1,Strst + bra.s flushfill + +ftoolong: + add.w MatchL,Strst + moveq #0,MatchL + moveq #0,d1 ; preserve d0 + move.b (Window,Strst.l),d1 + move.w d1,ins_h +; My assembler objects to passing <1(Window,Strst.l)> directly to UP_HASH... + move.b 1(Window,Strst.l),Avail ; Avail is not used in deflate_fast + UP_HASH d1,Avail ; preserve d0 + IFNE MIN_MATCH-3 + FAIL needs to UP_HASH another MIN_MATCH-3 times, but with what arg? + ENDC + bra.s flushfill + +fliteral: + TRACE_C <(Window,Strst.l)> + MOVINT Strst,_strstart ; ct_tally reads this variable + moveq #0,d0 + move.b (Window,Strst.l),d0 + MOVINT d0,-(sp) + CLRINT -(sp) + jsr _ct_tally ; d0 set if we need to flush + addq #2*INTSIZE,sp + addq.w #1,Strst + subq.w #1,Look + +flushfill: + tst.w d0 + beq.s frefill + FLUSH_B #0 + move.l Strst,_block_start +frefill: + cmp.w #MIN_LOOKAHEAD,Look + bhs flook_loop + bsr fill_window + bra flook_loop + +flast_flush: + FLUSH_B #1 ; sets our return value + +deflate_exit: + MOVINT Strst,_strstart ; save back cached values + move.w PrevL,prev_length + move.w Look,lookahead + movem.l (sp)+,DEFREGS + rts + + +; ========================================================================= +; void fill_window(void) calls the input function to refill the sliding +; window that we use to find substring matches in. + +More equr Head ; local variable in fill_window +WindTop equr Prev ; local variable used for sliding +SlidIx equr PrevL ; local variable used for sliding + + IFD AMIGA +FWREGS reg d2-d5/a2-a6 ; does NOT include Look and Strst + ELSE +FWREGS reg d1-d5/a0-a6 ; likewise + ENDC +; all registers available to be clobbered by the sliding operation: +; we exclude More, WindTop, SlidIx, Look, Strst, Window, a4 and a7. +SPAREGS reg d0-d3/a0-a1/a5-a6 +SPCOUNT equ 8 ; number of registers in SPAREGS + + +_fill_window: ; C-callable entry point + movem.l Strst/Look,-(sp) + IFD INT16 + moveq #0,Strst ; Strst must be valid as a long + ENDC + MOVINT _strstart,Strst + move.w lookahead,Look + BASEPTR _window,Window + bsr.s fill_window + MOVINT Strst,_strstart + move.w Look,lookahead + movem.l (sp)+,Strst/Look + rts + +; strstart, lookahead, and window must be cached in Strst, Look, and Window: +fill_window: ; asm-callable entry point + movem.l FWREGS,-(sp) + tst.w eofile ; we put this up here for speed + bne fwdone + and.l #$FFFF,Look ; make sure Look is valid as long +fw_refill: + move.l _window_size,More ; <= 64K + sub.l Look,More + sub.l Strst,More ; Strst is already valid as long + cmp.w #EOF,More + bne.s notboundary + subq.w #1,More + bra checkend + +notboundary: + tst.w sliding + beq checkend + cmp.w #WSIZE+MAX_DIST,Strst + blo checkend + IFGT 32768-WSIZE + lea WSIZE(Window),WindTop ; WindTop is aligned when Window is + ELSE + move.l Window,WindTop + add.l #WSIZE,WindTop + ENDC + move.l Window,d0 + and.w #3,d0 + beq.s isaligned + subq.w #1,d0 +align: move.b (WindTop)+,(Window)+ ; copy up to a longword boundary + dbra d0,align +isaligned: +; This is faster than a simple move.l (WindTop)+,(Window)+ / dbra loop: + move.w #(WSIZE-1)/(4*SPCOUNT),SlidIx +slide: movem.l (WindTop)+,SPAREGS ; copy, 32 bytes at a time! + movem.l SPAREGS,(Window) ; a slight overshoot doesn't matter. + lea 4*SPCOUNT(Window),Window ; can't use (aN)+ as movem.l dest + dbra SlidIx,slide + BASEPTR _window,Window ; restore cached value + sub.w #WSIZE,match_start + sub.w #WSIZE,Strst + sub.l #WSIZE,_block_start + add.w #WSIZE,More + BASEPTR _head,a0 + move.w #HASH_SIZE-1,d0 +fixhead: + move.w (a0),d1 + sub.w #WSIZE,d1 + bpl.s headok + moveq #0,d1 +headok: move.w d1,(a0)+ + dbra d0,fixhead + BASEPTR _prev,a0 + move.w #WSIZE-1,d0 +fixprev: + move.w (a0),d1 + sub.w #WSIZE,d1 + bpl.s prevok + moveq #0,d1 +prevok: move.w d1,(a0)+ + dbra d0,fixprev + TRACE_C #'.' + +checkend: ; assert eofile is false + MOVINT More,-(sp) ; assert More's upper word is zero + move.l Strst,d0 + add.w Look,d0 + add.l Window,d0 + move.l d0,-(sp) + move.l _read_buf,a0 + jsr (a0) ; refill the upper part of the window + addq #4+INTSIZE,sp + tst.w d0 + beq.s iseof + cmp.w #EOF,d0 + beq.s iseof + add.w d0,Look + cmp.w #MIN_LOOKAHEAD,Look + blo fw_refill ; eofile is still false + + bra.s fwdone +iseof: move.w #1,eofile +fwdone: movem.l (sp)+,FWREGS + rts + + +; ========================================================================= +; void lm_free(void) frees dynamic arrays in the DYN_ALLOC version. + + xdef _lm_free ; the entry point + +_lm_free: + IFD DYN_ALLOC + move.l _window,d0 + beq.s lf_no_window + move.l d0,-(sp) + jsr _free + addq #4,sp + clr.l _window +lf_no_window: + move.l _prev,d0 + beq.s lf_no_prev + move.l d0,-(sp) + jsr _free + move.l _head,(sp) ; reuse the same stack arg slot + jsr _free + addq #4,sp + clr.l _prev + clr.l _head +lf_no_prev: + ENDC + rts + +; ============================================================================ +; void lm_init(int pack_level, unsigned short *flags) allocates dynamic arrays +; if any, and initializes all variables so that deflate() is ready to go. + + xdef _lm_init ; the entry point + +Level equr d2 +;Window equr a2 ; as in deflate() + IFD AMIGA +INIREGS reg d2/a2 + ELSE +INIREGS reg d0-d2/a0-a1 + ENDC + +_lm_init: + MOVINT 4(sp),d0 + move.l 4+INTSIZE(sp),a0 + movem.l INIREGS,-(sp) + move.w d0,Level + cmp.w #1,Level + blt.s levelerr + bgt.s try9 + bset.b #B_FAST,1(a0) +try9: cmp.w #9,Level + bgt.s levelerr + blt.s levelok + bset.b #B_SLOW,1(a0) + bra.s levelok +levelerr: + pea level_message + jsr _error ; never returns +levelok: + clr.w sliding + tst.l _window_size + bne.s gotawindowsize + move.w #1,sliding + move.l #2*WSIZE,_window_size +gotawindowsize: + + BASEPTR _window,Window + IFD DYN_ALLOC + move.l Window,d0 ; fake tst.l + bne.s gotsomewind + CAL_SH WSIZE + move.l d0,Window + move.l d0,_window + bne.s gotsomewind + pea window_message + MOVINT #ZE_MEM,-(sp) + jsr _ziperr ; never returns +gotsomewind: + tst.l _prev + bne.s gotsomehead + CAL_SH WSIZE + move.l d0,_prev + beq.s nohead + CAL_SH HASH_SIZE + move.l d0,_head + bne.s gotfreshhead ; newly calloc'd memory is zeroed +nohead: pea hash_message + MOVINT #ZE_MEM,-(sp) + jsr _ziperr ; never returns +gotsomehead: + ENDC ; DYN_ALLOC + + move.w #(HASH_SIZE/2)-1,d0 ; two shortwords per loop + BASEPTR _head,a0 +wipeh: clr.l (a0)+ + dbra d0,wipeh +gotfreshhead: + move.l Level,d0 + IFEQ Sizeof_config-8 + asl.l #3,d0 + ELSE + mulu #Sizeof_config,d0 + ENDC + lea config_table,a0 + add.l d0,a0 + move.w Max_lazy(a0),max_lazy_match + move.w Good_length(a0),good_match + move.w Nice_length(a0),nice_match + move.w Max_chain(a0),max_chain_len + CLRINT _strstart + clr.l _block_start + bsr match_init + + clr.w eofile + MOVINT #WSIZE,-(sp) ; We read only 32K because lookahead is short + move.l Window,-(sp) ; even when int size is long, as if deflate.c + move.l _read_buf,a0 ; were compiled with MAXSEG_64K defined. + jsr (a0) + addq #4+INTSIZE,sp + move.w d0,lookahead + beq.s noread + cmp.w #EOF,d0 + bne.s irefill +noread: move.w #1,eofile + clr.w lookahead + bra.s init_done + +irefill: + move.w lookahead,d0 + cmp.w #MIN_LOOKAHEAD,d0 + bhs.s hashify + bsr _fill_window ; use the C-callable version +hashify: + clr.w ins_h + moveq #MIN_MATCH-2,d0 +hash1: move.b (Window)+,d1 + UP_HASH Level,d1 + dbra d0,hash1 + +init_done: + movem.l (sp)+,INIREGS + rts + +; strings for error messages: +hash_message dc.b 'hash table allocation',0 +window_message dc.b 'window allocation',0 +level_message dc.b 'bad pack level',0 + + end diff --git a/amiga/filedate.c b/amiga/filedate.c new file mode 100644 index 0000000..9ccbdda --- /dev/null +++ b/amiga/filedate.c @@ -0,0 +1,599 @@ +/* + Copyright (c) 1990-2002 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* Low-level Amiga routines shared between Zip and UnZip. + * + * Contains: FileDate() + * getenv() [replaces inadequate standard library version] + * setenv() [SAS/C only, replaces standard library version] + * set_TZ() [SAS/C only] + * GetPlatformLocalTimezone() [callback from timezone.c tzset()] + * time() + * sendpkt() + * Agetch() + * + * The first five are used by most Info-ZIP programs except fUnZip. + * The last two are used by all except the non-CRYPT version of fUnZip. + * Probably some of the stuff in here is unused by ZipNote and ZipSplit too... + * sendpkt() is used by Agetch() and FileDate(), and by screensize() in + * amiga/amiga.c (UnZip); time() is used only by Zip. + */ + + +/* HISTORY/CHANGES + * 2 Sep 92, Greg Roelofs, Original coding. + * 6 Sep 92, John Bush, Incorporated into UnZip 5.1 + * 6 Sep 92, John Bush, Interlude "FileDate()" defined, which calls or + * redefines SetFileDate() depending upon AMIGADOS2 definition. + * 11 Oct 92, John Bush, Eliminated AMIGADOS2 switch by determining + * revision via OpenLibrary() call. Now only one version of + * the program runs on both platforms (1.3.x vs. 2.x) + * 11 Oct 92, John Bush, Merged with Zip version and changed arg passing + * to take time_t input instead of struct DateStamp. + * Arg passing made to conform with utime(). + * 22 Nov 92, Paul Kienitz, fixed includes for Aztec and cleaned up some + * lint-ish errors; simplified test for AmigaDOS version. + * 11 Nov 95, Paul Kienitz, added Agetch() for crypt password input and + * UnZip's "More" prompt -- simplifies crypt.h and avoids + * use of library code redundant with sendpkt(). Made it + * available to fUnZip, which does not use FileDate(). + * 22 Nov 95, Paul Kienitz, created a new tzset() that gets the current + * timezone from the Locale preferences. These exist only under + * AmigaDOS 2.1 and up, but it is probably correctly set on more + * Amigas than the TZ environment variable is. We check that + * only if TZ is not validly set. We do not parse daylight + * savings syntax except to check for presence vs. absence of a + * DST part; United States rules are assumed. This is better + * than the tzset()s in the Amiga compilers' libraries do. + * 15 Jan 96, Chr. Spieler, corrected the logic when to select low level + * sendpkt() (when FileDate(), Agetch() or windowheight() is used), + * and AMIGA's Agetch() (CRYPT, and UnZip(SFX)'s UzpMorePause()). + * 10 Feb 96, Paul Kienitz, re-fiddled that selection logic again, moved + * stuff around for clarity. + * 16 Mar 96, Paul Kienitz, created a replacement localtime() to go with the + * new tzset(), because Aztec's is hopelessly broken. Also + * gmtime(), which localtime() calls. + * 12 Apr 96, Paul Kienitz, daylight savings was being handled incorrectly. + * 21 Apr 96, Paul Kienitz, had to replace time() as well, Aztec's returns + * local time instead of GMT. That's why their localtime() was bad, + * because it assumed time_t was already local, and gmtime() was + * the one that checked TZ. + * 23 Apr 96, Chr. Spieler, deactivated time() replacement for UnZip stuff. + * Currently, the UnZip sources do not make use of time() (and do + * not supply the working mktime() replacement, either!). + * 29 Apr 96, Paul Kienitz, created a replacement getenv() out of code that + * was previously embedded in tzset(), for reliable global test + * of whether TZ is set or not. + * 19 Jun 96, Haidinger Walter, re-adapted for current SAS/C compiler. + * 7 Jul 96, Paul Kienitz, smoothed together compiler-related changes. + * 4 Feb 97, Haidinger Walter, added set_TZ() for SAS/C. + * 23 Apr 97, Paul Kienitz, corrected Unix->Amiga DST error by adding + * mkgmtime() so localtime() could be used. + * 28 Apr 97, Christian Spieler, deactivated mkgmtime() definition for ZIP; + * the Zip sources supply this function as part of util.c. + * 24 May 97, Haidinger Walter, added time_lib support for SAS/C and moved + * set_TZ() to time_lib.c. + * 12 Jul 97, Paul Kienitz, adapted time_lib stuff for Aztec. + * 26 Jul 97, Chr. Spieler, old mkgmtime() fixed (ydays[] def, sign vs unsign). + * 30 Dec 97, Haidinger Walter, adaptation for SAS/C using z-stat.h functions. + * 19 Feb 98, Haidinger Walter, removed alloc_remember, more SAS.C fixes. + * 23 Apr 98, Chr. Spieler, removed mkgmtime(), changed FileDate to convert to + * Amiga file-time directly. + * 24 Apr 98, Paul Kienitz, clip Unix dates earlier than 1978 in FileDate(). + * 02 Sep 98, Paul Kienitz, C. Spieler, always include zip.h to get a defined + * header inclusion sequence that resolves all header dependencies. + * 06 Jun 00, Paul Kienitz, removed time_lib.c due to its incompatible license, + * moved set_TZ() back here, replaced minimal tzset() and localtime() + * with new versions derived from GNU glibc source. Gave locale_TZ() + * reasonable European defaults for daylight savings. + * 17 Jun 00, Paul Kienitz, threw out GNU code because of objections to the GPL + * virus, replaced with similar functions based on the public domain + * timezone code at ftp://elsie.nci.nih.gov/pub. As with the GNU + * stuff, support for timezone files and leap seconds was removed. + * 23 Aug 00, Paul Kienitz, moved timezone code out from here into separate + * platform-independent module 'timezone.c'. + * 31 Dec 00, Christian Spieler, moved system-specific timezone help funcions + * back in here, from 'timezone.c'. + * 07 Jan 01, Paul Kienitz, Chr. Spieler, added missing #include "timezone.h" + * and "symbolic" preprocessor constants for time calculations. + * 15 Jan 02, Paul Kienitz, excluded all time handling code from compilation + * for Zip utilities (when "defined(UTIL)") + */ + +#ifndef __amiga_filedate_c +#define __amiga_filedate_c + + +#include "zip.h" +#include +#include + +#include +#include +#include +#include + +#ifdef AZTEC_C +# include +# include +# include +# include +# include +# include +# include +# include +# define ESRCH ENOENT +# define EOSERR EIO +#endif + +#ifdef __SASC +# include +# if (defined(_M68020) && (!defined(__USE_SYSBASE))) + /* on 68020 or higher processors it is faster */ +# define __USE_SYSBASE /* to use the pragma libcall instead of syscall */ +# endif /* to access functions of the exec.library */ +# include /* see SAS/C manual:part 2,chapter 2,pages 6-7 */ +# include +# include +# ifdef DEBUG +# include +# endif +# ifdef MWDEBUG +# include /* include both before memwatch.h again just */ +# include /* to be safe */ +# include "memwatch.h" +# endif /* MWDEBUG */ +#endif /* __SASC */ + +#include "crypt.h" /* just so we can tell if CRYPT is supported */ + + +#if (!defined(FUNZIP) && !defined(UTIL)) + +#include "timezone.h" /* for AMIGA-specific timezone callbacks */ + +#ifndef SUCCESS +# define SUCCESS (-1L) +# define FAILURE 0L +#endif + +#define ReqVers 36L /* required library version for SetFileDate() */ +#define ENVSIZE 100 /* max space allowed for an environment var */ + +extern struct ExecBase *SysBase; + +#ifndef min +# define min(a, b) ((a) < (b) ? (a) : (b)) +# define max(a, b) ((a) < (b) ? (b) : (a)) +#endif + +#if defined(ZIP) || defined(HAVE_MKTIME) +static const unsigned short ydays[] = + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; +#else +extern const unsigned short ydays[]; /* in unzip's fileio.c */ +#endif + +#define LEAP(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0) +#define YDAYS(m, y) (ydays[m] + (m > 1 && LEAP(y))) +/* Number of leap years from 1978 to `y' (not including `y' itself). */ +#define ANLEAP(y) (((y) - 1977) / 4 - ((y) - 1901) / 100 + ((y) - 1601) / 400) +#define SECSPERMIN 60 +#define MINSPERHOUR 60 +#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) +#define SECSPERDAY 86400L + +/* prototypes */ +char *getenv(const char *var); +#ifdef __SASC +/* XXX !! We have really got to find a way to operate without these. */ +int setenv(const char *var, const char *value, int overwrite); +void set_TZ(long time_zone, int day_light); +#endif + +LONG FileDate(char *filename, time_t u[]); +LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs); +int Agetch(void); + +/* =============================================================== */ + +/***********************/ +/* Function filedate() */ +/***********************/ + +/* FileDate() (originally utime.c), by Paul Wells. Modified by John Bush + * and others (see also sendpkt() comments, below); NewtWare SetFileDate() + * clone cheaply ripped off from utime(). + */ + +/* DESCRIPTION + * This routine chooses between 2 methods to set the file date on AMIGA. + * Since AmigaDOS 2.x came out, SetFileDate() was available in ROM (v.36 + * and higher). Under AmigaDOS 1.3.x (less than v.36 ROM), SetFileDate() + * must be accomplished by constructing a message packet and sending it + * to the file system handler of the file to be stamped. + * + * The system's ROM version is extracted from the external system Library + * base. + * + * NOTE: although argument passing conforms with utime(), note the + * following differences: + * - Return value is boolean success/failure. + * - If a structure or array is passed, only the first value + * is used, which *may* correspond to date accessed and not + * date modified. + */ + +LONG FileDate(filename, u) + char *filename; + time_t u[]; +{ + LONG SetFileDate(UBYTE *filename, struct DateStamp *pDate); + LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs); + struct MsgPort *taskport; + BPTR dirlock, lock; + struct FileInfoBlock *fib; + LONG pktargs[4]; + UBYTE *ptr; + long ret; + + struct DateStamp pDate; + struct tm *ltm; + int years; + + tzset(); + /* Amiga file date is based on 01-Jan-1978 00:00:00 (local time): + * 8 years and 2 leapdays difference from Unix time. + */ + ltm = localtime(&u[0]); + years = ltm->tm_year + 1900; + if (years < 1978) + pDate.ds_Days = pDate.ds_Minute = pDate.ds_Tick = 0; + else { + pDate.ds_Days = (years - 1978) * 365L + (ANLEAP(years)) + + YDAYS(ltm->tm_mon, years) + (ltm->tm_mday - 1); + pDate.ds_Minute = ltm->tm_hour * 60 + ltm->tm_min; + pDate.ds_Tick = ltm->tm_sec * TICKS_PER_SECOND; + } + + if (SysBase->LibNode.lib_Version >= ReqVers) + { + return (SetFileDate(filename,&pDate)); /* native routine at 2.0+ */ + } + else /* !(SysBase->lib_Version >=ReqVers) */ + { + if( !(taskport = (struct MsgPort *)DeviceProc(filename)) ) + { + errno = ESRCH; /* no such process */ + return FAILURE; + } + + if( !(lock = Lock(filename,SHARED_LOCK)) ) + { + errno = ENOENT; /* no such file */ + return FAILURE; + } + + if( !(fib = (struct FileInfoBlock *)AllocMem( + (long)sizeof(struct FileInfoBlock),MEMF_PUBLIC|MEMF_CLEAR)) ) + { + errno = ENOMEM; /* insufficient memory */ + UnLock(lock); + return FAILURE; + } + + if( Examine(lock,fib)==FAILURE ) + { + errno = EOSERR; /* operating system error */ + UnLock(lock); + FreeMem(fib,(long)sizeof(*fib)); + return FAILURE; + } + + dirlock = ParentDir(lock); + ptr = (UBYTE *)AllocMem(64L,MEMF_PUBLIC); + strcpy((ptr+1),fib->fib_FileName); + *ptr = strlen(fib->fib_FileName); + FreeMem(fib,(long)sizeof(*fib)); + UnLock(lock); + + /* now fill in argument array */ + + pktargs[0] = 0; + pktargs[1] = (LONG)dirlock; + pktargs[2] = (LONG)&ptr[0] >> 2; + pktargs[3] = (LONG)&pDate; + + errno = ret = sendpkt(taskport,ACTION_SET_DATE,pktargs,4L); + + FreeMem(ptr,64L); + UnLock(dirlock); + + return SUCCESS; + } /* ?(SysBase->lib_Version >= ReqVers) */ +} /* FileDate() */ + + +char *getenv(const char *var) /* not reentrant! */ +{ + static char space[ENVSIZE]; + struct Process *me = (void *) FindTask(NULL); + void *old_window = me->pr_WindowPtr; + char *ret = NULL; + + me->pr_WindowPtr = (void *) -1; /* suppress any "Please insert" popups */ + if (SysBase->LibNode.lib_Version >= ReqVers) { + if (GetVar((char *) var, space, ENVSIZE - 1, /*GVF_GLOBAL_ONLY*/ 0) > 0) + ret = space; + } else { /* early AmigaDOS, get env var the crude way */ + BPTR hand, foot, spine; + int z = 0; + if (foot = Lock("ENV:", ACCESS_READ)) { + spine = CurrentDir(foot); + if (hand = Open((char *) var, MODE_OLDFILE)) { + z = Read(hand, space, ENVSIZE - 1); + Close(hand); + } + UnLock(CurrentDir(spine)); + } + if (z > 0) { + space[z] = '\0'; + ret = space; + } + } + me->pr_WindowPtr = old_window; + return ret; +} + +#ifdef __SASC +int setenv(const char *var, const char *value, int overwrite) +{ + struct Process *me = (void *) FindTask(NULL); + void *old_window = me->pr_WindowPtr; + int ret = -1; + + me->pr_WindowPtr = (void *) -1; /* suppress any "Please insert" popups */ + if (SysBase->LibNode.lib_Version >= ReqVers) + ret = !SetVar((char *)var, (char *)value, -1, GVF_GLOBAL_ONLY | LV_VAR); + else { + BPTR hand, foot, spine; + long len = value ? strlen(value) : 0; + if (foot = Lock("ENV:", ACCESS_READ)) { + spine = CurrentDir(foot); + if (len) { + if (hand = Open((char *) var, MODE_NEWFILE)) { + ret = Write(hand, (char *) value, len + 1) >= len; + Close(hand); + } + } else + ret = DeleteFile((char *) var); + UnLock(CurrentDir(spine)); + } + } + me->pr_WindowPtr = old_window; + return ret; +} + +/* Stores data from timezone and daylight to ENV:TZ. */ +/* ENV:TZ is required to exist by some other SAS/C library functions, */ +/* like stat() or fstat(). */ +void set_TZ(long time_zone, int day_light) +{ + char put_tz[MAXTIMEZONELEN]; /* string for putenv: "TZ=aaabbb:bb:bbccc" */ + int offset; + void *exists; /* dummy ptr to see if global envvar TZ already exists */ + exists = (void *)getenv(TZ_ENVVAR); + /* see if there is already an envvar TZ_ENVVAR. If not, create it */ + if (exists == NULL) { + /* create TZ string by pieces: */ + sprintf(put_tz, "GMT%+ld", time_zone / 3600L); + if (time_zone % 3600L) { + offset = (int) labs(time_zone % 3600L); + sprintf(put_tz + strlen(put_tz), ":%02d", offset / 60); + if (offset % 60) + sprintf(put_tz + strlen(put_tz), ":%02d", offset % 60); + } + if (day_light) + strcat(put_tz,"DST"); + setenv(TZ_ENVVAR, put_tz, 1); + } +} +#endif /* __SASC */ + +/* set state as well as possible from settings found in locale.library */ +int GetPlatformLocalTimezone(sp, fill_tzstate_from_rules) + register struct state * ZCONST sp; + void (*fill_tzstate_from_rules)(struct state * ZCONST sp_res, + ZCONST struct rule * ZCONST start, + ZCONST struct rule * ZCONST end); +{ + struct Library *LocaleBase; + struct Locale *ll; + struct Process *me = (void *) FindTask(NULL); + void *old_window = me->pr_WindowPtr; + BPTR eh; + int z, valid = FALSE; + + /* read timezone from locale.library if TZ envvar missing */ + me->pr_WindowPtr = (void *) -1; /* suppress any "Please insert" popups */ + if (LocaleBase = OpenLibrary("locale.library", 0)) { + if (ll = OpenLocale(NULL)) { + z = ll->loc_GMTOffset; /* in minutes */ + if (z == -300) { + if (eh = Lock("ENV:sys/locale.prefs", ACCESS_READ)) { + UnLock(eh); + valid = TRUE; + } else + z = 300; /* bug: locale not initialized, default bogus! */ + } else + valid = TRUE; + if (valid) { + struct rule startrule, stoprule; + + sp->timecnt = 0; + sp->typecnt = 1; + sp->charcnt = 2; + sp->chars[0] = sp->chars[1] = '\0'; + sp->ttis[0].tt_abbrind = 0; + sp->ttis[1].tt_abbrind = 1; + sp->ttis[0].tt_gmtoff = -z * MINSPERHOUR; + sp->ttis[1].tt_gmtoff = -z * MINSPERHOUR + SECSPERHOUR; + sp->ttis[0].tt_isdst = 0; + sp->ttis[1].tt_isdst = 1; + stoprule.r_type = MONTH_NTH_DAY_OF_WEEK; + stoprule.r_day = 0; + stoprule.r_week = 5; + stoprule.r_mon = 10; + stoprule.r_time = 2 * SECSPERHOUR; + startrule = stoprule; + startrule.r_mon = 4; + startrule.r_week = 1; + if (z >= -180 && z < 150) { + /* At this point we make a really gratuitous assumption: */ + /* if the time zone could be Europe, we use the European */ + /* Union rules without checking what country we're in. */ + /* The AmigaDOS locale country codes do not, at least in */ + /* 2.x versions of the OS, recognize very many countries */ + /* outside of Europe and North America. */ + sp->typecnt = 2; + startrule.r_mon = 3; /* one week earlier than US DST */ + startrule.r_week = 5; + } else if (z >= 150 && z <= 480 && + /* no DST in alaska, hawaii */ + (ll->loc_CountryCode == 0x55534100 /*"USA"*/ || + ll->loc_CountryCode == 0x43414E00 /*"CAN"*/)) + sp->typecnt = 2; + /* We check the country code for U.S. or Canada because */ + /* most of Latin America has no DST. Even in these two */ + /* countries there are some exceptions... */ + /* else if... Feel free to add more cases here! */ + + if (sp->typecnt > 1) + (*fill_tzstate_from_rules)(sp, &startrule, &stoprule); + } + CloseLocale(ll); + } + CloseLibrary(LocaleBase); + } + me->pr_WindowPtr = old_window; + return valid; +} + +#ifdef ZIP +time_t time(time_t *tp) +{ + time_t t; + struct DateStamp ds; + DateStamp(&ds); + t = ds.ds_Tick / TICKS_PER_SECOND + ds.ds_Minute * 60 + + (ds.ds_Days + 2922) * SECSPERDAY; + t = mktime(gmtime(&t)); + /* gmtime leaves ds in the local timezone, mktime converts it to GMT */ + if (tp) *tp = t; + return t; +} +#endif /* ZIP */ + +#endif /* !FUNZIP && !UTIL */ + + +#if CRYPT || !defined(FUNZIP) + +/* sendpkt.c + * by A. Finkel, P. Lindsay, C. Sheppner + * returns Res1 of the reply packet + */ +/* +#include +#include +#include +#include +#include +#include +*/ + +LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs); + +LONG sendpkt(pid,action,args,nargs) +struct MsgPort *pid; /* process identifier (handler message port) */ +LONG action, /* packet type (desired action) */ + *args, /* a pointer to argument list */ + nargs; /* number of arguments in list */ +{ + + struct MsgPort *replyport, *CreatePort(UBYTE *, long); + void DeletePort(struct MsgPort *); + struct StandardPacket *packet; + LONG count, *pargs, res1; + + replyport = CreatePort(NULL,0L); + if( !replyport ) return(0); + + packet = (struct StandardPacket *)AllocMem( + (long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR); + if( !packet ) + { + DeletePort(replyport); + return(0); + } + + packet->sp_Msg.mn_Node.ln_Name = (char *)&(packet->sp_Pkt); + packet->sp_Pkt.dp_Link = &(packet->sp_Msg); + packet->sp_Pkt.dp_Port = replyport; + packet->sp_Pkt.dp_Type = action; + + /* copy the args into the packet */ + pargs = &(packet->sp_Pkt.dp_Arg1); /* address of 1st argument */ + for( count=0; countsp_Pkt.dp_Res1; + + FreeMem((char *)packet,(long)sizeof(*packet)); + DeletePort(replyport); + + return(res1); + +} /* sendpkt() */ + +#endif /* CRYPT || !FUNZIP */ + + +#if CRYPT || (defined(UNZIP) && !defined(FUNZIP)) + +/* Agetch() reads one raw keystroke -- uses sendpkt() */ + +int Agetch(void) +{ + LONG sendpkt(struct MsgPort *pid, LONG action, LONG *args, LONG nargs); + struct Task *me = FindTask(NULL); + struct CommandLineInterface *cli = BADDR(((struct Process *) me)->pr_CLI); + BPTR fh = cli->cli_StandardInput; /* this is immune to < redirection */ + void *conp = ((struct FileHandle *) BADDR(fh))->fh_Type; + char longspace[8]; + long *flag = (long *) ((ULONG) &longspace[4] & ~3); /* LONGWORD ALIGNED! */ + UBYTE c; + + *flag = 1; + sendpkt(conp, ACTION_SCREEN_MODE, flag, 1); /* assume success */ + Read(fh, &c, 1); + *flag = 0; + sendpkt(conp, ACTION_SCREEN_MODE, flag, 1); + if (c == 3) /* ^C in input */ + Signal(me, SIGBREAKF_CTRL_C); + return c; +} + +#endif /* CRYPT || (UNZIP && !FUNZIP) */ + +#endif /* __amiga_filedate_c*/ diff --git a/amiga/makefile.azt b/amiga/makefile.azt new file mode 100644 index 0000000..d9390c8 --- /dev/null +++ b/amiga/makefile.azt @@ -0,0 +1,304 @@ +# Makefile for Zip, ZipNote, ZipCloak, ZipSplit for Aztec C 5.2 +# Also ZipLM, a version of Zip that needs much less free memory +# -- Paul Kienitz, last updated 07 Jan 2007 + +# Make sure platform is defined correctly, and select memory usage options: +DEFINES = -d AMIGA -d DYN_ALLOC -d ASM_CRC + +CC = cc +AS = as +LD = ln +LDLIBS = -lc16 + + +# -------- RELEASE VERSION: +CFLAGS = -psb0e -sabfmnpu -wcr0u $(DEFINES) +# -pbs means unsigned chars and short ints, -sabfmnpu is various small +# optimizations, -wcr0u adjusts type checking strictness +ASOPTS = -n -eAMIGA -eDYN_ALLOC -eCPUTEST -eINT16 +LDFLAGS = -m +q + +# -------- DEBUG VERSION: +CFLAGD = -bs -psb0e -s0f0n -wcr0u $(DEFINES) +# -bs is include source debugging info, -s0f0n is avoid hard-to-debug +# optimizations +LDFLAGD = -m +q -g -w + +# -------- MINIMUM MEMORY USAGE RELEASE VERSION: +WSIZ = WSIZE=4096 +LOWFLAGS = $(CFLAGS) -d $(WSIZ) -d SMALL_MEM +LOWASOPTS = $(ASOPTS) -e$(WSIZ) -eSMALL_MEM +# Options used for assembling amiga/deflate.a; must generally match the +# settings in DEFINES. + +# -------- MINIMUM MEMORY USAGE DEBUG VERSION: +LOWFLAGD = $(CFLAGD) -d $(WSIZ) -d SMALL_MEM + +# the directory where we stick all the object files: +O = obA/ + + +# default C rules +.c.o : + $(CC) $(CFLAGS) -o $@ $*.c + +# rules for routines containing entries needed by utilities +.c.oo : + $(CC) $(CFLAGS) -d UTIL -o $@ $*.c + +# rules for the low-memory version: + +.c.ol : + $(CC) $(LOWFLAGS) -o $@ $*.c + +# default C rules for debugging +.c.od : + $(CC) $(CFLAGD) -o $@ $*.c + +# debugging rules for routines containing entries needed by utilities +.c.dd : + $(CC) $(CFLAGD) -d UTIL -o $@ $*.c + +# rules for the debugging low-memory version: + +.c.dl : + $(CC) $(LOWFLAGD) -o $@ $*.c + + +# object file lists + +ZIP_H = zip.h ziperr.h tailor.h amiga/osdep.h amiga/z-stat.h + + +OBJZ = $(O)zip.o $(O)deflate.o \ + $(O)trees.o $(O)zipfile.o $(O)zipup.o $(O)util.o $(O)timezone.o \ + $(O)fileio.o $(O)globals.o $(O)crc32.o $(O)crypt.o $(O)ttyio.o \ + $(O)amiga.o $(O)amigazip.o $(O)crc_68.o + +OBJL = $(O)zip.ol $(O)deflate.ol \ + $(O)trees.ol $(O)zipfile.ol $(O)zipup.ol $(O)util.ol $(O)timezone.ol \ + $(O)fileio.ol $(O)globals.ol $(O)crc32.ol $(O)crypt.ol $(O)ttyio.ol \ + $(O)amiga.ol $(O)amigazip.ol $(O)crc_68.o + +OBJU = $(O)zipfile.oo $(O)fileio.oo \ + $(O)util.oo $(O)globals.o $(O)amiga.oo $(O)amigazip.oo +OBJN = $(O)zipnote.o $(OBJU) +OBJC = $(O)zipcloak.o $(OBJU) $(O)crc32.oo \ + $(O)crypt.oo $(O)ttyio.o +OBJS = $(O)zipsplit.o $(OBJU) + +# These are the debuggable versions: + +DBJZ = $(O)zip.od $(O)deflate.od \ + $(O)trees.od $(O)zipfile.od $(O)zipup.od $(O)util.od $(O)timezone.od \ + $(O)fileio.od $(O)globals.od $(O)crc32.od $(O)crypt.od $(O)ttyio.od \ + $(O)amiga.od $(O)amigazip.od $(O)crc_68.o + +DBJL = $(O)zip.dl $(O)deflate.dl \ + $(O)trees.dl $(O)zipfile.dl $(O)zipup.dl $(O)util.dl $(O)timezone.dl \ + $(O)fileio.dl $(O)globals.dl $(O)crc32.dl $(O)crypt.dl $(O)ttyio.dl \ + $(O)amiga.dl $(O)amigazip.dl $(O)crc_68.o + +DBJU = $(O)zipfile.dd $(O)fileio.dd \ + $(O)util.dd $(O)globals.od $(O)amiga.dd $(O)amigazip.dd +DBJN = $(O)zipnote.od $(DBJU) +DBJC = $(O)zipcloak.od $(DBJU) $(O)crc32.dd \ + $(O)crypt.dd $(O)ttyio.od +DBJS = $(O)zipsplit.od $(DBJU) + + +# HERE WE GO: + +all : Zip ZipNote ZipSplit ZipCloak ZipLM + +z : Zip + +n : ZipNote + +s : ZipSplit + +c : ZipCloak + +l : ZipLM + +# Debug versions: + +dall : Zip.dbg ZipNote.dbg ZipSplit.dbg ZipCloak.dbg ZipLM.dbg + +dz : Zip.dbg + +dn : ZipNote.dbg + +ds : ZipSplit.dbg + +dc : ZipCloak.dbg + +dl : ZipLM.dbg + + +Zip : $(OBJZ) $(ZIP_H) + $(LD) $(LDFLAGS) -o $@ $(OBJZ) $(LDLIBS) + -@delete Zip.dbg + +ZipNote : $(OBJN) $(ZIP_H) + $(LD) $(LDFLAGS) -o $@ $(OBJN) $(LDLIBS) + -@delete ZipNote.dbg + +ZipSplit : $(OBJS) $(ZIP_H) + $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS) + -@delete ZipSplit.dbg + +ZipCloak : $(OBJC) $(ZIP_H) + $(LD) $(LDFLAGS) -o $@ $(OBJC) $(LDLIBS) + -@delete ZipCloak.dbg + +ZipLM : $(OBJL) $(ZIP_H) + $(LD) $(LDFLAGS) -o $@ $(OBJL) $(LDLIBS) + -@delete ZipLM.dbg + + +Zip.dbg : $(DBJZ) $(ZIP_H) + $(LD) $(LDFLAGD) -o Zip $(DBJZ) $(LDLIBS) + +ZipNote.dbg : $(DBJN) $(ZIP_H) + $(LD) $(LDFLAGD) -o ZipNote $(DBJN) $(LDLIBS) + +ZipSplit.dbg : $(DBJS) $(ZIP_H) + $(LD) $(LDFLAGD) -o ZipSplit $(DBJS) $(LDLIBS) + +ZipCloak.dbg : $(DBJC) $(ZIP_H) + $(LD) $(LDFLAGD) -o ZipCloak $(DBJC) $(LDLIBS) + +ZipLM.dbg : $(DBJL) $(ZIP_H) + $(LD) $(LDFLAGD) -o ZipLM $(DBJL) $(LDLIBS) + + +clean : bugclean + -delete quiet $(OBJZ) + -delete quiet $(OBJL) + -delete quiet $(O)zipnote.o $(O)zipcloak.o $(O)zipsplit.o \ + $(O)crypt.oo $(OBJU) + +bugclean : + -delete quiet $(DBJZ) + -delete quiet $(DBJL) + -delete quiet $(O)zipnote.od $(O)zipcloak.od $(O)zipsplit.od \ + $(O)crypt.dd $(DBJU) + +cleaner : clean + -delete quiet Zip ZipNote ZipSplit ZipCloak ZipLM + -delete quiet Zip.dbg ZipNote.dbg ZipSplit.dbg ZipCloak.dbg ZipLM.dbg + + +# header dependencies: + +$(O)zip.o $(O)zipnote.o $(O)zipcloak.o $(O)zipsplit.o $(O)crypt.o $(O)ttyio.o \ + $(O)deflate.o $(O)trees.o $(O)zipfile.o $(O)zipup.o $(O)fileio.o $(O)util.o \ + $(O)timezone.o $(O)crc32.o $(O)globals.o $(O)amiga.o : $(ZIP_H) + +$(O)zip.ol $(O)zipnote.ol $(O)zipcloak.ol $(O)zipsplit.ol $(O)crypt.ol \ + $(O)ttyio.ol $(O)deflate.ol $(O)trees.ol $(O)zipfile.ol $(O)zipup.ol \ + $(O)fileio.ol $(O)util.ol $(O)timezone.ol $(O)crc32.ol $(O)globals.ol \ + $(O)amiga.ol : $(ZIP_H) + +$(O)crc32.oo $(O)crypt.oo $(O)zipfile.oo $(O)fileio.oo $(O)util.oo : $(ZIP_H) + +$(O)amigazip.o $(O)amigazip.ol $(O)amigazip.oo : amiga/amiga.h $(ZIP_H) + +$(O)zip.o $(O)zipnote.o $(O)zipcloak.o $(O)zipsplit.o $(O)zipup.o \ + $(O)zip.ol $(O)zipnote.ol $(O)zipcloak.ol $(O)zipsplit.ol \ + $(O)zipup.ol : revision.h + +$(O)amiga.o $(O)amiga.ol : crypt.h + +$(O)crc32.o $(O)crc32.oo $(O)crc32.ol $(O)crypt.o $(O)crypt.oo $(O)crypt.ol \ + $(O)zipcloak.o $(O)zipcloak.ol $(O)zip.o $(O)zip.ol \ + $(O)zipup.o $(O)zipup.ol \ + $(O)zipfile.o $(O)zipfile.oo $(O)zipfile.ol \ + $(O)fileio.o $(O)fileio.oo $(O)fileio.ol : crc32.h + +$(O)crypt.o $(O)crypt.oo $(O)crypt.ol $(O)ttyio.o $(O)ttyio.ol \ + $(O)zipcloak.o $(O)zipcloak.ol $(O)zip.o $(O)zip.ol \ + $(O)zipup.o $(O)zipup.ol : crypt.h ttyio.h + +$(O)timezone.o $(O)timezone.ol $(O)timezone.od $(O)timezone.dl \ + $(O)amiga.o $(O)amiga.ol $(O)amiga.oo : timezone.h + +$(O)zipup.o $(O)zipup.ol : amiga/zipup.h + + +# SPECIAL CASES: + +# -mr changes expression parsing; avoids a bogus "expression too complex" error: +$(O)trees.o : trees.c + $(CC) $(CFLAGS) -mr -o $@ trees.c + +$(O)trees.ol : trees.c + $(CC) $(LOWFLAGS) -mr -o $@ trees.c + +$(O)trees.od : trees.c + $(CC) $(CFLAGD) -mr -o $@ trees.c + +$(O)trees.ld : trees.c + $(CC) $(LOWFLAGD) -mr -o $@ trees.c + +# Substitute the assembly version of deflate.c: (but not in debug version) +$(O)deflate.o : amiga/deflate.a + $(AS) $(ASOPTS) -o $@ amiga/deflate.a + +$(O)deflate.ol : amiga/deflate.a + $(AS) $(LOWASOPTS) -o $@ amiga/deflate.a + +# The assembly CRC function: +$(O)crc_68.o : amiga/crc_68.a + $(AS) -n -o $@ amiga/crc_68.a + +# Put the Amiga internal version data with today's date into amiga.c: +$(O)amiga.o : amiga/amiga.c amiga/filedate.c amiga/stat.c + rx > env:VersionDate "say '""'translate(date('E'), '.', '/')'""'" + $(CC) $(CFLAGS) -o $@ amiga/amiga.c + delete env:VersionDate + +$(O)amiga.ol : amiga/amiga.c amiga/filedate.c amiga/stat.c + rx > env:VersionDate "say '""'translate(date('E'), '.', '/')'""'" + $(CC) $(LOWFLAGS) -o $@ amiga/amiga.c + delete env:VersionDate + +$(O)amiga.od : amiga/amiga.c amiga/filedate.c amiga/stat.c + rx > env:VersionDate "say '""'translate(date('E'), '.', '/')'""'" + $(CC) $(CFLAGD) -o $@ amiga/amiga.c + delete env:VersionDate + +$(O)amiga.ld : amiga/amiga.c amiga/filedate.c amiga/stat.c + rx > env:VersionDate "say '""'translate(date('E'), '.', '/')'""'" + $(CC) $(LOWFLAGD) -o $@ amiga/amiga.c + delete env:VersionDate + +$(O)amiga.oo : amiga/amiga.c amiga/filedate.c amiga/stat.c + rx > env:VersionDate "say '""'translate(date('E'), '.', '/')'""'" + $(CC) $(CFLAGS) -d UTIL -o $@ amiga/amiga.c + delete env:VersionDate + +$(O)amiga.dd : amiga/amiga.c amiga/filedate.c amiga/stat.c + rx > env:VersionDate "say '""'translate(date('E'), '.', '/')'""'" + $(CC) $(CFLAGD) -d UTIL -o $@ amiga/amiga.c + delete env:VersionDate + +# Put the compiler version number into amigazip.c: +$(O)amigazip.o : amiga/amigazip.c + $(CC) $(CFLAGS) -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c + +$(O)amigazip.ol : amiga/amigazip.c + $(CC) $(LOWFLAGS) -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c + +$(O)amigazip.od : amiga/amigazip.c + $(CC) $(CFLAGD) -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c + +$(O)amigazip.ld : amiga/amigazip.c + $(CC) $(LOWFLAGD) -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c + +$(O)amigazip.oo : amiga/amigazip.c + $(CC) $(CFLAGS) -d UTIL -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c + +$(O)amigazip.dd : amiga/amigazip.c + $(CC) $(CFLAGD) -d UTIL -o $@ -d __VERSION__=5 -d __REVISION__=2 amiga/amigazip.c diff --git a/amiga/match.a b/amiga/match.a new file mode 100644 index 0000000..ec5bcf0 --- /dev/null +++ b/amiga/match.a @@ -0,0 +1,182 @@ +;=========================================================================== +; Copyright (c) 1990-1999 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 1999-Oct-05 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, both of these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +;=========================================================================== +; match.a -- optional optimized asm version of longest match in deflate.c +; Written by Jean-loup Gailly +; Adapted for the Amiga by Carsten Steger +; using the code in match.S. +; The major change in this code consists of removing all unaligned +; word accesses, because they cause 68000-based Amigas to crash. +; For maximum speed, UNALIGNED_OK can be defined in Makefile.sasc. +; The program will then only run on 68020-based Amigas, though. +; If you have reduced WSIZE in zip.h, then make sure this is +; assembled with an equivalent -dWSIZE=. +; +; This code will run with registerized parameters too, unless SAS +; changes parameter passing conventions between new releases of SAS/C. + + +Cur_Match reg d0 ; Must be in d0! +Best_Len reg d1 +Loop_Counter reg d2 +Scan_Start reg d3 +Scan_End reg d4 +Limit reg d5 +Chain_Length reg d6 +Scan_Test reg d7 +Scan reg a0 +Match reg a1 +Prev_Address reg a2 +Scan_Ini reg a3 +Match_Ini reg a4 + +MAX_MATCH equ 258 +MIN_MATCH equ 3 + ifnd WSIZE +WSIZE equ 32768 + endc +MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1 + + + xref _max_chain_length + xref _prev_length + xref _prev + xref _window + xref _strstart + xref _good_match + xref _match_start + xref _nice_match + + + section match,code + + xdef _match_init + xdef @match_init + xdef _longest_match + xdef @longest_match + + +_match_init: +@match_init: + rts + + +_longest_match: + move.l 4(sp),Cur_Match +@longest_match: + ifd UNALIGNED_OK + movem.l d2-d6/a2-a4,-(sp) + else + movem.l d2-d7/a2-a4,-(sp) + endc + move.l _max_chain_length,Chain_Length + move.l _prev_length,Best_Len + lea _prev,Prev_Address + lea _window+MIN_MATCH,Match_Ini + move.l _strstart,Limit + move.l Match_Ini,Scan_Ini + add.l Limit,Scan_Ini + subi.w #MAX_DIST,Limit + bhi.b limit_ok + moveq #0,Limit +limit_ok: + cmp.l _good_match,Best_Len + bcs.b length_ok + lsr.l #2,Chain_Length +length_ok: + subq.l #1,Chain_Length + + ifd UNALIGNED_OK + + move.w -MIN_MATCH(Scan_Ini),Scan_Start + move.w -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End + + else + + move.b -MIN_MATCH(Scan_Ini),Scan_Start + lsl.w #8,Scan_Start + move.b -MIN_MATCH+1(Scan_Ini),Scan_Start + move.b -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End + lsl.w #8,Scan_End + move.b -MIN_MATCH(Scan_Ini,Best_Len.L),Scan_End + + endc + + bra.b do_scan + +long_loop: + + ifd UNALIGNED_OK + + move.w -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End + + else + + move.b -MIN_MATCH-1(Scan_Ini,Best_Len.L),Scan_End + lsl.w #8,Scan_End + move.b -MIN_MATCH(Scan_Ini,Best_Len.L),Scan_End + + endc + +short_loop: + lsl.w #1,Cur_Match + move.w 0(Prev_Address,Cur_Match.L),Cur_Match + cmp.w Limit,Cur_Match + dbls Chain_Length,do_scan + bra.b return + +do_scan: + move.l Match_Ini,Match + add.l Cur_Match,Match + + ifd UNALIGNED_OK + + cmp.w -MIN_MATCH-1(Match,Best_Len.L),Scan_End + bne.b short_loop + cmp.w -MIN_MATCH(Match),Scan_Start + bne.b short_loop + + else + + move.b -MIN_MATCH-1(Match,Best_Len.L),Scan_Test + lsl.w #8,Scan_Test + move.b -MIN_MATCH(Match,Best_Len.L),Scan_Test + cmp.w Scan_Test,Scan_End + bne.b short_loop + move.b -MIN_MATCH(Match),Scan_Test + lsl.w #8,Scan_Test + move.b -MIN_MATCH+1(Match),Scan_Test + cmp.w Scan_Test,Scan_Start + bne.b short_loop + + endc + + move.w #(MAX_MATCH-MIN_MATCH),Loop_Counter + move.l Scan_Ini,Scan +scan_loop: + cmpm.b (Match)+,(Scan)+ + dbne Loop_Counter,scan_loop + + sub.l Scan_Ini,Scan + addq.l #(MIN_MATCH-1),Scan + cmp.l Best_Len,Scan + bls.b short_loop + move.l Scan,Best_Len + move.l Cur_Match,_match_start + cmp.l _nice_match,Best_Len + bcs.b long_loop +return: + move.l Best_Len,d0 + ifd UNALIGNED_OK + movem.l (sp)+,d2-d6/a2-a4 + else + movem.l (sp)+,d2-d7/a2-a4 + endc + rts + + end diff --git a/amiga/match_68.a b/amiga/match_68.a new file mode 100644 index 0000000..d1a6c39 --- /dev/null +++ b/amiga/match_68.a @@ -0,0 +1,273 @@ +;=========================================================================== +; Copyright (c) 1990-1999 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 1999-Oct-05 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, both of these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +;=========================================================================== +; This is a 68000 assembly language version of the Zip function +; longest_match(). It is written for any 680x0 based computer, but at this +; time the feature for runtime testing of CPU type is only supported for the +; Amiga. Hopefully a similar test for the Macintosh is possible, and for any +; other system that supports both 68000 and 68020+ CPUs. This is written by +; Paul Kienitz, partially derived from a simpler version by Carsten Steger, +; derived in turn from a 386 assembly function by Jean-loup Gailly and Kai Uwe +; Rommel... but also based directly on the C original. +; +; The main difference of this from other longest_match() implementations is +; that it includes both byte based and word based versions of the function, +; and various symbols can be defined to select whether to use one routine or +; the other, or to do a platform-specific test at runtime. The symbols that +; can be used to select behavior are as follows: +; +; CPU020 if defined, use 68020 instructions always +; CPUTEST if defined, check at runtime for CPU type. Another symbol +; specifying the platform-specific test must be used with this. +; If neither of these is defined, use 68000 instructions only. +; AMIGA use Amiga-specific test for 68020, if CPUTEST defined. Also +; tells it to let a0/a1/d1 be clobbered by functions. +; ATSIGN define entry symbols in @foo form as well as _foo, with +; @longest_match taking its parm in d0 instead of on the stack. +; WSIZE if defined, determines the sliding window size for deflate; +; the default is 32K. If you have reduced WSIZE for the C code, +; make sure that this module is assembled with an equivalent +; "-dWSIZE=" (or "-e...") switch. +; +; NOTE: no provision is made for 16 bit ints. All external int variables are +; treated as 32 bit values. This also assumes that longest_match's result is +; returned in D0. + + IFND CPU020 + IFND CPUTEST +CPU000 equ 1 + ENDC + ENDC + +; global variables: + xref _max_chain_length ; unsigned int + xref _prev_length ; unsigned int + xref _match_start ; unsigned int + xref _strstart ; unsigned int + xref _good_match ; signed int + xref _nice_match ; signed int + xref _window ; array of unsigned char + xref _prev ; array of unsigned short + +; our entry points: + xdef _match_init ; void match_init(void); + xdef _longest_match ; int longest_match(unsigned cur_match); + IFD ATSIGN + xdef @match_init ; for SAS assembler + xdef @longest_match ; ditto + ENDC + +; flag variable for remembering CPU type: + IFD CPUTEST + section cpuflag,data +is020: ds.w 1 + ENDC + + + section match,code +_match_init: + IFD ATSIGN +@match_init: + ENDC + + IFD CPUTEST ; now check for platform type + IFD AMIGA ; Amiga specific test for '020 CPU: + + xref _SysBase + + NOLIST + INCLUDE 'exec/execbase.i' + LIST + + clr.w is020 ; default value is 68000 + move.l _SysBase,a0 + btst #AFB_68020,AttnFlags+1(a0) + beq.s cheap + move.w #1,is020 + +cheap: + ELSE ; !AMIGA + + !! Write an '020-detector for your system here! + + ENDC ; AMIGA + ENDC ; CPUTEST + rts ; match_init consists only of rts if CPUTEST unset + + + IFD AMIGA +SAVEREGS reg d3-d7/a2/a3/a5 ; don't protect d0/d1/a0/a1 + ELSE +SAVEREGS reg d1/d3-d7/a0-a3/a5 ; protect all but d0 return val + ENDC + +Cur_Match equr d0 ; Must be in d0! +Best_Len equr d1 +Scan_Start equr d3 +Scan_End equr d4 +Limit equr d5 +Chain_Length equr d6 +Scan_Test equr d7 +Scan equr a0 +Match equr a1 +Prev_Address equr a2 +Scan_Ini equr a3 +Match_Ini equr a5 + + +MAX_MATCH equ 258 +MIN_MATCH equ 3 + IFND WSIZE +WSIZE equ 32768 + ENDC +MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1 + +_longest_match: + move.l 4(sp),Cur_Match ; stack arg to register + IFD ATSIGN +@longest_match: + ENDC + movem.l SAVEREGS,-(sp) + +; setup steps common to byte and word versions: + move.l _max_chain_length,Chain_Length + move.l _prev_length,Best_Len + lea _prev,Prev_Address + lea _window,Match_Ini + move.l _strstart,Limit + move.l Match_Ini,Scan_Ini + addq #MIN_MATCH,Match_Ini + add.l Limit,Scan_Ini + subi.w #MAX_DIST,Limit + bhi.s limit_ok + moveq #0,Limit +limit_ok: + cmp.l _good_match,Best_Len + bcs.s length_ok + lsr.l #2,Chain_Length +length_ok: + subq.l #1,Chain_Length + + IFD CPUTEST + tst.w is020 ; can we use '020 stuff today? + bne WORD_match + ENDC + + IFND CPU020 + +; for 68000 or 68010, use byte operations: + moveq #0,Scan_Start ; clear 2nd and 4th bytes, use 1st & 3rd + moveq #0,Scan_End + moveq #0,Scan_Test + move.b (Scan_Ini),Scan_Start + swap Scan_Start + move.b 1(Scan_Ini),Scan_Start + move.b -1(Scan_Ini,Best_Len),Scan_End + swap Scan_End + move.b 0(Scan_Ini,Best_Len),Scan_End + bra.s bdo_scan + +blong_loop: + move.b -1(Scan_Ini,Best_Len),Scan_End + swap Scan_End + move.b 0(Scan_Ini,Best_Len),Scan_End + +bshort_loop: + add.w Cur_Match,Cur_Match + move.w 0(Prev_Address,Cur_Match.l),Cur_Match + cmp.l Limit,Cur_Match + dbls Chain_Length,bdo_scan + bra return + +bdo_scan: + move.l Match_Ini,Match + add.l Cur_Match,Match + move.b -MIN_MATCH-1(Match,Best_Len),Scan_Test + swap Scan_Test + move.b -MIN_MATCH(Match,Best_Len),Scan_Test + cmp.l Scan_Test,Scan_End + bne.s bshort_loop + move.b -MIN_MATCH(Match),Scan_Test + swap Scan_Test + move.b -MIN_MATCH+1(Match),Scan_Test + cmp.l Scan_Test,Scan_Start + bne.s bshort_loop + move.w #(MAX_MATCH-MIN_MATCH),Scan_Test + lea MIN_MATCH(Scan_Ini),Scan + +bscan_loop: + cmpm.b (Match)+,(Scan)+ + dbne Scan_Test,bscan_loop + subq #1,Scan + + sub.l Scan_Ini,Scan + cmp.l Best_Len,Scan + bls.s bshort_loop + move.l Scan,Best_Len + move.l Cur_Match,_match_start + cmp.l _nice_match,Best_Len + bcs.s blong_loop + IFD CPUTEST + bra return + ENDC + + ENDC ; !CPU020 + + IFND CPU000 + +; for 68020 or higher, use word operations even on odd addresses: +WORD_match: + move.w (Scan_Ini),Scan_Start + move.w -1(Scan_Ini,Best_Len),Scan_End + bra.s wdo_scan + +wlong_loop: + move.w -1(Scan_Ini,Best_Len),Scan_End + +wshort_loop: + add.w Cur_Match,Cur_Match + move.w (Prev_Address,Cur_Match.l),Cur_Match + cmp.l Limit,Cur_Match + dbls Chain_Length,wdo_scan + bra.s return + +wdo_scan: + move.l Match_Ini,Match + add.l Cur_Match,Match + cmp.w -MIN_MATCH-1(Match,Best_Len),Scan_End + bne.s wshort_loop + cmp.w -MIN_MATCH(Match),Scan_Start + bne.s wshort_loop + moveq #((MAX_MATCH-MIN_MATCH)/2),Scan_Test ; value = 127 + lea MIN_MATCH(Scan_Ini),Scan + +wscan_loop: + cmpm.w (Match)+,(Scan)+ + dbne Scan_Test,wscan_loop + subq #2,Scan + move.b -MIN_MATCH+1(Match),Scan_Test + cmp.b (Scan),Scan_Test + bne steven + addq #1,Scan +steven: + sub.l Scan_Ini,Scan + cmp.l Best_Len,Scan + bls.s wshort_loop + move.l Scan,Best_Len + move.l Cur_Match,_match_start + cmp.l _nice_match,Best_Len + bcs.s wlong_loop + + ENDC ; !CPU000 + +return: + move.l Best_Len,d0 ; function return value + movem.l (sp)+,SAVEREGS + rts + + end diff --git a/amiga/osdep.h b/amiga/osdep.h new file mode 100644 index 0000000..c573cf8 --- /dev/null +++ b/amiga/osdep.h @@ -0,0 +1,119 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2005-Feb-10 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#ifndef __amiga_osdep_h +#define __amiga_osdep_h + +/* default to MEDIUM_MEM, but allow makefile override */ +#if ( (!defined(BIG_MEM)) && (!defined(SMALL_MEM))) +# define MEDIUM_MEM +#endif + +/* check that TZ environment variable is defined before using UTC times */ +#if (!defined(NO_IZ_CHECK_TZ) && !defined(IZ_CHECK_TZ)) +# define IZ_CHECK_TZ +#endif + +#ifndef IZTZ_GETLOCALETZINFO +# define IZTZ_GETLOCALETZINFO GetPlatformLocalTimezone +#endif + +/* AmigaDOS can't even support disk partitions over 4GB, let alone files */ +#define NO_LARGE_FILE_SUPPORT +#ifdef LARGE_FILE_SUPPORT +# undef LARGE_FILE_SUPPORT +#endif + +#define USE_CASE_MAP +#define USE_EF_UT_TIME +#define HANDLE_AMIGA_SFX +#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \ + procname(n, 1)) +#define EXIT(e) ClearIOErr_exit(e) +void ClearIOErr_exit(int e); + +#include "amiga/z-stat.h" + +#ifdef __SASC +# include +# include +# if (defined(_M68020) && (!defined(__USE_SYSBASE))) + /* on 68020 or higher processors it is faster */ +# define __USE_SYSBASE /* to use the pragma libcall instead of syscall */ +# endif /* to access functions of the exec.library */ +# include /* see SAS/C manual:part 2,chapter 2,pages 6-7 */ +# include +# if (defined(_M68020) && !defined(UNALIGNED_OK)) +# define UNALIGNED_OK +# endif +# ifndef REENTRANT +# define REENTRANT +# endif +# if (defined(_NEAR_DATA) && !defined(DYN_ALLOC)) +# define DYN_ALLOC +# endif +# ifdef DEBUG +# include /* profiler header file */ +# endif +# ifndef IZTZ_SETLOCALTZINFO + /* XXX !! We have really got to find a way to operate without these. */ +# define IZTZ_SETLOCALTZINFO +# endif + +/* + A word on short-integers and SAS/C (a bug of [mc]alloc?) + Using short integers (i.e. compiling with option SHORT-INTEGERS) is + *not* recommended. To get maximum compression ratio the window size stored + in WSIZE should be 32k (0x8000). However, since the size of the window[] + array is 2*WSIZE, 65536 bytes must be allocated. The calloc function can + only allocate UINT_MAX (defined in limits.h) bytes which is one byte short + (65535) of the maximum window size if you are compiling with short-ints. + You'll get an error message "Out of memory (window allocation)" whenever + you try to deflate. Note that the compiler won't produce any warning. + The maximum window size with short-integers is therefore 32768 bytes. + The following is only implemented to allow the use of short-integers but + it is once again not recommended because of a loss in compression ratio. +*/ +# if (defined(_SHORTINT) && !defined(WSIZE)) +# define WSIZE 0x4000 /* only half of maximum window size */ +# endif /* possible with short-integers */ +#endif /* __SASC */ +/* + With Aztec C, using short integers imposes no size limits and makes + the program run faster, even with 32 bit CPUs, so it's recommended. +*/ +#ifdef AZTEC_C +# define NO_UNISTD_H +# define NO_RMDIR +# define BROKEN_FSEEK +# ifndef IZTZ_DEFINESTDGLOBALS +# define IZTZ_DEFINESTDGLOBALS +# endif +#endif + +extern int real_timezone_is_set; +void tzset(void); +#define VALID_TIMEZONE(tempvar) (tzset(), real_timezone_is_set) + +#ifdef ZCRYPT_INTERNAL +# ifndef CLIB_EXEC_PROTOS_H + void *FindTask(void *); +# endif +# define ZCR_SEED2 (unsigned)(ulg)FindTask(NULL) +#endif + +int Agetch(void); /* getch() like function, in amiga/filedate.c */ +char *GetComment(char *); + +#define FOPR "rb" +#define FOPM "rb+" +#define FOPW "wb" +/* prototype for ctrl-C trap function */ +void _abort(void); + +#endif /* !__amiga_osdep_h */ diff --git a/amiga/smakefile b/amiga/smakefile new file mode 100644 index 0000000..ce1317d --- /dev/null +++ b/amiga/smakefile @@ -0,0 +1,662 @@ +#=========================================================================== +# Makefile for Zip, ZipNote, ZipCloak, ZipSplit AMIGA SAS/C Version 6.58 +# Version: 2.3 last revised: 07 Jan 2007 +#=========================================================================== +# -John Bush, +# or: + +# updated for SAS/C Version 6.56+ and AmigaDOS 3.1 (V40) +# by Haidinger Walter, + +# additional supplements and maintenance by Paul Kienitz + +# This makefile should work with at least AmigaDOS 2.04 (V37) (not tested) +# and will probably not work with AmigaDOS 1.3 (V34) + +# If you have any improvements, critics or else please feel free to mail. +# Any response is appreciated. Haidinger Walter + +# Available targets: +# all builds all executeables below +# zip builds zip executeable +# zipsplit builds zipsplit executeable +# zipcloak builds zipcloak executeable +# zipnote builds zipnote executeable +# ziplm builds low memory version of zip executable +# clean remove all files created by the compilation +# spotless like clean target but removes binaries too + + +########################## +# USER MACRO DEFINITIONS # +########################## + +# *** NOTE *** +# The assembly version is not implemented yet. +# (Un)commenting the assembler macros has no effect unless the +# file dependencies are changed too. +# Most of the amiga/*.a files do not assmble with 68000 instructions. +# Any help is appreciated, of course. + +# Set the processor to generate code for. +# Compiler: ANY 68000 68010 68020 68030 68040 68060 +# Assembler: 0 0 1 2 3 4 n/a +# Defaults: ANY and 0 +# +CUSECPU = ANY +AUSECPU = 0 + +# UNCOMMENT to use 68020 instructions in the assembly version of deflate.o +# Only use if code is generated for 68020 or higher processors above. +# Note: You could use CPUTEST too to enable runtime cpu detection. +# However, it is not recommended since both 68000 and 68020 code will be +# included which would be an unnecessary increase in size. +# (see amiga/deflate.a for more information) +# +#AUSE020 = CPU020 + +# To disable the assembler replacements and use the standard C source, +# you have to change the Zip and ZipLM dependencies. See below for details. +# (remember that assembler use is *not* implemented yet) + +# Uncomment both CUTIL and LUTIL to make use of utility.library of OS 2.04+ +# The utility.library is *not* used for UnZipSFX to ensure maximum portability +# between the different Amiga systems (minimal config: 68000 and OS 1.2). +# You can change this by adding the $(LUTIL) macro in the UnZipSFX linking +# rules (See below: Final output targets, UnZipSFX:). +# WARNINGS when using the utility library: +# 1. All Executables will *only* work with AmigaDOS 2.04 (v37) or higher. +# 2. You *need not* compile/link with short-integers using the +# utility.library. It will crash your machine. See Libraries below. +# +# Default: commented (not used) +# +#CUTIL = UTILLIB DEFINE=_UTILLIB +#LUTIL = WITH SC:LIB/utillib.with # include necessary linker defines +# Choose one stack-handling method (default=faster) +# StackExtend: Dynamic runtime stack extension. You won't notice stack overflows. +# StackCheck: On a stack overflow a requester appears which allows you to exit. +# Note that either stack watching will slow down your executable because of the +# extra code run on each function entry. On the other hand, you won't crash +# anymore due to stack overflows. However, you should not have *any* stack +# problems with Info-ZIP programs if you raise your stack to 10000 (which I'd +# recommend as a minimum default stack for all applications) or more using the +# shell stack command. Type 'Stack 20000' or add it to your S:Shell-Startup. +# BTW: Typing 'Stack' prints your current stack size. +# +CSTACK = NOSTACKCHECK STACKEXTEND # slow, but always works +#CSTACK = STACKCHECK NOSTACKEXTEND # slow, requester & graceful exit +#CSTACK = NOSTACKCHECK NOSTACKEXTEND # faster but relies on larger stack (>=10K) + + +# +# LIBRARIES +# --------- + +# Choose one DATAOPTS , SASLIB , ASMOPTS and LSTARTUP +# Always comment/uncomment all macros of a set. + +# Library to use with near data and 2-byte integers +# Notes: o slower than 4-byte integers with 68000 cpu +# o *not* recommended due to poor overall performance +# o see comment in amiga/osdep.h +#DATAOPTS = DATA=NEAR SHORTINTEGERS DEF=_NEAR_DATA +#SASLIB = scs +#ASMOPTS = -dINT16 +#LSTARTUP = cres.o + +# Library to use with near data and 4-byte integers (DEFAULT) +# *** use this with the utility.library *** +DATAOPTS = DATA=NEAR DEF=_NEAR_DATA +SASLIB = sc +ASMOPTS = +LSTARTUP = cres.o + +# Library to use with far data and 2-byte integers +# use if DYN_ALLOC is not defined +# old default - far data always works but is slower +#DATAOPTS = DATA=FAR SHORTINTEGERS DEF=_FAR_DATA +#SASLIB = scsnb +#ASMOPTS = -dINT16 +#LSTARTUP = c.o + +# Library to use with far data and 4-byte integers +# if everything else fails: try this +#DATAOPTS = DATA=FAR DEF=_FAR_DATA +#SASLIB = scnb +#ASMOPTS = +#LSTARTUP = c.o + + +# +# DEBUGGING +# --------- + +# Default: No debugging information added. +# The three macros below will be overwritten if you choose to add +# debug info, therefore no need to comment. + +CDBG = NODEBUG NOPROFILE NOCOVERAGE # default: no debug info +ADBG = +LDBG = STRIPDEBUG # default: no debug info + +# Compiler and loader debug flags. Uncomment as needed. Recomment when done. +# Optimization disabled for faster compilation (by using NOOPT) + +#CDBG1 = DEF=DEBUG DEF=DEBUG_TIME # enables Info-Zip's debug output + +# Enable profiling and coverage when desired. Option COVERAGE commented +# seperately because running coverage may corrupt your drive in case of a +# system crash since a file 'cover.dat' is created in your working directory. +# Note that the use of COVERAGE forces the use of the c.o startup module. + +#CDBG2 = PROFILE +#CDBG3 = COVERAGE # must use c.o startup code: +#LSTARTUP = c.o # Uncomment *only* when you use COVERAGE + +# *Uncomment* here macros CDBG, ADBG and LDBG to include debugging information + +#CDBG = $(CDBG1) $(CDBG2) $(CDBG3) ADDSYM DEBUG=FULLFLUSH STACKCHECK NOOPT +#ADBG = DEBUG +#LDBG = ADDSYM + +# Optional use of memwatch.library which can be found in your +# sc:extras/memlib directory. Please read the short docs (memlib.doc). +# Note that memwatch.library has a small bug: MWTerm() displays always +# the first entry. +# Get the latest version from aminet (dev/debug/memlib.lha) or +# contact me to get the patch. Uncomment all macros to use. +#CMEMLIB = DEFINE=MWDEBUG=1 # define to enable library +#LMEMLIB = SC:LIB/memwatch.lib # path to library +#LSTARTUP = c.o # must use c.o with memlib! + + +# +# MAPPING +# ------- + +# Map filenames used when mapping (no need to comment) +# +MAPFZ = zip.map # Zip map filename +MAPFN = zipnote.map # ZipNote map filename +MAPFC = zipcloak.map # ZipCloak map filename +MAPFS = zipsplit.map # ZipSplit map filename +MAPFL = ziplm.map # Zip low memory version map filename + +# Map file output: Uncomment to highlight and bold headings. +# +#MAPFSTYLE = FANCY + +# Map flags for each EXECUTABLE. Uncomment to enable mapping. +# For map options please refer to: +# SAS/C v6 manual, volume 1: user's guide, chapter 8, page 136: map +# Default: all options enabled: f,h,l,o,s,x +# |-> options start here +#LMAPZ = $(MAPFSTYLE) MAP $(MAPFZ) f,h,l,o,s,x # Zip maps +#LMAPN = $(MAPFSTYLE) MAP $(MAPFN) f,h,l,o,s,x # ZipNote maps +#LMAPC = $(MAPFSTYLE) MAP $(MAPFC) f,h,l,o,s,x # ZipCloak maps +#LMAPS = $(MAPFSTYLE) MAP $(MAPFS) f,h,l,o,s,x # ZipSplit maps +#LMAPL = $(MAPFSTYLE) MAP $(MAPFL) f,h,l,o,s,x # Zip lowmem maps + +# +# LISTINGS +# -------- + +# Listfile-extensions for each executable (enter *with* dot) +# +LISTEXTZ = .lst # extension for Zip listfiles +LISTEXTU = .ulst # extension for utility listfiles (ZipNote,ZipCloak,ZipSplit) +LISTEXTL = .llst # extension for Zip low memory listfiles + + +# List files and cross references for each OBJECT. +# Add/remove flags as needed. Not all listed by default. +# Use LISTINCLUDES to determine the dependencies for smake +# +CLISTOPT = LISTHEADERS LISTMACROS # LISTSYSTEM LISTINCLUDES +CXREFOPT = XHEAD XSYS +# +# Uncomment to enable listing (default: commented) +# *** WARNING: List files require *lots* of disk space! +# +#CLIST = LIST $(CLISTOPT) +#CXREF = XREF $(CXREFOPT) + + +# +# SUPPRESSED COMPILER WARNINGS +# ---------------------------- + +# Compiler warnings to ignore +# +# Warning 105 : module does not define any externally-known symbols +# Warning 304 : Dead assignment eliminated... +# Note 306 : ...function inlined... +# Warning 317 : possibly uninitialized variable... +# Comment to enable. +# +CIGNORE = IGNORE=105,304,306,317 + + +# +# OBJECT EXTENSIONS +# + +# Extensions used for objects of each executeable. +# Transformation rules require unique extensions. +# Enter *with* dot. +# +O = .o # extension for Zip objects +OU = .uo # extension for utility objects (ZipNote, ZipSplit and ZipCloak) +OL = .lo # extension for low memory Zip objects + + +# Filename used to store converted options from environment variable +# LOCAL_ZIP. Default: scoptions_local_zip +# +CWITHOPT = scoptions_local_zip + + +# Filenames to store compiler options to prevent command line overflow +# +# Common options file for Zip and other executables +CFILE = scoptions-zip + + +# Temp filenames for object lists to load using linker "WITH" command. +OBJLISTZ = zip_objlist.with # Zip object list +OBJLISTN = zipnote_objlist.with # ZipNote object list +OBJLISTC = zipcloak_objlist.with # ZipCloak object list +OBJLISTS = zipsplit_objlist.with # ZipSplit object list +OBJLISTL = ziplm_objlist.with # Zip low-mem object list + + +# Filenames to store linker options +# +LWITHZ = zip.lnk # zip linker options +LWITHN = zipnote.lnk # zipnote linker options +LWITHC = zipcloak.lnk # zipcloak linker options +LWITHS = zipsplit.lnk # zipsplit linker options +LWITHL = ziplm.lnk # zip low-mem linker options + + +# Define AMIGA_BETA to print "Beta Notice" up front. See tailor.h. +# Undefine AMIGA_BETA when building a released version. +#CDEFBETA = DEF=AMIGA_BETA + +##################################### +# NOTHING TO CHANGE BEYOND HERE ... # +##################################### +# (except for C/asm dependencies) + +# Define MEDIUM_MEM for production release (per Paul Kienitz). +# This reduces runtime memory requirement but not speed or compression. +# Note: Do *not* use BIG_MEM or MMAP since it isn't yet supported by the + assembler version of deflate.c : amiga/deflate.a +CUSEMEM = DEF=MEDIUM_MEM +AUSEMEM = -DMEDIUM_MEM # for asm deflate.o, must match above + + +# Defines for building low-memory use version of Zip +WSIZEL = WSIZE=4096 # deflate.c window size for low-mem version +CLOWMEM = DEF=SMALL_MEM DEF=$(WSIZEL) +ALOWMEM = -DSMALL_MEM -D$(WSIZEL) # for asm deflate.o, must match above + + +# Compiler definitions +# +CC = sc +# +# Optimizer flags +# +OPTPASSES = 6 # set number of global optimizer passes +# +OPT1 = OPT OPTINL OPTINLOCAL OPTTIME OPTLOOP OPTSCHED +OPT2 = OPTCOMP=$(OPTPASSES) OPTDEP=$(OPTPASSES) OPTRDEP=$(OPTPASSES) +OPT = $(OPT1) $(OPT2) + + +# Compiler flags +# +CDEFINES = $(CMEMLIB) $(CDEFBETA) DEF=AMIGA +COPTIONS = $(DATAOPTS) CODE=NEAR CPU=$(CUSECPU) VERBOSE PARAMETERS=BOTH NOMINC +COPTIONS = $(COPTIONS) ERRORREXX NOERRORCONSOLE MEMSIZE=HUGE $(CLIST) $(CXREF) +COPTIONS = $(COPTIONS) $(CSTACK) $(CUTIL) STRICT UNSCHAR NOICONS STRINGMERGE +CFLAGS = $(CDEFINES) $(COPTIONS) $(OPT) $(CDBG) $(CIGNORE) + + +# Linker definitions +# See SASLIB definition above +# +LD = slink +# special linker flags for pure (i.e. resident) binary. +LDFLAGSS = FROM SC:LIB/$(LSTARTUP) +# common linker flags for all other executeables +LDFLAGSC = FROM SC:LIB/c.o +LDFLAGS2 = NOICONS $(LDBG) +LIBFLAGS = LIB $(LMEMLIB) SC:LIB/$(SASLIB).lib SC:LIB/amiga.lib + + +# Assembler definitions +# +ASM = asm +# +# Options used for assembling amiga/deflate.a +# Must match defines in C-Source. +# +AFLAGS0 = -d__SASC -dSASC -dAMIGA +AFLAGS1 = $(AUSE020) $(ASMOPTS) $(ADBG) +AFLAGS2 = -m$(AUSECPU) -jm -iINCLUDE: +AFLAGS = $(AFLAGS0) $(AFLAGS1) $(AFLAGS2) +ASMOPTSZ = $(AFLAGS) $(AUSEMEM) -dDYN_ALLOC # Zip asm flags +ASMOPTSL = $(AFLAGS) $(ALOWMEM) # Zip low-mem version asm flags + + +################## +# TARGET OBJECTS # +################## + + +# Zip objects +OBJZ1 = zip$(O) zipfile$(O) zipup$(O) fileio$(O) util$(O) globals$(O) +OBJZ2 = crc32$(O) crypt$(O) timezone$(O) ttyio$(O) +OBJZI = deflate$(O) trees$(O) +OBJZA = amiga$(O) amigazip$(O) stat$(O) filedate$(O) +OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZI) $(OBJZA) + +# Shared utility objects for ZipNote, ZipCloak and ZipSplit +OBJU1 = globals$(O) +OBJUU = zipfile$(OU) fileio$(OU) timezone$(O) util$(OU) +OBJUA = amigazip$(OU) amiga$(O) stat$(O) filedate$(O) +OBJU = $(OBJU1) $(OBJUU) $(OBJUA) + +# ZipNote objects +OBJN1 = zipnote$(O) +OBJN = $(OBJN1) $(OBJU) + +# ZipCloak objects +OBJC1 = zipcloak$(O) +OBJCU = $(OBJU) crypt$(OU) +OBJCS = crc32$(OU) ttyio$(O) +OBJC = $(OBJC1) $(OBJCU) $(OBJCS) + +#ZipSplit objects +OBJS1 = zipsplit$(O) +OBJS = $(OBJS1) $(OBJU) + +# ZipLM objects +OBJL1 = zip$(OL) zipfile$(OL) zipup$(OL) fileio$(OL) util$(OL) globals$(OL) +OBJL2 = crc32$(OL) crypt$(OL) timezone$(OL) ttyio$(OL) +OBJLI = deflate$(OL) trees$(OL) +OBJLA = amiga$(OL) amigazip$(OL) stat$(OL) filedate$(OL) +OBJL = $(OBJL1) $(OBJL2) $(OBJLI) $(OBJLA) + +# Common header files +ZIP_H1 = zip.h ziperr.h tailor.h +ZIP_HA = amiga/osdep.h amiga/z-stat.h +ZIP_H = $(ZIP_H1) $(ZIP_HA) + +# Output targets +ZIPS = Zip ZipNote ZipCloak ZipSplit ZipLM + + +# Temp filenames for object lists to load using linker "WITH" command. +OBJLISTZ = zip_objlist.with # Zip object list +OBJLISTN = zipnote_objlist.with # ZipNote object list +OBJLISTC = zipcloak_objlist.with # ZipCloak object list +OBJLISTS = zipsplit_objlist.with # ZipSplit object list +OBJLISTL = ziplm_objlist.with # Zip low-mem object list + +####################################### +# DEFAULT TARGET AND PROCESSING RULES # +####################################### + +all: request flush $(ZIPS) + +# Zip transformation rules +# +.c$(O): + $(CC) WITH=$(CFILE) $(CUSEMEM) LISTFILE=$>$(LISTEXTZ) OBJNAME=$@ $*.c + +# Zip low-memory version transformation rules +# +.c$(OL): + $(CC) WITH=$(CFILE) $(CLOWMEM) LISTFILE=$>$(LISTEXTL) OBJNAME=$@ $*.c + +# Utilities (ZipNote, ZipCloak and ZipSplit) transformation rules +# +.c$(OU): + $(CC) WITH=$(CFILE) $(CUSEMEM) DEF=UTIL LISTFILE=$>$(LISTEXTU) OBJNAME=$@ $*.c + + +######################### +# Final output targets. # +######################### + + +zip: local_zip CommonFlags $(OBJZ) + @Echo "$(OBJZ)" > $(OBJLISTZ) + Type $(OBJLISTZ) + @Echo "$(LDFLAGSS) $(LUTIL) WITH $(OBJLISTZ) $(LIBFLAGS)" \ + "$(LDFLAGS2) $(LMAPZ)" >$(LWITHZ) + Type $(LWITHZ) + $(LD) TO Zip WITH $(LWITHZ) + +zipnote: local_zip CommonFlags $(OBJN) + @Echo "$(OBJN)" > $(OBJLISTN) + Type $(OBJLISTN) + @Echo "$(LDFLAGSS) $(LUTIL) WITH $(OBJLISTN) $(LIBFLAGS) " \ + "$(LDFLAGS2) $(LMAPN)" >$(LWITHN) + Type $(LWITHN) + $(LD) TO ZipNote WITH $(LWITHN) + +zipcloak: local_zip CommonFlags $(OBJC) + @Echo "$(OBJC)" > $(OBJLISTC) + Type $(OBJLISTC) + @Echo "$(LDFLAGSS) $(LUTIL) WITH $(OBJLISTC) $(LIBFLAGS) " \ + "$(LDFLAGS2) $(LMAPC)" >$(LWITHC) + Type $(LWITHC) + $(LD) TO ZipCloak WITH $(LWITHC) + +zipsplit: local_zip CommonFlags $(OBJS) + @Echo "$(OBJS)" > $(OBJLISTS) + Type $(OBJLISTS) + @Echo "$(LDFLAGSS) $(LUTIL) WITH $(OBJLISTS) $(LIBFLAGS) " \ + "$(LDFLAGS2) $(LMAPS)" >$(LWITHS) + Type $(LWITHS) + $(LD) TO ZipSplit WITH $(LWITHS) + +ziplm: local_zip CommonFlags $(OBJL) + @Echo "$(OBJL)" > $(OBJLISTL) + Type $(OBJLISTL) + @Echo "$(LDFLAGSS) $(LUTIL) WITH $(OBJLISTL) $(LIBFLAGS) " \ + "$(LDFLAGS2) $(LMAPL)" >$(LWITHL) + Type $(LWITHL) + $(LD) TO ZipLM WITH $(LWITHL) + + +clean: + -Delete >nil: $(OBJZ) quiet + -Delete >nil: $(OBJN) quiet + -Delete >nil: $(OBJC) quiet + -Delete >nil: $(OBJS) quiet + -Delete >nil: $(OBJL) quiet + -Delete >nil: $(OBJLISTZ) $(OBJLISTL) $(OBJLISTN) $(OBJLISTS) $(OBJLISTC) quiet + -Delete >nil: $(MAPFZ) $(MAPFN) $(MAPFC) $(MAPFS) $(MAPFL) quiet + -Delete >nil: \#?$(LISTEXTZ) \#?$(LISTEXTU) \#?$(LISTEXTL) quiet + -Delete >nil: $(CWITHOPT) $(CFILE) quiet + -Delete >nil: $(LWITHZ) $(LWITHN) $(LWITHC) $(LWITHS) $(LWITHL) quiet + -Delete >nil: env:VersionDate quiet + -Delete >nil: \#?.q.?? \#?.tmp \#?.cov quiet + +spotless: clean + -Delete >nil: $(ZIPS) quiet + + +################ +# DEPENDENCIES # +################ + +# To change between the assembler and C sources, you have to comment/uncomment +# the approprite lines. C sources are marked by #C-src and assembler sources +# #asm-src at the end. +# Zip dependencies: +# + +zip$(O): zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +zipup$(O): zipup.c $(ZIP_H) revision.h crc32.h crypt.h amiga/zipup.h +zipfile$(O): zipfile.c $(ZIP_H) revision.h crc32.h +crypt$(O): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h +ttyio$(O): ttyio.c $(ZIP_H) crypt.h ttyio.h +deflate$(O): deflate.c $(ZIP_H) #C-src +trees$(O): trees.c $(ZIP_H) +fileio$(O): fileio.c $(ZIP_H) crc32.h +util$(O): util.c $(ZIP_H) +crc32$(O): crc32.c $(ZIP_H) crc32.h +globals$(O): globals.c $(ZIP_H) +timezone$(O): timezone.c $(ZIP_H) timezone.h +# Amiga specific objects +stat$(O): amiga/stat.c amiga/z-stat.h +filedate$(O): amiga/filedate.c crypt.h timezone.h +amiga$(O): amiga/amiga.c ziperr.h +amigazip$(O): amiga/amigazip.c $(ZIP_H) amiga/amiga.h env:Workbench +# Substitute assembly version of deflate.c: +#deflate$(O): amiga/deflate.a #asm-src +# $(ASM) $(ASMOPTSZ) -o$@ $*.a #asm-src + + +# Utility (ZipNote, ZipCloak, ZipSplit) dependencies: +# +zipnote$(O): zipnote.c $(ZIP_H) revision.h +zipcloak$(O): zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +zipsplit$(O): zipsplit.c $(ZIP_H) revision.h +zipfile$(OU): zipfile.c $(ZIP_H) revision.h crc32.h +fileio$(OU): fileio.c $(ZIP_H) crc32.h +util$(OU): util.c $(ZIP_H) +crc32$(OU): crc32.c $(ZIP_H) crc32.h +crypt$(OU): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h +# Amiga specific objects +amigazip$(OU): amiga/amigazip.c $(ZIP_H) amiga/amiga.h env:Workbench + +# ZipLM dependencies: +# +zip$(OL): zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +zipup$(OL): zipup.c $(ZIP_H) revision.h crc32.h crypt.h amiga/zipup.h +zipfile$(OL): zipfile.c $(ZIP_H) revision.h crc32.h +crypt$(OL): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h +ttyio$(OL): ttyio.c $(ZIP_H) crypt.h ttyio.h +deflate$(OL): deflate.c $(ZIP_H) +trees$(OL): trees.c $(ZIP_H) +fileio$(OL): fileio.c $(ZIP_H) crc32.h +util$(OL): util.c $(ZIP_H) +crc32$(OL): crc32.c $(ZIP_H) +globals$(OL): globals.c $(ZIP_H) +timezone$(OL): timezone.c $(ZIP_H) timezone.h +# Amiga specific objects +stat$(OL): amiga/stat.c amiga/z-stat.h +filedate$(OL): amiga/filedate.c crypt.h timezone.h +amiga$(OL): amiga/amiga.c ziperr.h +# Substitute assembly version of deflate.c: +#deflate$(OL): amiga/deflate.a +# $(ASM) $(ASMOPTSL) -o$@ $*.a + + +######################## +# DEPENDECIES END HERE # +######################## + +# flush all libraries to provide more mem for compilation +flush: + @Avail flush >nil: + +# write common compiler flags to file and echo to user +CommonFlags: + @Echo "$(CFLAGS)" >$(CFILE) + @Type "$(CWITHOPT)" >>$(CFILE) + -Type $(CFILE) + + +# special rules for adding Amiga internal version number to amiga/amiga.c +amiga$(O): + rx > env:VersionDate "say '""'translate(date('E'),'.','/')'""'" + $(CC) WITH=$(CFILE) $(CUSEMEM) LISTFILE=$>$(LISTEXTZ) OBJNAME=$@ $*.c + -Delete env:VersionDate + +amiga$(OL): + rx > env:VersionDate "say '""'translate(date('E'),'.','/')'""'" + $(CC) WITH=$(CFILE) $(CLOWMEM) LISTFILE=$>$(LISTEXTL) OBJNAME=$@ $*.c + -Delete env:VersionDate + + +# needed in amiga/amigazip.c +# should be set in startup-sequence, but just in case: +# (only works with OS 2.0 and above) + +env\:WorkBench: + @Execute < < (Workbench_smk.tmp) + FailAt 21 + If not exists ENV:Workbench + Version >nil: + SetEnv Workbench $$Workbench + Endif + < + + +# Read environment variable LOCAL_ZIP and convert options to SAS format +# +# e.g.: to define FOO_ONE and FOO_TWO enter: +# +# SetEnv LOCAL_ZIP "-DFOO_ONE -DFOO_TWO" +# +# Put the statement into your startup-sequence or (for AmigaDOS 2.0 or higher +# only) make sure LOCAL_ZIP is stored in the ENVARC: directory +# ( Copy ENV:LOCAL_ZIP ENVARC: ) +# + +local_zip: + @Execute < < (Local_Zip_smk.tmp) + Failat 21 + If exists ENV:LOCAL_ZIP + Echo "Using environment variable LOCAL_ZIP !" + Copy >NIL: ENV:LOCAL_ZIP SASCOPTS + Else + Echo "You could use envvar ZIP_OPT to set your special compilation options." + Delete >nil: SASCOPTS quiet + Endif + ; Do not remove the lctosc command! If LOCAL_ZIP is unset, an + ; empty file is created which needed by CommonFlags ! + lctosc >$(CWITHOPT) + < + + + +# Echo request to the user +# +request: + @Echo "" + @Echo " This makefile is for use with SAS/C version 6.58." + @Echo " If you still have an older version, please upgrade!" + @Echo " Patches are available on the Aminet under biz/patch/sc\#?." + @Echo "" + @Echo " Just a simple request..." + @Echo " Please give me a mail that you compiled whether you encounter any errors" + @Echo " or not. I'd just like to know how many Amiga users actually make use of" + @Echo " this makefile." + @Echo " If you mail me, I'll put you on my mailing-list and notify you whenever" + @Echo " new versions of Info-Zip are released." + @Echo " Have a look at the makefile for changes like CPU type, UtilLib, etc." + @Echo " Feel free to mail comments, suggestions, etc." + @Echo " Enjoy Info-Zip !" + @Echo " Haidinger Walter, " + @Echo "" + + +# Echo help in case of an error +# +.ONERROR: + @Echo "" + @Echo "[sigh] An error running this makefile was detected." + @Echo "This message may also appear if you interrupted smake by pressing CTRL-C." + @Echo "Contact Info-Zip authors at Zip-Bugs@lists.wku.edu or me for help." + @Echo "Haidinger Walter, " + diff --git a/amiga/stat.c b/amiga/stat.c new file mode 100644 index 0000000..6075c21 --- /dev/null +++ b/amiga/stat.c @@ -0,0 +1,293 @@ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* Here we have a handmade stat() function because Aztec's c.lib stat() */ +/* does not support an st_mode field, which we need... also a chmod(). */ + +/* This stat() is by Paul Wells, modified by Paul Kienitz. */ +/* Originally for use with Aztec C >= 5.0 and Lattice C <= 4.01 */ +/* Adapted for SAS/C 6.5x by Haidinger Walter */ + +/* POLICY DECISION: We will not attempt to remove global variables from */ +/* this source file for Aztec C. These routines are essentially just */ +/* augmentations of Aztec's c.lib, which is itself not reentrant. If */ +/* we want to produce a fully reentrant UnZip, we will have to use a */ +/* suitable startup module, such as purify.a for Aztec by Paul Kienitz. */ + +#ifndef __amiga_stat_c +#define __amiga_stat_c + +#include +#include +#include "amiga/z-stat.h" /* fake version of stat.h */ +#include + +#ifdef AZTEC_C +# include +# include +# include +# include +# include +# include +#endif +#ifdef __SASC +# include /* SAS/C dir function prototypes */ +# include +# include +# include +#endif + +#ifndef SUCCESS +# define SUCCESS (-1) +# define FAILURE (0) +#endif + + +void close_leftover_open_dirs(void); /* prototype */ + +static DIR *dir_cleanup_list = NULL; /* for resource tracking */ + +/* CALL THIS WHEN HANDLING CTRL-C OR OTHER UNEXPECTED EXIT! */ +void close_leftover_open_dirs(void) +{ + while (dir_cleanup_list) + closedir(dir_cleanup_list); +} + + +unsigned short disk_not_mounted; + +extern int stat(const char *file, struct stat *buf); + +stat(file,buf) +const char *file; +struct stat *buf; +{ + + struct FileInfoBlock *inf; + BPTR lock; + time_t ftime; + struct tm local_tm; + + if( (lock = Lock((char *)file,SHARED_LOCK))==0 ) + /* file not found */ + return(-1); + + if( !(inf = (struct FileInfoBlock *)AllocMem( + (long)sizeof(struct FileInfoBlock),MEMF_PUBLIC|MEMF_CLEAR)) ) + { + UnLock(lock); + return(-1); + } + + if( Examine(lock,inf)==FAILURE ) + { + FreeMem((char *)inf,(long)sizeof(*inf)); + UnLock(lock); + return(-1); + } + + /* fill in buf */ + buf->st_dev = + buf->st_nlink = + buf->st_uid = + buf->st_gid = + buf->st_rdev = 0; + buf->st_ino = inf->fib_DiskKey; + buf->st_blocks = inf->fib_NumBlocks; + buf->st_size = inf->fib_Size; + + /* now the date. AmigaDOS has weird datestamps--- + * ds_Days is the number of days since 1-1-1978; + * however, as Unix wants date since 1-1-1970... + */ + + ftime = + (inf->fib_Date.ds_Days * 86400 ) + + (inf->fib_Date.ds_Minute * 60 ) + + (inf->fib_Date.ds_Tick / TICKS_PER_SECOND ) + + (86400 * 8 * 365 ) + + (86400 * 2 ); /* two leap years */ + + /* tzset(); */ /* this should be handled by mktime(), instead */ + /* ftime += timezone; */ + local_tm = *gmtime(&ftime); + local_tm.tm_isdst = -1; + ftime = mktime(&local_tm); + + buf->st_ctime = + buf->st_atime = + buf->st_mtime = ftime; + + buf->st_mode = (inf->fib_DirEntryType < 0 ? S_IFREG : S_IFDIR); + + /* lastly, throw in the protection bits */ + buf->st_mode |= ((inf->fib_Protection ^ 0xF) & 0xFF); + + FreeMem((char *)inf, (long)sizeof(*inf)); + UnLock((BPTR)lock); + + return(0); + +} + +int fstat(int handle, struct stat *buf) +{ + /* fake some reasonable values for stdin */ + buf->st_mode = (S_IREAD|S_IWRITE|S_IFREG); + buf->st_size = -1; + buf->st_mtime = time(&buf->st_mtime); + return 0; +} + + +/* opendir(), readdir(), closedir(), rmdir(), and chmod() by Paul Kienitz. */ + +DIR *opendir(const char *path) +{ + DIR *dd = AllocMem(sizeof(DIR), MEMF_PUBLIC); + if (!dd) return NULL; + if (!(dd->d_parentlock = Lock((char *)path, MODE_OLDFILE))) { + disk_not_mounted = IoErr() == ERROR_DEVICE_NOT_MOUNTED; + FreeMem(dd, sizeof(DIR)); + return NULL; + } else + disk_not_mounted = 0; + if (!Examine(dd->d_parentlock, &dd->d_fib) || dd->d_fib.fib_EntryType < 0) { + UnLock(dd->d_parentlock); + FreeMem(dd, sizeof(DIR)); + return NULL; + } + dd->d_cleanuplink = dir_cleanup_list; /* track them resources */ + if (dir_cleanup_list) + dir_cleanup_list->d_cleanupparent = &dd->d_cleanuplink; + dd->d_cleanupparent = &dir_cleanup_list; + dir_cleanup_list = dd; + return dd; +} + +void closedir(DIR *dd) +{ + if (dd) { + if (dd->d_cleanuplink) + dd->d_cleanuplink->d_cleanupparent = dd->d_cleanupparent; + *(dd->d_cleanupparent) = dd->d_cleanuplink; + if (dd->d_parentlock) + UnLock(dd->d_parentlock); + FreeMem(dd, sizeof(DIR)); + } +} + +struct dirent *readdir(DIR *dd) +{ + return (ExNext(dd->d_parentlock, &dd->d_fib) ? (struct dirent *)dd : NULL); +} + + +#ifdef AZTEC_C + +int rmdir(const char *path) +{ + return (DeleteFile((char *)path) ? 0 : IoErr()); +} + +int chmod(const char *filename, int bits) /* bits are as for st_mode */ +{ + long protmask = (bits & 0xFF) ^ 0xF; + return !SetProtection((char *)filename, protmask); +} + + +/* This here removes unnecessary bulk from the executable with Aztec: */ +void _wb_parse(void) { } + +/* fake a unix function that does not apply to amigados: */ +int umask(void) { return 0; } + + +# include + +/* C library signal() messes up debugging yet adds no actual usefulness */ +typedef void (*__signal_return_type)(int); +__signal_return_type signal() { return SIG_ERR; } + + +/* The following replaces Aztec's argv-parsing function for compatibility with +Unix-like syntax used on other platforms. It also fixes the problem the +standard _cli_parse() has of accepting only lower-ascii characters. */ + +int _argc, _arg_len; +char **_argv, *_arg_lin; + +void _cli_parse(struct Process *pp, long alen, register UBYTE *aptr) +{ + register UBYTE *cp; + register struct CommandLineInterface *cli; + register short c; + register short starred = 0; +# ifdef PRESTART_HOOK + void Prestart_Hook(void); +# endif + + cli = (struct CommandLineInterface *) (pp->pr_CLI << 2); + cp = (UBYTE *) (cli->cli_CommandName << 2); + _arg_len = cp[0] + alen + 2; + if (!(_arg_lin = AllocMem((long) _arg_len, 0L))) + return; + c = cp[0]; + strncpy(_arg_lin, cp + 1, c); + _arg_lin[c] = 0; + for (cp = _arg_lin + c + 1; alen && (*aptr < '\n' || *aptr > '\r'); alen--) + *cp++ = *aptr++; + *cp = 0; + aptr = cp = _arg_lin + c + 1; + for (_argc = 1; ; _argc++) { + while (*cp == ' ' || *cp == '\t') + cp++; + if (!*cp) + break; + if (*cp == '"') { + cp++; + while (c = *cp++) { + if (c == '"' && !starred) { + *aptr++ = 0; + starred = 0; + break; + } else if (c == '\\' && !starred) + starred = 1; + else { + *aptr++ = c; + starred = 0; + } + } + } else { + while ((c = *cp++) && c != ' ' && c != '\t') + *aptr++ = c; + *aptr++ = 0; + } + if (c == 0) + --cp; + } + *aptr = 0; + if (!(_argv = AllocMem((_argc + 1) * sizeof(*_argv), 0L))) { + _argc = 0; + return; + } + for (c = 0, cp = _arg_lin; c < _argc; c++) { + _argv[c] = cp; + cp += strlen(cp) + 1; + } + _argv[c] = NULL; +# ifdef PRESTART_HOOK + Prestart_Hook(); +# endif +} + +#endif /* AZTEC_C */ + +#endif /* __amiga_stat_c */ diff --git a/amiga/z-stat.h b/amiga/z-stat.h new file mode 100644 index 0000000..53d6cd1 --- /dev/null +++ b/amiga/z-stat.h @@ -0,0 +1,95 @@ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#ifndef __amiga_z_stat_h +#define __amiga_z_stat_h + +/* Since older versions of the Lattice C compiler for Amiga, and all current */ +/* versions of the Manx Aztec C compiler for Amiga, either provide no stat() */ +/* function or provide one inadequate for unzip (Aztec's has no st_mode */ +/* field), we provide our own stat() function in stat.c by Paul Wells, and */ +/* this fake stat.h file by Paul Kienitz. Paul Wells originally used the */ +/* Lattice stat.h but that does not work for Aztec and is not distributable */ +/* with this package, so I made a separate one. This has to be pulled into */ +/* unzip.h when compiling an Amiga version, as "amiga/z-stat.h". */ + +/* We also provide here a "struct dirent" for use with opendir() & readdir() */ +/* functions included in amiga/stat.c. If you use amiga/stat.c, this must */ +/* be included wherever you use either readdir() or stat(). */ + +#ifdef AZTEC_C +# define __STAT_H +#else /* __SASC */ +/* do not include the following header, replacement definitions are here */ +# define _STAT_H /* do not include SAS/C */ +# define _DIRENT_H /* do not include SAS/C */ +# define _SYS_DIR_H /* do not include SAS/C */ +# define _COMMIFMT_H /* do not include SAS/C */ +# include +#endif +#include +#include + + +struct stat { + unsigned short st_mode; + time_t st_ctime, st_atime, st_mtime; + long st_size; + long st_ino; + long st_blocks; + short st_attr, st_dev, st_nlink, st_uid, st_gid, st_rdev; +}; + +#define S_IFDIR (1<<11) +#define S_IFREG (1<<10) + +#if 0 + /* these values here are totally random: */ +# define S_IFLNK (1<<14) +# define S_IFSOCK (1<<13) +# define S_IFCHR (1<<8) +# define S_IFIFO (1<<7) +# define S_IFMT (S_IFDIR|S_IFREG|S_IFCHR|S_IFLNK) +#else +# define S_IFMT (S_IFDIR|S_IFREG) +#endif + +#define S_IHIDDEN (1<<7) +#define S_ISCRIPT (1<<6) +#define S_IPURE (1<<5) +#define S_IARCHIVE (1<<4) +#define S_IREAD (1<<3) +#define S_IWRITE (1<<2) +#define S_IEXECUTE (1<<1) +#define S_IDELETE (1<<0) + +int stat(const char *name, struct stat *buf); +int fstat(int handle, struct stat *buf); /* returns dummy values */ + +typedef struct dirent { + struct dirent *d_cleanuplink, + **d_cleanupparent; + BPTR d_parentlock; + struct FileInfoBlock d_fib; +} DIR; +#define d_name d_fib.fib_FileName + +extern unsigned short disk_not_mounted; /* flag set by opendir() */ + +DIR *opendir(const char *); +void closedir(DIR *); +void close_leftover_open_dirs(void); /* call this if aborted in mid-run */ +struct dirent *readdir(DIR *); +int umask(void); + +#ifdef AZTEC_C +int rmdir(const char *); +int chmod(const char *filename, int bits); +#endif + +#endif /* __amiga_z_stat_h */ diff --git a/amiga/zipup.h b/amiga/zipup.h new file mode 100644 index 0000000..c9316f4 --- /dev/null +++ b/amiga/zipup.h @@ -0,0 +1,25 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#ifndef __amiga_zipup_h +#define __amiga_zipup_h + +#ifndef O_RAW +# define O_RAW 0 +#endif +#define fhow (O_RDONLY | O_RAW) +#define fbad (-1) +typedef int ftype; +#define zopen(n,p) open(n,p) +#define zread(f,b,n) read(f,b,n) +#define zclose(f) close(f) +#define zerr(f) (k == (extent)(-1L)) +#define zstdin 0 + +#endif /* __amiga_zipup_h */ + diff --git a/aosvs/aosvs.c b/aosvs/aosvs.c new file mode 100644 index 0000000..f944ad1 --- /dev/null +++ b/aosvs/aosvs.c @@ -0,0 +1,659 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#include +#include + +#include "zip.h" +#include /* parameter definitions */ +#include /* AOS/VS system call interface */ +#include /* AOS/VS ?FSTAT packet defs */ + +#ifndef UTIL /* AOS/VS specific fileio code not needed for UTILs */ + +#define PAD 0 +#define PATH_END ':' + +/* + * could probably avoid the union - + * all are same size & we're going to assume this + */ +typedef union zvsfstat_stru +{ + P_FSTAT norm_fstat_packet; /* normal fstat packet */ + P_FSTAT_DIR dir_fstat_packet; /* DIR/CPD fstat packet */ + P_FSTAT_UNIT unit_fstat_packet; /* unit (device) fstat packet */ + P_FSTAT_IPC ipc_fstat_packet; /* IPC file fstat packet */ +} ZVSFSTAT_STRU; + +typedef struct zextrafld +{ + char extra_header_id[2]; /* set to VS - in theory, an int */ + char extra_data_size[2]; /* size of rest, in Intel little-endian order */ + char extra_sentinel[4]; /* set to FCI w/ trailing null */ + unsigned char extra_rev; /* set to 10 for rev 1.0 */ + ZVSFSTAT_STRU fstat_packet; /* the fstat packet */ + char aclbuf[$MXACL]; /* raw ACL, or link-resolution name */ +} ZEXTRAFLD; + +#define ZEXTRA_HEADID "VS" +#define ZEXTRA_SENTINEL "FCI" +#define ZEXTRA_REV (unsigned char) 10 + +local ZEXTRAFLD zzextrafld; /* buffer for extra field containing + ?FSTAT packet & ACL buffer */ +local char zlinkres[$MXPL]; /* buf for link resolution contents */ +local char znamebuf[$MXPL]; /* buf for AOS/VS filename */ +static char vsnamebuf[$MXPL]; +static char uxnamebuf[FNMAX]; +static P_FSTAT vsfstatbuf; + +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +/* Local functions */ +local char *readd OF((DIR *)); + +char *readd(d) +DIR *d; /* directory stream to read from */ +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e; + + e = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; +} + +int procname(n, caseflag) +char *n; /* name to process */ +int caseflag; /* true to force case-sensitive match */ +/* Process a name or sh expression to operate on (or exclude). Return + an error code in the ZE_ class. */ +{ + char *a; /* path and name for recursion */ + DIR *d; /* directory stream from opendir() */ + char *e; /* pointer to name from readd() */ + int m; /* matched flag */ + char *p; /* path for recursion */ + struct stat s; /* result of stat() */ + struct zlist far *z; /* steps through zfiles list */ + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0, caseflag); + else if (LSSTAT(n, &s)) + { + /* Not a file or directory--search for shell expression in zip file */ + p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */ + m = 1; + for (z = zfiles; z != NULL; z = z->nxt) { + if (MATCH(p, z->iname, caseflag)) + { + z->mark = pcount ? filter(z->zname, caseflag) : 1; + if (verbose) + fprintf(mesg, "zip diagnostic: %scluding %s\n", + z->mark ? "in" : "ex", z->name); + m = 0; + } + } + free((zvoid *)p); + return m ? ZE_MISS : ZE_OK; + } + + /* Live name--use if file, recurse if directory */ + if ((s.st_mode & S_IFDIR) == 0) + { + /* add or remove name of file */ + if ((m = newname(n, 0, caseflag)) != ZE_OK) + return m; + } else { + /* Add trailing / to the directory name */ + if ((p = malloc(strlen(n)+2)) == NULL) + return ZE_MEM; + if (strcmp(n, ".") == 0) { + *p = '\0'; /* avoid "./" prefix and do not create zip entry */ + } else { + strcpy(p, n); + a = p + strlen(p); + if (a[-1] != '/') + strcpy(a, "/"); + if (dirnames && (m = newname(p, 1, caseflag)) != ZE_OK) { + free((zvoid *)p); + return m; + } + } + /* recurse into directory */ + if (recurse && (d = opendir(n)) != NULL) + { + while ((e = readd(d)) != NULL) { + if (strcmp(e, ".") && strcmp(e, "..")) + { + if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL) + { + closedir(d); + free((zvoid *)p); + return ZE_MEM; + } + strcat(strcpy(a, p), e); + if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */ + { + if (m == ZE_MISS) + zipwarn("name not matched: ", a); + else + ziperr(m, a); + } + free((zvoid *)a); + } + } + closedir(d); + } + free((zvoid *)p); + } /* (s.st_mode & S_IFDIR) == 0) */ + return ZE_OK; +} + +char *strlower(s) +char *s; /* string to convert */ +/* Convert all uppercase letters to lowercase in string s */ +{ + char *p; /* scans string */ + + for (p = s; *p; p++) + if (*p >= 'A' && *p <= 'Z') + *p += 'a' - 'A'; + return s; +} + +char *strupper(s) +char *s; /* string to convert */ +/* Convert all lowercase letters to uppercase in string s */ +{ + char *p; /* scans string */ + + for (p = s; *p; p++) + if (*p >= 'a' && *p <= 'z') + *p -= 'a' - 'A'; + return s; +} + +char *ex2in(x, isdir, pdosflag) +char *x; /* external file name */ +int isdir; /* input: x is a directory */ +int *pdosflag; /* output: force MSDOS file attributes? */ +/* Convert the external file name to a zip file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *n; /* internal file name (malloc'ed) */ + char *t; /* shortened name */ + int dosflag; + + dosflag = dosify; /* default for non-DOS and non-OS/2 */ + + /* Find starting point in name before doing malloc */ + for (t = x; *t == '/'; t++) + ; + + if (*t == '=') /* AOS/VS for ./ */ + t++; + else if (*t == ':') /* AOS/VS for / */ + t++; + + if (!pathput) + t = last(t, PATH_END); + + if (*t == '^') /* AOS/VS for ../ */ + { + if ((n = malloc(strlen(t) + 3)) == NULL) + return NULL; + strcpy(n, "../"); + strcpy(n + 3, t + 1); + } + else if (*t == '@') /* AOS/VS for :PER:, kind of like /dev/ */ + { + if ((n = malloc(strlen(t) + 5)) == NULL) + return NULL; + strcpy(n, "/PER/"); + strcpy(n + 5, t + 1); + } + else + { + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + } + /* now turn AOS/VS dir separators (colons) into slashes */ + for (t = n; *t != '\0'; t++) + if (*t == ':') + *t = '/'; + /* + * Convert filename to uppercase (for correct matching). + * (It may make more sense to patch the matching code, since + * we may want those filenames in uppercase on the target system, + * but this seems better at present. If we're converting, uppercase + * also seems to make sense.) + */ + strupper(n); + + + if (dosify) + msname(n); + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + return n; +} + + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + + return x; +} + +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ + time_t u[2]; /* argument for utime() */ + + /* Convert DOS time to time_t format in u */ + u[0] = u[1] = dos2unixtime(d); + utime(f, u); +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + /* convert FNMAX to malloc - 11/8/04 EG */ + char *name; + int len = strlen(f); + + if (f == label) { + if (a != NULL) + *a = label_mode; + if (n != NULL) + *n = -2L; /* convention for a label name */ + if (t != NULL) + t->atime = t->mtime = t->ctime = label_utim; + return label_time; + } + if ((name = malloc(len + 1)) == NULL) { + ZIPERR(ZE_MEM, "filetime"); + } + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + + if (strcmp(f, "-") == 0) { + if (fstat(fileno(stdin), &s) != 0) + error("fstat(stdin)"); + } else if (LSSTAT(name, &s) != 0) { + /* Accept about any file kind including directories + * (stored with trailing / with -r option) + */ + free(name); + return 0; + } + free(name); + + if (a != NULL) { + *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE); + if ((s.st_mode & S_IFDIR) != 0) { + *a |= MSDOS_DIR_ATTR; + } + } + if (n != NULL) + *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_ctime; + } + + return unix2dostime(&s.st_ctime); +} + +int deletedir(d) +char *d; +{ + return rmdir(d); +} + +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; + /* create extra field and change z->att if desired */ + /* NOTE: this AOS/VS version assumes the pathname in z->name is an + * AOS/VS pathname, not a unix-style one. Since you can zip up using + * unix-style pathnames, this may create problems occasionally. + * We COULD add code to parse back to AOS/VS format ... + * (This might also fail for other reasons such as access denied, but + * that should already have occurred.) + * We set the central-dir extra fld pointer & length here to the same data. + */ +{ + int aclend = 0; +/* + * use this to simplify because different calls depending on + * whether links are resolved + */ + unsigned short errc; + + z->ext = 0; /* init to no extra field */ +/* get the ?FSTAT info & the acl - if no errors, get memory & store. + * (first, we have to cut off the trailing slash that was added if + * it's a dir, since AOS/VS doesn't accept that kind of thing) + */ + strncpy(znamebuf, z->name, $MXPL); + znamebuf[$MXPL-1] = '\0'; + if (znamebuf[strlen(znamebuf)-1] == '/') + znamebuf[strlen(znamebuf)-1] = '\0'; + if (linkput) + errc = sys_fstat(znamebuf, BIT1, &(zzextrafld.fstat_packet)); + else + errc = sys_fstat(znamebuf, 0, &(zzextrafld.fstat_packet)); + if (errc) + { + fprintf(stderr, + "\n Warning: can't get ?FSTAT info & acl of %s - error %d\n ", + znamebuf, errc); + perror("sys_fstat()"); + } + else + { + /* store the ACL - or, if a link (no ACL!), store the resolution name */ + if (zzextrafld.fstat_packet.norm_fstat_packet.styp_type != $FLNK) + { + if ((errc = sys_gacl(znamebuf, zzextrafld.aclbuf)) != 0) + { + fprintf(stderr, "\n Warning: can't get acl of %s - error %d\n ", + z->name, errc); + perror("sys_gacl()"); + } + else + { + /* find length of ACL - ends with double-null */ + while (aclend++ < $MXACL && + (zzextrafld.aclbuf[aclend - 1] != '\0' || + zzextrafld.aclbuf[aclend] != '\0')) + /* EMPTY LOOP */ ; + if ((z->cextra = z->extra = + malloc(sizeof(ZEXTRAFLD) - $MXACL + aclend + 4)) != NULL) + { + strncpy(zzextrafld.extra_header_id, ZEXTRA_HEADID, + sizeof(zzextrafld.extra_header_id)); + strncpy(zzextrafld.extra_sentinel, ZEXTRA_SENTINEL, + sizeof(zzextrafld.extra_sentinel)); + zzextrafld.extra_rev = ZEXTRA_REV; /* this is a char, no need + to worry about byte order */ + /* set size (Intel (little-endian)) 2-byte int, which we've set + as array to make it easier */ + errc = (unsigned short) (sizeof(ZEXTRAFLD) - $MXACL + aclend + 4 - + sizeof(zzextrafld.extra_header_id) - + sizeof(zzextrafld.extra_data_size)); + zzextrafld.extra_data_size[0] = errc & 0xFF; /* low-order byte */ + zzextrafld.extra_data_size[1] = errc >> 8; /* high-order byte */ + memcpy((char *) z->extra, (char *) &zzextrafld, + sizeof(ZEXTRAFLD) - $MXACL + aclend + 4); + z->cext = z->ext = sizeof(ZEXTRAFLD) - $MXACL + aclend + 4; + } + } + } + else /* a link */ + { + if ((errc = sys_glink(z->name, zzextrafld.aclbuf)) != 0) + { + fprintf(stderr, + "\n Warning: can't get link-resolution of %s - error %d\n ", + z->name, errc); + perror("sys_glink()"); + } + else + { + aclend = strlen(zzextrafld.aclbuf) + 1; + if ((z->extra = malloc(sizeof(ZEXTRAFLD) - $MXACL + aclend + 4)) + != NULL) + { + strncpy(zzextrafld.extra_header_id, ZEXTRA_HEADID, + sizeof(zzextrafld.extra_header_id)); + strncpy(zzextrafld.extra_sentinel, ZEXTRA_SENTINEL, + sizeof(zzextrafld.extra_sentinel)); + zzextrafld.extra_rev = ZEXTRA_REV; /* this is a char, no need + to worry about byte order */ + /* set size (Intel (little-endian)) 2-byte int, which we've set + as array to make it easier */ + errc = (unsigned short) (sizeof(ZEXTRAFLD) - $MXACL + aclend + 4 - + sizeof(zzextrafld.extra_header_id) - + sizeof(zzextrafld.extra_data_size)); + zzextrafld.extra_data_size[0] = errc & 0xFF; /* low-order byte */ + zzextrafld.extra_data_size[1] = errc >> 8; /* high-order byte */ + memcpy((char *) z->extra, (char *) &zzextrafld, + sizeof(ZEXTRAFLD) - $MXACL + aclend + 4); + z->ext = sizeof(ZEXTRAFLD) - $MXACL + aclend + 4; + } + } + } + } + return ZE_OK; +} + +#endif /* !UTIL */ + +void version_local() +{ + printf("Compiled with %s under %s.\n", + "a C compiler", + "AOS/VS" + ); +} + + +/* + * This file defines for AOS/VS two Unix functions relating to links; + * the calling code should have the following defines: + * + * #define lstat(path,buf) zvs_lstat(path,buf) + * #define readlink(path,buf,nbytes) zvs_readlink(path,buf,nbytes) + * + * For these functions, I'm going to define yet 2 MORE filename buffers + * and also insert code to change pathnames to Unix & back. This is + * easier than changing all the other places this kind of thing happens to + * be efficient. This is a kludge. I'm also going to put the functions + * here for my immediate convenience rather than somewhere else for + * someone else's. + * + * WARNING: the use of static buffers means that you'd better get your + * data out of these buffers before the next call to any of these functions! + * + */ + +/* ========================================================================= + * ZVS_LSTAT() - get (or simulate) stat information WITHOUT following symlinks + * This is intended to look to the outside like the unix lstat() + * function. We do a quick-&-dirty filename conversion. + * + * If the file is NOT a symbolic link, we can just do a stat() on it and + * that should be fine. But if it IS a link, we have to set the elements + * of the stat struct ourselves, since AOS/VS doesn't have a built-in + * lstat() function. + * + * RETURNS: 0 on success, or -1 otherwise + * + */ + +int zvs_lstat(char *path, struct stat *buf) +{ + char *cp_vs = vsnamebuf; + char *cp_ux = path; + int mm, dd, yy; + + /* + * Convert the Unix pathname to an AOS/VS pathname. + * This is quick & dirty; it won't handle (for instance) pathnames with + * ../ in the middle of them, and may choke on other Unixisms. We hope + * they're unlikely. + */ + if (!strncmp(cp_ux, "../", 3)) + { + *cp_vs++ = '^'; /* AOS/VS for ../ */ + cp_ux += 3; + } + else if (!strncmp(cp_ux, "./", 2)) + { + *cp_vs++ = '='; /* AOS/VS for ./ */ + cp_ux += 2; + } + + do + { + if (*cp_ux == '/') + { + *cp_vs++ = ':'; + } + else + { + *cp_vs++ = (char) toupper(*cp_ux); + } + + } while (*cp_ux++ != '\0' && cp_vs - vsnamebuf < sizeof(vsnamebuf)); + + /* If Unix name was too long for our buffer, return an error return */ + if (cp_vs - vsnamebuf >= sizeof(vsnamebuf) && *(cp_vs - 1) != '\0') + return (-1); /* error */ + + /* Make AOS/VS ?FSTAT call that won't follow links & see if we find + * anything. If not, we return error. + */ + if (sys_fstat(vsnamebuf, + BIT1, /* BIT1 says to not resolve links */ + &vsfstatbuf)) + return (-1); /* error */ + + /* If we DID find the file but it's not a link, + * call stat() and return its value. + */ + if (vsfstatbuf.styp_type != $FLNK) + return (stat(path, buf)); /* call with Unix pathname ... */ + + /* Otherwise, we have to kludge up values for the stat structure */ + memset((char *) buf, 0, sizeof(*buf)); /* init to nulls (0 values) */ + buf->st_mode = S_IFLNK | 0777; /* link and rwxrwxrwx */ + buf->st_uid = -1; /* this is what we get on AOS/VS + anyway (maybe unless we set up + a dummy password file?) */ + buf->st_nlink = 1; + /* The DG date we've got is days since 12/31/67 and seconds/2. So we + * need to subtract 732 days (if that's not negative), convert to seconds, + * and add adjusted seconds. + */ + if (vsfstatbuf.stch.short_time[0] < 732) + buf->st_ctime = buf->st_mtime = buf->st_atime = 0L; + else + { + buf->st_ctime = buf->st_mtime = buf->st_atime = + ((long) vsfstatbuf.stch.short_time[0] - 732L) * 24L * 3600L + + 2L * (long) vsfstatbuf.stch.short_time[1]; + } + + /* And we need to get the filename linked to and use its length as + * the file size. We'll use the Unix pathname buffer for this - hope + * it's big enough. (We won't overwrite anything, but we could get a + * truncated path.) If there's an error, here's our last chance to + * say anything. + */ + if ((buf->st_size = zvs_readlink(vsnamebuf, uxnamebuf, FNMAX)) < 0) + return (-1); + else + return (0); + +} /* end zvs_lstat() */ + +/* ========================================================================= + * ZVS_READLINK() - get pathname pointed to by an AOS/VS link file + * This is intended to look to the outside like the unix readlink() + * function. We do a quick-&-dirty filename conversion. + * + * RETURNS: the length of the output path (in bytes), or -1 if an error + * + */ + +int zvs_readlink(char *path, char *buf, int nbytes) +{ + char *cp_vs = vsnamebuf; + char *cp_ux = buf; + + /* This is called with z->name, the filename the user gave, so we'll get + * the link-resolution name on the assumption that it's a valid AOS/VS + * name. We're also assuming a reasonable value (> 5) for nbytes. + */ + if (sys_glink(path, vsnamebuf)) + return (-1); /* readlink() is supposed to return -1 on error */ + + /* Now, convert the AOS/VS pathname to a Unix pathname. + * Note that sys_glink(), unlike readlink(), does add a null. + */ + if (*cp_vs == '^') /* AOS/VS for ../ */ + { + strncpy(cp_ux, "../", 3); + cp_ux += 3; + cp_vs++; + } + else if (*cp_vs == '@') /* AOS/VS for :PER:, kind of like /dev/ */ + { + strncpy(cp_ux, "/PER/", 5); + cp_ux += 5; + cp_vs++; + } + else if (*cp_vs == '=') /* AOS/VS for ./ */ + { + strncpy(cp_ux, "./", 2); + cp_ux += 2; + cp_vs++; + } + while (*cp_vs != '\0' && cp_ux - buf < nbytes) + { + if (*cp_vs == ':') + { + *cp_ux++ = '/'; + } + else + { + *cp_ux++ = (char) toupper(*cp_vs); + } + cp_vs++; + } + + return (cp_ux - buf); /* # characters in Unix path (no trailing null) */ + +} /* end zvs_readlink() */ diff --git a/aosvs/make.cli b/aosvs/make.cli new file mode 100644 index 0000000..32b2624 --- /dev/null +++ b/aosvs/make.cli @@ -0,0 +1,5 @@ +push +prompt pop +sea :c_4.10 :c_4.10:lang_rt [!sea] +cc%0/%/link/NOUNX AOS_VS/DEFINE NODIR/DEFINE .C +pop diff --git a/api.c b/api.c new file mode 100644 index 0000000..b6f57e7 --- /dev/null +++ b/api.c @@ -0,0 +1,718 @@ +/* + api.c - Zip 3 + + Copyright (c) 1990-2007 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/*--------------------------------------------------------------------------- + + api.c + + This module supplies a Zip dll engine for use directly from C/C++ + programs. + + The entry points are: + + ZpVer *ZpVersion(void); + int EXPENTRY ZpInit(LPZIPUSERFUNCTIONS lpZipUserFunc); + int EXPENTRY ZpArchive(ZCL C, LPZPOPT Opts); + + This module is currently only used by the Windows dll, and is not used at + all by any of the other platforms, although it should be easy enough to + implement this on most platforms. + + ---------------------------------------------------------------------------*/ +#define __API_C + +#include +#ifdef WINDLL +# include +# include "windll/windll.h" +#endif + +#ifdef OS2 +# define INCL_DOSMEMMGR +# include +#endif + +#ifdef __BORLANDC__ +#include +#endif +#include +#include +#include "api.h" /* this includes zip.h */ +#include "crypt.h" +#include "revision.h" +#ifdef USE_ZLIB +# include "zlib.h" +#endif + + +DLLPRNT *lpZipPrint; +DLLPASSWORD *lpZipPassword; +extern DLLCOMMENT *lpComment; +ZIPUSERFUNCTIONS ZipUserFunctions, far * lpZipUserFunctions; + +int ZipRet; +char szOrigDir[PATH_MAX]; +BOOL fNo_int64 = FALSE; /* flag for DLLSERVICE_NO_INT64 */ + +/* Local forward declarations */ +extern int zipmain OF((int, char **)); +int AllocMemory(unsigned int, char *, char *, BOOL); +int ParseString(LPSTR, unsigned int); +void FreeArgVee(void); + +ZPOPT Options; +char **argVee; +unsigned int argCee; + +/*--------------------------------------------------------------------------- + Local functions + ---------------------------------------------------------------------------*/ + +char szRootDir[PATH_MAX], szExcludeList[PATH_MAX], szIncludeList[PATH_MAX], szTempDir[PATH_MAX]; + +int ParseString(LPSTR s, unsigned int ArgC) +{ +unsigned int i; +int root_flag, m, j; +char *str1, *str2, *str3; +size_t size; + +i = ArgC; +str1 = (char *) malloc(lstrlen(s)+4); +lstrcpy(str1, s); +lstrcat(str1, " @"); + +if ((szRootDir != NULL) && (szRootDir[0] != '\0')) + { + root_flag = TRUE; + if (szRootDir[lstrlen(szRootDir)-1] != '\\') + lstrcat(szRootDir, "\\"); + } +else + root_flag = FALSE; + +str2 = strchr(str1, '\"'); /* get first occurance of double quote */ + +while ((str3 = strchr(str1, '\t')) != NULL) + { + str3[0] = ' '; /* Change tabs into a single space */ + } + +/* Note that if a quoted string contains multiple adjacent spaces, they + will not be removed, because they could well point to a valid + folder/file name. +*/ +while ((str2 = strchr(str1, '\"')) != NULL) + /* Found a double quote if not NULL */ + { + str3 = strchr(str2+1, '\"'); /* Get the second quote */ + if (str3 == NULL) + { + free(str1); + return ZE_PARMS; /* Something is screwy with the + string, bail out */ + } + str3[0] = '\0'; /* terminate str2 with a NULL */ + + /* strip unwanted fully qualified path from entry */ + if (root_flag) + if ((_strnicmp(szRootDir, str2+1, lstrlen(szRootDir))) == 0) + { + m = 0; + str2++; + for (j = lstrlen(szRootDir); j < lstrlen(str2); j++) + str2[m++] = str2[j]; + str2[m] = '\0'; + str2--; + } + size = _msize(argVee); + if ((argVee = (char **)realloc(argVee, size + sizeof(char *))) == NULL) + { + fprintf(stdout, "Unable to allocate memory in zip dll\n"); + return ZE_MEM; + } + /* argCee is incremented in AllocMemory */ + if (AllocMemory(i, str2+1, "Creating file list from string", TRUE) != ZE_OK) + { + free(str1); + return ZE_MEM; + } + i++; + str3+=2; /* Point past the whitespace character */ + str2[0] = '\0'; /* Terminate str1 */ + lstrcat(str1, str3); + } /* end while */ + +/* points to first occurance of a space */ +str2 = strchr(str1, ' '); + +/* Go through the string character by character, looking for instances + of two spaces together. Terminate when you find the trailing @ +*/ +while ((str2[0] != '\0') && (str2[0] != '@')) + { + while ((str2[0] == ' ') && (str2[1] == ' ')) + { + str3 = &str2[1]; + str2[0] = '\0'; + lstrcat(str1, str3); + } + str2++; + } + +/* Do we still have a leading space? */ +if (str1[0] == ' ') + { + str3 = &str1[1]; + lstrcpy(str1, str3); /* Dump the leading space */ + } + + +/* Okay, now we have gotten rid of any tabs and replaced them with + spaces, and have replaced multiple spaces with a single space. We + couldn't do this before because the folder names could have actually + contained these characters. +*/ + +str2 = str3 = str1; + +while ((str2[0] != '\0') && (str3[0] != '@')) + { + str3 = strchr(str2+1, ' '); + str3[0] = '\0'; + /* strip unwanted fully qualified path from entry */ + if (root_flag) + if ((_strnicmp(szRootDir, str2, lstrlen(szRootDir))) == 0) + { + m = 0; + for (j = lstrlen(Options.szRootDir); j < lstrlen(str2); j++) + str2[m++] = str2[j]; + str2[m] = '\0'; + } + size = _msize(argVee); + if ((argVee = (char **)realloc(argVee, size + sizeof(char *))) == NULL) + { + fprintf(stdout, "Unable to allocate memory in zip dll\n"); + return ZE_MEM; + } + if (AllocMemory(i, str2, "Creating file list from string", TRUE) != ZE_OK) + { + free(str1); + return ZE_MEM; + } + i++; + str3++; + str2 = str3; + } +free(str1); +return ZE_OK; +} + +int AllocMemory(unsigned int i, char *cmd, char *str, BOOL IncrementArgCee) +{ +if ((argVee[i] = (char *) malloc( sizeof(char) * strlen(cmd)+1 )) == NULL) + { + if (IncrementArgCee) + argCee++; + FreeArgVee(); + fprintf(stdout, "Unable to allocate memory in zip library at %s\n", str); + return ZE_MEM; + } +strcpy( argVee[i], cmd ); +argCee++; +return ZE_OK; +} + +void FreeArgVee(void) +{ +unsigned i; + +/* Free the arguments in the array */ +for (i = 0; i < argCee; i++) + { + free (argVee[i]); + argVee[i] = NULL; + } +/* Then free the array itself */ +free(argVee); + +/* Restore the original working directory */ +chdir(szOrigDir); +#ifdef __BORLANDC__ +setdisk(toupper(szOrigDir[0]) - 'A'); +#endif + +} + + +/*--------------------------------------------------------------------------- + Documented API entry points + ---------------------------------------------------------------------------*/ + +int EXPENTRY ZpInit(LPZIPUSERFUNCTIONS lpZipUserFunc) +{ +ZipUserFunctions = *lpZipUserFunc; +lpZipUserFunctions = &ZipUserFunctions; + +if (!lpZipUserFunctions->print || + !lpZipUserFunctions->comment) + return FALSE; + +return TRUE; +} + +int EXPENTRY ZpArchive(ZCL C, LPZPOPT Opts) +/* Add, update, freshen, or delete zip entries in a zip file. See the + command help in help() zip.c */ +{ +int k, j, m; +size_t size; + +Options = *Opts; /* Save off options, and make them available locally */ +szRootDir[0] = '\0'; +szExcludeList[0] = '\0'; +szIncludeList[0] = '\0'; +szTempDir[0] = '\0'; +if (Options.szRootDir) lstrcpy(szRootDir, Options.szRootDir); +if (Options.szExcludeList) lstrcpy(szExcludeList, Options.szExcludeList); +if (Options.szIncludeList) lstrcpy(szIncludeList, Options.szIncludeList); +if (Options.szTempDir) lstrcpy(szTempDir, Options.szTempDir); + +getcwd(szOrigDir, PATH_MAX); /* Save current drive and directory */ + +if ((szRootDir != NULL) && (szRootDir[0] != '\0')) + { + /* Make sure there isn't a trailing slash */ + if (szRootDir[lstrlen(szRootDir)-1] == '\\') + szRootDir[lstrlen(szRootDir)-1] = '\0'; + + chdir(szRootDir); +#ifdef __BORLANDC__ + setdisk(toupper(szRootDir[0]) - 'A'); +#endif + } + +argCee = 0; + +/* malloc additional 40 to allow for additional command line arguments. Note + that we are also adding in the count for the include lists as well as the + exclude list. */ +if ((argVee = (char **)malloc((C.argc+40)*sizeof(char *))) == NULL) + { + fprintf(stdout, "Unable to allocate memory in zip dll\n"); + return ZE_MEM; + } +if ((argVee[argCee] = (char *) malloc( sizeof(char) * strlen("wiz.exe")+1 )) == NULL) + { + free(argVee); + fprintf(stdout, "Unable to allocate memory in zip dll\n"); + return ZE_MEM; + } +strcpy( argVee[argCee], "wiz.exe" ); +argCee++; + + +/* Set compression level efficacy -0...-9 */ +if (AllocMemory(argCee, "-0", "Compression", FALSE) != ZE_OK) + return ZE_MEM; + +/* Check to see if the compression level is set to a valid value. If + not, then set it to the default. +*/ +if ((Options.fLevel < '0') || (Options.fLevel > '9')) + { + Options.fLevel = '6'; + if (!Options.fDeleteEntries) + fprintf(stdout, "Compression level set to invalid value. Setting to default\n"); + } + +argVee[argCee-1][1] = Options.fLevel; + +if (Options.fOffsets) /* Update offsets for SFX prefix */ + { + if (AllocMemory(argCee, "-A", "Offsets", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fDeleteEntries) /* Delete files from zip file -d */ + { + if (AllocMemory(argCee, "-d", "Delete", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fNoDirEntries) /* Do not add directory entries -D */ + { + if (AllocMemory(argCee, "-D", "No Dir Entries", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fFreshen) /* Freshen zip file--overwrite only -f */ + { + if (AllocMemory(argCee, "-f", "Freshen", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fRepair) /* Fix archive -F or -FF */ + { + if (Options.fRepair == 1) + { + if (AllocMemory(argCee, "-F", "Repair", FALSE) != ZE_OK) + return ZE_MEM; + } + else + { + if (AllocMemory(argCee, "-FF", "Repair", FALSE) != ZE_OK) + return ZE_MEM; + } + } +if (Options.fGrow) /* Allow appending to a zip file -g */ + { + if (AllocMemory(argCee, "-g", "Appending", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fJunkDir) /* Junk directory names -j */ + { + if (AllocMemory(argCee, "-j", "Junk Dir Names", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fEncrypt) /* encrypt -e */ + { + if (AllocMemory(argCee, "-e", "Encrypt", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fJunkSFX) /* Junk sfx prefix */ + { + if (AllocMemory(argCee, "-J", "Junk SFX", FALSE) != ZE_OK) + return ZE_MEM; + } + +if (Options.fForce) /* Make entries using DOS names (k for Katz) -k */ + { + if (AllocMemory(argCee, "-k", "Force DOS", FALSE) != ZE_OK) + return ZE_MEM; + } + +if (Options.fLF_CRLF) /* Translate LF_CRLF -l */ + { + if (AllocMemory(argCee, "-l", "LF-CRLF", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fCRLF_LF) /* Translate CR/LF to LF -ll */ + { + if (AllocMemory(argCee, "-ll", "CRLF-LF", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fMove) /* Delete files added to or updated in zip file -m */ + { + if (AllocMemory(argCee, "-m", "Move", FALSE) != ZE_OK) + return ZE_MEM; + } + +if (Options.fLatestTime) /* Set zip file time to time of latest file in it -o */ + { + if (AllocMemory(argCee, "-o", "Time", FALSE) != ZE_OK) + return ZE_MEM; + } + +if (Options.fComment) /* Add archive comment "-z" */ + { + if (AllocMemory(argCee, "-z", "Comment", FALSE) != ZE_OK) + return ZE_MEM; + } + +if (Options.fQuiet) /* quiet operation -q */ + { + if (AllocMemory(argCee, "-q", "Quiet", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fRecurse == 1) /* recurse into subdirectories -r */ + { + if (AllocMemory(argCee, "-r", "Recurse -r", FALSE) != ZE_OK) + return ZE_MEM; + } +else if (Options.fRecurse == 2) /* recurse into subdirectories -R */ + { + if (AllocMemory(argCee, "-R", "Recurse -R", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fSystem) /* include system and hidden files -S */ + { + if (AllocMemory(argCee, "-S", "System", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fExcludeDate) /* Exclude files newer than specified date -tt */ + { + if ((Options.Date != NULL) && (Options.Date[0] != '\0')) + { + if (AllocMemory(argCee, "-tt", "Date", FALSE) != ZE_OK) + return ZE_MEM; + if (AllocMemory(argCee, Options.Date, "Date", FALSE) != ZE_OK) + return ZE_MEM; + } + } + +if (Options.fIncludeDate) /* include files newer than specified date -t */ + { + if ((Options.Date != NULL) && (Options.Date[0] != '\0')) + { + if (AllocMemory(argCee, "-t", "Date", FALSE) != ZE_OK) + return ZE_MEM; + if (AllocMemory(argCee, Options.Date, "Date", FALSE) != ZE_OK) + return ZE_MEM; + } + } + +if (Options.fUpdate) /* Update zip file--overwrite only if newer -u */ + { + if (AllocMemory(argCee, "-u", "Update", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fVerbose) /* Mention oddities in zip file structure -v */ + { + if (AllocMemory(argCee, "-v", "Verbose", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.fVolume) /* Include volume label -$ */ + { + if (AllocMemory(argCee, "-$", "Volume", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.szSplitSize != NULL) /* Turn on archive splitting */ + { + if (AllocMemory(argCee, "-s", "Splitting", FALSE) != ZE_OK) + return ZE_MEM; + if (AllocMemory(argCee, Options.szSplitSize, "Split size", FALSE) != ZE_OK) + return ZE_MEM; + } +if (lpZipUserFunctions->split != NULL) /* Turn on archive split destinations select */ + { + if (AllocMemory(argCee, "-sp", "Split Pause Select Destination", FALSE) != ZE_OK) + return ZE_MEM; + } +#ifdef WIN32 +if (Options.fPrivilege) /* Use privileges -! */ + { + if (AllocMemory(argCee, "-!", "Privileges", FALSE) != ZE_OK) + return ZE_MEM; + } +#endif +if (Options.fExtra) /* Exclude extra attributes -X */ + { + if (AllocMemory(argCee, "-X", "Extra", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.IncludeList != NULL) /* Include file list -i */ + { + if (AllocMemory(argCee, "-i", "Include file list", FALSE) != ZE_OK) + return ZE_MEM; + k = 0; + if (Options.IncludeListCount > 0) + while ((Options.IncludeList[k] != NULL) && (Options.IncludeListCount != k+1)) + { + size = _msize(argVee); + if ((argVee = (char **)realloc(argVee, size + sizeof(char *))) == NULL) + { + fprintf(stdout, "Unable to allocate memory in zip dll\n"); + return ZE_MEM; + } + if (AllocMemory(argCee, Options.IncludeList[k], "Include file list array", TRUE) != ZE_OK) + { + return ZE_MEM; + } + k++; + } + else + while (Options.IncludeList[k] != NULL) + { + size = _msize(argVee); + if ((argVee = (char **)realloc(argVee, size + sizeof(char *))) == NULL) + { + FreeArgVee(); + fprintf(stdout, "Unable to allocate memory in zip dll\n"); + return ZE_MEM; + } + if (AllocMemory(argCee, Options.IncludeList[k], "Include file list array", TRUE) != ZE_OK) + return ZE_MEM; + k++; + } + + if (AllocMemory(argCee, "@", "End of Include List", FALSE) != ZE_OK) + return ZE_MEM; + } +if (Options.ExcludeList != NULL) /* Exclude file list -x */ + { + if (AllocMemory(argCee, "-x", "Exclude file list", FALSE) != ZE_OK) + return ZE_MEM; + k = 0; + if (Options.ExcludeListCount > 0) + while ((Options.ExcludeList[k] != NULL) && (Options.ExcludeListCount != k+1)) + { + size = _msize(argVee); + if ((argVee = (char **)realloc(argVee, size + sizeof(char *))) == NULL) + { + fprintf(stdout, "Unable to allocate memory in zip dll\n"); + return ZE_MEM; + } + if (AllocMemory(argCee, Options.ExcludeList[k], "Exclude file list array", TRUE) != ZE_OK) + return ZE_MEM; + k++; + } + else + while (Options.ExcludeList[k] != NULL) + { + size = _msize(argVee); + if ((argVee = (char **)realloc(argVee, size + sizeof(char *))) == NULL) + { + FreeArgVee(); + fprintf(stdout, "Unable to allocate memory in zip dll\n"); + return ZE_MEM; + } + if (AllocMemory(argCee, Options.ExcludeList[k], "Exclude file list array", TRUE) != ZE_OK) + return ZE_MEM; + k++; + } + if (AllocMemory(argCee, "@", "End of Exclude List", FALSE) != ZE_OK) + return ZE_MEM; + } + +if (szIncludeList != NULL && szIncludeList[0] != '\0') /* Include file list -i */ + { + if (AllocMemory(argCee, "-i", "Include file list", FALSE) != ZE_OK) + return ZE_MEM; + if ((k = ParseString(szIncludeList, argCee)) != ZE_OK) + return k; /* Something was screwy with the parsed string + bail out */ + if (AllocMemory(argCee, "@", "End of Include List", FALSE) != ZE_OK) + return ZE_MEM; + } +if (szExcludeList != NULL && szExcludeList[0] != '\0') /* Exclude file list -x */ + { + if (AllocMemory(argCee, "-x", "Exclude file list", FALSE) != ZE_OK) + return ZE_MEM; + + if ((k = ParseString(szExcludeList, argCee)) != ZE_OK) + return k; /* Something was screwy with the parsed string + bail out */ + + if (AllocMemory(argCee, "@", "End of Exclude List", FALSE) != ZE_OK) + return ZE_MEM; + } + +if ((szTempDir != NULL) && (szTempDir[0] != '\0') + && Options.fTemp) /* Use temporary directory -b */ + { + if (AllocMemory(argCee, "-b", "Temp dir switch command", FALSE) != ZE_OK) + return ZE_MEM; + if (AllocMemory(argCee, szTempDir, "Temporary directory", FALSE) != ZE_OK) + return ZE_MEM; + } + +if (AllocMemory(argCee, C.lpszZipFN, "Zip file name", FALSE) != ZE_OK) + return ZE_MEM; + +if ((szRootDir != NULL) && (szRootDir[0] != '\0')) + { + if (szRootDir[lstrlen(szRootDir)-1] != '\\') + lstrcat(szRootDir, "\\"); /* append trailing \\ */ + if (C.FNV != NULL) + { + for (k = 0; k < C.argc; k++) + { + if (AllocMemory(argCee, C.FNV[k], "Making argv", FALSE) != ZE_OK) + return ZE_MEM; + if ((_strnicmp(szRootDir, C.FNV[k], lstrlen(szRootDir))) == 0) + { + m = 0; + for (j = lstrlen(szRootDir); j < lstrlen(C.FNV[k]); j++) + argVee[argCee-1][m++] = C.FNV[k][j]; + argVee[argCee-1][m] = '\0'; + } + } + } + + } +else + if (C.FNV != NULL) + for (k = 0; k < C.argc; k++) + { + if (AllocMemory(argCee, C.FNV[k], "Making argv", FALSE) != ZE_OK) + return ZE_MEM; + } + +if (C.lpszAltFNL != NULL) + { + if ((k = ParseString(C.lpszAltFNL, argCee)) != ZE_OK) + return k; /* Something was screwy with the parsed string + bail out + */ + } + + + +argVee[argCee] = NULL; + +ZipRet = zipmain(argCee, argVee); + +/* Free the arguments in the array. Note this also restores the + current directory + */ +FreeArgVee(); + +return ZipRet; +} + +#if CRYPT +int encr_passwd(int modeflag, char *pwbuf, int size, const char *zfn) + { + return (*lpZipUserFunctions->password)(pwbuf, size, ((modeflag == ZP_PW_VERIFY) ? + "Verify password: " : "Enter password: "), + (char *)zfn); + } +#endif /* CRYPT */ + +void EXPENTRY ZpVersion(ZpVer far * p) /* should be pointer to const struct */ + { + p->structlen = ZPVER_LEN; + +#ifdef BETA + p->flag = 1; +#else + p->flag = 0; +#endif +#ifdef CRYPT + p->fEncryption = TRUE; +#else + p->fEncryption = FALSE; +#endif + lstrcpy(p->betalevel, Z_BETALEVEL); + lstrcpy(p->date, REVDATE); + +#ifdef ZLIB_VERSION + lstrcpy(p->zlib_version, ZLIB_VERSION); + p->flag |= 2; +#else + p->zlib_version[0] = '\0'; +#endif + +#ifdef ZIP64_SUPPORT + p->flag |= 4; /* Flag that ZIP64 was compiled in. */ +#endif + + p->zip.major = Z_MAJORVER; + p->zip.minor = Z_MINORVER; + p->zip.patchlevel = Z_PATCHLEVEL; + +#ifdef OS2 + p->os2dll.major = D2_MAJORVER; + p->os2dll.minor = D2_MINORVER; + p->os2dll.patchlevel = D2_PATCHLEVEL; +#endif +#ifdef WINDLL + p->windll.major = DW_MAJORVER; + p->windll.minor = DW_MINORVER; + p->windll.patchlevel = DW_PATCHLEVEL; +#endif + } diff --git a/api.h b/api.h new file mode 100644 index 0000000..f609633 --- /dev/null +++ b/api.h @@ -0,0 +1,184 @@ +/* + api.h - Zip 3 + + Copyright (c) 1990-2007 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* Only the Windows DLL is currently supported */ +#ifndef _ZIPAPI_H +#define _ZIPAPI_H + +#include "zip.h" + +#ifdef WIN32 +# ifndef PATH_MAX +# define PATH_MAX 260 +# endif +#else +# ifndef PATH_MAX +# define PATH_MAX 128 +# endif +#endif + +#if defined(WINDLL) || defined(API) +#include +/* Porting definations between Win 3.1x and Win32 */ +#ifdef WIN32 +# define far +# define _far +# define __far +# define near +# define _near +# define __near +#endif + +/*--------------------------------------------------------------------------- + Prototypes for public Zip API (DLL) functions. + ---------------------------------------------------------------------------*/ + +#define ZPVER_LEN sizeof(ZpVer) +/* These defines are set to zero for now, until OS/2 comes out + with a dll. + */ +#define D2_MAJORVER 0 +#define D2_MINORVER 0 +#define D2_PATCHLEVEL 0 + +/* intended to be a private struct: */ +typedef struct _zip_ver { + uch major; /* e.g., integer 5 */ + uch minor; /* e.g., 2 */ + uch patchlevel; /* e.g., 0 */ + uch not_used; +} _zip_version_type; + +typedef struct _ZpVer { + ulg structlen; /* length of the struct being passed */ + ulg flag; /* bit 0: is_beta bit 1: uses_zlib */ + char betalevel[10]; /* e.g., "g BETA" or "" */ + char date[20]; /* e.g., "4 Sep 95" (beta) or "4 September 1995" */ + char zlib_version[10]; /* e.g., "0.95" or NULL */ + BOOL fEncryption; /* TRUE if encryption enabled, FALSE otherwise */ + _zip_version_type zip; + _zip_version_type os2dll; + _zip_version_type windll; +} ZpVer; + +# ifndef EXPENTRY +# define EXPENTRY WINAPI +# endif + +#ifndef DEFINED_ONCE +#define DEFINED_ONCE +typedef int (WINAPI DLLPRNT) (LPSTR, unsigned long); +typedef int (WINAPI DLLPASSWORD) (LPSTR, int, LPCSTR, LPCSTR); +#endif +#ifdef ZIP64_SUPPORT +typedef int (WINAPI DLLSERVICE) (LPCSTR, unsigned __int64); +typedef int (WINAPI DLLSERVICE_NO_INT64) (LPCSTR, unsigned long, unsigned long); +#else +typedef int (WINAPI DLLSERVICE) (LPCSTR, unsigned long); +#endif +typedef int (WINAPI DLLSPLIT) (LPSTR); +typedef int (WINAPI DLLCOMMENT)(LPSTR); + +/* Structures */ + +typedef struct { /* zip options */ +LPSTR Date; /* Date to include after */ +LPSTR szRootDir; /* Directory to use as base for zipping */ +LPSTR szTempDir; /* Temporary directory used during zipping */ +BOOL fTemp; /* Use temporary directory '-b' during zipping */ +BOOL fSuffix; /* include suffixes (not implemented) */ +BOOL fEncrypt; /* encrypt files */ +BOOL fSystem; /* include system and hidden files */ +BOOL fVolume; /* Include volume label */ +BOOL fExtra; /* Exclude extra attributes */ +BOOL fNoDirEntries; /* Do not add directory entries */ +BOOL fExcludeDate; /* Exclude files newer than specified date */ +BOOL fIncludeDate; /* Include only files newer than specified date */ +BOOL fVerbose; /* Mention oddities in zip file structure */ +BOOL fQuiet; /* Quiet operation */ +BOOL fCRLF_LF; /* Translate CR/LF to LF */ +BOOL fLF_CRLF; /* Translate LF to CR/LF */ +BOOL fJunkDir; /* Junk directory names */ +BOOL fGrow; /* Allow appending to a zip file */ +BOOL fForce; /* Make entries using DOS names (k for Katz) */ +BOOL fMove; /* Delete files added or updated in zip file */ +BOOL fDeleteEntries; /* Delete files from zip file */ +BOOL fUpdate; /* Update zip file--overwrite only if newer */ +BOOL fFreshen; /* Freshen zip file--overwrite only */ +BOOL fJunkSFX; /* Junk SFX prefix */ +BOOL fLatestTime; /* Set zip file time to time of latest file in it */ +BOOL fComment; /* Put comment in zip file */ +BOOL fOffsets; /* Update archive offsets for SFX files */ +BOOL fPrivilege; /* Use privileges (WIN32 only) */ +BOOL fEncryption; /* TRUE if encryption supported, else FALSE. + this is a read only flag */ +LPSTR szSplitSize; /* This string contains the size that you want to + split the archive into. i.e. 100 for 100 bytes, + 2K for 2 k bytes, where K is 1024, m for meg + and g for gig. If this string is not NULL it + will automatically be assumed that you wish to + split an archive. */ +LPSTR szIncludeList; /* Pointer to include file list string (for VB) */ +long IncludeListCount; /* Count of file names in the include list array */ +char **IncludeList; /* Pointer to include file list array. Note that the last + entry in the array must be NULL */ +LPSTR szExcludeList; /* Pointer to exclude file list (for VB) */ +long ExcludeListCount; /* Count of file names in the include list array */ +char **ExcludeList; /* Pointer to exclude file list array. Note that the last + entry in the array must be NULL */ +int fRecurse; /* Recurse into subdirectories. 1 => -r, 2 => -R */ +int fRepair; /* Repair archive. 1 => -F, 2 => -FF */ +char fLevel; /* Compression level (0 - 9) */ +} ZPOPT, _far *LPZPOPT; + +typedef struct { + int argc; /* Count of files to zip */ + LPSTR lpszZipFN; /* name of archive to create/update */ + char **FNV; /* array of file names to zip up */ + LPSTR lpszAltFNL; /* pointer to a string containing a list of file + names to zip up, separated by whitespace. Intended + for use only by VB users, all others should set this + to NULL. */ +} ZCL, _far *LPZCL; + +typedef struct { + DLLPRNT *print; + DLLCOMMENT *comment; + DLLPASSWORD *password; + DLLSPLIT *split; /* This MUST be set to NULL unless you want to be queried + for a destination for each split archive. */ +#ifdef ZIP64_SUPPORT + DLLSERVICE *ServiceApplication64; + DLLSERVICE_NO_INT64 *ServiceApplication64_No_Int64; +#else + DLLSERVICE *ServiceApplication; +#endif +} ZIPUSERFUNCTIONS, far * LPZIPUSERFUNCTIONS; + +extern LPZIPUSERFUNCTIONS lpZipUserFunctions; + +void EXPENTRY ZpVersion(ZpVer far *); +int EXPENTRY ZpInit(LPZIPUSERFUNCTIONS lpZipUserFunc); +int EXPENTRY ZpArchive(ZCL C, LPZPOPT Opts); + +#if defined(ZIPLIB) || defined(COM_OBJECT) +# define ydays zp_ydays +#endif + + + +/* Functions not yet supported */ +#if 0 +int EXPENTRY ZpMain (int argc, char **argv); +int EXPENTRY ZpAltMain (int argc, char **argv, ZpInit *init); +#endif +#endif /* WINDLL? || API? */ + +#endif /* _ZIPAPI_H */ diff --git a/atari/Makefile b/atari/Makefile new file mode 100644 index 0000000..2c86196 --- /dev/null +++ b/atari/Makefile @@ -0,0 +1,111 @@ +# Makefile for Zip, ZipNote, ZipCloak and ZipSplit + +MAKE = make +SHELL = /bin/sh + +# (to use the Gnu compiler, change cc to gcc in CC and BIND) +CC = cc +BIND = $(CC) +AS = $(CC) -c +E = +CPP = /lib/cpp + +# probably can change this to 'install' if you have it +INSTALL = cp + +# target directories - where to install executables and man pages to +BINDIR = /usr/local/bin +manext=1 +MANDIR = /usr/local/man/man$(manext) + +# flags +# CFLAGS flags for C compile +# LFLAGS1 flags after output file spec, before obj file list +# LFLAGS2 flags after obj file list (libraries, etc) +CFLAGS = -O +LFLAGS1 = +LFLAGS2 = -s + +# object file lists +OBJZ = zip.o zipfile.o zipup.o fileio.o util.o crc32.o globals.o \ + crypt.o ttyio.o atari.o + +OBJI = deflate.o trees.o +OBJA = +OBJU = zipfile_.o fileio_.o util_.o globals.o atari_.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o $(OBJU) crc32_.o crypt_.o ttyio.o +OBJS = zipsplit.o $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h atari/osdep.h + +# suffix rules +.SUFFIXES: +.SUFFIXES: _.o .o .c .doc .1 +.c_.o: + rm -f $*_.c; ln $< $*_.c + $(CC) $(CFLAGS) -DUTIL -c $*_.c + rm -f $*_.c +.c.o: + $(CC) $(CFLAGS) -c $< + +.1.doc: + nroff -man $< | col -b | uniq > $@ + +# rules for zip, zipnote, zipcloak, zipsplit, and the Zip MANUAL. +$(OBJZ): $(ZIP_H) +$(OBJI): $(ZIP_H) +$(OBJN): $(ZIP_H) +$(OBJS): $(ZIP_H) +$(OBJC): $(ZIP_H) +zip.o crc32.o crypt.o fileio.o zipfile.o zipup.o: crc32.h +zipcloak.o crc32_.o crypt_.o fileio_.o zipfile_.o: crc32.h +zip.o zipup.o crypt.o ttyio.o zipcloak.o crypt_.o: crypt.h +zip.o zipup.o zipnote.o zipcloak.o zipsplit.o: revision.h +zip.o crypt.o ttyio.o zipcloak.o crypt_.o: ttyio.h +zipup.o: atari/zipup.h + +match.o: match.s + $(CPP) match.s > _match.s + $(AS) _match.s + mv _match.o match.o + rm -f _match.s + +ZIPS = zip$E zipnote$E zipsplit$E zipcloak$E + +zips: $(ZIPS) +zipsman: $(ZIPS) $(ZIPMANUAL) + +zip$E: $(OBJZ) $(OBJI) $(OBJA) + $(BIND) -o zip$E $(LFLAGS1) $(OBJZ) $(OBJI) $(OBJA) $(LFLAGS2) +zipnote$E: $(OBJN) + $(BIND) -o zipnote$E $(LFLAGS1) $(OBJN) $(LFLAGS2) +zipcloak$E: $(OBJC) + $(BIND) -o zipcloak$E $(LFLAGS1) $(OBJC) $(LFLAGS2) +zipsplit$E: $(OBJS) + $(BIND) -o zipsplit$E $(LFLAGS1) $(OBJS) $(LFLAGS2) + +$(ZIPMANUAL): man/zip.1 + nroff -man man/zip.1 | col -b | uniq > $(ZIPMANUAL) + +# install +install: $(ZIPS) + $(INSTALL) $(ZIPS) $(BINDIR) + $(INSTALL) man/zip.1 $(MANDIR)/zip.$(manext) + +uninstall: + -cd $(BINDIR); rm -f $(ZIPS) + -cd $(MANDIR); rm -f zip.$(manext) + +dist: $(ZIPMANUAL) + zip -u9T zip`sed -e '/VERSION/!d' -e 's/.*"\(.*\)".*/\1/' \ + -e s/[.]//g -e q revision.h` \ + `awk '/^Makefile/,/vms_zip.rnh/ {print $$1}' < contents` + +# ATARI version (gcc 2.5.8 and Mintlibs PL46) +atari: + $(MAKE) zips CFLAGS="-O -DATARI" OBJA=atari/atari.o CC=gcc E=.ttp + +# clean up after making stuff and installing it +clean: + rm -f *.o $(ZIPS) flags diff --git a/atari/README b/atari/README new file mode 100644 index 0000000..cce4206 --- /dev/null +++ b/atari/README @@ -0,0 +1,5 @@ +From: harry@hal.westfalen.de (Harald Denker) + +The old zip ATARI port is based on TurboC which is no more +supported (for more than 3 years). I used the GNU gcc 2.5.8 and +MiNTlibs PL46. diff --git a/atari/atari.c b/atari/atari.c new file mode 100644 index 0000000..ce5196c --- /dev/null +++ b/atari/atari.c @@ -0,0 +1,681 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#include "zip.h" + +#ifndef UTIL /* the companion #endif is a bit of ways down ... */ + +#include +#include +#include +#include +#include +#include + + +#define PAD 0 +#define PATH_END '/' + +extern char *label; /* defined in fileio.c */ + +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + + +local char *readd(d) +DIR *d; /* directory stream to read from */ +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e; + + e = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; +} + +local char *getVolumeLabel(drive, vtime, vmode, utim) + int drive; /* drive name: 'A' .. 'Z' or '\0' for current drive */ + ulg *vtime; /* volume label creation time (DOS format) */ + ulg *vmode; /* volume label file mode */ + time_t utim;/* volume label creation time (UNIX format) */ + +/* If a volume label exists for the given drive, return its name and + set its time and mode. The returned name must be static data. */ +{ + static char vol[14]; + _DTA *dtaptr; + + if (drive) { + vol[0] = (char)drive; + strcpy(vol+1, ":/"); + } else { + strcpy(vol, "/"); + } + strcat(vol, "*.*"); + if (Fsfirst(vol, FA_LABEL) == 0) { + dtaptr = Fgetdta(); + strncpy(vol, dtaptr->dta_name, sizeof(vol)-1); + *vtime = ((ulg)dtaptr->dta_date << 16) | + ((ulg)dtaptr->dta_time & 0xffff); + *vmode = (ulg)dtaptr->dta_attribute; + return vol; + } + return NULL; +} + +char GetFileMode(char *name) +{ + struct stat sb; + + sb.st_attr = 0; + Fxattr(linkput ? 1 : 0, name, &sb); + if (errno == EINVAL) { + _DTA *dtaptr, *old; + old = Fgetdta(); + Fsfirst(name, FA_RDONLY+FA_HIDDEN+FA_SYSTEM+FA_DIR); + dtaptr = Fgetdta(); + sb.st_attr = dtaptr->dta_attribute; + Fsetdta(old); + } + return sb.st_attr & 0x3f; +} + + +int wild2(w) +char *w; /* path/pattern to match */ +/* If not in exclude mode, expand the pattern based on the contents of the + file system. Return an error code in the ZE_ class. */ +{ + DIR *d; /* stream for reading directory */ + char *e; /* name found in directory */ + int r; /* temporary variable */ + char *n; /* constructed name from directory */ + int f; /* true if there was a match */ + char *a; /* alloc'ed space for name */ + char *p; /* path */ + char *q; /* name */ + char v[5]; /* space for device current directory */ + + if (volume_label == 1) { + volume_label = 2; + label = getVolumeLabel(w[1] == ':' ? to_up(w[0]) : '\0', + &label_time, &label_mode, &label_utim); + if (label != NULL) { + newname(label, 0, 0); + } + if (w[1] == ':' && w[2] == '\0') return ZE_OK; + /* "zip -$ foo a:" can be used to force drive name */ + } + + /* special handling of stdin request */ + if (strcmp(w, "-") == 0) /* if compressing stdin */ + return newname(w, 0, 0); + + /* Allocate and copy pattern */ + if ((p = a = malloc(strlen(w) + 1)) == NULL) + return ZE_MEM; + strcpy(p, w); + + /* Normalize path delimiter as '/'. */ + for (q = p; *q; q++) /* use / consistently */ + if (*q == '\\') + *q = '/'; + + /* Only name can have special matching characters */ + if ((q = isshexp(p)) != NULL && + (strrchr(q, '/') != NULL || strrchr(q, ':') != NULL)) + { + free((zvoid *)a); + return ZE_PARMS; + } + + /* Separate path and name into p and q */ + if ((q = strrchr(p, '/')) != NULL && (q == p || q[-1] != ':')) + { + *q++ = '\0'; /* path/name -> path, name */ + if (*p == '\0') /* path is just / */ + p = strcpy(v, "/."); + } + else if ((q = strrchr(p, ':')) != NULL) + { /* has device and no or root path */ + *q++ = '\0'; + p = strcat(strcpy(v, p), ":"); /* copy device as path */ + if (*q == '/') /* -> device:/., name */ + { + strcat(p, "/"); + q++; + } + strcat(p, "."); + } + else if (recurse && (strcmp(p, ".") == 0 || strcmp(p, "..") == 0)) + { /* current or parent directory */ + /* I can't understand Mark's code so I am adding a hack here to get + * "zip -r foo ." to work. Allow the dubious "zip -r foo .." but + * reject "zip -rm foo ..". + */ + if (dispose && strcmp(p, "..") == 0) + ziperr(ZE_PARMS, "cannot remove parent directory"); + q = "*.*"; + } + else /* no path or device */ + { + q = p; + p = strcpy(v, "."); + } + if (recurse && *q == '\0') { + q = "*.*"; + } + /* Search that level for matching names */ + if ((d = opendir(p)) == NULL) + { + free((zvoid *)a); + return ZE_MISS; + } + if ((r = strlen(p)) > 1 && + (strcmp(p + r - 2, ":.") == 0 || strcmp(p + r - 2, "/.") == 0)) + *(p + r - 1) = '\0'; + f = 0; + while ((e = readd(d)) != NULL) { + if (strcmp(e, ".") && strcmp(e, "..") && MATCH(q, e, 0)) + { + f = 1; + if (strcmp(p, ".") == 0) { /* path is . */ + r = procname(e, 0); /* name is name */ + if (r) { + f = 0; + break; + } + } else + { + if ((n = malloc(strlen(p) + strlen(e) + 2)) == NULL) + { + free((zvoid *)a); + closedir(d); + return ZE_MEM; + } + n = strcpy(n, p); + if (n[r = strlen(n) - 1] != '/' && n[r] != ':') + strcat(n, "/"); + r = procname(strcat(n, e), 0); /* name is path/name */ + free((zvoid *)n); + if (r) { + f = 0; + break; + } + } + } + } + closedir(d); + + /* Done */ + free((zvoid *)a); + return f ? ZE_OK : ZE_MISS; +} + + +#include +#include + +void regerror( char ZCONST *msg ) { + perror( msg ); +} + +static int ret; +static regexp *regptr; +static short is_w, ind_w; +static char fullpath[FILENAME_MAX], file_arg[FILENAME_MAX]; + +#define FTW_F 0 +#define FTW_D 1 +#define FTW_DNR 2 +#define FTW_NS 3 + +static int ftwfunc( struct stat *stats, int ftw_status ) +{ + char *path = &fullpath[0]; + + if (strncmp(path, "./", 2) == 0) path += 2; + switch (ftw_status) { + case FTW_NS: + zipwarn("can't stat file: ", path); + ret = ZE_MISS; + return 0; + case FTW_F: + if (!is_w || regexec(regptr, path, 1)) { +#if 0 + char fn[FILENAME_MAX]; + int k; + if (S_ISLNK(stats->st_mode) && + (k = readlink(path, fn, FILENAME_MAX)) > 0) { + int l = strlen(path); + fn[k] = '\0'; + strcat(strcat(path, " -> "), fn); + ret = newname(path, 0, 0); /* procname(path, 0); */ + path[l] = '\0'; + } else +#endif + ret = newname(path, 0, 0); /* procname(path, 0); */ + } + return 0; + case FTW_DNR: + zipwarn("can't open directory: ", path); + ret = ZE_MISS; + return 0; + case FTW_D: + if (strcmp(path, ".") == 0) return 0; + if (is_w && ind_w > 0 && strncmp(path, file_arg, ind_w) != 0) + return 4; + } + return 0; +} + +static int myftw( int depth ) +{ + register DIR *dirp; + struct dirent *entp; + struct stat stats; + register char *p,*q; + register long i; + + if (LSSTAT(fullpath, &stats) < 0) + return ftwfunc(&stats, FTW_NS); + + if (!S_ISDIR(stats.st_mode)) + return ftwfunc(&stats, FTW_F); + + if ((dirp = opendir(fullpath)) == NULL) + return ftwfunc(&stats, FTW_DNR); + + if (i = ftwfunc(&stats, FTW_D)) { + closedir(dirp); + return (i == 4 ? 0 : (int)i); + } + i = strlen(fullpath); + p = &fullpath[i]; + *p++ = '/'; *p = '\0'; + if (dirnames && i > 1) { + q = (strncmp(fullpath, "./", 2) == 0 ? &fullpath[2] : &fullpath[0]); + ret = newname(q, 1, 0); + } + i = 0; + while (depth > 0 && (entp = readdir(dirp)) != 0) + if (strcmp(entp->d_name,".") != 0 && strcmp(entp->d_name,"..") != 0) { + strcpy(p, entp->d_name); + if (i = myftw(depth-1)) + depth = 0; /* force User's finish */ + } + closedir(dirp); + return (int)i; +} + +int wild( char *p ) +{ + char *d; + + ret = ZE_OK; + if (p == NULL) p = "*"; + + if (strcmp(p, "-") == 0) /* if compressing stdin */ + ret = newname(p, 0, 0); + + strcpy(fullpath, p); + /* now turning UNIX-Wildcards into basic regular expressions */ + for (is_w = ind_w = 0, d = &file_arg[0]; *p; d++, p++) + switch (*p) { + case '*': *d++ = '.'; *d = *p; is_w = 1; break; + case '?': *d = '.'; is_w = 1; break; + case '[': *d = *p; + if (*(p+1) == '!') { + *++d = '^'; p++; + } is_w = 1; break; + case '.': *d++ = '\\'; *d = *p; break; + default : *d = *p; + if (!is_w) ind_w++; + } + *++d = '\0'; + if (is_w) { + strcat( file_arg, "$" ); /* to get things like *.[ch] work */ + if ((regptr = regcomp( file_arg )) == NULL) + return ZE_MEM; + strcpy( fullpath, "." ); + myftw( recurse ? 99 : 1 ); + free(regptr); + } else if (recurse) { + myftw( 99 ); + } else + myftw( 1 ); /* ret = procname( fullpath, 0 ); */ + return ret; +} + +int procname(n, caseflag) +char *n; /* name to process */ +int caseflag; /* true to force case-sensitive match */ +/* Process a name or sh expression to operate on (or exclude). Return + an error code in the ZE_ class. */ +{ + char *a; /* path and name for recursion */ + DIR *d; /* directory stream from opendir() */ + char *e; /* pointer to name from readd() */ + int m; /* matched flag */ + char *p; /* path for recursion */ + struct stat s; /* result of stat() */ + struct zlist far *z; /* steps through zfiles list */ + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0, caseflag); + else if (LSSTAT(n, &s)) + { + /* Not a file or directory--search for shell expression in zip file */ + p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */ + m = 1; + for (z = zfiles; z != NULL; z = z->nxt) { + if (MATCH(p, z->iname, caseflag)) + { + z->mark = pcount ? filter(z->zname, caseflag) : 1; + if (verbose) + fprintf(mesg, "zip diagnostic: %scluding %s\n", + z->mark ? "in" : "ex", z->name); + m = 0; + } + } + free((zvoid *)p); + return m ? ZE_MISS : ZE_OK; + } + + /* Live name--use if file, recurse if directory */ + for (p = n; *p; p++) /* use / consistently */ + if (*p == '\\') + *p = '/'; + if (!S_ISDIR(s.st_mode)) + { + /* add or remove name of file */ + if ((m = newname(n, 0, caseflag)) != ZE_OK) + return m; + } else { + /* Add trailing / to the directory name */ + if ((p = malloc(strlen(n)+2)) == NULL) + return ZE_MEM; + if (strcmp(n, ".") == 0) { + *p = '\0'; /* avoid "./" prefix and do not create zip entry */ + } else { + strcpy(p, n); + a = p + strlen(p); + if (a[-1] != '/') + strcpy(a, "/"); + if (dirnames && (m = newname(p, 1, caseflag)) != ZE_OK) { + free((zvoid *)p); + return m; + } + } + /* recurse into directory */ + if (recurse && (d = opendir(n)) != NULL) + { + while ((e = readd(d)) != NULL) { + if (strcmp(e, ".") && strcmp(e, "..")) + { + if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL) + { + closedir(d); + free((zvoid *)p); + return ZE_MEM; + } + strcat(strcpy(a, p), e); + if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */ + { + if (m == ZE_MISS) + zipwarn("name not matched: ", a); + else + ziperr(m, a); + } + free((zvoid *)a); + } + } + closedir(d); + } + free((zvoid *)p); + } /* (s.st_mode & S_IFDIR) == 0) */ + return ZE_OK; +} + +char *ex2in(x, isdir, pdosflag) +char *x; /* external file name */ +int isdir; /* input: x is a directory */ +int *pdosflag; /* output: force MSDOS file attributes? */ +/* Convert the external file name to a zip file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *n; /* internal file name (malloc'ed) */ + char *t, *p; /* shortened name */ + int dosflag; + + dosflag = 0; + + /* Find starting point in name before doing malloc */ + t = *x && *(x + 1) == ':' ? x + 2 : x; + while (*t == '/' || *t == '\\') + t++; + + /* Make changes, if any, to the copied name (leave original intact) */ + for (n = t; *n; n++) + if (*n == '\\') + *n = '/'; + + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); +#if 0 + if (p = strstr(t, " -> ")) /* shorten "link -> data" to "link" */ + *p = '\0'; +#endif + if (dosify) + msname(n); + + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + return n; +} + + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + return x; +} + +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ + struct utimbuf u; /* argument for utime() const ?? */ + + /* Convert DOS time to time_t format in u[0] and u[1] */ + u.actime = u.modtime = dos2unixtime(d); + + /* Set updated and accessed times of f */ + utime(f, &u); +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + /* convert FNMAX to malloc - 11/8/04 EG */ + char *name; + int len = strlen(f); + + if (f == label) { + if (a != NULL) + *a = label_mode; + if (n != NULL) + *n = -2L; /* convention for a label name */ + if (t != NULL) + t->atime = t->mtime = t->ctime = label_utim; + return label_time; + } + if ((name = malloc(len + 1)) == NULL) { + ZIPERR(ZE_MEM, "filetime"); + } + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + + if (strcmp(f, "-") == 0) { + if (fstat(fileno(stdin), &s) != 0) { + free(name); + error("fstat(stdin)"); + } + } else if (LSSTAT(name, &s) != 0) { + /* Accept about any file kind including directories + * (stored with trailing / with -r option) + */ + free(name); + return 0; + } + + if (a != NULL) { +/* *a = ((ulg)s.st_mode << 16) | (ulg)GetFileMode(name); */ + *a = ((ulg)s.st_mode << 16) | (ulg)s.st_attr; + } + free(name); + if (n != NULL) + *n = S_ISREG(s.st_mode) ? s.st_size : -1L; + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_ctime; + } + + return unix2dostime(&s.st_mtime); +} + +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; + /* create extra field and change z->att if desired */ +{ +#ifdef USE_EF_UT_TIME +#ifdef IZ_CHECK_TZ + if (!zp_tz_is_valid) return ZE_OK; /* skip silently if no valid TZ info */ +#endif + + if ((z->extra = (char *)malloc(EB_HEADSIZE+EB_UT_LEN(2))) == NULL) + return ZE_MEM; + if ((z->cextra = (char *)malloc(EB_HEADSIZE+EB_UT_LEN(1))) == NULL) + return ZE_MEM; + + z->extra[0] = 'U'; + z->extra[1] = 'T'; + z->extra[2] = EB_UT_LEN(2); /* length of data part of e.f. */ + z->extra[3] = 0; + z->extra[4] = EB_UT_FL_MTIME | EB_UT_FL_ATIME; + z->extra[5] = (char)(z_utim->mtime); + z->extra[6] = (char)(z_utim->mtime >> 8); + z->extra[7] = (char)(z_utim->mtime >> 16); + z->extra[8] = (char)(z_utim->mtime >> 24); + z->extra[9] = (char)(z_utim->atime); + z->extra[10] = (char)(z_utim->atime >> 8); + z->extra[11] = (char)(z_utim->atime >> 16); + z->extra[12] = (char)(z_utim->atime >> 24); + + z->ext = (EB_HEADSIZE+EB_UX_LEN(2)); + + memcpy(z->cextra, z->extra, (EB_HEADSIZE+EB_UT_LEN(1))); + z->cextra[EB_LEN] = EB_UT_LEN(1); + z->cext = (EB_HEADSIZE+EB_UX_LEN(1)); + + return ZE_OK; +#else /* !USE_EF_UT_TIME */ + return (int)(z-z); +#endif /* ?USE_EF_UT_TIME */ +} + +int deletedir(d) +char *d; /* directory to delete */ +/* Delete the directory *d if it is empty, do nothing otherwise. + Return the result of rmdir(), delete(), or system(). + For VMS, d must be in format [x.y]z.dir;1 (not [x.y.z]). + */ +{ + return rmdir(d); +} + +#endif /* !UTIL */ + + +/******************************/ +/* Function version_local() */ +/******************************/ + +void version_local() +{ + static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n"; +#ifdef __TURBOC__ + char buf[40]; +#endif + + printf(CompiledWith, + +#ifdef __GNUC__ + "gcc ", __VERSION__, +#else +# if 0 + "cc ", (sprintf(buf, " version %d", _RELEASE), buf), +# else +# ifdef __TURBOC__ + "Turbo C", (sprintf(buf, " (0x%04x = %d)", __TURBOC__, __TURBOC__), buf), +# else + "unknown compiler", "", +# endif +# endif +#endif + +#ifdef __MINT__ + "Atari TOS/MiNT", +#else + "Atari TOS", +#endif + + " (Atari ST/TT/Falcon030)", + +#ifdef __DATE__ + " on ", __DATE__ +#else + "", "" +#endif + ); + +} /* end function version_local() */ diff --git a/atari/make_all.mup b/atari/make_all.mup new file mode 100644 index 0000000..5f8c4dc --- /dev/null +++ b/atari/make_all.mup @@ -0,0 +1,7 @@ +rm -f *.o *.sym *.ttp +make370 SHELL=/bin/mupfel.ttp CC=gcc CFLAGS="-O -DATARI" E=.ttp OBJA=atari.o zips +#make370 SHELL=/bin/mupfel.ttp CC=gcc CFLAGS="-g -D__NO_INLINE__ -DATARI" E=.ttp OBJA=atari.o zip.ttp +#make370 SHELL=/bin/mupfel.ttp CC=gcc CFLAGS="-g -D__NO_INLINE__ -DATARI" E=.sym OBJA=atari.o zip.sym LFLAGS2="-B/bin/sym-" +#make370 SHELL=/bin/mupfel.ttp CC=gcc CFLAGS="-O -DATARI" E=.ttp OBJA=atari.o -n zips > make_all.mup +#fixstk 32K pgp.ttp +prgflags 017 007 *.ttp diff --git a/atari/make_zip.mup b/atari/make_zip.mup new file mode 100644 index 0000000..4ea4c31 --- /dev/null +++ b/atari/make_zip.mup @@ -0,0 +1,7 @@ +#rm -f *.o *.sym *.ttp +#make370 SHELL=/bin/mupfel.ttp CC=gcc CFLAGS="-O -DATARI" E=.ttp OBJA=atari.o zips +make370 SHELL=/bin/mupfel.ttp CC=gcc CFLAGS="-g -D__NO_INLINE__ -DATARI" E=.ttp OBJA=atari.o zip.ttp +make370 SHELL=/bin/mupfel.ttp CC=gcc CFLAGS="-g -D__NO_INLINE__ -DATARI" E=.sym OBJA=atari.o zip.sym LFLAGS2="-B/bin/sym-" +#make370 SHELL=/bin/mupfel.ttp CC=gcc CFLAGS="-O -DATARI" E=.ttp OBJA=atari.o -n zips > make_all.mup +#fixstk 32K pgp.ttp +prgflags 017 007 *.ttp diff --git a/atari/osdep.h b/atari/osdep.h new file mode 100644 index 0000000..46387b6 --- /dev/null +++ b/atari/osdep.h @@ -0,0 +1,20 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#define FOPR "rb" +#define FOPM "r+b" +#define FOPW "wb" + +#define DIRENT +#define NO_TERMIO +#define USE_CASE_MAP +#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \ + procname(n, 1)) + +#include +#include diff --git a/atari/zipup.h b/atari/zipup.h new file mode 100644 index 0000000..1de3f61 --- /dev/null +++ b/atari/zipup.h @@ -0,0 +1,19 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#ifndef O_RDONLY +# define O_RDONLY 0 +#endif +#define fhow O_RDONLY +#define fbad (-1) +typedef int ftype; +#define zopen(n,p) open(n,p) +#define zread(f,b,n) read(f,b,n) +#define zclose(f) close(f) +#define zerr(f) (k == (extent)(-1L)) +#define zstdin 0 diff --git a/atheos/Makefile b/atheos/Makefile new file mode 100644 index 0000000..91df1c8 --- /dev/null +++ b/atheos/Makefile @@ -0,0 +1,146 @@ +###################################################################### +# +# Makefile for Info-ZIP's zip, zipcloak, zipnote, and zipsplit on AtheOS +# +# Copyright (C) 1999-2007 Info-ZIP +# Chris Herborth (chrish@pobox.com) +# Ruslan Nickolaev (nruslan@hotbox.ru) +# +###################################################################### +# Things that don't change: + +# Punish people who don't have SMP hardware. +MAKE = make -j 4 -f atheos/Makefile +SHELL = /bin/sh + +LN = ln -s +RM = rm -f + +BIND = $(CC) +AS = as + +INSTALL = install + +# Target directories +prefix = /usr +BINDIR = $(prefix)/bin +manext = 1 +MANDIR = $(prefix)/man/man$(manext) +ZIPMANUAL = MANUAL + +VERSION = Version 2.3 of __DATE__ + +###################################################################### + +CC:=gcc +CFLAGS:=-O3 -march=i586 -Wall -I. -DHAVE_DIRENT_H -DPASSWD_FROM_STDIN -DASMV -DASM_CRC +LFLAGS1:= +LFLAGS2:= +TARGET=$(ZIPS) + +###################################################################### +# Helpful targets +all: + $(MAKE) CC=$(CC) CFLAGS="$(CFLAGS)" \ + LFLAGS1="$(LFLAGS1)" LFLAGS2="$(LFLAGS2)" \ + $(TARGET) + +###################################################################### +# Object file lists and other build goodies + +# Object file lists +OBJZ = zip.o zipfile.o zipup.o fileio.o util.o globals.o crc32.o crypt.o \ + ttyio.o atheos.o +OBJI = deflate.o trees.o +OBJA = match.o crc_i386.o +OBJU = zipfile_.o fileio_.o util_.o globals.o atheos_.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o $(OBJU) crc32_.o crypt_.o ttyio.o +OBJS = zipsplit.o $(OBJU) + +# Headers +ZIP_H = zip.h ziperr.h tailor.h atheos/osdep.h + +# What to build? +ZIPS = zip zipnote zipsplit zipcloak + +# suffix rules +.SUFFIXES: +.SUFFIXES: _.o .o .c .doc .1 +.c_.o: + $(RM) $*_.c; $(LN) $< $*_.c + $(CC) -c $(CFLAGS) -DUTIL $*_.c + $(RM) $*_.c + +.c.o: + $(CC) -c $(CFLAGS) $< + +.1.doc: + groff -man -Tascii $< > $@ + +# rules for zip, zipnote, zipcloak, zipsplit, and the Zip MANUAL. +$(OBJZ): $(ZIP_H) +$(OBJI): $(ZIP_H) +$(OBJN): $(ZIP_H) +$(OBJS): $(ZIP_H) +$(OBJC): $(ZIP_H) +zip.o crc32.o crypt.o fileio.o zipfile.o zipup.o: crc32.h +zipcloak.o crc32_.o crypt_.o fileio_.o zipfile_.o: crc32.h +zip.o zipup.o crypt.o ttyio.o zipcloak.o crypt_.o: crypt.h +zip.o zipup.o zipnote.o zipcloak.o zipsplit.o: revision.h +zip.o crypt.o ttyio.o zipcloak.o crypt_.o: ttyio.h +zipup.o: atheos/zipup.h + +match.o: match.S + $(CC) -E match.S > matchs.s + $(AS) -o $@ matchs.s + $(RM) matchs.s + +crc_i386.o: crc_i386.S + $(CC) -E crc_i386.S > crc_i386s.s + $(AS) -o $@ crc_i386s.s + $(RM) crc_i386s.s + +atheos.o: atheos/atheos.c + $(CC) -c $(CFLAGS) atheos/atheos.c + +atheos_.o: atheos/atheos.c + $(RM) $*_.c; $(LN) atheos/atheos.c $*_.c + $(CC) -c $(CFLAGS) -DUTIL $*_.c + $(RM) $*_.c + +zips: $(ZIPS) +zipsman: $(ZIPS) $(ZIPMANUAL) + +zip: $(OBJZ) $(OBJI) $(OBJA) + $(BIND) -o zip $(LFLAGS1) $(OBJZ) $(OBJI) $(OBJA) $(LFLAGS2) +zipnote: $(OBJN) + $(BIND) -o zipnote $(LFLAGS1) $(OBJN) $(LFLAGS2) +zipcloak: $(OBJC) + $(BIND) -o zipcloak $(LFLAGS1) $(OBJC) $(LFLAGS2) +zipsplit: $(OBJS) + $(BIND) -o zipsplit $(LFLAGS1) $(OBJS) $(LFLAGS2) + +$(ZIPMANUAL): man/zip.1 + groff -man -Tascii man/zip.1 > $(ZIPMANUAL) + +# install +install: $(ZIPS) + $(INSTALL) -m755 $(ZIPS) $(BINDIR) + mkdir -p $(MANDIR) + $(INSTALL) -m644 man/zip.1 $(MANDIR)/zip.$(manext) + +uninstall: + -cd $(BINDIR); $(RM) $(ZIPS) + -cd $(MANDIR); $(RM) zip.$(manext) + +dist: $(ZIPMANUAL) + zip -u9T zip`sed -e '/VERSION/!d' -e 's/.*"\(.*\)".*/\1/' \ + -e s/[.]//g -e q revision.h` \ + `awk '/^Makefile/,/vms_zip.rnh/ {print $$1}' < contents` + +# clean up after making stuff and installing it +clean: + $(RM) *.o $(ZIPS) flags + +# end of Makefile diff --git a/atheos/README b/atheos/README new file mode 100644 index 0000000..a96fffc --- /dev/null +++ b/atheos/README @@ -0,0 +1,21 @@ +Info-ZIP's zip for AtheOS/Syllable + +FEATURES + stores AtheOS/Syllable file attributes, compressing them if possible + +TODO +---- +There is only one thing to be fixed: + write_attr() should return count of writed bytes. However that's bug related with AFS only. + +Please report any bugs to Info-ZIP at www.info-zip.org. +If this bug related with AtheOS/Syllable only, you can mail me directly: nruslan@hotbox.ru. + +Visit the Info-ZIP web site (http://www.info-zip.org) for all the +latest zip and unzip information, FAQs, source code and ready-to-run +executables. + +- Ruslan Nickolaev (nruslan@hotbox.ru) + Sep 06/2004 + +(updated 12 November 2004) diff --git a/atheos/atheos.c b/atheos/atheos.c new file mode 100644 index 0000000..6f1c915 --- /dev/null +++ b/atheos/atheos.c @@ -0,0 +1,885 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html + + This AtheOS - specific file is based on unix.c and beos.c; + changes by Ruslan Nickolaev (nruslan@hotbox.ru) +*/ + +#include "zip.h" + +#ifndef UTIL /* the companion #endif is a bit of ways down ... */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define PAD 0 +#define PATH_END '/' + +/* Library functions not in (most) header files */ + +#ifdef _POSIX_VERSION +# include +#else + int utime OF((char *, time_t *)); +#endif + +extern char *label; +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +/* Local functions */ +local char *readd OF((DIR *)); +local int get_attr_dir( const char *, char **, off_t * ); +local int add_UT_ef( struct zlist far * ); +local int add_Ux_ef( struct zlist far * ); +local int add_At_ef( struct zlist far * ); + +local char *readd(d) +DIR *d; /* directory stream to read from */ +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e; + + e = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; +} + +int procname(n, caseflag) +char *n; /* name to process */ +int caseflag; /* true to force case-sensitive match */ +/* Process a name or sh expression to operate on (or exclude). Return + an error code in the ZE_ class. */ +{ + char *a; /* path and name for recursion */ + DIR *d; /* directory stream from opendir() */ + char *e; /* pointer to name from readd() */ + int m; /* matched flag */ + char *p; /* path for recursion */ + struct stat s; /* result of stat() */ + struct zlist far *z; /* steps through zfiles list */ + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0, caseflag); + else if (LSSTAT(n, &s)) + { + /* Not a file or directory--search for shell expression in zip file */ + p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */ + m = 1; + for (z = zfiles; z != NULL; z = z->nxt) { + if (MATCH(p, z->iname, caseflag)) + { + z->mark = pcount ? filter(z->zname, caseflag) : 1; + if (verbose) + fprintf(mesg, "zip diagnostic: %scluding %s\n", + z->mark ? "in" : "ex", z->name); + m = 0; + } + } + free((zvoid *)p); + return m ? ZE_MISS : ZE_OK; + } + + /* Live name--use if file, recurse if directory */ + if ((s.st_mode & S_IFREG) == S_IFREG || + (s.st_mode & S_IFLNK) == S_IFLNK) + { + /* add or remove name of file */ + if ((m = newname(n, 0, caseflag)) != ZE_OK) + return m; + } + else if ((s.st_mode & S_IFDIR) == S_IFDIR) + { + /* Add trailing / to the directory name */ + if ((p = malloc(strlen(n)+2)) == NULL) + return ZE_MEM; + if (strcmp(n, ".") == 0) { + *p = '\0'; /* avoid "./" prefix and do not create zip entry */ + } else { + strcpy(p, n); + a = p + strlen(p); + if (a[-1] != '/') + strcpy(a, "/"); + if (dirnames && (m = newname(p, 1, caseflag)) != ZE_OK) { + free((zvoid *)p); + return m; + } + } + /* recurse into directory */ + if (recurse && (d = opendir(n)) != NULL) + { + while ((e = readd(d)) != NULL) { + if (strcmp(e, ".") && strcmp(e, "..")) + { + if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL) + { + closedir(d); + free((zvoid *)p); + return ZE_MEM; + } + strcat(strcpy(a, p), e); + if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */ + { + if (m == ZE_MISS) + zipwarn("name not matched: ", a); + else + ziperr(m, a); + } + free((zvoid *)a); + } + } + closedir(d); + } + free((zvoid *)p); + } /* (s.st_mode & S_IFDIR) */ + else + zipwarn("ignoring special file: ", n); + return ZE_OK; +} + +char *ex2in(x, isdir, pdosflag) +char *x; /* external file name */ +int isdir; /* input: x is a directory */ +int *pdosflag; /* output: force MSDOS file attributes? */ +/* Convert the external file name to a zip file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *n; /* internal file name (malloc'ed) */ + char *t = NULL; /* shortened name */ + int dosflag; + + dosflag = dosify; /* default for non-DOS and non-OS/2 */ + + /* Find starting point in name before doing malloc */ + /* Strip "//host/share/" part of a UNC name */ + if (!strncmp(x,"//",2) && (x[2] != '\0' && x[2] != '/')) { + n = x + 2; + while (*n != '\0' && *n != '/') + n++; /* strip host name */ + if (*n != '\0') { + n++; + while (*n != '\0' && *n != '/') + n++; /* strip `share' name */ + } + if (*n != '\0') + t = n + 1; + } else + t = x; + while (*t == '/') + t++; /* strip leading '/' chars to get a relative path */ + while (*t == '.' && t[1] == '/') + t += 2; /* strip redundant leading "./" sections */ + + /* Make changes, if any, to the copied name (leave original intact) */ + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + + if (isdir == 42) return n; /* avoid warning on unused variable */ + + if (dosify) + msname(n); + + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + return n; +} + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + return x; +} + +/* + * XXX use ztimbuf in both POSIX and non POSIX cases ? + */ +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ +#ifdef _POSIX_VERSION + struct utimbuf u; /* argument for utime() const ?? */ +#else + time_t u[2]; /* argument for utime() */ +#endif + + /* Convert DOS time to time_t format in u */ +#ifdef _POSIX_VERSION + u.actime = u.modtime = dos2unixtime(d); + utime(f, &u); +#else + u[0] = u[1] = dos2unixtime(d); + utime(f, u); +#endif + +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + char *name; + int len = strlen(f); + + if (f == label) { + if (a != NULL) + *a = label_mode; + if (n != NULL) + *n = -2L; /* convention for a label name */ + if (t != NULL) + t->atime = t->mtime = t->ctime = label_utim; + return label_time; + } + if ((name = malloc(len + 1)) == NULL { + ZIPERR(ZE_MEM, "filetime"); + } + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + if (strcmp(f, "-") == 0) { + if (fstat(fileno(stdin), &s) != 0) { + free(name); + error("fstat(stdin)"); + } + } + else if (LSSTAT(name, &s) != 0) { + /* Accept about any file kind including directories + * (stored with trailing / with -r option) + */ + free(name); + return 0; + } + free(name); + + if (a != NULL) { +#ifndef OS390 + *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE); +#else +/* +** The following defines are copied from the unizip source and represent the +** legacy Unix mode flags. These fixed bit masks are no longer required +** by XOPEN standards - the S_IS### macros being the new recommended method. +** The approach here of setting the legacy flags by testing the macros should +** work under any _XOPEN_SOURCE environment (and will just rebuild the same bit +** mask), but is required if the legacy bit flags differ from legacy Unix. +*/ +#define UNX_IFDIR 0040000 /* Unix directory */ +#define UNX_IFREG 0100000 /* Unix regular file */ +#define UNX_IFSOCK 0140000 /* Unix socket (BSD, not SysV or Amiga) */ +#define UNX_IFLNK 0120000 /* Unix symbolic link (not SysV, Amiga) */ +#define UNX_IFBLK 0060000 /* Unix block special (not Amiga) */ +#define UNX_IFCHR 0020000 /* Unix character special (not Amiga) */ +#define UNX_IFIFO 0010000 /* Unix fifo (BCC, not MSC or Amiga) */ + { + mode_t legacy_modes; + + /* Initialize with permission bits - which are not implementation optional */ + legacy_modes = s.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX); + if (S_ISDIR(s.st_mode)) + legacy_modes |= UNX_IFDIR; + if (S_ISREG(s.st_mode)) + legacy_modes |= UNX_IFREG; + if (S_ISLNK(s.st_mode)) + legacy_modes |= UNX_IFLNK; + if (S_ISBLK(s.st_mode)) + legacy_modes |= UNX_IFBLK; + if (S_ISCHR(s.st_mode)) + legacy_modes |= UNX_IFCHR; + if (S_ISFIFO(s.st_mode)) + legacy_modes |= UNX_IFIFO; + if (S_ISSOCK(s.st_mode)) + legacy_modes |= UNX_IFSOCK; + *a = ((ulg)legacy_modes << 16) | !(s.st_mode & S_IWRITE); + } +#endif + if ((s.st_mode & S_IFMT) == S_IFDIR) { + *a |= MSDOS_DIR_ATTR; + } + } + if (n != NULL) + *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = t->mtime; /* best guess, (s.st_ctime: last status change!!) */ + } + return unix2dostime(&s.st_mtime); +} + +/* ---------------------------------------------------------------------- + +Return a malloc()'d buffer containing all of the attributes and their names +for the file specified in name. You have to free() this yourself. The length +of the buffer is also returned. + +If get_attr_dir() fails, the buffer will be NULL, total_size will be 0, +and an error will be returned: + + EOK - no errors occurred + EINVAL - attr_buff was pointing at a buffer + ENOMEM - insufficient memory for attribute buffer + +Other errors are possible (whatever is returned by the fs_attrib.h functions). + +PROBLEMS: + +- pointers are 32-bits; attributes are limited to ssize_t in size so it's + possible to overflow... in practice, this isn't too likely... your + machine will thrash like hell before that happens + +*/ + +#define INITIAL_BUFF_SIZE 65536 + +int get_attr_dir( const char *name, char **attr_buff, off_t *total_size ) +{ + int retval = EOK; + int fd; + DIR *fa_dir; + struct dirent *fa_ent; + off_t attrs_size = 0; + size_t entname_size; + char *ptr; + struct attr_info fa_info; + + *total_size = 0; + + /* ----------------------------------------------------------------- */ + /* Sanity-check. */ + if( *attr_buff != NULL ) { + return EINVAL; + } + + /* ----------------------------------------------------------------- */ + /* Can we open the file/directory? */ + /* */ + /* linkput is a zip global; it's set to 1 if we're storing symbolic */ + /* links as symbolic links (instead of storing the thing the link */ + /* points to)... if we're storing the symbolic link as a link, we'll */ + /* want the link's file attributes, otherwise we want the target's. */ + + fd = open( name, linkput ? O_RDONLY | O_NOTRAVERSE : O_RDONLY ); + if( fd < 0 ) { + return errno; + } + + /* ----------------------------------------------------------------- */ + /* Allocate an initial buffer; 64k should usually be enough. */ + *attr_buff = (char *)malloc( INITIAL_BUFF_SIZE ); + ptr = *attr_buff; + if( ptr == NULL ) { + close( fd ); + + return ENOMEM; + } + + /* ----------------------------------------------------------------- */ + /* Open the attributes directory for this file. */ + fa_dir = open_attrdir( fd ); + if( fa_dir == NULL ) { + close( fd ); + + free( ptr ); + *attr_buff = NULL; + + return retval; + } + + /* ----------------------------------------------------------------- */ + /* Read all the attributes; the buffer could grow > 64K if there are */ + /* many and/or they are large. */ + while( ( fa_ent = read_attrdir( fa_dir ) ) != NULL ) { + retval = stat_attr( fd, fa_ent->d_name, &fa_info ); + /* TODO: check retval != EOK */ + + entname_size = strlen( fa_ent->d_name ) + 1; + attrs_size += entname_size + sizeof( struct attr_info ) + fa_info.ai_size; + + if( attrs_size > INITIAL_BUFF_SIZE ) { + unsigned long offset = ptr - *attr_buff; + + *attr_buff = (char *)realloc( *attr_buff, attrs_size ); + if( *attr_buff == NULL ) { + retval = close_attrdir( fa_dir ); + /* TODO: check retval != EOK */ + close( fd ); + return ENOMEM; + } + + ptr = *attr_buff + offset; + } + + /* Now copy the data for this attribute into the buffer. */ + strcpy( ptr, fa_ent->d_name ); + ptr += entname_size; + + memcpy( ptr, &fa_info, sizeof( struct attr_info ) ); + ptr += sizeof( struct attr_info ); + + if( fa_info.ai_size > 0 ) { + ssize_t read_bytes = read_attr( fd, fa_ent->d_name, fa_info.ai_type, ptr, 0, fa_info.ai_size ); + if( read_bytes != fa_info.ai_size ) { + /* print a warning about mismatched sizes */ + char buff[80]; + sprintf( buff, "read %d, expected %d", read_bytes, (ssize_t)fa_info.ai_size ); + zipwarn( "attribute size mismatch: ", buff ); + } + + ptr += fa_info.ai_size; + } + } + + /* ----------------------------------------------------------------- */ + /* Close the attribute directory. */ + retval = close_attrdir( fa_dir ); + /* TODO: check retval != EOK */ + + /* ----------------------------------------------------------------- */ + /* If the buffer is too big, shrink it. */ + if( attrs_size < INITIAL_BUFF_SIZE ) { + *attr_buff = (char *)realloc( *attr_buff, attrs_size ); + if( *attr_buff == NULL ) { + close( fd ); + return ENOMEM; + } + } + + *total_size = attrs_size; + + close( fd ); + + return EOK; +} + +/* ---------------------------------------------------------------------- */ +/* Add a 'UT' extra field to the zlist data pointed to by z. */ + +#define EB_L_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(2)) +#define EB_C_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(1)) + +local int add_UT_ef( struct zlist far *z ) +{ + char *l_ef = NULL; + char *c_ef = NULL; + struct stat s; + +#ifdef IZ_CHECK_TZ + if (!zp_tz_is_valid) + return ZE_OK; /* skip silently if no valid TZ info */ +#endif + + /* We can't work if there's no entry to work on. */ + if( z == NULL ) { + return ZE_LOGIC; + } + + /* Check to make sure we've got enough room in the extra fields. */ + if( z->ext + EB_L_UT_SIZE > USHRT_MAX || + z->cext + EB_C_UT_SIZE > USHRT_MAX ) { + return ZE_MEM; + } + + /* stat() the file (or the symlink) to get the data; if we can't get */ + /* the data, there's no point in trying to fill out the fields. */ + if(LSSTAT( z->name, &s ) ) { + return ZE_OPEN; + } + + /* Allocate memory for the local and central extra fields. */ + if( z->extra && z->ext != 0 ) { + l_ef = (char *)realloc( z->extra, z->ext + EB_L_UT_SIZE ); + } else { + l_ef = (char *)malloc( EB_L_UT_SIZE ); + z->ext = 0; + } + if( l_ef == NULL ) { + return ZE_MEM; + } + z->extra = l_ef; + l_ef += z->ext; + + if( z->cextra && z->cext != 0 ) { + c_ef = (char *)realloc( z->cextra, z->cext + EB_C_UT_SIZE ); + } else { + c_ef = (char *)malloc( EB_C_UT_SIZE ); + z->cext = 0; + } + if( c_ef == NULL ) { + return ZE_MEM; + } + z->cextra = c_ef; + c_ef += z->cext; + + /* Now add the local version of the field. */ + *l_ef++ = 'U'; + *l_ef++ = 'T'; + *l_ef++ = (char)(EB_UT_LEN(2)); /* length of data in local EF */ + *l_ef++ = (char)0; + *l_ef++ = (char)(EB_UT_FL_MTIME | EB_UT_FL_ATIME); + *l_ef++ = (char)(s.st_mtime); + *l_ef++ = (char)(s.st_mtime >> 8); + *l_ef++ = (char)(s.st_mtime >> 16); + *l_ef++ = (char)(s.st_mtime >> 24); + *l_ef++ = (char)(s.st_atime); + *l_ef++ = (char)(s.st_atime >> 8); + *l_ef++ = (char)(s.st_atime >> 16); + *l_ef++ = (char)(s.st_atime >> 24); + + z->ext += EB_L_UT_SIZE; + + /* Now add the central version. */ + memcpy(c_ef, l_ef-EB_L_UT_SIZE, EB_C_UT_SIZE); + c_ef[EB_LEN] = (char)(EB_UT_LEN(1)); /* length of data in central EF */ + + z->cext += EB_C_UT_SIZE; + + return ZE_OK; +} + +/* ---------------------------------------------------------------------- */ +/* Add a 'Ux' extra field to the zlist data pointed to by z. */ + +#define EB_L_UX2_SIZE (EB_HEADSIZE + EB_UX2_MINLEN) +#define EB_C_UX2_SIZE (EB_HEADSIZE) + +local int add_Ux_ef( struct zlist far *z ) +{ + char *l_ef = NULL; + char *c_ef = NULL; + struct stat s; + + /* Check to make sure we've got enough room in the extra fields. */ + if( z->ext + EB_L_UX2_SIZE > USHRT_MAX || + z->cext + EB_C_UX2_SIZE > USHRT_MAX ) { + return ZE_MEM; + } + + /* stat() the file (or the symlink) to get the data; if we can't get */ + /* the data, there's no point in trying to fill out the fields. */ + if(LSSTAT( z->name, &s ) ) { + return ZE_OPEN; + } + + /* Allocate memory for the local and central extra fields. */ + if( z->extra && z->ext != 0 ) { + l_ef = (char *)realloc( z->extra, z->ext + EB_L_UX2_SIZE ); + } else { + l_ef = (char *)malloc( EB_L_UX2_SIZE ); + z->ext = 0; + } + if( l_ef == NULL ) { + return ZE_MEM; + } + z->extra = l_ef; + l_ef += z->ext; + + if( z->cextra && z->cext != 0 ) { + c_ef = (char *)realloc( z->cextra, z->cext + EB_C_UX2_SIZE ); + } else { + c_ef = (char *)malloc( EB_C_UX2_SIZE ); + z->cext = 0; + } + if( c_ef == NULL ) { + return ZE_MEM; + } + z->cextra = c_ef; + c_ef += z->cext; + + /* Now add the local version of the field. */ + *l_ef++ = 'U'; + *l_ef++ = 'x'; + *l_ef++ = (char)(EB_UX2_MINLEN); + *l_ef++ = (char)(EB_UX2_MINLEN >> 8); + *l_ef++ = (char)(s.st_uid); + *l_ef++ = (char)(s.st_uid >> 8); + *l_ef++ = (char)(s.st_gid); + *l_ef++ = (char)(s.st_gid >> 8); + + z->ext += EB_L_UX2_SIZE; + + /* Now add the central version of the field. */ + *c_ef++ = 'U'; + *c_ef++ = 'x'; + *c_ef++ = 0; + *c_ef++ = 0; + + z->cext += EB_C_UX2_SIZE; + + return ZE_OK; +} + +/* ---------------------------------------------------------------------- */ +/* Add a 'At' extra field to the zlist data pointed to by z. */ + +#define EB_L_AT_SIZE (EB_HEADSIZE + EB_L_AT_LEN) /* + attr size */ +#define EB_C_AT_SIZE (EB_HEADSIZE + EB_C_AT_LEN) + +#define MEMCOMPRESS_HEADER 6 /* ush compression type, ulg CRC */ +#define DEFLAT_WORSTCASE_ADD 5 /* byte blocktype, 2 * ush blocklength */ +#define MEMCOMPRESS_OVERHEAD (MEMCOMPRESS_HEADER + DEFLAT_WORSTCASE_ADD) + +local int add_At_ef( struct zlist far *z ) +{ + char *l_ef = NULL; + char *c_ef = NULL; + char *attrbuff = NULL; + off_t attrsize = 0; + char *compbuff = NULL; + ush compsize = 0; + uch flags = 0; + + /* Check to make sure we've got enough room in the extra fields. */ + if( z->ext + EB_L_AT_SIZE > USHRT_MAX || + z->cext + EB_C_AT_SIZE > USHRT_MAX ) { + return ZE_MEM; + } + + /* Attempt to load up a buffer full of the file's attributes. */ + { + if (get_attr_dir( z->name, &attrbuff, &attrsize) != EOK ) { + return ZE_OPEN; + } + if (attrsize == 0) { + return ZE_OK; + } + if (attrbuff == NULL) { + return ZE_LOGIC; + } + + /* Check for way too much data. */ + if (attrsize > (off_t)ULONG_MAX) { + zipwarn( "uncompressed attributes truncated", "" ); + attrsize = (off_t)(ULONG_MAX - MEMCOMPRESS_OVERHEAD); + } + } + + if (verbose) { + printf( "\t[in=%lu]", (unsigned long)attrsize ); + } + + /* Try compressing the data */ + compbuff = (char *)malloc( (size_t)attrsize + MEMCOMPRESS_OVERHEAD ); + if( compbuff == NULL ) { + return ZE_MEM; + } + compsize = memcompress( compbuff, + (size_t)attrsize + MEMCOMPRESS_OVERHEAD, + attrbuff, + (size_t)attrsize ); + if (verbose) { + printf( " [out=%u]", compsize ); + } + + /* Attempt to optimise very small attributes. */ + if (compsize > attrsize) { + free( compbuff ); + compsize = (ush)attrsize; + compbuff = attrbuff; + + flags = EB_AT_FL_NATURAL; + } + + /* Check to see if we really have enough room in the EF for the data. */ + if( ( z->ext + compsize + EB_L_AT_LEN ) > USHRT_MAX ) { + compsize = USHRT_MAX - EB_L_AT_LEN - z->ext; + } + + /* Allocate memory for the local and central extra fields. */ + if( z->extra && z->ext != 0 ) { + l_ef = (char *)realloc( z->extra, z->ext + EB_L_AT_SIZE + compsize ); + } else { + l_ef = (char *)malloc( EB_L_AT_SIZE + compsize ); + z->ext = 0; + } + if( l_ef == NULL ) { + return ZE_MEM; + } + z->extra = l_ef; + l_ef += z->ext; + + if( z->cextra && z->cext != 0 ) { + c_ef = (char *)realloc( z->cextra, z->cext + EB_C_AT_SIZE ); + } else { + c_ef = (char *)malloc( EB_C_AT_SIZE ); + z->cext = 0; + } + if( c_ef == NULL ) { + return ZE_MEM; + } + z->cextra = c_ef; + c_ef += z->cext; + + /* Now add the local version of the field. */ + *l_ef++ = 'A'; + *l_ef++ = 't'; + *l_ef++ = (char)(compsize + EB_L_AT_LEN); + *l_ef++ = (char)((compsize + EB_L_AT_LEN) >> 8); + *l_ef++ = (char)((unsigned long)attrsize); + *l_ef++ = (char)((unsigned long)attrsize >> 8); + *l_ef++ = (char)((unsigned long)attrsize >> 16); + *l_ef++ = (char)((unsigned long)attrsize >> 24); + *l_ef++ = flags; + memcpy( l_ef, compbuff, (size_t)compsize ); + + z->ext += EB_L_AT_SIZE + compsize; + + /* And the central version. */ + *c_ef++ = 'A'; + *c_ef++ = 't'; + *c_ef++ = (char)(EB_C_AT_LEN); + *c_ef++ = (char)(EB_C_AT_LEN >> 8); + *c_ef++ = (char)compsize; + *c_ef++ = (char)(compsize >> 8); + *c_ef++ = (char)(compsize >> 16); + *c_ef++ = (char)(compsize >> 24); + *c_ef++ = flags; + + z->cext += EB_C_AT_SIZE; + + return ZE_OK; +} + +/* Extra field info: + - 'UT' - UNIX time extra field + - 'Ux' - UNIX uid/gid extra field + - 'At' - AtheOS file attributes extra field + + This is done the same way ../unix/unix.c stores the 'UT'/'Ux' fields + (full data in local header, only modification time in central header), + with the 'At' field added to the end and the size of the 'At' field + in the central header. + + See the end of atheos/osdep.h for a simple explanation of the 'At' EF + layout. + */ +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; + /* store full data in local header but just modification time stamp info + in central header */ +{ + int retval; + + /* Check to make sure z is valid. */ + if( z == NULL ) { + return ZE_LOGIC; + } + + retval = add_UT_ef(z); + if( retval != ZE_OK ) { + return retval; + } + + retval = add_Ux_ef(z); + if( retval != ZE_OK ) { + return retval; + } + + return add_At_ef(z); /* last function; we can use return value directly */ +} + +/* ---------------------------------------------------------------------- */ +/* Set a file's MIME type. */ +void setfiletype(const char *file, const char *type) +{ + int fd; + off_t nLen; + ssize_t nError; + + fd = open( file, O_RDWR ); + + if (fd < 0) { + zipwarn( "can't open zipfile to write file type", "" ); + } + + else + { + nLen = strlen( type ); + /* FIXME: write_attr() should return count of writed bytes */ + nError = write_attr( fd, "os::MimeType", O_TRUNC, ATTR_TYPE_STRING, type, 0, nLen ); + if (nError < 0) { + zipwarn( "couldn't write complete file type", "" ); + } + close( fd ); + } +} + +#endif /* !UTIL */ + +/******************************/ +/* Function version_local() */ +/******************************/ + +void version_local() +{ + static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n"; + + printf(CompiledWith, + +#ifdef __GNUC__ + "gcc ", __VERSION__, +#else + "(unknown compiler)", "", +#endif + + "Syllable", + +#if defined(i486) || defined(__i486) || defined(__i486__) || defined(i386) || defined(__i386) || defined(__i386__) + " (x86)", +#else + " (unknown platform)", +#endif + +#ifdef __DATE__ + " on ", __DATE__ +#else + "", "" +#endif + ); + +} /* end function version_local() */ diff --git a/atheos/osdep.h b/atheos/osdep.h new file mode 100644 index 0000000..0869f94 --- /dev/null +++ b/atheos/osdep.h @@ -0,0 +1,64 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ + +#ifndef _OSDEP_H_ +#define _OSDEP_H_ + +#include +#include +#include + +#define USE_EF_UT_TIME /* Enable use of "UT" extra field time info */ + +#define EB_L_AT_LEN 5 /* min size is an unsigned long and flag */ +#define EB_C_AT_LEN 5 /* Length of data in local EF and flag. */ + +#define EB_AT_FL_NATURAL 0x01 /* data is 'natural' (not compressed) */ +#define EB_AT_FL_BADBITS 0xfe /* bits currently undefined */ + +#ifndef ZP_NEED_MEMCOMPR + define ZP_NEED_MEMCOMPR +#endif + +#define deletedir(d) rmdir(d); + +/* Set a file's MIME type. */ +void setfiletype( const char *file, const char *type ); + +/* +'At' extra-field layout: + +'At' - signature +ef_size - size of data in this EF (little-endian unsigned short) +full_size - uncompressed data size (little-endian unsigned long) +flag - flags (byte) + flags & EB_AT_FL_NATURAL = the data is not compressed + flags & EB_AT_FL_BADBITS = the data is corrupted or we + can't handle it properly +data - compressed or uncompressed file attribute data + +If flag & EB_AT_FL_NATURAL, the data is not compressed; this optimisation is +necessary to prevent wasted space for files with small attributes. In this +case, there should be ( ef_size - EB_L_AT_LEN ) bytes of data, and full_size +should equal ( ef_size - EB_L_AT_LEN ). + +If the data is compressed, there will be ( ef_size - EB_L_AT_LEN ) bytes of +compressed data, and full_size bytes of uncompressed data. + +If a file has absolutely no attributes, there will not be a 'At' extra field. + +The uncompressed data is arranged like this: + +attr_name\0 - C string +struct attr_info (little-endian) +attr_data (length in attr_info.ai_size) +*/ + +#endif + diff --git a/atheos/zipup.h b/atheos/zipup.h new file mode 100644 index 0000000..d3d39a3 --- /dev/null +++ b/atheos/zipup.h @@ -0,0 +1,24 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#ifndef _ZIPUP_H_ +#define _ZIPUP_H_ + +#ifndef O_RDONLY +# include +#endif +#define fhow O_RDONLY +#define fbad (-1) +typedef int ftype; +#define zopen(n,p) open(n,p) +#define zread(f,b,n) read(f,b,n) +#define zclose(f) close(f) +#define zerr(f) (k == (extent)(-1L)) +#define zstdin 0 + +#endif /* _ZIPUP_H_ */ diff --git a/beos/Contents b/beos/Contents new file mode 100644 index 0000000..939a535 --- /dev/null +++ b/beos/Contents @@ -0,0 +1,14 @@ +Contents of the "beos" sub-directory for Zip 2.2 and later: + + Contents this file + README Notes from the author of the BeOS port + Makefile makefile for building (sorry, no project files) + beos.c BeOS-specific routines (similar to the UNIX ones) + osdep.h BeOS-specific includes and whatnot + zipup.h Definitions for zip routines + +This port supports both Metrowerks CodeWarrior and GNU C as the compiler, +and PowerPC and x86 architectures. + +- Chris Herborth (chrish@pobox.com) + June 24, 1998 diff --git a/beos/Makefile b/beos/Makefile new file mode 100644 index 0000000..1b9e613 --- /dev/null +++ b/beos/Makefile @@ -0,0 +1,182 @@ +###################################################################### +# +# Makefile for Info-ZIP's zip, zipcloak, zipnote, and zipsplit on BeOS +# +# Copyright © 1999 Info-ZIP +# Chris Herborth (chrish@pobox.com) +# +# This is the new New and Improved Makefile for BeOS; it automatically +# detects your platform and uses the appropriate compiler and compiler +# flags. + +###################################################################### +# Things that don't change: + +# Punish people who don't have SMP hardware. +MAKE = make -j 4 -f beos/Makefile +SHELL = /bin/sh + +LN = ln -s + +BIND = $(CC) +AS = $(CC) -c +CPP = $(CC) -E + +INSTALL = install + +# Target directories +prefix = /boot/home/config +BINDIR = $(prefix)/bin +manext = 1 +MANDIR = $(prefix)/man/man$(manext) +ZIPMANUAL = MANUAL + +VERSION = Version 2.3 of __DATE__ + +###################################################################### +# Things that change: + +# PowerPC system +ifeq "$(BE_HOST_CPU)" "ppc" + +CC:=mwcc + +ifeq "$(shell uname -r)" "4.0" + +CFLAGS:=-O7 -opt schedule604 -rostr -w9 \ + -I. -DHAVE_DIRENT_H -DPASSWD_FROM_STDIN +LFLAGS1:=-warn + +else + +CFLAGS:=-O7 -proc 604e -w9 -I. -DHAVE_DIRENT_H -DPASSWD_FROM_STDIN +LFLAGS1:=-nodup + +endif + +LFLAGS2:=-L/boot/develop/lib/ppc -lbe -lroot +OBJA = +TARGET=$(ZIPS) + +# x86 system +else + +CC:=gcc + +# Removed -Wconversion and -Wshadow because of the unnecessary warnings +# they generate. - Sept. 28, 1999 +CFLAGS:=-O3 -mpentiumpro \ + -Wall -Wno-multichar -Wno-ctor-dtor-privacy \ + -Wbad-function-cast -Woverloaded-virtual \ + -I. -I/boot/develop/headers/be/support \ + -I/boot/develop/headers/be/storage \ + -DHAVE_DIRENT_H -DPASSWD_FROM_STDIN # -DASMV +LFLAGS1:= +LFLAGS2:=-L/boot/develop/lib/x86 -lbe -lroot +OBJA = #match.o +TARGET=$(ZIPS) + +endif + +###################################################################### +# Helpful targets +all: + $(MAKE) CC=$(CC) CFLAGS="$(CFLAGS)" \ + LFLAGS1="$(LFLAGS1)" LFLAGS2="$(LFLAGS2)" \ + $(TARGET) + +###################################################################### +# Object file lists and other build goodies + +# Object file lists +OBJZ = zip.o zipfile.o zipup.o fileio.o util.o globals.o crypt.o ttyio.o \ + beos.o crc32.o +OBJI = deflate.o trees.o +# OBJA moved into ifeq block above; we'll use assembly for x86 +OBJU = zipfile_.o fileio_.o util_.o globals.o beos_.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o $(OBJU) crc32_.o crypt_.o ttyio.o +OBJS = zipsplit.o $(OBJU) + +# Headers +ZIP_H = zip.h ziperr.h tailor.h beos/osdep.h + +# What to build? +ZIPS = zip zipnote zipsplit zipcloak + +# suffix rules +.SUFFIXES: +.SUFFIXES: _.o .o .c .doc .1 +.c_.o: + rm -f $*_.c; $(LN) $< $*_.c + $(CC) -c $(CFLAGS) -DUTIL $*_.c + rm -f $*_.c + +.c.o: + $(CC) -c $(CFLAGS) $< + +.1.doc: + groff -man -Tascii $< > $@ + +# rules for zip, zipnote, zipcloak, zipsplit, and the Zip MANUAL. +$(OBJZ): $(ZIP_H) +$(OBJI): $(ZIP_H) +$(OBJN): $(ZIP_H) +$(OBJS): $(ZIP_H) +$(OBJC): $(ZIP_H) +zip.o crc32.o crypt.o fileio.o zipfile.o zipup.o: crc32.h +zipcloak.o crc32_.o crypt_.o fileio_.o zipfile_.o: crc32.h +zip.o zipup.o crypt.o ttyio.o zipcloak.o crypt_.o: crypt.h +zip.o zipup.o zipnote.o zipcloak.o zipsplit.o: revision.h +zip.o crypt.o ttyio.o zipcloak.o crypt_.o: ttyio.h +zipup.o: beos/zipup.h + +match.o: match.S + $(CPP) match.S > _match.s + $(AS) _match.s + mv -f _match.o match.o + rm -f _match.s + +beos.o: beos/beos.c + $(CC) -c $(CFLAGS) beos/beos.c + +beos_.o: beos/beos.c + rm -f $*_.c; $(LN) beos/beos.c $*_.c + $(CC) -c $(CFLAGS) -DUTIL $*_.c + rm -f $*_.c + +zips: $(ZIPS) +zipsman: $(ZIPS) $(ZIPMANUAL) + +zip: $(OBJZ) $(OBJI) $(OBJA) + $(BIND) -o zip $(LFLAGS1) $(OBJZ) $(OBJI) $(OBJA) $(LFLAGS2) +zipnote: $(OBJN) + $(BIND) -o zipnote $(LFLAGS1) $(OBJN) $(LFLAGS2) +zipcloak: $(OBJC) + $(BIND) -o zipcloak $(LFLAGS1) $(OBJC) $(LFLAGS2) +zipsplit: $(OBJS) + $(BIND) -o zipsplit $(LFLAGS1) $(OBJS) $(LFLAGS2) + +$(ZIPMANUAL): man/zip.1 + groff -man -Tascii man/zip.1 > $(ZIPMANUAL) + +# install +install: $(ZIPS) + $(INSTALL) -m755 $(ZIPS) $(BINDIR) + mkdir -p $(MANDIR) + $(INSTALL) -m644 man/zip.1 $(MANDIR)/zip.$(manext) + +uninstall: + -cd $(BINDIR); rm -f $(ZIPS) + -cd $(MANDIR); rm -f zip.$(manext) + +dist: $(ZIPMANUAL) + zip -u9T zip`sed -e '/VERSION/!d' -e 's/.*"\(.*\)".*/\1/' \ + -e s/[.]//g -e q revision.h` \ + `awk '/^Makefile/,/vms_zip.rnh/ {print $$1}' < contents` + +# clean up after making stuff and installing it +clean: + rm -f *.o $(ZIPS) flags + +# end of Makefile diff --git a/beos/README b/beos/README new file mode 100644 index 0000000..b985ea0 --- /dev/null +++ b/beos/README @@ -0,0 +1,31 @@ +Info-ZIP's zip for BeOS + +KNOWN BUGS + +- None! (as of zip 2.21) + +- building on x86 BeOS generates a hell of a lot of bugs; I'm not going to + worry about them until Be fixes their headers though... + +FEATURES + +- stores BeOS file attributes, compressing them if possible (as of 2.21, + this works properly for symbolic links, too; as of 2.3, this works + properly for symbolic links whether you're storing them as links or not) + +- zip files are created with the correct file type (application/zip) + +- supports both Metrowerks CodeWarrior (PowerPC platform) and GNU C + (x86 platform), automatically picking the default compiler for each + architecture + +Please report any bugs to the Zip-Bugs mailing list; our email address is +zip-bugs@lists.wku.edu. If it's something BeOS-specific, you could email +me directly. + +Visit the Info-ZIP web site (http://www.cdrom.com/pub/infozip/) for all the +latest zip and unzip information, FAQs, source code and ready-to-run +executables. + +- Chris Herborth (chrish@pobox.com) + April 2/1999 diff --git a/beos/beos.c b/beos/beos.c new file mode 100644 index 0000000..d8d16df --- /dev/null +++ b/beos/beos.c @@ -0,0 +1,945 @@ +/* + Copyright (c) 1990-2002 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + + This BeOS-specific file is based on unix.c in the unix directory; changes + by Chris Herborth (chrish@pobox.com). + +*/ + +#include "zip.h" + +#ifndef UTIL /* the companion #endif is a bit of ways down ... */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + + +#define PAD 0 +#define PATH_END '/' + +/* Library functions not in (most) header files */ + +#ifdef _POSIX_VERSION +# include +#else + int utime OF((char *, time_t *)); +#endif + +extern char *label; +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +/* Local functions */ +local char *readd OF((DIR *)); +local int get_attr_dir( const char *, char **, off_t * ); +local int add_UT_ef( struct zlist far * ); +local int add_Ux_ef( struct zlist far * ); +local int add_Be_ef( struct zlist far * ); + + +#ifdef NO_DIR /* for AT&T 3B1 */ +#include +#ifndef dirent +# define dirent direct +#endif +typedef FILE DIR; +/* +** Apparently originally by Rich Salz. +** Cleaned up and modified by James W. Birdsall. +*/ + +#define opendir(path) fopen(path, "r") + +struct dirent *readdir(dirp) +DIR *dirp; +{ + static struct dirent entry; + + if (dirp == NULL) + return NULL; + for (;;) + if (fread (&entry, sizeof (struct dirent), 1, dirp) == 0) + return NULL; + else if (entry.d_ino) + return (&entry); +} /* end of readdir() */ + +#define closedir(dirp) fclose(dirp) +#endif /* NO_DIR */ + + +local char *readd(d) +DIR *d; /* directory stream to read from */ +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e; + + e = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; +} + +int procname(n, caseflag) +char *n; /* name to process */ +int caseflag; /* true to force case-sensitive match */ +/* Process a name or sh expression to operate on (or exclude). Return + an error code in the ZE_ class. */ +{ + char *a; /* path and name for recursion */ + DIR *d; /* directory stream from opendir() */ + char *e; /* pointer to name from readd() */ + int m; /* matched flag */ + char *p; /* path for recursion */ + struct stat s; /* result of stat() */ + struct zlist far *z; /* steps through zfiles list */ + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0, caseflag); + else if (LSSTAT(n, &s)) + { + /* Not a file or directory--search for shell expression in zip file */ + p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */ + m = 1; + for (z = zfiles; z != NULL; z = z->nxt) { + if (MATCH(p, z->iname, caseflag)) + { + z->mark = pcount ? filter(z->zname, caseflag) : 1; + if (verbose) + fprintf(mesg, "zip diagnostic: %scluding %s\n", + z->mark ? "in" : "ex", z->name); + m = 0; + } + } + free((zvoid *)p); + return m ? ZE_MISS : ZE_OK; + } + + /* Live name--use if file, recurse if directory */ + if ((s.st_mode & S_IFDIR) == 0) + { + /* add or remove name of file */ + if ((m = newname(n, 0, caseflag)) != ZE_OK) + return m; + } else { + /* Add trailing / to the directory name */ + if ((p = malloc(strlen(n)+2)) == NULL) + return ZE_MEM; + if (strcmp(n, ".") == 0) { + *p = '\0'; /* avoid "./" prefix and do not create zip entry */ + } else { + strcpy(p, n); + a = p + strlen(p); + if (a[-1] != '/') + strcpy(a, "/"); + if (dirnames && (m = newname(p, 1, caseflag)) != ZE_OK) { + free((zvoid *)p); + return m; + } + } + /* recurse into directory */ + if (recurse && (d = opendir(n)) != NULL) + { + while ((e = readd(d)) != NULL) { + if (strcmp(e, ".") && strcmp(e, "..")) + { + if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL) + { + closedir(d); + free((zvoid *)p); + return ZE_MEM; + } + strcat(strcpy(a, p), e); + if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */ + { + if (m == ZE_MISS) + zipwarn("name not matched: ", a); + else + ziperr(m, a); + } + free((zvoid *)a); + } + } + closedir(d); + } + free((zvoid *)p); + } /* (s.st_mode & S_IFDIR) == 0) */ + return ZE_OK; +} + +char *ex2in(x, isdir, pdosflag) +char *x; /* external file name */ +int isdir; /* input: x is a directory */ +int *pdosflag; /* output: force MSDOS file attributes? */ +/* Convert the external file name to a zip file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *n; /* internal file name (malloc'ed) */ + char *t; /* shortened name */ + int dosflag; + + dosflag = dosify; /* default for non-DOS and non-OS/2 */ + + /* Find starting point in name before doing malloc */ + for (t = x; *t == '/'; t++) + ; /* strip leading '/' chars to get a relative path */ + while (*t == '.' && t[1] == '/') + t += 2; /* strip redundant leading "./" sections */ + + /* Make changes, if any, to the copied name (leave original intact) */ + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + + if (isdir == 42) return n; /* avoid warning on unused variable */ + + if (dosify) + msname(n); + + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + return n; +} + + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + return x; +} + +/* + * XXX use ztimbuf in both POSIX and non POSIX cases ? + */ +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ +#ifdef _POSIX_VERSION + struct utimbuf u; /* argument for utime() const ?? */ +#else + time_t u[2]; /* argument for utime() */ +#endif + + /* Convert DOS time to time_t format in u */ +#ifdef _POSIX_VERSION + u.actime = u.modtime = dos2unixtime(d); + utime(f, &u); +#else + u[0] = u[1] = dos2unixtime(d); + utime(f, u); +#endif + +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + /* convert FNAMX to malloc - 11/8/04 EG */ + char *name; + int len = strlen(f); + + if (f == label) { + if (a != NULL) + *a = label_mode; + if (n != NULL) + *n = -2L; /* convention for a label name */ + if (t != NULL) + t->atime = t->mtime = t->ctime = label_utim; + return label_time; + } + if ((name = malloc(len + 1)) == NULL) { + ZIPERR(ZE_MEM, "filetime"); + } + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + if (strcmp(f, "-") == 0) { + if (fstat(fileno(stdin), &s) != 0) { + free(name); + error("fstat(stdin)"); + } + } else if (LSSTAT(name, &s) != 0) { + /* Accept about any file kind including directories + * (stored with trailing / with -r option) + */ + free(name); + return 0; + } + free(name); + + if (a != NULL) { + *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE); + if ((s.st_mode & S_IFMT) == S_IFDIR) { + *a |= MSDOS_DIR_ATTR; + } + } + if (n != NULL) + *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_mtime; /* best guess (s.st_ctime: last status change!) */ + } + + return unix2dostime(&s.st_mtime); +} + +/* ---------------------------------------------------------------------- + +Return a malloc()'d buffer containing all of the attributes and their names +for the file specified in name. You have to free() this yourself. The length +of the buffer is also returned. + +If get_attr_dir() fails, the buffer will be NULL, total_size will be 0, +and an error will be returned: + + EOK - no errors occurred + EINVAL - attr_buff was pointing at a buffer + ENOMEM - insufficient memory for attribute buffer + +Other errors are possible (whatever is returned by the fs_attr.h functions). + +PROBLEMS: + +- pointers are 32-bits; attributes are limited to off_t in size so it's + possible to overflow... in practice, this isn't too likely... your + machine will thrash like hell before that happens + +*/ + +#define INITIAL_BUFF_SIZE 65536 + +int get_attr_dir( const char *name, char **attr_buff, off_t *total_size ) +{ + int retval = EOK; + int fd; + DIR *fa_dir; + struct dirent *fa_ent; + off_t attrs_size; + off_t this_size; + char *ptr; + struct attr_info fa_info; + struct attr_info big_fa_info; + + retval = EOK; + attrs_size = 0; /* gcc still says this is used uninitialized... */ + *total_size = 0; + + /* ----------------------------------------------------------------- */ + /* Sanity-check. */ + if( *attr_buff != NULL ) { + return EINVAL; + } + + /* ----------------------------------------------------------------- */ + /* Can we open the file/directory? */ + /* */ + /* linkput is a zip global; it's set to 1 if we're storing symbolic */ + /* links as symbolic links (instead of storing the thing the link */ + /* points to)... if we're storing the symbolic link as a link, we'll */ + /* want the link's file attributes, otherwise we want the target's. */ + if( linkput ) { + fd = open( name, O_RDONLY | O_NOTRAVERSE ); + } else { + fd = open( name, O_RDONLY ); + } + if( fd < 0 ) { + return errno; + } + + /* ----------------------------------------------------------------- */ + /* Allocate an initial buffer; 64k should usually be enough. */ + *attr_buff = (char *)malloc( INITIAL_BUFF_SIZE ); + ptr = *attr_buff; + if( ptr == NULL ) { + close( fd ); + + return ENOMEM; + } + + /* ----------------------------------------------------------------- */ + /* Open the attributes directory for this file. */ + fa_dir = fs_fopen_attr_dir( fd ); + if( fa_dir == NULL ) { + close( fd ); + + free( ptr ); + *attr_buff = NULL; + + return retval; + } + + /* ----------------------------------------------------------------- */ + /* Read all the attributes; the buffer could grow > 64K if there are */ + /* many and/or they are large. */ + fa_ent = fs_read_attr_dir( fa_dir ); + while( fa_ent != NULL ) { + retval = fs_stat_attr( fd, fa_ent->d_name, &fa_info ); + /* TODO: check retval != EOK */ + + this_size = strlen( fa_ent->d_name ) + 1; + this_size += sizeof( struct attr_info ); + this_size += fa_info.size; + + attrs_size += this_size; + + if( attrs_size > INITIAL_BUFF_SIZE ) { + unsigned long offset = ptr - *attr_buff; + + *attr_buff = (char *)realloc( *attr_buff, attrs_size ); + if( *attr_buff == NULL ) { + retval = fs_close_attr_dir( fa_dir ); + /* TODO: check retval != EOK */ + close( fd ); + + return ENOMEM; + } + + ptr = *attr_buff + offset; + } + + /* Now copy the data for this attribute into the buffer. */ + strcpy( ptr, fa_ent->d_name ); + ptr += strlen( fa_ent->d_name ); + *ptr++ = '\0'; + + /* We need to put a big-endian version of the fa_info data into */ + /* the archive. */ + big_fa_info.type = B_HOST_TO_BENDIAN_INT32( fa_info.type ); + big_fa_info.size = B_HOST_TO_BENDIAN_INT64( fa_info.size ); + memcpy( ptr, &big_fa_info, sizeof( struct attr_info ) ); + ptr += sizeof( struct attr_info ); + + if( fa_info.size > 0 ) { + ssize_t read_bytes; + + read_bytes = fs_read_attr( fd, fa_ent->d_name, fa_info.type, 0, + ptr, fa_info.size ); + if( read_bytes != fa_info.size ) { + /* print a warning about mismatched sizes */ + char buff[80]; + + sprintf( buff, "read %ld, expected %ld", + (ssize_t)read_bytes, (ssize_t)fa_info.size ); + zipwarn( "attribute size mismatch: ", buff ); + } + + /* Wave my magic wand... this swaps all the Be types to big- */ + /* endian automagically. */ + (void)swap_data( fa_info.type, ptr, fa_info.size, + B_SWAP_HOST_TO_BENDIAN ); + + ptr += fa_info.size; + } + + fa_ent = fs_read_attr_dir( fa_dir ); + } + + /* ----------------------------------------------------------------- */ + /* Close the attribute directory. */ + retval = fs_close_attr_dir( fa_dir ); + /* TODO: check retval != EOK */ + + /* ----------------------------------------------------------------- */ + /* If the buffer is too big, shrink it. */ + if( attrs_size < INITIAL_BUFF_SIZE ) { + *attr_buff = (char *)realloc( *attr_buff, attrs_size ); + if( *attr_buff == NULL ) { + /* This really shouldn't happen... */ + close( fd ); + + return ENOMEM; + } + } + + *total_size = attrs_size; + + close( fd ); + + return EOK; +} + +/* ---------------------------------------------------------------------- */ +/* Add a 'UT' extra field to the zlist data pointed to by z. */ + +#define EB_L_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(2)) +#define EB_C_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(1)) + +local int add_UT_ef( struct zlist far *z ) +{ + char *l_ef = NULL; + char *c_ef = NULL; + struct stat s; + +#ifdef IZ_CHECK_TZ + if (!zp_tz_is_valid) + return ZE_OK; /* skip silently if no valid TZ info */ +#endif + + /* We can't work if there's no entry to work on. */ + if( z == NULL ) { + return ZE_LOGIC; + } + + /* Check to make sure we've got enough room in the extra fields. */ + if( z->ext + EB_L_UT_SIZE > USHRT_MAX || + z->cext + EB_C_UT_SIZE > USHRT_MAX ) { + return ZE_MEM; + } + + /* stat() the file (or the symlink) to get the data; if we can't get */ + /* the data, there's no point in trying to fill out the fields. */ + if(LSSTAT( z->name, &s ) ) { + return ZE_OPEN; + } + + /* Allocate memory for the local and central extra fields. */ + if( z->extra && z->ext != 0 ) { + l_ef = (char *)realloc( z->extra, z->ext + EB_L_UT_SIZE ); + } else { + l_ef = (char *)malloc( EB_L_UT_SIZE ); + z->ext = 0; + } + if( l_ef == NULL ) { + return ZE_MEM; + } + z->extra = l_ef; + l_ef += z->ext; + + if( z->cextra && z->cext != 0 ) { + c_ef = (char *)realloc( z->cextra, z->cext + EB_C_UT_SIZE ); + } else { + c_ef = (char *)malloc( EB_C_UT_SIZE ); + z->cext = 0; + } + if( c_ef == NULL ) { + return ZE_MEM; + } + z->cextra = c_ef; + c_ef += z->cext; + + /* Now add the local version of the field. */ + *l_ef++ = 'U'; + *l_ef++ = 'T'; + *l_ef++ = (char)(EB_UT_LEN(2)); /* length of data in local EF */ + *l_ef++ = (char)0; + *l_ef++ = (char)(EB_UT_FL_MTIME | EB_UT_FL_ATIME); + *l_ef++ = (char)(s.st_mtime); + *l_ef++ = (char)(s.st_mtime >> 8); + *l_ef++ = (char)(s.st_mtime >> 16); + *l_ef++ = (char)(s.st_mtime >> 24); + *l_ef++ = (char)(s.st_atime); + *l_ef++ = (char)(s.st_atime >> 8); + *l_ef++ = (char)(s.st_atime >> 16); + *l_ef++ = (char)(s.st_atime >> 24); + + z->ext += EB_L_UT_SIZE; + + /* Now add the central version. */ + memcpy(c_ef, l_ef-EB_L_UT_SIZE, EB_C_UT_SIZE); + c_ef[EB_LEN] = (char)(EB_UT_LEN(1)); /* length of data in central EF */ + + z->cext += EB_C_UT_SIZE; + + return ZE_OK; +} + +/* ---------------------------------------------------------------------- */ +/* Add a 'Ux' extra field to the zlist data pointed to by z. */ + +#define EB_L_UX2_SIZE (EB_HEADSIZE + EB_UX2_MINLEN) +#define EB_C_UX2_SIZE (EB_HEADSIZE) + +local int add_Ux_ef( struct zlist far *z ) +{ + char *l_ef = NULL; + char *c_ef = NULL; + struct stat s; + + /* Check to make sure we've got enough room in the extra fields. */ + if( z->ext + EB_L_UX2_SIZE > USHRT_MAX || + z->cext + EB_C_UX2_SIZE > USHRT_MAX ) { + return ZE_MEM; + } + + /* stat() the file (or the symlink) to get the data; if we can't get */ + /* the data, there's no point in trying to fill out the fields. */ + if(LSSTAT( z->name, &s ) ) { + return ZE_OPEN; + } + + /* Allocate memory for the local and central extra fields. */ + if( z->extra && z->ext != 0 ) { + l_ef = (char *)realloc( z->extra, z->ext + EB_L_UX2_SIZE ); + } else { + l_ef = (char *)malloc( EB_L_UX2_SIZE ); + z->ext = 0; + } + if( l_ef == NULL ) { + return ZE_MEM; + } + z->extra = l_ef; + l_ef += z->ext; + + if( z->cextra && z->cext != 0 ) { + c_ef = (char *)realloc( z->cextra, z->cext + EB_C_UX2_SIZE ); + } else { + c_ef = (char *)malloc( EB_C_UX2_SIZE ); + z->cext = 0; + } + if( c_ef == NULL ) { + return ZE_MEM; + } + z->cextra = c_ef; + c_ef += z->cext; + + /* Now add the local version of the field. */ + *l_ef++ = 'U'; + *l_ef++ = 'x'; + *l_ef++ = (char)(EB_UX2_MINLEN); + *l_ef++ = (char)(EB_UX2_MINLEN >> 8); + *l_ef++ = (char)(s.st_uid); + *l_ef++ = (char)(s.st_uid >> 8); + *l_ef++ = (char)(s.st_gid); + *l_ef++ = (char)(s.st_gid >> 8); + + z->ext += EB_L_UX2_SIZE; + + /* Now add the central version of the field. */ + *c_ef++ = 'U'; + *c_ef++ = 'x'; + *c_ef++ = 0; + *c_ef++ = 0; + + z->cext += EB_C_UX2_SIZE; + + return ZE_OK; +} + +/* ---------------------------------------------------------------------- */ +/* Add a 'Be' extra field to the zlist data pointed to by z. */ + +#define EB_L_BE_SIZE (EB_HEADSIZE + EB_L_BE_LEN) /* + attr size */ +#define EB_C_BE_SIZE (EB_HEADSIZE + EB_C_BE_LEN) + +/* maximum memcompress overhead is the sum of the compression header length */ +/* (6 = ush compression type, ulg CRC) and the worstcase deflate overhead */ +/* when uncompressible data are kept in 2 "stored" blocks (5 per block = */ +/* byte blocktype + 2 * ush blocklength) */ +#define MEMCOMPRESS_OVERHEAD (EB_MEMCMPR_HSIZ + EB_DEFLAT_EXTRA) + +local int add_Be_ef( struct zlist far *z ) +{ + char *l_ef = NULL; + char *c_ef = NULL; + char *attrbuff = NULL; + off_t attrsize = 0; + char *compbuff = NULL; + ush compsize = 0; + uch flags = 0; + + /* Check to make sure we've got enough room in the extra fields. */ + if( z->ext + EB_L_BE_SIZE > USHRT_MAX || + z->cext + EB_C_BE_SIZE > USHRT_MAX ) { + return ZE_MEM; + } + + /* Attempt to load up a buffer full of the file's attributes. */ + { + int retval; + + retval = get_attr_dir( z->name, &attrbuff, &attrsize ); + if( retval != EOK ) { + return ZE_OPEN; + } + if( attrsize == 0 ) { + return ZE_OK; + } + if( attrbuff == NULL ) { + return ZE_LOGIC; + } + + /* Check for way too much data. */ + if( attrsize > (off_t)ULONG_MAX ) { + zipwarn( "uncompressed attributes truncated", "" ); + attrsize = (off_t)(ULONG_MAX - MEMCOMPRESS_OVERHEAD); + } + } + + if( verbose ) { + printf( "\t[in=%lu]", (unsigned long)attrsize ); + } + + /* Try compressing the data */ + compbuff = (char *)malloc( (size_t)attrsize + MEMCOMPRESS_OVERHEAD ); + if( compbuff == NULL ) { + return ZE_MEM; + } + compsize = memcompress( compbuff, + (size_t)attrsize + MEMCOMPRESS_OVERHEAD, + attrbuff, + (size_t)attrsize ); + if( verbose ) { + printf( " [out=%u]", compsize ); + } + + /* Attempt to optimise very small attributes. */ + if( compsize > attrsize ) { + free( compbuff ); + compsize = (ush)attrsize; + compbuff = attrbuff; + + flags = EB_BE_FL_NATURAL; + } + + /* Check to see if we really have enough room in the EF for the data. */ + if( ( z->ext + compsize + EB_L_BE_LEN ) > USHRT_MAX ) { + compsize = USHRT_MAX - EB_L_BE_LEN - z->ext; + } + + /* Allocate memory for the local and central extra fields. */ + if( z->extra && z->ext != 0 ) { + l_ef = (char *)realloc( z->extra, z->ext + EB_L_BE_SIZE + compsize ); + } else { + l_ef = (char *)malloc( EB_L_BE_SIZE + compsize ); + z->ext = 0; + } + if( l_ef == NULL ) { + return ZE_MEM; + } + z->extra = l_ef; + l_ef += z->ext; + + if( z->cextra && z->cext != 0 ) { + c_ef = (char *)realloc( z->cextra, z->cext + EB_C_BE_SIZE ); + } else { + c_ef = (char *)malloc( EB_C_BE_SIZE ); + z->cext = 0; + } + if( c_ef == NULL ) { + return ZE_MEM; + } + z->cextra = c_ef; + c_ef += z->cext; + + /* Now add the local version of the field. */ + *l_ef++ = 'B'; + *l_ef++ = 'e'; + *l_ef++ = (char)(compsize + EB_L_BE_LEN); + *l_ef++ = (char)((compsize + EB_L_BE_LEN) >> 8); + *l_ef++ = (char)((unsigned long)attrsize); + *l_ef++ = (char)((unsigned long)attrsize >> 8); + *l_ef++ = (char)((unsigned long)attrsize >> 16); + *l_ef++ = (char)((unsigned long)attrsize >> 24); + *l_ef++ = flags; + memcpy( l_ef, compbuff, (size_t)compsize ); + + z->ext += EB_L_BE_SIZE + compsize; + + /* And the central version. */ + *c_ef++ = 'B'; + *c_ef++ = 'e'; + *c_ef++ = (char)(EB_C_BE_LEN); + *c_ef++ = (char)(EB_C_BE_LEN >> 8); + *c_ef++ = (char)compsize; + *c_ef++ = (char)(compsize >> 8); + *c_ef++ = (char)(compsize >> 16); + *c_ef++ = (char)(compsize >> 24); + *c_ef++ = flags; + + z->cext += EB_C_BE_SIZE; + + return ZE_OK; +} + +/* Extra field info: + - 'UT' - UNIX time extra field + - 'Ux' - UNIX uid/gid extra field + - 'Be' - BeOS file attributes extra field + + This is done the same way ../unix/unix.c stores the 'UT'/'Ux' fields + (full data in local header, only modification time in central header), + with the 'Be' field added to the end and the size of the 'Be' field + in the central header. + + See the end of beos/osdep.h for a simple explanation of the 'Be' EF + layout. + */ +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; + /* store full data in local header but just modification time stamp info + in central header */ +{ + int retval; + + /* Tell picky compilers to shut up about unused variables. */ + z_utim = z_utim; + + /* Check to make sure z is valid. */ + if( z == NULL ) { + return ZE_LOGIC; + } + + /* This function is much simpler now that I've moved the extra fields */ + /* out... it simplified the 'Be' code, too. */ + retval = add_UT_ef( z ); + if( retval != ZE_OK ) { + return retval; + } + + retval = add_Ux_ef( z ); + if( retval != ZE_OK ) { + return retval; + } + + retval = add_Be_ef( z ); + if( retval != ZE_OK ) { + return retval; + } + + return ZE_OK; +} + +/* ---------------------------------------------------------------------- */ +/* Set a file's MIME type. */ +void setfiletype( const char *file, const char *type ) +{ + int fd; + attr_info fa; + ssize_t wrote_bytes; + + fd = open( file, O_RDWR ); + if( fd < 0 ) { + zipwarn( "can't open zipfile to write file type", "" ); + return; + } + + fa.type = B_MIME_STRING_TYPE; + fa.size = (off_t)(strlen( type ) + 1); + + wrote_bytes = fs_write_attr( fd, BE_FILE_TYPE_NAME, fa.type, 0, + type, fa.size ); + if( wrote_bytes != (ssize_t)fa.size ) { + zipwarn( "couldn't write complete file type", "" ); + } + + close( fd ); +} + +int deletedir(d) +char *d; /* directory to delete */ +/* Delete the directory *d if it is empty, do nothing otherwise. + Return the result of rmdir(), delete(), or system(). + For VMS, d must be in format [x.y]z.dir;1 (not [x.y.z]). + */ +{ +# ifdef NO_RMDIR + /* code from Greg Roelofs, who horked it from Mark Edwards (unzip) */ + int r, len; + char *s; /* malloc'd string for system command */ + + len = strlen(d); + if ((s = malloc(len + 34)) == NULL) + return 127; + + sprintf(s, "IFS=\" \t\n\" /bin/rmdir %s 2>/dev/null", d); + r = system(s); + free(s); + return r; +# else /* !NO_RMDIR */ + return rmdir(d); +# endif /* ?NO_RMDIR */ +} + +#endif /* !UTIL */ + + +/******************************/ +/* Function version_local() */ +/******************************/ + +void version_local() +{ + static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n"; + + printf(CompiledWith, + +#ifdef __MWERKS__ + "Metrowerks CodeWarrior", "", +#else +# ifdef __GNUC__ + "gcc ", __VERSION__, +# endif +#endif + + "BeOS", + +#ifdef __POWERPC__ + " (PowerPC)", +#else +# ifdef __INTEL__ + " (x86)", +# else + " (UNKNOWN!)", +# endif +#endif + +#ifdef __DATE__ + " on ", __DATE__ +#else + "", "" +#endif + ); + +} /* end function version_local() */ diff --git a/beos/osdep.h b/beos/osdep.h new file mode 100644 index 0000000..0197903 --- /dev/null +++ b/beos/osdep.h @@ -0,0 +1,59 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#include +#include +#include + +#include /* for B_NO_ERROR */ + +#define USE_EF_UT_TIME /* Enable use of "UT" extra field time info */ + +#define EB_L_BE_LEN 5 /* min size is an unsigned long and flag */ +#define EB_C_BE_LEN 5 /* Length of data in local EF and flag. */ + +#define EB_BE_FL_NATURAL 0x01 /* data is 'natural' (not compressed) */ +#define EB_BE_FL_BADBITS 0xfe /* bits currently undefined */ + +#ifndef ZP_NEED_MEMCOMPR +# define ZP_NEED_MEMCOMPR +#endif + +/* Set a file's MIME type. */ +#define BE_FILE_TYPE_NAME "BEOS:TYPE" +void setfiletype( const char *file, const char *type ); + +/* +DR9 'Be' extra-field layout: + +'Be' - signature +ef_size - size of data in this EF (little-endian unsigned short) +full_size - uncompressed data size (little-endian unsigned long) +flag - flags (byte) + flags & EB_BE_FL_NATURAL = the data is not compressed + flags & EB_BE_FL_BADBITS = the data is corrupted or we + can't handle it properly +data - compressed or uncompressed file attribute data + +If flag & EB_BE_FL_NATURAL, the data is not compressed; this optimisation is +necessary to prevent wasted space for files with small attributes (which +appears to be quite common on the Advanced Access DR9 release). In this +case, there should be ( ef_size - EB_L_BE_LEN ) bytes of data, and full_size +should equal ( ef_size - EB_L_BE_LEN ). + +If the data is compressed, there will be ( ef_size - EB_L_BE_LEN ) bytes of +compressed data, and full_size bytes of uncompressed data. + +If a file has absolutely no attributes, there will not be a 'Be' extra field. + +The uncompressed data is arranged like this: + +attr_name\0 - C string +struct attr_info (big-endian) +attr_data (length in attr_info.size) +*/ diff --git a/beos/zipup.h b/beos/zipup.h new file mode 100644 index 0000000..40c79eb --- /dev/null +++ b/beos/zipup.h @@ -0,0 +1,19 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#ifndef O_RDONLY +# include +#endif +#define fhow O_RDONLY +#define fbad (-1) +typedef int ftype; +#define zopen(n,p) open(n,p) +#define zread(f,b,n) read(f,b,n) +#define zclose(f) close(f) +#define zerr(f) (k == (extent)(-1L)) +#define zstdin 0 diff --git a/bzip2/install.txt b/bzip2/install.txt new file mode 100644 index 0000000..87d45ad --- /dev/null +++ b/bzip2/install.txt @@ -0,0 +1,258 @@ +HOW TO ADD BZIP2 SUPPORT TO ZIP + +This document describes how to add bzip2 support to Zip. + +Compiling or linking in the bzip2 library adds an additional bzip2 +compression method to Zip. This new method can be selected instead +of the Zip traditional compression method deflation to compress files +and often gives a better compression ratio (perhaps at the cost of +greater CPU time). The compression method is specified using the +"-Z method" command-line option, where "method" may be either "deflate" +(the default), or "bzip2" (if Zip is built with bzip2 support). Zip +has been tested with bzip2 library 1.0.5 and earlier. + +Notes + +Compression method bzip2 requires a modern unzip. Before using bzip2 +compression in Zip, verify that a modern UnZip program with bzip2 support +will be used to read the resulting zip archive so that entries compressed +with bzip2 (compression method 12) can be read. Older unzips probably +won't recognize the compression method and will skip those entries. + +The Zip source kit does not include the bzip2 library or source files, but +these can be found at "http://www.bzip.org/" for example. See below for +how to add bzip2 to Zip for various operating systems. + +Zip using bzip2 compression is not compatible with the bzip2 application, +but instead provides an additional way to compress files before adding +them to a Zip archive. It does not replace the bzip2 program itself, +which creates bzip2 archives in a different format that are not +compatible with zip or unzip. + +The bzip2 code and algorithms are provided under the bzip2 license +(provided in the bzip2 source kit) and what is not covered by that license +is covered under the Info-ZIP license. Info-ZIP will look at issues +involving the use of bzip2 compression in Zip, but any questions about +the bzip2 code and algorithms or bzip2 licensing, for example, should be +directed to the bzip2 maintainer. + + +Installation + +To build Zip with bzip2 support, Zip generally needs one bzip2 header +file, "bzlib.h", and the object library, typically "libbz2.a", except +in cases where the source files are compiled in directly. If you +are either compiling the bzip2 library or compiling in the bzip2 +source files, we recommend defining the C macro BZ_NO_STDIO, which +excludes a lot of standalone error code (not used when bzip2 is +used as a library and makes the library smaller) and provides hooks +that Zip can use to provide better error handling. However, a +standard bzip2 object library will work, though any errors that bzip2 +generates may be more cryptic. + +Building the bzip2 library from the bzip2 source files (recommended): + + Download the latest bzip2 package (from "http://www.bzip.org/", for + example). + + Unpack the bzip2 source kit (bzip2-1.0.5.tar.gz was current as of + this writing, but the latest should work). + + Read the README file in the bzip2 source kit. + + Compile the bzip2 library for your OS, preferably defining + BZ_NO_STDIO. Note: On UNIX systems, this may be done automatically + when building Zip, as explained below. + + +Installation on UNIX (see below for installation on other systems): + + Note: Zip on UNIX uses the "bzlib.h" include file and the compiled + "libbz2.a" library to static link to bzip2. Currently we do not + support using the shared library (patches welcome). + + The easiest approach may be to drop the two above files in the + bzip2 directory of the Zip source tree and build Zip using the + "generic" target, that is, using a command like + make -f unix/Makefile generic + If all goes well, make should confirm that it found the files and + will be compiling in bzip2 by setting the BZIP2_SUPPORT flag and + then including the libraries while compiling and linking Zip. + + To use bzlib.h and libbz2.a from somewhere else on your system, + define the "make" macro IZ_BZIP2 to point to that directory. For + example: + make -f unix/Makefile generic IZ_BZIP2=/mybz2 + where /mybz2 might be "/usr/local/src/bzip2/bzip2-1.0.5" on some + systems. Only a compiled bzip2 library can be pointed to using + IZ_BZIP2 and Zip will not compile bzip2 source in other than the + bzip2 directory. + + If IZ_BZIP2 is not defined, Zip will look for the bzip2 files in + the "bzip2" directory in the Zip source directory. The bzip2 + directory is empty in the Zip source distribution (except for + this install.txt file) and is provided as a place to put the + bzip2 files. To use this directory, either drop bzlib.h and + libbz2.a in it to use the compiled library as noted above or drop + the contents of the bzip2 source kit in this directory so that + bzlib.h is directly in the bzip2 directory and Zip will try to + compile it if no compiled library is already there. + + + Unpacking bzip2 so Zip compiles it: + + To make this work, the bzip2 source kit must be unpacked directly + into the Zip "bzip2" directory. For example: + + # Unpack the Zip source kit. + gzip -cd zip30.tar-gz | tar xfo - + # Move down to the Zip kit's "bzip2" directory, ... + cd zip30/bzip2 + # ... and unpack the bzip2 source kit there. + gzip -cd ../../bzip2-1.0.5.tar.gz | tar xfo - + # Move the bzip2 source files up to the Zip kit's bzip2 directory. + cd bzip2-1.0.5 + mv * .. + # Return to the Zip source kit directory, ready to build. + cd ../.. + # Build Zip. + make -f unix/Makefile generic + + + Using a system bzip2 library: + + If IZ_BZIP2 is not defined and both a compiled library and the bzip2 + source files are missing from the Zip bzip2 directory, Zip will test + to see if bzip2 is globally defined on the system in the default + include and library paths and, if found, link in the system bzip2 + library. This is automatic. + + + Preventing inclusion of bzip2: + + To build Zip with _no_ bzip2 support on a system where the automatic + bzip2 detection scheme will find bzip2, you can specify a bad + IZ_BZIP2 directory. For example: + + make -f unix/Makefile generic IZ_BZIP2=no_such_directory + + You can also define NO_BZIP2_SUPPORT to exclude bzip2. + + + Verifying bzip2 support in Zip: + + When the Zip build is complete, verify that bzip2 support has been + enabled by checking the feature list: + + ./zip -v + + If all went well, bzip2 (and its library version) should be listed. + + +Installation on other systems + + MSDOS: + + Thanks to Robert Riebisch, the DJGPP 2.x Zip port now supports bzip2. + To include bzip2, first install bzip2. The new msdos/makebz2.dj2 + makefile then looks in the standard bzip2 installation directories + for the needed files. As he says: + It doesn't try to be clever about finding libbz2.a. It just + expects bzip2 stuff installed to the default include and library + folders, e.g., "C:\DJGPP\include" and "C:\DJGPP\lib" on DOS. + + Given a standard DJGPP 2.x installation, this should create a + version of Zip 3.0 with bzip2 support. + + The bzip2 library for DJGPP can be found on any DJGPP mirror in + "current/v2apps" (or "beta/v2apps/" for the latest beta). This + library has been ported to MSDOS/DJGPP by Juan Manuel Guerrero. + + + WIN32 (Windows NT/2K/XP/2K3/... and Windows 95/98/ME): + + For Windows there seems to be two approaches, either use bzip2 + as a dynamic link library or compile the bzip2 source in directly. + I have not gotten the static library libbz2.lib to work, but that + may be me. + + Using bzip2 as a dynamic link library: + + Building bzip2: + + If you have the needed bzlib.h, libbz2.lib, and libbz2.dll files + you can skip building bzip2. If not, open the libbz2.dsp project + and build libbz2.dll + + This creates + debug/libbz2.lib + and + libbz2.dll + + + Building Zip: + + Copy libbz2.lib to the bzip2 directory in the Zip source tree. This + is needed to compile Zip with bzip2 support. Also copy the matching + bzlib.h from the bzip2 source to the same directory. + + Add libbz2.lib to the link list for whatever you are building. Also + define the compiler define BZIP2_SUPPORT. + + Build Zip. + + + Using Zip with bzip2 as dll: + + Put libbz2.dll in your command path. This is needed to run Zip with + bzip2 support. + + Verify that bzip2 is enabled with the command + + zip -v + + You should see bzip2 listed. + + Compiling in bzip2 from the bzip2 source: + + This approach compiles in the bzip2 code directly. No external + library is needed. + + Get a copy of the bzip2 source and copy the contents to the bzip2 + directory in the Zip source tree so that bzlib.h is directly in + the bzip2 directory. + + Use the vc6bz2 project to build Zip. This project knows of the + added bzip2 files. + + Verify that bzip2 is enabled with the command + + zip -v + + + Windows DLL (WIN32): + + Nothing yet. + + + Mac OS X: + + Follow the standard UNIX build procedure. Mac OS X includes bzip2 + and the UNIX builders should find the bzip2 files in the standard + places. Note that the version of bzip2 on your OS may not be + current and you can instead specify a different library or compile + your own bzip2 library as noted in the Unix procedures above. + + + OS/2: + + Nothing yet. + + + VMS (OpenVMS): + + See [.vms]install_vms.txt for how to enable bzip2 support on VMS. + + +Last updated 26 March 2007, 15 July 2007, 9 April 2008, 27 June 2008 +S. Schweda, E. Gordon diff --git a/cmsmvs/README.CMS b/cmsmvs/README.CMS new file mode 100644 index 0000000..a4425da --- /dev/null +++ b/cmsmvs/README.CMS @@ -0,0 +1,434 @@ +Using ZIP and UNZIP on VM/CMS +============================= + + +Installing executables +---------------------- + +The following CMS MODULEs are available: + ZIP + ZIPNOTE + ZIPCLOAK + ZIPSPLIT + UNZIP + +In addition to these, each MODULE file also has an EXEC with the same +name. These EXECs are front-ends to the MODULES that will attempt to +set up the required runtime libraries before running the MODULE. +All the EXECs are identical. Only their names are different. +They are stored as plain text files. + +The CMS MODULE files have been packed using the COPYFILE command to +allow their file format to be properly restored, since variable length +binary files will not currently unzip properly (see below for details). +The MODULEs are shipped with a filetype or extension of CMO (for CMS +MODULE). Their names may vary on the distribution disk to indicate +their level, etc. + +To restore them to executable MODULEs on CMS, do the following: + 1. Upload them to CMS with a Fixed record length with LRECL 1024. + Example, from a DOS or OS/2 window, type this: + SEND unzip.cmo A:unzip module a (RECFM F LRECL 1024 + + Example, using FTP from CMS, type this: + BINARY FIXED 1024 + GET unzip.cmo unzip.module.a + + Note: Replace "unzip.cmo" with the actual name. + + 2. Use COPYFILE to unpack the file. + Example, in CMS type this: + COPYFILE UNZIP MODULE A (UNPACK REPLACE OLDDATE + + 3. Repeat steps 1-2 for each of the programs. + + 4. Build the ZIPINFO module by typing this: + COPYFILE UNZIP MODULE A ZIPINFO MODULE A (OLDDATE + + 5. Upload the EXECs to CMS as text files (with ASCII-to-EBCDIC + translation). + Example, from a DOS or OS/2 window, type this: + SEND unzip.exc A:unzip exec a (CRLF + + Example, using FTP from CMS, type this: + GET unzip.exc unzip.exec.a + + 6. Repeat steps 4 for each of the EXECs. + + +Preparing the environment +------------------------- + +The executables provided were compiled with IBM C 3.1.0 and +require the the Language Environment (LE) runtime libraries. + +To provide access to the runtime libraries: + 1. Link to the disk containing the Language Environment files, + if necessary. + + 2. Use the command "GLOBAL LOADLIB SCEERUN" + + These commands can be placed in your PROFILE EXEC. + + Note: EXECs have been provided called ZIP, UNZIP, etc. that + issue the GLOBAL LOADLIB statement. This was done to alleviate + frustration of users that don't have the GLOBAL LOADLIB statement + in their PROFILE EXEC. These EXECs may require changing for + your system. + + Unfortunately, there is no way, using IBM C, to produce a MODULE + that doesn't require a runtime library. + + +Testing +------- + +To test the MODULEs, just type ZIP or UNZIP. They should +show help information on using the commands. + +If you see something like this: + DMSLIO201W The following names are undefined: + CEEEV003 + DMSABE155T User abend 4093 called from 00DCD298 reason code 000003EB + +Then you don't have access to the proper runtime libraries, as +described above. + +Here is additional information on the ZIP and UNZIP programs that +may assist support personnel: + - Compiled with IBM C V3R1M0 on VM/ESA 2.2.0 with + CMS level 13 Service Level 702. + + - Require the SCEERUN LOADLIB runtime library. This is + part of the Language Environment (LE). + + - Linked with options RMODE ANY AMODE ANY RLDSAVE. + +If you continue to have trouble, report the problem to Zip-Bugs +(see the bottom of this document). + + + +Compiling the source on VM/CMS +------------------------------ + +The source has been successfully compiled previously using +C/370 2.1 and 2.2. The source has been recently compiled using +IBM C 3.1.0 on VM/ESA 2.2.0 with CMS level 13. I don't have +access to an MVS system so the code hasn't been tested there +in a while. + + 1. Unzip the source files required for CMS. The root-level files + inside the ZIP file and the files in the CMSMVS subdirectory are + needed. Example (use both commands): + unzip -aj zip23.zip -x */* -dc + unzip -aj zip23.zip cmsmvs/* -dc + + This example unzips the files to the C-disk, while translating + character data and ignoring paths. + + If you don't already have a working UNZIP MODULE on CMS you will + have to unzip the files on another system and transport them + to CMS. All the required files are plain text so they can + be transferred with ASCII-to-EBCDIC translations. + + 2. Repeat step 1 with the zip file containing the UNZIP code. + Unzip the files to a different disk than the disk used for the ZIP + code. + + 3. To compile the ZIP code, run the supplied CCZIP EXEC. + To compile the UNZIP code, run the supplied CCUNZIP EXEC. + +NOTE: +Some of the ZIP and UNZIP source files have the same name. It is +recommended that you keep the source from each on separate disks and +move the disk you are building from ahead of the other in the search +order. + +For example, you may have a 192 disk with the ZIP source code and +a 193 disk with the UNZIP source code. To compile ZIP, access +the 192 disk as B, then run CCZIP. This will create the following +modules: ZIP, ZIPNOTE, ZIPSPLIT, ZIPCLOAK. + +To compile UNZIP, access 193 as B, then run CCUNZIP. This will create +the following modules: UNZIP, ZIPINFO (a copy of UNZIP). + + +========================================================================= + + +Using ZIP/UNZIP +--------------- + +Documentation for the commands is in MANUAL NONAME (for ZIP) and in +UNZIP DOC UNZIP. INFOZIP DOC describes the use of the -Z option of +UNZIP. + +The rest of this section explains special notes concerning the VM/CMS +version of ZIP and UNZIP. + + +Filenames and directories +------------------------- + + 1. Specifying filenames + + a. When specifying CMS files, use filename.filetype.filemode format + (separate the three parts of the name with a period and use no + spaces). Example: profile.exec.a + + Unfortunately, this prevents you from using ZIP from + FILELIST. To unzip a zip file, however, you can type something + like this next to it in FILELIST: + unzip /n -d c + + This will unzip the contents of the current file to a C-disk. + + b. It is possible to use DD names with ZIP and UNZIP on CMS, though + it can be cumbersome. Example: + filedef out disk myzip zip a + zip dd:out file1.txt file2.txt + + While you can also use a DD name for the input files, ZIP + currently does not correctly resolve the filename and will + store something like "dd:in" inside the ZIP file. A file stored + in this manor cannot easily be unzipped, as "dd:in" is an invalid + filename. + + c. In places where a directory name would be used on a PC, such as + for the ZIP -b (work path) option or the UNZIP -d (destination + path) options, use a filemode letter for CMS. For example, + to unzip files onto a C-disk, you might type something like this: + unzip myzip.zip -d c + + Currently, ZIP uses the A-disk for work files. When zipping + large files, you may want to specify a larger disk for work files. + This example will use a C-disk for work files. + zip -b C myzip.zip.c test.dat.a + + + 2. Filename conversions + + a. Filemode letters are never stored into the zip file or take from + a zip file. Only the filename and filetype are used. + ZIP removes the filemode when storing the filename into the + zip file. UNZIP assumes "A" for the filemode unless the -d + option is used. + + b. When unzipping, any path names are removed from the fileid + and the last two period-separated words are used as the + filename and filetype. These are truncated to a maximum of + eight characters, if necessary. If the filetype (extension) + is missing, then UNZIP uses "NONAME" for the filetype. + Any '(' or ')' characters are removed from the fileid. + + c. All files are created in upper-case. Files in mixed-case + cannot currently be stored into a ZIP file. + + d. Shared File System (SFS) directories are not supported. + Files are always accessed by fn.ft.fm. To use an SFS disk, + Assign it a filemode, then it can be used. + + + 3. Wildcards in file names + + a. Wildcards are not supported in the zip filename. The full + filename of the zip file must be given (but the .zip is not + necessary). So, you can't do this: + unzip -t *.zip + + b. Wildcards CAN be used with UNZIP to select (or exclude) files + inside a zip file. Examples: + unzip myzip *.c - Unzip all .c files. + unzip myzip *.c -x z*.c - Unzip all .c files but those + starting with Z. + + c. Wildcards cannot currently be used to select files with ZIP. + So, you can't do this: + zip -a myzip *.exec + + I expect to fix this for CMS in the future. + + + 4. File timestamps + + a. The dates and times of files being zipped or unzipped are not + currently read or set. When a file is zipped, the timestamp + inside the zip file will always be the current system date and + time. Likewise, when unzipping, the date and time of files + being unzipped will always be the current system date/time. + + b. Existing files are assumed to be newer than files inside a zip + file when using the -f freshen option of UNZIP. This will prevent + overwriting files that may be newer than the files inside the + zip file, but also effectively prevents the -f option from working. + + + 5. ASCII, EBCDIC, and binary data + + Background + ---------- + Most systems create data files as just a stream of bytes. Record + breaks happen when certain characters (new line and/or carriage + return characters) are encountered in the data. How to interpret + the data in a file is up to the user. The system must be told + to either notice new line characters in the data or to assume + that the data in the file is binary data and should be read or + written as-is. + + CMS and MVS are record-based systems. All files are composed + of data records. These can be stored in fixed-length files or + in variable length files. With fixed-length files, each record + is the same length. The record breaks are implied by the + LRECL (logical record length) attribute associated with the file. + With variable-length files, each record contains the length of + that record. The separation of records are not part of the + data, but part of the file structure. + + This means you can store any type of data in either type of file + structure without having to worry about the data being interpreted + as a record break. Fixed-length files may have padding at the + end of the file to make up a full record. Variable-length files + have no padding, but require extra record length data be stored + with the file data. + + Storing fixed-length files into a zip file is simple, because all + the data can just be dumped into the zip file and the record + format (RECFM) and logical record length (LRECL) can be stored + in the extra data area of the zip file so they can be restored + when UNZIP is used. + + Storing variable-length data is harder. There is no place to put + the record length data needed for each record of the file. This + data could be written to the zip file as the first two bytes of + each record and interpreted that way by UNZIP. That would make + the data unusable on systems other than CMS and MVS, though. + + Currently, there isn't a solution to this problem. Each record is + written to the zip file and the record length information is + discarded. Binary data stored in variable-length files can't be put + into a zip file then later unzipped back into the proper records. + This is fine for binary data that will be read as a stream of bytes + but not OK where the records matter, such as with CMS MODULEs. + + If the data is text (character data), there is a solution. + This data can be converted into ASCII when it's stored into + a zip file. The end of each record is now marked in the file + by new line characters. Another advantage of this method is + that the data is now accessible to non-EBCDIC systems. When + the data is unzipped on CMS or MVS, it is converted back into + EBCDIC and the records are recreated into a variable-length file. + + + So, here's what we have... + + a. To store readable text data into a zip file that can be used + on other platforms, use the -a option with ZIP to convert the + data to ASCII. These files will unzip into variable-length + files on CMS and should not contain binary data or corruption + may occur. + + b. Files that were zipped on an ASCII-based system will be + automatically translated to EBCDIC when unzipped. To prevent + this (to unzip binary data on CMS that was sent from an + ASCII-based system), use the -B option with UNZIP to force Binary + mode. To zip binary files on CMS, use the -B option with ZIP to + force Binary mode. This will prevent any data conversions from + taking place. + + c. When using the ZIP program without specifying the "-a" or "-B" + option, ZIP defaults to "native" (EBCDIC) mode and tries to + preserve the file information (RECFM, LRECL, and BLKSIZE). So + when you unzip a file zipped with ZIP under CMS or MVS, UNZIP + restores the file info. The output will be fixed-length if the + original was fixed and variable-length if the original was + variable. + + If UNZIP gives a "write error (disk full?)" message, you may be + trying to unzip a binary file that was zipped as a text file + (without using the -B option) + + + Summary + ------- + Here's how to ZIP the different types of files. + + RECFM F text + Use the -a option with ZIP to convert to ASCII for use with other + platforms or no options for use on EBCDIC systems only. + + RECFM V text + Use the -a option with ZIP to convert to ASCII for use with other + platforms or no options for use on EBCDIC systems only. + + + RECFM F binary + Use the -B option with ZIP (upper-case "B"). + + RECFM V binary + Use the -B option with ZIP. Can be zipped OK but the record + structure is destroyed when unzipped. This is OK for data files + read as binary streams but not OK for files such as CMS MODULEs. + + + 6. Character Sets + + If you are used to running UNZIP on systems like UNIX, DOS, OS/2 or + Windows, you will may have some problems with differences in the + character set. + + There are a number of different EBCDIC code pages, like there are a + number of different ASCII code pages. For example, there is a US + EBCDIC, a German EBCDIC, and a Swedish EBCDIC. As long as you are + working with other people who use the same EBCDIC code page, you + will have no trouble. If you work with people who use ASCII, or who + use a different EBCDIC code page, you may need to do some + translation. + + UNZIP translates ASCII text files to and from Open Systems EBCDIC + (IBM-1047), which may not be the EBCDIC that you are using. For + example, US EBCDIC (IBM-037) uses different character codes for + square brackets. In such cases, you can use the ICONV utility + (supplied with IBM C) to translate between your EBCDIC character set + and IBM-1047. + + If your installation does not use IBM-1047 EBCDIC, messages from + UNZIP may look a little odd. For example, in a US EBCDIC + installation, an opening square bracket will become an i-acute and a + closing square bracket will become a u-grave. + + The supplied ZIP and UNZIP EXECs attempt to correct this by setting + CMS INPUT and OUTPUT translations to adjust the display of left and + right brackets. You may need to change this if brackets don't + display correctly on your system. + + + 7. You can unzip using VM/CMS PIPELINES so unzip can be used as + a pipeline filter. Example: + 'PIPE COMMAND UNZIP -p test.zip george.test | Count Lines | Cons' + + + + +Please report all bugs and problems to: + Zip-Bugs@lists.wku.edu + + +----------------------------------------------------------------------- +Original CMS/MVS port by George Petrov. +e-mail: c888090@nlevdpsb.snads.philips.nl +tel: +31-40-781155 + +Philips C&P +Eindhoven +The Netherlands + +----------------------------------------------------------------------- +Additional fixes and README re-write (4/98) by Greg Hartwig. +e-mail: ghartwig@ix.netcom.com + ghartwig@vnet.ibm.com + +----------------------------------------------------------------------- +Additional notes from Ian E. Gorman. +e-mail: ian@iosphere.net + diff --git a/cmsmvs/README.MVS b/cmsmvs/README.MVS new file mode 100644 index 0000000..4d451db --- /dev/null +++ b/cmsmvs/README.MVS @@ -0,0 +1,92 @@ +Thank you for trying this first port of ZIP for VM/CMS and MVS! + + + Using under MVS: + --------------------------- + +1. To use the Info-ZIP's ZIP under MVS you need: + + - C/370 ver 2.1 compiler or another compatible compiler supporting + long names for function/variable names. + +2. To compile the program under MVS do : + + - unzip all the files from zip22.zip file. They are stored as + ASCII format so you have to unzip them first on PC or other + system that already have UNZIP, and then upload them to the + mainframe with ASCII to EBCDIC conversion. + + - Copy all the .C files in the PDS called youruserid.ZIP.C + + - Copy all the .H files in the PDS called youruserid.ZIP.H + + - adjust the job ZIPMVSC.JOB to work on your size. Change my + userid - C888090 to yours + + - execute the job ZIPMVSC to compile and link all the sources. + + - maybe you have to preallocate PDS datasets named: + youruserid.ZIP.OBJ and youruserid.ZIP.LOAD + + - execute ZIPVMC to compile and link all the sources. + + - if everything is ok you will get an ZIP MODULE + + - the warnings about the duplicated ASCII and EBCDIC symbols + are OK :-) + +3. Using ZIP + + - Just read MANUAL + + - A few exceptions concerning MVS + + 3.1. if you want to make a portable zip file that is to be unzipped + on ASCII based systems use the -a option + + 3.2. If you want to zip the input files as binary ebcdic files + use the -B (capital letter) option + + 3.3. The date/end the time of the input files is set in the zip's + dir to the current system date/time + + 3.4. Without specifying the "-a" or "-B" option, the ZIP program + defaults to "native" (EBCDIC) mode and tries to preserve the + file information (LRECL,BLKSIZE..) + So when you UNZIP a file zipped with ZIP under VM/MVS it + restores the file info. + + There currently some problems with file with RECFM=V* + I don't save the length of each record yet :-) + + 3.5. No wildcards are supported as input file names: + + So you CAN'T use things like: zip myzip *.c + + 3.6. You can use DD names for zipfilename for example: + + under tso/rexx: + + "alloc fi(input) da('myzip.zip')" + "zip dd:input file1.txt file2.txt ..." + + under Batch: + + //MYZIP JOB (account) + //STEP1 EXEC PGM=ZIP,PARM='dd:input file1.txt file2.txt' + //STEPLIB DD DSN=userid.UNZIP.LOAD,DISP=SHR + //INPUT DD DSN=userid.MYZIP.ZIP,DISP=NEW, + // SPACE=(15000,(15000,10000),RLSE), + // DCB=(LRECL=80,RECFM=F) + //SYSPRINT DD SYSOUT=* + + +Please report all bugs and problems to : + zip-bugs@lists.wku.edu + +That's all for now. + +Have fun! + + +George Petrov diff --git a/cmsmvs/README.MVS.LE b/cmsmvs/README.MVS.LE new file mode 100644 index 0000000..f7dcb8a --- /dev/null +++ b/cmsmvs/README.MVS.LE @@ -0,0 +1,286 @@ +Notes on Zip under MVS Language Environment (LE). + +First see README.MVS. This note describes just one beta test on OS/390 +V2R5 using IBM's C compiler (5647A01), V2R4. The major difference is +the use of LE on the beta site, together with some MVS native mode +fixes. Changes have not been tested on CMS. + +Some of the notes are to clarify things that were not clear from the +MANUAL or README.MVS. + +1. By default, IBM C generates the same csect name for each input + source. The prelink stage does not rename them and the linkage + editor throws away all but the first occurrence of each duplicate. + Oops, my code just disappeared :(. + + To get around this "feature", compile with the CSECT option to + force sensible names on the code and data sections of each csect. + The name of the static data csect defaults to the source name in + lower case, the code csect defaults to the source name in upper + case. These csect names still have to be unique, they cannot be + the same as function names. Of course, several csects have a + function which is the same name as the source in lower case, not + exactly an unusual occurrence. Therefore to make the csect name + unique, some of the sources have + + #ifdef MVS + # pragma csect(STATIC,xxxx_s) + #endif + + Where xxxx is an abbreviation of the source name. There has to be + a better way! + +2. The prelink step always gets cond code 4. It complains about + unresolved references, ignore it unless the linker also complains. + Prelink also complains about duplicate @@PPA2 sections and so does + the linker, but it seems to do no harm. Compile and link steps + should get 0, just prelink gets 4. See JCL at the bottom. + +3. Under MVS native mode (not Open Edition), tmpnam() returns a quoted + name of 5 qualifiers. The first is a HLQ chosen according to the + MVS LE algorithm (see below), the other qualifiers are time stamps. + If running on MVS and tmpnam() returns a quoted name with at leat + one '.', it is only safe to let the user change the high level + qualifier. Therefore -b insists on a single qualifier without '.' + in the MVS native environment. + +4. In Open Edition (OE) mode, the manual says that tmpnam() returns a + fully qualified name in directory TMPDIR or /tmp if TMPDIR is not + set. There is no point in zip trying to override that name so -b + is ignored in MVS OE mode (untested). The user should specify + environment variable TMPDIR instead. + +5. The MVS LE algorithm for choosing the high level qualifier for + native filenames is interesting, as in "May you live in interesting + times". The HLQ varies according to the environment the program is + running in, sometimes it is userid, sometimes it is TSO prefix. + See OS/390 C/C++ Programming Guide, Using a Data Set Name, + somewhere around section 2.9. + + If in doubt, use fully qualified and quoted names. Instead of + archive.zip, use 'prefix.archive.zip'. For input files, instead of + filename, use 'prefix.filename'. For PARM= in JCL, double up the + quotes. You even have to quote filenames in stdin. + +6. If your PARM includes any '/', make sure the PARM starts with '/'. + LE assumes anything before the first '/' is LE run time parameters. + It does no harm to always code a leading '/' for LE parms. + +7. JCL limits a PARM= to 100 characters total with approx. 65 on a + single line. Alas the syntax for continuing PARM= always embeds an + extra ',' somewhere in the parameters that the program finally + gets. No workaround, limit your PARM to a single line. With the + extra quotes around filenames, that does not leave much room. In + most cases, you will have to use '-@' to read the list of filenames + from SYSIN (stdin), it will not fit on a single PARM line. + +8. Filenames can be dataset names or you can refer to a ddname with + 'DD:name', case insensitive for external files, case sensitive for + OE files. You can even specify 'dd:name(mem)'. No wildcards, to + zip a complete pds you have to specify each member individually. + Directory recursion in OE does not appear to work at the moment. + +9. Zip attempts to map MVS filenames to Unix style names. It did not + work correctly for quoted names, fixed. Although you can pick up + an external (non-OE) file with a name using any case, be aware that + the mapping to a Unix style name faithfully follows the case you + supply. + +10. The archive file was being created with recfm=V and lrecl=32760. + 32760 is not valid for recfm=V under MVS, I originally changed it + to lrecl=32756. Then zip broke trying to fseek() over a record + boundary, I do not know whether this was a zip or LE bug. Trial + and error showed that recfm=U with byteseek seems to work on MVS. + No BDW or RDW, just a byte stream. The blocksize is always 6144. + + NOTE: This is an incompatible change from the previous beta, + archive files used to be recfm=V. That should not matter + because we just transfer the data, ignoring BDW and RDW + anyway. + +11. Zip used to complain about preallocated but empty archives, wrong + length records, no signature etc. The usual IBM/360 problem of no + end of file marker in a new, unopened dataset. Fixed, see routine + readzipfile in zipfile.c for the gory details. PARM= works fine. + +12. Several source files have records that are more than 80 bytes long. + It works if you transfer to mainframe datasets with a larger lrecl, + I used recfm=fb,lrecl=120 for the .C and .H files. To compile with + anything longer than 72 bytes, you need MVS C options NOMARGINS and + NOSEQUENCE (NOMAR,NOSEQ). + +13. cmsmvs was still using zname instead of name for open. Fixed. + +14. zip has to jump through a lot of hoops to see if an existing + zipfile actually contains data. A side effect of this is that + creating a zipfile with the RLSE parameter is a waste of time. + +Keith Owens . Not a maintainer, just a beta tester. +Mon Sep 14 19:31:30 EST 1998 + + +Sample JCL to compile Zip under MVS LE. You might need a large region, +I used REGION=128M on the job card. Also watch the output lines, +75,000 with OPT(2), 100,000+ with OPT(2) replaced with DEF(DEBUG). You +need to allocate prefix.ZIP.C.OBJ (recfm=FB, lrecl=80) and +prefix.ZIP.LOAD (recfm=U, blksize is site defined). + +//CBC JCLLIB ORDER=CBC.SCBCPRC +//ZIP EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(ZIP)', +// OUTFILE='prefix.ZIP.C.OBJ(ZIP),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//CRYPT EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(CRYPT)', +// OUTFILE='prefix.ZIP.C.OBJ(CRYPT),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//TTYIO EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(TTYIO)', +// OUTFILE='prefix.ZIP.C.OBJ(TTYIO),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//TREES EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(TREES)', +// OUTFILE='prefix.ZIP.C.OBJ(TREES),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//DEFLATE EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(DEFLATE)', +// OUTFILE='prefix.ZIP.C.OBJ(DEFLATE),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//FILEIO EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(FILEIO)', +// OUTFILE='prefix.ZIP.C.OBJ(FILEIO),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//GLOBALS EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(GLOBALS)', +// OUTFILE='prefix.ZIP.C.OBJ(GLOBALS),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//UTIL EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(UTIL)', +// OUTFILE='prefix.ZIP.C.OBJ(UTIL),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//CRC32 EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(CRC32)', +// OUTFILE='prefix.ZIP.C.OBJ(CRC32),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//CRCTAB EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(CRCTAB)', +// OUTFILE='prefix.ZIP.C.OBJ(CRCTAB),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//ZIPFILE EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(ZIPFILE)', +// OUTFILE='prefix.ZIP.C.OBJ(ZIPFILE),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//ZIPUP EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(ZIPUP)', +// OUTFILE='prefix.ZIP.C.OBJ(ZIPUP),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//CMSMVS EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(CMSMVS)', +// OUTFILE='prefix.ZIP.C.OBJ(CMSMVS),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//MVS EXEC EDCC,COND=(0,NE),CREGSIZ='4M', +// INFILE='prefix.ZIP.C(MVS)', +// OUTFILE='prefix.ZIP.C.OBJ(MVS),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE', +// CPARM2='OPT(2),DEF(MVS),NOMAR,NOSEQ,CSECT' +//COMPILE.USERLIB DD DSN=prefix.ZIP.H,DISP=SHR +//PLINK EXEC PROC=EDCPL, +// OUTFILE='prefix.ZIP.LOAD(ZIP),DISP=SHR', +// PREGSIZ=6M, +// PPARM='NONCAL,MAP,MEMORY', +// LPARM='LIST,MAP,XREF' +//PLKED.SYSIN DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(ZIP) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(CRYPT) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(TREES) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(DEFLATE) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(FILEIO) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(GLOBALS) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(UTIL) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(CRC32) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(CRCTAB) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(ZIPFILE) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(ZIPUP) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(MVS) +// DD DISP=SHR,DSN=prefix.ZIP.C.OBJ(CMSMVS) +//LKED.SYSLIB DD DISP=SHR,DSN=CEE.SCEELKED +//SYSUT1 DD UNIT=SYSDA,SPACE=(CYL,(2,2)) +// + +Sample JCL to zip the mainframe .C and .H files as ASCII (-a). Delete +any existing archive first, point the temporary file at a particular +prefix (-b), use 'prefix.ARCHIVE.ZIP' for the archive file, read the +list of files to zip from stdin (SYSIN). + +//DELETE EXEC PGM=IDCAMS +//SYSPRINT DD SYSOUT=* +//SYSIN DD * + DELETE prefix.ARCHIVE.ZIP + SET MAXCC = 0 +//ZIP EXEC PGM=ZIP, +// PARM='/-a -v -b temppref ''prefix.ARCHIVE.ZIP'' -@' +//STEPLIB DD DSN=prefix.ZIP.LOAD,DISP=SHR +//SYSPRINT DD SYSOUT=* +//SYSOUT DD SYSOUT=* +//CEEDUMP DD SYSOUT=* +//ZIPC DD DISP=SHR,DSN=prefix.ZIP.C +//ZIPH DD DISP=SHR,DSN=prefix.ZIP.H +//SYSIN DD * +dd:zipc(api) +dd:zipc(cms) +dd:zipc(cmsmvs) +dd:zipc(crctab) +dd:zipc(crc32) +dd:zipc(crypt) +dd:zipc(deflate) +dd:zipc(fileio) +dd:zipc(globals) +dd:zipc(mktime) +dd:zipc(mvs) +dd:zipc(trees) +dd:zipc(ttyio) +dd:zipc(util) +dd:zipc(zip) +dd:zipc(zipcloak) +dd:zipc(zipfile) +dd:zipc(zipnote) +dd:zipc(zipsplit) +dd:zipc(zipup) +dd:ziph(api) +dd:ziph(cmsmvs) +dd:ziph(crypt) +dd:ziph(cstat) +dd:ziph(ebcdic) +dd:ziph(mvs) +dd:ziph(revision) +dd:ziph(stat) +dd:ziph(tailor) +dd:ziph(ttyio) +dd:ziph(zip) +dd:ziph(ziperr) +dd:ziph(zipup) diff --git a/cmsmvs/cczip.exec b/cmsmvs/cczip.exec new file mode 100644 index 0000000..86edb59 --- /dev/null +++ b/cmsmvs/cczip.exec @@ -0,0 +1,123 @@ +/* CCZIP EXEC Compile zip for VM/CMS */ +/* Author: George Petrov, 11 Apr 1995 (VMCOMPIL EXEC) */ +/* Modified for IBM C V3R1 by Ian E. Gorman, 2 Nov 1998 + Facilities for compiling and testing were provided by + OmniMark Technologies Corporation, Ottawa, Canada +*/ +Address Command +Signal On Error + +/* Allow longnames, compile re-entrant code. + globals.c and cmsmvs.c require EXTENDED features */ +CCopts = 'LONGNAME RENT LANGLVL(EXTENDED) NOEXECOPS' + +/* ZIP options -- VM_CMS, REENTRANT */ +CCopts = CCopts 'DEFINE(VM_CMS,REENTRANT)' + +/* Link the load module to run in more or less than 16MB memory */ +LINKopts = 'AMODE ANY RMODE ANY RLDSAVE' + +/* resources needed to build */ +'GLOBAL TXTLIB SCEELKED CMSLIB' +'GLOBAL LOADLIB SCEERUN' + +/* produce the TEXT (object) files */ +linklist='' +modname='ZIP' +Say 'Building' modname 'MODULE...' +Call Compile 'ZIP' +Call Compile 'CRC32' +Call Compile 'CRYPT' +Call Compile 'DEFLATE' +Call Compile 'FILEIO' +Call Compile 'GLOBALS' +Call Compile 'TREES' +Call Compile 'TTYIO' +Call Compile 'UTIL' +Call Compile 'ZIPUP' +Call Compile 'ZIPFILE' +Call Compile 'CMSMVS' +Call Compile 'CMS' + +Say 'Linking...' +'EXEC CMOD' linklist '(MODNAME' modname LINKopts +Say modname 'built successfully.' + + +/*---------------------------------------------------------------------*/ +/* Build utility programs */ +/*---------------------------------------------------------------------*/ +CCopts = CCopts 'DEFINE(UTIL)' + + +linklist='' +modname='ZIPNOTE' +Say +Say 'Building' modname 'MODULE...' +Call Compile 'ZIPNOTE' +Call Compile 'ZIPFILE' +Call Compile 'FILEIO' +Call Compile 'UTIL' +Call Compile 'GLOBALS' +Call Compile 'CMSMVS' + +Say 'Linking...' +'EXEC CMOD' linklist '(MODNAME' modname LINKopts +Say modname 'built successfully.' + + +linklist='' +modname='ZIPSPLIT' +Say +Say 'Building' modname 'MODULE...' +Call Compile 'ZIPSPLIT' +Call Compile 'ZIPFILE' +Call Compile 'FILEIO' +Call Compile 'UTIL' +Call Compile 'GLOBALS' +Call Compile 'CMSMVS' + +Say 'Linking...' +'EXEC CMOD' linklist '(MODNAME' modname LINKopts +Say modname 'built successfully.' + + +linklist='' +modname='ZIPCLOAK' +Say +Say 'Building' modname 'MODULE...' +Call Compile 'ZIPCLOAK' +Call Compile 'ZIPFILE' +Call Compile 'FILEIO' +Call Compile 'UTIL' +Call Compile 'GLOBALS' +Call Compile 'CRC32' +Call Compile 'CRYPT' +Call Compile 'TTYIO' +Call Compile 'CMSMVS' + +Say 'Linking...' +'EXEC CMOD' linklist '(MODNAME' modname LINKopts +Say modname 'built successfully.' +Say 'Done.' + +Exit rc + + + +error: + Say 'Error' rc 'during compilation!' + Say 'Error in line' sigl':' + Say ' 'Sourceline(sigl) + Exit rc + + + +Compile: Procedure Expose CCopts LINKopts linklist + Parse arg filename filetype filemode . + If filetype='' Then filetype='C' + linklist = linklist filename + + Say 'Compiling' filename filetype filemode '...' + 'EXEC CC' filename filetype filemode '('CCopts + Return rc diff --git a/cmsmvs/cms.c b/cmsmvs/cms.c new file mode 100644 index 0000000..e69f5cb --- /dev/null +++ b/cmsmvs/cms.c @@ -0,0 +1,34 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/* + * VM/CMS specific things. + */ + +#include "zip.h" + +int procname(n, caseflag) +char *n; /* name to process */ +int caseflag; /* true to force case-sensitive match */ +/* Process a name or sh expression to operate on (or exclude). Return + an error code in the ZE_ class. */ +{ + FILE *stream; + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0, caseflag); + else { + if ((stream = fopen(n, "r")) != (FILE *)NULL) + { + fclose(stream); + return newname(n, 0, caseflag); + } + else return ZE_MISS; + } + return ZE_OK; +} diff --git a/cmsmvs/cmsmvs.c b/cmsmvs/cmsmvs.c new file mode 100644 index 0000000..9c56de7 --- /dev/null +++ b/cmsmvs/cmsmvs.c @@ -0,0 +1,442 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/* + * routines common to VM/CMS and MVS + */ + +#include "zip.h" + +#include +#include +#include + +#ifndef MVS /* MVS has perfectly good definitions of the following */ +int stat(const char *path, struct stat *buf) +{ + if ((buf->fp = fopen(path, "r")) != NULL) { + fldata_t fdata; + if (fldata( buf->fp, buf->fname, &fdata ) == 0) { + buf->st_dev = fdata.__device; + buf->st_mode = *(short *)(&fdata); + } + strcpy( buf->fname, path ); + fclose(buf->fp); + } + return (buf->fp != NULL ? 0 : 1); +} +#endif /* MVS */ + + +#ifndef UTIL /* the companion #endif is a bit of ways down ... */ + +#define PAD 0 +#define PATH_END '/' + +/* Library functions not in (most) header files */ + +#ifdef USE_ZIPMAIN +int main OF((void)); +#endif + +int utime OF((char *, ztimbuf *)); + +extern char *label; +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +#ifndef MVS /* MVS has perfectly good definitions of the following */ +int fstat(int fd, struct stat *buf) +{ + fldata_t fdata; + + if ((fd != -1) && (fldata( (FILE *)fd, buf->fname, &fdata ) == 0)) { + buf->st_dev = fdata.__device; + buf->st_mode = *(short *)(&fdata); + buf->fp = (FILE *)fd; + return 0; + } + return -1; +} +#endif /* MVS */ + + +char *ex2in(x, isdir, pdosflag) +char *x; /* external file name */ +int isdir; /* input: x is a directory */ +int *pdosflag; /* output: force MSDOS file attributes? */ +/* Convert the external file name to a zip file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *n; /* internal file name (malloc'ed) */ + char *t; /* shortened name */ + int dosflag; + char mem[10] = ""; /* member name */ + char ext[10] = ""; /* extension name */ + + dosflag = dosify; /* default for non-DOS non-OS/2 */ + + /* Find starting point in name before doing malloc */ + for (t = x; *t == '/'; t++) + ; + + /* Make changes, if any, to the copied name (leave original intact) */ + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + +#ifdef MVS + /* strip quotes from name, non-OE format */ + if (*n == '\'' && (t = strrchr(n, '\'')) != n) { + if (!*(t+1)) { + /* yes, it is a quoted name */ + int l = strlen(n) - 2; + memmove(n, n+1, l); + *(n+l) = '\0'; + } + } + /* Change member names to fn.ext */ + if (t = strrchr(n, '(')) { + *t = '\0'; + strcpy(mem,t+1); /* Save member name */ + if (t = strchr(mem, ')')) *t = '\0'; /* Set end of mbr */ + /* Save extension */ + if (t = strrchr(n, '.')) t++; + else t = n; + strcpy(ext,t); + /* Build name as "member.ext" */ + strcpy(t,mem); + strcat(t,"."); + strcat(t,ext); + } + + /* Change all but the last '.' to '/' */ + if (t = strrchr(n, '.')) { + while (--t > n) + if (*t == '.') + *t = '/'; + } +#else + /* On CMS, remove the filemode (all past 2nd '.') */ + if (t = strchr(n, '.')) + if (t = strchr(t+1, '.')) + *t = '\0'; + t = n; +#endif + + strcpy(n, t); + + if (isdir == 42) return n; /* avoid warning on unused variable */ + + if (dosify) + msname(n); /* msname() needs string in native charset */ + + strtoasc(n, n); + + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + return n; +} + + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strtoebc(x, n); + return x; +} + + +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ + ztimbuf u; /* argument for utime() */ + + /* Convert DOS time to time_t format in u.actime and u.modtime */ + u.actime = u.modtime = dos2unixtime(d); + + utime(f, &u); +} + + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +{ + FILE *stream; + time_t ltime; + + if (strcmp(f, "-") != 0) { /* if not compressing stdin */ + Trace((mesg, "opening file '%s' with '%s'\n", f, FOPR)); + if ((stream = fopen(f, FOPR)) == (FILE *)NULL) { + return 0; + } else { + if (n != NULL) { + /* With byteseek, this will work */ + fseek(stream, 0L, SEEK_END); + *n = ftell(stream); + Trace((mesg, "file size = %lu\n", *((ulg *)n))); + } + fclose(stream); + } + } + else { + /* Reading from stdin */ + if (n != NULL) { + *n = -1L; + } + } + + /* Return current time for all the times -- for now */ + time(<ime); + if (t != NULL) + t->atime = t->mtime = t->ctime = ltime; + + /* Set attributes (always a file) */ + if (a != NULL) + *a = 0; + + return unix2dostime(<ime); +} + + + +int set_extra_field(z, z_utim) +struct zlist far *z; +iztimes *z_utim; +/* create extra field and change z->att if desired */ +{ + fldata_t fdata; + FILE *stream; + char *eb_ptr; +#ifdef USE_EF_UT_TIME + extent ef_l_len = (EB_HEADSIZE+EB_UT_LEN(1)); +#else /* !USE_EF_UT_TIME */ + extent ef_l_len = 0; +#endif /* ?USE_EF_UT_TIME */ + int set_cmsmvs_eb = 0; + +/*translate_eol = 0;*/ + if (aflag == ASCII) { + z->att = ASCII; + } else { + if (bflag) + z->att = BINARY; + else + z->att = __EBCDIC; + ef_l_len += sizeof(fdata)+EB_HEADSIZE; + set_cmsmvs_eb = 1; + } + + if (ef_l_len > 0) { + z->extra = (char *)malloc(ef_l_len); + if (z->extra == NULL) { + printf("\nFLDATA : Unable to allocate memory !\n"); + return ZE_MEM; + } + z->cext = z->ext = ef_l_len; + eb_ptr = z->cextra = z->extra; + + if (set_cmsmvs_eb) { + if (bflag) +/*** stream = fopen(z->zname,"rb,type=record"); $RGH$ ***/ + stream = fopen(z->name,"rb"); + else + stream = fopen(z->name,"r"); + if (stream == NULL) { + printf("\nFLDATA : Could not open file : %s !\n",z->name); + printf("Error %d: '%s'\n", errno, strerror(errno)); + return ZE_NONE; + } + + fldata(stream,z->name,&fdata); + /*put the system ID */ +#ifdef VM_CMS + *(eb_ptr) = EF_VMCMS & 0xFF; + *(eb_ptr+1) = EF_VMCMS >> 8; +#else + *(eb_ptr) = EF_MVS & 0xFF; + *(eb_ptr+1) = EF_MVS >> 8; +#endif + *(eb_ptr+2) = sizeof(fdata) & 0xFF; + *(eb_ptr+3) = sizeof(fdata) >> 8; + + memcpy(eb_ptr+EB_HEADSIZE,&fdata,sizeof(fdata)); + fclose(stream); +#ifdef USE_EF_UT_TIME + eb_ptr += (sizeof(fdata)+EB_HEADSIZE); +#endif /* USE_EF_UT_TIME */ + } +#ifdef USE_EF_UT_TIME + eb_ptr[0] = 0x55; /* ascii[(unsigned)('U')] */ + eb_ptr[1] = 0x54; /* ascii[(unsigned)('T')] */ + eb_ptr[2] = EB_UT_LEN(1); /* length of data part of e.f. */ + eb_ptr[3] = 0; + eb_ptr[4] = EB_UT_FL_MTIME; + eb_ptr[5] = (char)(z_utim->mtime); + eb_ptr[6] = (char)(z_utim->mtime >> 8); + eb_ptr[7] = (char)(z_utim->mtime >> 16); + eb_ptr[8] = (char)(z_utim->mtime >> 24); +#endif /* USE_EF_UT_TIME */ + } + + return ZE_OK; +} + +int deletedir(d) +char *d; /* directory to delete */ +/* Delete the directory *d if it is empty, do nothing otherwise. + Return the result of rmdir(), delete(), or system(). + For VMS, d must be in format [x.y]z.dir;1 (not [x.y.z]). + */ +{ + return 0; +} + +#ifdef USE_ZIPMAIN +/* This function is called as main() to parse arguments */ +/* into argc and argv. This is required for stand-alone */ +/* execution. This calls the "real" main() when done. */ + +int main(void) + { + int argc=0; + char *argv[50]; + + int iArgLen; + char argstr[256]; + char **pEPLIST, *pCmdStart, *pArgStart, *pArgEnd; + + /* Get address of extended parameter list from S/370 Register 0 */ + pEPLIST = (char **)__xregs(0); + + /* Null-terminate the argument string */ + pCmdStart = *(pEPLIST+0); + pArgStart = *(pEPLIST+1); + pArgEnd = *(pEPLIST+2); + iArgLen = pArgEnd - pCmdStart + 1; + + /* Make a copy of the command string */ + memcpy(argstr, pCmdStart, iArgLen); + argstr[iArgLen] = '\0'; /* Null-terminate */ + + /* Store first token (cmd) */ + argv[argc++] = strtok(argstr, " "); + + /* Store the rest (args) */ + while (argv[argc-1]) + argv[argc++] = strtok(NULL, " "); + argc--; /* Back off last NULL entry */ + + /* Call "real" main() function */ + return zipmain(argc, argv); + +} +#endif /* USE_ZIPMAIN */ + +#endif /* !UTIL */ + + +/******************************/ +/* Function version_local() */ +/******************************/ + +void version_local() +{ + char liblvlmsg [50+1]; + char *compiler = "?"; + char *platform = "?"; + char complevel[64]; + + /* Map the runtime library level information */ + union { + unsigned int iVRM; + struct { + unsigned int pd:4; /* Product designation */ + unsigned int vv:4; /* Version */ + unsigned int rr:8; /* Release */ + unsigned int mm:16; /* Modification level */ + } xVRM; + } VRM; + + + /* Break down the runtime library level */ + VRM.iVRM = __librel(); + sprintf(liblvlmsg, "Using runtime library level %s V%dR%dM%d", + (VRM.xVRM.pd==1 ? "LE" : "CE"), + VRM.xVRM.vv, VRM.xVRM.rr, VRM.xVRM.mm); + /* Note: LE = Language Environment, CE = Common Env. (C/370). */ + /* This refers ONLY to the current runtimes, not the compiler. */ + + +#ifdef VM_CMS + platform = "VM/CMS"; + #ifdef __IBMC__ + compiler = "IBM C"; + #else + compiler = "C/370"; + #endif +#endif + +#ifdef MVS + platform = "MVS"; + #ifdef __IBMC__ + compiler = "IBM C/C++"; + #else + compiler = "C/370"; + #endif +#endif + +#ifdef __COMPILER_VER__ + VRM.iVRM = __COMPILER_VER__; + sprintf(complevel," V%dR%dM%d", + VRM.xVRM.vv, VRM.xVRM.rr, VRM.xVRM.mm); +#else +#ifdef __IBMC__ + sprintf(complevel," V%dR%d", __IBMC__ / 100, (__IBMC__ % 100)/10); +#else + complevel[0] = '\0'; +#endif +#endif + + + printf("Compiled with %s%s for %s%s%s.\n\n", + + /* Add compiler name and level */ + compiler, complevel, + + /* Add platform */ + platform, + + /* Add timestamp */ +#ifdef __DATE__ + " on " __DATE__ +#ifdef __TIME__ + " at " __TIME__ +#endif +#endif + ".\n", + liblvlmsg + ); +} /* end function version_local() */ diff --git a/cmsmvs/cmsmvs.h b/cmsmvs/cmsmvs.h new file mode 100644 index 0000000..e2adb31 --- /dev/null +++ b/cmsmvs/cmsmvs.h @@ -0,0 +1,123 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/* Include file for VM/CMS and MVS */ + +/* This is normally named osdep.h on most systems. Since CMS */ +/* generally doesn't support directories, it's been given a unique */ +/* name to avoid confusion. */ + + +#ifndef __cmsmvs_h /* prevent multiple inclusions */ +#define __cmsmvs_h + +#ifdef MVS +# define _POSIX_SOURCE /* tell MVS we want full definitions */ +# include +#endif /* MVS */ + +#include /* the usual non-BSD time functions */ +/* cstat.h is not required for MVS and actually gets in the way. Is it + * needed for CMS? + */ +#ifdef MVS +# include +# include +#else /* !MVS */ +# include "cstat.h" +#endif + + +/* Newer compiler version defines something for us */ +#if defined(__VM__) && !defined(VM_CMS) +# define VM_CMS +#endif + +#define CMS_MVS +#define EBCDIC + +#ifndef MVS /* MVS has perfectly good definitions for the following */ +# define NO_UNISTD_H +# define NO_FCNTL_H +#endif /*MVS */ + +/* If we're generating a stand-alone CMS module, patch in */ +/* a new main() function before the real main() for arg parsing. */ +#ifdef CMS_STAND_ALONE +# define USE_ZIPMAIN +#endif + +#ifndef NULL +# define NULL 0 +#endif + +#define PASSWD_FROM_STDIN + /* Kludge until we know how to open a non-echo tty channel */ + +/* definition for ZIP */ +#define getch() getc(stdin) +#define MAXPATHLEN 128 +#define NO_RMDIR +#define NO_MKTEMP +#define USE_CASE_MAP +#define isatty(t) 1 + +#ifndef MVS /* MVS has perfectly good definitions for the following */ +# define fileno(x) (char *)(x) +# define fdopen fopen +# define unlink remove +# define link rename +# define utime(f,t) +#endif /*MVS */ +#ifdef ZCRYPT_INTERNAL +# define ZCR_SEED2 (unsigned)3141592654L /* use PI as seed pattern */ +#endif + +#ifdef MVS +# if defined(__CRC32_C) +# pragma csect(STATIC,"crc32_s") +# elif defined(__DEFLATE_C) +# pragma csect(STATIC,"deflat_s") +# elif defined(__ZIPFILE_C) +# pragma csect(STATIC,"zipfil_s") +# elif defined(__ZIPUP_C) +# pragma csect(STATIC,"zipup_s") +# endif +#endif /* MVS */ + +/* end defines for ZIP */ + + + +#if 0 /*$RGH$*/ +/* RECFM=F, LRECL=1 works for sure */ +#define FOPR "rb,recfm=fb" +#define FOPM "r+" +#define FOPW "wb,recfm=fb,lrecl=1" +#define FOPWT "w" +#endif + +/* Try allowing ZIP files to be RECFM=V with "byteseek" for CMS, recfm=U for MVS */ +#define FOPR "rb,byteseek" +#define FOPM "r+,byteseek" +#ifdef MVS + #define FOPW "wb,recfm=u,byteseek" +#else /* !MVS */ + #define FOPW "wb,recfm=v,lrecl=32760,byteseek" +#endif /* MVS */ + +#if 0 +#define FOPW_TMP "w,byteseek" +#else +#define FOPW_TMP "w,type=memory(hiperspace)" +#endif + +#define CBSZ 0x40000 +#define ZBSZ 0x40000 + +#endif /* !__cmsmvs_h */ diff --git a/cmsmvs/cstat.h b/cmsmvs/cstat.h new file mode 100644 index 0000000..f02a5c3 --- /dev/null +++ b/cmsmvs/cstat.h @@ -0,0 +1,53 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/* cstat.h + + Definitions used for file status functions + +*/ + +#ifndef __STAT_H +#define __STAT_H + +#include + +#define S_IFMT 0xF000 /* file type mask */ +#define S_IFDIR 0x4000 /* directory */ +#define S_IFIFO 0x1000 /* FIFO special */ +#define S_IFCHR 0x2000 /* character special */ +#define S_IFBLK 0x3000 /* block special */ +#define S_IFREG 0x8000 /* or just 0x0000, regular */ +#define S_IREAD 0x0100 /* owner may read */ +#define S_IWRITE 0x0080 /* owner may write */ +#define S_IEXEC 0x0040 /* owner may execute */ + +struct stat +{ + short st_dev; /* Drive number of disk containing the */ + /* file or file handle if the file is */ + /* on device */ + short st_ino; /* Not meaningfull for VM/CMS */ + short st_mode; /* Bit mask giving information about */ + /* the file's mode */ + short st_nlink; /* Set to the integer constant 1 */ + int st_uid; /* Not meaningfull for VM/CMS */ + int st_gid; /* Not meaningfull for VM/CMS */ + short st_rdev; /* Same as st_dev */ + long st_size; /* Size of the file in bytes */ + long st_atime; /* Most recent access */ + long st_mtime; /* Same as st_atime */ + long st_ctime; /* Same as st_atime */ + FILE *fp; + char fname[FILENAME_MAX]; +}; + +int stat(const char *path, struct stat *sb); +int fstat(int fd, struct stat *sb); + +#endif /* __STAT_H */ diff --git a/cmsmvs/mc.exec b/cmsmvs/mc.exec new file mode 100644 index 0000000..ca22a18 --- /dev/null +++ b/cmsmvs/mc.exec @@ -0,0 +1,95 @@ +/* MAKECPIP EXEC Make program to build a C/370 module */ +/* Author: George Petrov, 29 Sep 1994 */ + +arg fn . '(' cparms /* Filter name */ +'pipe (end ?) < 'fn' makefile', /* get all source files from */ + '| frlab GLOBALS:'||, + '| drop', + '| strip', + '| var globals' +cparms = cparms globals +say '' +say 'Compile options : 'cparms +say '' +if pos('REB',cparms) > 0 then do +parse var cparms cp1 'REB' . ' ' cp2 /* REBuild options specified ? */ +cparms = cp1||cp2 +pipe1=, +'pipe (end ?) < 'fn' makefile', /* get all source files from */ + '| nfind *'||, /* the makefile and compile */ + '| frlab TEXT:'||, /* only the those who are */ + '| r: tolab MODULE:'||, /* changed or never compiled */ + '| drop', + '| o: fanout', + '| chop before str /(/', + '| statew', + '| c: fanout', /* compiled */ + '| specs /Compiling / 1 w1-3 n / .../ n', + '| cons' +end +else do +pipe1=, +'pipe (end ?) < 'fn' makefile', /* get all source files from */ + '| nfind *'||, /* the makefile and compile */ + '| frlab TEXT:'||, /* only the those who are */ + '| r: tolab MODULE:'||, /* changed or never compiled */ + '| drop', + '| o: fanout', + '| specs w1 1 /C/ nw w3 nw write w1 1 /TEXT A/ nw', + '| chop before str /(/', + '| statew', + '| change (57 66) / /0/', + '| sort 1.8 d', /* sort the date and time */ + '| uniq 1-17 singles', /* if the first is a source */ + '| sort 1.8 d 64.2 d 57.2 d 60.2 d 66.8 d', /* sort the date */ + '| uniq 1-8 first', /* if the first is a source */ + '| locate 9.8 /C /', /* program then it has to be */ + '| c: fanout', /* compiled */ + '| specs /Compiling / 1 w1-3 n / .../ n', + '| cons' +end +pipe2= '?', + 'r:', + '| drop', + '| specs w1 1', /* save the module name in var */ + '| var module', + '?', + 'o:', + '| specs w1 1', + '| join * / /', + '| var texts', /* save all the text file names */ + '?', /* for later include */ + 'c:', + '| specs /CC / 1 w1-3 n /(NOTERM 'cparms'/ nw', /* compile! */ + '| err: cms | cons', + '?', + 'err:', + '| strip both', + '| nfind 0'||, + '| var err', + '| specs /----> Errors found! RC=/ 1 1-* n', + '| cons' +/* '| g: gate'*/ +pipe1 pipe2 +say '' +if symbol('err') = 'VAR' & err ^= 0 then do + say 'Errors found in source files - link aborted! RC = 'err + exit err +end +say 'Generating module 'module +'pipe cms cmod' fn texts' DMSCSL | > 'fn' LINK A' +'set cmstype ht' +'state 'fn' LINK A' +rcc = rc +'set cmstype rt' +if rcc = 0 then do + say '' + say 'ERRORS discovered during linking!' + say 'See: 'fn' LINK A for more info' +end +exit rc +error: +say 'Error in REXX detected!' +Say 'Syntax error on line' Sigl':' Sourceline(Sigl) +Say 'Error was:' Errortext(RC) +return rc diff --git a/cmsmvs/mvs.c b/cmsmvs/mvs.c new file mode 100644 index 0000000..d7f7437 --- /dev/null +++ b/cmsmvs/mvs.c @@ -0,0 +1,221 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/* + * MVS specific things + */ +#include "zip.h" +#include "mvs.h" +#include + +static int gen_node( DIR *dirp, RECORD *recptr ) +{ + char *ptr, *name, ttr[TTRLEN]; + int skip, count = 2; + unsigned int info_byte, alias, ttrn; + struct dirent *new; + + ptr = recptr->rest; + while (count < recptr->count) { + if (!memcmp( ptr, endmark, NAMELEN )) + return 1; + name = ptr; /* member name */ + ptr += NAMELEN; + memcpy( ttr, ptr, TTRLEN ); /* ttr name */ + ptr += TTRLEN; + info_byte = (unsigned int) (*ptr); /* info byte */ + if ( !(info_byte & ALIAS_MASK) ) { /* no alias */ + new = malloc( sizeof(struct dirent) ); + if (dirp->D_list == NULL) + dirp->D_list = dirp->D_curpos = new; + else + dirp->D_curpos = (dirp->D_curpos->d_next = new); + new->d_next = NULL; + memcpy( new->d_name, name, NAMELEN ); + new->d_name[NAMELEN] = '\0'; + if ((name = strchr( new->d_name, ' ' )) != NULL) + *name = '\0'; /* skip trailing blanks */ + } + skip = (info_byte & SKIP_MASK) * 2 + 1; + ptr += skip; + count += (TTRLEN + NAMELEN + skip); + } + return 0; +} + +DIR *opendir(const char *dirname) +{ + int bytes, list_end = 0; + DIR *dirp; + FILE *fp; + RECORD rec; + + fp = fopen( dirname, "rb" ); + if (fp != NULL) { + dirp = malloc( sizeof(DIR) ); + if (dirp != NULL) { + dirp->D_list = dirp->D_curpos = NULL; + strcpy( dirp->D_path, dirname ); + do { + bytes = fread( &rec, 1, sizeof(rec), fp ); + if (bytes == sizeof(rec)) + list_end = gen_node( dirp, &rec ); + } while (!feof(fp) && !list_end); + fclose( fp ); + dirp->D_curpos = dirp->D_list; + return dirp; + } + fclose( fp ); + } + return NULL; +} + +struct dirent *readdir(DIR *dirp) +{ + struct dirent *cur; + + cur = dirp->D_curpos; + dirp->D_curpos = dirp->D_curpos->d_next; + return cur; +} + +void rewinddir(DIR *dirp) +{ + dirp->D_curpos = dirp->D_list; +} + +int closedir(DIR *dirp) +{ + struct dirent *node; + + while (dirp->D_list != NULL) { + node = dirp->D_list; + dirp->D_list = dirp->D_list->d_next; + free( node ); + } + free( dirp ); + return 0; +} + +local char *readd(d) +DIR *d; /* directory stream to read from */ +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e; + + e = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; +} + +int procname(n, caseflag) +char *n; /* name to process */ +int caseflag; /* true to force case-sensitive match */ +/* Process a name or sh expression to operate on (or exclude). Return + an error code in the ZE_ class. */ +{ + char *a; /* path and name for recursion */ + DIR *d; /* directory stream from opendir() */ + char *e; /* pointer to name from readd() */ + int m; /* matched flag */ + char *p; /* path for recursion */ + struct stat s; /* result of stat() */ + struct zlist far *z; /* steps through zfiles list */ + int exists; /* 1 if file exists */ + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0, caseflag); + else if (!(exists = (LSSTAT(n, &s) == 0))) + { +#ifdef MVS + /* special case for MVS. stat does not work on non-HFS files so if + * stat fails with ENOENT, try to open the file for reading anyway. + * If the user has no OMVS segment, stat gets an initialization error, + * even on external files. + */ + if (errno == ENOENT || errno == EMVSINITIAL) { + FILE *f = fopen(n, "r"); + if (f) { + /* stat got ENOENT but fopen worked, external file */ + fclose(f); + exists = 1; + memset(&s, '\0', sizeof(s)); /* stat data is unreliable for externals */ + s.st_mode = S_IFREG; /* fudge it */ + } + } +#endif /* MVS */ + } + if (! exists) { + /* Not a file or directory--search for shell expression in zip file */ + p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */ + m = 1; + for (z = zfiles; z != NULL; z = z->nxt) { + if (MATCH(p, z->iname, caseflag)) + { + z->mark = pcount ? filter(z->zname, caseflag) : 1; + if (verbose) + fprintf(mesg, "zip diagnostic: %scluding %s\n", + z->mark ? "in" : "ex", z->name); + m = 0; + } + } + free((zvoid *)p); + return m ? ZE_MISS : ZE_OK; + } + + /* Live name--use if file, recurse if directory */ + if (!S_ISDIR(s.st_mode)) + { + /* add or remove name of file */ + if ((m = newname(n, 0, caseflag)) != ZE_OK) + return m; + } else { + /* Add trailing / to the directory name */ + if ((p = malloc(strlen(n)+2)) == NULL) + return ZE_MEM; + if (strcmp(n, ".") == 0) { + *p = '\0'; /* avoid "./" prefix and do not create zip entry */ + } else { + strcpy(p, n); + a = p + strlen(p); + if (a[-1] != '/') + strcpy(a, "/"); + if (dirnames && (m = newname(p, 1, caseflag)) != ZE_OK) { + free((zvoid *)p); + return m; + } + } + /* recurse into directory */ + if (recurse && (d = opendir(n)) != NULL) + { + while ((e = readd(d)) != NULL) { + if (strcmp(e, ".") && strcmp(e, "..")) + { + if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL) + { + closedir(d); + free((zvoid *)p); + return ZE_MEM; + } + strcat(strcpy(a, p), e); + if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */ + { + if (m == ZE_MISS) + zipwarn("name not matched: ", a); + else + ziperr(m, a); + } + free((zvoid *)a); + } + } + closedir(d); + } + free((zvoid *)p); + } /* (s.st_mode & S_IFDIR) == 0) */ + return ZE_OK; +} diff --git a/cmsmvs/mvs.h b/cmsmvs/mvs.h new file mode 100644 index 0000000..b2f9760 --- /dev/null +++ b/cmsmvs/mvs.h @@ -0,0 +1,40 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/* definitions */ + +#define NAMELEN 8 + +struct dirent { + struct dirent *d_next; + char d_name[NAMELEN+1]; +}; + +typedef struct _DIR { + struct dirent *D_list; + struct dirent *D_curpos; + char D_path[FILENAME_MAX]; +} DIR; + +DIR * opendir(const char *dirname); +struct dirent *readdir(DIR *dirp); +void rewinddir(DIR *dirp); +int closedir(DIR *dirp); +char * readd(DIR *dirp); + +#define ALIAS_MASK (unsigned int) 0x80 +#define SKIP_MASK (unsigned int) 0x1F +#define TTRLEN 3 +#define RECLEN 254 + +typedef _Packed struct { + unsigned short int count; + char rest[RECLEN]; +} RECORD; + +char *endmark = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; diff --git a/cmsmvs/mvs.mki b/cmsmvs/mvs.mki new file mode 100644 index 0000000..316d064 --- /dev/null +++ b/cmsmvs/mvs.mki @@ -0,0 +1,125 @@ +# Makefile for the MVS (OS/390 Base) version of ZIP 2.3 +# Produced for C/C++ V3R2 in OS/390 1.2.0 by Ian E. Gorman, 2 Nov 1998 +# Facilities for compiling and testing were made available by +# OmniMark Technologies Corporation, Ottawa, Canada + +# NOTES +# +# The only tabs in this file are in the first character of each recipe +# line, where they are required by make. +# +# Run this makefile in OpenMVS (OS/390 POSIX) using source files in the +# HFS file system. You can write the load module to either HFS file +# system or to a PDS in the native MVS file system. The PDS must have +# sufficient free space to hold the load module. +# +# To compile to a member of a PDS: +# make +# or +# make zip.mvs +# +# To compile a test version into the HFS file system: +# make hfs + +# ZIP options -- MVS, REENTRANT +ZIPOPTS=-DMVS -DREENTRANT + +# directories + +# generic source code +SRC=.. +SRC_P=$(SRC)/ + +# source code for MVS +CMSMVS=../cmsmvs +CMSMVS_P=$(CMSMVS)/ + +# include files +INCLS=-I$(SRC) -I$(CMSMVS) + +# object files and load modules +BLD_P=../mvs/ + +# Other options + +# Suffixes (E and O must be different) +E= +O=.o + +# Need EXTENDED features for global.c and vmvms.c, so not using c89 +CC=cc +CFLAGS=-D_OPEN_SYS $(ZIPOPTS) $(INCLS) + +LD=cc +LDFLAGS= + +# Files + +# object (TEXT) files +OBJECTS= $(BLD_P)zip$(O) $(BLD_P)trees$(O) \ + $(BLD_P)crypt$(O) $(BLD_P)ttyio$(O) $(BLD_P)deflate$(O) \ + $(BLD_P)fileio$(O) $(BLD_P)globals$(O) $(BLD_P)util$(O) \ + $(BLD_P)crc32$(O) $(BLD_P)zipfile$(O) \ + $(BLD_P)zipup$(O) $(BLD_P)cmsmvs$(O) $(BLD_P)mvs$(O) + +# Header files +HFILES= $(SRC_P)api.h $(SRC_P)crc32.h $(SRC_P)crypt.h $(SRC_P)ebcdic.h \ + $(SRC_P)revision.h $(SRC_P)tailor.h $(SRC_P)ttyio.h \ + $(SRC_P)zip.h $(SRC_P)ziperr.h $(CMSMVS_P)cmsmvs.h \ + $(CMSMVS_P)cstat.h $(CMSMVS_P)mvs.h $(CMSMVS_P)zipup.h + +# Rules + +all: $(BLD_P)zip.mvs$(E) +hfs: $(BLD_P)zip$(E) + +# link + +$(BLD_P)zip.mvs$(E): $(OBJECTS) + $(LD) -o "//INFOZIP.LOAD(ZIP)" $(LDFLAGS) $^ + echo "tso call \"infozip(zip)\" \"'\"\"""$$""@""\"\"'\"" > $% + chmod a+x $% + +$(BLD_P)zip$(E): $(OBJECTS) + $(LD) -o $% $(LDFLAGS) $^ + +# compile + +$(BLD_P)trees$(O): $(SRC_P)trees.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)trees.c + +$(BLD_P)crypt$(O): $(SRC_P)crypt.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)crypt.c + +$(BLD_P)ttyio$(O): $(SRC_P)ttyio.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)ttyio.c + +$(BLD_P)deflate$(O): $(SRC_P)deflate.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)deflate.c + +$(BLD_P)fileio$(O): $(SRC_P)fileio.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)fileio.c + +$(BLD_P)globals$(O): $(SRC_P)globals.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)globals.c + +$(BLD_P)zip$(O): $(SRC_P)zip.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)zip.c + +$(BLD_P)util$(O): $(SRC_P)util.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)util.c + +$(BLD_P)crc32$(O): $(SRC_P)crc32.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)crc32.c + +$(BLD_P)zipfile$(O): $(SRC_P)zipfile.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)zipfile.c + +$(BLD_P)zipup$(O): $(SRC_P)zipup.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(SRC_P)zipup.c + +$(BLD_P)cmsmvs$(O): $(CMSMVS_P)cmsmvs.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(CMSMVS_P)cmsmvs.c + +$(BLD_P)mvs$(O): $(CMSMVS_P)mvs.c $(HFILES) + $(CC) -c -o $% $(CFLAGS) $(CMSMVS_P)mvs.c diff --git a/cmsmvs/pipzip.rexx b/cmsmvs/pipzip.rexx new file mode 100644 index 0000000..4249ded --- /dev/null +++ b/cmsmvs/pipzip.rexx @@ -0,0 +1,27 @@ +/* PIPZIP REXX Rexx filter to use ZIP */ +/* Author : George Petrov, 8 May 1995 */ + +parse arg opts +'callpipe *:', + '| specs w1 1 /./ n w2 n', + '| join * / /', + '| specs /zip 'opts'/ 1 1-* nw', + '| cms', + '| *:' + +exit rc + + + + + + + + + + + + + + + diff --git a/cmsmvs/zip.exec b/cmsmvs/zip.exec new file mode 100644 index 0000000..0b9de97 --- /dev/null +++ b/cmsmvs/zip.exec @@ -0,0 +1,66 @@ +/***********************************************************************/ +/* */ +/* Front-end EXEC to set up linkage to the C runtime libraries */ +/* before executing a MODULE generated from C code. */ +/* */ +/* Copy this file as an EXEC with a filename matching the C MODULE. */ +/* */ +/* Greg Hartwig (ghartwig@vnet.ibm.com) 7/31/97, 4/24/98. */ +/* */ +/***********************************************************************/ +Address Command +Parse Arg argstring +Parse Source . . myname . + +/* Set output and input character translation so brackets show up */ +'SET OUTPUT AD' 'BA'x +'SET OUTPUT BD' 'BB'x +'SET INPUT BA AD' +'SET INPUT BB BD' + +Call CLIB +If rc<>0 Then Do + Say 'The required C runtime libraries don''t appear to be available.' + Say myname 'can not run.' + Exit 12 +End + +/* Run the command */ +myname argstring +Exit rc + + + + +/* Contents of the CLIB EXEC, modified for RC checking. */ +/* Removed TXTLIB setting. Only LOADLIB needed for execution. */ +CLIB: +/***************************************************/ +/* SET UP LIBRARIES FOR LE for MVS & VM */ +/***************************************************/ +Address COMMAND + +loadlib ='EDCLINK' /* C/370 runtime */ +loadlib ='SCEERUN' /* LE runtime */ + + +theirs=queued() /* old stack contentsM068*/ + 'QUERY LOADLIB ( LIFO' /* old setting M068*/ + LoadlibList='' /* init list M068*/ +rc=0 + Do while queued()^=theirs /* all lines from cmdM068*/ + Parse upper pull 'LOADLIB' '=' Ltemp /* get one line M068*/ + LoadlibList= Ltemp Loadliblist /* was stacked LIFO M068*/ + End /*M068*/ + If loadlibList='NONE' , + Then Do + 'GLOBAL LOADLIB' Loadlib /* enforce what we need */ + End + Else Do + Do xx=1 to Words(loadlib) + If Find(loadliblist,word(loadlib,xx)) = 0 , + then loadliblist = loadliblist word(loadlib,xx) + End + 'GLOBAL LOADLIB' loadliblist /* enforce what we need */ + End +Return diff --git a/cmsmvs/zip.makefile b/cmsmvs/zip.makefile new file mode 100644 index 0000000..85bef22 --- /dev/null +++ b/cmsmvs/zip.makefile @@ -0,0 +1,21 @@ +* This is a comment +* this makefile compiles filter ZIPME + +GLOBALS: + long def(VM_CMS) +TEXT: + trees c + crypt c + ttyio c + deflate c + fileio c + globals c + zip c + util c + crc32.c + zipfile c + zipup c + cmsmvs c + cms c +MODULE: + zip module diff --git a/cmsmvs/zipcloak.exec b/cmsmvs/zipcloak.exec new file mode 100644 index 0000000..0b9de97 --- /dev/null +++ b/cmsmvs/zipcloak.exec @@ -0,0 +1,66 @@ +/***********************************************************************/ +/* */ +/* Front-end EXEC to set up linkage to the C runtime libraries */ +/* before executing a MODULE generated from C code. */ +/* */ +/* Copy this file as an EXEC with a filename matching the C MODULE. */ +/* */ +/* Greg Hartwig (ghartwig@vnet.ibm.com) 7/31/97, 4/24/98. */ +/* */ +/***********************************************************************/ +Address Command +Parse Arg argstring +Parse Source . . myname . + +/* Set output and input character translation so brackets show up */ +'SET OUTPUT AD' 'BA'x +'SET OUTPUT BD' 'BB'x +'SET INPUT BA AD' +'SET INPUT BB BD' + +Call CLIB +If rc<>0 Then Do + Say 'The required C runtime libraries don''t appear to be available.' + Say myname 'can not run.' + Exit 12 +End + +/* Run the command */ +myname argstring +Exit rc + + + + +/* Contents of the CLIB EXEC, modified for RC checking. */ +/* Removed TXTLIB setting. Only LOADLIB needed for execution. */ +CLIB: +/***************************************************/ +/* SET UP LIBRARIES FOR LE for MVS & VM */ +/***************************************************/ +Address COMMAND + +loadlib ='EDCLINK' /* C/370 runtime */ +loadlib ='SCEERUN' /* LE runtime */ + + +theirs=queued() /* old stack contentsM068*/ + 'QUERY LOADLIB ( LIFO' /* old setting M068*/ + LoadlibList='' /* init list M068*/ +rc=0 + Do while queued()^=theirs /* all lines from cmdM068*/ + Parse upper pull 'LOADLIB' '=' Ltemp /* get one line M068*/ + LoadlibList= Ltemp Loadliblist /* was stacked LIFO M068*/ + End /*M068*/ + If loadlibList='NONE' , + Then Do + 'GLOBAL LOADLIB' Loadlib /* enforce what we need */ + End + Else Do + Do xx=1 to Words(loadlib) + If Find(loadliblist,word(loadlib,xx)) = 0 , + then loadliblist = loadliblist word(loadlib,xx) + End + 'GLOBAL LOADLIB' loadliblist /* enforce what we need */ + End +Return diff --git a/cmsmvs/zipmvsc.job b/cmsmvs/zipmvsc.job new file mode 100644 index 0000000..3c786d7 --- /dev/null +++ b/cmsmvs/zipmvsc.job @@ -0,0 +1,89 @@ +//CCZIP JOB (BI09255), +// MSGLEVEL=(1,1),MSGCLASS=C,CLASS=D,NOTIFY=C888090 +//PROCLIB JCLLIB ORDER=(SYS1.C370.PROCLIB.M24) +//ZIP EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(ZIP)', +// OUTFILE='C888090.ZIP.C.OBJ(ZIP),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//CRYPT EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(CRYPT)', +// OUTFILE='C888090.ZIP.C.OBJ(CRYPT),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//TTYIO EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(TTYIO)', +// OUTFILE='C888090.ZIP.C.OBJ(TTYIO),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//TREES EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(TREES)', +// OUTFILE='C888090.ZIP.C.OBJ(TREES),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//DEFLATE EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(DEFLATE)', +// OUTFILE='C888090.ZIP.C.OBJ(DEFLATE),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//FILEIO EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(FILEIO)', +// OUTFILE='C888090.ZIP.C.OBJ(FILEIO),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//GLOBALS EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(GLOBALS)', +// OUTFILE='C888090.ZIP.C.OBJ(GLOBALS),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//UTIL EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(UTIL)', +// OUTFILE='C888090.ZIP.C.OBJ(UTIL),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//CRC32 EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(CRC32)', +// OUTFILE='C888090.ZIP.C.OBJ(CRC32),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//ZIPFILE EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(ZIPFILE)', +// OUTFILE='C888090.ZIP.C.OBJ(ZIPFILE),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//ZIPUP EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(ZIPUP)', +// OUTFILE='C888090.ZIP.C.OBJ(ZIPUP),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//CMSMVS EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(CMSMVS)', +// OUTFILE='C888090.ZIP.C.OBJ(CMSMVS),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//MVS EXEC EDCC,COND=(12,LE),CREGSIZ='4M', +// INFILE='C888090.ZIP.C(MVS)', +// OUTFILE='C888090.ZIP.C.OBJ(MVS),DISP=SHR', +// CPARM='LONG,NOTERM,LIST,XREF,SOURCE,OPT(2),DEF(MVS)' +//COMPILE.USERLIB DD DSN=C888090.ZIP.H,DISP=SHR +//PLINK EXEC PROC=EDCPL,COND=(12,LE), +// OUTFILE='C888090.ZIP.LOAD(ZIP),DISP=SHR', +// PPARM='NONCAL,MAP', +// LPARM='LIST,MAP,XREF' +//SYSPRINT DD SYSOUT=* +//PLKED.SYSIN DD DSN=C888090.ZIP.C.OBJ(ZIP),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(BITS),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(CRYPT),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(TREES),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(DEFLATE),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(FILEIO),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(GLOBALS),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(UTIL),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(CRC32),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(ZIPFILE),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(ZIPUP),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(CMSMVS),DISP=SHR +// DD DSN=C888090.ZIP.C.OBJ(MVS),DISP=SHR +//PLKED.SYSLIB DD DSN=SYS1.C370.SEDCBASE,DISP=SHR +// DD DSN=SYS1.PL1.SIBMBASE,DISP=SHR +//SYSUT1 DD UNIT=SYSDA,SPACE=(CYL,(2,2)),DISP=NEW diff --git a/cmsmvs/zipname.conven b/cmsmvs/zipname.conven new file mode 100644 index 0000000..e17fe9c --- /dev/null +++ b/cmsmvs/zipname.conven @@ -0,0 +1,200 @@ + + Zip file/directories name convention under MVS + --------------------------------------------------- + Draft 1.1 + + +1. Translating native file names to Zip filenames. + +1.1 Zipping a PDS + +On MVS there are directories called PDS (Partition Data Set) which have +the following format : name1.name2.name3(mname) +for example: myuserid.unzip.c(unzip) + +So as you see the path delimiter is '.'. Each dir name can be max 8 +chars long beginning with a number. + +Between '(' and ')' there is the so called member name - it is also 8 +chars long. This is the actual file name. + + +1.1.1 Converting MVS PDS name to zip path/filename (status: not implemented) + +The PDS name is converted to zippath as follows: +in the zip : name1/name2/mname.name3 +becomes on MVS: name1.name2.name3(mname) + + +1.2 Unzipping as PDS (status: implemented) + +When you unzip the file name myuserid/unzip/unzip.c the same process +is done backwards, so you get : myuserid.unzip.c(unzip) + +Notice that the file extension is used as last dirname! + + +1.2 Unzipping to a different PDS (status: implemented) + +You can also use -d option while unzipping for example: +unzip mytest myuserid/unzip/unzip.c -dnewdest.test + +then the new name will become: +newdest.test.myuserid.unzip.c(unzip) + + Second example: + +unzip mytest myuserid/unzip/*.c -dnewdest.test + +then you get a PDS: +newdest.test.myuserid.unzip.c(...) + +with all *.c files in it. + + +1.3 Zipping a Sequential Dataset (status: not implemented) + + Sequential dataset is a dataset with NO members. +Such a dataset is translated from native MVS to zip format by replacing +the '.' (points) with '/' (backslash). + +Example: +on MVS: name1.name2.name3 +becomes in the zip : name1/name2/name3 + +NOTE : The new filename in the zip has NO extension this way it can be + recognised as a Sequential dataset and not a PDS. + But this also means that all files in the zip archive that have + no extension will be unzipped as Sequential datasets! + + +1.4 Using a DDNAMES for input. (status: not implemented) + +To use DDNAMES as input file names put a 'dd:' before the ddname: +example: zip myzip dd:name1 dd:name2 dd:sales + +In the Zip archive the ddnames are saved as name.DDNAME so if you try +the example above you will get in your zip file (when listing it) : + +..size .. date time .. crc .. NAME1.DDNAME +..size .. date time .. crc .. NAME2.DDNAME +..size .. date time .. crc .. SALES.DDNAME + + +1.4 Using a DDNAMES as zip name (status: implemented) + +It is allowed to use a DDNAME as zipfile, just put dd: before it +example: unzip dd:myzip *.c + this will unzip all .c files from ddname myzip + +example2: ZIP DD:MYZIP DD:MANE1 MYSOURCE.C MYDOC.TEXT(ZIPPING) + this will zip ddname name1 file mysource.c and PDS mydoc.text(zipping) + into as a zip file in the ddname myzip + + +2. Converting longer path names (unix like) (status: not implemented) + to native MVS names. + +When in the zip archive there are dirnames longer that 8 chars they are +chopped at the 8 position. For example + MyLongZippath/WithLongFileName.text +is translated to: + MYLONGZI.TEXT(WITHLONG) + +Notice that all chars are converted to uppercase. + + +2.1 Using special characters (status: implemented) + +Also all '_' (underscore), '+' (plus), '-' (minus), '(' and ')' +from the file name/path in the zip archive are skipped because they +are not valid in the MVS filenames. + + +2.2 Numeric file names (status: not implemented) + +On MVS no name can begin with a number, so when a dir/file name begins with +one, a leading letter 'N' is inserted. For example: + Contents.512 +becomes: + CONTENTS.N512 + + + + + Zip file/directories name convention under VM/CMS + --------------------------------------------------- + +1. Translating native file names to Zip filenames. + +On VM/CMS (not ESA ) there are NO directories so you got only disks +and files. + +The file names are delimited with spaces. But for use with unzip/zip +you have to use '.' points as delimiters. + +For example on your A disk you have file called PROFILE EXEC +if you want to zip it type : zip myzip profile.exec + +If the same file is on your F disk you have to type: +zip myzip profile.exec.f + +So as you can see the general format is fname.ftype.fmode + +In the zipfile the disk from which the file comes is not saved! +So only the fname.ftype is saved. + +If you unzip and you want to give a different destination disk just use +the -d option like: + + unzip mytest *.c -df + +This will unzip all *.c files to your F disk. + + +2. Converting longer path names (unix like) to native VM/CMS names. + +When in the zip archive there are dirnames longer that 8 chars they are +chopped at the 8 position. Also the path is removed. For example + Zippath/WithLongFileName.text +is translated to: + WITHLONG.TEXT + +Notice that all chars are converted to uppercase. + +Also all '+' (plus), '-' (minus), '(' and ')' +from the file name/path in the zip archive are skipped because they +are not valid in the VM/CMS filenames. + +If there is no extension for the file name in the zip archive, unzip +will add .NONAME for example: + mypath/dir1/testfile +becomes: + TESTFILE.NONAME + +3. Future? + +There is also discussion for a new option on ZIP that you can give +a virtual directory to be added before each file name that is zipped. + +For example you want to zip a few .c file and put them in the zip +structure under the directory 'mydir/test', but you can't create dirs on +VM/CMS so you have to the something like: + +ZIP myzip file1.c file2.c -dmydir/test + +and you get in the zip archive files: + + mydir/test/file1.c + mydir/test/file2.c + +------------------------------------------------------------------------- + + +NOTE: Not all of those functions are implemented in the first beta + release of VM/MVS UNZIP/ZIP. + +Every ideas/corrections/bugs will be appreciated. +Mail to maillist: Info-ZIP@LISTS.WKU.EDU + +George Petrov diff --git a/cmsmvs/zipnote.exec b/cmsmvs/zipnote.exec new file mode 100644 index 0000000..0b9de97 --- /dev/null +++ b/cmsmvs/zipnote.exec @@ -0,0 +1,66 @@ +/***********************************************************************/ +/* */ +/* Front-end EXEC to set up linkage to the C runtime libraries */ +/* before executing a MODULE generated from C code. */ +/* */ +/* Copy this file as an EXEC with a filename matching the C MODULE. */ +/* */ +/* Greg Hartwig (ghartwig@vnet.ibm.com) 7/31/97, 4/24/98. */ +/* */ +/***********************************************************************/ +Address Command +Parse Arg argstring +Parse Source . . myname . + +/* Set output and input character translation so brackets show up */ +'SET OUTPUT AD' 'BA'x +'SET OUTPUT BD' 'BB'x +'SET INPUT BA AD' +'SET INPUT BB BD' + +Call CLIB +If rc<>0 Then Do + Say 'The required C runtime libraries don''t appear to be available.' + Say myname 'can not run.' + Exit 12 +End + +/* Run the command */ +myname argstring +Exit rc + + + + +/* Contents of the CLIB EXEC, modified for RC checking. */ +/* Removed TXTLIB setting. Only LOADLIB needed for execution. */ +CLIB: +/***************************************************/ +/* SET UP LIBRARIES FOR LE for MVS & VM */ +/***************************************************/ +Address COMMAND + +loadlib ='EDCLINK' /* C/370 runtime */ +loadlib ='SCEERUN' /* LE runtime */ + + +theirs=queued() /* old stack contentsM068*/ + 'QUERY LOADLIB ( LIFO' /* old setting M068*/ + LoadlibList='' /* init list M068*/ +rc=0 + Do while queued()^=theirs /* all lines from cmdM068*/ + Parse upper pull 'LOADLIB' '=' Ltemp /* get one line M068*/ + LoadlibList= Ltemp Loadliblist /* was stacked LIFO M068*/ + End /*M068*/ + If loadlibList='NONE' , + Then Do + 'GLOBAL LOADLIB' Loadlib /* enforce what we need */ + End + Else Do + Do xx=1 to Words(loadlib) + If Find(loadliblist,word(loadlib,xx)) = 0 , + then loadliblist = loadliblist word(loadlib,xx) + End + 'GLOBAL LOADLIB' loadliblist /* enforce what we need */ + End +Return diff --git a/cmsmvs/zipsplit.exec b/cmsmvs/zipsplit.exec new file mode 100644 index 0000000..0b9de97 --- /dev/null +++ b/cmsmvs/zipsplit.exec @@ -0,0 +1,66 @@ +/***********************************************************************/ +/* */ +/* Front-end EXEC to set up linkage to the C runtime libraries */ +/* before executing a MODULE generated from C code. */ +/* */ +/* Copy this file as an EXEC with a filename matching the C MODULE. */ +/* */ +/* Greg Hartwig (ghartwig@vnet.ibm.com) 7/31/97, 4/24/98. */ +/* */ +/***********************************************************************/ +Address Command +Parse Arg argstring +Parse Source . . myname . + +/* Set output and input character translation so brackets show up */ +'SET OUTPUT AD' 'BA'x +'SET OUTPUT BD' 'BB'x +'SET INPUT BA AD' +'SET INPUT BB BD' + +Call CLIB +If rc<>0 Then Do + Say 'The required C runtime libraries don''t appear to be available.' + Say myname 'can not run.' + Exit 12 +End + +/* Run the command */ +myname argstring +Exit rc + + + + +/* Contents of the CLIB EXEC, modified for RC checking. */ +/* Removed TXTLIB setting. Only LOADLIB needed for execution. */ +CLIB: +/***************************************************/ +/* SET UP LIBRARIES FOR LE for MVS & VM */ +/***************************************************/ +Address COMMAND + +loadlib ='EDCLINK' /* C/370 runtime */ +loadlib ='SCEERUN' /* LE runtime */ + + +theirs=queued() /* old stack contentsM068*/ + 'QUERY LOADLIB ( LIFO' /* old setting M068*/ + LoadlibList='' /* init list M068*/ +rc=0 + Do while queued()^=theirs /* all lines from cmdM068*/ + Parse upper pull 'LOADLIB' '=' Ltemp /* get one line M068*/ + LoadlibList= Ltemp Loadliblist /* was stacked LIFO M068*/ + End /*M068*/ + If loadlibList='NONE' , + Then Do + 'GLOBAL LOADLIB' Loadlib /* enforce what we need */ + End + Else Do + Do xx=1 to Words(loadlib) + If Find(loadliblist,word(loadlib,xx)) = 0 , + then loadliblist = loadliblist word(loadlib,xx) + End + 'GLOBAL LOADLIB' loadliblist /* enforce what we need */ + End +Return diff --git a/cmsmvs/zipup.h b/cmsmvs/zipup.h new file mode 100644 index 0000000..0ea8962 --- /dev/null +++ b/cmsmvs/zipup.h @@ -0,0 +1,18 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#define fhow "r,byteseek" +#define fhowb "rb,byteseek" + +#define fbad NULL +typedef FILE *ftype; +#define zopen(n,p) (ftype)fopen((n),(p)) +#define zread(f,b,n) fread((b),1,(n),(FILE*)(f)) +#define zclose(f) fclose((FILE*)(f)) +#define zerr(f) ferror((FILE*)(f)) +#define zstdin stdin diff --git a/cmsmvs/zipvmc.exec b/cmsmvs/zipvmc.exec new file mode 100644 index 0000000..3fdd800 --- /dev/null +++ b/cmsmvs/zipvmc.exec @@ -0,0 +1,48 @@ +/* VMCOMPIL EXEC Unzip compile for VM/CMS */ +/* Author : George Petrov, 11 Apr 1995 */ + +signal on error + +parms = '(long def(VM_CMS)' + +/* Add local parms */ +parms = parms 'TARGET(COMPAT) SOURCE' + + +say 'Compiling TREES C...' +'cc trees c 'parms +say 'Compiling CRYPT C...' +'cc crypt c 'parms +say 'Compiling TTYIO C...' +'cc ttyio c 'parms +say 'Compiling DEFLATE C...' +'cc deflate c 'parms +say 'Compiling FILEIO C...' +'cc fileio c 'parms +say 'Compiling GLOBALS C...' +'cc globals c 'parms +say 'Compiling ZIP C...' +'cc zip c 'parms +say 'Compiling UTIL C...' +'cc util c 'parms +say 'Compiling CRC32 C...' +'cc crc32 c 'parms +say 'Compiling ZIPFILE C...' +'cc zipfile c 'parms +say 'Compiling ZIPUP C...' +'cc zipup c 'parms +say 'Compiling CMSMVS C...' +'cc cmsmvs c 'parms +say 'Compiling CMS C...' +'cc cms c 'parms + +say 'Linking all files...' +'cmod zip zip trees crypt deflate fileio globals ttyio', + 'util crc32 zipfile zipup cmsmvs cms' +say 'All Done!' +say "To run enter : ZIP parms" +exit rc + +error: +say 'Error durring compilation!' +exit rc diff --git a/crc32.c b/crc32.c new file mode 100644 index 0000000..6b2403b --- /dev/null +++ b/crc32.c @@ -0,0 +1,732 @@ +/* + Copyright (c) 1990-2008 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results about a factor + * of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* $Id: crc32.c,v 2.0 2007/01/07 05:20:36 spc Exp $ */ + +#define __CRC32_C /* identifies this source module */ + +#include "zip.h" + +#if (!defined(USE_ZLIB) || defined(USE_OWN_CRCTAB)) + +#ifndef ZCONST +# define ZCONST const +#endif + +#include "crc32.h" + +/* When only the table of precomputed CRC values is needed, only the basic + system-independent table containing 256 entries is created; any support + for "unfolding" optimization is disabled. + */ +#if (defined(USE_ZLIB) || defined(CRC_TABLE_ONLY)) +# ifdef IZ_CRCOPTIM_UNFOLDTBL +# undef IZ_CRCOPTIM_UNFOLDTBL +# endif +#endif /* (USE_ZLIB || CRC_TABLE_ONLY) */ + +#if defined(IZ_CRCOPTIM_UNFOLDTBL) +# define CRC_TBLS 4 +#else +# define CRC_TBLS 1 +#endif + + +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first (or only) table is simply the CRC of all possible eight bit values. + This is all the information needed to generate CRC's on data a byte-at-a-time + for all combinations of CRC register values and incoming bytes. + The remaining 3 tables (if IZ_CRCOPTIM_UNFOLDTBL is enabled) allow for + word-at-a-time CRC calculation, where a word is four bytes. +*/ + +#ifdef DYNAMIC_CRC_TABLE + +/* ========================================================================= + * Make the crc table. This function is needed only if you want to compute + * the table dynamically. + */ + +local void make_crc_table OF((void)); + +#if (defined(DYNALLOC_CRCTAB) && defined(REENTRANT)) + error: Dynamic allocation of CRC table not safe with reentrant code. +#endif /* DYNALLOC_CRCTAB && REENTRANT */ + +#ifdef DYNALLOC_CRCTAB + local ulg near *crc_table = NULL; +# if 0 /* not used, since sizeof("near *") <= sizeof(int) */ + /* Use this section when access to a "local int" is faster than access to + a "local pointer" (e.g.: i86 16bit code with far pointers). */ + local int crc_table_empty = 1; +# define CRC_TABLE_IS_EMPTY (crc_table_empty != 0) +# define MARK_CRCTAB_FILLED crc_table_empty = 0 +# define MARK_CRCTAB_EMPTY crc_table_empty = 1 +# else + /* Use this section on systems where the size of pointers and ints is + equal (e.g.: all 32bit systems). */ +# define CRC_TABLE_IS_EMPTY (crc_table == NULL) +# define MARK_CRCTAB_FILLED crc_table = crctab_p +# define MARK_CRCTAB_EMPTY crc_table = NULL +# endif +#else /* !DYNALLOC_CRCTAB */ + local ulg near crc_table[CRC_TBLS*256]; + local int crc_table_empty = 1; +# define CRC_TABLE_IS_EMPTY (crc_table_empty != 0) +# define MARK_CRCTAB_FILLED crc_table_empty = 0 +#endif /* ?DYNALLOC_CRCTAB */ + + +local void make_crc_table() +{ + ulg c; /* crc shift register */ + int n; /* counter for all possible eight bit values */ + int k; /* byte being shifted into crc apparatus */ +#ifdef DYNALLOC_CRCTAB + ulg near *crctab_p; /* temporary pointer to allocated crc_table area */ +#else /* !DYNALLOC_CRCTAB */ +# define crctab_p crc_table +#endif /* DYNALLOC_CRCTAB */ + +#ifdef COMPUTE_XOR_PATTERN + /* This piece of code has been left here to explain how the XOR pattern + * used in the creation of the crc_table values can be recomputed. + * For production versions of this function, it is more efficient to + * supply the resultant pattern at compile time. + */ + ulg xor; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static ZCONST uch p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* make exclusive-or pattern from polynomial (0xedb88320L) */ + xor = 0L; + for (n = 0; n < sizeof(p)/sizeof(uch); n++) + xor |= 1L << (31 - p[n]); +#else +# define xor 0xedb88320L +#endif + +#ifdef DYNALLOC_CRCTAB + crctab_p = (ulg near *) nearmalloc (CRC_TBLS*256*sizeof(ulg)); + if (crctab_p == NULL) { + ziperr(ZE_MEM, "crc_table allocation"); + } +#endif /* DYNALLOC_CRCTAB */ + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (ulg)n; + for (k = 8; k; k--) + c = c & 1 ? xor ^ (c >> 1) : c >> 1; + crctab_p[n] = REV_BE(c); + } + +#ifdef IZ_CRCOPTIM_UNFOLDTBL + /* generate crc for each value followed by one, two, and three zeros */ + for (n = 0; n < 256; n++) { + c = crctab_p[n]; + for (k = 1; k < 4; k++) { + c = CRC32(c, 0, crctab_p); + crctab_p[k*256+n] = c; + } + } +#endif /* IZ_CRCOPTIM_UNFOLDTBL */ + + MARK_CRCTAB_FILLED; +} + +#else /* !DYNAMIC_CRC_TABLE */ + +#ifdef DYNALLOC_CRCTAB + error: Inconsistent flags, DYNALLOC_CRCTAB without DYNAMIC_CRC_TABLE. +#endif + +/* ======================================================================== + * Table of CRC-32's of all single-byte values (made by make_crc_table) + */ +local ZCONST ulg near crc_table[CRC_TBLS*256] = { +# ifdef IZ_CRC_BE_OPTIMIZ + 0x00000000L, 0x96300777L, 0x2c610eeeL, 0xba510999L, 0x19c46d07L, + 0x8ff46a70L, 0x35a563e9L, 0xa395649eL, 0x3288db0eL, 0xa4b8dc79L, + 0x1ee9d5e0L, 0x88d9d297L, 0x2b4cb609L, 0xbd7cb17eL, 0x072db8e7L, + 0x911dbf90L, 0x6410b71dL, 0xf220b06aL, 0x4871b9f3L, 0xde41be84L, + 0x7dd4da1aL, 0xebe4dd6dL, 0x51b5d4f4L, 0xc785d383L, 0x56986c13L, + 0xc0a86b64L, 0x7af962fdL, 0xecc9658aL, 0x4f5c0114L, 0xd96c0663L, + 0x633d0ffaL, 0xf50d088dL, 0xc8206e3bL, 0x5e10694cL, 0xe44160d5L, + 0x727167a2L, 0xd1e4033cL, 0x47d4044bL, 0xfd850dd2L, 0x6bb50aa5L, + 0xfaa8b535L, 0x6c98b242L, 0xd6c9bbdbL, 0x40f9bcacL, 0xe36cd832L, + 0x755cdf45L, 0xcf0dd6dcL, 0x593dd1abL, 0xac30d926L, 0x3a00de51L, + 0x8051d7c8L, 0x1661d0bfL, 0xb5f4b421L, 0x23c4b356L, 0x9995bacfL, + 0x0fa5bdb8L, 0x9eb80228L, 0x0888055fL, 0xb2d90cc6L, 0x24e90bb1L, + 0x877c6f2fL, 0x114c6858L, 0xab1d61c1L, 0x3d2d66b6L, 0x9041dc76L, + 0x0671db01L, 0xbc20d298L, 0x2a10d5efL, 0x8985b171L, 0x1fb5b606L, + 0xa5e4bf9fL, 0x33d4b8e8L, 0xa2c90778L, 0x34f9000fL, 0x8ea80996L, + 0x18980ee1L, 0xbb0d6a7fL, 0x2d3d6d08L, 0x976c6491L, 0x015c63e6L, + 0xf4516b6bL, 0x62616c1cL, 0xd8306585L, 0x4e0062f2L, 0xed95066cL, + 0x7ba5011bL, 0xc1f40882L, 0x57c40ff5L, 0xc6d9b065L, 0x50e9b712L, + 0xeab8be8bL, 0x7c88b9fcL, 0xdf1ddd62L, 0x492dda15L, 0xf37cd38cL, + 0x654cd4fbL, 0x5861b24dL, 0xce51b53aL, 0x7400bca3L, 0xe230bbd4L, + 0x41a5df4aL, 0xd795d83dL, 0x6dc4d1a4L, 0xfbf4d6d3L, 0x6ae96943L, + 0xfcd96e34L, 0x468867adL, 0xd0b860daL, 0x732d0444L, 0xe51d0333L, + 0x5f4c0aaaL, 0xc97c0dddL, 0x3c710550L, 0xaa410227L, 0x10100bbeL, + 0x86200cc9L, 0x25b56857L, 0xb3856f20L, 0x09d466b9L, 0x9fe461ceL, + 0x0ef9de5eL, 0x98c9d929L, 0x2298d0b0L, 0xb4a8d7c7L, 0x173db359L, + 0x810db42eL, 0x3b5cbdb7L, 0xad6cbac0L, 0x2083b8edL, 0xb6b3bf9aL, + 0x0ce2b603L, 0x9ad2b174L, 0x3947d5eaL, 0xaf77d29dL, 0x1526db04L, + 0x8316dc73L, 0x120b63e3L, 0x843b6494L, 0x3e6a6d0dL, 0xa85a6a7aL, + 0x0bcf0ee4L, 0x9dff0993L, 0x27ae000aL, 0xb19e077dL, 0x44930ff0L, + 0xd2a30887L, 0x68f2011eL, 0xfec20669L, 0x5d5762f7L, 0xcb676580L, + 0x71366c19L, 0xe7066b6eL, 0x761bd4feL, 0xe02bd389L, 0x5a7ada10L, + 0xcc4add67L, 0x6fdfb9f9L, 0xf9efbe8eL, 0x43beb717L, 0xd58eb060L, + 0xe8a3d6d6L, 0x7e93d1a1L, 0xc4c2d838L, 0x52f2df4fL, 0xf167bbd1L, + 0x6757bca6L, 0xdd06b53fL, 0x4b36b248L, 0xda2b0dd8L, 0x4c1b0aafL, + 0xf64a0336L, 0x607a0441L, 0xc3ef60dfL, 0x55df67a8L, 0xef8e6e31L, + 0x79be6946L, 0x8cb361cbL, 0x1a8366bcL, 0xa0d26f25L, 0x36e26852L, + 0x95770cccL, 0x03470bbbL, 0xb9160222L, 0x2f260555L, 0xbe3bbac5L, + 0x280bbdb2L, 0x925ab42bL, 0x046ab35cL, 0xa7ffd7c2L, 0x31cfd0b5L, + 0x8b9ed92cL, 0x1daede5bL, 0xb0c2649bL, 0x26f263ecL, 0x9ca36a75L, + 0x0a936d02L, 0xa906099cL, 0x3f360eebL, 0x85670772L, 0x13570005L, + 0x824abf95L, 0x147ab8e2L, 0xae2bb17bL, 0x381bb60cL, 0x9b8ed292L, + 0x0dbed5e5L, 0xb7efdc7cL, 0x21dfdb0bL, 0xd4d2d386L, 0x42e2d4f1L, + 0xf8b3dd68L, 0x6e83da1fL, 0xcd16be81L, 0x5b26b9f6L, 0xe177b06fL, + 0x7747b718L, 0xe65a0888L, 0x706a0fffL, 0xca3b0666L, 0x5c0b0111L, + 0xff9e658fL, 0x69ae62f8L, 0xd3ff6b61L, 0x45cf6c16L, 0x78e20aa0L, + 0xeed20dd7L, 0x5483044eL, 0xc2b30339L, 0x612667a7L, 0xf71660d0L, + 0x4d476949L, 0xdb776e3eL, 0x4a6ad1aeL, 0xdc5ad6d9L, 0x660bdf40L, + 0xf03bd837L, 0x53aebca9L, 0xc59ebbdeL, 0x7fcfb247L, 0xe9ffb530L, + 0x1cf2bdbdL, 0x8ac2bacaL, 0x3093b353L, 0xa6a3b424L, 0x0536d0baL, + 0x9306d7cdL, 0x2957de54L, 0xbf67d923L, 0x2e7a66b3L, 0xb84a61c4L, + 0x021b685dL, 0x942b6f2aL, 0x37be0bb4L, 0xa18e0cc3L, 0x1bdf055aL, + 0x8def022dL +# ifdef IZ_CRCOPTIM_UNFOLDTBL + , + 0x00000000L, 0x41311b19L, 0x82623632L, 0xc3532d2bL, 0x04c56c64L, + 0x45f4777dL, 0x86a75a56L, 0xc796414fL, 0x088ad9c8L, 0x49bbc2d1L, + 0x8ae8effaL, 0xcbd9f4e3L, 0x0c4fb5acL, 0x4d7eaeb5L, 0x8e2d839eL, + 0xcf1c9887L, 0x5112c24aL, 0x1023d953L, 0xd370f478L, 0x9241ef61L, + 0x55d7ae2eL, 0x14e6b537L, 0xd7b5981cL, 0x96848305L, 0x59981b82L, + 0x18a9009bL, 0xdbfa2db0L, 0x9acb36a9L, 0x5d5d77e6L, 0x1c6c6cffL, + 0xdf3f41d4L, 0x9e0e5acdL, 0xa2248495L, 0xe3159f8cL, 0x2046b2a7L, + 0x6177a9beL, 0xa6e1e8f1L, 0xe7d0f3e8L, 0x2483dec3L, 0x65b2c5daL, + 0xaaae5d5dL, 0xeb9f4644L, 0x28cc6b6fL, 0x69fd7076L, 0xae6b3139L, + 0xef5a2a20L, 0x2c09070bL, 0x6d381c12L, 0xf33646dfL, 0xb2075dc6L, + 0x715470edL, 0x30656bf4L, 0xf7f32abbL, 0xb6c231a2L, 0x75911c89L, + 0x34a00790L, 0xfbbc9f17L, 0xba8d840eL, 0x79dea925L, 0x38efb23cL, + 0xff79f373L, 0xbe48e86aL, 0x7d1bc541L, 0x3c2ade58L, 0x054f79f0L, + 0x447e62e9L, 0x872d4fc2L, 0xc61c54dbL, 0x018a1594L, 0x40bb0e8dL, + 0x83e823a6L, 0xc2d938bfL, 0x0dc5a038L, 0x4cf4bb21L, 0x8fa7960aL, + 0xce968d13L, 0x0900cc5cL, 0x4831d745L, 0x8b62fa6eL, 0xca53e177L, + 0x545dbbbaL, 0x156ca0a3L, 0xd63f8d88L, 0x970e9691L, 0x5098d7deL, + 0x11a9ccc7L, 0xd2fae1ecL, 0x93cbfaf5L, 0x5cd76272L, 0x1de6796bL, + 0xdeb55440L, 0x9f844f59L, 0x58120e16L, 0x1923150fL, 0xda703824L, + 0x9b41233dL, 0xa76bfd65L, 0xe65ae67cL, 0x2509cb57L, 0x6438d04eL, + 0xa3ae9101L, 0xe29f8a18L, 0x21cca733L, 0x60fdbc2aL, 0xafe124adL, + 0xeed03fb4L, 0x2d83129fL, 0x6cb20986L, 0xab2448c9L, 0xea1553d0L, + 0x29467efbL, 0x687765e2L, 0xf6793f2fL, 0xb7482436L, 0x741b091dL, + 0x352a1204L, 0xf2bc534bL, 0xb38d4852L, 0x70de6579L, 0x31ef7e60L, + 0xfef3e6e7L, 0xbfc2fdfeL, 0x7c91d0d5L, 0x3da0cbccL, 0xfa368a83L, + 0xbb07919aL, 0x7854bcb1L, 0x3965a7a8L, 0x4b98833bL, 0x0aa99822L, + 0xc9fab509L, 0x88cbae10L, 0x4f5def5fL, 0x0e6cf446L, 0xcd3fd96dL, + 0x8c0ec274L, 0x43125af3L, 0x022341eaL, 0xc1706cc1L, 0x804177d8L, + 0x47d73697L, 0x06e62d8eL, 0xc5b500a5L, 0x84841bbcL, 0x1a8a4171L, + 0x5bbb5a68L, 0x98e87743L, 0xd9d96c5aL, 0x1e4f2d15L, 0x5f7e360cL, + 0x9c2d1b27L, 0xdd1c003eL, 0x120098b9L, 0x533183a0L, 0x9062ae8bL, + 0xd153b592L, 0x16c5f4ddL, 0x57f4efc4L, 0x94a7c2efL, 0xd596d9f6L, + 0xe9bc07aeL, 0xa88d1cb7L, 0x6bde319cL, 0x2aef2a85L, 0xed796bcaL, + 0xac4870d3L, 0x6f1b5df8L, 0x2e2a46e1L, 0xe136de66L, 0xa007c57fL, + 0x6354e854L, 0x2265f34dL, 0xe5f3b202L, 0xa4c2a91bL, 0x67918430L, + 0x26a09f29L, 0xb8aec5e4L, 0xf99fdefdL, 0x3accf3d6L, 0x7bfde8cfL, + 0xbc6ba980L, 0xfd5ab299L, 0x3e099fb2L, 0x7f3884abL, 0xb0241c2cL, + 0xf1150735L, 0x32462a1eL, 0x73773107L, 0xb4e17048L, 0xf5d06b51L, + 0x3683467aL, 0x77b25d63L, 0x4ed7facbL, 0x0fe6e1d2L, 0xccb5ccf9L, + 0x8d84d7e0L, 0x4a1296afL, 0x0b238db6L, 0xc870a09dL, 0x8941bb84L, + 0x465d2303L, 0x076c381aL, 0xc43f1531L, 0x850e0e28L, 0x42984f67L, + 0x03a9547eL, 0xc0fa7955L, 0x81cb624cL, 0x1fc53881L, 0x5ef42398L, + 0x9da70eb3L, 0xdc9615aaL, 0x1b0054e5L, 0x5a314ffcL, 0x996262d7L, + 0xd85379ceL, 0x174fe149L, 0x567efa50L, 0x952dd77bL, 0xd41ccc62L, + 0x138a8d2dL, 0x52bb9634L, 0x91e8bb1fL, 0xd0d9a006L, 0xecf37e5eL, + 0xadc26547L, 0x6e91486cL, 0x2fa05375L, 0xe836123aL, 0xa9070923L, + 0x6a542408L, 0x2b653f11L, 0xe479a796L, 0xa548bc8fL, 0x661b91a4L, + 0x272a8abdL, 0xe0bccbf2L, 0xa18dd0ebL, 0x62defdc0L, 0x23efe6d9L, + 0xbde1bc14L, 0xfcd0a70dL, 0x3f838a26L, 0x7eb2913fL, 0xb924d070L, + 0xf815cb69L, 0x3b46e642L, 0x7a77fd5bL, 0xb56b65dcL, 0xf45a7ec5L, + 0x370953eeL, 0x763848f7L, 0xb1ae09b8L, 0xf09f12a1L, 0x33cc3f8aL, + 0x72fd2493L + , + 0x00000000L, 0x376ac201L, 0x6ed48403L, 0x59be4602L, 0xdca80907L, + 0xebc2cb06L, 0xb27c8d04L, 0x85164f05L, 0xb851130eL, 0x8f3bd10fL, + 0xd685970dL, 0xe1ef550cL, 0x64f91a09L, 0x5393d808L, 0x0a2d9e0aL, + 0x3d475c0bL, 0x70a3261cL, 0x47c9e41dL, 0x1e77a21fL, 0x291d601eL, + 0xac0b2f1bL, 0x9b61ed1aL, 0xc2dfab18L, 0xf5b56919L, 0xc8f23512L, + 0xff98f713L, 0xa626b111L, 0x914c7310L, 0x145a3c15L, 0x2330fe14L, + 0x7a8eb816L, 0x4de47a17L, 0xe0464d38L, 0xd72c8f39L, 0x8e92c93bL, + 0xb9f80b3aL, 0x3cee443fL, 0x0b84863eL, 0x523ac03cL, 0x6550023dL, + 0x58175e36L, 0x6f7d9c37L, 0x36c3da35L, 0x01a91834L, 0x84bf5731L, + 0xb3d59530L, 0xea6bd332L, 0xdd011133L, 0x90e56b24L, 0xa78fa925L, + 0xfe31ef27L, 0xc95b2d26L, 0x4c4d6223L, 0x7b27a022L, 0x2299e620L, + 0x15f32421L, 0x28b4782aL, 0x1fdeba2bL, 0x4660fc29L, 0x710a3e28L, + 0xf41c712dL, 0xc376b32cL, 0x9ac8f52eL, 0xada2372fL, 0xc08d9a70L, + 0xf7e75871L, 0xae591e73L, 0x9933dc72L, 0x1c259377L, 0x2b4f5176L, + 0x72f11774L, 0x459bd575L, 0x78dc897eL, 0x4fb64b7fL, 0x16080d7dL, + 0x2162cf7cL, 0xa4748079L, 0x931e4278L, 0xcaa0047aL, 0xfdcac67bL, + 0xb02ebc6cL, 0x87447e6dL, 0xdefa386fL, 0xe990fa6eL, 0x6c86b56bL, + 0x5bec776aL, 0x02523168L, 0x3538f369L, 0x087faf62L, 0x3f156d63L, + 0x66ab2b61L, 0x51c1e960L, 0xd4d7a665L, 0xe3bd6464L, 0xba032266L, + 0x8d69e067L, 0x20cbd748L, 0x17a11549L, 0x4e1f534bL, 0x7975914aL, + 0xfc63de4fL, 0xcb091c4eL, 0x92b75a4cL, 0xa5dd984dL, 0x989ac446L, + 0xaff00647L, 0xf64e4045L, 0xc1248244L, 0x4432cd41L, 0x73580f40L, + 0x2ae64942L, 0x1d8c8b43L, 0x5068f154L, 0x67023355L, 0x3ebc7557L, + 0x09d6b756L, 0x8cc0f853L, 0xbbaa3a52L, 0xe2147c50L, 0xd57ebe51L, + 0xe839e25aL, 0xdf53205bL, 0x86ed6659L, 0xb187a458L, 0x3491eb5dL, + 0x03fb295cL, 0x5a456f5eL, 0x6d2fad5fL, 0x801b35e1L, 0xb771f7e0L, + 0xeecfb1e2L, 0xd9a573e3L, 0x5cb33ce6L, 0x6bd9fee7L, 0x3267b8e5L, + 0x050d7ae4L, 0x384a26efL, 0x0f20e4eeL, 0x569ea2ecL, 0x61f460edL, + 0xe4e22fe8L, 0xd388ede9L, 0x8a36abebL, 0xbd5c69eaL, 0xf0b813fdL, + 0xc7d2d1fcL, 0x9e6c97feL, 0xa90655ffL, 0x2c101afaL, 0x1b7ad8fbL, + 0x42c49ef9L, 0x75ae5cf8L, 0x48e900f3L, 0x7f83c2f2L, 0x263d84f0L, + 0x115746f1L, 0x944109f4L, 0xa32bcbf5L, 0xfa958df7L, 0xcdff4ff6L, + 0x605d78d9L, 0x5737bad8L, 0x0e89fcdaL, 0x39e33edbL, 0xbcf571deL, + 0x8b9fb3dfL, 0xd221f5ddL, 0xe54b37dcL, 0xd80c6bd7L, 0xef66a9d6L, + 0xb6d8efd4L, 0x81b22dd5L, 0x04a462d0L, 0x33cea0d1L, 0x6a70e6d3L, + 0x5d1a24d2L, 0x10fe5ec5L, 0x27949cc4L, 0x7e2adac6L, 0x494018c7L, + 0xcc5657c2L, 0xfb3c95c3L, 0xa282d3c1L, 0x95e811c0L, 0xa8af4dcbL, + 0x9fc58fcaL, 0xc67bc9c8L, 0xf1110bc9L, 0x740744ccL, 0x436d86cdL, + 0x1ad3c0cfL, 0x2db902ceL, 0x4096af91L, 0x77fc6d90L, 0x2e422b92L, + 0x1928e993L, 0x9c3ea696L, 0xab546497L, 0xf2ea2295L, 0xc580e094L, + 0xf8c7bc9fL, 0xcfad7e9eL, 0x9613389cL, 0xa179fa9dL, 0x246fb598L, + 0x13057799L, 0x4abb319bL, 0x7dd1f39aL, 0x3035898dL, 0x075f4b8cL, + 0x5ee10d8eL, 0x698bcf8fL, 0xec9d808aL, 0xdbf7428bL, 0x82490489L, + 0xb523c688L, 0x88649a83L, 0xbf0e5882L, 0xe6b01e80L, 0xd1dadc81L, + 0x54cc9384L, 0x63a65185L, 0x3a181787L, 0x0d72d586L, 0xa0d0e2a9L, + 0x97ba20a8L, 0xce0466aaL, 0xf96ea4abL, 0x7c78ebaeL, 0x4b1229afL, + 0x12ac6fadL, 0x25c6adacL, 0x1881f1a7L, 0x2feb33a6L, 0x765575a4L, + 0x413fb7a5L, 0xc429f8a0L, 0xf3433aa1L, 0xaafd7ca3L, 0x9d97bea2L, + 0xd073c4b5L, 0xe71906b4L, 0xbea740b6L, 0x89cd82b7L, 0x0cdbcdb2L, + 0x3bb10fb3L, 0x620f49b1L, 0x55658bb0L, 0x6822d7bbL, 0x5f4815baL, + 0x06f653b8L, 0x319c91b9L, 0xb48adebcL, 0x83e01cbdL, 0xda5e5abfL, + 0xed3498beL + , + 0x00000000L, 0x6567bcb8L, 0x8bc809aaL, 0xeeafb512L, 0x5797628fL, + 0x32f0de37L, 0xdc5f6b25L, 0xb938d79dL, 0xef28b4c5L, 0x8a4f087dL, + 0x64e0bd6fL, 0x018701d7L, 0xb8bfd64aL, 0xddd86af2L, 0x3377dfe0L, + 0x56106358L, 0x9f571950L, 0xfa30a5e8L, 0x149f10faL, 0x71f8ac42L, + 0xc8c07bdfL, 0xada7c767L, 0x43087275L, 0x266fcecdL, 0x707fad95L, + 0x1518112dL, 0xfbb7a43fL, 0x9ed01887L, 0x27e8cf1aL, 0x428f73a2L, + 0xac20c6b0L, 0xc9477a08L, 0x3eaf32a0L, 0x5bc88e18L, 0xb5673b0aL, + 0xd00087b2L, 0x6938502fL, 0x0c5fec97L, 0xe2f05985L, 0x8797e53dL, + 0xd1878665L, 0xb4e03addL, 0x5a4f8fcfL, 0x3f283377L, 0x8610e4eaL, + 0xe3775852L, 0x0dd8ed40L, 0x68bf51f8L, 0xa1f82bf0L, 0xc49f9748L, + 0x2a30225aL, 0x4f579ee2L, 0xf66f497fL, 0x9308f5c7L, 0x7da740d5L, + 0x18c0fc6dL, 0x4ed09f35L, 0x2bb7238dL, 0xc518969fL, 0xa07f2a27L, + 0x1947fdbaL, 0x7c204102L, 0x928ff410L, 0xf7e848a8L, 0x3d58149bL, + 0x583fa823L, 0xb6901d31L, 0xd3f7a189L, 0x6acf7614L, 0x0fa8caacL, + 0xe1077fbeL, 0x8460c306L, 0xd270a05eL, 0xb7171ce6L, 0x59b8a9f4L, + 0x3cdf154cL, 0x85e7c2d1L, 0xe0807e69L, 0x0e2fcb7bL, 0x6b4877c3L, + 0xa20f0dcbL, 0xc768b173L, 0x29c70461L, 0x4ca0b8d9L, 0xf5986f44L, + 0x90ffd3fcL, 0x7e5066eeL, 0x1b37da56L, 0x4d27b90eL, 0x284005b6L, + 0xc6efb0a4L, 0xa3880c1cL, 0x1ab0db81L, 0x7fd76739L, 0x9178d22bL, + 0xf41f6e93L, 0x03f7263bL, 0x66909a83L, 0x883f2f91L, 0xed589329L, + 0x546044b4L, 0x3107f80cL, 0xdfa84d1eL, 0xbacff1a6L, 0xecdf92feL, + 0x89b82e46L, 0x67179b54L, 0x027027ecL, 0xbb48f071L, 0xde2f4cc9L, + 0x3080f9dbL, 0x55e74563L, 0x9ca03f6bL, 0xf9c783d3L, 0x176836c1L, + 0x720f8a79L, 0xcb375de4L, 0xae50e15cL, 0x40ff544eL, 0x2598e8f6L, + 0x73888baeL, 0x16ef3716L, 0xf8408204L, 0x9d273ebcL, 0x241fe921L, + 0x41785599L, 0xafd7e08bL, 0xcab05c33L, 0x3bb659edL, 0x5ed1e555L, + 0xb07e5047L, 0xd519ecffL, 0x6c213b62L, 0x094687daL, 0xe7e932c8L, + 0x828e8e70L, 0xd49eed28L, 0xb1f95190L, 0x5f56e482L, 0x3a31583aL, + 0x83098fa7L, 0xe66e331fL, 0x08c1860dL, 0x6da63ab5L, 0xa4e140bdL, + 0xc186fc05L, 0x2f294917L, 0x4a4ef5afL, 0xf3762232L, 0x96119e8aL, + 0x78be2b98L, 0x1dd99720L, 0x4bc9f478L, 0x2eae48c0L, 0xc001fdd2L, + 0xa566416aL, 0x1c5e96f7L, 0x79392a4fL, 0x97969f5dL, 0xf2f123e5L, + 0x05196b4dL, 0x607ed7f5L, 0x8ed162e7L, 0xebb6de5fL, 0x528e09c2L, + 0x37e9b57aL, 0xd9460068L, 0xbc21bcd0L, 0xea31df88L, 0x8f566330L, + 0x61f9d622L, 0x049e6a9aL, 0xbda6bd07L, 0xd8c101bfL, 0x366eb4adL, + 0x53090815L, 0x9a4e721dL, 0xff29cea5L, 0x11867bb7L, 0x74e1c70fL, + 0xcdd91092L, 0xa8beac2aL, 0x46111938L, 0x2376a580L, 0x7566c6d8L, + 0x10017a60L, 0xfeaecf72L, 0x9bc973caL, 0x22f1a457L, 0x479618efL, + 0xa939adfdL, 0xcc5e1145L, 0x06ee4d76L, 0x6389f1ceL, 0x8d2644dcL, + 0xe841f864L, 0x51792ff9L, 0x341e9341L, 0xdab12653L, 0xbfd69aebL, + 0xe9c6f9b3L, 0x8ca1450bL, 0x620ef019L, 0x07694ca1L, 0xbe519b3cL, + 0xdb362784L, 0x35999296L, 0x50fe2e2eL, 0x99b95426L, 0xfcdee89eL, + 0x12715d8cL, 0x7716e134L, 0xce2e36a9L, 0xab498a11L, 0x45e63f03L, + 0x208183bbL, 0x7691e0e3L, 0x13f65c5bL, 0xfd59e949L, 0x983e55f1L, + 0x2106826cL, 0x44613ed4L, 0xaace8bc6L, 0xcfa9377eL, 0x38417fd6L, + 0x5d26c36eL, 0xb389767cL, 0xd6eecac4L, 0x6fd61d59L, 0x0ab1a1e1L, + 0xe41e14f3L, 0x8179a84bL, 0xd769cb13L, 0xb20e77abL, 0x5ca1c2b9L, + 0x39c67e01L, 0x80fea99cL, 0xe5991524L, 0x0b36a036L, 0x6e511c8eL, + 0xa7166686L, 0xc271da3eL, 0x2cde6f2cL, 0x49b9d394L, 0xf0810409L, + 0x95e6b8b1L, 0x7b490da3L, 0x1e2eb11bL, 0x483ed243L, 0x2d596efbL, + 0xc3f6dbe9L, 0xa6916751L, 0x1fa9b0ccL, 0x7ace0c74L, 0x9461b966L, + 0xf10605deL +# endif /* IZ_CRCOPTIM_UNFOLDTBL */ +# else /* !IZ_CRC_BE_OPTIMIZ */ + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +# ifdef IZ_CRCOPTIM_UNFOLDTBL + , + 0x00000000L, 0x191b3141L, 0x32366282L, 0x2b2d53c3L, 0x646cc504L, + 0x7d77f445L, 0x565aa786L, 0x4f4196c7L, 0xc8d98a08L, 0xd1c2bb49L, + 0xfaefe88aL, 0xe3f4d9cbL, 0xacb54f0cL, 0xb5ae7e4dL, 0x9e832d8eL, + 0x87981ccfL, 0x4ac21251L, 0x53d92310L, 0x78f470d3L, 0x61ef4192L, + 0x2eaed755L, 0x37b5e614L, 0x1c98b5d7L, 0x05838496L, 0x821b9859L, + 0x9b00a918L, 0xb02dfadbL, 0xa936cb9aL, 0xe6775d5dL, 0xff6c6c1cL, + 0xd4413fdfL, 0xcd5a0e9eL, 0x958424a2L, 0x8c9f15e3L, 0xa7b24620L, + 0xbea97761L, 0xf1e8e1a6L, 0xe8f3d0e7L, 0xc3de8324L, 0xdac5b265L, + 0x5d5daeaaL, 0x44469febL, 0x6f6bcc28L, 0x7670fd69L, 0x39316baeL, + 0x202a5aefL, 0x0b07092cL, 0x121c386dL, 0xdf4636f3L, 0xc65d07b2L, + 0xed705471L, 0xf46b6530L, 0xbb2af3f7L, 0xa231c2b6L, 0x891c9175L, + 0x9007a034L, 0x179fbcfbL, 0x0e848dbaL, 0x25a9de79L, 0x3cb2ef38L, + 0x73f379ffL, 0x6ae848beL, 0x41c51b7dL, 0x58de2a3cL, 0xf0794f05L, + 0xe9627e44L, 0xc24f2d87L, 0xdb541cc6L, 0x94158a01L, 0x8d0ebb40L, + 0xa623e883L, 0xbf38d9c2L, 0x38a0c50dL, 0x21bbf44cL, 0x0a96a78fL, + 0x138d96ceL, 0x5ccc0009L, 0x45d73148L, 0x6efa628bL, 0x77e153caL, + 0xbabb5d54L, 0xa3a06c15L, 0x888d3fd6L, 0x91960e97L, 0xded79850L, + 0xc7cca911L, 0xece1fad2L, 0xf5facb93L, 0x7262d75cL, 0x6b79e61dL, + 0x4054b5deL, 0x594f849fL, 0x160e1258L, 0x0f152319L, 0x243870daL, + 0x3d23419bL, 0x65fd6ba7L, 0x7ce65ae6L, 0x57cb0925L, 0x4ed03864L, + 0x0191aea3L, 0x188a9fe2L, 0x33a7cc21L, 0x2abcfd60L, 0xad24e1afL, + 0xb43fd0eeL, 0x9f12832dL, 0x8609b26cL, 0xc94824abL, 0xd05315eaL, + 0xfb7e4629L, 0xe2657768L, 0x2f3f79f6L, 0x362448b7L, 0x1d091b74L, + 0x04122a35L, 0x4b53bcf2L, 0x52488db3L, 0x7965de70L, 0x607eef31L, + 0xe7e6f3feL, 0xfefdc2bfL, 0xd5d0917cL, 0xcccba03dL, 0x838a36faL, + 0x9a9107bbL, 0xb1bc5478L, 0xa8a76539L, 0x3b83984bL, 0x2298a90aL, + 0x09b5fac9L, 0x10aecb88L, 0x5fef5d4fL, 0x46f46c0eL, 0x6dd93fcdL, + 0x74c20e8cL, 0xf35a1243L, 0xea412302L, 0xc16c70c1L, 0xd8774180L, + 0x9736d747L, 0x8e2de606L, 0xa500b5c5L, 0xbc1b8484L, 0x71418a1aL, + 0x685abb5bL, 0x4377e898L, 0x5a6cd9d9L, 0x152d4f1eL, 0x0c367e5fL, + 0x271b2d9cL, 0x3e001cddL, 0xb9980012L, 0xa0833153L, 0x8bae6290L, + 0x92b553d1L, 0xddf4c516L, 0xc4eff457L, 0xefc2a794L, 0xf6d996d5L, + 0xae07bce9L, 0xb71c8da8L, 0x9c31de6bL, 0x852aef2aL, 0xca6b79edL, + 0xd37048acL, 0xf85d1b6fL, 0xe1462a2eL, 0x66de36e1L, 0x7fc507a0L, + 0x54e85463L, 0x4df36522L, 0x02b2f3e5L, 0x1ba9c2a4L, 0x30849167L, + 0x299fa026L, 0xe4c5aeb8L, 0xfdde9ff9L, 0xd6f3cc3aL, 0xcfe8fd7bL, + 0x80a96bbcL, 0x99b25afdL, 0xb29f093eL, 0xab84387fL, 0x2c1c24b0L, + 0x350715f1L, 0x1e2a4632L, 0x07317773L, 0x4870e1b4L, 0x516bd0f5L, + 0x7a468336L, 0x635db277L, 0xcbfad74eL, 0xd2e1e60fL, 0xf9ccb5ccL, + 0xe0d7848dL, 0xaf96124aL, 0xb68d230bL, 0x9da070c8L, 0x84bb4189L, + 0x03235d46L, 0x1a386c07L, 0x31153fc4L, 0x280e0e85L, 0x674f9842L, + 0x7e54a903L, 0x5579fac0L, 0x4c62cb81L, 0x8138c51fL, 0x9823f45eL, + 0xb30ea79dL, 0xaa1596dcL, 0xe554001bL, 0xfc4f315aL, 0xd7626299L, + 0xce7953d8L, 0x49e14f17L, 0x50fa7e56L, 0x7bd72d95L, 0x62cc1cd4L, + 0x2d8d8a13L, 0x3496bb52L, 0x1fbbe891L, 0x06a0d9d0L, 0x5e7ef3ecL, + 0x4765c2adL, 0x6c48916eL, 0x7553a02fL, 0x3a1236e8L, 0x230907a9L, + 0x0824546aL, 0x113f652bL, 0x96a779e4L, 0x8fbc48a5L, 0xa4911b66L, + 0xbd8a2a27L, 0xf2cbbce0L, 0xebd08da1L, 0xc0fdde62L, 0xd9e6ef23L, + 0x14bce1bdL, 0x0da7d0fcL, 0x268a833fL, 0x3f91b27eL, 0x70d024b9L, + 0x69cb15f8L, 0x42e6463bL, 0x5bfd777aL, 0xdc656bb5L, 0xc57e5af4L, + 0xee530937L, 0xf7483876L, 0xb809aeb1L, 0xa1129ff0L, 0x8a3fcc33L, + 0x9324fd72L + , + 0x00000000L, 0x01c26a37L, 0x0384d46eL, 0x0246be59L, 0x0709a8dcL, + 0x06cbc2ebL, 0x048d7cb2L, 0x054f1685L, 0x0e1351b8L, 0x0fd13b8fL, + 0x0d9785d6L, 0x0c55efe1L, 0x091af964L, 0x08d89353L, 0x0a9e2d0aL, + 0x0b5c473dL, 0x1c26a370L, 0x1de4c947L, 0x1fa2771eL, 0x1e601d29L, + 0x1b2f0bacL, 0x1aed619bL, 0x18abdfc2L, 0x1969b5f5L, 0x1235f2c8L, + 0x13f798ffL, 0x11b126a6L, 0x10734c91L, 0x153c5a14L, 0x14fe3023L, + 0x16b88e7aL, 0x177ae44dL, 0x384d46e0L, 0x398f2cd7L, 0x3bc9928eL, + 0x3a0bf8b9L, 0x3f44ee3cL, 0x3e86840bL, 0x3cc03a52L, 0x3d025065L, + 0x365e1758L, 0x379c7d6fL, 0x35dac336L, 0x3418a901L, 0x3157bf84L, + 0x3095d5b3L, 0x32d36beaL, 0x331101ddL, 0x246be590L, 0x25a98fa7L, + 0x27ef31feL, 0x262d5bc9L, 0x23624d4cL, 0x22a0277bL, 0x20e69922L, + 0x2124f315L, 0x2a78b428L, 0x2bbade1fL, 0x29fc6046L, 0x283e0a71L, + 0x2d711cf4L, 0x2cb376c3L, 0x2ef5c89aL, 0x2f37a2adL, 0x709a8dc0L, + 0x7158e7f7L, 0x731e59aeL, 0x72dc3399L, 0x7793251cL, 0x76514f2bL, + 0x7417f172L, 0x75d59b45L, 0x7e89dc78L, 0x7f4bb64fL, 0x7d0d0816L, + 0x7ccf6221L, 0x798074a4L, 0x78421e93L, 0x7a04a0caL, 0x7bc6cafdL, + 0x6cbc2eb0L, 0x6d7e4487L, 0x6f38fadeL, 0x6efa90e9L, 0x6bb5866cL, + 0x6a77ec5bL, 0x68315202L, 0x69f33835L, 0x62af7f08L, 0x636d153fL, + 0x612bab66L, 0x60e9c151L, 0x65a6d7d4L, 0x6464bde3L, 0x662203baL, + 0x67e0698dL, 0x48d7cb20L, 0x4915a117L, 0x4b531f4eL, 0x4a917579L, + 0x4fde63fcL, 0x4e1c09cbL, 0x4c5ab792L, 0x4d98dda5L, 0x46c49a98L, + 0x4706f0afL, 0x45404ef6L, 0x448224c1L, 0x41cd3244L, 0x400f5873L, + 0x4249e62aL, 0x438b8c1dL, 0x54f16850L, 0x55330267L, 0x5775bc3eL, + 0x56b7d609L, 0x53f8c08cL, 0x523aaabbL, 0x507c14e2L, 0x51be7ed5L, + 0x5ae239e8L, 0x5b2053dfL, 0x5966ed86L, 0x58a487b1L, 0x5deb9134L, + 0x5c29fb03L, 0x5e6f455aL, 0x5fad2f6dL, 0xe1351b80L, 0xe0f771b7L, + 0xe2b1cfeeL, 0xe373a5d9L, 0xe63cb35cL, 0xe7fed96bL, 0xe5b86732L, + 0xe47a0d05L, 0xef264a38L, 0xeee4200fL, 0xeca29e56L, 0xed60f461L, + 0xe82fe2e4L, 0xe9ed88d3L, 0xebab368aL, 0xea695cbdL, 0xfd13b8f0L, + 0xfcd1d2c7L, 0xfe976c9eL, 0xff5506a9L, 0xfa1a102cL, 0xfbd87a1bL, + 0xf99ec442L, 0xf85cae75L, 0xf300e948L, 0xf2c2837fL, 0xf0843d26L, + 0xf1465711L, 0xf4094194L, 0xf5cb2ba3L, 0xf78d95faL, 0xf64fffcdL, + 0xd9785d60L, 0xd8ba3757L, 0xdafc890eL, 0xdb3ee339L, 0xde71f5bcL, + 0xdfb39f8bL, 0xddf521d2L, 0xdc374be5L, 0xd76b0cd8L, 0xd6a966efL, + 0xd4efd8b6L, 0xd52db281L, 0xd062a404L, 0xd1a0ce33L, 0xd3e6706aL, + 0xd2241a5dL, 0xc55efe10L, 0xc49c9427L, 0xc6da2a7eL, 0xc7184049L, + 0xc25756ccL, 0xc3953cfbL, 0xc1d382a2L, 0xc011e895L, 0xcb4dafa8L, + 0xca8fc59fL, 0xc8c97bc6L, 0xc90b11f1L, 0xcc440774L, 0xcd866d43L, + 0xcfc0d31aL, 0xce02b92dL, 0x91af9640L, 0x906dfc77L, 0x922b422eL, + 0x93e92819L, 0x96a63e9cL, 0x976454abL, 0x9522eaf2L, 0x94e080c5L, + 0x9fbcc7f8L, 0x9e7eadcfL, 0x9c381396L, 0x9dfa79a1L, 0x98b56f24L, + 0x99770513L, 0x9b31bb4aL, 0x9af3d17dL, 0x8d893530L, 0x8c4b5f07L, + 0x8e0de15eL, 0x8fcf8b69L, 0x8a809decL, 0x8b42f7dbL, 0x89044982L, + 0x88c623b5L, 0x839a6488L, 0x82580ebfL, 0x801eb0e6L, 0x81dcdad1L, + 0x8493cc54L, 0x8551a663L, 0x8717183aL, 0x86d5720dL, 0xa9e2d0a0L, + 0xa820ba97L, 0xaa6604ceL, 0xaba46ef9L, 0xaeeb787cL, 0xaf29124bL, + 0xad6fac12L, 0xacadc625L, 0xa7f18118L, 0xa633eb2fL, 0xa4755576L, + 0xa5b73f41L, 0xa0f829c4L, 0xa13a43f3L, 0xa37cfdaaL, 0xa2be979dL, + 0xb5c473d0L, 0xb40619e7L, 0xb640a7beL, 0xb782cd89L, 0xb2cddb0cL, + 0xb30fb13bL, 0xb1490f62L, 0xb08b6555L, 0xbbd72268L, 0xba15485fL, + 0xb853f606L, 0xb9919c31L, 0xbcde8ab4L, 0xbd1ce083L, 0xbf5a5edaL, + 0xbe9834edL + , + 0x00000000L, 0xb8bc6765L, 0xaa09c88bL, 0x12b5afeeL, 0x8f629757L, + 0x37def032L, 0x256b5fdcL, 0x9dd738b9L, 0xc5b428efL, 0x7d084f8aL, + 0x6fbde064L, 0xd7018701L, 0x4ad6bfb8L, 0xf26ad8ddL, 0xe0df7733L, + 0x58631056L, 0x5019579fL, 0xe8a530faL, 0xfa109f14L, 0x42acf871L, + 0xdf7bc0c8L, 0x67c7a7adL, 0x75720843L, 0xcdce6f26L, 0x95ad7f70L, + 0x2d111815L, 0x3fa4b7fbL, 0x8718d09eL, 0x1acfe827L, 0xa2738f42L, + 0xb0c620acL, 0x087a47c9L, 0xa032af3eL, 0x188ec85bL, 0x0a3b67b5L, + 0xb28700d0L, 0x2f503869L, 0x97ec5f0cL, 0x8559f0e2L, 0x3de59787L, + 0x658687d1L, 0xdd3ae0b4L, 0xcf8f4f5aL, 0x7733283fL, 0xeae41086L, + 0x525877e3L, 0x40edd80dL, 0xf851bf68L, 0xf02bf8a1L, 0x48979fc4L, + 0x5a22302aL, 0xe29e574fL, 0x7f496ff6L, 0xc7f50893L, 0xd540a77dL, + 0x6dfcc018L, 0x359fd04eL, 0x8d23b72bL, 0x9f9618c5L, 0x272a7fa0L, + 0xbafd4719L, 0x0241207cL, 0x10f48f92L, 0xa848e8f7L, 0x9b14583dL, + 0x23a83f58L, 0x311d90b6L, 0x89a1f7d3L, 0x1476cf6aL, 0xaccaa80fL, + 0xbe7f07e1L, 0x06c36084L, 0x5ea070d2L, 0xe61c17b7L, 0xf4a9b859L, + 0x4c15df3cL, 0xd1c2e785L, 0x697e80e0L, 0x7bcb2f0eL, 0xc377486bL, + 0xcb0d0fa2L, 0x73b168c7L, 0x6104c729L, 0xd9b8a04cL, 0x446f98f5L, + 0xfcd3ff90L, 0xee66507eL, 0x56da371bL, 0x0eb9274dL, 0xb6054028L, + 0xa4b0efc6L, 0x1c0c88a3L, 0x81dbb01aL, 0x3967d77fL, 0x2bd27891L, + 0x936e1ff4L, 0x3b26f703L, 0x839a9066L, 0x912f3f88L, 0x299358edL, + 0xb4446054L, 0x0cf80731L, 0x1e4da8dfL, 0xa6f1cfbaL, 0xfe92dfecL, + 0x462eb889L, 0x549b1767L, 0xec277002L, 0x71f048bbL, 0xc94c2fdeL, + 0xdbf98030L, 0x6345e755L, 0x6b3fa09cL, 0xd383c7f9L, 0xc1366817L, + 0x798a0f72L, 0xe45d37cbL, 0x5ce150aeL, 0x4e54ff40L, 0xf6e89825L, + 0xae8b8873L, 0x1637ef16L, 0x048240f8L, 0xbc3e279dL, 0x21e91f24L, + 0x99557841L, 0x8be0d7afL, 0x335cb0caL, 0xed59b63bL, 0x55e5d15eL, + 0x47507eb0L, 0xffec19d5L, 0x623b216cL, 0xda874609L, 0xc832e9e7L, + 0x708e8e82L, 0x28ed9ed4L, 0x9051f9b1L, 0x82e4565fL, 0x3a58313aL, + 0xa78f0983L, 0x1f336ee6L, 0x0d86c108L, 0xb53aa66dL, 0xbd40e1a4L, + 0x05fc86c1L, 0x1749292fL, 0xaff54e4aL, 0x322276f3L, 0x8a9e1196L, + 0x982bbe78L, 0x2097d91dL, 0x78f4c94bL, 0xc048ae2eL, 0xd2fd01c0L, + 0x6a4166a5L, 0xf7965e1cL, 0x4f2a3979L, 0x5d9f9697L, 0xe523f1f2L, + 0x4d6b1905L, 0xf5d77e60L, 0xe762d18eL, 0x5fdeb6ebL, 0xc2098e52L, + 0x7ab5e937L, 0x680046d9L, 0xd0bc21bcL, 0x88df31eaL, 0x3063568fL, + 0x22d6f961L, 0x9a6a9e04L, 0x07bda6bdL, 0xbf01c1d8L, 0xadb46e36L, + 0x15080953L, 0x1d724e9aL, 0xa5ce29ffL, 0xb77b8611L, 0x0fc7e174L, + 0x9210d9cdL, 0x2aacbea8L, 0x38191146L, 0x80a57623L, 0xd8c66675L, + 0x607a0110L, 0x72cfaefeL, 0xca73c99bL, 0x57a4f122L, 0xef189647L, + 0xfdad39a9L, 0x45115eccL, 0x764dee06L, 0xcef18963L, 0xdc44268dL, + 0x64f841e8L, 0xf92f7951L, 0x41931e34L, 0x5326b1daL, 0xeb9ad6bfL, + 0xb3f9c6e9L, 0x0b45a18cL, 0x19f00e62L, 0xa14c6907L, 0x3c9b51beL, + 0x842736dbL, 0x96929935L, 0x2e2efe50L, 0x2654b999L, 0x9ee8defcL, + 0x8c5d7112L, 0x34e11677L, 0xa9362eceL, 0x118a49abL, 0x033fe645L, + 0xbb838120L, 0xe3e09176L, 0x5b5cf613L, 0x49e959fdL, 0xf1553e98L, + 0x6c820621L, 0xd43e6144L, 0xc68bceaaL, 0x7e37a9cfL, 0xd67f4138L, + 0x6ec3265dL, 0x7c7689b3L, 0xc4caeed6L, 0x591dd66fL, 0xe1a1b10aL, + 0xf3141ee4L, 0x4ba87981L, 0x13cb69d7L, 0xab770eb2L, 0xb9c2a15cL, + 0x017ec639L, 0x9ca9fe80L, 0x241599e5L, 0x36a0360bL, 0x8e1c516eL, + 0x866616a7L, 0x3eda71c2L, 0x2c6fde2cL, 0x94d3b949L, 0x090481f0L, + 0xb1b8e695L, 0xa30d497bL, 0x1bb12e1eL, 0x43d23e48L, 0xfb6e592dL, + 0xe9dbf6c3L, 0x516791a6L, 0xccb0a91fL, 0x740cce7aL, 0x66b96194L, + 0xde0506f1L +# endif /* IZ_CRCOPTIM_UNFOLDTBL */ +# endif /* ? IZ_CRC_BE_OPTIMIZ */ +}; +#endif /* ?DYNAMIC_CRC_TABLE */ + +/* use "OF((void))" here to work around a Borland TC++ 1.0 problem */ +#ifdef USE_ZLIB +ZCONST uLongf *get_crc_table OF((void)) +#else +ZCONST ulg near *get_crc_table OF((void)) +#endif +{ +#ifdef DYNAMIC_CRC_TABLE + if (CRC_TABLE_IS_EMPTY) + make_crc_table(); +#endif +#ifdef USE_ZLIB + return (ZCONST uLongf *)crc_table; +#else + return crc_table; +#endif +} + +#ifdef DYNALLOC_CRCTAB +void free_crc_table() +{ + if (!CRC_TABLE_IS_EMPTY) + { + nearfree((ulg near *)crc_table); + MARK_CRCTAB_EMPTY; + } +} +#endif + +#ifndef USE_ZLIB +#ifndef CRC_TABLE_ONLY +#ifndef ASM_CRC + +#define DO1(crc, buf) crc = CRC32(crc, *buf++, crc_32_tab) +#define DO2(crc, buf) DO1(crc, buf); DO1(crc, buf) +#define DO4(crc, buf) DO2(crc, buf); DO2(crc, buf) +#define DO8(crc, buf) DO4(crc, buf); DO4(crc, buf) + +#if (defined(IZ_CRC_BE_OPTIMIZ) || defined(IZ_CRC_LE_OPTIMIZ)) + +# ifdef IZ_CRCOPTIM_UNFOLDTBL +# ifdef IZ_CRC_BE_OPTIMIZ +# define DO_OPT4(c, buf4) c ^= *(buf4)++; \ + c = crc_32_tab[c & 0xff] ^ crc_32_tab[256+((c>>8) & 0xff)] ^ \ + crc_32_tab[2*256+((c>>16) & 0xff)] ^ crc_32_tab[3*256+(c>>24)] +# else /* !IZ_CRC_BE_OPTIMIZ */ +# define DO_OPT4(c, buf4) c ^= *(buf4)++; \ + c = crc_32_tab[3*256+(c & 0xff)] ^ crc_32_tab[2*256+((c>>8) & 0xff)] \ + ^ crc_32_tab[256+((c>>16) & 0xff)] ^ crc_32_tab[c>>24] +# endif /* ?IZ_CRC_BE_OPTIMIZ */ +# else /* !IZ_CRCOPTIM_UNFOLDTBL */ +# define DO_OPT4(c, buf4) c ^= *(buf4)++; \ + c = CRC32UPD(c, crc_32_tab); \ + c = CRC32UPD(c, crc_32_tab); \ + c = CRC32UPD(c, crc_32_tab); \ + c = CRC32UPD(c, crc_32_tab) +# endif /* ?IZ_CRCOPTIM_UNFOLDTBL */ + +# define DO_OPT16(crc, buf4) DO_OPT4(crc, buf4); DO_OPT4(crc, buf4); \ + DO_OPT4(crc, buf4); DO_OPT4(crc, buf4); + +#endif /* (IZ_CRC_BE_OPTIMIZ || IZ_CRC_LE_OPTIMIZ) */ + + +/* ========================================================================= */ +ulg crc32(crc, buf, len) + ulg crc; /* crc shift register */ + register ZCONST uch *buf; /* pointer to bytes to pump through */ + extent len; /* number of bytes in buf[] */ +/* Run a set of bytes through the crc shift register. If buf is a NULL + pointer, then initialize the crc shift register contents instead. + Return the current crc in either case. */ +{ + register z_uint4 c; + register ZCONST ulg near *crc_32_tab; + + if (buf == NULL) return 0L; + + crc_32_tab = get_crc_table(); + + c = (REV_BE((z_uint4)crc) ^ 0xffffffffL); + +#if (defined(IZ_CRC_BE_OPTIMIZ) || defined(IZ_CRC_LE_OPTIMIZ)) + /* Align buf pointer to next DWORD boundary. */ + while (len && ((ptrdiff_t)buf & 3)) { + DO1(c, buf); + len--; + } + { + ZCONST z_uint4 *buf4 = (ZCONST z_uint4 *)buf; + while (len >= 16) { + DO_OPT16(c, buf4); + len -= 16; + } + while (len >= 4) { + DO_OPT4(c, buf4); + len -= 4; + } + buf = (ZCONST uch *)buf4; + } +#else /* !(IZ_CRC_BE_OPTIMIZ || IZ_CRC_LE_OPTIMIZ) */ +#ifndef NO_UNROLLED_LOOPS + while (len >= 8) { + DO8(c, buf); + len -= 8; + } +#endif /* !NO_UNROLLED_LOOPS */ +#endif /* ?(IZ_CRC_BE_OPTIMIZ || IZ_CRC_LE_OPTIMIZ) */ + if (len) do { + DO1(c, buf); + } while (--len); + + return REV_BE(c) ^ 0xffffffffL; /* (instead of ~c for 64-bit machines) */ +} +#endif /* !ASM_CRC */ +#endif /* !CRC_TABLE_ONLY */ +#endif /* !USE_ZLIB */ +#endif /* !USE_ZLIB || USE_OWN_CRCTAB */ diff --git a/crc32.h b/crc32.h new file mode 100644 index 0000000..83af240 --- /dev/null +++ b/crc32.h @@ -0,0 +1,60 @@ +/* + Copyright (c) 1990-2008 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* crc32.h -- compute the CRC-32 of a data stream + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef __crc32_h +#define __crc32_h /* identifies this source module */ + +/* This header should be read AFTER zip.h resp. unzip.h + * (the latter with UNZIP_INTERNAL defined...). + */ + +#ifndef OF +# define OF(a) a +#endif +#ifndef ZCONST +# define ZCONST const +#endif + +#ifdef DYNALLOC_CRCTAB + void free_crc_table OF((void)); +#endif +#ifndef USE_ZLIB + ZCONST ulg near *get_crc_table OF((void)); +#endif +#if (defined(USE_ZLIB) || defined(CRC_TABLE_ONLY)) +# ifdef IZ_CRC_BE_OPTIMIZ +# undef IZ_CRC_BE_OPTIMIZ +# endif +#else /* !(USE_ZLIB || CRC_TABLE_ONLY) */ + ulg crc32 OF((ulg crc, ZCONST uch *buf, extent len)); +#endif /* ?(USE_ZLIB || CRC_TABLE_ONLY) */ + +#ifndef CRC_32_TAB +# define CRC_32_TAB crc_32_tab +#endif + +#ifdef CRC32 +# undef CRC32 +#endif +#ifdef IZ_CRC_BE_OPTIMIZ +# define CRC32UPD(c, crctab) (crctab[((c) >> 24)] ^ ((c) << 8)) +# define CRC32(c, b, crctab) (crctab[(((int)(c) >> 24) ^ (b))] ^ ((c) << 8)) +# define REV_BE(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ + (((w)&0xff00)<<8)+(((w)&0xff)<<24)) +#else +# define CRC32UPD(c, crctab) (crctab[((int)(c)) & 0xff] ^ ((c) >> 8)) +# define CRC32(c, b, crctab) (crctab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8)) +# define REV_BE(w) w +#endif + +#endif /* !__crc32_h */ diff --git a/crc_i386.S b/crc_i386.S new file mode 100644 index 0000000..38dbc86 --- /dev/null +++ b/crc_i386.S @@ -0,0 +1,304 @@ +/* + Copyright (c) 1990-2007 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + * crc_i386.S, optimized CRC calculation function for Zip and UnZip, + * created by Paul Kienitz and Christian Spieler. Last revised 07 Jan 2007. + * + * GRR 961110: incorporated Scott Field optimizations from win32/crc_i386.asm + * => overall 6% speedup in "unzip -tq" on 9MB zipfile (486-66) + * + * SPC 970402: revised for Rodney Brown's optimizations (32-bit-wide + * aligned reads for most of the data from buffer), can be + * disabled by defining the macro NO_32_BIT_LOADS + * + * SPC 971012: added Rodney Brown's additional tweaks for 32-bit-optimized + * CPUs (like the Pentium Pro, Pentium II, and probably some + * Pentium clones). This optimization is controlled by the + * preprocessor switch "__686" and is disabled by default. + * (This default is based on the assumption that most users + * do not yet work on a Pentium Pro or Pentium II machine ...) + * + * COS 050116: Enabled the 686 build by default, because there are hardly any + * pre-686 CPUs in serious use nowadays. (See SPC 970402 above.) + * + * SPC 060103: Updated code to incorporate newer optimizations found in zlib. + * + * SPC 070107: Added conditional switch to deactivate crc32() compilation. + * + * FLAT memory model assumed. Calling interface: + * - args are pushed onto the stack from right to left, + * - return value is given in the EAX register, + * - all other registers (with exception of EFLAGS) are preserved. (With + * GNU C 2.7.x, %edx and %ecx are `scratch' registers, but preserving + * them nevertheless adds only 4 single byte instructions.) + * + * This source generates the function + * ulg crc32(ulg crc, ZCONST uch *buf, extent len). + * + * Loop unrolling can be disabled by defining the macro NO_UNROLLED_LOOPS. + * This results in shorter code at the expense of reduced performance. + */ + +/* This file is NOT used in conjunction with zlib, or when only creation of + * the basic CRC_32_Table (for other purpose) is requested. + */ +#if !defined(USE_ZLIB) && !defined(CRC_TABLE_ONLY) + +/* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix + * external symbols with an underline character '_'. + */ +#if defined(NO_UNDERLINE) || defined(__ELF__) +# define _crc32 crc32 +# define _get_crc_table get_crc_table +#endif +/* Use 16-byte alignment if your assembler supports it. Warning: gas + * uses a log(x) parameter (.align 4 means 16-byte alignment). On SVR4 + * the parameter is a number of bytes. + */ +#ifndef ALIGNMENT +# define ALIGNMENT .align 4,0x90 +#endif + +#if defined(i386) || defined(_i386) || defined(_I386) || defined(__i386) + +/* This version is for 386 Unix, OS/2, MSDOS in 32 bit mode (gcc & gas). + * Warning: it uses the AT&T syntax: mov source,dest + * This file is only optional. If you want to use the C version, + * remove -DASM_CRC from CFLAGS in Makefile and set OBJA to an empty string. + */ + + .file "crc_i386.S" + +#if !defined(PRE_686) && !defined(__686) + /* Optimize for Pentium Pro and compatible CPUs by default. */ +# define __686 +#endif + +#if defined(NO_STD_STACKFRAME) && defined(USE_STD_STACKFRAME) +# undef USE_STACKFRAME +#else + /* The default is to use standard stack frame entry, because it + * results in smaller code! + */ +# ifndef USE_STD_STACKFRAME +# define USE_STD_STACKFRAME +# endif +#endif + +#ifdef USE_STD_STACKFRAME +# define _STD_ENTRY pushl %ebp ; movl %esp,%ebp +# define arg1 8(%ebp) +# define arg2 12(%ebp) +# define arg3 16(%ebp) +# define _STD_LEAVE popl %ebp +#else /* !USE_STD_STACKFRAME */ +# define _STD_ENTRY +# define arg1 24(%esp) +# define arg2 28(%esp) +# define arg3 32(%esp) +# define _STD_LEAVE +#endif /* ?USE_STD_STACKFRAME */ + +/* + * These two (three) macros make up the loop body of the CRC32 cruncher. + * registers modified: + * eax : crc value "c" + * esi : pointer to next data byte (or lword) "buf++" + * registers read: + * edi : pointer to base of crc_table array + * scratch registers: + * ebx : index into crc_table array + * (requires upper three bytes = 0 when __686 is undefined) + */ +#ifndef __686 /* optimize for 386, 486, Pentium */ +#define Do_CRC /* c = (c >> 8) ^ table[c & 0xFF] */\ + movb %al, %bl ;/* tmp = c & 0xFF */\ + shrl $8, %eax ;/* c = (c >> 8) */\ + xorl (%edi, %ebx, 4), %eax ;/* c ^= table[tmp] */ +#else /* __686 : optimize for Pentium Pro and compatible CPUs */ +#define Do_CRC /* c = (c >> 8) ^ table[c & 0xFF] */\ + movzbl %al, %ebx ;/* tmp = c & 0xFF */\ + shrl $8, %eax ;/* c = (c >> 8) */\ + xorl (%edi, %ebx, 4), %eax ;/* c ^=table[tmp] */ +#endif /* ?__686 */ + +#define Do_CRC_byte /* c = (c >> 8) ^ table[(c^*buf++)&0xFF] */\ + xorb (%esi), %al ;/* c ^= *buf */\ + incl %esi ;/* buf++ */\ + Do_CRC + +#define Do_CRC_byteof(ofs) /* c = (c >> 8) ^ table[(c^*buf++)&0xFF] */\ + xorb ofs(%esi), %al ;/* c ^= *buf */\ + incl %esi ;/* buf++ */\ + Do_CRC + +#ifndef NO_32_BIT_LOADS +# ifdef IZ_CRCOPTIM_UNFOLDTBL + /* the edx register is needed in crc calculation */ +# define SavLen arg3 +# define UpdCRC_lword \ + movzbl %al, %ebx ; \ + movl 3072(%edi,%ebx,4), %edx ; \ + movzbl %ah, %ebx ; \ + shrl $16, %eax ; \ + xor 2048(%edi,%ebx,4), %edx ; \ + movzbl %al, %ebx ; \ + shrl $8,%eax ; \ + xorl 1024(%edi,%ebx,4), %edx ; \ + movl (%edi,%eax,4), %eax ; \ + xorl %edx,%eax ; +# define UpdCRC_lword_sh(dwPtrIncr) \ + movzbl %al, %ebx ; \ + movl 3072(%edi,%ebx,4), %edx ; \ + movzbl %ah, %ebx ; \ + shrl $16, %eax ; \ + xor 2048(%edi,%ebx,4), %edx ; \ + movzbl %al, %ebx ; \ + addl $4*(dwPtrIncr), %esi ;/* ((ulg *)buf)+=dwPtrIncr */\ + shrl $8,%eax ; \ + xorl 1024(%edi,%ebx,4), %edx ; \ + movl (%edi,%eax,4),%eax ; \ + xorl %edx,%eax ; +# else /* !IZ_CRCOPTIM_UNFOLDTBL */ + /* the edx register is not needed anywhere else */ +# define SavLen %edx +# define UpdCRC_lword \ + Do_CRC \ + Do_CRC \ + Do_CRC \ + Do_CRC +# define UpdCRC_lword_sh(dwPtrIncr) \ + Do_CRC \ + Do_CRC \ + addl $4*(dwPtrIncr), %esi ;/* ((ulg *)buf)++ */\ + Do_CRC \ + Do_CRC +# endif /* ?IZ_CRCOPTIM_UNFOLDTBL */ +#define Do_CRC_lword \ + xorl (%esi), %eax ;/* c ^= *(ulg *)buf */\ + UpdCRC_lword_sh(1) /* ... ((ulg *)buf)++ */ +#define Do_CRC_4lword \ + xorl (%esi), %eax ;/* c ^= *(ulg *)buf */\ + UpdCRC_lword \ + xorl 4(%esi), %eax ;/* c ^= *((ulg *)buf+1) */\ + UpdCRC_lword \ + xorl 8(%esi), %eax ;/* c ^= *((ulg *)buf+2) */\ + UpdCRC_lword \ + xorl 12(%esi), %eax ;/* c ^= *((ulg *)buf]+3 */\ + UpdCRC_lword_sh(4) /* ... ((ulg *)buf)+=4 */ +#endif /* !NO_32_BIT_LOADS */ + + + .text + + .globl _crc32 + +_crc32: /* ulg crc32(ulg crc, uch *buf, extent len) */ + _STD_ENTRY + pushl %edi + pushl %esi + pushl %ebx + pushl %edx + pushl %ecx + + movl arg2, %esi /* 2nd arg: uch *buf */ + subl %eax, %eax /* > if (!buf) */ + testl %esi, %esi /* > return 0; */ + jz .L_fine /* > else { */ + call _get_crc_table + movl %eax, %edi + movl arg1, %eax /* 1st arg: ulg crc */ +#ifndef __686 + subl %ebx, %ebx /* ebx=0; bl usable as dword */ +#endif + movl arg3, %ecx /* 3rd arg: extent len */ + notl %eax /* > c = ~crc; */ + + testl %ecx, %ecx +#ifndef NO_UNROLLED_LOOPS + jz .L_bail +# ifndef NO_32_BIT_LOADS + /* Assert now have positive length */ +.L_align_loop: + testl $3, %esi /* Align buf on lword boundary */ + jz .L_aligned_now + Do_CRC_byte + decl %ecx + jnz .L_align_loop +.L_aligned_now: +# endif /* !NO_32_BIT_LOADS */ + movl %ecx, SavLen /* save current value of len */ + shrl $4, %ecx /* ecx = len / 16 */ + jz .L_No_Sixteens +/* align loop head at start of 486 internal cache line !! */ + ALIGNMENT +.L_Next_Sixteen: +# ifndef NO_32_BIT_LOADS + Do_CRC_4lword +# else /* NO_32_BIT_LOADS */ + Do_CRC_byteof(0) + Do_CRC_byteof(1) + Do_CRC_byteof(2) + Do_CRC_byteof(3) + Do_CRC_byteof(4) + Do_CRC_byteof(5) + Do_CRC_byteof(6) + Do_CRC_byteof(7) + Do_CRC_byteof(8) + Do_CRC_byteof(9) + Do_CRC_byteof(10) + Do_CRC_byteof(11) + Do_CRC_byteof(12) + Do_CRC_byteof(13) + Do_CRC_byteof(14) + Do_CRC_byteof(15) + addl $16,%esi ;/* buf += 16 */ +# endif /* ?NO_32_BIT_LOADS */ + decl %ecx + jnz .L_Next_Sixteen + +.L_No_Sixteens: + movl SavLen, %ecx + andl $15, %ecx /* ecx = len % 16 */ +# ifndef NO_32_BIT_LOADS + shrl $2,%ecx /* ecx = len / 4 */ + jz .L_No_Fours +.L_Next_Four: + Do_CRC_lword + decl %ecx + jnz .L_Next_Four +.L_No_Fours: + movl SavLen,%ecx + andl $3,%ecx /* ecx = len % 4 */ +# endif /* !NO_32_BIT_LOADS */ +#endif /* !NO_UNROLLED_LOOPS */ + jz .L_bail /* > if (len) */ +/* align loop head at start of 486 internal cache line !! */ + ALIGNMENT +.L_loupe: /* > do { */ + Do_CRC_byte /* c = CRC32(c,*buf++,crctab);*/ + decl %ecx /* > } while (--len); */ + jnz .L_loupe + +.L_bail: /* > } */ + notl %eax /* > return ~c; */ +.L_fine: + popl %ecx + popl %edx + popl %ebx + popl %esi + popl %edi + _STD_LEAVE + ret + +#else + error: this asm version is for 386 only +#endif /* i386 || _i386 || _I386 || __i386 */ + +#endif /* !USE_ZLIB && !CRC_TABLE_ONLY */ diff --git a/crypt.c b/crypt.c new file mode 100644 index 0000000..cc974ec --- /dev/null +++ b/crypt.c @@ -0,0 +1,690 @@ +/* + Copyright (c) 1990-2008 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] + + The main encryption/decryption source code for Info-Zip software was + originally written in Europe. To the best of our knowledge, it can + be freely distributed in both source and object forms from any country, + including the USA under License Exception TSU of the U.S. Export + Administration Regulations (section 740.13(e)) of 6 June 2002. + + NOTE on copyright history: + Previous versions of this source package (up to version 2.8) were + not copyrighted and put in the public domain. If you cannot comply + with the Info-Zip LICENSE, you may want to look for one of those + public domain versions. + */ + +/* + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + */ + +#define ZCRYPT_INTERNAL +#include "zip.h" +#include "crypt.h" +#include "ttyio.h" + +#if CRYPT + +#ifndef FALSE +# define FALSE 0 +#endif + +#ifdef ZIP + /* For the encoding task used in Zip (and ZipCloak), we want to initialize + the crypt algorithm with some reasonably unpredictable bytes, see + the crypthead() function. The standard rand() library function is + used to supply these `random' bytes, which in turn is initialized by + a srand() call. The srand() function takes an "unsigned" (at least 16bit) + seed value as argument to determine the starting point of the rand() + pseudo-random number generator. + This seed number is constructed as "Seed = Seed1 .XOR. Seed2" with + Seed1 supplied by the current time (= "(unsigned)time()") and Seed2 + as some (hopefully) nondeterministic bitmask. On many (most) systems, + we use some "process specific" number, as the PID or something similar, + but when nothing unpredictable is available, a fixed number may be + sufficient. + NOTE: + 1.) This implementation requires the availability of the following + standard UNIX C runtime library functions: time(), rand(), srand(). + On systems where some of them are missing, the environment that + incorporates the crypt routines must supply suitable replacement + functions. + 2.) It is a very bad idea to use a second call to time() to set the + "Seed2" number! In this case, both "Seed1" and "Seed2" would be + (almost) identical, resulting in a (mostly) "zero" constant seed + number passed to srand(). + + The implementation environment defined in the "zip.h" header should + supply a reasonable definition for ZCR_SEED2 (an unsigned number; for + most implementations of rand() and srand(), only the lower 16 bits are + significant!). An example that works on many systems would be + "#define ZCR_SEED2 (unsigned)getpid()". + The default definition for ZCR_SEED2 supplied below should be regarded + as a fallback to allow successful compilation in "beta state" + environments. + */ +# include /* time() function supplies first part of crypt seed */ + /* "last resort" source for second part of crypt seed pattern */ +# ifndef ZCR_SEED2 +# define ZCR_SEED2 (unsigned)3141592654L /* use PI as default pattern */ +# endif +# ifdef GLOBAL /* used in Amiga system headers, maybe others too */ +# undef GLOBAL +# endif +# define GLOBAL(g) g +#else /* !ZIP */ +# define GLOBAL(g) G.g +#endif /* ?ZIP */ + + +#ifdef UNZIP + /* char *key = (char *)NULL; moved to globals.h */ +# ifndef FUNZIP + local int testp OF((__GPRO__ ZCONST uch *h)); + local int testkey OF((__GPRO__ ZCONST uch *h, ZCONST char *key)); +# endif +#else /* def UNZIP */ /* moved to globals.h for UnZip */ + local z_uint4 keys[3]; /* keys defining the pseudo-random sequence */ +#endif /* def UNZIP [else] */ + +#ifndef Trace +# ifdef CRYPT_DEBUG +# define Trace(x) fprintf x +# else +# define Trace(x) +# endif +#endif + +#include "crc32.h" + +#ifdef IZ_CRC_BE_OPTIMIZ + local z_uint4 near crycrctab[256]; + local z_uint4 near *cry_crctb_p = NULL; + local z_uint4 near *crytab_init OF((__GPRO)); +# define CRY_CRC_TAB cry_crctb_p +# undef CRC32 +# define CRC32(c, b, crctab) (crctab[((int)(c) ^ (b)) & 0xff] ^ ((c) >> 8)) +#else +# define CRY_CRC_TAB CRC_32_TAB +#endif /* ?IZ_CRC_BE_OPTIMIZ */ + +/*********************************************************************** + * Return the next byte in the pseudo-random sequence + */ +int decrypt_byte(__G) + __GDEF +{ + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an + * unpredictable manner on 16-bit systems; not a problem + * with any known compiler so far, though */ + + temp = ((unsigned)GLOBAL(keys[2]) & 0xffff) | 2; + return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); +} + +/*********************************************************************** + * Update the encryption keys with the next byte of plain text + */ +int update_keys(__G__ c) + __GDEF + int c; /* byte of plain text */ +{ + GLOBAL(keys[0]) = CRC32(GLOBAL(keys[0]), c, CRY_CRC_TAB); + GLOBAL(keys[1]) = (GLOBAL(keys[1]) + + (GLOBAL(keys[0]) & 0xff)) + * 134775813L + 1; + { + register int keyshift = (int)(GLOBAL(keys[1]) >> 24); + GLOBAL(keys[2]) = CRC32(GLOBAL(keys[2]), keyshift, CRY_CRC_TAB); + } + return c; +} + + +/*********************************************************************** + * Initialize the encryption keys and the random header according to + * the given password. + */ +void init_keys(__G__ passwd) + __GDEF + ZCONST char *passwd; /* password string with which to modify keys */ +{ +#ifdef IZ_CRC_BE_OPTIMIZ + if (cry_crctb_p == NULL) { + cry_crctb_p = crytab_init(__G); + } +#endif + GLOBAL(keys[0]) = 305419896L; + GLOBAL(keys[1]) = 591751049L; + GLOBAL(keys[2]) = 878082192L; + while (*passwd != '\0') { + update_keys(__G__ (int)*passwd); + passwd++; + } +} + + +/*********************************************************************** + * Initialize the local copy of the table of precomputed crc32 values. + * Whereas the public crc32-table is optimized for crc32 calculations + * on arrays of bytes, the crypt code needs the crc32 values in an + * byte-order-independent form as 32-bit unsigned numbers. On systems + * with Big-Endian byte order using the optimized crc32 code, this + * requires inverting the byte-order of the values in the + * crypt-crc32-table. + */ +#ifdef IZ_CRC_BE_OPTIMIZ +local z_uint4 near *crytab_init(__G) + __GDEF +{ + int i; + + for (i = 0; i < 256; i++) { + crycrctab[i] = REV_BE(CRC_32_TAB[i]); + } + return crycrctab; +} +#endif + + +#ifdef ZIP + +/*********************************************************************** + * Write encryption header to file zfile using the password passwd + * and the cyclic redundancy check crc. + */ +void crypthead(passwd, crc) + ZCONST char *passwd; /* password string */ + ulg crc; /* crc of file being encrypted */ +{ + int n; /* index in random header */ + int t; /* temporary */ + int c; /* random byte */ + uch header[RAND_HEAD_LEN]; /* random header */ + static unsigned calls = 0; /* ensure different random header each time */ + + /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the + * output of rand() to get less predictability, since rand() is + * often poorly implemented. + */ + if (++calls == 1) { + srand((unsigned)time(NULL) ^ ZCR_SEED2); + } + init_keys(passwd); + for (n = 0; n < RAND_HEAD_LEN-2; n++) { + c = (rand() >> 7) & 0xff; + header[n] = (uch)zencode(c, t); + } + /* Encrypt random header (last two bytes is high word of crc) */ + init_keys(passwd); + for (n = 0; n < RAND_HEAD_LEN-2; n++) { + header[n] = (uch)zencode(header[n], t); + } + header[RAND_HEAD_LEN-2] = (uch)zencode((int)(crc >> 16) & 0xff, t); + header[RAND_HEAD_LEN-1] = (uch)zencode((int)(crc >> 24) & 0xff, t); + bfwrite(header, 1, RAND_HEAD_LEN, BFWRITE_DATA); +} + + +#ifdef UTIL + +/*********************************************************************** + * Encrypt the zip entry described by z from file in_file to file y + * using the password passwd. Return an error code in the ZE_ class. + */ +int zipcloak(z, passwd) + struct zlist far *z; /* zip entry to encrypt */ + ZCONST char *passwd; /* password string */ +{ + int c; /* input byte */ + int res; /* result code */ + zoff_t n; /* holds offset and counts size */ + int t; /* temporary */ + struct zlist far *localz; /* local header */ + uch buf[1024]; /* write buffer */ + int b; /* bytes in buffer */ + + /* Set encrypted bit, clear extended local header bit and write local + header to output file */ + if ((n = (zoff_t)zftello(y)) == (zoff_t)-1L) return ZE_TEMP; + + /* assume this archive is one disk and the file is open */ + + /* read the local header */ + res = readlocal(&localz, z); + + /* update disk and offset */ + z->dsk = 0; + z->off = n; + + /* Set encryption and unset any extended local header */ + z->flg |= 1, z->flg &= ~8; + localz->lflg |= 1, localz->lflg &= ~8; + + /* Add size of encryption header */ + localz->siz += RAND_HEAD_LEN; + z->siz = localz->siz; + + /* Put the local header */ + if ((res = putlocal(localz, PUTLOCAL_WRITE)) != ZE_OK) return res; + + /* Initialize keys with password and write random header */ + crypthead(passwd, localz->crc); + + /* Encrypt data */ + b = 0; + for (n = z->siz - RAND_HEAD_LEN; n; n--) { + if ((c = getc(in_file)) == EOF) { + return ferror(in_file) ? ZE_READ : ZE_EOF; + } + buf[b] = (uch)zencode(c, t); + b++; + if (b >= 1024) { + /* write the buffer */ + bfwrite(buf, 1, b, BFWRITE_DATA); + b = 0; + } + } + if (b) { + /* write the buffer */ + bfwrite(buf, 1, b, BFWRITE_DATA); + b = 0; + } + + /* Since we seek to the start of each local header can skip + reading any extended local header */ + /* + if ((flag & 8) != 0 && zfseeko(in_file, 16L, SEEK_CUR)) { + return ferror(in_file) ? ZE_READ : ZE_EOF; + } + if (fflush(y) == EOF) return ZE_TEMP; + */ + + /* Update number of bytes written to output file */ + tempzn += (4 + LOCHEAD) + localz->nam + localz->ext + localz->siz; + + /* Free local header */ + if (localz->ext) free(localz->extra); + if (localz->nam) free(localz->iname); + if (localz->nam) free(localz->name); +#ifdef UNICODE_SUPPORT + if (localz->uname) free(localz->uname); +#endif + free(localz); + + return ZE_OK; +} + +/*********************************************************************** + * Decrypt the zip entry described by z from file in_file to file y + * using the password passwd. Return an error code in the ZE_ class. + */ +int zipbare(z, passwd) + struct zlist far *z; /* zip entry to encrypt */ + ZCONST char *passwd; /* password string */ +{ +#ifdef ZIP10 + int c0 /* byte preceding the last input byte */ +#endif + int c1; /* last input byte */ + /* all file offset and size now zoff_t - 8/28/04 EG */ + zoff_t size; /* size of input data */ + struct zlist far *localz; /* local header */ + uch buf[1024]; /* write buffer */ + int b; /* bytes in buffer */ + zoff_t n; + int r; /* size of encryption header */ + int res; /* return code */ + + /* Save position */ + if ((n = (zoff_t)zftello(y)) == (zoff_t)-1L) return ZE_TEMP; + + /* Read local header */ + res = readlocal(&localz, z); + + /* Update disk and offset */ + z->dsk = 0; + z->off = n; + + /* Initialize keys with password */ + init_keys(passwd); + + /* Decrypt encryption header, save last two bytes */ + c1 = 0; + for (r = RAND_HEAD_LEN; r; r--) { +#ifdef ZIP10 + c0 = c1; +#endif + if ((c1 = getc(in_file)) == EOF) { + return ferror(in_file) ? ZE_READ : ZE_EOF; + } + Trace((stdout, " (%02x)", c1)); + zdecode(c1); + Trace((stdout, " %02x", c1)); + } + Trace((stdout, "\n")); + + /* If last two bytes of header don't match crc (or file time in the + * case of an extended local header), back up and just copy. For + * pkzip 2.0, the check has been reduced to one byte only. + */ +#ifdef ZIP10 + if ((ush)(c0 | (c1<<8)) != + (z->flg & 8 ? (ush) z->tim & 0xffff : (ush)(z->crc >> 16))) { +#else + if ((ush)c1 != (z->flg & 8 ? (ush) z->tim >> 8 : (ush)(z->crc >> 24))) { +#endif + if (zfseeko(in_file, n, SEEK_SET)) { + return ferror(in_file) ? ZE_READ : ZE_EOF; + } + if ((res = zipcopy(z)) != ZE_OK) { + ziperr(res, "was copying an entry"); + } + return ZE_MISS; + } + + z->siz -= RAND_HEAD_LEN; + localz->siz = z->siz; + + localz->flg = z->flg &= ~9; + z->lflg = localz->lflg &= ~9; + + if ((res = putlocal(localz, PUTLOCAL_WRITE)) != ZE_OK) return res; + + /* Decrypt data */ + b = 0; + for (size = z->siz; size; size--) { + if ((c1 = getc(in_file)) == EOF) { + return ferror(in_file) ? ZE_READ : ZE_EOF; + } + zdecode(c1); + buf[b] = c1; + b++; + if (b >= 1024) { + /* write the buffer */ + bfwrite(buf, 1, b, BFWRITE_DATA); + b = 0; + } + } + if (b) { + /* write the buffer */ + bfwrite(buf, 1, b, BFWRITE_DATA); + b = 0; + } + /* Since we seek to the start of each local header can skip + reading any extended local header */ + + /* Update number of bytes written to output file */ + tempzn += (4 + LOCHEAD) + localz->nam + localz->ext + localz->siz; + + /* Free local header */ + if (localz->ext) free(localz->extra); + if (localz->nam) free(localz->iname); + if (localz->nam) free(localz->name); +#ifdef UNICODE_SUPPORT + if (localz->uname) free(localz->uname); +#endif + free(localz); + + return ZE_OK; +} + + +#else /* !UTIL */ + +/*********************************************************************** + * If requested, encrypt the data in buf, and in any case call fwrite() + * with the arguments to zfwrite(). Return what fwrite() returns. + * + * now write to global y + * + * A bug has been found when encrypting large files that don't + * compress. See trees.c for the details and the fix. + */ +unsigned zfwrite(buf, item_size, nb) + zvoid *buf; /* data buffer */ + extent item_size; /* size of each item in bytes */ + extent nb; /* number of items */ +#if 0 + FILE *f; /* file to write to */ +#endif +{ + int t; /* temporary */ + + if (key != (char *)NULL) { /* key is the global password pointer */ + ulg size; /* buffer size */ + char *p = (char *)buf; /* steps through buffer */ + + /* Encrypt data in buffer */ + for (size = item_size*(ulg)nb; size != 0; p++, size--) { + *p = (char)zencode(*p, t); + } + } + /* Write the buffer out */ + return bfwrite(buf, item_size, nb, BFWRITE_DATA); +} + +#endif /* ?UTIL */ +#endif /* ZIP */ + + +#if (defined(UNZIP) && !defined(FUNZIP)) + +/*********************************************************************** + * Get the password and set up keys for current zipfile member. + * Return PK_ class error. + */ +int decrypt(__G__ passwrd) + __GDEF + ZCONST char *passwrd; +{ + ush b; + int n, r; + uch h[RAND_HEAD_LEN]; + + Trace((stdout, "\n[incnt = %d]: ", GLOBAL(incnt))); + + /* get header once (turn off "encrypted" flag temporarily so we don't + * try to decrypt the same data twice) */ + GLOBAL(pInfo->encrypted) = FALSE; + defer_leftover_input(__G); + for (n = 0; n < RAND_HEAD_LEN; n++) { + b = NEXTBYTE; + h[n] = (uch)b; + Trace((stdout, " (%02x)", h[n])); + } + undefer_input(__G); + GLOBAL(pInfo->encrypted) = TRUE; + + if (GLOBAL(newzip)) { /* this is first encrypted member in this zipfile */ + GLOBAL(newzip) = FALSE; + if (passwrd != (char *)NULL) { /* user gave password on command line */ + if (!GLOBAL(key)) { + if ((GLOBAL(key) = (char *)malloc(strlen(passwrd)+1)) == + (char *)NULL) + return PK_MEM2; + strcpy(GLOBAL(key), passwrd); + GLOBAL(nopwd) = TRUE; /* inhibit password prompting! */ + } + } else if (GLOBAL(key)) { /* get rid of previous zipfile's key */ + free(GLOBAL(key)); + GLOBAL(key) = (char *)NULL; + } + } + + /* if have key already, test it; else allocate memory for it */ + if (GLOBAL(key)) { + if (!testp(__G__ h)) + return PK_COOL; /* existing password OK (else prompt for new) */ + else if (GLOBAL(nopwd)) + return PK_WARN; /* user indicated no more prompting */ + } else if ((GLOBAL(key) = (char *)malloc(IZ_PWLEN+1)) == (char *)NULL) + return PK_MEM2; + + /* try a few keys */ + n = 0; + do { + r = (*G.decr_passwd)((zvoid *)&G, &n, GLOBAL(key), IZ_PWLEN+1, + GLOBAL(zipfn), GLOBAL(filename)); + if (r == IZ_PW_ERROR) { /* internal error in fetch of PW */ + free (GLOBAL(key)); + GLOBAL(key) = NULL; + return PK_MEM2; + } + if (r != IZ_PW_ENTERED) { /* user replied "skip" or "skip all" */ + *GLOBAL(key) = '\0'; /* We try the NIL password, ... */ + n = 0; /* and cancel fetch for this item. */ + } + if (!testp(__G__ h)) + return PK_COOL; + if (r == IZ_PW_CANCELALL) /* User replied "Skip all" */ + GLOBAL(nopwd) = TRUE; /* inhibit any further PW prompt! */ + } while (n > 0); + + return PK_WARN; + +} /* end function decrypt() */ + + + +/*********************************************************************** + * Test the password. Return -1 if bad, 0 if OK. + */ +local int testp(__G__ h) + __GDEF + ZCONST uch *h; +{ + int r; + char *key_translated; + + /* On systems with "obscure" native character coding (e.g., EBCDIC), + * the first test translates the password to the "main standard" + * character coding. */ + +#ifdef STR_TO_CP1 + /* allocate buffer for translated password */ + if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL) + return -1; + /* first try, test password translated "standard" charset */ + r = testkey(__G__ h, STR_TO_CP1(key_translated, GLOBAL(key))); +#else /* !STR_TO_CP1 */ + /* first try, test password as supplied on the extractor's host */ + r = testkey(__G__ h, GLOBAL(key)); +#endif /* ?STR_TO_CP1 */ + +#ifdef STR_TO_CP2 + if (r != 0) { +#ifndef STR_TO_CP1 + /* now prepare for second (and maybe third) test with translated pwd */ + if ((key_translated = malloc(strlen(GLOBAL(key)) + 1)) == (char *)NULL) + return -1; +#endif + /* second try, password translated to alternate ("standard") charset */ + r = testkey(__G__ h, STR_TO_CP2(key_translated, GLOBAL(key))); +#ifdef STR_TO_CP3 + if (r != 0) + /* third try, password translated to another "standard" charset */ + r = testkey(__G__ h, STR_TO_CP3(key_translated, GLOBAL(key))); +#endif +#ifndef STR_TO_CP1 + free(key_translated); +#endif + } +#endif /* STR_TO_CP2 */ + +#ifdef STR_TO_CP1 + free(key_translated); + if (r != 0) { + /* last resort, test password as supplied on the extractor's host */ + r = testkey(__G__ h, GLOBAL(key)); + } +#endif /* STR_TO_CP1 */ + + return r; + +} /* end function testp() */ + + +local int testkey(__G__ h, key) + __GDEF + ZCONST uch *h; /* decrypted header */ + ZCONST char *key; /* decryption password to test */ +{ + ush b; +#ifdef ZIP10 + ush c; +#endif + int n; + uch *p; + uch hh[RAND_HEAD_LEN]; /* decrypted header */ + + /* set keys and save the encrypted header */ + init_keys(__G__ key); + memcpy(hh, h, RAND_HEAD_LEN); + + /* check password */ + for (n = 0; n < RAND_HEAD_LEN; n++) { + zdecode(hh[n]); + Trace((stdout, " %02x", hh[n])); + } + + /* use fzofft to format zoff_t as strings - 10/19/04 from SMS */ + Trace((stdout, + "\n lrec.crc= %08lx crec.crc= %08lx pInfo->ExtLocHdr= %s\n", + GLOBAL(lrec.crc32), GLOBAL(pInfo->crc), + GLOBAL(pInfo->ExtLocHdr) ? "true":"false")); + Trace((stdout, " incnt = %d unzip offset into zipfile = %s\n", + GLOBAL(incnt), + fzofft(GLOBAL(cur_zipfile_bufstart)+(GLOBAL(inptr)-GLOBAL(inbuf)), + NULL, NULL))); + + /* same test as in zipbare(): */ + +#ifdef ZIP10 /* check two bytes */ + c = hh[RAND_HEAD_LEN-2], b = hh[RAND_HEAD_LEN-1]; + Trace((stdout, + " (c | (b<<8)) = %04x (crc >> 16) = %04x lrec.time = %04x\n", + (ush)(c | (b<<8)), (ush)(GLOBAL(lrec.crc32) >> 16), + ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff)))); + if ((ush)(c | (b<<8)) != (GLOBAL(pInfo->ExtLocHdr) ? + ((ush)GLOBAL(lrec.last_mod_dos_datetime) & 0xffff) : + (ush)(GLOBAL(lrec.crc32) >> 16))) + return -1; /* bad */ +#else + b = hh[RAND_HEAD_LEN-1]; + Trace((stdout, " b = %02x (crc >> 24) = %02x (lrec.time >> 8) = %02x\n", + b, (ush)(GLOBAL(lrec.crc32) >> 24), + ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff)); + if (b != (GLOBAL(pInfo->ExtLocHdr) ? + ((ush)GLOBAL(lrec.last_mod_dos_datetime) >> 8) & 0xff : + (ush)(GLOBAL(lrec.crc32) >> 24))) + return -1; /* bad */ +#endif + /* password OK: decrypt current buffer contents before leaving */ + for (n = (zoff_t)GLOBAL(incnt) > GLOBAL(csize) ? + (int)GLOBAL(csize) : GLOBAL(incnt), + p = GLOBAL(inptr); n--; p++) + zdecode(*p); + return 0; /* OK */ + +} /* end function testkey() */ + +#endif /* UNZIP && !FUNZIP */ + +#else /* !CRYPT */ + +/* something "externally visible" to shut up compiler/linker warnings */ +int zcr_dummy; + +#endif /* ?CRYPT */ diff --git a/crypt.h b/crypt.h new file mode 100644 index 0000000..61f3234 --- /dev/null +++ b/crypt.h @@ -0,0 +1,169 @@ +/* + Copyright (c) 1990-2007 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + crypt.h (full version) by Info-ZIP. Last revised: [see CR_VERSION_DATE] + + The main encryption/decryption source code for Info-Zip software was + originally written in Europe. To the best of our knowledge, it can + be freely distributed in both source and object forms from any country, + including the USA under License Exception TSU of the U.S. Export + Administration Regulations (section 740.13(e)) of 6 June 2002. + + NOTE on copyright history: + Previous versions of this source package (up to version 2.8) were + not copyrighted and put in the public domain. If you cannot comply + with the Info-Zip LICENSE, you may want to look for one of those + public domain versions. + */ + +#ifndef __crypt_h /* don't include more than once */ +#define __crypt_h + +#ifdef CRYPT +# undef CRYPT +#endif +/* + Logic of selecting "full crypt" code: + a) default behaviour: + - dummy crypt code when compiling UnZipSFX stub, to minimize size + - full crypt code when used to compile Zip, UnZip and fUnZip + b) USE_CRYPT defined: + - always full crypt code + c) NO_CRYPT defined: + - never full crypt code + NO_CRYPT takes precedence over USE_CRYPT + */ +#if defined(NO_CRYPT) +# define CRYPT 0 /* dummy version */ +#else +#if defined(USE_CRYPT) +# define CRYPT 1 /* full version */ +#else +#if !defined(SFX) +# define CRYPT 1 /* full version for zip and main unzip */ +#else +# define CRYPT 0 /* dummy version for unzip sfx */ +#endif +#endif /* ?USE_CRYPT */ +#endif /* ?NO_CRYPT */ + +#if CRYPT +/* full version */ + +#ifdef CR_BETA +# undef CR_BETA /* this is not a beta release */ +#endif + +#define CR_MAJORVER 2 +#define CR_MINORVER 91 +#ifdef CR_BETA +# define CR_BETA_VER "c BETA" +# define CR_VERSION_DATE "05 Jan 2007" /* last real code change */ +#else +# define CR_BETA_VER "" +# define CR_VERSION_DATE "05 Jan 2007" /* last public release date */ +# define CR_RELEASE +#endif + +#ifndef __G /* UnZip only, for now (DLL stuff) */ +# define __G +# define __G__ +# define __GDEF +# define __GPRO void +# define __GPRO__ +#endif + +#if defined(MSDOS) || defined(OS2) || defined(WIN32) +# ifndef DOS_OS2_W32 +# define DOS_OS2_W32 +# endif +#endif + +#if defined(DOS_OS2_W32) || defined(__human68k__) +# ifndef DOS_H68_OS2_W32 +# define DOS_H68_OS2_W32 +# endif +#endif + +#if defined(VM_CMS) || defined(MVS) +# ifndef CMS_MVS +# define CMS_MVS +# endif +#endif + +/* To allow combining of Zip and UnZip static libraries in a single binary, + * the Zip and UnZip versions of the crypt core functions have to be named + * differently. + */ +#ifdef ZIP +# ifdef REALLY_SHORT_SYMS +# define decrypt_byte zdcrby +# else +# define decrypt_byte zp_decrypt_byte +# endif +# define update_keys zp_update_keys +# define init_keys zp_init_keys +#else /* !ZIP */ +# ifdef REALLY_SHORT_SYMS +# define decrypt_byte dcrbyt +# endif +#endif /* ?ZIP */ + +#define IZ_PWLEN 80 /* input buffer size for reading encryption key */ +#ifndef PWLEN /* for compatibility with previous zcrypt release... */ +# define PWLEN IZ_PWLEN +#endif +#define RAND_HEAD_LEN 12 /* length of encryption random header */ + +/* the crc_32_tab array has to be provided externally for the crypt calculus */ + +/* encode byte c, using temp t. Warning: c must not have side effects. */ +#define zencode(c,t) (t=decrypt_byte(__G), update_keys(c), t^(c)) + +/* decode byte c in place */ +#define zdecode(c) update_keys(__G__ c ^= decrypt_byte(__G)) + +int decrypt_byte OF((__GPRO)); +int update_keys OF((__GPRO__ int c)); +void init_keys OF((__GPRO__ ZCONST char *passwd)); + +#ifdef ZIP + void crypthead OF((ZCONST char *, ulg)); +# ifdef UTIL + int zipcloak OF((struct zlist far *, ZCONST char *)); + int zipbare OF((struct zlist far *, ZCONST char *)); +# else + unsigned zfwrite OF((zvoid *, extent, extent)); + extern char *key; +# endif +#endif /* ZIP */ + +#if (defined(UNZIP) && !defined(FUNZIP)) + int decrypt OF((__GPRO__ ZCONST char *passwrd)); +#endif + +#ifdef FUNZIP + extern int encrypted; +# ifdef NEXTBYTE +# undef NEXTBYTE +# endif +# define NEXTBYTE \ + (encrypted? update_keys(__G__ getc(G.in)^decrypt_byte(__G)) : getc(G.in)) +#endif /* FUNZIP */ + +#else /* !CRYPT */ +/* dummy version */ + +#define zencode +#define zdecode + +#define zfwrite(b,s,c) bfwrite(b,s,c,BFWRITE_DATA) + +#endif /* ?CRYPT */ +#endif /* !__crypt_h */ diff --git a/deflate.c b/deflate.c new file mode 100644 index 0000000..c830854 --- /dev/null +++ b/deflate.c @@ -0,0 +1,929 @@ +/* + deflate.c - Zip 3 + + Copyright (c) 1990-2007 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2005-Feb-10 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + * deflate.c by Jean-loup Gailly. + * + * PURPOSE + * + * Identify new text as repetitions of old text within a fixed- + * length sliding window trailing behind the new text. + * + * DISCUSSION + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many info-zippers for bug reports and testing. + * + * REFERENCES + * + * APPNOTE.TXT documentation file in PKZIP 1.93a distribution. + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + * INTERFACE + * + * void lm_init (int pack_level, ush *flags) + * Initialize the "longest match" routines for a new file + * + * ulg deflate (void) + * Processes a new input file and return its compressed length. Sets + * the compressed length, crc, deflate flags and internal file + * attributes. + */ + +#define __DEFLATE_C + +#include "zip.h" + +#ifndef USE_ZLIB + +/* =========================================================================== + * Configuration parameters + */ + +/* Compile with MEDIUM_MEM to reduce the memory requirements or + * with SMALL_MEM to use as little memory as possible. Use BIG_MEM if the + * entire input file can be held in memory (not possible on 16 bit systems). + * Warning: defining these symbols affects HASH_BITS (see below) and thus + * affects the compression ratio. The compressed output + * is still correct, and might even be smaller in some cases. + */ + +#ifdef SMALL_MEM +# define HASH_BITS 13 /* Number of bits used to hash strings */ +#endif +#ifdef MEDIUM_MEM +# define HASH_BITS 14 +#endif +#ifndef HASH_BITS +# define HASH_BITS 15 + /* For portability to 16 bit machines, do not use values above 15. */ +#endif + +#define HASH_SIZE (unsigned)(1<= HASH_BITS + */ + +unsigned int near prev_length; +/* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + unsigned near strstart; /* start of string to insert */ + unsigned near match_start; /* start of matching string */ +local int eofile; /* flag set at end of input file */ +local unsigned lookahead; /* number of valid bytes ahead in window */ + +unsigned near max_chain_length; +/* To speed up deflation, hash chains are never searched beyond this length. + * A higher limit improves compression ratio but degrades the speed. + */ + +local unsigned int max_lazy_match; +/* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +#define max_insert_length max_lazy_match +/* Insert new strings in the hash table only if the match length + * is not greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + +unsigned near good_match; +/* Use a faster search when the previous match is longer than this */ + +#ifdef FULL_SEARCH +# define nice_match MAX_MATCH +#else + int near nice_match; /* Stop searching when current match exceeds this */ +#endif + + +/* Values for max_lazy_match, good_match, nice_match and max_chain_length, + * depending on the desired pack level (0..9). The values given below have + * been tuned to exclude worst case performance for pathological files. + * Better values may be found for specific files. + */ + +typedef struct config { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; +} config; + +local config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0}, /* store only */ +/* 1 */ {4, 4, 8, 4}, /* maximum speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8}, +/* 3 */ {4, 6, 32, 32}, + +/* 4 */ {4, 4, 16, 16}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32}, +/* 6 */ {8, 16, 128, 128}, +/* 7 */ {8, 32, 128, 256}, +/* 8 */ {32, 128, 258, 1024}, +/* 9 */ {32, 258, 258, 4096}}; /* maximum compression */ + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +/* =========================================================================== + * Prototypes for local functions. + */ + +local void fill_window OF((void)); + +local uzoff_t deflate_fast OF((void)); /* now use uzoff_t 7/24/04 EG */ + + int longest_match OF((IPos cur_match)); +#if defined(ASMV) && !defined(RISCOS) + void match_init OF((void)); /* asm code initialization */ +#endif + +#ifdef DEBUG +local void check_match OF((IPos start, IPos match, int length)); +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(h,c) (h = (((h)< 0 if the input file is already read or + * mmap'ed in the window[] array, 0 otherwise. In the first case, + * window_size is sufficient to contain the whole input file plus + * MIN_LOOKAHEAD bytes (to avoid referencing memory beyond the end + * of window[] when looking for matches towards the end). + */ +void lm_init (pack_level, flags) + int pack_level; /* 0: store, 1: best speed, 9: best compression */ + ush *flags; /* general purpose bit flag */ +{ + register unsigned j; + + if (pack_level < 1 || pack_level > 9) error("bad pack level"); + + /* Do not slide the window if the whole input is already in memory + * (window_size > 0) + */ + sliding = 0; + if (window_size == 0L) { + sliding = 1; + window_size = (ulg)2L*WSIZE; + } + + /* Use dynamic allocation if compiler does not like big static arrays: */ +#ifdef DYN_ALLOC + if (window == NULL) { + window = (uch far *) zcalloc(WSIZE, 2*sizeof(uch)); + if (window == NULL) ziperr(ZE_MEM, "window allocation"); + } + if (prev == NULL) { + prev = (Pos far *) zcalloc(WSIZE, sizeof(Pos)); + head = (Pos far *) zcalloc(HASH_SIZE, sizeof(Pos)); + if (prev == NULL || head == NULL) { + ziperr(ZE_MEM, "hash table allocation"); + } + } +#endif /* DYN_ALLOC */ + + /* Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ + head[HASH_SIZE-1] = NIL; + memset((char*)head, NIL, (unsigned)(HASH_SIZE-1)*sizeof(*head)); + + /* Set the default configuration parameters: + */ + max_lazy_match = configuration_table[pack_level].max_lazy; + good_match = configuration_table[pack_level].good_length; +#ifndef FULL_SEARCH + nice_match = configuration_table[pack_level].nice_length; +#endif + max_chain_length = configuration_table[pack_level].max_chain; + if (pack_level <= 2) { + *flags |= FAST; + } else if (pack_level >= 8) { + *flags |= SLOW; + } + /* ??? reduce max_chain_length for binary files */ + + strstart = 0; + block_start = 0L; +#if defined(ASMV) && !defined(RISCOS) + match_init(); /* initialize the asm code */ +#endif + + j = WSIZE; +#ifndef MAXSEG_64K + if (sizeof(int) > 2) j <<= 1; /* Can read 64K in one step */ +#endif + lookahead = (*read_buf)((char*)window, j); + + if (lookahead == 0 || lookahead == (unsigned)EOF) { + eofile = 1, lookahead = 0; + return; + } + eofile = 0; + /* Make sure that we always have enough lookahead. This is important + * if input comes from a device such as a tty. + */ + if (lookahead < MIN_LOOKAHEAD) fill_window(); + + ins_h = 0; + for (j=0; j= 1 + */ +#ifndef ASMV +/* For 80x86 and 680x0 and ARM, an optimized version is in match.asm or + * match.S. The code is functionally equivalent, so you can use the C version + * if desired. + */ +int longest_match(cur_match) + IPos cur_match; /* current match */ +{ + unsigned chain_length = max_chain_length; /* max hash chain length */ + register uch far *scan = window + strstart; /* current string */ + register uch far *match; /* matched string */ + register int len; /* length of current match */ + int best_len = prev_length; /* best match length so far */ + IPos limit = strstart > (IPos)MAX_DIST ? strstart - (IPos)MAX_DIST : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + +/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ +#if HASH_BITS < 8 || MAX_MATCH != 258 + error: Code too clever +#endif + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register uch far *strend = window + strstart + MAX_MATCH - 1; + register ush scan_start = *(ush far *)scan; + register ush scan_end = *(ush far *)(scan+best_len-1); +#else + register uch far *strend = window + strstart + MAX_MATCH; + register uch scan_end1 = scan[best_len-1]; + register uch scan_end = scan[best_len]; +#endif + + /* Do not waste too much time if we already have a good match: */ + if (prev_length >= good_match) { + chain_length >>= 2; + } + + Assert(strstart <= window_size-MIN_LOOKAHEAD, "insufficient lookahead"); + + do { + Assert(cur_match < strstart, "no future"); + match = window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2: + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ush far *)(match+best_len-1) != scan_end || + *(ush far *)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + scan++, match++; + do { + } while (*(ush far *)(scan+=2) == *(ush far *)(match+=2) && + *(ush far *)(scan+=2) == *(ush far *)(match+=2) && + *(ush far *)(scan+=2) == *(ush far *)(match+=2) && + *(ush far *)(scan+=2) == *(ush far *)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= window+(unsigned)(window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= window+(unsigned)(window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ush far *)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & WMASK]) > limit + && --chain_length != 0); + + return best_len; +} +#endif /* ASMV */ + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(start, match, length) + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (memcmp((char*)window + match, + (char*)window + start, length) != EQUAL) { + fprintf(mesg, + " start %d, match %d, length %d\n", + start, match, length); + error("invalid match"); + } + if (verbose > 1) { + fprintf(mesg,"\\[%d,%d]", start-match, length); +#ifndef WINDLL + do { putc(window[start++], mesg); } while (--length != 0); +#else + do { fprintf(stdout,"%c",window[start++]); } while (--length != 0); +#endif + } +} +#else +# define check_match(start, match, length) +#endif + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK(eof) \ + flush_block(block_start >= 0L ? (char*)&window[(unsigned)block_start] : \ + (char*)NULL, (ulg)strstart - (ulg)block_start, (eof)) + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead, and sets eofile if end of input file. + * + * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0 + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or eofile is set; file reads are + * performed for at least two bytes (required for the translate_eol option). + */ +local void fill_window() +{ + register unsigned n, m; + unsigned more; /* Amount of free space at the end of the window. */ + + do { + more = (unsigned)(window_size - (ulg)lookahead - (ulg)strstart); + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (more == (unsigned)EOF) { + /* Very unlikely, but possible on 16 bit machine if strstart == 0 + * and lookahead == 1 (input done one byte at time) + */ + more--; + + /* For MMAP or BIG_MEM, the whole input file is already in memory so + * we must not perform sliding. We must however call (*read_buf)() in + * order to compute the crc, update lookahead and possibly set eofile. + */ + } else if (strstart >= WSIZE+MAX_DIST && sliding) { + +#ifdef FORCE_METHOD + /* When methods "stored" or "store_block" are requested, the + * current block must be flushed before sliding the window. + */ + if (level <= 2) FLUSH_BLOCK(0), block_start = strstart; +#endif + /* By the IN assertion, the window is not empty so we can't confuse + * more == 0 with more == 64K on a 16 bit machine. + */ + memcpy((char*)window, (char*)window+WSIZE, (unsigned)WSIZE); + match_start -= WSIZE; + strstart -= WSIZE; /* we now have strstart >= MAX_DIST: */ + + block_start -= (long) WSIZE; + + for (n = 0; n < HASH_SIZE; n++) { + m = head[n]; + head[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL); + } + for (n = 0; n < WSIZE; n++) { + m = prev[n]; + prev[n] = (Pos)(m >= WSIZE ? m-WSIZE : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } + more += WSIZE; + if (dot_size > 0 && !display_globaldots) { + /* initial space */ + if (noisy && dot_count == -1) { +#ifndef WINDLL + putc(' ', mesg); + fflush(mesg); +#else + fprintf(stdout,"%c",' '); +#endif + dot_count++; + } + dot_count++; + if (dot_size <= (dot_count + 1) * WSIZE) dot_count = 0; + } + if ((verbose || noisy) && dot_size && !dot_count) { +#ifndef WINDLL + putc('.', mesg); + fflush(mesg); +#else + fprintf(stdout,"%c",'.'); +#endif + mesg_line_started = 1; + } + } + if (eofile) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the MMAP or BIG_MEM case (not yet supported in gzip), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = (*read_buf)((char*)window+strstart+lookahead, more); + if (n == 0 || n == (unsigned)EOF) { + eofile = 1; + } else { + lookahead += n; + } + } while (lookahead < MIN_LOOKAHEAD && !eofile); +} + +/* =========================================================================== + * Processes a new input file and return its compressed length. This + * function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local uzoff_t deflate_fast() +{ + IPos hash_head = NIL; /* head of the hash chain */ + int flush; /* set if current block must be flushed */ + unsigned match_length = 0; /* length of best match */ + + prev_length = MIN_MATCH-1; + while (lookahead != 0) { + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ +#ifndef DEFL_UNDETERM + if (lookahead >= MIN_MATCH) +#endif + INSERT_STRING(strstart, hash_head); + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && strstart - hash_head <= MAX_DIST) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ +#ifndef HUFFMAN_ONLY +# ifndef DEFL_UNDETERM + /* Do not look for matches beyond the end of the input. + * This is necessary to make deflate deterministic. + */ + if ((unsigned)nice_match > lookahead) nice_match = (int)lookahead; +# endif + match_length = longest_match (hash_head); + /* longest_match() sets match_start */ + if (match_length > lookahead) match_length = lookahead; +#endif + } + if (match_length >= MIN_MATCH) { + check_match(strstart, match_start, match_length); + + flush = ct_tally(strstart-match_start, match_length - MIN_MATCH); + + lookahead -= match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (match_length <= max_insert_length +#ifndef DEFL_UNDETERM + && lookahead >= MIN_MATCH +#endif + ) { + match_length--; /* string at strstart already in hash table */ + do { + strstart++; + INSERT_STRING(strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ +#ifdef DEFL_UNDETERM + /* If lookahead < MIN_MATCH these bytes are garbage, + * but it does not matter since the next lookahead bytes + * will be emitted as literals. + */ +#endif + } while (--match_length != 0); + strstart++; + } else { + strstart += match_length; + match_length = 0; + ins_h = window[strstart]; + UPDATE_HASH(ins_h, window[strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c",window[strstart])); + flush = ct_tally (0, window[strstart]); + lookahead--; + strstart++; + } + if (flush) FLUSH_BLOCK(0), block_start = strstart; + + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (lookahead < MIN_LOOKAHEAD) fill_window(); + } + return FLUSH_BLOCK(1); /* eof */ +} + +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +uzoff_t deflate() +{ + IPos hash_head = NIL; /* head of hash chain */ + IPos prev_match; /* previous match */ + int flush; /* set if current block must be flushed */ + int match_available = 0; /* set if previous match exists */ + register unsigned match_length = MIN_MATCH-1; /* length of best match */ +#ifdef DEBUG + extern uzoff_t isize; /* byte length of input file, for debug only */ +#endif + + if (level <= 3) return deflate_fast(); /* optimized for speed */ + + /* Process the input block. */ + while (lookahead != 0) { + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ +#ifndef DEFL_UNDETERM + if (lookahead >= MIN_MATCH) +#endif + INSERT_STRING(strstart, hash_head); + + /* Find the longest match, discarding those <= prev_length. + */ + prev_length = match_length, prev_match = match_start; + match_length = MIN_MATCH-1; + + if (hash_head != NIL && prev_length < max_lazy_match && + strstart - hash_head <= MAX_DIST) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ +#ifndef HUFFMAN_ONLY +# ifndef DEFL_UNDETERM + /* Do not look for matches beyond the end of the input. + * This is necessary to make deflate deterministic. + */ + if ((unsigned)nice_match > lookahead) nice_match = (int)lookahead; +# endif + match_length = longest_match (hash_head); + /* longest_match() sets match_start */ + if (match_length > lookahead) match_length = lookahead; +#endif + +#ifdef FILTERED + /* Ignore matches of length <= 5 */ + if (match_length <= 5) { +#else + /* Ignore a length 3 match if it is too distant: */ + if (match_length == MIN_MATCH && strstart-match_start > TOO_FAR){ +#endif + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (prev_length >= MIN_MATCH && match_length <= prev_length) { +#ifndef DEFL_UNDETERM + unsigned max_insert = strstart + lookahead - MIN_MATCH; + +#endif + check_match(strstart-1, prev_match, prev_length); + + flush = ct_tally(strstart-1-prev_match, prev_length - MIN_MATCH); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. + */ + lookahead -= prev_length-1; + prev_length -= 2; +#ifndef DEFL_UNDETERM + do { + if (++strstart <= max_insert) { + INSERT_STRING(strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } + } while (--prev_length != 0); + strstart++; +#else /* DEFL_UNDETERM */ + do { + strstart++; + INSERT_STRING(strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH + * these bytes are garbage, but it does not matter since the + * next lookahead bytes will always be emitted as literals. + */ + } while (--prev_length != 0); + strstart++; +#endif /* ?DEFL_UNDETERM */ + match_available = 0; + match_length = MIN_MATCH-1; + + if (flush) FLUSH_BLOCK(0), block_start = strstart; + + } else if (match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c",window[strstart-1])); + if (ct_tally (0, window[strstart-1])) { + FLUSH_BLOCK(0), block_start = strstart; + } + strstart++; + lookahead--; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + match_available = 1; + strstart++; + lookahead--; + } + Assert(strstart <= isize && lookahead <= isize, "a bit too far"); + + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (lookahead < MIN_LOOKAHEAD) fill_window(); + } + if (match_available) ct_tally (0, window[strstart-1]); + + return FLUSH_BLOCK(1); /* eof */ +} +#endif /* !USE_ZLIB */ diff --git a/ebcdic.h b/ebcdic.h new file mode 100644 index 0000000..a52de1e --- /dev/null +++ b/ebcdic.h @@ -0,0 +1,328 @@ +/* + ebcdic.h + + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2005-Feb-10 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/licen +*/ +/*--------------------------------------------------------------------------- + + ebcdic.h + + The CECP 1047 (Extended de-facto EBCDIC) <-> ISO 8859-1 conversion tables, + from ftp://aix1.segi.ulg.ac.be/pub/docs/iso8859/iso8859.networking + + NOTES: + (OS/390 port 12/97) + These table no longer represent the standard mappings (for example in the + OS/390 iconv utility). In order to follow current standards I remapped + ebcdic x0a to ascii x15 and + ebcdic x85 to ascii x25 (and vice-versa) + Without these changes, newlines in auto-convert text files appeared + as literal \045. + I'm not sure what effect this remap would have on the MVS and CMS ports, so + I ifdef'd these changes. Hopefully these ifdef's can be removed when the + MVS/CMS folks test the new mappings. + + Christian Spieler , 27-Apr-1998 + The problem mentioned by Paul von Behren was already observed previously + on VM/CMS, during the preparation of the CMS&MVS port of UnZip 5.20 in + 1996. At that point, the ebcdic tables were not changed since they seemed + to be an adopted standard (to my knowledge, these tables are still used + as presented in mainfraime KERMIT). Instead, the "end-of-line" conversion + feature of Zip's and UnZip's "text-translation" mode was used to force + correct mappings between ASCII and EBCDIC newline markers. + Before interchanging the ASCII mappings of the EBCDIC control characters + "NL" 0x25 and "LF" 0x15 according to the OS/390 setting, we have to + make sure that EBCDIC 0x15 is never used as line termination. + + ---------------------------------------------------------------------------*/ + +#ifndef __ebcdic_h /* prevent multiple inclusions */ +#define __ebcdic_h + + +#ifndef ZCONST +# define ZCONST const +#endif + +#ifdef EBCDIC +#ifndef MTS /* MTS uses a slightly "special" EBCDIC code page */ + +ZCONST uch ebcdic[] = { + 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, /* 00 - 07 */ +#ifdef OS390 + 0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 08 - 0F */ +#else + 0x16, 0x05, 0x25, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 08 - 0F */ +#endif + 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, /* 10 - 17 */ + 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F, /* 18 - 1F */ + 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, /* 20 - 27 */ + 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, /* 28 - 2F */ + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, /* 30 - 37 */ + 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, /* 38 - 3F */ + 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, /* 40 - 47 */ + 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, /* 48 - 4F */ + 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, /* 50 - 57 */ + 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D, /* 58 - 5F */ + 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 60 - 67 */ + 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* 68 - 6F */ + 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, /* 70 - 77 */ + 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07, /* 78 - 7F */ +#ifdef OS390 + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x06, 0x17, /* 80 - 87 */ +#else + 0x20, 0x21, 0x22, 0x23, 0x24, 0x15, 0x06, 0x17, /* 80 - 87 */ +#endif + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x09, 0x0A, 0x1B, /* 88 - 8F */ + 0x30, 0x31, 0x1A, 0x33, 0x34, 0x35, 0x36, 0x08, /* 90 - 97 */ + 0x38, 0x39, 0x3A, 0x3B, 0x04, 0x14, 0x3E, 0xFF, /* 98 - 9F */ + 0x41, 0xAA, 0x4A, 0xB1, 0x9F, 0xB2, 0x6A, 0xB5, /* A0 - A7 */ + 0xBB, 0xB4, 0x9A, 0x8A, 0xB0, 0xCA, 0xAF, 0xBC, /* A8 - AF */ + 0x90, 0x8F, 0xEA, 0xFA, 0xBE, 0xA0, 0xB6, 0xB3, /* B0 - B7 */ + 0x9D, 0xDA, 0x9B, 0x8B, 0xB7, 0xB8, 0xB9, 0xAB, /* B8 - BF */ + 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9E, 0x68, /* C0 - C7 */ + 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* C8 - CF */ + 0xAC, 0x69, 0xED, 0xEE, 0xEB, 0xEF, 0xEC, 0xBF, /* D0 - D7 */ + 0x80, 0xFD, 0xFE, 0xFB, 0xFC, 0xBA, 0xAE, 0x59, /* D8 - DF */ + 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9C, 0x48, /* E0 - E7 */ + 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* E8 - EF */ + 0x8C, 0x49, 0xCD, 0xCE, 0xCB, 0xCF, 0xCC, 0xE1, /* F0 - F7 */ + 0x70, 0xDD, 0xDE, 0xDB, 0xDC, 0x8D, 0x8E, 0xDF /* F8 - FF */ +}; + +#if (defined(ZIP) || CRYPT) +ZCONST uch ascii[] = { + 0x00, 0x01, 0x02, 0x03, 0x9C, 0x09, 0x86, 0x7F, /* 00 - 07 */ + 0x97, 0x8D, 0x8E, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 08 - 0F */ +#ifdef OS390 + 0x10, 0x11, 0x12, 0x13, 0x9D, 0x0A, 0x08, 0x87, /* 10 - 17 */ +#else + 0x10, 0x11, 0x12, 0x13, 0x9D, 0x85, 0x08, 0x87, /* 10 - 17 */ +#endif + 0x18, 0x19, 0x92, 0x8F, 0x1C, 0x1D, 0x1E, 0x1F, /* 18 - 1F */ +#ifdef OS390 + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x17, 0x1B, /* 20 - 27 */ +#else + 0x80, 0x81, 0x82, 0x83, 0x84, 0x0A, 0x17, 0x1B, /* 20 - 27 */ +#endif + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x05, 0x06, 0x07, /* 28 - 2F */ + 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30 - 37 */ + 0x98, 0x99, 0x9A, 0x9B, 0x14, 0x15, 0x9E, 0x1A, /* 38 - 3F */ + 0x20, 0xA0, 0xE2, 0xE4, 0xE0, 0xE1, 0xE3, 0xE5, /* 40 - 47 */ + 0xE7, 0xF1, 0xA2, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, /* 48 - 4F */ + 0x26, 0xE9, 0xEA, 0xEB, 0xE8, 0xED, 0xEE, 0xEF, /* 50 - 57 */ + 0xEC, 0xDF, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E, /* 58 - 5F */ + 0x2D, 0x2F, 0xC2, 0xC4, 0xC0, 0xC1, 0xC3, 0xC5, /* 60 - 67 */ + 0xC7, 0xD1, 0xA6, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, /* 68 - 6F */ + 0xF8, 0xC9, 0xCA, 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, /* 70 - 77 */ + 0xCC, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, /* 78 - 7F */ + 0xD8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80 - 87 */ + 0x68, 0x69, 0xAB, 0xBB, 0xF0, 0xFD, 0xFE, 0xB1, /* 88 - 8F */ + 0xB0, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, /* 90 - 97 */ + 0x71, 0x72, 0xAA, 0xBA, 0xE6, 0xB8, 0xC6, 0xA4, /* 98 - 9F */ + 0xB5, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* A0 - A7 */ + 0x79, 0x7A, 0xA1, 0xBF, 0xD0, 0x5B, 0xDE, 0xAE, /* A8 - AF */ + 0xAC, 0xA3, 0xA5, 0xB7, 0xA9, 0xA7, 0xB6, 0xBC, /* B0 - B7 */ + 0xBD, 0xBE, 0xDD, 0xA8, 0xAF, 0x5D, 0xB4, 0xD7, /* B8 - BF */ + 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* C0 - C7 */ + 0x48, 0x49, 0xAD, 0xF4, 0xF6, 0xF2, 0xF3, 0xF5, /* C8 - CF */ + 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, /* D0 - D7 */ + 0x51, 0x52, 0xB9, 0xFB, 0xFC, 0xF9, 0xFA, 0xFF, /* D8 - DF */ + 0x5C, 0xF7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* E0 - E7 */ + 0x59, 0x5A, 0xB2, 0xD4, 0xD6, 0xD2, 0xD3, 0xD5, /* E8 - EF */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* F0 - F7 */ + 0x38, 0x39, 0xB3, 0xDB, 0xDC, 0xD9, 0xDA, 0x9F /* F8 - FF */ +}; +#endif /* ZIP || CRYPT */ + +#else /* MTS */ + +/* + * This is the MTS ASCII->EBCDIC translation table. It provides a 1-1 + * translation from ISO 8859/1 8-bit ASCII to IBM Code Page 37 EBCDIC. + */ + +ZCONST uch ebcdic[] = { + 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, /* 00 - 07 */ + 0x16, 0x05, 0x25, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 08 - 0F */ + 0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, /* 10 - 17 */ + 0x18, 0x19, 0x3F, 0x27, 0x1C, 0x1D, 0x1E, 0x1F, /* 18 - 1F */ + 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, /* 20 - 27 */ + 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, /* 28 - 2F */ + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, /* 30 - 37 */ + 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, /* 38 - 3F */ + 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, /* 40 - 47 */ + 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, /* 48 - 4F */ + 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, /* 50 - 57 */ + 0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D, /* 58 - 5F */ + 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 60 - 67 */ + 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* 68 - 6F */ + 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, /* 70 - 77 */ + 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07, /* 78 - 7F */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x15, 0x06, 0x17, /* 80 - 87 */ + 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x09, 0x0A, 0x1B, /* 88 - 8F */ + 0x30, 0x31, 0x1A, 0x33, 0x34, 0x35, 0x36, 0x08, /* 90 - 97 */ + 0x38, 0x39, 0x3A, 0x3B, 0x04, 0x14, 0x3E, 0xFF, /* 98 - 9F */ + 0x41, 0xAA, 0x4A, 0xB1, 0x9F, 0xB2, 0x6A, 0xB5, /* A0 - A7 */ + 0xBD, 0xB4, 0x9A, 0x8A, 0x5F, 0xCA, 0xAF, 0xBC, /* A8 - AF */ + 0x90, 0x8F, 0xEA, 0xFA, 0xBE, 0xA0, 0xB6, 0xB3, /* B0 - B7 */ + 0x9D, 0xDA, 0x9B, 0x8B, 0xB7, 0xB8, 0xB9, 0xAB, /* B8 - BF */ + 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9E, 0x68, /* C0 - C7 */ + 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* C8 - CF */ + 0xAC, 0x69, 0xED, 0xEE, 0xEB, 0xEF, 0xEC, 0xBF, /* D0 - D7 */ + 0x80, 0xFD, 0xFE, 0xFB, 0xFC, 0xAD, 0xAE, 0x59, /* D8 - DF */ + 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9C, 0x48, /* E0 - E7 */ + 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* E8 - EF */ + 0x8C, 0x49, 0xCD, 0xCE, 0xCB, 0xCF, 0xCC, 0xE1, /* F0 - F7 */ + 0x70, 0xDD, 0xDE, 0xDB, 0xDC, 0x8D, 0x8E, 0xDF /* F8 - FF */ +}; + +#if (defined(ZIP) || CRYPT) +ZCONST uch ascii[] = { + 0x00, 0x01, 0x02, 0x03, 0x9C, 0x09, 0x86, 0x7F, /* 00 - 07 */ + 0x97, 0x8D, 0x8E, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 08 - 0F */ + 0x10, 0x11, 0x12, 0x13, 0x9D, 0x85, 0x08, 0x87, /* 10 - 17 */ + 0x18, 0x19, 0x92, 0x8F, 0x1C, 0x1D, 0x1E, 0x1F, /* 18 - 1F */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x0A, 0x17, 0x1B, /* 20 - 27 */ + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x05, 0x06, 0x07, /* 28 - 2F */ + 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30 - 37 */ + 0x98, 0x99, 0x9A, 0x9B, 0x14, 0x15, 0x9E, 0x1A, /* 38 - 3F */ + 0x20, 0xA0, 0xE2, 0xE4, 0xE0, 0xE1, 0xE3, 0xE5, /* 40 - 47 */ + 0xE7, 0xF1, 0xA2, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, /* 48 - 4F */ + 0x26, 0xE9, 0xEA, 0xEB, 0xE8, 0xED, 0xEE, 0xEF, /* 50 - 57 */ + 0xEC, 0xDF, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAC, /* 58 - 5F */ + 0x2D, 0x2F, 0xC2, 0xC4, 0xC0, 0xC1, 0xC3, 0xC5, /* 60 - 67 */ + 0xC7, 0xD1, 0xA6, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, /* 68 - 6F */ + 0xF8, 0xC9, 0xCA, 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, /* 70 - 77 */ + 0xCC, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, /* 78 - 7F */ + 0xD8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80 - 87 */ + 0x68, 0x69, 0xAB, 0xBB, 0xF0, 0xFD, 0xFE, 0xB1, /* 88 - 8F */ + 0xB0, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, /* 90 - 97 */ + 0x71, 0x72, 0xAA, 0xBA, 0xE6, 0xB8, 0xC6, 0xA4, /* 98 - 9F */ + 0xB5, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* A0 - A7 */ + 0x79, 0x7A, 0xA1, 0xBF, 0xD0, 0xDD, 0xDE, 0xAE, /* A8 - AF */ + 0x5E, 0xA3, 0xA5, 0xB7, 0xA9, 0xA7, 0xB6, 0xBC, /* B0 - B7 */ + 0xBD, 0xBE, 0x5B, 0x5D, 0xAF, 0xA8, 0xB4, 0xD7, /* B8 - BF */ + 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* C0 - C7 */ + 0x48, 0x49, 0xAD, 0xF4, 0xF6, 0xF2, 0xF3, 0xF5, /* C8 - CF */ + 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, /* D0 - D7 */ + 0x51, 0x52, 0xB9, 0xFB, 0xFC, 0xF9, 0xFA, 0xFF, /* D8 - DF */ + 0x5C, 0xF7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* E0 - E7 */ + 0x59, 0x5A, 0xB2, 0xD4, 0xD6, 0xD2, 0xD3, 0xD5, /* E8 - EF */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* F0 - F7 */ + 0x38, 0x39, 0xB3, 0xDB, 0xDC, 0xD9, 0xDA, 0x9F /* F8 - FF */ +}; +#endif /* ZIP || CRYPT */ + +#endif /* ?MTS */ +#endif /* EBCDIC */ + +/*--------------------------------------------------------------------------- + + The following conversion tables translate between IBM PC CP 850 + (OEM codepage) and the "Western Europe & America" Windows codepage 1252. + The Windows codepage 1252 contains the ISO 8859-1 "Latin 1" codepage, + with some additional printable characters in the range (0x80 - 0x9F), + that is reserved to control codes in the ISO 8859-1 character table. + + The ISO <--> OEM conversion tables were constructed with the help + of the WIN32 (Win16?) API's OemToAnsi() and AnsiToOem() conversion + functions and have been checked against the CP850 and LATIN1 tables + provided in the MS-Kermit 3.14 distribution. + + ---------------------------------------------------------------------------*/ + +#ifdef IZ_ISO2OEM_ARRAY +#ifdef OEM_RUSS +ZCONST uch Far iso2oem[] = { + 0x3F, 0x3F, 0x27, 0x9F, 0x22, 0x2E, 0xC5, 0xCE, /* 80 - 87 */ + 0xFD, 0x25, 0x53, 0x3C, 0x4F, 0x3F, 0x3F, 0x3F, /* 88 - 8F */ + 0x3F, 0x27, 0x27, 0x22, 0x22, 0xF9, 0x2D, 0x2D, /* 90 - 97 */ + 0x7E, 0x54, 0x73, 0x3E, 0x6F, 0x3F, 0x3F, 0x59, /* 98 - 9F */ + 0xFF, 0xF6, 0xF7, 0x9C, 0xCF, 0xBE, 0xFE, 0xF5, /* A0 - A7 */ + 0xF0, 0xB8, 0xF2, 0xAE, 0xAA, 0xF0, 0xA9, 0xEE, /* A8 - AF */ + 0xF8, 0xFB, 0xF4, 0xF5, 0xEF, 0xE6, 0xF4, 0xFA, /* B0 - B7 */ + 0xF1, 0xFC, 0xF3, 0xAF, 0xAC, 0xAB, 0xF3, 0xA8, /* B8 - BF */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x86, 0x86, 0x87, /* C0 - C7 */ + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, /* C8 - CF */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* D0 - D7 */ + 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, /* D8 - DF */ + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, /* E0 - E7 */ + 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, /* E8 - EF */ + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, /* F0 - F7 */ + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF /* F8 - FF */ +}; +#else /* OEM_RUS */ +ZCONST uch Far iso2oem[] = { + 0x3F, 0x3F, 0x27, 0x9F, 0x22, 0x2E, 0xC5, 0xCE, /* 80 - 87 */ + 0x5E, 0x25, 0x53, 0x3C, 0x4F, 0x3F, 0x3F, 0x3F, /* 88 - 8F */ + 0x3F, 0x27, 0x27, 0x22, 0x22, 0x07, 0x2D, 0x2D, /* 90 - 97 */ + 0x7E, 0x54, 0x73, 0x3E, 0x6F, 0x3F, 0x3F, 0x59, /* 98 - 9F */ + 0xFF, 0xAD, 0xBD, 0x9C, 0xCF, 0xBE, 0xDD, 0xF5, /* A0 - A7 */ + 0xF9, 0xB8, 0xA6, 0xAE, 0xAA, 0xF0, 0xA9, 0xEE, /* A8 - AF */ + 0xF8, 0xF1, 0xFD, 0xFC, 0xEF, 0xE6, 0xF4, 0xFA, /* B0 - B7 */ + 0xF7, 0xFB, 0xA7, 0xAF, 0xAC, 0xAB, 0xF3, 0xA8, /* B8 - BF */ + 0xB7, 0xB5, 0xB6, 0xC7, 0x8E, 0x8F, 0x92, 0x80, /* C0 - C7 */ + 0xD4, 0x90, 0xD2, 0xD3, 0xDE, 0xD6, 0xD7, 0xD8, /* C8 - CF */ + 0xD1, 0xA5, 0xE3, 0xE0, 0xE2, 0xE5, 0x99, 0x9E, /* D0 - D7 */ + 0x9D, 0xEB, 0xE9, 0xEA, 0x9A, 0xED, 0xE8, 0xE1, /* D8 - DF */ + 0x85, 0xA0, 0x83, 0xC6, 0x84, 0x86, 0x91, 0x87, /* E0 - E7 */ + 0x8A, 0x82, 0x88, 0x89, 0x8D, 0xA1, 0x8C, 0x8B, /* E8 - EF */ + 0xD0, 0xA4, 0x95, 0xA2, 0x93, 0xE4, 0x94, 0xF6, /* F0 - F7 */ + 0x9B, 0x97, 0xA3, 0x96, 0x81, 0xEC, 0xE7, 0x98 /* F8 - FF */ +}; +#endif /* OEM_RUS */ +#endif /* IZ_ISO2OEM_ARRAY */ + +#ifdef IZ_OEM2ISO_ARRAY +#ifdef OEM_RUSS +ZCONST uch Far oem2iso[] = { + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, /* 80 - 87 */ + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, /* 88 - 8F */ + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, /* 90 - 97 */ + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, /* 98 - 9F */ + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, /* A0 - A7 */ + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, /* A8 - AF */ + 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xC1, 0xC2, 0xC0, /* B0 - B7 */ + 0xA9, 0xA6, 0xA6, 0x2B, 0x2B, 0xA2, 0xA5, 0x2B, /* B8 - BF */ + 0x2B, 0x2D, 0x2D, 0x2B, 0x2D, 0x2B, 0xE3, 0xC3, /* C0 - C7 */ + 0x2B, 0x2B, 0x2D, 0x2D, 0xA6, 0x2D, 0x2B, 0xA4, /* C8 - CF */ + 0xF0, 0xD0, 0xCA, 0xCB, 0xC8, 0x69, 0xCD, 0xCE, /* D0 - D7 */ + 0xCF, 0x2B, 0x2B, 0xA6, 0x5F, 0xA6, 0xCC, 0xAF, /* D8 - DF */ + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, /* E0 - E7 */ + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, /* E8 - EF */ + 0xA8, 0xB8, 0xAA, 0xBA, 0xB2, 0xB3, 0xA1, 0xA2, /* F0 - F7 */ + 0xB0, 0x95, 0xB7, 0xB1, 0xB9, 0x88, 0xA6, 0xA0 /* F8 - FF */ +}; +#else /* OEM_RUS */ +ZCONST uch Far oem2iso[] = { + 0xC7, 0xFC, 0xE9, 0xE2, 0xE4, 0xE0, 0xE5, 0xE7, /* 80 - 87 */ + 0xEA, 0xEB, 0xE8, 0xEF, 0xEE, 0xEC, 0xC4, 0xC5, /* 88 - 8F */ + 0xC9, 0xE6, 0xC6, 0xF4, 0xF6, 0xF2, 0xFB, 0xF9, /* 90 - 97 */ + 0xFF, 0xD6, 0xDC, 0xF8, 0xA3, 0xD8, 0xD7, 0x83, /* 98 - 9F */ + 0xE1, 0xED, 0xF3, 0xFA, 0xF1, 0xD1, 0xAA, 0xBA, /* A0 - A7 */ + 0xBF, 0xAE, 0xAC, 0xBD, 0xBC, 0xA1, 0xAB, 0xBB, /* A8 - AF */ + 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xC1, 0xC2, 0xC0, /* B0 - B7 */ + 0xA9, 0xA6, 0xA6, 0x2B, 0x2B, 0xA2, 0xA5, 0x2B, /* B8 - BF */ + 0x2B, 0x2D, 0x2D, 0x2B, 0x2D, 0x2B, 0xE3, 0xC3, /* C0 - C7 */ + 0x2B, 0x2B, 0x2D, 0x2D, 0xA6, 0x2D, 0x2B, 0xA4, /* C8 - CF */ + 0xF0, 0xD0, 0xCA, 0xCB, 0xC8, 0x69, 0xCD, 0xCE, /* D0 - D7 */ + 0xCF, 0x2B, 0x2B, 0xA6, 0x5F, 0xA6, 0xCC, 0xAF, /* D8 - DF */ + 0xD3, 0xDF, 0xD4, 0xD2, 0xF5, 0xD5, 0xB5, 0xFE, /* E0 - E7 */ + 0xDE, 0xDA, 0xDB, 0xD9, 0xFD, 0xDD, 0xAF, 0xB4, /* E8 - EF */ + 0xAD, 0xB1, 0x3D, 0xBE, 0xB6, 0xA7, 0xF7, 0xB8, /* F0 - F7 */ + 0xB0, 0xA8, 0xB7, 0xB9, 0xB3, 0xB2, 0xA6, 0xA0 /* F8 - FF */ +}; +#endif /* OEM_RUS */ +#endif /* IZ_OEM2ISO_ARRAY */ + +#if defined(THEOS) || defined(THEOS_SUPPORT) +# include "theos/charconv.h" +#endif + +#endif /* __ebcdic_h */ diff --git a/file_id.diz b/file_id.diz new file mode 100644 index 0000000..5e3f34e --- /dev/null +++ b/file_id.diz @@ -0,0 +1,15 @@ +Info-ZIP's Zip 3.0: generic C sources. + Complete C source code for Info-ZIP's + PKZIP-compatible .zip archiver, for + all supported compilers and platforms + (Unix, OS/2, MS-DOS, NT, VMS, Amiga, + Atari, Mac, Acorn, VM/CMS, etc.), plus + lots of pretty decent documentation. + Includes Info-ZIP's ZCrypt 2.9 for + PKWARE-compatible standard encryption + and decryption support for Info-ZIP's + Zip 2.32, Zip 3.0, UnZip 5.52, + UnZip 6.0, and WiZ 5.02 (and later). +This is FREE (but copyrighted) software. +See LICENSE for details on distribution +and reuse. diff --git a/fileio.c b/fileio.c new file mode 100644 index 0000000..1847e62 --- /dev/null +++ b/fileio.c @@ -0,0 +1,4903 @@ +/* + fileio.c - Zip 3 + + Copyright (c) 1990-2008 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + * fileio.c by Mark Adler + */ +#define __FILEIO_C + +#include "zip.h" +#include "crc32.h" + +#ifdef MACOS +# include "helpers.h" +#endif + +#ifdef VMS +# include "vms/vms.h" +#endif /* def VMS */ + +#include + +#ifdef NO_MKTIME +time_t mktime OF((struct tm *)); +#endif + +#ifdef OSF +#define EXDEV 18 /* avoid a bug in the DEC OSF/1 header files. */ +#else +#include +#endif + +#ifdef NO_ERRNO +extern int errno; +#endif + +/* ----------------------- + For long option support + ----------------------- */ +#include + + +#if defined(VMS) || defined(TOPS20) +# define PAD 5 +#else +# define PAD 0 +#endif + +#ifdef NO_RENAME +int rename OF((ZCONST char *, ZCONST char *)); +#endif + + +/* Local functions */ +local int optionerr OF((char *, ZCONST char *, int, int)); +local unsigned long get_shortopt OF((char **, int, int *, int *, char **, int *, int)); +local unsigned long get_longopt OF((char **, int, int *, int *, char **, int *, int)); + +#ifdef UNICODE_SUPPORT +local int utf8_char_bytes OF((ZCONST char *utf8)); +local long ucs4_char_from_utf8 OF((ZCONST char **utf8 )); +local int utf8_from_ucs4_char OF((char *utf8buf, ulg ch)); +local int utf8_to_ucs4_string OF((ZCONST char *utf8, ulg *usc4buf, + int buflen)); +local int ucs4_string_to_utf8 OF((ZCONST ulg *ucs4, char *utf8buf, + int buflen)); +#if 0 + local int utf8_chars OF((ZCONST char *utf8)); +#endif +#endif /* UNICODE_SUPPORT */ + +#ifndef UTIL /* the companion #endif is a bit of ways down ... */ + +local int fqcmp OF((ZCONST zvoid *, ZCONST zvoid *)); +local int fqcmpz OF((ZCONST zvoid *, ZCONST zvoid *)); + + +/* Local module level variables. */ +char *label = NULL; /* global, but only used in `system'.c */ +local z_stat zipstatb; /* now use z_stat globally - 7/24/04 EG */ +#if defined(UNICODE_SUPPORT) && defined(WIN32) + local zw_stat zipstatbw; +#endif +#if (!defined(MACOS) && !defined(WINDLL)) +local int zipstate = -1; +#else +int zipstate; +#endif +/* -1 unknown, 0 old zip file exists, 1 new zip file */ + +#if 0 +char *getnam(n, fp) +char *n; /* where to put name (must have >=FNMAX+1 bytes) */ +#endif + +/* converted to return string pointer from malloc to avoid + size limitation - 11/8/04 EG */ +#define GETNAM_MAX 9000 /* hopefully big enough for now */ +char *getnam(fp) + FILE *fp; + /* Read a \n or \r delimited name from stdin into n, and return + n. If EOF, then return NULL. Also, if problem return NULL. */ +{ + char name[GETNAM_MAX + 1]; + int c; /* last character read */ + char *p; /* pointer into name area */ + + + p = name; + while ((c = getc(fp)) == '\n' || c == '\r') + ; + if (c == EOF) + return NULL; + do { + if (p - name >= GETNAM_MAX) + return NULL; + *p++ = (char) c; + c = getc(fp); + } while (c != EOF && (c != '\n' && c != '\r')); +#ifdef WIN32 +/* + * WIN32 strips off trailing spaces and periods in filenames + * XXX what about a filename that only consists of spaces ? + * Answer: on WIN32, a filename must contain at least one non-space char + */ + while (p > name) { + if ((c = p[-1]) != ' ' && c != '.') + break; + --p; + } +#endif + *p = 0; + /* malloc a copy */ + if ((p = malloc(strlen(name) + 1)) == NULL) { + return NULL; + } + strcpy(p, name); + return p; +} + +struct flist far *fexpel(f) +struct flist far *f; /* entry to delete */ +/* Delete the entry *f in the doubly-linked found list. Return pointer to + next entry to allow stepping through list. */ +{ + struct flist far *t; /* temporary variable */ + + t = f->nxt; + *(f->lst) = t; /* point last to next, */ + if (t != NULL) + t->lst = f->lst; /* and next to last */ + if (f->name != NULL) /* free memory used */ + free((zvoid *)(f->name)); + if (f->zname != NULL) + free((zvoid *)(f->zname)); + if (f->iname != NULL) + free((zvoid *)(f->iname)); +#ifdef UNICODE_SUPPORT + if (f->uname) + free((zvoid *)f->uname); +# ifdef WIN32 + if (f->namew) + free((zvoid *)f->namew); + if (f->inamew) + free((zvoid *)f->inamew); + if (f->znamew) + free((zvoid *)f->znamew); +# endif +#endif + farfree((zvoid far *)f); + fcount--; /* decrement count */ + return t; /* return pointer to next */ +} + +local int fqcmp(a, b) + ZCONST zvoid *a, *b; /* pointers to pointers to found entries */ +/* Used by qsort() to compare entries in the found list by name. */ +{ + return strcmp((*(struct flist far **)a)->name, + (*(struct flist far **)b)->name); +} + +local int fqcmpz(a, b) + ZCONST zvoid *a, *b; /* pointers to pointers to found entries */ +/* Used by qsort() to compare entries in the found list by iname. */ +{ + return strcmp((*(struct flist far **)a)->iname, + (*(struct flist far **)b)->iname); +} + +char *last(p, c) + char *p; /* sequence of path components */ + int c; /* path components separator character */ +/* Return a pointer to the start of the last path component. For a directory + * name terminated by the character in c, the return value is an empty string. + */ +{ + char *t; /* temporary variable */ + + if ((t = strrchr(p, c)) != NULL) + return t + 1; + else +#ifndef AOS_VS + return p; +#else +/* We want to allow finding of end of path in either AOS/VS-style pathnames + * or Unix-style pathnames. This presents a few little problems ... + */ + { + if (*p == '=' || *p == '^') /* like ./ and ../ respectively */ + return p + 1; + else + return p; + } +#endif +} + +#if defined(UNICODE_SUPPORT) && defined(WIN32) +wchar_t *lastw(pw, c) + wchar_t *pw; /* sequence of path components */ + wchar_t c; /* path components separator character */ +/* Return a pointer to the start of the last path component. For a directory + * name terminated by the character in c, the return value is an empty string. + */ +{ + wchar_t *tw; /* temporary variable */ + + if ((tw = wcsrchr(pw, c)) != NULL) + return tw + 1; + else +# ifndef AOS_VS + return pw; +# else +/* We want to allow finding of end of path in either AOS/VS-style pathnames + * or Unix-style pathnames. This presents a few little problems ... + */ + { + if (*pw == (wchar_t)'=' || *pw == (wchar_t)'^') /* like ./ and ../ respectively */ + return pw + 1; + else + return pw; + } +# endif +} +#endif + + +char *msname(n) + char *n; +/* Reduce all path components to MSDOS upper case 8.3 style names. */ +{ + int c; /* current character */ + int f; /* characters in current component */ + char *p; /* source pointer */ + char *q; /* destination pointer */ + + p = q = n; + f = 0; + while ((c = (unsigned char)*POSTINCSTR(p)) != 0) + if (c == ' ' || c == ':' || c == '"' || c == '*' || c == '+' || + c == ',' || c == ';' || c == '<' || c == '=' || c == '>' || + c == '?' || c == '[' || c == ']' || c == '|') + continue; /* char is discarded */ + else if (c == '/') + { + *POSTINCSTR(q) = (char)c; + f = 0; /* new component */ + } +#ifdef __human68k__ + else if (ismbblead(c) && *p) + { + if (f == 7 || f == 11) + f++; + else if (*p && f < 12 && f != 8) + { + *q++ = c; + *q++ = *p++; + f += 2; + } + } +#endif /* __human68k__ */ + else if (c == '.') + { + if (f == 0) + continue; /* leading dots are discarded */ + else if (f < 9) + { + *POSTINCSTR(q) = (char)c; + f = 9; /* now in file type */ + } + else + f = 12; /* now just excess characters */ + } + else + if (f < 12 && f != 8) + { + f += CLEN(p); /* do until end of name or type */ + *POSTINCSTR(q) = (char)(to_up(c)); + } + *q = 0; + return n; +} + +#ifdef UNICODE_SUPPORT +wchar_t *msnamew(nw) + wchar_t *nw; +/* Reduce all path components to MSDOS upper case 8.3 style names. */ +{ + wchar_t c; /* current character */ + int f; /* characters in current component */ + wchar_t *pw; /* source pointer */ + wchar_t *qw; /* destination pointer */ + + pw = qw = nw; + f = 0; + while ((c = (unsigned char)*pw++) != 0) + if (c == ' ' || c == ':' || c == '"' || c == '*' || c == '+' || + c == ',' || c == ';' || c == '<' || c == '=' || c == '>' || + c == '?' || c == '[' || c == ']' || c == '|') + continue; /* char is discarded */ + else if (c == '/') + { + *qw++ = c; + f = 0; /* new component */ + } +#ifdef __human68k__ + else if (ismbblead(c) && *pw) + { + if (f == 7 || f == 11) + f++; + else if (*pw && f < 12 && f != 8) + { + *qw++ = c; + *qw++ = *pw++; + f += 2; + } + } +#endif /* __human68k__ */ + else if (c == '.') + { + if (f == 0) + continue; /* leading dots are discarded */ + else if (f < 9) + { + *qw++ = c; + f = 9; /* now in file type */ + } + else + f = 12; /* now just excess characters */ + } + else + if (f < 12 && f != 8) + { + f++; /* do until end of name or type */ + *qw++ = towupper(c); + } + *qw = 0; + return nw; +} +#endif + + +int proc_archive_name(n, caseflag) + char *n; /* name to process */ + int caseflag; /* true to force case-sensitive match */ +/* Process a name or sh expression in existing archive to operate + on (or exclude). Return an error code in the ZE_ class. */ +{ + int m; /* matched flag */ + char *p; /* path for recursion */ + struct zlist far *z; /* steps through zfiles list */ + + if (strcmp(n, "-") == 0) { /* if compressing stdin */ + zipwarn("Cannot select stdin when selecting archive entries", ""); + return ZE_MISS; + } + else + { + /* Search for shell expression in zip file */ + p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */ + m = 1; + for (z = zfiles; z != NULL; z = z->nxt) { + if (MATCH(p, z->iname, caseflag)) + { + z->mark = pcount ? filter(z->zname, caseflag) : 1; + if (verbose) + fprintf(mesg, "zip diagnostic: %scluding %s\n", + z->mark ? "in" : "ex", z->oname); + m = 0; + } + } +#ifdef UNICODE_SUPPORT + /* also check escaped Unicode names */ + for (z = zfiles; z != NULL; z = z->nxt) { + if (z->zuname) { +#ifdef WIN32 + /* It seems something is lost in going from a listed + name from zip -su in a console window to using that + name in a command line. This kluge may fix it + and just takes zuname, converts to oem (i.e. ouname), + then converts it back which ends up not the same as + started with. + */ + char *zuname = z->wuname; +#else + char *zuname = z->zuname; +#endif + if (MATCH(p, zuname, caseflag)) + { + z->mark = pcount ? filter(zuname, caseflag) : 1; + if (verbose) { + fprintf(mesg, "zip diagnostic: %scluding %s\n", + z->mark ? "in" : "ex", z->oname); + fprintf(mesg, " Escaped Unicode: %s\n", + z->ouname); + } + m = 0; + } + } + } +#endif + free((zvoid *)p); + return m ? ZE_MISS : ZE_OK; + } +} + + +int check_dup() +/* Sort the found list and remove duplicates. + Return an error code in the ZE_ class. */ +{ + struct flist far *f; /* steps through found linked list */ + extent j, k; /* indices for s */ + struct flist far **s; /* sorted table */ + struct flist far **nodup; /* sorted table without duplicates */ + + /* sort found list, remove duplicates */ + if (fcount) + { + extent fl_size = fcount * sizeof(struct flist far *); + if ((fl_size / sizeof(struct flist far *)) != fcount || + (s = (struct flist far **)malloc(fl_size)) == NULL) + return ZE_MEM; + for (j = 0, f = found; f != NULL; f = f->nxt) + s[j++] = f; + /* Check names as given (f->name) */ + qsort((char *)s, fcount, sizeof(struct flist far *), fqcmp); + for (k = j = fcount - 1; j > 0; j--) + if (strcmp(s[j - 1]->name, s[j]->name) == 0) + /* remove duplicate entry from list */ + fexpel(s[j]); /* fexpel() changes fcount */ + else + /* copy valid entry into destination position */ + s[k--] = s[j]; + s[k] = s[0]; /* First entry is always valid */ + nodup = &s[k]; /* Valid entries are at end of array s */ + + /* sort only valid items and check for unique internal names (f->iname) */ + qsort((char *)nodup, fcount, sizeof(struct flist far *), fqcmpz); + for (j = 1; j < fcount; j++) + if (strcmp(nodup[j - 1]->iname, nodup[j]->iname) == 0) + { + char tempbuf[FNMAX+4081]; + + sprintf(errbuf, " first full name: %s\n", nodup[j - 1]->name); + sprintf(tempbuf, " second full name: %s\n", nodup[j]->name); + strcat(errbuf, " "); + strcat(errbuf, tempbuf); +#ifdef EBCDIC + strtoebc(nodup[j]->iname, nodup[j]->iname); +#endif + sprintf(tempbuf, "name in zip file repeated: %s", nodup[j]->iname); + strcat(errbuf, " "); + strcat(errbuf, tempbuf); + if (pathput == 0) { + strcat(errbuf, "\n this may be a result of using -j"); + } +#ifdef EBCDIC + strtoasc(nodup[j]->iname, nodup[j]->iname); +#endif + zipwarn(errbuf, ""); + return ZE_PARMS; + } + free((zvoid *)s); + } + return ZE_OK; +} + +int filter(name, casesensitive) + char *name; + int casesensitive; + /* Scan the -R, -i and -x lists for matches to the given name. + Return TRUE if the name must be included, FALSE otherwise. + Give precedence to -x over -i and -R. + Note that if both R and i patterns are given then must + have a match for both. + This routine relies on the following global variables: + patterns array of match pattern structures + pcount total number of patterns + icount number of -i patterns + Rcount number of -R patterns + These data are set up by the command line parsing code. + */ +{ + unsigned int n; + int slashes; + char *p, *q; + /* without -i patterns, every name matches the "-i select rules" */ + int imatch = (icount == 0); + /* without -R patterns, every name matches the "-R select rules" */ + int Rmatch = (Rcount == 0); + + if (pcount == 0) return TRUE; + + for (n = 0; n < pcount; n++) { + if (!patterns[n].zname[0]) /* it can happen... */ + continue; + p = name; + switch (patterns[n].select) { + case 'R': + if (Rmatch) + /* one -R match is sufficient, skip this pattern */ + continue; + /* With -R patterns, if the pattern has N path components (that is, + N-1 slashes), then we test only the last N components of name. + */ + slashes = 0; + for (q = patterns[n].zname; (q = MBSCHR(q, '/')) != NULL; MB_NEXTCHAR(q)) + slashes++; + /* The name may have M path components (M-1 slashes) */ + for (q = p; (q = MBSCHR(q, '/')) != NULL; MB_NEXTCHAR(q)) + slashes--; + /* Now, "slashes" contains the difference "N-M" between the number + of path components in the pattern (N) and in the name (M). + */ + if (slashes < 0) + /* We found "M > N" + --> skip the first (M-N) path components of the name. + */ + for (q = p; (q = MBSCHR(q, '/')) != NULL; MB_NEXTCHAR(q)) + if (++slashes == 0) { + p = q + 1; /* q points at '/', mblen("/") is 1 */ + break; + } + break; + case 'i': + if (imatch) + /* one -i match is sufficient, skip this pattern */ + continue; + break; + } + if (MATCH(patterns[n].zname, p, casesensitive)) { + switch (patterns[n].select) { + case 'x': + /* The -x match takes precedence over everything else */ + return FALSE; + case 'R': + Rmatch = TRUE; + break; + default: + /* this must be a type -i match */ + imatch = TRUE; + break; + } + } + } + return imatch && Rmatch; +} + + +#ifdef UNICODE_SUPPORT +# ifdef WIN32 + +int newnamew(namew, isdir, casesensitive) + wchar_t *namew; /* name to add (or exclude) */ + int isdir; /* true for a directory */ + int casesensitive; /* true for case-sensitive matching */ +/* Add (or exclude) the name of an existing disk file. Return an error + code in the ZE_ class. */ +{ + wchar_t *inamew = NULL; /* internal name */ + wchar_t *znamew = NULL; /* external version of iname */ + wchar_t *undosmw = NULL; /* zname version with "-j" and "-k" options disabled */ + char *oname = NULL; /* iname converted for display */ + char *name = NULL; + char *iname = NULL; + char *zname = NULL; + char *zuname = NULL; + char *undosm = NULL; + struct flist far *f; /* where in found, or new found entry */ + struct zlist far *z; /* where in zfiles (if found) */ + int dosflag; + + /* Scanning files ... + * + * After 5 seconds output Scanning files... + * then a dot every 2 seconds + */ + if (noisy) { + /* If find files then output message after delay */ + if (scan_count == 0) { + time_t current = time(NULL); + scan_start = current; + } + scan_count++; + if (scan_count % 100 == 0) { + time_t current = time(NULL); + + if (current - scan_start > scan_delay) { + if (scan_last == 0) { + zipmessage_nl("Scanning files ", 0); + scan_last = current; + } + if (current - scan_last > scan_dot_time) { + scan_last = current; + fprintf(mesg, "."); + fflush(mesg); + } + } + } + } + + /* Search for name in zip file. If there, mark it, else add to + list of new names to do (or remove from that list). */ + if ((inamew = ex2inw(namew, isdir, &dosflag)) == NULL) + return ZE_MEM; + + /* Discard directory names with zip -rj */ + if (*inamew == (wchar_t)'\0') { + + /* If extensions needs to be swapped, we will have empty directory names + instead of the original directory. For example, zipping 'c.', 'c.main' + should zip only 'main.c' while 'c.' will be converted to '\0' by ex2in. */ + + if (pathput && !recurse) error("empty name without -j or -r"); + free((zvoid *)inamew); + return ZE_OK; + } + + if (dosflag || !pathput) { + int save_dosify = dosify, save_pathput = pathput; + dosify = 0; + pathput = 1; + /* zname is temporarly mis-used as "undosmode" iname pointer */ + if ((znamew = ex2inw(namew, isdir, NULL)) != NULL) { + undosmw = in2exw(znamew); + free(znamew); + } + dosify = save_dosify; + pathput = save_pathput; + } + if ((znamew = in2exw(inamew)) == NULL) + return ZE_MEM; + + /* Convert names from wchar_t to char */ + + name = wchar_to_local_string(namew); + iname = wchar_to_local_string(inamew); + zname = wchar_to_local_string(znamew); + + oname = local_to_display_string(zname); + + zuname = wchar_to_local_string(znamew); + + if (undosmw == NULL) + undosmw = znamew; + undosm = wchar_to_local_string(undosmw); + + if ((z = zsearch(zuname)) != NULL) { + if (pcount && !filter(undosm, casesensitive)) { + /* Do not clear z->mark if "exclude", because, when "dosify || !pathput" + * is in effect, two files with different filter options may hit the + * same z entry. + */ + if (verbose) + fprintf(mesg, "excluding %s\n", oname); + } else { + z->mark = 1; + if ((z->name = malloc(strlen(name) + 1 + PAD)) == NULL) { + if (undosmw != znamew) + free(undosmw); + if (undosm) free(undosm); + if (inamew) free(inamew); + if (znamew) free(znamew); + if (name) free(name); + if (iname) free(iname); + if (zname) free(zname); + if (oname) free(oname); + if (zuname) free(zuname); + return ZE_MEM; + } + strcpy(z->name, name); + z->oname = oname; + oname = NULL; + z->dosflag = dosflag; + +#ifdef FORCE_NEWNAME + free((zvoid *)(z->iname)); + z->iname = iname; + iname = NULL; +#else + /* Better keep the old name. Useful when updating on MSDOS a zip file + * made on Unix. + */ +#endif /* ? FORCE_NEWNAME */ + } + + if ((z->namew = (wchar_t *)malloc((wcslen(namew) + 1) * sizeof(wchar_t))) == NULL) { + if (undosmw != znamew) + free(undosmw); + if (undosm) free(undosm); + if (inamew) free(inamew); + if (znamew) free(znamew); + if (name) free(name); + if (iname) free(iname); + if (zname) free(zname); + if (oname) free(oname); + if (zuname) free(zuname); + return ZE_MEM; + } + wcscpy(z->namew, namew); + z->inamew = inamew; + inamew = NULL; + z->znamew = znamew; + znamew = NULL; + z->uname = wchar_to_utf8_string(z->inamew); + if (name == label) { + label = z->name; + } + } else if (pcount == 0 || filter(undosm, casesensitive)) { + + /* Check that we are not adding the zip file to itself. This + * catches cases like "zip -m foo ../dir/foo.zip". + */ +/* Version of stat() for CMS/MVS isn't complete enough to see if */ +/* files match. Just let ZIP.C compare the filenames. That's good */ +/* enough for CMS anyway since there aren't paths to worry about. */ + zw_stat statbw; /* need for wide stat */ + wchar_t *zipfilew = local_to_wchar_string(zipfile); + + if (zipstate == -1) + zipstate = strcmp(zipfile, "-") != 0 && + zwstat(zipfilew, &zipstatbw) == 0; + free(zipfilew); + + if (zipstate == 1 && (statbw = zipstatbw, zwstat(namew, &statbw) == 0 + && zipstatbw.st_mode == statbw.st_mode + && zipstatbw.st_ino == statbw.st_ino + && zipstatbw.st_dev == statbw.st_dev + && zipstatbw.st_uid == statbw.st_uid + && zipstatbw.st_gid == statbw.st_gid + && zipstatbw.st_size == statbw.st_size + && zipstatbw.st_mtime == statbw.st_mtime + && zipstatbw.st_ctime == statbw.st_ctime)) { + /* Don't compare a_time since we are reading the file */ + if (verbose) + fprintf(mesg, "file matches zip file -- skipping\n"); + if (undosmw != znamew) + free(undosmw); + if (undosm) free(undosm); + if (inamew) free(inamew); + if (znamew) free(znamew); + if (name) free(name); + if (iname) free(iname); + if (zname) free(zname); + if (oname) free(oname); + if (zuname) free(zuname); + return ZE_OK; + } + + /* allocate space and add to list */ + if ((f = (struct flist far *)farmalloc(sizeof(struct flist))) == NULL || + fcount + 1 < fcount || + (f->name = malloc(strlen(name) + 1 + PAD)) == NULL) + { + if (f != NULL) + farfree((zvoid far *)f); + if (undosmw != znamew) + free(undosmw); + if (undosm) free(undosm); + if (inamew) free(inamew); + if (znamew) free(znamew); + if (name) free(name); + if (iname) free(iname); + if (zname) free(zname); + if (oname) free(oname); + if (zuname) free(zuname); + return ZE_MEM; + } + if (undosmw != znamew) + free((zvoid *)undosmw); + strcpy(f->name, name); + f->iname = iname; + iname = NULL; + f->zname = zname; + zname = NULL; + /* Unicode */ + if ((f->namew = (wchar_t *)malloc((wcslen(namew) + 1) * sizeof(wchar_t))) == NULL) { + if (f != NULL) + farfree((zvoid far *)f); + if (undosmw != znamew) + free(undosmw); + if (undosm) free(undosm); + if (inamew) free(inamew); + if (znamew) free(znamew); + if (name) free(name); + if (iname) free(iname); + if (zname) free(zname); + if (oname) free(oname); + if (zuname) free(zuname); + return ZE_MEM; + } + wcscpy(f->namew, namew); + f->znamew = znamew; + znamew = NULL; + f->uname = wchar_to_utf8_string(inamew); + f->inamew = inamew; + inamew = NULL; + f->oname = oname; + oname = NULL; + f->dosflag = dosflag; + *fnxt = f; + f->lst = fnxt; + f->nxt = NULL; + fnxt = &f->nxt; + fcount++; + if (name == label) { + label = f->name; + } + } + if (undosm) free(undosm); + if (inamew) free(inamew); + if (znamew) free(znamew); + if (name) free(name); + if (iname) free(iname); + if (zname) free(zname); + if (oname) free(oname); + if (zuname) free(zuname); + return ZE_OK; +} + +# endif +#endif + +int newname(name, isdir, casesensitive) + char *name; /* name to add (or exclude) */ + int isdir; /* true for a directory */ + int casesensitive; /* true for case-sensitive matching */ +/* Add (or exclude) the name of an existing disk file. Return an error + code in the ZE_ class. */ +{ + char *iname, *zname; /* internal name, external version of iname */ + char *undosm; /* zname version with "-j" and "-k" options disabled */ + char *oname; /* iname converted for display */ + struct flist far *f; /* where in found, or new found entry */ + struct zlist far *z; /* where in zfiles (if found) */ + int dosflag; + + /* Scanning files ... + * + * After 5 seconds output Scanning files... + * then a dot every 2 seconds + */ + if (noisy) { + /* If find files then output message after delay */ + if (scan_count == 0) { + time_t current = time(NULL); + scan_start = current; + } + scan_count++; + if (scan_count % 100 == 0) { + time_t current = time(NULL); + + if (current - scan_start > scan_delay) { + if (scan_last == 0) { + zipmessage_nl("Scanning files ", 0); + scan_last = current; + } + if (current - scan_last > scan_dot_time) { + scan_last = current; + fprintf(mesg, "."); + fflush(mesg); + } + } + } + } + + /* Search for name in zip file. If there, mark it, else add to + list of new names to do (or remove from that list). */ + if ((iname = ex2in(name, isdir, &dosflag)) == NULL) + return ZE_MEM; + + /* Discard directory names with zip -rj */ + if (*iname == '\0') { +#ifndef AMIGA +/* A null string is a legitimate external directory name in AmigaDOS; also, + * a command like "zip -r zipfile FOO:" produces an empty internal name. + */ +# ifndef RISCOS + /* If extensions needs to be swapped, we will have empty directory names + instead of the original directory. For example, zipping 'c.', 'c.main' + should zip only 'main.c' while 'c.' will be converted to '\0' by ex2in. */ + + if (pathput && !recurse) error("empty name without -j or -r"); + +# endif /* !RISCOS */ +#endif /* !AMIGA */ + free((zvoid *)iname); + return ZE_OK; + } + undosm = NULL; + if (dosflag || !pathput) { + int save_dosify = dosify, save_pathput = pathput; + dosify = 0; + pathput = 1; + /* zname is temporarly mis-used as "undosmode" iname pointer */ + if ((zname = ex2in(name, isdir, NULL)) != NULL) { + undosm = in2ex(zname); + free(zname); + } + dosify = save_dosify; + pathput = save_pathput; + } + if ((zname = in2ex(iname)) == NULL) + return ZE_MEM; +#ifdef UNICODE_SUPPORT + /* Convert name to display or OEM name */ + oname = local_to_display_string(iname); +#else + if ((oname = malloc(strlen(zname) + 1)) == NULL) + return ZE_MEM; + strcpy(oname, zname); +#endif + if (undosm == NULL) + undosm = zname; + if ((z = zsearch(zname)) != NULL) { + if (pcount && !filter(undosm, casesensitive)) { + /* Do not clear z->mark if "exclude", because, when "dosify || !pathput" + * is in effect, two files with different filter options may hit the + * same z entry. + */ + if (verbose) + fprintf(mesg, "excluding %s\n", oname); + free((zvoid *)iname); + free((zvoid *)zname); + } else { + z->mark = 1; + if ((z->name = malloc(strlen(name) + 1 + PAD)) == NULL) { + if (undosm != zname) + free((zvoid *)undosm); + free((zvoid *)iname); + free((zvoid *)zname); + return ZE_MEM; + } + strcpy(z->name, name); + z->oname = oname; + z->dosflag = dosflag; + +#ifdef FORCE_NEWNAME + free((zvoid *)(z->iname)); + z->iname = iname; +#else + /* Better keep the old name. Useful when updating on MSDOS a zip file + * made on Unix. + */ + free((zvoid *)iname); + free((zvoid *)zname); +#endif /* ? FORCE_NEWNAME */ + } +#if defined(UNICODE_SUPPORT) && defined(WIN32) + z->namew = NULL; + z->inamew = NULL; + z->znamew = NULL; +#endif + if (name == label) { + label = z->name; + } + } else if (pcount == 0 || filter(undosm, casesensitive)) { + + /* Check that we are not adding the zip file to itself. This + * catches cases like "zip -m foo ../dir/foo.zip". + */ +#ifndef CMS_MVS +/* Version of stat() for CMS/MVS isn't complete enough to see if */ +/* files match. Just let ZIP.C compare the filenames. That's good */ +/* enough for CMS anyway since there aren't paths to worry about. */ + z_stat statb; /* now use structure z_stat and function zstat globally 7/24/04 EG */ + + if (zipstate == -1) + zipstate = strcmp(zipfile, "-") != 0 && + zstat(zipfile, &zipstatb) == 0; + + if (zipstate == 1 && (statb = zipstatb, zstat(name, &statb) == 0 + && zipstatb.st_mode == statb.st_mode +#ifdef VMS + && memcmp(zipstatb.st_ino, statb.st_ino, sizeof(statb.st_ino)) == 0 + && strcmp(zipstatb.st_dev, statb.st_dev) == 0 + && zipstatb.st_uid == statb.st_uid +#else /* !VMS */ + && zipstatb.st_ino == statb.st_ino + && zipstatb.st_dev == statb.st_dev + && zipstatb.st_uid == statb.st_uid + && zipstatb.st_gid == statb.st_gid +#endif /* ?VMS */ + && zipstatb.st_size == statb.st_size + && zipstatb.st_mtime == statb.st_mtime + && zipstatb.st_ctime == statb.st_ctime)) { + /* Don't compare a_time since we are reading the file */ + if (verbose) + fprintf(mesg, "file matches zip file -- skipping\n"); + if (undosm != zname) + free((zvoid *)zname); + if (undosm != iname) + free((zvoid *)undosm); + free((zvoid *)iname); + free(oname); + return ZE_OK; + } +#endif /* CMS_MVS */ + + /* allocate space and add to list */ + if ((f = (struct flist far *)farmalloc(sizeof(struct flist))) == NULL || + fcount + 1 < fcount || + (f->name = malloc(strlen(name) + 1 + PAD)) == NULL) + { + if (f != NULL) + farfree((zvoid far *)f); + if (undosm != zname) + free((zvoid *)undosm); + free((zvoid *)iname); + free((zvoid *)zname); + free(oname); + return ZE_MEM; + } + strcpy(f->name, name); + f->iname = iname; + f->zname = zname; +#ifdef UNICODE_SUPPORT + /* Unicode */ + f->uname = local_to_utf8_string(iname); +#ifdef WIN32 + f->namew = NULL; + f->inamew = NULL; + f->znamew = NULL; + if (strcmp(f->name, "-") == 0) { + f->namew = local_to_wchar_string(f->name); + } +#endif + +#endif + f->oname = oname; + f->dosflag = dosflag; + + *fnxt = f; + f->lst = fnxt; + f->nxt = NULL; + fnxt = &f->nxt; + fcount++; + if (name == label) { + label = f->name; + } + } + if (undosm != zname) + free((zvoid *)undosm); + return ZE_OK; +} + +ulg dostime(y, n, d, h, m, s) +int y; /* year */ +int n; /* month */ +int d; /* day */ +int h; /* hour */ +int m; /* minute */ +int s; /* second */ +/* Convert the date y/n/d and time h:m:s to a four byte DOS date and + time (date in high two bytes, time in low two bytes allowing magnitude + comparison). */ +{ + return y < 1980 ? DOSTIME_MINIMUM /* dostime(1980, 1, 1, 0, 0, 0) */ : + (((ulg)y - 1980) << 25) | ((ulg)n << 21) | ((ulg)d << 16) | + ((ulg)h << 11) | ((ulg)m << 5) | ((ulg)s >> 1); +} + + +ulg unix2dostime(t) +time_t *t; /* unix time to convert */ +/* Return the Unix time t in DOS format, rounded up to the next two + second boundary. */ +{ + time_t t_even; + struct tm *s; /* result of localtime() */ + + t_even = (time_t)(((unsigned long)(*t) + 1) & (~1)); + /* Round up to even seconds. */ + s = localtime(&t_even); /* Use local time since MSDOS does. */ + if (s == (struct tm *)NULL) { + /* time conversion error; use current time as emergency value + (assuming that localtime() does at least accept this value!) */ + t_even = (time_t)(((unsigned long)time(NULL) + 1) & (~1)); + s = localtime(&t_even); + } + return dostime(s->tm_year + 1900, s->tm_mon + 1, s->tm_mday, + s->tm_hour, s->tm_min, s->tm_sec); +} + +int issymlnk(a) +ulg a; /* Attributes returned by filetime() */ +/* Return true if the attributes are those of a symbolic link */ +{ +#ifndef QDOS +#ifdef S_IFLNK +#ifdef __human68k__ + int *_dos_importlnenv(void); + + if (_dos_importlnenv() == NULL) + return 0; +#endif + return ((a >> 16) & S_IFMT) == S_IFLNK; +#else /* !S_IFLNK */ + return (int)a & 0; /* avoid warning on unused parameter */ +#endif /* ?S_IFLNK */ +#else + return 0; +#endif +} + +#endif /* !UTIL */ + + +#if (!defined(UTIL) && !defined(ZP_NEED_GEN_D2U_TIME)) + /* There is no need for dos2unixtime() in the ZipUtils' code. */ +# define ZP_NEED_GEN_D2U_TIME +#endif +#if ((defined(OS2) || defined(VMS)) && defined(ZP_NEED_GEN_D2U_TIME)) + /* OS/2 and VMS use a special solution to handle time-stams of files. */ +# undef ZP_NEED_GEN_D2U_TIME +#endif +#if (defined(W32_STATROOT_FIX) && !defined(ZP_NEED_GEN_D2U_TIME)) + /* The Win32 stat()-bandaid to fix stat'ing root directories needs + * dos2unixtime() to calculate the time-stamps. */ +# define ZP_NEED_GEN_D2U_TIME +#endif + +#ifdef ZP_NEED_GEN_D2U_TIME + +time_t dos2unixtime(dostime) +ulg dostime; /* DOS time to convert */ +/* Return the Unix time_t value (GMT/UTC time) for the DOS format (local) + * time dostime, where dostime is a four byte value (date in most significant + * word, time in least significant word), see dostime() function. + */ +{ + struct tm *t; /* argument for mktime() */ + ZCONST time_t clock = time(NULL); + + t = localtime(&clock); + t->tm_isdst = -1; /* let mktime() determine if DST is in effect */ + /* Convert DOS time to UNIX time_t format */ + t->tm_sec = (((int)dostime) << 1) & 0x3e; + t->tm_min = (((int)dostime) >> 5) & 0x3f; + t->tm_hour = (((int)dostime) >> 11) & 0x1f; + t->tm_mday = (int)(dostime >> 16) & 0x1f; + t->tm_mon = ((int)(dostime >> 21) & 0x0f) - 1; + t->tm_year = ((int)(dostime >> 25) & 0x7f) + 80; + + return mktime(t); +} + +#undef ZP_NEED_GEN_D2U_TIME +#endif /* ZP_NEED_GEN_D2U_TIME */ + + +#ifndef MACOS +int destroy(f) + char *f; /* file to delete */ +/* Delete the file *f, returning non-zero on failure. */ +{ + return unlink(f); +} + + +int replace(d, s) +char *d, *s; /* destination and source file names */ +/* Replace file *d by file *s, removing the old *s. Return an error code + in the ZE_ class. This function need not preserve the file attributes, + this will be done by setfileattr() later. + */ +{ + z_stat t; /* results of stat() */ +#if defined(CMS_MVS) + /* cmsmvs.h defines FOPW_TEMP as memory(hiperspace). Since memory is + * lost at end of run, always do copy instead of rename. + */ + int copy = 1; +#else + int copy = 0; +#endif + int d_exists; + +#if defined(VMS) || defined(CMS_MVS) + /* stat() is broken on VMS remote files (accessed through Decnet). + * This patch allows creation of remote zip files, but is not sufficient + * to update them or compress remote files */ + unlink(d); +#else /* !(VMS || CMS_MVS) */ + d_exists = (LSTAT(d, &t) == 0); + if (d_exists) + { + /* + * respect existing soft and hard links! + */ + if (t.st_nlink > 1 +# ifdef S_IFLNK + || (t.st_mode & S_IFMT) == S_IFLNK +# endif + ) + copy = 1; + else if (unlink(d)) + return ZE_CREAT; /* Can't erase zip file--give up */ + } +#endif /* ?(VMS || CMS_MVS) */ +#ifndef CMS_MVS + if (!copy) { + if (rename(s, d)) { /* Just move s on top of d */ + copy = 1; /* failed ? */ +#if !defined(VMS) && !defined(ATARI) && !defined(AZTEC_C) +#if !defined(CMS_MVS) && !defined(RISCOS) && !defined(QDOS) + /* For VMS, ATARI, AMIGA Aztec, VM_CMS, MVS, RISCOS, + always assume that failure is EXDEV */ + if (errno != EXDEV +# ifdef THEOS + && errno != EEXIST +# else +# ifdef ENOTSAM + && errno != ENOTSAM /* Used at least on Turbo C */ +# endif +# endif + ) return ZE_CREAT; +#endif /* !CMS_MVS && !RISCOS */ +#endif /* !VMS && !ATARI && !AZTEC_C */ + } + } +#endif /* !CMS_MVS */ + + if (copy) { + FILE *f, *g; /* source and destination files */ + int r; /* temporary variable */ + +#ifdef RISCOS + if (SWI_OS_FSControl_26(s,d,0xA1)!=NULL) { +#endif + + /* Use zfopen for almost all opens where fopen is used. For + most OS that support large files we use the 64-bit file + environment and zfopen maps to fopen, but this allows + tweeking ports that don't do that. 7/24/04 */ + if ((f = zfopen(s, FOPR)) == NULL) { + fprintf(mesg," replace: can't open %s\n", s); + return ZE_TEMP; + } + if ((g = zfopen(d, FOPW)) == NULL) + { + fclose(f); + return ZE_CREAT; + } + + r = fcopy(f, g, (ulg)-1L); + fclose(f); + if (fclose(g) || r != ZE_OK) + { + unlink(d); + return r ? (r == ZE_TEMP ? ZE_WRITE : r) : ZE_WRITE; + } + unlink(s); +#ifdef RISCOS + } +#endif + } + return ZE_OK; +} +#endif /* !MACOS */ + + +int getfileattr(f) +char *f; /* file path */ +/* Return the file attributes for file f or 0 if failure */ +{ +#ifdef __human68k__ + struct _filbuf buf; + + return _dos_files(&buf, f, 0xff) < 0 ? 0x20 : buf.atr; +#else + z_stat s; + + return SSTAT(f, &s) == 0 ? (int) s.st_mode : 0; +#endif +} + + +int setfileattr(f, a) +char *f; /* file path */ +int a; /* attributes returned by getfileattr() */ +/* Give the file f the attributes a, return non-zero on failure */ +{ +#if defined(TOPS20) || defined (CMS_MVS) + return 0; +#else +#ifdef __human68k__ + return _dos_chmod(f, a) < 0 ? -1 : 0; +#else + return chmod(f, a); +#endif +#endif +} + + +/* tempname */ + +#ifndef VMS /* VMS-specific function is in VMS.C. */ + +char *tempname(zip) + char *zip; /* path name of zip file to generate temp name for */ + +/* Return a temporary file name in its own malloc'ed space, using tempath. */ +{ + char *t = zip; /* malloc'ed space for name (use zip to avoid warning) */ + +# ifdef CMS_MVS + if ((t = malloc(strlen(tempath) + L_tmpnam + 2)) == NULL) + return NULL; + +# ifdef VM_CMS + tmpnam(t); + /* Remove filemode and replace with tempath, if any. */ + /* Otherwise A-disk is used by default */ + *(strrchr(t, ' ')+1) = '\0'; + if (tempath!=NULL) + strcat(t, tempath); + return t; +# else /* !VM_CMS */ + /* For MVS */ + tmpnam(t); + if (tempath != NULL) + { + int l1 = strlen(t); + char *dot; + if (*t == '\'' && *(t+l1-1) == '\'' && (dot = strchr(t, '.'))) + { + /* MVS and not OE. tmpnam() returns quoted string of 5 qualifiers. + * First is HLQ, rest are timestamps. User can only replace HLQ. + */ + int l2 = strlen(tempath); + if (strchr(tempath, '.') || l2 < 1 || l2 > 8) + ziperr(ZE_PARMS, "On MVS and not OE, tempath (-b) can only be HLQ"); + memmove(t+1+l2, dot, l1+1-(dot-t)); /* shift dot ready for new hlq */ + memcpy(t+1, tempath, l2); /* insert new hlq */ + } + else + { + /* MVS and probably OE. tmpnam() returns filename based on TMPDIR, + * no point in even attempting to change it. User should modify TMPDIR + * instead. + */ + zipwarn("MVS, assumed to be OE, change TMPDIR instead of option -b: ", + tempath); + } + } + return t; +# endif /* !VM_CMS */ + +# else /* !CMS_MVS */ + +# ifdef TANDEM + char cur_subvol [FILENAME_MAX]; + char temp_subvol [FILENAME_MAX]; + char *zptr; + char *ptr; + char *cptr = &cur_subvol[0]; + char *tptr = &temp_subvol[0]; + short err; + FILE *tempf; + int attempts; + + t = (char *)malloc(NAMELEN); /* malloc here as you cannot free */ + /* tmpnam allocated storage later */ + + zptr = strrchr(zip, TANDEM_DELIMITER); + + if (zptr != NULL) { + /* ZIP file specifies a Subvol so make temp file there so it can just + be renamed at end */ + + *tptr = *cptr = '\0'; + strcat(cptr, getenv("DEFAULTS")); + + strncat(tptr, zip, _min(FILENAME_MAX, (zptr - zip)) ); /* temp subvol */ + strncat(t, zip, _min(NAMELEN, ((zptr - zip) + 1)) ); /* temp stem */ + + err = chvol(tptr); + ptr = t + strlen(t); /* point to end of stem */ + } + else + ptr = t; + + /* If two zips are running in same subvol then we can get contention problems + with the temporary filename. As a work around we attempt to create + the file here, and if it already exists we get a new temporary name */ + + attempts = 0; + do { + attempts++; + tmpnam(ptr); /* Add filename */ + tempf = zfopen(ptr, FOPW_TMP); /* Attempt to create file */ + } while (tempf == NULL && attempts < 100); + + if (attempts >= 100) { + ziperr(ZE_TEMP, "Could not get unique temp file name"); + } + + fclose(tempf); + + if (zptr != NULL) { + err = chvol(cptr); /* Put ourself back to where we came in */ + } + + return t; + +# else /* !CMS_MVS && !TANDEM */ +/* + * Do something with TMPDIR, TMP, TEMP ???? + */ + if (tempath != NULL) + { + if ((t = malloc(strlen(tempath) + 12)) == NULL) + return NULL; + strcpy(t, tempath); + +# if (!defined(VMS) && !defined(TOPS20)) +# ifdef MSDOS + { + char c = (char)lastchar(t); + if (c != '/' && c != ':' && c != '\\') + strcat(t, "/"); + } +# else + +# ifdef AMIGA + { + char c = (char)lastchar(t); + if (c != '/' && c != ':') + strcat(t, "/"); + } +# else /* !AMIGA */ +# ifdef RISCOS + if (lastchar(t) != '.') + strcat(t, "."); +# else /* !RISCOS */ + +# ifdef QDOS + if (lastchar(t) != '_') + strcat(t, "_"); +# else + if (lastchar(t) != '/') + strcat(t, "/"); +# endif /* ?QDOS */ +# endif /* ?RISCOS */ +# endif /* ?AMIGA */ +# endif /* ?MSDOS */ +# endif /* !VMS && !TOPS20 */ + } + else + { + if ((t = malloc(12)) == NULL) + return NULL; + *t = 0; + } +# ifdef NO_MKTEMP + { + char *p = t + strlen(t); + sprintf(p, "%08lx", (ulg)time(NULL)); + return t; + } +# else + strcat(t, "ziXXXXXX"); /* must use lowercase for Linux dos file system */ +# if defined(UNIX) && !defined(NO_MKSTEMP) + /* tempname should not be called */ + return t; +# else + return mktemp(t); +# endif +# endif /* NO_MKTEMP */ +# endif /* TANDEM */ +# endif /* CMS_MVS */ +} +#endif /* !VMS */ + +int fcopy(f, g, n) + FILE *f, *g; /* source and destination files */ + /* now use uzoff_t for all file sizes 5/14/05 CS */ + uzoff_t n; /* number of bytes to copy or -1 for all */ +/* Copy n bytes from file *f to file *g, or until EOF if (zoff_t)n == -1. + Return an error code in the ZE_ class. */ +{ + char *b; /* malloc'ed buffer for copying */ + extent k; /* result of fread() */ + uzoff_t m; /* bytes copied so far */ + + if ((b = malloc(CBSZ)) == NULL) + return ZE_MEM; + m = 0; + while (n == (uzoff_t)(-1L) || m < n) + { + if ((k = fread(b, 1, n == (uzoff_t)(-1) ? + CBSZ : (n - m < CBSZ ? (extent)(n - m) : CBSZ), f)) == 0) + { + if (ferror(f)) + { + free((zvoid *)b); + return ZE_READ; + } + else + break; + } + if (fwrite(b, 1, k, g) != k) + { + free((zvoid *)b); + fprintf(mesg," fcopy: write error\n"); + return ZE_TEMP; + } + m += k; + } + free((zvoid *)b); + return ZE_OK; +} + + +/* from zipfile.c */ + +#ifdef THEOS + /* Macros cause stack overflow in compiler */ + ush SH(uch* p) { return ((ush)(uch)((p)[0]) | ((ush)(uch)((p)[1]) << 8)); } + ulg LG(uch* p) { return ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16)); } +#else /* !THEOS */ + /* Macros for converting integers in little-endian to machine format */ +# define SH(a) ((ush)(((ush)(uch)(a)[0]) | (((ush)(uch)(a)[1]) << 8))) +# define LG(a) ((ulg)SH(a) | ((ulg)SH((a)+2) << 16)) +# ifdef ZIP64_SUPPORT /* zip64 support 08/31/2003 R.Nausedat */ +# define LLG(a) ((zoff_t)LG(a) | ((zoff_t)LG((a)+4) << 32)) +# endif +#endif /* ?THEOS */ + + +/* always copies from global in_file to global output file y */ +int bfcopy(n) + /* now use uzoff_t for all file sizes 5/14/05 CS */ + uzoff_t n; /* number of bytes to copy or -1 for all */ +/* Copy n bytes from in_file to out_file, or until EOF if (zoff_t)n == -1. + + Normally we have the compressed size from either the central directory + entry or the local header. + + If n != -1 and EOF, close current split and open next and continue + copying. + + If n == -2, copy until find the extended header (data descriptor). Only + used for -FF when no size available. + + If fix == 1 calculate CRC of input entry and verify matches. + + If fix == 2 and this entry using data descriptor keep a sliding + window in the buffer for looking for signature. + + Return an error code in the ZE_ class. */ +{ + char *b; /* malloc'ed buffer for copying */ + extent k; /* result of fread() */ + uzoff_t m; /* bytes copied so far */ + extent brd; /* bytes to read */ + zoff_t data_start = 0; + zoff_t des_start = 0; + char *split_path; + extent kk; + int i; + char sbuf[4]; /* buffer for sliding signature window for fix = 2 */ + int des = 0; /* this entry has data descriptor to find */ + + if ((b = malloc(CBSZ)) == NULL) + return ZE_MEM; + + if (copy_only && !display_globaldots) { + /* initialize dot count */ + dot_count = -1; + } + + if (fix == 2 && n == (uzoff_t) -2) { + data_start = zftello(in_file); + for (kk = 0; kk < 4; kk++) + sbuf[kk] = 0; + des = 1; + } + + des_good = 0; + + m = 0; + while (des || n == (uzoff_t)(-1L) || m < n) + { + if (des || n == (uzoff_t)(-1)) + brd = CBSZ; + else + brd = (n - m < CBSZ ? (extent)(n - m) : CBSZ); + + des_start = zftello(in_file); + + if ((k = fread(b, 1, brd, in_file)) == 0) + { + if (fix == 2 && k < brd) { + free((zvoid *)b); + return ZE_READ; + } + else if (ferror(in_file)) + { + free((zvoid *)b); + return ZE_READ; + } + else { + break; + } + } + + + /* end at extended local header (data descriptor) signature */ + if (des) { + des_crc = 0; + des_csize = 0; + des_usize = 0; + + /* If first 4 bytes in buffer are data descriptor signature then + try to read the data descriptor. + If not, scan for signature and break if found, let bfwrite flush + the data and then next read should put the data descriptor at + the beginning of the buffer. + */ + + if ( + (b[0] != 0x50 /*'P' except EBCDIC*/ || + b[1] != 0x4b /*'K' except EBCDIC*/ || + b[2] != '\07' || + b[3] != '\010')) { + /* buffer is not start of data descriptor */ + + for (kk = 0; kk < k; kk++) { + /* add byte to end of sbuf */ + for (i = 0; i < 3; i++) + sbuf[i] = sbuf[i + 1]; + sbuf[3] = b[kk]; + + /* see if this is signature */ + if ( + (sbuf[0] == 0x50 /*'P' except EBCDIC*/ && + sbuf[1] == 0x4b /*'K' except EBCDIC*/ && + sbuf[2] == '\07' && + sbuf[3] == '\010')) { + kk -= 3; + if (zfseeko(in_file, bytes_this_split + kk, SEEK_SET) != 0) { + /* seek error */ + ZIPERR(ZE_READ, "seek failed reading descriptor"); + } + des_start = zftello(in_file); + k = kk; + break; + } + } + } + else + + /* signature at start of buffer */ + { + des_good = 0; + +#ifdef ZIP64_SUPPORT + if (zip64_entry) { + + /* read Zip64 data descriptor */ + if (k < 24) { + /* not enough bytes, so can't be data descriptor + as data descriptors can't be split across splits + */ + } + else + { + /* read the Zip64 descriptor */ + + des_crc = LG(b + 4); + des_csize = LLG(b + 8); + des_usize = LLG(b + 16); + + /* if this is the right data descriptor then the sizes should match */ + if ((uzoff_t)des_start - (uzoff_t)data_start != des_csize) { + /* apparently this signature does not go with this data so skip */ + + /* write out signature as data */ + k = 4; + if (zfseeko(in_file, des_start + k, SEEK_SET) != 0) { + /* seek error */ + ZIPERR(ZE_READ, "seek failed reading descriptor"); + } + if (bfwrite(b, 1, k, BFWRITE_DATA) != k) + { + free((zvoid *)b); + fprintf(mesg," fcopy: write error\n"); + return ZE_TEMP; + } + m += k; + continue; + } + else + { + /* apparently this is the correct data descriptor */ + + /* we should check the CRC but would need to inflate + the data */ + + /* skip descriptor as will write out later */ + des_good = 1; + k = 24; + data_start = zftello(in_file); + if (zfseeko(in_file, des_start + k, SEEK_SET) != 0) { + /* seek error */ + ZIPERR(ZE_READ, "seek failed reading descriptor"); + } + data_start = zftello(in_file); + } + } + + } + else +#endif + { + /* read standard data descriptor */ + + if (k < 16) { + /* not enough bytes, so can't be data descriptor + as data descriptors can't be split across splits + */ + } + else + { + /* read the descriptor */ + + des_crc = LG(b + 4); + des_csize = LG(b + 8); + des_usize = LG(b + 12); + + /* if this is the right data descriptor then the sizes should match */ + if ((uzoff_t)des_start - (uzoff_t)data_start != des_csize) { + /* apparently this signature does not go with this data so skip */ + + /* write out signature as data */ + k = 4; + if (zfseeko(in_file, des_start + k, SEEK_SET) != 0) { + /* seek error */ + ZIPERR(ZE_READ, "seek failed reading descriptor"); + } + if (bfwrite(b, 1, k, BFWRITE_DATA) != k) + { + free((zvoid *)b); + fprintf(mesg," fcopy: write error\n"); + return ZE_TEMP; + } + m += k; + continue; + } + else + { + /* apparently this is the correct data descriptor */ + + /* we should check the CRC but this does not work for + encrypted data */ + + /* skip descriptor as will write out later */ + des_good = 1; + data_start = zftello(in_file); + k = 16; + if (zfseeko(in_file, des_start + k, SEEK_SET) != 0) { + /* seek error */ + ZIPERR(ZE_READ, "seek failed reading descriptor"); + } + data_start = zftello(in_file); + } + } + + + } + } + } + + + if (des_good) { + /* skip descriptor as will write out later */ + } else { + /* write out apparently wrong descriptor as data */ + if (bfwrite(b, 1, k, BFWRITE_DATA) != k) + { + free((zvoid *)b); + fprintf(mesg," fcopy: write error\n"); + return ZE_TEMP; + } + m += k; + } + + if (copy_only && !display_globaldots) { + if (dot_size > 0) { + /* initial space */ + if (noisy && dot_count == -1) { +#ifndef WINDLL + putc(' ', mesg); + fflush(mesg); +#else + fprintf(stdout,"%c",' '); +#endif + dot_count++; + } + dot_count += k; + if (dot_size <= dot_count) dot_count = 0; + } + if ((verbose || noisy) && dot_size && !dot_count) { +#ifndef WINDLL + putc('.', mesg); + fflush(mesg); +#else + fprintf(stdout,"%c",'.'); +#endif + mesg_line_started = 1; + } + } + + if (des_good) + break; + + if (des) + continue; + + if ((des || n != (uzoff_t)(-1L)) && m < n && feof(in_file)) { + /* open next split */ + current_in_disk++; + + if (current_in_disk >= total_disks) { + /* done */ + break; + + } else if (current_in_disk == total_disks - 1) { + /* last disk is archive.zip */ + if ((split_path = malloc(strlen(in_path) + 1)) == NULL) { + zipwarn("reading archive: ", in_path); + return ZE_MEM; + } + strcpy(split_path, in_path); + } else { + /* other disks are archive.z01, archive.z02, ... */ + split_path = get_in_split_path(in_path, current_in_disk); + } + + fclose(in_file); + + /* open the split */ + while ((in_file = zfopen(split_path, FOPR)) == NULL) { + int r = 0; + + /* could not open split */ + + if (fix == 1 && skip_this_disk) { + free(split_path); + free((zvoid *)b); + return ZE_FORM; + } + + /* Ask for directory with split. Updates in_path */ + r = ask_for_split_read_path(current_in_disk); + if (r == ZE_ABORT) { + zipwarn("could not find split: ", split_path); + free(split_path); + free((zvoid *)b); + return ZE_ABORT; + } + if (r == ZE_EOF) { + zipmessage_nl("", 1); + zipwarn("user ended reading - closing archive", ""); + free(split_path); + free((zvoid *)b); + return ZE_EOF; + } + if (fix == 2 && skip_this_disk) { + /* user asked to skip this disk */ + zipwarn("skipping split file: ", split_path); + current_in_disk++; + } + + if (current_in_disk == total_disks - 1) { + /* last disk is archive.zip */ + if ((split_path = malloc(strlen(in_path) + 1)) == NULL) { + zipwarn("reading archive: ", in_path); + return ZE_MEM; + } + strcpy(split_path, in_path); + } else { + /* other disks are archive.z01, archive.z02, ... */ + split_path = get_in_split_path(zipfile, current_in_disk); + } + } + if (fix == 2 && skip_this_disk) { + /* user asked to skip this disk */ + free(split_path); + free((zvoid *)b); + return ZE_FORM; + } + free(split_path); + } + } + free((zvoid *)b); + return ZE_OK; +} + + + +#ifdef NO_RENAME +int rename(from, to) +ZCONST char *from; +ZCONST char *to; +{ + unlink(to); + if (link(from, to) == -1) + return -1; + if (unlink(from) == -1) + return -1; + return 0; +} + +#endif /* NO_RENAME */ + + +#ifdef ZMEM + +/************************/ +/* Function memset() */ +/************************/ + +/* + * memset - for systems without it + * bill davidsen - March 1990 + */ + +char * +memset(buf, init, len) +register char *buf; /* buffer loc */ +register int init; /* initializer */ +register unsigned int len; /* length of the buffer */ +{ + char *start; + + start = buf; + while (len--) *(buf++) = init; + return(start); +} + + +/************************/ +/* Function memcpy() */ +/************************/ + +char * +memcpy(dst,src,len) /* v2.0f */ +register char *dst, *src; +register unsigned int len; +{ + char *start; + + start = dst; + while (len--) + *dst++ = *src++; + return(start); +} + + +/************************/ +/* Function memcmp() */ +/************************/ + +int +memcmp(b1,b2,len) /* jpd@usl.edu -- 11/16/90 */ +register char *b1, *b2; +register unsigned int len; +{ + + if (len) do { /* examine each byte (if any) */ + if (*b1++ != *b2++) + return (*((uch *)b1-1) - *((uch *)b2-1)); /* exit when miscompare */ + } while (--len); + + return(0); /* no miscompares, yield 0 result */ +} + +#endif /* ZMEM */ + + +/*------------------------------------------------------------------ + * Split archives + */ + + +/* ask_for_split_read_path + * + * If the next split file is not in the current directory, ask + * the user where it is. + * + * in_path is the base path for reading splits and is usually + * the same as zipfile. The path in in_path must be the archive + * file ending in .zip as this is assumed by get_in_split_path(). + * + * Updates in_path if changed. Returns ZE_OK if OK or ZE_ABORT if + * user cancels reading archive. + * + * If fix = 1 then allow skipping disk (user may not have it). + */ + +#define SPLIT_MAXPATH (FNMAX + 4010) + +int ask_for_split_read_path(current_disk) + ulg current_disk; +{ + FILE *f; + int is_readable = 0; + int i; + char *split_dir = NULL; + char *archive_name = NULL; + char *split_name = NULL; + char *split_path = NULL; + char buf[SPLIT_MAXPATH + 100]; + + /* get split path */ + split_path = get_in_split_path(in_path, current_disk); + + /* get the directory */ + if ((split_dir = malloc(strlen(in_path) + 40)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + strcpy(split_dir, in_path); + + /* remove any name at end */ + for (i = strlen(split_dir) - 1; i >= 0; i--) { + if (split_dir[i] == '/' || split_dir[i] == '\\' + || split_dir[i] == ':') { + split_dir[i + 1] = '\0'; + break; + } + } + if (i < 0) + split_dir[0] = '\0'; + + /* get the name of the archive */ + if ((archive_name = malloc(strlen(in_path) + 1)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + if (strlen(in_path) == strlen(split_dir)) { + archive_name[0] = '\0'; + } else { + strcpy(archive_name, in_path + strlen(split_dir)); + } + + /* get the name of the split */ + if ((split_name = malloc(strlen(split_path) + 1)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + if (strlen(in_path) == strlen(split_dir)) { + split_name[0] = '\0'; + } else { + strcpy(split_name, split_path + strlen(split_dir)); + } + if (i < 0) { + strcpy(split_dir, "(current directory)"); + } + + fprintf(mesg, "\n\nCould not find:\n"); + fprintf(mesg, " %s\n", split_path); + /* + fprintf(mesg, "Please enter the path directory (. for cur dir) where\n"); + fprintf(mesg, " %s\n", split_name); + fprintf(mesg, "is located\n"); + */ + for (;;) { + if (is_readable) { + fprintf(mesg, "\nHit c (change path to where this split file is)"); + fprintf(mesg, "\n q (abort archive - quit)"); + fprintf(mesg, "\n or ENTER (continue with this split): "); + } else { + if (fix == 1) { + fprintf(mesg, "\nHit c (change path to where this split file is)"); + fprintf(mesg, "\n s (skip this split)"); + fprintf(mesg, "\n q (abort archive - quit)"); + fprintf(mesg, "\n or ENTER (try reading this split again): "); + } else if (fix == 2) { + fprintf(mesg, "\nHit c (change path to where this split file is)"); + fprintf(mesg, "\n s (skip this split)"); + fprintf(mesg, "\n q (abort archive - quit)"); + fprintf(mesg, "\n e (end this archive - no more splits)"); + fprintf(mesg, "\n z (look for .zip split - the last split)"); + fprintf(mesg, "\n or ENTER (try reading this split again): "); + } else { + fprintf(mesg, "\nHit c (change path to where this split file is)"); + fprintf(mesg, "\n q (abort archive - quit)"); + fprintf(mesg, "\n or ENTER (try reading this split again): "); + } + } + fflush(mesg); + fgets(buf, SPLIT_MAXPATH, stdin); + /* remove any newline */ + for (i = 0; buf[i]; i++) { + if (buf[i] == '\n') { + buf[i] = '\0'; + break; + } + } + if (toupper(buf[0]) == 'Q') { + return ZE_ABORT; + } else if ((fix == 1 || fix == 2) && toupper(buf[0]) == 'S') { + /* + fprintf(mesg, "\nSkip this split/disk? (files in this split will not be recovered) [n/y] "); + fflush(mesg); + fgets(buf, SPLIT_MAXPATH, stdin); + if (buf[0] == 'y' || buf[0] == 'Y') { + */ + skip_this_disk = current_in_disk + 1; + return ZE_FORM; + } else if (toupper(buf[0]) == 'C') { + fprintf(mesg, "\nEnter path where this split is (ENTER = same dir, . = current dir)"); + fprintf(mesg, "\n: "); + fflush(mesg); + fgets(buf, SPLIT_MAXPATH, stdin); + is_readable = 0; + /* remove any newline */ + for (i = 0; buf[i]; i++) { + if (buf[i] == '\n') { + buf[i] = '\0'; + break; + } + } + if (buf[0] == '\0') { + /* Hit ENTER so try old path again - could be removable media was changed */ + strcpy(buf, split_path); + } + } else if (fix == 2 && toupper(buf[0]) == 'E') { + /* no more splits to read */ + return ZE_EOF; + } else if (fix == 2 && toupper(buf[0]) == 'Z') { + total_disks = current_disk + 1; + free(split_path); + split_path = get_in_split_path(in_path, current_disk); + buf[0] = '\0'; + strncat(buf, split_path, SPLIT_MAXPATH); + } + if (strlen(buf) > 0) { + /* changing path */ + + /* check if user wants current directory */ + if (buf[0] == '.' && buf[1] == '\0') { + buf[0] = '\0'; + } + /* remove any name at end */ + for (i = strlen(buf); i >= 0; i--) { + if (buf[i] == '/' || buf[i] == '\\' + || buf[i] == ':') { + buf[i + 1] = '\0'; + break; + } + } + /* update base_path to newdir/split_name - in_path is the .zip file path */ + free(in_path); + if (i < 0) { + /* just name so current directory */ + strcpy(buf, "(current directory)"); + if (archive_name == NULL) { + i = 0; + } else { + i = strlen(archive_name); + } + if ((in_path = malloc(strlen(archive_name) + 40)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + strcpy(in_path, archive_name); + } else { + /* not the current directory */ + /* remove any name at end */ + for (i = strlen(buf); i >= 0; i--) { + if (buf[i] == '/') { + buf[i + 1] = '\0'; + break; + } + } + if (i < 0) { + buf[0] = '\0'; + } + if ((in_path = malloc(strlen(buf) + strlen(archive_name) + 40)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + strcpy(in_path, buf); + strcat(in_path, archive_name); + } + + free(split_path); + + /* get split path */ + split_path = get_in_split_path(in_path, current_disk); + + free(split_dir); + if ((split_dir = malloc(strlen(in_path) + 40)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + strcpy(split_dir, in_path); + /* remove any name at end */ + for (i = strlen(split_dir); i >= 0; i--) { + if (split_dir[i] == '/') { + split_dir[i + 1] = '\0'; + break; + } + } + + /* try to open it */ + if ((f = fopen(split_path, "r")) == NULL) { + fprintf(mesg, "\nCould not find or open\n"); + fprintf(mesg, " %s\n", split_path); + /* + fprintf(mesg, "Please enter the path (. for cur dir) where\n"); + fprintf(mesg, " %s\n", split_name); + fprintf(mesg, "is located\n"); + */ + continue; + } + fclose(f); + is_readable = 1; + fprintf(mesg, "Found: %s\n", split_path); + } else { + /* try to open it */ + if ((f = fopen(split_path, "r")) == NULL) { + fprintf(mesg, "\nCould not find or open\n"); + fprintf(mesg, " %s\n", split_path); + /* + fprintf(mesg, "Please enter the path (. for cur dir) where\n"); + fprintf(mesg, " %s\n", split_name); + fprintf(mesg, "is located\n"); + */ + continue; + } + fclose(f); + is_readable = 1; + fprintf(mesg, "\nFound: %s\n", split_path); + break; + } + } + free(archive_name); + free(split_dir); + free(split_name); + + return ZE_OK; +} + + +/* ask_for_split_write_path + * + * Verify the directory for the next split. Called + * when -sp is used to pause between writing splits. + * + * Updates out_path and return 1 if OK or 0 if cancel + */ +int ask_for_split_write_path(current_disk) + ulg current_disk; +{ + unsigned int num = (unsigned int)current_disk + 1; + int i; + char *split_dir = NULL; + char *split_name = NULL; + char buf[FNMAX + 40]; + + /* get the directory */ + if ((split_dir = malloc(strlen(out_path) + 40)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + strcpy(split_dir, out_path); + + /* remove any name at end */ + for (i = strlen(split_dir); i >= 0; i--) { + if (split_dir[i] == '/' || split_dir[i] == '\\' + || split_dir[i] == ':') { + split_dir[i + 1] = '\0'; + break; + } + } + + /* get the name of the split */ + if ((split_name = malloc(strlen(out_path) + 1)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + if (strlen(out_path) == strlen(split_dir)) { + split_name[0] = '\0'; + } else { + strcpy(split_name, out_path + strlen(split_dir)); + } + if (i < 0) { + strcpy(split_dir, "(current directory)"); + } + if (mesg_line_started) + fprintf(mesg, "\n"); + fprintf(mesg, "\nOpening disk %d\n", num); + fprintf(mesg, "Hit ENTER to write to default path of\n"); + fprintf(mesg, " %s\n", split_dir); + fprintf(mesg, "or enter a new directory path (. for cur dir) and hit ENTER\n"); + for (;;) { + fprintf(mesg, "\nPath (or hit ENTER to continue): "); + fflush(mesg); + fgets(buf, FNMAX, stdin); + /* remove any newline */ + for (i = 0; buf[i]; i++) { + if (buf[i] == '\n') { + buf[i] = '\0'; + break; + } + } + if (strlen(buf) > 0) { + /* changing path */ + + /* current directory */ + if (buf[0] == '.' && buf[1] == '\0') { + buf[0] = '\0'; + } + /* remove any name at end */ + for (i = strlen(buf); i >= 0; i--) { + if (buf[i] == '/' || buf[i] == '\\' + || buf[i] == ':') { + buf[i + 1] = '\0'; + break; + } + } + /* update out_path to newdir/split_name */ + free(out_path); + if (i < 0) { + /* just name so current directory */ + strcpy(buf, "(current directory)"); + if (split_name == NULL) { + i = 0; + } else { + i = strlen(split_name); + } + if ((out_path = malloc(strlen(split_name) + 40)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + strcpy(out_path, split_name); + } else { + /* not the current directory */ + /* remove any name at end */ + for (i = strlen(buf); i >= 0; i--) { + if (buf[i] == '/') { + buf[i + 1] = '\0'; + break; + } + } + if (i < 0) { + buf[0] = '\0'; + } + if ((out_path = malloc(strlen(buf) + strlen(split_name) + 40)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + strcpy(out_path, buf); + strcat(out_path, split_name); + } + fprintf(mesg, "Writing to:\n %s\n", buf); + free(split_name); + free(split_dir); + if ((split_dir = malloc(strlen(out_path) + 40)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + strcpy(split_dir, out_path); + /* remove any name at end */ + for (i = strlen(split_dir); i >= 0; i--) { + if (split_dir[i] == '/') { + split_dir[i + 1] = '\0'; + break; + } + } + if ((split_name = malloc(strlen(out_path) + 1)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + strcpy(split_name, out_path + strlen(split_dir)); + } else { + break; + } + } + free(split_dir); + free(split_name); + + /* for now no way out except Ctrl C */ + return 1; +} + + +/* split_name + * + * get name of split being read + */ +char *get_in_split_path(base_path, disk_number) + char *base_path; + ulg disk_number; +{ + char *split_path = NULL; + int base_len = 0; + int path_len = 0; + ulg num = disk_number + 1; + char ext[6]; +#ifdef VMS + int vers_len; /* File version length. */ + char *vers_ptr; /* File version string. */ +#endif /* def VMS */ + + /* + * A split has extension z01, z02, ..., z99, z100, z101, ... z999 + * We currently support up to .z99999 + * WinZip will also read .100, .101, ... but AppNote 6.2.2 uses above + * so use that. Means on DOS can only have 100 splits. + */ + + if (num == total_disks) { + /* last disk is base path */ + if ((split_path = malloc(strlen(base_path) + 1)) == NULL) { + ZIPERR(ZE_MEM, "base path"); + } + strcpy(split_path, base_path); + + return split_path; + } else { + if (num > 99999) { + ZIPERR(ZE_BIG, "More than 99999 splits needed"); + } + sprintf(ext, "z%02lu", num); + } + + /* create path for this split - zip.c checked for .zip extension */ + base_len = strlen(base_path) - 3; + path_len = base_len + strlen(ext); + +#ifdef VMS + /* On VMS, locate the file version, and adjust base_len accordingly. + Note that path_len is correct, as-is. + */ + vers_ptr = vms_file_version( base_path); + vers_len = strlen( vers_ptr); + base_len -= vers_len; +#endif /* def VMS */ + + if ((split_path = malloc(path_len + 1)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + /* copy base_path except for end zip */ + strcpy(split_path, base_path); + split_path[base_len] = '\0'; + /* add extension */ + strcat(split_path, ext); + +#ifdef VMS + /* On VMS, append (preserve) the file version. */ + strcat(split_path, vers_ptr); +#endif /* def VMS */ + + return split_path; +} + + +/* split_name + * + * get name of split being written + */ +char *get_out_split_path(base_path, disk_number) + char *base_path; + ulg disk_number; +{ + char *split_path = NULL; + int base_len = 0; + int path_len = 0; + ulg num = disk_number + 1; + char ext[6]; +#ifdef VMS + int vers_len; /* File version length. */ + char *vers_ptr; /* File version string. */ +#endif /* def VMS */ + + /* + * A split has extension z01, z02, ..., z99, z100, z101, ... z999 + * We currently support up to .z99999 + * WinZip will also read .100, .101, ... but AppNote 6.2.2 uses above + * so use that. Means on DOS can only have 100 splits. + */ + + if (num > 99999) { + ZIPERR(ZE_BIG, "More than 99999 splits needed"); + } + sprintf(ext, "z%02lu", num); + + /* create path for this split - zip.c checked for .zip extension */ + base_len = strlen(base_path) - 3; + path_len = base_len + strlen(ext); + +#ifdef VMS + /* On VMS, locate the file version, and adjust base_len accordingly. + Note that path_len is correct, as-is. + */ + vers_ptr = vms_file_version( base_path); + vers_len = strlen( vers_ptr); + base_len -= vers_len; +#endif /* def VMS */ + + if ((split_path = malloc(path_len + 1)) == NULL) { + ZIPERR(ZE_MEM, "split path"); + } + /* copy base_path except for end zip */ + strcpy(split_path, base_path); + split_path[base_len] = '\0'; + /* add extension */ + strcat(split_path, ext); + +#ifdef VMS + /* On VMS, append (preserve) the file version. */ + strcat(split_path, vers_ptr); +#endif /* def VMS */ + + return split_path; +} + +/* close_split + * + * close a split - assume that the paths needed for the splits are + * available. + */ +int close_split(disk_number, tempfile, temp_name) + ulg disk_number; + FILE *tempfile; + char *temp_name; +{ + char *split_path = NULL; + + split_path = get_out_split_path(out_path, disk_number); + + if (noisy_splits) { + zipmessage("\tClosing split ", split_path); + } + + fclose(tempfile); + + rename_split(temp_name, split_path); + set_filetype(split_path); + + return ZE_OK; +} + +/* bfwrite + Does the fwrite but also counts bytes and does splits */ +size_t bfwrite(buffer, size, count, mode) + ZCONST void *buffer; + size_t size; + size_t count; + int mode; +{ + size_t bytes_written = 0; + size_t r; + size_t b = size * count; + uzoff_t bytes_left_in_split = 0; + size_t bytes_to_write = b; + + + /* -------------------------------- */ + /* local header */ + if (mode == BFWRITE_LOCALHEADER) { + /* writing local header - reset entry data count */ + bytes_this_entry = 0; + /* save start of local header so we can rewrite later */ + current_local_file = y; + current_local_disk = current_disk; + current_local_offset = bytes_this_split; + } + + if (split_size == 0) + bytes_left_in_split = bytes_to_write; + else + bytes_left_in_split = split_size - bytes_this_split; + + if (bytes_to_write > bytes_left_in_split) { + if (mode == BFWRITE_HEADER || + mode == BFWRITE_LOCALHEADER || + mode == BFWRITE_CENTRALHEADER) { + /* if can't write entire header save for next split */ + bytes_to_write = 0; + } else { + /* normal data so fill the split */ + bytes_to_write = (size_t)bytes_left_in_split; + } + } + + /* -------------------------------- */ + /* central header */ + if (mode == BFWRITE_CENTRALHEADER) { + /* set start disk for CD */ + if (cd_start_disk == (ulg)-1) { + cd_start_disk = current_disk; + cd_start_offset = bytes_this_split; + } + cd_entries_this_disk++; + total_cd_entries++; + } + + /* -------------------------------- */ + if (bytes_to_write > 0) { + /* write out the bytes for this split */ + r = fwrite(buffer, size, bytes_to_write, y); + bytes_written += r; + bytes_to_write = b - r; + bytes_this_split += r; + if (mode == BFWRITE_DATA) + /* if data descriptor do not include in count */ + bytes_this_entry += r; + } else { + bytes_to_write = b; + } + + if (bytes_to_write > 0) { + if (split_method) { + /* still bytes to write so close split and open next split */ + bytes_prev_splits += bytes_this_split; + + if (split_method == 1 && ferror(y)) { + /* if writing all splits to same place and have problem then bad */ + ZIPERR(ZE_WRITE, "Could not write split"); + } + + if (split_method == 2 && ferror(y)) { + /* A split must be at least 64K except last .zip split */ + if (bytes_this_split < 64 * (uzoff_t)0x400) { + ZIPERR(ZE_WRITE, "Not enough space to write split"); + } + } + + /* close this split */ + if (split_method == 1 && current_local_disk == current_disk) { + /* keep split open so can update it */ + current_local_tempname = tempzip; + } else { + /* close split */ + close_split(current_disk, y, tempzip); + y = NULL; + free(tempzip); + tempzip = NULL; + } + cd_entries_this_disk = 0; + bytes_this_split = 0; + + /* increment disk - disks are numbered 0, 1, 2, ... and + splits are 01, 02, ... */ + current_disk++; + + if (split_method == 2 && split_bell) { + /* bell when pause to ask for next split */ + putc('\007', mesg); + fflush(mesg); + } + + for (;;) { + /* if method 2 pause and allow changing path */ + if (split_method == 2) { + if (ask_for_split_write_path(current_disk) == 0) { + ZIPERR(ZE_ABORT, "could not write split"); + } + } + + /* open next split */ +#if defined(UNIX) && !defined(NO_MKSTEMP) + { + int yd; + int i; + + /* use mkstemp to avoid race condition and compiler warning */ + + if (tempath != NULL) + { + /* if -b used to set temp file dir use that for split temp */ + if ((tempzip = malloc(strlen(tempath) + 12)) == NULL) { + ZIPERR(ZE_MEM, "allocating temp filename"); + } + strcpy(tempzip, tempath); + if (lastchar(tempzip) != '/') + strcat(tempzip, "/"); + } + else + { + /* create path by stripping name and appending template */ + if ((tempzip = malloc(strlen(zipfile) + 12)) == NULL) { + ZIPERR(ZE_MEM, "allocating temp filename"); + } + strcpy(tempzip, zipfile); + for(i = strlen(tempzip); i > 0; i--) { + if (tempzip[i - 1] == '/') + break; + } + tempzip[i] = '\0'; + } + strcat(tempzip, "ziXXXXXX"); + + if ((yd = mkstemp(tempzip)) == EOF) { + ZIPERR(ZE_TEMP, tempzip); + } + if ((y = fdopen(yd, FOPW_TMP)) == NULL) { + ZIPERR(ZE_TEMP, tempzip); + } + } +#else + if ((tempzip = tempname(zipfile)) == NULL) { + ZIPERR(ZE_MEM, "allocating temp filename"); + } + if ((y = zfopen(tempzip, FOPW_TMP)) == NULL) { + ZIPERR(ZE_TEMP, tempzip); + } +#endif + + r = fwrite((char *)buffer + bytes_written, 1, bytes_to_write, y); + bytes_written += r; + bytes_this_split += r; + if (!(mode == BFWRITE_HEADER || + mode == BFWRITE_LOCALHEADER || + mode == BFWRITE_CENTRALHEADER)) { + bytes_this_entry += r; + } + if (bytes_to_write > r) { + /* buffer bigger than split */ + if (split_method == 2) { + /* let user choose another disk */ + zipwarn("Not enough room on disk", ""); + continue; + } else { + ZIPERR(ZE_WRITE, "Not enough room on disk"); + } + } + if (mode == BFWRITE_LOCALHEADER || + mode == BFWRITE_HEADER || + mode == BFWRITE_CENTRALHEADER) { + if (split_method == 1 && current_local_file && + current_local_disk != current_disk) { + /* We're opening a new split because the next header + did not fit on the last split. We need to now close + the last split and update the pointers for + the current split. */ + close_split(current_local_disk, current_local_file, + current_local_tempname); + free(current_local_tempname); + } + current_local_tempname = tempzip; + current_local_file = y; + current_local_offset = 0; + current_local_disk = current_disk; + } + break; + } + } + else + { + /* likely have more than fits but no splits */ + + /* probably already have error "no space left on device" */ + /* could let flush_outbuf() handle error but bfwrite() is called for + headers also */ + if (ferror(y)) + ziperr(ZE_WRITE, "write error on zip file"); + } + } + + + /* display dots for archive instead of for each file */ + if (display_globaldots) { + if (dot_size > 0) { + /* initial space */ + if (dot_count == -1) { +#ifndef WINDLL + putc(' ', mesg); + fflush(mesg); +#else + fprintf(stdout,"%c",' '); +#endif + /* assume a header will be written first, so avoid 0 */ + dot_count = 1; + } + /* skip incrementing dot count for small buffers like for headers */ + if (size * count > 1000) { + dot_count++; + if (dot_size <= dot_count * (zoff_t)size * (zoff_t)count) dot_count = 0; + } + } + if (dot_size && !dot_count) { + dot_count++; +#ifndef WINDLL + putc('.', mesg); + fflush(mesg); +#else + fprintf(stdout,"%c",'.'); +#endif + mesg_line_started = 1; + } + } + + + return bytes_written; +} + + +#ifdef UNICODE_SUPPORT + +/*--------------------------------------------- + * Unicode conversion functions + * + * Provided by Paul Kienitz + * + * Some modifications to work with Zip + * + *--------------------------------------------- + */ + +/* + NOTES APPLICABLE TO ALL STRING FUNCTIONS: + + All of the x_to_y functions take parameters for an output buffer and + its available length, and return an int. The value returned is the + length of the string that the input produces, which may be larger than + the provided buffer length. If the returned value is less than the + buffer length, then the contents of the buffer will be null-terminated; + otherwise, it will not be terminated and may be invalid, possibly + stopping in the middle of a multibyte sequence. + + In all cases you may pass NULL as the buffer and/or 0 as the length, if + you just want to learn how much space the string is going to require. + + The functions will return -1 if the input is invalid UTF-8 or cannot be + encoded as UTF-8. +*/ + +/* utility functions for managing UTF-8 and UCS-4 strings */ + + +/* utf8_char_bytes + * + * Returns the number of bytes used by the first character in a UTF-8 + * string, or -1 if the UTF-8 is invalid or null. + */ +local int utf8_char_bytes(utf8) + ZCONST char *utf8; +{ + int t, r; + unsigned lead; + + if (!utf8) + return -1; /* no input */ + lead = (unsigned char) *utf8; + if (lead < 0x80) + r = 1; /* an ascii-7 character */ + else if (lead < 0xC0) + return -1; /* error: trailing byte without lead byte */ + else if (lead < 0xE0) + r = 2; /* an 11 bit character */ + else if (lead < 0xF0) + r = 3; /* a 16 bit character */ + else if (lead < 0xF8) + r = 4; /* a 21 bit character (the most currently used) */ + else if (lead < 0xFC) + r = 5; /* a 26 bit character (shouldn't happen) */ + else if (lead < 0xFE) + r = 6; /* a 31 bit character (shouldn't happen) */ + else + return -1; /* error: invalid lead byte */ + for (t = 1; t < r; t++) + if ((unsigned char) utf8[t] < 0x80 || (unsigned char) utf8[t] >= 0xC0) + return -1; /* error: not enough valid trailing bytes */ + return r; +} + + +/* ucs4_char_from_utf8 + * + * Given a reference to a pointer into a UTF-8 string, returns the next + * UCS-4 character and advances the pointer to the next character sequence. + * Returns ~0 and does not advance the pointer when input is ill-formed. + * + * Since the Unicode standard says 32-bit values won't be used (just + * up to the current 21-bit mappings) changed this to signed to allow -1 to + * be returned. + */ +long ucs4_char_from_utf8(utf8) + ZCONST char **utf8; +{ + ulg ret; + int t, bytes; + + if (!utf8) + return -1; /* no input */ + bytes = utf8_char_bytes(*utf8); + if (bytes <= 0) + return -1; /* invalid input */ + if (bytes == 1) + ret = **utf8; /* ascii-7 */ + else + ret = **utf8 & (0x7F >> bytes); /* lead byte of a multibyte sequence */ + (*utf8)++; + for (t = 1; t < bytes; t++) /* consume trailing bytes */ + ret = (ret << 6) | (*((*utf8)++) & 0x3F); + return (long) ret; +} + + +/* utf8_from_ucs4_char - Convert UCS char to UTF-8 + * + * Returns the number of bytes put into utf8buf to represent ch, from 1 to 6, + * or -1 if ch is too large to represent. utf8buf must have room for 6 bytes. + */ +local int utf8_from_ucs4_char(utf8buf, ch) + char *utf8buf; + ulg ch; +{ + int trailing = 0; + int leadmask = 0x80; + int leadbits = 0x3F; + ulg tch = ch; + int ret; + + if (ch > 0x7FFFFFFF) + return -1; /* UTF-8 can represent 31 bits */ + if (ch < 0x7F) + { + *utf8buf++ = (char) ch; /* ascii-7 */ + return 1; + } + do { + trailing++; + leadmask = (leadmask >> 1) | 0x80; + leadbits >>= 1; + tch >>= 6; + } while (tch & ~leadbits); + ret = trailing + 1; + /* produce lead byte */ + *utf8buf++ = (char) (leadmask | (ch >> (6 * trailing))); + /* produce trailing bytes */ + while (--trailing >= 0) + *utf8buf++ = (char) (0x80 | ((ch >> (6 * trailing)) & 0x3F)); + return ret; +} + + +/*===================================================================*/ + +/* utf8_to_ucs4_string - convert UTF-8 string to UCS string + * + * Return UCS count. Now returns int so can return -1. + */ +local int utf8_to_ucs4_string(utf8, ucs4buf, buflen) + ZCONST char *utf8; + ulg *ucs4buf; + int buflen; +{ + int count = 0; + + for (;;) + { + long ch = ucs4_char_from_utf8(&utf8); + if (ch == -1) + return -1; + else + { + if (ucs4buf && count < buflen) + ucs4buf[count] = ch; + if (ch == 0) + return count; + count++; + } + } +} + + +/* ucs4_string_to_utf8 + * + * + */ +local int ucs4_string_to_utf8(ucs4, utf8buf, buflen) + ZCONST ulg *ucs4; + char *utf8buf; + int buflen; +{ + char mb[6]; + int count = 0; + + if (!ucs4) + return -1; + for (;;) + { + int mbl = utf8_from_ucs4_char(mb, *ucs4++); + int c; + if (mbl <= 0) + return -1; + /* We could optimize this a bit by passing utf8buf + count */ + /* directly to utf8_from_ucs4_char when buflen >= count + 6... */ + c = buflen - count; + if (mbl < c) + c = mbl; + if (utf8buf && count < buflen) + strncpy(utf8buf + count, mb, c); + if (mbl == 1 && !mb[0]) + return count; /* terminating nul */ + count += mbl; + } +} + + +#if 0 /* currently unused */ +/* utf8_chars + * + * Wrapper: counts the actual unicode characters in a UTF-8 string. + */ +local int utf8_chars(utf8) + ZCONST char *utf8; +{ + return utf8_to_ucs4_string(utf8, NULL, 0); +} +#endif + + +/* --------------------------------------------------- */ +/* Unicode Support + * + * These functions common for all Unicode ports. + * + * These functions should allocate and return strings that can be + * freed with free(). + * + * 8/27/05 EG + * + * Use zwchar for wide char which is unsigned long + * in zip.h and 32 bits. This avoids problems with + * different sizes of wchar_t. + */ + +#ifdef WIN32 + +zwchar *wchar_to_wide_string(wchar_string) + wchar_t *wchar_string; +{ + int i; + int wchar_len; + zwchar *wide_string; + + wchar_len = wcslen(wchar_string); + + if ((wide_string = malloc((wchar_len + 1) * sizeof(zwchar))) == NULL) { + ZIPERR(ZE_MEM, "wchar to wide conversion"); + } + for (i = 0; i <= wchar_len; i++) { + wide_string[i] = wchar_string[i]; + } + + return wide_string; +} + +/* is_ascii_stringw + * Checks if a wide string is all ascii + */ +int is_ascii_stringw(wstring) + wchar_t *wstring; +{ + wchar_t *pw; + wchar_t cw; + + if (wstring == NULL) + return 0; + + for (pw = wstring; (cw = *pw) != '\0'; pw++) { + if (cw > 0x7F) { + return 0; + } + } + return 1; +} + +#endif + +/* is_ascii_string + * Checks if a string is all ascii + */ +int is_ascii_string(mbstring) + char *mbstring; +{ + char *p; + uch c; + + if (mbstring == NULL) + return 0; + + for (p = mbstring; (c = (uch)*p) != '\0'; p++) { + if (c > 0x7F) { + return 0; + } + } + return 1; +} + +/* local to UTF-8 */ +char *local_to_utf8_string(local_string) + char *local_string; +{ + zwchar *wide_string = local_to_wide_string(local_string); + char *utf8_string = wide_to_utf8_string(wide_string); + + free(wide_string); + return utf8_string; +} + +/* wide_char_to_escape_string + provides a string that represents a wide char not in local char set + + An initial try at an algorithm. Suggestions welcome. + + If not an ASCII char, probably need 2 bytes at least. So if + a 2-byte wide encode it as 4 hex digits with a leading #U. + Since the Unicode standard has been frozen, it looks like 3 bytes + should be enough for any large Unicode character. In these cases + prefix the string with #L. + So + #U1234 + is a 2-byte wide character with bytes 0x12 and 0x34 while + #L123456 + is a 3-byte wide with bytes 0x12, 0x34, and 0x56. + On Windows, wide that need two wide characters as a surrogate pair + to represent them need to be converted to a single number. + */ + + /* set this to the max bytes an escape can be */ +#define MAX_ESCAPE_BYTES 8 + +char *wide_char_to_escape_string(wide_char) + zwchar wide_char; +{ + int i; + zwchar w = wide_char; + uch b[9]; + char e[7]; + int len; + char *r; + + /* fill byte array with zeros */ + for (len = 0; len < sizeof(zwchar); len++) { + b[len] = 0; + } + /* get bytes in right to left order */ + for (len = 0; w; len++) { + b[len] = (char)(w % 0x100); + w /= 0x100; + } + + if ((r = malloc(MAX_ESCAPE_BYTES + 8)) == NULL) { + ZIPERR(ZE_MEM, "wide_char_to_escape_string"); + } + strcpy(r, "#"); + /* either 2 bytes or 4 bytes */ + if (len < 3) { + len = 2; + strcat(r, "U"); + } else { + len = 3; + strcat(r, "L"); + } + for (i = len - 1; i >= 0; i--) { + sprintf(e, "%02x", b[i]); + strcat(r, e); + } + return r; +} + +#if 0 +/* returns the wide character represented by the escape string */ +zwchar escape_string_to_wide(escape_string) + char *escape_string; +{ + int i; + zwchar w; + char c; + char u; + int len; + char *e = escape_string; + + if (e == NULL) { + return 0; + } + if (e[0] != '#') { + /* no leading # */ + return 0; + } + len = strlen(e); + /* either #U1234 or #L123456 format */ + if (len != 6 && len != 8) { + return 0; + } + w = 0; + if (e[1] == 'L') { + if (len != 8) { + return 0; + } + /* 3 bytes */ + for (i = 2; i < 8; i++) { + c = e[i]; + u = toupper(c); + if (u >= 'A' && u <= 'F') { + w = w * 0x10 + (zwchar)(u + 10 - 'A'); + } else if (c >= '0' && c <= '9') { + w = w * 0x10 + (zwchar)(c - '0'); + } else { + return 0; + } + } + } else if (e[1] == 'U') { + /* 2 bytes */ + for (i = 2; i < 6; i++) { + c = e[i]; + u = toupper(c); + if (u >= 'A' && u <= 'F') { + w = w * 0x10 + (zwchar)(u + 10 - 'A'); + } else if (c >= '0' && c <= '9') { + w = w * 0x10 + (zwchar)(c - '0'); + } else { + return 0; + } + } + } + return w; +} +#endif + + +char *local_to_escape_string(local_string) + char *local_string; +{ + zwchar *wide_string = local_to_wide_string(local_string); + char *escape_string = wide_to_escape_string(wide_string); + + free(wide_string); + return escape_string; +} + +#ifdef WIN32 +char *wchar_to_local_string(wstring) + wchar_t *wstring; +{ + zwchar *wide_string = wchar_to_wide_string(wstring); + char *local_string = wide_to_local_string(wide_string); + + free(wide_string); + + return local_string; +} +#endif + + +#ifndef WIN32 /* The Win32 port uses a system-specific variant. */ +/* convert wide character string to multi-byte character string */ +char *wide_to_local_string(wide_string) + zwchar *wide_string; +{ + int i; + wchar_t wc; + int b; + int state_dependent; + int wsize = 0; + int max_bytes = MB_CUR_MAX; + char buf[9]; + char *buffer = NULL; + char *local_string = NULL; + + for (wsize = 0; wide_string[wsize]; wsize++) ; + + if (MAX_ESCAPE_BYTES > max_bytes) + max_bytes = MAX_ESCAPE_BYTES; + + if ((buffer = (char *)malloc(wsize * max_bytes + 1)) == NULL) { + ZIPERR(ZE_MEM, "wide_to_local_string"); + } + + /* convert it */ + buffer[0] = '\0'; + /* set initial state if state-dependent encoding */ + wc = (wchar_t)'a'; + b = wctomb(NULL, wc); + if (b == 0) + state_dependent = 0; + else + state_dependent = 1; + for (i = 0; i < wsize; i++) { + if (sizeof(wchar_t) < 4 && wide_string[i] > 0xFFFF) { + /* wchar_t probably 2 bytes */ + /* could do surrogates if state_dependent and wctomb can do */ + wc = zwchar_to_wchar_t_default_char; + } else { + wc = (wchar_t)wide_string[i]; + } + b = wctomb(buf, wc); + if (unicode_escape_all) { + if (b == 1 && (uch)buf[0] <= 0x7f) { + /* ASCII */ + strncat(buffer, buf, b); + } else { + /* use escape for wide character */ + char *e = wide_char_to_escape_string(wide_string[i]); + strcat(buffer, e); + free(e); + } + } else if (b > 0) { + /* multi-byte char */ + strncat(buffer, buf, b); + } else { + /* no MB for this wide */ + if (use_wide_to_mb_default) { + /* default character */ + strcat(buffer, wide_to_mb_default_string); + } else { + /* use escape for wide character */ + char *e = wide_char_to_escape_string(wide_string[i]); + strcat(buffer, e); + free(e); + } + } + } + if ((local_string = (char *)malloc(strlen(buffer) + 1)) == NULL) { + free(buffer); + ZIPERR(ZE_MEM, "wide_to_local_string"); + } + strcpy(local_string, buffer); + free(buffer); + + return local_string; +} +#endif /* !WIN32 */ + + +/* convert wide character string to escaped string */ +char *wide_to_escape_string(wide_string) + zwchar *wide_string; +{ + int i; + int wsize = 0; + char buf[9]; + char *buffer = NULL; + char *escape_string = NULL; + + for (wsize = 0; wide_string[wsize]; wsize++) ; + + if ((buffer = (char *)malloc(wsize * MAX_ESCAPE_BYTES + 1)) == NULL) { + ZIPERR(ZE_MEM, "wide_to_escape_string"); + } + + /* convert it */ + buffer[0] = '\0'; + for (i = 0; i < wsize; i++) { + if (wide_string[i] <= 0x7f && isprint((char)wide_string[i])) { + /* ASCII */ + buf[0] = (char)wide_string[i]; + buf[1] = '\0'; + strcat(buffer, buf); + } else { + /* use escape for wide character */ + char *e = wide_char_to_escape_string(wide_string[i]); + strcat(buffer, e); + free(e); + } + } + if ((escape_string = (char *)malloc(strlen(buffer) + 1)) == NULL) { + ZIPERR(ZE_MEM, "wide_to_escape_string"); + } + strcpy(escape_string, buffer); + free(buffer); + + return escape_string; +} + + +/* convert local string to display character set string */ +char *local_to_display_string(local_string) + char *local_string; +{ + char *temp_string; + char *display_string; + + /* For Windows, OEM string should never be bigger than ANSI string, says + CharToOem description. + On UNIX, non-printable characters (0x00 - 0xFF) will be replaced by + "^x", so more space may be needed. Note that "^" itself is a valid + name character, so this leaves an ambiguity, but UnZip displays + names this way, too. (0x00 is not possible, I hope.) + For all other ports, just make a copy of local_string. + */ + +#ifdef UNIX + char *cp_dst; /* Character pointers used in the */ + char *cp_src; /* copying/changing procedure. */ +#endif + + if ((temp_string = (char *)malloc(2 * strlen(local_string) + 1)) == NULL) { + ZIPERR(ZE_MEM, "local_to_display_string"); + } + +#ifdef WIN32 + /* convert to OEM display character set */ + local_to_oem_string(temp_string, local_string); +#else +# ifdef UNIX + /* Copy source string, expanding non-printable characters to "^x". */ + cp_dst = temp_string; + cp_src = local_string; + while (*cp_src != '\0') { + if ((unsigned char)*cp_src < ' ') { + *cp_dst++ = '^'; + *cp_dst++ = '@'+ *cp_src++; + } + else { + *cp_dst++ = *cp_src++; + } + } + *cp_dst = '\0'; +# else /* not UNIX */ + strcpy(temp_string, local_string); +# endif /* UNIX */ +#endif + +#ifdef EBCDIC + { + char *ebc; + + if ((ebc = malloc(strlen(display_string) + 1)) == NULL) { + ZIPERR(ZE_MEM, "local_to_display_string"); + } + strtoebc(ebc, display_string); + free(display_string); + display_string = ebc; + } +#endif + + if ((display_string = (char *)malloc(strlen(temp_string) + 1)) == NULL) { + ZIPERR(ZE_MEM, "local_to_display_string"); + } + strcpy(display_string, temp_string); + free(temp_string); + + return display_string; +} + +/* UTF-8 to local */ +char *utf8_to_local_string(utf8_string) + char *utf8_string; +{ + zwchar *wide_string = utf8_to_wide_string(utf8_string); + char *loc = wide_to_local_string(wide_string); + if (wide_string) + free(wide_string); + return loc; +} + +/* UTF-8 to local */ +char *utf8_to_escape_string(utf8_string) + char *utf8_string; +{ + zwchar *wide_string = utf8_to_wide_string(utf8_string); + char *escape_string = wide_to_escape_string(wide_string); + free(wide_string); + return escape_string; +} + +#ifndef WIN32 /* The Win32 port uses a system-specific variant. */ +/* convert multi-byte character string to wide character string */ +zwchar *local_to_wide_string(local_string) + char *local_string; +{ + int wsize; + wchar_t *wc_string; + zwchar *wide_string; + + /* for now try to convert as string - fails if a bad char in string */ + wsize = mbstowcs(NULL, local_string, MB_CUR_MAX ); + if (wsize == (size_t)-1) { + /* could not convert */ + return NULL; + } + + /* convert it */ + if ((wc_string = (wchar_t *)malloc((wsize + 1) * sizeof(wchar_t))) == NULL) { + ZIPERR(ZE_MEM, "local_to_wide_string"); + } + wsize = mbstowcs(wc_string, local_string, strlen(local_string) + 1); + wc_string[wsize] = (wchar_t) 0; + + /* in case wchar_t is not zwchar */ + if ((wide_string = (zwchar *)malloc((wsize + 1) * sizeof(zwchar))) == NULL) { + ZIPERR(ZE_MEM, "local_to_wide_string"); + } + for (wsize = 0; (wide_string[wsize] = (zwchar)wc_string[wsize]); wsize++) ; + wide_string[wsize] = (zwchar)0; + free(wc_string); + + return wide_string; +} +#endif /* !WIN32 */ + + +#if 0 +/* All wchar functions are only used by Windows and are + now in win32zip.c so that the Windows functions can + be used and multiple character wide characters can + be handled easily. */ +# ifndef WIN32 +char *wchar_to_utf8_string(wstring) + wchar_t *wstring; +{ + zwchar *wide_string = wchar_to_wide_string(wstring); + char *local_string = wide_to_utf8_string(wide_string); + + free(wide_string); + + return local_string; +} +# endif +#endif + + +/* convert wide string to UTF-8 */ +char *wide_to_utf8_string(wide_string) + zwchar *wide_string; +{ + int mbcount; + char *utf8_string; + + /* get size of utf8 string */ + mbcount = ucs4_string_to_utf8(wide_string, NULL, 0); + if (mbcount == -1) + return NULL; + if ((utf8_string = (char *) malloc(mbcount + 1)) == NULL) { + ZIPERR(ZE_MEM, "wide_to_utf8_string"); + } + mbcount = ucs4_string_to_utf8(wide_string, utf8_string, mbcount + 1); + if (mbcount == -1) + return NULL; + + return utf8_string; +} + +/* convert UTF-8 string to wide string */ +zwchar *utf8_to_wide_string(utf8_string) + char *utf8_string; +{ + int wcount; + zwchar *wide_string; + + wcount = utf8_to_ucs4_string(utf8_string, NULL, 0); + if (wcount == -1) + return NULL; + if ((wide_string = (zwchar *) malloc((wcount + 2) * sizeof(zwchar))) == NULL) { + ZIPERR(ZE_MEM, "utf8_to_wide_string"); + } + wcount = utf8_to_ucs4_string(utf8_string, wide_string, wcount + 1); + + return wide_string; +} + + +#endif /* UNICODE_SUPPORT */ + + +/*--------------------------------------------------------------- + * Long option support + * 8/23/2003 + * + * Defines function get_option() to get and process the command + * line options and arguments from argv[]. The caller calls + * get_option() in a loop to get either one option and possible + * value or a non-option argument each loop. + * + * This version does not include argument file support and can + * work directly on argv. The argument file code complicates things and + * it seemed best to leave it out for now. If argument file support (reading + * in command line arguments stored in a file and inserting into + * command line where @filename is found) is added later the arguments + * can change and a freeable copy of argv will be needed and can be + * created using copy_args in the left out code. + * + * Supports short and long options as defined in the array options[] + * in zip.c, multiple short options in an argument (like -jlv), long + * option abbreviation (like --te for --temp-file if --te unique), + * short and long option values (like -b filename or --temp-file filename + * or --temp-file=filename), optional and required values, option negation + * by trailing - (like -S- to not include hidden and system files in MSDOS), + * value lists (like -x a b c), argument permuting (returning all options + * and values before any non-option arguments), and argument files (where any + * non-option non-value argument in form @path gets substituted with the + * white space separated arguments in the text file at path). In this + * version argument file support has been removed to simplify development but + * may be added later. + * + * E. Gordon + */ + + +/* message output - char casts are needed to handle constants */ +#define oWARN(message) zipwarn((char *) message, "") +#define oERR(err,message) ZIPERR(err, (char *) message) + + +/* Although the below provides some support for multibyte characters + the proper thing to do may be to use wide characters and support + Unicode. May get to it soon. EG + */ + +/* For now stay with muti-byte characters. May support wide characters + in Zip 3.1. + */ + +/* multibyte character set support + Multibyte characters use typically two or more sequential bytes + to represent additional characters than can fit in a single byte + character set. The code used here is based on the ANSI mblen function. */ +#ifdef MULTIBYTE_GETOPTNS + int mb_clen(ptr) + ZCONST char *ptr; + { + /* return the number of bytes that the char pointed to is. Return 1 if + null character or error like not start of valid multibyte character. */ + int cl; + + cl = mblen(ptr, MB_CUR_MAX); + return (cl > 0) ? cl : 1; + } +#endif + + + /* moved to zip.h */ +#if 0 +#ifdef UNICODE_SUPPORT +# define MB_CLEN(ptr) (1) +# define MB_NEXTCHAR(ptr) ((ptr)++) +# ifdef MULTIBYTE_GETOPTNS +# undef MULTIBYTE_GETOPTNS +# endif +#else +# ifdef _MBCS +# ifndef MULTIBYTE_GETOPTNS +# define MULTIBYTE_GETOPTNS +# endif +# endif +/* multibyte character set support + Multibyte characters use typically two or more sequential bytes + to represent additional characters than can fit in a single byte + character set. The code used here is based on the ANSI mblen function. */ +# ifdef MULTIBYTE_GETOPTNS + local int mb_clen OF((ZCONST char *)); /* declare proto first */ + local int mb_clen(ptr) + ZCONST char *ptr; + { + /* return the number of bytes that the char pointed to is. Return 1 if + null character or error like not start of valid multibyte character. */ + int cl; + + cl = mblen(ptr, MB_CUR_MAX); + return (cl > 0) ? cl : 1; + } +# define MB_CLEN(ptr) mb_clen(ptr) +# define MB_NEXTCHAR(ptr) ((ptr) += MB_CLEN(ptr)) +# else +# define MB_CLEN(ptr) (1) +# define MB_NEXTCHAR(ptr) ((ptr)++) +# endif +#endif +#endif + + +/* constants */ + +/* function get_args_from_arg_file() can return this in depth parameter */ +#define ARG_FILE_ERR -1 + +/* internal settings for optchar */ +#define SKIP_VALUE_ARG -1 +#define THIS_ARG_DONE -2 +#define START_VALUE_LIST -3 +#define IN_VALUE_LIST -4 +#define NON_OPTION_ARG -5 +#define STOP_VALUE_LIST -6 +/* 7/25/04 EG */ +#define READ_REST_ARGS_VERBATIM -7 + + +/* global veriables */ + +int enable_permute = 1; /* yes - return options first */ +/* 7/25/04 EG */ +int doubledash_ends_options = 1; /* when -- what follows are not options */ + +/* buffer for error messages (this sizing is a guess but must hold 2 paths) */ +#define OPTIONERR_BUF_SIZE (FNMAX * 2 + 4000) +local char Far optionerrbuf[OPTIONERR_BUF_SIZE + 1]; + +/* error messages */ +static ZCONST char Far op_not_neg_err[] = "option %s not negatable"; +static ZCONST char Far op_req_val_err[] = "option %s requires a value"; +static ZCONST char Far op_no_allow_val_err[] = "option %s does not allow a value"; +static ZCONST char Far sh_op_not_sup_err[] = "short option '%c' not supported"; +static ZCONST char Far oco_req_val_err[] = "option %s requires one character value"; +static ZCONST char Far oco_no_mbc_err[] = "option %s does not support multibyte values"; +static ZCONST char Far num_req_val_err[] = "option %s requires number value"; +static ZCONST char Far long_op_ambig_err[] = "long option '%s' ambiguous"; +static ZCONST char Far long_op_not_sup_err[] = "long option '%s' not supported"; + +static ZCONST char Far no_arg_files_err[] = "argument files not enabled\n"; + + +/* below removed as only used for processing argument files */ + +/* get_nextarg */ +/* get_args_from_string */ +/* insert_args */ +/* get_args_from_arg_file */ + + +/* copy error, option name, and option description if any to buf */ +local int optionerr(buf, err, optind, islong) + char *buf; + ZCONST char *err; + int optind; + int islong; +{ + char optname[50]; + + if (options[optind].name && options[optind].name[0] != '\0') { + if (islong) + sprintf(optname, "'%s' (%s)", options[optind].longopt, options[optind].name); + else + sprintf(optname, "'%s' (%s)", options[optind].shortopt, options[optind].name); + } else { + if (islong) + sprintf(optname, "'%s'", options[optind].longopt); + else + sprintf(optname, "'%s'", options[optind].shortopt); + } + sprintf(buf, err, optname); + return 0; +} + + +/* copy_args + * + * Copy arguments in args, allocating storage with malloc. + * Copies until a NULL argument is found or until max_args args + * including args[0] are copied. Set max_args to 0 to copy + * until NULL. Always terminates returned args[] with NULL arg. + * + * Any argument in the returned args can be freed with free(). Any + * freed argument should be replaced with either another string + * allocated with malloc or by NULL if last argument so that free_args + * will properly work. + */ +char **copy_args(args, max_args) + char **args; + int max_args; +{ + int j; + char **new_args; + + if (args == NULL) { + return NULL; + } + + /* count args */ + for (j = 0; args[j] && (max_args == 0 || j < max_args); j++) ; + + if ((new_args = (char **) malloc((j + 1) * sizeof(char *))) == NULL) { + oERR(ZE_MEM, "ca"); + } + + for (j = 0; args[j] && (max_args == 0 || j < max_args); j++) { + if (args[j] == NULL) { + /* null argument is end of args */ + new_args[j] = NULL; + break; + } + if ((new_args[j] = malloc(strlen(args[j]) + 1)) == NULL) { + free_args(new_args); + oERR(ZE_MEM, "ca"); + } + strcpy(new_args[j], args[j]); + } + new_args[j] = NULL; + + return new_args; +} + + +/* free args - free args created with one of these functions */ +int free_args(args) + char **args; +{ + int i; + + if (args == NULL) { + return 0; + } + + for (i = 0; args[i]; i++) { + free(args[i]); + } + free(args); + return i; +} + + +/* insert_arg + * + * Insert the argument arg into the array args before argument at_arg. + * Return the new count of arguments (argc). + * + * If free_args is true, this function frees the old args array + * (but not the component strings). DO NOT set free_args on original + * argv but only on args allocated with malloc. + */ + +int insert_arg(pargs, arg, at_arg, free_args) + char ***pargs; + ZCONST char *arg; + int at_arg; + int free_args; +{ + char *newarg = NULL; + char **args; + char **newargs = NULL; + int argnum; + int newargnum; + int argcnt; + int newargcnt; + + if (pargs == NULL) { + return 0; + } + args = *pargs; + + /* count args */ + if (args == NULL) { + argcnt = 0; + } else { + for (argcnt = 0; args[argcnt]; argcnt++) ; + } + if (arg == NULL) { + /* done */ + return argcnt; + } + newargcnt = argcnt + 1; + + /* get storage for new args */ + if ((newargs = (char **) malloc((newargcnt + 1) * sizeof(char *))) == NULL) { + oERR(ZE_MEM, "ia"); + } + + /* copy argument pointers from args to position at_arg, copy arg, then rest args */ + argnum = 0; + newargnum = 0; + if (args) { + for (; args[argnum] && argnum < at_arg; argnum++) { + newargs[newargnum++] = args[argnum]; + } + } + /* copy new arg */ + if ((newarg = (char *) malloc(strlen(arg) + 1)) == NULL) { + oERR(ZE_MEM, "ia"); + } + strcpy(newarg, arg); + + newargs[newargnum++] = newarg; + if (args) { + for ( ; args[argnum]; argnum++) { + newargs[newargnum++] = args[argnum]; + } + } + newargs[newargnum] = NULL; + + /* free old args array but not component strings - this assumes that + args was allocated with malloc as copy_args does. DO NOT DO THIS + on the original argv. + */ + if (free_args) + free(args); + + *pargs = newargs; + + return newargnum; +} + +/* ------------------------------------- */ + + + + +/* get_shortopt + * + * Get next short option from arg. The state is stored in argnum, optchar, and + * option_num so no static storage is used. Returns the option_ID. + * + * parameters: + * args - argv array of arguments + * argnum - index of current arg in args + * optchar - pointer to index of next char to process. Can be 0 or + * const defined at top of this file like THIS_ARG_DONE + * negated - on return pointer to int set to 1 if option negated or 0 otherwise + * value - on return pointer to string set to value of option if any or NULL + * if none. If value is returned then the caller should free() + * it when not needed anymore. + * option_num - pointer to index in options[] of returned option or + * o_NO_OPTION_MATCH if none. Do not change as used by + * value lists. + * depth - recursion depth (0 at top level, 1 or more in arg files) + */ +local unsigned long get_shortopt(args, argnum, optchar, negated, value, + option_num, depth) + char **args; + int argnum; + int *optchar; + int *negated; + char **value; + int *option_num; + int depth; +{ + char *shortopt; + int clen; + char *nextchar; + char *s; + char *start; + int op; + char *arg; + int match = -1; + + + /* get arg */ + arg = args[argnum]; + /* current char in arg */ + nextchar = arg + (*optchar); + clen = MB_CLEN(nextchar); + /* next char in arg */ + (*optchar) += clen; + /* get first char of short option */ + shortopt = arg + (*optchar); + /* no value */ + *value = NULL; + + if (*shortopt == '\0') { + /* no more options in arg */ + *optchar = 0; + *option_num = o_NO_OPTION_MATCH; + return 0; + } + + /* look for match in options */ + clen = MB_CLEN(shortopt); + for (op = 0; options[op].option_ID; op++) { + s = options[op].shortopt; + if (s && s[0] == shortopt[0]) { + if (s[1] == '\0' && clen == 1) { + /* single char match */ + match = op; + } else { + /* 2 wide short opt. Could support more chars but should use long opts instead */ + if (s[1] == shortopt[1]) { + /* match 2 char short opt or 2 byte char */ + match = op; + if (clen == 1) (*optchar)++; + break; + } + } + } + } + + if (match > -1) { + /* match */ + clen = MB_CLEN(shortopt); + nextchar = arg + (*optchar) + clen; + /* check for trailing dash negating option */ + if (*nextchar == '-') { + /* negated */ + if (options[match].negatable == o_NOT_NEGATABLE) { + if (options[match].value_type == o_NO_VALUE) { + optionerr(optionerrbuf, op_not_neg_err, match, 0); + if (depth > 0) { + /* unwind */ + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + } else { + *negated = 1; + /* set up to skip negating dash */ + (*optchar) += clen; + clen = 1; + } + } + + /* value */ + clen = MB_CLEN(arg + (*optchar)); + /* optional value, one char value, and number value must follow option */ + if (options[match].value_type == o_ONE_CHAR_VALUE) { + /* one char value */ + if (arg[(*optchar) + clen]) { + /* has value */ + if (MB_CLEN(arg + (*optchar) + clen) > 1) { + /* multibyte value not allowed for now */ + optionerr(optionerrbuf, oco_no_mbc_err, match, 0); + if (depth > 0) { + /* unwind */ + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + if ((*value = (char *) malloc(2)) == NULL) { + oERR(ZE_MEM, "gso"); + } + (*value)[0] = *(arg + (*optchar) + clen); + (*value)[1] = '\0'; + *optchar += clen; + clen = 1; + } else { + /* one char values require a value */ + optionerr(optionerrbuf, oco_req_val_err, match, 0); + if (depth > 0) { + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + } else if (options[match].value_type == o_NUMBER_VALUE) { + /* read chars until end of number */ + start = arg + (*optchar) + clen; + if (*start == '+' || *start == '-') { + start++; + } + s = start; + for (; isdigit(*s); MB_NEXTCHAR(s)) ; + if (s == start) { + /* no digits */ + optionerr(optionerrbuf, num_req_val_err, match, 0); + if (depth > 0) { + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + start = arg + (*optchar) + clen; + if ((*value = (char *) malloc((int)(s - start) + 1)) == NULL) { + oERR(ZE_MEM, "gso"); + } + *optchar += (int)(s - start); + strncpy(*value, start, (int)(s - start)); + (*value)[(int)(s - start)] = '\0'; + clen = MB_CLEN(s); + } else if (options[match].value_type == o_OPTIONAL_VALUE) { + /* optional value */ + /* This seemed inconsistent so now if no value attached to argument look + to the next argument if that argument is not an option for option + value - 11/12/04 EG */ + if (arg[(*optchar) + clen]) { + /* has value */ + /* add support for optional = - 2/6/05 EG */ + if (arg[(*optchar) + clen] == '=') { + /* skip = */ + clen++; + } + if (arg[(*optchar) + clen]) { + if ((*value = (char *)malloc(strlen(arg + (*optchar) + clen) + 1)) + == NULL) { + oERR(ZE_MEM, "gso"); + } + strcpy(*value, arg + (*optchar) + clen); + } + *optchar = THIS_ARG_DONE; + } else if (args[argnum + 1] && args[argnum + 1][0] != '-') { + /* use next arg for value */ + if ((*value = (char *)malloc(strlen(args[argnum + 1]) + 1)) == NULL) { + oERR(ZE_MEM, "gso"); + } + /* using next arg as value */ + strcpy(*value, args[argnum + 1]); + *optchar = SKIP_VALUE_ARG; + } + } else if (options[match].value_type == o_REQUIRED_VALUE || + options[match].value_type == o_VALUE_LIST) { + /* see if follows option */ + if (arg[(*optchar) + clen]) { + /* has value following option as -ovalue */ + /* add support for optional = - 6/5/05 EG */ + if (arg[(*optchar) + clen] == '=') { + /* skip = */ + clen++; + } + if ((*value = (char *)malloc(strlen(arg + (*optchar) + clen) + 1)) + == NULL) { + oERR(ZE_MEM, "gso"); + } + strcpy(*value, arg + (*optchar) + clen); + *optchar = THIS_ARG_DONE; + } else { + /* use next arg for value */ + if (args[argnum + 1]) { + if ((*value = (char *)malloc(strlen(args[argnum + 1]) + 1)) == NULL) { + oERR(ZE_MEM, "gso"); + } + strcpy(*value, args[argnum + 1]); + if (options[match].value_type == o_VALUE_LIST) { + *optchar = START_VALUE_LIST; + } else { + *optchar = SKIP_VALUE_ARG; + } + } else { + /* no value found */ + optionerr(optionerrbuf, op_req_val_err, match, 0); + if (depth > 0) { + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + } + } + + *option_num = match; + return options[match].option_ID; + } + sprintf(optionerrbuf, sh_op_not_sup_err, *shortopt); + if (depth > 0) { + /* unwind */ + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + return 0; +} + + +/* get_longopt + * + * Get the long option in args array at argnum. + * Parameters same as for get_shortopt. + */ + +local unsigned long get_longopt(args, argnum, optchar, negated, value, + option_num, depth) + char **args; + int argnum; + int *optchar; + int *negated; + char **value; + int *option_num; + int depth; +{ + char *longopt; + char *lastchr; + char *valuestart; + int op; + char *arg; + int match = -1; + *value = NULL; + + if (args == NULL) { + *option_num = o_NO_OPTION_MATCH; + return 0; + } + if (args[argnum] == NULL) { + *option_num = o_NO_OPTION_MATCH; + return 0; + } + /* copy arg so can chop end if value */ + if ((arg = (char *)malloc(strlen(args[argnum]) + 1)) == NULL) { + oERR(ZE_MEM, "glo"); + } + strcpy(arg, args[argnum]); + + /* get option */ + longopt = arg + 2; + /* no value */ + *value = NULL; + + /* find = */ + for (lastchr = longopt, valuestart = longopt; + *valuestart && *valuestart != '='; + lastchr = valuestart, MB_NEXTCHAR(valuestart)) ; + if (*valuestart) { + /* found =value */ + *valuestart = '\0'; + valuestart++; + } else { + valuestart = NULL; + } + + if (*lastchr == '-') { + /* option negated */ + *negated = 1; + *lastchr = '\0'; + } else { + *negated = 0; + } + + /* look for long option match */ + for (op = 0; options[op].option_ID; op++) { + if (options[op].longopt && strcmp(options[op].longopt, longopt) == 0) { + /* exact match */ + match = op; + break; + } + if (options[op].longopt && strncmp(options[op].longopt, longopt, strlen(longopt)) == 0) { + if (match > -1) { + sprintf(optionerrbuf, long_op_ambig_err, longopt); + free(arg); + if (depth > 0) { + /* unwind */ + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + match = op; + } + } + + if (match == -1) { + sprintf(optionerrbuf, long_op_not_sup_err, longopt); + free(arg); + if (depth > 0) { + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + + /* one long option an arg */ + *optchar = THIS_ARG_DONE; + + /* if negated then see if allowed */ + if (*negated && options[match].negatable == o_NOT_NEGATABLE) { + optionerr(optionerrbuf, op_not_neg_err, match, 1); + free(arg); + if (depth > 0) { + /* unwind */ + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + /* get value */ + if (options[match].value_type == o_OPTIONAL_VALUE) { + /* optional value in form option=value */ + if (valuestart) { + /* option=value */ + if ((*value = (char *)malloc(strlen(valuestart) + 1)) == NULL) { + free(arg); + oERR(ZE_MEM, "glo"); + } + strcpy(*value, valuestart); + } + } else if (options[match].value_type == o_REQUIRED_VALUE || + options[match].value_type == o_NUMBER_VALUE || + options[match].value_type == o_ONE_CHAR_VALUE || + options[match].value_type == o_VALUE_LIST) { + /* handle long option one char and number value as required value */ + if (valuestart) { + /* option=value */ + if ((*value = (char *)malloc(strlen(valuestart) + 1)) == NULL) { + free(arg); + oERR(ZE_MEM, "glo"); + } + strcpy(*value, valuestart); + } else { + /* use next arg */ + if (args[argnum + 1]) { + if ((*value = (char *)malloc(strlen(args[argnum + 1]) + 1)) == NULL) { + free(arg); + oERR(ZE_MEM, "glo"); + } + /* using next arg as value */ + strcpy(*value, args[argnum + 1]); + if (options[match].value_type == o_VALUE_LIST) { + *optchar = START_VALUE_LIST; + } else { + *optchar = SKIP_VALUE_ARG; + } + } else { + /* no value found */ + optionerr(optionerrbuf, op_req_val_err, match, 1); + free(arg); + if (depth > 0) { + /* unwind */ + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + } + } else if (options[match].value_type == o_NO_VALUE) { + /* this option does not accept a value */ + if (valuestart) { + /* --option=value */ + optionerr(optionerrbuf, op_no_allow_val_err, match, 1); + free(arg); + if (depth > 0) { + oWARN(optionerrbuf); + return o_ARG_FILE_ERR; + } else { + oERR(ZE_PARMS, optionerrbuf); + } + } + } + free(arg); + + *option_num = match; + return options[match].option_ID; +} + + + +/* get_option + * + * Main interface for user. Use this function to get options, values and + * non-option arguments from a command line provided in argv form. + * + * To use get_option() first define valid options by setting + * the global variable options[] to an array of option_struct. Also + * either change defaults below or make variables global and set elsewhere. + * Zip uses below defaults. + * + * Call get_option() to get an option (like -b or --temp-file) and any + * value for that option (like filename for -b) or a non-option argument + * (like archive name) each call. If *value* is not NULL after calling + * get_option() it is a returned value and the caller should either store + * the char pointer or free() it before calling get_option() again to avoid + * leaking memory. If a non-option non-value argument is returned get_option() + * returns o_NON_OPTION_ARG and value is set to the entire argument. + * When there are no more arguments get_option() returns 0. + * + * The parameters argnum (after set to 0 on initial call), + * optchar, first_nonopt_arg, option_num, and depth (after initial + * call) are set and maintained by get_option() and should not be + * changed. The parameters argc, negated, and value are outputs and + * can be used by the calling program. get_option() returns either the + * option_ID for the current option, a special value defined in + * zip.h, or 0 when no more arguments. + * + * The value returned by get_option() is the ID value in the options + * table. This value can be duplicated in the table if different + * options are really the same option. The index into the options[] + * table is given by option_num, though the ID should be used as + * option numbers change when the table is changed. The ID must + * not be 0 for any option as this ends the table. If get_option() + * finds an option not in the table it calls oERR to post an + * error and exit. Errors also result if the option requires a + * value that is missing, a value is present but the option does + * not take one, and an option is negated but is not + * negatable. Non-option arguments return o_NON_OPTION_ARG + * with the entire argument in value. + * + * For Zip, permuting is on and all options and their values are + * returned before any non-option arguments like archive name. + * + * The arguments "-" alone and "--" alone return as non-option arguments. + * Note that "-" should not be used as part of a short option + * entry in the table but can be used in the middle of long + * options such as in the long option "a-long-option". Now "--" alone + * stops option processing, returning any arguments following "--" as + * non-option arguments instead of options. + * + * Argument file support is removed from this version. It may be added later. + * + * After each call: + * argc is set to the current size of args[] but should not change + * with argument file support removed, + * argnum is the index of the current arg, + * value is either the value of the returned option or non-option + * argument or NULL if option with no value, + * negated is set if the option was negated by a trailing dash (-) + * option_num is set to either the index in options[] for the option or + * o_NO_OPTION_MATCH if no match. + * Negation is checked before the value is read if the option is negatable so + * that the - is not included in the value. If the option is not negatable + * but takes a value then the - will start the value. If permuting then + * argnum and first_nonopt_arg are unreliable and should not be used. + * + * Command line is read from left to right. As get_option() finds non-option + * arguments (arguments not starting with - and that are not values to options) + * it moves later options and values in front of the non-option arguments. + * This permuting is turned off by setting enable_permute to 0. Then + * get_option() will return options and non-option arguments in the order + * found. Currently permuting is only done after an argument is completely + * processed so that any value can be moved with options they go with. All + * state information is stored in the parameters argnum, optchar, + * first_nonopt_arg and option_num. You should not change these after the + * first call to get_option(). If you need to back up to a previous arg then + * set argnum to that arg (remembering that args may have been permuted) and + * set optchar = 0 and first_nonopt_arg to the first non-option argument if + * permuting. After all arguments are returned the next call to get_option() + * returns 0. The caller can then call free_args(args) if appropriate. + * + * get_option() accepts arguments in the following forms: + * short options + * of 1 and 2 characters, e.g. a, b, cc, d, and ba, after a single + * leading -, as in -abccdba. In this example if 'b' is followed by 'a' + * it matches short option 'ba' else it is interpreted as short option + * b followed by another option. The character - is not legal as a + * short option or as part of a 2 character short option. + * + * If a short option has a value it immediately follows the option or + * if that option is the end of the arg then the next arg is used as + * the value. So if short option e has a value, it can be given as + * -evalue + * or + * -e value + * and now + * -e=value + * but now that = is optional a leading = is stripped for the first. + * This change allows optional short option values to be defaulted as + * -e= + * Either optional or required values can be specified. Optional values + * now use both forms as ignoring the later got confusing. Any + * non-value short options can preceed a valued short option as in + * -abevalue + * Some value types (one_char and number) allow options after the value + * so if oc is an option that takes a character and n takes a number + * then + * -abocVccn42evalue + * returns value V for oc and value 42 for n. All values are strings + * so programs may have to convert the "42" to a number. See long + * options below for how value lists are handled. + * + * Any short option can be negated by following it with -. Any - is + * handled and skipped over before any value is read unless the option + * is not negatable but takes a value and then - starts the value. + * + * If the value for an optional value is just =, then treated as no + * value. + * + * long options + * of arbitrary length are assumed if an arg starts with -- but is not + * exactly --. Long options are given one per arg and can be abbreviated + * if the abbreviation uniquely matches one of the long options. + * Exact matches always match before partial matches. If ambiguous an + * error is generated. + * + * Values are specified either in the form + * --longoption=value + * or can be the following arg if the value is required as in + * --longoption value + * Optional values to long options must be in the first form. + * + * Value lists are specified by o_VALUE_LIST and consist of an option + * that takes a value followed by one or more value arguments. + * The two forms are + * --option=value + * or + * -ovalue + * for a single value or + * --option value1 value2 value3 ... --option2 + * or + * -o value1 value2 value3 ... + * for a list of values. The list ends at the next option, the + * end of the command line, or at a single "@" argument. + * Each value is treated as if it was preceeded by the option, so + * --option1 val1 val2 + * with option1 value_type set to o_VALUE_LIST is the same as + * --option1=val1 --option1=val2 + * + * Long options can be negated by following the option with - as in + * --longoption- + * Long options with values can also be negated if this makes sense for + * the caller as: + * --longoption-=value + * If = is not followed by anything it is treated as no value. + * + * @path + * When an argument in the form @path is encountered, the file at path + * is opened and white space separated arguments read from the file + * and inserted into the command line at that point as if the contents + * of the file were directly typed at that location. The file can + * have options, files to zip, or anything appropriate at that location + * in the command line. Since Zip has permuting enabled, options and + * files will propagate to the appropriate locations in the command + * line. + * + * Argument files support has been removed from this version. It may + * be added back later. + * + * non-option argument + * is any argument not given above. If enable_permute is 1 then + * these are returned after all options, otherwise all options and + * args are returned in order. Returns option ID o_NON_OPTION_ARG + * and sets value to the argument. + * + * + * Arguments to get_option: + * char ***pargs - pointer to arg array in the argv form + * int *argc - returns the current argc for args incl. args[0] + * int *argnum - the index of the current argument (caller + * should set = 0 on first call and not change + * after that) + * int *optchar - index of next short opt in arg or special + * int *first_nonopt_arg - used by get_option to permute args + * int *negated - option was negated (had trailing -) + * char *value - value of option if any (free when done with it) or NULL + * int *option_num - the index in options of the last option returned + * (can be o_NO_OPTION_MATCH) + * int recursion_depth - current depth of recursion + * (always set to 0 by caller) + * (always 0 with argument files support removed) + * + * Caller should only read the returned option ID and the value, negated, + * and option_num (if required) parameters after each call. + * + * Ed Gordon + * 24 August 2003 (last updated 2 April 2008 EG) + * + */ + +unsigned long get_option(pargs, argc, argnum, optchar, value, + negated, first_nonopt_arg, option_num, recursion_depth) + char ***pargs; + int *argc; + int *argnum; + int *optchar; + char **value; + int *negated; + int *first_nonopt_arg; + int *option_num; + int recursion_depth; +{ + char **args; + unsigned long option_ID; + + int argcnt; + int first_nonoption_arg; + char *arg = NULL; + int h; + int optc; + int argn; + int j; + int v; + int read_rest_args_verbatim = 0; /* 7/25/04 - ignore options and arg files for rest args */ + + /* value is outdated. The caller should free value before + calling get_option again. */ + *value = NULL; + + /* if args is NULL then done */ + if (pargs == NULL) { + *argc = 0; + return 0; + } + args = *pargs; + if (args == NULL) { + *argc = 0; + return 0; + } + + /* count args */ + for (argcnt = 0; args[argcnt]; argcnt++) ; + + /* if no provided args then nothing to do */ + if (argcnt < 1 || (recursion_depth == 0 && argcnt < 2)) { + *argc = argcnt; + /* return 0 to note that no args are left */ + return 0; + } + + *negated = 0; + first_nonoption_arg = *first_nonopt_arg; + argn = *argnum; + optc = *optchar; + + if (optc == READ_REST_ARGS_VERBATIM) { + read_rest_args_verbatim = 1; + } + + if (argn == -1 || (recursion_depth == 0 && argn == 0)) { + /* first call */ + /* if depth = 0 then args[0] is argv[0] so skip */ + *option_num = o_NO_OPTION_MATCH; + optc = THIS_ARG_DONE; + first_nonoption_arg = -1; + } + + /* if option_num is set then restore last option_ID in case continuing value list */ + option_ID = 0; + if (*option_num != o_NO_OPTION_MATCH) { + option_ID = options[*option_num].option_ID; + } + + /* get next option if any */ + for (;;) { + if (read_rest_args_verbatim) { + /* rest of args after "--" are non-option args if doubledash_ends_options set */ + argn++; + if (argn > argcnt || args[argn] == NULL) { + /* done */ + option_ID = 0; + break; + } + arg = args[argn]; + if ((*value = (char *)malloc(strlen(arg) + 1)) == NULL) { + oERR(ZE_MEM, "go"); + } + strcpy(*value, arg); + *option_num = o_NO_OPTION_MATCH; + option_ID = o_NON_OPTION_ARG; + break; + + /* permute non-option args after option args so options are returned first */ + } else if (enable_permute) { + if (optc == SKIP_VALUE_ARG || optc == THIS_ARG_DONE || + optc == START_VALUE_LIST || optc == IN_VALUE_LIST || + optc == STOP_VALUE_LIST) { + /* moved to new arg */ + if (first_nonoption_arg > -1 && args[first_nonoption_arg]) { + /* do the permuting - move non-options after this option */ + /* if option and value separate args or starting list skip option */ + if (optc == SKIP_VALUE_ARG || optc == START_VALUE_LIST) { + v = 1; + } else { + v = 0; + } + for (h = first_nonoption_arg; h < argn; h++) { + arg = args[first_nonoption_arg]; + for (j = first_nonoption_arg; j < argn + v; j++) { + args[j] = args[j + 1]; + } + args[j] = arg; + } + first_nonoption_arg += 1 + v; + } + } + } else if (optc == NON_OPTION_ARG) { + /* if not permuting then already returned arg */ + optc = THIS_ARG_DONE; + } + + /* value lists */ + if (optc == STOP_VALUE_LIST) { + optc = THIS_ARG_DONE; + } + + if (optc == START_VALUE_LIST || optc == IN_VALUE_LIST) { + if (optc == START_VALUE_LIST) { + /* already returned first value */ + argn++; + optc = IN_VALUE_LIST; + } + argn++; + arg = args[argn]; + /* if end of args and still in list and there are non-option args then + terminate list */ + if (arg == NULL && (optc == START_VALUE_LIST || optc == IN_VALUE_LIST) + && first_nonoption_arg > -1) { + /* terminate value list with @ */ + /* this is only needed for argument files */ + /* but is also good for show command line so command lines with lists + can always be read back in */ + argcnt = insert_arg(&args, "@", first_nonoption_arg, 1); + argn++; + if (first_nonoption_arg > -1) { + first_nonoption_arg++; + } + } + + arg = args[argn]; + if (arg && arg[0] == '@' && arg[1] == '\0') { + /* inserted arguments terminator */ + optc = STOP_VALUE_LIST; + continue; + } else if (arg && arg[0] != '-') { /* not option */ + /* - and -- are not allowed in value lists unless escaped */ + /* another value in value list */ + if ((*value = (char *)malloc(strlen(args[argn]) + 1)) == NULL) { + oERR(ZE_MEM, "go"); + } + strcpy(*value, args[argn]); + break; + + } else { + argn--; + optc = THIS_ARG_DONE; + } + } + + /* move to next arg */ + if (optc == SKIP_VALUE_ARG) { + argn += 2; + optc = 0; + } else if (optc == THIS_ARG_DONE) { + argn++; + optc = 0; + } + if (argn > argcnt) { + break; + } + if (args[argn] == NULL) { + /* done unless permuting and non-option args */ + if (first_nonoption_arg > -1 && args[first_nonoption_arg]) { + /* return non-option arguments at end */ + if (optc == NON_OPTION_ARG) { + first_nonoption_arg++; + } + /* after first pass args are permuted but skipped over non-option args */ + /* swap so argn points to first non-option arg */ + j = argn; + argn = first_nonoption_arg; + first_nonoption_arg = j; + } + if (argn > argcnt || args[argn] == NULL) { + /* done */ + option_ID = 0; + break; + } + } + + /* after swap first_nonoption_arg points to end which is NULL */ + if (first_nonoption_arg > -1 && (args[first_nonoption_arg] == NULL)) { + /* only non-option args left */ + if (optc == NON_OPTION_ARG) { + argn++; + } + if (argn > argcnt || args[argn] == NULL) { + /* done */ + option_ID = 0; + break; + } + if ((*value = (char *)malloc(strlen(args[argn]) + 1)) == NULL) { + oERR(ZE_MEM, "go"); + } + strcpy(*value, args[argn]); + optc = NON_OPTION_ARG; + option_ID = o_NON_OPTION_ARG; + break; + } + + arg = args[argn]; + + /* is it an option */ + if (arg[0] == '-') { + /* option */ + if (arg[1] == '\0') { + /* arg = - */ + /* treat like non-option arg */ + *option_num = o_NO_OPTION_MATCH; + if (enable_permute) { + /* permute args to move all non-option args to end */ + if (first_nonoption_arg < 0) { + first_nonoption_arg = argn; + } + argn++; + } else { + /* not permute args so return non-option args when found */ + if ((*value = (char *)malloc(strlen(arg) + 1)) == NULL) { + oERR(ZE_MEM, "go"); + } + strcpy(*value, arg); + optc = NON_OPTION_ARG; + option_ID = o_NON_OPTION_ARG; + break; + } + + } else if (arg[1] == '-') { + /* long option */ + if (arg[2] == '\0') { + /* arg = -- */ + if (doubledash_ends_options) { + /* Now -- stops permuting and forces the rest of + the command line to be read verbatim - 7/25/04 EG */ + + /* never permute args after -- and return as non-option args */ + if (first_nonoption_arg < 1) { + /* -- is first non-option argument - 8/7/04 EG */ + argn--; + } else { + /* go back to start of non-option args - 8/7/04 EG */ + argn = first_nonoption_arg - 1; + } + + /* disable permuting and treat remaining arguments as not + options */ + read_rest_args_verbatim = 1; + optc = READ_REST_ARGS_VERBATIM; + + } else { + /* treat like non-option arg */ + *option_num = o_NO_OPTION_MATCH; + if (enable_permute) { + /* permute args to move all non-option args to end */ + if (first_nonoption_arg < 0) { + first_nonoption_arg = argn; + } + argn++; + } else { + /* not permute args so return non-option args when found */ + if ((*value = (char *)malloc(strlen(arg) + 1)) == NULL) { + oERR(ZE_MEM, "go"); + } + strcpy(*value, arg); + optc = NON_OPTION_ARG; + option_ID = o_NON_OPTION_ARG; + break; + } + } + + } else { + option_ID = get_longopt(args, argn, &optc, negated, value, option_num, recursion_depth); + if (option_ID == o_ARG_FILE_ERR) { + /* unwind as only get this if recursion_depth > 0 */ + return option_ID; + } + break; + } + + } else { + /* short option */ + option_ID = get_shortopt(args, argn, &optc, negated, value, option_num, recursion_depth); + + if (option_ID == o_ARG_FILE_ERR) { + /* unwind as only get this if recursion_depth > 0 */ + return option_ID; + } + + if (optc == 0) { + /* if optc = 0 then ran out of short opts this arg */ + optc = THIS_ARG_DONE; + } else { + break; + } + } + +#if 0 + /* argument file code left out + so for now let filenames start with @ + */ + + } else if (allow_arg_files && arg[0] == '@') { + /* arg file */ + oERR(ZE_PARMS, no_arg_files_err); +#endif + + } else { + /* non-option */ + if (enable_permute) { + /* permute args to move all non-option args to end */ + if (first_nonoption_arg < 0) { + first_nonoption_arg = argn; + } + argn++; + } else { + /* no permute args so return non-option args when found */ + if ((*value = (char *)malloc(strlen(arg) + 1)) == NULL) { + oERR(ZE_MEM, "go"); + } + strcpy(*value, arg); + *option_num = o_NO_OPTION_MATCH; + optc = NON_OPTION_ARG; + option_ID = o_NON_OPTION_ARG; + break; + } + + } + } + + *pargs = args; + *argc = argcnt; + *first_nonopt_arg = first_nonoption_arg; + *argnum = argn; + *optchar = optc; + + return option_ID; +} diff --git a/globals.c b/globals.c new file mode 100644 index 0000000..e73392a --- /dev/null +++ b/globals.c @@ -0,0 +1,253 @@ +/* + globals.c - Zip 3 + + Copyright (c) 1990-2008 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + * globals.c by Mark Adler + */ +#define __GLOBALS_C + +#define GLOBALS /* include definition of errors[] in zip.h */ +#ifndef UTIL +#define UTIL /* do not declare the read_buf variable */ +#endif + +#include "zip.h" + + +/* Handy place to build error messages */ +char errbuf[FNMAX+4081]; + +/* Argument processing globals */ +int recurse = 0; /* 1=recurse into directories encountered */ +int dispose = 0; /* 1=remove files after put in zip file */ +int pathput = 1; /* 1=store path with name */ +#ifdef RISCOS +int scanimage = 1; /* 1=scan through image files */ +#endif +int method = BEST; /* one of BEST, DEFLATE (only), or STORE (only) */ +int dosify = 0; /* 1=make new entries look like MSDOS */ +int verbose = 0; /* 1=report oddities in zip file structure */ +int fix = 0; /* 1=fix the zip file, 2=FF, 3=ZipNote */ +int filesync = 0; /* 1=file sync, delete entries not on file system */ +int adjust = 0; /* 1=adjust offsets for sfx'd file (keep preamble) */ +int level = 6; /* 0=fastest compression, 9=best compression */ +int translate_eol = 0; /* Translate end-of-line LF -> CR LF */ +#ifdef VMS + int vmsver = 0; /* 1=append VMS version number to file names */ + int vms_native = 0; /* 1=store in VMS format */ + int vms_case_2 = 0; /* ODS2 file name case in VMS. -1: down. */ + int vms_case_5 = 0; /* ODS5 file name case in VMS. +1: preserve. */ +#endif /* VMS */ +#if defined(OS2) || defined(WIN32) + int use_longname_ea = 0; /* 1=use the .LONGNAME EA as the file's name */ +#endif +/* 9/26/04 */ +int no_wild = 0; /* 1 = wildcards are disabled */ +int allow_regex = 0; /* 1 = allow [list] matching */ +#ifdef WILD_STOP_AT_DIR + int wild_stop_at_dir = 1; /* default wildcards do not include / in matches */ +#else + int wild_stop_at_dir = 0; /* default wildcards do include / in matches */ +#endif + +#ifdef UNICODE_SUPPORT + int using_utf8 = 0; /* 1 if current character set UTF-8 */ +# ifdef WIN32 + int no_win32_wide = -1; /* 1 = no wide functions, like GetFileAttributesW() */ +# endif +#endif + +ulg skip_this_disk = 0; +int des_good = 0; /* Good data descriptor found */ +ulg des_crc = 0; /* Data descriptor CRC */ +uzoff_t des_csize = 0; /* Data descriptor csize */ +uzoff_t des_usize = 0; /* Data descriptor usize */ + +/* dots 10/20/04 */ +zoff_t dot_size = 0; /* bytes processed in deflate per dot, 0 = no dots */ +zoff_t dot_count = 0; /* buffers seen, recyles at dot_size */ +/* status 10/30/04 */ +int display_counts = 0; /* display running file count */ +int display_bytes = 0; /* display running bytes remaining */ +int display_globaldots = 0; /* display dots for archive instead of each file */ +int display_volume = 0; /* display current input and output volume (disk) numbers */ +int display_usize = 0; /* display uncompressed bytes */ +ulg files_so_far = 0; /* files processed so far */ +ulg bad_files_so_far = 0; /* bad files skipped so far */ +ulg files_total = 0; /* files total to process */ +uzoff_t bytes_so_far = 0; /* bytes processed so far (from initial scan) */ +uzoff_t good_bytes_so_far = 0;/* good bytes read so far */ +uzoff_t bad_bytes_so_far = 0; /* bad bytes skipped so far */ +uzoff_t bytes_total = 0; /* total bytes to process (from initial scan) */ + +/* logfile 6/5/05 */ +int logall = 0; /* 0 = warnings/errors, 1 = all */ +FILE *logfile = NULL; /* pointer to open logfile or NULL */ +int logfile_append = 0; /* append to existing logfile */ +char *logfile_path = NULL; /* pointer to path of logfile */ + +int hidden_files = 0; /* process hidden and system files */ +int volume_label = 0; /* add volume label */ +int dirnames = 1; /* include directory entries by default */ +int filter_match_case = 1; /* 1=match case when filter() */ +int diff_mode = 0; /* 1=require --out and only store changed and add */ +#if defined(WIN32) +int only_archive_set = 0; /* include only files with DOS archive bit set */ +int clear_archive_bits = 0; /* clear DOS archive bit of included files */ +#endif +int linkput = 0; /* 1=store symbolic links as such */ +int noisy = 1; /* 0=quiet operation */ +int extra_fields = 1; /* 0=create minimum, 1=don't copy old, 2=keep old */ +int use_descriptors = 0; /* 1=use data descriptors 12/29/04 */ +int zip_to_stdout = 0; /* output zipfile to stdout 12/30/04 */ +int allow_empty_archive = 0; /* if no files, create empty archive anyway 12/28/05 */ +int copy_only = 0; /* 1=copying archive entries only */ +int allow_fifo = 0; /* 1=allow reading Unix FIFOs, waiting if pipe open */ +int show_files = 0; /* show files to operate on and exit (=2 log only) */ + +int output_seekable = 1; /* 1 = output seekable 3/13/05 EG */ + +#ifdef ZIP64_SUPPORT /* zip64 support 10/4/03 */ + int force_zip64 = -1; /* if 1 force entries to be zip64, 0 force not zip64 */ + /* mainly for streaming from stdin */ + int zip64_entry = 0; /* current entry needs Zip64 */ + int zip64_archive = 0; /* if 1 then at least 1 entry needs zip64 */ +#endif + +#ifdef NTSD_EAS + int use_privileges = 0; /* 1=use security privilege overrides */ +#endif +#ifndef RISCOS +#ifndef QDOS +#ifndef TANDEM +char *special = ".Z:.zip:.zoo:.arc:.lzh:.arj"; /* List of special suffixes */ +#else /* TANDEM */ +char *special = " Z: zip: zoo: arc: lzh: arj"; /* List of special suffixes */ +#endif +#else /* QDOS */ +char *special = "_Z:_zip:_zoo:_arc:_lzh:_arj"; /* List of special suffixes */ +#endif +#else /* RISCOS */ +char *special = "DDC:D96:68E"; +#endif /* ?RISCOS */ +char *key = NULL; /* Scramble password if scrambling */ +char *tempath = NULL; /* Path for temporary files */ +FILE *mesg; /* stdout by default, stderr for piping */ + +#ifdef UNICODE_SUPPORT + int utf8_force = 0; /* 1=force storing UTF-8 as standard per AppNote bit 11 */ +#endif +int unicode_escape_all = 0; /* 1=escape all non-ASCII characters in paths */ +int unicode_mismatch = 1; /* unicode mismatch is 0=error, 1=warn, 2=ignore, 3=no */ + +time_t scan_delay = 5; /* seconds before display Scanning files message */ +time_t scan_dot_time = 2; /* time in seconds between Scanning files dots */ +time_t scan_start = 0; /* start of scan */ +time_t scan_last = 0; /* time of last message */ +int scan_started = 0; /* scan has started */ +uzoff_t scan_count = 0; /* Used for Scanning files ... message */ + +ulg before = 0; /* 0=ignore, else exclude files before this time */ +ulg after = 0; /* 0=ignore, else exclude files newer than this time */ + +/* Zip file globals */ +char *zipfile; /* New or existing zip archive (zip file) */ + +/* zip64 support 08/31/2003 R.Nausedat */ +/* all are across splits - subtract bytes_prev_splits to get offsets for current disk */ +uzoff_t zipbeg; /* Starting offset of zip structures */ +uzoff_t cenbeg; /* Starting offset of central dir */ +uzoff_t tempzn; /* Count of bytes written to output zip files */ + +/* 10/28/05 */ +char *tempzip = NULL; /* name of temp file */ +FILE *y = NULL; /* output file now global so can change in splits */ +FILE *in_file = NULL; /* current input file for splits */ +char *in_path = NULL; /* base name of input archive file */ +char *in_split_path = NULL; /* in split path */ +char *out_path = NULL; /* base name of output file, usually same as zipfile */ +int zip_attributes = 0; + +/* in split globals */ + +ulg total_disks = 0; /* total disks in archive */ +ulg current_in_disk = 0; /* current read split disk */ +uzoff_t current_in_offset = 0; /* current offset in current read disk */ +ulg skip_current_disk = 0; /* if != 0 and fix then skip entries on this disk */ + + +/* out split globals */ + +ulg current_local_disk = 0; /* disk with current local header */ + +ulg current_disk = 0; /* current disk number */ +ulg cd_start_disk = (ulg)-1; /* central directory start disk */ +uzoff_t cd_start_offset = 0; /* offset of start of cd on cd start disk */ +uzoff_t cd_entries_this_disk = 0; /* cd entries this disk */ +uzoff_t total_cd_entries = 0; /* total cd entries in new/updated archive */ +ulg zip64_eocd_disk = 0; /* disk with Zip64 End Of Central Directory Record */ +uzoff_t zip64_eocd_offset = 0; /* offset for Zip64 EOCD Record */ + +/* for split method 1 (keep split with local header open and update) */ +char *current_local_tempname = NULL; /* name of temp file */ +FILE *current_local_file = NULL; /* file pointer for current local header */ +uzoff_t current_local_offset = 0; /* offset to start of current local header */ + +/* global */ +uzoff_t bytes_this_split = 0; /* bytes written to the current split */ +int read_split_archive = 0; /* 1=scanzipf_reg detected spanning signature */ +int split_method = 0; /* 0=no splits, 1=seekable, 2=data desc, -1=no */ +uzoff_t split_size = 0; /* how big each split should be */ +int split_bell = 0; /* when pause for next split ring bell */ +uzoff_t bytes_prev_splits = 0; /* total bytes written to all splits before this */ +uzoff_t bytes_this_entry = 0; /* bytes written for this entry across all splits */ +int noisy_splits = 0; /* note when splits are being created */ +int mesg_line_started = 0; /* 1=started writing a line to mesg */ +int logfile_line_started = 0; /* 1=started writing a line to logfile */ + +#ifdef WIN32 + int nonlocal_name = 0; /* Name has non-local characters */ + int nonlocal_path = 0; /* Path has non-local characters */ +#endif +#ifdef UNICODE_SUPPORT + int use_wide_to_mb_default = 0; +#endif + +struct zlist far *zfiles = NULL; /* Pointer to list of files in zip file */ +/* The limit for number of files using the Zip64 format is 2^64 - 1 (8 bytes) + but extent is used for many internal sorts and other tasks and is generally + long on 32-bit systems. Because of that, but more because of various memory + utilization issues limiting the practical number of central directory entries + that can be sorted, the number of actual entries that can be stored probably + can't exceed roughly 2^30 on 32-bit systems so extent is probably sufficient. */ +extent zcount; /* Number of files in zip file */ +int zipfile_exists = 0; /* 1 if zipfile exists */ +ush zcomlen; /* Length of zip file comment */ +char *zcomment = NULL; /* Zip file comment (not zero-terminated) */ +struct zlist far **zsort; /* List of files sorted by name */ +#ifdef UNICODE_SUPPORT + struct zlist far **zusort; /* List of files sorted by zuname */ +#endif + +/* Files to operate on that are not in zip file */ +struct flist far *found = NULL; /* List of names found */ +struct flist far * far *fnxt = &found; + /* Where to put next name in found list */ +extent fcount; /* Count of files in list */ + +/* Patterns to be matched */ +struct plist *patterns = NULL; /* List of patterns to be matched */ +unsigned pcount = 0; /* number of patterns */ +unsigned icount = 0; /* number of include only patterns */ +unsigned Rcount = 0; /* number of -R include patterns */ + +#ifdef IZ_CHECK_TZ +int zp_tz_is_valid; /* signals "timezone info is available" */ +#endif diff --git a/human68k/Makefile b/human68k/Makefile new file mode 100644 index 0000000..be1a8b7 --- /dev/null +++ b/human68k/Makefile @@ -0,0 +1,95 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for human68k +# Written by NIIMI Satoshi +# +# 1999/09/23: Modified by Shimazaki Ryo. + +ifeq "$(TARGET)" "X68030" +COPT = -m68020-40 +AOPT = -m68020 -sCPU020 +LDFLAGS = -L/usr/local/lib/lib060 +endif + +VPATH = human68k + +CC = gcc2 +CFLAGS = $(COPT) -I. -Wall -O2 -fomit-frame-pointer -fstrength-reduce \ + -DASM_CRC -D__DOS_INLINE__ +#LDFLAGS = -Wl,-x +LIBS = -lhmem -lttyi -lsignal + +AS = g2as +ASFLAGS = $(AOPT) -1 -c4 -y -w2 + +# object file lists +OBJZ = zip.o zipfile.o zipup.o fileio.o util.o globals.o crypt.o ttyio.o \ + crc32.o human68k.o crc_68.o +OBJI = deflate.o trees.o +OBJA = +OBJU = zipfile_.o fileio_.o util_.o globals.o human68k_.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o $(OBJU) crc32_.o crypt_.o ttyio.o +OBJS = zipsplit.o $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h human68k/osdep.h + +all: zips + +.SUFFIXES: _.o .o .c +.c_.o: + $(CC) $(CFLAGS) -DUTIL -c $< -o $@ +.c.o: + $(CC) $(CFLAGS) -c $< -o $@ + +ZIPS = zip.x zipnote.x zipsplit.x zipcloak.x + +zips: $(ZIPS) + +zip.x: $(OBJZ) $(OBJI) $(OBJA) + $(CC) $(LDFLAGS) -o $@ $(OBJZ) $(OBJI) $(OBJA) $(LIBS) +zipnote.x: $(OBJN) + $(CC) $(LDFLAGS) -o $@ $(OBJN) $(LIBS) +zipcloak.x: $(OBJC) + $(CC) $(LDFLAGS) -o $@ $(OBJC) $(LIBS) +zipsplit.x: $(OBJS) + $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + + +human68k.o: human68k/human68k.c + $(CC) $(CFLAGS) -c -o $@ $< + +human68k_.o: human68k/human68k.c + $(CC) $(CFLAGS) -c -o $@ $< -DUTIL + +#match.o: human68k/match.s +# $(AS) $(ASFLAGS) -o $@ $< + +deflate.o: human68k/deflate.s + $(AS) $(ASFLAGS) -o $@ $< + +crc_68.o: human68k/crc_68.s + $(AS) $(ASFLAGS) -o $@ $< + + +clean: + rm -f *.o $(ZIPS) + +zip.bfd: $(ZIPS) + rm -f $@ + for file in $(ZIPS); do \ + bdif -A -R uploaded/$$file $$file $@; \ + done + +# rules for zip, zipnote, zipcloak, zipsplit. +$(OBJZ): $(ZIP_H) +$(OBJI): $(ZIP_H) +$(OBJN): $(ZIP_H) +$(OBJS): $(ZIP_H) +$(OBJC): $(ZIP_H) +zip.o crc32.o crypt.o fileio.o zipfile.o zipup.o: crc32.h +zipcloak.o crc32_.o crypt_.o fileio_.o zipfile_.o: crc32.h +zip.o zipup.o crypt.o ttyio.o zipcloak.o crypt_.o: crypt.h +zip.o zipup.o zipnote.o zipcloak.o zipsplit.o: revision.h +zip.o crypt.o ttyio.o zipcloak.o crypt_.o: ttyio.h +zipup.o: human68k/zipup.h + +# EOF diff --git a/human68k/Makefile.gcc b/human68k/Makefile.gcc new file mode 100644 index 0000000..edf2989 --- /dev/null +++ b/human68k/Makefile.gcc @@ -0,0 +1,78 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for human68k +# Written by NIIMI Satoshi + +VPATH = human68k + +CC = gcc +AS = as + +# if you are using mc68030 (or higher) based X68000, +# uncomment following defines +#CC = gcc -DUNALIGNED_OK +#AS = as -s UNALIGNED_OK + +CFLAGS = -Wall -O -fomit-frame-pointer -fstrength-reduce -DASMV +LDFLAGS = -s +LIBS = -lsignal -lmb -ldos + +# object file lists +OBJZ = zip.o zipfile.o zipup.o fileio.o util.o crc32.o globals.o \ + crypt.o ttyio.o + +OBJI = deflate.o trees.o +OBJA = match.o human68k.o +OBJU = zipfile_.o fileio_.o util_.o globals.o human68_.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o $(OBJU) crc32_.o crypt_.o ttyio.o +OBJS = zipsplit.o $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h human68k/osdep.h + +all: zips + +.SUFFIXES: _.o .o .c +.c_.o: + $(CC) $(CFLAGS) -DUTIL -c $< -o $@ +.c.o: + $(CC) $(CFLAGS) -c $< -o $@ + +ZIPS = zip.x zipnote.x zipsplit.x zipcloak.x + +zips: $(ZIPS) + +zip.x: $(OBJZ) $(OBJI) $(OBJA) + $(CC) -o zip.x $(LDFLAGS) $(OBJZ) $(OBJI) $(OBJA) $(LIBS) +zipnote.x: $(OBJN) + $(CC) -o zipnote.x $(LDFLAGS) $(OBJN) $(LIBS) +zipcloak.x: $(OBJC) + $(CC) -o zipcloak.x $(LDFLAGS) $(OBJC) $(LIBS) +zipsplit.x: $(OBJS) + $(CC) -o zipsplit.x $(LDFLAGS) $(OBJS) $(LIBS) + +match.o: human68k/match.s + $(AS) -o $@ $< + +human68_.o: human68k/human68k.c + $(CC) $(CFLAGS) -DUTIL -c -o $@ $< + +clean: + rm -f *.o $(ZIPS) + +zip.bfd: $(ZIPS) + rm -f $@ + for file in $(ZIPS); do \ + bdif -A -R uploaded/$$file $$file $@; \ + done + +# rules for zip, zipnote, zipcloak, zipsplit. +$(OBJZ): $(ZIP_H) +$(OBJI): $(ZIP_H) +$(OBJN): $(ZIP_H) +$(OBJS): $(ZIP_H) +$(OBJC): $(ZIP_H) +zip.o crc32.o crypt.o fileio.o zipfile.o zipup.o: crc32.h +zipcloak.o crc32_.o crypt_.o fileio_.o zipfile_.o: crc32.h +zip.o zipup.o crypt.o ttyio.o zipcloak.o crypt_.o: crypt.h +zip.o zipup.o zipnote.o zipcloak.o zipsplit.o: revision.h +zip.o crypt.o ttyio.o zipcloak.o crypt_.o: ttyio.h +zipup.o: human68k/zipup.h diff --git a/human68k/crc_68.s b/human68k/crc_68.s new file mode 100644 index 0000000..9ce78d8 --- /dev/null +++ b/human68k/crc_68.s @@ -0,0 +1,144 @@ +;=========================================================================== +; Copyright (c) 1990-2000 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 2000-Apr-09 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, all these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +;=========================================================================== +; crc_68 created by Paul Kienitz, last modified 04 Jan 96. +; +; Return an updated 32 bit CRC value, given the old value and a block of data. +; The CRC table used to compute the value is gotten by calling get_crc_table(). +; This replaces the older updcrc() function used in Zip and fUnZip. The +; prototype of the function is: +; +; ulg crc32(ulg crcval, uch *text, extent textlen); +; +; On the Amiga, type extent is always unsigned long, not unsigned int, because +; int can be short or long at whim, but size_t is long. +; +; If using this source on a non-Amiga 680x0 system, note that we treat +; a0/a1/d0/d1 as scratch registers not preserved across function calls. +; We do not bother to support registerized arguments for crc32() -- the +; textlen parm is usually large enough so that savings outside the loop +; are pointless. +; +; Define NO_UNROLLED_LOOPS to use a simple short loop which might be more +; efficient on certain machines with dinky instruction caches ('020?), or for +; processing short strings. If loops are unrolled, the textlen parm must be +; less than 512K; if not unrolled, it must be less than 64K. +; +; 1999/09/23: for Human68k: Modified by Shimazaki Ryo. + + xdef _crc32 ; (ulg val, uch *buf, extent bufsize) + +DO_CRC0 MACRO + moveq #0,ltemp + move.b (textbuf)+,ltemp + eor.b crcval,ltemp + lsl.w #2,ltemp + move.l (crc_table,ltemp.w),ltemp + lsr.l #8,crcval + eor.l ltemp,crcval + ENDM + + +DO_CRC2 MACRO + move.b (textbuf)+,btemp + eor.b crcval,btemp + lsr.l #8,crcval + move.l (crc_table,btemp.w*4),ltemp + eor.l ltemp,crcval + ENDM + +crc_table reg a0 array of unsigned long +crcval reg d0 unsigned long initial value +textbuf reg a1 array of unsigned char +textbufsize reg d1 unsigned long (count of bytes in textbuf) +btemp reg d2 +ltemp reg d3 + + + xref _get_crc_table ; ulg *get_crc_table(void) + + + + quad +_crc32: + move.l 8(sp),d0 + bne.s valid +;;;;; moveq #0,d0 + rts +valid: movem.l btemp/ltemp,-(sp) + jsr _get_crc_table + movea.l d0,crc_table + move.l 12(sp),crcval + move.l 16(sp),textbuf + move.l 20(sp),textbufsize + not.l crcval + + ifdef NO_UNROLLED_LOOPS + + if CPU==68000 + bra.s decr +loop: DO_CRC0 +decr: dbra textbufsize,loop + bra.s done + + else +twenty: moveq #0,btemp + bra.s decr2 +loop2: DO_CRC2 +decr2: dbra textbufsize,loop2 + endif + + ELSE ; !NO_UNROLLED_LOOPS + + if CPU==68000 + moveq #7,btemp + and textbufsize,btemp + lsr.l #3,textbufsize + bra decr8 +loop8: DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 + DO_CRC0 +decr8: dbra textbufsize,loop8 + bra.s decr1 +loop1: DO_CRC0 +decr1: dbra btemp,loop1 + bra done + + else +twenty: moveq #0,btemp + move.l textbufsize,-(sp) + lsr.l #3,textbufsize + bra decr82 + quad +loop82: DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 + DO_CRC2 +decr82: dbra textbufsize,loop82 + moveq #7,textbufsize + and.l (sp)+,textbufsize + bra.s decr12 +loop12: DO_CRC2 +decr12: dbra textbufsize,loop12 + endif + + ENDC ; ?NO_UNROLLED_LOOPS + +done: movem.l (sp)+,btemp/ltemp + not.l crcval +;;;;; move.l crcval,d0 ; crcval already is d0 + rts diff --git a/human68k/deflate.s b/human68k/deflate.s new file mode 100644 index 0000000..246962c --- /dev/null +++ b/human68k/deflate.s @@ -0,0 +1,1076 @@ +;=========================================================================== +; Copyright (c) 1990-1999 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 1999-Oct-05 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, both of these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +;=========================================================================== +; This is a 680x0 assembly language translation of the Info-ZIP source file +; deflate.c, by Paul Kienitz. No rights reserved. The function longest_match +; is based in part on match.a by Carsten Steger, which in turn is partly based +; on match.s for 386 by Jean-loup Gailly and Kai Uwe Rommel. Mostly, however, +; this material is based on deflate.c, by Gailly, Rommel, and Igor Mandrichenko. +; This code is not commented very much; see deflate.c for comments that explain +; what the functions are doing. +; +; The symbols that can be used to select different versions are as follows: +; +; CPU020 if defined, use 68020 instructions always. +; +; CPUTEST if defined, check at runtime for CPU type. Another symbol +; specifying the platform-specific test must be used with this. +; If neither of these is defined, use 68000 instructions only. +; Runtime test is nonportable; it is different for each OS. +; +; AMIGA use Amiga-specific test for 68020, if CPUTEST defined. Also +; tells it that registers d0/a0/d1/a1 are not preserved by +; function calls. At present, if AMIGA is not defined, it +; causes functions to preserve all registers. ALL OF THIS CODE +; CURRENTLY ASSUMES THAT REGISTERS D2-D7/A2-A6 WILL BE PRESERVED +; BY ANY FUNCTIONS THAT IT CALLS. +; +; DYN_ALLOC should be defined here if it is defined for C source; tells us +; that big arrays are allocated instead of static. +; +; WSIZE must be defined as the same number used for WSIZE in the C +; source, and must be a power of two <= 32768. As elsewhere, +; the default value is 32768. +; +; INT16 define this if ints are 16 bits; otherwise 32 bit ints assumed. +; +; SMALL_MEM define this if it is defined in the C source; otherwise it uses +; the MEDIUM_MEM model. BIG_MEM and MMAP are *not* supported. +; The FULL_SEARCH option in deflate.c is also not supported. +; +; DEBUG activates some tracing output, as in the C source. +; +; QUADLONG this selects a different version of the innermost longest_match +; loop code for 68020 operations, comparing bytes four at a time +; instead of two at a time. It seems to be a tiny bit faster on +; average, but it's slower often enough that one can't generalize. +; +; This code currently assumes that function results are returned in D0 for +; all platforms. It assumes that args to functions are pushed onto the stack, +; last arg first. It also currently assumes that all C symbols have an +; underscore prepended when referenced from assembly. +; +; 1999/09/23: for Human68k: Modified by Shimazaki Ryo. + + IFNDEF CPU020 + IFNDEF CPUTEST +CPU000 equ 1 + ENDC + ENDC + +; Use these macros for accessing variables of type int: + IFDEF INT16 +MOVINT MACRO _1,_2 + move.w _1,_2 + ENDM +CLRINT MACRO _1 + clr.w _1 + ENDM +INTSIZE equ 2 + ELSE ; !INT16 +MOVINT MACRO _1,_2 + move.l _1,_2 + ENDM +CLRINT MACRO _1 + clr.l _1 + ENDM +INTSIZE equ 4 + ENDC + + IFDEF DYN_ALLOC +BASEPTR MACRO _1,_2 + move.l _1,_2 + ENDM + ELSE +BASEPTR MACRO _1,_2 + lea _1,_2 + ENDM + ENDC + +; constants we use, many of them adjustable: + +MAX_MATCH equ 258 +MIN_MATCH equ 3 +TOO_FAR equ 4096 + IFNDEF WSIZE +WSIZE equ 32768 + ENDC +WMASK equ WSIZE-1 +MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1 +MIN_LOOKAHEAD equ MAX_MATCH+MIN_MATCH+1 +; IFD BIG_MEM ; NOT supported -- type Pos needs to be 32 bits +;HASH_BITS equ 15 +; ELSE + IFDEF SMALL_MEM +HASH_BITS equ 13 + ELSE +HASH_BITS equ 14 ; default -- MEDIUM_MEM + ENDC +; ENDC ; BIG_MEM +HASH_SIZE equ 1< + MOVINT Strst,_strstart ; ct_tally reads this variable + moveq #0,d0 + move.b -1(Window,Strst.l),d0 + movem.l d2/a2,-(sp) + MOVINT d0,-(sp) + CLRINT -(sp) + jsr _ct_tally + addq #2*INTSIZE,sp + movem.l (sp)+,d2/a2 + tst.w d0 + beq.s skipliteral + FLUSH_B 0 + move.l Strst,_block_start +skipliteral: + addq.w #1,Strst + subq.w #1,Look + +refill: + cmp.w #MIN_LOOKAHEAD,Look + bhs look_loop + bsr fill_window + bra look_loop + +last_tally: + tst.w Avail + beq last_flush + MOVINT Strst,_strstart ; ct_tally reads this variable + moveq #0,d0 + move.b -1(Window,Strst.l),d0 + movem.l d2/a2,-(sp) + MOVINT d0,-(sp) + CLRINT -(sp) + jsr _ct_tally + addq #2*INTSIZE,sp + movem.l (sp)+,d2/a2 +last_flush: + FLUSH_B 1 + bra deflate_exit + +; ================== This is another version used for low compression levels: + +deflate_fast: + moveq #0,MatchL + moveq #MIN_MATCH-1,PrevL +flook_loop: + tst.w Look + beq flast_flush + + IN_STR a0,d0 + tst.w Head + beq.s fno_new_match + move.w Strst,d0 + sub.w Head,d0 + cmp.w #MAX_DIST,d0 + bhi.s fno_new_match + move.w PrevL,prev_length ; longest_match reads these variables + MOVINT Strst,_strstart + MOVINT Head,d0 ; parm for longest_match + bsr longest_match ; sets match_start + cmp.w Look,d0 ; does length exceed valid data? + bls.s fstml + move.w Look,d0 +fstml: move.w d0,MatchL ; valid length of match + +fno_new_match: + cmp.w #MIN_MATCH,MatchL + blo fliteral + ; CHECK_MATCH Strst,match_start,MatchL + MOVINT Strst,_strstart ; ct_tally reads this variable + move.l MatchL,d0 + subq.w #MIN_MATCH,d0 + movem.l d2/a2,-(sp) + MOVINT d0,-(sp) + move.l Strst,d0 + sub.w (match_start,pc),d0 + MOVINT d0,-(sp) + jsr _ct_tally ; sets d0 true if we have to flush + addq #2*INTSIZE,sp + movem.l (sp)+,d2/a2 + sub.w MatchL,Look + cmp.w (max_lazy_match,pc),MatchL + bhi ftoolong + subq.w #2,MatchL +finsertmatch: + addq.w #1,Strst + IN_STR a0,d1 ; preserve d0 + dbra MatchL,finsertmatch + moveq #0,MatchL ; not needed? + addq.w #1,Strst + bra.s flushfill + +ftoolong: + add.w MatchL,Strst + moveq #0,MatchL + moveq #0,d1 ; preserve d0 + move.b (Window,Strst.l),d1 + move.w d1,ins_h +; My assembler objects to passing <1(Window,Strst.l)> directly to UP_HASH... + move.b 1(Window,Strst.l),Avail ; Avail is not used in deflate_fast + UP_HASH d1,Avail ; preserve d0 + IFNE MIN_MATCH-3 + FAIL needs to UP_HASH another MIN_MATCH-3 times, but with what arg? + ENDC + bra.s flushfill + +fliteral: + TRACE_C <(Window,Strst.l)> + MOVINT Strst,_strstart ; ct_tally reads this variable + moveq #0,d0 + move.b (Window,Strst.l),d0 + movem.l d2/a2,-(sp) + MOVINT d0,-(sp) + CLRINT -(sp) + jsr _ct_tally ; d0 set if we need to flush + addq #2*INTSIZE,sp + movem.l (sp)+,d2/a2 + addq.w #1,Strst + subq.w #1,Look + +flushfill: + tst.w d0 + beq.s frefill + FLUSH_B 0 + move.l Strst,_block_start +frefill: + cmp.w #MIN_LOOKAHEAD,Look + bhs flook_loop + bsr fill_window + bra flook_loop + +flast_flush: + FLUSH_B 1 ; sets our return value + +deflate_exit: + MOVINT Strst,_strstart ; save back cached values + move.w PrevL,prev_length + move.w Look,lookahead + movem.l (sp)+,DEFREGS + rts + + +; ========================================================================= +; void fill_window(void) calls the input function to refill the sliding +; window that we use to find substring matches in. + +More reg Head ; local variable in fill_window +WindTop reg Prev ; local variable used for sliding +SlidIx reg PrevL ; local variable used for sliding + +FWREGS reg d2-d5/a2-a6 ; does NOT include Look and Strst +; all registers available to be clobbered by the sliding operation: +; we exclude More, WindTop, SlidIx, Look, Strst, Window, a4 and a7. +SPAREGS reg d0-d3/a0-a1/a5-a6 +SPCOUNT equ 8 ; number of registers in SPAREGS + + +_fill_window: ; C-callable entry point + movem.l Look/Strst,-(sp) + IFDEF INT16 + moveq #0,Strst ; Strst must be valid as a long + ENDC + MOVINT (_strstart,pc),Strst + move.w (lookahead,pc),Look + BASEPTR _window,Window + bsr.s fill_window + MOVINT Strst,_strstart + move.w Look,lookahead + movem.l (sp)+,Look/Strst + rts + +; strstart, lookahead, and window must be cached in Strst, Look, and Window: +fill_window: ; asm-callable entry point + movem.l FWREGS,-(sp) + move.w (eofile,pc),d0 ; we put this up here for speed + bne fwdone + and.l #$FFFF,Look ; make sure Look is valid as long +fw_refill: + move.l (_window_size,pc),More ; <= 64K + sub.l Look,More + sub.l Strst,More ; Strst is already valid as long + cmp.w #EOF,More + bne.s notboundary + subq.w #1,More + bra checkend + +notboundary: + move.w (sliding,pc),d0 + beq checkend + cmp.w #WSIZE+MAX_DIST,Strst + blo checkend + IF (32768-WSIZE)>0 + lea WSIZE(Window),WindTop ; WindTop is aligned when Window is + ELSE + move.l Window,WindTop + add.l #WSIZE,WindTop + ENDC + move.l Window,d0 + and.w #3,d0 + beq.s isaligned + subq.w #1,d0 +align: move.b (WindTop)+,(Window)+ ; copy up to a longword boundary + dbra d0,align +isaligned: +; This is faster than a simple move.l (WindTop)+,(Window)+ / dbra loop: + move.w #(WSIZE-1)/(4*SPCOUNT),SlidIx +slide: movem.l (WindTop)+,SPAREGS ; copy, 32 bytes at a time! + movem.l SPAREGS,(Window) ; a slight overshoot doesn't matter. + lea 4*SPCOUNT(Window),Window ; can't use (aN)+ as movem.l dest + dbra SlidIx,slide + BASEPTR _window,Window ; restore cached value + sub.w #WSIZE,match_start + sub.w #WSIZE,Strst + sub.l #WSIZE,_block_start + add.w #WSIZE,More + BASEPTR _head,a0 + move.w #HASH_SIZE-1,d0 +fixhead: + move.w (a0),d1 + sub.w #WSIZE,d1 + bpl.s headok + moveq #0,d1 +headok: move.w d1,(a0)+ + dbra d0,fixhead + BASEPTR _prev,a0 + move.w #WSIZE-1,d0 +fixprev: + move.w (a0),d1 + sub.w #WSIZE,d1 + bpl.s prevok + moveq #0,d1 +prevok: move.w d1,(a0)+ + dbra d0,fixprev + TRACE_C #'.' + + move _verbose+INTSIZE-2,d0 + beq checkend + movem.l d2/a2,-(sp) + xref _print_period + jsr _print_period + movem.l (sp)+,d2/a2 + +checkend: ; assert eofile is false + movem.l d2/a2,-(sp) + MOVINT More,-(sp) ; assert More's upper word is zero + move.l Strst,d0 + add.w Look,d0 + add.l Window,d0 + move.l d0,-(sp) + move.l _read_buf,a0 + jsr (a0) ; refill the upper part of the window + addq #4+INTSIZE,sp + movem.l (sp)+,d2/a2 + tst.w d0 + beq.s iseof + cmp.w #EOF,d0 + beq.s iseof + add.w d0,Look + cmp.w #MIN_LOOKAHEAD,Look + blo fw_refill ; eofile is still false + + bra.s fwdone +iseof: move.w #1,eofile +fwdone: movem.l (sp)+,FWREGS + rts + + +; ========================================================================= +; void lm_free(void) frees dynamic arrays in the DYN_ALLOC version. + +;;; xdef _lm_free ; the entry point + +_lm_free: + IFDEF DYN_ALLOC + move.l _window,d0 + beq.s lf_no_window + movem.l d2/a2,-(sp) + move.l d0,-(sp) + jsr _free + addq #4,sp + movem.l (sp)+,d2/a2 + clr.l _window +lf_no_window: + move.l _prev,d0 + beq.s lf_no_prev + movem.l d2/a2,-(sp) + move.l d0,-(sp) + jsr _free + move.l _head,(sp) ; reuse the same stack arg slot + jsr _free + addq #4,sp + movem.l (sp)+,d2/a2 + clr.l _prev + clr.l _head +lf_no_prev: + ENDC + rts + +; ============================================================================ +; void lm_init(int pack_level, unsigned short *flags) allocates dynamic arrays +; if any, and initializes all variables so that deflate() is ready to go. + +;;; xdef _lm_init ; the entry point + +Level reg d2 +;Window reg a2 ; as in deflate() + +_lm_init: + MOVINT 4(sp),d0 + move.l 4+INTSIZE(sp),a0 + move.w d0,Level + cmp.w #1,Level + blt.s levelerr + bgt.s try9 + bset.b #B_FAST,1(a0) +try9: cmp.w #9,Level + bgt.s levelerr + blt.s levelok + bset.b #B_SLOW,1(a0) + bra.s levelok +levelerr: + pea (level_message,pc) + jsr _error ; never returns +levelok: + clr.w sliding + move.l (_window_size,pc),d0 + bne.s gotawindowsize + move.w #1,sliding + move.l #2*WSIZE,_window_size +gotawindowsize: + + BASEPTR _window,Window + IFDEF DYN_ALLOC + move.l Window,d0 ; fake tst.l + bne.s gotsomewind + CAL_SH WSIZE + move.l d0,Window + move.l d0,_window + bne.s gotsomewind + pea (window_message,pc) + bra error +gotsomewind: + tst.l _prev + bne.s gotsomehead + CAL_SH WSIZE + move.l d0,_prev + beq.s nohead + CAL_SH HASH_SIZE + move.l d0,_head + bne.s gotfreshhead ; newly calloc'd memory is zeroed +nohead: pea (hash_message,pc) +error: MOVINT #ZE_MEM,-(sp) + jsr _ziperr ; never returns +gotsomehead: + ENDC ; DYN_ALLOC + + move.w #(HASH_SIZE/2)-1,d0 ; two shortwords per loop + BASEPTR _head,a0 +wipeh: clr.l (a0)+ + dbra d0,wipeh +gotfreshhead: + move.l Level,d0 + IFEQ Sizeof_config-8 + asl.l #3,d0 + ELSE + mulu #Sizeof_config,d0 + ENDC + lea (config_table,pc),a0 + add.l d0,a0 + move.w Max_lazy(a0),max_lazy_match + move.w Good_length(a0),good_match + move.w Nice_length(a0),nice_match + move.w Max_chain(a0),max_chain_len + CLRINT _strstart + clr.l _block_start + bsr match_init + + clr.w eofile + movem.l d2/a2,-(sp) + MOVINT #WSIZE,-(sp) ; We read only 32K because lookahead is short + move.l Window,-(sp) ; even when int size is long, as if deflate.c + move.l _read_buf,a0 ; were compiled with MAXSEG_64K defined. + jsr (a0) + addq #4+INTSIZE,sp + movem.l (sp)+,d2/a2 + move.w d0,lookahead + beq.s noread + cmp.w #EOF,d0 + bne.s irefill +noread: move.w #1,eofile + clr.w lookahead + bra.s init_done + +irefill: + move.w (lookahead,pc),d0 + cmp.w #MIN_LOOKAHEAD,d0 + bhs.s hashify + bsr _fill_window ; use the C-callable version +hashify: + clr.w ins_h + moveq #MIN_MATCH-2,d0 +hash1: move.b (Window)+,d1 + UP_HASH Level,d1 + dbra d0,hash1 + +init_done: + rts + +; strings for error messages: + IFDEF DYN_ALLOC +hash_message dc.b 'hash table allocation',0 +window_message dc.b 'window allocation',0 + ENDC +level_message dc.b 'bad pack level',0 + + end diff --git a/human68k/human68k.c b/human68k/human68k.c new file mode 100644 index 0000000..be47b57 --- /dev/null +++ b/human68k/human68k.c @@ -0,0 +1,371 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#include "zip.h" + +#include +#include +#include +#ifndef UTIL +#include +#endif + +#define MATCH shmatch + +#define PAD 0 + + +#ifndef UTIL + +/* Library functions not in (most) header files */ + +int utime OF((char *, ztimbuf *)); + +/* Local functions */ +local char *readd OF((DIR *)); + +local char *readd(DIR* d) +{ + struct dirent* e = readdir(d); + + return e == NULL ? NULL : e->d_name; +} + +int wild(char* w) +{ + struct _filbuf inf; + /* convert FNAMX to malloc - 11/08/04 EG */ + char *name; + char *p; + + if (strcmp(w, "-") == 0) /* if compressing stdin */ + return newname(w, 0, 0); + if ((name = malloc(strlen(w) + 1)) == NULL) { + ZIPERR(ZE_MEM, "wild"); + } + strcpy(name, w); + _toslash(name); + + if ((p = strrchr(name, '/')) == NULL && (p = strrchr(name, ':')) == NULL) + p = name; + else + p++; + if (_dos_lfiles (&inf, w, 0xff) < 0) { + free(name); + return ZE_MISS; + } + do { + int r; + + strcpy(p, inf.name); + r = procname(name, 0); + if (r != ZE_OK) { + free(name); + return r; + } + } while (_dos_nfiles(&inf) >= 0); + free(name); + + return ZE_OK; +} + +int procname(n, caseflag) +char *n; /* name to process */ +int caseflag; /* true to force case-sensitive match */ +/* Process a name or sh expression to operate on (or exclude). Return + an error code in the ZE_ class. */ +{ + char *a; /* path and name for recursion */ + DIR *d; /* directory stream from opendir() */ + char *e; /* pointer to name from readd() */ + int m; /* matched flag */ + char *p; /* path for recursion */ + struct stat s; /* result of stat() */ + struct zlist far *z; /* steps through zfiles list */ + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0, caseflag); + else if (LSSTAT(n, &s)) + { + /* Not a file or directory--search for shell expression in zip file */ + p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */ + m = 1; + for (z = zfiles; z != NULL; z = z->nxt) { + if (MATCH(p, z->iname, caseflag)) + { + z->mark = pcount ? filter(z->zname, caseflag) : 1; + if (verbose) + fprintf(mesg, "zip diagnostic: %scluding %s\n", + z->mark ? "in" : "ex", z->name); + m = 0; + } + } + free((zvoid *)p); + return m ? ZE_MISS : ZE_OK; + } + + /* Live name--use if file, recurse if directory */ + _toslash(n); + if ((s.st_mode & S_IFDIR) == 0) + { + /* add or remove name of file */ + if ((m = newname(n, 0, caseflag)) != ZE_OK) + return m; + } else { + /* Add trailing / to the directory name */ + if ((p = malloc(strlen(n)+2)) == NULL) + return ZE_MEM; + if (strcmp(n, ".") == 0) { + *p = '\0'; /* avoid "./" prefix and do not create zip entry */ + } else { + strcpy(p, n); + a = p + strlen(p); + if (a[-1] != '/') + strcpy(a, "/"); + if (dirnames && (m = newname(p, 1, caseflag)) != ZE_OK) { + free((zvoid *)p); + return m; + } + } + /* recurse into directory */ + if (recurse && (d = opendir(n)) != NULL) + { + while ((e = readd(d)) != NULL) { + if (strcmp(e, ".") && strcmp(e, "..")) + { + if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL) + { + closedir(d); + free((zvoid *)p); + return ZE_MEM; + } + strcat(strcpy(a, p), e); + if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */ + { + if (m == ZE_MISS) + zipwarn("name not matched: ", a); + else + ziperr(m, a); + } + free((zvoid *)a); + } + } + closedir(d); + } + free((zvoid *)p); + } /* (s.st_mode & S_IFDIR) == 0) */ + return ZE_OK; +} + +char *ex2in(x, isdir, pdosflag) +char *x; /* external file name */ +int isdir; /* input: x is a directory */ +int *pdosflag; /* output: force MSDOS file attributes? */ +/* Convert the external file name to a zip file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *n; /* internal file name (malloc'ed) */ + char *t; /* shortened name */ + + /* Find starting point in name before doing malloc */ + t = (x[0] && x[1] == (char)':') ? x + 2 : x; + while (*t == (char)'/') + t++; + + /* Make changes, if any, to the copied name (leave original intact) */ + _toslash(t); + + if (!pathput) + t = last(t, '/'); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + + if (dosify) + msname(n); + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosify; + return n; +} + + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + return strcpy(x, n); +} + +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ + ztimbuf u; /* argument for utime() */ + + /* Convert DOS time to time_t format in u */ + u.actime = u.modtime = dos2unixtime(d); + + /* Set updated and accessed times of f */ + utime(f, &u); +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + /* convert FNMAX to malloc - 11/8/04 EG */ + char *name; + int len = strlen(f); + isstdin = !strcmp(f, "-"); + + if ((name = malloc(len + 1)) == NULL) { + ZIPERR(ZE_MEM, "filetime"); + } + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + + if (isstdin) { + if (fstat(fileno(stdin), &s) != 0) { + free(name); + error("fstat(stdin)"); + } + } else if (LSSTAT(name, &s) != 0) { + /* Accept about any file kind including directories + * (stored with trailing / with -r option) + */ + free(name); + return 0; + } + + if (a != NULL) { + int atr = _dos_chmod(name, -1); + + if (atr < 0) + atr = 0x20; + *a = ((ulg)s.st_mode << 16) | (isstdin ? 0L : (ulg)atr); + } + free(name); + if (n != NULL) + *n = S_ISVOL(s.st_mode) ? -2L : S_ISREG(s.st_mode) ? s.st_size : -1L; + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_ctime; + } + + return unix2dostime(&s.st_mtime); +} + +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; + /* create extra field and change z->att if desired */ +{ +#ifdef USE_EF_UT_TIME + if ((z->extra = (char *)malloc(EB_HEADSIZE+EB_UT_LEN(1))) == NULL) + return ZE_MEM; + + z->extra[0] = 'U'; + z->extra[1] = 'T'; + z->extra[2] = EB_UT_LEN(1); /* length of data part of e.f. */ + z->extra[3] = 0; + z->extra[4] = EB_UT_FL_MTIME; + z->extra[5] = (char)(z_utim->mtime); + z->extra[6] = (char)(z_utim->mtime >> 8); + z->extra[7] = (char)(z_utim->mtime >> 16); + z->extra[8] = (char)(z_utim->mtime >> 24); + + z->cext = z->ext = (EB_HEADSIZE+EB_UT_LEN(1)); + z->cextra = z->extra; + + return ZE_OK; +#else /* !USE_EF_UT_TIME */ + return (int)(z-z); +#endif /* ?USE_EF_UT_TIME */ +} + +int deletedir(d) +char *d; /* directory to delete */ +/* Delete the directory *d if it is empty, do nothing otherwise. + Return the result of rmdir(), delete(), or system(). + For VMS, d must be in format [x.y]z.dir;1 (not [x.y.z]). + */ +{ + return rmdir(d); +} + +void print_period(void) +{ + fputc('.', stderr); +} + +#endif /* !UTIL */ + + +/******************************/ +/* Function version_local() */ +/******************************/ + +void version_local() +{ + static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n"; +#if 0 + char buf[40]; +#endif + + printf(CompiledWith, + +#ifdef __GNUC__ + "gcc ", __VERSION__, +#else +# if 0 + "cc ", (sprintf(buf, " version %d", _RELEASE), buf), +# else + "unknown compiler", "", +# endif +#endif + + "Human68k", +#ifdef __MC68020__ + " (X68030)", +#else + " (X680x0)", +#endif + +#ifdef __DATE__ + " on ", __DATE__ +#else + "", "" +#endif + ); + +} /* end function version_local() */ diff --git a/human68k/match.s b/human68k/match.s new file mode 100644 index 0000000..4e6bc1c --- /dev/null +++ b/human68k/match.s @@ -0,0 +1,163 @@ +*=========================================================================== +* Copyright (c) 1990-1999 Info-ZIP. All rights reserved. +* +* See the accompanying file LICENSE, version 1999-Oct-05 or later +* (the contents of which are also included in zip.h) for terms of use. +* If, for some reason, both of these files are missing, the Info-ZIP license +* also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*=========================================================================== +* +* match.s -- optional optimized asm version of longest match in deflate.c +* Written by Jean-loup Gailly +* +* Adapted for X68000 by NIIMI Satoshi +* Adapted for the Amiga by Carsten Steger +* using the code in match.S. +* The major change in this code consists of removing all unaligned +* word accesses, because they cause 68000-based machines to crash. +* For maximum speed, UNALIGNED_OK can be defined. +* The program will then only run on 68020-based machines, though. + + +Cur_Match reg d0 ; Must be in d0! +Best_Len reg d1 +Loop_Counter reg d2 +Scan_Start reg d3 +Scan_End reg d4 +Limit reg d5 +Chain_Length reg d6 +Scan_Test reg d7 +Scan reg a0 +Match reg a1 +Prev_Address reg a2 +Scan_Ini reg a3 +Match_Ini reg a4 + +MAX_MATCH equ 258 +MIN_MATCH equ 3 +WSIZE equ 32768 +MAX_DIST equ WSIZE-MAX_MATCH-MIN_MATCH-1 + + + .xref _max_chain_length + .xref _prev_length + .xref _prev + .xref _window + .xref _strstart + .xref _good_match + .xref _match_start + .xref _nice_match + + + .xdef _match_init + .xdef _longest_match + + .text + .even + + +_match_init: + rts + + +_longest_match: + move.l 4(sp),Cur_Match +.ifdef UNALIGNED_OK + movem.l d2-d6/a2-a4,-(sp) +.else + movem.l d2-d7/a2-a4,-(sp) +.endif + move.l _max_chain_length,Chain_Length + move.l _prev_length,Best_Len + lea _prev,Prev_Address + lea _window+MIN_MATCH,Match_Ini + move.l _strstart,Limit + move.l Match_Ini,Scan_Ini + add.l Limit,Scan_Ini + subi.w #MAX_DIST,Limit + bhi.b limit_ok + moveq #0,Limit +limit_ok: + cmp.l _good_match,Best_Len + bcs.b length_ok + lsr.l #2,Chain_Length +length_ok: + subq.l #1,Chain_Length + +.ifdef UNALIGNED_OK + move.w -MIN_MATCH(Scan_Ini),Scan_Start + move.w -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End +.else + move.b -MIN_MATCH(Scan_Ini),Scan_Start + lsl.w #8,Scan_Start + move.b -MIN_MATCH+1(Scan_Ini),Scan_Start + move.b -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End + lsl.w #8,Scan_End + move.b -MIN_MATCH(Scan_Ini,Best_Len.w),Scan_End +.endif + + bra.b do_scan + +long_loop: + +.ifdef UNALIGNED_OK + move.w -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End +.else + move.b -MIN_MATCH-1(Scan_Ini,Best_Len.w),Scan_End + lsl.w #8,Scan_End + move.b -MIN_MATCH(Scan_Ini,Best_Len.w),Scan_End +.endif + +short_loop: + lsl.w #1,Cur_Match + move.w 0(Prev_Address,Cur_Match.l),Cur_Match + cmp.w Limit,Cur_Match + dbls Chain_Length,do_scan + bra.b return + +do_scan: + move.l Match_Ini,Match + add.l Cur_Match,Match + +.ifdef UNALIGNED_OK + cmp.w -MIN_MATCH-1(Match,Best_Len.w),Scan_End + bne.b short_loop + cmp.w -MIN_MATCH(Match),Scan_Start + bne.b short_loop +.else + move.b -MIN_MATCH-1(Match,Best_Len.w),Scan_Test + lsl.w #8,Scan_Test + move.b -MIN_MATCH(Match,Best_Len.w),Scan_Test + cmp.w Scan_Test,Scan_End + bne.b short_loop + move.b -MIN_MATCH(Match),Scan_Test + lsl.w #8,Scan_Test + move.b -MIN_MATCH+1(Match),Scan_Test + cmp.w Scan_Test,Scan_Start + bne.b short_loop +.endif + + move.w #(MAX_MATCH-MIN_MATCH),Loop_Counter + move.l Scan_Ini,Scan +scan_loop: + cmpm.b (Match)+,(Scan)+ + dbne Loop_Counter,scan_loop + + sub.l Scan_Ini,Scan + addq.l #(MIN_MATCH-1),Scan + cmp.l Best_Len,Scan + bls.b short_loop + move.l Scan,Best_Len + move.l Cur_Match,_match_start + cmp.l _nice_match,Best_Len + bcs.b long_loop +return: + move.l Best_Len,d0 +.ifdef UNALIGNED_OK + movem.l (sp)+,d2-d6/a2-a4 +.else + movem.l (sp)+,d2-d7/a2-a4 +.endif + rts + + end diff --git a/human68k/osdep.h b/human68k/osdep.h new file mode 100644 index 0000000..088a9ac --- /dev/null +++ b/human68k/osdep.h @@ -0,0 +1,28 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#include +#include +#include + +#ifdef ZCRYPT_INTERNAL +# include /* getpid() declaration for srand seed */ +#endif + +#define USE_CASE_MAP + +#define ROUNDED_TIME(time) (((time) + 1) & (~1)) + +#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \ + procname(n, 1)) + +#ifdef HAVE_MBCTYPE_H +# include +#else +# define ismbblead(c) (0x80 <= (c) && ((c) < 0xa0 || 0xe0 <= (c))) +#endif diff --git a/human68k/zipup.h b/human68k/zipup.h new file mode 100644 index 0000000..592cff8 --- /dev/null +++ b/human68k/zipup.h @@ -0,0 +1,16 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#define fhow (O_RDONLY|O_BINARY) +#define fbad (-1) +typedef int ftype; +#define zopen(n,p) open(n,p) +#define zread(f,b,n) read(f,b,n) +#define zclose(f) close(f) +#define zerr(f) (k == (extent)(-1L)) +#define zstdin 0 diff --git a/macos/Contents b/macos/Contents new file mode 100644 index 0000000..3aec069 --- /dev/null +++ b/macos/Contents @@ -0,0 +1,63 @@ +Contents of the "macos" sub-archive for Zip 2.3 and later: + + +MacOS: + + Contents this file + readme.1st Instruction to unpack mac specific files + README.TXT Dirk Haase's infos on updated MacIntosh ports of Zip/UnZip + HISTORY.TXT Dirk Haase's MacOS specific ChangeLog + + zipup.h MacOS + osdep.h MacOS specific configuration and declarations + + ZipLib.h used to build a static library, global to the project + ZipSx.h used to build a standalone App with MW Sioux, global + to the project + ZpPrj.hqx Metrowerks CodeWarrior pro3 project file (BinHex) + + + source/ subdirectory containing all sources: + a) Zip specific code + extrafld.c contains all code related to the mac extra field + extrafld.h + macglob.h + macopen.c replaces fopen() and open() + macopen.h + macos.c Macintosh-specific routines for use with Info-ZIP's Zip + MatWild.c Pattern matching function + recurse.c Functions to go through the directories + recurse.h + unixlike.c This file provides a unix like file-stat routine + unixlike.h + VolWarn.h contains the warning message, about volumes with the + same name + zip_rc.hqx resource file for Macintosh unzip (BinHex) + + + b) general utilities shared between Zip and UnZip + charmap.h character mapping tables ISO 8859-1 <--> MacRoman + helpers.c some helper functions + helpers.h + macstuff.c Mac filemanager routines copied from MoreFiles 1.4.8 + macstuff.h + mactime.c replacement for broken Metrowerks RTL time functions + pathname.c functions for handling MacOS HFS path- /filenames + pathname.h + +The new ZpPrj.hqx project file should be "un-BinHex'ed" into ZpPrj, +which builds the following targets: + - Zip Lib (68K) -> static library 68k + - Zip Lib (PPC) -> static library PPC + - Zip Sioux (68K) -> MW Sioux standalone App, good for debugging + - Zip Sioux (PPC) -> MW Sioux standalone App, good for debugging + + +The resource files and the compiler project files are in BinHex form because +they contain Macintosh resource forks. The resource info cannot be +maintained when handling (e.g. repacking) the master source collection on +non-Macintosh systems. The BinHex form is the traditional way for +transferring such files via non-Macintosh systems. +It's also the safest since it uses only printable characters. The ".hqx" +files must be converted with StuffitExpander or BinHex 4.0 (or equivalent) +on a Macintosh system before using them. diff --git a/macos/HISTORY.TXT b/macos/HISTORY.TXT new file mode 100644 index 0000000..3a14a02 --- /dev/null +++ b/macos/HISTORY.TXT @@ -0,0 +1,600 @@ +A free Macintosh Port of Info-ZIP's +Zip and UnZip +By Dirk Haase, d_haase@sitec.net +Home page: www.sitec.net/maczip +Mirror page: +www.haase-online.de/dirk/maczip +================================ + + + + + +Release MacZip ver1.07 beta 1 +22. Februray 2001 +----------------- + +1) CHG: {unzip} switch to latest final release + unzip 5.42 + +2) CHG: {zip} switch to latest beta release + zip 2.40a + + + + + +Release MacZip ver1.06 final +22. Februray 2001 +----------------- + +1) CHG: {unzip} switch to latest final release + unzip 5.42 + +2) CHG: switch to latest release of Apples + Universal Interfaces 3.3.2 + +3) CHG: switch to latest release of + Morefiles 1.5 + + + + +Release MacZip ver1.06 beta 2 +02. August 2000 +--------------- + +1) CHG: {unzip} switch to latest beta release + unzip 5.42d + + + + + +Release MacZip ver1.06 beta 1 +27. July 2000 +------------- + +1) CHG: {zip} switch to latest beta release + unzip 2.30 + +2) CHG: {unzip} switch to latest beta release + unzip 5.42c + + + + + +Release MacZip ver1.05 final +27. July 2000 +------------- + +1) CHG: {unzip} switch to latest final release + unzip 5.41 + +2) FIX: {unzip} Fixed "unique unzip folder" foldername handling + +3) FIX: {unzip} added prototype crc32() in macbin3.c + +4) CHG: {unzip/zip} added exported Codewarrior project-file in xml-format + +5) ADD: {unzip} added extra-field recognition for Mac SmartZip in + zipinfo.c and unzpriv.h. + + + + + +Release MacZip ver1.04 final +25. January 2000 +---------------- + + +Final release of MacZip. All parts now +in final release state !! + +1) Switch to MW Codewarrior pro 5.3 + +2) CHG: {zip} switch (back) to latest final release + unzip 2.30 + +3) CHG: {unzip} switch (back) to latest final release + unzip 5.40 + + + + +Release MacZip ver1.04 beta 3 +05. October 1999 +---------------- + +1) CHG: {zip} switch to latest source level + unzip 2.30o beta release + +2) CHG: {unzip} switch to latest source level + unzip 5.41c beta release + +3) ADD: {console} added menu to print the license + + + + +Release MacZip ver1.04 beta 2 +02. June 1999 +-------------- + +1) FIX: {unzip} added one more criteria to make the recognition + of macbinary more save. + +2) FIX: {unzip} sometimes, archive entries without any extra field + caused problems; the default setting of the extra field + was not set back to 'unknown' properly. + +3) FIX: {zip} Archive filename with invalid characters like '/' gets + renamed. However, I do not check the complete path - needs + some more work here. + +4) FIX: {zip} Filename match was case sensitive. + +6) CHG: {zip} switch to latest source level + unzip 2.30m beta release + +7) CHG: {unzip} switch to latest source level + unzip 5.41b beta release + +8) FIX: {zip/unzip 68k only) I have found a wrong compiler setting + for the 68k version. Because of this wrong setting the 68k + version crashed. + + + + +Release MacZip ver1.04 beta 1 +30. March 1999 +-------------- + +1) CHG: {unzip) switch to latest source level + unzip 5.41a beta release + +2) ADD: {all} Added message logging support for Syslogd + by Brian Bergstrand. Syslogd can be found at + http://www.classicalguitar.net/brian/apps/syslogd/ + This feature is 'under construction'. + +3) FIX: {all} many small fixes and code cleanups + + + + +Release MacZip ver1.03 +27. March 1999 +-------------- + +1) CHG: {console} Like Stuffit Expander MacZip quits automatically when + used with drag'n drop or as Helper App (Web-Browser). + +2) CHG: {console} Since Macintosh users are used to be guided by their + software in order not to do something stupid, I added a check + to post an extra warning if the options -m and data fork only + are both checked. + This behavior can be disabled: See Applescript example and + "maczip.env". + +3) CHG: {zip} switch from immediate deletion to moving to the + trash. Immediate deletion is now an option in "maczip.env". + +4) CHG: {zip} enhanced progress display. + +5) CHG: {zip) switch to latest source level + zip 2.3l beta release + +6) CHG: {unzip} The zip archive contains file names greater than + 31 characters. When MacZip tries to unzip the file, the + FSpCreate command fails because the filename length is to + long. MacZip correct this problem by trying to truncate + the file names to the 31 character limit. + +7) FIX: {zip/console} A couple of minor fixes + +8) CHG: {zip} Switched file-globbing to the Info-ZIP version. + + + + +Release MacZip ver1.02 +14. February 1999 +----------------- + +1) CHG: {zip} Changed the rule of file inclusion if switch '-X' + is set. Following conditions are checked: + a) if length of resource-fork is equal zero *and* the + length of data-fork is equal zero include the file. + b) if length of resource-fork greater zero *and* the + length of data-fork is equal zero don't include the file. + c) if length of data-fork greater zero include the file. + +2) CHG: {Console} Some users are very confused by the buttons "START PATH" + and "ZIP ARCHIVE". Somehow, it wasn't clear what the intended + meaning was. I changed the buttons to more clear labels on + them like: "file or folder to compress" and "location of + compressed file" + +3) CHG: {Console} I changed the menu structure to be more intuitive. + +4) FIX: {Console} Found a nasty bug which sometimes caused crashes + when the Zip / Unzip Dialogbox was used. + +5) CHG: {Console} Handling of file dialog is now a bit more restricted: + e.g: it's not possible to select a file if you have to select + a folder. + + + + +Release MacZip ver1.01 +30. January 1999 +---------------------- + +1) CHG: {console} The use of the "Current App" mechanism was clumsy + and forces the user into the Zip or Unzip modes. This kind + of modality is not so good for the command line. It's now + neccessary to enter zip or unzip to choose the action. + +2) FIX: {console} When Applescript sends quit to MacZip the script + that is running shows a spinning cursor and MacZip + does not quit. + +3) FIX: {console} MacZip gots accidentally the wrong creator code + (from BBedit) + + + + +Final Release MacZip ver1.0 +--------------------------- + +Released 21. January 1999 + + + + +9. Beta release 06.December.1998 +--------------------------------- + +1) CHG: {console} The checkbox of Filedialog (for extract path and file path) + "Show all files" is now selected by default. + +2) CHG: {unzip/standalone} changed prototypes of mac[f]printf() to return + an int number (better ANSI conformance); + +3) FIX: {unzip} repaired "stdout/stderr" mode of macwrite(). So func + MacMessagePrnt() is now obsolete and removed. + +4) ADD: {zip/unzip} Compressed Mac3 extra-fields are now supported + (Thanks to Christian Spieler) + +5) ADD: {unzip} Extraction of ZipIt archive are now supported. This support + is not complete: Filenames are correct but folder names are only + restored with the public directory names. + +6) ADD: {zip/unzip} Improved documentation. + +7) FIX: {unzip} Function isZipfile() is completely rewritten. + +8) CHG: {zip/unzip) switch to latest source level + zip 2.3i beta and unzip 5.4 final release + +9) ADD: Applescript event "do_cmd". + +Unless there are big bugs found, this release will be the last +beta release. The final release will come out in January 1999. + + + + +8. Beta release 20.November.1998 +--------------------------------- + +1) CHG: {zip/unzip) switch to latest source level + zip 2.3h beta and unzip 5.4 final release + +2) ADD: {zip} Zip finds "namelocked" files also, if switch "-S" + is set. + +3) FIX: {unzip} Function isZipfile() fails if the zip archive + has a comment. + +4) CHG: {zip} added some small speed improvements to pattern matching and + isZipFile() function. + +5) FIX: {unzip} Display of comments is fixed. + UzpMessagePrnt() is replaced by MacMessagePrnt(). I do not care + about ansi-bombs. I'm not sure, so this fix may be changed later. + +6) RMV: {unzip} Buildin More capability is removed since it's already built + into the GUI-App. + + + +7. Beta release 09.November.1998 +--------------------------------- + +1) CHG: {all} switched to Metrowerks Codewarrior Pro 4 + +2) FIX: {unzip} Display of comments stored in the zip-file is + now fixed + +3) FIX: {zip} Fixed display of the zip help-screen. + +4) CHG: {zip/unzip} Changed special dir 'Re$0urce.Fk' to 'XtraStuf.mac' + (see entry at 13.June.1998 item 3). I found it more descriptive for + users outside the mac-community. + +5) CHG: {all} switched to MoreFiles 1.4.9. + +6) CHG: {console} changed behaivor of the file open dialog: The select + button is now always enabled. + +7) ADD: {all} Environment variables are now supported. + Basically, it is possible to add timezone (= TZ environment variable) + support here, but it's not yet implemented. + See "MacZip.Env" for further info. + +8) RMV: {console} Targets "zip only" and "unzip only" are removed. + + + +6. Beta release 09.September.1998 +--------------------------------- + + +1) CHG: {Zip/Unzip} Metrowerks Standardlibrary time funktions are + rather broken and incomplete so I was forced to rewrite the + funktions: mktime(), localtime(), gmtime() and time(). + +2) ADD: {Console} Added Pause Funktion for screen output. + The Pause-Function is selfadjusting: Count of lines is depending + on the window size. + +3) CHG: Extra-Field layout is changed: All datas are now in little-endian + format (see appnote) + +4) ADD: {Console} Added an option to test the archive automatically + after zipping. This option is only via Zip-Dialogbox available + because it needs the unzip-module also. + +5) CHG: {Zip} code is now up to date with the latest beta 2.3f. + +6) ADD: {Console} Added (drag'n) drop support. Drop on the MacZip icon. + The following situations are supported: + 1. drop of one or more zipfiles (action = unzip) + each archive will be extracted in a separate folder + 2. drop of a folder (action = zip -r ) + The complete folder (inclusive sub-folders) + will be zipped + Not (yet) supported is currently: dropping more than one file + to compress. Workaround: Put all your files in one folder and + drop that folder on MacZip. + MacZip recognize zip-archives automatically. + + +5. Beta release 21.Aug.1998 +---------------------------- + + +1) ADD: {Console} Userinterface has now a Statusbar to show the + Progress. + +2) ADD: {Console} It's now possible to stop the run of Zip/Unzip + with the well known shortcut [Command] + [.] + +3) CHG: {Console} Improved user-entry routine. + +4) ADD: {Zip/Unzip} Crypt-code added. It's now possible to + encrypt/decrypt archives. + +5) RMV: {Unzip} Removed the warning of PKZip/Mac archive. + Unzip gets confused with the extra field of PKZip/Mac. So I assume + the extra field isn't compatible with Info-ZIP's definition. + +6) CHG: switched to Metrowerks Codewarrior Pro 3 + this includes: + - new Universal Interfaces 3.1 Headers + - improved codegeneration + +7) CHG: {Zip} code is now up to date with the latest beta 2.3e. + +8) CHG: {Unzip} changed function names wprintf, wgets .. to macprintf, macgets .. + to avoid naming conflict standart library. + +9) ADD: {Zip/Unzip} FXinfo, Mac-Pathname, file-dates and Finder-Comments + are now stored in the extra-field. Extra-field layout is + changed accordingly. Unzip uses now the filename stored in the + extra-field when unzipping. + +10) CHG: {Unzip} code is now up to date with the latest beta 5.33g. + +11) CHG: {Unzip} code is (again) up to date with the latest beta 5.33h. + +12) ADD: {Unzip} following switches were added: + -J [MacOS only] ignore mac extra info. All macintosh + info are not restored. Datafork and resource-fork + are restored separatly. + + -i [MacOS only] ignore filenames stored in mac extra + field. Use the most compatible filename stored in + the public field. + + -E [MacOS only] show mac extra field during restoring + +13) ADD: {Zip/Unzip} Charset MacRoman to ISO8859 Latin and vice versa + +14) RMV: {Zip} -N option removed. This MacZip crashes using this option. + I will fix it later. + + +I think I'm very close for a final release of "MacZip 1.0" :-) + + + +4. Beta release 27.June.1998 +---------------------------- + +26.June.1998 +------------ + +1) FIX: {Zip} extra field size value was wrong. + + + +25.June.1998 +------------ + +1) CHG: {Zip} code is now up to date with the latest beta 2.3d. + So both modules, zip & unzip, uses now latest beta. + +2) ADD: {Zip} added a UT extra-field for better compatibility. + +3) CHG: {Unzip} changed the code to find the mac extra-field. + Unzip has to look for a mac extra-field because + mac-archives has now two extra-fields (UT + M3). + +4) CHG: {Unzip} changed the method to move extra-field data to + the internal extra-structure. + Old method was just BlockMove of the ef_structptr to ef_memptr. + This method was dangerous because not all members of the + structure seamless aligned. There are may be some fill + bytes in the structure depending on the compiler setting. + +5) ADD: {Unzip} added a warning if unzipping a ZipIt/PKZip archive. + ZipIt/PKZip archives are usually additionally coded somehow. + InfoZip's Unzip will *not* decode the files. So extracted + files are may be not decoded. (see also 6. and 7.) + +6) ADD: ZipIt (the Shareware Tool) has now a new extra-field signature: + 0x2705. Found in "ZipIt 1.3.8". I added a new macro: EF_ZIPIT2 + +7) ADD: Added PKWare's extra-field signature: 0xCF77. + Found in "PKZIP v2.03". I added a new macro: EF_PKMAC + +8) ADD: {console} It's now possible to save all screen outputs + to the disk. + +9) RMV: {console} this is the first beta without expire-date. + + +16.June.1998 +------------ + +1) FIX: {Unzip/console} Extract path now defaults to current-dir if + no path is given. + +2> CHG: {Unzip} creates now a extract-folder by default. This behavior + differs to the commandline tool of Unzip on other platforms. + However, for a mac-user is this behavior more convenient. + + +3. Beta release 15.June.1998 +---------------------------- + +15.June.1998 +------------ + +1) CHG: {unzip/zip} I changed the layout of the extra field + to support more data. + + +14.June.1998 +------------ + +1) FIX: {Unzip} adjusted time_t value with an correct offset value. + +2) FIX: {Unzip} removed all unused code based on unfinished ideas by + former porter(s). + +3) CHG: use of shared code izshr 032. + +13.June.1998 +------------ + +1) FIX: {Unzip} Filenames are only converted when needed. When zipping + with the switch 'datafork only' the filenames are shorted which + was wrong. + +2) CHG: {Unzip} code is now up to date with the latest beta 5.33f. + +3) CHG: {Zip} Changed the naming rule of filenames from old Johnny Lee's + to my implementation. Johnny Lee's idea is based on change of the + filenames which cases several problems when unziping on a non mac + plattform. My idea is to add a special directory: 'Re$0urce.Fk'. + For the future: Zip will create archives according the new nameing + rule. However unzip will be compatible with old nameing rule. + See also 4. + +4} ADD: {Unzip} Added a new nameing rule for resource forks filename. + Resource forks are now stored in a special directory: 'Re$0urce.Fk'. + This naming rule make it easier to for other platforms to use + mac zip-files. + + + +11.June.1998 +------------ +1) FIX: {Zip} Internal file attribute is set to BINARY by default + when zipping resource forks otherwise Unzip will create + sometimes wrong resource-forks. + +2) CHG: {Unzip} code is now up to date with the latest beta 5.33e. + + + + +2. Beta release 10.June.1998 +-------------------------- + +1) FIX: {Unzip} Long pathname fix solved. Unzip is now able to extract + archives with path longer than 256 chars. + +2) CHG: {Unzip} removed all conversion from c-style string to + pascal-string (see fix 1) + +3) ADD: {Unzip} Finderinfo of folders are also restored. + +4) ADD: {Console} Added info about current path in the command-line box. + +5) FIX: {Console} Construction of the command-line of the unzip-dialog + box fixed. + + + +First beta release 06.June.1998 +----------------------------- + +no history. +Just to many code was neccessary to build the first mac-port. + + +Start of the port MacZip +February 1998 + + +-------------------------------------------------------------------------------- +Legende: + +FIX: fixes a bug +CHG: inform about changed items. +ADD: added feature +RMV: removed Item + +{Unzip} -> only related to the Unzip-module +{Zip} -> only related to the Zip-module + These are just libraries and are linked into the console-app. + +{Console} -> only related to the Userinterface (not SIOUX) + MacOS has no tool like a command-line. So it's neccessary + to write wrapper around the command-line tools. + + + + +Dirk Haase diff --git a/macos/README.TXT b/macos/README.TXT new file mode 100644 index 0000000..839658d --- /dev/null +++ b/macos/README.TXT @@ -0,0 +1,569 @@ +A free Macintosh Port of Info-ZIP's +Zip and UnZip +By Dirk Haase, d_haase@sitec.net +Home page: www.sitec.net/maczip +Mirror page: +www.haase-online.de/dirk/maczip +================================ + + + +Abstract: +--------- +MacZip is a cross-platform compatible tool that includes +both Zip (for compression) and UnZip (for extraction). + +Zip is a compression and file packaging utility for Unix, +VMS, MSDOS, OS/2, Windows 9x, Windows NT, Atari, Macintosh, +Amiga, Acorn RISC OS, and other systems. + +UnZip unpacks zip archives. The Zip and UnZip programs can +process archives produced by PKZIP, and PKZIP and PKUNZIP +can work with archives produced by zip. Zip version 2.2 is +compatible with PKZIP 2.04. + +If you are new to MacZip please read first the file +"ReadMe.1st". + + + +License: +-------- + Copyright (c) 1990-2001 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in unzip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html + + + +Requirements +------------ +MacZip requires at least System 7 and a Macintosh with a +minimum of a Motorola 68020 or PowerPC 601 processor. Other +configurations may work but it is not tested at all. + +The application is distributed as a fat binary with both +regular 68K and native PowerPC versions included. + + + +Installation +------------ +Move the executable(s) somewhere--for example, drag it (or +them) to your Applications folder. For easy access, make an +alias in the Launcher Control Panel or directly on your +desktop. The GUI is very simple. It was not my intention to +make a full-blown GUI, however I think it is comfortable +enough to use it as regular tool. + +This port supports also Apple-event. So you can install it +in your WWW-Browser as a helper app. + +For more Info about the contents of this package, take a +look into the "macos/Contents" (or :macos:Contents) file. +Some notes on how to rebuild the Macintosh applications can +be found in INSTALL. + + + +Usage: +------ + +Basically there are four ways to start MacZip: + +a) Drag'n Drop +b) using the Dialog box (Menu: File -> Zip/Unzip): + +Please read the file "ReadMe.1st" +for the description of the items a and b. + +c) Using the Command line (Menu: File->Command Line): + The Zip & UnZip tools are command line tools. So the + behavior is exactly the same like the Zip & UnZip tools on + Unix or Windows/DOS. This means, if you want to zip some + files, you have to write a command line like this: "zip + [switches] path_to_zip_archive path_to_files_folders" + + - Go to "File", select "Command Line" and the + "MacZip Entry box" Dialog Box appears. + + An example: + + a: your zip may be created at + Macintosh HD:applications:archive.zip + + b: your files may be found at + Macintosh HD:somewhere:my_folder_to_archive:* + + Note: At the end of the path there must be a filename or + a wild card ! + (see Footnotes: 1 wild card, 2 Mac path names) + + So the command line should look like (one line!): + + zip "Macintosh HD:applications:archive.zip" "Macintosh HD:somewhere:my_folder_to_archive:*" + + - Click on "Enter" to start the task. + + Since you can not set a default folder you have to enter + always a full qualified path names. Full-qualified path + names are path names including the Volume name ! (see + Footnote: 2 Mac path names) + + + +d) Using Applescript: + +There is only one additional event defined: "do_cmd". You +can enter every valid command line. The first word must be +"zip" or "unzip" to select the action (compress or +extraction). + +See sample Applescript: + + tell application "MacZip (PPC)" + activate + with timeout of 90000 seconds + do_cmd "zip -rjjN Volume:archive \"My Volume:*\" " + end timeout + end tell + +This script opens MacZip, brings it to the foreground on the +Mac, starts the zip action with the command line: zip -rjjN +Volume:archive "My Volume:*" . + + +A short introduction is also available online: +http://www.sitec.net/maczip/How-To-Do/ + +It's possible to stop the run of Zip/Unzip with the well +known shortcut [Command] + [.]. + + +--------------------------------------------------------------------------- + +There are some Mac-specific switches available. +Zip Module: + -df [MacOS] Include only data-fork of files zipped into + the archive. Good for exporting files to foreign + operating-systems. Resource-forks will be ignored + at all. + + -jj [MacOS] record Fullpath (+ Volname). The complete + path including volume will be stored. By default + the relative path will be stored. + + -S [MSDOS, OS/2, WIN32 and ATARI] Include system and + hidden files. + [MacOS] Includes finder invisible files, which are + ignored otherwise. + +Unzip Module: + -E [MacOS only] display contents of MacOS extra field + during restore operation. + + -i [MacOS only] ignore filenames stored in MacOS extra + fields. Instead, the most compatible filename + stored in the generic part of the entry's header is + used. + + -J [MacOS only] ignore MacOS extra fields. All Macin- + tosh specific info is skipped. Data-fork and + resource-fork are restored as separate files. + + +Select [File]->[Get Help on Zip/Unzip] for a complete list +of switches. + + + +Limitations / Problems: +----------------------- + + - Aliases are not supported. I tried, but I got broken + aliases. This port will silently ignore all aliases. + It's on my to-do list for future releases. + + - Zip needs much memory to compress many files: You may need + to increase the 'Preferred Size' in 'Get Info'. Values of 12 + Megabytes or more are possible + + - Unzip needs about 500 Kbytes of memory to unzip no matter + how many files were compressed and expanded. + + - and finally one big macintosh-related problem: + This port has one weak point: It's based on path names. + As you may be already know: Path names are not unique on a Mac ! + The main reason is that an attempt to implement support exact + saving of the MacOS specific internal file structures would + require a throughout rewrite of major parts of shared code, + probably sacrifying compatibility with other systems. I have + no solution at the moment. The port will just warn you if you + try zip from / to a volume which has a duplicate name. + MacZip has problems to find the archive or the files. My + (Big) recommendation: Name all your volumes with a unique + name and MacZip will run without any problem. + + +Known Bugs: + + - crypted files in a zip archive are sometimes corrupt: + I get an error message: invalid compressed data to inflate. + Appearance of this error is purely be chance: I did a small + test: Unzipping an archive containing 3589 files 56 files + fails to unzip, so about 1.5%. Root cause is completely + unclear to me :( + +I strongly recommend to test your archive (e.g. unzip -t archive). + + + + + +Zip Programs / Macintosh Extra-Data: +----------------------------------------- +A brief overview: +Currently, as far as I know, there are 6 Zip programs +available for the Macintosh platform. These programs build +(of course) different variants of Zip files: + + - Info-ZIP's first Port of Zip. Ported by Johnny Lee + This port is rather outdated and no longer supported (since 1992). + 68K only. Only minimal Mac-info is stored + (Creator/Type, Finder attributes). Creator/Type: '????' / '????' + Until year 1998, only UnZip 5.32 survived. + + - ZipIt by Tom Brown. This is Shareware and still supported I think. + ZipIt has a nice GUI, but I found it can't handle large Zip files + quite well. ZipIt compresses Macintosh files using the Mac Binary + format. So, transferring files to other platforms is not so easy. + Only minimal Mac-info is stored (Creator/Type, Finder attributes). + Mac filenames are changed to a most compatible filename. + Creator/Type: 'ZIP ' / 'ZIP ' + + - PKZIP/mac v2.03/210d. This is Shareware. + This Zip implementation for the Mac can be found on ASI's web site + (http://www.asizip.com/products/products.htm). The name of this + program is misleading, it is NOT a product from PKWARE. ASI's last + release version is v2.03, and they also offer a newer beta version + PKZIP/mac 210d. But even the Beta version is rather outdated (1995). + Only minimal Mac-info is stored (Creator/Type, Finder attributes). + The Zipfile format looks like incompatible to other platforms. + (More details about the compatibility issue can be found in + proginfo/3rdparty.bug!). Type: 'PKz1' + Mac filenames are restored without any change. + + - Aladdin DropZip 1999, This is Shareware. Aladdin chose + the format of ZipIt. Therefore, it has the some drawbacks + like ZipIt. + Creator/Type: 'SITx' / 'ZIP ' + + - SmartZip 1.0 1999 - by Marco Bambini Vampire Software. + This is Shareware. SmartZip compresses Macintosh files using the + Mac Binary. Therefore, it has the same drawbacks like ZipIt. + Creator/Type: 'dZIP' / 'ZIP ' + +and finally: + - Info-ZIP's latest Port of Zip. MacZip 1.0. Ported by me :-) + It is supported (of course) and up to date. Full set of macintosh + info is stored: Creator/Type, Finder attributes, Finder comments, + MacOS 8.0 Folder settings, Icon/Folder Positions ... + Mac filenames are restored without any change. + Creator/Type: 'IZip' / 'ZIP ' + + +Compatibility of my port; Extraction: + - Archives from Info-ZIP's first port (by Johnny Lee) are + still compatible. + - Extraction of ZipIt archives is supported. This support + is not complete: Filenames are correct but Directory names + are sometimes mangled to a DOS compatible form. Segmented + archives are not supported. + - PKZiP/mac archive files are extracted without resource-forks + and without any Finder info. I have no information about + that zip format. + +Compatibility of my port; Compression: + - My port supports only the new Info-ZIP format (introduced + with this port). Therefore archives created by MacZip 1.0 + (March 1999) must be extracted with this version or later + releases of Info-ZIP's UnZip to restore the complete set of + Macintosh attributes. + +Note: This port is complete unrelated to the shareware ZipIt. +Even more, handling of special Macintosh attributes is +incompatible with ZipIt. This port (MacZip) may be used to +extract archives created by ZipIt, but make sure that you +get the result as you expected. + + + +Macintosh Files; File Forks: +---------------------------- + +All Macintosh files comprise two forks, known as the data +fork and the resource fork. Unlike the bytes stored in the +resource fork, the bytes in the data fork do not have to +exhibit any particular internal structure. The application +is responsible for interpreting the bytes in the data fork +in whatever manner is appropriate. The bytes in the resource +fork usually have a defined internal structure and contain +data object like menus, dialog boxes, icons and pictures. +Although all Macintosh files contain both a data fork and a +resource fork, one or both of these forks may be empty. + +MacZip stores data-forks and resource-forks separately. The +Zipfile format does not allow to store two archive entries +using exactly the same name. My solution is to modify the +Path name of the resource-fork. All resource-fork names are +prepended with a leading special directory named +"XtraStuf.mac". So, when extracting on a Mac, you should +never see this directory "XtraStuf.mac" on your *disk*. + +On all foreign systems that support directories in filenames +(e.g.: OS/2, Unix, DOS/Windows, VMS) you will get a +directory "XtraStuf.mac" when extracting MacZip archives. +You can delete the complete directory "XtraStuf.mac" since +Mac resources do not make much sense outside the MacOS +world. + + + +Text encoding; Charsets of the Filenames: +----------------------------------------- + +The following information is only important if you plan to +transfer archives across different platforms/language systems: + +A typical Zip archive does not support different charsets. +All filenames stored in the public area (= accessible by +foreign systems other than MacOS) must be coded in the +charset ISO-8859-1 (CP1252 in the Microsoft Windows world) +or CP850 (DOSLatin1). The latter should only be used by Zip +programs that mark the archive entries as "created under +DOS". Apart from Macs, the commonly used platforms either +support ISO-8859-1 directly, or are compatible with it. To +achieve maximum compatibility, MacZip convert filenames from +the Mac OS Roman character set to ISO-8859-1 and vice versa. +But not every char of the charset MacRoman has their +equivalent in ISO-8859-1. To make the mapping in most cases +possible, I chose most similar chars or at least the MIDDLE +DOT. + +Mac OS Roman character set is used for at least the +following Mac OS localizations: U.S., British, Canadian +French, French, Swiss French, German, Swiss German, Italian, +Swiss Italian, Dutch, Swedish, Norwegian, Danish, Finnish, +Spanish, Catalan, Portuguese, Brazilian, and the default +International system. + +In all Mac OS encodings, character codes 0x00-0x7F are +identical to ASCII, except that + - in Mac OS Japanese, yen sign replaces reverse solidus + - in Mac OS Arabic, Farsi, and Hebrew, some of the + punctuation in this range is treated as having strong + left-right directionality, although the corresponding + Unicode characters have neutral directionality +So, for best compatibility, confine filenames to the standard +7-bit ASCII character set. + +If you generate a filename list of your archive (unzip -l), +you will see the converted filenames. Your can also extract +the archive with the switch '-i' (= ignore mac filenames), +and test your result. + +This MacZip port uses its own filename stored in the +archive. At the moment, the filename will be not converted. +However, I'm planning to add support for Unicode. + +Currently, the following Mac OS encodings are NOT supported: +Japanese, ChineseTrad, Korean, Arabic, Hebrew, Greek, +Cyrillic, Devanagari, Gurmukhi, Gujarati, Oriya, Bengali, +Tamil, Telugu Kannada, Malayalam, Sinhalese, Burmese, Khmer, +Thai, Laotian, Georgian, Armenian, ChineseSimp, Tibetan, +Mongolian, Ethiopic, Vietnamese, ExtArabic and finally: +Symbol - this is the encoding for the font named "Symbol". +Dingbats - this is the encoding for the font named "Zapf Dingbats". +If you extract an archive coded with one of these +charsets you will probably get filenames with funny +characters. + +These problems apply only to filenames and NOT to the file +content. +of course: The content of the files will NEVER be converted !! + + + +File-/Creator Type: +------------- + +This port uses the creator type 'IZip' and it is registered +at Apple (since 08. March 1998). File types can not be +registered any more. This port uses 'ZIP ' for Zip archive +files. The creator 'IZip' type should be used for all future +versions of MacZip. + + + +Hints for proper restoration of file-time stamps: +------------------------------------------------- + +UnZip requires the host computer to have proper time zone +information in order to handle certain tasks correctly (see +unzip.txt). To set the time zone on the Macintosh, go to +the Map Control Panel and enter the correct number of hours +(and, in a few locales, minutes) offset from Universal +Time/Greenwich Mean Time. For example, the US Pacific time +zone is -8 hours from UTC/GMT during standard (winter) time +and -7 hours from UTC/GMT during Daylight Savings Time. The +US Eastern time zone is -5 hours during the winter and -4 +hours during the summer. + +Discussion of Daylight Savings Time +----------------------------------- +The setting in the Date & Time control panel for Daylight +Savings time is a universal setting. That is, it assumes +everybody in the world is observing Daylight Savings time +when its check box is selected. + +If other areas of the world are not observing Daylight +Savings time when the check box is selected in the Date & +Time control panel, then the Map control panel will be off +by an hour for all areas that are not recognizing Daylight +Savings time. + +Conversely, if you set the Map control panel to an area that +does not observe Daylight Savings time and deselect/uncheck +the check box for Daylight Savings time in the Date & Time +control panel, then time in all areas celebrating Daylight +Savings time will be off by an hour in the Map control +panel. + +Example: + In the case of Hawaiians, sometimes they are three hours + behind Pacific Standard Time (PST) and sometimes two hours + behind Pacific Daylight Time (PDT). The Map control panel + can only calculate differences between time zones relative + to Greenwich Mean Time (GMT). Hawaii will always show up as + three hours past the Pacific time zone and five hours past + the Central time zone. + + When Hawaiians are not observing Daylight Savings time, but + the rest of the country is, there is no combination of + settings in Map and Date & Time control panels which will + enable you to display Hawaiian local time correctly AND + concurrently display the correct time in other places that + do observe Daylight Savings time. + + The knowledge about which countries observe Daylight Savings + time and which do not is not built into the Map control + panel, so it does not allow for such a complex calculation. + + This same situation also occurs in other parts of the world + besides Hawaii. Phoenix, Arizona is an example of an area of + the U.S. which also does not observe Daylight Savings time. + +Conclusion: +MacZip only knows the GMT and DST offsets of the +current time, not for the time in question. + + +Projects & Packages: +-------------------- + +A Note to version numbers: Version of MacZip is currently +1.06 and is based on the zip code version 2.3 and unzip code +version 5.42. See About Box for current version and compiler +build date. + +Because of the amount of sources I splitted this port into +several projects. See http://www.sitec.net/maczip for +updates. + +- core source parts: + unzxxx.zip + zipxxx.zip + These archives contains the main parts of the port. You can + build libraries and a standalone App with Metrowerks + standard console SIOUX. They contain only sources, no + executables. These archives are exact copies of the standard + Info-ZIP source distributions; they were only repackaged + under MacOS using MacZip, with one minor addition: For those + files that are stored in BinHex'ed format in the Info-ZIP + reference source archives, unpacked version that are ready + for use have been added. + +- additional source part: + MacZipxxx.zip: contains all the GUI stuff and the project + files to build the main-app. Only sources of the GUI, no + zip or unzip code. To build MacZip successfully you will + need to also download the zip and unzip packages. + +- executables: + MacZipxxxnc.hqx: contains only executables and 'README.TXT', + This version is without en-/decryption support ! + MacZipxxxc.hqx: contains only executables and 'README.TXT', + This version supports en-/decryption ! + +- encryption sources: + zcryptxx.zip: To build crypt versions of MacZip. + download from ftp://ftp.icce.rug.nl/infozip/ (and subdirectories) + +- documentation: + MacZipDocu.zip: contains some further docus about the algorithm, + limits, Info-ZIP's appnote and a How-to-do Webpage. + + +Credits: +-------- + +Macstuff.c and recurse.c: All the functions are from More Files. +More Files fixes many of the broken or underfunctional parts of +the file system. Thanks to Jim Luther. (see morefiles.doc) + + + + +--------------------------------------------------------------------------- +Footnotes: + +1. wild card: + The '*' is a wild card and means 'all files' + Just in case you don't know wild cards: + '*' is a place holder for any character. + e.g.: + "this*" matches with "this_file" or "this_textfile" but it + doesn't match with "only_this_file" or "first_this_textfile" + "*this*" matches with "this_file" or "this_textfile" AND + matches with "only_this_file" or "first_this_textfile" + + +2. Mac pathnames: +The following characteristics of Macintosh pathnames should +be noted: + + A full pathname never begins with a colon, but must contain + at least one colon. + A partial pathname always begins with a colon separator except + in the case where the file partial pathname is a simple file or + directory name. + Single trailing separator colons in full or partial pathnames + are ignored except in the case of full pathnames to volumes. + In full pathnames to volumes, the trailing separator colon is + required. + Consecutive separator colons can be used to ascend a level + from a directory to its parent directory. Two consecutive + separator colons will ascend one level, three consecutive + separator colons will ascend two levels, and so on. Ascending + can only occur from a directory; not a file. + + + + + +--------------------------------------------------------------------------- + +Dirk Haase +========== diff --git a/macos/ZipLib.h b/macos/ZipLib.h new file mode 100644 index 0000000..e3dacf3 --- /dev/null +++ b/macos/ZipLib.h @@ -0,0 +1,166 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/*--------------------------------------------------------------------------- + + ZipLib.h + + This header-files is global to the project ZipLib. + + ---------------------------------------------------------------------------*/ + + + +/*****************************************************************************/ +/* Macros, typedefs */ +/*****************************************************************************/ + +#define MACOS +#define MACZIP + +#define OLDROUTINENAMES 0 /* use new function names only */ +#define OLDROUTINELOCATIONS 0 /* use new headerlocations only */ +#define SystemSevenOrLater 1 /* Runs only on System 7.0 or later */ + +/* These functions are defined as a macro instead of a function. +so we have to undefine them for replacing (see printf.c) */ +#undef getc +#undef getchar +#undef putchar +#undef putc + +#ifndef ZCONST +# define ZCONST const +#endif + +#define NAME_MAX 1024 + + +/*****************************************************************************/ +/* Includes standard headers */ +/*****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Many things are different for mac-users, so we need + special mac functions :-) */ +int Zmacstat (const char *path, struct stat *buf); +#define stat(path, bufPtr) Zmacstat(path, bufPtr) +#define lstat(path, bufPtr) Zmacstat(path, bufPtr) + +int fprintf(FILE *file, const char *format, ...); +int printf(const char *format, ...); +void perror(const char *parm1); + + + +/* +#define MAC_DEBUG 1 +#define DEBUG 1 + */ + + +#ifdef MAC_DEBUG +#define LOG_DEBUG 7 /* debug-level messages */ +int Print2Syslog(UInt8 priority, const char *format, ...); +#include + + +#define Notify(msg) \ + { \ + (void)Print2Syslog(LOG_DEBUG, "%s (file: %s line: %d)", \ + msg, __FILE__, __LINE__); \ + } + + + + +#define Assert_it(cond,msg,kind) \ + { \ + if (!(cond)) \ + { \ + (void)Print2Syslog(LOG_DEBUG,"%s failed: [%s] cond: [%s] (file: %s line: %d)", \ + kind, msg, #cond, __FILE__, __LINE__); \ + } \ + } + + + + + +#define AssertBool(b,msg) Assert_it (((b) == TRUE) || ((b) == FALSE),(msg),("AssertBool ")) + + + +#define AssertStr(s,msg) \ + { \ + int s_i = 0; \ + Assert_it ((s),(msg),("1. AssertStr ")); \ + while ((s)[s_i]) { \ + Assert_it ((!iscntrl((s)[s_i]) || ((s)[s_i] == 0x0A) || \ + ((s)[s_i] == 0x0D)),(s),("2. AssertStr ")); \ + s_i++; \ + } \ + } + + + +#define AssertTime(t,msg) Assert_it (((t).tm_sec >= 0) && ((t).tm_sec < 62) && \ + ((t).tm_min >= 0) && ((t).tm_min < 60) && \ + ((t).tm_hour >= 0) && ((t).tm_hour < 24) && \ + ((t).tm_mday >= 1) && ((t).tm_mday < 32) && \ + ((t).tm_mon >= 0) && ((t).tm_mon < 12) && \ + ((t).tm_wday >= 0) && ((t).tm_wday < 7) && \ + ((t).tm_yday >= 0) && ((t).tm_yday < 366),(msg),("AssertStr ")) + + + +#define AssertIntRange(myvalue,minimum,maximum, msg) Assert_it ( \ + ((myvalue) >= (minimum)) && ((myvalue) <= (maximum)), msg,("AssertIntRange ")) + + + + +#define AssertStrNoOverlap(str1,str2,msg) \ + { \ + long s_i = 0; \ + AssertStr((str1),(msg)) \ + AssertStr((str2),(msg)) \ + if ((str1) < (str2)) \ + { \ + s_i = strlen((str2)); \ + Assert_it ( (((str1) + s_i) < (str2)),(msg),("AssertStrNoOverlap ")); \ + } \ + else \ + { \ + s_i = strlen((str1)); \ + Assert_it ( (((str2) + s_i) < (str1)),(msg),("AssertStrNoOverlap ")); \ + } \ + } \ + + + + +#else +#define Assert_it(cond,msg,kind) +#define AssertBool(b,msg) +#define AssertStr(s,msg) +#define AssertTime(t,msg) +#define AssertIntRange(myvalue,minimum,maximum,msg) +#define AssertStrNoOverlap(str1,str2,msg) +#endif + diff --git a/macos/ZipSx.h b/macos/ZipSx.h new file mode 100644 index 0000000..d2b9ae8 --- /dev/null +++ b/macos/ZipSx.h @@ -0,0 +1,167 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/*--------------------------------------------------------------------------- + + ZipSx.h + + This header-files is global to the project ZipSioux. + + ---------------------------------------------------------------------------*/ + + +/*****************************************************************************/ +/* Macros, typedefs */ +/*****************************************************************************/ + +#define MACOS +#define USE_SIOUX +#define MACZIP + +#define OLDROUTINENAMES 0 /* use new function names only */ +#define OLDROUTINELOCATIONS 0 /* use new headerlocations only */ +#define SystemSevenOrLater 1 /* Runs only on System 7.0 or later */ + +/* These functions are defined as a macro instead of a function. +so we have to undefine them for replacing (see printf.c) */ +#undef getc +#undef getchar +#undef putchar + +#ifndef ZCONST +# define ZCONST const +#endif + +#define NAME_MAX 1024 + + +/*****************************************************************************/ +/* Includes standard headers */ +/*****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* Many things are different for mac-users, so we need + special mac functions :-) */ +int Zmacstat (const char *path, struct stat *buf); +#define stat(path, bufPtr) Zmacstat(path, bufPtr) +#define lstat(path, bufPtr) Zmacstat(path, bufPtr) + +int fprintf(FILE *file, const char *format, ...); +int printf(const char *format, ...); +void perror(const char *parm1); + + + +/* +#define MAC_DEBUG 1 + */ + + + + + + +#ifdef MAC_DEBUG +#define LOG_DEBUG 7 /* debug-level messages */ +int Print2Syslog(UInt8 priority, const char *format, ...); +#include + + +#define Notify(msg) \ + { \ + (void)Print2Syslog(LOG_DEBUG, "%s (file: %s line: %d)", \ + msg, __FILE__, __LINE__); \ + } + + + + +#define Assert_it(cond,msg,kind) \ + { \ + if (!(cond)) \ + { \ + (void)Print2Syslog(LOG_DEBUG,"%s failed: [%s] cond: [%s] (file: %s line: %d)", \ + kind, msg, #cond, __FILE__, __LINE__); \ + } \ + } + + + + +#define AssertBool(b,msg) Assert_it (((b) == TRUE) || ((b) == FALSE),(msg),("AssertBool ")) + + + +#define AssertStr(s,msg) \ + { \ + int s_i = 0; \ + Assert_it ((s),(msg),("1. AssertStr ")); \ + while ((s)[s_i]) { \ + Assert_it ((!iscntrl((s)[s_i]) || ((s)[s_i] == 0x0A) || \ + ((s)[s_i] == 0x0D)),(s),("2. AssertStr ")); \ + s_i++; \ + } \ + } + + + +#define AssertTime(t,msg) Assert_it (((t).tm_sec >= 0) && ((t).tm_sec < 62) && \ + ((t).tm_min >= 0) && ((t).tm_min < 60) && \ + ((t).tm_hour >= 0) && ((t).tm_hour < 24) && \ + ((t).tm_mday >= 1) && ((t).tm_mday < 32) && \ + ((t).tm_mon >= 0) && ((t).tm_mon < 12) && \ + ((t).tm_wday >= 0) && ((t).tm_wday < 7) && \ + ((t).tm_yday >= 0) && ((t).tm_yday < 366),(msg),("AssertStr ")) + + + +#define AssertIntRange(myvalue,minimum,maximum, msg) Assert_it ( \ + ((myvalue) >= (minimum)) && ((myvalue) <= (maximum)), msg,("AssertIntRange ")) + + + + +#define AssertStrNoOverlap(str1,str2,msg) \ + { \ + long s_i = 0; \ + AssertStr((str1),(msg)) \ + AssertStr((str2),(msg)) \ + if ((str1) < (str2)) \ + { \ + s_i = strlen((str2)); \ + Assert_it ( (((str1) + s_i) < (str2)),(msg),("AssertStrNoOverlap ")); \ + } \ + else \ + { \ + s_i = strlen((str1)); \ + Assert_it ( (((str2) + s_i) < (str1)),(msg),("AssertStrNoOverlap ")); \ + } \ + } \ + + + + +#else +#define Assert_it(cond,msg,kind) +#define AssertBool(b,msg) +#define AssertStr(s,msg) +#define AssertTime(t,msg) +#define AssertIntRange(myvalue,minimum,maximum,msg) +#define AssertStrNoOverlap(str1,str2,msg) +#endif + diff --git a/macos/ZpPrj.hqx b/macos/ZpPrj.hqx new file mode 100644 index 0000000..5bb3da0 --- /dev/null +++ b/macos/ZpPrj.hqx @@ -0,0 +1,455 @@ +(This file must be converted with BinHex 4.0) +:#9T`8(*U,R0TG!"6594%8dP8)3#3"&66!*!%Ip96593K!!%!!&66FNaKG3)!N!3 +@!*!$$39DF&"bDJ#3!aEf1!,VX93!6&MU!*!$J!#3"!,cIF3NA3#3'[q3"%e08(* +$9dP&!3b[H&ZZXklEb3#3"3,E[3#3"P40!!$hQ!#3"L8D"RMDS*NlIS6ISVG-[(8 +R+hBY21RaEd$i`XJbN!"bQK8YHRN,mmTE("$HbP6f+lXeRq'lH*3I@AbbH%Ef3E+ +Yif3KHp54hE%@hq8Fj,%GAml1RLpN-E,i(GQARdH@0q0,K(GffT%p5)X[RVFF@D4 +BKrHBaXd@6VD,AXpZB5d!C#'6K@abQi`@mJ[Cj$MPC!8iDT2X[EaXE0rjRCHM[$` +Ej#4Rp[RPjG6VcFj"ITHAR9DQepPe(-SAiAji1arZ(-5ApPP[lbMciLAdmP)if0m +4Z#m[-q'q["cNPGI1p`,!!JLip@eQPi2X'farqH4p"**I)T!!,ckH3A`!+i#AjfI +6V9BMbl,P@GDh0P[fhKZcCArkf5`lka2F0rFYkb28qpDfD[R@DP(8@d9PSQMYcUH +l#l&K+CqqV@b6b'8EXQaE[)pm16Za$2kVE&Ajrhr50p-icq)mQh-k-9rKr#ThirR +rPjaIiecK!m`jJh-@jcQFFcJAF-lMl1)dliLFcVQ"F`IR*Xk0R"GcEZCFalQ0mbl +1fcR[i$c+q@,1jh$HcAQBm`MR4C`2FElF9MERGNj6amLPR&XjIj*c$@F2jmXiAm$ +j*XlAFlk"mi@FrjhcMcNrbIN*cSpcISVc6cMr,HHpR$r0q3#eRXTrcYrLI$mR'2- +,R+rKI"hRIH3Bb9R2#IC-iM3GT%lK(-,CcQPUVdlJ(-lCbMQ1Xi(6p)BkME10Xj% +c+PDCdr561TN6d2S-jjpa'Lb,I*!!mcpbrKVR@cNIiIaPcSFjIjhc9cKrNI2GR'r +Mr#$RKcMIc[R[1Aq9mbfFlq6m*Fi,1*Ga,Z@mKI0IFGl*#5!Dh)bmK[09R,GaAX, +j"jarb2RI1(q(FaIR4cJrb[Nqc[Gb(Z#mQA-Ijhl1Jp4a$2rr-qGri@idr`pa2Tr +c#j`c1@GcRXXjPh-Kjha1dcX4X#IbK!KDTSmLi&#%2SXmRI-QcLq9Z!9QHAK&RJp +`lZ(FbhNGjrfFi0ZA1@rJr$6RRh*qP[1jR(r"H68Rb4GarLERAh1H6mK%r[mHjqp +bAXYTHM*b(ZI2F2iXj`61[`QF)`)'4&l"HCccMCcrM[2R16r(qAR1Rq!dI4jj2HF +pR$r&qmEbrbAmTmDmG5@R`BL)@2XZiLEchf"#j+Fj$@j%`)h)-cJ0YN6%B*!!fZ" +0"!b*Q-YJ5Z6l13f@4"l,H6RRrq,m"ZHMR,r0#FVclQpbISXh8X0[Fcl'q6MRDNj +kp$ZFEqEm1FlAFVk)df"Bj'l1*Cc,1EXjRmhj4Fi(1@rN[*lcMcMr0HFV1DrKT2p +IcEQEmcpaIScc2h$Zj2`0c[G`AX&j+HFl*#EQK*KF5AfSiiFjrbYhe2BUcZFYQ8# +8`"SqHK"mJ1I3kr3C28Brd%[d&(J&2Y#Ep#9p$1pa'!D(S)I"!2UBIUI2k&ekQ$k +NTkNhA)PD1m`$$m!AqJL1"DHLhq&FB#FB#Zm#3m%Rq0Hr%%46EGlDqbRHVF#K%H! +jCH(Hi#JG!5E6*4lH8SZ90Sij`3pl6lJjll@6MSXbZAq0&J$qBllBSmf01Ffr4[l +C`lkV[XcL4ASG'Uq6pdGP+lLTLlHfZ[CGhY-)T@1p"c3qUpkHR1ZA["4,,hRFkea +YBX@*hcX-dG"#+9Im%9i"mj8`IdC`pR"ZifcRl1$Xj"c&1CTc$1GBcR'FNcQl1'G +`VZ*FcEQ@Fb2R*XiYR$GclZHmKI0@cJ1F"cN2F4lQ[)hc+1IYR(G`2Src(Xjl19r +!q41F@f-(QGk,(-FjM(-iCbXRM$VH@aj#JTLJCcJ!8S+3!+!HU!JLJMDJ)qJ*@MT +N"$e"8C!!&83&)8&+Kk"K"%KC3E!i)0$PJemF2ha%-$h8ZV&k4A@S8HedmNlrlUV +k4r+lI'5L-VEe@@SUj"`H)5q"0Af[ML&D&MAMJ*Q(BUqXb8H5K0BVJkB$kF&FTK+ +E1,G`MZBF`cQ@Fa,R+-j1cKXiEq5mQA-NjdE1rCbhF0l+HC!!Xiec'fF2Cc[R#-j +9R$GacZ$FblQDFbhR2Xl*R)FjEq-mbRNAjpfFcq0m2ZFpR&XjQcLE1BG`YR!1j4` +QQE%pEq+fM@mD("[Z(pkQ6*ArB1m@(2NMrbrTZlE[a'9UA)NZ-1G*h2#q2MlNie# +FlAKr`'(q0ph`MVp(96SX3dYqJ(B)h'F3ShNX,hEQPI(CraA+,q4E26%a@U*4G2h +S*GZQpp4VDZqA6Ni-IBGlai[LEVbSIX8L6)&*mGBRF[Cp'P`'R8-#ZKG'%!T3Na# +3!-m)-8N-L68ZIi`Zd6(CV9@'cMfh-Y4UGPU0[2,dLj`Tq,X[KR+QI5p6KIl4ahY +LPcQ1D'%LG1"lQRGkkX`5C4jc2[L!DZG,#8B,5U,`Fq[1G#3r8(Mci'9Ud,jSF#T +ciQZmAjrirRI0jCeZYIacC+Q'iD#62CM9E%`2YX+JZLEVVGQjbYU*LD&c+[cadf` +LhS-SY$AS24*%1!"B$AaU%FbHEZBiI&Le*&2dm*m[h!(MBQeX&DQ`Q-m4dY!$bD8 +kHP%6%rda"hqX)Y,(1*GLV%NarU3BRe1-mLR'G"6MGiV4*m@3!)"LY%a"B48MHSS +40SAJU"bI-b0DLV%IaELIFKb+X6Xc5U8Bhe115CP42-9iN@)m66&kT4ME8S`!+ND +`&'1!bP%MmhBlHQAHENIq6!ilBQEHEJF8c*[YH+'TL4e&-HqfSf(QcBaJ-HTRalI +-QaR0XZ0rjXefp0#0fM&5apJFihD-d6&kamJGih@-",S41aQYXQ09M1SaQXGB%f0 +hCUc,MZFamX5i(102M-iaYZG'X%`IfUkLVScJ-8E&'"jMCi`p-N,'Q#)M9BcX-BV +'Q"BMLBaU-CE)q"NMMibJ-IE)5"TMN!#-G$%qb@JJif#-"c++a@JM)f+-p6(ZaTJ +KSh#-26)#akJG)cf-J$+'b"JAii#-CXPS(b0DGM63M36#+mfiD'a8e)cUfE&(4Kd +CKh5MMSa1-LV*b#0MNk!-Sj!!M&'kN8P'*"Q9G118M&bD)4$'`aJTC265MR%bcZP +'1aP9C066MABbqXIS'D10M!$+f+!Gph0MPS`&-QVTa[BB(@4-N4%h4J8CE@2Ncih +9-3l(i)SE-Q%iaBfmqX-Q$+-`f-)J#i-SE[L%N8I'C"PjC'5@m8FcHQK(%4PcC%5 +6F6X'BaM6C151N8h'laK*C-54N6Y'(XfiR"fhBr5488I'm4LVBlb4F8Q898Bc'FY +Nh*049XBecBLQ(FQ%Kc2UL6M+q#hFJh%l0j,,+#lMSCR"(KP@53lhm0'6rT!!Ma[ +UBD#(34i'HKMHBCL(34i'HK"a'44#hN"HmSGk'1Y&cf"FQ2N+aL@4LKMrCE5BN@, +'N4QbB-5Bd@)h&X`i-#2'M!XMmM*kc2JK)kb-*6,HbYJK+J9ML)`I-YTS4LJ91+[ +!9`@q+["9JFF+r&AJV!*R&6LV`'N&,L[`9S(h#Xa9B+i#Fa@iVm"G"8G3F!F&eLZ +iJS*$+,L&JPXSZ)@#@bK`AX%V&,a#`5Z8I)+4BS-IGPcBi!!MbBb1-Tl+q'Cb60[ +d$q2CGJcCi*%Ge6-iT-!K"3iTm%H"2`Vm8H#2!Rm8q+2!(`Aq+2$(MLFcrQS`5)& +"#Ja5i)S#Ea4iSm!E4@mSX%%jSQQ`4i%j#Xa4p)d#Fa5BSm!I"HiSF%H"1`VF8H# +1!RF8Z+-F$6DiSm!G"HiSF%H"1mUH-pLM`"d&lLK`4p'AM"`UqPf"!`SX925k!JF +9Q+$!"!8Q+,"5JBm+E&$JJJ)A&,LJ`!-&(LM`3)%(#Ma3i)%#$a4iS-!$"4iSm%# +"X3T-8'##!K-8H+$J&!T1SH!5#LkKY"8`A%2"+44F3X%I&0a!`8%82%,")a3m3X% +M&$a#`5-82%,")a3m3X'R&(a+`DH8)r@')bNiNS+[+(Q5i5E+N@E$663pT1NK63p +THNM6EjVHd[55TTFd[D6T58hrDAT+de1DRY,dP+DR0$fPk5G02fRk5G02'KcAm'% +06dC@e["L63pVkUDTQkCZQVTTq,1'2f[iS)C$DlLcKQYV1,D'3fXiY)C$DlLfT[i +D,00`F!fHDALeKMYUZ,@'-fViYBCIDrLeKPpVq,@'[fTiVBD6DMLPKXYUH+@'9fT +iTBE[DRL`"PmeZ+[Kq"UFe'#N"L-eA&1$NaUFe25LTKFe[DMT3Dd8ErTF`fXe[Dl +TG3d@D$"!dr1DRYId[!BM0&a4Jp%DM0$JY!B(0"aCJ`-DRUc"!Jd@D,"!Jh%Dr02 +JP!EV0"LSiG%D204`D3f(eR"S$3CUF&1$QaVFe'#3!!Er0IL[`Am09pC`!#d(-"U +!JQmVH,L#0bXd!S8fS1$IL[STDU%F#6HDJD)HL[FUhUTiUq+YL[j8p*ULca4pT1J +K43mTHNJjGXriY(Q[3RG3p)b#RbZiX,,Z"XXdZ+2",JfQDEL!KJYSY!X0(p"`!3e +Id2!%$5I3F!)0*p$`#-dl0*a&`b-dr%H$[aVqSm&RMHDK`9)0(QY`@S2A'Pc@B,N +'bc9BVZ&''McAe&C6Fdep0(LZ`A-0RQX`A-060(a,`m-d2%a66`dAdh!a$5jVF&Q +$baTFe[")$Br8p)Q'#fPiNSCVDMLQKYGSZ*''-fNiU+Eq'JkRiD!D(UIK8jUHdh! +R66pU1*H'FfNiPiCcDAL@KQGTH*D'@fRk9F1[0$fVk9P0VfUiPSCVDEL@KQYT1+k +'(fTiSBB6D[T3``Ze[*!!mAZM%5Pd(iAZSp!8&0U43[qaNaMS)%CV8'J-QJ!0RpE +`E!hre["[$Ir@m'm0lpE`EJh[e["Y$Gr@m'd0hpEU*ZJ8B3GIH-fNB'1B3JRj'%8 +aRe@'`bJ'fdl93qCGKdIr(k0G&iF0[#%M-bGm-JqU9h[+JqSeiaYjr%&'P,'fP!I +eE&M+JlTf@5p2X8P-&!VFXe-H9,V,8aj8[#Y6(T5qUe)He-#V8ai8`fY5(P6&De- +H9-IV8Ki8h4Y6(Y6JQe)HP12l8Kl8cGHP2#LMVdTj8&6IP2+JVViQj8&jI8A+Jc, +l`T3(pIDG[6c*-6!Ipe"iVdM[339qIXU$8[lbP!FerD'8"mApH-U$+[r6+3r+rBG +5(Y6p$kBm6!$X6AQB%VJKj@'5i2U8KdQ$25N28`L[6hQB9(K$bX-Nd'G5(UDD4U8 +m6$f05hQBL*U8mM#jp2k8KmNUjfrAPiGTUkRIb12M+00CAFIbK"Kqp3Y@*5%[Rr2 +%D'*LHfYpqd1Q'%8rU[TPTCU9!ZrB&'H)J%d0cjQiHAcFqDRB&leNmjEJSQ'UecM +CQLfQFbPHr@*FabPMeHRc*Y[jG(e(hFQek)D4d@'j&[q0Q2c#a@3MMkmhTaZc05I +D'Q*m6rbr,IjI&Iq[MIpAarm[@Ra(jh'GXKM83X+ha2rhaIpharmEirp0LqRE9p+ ++ebL#f'+Ck)liId6m2b2qEer-fV*LI2YZEIKFj6VMre(arqMiIdcm2cEq(lIiL+% +q!PP&aq$*mArABT+aChCf9BZm9TR'hl5,@R8pUE+P'BEVKm9m,ieYpS,irfL-Zcr +H(iVr$mIr0mIrpmErqq2r@q,r@q2r!r(r`F9kk-F-ETSFU3"H4kT&[B5!ZXA`qZA +"AU-ZTQk0riI(rif,Z4U@"am$Q`X(*[RI&2rEmX+B%cR9+L!QqAUp'"dpr(VhhhD +Tq6pX-9IMiGF2MIq(a2mYLlQ'R,!jAd!C&4qcGAjq[ZpAGXmfpecHfH(mT08%'lH +MKZq)!"i#`hK'VKNDAcqmTV*QrH$8)(phM!a0+BL'U(aQTLGV3*0flr!0CV`6RKD +ki0la6eC+49ZBd)TjNY!!CKar%am6&-kZK6RZZZ9Mch%qRrR`k,*p'r84B-kl2PX +jV[V,2,2PlqCM2YNce[6Q[CXDkY+HUZXC0R[cfUi,m$j`mpI-q60rcBFRJ*P)DG) +I!4m#TNliQ1e[rGV0jF`imqpYfhGlCEd)4Q3ri%JrmrTf@S3lTLJk-KL00dmF1D0 +9*Q3fedk!N!#$'@ZQ2,KM*Ye-FYKm+19MXTHeR"p'(4lE,LHDm)H`8aIFiA(!c$G +hq"G-D&3P8ma'-`1q`RPL2"-Q26Bl9DN)$i2*`IQ,qGY)KBHD'M&V5kpCc`J6BQI +[D82QckGP0kiQMPR!b1Vjq6ZG'fAqRKPqFY"rdaR5CDD1qINC38KKKYEdE11ERB2 +%0i,CIZBBm@%i9e6dCP-Mj`C2'qC1lD`rZI%LB1DI1fScKrFaPiL2`0b!&(91$-d +,MKpeeSZDF-Im2pi!h$(PJ%F!GbJRH!9`"kpF&0K"R6i@LhAm-(Gi3P`3H%5G1,0 +Nf6lEUNlI"r`%$"1Ydb-"A`(Lm(GBPYei0VQLBYCbqX2d@p4T('EVJ5`m$&C52p0 +,8AR"KF("*5T@@A`dG`K@6+"`"c)bZmmGRKV#DU*k5c$,cahH$!+j8AZ#(J35`8& +QqlPMAKm"KMY`%NQ%1l`pQ2AR$Qm-XHfUelH$k4(Z!$*kKcZm+*J#!@EaD3#[Z+- +(K-Nhk!H#4`"hH(2`GZl`bU$1h1&p)GTAJpL$K`"hH%hJ*F!GrK(i#A$(Zr%9i)i +DibrJi"f0L$X`(FcKMNNZm*-lqJm["ZlJ%(JkF!F'iIR!(4J"4q#1hXBEJM[k$Bm +)lZJ0F)-lkQM"hYcaCN3,lSM"1i)lH!EH%G`a@5&#C+2H+Ki6L4b[M`VBcKfq+8b +kF)GR#Ah+(6iN6+a`KhF+lq)1la3Q6lM$"d@mS"VY-cJ#GhL,#-YXe,X$0BFlq)V +-4$EU6m+%#(IiH9!Vl["6`EF#kX58UUHr4%k3!*2K"m-GrK,iaA#(PiF`Z5Ca6Ub +QQm4FDXiGrK[icA!(IZ%l`adi!VrLMMk(Lh&(2m&aZ+2ZBTMEC)h!,ZjiJaK`0ZN +PJcm0Gr3(rF8GILc`$ZlS$haVZ-0r"EcL$Jm8m*ml2%c`Xq%1(aCmEEM$Xi3q09q +c&"C-jJjZK*m-Gr!aZ"Khm#+i*(IiPH!h`aeiL4m0Gr3"IMAFd3IieR!(VZ&I`af +B!LC`4fq$eGc49rMCF%HYi92Fm@CmEEMM2A!ClZ$1q0a`"jE!EER$CiGBlP"&)$V +F`A("(ql`Im%2KcY`'PmFl["h`4q(1caKm-RK$Zj)2jT[L2L"p`phm'&i!AId"pi +rh)'le)3lZ!FFK$Y`'3mKlX![[)5iSmrKM0c4*h!dlRJRhN,Fi4-%$R"(Vq-*`Kf +H0IJ,FBFR$I8hAiXF!VmKlZKMq$jhm!EmKlL$@q*$a"eiKKm4Gr!LhXXGh!1Zc4f +B$Mjc"fk#4Gb"4hJ(F3F@L"V9BKhKGp`4!aIQ$Tk(pa"hq1R!hlQMcq#NjKZUPJ' +qFBH4-jj%h+%hi%h%(AS*(NAF`62TFHlJBrJ6F3F[`UH)1hS1[b,Z`'@i'hIJ(6h +&(4J%eq!1,)!cFNFIiQ[%(If![a&h["1I)ql`(!*EZ--R#El2(9J,0c6I-2%$rX) +G@![[jJj0"GcQMKVMBF3G(MqmLc[k%NmMlUJVRNEF`CI!-HlJ'23AGr3L(NIFJBP +J"AGJ%lb*1rS5[b2ZU#1q4pca(VJ$GhJNiB0N[Z&b"IJXGfJpk"MFJArJ*hG`82U +D1cJr[)`lH$9p`4dm&Tf"1cJKh)3lF!@[+1lJ-r"PlZ!9V(R!(CK16EJ$Bm"UlX! +JH"phB!Gib"hp$0IQM[i4,i6KeS,Hj!kY#mmZml@+2AKhFBH'KBFAGiM4j1'1'X- +VZB-$@IFdFiIIM(F9q6jpC15bPAVMFfA[m,U4dHe@*rGNR,99rb"C0k"9Mb$4reV +eqa$pVe92$h&DD0@$4[5r9[eM42r$q"SI,AZ(4jESIfek"(Q,A841eGG(p,mfrA' +B,1F1hae`L6[mHG!IZ'1b8I5r0MhAi-lFi@&KhQM[m$J5rDp0,a,4rpVd(8'li!j +[($(TEG-M"pcM$KmFdIrDp-!3r@m%pEAV+A#(Ra%H80cK833[i!lr(bDaZF26KfP +Vl[!KNY8K4ZJj*2VI#,hMd(bi`fF1[XmG[NkLrih3I`N[,qlS[j!!P8'%N!#!ch5 +Zld9UKQh3UIlaLhZ90LfCB+HE04Mpm4GQjPMU'f(#A*C+bmcjdR*"KRLhZmQ08,H +[Ch*Nq,54CMF[QRQh-McAEV5+r0pRT[Ur6AP)1bHILaTp'0X(QAcISH&iEi$ZScF +mlc8)0G[Md%K)frGH9Emd,R`-A'LIRcm3"c&#fVlId9NjM3XIZD(i+B6ERML)&Y, +frD(ZffPFq+-ELX(2N!0r1!irK,&p''UB[j[90TPU,PNEQM`-RQb*HFS@L#B23bP +EBakcfP!j$`-V25N2`bcE8Ki'AEDRqM$XXMrQDAM31X[NB4$QPT5()CPE8ak'CJk +Q2!c8(%Tj',BjR2)`L(0EbX13!-k4P)F"RU-T$m-kGkBm$2,FPI)`N!"cImT$ql2 +pLMH9AXQ$UAKGbS24H%[+Jq&i8mU$+IQ3!*3(dr,QP!GMmk'p2%@V4*1(3IJ$k6d +-(Gk6mQ!!-5cP`FKKH-U$FAaVbS-C4&[+J`(pL*3(NrVfP)GKpcX5rM!dqjb8Kb( +jBbN2`q1hTc`-'ADN1Q+k2c,P`C5r)H9KkBXa+3p,B)a2H9JJBh,+``$j"hTmVj` +(+mI1p"i'(UI&2%1qPBGP0kBFHdq)i4H'X#E+2fr"9&SEjIYlr)6!I@'"`h2@5$@ +XVIAp,b53!%`d$*`dZh&N+M[`fHJ8C,BRr2`AhD$'h(AM3,CdGYQ"6pqFII`(Vqi +krM+"V@0DaSBhE8%[[(kU@ZLPGYrNe1BRF[r3a)4HL*&hEklAp)TkY*Th4C82%iq +2bFIE4DjReZFf0+VQrIV8Q(iBNDpGN4FG&*8KkiZ@8Zr8dQe2[QLp((qaRR$4hHA +)KqGhG@rTUfMpEp565cp'kX-@1$-VjIicGLXF['%mMl&l5cA9mjfk9hqpPZKCC6h +[6NY#rZjHS44HRrA9rYB4iH`*Vmmc#!5CUV+8f6pZ!a"Ep$)@PCJ$HhV$[hmbHml +YhaU[c1RhKTR3a&4,B%(QHX@DbarGGB)p"0dhPY!2ZK)B9TMe*`h@Y!r&JV*KSYl +8KKClZmEU4%[l9@chQXC'P!fX09ac&`0kX5`E-TBhAD%+Qpb@,UELh[T9N91i-[9 +NrEE)UPBRjrfXU49j6,h4m!j,aYE*A5hAVX)HX1fCGCF[X$E+)mCD9h$('N4Qci% +EZZ4MIDE)k9bCfV#H915-Ur)K9j!!`TkdXe'h0U`&&APXc)GYiZMZd"6eBmfSb&R +GaQ9BeGCTIcHfhKbL0R9DXBdEkMDB$+l6&RKmBcCRkVK1'@4#im4*hP5RGHE%UEa +M2Q`m*kd[P%RUY*HF2&98XEQYdj+aka3#c4f@J&K#QqQZU"1i8jZeR0k+ZQVCY,V +2L+a3fMKVfEihB+-B&H[%%XlD&SXPA&3l5,'%LfSTLBdhGr3L0QG'ZUNAJE"bT)A +j2f[C[YFbE9b[*H,Xl,JDr91[*DKB3YFl`5Dlb0CVIcShi%'ppTlc!Kl8Db-j2q" +"[6,1JS!($8lK,Jaid1$+D1F(2'M3i@&4`)-'LlXii%'$0V!A"$aSd,Cd5F#$"Ud +eP`BmD,![Z`-H0'T&Z#cJ3D1iY6cJ3D0fDLX#(M4U&ESbp,He"Vi`i%'MY9`9m+" +4kd`QE8hr0@TaZ5EQ`iCaEF#$*LHCe`8mD0,fqU+!"dhfjIU!"deDafi)H0#N4Hh +'J!G0pZ@QJ!G0@S0Z$RM3T(hPPS!(eZjfDm#$CLd"QB3e&U$0@U!bl@TUhDbe-KD +fc&GKb`XZQhkfYV2)C)DR0@Z&#KBE'd9V)iZ9XTN5EpBpJ9SCI"NLaQ!*E55i)GU +YBJR08$a[`a,D@"X1dIlbXN[c+qR4)IDPXB51JK0$l-[,4fEDp-d3mIk+LDd9F(b +)eTeAATTG62eDV199MEBeE,'@9iHG&PVN%pFd@&r6h#%[AVZK-X)l@qJl,+(T[aD +YG+m2q0HLGHDHJ(mYpZAH)&1fL$&Q1I)ZV(f(1K&qif6H*FP3qr+Q#TIQMYlBPdp +@i5e$R8k&NaJq0&3,BV'%(UT0VPK#$p8'9LbKKfSh+TE3`m5BJjplRQX3$"0E$l( +&P*%kKr(f52YMChH`A"dQ0lTYjlS+9Uc@k[3)2U1Q"iD*-8GG0X,FB@plM0+Ep`l +6J[9fHX[JeM"Y3ZmBBE-#dl,djA2fV"X%$iEEPhIZkSK,`m@#Zpbl`0a4ZqHLjCL +q(QjIhKhH0e`Hmlc`2QXYq[afZdlGKfY9HSpl'aMUK&[!mBYRkp5j94jhEdCbF`F +ZL#9dUpa#,+&Ea6#aK'l9fPFXS9[P,Q)*MF@RXi4Zdkj6,+(EY(mA5qJf-88XSGZ +dXaC,k$CYPX85ZNhF%N[S0RYG,+(Ej%CL#6e#e`'aK"iK0a*,k"&LQ9K#Mp"'@bb +K4fMT,*E3f'8k5qJ4@YH+*I3)E96&LDKG'9SXSG[P%')*hDiYV&K#YfZl,CE3l9S +pLb9dZdD3!')*hDjPVPK#Yf[I+TE3(ES)L#9dKha,,+%lP0A%%VV$(K0,k!kYPX8 +5ZN1X&8[S$Zeca4,DZTb+*I4)TAQaK"iTpaG,k*(DUSXPp%Ml@5bK4jTA,+&(DQ8 +XPY!Mj59L#GdTrSQmhLPI&%[S6ZhZa4+k8qiVPY#GpVPB3RIk0V'%lY4#@5bK1m9 +AXB3H*4m95qK4FNkaK"iPISXPp#KYf-85HT6p,*E3Shbc@%+2dNjC,+&(DI-VPY# +MGI!35qM4fUD,*I4ShbIQRD2&2,'%(QhrLbAdD0mTPY#Ma3baK"kYhDjB3Sq4GiS +Pp"MjM9K#Me%E%8[S-H+J@%+2XFI%%RU-m@)*28D1,TE3Bm9TXB3H+fm@5qLa1UQ +**I4BF8J'2FD+&f)*2GEDL5Ad@2QI@%*E&eZaK"iR*a0,k((b','%(LG(%N[SFH+ +b@%+2Xmr&%RUFla&,k((D'SXPp(MjX9K#MpFH@LbKamZra4*k[2aE,+((LhGL#6h +HAK*,k2(q&d[S#GUML#Ad",&(,+%Rb&2&%RU#j&!XS5H)k@)*28&F%%[S#GC),+% +Rb"h&%RULqS4B3Nq8CiXPp%6aALbK*fUR,jE3%m9VXB5H+,k)*I4%DbD@d1`$l5b +K*pPRBJNp5@`35qK*BS0B3Nq51iNPp#5aALbK*iNMBJNpb6U+*I4NY65aK*kXTL1 +Z5*2&Bl'%RU`++jE3Nm9lXB5H,'F35qM*B*Q6r#E6Efk5QT@pR59dPfXDLN90&qp +cFQfA&XaL#GhP'K0L#GhP@SJbG0)&6MK,k#jUjbbKTp"ccK*kLZX-LLAd&0Fb&%[ +S+DlP+CE38l3r&N[S+DkI*jE38qKcC`NpPEc1%RUUkb++*I48ebB85qLTV[JTPY" +6A@94,+'RZK+M@%*2"3HG*I48HXpC3Npcl85aK*lQqSCL#6h0e42&%RSDIHBXSDI +4Cmi5HTUVm)NPp$4`bPP#RdAr1%[SXeb285bKch)94,'%2N[A$l'%2X[e3m85qLc +AmK2plbcAk"2plba`c9P#RdeIX9kM[@1e4V%j2PXR&Y(rcYCp"%l%(DZ-bNSBCp[ +(S[qGE8q)rRFf1-9DMRc6U6[V1GSlqPK@`TMZ@SUb%XCd9f58P6#QZjUNV)3ahA8 +"iHrFXDSL()FlJf@Xp-Jh`jj$cq'1pl'q!(IJK+b%-81A#h#E1pDDK(G`a`U#XK, +'$([1p#cI6(#+G4hY(6dR+f(-G$e(@3PMTUY!bNSB-qdj@3PMTUY4bNSB-eeM8&E +#Q+R&ZDb%F3kiaPU2pSkHNj8`cY%P4eE#1-F9)f8PM(0F+e9@`MM(05YP*BacA)G +39X)iajk6P6$1"DIX#L2FQEUc(U5p`ajG9X)iejk6P6$1eETG9X)i9aYd@3RMA&H +%P*8`cVARC#@-@IDdV)3abji6*ljC[Np@`TLP8iQXK$(,062&hA1@Db$+5KLcA#p +59X+BEFr*5KLcj41b%XCXHdj@`TLYKLmVBFc@qPa@`TKYcmP+',1eETH9-'DlSU5 +-)ThR#UDb%XCji"TVAGSlHNkQ8Fl6CPe@`MM2e9e&rcY21h[4rmjc*8A4rmjcc8R +4rqEBFl)5aKa`LV8`lCfT1qYKfMZXff8PM$RfR-bLc(&e@&N*BiiV@-UXaKbjKDb +%-GHHNj8`jYV6XK,'A(Y19X+BkrYN*BbjmL&C#@1Z+cR+*-GFEHYP*BajFJYC#@1 +H25FVBFac$3"C#@1H25%VBFbcjd6rQqIkRk,rcG2@Ar5rHDk"+IVII,Q&k(rcAGP +6p,rjFJ[4rqE,%8ArQbq1L[ihhe9#4IqE,dF8r@qqp[ULrbe`E9E4raCSSbrkh`* +l6[5r"Fk!L2kh3'iKqYm#ZBASI`YF@92d[`@ZXbMkhd*A%aApEk%p*rVI3YmRqYp +#ZBASI`YGT96d[iAbCY(r&XSY42mlhp9K4Imlhp9'4Imlhji3rHpmHdld[r1T1bZ +DfMZ`Ar5rmee,325rmm8jdIm@ZA+Xk(q,A*&8p,p&VJSUqYmLZB[SIi[NjD,r,A+ +PAG(r&SRpS[mY%SG%re[XbUDLrbffjd6r@qbk!U,r,CC$LrkhQ(jJ(94laqU@S[m +YGK94dIm@ZckNk(mAf(1LrehJqd6rZd!q*rVI"ESELIjh!E9QV8alaaUCS[pGi&U +MS[pGJ)E#fTPm5q`2dIq@Z&+#k(p,A,Y8p,mPpU,SId[N(+,r,E'ZS[mYN4q)rVG +%6LRkha*V,2VI%VQ)k(p,A,Y8p,mPVN8UqKqqkkbrDHrS,G(rPMV',2VI8PFm&Ie +[UBjKS[mY&AY%re[U@JZLrbf9pi[qYe6X&re[+6'Xd@R[i!'Lrbfe[dArklBr42r +VGL9AdIqkl3r4rlVP6+,rGDYYL2lA,GD+rYGYIiMqeff2L[lAEAq)rYGY286rklB +HS[peLm'Lrbf6YiRqYmaq&Ie[QEa6p,pPVViUqYmb9h`9r@qCXf1Lrbd64dAr@bB +I&Ie[QCJRqYmbqEVSIm[%E0(rPVRDTZKrbq9jS[mYPdH+rVIFZ624rjDVEBMqYe` +R10(rPX[242pElMV)S[mYYcp%re[ZZJkLrbfh2d6r@klf*[VIFVQqk(mVe"*%reX +K4a6pEi9VdBVqYm+C*G(r9UKeLIkh`M@'42pEBHq+rVI#PCC&re[KfUVH9H3RAIY +8p,m9VKNUJ5[!-PElY(F'#eMadpkCrQ(96hYRDX(+Rh`VAI06p,q9VLJUqYp+-)p +931dGUkD+rVI5Y94&re[TUV#LrkedY9I4reDkJU[SIbYGV96d[j@ZmbVkhdVA(4A +pEb@pa9UPpXld-'Z1mPe),9LRe0ka)URSIaHkiURSIaGD$p(r,U4[@028hY%VS[p +Gk)U[S[pGk1UaS[pG#+k`[LRI+RU'P8hYRAN$Dj[D1eC@&Ie[P5ZrL[khbRP$dIp +@ZFUXk(qVA-e8p,p9VJSVqYmUed)5r@m9[Fh+ThbVID[SIkYGJeAd[p@Z&#[khfT +`La93l4hVd)VqYpS99NAr@qekV+,rVAD09Y(r9S0pV02+YiEqC1e@HfIHCYG8iSl +e@%Ar@q1DXD,rVA%0@p(reYK2S[qYF9eDdIr@Z&kYk(pVa"M4rpD!@DcYbVH@hQ0 +e9hYRmV,#UlfMaU,rVAApA0(reVVUVHKrDm8jdIr@LQfLrkeeV9c4rpEk9Y(reY' +hV2aUlqJRdIr@ZEUYk(rVA)&Ap,peiTESIq[%+Y(reVNqV1KrkebY9[5rGI!+9Vl +PBpNeeX+eG`B,@!rAhTQkXb+Z[@20@p(r,K)[4Iqlb09h4Iqlb(9K4Iqlb&9M4Iq +lb,9e4Iqlb29j4IpE$qkc2Ukp-aM('VRfc[3`kq6D1r0qeXUeGkce+rVIHYIV&Ie +[[D[$L[khAJiKqYpkelF9r@mpI)QeFrNfZ#kXk(mE`%h@d,9hF!A4rcEiEY(r0[K +ZdImfZ0U[k(mEd%&B1GMHXHDXk(mEA,p@p,m0m#T@&1EEk,UeS[pY"0GB9GMHQ9j +PC@&lCpl'kX,fMTi@r@qMDrk+rVI4eAj&rpYSEiRqYa(1b@V$I*[N!D,rEE+R4Ir +E"0D`mV#p-rh!kX2f$S`8r@q6EaApEj0i,2VI*[Q0k(qEa#h4rcD*@k,rE4BM4Ir +EE$q*rVFCM'"0BAYRHS"eL1dGka+,rVGCr"$pEl1i*IVICYI$&Ie[XlJPqYm@9li +9r@q,DqU+rVI&GAY&rpX#"YQCDqlJ(k,rED%@V&jXleM49r5r,Dj2,2VI&YFd&[e +[Laa,p,qYiSISIeYGK9Id[kfZmb[kheE`MV@0lChT6eBfYRIJPZKr@ehE9r5rVDi +9,2VI9VQ)k(pEIEISIcfq@r5r(R&,p,mHF9Vd[alV,ITI$lh01X$fcY51YAlY(9a +%p,mHZBMSIcfZ#LckA`pmRY9mqEDj2V$SIpYmUqKrfjaY&re[QaJTqYmfDbckhcE +HcfV(pSkH&[e[QcdYqYmf0![@2HEElYUqS[pY&lG%rp[ZQX5LrffhaU,rE3FI@AR +ChS%PS[pYTaDX[fc[i1LLrfehY@24rlDl3V$SIc[N(k,rlA!eBp(rGXJM4IrE)@D +)rVH$AQ+GBR[(UX1Lrqe`c@E4rbjf2@(4rbjf4@,4rbjfY@E4rbjfK@R4rbkfEd6 +rZjMqBG9QH`IA&rh[B[Q6k(mlAA9Bp,qGVPJXqYp1hbIkhdljK1Kr1m&69SqfGh! +QdIpfbZp&rpYTr86rfb@(%2e[PkXHLrkh5b0ddIpff4qLrqebr@R4rhEj2Y(rGP% +[9Q+fGq#Ck(qla@r4rhEE(k,rlCDML2khfrH*rVGEc8$d[peb"G(rGSXVS[rYMUX +[fc[d#G(r,T&2LrjhLAaDp,p,A&GDp,p,A2YDp,p,`&r@TEChk#kLree#h9N&fpl +"+8ArHjDV*B[qpbaAB4Ep,r6Q-`KQ0P,F2ZP@IfB[aB0l[QX3&!Eka6G#-KJB+AG +F$&YT!11#*+*UL0YR"d$-'%Km(8V-im,H--&Bk"cVYYF0$1c'Dfe1ClEC2pfD'@J +AVGVXG,FcX,ZfCq##rJX'DUhTcN#eABqc)5%MAh&&Mj!!PXqbJ[!DZfUfq3L&@E- +K$'(eJhT(&G1pPQimQGZcBF`b-KX)MM1rb0`LmiV-+9TI3R-bMmM-),1)c!XbHmJ +X)[1#GJPkFc*hb'`JXi,-!M)rb"bJc2q&+Rb0#j`NJcFRh62rH@q'TpdjRmU6UQS +)h"F@D&CX#&efAfA2Ir,[2RqIjE#%$3rr$f1UIBdPaIZAa9rX2S2K$NX0"N5h8Y" +-T-NGqZ,XE0FFGa$B-p[SeYF0cADkVCQ+hU1(LKVZSVN8UkGCLreSCD,DeAdd&im +(+rkMaR,ejZE1"e+XVhYeR3kNa34iN!$ZKH%G+kS2a"Zm0K&lmd[bjS2KkqSGVEm +2E'p!%AYcb$"EEc5+NR'4,E6*h-!H$V5TC1%"ASC,UdAc`4U[h6!QlFK(EYTF'@p +hkc2eUrlME4LE)jmG"J*+iGALfIKRMAdpe*[cmr5j(G9Qh[KkNKh9cR5eFD6kNU+ +[r!`69PZBm-%@6X`MpNE['0l`8'LP38cikXl-0aYJChl9NHTILVXeaDeNZ21LThq +lq)4A#NZdUjlmlbS4GDY@b-Q%aZkh(p**8!&dSQY`6S)UQ"0HJA+Lbd$ZJLXBi$) +%MH*L#deZQk)+i2(i)RlCq$ai%eH"EU,,`"d,,KHX!0S%$N!f+@U!R8K3+AFCV&e +`IjZ@J0V&CQ%k&PKUK`T%%ed"D+,li*Ri-MLli&)TI@"1"TYUpF-`#5S`6(30KNP +3K@(#+c"-G"Q'AA#P[ef'S#PFE+8TUM!FMbrLNSh2`c"a&4JQZJc$XH"b`3S`61! +!$*1L"X1*"*9bPf(B"IHhD3Q'A@`@KQ1"TADS`$$4&4JQZJq'L5r$X!XZPE)-`qX +(Til#-!NU-%ad$BC*8)9K`LX`6(3CKPe`TEpGKU!TA'bP+DS`()m[iT+0cm-`F48 +B*VS-`l(JFX%+-%cJ!!b6SJE$L359FTGKf!AhYfN*KPeX&SCMJD9fU-!`d48B*VS +2KSN[`l!,,T8b"m1RC+P"BHU80(9#R"U8T`B%UY-59Ep)05"6R45U6NT9&E&U8+l +kVVKd5Pik*6!05%bR4DCqQDNU0!e)6B0Ldk$FG%Vk'44r6XNr*`5J33PS3!3k,32 +e#d%$8Y"*-HLN(&34K!BPSHm+1+FNR&-LcS#-FeV)kCGbUQ,1J*`c+1J-5MURj*9 +"JH@8a(*#C"Q8@3D%PY055lrB-L#hR"4F6NSZ&G&P8(EjVNKb5LBj*C3-5#@RaC* +qZD3UQ!a)*S1LbD"XNT`B,8NBk54jZ%YR+!*H1NN!HHN8HG",CmM"AMj"[Krc@C) +GQBp209kQF3,i+q4)BdXQK`q"kGJm#+BcP'!`RDB)K-8NrHA+J@%q`FRfb`*L2Mi +1L8&`AfrQB6'GS4mB+i*(1NNr-&C%Mh55!@$X&6l5'@V!@"8rmPP+R9N83$+0-`# +-C4%NNk-A'(Z&N!"dKP2!@"&$LNRkbe8$aUSNNXr5ehjPB#`+)lN%9@$X&8I5d*N +EH3J5e2!j0IU3!!iZL2RT($P"2jqJMerNK2ed(p5Uh$YM&@3)UPbH(%VRU&@j-%' +8MkqU"lND$ik[9!GB6JjN$)aNp!pP$)aP*!TINI$55IV*@dA'5bFC)'qp8Pik3if +m9H@mI*B5)"3P[8cM$*!!Yl+XPmR45pjkTEedKP2NV5,[&C2dPkY'hUSLAcj,ArZ +9b9Y4kXXPU*+hV0bApiI*iQ+3!#-*Ld'#$#S'19+J''4)BQ)K`FfG9M0@Zr$%@h1 +XE-[K2U+@iT-GA8SL$9d+GbeED,F8QPC5a0#TN!$#`p)J0!QP33+IiTAMqdVS5&i +3Qi2T)%X'TDXjDQhJBh3TrN4$*a#k&!j!Pf1VRC+%jb$"#A41XqBJK8qE5r(9q[V +%14-IL*j"MKSr##62)%Fr2mJ+RS8%9AjJReMK"aQjY"4IJj1d@&S+Vl9E2cr)+k@ +&&%9qN!$95B-%II`JUh+9%q6j39'$$E)-mS0!J5hNU2+$J[jD5P*Yk")rb)L[[I% +9IT!!P9k$"!2m)#-CPZ+VpHhM"i'Z&Z5SmB0!93Ybp21$V+C@5&$P"rD*&Ak3!&( +N5[%e1%RVFDA`@V[emi1m'&G)8H3(@5NZ50$($l)DF6P"RKm8CEiJbb!r#%5q3Si +U2bK)I+8NeBBZmB1-[YFEAq%(*p5p[1SHT1MM"fRG[46ZDJKiTA0Nq8'3!#2*$i) +%'Ai3j%MaJb"$NKm%#Ab!,m8RmD#842UP&&lVPa6!9e,%N!#YN!$#!rJJ0!R`33) +Ii-[aI59d!"r%jJ!qb*)"q'U1@K[i!&q+2p(3#B![K32`jGKUTb3"2NL3!!6i)%% +Di)-82X#AiU[e6IVbQAS1!Rb3!#-*m%'#$-!(19)!(f4)!Rb3!-!(q&*m%Jp+5D4 +I5Z'eINN"I#9&$0N++6b!$d+6!"mNm!'q(0pA3JI`3@`1i)-X'B#[jULeJ3r`TIJ +6$Cd!q&)i!&q1VAC+%Z#$"%Q!$a+N!6j)i30m+EjDhd%'ElYpDl@jFlDk-rmQ(X3 +bP0k`VMAp-+Vi1GK1*CK!F(&*8Z'#-N6#aDA)JiY+%JBAj*-%2bD*)hkJp*BINUe +K#[46B6'%Li9ji1kZNi$ZJP)pPi`5D%r'C!T5DVBFI,[)$'5Ril*&p+(CMbQd83+ +#r4"J0hQIVPB5APe3%P*G8"T'ACJ2RAj-ZKBq4")6f'5iZ#`X"@BB,Li(5eR,#aH +8JD@#XB8IQ+KKaViL9X-F,190+Q*KF9M+@P'iS"`XC3E%Nc'CJJ5`9$5eF*%",!A +@&E'i0#`9$#Vm`(3EqE#8FCj)a+4J+HX[iB,bX*3CC[GMdV9)`e)!59Ni#U!S"d0 +C#-V!6`&kdV#6JC`mh15K*J%c@BM*`8X'@V+`%N"+%8i#+!PJ*!-K"IK)3iF2'aR +)b-*&$LTL5aS9@%Fm1XXpiU%"!iP(jhK)2$E,4Z+K'8k5LXa#DLSm!@DT3"p1%jA +2FC9-F",X%m&ahK)2bV+AH'L1`k4M%d`Q(9NXAF"UiY&&EK12$aK10VUhp"QfNiU +X0QLDqD3#(Ip*4a@UQq9#mG"HQ#Z4khKd,mb9L(BmZJ4c"G)G$bh#A*Q!Tm+cA45 +3!2&%j8X`ed[-%m%CQ#Z3!24iD!RQ!X+HMLb@VJ*c&3SIMkr!A)R1*k),-&HQpUR +`3S2QB#iJqmR)!1B+a(pVIIY$A-l&CL(1"3B!jf*cm1BLXq$Q!M23jXGPqmB26R5 +0(qCh4kc118K,K5Dl1KBDKc-ANJ8c&jL$XQ4N!XL5F8'a!K"cX88)Fp%"J+9M#iA +1J*FI9fl"0($jB3kfNM(jDQBKb`9Q!@[Gk'KP,C(R2!"CmHJXD-9$!pL+4qH!+ak +EKDjiD!Dm8T(ChNQ&*lSR&HMh5U,b14$,"#Hl1a%F"l*i8"E+iU%j-%[(*Z!X(9N +XA3"TmHJLU-AM!eM,4[H@2J0YUFKUJkEK,4AS!#iG9DKZ&Z6LS39H9K)IA'b"Pj@ +%"aGEj'8&dF%&"VbX,$Mi`@P5%)J0X6SAH9Q[d"!,6I'bJXMJ!SZm,"!BNR&"X8U +mV#)YZ1J5,b[*#V(B2#mV5`TqF,i&-l`X%"-5F6PH9K!5iKV$ZRcll-kGH9%*-*5 +1AMmemB!bNCmqL!GRCK"5N4I06HHd["RG+V`X2Db3!!SX#S@9%K)GP,"hVLFHA#b +KLkb@-$m'P!S-q(433"HE+Tq,bKI2K@C+jmF9#ZFRb!X$3G&+`"'M,GQLpB+'#`f ++9J--2d%H0BYJi5M0KNCV1pKGNcG0Q3j8Qc8I9j!!1$hQd+X@!p!$Mb5&HF1qmmD +rT6p+JV,1+2%&h"XSG%c+kLed,,jFD+F3$6bb9ZKdJ[,F3+l3[R4BU%"5VmX@14Q +G,l%[JG@Hee[HI(L[k&BXE3fUNT5h80SqQ2*CC1ejeG*@!#SIA@#@)23!FT46q05 +N9X'"4bCTc-lC*KNb%&J)cr+f62$!``LI[k"ZP%M%JV,VZQLl'iUUr#FG[r$"QBE +c+i1e@Yf-8RG$RG*PlAmp'ITH6hcKp35@AqqkT[4f&epmZBY1[pZ&e9lGefmZ[[, +UI+qjX-+V`lbqh'j4N3heSU-fHp0-hZaQkm+DBE6rTTPfUqL@Ll,e6'bpjhT0YG& +Si4Df-@qdXl'YPD#)fN5ASQ"BfC!!@b2+49$fr05C$BV-CYAQ,CHfLNDYIjTellC +@K[TPKHZVDjpD[rbLfMRpP-,'#FN``9k)8CR0reLZZIIN-Z8)AJ&6R01)1AD0M'r +CCKBEQeNT*l,Z[SK-Aj!!*&ClZC6DFqXTPC&Y3q-E&KV!aXAl`5D9D[(!@29LYhE +c[4ZVdrPLaIeQm,0kpA34UI+C4V2PbfcX%PRA@m`aPG%%jc)@RZ&D)p13!,'fNiF +PZciINNP$Gq4$-QQSBMl%KjA$"j1QA-d,9ZIj92&#T)0bUH,&5!GYU-lN*IXb3AI +N"9eYeLE(81p)cZUNM%dF+V*S`HH(G(ppEEdJ*TZ)!J8af858*iM*@jAi26lc`[V +pH*X+5SANE8dLk`Jm8LhUH@GG4$6hhh2-cF&q)U-Rr-5FG5f`'a[$JfAD&,Th(iD +$iL0FE40AA@[(k0TE+j[bDZ%i8+lmX4GRHb!H@BT,i(iL@5`N8b9dX%20GBG)35Q +*)`[9$V06HcNZN@kKFM91p-ck`bf6CJ@C[LQ&ji2&HL5blZ#&Q$ji!F$KFq[YrU* +66*FAqrah3e&`FDaDCa9)Fh'S8mYMT1'GjYq0+2EHcHe'F(ecLi[EZr8'IfmU0ED +Mh1`TVQahqAqXHf@CB%marC3,`rpMeHeFl-eh0+TG(h1Xb(06APr[qVGlS5VfCPr +jekY,pd*KZJp@aZE`8NPYZ,,&k9kS6RFX6hH[2Yd(#p4pX%)Q`LX4&ek0ZRY&kMj +BTHjBTKZVHmSiqHmpfUZ([6K3RHjdChIX)0CFlDfA98X%FHG&QBY$jFYL&h%3-E- +,92&)8)RPdS(0NIb+HJHTLCFPlVc+QKKhBGj&!ab0&A"h8S"i+@bP[2ViY6*iF+M +9f0kD+pXJGV82@H1'SUaAr-VGQ2caUpZEpEP'2E4,iLjfCC)PlZblVbX,',mbL'A ++[@Hfk*5[L&qj'pX#lST'1TbcFkrA8pk9Zr(H*9IQ"Nb3!##j1Pc8Qpfb4q-hZeU +c"@`cNGS2L6@0LdQ8aBAijABaLAC*[-C9a)A%X-i&a-!Q8j98S@*3NkP+)X6[c8a +9dQ8R`'*c)NlZ$AqjP$&%2f-m*,8MYL8ImHZNBZd(`dr@6lB[hh'`X0!F`kRNJGh +ha1i*4(N1"Eqq,&Xk9bEq-(6V)&U$Akp%61`Ud@'*Q)6Fl"A-A@l)ZaYDphC"2)3 +E#)VI2BQBj'#TpkciYHQbJke!3e*A4pZ0ZL3QF4@V51)PANI0T+95!6C$3XG1*,H +j2'S%lh)APY6k!1%&q"#BM["ca&Sj'4$,kEGP1Q*IPM[KZQF([54hA#9kbBp2"AQ +*BPG"q,kib(YLr$@lfAYfr3YrMMFcZjZDedh1k'EQj6+@X9NhdB5cTKYP5mrGTQG +YCEif2RbAmR2-'#HQ"eLcIS+q-@$@#6(K#ZJF$K-1II%Te$flUX9-p4"T@8Z)DC& +i5*iLq5hU3V,FbQpc&j*P*$Rb%qIEQHFR8k6BQ'-mlMV,i(,X+8r&mTc4alTXL%P +mY&Fc3G&dK%NV%I&H-h#qDblm0kK1#KI"K4GLmL0XT9iN%BA*Xm+mQ%'b'jTA,$i +L&R"J@X3i8K*kpm"ib!'(*2CFAK-824DH[!qQGA)61SQTR0#a5Cc3KUq*A@,VbSf +RSb`-fl*dh*Ehhq'c#q5#"k&[J*!!`)1'J!IGpDXkZiUJ+R4RJHQ'XH'"q9[(AXZ ++QF&M4H[jHE'R`d#A'FbrVR!fRm'1ZdTpfNb`l3Nbfej'4+qVjF85BfL4i!Ierid +(4X)00k-,#6aJ(ra6H""f4Ki6H+!#(RJ1,EHhRAS2Ba1A%RMJk3FKE!K3a!0lUE- +60l@`GHVlkXE'*ST(ASfk[AYife4rifLHR#e$kV[hi$[Z1[U1[*P$pKfH"D3hCeE +i4Je16)`q8[PV19HhfrpCpbIHXAEmQMh(mKJI&!TEbl'fdAPiH1Rd1cE[,REdFcj +6elEbV@[A,`h3(cXR0`mY$I!1Lc$AlcU+-,i,6qpRhh(6p*&hj,e*NPm-1IGeCai +"%IZ1r8HlqR6IK``JqB([`8Hm(J-F"6HNlliM&)"CA$ib86RfeX%qSqr0,1Ak4pl +"YlFe2IY)Mi',eMdM&1!GI(1Q'`aVrV#ZpKhlUppMThEZLRHB!G`IpePff$[cG5d +p`5KlaNB[2TBRl8C@V2b1dBH4kV[[#!eJJYX[h[KI#*bb95Ym1dCEfjF'U%G)"6- +G`2+NY9cY(E21A5VJ(Id&qIYhe)$mIlpMN!!422'1'qD1&Z68&cDJ*2b`le&X3JB +8J)(Z5,ND9[[M-#iB)3([f(1N3`El)elA2EZqMBarril$4pMlB&eMl`J28%L1jMZ +A#-#c8!#P*Aa#f6LkUr%`AdalFKBq()A#!Gl"0iFQHDDZ1`kqidG0B[@'q$i%a54 +$PTj35%*101A`!!BA+U'pKLXJqHN[krH8q5BYqD%*QY,f9[jT6E$bMR#6kC!!Tc5 +iFRGm6i-lmBiR0EJ6lhK5Jc[jMLFdZ-&hK&*SF29lEpR2"&iNHrc@ekeF1hBUpar +)([r'IGRM2RA0SET1ZR9p0VlbcK9hR2abiq[hhPCEU%F)J`CADE5R0EM"GcbT`I8 +qi`FDh)Ph2+A"&4m54U$"pHF3rr16l`J&B0bBV!r@,'[%R[p#2l5m-U"p6mZV-TQ +`!#f[jb%T3VlfSG%YNipd%%`RI'+k+$aJ+LMXC(VQeU--cKKh-VNApr*-I6'Q%ci +aK@-mYhq-DGilISM!XHQCJ5QF[kY(q-hdc,'P!(`kc@)j#bqX,+k#NrP'ISF4Q)I +81[ST4R$L(8mbJK2[H",*6llM#53II%Gi!*+(,mc6pGBec''HVY*S6c1#`AFmb3K +kRr%$4R$L(8pTHF@(a0ia)$1CGpL0P%lJd*(m5*raL"Xk8C6SHdFSJ*E(&b)`,mC ++'08[SGK8%Gqmip$fhGpqarEYZapqKdc[XkCANF)0r4p[&I1+5Sjrm&DT[H2dY-U +J@Ka#-+hb)`q5'00j`S1NeKrK!@Vk2hKeP1[a2Dq1@Pe2UpHRqjl[5Bq0@MhX1jl +`aULp3hCeUJc#G5cj-3IR&6LSr02UGH8Gi44cF%pTAP5eGl,K(c@[%qpi8[-kmBi +R0Dq6lhK#maTm4hM!r0T6@P9[2@)-lLP0TrFG2p"d"YpaNJP@J&@qN!!+Pk4`!#d +QYAA!d%H")&X(0#DRj0$6,l@HR,H1BmM+&`ShJf5r-lL,$65L0chhr0,pHY+CFbZ +ZZI[*h+r+6RrarZa(VQXFUZ[%keGRQfjrdiTRAhfAmG'EUTpCU-FCIm8''Xr80Fc +"YIS-h@8$M4#iVfGbC2LdN5BDpX'm@aQHDcGDaAGpIcI"38KVZ%MSLPeUD-cA-($ +5l-D4UHc!THH(!'-frrR*Di1rG$IFDHRXXJ22I%Efm4qmZ[0f3LEdEFa1(K[HY!@ +RSHZRUS@Z-IG06Qeq)[F268b8cPV[f&b[UISm@XflSXU(L8H2qhLl++Fm2VHK86A +[ekH3!&(-rmHCa$LDpI@GY,jS`BM9MkjBj+(4HVD+[pH8GrZc-rRlKM,`hZb(q2H +0XQDcpF&@*j9hFl+ePDc[CmUlml+RmHr&-4p@qQq2GjZcl14ha#IZjY6Bjr,C!*! +!0A`-k,lrlHYffqX'"P5ejh4QQrhXiM'A)BZpXp2GcX$ZfTk"#rS[')$*(afSYZX +$5j)dJ%CS-+"SIk%[hmJe3q2VKpG8eU`IR"VNlik4SDNe5kXd3#-l*hKI$![-mN- +)KrZP60k1-d@B-(P'm2H@P+HG[lHQ2#2jHc$PkH6[SC4R&(m2Tca`cpY5RM(m2C, +bM1A[dC4R%Rr[6(NQmrHZP!ISZMrPJ5rAaccQUTaR0F&e+Fp'JTY5RNebq90jc)b +`1M(PkH([JC4R'hr[5AQB+AX6JS'(Kj8mGa2HN!$HFar"Be1HPa!m-Z9jJ1#1P1H +Pr,dqeI&"`M[6Hhk+i#NTcrd%Mcq@j``)i8[YF0EbD"*NKl2UAJ'KTamlR1'D9E2 +,$MIj3Z0QN!$1j#jf1(ZQVQ%11bHFD96XF&DrpjEpj4k9NlHqEZADX91jrd$fq$I +ZbalhU@X1eAA5VHZcmC9hVVMMj*FEAlrhYYT#2Fk-AhBiLpiA&3kd#FXePhHkeBI +dZ*!!K)qp3N*N2SYTCb!)fmVpMiq'!,D9q`UEbrREbRhQCVH91qBfF'(UfmU&ebJ +-pGRb93GYp@FLe*jcIiS,iaI#8"Zeq1T`Z@hckS'!8"JT[2NHk$E6p(RS([c#"k! +pqCC,qUlY1h%C5mkj,k5JCbZ2!L8F8X6%N!"5eH`3'cQLkdF[f6DpTekE+&UlYdi +bZK*G%U"`q[jKM[pAm1+kK6fFQcLhFDlLA-fjNA-,jpfFScR(F)lPR-3jQA-8CbG +R1fFEj`M1NC`c1'rK[)rc*C`2F,k8md&i01XDARCX,6b6Kh80RjhbG2$hmT5(G3f +[6(PBer#UP!IalHU8Kh80VdPj@0I`fT4R((q[5hPBer$'P!FamUD8"ijiAmV$91c +V8KkceQ(NG5N2`emReL%dHFckKj%hT$aQrF2)De)Hl%9HQ2+`rZ%9+3rV(cirjB( +aI#EPH5(KSe1H&r(h$5Q2@4-aFPh+BpBV2,R@SFPMeMp8I5N2DbGf(FYcjSh`SA2 +!$H&pjQcRl1$Xj"c&1CTcM*`I2JpAKiI$XH(2F'0i,j`@[JSAK4I#qH"cF$9iQ19 +BU686KckD"&NcXES19HMTjiEU&erdX,0`@-NA#MH$C,m`932+-&V$Y-B!KXm`2XY +d3L(S6ZScQaX0f65qDA"XZ(pifcG`hNlH@[CVrXMrV*d4,hRb`C%$R(rqD1jLEG2 +S6Fmp[p3"*jdjYq+DZjr-rDVXp"I[chlNZXDKZNkmIR@fkIBhVAMfeAFC(lfTqTQ +&HTca9kaYqNaG`aa@[6XMGeREp!`%BCR0,5b`bFFbQlZZ[AHCcBh2F*R0SfmR*,a +NQFd`Qp8G)kG2GQYZmm,-c0&@)lp[QM@ffCieRq+NdbllNb83DK0HYlTM+!`'K-4 +mBET,iRA'T461l"1B8qN,SpMX08aJ1BNcq35qH(+YNc2["8BCEX)+``MH-j(c#h& +$V5r'kGqrF#mpmhdTX[-[Pa[c4V)[aXlkDScrbh#[IMM'I5h'ICeYfIRqUTaBMQ4 +ha[ar(E[UEf+qEf52+IrrEAcR0m0rY6UqkqciIhVm2b2Qr9CmclGMh-3BpeKmrq1 +aMYm*HEb1#G9P8Q&RAi`(0@qmZ$AEV'%T9NaNA38`46*XLSdP[c1rG@66qZCXB`N +!"l,3d!r"+DA6%f#$E(4LU6FAP2P#!0Ce-kqUVrDhC[r[%H"mcf$T31-@KJSGk*2 +HZc1lK1q-*81&5Ba0Kq'S-'Gf#9p)mIa,b)ZbmVekrYqlm,E[c(3"!cc"4B`(*55 +FaVR90SPDJ3fI$!,92Y4HqDVf`#@a+a`#&d*PqMl4UfG5%MJCl`SDZCd6Kfq'mh( +%EZ$%+4ZAl$'FZ(@c-eJ(j`M1PSJ&Z(HhFJlPC0q`8C`iGSrN(-[Cb6PZ+BIb[Qf +1lESL-jhZi9hIM[eUPUdf,MdK1KERmk('(6cF*M2j-j1iQqm0Dq"p)q2lkQlV"AD +r`VE`hZI(+4E5Uir[mq0QdLI0qfHkjHD1#D4U)&rN,Z,BBM)4erK-rR60G$Z(mc@ +k$CV8bArIX"qMc@I2Y$Z(ihEF4)[[RHRZ2&bR4VCDLjc+ZkPhiRe0lqI2Vmed'ke +liaEZ*IqULG&10e[q"AGIQacL1Rq$2h2+AGEU2[3HlXi,F3HI$p4X#R([(65(&cI +bAm8J,qjAAX$Gh""hP(k0V!jahcR("T2hI8aFmZ)qi@k$bf+q4rRc8"NAIHSRZ9X +Hqjlpe6D(I!ql41D+%0IbjX9q5K#ECc1('1[,4&bcZ9eI*Z)Dpbhf65+ZjAf,IC1 +)fr2V[IlirFZiNeeqphbdeam(a9AC$(1IQ#Vpm4XIjUiRa"e`efhTM`FrapeP-Hj +RH[eal58@91*H[G!IGDqmNl[,Ber5Rejr4+IXb5Y#A)Fpj08TqT+riNj`m"G@,p3 +THVUB)CZUYPqd8+IS#phD8RC,I35mP$T&Alk&ZcXLlKVmN!!k45rl-qi-2YKm2pI +Vil2&0[+$kp4'k[4+0d58h9mll$q[6[T*Rq)12+&pIRDK6VV2A[pfL"[bSB8kkCF +kFrTBL*Yaad+Gp-@rc0hMXBrT6kp1H[LVh*PGk[L@[R1K6ZV2k5d(MGeLQeFRYCq +P&Kh$(Q+0Qd,rIH9hL9XCFAU5A-UVklV2%bFlZcA*2b6IPrqCZ+YM(*[SHIRUAJY +h8qAZGbD1hHfmI0'9p*EbAB5mTjI[VKF6*cMG4"p,(far#RdJHq"&6KBc[,KYY3Z +)Hh1Xhk[i-cA8pHh'I65q!kiRrG&XAF&R)2'qKIl3,`*Ve0q%Z+%Z-1ReKci$6U6 +q0[)!qY*lRck0RPIr&2[l&EhhcB5R+V',IUAZdRm["`m82@*j#FZmbIZ@`@r99b* +1rc*raT9aNAH!P9VqDm,(mGDfDd2FErdLFI"Gmld+rY%3qLEb02L`PYqDI,2Jah0 +[$A&AITBiq+lj4T!!3adIiUk&HfKj-Hrq2B[VaGh`am5"lF4pDU'ZN5IF5KbFQcJ +ifA$MMXrrfpR%JIrJUhQ61LlNqp3r%LFFZdQHXc,%(3*lY([rm3lUEYpKS28"iLC +%r[3R[%0f$A`aNp[DA4piKmNK1"(jrp4'4r`B$BG6TiDii@ka*rJa",i5Z6$%IC' +HeR'Rf(fmThiLe1qVD!Mk#5(ZY@q&,lD(I!rF6Gc8%0FU"lSqa+hm#q+Q44b#-bd +*F4I6NeUmSNlS&F0Lhm`Qc[5)M3-RT-q@fdr6Babm6ITXrkZ*NfA[4UTcr(D)H`p +[dq+YqFj'$e"RKEK4p,D@Hj)2h(mia!eP0d)0[lCi4RpErR&mrN[`84ehqecm,Zk +NRbDq4#iZIB-Z)6Md+*a@"hkXR[A&(Jlp+9a,"hkXpVb`Kd26fDT9"hkXpY+[$SI +Qd%-kEUJi(plTF1J&Vb,1B,AY*lLAp-HGRb"Z3Dc(bhVpd3'2e%q*G@9h4-'26R" +D2cA%E8,RF$Kd%Ea(Xd1LlH0hpA$SCA"F(IF5(UDZ*1qiiUA%A4$L0X06(3jp4*b +!2e)RH+h8qe*Lp)q(Z0Ir83q(ERdpFD)(Y)Q$JN-cl$p2$e$Ai4cLiC!!@9'$r[$ +d!(8pQaFk(2ShD"XkkJ&M`"k(3epq*A(#cpVNiB*$M@#"M[bXaIF,$Mh(ZSTr3E[ +i+(dfrAELi)1d'$a-qZc2i-BkEPSl(ClUF1Kcm%XGYdImHIL3!-1KYlfE10Q%GXQ +024cDLGDLikSI(El(im'4#ATBK`eXe9XqeX1Kc3HiJpp42rLcdcqmc6PX[VGm'Fc +m303riR'40kZ2I6VU(iQi$KeDR2i4Mp1VA(GiAp3r%[R'LSq#IbhL)VU@HIH[`9m +GrVd@(Up(3Yb(U+Z(ImIRri%lc@k5a2hqTKlqADA@*6V+'cl6`lpAQdpdP!jjTr6 +P#ML%MMV+-(QGlF[MmhI"QcA[XR@LVi5(I84H*AZd[J9mF[MhN!$i,FXr,j!![`V +qAB9fSXXG+mdlf#YIm1qem'1p1G6[@q#T`lqAL+qbIhi,f1EKhr(j[r`)FHKA*Y9 +MD+`1rqTrMMM`h(a,h5&6m'mY'S'@6jP8Mm2I(!rl@lL3!0iDqV*1(9,`le+iVik +kdI9I1SKraqFr)$m6h@L2pE,iGhcqGM"H4peS*(c&iGp9k-3kkNB,ZA0pGJ303$m +RpJ&i)(hfQ(Km9BKlUhJLq(H*20[61I4ap+Z(ImIRhb0HHMU(2PiG3["[S4a,&SF +p+Mm8([B&qEfhEV-q!9cfm1rir#I4)(6Fd,VeAaEa,llITPi&$fLk,H*I)Zj4GCc +24[b,ad9'hD$@i9mLhbKU%m1r4,iMERlTi9rG(iKcKYq4Ec3mAr![qMbd62fL%$I +M,3[mVqjkZ)F15f[VTi'TJRpe0mK6Aa$LKS"hJRr4Xq`ESrPBR(MP3Pp'XlmMcQ# +[VCr*iI6#0m+9pG8acR!D`DhSFm3RlXhI&R"+m#pk$KLKeAQS+hUKKhr4&k$&k*G +&r%"AN!"hX$QT$MU62NqYb-1rZLqK9HMr&h%DMG29qeH*)cqdefJcJRr4R`!l0$c +8pMhij1&Ip!`d"5fI0Arh`Q@&rp@pPEN'$DFMEYk[,H"Ih4[T-Id,i4e[**r`[qK +b0!r0HrRHl2XprKGYJR&DcC0hdbFHrNA24[[3kUl`*(L&p0RH$a,h81`$F%[dc[2 +3ZE@m$lS06RMi&jeKGe-0CbGZ2ca@q&rGAm1400S&FEI)%ccmLfk&BfYe$qU%rLf +kmLr"bEAp6MkMK`VrUrX!ZE9e-(m2fK1HAKKj#4LQj4hQlf&Q1qSLRhL1ld!,jAe +SXCiq&aN&Fl9kX[NHNFm,hSpr'h(SYm6"ai6RAI%QiPi6hMId$rRRkAD4[@J6@Th +Ir$hI2[0dZmLBZSlT8q+1bVfN6S[S#DhHDrlH$MpdGET'r[(kq!jd5DR6@,LG9Qq +(ek+h5CfDj8RHRUakcXehT%j[KPYVDQAMk$HTdb'iR9C$0Rr[kZQ,NBYqM`"2(p9 +AbKfP6K2JkYSj#22hERLfUe1RrIe`L,Z(A[(UC2LCd@)d1'rj4a`r)Um'1c5kQFh +h"ldkGGe-!2Q*-jcHeHQ2k@hY,!Ed!Aj[kh4mrJjjfb-alS1p1Vd0E8@(29reci0 +9VNl23S28kY[d2Ea3k[40Z,j@4b81RLae@Lm2"XISEhLMe1R6B)%11mAUUpACT8k +[&+F0YK2h)R&@qZNAdBVdlm3q0K`dFXS-HjV(Z40apkR(I@QQHYr'fir)JcfFDhi +E'V5'Aj!!lhki8AfSGr-Pe%kMT4$h-R6+ZX!2QRm*,926bm3pf01IQYk2VUc9YBL +MRlak0rmQ'V4fYS8iH-A9)@kRZLNk$h(`L6H'Z!I%!h!2qN#pjAh[rJ)"4YHbF3C +2ACeZG6NKG"jJhf#'e+RTYp'U0"SbFDp5(jGk2b`rH(q-3kH81Xf#NqL`DDaq[EU +fe1P+HPZr0mBaKq(9UHNVmM0i",#2VLh[Hm"h'pb`F8E2P6SeI36Xdmie!0HQ,ed +rrD5D%r-[`#pp)rAq1*U)GTk)12LN9kHQVm)9p3GL($c%Ue26qq3I[a[MQ,f3!$T +p5pd4[3iHKQiZGCU#4U$9Bi(hH$mel9HI0[K'h-1pIQVq@IX!hBCh`0qN6Tm8bm& +Em!bq,rh8U2i02`9qk6qTdjqM9@Zd'Z,HUZiMIIm+Z)K@*`GqdF'ppcAHBTfBU5% +1r9IH[3*ZS1NG'iIZ+A'2q1k24(k*VL&a9cPRi-eKk0qbYlbjMBEIK`2V-)HKhiP +1*('0Tk(Yk6#(SGmPGjGmAd-ld'%13pmJYjDicm*&0&SaFEr1ZpAji4hhUQ-C$B' +iGpJhZd2F,(NB1J"aCMBLmUS3plKkkLG#h$["!q(aM4H+LfBHMEKh`IrGqckYR[( +*%2GZF9EHph*a&ai(c$+(+1qE3UpUjKTXR1'"lRdcl32$PBKl,rc%[HpCkVl-#J' +rr*IhVD8(p+G$h2[8YH9pCm%4p5dacZ#1Hpm'iicH50a[dJrZIBqTVe0ri*Fj5RR +I+p&H0E-*0Jlp5plh#E"!bq1)-h0)lRd2b*rXM0lr"`#3!edP!!!: diff --git a/macos/osdep.h b/macos/osdep.h new file mode 100644 index 0000000..5a69033 --- /dev/null +++ b/macos/osdep.h @@ -0,0 +1,118 @@ +/* + Copyright (c) 1990-2007 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#ifndef __MACOS_OSDEP_H +#define __MACOS_OSDEP_H 1 + +#ifndef MACOS +# define MACOS +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "unixlike.h" +#include "macglob.h" + +#define NO_MKTEMP 1 +#define PASSWD_FROM_STDIN 1 +#define NO_SYMLINKS 1 + +#define USE_ZIPMAIN 1 + +#define USE_CASE_MAP 1 /* case_map is used to ignore case in comparisons */ + + + + +/* +#define DEBUG_TIME + */ + +#if (!defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME)) +# define USE_EF_UT_TIME +#endif + +#undef IZ_CHECK_TZ + +#ifndef ZP_NEED_MEMCOMPR +# define ZP_NEED_MEMCOMPR +#endif + + +#define EXDEV 18 + +#define PATHCUT ':' + + +/* file operations use "b" for binary */ +#define FOPR "rb" +#define FOPM "r+b" +#define FOPW "wb" + +/* +#define DEBUG +*/ + +/* These functions are defined as a macro instead of a function. +so we have to undefine them for replacing (see printf.c) */ +#undef getc +#undef getchar +#undef putchar + + + +void setfiletype(char *file, unsigned long Creator, unsigned long Type); + +char *GetZipVersionsInfo(void); +char *GetZipVersionLocal(void); +char *GetZipCopyright(void); + +void InitAllVars(void); + +void PrintFileInfo(void); + + + +int fprintf(FILE *file, const char *format, ...); +int printf(const char *format, ...); +void perror(const char *parm1); +int macgetch(void); + + +int MacOpen(const char *path,int oflag,...); +FILE *MacFopen(const char *path,const char *mode); +#define fopen(path, mode) MacFopen(path, mode) +#define open(path, oflag) MacOpen(path, oflag) + + +char *GetComment(char *filename); +int readlink(char *path, char *buf, int size); + +void PrintStatProgress(char *msg); +void InformProgress(const long progressMax, const long progressSoFar ); +void ShowCounter(Boolean reset); +void leftStatusString(char *status); + + + + +#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \ + procname(n, 1)) + +#endif /* __MACOS_OSDEP_H */ diff --git a/macos/readme.1st b/macos/readme.1st new file mode 100644 index 0000000..6182756 --- /dev/null +++ b/macos/readme.1st @@ -0,0 +1,16 @@ +This port is for Mac versions before Mac OS X. As Mac OS X is build on Unix, +use the Unix port for Mac OS X. - 7 June 2008 + + +Before you start: + +Extract "*.hqx" and "source:*.hqx" first and read the Readme.txt. + +The resource file and the compiler project files are in BinHex form because +they contain Macintosh resource forks and as such can not be simply +stored a normal file on a non-Macintosh system. BinHex form is the +traditional way for transferring such files via non-Macintosh systems. +It's also the safest since it uses only printable characters. The ".hqx" +files must be converted with StuffitExpander or BinHex 4.0 (or equivalent) +on a Macintosh system before using them. + diff --git a/macos/source/VolWarn.h b/macos/source/VolWarn.h new file mode 100644 index 0000000..2d921eb --- /dev/null +++ b/macos/source/VolWarn.h @@ -0,0 +1,69 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/* + +This is an Important note about pathnames + +*/ + +static char DuplicVolumeNote[] = { + "\rIMPORTANT NOTE:" \ + "\r" \ + "\r This port has one weak point: It is based on pathnames !! " \ + "\r Because it's a port !! Unlike MacOS: As far as I know all other "\ + "\r Operatingsystems (eg.: Unix, DOS, OS/2, ...) are based on pathnames" \ + "\r " \ + /* a short quote from "Inside Macintintosh, Files"; slightly modified by me */ + "\r On a Mac: Files and directories located in the same directory " \ + "\r must all have unique names. However, there is no requirement " \ + "\r that volumes have unique names. It is perfectly acceptable for two mounted" \ + "\r volumes to have the same name. This is one reason why a application should " \ + "\r use volume reference numbers rather than volume names to specify volumes," \ + "\r but for this Zip-Port I can't use reference numbers. " \ + "\r " \ + /* end quote */ + "\r" \ + "\r From the developers point of view:"\ + "\r The use of pathnames, however, is highly discouraged. If the user changes"\ + "\r names or moves things around, they are worthless." \ + "\r Full pathnames are particularly unreliable as a means of identifying files," \ + "\r directories or volumes within your application," \ + "\r for two primary reasons:" \ + "\r" \ + "\r* The user can change the name of any element in the path at" \ + "\r virtually any time." \ + "\r* Volume names on the Macintosh are *not* unique. Multiple" \ + "\r mounted volumes can have the same name. For this reason, the use of" \ + "\r a full pathname to identify a specific volume may not produce the" \ + "\r results you expect. If more than one volume has the same name and" \ + "\r a full pathname is used, the File Manager currently uses the first" \ + "\r mounted volume it finds with a matching name in the volume queue." \ + "\r" \ + "\r" \ + "\r The main reason is that an attempt to implement support exact saving of" \ + "\r the MacOS specific internal file-structures would require a throughout" \ + "\r rewrite of major parts of shared code, probably sacrifying compatibility" \ + "\r with other systems." \ + "\r I have no solution at the moment. The port will just warn you if you try" \ + "\r zip from / to a volume which has a duplicate name." \ + "\r MacZip has problems to find the archives and files." \ + "\r" \ + "\r" \ + "\r ... and the moral of this story:" \ + "\r" \ + "\r Don't mount multiple volumes with the same " \ + "\r name while zip/unzip is running" \ + "\r and "\ + "\r My (Big) recommendation: Name all your volumes with a unique name "\ + "\r (e.g: add a space character to the name) and" \ + "\r MacZip will run without any problem." \ + "\r" \ + "\r" \ + "\r Dirk Haase" \ + }; diff --git a/macos/source/charmap.h b/macos/source/charmap.h new file mode 100644 index 0000000..5656b63 --- /dev/null +++ b/macos/source/charmap.h @@ -0,0 +1,380 @@ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#ifndef __macos_charmap_h +#define __macos_charmap_h + +/* + +Conversion table from MacOS Roman to +"Western Europe & America" Windows codepage 1252 + + Notes on Mac OS Roman: + ---------------------- + + Mac OS Roman character set is used for at least the following Mac OS + localizations: U.S., British, Canadian French, French, Swiss + French, German, Swiss German, Italian, Swiss Italian, Dutch, + Swedish, Norwegian, Danish, Finnish, Spanish, Catalan, + Portuguese, Brazilian, and the default International system. + + Not every char of the charset MacRoman has their equivalent + in Windows CodePage1252. + To make the mapping in most cases possible, I choosed + most similar chars or at least the BULLET. Chars that + do not have a direct match are marked with '***' + + The Windows codepage 1252 contains the ISO 8859-1 "Latin 1" codepage, + with some additional printable characters in the range (0x80 - 0x9F), + that is reserved to control codes in the ISO 8859-1 character table. + +In all Mac OS encodings, character codes 0x00-0x7F are identical to ASCII + +*/ + + + +ZCONST unsigned char MacRoman_to_WinCP1252[128] = { +/* Win CP1252 UniCode UniCode Names */ + 0xC4 , /* 0x00C4 #LATIN CAPITAL LETTER A WITH DIAERESIS */ + 0xC5 , /* 0x00C5 #LATIN CAPITAL LETTER A WITH RING ABOVE */ + 0xC7 , /* 0x00C7 #LATIN CAPITAL LETTER C WITH CEDILLA */ + 0xC9 , /* 0x00C9 #LATIN CAPITAL LETTER E WITH ACUTE */ + 0xD1 , /* 0x00D1 #LATIN CAPITAL LETTER N WITH TILDE */ + 0xD6 , /* 0x00D6 #LATIN CAPITAL LETTER O WITH DIAERESIS */ + 0xDC , /* 0x00DC #LATIN CAPITAL LETTER U WITH DIAERESIS */ + 0xE1 , /* 0x00E1 #LATIN SMALL LETTER A WITH ACUTE */ + 0xE0 , /* 0x00E0 #LATIN SMALL LETTER A WITH GRAVE */ + 0xE2 , /* 0x00E2 #LATIN SMALL LETTER A WITH CIRCUMFLEX */ + 0xE4 , /* 0x00E4 #LATIN SMALL LETTER A WITH DIAERESIS */ + 0xE3 , /* 0x00E3 #LATIN SMALL LETTER A WITH TILDE */ + 0xE5 , /* 0x00E5 #LATIN SMALL LETTER A WITH RING ABOVE */ + 0xE7 , /* 0x00E7 #LATIN SMALL LETTER C WITH CEDILLA */ + 0xE9 , /* 0x00E9 #LATIN SMALL LETTER E WITH ACUTE */ + 0xE8 , /* 0x00E8 #LATIN SMALL LETTER E WITH GRAVE */ + 0xEA , /* 0x00EA #LATIN SMALL LETTER E WITH CIRCUMFLEX */ + 0xEB , /* 0x00EB #LATIN SMALL LETTER E WITH DIAERESIS */ + 0xED , /* 0x00ED #LATIN SMALL LETTER I WITH ACUTE */ + 0xEC , /* 0x00EC #LATIN SMALL LETTER I WITH GRAVE */ + 0xEE , /* 0x00EE #LATIN SMALL LETTER I WITH CIRCUMFLEX */ + 0xEF , /* 0x00EF #LATIN SMALL LETTER I WITH DIAERESIS */ + 0xF1 , /* 0x00F1 #LATIN SMALL LETTER N WITH TILDE */ + 0xF3 , /* 0x00F3 #LATIN SMALL LETTER O WITH ACUTE */ + 0xF2 , /* 0x00F2 #LATIN SMALL LETTER O WITH GRAVE */ + 0xF4 , /* 0x00F4 #LATIN SMALL LETTER O WITH CIRCUMFLEX */ + 0xF6 , /* 0x00F6 #LATIN SMALL LETTER O WITH DIAERESIS */ + 0xF5 , /* 0x00F5 #LATIN SMALL LETTER O WITH TILDE */ + 0xFA , /* 0x00FA #LATIN SMALL LETTER U WITH ACUTE */ + 0xF9 , /* 0x00F9 #LATIN SMALL LETTER U WITH GRAVE */ + 0xFB , /* 0x00FB #LATIN SMALL LETTER U WITH CIRCUMFLEX */ + 0xFC , /* 0x00FC #LATIN SMALL LETTER U WITH DIAERESIS */ + 0x86 , /* 0x2020 #DAGGER */ + 0xB0 , /* 0x00B0 #DEGREE SIGN */ + 0xA2 , /* 0x00A2 #CENT SIGN */ + 0xA3 , /* 0x00A3 #POUND SIGN */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 #BULLET */ + 0xB6 , /* 0x00B6 #PILCROW SIGN */ + 0xDF , /* 0x00DF #LATIN SMALL LETTER SHARP S */ + 0xAE , /* 0x00AE #REGISTERED SIGN */ + 0xA9 , /* 0x00A9 #COPYRIGHT SIGN */ + 0x99 , /* 0x2122 #TRADE MARK SIGN */ + 0xB4 , /* 0x00B4 #ACUTE ACCENT */ + 0xA8 , /* 0x00A8 #DIAERESIS */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xC6 , /* 0x00C6 #LATIN CAPITAL LETTER AE */ + 0xD8 , /* 0x00D8 #LATIN CAPITAL LETTER O WITH STROKE */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xB1 , /* 0x00B1 #PLUS-MINUS SIGN */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x00A5 #YEN SIGN */ + 0xB5 , /* 0x00B5 #MICRO SIGN */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xAA , /* 0x00AA #FEMININE ORDINAL INDICATOR */ + 0xBA , /* 0x00BA #MASCULINE ORDINAL INDICATOR */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xE6 , /* 0x00E6 #LATIN SMALL LETTER AE */ + 0xF8 , /* 0x00F8 #LATIN SMALL LETTER O WITH STROKE */ + 0xBF , /* 0x00BF #INVERTED QUESTION MARK */ + 0xA1 , /* 0x00A1 #INVERTED EXCLAMATION MARK */ + 0xAC , /* 0x00AC #NOT SIGN */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x83 , /* 0x0192 #LATIN SMALL LETTER F WITH HOOK */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xAB , /* 0x00AB #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ + 0xBB , /* 0x00BB #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ + 0x85 , /* 0x2026 #HORIZONTAL ELLIPSIS */ + 0xA0 , /* 0x00A0 #NO-BREAK SPACE */ + 0xC0 , /* 0x00C0 #LATIN CAPITAL LETTER A WITH GRAVE */ + 0xC3 , /* 0x00C3 #LATIN CAPITAL LETTER A WITH TILDE */ + 0xD5 , /* 0x00D5 #LATIN CAPITAL LETTER O WITH TILDE */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x96 , /* 0x2013 #EN DASH */ + 0x97 , /* 0x2014 #EM DASH */ + 0x93 , /* 0x201C #LEFT DOUBLE QUOTATION MARK */ + 0x94 , /* 0x201D #RIGHT DOUBLE QUOTATION MARK */ + 0x91 , /* 0x2018 #LEFT SINGLE QUOTATION MARK */ + 0x92 , /* 0x2019 #RIGHT SINGLE QUOTATION MARK */ + 0xF7 , /* 0x00F7 #DIVISION SIGN */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xFF , /* 0x00FF #LATIN SMALL LETTER Y WITH DIAERESIS */ + 0x9F , /* 0x0178 #LATIN CAPITAL LETTER Y WITH DIAERESIS */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xA4 , /* 0x00A4 #CURRENCY SIGN */ + 0x8B , /* 0x2039 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK */ + 0x9B , /* 0x203A #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x87 , /* 0x2021 #DOUBLE DAGGER */ + 0xB7 , /* 0x00B7 #MIDDLE DOT */ + 0x82 , /* 0x201A #SINGLE LOW-9 QUOTATION MARK */ + 0x84 , /* 0x201E #DOUBLE LOW-9 QUOTATION MARK */ + 0x89 , /* 0x2030 #PER MILLE SIGN */ + 0xC2 , /* 0x00C2 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ + 0xCA , /* 0x00CA #LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ + 0xC1 , /* 0x00C1 #LATIN CAPITAL LETTER A WITH ACUTE */ + 0xCB , /* 0x00CB #LATIN CAPITAL LETTER E WITH DIAERESIS */ + 0xC8 , /* 0x00C8 #LATIN CAPITAL LETTER E WITH GRAVE */ + 0xCD , /* 0x00CD #LATIN CAPITAL LETTER I WITH ACUTE */ + 0xCE , /* 0x00CE #LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ + 0xCF , /* 0x00CF #LATIN CAPITAL LETTER I WITH DIAERESIS */ + 0xCC , /* 0x00CC #LATIN CAPITAL LETTER I WITH GRAVE */ + 0xD3 , /* 0x00D3 #LATIN CAPITAL LETTER O WITH ACUTE */ + 0xD4 , /* 0x00D4 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xD2 , /* 0x00D2 #LATIN CAPITAL LETTER O WITH GRAVE */ + 0xDA , /* 0x00DA #LATIN CAPITAL LETTER U WITH ACUTE */ + 0xDB , /* 0x00DB #LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ + 0xD9 , /* 0x00D9 #LATIN CAPITAL LETTER U WITH GRAVE */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x88 , /* 0x02C6 #MODIFIER LETTER CIRCUMFLEX ACCENT */ + 0x98 , /* 0x02DC #SMALL TILDE */ + 0xAF , /* 0x00AF #MACRON */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0xB8 , /* 0x00B8 #CEDILLA */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 , /* 0x2022 # *** BULLET */ + 0x95 /* 0x2022 # *** BULLET */ + }; + + + +ZCONST unsigned char WinCP1252_to_MacRoman[128] = { +/* Mac Roman UniCode UniCode Names */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xE2 , /* 0x201A # SINGLE LOW-9 QUOTATION MARK */ + 0xC4 , /* 0x0192 # LATIN SMALL LETTER F WITH HOOK */ + 0xE3 , /* 0x201E # DOUBLE LOW-9 QUOTATION MARK */ + 0xC9 , /* 0x2026 # HORIZONTAL ELLIPSIS */ + 0xA0 , /* 0x2020 # DAGGER */ + 0xE0 , /* 0x2021 # DOUBLE DAGGER */ + 0xF6 , /* 0x02C6 # MODIFIER LETTER CIRCUMFLEX ACCENT */ + 0xE4 , /* 0x2030 # PER MILLE SIGN */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xDC , /* 0x2039 # SINGLE LEFT-POINTING ANGLE QUOTATION MARK */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xD4 , /* 0x2018 # LEFT SINGLE QUOTATION MARK */ + 0xD5 , /* 0x2019 # RIGHT SINGLE QUOTATION MARK */ + 0xD2 , /* 0x201C # LEFT DOUBLE QUOTATION MARK */ + 0xD3 , /* 0x201D # RIGHT DOUBLE QUOTATION MARK */ + 0xA5 , /* 0x2022 # BULLET */ + 0xD0 , /* 0x2013 # EN DASH */ + 0xD1 , /* 0x2014 # EM DASH */ + 0xF7 , /* 0x02DC # SMALL TILDE */ + 0xAA , /* 0x2122 # TRADE MARK SIGN */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xDD , /* 0x203A # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xD9 , /* 0x0178 # LATIN CAPITAL LETTER Y WITH DIAERESIS */ + 0xCA , /* 0x00A0 # NO-BREAK SPACE */ + 0xC1 , /* 0x00A1 # INVERTED EXCLAMATION MARK */ + 0xA2 , /* 0x00A2 # CENT SIGN */ + 0xA3 , /* 0x00A3 # POUND SIGN */ + 0xDB , /* 0x00A4 # CURRENCY SIGN */ + 0xB4 , /* 0x00A5 # YEN SIGN */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xAC , /* 0x00A8 # DIAERESIS */ + 0xA9 , /* 0x00A9 # COPYRIGHT SIGN */ + 0xBB , /* 0x00AA # FEMININE ORDINAL INDICATOR */ + 0xC7 , /* 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ + 0xC2 , /* 0x00AC # NOT SIGN */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA8 , /* 0x00AE # REGISTERED SIGN */ + 0xF8 , /* 0x00AF # MACRON */ + 0xA1 , /* 0x00B0 # DEGREE SIGN */ + 0xB1 , /* 0x00B1 # PLUS-MINUS SIGN */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xAB , /* 0x00B4 # ACUTE ACCENT */ + 0xB5 , /* 0x00B5 # MICRO SIGN */ + 0xA6 , /* 0x00B6 # PILCROW SIGN */ + 0xE1 , /* 0x00B7 # MIDDLE DOT */ + 0xFC , /* 0x00B8 # CEDILLA */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xBC , /* 0x00BA # MASCULINE ORDINAL INDICATOR */ + 0xC8 , /* 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xC0 , /* 0x00BF # INVERTED QUESTION MARK */ + 0xCB , /* 0x00C0 # LATIN CAPITAL LETTER A WITH GRAVE */ + 0xE7 , /* 0x00C1 # LATIN CAPITAL LETTER A WITH ACUTE */ + 0xE5 , /* 0x00C2 # LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ + 0xCC , /* 0x00C3 # LATIN CAPITAL LETTER A WITH TILDE */ + 0x80 , /* 0x00C4 # LATIN CAPITAL LETTER A WITH DIAERESIS */ + 0x81 , /* 0x00C5 # LATIN CAPITAL LETTER A WITH RING ABOVE */ + 0xAE , /* 0x00C6 # LATIN CAPITAL LETTER AE */ + 0x82 , /* 0x00C7 # LATIN CAPITAL LETTER C WITH CEDILLA */ + 0xE9 , /* 0x00C8 # LATIN CAPITAL LETTER E WITH GRAVE */ + 0x83 , /* 0x00C9 # LATIN CAPITAL LETTER E WITH ACUTE */ + 0xE6 , /* 0x00CA # LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ + 0xE8 , /* 0x00CB # LATIN CAPITAL LETTER E WITH DIAERESIS */ + 0xED , /* 0x00CC # LATIN CAPITAL LETTER I WITH GRAVE */ + 0xEA , /* 0x00CD # LATIN CAPITAL LETTER I WITH ACUTE */ + 0xEB , /* 0x00CE # LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ + 0xEC , /* 0x00CF # LATIN CAPITAL LETTER I WITH DIAERESIS */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0x84 , /* 0x00D1 # LATIN CAPITAL LETTER N WITH TILDE */ + 0xF1 , /* 0x00D2 # LATIN CAPITAL LETTER O WITH GRAVE */ + 0xEE , /* 0x00D3 # LATIN CAPITAL LETTER O WITH ACUTE */ + 0xEF , /* 0x00D4 # LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ + 0xCD , /* 0x00D5 # LATIN CAPITAL LETTER O WITH TILDE */ + 0x85 , /* 0x00D6 # LATIN CAPITAL LETTER O WITH DIAERESIS */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xAF , /* 0x00D8 # LATIN CAPITAL LETTER O WITH STROKE */ + 0xF4 , /* 0x00D9 # LATIN CAPITAL LETTER U WITH GRAVE */ + 0xF2 , /* 0x00DA # LATIN CAPITAL LETTER U WITH ACUTE */ + 0xF3 , /* 0x00DB # LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ + 0x86 , /* 0x00DC # LATIN CAPITAL LETTER U WITH DIAERESIS */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA7 , /* 0x00DF # LATIN SMALL LETTER SHARP S */ + 0x88 , /* 0x00E0 # LATIN SMALL LETTER A WITH GRAVE */ + 0x87 , /* 0x00E1 # LATIN SMALL LETTER A WITH ACUTE */ + 0x89 , /* 0x00E2 # LATIN SMALL LETTER A WITH CIRCUMFLEX */ + 0x8B , /* 0x00E3 # LATIN SMALL LETTER A WITH TILDE */ + 0x8A , /* 0x00E4 # LATIN SMALL LETTER A WITH DIAERESIS */ + 0x8C , /* 0x00E5 # LATIN SMALL LETTER A WITH RING ABOVE */ + 0xBE , /* 0x00E6 # LATIN SMALL LETTER AE */ + 0x8D , /* 0x00E7 # LATIN SMALL LETTER C WITH CEDILLA */ + 0x8F , /* 0x00E8 # LATIN SMALL LETTER E WITH GRAVE */ + 0x8E , /* 0x00E9 # LATIN SMALL LETTER E WITH ACUTE */ + 0x90 , /* 0x00EA # LATIN SMALL LETTER E WITH CIRCUMFLEX */ + 0x91 , /* 0x00EB # LATIN SMALL LETTER E WITH DIAERESIS */ + 0x93 , /* 0x00EC # LATIN SMALL LETTER I WITH GRAVE */ + 0x92 , /* 0x00ED # LATIN SMALL LETTER I WITH ACUTE */ + 0x94 , /* 0x00EE # LATIN SMALL LETTER I WITH CIRCUMFLEX */ + 0x95 , /* 0x00EF # LATIN SMALL LETTER I WITH DIAERESIS */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0x96 , /* 0x00F1 # LATIN SMALL LETTER N WITH TILDE */ + 0x98 , /* 0x00F2 # LATIN SMALL LETTER O WITH GRAVE */ + 0x97 , /* 0x00F3 # LATIN SMALL LETTER O WITH ACUTE */ + 0x99 , /* 0x00F4 # LATIN SMALL LETTER O WITH CIRCUMFLEX */ + 0x9B , /* 0x00F5 # LATIN SMALL LETTER O WITH TILDE */ + 0x9A , /* 0x00F6 # LATIN SMALL LETTER O WITH DIAERESIS */ + 0xD6 , /* 0x00F7 # DIVISION SIGN */ + 0xBF , /* 0x00F8 # LATIN SMALL LETTER O WITH STROKE */ + 0x9D , /* 0x00F9 # LATIN SMALL LETTER U WITH GRAVE */ + 0x9C , /* 0x00FA # LATIN SMALL LETTER U WITH ACUTE */ + 0x9E , /* 0x00FB # LATIN SMALL LETTER U WITH CIRCUMFLEX */ + 0x9F , /* 0x00FC # LATIN SMALL LETTER U WITH DIAERESIS */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xA5 , /* 0x2022 # *** BULLET */ + 0xD8 /* 0x00FF # LATIN SMALL LETTER Y WITH DIAERESIS */ + }; + + +/* + +The following characters has no equivalent +to each other: + +MacCodes +164 0xA4 0x00A7 # SECTION SIGN +253 0xFD 0x02DD # DOUBLE ACUTE ACCENT +189 0xBD 0x03A9 # GREEK CAPITAL LETTER OMEGA +185 0xB9 0x03C0 # GREEK SMALL LETTER PI +255 0xFF 0x02C7 # CARON +249 0xF9 0x02D8 # BREVE +250 0xFA 0x02D9 # DOT ABOVE +251 0xFB 0x02DA # RING ABOVE +254 0xFE 0x02DB # OGONEK +218 0xDA 0x2044 # FRACTION SLASH +182 0xB6 0x2202 # PARTIAL DIFFERENTIAL +198 0xC6 0x2206 # INCREMENT +184 0xB8 0x220F # N-ARY PRODUCT +183 0xB7 0x2211 # N-ARY SUMMATION +195 0xC3 0x221A # SQUARE ROOT +176 0xB0 0x221E # INFINITY +186 0xBA 0x222B # INTEGRAL +197 0xC5 0x2248 # ALMOST EQUAL TO +173 0xAD 0x2260 # NOT EQUAL TO +178 0xB2 0x2264 # LESS-THAN OR EQUAL TO +179 0xB3 0x2265 # GREATER-THAN OR EQUAL TO +215 0xD7 0x25CA # LOZENGE +240 0xF0 0xF8FF # Apple logo +222 0xDE 0xFB01 # LATIN SMALL LIGATURE FI +223 0xDF 0xFB02 # LATIN SMALL LIGATURE FL +245 0xF5 0x0131 # LATIN SMALL LETTER DOTLESS I +206 0xCE 0x0152 # LATIN CAPITAL LIGATURE OE +207 0xCF 0x0153 # LATIN SMALL LIGATURE OE + +WinCodes +129 0x81 #UNDEFINED +141 0x8D #UNDEFINED +143 0x8F #UNDEFINED +144 0x90 #UNDEFINED +157 0x9D #UNDEFINED +167 0xA7 0x00A7 #SECTION SIGN +173 0xAD 0x00AD #SOFT HYPHEN +178 0xB2 0x00B2 #SUPERSCRIPT TWO +179 0xB3 0x00B3 #SUPERSCRIPT THREE +185 0xB9 0x00B9 #SUPERSCRIPT ONE +188 0xBC 0x00BC #VULGAR FRACTION ONE QUARTER +189 0xBD 0x00BD #VULGAR FRACTION ONE HALF +190 0xBE 0x00BE #VULGAR FRACTION THREE QUARTERS +208 0xD0 0x00D0 #LATIN CAPITAL LETTER ETH +215 0xD7 0x00D7 #MULTIPLICATION SIGN +221 0xDD 0x00DD #LATIN CAPITAL LETTER Y WITH ACUTE +222 0xDE 0x00DE #LATIN CAPITAL LETTER THORN +240 0xF0 0x00F0 #LATIN SMALL LETTER ETH +253 0xFD 0x00FD #LATIN SMALL LETTER Y WITH ACUTE +254 0xFE 0x00FE #LATIN SMALL LETTER THORN +140 0x8C 0x0152 #LATIN CAPITAL LIGATURE OE +156 0x9C 0x0153 #LATIN SMALL LIGATURE OE +138 0x8A 0x0160 #LATIN CAPITAL LETTER S WITH CARON +154 0x9A 0x0161 #LATIN SMALL LETTER S WITH CARON +142 0x8E 0x017D #LATIN CAPITAL LETTER Z WITH CARON +158 0x9E 0x017E #LATIN SMALL LETTER Z WITH CARON +128 0x80 0x20AC #EURO SIGN +166 0xA6 0x00A6 #BROKEN BAR + + +*/ + + + + +#endif /* !__macos_charmap_h */ diff --git a/macos/source/extrafld.c b/macos/source/extrafld.c new file mode 100644 index 0000000..a2efcdb --- /dev/null +++ b/macos/source/extrafld.c @@ -0,0 +1,920 @@ +/* + Copyright (c) 1990-2002 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/*--------------------------------------------------------------------------- + + extrafld.c + + contains functions to build extra-fields. + + ---------------------------------------------------------------------------*/ + +/*****************************************************************************/ +/* Includes */ +/*****************************************************************************/ + +#include +#include "zip.h" +#include "unixlike.h" +#include "helpers.h" +#include "pathname.h" + + +/*****************************************************************************/ +/* Macros, typedefs */ +/*****************************************************************************/ + +/* ---------------------------------------------------------------------- */ +/* Add a 'MAC3' extra field to the zlist data pointed to by z. */ +/* This is the (new) Info-zip extra block for Macintosh */ +#define EB_MAC3_HLEN 14 /* fixed length part of MAC3's header */ +#define EB_L_MAC3_FINFO_LEN 52 /* fixed part of MAC3 compressible data */ + +#define EB_MAX_OF_VARDATA 1300 /* max possible datasize */ + +#define EB_L_MAC3_SIZE (EB_HEADSIZE + EB_MAC3_HLEN) +#define EB_C_MAC3_SIZE (EB_HEADSIZE + EB_MAC3_HLEN) + +/* maximum memcompress overhead is the sum of the compression header length */ +/* (6 = ush compression type, ulg CRC) and the worstcase deflate overhead */ +/* when uncompressible data are kept in 2 "stored" blocks (5 per block = */ +/* byte blocktype + 2 * ush blocklength) */ +#define MEMCOMPRESS_OVERHEAD (EB_MEMCMPR_HSIZ + EB_DEFLAT_EXTRA) + +#define EB_M3_FL_COMPRESS 0x00 +#define EB_M3_FL_DATFRK 0x01 /* data is data-fork */ +#define EB_M3_FL_NOCHANGE 0x02 /* filename will be not changed */ +#define EB_M3_FL_UNCMPR 0x04 /* data is 'natural' (not compressed) */ +#define EB_M3_FL_TIME64 0x08 /* time is coded in 64 bit */ +#define EB_M3_FL_NOUTC 0x10 /* only 'local' time-stamps are stored */ + + +#define EB_L_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(2)) +#define EB_C_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(1)) + +/* disable compressing of extra field +#define MAC_EXTRAFLD_UNCMPR */ + +/* ---------------------------------------------------------------------- */ +/* Add a 'JLEE' extra field to the zlist data pointed to by z. */ +/* This is the (old) Info-zip resource-fork extra block for Macintosh +(last Revision 1996-09-22) Layout made by Johnny Lee, Code made by me :-) */ +#define EB_L_JLEE_LEN 40 /* fixed length of JLEE's header */ +#define EB_C_JLEE_LEN 40 /* fixed length of JLEE's header */ + +#define EB_L_JLEE_SIZE (EB_HEADSIZE + EB_L_JLEE_LEN) +#define EB_C_JLEE_SIZE (EB_HEADSIZE + EB_C_JLEE_LEN) + + + +/*****************************************************************************/ +/* Global Vars */ +/*****************************************************************************/ + +extern MacZipGlobals MacZip; +extern unsigned long count_of_Zippedfiles; + + + +/*****************************************************************************/ +/* Prototypes */ +/*****************************************************************************/ + +static int add_UT_ef(struct zlist far *z, iztimes *z_utim); +static int add_JLEE_ef(struct zlist far *z); /* old mac extra field */ +static int add_MAC3_ef(struct zlist far *z); /* new mac extra field */ + +static void make_extrafield_JLEE(char *l_ef); +static unsigned make_extrafield_MAC3(char *ef); +static char *make_EF_Head_MAC3(char *ef, unsigned compsize, ulg attrsize, + unsigned flag); + +static void print_extra_info(void); +void UserStop(void); + + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ + + +/* +* Set the extra-field's for each compressed file +*/ +int set_extra_field(struct zlist far *z, iztimes *z_utim) + /* store full data in local header but just modification time stamp info + in central header */ +{ + int retval; + + Assert_it(z, "set_extra_field","") + Assert_it(z_utim, "set_extra_field","") + + z_utim = z_utim; + + /* Check to make sure z is valid. */ + if( z == NULL ) { + return ZE_LOGIC; + } + + /* Resource forks are always binary */ + if (MacZip.CurrentFork == ResourceFork) z->att = BINARY; + + if (noisy) + { + count_of_Zippedfiles++; + InformProgress(MacZip.RawCountOfItems, count_of_Zippedfiles ); + } + + /* + PrintFileInfo(); + */ + switch (MacZip.MacZipMode) + { + case JohnnyLee_EF: + { + retval = add_JLEE_ef( z ); + if (retval != ZE_OK) return retval; + break; + } + case NewZipMode_EF: + { /* */ +#ifdef USE_EF_UT_TIME + retval = add_UT_ef(z, z_utim); + if (retval != ZE_OK) return retval; +#endif + + retval = add_MAC3_ef( z ); + if (retval != ZE_OK) return retval; + break; + } + default: + { + printerr("Unknown Extrafieldmode", -1, -1, __LINE__, __FILE__, ""); + return ZE_LOGIC; /* function should never reach this point */ + } + } + + /* MacStat information is now outdated and + must be refreshed for the next file */ + MacZip.isMacStatValid = false; + + return ZE_OK; +} + + + + +#ifdef USE_EF_UT_TIME +/* +* Build and add the Unix time extra-field. This extra field +* will be included be default. Johnny Lee's implementation does +* not use this kind of extra-field. +* All datas are in Intel (=little-endian) format + + Extra field info: + - 'UT' - UNIX time extra field + + This is done the same way ../unix/unix.c stores the 'UT'/'Ux' fields + (full data in local header, only modification time in central header), + with the 'M3' field added to the end and the size of the 'M3' field + in the central header. + */ + +static int add_UT_ef(struct zlist far *z, iztimes *z_utim) +{ + char *l_ef = NULL; + char *c_ef = NULL; + + Assert_it(z, "add_UT_ef","") + +#ifdef IZ_CHECK_TZ + if (!zp_tz_is_valid) + return ZE_OK; /* skip silently if no valid TZ info */ +#endif + + /* We can't work if there's no entry to work on. */ + if( z == NULL ) { + return ZE_LOGIC; + } + + /* Check to make sure we've got enough room in the extra fields. */ + if( z->ext + EB_L_UT_SIZE > EF_SIZE_MAX || + z->cext + EB_C_UT_SIZE > EF_SIZE_MAX ) { + return ZE_MEM; + } + + /* Allocate memory for the local and central extra fields. */ + if( z->extra && z->ext != 0 ) { + l_ef = (char *)realloc( z->extra, z->ext + EB_L_UT_SIZE ); + } else { + l_ef = (char *)malloc( EB_L_UT_SIZE ); + z->ext = 0; + } + if( l_ef == NULL ) { + return ZE_MEM; + } + z->extra = l_ef; + l_ef += z->ext; + + if( z->cextra && z->cext != 0 ) { + c_ef = (char *)realloc( z->cextra, z->cext + EB_C_UT_SIZE ); + } else { + c_ef = (char *)malloc( EB_C_UT_SIZE ); + z->cext = 0; + } + if( c_ef == NULL ) { + return ZE_MEM; + } + z->cextra = c_ef; + c_ef += z->cext; + + /* Now add the local version of the field. */ + *l_ef++ = 'U'; + *l_ef++ = 'T'; + *l_ef++ = (char)(EB_UT_LEN(2)); /* length of data in local EF */ + *l_ef++ = (char)0; + *l_ef++ = (char)(EB_UT_FL_MTIME | EB_UT_FL_CTIME); + *l_ef++ = (char)(z_utim->mtime); + *l_ef++ = (char)(z_utim->mtime >> 8); + *l_ef++ = (char)(z_utim->mtime >> 16); + *l_ef++ = (char)(z_utim->mtime >> 24); + *l_ef++ = (char)(z_utim->ctime); + *l_ef++ = (char)(z_utim->ctime >> 8); + *l_ef++ = (char)(z_utim->ctime >> 16); + *l_ef++ = (char)(z_utim->ctime >> 24); + + z->ext += EB_L_UT_SIZE; + + /* Now add the central version. */ + memcpy(c_ef, l_ef-EB_L_UT_SIZE, EB_C_UT_SIZE); + c_ef[EB_LEN] = (char)(EB_UT_LEN(1)); /* length of data in central EF */ + + z->cext += EB_C_UT_SIZE; + + return ZE_OK; +} +#endif /* USE_EF_UT_TIME */ + + +/* +* Build and add the old 'Johnny Lee' Mac extra field +* All native datas are in Motorola (=big-endian) format +*/ + +static int add_JLEE_ef( struct zlist far *z ) +{ + char *l_ef = NULL; + char *c_ef = NULL; + + Assert_it(z, "add_JLEE_ef","") + + /* Check to make sure we've got enough room in the extra fields. */ + if ( z->ext + EB_L_JLEE_SIZE > EF_SIZE_MAX || + z->cext + EB_C_JLEE_SIZE > EF_SIZE_MAX ) { + return ZE_MEM; + } + + + /* Allocate memory for the local extra fields. */ + if ( z->extra && z->ext != 0 ) { + l_ef = (char *)realloc( z->extra, z->ext + EB_L_JLEE_SIZE ); + } else { + l_ef = (char *)malloc( EB_L_JLEE_SIZE ); + z->ext = 0; + } + if ( l_ef == NULL ) { + return ZE_MEM; + } + z->extra = l_ef; + l_ef += z->ext; + + /* Allocate memory for the central extra fields. */ + if ( z->cextra && z->cext != 0 ) { + c_ef = (char *)realloc( z->cextra, z->cext + EB_C_JLEE_SIZE ); + } else { + c_ef = (char *)malloc( EB_C_JLEE_SIZE ); + z->cext = 0; + } + if ( c_ef == NULL ) { + return ZE_MEM; + } + z->cextra = c_ef; + c_ef += z->cext; + + + if ( verbose ) { + print_extra_info(); + } + + + /** + ** + ** Now add the local version of the field. + **/ + make_extrafield_JLEE(l_ef); + z->ext += EB_L_JLEE_SIZE; + + + /** + ** + ** Now add the central version of the field. + ** It's identical to the local header. I wonder why ?? + * the first two fields are in Intel little-endian format */ + make_extrafield_JLEE(c_ef); + z->cext += EB_C_JLEE_SIZE; + + return ZE_OK; +} + + + +/* +* This is an implementation of Johnny Lee's extra field. +* I never saw Johnny Lee's code. My code is based on the extra-field +* definition mac (see latest appnote 1997-03-11) +* and on some experiments with Johnny Lee's Zip-app version 1.0, 1992 +* +* Unfortunately I cannot agree with his extra-field layout. +* - it wasted space +* - and holds not all mac-specific information +* +* I coded this extra-field only for testing purposes. +* I don't want support this extra-field. Please use my implementation. +* +* This is old implementation of Johnny Lee's extra field. +* All native datas are in Motorola (=big-endian) format +*/ + +static void make_extrafield_JLEE(char *ef) +{ + + Assert_it(ef, "make_extrafield_JLEE","") + + if (MacZip.isMacStatValid == false) + { + fprintf(stderr,"Internal Logic Error: [%d/%s] MacStat is out of sync !", + __LINE__,__FILE__); + exit(-1); + } + + + /* the first two fields are in Intel little-endian format */ + *ef++ = 0xC8; /* tag for this extra block */ + *ef++ = 0x07; + + *ef++ = (char)(EB_L_JLEE_LEN); /* total data size this block */ + *ef++ = (char)((EB_L_JLEE_LEN) >> 8); + + /* the following fields are in motorola big-endian format */ + *ef++ = 'J'; /* extra field signature: 4 Bytes */ + *ef++ = 'L'; /* the old style extra field */ + *ef++ = 'E'; + *ef++ = 'E'; + + /* Start Macintosh Finder FInfo structure 16 Bytes overall */ + /* Type: 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 24); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType); + + /* Creator: 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 24); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator); + + /* file Finder Flags: 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags); + + /* Finders Icon position of a file*/ + /* V/Y-Position: 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v); + /* H/X-Position: 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h); + + /* fdFldr Folder containing file 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFldr >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFldr); + /* End Macintosh Finder FInfo structure */ + + + /* Creation-time 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 24); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat); + + /* Modification-time 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 24); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat); + + /* info Bits 4 Bytes */ + *ef++ = 0x00; + *ef++ = 0x00; + *ef++ = 0x00; + if (MacZip.DataForkOnly) + { /* don't convert filename for unzipping */ + /* 0x01 = data-fork; 0x00 = resource-fork */ + *ef++ = (char) (MacZip.CurrentFork == DataFork) | 2; + } + else + { + *ef++ = (char) (MacZip.CurrentFork == DataFork); + } + + /* file's location folder ID 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlParID >> 24); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlParID >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlParID >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlParID); + /* ============ */ + /* 40 Bytes */ +} + + + +/* +* Build and add the new mac extra field +* All native data are stored in Intel (=little-endian) format +*/ + +static int add_MAC3_ef( struct zlist far *z ) +{ + char *l_ef = NULL; + char *c_ef = NULL; + char *attrbuff = NULL; + off_t attrsize = (EB_L_MAC3_FINFO_LEN + EB_MAX_OF_VARDATA); + char *compbuff = NULL; + unsigned compsize = 0; + unsigned m3_compr; + Boolean compress_data = true; + + Assert_it(z, "add_MAC3_ef","") + + UserStop(); /* do event handling and let the user stop */ + + if( verbose ) { + print_extra_info(); + } + + /* allocate temporary buffer to collect the Mac extra field info */ + attrbuff = (char *)malloc( (size_t)attrsize ); + if( attrbuff == NULL ) { + return ZE_MEM; + } + + /* fill the attribute buffer, to get its (uncompressed) size */ + attrsize = make_extrafield_MAC3(attrbuff); + + if (compress_data && + ((compbuff = (char *)malloc((size_t)attrsize + MEMCOMPRESS_OVERHEAD)) + != NULL)) + { + /* Try compressing the data */ + compsize = memcompress( compbuff, + (size_t)attrsize + MEMCOMPRESS_OVERHEAD, + attrbuff, + (size_t)attrsize ); +#ifdef MAC_EXTRAFLD_UNCMPR + compsize = attrsize; +#endif + } + else + { + compsize = attrsize; + } + + if ((compsize) < attrsize) { + /* compression gained some space ... */ + free(attrbuff); /* no longer needed ... */ + m3_compr = EB_M3_FL_COMPRESS; + } else { + /* compression does not help, store data in uncompressed mode */ + if (compbuff != NULL) free(compbuff); + compbuff = attrbuff; + compsize = attrsize; + m3_compr = EB_M3_FL_UNCMPR; + } + + /* Check to make sure we've got enough room in the extra fields. */ + if( z->ext + (EB_L_MAC3_SIZE + compsize) > EF_SIZE_MAX || + z->cext + EB_C_MAC3_SIZE > EF_SIZE_MAX ) { + if (compbuff != NULL) free(compbuff); + return ZE_MEM; + } + + /* Allocate memory for the local extra fields. */ + if( z->extra && z->ext != 0 ) { + l_ef = (char *)realloc( z->extra, z->ext + + EB_L_MAC3_SIZE + compsize); + } else { + l_ef = (char *)malloc( EB_L_MAC3_SIZE + compsize); + z->ext = 0; + } + if( l_ef == NULL ) { + return ZE_MEM; + } + z->extra = l_ef; + l_ef += z->ext; + + /* Allocate memory for the central extra fields. */ + if( z->cextra && z->cext != 0 ) { + c_ef = (char *)realloc( z->cextra, z->cext + EB_C_MAC3_SIZE); + } else { + c_ef = (char *)malloc( EB_C_MAC3_SIZE ); + z->cext = 0; + } + if( c_ef == NULL ) { + return ZE_MEM; + } + z->cextra = c_ef; + c_ef += z->cext; + + /** + ** Now add the local version of the field. + **/ + l_ef = make_EF_Head_MAC3(l_ef, compsize, (ulg)attrsize, m3_compr); + memcpy(l_ef, compbuff, (size_t)compsize); + l_ef += compsize; + z->ext += EB_L_MAC3_SIZE + compsize; + free(compbuff); + /* And the central version. */ + c_ef = make_EF_Head_MAC3(c_ef, 0, (ulg)attrsize, m3_compr); + z->cext += EB_C_MAC3_SIZE; + + return ZE_OK; +} + + + + +/* +* Build the new mac local extra field header. +* It's identical with the central extra field. +* All native data are in Intel (=little-endian) format +*/ +static char *make_EF_Head_MAC3(char *ef, unsigned compsize, ulg attrsize, + unsigned flag) +{ + unsigned info_flag = flag; + + Assert_it(ef, "make_EF_Head_MAC3","") + + /* the first four fields are in Intel little-endian format */ + *ef++ = 'M'; /* tag for this extra block 2 Bytes */ + *ef++ = '3'; + + /* total data size this block 2 Bytes */ + *ef++ = (char) (EB_MAC3_HLEN + compsize); + *ef++ = (char)((EB_MAC3_HLEN + compsize) >> 8); + + *ef++ = (char)(attrsize); + *ef++ = (char)(attrsize >> 8); + *ef++ = (char)(attrsize >> 16); + *ef++ = (char)(attrsize >> 24); + + /* info Bits (flags) 2 Bytes */ + + if (MacZip.DataForkOnly) info_flag |= (EB_M3_FL_DATFRK | + EB_M3_FL_NOCHANGE); + if (MacZip.CurrentFork == DataFork) info_flag |= EB_M3_FL_DATFRK; + if (!MacZip.HaveGMToffset) info_flag |= EB_M3_FL_NOUTC; + + *ef++ = (char)info_flag; + *ef++ = (char)0x00; /* reserved at the moment */ + + /* Note: Apple defined File-Type/-Creator as OSType ( =unsigned long, + see Universal Headers 3.1). However, File-Type/-Creator are a + unique four-character sequence. Therefore the byteorder of the + File-Type/-Creator are NOT changed. The native format is used. */ + + /* Type: 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 24); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType); + + /* Creator: 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 24); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator); + + return ef; +} + + + + + +/* +* Build the new mac local extra field header. +* All native data are in Intel (=little-endian) format +*/ +unsigned make_extrafield_MAC3(char *ef) +{ + char *ef_m3_begin = ef; + char *temp_Pathname; + char tmp_buffer[NAME_MAX]; + unsigned char comment[257]; + unsigned short FLength = 0; + unsigned short CLength = 0; + short tempFork; + OSErr err; + + Assert_it(ef, "make_extrafield_MAC3","") + + if (MacZip.isMacStatValid == false) + { + fprintf(stderr, + "Internal Logic Error: [%d/%s] MacStat is out of sync !", + __LINE__, __FILE__); + exit(-1); + } + + /* Start Macintosh Finder FInfo structure except Type/Creator + (see make_EF_Head_MAC3()) 8 Bytes overall */ + + /* file Finder Flags: 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags >> 8); + + /* Finders Icon position of a file*/ + /* V/Y-Position: 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v >> 8); + + /* H/X-Position: 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h >> 8); + + /* fdFldr Folder containing file 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFldr); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFldr >> 8); + + /* End Macintosh Finder FInfo structure */ + + /* 8 Bytes so far ... */ + + /* Start Macintosh Finder FXInfo structure 16 Bytes overall */ + /* Icon ID: 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdIconID); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdIconID >> 8); + + /* unused: 6 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[0]); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[0] >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[1]); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[1] >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[2]); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdUnused[2] >> 8); + /* Script flag: 1 Byte */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdScript); + /* More flag bits: 1 Byte */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdXFlags); + /* Comment ID 2 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdComment); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdComment >> 8); + + /* Home Dir ID: 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdPutAway); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdPutAway >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdPutAway >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlXFndrInfo.fdPutAway >> 24); + /* End Macintosh Finder FXInfo structure */ + + /* 24 Bytes so far ... */ + + /* file version number 1 Byte */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFVersNum); + + /* directory access rights 1 Byte */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioACUser); + + /* Creation-time 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlCrDat >> 24); + /* Modification-time 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlMdDat >> 24); + /* Backup-time 4 Bytes */ + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlBkDat); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlBkDat >> 8); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlBkDat >> 16); + *ef++ = (char)(MacZip.fpb.hFileInfo.ioFlBkDat >> 24); + + /* 38 Bytes so far ... */ +#ifdef USE_EF_UT_TIME + if (MacZip.HaveGMToffset) { + /* GMT-Offset times 12 Bytes */ + *ef++ = (char)(MacZip.Cr_UTCoffs); + *ef++ = (char)(MacZip.Cr_UTCoffs >> 8); + *ef++ = (char)(MacZip.Cr_UTCoffs >> 16); + *ef++ = (char)(MacZip.Cr_UTCoffs >> 24); + *ef++ = (char)(MacZip.Md_UTCoffs); + *ef++ = (char)(MacZip.Md_UTCoffs >> 8); + *ef++ = (char)(MacZip.Md_UTCoffs >> 16); + *ef++ = (char)(MacZip.Md_UTCoffs >> 24); + *ef++ = (char)(MacZip.Bk_UTCoffs); + *ef++ = (char)(MacZip.Bk_UTCoffs >> 8); + *ef++ = (char)(MacZip.Bk_UTCoffs >> 16); + *ef++ = (char)(MacZip.Bk_UTCoffs >> 24); + } + /* 50 Bytes so far ... */ +#endif + + /* Text Encoding Base (charset) 2 Bytes */ + *ef++ = (char)(MacZip.CurrTextEncodingBase); + *ef++ = (char)(MacZip.CurrTextEncodingBase >> 8); + /* 52 Bytes so far ... */ + + /* MacZip.CurrentFork will be changed, so we have to save it */ + tempFork = MacZip.CurrentFork; + if (!MacZip.StoreFullPath) { + temp_Pathname = StripPartialDir(tmp_buffer, MacZip.SearchDir, + MacZip.FullPath); + } else { + temp_Pathname = MacZip.FullPath; + } + MacZip.CurrentFork = tempFork; + + FLength = strlen(temp_Pathname) + 1; + memcpy( ef, temp_Pathname, (size_t)FLength ); + ef += FLength; /* make room for the string - variable length */ + + err = FSpLocationFromFullPath(strlen(MacZip.FullPath), MacZip.FullPath, + &MacZip.fileSpec); + printerr("FSpLocationFromFullPath:", err, err, + __LINE__, __FILE__, tmp_buffer); + + err = FSpDTGetComment(&MacZip.fileSpec, comment); + printerr("FSpDTGetComment:", (err != -5012) && (err != 0), err, + __LINE__, __FILE__, ""); + PToCCpy(comment,tmp_buffer); + + CLength = strlen(tmp_buffer) + 1; + memcpy( ef, tmp_buffer, (size_t)CLength ); + ef += CLength; /* make room for the string - variable length */ + + if (verbose) printf("\n comment: [%s]", tmp_buffer); + + return (unsigned)(ef - ef_m3_begin); +} + + + + + + +/* +* Print all native data of the new mac local extra field. +* It's for debugging purposes and disabled by default. +*/ + +static void PrintFileInfo(void) +{ +DateTimeRec MacTime; + +printf("\n\n---------------------------------------------"\ + "----------------------------------"); +printf("\n FullPath Name = [%s]", MacZip.FullPath); +printf("\n File Attributes = %s 0x%x %d", + sBit2Str(MacZip.fpb.hFileInfo.ioFlAttrib), + MacZip.fpb.hFileInfo.ioFlAttrib, + MacZip.fpb.hFileInfo.ioFlAttrib); +printf("\n Enclosing Folder ID# = 0x%x %d", + MacZip.fpb.hFileInfo.ioFlParID, + MacZip.fpb.hFileInfo.ioFlParID); + +if (!MacZip.isDirectory) +{ +printf("\n File Type = [%c%c%c%c] 0x%lx", + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 24, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 16, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 8, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType); + +printf("\n File Creator = [%c%c%c%c] 0x%lx", + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 24, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 16, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 8, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator); + +printf("\n Data Fork :" ); +printf("\n Actual (Logical) Length = %d 0x%x ", + MacZip.fpb.hFileInfo.ioFlLgLen, + MacZip.fpb.hFileInfo.ioFlLgLen); +printf("\n Allocated (Physical) Length = %d 0x%x", + MacZip.fpb.hFileInfo.ioFlPyLen, + MacZip.fpb.hFileInfo.ioFlPyLen); +printf("\n Resource Fork :" ); +printf("\n Actual (Logical) Length = %d 0x%x", + MacZip.fpb.hFileInfo.ioFlRLgLen, + MacZip.fpb.hFileInfo.ioFlRLgLen ); +printf("\n Allocated (Physical) Length = %d 0x%x", + MacZip.fpb.hFileInfo.ioFlRPyLen, + MacZip.fpb.hFileInfo.ioFlRPyLen ); +} + +printf("\n Dates : "); + +SecondsToDate (MacZip.CreatDate, &MacTime); +printf("\n Created = %4d/%2d/%2d %2d:%2d:%2d ", + MacTime.year, + MacTime.month, + MacTime.day, + MacTime.hour, + MacTime.minute, + MacTime.second); + +SecondsToDate (MacZip.BackDate, &MacTime); +printf("\n Backup = %4d/%2d/%2d %2d:%2d:%2d ", + MacTime.year, + MacTime.month, + MacTime.day, + MacTime.hour, + MacTime.minute, + MacTime.second); + +SecondsToDate (MacZip.ModDate, &MacTime); +printf("\n Modified = %4d/%2d/%2d %2d:%2d:%2d ", + MacTime.year, + MacTime.month, + MacTime.day, + MacTime.hour, + MacTime.minute, + MacTime.second); + +if (!MacZip.isDirectory) +{ +printf("\n Finder Flags : %s 0x%x %d", + sBit2Str(MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags), + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags); +printf("\n Finder Icon Position = X: %d 0x%x ", + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.h); +printf("\n Y: %d 0x%x ", + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdLocation.v); +} +else +{ +printf("\n Finder Flags : %s 0x%x %d", + sBit2Str(MacZip.fpb.dirInfo.ioDrUsrWds.frFlags), + MacZip.fpb.dirInfo.ioDrUsrWds.frFlags, + MacZip.fpb.dirInfo.ioDrUsrWds.frFlags); +printf("\n Finder Icon Position = X: %d 0x%x ", + MacZip.fpb.dirInfo.ioDrUsrWds.frLocation.h, + MacZip.fpb.dirInfo.ioDrUsrWds.frLocation.h); +printf("\n Y: %d 0x%x ", + MacZip.fpb.dirInfo.ioDrUsrWds.frLocation.v, + MacZip.fpb.dirInfo.ioDrUsrWds.frLocation.v); +} + +printf("\n----------------------------------------------------"\ + "---------------------------\n"); +} + + + +/* +* If the switch '-v' is used, print some more info. +*/ + +static void print_extra_info(void) +{ +char Fork[20]; + +if (MacZip.CurrentFork == DataFork) sstrcpy(Fork,""); +else sstrcpy(Fork,""); + +printf("\n%16s [%c%c%c%c] [%c%c%c%c]",Fork, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 24, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 16, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType >> 8, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType, + + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 24, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 16, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator >> 8, + MacZip.fpb.hFileInfo.ioFlFndrInfo.fdCreator); +} diff --git a/macos/source/getenv.c b/macos/source/getenv.c new file mode 100644 index 0000000..3b22327 --- /dev/null +++ b/macos/source/getenv.c @@ -0,0 +1,398 @@ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + +This file implements the getenv() function. + +# Background: +# Under Unix: Each Process (= running Program) has a set of +# associated variables. The variables are called enviroment +# variables and, together, constitute the process environment. +# These variables include the search path, the terminal type, +# and the user's login name. + +# Unfortunatelly the MacOS has no equivalent. So we need +# a file to define the environment variables. +# Name of this file is "MacZip.Env". It can be placed +# in the current folder of MacZip or in the +# preference folder of the system disk. +# If MacZip founds the "MacZip.Env" file in the current +# the folder of MacZip the "MacZip.Env" file in the +# preference folder will be ignored. + +# An environment variable has a name and a value: +# Name=Value +# Note: Spaces are significant: +# ZIPOPT=-r and +# ZIPOPT = -r are different !!! + + + */ + +/*****************************************************************************/ +/* Includes */ +/*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include "pathname.h" +#include "helpers.h" + +/*****************************************************************************/ +/* Module level Vars */ +/*****************************************************************************/ + +static char ListAllKeyValues = 0; +static unsigned LineNumber = 0; +static char CompletePath[NAME_MAX]; +Boolean IgnoreEnvironment = false; /* used by dialog.c and initfunc.c + of the Mainapp */ + +/*****************************************************************************/ +/* Macros, typedefs */ +/*****************************************************************************/ + +typedef struct _EnviromentPair { + char *key; + char *value; +} EnviromentPair; + + +#define MAX_COMMAND 1024 + + +/*****************************************************************************/ +/* Prototypes */ +/*****************************************************************************/ + + +int get_char(FILE *file); +void unget_char(int ch,FILE *file); +int get_string(char *string,int size, FILE *file, char *terms); +void skip_comments(FILE *file); +char *load_entry(FILE *file); +char *getenv(const char *name); +EnviromentPair *ParseLine(char *line); +OSErr FSpFindFolder_Name(short vRefNum, OSType folderType, + Boolean createFolder,FSSpec *spec, unsigned char *name); +FILE * FSp_fopen(ConstFSSpecPtr spec, const char * open_mode); +void ShowAllKeyValues(void); +void Set_LineNum(unsigned ln); + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ + + +/* get_string(str, max, file, termstr) : like fgets() but + * (1) has terminator string which should include \n + * (2) will always leave room for the null + * (3) uses get_char() so LineNumber will be accurate + * (4) returns EOF or terminating character, whichever + */ +int get_string(char *string, int size, FILE *file, char *terms) +{ + int ch; + + while (EOF != (ch = get_char(file)) && !strchr(terms, ch)) { + if (size > 1) { + *string++ = (char) ch; + size--; + } + } + + if (size > 0) + { + *string = '\0'; + } + + return ch; +} + + + + +void Set_LineNum(unsigned ln) +{ + LineNumber = ln; +} + + + +/* get_char(file) : like getc() but increment LineNumber on newlines + */ +int get_char(FILE *file) +{ + int ch; + + ch = getc(file); + if (ch == '\n') + { + Set_LineNum(LineNumber + 1); + } + + return ch; +} + + + + +/* skip_comments(file) : read past comment (if any) + */ +void skip_comments(FILE *file) +{ + int ch; + + while (EOF != (ch = get_char(file))) + { + /* ch is now the first character of a line. + */ + + while (ch == ' ' || ch == '\t') + { + ch = get_char(file); + } + + if (ch == EOF) + { + break; + } + + /* ch is now the first non-blank character of a line. + */ + + if (ch != '\n' && ch != '#') + { + break; + } + + /* ch must be a newline or comment as first non-blank + * character on a line. + */ + + while (ch != '\n' && ch != EOF) + { + ch = get_char(file); + } + + /* ch is now the newline of a line which we're going to + * ignore. + */ + } + + if (ch != EOF) + { + unget_char(ch, file); + } +} + + + + +/* unget_char(ch, file) : like ungetc but do LineNumber processing + */ +void unget_char(int ch, FILE *file) +{ + ungetc(ch, file); + if (ch == '\n') + { + Set_LineNum(LineNumber - 1); + } +} + + +/* this function reads one file entry -- the next -- from a file. +* it skips any leading blank lines, ignores comments, and returns +* NULL if for any reason the entry can't be read and parsed. +*/ + +char *load_entry(FILE *file) +{ + int ch; + static char cmd[MAX_COMMAND]; + + skip_comments(file); + + ch = get_string(cmd, MAX_COMMAND, file, "\n"); + + if (ch == EOF) + { + return NULL; + } + + return cmd; +} + + + + + +EnviromentPair *ParseLine(char *line) +{ +char *tmpPtr; +static EnviromentPair *Env; +unsigned short length = strlen(line); + +Env->key = ""; +Env->value = ""; + +for (tmpPtr = line; *tmpPtr; tmpPtr++) + { + if (*tmpPtr == '=') + { + *tmpPtr = 0; + Env->key = line; + if (strlen(Env->key) < length) + { + Env->value = ++tmpPtr; + } + return Env; + } + } +return Env; +} + + + + + +char *getenv(const char *name) +{ +FILE *fp; +char *LineStr = NULL; +EnviromentPair *Env1; +FSSpec spec; +OSErr err; + +if (IgnoreEnvironment) + return NULL; /* user wants to ignore the environment vars */ + +if (name == NULL) + return NULL; + +GetCompletePath(CompletePath,"MacZip.Env",&spec,&err); + +/* try open the file in the current folder */ +fp = FSp_fopen(&spec,"r"); +if (fp == NULL) + { /* Okey, lets try open the file in the preference folder */ + FSpFindFolder_Name( + kOnSystemDisk, + kPreferencesFolderType, + kDontCreateFolder, + &spec, + "\pMacZip.Env"); + fp = FSp_fopen(&spec,"r"); + if (fp == NULL) + { + return NULL; /* there is no enviroment-file */ + } + } + +LineStr = load_entry(fp); +while (LineStr != NULL) + { /* parse the file line by line */ + Env1 = ParseLine(LineStr); + if (strlen(Env1->value) > 0) + { /* we found a key/value pair */ + if (ListAllKeyValues) + printf("\n Line:%3d [%s] = [%s]",LineNumber,Env1->key,Env1->value); + if (stricmp(name,Env1->key) == 0) + { /* we found the value of a given key */ + return Env1->value; + } + } + LineStr = load_entry(fp); /* read next line */ + } +fclose(fp); + +return NULL; +} + + + + + +OSErr FSpFindFolder_Name( + short vRefNum, /* Volume reference number. */ + OSType folderType, /* Folder type taken by FindFolder. */ + Boolean createFolder, /* Should we create it if non-existant. */ + FSSpec *spec, /* Pointer to resulting directory. */ + unsigned char *name) /* Name of the file in the folder */ +{ + short foundVRefNum; + long foundDirID; + OSErr err; + + err = FindFolder(vRefNum, folderType, createFolder, + &foundVRefNum, &foundDirID); + if (err != noErr) + { + return err; + } + + err = FSMakeFSSpec(foundVRefNum, foundDirID, name, spec); + return err; +} + + + + +void ShowAllKeyValues(void) +{ +OSErr err; +FSSpec spec; +Boolean tmpIgnoreEnvironment = IgnoreEnvironment; + +ListAllKeyValues = 1; +IgnoreEnvironment = false; + +GetCompletePath(CompletePath,"MacZip.Env",&spec,&err); +if (err != 0) + { /* Okey, lets try open the file in the preference folder */ + FSpFindFolder_Name( + kOnSystemDisk, + kPreferencesFolderType, + kDontCreateFolder, + &spec, + "\pMacZip.Env"); + GetFullPathFromSpec(CompletePath,&spec, &err); + if (err != 0) + { + return; /* there is no enviroment-file */ + } + } + +printf("\nLocation of the current \"MacZip.Env\" file:\n [%s]",CompletePath); + +printf("\n\nList of all environment variables\n"); +getenv(" "); +printf("\n\nEnd\n\n"); + +/* restore used variables */ +ListAllKeyValues = 0; +LineNumber = 0; +IgnoreEnvironment = tmpIgnoreEnvironment; +} + + + + + + + + + + diff --git a/macos/source/helpers.c b/macos/source/helpers.c new file mode 100644 index 0000000..36b5bef --- /dev/null +++ b/macos/source/helpers.c @@ -0,0 +1,479 @@ +/* + Copyright (c) 1990-2001 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/*--------------------------------------------------------------------------- + + helpers.c + + Some useful functions Used by unzip and zip. + + ---------------------------------------------------------------------------*/ + +/*****************************************************************************/ +/* Includes */ +/*****************************************************************************/ + +#include "zip.h" +#include +#include +#include + +#include "macstuff.h" +#include "helpers.h" +#include "pathname.h" + + +/*****************************************************************************/ +/* Global Vars */ +/*****************************************************************************/ + + +extern int noisy; +extern char MacPathEnd; +extern char *zipfile; /* filename of the Zipfile */ +extern char *tempzip; /* Temporary zip file name */ +extern ZCONST unsigned char MacRoman_to_WinCP1252[128]; + + +static char argStr[1024]; +static char *argv[MAX_ARGS + 1]; + + + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ + + +/* +** Copy a C string to a Pascal string +** +*/ + +unsigned char *CToPCpy(unsigned char *pstr, char *cstr) +{ + register char *dptr; + register unsigned len; + + len=0; + dptr=(char *)pstr+1; + while (len<255 && (*dptr++ = *cstr++)!='\0') ++len; + *pstr= (unsigned char)len; + return pstr; +} + + +/* +** Copy a Pascal string to a C string +** +*/ + +char *PToCCpy(unsigned char *pstr, char *cstr) +{ +strncpy(cstr, (char *) &pstr[1], *pstr); + cstr[pstr[0]] = '\0'; /* set endmarker for c-string */ +return cstr; +} + + +/* +** strcpy() and strcat() work-alikes which allow overlapping buffers. +*/ + +char *sstrcpy(char *to,const char *from) +{ + memmove(to, from, 1+strlen(from)); + return to; +} + +char *sstrcat(char *to,const char *from) +{ + sstrcpy(to + strlen(to), from); + return to; +} + + + +/* +** Alloc memory and init it +** +*/ + +char *StrCalloc(unsigned short size) +{ +char *strPtr = NULL; + +if ((strPtr = calloc(size, sizeof(char))) == NULL) + printerr("StrCalloc failed:", -1, size, __LINE__, __FILE__, ""); + +Assert_it(strPtr,"strPtr == NULL","") +return strPtr; +} + + + +/* +** Release only non NULL pointers +** +*/ + +char *StrFree(char *strPtr) +{ + +if (strPtr != NULL) + { + free(strPtr); + } + +return NULL; +} + + + + +/* +** Return a value in a binary string +** +*/ + +char *sBit2Str(unsigned short value) +{ + static char str[sizeof(value)*8]; + int biz = 16; + int strwid = 16; + int i, j; + char *tempPtr = str; + + j = strwid - (biz + (biz >> 2)- (biz % 4 ? 0 : 1)); + + for (i = 0; i < j; i++) { + *tempPtr++ = ' '; + } + while (--biz >= 0) + { + *tempPtr++ = ((value >> biz) & 1) + '0'; + if (!(biz % 4) && biz) { + *tempPtr++ = ' '; + } + } + *tempPtr = '\0'; + + return str; +} + + + + +/* +** Parse commandline style arguments +** +*/ + +int ParseArguments(char *s, char ***arg) +{ + int n = 1, Quote = 0; + char *p = s, *p1, c; + + argv[0] = GetAppName(); + + *arg = argv; + + p1 = (char *) argStr; + while ((c = *p++) != 0) { + if (c==' ') continue; + argv[n++] = p1; + if (n > MAX_ARGS) + return (n-1); + do { + if (c=='\\' && *p++) + c = *p++; + else + if ((c=='"') || (c == '\'')) { + if (!Quote) { + Quote = c; + continue; + } + if (c == Quote) { + Quote = 0; + continue; + } + } + *p1++ = c; + } while (*p && ((c = *p++) != ' ' || Quote)); + *p1++ = '\0'; + } + return n; +} + + + +/* +** Print commandline style arguments +** +*/ + +void PrintArguments(int argc, char **argv) +{ + +printf("\n Arguments:"); +printf("\n --------------------------"); + +while(--argc >= 0) + printf("\n argc: %d argv: [%s]", argc, &*argv[argc]); + +printf("\n --------------------------\n\n"); +return; +} + + + +/* +** return some error-msg on file-system +** +*/ + +int PrintUserHFSerr(int cond, int err, char *msg2) +{ +char *msg; + +if (cond != 0) + { + switch (err) + { + case -35: + msg = "No such Volume"; + break; + + case -56: + msg = "No such Drive"; + break; + + case -37: + msg = "Bad Volume Name"; + break; + + case -49: + msg = "File is already open for writing"; + break; + + case -43: + msg = "Directory/File not found"; + break; + + case -120: + msg = "Directory/File not found or incomplete pathname"; + break; + + default: return err; + } + fprintf(stderr, "\n\n Error: %s ->%s", msg, msg2); + exit(err); + } + +return 0; +} + + + +/* +** Check mounted volumes and return number of volumes +** with the same name. +*/ + +short CheckMountedVolumes(char *FullPath) +{ +FSSpec volumes[50]; /* 50 Volumes should be enough */ +char VolumeName[257], volume[257]; +short actVolCount, volIndex = 1, VolCount = 0; +OSErr err; +int i; + +GetVolumeFromPath(FullPath, VolumeName); + +err = OnLine(volumes, 50, &actVolCount, &volIndex); +printerr("OnLine:", (err != -35) && (err != 0), err, __LINE__, __FILE__, ""); + +for (i=0; i < actVolCount; i++) + { + PToCCpy(volumes[i].name,volume); + if (stricmp(volume, VolumeName) == 0) VolCount++; + } +printerr("OnLine: ", (VolCount == 0), VolCount, __LINE__, __FILE__, FullPath); + +return VolCount; +} + + + + + + + + +/* +** compares strings, ignoring differences in case +** +*/ + +int stricmp(const char *p1, const char *p2) +{ +int diff; + +while (*p1 && *p2) + { + if (*p1 != *p2) + { + if (isalpha(*p1) && isalpha(*p2)) + { + diff = toupper(*p1) - toupper(*p2); + if (diff) return diff; + } + else break; + } + p1++; + p2++; + } +return *p1 - *p2; +} + + + +/* +** Convert the MacOS-Strings (Filenames/Findercomments) to a most compatible. +** These strings will be stored in the public area of the zip-archive. +** Every foreign platform (outside macos) will access these strings +** for extraction. +*/ + +void MakeCompatibleString(char *MacOS_Str, + const char SpcChar1, const char SpcChar2, + const char SpcChar3, const char SpcChar4, + short CurrTextEncodingBase) +{ + char *tmpPtr; + register uch curch; + + Assert_it(MacOS_Str,"MakeCompatibleString MacOS_Str == NULL","") + for (tmpPtr = MacOS_Str; (curch = *tmpPtr) != '\0'; tmpPtr++) + { + if (curch == SpcChar1) + *tmpPtr = SpcChar2; + else + if (curch == SpcChar3) + *tmpPtr = SpcChar4; + else /* default */ + /* now convert from MacRoman to ISO-8859-1 */ + /* but convert only if MacRoman is activ */ + if ((CurrTextEncodingBase == kTextEncodingMacRoman) && + (curch > 127)) + { + *tmpPtr = (char)MacRoman_to_WinCP1252[curch - 128]; + } + } /* end for */ +} + + + + +Boolean CheckForSwitch(char *Switch, int argc, char **argv) +{ + char *p; /* steps through option arguments */ + int i; /* arg counter, root directory flag */ + + for (i = 1; i < argc; i++) + { + if (argv[i][0] == '-') + { + if (argv[i][1]) + { + for (p = argv[i]+1; *p; p++) + { + if (*p == Switch[0]) + { + return true; + } + if ((Switch[1] != NULL) && + ((*p == Switch[0]) && (*p == Switch[1]))) + { + return true; + } + } + } + } + } + +return false; +} + + + + + + + +#if (defined(USE_SIOUX) || defined(MACUNZIP_STANDALONE)) + +/* +** checks the condition and returns an error-msg +** this function is for internal use only +*/ + +OSErr printerr(const char *msg, int cond, int err, int line, char *file, + const char *msg2) +{ + +if (cond != 0) + { + fprintf(stderr, "\nint err: %d: %s %d [%d/%s] {%s}\n", clock(), msg, err, + line, file, msg2); + } + +return cond; +} + + +/* +fake-functions: +Not Implemented for metrowerks SIOUX +*/ + +void leftStatusString(char *status) +{ +status = status; +} + + +void rightStatusString(char *status) +{ +status = status; +} + + + +void DoWarnUserDupVol( char *FullPath ) +{ + char VolName[257]; + GetVolumeFromPath(FullPath, VolName); + + printf("\n There are more than one volume that has the same name !!\n"); + + printf("\n Volume: %s\n",VolName); + + printf("\n This port has one weak point:"); + printf("\n It is based on pathnames. As you may be already know:"); + printf("\n Pathnames are not unique on a Mac !"); + printf("\n MacZip has problems to find the correct location of"); + printf("\n the archive or the files.\n"); + + printf("\n My (Big) recommendation: Name all your volumes with an"); + printf("\n unique name and MacZip will run without any problem."); +} + + + +#endif diff --git a/macos/source/helpers.h b/macos/source/helpers.h new file mode 100644 index 0000000..a9df5d8 --- /dev/null +++ b/macos/source/helpers.h @@ -0,0 +1,57 @@ +/* + Copyright (c) 1990-2001 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#ifndef HELPERS_H +#define HELPERS_H 1 + + /* Convert a C string to a Pascal string */ +unsigned char *CToPCpy(unsigned char *pstr, char *cstr); + + /* Convert a Pascal string to a C string */ +char *PToCCpy(unsigned char *pstr, char *cstr); + +char *sstrcpy(char *to,const char *from); +char *sstrcat(char *to,const char *from); + +char *StrCalloc(unsigned short size); +char *StrFree(char *strPtr); + +char *sBit2Str(unsigned short value); + +void print_extra_info(void); + +int ParseArguments(char *s, char ***arg); +void PrintArguments(int argc, char **argv); + +Boolean IsZipFile(char *name); +OSErr printerr(const char *msg, int cond, int err, int line, char *file, + const char *msg2); +int PrintUserHFSerr(int cond, int err, char *msg2); + +short CheckMountedVolumes(char *FullPath); +void DoWarnUserDupVol(char *path); + +void PrintFileInfo(void); + +int stricmp(const char *p1, const char *p2); +void leftStatusString(char *status); +void rightStatusString(char *status); + +Boolean isZipFile(FSSpec *fileToOpen); + +unsigned long MacFileDate_to_UTime(unsigned long mactime); +Boolean CheckForSwitch(char *Switch, int argc, char **argv); + +void MakeCompatibleString(char *MacOS_Str, + const char SpcChar1, const char SpcChar2, + const char SpcChar3, const char SpcChar4, + short CurrTextEncodingBase); + +#define MAX_ARGS 25 + +#endif /* HELPERS_H */ diff --git a/macos/source/macglob.h b/macos/source/macglob.h new file mode 100644 index 0000000..17415e1 --- /dev/null +++ b/macos/source/macglob.h @@ -0,0 +1,86 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#ifndef _MACGLOBAL_ +#define _MACGLOBAL_ + +#include + +/* +all my Global vars are defined here. +*/ + +#define ResourceFork -1 +#define DataFork 1 +#define NoFork 0 + +/* +all my Global vars are defined here. +*/ +typedef struct { + short CurrentFork; + short MacZipMode; + + Boolean isMacStatValid; + Boolean HaveGMToffset; + + short CurrTextEncodingBase; + + /* info about the current file */ + Boolean isDirectory; + char FullPath[NAME_MAX]; + char FileName[NAME_MAX]; + FSSpec fileSpec; + + long dirID; + CInfoPBRec fpb; + + /* time infos about the current file */ + time_t CreatDate; + time_t ModDate; + time_t BackDate; + long Cr_UTCoffs; /* offset "local time - UTC" for CreatDate */ + long Md_UTCoffs; /* offset "local time - UTC" for ModDate */ + long Bk_UTCoffs; /* offset "local time - UTC" for BackDate */ + + /* some statistics over all*/ + unsigned long FoundFiles; + unsigned long FoundDirectories; + unsigned long RawCountOfItems; + unsigned long BytesOfData; + + unsigned long attrsize; + + /* some switches and user parameters */ + Boolean DataForkOnly; + Boolean StoreFullPath; + Boolean StoreFoldersAlso; /* internal switch is true if '-r' is set */ + unsigned short SearchLevels; + char Pattern[NAME_MAX]; + Boolean IncludeInvisible; + Boolean StatingProgress; + + char SearchDir[NAME_MAX]; + char CurrentPath[NAME_MAX]; + + /* current zip / tempzip file info */ + char ZipFullPath[NAME_MAX]; + + FSSpec ZipFileSpec; + unsigned long ZipFileType; + char TempZipFullPath[NAME_MAX]; + FSSpec TempZipFileSpec; + +} MacZipGlobals; + + + +void UserStop(void); + + +#endif diff --git a/macos/source/macopen.c b/macos/source/macopen.c new file mode 100644 index 0000000..9e18730 --- /dev/null +++ b/macos/source/macopen.c @@ -0,0 +1,363 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/*** macopen.c; stuff only required for the Mac port ***/ + +#include "zip.h" + +#include +#include +#include +#include + +#include "helpers.h" +#include "pathname.h" +#include "macopen.h" +#include "macstuff.h" + +#ifdef MACZIP +#include "macglob.h" + +extern char *zipfile; /* filename of the Zipfile */ +extern char *tempzip; /* Temporary zip file name */ + +extern MacZipGlobals MacZip; + + +/* don't include "osdep.h" otherwise we will trap into endless loop */ +#undef open +#undef fopen + + + +FILE *MacFopen(const char *path, const char *mode) +{ +static char TruncPath[NAME_MAX]; +OSErr err = 0; + +AssertStr(path,path) + + /* open zipfile or tempzip */ +if (strcmp(zipfile,path) == 0) + { + GetCompletePath(MacZip.ZipFullPath,path,&MacZip.ZipFileSpec,&err); + err = PrintUserHFSerr((err != -43) && (err != 0), err, path); + printerr("GetCompletePath:",err,err,__LINE__,__FILE__,path); + if (CheckMountedVolumes(MacZip.ZipFullPath) > 1) + DoWarnUserDupVol(MacZip.ZipFullPath); + + /* tempfile should appear in the same directory of the zipfile + -> save path of zipfile */ + TruncFilename(TruncPath, MacZip.ZipFullPath); + return fopen(MacZip.ZipFullPath, mode); + } + +if (strcmp(tempzip,path) == 0) + { /* add path of zipfile */ + sstrcat(TruncPath,tempzip); + GetCompletePath(MacZip.TempZipFullPath,TruncPath,&MacZip.TempZipFileSpec,&err); + err = PrintUserHFSerr((err != -43) && (err != 0), err, path); + printerr("GetCompletePath:",err,err,__LINE__,__FILE__,path); + + return fopen(MacZip.TempZipFullPath, mode); + } + +printerr("MacFopen:",err,err,__LINE__,__FILE__,path); +return NULL; +} + + + + +int MacOpen(const char *path,int oflag, ...) +{ +char RealFname[NAME_MAX]; + +AssertStr(path,path) + +RfDfFilen2Real(RealFname,path, MacZip.MacZipMode, MacZip.DataForkOnly, &MacZip.CurrentFork); +/* convert to real fname and init global var MacZip.CurrentFork !! */ + +switch (MacZip.CurrentFork) + { + case DataFork: + { + return my_open(RealFname, oflag); + break; + } + case ResourceFork: + { + return my_open( RealFname, oflag | O_RSRC); + break; + } + default: /* for now (Zip ver 2.3b) MacOpen should never reach this point */ + { /* however, this may change in the future ... */ + printerr("open: no resource / datafork ",-1,-1,__LINE__,__FILE__,path); + return -1; + } + } +} + + +#ifdef muell + /* file to delete */ +int destroy(char *path) +{ +static char lastpath[NAME_MAX]; +char currpath[NAME_MAX]; +static Boolean FirstCall = true; +long rc; + +AssertStr(path,path) + +RfDfFilen2Real(currpath, path, MacZip.MacZipMode, MacZip.DataForkOnly, &MacZip.CurrentFork); + +if (FirstCall == true) + { + FirstCall = false; + rc = remove(currpath); + } +else if (strcmp(currpath,lastpath) == 0) return 0; /* ignore, file is already deleted */ + else rc = remove(currpath); /* we are removeing all the files only by their + pathname this is dangerous on a mac but there is no other way without + a complete rewrite of the port */ + +strcpy(lastpath,currpath); + +return rc; +} +#endif + + + + +/* this function replaces the function "replace()" defined in fileio.c */ +int replace(char *new_f, char *temp_f) /* destination and source file names */ +{ +OSErr err = 0; +char newfname[NAME_MAX]; + +AssertStr(new_f,new_f) +AssertStr(temp_f,temp_f) + +UserStop(); + +GetFilename(newfname, new_f); + +/* check zipfile name and tempfile name */ +/* we are using this function only for replacing the tempfile with the zipfile */ +if ((strcmp(zipfile,new_f) == 0) || (strcmp(tempzip,temp_f) == 0)) + { + remove(MacZip.ZipFullPath); + + /* rename the temp file to the zip file */ + err = rename(MacZip.TempZipFullPath,MacZip.ZipFullPath); + printerr("rename:",err,err,__LINE__,__FILE__,MacZip.TempZipFullPath); +if (err != 0) return ZE_CREAT; + else return ZE_OK; + } +else return ZE_CREAT; +} + + + + /* file to delete */ + /* we are removeing all the files only by their + pathname this is dangerous on a mac but there is no + other way without a complete rewrite of the port */ + +int destroy(char *path) +{ +static char lastpath[NAME_MAX]; +static FSSpec trashfolder; +static Boolean FirstCall = true; +static char Num = 0; +static Boolean Immediate_File_Deletion = false; +char currpath[NAME_MAX], *envptr; +FSSpec fileToDelete; +OSErr err; + +/* init this function */ +if ((path == NULL) || + (strlen(path) == 0)) + { + FirstCall = true; + Num = 0; + return -1; + } + +UserStop(); + +RfDfFilen2Real(currpath, path, MacZip.MacZipMode, + MacZip.DataForkOnly, &MacZip.CurrentFork); +GetCompletePath(currpath,currpath,&fileToDelete, &err); + +if (FirstCall == true) + { + FirstCall = false; + sstrcpy(lastpath,currpath); + err = FSpFindFolder(fileToDelete.vRefNum, kTrashFolderType, + kDontCreateFolder,&trashfolder); + printerr("FSpFindFolder:",err,err,__LINE__,__FILE__,path); + + envptr = getenv("Immediate_File_Deletion"); + if (!(envptr == (char *)NULL || *envptr == '\0')) + { + if (stricmp(envptr,"yes") == 0) + Immediate_File_Deletion = true; + else + Immediate_File_Deletion = false; + } + + if (Immediate_File_Deletion) + { + err = FSpDelete(&fileToDelete); + return err; + } + + err = CatMove (fileToDelete.vRefNum, fileToDelete.parID, + fileToDelete.name, trashfolder.parID, trashfolder.name); + return err; + } + +if (strcmp(currpath,lastpath) == 0) + { + return 0; /* ignore, file is already deleted */ + } +else + { + + if (Immediate_File_Deletion) + { + err = FSpDelete(&fileToDelete); + sstrcpy(lastpath,path); + return err; + } + + err = CatMove (fileToDelete.vRefNum, fileToDelete.parID, + fileToDelete.name, trashfolder.parID, trashfolder.name); + + /* -48 = file is already existing so we have to rename it before + moving the file */ + if (err == -48) + { + Num++; + if (fileToDelete.name[0] >= 28) /* cut filename if to long */ + fileToDelete.name[0] = 28; + P2CStr(fileToDelete.name); + sprintf(currpath,"%s~%d",(char *)fileToDelete.name,Num); + C2PStr(currpath); + C2PStr((char *)fileToDelete.name); + err = HRename (fileToDelete.vRefNum, fileToDelete.parID, + fileToDelete.name, (unsigned char *) currpath); + err = CatMove (fileToDelete.vRefNum, fileToDelete.parID, + (unsigned char *) currpath, trashfolder.parID, + trashfolder.name); + } + } + +sstrcpy(lastpath,currpath); +return err; +} + + + +#endif /* #ifdef MACZIP */ + + + + +/* + * int open(const char *path, int oflag) + * + * Opens a file stream. + */ +int my_open(char *path, int oflag) +{ + FSSpec spec; + char permission; + HParamBlockRec hpb; + OSErr err, errno; + Boolean targetIsFolder, wasAliased; + + AssertStr(path,path) + + /* Setup permission */ + if ((oflag & 0x03) == O_RDWR) + permission = fsRdWrPerm; + else + permission = (oflag & O_RDONLY) ? fsRdPerm : 0 + (oflag & O_WRONLY) ? fsWrPerm : 0; + + FSpLocationFromFullPath(strlen(path),path, &spec); + if ((oflag & (O_ALIAS | O_NRESOLVE)) == 0) + ResolveAliasFile(&spec, true, &targetIsFolder, &wasAliased); + hpb.fileParam.ioNamePtr = spec.name; + hpb.fileParam.ioVRefNum = spec.vRefNum; + hpb.fileParam.ioDirID = spec.parID; + hpb.ioParam.ioPermssn = permission; + + if (oflag & O_RSRC) /* open the resource fork of the file */ + err = PBHOpenRFSync(&hpb); + else /* open the data fork of the file */ + err = PBHOpenDFSync(&hpb); + + if ((err == fnfErr) && (oflag & O_CREAT)) { + hpb.fileParam.ioFlVersNum = 0; + err = PBHCreateSync(&hpb); + if (err == noErr) { + /* Set the finder info */ + unsigned long secs; + unsigned long isbinary = oflag & O_BINARY; + + hpb.fileParam.ioFlFndrInfo.fdType = '\?\?\?\?'; + hpb.fileParam.ioFlFndrInfo.fdCreator = '\?\?\?\?'; + hpb.fileParam.ioFlFndrInfo.fdFlags = 0; + if (oflag & O_ALIAS) /* set the alias bit */ + hpb.fileParam.ioFlFndrInfo.fdFlags = kIsAlias; + else /* clear all flags */ + hpb.fileParam.ioFlFndrInfo.fdFlags = 0; + + GetDateTime(&secs); + hpb.fileParam.ioFlCrDat = hpb.fileParam.ioFlMdDat = secs; + PBHSetFInfoSync(&hpb); + } + + if (err && (err != dupFNErr)) { + errno = err; return -1; + } + + if (oflag & O_RSRC) /* open the resource fork of the file */ + err = PBHOpenRFSync(&hpb); + else /* open the data fork of the file */ + err = PBHOpenDFSync(&hpb); + } + + if (err && (err != dupFNErr) && (err != opWrErr)) { + errno = err; return -1; + } + + if (oflag & O_TRUNC) { + IOParam pb; + + pb.ioRefNum = hpb.ioParam.ioRefNum; + pb.ioMisc = 0L; + err = PBSetEOFSync((ParmBlkPtr)&pb); + if (err != noErr) { + errno = err; return -1; + } + } + + if (oflag & O_APPEND) lseek(hpb.ioParam.ioRefNum,0,SEEK_END); + + return (hpb.ioParam.ioRefNum); +} + + + + + diff --git a/macos/source/macopen.h b/macos/source/macopen.h new file mode 100644 index 0000000..152bceb --- /dev/null +++ b/macos/source/macopen.h @@ -0,0 +1,21 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#ifndef __MACOPEN_H__ +#define __MACOPEN_H__ + +#include +#include + + +FILE *MacFopen(const char *path, const char *mode); +int MacOpen(const char *path, int oflag, ...); + +int my_open(char *path, int oflag); + +#endif /* __MACOPEN_H__ */ diff --git a/macos/source/macos.c b/macos/source/macos.c new file mode 100644 index 0000000..935c9a1 --- /dev/null +++ b/macos/source/macos.c @@ -0,0 +1,1079 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/*--------------------------------------------------------------------------- + + macos.c + + Macintosh-specific routines for use with Info-ZIP's Zip 2.3 and later. + + ---------------------------------------------------------------------------*/ + + +/*****************************************************************************/ +/* Includes */ +/*****************************************************************************/ + +#include "zip.h" + +#include "revision.h" +#include "crypt.h" + +#include +#include +#include +#include + +#include + +#include +#include + +/* #include "charmap.h" */ +#include "helpers.h" +#include "macstuff.h" +#include "pathname.h" +#include "recurse.h" + + +/*****************************************************************************/ +/* Macros, typedefs */ +/*****************************************************************************/ + +#define PATH_END MacPathEnd + +/*****************************************************************************/ +/* Global Vars */ +/*****************************************************************************/ + +int error_level; /* used only in ziperr() */ + + +/* Note: sizeof() returns the size of this allusion + 13 is current length of "XtraStuf.mac:" */ +extern const char ResourceMark[13]; /* var is initialized in file pathname.c */ + + +extern jmp_buf EnvForExit; +MacZipGlobals MacZip; + +unsigned long count_of_Zippedfiles = 0; + + +/*****************************************************************************/ +/* Module level Vars */ +/*****************************************************************************/ + +static const char MacPathEnd = ':'; /* the Macintosh dir separator */ + +/* Inform Progress vars */ +long estTicksToFinish; +long createTime; +long updateTicks; + +static char *Time_Est_strings[] = { + "Zipping Files; Items done:", + "More than 24 hours", + "More than %s hours", + "About %s hours, %s minutes", + "About an hour", + "Less than an hour", + "About %s minutes, %s seconds", + "About a minute", + "Less than a minute", + "About %s seconds", + "About a second", + "About 1 minute, %s seconds"}; + + + +/*****************************************************************************/ +/* Prototypes */ +/*****************************************************************************/ + +int DoCurrentDir(void); + +void DoAboutBox(void); +void DoQuit(void); +void DoEventLoop(void); + +void ZipInitAllVars(void); +void UserStop(void); +Boolean IsZipFile(char *name); + +static long EstimateCompletionTime(const long progressMax, + const long progressSoFar, unsigned char percent); +static void UpdateTimeToComplete(void); + + + + +#ifdef USE_SIOUX +#include +void DoWarnUserDupVol( char *FullPath ); + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ + +/* +** Standalone Unzip with Metrowerks SIOUX starts here +** +*/ +int main(int argc, char **argv) +{ + int return_code; + + SIOUXSettings.asktosaveonclose = FALSE; + SIOUXSettings.showstatusline = TRUE; + + SIOUXSettings.columns = 100; + SIOUXSettings.rows = 40; + + /* 30 = MacZip Johnny Lee's; 40 = new (my) MacZip */ + MacZip.MacZipMode = NewZipMode_EF; + + argc = ccommand(&argv); + if (verbose) PrintArguments(argc, argv); + + ZipInitAllVars(); + + return_code = zipmain(argc, argv); + + if (verbose) printf("\n\n Finish"); + return return_code; +} + + + +/* +** SIOUX needs no extra event handling +** +*/ + +void UserStop(void) +{ +}; + + + + +/* +** Password enter function '*' printed for each char +** +*/ + +int macgetch(void) +{ + WindowPtr whichWindow; + EventRecord theEvent; + char c; /* one-byte buffer for read() to use */ + + do { + SystemTask(); + if (!GetNextEvent(everyEvent, &theEvent)) + theEvent.what = nullEvent; + else { + switch (theEvent.what) { + case keyDown: + c = theEvent.message & charCodeMask; + break; + case mouseDown: + if (FindWindow(theEvent.where, &whichWindow) == + inSysWindow) + SystemClick(&theEvent, whichWindow); + break; + case updateEvt: + break; + } + } + } while (theEvent.what != keyDown); + + printf("*"); + fflush(stdout); + + return (int)c; +} + +#endif + + + + +/******************************/ +/* Function version_local() */ +/******************************/ + +/* +** Print Compilers version and compile time/date +** +*/ + +void version_local() +{ +/* prints e.g: +Compiled with Metrowerks CodeWarrior version 2000 for PowerPC Processor + compile time: Feb 4 1998 17:49:49. +*/ + +static ZCONST char CompiledWith[] = + "\n\nCompiled with %s %x for %s \n %s %s %s.\n\n"; + + printf(CompiledWith, + + +#ifdef __MWERKS__ + " Metrowerks CodeWarrior version", __MWERKS__, +#endif + + +#ifdef __MC68K__ + " MC68K Processor", +#else + " PowerPC Processor", +#endif + +#ifdef __DATE__ + "compile time: ", __DATE__, __TIME__ +#else + "", "", "" +#endif + ); +} /* end function version_local() */ + + + + + +/* +** Deletes a dir if the switch '-m' is used +** +*/ + +int deletedir(char *path) +{ +static char Num = 0; +static FSSpec trashfolder; +static Boolean FirstCall = true; +static Boolean Immediate_File_Deletion = false; +OSErr err; +FSSpec dirToDelete; +char currpath[NAME_MAX], *envptr; +CInfoPBRec fpb; + +/* init this function */ +if ((path == NULL) || + (strlen(path) == 0)) + { + Num = 0; + FirstCall = true; + return -1; + } + +UserStop(); + +GetCompletePath(currpath,path,&dirToDelete, &err); + +if (FirstCall == true) + { + FirstCall = false; + envptr = getenv("Immediate_File_Deletion"); + if (!(envptr == (char *)NULL || *envptr == '\0')) + { + if (stricmp(envptr,"yes") == 0) + Immediate_File_Deletion = true; + else + Immediate_File_Deletion = false; + } + err = FSpFindFolder(dirToDelete.vRefNum, kTrashFolderType, + kDontCreateFolder,&trashfolder); + printerr("FSpFindFolder:",err,err,__LINE__,__FILE__,path); + } + + fpb.dirInfo.ioNamePtr = dirToDelete.name; + fpb.dirInfo.ioVRefNum = dirToDelete.vRefNum; + fpb.dirInfo.ioDrDirID = dirToDelete.parID; + fpb.dirInfo.ioFDirIndex = 0; + + err = PBGetCatInfoSync(&fpb); + printerr("PBGetCatInfo deletedir ", err, err, + __LINE__, __FILE__, ""); + +if (fpb.dirInfo.ioDrNmFls > 0) + { + return 0; /* do not move / delete folders which are not empty */ + } + +if (Immediate_File_Deletion) + { + err = FSpDelete(&dirToDelete); + return err; + } + +err = CatMove (dirToDelete.vRefNum, dirToDelete.parID, + dirToDelete.name, trashfolder.parID, trashfolder.name); + +/* -48 = file is already existing so we have to rename it before + moving the file */ +if (err == -48) + { + Num++; + if (dirToDelete.name[0] >= 28) /* cut foldername if to long */ + dirToDelete.name[0] = 28; + P2CStr(dirToDelete.name); + sprintf(currpath,"%s~%d",(char *)dirToDelete.name,Num); + C2PStr(currpath); + C2PStr((char *)dirToDelete.name); + err = HRename (dirToDelete.vRefNum, dirToDelete.parID, + dirToDelete.name, (unsigned char *) currpath); + + err = CatMove (dirToDelete.vRefNum, dirToDelete.parID, + (unsigned char *) currpath, trashfolder.parID, + trashfolder.name); + } + +return err; +} + + + + +/* +** Set the file-type so the archive will get the correct icon, type +** and creator code. +*/ + +void setfiletype(char *new_f, unsigned long Creator, unsigned long Type) +{ +OSErr err; + +if (strcmp(zipfile, new_f) == 0) + err = FSpChangeCreatorType(&MacZip.ZipFileSpec, Creator, Type); +printerr("FSpChangeCreatorType:", err, err, __LINE__, __FILE__, new_f); + +return; +} + + + + + +/* +** Convert the external (native) filename into Zip's internal Unix compatible +** name space. +*/ + +char *ex2in(char *externalFilen, int isdir, int *pdosflag) +/* char *externalFilen external file name */ +/* int isdir input: externalFilen is a directory */ +/* int *pdosflag output: force MSDOS file attributes? */ +/* Convert the external file name to a zip file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *internalFilen; /* internal file name (malloc'ed) */ + char *t; /* shortened name */ + char *Pathname; + char buffer[NAME_MAX]; + int dosflag; + + AssertStr(externalFilen, externalFilen) + AssertBool(isdir,"") + + dosflag = dosify; /* default for non-DOS and non-OS/2 */ + + /* Find starting point in name before doing malloc */ + for (t = externalFilen; *t == PATH_END; t++) + ; + + if (!MacZip.StoreFullPath) + { + Pathname = StripPartialDir(buffer, MacZip.SearchDir,t); + } + else + { + Pathname = t; + } + + /* Make changes, if any, to the copied name (leave original intact) */ + if (!pathput) + { + t = last(Pathname, PATH_END); + } + else t = Pathname; + + /* Malloc space for internal name and copy it */ + if ((internalFilen = malloc(strlen(t) + 10 + strlen(ResourceMark) )) == NULL) + return NULL; + + sstrcpy(internalFilen, t); + + /* we have to eliminate illegal chars: + * The name space for Mac filenames and Zip filenames (unix style names) + * do both include all printable extended-ASCII characters. The only + * difference we have to take care of is the single special character + * used as path delimiter: + * ':' on MacOS and '/' on Unix and '\' on Dos. + * So, to convert between Mac filenames and Unix filenames without any + * loss of information, we simply interchange ':' and '/'. Additionally, + * we try to convert the coding of the extended-ASCII characters into + * InfoZip's standard ISO 8859-1 codepage table. + */ + MakeCompatibleString(internalFilen, ':', '/', '/', ':', + MacZip.CurrTextEncodingBase); + + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + + if (isdir) + { + return internalFilen; /* avoid warning on unused variable */ + } + + if (dosify) + { + msname(internalFilen); + printf("\n ex2in: %s",internalFilen); + } + + return internalFilen; +} + + + +/* +** Collect all filenames. Go through all directories +** +*/ + +int wild(char *Pathpat) + /* path/pattern to match */ +/* If not in exclude mode, expand the pattern based on the contents of the + file system. Return an error code in the ZE_ class. */ +{ +FSSpec Spec; +char fullpath[NAME_MAX]; +OSErr err; + +AssertStr(Pathpat, Pathpat); + +if (noisy) printf("%s \n\n",GetZipVersionsInfo()); + +if (extra_fields == 0) + { + MacZip.DataForkOnly = true; + } + +/* for switch '-R' -> '.' means current dir */ +if (strcmp(Pathpat,".") == 0) sstrcpy(Pathpat,"*"); + +sstrcpy(MacZip.Pattern,Pathpat); + +if (recurse) + { + MacZip.StoreFoldersAlso = true; + MacZip.SearchLevels = 0; /* if 0 we aren't checking levels */ + } +else + { + MacZip.StoreFoldersAlso = false; + MacZip.SearchLevels = 1; + } + +/* make complete path */ +GetCompletePath(fullpath, MacZip.Pattern, &Spec,&err); +err = PrintUserHFSerr((err != -43) && (err != 0), err, MacZip.Pattern); +printerr("GetCompletePath:", err, err, __LINE__, __FILE__, fullpath); + +/* extract the filepattern */ +GetFilename(MacZip.Pattern, fullpath); + +/* extract Path and get FSSpec of search-path */ +/* get FSSpec of search-path ; we need a dir to start + searching for filenames */ +TruncFilename(MacZip.SearchDir, fullpath); +GetCompletePath(MacZip.SearchDir, MacZip.SearchDir, &Spec,&err); + +if (noisy) { + if (MacZip.SearchLevels == 0) + { + printf("\nSearch Pattern: [%s] Levels: all", MacZip.Pattern); + } + else + { + printf("\nSearch Pattern: [%s] Levels: %d", MacZip.Pattern, + MacZip.SearchLevels); + } + printf("\nSearch Path: [%s]", MacZip.SearchDir); + printf("\nZip-File: [%s] \n",MacZip.ZipFullPath); + +} + +/* we are working only with pathnames; + * this can cause big problems on a mac ... + */ +if (CheckMountedVolumes(MacZip.SearchDir) > 1) + DoWarnUserDupVol(MacZip.SearchDir); + +/* start getting all filenames */ +err = FSpRecurseDirectory(&Spec, MacZip.SearchLevels); +printerr("FSpRecurseDirectory:", err, err, __LINE__, __FILE__, ""); + +return ZE_OK; +} + + + +/* +** Convert the internal filename into a external (native). +** The user will see this modified filename. +** For more performance: +** I do not completly switch back to the native macos filename. +** The user will still see directory separator '/' and the converted +** charset. +*/ + +char *in2ex(char *n) /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + AssertStr(n,n) + + if ((x = malloc(strlen(n) + 1)) == NULL) + return NULL; + + RfDfFilen2Real(x, n, MacZip.MacZipMode, MacZip.DataForkOnly, + &MacZip.CurrentFork); + + return x; +} + + + + +/* +** Process on filenames. This function will be called to collect +** the filenames. +*/ + +int procname(char *filename, /* name to process */ + int caseflag) /* true to force case-sensitive match + (always false on a Mac) */ +/* Process a name . Return + an error code in the ZE_ class. */ +{ + int rc; /* matched flag */ + +AssertBool(caseflag,"caseflag") +AssertStr(filename,filename) + + /* add or remove name of file */ +rc = newname(filename, MacZip.isDirectory, caseflag); + +return rc; +} + + + + +ulg filetime( +char *f, /* name of file to get info on */ +ulg *a, /* return value: file attributes */ +long *n, /* return value: file size */ +iztimes *t) /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + + AssertStr(f,f) + + if (strlen(f) == 0) return 0; + + if (SSTAT(f, &s) != 0) + /* Accept about any file kind including directories + * (stored with trailing : with -r option) + */ + return 0; + + if (a != NULL) { + *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE); + if (MacZip.isDirectory) { + *a |= MSDOS_DIR_ATTR; + } + } + if (n != NULL) + *n = (s.st_mode & UNX_IFMT) == UNX_IFREG ? s.st_size : -1L; + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_ctime; /* on Mac, st_ctime contains creation time! */ + } + + return unix2dostime(&s.st_mtime); +} + + + +void stamp(char *f, ulg d) +/* char *f; name of file to change */ +/* ulg d; dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ + time_t u[2]; /* argument for utime() */ + +f = f; + + /* Convert DOS time to time_t format in u */ + + u[0] = u[1] = dos2unixtime(d); +/* utime(f, u); */ +} + + + + +/* +** return only the longest part of the path: +** second parameter: Volume:test folder:second folder: +** third parameter: Volume:test folder:second folder:third folder:file +** result will be: third folder:file +** first parameter: contains string buffer that will be used to prepend +** the "resource mark" part in front of the result when +** a resource fork is processed in "M3" mode. +** +*/ + +char *StripPartialDir(char *CompletePath, + const char *PartialPath, const char *FullPath) +{ +const char *tmpPtr1 = PartialPath; +const char *tmpPtr2 = FullPath; +int result; + +Assert_it(CompletePath,"StripPartialDir","") +AssertStrNoOverlap(FullPath,PartialPath,PartialPath) + +if (MacZip.DataForkOnly) + { + tmpPtr2 += strlen(tmpPtr1); + return (char *)tmpPtr2; + } + +switch (MacZip.MacZipMode) + { + case JohnnyLee_EF: + { + tmpPtr2 += strlen(tmpPtr1); + return (char *)tmpPtr2; + break; + } + + case NewZipMode_EF: + { /* determine Fork type */ + result = strncmp(FullPath, ResourceMark, sizeof(ResourceMark)-2); + if (result != 0) + { /* data fork */ + MacZip.CurrentFork = DataFork; + tmpPtr2 += strlen(tmpPtr1); + return (char *)tmpPtr2; + } + else + { /* resource fork */ + MacZip.CurrentFork = ResourceFork; + sstrcpy(CompletePath, ResourceMark); + tmpPtr2 += strlen(tmpPtr1); + tmpPtr2 += sizeof(ResourceMark); + sstrcat(CompletePath, tmpPtr2); + return (char *)CompletePath; + } + break; + } + } + + return NULL; /* function should never reach this point */ +} + + + + +/* +** Init all global variables +** Must be called for each zip-run +*/ + +void ZipInitAllVars(void) +{ +getcwd(MacZip.CurrentPath, sizeof(MacZip.CurrentPath)); +/* MacZip.MacZipMode = JohnnyLee_EF; */ +MacZip.MacZipMode = NewZipMode_EF; + +MacZip.DataForkOnly = false; +MacZip.CurrentFork = NoFork; + +MacZip.StoreFoldersAlso = false; + +MacZip.FoundFiles = 0; +MacZip.FoundDirectories = 0; +MacZip.RawCountOfItems = 0; +MacZip.BytesOfData = 0; + +MacZip.StoreFullPath = false; +MacZip.StatingProgress = false; +MacZip.IncludeInvisible = false; + +MacZip.isMacStatValid = false; + +MacZip.CurrTextEncodingBase = FontScript(); + +MacZip.HaveGMToffset = false; + +createTime = TickCount(); +estTicksToFinish = -1; +updateTicks = 0; + +/* init some functions */ +IsZipFile(NULL); + +destroy(NULL); +deletedir(NULL); +ShowCounter(true); + +extra_fields = 1; +error_level = 0; +count_of_Zippedfiles = 0; +} + + + + +/* +** Get the findercomment and store it as file-comment in the Zip-file +** +*/ +char *GetComment(char *filename) +{ +OSErr err; +static char buffer[NAME_MAX]; +char buffer2[NAME_MAX]; +char *tmpPtr; + +if (filename == NULL) return NULL; + + /* now we can convert Unix-Path in HFS-Path */ +for (tmpPtr = filename; *tmpPtr; tmpPtr++) + if (*tmpPtr == '/') + *tmpPtr = ':'; + +if (MacZip.StoreFullPath) + { /* filename is already a fullpath */ + sstrcpy(buffer,filename); + } +else + { /* make a fullpath */ + sstrcpy(buffer,MacZip.SearchDir); + sstrcat(buffer,filename); + } + +/* make fullpath and get FSSpec */ +/* Unfortunately: I get only the converted filename here */ +/* so filenames with extended characters can not be found */ +GetCompletePath(buffer2,buffer, &MacZip.fileSpec, &err); +printerr("GetCompletePath:",(err != -43) && (err != -120) && (err != 0) , + err,__LINE__,__FILE__,buffer); + +err = FSpDTGetComment(&MacZip.fileSpec, (unsigned char *) buffer); +printerr("FSpDTGetComment:", (err != -5012) && (err != 0), err, + __LINE__, __FILE__, filename); +P2CStr((unsigned char *) buffer); +if (err == -5012) return NULL; /* no finder-comments found */ + +if (noisy) printf("\n%32s -> %s",filename, buffer); +/* +Beside the script change we need only to change 0x0d in 0x0a +so the last two arguments are not needed and does nothing. +*/ +MakeCompatibleString(buffer, 0x0d, 0x0a, ' ', ' ', + MacZip.CurrTextEncodingBase); + +return buffer; +} + + + + +/* +** Print a progress indicator for stating the files +** +*/ + +void PrintStatProgress(char *msg) +{ + +if (!noisy) return; /* do no output if noisy is false */ + +MacZip.StatingProgress = true; + +if (strcmp(msg,"done") == 0) + { + MacZip.StatingProgress = false; + printf("\n ... done \n\n"); + } +else printf("\n %s",msg); + +} + + + + +void InformProgress(const long progressMax, const long progressSoFar ) +{ +int curr_percent; +char no_time[5] = "..."; + +curr_percent = percent(progressMax, progressSoFar); + +if (curr_percent < 95) + { + estTicksToFinish = EstimateCompletionTime(progressMax, + progressSoFar, curr_percent); + } +else + { + rightStatusString(no_time); + leftStatusString(no_time); + } + +updateTicks = TickCount() + 60; +return; +} + + +void ShowCounter(Boolean reset) +{ +static char statusline[100]; +static unsigned long filecount = 0; + +if (reset) + { + filecount = 0; + return; + } + +if (noisy) + { + sprintf(statusline, "%6d", filecount++); + rightStatusString(statusline); + } +} + + +static long EstimateCompletionTime(const long progressMax, + const long progressSoFar, + unsigned char curr_percent) +{ + long max = progressMax, value = progressSoFar; + static char buf[100]; + unsigned long ticksTakenSoFar = TickCount() - createTime; + float currentRate = (float) ticksTakenSoFar / (float) value; + long newEst = (long)( currentRate * (float)( max - value )); + + sprintf(buf, "%d [%d%%]",progressSoFar, curr_percent); + rightStatusString(buf); + + estTicksToFinish = newEst; + + UpdateTimeToComplete(); + +return estTicksToFinish; +} + + + + + +static void UpdateTimeToComplete(void) +{ + short days, hours, minutes, seconds; + char estStr[255]; + Str15 xx, yy; + short idx = 0; + + if ( estTicksToFinish == -1 ) + return; + + days = estTicksToFinish / 5184000L; + hours = ( estTicksToFinish - ( days * 5184000L )) / 216000L; + minutes = ( estTicksToFinish - ( days * 5184000L ) - + ( hours * 216000L )) / 3600L; + seconds = ( estTicksToFinish - ( days * 5184000L ) - + ( hours * 216000L ) - ( minutes * 3600L )) / 60L; + + xx[0] = 0; + yy[0] = 0; + + if ( days ) + { + /* "more than 24 hours" */ + + idx = 1; + goto setEstTimeStr; + } + + if ( hours >= 8 ) + { + /* "more than x hours" */ + + NumToString( hours, xx ); + idx = 2; + goto setEstTimeStr; + } + + if ( estTicksToFinish > 252000L ) /* > 1hr, 10 minutes */ + { + /* "about x hours, y minutes" */ + + NumToString( hours, xx ); + NumToString( minutes, yy ); + idx = 3; + goto setEstTimeStr; + } + + if ( estTicksToFinish > 198000L ) /* > 55 minutes */ + { + /* "about an hour" */ + idx = 4; + goto setEstTimeStr; + } + + if ( estTicksToFinish > 144000L ) /* > 40 minutes */ + { + /* "less than an hour" */ + + idx = 5; + goto setEstTimeStr; + } + + if ( estTicksToFinish > 4200L ) /* > 1 minute, 10 sec */ + { + /* "about x minutes, y seconds */ + + NumToString( minutes, xx ); + NumToString( seconds, yy ); + + if ( minutes == 1 ) + idx = 11; + else + idx = 6; + goto setEstTimeStr; + } + + if ( estTicksToFinish > 3000L ) /* > 50 seconds */ + { + /* "about a minute" */ + + idx = 7; + goto setEstTimeStr; + } + + if ( estTicksToFinish > 1500L ) /* > 25 seconds */ + { + /* "less than a minute" */ + + idx = 8; + goto setEstTimeStr; + } + + if ( estTicksToFinish > 120L ) /* > 2 seconds */ + { + NumToString( seconds, xx ); + idx = 9; + goto setEstTimeStr; + } + + idx = 10; + + setEstTimeStr: + sprintf(estStr,Time_Est_strings[idx],P2CStr(xx),P2CStr(yy)); + leftStatusString((char *)estStr); +} + + + + + +/* +** Just return the zip version +** +*/ + +char *GetZipVersionsInfo(void) +{ +static char ZipVersion[100]; + +sprintf(ZipVersion, "Zip Module\n%d.%d%d%s of %s", Z_MAJORVER, Z_MINORVER, + Z_PATCHLEVEL, Z_BETALEVEL, REVDATE); + +return ZipVersion; +} + + + + +#ifndef USE_SIOUX + +/* +** Just return the copyright message +** +*/ + +char *GetZipCopyright(void) +{ +static char CopyR[300]; + +sstrcpy(CopyR, copyright[0]); +sstrcat(CopyR, copyright[1]); +sstrcat(CopyR, "\r\rPlease send bug reports to the authors at\r"\ + "Zip-Bugs@lists.wku.edu"); + +return CopyR; +} + + + + +/* +** Just return the compilers date/time +** +*/ + +char *GetZipVersionLocal(void) +{ +static char ZipVersionLocal[50]; + +sprintf(ZipVersionLocal, "[%s %s]", __DATE__, __TIME__); + +return ZipVersionLocal; +} + +#endif /* #ifndef USE_SIOUX */ + + + + diff --git a/macos/source/macstuff.c b/macos/source/macstuff.c new file mode 100644 index 0000000..0323607 --- /dev/null +++ b/macos/source/macstuff.c @@ -0,0 +1,1724 @@ +/* +These Functions were originally part of More Files version 1.4.8 + +More Files fixes many of the broken or underfunctional +parts of the file system. + +More Files + +A collection of File Manager and related routines + +by Jim Luther (Apple Macintosh Developer Technical Support Emeritus) +with significant code contributions by Nitin Ganatra +(Apple Macintosh Developer Technical Support Emeritus) +Copyright 1992-1998 Apple Computer, Inc. +Portions copyright 1995 Jim Luther +All rights reserved. + +The Package "More Files" is distributed under the following +license terms: + + "You may incorporate this sample code into your + applications without restriction, though the + sample code has been provided "AS IS" and the + responsibility for its operation is 100% yours. + However, what you are not permitted to do is to + redistribute the source as "DSC Sample Code" after + having made changes. If you're going to + redistribute the source, we require that you make + it clear in the source that the code was descended + from Apple Sample Code, but that you've made + changes." + + +The following changes are made by Info-ZIP: + +- The only changes are made by pasting the functions + (mostly found in MoreFilesExtras.c / MoreFiles.c) + directly into macstuff.c / macstuff.h and slightly + reformatting the text (replacement of TABs by spaces, + removal/replacement of non-ASCII characters). + The code itself is NOT changed. + +This file has been modified by Info-ZIP for use in MacZip. +This file is NOT part of the original package More Files. + +More Files can be found on the MetroWerks CD and Developer CD from +Apple. You can also download the latest version from: + + http://members.aol.com/JumpLong/#MoreFiles + +Jim Luther's Home-page: + http://members.aol.com/JumpLong/ + + +*/ + +#include + + +#include "macstuff.h" + + + +extern int errno; + +static OSErr GetCommentFromDesktopFile(short vRefNum, + long dirID, + ConstStr255Param name, + Str255 comment); + +static OSErr GetCommentID(short vRefNum, + long dirID, + ConstStr255Param name, + short *commentID); + +static OSErr GetDesktopFileName(short vRefNum, + Str255 desktopName); + + +enum +{ + kBNDLResType = 'BNDL', + kFREFResType = 'FREF', + kIconFamResType = 'ICN#', + kFCMTResType = 'FCMT', + kAPPLResType = 'APPL' +}; + + +/*****************************************************************************/ + +/* +** File Manager FSp calls +*/ + +/*****************************************************************************/ + +pascal OSErr FSMakeFSSpecCompat(short vRefNum, + long dirID, + ConstStr255Param fileName, + FSSpec *spec) +{ + OSErr result; + +#if !__MACOSSEVENORLATER + if ( !FSHasFSSpecCalls() && !QTHasFSSpecCalls() ) + { + Boolean isDirectory; + + result = GetObjectLocation(vRefNum, dirID, fileName, + &(spec->vRefNum), &(spec->parID), spec->name, + &isDirectory); + } + else +#endif /* !__MACOSSEVENORLATER */ + { + /* Let the file system create the FSSpec if it can since it does the job */ + /* much more efficiently than I can. */ + result = FSMakeFSSpec(vRefNum, dirID, fileName, spec); + + /* Fix a bug in Macintosh PC Exchange's MakeFSSpec code where 0 is */ + /* returned in the parID field when making an FSSpec to the volume's */ + /* root directory by passing a full pathname in MakeFSSpec's */ + /* fileName parameter. Fixed in Mac OS 8.1 */ + if ( (result == noErr) && (spec->parID == 0) ) + spec->parID = fsRtParID; + } + return ( result ); +} + + +/*****************************************************************************/ +/* FSHasFSSpecCalls returns true if the file system provides FSSpec calls. */ + +#if !__MACOSSEVENORLATER +static Boolean FSHasFSSpecCalls(void) +{ + long response; +#if !GENERATENODATA + static Boolean tested = false; + static Boolean result = false; +#else + Boolean result = false; +#endif + +#if !GENERATENODATA + if ( !tested ) + { + tested = true; +#endif + if ( Gestalt(gestaltFSAttr, &response) == noErr ) + { + result = ((response & (1L << gestaltHasFSSpecCalls)) != 0); + } +#if !GENERATENODATA + } +#endif + return ( result ); +} +#endif /* !__MACOSSEVENORLATER */ + + + +/*****************************************************************************/ +/* QTHasFSSpecCalls returns true if QuickTime provides FSSpec calls */ +/* except for FSpExchangeFiles. */ + +#if !__MACOSSEVENORLATER +static Boolean QTHasFSSpecCalls(void) +{ + long response; +#if !GENERATENODATA + static Boolean tested = false; + static Boolean result = false; +#else + Boolean result = false; +#endif + +#if !GENERATENODATA + if ( !tested ) + { + tested = true; +#endif + result = (Gestalt(gestaltQuickTimeVersion, &response) == noErr); +#if !GENERATENODATA + } +#endif + return ( result ); +} +#endif /* !__MACOSSEVENORLATER */ + + + + +/* + *---------------------------------------------------------------------- + * + * FSpGetDefaultDir -- + * + * This function gets the current default directory. + * + * Results: + * The provided FSSpec is changed to point to the "default" + * directory. The function returns what ever errors + * FSMakeFSSpecCompat may encounter. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int FSpGetDefaultDir(FSSpecPtr dirSpec) /* On return the default directory. */ +{ + OSErr err; + short vRefNum = 0; + long int dirID = 0; + + err = HGetVol(NULL, &vRefNum, &dirID); + + if (err == noErr) { + err = FSMakeFSSpecCompat(vRefNum, dirID, (ConstStr255Param) NULL, + dirSpec); + } + + return err; +} + +/* + *---------------------------------------------------------------------- + * + * FSpSetDefaultDir -- + * + * This function sets the default directory to the directory + * pointed to by the provided FSSpec. + * + * Results: + * The function returns what ever errors HSetVol may encounter. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int FSpSetDefaultDir(FSSpecPtr dirSpec) /* The new default directory. */ +{ + OSErr err; + + /* + * The following special case is needed to work around a bug + * in the Macintosh OS. (Acutally PC Exchange.) + */ + + if (dirSpec->parID == fsRtParID) { + err = HSetVol(NULL, dirSpec->vRefNum, fsRtDirID); + } else { + err = HSetVol(dirSpec->name, dirSpec->vRefNum, dirSpec->parID); + } + + return err; +} + +/* + *---------------------------------------------------------------------- + * + * FSpFindFolder -- + * + * This function is a version of the FindFolder function that + * returns the result as a FSSpec rather than a vRefNum and dirID. + * + * Results: + * Results will be simaler to that of the FindFolder function. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +OSErr +FSpFindFolder( + short vRefNum, /* Volume reference number. */ + OSType folderType, /* Folder type taken by FindFolder. */ + Boolean createFolder, /* Should we create it if non-existant. */ + FSSpec *spec) /* Pointer to resulting directory. */ +{ + short foundVRefNum; + long foundDirID; + OSErr err; + + err = FindFolder(vRefNum, folderType, createFolder, + &foundVRefNum, &foundDirID); + if (err != noErr) { + return err; + } + + err = FSMakeFSSpecCompat(foundVRefNum, foundDirID, "\p", spec); + return err; +} + + + +/* + *---------------------------------------------------------------------- + * + * FSpPathFromLocation -- + * + * This function obtains a full path name for a given macintosh + * FSSpec. Unlike the More Files function FSpGetFullPath, this + * function will return a C string in the Handle. It also will + * create paths for FSSpec that do not yet exist. + * + * Results: + * OSErr code. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +OSErr +FSpPathFromLocation( + FSSpec *spec, /* The location we want a path for. */ + int *length, /* Length of the resulting path. */ + Handle *fullPath) /* Handle to path. */ +{ + OSErr err; + FSSpec tempSpec; + CInfoPBRec pb; + + *fullPath = NULL; + + /* + * Make a copy of the input FSSpec that can be modified. + */ + BlockMoveData(spec, &tempSpec, sizeof(FSSpec)); + + if (tempSpec.parID == fsRtParID) { + /* + * The object is a volume. Add a colon to make it a full + * pathname. Allocate a handle for it and we are done. + */ + tempSpec.name[0] += 2; + tempSpec.name[tempSpec.name[0] - 1] = ':'; + tempSpec.name[tempSpec.name[0]] = '\0'; + + err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); + } else { + /* + * The object isn't a volume. Is the object a file or a directory? + */ + pb.dirInfo.ioNamePtr = tempSpec.name; + pb.dirInfo.ioVRefNum = tempSpec.vRefNum; + pb.dirInfo.ioDrDirID = tempSpec.parID; + pb.dirInfo.ioFDirIndex = 0; + err = PBGetCatInfoSync(&pb); + + if ((err == noErr) || (err == fnfErr)) { + /* + * If the file doesn't currently exist we start over. If the + * directory exists everything will work just fine. Otherwise we + * will just fail later. If the object is a directory, append a + * colon so full pathname ends with colon. + */ + if (err == fnfErr) { + BlockMoveData(spec, &tempSpec, sizeof(FSSpec)); + } else if ( (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0 ) { + tempSpec.name[0] += 1; + tempSpec.name[tempSpec.name[0]] = ':'; + } + + /* + * Create a new Handle for the object - make it a C string. + */ + tempSpec.name[0] += 1; + tempSpec.name[tempSpec.name[0]] = '\0'; + err = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); + if (err == noErr) { + /* + * Get the ancestor directory names - loop until we have an + * error or find the root directory. + */ + pb.dirInfo.ioNamePtr = tempSpec.name; + pb.dirInfo.ioVRefNum = tempSpec.vRefNum; + pb.dirInfo.ioDrParID = tempSpec.parID; + do { + pb.dirInfo.ioFDirIndex = -1; + pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID; + err = PBGetCatInfoSync(&pb); + if (err == noErr) { + /* + * Append colon to directory name and add + * directory name to beginning of fullPath. + */ + ++tempSpec.name[0]; + tempSpec.name[tempSpec.name[0]] = ':'; + + (void) Munger(*fullPath, 0, NULL, 0, &tempSpec.name[1], + tempSpec.name[0]); + err = MemError(); + } + } while ( (err == noErr) && + (pb.dirInfo.ioDrDirID != fsRtDirID) ); + } + } + } + + /* + * On error Dispose the handle, set it to NULL & return the err. + * Otherwise, set the length & return. + */ + if (err == noErr) { + *length = GetHandleSize(*fullPath) - 1; + } else { + if ( *fullPath != NULL ) { + DisposeHandle(*fullPath); + } + *fullPath = NULL; + *length = 0; + } + + return err; +} + + + +/*****************************************************************************/ + +pascal OSErr FSpGetDirectoryID(const FSSpec *spec, + long *theDirID, + Boolean *isDirectory) +{ + return ( GetDirectoryID(spec->vRefNum, spec->parID, spec->name, + theDirID, isDirectory) ); +} + + +/*****************************************************************************/ + +pascal OSErr GetDirectoryID(short vRefNum, + long dirID, + ConstStr255Param name, + long *theDirID, + Boolean *isDirectory) +{ + CInfoPBRec pb; + OSErr error; + + error = GetCatInfoNoName(vRefNum, dirID, name, &pb); + if ( error == noErr ) + { + *isDirectory = (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0; + if ( *isDirectory ) + { + *theDirID = pb.dirInfo.ioDrDirID; + } + else + { + *theDirID = pb.hFileInfo.ioFlParID; + } + } + + return ( error ); +} + + +/*****************************************************************************/ + +pascal OSErr GetCatInfoNoName(short vRefNum, + long dirID, + ConstStr255Param name, + CInfoPBPtr pb) +{ + Str31 tempName; + OSErr error; + + /* Protection against File Sharing problem */ + if ( (name == NULL) || (name[0] == 0) ) + { + tempName[0] = 0; + pb->dirInfo.ioNamePtr = tempName; + pb->dirInfo.ioFDirIndex = -1; /* use ioDirID */ + } + else + { + pb->dirInfo.ioNamePtr = (StringPtr)name; + pb->dirInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */ + } + pb->dirInfo.ioVRefNum = vRefNum; + pb->dirInfo.ioDrDirID = dirID; + error = PBGetCatInfoSync(pb); + pb->dirInfo.ioNamePtr = NULL; + return ( error ); +} + + + +/*****************************************************************************/ + +pascal OSErr GetObjectLocation(short vRefNum, + long dirID, + ConstStr255Param pathname, + short *realVRefNum, + long *realParID, + Str255 realName, + Boolean *isDirectory) +{ + OSErr error; + CInfoPBRec pb; + Str255 tempPathname; + + /* clear results */ + *realVRefNum = 0; + *realParID = 0; + realName[0] = 0; + + /* + ** Get the real vRefNum + */ + error = DetermineVRefNum(pathname, vRefNum, realVRefNum); + if ( error == noErr ) + { + /* + ** Determine if the object already exists and if so, + ** get the real parent directory ID if it's a file + */ + + /* Protection against File Sharing problem */ + if ( (pathname == NULL) || (pathname[0] == 0) ) + { + tempPathname[0] = 0; + pb.hFileInfo.ioNamePtr = tempPathname; + pb.hFileInfo.ioFDirIndex = -1; /* use ioDirID */ + } + else + { + pb.hFileInfo.ioNamePtr = (StringPtr)pathname; + pb.hFileInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */ + } + pb.hFileInfo.ioVRefNum = vRefNum; + pb.hFileInfo.ioDirID = dirID; + error = PBGetCatInfoSync(&pb); + if ( error == noErr ) + { + /* + ** The file system object is present and we have the file's + ** real parID + */ + + /* Is it a directory or a file? */ + *isDirectory = (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0; + if ( *isDirectory ) + { + /* + ** It's a directory, get its name and parent dirID, and then + ** we're done + */ + + pb.dirInfo.ioNamePtr = realName; + pb.dirInfo.ioVRefNum = *realVRefNum; + /* pb.dirInfo.ioDrDirID already contains the dirID of the + directory object */ + pb.dirInfo.ioFDirIndex = -1; /* get information about ioDirID */ + error = PBGetCatInfoSync(&pb); + + /* get the parent ID here, because the file system can return the */ + /* wrong parent ID from the last call. */ + *realParID = pb.dirInfo.ioDrParID; + } + else + { + /* + ** It's a file - use the parent directory ID from the last call + ** to GetCatInfoparse, get the file name, and then we're done + */ + *realParID = pb.hFileInfo.ioFlParID; + error = GetFilenameFromPathname(pathname, realName); + } + } + else if ( error == fnfErr ) + { + /* + ** The file system object is not present - see if its parent is present + */ + + /* + ** Parse to get the object name from end of pathname + */ + error = GetFilenameFromPathname(pathname, realName); + + /* if we can't get the object name from the end, we can't continue */ + if ( error == noErr ) + { + /* + ** What we want now is the pathname minus the object name + ** for example: + ** if pathname is 'vol:dir:file' tempPathname becomes 'vol:dir:' + ** if pathname is 'vol:dir:file:' tempPathname becomes 'vol:dir:' + ** if pathname is ':dir:file' tempPathname becomes ':dir:' + ** if pathname is ':dir:file:' tempPathname becomes ':dir:' + ** if pathname is ':file' tempPathname becomes ':' + ** if pathname is 'file or file:' tempPathname becomes '' + */ + + /* get a copy of the pathname */ + BlockMoveData(pathname, tempPathname, pathname[0] + 1); + + /* remove the object name */ + tempPathname[0] -= realName[0]; + /* and the trailing colon (if any) */ + if ( pathname[pathname[0]] == ':' ) + { + --tempPathname[0]; + } + + /* OK, now get the parent's directory ID */ + + /* Protection against File Sharing problem */ + pb.hFileInfo.ioNamePtr = (StringPtr)tempPathname; + if ( tempPathname[0] != 0 ) + { + pb.hFileInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */ + } + else + { + pb.hFileInfo.ioFDirIndex = -1; /* use ioDirID */ + } + pb.hFileInfo.ioVRefNum = vRefNum; + pb.hFileInfo.ioDirID = dirID; + error = PBGetCatInfoSync(&pb); + *realParID = pb.dirInfo.ioDrDirID; + + *isDirectory = false; /* we don't know what the object is + really going to be */ + } + + if ( error != noErr ) + { + error = dirNFErr; /* couldn't find parent directory */ + } + else + { + error = fnfErr; /* we found the parent, but not the file */ + } + } + } + + return ( error ); +} + + + +/*****************************************************************************/ + +pascal OSErr DetermineVRefNum(ConstStr255Param pathname, + short vRefNum, + short *realVRefNum) +{ + HParamBlockRec pb; + OSErr error; + + error = GetVolumeInfoNoName(pathname,vRefNum, &pb); + if ( error == noErr ) + { + *realVRefNum = pb.volumeParam.ioVRefNum; + } + return ( error ); +} + + +/*****************************************************************************/ + +pascal OSErr GetFilenameFromPathname(ConstStr255Param pathname, + Str255 filename) +{ + short index; + short nameEnd; + OSErr error; + + /* default to no filename */ + filename[0] = 0; + + /* check for no pathname */ + if ( pathname != NULL ) + { + /* get string length */ + index = pathname[0]; + + /* check for empty string */ + if ( index != 0 ) + { + /* skip over last trailing colon (if any) */ + if ( pathname[index] == ':' ) + { + --index; + } + + /* save the end of the string */ + nameEnd = index; + + /* if pathname ends with multiple colons, then this pathname refers */ + /* to a directory, not a file */ + if ( pathname[index] != ':' ) + { + /* parse backwards until we find a colon or hit the beginning + of the pathname */ + while ( (index != 0) && (pathname[index] != ':') ) + { + --index; + } + + /* if we parsed to the beginning of the pathname and the + pathname ended */ + /* with a colon, then pathname is a full pathname to a volume, + not a file */ + if ( (index != 0) || (pathname[pathname[0]] != ':') ) + { + /* get the filename and return noErr */ + filename[0] = (char)(nameEnd - index); + BlockMoveData(&pathname[index+1], &filename[1], nameEnd - index); + error = noErr; + } + else + { + /* pathname to a volume, not a file */ + error = notAFileErr; + } + } + else + { + /* directory, not a file */ + error = notAFileErr; + } + } + else + { + /* empty string isn't a file */ + error = notAFileErr; + } + } + else + { + /* NULL pathname isn't a file */ + error = notAFileErr; + } + + return ( error ); +} + + + +/*****************************************************************************/ + +/* +** GetVolumeInfoNoName uses pathname and vRefNum to call PBHGetVInfoSync +** in cases where the returned volume name is not needed by the caller. +** The pathname and vRefNum parameters are not touched, and the pb +** parameter is initialized by PBHGetVInfoSync except that ioNamePtr in +** the parameter block is always returned as NULL (since it might point +** to the local tempPathname). +** +** I noticed using this code in several places, so here it is once. +** This reduces the code size of MoreFiles. +*/ +pascal OSErr GetVolumeInfoNoName(ConstStr255Param pathname, + short vRefNum, + HParmBlkPtr pb) +{ + Str255 tempPathname; + OSErr error; + + /* Make sure pb parameter is not NULL */ + if ( pb != NULL ) + { + pb->volumeParam.ioVRefNum = vRefNum; + if ( pathname == NULL ) + { + pb->volumeParam.ioNamePtr = NULL; + pb->volumeParam.ioVolIndex = 0; /* use ioVRefNum only */ + } + else + { /* make a copy of the string and */ + BlockMoveData(pathname, tempPathname, pathname[0] + 1); + /* use the copy so original isn't trashed */ + pb->volumeParam.ioNamePtr = (StringPtr)tempPathname; + /* use ioNamePtr/ioVRefNum combination */ + pb->volumeParam.ioVolIndex = -1; + } + error = PBHGetVInfoSync(pb); + pb->volumeParam.ioNamePtr = NULL; /* ioNamePtr may point to local + tempPathname, so don't return it */ + } + else + { + error = paramErr; + } + return ( error ); +} + + + + +/*****************************************************************************/ + +pascal OSErr FSpGetFullPath(const FSSpec *spec, + short *fullPathLength, + Handle *fullPath) +{ + OSErr result; + OSErr realResult; + FSSpec tempSpec; + CInfoPBRec pb; + + *fullPathLength = 0; + *fullPath = NULL; + + /* Default to noErr */ + realResult = noErr; + + /* Make a copy of the input FSSpec that can be modified */ + BlockMoveData(spec, &tempSpec, sizeof(FSSpec)); + + if ( tempSpec.parID == fsRtParID ) + { + /* The object is a volume */ + + /* Add a colon to make it a full pathname */ + ++tempSpec.name[0]; + tempSpec.name[tempSpec.name[0]] = ':'; + + /* We're done */ + result = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); + } + else + { + /* The object isn't a volume */ + + /* Is the object a file or a directory? */ + pb.dirInfo.ioNamePtr = tempSpec.name; + pb.dirInfo.ioVRefNum = tempSpec.vRefNum; + pb.dirInfo.ioDrDirID = tempSpec.parID; + pb.dirInfo.ioFDirIndex = 0; + result = PBGetCatInfoSync(&pb); + /* Allow file/directory name at end of path to not exist. */ + realResult = result; + if ( (result == noErr) || (result == fnfErr) ) + { + /* if the object is a directory, append a colon so full pathname + ends with colon */ + if ( (result == noErr) && (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0 ) + { + ++tempSpec.name[0]; + tempSpec.name[tempSpec.name[0]] = ':'; + } + + /* Put the object name in first */ + result = PtrToHand(&tempSpec.name[1], fullPath, tempSpec.name[0]); + if ( result == noErr ) + { + /* Get the ancestor directory names */ + pb.dirInfo.ioNamePtr = tempSpec.name; + pb.dirInfo.ioVRefNum = tempSpec.vRefNum; + pb.dirInfo.ioDrParID = tempSpec.parID; + do /* loop until we have an error or find the root directory */ + { + pb.dirInfo.ioFDirIndex = -1; + pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID; + result = PBGetCatInfoSync(&pb); + if ( result == noErr ) + { + /* Append colon to directory name */ + ++tempSpec.name[0]; + tempSpec.name[tempSpec.name[0]] = ':'; + + /* Add directory name to beginning of fullPath */ + (void) Munger(*fullPath, 0, NULL, 0, &tempSpec.name[1], + tempSpec.name[0]); + result = MemError(); + } + } while ( (result == noErr) && (pb.dirInfo.ioDrDirID != fsRtDirID) ); + } + } + } + if ( result == noErr ) + { + /* Return the length */ + *fullPathLength = InlineGetHandleSize(*fullPath); + result = realResult; /* return realResult in case it was fnfErr */ + } + else + { + /* Dispose of the handle and return NULL and zero length */ + if ( *fullPath != NULL ) + { + DisposeHandle(*fullPath); + } + *fullPath = NULL; + *fullPathLength = 0; + } + + return ( result ); +} + + + +/*****************************************************************************/ + +pascal OSErr FSpLocationFromFullPath(short fullPathLength, + const void *fullPath, + FSSpec *spec) +{ + AliasHandle alias; + OSErr result; + Boolean wasChanged; + Str32 nullString; + + /* Create a minimal alias from the full pathname */ + nullString[0] = 0; /* null string to indicate no zone or server name */ + result = NewAliasMinimalFromFullPath(fullPathLength, fullPath, nullString, + nullString, &alias); + + if ( result == noErr ) + { + /* Let the Alias Manager resolve the alias. */ + result = ResolveAlias(NULL, alias, spec, &wasChanged); + + DisposeHandle((Handle)alias); /* Free up memory used */ + } + + return ( result ); +} + + + +/*****************************************************************************/ + +pascal OSErr GetFullPath(short vRefNum, + long dirID, + ConstStr255Param name, + short *fullPathLength, + Handle *fullPath) +{ + OSErr result; + FSSpec spec; + + *fullPathLength = 0; + *fullPath = NULL; + + result = FSMakeFSSpecCompat(vRefNum, dirID, name, &spec); + if ( (result == noErr) || (result == fnfErr) ) + { + result = FSpGetFullPath(&spec, fullPathLength, fullPath); + } + + return ( result ); +} + + + +/*****************************************************************************/ + +pascal OSErr ChangeCreatorType(short vRefNum, + long dirID, + ConstStr255Param name, + OSType creator, + OSType fileType) +{ + CInfoPBRec pb; + OSErr error; + short realVRefNum; + long parID; + + pb.hFileInfo.ioNamePtr = (StringPtr)name; + pb.hFileInfo.ioVRefNum = vRefNum; + pb.hFileInfo.ioDirID = dirID; + pb.hFileInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */ + error = PBGetCatInfoSync(&pb); + if ( error == noErr ) + { + if ( (pb.hFileInfo.ioFlAttrib & ioDirMask) == 0 ) /* if file */ + { /* save parent dirID for BumpDate call */ + parID = pb.hFileInfo.ioFlParID; + + /* If creator not 0x00000000, change creator */ + if ( creator != (OSType)0x00000000 ) + { + pb.hFileInfo.ioFlFndrInfo.fdCreator = creator; + } + + /* If fileType not 0x00000000, change fileType */ + if ( fileType != (OSType)0x00000000 ) + { + pb.hFileInfo.ioFlFndrInfo.fdType = fileType; + } + + pb.hFileInfo.ioDirID = dirID; + error = PBSetCatInfoSync(&pb); /* now, save the new information + back to disk */ + + if ( (error == noErr) && (parID != fsRtParID) ) /* can't + bump fsRtParID */ + { + /* get the real vRefNum in case a full pathname was passed */ + error = DetermineVRefNum(name, vRefNum, &realVRefNum); + if ( error == noErr ) + { + error = BumpDate(realVRefNum, parID, NULL); + /* and bump the parent directory's mod date to wake + up the Finder */ + /* to the change we just made */ + } + } + } + else + { + /* it was a directory, not a file */ + error = notAFileErr; + } + } + + return ( error ); +} + +/*****************************************************************************/ + +pascal OSErr FSpChangeCreatorType(const FSSpec *spec, + OSType creator, + OSType fileType) +{ + return ( ChangeCreatorType(spec->vRefNum, spec->parID, spec->name, + creator, fileType) ); +} + +/*****************************************************************************/ + +pascal OSErr BumpDate(short vRefNum, + long dirID, + ConstStr255Param name) +/* Given a file or directory, change its modification date to the + current date/time. */ +{ + CInfoPBRec pb; + Str31 tempName; + OSErr error; + unsigned long secs; + + /* Protection against File Sharing problem */ + if ( (name == NULL) || (name[0] == 0) ) + { + tempName[0] = 0; + pb.hFileInfo.ioNamePtr = tempName; + pb.hFileInfo.ioFDirIndex = -1; /* use ioDirID */ + } + else + { + pb.hFileInfo.ioNamePtr = (StringPtr)name; + pb.hFileInfo.ioFDirIndex = 0; /* use ioNamePtr and ioDirID */ + } + pb.hFileInfo.ioVRefNum = vRefNum; + pb.hFileInfo.ioDirID = dirID; + error = PBGetCatInfoSync(&pb); + if ( error == noErr ) + { + GetDateTime(&secs); + /* set mod date to current date, or one second into the future + if mod date = current date */ + pb.hFileInfo.ioFlMdDat = + (secs == pb.hFileInfo.ioFlMdDat) ? (++secs) : (secs); + if ( pb.dirInfo.ioNamePtr == tempName ) + { + pb.hFileInfo.ioDirID = pb.hFileInfo.ioFlParID; + } + else + { + pb.hFileInfo.ioDirID = dirID; + } + error = PBSetCatInfoSync(&pb); + } + + return ( error ); +} + +/*****************************************************************************/ + +pascal OSErr FSpBumpDate(const FSSpec *spec) +{ + return ( BumpDate(spec->vRefNum, spec->parID, spec->name) ); +} + + +/*****************************************************************************/ + +pascal OSErr OnLine(FSSpecPtr volumes, + short reqVolCount, + short *actVolCount, + short *volIndex) +{ + HParamBlockRec pb; + OSErr error = noErr; + FSSpec *endVolArray; + + if ( *volIndex > 0 ) + { + *actVolCount = 0; + for ( endVolArray = volumes + reqVolCount; + (volumes < endVolArray) && (error == noErr); ++volumes ) + { + pb.volumeParam.ioNamePtr = (StringPtr) & volumes->name; + pb.volumeParam.ioVolIndex = *volIndex; + error = PBHGetVInfoSync(&pb); + if ( error == noErr ) + { + volumes->parID = fsRtParID; /* the root directory's + parent is 1 */ + volumes->vRefNum = pb.volumeParam.ioVRefNum; + ++*volIndex; + ++*actVolCount; + } + } + } + else + { + error = paramErr; + } + + return ( error ); +} + + +/*****************************************************************************/ + +pascal OSErr DTGetComment(short vRefNum, + long dirID, + ConstStr255Param name, + Str255 comment) +{ + DTPBRec pb; + OSErr error; + short dtRefNum; + Boolean newDTDatabase; + + if (comment != NULL) + { + comment[0] = 0; /* return nothing by default */ + + /* attempt to open the desktop database */ + error = DTOpen(name, vRefNum, &dtRefNum, &newDTDatabase); + if ( error == noErr ) + { + /* There was a desktop database and it's now open */ + + if ( !newDTDatabase ) + { + pb.ioDTRefNum = dtRefNum; + pb.ioNamePtr = (StringPtr)name; + pb.ioDirID = dirID; + pb.ioDTBuffer = (Ptr)&comment[1]; + /* + ** IMPORTANT NOTE #1: Inside Macintosh says that comments + ** are up to 200 characters. While that may be correct for + ** the HFS file system's Desktop Manager, other file + ** systems (such as Apple Photo Access) return up to + ** 255 characters. Make sure the comment buffer is a Str255 + ** or you'll regret it. + ** + ** IMPORTANT NOTE #2: Although Inside Macintosh doesn't + ** mention it, ioDTReqCount is a input field to + ** PBDTGetCommentSync. Some file systems (like HFS) ignore + ** ioDTReqCount and always return the full comment -- + ** others (like AppleShare) respect ioDTReqCount and only + ** return up to ioDTReqCount characters of the comment. + */ + pb.ioDTReqCount = sizeof(Str255) - 1; + error = PBDTGetCommentSync(&pb); + if (error == noErr) + { + comment[0] = (unsigned char)pb.ioDTActCount; + } + } + } + else + { + /* There is no desktop database - try the Desktop file */ + error = GetCommentFromDesktopFile(vRefNum, dirID, name, comment); + if ( error != noErr ) + { + error = afpItemNotFound; /* return an expected error */ + } + } + } + else + { + error = paramErr; + } + + return (error); +} + +/*****************************************************************************/ + +pascal OSErr FSpDTGetComment(const FSSpec *spec, + Str255 comment) +{ + return (DTGetComment(spec->vRefNum, spec->parID, spec->name, comment)); +} + + +/*****************************************************************************/ + +pascal OSErr DTSetComment(short vRefNum, + long dirID, + ConstStr255Param name, + ConstStr255Param comment) +{ + DTPBRec pb; + OSErr error; + short dtRefNum; + Boolean newDTDatabase; + + error = DTOpen(name, vRefNum, &dtRefNum, &newDTDatabase); + if ( error == noErr ) + { + pb.ioDTRefNum = dtRefNum; + pb.ioNamePtr = (StringPtr)name; + pb.ioDirID = dirID; + pb.ioDTBuffer = (Ptr)&comment[1]; + /* Truncate the comment to 200 characters just in case */ + /* some file system doesn't range check */ + if ( comment[0] <= 200 ) + { + pb.ioDTReqCount = comment[0]; + } + else + { + pb.ioDTReqCount = 200; + } + error = PBDTSetCommentSync(&pb); + } + return (error); +} + +/*****************************************************************************/ + +pascal OSErr FSpDTSetComment(const FSSpec *spec, + ConstStr255Param comment) +{ + return (DTSetComment(spec->vRefNum, spec->parID, spec->name, comment)); +} + + +/*****************************************************************************/ + +pascal OSErr DTOpen(ConstStr255Param volName, + short vRefNum, + short *dtRefNum, + Boolean *newDTDatabase) +{ + OSErr error; + GetVolParmsInfoBuffer volParmsInfo; + long infoSize; + DTPBRec pb; + + /* Check for volume Desktop Manager support before calling */ + infoSize = sizeof(GetVolParmsInfoBuffer); + error = HGetVolParms(volName, vRefNum, &volParmsInfo, &infoSize); + if ( error == noErr ) + { + if ( hasDesktopMgr(volParmsInfo) ) + { + pb.ioNamePtr = (StringPtr)volName; + pb.ioVRefNum = vRefNum; + error = PBDTOpenInform(&pb); + /* PBDTOpenInform informs us if the desktop was just created */ + /* by leaving the low bit of ioTagInfo clear (0) */ + *newDTDatabase = ((pb.ioTagInfo & 1L) == 0); + if ( error == paramErr ) + { + error = PBDTGetPath(&pb); + /* PBDTGetPath doesn't tell us if the database is new */ + /* so assume it is not new */ + *newDTDatabase = false; + } + *dtRefNum = pb.ioDTRefNum; + } + else + { + error = paramErr; + } + } + return ( error ); +} + +/*****************************************************************************/ + +/* +** GetCommentFromDesktopFile +** +** Get a file or directory's Finder comment field (if any) from the +** Desktop file's 'FCMT' resources. +*/ +static OSErr GetCommentFromDesktopFile(short vRefNum, + long dirID, + ConstStr255Param name, + Str255 comment) +{ + OSErr error; + short commentID; + short realVRefNum; + Str255 desktopName; + short savedResFile; + short dfRefNum; + StringHandle commentHandle; + + /* Get the comment ID number */ + error = GetCommentID(vRefNum, dirID, name, &commentID); + if ( error == noErr ) + { + if ( commentID != 0 ) /* commentID == 0 means there's no comment */ + { + error = DetermineVRefNum(name, vRefNum, &realVRefNum); + if ( error == noErr ) + { + error = GetDesktopFileName(realVRefNum, desktopName); + if ( error == noErr ) + { + savedResFile = CurResFile(); + /* + ** Open the 'Desktop' file in the root directory. (because + ** opening the resource file could preload unwanted resources, + ** bracket the call with SetResLoad(s)) + */ + SetResLoad(false); + dfRefNum = HOpenResFile(realVRefNum, fsRtDirID, desktopName, + fsRdPerm); + SetResLoad(true); + + if ( dfRefNum != -1) + { + /* Get the comment resource */ + commentHandle = (StringHandle)Get1Resource(kFCMTResType, + commentID); + if ( commentHandle != NULL ) + { + if ( InlineGetHandleSize((Handle)commentHandle) > 0 ) + { + BlockMoveData(*commentHandle, comment, + *commentHandle[0] + 1); + } + else + { /* no comment available */ + error = afpItemNotFound; + } + } + else + { /* no comment available */ + error = afpItemNotFound; + } + + /* restore the resource chain and close + the Desktop file */ + UseResFile(savedResFile); + CloseResFile(dfRefNum); + } + else + { + error = afpItemNotFound; + } + } + else + { + error = afpItemNotFound; + } + } + } + else + { + error = afpItemNotFound; /* no comment available */ + } + } + + return ( error ); +} + +/*****************************************************************************/ + +pascal OSErr HGetVolParms(ConstStr255Param volName, + short vRefNum, + GetVolParmsInfoBuffer *volParmsInfo, + long *infoSize) +{ + HParamBlockRec pb; + OSErr error; + + pb.ioParam.ioNamePtr = (StringPtr)volName; + pb.ioParam.ioVRefNum = vRefNum; + pb.ioParam.ioBuffer = (Ptr)volParmsInfo; + pb.ioParam.ioReqCount = *infoSize; + error = PBHGetVolParmsSync(&pb); + if ( error == noErr ) + { + *infoSize = pb.ioParam.ioActCount; + } + return ( error ); +} + +/*****************************************************************************/ +/* +** GetCommentID +** +** Get the comment ID number for the Desktop file's 'FCMT' resource ID from +** the file or folders fdComment (frComment) field. +*/ +static OSErr GetCommentID(short vRefNum, + long dirID, + ConstStr255Param name, + short *commentID) +{ + CInfoPBRec pb; + OSErr error; + + error = GetCatInfoNoName(vRefNum, dirID, name, &pb); + *commentID = pb.hFileInfo.ioFlXFndrInfo.fdComment; + return ( error ); +} + +/*****************************************************************************/ + +/* +** GetDesktopFileName +** +** Get the name of the Desktop file. +*/ +static OSErr GetDesktopFileName(short vRefNum, + Str255 desktopName) +{ + OSErr error; + HParamBlockRec pb; + short index; + Boolean found; + + pb.fileParam.ioNamePtr = desktopName; + pb.fileParam.ioVRefNum = vRefNum; + pb.fileParam.ioFVersNum = 0; + index = 1; + found = false; + do + { + pb.fileParam.ioDirID = fsRtDirID; + pb.fileParam.ioFDirIndex = index; + error = PBHGetFInfoSync(&pb); + if ( error == noErr ) + { + if ( (pb.fileParam.ioFlFndrInfo.fdType == 'FNDR') && + (pb.fileParam.ioFlFndrInfo.fdCreator == 'ERIK') ) + { + found = true; + } + } + ++index; + } while ( (error == noErr) && !found ); + + return ( error ); +} + + +/*****************************************************************************/ + +pascal OSErr XGetVInfo(short volReference, + StringPtr volName, + short *vRefNum, + UnsignedWide *freeBytes, + UnsignedWide *totalBytes) +{ + OSErr result; + long response; + XVolumeParam pb; + + /* See if large volume support is available */ + if ( ( Gestalt(gestaltFSAttr, &response) == noErr ) && ((response & (1L << gestaltFSSupports2TBVols)) != 0) ) + { + /* Large volume support is available */ + pb.ioVRefNum = volReference; + pb.ioNamePtr = volName; + pb.ioXVersion = 0; /* this XVolumeParam version (0) */ + pb.ioVolIndex = 0; /* use ioVRefNum only, return volume name */ + result = PBXGetVolInfoSync(&pb); + if ( result == noErr ) + { + /* The volume name was returned in volName (if not NULL) and */ + /* we have the volume's vRefNum and allocation block size */ + *vRefNum = pb.ioVRefNum; + + /* return the freeBytes and totalBytes */ + *totalBytes = pb.ioVTotalBytes; + *freeBytes = pb.ioVFreeBytes; + } + } + else + { + /* No large volume support */ + + /* Use HGetVInfo to get the results */ + result = HGetVInfo(volReference, volName, vRefNum, &freeBytes->lo, &totalBytes->lo); + if ( result == noErr ) + { + /* zero the high longs of totalBytes and freeBytes */ + totalBytes->hi = 0; + freeBytes->hi = 0; + } + } + return ( result ); +} + + + +/*****************************************************************************/ + +pascal OSErr HGetVInfo(short volReference, + StringPtr volName, + short *vRefNum, + unsigned long *freeBytes, + unsigned long *totalBytes) +{ + HParamBlockRec pb; + unsigned long allocationBlockSize; + unsigned short numAllocationBlocks; + unsigned short numFreeBlocks; + VCB *theVCB; + Boolean vcbFound; + OSErr result; + + /* Use the File Manager to get the real vRefNum */ + pb.volumeParam.ioVRefNum = volReference; + pb.volumeParam.ioNamePtr = volName; + pb.volumeParam.ioVolIndex = 0; /* use ioVRefNum only, return volume name */ + result = PBHGetVInfoSync(&pb); + + if ( result == noErr ) + { + /* The volume name was returned in volName (if not NULL) and */ + /* we have the volume's vRefNum and allocation block size */ + *vRefNum = pb.volumeParam.ioVRefNum; + allocationBlockSize = (unsigned long)pb.volumeParam.ioVAlBlkSiz; + + /* System 7.5 (and beyond) pins the number of allocation blocks and */ + /* the number of free allocation blocks returned by PBHGetVInfo to */ + /* a value so that when multiplied by the allocation block size, */ + /* the volume will look like it has $7fffffff bytes or less. This */ + /* was done so older applications that use signed math or that use */ + /* the GetVInfo function (which uses signed math) will continue to work. */ + /* However, the unpinned numbers (which we want) are always available */ + /* in the volume's VCB so we'll get those values from the VCB if possible. */ + + /* Find the volume's VCB */ + vcbFound = false; + theVCB = (VCB *)(GetVCBQHdr()->qHead); + while ( (theVCB != NULL) && !vcbFound ) + { + /* Check VCB signature before using VCB. Don't have to check for */ + /* MFS (0xd2d7) because they can't get big enough to be pinned */ + if ( theVCB->vcbSigWord == 0x4244 ) + { + if ( theVCB->vcbVRefNum == *vRefNum ) + { + vcbFound = true; + } + } + + if ( !vcbFound ) + { + theVCB = (VCB *)(theVCB->qLink); + } + } + + if ( theVCB != NULL ) + { + /* Found a VCB we can use. Get the un-pinned number of allocation blocks */ + /* and the number of free blocks from the VCB. */ + numAllocationBlocks = (unsigned short)theVCB->vcbNmAlBlks; + numFreeBlocks = (unsigned short)theVCB->vcbFreeBks; + } + else + { + /* Didn't find a VCB we can use. Return the number of allocation blocks */ + /* and the number of free blocks returned by PBHGetVInfoSync. */ + numAllocationBlocks = (unsigned short)pb.volumeParam.ioVNmAlBlks; + numFreeBlocks = (unsigned short)pb.volumeParam.ioVFrBlk; + } + + /* Now, calculate freeBytes and totalBytes using unsigned values */ + *freeBytes = numFreeBlocks * allocationBlockSize; + *totalBytes = numAllocationBlocks * allocationBlockSize; + } + + return ( result ); +} + + +/* +** PBXGetVolInfoSync is the glue code needed to make PBXGetVolInfoSync +** File Manager requests from CFM-based programs. At some point, Apple +** will get around to adding this to the standard libraries you link with +** and you'll get a duplicate symbol link error. At that time, just delete +** this code (or comment it out). +** +** Non-CFM 68K programs don't needs this glue (and won't get it) because +** they instead use the inline assembly glue found in the Files.h interface +** file. +*/ + +#if __WANTPASCALELIMINATION +#undef pascal +#endif + +#if GENERATINGCFM +pascal OSErr PBXGetVolInfoSync(XVolumeParamPtr paramBlock) +{ + enum + { + kXGetVolInfoSelector = 0x0012, /* Selector for XGetVolInfo */ + + uppFSDispatchProcInfo = kRegisterBased + | REGISTER_RESULT_LOCATION(kRegisterD0) + | RESULT_SIZE(SIZE_CODE(sizeof(OSErr))) + | REGISTER_ROUTINE_PARAMETER(1, kRegisterD1, SIZE_CODE(sizeof(long))) /* trap word */ + | REGISTER_ROUTINE_PARAMETER(2, kRegisterD0, SIZE_CODE(sizeof(long))) /* selector */ + | REGISTER_ROUTINE_PARAMETER(3, kRegisterA0, SIZE_CODE(sizeof(XVolumeParamPtr))) + }; + + return ( CallOSTrapUniversalProc(NGetTrapAddress(_FSDispatch, OSTrap), + uppFSDispatchProcInfo, + _FSDispatch, + kXGetVolInfoSelector, + paramBlock) ); +} +#endif + +#if __WANTPASCALELIMINATION +#define pascal +#endif + +/*****************************************************************************/ + +pascal OSErr GetDirName(short vRefNum, + long dirID, + Str31 name) +{ + CInfoPBRec pb; + OSErr error; + + if ( name != NULL ) + { + pb.dirInfo.ioNamePtr = name; + pb.dirInfo.ioVRefNum = vRefNum; + pb.dirInfo.ioDrDirID = dirID; + pb.dirInfo.ioFDirIndex = -1; /* get information about ioDirID */ + error = PBGetCatInfoSync(&pb); + } + else + { + error = paramErr; + } + + return ( error ); +} + + +/*****************************************************************************/ + +pascal OSErr GetVolFileSystemID(ConstStr255Param pathname, + short vRefNum, + short *fileSystemID) +{ + HParamBlockRec pb; + OSErr error; + + error = GetVolumeInfoNoName(pathname,vRefNum, &pb); + if ( error == noErr ) + { + *fileSystemID = pb.volumeParam.ioVFSID; + } + + return ( error ); +} + +/*****************************************************************************/ + +pascal OSErr GetDInfo(short vRefNum, + long dirID, + ConstStr255Param name, + DInfo *fndrInfo) +{ + CInfoPBRec pb; + OSErr error; + + error = GetCatInfoNoName(vRefNum, dirID, name, &pb); + if ( error == noErr ) + { + if ( (pb.dirInfo.ioFlAttrib & ioDirMask) != 0 ) + { + /* it's a directory, return the DInfo */ + *fndrInfo = pb.dirInfo.ioDrUsrWds; + } + else + { + /* oops, a file was passed */ + error = dirNFErr; + } + } + + return ( error ); +} + +/*****************************************************************************/ + +pascal OSErr FSpGetDInfo(const FSSpec *spec, + DInfo *fndrInfo) +{ + return ( GetDInfo(spec->vRefNum, spec->parID, spec->name, fndrInfo) ); +} + + diff --git a/macos/source/macstuff.h b/macos/source/macstuff.h new file mode 100644 index 0000000..9e92dce --- /dev/null +++ b/macos/source/macstuff.h @@ -0,0 +1,18 @@ +/* + Copyright (c) 1990-2001 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#ifndef _MACSTUFF_H +#define _MACSTUFF_H 1 + +#include "MoreFilesExtras.h" +#include "MoreDesktopMgr.h" +#include "MoreFiles.h" +#include "FSpCompat.h" +#include "FullPath.h" + +#endif /* _MACSTUFF_H */ diff --git a/macos/source/mactime.c b/macos/source/mactime.c new file mode 100644 index 0000000..af9ad5e --- /dev/null +++ b/macos/source/mactime.c @@ -0,0 +1,451 @@ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* ----------------------------------------------------------------------------- + +The original functions (Metrowerks Codewarrior pro 3.0) gmtime, localtime, +mktime and time do not work correctly. The supplied link library mactime.c +contains replacement functions for them. + + * Caveat: On a Mac, we only know the GMT and DST offsets for + * the current time, not for the time in question. + * Mac has no support for DST handling. + * DST changeover is all manually set by the user. + + +------------------------------------------------------------------------------*/ + +/*****************************************************************************/ +/* Includes */ +/*****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "mactime.h" + + +/* +The MacOS function GetDateTime returns the +number of seconds elapsed since midnight, January 1, 1904. +*/ +const unsigned long MacOS_2_Unix = 2082844800L; + + +/*****************************************************************************/ +/* Macros, typedefs */ +/*****************************************************************************/ + + +#ifndef TEST_TIME_LIB +#define my_gmtime gmtime +#define my_localtime localtime +#define my_mktime mktime +#define my_time time +#endif + + +/*****************************************************************************/ +/* Prototypes */ +/*****************************************************************************/ +/* internal prototypes */ +static void clear_tm(struct tm * tm); +static long GMTDelta(void); +static Boolean DaylightSaving(void); +static time_t GetTimeMac(void); +static time_t Mactime(time_t *timer); +static void normalize(int *i,int *j,int norm); +static struct tm *time2tm(const time_t *timer); +static time_t tm2time(struct tm *tp); + +/* Because serial port and SLIP conflict with ReadXPram calls, + we cache the call here so we don't hang on calling ReadLocation() */ +static void myReadLocation(MachineLocation * loc); + + +/* prototypes for STD lib replacement functions */ +struct tm *my_gmtime(const time_t *t); +struct tm *my_localtime(const time_t *t); +time_t my_mktime(struct tm *tp); +time_t my_time(time_t *t); + + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ + + /* + * Mac file times are based on 1904 Jan 1 00:00 local time, + * not 1970 Jan 1 00:00 UTC. + * So we have to convert the time stamps into UNIX UTC + * compatible values. + */ +time_t MacFtime2UnixFtime(unsigned long macftime) +{ + long UTCoffset; + + GetGMToffsetMac(macftime, &UTCoffset); + MACOS_TO_UNIX(macftime); + macftime -= UTCoffset; + + return macftime; +} + + + /* + * Mac file times are based on 1904 Jan 1 00:00 local time, + * not 1970 Jan 1 00:00 UTC. + * So we have to convert the time stamps into MacOS local + * compatible values. + */ +unsigned long UnixFtime2MacFtime(time_t unxftime) +{ + long UTCoffset; + unsigned long macftime = unxftime; + + UNIX_TO_MACOS(macftime); + GetGMToffsetMac(macftime, &UTCoffset); + macftime += UTCoffset; + + return macftime; +} + + + + + +/* +* This function convert a file-localtime to an another +* file-localtime. +*/ +time_t AdjustForTZmoveMac(unsigned long macloctim, long s_gmtoffs) +{ + time_t MacGMTTime; + long UTCoffset; + + /* convert macloctim into corresponding UTC value */ + MacGMTTime = macloctim - s_gmtoffs; + GetGMToffsetMac(macloctim, &UTCoffset); + + return (MacGMTTime + UTCoffset); +} /* AdjustForTZmove() */ + + + + +/* + * This function calculates the difference between the supplied Mac + * ftime value (local time) and the corresponding UTC time in seconds. + */ +Boolean GetGMToffsetMac(unsigned long mactime, long *UTCoffset) +{ + +mactime = mactime; +/* + * Caveat: On a Mac, we only know the GMT and DST offsets for + * the current time, not for the time in question. + * Mac has no support for DST handling. + * DST changeover is all manually set by the user. + + May be later I can include a support of GMT offset calculation for the + time in question here. +*/ + *UTCoffset = GMTDelta(); + + return true; +} + + + + + + + +/***************************************************************************** + * Standard Library Replacement Functions + * gmtime(), mktime(), localtime(), time() + * + * The unix epoch is used here. + * These functions gmtime(), mktime(), localtime() and time() + * expects and returns unix times. + * + * At midnight Jan. 1, 1970 GMT, the local time was + * midnight Jan. 1, 1970 + GMTDelta(). + * + * + *****************************************************************************/ + + +struct tm *my_gmtime(const time_t *timer) +{ + return time2tm(timer); +} + + + + +struct tm *my_localtime(const time_t *timer) +{ + time_t maclocal; + + maclocal = *timer; + maclocal += GMTDelta(); + + return time2tm(&maclocal); +} + + + + +time_t my_mktime(struct tm *tp) +{ + time_t maclocal; + + maclocal = tm2time(tp); + maclocal -= GMTDelta(); + + return maclocal; +} + + + + + + +time_t my_time(time_t *time) +{ +time_t tmp_time; + +GetDateTime(&tmp_time); + +MACOS_TO_UNIX(tmp_time); + +if (time) + { + *time = tmp_time; + } + +return tmp_time; +} + + + +/*****************************************************************************/ +/* static module level functions +/*****************************************************************************/ + + +/* + * The geographic location and time zone information of a Mac + * are stored in extended parameter RAM. The ReadLocation + * produdure uses the geographic location record, MachineLocation, + * to read the geographic location and time zone information in + * extended parameter RAM. + * + * Because serial port and SLIP conflict with ReadXPram calls, + * we cache the call here. + * + * Caveat: this caching will give the wrong result if a session + * extend across the DST changeover time, but + * this function resets itself every 2 hours. + */ +static void myReadLocation(MachineLocation * loc) +{ + static MachineLocation storedLoc; /* InsideMac, OSUtilities, page 4-20 */ + static time_t first_call = 0, last_call = 86400; + + if ((last_call - first_call) > 7200) + { + GetDateTime(&first_call); + ReadLocation(&storedLoc); + } + + GetDateTime(&last_call); + *loc = storedLoc; +} + + + + +static Boolean DaylightSaving(void) +{ + MachineLocation loc; + unsigned char dlsDelta; + + myReadLocation(&loc); + dlsDelta = loc.u.dlsDelta; + + return (dlsDelta != 0); +} + + + + +/* current local time = GMTDelta() + GMT + GMT = local time - GMTDelta() */ +static long GMTDelta(void) +{ + MachineLocation loc; + long gmtDelta; + + myReadLocation(&loc); + + /* + * On a Mac, the GMT value is in seconds east of GMT. For example, + * San Francisco is at -28,800 seconds (8 hours * 3600 seconds per hour) + * east of GMT. The gmtDelta field is a 3-byte value contained in a + * long word, so you must take care to get it properly. + */ + gmtDelta = loc.u.gmtDelta & 0x00FFFFFF; + if ((gmtDelta & 0x00800000) != 0) + { + gmtDelta |= 0xFF000000; + } + + return gmtDelta; +} + + + +/* This routine simulates stdclib time(), time in seconds since 1.1.1970 + The time is in GMT */ +static time_t GetTimeMac(void) +{ + unsigned long maclocal; + + + /* + * Get the current time expressed as the number of seconds + * elapsed since the Mac epoch, midnight, Jan. 1, 1904 (local time). + * On a Mac, current time accuracy is up to a second. + */ + + GetDateTime(&maclocal); /* Get Mac local time */ + maclocal -= GMTDelta(); /* Get Mac GMT */ + MACOS_TO_UNIX(maclocal); + + return maclocal; /* return unix GMT */ +} + + + + +/* + * clear_tm - sets a broken-down time to the equivalent of 1970/1/1 00:00:00 + */ + +static void clear_tm(struct tm * tm) +{ + tm->tm_sec = 0; + tm->tm_min = 0; + tm->tm_hour = 0; + tm->tm_mday = 1; + tm->tm_mon = 0; + tm->tm_year = 0; + tm->tm_wday = 1; + tm->tm_yday = 0; + tm->tm_isdst = -1; +} + + +static void normalize(int *i,int *j,int norm) +{ + while(*i < 0) + { + *i += norm; + (*j)--; + } + + while(*i >= norm) + { + *i -= norm; + (*j)++; + } +} + + + +/* Returns the GMT times */ +static time_t Mactime(time_t *timer) +{ + time_t t = GetTimeMac(); + + if (timer != NULL) + *timer = t; + + return t; +} + + + + +static struct tm *time2tm(const time_t *timer) +{ + DateTimeRec dtr; + MachineLocation loc; + time_t macLocal = *timer; + + static struct tm statictime; + static const short monthday[12] = + {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; + + UNIX_TO_MACOS(macLocal); + SecondsToDate(macLocal, &dtr); + + statictime.tm_sec = dtr.second; /* second, from 0 to 59 */ + statictime.tm_min = dtr.minute; /* minute, from 0 to 59 */ + statictime.tm_hour = dtr.hour; /* hour, from 0 to 23 */ + statictime.tm_mday = dtr.day; /* day of the month, from 1 to 31 */ + statictime.tm_mon = dtr.month - 1; /* month, 1= January and 12 = December */ + statictime.tm_year = dtr.year - 1900; /* year, ranging from 1904 to 2040 */ + statictime.tm_wday = dtr.dayOfWeek - 1; /* day of the week, 1 = Sun, 7 = Sat */ + + statictime.tm_yday = monthday[statictime.tm_mon] + + statictime.tm_mday - 1; + + if (2 < statictime.tm_mon && !(statictime.tm_year & 3)) + { + ++statictime.tm_yday; + } + + myReadLocation(&loc); + statictime.tm_isdst = DaylightSaving(); + + return(&statictime); +} + + + + + +static time_t tm2time(struct tm *tp) +{ +time_t intMacTime; +DateTimeRec dtr; + + normalize(&tp->tm_sec, &tp->tm_min, 60); + normalize(&tp->tm_min, &tp->tm_hour,60); + normalize(&tp->tm_hour,&tp->tm_mday,24); + normalize(&tp->tm_mon, &tp->tm_year,12); + + dtr.year = tp->tm_year + 1900; /* years since 1900 */ + dtr.month = tp->tm_mon + 1; /* month, 0 = January and 11 = December */ + dtr.day = tp->tm_mday; /* day of the month, from 1 to 31 */ + dtr.hour = tp->tm_hour; /* hour, from 0 to 23 */ + dtr.minute = tp->tm_min; /* minute, from 0 to 59 */ + dtr.second = tp->tm_sec; /* second, from 0 to 59 */ + + DateToSeconds(&dtr, &intMacTime); + + MACOS_TO_UNIX(intMacTime); + + return intMacTime; +} diff --git a/macos/source/mactime.h b/macos/source/mactime.h new file mode 100644 index 0000000..cb76aa4 --- /dev/null +++ b/macos/source/mactime.h @@ -0,0 +1,61 @@ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#ifndef _MACTIME_H_ +#define _MACTIME_H_ +/* ----------------------------------------------------------------------------- + +The original functions (Metrowerks Codewarrior pro 3.0) gmtime, localtime, +mktime and time do not work correctly. The supplied link library mactime.c +contains replacement functions for them. + + * Caveat: On a Mac, we only know the GMT and DST offsets for + * the current time, not for the time in question. + * Mac has no support for DST handling. + * DST changeover is all manually set by the user. + + +------------------------------------------------------------------------------*/ + +#include +#include + +/*****************************************************************************/ +/* Macros, typedefs */ +/*****************************************************************************/ + + + /* + * ARGH. Mac times are based on 1904 Jan 1 00:00, not 1970 Jan 1 00:00. + * So we have to diddle time_t's appropriately: add or subtract 66 years' + * worth of seconds == number of days times 86400 == (66*365 regular days + + * 17 leap days ) * 86400 == (24090 + 17) * 86400 == 2082844800L seconds. + * We hope time_t is an unsigned long (ulg) on the Macintosh... + */ +/* +This Offset is only used by MacFileDate_to_UTime() +*/ + +#define MACOS_TO_UNIX(x) (x) -= (unsigned long)MacOS_2_Unix +#define UNIX_TO_MACOS(x) (x) += (unsigned long)MacOS_2_Unix + +/* +The MacOS function GetDateTime returns the +number of seconds elapsed since midnight, January 1, 1904. +*/ +extern const unsigned long MacOS_2_Unix; + + +/* prototypes for public utility functions */ +time_t MacFtime2UnixFtime(unsigned long macftime); +unsigned long UnixFtime2MacFtime(time_t unxftime); +time_t AdjustForTZmoveMac(unsigned long macloctim, long s_gmtoffs); +Boolean GetGMToffsetMac(unsigned long macftime, long *UTCoffset); + + +#endif diff --git a/macos/source/pathname.c b/macos/source/pathname.c new file mode 100644 index 0000000..6bf1003 --- /dev/null +++ b/macos/source/pathname.c @@ -0,0 +1,726 @@ +/* + Copyright (c) 1990-2003 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/*--------------------------------------------------------------------------- + + pathname.c + + Function dealing with the pathname. Mostly C-string work. + + ---------------------------------------------------------------------------*/ + +/*****************************************************************************/ +/* Includes */ +/*****************************************************************************/ + +#include +#include +#include +#include + +#include "pathname.h" +#include "helpers.h" +#include "macstuff.h" + + +/*****************************************************************************/ +/* Global Vars */ +/*****************************************************************************/ + +const char ResourceMark[] = "XtraStuf.mac:"; /* see also macos.c */ + + +#include "zip.h" + + + + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ + + +/* + *---------------------------------------------------------------------- + * + * FSpFindFolder -- + * + * This function is a version of the FindFolder function that + * returns the result as a FSSpec rather than a vRefNum and dirID. + * + * Results: + * Results will be simaler to that of the FindFolder function. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +OSErr +FSpFindFolder( + short vRefNum, /* Volume reference number. */ + OSType folderType, /* Folder type taken by FindFolder. */ + Boolean createFolder, /* Should we create it if non-existant. */ + FSSpec *spec) /* Pointer to resulting directory. */ +{ + short foundVRefNum; + long foundDirID; + OSErr err; + + err = FindFolder(vRefNum, folderType, createFolder, + &foundVRefNum, &foundDirID); + if (err != noErr) { + return err; + } + + err = FSMakeFSSpecCompat(foundVRefNum, foundDirID, "\p", spec); + return err; +} + + +/* +** return volumename from pathname +** +*/ + +unsigned short GetVolumeFromPath(const char *FullPath, char *VolumeName) +{ +const char *VolEnd, *tmpPtr1; +char *tmpPtr2 = VolumeName; + +AssertStr(FullPath,"GetVolumeFromPath") + +for (VolEnd = FullPath; *VolEnd != '\0' && *VolEnd != ':'; VolEnd++) + ; +if (*VolEnd == '\0') return 0; + +for (tmpPtr1 = FullPath; tmpPtr1 != VolEnd;) + { + *tmpPtr2++ = *tmpPtr1++; + } + +*tmpPtr2 = '\0'; + +return (unsigned short) strlen(VolumeName); +} + + + +/***********************************/ +/* Function FindNewExtractFolder() */ +/***********************************/ + +char *FindNewExtractFolder(char *ExtractPath, Boolean uniqueFolder) +{ +char buffer[NAME_MAX], *tmpPtr, *namePtr; +char *last_dotpos = ExtractPath; +short count = 0, folderCount = 0; +OSErr err; +FSSpec Spec; +long theDirID; +Boolean isDirectory; +unsigned short namelen, pathlen = strlen(ExtractPath); +unsigned long ext_length = 0; +unsigned long num_to_cut = 0; +long firstpart_length = pathlen; + +AssertStr(ExtractPath,"FindNewExtractFolder ExtractPath == NULL") + +for (tmpPtr = ExtractPath; *tmpPtr; tmpPtr++) + if (*tmpPtr == ':') + { + folderCount++; + namePtr = tmpPtr; + } + +if (folderCount > 1) { + namelen = strlen(namePtr); +} else { + namelen = strlen(ExtractPath); +} + +if (uniqueFolder) { + for (count = 0; count < 99; count++) + { + memset(buffer,0,sizeof(buffer)); + + if (namelen >= 28) + ExtractPath[pathlen-2] = 0x0; + else + ExtractPath[pathlen-1] = 0x0; + + sprintf(buffer,"%s%d",ExtractPath,count); + GetCompletePath(ExtractPath, buffer, &Spec,&err); + err = FSpGetDirectoryID(&Spec, &theDirID, &isDirectory); + if (err == -43) break; + } +} else { + /* Look for the last extension pos */ + for (tmpPtr = ExtractPath; *tmpPtr; tmpPtr++) + if (*tmpPtr == '.') last_dotpos = tmpPtr; + + ext_length = strlen(last_dotpos); + + if (ext_length < 6) { /* up to 5 chars are treated as a */ + /* normal extension like ".html" or ".class" */ + int nameLength = last_dotpos - ExtractPath; + if (nameLength > 1) { + ExtractPath[nameLength] = 0x0; + } else { + ExtractPath[pathlen-1] = 0x0; + } + } else { + ExtractPath[pathlen-1] = 0x0; + } + + GetCompletePath(ExtractPath, ExtractPath, &Spec,&err); +} + +/* Foldernames must always end with a colon */ +sstrcat(ExtractPath,":"); +return ExtractPath; +} + + + +/* +** creates an archive file name +** +*/ + +void createArchiveName(char *thePath) +{ +char *tmpPtr, *namePtr; +short folderCount = 0; +unsigned short namelen, pathlen = strlen(thePath); + +if (thePath[pathlen-1] == ':') thePath[pathlen-1] = 0x0; + +for (tmpPtr = thePath; *tmpPtr; tmpPtr++) + if (*tmpPtr == ':') + { + folderCount++; + namePtr = tmpPtr; + } + +namelen = strlen(namePtr); + + /* we have to eliminate illegal chars: + * The name space for Mac filenames and Zip filenames (unix style names) + * do both include all printable extended-ASCII characters. The only + * difference we have to take care of is the single special character + * used as path delimiter: + * ':' on MacOS and '/' on Unix and '\\' on Dos. + * So, to convert between Mac filenames and Unix filenames without any + * loss of information, we simply interchange ':' and '/'. Additionally, + * we try to convert the coding of the extended-ASCII characters into + * InfoZip's standard ISO 8859-1 codepage table. + */ + MakeCompatibleString(namePtr, '/', '_', '.', '-', -1); + + /* Avoid filenames like: "Archive..zip" */ +if (thePath[pathlen-1] == '.') + { + thePath[pathlen-1] = 0; + } + +if (folderCount >= 1) + { /* path contains at least one folder */ + + if (namelen >= 28) + { + pathlen = pathlen-4; + } + + thePath[pathlen] = '.'; + thePath[pathlen+1] = 'z'; + thePath[pathlen+2] = 'i'; + thePath[pathlen+3] = 'p'; + thePath[pathlen+4] = 0x0; + return; + } +else + { /* path contains no folder */ + FindDesktopFolder(thePath); + createArchiveName(thePath); + } +} + + + +/* +** finds the desktop-folder on a volume with +** largest amount of free-space. +*/ + +void FindDesktopFolder(char *Path) +{ +char buffer[255]; +FSSpec volumes[50]; /* 50 Volumes should be enough */ +short actVolCount, volIndex = 1, VolCount = 0; +OSErr err; +short i, foundVRefNum; +FSSpec spec; +UInt64 freeBytes; +UInt64 totalBytes; +UInt64 MaxFreeBytes; + +err = OnLine(volumes, 50, &actVolCount, &volIndex); +printerr("OnLine:", (err != -35) && (err != 0), err, __LINE__, __FILE__, ""); + +MaxFreeBytes = 0; + +for (i=0; i < actVolCount; i++) + { + XGetVInfo(volumes[i].vRefNum, + volumes[i].name, + &volumes[i].vRefNum, + &freeBytes, + &totalBytes); + + if (MaxFreeBytes < freeBytes) { + MaxFreeBytes = freeBytes; + foundVRefNum = volumes[i].vRefNum; + } + + if ((freeBytes == 0) && (MaxFreeBytes < freeBytes)) { + MaxFreeBytes = freeBytes; + foundVRefNum = volumes[i].vRefNum; + } + +} + + FSpFindFolder(foundVRefNum, kDesktopFolderType, + kDontCreateFolder,&spec); + + GetFullPathFromSpec(buffer, &spec , &err); + sstrcat(buffer,Path); + sstrcpy(Path,buffer); +} + + +/* +** return the path without the filename +** +*/ + +char *TruncFilename(char *DirPath, const char *FilePath) +{ +char *tmpPtr; +char *dirPtr = NULL; + +AssertStr(DirPath,"TruncFilename") +Assert_it(Spec,"TruncFilename","") + +sstrcpy(DirPath, FilePath); + +for (tmpPtr = DirPath; *tmpPtr; tmpPtr++) + if (*tmpPtr == ':') + dirPtr = tmpPtr; + +if (dirPtr) + *++dirPtr = '\0'; +else + printerr("TruncFilename: FilePath has no Folders", -1, + -1, __LINE__, __FILE__, FilePath); + +return DirPath; +} + + + +/* +** return only filename +** +*/ + +char *GetFilename(char *FileName, const char *FilePath) +{ +const char *tmpPtr; +const char *dirPtr = NULL; + +Assert_it(FileName,"GetFilename","") +Assert_it(FilePath,"GetFilename","") + +for (tmpPtr = FilePath; *tmpPtr; tmpPtr++) + { + if (*tmpPtr == ':') + { + dirPtr = tmpPtr; + } + } + +if (dirPtr) + { + ++dirPtr; /* jump over the ':' */ + } +else + { + return strcpy(FileName, FilePath); /* FilePath has no Folders */ + } + +return strcpy(FileName, dirPtr); +} + + + +/* +** return fullpathname from folder/dir-id +** +*/ + +char *GetFullPathFromID(char *CompletePath, short vRefNum, long dirID, + ConstStr255Param name, OSErr *err) +{ +FSSpec spec; + + *err = FSMakeFSSpecCompat(vRefNum, dirID, name, &spec); + printerr("FSMakeFSSpecCompat:", (*err != -43) && (*err != 0), *err, + __LINE__, __FILE__, ""); + if ( (*err == noErr) || (*err == fnfErr) ) + { + return GetFullPathFromSpec(CompletePath, &spec, err); + } + +return NULL; +} + + + +/* +** convert real-filename to archive-filename +** +*/ + +char *Real2RfDfFilen(char *RfDfFilen, const char *RealPath, + short CurrentFork, short MacZipMode, Boolean DataForkOnly) +{ + +AssertStr(RealPath,"Real2RfDfFilen") +AssertStr(RfDfFilen,"Real2RfDfFilen") + +if (DataForkOnly) /* make no changes */ + { + return sstrcpy(RfDfFilen, RealPath); + } + +switch (MacZipMode) + { + case JohnnyLee_EF: + { + sstrcpy(RfDfFilen, RealPath); + if (CurrentFork == DataFork) /* data-fork */ + return sstrcat(RfDfFilen, "d"); + if (CurrentFork == ResourceFork) /* resource-fork */ + return sstrcat(RfDfFilen, "r"); + break; + } + + case NewZipMode_EF: + { + switch (CurrentFork) + { + case DataFork: + { + sstrcpy(RfDfFilen, RealPath); + return RfDfFilen; /* data-fork */ + break; + } + case ResourceFork: + { + sstrcpy(RfDfFilen, ResourceMark); + sstrcat(RfDfFilen, RealPath); /* resource-fork */ + return RfDfFilen; + break; + } + default: + { + printerr("Real2RfDfFilen:", -1, -1, + __LINE__, __FILE__, RealPath); + return NULL; /* function should never reach this point */ + } + } + break; + } + default: + { + printerr("Real2RfDfFilen:", -1, -1, __LINE__, __FILE__, RealPath); + return NULL; /* function should never reach this point */ + } + } + +printerr("Real2RfDfFilen:", -1, -1, __LINE__, __FILE__, RealPath); +return NULL; /* function should never come reach this point */ +} + + + +/* +** convert archive-filename into a real filename +** +*/ + +char *RfDfFilen2Real(char *RealFn, const char *RfDfFilen, short MacZipMode, + Boolean DataForkOnly, short *CurrentFork) +{ +short length; +int result; + +AssertStr(RfDfFilen,"RfDfFilen2Real") + +if (DataForkOnly || + (MacZipMode == UnKnown_EF) || + (MacZipMode < JohnnyLee_EF)) + { + *CurrentFork = DataFork; + return sstrcpy(RealFn,RfDfFilen); + } + +result = strncmp(RfDfFilen, ResourceMark, sizeof(ResourceMark)-2); +if (result == 0) + { + MacZipMode = NewZipMode_EF; + } + +switch (MacZipMode) + { + case JohnnyLee_EF: + { + sstrcpy(RealFn, RfDfFilen); + length = strlen(RealFn); /* determine Fork type */ + if (RealFn[length-1] == 'd') *CurrentFork = DataFork; + else *CurrentFork = ResourceFork; + RealFn[length-1] = '\0'; /* simply cut one char */ + return RealFn; + break; + } + + case NewZipMode_EF: + { /* determine Fork type */ + result = strncmp(RfDfFilen, ResourceMark, sizeof(ResourceMark)-2); + if (result != 0) + { + *CurrentFork = DataFork; + sstrcpy(RealFn, RfDfFilen); + return RealFn; /* data-fork */ + } + else + { + *CurrentFork = ResourceFork; + if (strlen(RfDfFilen) > (sizeof(ResourceMark) - 1)) + { + sstrcpy(RealFn, &RfDfFilen[sizeof(ResourceMark)-1]); + } + else RealFn[0] = '\0'; + return RealFn; /* resource-fork */ + } + break; + } + default: + { + *CurrentFork = NoFork; + printerr("RfDfFilen2Real():", -1, MacZipMode, + __LINE__, __FILE__, RfDfFilen); + return NULL; /* function should never reach this point */ + } + } + +printerr("RfDfFilen2Real():", -1, MacZipMode, __LINE__, __FILE__, RfDfFilen); +return NULL; /* function should never reach this point */ +} + + + +/* +** return the applications name (argv[0]) +** +*/ + +char *GetAppName(void) +{ +ProcessSerialNumber psn; +static Str255 AppName; +ProcessInfoRec pinfo; +OSErr err; + +GetCurrentProcess(&psn); +pinfo.processName = AppName; +pinfo.processInfoLength = sizeof(pinfo); +pinfo.processAppSpec = NULL; + +err = GetProcessInformation(&psn,&pinfo); +AppName[AppName[0]+1] = 0x00; + +return (char *)&AppName[1]; +} + + + +/* +** return fullpathname from FSSpec +** +*/ + +char *GetFullPathFromSpec(char *FullPath, FSSpec *Spec, OSErr *err) +{ +Handle hFullPath; +short len; + +Assert_it(Spec,"GetFullPathFromSpec","") + +*err = FSpGetFullPath(Spec, &len, &hFullPath); +printerr("FSpGetFullPath:", (*err != -43) && (*err != 0), *err, + __LINE__, __FILE__, ""); + +memmove(FullPath, (Handle) *hFullPath, len); +FullPath[len] = '\0'; /* make c-string */ + +DisposeHandle((Handle)hFullPath); /* we don't need it any more */ + +printerr("Warning path length exceeds limit: ", len >= NAME_MAX, len, + __LINE__, __FILE__, " chars "); + +return FullPath; +} + + + + +/* +* This function expands a given partial path to a complete path. +* Path expansions are relative to the running app. +* This function follows the notation: +* 1. relative path: +* a: ":subfolder:filename" -> ":current folder:subfolder:filename" +* b: "::folder2:filename" -> folder2 is beside the current +* folder on the same level +* c: "filename" -> in current folder +* +* An absolute path will be returned. + +The following characteristics of Macintosh pathnames should be noted: + + A full pathname never begins with a colon, but must contain at + least one colon. + A partial pathname always begins with a colon separator except in + the case where the file partial pathname is a simple file or + directory name. + Single trailing separator colons in full or partial pathnames are + ignored except in the case of full pathnames to volumes. + In full pathnames to volumes, the trailing separator colon is required. + Consecutive separator colons can be used to ascend a level from a + directory to its parent directory. Two consecutive separator colons + will ascend one level, three consecutive separator colons will ascend + two levels, and so on. Ascending can only occur from a directory; + not a file. +*/ + +char *GetCompletePath(char *CompletePath, const char *name, FSSpec *Spec, + OSErr *err) +{ +Boolean hasDirName = false; +char currentdir[NAME_MAX]; +char *tmpPtr; +unsigned short pathlen; + +AssertStr(name,"GetCompletePath") +Assert_it(Spec,"GetCompletePath","") +Assert_it((CompletePath != name),"GetCompletePath","") + +for (tmpPtr = name; *tmpPtr; tmpPtr++) + if (*tmpPtr == ':') hasDirName = true; + +if (name[0] != ':') /* case c: path including volume name or only filename */ + { + if (hasDirName) + { /* okey, starts with volume name, so it must be a complete path */ + sstrcpy(CompletePath, name); + } + else + { /* only filename: add cwd and return */ + getcwd(currentdir, NAME_MAX); + sstrcat(currentdir, name); + sstrcpy(CompletePath, currentdir); + } + } +else if (name[1] == ':') /* it's case b: "::folder2:filename" */ + { + printerr("GetCompletePath ", -1, *err, __LINE__, __FILE__, "not implemented"); + /* it's not yet implemented; do we really need this case ?*/ + return NULL; + } +else /* it's case a: ":subfolder:filename" */ + { + getcwd(CompletePath, NAME_MAX); /* we don't need a second colon */ + CompletePath[strlen(CompletePath)-1] = '\0'; + sstrcat(CompletePath, name); + } + +pathlen = strlen(CompletePath); +*err = FSpLocationFromFullPath(pathlen, CompletePath, Spec); + +return CompletePath; +} + + + +char *MakeFilenameShorter(const char *LongFilename) +{ +static char filename[35]; /* contents should be never longer than 32 chars */ +static unsigned char Num = 0; /* change the number for every call */ + /* this var will rollover without a problem */ +char tempLongFilename[1024], charnum[5]; +char *last_dotpos = tempLongFilename; +unsigned long full_length = strlen(LongFilename); +unsigned long ext_length = 0; +unsigned long num_to_cut = 0; +long firstpart_length; +char *tmpPtr; +short MaxLength = 31; + +if (full_length <= MaxLength) /* filename is not long */ + { + return strcpy(filename,LongFilename); + } + +Num++; +strcpy(tempLongFilename,LongFilename); + +/* Look for the last extension pos */ +for (tmpPtr = tempLongFilename; *tmpPtr; tmpPtr++) + if (*tmpPtr == '.') last_dotpos = tmpPtr; + +ext_length = strlen(last_dotpos); +firstpart_length = last_dotpos - tempLongFilename; + +if (ext_length > 6) /* up to 5 chars are treated as a */ + { /* normal extension like ".html" or ".class" */ + firstpart_length = 0; + } + +num_to_cut = full_length - MaxLength; + +/* number the files to make the names unique */ +sprintf(charnum,"~%x", Num); +num_to_cut += strlen(charnum); + +if (firstpart_length == 0) + { + firstpart_length = full_length; + tempLongFilename[firstpart_length - num_to_cut] = 0; + sprintf(filename,"%s%s", tempLongFilename, charnum); + } +else + { + tempLongFilename[firstpart_length - num_to_cut] = 0; + sprintf(filename,"%s%s%s", tempLongFilename, charnum, last_dotpos); + } + +return filename; +} diff --git a/macos/source/pathname.h b/macos/source/pathname.h new file mode 100644 index 0000000..1a39ed3 --- /dev/null +++ b/macos/source/pathname.h @@ -0,0 +1,64 @@ +/* + Copyright (c) 1990-2001 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#ifndef PATHNAME_H +#define PATHNAME_H 1 + + +char *StripPartialDir(char *CompletePath, + const char *PartialPath, const char *FullPath); + +char *Real2RfDfFilen(char *RfDfFilen, const char *RealPath, short CurrentFork, + short MacZipMode, Boolean DataForkOnly); +char *RfDfFilen2Real(char *RealFn, const char *RfDfFilen, short MacZipMode, + Boolean DataForkOnly, short *CurrentFork); + +unsigned short GetVolumeFromPath(const char *FullPath, char *VolumeName); +char *GetCompletePath(char *CompletePath, const char *name, FSSpec *Spec, + OSErr *err); +char *TruncFilename(char *DirPath, const char *FilePath); +char *GetFilename(char *CompletePath, const char *name); +char *GetFullPathFromSpec(char *CompletePath, FSSpec *Spec, OSErr *err); +char *GetFullPathFromID(char *CompletePath, short vRefNum, long dirID, + ConstStr255Param name, OSErr *err); + +char *GetAppName(void); +void createArchiveName(char *Path); +void FindDesktopFolder(char *Path); +char *FindNewExtractFolder(char *ExtractPath, Boolean uniqueFolder); +OSErr FSpFindFolder( + short vRefNum, /* Volume reference number. */ + OSType folderType, /* Folder type taken by FindFolder. */ + Boolean createFolder, /* Should we create it if non-existant. */ + FSSpec *spec); /* Pointer to resulting directory. */ + +char *MakeFilenameShorter(const char *LongFilename); + +/* +Rule: UnKnown_EF should always be zero. + JohnnyLee_EF, NewZipMode_EF should always greater than all + other definitions +*/ +#define UnKnown_EF 0 +#define TomBrownZipIt1_EF 10 +#define TomBrownZipIt2_EF 20 +#define JohnnyLee_EF 30 +#define NewZipMode_EF 40 + + + +#define ResourceFork -1 +#define DataFork 1 +#define NoFork 0 + + +#ifndef NAME_MAX +#define NAME_MAX 1024 +#endif + +#endif /* PATHNAME_H */ diff --git a/macos/source/recurse.c b/macos/source/recurse.c new file mode 100644 index 0000000..e87db3c --- /dev/null +++ b/macos/source/recurse.c @@ -0,0 +1,442 @@ +/* +These functions are based on Jim Luther's IterateDirectory() found in MoreFiles +However, it's heavily modified by Dirk Haase +*/ + +/* +** IterateDirectory: File Manager directory iterator routines. +** +** by Jim Luther +** +** File: IterateDirectory.c +** +** Copyright (c) 1995-1998 Jim Luther and Apple Computer, Inc. +** All rights reserved. +** +** You may incorporate this sample code into your applications without +** restriction, though the sample code has been provided "AS IS" and the +** responsibility for its operation is 100% yours. +** +** IterateDirectory is designed to drop into the MoreFiles sample code +** library I wrote while in Apple Developer Technical Support +*/ + +/*****************************************************************************/ +/* Includes */ +/*****************************************************************************/ + +#include +#include +#include +#include +#include + + +#include "zip.h" +#include "macstuff.h" +#include "helpers.h" +#include "recurse.h" +#include "macglob.h" +#include "pathname.h" + + + + +/*****************************************************************************/ +/* Macros, typedefs */ +/*****************************************************************************/ + +/* The RecurseGlobals structure is used to minimize the amount of +** stack space used when recursively calling RecurseDirectoryLevel +** and to hold global information that might be needed at any time. +*/ +struct RecurseGlobals +{ + short vRefNum; + CInfoPBRec cPB; /* the parameter block used for + PBGetCatInfo calls */ + unsigned char *itemName; /* the name of the current item */ + char *FullPath; + short FullPathLen; + OSErr result; /* temporary holder of results - + saves 2 bytes of stack each level */ + Boolean quitFlag; /* set to true if filter wants to + kill interation */ + unsigned short maxLevels; /* Maximum levels to + iterate through */ + unsigned short currentLevel; /* The current level + IterateLevel is on */ +}; + +typedef struct RecurseGlobals RecurseGlobals; +typedef RecurseGlobals *RecurseGlobalsPtr; + + +/*****************************************************************************/ +/* Global Vars */ +/*****************************************************************************/ + +extern MacZipGlobals MacZip; +extern const char ResourceMark[13]; /* "XtraStuf.mac:" var is initialized in file pathname.c */ +extern int extra_fields; /* do not create extra fields if false */ + +static RecurseGlobals theGlobals; + +static unsigned long DirLevels = 0; +static char *buffer; +extern int verbose; /* 1=report oddities in zip file structure */ + +/*****************************************************************************/ +/* Prototypes */ +/*****************************************************************************/ + +int procname(char *filename, int caseflag); +int MatchWild( char *pPat, char *pStr, int case_sens); +Boolean IsZipFile(char *name); + +static void RecurseDirectoryLevel(long DirID, RecurseGlobals *Globals); +static Boolean isRegularItem( RecurseGlobals *Globals); +static void ProcessFiles(RecurseGlobals *Globals, + Boolean hasDataFork, Boolean hasResourceFork); +static void ProcessDirectory(RecurseGlobals *Globals, + Boolean IncludeItem, long DirID); +static void ProcessItem(RecurseGlobals *Globals, long DirID); + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ + +static void RecurseDirectoryLevel(long DirID, RecurseGlobals *Globals) +{ +char buffer2[23]; + + /* if maxLevels is zero, we aren't checking levels */ + if ( (Globals->maxLevels == 0) || + /* if currentLevel < maxLevels, look at this level */ + (Globals->currentLevel < Globals->maxLevels) ) + { + short index = 1; + + ++Globals->currentLevel; /* go to next level */ + if (DirLevels < Globals->currentLevel) DirLevels = Globals->currentLevel; + sprintf(buffer2,"Globals->currentLevel: %d",Globals->currentLevel); + + do + { /* Isn't C great... What I'd give for a "WITH + theGlobals DO" about now... */ + + /* Get next source item at the current directory level */ + Globals->cPB.dirInfo.ioFDirIndex = index; + Globals->cPB.dirInfo.ioDrDirID = DirID; + Globals->result = PBGetCatInfoSync((CInfoPBPtr)&Globals->cPB); + + ShowCounter(false); + + if ( Globals->result == noErr ) + { + ProcessItem(Globals, DirID); + } /* if ( Globals->result == noErr ) */ + + ++index; /* prepare to get next item */ + /* time to fall back a level? */ + } while ( (Globals->result == noErr) && (!Globals->quitFlag) ); + + if ( (Globals->result == fnfErr) || /* fnfErr is OK - + it only means we hit + the end of this level */ + (Globals->result == afpAccessDenied) ) /* afpAccessDenied is OK, + too - it only means we cannot see inside a directory */ + { + Globals->result = noErr; + } + + --Globals->currentLevel; /* return to previous level as we leave */ + } +} + + + +/*****************************************************************************/ + +pascal OSErr RecurseDirectory(short vRefNum, + long thedirID, + ConstStr255Param name, + unsigned short maxLevels) +{ + OSErr result; + short theVRefNum; + Boolean isDirectory; + long DirID; + + /* Get the real directory ID and make sure it is a directory */ + result = GetDirectoryID(vRefNum, thedirID, name, &DirID, &isDirectory); + if ( result == noErr ) + { + if ( isDirectory == true ) + { + /* Get the real vRefNum */ + result = DetermineVRefNum(name, vRefNum, &theVRefNum); + if ( result == noErr ) + { + /* Set up the globals we need to access from + the recursive routine. */ + theGlobals.cPB.hFileInfo.ioNamePtr = theGlobals.itemName; + theGlobals.cPB.hFileInfo.ioVRefNum = theVRefNum; + theGlobals.itemName[0] = 0; + theGlobals.result = noErr; + theGlobals.quitFlag = false; + theGlobals.maxLevels = maxLevels; + theGlobals.currentLevel = 0; /* start at level 0 */ + + /* Here we go into recursion land... */ + RecurseDirectoryLevel(DirID, &theGlobals); + + result = theGlobals.result; /* set the result */ + } + } + else + { + result = dirNFErr; /* a file was passed instead + of a directory */ + } + } + + return ( result ); +} + + + +/*****************************************************************************/ + +pascal OSErr FSpRecurseDirectory(const FSSpec *spec, + unsigned short maxLevels) +{ + OSErr rc; + + theGlobals.vRefNum = spec->vRefNum; + + /* make room for pathnames */ + theGlobals.itemName = (unsigned char *) StrCalloc(NAME_MAX); + theGlobals.FullPath = StrCalloc(NAME_MAX); + buffer = StrCalloc(NAME_MAX); + + + if ((noisy) && (MacZip.DataForkOnly)) + printf("\n Warning: Datafork only \n"); + + /* reset the count to zero */ + ShowCounter(true); + + if (noisy) leftStatusString("Build File List; Items done:"); + if (noisy) printf("\n Collecting Filenames ..."); + rc = RecurseDirectory(spec->vRefNum, spec->parID, spec->name,maxLevels); + printerr("RecurseDirectory:",rc,rc,__LINE__,__FILE__,""); + + if (noisy) printf("\n... done \n\n %6d matched files found \n", + MacZip.FoundFiles); + if (noisy) printf(" %6d folders found in %d Levels \n", + MacZip.FoundDirectories,DirLevels); + + if (MacZip.BytesOfData > (1024*1024)) + if (noisy) printf(" %4.3f MBytes unzipped size\n\n", + (float) MacZip.BytesOfData/(1024*1024)); + else + if (noisy) printf(" %4.3f KBytes unzipped size\n\n", + (float) MacZip.BytesOfData/1024); + + /* free all memory of pathnames */ + theGlobals.itemName = (unsigned char *) StrFree((char *)theGlobals.itemName); + theGlobals.FullPath = StrFree(theGlobals.FullPath); + buffer = StrFree(buffer); + + return rc; +} + + + + +/* +* Return true if filename == zipfile +* After the first match no further check will be done ! +* +*/ +Boolean IsZipFile(char *filen) +{ +static firstMatch = false; + +if (filen == NULL) + firstMatch = false; + +if (!firstMatch) + { + if (stricmp(filen, MacZip.ZipFullPath) == 0) + { + firstMatch = true; + return true; + } + } + +return false; +} + + + +static Boolean isRegularItem( RecurseGlobals *Globals) +{ +Boolean isInvisible = false, + isAlias = false, + isSystem = false; + +isSystem = !((Globals->cPB.hFileInfo.ioFlFndrInfo.fdFlags & + (1 << 12)) == 0 ); +isInvisible = !((Globals->cPB.hFileInfo.ioFlFndrInfo.fdFlags & + (1 << 14)) == 0 ); +isAlias = !((Globals->cPB.hFileInfo.ioFlFndrInfo.fdFlags & + (1 << 15)) == 0); + +if (isAlias == true) + { + return false; + } + +if (MacZip.IncludeInvisible == true) + { + return true; + } + +if ((isSystem == true) || + (isInvisible == true)) + { + return false; + } + +return true; +} + + + + +static void ProcessFiles(RecurseGlobals *Globals, + Boolean hasDataFork, Boolean hasResourceFork) +{ + /* some file statistics */ +MacZip.FoundFiles++; + +if (hasDataFork == true) + { + MacZip.BytesOfData = + Globals->cPB.hFileInfo.ioFlLgLen + + MacZip.BytesOfData; + MacZip.CurrentFork = DataFork; + MacZip.RawCountOfItems++; + + if (MacZip.DataForkOnly == true) + { + procname(Globals->FullPath, false); + hasResourceFork = false; + } + else + { + procname(Real2RfDfFilen(buffer,Globals->FullPath, + DataFork, MacZip.MacZipMode, + MacZip.DataForkOnly), false); + } + } + +if (hasResourceFork == true) + { + MacZip.BytesOfData = + Globals->cPB.hFileInfo.ioFlRLgLen + + MacZip.BytesOfData; + MacZip.CurrentFork = ResourceFork; + MacZip.RawCountOfItems++; + + procname(Real2RfDfFilen(buffer, Globals->FullPath, + ResourceFork, MacZip.MacZipMode, + MacZip.DataForkOnly), false); + } +} + + + + +static void ProcessDirectory(RecurseGlobals *Globals, + Boolean IncludeItem, long DirID) +{ +OSErr rc; + +MacZip.isDirectory = true; + +GetFullPathFromID(Globals->FullPath,Globals->vRefNum, DirID, + Globals->itemName, &rc); + +MacZip.RawCountOfItems++; +MacZip.FoundDirectories++; + +if (MacZip.StoreFoldersAlso) + { + procname(Globals->FullPath, false); + } + + /* We have a directory */ + if ( !Globals->quitFlag && IncludeItem) + { + /* Dive again if the IterateFilterProc didn't say "quit" and dir is + not an alias */ + RecurseDirectoryLevel(Globals->cPB.dirInfo.ioDrDirID, + Globals); + } +} + + + +static void ProcessItem(RecurseGlobals *Globals, long DirID) +{ +OSErr rc; +Boolean IncludeItem = false, hasDataFork = false; +Boolean hasResourceFork = false; + +IncludeItem = isRegularItem(Globals); + +/* Is it a File? */ +if ( (Globals->cPB.hFileInfo.ioFlAttrib & ioDirMask) == 0 ) + { + PToCCpy(Globals->itemName,MacZip.FileName); + MacZip.isDirectory = false; + + hasDataFork = (Globals->cPB.hFileInfo.ioFlLgLen != 0); + hasResourceFork = (Globals->cPB.hFileInfo.ioFlRLgLen != 0); + + /* include also files with zero recource- and data-fork */ + if ((hasDataFork == 0) && (hasResourceFork == 0)) + hasDataFork = true; + + if ((hasDataFork == 0) && + (hasResourceFork != 0) && + (extra_fields == false)) + { + IncludeItem = false; + } + + GetFullPathFromID(Globals->FullPath,Globals->vRefNum, + DirID, Globals->itemName, &rc); + printerr("GetFullPathFromID:",rc,rc,__LINE__, + __FILE__,MacZip.FileName); + + if (IncludeItem && /* don't include the zipfile itself */ + (!IsZipFile(Globals->FullPath)) ) + { + if (MATCH(MacZip.Pattern, MacZip.FileName, false) == true) + { + ProcessFiles(Globals, hasDataFork, hasResourceFork); + } /* if (MatchWild( MacZip.FileName,MacZip.Pattern ) == + true) */ + } /* if (!IsZipFile(Globals->FullPath)) */ + } /* Is it a File? */ + +/* Is it a directory? */ +if ( (Globals->cPB.hFileInfo.ioFlAttrib & ioDirMask) != 0 ) + { + ProcessDirectory(Globals,IncludeItem, DirID); + } /* Is it a directory? */ +} diff --git a/macos/source/recurse.h b/macos/source/recurse.h new file mode 100644 index 0000000..cfbc4b0 --- /dev/null +++ b/macos/source/recurse.h @@ -0,0 +1,129 @@ +/* +** IterateDirectory: File Manager directory iterator routines. +** +** by Jim Luther +** +** File: IterateDirectory.h +** +** Copyright (c) 1995-1998 Jim Luther and Apple Computer, Inc. +** All rights reserved. +** +** You may incorporate this sample code into your applications without +** restriction, though the sample code has been provided "AS IS" and the +** responsibility for its operation is 100% yours. +** +** IterateDirectory is designed to drop into the MoreFiles sample code +** library I wrote while in Apple Developer Technical Support +*/ + +#ifndef __RECURSEDIRECTORY__ +#define __RECURSEDIRECTORY__ + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*****************************************************************************/ + +pascal OSErr RecurseDirectory(short vRefNum, + long dirID, + ConstStr255Param name, + unsigned short maxLevels ); +/* Iterate (scan) through a directory's content. + The IterateDirectory function performs a recursive iteration (scan) of + the specified directory and calls your IterateFilterProc function once + for each file and directory found. + + The maxLevels parameter lets you control how deep the recursion goes. + If maxLevels is 1, IterateDirectory only scans the specified directory; + if maxLevels is 2, IterateDirectory scans the specified directory and + one subdirectory below the specified directory; etc. Set maxLevels to + zero to scan all levels. + + The yourDataPtr parameter can point to whatever data structure you might + want to access from within the IterateFilterProc. + + vRefNum input: Volume specification. + dirID input: Directory ID. + name input: Pointer to object name, or nil when dirID + specifies a directory that's the object. + maxLevels input: Maximum number of directory levels to scan or + zero to scan all directory levels. + iterateFilter input: A pointer to the routine you want called once + for each file and directory found by + IterateDirectory. + yourDataPtr input: A pointer to whatever data structure you might + want to access from within the IterateFilterProc. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + paramErr -50 No default volume or iterateFilter was NULL + dirNFErr -120 Directory not found or incomplete pathname + or a file was passed instead of a directory + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: RecurseFilterProcPtr, FSpRecurseDirectory +*/ + +/*****************************************************************************/ + +pascal OSErr FSpRecurseDirectory(const FSSpec *spec, + unsigned short maxLevels); +/* Iterate (scan) through a directory's content. + The FSpIterateDirectory function performs a recursive iteration (scan) + of the specified directory and calls your IterateFilterProc function once + for each file and directory found. + + The maxLevels parameter lets you control how deep the recursion goes. + If maxLevels is 1, FSpIterateDirectory only scans the specified directory; + if maxLevels is 2, FSpIterateDirectory scans the specified directory and + one subdirectory below the specified directory; etc. Set maxLevels to + zero to scan all levels. + + The yourDataPtr parameter can point to whatever data structure you might + want to access from within the IterateFilterProc. + + spec input: An FSSpec record specifying the directory to scan. + maxLevels input: Maximum number of directory levels to scan or + zero to scan all directory levels. + iterateFilter input: A pointer to the routine you want called once + for each file and directory found by + FSpIterateDirectory. + yourDataPtr input: A pointer to whatever data structure you might + want to access from within the IterateFilterProc. + + Result Codes + noErr 0 No error + nsvErr -35 No such volume + ioErr -36 I/O error + bdNamErr -37 Bad filename + fnfErr -43 File not found + paramErr -50 No default volume or iterateFilter was NULL + dirNFErr -120 Directory not found or incomplete pathname + afpAccessDenied -5000 User does not have the correct access + afpObjectTypeErr -5025 Directory not found or incomplete pathname + + __________ + + See also: RecurseFilterProcPtr, RecurseDirectory +*/ + + + +/*****************************************************************************/ + + + +#endif /* __RECURSEDIRECTORY__ */ diff --git a/macos/source/unixlike.c b/macos/source/unixlike.c new file mode 100644 index 0000000..4eb55da --- /dev/null +++ b/macos/source/unixlike.c @@ -0,0 +1,313 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/*--------------------------------------------------------------------------- + + unixlike.c + + Macintosh-specific routines to emulate unixfunctions. + + ---------------------------------------------------------------------------*/ + +/*****************************************************************************/ +/* Includes */ +/*****************************************************************************/ + +#include "zip.h" + +#include +#include +#include + +#include "unixlike.h" +#include "helpers.h" +#include "pathname.h" +#include "macstuff.h" +#include "macglob.h" +#include "mactime.h" + +/*****************************************************************************/ +/* Global Vars */ +/*****************************************************************************/ + +extern MacZipGlobals MacZip; +extern int errno; + + +/*****************************************************************************/ +/* Prototypes */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Functions */ +/*****************************************************************************/ + + + + +/* + *---------------------------------------------------------------------- + * + * MacStat -- + * + * This function replaces the library version of stat. The stat + * function provided by most Mac compiliers is rather broken and + * incomplete. + * + * Results: + * See stat documentation. + * + * Side effects: + * See stat documentation. + * + *---------------------------------------------------------------------- + */ + +int Zmacstat(const char *Fname, struct stat *buf) +{ + OSErr err, rc; + short fullPathLength; + Handle hFullPath; + char path[NAME_MAX], path2[NAME_MAX]; + HVolumeParam vpb; + static unsigned long count_of_files = 0; + + AssertStr(Fname,Fname) + Assert_it(buf,"","") + + UserStop(); + + memset(buf, 0, sizeof(buf)); /* zero out all fields */ + + RfDfFilen2Real(path2, Fname, MacZip.MacZipMode, MacZip.DataForkOnly, + &MacZip.CurrentFork); + GetCompletePath(path, path2, &MacZip.fileSpec, &err); + err = PrintUserHFSerr((err != -43) && (err != 0), err, path); + printerr("GetCompletePath:", err, err, __LINE__, __FILE__, path); + + if (err != noErr) { + errno = err; + return -1; + } + + /* Collect here some more information, it's not related to Macstat. + (note: filespec gets changed later in this function) */ + /* clear string-buffer */ + memset(MacZip.FullPath, 0x00, sizeof(MacZip.FullPath)); + rc = FSpGetFullPath(&MacZip.fileSpec, &fullPathLength, &hFullPath); + strncpy(MacZip.FullPath, *hFullPath, fullPathLength); + DisposeHandle(hFullPath); /* we don't need it any more */ + /* Collect some more information not related to Macstat */ + + + /* + * Fill the fpb & vpb struct up with info about file or directory. + */ + + FSpGetDirectoryID(&MacZip.fileSpec, &MacZip.dirID, &MacZip.isDirectory); + vpb.ioVRefNum = MacZip.fpb.hFileInfo.ioVRefNum = MacZip.fileSpec.vRefNum; + vpb.ioNamePtr = MacZip.fpb.hFileInfo.ioNamePtr = MacZip.fileSpec.name; + + if (MacZip.isDirectory) { + MacZip.fpb.hFileInfo.ioDirID = MacZip.fileSpec.parID; + /* + * Directories are executable by everyone. + */ + buf->st_mode |= UNX_IXUSR | UNX_IXGRP | UNX_IXOTH | UNX_IFDIR; + } else { + MacZip.fpb.hFileInfo.ioDirID = MacZip.dirID; + } + + MacZip.fpb.hFileInfo.ioFDirIndex = 0; + err = PBGetCatInfoSync((CInfoPBPtr)&MacZip.fpb); + + if (err == noErr) { + vpb.ioVolIndex = 0; + err = PBHGetVInfoSync((HParmBlkPtr)&vpb); + if (err == noErr && buf != NULL) { + /* + * Files are always readable by everyone. + */ + buf->st_mode |= UNX_IRUSR | UNX_IRGRP | UNX_IROTH; + + /* + * Use the Volume Info & File Info to fill out stat buf. + */ + if (MacZip.fpb.hFileInfo.ioFlAttrib & 0x10) { + buf->st_mode |= UNX_IFDIR; + buf->st_nlink = 2; + } else { + buf->st_nlink = 1; + if (MacZip.fpb.hFileInfo.ioFlFndrInfo.fdFlags & 0x8000) { + buf->st_mode |= UNX_IFLNK; + } else { + buf->st_mode |= UNX_IFREG; + } + } + + if (MacZip.fpb.hFileInfo.ioFlFndrInfo.fdType == 'APPL') { + /* + * Applications are executable by everyone. + */ + buf->st_mode |= UNX_IXUSR | UNX_IXGRP | UNX_IXOTH; + } + if ((MacZip.fpb.hFileInfo.ioFlAttrib & 0x01) == 0){ + /* + * If not locked, then everyone has write acces. + */ + buf->st_mode |= UNX_IWUSR | UNX_IWGRP | UNX_IWOTH; + } + + buf->st_ino = MacZip.fpb.hFileInfo.ioDirID; + buf->st_dev = MacZip.fpb.hFileInfo.ioVRefNum; + buf->st_uid = -1; + buf->st_gid = -1; + buf->st_rdev = 0; + + if (MacZip.CurrentFork == ResourceFork) + buf->st_size = MacZip.fpb.hFileInfo.ioFlRLgLen; + else + buf->st_size = MacZip.fpb.hFileInfo.ioFlLgLen; + + buf->st_blksize = vpb.ioVAlBlkSiz; + buf->st_blocks = (buf->st_size + buf->st_blksize - 1) + / buf->st_blksize; + + /* + * The times returned by the Mac file system are in the + * local time zone. We convert them to GMT so that the + * epoch starts from GMT. This is also consistent with + * what is returned from "clock seconds". + */ + if (!MacZip.isDirectory) { + MacZip.CreatDate = MacZip.fpb.hFileInfo.ioFlCrDat; + MacZip.ModDate = MacZip.fpb.hFileInfo.ioFlMdDat; + MacZip.BackDate = MacZip.fpb.hFileInfo.ioFlBkDat; + } else { + MacZip.CreatDate = MacZip.fpb.dirInfo.ioDrCrDat; + MacZip.ModDate = MacZip.fpb.dirInfo.ioDrMdDat; + MacZip.BackDate = MacZip.fpb.dirInfo.ioDrBkDat; + } + +#ifdef IZ_CHECK_TZ + if (!zp_tz_is_valid) + { + MacZip.HaveGMToffset = false; + MacZip.Md_UTCoffs = 0L; + MacZip.Cr_UTCoffs = 0L; + MacZip.Bk_UTCoffs = 0L; + } + else +#endif + { + /* Do not use GMT offsets when Md_UTCoffs calculation + * fails, since this time stamp is used for time + * comparisons in Zip and UnZip operations. + * We do not bother when GMT offset calculation fails for + * any other time stamp value. Instead we simply assume + * a default value of 0. + */ + MacZip.HaveGMToffset = + GetGMToffsetMac(MacZip.ModDate, &MacZip.Md_UTCoffs); + if (MacZip.HaveGMToffset) { + GetGMToffsetMac(MacZip.CreatDate, &MacZip.Cr_UTCoffs); + GetGMToffsetMac(MacZip.BackDate, &MacZip.Bk_UTCoffs); + } else { + MacZip.Cr_UTCoffs = 0L; + MacZip.Bk_UTCoffs = 0L; + } + } +#ifdef DEBUG_TIME + { + printf("\nZmacstat: MacZip.HaveGMToffset: %d", + MacZip.HaveGMToffset); + printf("\nZmacstat: Mac modif: %lu local -> UTOffset: %d", + MacZip.ModDate, MacZip.Md_UTCoffs); + printf("\nZmacstat: Mac creat: %lu local -> UTOffset: %d", + MacZip.CreatDate, MacZip.Cr_UTCoffs); + printf("\nZmacstat: Mac back: %lu local -> UTOffset: %d", + MacZip.BackDate, MacZip.Bk_UTCoffs); + } +#endif /* DEBUG_TIME */ + + + buf->st_mtime = MacFtime2UnixFtime(MacZip.ModDate); + buf->st_ctime = MacFtime2UnixFtime(MacZip.CreatDate); + buf->st_atime = buf->st_mtime; + +#ifdef DEBUG_TIME + { + printf("\nZmacstat: Unix modif: %lu UTC; Mac: %lu local", + buf->st_mtime, MacZip.ModDate); + printf("\nZmacstat: Unix creat: %lu UTC; Mac: %lu local\n", + buf->st_ctime, MacZip.CreatDate); + } +#endif /* DEBUG_TIME */ + + if (noisy) + { + if (MacZip.StatingProgress) + { + count_of_files++; + InformProgress(MacZip.RawCountOfItems, count_of_files ); + } + else + count_of_files = 0; + } + } + } + + if (err != noErr) { + errno = err; + } + + MacZip.isMacStatValid = true; + return (err == noErr ? 0 : -1); +} + + + + + +/* + *---------------------------------------------------------------------- + * + * chmod -- + * + * Results: + * See chmod documentation. + * + * Side effects: + * See chmod documentation. + * + *---------------------------------------------------------------------- + */ + +int chmod(char *path, int mode) +{ + HParamBlockRec hpb; + OSErr err; + + hpb.fileParam.ioNamePtr = C2PStr(path); + hpb.fileParam.ioVRefNum = 0; + hpb.fileParam.ioDirID = 0; + + if (mode & 0200) { + err = PBHRstFLockSync(&hpb); + } else { + err = PBHSetFLockSync(&hpb); + } + + if (err != noErr) { + errno = err; + return -1; + } + + return 0; +} diff --git a/macos/source/unixlike.h b/macos/source/unixlike.h new file mode 100644 index 0000000..e61a354 --- /dev/null +++ b/macos/source/unixlike.h @@ -0,0 +1,86 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/* + * Directory Operations for Mac based on BSD 4.3 + * By Jason Linhart, January 1997 + */ + +#ifndef _UNIXLIKE_H +#define _UNIXLIKE_H 1 + +#include + +#ifndef NAME_MAX +#define NAME_MAX 2048 +#endif + +#define UNX_IFMT 0170000 /* Unix file type mask */ +#define UNX_IFSOCK 0140000 /* Unix socket (BSD, not SysV or Amiga) */ +#define UNX_IFLNK 0120000 /* Unix symbolic link (not SysV, Amiga) */ +#define UNX_IFREG 0100000 /* Unix regular file */ +#define UNX_IFBLK 0060000 /* Unix block special (not Amiga) */ +#define UNX_IFDIR 0040000 /* Unix directory */ +#define UNX_IFCHR 0020000 /* Unix character special (not Amiga) */ +#define UNX_IFIFO 0010000 /* Unix fifo (BCC, not MSC or Amiga) */ + +#define UNX_ISUID 04000 /* Unix set user id on execution */ +#define UNX_ISGID 02000 /* Unix set group id on execution */ +#define UNX_ISVTX 01000 /* Unix directory permissions control */ +#define UNX_ENFMT UNX_ISGID /* Unix record locking enforcement flag */ + +#define UNX_IRWXU 00700 /* Unix read, write, execute: owner */ +#define UNX_IRUSR 00400 /* Unix read permission: owner */ +#define UNX_IWUSR 00200 /* Unix write permission: owner */ +#define UNX_IXUSR 00100 /* Unix execute permission: owner */ + +#define UNX_IRWXG 00070 /* Unix read, write, execute: group */ +#define UNX_IRGRP 00040 /* Unix read permission: group */ +#define UNX_IWGRP 00020 /* Unix write permission: group */ +#define UNX_IXGRP 00010 /* Unix execute permission: group */ + +#define UNX_IRWXO 00007 /* Unix read, write, execute: other */ +#define UNX_IROTH 00004 /* Unix read permission: other */ +#define UNX_IWOTH 00002 /* Unix write permission: other */ +#define UNX_IXOTH 00001 /* Unix execute permission: other */ + +/* historical file modes */ +#define S_IREAD 0x100 +#define S_IWRITE 0x80 +#define S_IEXEC 0x40 + + +#define isatty(arg) 1 + + +#define EINVAL 22 /* Invalid argument */ +#define ENAMETOOLONG 63 /* File name too long */ + + +struct dirent { + char d_name[NAME_MAX]; +}; + +/* + * The following definitions are usually found in fcntl.h. + * However, MetroWerks has screwed that file up a couple of times + * and all we need are the defines. + */ +#define O_APPEND 0x0100 /* open the file in append mode */ +#define O_CREAT 0x0200 /* create the file if it doesn't exist */ +#define O_EXCL 0x0400 /* if the file exists don't create it again */ +#define O_TRUNC 0x0800 /* truncate the file after opening it */ + + +int Zmacstat (const char *path, struct stat *buf); +int chmod(char *path, int mode); + + +#include "macstuff.h" + +#endif /* _UNIXLIKE_H */ diff --git a/macos/source/zip_rc.hqx b/macos/source/zip_rc.hqx new file mode 100644 index 0000000..99e0d25 --- /dev/null +++ b/macos/source/zip_rc.hqx @@ -0,0 +1,43 @@ +(This file must be converted with BinHex 4.0) +:#RTTF#jbBbjcDA3!8dP84&0*9#%!N!3([`#3"&(E8dP8)3!"!!!([h*-BA8#Q3# +3!aDCQ3d!"RTTF#jbB`!!&[Bi"2[rG!"-5QS!N!1!!*!%"32,j+m2!*!Drj!%8P0 +53e*6483"",#mXHDaqlGG!!!GmJ#3"JFj!*!%6Mi!N!MGc!`!P@6pq1R*k4&+Z,d +p"5$(b(-Upcc#j%EiHCfjPTq%8h+X8d)MR$`rF[b9Vh`pTLc2jqZ9r'RNq9VN1'& +'MMmj6Sk6#5HFc0J4lN8iHFU2--,*K%Z1NIR+#1XNR("#bE-)2I+FF$*G@H6BL+` +*!&6IV1ml1d+22#-$4UEm*#01"T`m*4`Ji(03ThM'$-EBilf-V8-e6Q8bXEVD@Xi +2bilcmGEY"lV6QGjZrK)I1CKZ$BfR4pSbLD'f`F'qVPKb+*(-*V2CPLfaGj1CE+a +Z+-$kpr4hpHrCf@d%f66E!A2P-rA6phmUj)QrdYP4r[6)H+cZF"hRV``NHSG5`b! +F6-0YBZ$!JH&%#frIb,2TmH4`LVGN4c1(%U1Q8#cf)P44dU"#-`D)I($H4I5qc[j +NJLI5)qpN5)Ic[S(-`-&1H(U2L*U'-H`1Y1p&qc#*YVk4(RNUbp(ae(#'R,B[d%B +(Nd40$id1C`FhmUlKNBmbkAf$Sra8qpDYcm0,H%GIhbiej(!EESbmC+a*'3dqdlC +j)%*H#+!,D!K4#J#3!$9H-J)mB*6L!50R"%"&hi6DD*61[-qq22%f1hkXPq@r)'` +(1hjQJ19cKP'bY0#60RQ3!&kd,r))mj-X,LBCCa&CeiX#f`ibZ$9##+[1HUJ34G5 +584+#&@p9i[UDj-&PD2rAi0qYdMpMQ""M8FLBT`#FUMje-i6rVXl2qI`jK@XY#eH ++%JH[5(`6,qEcH@K,(FfA4rZDNG,4mp60fALH@TT,SC!!5Sf0$HHP31&mP"AfKN) +K-!N[&XjM@##`1I,(a"V"#L%@#U9'*'lT-5CaU8GqpLTFkUP"%klmfMLJ1QpH5r2 +djNdfhIXJFIqqN!!&1QHe$jUlHF`jZ2I41X8k$@ZbKF1C2"Cq6YZaF(Z+5Yra&63 +"alCh62Vm6N(RqR90&)#m`cE3mILqV`@qBmcQkf0"9Ei%#**RRRpcS0DmV!N6DB- +&#R112Ym4-1d)GJ(R0,i,0!TEJ!%$#Mj$SFqp80)XU4&"+j!!DmFJk)S2*[(KNMR +mHApd)4Im@I2aqEBrpd,EVi3ehd@qETI[eprhmmlp0UGjqhe`q#[[Ljk#GDclAll +[P91j$d[[ir`4X1LcbmVcI$8cCd49rY*`E2l+F1l-Uk0CV,edY8%d('d@pD*qVRk +L@64FE9KlU9Q%E`3$i@+cD"BSp)'26f,8K%[iL[#3!$-h&aDPY5L2CJBBpF5Kh5k ++ASJVqckQ9kG`*C95rEka+29B5U+f"eYIqF&ZC()P-%GbHXQ44)a!l[Z9q3[c5Z! +aN!!pGHT"X#q,IJ$8lG#i224dkNXMhd,#3I"ap4JkEk@YlrKEp1r14erRqIYVJY@ +RbX4G0GVTc4A5A20`[E`GcX60GGI#0@$KHMqfFB9BIV4&%kr6+kH*J`(FR3lKcJj +pNqpN!JiZ-`'&1jQ!a*e-31RCQB$%R8c!dY1CJ19(C`+@AjGIa[qCCq8qH,K8FA% +LH$LpGbZiFpp0ehUR[lZTL-[HU3T8q*FVkd5&AaDBjrX##ha2S$UImK6,r-Z9MDM +#PaVqNfUH+VqmXplAGpG!G`k,I&I!i[ZC`J,Iba3@rEQC`J,Iba5@rFQGIhNq5h` +r-lM2ArAJIYjp(jEjYX!5he+i`cIhZRrjYq)%rjNh@"K4Ej!!V8&p!,8@0C*$l3L +bk#`f"%i9DMaRk,i*YC&aj0dFH6G(hXf4Gh2Nh4ajYp5aY(5[I@a#hBBDeh9E'*X +Kq3q,)QS*99$0SCj&R68Va[9Ie6lJ9444KDk%dDE9%CrPQhJ,hbD#)RJ8936RJK1 +bjb%HMTILXr&#r&Um++SIZ#*1fAP1hM-c'CG*VekG*BkGApkj'DZA13GkPA1JPcN +(iC4c%*m@1&[2l0@LLCK%pFUBG%kj4M@2,@pY&UjA+*Y2#Zil5%pF&GI[LBAVh-2 +$3I"aCG,5ekC[qL[MlZ1QRP32Ga5YQFY`Cf-[rZ!JX+GrCir-1R)J6J!jdY[ekRU +IXFT6',*jNmH[B69Hq&&6$N-NlS3K8Xm03mM2+VTKb253!iSqNDRHIKqNq$hqV6$ +%pVF8KPMc@68N$0Q#[KXH1UJL$1P'',*PpB``C"5M'eXG)JbTfDal(BB!AfdN$-' +cjq2P-%6bli8Kq,pej"NCErJr%NGk[[Pkpa44M+pBl4Mq$SC![ij'pZ[3j20d)N[ +i$qR%J5hSI`01r3hJcl+!m54`kMY9f'+N1PrYaRqe4SCq@E8Hr)$%dK,,5@`LdR2 +b$cBKPr+"5-q*AH`)BBm-4AUqlG-DHk"a9QQ`Yi"0+Beefb-pTlj6'Z(2`,ZS0"j ++!KY9'SpQ-0f,5U2Q'(Lr+Sd(h`3fV65DpX2VT0+)[!EHKdUMS4ABTdVMX4IJG8T +T'*pJ6K'P8IXk0+iTMFB8I'L[i9r!Qp6c`!dlH9,2idGJTp9PD'b(MjH9AZ0cQ02 +TqYdI$#8c2*2-$Kr+**,r!`#3!dm4!!!: diff --git a/macos/zipup.h b/macos/zipup.h new file mode 100644 index 0000000..ce2af4a --- /dev/null +++ b/macos/zipup.h @@ -0,0 +1,25 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#ifndef O_RDONLY +# include +#endif + +#define fhow (O_RDONLY|O_BINARY) +#define fbad (-1) + +typedef int ftype; + + +#define zopen(n,p) MacOpen(n,p) +#define zread(f,b,n) read(f,b,n) +#define zclose(f) close(f) +#define zerr(f) (k == (extent)(-1L)) +#define zstdin 0 + + diff --git a/man/zip.1 b/man/zip.1 new file mode 100644 index 0000000..0c2fce0 --- /dev/null +++ b/man/zip.1 @@ -0,0 +1,2840 @@ +.\" ========================================================================= +.\" Copyright (c) 1990-2008 Info-ZIP. All rights reserved. +.\" +.\" See the accompanying file LICENSE, version 2007-Mar-4 or later +.\" (the contents of which are also included in zip.h) for terms of use. +.\" If, for some reason, all these files are missing, the Info-ZIP license +.\" also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +.\" ========================================================================== +.\" +.\" zip.1 by Mark Adler, Jean-loup Gailly and R. P. C. Rodgers +.\" updated by E. Gordon for Zip 3.0 (8 May 2005, 24 December 2006, +.\" 4 February 2007, 27 May 2007, 4 June 2007 by EG; 12 June 2007 by CS; +.\" 30 August 2007, 27 April 2008, 25 May 2008, 27 May 2008 by EG, +.\" 7 June 2008 by SMS and EG; 12 June 2008 by EG) +.\" +.TH ZIP 1L "16 June 2008 (v3.0)" Info-ZIP +.SH NAME +zip \- package and compress (archive) files +.SH SYNOPSIS +.B zip +.RB [\- aABcdDeEfFghjklLmoqrRSTuvVwXyz!@$ ] +[\-\-longoption ...] +.RB [\- b " path]" +.RB [\- n " suffixes]" +.RB [\- t " date]" +.RB [\- tt " date]" +[\fIzipfile\fR [\fIfile\fR \.\|.\|.]] +[\fB-xi\fR list] +.PP +.B zipcloak +(see separate man page) +.PP +.B zipnote +(see separate man page) +.PP +.B zipsplit +(see separate man page) +.PP +Note: Command line processing in +.I zip +has been changed to support long options and handle all +options and arguments more consistently. Some old command +lines that depend on command line inconsistencies may no longer +work. +.SH DESCRIPTION +.I zip +is a compression and file packaging utility for Unix, VMS, MSDOS, +OS/2, Windows 9x/NT/XP, Minix, Atari, Macintosh, Amiga, and Acorn +RISC OS. It is analogous to a combination of the Unix commands +.IR tar (1) +and +.IR compress (1) +and is compatible with PKZIP (Phil Katz's ZIP for MSDOS systems). +.LP +A companion program +.RI ( unzip (1L)) +unpacks +.I zip +archives. +The +.I zip +and +.IR unzip (1L) +programs can work with archives produced by PKZIP (supporting +most PKZIP features up to PKZIP version 4.6), +and PKZIP and PKUNZIP can work with archives produced by +\fIzip\fP (with some exceptions, notably streamed archives, +but recent changes in the zip file standard may facilitate +better compatibility). +.I zip +version 3.0 is compatible with PKZIP 2.04 and also supports +the Zip64 extensions of PKZIP 4.5 which allow archives +as well as files to exceed the previous 2 GB limit (4 GB in +some cases). \fIzip\fP also now supports \fBbzip2\fP compression +if the \fBbzip2\fP library is included when \fIzip\fP is compiled. +Note that PKUNZIP 1.10 cannot extract files produced by +PKZIP 2.04 or +\fIzip\ 3.0\fP. You must use PKUNZIP 2.04g or +\fIunzip\ 5.0p1\fP (or later versions) to extract them. +.PP +See the \fBEXAMPLES\fP section at the bottom of this page +for examples of some typical uses of \fIzip\fP. +.PP +\fBLarge\ Archives\ and\ Zip64.\fP +.I zip +automatically uses the Zip64 extensions when files larger than 4 GB are +added to an archive, an archive containing Zip64 entries is updated +(if the resulting archive still needs Zip64), +the size of the archive will exceed 4 GB, or when the +number of entries in the archive will exceed about 64K. +Zip64 is also used for archives streamed from standard input as the size +of such archives are not known in advance, but the option \fB\-fz\-\fP can +be used to force \fIzip\fP to create PKZIP 2 compatible archives (as long +as Zip64 extensions are not needed). You must use a PKZIP 4.5 +compatible unzip, such as \fIunzip\ 6.0\fP or later, to extract files +using the Zip64 extensions. +.PP +In addition, streamed archives, entries encrypted with standard encryption, +or split archives created with the pause option may not be compatible with +PKZIP as data descriptors are used +and PKZIP at the time of this writing does not support data descriptors +(but recent changes in the PKWare published zip standard now include some +support for the data descriptor format \fIzip\fP uses). + +.PP +\fBMac OS X.\fP Though previous Mac versions had their own \fIzip\fP port, +\fIzip\fP supports Mac OS X as part of the Unix port and most Unix features +apply. References to "MacOS" below generally refer to MacOS versions older +than OS X. Support for some Mac OS features in the Unix Mac OS X port, such +as resource forks, is expected in the next \fIzip\fP release. + +.PP +For a brief help on \fIzip\fP and \fIunzip\fP, +run each without specifying any parameters on the command line. + +.SH "USE" +.PP +The program is useful for packaging a set of files for distribution; +for archiving files; +and for saving disk space by temporarily +compressing unused files or directories. +.LP +The +.I zip +program puts one or more compressed files into a single +.I zip +archive, +along with information about the files +(name, path, date, time of last modification, protection, +and check information to verify file integrity). +An entire directory structure can be packed into a +.I zip +archive with a single command. +Compression ratios of 2:1 to 3:1 are common for text files. +.I zip +has one compression method (deflation) and can also store files without +compression. (If \fBbzip2\fP support is added, \fIzip\fP can also +compress using \fBbzip2\fP compression, but such entries require a +reasonably modern unzip to decompress. When \fBbzip2\fP compression +is selected, it replaces deflation as the default method.) +.I zip +automatically chooses the better of the two (deflation or store or, if +\fBbzip2\fP is selected, \fBbzip2\fP or store) for each file to be +compressed. +.LP +\fBCommand\ format.\fP The basic command format is +.IP +\fBzip\fR options archive inpath inpath ... +.LP +where \fBarchive\fR is a new or existing \fIzip\fR archive +and \fBinpath\fR is a directory or file path optionally including wildcards. +When given the name of an existing +.I zip +archive, +.I zip +will replace identically named entries in the +.I zip +archive (matching the relative names as stored in +the archive) or add entries for new names. +For example, +if +.I foo.zip +exists and contains +.I foo/file1 +and +.IR foo/file2 , +and the directory +.I foo +contains the files +.I foo/file1 +and +.IR foo/file3 , +then: +.IP +\fCzip -r foo.zip foo\fP +.LP +or more concisely +.IP +\fCzip -r foo foo\fP +.LP +will replace +.I foo/file1 +in +.I foo.zip +and add +.I foo/file3 +to +.IR foo.zip . +After this, +.I foo.zip +contains +.IR foo/file1 , +.IR foo/file2 , +and +.IR foo/file3 , +with +.I foo/file2 +unchanged from before. +.LP +So if before the zip command is executed \fIfoo.zip\fP has: +.IP +\fC foo/file1 foo/file2 +.LP +and directory foo has: +.IP +\fC file1 file3\fP +.LP +then \fIfoo.zip\fP will have: +.IP +\fC foo/file1 foo/file2 foo/file3\fP +.LP +where \fIfoo/file1\fP is replaced and +\fIfoo/file3\fP is new. +.LP +\fB\-@\ file\ lists.\fP If a file list is specified as +\fB\-@\fP +[Not on MacOS], +.I zip +takes the list of input files from standard input instead of from +the command line. For example, +.IP +\fCzip -@ foo\fP +.LP +will store the files listed one per line on stdin in \fIfoo.zip\fP. +.LP +Under Unix, +this option can be used to powerful effect in conjunction with the +\fIfind\fP\ (1) +command. +For example, +to archive all the C source files in the current directory and +its subdirectories: +.IP +\fCfind . -name "*.[ch]" -print | zip source -@\fP +.LP +(note that the pattern must be quoted to keep the shell from expanding it). +.LP +\fBStreaming\ input\ and\ output.\fP +.I zip +will also accept a single dash ("-") as the zip file name, in which case it +will write the zip file to standard output, allowing the output to be piped +to another program. For example: +.IP +\fCzip -r - . | dd of=/dev/nrst0 obs=16k\fP +.LP +would write the zip output directly to a tape with the specified block size +for the purpose of backing up the current directory. +.LP +.I zip +also accepts a single dash ("-") as the name of a file to be compressed, in +which case it will read the file from standard input, allowing zip to take +input from another program. For example: +.IP +\fCtar cf - . | zip backup -\fP +.LP +would compress the output of the tar command for the purpose of backing up +the current directory. This generally produces better compression than +the previous example using the -r option because +.I zip +can take advantage of redundancy between files. The backup can be restored +using the command +.IP +\fCunzip -p backup | tar xf -\fP +.LP +When no zip file name is given and stdout is not a terminal, +.I zip +acts as a filter, compressing standard input to standard output. +For example, +.IP +\fCtar cf - . | zip | dd of=/dev/nrst0 obs=16k\fP +.LP +is equivalent to +.IP +\fCtar cf - . | zip - - | dd of=/dev/nrst0 obs=16k\fP +.LP +.I zip +archives created in this manner can be extracted with the program +.I funzip +which is provided in the +.I unzip +package, or by +.I gunzip +which is provided in the +.I gzip +package (but some +.I gunzip +may not support this if +.I zip +used the Zip64 extensions). For example: +.IP +\fPdd if=/dev/nrst0 ibs=16k | funzip | tar xvf -\fC +.LP +The stream can also be saved to a file and +.I unzip +used. +.LP +If Zip64 support for large files and archives is enabled and +\fIzip\fR is used as a filter, \fIzip\fR creates a Zip64 archive +that requires a PKZIP 4.5 or later compatible unzip to read it. This is +to avoid amgibuities in the zip file structure as defined in the current +zip standard (PKWARE AppNote) where the decision to use Zip64 needs to +be made before data is written for the entry, but for a stream the size +of the data is not known at that point. If the data is known to be smaller +than 4 GB, the option \fB\-fz\-\fP can be used to prevent use of Zip64, +but \fIzip\fP will exit with an error if Zip64 was in fact needed. +\fIzip\ 3\fR and \fIunzip\ 6\fR and later can read archives with Zip64 +entries. Also, \fIzip\fP removes the Zip64 extensions if not needed +when archive entries are copied (see the \fB\-U\fP (\fB\-\-copy\fP) +option). +.LP +When directing the output to another file, note that all options should be +before the redirection including \fB-x\fP. For example: +.IP +\fPzip archive "*.h" "*.c" -x donotinclude.h orthis.h > tofile\fC +.LP +\fBZip\ files.\fP When changing an existing +.I zip +archive, +.I zip +will write a temporary file with the new contents, +and only replace the old one when the process of creating the new version +has been completed without error. +.LP +If the name of the +.I zip +archive does not contain an extension, the extension +\fB.zip\fP +is added. If the name already contains an extension other than +\fB.zip\fP, +the existing extension is kept unchanged. However, split archives +(archives split over multiple files) require the \fB.zip\fP extension +on the last split. +.PP +\fBScanning\ and\ reading\ files.\fP +When \fIzip\fP starts, it scans for files to process (if needed). If +this scan takes longer than about 5 seconds, \fIzip\fP will display +a "Scanning files" message and start displaying progress dots every 2 seconds +or every so many entries processed, whichever takes longer. If there is more +than 2 seconds between dots it could indicate that finding each file is taking +time and could mean a slow network connection for example. +(Actually the initial file scan is +a two-step process where the directory scan is followed by a sort and these +two steps are separated with a space in the dots. If updating an existing +archive, a space also appears between the existing file scan and the new +file scan.) The scanning files dots are not controlled by the \fB\-ds\fP +dot size option, but the dots are turned off by the \fB\-q\fP quiet option. The +\fB\-sf\fP show files option can be used to scan for files and get the list of +files scanned without actually processing them. +.LP +If \fIzip\fR is not able to read a file, it +issues a warning but +continues. See the \fB\-MM\fP option below for more on how \fIzip\fP handles +patterns that are not matched and files that are not readable. +If some files were skipped, a +warning is issued at the end of the zip operation noting how many files +were read and how many skipped. +.PP +\fBCommand\ modes.\fP \fIzip\fP now supports two distinct types of command +modes, \fBexternal\fP and \fBinternal\fP. The \fBexternal\fP modes +(add, update, and freshen) read files from the file system (as well as from an +existing archive) while the \fBinternal\fP modes (delete and copy) operate +exclusively on entries in an existing archive. +.LP +.TP +.BI add\ \ \ \ \ \ +Update existing entries and add new files. If the archive does not exist +create it. This is the default mode. +.TP +.BI update\ \fP(\fB\-u\fP) +Update existing entries if newer on the file system and add new files. If +the archive does not exist issue warning then create a new archive. +.TP +.BI freshen\ \fP(\fB\-f\fP) +Update existing entries of an archive if newer on the file system. +Does not add new files to the archive. +.TP +.BI delete\ \fP(\fB\-d\fP) +Select entries in an existing archive and delete them. +.TP +.BI copy\ \fP(\fB\-U\fP) +Select entries in an existing archive and copy them to a new archive. +This new mode is similar to \fBupdate\fP but command line patterns +select entries in the existing archive rather than files from +the file system and it uses the \fB\-\-out\fP option to write the +resulting archive to a new file rather than update the existing +archive, leaving the original archive unchanged. +.LP +The new File Sync option (\fB\-FS\fP) is also considered a new mode, +though it is similar to \fBupdate\fP. This mode synchronizes the +archive with the files on the OS, only replacing files in the +archive if the file time or size of the OS file is different, adding +new files, and deleting entries from the archive where there is +no matching file. As this mode can delete entries from the archive, +consider making a backup copy of the archive. + +Also see \fB\-DF\fP for creating difference archives. + +See each option description below for details and the \fBEXAMPLES\fP section +below for examples. +.PP +\fBSplit\ archives.\fP \fIzip\fP version 3.0 and later can create split +archives. A +\fBsplit archive\fP is a standard zip archive split over multiple +files. (Note that split archives are not just archives split in to +pieces, as the offsets of entries are now based on the start of each +split. Concatenating the pieces together will invalidate these offsets, +but \fIunzip\fP can usually deal with it. \fIzip\fP will usually refuse +to process such a spliced archive unless the \fB\-FF\fP fix option is +used to fix the offsets.) +.LP +One use of split archives is storing a large archive on multiple +removable media. +For a split archive with 20 split files the files are typically named (replace +ARCHIVE with the name of your archive) ARCHIVE.z01, ARCHIVE.z02, ..., ARCHIVE.z19, +ARCHIVE.zip. Note that the last file is the \fB.zip\fP file. In contrast, +\fBspanned archives\fP are the original multi-disk archive generally requiring +floppy disks and using volume labels to store disk numbers. \fIzip\fP supports +split archives but not spanned archives, though a procedure exists for converting +split archives of the right size to spanned archives. The reverse is also true, +where each file of a spanned archive can be copied in order to files with the +above names to create a split archive. +.LP +Use \fB\-s\fP to set the split size and create a split archive. The size is +given as a number followed optionally by one of k (kB), m (MB), g (GB), or t (TB) +(the default is m). The \fB\-sp\fP option can be used to pause \fIzip\fP between +splits to allow changing removable media, for example, but read the descriptions +and warnings for both \fB\-s\fP and \fB\-sp\fP below. +.LP +Though \fIzip\fP does not update split archives, \fIzip\fP provides the new +option \fB\-O\fP (\fB\-\-output\-file\fP or \fB\-\-out\fP) to allow split archives +to be updated and saved in a new archive. For example, +.IP +\fCzip inarchive.zip foo.c bar.c \-\-out outarchive.zip\fP +.LP +reads archive \fBinarchive.zip\fP, even if split, adds the files \fBfoo.c\fP and +\fBbar.c\fP, and writes the resulting archive to \fBoutarchive.zip\fP. If +\fBinarchive.zip\fP is split then \fBoutarchive.zip\fP defaults to the same +split size. Be aware that if \fBoutarchive.zip\fP and any split files that are +created with it already exist, these are always overwritten as needed without +warning. This may be changed in the future. +.PP +\fBUnicode.\fP Though the zip standard requires storing paths in an archive using +a specific character set, in practice zips have stored paths in archives in whatever +the local character set is. This creates problems when an archive is created or +updated on a system using one character set and then extracted on another system +using a different character set. When compiled with Unicode support enabled on +platforms that support wide characters, \fIzip\fP now stores, in addition to the +standard local path for backward compatibility, the UTF-8 translation of the path. +This provides a common universal character set for storing paths that allows these +paths to be fully extracted on other systems that support Unicode and to match as +close as possible on systems that don't. + +On Win32 systems where paths are internally stored as Unicode but represented in +the local character set, it's possible that some paths will be skipped during a +local character set directory scan. \fIzip\fP with Unicode support now can read +and store these paths. Note that Win 9x systems and FAT file systems don't fully +support Unicode. + +Be aware that console windows on Win32 and Unix, for example, sometimes don't +accurately show all characters due to how each operating system switches in +character sets for display. However, directory navigation tools should show the +correct paths if the needed fonts are loaded. +.PP +\fBCommand line format.\fP This version of +.I zip +has updated command line processing and support for long options. +.PP +Short options take the form +.IP +\fC-s[-][s[-]...][value][=value][\ value]\fP +.LP +where s is a one or two character short option. A short option +that takes a value is last in an argument and anything after it is +taken as the value. If the option can be negated and "-" immediately +follows the option, the option is negated. +Short options can also be given as separate arguments +.IP +\fC-s[-][value][=value][\ value]\ -s[-][value][=value][\ value]\ ...\fP +.LP +Short options in general take values either as part of the same +argument or as the following argument. An optional = is also supported. +So +.IP +\fC-ttmmddyyyy\fP +.LP +and +.IP +\fC-tt=mmddyyyy\fP +.LP +and +.IP +\fC-tt mmddyyyy\fP +.LP +all work. The \fB\-x\fP and \fB\-i\fP options accept lists of values +and use a slightly different format described below. See the +\fB\-x\fP and \fB\-i\fP options. +.PP +Long options take the form +.IP +\fC--longoption[-][=value][ value]\fP +.LP +where the option starts with --, has a multicharacter name, can +include a trailing dash to negate the option (if the option +supports it), and can have a value (option argument) specified by +preceeding it with = (no spaces). Values can also follow the +argument. So +.IP +\fC--before-date=mmddyyyy\fP +.LP +and +.IP +\fC--before-date mmddyyyy\fP +.LP +both work. + +Long option names can be shortened to the shortest unique +abbreviation. See the option descriptions below for which +support long options. To avoid confusion, avoid abbreviating +a negatable option with an embedded dash ("-") at the dash +if you plan to negate it (the parser would consider +a trailing dash, such as for the option \fB\-\-some\-option\fP using +\fB\-\-some\-\fP as the option, as part of the name rather +than a negating dash). This may be changed to force the last +dash in \fB\-\-some\-\fP to be negating in the future. +.SH "OPTIONS" +.TP +.PD 0 +.BI \-a +.TP +.PD +.B \-\-ascii +[Systems using EBCDIC] Translate file to ASCII format. + +.TP +.PD 0 +.B \-A +.TP +.PD +.B \-\-adjust-sfx +Adjust self-extracting executable archive. +A self-extracting executable archive is created by prepending +the SFX stub to an existing archive. The +.B \-A +option tells +.I zip +to adjust the entry offsets stored +in the archive to take into account this "preamble" data. +.LP +Note: self-extracting archives for the Amiga are a special case. +At present, only the Amiga port of \fIzip\fP is capable of adjusting +or updating these without corrupting them. -J can be used to remove +the SFX stub if other updates need to be made. + +.TP +.PD 0 +.B \-AC +.TP +.PD +.B \-\-archive-clear +[WIN32] Once archive is created (and tested if \fB\-T\fP is used, +which is recommended), clear the archive bits of files processed. WARNING: +Once the bits are cleared they are cleared. You may want to use the +\fB\-sf\fP show files option to store the list of files processed in case +the archive operation must be repeated. Also consider using +the \fB\-MM\fP must match option. Be sure to check out \fB\-DF\fP as a +possibly better way to do incremental backups. + +.TP +.PD 0 +.B \-AS +.TP +.PD +.B \-\-archive-set +[WIN32] Only include files that have the archive bit set. Directories +are not stored when \fB\-AS\fP is used, though by default the paths +of entries, including directories, are stored as usual and can be used +by most unzips to recreate directories. + +The archive bit is set by the operating system when a file is modified +and, if used with \fB\-AC\fP, \fB\-AS\fP can provide an +incremental backup capability. However, other applications can +modify the archive bit and it may not be a reliable indicator of +which files have changed since the last archive operation. Alternative +ways to create incremental backups are using \fB\-t\fP to use file dates, +though this won't catch old files copied to directories being archived, +and \fB\-DF\fP to create a differential archive. + +.TP +.PD 0 +.B \-B +.TP +.PD +.B \-\-binary +[VM/CMS and MVS] force file to be read binary (default is text). + +.TP +.B \-B\fRn +[TANDEM] set Edit/Enscribe formatting options with n defined as +.RS +bit 0: Don't add delimiter (Edit/Enscribe) +.RE +.RS +bit 1: Use LF rather than CR/LF as delimiter (Edit/Enscribe) +.RE +.RS +bit 2: Space fill record to maximum record length (Enscribe) +.RE +.RS +bit 3: Trim trailing space (Enscribe) +.RE +.RS +bit 8: Force 30K (Expand) large read for unstructured files +.RE + +.TP +.PD 0 +.BI \-b\ \fRpath +.TP +.PD +.B \-\-temp-path\ \fRpath +Use the specified +.I path +for the temporary +.I zip +archive. For example: +.RS +.IP +\fCzip -b /tmp stuff *\fP +.RE +.IP +will put the temporary +.I zip +archive in the directory +.IR /tmp , +copying over +.I stuff.zip +to the current directory when done. This option is useful when +updating an existing archive and the file system containing this +old archive does not have enough space to hold both old and new archives +at the same time. It may also be useful when streaming in some +cases to avoid the need for data descriptors. Note that using +this option may require \fIzip\fP take additional time to copy +the archive file when done to the destination file system. + +.TP +.PD 0 +.B \-c +.TP +.PD +.B \-\-entry-comments +Add one-line comments for each file. +File operations (adding, updating) are done first, +and the user is then prompted for a one-line comment for each file. +Enter the comment followed by return, or just return for no comment. + +.TP +.PD 0 +.B \-C +.TP +.PD +.B \-\-preserve-case +[VMS] Preserve case all on VMS. Negating this option +(\fB\-C-\fP) downcases. + +.TP +.PD 0 +.B \-C2 +.TP +.PD +.BI \-\-preserve-case-2 +[VMS] Preserve case ODS2 on VMS. Negating this option +(\fB\-C2-\fP) downcases. + +.TP +.PD 0 +.B \-C5 +.TP +.PD +.B \-\-preserve-case-5 +[VMS] Preserve case ODS5 on VMS. Negating this option +(\fB\-C5-\fP) downcases. + +.TP +.PD 0 +.B \-d +.TP +.PD +.B \-\-delete +Remove (delete) entries from a +.I zip +archive. +For example: +.RS +.IP +\fCzip -d foo foo/tom/junk foo/harry/\\* \\*.o\fP +.RE +.IP +will remove the entry +.IR foo/tom/junk , +all of the files that start with +.IR foo/harry/ , +and all of the files that end with +.B \&.o +(in any path). +Note that shell pathname expansion has been inhibited with backslashes, +so that +.I zip +can see the asterisks, +enabling +.I zip +to match on the contents of the +.I zip +archive instead of the contents of the current directory. +(The backslashes are not used on MSDOS-based platforms.) +Can also use quotes to escape the asterisks as in +.RS +.IP +\fCzip -d foo foo/tom/junk "foo/harry/*" "*.o"\fP +.RE +.IP +Not escaping the asterisks on a system where the shell expands +wildcards could result in the asterisks being converted to a +list of files in the current directory and that list used to +delete entries from the archive. +.IP +Under MSDOS, +.B \-d +is case sensitive when it matches names in the +.I zip +archive. +This requires that file names be entered in upper case if they were +zipped by PKZIP on an MSDOS system. (We considered making this +case insensitive on systems where paths were case insensitive, +but it is possible the archive came from a system where case does +matter and the archive could include both \fBBar\fP and \fBbar\fP +as separate files in the archive.) But see the new option \fB\-ic\fP +to ignore case in the archive. + +.TP +.PD 0 +.B \-db +.TP +.PD +.B \-\-display-bytes +Display running byte counts showing the bytes zipped and the bytes to go. + +.TP +.PD 0 +.B \-dc +.TP +.PD +.B \-\-display-counts +Display running count of entries zipped and entries to go. + +.TP +.PD 0 +.B \-dd +.TP +.PD +.B \-\-display-dots +Display dots while each entry is zipped (except on ports that have their own +progress indicator). See \fB-ds\fR below for setting dot size. The default is +a dot every 10 MB of input file processed. The \fB-v\fR option +also displays dots (previously at a much higher rate than this but now \fB\-v\fP +also defaults to 10 MB) and this rate is also controlled by \fB-ds\fR. + +.TP +.PD 0 +.B \-df +.TP +.PD +.B \-\-datafork +[MacOS] Include only data-fork of files zipped into the archive. +Good for exporting files to foreign operating-systems. +Resource-forks will be ignored at all. + +.TP +.PD 0 +.B \-dg +.TP +.PD +.B \-\-display-globaldots +Display progress dots for the archive instead of for each file. The command +.RS +.IP + zip -qdgds 10m +.RE +.IP +will turn off most output except dots every 10 MB. + +.TP +.PD 0 +.B \-ds\ \fRsize +.TP +.PD +.B \-\-dot-size\ \fRsize +Set amount of input file processed for each dot displayed. See \fB-dd\fR to +enable displaying dots. Setting this option implies \fB-dd\fR. Size is +in the format nm where n is a number and m is a multiplier. Currently m can +be k (KB), m (MB), g (GB), or t (TB), so if n is 100 and m is k, size would be +100k which is 100 KB. The default is 10 MB. +.IP +The \fB-v\fR option also displays dots and now defaults to +10 MB also. This rate is also controlled by this option. A size of 0 turns dots off. +.IP +This option does not control the dots from the "Scanning files" message as +\fIzip\fP scans for input files. The dot size for that is fixed at 2 seconds +or a fixed number of entries, whichever is longer. + +.TP +.PD 0 +.B \-du +.TP +.PD +.B \-\-display-usize +Display the uncompressed size of each entry. + +.TP +.PD 0 +.B \-dv +.TP +.PD +.B \-\-display-volume +Display the volume (disk) number each entry is being read from, +if reading an existing archive, and being written to. + +.TP +.PD 0 +.B \-D +.TP +.PD +.B \-\-no-dir-entries +Do not create entries in the +.I zip +archive for directories. Directory entries are created by default so that +their attributes can be saved in the zip archive. +The environment variable ZIPOPT can be used to change the default options. For +example under Unix with sh: +.RS +.IP +ZIPOPT="-D"; export ZIPOPT +.RE +.IP +(The variable ZIPOPT can be used for any option, including \fB\-i\fP and \fB\-x\fP +using a new option format detailed below, and can include several options.) The option +.B \-D +is a shorthand +for +.B \-x +"*/" but the latter previously could not be set as default in the ZIPOPT +environment variable as the contents of ZIPOPT gets inserted near the beginning +of the command line and the file list had to end at the end of the line. +.IP +This version of +.I zip +does allow +.B \-x +and +.B \-i +options in ZIPOPT if the form +.IP +\fC +.BR \-x \ file\ file\ ... \ @\fP +.IP +is used, where the @ (an argument that is just @) terminates +the list. + +.TP +.PD 0 +.B \-DF +.TP +.PD +.B \-\-difference-archive +Create an archive that contains all new and changed files since +the original archive was created. For this to work, the input +file list and current directory must be the same as during the +original \fIzip\fP operation. +.IP +For example, if the existing archive was created using +.RS +.IP +\fCzip -r foofull . +.RE +.IP +from the \fIbar\fP directory, then the command +.RS +.IP +\fCzip -r foofull . -DF --out foonew +.RE +.IP +also from the \fIbar\fP directory creates the archive \fIfoonew\fP +with just the files not in \fIfoofull\fP and the files where +the size or file time of the files do not match those in \fIfoofull\fP. + +Note that the timezone environment variable TZ should be set according to +the local timezone in order for this option to work correctly. A +change in timezone since the original archive was created could +result in no times matching and all files being included. + +A possible approach to backing up a directory might be to create +a normal archive of the contents of the directory as a full +backup, then use this option to create incremental backups. + +.TP +.PD 0 +.B \-e +.TP +.PD +.B \-\-encrypt +Encrypt the contents of the +.I zip +archive using a password which is entered on the terminal in response +to a prompt +(this will not be echoed; if standard error is not a tty, +.I zip +will exit with an error). +The password prompt is repeated to save the user from typing errors. + +.TP +.PD 0 +.B \-E +.TP +.PD +.B \-\-longnames +[OS/2] Use the .LONGNAME Extended Attribute (if found) as filename. + +.TP +.PD 0 +.B \-f +.TP +.PD +.B \-\-freshen +Replace (freshen) an existing entry in the +.I zip +archive only if it has been modified more recently than the +version already in the +.I zip +archive; +unlike the update option +.RB ( \-u ) +this will not add files that are not already in the +.I zip +archive. +For example: +.RS +.IP +\fCzip -f foo\fP +.RE +.IP +This command should be run from the same directory from which the original +.I zip +command was run, since paths stored in +.I zip +archives are always relative. +.IP +Note that the timezone environment variable TZ should be set according to +the local timezone in order for the +\fB\-f\fP, \fB\-u\fP and \fB\-o\fP +options to work correctly. +.IP +The reasons behind this are somewhat subtle but have to do with the differences +between the Unix-format file times (always in GMT) and most of the other +operating systems (always local time) and the necessity to compare the two. +A typical TZ value is ``MET-1MEST'' (Middle European time with automatic +adjustment for ``summertime'' or Daylight Savings Time). +.IP +The format is TTThhDDD, where TTT is the time zone such as MET, hh is the +difference between GMT and local time such as -1 above, and DDD is +the time zone when daylight savings time is in effect. Leave off +the DDD if there is no daylight savings time. For the US Eastern +time zone EST5EDT. + +.TP +.PD 0 +.B \-F +.TP +.B \-\-fix\ \ \ \ \ \ +.TP +.B \-FF +.TP +.PD +.B \-\-fixfix\ \ +Fix the +.I zip +archive. The \fB\-F\fP option can be used if some portions of the archive +are missing, but requires a reasonably intact central directory. +The input archive is scanned as usual, but \fIzip\fP will ignore +some problems. The resulting archive should be valid, but any +inconsistent entries will be left out. +.IP +When doubled as in +\fB\-FF\fP, +the archive is scanned from the beginning and \fIzip\fP scans for special +signatures to identify the limits between the archive members. The +single +.B \-F +is more reliable if the archive is not too much damaged, so try this +option first. +.IP +If the archive is too damaged or the end has been truncated, you +must use \fB\-FF\fP. This is a change from \fIzip\ 2.32\fP, where +the \fB\-F\fP option is able to read a truncated archive. The +\fB\-F\fP option now more reliably fixes archives with minor +damage and the \fB\-FF\fP option is needed to fix archives where +\fB\-F\fP might have been sufficient before. +.IP +Neither option will recover archives that have been incorrectly +transferred in ascii mode instead of binary. After the repair, the +.B \-t +option of +.I unzip +may show that some files have a bad CRC. Such files cannot be recovered; +you can remove them from the archive using the +.B \-d +option of +\fIzip\fP. +.IP +Note that \fB\-FF\fP may have trouble fixing archives that include an +embedded zip archive that was stored (without compression) in the archive +and, depending on the damage, it may find the entries in the embedded +archive rather than the archive itself. Try \fB\-F\fP first as it +does not have this problem. +.IP +The format of the fix commands have changed. For example, to fix +the damaged archive \fIfoo.zip\fP, +.RS +.IP +\fCzip -F foo --out foofix +.RE +.IP +tries to read the entries normally, copying good entries to the +new archive \fIfoofix.zip\fP. If this doesn't work, as when the +archive is truncated, or if some entries you know are in the archive +are missed, then try +.RS +.IP +\fCzip -FF foo --out foofixfix +.RE +.IP +and compare the resulting archive to the archive created by \fB\-F\fP. The +\fB\-FF\fP option may create an inconsistent archive. Depending on +what is damaged, you can then use the \fB\-F\fP option to fix that archive. +.IP +A split archive with missing split files can be fixed using +\fB\-F\fP if you have the last split of the archive (the \fB\.zip\fP file). +If this file is missing, you must use \fB\-FF\fP to fix the archive, +which will prompt you for the splits you have. +.IP +Currently the fix options can't recover entries that have a bad checksum +or are otherwise damaged. + +.TP +.PD 0 +.B \-FI +.TP +.PD +.B \-\-fifo +[Unix] Normally \fIzip\fP skips reading any FIFOs (named pipes) encountered, as +\fIzip\fP can hang if the FIFO is not being fed. This option tells \fIzip\fP to +read the contents of any FIFO it finds. + +.TP +.PD 0 +.B \-FS +.TP +.PD +.B \-\-filesync +Synchronize the contents of an archive with the files on the OS. +Normally when an archive is updated, new files are added and changed +files are updated but files that no longer exist on the OS are not +deleted from the archive. This option enables a new mode that checks +entries in the archive against the file system. If the file time and +file size of the entry matches that of the OS file, the entry is +copied from the old archive instead of being read from the file system +and compressed. If the OS file has changed, the entry is read and +compressed as usual. If the entry in the archive does not match a +file on the OS, the entry is deleted. Enabling this option should +create archives that are the same as new archives, but since existing +entries are copied instead of compressed, updating an existing archive +with \fB\-FS\fP can be much faster than creating a new archive. Also +consider using \fB\-u\fP for updating an archive. +.IP +For this option to work, the archive should be updated from the same +directory it was created in so the relative paths match. If few files +are being copied from the old archive, it may be faster to create a +new archive instead. +.IP +Note that the timezone environment variable TZ should be set according to +the local timezone in order for this option to work correctly. A +change in timezone since the original archive was created could +result in no times matching and recompression of all files. +.IP +This option deletes files from the archive. If you need to preserve +the original archive, make a copy of the archive first or use the +\fB\-\-out\fP option to output the updated archive to a new file. +Even though it may be slower, creating a new archive with a new archive +name is safer, avoids mismatches between archive and OS paths, and +is preferred. + +.TP +.PD 0 +.B \-g +.TP +.PD +.B \-\-grow \ \ \ \ \ \ +Grow (append to) the specified +.I zip +archive, instead of creating a new one. If this operation fails, +.I zip +attempts to restore the archive to its original state. If the restoration +fails, the archive might become corrupted. This option is ignored when +there's no existing archive or when at least one archive member must be +updated or deleted. + +.TP +.PD 0 +.B \-h +.TP +.PD 0 +.B \-? +.TP +.PD +.B \-\-help \ \ \ \ \ \ +Display the +.I zip +help information (this also appears if +.I zip +is run with no arguments). + +.TP +.PD 0 +.B \-h2 +.TP +.PD +.B \-\-more-help +Display extended help including more on command line format, pattern matching, and +more obscure options. + +.TP +.PD 0 +.B \-i\ \fRfiles +.TP +.PD +.B \-\-include\ \fRfiles +Include only the specified files, as in: +.RS +.IP +\fCzip -r foo . -i \\*.c\fP +.RE +.IP +which will include only the files that end in +.IR \& .c +in the current directory and its subdirectories. (Note for PKZIP +users: the equivalent command is +.RS +.IP +\fCpkzip -rP foo *.c\fP +.RE +.IP +PKZIP does not allow recursion in directories other than the current one.) +The backslash avoids the shell filename substitution, so that the +name matching is performed by +.I zip +at all directory levels. +[This is for Unix and other systems where \\ escapes the +next character. For other systems where the shell does not +process * do not use \\ and the above is +.RS +.IP +\fCzip -r foo . -i *.c\fP +.RE +.IP +Examples are for Unix unless otherwise specified.] So to include dir, +a directory directly under the current directory, use +.RS +.IP +\fCzip -r foo . -i dir/\\* +.RE +.IP +or +.RS +.IP +\fCzip -r foo . -i "dir/*" +.RE +.IP +to match paths such as dir/a and dir/b/file.c [on +ports without wildcard expansion in the shell such as MSDOS and Windows +.RS +.IP +\fCzip -r foo . -i dir/* +.RE +.IP +is used.] Note that currently the trailing / is needed +for directories (as in +.RS +.IP +\fCzip -r foo . -i dir/ +.RE +.IP +to include directory dir). +.IP +The long option form of the first example is +.RS +.IP +\fCzip -r foo . --include \\*.c +.RE +.IP +and does the same thing as the short option form. +.IP +Though the command syntax used to require \fB-i\fR at +the end of the command line, this version actually +allows \fB\-i\fP (or \fB\-\-include\fP) anywhere. The +list of files terminates at the next argument starting +with \fB-\fR, the end of the command line, or the list +terminator \fB@\fR (an argument that is just @). So +the above can be given as +.RS +.IP +zip -i \\*.c @ -r foo .\fP +.RE +.IP +for example. There must be a space between +the option and the first file of a list. For just +one file you can use the single value form +.RS +.IP +\fCzip -i\\*.c -r foo .\fP +.RE +.IP +(no space between option and value) or +.RS +.IP +\fCzip --include=\\*.c -r foo .\fP +.RE +.IP +as additional examples. The single value forms are +not recommended because they can be confusing and, +in particular, the \fB\-ifile\fP format can cause +problems if the first letter of \fBfile\fP combines with +\fBi\fP to form a two-letter option starting with +\fBi\fP. Use \fB\-sc\fP to see how your command line +will be parsed. +.IP +Also possible: +.RS +.IP +\fCzip -r foo . -i@include.lst\fP +.RE +.IP +which will only include the files in the current directory and its +subdirectories that match the patterns in the file include.lst. +.IP +Files to \fB\-i\fR and \fB\-x\fR are patterns matching internal archive paths. See +\fB-R\fR for more on patterns. + +.TP +.PD 0 +.B \-I +.TP +.PD +.B \-\-no-image +[Acorn RISC OS] Don't scan through Image files. When used, \fIzip\fP will not +consider Image files (eg. DOS partitions or Spark archives when SparkFS +is loaded) as directories but will store them as single files. + +For example, if you have SparkFS loaded, zipping a Spark archive will result +in a zipfile containing a directory (and its content) while using the 'I' +option will result in a zipfile containing a Spark archive. Obviously this +second case will also be obtained (without the 'I' option) if SparkFS isn't +loaded. + +.TP +.PD 0 +.B \-ic +.TP +.PD +.B \-\-ignore-case +[VMS, WIN32] Ignore case when matching archive entries. This option is +only available on systems where the case of files is ignored. On systems +with case-insensitive file systems, case is normally ignored when matching files +on the file system but is not ignored for -f (freshen), -d (delete), -U (copy), +and similar modes when matching against archive entries (currently -f +ignores case on VMS) because archive entries can be from systems where +case does matter and names that are the same except for case can exist +in an archive. The \fB\-ic\fR option makes all matching case insensitive. +This can result in multiple archive entries matching a command line pattern. + +.TP +.PD 0 +.B \-j +.TP +.PD +.B \-\-junk-paths +Store just the name of a saved file (junk the path), and do not store +directory names. By default, +.I zip +will store the full path (relative to the current directory). + +.TP +.PD 0 +.B \-jj +.TP +.PD +.B \-\-absolute-path +[MacOS] record Fullpath (+ Volname). The complete path including +volume will be stored. By default the relative path will be stored. + +.TP +.PD 0 +.B \-J +.TP +.PD +.B \-\-junk-sfx +Strip any prepended data (e.g. a SFX stub) from the archive. +.TP +.PD 0 +.B \-k +.TP +.PD +.B \-\-DOS-names +Attempt to convert the names and paths to conform to MSDOS, +store only the MSDOS attribute (just the user write attribute from Unix), +and mark the entry as made under MSDOS (even though it was not); +for compatibility with PKUNZIP under MSDOS which cannot handle certain +names such as those with two dots. +.TP +.PD 0 +.B \-l +.TP +.PD +.B \-\-to-crlf +Translate the Unix end-of-line character LF into the +MSDOS convention CR LF. This option should not be used on binary files. +This option can be used on Unix if the zip file is intended for PKUNZIP +under MSDOS. If the input files already contain CR LF, this option adds +an extra CR. This is to ensure that +\fBunzip -a\fP +on Unix will get back an exact copy of the original file, +to undo the effect of +\fBzip -l\fP. See \fB-ll\fR for how binary files are handled. +.TP +.PD 0 +.B \-la +.TP +.PD +.B \-\-log-append +Append to existing logfile. Default is to overwrite. +.TP +.PD 0 +.B \-lf\ \fPlogfilepath +.TP +.PD +.B \-\-logfile-path\ \fPlogfilepath +Open a logfile at the given path. By default any existing file at that location +is overwritten, but the \fB\-la\fP option will result in an existing file being +opened and the new log information appended to any existing information. +Only warnings and errors are written to the log unless the \fB\-li\fP option is +also given, then all information messages are also written to the log. +.TP +.PD 0 +.B \-li +.TP +.PD +.B \-\-log-info +Include information messages, such as file names being zipped, in the log. +The default is to only include the command line, any warnings and errors, and +the final status. +.TP +.PD 0 +.B \-ll +.TP +.PD +.B \-\-from-crlf +Translate the MSDOS end-of-line CR LF into Unix LF. +This option should not be used on binary files. +This option can be used on MSDOS if the zip file is intended for unzip +under Unix. If the file is converted and the file is later determined +to be binary a warning is issued and the file is probably +corrupted. In this release if \fB-ll\fR detects binary in the first buffer +read from a file, \fIzip\fR now issues a warning and skips line end +conversion on the file. This check seems to catch all binary files +tested, but the original check remains and if a converted file is +later determined to be binary that warning is still issued. A new algorithm +is now being used for binary detection that should allow line end conversion +of text files in \fBUTF-8\fR and similar encodings. +.TP +.PD 0 +.B \-L +.TP +.PD +.B \-\-license +Display the +.I zip +license. +.TP +.PD 0 +.B \-m +.TP +.PD +.B \-\-move \ \ \ +Move the specified files into the +.I zip +archive; actually, +this deletes the target directories/files after making the specified +.I zip +archive. If a directory becomes empty after removal of the files, the +directory is also removed. No deletions are done until +.I zip +has created the archive without error. +This is useful for conserving disk space, +but is potentially dangerous so it is recommended to use it in +combination with +.B \-T +to test the archive before removing all input files. +.TP +.PD 0 +.B \-MM +.TP +.PD +.B \-\-must-match +All input patterns must match at least one file and all input files +found must be readable. Normally when an input pattern does not match +a file the "name not matched" warning is issued and when an input file +has been found but later is missing or not readable a missing or not +readable warning is issued. In either case +.I zip +continues creating the archive, with missing or unreadable new files +being skipped and files already in the archive remaining unchanged. +After the archive is created, if any files were not readable +.I zip +returns the OPEN error code (18 on most systems) instead of the normal +success return (0 on most systems). With \fB\-MM\fP set, +.I zip +exits as soon as an input pattern is not matched (whenever the +"name not matched" warning would be issued) or when an input file is +not readable. In either case \fIzip\fR exits with an OPEN error +and no archive is created. +.IP +This option is useful when a known list of files is to be zipped so +any missing or unreadable files will result in an error. It is less +useful when used with wildcards, but \fIzip\fR will still exit with an +error if any input pattern doesn't match at least one file and if any +matched files are unreadable. If you want to create the archive +anyway and only need to know if files were skipped, don't use +.B \-MM +and just check the return code. Also \fB\-lf\fP could be useful. +.TP +.PD 0 +.BI \-n\ \fRsuffixes +.TP +.PD +.B \-\-suffixes\ \fRsuffixes +Do not attempt to compress files named with the given +\fBsuffixes\fR. +Such files are simply stored (0% compression) in the output zip file, +so that +.I zip +doesn't waste its time trying to compress them. +The suffixes are separated by +either colons or semicolons. For example: +.RS +.IP +\fCzip -rn .Z:.zip:.tiff:.gif:.snd foo foo\fP +.RE +.IP +will copy everything from +.I foo +into +.IR foo.zip , +but will store any files that end in +.IR .Z , +.IR .zip , +.IR .tiff , +.IR .gif , +or +.I .snd +without trying to compress them +(image and sound files often have their own specialized compression methods). +By default, +.I zip +does not compress files with extensions in the list +.I .Z:.zip:.zoo:.arc:.lzh:.arj. +Such files are stored directly in the output archive. +The environment variable ZIPOPT can be used to change the default options. For +example under Unix with csh: +.RS +.IP +setenv ZIPOPT "-n .gif:.zip" +.RE +.IP +To attempt compression on all files, use: +.RS +.IP +zip -n : foo +.RE +.IP +The maximum compression option +.B \-9 +also attempts compression on all files regardless of extension. +.IP +On Acorn RISC OS systems the suffixes are actually filetypes (3 hex digit +format). By default, \fIzip\fP does not compress files with filetypes in the list +DDC:D96:68E (i.e. Archives, CFS files and PackDir files). +.TP +.PD 0 +.B \-nw +.TP +.PD +.B \-\-no-wild +Do not perform internal wildcard processing (shell processing of wildcards is still done +by the shell unless the arguments are escaped). Useful if a list of paths is being +read and no wildcard substitution is desired. +.TP +.PD 0 +.B \-N +.TP +.PD +.B \-\-notes +[Amiga, MacOS] Save Amiga or MacOS filenotes as zipfile comments. They can be +restored by using the -N option of \fIunzip\fP. If -c is used also, you are +prompted for comments only for those files that do not have filenotes. +.TP +.PD 0 +.B \-o +.TP +.PD +.B \-\-latest-time +Set the "last modified" time of the +.I zip +archive to the latest (oldest) "last modified" time +found among the entries in the +.I zip +archive. +This can be used without any other operations, if desired. +For example: +.IP +\fCzip -o foo\fP +.IP +will change the last modified time of +\fBfoo.zip\fP +to the latest time of the entries in +.BR foo.zip . +.TP +.PD 0 +.B \-O \fPoutput-file +.TP +.PD +.B \-\-output-file \fPoutput-file +Process the archive changes as usual, but instead of updating the existing archive, +output the new archive to output-file. Useful for updating an archive +without changing the existing archive and the input archive must be a different file +than the output archive. + +This option can be used to create updated split archives. +It can also be used with \fB\-U\fP to copy entries from an existing archive to a new +archive. See the \fBEXAMPLES\fP section below. + +Another use is converting \fIzip\fP files from one split size to another. For instance, +to convert an archive with 700 MB CD splits to one with 2 GB DVD splits, can use: +.RS +.IP +zip -s 2g cd-split.zip --out dvd-split.zip +.RE +.IP +which uses copy mode. See \fB\-U\fP below. Also: +.RS +.IP +zip -s 0 split.zip --out unsplit.zip +.RE +.IP +will convert a split archive to a single-file archive. + +Copy mode will convert stream entries (using data descriptors and which +should be compatible with most unzips) to normal entries (which should +be compatible +with all unzips), except if standard encryption was used. For archives +with encrypted entries, \fIzipcloak\fP will decrypt the entries and convert +them to normal entries. +.TP +.PD 0 +.B \-p +.TP +.PD +.B \-\-paths +Include relative file paths as part of the names of files stored in the archive. +This is the default. The \fB\-j\fP option junks the paths and just stores the +names of the files. +.TP +.PD 0 +.B \-P\ \fRpassword +.TP +.PD +.B \-\-password\ \fRpassword +Use \fIpassword\fP to encrypt zipfile entries (if any). \fBTHIS IS +INSECURE!\fP Many multi-user operating systems provide ways for any user to +see the current command line of any other user; even on stand-alone systems +there is always the threat of over-the-shoulder peeking. Storing the plaintext +password as part of a command line in an automated script is even worse. +Whenever possible, use the non-echoing, interactive prompt to enter passwords. +(And where security is truly important, use strong encryption such as Pretty +Good Privacy instead of the relatively weak standard encryption provided by +zipfile utilities.) +.TP +.PD 0 +.B \-q +.TP +.PD +.B \-\-quiet +Quiet mode; +eliminate informational messages and comment prompts. +(Useful, for example, in shell scripts and background tasks). +.TP +.PD 0 +.BI \-Q\fRn +.TP +.PD +.B \-\-Q\-flag\ \fRn +[QDOS] store information about the file in the file header with n defined as +.RS +bit 0: Don't add headers for any file +.RE +.RS +bit 1: Add headers for all files +.RE +.RS +bit 2: Don't wait for interactive key press on exit +.RE +.TP +.PD 0 +.B \-r +.TP +.PD +.B \-\-recurse\-paths +Travel the directory structure recursively; +for example: +.RS +.IP +zip -r foo.zip foo +.RE +.IP +or more concisely +.RS +.IP +zip -r foo foo +.RE +.IP +In this case, all the files and directories in +.B foo +are saved in a +.I zip +archive named \fBfoo.zip\fP, +including files with names starting with \fB"."\fP, +since the recursion does not use the shell's file-name substitution mechanism. +If you wish to include only a specific subset of the files in directory +\fBfoo\fP +and its subdirectories, use the +\fB\-i\fP +option to specify the pattern of files to be included. +You should not use +\fB\-r\fP +with the name \fB".*"\fP, +since that matches \fB".."\fP +which will attempt to zip up the parent directory +(probably not what was intended). +.IP +Multiple source directories are allowed as in +.RS +.IP +\fCzip -r foo foo1 foo2\fP +.RE +.IP +which first zips up \fBfoo1\fP and then \fBfoo2\fP, going down each directory. +.IP +Note that while wildcards to \fB-r\fR are typically resolved while recursing down +directories in the file system, any \fB-R\fN, \fB-x\fR, and \fB-i\fR wildcards +are applied to internal archive pathnames once the directories are scanned. +To have wildcards apply to files in subdirectories when recursing on +Unix and similar systems where the shell does wildcard substitution, either +escape all wildcards or put all arguments with wildcards in quotes. This lets +\fIzip\fR see the wildcards and match files in subdirectories using them as +it recurses. +.TP +.PD 0 +.B \-R +.TP +.PD +.B \-\-recurse\-patterns +Travel the directory structure recursively starting at the +current directory; +for example: +.RS +.IP +\fCzip -R foo "*.c"\fP +.RE +.IP +In this case, all the files matching \fB*.c\fP in the tree starting at the +current directory are stored into a +.I zip +archive named +\fBfoo.zip\fP. +Note that \fB*.c\fP will match \fBfile.c\fP, \fBa/file.c\fP +and \fBa/b/.c\fP. More than one pattern can be listed as separate +arguments. +Note for PKZIP users: the equivalent command is +.RS +.IP +\fCpkzip -rP foo *.c\fP +.RE +.IP +Patterns are relative file paths as they appear in the archive, or will after +zipping, and can have optional wildcards in them. For example, given +the current directory is \fBfoo\fP and under it are directories \fBfoo1\fP and \fBfoo2\fP +and in \fBfoo1\fP is the file \fBbar.c\fP, +.RS +.IP +\fCzip -R foo/*\fP +.RE +.IP +will zip up \fBfoo\fP, \fBfoo/foo1\fP, \fBfoo/foo1/bar.c\fP, and \fBfoo/foo2\fP. +.RS +.IP +\fCzip -R */bar.c\fP +.RE +.IP +will zip up \fBfoo/foo1/bar.c\fP. See the note for \fB-r\fR on escaping wildcards. + +.TP +.PD 0 +.B \-RE +.TP +.PD +.B \-\-regex +[WIN32] Before \fIzip\fP \fI3.0\fP, regular expression list matching was +enabled by default on Windows platforms. Because of confusion resulting +from the need to escape "[" and "]" in names, it is now off by default for +Windows so "[" and "]" are just normal characters in names. This option +enables [] matching again. + +.TP +.PD 0 +.B \-s\ \fPsplitsize +.TP +.PD +.B \-\-split\-size\ \fPsplitsize +Enable creating a split archive and set the split size. A split archive is an archive +that could be split over many files. As the archive is created, if the size of the +archive reaches the specified split size, that split is closed and the next split +opened. In general all splits but the last will be the split size and the last +will be whatever is left. If the entire archive is smaller than the split size a +single-file archive is created. + +Split archives are stored in numbered files. For example, if the output +archive is named \fBarchive\fP and three splits are required, the resulting +archive will be in the three files \fBarchive.z01\fP, \fBarchive.z02\fP, and +\fBarchive.zip\fP. Do not change the numbering of these files or the archive +will not be readable as these are used to determine the order the splits are read. + +Split size is a number optionally followed by a multiplier. Currently the +number must be an integer. The multiplier can currently be one of +\fBk\fP (kilobytes), \fBm\fP (megabytes), \fBg\fP (gigabytes), or \fBt\fP +(terabytes). As 64k is the minimum split size, numbers without multipliers +default to megabytes. For example, to create a split archive called \fBfoo\fP +with the contents of the \fBbar\fP directory with splits of 670 MB that might +be useful for burning on CDs, the command: +.RS +.IP +zip -s 670m -r foo bar +.RE +.IP +could be used. + +Currently the old splits of a split archive are not excluded from a new +archive, but they can be specifically excluded. If possible, keep +the input and output archives out of the path being zipped when creating +split archives. + +Using \fB\-s\fP without \fB\-sp\fP as above creates all the splits where +\fBfoo\fP is being written, in this case the current directory. This split +mode updates the splits as the archive is being created, requiring all +splits to remain writable, but creates split archives that are readable by +any unzip that supports split archives. See \fB\-sp\fP below for enabling +split pause mode which allows splits to be written directly to removable +media. + +The option \fB\-sv\fP can be used to enable verbose splitting and provide details of +how the splitting is being done. The \fB\-sb\fP option can be used to ring the bell +when \fIzip\fP pauses for the next split destination. + +Split archives cannot be updated, but see the \fB\-O\fP (\fB\-\-out\fP) option for +how a split archive can be updated as it is copied to a new archive. +A split archive can also be converted into a single-file archive using a +split size of 0 or negating the \fB\-s\fP option: +.RS +.IP +zip -s 0 split.zip --out single.zip +.RE +.IP +Also see \fB\-U\fP (\fB\-\-copy\fP) for more on using copy mode. +.TP +.PD 0 +.B \-sb +.TP +.PD +.B \-\-split\-bell +If splitting and using split pause mode, ring the bell when \fIzip\fP pauses +for each split destination. +.TP +.PD 0 +.B \-sc +.TP +.PD +.B \-\-show\-command +Show the command line starting \fIzip\fP as processed and exit. The new command parser +permutes the arguments, putting all options and any values associated with them +before any non-option arguments. This allows an option to appear anywhere in the +command line as long as any values that go with the option go with it. This option +displays the command line as \fIzip\fP sees it, including any arguments from +the environment such as from the \fBZIPOPT\fP variable. Where allowed, options later +in the command line can override options earlier in the command line. +.TP +.PD 0 +.B \-sf +.TP +.PD +.B \-\-show\-files +Show the files that would be operated on, then exit. For instance, if creating +a new archive, this will list the files that would be added. If the option is +negated, \fB\-sf\-\fP, output only to an open log file. Screen display is +not recommended for large lists. +.TP +.PD 0 +.B \-so +.TP +.PD +.B \-\-show\-options +Show all available options supported by \fIzip\fP as compiled on the current system. +As this command reads the option table, it should include all options. Each line +includes the short option (if defined), the long option (if defined), the format +of any value that goes with the option, if the option can be negated, and a +small description. The value format can be no value, required value, optional +value, single character value, number value, or a list of values. The output of +this option is not intended to show how to use any option but only +show what options are available. +.TP +.PD 0 +.B \-sp +.TP +.PD +.B \-\-split\-pause +If splitting is enabled with \fB\-s\fP, enable split pause mode. This +creates split archives as \fB\-s\fP does, but stream writing is used so each +split can be closed as soon as it is written and \fIzip\fP will pause between each +split to allow changing split destination or media. + +Though this split mode allows writing splits directly to removable media, it +uses stream archive format that may not be readable by some unzips. Before +relying on splits created with \fB\-sp\fP, test a split archive with the unzip +you will be using. + +To convert a stream split archive (created with \fB\-sp\fP) to a standard archive +see the \fB\-\-out\fP option. +.TP +.PD 0 +.B \-su +.TP +.PD +.B \-\-show\-unicode +As \fB\-sf\fP, but also show Unicode version of the path if exists. +.TP +.PD 0 +.B \-sU +.TP +.PD +.B \-\-show\-just\-unicode +As \fB\-sf\fP, but only show Unicode version of the path if exists, otherwise show +the standard version of the path. +.TP +.PD 0 +.B \-sv +.TP +.PD +.B \-\-split\-verbose +Enable various verbose messages while splitting, showing how the splitting is being +done. +.TP +.PD 0 +.B \-S +.TP +.PD +.B \-\-system-hidden +[MSDOS, OS/2, WIN32 and ATARI] Include system and hidden files. +.RS +[MacOS] Includes finder invisible files, which are ignored otherwise. +.RE +.TP +.PD 0 +.BI \-t\ \fRmmddyyyy +.TP +.PD +.B \-\-from\-date\ \fRmmddyyyy +Do not operate on files modified prior to the specified date, +where +.B mm +is the month (00-12), +.B dd +is the day of the month (01-31), +and +.B yyyy +is the year. +The +.I ISO\ 8601 +date format +.B yyyy\-mm\-dd +is also accepted. +For example: +.RS +.IP +\fCzip -rt 12071991 infamy foo\fP + +\fCzip -rt 1991-12-07 infamy foo\fP +.RE +.IP +will add all the files in +.B foo +and its subdirectories that were last modified on or after 7 December 1991, +to the +.I zip +archive +.BR infamy.zip . +.TP +.PD 0 +.BI \-tt\ \fRmmddyyyy +.TP +.PD +.B \-\-before\-date\ \fRmmddyyyy +Do not operate on files modified after or at the specified date, +where +.B mm +is the month (00-12), +.B dd +is the day of the month (01-31), +and +.B yyyy +is the year. +The +.I ISO\ 8601 +date format +.B yyyy\-mm\-dd +is also accepted. +For example: +.RS +.IP +\fCzip -rtt 11301995 infamy foo\fP + +\fCzip -rtt 1995-11-30 infamy foo\fP +.RE +.IP +will add all the files in +.B foo +and its subdirectories that were last modified before 30 November 1995, +to the +.I zip +archive +.BR infamy.zip . +.TP +.PD 0 +.B \-T +.TP +.PD +.B \-\-test\ \ \ \ +Test the integrity of the new zip file. If the check fails, the old zip file +is unchanged and (with the +.B -m +option) no input files are removed. +.TP +.PD 0 +.B \-TT\ \fPcmd +.TP +.PD +.B \-\-unzip-command\ \fPcmd +Use command cmd instead of 'unzip -tqq' to test an archive when the \fB\-T\fP +option is used. On Unix, to use a copy of unzip in the current directory instead +of the standard system unzip, could use: +.IP +\fC zip archive file1 file2 -T -TT "./unzip -tqq"\fP +.IP +In cmd, {} is replaced by the name of the temporary archive, otherwise the name +of the archive is appended to the end of the command. +The return code is checked for success (0 on Unix). +.TP +.PD 0 +.B \-u +.TP +.PD +.B \-\-update +Replace (update) an existing entry in the +.I zip +archive only if it has been modified more recently +than the version already in the +.I zip +archive. +For example: +.RS +.IP +\fCzip -u stuff *\fP +.RE +.IP +will add any new files in the current directory, +and update any files which have been modified since the +.I zip +archive +.I stuff.zip +was last created/modified (note that +.I zip +will not try to pack +.I stuff.zip +into itself when you do this). +.IP +Note that the +.B \-u +option with no input file arguments acts like the +.B \-f +(freshen) option. +.TP +.PD 0 +.B \-U +.TP +.PD +.B \-\-copy\-entries +Copy entries from one archive to another. Requires the \fB\-\-out\fP +option to specify a different output file than the input archive. Copy +mode is the reverse of \fB\-d\fP delete. When delete is being used +with \fB\-\-out\fP, the selected entries are deleted from the archive +and all other entries are copied to the new archive, while copy mode +selects the files to include in the new archive. Unlike \fB\-u\fP +update, input patterns on the command line are matched against archive +entries only and not the file system files. For instance, +.RS +.IP +\fCzip inarchive "*.c" --copy --out outarchive\fP +.RE +.IP +copies entries with names ending in \fB\.c\fP from \fBinarchive\fP +to \fBoutarchive\fP. The wildcard must be escaped on some systems +to prevent the shell from substituting names of files from the +file system which may have no relevance to the entries in the archive. + +If no input files appear on the command line and \fB\-\-out\fP is +used, copy mode is assumed: +.RS +.IP +\fCzip inarchive --out outarchive\fP +.RE +.IP +This is useful for changing split size for instance. Encrypting +and decrypting entries is not yet supported using copy mode. Use +\fIzipcloak\fP for that. +.TP +.PD 0 +.B \-UN\ \fRv +.TP +.PD +.B \-\-unicode\ \fRv +Determine what \fIzip\fP should do with Unicode file names. +\fIzip\ 3.0\fP, in addition to the standard file path, now +includes the UTF\-8 translation of the path if the entry path +is not entirely 7-bit ASCII. When an entry +is missing the Unicode path, \fIzip\fP reverts back to the +standard file path. The problem with using the standard path +is this path is in the local character set of the zip that created +the entry, which may contain characters that are not valid in +the character set being used by the unzip. When \fIzip\fP is +reading an archive, if an entry also has a Unicode path, +\fIzip\fP now defaults to using the Unicode path to recreate +the standard path using the current local character set. + +This option can be used to determine what \fIzip\fP should do +with this path if there is a mismatch between the stored standard path +and the stored UTF-8 path (which can happen if the standard path was +updated). In all cases, if there is a mismatch it is +assumed that the standard path is more current and +\fIzip\fP uses that. Values for \fBv\fP are +.RS +.IP +q \- quit if paths do not match +.IP +w \- warn, continue with standard path +.IP +i \- ignore, continue with standard path +.IP +n \- no Unicode, do not use Unicode paths +.RE +.IP +The default is to warn and continue. + +Characters that are not valid in the current character set are +escaped as \fB#Uxxxx\fP and \fB#Lxxxxxx\fP, where x is an +ASCII character for a hex digit. The first is used if a 16-bit +character number is sufficient to represent the Unicode character +and the second if the character needs more than 16 bits to +represent it's Unicode character code. Setting \fB\-UN\fP to +.RS +.IP +e \- escape +.RE +.IP +as in +.RS +.IP +\fCzip archive -sU -UN=e\fP +.RE +.IP +forces \fIzip\fP to escape all characters that are not printable 7-bit +ASCII. + +Normally \fIzip\fP stores UTF\-8 directly in the standard path field +on systems where UTF\-8 is the current character set and stores the +UTF\-8 in the new extra fields otherwise. The option +.RS +.IP +u \- UTF\-8 +.RE +.IP +as in +.RS +.IP +\fCzip archive dir -r -UN=UTF8\fP +.RE +.IP +forces \fIzip\fP to store UTF\-8 as native in the archive. Note that +storing UTF\-8 directly is the default on Unix systems that support it. +This option could be useful on Windows systems where the escaped +path is too large to be a valid path and the UTF\-8 version of the +path is smaller, but native UTF\-8 is not backward compatible on +Windows systems. + +.TP +.PD 0 +.B \-v +.TP +.PD +.B \-\-verbose +Verbose mode or print diagnostic version info. +.IP +Normally, when applied to real operations, this option enables the display of a +progress indicator during compression (see \fB-dd\fR for more on dots) and +requests verbose diagnostic info about zipfile structure oddities. +.IP +However, when +.B \-v +is the only command line argument a diagnostic screen is printed instead. This +should now work even if stdout is redirected to a file, allowing easy saving +of the information for sending with bug reports to Info-ZIP. The version +screen provides the help screen header with program name, version, and release +date, some pointers to the Info-ZIP home and distribution sites, and shows +information about the target environment (compiler type and version, OS +version, compilation date and the enabled optional features used to create the +.I zip +executable). +.TP +.PD 0 +.B \-V +.TP +.PD +.B \-\-VMS\-portable +[VMS] Save VMS file attributes. +(Files are truncated at EOF.) When a -V archive is unpacked on a +non-VMS system, some file types (notably Stream_LF +text files and pure binary files like fixed-512) +should be extracted intact. Indexed files and file +types with embedded record sizes (notably variable-length record types) +will probably be seen as corrupt elsewhere. +.TP +.PD 0 +.B \-VV +.TP +.PD +.B \-\-VMS\-specific +[VMS] Save VMS file attributes, and all allocated +blocks in a file, including any data beyond EOF. +Useful for moving ill-formed files among VMS systems. When a -VV archive is +unpacked on a non-VMS system, almost all files will appear corrupt. +.TP +.PD 0 +.B \-w +.TP +.PD +.B \-\-VMS\-versions +[VMS] Append the version number of the files to the name, +including multiple versions of files. Default is to use only +the most recent version of a specified file. +.TP +.PD 0 +.B \-ww +.TP +.PD +.B \-\-VMS\-dot\-versions +[VMS] Append the version number of the files to the name, +including multiple versions of files, using the \.nnn format. +Default is to use only the most recent version of a specified +file. +.TP +.PD 0 +.BI \-ws +.TP +.PD +.B \-\-wild\-stop\-dirs +Wildcards match only at a directory level. Normally \fIzip\fP handles +paths as strings and given the paths +.RS +.IP +/foo/bar/dir/file1.c +.IP +/foo/bar/file2.c +.RE +.IP +an input pattern such as +.RS +.IP +/foo/bar/* +.RE +.IP +normally would match both paths, the * matching \fBdir/file1.c\fP +and \fBfile2.c\fP. Note that in the first case a directory +boundary (/) was crossed in the match. With \fB\-ws\fP no +directory bounds will be included in the match, making +wildcards local to a specific directory level. So, with +\fB\-ws\fP enabled, only the second path would be matched. + +When using \fB\-ws\fP, use ** to match across directory boundaries as +* does normally. +.TP +.PD 0 +.BI \-x\ \fRfiles +.TP +.PD +.B \-\-exclude\ \fRfiles +Explicitly exclude the specified files, as in: +.RS +.IP +\fCzip -r foo foo -x \\*.o\fP +.RE +.IP +which will include the contents of +.B foo +in +.B foo.zip +while excluding all the files that end in +\fB.o\fP. +The backslash avoids the shell filename substitution, so that the +name matching is performed by +.I zip +at all directory levels. +.IP +Also possible: +.RS +.IP +\fCzip -r foo foo -x@exclude.lst\fP +.RE +.IP +which will include the contents of +.B foo +in +.B foo.zip +while excluding all the files that match the patterns in the file +\fBexclude.lst\fP. +.IP +The long option forms of the above are +.RS +.IP +\fCzip -r foo foo --exclude \\*.o\fP +.RE +.IP +and +.RS +.IP +\fCzip -r foo foo --exclude @exclude.lst\fP +.RE +.IP +Multiple patterns can be specified, as in: +.RS +.IP +\fCzip -r foo foo -x \\*.o \\*.c\fP +.RE +.IP +If there is no space between \fB\-x\fP and +the pattern, just one value is assumed (no list): +.RS +.IP +\fCzip -r foo foo -x\\*.o\fP +.RE +.IP +.IP +See \fB-i\fR for more on include and exclude. +.TP +.PD 0 +.B \-X +.TP +.PD +.B \-\-no\-extra +Do not save extra file attributes (Extended Attributes on OS/2, uid/gid +and file times on Unix). The zip format uses extra fields to include +additional information for each entry. Some extra fields are specific +to particular systems while others are applicable to all systems. +Normally when \fIzip\fP reads entries from an existing archive, it +reads the extra fields it knows, strips the rest, and adds +the extra fields applicable to that system. With \fB\-X\fP, \fIzip\fP strips +all old fields and only includes the Unicode and Zip64 extra fields +(currently these two extra fields cannot be disabled). + +Negating this option, \fB\-X\-\fP, includes all the default extra fields, +but also copies over any unrecognized extra fields. +.TP +.PD 0 +.B \-y +.TP +.PD +.B \-\-symlinks +For UNIX and VMS (V8.3 and later), store symbolic links as such in the +.I zip +archive, instead of compressing and storing the file referred to by +the link. This can avoid multiple copies of files being included in +the archive as \fIzip\fP recurses the directory trees and accesses +files directly and by links. +.TP +.PD 0 +.B \-z +.TP +.PD +.B \-\-archive\-comment +Prompt for a multi-line comment for the entire +.I zip +archive. +The comment is ended by a line containing just a period, +or an end of file condition (^D on Unix, ^Z on MSDOS, OS/2, and VMS). +The comment can be taken from a file: +.RS +.IP +\fCzip -z foo < foowhat\fP +.RE +.TP +.PD 0 +.B \-Z\ \fRcm +.TP +.PD +.B \-\-compression\-method\ \fRcm +Set the default compression method. Currently the main methods supported +by \fIzip\fP are \fBstore\fP and \fBdeflate\fP. Compression method +can be set to: + +\fBstore\fP \- Setting the compression method to \fBstore\fP forces +\fIzip\fP to store entries with no compression. This is generally +faster than compressing entries, but results in no space savings. +This is the same as using \fB\-0\fP (compression level zero). + +\fBdeflate\fP \- This is the default method for \fIzip\fP. If \fIzip\fP +determines that storing is better than deflation, the entry will be +stored instead. + +\fBbzip2\fP \- If \fBbzip2\fP support is compiled in, this compression +method also becomes available. Only some modern unzips currently support +the \fBbzip2\fP compression method, so test the unzip you will be using +before relying on archives using this method (compression method 12). + +For example, to add \fBbar.c\fP to archive \fBfoo\fP using \fBbzip2\fP +compression: +.RS +.IP +zip -Z bzip2 foo bar.c +.RE +.IP +The compression method can be abbreviated: +.RS +.IP +zip -Zb foo bar.c +.RE +.IP +.TP +.PD 0 +.BI \-# +.TP +.PD +.B (\-0, \-1, \-2, \-3, \-4, \-5, \-6, \-7, \-8, \-9) +Regulate the speed of compression using the specified digit +.BR # , +where +.B \-0 +indicates no compression (store all files), +.B \-1 +indicates the fastest compression speed (less compression) +and +.B \-9 +indicates the slowest compression speed (optimal compression, ignores +the suffix list). The default compression level is +.BR \-6. + +Though still being worked, the intention is this setting will control +compression speed for all compression methods. Currently only +deflation is controlled. +.TP +.PD 0 +.B \-! +.TP +.PD +.B \-\-use\-privileges +[WIN32] Use priviliges (if granted) to obtain all aspects of WinNT security. +.TP +.PD 0 +.B \-@ +.TP +.PD +.B \-\-names\-stdin +Take the list of input files from standard input. Only one filename per line. +.TP +.PD 0 +.B \-$ +.TP +.PD +.B \-\-volume\-label +[MSDOS, OS/2, WIN32] Include the volume label for the drive holding +the first file to be compressed. If you want to include only the volume +label or to force a specific drive, use the drive name as first file name, +as in: +.RS +.IP +\fCzip -$ foo a: c:bar\fP +.RE +.IP +.SH "EXAMPLES" +The simplest example: +.IP +\fCzip stuff *\fP +.LP +creates the archive +.I stuff.zip +(assuming it does not exist) +and puts all the files in the current directory in it, in compressed form +(the +\fB\&.zip\fP +suffix is added automatically, unless the archive name contains +a dot already; +this allows the explicit specification of other suffixes). +.LP +Because of the way the shell on Unix does filename substitution, +files starting with "." are not included; +to include these as well: +.IP +\fCzip stuff .* *\fP +.LP +Even this will not include any subdirectories from the current directory. +.LP +To zip up an entire directory, the command: +.IP +\fCzip -r foo foo\fP +.LP +creates the archive +.IR foo.zip , +containing all the files and directories in the directory +.I foo +that is contained within the current directory. +.LP +You may want to make a +.I zip +archive that contains the files in +.IR foo , +without recording the directory name, +.IR foo . +You can use the +.B \-j +option to leave off the paths, +as in: +.IP +\fCzip -j foo foo/*\fP +.LP +If you are short on disk space, +you might not have enough room to hold both the original directory +and the corresponding compressed +.I zip +archive. +In this case, you can create the archive in steps using the +.B \-m +option. +If +.I foo +contains the subdirectories +.IR tom , +.IR dick , +and +.IR harry , +you can: +.IP +\fCzip -rm foo foo/tom\fP +.br +\fCzip -rm foo foo/dick\fP +.br +\fCzip -rm foo foo/harry\fP +.LP +where the first command creates +.IR foo.zip , +and the next two add to it. +At the completion of each +.I zip +command, +the last created archive is deleted, +making room for the next +.I zip +command to function. + + + +.LP +Use \fB\-s\fP to set the split size and create a split archive. The size is given as +a number followed optionally by one of k (kB), m (MB), g (GB), or t (TB). +The command +.IP +\fCzip -s 2g -r split.zip foo\fP +.LP +creates a split archive of the directory foo with splits no bigger than 2\ GB each. If +foo contained 5\ GB of contents and the contents were stored in the split archive without +compression (to make this example simple), this would create three splits, split.z01 at 2\ GB, +split.z02 at 2\ GB, and split.zip at a little over 1\ GB. +.LP +The \fB\-sp\fP option can be used to pause \fIzip\fP between splits to allow changing +removable media, for example, but read the descriptions and warnings for both \fB\-s\fP +and \fB\-sp\fP below. +.LP +Though \fIzip\fP does not update split archives, \fIzip\fP provides the new option \fB\-O\fP +(\fB\-\-output\-file\fP) to allow split archives to be updated and saved in a new archive. For example, +.IP +\fCzip inarchive.zip foo.c bar.c \-\-out outarchive.zip\fP +.LP +reads archive \fBinarchive.zip\fP, even if split, adds the files \fBfoo.c\fP and +\fBbar.c\fP, and writes the resulting archive to \fBoutarchive.zip\fP. If +\fBinarchive.zip\fP is split then \fBoutarchive.zip\fP defaults +to the same split size. Be aware that \fBoutarchive.zip\fP and any split files +that are created with it are always overwritten without warning. This may be changed +in the future. + + + + +.SH "PATTERN MATCHING" +This section applies only to Unix. +Watch this space for details on MSDOS and VMS operation. +However, the special wildcard characters \fB*\fR and \fB[]\fR below apply +to at least MSDOS also. +.LP +The Unix shells (\fIsh\fP, \fIcsh\fP, \fIbash\fP, and others) normally +do filename substitution (also called "globbing") on command arguments. +Generally the special characters are: +.TP +.B ? +match any single character +.TP +.B * +match any number of characters (including none) +.TP +.B [] +match any character in the range indicated within the brackets +(example: [a\-f], [0\-9]). This form of wildcard matching +allows a user to specify a list of characters between square brackets and +if any of the characters match the expression matches. For example: +.RS +.IP +\fCzip archive "*.[hc]"\fP +.RE +.IP +would archive all files in the current directory that end in +\fB.h\fP or \fB.c\fP. + +Ranges of characters are supported: +.RS +.IP +\fCzip archive "[a\-f]*"\fP +.RE +.IP +would add to the archive all files starting with "a" through "f". + +Negation is also supported, where any character in that position not in +the list matches. Negation is supported by adding \fB!\fP or \fB^\fP +to the beginning of the list: +.RS +.IP +\fCzip archive "*.[!o]"\fP +.RE +.IP +matches files that don't end in ".o". + +On WIN32, [] matching needs to be turned on with the -RE option to avoid +the confusion that names with [ or ] have caused. + +.LP +When these characters are encountered +(without being escaped with a backslash or quotes), +the shell will look for files relative to the current path +that match the pattern, +and replace the argument with a list of the names that matched. +.LP +The +.I zip +program can do the same matching on names that are in the +.I zip +archive being modified or, +in the case of the +.B \-x +(exclude) or +.B \-i +(include) options, on the list of files to be operated on, by using +backslashes or quotes to tell the shell not to do the name expansion. +In general, when +.I zip +encounters a name in the list of files to do, it first looks for the name in +the file system. If it finds it, it then adds it to the list of files to do. +If it does not find it, it looks for the name in the +.I zip +archive being modified (if it exists), using the pattern matching characters +described above, if present. For each match, it will add that name to the +list of files to be processed, unless this name matches one given +with the +.B \-x +option, or does not match any name given with the +.B \-i +option. +.LP +The pattern matching includes the path, +and so patterns like \\*.o match names that end in ".o", +no matter what the path prefix is. +Note that the backslash must precede every special character (i.e. ?*[]), +or the entire argument must be enclosed in double quotes (""). +.LP +In general, use backslashes or double quotes for paths +that have wildcards to make +.I zip +do the pattern matching for file paths, and always for +paths and strings that have spaces or wildcards for +\fB\-\i\fP, \fB\-x\fP, \fB\-R\fP, \fB\-d\fP, and \fB\-U\fP +and anywhere \fIzip\fP needs to process the wildcards. +.SH "ENVIRONMENT" +.LP +The following environment variables are read and used by +.I zip +as described. +.TP +.B ZIPOPT\ \ +contains default options that will be used when running +\fIzip\fR. The contents of this environment variable will get +added to the command line just after the \fBzip\fR command. +.TP +.B ZIP\ \ \ \ \ +[Not on RISC OS and VMS] see ZIPOPT +.TP +.B Zip$Options +[RISC OS] see ZIPOPT +.TP +.B Zip$Exts +[RISC OS] contains extensions separated by a : that will cause +native filenames with one of the specified extensions to +be added to the zip file with basename and extension swapped. +.TP +.B ZIP_OPTS +[VMS] see ZIPOPT +.SH "SEE ALSO" +compress(1), +shar(1L), +tar(1), +unzip(1L), +gzip(1L) +.SH DIAGNOSTICS +The exit status (or error level) approximates the exit codes defined by PKWARE +and takes on the following values, except under VMS: +.RS +.IP 0 +normal; no errors or warnings detected. +.IP 2 +unexpected end of zip file. +.IP 3 +a generic error in the zipfile format was detected. Processing may have +completed successfully anyway; some broken zipfiles created by other +archivers have simple work-arounds. +.IP 4 +\fIzip\fP was unable to allocate memory for one or more buffers during +program initialization. +.IP 5 +a severe error in the zipfile format was detected. Processing probably +failed immediately. +.IP 6 +entry too large to be processed (such as input files larger than 2 GB when +not using Zip64 or trying to read an existing archive that is too large) or +entry too large to be split with \fIzipsplit\fP +.IP 7 +invalid comment format +.IP 8 +\fIzip\fP -T failed or out of memory +.IP 9 +the user aborted \fIzip\fP prematurely with control-C (or similar) +.IP 10 +\fIzip\fP encountered an error while using a temp file +.IP 11 +read or seek error +.IP 12 +\fIzip\fP has nothing to do +.IP 13 +missing or empty zip file +.IP 14 +error writing to a file +.IP 15 +\fIzip\fP was unable to create a file to write to +.IP 16 +bad command line parameters +.IP 18 +\fIzip\fP could not open a specified file to read +.IP 19 +\fIzip\fP was compiled with options not supported on this system +.RE +.PP +VMS interprets standard Unix (or PC) return values as other, scarier-looking +things, so \fIzip\fP instead maps them into VMS-style status codes. In +general, \fIzip\fP sets VMS Facility = 1955 (0x07A3), Code = 2* Unix_status, +and an appropriate Severity (as specified in ziperr.h). More details are +included in the VMS-specific documentation. See [.vms]NOTES.TXT and +[.vms]vms_msg_gen.c. +.PD +.SH BUGS +.I zip +3.0 is not compatible with PKUNZIP 1.10. Use +.I zip +1.1 to produce +.I zip +files which can be extracted by PKUNZIP 1.10. +.PP +.I zip +files produced by +.I zip +3.0 must not be +.I updated +by +.I zip +1.1 or PKZIP 1.10, if they contain +encrypted members or if they have been produced in a pipe or on a non-seekable +device. The old versions of +.I zip +or PKZIP would create an archive with an incorrect format. +The old versions can list the contents of the zip file +but cannot extract it anyway (because of the new compression algorithm). +If you do not use encryption and use regular disk files, you do +not have to care about this problem. +.LP +Under VMS, +not all of the odd file formats are treated properly. +Only stream-LF format +.I zip +files are expected to work with +.IR zip . +Others can be converted using Rahul Dhesi's BILF program. +This version of +.I zip +handles some of the conversion internally. +When using Kermit to transfer zip files from VMS to MSDOS, type "set +file type block" on VMS. When transfering from MSDOS to VMS, type +"set file type fixed" on VMS. In both cases, type "set file type +binary" on MSDOS. +.LP +Under some older VMS versions, \fIzip\fP may hang for file +specifications that use DECnet syntax +.I foo::*.*. +.LP +On OS/2, zip cannot match some names, such as those including an +exclamation mark or a hash sign. This is a bug in OS/2 itself: the +32-bit DosFindFirst/Next don't find such names. Other programs such +as GNU tar are also affected by this bug. +.LP +Under OS/2, the amount of Extended Attributes displayed by DIR is (for +compatibility) the amount returned by the 16-bit version of +DosQueryPathInfo(). Otherwise OS/2 1.3 and 2.0 would report different +EA sizes when DIRing a file. +However, the structure layout returned by the 32-bit DosQueryPathInfo() +is a bit different, it uses extra padding bytes and link pointers (it's +a linked list) to have all fields on 4-byte boundaries for portability +to future RISC OS/2 versions. Therefore the value reported by +.I zip +(which uses this 32-bit-mode size) differs from that reported by DIR. +.I zip +stores the 32-bit format for portability, even the 16-bit +MS-C-compiled version running on OS/2 1.3, so even this one shows the +32-bit-mode size. +.SH AUTHORS +Copyright (C) 1997-2008 Info-ZIP. +.LP +Currently distributed under the Info-ZIP license. +.LP +Copyright (C) 1990-1997 Mark Adler, Richard B. Wales, Jean-loup Gailly, +Onno van der Linden, Kai Uwe Rommel, Igor Mandrichenko, John Bush and +Paul Kienitz. +.LP +Original copyright: +.LP +Permission is granted to any individual or institution to use, copy, or +redistribute this software so long as all of the original files are included, +that it is not sold for profit, and that this copyright notice +is retained. +.LP +LIKE ANYTHING ELSE THAT'S FREE, ZIP AND ITS ASSOCIATED UTILITIES ARE +PROVIDED AS IS AND COME WITH NO WARRANTY OF ANY KIND, EITHER EXPRESSED OR +IMPLIED. IN NO EVENT WILL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES +RESULTING FROM THE USE OF THIS SOFTWARE. +.LP +Please send bug reports and comments using the web page at: +.IR www.info-zip.org . +For bug reports, please include the version of +.IR zip +(see \fIzip\ \-h\fR), +the make options used to compile it (see \fIzip\ \-v\fR), +the machine and operating system in use, +and as much additional information as possible. +.SH ACKNOWLEDGEMENTS +Thanks to R. P. Byrne for his +.I Shrink.Pas +program, which inspired this project, +and from which the shrink algorithm was stolen; +to Phil Katz for placing in the public domain the +.I zip +file format, compression format, and .ZIP filename extension, and for +accepting minor changes to the file format; to Steve Burg for +clarifications on the deflate format; to Haruhiko Okumura and Leonid +Broukhis for providing some useful ideas for the compression +algorithm; to Keith Petersen, Rich Wales, Hunter Goatley and Mark +Adler for providing a mailing list and +.I ftp +site for the Info-ZIP group to use; and most importantly, to the +Info-ZIP group itself (listed in the file +.IR infozip.who ) +without whose tireless testing and bug-fixing efforts a portable +.I zip +would not have been possible. +Finally we should thank (blame) the first Info-ZIP moderator, +David Kirschbaum, +for getting us into this mess in the first place. +The manual page was rewritten for Unix by R. P. C. Rodgers and +updated by E. Gordon for \fIzip\fR 3.0. +.\" end of file diff --git a/man/zipcloak.1 b/man/zipcloak.1 new file mode 100644 index 0000000..8260b98 --- /dev/null +++ b/man/zipcloak.1 @@ -0,0 +1,111 @@ +.TH zipcloak 1 "v3.0 of 8 May 2008" +.SH NAME +zipcloak \- encrypt entries in a zipfile + +.SH SYNOPSIS +.I zipcloak +.RB [ \-d ] +.RB [ \-b\ path ] +.RB [ \-h ] +.RB [ \-v ] +.RB [ \-L ] +zipfile + +.SH ARGUMENTS +.in +13 +.ti -13 +zipfile Zipfile to encrypt entries in + +.SH OPTIONS +.TP +.PD 0 +.B \-b\ \fPpath +.TP +.PD +.B \-\-temp\-path \fPpath +Use the directory given by path for the temporary zip file. + +.TP +.PD 0 +.B \-d +.TP +.PD +.B \-\-decrypt +Decrypt encrypted entries (copy if given wrong password). + +.TP +.PD 0 +.B \-h +.TP +.PD +.B \-\-help\ +Show a short help. + +.TP +.PD 0 +.B \-L +.TP +.PD +.B \-\-license +Show software license. + +.TP +.PD 0 +.B \-O\ \fPpath +.TP +.PD +.B \-\-output\-file\ \fPzipfile +Write output to new archive zipfile, leaving original archive as is. + +.TP +.PD 0 +.B \-q +.TP +.PD +.B \-\-quiet +Quiet operation. Suppresses some informational messages. + +.TP +.PD 0 +.B \-v +.TP +.PD +.B \-\-version +Show version information. + +.SH DESCRIPTION +.I zipcloak +encrypts all unencrypted entries in the zipfile. This is the default action. + +.TP +The \-d option is used to decrypt encrypted entries in the zipfile. + +.TP +\fIzipcloak \fBuses original zip encryption which is considered weak. + +.TP +Note: +The encryption code of this program is not copyrighted and is put in +the public domain. It was originally written in Europe and can be freely +distributed from any country including the U.S.A. (Previously if this +program was imported into the U.S.A, it could not be re-exported from +the U.S.A to another country.) See the file README.CR included in the +source distribution for more on this. Otherwise, the Info-ZIP license +applies. + +.SH EXAMPLES +To be added. + +.SH BUGS +Large files (> 2 GB) and large archives not yet supported. + +Split archives not yet supported. A work around is to convert the +split archive to a single-file archive using \fIzip\fP and then +use \fIzipcloak\fP on the single-file archive. If needed, the +resulting archive can then be split again using \fIzip\fP. + + +.SH SEE ALSO +zip(1), unzip(1) +.SH AUTHOR +Info-ZIP diff --git a/man/zipnote.1 b/man/zipnote.1 new file mode 100644 index 0000000..fb4d18b --- /dev/null +++ b/man/zipnote.1 @@ -0,0 +1,85 @@ +.TH zipnote 1 "v3.0 of 8 May 2008" +.SH NAME +zipnote \- write the comments in zipfile to stdout, edit comments and rename files in zipfile + +.SH SYNOPSIS +.I zipnote +.RB [ \-w ] +.RB [ \-b\ path ] +.RB [ \-h ] +.RB [ \-v ] +.RB [ \-L ] +zipfile + +.SH ARGUMENTS +.in +13 +.ti -13 +zipfile Zipfile to read comments from or edit. + +.SH OPTIONS +.TP +.BI \-w +Write comments to a zipfile from stdin (see below). +.TP +.BI \-b\ \fRpath +Use path for the temporary zip file. +.TP +.BI \-h +Show a short help. +.TP +.BI \-v +Show version information. +.TP +.BI \-L +Show software license. + +.SH DESCRIPTION +.I zipnote +writes the comments in a zipfile to stdout. This is the default mode. A second mode +allows updating the comments in a zipfile as well as allows changing the names +of the files in the zipfile. These modes are described below. + +.SH EXAMPLES +To write all comments in a zipfile to stdout use for example +.LP +.nf + zipnote foo.zip > foo.tmp +.fi +.LP +This writes all comments in the zipfile +.I foo.zip +to the file +.I foo.tmp +in a specific format. + +.LP +If desired, this file can then be edited to change the comments and then used +to update the zipfile. +.LP +.nf + zipnote -w foo.zip < foo.tmp +.fi +.LP +The names of the files in the zipfile can also be changed in this way. This is done by +following lines like +.nf + "@ name" +.fi +in the created temporary file (called +.I foo.tmp +here) with lines like +.nf + "@=newname" +.fi +and then using the -w option as above. + +.SH BUGS +The temporary file format is rather specific and zipnote is rather picky about it. +It should be easier to change file names in a script. + +Does not yet support large (> 2 GB) or split archives. + +.SH SEE ALSO +zip(1), unzip(1) +.SH AUTHOR +Info-ZIP diff --git a/man/zipsplit.1 b/man/zipsplit.1 new file mode 100644 index 0000000..4a4de64 --- /dev/null +++ b/man/zipsplit.1 @@ -0,0 +1,69 @@ +.TH zipnote 1 "v3.0 of 8 May 2008" +.SH NAME +zipsplit \- split a zipfile into smaller zipfiles + +.SH SYNOPSIS +.I zipsplit +.RB [ \-t ] +.RB [ \-i ] +.RB [ \-p ] +.RB [ \-s ] +.RB [ \-n\ size ] +.RB [ \-r\ room ] +.RB [ \-b\ path ] +.RB [ \-h ] +.RB [ \-v ] +.RB [ \-L ] +zipfile + +.SH ARGUMENTS +.in +13 +.ti -13 +zipfile Zipfile to split. + +.SH OPTIONS +.TP +.BI \-t +Report how many files it will take, but don't make them. +.TP +.BI \-i +Make index (zipsplit.idx) and count its size against first zip file. +.TP +.BI \-n\ \fRsize +Make zip files no larger than "size" (default = 36000). +.TP +.BI \-r\ \fRroom +Leave room for "room" bytes on the first disk (default = 0). +.TP +.BI \-b\ \fRpath +Use path for the output zip files. +.TP +.BI \-p +Pause between output zip files. +.TP +.BI \-s +Do a sequential split even if it takes more zip files. +.TP +.BI \-h +Show a short help. +.TP +.BI \-v +Show version information. +.TP +.BI \-L +Show software license. + +.SH DESCRIPTION +.I zipsplit +reads a zipfile and splits it into smaller zipfiles. + +.SH EXAMPLES +To be filled in. + +.SH BUGS +Does not yet support large (> 2 GB) or split archives. + +.SH SEE ALSO +zip(1), unzip(1) +.SH AUTHOR +Info-ZIP diff --git a/match.S b/match.S new file mode 100644 index 0000000..eb8f735 --- /dev/null +++ b/match.S @@ -0,0 +1,407 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2004-May-22 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ + +/* + * match.s by Jean-loup Gailly. Translated to 32 bit code by Kai Uwe Rommel. + * The 68020 version has been written by Francesco Potorti` + * with adaptations by Carsten Steger , + * Andreas Schwab and + * Kristoffer Eriksson + */ + +/* This file is NOT used in conjunction with zlib. */ +#ifndef USE_ZLIB + +/* Preprocess with -DNO_UNDERLINE if your C compiler does not prefix + * external symbols with an underline character '_'. + */ +#if defined(NO_UNDERLINE) || defined(__ELF__) +# define _prev prev +# define _window window +# define _match_start match_start +# define _prev_length prev_length +# define _good_match good_match +# define _nice_match nice_match +# define _strstart strstart +# define _max_chain_length max_chain_length + +# define _match_init match_init +# define _longest_match longest_match +#endif + +#ifdef DYN_ALLOC + error: DYN_ALLOC not yet supported in match.s +#endif + +/* Use 16-bytes alignment if your assembler supports it. Warning: gas + * uses a log(x) parameter (.align 4 means 16-bytes alignment). On SVR4 + * the parameter is a number of bytes. + */ +#ifndef ALIGNMENT +# define ALIGNMENT 4 +#endif + + +#ifndef WSIZE +# define WSIZE 32768 +#endif +#define MIN_MATCH 3 +#define MAX_MATCH 258 +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) +#define MAX_DIST (WSIZE - MIN_LOOKAHEAD) + +#if defined(i386) || defined(_I386) || defined(_i386) || defined(__i386) + +/* This version is for 386 Unix or OS/2 in 32 bit mode. + * Warning: it uses the AT&T syntax: mov source,dest + * This file is only optional. If you want to force the C version, + * add -DNO_ASM to CFLAGS in Makefile and set OBJA to an empty string. + * If you have reduced WSIZE in (g)zip.h, then make sure this is + * assembled with an equivalent -DWSIZE=. + * This version assumes static allocation of the arrays (-DDYN_ALLOC not used). + */ + + .file "match.S" + + .globl _match_init + .globl _longest_match + + .text + +_match_init: + ret + +/*----------------------------------------------------------------------- + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + */ + + .align ALIGNMENT + +_longest_match: /* int longest_match(cur_match) */ + +#define cur_match 20(%esp) + /* return address */ /* esp+16 */ + push %ebp /* esp+12 */ + push %edi /* esp+8 */ + push %esi /* esp+4 */ + push %ebx /* esp */ + +/* + * match equ esi + * scan equ edi + * chain_length equ ebp + * best_len equ ebx + * limit equ edx + */ + mov cur_match,%esi + mov _strstart,%edx + mov _max_chain_length,%ebp /* chain_length = max_chain_length */ + mov %edx,%edi + sub $(MAX_DIST),%edx /* limit = strstart-MAX_DIST */ + cld /* string ops increment si and di */ + jae limit_ok + sub %edx,%edx /* limit = NIL */ +limit_ok: + add $2+_window,%edi /* edi = offset(window+strstart+2) */ + mov _prev_length,%ebx /* best_len = prev_length */ + movw -2(%edi),%cx /* cx = scan[0..1] */ + movw -3(%ebx,%edi),%ax /* ax = scan[best_len-1..best_len] */ + cmp _good_match,%ebx /* do we have a good match already? */ + jb do_scan + shr $2,%ebp /* chain_length >>= 2 */ + jmp do_scan + + .align ALIGNMENT +long_loop: +/* at this point, edi == scan+2, esi == cur_match */ + movw -3(%ebx,%edi),%ax /* ax = scan[best_len-1..best_len] */ + movw -2(%edi),%cx /* cx = scan[0..1] */ +short_loop: +/* + * at this point, di == scan+2, si == cur_match, + * ax = scan[best_len-1..best_len] and cx = scan[0..1] + */ + and $(WSIZE-1), %esi + dec %ebp /* --chain_length */ + movw _prev(,%esi,2),%si /* cur_match = prev[cur_match] */ + /* top word of esi is still 0 */ + jz the_end + cmp %edx,%esi /* cur_match <= limit ? */ + jbe the_end +do_scan: + cmpw _window-1(%ebx,%esi),%ax/* check match at best_len-1 */ + jne short_loop + cmpw _window(%esi),%cx /* check min_match_length match */ + jne short_loop + + add $2+_window,%esi /* si = match */ + mov $((MAX_MATCH>>1)-1),%ecx/* scan for at most MAX_MATCH bytes */ + mov %edi,%eax /* ax = scan+2 */ + repe; cmpsw /* loop until mismatch */ + je maxmatch /* match of length MAX_MATCH? */ +mismatch: + movb -2(%edi),%cl /* mismatch on first or second byte? */ + xchg %edi,%eax /* edi = scan+2, eax = end of scan */ + subb -2(%esi),%cl /* cl = 0 if first bytes equal */ + sub %edi,%eax /* eax = len */ + sub $2+_window,%esi /* esi = cur_match + len */ + sub %eax,%esi /* esi = cur_match */ + subb $1,%cl /* set carry if cl == 0 (cannot use DEC) */ + adc $0,%eax /* eax = carry ? len+1 : len */ + cmp %ebx,%eax /* len > best_len ? */ + jle long_loop + mov %esi,_match_start /* match_start = cur_match */ + mov %eax,%ebx /* ebx = best_len = len */ +#ifdef FULL_SEARCH + cmp $(MAX_MATCH),%eax /* len >= MAX_MATCH ? */ +#else + cmp _nice_match,%eax /* len >= nice_match ? */ +#endif + jl long_loop +the_end: + mov %ebx,%eax /* result = eax = best_len */ + pop %ebx + pop %esi + pop %edi + pop %ebp + ret + .align ALIGNMENT +maxmatch: + cmpsb + jmp mismatch + +#else /* !(i386 || _I386 || _i386 || __i386) */ + +/* ======================== 680x0 version ================================= */ + +#if defined(m68k)||defined(mc68k)||defined(__mc68000__)||defined(__MC68000__) +# ifndef mc68000 +# define mc68000 +# endif +#endif + +#if defined(__mc68020__) || defined(__MC68020__) || defined(sysV68) +# ifndef mc68020 +# define mc68020 +# endif +#endif + +#if defined(mc68020) || defined(mc68000) + +#if (defined(mc68020) || defined(NeXT)) && !defined(UNALIGNED_OK) +# define UNALIGNED_OK +#endif + +#ifdef sysV68 /* Try Motorola Delta style */ + +# define GLOBAL(symbol) global symbol +# define TEXT text +# define FILE(filename) file filename +# define invert_maybe(src,dst) dst,src +# define imm(data) &data +# define reg(register) %register + +# define addl add.l +# define addql addq.l +# define blos blo.b +# define bhis bhi.b +# define bras bra.b +# define clrl clr.l +# define cmpmb cmpm.b +# define cmpw cmp.w +# define cmpl cmp.l +# define lslw lsl.w +# define lsrl lsr.l +# define movel move.l +# define movew move.w +# define moveb move.b +# define moveml movem.l +# define subl sub.l +# define subw sub.w +# define subql subq.l + +# define IndBase(bd,An) (bd,An) +# define IndBaseNdxl(bd,An,Xn) (bd,An,Xn.l) +# define IndBaseNdxw(bd,An,Xn) (bd,An,Xn.w) +# define predec(An) -(An) +# define postinc(An) (An)+ + +#else /* default style (Sun 3, NeXT, Amiga, Atari) */ + +# define GLOBAL(symbol) .globl symbol +# define TEXT .text +# define FILE(filename) .even +# define invert_maybe(src,dst) src,dst +# if defined(sun) || defined(mc68k) +# define imm(data) #data +# else +# define imm(data) \#data +# endif +# define reg(register) register + +# define blos bcss +# if defined(sun) || defined(mc68k) +# define movel movl +# define movew movw +# define moveb movb +# endif +# define IndBase(bd,An) An@(bd) +# define IndBaseNdxl(bd,An,Xn) An@(bd,Xn:l) +# define IndBaseNdxw(bd,An,Xn) An@(bd,Xn:w) +# define predec(An) An@- +# define postinc(An) An@+ + +#endif /* styles */ + +#define Best_Len reg(d0) /* unsigned */ +#define Cur_Match reg(d1) /* Ipos */ +#define Loop_Counter reg(d2) /* int */ +#define Scan_Start reg(d3) /* unsigned short */ +#define Scan_End reg(d4) /* unsigned short */ +#define Limit reg(d5) /* IPos */ +#define Chain_Length reg(d6) /* unsigned */ +#define Scan_Test reg(d7) +#define Scan reg(a0) /* *uch */ +#define Match reg(a1) /* *uch */ +#define Prev_Address reg(a2) /* *Pos */ +#define Scan_Ini reg(a3) /* *uch */ +#define Match_Ini reg(a4) /* *uch */ +#define Stack_Pointer reg(sp) + + GLOBAL (_match_init) + GLOBAL (_longest_match) + + TEXT + + FILE ("match.S") + +_match_init: + rts + +/*----------------------------------------------------------------------- + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + */ + +/* int longest_match (cur_match) */ + +#ifdef UNALIGNED_OK +# define pushreg 15928 /* d2-d6/a2-a4 */ +# define popreg 7292 +#else +# define pushreg 16184 /* d2-d7/a2-a4 */ +# define popreg 7420 +#endif + +_longest_match: + movel IndBase(4,Stack_Pointer),Cur_Match + moveml imm(pushreg),predec(Stack_Pointer) + movel _max_chain_length,Chain_Length + movel _prev_length,Best_Len + movel imm(_prev),Prev_Address + movel imm(_window+MIN_MATCH),Match_Ini + movel _strstart,Limit + movel Match_Ini,Scan_Ini + addl Limit,Scan_Ini + subw imm(MAX_DIST),Limit + bhis L__limit_ok + clrl Limit +L__limit_ok: + cmpl invert_maybe(_good_match,Best_Len) + blos L__length_ok + lsrl imm(2),Chain_Length +L__length_ok: + subql imm(1),Chain_Length +#ifdef UNALIGNED_OK + movew IndBase(-MIN_MATCH,Scan_Ini),Scan_Start + movew IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End +#else + moveb IndBase(-MIN_MATCH,Scan_Ini),Scan_Start + lslw imm(8),Scan_Start + moveb IndBase(-MIN_MATCH+1,Scan_Ini),Scan_Start + moveb IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End + lslw imm(8),Scan_End + moveb IndBaseNdxw(-MIN_MATCH,Scan_Ini,Best_Len),Scan_End +#endif + bras L__do_scan + +L__long_loop: +#ifdef UNALIGNED_OK + movew IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End +#else + moveb IndBaseNdxw(-MIN_MATCH-1,Scan_Ini,Best_Len),Scan_End + lslw imm(8),Scan_End + moveb IndBaseNdxw(-MIN_MATCH,Scan_Ini,Best_Len),Scan_End +#endif + +L__short_loop: + lslw imm(1),Cur_Match + movew IndBaseNdxl(0,Prev_Address,Cur_Match),Cur_Match + cmpw invert_maybe(Limit,Cur_Match) + dbls Chain_Length,L__do_scan + bras L__return + +L__do_scan: + movel Match_Ini,Match + addl Cur_Match,Match +#ifdef UNALIGNED_OK + cmpw invert_maybe(IndBaseNdxw(-MIN_MATCH-1,Match,Best_Len),Scan_End) + bne L__short_loop + cmpw invert_maybe(IndBase(-MIN_MATCH,Match),Scan_Start) + bne L__short_loop +#else + moveb IndBaseNdxw(-MIN_MATCH-1,Match,Best_Len),Scan_Test + lslw imm(8),Scan_Test + moveb IndBaseNdxw(-MIN_MATCH,Match,Best_Len),Scan_Test + cmpw invert_maybe(Scan_Test,Scan_End) + bne L__short_loop + moveb IndBase(-MIN_MATCH,Match),Scan_Test + lslw imm(8),Scan_Test + moveb IndBase(-MIN_MATCH+1,Match),Scan_Test + cmpw invert_maybe(Scan_Test,Scan_Start) + bne L__short_loop +#endif + + movew imm((MAX_MATCH-MIN_MATCH+1)-1),Loop_Counter + movel Scan_Ini,Scan +L__scan_loop: + cmpmb postinc(Match),postinc(Scan) + dbne Loop_Counter,L__scan_loop + + subl Scan_Ini,Scan + addql imm(MIN_MATCH-1),Scan + cmpl invert_maybe(Best_Len,Scan) + bls L__short_loop + movel Scan,Best_Len + movel Cur_Match,_match_start +#ifdef FULL_SEARCH + cmpl invert_maybe(imm(MAX_MATCH),Best_Len) +#else + cmpl invert_maybe(_nice_match,Best_Len) +#endif + blos L__long_loop +L__return: + moveml postinc(Stack_Pointer),imm(popreg) + rts + +#else + error: this asm version is for 386 or 680x0 only +#endif /* mc68000 || mc68020 */ +#endif /* i386 || _I386 || _i386 || __i386 */ + +#endif /* !USE_ZLIB */ diff --git a/msdos/README.DOS b/msdos/README.DOS new file mode 100644 index 0000000..0b9a57b --- /dev/null +++ b/msdos/README.DOS @@ -0,0 +1,132 @@ +README.DOS + +Some notes about the supplied MSDOS executables and their compilers: + +A) The 32-bit DOS executables "zip.exe" and the auxilary utilities + "zipnote.exe", "zipsplit.exe", "zipcloak.exe" (crypt-enabled distribution + only) were compiled with DJGPP v 2.03, using gcc 2.95.3 as compiler. + They require a DPMI server to run, e.g.: a DOS command prompt window + under WINDOWS 3.x or Windows 9x. To use this program under plain DOS, + you should install the free (GPL'ed) DPMI server CWSDPMI.EXE. Look + for "csdpmi5b.zip" under "simtelnet/gnu/djgpp/v2misc/" on the SimTelNet + home site "ftp.cdrom.com" or any mirror site of the SimtelNet archive. + + We have decided to provide 32-bit rather than 16-bit executables of + the auxilary tools for the following reasons: + - Nowadays, it has become quite unlikely to find PC computers "in action" + that do not at least have an i386 CPU. + - the 32-bit versions do not impose additional archive handling limits + beyond those defined by the Zip archive format + - the 32-bit DJGPP executables can handle long filenames on systems running + Windows 95/98/Me and Windows 2K/XP. + +B) There are two 16-bit MSDOS executables provided in zcr2?x.zip: + zip16.exe regular Zip program, requires ca. 455 KBytes of contiguous + free DOS memory or more. + zip16-sm.exe a variant that was compiled with the SMALL_MEM option + for minimal memory consumption; requires at minimum + 322 KBytes of contiguous free DOS memory. + + The SMALL_MEM variant requires much less space for the compression + buffers, but at the cost of some compression efficiency. + Therefore, we recommend to use the "SMALL_MEM" 16-bit "zip16-sm.exe" only + in case of "out of memory" problems (DOS memory is low and/or very large + number of archive entries), when the 32-bit program cannot be used for + some reason (286 or older; no DPMI server; ...). + +C) Hard limits of the Zip archive format: + Number of entries in Zip archive: 64 k (2^16 - 1 entries) + Compressed size of archive entry: 4 GByte (2^32 - 1 Bytes) + Uncompressed size of entry: 4 GByte (2^32 - 1 Bytes) + Size of single-volume Zip archive: 4 GByte (2^32 - 1 Bytes) + Per-volume size of multi-volume archives: 4 GByte (2^32 - 1 Bytes) + Number of parts for multi-volume archives: 64 k (1^16 - 1 parts) + Total size of multi-volume archive: 256 TByte (4G * 64k) + + The number of archive entries and of multivolume parts are limited by + the structure of the "end-of-central-directory" record, where the these + numbers are stored in 2-Byte fields. + Some Zip and/or UnZip implementations (for example Info-ZIP's) allow + handling of archives with more than 64k entries. (The information + from "number of entries" field in the "end-of-central-directory" record + is not really neccessary to retrieve the contents of a Zip archive; + it should rather be used for consistency checks.) + + Length of an archive entry name: 64 kByte (2^16 - 1) + Length of archive member comment: 64 kByte (2^16 - 1) + Total length of "extra field": 64 kByte (2^16 - 1) + Length of a single e.f. block: 64 kByte (2^16 - 1) + Length of archive comment: 64 KByte (2^16 - 1) + + Additional limitation claimed by PKWARE: + Size of local-header structure (fixed fields of 30 Bytes + filename + local extra field): < 64 kByte + Size of central-directory structure (46 Bytes + filename + + central extra field + member comment): < 64 kByte + +D) Implementation limits of the Zip executables: + + 1. Size limits caused by file I/O and compression handling: + Size of Zip archive: 2 GByte (2^31 - 1 Bytes) + Compressed size of archive entry: 2 GByte (2^31 - 1 Bytes) + Uncompressed size of entry: 2 GByte (2^31 - 1 Bytes), + (could/should be 4 GBytes...) + Multi-volume archive creation is not supported. + + 2. Limits caused by handling of archive contents lists + + 2.1. Number of archive entries (freshen, update, delete) + a) 16-bit executable: 64k (2^16 -1) or 32k (2^15 - 1), + (unsigned vs. signed type of size_t) + a1) 16-bit executable: <16k ((2^16)/4) + (The smaller limit a1) results from the array size limit of + the "qsort()" function.) + 32-bit executables <1G ((2^32)/4) + (usual system limit of the "qsort()" function on 32-bit systems) + + b) stack space needed by qsort to sort list of archive entries + + NOTE: In the current executables, overflows of limits a) and b) are NOT + checked! + + c) amount of free memory to hold "central directory information" of + all archive entries; one entry needs: + 96 bytes (32-bit) resp. 80 bytes (16-bit) + + 3 * length of entry name + + length of zip entry comment (when present) + + length of extra field(s) (when present, e.g.: UT needs 9 bytes) + + some bytes for book-keeping of memory allocation + + Conclusion: + For systems with limited memory space (MSDOS, small AMIGAs, other + environments without virtual memory), the number of archive entries + is most often limited by condition c). + For example, with approx. 100 kBytes of free memory after loading and + initializing the program, a 16-bit DOS Zip cannot process more than 600 + to 1000 (+) archive entries. (For the 16-bit Windows DLL or the 16-bit + OS/2 port, limit c) is less important because Windows or OS/2 executables + are not restricted to the 1024k area of real mode memory. These 16-bit + ports are limited by conditions a1) and b), say: at maximum approx. + 16000 entries!) + + + 2.2. Number of "new" entries (add operation) + In addition to the restrictions above (2.1.), the following limits + caused by the handling of the "new files" list apply: + + a) 16-bit executable: <16k ((2^64)/4) + + b) stack size required for "qsort" operation on "new entries" list. + + NOTE: In the current executables, the overflow checks for these limits + are missing! + + c) amount of free memory to hold the directory info list for new entries; + one entry needs: + 24 bytes (32-bit) resp. 22 bytes (16-bit) + + 3 * length of filename + + +Please report any problems to: Zip-Bugs@lists.wku.edu + +Last updated: 07 July 2001 diff --git a/msdos/crc_i86.asm b/msdos/crc_i86.asm new file mode 100644 index 0000000..3ad0349 --- /dev/null +++ b/msdos/crc_i86.asm @@ -0,0 +1,497 @@ +;=========================================================================== +; Copyright (c) 1990-2007 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 2000-Apr-09 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, all these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +;=========================================================================== +; Created by Christian Spieler, last modified 07 Jan 2007. +; + TITLE crc_i86.asm + NAME crc_i86 +; +; Optimized 8086 assembler version of the CRC32 calculation loop, intended +; for real mode Info-ZIP programs (Zip 2.1, UnZip 5.2, and later versions). +; Supported compilers are Microsoft C (DOS real mode) and Borland C(++) +; (Turbo C). Watcom C (16bit) should also work. +; This module was inspired by a similar module for the Amiga (Paul Kienitz). +; +; It replaces the `ulg crc32(ulg crc, ZCONST uch *buf, extent len)' function +; in crc32.c. +; +; In March/April 1997, the code has been revised to incorporate Rodney Brown's +; ideas for optimized access to the data buffer. For 8086 real mode code, +; the data buffer is now accessed by aligned word-wide read operations. +; This new optimization may be turned off by defining the macro switch +; NO_16_BIT_LOADS. +; +; In December 1998, the loop branch commands were changed from "loop dest" +; into "dec cx; jnz dest". On modern systems (486 and newer), the latter +; code is usually much faster (e.g. 1 clock cycle compared to 5 for "loop" +; on Pentium MMX). For the 286, the penalty of "dec cx; jnz" is one clock +; cycle (12 vs. 11 cycles); on an 8088 the cycle counts are 22 (dec cx; jnz) +; vs. 18 (loop). I decided to optimize for newer CPU models by default, because +; I expect that old 80286 or 8088 dinosaurier machines may be rarely used +; nowadays. In case you want optimum performance for these old CPU models +; you should define the OPTIMIZE_286_88 macro switch on the assembler's +; command line. +; Likewise, "jcxz" was replaced by "jz", because the latter is faster on +; 486 and newer CPUs (without any penalty on 80286 and older CPU models). +; +; In January 2007, the "hand-made" memory model setup section has been guarded +; against redefinition of @CodeSize and @DataSize symbols, to work around a +; problem with current Open Watcom (version 1.6) wasm assembler. +; +; The code in this module should work with all kinds of C memory models +; (except Borland's __HUGE__ model), as long as the following +; restrictions are not violated: +; +; - The implementation assumes that the char buffer is confined to a +; 64k segment. The pointer `s' to the buffer must be in a format that +; all bytes can be accessed by manipulating the offset part, only. +; This means: +; + no huge pointers +; + char buffer size < 64 kByte +; +; - Since the buffer size argument `n' is of type `size_t' (= unsigned short) +; for this routine, the char buffer size is limited to less than 64 kByte, +; anyway. So, the assumption above should be easily fulfilled. +; +;============================================================================== +; +; Do NOT assemble this source if external crc32 routine from zlib gets used, +; or only the precomputed CRC_32_Table is needed. +; +ifndef USE_ZLIB +ifndef CRC_TABLE_ONLY +; +; Setup of amount of assemble time informational messages: +; +ifdef DEBUG + VERBOSE_INFO EQU 1 +else + ifdef _AS_MSG_ + VERBOSE_INFO EQU 1 + else + VERBOSE_INFO EQU 0 + endif +endif +; +; Selection of memory model, and initialization of memory model +; related macros: +; +ifndef __SMALL__ + ifndef __COMPACT__ + ifndef __MEDIUM__ + ifndef __LARGE__ + ifndef __HUGE__ +; __SMALL__ EQU 1 + endif + endif + endif + endif +endif + +ifdef __HUGE__ +; .MODEL Huge + ifndef @CodeSize + @CodeSize EQU 1 + endif + ifndef @DataSize + @DataSize EQU 1 + endif + Save_DS EQU 1 + if VERBOSE_INFO + if1 + %out Assembling for C, Huge memory model + endif + endif +else + ifdef __LARGE__ +; .MODEL Large + ifndef @CodeSize + @CodeSize EQU 1 + endif + ifndef @DataSize + @DataSize EQU 1 + endif + if VERBOSE_INFO + if1 + %out Assembling for C, Large memory model + endif + endif + else + ifdef __COMPACT__ +; .MODEL Compact + ifndef @CodeSize + @CodeSize EQU 0 + endif + ifndef @DataSize + @DataSize EQU 1 + endif + if VERBOSE_INFO + if1 + %out Assembling for C, Compact memory model + endif + endif + else + ifdef __MEDIUM__ +; .MODEL Medium + ifndef @CodeSize + @CodeSize EQU 1 + endif + ifndef @DataSize + @DataSize EQU 0 + endif + if VERBOSE_INFO + if1 + %out Assembling for C, Medium memory model + endif + endif + else +; .MODEL Small + ifndef @CodeSize + @CodeSize EQU 0 + endif + ifndef @DataSize + @DataSize EQU 0 + endif + if VERBOSE_INFO + if1 + %out Assembling for C, Small memory model + endif + endif + endif + endif + endif +endif + +if @CodeSize + LCOD_OFS EQU 2 +else + LCOD_OFS EQU 0 +endif + +IF @DataSize + LDAT_OFS EQU 2 +else + LDAT_OFS EQU 0 +endif + +ifdef Save_DS +; (di,si,ds)+(size, return address) + SAVE_REGS EQU 6+(4+LCOD_OFS) +else +; (di,si)+(size, return address) + SAVE_REGS EQU 4+(4+LCOD_OFS) +endif + +; +; Selection of the supported CPU instruction set and initialization +; of CPU type related macros: +; +ifdef __686 + Use_286_code EQU 1 + Align_Size EQU 4 ; dword alignment on Pentium II/III/IV + Alig_PARA EQU 1 ; paragraph aligned code segment +else +ifdef __586 + Use_286_code EQU 1 + Align_Size EQU 4 ; dword alignment on Pentium + Alig_PARA EQU 1 ; paragraph aligned code segment +else +ifdef __486 + Use_286_code EQU 1 + Align_Size EQU 4 ; dword alignment on 32 bit processors + Alig_PARA EQU 1 ; paragraph aligned code segment +else +ifdef __386 + Use_286_code EQU 1 + Align_Size EQU 4 ; dword alignment on 32 bit processors + Alig_PARA EQU 1 ; paragraph aligned code segment +else +ifdef __286 + Use_286_code EQU 1 + Align_Size EQU 2 ; word alignment on 16 bit processors + Alig_PARA EQU 0 ; word aligned code segment +else +ifdef __186 + Use_186_code EQU 1 + Align_Size EQU 2 ; word alignment on 16 bit processors + Alig_PARA EQU 0 ; word aligned code segment +else + Align_Size EQU 2 ; word alignment on 16 bit processors + Alig_PARA EQU 0 ; word aligned code segment +endif ;?__186 +endif ;?__286 +endif ;?__386 +endif ;?__486 +endif ;?__586 +endif ;?__686 + +ifdef Use_286_code + .286 + Have_80x86 EQU 1 +else +ifdef Use_186_code + .186 + Have_80x86 EQU 1 +else + .8086 + Have_80x86 EQU 0 +endif ;?Use_186_code +endif ;?Use_286_code + +; +; Declare the segments used in this module: +; +if @CodeSize +if Alig_PARA +CRC32_TEXT SEGMENT PARA PUBLIC 'CODE' +else +CRC32_TEXT SEGMENT WORD PUBLIC 'CODE' +endif +CRC32_TEXT ENDS +else ;!@CodeSize +if Alig_PARA +_TEXT SEGMENT PARA PUBLIC 'CODE' +else +_TEXT SEGMENT WORD PUBLIC 'CODE' +endif +_TEXT ENDS +endif ;?@CodeSize +_DATA SEGMENT WORD PUBLIC 'DATA' +_DATA ENDS +_BSS SEGMENT WORD PUBLIC 'BSS' +_BSS ENDS +DGROUP GROUP _BSS, _DATA +if @DataSize + ASSUME DS: nothing, SS: DGROUP +else + ASSUME DS: DGROUP, SS: DGROUP +endif + +if @CodeSize +EXTRN _get_crc_table:FAR +else +EXTRN _get_crc_table:NEAR +endif + + +Do_CRC MACRO + mov bl,al + sub bh,bh +if Have_80x86 + shl bx,2 +else + shl bx,1 + shl bx,1 +endif + mov al,ah + mov ah,dl + mov dl,dh + sub dh,dh + xor ax,WORD PTR [bx][si] + xor dx,WORD PTR [bx+2][si] + ENDM +; +Do_1 MACRO +if @DataSize + xor al,BYTE PTR es:[di] +else + xor al,BYTE PTR [di] +endif + inc di + Do_CRC + ENDM +; +Do_2 MACRO +ifndef NO_16_BIT_LOADS +if @DataSize + xor ax,WORD PTR es:[di] +else + xor ax,WORD PTR [di] +endif + add di,2 + Do_CRC + Do_CRC +else + Do_1 + Do_1 +endif + ENDM +; +Do_4 MACRO + Do_2 + Do_2 + ENDM +; + +IF @CodeSize +CRC32_TEXT SEGMENT + ASSUME CS: CRC32_TEXT +else +_TEXT SEGMENT + ASSUME CS: _TEXT +endif +; Line 37 + +; +;ulg crc32(ulg crc, +; ZCONST uch *buf, +; extent len) +; + PUBLIC _crc32 +if @CodeSize +_crc32 PROC FAR +else +_crc32 PROC NEAR +endif +if Have_80x86 + enter WORD PTR 0,0 +else + push bp + mov bp,sp +endif + push di + push si +if @DataSize +; crc = 4+LCOD_OFS DWORD (unsigned long) +; buf = 8+LCOD_OFS DWORD PTR BYTE (uch *) +; len = 12+LCOD_OFS WORD (unsigned int) +else +; crc = 4+LCOD_OFS DWORD (unsigned long) +; buf = 8+LCOD_OFS WORD PTR BYTE (uch *) +; len = 10+LCOD_OFS WORD (unsigned int) +endif +; +if @DataSize + mov ax,WORD PTR [bp+8+LCOD_OFS] ; buf + or ax,WORD PTR [bp+10+LCOD_OFS] ; == NULL ? +else + cmp WORD PTR [bp+8+LCOD_OFS],0 ; buf == NULL ? +endif + jne crc_update + sub ax,ax ; crc = 0 + cwd +ifndef NO_UNROLLED_LOOPS + jmp fine +else + jmp SHORT fine +endif +; +crc_update: + call _get_crc_table +; When used with compilers that conform to the Microsoft/Borland standard +; C calling convention, model-dependent handling is not needed, because +; _get_crc_table returns NEAR pointer. +; But Watcom C is different and does not allow one to assume DS pointing to +; DGROUP. So, we load DS with DGROUP, to be safe. +;if @DataSize +; push ds +; mov ds,dx +; ASSUME DS: nothing +;endif + mov si,ax ;crc_table +if @DataSize + push ds + mov ax,SEG DGROUP + mov ds,ax + ASSUME DS: DGROUP +endif +; + mov ax,WORD PTR [bp+4+LCOD_OFS] ;crc + mov dx,WORD PTR [bp+6+LCOD_OFS] + not ax + not dx +if @DataSize + les di,DWORD PTR [bp+8+LCOD_OFS] ;buf + mov cx,WORD PTR [bp+12+LCOD_OFS] ;len +else + mov di,WORD PTR [bp+8+LCOD_OFS] ;buf + mov cx,WORD PTR [bp+10+LCOD_OFS] ;len +endif +; +ifndef NO_UNROLLED_LOOPS +ifndef NO_16_BIT_LOADS + test cx,cx + jnz start + jmp done +start: test di,1 + jz is_wordaligned + dec cx + Do_1 + mov WORD PTR [bp+10+LDAT_OFS+LCOD_OFS],cx +is_wordaligned: +endif ; !NO_16_BIT_LOADS +if Have_80x86 + shr cx,2 +else + shr cx,1 + shr cx,1 +endif + jz No_Fours +; + align Align_Size ; align destination of branch +Next_Four: + Do_4 +ifndef OPTIMIZE_286_88 + dec cx ; on 286, "loop Next_Four" needs 11 + jnz Next_Four ; clocks, one less than this code +else + loop Next_Four +endif +; +No_Fours: +if @DataSize + mov cx,WORD PTR [bp+12+LCOD_OFS] ;len +else + mov cx,WORD PTR [bp+10+LCOD_OFS] ;len +endif + and cx,00003H +endif ; !NO_UNROLLED_LOOPS + jz done +; + align Align_Size ; align destination of branch +Next_Byte: + Do_1 +ifndef OPTIMIZE_286_88 + dec cx ; on 286, "loop Next_Four" needs 11 + jnz Next_Byte ; clocks, one less than this code +else + loop Next_Four +endif +; +done: +if @DataSize + pop ds +; ASSUME DS: DGROUP + ASSUME DS: nothing +endif + not ax + not dx +; +fine: + pop si + pop di +if Have_80x86 + leave +else + mov sp,bp + pop bp +endif + ret + +_crc32 ENDP + +if @CodeSize +CRC32_TEXT ENDS +else +_TEXT ENDS +endif +; +endif ;!CRC_TABLE_ONLY +endif ;!USE_ZLIB +; +END diff --git a/msdos/makebz2.dj2 b/msdos/makebz2.dj2 new file mode 100644 index 0000000..161f1e3 --- /dev/null +++ b/msdos/makebz2.dj2 @@ -0,0 +1,148 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for +# djgpp 2.x +# +# This simple modified version of makefile.dj2 adds bzip2 support +# to Zip for djgpp 2.x and was donated by Robert Riebisch. +# +# Given standard djgpp 2.x and bzip2 installations, this should create a +# version of Zip 3.0 with bzip2 support. Additional information is in +# bzip2/install.txt. +# +# 27 June 2008 + +VPATH=.;msdos +# ------------- djgpp ------------- +CPPFLAGS=-I. -DDOS -DASM_CRC -DBZIP2_SUPPORT $(LOCAL_ZIP) +ASFLAGS=$(CPPFLAGS) +CFLAGS=-Wall -O2 $(CPPFLAGS) +UTILFLAGS=-c -DUTIL $(CFLAGS) -o +CC=gcc +LD=gcc +LDFLAGS=-s + +# ------------- file packer -------- +# Laszlo Molnar who wrote DJ Packer and Markus F. X. J. Oberhumer who wrote +# the compression library used by the DJ Packer have collaborated on the +# Ultimate Packer for eXecutables, which has recently been released. Look +# for upx???d.zip at http://upx.sourceforge.net +# As an alternative, look for "djp.exe", now two years old, in the archive +# mlp107[b,s].zip, found in the same location as csdpmi?[b,s].zip (see below). +# If you have got an executable packer in your PATH, you may reduce the +# size of the disk image of the zip*.exe's by uncommenting the lines +# containing $(DJP) below where the exe's are built. +#DJP=djp -q +DJP=upx -qq --best + +# variables + +#set CRC32 to crc_gcc.o or nothing, depending on whether ASM_CRC is defined: +CRCA_O = crc_gcc.o + +OBJZ = zip.o crypt.o ttyio.o zipfile.o zipup.o fileio.o util.o \ + crc32.o $(CRCA_O) globals.o +OBJI = deflate.o trees.o match.o msdos.o +OBJU = zipfile_.o fileio_.o util_.o globals.o msdos_.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o crc32_.o crypt_.o ttyio.o $(OBJU) +OBJS = zipsplit.o $(OBJU) +LIBS = -lbz2 + +ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h + +# rules + +.SUFFIXES: # Delete make's default suffix list +.SUFFIXES: .exe .out .a .ln .o .c .cc .C .p .f .F .y .l .s .S .h + +.c.o: + $(CC) -c $(CFLAGS) $< -o $@ + +zips: zip.exe zipnote.exe zipsplit.exe zipcloak.exe + +zip.o: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + +zipfile.o: zipfile.c $(ZIP_H) crc32.h + +zipup.o: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h + +fileio.o: fileio.c $(ZIP_H) crc32.h + +util.o: util.c $(ZIP_H) + +globals.o: globals.c $(ZIP_H) + +deflate.o: deflate.c $(ZIP_H) + +trees.o: trees.c $(ZIP_H) + +crc_gcc.o: crc_i386.S + $(CC) $(ASFLAGS) -x assembler-with-cpp -c -o $@ crc_i386.S + +crc32.o: crc32.c $(ZIP_H) crc32.h + +crypt.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + +ttyio.o: ttyio.c $(ZIP_H) crypt.h ttyio.h + +msdos.o: msdos/msdos.c $(ZIP_H) + +zipcloak.o: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + +zipnote.o: zipnote.c $(ZIP_H) revision.h + +zipsplit.o: zipsplit.c $(ZIP_H) revision.h + +zipfile_.o: zipfile.c $(ZIP_H) crc32.h + $(CC) $(UTILFLAGS) $@ zipfile.c + +fileio_.o: fileio.c $(ZIP_H) crc32.h + $(CC) $(UTILFLAGS) $@ fileio.c + +util_.o: util.c $(ZIP_H) + $(CC) $(UTILFLAGS) $@ util.c + +crc32_.o: crc32.c $(ZIP_H) crc32.h + $(CC) $(UTILFLAGS) $@ crc32.c + +crypt_.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) $(UTILFLAGS) $@ crypt.c + +msdos_.o: msdos/msdos.c $(ZIP_H) + $(CC) $(UTILFLAGS) $@ msdos/msdos.c + + +match.o: match.S + $(CC) $(ASFLAGS) -x assembler-with-cpp -c -o $@ match.S + +zip.exe: $(OBJZ) $(OBJI) + echo $(OBJZ) > zip.rsp + echo $(OBJI) >> zip.rsp + echo $(LIBS) >> zip.rsp + $(LD) $(LDFLAGS) -o $@ @zip.rsp + del zip.rsp +# stubedit $@ dpmi=cwsdpmi.exe +# $(DJP) $@ + +zipcloak.exe: $(OBJC) + $(LD) $(LDFLAGS) $(OBJC) -o $@ +# stubedit $@ dpmi=cwsdpmi.exe +# $(DJP) $@ + +zipnote.exe: $(OBJN) + $(LD) $(LDFLAGS) $(OBJN) -o $@ +# stubedit $@ dpmi=cwsdpmi.exe +# $(DJP) $@ + +zipsplit.exe: $(OBJS) + $(LD) $(LDFLAGS) $(OBJS) -o $@ +# stubedit $@ dpmi=cwsdpmi.exe +# $(DJP) $@ + +# These stand alone executables require dpmi services to run. When +# running in a DOS window under windows 3.1 or later, the dpmi server +# is automatically present. Under DOS, if a dpmi server is not installed, +# by default the program will look for "cwsdpmi.exe." If found, it will +# be loaded for the duration of the program. +# cwsdpmi is a "free" dpmi server written by Charles W. Sandmann +# (sandman@clio.rice.edu). It may be found, among other sites, on SimTel +# and its mirrors in the .../vendors/djgpp/v2misc directory. diff --git a/msdos/makefile.bor b/msdos/makefile.bor new file mode 100644 index 0000000..88ecde4 --- /dev/null +++ b/msdos/makefile.bor @@ -0,0 +1,197 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for +# Borland (Turbo) C++ 1.0 or 2.0. +# Warning: this file is not suitable for Turbo C 2.0. Use makefile.tc instead. + +# To use, do "make -fmakefile.bor" + +# WARNING: the small model is not supported. +# Add -DSMALL_MEM or -DMEDIUM_MEM to the LOC macro if you wish to reduce +# the memory requirements. +# Add -DNO_ASM to CFLAGS and comment out the ASMOBJS definition if +# you do not have tasm. + +# Optional nonstandard preprocessor flags (as -DMEDIUM_MEM or -DNO_ASM) +# should be added to the environment via "set LOCAL_ZIP=-DFOO" or added +# to the declaration of LOC here: +LOC = -DDOS -DNO_SECURE_TESTS $(LOCAL_ZIP) + +# Zip requires compact or large memory model. +# with 2.1, compact model exceeds 64k code segment; use large model +ZIPMODEL=l # large model for Zip and ZipUtils + +# name of Flag to select memory model for assembler compiles, supported +# values are __SMALL__ , __MEDIUM__ , __COMPACT__ , __LARGE__ : +ASMODEL=__LARGE__ # keep in sync with ZIPMODEL definition !! + +# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc. +CPU_TYP = 0 + +# Uncomment the following macro to use the optimized assembler +# routines in Zip: +CRCA_O = crc_i86.obj +ASMOBJS = match.obj $(CRCA_O) + +ASCPUFLAG = __$(CPU_TYP)86 +!if $(CPU_TYP) != 0 +CC_CPUFLG = -$(CPU_TYP) +!endif + +VPATH=.;msdos +# ------------- Turbo C++, Borland C++ ------------- +!if $(CC_REV) == 1 +CC = tcc +!else +! if !$(CC_REV) +CC_REV = 3 +! endif +CC = bcc +!endif + +MODEL=-m$(ZIPMODEL) +!if $(CC_REV) == 1 +CFLAGS=-w -w-eff -w-def -w-sig -w-cln -a -d -G -O -Z $(CC_CPUFLG) $(MODEL) $(LOC) +!else +CFLAGS=-w -w-cln -O2 -Z $(CC_CPUFLG) $(MODEL) $(LOC) +!endif +UTILFLAGS=-DUTIL $(CFLAGS) -o +# for Turbo C++ 1.0, replace bcc with tcc and use the upper version of CFLAGS + +AS=tasm +ASFLAGS=-ml -t -m2 -DDYN_ALLOC -DSS_NEQ_DS -D$(ASCPUFLAG) -D$(ASMODEL) $(LOC) + +LD=$(CC) +LDFLAGS=$(MODEL) + +# ------------- Common declarations: +STRIP=@rem +# If you don't have UPX, LZEXE, or PKLITE, get one of them. Then define: +# (NOTE: upx needs a 386 or higher system to run the exe compressor) +#STRIP=upx --8086 --best +# or +#STRIP=lzexe +# or (if you've registered PKLITE) +#STRIP=pklite +# This makes a big difference in .exe size (and possibly load time) + +# ------------- Used by install rule +# set BIN to the directory you want to install the executables to +BIN = c:\util + +# variables +OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \ + crc32.obj globals.obj + +OBJI = deflate.obj trees.obj $(ASMOBJS) msdos.obj + +OBJU = zipfile_.obj fileio_.obj util_.obj globals.obj msdos_.obj +OBJN = zipnote.obj $(OBJU) +OBJC = zipcloak.obj crc32_.obj crypt_.obj ttyio.obj $(OBJU) +OBJS = zipsplit.obj $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h + +ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe + +zips: $(ZIPS) + +zip.obj: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +zipfile.obj: zipfile.c $(ZIP_H) crc32.h + $(CC) -c $(CFLAGS) $*.c + +zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h + $(CC) -c $(CFLAGS) $*.c + +fileio.obj: fileio.c $(ZIP_H) crc32.h + $(CC) -c $(CFLAGS) $*.c + +util.obj: util.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +globals.obj: globals.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c $(ZIP_H) crc32.h + $(CC) -c $(CFLAGS) $*.c + +crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +msdos.obj: msdos/msdos.c $(ZIP_H) + $(CC) -c $(CFLAGS) msdos/$*.c + +zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +zipnote.obj: zipnote.c $(ZIP_H) revision.h + $(CC) -c $(CFLAGS) $*.c + +zipsplit.obj: zipsplit.c $(ZIP_H) revision.h + $(CC) -c $(CFLAGS) $*.c + +zipfile_.obj: zipfile.c $(ZIP_H) crc32.h + $(CC) -c $(UTILFLAGS)$* zipfile.c + +fileio_.obj: fileio.c $(ZIP_H) crc32.h + $(CC) -c $(UTILFLAGS)$* fileio.c + +util_.obj: util.c $(ZIP_H) + $(CC) -c $(UTILFLAGS)$* util.c + +crc32_.obj: crc32.c $(ZIP_H) crc32.h + $(CC) -c $(UTILFLAGS) crc32.c + +crypt_.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) -c $(UTILFLAGS)$* crypt.c + +msdos_.obj: msdos/msdos.c $(ZIP_H) + $(CC) -c $(UTILFLAGS)$* msdos/msdos.c + +crc_i86.obj: msdos/crc_i86.asm + $(AS) $(ASFLAGS) msdos\crc_i86.asm ; + +match.obj: msdos/match.asm + $(AS) $(ASFLAGS) msdos\match.asm ; + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +zip.exe: $(OBJZ) $(OBJI) + echo $(OBJZ) > zip.rsp + echo $(OBJI) >> zip.rsp + $(LD) $(LDFLAGS) @zip.rsp + del zip.rsp + $(STRIP) zip.exe + +zipcloak.exe: $(OBJC) + echo $(OBJC) > zipc.rsp + $(LD) $(LDFLAGS) @zipc.rsp + del zipc.rsp + $(STRIP) zipcloak.exe + +zipnote.exe: $(OBJN) + echo $(OBJN) > zipn.rsp + $(LD) $(LDFLAGS) @zipn.rsp + del zipn.rsp + $(STRIP) zipnote.exe + +zipsplit.exe: $(OBJS) + echo $(OBJS) > zips.rsp + $(LD) $(LDFLAGS) @zips.rsp + del zips.rsp + $(STRIP) zipsplit.exe + +install: $(ZIPS) + copy /b *.exe $(BIN) + +clean: + del *.obj + del *.exe diff --git a/msdos/makefile.dj1 b/msdos/makefile.dj1 new file mode 100644 index 0000000..05137cc --- /dev/null +++ b/msdos/makefile.dj1 @@ -0,0 +1,126 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for +# djgpp 1.x +VPATH=.;msdos +# ------------- djgpp ------------- +CPPFLAGS=-I. -DDOS -DASM_CRC $(LOCAL_ZIP) +ASFLAGS=$(CPPFLAGS) +CFLAGS=-Wall -O2 -m486 $(CPPFLAGS) +UTILFLAGS=-c -DUTIL $(CFLAGS) -o +CC=gcc +LD=gcc +LDFLAGS=-s + +STRIP=strip + +# Change the STUBIFY definition to the upper version if you want to create +# executables which can be used without any external extender file. +# >>> NOTE: Either copy the go32 extender into your build directory, or +# >>> edit the STUBIFY macro and add the correct path to "go32.exe". +#STUBIFY=coff2exe -s go32.exe +STUBIFY=coff2exe + +# variables + +#set CRCA_O to crc_gcc.o or nothing, depending on whether ASM_CRC is defined: +CRCA_O = crc_gcc.o + +OBJZ = zip.o crypt.o ttyio.o zipfile.o zipup.o fileio.o util.o \ + crc32.o $(CRCA_O) globals.o +OBJI = deflate.o trees.o match.o msdos.o +OBJU = zipfile_.o fileio_.o util_.o globals.o msdos_.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o crc32_.o crypt_.o ttyio.o $(OBJU) +OBJS = zipsplit.o $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h + +# rules + +.SUFFIXES: # Delete make's default suffix list +.SUFFIXES: .exe .out .a .ln .o .c .cc .C .p .f .F .y .l .s .S .h + +.c.o: + $(CC) -c $(CFLAGS) $< -o $@ + +zips: zip.exe zipnote.exe zipsplit.exe zipcloak.exe + +zip.o: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + +zipfile.o: zipfile.c $(ZIP_H) crc32.h + +zipup.o: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h + +fileio.o: fileio.c $(ZIP_H) + +util.o: util.c $(ZIP_H) + +globals.o: globals.c $(ZIP_H) + +deflate.o: deflate.c $(ZIP_H) + +trees.o: trees.c $(ZIP_H) + +crc_gcc.o: crc_i386.S + $(CC) $(ASFLAGS) -x assembler-with-cpp -c -o $@ crc_i386.S + +crc32.o: crc32.c $(ZIP_H) crc32.h + +crypt.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + +ttyio.o: ttyio.c $(ZIP_H) crypt.h ttyio.h + +msdos.o: msdos/msdos.c $(ZIP_H) + +zipcloak.o: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + +zipnote.o: zipnote.c $(ZIP_H) revision.h + +zipsplit.o: zipsplit.c $(ZIP_H) revision.h + +zipfile_.o: zipfile.c $(ZIP_H) crc32.h + $(CC) $(UTILFLAGS) $@ zipfile.c + +fileio_.o: fileio.c $(ZIP_H) crc32.h + $(CC) $(UTILFLAGS) $@ fileio.c + +util_.o: util.c $(ZIP_H) + $(CC) $(UTILFLAGS) $@ util.c + +crc32_.o: crc32.c $(ZIP_H) crc32.h + $(CC) $(UTILFLAGS) $@ crc32.c + +crypt_.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) $(UTILFLAGS) $@ crypt.c + +msdos_.o: msdos/msdos.c $(ZIP_H) + $(CC) $(UTILFLAGS) $@ msdos/msdos.c + +match.o: match.S + $(CC) $(ASFLAGS) -x assembler-with-cpp -c -o $@ match.S + +zip.exe: $(OBJZ) $(OBJI) + echo $(OBJZ) > zip.rsp + echo $(OBJI) >> zip.rsp + $(LD) $(LDFLAGS) -o zip @zip.rsp + del zip.rsp + $(STRIP) zip + $(STUBIFY) zip + del zip + +zipcloak.exe: $(OBJC) + $(LD) $(LDFLAGS) $(OBJC) -o zipcloak + $(STRIP) zipcloak + $(STUBIFY) zipcloak + del zipcloak + +zipnote.exe: $(OBJN) + $(LD) $(LDFLAGS) $(OBJN) -o zipnote + $(STRIP) zipnote + $(STUBIFY) zipnote + del zipnote + +zipsplit.exe: $(OBJS) + $(LD) $(LDFLAGS) $(OBJS) -o zipsplit + $(STRIP) zipsplit + $(STUBIFY) zipsplit + del zipsplit diff --git a/msdos/makefile.dj2 b/msdos/makefile.dj2 new file mode 100644 index 0000000..39192ee --- /dev/null +++ b/msdos/makefile.dj2 @@ -0,0 +1,136 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for +# djgpp 2.x +VPATH=.;msdos +# ------------- djgpp ------------- +CPPFLAGS=-I. -DDOS -DASM_CRC $(LOCAL_ZIP) +ASFLAGS=$(CPPFLAGS) +CFLAGS=-Wall -O2 $(CPPFLAGS) +UTILFLAGS=-c -DUTIL $(CFLAGS) -o +CC=gcc +LD=gcc +LDFLAGS=-s + +# ------------- file packer -------- +# Laszlo Molnar who wrote DJ Packer and Markus F. X. J. Oberhumer who wrote +# the compression library used by the DJ Packer have collaborated on the +# Ultimate Packer for eXecutables, which has recently been released. Look +# for upx???d.zip at http://upx.sourceforge.net +# As an alternative, look for "djp.exe", now two years old, in the archive +# mlp107[b,s].zip, found in the same location as csdpmi?[b,s].zip (see below). +# If you have got an executable packer in your PATH, you may reduce the +# size of the disk image of the zip*.exe's by uncommenting the lines +# containing $(DJP) below where the exe's are built. +#DJP=djp -q +DJP=upx -qq --best + +# variables + +#set CRC32 to crc_gcc.o or nothing, depending on whether ASM_CRC is defined: +CRCA_O = crc_gcc.o + +OBJZ = zip.o crypt.o ttyio.o zipfile.o zipup.o fileio.o util.o \ + crc32.o $(CRCA_O) globals.o +OBJI = deflate.o trees.o match.o msdos.o +OBJU = zipfile_.o fileio_.o util_.o globals.o msdos_.o +OBJN = zipnote.o $(OBJU) +OBJC = zipcloak.o crc32_.o crypt_.o ttyio.o $(OBJU) +OBJS = zipsplit.o $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h + +# rules + +.SUFFIXES: # Delete make's default suffix list +.SUFFIXES: .exe .out .a .ln .o .c .cc .C .p .f .F .y .l .s .S .h + +.c.o: + $(CC) -c $(CFLAGS) $< -o $@ + +zips: zip.exe zipnote.exe zipsplit.exe zipcloak.exe + +zip.o: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + +zipfile.o: zipfile.c $(ZIP_H) crc32.h + +zipup.o: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h + +fileio.o: fileio.c $(ZIP_H) crc32.h + +util.o: util.c $(ZIP_H) + +globals.o: globals.c $(ZIP_H) + +deflate.o: deflate.c $(ZIP_H) + +trees.o: trees.c $(ZIP_H) + +crc_gcc.o: crc_i386.S + $(CC) $(ASFLAGS) -x assembler-with-cpp -c -o $@ crc_i386.S + +crc32.o: crc32.c $(ZIP_H) crc32.h + +crypt.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + +ttyio.o: ttyio.c $(ZIP_H) crypt.h ttyio.h + +msdos.o: msdos/msdos.c $(ZIP_H) + +zipcloak.o: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + +zipnote.o: zipnote.c $(ZIP_H) revision.h + +zipsplit.o: zipsplit.c $(ZIP_H) revision.h + +zipfile_.o: zipfile.c $(ZIP_H) crc32.h + $(CC) $(UTILFLAGS) $@ zipfile.c + +fileio_.o: fileio.c $(ZIP_H) crc32.h + $(CC) $(UTILFLAGS) $@ fileio.c + +util_.o: util.c $(ZIP_H) + $(CC) $(UTILFLAGS) $@ util.c + +crc32_.o: crc32.c $(ZIP_H) crc32.h + $(CC) $(UTILFLAGS) $@ crc32.c + +crypt_.o: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) $(UTILFLAGS) $@ crypt.c + +msdos_.o: msdos/msdos.c $(ZIP_H) + $(CC) $(UTILFLAGS) $@ msdos/msdos.c + + +match.o: match.S + $(CC) $(ASFLAGS) -x assembler-with-cpp -c -o $@ match.S + +zip.exe: $(OBJZ) $(OBJI) + echo $(OBJZ) > zip.rsp + echo $(OBJI) >> zip.rsp + $(LD) $(LDFLAGS) -o $@ @zip.rsp + del zip.rsp +# stubedit $@ dpmi=cwsdpmi.exe +# $(DJP) $@ + +zipcloak.exe: $(OBJC) + $(LD) $(LDFLAGS) $(OBJC) -o $@ +# stubedit $@ dpmi=cwsdpmi.exe +# $(DJP) $@ + +zipnote.exe: $(OBJN) + $(LD) $(LDFLAGS) $(OBJN) -o $@ +# stubedit $@ dpmi=cwsdpmi.exe +# $(DJP) $@ + +zipsplit.exe: $(OBJS) + $(LD) $(LDFLAGS) $(OBJS) -o $@ +# stubedit $@ dpmi=cwsdpmi.exe +# $(DJP) $@ + +# These stand alone executables require dpmi services to run. When +# running in a DOS window under windows 3.1 or later, the dpmi server +# is automatically present. Under DOS, if a dpmi server is not installed, +# by default the program will look for "cwsdpmi.exe." If found, it will +# be loaded for the duration of the program. +# cwsdpmi is a "free" dpmi server written by Charles W. Sandmann +# (sandman@clio.rice.edu). It may be found, among other sites, on SimTel +# and its mirrors in the .../vendors/djgpp/v2misc directory. diff --git a/msdos/makefile.emx b/msdos/makefile.emx new file mode 100644 index 0000000..3a50b5b --- /dev/null +++ b/msdos/makefile.emx @@ -0,0 +1,169 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit +# using emx 0.9c for DOS. +# By Kai-Uwe Rommel, Chr. Spieler, E-Yen Tan (and others). +# Last updated 7th January 2007. +# +# This Makefile is a stripped down version of win32/Makefile.emx that +# builds executables applying the default MSDOS emx setup. For variant +# targets (using zlib), and cross-compilation for WIN32 or OS/2, take a +# look into "win32/makefile.emx" resp. "os2/makefile.os2". +# +# Supported Make utilities: +# - Microsoft/IBM nmake (e.g. from MSC 6.0 or newer) +# - dmake 3.8 or higher +# - GNU make, at least version 3.68 (GNUish 16-bit port, RSXNT Make 3.75 in a +# Win95/WinNT DOS box, DJGPP v1.12 Make 3.71, some versions of DJGPP v2.x +# 32-bit Make; current DJGPP v2.01 Make 3.76.1 does NOT work) +# - NOT watcom make +# The "smart" Make utilities mentioned below are Christian Spieler's +# enhanced version of GNUish 16-bit Make (3.74) and his adaption of these +# GNU Make sources to EMX (32-bit). + +# Supported 32-bit C Compilers for MSDOS: +# - GNU gcc (emx kit 0.9c or newer, 32-bit) + +# Supported Assemblers: +# - GNU as with GNU gcc + + +# To use, enter "make/nmake/dmake -f msdos/makefile.emx" +# (this makefile depends on its name being "msdos/makefile.emx"). + +# emx 0.9c, gcc, a.out format, for MS-DOS +CC=gcc -O2 -m486 -Wall +CFLAGS=-DDOS -DMSDOS -DASM_CRC +AS=gcc +ASFLAGS=-Di386 +LDFLAGS=-o ./ +LDFLAGS2=-s -Zsmall-conv +OUT=-o +OBJ=.o +CRCA_O=crc_gcc.o +OBJA=matchgcc.o +OBJZS=msdos.o +OBJUS=msdos_.o +OSDEP_H=msdos/osdep.h +ZIPUP_H=msdos/zipup.h + +#default settings for target dependent macros: +DIRSEP = / +AS_DIRSEP = / +RM = del +LOCAL_OPTS = $(LOCAL_ZIP) +CCFLAGS = $(CFLAGS) $(LOCAL_OPTS) + + +OBJZ1 = zip$(OBJ) zipfile$(OBJ) zipup$(OBJ) fileio$(OBJ) util$(OBJ) \ + crc32$(OBJ) $(CRCA_O) +OBJZ2 = globals$(OBJ) deflate$(OBJ) trees$(OBJ) crypt$(OBJ) \ + ttyio$(OBJ) +OBJZ = $(OBJZ1) $(OBJZ2) $(OBJZS) $(OBJA) + +OBJU1 = zipfile_$(OBJ) fileio_$(OBJ) util_$(OBJ) globals$(OBJ) +OBJU = $(OBJU1) $(OBJUS) + +OBJN = zipnote$(OBJ) $(OBJU) +OBJS = zipsplit$(OBJ) $(OBJU) +OBJC1 = zipcloak$(OBJ) crc32_$(OBJ) crypt_$(OBJ) ttyio$(OBJ) +OBJC = $(OBJC1) $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h $(OSDEP_H) + +# rules + +.SUFFIXES: .c $(OBJ) + +.c$(OBJ): + $(CC) -c -I. $(CCFLAGS) $(OUT)$@ $< + +# targets + +all: zip.exe zipnote.exe zipsplit.exe zipcloak.exe + +zip$(OBJ): zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +zipfile$(OBJ): zipfile.c $(ZIP_H) crc32.h +zipup$(OBJ): zipup.c $(ZIP_H) revision.h crc32.h crypt.h $(ZIPUP_H) +fileio$(OBJ): fileio.c $(ZIP_H) crc32.h +util$(OBJ): util.c $(ZIP_H) +globals$(OBJ): globals.c $(ZIP_H) +deflate$(OBJ): deflate.c $(ZIP_H) +trees$(OBJ): trees.c $(ZIP_H) +crc32$(OBJ): crc32.c $(ZIP_H) crc32.h +crypt$(OBJ): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h +ttyio$(OBJ): ttyio.c $(ZIP_H) crypt.h ttyio.h + +msdos$(OBJ): msdos/msdos.c $(ZIP_H) + $(CC) -c -I. $(CCFLAGS) msdos$(DIRSEP)msdos.c + +win32zip$(OBJ): win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h + $(CC) -c -I. $(CCFLAGS) win32$(DIRSEP)win32zip.c + +win32$(OBJ): win32/win32.c $(ZIP_H) win32/win32zip.h + $(CC) -c -I. $(CCFLAGS) win32$(DIRSEP)win32.c + +nt$(OBJ): win32/nt.c $(ZIP_H) win32/nt.h + $(CC) -c -I. $(CCFLAGS) win32$(DIRSEP)nt.c + +crc_gcc$(OBJ): crc_i386.S # 32bit, GNU AS + $(AS) $(ASFLAGS) -x assembler-with-cpp -c -o $@ crc_i386.S + +matchgcc$(OBJ): match.S + $(AS) $(ASFLAGS) -x assembler-with-cpp -c -o $@ match.S + +zipcloak$(OBJ): zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +zipnote$(OBJ): zipnote.c $(ZIP_H) revision.h +zipsplit$(OBJ): zipsplit.c $(ZIP_H) revision.h + +zipfile_$(OBJ): zipfile.c $(ZIP_H) crc32.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ zipfile.c + +fileio_$(OBJ): fileio.c $(ZIP_H) crc32.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ fileio.c + +util_$(OBJ): util.c $(ZIP_H) + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ util.c + +crc32_$(OBJ): crc32.c $(ZIP_H) crc32.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ crc32.c + +crypt_$(OBJ): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ crypt.c + +msdos_$(OBJ): msdos/msdos.c $(ZIP_H) + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ msdos$(DIRSEP)msdos.c + +win32_$(OBJ): win32/win32.c $(ZIP_H) win32/win32zip.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ win32$(DIRSEP)win32.c + +# This next bit is nasty, but is needed to overcome the MS-DOS command +# line limit as response files for emx's gcc seem to only work if each +# file is on a different line. DJGPP doesn't do this (if you are at all +# interested). + +zip.exe: $(OBJZ) +# for DUMB make utilities, uncomment the following commands: + -@$(RM) zip.rsp + @for %%f in ($(OBJZ1)) do echo %%f >> zip.rsp + @for %%f in ($(OBJZ2)) do echo %%f >> zip.rsp + @for %%f in ($(OBJZS) $(OBJA)) do echo %%f >> zip.rsp + $(CC) $(LDFLAGS)$@ @zip.rsp $(LDFLAGS2) + @$(RM) zip.rsp +# smart make utilities (like well done ports of GNU Make) can use this: +# $(CC) $(LDFLAGS)$@ $(OBJZ) $(LDFLAGS2) + +zipcloak.exe: $(OBJC) +# for DUMB make utilities, uncomment the following commands: + -@$(RM) zipcloak.rsp + @for %%f in ($(OBJC1)) do echo %%f >> zipcloak.rsp + @for %%f in ($(OBJU1)) do echo %%f >> zipcloak.rsp + @for %%f in ($(OBJUS)) do echo %%f >> zipcloak.rsp + $(CC) $(LDFLAGS)$@ @zipcloak.rsp $(LDFLAGS2) + @$(RM) zipcloak.rsp +# smart make utilities (like well done ports of GNU Make) can use this: +# $(CC) $(LDFLAGS)$@ $(OBJC) $(LDFLAGS2) + +zipnote.exe: $(OBJN) + $(CC) $(LDFLAGS)$@ $(OBJN) $(LDFLAGS2) + +zipsplit.exe: $(OBJS) + $(CC) $(LDFLAGS)$@ $(OBJS) $(LDFLAGS2) diff --git a/msdos/makefile.msc b/msdos/makefile.msc new file mode 100644 index 0000000..a7ec9c9 --- /dev/null +++ b/msdos/makefile.msc @@ -0,0 +1,209 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for +# Microsoft C 5.1 and above. + +# To use, do "make makefile.msc" + +# Add -DSMALL_MEM or -DMEDIUM_MEM to the LOC macro if you wish to reduce +# the memory requirements. +# Add -DNO_ASM to CFLAGS and comment out the ASMOBJS definition if +# you do not have masm. +# +# If you want link Zip against zlib to replace the built-in deflate routines, +# the following changes are required: +# - in the definition of "LOC", add "-DUSE_ZLIB" and remove "-DNO_SECURE_TESTS" +# - comment out the "ASMOBJS" symbol definition +# - modify the linking command blocks for zip and zipcloak according to +# the following scheme: +# add a command line "echo ,,,zlib_$(ZIPMODEL); >> zip[c].rsp" just +# before the "$(LD)..." line; and remove the semicolon character from the +# "echo ..." line immediately preceding the just inserted command + + +# Optional nonstandard preprocessor flags (as -DMEDIUM_MEM or -DNO_ASM) +# should be added to the environment via "set LOCAL_ZIP=-DFOO" or added +# to the declaration of LOC here: +LOC = -DDOS -DDYN_ALLOC -DNO_SECURE_TESTS $(LOCAL_ZIP) + +# Zip requires compact or large memory model. +# with 2.1, compact model exceeds 64k code segment; use large model +ZIPMODEL=L # large model for Zip and ZipUtils + +# name of Flag to select memory model for assembler compiles, supported +# values are __SMALL__ , __MEDIUM__ , __COMPACT__ , __LARGE__ : +ASMODEL=__LARGE__ # keep in sync with ZIPMODEL definition !! + +# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc. +CPU_TYP = 0 + +# Uncomment the following macro to use the optimized assembler +# routines in Zip: +ASMOBJS = match.obj crc_i86.obj + +ASCPUFLAG = __$(CPU_TYP)86 + +# ------------- Microsoft C 5.1, 6.0, 7.0 and VC++ Pro 1.0 ------------- +CC=cl +MODEL=-A$(ZIPMODEL) +FP= +# With the feature additions of Zip 3, the default data segment gets occupied +# with too much initialized data to fit into 64k. As a workaround, for some +# source files with large amount of message strings, -Gt is used to +# force data items of size or larger into their own data segments. +COMMON_CFLAGS=-nologo -I. $(MODEL) $(FP) -DMSC $(LOC) -W3 -G$(CPU_TYP) +CFLAGS=$(COMMON_CFLAGS) -Ox +SPECFLAGS=$(COMMON_CFLAGS) -Oaict -Gs +# For MSC/C++ 7.0 and VC++ no special flags are needed: +# SPECFLAGS=$(CFLAGS) +UTILFLAGS=-DUTIL $(CFLAGS) -Fo + +AS=masm +ASFLAGS=-ml -t -D$(ASCPUFLAG) -D$(ASMODEL) $(LOC) +# For MSC 6.0, use: +#AS=ml +#ASFLAGS=-c -D$(ASCPUFLAG) -D$(ASMODEL) $(LOC) +# Supress -DDYN_ALLOC in ASFLAGS if you have suppressed it in CFLAGS + +LD=link +LDFLAGS=/noi/farcall/packcode/e/st:0x1400/m +# If you use an exe packer as recommended below, remove /e from LDFLAGS + +# ------------- Common declarations: +STRIP=rem +# If you don't have UPX, LZEXE, or PKLITE, get one of them. Then define: +# (NOTE: upx needs a 386 or higher system to run the exe compressor) +#STRIP=upx --8086 --best +# or +#STRIP=lzexe +# or (if you've registered PKLITE) +#STRIP=pklite +# and remove /e from LDFLAGS. +# This makes a big difference in .exe size (and possibly load time) + +# ------------- Used by install rule +# set BIN to the directory you want to install the executables to +BIN = c:\util + +# variables +OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \ + crc32.obj globals.obj + +OBJI = deflate.obj trees.obj $(ASMOBJS) msdos.obj + +OBJU = zipfile_.obj fileio_.obj util_.obj globals.obj msdos_.obj +OBJN = zipnote.obj $(OBJU) +OBJC = zipcloak.obj crc32_.obj crypt_.obj ttyio.obj $(OBJU) +OBJS = zipsplit.obj $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h + +ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe + +zips: $(ZIPS) + +zip.obj: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + $(CC) -c $(CFLAGS) -Gt65 $*.c + +# MSC 5.1 generates bad code on zipfile with -Ox +zipfile.obj: zipfile.c $(ZIP_H) crc32.h + $(CC) -c $(SPECFLAGS) $*.c + +zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h + $(CC) -c $(CFLAGS) $*.c + +fileio.obj: fileio.c $(ZIP_H) crc32.h + $(CC) -c $(CFLAGS) $*.c + +util.obj: util.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +globals.obj: globals.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c $(ZIP_H) crc32.h + $(CC) -c $(CFLAGS) $*.c + +crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +msdos.obj: msdos/msdos.c $(ZIP_H) + $(CC) -c $(CFLAGS) msdos/$*.c + +zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +zipnote.obj: zipnote.c $(ZIP_H) revision.h + $(CC) -c $(CFLAGS) $*.c + +# MSC 5.1 dies on zipsplit with -Ox +zipsplit.obj: zipsplit.c $(ZIP_H) revision.h + $(CC) -c $(SPECFLAGS) $*.c + +# MSC 5.1 generates bad code on zipfile with -Ox +zipfile_.obj: zipfile.c $(ZIP_H) crc32.h + $(CC) -c $(SPECFLAGS) -DUTIL -Fo$@ zipfile.c + +fileio_.obj: fileio.c $(ZIP_H) crc32.h + $(CC) -c $(UTILFLAGS)$@ fileio.c + +util_.obj: util.c $(ZIP_H) + $(CC) -c $(UTILFLAGS)$@ util.c + +crc32_.obj: crc32.c $(ZIP_H) crc32.h + $(CC) -c $(UTILFLAGS)$@ crc32.c + +crypt_.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) -c $(UTILFLAGS)$@ crypt.c + +msdos_.obj: msdos/msdos.c $(ZIP_H) + $(CC) -c $(UTILFLAGS)$@ msdos/msdos.c + +crc_i86.obj: msdos/crc_i86.asm + $(AS) $(ASFLAGS) msdos\crc_i86.asm ; + +match.obj: msdos/match.asm + $(AS) $(ASFLAGS) msdos\match.asm ; + +# we must cut the command line to fit in the MS/DOS 128 byte limit: +zip.exe: $(OBJZ) $(OBJI) + echo $(OBJZ)+ > zip.rsp + echo $(OBJI); >> zip.rsp + $(LD) $(LDFLAGS) @zip.rsp + del zip.rsp + $(STRIP) zip.exe + +zipcloak.exe: $(OBJC) + echo $(OBJC); > zipc.rsp + $(LD) $(LDFLAGS) @zipc.rsp + del zipc.rsp + $(STRIP) zipcloak.exe + +zipnote.exe: $(OBJN) + echo $(OBJN); > zipn.rsp + $(LD) $(LDFLAGS) @zipn.rsp + del zipn.rsp + $(STRIP) zipnote.exe + +zipsplit.exe: $(OBJS) + echo $(OBJS); > zips.rsp + $(LD) $(LDFLAGS) @zips.rsp + del zips.rsp + $(STRIP) zipsplit.exe + +# No `install' and `clean' target possible as long as MSC's old MAKE utility +# is supported (MSC 5.1 Make always tries to update ALL targets. The result +# is that install and clean are always executed, unless an error occured.) +#install: $(ZIPS) +# copy /b *.exe $(BIN) +# +#clean: +# del *.obj +# del *.exe diff --git a/msdos/makefile.tc b/msdos/makefile.tc new file mode 100644 index 0000000..9ce3e32 --- /dev/null +++ b/msdos/makefile.tc @@ -0,0 +1,177 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit for +# Turbo C 2.0. (Thanks to Andrew Cadach ) + +# To use, do "make -fmakefile.tc" + +# WARNING: the small model is not supported. You must use the large model. +# Add -DSMALL_MEM or -DMEDIUM_MEM to the LOC macro if you wish to reduce +# the memory requirements. +# Add -DNO_ASM to CFLAGS and comment out the ASMOBJS definition if +# you do not have tasm. + +# Optional nonstandard preprocessor flags (as -DMEDIUM_MEM or -DNO_ASM) +# should be added to the environment via "set LOCAL_ZIP=-DFOO" or added +# to the declaration of LOC here: +LOC = -DDOS -DNO_SECURE_TESTS $(LOCAL_ZIP) + +# Zip requires compact or large memory model. +# with 2.1, compact model exceeds 64k code segment; use large model +ZIPMODEL=l # large model for Zip and ZipUtils + +# name of Flag to select memory model for assembler compiles, supported +# values are __SMALL__ , __MEDIUM__ , __COMPACT__ , __LARGE__ : +ASMODEL=__LARGE__ # keep in sync with ZIPMODEL definition !! + +# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc. +CPU_TYP = 0 + +# Uncomment the following macro to use the optimized assembler +# routines in Zip: +ASMOBJS = match.obj crc_i86.obj + +ASCPUFLAG = __$(CPU_TYP)86 + +# ------------- Turbo C 2.0 ------------- +MODEL=-m$(ZIPMODEL) +CFLAGS=-w -w-eff -w-def -w-sig -w-cln -a -d -G -O -Z $(MODEL) $(LOC) +UTILFLAGS=-DUTIL $(CFLAGS) -o +CC=tcc + +# Old versions of tasm (prior to 2.01) may not like the "-m2" option... +AS=tasm +ASFLAGS=-ml -t -m2 -DDYN_ALLOC -DSS_NEQ_DS -D$(ASCPUFLAG) -D$(ASMODEL) $(LOC) + +LD=tcc +LDFLAGS=$(MODEL) + +# ------------- Common declarations: +STRIP=rem +# If you don't have UPX, LZEXE, or PKLITE, get one of them. Then define: +# (NOTE: upx needs a 386 or higher system to run the exe compressor) +#STRIP=upx --8086 --best +# or +#STRIP=lzexe +# or (if you've registered PKLITE) +#STRIP=pklite +# This makes a big difference in .exe size (and possibly load time) + +# ------------- Used by install rule +# set BIN to the directory you want to install the executables to +BIN = c:\util + +# variables +OBJZ = zip.obj crypt.obj ttyio.obj zipfile.obj zipup.obj fileio.obj util.obj \ + crc32.obj globals.obj + +OBJI = deflate.obj trees.obj $(ASMOBJS) msdos.obj + +OBJU = _zipfile.obj _fileio.obj _util.obj globals.obj _msdos.obj +OBJN = zipnote.obj $(OBJU) +OBJC = zipcloak.obj _crc32.obj _crypt.obj ttyio.obj $(OBJU) +OBJS = zipsplit.obj $(OBJU) + +ZIP_H = zip.h ziperr.h tailor.h msdos/osdep.h + +ZIPS = zip.exe zipnote.exe zipsplit.exe zipcloak.exe + +zips: $(ZIPS) + +zip.obj: zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +zipfile.obj: zipfile.c $(ZIP_H) crc32.h + $(CC) -c $(CFLAGS) $*.c + +zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos/zipup.h + $(CC) -c $(CFLAGS) $*.c + +fileio.obj: fileio.c $(ZIP_H) crc32.h + $(CC) -c $(CFLAGS) $*.c + +util.obj: util.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +globals.obj: globals.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +deflate.obj: deflate.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +trees.obj: trees.c $(ZIP_H) + $(CC) -c $(CFLAGS) $*.c + +crc32.obj: crc32.c $(ZIP_H) crc32.h + $(CC) -c $(CFLAGS) $*.c + +crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h + $(CC) -c $(CFLAGS) $*.c + +msdos.obj: msdos/msdos.c $(ZIP_H) + $(CC) -c $(CFLAGS) msdos/$*.c + +zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h + $(CC) -c $(CFLAGS) -o$* $*.c + +zipnote.obj: zipnote.c $(ZIP_H) revision.h + $(CC) -c $(CFLAGS) -o$* $*.c + +zipsplit.obj: zipsplit.c $(ZIP_H) revision.h + $(CC) -c $(CFLAGS) -o$* $*.c + +_zipfile.obj: zipfile.c $(ZIP_H) crc32.h + $(CC) -c $(UTILFLAGS)$* zipfile.c + +_fileio.obj: fileio.c $(ZIP_H) crc32.h + $(CC) -c $(UTILFLAGS)$* fileio.c + +_util.obj: util.c $(ZIP_H) + $(CC) -c $(UTILFLAGS)$* util.c + +_crc32.obj: crc32.c $(ZIP_H) crc32.h + $(CC) -c $(UTILFLAGS)$* crc32.c + +_crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) -c $(UTILFLAGS)$* crypt.c + +_msdos.obj: msdos/msdos.c $(ZIP_H) + $(CC) -c $(UTILFLAGS)$* msdos/msdos.c + +crc_i86.obj: msdos/crc_i86.asm + $(AS) $(ASFLAGS) msdos\crc_i86.asm ; + +match.obj: msdos/match.asm + $(AS) $(ASFLAGS) msdos\match.asm ; + +# make sure the command line fits in the MS/DOS 128 byte limit: +zip.exe: $(OBJZ) $(OBJI) + rem ignore any warnings in the following renaming commands: + ren _*.obj _*.ob + ren zipcloak.obj *.ob + ren zipnote.obj *.ob + ren zipsplit.obj *.ob + $(LD) $(LDFLAGS) -ezip.exe *.obj + ren _*.ob _*.obj + ren zip???*.ob *.obj + $(STRIP) zip.exe + +zipcloak.exe: $(OBJC) + $(LD) $(LDFLAGS) -ezipcloak.exe $(OBJC) + $(STRIP) zipcloak.exe + +zipnote.exe: $(OBJN) + $(LD) $(LDFLAGS) -ezipnote.exe $(OBJN) + $(STRIP) zipnote.exe + +zipsplit.exe: $(OBJS) + $(LD) $(LDFLAGS) -ezipsplit.exe $(OBJS) + $(STRIP) zipsplit.exe + +install: $(ZIPS) + copy /b *.exe $(BIN) + +clean: + del *.obj + del *.exe diff --git a/msdos/makefile.wat b/msdos/makefile.wat new file mode 100644 index 0000000..dd4d8cd --- /dev/null +++ b/msdos/makefile.wat @@ -0,0 +1,256 @@ +# WMAKE makefile for 16 bit MSDOS or 32 bit DOS extender (PMODE/W or DOS/4GW) +# using Watcom C/C++ v11.0+, by Paul Kienitz, last revised 07 Aug 2005. +# Makes Zip.exe, ZipNote.exe, ZipCloak.exe, and ZipSplit.exe. +# +# Invoke from Zip source dir with "WMAKE -F MSDOS\MAKEFILE.WAT [targets]" +# To build with debug info use "WMAKE DEBUG=1 ..." +# To build with no assembly modules use "WMAKE NOASM=1 ..." +# To make the PMODE/W version use "WMAKE PM=1 ..." +# To make the DOS/4GW version use "WMAKE GW=1 ..." (overrides PM=1) +# Note: specifying PM or GW without NOASM requires that the win32 source +# directory be present, so it can access the 32 bit assembly sources. +# PMODE/W is recommended over DOS/4GW for best performance. +# To create a low memory usage version of Zip, use "WMAKE WSIZE=8192 ..." +# (or whatever power of two less than 32768 you wish) -- this also causes +# SMALL_MEM to be defined. Compression performance will be reduced. +# This currently is not supported with PM=1 or GW=1. +# +# Other options to be fed to the compiler and assembler can be specified in +# an environment variable called LOCAL_ZIP. + +variation = $(%LOCAL_ZIP) + +# Stifle annoying "Delete this file?" questions when errors occur: +.ERASE + +.EXTENSIONS: +.EXTENSIONS: .exe .obj .c .h .asm + +# We maintain multiple sets of object files in different directories so that +# we can compile msdos, dos/4gw or pmode/w, and win32 versions of Zip without +# their object files interacting. The following var must be a directory name +# ending with a backslash. All object file names must include this macro +# at the beginning, for example "$(O)foo.obj". + +!ifdef GW +PM = 1 # both protected mode formats use the same object files +!endif + +!ifdef DEBUG +! ifdef PM +OBDIR = od32d +! else +! ifdef WSIZE +OBDIR = od16l +size = -DWSIZE=$(WSIZE) -DSMALL_MEM +! else +OBDIR = od16d +size = -DMEDIUM_MEM +! endif +! endif +!else +! ifdef PM +OBDIR = ob32d +! else +! ifdef WSIZE +OBDIR = ob16l +size = -DWSIZE=$(WSIZE) -DSMALL_MEM +! else +OBDIR = ob16d +size = -DMEDIUM_MEM +! endif +! endif +!endif +O = $(OBDIR)\ # comment here so backslash won't continue the line + +# The assembly hot-spot code in crc_i[3]86.asm and match[32].asm is +# optional. This section controls its usage. + +!ifdef NOASM + # C source +asmob = +cvars = $+$(cvars)$- -DDYN_ALLOC -DNO_ASM # or ASM_CRC might default on! +# "$+$(foo)$-" means expand foo as it has been defined up to now; normally, +# this make defers inner expansion until the outer macro is expanded. +!else # !NOASM +asmob = $(O)crc.obj $(O)match.obj +! ifdef PM +cvars = $+$(cvars)$- -DASM_CRC -DASMV # no DYN_ALLOC with match32.asm +crc_s = win32\crc_i386.asm # requires that the win32 directory be present +mat_s = win32\match32.asm # ditto +! else +cvars = $+$(cvars)$- -DDYN_ALLOC -DASM_CRC -DASMV +avars = $+$(avars)$- -DDYN_ALLOC +crc_s = msdos\crc_i86.asm +mat_s = msdos\match.asm +! endif +!endif + +# Now we have to pick out the proper compiler and options for it. This gets +# pretty complicated with the PM, GW, DEBUG, and NOASM options... + +link = wlink +asm = wasm + +!ifdef PM +cc = wcc386 +# Use Pentium Pro timings, register args, static strings in code: +cflags = -bt=DOS -mf -6r -zt -zq +aflags = -bt=DOS -mf -3 -zq +cvars = $+$(cvars)$- -DDOS $(variation) +avars = $+$(avars)$- -DWATCOM_DSEG $(variation) + +! ifdef GW +lflags = sys DOS4G +! else +# THIS REQUIRES THAT PMODEW.EXE BE FINDABLE IN THE COMMAND PATH. +# It does NOT require you to add a pmodew entry to wlink.lnk or wlsystem.lnk. +defaultlibs = libpath %WATCOM%\lib386 libpath %WATCOM%\lib386\dos +lflags = format os2 le op osname='PMODE/W' op stub=pmodew.exe $(defaultlibs) +! endif + +!else # plain 16-bit DOS: + +cc = wcc +# Use plain 8086 instructions, large memory model, static strings in code: +cflags = -bt=DOS -ml -0 -zt -zq +aflags = -bt=DOS -ml -0 -zq +cvars = $+$(cvars)$- -DDOS $(size) $(variation) +avars = $+$(avars)$- $(size) $(variation) +lflags = sys DOS +!endif # !PM + +# Specify optimizations, or a nonoptimized debugging version: + +!ifdef DEBUG +cdebug = -od -d2 +ldebug = d w all op symf +!else +! ifdef PM +cdebug = -s -obhikl+rt -oe=100 -zp8 +# -oa helps slightly but might be dangerous. +! else +cdebug = -s -oehiklrt +! endif +ldebug = op el +!endif + +# How to compile most sources: +.c.obj: + $(cc) $(cdebug) $(cflags) $(cvars) $[@ -fo=$@ + +# Our object files. OBJZ is for Zip, OBJC is for ZipCloak, OBJN is for +# ZipNote, and OBJS is for ZipSplit: + +OBJZ2 = $(O)zip.obj $(O)crypt.obj $(O)ttyio.obj $(O)zipfile.obj $(O)zipup.obj +OBJZA = $(OBJZ2) $(O)util.obj $(O)fileio.obj $(O)deflate.obj +OBJZB = $(O)trees.obj $(O)globals.obj $(O)crc32.obj $(asmob) $(O)msdos.obj + +OBJU2 = $(O)zipfile_.obj $(O)fileio_.obj $(O)util_.obj $(O)globals.obj +OBJ_U = $(OBJU2) $(O)msdos_.obj + +OBJC = $(O)zipcloak.obj $(O)crc32_.obj $(O)crypt_.obj $(O)ttyio.obj $(OBJ_U) + +OBJN = $(O)zipnote.obj $(OBJ_U) + +OBJS = $(O)zipsplit.obj $(OBJ_U) + +# Common header files included by all C sources: + +ZIP_H = zip.h ziperr.h tailor.h msdos\osdep.h + + +# HERE WE GO! By default, make all targets: +all: Zip.exe ZipNote.exe ZipCloak.exe ZipSplit.exe + +# Convenient shorthand options for single targets: +z: Zip.exe .SYMBOLIC +n: ZipNote.exe .SYMBOLIC +c: ZipCloak.exe .SYMBOLIC +s: ZipSplit.exe .SYMBOLIC + +Zip.exe: $(OBDIR) $(OBJZA) $(OBJZB) $(OBJV) + set WLK_VA=file {$(OBJZA)} + set WLK_VB=file {$(OBJZB) $(OBJV)} + $(link) $(lflags) $(ldebug) name $@ @WLK_VA @WLK_VB + set WLK_VA= + set WLK_VB= +# We use WLK_VA and WLK_VB to keep the size of each command under 256 chars. + +ZipNote.exe: $(OBDIR) $(OBJN) + set WLK_VAR=file {$(OBJN)} + $(link) $(lflags) $(ldebug) name $@ @WLK_VAR + set WLK_VAR= + +ZipCloak.exe: $(OBDIR) $(OBJC) + set WLK_VAR=file {$(OBJC)} + $(link) $(lflags) $(ldebug) name $@ @WLK_VAR + set WLK_VAR= + +ZipSplit.exe: $(OBDIR) $(OBJS) + set WLK_VAR=file {$(OBJS)} + $(link) $(lflags) $(ldebug) name $@ @WLK_VAR + set WLK_VAR= + +# Source dependencies: + +$(O)crc32.obj: crc32.c $(ZIP_H) crc32.h +$(O)crypt.obj: crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h +$(O)deflate.obj: deflate.c $(ZIP_H) +$(O)fileio.obj: fileio.c $(ZIP_H) crc32.h +$(O)globals.obj: globals.c $(ZIP_H) +$(O)trees.obj: trees.c $(ZIP_H) +$(O)ttyio.obj: ttyio.c $(ZIP_H) crypt.h ttyio.h +$(O)util.obj: util.c $(ZIP_H) +$(O)zip.obj: zip.c $(ZIP_H) crc32.h crypt.h revision.h ttyio.h +$(O)zipfile.obj: zipfile.c $(ZIP_H) crc32.h +$(O)zipup.obj: zipup.c $(ZIP_H) revision.h crc32.h crypt.h msdos\zipup.h +$(O)zipnote.obj: zipnote.c $(ZIP_H) revision.h +$(O)zipcloak.obj: zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +$(O)zipsplit.obj: zipsplit.c $(ZIP_H) revision.h + +# Special case object files: + +$(O)msdos.obj: msdos\msdos.c $(ZIP_H) + $(cc) $(cdebug) $(cflags) $(cvars) msdos\msdos.c -fo=$@ + +$(O)match.obj: $(mat_s) + $(asm) $(aflags) $(avars) $(mat_s) -fo=$@ + +$(O)crc.obj: $(crc_s) + $(asm) $(aflags) $(avars) $(crc_s) -fo=$@ + +# Variant object files for ZipNote, ZipCloak, and ZipSplit: + +$(O)zipfile_.obj: zipfile.c $(ZIP_H) crc32.h + $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL zipfile.c -fo=$@ + +$(O)fileio_.obj: fileio.c $(ZIP_H) crc32.h + $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL fileio.c -fo=$@ + +$(O)util_.obj: util.c $(ZIP_H) + $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL util.c -fo=$@ + +$(O)crc32_.obj: crc32.c $(ZIP_H) crc32.h + $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL crc32.c -fo=$@ + +$(O)crypt_.obj: crypt.c $(ZIP_H) crc32.h crypt.h ttyio.h + $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL crypt.c -fo=$@ + +$(O)msdos_.obj: msdos\msdos.c $(ZIP_H) + $(cc) $(cdebug) $(cflags) $(cvars) -DUTIL msdos\msdos.c -fo=$@ + +# Creation of subdirectory for intermediate files +$(OBDIR): + -mkdir $@ + +# Unwanted file removal: + +clean: .SYMBOLIC + del $(O)*.obj + +cleaner: clean .SYMBOLIC + del Zip.exe + del ZipNote.exe + del ZipCloak.exe + del ZipSplit.exe diff --git a/msdos/match.asm b/msdos/match.asm new file mode 100644 index 0000000..998881e --- /dev/null +++ b/msdos/match.asm @@ -0,0 +1,477 @@ +;=========================================================================== +; Copyright (c) 1990-2008 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 2007-Mar-04 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, all these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +;=========================================================================== +; +; match.asm by Jean-loup Gailly. + +; match.asm, optimized version of longest_match() in deflate.c +; Must be assembled with masm -ml. To be used only with C compact model +; or large model. (For large model, assemble with -D__LARGE__). +; This file is only optional. If you don't have masm or tasm, use the +; C version (add -DNO_ASM to CFLAGS in makefile.msc and remove match.obj +; from OBJI). If you have reduced WSIZE in zip.h, then make sure this is +; assembled with an equivalent -DWSIZE=. +; +; The code has been prepared for two different C compiler calling conventions +; and contains some support for dynamically allocated working space. +; The different environments are selected by two conditional flags: +; DYN_ALLOC : select support for malloc'ed working space +; SS_NEQ_DS : relaxes assumption that stack and default data segments +; are identical +; When SS_NEQ_DS is defined, the code segment is used to store some +; local variables. This (bad) coding practice is very likely to break any +; `segment protection scheme', it will most probably only work for real +; mode programs. +; +; Turbo C 2.0 does not support static allocation of more than 64K bytes per +; file, and does not have SS == DS. So TC and BC++ users must use: +; tasm -ml -DDYN_ALLOC -DSS_NEQ_DS match; +; +; To simplify the code, the option -DDYN_ALLOC is supported for OS/2 +; only if the arrays are guaranteed to have zero offset (allocated by +; halloc). We also require SS==DS. This is satisfied for MSC but not Turbo C. +; +; Per default, test code is included to check if the above requirements are +; fulfilled. This test code can be disabled by defining the compile time +; option flag NO_SECURE_TESTS when compiling for a production executable. +; This shortens the code size (but the performance gain is neglectable). +; The security tests should remain enabled, when a new C compiler +; and/or a new set of compilation options is tried. + + name match + +; Do NOT assemble this source if external crc32 routine from zlib gets used. +; +ifndef USE_ZLIB + +ifdef DEBUG + VERBOSE_INFO EQU 1 +else + ifdef _AS_MSG_ + VERBOSE_INFO EQU 1 + else + VERBOSE_INFO EQU 0 + endif +endif + +ifndef __SMALL__ + ifndef __COMPACT__ + ifndef __MEDIUM__ + ifndef __LARGE__ + ifndef __HUGE__ +; __SMALL__ EQU 1 + endif + endif + endif + endif +endif + +ifdef __HUGE__ +; .MODEL Huge + ifndef @CodeSize + @CodeSize EQU 1 + endif + ifndef @DataSize + @DataSize EQU 1 + endif + Save_DS EQU 1 + if VERBOSE_INFO + if1 + %out Assembling for C, Huge memory model + endif + endif +else + ifdef __LARGE__ +; .MODEL Large + ifndef @CodeSize + @CodeSize EQU 1 + endif + ifndef @DataSize + @DataSize EQU 1 + endif + if VERBOSE_INFO + if1 + %out Assembling for C, Large memory model + endif + endif + else + ifdef __COMPACT__ +; .MODEL Compact + ifndef @CodeSize + @CodeSize EQU 0 + endif + ifndef @DataSize + @DataSize EQU 1 + endif + if VERBOSE_INFO + if1 + %out Assembling for C, Compact memory model + endif + endif + else + ifdef __MEDIUM__ +; .MODEL Medium + ifndef @CodeSize + @CodeSize EQU 1 + endif + ifndef @DataSize + @DataSize EQU 0 + endif + if VERBOSE_INFO + if1 + %out Assembling for C, Medium memory model + endif + endif + else +; .MODEL Small + ifndef @CodeSize + @CodeSize EQU 0 + endif + ifndef @DataSize + @DataSize EQU 0 + endif + if VERBOSE_INFO + if1 + %out Assembling for C, Small memory model + endif + endif + endif + endif + endif +endif + +if @CodeSize + LCOD_OFS EQU 2 +else + LCOD_OFS EQU 0 +endif + +IF @DataSize + LDAT_OFS EQU 2 +else + LDAT_OFS EQU 0 +endif + +ifdef Save_DS +; (di,si,ds)+(size, return address) + SAVE_REGS EQU 6+(4+LCOD_OFS) +else +; (di,si)+(size, return address) + SAVE_REGS EQU 4+(4+LCOD_OFS) +endif + +; +; Selection of the supported CPU instruction set and initialization +; of CPU type related macros: +; +ifdef __586 + Use_286_code EQU 1 + Align_Size EQU 16 ; paragraph alignment on Pentium + Alig_PARA EQU 1 ; paragraph aligned code segment +else +ifdef __486 + Use_286_code EQU 1 + Align_Size EQU 4 ; dword alignment on 32 bit processors + Alig_PARA EQU 1 ; paragraph aligned code segment +else +ifdef __386 + Use_286_code EQU 1 + Align_Size EQU 4 ; dword alignment on 32 bit processors + Alig_PARA EQU 1 ; paragraph aligned code segment +else +ifdef __286 + Use_286_code EQU 1 + Align_Size EQU 2 ; word alignment on 16 bit processors + Alig_PARA EQU 0 ; word aligned code segment +else +ifdef __186 + Use_186_code EQU 1 + Align_Size EQU 2 ; word alignment on 16 bit processors + Alig_PARA EQU 0 ; word aligned code segment +else + Align_Size EQU 2 ; word alignment on 16 bit processors + Alig_PARA EQU 0 ; word aligned code segment +endif ;?__186 +endif ;?__286 +endif ;?__386 +endif ;?__486 +endif ;?__586 + +ifdef Use_286_code + .286 + Have_80x86 EQU 1 +else +ifdef Use_186_code + .186 + Have_80x86 EQU 1 +else + .8086 + Have_80x86 EQU 0 +endif ;?Use_186_code +endif ;?Use_286_code + +ifndef DYN_ALLOC + extrn _prev : word + extrn _window : byte + prev equ _prev ; offset part + window equ _window +endif + +_DATA segment word public 'DATA' + extrn _nice_match : word + extrn _match_start : word + extrn _prev_length : word + extrn _good_match : word + extrn _strstart : word + extrn _max_chain_length : word +ifdef DYN_ALLOC + extrn _prev : word + extrn _window : word + prev equ 0 ; offset forced to zero + window equ 0 + window_seg equ _window[2] + window_off equ 0 +else + wseg dw seg _window + window_seg equ wseg + window_off equ offset _window +endif +_DATA ends + +DGROUP group _DATA + +if @CodeSize +if Alig_PARA +MATCH_TEXT SEGMENT PARA PUBLIC 'CODE' +else +MATCH_TEXT SEGMENT WORD PUBLIC 'CODE' +endif + assume cs: MATCH_TEXT, ds: DGROUP +else ;!@CodeSize +if Alig_PARA +_TEXT segment para public 'CODE' +else +_TEXT segment word public 'CODE' +endif + assume cs: _TEXT, ds: DGROUP +endif ;?@CodeSize + + public _match_init + public _longest_match + +ifndef WSIZE + WSIZE equ 32768 ; keep in sync with zip.h ! +endif + MIN_MATCH equ 3 + MAX_MATCH equ 258 + MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1) + MAX_DIST equ (WSIZE-MIN_LOOKAHEAD) + +ifdef DYN_ALLOC + ifdef SS_NEQ_DS + prev_ptr dw seg _prev ; pointer to the prev array + endif +else + prev_ptr dw seg _prev ; pointer to the prev array +endif +ifdef SS_NEQ_DS + match_start dw 0 ; copy of _match_start if SS != DS + nice_match dw 0 ; copy of _nice_match if SS != DS +endif + +; initialize or check the variables used in match.asm. + +if @CodeSize +_match_init proc far ; 'proc far' for large model +else +_match_init proc near ; 'proc near' for compact model +endif +ifdef SS_NEQ_DS + ma_start equ cs:match_start ; does not work on OS/2 + nice equ cs:nice_match +else + assume ss: DGROUP + ma_start equ ss:_match_start + nice equ ss:_nice_match + ifndef NO_SECURE_TESTS + mov ax,ds + mov bx,ss + cmp ax,bx ; SS == DS? + jne fatal_err + endif +endif +ifdef DYN_ALLOC + ifndef NO_SECURE_TESTS + cmp _prev[0],0 ; verify zero offset + jne fatal_err + cmp _window[0],0 + jne fatal_err + endif + ifdef SS_NEQ_DS + mov ax,_prev[2] ; segment value + mov cs:prev_ptr,ax ; ugly write to code, crash on OS/2 + prev_seg equ cs:prev_ptr + else + prev_seg equ ss:_prev[2] ; works on OS/2 if SS == DS + endif +else + prev_seg equ cs:prev_ptr +endif + ret +ifndef NO_SECURE_TESTS +if @CodeSize + extrn _exit : far ; 'far' for large model +else + extrn _exit : near ; 'near' for compact model +endif +fatal_err: ; (quiet) emergency stop: + call _exit ; incompatible "global vars interface" +endif + +_match_init endp + +; ----------------------------------------------------------------------- +; Set match_start to the longest match starting at the given string and +; return its length. Matches shorter or equal to prev_length are discarded, +; in which case the result is equal to prev_length and match_start is +; garbage. +; IN assertions: cur_match is the head of the hash chain for the current +; string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + +; int longest_match(cur_match) + + align Align_Size + +if @CodeSize +_longest_match proc far ; 'proc far' for large model +else +_longest_match proc near ; 'proc near' for compact model +endif + push bp + mov bp,sp + push di + push si + push ds + +if @CodeSize + cur_match equ word ptr [bp+6] ; [bp+6] for large model +else + cur_match equ word ptr [bp+4] ; [bp+4] for compact model +endif + +; window equ es:window (es:0 for DYN_ALLOC) +; prev equ ds:prev +; match equ es:si +; scan equ es:di +; chain_length equ bp +; best_len equ bx +; limit equ dx + + mov si,cur_match ; use bp before it is destroyed +ifdef SS_NEQ_DS + mov ax,_nice_match + mov nice,ax ; ugly write to code, crash on OS/2 +endif + mov dx,_strstart + mov bp,_max_chain_length ; chain_length = max_chain_length + mov di,dx + sub dx,MAX_DIST ; limit = strstart-MAX_DIST + cld ; string ops increment si and di + jae limit_ok + sub dx,dx ; limit = NIL +limit_ok: + add di,2+window_off ; di = offset(window + strstart + 2) + mov bx,_prev_length ; best_len = prev_length + mov es,window_seg + mov ax,es:[bx+di-3] ; ax = scan[best_len-1..best_len] + mov cx,es:[di-2] ; cx = scan[0..1] + cmp bx,_good_match ; do we have a good match already? + mov ds,prev_seg ; (does not destroy the flags) + assume ds: nothing + jb do_scan ; good match? +if Have_80x86 + shr bp,2 ; chain_length >>= 2 +else + shr bp,1 ; chain_length >>= 2 + shr bp,1 +endif + jmp short do_scan + + align Align_Size ; align destination of branch +long_loop: +; at this point, ds:di == scan+2, ds:si == cur_match + mov ax,[bx+di-3] ; ax = scan[best_len-1..best_len] + mov cx,[di-2] ; cx = scan[0..1] + mov ds,prev_seg ; reset ds to address the prev array +short_loop: +; at this point, di == scan+2, si = cur_match, +; ax = scan[best_len-1..best_len] and cx = scan[0..1] +if (WSIZE-32768) + and si,WSIZE-1 ; not needed if WSIZE=32768 +endif + shl si,1 ; cur_match as word index + dec bp ; --chain_length + mov si,prev[si] ; cur_match = prev[cur_match] + jz the_end + cmp si,dx ; cur_match <= limit ? + jbe the_end +do_scan: + cmp ax,word ptr es:window[bx+si-1] ; check match at best_len-1 + jne short_loop + cmp cx,word ptr es:window[si] ; check min_match_length match + jne short_loop + + mov cx,es + add si,2+window_off ; si = match + mov ds,cx ; ds = es = window + mov cx,(MAX_MATCH-2)/2 ; scan for at most MAX_MATCH bytes + mov ax,di ; ax = scan+2 + repe cmpsw ; loop until mismatch + je maxmatch ; match of length MAX_MATCH? +mismatch: + mov cl,[di-2] ; mismatch on first or second byte? + xchg ax,di ; di = scan+2, ax = end of scan + sub cl,[si-2] ; cl = 0 if first bytes equal + sub ax,di ; ax = len + sub si,2+window_off ; si = cur_match + len + sub si,ax ; si = cur_match + sub cl,1 ; set carry if cl == 0 (can't use DEC) + adc ax,0 ; ax = carry ? len+1 : len + cmp ax,bx ; len > best_len ? + jle long_loop + mov ma_start,si ; match_start = cur_match + mov bx,ax ; bx = best_len = len + cmp ax,nice ; len >= nice_match ? + jl long_loop +the_end: + pop ds + assume ds: DGROUP +ifdef SS_NEQ_DS + mov ax,ma_start ; garbage if no match found + mov ds:_match_start,ax +endif + pop si + pop di + pop bp + mov ax,bx ; result = ax = best_len + ret +maxmatch: ; come here if maximum match + cmpsb ; increment si and di + jmp mismatch ; force match_length = MAX_LENGTH + +_longest_match endp + +if @CodeSize +MATCH_TEXT ENDS +else +_TEXT ENDS +endif +; +endif ;!USE_ZLIB +; +end diff --git a/msdos/msdos.c b/msdos/msdos.c new file mode 100644 index 0000000..4f71397 --- /dev/null +++ b/msdos/msdos.c @@ -0,0 +1,1126 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2005-Feb-10 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#include "zip.h" + +#ifndef UTIL /* little or no material in this file is used by UTIL */ + +#include +#include + + +#if defined(__GO32__) || defined(__TURBOC__) +# include /* prototypes of find*() */ + typedef struct ffblk ff_dir; +# define FATTR (hidden_files ? FA_HIDDEN+FA_SYSTEM+FA_DIREC : FA_DIREC) +# define FFIRST(n,d,a) findfirst(n,(struct ffblk *)d,a) +# define FNEXT(d) findnext((struct ffblk *)d) +# if (defined(__TURBOC__) || (defined(__DJGPP__) && (__DJGPP__ >=2))) +# if (defined(__DJGPP__) && (__DJGPP__ == 2) && (__DJGPP_MINOR__ == 0)) +# include +# endif +# define GetFileMode(name) _chmod(name, 0) +# define SetFileMode(name, attr) _chmod(name, 1, attr) +# else /* DJGPP v1.x */ +# define GetFileMode(name) bdosptr(0x43, (name), 0) +# endif +#endif /* __GO32__ || __TURBOC__ */ + +#if defined(MSC) || defined(__WATCOMC__) + typedef struct find_t ff_dir; +# define FATTR (hidden_files ? _A_HIDDEN+_A_SYSTEM+_A_SUBDIR : _A_SUBDIR) +# ifndef FA_LABEL +# define FA_LABEL _A_VOLID +# endif +# define FFIRST(n,d,a) _dos_findfirst(n,a,(struct find_t *)d) +# define FNEXT(d) _dos_findnext((struct find_t *)d) +# define ff_name name +# define ff_fdate wr_date +# define ff_ftime wr_time +# define ff_attrib attrib +#endif /* MSC || __WATCOMC__ */ + +#ifdef __EMX__ +# ifdef EMX_OBSOLETE /* emx 0.9b or earlier */ +# define size_t xxx_size_t +# define wchar_t xxx_wchar_t +# define tm xxx_tm +# include +# undef size_t +# undef wchar_t +# undef tm +# else /* !EMX_OBSOLETE */ /* emx 0.9c or newer */ +# include +# endif /* ?EMX_OBSOLETE */ + typedef struct _find ff_dir; +# define FATTR (hidden_files ? _A_HIDDEN+_A_SYSTEM+_A_SUBDIR : _A_SUBDIR) +# define FA_LABEL _A_VOLID +# define FFIRST(n,d,a) __findfirst(n,a,d) +# define FNEXT(d) __findnext(d) +# define ff_name name +# define ff_fdate date +# define ff_ftime time +# define ff_attrib attr +# define GetFileMode(name) __chmod(name, 0, 0) +# define SetFileMode(name, attr) __chmod(name, 1, attr) +#endif /* __EMX__ */ + +#ifndef SetFileMode +# define SetFileMode(name, attr) _dos_setfileattr(name, attr) +#endif + + +#define PAD 0 +#define PATH_END '/' + +/* Library functions not in (most) header files */ +int rmdir OF((const char *)); +int utime OF((char *, ztimbuf *)); + +/* Local functions */ +#ifndef GetFileMode +int GetFileMode OF((char *name)); +#endif /* !GetFileMode */ + +local int initDirSearch OF((char *name, ff_dir *ff_context_p)); +local char *getVolumeLabel OF((int, ulg *, ulg *, time_t *)); +local int wild_recurse OF((char *, char *)); +local int procname_dos OF((char *n, int caseflag, unsigned attribs)); +local int is_running_on_windows OF((void)); + +#define MSDOS_INVALID_ATTR 0xFF +#define getDirEntryAttr(d) ((d)->ff_attrib) + +/* Module level variables */ +extern char *label; +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +/* Module level constants */ +local ZCONST char wild_match_all[] = "*.*"; + + +#ifndef GetFileMode +int GetFileMode(char *name) +{ + unsigned int attr = 0; + return (_dos_getfileattr(name, &attr) ? -1 : attr); +} +#endif /* !GetFileMode */ + +local int initDirSearch(name, ff_context_p) + char *name; /* name of directory to scan */ + ff_dir *ff_context_p; /* pointer to FFIRST/FNEXT context structure */ +{ + int r; /* FFIRST return value */ + char *p, *q; /* temporary copy of name, and aux pointer */ + + if ((p = malloc(strlen(name) + (2 + sizeof(wild_match_all)))) == NULL) + return ZE_MEM; + + strcpy(p, name); + q = p + strlen(p); + if (q[-1] == ':') + *q++ = '.'; + if ((q - p) > 0 && *(q - 1) != '/') + *q++ = '/'; + strcpy(q, wild_match_all); + r = FFIRST(p, ff_context_p, FATTR); + free((zvoid *)p); + + return (r ? ZE_MISS : ZE_OK); +} + +local char *getVolumeLabel(drive, vtime, vmode, vutim) + int drive; /* drive name: 'A' .. 'Z' or '\0' for current drive */ + ulg *vtime; /* volume label creation time (DOS format) */ + ulg *vmode; /* volume label file mode */ + time_t *vutim;/* volume label creation time (UNIX format) */ + +/* If a volume label exists for the given drive, return its name and + set its time and mode. The returned name must be static data. */ +{ + static char vol[14]; + ff_dir d; + char *p; + + if (drive) { + vol[0] = (char)drive; + strcpy(vol+1, ":/"); + } else { + strcpy(vol, "/"); + } + strcat(vol, wild_match_all); + if (FFIRST(vol, &d, FA_LABEL) == 0) { + strncpy(vol, d.ff_name, sizeof(vol)-1); + vol[sizeof(vol)-1] = '\0'; /* just in case */ + if ((p = strchr(vol, '.')) != NULL) /* remove dot, though PKZIP doesn't */ + strcpy(p, p + 1); + *vtime = ((ulg)d.ff_fdate << 16) | ((ulg)d.ff_ftime & 0xffff); + *vmode = (ulg)d.ff_attrib; + *vutim = dos2unixtime(*vtime); + return vol; + } + return NULL; +} + + +#ifdef MSDOS16 +#define ONENAMELEN 12 /* no 16-bit compilers supports LFN */ +#else +#define ONENAMELEN 255 +#endif + +/* whole is a pathname with wildcards, wildtail points somewhere in the */ +/* middle of it. All wildcards to be expanded must come AFTER wildtail. */ + +local int wild_recurse(whole, wildtail) +char *whole; +char *wildtail; +{ + ff_dir dir; + char *subwild, *name, *newwhole = NULL, *glue = NULL, plug = 0, plug2; + ush newlen, amatch = 0; + int e = ZE_MISS; + + if (!isshexp(wildtail)) { + struct stat s; /* dummy buffer for stat() */ + + if (!LSSTAT(whole, &s)) /* file exists ? */ + return procname(whole, 0); + else + return ZE_MISS; /* woops, no wildcards! */ + } + + /* back up thru path components till existing dir found */ + do { + name = wildtail + strlen(wildtail) - 1; + for (;;) + if (name-- <= wildtail || *name == PATH_END) { + subwild = name + 1; + plug2 = *subwild; + *subwild = 0; + break; + } + if (glue) + *glue = plug; + glue = subwild; + plug = plug2; + e = initDirSearch(whole, &dir); + } while (e == ZE_MISS && subwild > wildtail); + wildtail = subwild; /* skip past non-wild components */ + if (e != ZE_OK) { + if (glue) + *glue = plug; + goto ohforgetit; + } + subwild = strchr(wildtail + 1, PATH_END); + /* this "+ 1" dodges the ^^^ hole left by *glue == 0 */ + if (subwild != NULL) { + *(subwild++) = 0; /* wildtail = one component pattern */ + newlen = strlen(whole) + strlen(subwild) + (ONENAMELEN + 2); + } else + newlen = strlen(whole) + (ONENAMELEN + 1); + if ((newwhole = malloc(newlen)) == NULL) { + if (glue) + *glue = plug; + e = ZE_MEM; + goto ohforgetit; + } + strcpy(newwhole, whole); + newlen = strlen(newwhole); + if (glue) + *glue = plug; /* repair damage to whole */ + if (!isshexp(wildtail)) { + e = ZE_MISS; /* non-wild name not found */ + goto ohforgetit; + } + + do { + if (strcmp(dir.ff_name, ".") && strcmp(dir.ff_name, "..") + && MATCH(wildtail, dir.ff_name, 0)) { + strcpy(newwhole + newlen, dir.ff_name); + if (subwild) { + name = newwhole + strlen(newwhole); + *(name++) = PATH_END; + strcpy(name, subwild); + e = wild_recurse(newwhole, name); + } else + e = procname_dos(newwhole, 0, getDirEntryAttr(&dir)); + newwhole[newlen] = 0; + if (e == ZE_OK) + amatch = 1; + else if (e != ZE_MISS) + break; + } + } while (FNEXT(&dir) == 0); + + ohforgetit: + if (subwild) + *--subwild = PATH_END; + if (newwhole) + free(newwhole); + if (e == ZE_MISS && amatch) + e = ZE_OK; + return e; +} + +int wild(w) +char *w; /* path/pattern to match */ +/* If not in exclude mode, expand the pattern based on the contents of the + file system. Return an error code in the ZE_ class. */ +{ + char *p; /* path */ + char *q; /* diskless path */ + int e; /* result */ + + if (volume_label == 1) { + volume_label = 2; + label = getVolumeLabel((w != NULL && w[1] == ':') ? to_up(w[0]) : '\0', + &label_time, &label_mode, &label_utim); + if (label != NULL) + (void)newname(label, 0, 0); + if (w == NULL || (w[1] == ':' && w[2] == '\0')) return ZE_OK; + /* "zip -$ foo a:" can be used to force drive name */ + } + /* special handling of stdin request */ + if (strcmp(w, "-") == 0) /* if compressing stdin */ + return newname(w, 0, 0); + + /* Allocate and copy pattern, leaving room to add "." if needed */ + if ((p = malloc(strlen(w) + 2)) == NULL) + return ZE_MEM; + strcpy(p, w); + + /* Normalize path delimiter as '/' */ + for (q = p; *q; q++) /* use / consistently */ + if (*q == '\\') + *q = '/'; + + /* Separate the disk part of the path */ + q = strchr(p, ':'); + if (q != NULL) { + if (strchr(++q, ':')) /* sanity check for safety of wild_recurse */ + return ZE_MISS; + } else + q = p; + + /* Normalize bare disk names */ + if (q > p && !*q) + strcpy(q, "."); + + /* Here we go */ + e = wild_recurse(p, q); + free((zvoid *)p); + return e; +} + +local int procname_dos(n, caseflag, attribs) +char *n; /* name to process */ +int caseflag; /* true to force case-sensitive match */ +unsigned attribs; /* file attributes, if available */ +/* Process a name or sh expression to operate on (or exclude). Return + an error code in the ZE_ class. */ +{ + char *a; /* path and name for recursion */ + ff_dir *d; /* control structure for FFIRST/FNEXT */ + char *e; /* pointer to name from readd() */ + int m; /* matched flag */ + int ff_status; /* return value of FFIRST/FNEXT */ + char *p; /* path for recursion */ + struct stat s; /* result of stat() */ + struct zlist far *z; /* steps through zfiles list */ + + if (n == NULL) /* volume_label request in freshen|delete mode ?? */ + return ZE_OK; + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0, caseflag); + else if (*n == '\0') return ZE_MISS; + else if (attribs != MSDOS_INVALID_ATTR) + { + /* Avoid calling stat() for performance reasons when it is already known + (from a previous directory scan) that the passed name corresponds to + a "real existing" file. The only information needed further down in + this function is the distinction between directory entries and other + (typically normal file) entries. This distinction can be derived from + the file's attributes that the directory lookup has already provided + "for free". + */ + s.st_mode = ((attribs & MSDOS_DIR_ATTR) ? S_IFDIR : S_IFREG); + } + else if (LSSTAT(n, &s) +#ifdef __TURBOC__ + /* For this compiler, stat() succeeds on wild card names! */ + || isshexp(n) +#endif + ) + { + /* Not a file or directory--search for shell expression in zip file */ + if (caseflag) { + p = malloc(strlen(n) + 1); + if (p != NULL) + strcpy(p, n); + } else + p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */ + m = 1; + for (z = zfiles; z != NULL; z = z->nxt) { + if (MATCH(p, z->iname, caseflag)) + { + z->mark = pcount ? filter(z->zname, caseflag) : 1; + if (z->mark) z->dosflag = 1; /* force DOS attribs for incl. names */ + if (verbose) + fprintf(mesg, "zip diagnostic: %scluding %s\n", + z->mark ? "in" : "ex", z->name); + m = 0; + } + } + free((zvoid *)p); + return m ? ZE_MISS : ZE_OK; + } + + /* Live name--use if file, recurse if directory */ + for (p = n; *p; p++) /* use / consistently */ + if (*p == '\\') + *p = '/'; + if ((s.st_mode & S_IFDIR) == 0) + { + /* add or remove name of file */ + if ((m = newname(n, 0, caseflag)) != ZE_OK) + return m; + } else { + /* Add trailing / to the directory name */ + if ((p = malloc(strlen(n)+2)) == NULL) + return ZE_MEM; + if (strcmp(n, ".") == 0 || strcmp(n, "/.") == 0) { + *p = '\0'; /* avoid "./" prefix and do not create zip entry */ + } else { + strcpy(p, n); + a = p + strlen(p); + if (a[-1] != '/') + strcpy(a, "/"); + if (dirnames && (m = newname(p, 1, caseflag)) != ZE_OK) { + free((zvoid *)p); + return m; + } + } + /* recurse into directory */ + if (recurse) + { + if ((d = malloc(sizeof(ff_dir))) == NULL || + (m = initDirSearch(n, d)) == ZE_MEM) + { + if (d != NULL) + free((zvoid *)d); + free((zvoid *)p); + return ZE_MEM; + } + for (e = d->ff_name, ff_status = m; + ff_status == 0; + ff_status = FNEXT(d)) + { + if (strcmp(e, ".") && strcmp(e, "..")) + { + if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL) + { + free((zvoid *)d); + free((zvoid *)p); + return ZE_MEM; + } + strcat(strcpy(a, p), e); + if ((m = procname_dos(a, caseflag, getDirEntryAttr(d))) + != ZE_OK) /* recurse on name */ + { + if (m == ZE_MISS) + zipwarn("name not matched: ", a); + else + ziperr(m, a); + } + free((zvoid *)a); + } + } + free((zvoid *)d); + } + free((zvoid *)p); + } /* (s.st_mode & S_IFDIR) == 0) */ + return ZE_OK; +} + +int procname(n, caseflag) +char *n; /* name to process */ +int caseflag; /* true to force case-sensitive match */ +{ + return procname_dos(n, caseflag, MSDOS_INVALID_ATTR); +} + +char *ex2in(x, isdir, pdosflag) +char *x; /* external file name */ +int isdir; /* input: x is a directory */ +int *pdosflag; /* output: force MSDOS file attributes? */ +/* Convert the external file name to a zip file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *n; /* internal file name (malloc'ed) */ + char *t; /* shortened name */ + int dosflag; + + dosflag = 1; + + /* Find starting point in name before doing malloc */ + /* Strip drive specification */ + t = *x && *(x + 1) == ':' ? x + 2 : x; + /* Strip "//host/share/" part of a UNC name */ + if ((!strncmp(x,"//",2) || !strncmp(x,"\\\\",2)) && + (x[2] != '\0' && x[2] != '/' && x[2] != '\\')) { + n = x + 2; + while (*n != '\0' && *n != '/' && *n != '\\') + n++; /* strip host name */ + if (*n != '\0') { + n++; + while (*n != '\0' && *n != '/' && *n != '\\') + n++; /* strip `share' name */ + } + if (*n != '\0') + t = n + 1; + } + /* Strip leading "/" to convert an absolute path into a relative path */ + while (*t == '/' || *t == '\\') + t++; + /* Skip leading "./" as well */ + while (*t == '.' && (t[1] == '/' || t[1] == '\\')) + t += 2; + + /* Make changes, if any, to the copied name (leave original intact) */ + for (n = t; *n; n++) + if (*n == '\\') + *n = '/'; + + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + + if (isdir == 42) return n; /* avoid warning on unused variable */ + + if (dosify) + msname(n); + else +#if defined(__DJGPP__) && __DJGPP__ >= 2 + if (_USE_LFN == 0) +#endif + strlwr(n); + if (pdosflag) + *pdosflag = dosflag; + return n; +} + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + + return x; +} + +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ +#if defined(__TURBOC__) || defined(__GO32__) + int h; /* file handle */ + + if ((h = open(f, 0)) != -1) + { + setftime(h, (struct ftime *)(void *)&d); + close(h); + } +#else /* !__TURBOC__ && !__GO32__ */ + ztimbuf u; /* argument for utime() */ + + /* Convert DOS time to time_t format in u.actime and u.modtime */ + u.actime = u.modtime = dos2unixtime(d); + + /* Set updated and accessed times of f */ + utime(f, &u); +#endif /* ?(__TURBOC__ || __GO32__) */ +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + /* convert FNMAX to malloc - 11/8/04 EG */ + char *name; + int len = strlen(f); + int isstdin = !strcmp(f, "-"); + + if (f == label) { + if (a != NULL) + *a = label_mode; + if (n != NULL) + *n = -2L; /* convention for a label name */ + if (t != NULL) + t->atime = t->mtime = t->ctime = label_utim; + return label_time; + } + if ((name = malloc(len + 1)) == NULL) { + ZIPERR(ZE_MEM, "filetime"); + } + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + + if (isstdin) { + if (fstat(fileno(stdin), &s) != 0) { + free(name); + error("fstat(stdin)"); + } + time((time_t *)&s.st_mtime); /* some fstat()s return time zero */ + } else if (LSSTAT(name, &s) != 0) { + /* Accept about any file kind including directories + * (stored with trailing / with -r option) + */ + free(name); + return 0; + } + + if (a != NULL) { + *a = ((ulg)s.st_mode << 16) | (isstdin ? 0L : (ulg)GetFileMode(name)); +#if (S_IFREG != 0x8000) + /* kludge to work around non-standard S_IFREG flag used in DJGPP V2.x */ + if ((s.st_mode & S_IFMT) == S_IFREG) *a |= 0x80000000L; +#endif + } + free(name); + if (n != NULL) + *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_ctime; + } + + return unix2dostime((time_t *)&s.st_mtime); +} + +int deletedir(d) +char *d; /* directory to delete */ +/* Delete the directory *d if it is empty, do nothing otherwise. + Return the result of rmdir(), delete(), or system(). + */ +{ + return rmdir(d); +} + +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; + /* create extra field and change z->att if desired */ +{ +#ifdef USE_EF_UT_TIME +#ifdef IZ_CHECK_TZ + if (!zp_tz_is_valid) return ZE_OK; /* skip silently if no valid TZ info */ +#endif + + if ((z->extra = (char *)malloc(EB_HEADSIZE+EB_UT_LEN(1))) == NULL) + return ZE_MEM; + + z->extra[0] = 'U'; + z->extra[1] = 'T'; + z->extra[2] = EB_UT_LEN(1); /* length of data part of e.f. */ + z->extra[3] = 0; + z->extra[4] = EB_UT_FL_MTIME; + z->extra[5] = (char)(z_utim->mtime); + z->extra[6] = (char)(z_utim->mtime >> 8); + z->extra[7] = (char)(z_utim->mtime >> 16); + z->extra[8] = (char)(z_utim->mtime >> 24); + + z->cext = z->ext = (EB_HEADSIZE+EB_UT_LEN(1)); + z->cextra = z->extra; + + return ZE_OK; +#else /* !USE_EF_UT_TIME */ + return (int)(z-z); +#endif /* ?USE_EF_UT_TIME */ +} + + +#ifdef MY_ZCALLOC /* Special zcalloc function for MEMORY16 (MSDOS/OS2) */ + +#if defined(__TURBOC__) && !defined(OS2) +/* Small and medium model are for now limited to near allocation with + * reduced MAX_WBITS and MAX_MEM_LEVEL + */ + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + zvoid far *org_ptr; + zvoid far *new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +zvoid far *zcalloc (unsigned items, unsigned size) +{ + zvoid far *buf; + ulg bsize = (ulg)items*size; + + if (bsize < (65536L-16L)) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-NULL) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +zvoid zcfree (zvoid far *ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = next_ptr - 1; n >= 0; n--) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ziperr(ZE_MEM, "zcfree: ptr not found"); +} +#endif /* __TURBOC__ */ + +#if defined(MSC) || defined(__WATCOMC__) +#if (!defined(_MSC_VER) || (_MSC_VER < 700)) +# define _halloc halloc +# define _hfree hfree +#endif + +zvoid far *zcalloc (unsigned items, unsigned size) +{ + return (zvoid far *)_halloc((long)items, size); +} + +zvoid zcfree (zvoid far *ptr) +{ + _hfree((void huge *)ptr); +} +#endif /* MSC || __WATCOMC__ */ + +#endif /* MY_ZCALLOC */ + +#if (defined(__WATCOMC__) && defined(ASMV) && !defined(__386__)) +/* This is a hack to connect "call _exit" in match.asm to exit() */ +#pragma aux xit "_exit" parm caller [] +void xit(void) +{ + exit(20); +} +#endif + +local int is_running_on_windows(void) +{ + char * var = getenv("OS"); + + /* if the OS env.var says 'Windows_NT' then */ + /* we're likely running on a variant of WinNT */ + + if ((NULL != var) && (0 == strcmp("Windows_NT", var))) + { + return 1; + } + + /* if the windir env.var is non-null then */ + /* we're likely running on a variant of Win9x */ + /* DOS mode of Win9x doesn't define windir, only winbootdir */ + /* NT's command.com can't see lowercase env. vars */ + + var = getenv("windir"); + if ((NULL != var) && (0 != var[0])) + { + return 1; + } + + return 0; +} + +void check_for_windows(char *app) +{ + /* Print a warning for users running under Windows */ + /* to reduce bug reports due to running DOS version */ + /* under Windows, when Windows version usually works correctly */ + + /* This is only called from the DOS version */ + + if (is_running_on_windows()) + { + printf("\nzip warning: You are running MSDOS %s on Windows.\n" + "Try the Windows version before reporting any problems.\n", + app); + } +} + +#endif /* !UTIL */ + + +#ifndef WINDLL +/******************************/ +/* Function version_local() */ +/******************************/ + +static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s.\n\n"; + /* At module level to keep Turbo C++ 1.0 happy !! */ + +void version_local() +{ +#if defined(__DJGPP__) || defined(__WATCOMC__) || \ + (defined(_MSC_VER) && (_MSC_VER != 800)) + char buf[80]; +#endif + +/* Define the compiler name and version strings */ +#if defined(__GNUC__) +# if defined(__DJGPP__) + sprintf(buf, "djgpp v%d.%02d / gcc ", __DJGPP__, __DJGPP_MINOR__); +# define COMPILER_NAME1 buf +# elif defined(__GO32__) /* __GO32__ is defined as "1" only (sigh) */ +# define COMPILER_NAME1 "djgpp v1.x / gcc " +# elif defined(__EMX__) /* ...so is __EMX__ (double sigh) */ +# define COMPILER_NAME1 "emx+gcc " +# else +# define COMPILER_NAME1 "gcc " +# endif +# define COMPILER_NAME2 __VERSION__ +#elif defined(__WATCOMC__) +# if (__WATCOMC__ % 10 > 0) +/* We do this silly test because __WATCOMC__ gives two digits for the */ +/* minor version, but Watcom packaging prefers to show only one digit. */ + sprintf(buf, "Watcom C/C++ %d.%02d", __WATCOMC__ / 100, + __WATCOMC__ % 100); +# else + sprintf(buf, "Watcom C/C++ %d.%d", __WATCOMC__ / 100, + (__WATCOMC__ % 100) / 10); +# endif +# define COMPILER_NAME1 buf +# define COMPILER_NAME2 "" +#elif defined(__TURBOC__) +# ifdef __BORLANDC__ +# define COMPILER_NAME1 "Borland C++" +# if (__BORLANDC__ < 0x0200) +# define COMPILER_NAME2 " 1.0" +# elif (__BORLANDC__ == 0x0200) /* James: __TURBOC__ = 0x0297 */ +# define COMPILER_NAME2 " 2.0" +# elif (__BORLANDC__ == 0x0400) +# define COMPILER_NAME2 " 3.0" +# elif (__BORLANDC__ == 0x0410) /* __BCPLUSPLUS__ = 0x0310 */ +# define COMPILER_NAME2 " 3.1" +# elif (__BORLANDC__ == 0x0452) /* __BCPLUSPLUS__ = 0x0320 */ +# define COMPILER_NAME2 " 4.0 or 4.02" +# elif (__BORLANDC__ == 0x0460) /* __BCPLUSPLUS__ = 0x0340 */ +# define COMPILER_NAME2 " 4.5" +# elif (__BORLANDC__ == 0x0500) /* __TURBOC__ = 0x0500 */ +# define COMPILER_NAME2 " 5.0" +# else +# define COMPILER_NAME2 " later than 5.0" +# endif +# else +# define COMPILER_NAME1 "Turbo C" +# if (__TURBOC__ > 0x0401) +# define COMPILER_NAME2 "++ later than 3.0" +# elif (__TURBOC__ == 0x0401) /* Kevin: 3.0 -> 0x0401 */ +# define COMPILER_NAME2 "++ 3.0" +# elif (__TURBOC__ == 0x0296) /* [662] checked by SPC */ +# define COMPILER_NAME2 "++ 1.01" +# elif (__TURBOC__ == 0x0295) /* [661] vfy'd by Kevin */ +# define COMPILER_NAME2 "++ 1.0" +# elif (__TURBOC__ == 0x0201) /* Brian: 2.01 -> 0x0201 */ +# define COMPILER_NAME2 " 2.01" +# elif ((__TURBOC__ >= 0x018d) && (__TURBOC__ <= 0x0200)) /* James: 0x0200 */ +# define COMPILER_NAME2 " 2.0" +# elif (__TURBOC__ > 0x0100) +# define COMPILER_NAME2 " 1.5" /* James: 0x0105? */ +# else +# define COMPILER_NAME2 " 1.0" /* James: 0x0100 */ +# endif +# endif +#elif defined(MSC) +# if defined(_QC) && !defined(_MSC_VER) +# define COMPILER_NAME1 "Microsoft Quick C" +# define COMPILER_NAME2 "" /* _QC is defined as 1 */ +# else +# define COMPILER_NAME1 "Microsoft C " +# ifdef _MSC_VER +# if (_MSC_VER == 800) +# define COMPILER_NAME2 "8.0/8.0c (Visual C++ 1.0/1.5)" +# else +# define COMPILER_NAME2 \ + (sprintf(buf, "%d.%02d", _MSC_VER/100, _MSC_VER%100), buf) +# endif +# else +# define COMPILER_NAME2 "5.1 or earlier" +# endif +# endif +#else +# define COMPILER_NAME1 "unknown compiler" +# define COMPILER_NAME2 "" +#endif + +/* Define the OS name and memory environment strings */ +#if defined(__WATCOMC__) || defined(__TURBOC__) || defined(MSC) || \ + defined(__GNUC__) +# define OS_NAME1 "\nMS-DOS" +#else +# define OS_NAME1 "MS-DOS" +#endif + +#if (defined(__GNUC__) || (defined(__WATCOMC__) && defined(__386__))) +# define OS_NAME2 " (32-bit)" +#elif defined(M_I86HM) || defined(__HUGE__) +# define OS_NAME2 " (16-bit, huge)" +#elif defined(M_I86LM) || defined(__LARGE__) +# define OS_NAME2 " (16-bit, large)" +#elif defined(M_I86MM) || defined(__MEDIUM__) +# define OS_NAME2 " (16-bit, medium)" +#elif defined(M_I86CM) || defined(__COMPACT__) +# define OS_NAME2 " (16-bit, compact)" +#elif defined(M_I86SM) || defined(__SMALL__) +# define OS_NAME2 " (16-bit, small)" +#elif defined(M_I86TM) || defined(__TINY__) +# define OS_NAME2 " (16-bit, tiny)" +#else +# define OS_NAME2 " (16-bit)" +#endif + +/* Define the compile date string */ +#ifdef __DATE__ +# define COMPILE_DATE " on " __DATE__ +#else +# define COMPILE_DATE "" +#endif + + printf(CompiledWith, COMPILER_NAME1, COMPILER_NAME2, + OS_NAME1, OS_NAME2, COMPILE_DATE); + +} /* end function version_local() */ +#endif /* !WINDLL */ + + +#if 0 /* inserted here for future use (clearing of archive bits) */ +#if (defined(__GO32__) && (!defined(__DJGPP__) || (__DJGPP__ < 2))) + +#include +int volatile _doserrno; + +unsigned _dos_setfileattr(char *name, unsigned attr) +{ +#if 0 /* stripping of trailing '/' is not needed for zip-internal use */ + unsigned namlen = strlen(name); + char *i_name = alloca(namlen + 1); + + strcpy(i_name, name); + if (namlen > 1 && i_name[namlen-1] == '/' && i_name[namlen-2] != ':') + i_name[namlen-1] = '\0'; + asm("movl %0, %%edx": : "g" (i_name)); +#else + asm("movl %0, %%edx": : "g" (name)); +#endif + asm("movl %0, %%ecx": : "g" (attr)); + asm("movl $0x4301, %eax"); + asm("int $0x21": : : "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi"); + _doserrno = 0; + asm("jnc 1f"); + asm("movl %%eax, %0": "=m" (_doserrno)); + switch (_doserrno) { + case 2: + case 3: + errno = ENOENT; + break; + case 5: + errno = EACCES; + break; + } + asm("1:"); + return (unsigned)_doserrno; +} + +#endif /* DJGPP v1.x */ +#endif /* never (not yet used) */ + + +#if (defined(__DJGPP__) && (__DJGPP__ >= 2)) + +/* Disable determination of "x" bit in st_mode field for [f]stat() calls. */ +int _is_executable (const char *path, int fhandle, const char *ext) +{ + return 0; +} + +/* Prevent globbing of filenames. This gives the same functionality as + * "stubedit globbing=no" did with DJGPP v1. + */ +#ifndef USE_DJGPP_GLOB +char **__crt0_glob_function(char *_arg) +{ + return NULL; +} +#endif + +/* Reduce the size of the executable and remove the functionality to read + * the program's environment from whatever $DJGPP points to. + */ +#if !defined(USE_DJGPP_ENV) || defined(UTIL) +void __crt0_load_environment_file(char *_app_name) +{ +} +#endif + +#endif /* __DJGPP__ >= 2 */ + + +#if defined(_MSC_VER) && _MSC_VER == 700 + +/* + * ARGH. MSC 7.0 libraries think times are based on 1899 Dec 31 00:00, not + * 1970 Jan 1 00:00. So we have to diddle time_t's appropriately: add + * 70 years' worth of seconds for localtime() wrapper function; + * (70*365 regular days + 17 leap days + 1 1899 day) * 86400 == + * (25550 + 17 + 1) * 86400 == 2209075200 seconds. + * Let time() and stat() return seconds since 1970 by using our own + * _dtoxtime() which is the routine that is called by these two functions. + */ + + +#ifdef UTIL +# include +#endif + +#ifndef UTIL +#undef localtime +struct tm *localtime(const time_t *); + +struct tm *msc7_localtime(const time_t *clock) +{ + time_t t = *clock; + + t += 2209075200L; + return localtime(&t); +} +#endif /* !UTIL */ + + +void __tzset(void); +int _isindst(struct tm *); + +extern int _days[]; + +/* Nonzero if `y' is a leap year, else zero. */ +#define leap(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0) + +/* Number of leap years from 1970 to `y' (not including `y' itself). */ +#define nleap(y) (((y) - 1969) / 4 - ((y) - 1901) / 100 + ((y) - 1601) / 400) + +time_t _dtoxtime(year, month, mday, hour, min, sec) +int year, month, mday, year, hour, min, sec; +{ + struct tm tm; + time_t t; + int days; + + days = _days[month - 1] + mday; + year += 1980; + if (leap(year) && month > 2) + ++days; + tm.tm_yday = days; + tm.tm_mon = month - 1; + tm.tm_year = year - 1900; + tm.tm_hour = hour; + __tzset(); + days += 365 * (year - 1970) + nleap (year); + t = 86400L * days + 3600L * hour + 60 * min + sec + _timezone; + if (_daylight && _isindst(&tm)) + t -= 3600; + return t; +} + +#endif /* _MSC_VER && _MSC_VER == 700 */ + + +#ifdef __WATCOMC__ + +/* This papers over a bug in Watcom 10.6's standard library... sigh */ +/* Apparently it applies to both the DOS and Win32 stat()s. */ + +int stat_bandaid(const char *path, struct stat *buf) +{ + char newname[4]; + if (!stat(path, buf)) + return 0; + else if (!strcmp(path, ".") || (path[0] && !strcmp(path + 1, ":."))) { + strcpy(newname, path); + newname[strlen(path) - 1] = '\\'; /* stat(".") fails for root! */ + return stat(newname, buf); + } else + return -1; +} + +#endif diff --git a/msdos/osdep.h b/msdos/osdep.h new file mode 100644 index 0000000..0e0f23f --- /dev/null +++ b/msdos/osdep.h @@ -0,0 +1,218 @@ +/* + Copyright (c) 1990-2008 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2007-Mar-4 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* The symbol DOS is used throughout the Zip source to identify code portions + * specific to the MSDOS port. + * Just to make sure, we check that it is set. + * (Currently, this should should not be neccessary, since currently it has + * to be set on the compiler command line to get this file read in.) + */ +#ifndef DOS +# define DOS +#endif + +/* The symbol MSDOS is consistently used in the generic source files + * to identify code to support for MSDOS (and MSDOS related) stuff. + * e.g: FAT or (FAT like) file systems, + * '\\' as directory separator in paths, + * "\r\n" as record (line) terminator in text files, ... + * + * IMPORTANT Note: + * This symbol is not unique for the MSDOS port !!!!!! + * It is also defined by ports to some other OS which are (to some extend) + * considered DOS compatible. + * Examples are: OS/2 (OS2), Windows NT and Windows 95 (WIN32). + * + */ +#ifndef MSDOS +# define MSDOS +#endif + +/* Power C is similar to Turbo C */ +#ifdef __POWERC +# define __TURBOC__ +#endif /* __POWERC */ + +/* Automatic setting of the common Microsoft C idenfifier MSC. + * NOTE: Watcom also defines M_I*86 ! + */ +#if defined(_MSC_VER) || (defined(M_I86) && !defined(__WATCOMC__)) +# ifndef MSC +# define MSC /* This should work for older MSC, too! */ +# endif +#endif + +#if !defined(__GO32__) && !defined(__EMX__) +# define NO_UNISTD_H +#endif + +#if defined(__WATCOMC__) && defined(__386__) +# define WATCOMC_386 +#endif + +#ifdef WINDLL +# define MSWIN +# define MEMORY16 +#endif + + +#if !defined(__EMX__) && !defined(__GO32__) && !defined(WATCOMC_386) +#if !defined(WINDLL) +# define MSDOS16 /* 16 bit MSDOS only */ +# define MEMORY16 +#endif +#endif + +#if !defined(NO_ASM) && !defined(ASMV) +# define ASMV +#endif + +/* enable creation of UTC time fields unless explicitely suppressed */ +#if !defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME) +# define USE_EF_UT_TIME +#endif + +/* check that TZ environment variable is defined before using UTC times */ +#if (!defined(NO_IZ_CHECK_TZ) && !defined(IZ_CHECK_TZ)) +# define IZ_CHECK_TZ +#endif + +#ifdef MEMORY16 +# ifndef NO_ASM +# define ASM_CRC 1 +# endif /* ?NO_ASM */ +# ifdef __TURBOC__ +# include +# if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__) +# if defined(DYNAMIC_CRC_TABLE) && defined(DYNALLOC_CRCTAB) + error: No dynamic CRC table allocation with Borland C far data models. +# endif /* DYNAMIC_CRC_TABLE */ +# endif /* Turbo/Borland C far data memory models */ +# define nearmalloc malloc +# define nearfree free +# define DYN_ALLOC +# else /* !__TURBOC__ */ +# include +# define nearmalloc _nmalloc +# define nearfree _nfree +# define farmalloc _fmalloc +# define farfree _ffree +# endif /* ?__TURBOC__ */ +# define MY_ZCALLOC 1 +# ifdef SMALL_MEM +# define CBSZ 2048 +# define ZBSZ 2048 +# endif +# ifdef MEDIUM_MEM +# define CBSZ 4096 +# define ZBSZ 4096 +# endif +# ifndef CBSZ +# define CBSZ 8192 +# define ZBSZ 8192 +# endif +#endif /* MEMORY16 */ + + +/* Symbolic links are not supported, but some compilers may define S_IFLNK. */ +#ifndef NO_SYMLINKS +# define NO_SYMLINKS +#endif + +#ifdef MATCH +# undef MATCH +#endif +#define MATCH dosmatch /* use DOS style wildcard matching */ + +#define USE_CASE_MAP + +#define ROUNDED_TIME(time) (((time) + 1) & (~1)) +#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \ + procname(n, 1)) + +#define FOPR "rb" +#define FOPM "r+b" +#define FOPW "wb" + +#include +#include +#include + +#ifdef ZCRYPT_INTERNAL +# ifdef WINDLL +# define ZCR_SEED2 (unsigned)3141592654L /* use PI as seed pattern */ +# else +# ifndef __GO32__ +# include /* getpid() declaration for srand seed */ +# endif +# endif +#endif + +/* + * djgpp 1.x did not declare these + */ +#if defined(__GO32__) && !defined(__DJGPP__) +char *strlwr(char *); +int setmode(int, int); +#endif + +#ifdef __WATCOMC__ +# define NO_MKTEMP +# define HAS_OPENDIR +# define SSTAT stat_bandaid + int stat_bandaid(const char *path, struct stat *buf); + +/* Get asm routines to link properly without using "__cdecl": */ +# ifdef __386__ +# ifdef ASMV +# pragma aux match_init "_*" parm caller [] modify [] +# pragma aux longest_match "_*" parm caller [] value [eax] \ + modify [eax ecx edx] +# endif +# ifndef USE_ZLIB +# pragma aux crc32 "_*" parm caller [] value [eax] modify [eax] +# pragma aux get_crc_table "_*" parm caller [] value [eax] \ + modify [eax ecx edx] +# endif /* !USE_ZLIB */ +# else /* !__386__ */ +# ifdef ASMV +# pragma aux match_init "_*" parm caller [] loadds modify [ax bx] +# pragma aux longest_match "_*" parm caller [] loadds value [ax] \ + modify [ax bx cx dx es] +# endif /* ASMV */ +# ifndef USE_ZLIB +# pragma aux crc32 "_*" parm caller [] value [ax dx] \ + modify [ax bx cx dx es] +# pragma aux get_crc_table "_*" parm caller [] value [ax] \ + modify [ax bx cx dx] +# endif /* !USE_ZLIB */ +# endif /* ?__386__ */ +#endif /* __WATCOMC__ */ + +/* + * Wrapper function to get around the MSC7 00:00:00 31 Dec 1899 time base, + * see msdos.c for more info + */ + +#if defined(_MSC_VER) && _MSC_VER == 700 +# define localtime(t) msc7_localtime(t) +#endif + +#ifdef __TURBOC__ +# ifdef __FILEIO_C +# include /* supplies mktemp() prototype */ +# endif +#endif + +#if (defined(__TURBOC__) && !defined(__BORLANDC__) && __TURBOC__ <= 0x0201) +# ifndef NO_MKTIME +# define NO_MKTIME /* TC 2.01 and earlier do not supply mktime() */ +# endif +#endif + +void check_for_windows(char *app); diff --git a/msdos/zipup.h b/msdos/zipup.h new file mode 100644 index 0000000..78b428a --- /dev/null +++ b/msdos/zipup.h @@ -0,0 +1,16 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#define fhow (O_RDONLY|O_BINARY) +#define fbad (-1) +typedef int ftype; +#define zopen(n,p) open(n,p) +#define zread(f,b,n) read(f,b,n) +#define zclose(f) close(f) +#define zerr(f) (k == (extent)(-1L)) +#define zstdin 0 diff --git a/novell/MAKEINIT b/novell/MAKEINIT new file mode 100644 index 0000000..f9929e7 --- /dev/null +++ b/novell/MAKEINIT @@ -0,0 +1,71 @@ +# +# makeinit file for makefiles created with QMK386 +# +# Novell's NetWare SDK - Release 15 +# +# Directories for both the WATCOM and NOVELL tools +# +wat386loc = e:\watcom\ +nlm386loc = c:\novell\ndk\nwsdk\ +nlm386hdr = $(nlm386loc)INCLUDE\NLM;$(nlm386loc)INCLUDE;. +nlm386imp = $(nlm386loc)IMPORTS +nlm386lib = $(wat386loc)LIB386;$(wat386loc)LIB386\NETWARE +# +# Define this macro with your copyright statement +# +#copyright = (C) Copyright 199x NONAME, INC. All Rights Reserved +# +# Macros that point to various tools we'll need to compile +# +wcc386r = WCC386 # location of 386 real mode compiler +wcc386p = WCC386P # protected compiler (last avail on Watcom v9.5 +wcc386 = $(wcc386r) # version we want to use + +linkr = WLINK # location of real mode linker +linkp = WLINKP # protected linker (last avail on Watcom v9.5 +linker = $(linkr) # version we want to use +nlmlinkr = $(nlm386loc)TOOLS\NLMLINKR # location of real mode Novell linker +nlmlinkp = $(nlm386loc)TOOLS\NLMLINKX # location of protected Novell linker +nlmlinker = $(nlmlinkr) # version we want to use + +nlmpackr = $(nlm386loc)TOOLS\NLMPACK # location of real mode NLM compression utility +nlmpackp = $(nlm386loc)TOOLS\NLMPACKP # location of protected NLM compression utility +nlmpack = $(nlmpackr) # location of NLM compression utility + +inc_386 = $(nlm386hdr) +lib_386 = $(nlm386lib) +code_386 = $(wat386loc)BIN\386WCGL.EXE # code generator (last avail on Watcom v9.01 +librarian = $(wat386loc)BINB\WLIB # location of librarian +# +# NLM Import Files +# +startup = $(nlm386imp)\PRELUDE.OBJ # other option is nwpre.obj +allimp = $(nlm386imp)\ALL.IMP # import to include all imports +clibimp = $(nlm386imp)\CLIB.IMP # the clib import file +tliimp = $(nlm386imp)\TLI.IMP # the tli import file +aioimp = $(nlm386imp)\AIO.IMP # the aio import file +socklibimp = $(nlm386imp)\SOCKLIB.IMP # the socket import file +mathlibimp = $(nlm386imp)\MATHLIB.IMP # the math library import file +dsapiimp = $(nlm386imp)\DSAPI.IMP # the NDS import file +nutimp = $(nlm386imp)\NWSNUT.IMP # the NWSNUT import file +appleimp = $(nlm386imp)\APPLTLK.IMP # the AppleTalk import file +nitimp = $(nlm386imp)\NIT.IMP # the legacy NLM import file +nlmlibimp = $(nlm386imp)\NLMLIB.IMP # the NLM-specific import file +requesterimp = $(nlm386imp)\REQUESTR.IMP # the Requester import file +fpsmimp = $(nlm386imp)\FPSM.IMP # floating point support import file +threadsimp = $(nlm386imp)\THREADS.IMP # the threads import file +dseventimp = $(nlm386imp)\DSEVENT.IMP # DS Events import file +psrvimp = $(nlm386imp)\NWPSRV.IMP # print services import file +psrv3ximp = $(nlm386imp)\NWPSRV3X.IMP # 3.x print services import file +streamsimp = $(nlm386imp)\STREAMS.IMP # streams import file +unicodeimp = $(nlm386imp)\UNICODE.IMP # unicode import file +agentimp = $(nlm386imp)\agent.imp # SNMP Agent import file +smileimp = $(nlm386imp)\smile.imp # SMILE (SNMP) import file +# +# Cross-platform Import Files +# +audnlm32imp = $(nlm386imp)\AUDNLM32.IMP # auditing import file +calnlm32imp = $(nlm386imp)\CALNLM32.IMP # NWCALLS import file +clxnlm32imp = $(nlm386imp)\CLXNLM32.IMP # NWCLIENT import file +locnlm32imp = $(nlm386imp)\LOCNLM32.IMP # NWLOCALE import file +netnlm32imp = $(nlm386imp)\NETNLM32.IMP # NWNET import file diff --git a/novell/Makefile b/novell/Makefile new file mode 100644 index 0000000..c88bf86 --- /dev/null +++ b/novell/Makefile @@ -0,0 +1,142 @@ +# +# This makefile was generated by QMK386 v2.14 +# +# Program: unzip.NLM +# This makefile rebuilds the zip NetWare Loadable Module +# +# Created: Sun Jan 03 03:54:03 1999 +# +# MAKEINIT defines many of the macros used herein +# The following macros can be set via your environment: +# CCF386 : Set compile options +# QMKVER : Set to 'd' or 'p' to define VERSION +# SILENT : If defined, .SILENT will be set +# +# The following macros are defined for your program: +# vMAJ : Major version number +# vMIN : Minor version number +# vREV : Revision number + +!ifdef %SILENT +.silent +!endif + +program = zip + +pvmaj = 1 # major version number +pvmin = 00 # minor version number +pvrev = 3 # revision number e.g. 0,1,2, ... + +!ifndef %qmkver +! define version p # use 'd' or 'p' here +!else +! define version $(%qmkver) +!endif +!ifeq version d +! define lversion DEBUG +! define debug /dDEBUG +!else +! define lversion PRODUCTION +! define debug +!endif + +nlm_TYPE = Form Novell NLM '$(program)' +nlm_NAME = Name $^& +nlm_SCREEN = Op ScreenName '$(program)' +nlm_THREAD = Op ThreadName '$^&__P ' +nlm_STACK = Op Stack = 8k +nlm_NLMVER = Op Version = $(pvmaj).$(pvmin).$(pvrev) +nlm_COPYRIGHT = Op Copyright '$(copyright)' +linkop = $+$(linkop)$- Caseexact +linkop = $+$(linkop)$- Nod +!ifeq version d +! define linkop $+$(linkop)$- Map +! define linkop $+$(linkop)$- Verbose +! define ldebug debug all debug novell +!endif + +objlst = BITS.OBJ +objlst = $+$(objlst)$- CRC32.OBJ +objlst = $+$(objlst)$- CRYPT.OBJ +objlst = $+$(objlst)$- DEFLATE.OBJ +objlst = $+$(objlst)$- FILEIO.OBJ +objlst = $+$(objlst)$- GLOBALS.OBJ +objlst = $+$(objlst)$- MKTIME.OBJ +objlst = $+$(objlst)$- NETWARE.OBJ +objlst = $+$(objlst)$- SIGNAL.OBJ +objlst = $+$(objlst)$- TREES.OBJ +objlst = $+$(objlst)$- TTYIO.OBJ +objlst = $+$(objlst)$- UTIL.OBJ +objlst = $+$(objlst)$- ZIP.OBJ +objlst = $+$(objlst)$- ZIPFILE.OBJ +objlst = $+$(objlst)$- ZIPUP.OBJ +objlst = $+$(objlst)$- $(startup) + +import = $(allimp) + +module = CLib + +build_msg = Building a $(lversion) version of $(program) + +pgm_ver = /dvMAJ="$(pvmaj)" /dvMIN="$(pvmin)" /dvREV="$(pvrev)" + +!ifndef %ccf386 +! define d_wcc386opt /ms /w4 /e99 /zp1 /3s /ot /d2 /dN_PLAT_NLM /d_FIND_OLD_HEADERS -dNO_ASM -dNLM $(debug) +! define p_wcc386opt /ms /w4 /s /zp1 /3s /oaxt /dN_PLAT_NLM /d_FIND_OLD_HEADERS -dNO_ASM -dNLM +! define x_wcc386opt $($(version)_wcc386opt) $(pgm_ver) +!else +! define x_wcc386opt $(%ccf386) +!endif + +compiler_cmd = $(wcc386) $(x_wcc386opt) $[*.c + +.BEFORE + echo $(build_msg) + set inc386=$(inc_386) + set lib386=$(lib_386) + set wcg386=$(code_386) + +.c.obj: + $(compiler_cmd) + +zip.nlm : $(objlst) zip.LNK + $(linker) @zip + +zip.LNK : MAKEFILE + if exist $^&.LNK del $^&.LNK + %append $^&.LNK $(nlm_TYPE) + %append $^&.LNK $(nlm_NAME) + %append $^&.LNK $(nlm_SCREEN) + %append $^&.LNK $(nlm_THREAD) + %append $^&.LNK $(nlm_STACK) + %append $^&.LNK $(nlm_NLMVER) +!ifdef copyright + %append $^&.LNK $(nlm_COPYRIGHT) +!endif +!ifdef ldebug + %append $^&.LNK $(ldebug) +!endif + for %i in ($(linkop)) do %append $^&.LNK Op %i + for %i in ($(objlst)) do %append $^&.LNK File %i + for %i in ($(import)) do %append $^&.LNK Import @%i + for %i in ($(export)) do %append $^&.LNK Export @%i + for %i in ($(module)) do %append $^&.LNK Module %i + for %i in ($(library)) do %append $^&.LNK Library %i + +clean : .symbolic + del *.MAP + del *.OBJ + del *.ERR + del *.LNK + del *.NLM + +zip : .symbolic + -pkzip -u zip MAKEFILE *.c *.h + +unzip : .symbolic + -pkunzip -n -d zip + +save : .symbolic + %make zip + %make clean + diff --git a/novell/Netware.c b/novell/Netware.c new file mode 100644 index 0000000..20efa16 --- /dev/null +++ b/novell/Netware.c @@ -0,0 +1,970 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void UseAccurateCaseForPaths(int); + +#include "zip.h" + + /*------------------------------------------------------------------ + ** Global Variables + */ + +#define skipspace( x ) while( isspace( *x ) ) ++x +#define nextspace( x ) while( *x && !isspace( *x ) ) ++x +#define CWS 0 +#define CWV 1 +#define CWP 2 +#define ALL 99 + +/* Globals */ +extern char *GetWorkArea(void); +extern char *next_arg(char *); +extern int NLM_exiting; +char fid[100]; +static breakkey = FALSE; + +#define MATCH shmatch + +extern char *label; +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +#define PAD 0 +#define PATH_END '/' + +local char *readd(d) +DIR *d; /* directory stream to read from */ +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e; + + e = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; +} + +void findzip(char *s) +{ + dowhereis(s); +} + +void dowhereis(char *s) +{ + char dir[_MAX_PATH]; + char fsv[_MAX_SERVER+_MAX_VOLUME+1]; + char fdir[_MAX_PATH]; + char fname[_MAX_FNAME],fext[_MAX_EXT], both[_MAX_FNAME+_MAX_EXT]; + char *p = next_arg(s); /* point at argument */ + + if(!*p) + { + printf("No filename specified!"); + return; + } + + //setlocale (LC_ALL, "NORWAY"); + NWLsetlocale (LC_ALL, "NORWAY"); + + strcpy(dir,GetWorkArea()); + + /* get the file name specification */ + _splitpath(p,fsv,fdir,fname,fext); + + //printf ("p %s, fsv %s, fdir %s, fname %s, fext %s\n", p,fsv,fdir,fname,fext); + //getch(); + + sprintf(both,"%s%s",strupr(fname),strupr(fext)); + + breakkey = FALSE; + + /* startup the recursive file find operation */ + chdir(fsv); + UseAccurateCaseForPaths(1); + SetCurrentNameSpace (NW_NS_LONG); + chdir(fdir); + findit(both); +} + +char *GetWorkArea(void) +{ + static char cwd[_MAX_PATH]; + static char serverName[_MAX_SERVER]; + static char volumeName[_MAX_VOLUME + 1]; + static char dirName[_MAX_DIR]; + + if(getcwd(cwd,_MAX_PATH) == NULL) + return NULL; + + ParsePath(cwd,serverName,volumeName,dirName); /* shouldn't fail! */ + + return cwd; +} + +char *next_arg(char *s) +{ + char *p; + + skipspace(s); /* ignore white */ + p = s; + nextspace(s); /* find next blank */ + *s = NULL; + return(p); +} + +static void findit(char *what) +{ + char dir[_MAX_PATH]; + char zipdir[_MAX_PATH]; + char szzipfile[_MAX_PATH]; + char *psz; + DIR *dirStructPtr; + DIR *dirStructPtrSave; + int r; + + getcwd(dir,_MAX_PATH); + + psz = dir; + + while (*psz) + { + if (*psz == ':') + { + strcpy (zipdir, psz + 1); + break; + } + psz++; + } + + dirStructPtrSave = dirStructPtr = opendir(what); + + /* + _A_NORMAL Normal file; read/write permitted + _A_RDONLY Read-only file + _A_HIDDEN Hidden file + _A_SYSTEM System file + _A_VOLID Volume ID entry + _A_SUBDIR Subdirectory + _A_ARCH Archive file + */ + + if (hidden_files) + SetReaddirAttribute (dirStructPtr, _A_NORMAL | _A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_ARCH); + else + SetReaddirAttribute (dirStructPtr, _A_NORMAL | _A_ARCH); + + //while(dirStructPtr && !breakkey) + while(dirStructPtr && !NLM_exiting) + { + //printf ("\n NLM_exiting test Line 167.... \n"); + + dirStructPtr = readdir(dirStructPtr); + if((dirStructPtr == NULL) || (dirStructPtr == -1)) + break; + + /* Filen er funnet */ + if(dirStructPtr->d_attr & _A_SUBDIR) + continue; + + strcpy (szzipfile, zipdir); + strcat (szzipfile, "/"); + strcat (szzipfile, dirStructPtr->d_name); + procnamehho (szzipfile); + + //ThreadSwitchWithDelay(); + + //if(kbhit() && getch() == 3) + // printf("^C\n",breakkey = TRUE); + } + + if(dirStructPtrSave) + closedir(dirStructPtrSave); + + if (!recurse) + return; + + /* Now traverse the directories in this path */ + + dirStructPtrSave = dirStructPtr = opendir("*.*"); + if(dirStructPtr == NULL) + return; + + if (hidden_files) + SetReaddirAttribute (dirStructPtr, _A_NORMAL | _A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_ARCH | _A_SUBDIR); + else + SetReaddirAttribute (dirStructPtr, _A_NORMAL | _A_ARCH | _A_SUBDIR); + + //ThreadSwitchWithDelay(); + + while(!NLM_exiting) + { + //printf ("\n NLM_exiting test Line 204.... \n"); getch (); + + dirStructPtr = readdir(dirStructPtr); + if((dirStructPtr == NULL) || (dirStructPtr == -1)) + break; + + if(dirStructPtr->d_attr & _A_SUBDIR) + { + strcpy (szzipfile, zipdir); + strcat (szzipfile, "/"); + strcat (szzipfile, dirStructPtr->d_name); + procnamehho (szzipfile); + + chdir(dirStructPtr->d_name); + findit(what); + chdir(".."); + } + + //if(kbhit() && getch() == 3) + // printf("^C\n",breakkey = TRUE); + } + + if(dirStructPtrSave) + closedir(dirStructPtrSave); +} + + +int wild(w) +char *w; /* path/pattern to match */ +/* If not in exclude mode, expand the pattern based on the contents of the + file system. Return an error code in the ZE_ class. */ +{ + DIR *d; /* stream for reading directory */ + char *e; /* name found in directory */ + int r; /* temporary variable */ + char *n; /* constructed name from directory */ + int f; /* true if there was a match */ + char *a; /* alloc'ed space for name */ + //char *p; /* path */ + char *q; /* name */ + char v[5]; /* space for device current directory */ + + + char dir[_MAX_PATH]; + char fsv[_MAX_SERVER+_MAX_VOLUME+1]; + char fdir[_MAX_PATH]; + char fname[_MAX_FNAME],fext[_MAX_EXT], both[_MAX_FNAME+_MAX_EXT]; + char *p; /* point at argument */ + + p = w; + + + /* Test HHO */ + findzip(p); + + return ZE_OK; + + + strcpy(dir,GetWorkArea()); + + /* get the file name specification */ + + _splitpath(p,fsv,fdir,fname,fext); + sprintf(both,"%s%s",strupr(fname),strupr(fext)); + + /* startup the recursive file find operation */ + + chdir(fsv); + + /* Search that level for matching names */ + if ((d = opendir(both)) == NULL) + { + free((zvoid *)a); + return ZE_MISS; + } + + f = 0; + while ((e = readd(d)) != NULL) { + if (strcmp(e, ".") && strcmp(e, "..") && MATCH(q, e)) + { + f = 1; + if (strcmp(p, ".") == 0) { /* path is . */ + r = procname(e); /* name is name */ + if (r) { + f = 0; + break; + } + } else + { + if ((n = malloc(strlen(p) + strlen(e) + 2)) == NULL) + { + free((zvoid *)a); + closedir(d); + return ZE_MEM; + } + n = strcpy(n, p); + if (n[r = strlen(n) - 1] != '/' && n[r] != ':') + strcat(n, "/"); + r = procname(strcat(n, e)); /* name is path/name */ + free((zvoid *)n); + if (r) { + f = 0; + break; + } + } + } + } + closedir(d); + + /* Done */ + free((zvoid *)a); + return f ? ZE_OK : ZE_MISS; +} + +int procnamehho (char *n) +{ + int m; /* matched flag */ + char *p; /* path for recursion */ + struct stat s; /* result of stat() */ + struct zlist far *z; /* steps through zfiles list */ + + char *a; + + if (n == NULL) /* volume_label request in freshen|delete mode ?? */ + return ZE_OK; + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0); + else if (stat(n, &s) +#if defined(__TURBOC__) || defined(__WATCOMC__) + /* For these 2 compilers, stat() succeeds on wild card names! */ + || isshexp(n) +#endif + ) + { + /* Not a file or directory--search for shell expression in zip file */ + p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */ + m = 1; + for (z = zfiles; z != NULL; z = z->nxt) { + if (MATCH(p, z->iname)) + { + z->mark = pcount ? filter(z->zname) : 1; + if (verbose) + fprintf(mesg, "zip diagnostic: %scluding %s\n", + z->mark ? "in" : "ex", z->name); + m = 0; + } + } + free((zvoid *)p); + return m ? ZE_MISS : ZE_OK; + } + + /* Live name--use if file, recurse if directory */ + for (p = n; *p; p++) /* use / consistently */ + if (*p == '\\') + *p = '/'; + + //printf ("\nHHO %s\n", n); + if ((s.st_mode & S_IFDIR) == 0) + { + //printf ("\nHHO1 %s\n", n); + /* add or remove name of file */ + //printf ("\nAdding name %s to list.\n", n); + if ((m = newname(n, 0)) != ZE_OK) + return m; + } else { + + /* Add trailing / to the directory name */ + if ((p = malloc(strlen(n)+2)) == NULL) + return ZE_MEM; + if (strcmp(n, ".") == 0 || strcmp(n, "/.") == 0) { + *p = '\0'; /* avoid "./" prefix and do not create zip entry */ + } else { + strcpy(p, n); + a = p + strlen(p); + if (a[-1] != '/') + strcpy(a, "/"); + //if (dirnames && (m = newname(p, 1)) != ZE_OK) { + if ((m = newname(p, 1)) != ZE_OK) { + free((zvoid *)p); + return m; + } + free ((zvoid *)p); + } + + return ZE_OK; + } + return ZE_OK; +} + +int procname(n) +char *n; /* name to process */ +/* Process a name or sh expression to operate on (or exclude). Return + an error code in the ZE_ class. */ +{ + char *a; /* path and name for recursion */ + DIR *d; /* directory stream from opendir() */ + char *e; /* pointer to name from readd() */ + int m; /* matched flag */ + char *p; /* path for recursion */ + struct stat s; /* result of stat() */ + struct zlist far *z; /* steps through zfiles list */ + + if (n == NULL) /* volume_label request in freshen|delete mode ?? */ + return ZE_OK; + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0); + else if (stat(n, &s) +#if defined(__TURBOC__) || defined(__WATCOMC__) + /* For these 2 compilers, stat() succeeds on wild card names! */ + || isshexp(n) +#endif + ) + { + /* Not a file or directory--search for shell expression in zip file */ + p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */ + m = 1; + for (z = zfiles; z != NULL; z = z->nxt) { + if (MATCH(p, z->iname)) + { + z->mark = pcount ? filter(z->zname) : 1; + if (verbose) + fprintf(mesg, "zip diagnostic: %scluding %s\n", + z->mark ? "in" : "ex", z->name); + m = 0; + } + } + free((zvoid *)p); + return m ? ZE_MISS : ZE_OK; + } + + /* Live name--use if file, recurse if directory */ + for (p = n; *p; p++) /* use / consistently */ + if (*p == '\\') + *p = '/'; + if ((s.st_mode & S_IFDIR) == 0) + { + /* add or remove name of file */ + if ((m = newname(n, 0)) != ZE_OK) + return m; + } else { + /* Add trailing / to the directory name */ + if ((p = malloc(strlen(n)+2)) == NULL) + return ZE_MEM; + if (strcmp(n, ".") == 0 || strcmp(n, "/.") == 0) { + *p = '\0'; /* avoid "./" prefix and do not create zip entry */ + } else { + strcpy(p, n); + a = p + strlen(p); + if (a[-1] != '/') + strcpy(a, "/"); + if (dirnames && (m = newname(p, 1)) != ZE_OK) { + free((zvoid *)p); + return m; + } + } + /* recurse into directory */ + if (recurse && (d = opendir(n)) != NULL) + { + while ((e = readd(d)) != NULL) { + if (strcmp(e, ".") && strcmp(e, "..")) + { + if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL) + { + closedir(d); + free((zvoid *)p); + return ZE_MEM; + } + strcat(strcpy(a, p), e); + if ((m = procname(a)) != ZE_OK) /* recurse on name */ + { + if (m == ZE_MISS) + zipwarn("name not matched: ", a); + else + ziperr(m, a); + } + free((zvoid *)a); + } + } + closedir(d); + } + free((zvoid *)p); + } /* (s.st_mode & S_IFDIR) == 0) */ + return ZE_OK; +} + +char *szRelativParameter; +char szRelativ[512]; +int iRelativOK = FALSE; +int iRelativPakking = FALSE; + +int fixRelativpath () +{ + char *szp; + + szp = szRelativParameter; + + if (szRelativParameter[0] == '/' || szRelativParameter[0] == '\\') + szp++; + + while (*szp) { + if (*szp == '\\') + *szp = '/'; + szp++; + } + + szp = szRelativParameter; + if (szRelativParameter[0] == '/') + szp++; + + strcpy (szRelativ, szp); + + if (strlen(szp) == 0) { + szRelativ[0] = '\0'; + return FALSE; + } + return TRUE; +} + + +char *ex2in(x, isdir, pdosflag) +char *x; /* external file name */ +int isdir; /* input: x is a directory */ +int *pdosflag; /* output: force MSDOS file attributes? */ +/* Convert the external file name to a zip file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *n; /* internal file name (malloc'ed) */ + char *t; /* shortened name */ + int dosflag; + char *sztUpper; + + + /* Find starting point in name before doing malloc */ + t = *x && *(x + 1) == ':' ? x + 2 : x; + while (*t == '/' || *t == '\\') + t++; + + /* Make changes, if any, to the copied name (leave original intact) */ + for (n = t; *n; n++) + if (*n == '\\') + *n = '/'; + + if (iRelativPakking) { + //printf ("\n LINE 516 *ex2ex Internt navn %s external name %s.\n", t, x); getch (); + if (!iRelativOK) { + if (!fixRelativpath()) { + iRelativOK = FALSE; + iRelativPakking = FALSE; + } + else { + sztUpper = malloc (strlen(t) + 10); + strcpy (sztUpper, t); + NWLstrupr (sztUpper); + NWLstrupr (szRelativ); + if (strncmp (sztUpper, szRelativ, strlen(szRelativ)) == 0) { + t = t + strlen(szRelativ); + iRelativPakking = TRUE; + iRelativOK = TRUE; + } + else { + iRelativOK = FALSE; + iRelativPakking = FALSE; + } + free (sztUpper); + } + } + else + { + t = t + strlen(szRelativ); + } + } + + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + + if (dosify) + msname(n); + + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + + return n; +} + + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + + //if ( !IsFileNameValid(x) ) + //ChangeNameForFAT(x); + + //printf ("\n *in2ex Internt navn %s external name %s.\n", n, x); getch (); + + return x; +} + + +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ + //SetFileTime(f, d); +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + /* convert FNMAX to malloc - 11/8/04 EG */ + char *name; + int len = strlen(f); + + if (f == label) { + if (a != NULL) + *a = label_mode; + if (n != NULL) + *n = -2L; /* convention for a label name */ + if (t != NULL) + t->atime = t->mtime = t->ctime = label_utim; + return label_time; + } + if ((name = malloc(len + 1)) == NULL) { + ZIPERR(ZE_MEM, "filetime"); + } + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + if (strcmp(f, "-") == 0) { + if (fstat(fileno(stdin), &s) != 0) + error("fstat(stdin)"); + } + else if (stat(name, &s) != 0) { + /* Accept about any file kind including directories + * (stored with trailing / with -r option) + */ + free(name); + return 0; + } + free(name); + + if (a != NULL) { + *a = s.st_attr; // << 16) | !(s.st_mode & S_IWRITE); + //*a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWRITE); + //if ((s.st_mode & S_IFMT) == S_IFDIR) { + //*a |= MSDOS_DIR_ATTR; + //} + } + if (n != NULL) + *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; + + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = t->mtime; /* best guess, (s.st_ctime: last status change!!) */ + } + return unix2dostime(&s.st_mtime); +} + + +ulg filetimeHHO(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + char *name; + int len = strlen(f), isstdin = !strcmp(f, "-"); + + if (f == label) { + if (a != NULL) + *a = label_mode; + if (n != NULL) + *n = -2L; /* convention for a label name */ + if (t != NULL) + t->atime = t->mtime = t->ctime = label_utim; + return label_time; + } + if ((name = malloc(len + 1)) == NULL) { + ZIPERR(ZE_MEM, "filetimeHHO"); + } + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + + if (isstdin) { + /* it is common for some PC based compilers to + fail with fstat() on devices or pipes */ + if (fstat(fileno(stdin), &s) != 0) { + s.st_mode = S_IFREG; s.st_size = -1L; + } + time(&s.st_ctime); + s.st_atime = s.st_mtime = s.st_ctime; + } else if (stat(name, &s) != 0) { + /* Accept about any file kind including directories + * (stored with trailing / with -r option) + */ + free(name); + return 0; + } + + if (a != NULL) { + //*a = ((ulg)s.st_mode << 16) | (isstdin ? 0L : (ulg)GetFileMode(name)); + //*a = (ulg)s.st_mode; + *a = s.st_attr; + } + + printf ("\nDette er en test LINE : 721 \n"); getch(); + + if (n != NULL) + *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; +#ifdef __WATCOMC__ + /* of course, Watcom always has to make an exception */ + if (s.st_atime == 312764400) + s.st_atime = s.st_mtime; + if (s.st_ctime == 312764400) + s.st_ctime = s.st_mtime; +#endif + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_ctime; + } + + printf ("\nDette er en test LINE : 735 \n"); getch(); + + //return GetFileTime(name); + free(name); + return t->atime; +} + +int deletedir(d) +char *d; /* directory to delete */ +/* Delete the directory *d if it is empty, do nothing otherwise. + Return the result of rmdir(), delete(), or system(). + */ +{ + return rmdir(d); +} + +int set_extra_field(z, z_utim) + struct zlist far *z; + iztimes *z_utim; + /* create extra field and change z->att if desired */ +{ +#ifdef USE_EF_UT_TIME + if ((z->extra = (char *)malloc(EB_HEADSIZE+EB_UT_LEN(1))) == NULL) + return ZE_MEM; + + z->extra[0] = 'U'; + z->extra[1] = 'T'; + z->extra[2] = EB_UT_LEN(1); /* length of data part of e.f. */ + z->extra[3] = 0; + z->extra[4] = EB_UT_FL_MTIME; + z->extra[5] = (char)(z_utim->mtime); + z->extra[6] = (char)(z_utim->mtime >> 8); + z->extra[7] = (char)(z_utim->mtime >> 16); + z->extra[8] = (char)(z_utim->mtime >> 24); + + z->cext = z->ext = (EB_HEADSIZE+EB_UT_LEN(1)); + z->cextra = z->extra; + + return ZE_OK; +#else /* !USE_EF_UT_TIME */ + return (int)(z-z); +#endif /* ?USE_EF_UT_TIME */ +} + + +/******************************/ +/* Function version_local() */ +/******************************/ + +static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n"; + /* At module level to keep Turbo C++ 1.0 happy !! */ + +void version_local() +{ +#if defined(__DJGPP__) || defined(__WATCOMC__) || \ + (defined(_MSC_VER) && (_MSC_VER != 800)) + char buf[80]; +#endif + + printf(CompiledWith, + +#ifdef __GNUC__ +# if defined(__DJGPP__) + (sprintf(buf, "djgpp v%d / gcc ", __DJGPP__), buf), +# elif defined(__GO32__) + "djgpp v1.x / gcc ", +# elif defined(__EMX__) /* ...so is __EMX__ (double sigh) */ + "emx+gcc ", +# else + "gcc ", +# endif + __VERSION__, +#elif defined(__WATCOMC__) +# if (__WATCOMC__ % 10 > 0) +/* We do this silly test because __WATCOMC__ gives two digits for the */ +/* minor version, but Watcom packaging prefers to show only one digit. */ + (sprintf(buf, "Watcom C/C++ %d.%02d", __WATCOMC__ / 100, + __WATCOMC__ % 100), buf), "", +# else + (sprintf(buf, "Watcom C/C++ %d.%d", __WATCOMC__ / 100, + (__WATCOMC__ % 100) / 10), buf), "", +# endif +#elif defined(__TURBOC__) +# ifdef __BORLANDC__ + "Borland C++", +# if (__BORLANDC__ < 0x0200) + " 1.0", +# elif (__BORLANDC__ == 0x0200) /* James: __TURBOC__ = 0x0297 */ + " 2.0", +# elif (__BORLANDC__ == 0x0400) + " 3.0", +# elif (__BORLANDC__ == 0x0410) /* __BCPLUSPLUS__ = 0x0310 */ + " 3.1", +# elif (__BORLANDC__ == 0x0452) /* __BCPLUSPLUS__ = 0x0320 */ + " 4.0 or 4.02", +# elif (__BORLANDC__ == 0x0460) /* __BCPLUSPLUS__ = 0x0340 */ + " 4.5", +# elif (__BORLANDC__ == 0x0500) /* __TURBOC__ = 0x0500 */ + " 5.0", +# else + " later than 5.0", +# endif +# else + "Turbo C", +# if (__TURBOC__ > 0x0401) + "++ later than 3.0" +# elif (__TURBOC__ == 0x0401) /* Kevin: 3.0 -> 0x0401 */ + "++ 3.0", +# elif (__TURBOC__ == 0x0295) /* [661] vfy'd by Kevin */ + "++ 1.0", +# elif ((__TURBOC__ >= 0x018d) && (__TURBOC__ <= 0x0200)) /* James: 0x0200 */ + " 2.0", +# elif (__TURBOC__ > 0x0100) + " 1.5", /* James: 0x0105? */ +# else + " 1.0", /* James: 0x0100 */ +# endif +# endif +#elif defined(MSC) + "Microsoft C ", +# ifdef _MSC_VER +# if (_MSC_VER == 800) + "(Visual C++ v1.1)", +# elif (_MSC_VER == 850) + "(Windows NT v3.5 SDK)", +# elif (_MSC_VER == 900) + "(Visual C++ v2.0/v2.1)", +# elif (_MSC_VER > 900) + (sprintf(buf2, "(Visual C++ v%d.%d)", _MSC_VER/100 - 6, + _MSC_VER%100/10), buf2), +# else + (sprintf(buf, "%d.%02d", _MSC_VER/100, _MSC_VER%100), buf), +# endif +# else + "5.1 or earlier", +# endif +#else + "unknown compiler", "", +#endif + + "MS-DOS", + +#if (defined(__GNUC__) || (defined(__WATCOMC__) && defined(__386__))) + " (32-bit)", +#elif defined(M_I86HM) || defined(__HUGE__) + " (16-bit, huge)", +#elif defined(M_I86LM) || defined(__LARGE__) + " (16-bit, large)", +#elif defined(M_I86MM) || defined(__MEDIUM__) + " (16-bit, medium)", +#elif defined(M_I86CM) || defined(__COMPACT__) + " (16-bit, compact)", +#elif defined(M_I86SM) || defined(__SMALL__) + " (16-bit, small)", +#elif defined(M_I86TM) || defined(__TINY__) + " (16-bit, tiny)", +#else + " (16-bit)", +#endif + +#ifdef __DATE__ + " on ", __DATE__ +#else + "", "" +#endif + ); + +} /* end function version_local() */ + + +#ifdef __WATCOMC__ + +/* This papers over a bug in Watcom 10.6's standard library... sigh */ +/* Apparently it applies to both the DOS and Win32 stat()s. */ + +int stat_bandaid(const char *path, struct stat *buf) +{ + char newname[4]; + if (!stat(path, buf)) + return 0; + else if (!strcmp(path, ".") || (path[0] && !strcmp(path + 1, ":."))) { + strcpy(newname, path); + newname[strlen(path) - 1] = '\\'; /* stat(".") fails for root! */ + return stat(newname, buf); + } else + return -1; +} + +#endif + + diff --git a/novell/README b/novell/README new file mode 100644 index 0000000..a620c1b --- /dev/null +++ b/novell/README @@ -0,0 +1,9 @@ +Unfinished integration into zip 2.4 of novell port to zip 2.2. + +TODO: + +Too much novell specific stuff via ifdef into the main sourcecode, +use atexit() and setjmp()/longjmp() constructions instead. + +If a function doesn't exist (e.g. isatty), just write a wrapper +and put it in Netware.c diff --git a/novell/m.cmd b/novell/m.cmd new file mode 100644 index 0000000..04084b3 --- /dev/null +++ b/novell/m.cmd @@ -0,0 +1,9 @@ +wmake + +copy zip.nlm f: + +attrib -r -h -s g:\hho\*.* /s +del g:\hho\Attrib\*.* +del g:\hho\Attrib\*.* +rmdir g:\hho\Attrib + diff --git a/novell/osdep.h b/novell/osdep.h new file mode 100644 index 0000000..f7b463c --- /dev/null +++ b/novell/osdep.h @@ -0,0 +1,205 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +/* The symbol DOS is used throughout the Zip source to identify code portions + * specific to the MSDOS port. + * Just to make sure, we check that it is set. + * (Currently, this should should not be neccessary, since currently it has + * to be set on the compiler command line to get this file read in.) + */ +#ifndef DOS +# define DOS +#endif + +/* The symbol MSDOS is consistently used in the generic source files + * to identify code to support for MSDOS (and MSDOS related) stuff. + * e.g: FAT or (FAT like) file systems, + * '\\' as directory separator in paths, + * "\r\n" as record (line) terminator in text files, ... + * + * IMPORTANT Note: + * This symbol is not unique for the MSDOS port !!!!!! + * It is also defined by ports to some other OS which are (to some extend) + * considered DOS compatible. + * Examples are: OS/2 (OS2), Windows NT and Windows 95 (WIN32). + * + */ +#ifndef MSDOS +# define MSDOS +#endif + +/* Power C is similar to Turbo C */ +#ifdef __POWERC +# define __TURBOC__ +#endif /* __POWERC */ + +/* Automatic setting of the common Microsoft C idenfifier MSC. + * NOTE: Watcom also defines M_I*86 ! + */ +#if defined(_MSC_VER) || (defined(M_I86) && !defined(__WATCOMC__)) +# ifndef MSC +# define MSC /* This should work for older MSC, too! */ +# endif +#endif + +#if !defined(__GO32__) && !defined(__EMX__) +# define NO_UNISTD_H +#endif + +#if defined(__WATCOMC__) && defined(__386__) +# define WATCOMC_386 +#endif + +#ifdef WINDLL +# define MSWIN +# define MEMORY16 +#endif + + +#if !defined(__EMX__) && !defined(__GO32__) && !defined(WATCOMC_386) +#if !defined(WINDLL) +# define MSDOS16 /* 16 bit MSDOS only */ +# define MEMORY16 +#endif +#endif + +#if !defined(NO_ASM) && !defined(ASMV) +# define ASMV +#endif + +/* enable creation of UTC time fields unless explicitely suppressed */ +#if !defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME) +# define USE_EF_UT_TIME +#endif + +/* check that TZ environment variable is defined before using UTC times */ +#if (!defined(NO_IZ_CHECK_TZ) && !defined(IZ_CHECK_TZ)) +# define IZ_CHECK_TZ +#endif + +#ifdef MEMORY16 +# ifndef NO_ASM +# define ASM_CRC 1 +# endif /* ?NO_ASM */ +# ifdef __TURBOC__ +# include +# if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__) +# if defined(DYNAMIC_CRC_TABLE) && defined(DYNALLOC_CRCTAB) + error: No dynamic CRC table allocation with Borland C far data models. +# endif /* DYNAMIC_CRC_TABLE */ +# endif /* Turbo/Borland C far data memory models */ +# define nearmalloc malloc +# define nearfree free +# define DYN_ALLOC +# else /* !__TURBOC__ */ +# include +# define nearmalloc _nmalloc +# define nearfree _nfree +# define farmalloc _fmalloc +# define farfree _ffree +# endif /* ?__TURBOC__ */ +# define MY_ZCALLOC 1 +# ifdef SMALL_MEM +# define CBSZ 2048 +# define ZBSZ 2048 +# endif +# ifdef MEDIUM_MEM +# define CBSZ 4096 +# define ZBSZ 4096 +# endif +# ifndef CBSZ +# define CBSZ 8192 +# define ZBSZ 8192 +# endif +#endif /* MEMORY16 */ + + +#ifdef MATCH +# undef MATCH +#endif +#define MATCH dosmatch /* use DOS style wildcard matching */ + +#define USE_CASE_MAP + +#define ROUNDED_TIME(time) (((time) + 1) & (~1)) +#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \ + procname(n, 1)) + +#define FOPR "rb" +#define FOPM "r+b" +#define FOPW "wb" + +#include +#include +#include + +#ifdef ZCRYPT_INTERNAL +# ifdef WINDLL +# define ZCR_SEED2 (unsigned)3141592654L /* use PI as seed pattern */ +# else +# ifndef __GO32__ +# include /* getpid() declaration for srand seed */ +# endif +# endif +#endif + +/* + * djgpp 1.x did not declare these + */ +#if defined(__GO32__) && !defined(__DJGPP__) +char *strlwr(char *); +int setmode(int, int); +#endif + +#ifdef __WATCOMC__ +# define NO_MKTEMP +# define HAS_OPENDIR +# define SSTAT stat_bandaid + int stat_bandaid(const char *path, struct stat *buf); + +/* Get asm routines to link properly without using "__cdecl": */ +# ifdef __386__ +# ifdef ASMV +# pragma aux match_init "_*" parm caller [] modify [] +# pragma aux longest_match "_*" parm caller [] value [eax] \ + modify [eax ecx edx] +# endif +# ifndef USE_ZLIB +# pragma aux crc32 "_*" parm caller [] value [eax] modify [eax] +# pragma aux get_crc_table "_*" parm caller [] value [eax] \ + modify [eax ecx edx] +# endif /* !USE_ZLIB */ +# else /* !__386__ */ +# ifdef ASMV +# pragma aux match_init "_*" parm caller [] loadds modify [ax bx] +# pragma aux longest_match "_*" parm caller [] loadds value [ax] \ + modify [ax bx cx dx es] +# endif /* ASMV */ +# ifndef USE_ZLIB +# pragma aux crc32 "_*" parm caller [] value [ax dx] \ + modify [ax bx cx dx es] +# pragma aux get_crc_table "_*" parm caller [] value [ax] \ + modify [ax bx cx dx] +# endif /* !USE_ZLIB */ +# endif /* ?__386__ */ +#endif /* __WATCOMC__ */ + +/* + * Wrapper function to get around the MSC7 00:00:00 31 Dec 1899 time base, + * see msdos.c for more info + */ + +#if defined(_MSC_VER) && _MSC_VER == 700 +# define localtime(t) msc7_localtime(t) +#endif + +#if (defined(__TURBOC__) && !defined(__BORLANDC__) && __TURBOC__ <= 0x0201) +# ifndef NO_MKTIME +# define NO_MKTIME /* TC 2.01 and earlier do not supply mktime() */ +# endif +#endif diff --git a/novell/signal.c b/novell/signal.c new file mode 100644 index 0000000..a092bd3 --- /dev/null +++ b/novell/signal.c @@ -0,0 +1,49 @@ +#include +#include + +/*******************************/ +/* Interupt handler */ +/*******************************/ + +int NLM_mainThreadGroupID; +int NLM_threadCnt = 0; +int NLM_exiting = FALSE; + +#pragma off(unreferenced); +void NLM_SignalHandler(int sig) +#pragma on(unreferenced); +{ + int handlerThreadGroupID; + + switch(sig) + { + case SIGTERM: + NLM_exiting = TRUE; + handlerThreadGroupID = GetThreadGroupID(); + SetThreadGroupID(NLM_mainThreadGroupID); + + /* NLM SDK functions may be called here */ + + while (NLM_threadCnt != 0) + ThreadSwitchWithDelay(); + SetThreadGroupID(handlerThreadGroupID); + break; + case SIGINT: + signal(SIGINT, NLM_SignalHandler); + break; + } + return; +} + +void NLMsignals(void) +{ + ++NLM_threadCnt; + NLM_mainThreadGroupID = GetThreadGroupID(); + signal(SIGTERM, NLM_SignalHandler); + signal(SIGINT, NLM_SignalHandler); +} + +void NLMexit(void) +{ + --NLM_threadCnt; +} diff --git a/novell/zip.lnk b/novell/zip.lnk new file mode 100644 index 0000000..19626c7 --- /dev/null +++ b/novell/zip.lnk @@ -0,0 +1,25 @@ +Form Novell NLM 'zip' +Name zip +Op ScreenName 'zip' +Op ThreadName 'zip__P ' +Op Stack = 8k +Op Version = 1.00.3 +Op Caseexact +Op Nod +File BITS.OBJ +File CRC_i386.OBJ +File CRYPT.OBJ +File DEFLATE.OBJ +File FILEIO.OBJ +File GLOBALS.OBJ +File MKTIME.OBJ +File NETWARE.OBJ +File TREES.OBJ +File TTYIO.OBJ +File UTIL.OBJ +File ZIP.OBJ +File ZIPFILE.OBJ +File ZIPUP.OBJ +File c:\novell\ndk\nwsdk\IMPORTS\PRELUDE.OBJ +Import @c:\novell\ndk\nwsdk\IMPORTS\ALL.IMP +Module CLib diff --git a/novell/zipup.h b/novell/zipup.h new file mode 100644 index 0000000..78b428a --- /dev/null +++ b/novell/zipup.h @@ -0,0 +1,16 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#define fhow (O_RDONLY|O_BINARY) +#define fbad (-1) +typedef int ftype; +#define zopen(n,p) open(n,p) +#define zread(f,b,n) read(f,b,n) +#define zclose(f) close(f) +#define zerr(f) (k == (extent)(-1L)) +#define zstdin 0 diff --git a/os2/makefile.os2 b/os2/makefile.os2 new file mode 100644 index 0000000..a008ea5 --- /dev/null +++ b/os2/makefile.os2 @@ -0,0 +1,563 @@ +# Makefile for Zip, ZipCloak, ZipNote and ZipSplit + +# Supported Make utilities: +# - Microsoft/IBM nmake +# - dmake 3.8 or higher +# - GNU make, at least version 3.68 +# - NOT watcom make +# For Microsoft and Watcom C, better use NMAKE, +# otherwise it doesn't matter. + +# Supported 16-bit C Compilers (created programs run under OS/2 1.x and 2.x): +# - Microsoft C 6.00A +# - Watcom C/C++ 16-bit + +# Supported 32-bit C Compilers (created programs run under OS/2 2.x only): +# - GNU gcc (emx kit 0.9c or newer) +# - IBM C Set/2 or C Set++ - does not yet work with ASM code +# - Watcom C/C++ 32-bit - does not yet work with ASM code +# - Borland C++ - no ASM code yet +# - MetaWare High C/C++ - no ASM code yet + +# Supported Cross-Compilers for MS-DOS: +# - Microsoft C 6.00A (16-bit) +# - Watcom C/C++ (16- and 32-bit) +# - GNU gcc (emx kit 0.9c or newer, 32-bit) + +# Supported Cross-Compilers for Win32 (WinNT/Win95): +# - GNU gcc (emx kit 0.9c or newer, with RSXNT 1.4 or newer) + +# Supported Assemblers: +# - Microsoft MASM 6.00 with Microsoft C, IBM C +# - Watcom WASM with Watcom C/C++ +# - GNU as with GNU gcc + +# To use MASM 5.x instead of MASM 6.00: +# - set AS="masm -T -Ml" +# - set ASEOL=";" + + +# To use, enter "make/nmake/dmake -f os2/makefile.os2" +# (this makefile depends on its name being "os2/makefile.os2"). + +# Add -DNO_ASM to CFLAGS and define OBJA to `nothing' if you do not have +# masm or ml. +# Add -DDYN_ALLOC to ASFLAGS if you have defined it in tailor.h or CFLAGS + +# Note: assembly language modules are really only supported for +# Microsoft 16-bit and GNU gcc 32-bit compilation. + +# Notes on 16-bit (Microsoft C 6.00) compilation: + +# The resulting programs can be used under OS/2 protected mode only. +# A larger stack has to be used for OS/2 because system calls +# use more stack than under DOS, 8k is recommended by Microsoft. +# Note that __STDC__ has to be defined explicitly with C 6.00 when -Ze +# is given, because Microsoft disables __STDC__ when their extensions +# are enabled. This is different from the C 5.10 behaviour. + +# Notes on 32-bit OS/2 compilation: + +# The resulting programs can be used under OS/2 protected +# mode of OS/2 2.x only, not under 1.x and not under DOS. +# It makes no difference if __STDC__ is defined or not. +# Borland C++ works with DYN_ALLOC only. + +# Special Notes on IBM C/C++ compilation: + +# The older C compiler (C Set/2) breaks, while optimizing, on deflate.c +# and trees.c (generates incorrect code). The newer C++ compiler (C Set++) +# doesn't but instead breaks on crypt.c in the initial version and up to +# CSD level 003. Starting with CSD level 004, it doesn't break any longer. + +# Notes on Watcom C/C++ compilation for DOS with the PMODE/W extender: +# +# You need to add the following section to your \watcom\binb\wlsystem.lnk +# file and also need to copy pmodew.exe to the same directory: +# +# system begin pmodew +# option osname='PMODE/W' +# libpath %WATCOM%\lib386 +# libpath %WATCOM%\lib386\dos +# op stub=pmodew.exe +# format os2 le +# end +# +# PMODE/W 1.16 or higher is required. + + +default: + @echo "Enter $(MAKE) -f os2/makefile.os2 target" + @echo "where target is one of:" + @echo " msc mscdos ibm ibmdyn ibmdebug ibmprof metaware borland" + @echo " gcc gccdyn gcczlib gccdebug gccdos gccwin32 gccw32dyn" + @echo " watcom watcom16 watcomdos watcom16dos pmodew" + +# MS C 6.00 for OS/2, 16-bit +msc: + $(MAKE) -f os2/makefile.os2 zips \ + CC="cl -nologo -AL -Ocegit -Gs $(FP)" \ + CFLAGS="-W1 -Zep -J -G2 -D__STDC__ -DOS2 -DASM_CRC" \ + AS="ml -nologo -c -Zm -Cp" \ + ASFLAGS="-D__LARGE__ -D__286" \ + LDFLAGS="-F 2000 -Lp -Fe" \ + LDFLAGS2="-link /noe /pm:vio" \ + OUT="-Fo" \ + OBJ=".obj" \ + CRCA_O="crc_i86.obj" \ + OBJA="match.obj" \ + DEF="os2\zip.def" + +# MS C 6.00 for OS/2, 16-bit, debug +mscdebug: + $(MAKE) -f os2/makefile.os2 zips \ + CC="cl -nologo -AL -Zi -Od $(FP)" \ + CFLAGS="-W1 -Zep -J -G2 -D__STDC__ -DOS2 -DASM_CRC" \ + AS="ml -nologo -c -Zim -Cp" \ + ASFLAGS="-D__LARGE__ -D__286" \ + LDFLAGS="-F 2000 -Lp -Fe" \ + LDFLAGS2="-link /noe /pm:vio" \ + OUT="-Fo" \ + OBJ=".obj" \ + CRCA_O="crc_i86.obj" \ + OBJA="match.obj" \ + DEF="os2\zip.def" + +# crosscompilation for MS-DOS with MS C 6.00 +mscdos: + $(MAKE) -f os2/makefile.os2 zips \ + CC="cl -nologo -AL -Ocegit -Gs $(FP)" \ + CFLAGS="-W1 -Zep -J -D__STDC__ -DDOS -DASM_CRC -DDYN_ALLOC" \ + AS="ml -nologo -c -Zm -Cp" \ + ASFLAGS="-D__LARGE__ -DDYN_ALLOC" \ + LDFLAGS="-F 2000 -Lr -Fe" \ + LDFLAGS2="-link /noe /exe" \ + OUT="-Fo" \ + OBJ=".obj" \ + CRCA_O="crc_i86.obj" \ + OBJA="match.obj" \ + OBJ2="msdos.obj" OBJU2="msdos_.obj" \ + OSDEP_H="msdos/osdep.h" ZIPUP_H="msdos/zipup.h" + + +# IBM C Set/2, statically linked runtime +ibm: + $(MAKE) -f os2/makefile.os2 zips \ + CC="icc -Q -O -Gs" \ + CFLAGS="-Sm -Sp1 -DOS2 -DNO_ASM" \ + AS="ml -nologo -c -Zm -Cp" \ + ASFLAGS="" \ + LDFLAGS="-B/ST:0x50000 -Fe" \ + LDFLAGS2="" \ + OUT="-Fo" \ + OBJ=".obj" \ + OBJA="" \ + DEF="os2/zip.def" + +# IBM C Set/2, dynamically linked runtime +ibmdyn: + $(MAKE) -f os2/makefile.os2 zips \ + CC="icc -Q -O -Gd -Gs" \ + CFLAGS="-Sm -Sp1 -DOS2 -DNO_ASM" \ + AS="ml -nologo -c -Zm -Cp" \ + ASFLAGS="" \ + LDFLAGS="-B/ST:0x50000 -Fe" \ + LDFLAGS2="" \ + OUT="-Fo" \ + OBJ=".obj" \ + OBJA="" \ + DEF="os2/zip.def" + +# IBM C Set/2, debug version +ibmdebug: + $(MAKE) -f os2/makefile.os2 zips \ + CC="icc -Q -Ti" \ + CFLAGS="-Sm -Sp1 -DOS2 -DNO_ASM -Tm" \ + AS="ml -nologo -c -Zim -Cp" \ + ASFLAGS="" \ + LDFLAGS="-B/ST:0x50000 -Fe" \ + LDFLAGS2="" \ + OUT="-Fo" \ + OBJ=".obj" \ + OBJA="" \ + DEF="os2/zip.def" + +# IBM C Set/2, profiling version for PROFIT +ibmprof: + $(MAKE) -f os2/makefile.os2 zips \ + CC="icc -Q -O -Gs -Gh -Ti" \ + CFLAGS="-Sm -Sp1 -DOS2 -DNO_ASM" \ + AS="ml -nologo -c -Zm -Cp" \ + ASFLAGS="" \ + LDFLAGS="-B/ST:0x50000 -Fe" \ + LDFLAGS2="profit.obj" \ + OUT="-Fo" \ + OBJ=".obj" \ + OBJA="" \ + DEF="os2/zip.def" + +# Watcom C/386 9.0 or higher +watcom: + $(MAKE) -f os2/makefile.os2 zips \ + CC="wcl386 -bt=os2v2 -zq -Ox -s" \ + CFLAGS="-Zp1 -DOS2 -DNO_ASM" \ + AS="wasm -zq -bt=os2v2 -3p" \ + ASFLAGS="" \ + LDFLAGS="-k0x50000 -x -l=os2v2 -Fe=" \ + LDFLAGS2="" \ + OUT="-Fo" \ + OBJ=".obj" \ + OBJA="" \ + DIRSEP="\\" \ + AS_DIRSEP="\\" + +# Watcom C/286 9.0 or higher +watcom16: + $(MAKE) -f os2/makefile.os2 zips \ + CC="wcl -bt=os2 -zq -ml -Ox -s" \ + CFLAGS="-Zp1 -DOS2 -DNO_ASM" \ + AS="wasm -zq -bt=os2 -2p -ml" \ + ASFLAGS="" \ + LDFLAGS="/\"option newfiles\" -k0x3000 -x -l=os2 -Fe=" \ + LDFLAGS2="" \ + OUT="-Fo" \ + OBJ=".obj" \ + OBJA="" \ + DIRSEP="\\" \ + AS_DIRSEP="\\" + +# Watcom C/386 9.0 or higher, crosscompilation for DOS, DOS4GW extender +watcomdos: + $(MAKE) -f os2/makefile.os2 zips \ + CC="wcl386 -bt=dos4g -zq -Ox -s" \ + CFLAGS="-Zp1 -DDOS -DMSDOS -DASM_CRC" \ + AS="wasm -zq -bt=dos4g -3p" \ + ASFLAGS="-DWATCOM_DSEG" \ + LDFLAGS="-k0x50000 -x -l=dos4g -Fe=" \ + LDFLAGS2="" \ + OUT="-Fo" \ + OBJ=".obj" \ + CRCA_O="crc_i386.obj" \ + OBJA="match32.obj" \ + OBJ2="msdos.obj" \ + OBJU2="msdos_.obj" \ + OSDEP_H="msdos/osdep.h" \ + ZIPUP_H="msdos/zipup.h" \ + DIRSEP="\\" \ + AS_DIRSEP="\\" + +# Watcom C/386 9.0 or higher, crosscompilation for DOS, PMODE/W extender +pmodew: + $(MAKE) -f os2/makefile.os2 zips \ + CC="wcl386 -bt=dos4g -zq -Ox -s" \ + CFLAGS="-Zp1 -DDOS -DMSDOS -DASM_CRC" \ + AS="wasm -zq -bt=dos4g -3p" \ + ASFLAGS="-DWATCOM_DSEG" \ + LDFLAGS="-k0x50000 -x -l=pmodew -Fe=" \ + LDFLAGS2="" \ + OUT="-Fo" \ + OBJ=".obj" \ + CRCA_O="crc_i386.obj" \ + OBJA="match32.obj" \ + OBJ2="msdos.obj" \ + OBJU2="msdos_.obj" \ + OSDEP_H="msdos/osdep.h" \ + ZIPUP_H="msdos/zipup.h" \ + DIRSEP="\\" \ + AS_DIRSEP="\\" + +# Watcom C/286 9.0 or higher, crosscompilation for DOS +watcom16dos: + $(MAKE) -f os2/makefile.os2 zips \ + CC="wcl -bt=dos -zq -ml -Ox -s" \ + CFLAGS="-Zp1 -DDOS -DMSDOS -DDYN_ALLOC -DNO_ASM" \ + AS="wasm -zq -bt=dos -2 -ml" \ + ASFLAGS="-DDYN_ALLOC" \ + LDFLAGS="-k0x2000 -x -l=dos -Fe=" \ + LDFLAGS2="" \ + OUT="-Fo" \ + OBJ=".obj" \ + OBJA="" \ + OBJ2="msdos.obj" \ + OBJU2="msdos_.obj" \ + OSDEP_H="msdos/osdep.h" \ + ZIPUP_H="msdos/zipup.h" \ + DIRSEP="\\" \ + AS_DIRSEP="\\" + +# MetaWare High C/C++ 3.2 +metaware: + $(MAKE) -f os2/makefile.os2 zips \ + CC="hc -O2" \ + CFLAGS="-D__32BIT__ -DOS2 -DNO_ASM" \ + AS="ml -nologo -c -Zm -Cp" \ + ASFLAGS="" \ + LDFLAGS="-o " \ + LDFLAGS2="" \ + OUT="-o ./" \ + OBJ=".obj" \ + DEF="-Hdef=os2/zip.def" + +# Borland C++ +borland: + $(MAKE) -f os2/makefile.os2 zips \ + CC="bcc -O" \ + CFLAGS="-w- -DOS2 -DDYN_ALLOC -DNO_ASM" \ + AS="ml -nologo -c -Zm -Cp" \ + ASFLAGS="" \ + LDFLAGS="-e" \ + LDFLAGS2="" \ + OUT="-o" \ + OBJ=".obj" \ + OBJA="" \ + DEF="-sDos2/zip.def" + +# emx 0.9c, gcc, OMF format, statically linked C runtime and emx +gcc: + $(MAKE) -f os2/makefile.os2 zips \ + CC="gcc -Zomf -O -Wimplicit" \ + CFLAGS="-DOS2 -DASM_CRC" \ + AS="gcc -Zomf" \ + ASFLAGS="-Di386" \ + LDFLAGS="-o ./" \ + LDFLAGS2="-Zsys -Zstack 320 -s -Zsmall-conv" \ + OUT="-o" \ + OBJ=".obj" \ + CRCA_O="crc_gcc.obj" \ + OBJA="matchgcc.obj" \ + DEF="os2/zip.def" + +# emx 0.9c, gcc, OMF format, dynamically linked C runtime and emx +gccdyn: + $(MAKE) -f os2/makefile.os2 zips \ + CC="gcc -Zomf -O -Wimplicit" \ + CFLAGS="-DOS2 -DASM_CRC" \ + AS="gcc -Zomf" \ + ASFLAGS="-Di386" \ + LDFLAGS="-o ./" \ + LDFLAGS2="-Zcrtdll -Zstack 320 -s" \ + OUT="-o" \ + OBJ=".obj" \ + CRCA_O="crc_gcc.obj" \ + OBJA="matchgcc.obj" \ + DEF="os2/zip.def" + +# emx 0.9c, gcc, OMF format, statically linked zlib, C runtime, and emx +gcczlib: + $(MAKE) -f os2/makefile.os2 zips \ + CC="gcc -Zomf -O -Wimplicit" \ + CFLAGS="-DOS2 -DUSE_ZLIB" \ + AS="gcc -Zomf" \ + ASFLAGS="-Di386 -DUSE_ZLIB" \ + LDFLAGS="-o ./" \ + LDFLAGS2="-L. -lzlib -Zsys -Zstack 320 -s -Zsmall-conv" \ + OUT="-o" \ + OBJ=".obj" \ + CRCA_O="" \ + OBJA="" \ + DEF="os2/zip.def" + +# emx 0.9c, gcc, a.out format, with debug info for gdb +gccdebug: + $(MAKE) -f os2/makefile.os2 zips \ + CC="gcc -g -Wimplicit" \ + CFLAGS="-DOS2 -DASM_CRC" \ + AS="gcc" \ + ASFLAGS="-Di386" \ + LDFLAGS="-o ./" \ + LDFLAGS2="" \ + OUT="-o" \ + OBJ=".o" \ + CRCA_O="crc_gcc.o" \ + OBJA="matchgcc.o" \ + DEF="os2/zip.def" + +# emx 0.9c, gcc, a.out format, for MS-DOS +gccdos: + $(MAKE) -f os2/makefile.os2 zips \ + CC="gcc -O -Wimplicit" \ + CFLAGS="-DDOS -DMSDOS -DASM_CRC" \ + AS="gcc" \ + ASFLAGS="-Di386" \ + LDFLAGS="-o ./" \ + LDFLAGS2="-s -Zsmall-conv" \ + OUT="-o" \ + OBJ=".o" \ + CRCA_O="crc_gcc.o" \ + OBJA="matchgcc.o" \ + OBJ2="msdos.o" \ + OBJU2="msdos_.o" \ + OSDEP_H="msdos/osdep.h" \ + ZIPUP_H="msdos/zipup.h" + +# emx 0.9c, gcc, RSXNT 1.4, cross-compilation for Win32 +gccwin32: + $(MAKE) -f os2/makefile.os2 zips \ + CC="gcc -Zwin32 -O -m486 -Wall" \ + CFLAGS="-DWIN32 -DASM_CRC" \ + AS="gcc -Zwin32" \ + ASFLAGS="-Di386" \ + LDFLAGS="-o ./" \ + LDFLAGS2="-ladvapi32 -Zsys -Zsmall-conv -s" \ + OUT="-o" \ + OBJ=".o" \ + CRCA_O="crc_gcc.o" \ + OBJA="matchgcc.o" \ + OBJ2="win32zip.o win32.o nt.o" \ + OBJU2="win32_.o" \ + OSDEP_H="win32/osdep.h" \ + ZIPUP_H="win32/zipup.h" \ + DEF="win32/zip.def" + +# emx 0.9c, gcc, RSXNT 1.4, cross-compilation for Win32, use emx C rtl DLL +gccw32dyn: + $(MAKE) -f os2/makefile.os2 zips \ + CC="gcc -Zwin32 -Zcrtdll=crtrsxnt -O -m486 -Wall" \ + CFLAGS="-DWIN32 -DASM_CRC" \ + AS="gcc -Zwin32" \ + ASFLAGS="-Di386" \ + LDFLAGS="-o ./" \ + LDFLAGS2="-ladvapi32 -s" \ + OUT="-o" \ + OBJ=".o" \ + CRCA_O="crc_gcc.o" \ + OBJA="matchgcc.o" \ + OBJ2="win32zip.o win32.o nt.o" \ + OBJU2="win32_.o" \ + OSDEP_H="win32/osdep.h" \ + ZIPUP_H="win32/zipup.h" \ + DEF="win32/zip.def" + +# VPATH = .;os2 + +# variables + +#default settings for target dependent macros: +DIRSEP = / +AS_DIRSEP = / +# LOCAL_OPTS = +CCFLAGS = $(CFLAGS) $(LOCAL_OPTS) + +OSDEP_H = os2/osdep.h +ZIPUP_H = os2/os2zip.h os2/zipup.h +CRCA_O = + + +OBJZ = zip$(OBJ) zipfile$(OBJ) zipup$(OBJ) fileio$(OBJ) util$(OBJ) \ + crc32$(OBJ) $(CRCA_O) globals$(OBJ) \ + deflate$(OBJ) trees$(OBJ) crypt$(OBJ) ttyio$(OBJ) +OBJ2 = os2zip$(OBJ) os2$(OBJ) os2acl$(OBJ) + +OBJU = zipfile_$(OBJ) fileio_$(OBJ) util_$(OBJ) globals$(OBJ) +OBJU2 = os2zip_$(OBJ) + +OBJN = zipnote$(OBJ) $(OBJU) $(OBJU2) +OBJS = zipsplit$(OBJ) $(OBJU) $(OBJU2) +OBJC = zipcloak$(OBJ) crc32_$(OBJ) crypt_$(OBJ) ttyio$(OBJ) $(OBJU) $(OBJU2) + +ZIP_H = zip.h ziperr.h tailor.h $(OSDEP_H) + +# rules + +.SUFFIXES: .c $(OBJ) + +.c$(OBJ): + $(CC) -c -I. $(CCFLAGS) $< + +.asm$(OBJ): + $(AS) $(ASFLAGS) $< $(ASEOL) + +# targets + +zips: zip.exe zipnote.exe zipsplit.exe zipcloak.exe + +zip$(OBJ): zip.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +zipfile$(OBJ): zipfile.c $(ZIP_H) crc32.h +zipup$(OBJ): zipup.c $(ZIP_H) revision.h crc32.h crypt.h $(ZIPUP_H) +fileio$(OBJ): fileio.c $(ZIP_H) crc32.h +util$(OBJ): util.c $(ZIP_H) +globals$(OBJ): globals.c $(ZIP_H) +deflate$(OBJ): deflate.c $(ZIP_H) +trees$(OBJ): trees.c $(ZIP_H) +crc32$(OBJ): crc32.c $(ZIP_H) crc32.h +crypt$(OBJ): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h +ttyio$(OBJ): ttyio.c $(ZIP_H) crypt.h ttyio.h + +os2zip$(OBJ): os2/os2zip.c $(ZIP_H) os2/os2zip.h os2/os2acl.h + $(CC) -c -I. $(CCFLAGS) os2$(DIRSEP)os2zip.c + +os2$(OBJ): os2/os2.c $(ZIP_H) os2/os2zip.h + $(CC) -c -I. $(CCFLAGS) os2$(DIRSEP)os2.c + +os2acl$(OBJ): os2/os2acl.c os2/os2acl.h + $(CC) -c -I. $(CCFLAGS) os2$(DIRSEP)os2acl.c + +msdos$(OBJ): msdos/msdos.c $(ZIP_H) + $(CC) -c -I. $(CCFLAGS) msdos$(DIRSEP)msdos.c + +win32zip$(OBJ): win32/win32zip.c $(ZIP_H) win32/win32zip.h win32/nt.h + $(CC) -c -I. $(CCFLAGS) win32$(DIRSEP)win32zip.c + +win32$(OBJ): win32/win32.c $(ZIP_H) win32/win32zip.h + $(CC) -c -I. $(CCFLAGS) win32$(DIRSEP)win32.c + +nt$(OBJ): win32/nt.c win32/nt.h + $(CC) -c -I. $(CCFLAGS) win32$(DIRSEP)nt.c + +crc_i86$(OBJ): msdos/crc_i86.asm # 16bit only + $(AS) $(ASFLAGS) msdos$(AS_DIRSEP)crc_i86.asm $(ASEOL) + +crc_i386$(OBJ): win32/crc_i386.asm # 32bit, MASM + $(AS) $(ASFLAGS) win32$(AS_DIRSEP)crc_i386.asm $(ASEOL) + +crc_gcc$(OBJ): crc_i386.S # 32bit, GNU AS + $(AS) $(ASFLAGS) -x assembler-with-cpp -c -o $@ crc_i386.S + +match$(OBJ): msdos/match.asm + $(AS) $(ASFLAGS) msdos$(AS_DIRSEP)match.asm $(ASEOL) + +match32$(OBJ): win32/match32.asm + $(AS) $(ASFLAGS) win32$(AS_DIRSEP)match32.asm + +matchgcc$(OBJ): match.S + $(AS) $(ASFLAGS) -x assembler-with-cpp -c -o $@ match.S + +zipcloak$(OBJ): zipcloak.c $(ZIP_H) revision.h crc32.h crypt.h ttyio.h +zipnote$(OBJ): zipnote.c $(ZIP_H) revision.h +zipsplit$(OBJ): zipsplit.c $(ZIP_H) revision.h + +zipfile_$(OBJ): zipfile.c $(ZIP_H) crc32.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ zipfile.c + +fileio_$(OBJ): fileio.c $(ZIP_H) crc32.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ fileio.c + +util_$(OBJ): util.c $(ZIP_H) os2/os2zip.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ util.c + +crc32_$(OBJ): crc32.c $(ZIP_H) crc32.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ crc32.c + +crypt_$(OBJ): crypt.c $(ZIP_H) crypt.h crc32.h ttyio.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ crypt.c + +os2zip_$(OBJ): os2/os2zip.c $(ZIP_H) os2/os2zip.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ os2$(DIRSEP)os2zip.c + +msdos_$(OBJ): msdos/msdos.c $(ZIP_H) + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ msdos$(DIRSEP)msdos.c + +win32_$(OBJ): win32/win32.c $(ZIP_H) win32/win32zip.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ win32$(DIRSEP)win32.c + +zip.exe: $(OBJZ) $(OBJ2) $(OBJA) + $(CC) $(LDFLAGS)$@ $(DEF) $(OBJZ) $(OBJ2) $(OBJA) $(LDFLAGS2) + +zipcloak.exe: $(OBJC) + $(CC) $(LDFLAGS)$@ $(DEF) $(OBJC) $(LDFLAGS2) + +zipnote.exe: $(OBJN) + $(CC) $(LDFLAGS)$@ $(DEF) $(OBJN) $(LDFLAGS2) + +zipsplit.exe: $(OBJS) + $(CC) $(LDFLAGS)$@ $(DEF) $(OBJS) $(LDFLAGS2) diff --git a/os2/match32.asm b/os2/match32.asm new file mode 100644 index 0000000..4797a73 --- /dev/null +++ b/os2/match32.asm @@ -0,0 +1,175 @@ +;=========================================================================== +; Copyright (c) 1990-2005 Info-ZIP. All rights reserved. +; +; See the accompanying file LICENSE, version 2005-Feb-10 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, all these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +;=========================================================================== +; +; match32.asm by Jean-loup Gailly. + +; match32.asm, optimized version of longest_match() in deflate.c +; To be used only with 32 bit flat model. To simplify the code, the option +; -DDYN_ALLOC is not supported. +; This file is only optional. If you don't have an assembler, use the +; C version (add -DNO_ASM to CFLAGS in makefile and remove match.o +; from OBJI). If you have reduced WSIZE in zip.h, then make sure this is +; assembled with an equivalent -DWSIZE=. + +; Caution: this module works for IBM's C/C++ compiler versions 2 and 3 +; and for Watcom's 32-bit C/C++ compiler. Both pass the first (and only) +; argument for longest_match in the EAX register, not on the stack, with +; the default calling conventions (_System would use the stack). +; +;============================================================================== +; +; Do NOT assemble this source if external crc32 routine from zlib gets used. +; + IFNDEF USE_ZLIB +; + .386 + + name match + +BSS32 segment dword USE32 public 'BSS' + extrn window : byte + extrn prev : word + extrn prev_length : dword + extrn strstart : dword + extrn match_start : dword + extrn max_chain_length : dword + extrn good_match : dword + extrn nice_match : dword +BSS32 ends + +CODE32 segment dword USE32 public 'CODE' + assume cs:CODE32, ds:FLAT, ss:FLAT + + public match_init + public longest_match + + ifndef WSIZE + WSIZE equ 32768 ; keep in sync with zip.h ! + endif + MIN_MATCH equ 3 + MAX_MATCH equ 258 + MIN_LOOKAHEAD equ (MAX_MATCH+MIN_MATCH+1) + MAX_DIST equ (WSIZE-MIN_LOOKAHEAD) + +; initialize or check the variables used in match.asm. + +match_init proc near + ret +match_init endp + +; ----------------------------------------------------------------------- +; Set match_start to the longest match starting at the given string and +; return its length. Matches shorter or equal to prev_length are discarded, +; in which case the result is equal to prev_length and match_start is +; garbage. +; IN assertions: cur_match is the head of the hash chain for the current +; string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + +; int longest_match(cur_match) + +longest_match proc near + + ; return address ; esp+16 + push ebp ; esp+12 + push edi ; esp+8 + push esi ; esp+4 + + lea ebx,window + add ebx,2 + window_off equ dword ptr [esp] + push ebx ; esp + +; match equ esi +; scan equ edi +; chain_length equ ebp +; best_len equ ebx +; limit equ edx + + mov esi,eax ; cur_match + mov edx,strstart + mov ebp,max_chain_length ; chain_length = max_chain_length + mov edi,edx + sub edx,MAX_DIST ; limit = strstart-MAX_DIST + cld ; string ops increment esi and edi + jae short limit_ok + sub edx,edx ; limit = NIL +limit_ok: + add edi,window_off ; edi = offset(window + strstart + 2) + mov ebx,prev_length ; best_len = prev_length + mov cx,[edi-2] ; cx = scan[0..1] + mov ax,[ebx+edi-3] ; ax = scan[best_len-1..best_len] + cmp ebx,good_match ; do we have a good match already? + jb do_scan + shr ebp,2 ; chain_length >>= 2 + jmp short do_scan + + align 4 ; align destination of branch +long_loop: +; at this point, edi == scan+2, esi == cur_match + mov ax,[ebx+edi-3] ; ax = scan[best_len-1..best_len] + mov cx,[edi-2] ; cx = scan[0..1] +short_loop: +; at this point, edi == scan+2, esi == cur_match, +; ax = scan[best_len-1..best_len] and cx = scan[0..1] + and esi,WSIZE-1 ; not needed if WSIZE=32768 + dec ebp ; --chain_length + shl esi,1 ; cur_match as word index + mov si,prev[esi] ; cur_match = prev[cur_match] + ; top word of esi is still 0 + jz the_end + cmp esi,edx ; cur_match <= limit ? + jbe short the_end +do_scan: + cmp ax,word ptr window[ebx+esi-1] ; check match at best_len-1 + jne short_loop + cmp cx,word ptr window[esi] ; check min_match_length match + jne short_loop + + add esi,window_off ; esi = match + mov ecx,(MAX_MATCH-2)/2 ; scan for at most MAX_MATCH bytes + mov eax,edi ; eax = scan+2 + repe cmpsw ; loop until mismatch + je maxmatch ; match of length MAX_MATCH? +mismatch: + mov cl,[edi-2] ; mismatch on first or second byte? + xchg eax,edi ; edi = scan+2, eax = end of scan + sub cl,[esi-2] ; cl = 0 if first bytes equal + sub eax,edi ; eax = len + sub esi,window_off ; esi = match - (2 + offset(window)) + sub esi,eax ; esi = cur_match (= match - len) + sub cl,1 ; set carry if cl == 0 (can't use DEC) + adc eax,0 ; eax = carry ? len+1 : len + cmp eax,ebx ; len > best_len ? + jle long_loop + mov match_start,esi ; match_start = cur_match + mov ebx,eax ; ebx = best_len = len + ifdef FULL_SEARCH + cmp eax,MAX_MATCH ; len >= MAX_MATCH ? + else + cmp eax,nice_match ; len >= nice_match ? + endif + jl long_loop +the_end: + mov eax,ebx ; result = eax = best_len + pop ebx + pop esi + pop edi + pop ebp + ret +maxmatch: ; come here if maximum match + cmpsb ; increment esi and edi + jmp mismatch ; force match_length = MAX_LENGTH + +longest_match endp + +CODE32 ends +; + ENDIF ; !USE_ZLIB +; + end diff --git a/os2/os2.c b/os2/os2.c new file mode 100644 index 0000000..b44fe2e --- /dev/null +++ b/os2/os2.c @@ -0,0 +1,481 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2005-Feb-10 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#include "zip.h" + +#ifndef UTIL /* the companion #endif is a bit of ways down ... */ + +#include +#if defined(__IBMC__) || defined(MSC) +#include +#endif + +/* Extra malloc() space in names for cutpath() */ +#define PAD 0 +#define PATH_END '/' + + +#include "os2zip.h" + +/* Library functions not in (most) header files */ + +extern char *label; +local ulg label_time = 0; +local ulg label_mode = 0; +local time_t label_utim = 0; + +/* Local functions */ +local char *readd OF((DIR *)); + + +local char *readd(d) +DIR *d; /* directory stream to read from */ +/* Return a pointer to the next name in the directory stream d, or NULL if + no more entries or an error occurs. */ +{ + struct dirent *e; + + e = readdir(d); + return e == NULL ? (char *) NULL : e->d_name; +} + +int wild(w) +char *w; /* path/pattern to match */ +/* If not in exclude mode, expand the pattern based on the contents of the + file system. Return an error code in the ZE_ class. */ +{ + DIR *d; /* stream for reading directory */ + char *e; /* name found in directory */ + int r; /* temporary variable */ + char *n; /* constructed name from directory */ + int f; /* true if there was a match */ + char *a; /* alloc'ed space for name */ + char *p; /* path */ + char *q; /* name */ + char v[5]; /* space for device current directory */ + + if (volume_label == 1) { + volume_label = 2; + label = getVolumeLabel((w != NULL && w[1] == ':') ? to_up(w[0]) : '\0', + &label_time, &label_mode, &label_utim); + if (label != NULL) { + newname(label, 0, 0); + } + if (w == NULL || (w[1] == ':' && w[2] == '\0')) return ZE_OK; + /* "zip -$ foo a:" can be used to force drive name */ + } + + if (w == NULL) + return ZE_OK; + + /* special handling of stdin request */ + if (strcmp(w, "-") == 0) /* if compressing stdin */ + return newname(w, 0, 0); + + /* Allocate and copy pattern */ + if ((p = a = malloc(strlen(w) + 1)) == NULL) + return ZE_MEM; + strcpy(p, w); + + /* catch special case: treat "*.*" as "*" for DOS-impaired people */ + r = strlen(p); + if (strcmp(p + r - 3, "*.*") == 0) + p[r - 2] = '\0'; + + /* Normalize path delimiter as '/'. */ + for (q = p; *q; q++) /* use / consistently */ + if (*q == '\\') + *q = '/'; + + /* Only name can have special matching characters */ + if ((q = isshexp(p)) != NULL && + (strrchr(q, '/') != NULL || strrchr(q, ':') != NULL)) + { + free((zvoid *)a); + return ZE_PARMS; + } + + /* Separate path and name into p and q */ + if ((q = strrchr(p, '/')) != NULL && (q == p || q[-1] != ':')) + { + *q++ = '\0'; /* path/name -> path, name */ + if (*p == '\0') /* path is just / */ + p = strcpy(v, "/."); + } + else if ((q = strrchr(p, ':')) != NULL) + { /* has device and no or root path */ + *q++ = '\0'; + p = strcat(strcpy(v, p), ":"); /* copy device as path */ + if (*q == '/') /* -> device:/., name */ + { + strcat(p, "/"); + q++; + } + strcat(p, "."); + } + else if (recurse && (strcmp(p, ".") == 0 || strcmp(p, "..") == 0)) + { /* current or parent directory */ + /* I can't understand Mark's code so I am adding a hack here to get + * "zip -r foo ." to work. Allow the dubious "zip -r foo .." but + * reject "zip -rm foo ..". + */ + if (dispose && strcmp(p, "..") == 0) + ziperr(ZE_PARMS, "cannot remove parent directory"); + q = "*"; + } + else /* no path or device */ + { + q = p; + p = strcpy(v, "."); + } + if (recurse && *q == '\0') { + q = "*"; + } + /* Search that level for matching names */ + if ((d = opendir(p)) == NULL) + { + free((zvoid *)a); + return ZE_MISS; + } + if ((r = strlen(p)) > 1 && + (strcmp(p + r - 2, ":.") == 0 || strcmp(p + r - 2, "/.") == 0)) + *(p + r - 1) = '\0'; + f = 0; + while ((e = readd(d)) != NULL) { + if (strcmp(e, ".") && strcmp(e, "..") && MATCH(q, e, 0)) + { + f = 1; + if (strcmp(p, ".") == 0) { /* path is . */ + r = procname(e, 0); /* name is name */ + if (r) { + f = 0; + break; + } + } else + { + if ((n = malloc(strlen(p) + strlen(e) + 2)) == NULL) + { + free((zvoid *)a); + closedir(d); + return ZE_MEM; + } + n = strcpy(n, p); + if (n[r = strlen(n) - 1] != '/' && n[r] != ':') + strcat(n, "/"); + r = procname(strcat(n, e), 0); /* name is path/name */ + free((zvoid *)n); + if (r) { + f = 0; + break; + } + } + } + } + closedir(d); + + /* Done */ + free((zvoid *)a); + return f ? ZE_OK : ZE_MISS; +} + +int procname(n, caseflag) +char *n; /* name to process */ +int caseflag; /* true to force case-sensitive match */ +/* Process a name or sh expression to operate on (or exclude). Return + an error code in the ZE_ class. */ +{ + char *a; /* path and name for recursion */ + DIR *d; /* directory stream from opendir() */ + char *e; /* pointer to name from readd() */ + int m; /* matched flag */ + char *p; /* path for recursion */ + struct stat s; /* result of stat() */ + struct zlist far *z; /* steps through zfiles list */ + + if (n == NULL) /* volume_label request in freshen|delete mode ?? */ + return ZE_OK; + + if (strcmp(n, "-") == 0) /* if compressing stdin */ + return newname(n, 0, caseflag); + else if (LSSTAT(n, &s) +#if defined(__TURBOC__) || defined(__WATCOMC__) + /* For these 2 compilers, stat() succeeds on wild card names! */ + || isshexp(n) +#endif + ) + { + /* Not a file or directory--search for shell expression in zip file */ + p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */ + m = 1; + for (z = zfiles; z != NULL; z = z->nxt) { + if (MATCH(p, z->iname, caseflag)) + { + z->mark = pcount ? filter(z->zname, caseflag) : 1; + if (verbose) + fprintf(mesg, "zip diagnostic: %scluding %s\n", + z->mark ? "in" : "ex", z->name); + m = 0; + } + } + free((zvoid *)p); + return m ? ZE_MISS : ZE_OK; + } + + /* Live name--use if file, recurse if directory */ + for (p = n; *p; p++) /* use / consistently */ + if (*p == '\\') + *p = '/'; + if ((s.st_mode & S_IFDIR) == 0) + { + /* add or remove name of file */ + if ((m = newname(n, 0, caseflag)) != ZE_OK) + return m; + } else { + /* Add trailing / to the directory name */ + if ((p = malloc(strlen(n)+2)) == NULL) + return ZE_MEM; + if (strcmp(n, ".") == 0 || strcmp(n, "/.") == 0) { + *p = '\0'; /* avoid "./" prefix and do not create zip entry */ + } else { + strcpy(p, n); + a = p + strlen(p); + if (a[-1] != '/') + strcpy(a, "/"); + if (dirnames && (m = newname(p, 1, caseflag)) != ZE_OK) { + free((zvoid *)p); + return m; + } + } + /* recurse into directory */ + if (recurse && (d = opendir(n)) != NULL) + { + while ((e = readd(d)) != NULL) { + if (strcmp(e, ".") && strcmp(e, "..")) + { + if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL) + { + closedir(d); + free((zvoid *)p); + return ZE_MEM; + } + strcat(strcpy(a, p), e); + if ((m = procname(a, caseflag)) != ZE_OK) /* recurse on name */ + { + if (m == ZE_MISS) + zipwarn("name not matched: ", a); + else + ziperr(m, a); + } + free((zvoid *)a); + } + } + closedir(d); + } + free((zvoid *)p); + } /* (s.st_mode & S_IFDIR) == 0) */ + return ZE_OK; +} + +char *ex2in(x, isdir, pdosflag) +char *x; /* external file name */ +int isdir; /* input: x is a directory */ +int *pdosflag; /* output: force MSDOS file attributes? */ +/* Convert the external file name to a zip file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *n; /* internal file name (malloc'ed) */ + char *t; /* shortened name */ + int dosflag; + + dosflag = dosify || IsFileSystemFAT(x) || (x == label); + if (!dosify && use_longname_ea && (t = GetLongPathEA(x)) != NULL) + { + x = t; + dosflag = 0; + } + + /* Find starting point in name before doing malloc */ + /* Strip drive specification */ + t = *x && *(x + 1) == ':' ? x + 2 : x; + /* Strip "//host/share/" part of a UNC name */ + if ((!strncmp(x,"//",2) || !strncmp(x,"\\\\",2)) && + (x[2] != '\0' && x[2] != '/' && x[2] != '\\')) { + n = x + 2; + while (*n != '\0' && *n != '/' && *n != '\\') + n++; /* strip host name */ + if (*n != '\0') { + n++; + while (*n != '\0' && *n != '/' && *n != '\\') + n++; /* strip `share' name */ + } + if (*n != '\0') + t = n + 1; + } + /* Strip leading "/" to convert an absolute path into a relative path */ + while (*t == '/' || *t == '\\') + t++; + /* Strip leading "./" as well as drive letter */ + while (*t == '.' && (t[1] == '/' || t[1] == '\\')) + t += 2; + + /* Make changes, if any, to the copied name (leave original intact) */ + for (n = t; *n; n++) + if (*n == '\\') + *n = '/'; + + if (!pathput) + t = last(t, PATH_END); + + /* Malloc space for internal name and copy it */ + if ((n = malloc(strlen(t) + 1)) == NULL) + return NULL; + strcpy(n, t); + + if (dosify) + msname(n); + + /* Returned malloc'ed name */ + if (pdosflag) + *pdosflag = dosflag; + return n; +} + + +char *in2ex(n) +char *n; /* internal file name */ +/* Convert the zip file name to an external file name, returning the malloc'ed + string or NULL if not enough memory. */ +{ + char *x; /* external file name */ + + if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) + return NULL; + strcpy(x, n); + + return x; +} + + +void stamp(f, d) +char *f; /* name of file to change */ +ulg d; /* dos-style time to change it to */ +/* Set last updated and accessed time of file f to the DOS time d. */ +{ + SetFileTime(f, d); +} + +ulg filetime(f, a, n, t) +char *f; /* name of file to get info on */ +ulg *a; /* return value: file attributes */ +long *n; /* return value: file size */ +iztimes *t; /* return value: access, modific. and creation times */ +/* If file *f does not exist, return 0. Else, return the file's last + modified date and time as an MSDOS date and time. The date and + time is returned in a long with the date most significant to allow + unsigned integer comparison of absolute times. Also, if a is not + a NULL pointer, store the file attributes there, with the high two + bytes being the Unix attributes, and the low byte being a mapping + of that to DOS attributes. If n is not NULL, store the file size + there. If t is not NULL, the file's access, modification and creation + times are stored there as UNIX time_t values. + If f is "-", use standard input as the file. If f is a device, return + a file size of -1 */ +{ + struct stat s; /* results of stat() */ + char *name; + ulg r; + unsigned int len = strlen(f); + int isstdin = !strcmp(f, "-"); + + if (f == label) { + if (a != NULL) + *a = label_mode; + if (n != NULL) + *n = -2L; /* convention for a label name */ + if (t != NULL) + t->atime = t->mtime = t->ctime = label_utim; + return label_time; + } + + if ((name = malloc(len + 1)) == NULL) { + ZIPERR(ZE_MEM, "filetime"); + } + strcpy(name, f); + if (name[len - 1] == '/') + name[len - 1] = '\0'; + /* not all systems allow stat'ing a file with / appended */ + + if (isstdin) { + /* it is common for some PC based compilers to + fail with fstat() on devices or pipes */ + if (fstat(fileno(stdin), &s) != 0) { + s.st_mode = S_IFREG; s.st_size = -1L; + } + time(&s.st_ctime); + s.st_atime = s.st_mtime = s.st_ctime; + } else if (LSSTAT(name, &s) != 0) { + /* Accept about any file kind including directories + * (stored with trailing / with -r option) + */ + free(name); + return 0; + } + + if (a != NULL) { + *a = ((ulg)s.st_mode << 16) | (isstdin ? 0L : (ulg)GetFileMode(name)); + } + if (n != NULL) + *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L; +#ifdef __WATCOMC__ + /* of course, Watcom always has to make an exception */ + if (s.st_atime == 312764400) + s.st_atime = s.st_mtime; + if (s.st_ctime == 312764400) + s.st_ctime = s.st_mtime; +#endif + if (t != NULL) { + t->atime = s.st_atime; + t->mtime = s.st_mtime; + t->ctime = s.st_ctime; + } + + r = GetFileTime(name); + free(name); + + return r; +} + +int deletedir(d) +char *d; /* directory to delete */ +/* Delete the directory *d if it is empty, do nothing otherwise. + Return the result of rmdir(), delete(), or system(). + */ +{ + return rmdir(d); +} + + +#if defined MY_ZCALLOC /* Special zcalloc function for MEMORY16 (MSDOS/OS2) */ + +#ifdef MSC /* Microsoft C */ + +zvoid far *zcalloc (unsigned items, unsigned size) +{ + return (zvoid far *)halloc((long)items, size); +} + +zvoid zcfree (zvoid far *ptr) +{ + hfree((void huge *)ptr); +} + +#endif /* MSC */ + +#endif /* MY_ZCALLOC */ + +#endif /* !UTIL */ diff --git a/os2/os2acl.c b/os2/os2acl.c new file mode 100644 index 0000000..4f88643 --- /dev/null +++ b/os2/os2acl.c @@ -0,0 +1,385 @@ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* os2acl.c - access to OS/2 (LAN Server) ACLs + * + * Author: Kai Uwe Rommel + * Created: Mon Aug 08 1994 + * + */ + +/* + * supported 32-bit compilers: + * - emx+gcc + * - IBM C Set++ 2.1 or newer + * - Watcom C/C++ 10.0 or newer + * + * supported 16-bit compilers: + * - MS C 6.00A + * - Watcom C/C++ 10.0 or newer + * + * supported OS/2 LAN environments: + * - IBM LAN Server/Requester 3.0, 4.0 and 5.0 (Warp Server) + * - IBM Peer 1.0 (Warp Connect) + */ + +#ifdef KUR + static char *rcsid = + "$Id: os2acl.c,v 1.3 1996/04/03 19:18:27 rommel Exp rommel $"; + static char *rcsrev = "$Revision: 1.3 $"; +#endif + +/* + * $Log: os2acl.c,v $ + * Revision 1.3 1996/04/03 19:18:27 rommel + * minor fixes + * + * Revision 1.2 1996/03/30 22:03:52 rommel + * avoid frequent dynamic allocation for every call + * streamlined code + * + * Revision 1.1 1996/03/30 09:35:00 rommel + * Initial revision + * + */ + +#include +#include +#include +#include +#include + +#define INCL_NOPM +#define INCL_DOS +#define INCL_DOSERRORS +#include + +#include "os2/os2acl.h" + +#define UNLEN 20 + +#if defined(__WATCOMC__) && defined(__386__) && !defined(__32BIT__) +#define __32BIT__ +#endif + +#ifdef __32BIT__ +typedef ULONG U_INT; +#ifdef __EMX__ +#define PSTR16 _far16ptr +#define PTR16(x) _emx_32to16(x) +#else /* other 32-bit */ +#define PSTR16 PCHAR16 +#define PTR16(x) ((PCHAR16)(x)) +#endif +#else /* 16-bit */ +typedef USHORT U_INT; +#define PSTR16 PSZ +#define PTR16(x) (x) +#endif + +typedef struct access_list +{ + char acl_ugname[UNLEN+1]; + char acl_pad; + USHORT acl_access; +} +ACCLIST; + +typedef struct access_info +{ + PSTR16 acc_resource_name; + USHORT acc_attr; + USHORT acc_count; +} +ACCINFO; + +static ACCINFO *ai; +static char *path, *data; + +#ifdef __32BIT__ + +#ifdef __EMX__ + +static USHORT (APIENTRY *_NetAccessGetInfo)(PSZ pszServer, PSZ pszResource, + USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, PUSHORT pcbTotalAvail); +static USHORT (APIENTRY *_NetAccessSetInfo)(PSZ pszServer, PSZ pszResource, + USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, USHORT sParmNum); +static USHORT (APIENTRY *_NetAccessAdd)(PSZ pszServer, + USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer); + +USHORT NetAccessGetInfo(PSZ pszServer, PSZ pszResource, USHORT sLevel, + PVOID pbBuffer, USHORT cbBuffer, PUSHORT pcbTotalAvail) +{ + return (USHORT) + (_THUNK_PROLOG (4+4+2+4+2+4); + _THUNK_FLAT (pszServer); + _THUNK_FLAT (pszResource); + _THUNK_SHORT (sLevel); + _THUNK_FLAT (pbBuffer); + _THUNK_SHORT (cbBuffer); + _THUNK_FLAT (pcbTotalAvail); + _THUNK_CALLI (_emx_32to16(_NetAccessGetInfo))); +} + +USHORT NetAccessSetInfo(PSZ pszServer, PSZ pszResource, USHORT sLevel, + PVOID pbBuffer, USHORT cbBuffer, USHORT sParmNum) +{ + return (USHORT) + (_THUNK_PROLOG (4+4+2+4+2+2); + _THUNK_FLAT (pszServer); + _THUNK_FLAT (pszResource); + _THUNK_SHORT (sLevel); + _THUNK_FLAT (pbBuffer); + _THUNK_SHORT (cbBuffer); + _THUNK_SHORT (sParmNum); + _THUNK_CALLI (_emx_32to16(_NetAccessSetInfo))); +} + +USHORT NetAccessAdd(PSZ pszServer, USHORT sLevel, + PVOID pbBuffer, USHORT cbBuffer) +{ + return (USHORT) + (_THUNK_PROLOG (4+2+4+2); + _THUNK_FLAT (pszServer); + _THUNK_SHORT (sLevel); + _THUNK_FLAT (pbBuffer); + _THUNK_SHORT (cbBuffer); + _THUNK_CALLI (_emx_32to16(_NetAccessAdd))); +} + +#else /* other 32-bit */ + +APIRET16 (* APIENTRY16 NetAccessGetInfo)(PCHAR16 pszServer, PCHAR16 pszResource, + USHORT sLevel, PVOID16 pbBuffer, USHORT cbBuffer, PVOID16 pcbTotalAvail); +APIRET16 (* APIENTRY16 NetAccessSetInfo)(PCHAR16 pszServer, PCHAR16 pszResource, + USHORT sLevel, PVOID16 pbBuffer, USHORT cbBuffer, USHORT sParmNum); +APIRET16 (* APIENTRY16 NetAccessAdd)(PCHAR16 pszServer, + USHORT sLevel, PVOID16 pbBuffer, USHORT cbBuffer); + +#define _NetAccessGetInfo NetAccessGetInfo +#define _NetAccessSetInfo NetAccessSetInfo +#define _NetAccessAdd NetAccessAdd + +#if !defined(__IBMC__) || !defined(__TILED__) +#define _tmalloc malloc +#define _tfree free +#endif + +#endif +#else /* 16-bit */ + +USHORT (APIENTRY *NetAccessGetInfo)(PSZ pszServer, PSZ pszResource, + USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, PUSHORT pcbTotalAvail); +USHORT (APIENTRY *NetAccessSetInfo)(PSZ pszServer, PSZ pszResource, + USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, USHORT sParmNum); +USHORT (APIENTRY *NetAccessAdd)(PSZ pszServer, + USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer); + +#define _NetAccessGetInfo NetAccessGetInfo +#define _NetAccessSetInfo NetAccessSetInfo +#define _NetAccessAdd NetAccessAdd + +#define _tmalloc malloc +#define _tfree free + +#define DosQueryProcAddr(handle, ord, name, funcptr) \ + DosGetProcAddr(handle, name, funcptr) +#define DosQueryCurrentDir DosQCurDir +#define DosQueryCurrentDisk DosQCurDisk + +#endif + + +static BOOL acl_init(void) +{ + static BOOL initialized, netapi_avail; + HMODULE netapi; + char buf[256]; + + if (initialized) + return netapi_avail; + + initialized = TRUE; + + if (DosLoadModule(buf, sizeof(buf), "NETAPI", &netapi)) + return FALSE; + + if (DosQueryProcAddr(netapi, 0, "NETACCESSGETINFO", (PFN *) &_NetAccessGetInfo) || + DosQueryProcAddr(netapi, 0, "NETACCESSSETINFO", (PFN *) &_NetAccessSetInfo) || + DosQueryProcAddr(netapi, 0, "NETACCESSADD", (PFN *) &_NetAccessAdd)) + return FALSE; + +#if defined(__WATCOMC__) && defined(__386__) + NetAccessGetInfo = (PVOID) (ULONG) (PVOID16) NetAccessGetInfo; + NetAccessSetInfo = (PVOID) (ULONG) (PVOID16) NetAccessSetInfo; + NetAccessAdd = (PVOID) (ULONG) (PVOID16) NetAccessAdd; +#endif + + if ((path = _tmalloc(CCHMAXPATH)) == NULL) + return FALSE; + if ((data = _tmalloc(ACL_BUFFERSIZE)) == NULL) + return FALSE; + if ((ai = _tmalloc(sizeof(ACCINFO))) == NULL) + return -1; + + netapi_avail = TRUE; + + return netapi_avail; +} + +static void acl_mkpath(char *buffer, const char *source) +{ + char *ptr; + static char cwd[CCHMAXPATH]; + static U_INT cwdlen; + U_INT cdrive; + ULONG drivemap; + + if (isalpha((int)source[0]) && source[1] == ':') + buffer[0] = 0; /* fully qualified names */ + else + { + if (cwd[0] == 0) + { + DosQueryCurrentDisk(&cdrive, &drivemap); + cwd[0] = (char)(cdrive + '@'); + cwd[1] = ':'; + cwd[2] = '\\'; + cwdlen = sizeof(cwd) - 3; + DosQueryCurrentDir(0, cwd + 3, &cwdlen); + cwdlen = strlen(cwd); + } + + if (source[0] == '/' || source[0] == '\\') + { + if (source[1] == '/' || source[1] == '\\') + buffer[0] = 0; /* UNC names */ + else + { + strncpy(buffer, cwd, 2); + buffer[2] = 0; + } + } + else + { + strcpy(buffer, cwd); + if (cwd[cwdlen - 1] != '\\' && cwd[cwdlen - 1] != '/') + strcat(buffer, "/"); + } + } + + strcat(buffer, source); + + for (ptr = buffer; *ptr; ptr++) + if (*ptr == '/') + *ptr = '\\'; + + if (ptr[-1] == '\\') + ptr[-1] = 0; + + strupr(buffer); +} + +static int acl_bin2text(char *data, char *text) +{ + ACCINFO *ai; + ACCLIST *al; + U_INT cnt, offs; + + ai = (ACCINFO *) data; + al = (ACCLIST *) (data + sizeof(ACCINFO)); + + offs = sprintf(text, "ACL1:%X,%d\n", + ai -> acc_attr, ai -> acc_count); + + for (cnt = 0; cnt < ai -> acc_count; cnt++) + offs += sprintf(text + offs, "%s,%X\n", + al[cnt].acl_ugname, al[cnt].acl_access); + + return strlen(text); +} + +int acl_get(char *server, const char *resource, char *buffer) +{ + USHORT datalen; + PSZ srv = NULL; + int rc; + + if (!acl_init()) + return -1; + + if (server) + srv = server; + + acl_mkpath(path, resource); + datalen = 0; + + rc = NetAccessGetInfo(srv, path, 1, data, ACL_BUFFERSIZE, &datalen); + + if (rc == 0) + acl_bin2text(data, buffer); + + return rc; +} + +static int acl_text2bin(char *data, char *text, char *path) +{ + ACCINFO *ai; + ACCLIST *al; + char *ptr, *ptr2; + U_INT cnt; + + ai = (ACCINFO *) data; + ai -> acc_resource_name = PTR16(path); + + if (sscanf(text, "ACL1:%hX,%hd", + &ai -> acc_attr, &ai -> acc_count) != 2) + return ERROR_INVALID_PARAMETER; + + al = (ACCLIST *) (data + sizeof(ACCINFO)); + ptr = strchr(text, '\n') + 1; + + for (cnt = 0; cnt < ai -> acc_count; cnt++) + { + ptr2 = strchr(ptr, ','); + strncpy(al[cnt].acl_ugname, ptr, ptr2 - ptr); + al[cnt].acl_ugname[ptr2 - ptr] = 0; + sscanf(ptr2 + 1, "%hx", &al[cnt].acl_access); + ptr = strchr(ptr, '\n') + 1; + } + + return sizeof(ACCINFO) + ai -> acc_count * sizeof(ACCLIST); +} + +int acl_set(char *server, const char *resource, char *buffer) +{ + USHORT datalen; + PSZ srv = NULL; + + if (!acl_init()) + return -1; + + if (server) + srv = server; + + acl_mkpath(path, resource); + + ai -> acc_resource_name = PTR16(path); + ai -> acc_attr = 0; + ai -> acc_count = 0; + + NetAccessAdd(srv, 1, ai, sizeof(ACCINFO)); + /* Ignore any errors, most probably because ACL already exists. */ + /* In any such case, try updating the existing ACL. */ + + datalen = acl_text2bin(data, buffer, path); + + return NetAccessSetInfo(srv, path, 1, data, datalen, 0); +} + +/* end of os2acl.c */ diff --git a/os2/os2acl.h b/os2/os2acl.h new file mode 100644 index 0000000..03bb8a2 --- /dev/null +++ b/os2/os2acl.h @@ -0,0 +1,34 @@ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* os2acl.h + * + * Author: Kai Uwe Rommel + * Created: Fri Mar 29 1996 + */ + +/* $Id: os2acl.h,v 1.1 1996/03/30 09:35:00 rommel Exp rommel $ */ + +/* + * $Log: os2acl.h,v $ + * Revision 1.1 1996/03/30 09:35:00 rommel + * Initial revision + * + */ + +#ifndef _OS2ACL_H +#define _OS2ACL_H + +#define ACL_BUFFERSIZE 4096 + +int acl_get(char *server, const char *resource, char *buffer); +int acl_set(char *server, const char *resource, char *buffer); + +#endif /* _OS2ACL_H */ + +/* end of os2acl.h */ diff --git a/os2/os2zip.c b/os2/os2zip.c new file mode 100644 index 0000000..83bc3bc --- /dev/null +++ b/os2/os2zip.c @@ -0,0 +1,1213 @@ +/* + * @(#)dir.c 1.4 87/11/06 Public Domain. + * + * A public domain implementation of BSD directory routines for + * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield), + * August 1987 + * + * Ported to OS/2 by Kai Uwe Rommel + * Addition of other OS/2 file system specific code + * Placed into the public domain + */ + +/* does also contain EA access code for use in ZIP */ + + +#ifdef OS2 + + +#if defined(__EMX__) && !defined(__32BIT__) +# define __32BIT__ +#endif + +#include "zip.h" + +#include +#include +#include +#ifndef __BORLANDC__ +#include +#endif + +#define INCL_NOPM +#define INCL_DOSNLS +#define INCL_DOSERRORS +#include + +#include "os2zip.h" +#include "os2acl.h" + + +#ifndef max +#define max(a, b) ((a) < (b) ? (b) : (a)) +#endif + + +#ifdef __32BIT__ +#define DosFindFirst(p1, p2, p3, p4, p5, p6) \ + DosFindFirst(p1, p2, p3, p4, p5, p6, 1) +#else +#define DosQueryCurrentDisk DosQCurDisk +#define DosQueryFSAttach(p1, p2, p3, p4, p5) \ + DosQFSAttach(p1, p2, p3, p4, p5, 0) +#define DosQueryFSInfo(d, l, b, s) \ + DosQFSInfo(d, l, b, s) +#define DosQueryPathInfo(p1, p2, p3, p4) \ + DosQPathInfo(p1, p2, p3, p4, 0) +#define DosSetPathInfo(p1, p2, p3, p4, p5) \ + DosSetPathInfo(p1, p2, p3, p4, p5, 0) +#define DosEnumAttribute(p1, p2, p3, p4, p5, p6, p7) \ + DosEnumAttribute(p1, p2, p3, p4, p5, p6, p7, 0) +#define DosFindFirst(p1, p2, p3, p4, p5, p6) \ + DosFindFirst(p1, p2, p3, p4, p5, p6, 0) +#define DosMapCase DosCaseMap +#endif + + +#ifndef UTIL + +extern int noisy; + +#ifndef S_IFMT +#define S_IFMT 0xF000 +#endif + +static int attributes = _A_DIR | _A_HIDDEN | _A_SYSTEM; + +static char *getdirent(char *); +static void free_dircontents(struct _dircontents *); + +#ifdef __32BIT__ +static HDIR hdir; +static ULONG count; +static FILEFINDBUF3 find; +#else +static HDIR hdir; +static USHORT count; +static FILEFINDBUF find; +#endif + +DIR *opendir(const char *name) +{ + struct stat statb; + DIR *dirp; + char c; + char *s; + struct _dircontents *dp; + char nbuf[MAXPATHLEN + 1]; + int len; + + attributes = hidden_files ? (_A_DIR | _A_HIDDEN | _A_SYSTEM) : _A_DIR; + + strcpy(nbuf, name); + if ((len = strlen(nbuf)) == 0) + return NULL; + + if (((c = nbuf[len - 1]) == '\\' || c == '/') && (len > 1)) + { + nbuf[len - 1] = 0; + --len; + + if (nbuf[len - 1] == ':') + { + strcpy(nbuf+len, "\\."); + len += 2; + } + } + else + if (nbuf[len - 1] == ':') + { + strcpy(nbuf+len, "."); + ++len; + } + +#ifndef __BORLANDC__ + /* when will we ever see a Borland compiler that can properly stat !!! */ + if (stat(nbuf, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR) + return NULL; +#endif + + if ((dirp = malloc(sizeof(DIR))) == NULL) + return NULL; + + if (nbuf[len - 1] == '.' && (len == 1 || nbuf[len - 2] != '.')) + strcpy(nbuf+len-1, "*.*"); + else + if (((c = nbuf[len - 1]) == '\\' || c == '/') && (len == 1)) + strcpy(nbuf+len, "*"); + else + strcpy(nbuf+len, "\\*"); + + /* len is no longer correct (but no longer needed) */ + + dirp -> dd_loc = 0; + dirp -> dd_contents = dirp -> dd_cp = NULL; + + if ((s = getdirent(nbuf)) == NULL) + return dirp; + + do + { + if (((dp = malloc(sizeof(struct _dircontents))) == NULL) || + ((dp -> _d_entry = malloc(strlen(s) + 1)) == NULL) ) + { + if (dp) + free(dp); + free_dircontents(dirp -> dd_contents); + + return NULL; + } + + if (dirp -> dd_contents) + { + dirp -> dd_cp -> _d_next = dp; + dirp -> dd_cp = dirp -> dd_cp -> _d_next; + } + else + dirp -> dd_contents = dirp -> dd_cp = dp; + + strcpy(dp -> _d_entry, s); + dp -> _d_next = NULL; + + dp -> _d_size = find.cbFile; + dp -> _d_mode = find.attrFile; + dp -> _d_time = *(unsigned *) &(find.ftimeLastWrite); + dp -> _d_date = *(unsigned *) &(find.fdateLastWrite); + } + while ((s = getdirent(NULL)) != NULL); + + dirp -> dd_cp = dirp -> dd_contents; + + return dirp; +} + +void closedir(DIR * dirp) +{ + free_dircontents(dirp -> dd_contents); + free(dirp); +} + +struct dirent *readdir(DIR * dirp) +{ + static struct dirent dp; + + if (dirp -> dd_cp == NULL) + return NULL; + + dp.d_namlen = dp.d_reclen = + strlen(strcpy(dp.d_name, dirp -> dd_cp -> _d_entry)); + + dp.d_ino = 0; + + dp.d_size = dirp -> dd_cp -> _d_size; + dp.d_mode = dirp -> dd_cp -> _d_mode; + dp.d_time = dirp -> dd_cp -> _d_time; + dp.d_date = dirp -> dd_cp -> _d_date; + + dirp -> dd_cp = dirp -> dd_cp -> _d_next; + dirp -> dd_loc++; + + return &dp; +} + +void seekdir(DIR * dirp, long off) +{ + long i = off; + struct _dircontents *dp; + + if (off >= 0) + { + for (dp = dirp -> dd_contents; --i >= 0 && dp; dp = dp -> _d_next); + + dirp -> dd_loc = off - (i + 1); + dirp -> dd_cp = dp; + } +} + +long telldir(DIR * dirp) +{ + return dirp -> dd_loc; +} + +static void free_dircontents(struct _dircontents * dp) +{ + struct _dircontents *odp; + + while (dp) + { + if (dp -> _d_entry) + free(dp -> _d_entry); + + dp = (odp = dp) -> _d_next; + free(odp); + } +} + +static char *getdirent(char *dir) +{ + int done; + static int lower; + + if (dir != NULL) + { /* get first entry */ + hdir = HDIR_SYSTEM; + count = 1; + done = DosFindFirst(dir, &hdir, attributes, &find, sizeof(find), &count); + lower = IsFileSystemFAT(dir); + } + else /* get next entry */ + done = DosFindNext(hdir, &find, sizeof(find), &count); + + if (done == 0) + { + if (lower) + StringLower(find.achName); + return find.achName; + } + else + { + DosFindClose(hdir); + return NULL; + } +} + +/* FAT / HPFS detection */ + +int IsFileSystemFAT(char *dir) +{ + static USHORT nLastDrive = -1, nResult; + ULONG lMap; + BYTE bData[64]; + char bName[3]; +#ifdef __32BIT__ + ULONG nDrive, cbData; + PFSQBUFFER2 pData = (PFSQBUFFER2) bData; +#else + USHORT nDrive, cbData; + PFSQBUFFER pData = (PFSQBUFFER) bData; +#endif + + /* We separate FAT and HPFS+other file systems here. + at the moment I consider other systems to be similar to HPFS, + i.e. support long file names and being case sensitive */ + + if (isalpha(dir[0]) && (dir[1] == ':')) + nDrive = to_up(dir[0]) - '@'; + else + DosQueryCurrentDisk(&nDrive, &lMap); + + if (nDrive == nLastDrive) + return nResult; + + bName[0] = (char) (nDrive + '@'); + bName[1] = ':'; + bName[2] = 0; + + nLastDrive = nDrive; + cbData = sizeof(bData); + + if (!DosQueryFSAttach(bName, 0, FSAIL_QUERYNAME, (PVOID) pData, &cbData)) + nResult = !strcmp((char *) pData -> szFSDName + pData -> cbName, "FAT"); + else + nResult = FALSE; + + /* End of this ugly code */ + return nResult; +} + +/* access mode bits and time stamp */ + +int GetFileMode(char *name) +{ +#ifdef __32BIT__ + FILESTATUS3 fs; + return DosQueryPathInfo(name, 1, &fs, sizeof(fs)) ? -1 : fs.attrFile; +#else + USHORT mode; + return DosQFileMode(name, &mode, 0L) ? -1 : mode; +#endif +} + +ulg GetFileTime(char *name) +{ +#ifdef __32BIT__ + FILESTATUS3 fs; +#else + FILESTATUS fs; +#endif + USHORT nDate, nTime; + DATETIME dtCurrent; + + if (strcmp(name, "-") == 0) + { + DosGetDateTime(&dtCurrent); + fs.fdateLastWrite.day = dtCurrent.day; + fs.fdateLastWrite.month = dtCurrent.month; + fs.fdateLastWrite.year = dtCurrent.year - 1980; + fs.ftimeLastWrite.hours = dtCurrent.hours; + fs.ftimeLastWrite.minutes = dtCurrent.minutes; + fs.ftimeLastWrite.twosecs = dtCurrent.seconds / 2; + } + else + if (DosQueryPathInfo(name, 1, (PBYTE) &fs, sizeof(fs))) + return -1; + + nDate = * (USHORT *) &fs.fdateLastWrite; + nTime = * (USHORT *) &fs.ftimeLastWrite; + + return ((ULONG) nDate) << 16 | nTime; +} + +void SetFileTime(char *path, ulg stamp) +{ + FILESTATUS fs; + USHORT fd, ft; + + if (DosQueryPathInfo(path, FIL_STANDARD, (PBYTE) &fs, sizeof(fs))) + return; + + fd = (USHORT) (stamp >> 16); + ft = (USHORT) stamp; + fs.fdateLastWrite = fs.fdateCreation = * (FDATE *) &fd; + fs.ftimeLastWrite = fs.ftimeCreation = * (FTIME *) &ft; + + DosSetPathInfo(path, FIL_STANDARD, (PBYTE) &fs, sizeof(fs), 0); +} + +/* read volume label */ + +char *getVolumeLabel(int drive, unsigned long *vtime, unsigned long *vmode, + time_t *utim) +{ + static FSINFO fi; + + if (DosQueryFSInfo(drive ? drive - 'A' + 1 : 0, + FSIL_VOLSER, (PBYTE) &fi, sizeof(fi))) + return NULL; + + time(utim); + *vtime = unix2dostime(utim); + *vmode = _A_VOLID | _A_ARCHIVE; + + return (fi.vol.cch > 0) ? fi.vol.szVolLabel : NULL; +} + +/* FAT / HPFS name conversion stuff */ + +int IsFileNameValid(char *name) +{ + HFILE hf; +#ifdef __32BIT__ + ULONG uAction; +#else + USHORT uAction; +#endif + + switch(DosOpen(name, &hf, &uAction, 0, 0, FILE_OPEN, + OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, 0)) + { + case ERROR_INVALID_NAME: + case ERROR_FILENAME_EXCED_RANGE: + return FALSE; + case NO_ERROR: + DosClose(hf); + default: + return TRUE; + } +} + +void ChangeNameForFAT(char *name) +{ + char *src, *dst, *next, *ptr, *dot, *start; + static char invalid[] = ":;,=+\"[]<>| \t"; + + if (isalpha(name[0]) && (name[1] == ':')) + start = name + 2; + else + start = name; + + src = dst = start; + if ((*src == '/') || (*src == '\\')) + src++, dst++; + + while (*src) + { + for (next = src; *next && (*next != '/') && (*next != '\\'); next++); + + for (ptr = src, dot = NULL; ptr < next; ptr++) + if (*ptr == '.') + { + dot = ptr; /* remember last dot */ + *ptr = '_'; + } + + if (dot == NULL) + for (ptr = src; ptr < next; ptr++) + if (*ptr == '_') + dot = ptr; /* remember last _ as if it were a dot */ + + if (dot && (dot > src) && + ((next - dot <= 4) || + ((next - src > 8) && (dot - src > 3)))) + { + if (dot) + *dot = '.'; + + for (ptr = src; (ptr < dot) && ((ptr - src) < 8); ptr++) + *dst++ = *ptr; + + for (ptr = dot; (ptr < next) && ((ptr - dot) < 4); ptr++) + *dst++ = *ptr; + } + else + { + if (dot && (next - src == 1)) + *dot = '.'; /* special case: "." as a path component */ + + for (ptr = src; (ptr < next) && ((ptr - src) < 8); ptr++) + *dst++ = *ptr; + } + + *dst++ = *next; /* either '/' or 0 */ + + if (*next) + { + src = next + 1; + + if (*src == 0) /* handle trailing '/' on dirs ! */ + *dst = 0; + } + else + break; + } + + for (src = start; *src != 0; ++src) + if ((strchr(invalid, *src) != NULL) || (*src == ' ')) + *src = '_'; +} + +/* .LONGNAME EA code */ + +typedef struct +{ + ULONG cbList; /* length of value + 22 */ +#ifdef __32BIT__ + ULONG oNext; +#endif + BYTE fEA; /* 0 */ + BYTE cbName; /* length of ".LONGNAME" = 9 */ + USHORT cbValue; /* length of value + 4 */ + BYTE szName[10]; /* ".LONGNAME" */ + USHORT eaType; /* 0xFFFD for length-preceded ASCII */ + USHORT eaSize; /* length of value */ + BYTE szValue[CCHMAXPATH]; +} +FEALST; + +typedef struct +{ + ULONG cbList; +#ifdef __32BIT__ + ULONG oNext; +#endif + BYTE cbName; + BYTE szName[10]; /* ".LONGNAME" */ +} +GEALST; + +char *GetLongNameEA(const char *name) +{ + EAOP eaop; + GEALST gealst; + static FEALST fealst; + char *ptr; + + eaop.fpGEAList = (PGEALIST) &gealst; + eaop.fpFEAList = (PFEALIST) &fealst; + eaop.oError = 0; + + strcpy((char *) gealst.szName, ".LONGNAME"); + gealst.cbName = (BYTE) strlen((char *) gealst.szName); +#ifdef __32BIT__ + gealst.oNext = 0; +#endif + + gealst.cbList = sizeof(gealst); + fealst.cbList = sizeof(fealst); + + if (DosQueryPathInfo(name, FIL_QUERYEASFROMLIST, + (PBYTE) &eaop, sizeof(eaop))) + return NULL; + + if (fealst.cbValue > 4 && fealst.eaType == 0xFFFD) + { + fealst.szValue[fealst.eaSize] = 0; + + for (ptr = fealst.szValue; *ptr; ptr++) + if (*ptr == '/' || *ptr == '\\') + *ptr = '!'; + + return (char *) fealst.szValue; + } + + return NULL; +} + +char *GetLongPathEA(const char *name) +{ + static char nbuf[CCHMAXPATH + 1]; + char tempbuf[CCHMAXPATH + 1]; + char *comp, *next, *ea, sep; + BOOL bFound = FALSE; + + nbuf[0] = 0; + strncpy(tempbuf, name, CCHMAXPATH); + tempbuf[CCHMAXPATH] = '\0'; + next = tempbuf; + + while (*next) + { + comp = next; + + while (*next != '\\' && *next != '/' && *next != 0) + next++; + + sep = *next; + *next = 0; + + ea = GetLongNameEA(tempbuf); + strcat(nbuf, ea ? ea : comp); + bFound = bFound || (ea != NULL); + + if (sep) + { + strcat(nbuf, "\\"); + *next++ = sep; + } + } + + return (nbuf[0] != 0) && bFound ? nbuf : NULL; +} + +/* general EA code */ + +typedef struct +{ + USHORT nID; + USHORT nSize; + ULONG lSize; +} +EFHEADER, *PEFHEADER; + +#ifdef __32BIT__ + +/* Perhaps due to bugs in the current OS/2 2.0 kernel, the success or + failure of the DosEnumAttribute() and DosQueryPathInfo() system calls + depends on the area where the return buffers are allocated. This + differs for the various compilers, for some alloca() works, for some + malloc() works, for some, both work. We'll have to live with that. */ + +/* The use of malloc() is not very convenient, because it requires + backtracking (i.e. free()) at error returns. We do that for system + calls that may fail, but not for malloc() calls, because they are VERY + unlikely to fail. If ever, we just leave some memory allocated + over the usually short lifetime of a zip process ... */ + +#ifdef __GNUC__ +#define alloc(x) alloca(x) +#define unalloc(x) +#else +#define alloc(x) malloc(x) +#define unalloc(x) free(x) +#endif + +void GetEAs(char *path, char **bufptr, size_t *size, + char **cbufptr, size_t *csize) +{ + FILESTATUS4 fs; + PDENA2 pDENA, pFound; + EAOP2 eaop; + PGEA2 pGEA; + PGEA2LIST pGEAlist; + PFEA2LIST pFEAlist; + PEFHEADER pEAblock; + ULONG ulAttributes, ulMemoryBlock; + ULONG nLength; + ULONG nBlock; + char szName[CCHMAXPATH]; + + *size = *csize = 0; + + strcpy(szName, path); + nLength = strlen(szName); + if (szName[nLength - 1] == '/') + szName[nLength - 1] = 0; + + if (DosQueryPathInfo(szName, FIL_QUERYEASIZE, (PBYTE) &fs, sizeof(fs))) + return; + nBlock = max(fs.cbList, 65535); + if ((pDENA = alloc((size_t) nBlock)) == NULL) + return; + + ulAttributes = -1; + + if (DosEnumAttribute(ENUMEA_REFTYPE_PATH, szName, 1, pDENA, nBlock, + &ulAttributes, ENUMEA_LEVEL_NO_VALUE) + || ulAttributes == 0 + || (pGEAlist = alloc((size_t) nBlock)) == NULL) + { + unalloc(pDENA); + return; + } + + pGEA = pGEAlist -> list; + memset(pGEAlist, 0, nBlock); + pFound = pDENA; + + while (ulAttributes--) + { + if (!(strcmp(pFound -> szName, ".LONGNAME") == 0 && use_longname_ea)) + { + pGEA -> cbName = pFound -> cbName; + strcpy(pGEA -> szName, pFound -> szName); + + nLength = sizeof(GEA2) + strlen(pGEA -> szName); + nLength = ((nLength - 1) / sizeof(ULONG) + 1) * sizeof(ULONG); + + pGEA -> oNextEntryOffset = ulAttributes ? nLength : 0; + pGEA = (PGEA2) ((PCH) pGEA + nLength); + } + + pFound = (PDENA2) ((PCH) pFound + pFound -> oNextEntryOffset); + } + + if (pGEA == pGEAlist -> list) /* no attributes to save */ + { + unalloc(pDENA); + unalloc(pGEAlist); + return; + } + + pGEAlist -> cbList = (PCH) pGEA - (PCH) pGEAlist; + + pFEAlist = (PVOID) pDENA; /* reuse buffer */ + pFEAlist -> cbList = nBlock; + + eaop.fpGEA2List = pGEAlist; + eaop.fpFEA2List = pFEAlist; + eaop.oError = 0; + + if (DosQueryPathInfo(szName, FIL_QUERYEASFROMLIST, + (PBYTE) &eaop, sizeof(eaop))) + { + unalloc(pDENA); + unalloc(pGEAlist); + return; + } + + /* The maximum compressed size is (in case of STORE type) the + uncompressed size plus the size of the compression type field + plus the size of the CRC field + 2*5 deflate overhead bytes + for uncompressable data. + (5 bytes per 32Kb block, max compressed size = 2 blocks) */ + + ulAttributes = pFEAlist -> cbList; + ulMemoryBlock = ulAttributes + + sizeof(USHORT) + sizeof(ULONG) + EB_DEFLAT_EXTRA; + pEAblock = (PEFHEADER) malloc(sizeof(EFHEADER) + ulMemoryBlock); + + if (pEAblock == NULL) + { + unalloc(pDENA); + unalloc(pGEAlist); + return; + } + + *bufptr = (char *) pEAblock; + *size = sizeof(EFHEADER); + + pEAblock -> nID = EF_OS2EA; + pEAblock -> nSize = sizeof(pEAblock -> lSize); + pEAblock -> lSize = ulAttributes; /* uncompressed size */ + + nLength = memcompress((char *) (pEAblock + 1), ulMemoryBlock, + (char *) pFEAlist, ulAttributes); + *size += nLength; + pEAblock -> nSize += nLength; + + if ((pEAblock = (PEFHEADER) malloc(sizeof(EFHEADER))) == NULL) + { + unalloc(pDENA); + unalloc(pGEAlist); + return; + } + + *cbufptr = (char *) pEAblock; + *csize = sizeof(EFHEADER); + + pEAblock -> nID = EF_OS2EA; + pEAblock -> nSize = sizeof(pEAblock -> lSize); + pEAblock -> lSize = ulAttributes; + + if (noisy) + printf(" (%ld bytes EA's)", ulAttributes); + + unalloc(pDENA); + unalloc(pGEAlist); +} + +#else /* !__32BIT__ */ + +typedef struct +{ + ULONG oNextEntryOffset; + BYTE fEA; + BYTE cbName; + USHORT cbValue; + CHAR szName[1]; +} +FEA2, *PFEA2; + +typedef struct +{ + ULONG cbList; + FEA2 list[1]; +} +FEA2LIST, *PFEA2LIST; + +void GetEAs(char *path, char **bufptr, size_t *size, + char **cbufptr, size_t *csize) +{ + FILESTATUS2 fs; + PDENA1 pDENA, pFound; + EAOP eaop; + PGEALIST pGEAlist; + PGEA pGEA; + PFEALIST pFEAlist; + PFEA pFEA; + PFEA2LIST pFEA2list; + PFEA2 pFEA2; + EFHEADER *pEAblock; + ULONG ulAttributes; + USHORT nLength, nMaxSize; + char szName[CCHMAXPATH]; + + *size = *csize = 0; + + strcpy(szName, path); + nLength = strlen(szName); + if (szName[nLength - 1] == '/') + szName[nLength - 1] = 0; + + if (DosQueryPathInfo(szName, FIL_QUERYEASIZE, (PBYTE) &fs, sizeof(fs)) + || fs.cbList <= 2 * sizeof(ULONG)) + return; + + ulAttributes = -1; + nMaxSize = (USHORT) min(fs.cbList * 2, 65520L); + + if ((pDENA = malloc((size_t) nMaxSize)) == NULL) + return; + + if (DosEnumAttribute(ENUMEA_REFTYPE_PATH, szName, 1, pDENA, fs.cbList, + &ulAttributes, ENUMEA_LEVEL_NO_VALUE) + || ulAttributes == 0 + || (pGEAlist = malloc(nMaxSize)) == NULL) + { + free(pDENA); + return; + } + + pGEA = pGEAlist -> list; + pFound = pDENA; + + while (ulAttributes--) + { + nLength = strlen(pFound -> szName); + + if (!(strcmp(pFound -> szName, ".LONGNAME") == 0 && use_longname_ea)) + { + pGEA -> cbName = pFound -> cbName; + strcpy(pGEA -> szName, pFound -> szName); + + pGEA++; + pGEA = (PGEA) (((PCH) pGEA) + nLength); + } + + pFound++; + pFound = (PDENA1) (((PCH) pFound) + nLength); + } + + if (pGEA == pGEAlist -> list) + { + free(pDENA); + free(pGEAlist); + return; + } + + pGEAlist -> cbList = (PCH) pGEA - (PCH) pGEAlist; + + pFEAlist = (PFEALIST) pDENA; /* reuse buffer */ + pFEAlist -> cbList = fs.cbList; + pFEA = pFEAlist -> list; + + eaop.fpGEAList = pGEAlist; + eaop.fpFEAList = pFEAlist; + eaop.oError = 0; + + if (DosQueryPathInfo(szName, FIL_QUERYEASFROMLIST, + (PBYTE) &eaop, sizeof(eaop))) + { + free(pDENA); + free(pGEAlist); + return; + } + + /* now convert into new OS/2 2.0 32-bit format */ + + pFEA2list = (PFEA2LIST) pGEAlist; /* reuse buffer */ + pFEA2 = pFEA2list -> list; + + while ((PCH) pFEA - (PCH) pFEAlist < pFEAlist -> cbList) + { + nLength = sizeof(FEA) + pFEA -> cbName + 1 + pFEA -> cbValue; + memcpy((PCH) pFEA2 + sizeof(pFEA2 -> oNextEntryOffset), pFEA, nLength); + memset((PCH) pFEA2 + sizeof(pFEA2 -> oNextEntryOffset) + nLength, 0, 3); + pFEA = (PFEA) ((PCH) pFEA + nLength); + + nLength = sizeof(FEA2) + pFEA2 -> cbName + 1 + pFEA2 -> cbValue; + nLength = ((nLength - 1) / sizeof(ULONG) + 1) * sizeof(ULONG); + /* rounded up to 4-byte boundary */ + pFEA2 -> oNextEntryOffset = + ((PCH) pFEA - (PCH) pFEAlist < pFEAlist -> cbList) ? nLength : 0; + pFEA2 = (PFEA2) ((PCH) pFEA2 + nLength); + } + + pFEA2list -> cbList = (PCH) pFEA2 - (PCH) pFEA2list; + ulAttributes = pFEA2list -> cbList; + + pEAblock = (PEFHEADER) pDENA; /* reuse buffer */ + + *bufptr = (char *) pEAblock; + *size = sizeof(EFHEADER); + + pEAblock -> nID = EF_OS2EA; + pEAblock -> nSize = sizeof(pEAblock -> lSize); + pEAblock -> lSize = ulAttributes; /* uncompressed size */ + + nLength = (USHORT) memcompress((char *) (pEAblock + 1), + nMaxSize - sizeof(EFHEADER), (char *) pFEA2list, ulAttributes); + + *size += nLength; + pEAblock -> nSize += nLength; + + pEAblock = (PEFHEADER) pGEAlist; + + *cbufptr = (char *) pEAblock; + *csize = sizeof(EFHEADER); + + pEAblock -> nID = EF_OS2EA; + pEAblock -> nSize = sizeof(pEAblock -> lSize); + pEAblock -> lSize = ulAttributes; + + if (noisy) + printf(" (%ld bytes EA's)", ulAttributes); +} + +#endif /* __32BIT__ */ + +void GetACL(char *path, char **bufptr, size_t *size, + char **cbufptr, size_t *csize) +{ + static char *buffer; + char *cbuffer; + long bytes, cbytes; + PEFHEADER pACLblock; + + if (buffer == NULL) /* avoid frequent allocation (for every file) */ + if ((buffer = malloc(ACL_BUFFERSIZE)) == NULL) + return; + + if (acl_get(NULL, path, buffer)) + return; /* this will be the most likely case */ + + bytes = strlen(buffer); + + /* The maximum compressed size is (in case of STORE type) the + uncompressed size plus the size of the compression type field + plus the size of the CRC field + 2*5 deflate overhead bytes + for uncompressable data. + (5 bytes per 32Kb block, max compressed size = 2 blocks) */ + + cbytes = bytes + sizeof(USHORT) + sizeof(ULONG) + EB_DEFLAT_EXTRA; + if ((*bufptr = realloc(*bufptr, *size + sizeof(EFHEADER) + cbytes)) == NULL) + return; + + pACLblock = (PEFHEADER) (*bufptr + *size); + + cbuffer = (char *) (pACLblock + 1); + cbytes = memcompress(cbuffer, cbytes, buffer, bytes); + + *size += sizeof(EFHEADER) + cbytes; + + pACLblock -> nID = EF_ACL; + pACLblock -> nSize = sizeof(pACLblock -> lSize) + cbytes; + pACLblock -> lSize = bytes; /* uncompressed size */ + + if ((*cbufptr = realloc(*cbufptr, *csize + sizeof(EFHEADER))) == NULL) + return; + + pACLblock = (PEFHEADER) (*cbufptr + *csize); + *csize += sizeof(EFHEADER); + + pACLblock -> nID = EF_ACL; + pACLblock -> nSize = sizeof(pACLblock -> lSize); + pACLblock -> lSize = bytes; + + if (noisy) + printf(" (%ld bytes ACL)", bytes); +} + +#ifdef USE_EF_UT_TIME + +int GetExtraTime(struct zlist far *z, iztimes *z_utim) +{ + int eb_c_size = EB_HEADSIZE + EB_UT_LEN(1); + int eb_l_size = eb_c_size; + char *eb_c_ptr; + char *eb_l_ptr; + unsigned long ultime; + +#ifdef IZ_CHECK_TZ + if (!zp_tz_is_valid) return ZE_OK; /* skip silently no correct tz info */ +#endif + + eb_c_ptr = realloc(z->cextra, (z->cext + eb_c_size)); + if (eb_c_ptr == NULL) + return ZE_MEM; + z->cextra = eb_c_ptr; + eb_c_ptr += z->cext; + z->cext += eb_c_size; + + eb_c_ptr[0] = 'U'; + eb_c_ptr[1] = 'T'; + eb_c_ptr[2] = EB_UT_LEN(1); /* length of data part of e.f. */ + eb_c_ptr[3] = 0; + eb_c_ptr[4] = EB_UT_FL_MTIME; + ultime = (unsigned long) z_utim->mtime; + eb_c_ptr[5] = (char)(ultime); + eb_c_ptr[6] = (char)(ultime >> 8); + eb_c_ptr[7] = (char)(ultime >> 16); + eb_c_ptr[8] = (char)(ultime >> 24); + + if (z_utim->mtime != z_utim->atime || z_utim->mtime != z_utim->ctime) + { + eb_c_ptr[4] = EB_UT_FL_MTIME | EB_UT_FL_ATIME | EB_UT_FL_CTIME; + eb_l_size = EB_HEADSIZE + EB_UT_LEN(3); /* only on HPFS they can differ */ + /* so only then it makes sense to store all three time stamps */ + } + + eb_l_ptr = realloc(z->extra, (z->ext + eb_l_size)); + if (eb_l_ptr == NULL) + return ZE_MEM; + z->extra = eb_l_ptr; + eb_l_ptr += z->ext; + z->ext += eb_l_size; + + memcpy(eb_l_ptr, eb_c_ptr, eb_c_size); + + if (eb_l_size > eb_c_size) + { + eb_l_ptr[2] = EB_UT_LEN(3); + ultime = (unsigned long) z_utim->atime; + eb_l_ptr[9] = (char)(ultime); + eb_l_ptr[10] = (char)(ultime >> 8); + eb_l_ptr[11] = (char)(ultime >> 16); + eb_l_ptr[12] = (char)(ultime >> 24); + ultime = (unsigned long) z_utim->ctime; + eb_l_ptr[13] = (char)(ultime); + eb_l_ptr[14] = (char)(ultime >> 8); + eb_l_ptr[15] = (char)(ultime >> 16); + eb_l_ptr[16] = (char)(ultime >> 24); + } + + return ZE_OK; +} + +#endif /* USE_EF_UT_TIME */ + +int set_extra_field(struct zlist far *z, iztimes *z_utim) +{ + /* store EA data in local header, and size only in central headers */ + GetEAs(z->name, &z->extra, &z->ext, &z->cextra, &z->cext); + + /* store ACL data in local header, and size only in central headers */ + GetACL(z->name, &z->extra, &z->ext, &z->cextra, &z->cext); + +#ifdef USE_EF_UT_TIME + /* store extended time stamps in both headers */ + return GetExtraTime(z, z_utim); +#else /* !USE_EF_UT_TIME */ + return ZE_OK; +#endif /* ?USE_EF_UT_TIME */ +} + +#endif /* !UTIL */ + +/* Initialize the table of uppercase characters including handling of + country dependent characters. */ + +void init_upper() +{ + COUNTRYCODE cc; + unsigned nCnt, nU; + + for (nCnt = 0; nCnt < sizeof(upper); nCnt++) + upper[nCnt] = lower[nCnt] = (unsigned char) nCnt; + + cc.country = cc.codepage = 0; + DosMapCase(sizeof(upper), &cc, (PCHAR) upper); + + for (nCnt = 0; nCnt < 256; nCnt++) + { + nU = upper[nCnt]; + if (nU != nCnt && lower[nU] == (unsigned char) nU) + lower[nU] = (unsigned char) nCnt; + } + + for (nCnt = 'A'; nCnt <= 'Z'; nCnt++) + lower[nCnt] = (unsigned char) (nCnt - 'A' + 'a'); +} + +char *StringLower(char *szArg) +{ + unsigned char *szPtr; + for (szPtr = (unsigned char *) szArg; *szPtr; szPtr++) + *szPtr = lower[*szPtr]; + return szArg; +} + +#if defined(__IBMC__) && defined(__DEBUG_ALLOC__) +void DebugMalloc(void) +{ + _dump_allocated(0); /* print out debug malloc memory statistics */ +} +#endif + + +/******************************/ +/* Function version_local() */ +/******************************/ + +void version_local() +{ + static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n"; +#if defined(__IBMC__) || defined(__WATCOMC__) || defined(_MSC_VER) + char buf[80]; +#endif + + printf(CompiledWith, + +#ifdef __GNUC__ +# ifdef __EMX__ /* __EMX__ is defined as "1" only (sigh) */ + "emx+gcc ", __VERSION__, +# else + "gcc/2 ", __VERSION__, +# endif +#elif defined(__IBMC__) + "IBM ", +# if (__IBMC__ < 200) + (sprintf(buf, "C Set/2 %d.%02d", __IBMC__/100,__IBMC__%100), buf), +# elif (__IBMC__ < 300) + (sprintf(buf, "C Set++ %d.%02d", __IBMC__/100,__IBMC__%100), buf), +# else + (sprintf(buf, "Visual Age C++ %d.%02d", __IBMC__/100,__IBMC__%100), buf), +# endif +#elif defined(__WATCOMC__) + "Watcom C", (sprintf(buf, " (__WATCOMC__ = %d)", __WATCOMC__), buf), +#elif defined(__TURBOC__) +# ifdef __BORLANDC__ + "Borland C++", +# if (__BORLANDC__ < 0x0460) + " 1.0", +# elif (__BORLANDC__ == 0x0460) + " 1.5", +# else + " 2.0", +# endif +# else + "Turbo C", +# if (__TURBOC__ >= 661) + "++ 1.0 or later", +# elif (__TURBOC__ == 661) + " 3.0?", +# elif (__TURBOC__ == 397) + " 2.0", +# else + " 1.0 or 1.5?", +# endif +# endif +#elif defined(MSC) + "Microsoft C ", +# ifdef _MSC_VER + (sprintf(buf, "%d.%02d", _MSC_VER/100, _MSC_VER%100), buf), +# else + "5.1 or earlier", +# endif +#else + "unknown compiler", "", +#endif /* __GNUC__ */ + + "OS/2", + +/* GRR: does IBM C/2 identify itself as IBM rather than Microsoft? */ +#if (defined(MSC) || (defined(__WATCOMC__) && !defined(__386__))) +# if defined(M_I86HM) || defined(__HUGE__) + " (16-bit, huge)", +# elif defined(M_I86LM) || defined(__LARGE__) + " (16-bit, large)", +# elif defined(M_I86MM) || defined(__MEDIUM__) + " (16-bit, medium)", +# elif defined(M_I86CM) || defined(__COMPACT__) + " (16-bit, compact)", +# elif defined(M_I86SM) || defined(__SMALL__) + " (16-bit, small)", +# elif defined(M_I86TM) || defined(__TINY__) + " (16-bit, tiny)", +# else + " (16-bit)", +# endif +#else + " 2.x/3.x (32-bit)", +#endif + +#ifdef __DATE__ + " on ", __DATE__ +#else + "", "" +#endif + ); + + /* temporary debugging code for Borland compilers only */ +#ifdef __TURBOC__ + printf("\t(__TURBOC__ = 0x%04x = %d)\n", __TURBOC__, __TURBOC__); +#ifdef __BORLANDC__ + printf("\t(__BORLANDC__ = 0x%04x)\n",__BORLANDC__); +#else + printf("\tdebug(__BORLANDC__ not defined)\n"); +#endif +#ifdef __TCPLUSPLUS__ + printf("\t(__TCPLUSPLUS__ = 0x%04x)\n", __TCPLUSPLUS__); +#else + printf("\tdebug(__TCPLUSPLUS__ not defined)\n"); +#endif +#ifdef __BCPLUSPLUS__ + printf("\t(__BCPLUSPLUS__ = 0x%04x)\n\n", __BCPLUSPLUS__); +#else + printf("\tdebug(__BCPLUSPLUS__ not defined)\n\n"); +#endif +#endif /* __TURBOC__ */ + +} /* end function version_local() */ + +#endif /* OS2 */ diff --git a/os2/os2zip.h b/os2/os2zip.h new file mode 100644 index 0000000..06d0a02 --- /dev/null +++ b/os2/os2zip.h @@ -0,0 +1,84 @@ +/* + * @(#) dir.h 1.4 87/11/06 Public Domain. + * + * A public domain implementation of BSD directory routines for + * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield), + * August 1987 + * + * Ported to OS/2 by Kai Uwe Rommel + * Addition of other OS/2 file system specific code + * Placed into the public domain + */ + + +#define MAXNAMLEN 256 +#define MAXPATHLEN 256 + +#define _A_RONLY 0x01 +#define _A_HIDDEN 0x02 +#define _A_SYSTEM 0x04 +#define _A_VOLID 0x08 +#define _A_DIR 0x10 +#define _A_ARCHIVE 0x20 + + +struct dirent +{ + ino_t d_ino; /* a bit of a farce */ + int d_reclen; /* more farce */ + int d_namlen; /* length of d_name */ + char d_name[MAXNAMLEN + 1]; /* null terminated */ + /* nonstandard fields */ + long d_size; /* size in bytes */ + unsigned d_mode; /* DOS or OS/2 file attributes */ + unsigned d_time; + unsigned d_date; +}; + +/* The fields d_size and d_mode are extensions by me (Kai Uwe Rommel). + * The find_first and find_next calls deliver this data without any extra cost. + * If this data is needed, these fields save a lot of extra calls to stat() + * (each stat() again performs a find_first call !). + */ + +struct _dircontents +{ + char *_d_entry; + long _d_size; + unsigned _d_mode, _d_time, _d_date; + struct _dircontents *_d_next; +}; + +typedef struct _dirdesc +{ + int dd_id; /* uniquely identify each open directory */ + long dd_loc; /* where we are in directory entry is this */ + struct _dircontents *dd_contents; /* pointer to contents of dir */ + struct _dircontents *dd_cp; /* pointer to current position */ +} +DIR; + + +extern DIR *opendir(const char *); +extern struct dirent *readdir(DIR *); +extern void seekdir(DIR *, long); +extern long telldir(DIR *); +extern void closedir(DIR *); +#define rewinddir(dirp) seekdir(dirp, 0L) + +int GetFileMode(char *name); +ulg GetFileTime(char *name); +void SetFileTime(char *path, ulg stamp); +char *getVolumeLabel(int drive, unsigned long *time, unsigned long *mode, + time_t *utim); + +int IsFileNameValid(char *name); +int IsFileSystemFAT(char *dir); +void ChangeNameForFAT(char *name); + +char *GetLongNameEA(const char *name); +char *GetLongPathEA(const char *name); +void GetEAs(char *name, char **bufptr, size_t *size, + char **cbufptr, size_t *csize); + +char *StringLower(char *); diff --git a/os2/osdep.h b/os2/osdep.h new file mode 100644 index 0000000..ea2c3f9 --- /dev/null +++ b/os2/osdep.h @@ -0,0 +1,173 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#if defined(__OS2__) && !defined(OS2) +# define OS2 +#endif + +/* Automatic setting of the common Microsoft C idenfifier MSC. + * NOTE: Watcom also defines M_I*86 ! + */ +#if defined(_MSC_VER) || (defined(M_I86) && !defined(__WATCOMC__)) +# ifndef MSC +# define MSC /* This should work for older MSC, too! */ +# endif +#endif + +#if defined(__WATCOMC__) && defined(__386__) +# define WATCOMC_386 +#endif + +#if defined(__EMX__) || defined(WATCOMC_386) || defined(__BORLANDC__) +# if (defined(OS2) && !defined(__32BIT__)) +# define __32BIT__ +# endif +#endif + +#if defined(OS2) && !defined(__32BIT__) +# define MEMORY16 +#endif + +#ifndef NO_ASM +# define ASMV +/* # define ASM_CRC */ +#endif + +/* enable creation of UTC time fields unless explicitely suppressed */ +#if (!defined(NO_EF_UT_TIME) && !defined(USE_EF_UT_TIME)) +# define USE_EF_UT_TIME +#endif + +/* check that TZ environment variable is defined before using UTC times */ +#if (!defined(NO_IZ_CHECK_TZ) && !defined(IZ_CHECK_TZ)) +# define IZ_CHECK_TZ +#endif + +#ifndef ZP_NEED_MEMCOMPR +# define ZP_NEED_MEMCOMPR +#endif + +#ifdef MEMORY16 +# ifdef __TURBOC__ +# include +# if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__) +# if defined(DYNAMIC_CRC_TABLE) && defined(DYNALLOC_CRCTAB) + error: No dynamic CRC table allocation with Borland C far data models. +# endif /* DYNAMIC_CRC_TABLE */ +# endif /* Turbo/Borland C far data memory models */ +# define nearmalloc malloc +# define nearfree free +# define DYN_ALLOC +# else /* !__TURBOC__ */ +# include +# define nearmalloc _nmalloc +# define nearfree _nfree +# define farmalloc _fmalloc +# define farfree _ffree +# endif /* ?__TURBOC__ */ +# define MY_ZCALLOC 1 +#endif /* MEMORY16 */ + + +/* The symbol MSDOS is consistently used in the generic source files + * to identify code to support for MSDOS (and MSDOS related) stuff. + * e.g: FAT or (FAT like) file systems, + * '\\' as directory separator in paths, + * "\r\n" as record (line) terminator in text files, ... + * + * MSDOS is defined anyway with MS C 16-bit. So the block above works. + * For the 32-bit compilers, MSDOS must not be defined in the block above. + */ +#if (defined(OS2) && !defined(MSDOS)) +# define MSDOS +/* inherit MS-DOS file system etc. stuff */ +#endif + +#define USE_CASE_MAP +#define PROCNAME(n) (action == ADD || action == UPDATE ? wild(n) : \ + procname(n, 1)) + +/* time stamp resolution of file system is 2 seconds */ +#define ROUNDED_TIME(time) ((time_t)(((unsigned long)(time) + 1) & (~1))) + +#define FOPR "rb" +#define FOPM "r+b" +#define FOPW "wb" + +#ifdef __32BIT__ +# define CBSZ 0x40000 +# define ZBSZ 0x40000 +#else +# define CBSZ 0xE000 +# define ZBSZ 0x7F00 /* Some libraries do not allow a buffer size > 32K */ +#endif + +#include +#include +#include + +#ifdef ZCRYPT_INTERNAL +# ifndef __GO32__ +# include /* getpid() declaration for srand seed */ +# endif +#endif + +/* for some (all ?) versions of IBM C Set/2 and IBM C Set++ */ +#ifndef S_IFMT +# define S_IFMT 0xF000 +#endif /* !S_IFMT */ + +#ifdef MSC +# define NO_UNISTD_H +#endif + +#ifdef __WATCOMC__ +# define NO_MKTEMP +/* Get asm routines to link properly without using "__cdecl": */ +# ifdef __386__ +# ifdef ASMV +# pragma aux window "*"; +# pragma aux prev "*"; +# pragma aux prev_length "*"; +# pragma aux strstart "*"; +# pragma aux match_start "*"; +# pragma aux max_chain_length "*"; +# pragma aux good_match "*"; +# pragma aux nice_match "*"; +# pragma aux match_init "*"; +# pragma aux longest_match "*"; +# endif +# ifndef USE_ZLIB +# pragma aux crc32 "_*" parm caller [] value [eax] modify [eax] +# pragma aux get_crc_table "_*" parm caller [] value [eax] \ + modify [eax ecx edx] +# endif /* !USE_ZLIB */ +# else /* !__386__ */ +# if defined(ASMV) || defined(ASM_CRC) +/*# error 16 bit assembly modules currently DO NOT WORK with Watcom C. */ +# endif +# ifdef ASMV +# pragma aux match_init "_*" parm caller [] loadds modify [ax bx] +# pragma aux longest_match "_*" parm caller [] loadds value [ax] \ + modify [ax bx cx dx es] +# endif +# ifndef USE_ZLIB +# pragma aux crc32 "_*" parm caller [] value [ax dx] \ + modify [ax bx cx dx es] +# pragma aux get_crc_table "_*" parm caller [] value [ax] \ + modify [ax bx cx dx] +# endif /* !USE_ZLIB */ +# endif /* ?__386__ */ +#endif + +#ifdef __IBMC__ +# define NO_UNISTD_H +# define NO_MKTEMP +# define timezone _timezone /* (underscore names work with */ +# define tzset _tzset /* all versions of C Set) */ +#endif diff --git a/os2/zip.def b/os2/zip.def new file mode 100644 index 0000000..7404eee --- /dev/null +++ b/os2/zip.def @@ -0,0 +1,3 @@ +NAME WINDOWCOMPAT NEWFILES +DESCRIPTION 'The world-famous zip utilities from Info-ZIP' +; STACKSIZE 0x50000 diff --git a/os2/zipup.h b/os2/zipup.h new file mode 100644 index 0000000..592cff8 --- /dev/null +++ b/os2/zipup.h @@ -0,0 +1,16 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#define fhow (O_RDONLY|O_BINARY) +#define fbad (-1) +typedef int ftype; +#define zopen(n,p) open(n,p) +#define zread(f,b,n) read(f,b,n) +#define zclose(f) close(f) +#define zerr(f) (k == (extent)(-1L)) +#define zstdin 0 diff --git a/proginfo/3rdparty.bug b/proginfo/3rdparty.bug new file mode 100644 index 0000000..32e7823 --- /dev/null +++ b/proginfo/3rdparty.bug @@ -0,0 +1,114 @@ +Known, current PKZIP bugs/limitations: +------------------------------------- + + - PKUNZIP 2.04g is reported to corrupt some files when compressing them with + the -ex option; when tested, the files fail the CRC check, and comparison + with the original file shows bogus data (6K in one case) embedded in the + middle. PKWARE apparently characterized this as a "known problem." + + - PKUNZIP 2.04g considers volume labels valid only if originated on a FAT + file system, but other OSes and file systems (e.g., Amiga and OS/2 HPFS) + support volume labels, too. + + - PKUNZIP 2.04g can restore volume labels created by Zip 2.x but not by + PKZIP 2.04g (OS/2 DOS box only??). + + - PKUNZIP 2.04g gives an error message for stored directory entries created + under other OSes (although it creates the directory anyway), and PKZIP -vt + does not report the directory attribute bit as being set, even if it is. + + - PKZIP 2.04g mangles unknown extra fields (especially OS/2 extended attri- + butes) when adding new files to an existing zipfile [example: Walnut Creek + Hobbes March 1995 CD-ROM, FILE_ID.DIZ additions]. + + - PKUNZIP 2.04g is unable to detect or deal with prepended junk in a zipfile, + reporting CRC errors in valid compressed data. + + - PKUNZIP 2.04g (registered version) incorrectly updates/freshens the AV extra + field in authenticated archives. The resultant extra block length and total + extra field length are inconsistent. + + - [Windows version 2.01] Win95 long filenames (VFAT) are stored OK, but the + file system is always listed as ordinary DOS FAT. + + - [Windows version 2.50] NT long filenames (NTFS) are stored OK, but the + file system is always listed as ordinary DOS FAT. + + - PKZIP 2.04 for DOS encrypts using the OEM code page for 8-bit passwords, + while PKZIP 2.50 for Windows uses Latin-1 (ISO 8859-1). This means an + archive encrypted with an 8-bit password with one of the two PKZIP versions + cannot be decrypted with the other version. + + - PKZIP for Windows GUI (v 2.60), PKZIP for Windows command line (v 2.50) and + PKZIP for Unix (v 2.51) save the host's native file timestamps, but + only in a local extra field. Thus, timestamp-related selections (update + or freshen, both in extraction or archiving operations) use the DOS-format + localtime records in the Zip archives for comparisons. This may result + in wrong decisions of the program when updating archives that were + previously created in a different local time zone. + + - PKZIP releases newer than PKZIP for DOS 2.04g (PKZIP for Windows, both + GUI v 2.60 and console v 2.50; PKZIP for Unix v 2.51; probably others too) + use different code pages for storing filenames in central (OEM Codepage) + and local (ANSI / ISO 8859-1 Codepage) headers. When a stored filename + contains extended-ASCII characters, the local and central filename fields + do not match. As a consequence, Info-ZIP's Zip program considers such + archives as being corrupt and does not allow to modify them. Beginning + with release 5.41, Info-ZIP's UnZip contains a workaround to list AND + extract such archives with the correct filenames. + Maybe PKWARE has implemented this "feature" to allow extraction of their + "made-by-PKZIP for Unix/Windows" archives using old (v5.2 and earlier) + versions of Info-ZIP's UnZip for Unix/WinNT ??? (UnZip versions before + v 5.3 assumed that all archive entries were encoded in the codepage of + the UnZip program's host system.) + + - PKUNZIP 2.04g is reported to have problems with archives created on and/or + copied from Iomega ZIP drives (irony, eh?). + +Known, current WinZip bugs/limitations: +-------------------------------------- + + - [16-bit version 6.1a] NT short filenames (FAT) are stored OK, but the + file system is always listed as NTFS. + + - WinZip doesn't allow 8-bit passwords, which means it cannot decrypt an + archive created with an 8-bit password (by PKZIP or Info-ZIP's Zip). + + - WinZip (at least Versions 6.3 PL1, 7.0 SR1) fails to remove old extra + fields when freshening existing archive entries. When updating archives + created by Info-ZIP's Zip that contain UT time stamp extra field blocks, + UnZip cannot display or restore the updated (DOS) time stamps of the + freshened archive members. + +Known, current other third-party Zip utils bugs/limitations: +------------------------------------------------------------ + + - Asi's PKZip clones for Macintosh (versions 2.3 and 2.10d) are thoroughly + broken. They create invalid Zip archives! + a) For the first entry, both compressed size and uncompressed length + are recorded as 0, despite the fact that compressed data of non-zero + length has been added. + b) Their program creates extra fields with an (undocumented) internal + structure that violates the requirements of PKWARE's Zip format + specification document "appnote.txt": Their extra field seems to + contain pure data; the 4-byte block header consisting of block ID + and data length is missing. + +Possibly current PKZIP bugs: +--------------------------- + + - PKZIP (2.04g?) can silently ignore read errors on network drives, storing + the correct CRC and compressed length but an incorrect and inconsistent + uncompressed length. + + - PKZIP (2.04g?), when deleting files from within a zipfile on a Novell + drive, sometimes only zeros out the data while failing to shrink the + zipfile. + +Other limitations: +----------------- + + - PKZIP 1.x and 2.x encryption has been cracked (known-plaintext approach; + see http://www.cryptography.com/ for details). + +[many other bugs in PKZIP 1.0, 1.1, 1.93a, 2.04c and 2.04e] diff --git a/proginfo/ZipPorts b/proginfo/ZipPorts new file mode 100644 index 0000000..2d946d3 --- /dev/null +++ b/proginfo/ZipPorts @@ -0,0 +1,285 @@ +__________________________________________________________________________ + + This is the Info-ZIP file ZipPorts, last updated on 17 February 1996. +__________________________________________________________________________ + + +This document defines a set of rules and guidelines for those who wish to +contribute patches to Zip and UnZip (or even entire ports to new operating +systems). The list below is something between a style sheet and a "Miss +Manners" etiquette guide. While Info-ZIP encourages contributions and +fixes from anyone who finds something worth changing, we are also aware +of the fact that no two programmers have the programming style and that +unrestrained changes by a few dozen contributors would result in hideously +ugly (and unmaintainable) Frankenstein code. So consider the following an +attempt by the maintainers to maintain sanity as well as useful code. + +(The first version of this document was called either "ZipRules" or the +"No Feelthy ..." file and was compiled by David Kirschbaum in consulta- +tion with Mark Adler, Cave McNewt and others. The current incarnation +expands upon the original with insights gained from a few more years of +happy hacking...) + + +Summary: + + (0) The Platinum Rule: DON'T BREAK EXISTING PORTS +(0.1) The Golden Rule: DO UNTO THE CODE AS OTHERS HAVE DONE BEFORE +(0.2) The Silver Rule: DO UNTO THE LATEST BETA CODE +(0.3) The Bronze Rule: NO FEELTHY PIGGYBACKS + + (1) NO FEELTHY TABS + (2) NO FEELTHY CARRIAGE RETURNS + (3) NO FEELTHY 8-BIT CHARS + (4) NO FEELTHY LEFT-JUSTIFIED DASHES + (5) NO FEELTHY FANCY_FILENAMES + (6) NO FEELTHY NON-ZIPFILES AND NO FEELTHY E-MAIL BETAS + (7) NO FEELTHY E-MAIL BINARIES + + +Explanations: + + (0) The Platinum Rule: DON'T BREAK EXISTING PORTS + + No doubt about it, this is the one which really pisses us off and + pretty much guarantees that your port or patch will be ignored and/ + or laughed at. Examples range from the *really* severe cases which + "port" by ripping out all of the existing multi-OS code, to more + subtle oopers like relying on a local capability which doesn't exist + on other OSes or in older compilers (e.g., the use of ANSI "#elif" + or "#pragma" or "##" constructs, C++ comments, GNU extensions, etc.). + As to the former, use #ifdefs for your new code (see rule 0.3). And + as to the latter, trust us--there are few things we'd like better + than to be able to use some of the elegant "new" features out there + (many of which have been around for a decade or more). But our code + still compiles on machines dating back even longer, at least in spirit + --e.g., the AT&T 3B1 family and Dynix/ptx. Until we say otherwise, + dinosaurs are supported. + + +(0.1) The Golden Rule: DO UNTO THE CODE AS OTHERS HAVE DONE BEFORE + + In other words, try to fit into the local style of programming--no + matter how painful it may be. This includes cosmetic aspects like + indenting the same amount (both in the main C code and in the in- + clude files), using braces and comments similarly, NO TABS (see rule + #1), etc.; but also more substantive things like (for UnZip) putting + character strings into static (far) variables and using the LoadFar- + String macros to avoid overflowing limited MS-DOS data segments, and + using the ugly Info() macro instead of the more usual *printf() + functions so that dynamic-link-library ports are simpler. NEVER put + single-OS code (e.g., OS/2) of more than two or three lines into the + main (generic) modules; those are shared by everybody, and nobody else + cares about it or wants to see it. + + Note that not only do Zip and UnZip differ in these respects, so do + individual parts of each program. While it would be nice to have + global consistency, cosmetic changes are not a high priority; for + now we'll settle for local consistency--i.e., don't make things any + worse than they already are. + + Exception (BIG exception): single-letter variable names. Despite + the prevailing practice in much of Zip and parts of UnZip, and de- + spite the fact that one-letter variables allow you to pack really + cool, compact and complicated expressions onto one line, they also + make the code very difficult to maintain and are therefore *strongly* + discouraged. Don't ask us who is responsible in the first place; + while this sort of brain damage is not uncommon among former BASIC + programmers, it is nevertheless a lifelong embarrassment, and we do + try to pity the poor sod (that is, when we're not chasing bugs and + cursing him). :-) + + +(0.2) The Silver Rule: DO UNTO THE LATEST BETA CODE + + Few things are as annoying as receiving a large patch which obviously + represents a lot of time and careful work but which is relative to + an old version of Info-ZIP code. As wonderful as Larry Wall's patch + program is at applying context diffs to modified code, we regularly + make near-global changes and/or reorganize big chunks of the sources + (particularly in UnZip), and "patch" can't work miracles--big changes + invariably break any patch which is relative to an old version of the + code. + + Bottom line: contact the Info-ZIP core team FIRST (via the zip-bugs + e-mail address) and get up to date with the latest code before begin- + ning a big new port. And try to *stay* up to date while working on + your port--at least, as much as possible. + + +(0.3) The Bronze Rule: NO FEELTHY PIGGYBACKS + + UnZip is currently ported to something like 12 operating systems + (a few more or less depending on how one counts), and each of these, + with the possible exception of VM/CMS, has a unique macro identifying + it: AMIGA, ATARI_ST, __human68k__, MACOS, MSDOS, MVS, OS2, TOPS20, + UNIX, VMS, WIN32. Zip is moving in the same direction. New ports + should NOT piggyback one of the existing ports unless they are sub- + stantially similar--for example, Minix and Coherent are basically Unix + and therefore are included in the UNIX macro, but DOS djgpp ports and + OS/2 emx ports (both of which use the Unix-originated GNU C compiler + and often have "unix" defined by default) are obviously *not* Unix. + [The existing MTS port is a special exception; basically only one per- + son knows what MTS really is, and he's not telling. Presumably it's + not very close to Unix, but it's not worth arguing about it now.] + Along the same lines, neither OS/2 nor Human68K is the same as (or + even close to) MS-DOS. MVS and VM/CMS, on the other hand, are quite + similar to each other and are therefore combined in most places. + + Bottom line: when adding a new port (e.g., QDOS), create a new macro + for it ("QDOS"), a new subdirectory ("qdos") and a new source file for + OS-specific code ("qdos/qdos.c"). Use #ifdefs to fit any OS-specific + changes into the existing code (e.g., unzpriv.h). If it's close enough + to an existing port that piggybacking is a temptation, define a new + "combination macro" (e.g., "CMS_MVS") and replace the old macros as + required. (This last applies to UnZip, at least; the old preference + in Zip was fewer macros and long #ifdef lines, so talk to Onno or Jean- + loup about that.) See also rule 0.1. + + (Note that, for UnZip, new ports need not attempt to deal with all + features. Among other things, the wildcard-zipfile code in do_wild() + may be replaced with a supplied dummy version, since opendir/readdir/ + closedir() or the equivalent can be difficult to implement.) + + + (1) NO FEELTHY TABS + + Some editors and e-mail systems either have no capability to use + and/or display tab characters (ASCII 9) correctly, or they use non- + standard or variable-width tab columns, or other horrors. Some edi- + tors auto-convert spaces to tabs, after which the blind use of "diff + -c" results in a huge and mostly useless patch. Yes, *we* know about + diff's "-b" option, but not everyone does. And yes, we also know this + makes the source files bigger, even after compression; so be it. If + we *really* cared that much about the size of the sources, we'd still + be writing Unix-only utilities. + + Bottom line: use spaces, not tabs. + + Exception: some of the makefiles (the Unix one in particular) require + tabs as part of the syntax. + + Related utility programs: + Unix, OS/2 and MS-DOS: expand, unexpand. + MS-DOS: Buerg's TABS; Toad Hall's TOADSOFT. + And some editors have the conversion built-in. + + + (2) NO FEELTHY CARRIAGE RETURNS + + All source, documentation and other text files shall have Unix style + line endings (LF only, a.k.a. ctrl-J), not the DOS/OS2/NT CR+LF or Mac + CR-only line endings. + + Reason: "real programmers" in any environment can convert back and + forth between Unix and DOS/Mac style. All PC compilers but a few old + Borland versions can use either Unix or MS-DOS end-of-lines. Buerg's + LIST (file-display utility) for MS-DOS can use Unix or MS-DOS EOLs. + Both Zip and UnZip can convert line-endings as appropriate. But Unix + utilities like diff and patch die a horrible death (or produce horrible + output) if the target files have CRs. + + Related utilities: flip for Unix, OS/2 and MS-DOS; Unix "tr". + + Exceptions: documentation in pre-compiled binary distributions should + be in the local (target) format. + + + (3) NO FEELTHY 8-BIT CHARS + + Do all your editing in a plain-text ASCII editor. No WordPerfect, MS + Word, WordStar document mode, or other word processor files, thenkyew. + No desktop publishing. *Especially* no EBCDIC. No TIFFs, no GIFs, no + embedded pictures or dancing ladies (too bad, Cave Newt). [Sigh... -CN] + + Reason: compatibility with different consoles. My old XT clone is + the most limited! + + Exceptions: some Macintosh makefiles apparently require some 8-bit + characters; the Human68k port uses 8-bit characters for Kanji or Kana + comments (I think); etc. + + Related utilities: vi, emacs, EDLIN, Turbo C editor, other programmers' + editors, various word processor -> text conversion utilities. + + + (4) NO FEELTHY LEFT-JUSTIFIED DASHES + + Always precede repeated dashes (------) with one or more leading non- + dash characters: spaces, tabs, pound signs (#), comments (/*), what- + ever. + + Reason: sooner or later your source file will be e-mailed through an + undigestifier utility, most of which treat leading dashes as end-of- + message separators. We'd rather not have your code broken up into a + dozen separate untitled messages, thank you. + + + (5) NO FEELTHY FANCY_FILENAMES + + Assume the worst: that someone on a brain-damaged DOS system has to + work with everything your magic fingers produced. Keep the filenames + unimaginative and within MS-DOS limits (i.e., ordinary A..Z, 1..9, + "-$_!"-type characters, in the 8.3 "filename.ext" format). Mac and + Unix users, giggle all you want, but no spaces or multiple dots. + + Reason: compatibility with different file systems. MS-DOS FAT is the + most limited, with the exception of CompuServe (6.3, argh). + + Exceptions: slightly longer names are occasionally acceptable within + OS-specific subdirectories, but don't do that unless there's a good + reason for it. + + + (6) NO FEELTHY NON-ZIPFILES AND NO FEELTHY E-MAIL BETAS + + Beta testers and developers are in general expected to have both + ftp capability and the ability to deal with zipfiles. Those without + should either find a friend who does or else learn about ftp-mailers. + + Reason: the core development team barely has time to work on the + code, much less prepare oddball formats and/or mail betas out (and + the situation is getting worse, sigh). + + Exceptions: anyone seriously proposing to do a new port will be + given special treatment, particularly with respect to UnZip; we + obviously realize that bootstrapping a completely new port can be + quite difficult and have no desire to make it even harder due to + lack of access to the latest code (rule 0.2). + + Public releases of UnZip, on the other hand, will be available in + two formats: .tar.Z (16-bit compress'd tar) and .zip (either "plain" + or self-extracting). Zip sources and executables will generally only + be distributed in .zip format, since Zip is pretty much useless without + UnZip. + + + (7) NO FEELTHY E-MAIL BINARIES + + Binary files (e.g., executables, test zipfiles, etc.) should NEVER + be mailed raw. Where possible, they should be uploaded via ftp in + BINARY mode; if that's impossible, Mark's "ship" ASCII-encoder should + be used; and if that's unavailable, uuencode or xxencode should be + used. Weirdo NeXTmail, mailtool and MIME formats are also Right Out. + + Files larger than 50KB may need to be broken into pieces for mailing + (be sure to label them in order!), unless "ship" is used (it can + auto-split, label and mail files if told to do so). If Down Under + is involved, files must be broken into under-20KB chunks. + + Reasons: to prevent sounds of gagging mailers from resounding through- + out the land. To be relatively efficient in the binary->ASCII conver- + sion. (Yeah, yeah, I know, there's better conversions out there. But + not as widely known, and they often break on BITNET gateways.) + + Related utilities: ship, uuencode, uudecode, uuxfer20, quux, others. + Just make sure they don't leave embedded or trailing spaces (that is, + they should use the "`" character in place of ASCII 32). Otherwise + mailers are prone to truncate or whatever. + + +Greg Roelofs (a.k.a. Cave Newt) +Info-ZIP UnZip maintainer + +David Kirschbaum +former Info-ZIP Coordinator diff --git a/proginfo/algorith.txt b/proginfo/algorith.txt new file mode 100644 index 0000000..867e30b --- /dev/null +++ b/proginfo/algorith.txt @@ -0,0 +1,68 @@ +Zip's deflation algorithm is a variation of LZ77 (Lempel-Ziv 1977, see +reference below). It finds duplicated strings in the input data. The +second occurrence of a string is replaced by a pointer to the previous +string, in the form of a pair (distance, length). Distances are +limited to 32K bytes, and lengths are limited to 258 bytes. When a +string does not occur anywhere in the previous 32K bytes, it is +emitted as a sequence of literal bytes. (In this description, +'string' must be taken as an arbitrary sequence of bytes, and is not +restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when zip determines that it +would be useful to start another block with fresh trees. (This is +somewhat similar to compress.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (zip -1 +to -9). So zip does not always find the longest possible match but +generally finds a match which is long enough. + +zip also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, zip searches for a +longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the longer match is emitted afterwards. Otherwise, +the original match is kept, and the next match search is attempted only +N steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, zip reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, zip attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (speed options -1 to -3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + +Jean-loup Gailly +jloup@chorus.fr + +References: + +[LZ77] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data +Compression", IEEE Transactions on Information Theory", Vol. 23, No. 3, +pp. 337-343. + +APPNOTE.TXT documentation file in PKZIP 1.93a. It is available by +ftp in ftp.cso.uiuc.edu:/pc/exec-pc/pkz193a.exe [128.174.5.59] + +'Deflate' Compressed Data Format Specification: +ftp://ftp.uu.net/pub/archiving/zip/doc/deflate-1.1.doc diff --git a/proginfo/ebcdic.msg b/proginfo/ebcdic.msg new file mode 100644 index 0000000..1a7bbad --- /dev/null +++ b/proginfo/ebcdic.msg @@ -0,0 +1,63 @@ +From dima@mitrah.ru Mon Nov 10 02:25:38 2003 +Return-Path: +Received: from b.mx.sonic.net (eth0.b.mx.sonic.net [209.204.159.4]) + by eth0.a.lds.sonic.net (8.12.10/8.12.9) with ESMTP id hAAAPccT025257 + for ; Mon, 10 Nov 2003 02:25:38 -0800 +Received: from icicle.pobox.com (icicle.pobox.com [207.8.214.2]) + by b.mx.sonic.net (8.12.10/8.12.7) with ESMTP id hAAAPar9007141 + for ; Mon, 10 Nov 2003 02:25:37 -0800 +Received: from icicle.pobox.com (localhost[127.0.0.1]) + by icicle.pobox.com (Postfix) with ESMTP id 9BA347A96B + for ; Sat, 8 Nov 2003 06:15:13 -0500 (EST) +Delivered-To: newt@pobox.com +Received: from mail.ropnet.ru (mail.ropnet.ru[212.42.37.90]) + by icicle.pobox.com (Postfix) with ESMTP id A96817A8F7 + for ; Sat, 8 Nov 2003 06:15:04 -0500 (EST) +Received: from d34-67.ropnet.ru (d34-67.ropnet.ru [212.42.34.67]) + by mail.ropnet.ru (8.11.7/8.11.7) with ESMTP id hA8BEjF76200 + for ; Sat, 8 Nov 2003 14:14:46 +0300 (MSK) +Resent-Date: Sat, 8 Nov 2003 14:14:46 +0300 (MSK) +Resent-Message-Id: <200311081114.hA8BEjF76200@mail.ropnet.ru> +Date: Sat, 8 Nov 2003 14:18:18 +0300 +From: Dmitri Koulikov +X-Mailer: The Bat! (v1.62r) Personal +Reply-To: Dmitri Koulikov +X-Priority: 3 (Normal) +Message-ID: <815640011.20031108141818@mitrah.ru> +To: newt@pobox.com +Subject: unzip and zip lack NLS - 2 +Resent-From: Dmitri Koulikov +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="----------EB1581C42AB86662" +Status: R + +------------EB1581C42AB86662 +Content-Type: text/plain; charset=us-ascii +Content-Transfer-Encoding: 7bit + +Hello Greg Roelofs, + + By mistake I sent you wrong version of ebcdic.h. Now it is as it +have to. + Additionally I found that zip works with Russian filenames good. +But fails to process -D switch. So I have to chahge zipfile.c. Most +probably this is not good but it works. + +-- +Best regards, + Dmitri + +mailto:dima@mitrah.ru +------------EB1581C42AB86662 +Content-Type: application/octet-stream; name="ebcdic.h" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename="ebcdic.h" + +------------EB1581C42AB86662 +Content-Type: application/octet-stream; name="zipfile.c" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; filename="zipfile.c" + +------------EB1581C42AB86662-- + + diff --git a/proginfo/extrafld.txt b/proginfo/extrafld.txt new file mode 100644 index 0000000..624e05c --- /dev/null +++ b/proginfo/extrafld.txt @@ -0,0 +1,1372 @@ +The following are the known types of zipfile extra fields as of this +writing. Extra fields are documented in PKWARE's appnote.txt and are +intended to allow for backward- and forward-compatible extensions to +the zipfile format. Multiple extra-field types may be chained together, +provided that the total length of all extra-field data is less than 64KB. +(In fact, PKWARE requires that the total length of the entire file header, +including timestamp, file attributes, filename, comment, extra field, etc., +be no more than 64KB.) + +Each extra-field type (or subblock) must contain a four-byte header con- +sisting of a two-byte header ID and a two-byte length (little-endian) for +the remaining data in the subblock. If there are additional subblocks +within the extra field, the header for each one will appear immediately +following the data for the previous subblock (i.e., with no padding for +alignment). + +All integer fields in the descriptions below are in little-endian (Intel) +format unless otherwise specified. Note that "Short" means two bytes, +"Long" means four bytes, and "Long-Long" means eight bytes, regardless +of their native sizes. Unless specifically noted, all integer fields should +be interpreted as unsigned (non-negative) numbers. + +Christian Spieler, 20010517 + +Updated to include the Unicode extra fields. Added new Unix extra field. + +Ed Gordon, 20060819, 20070607, 20070909, 20080426, 20080509 + + ------------------------- + + Header ID's of 0 thru 31 are reserved for use by PKWARE. + The remaining ID's can be used by third party vendors for + proprietary usage. + + The current Header ID mappings defined by PKWARE are: + + 0x0001 ZIP64 extended information extra field + 0x0007 AV Info + 0x0009 OS/2 extended attributes (also Info-ZIP) + 0x000a NTFS (Win9x/WinNT FileTimes) + 0x000c OpenVMS (also Info-ZIP) + 0x000d Unix + 0x000f Patch Descriptor + 0x0014 PKCS#7 Store for X.509 Certificates + 0x0015 X.509 Certificate ID and Signature for + individual file + 0x0016 X.509 Certificate ID for Central Directory + + The Header ID mappings defined by Info-ZIP and third parties are: + + 0x0065 IBM S/390 attributes - uncompressed + 0x0066 IBM S/390 attributes - compressed + 0x07c8 Info-ZIP Macintosh (old, J. Lee) + 0x2605 ZipIt Macintosh (first version) + 0x2705 ZipIt Macintosh v 1.3.5 and newer (w/o full filename) + 0x334d Info-ZIP Macintosh (new, D. Haase's 'Mac3' field ) + 0x4154 Tandem NSK + 0x4341 Acorn/SparkFS (David Pilling) + 0x4453 Windows NT security descriptor (binary ACL) + 0x4704 VM/CMS + 0x470f MVS + 0x4854 Theos, old inofficial port + 0x4b46 FWKCS MD5 (see below) + 0x4c41 OS/2 access control list (text ACL) + 0x4d49 Info-ZIP OpenVMS (obsolete) + 0x4d63 Macintosh SmartZIP, by Macro Bambini + 0x4f4c Xceed original location extra field + 0x5356 AOS/VS (binary ACL) + 0x5455 extended timestamp + 0x5855 Info-ZIP Unix (original; also OS/2, NT, etc.) + 0x554e Xceed unicode extra field + 0x6375 Info-ZIP Unicode Comment + 0x6542 BeOS (BeBox, PowerMac, etc.) + 0x6854 Theos + 0x7075 Info-ZIP Unicode Path + 0x756e ASi Unix + 0x7855 Info-ZIP Unix (previous new) + 0x7875 Info-ZIP Unix (new) + 0xfb4a SMS/QDOS + +The following are detailed descriptions of the known extra-field block types: + + -OS/2 Extended Attributes Extra Field: + ==================================== + + The following is the layout of the OS/2 extended attributes "extra" + block. (Last Revision 19960922) + + Note: all fields stored in Intel low-byte/high-byte order. + + Local-header version: + + Value Size Description + ----- ---- ----------- + (OS/2) 0x0009 Short tag for this extra block type + TSize Short total data size for this block + BSize Long uncompressed EA data size + CType Short compression type + EACRC Long CRC value for uncompressed EA data + (var.) variable compressed EA data + + Central-header version: + + Value Size Description + ----- ---- ----------- + (OS/2) 0x0009 Short tag for this extra block type + TSize Short total data size for this block (4) + BSize Long size of uncompressed local EA data + + The value of CType is interpreted according to the "compression + method" section above; i.e., 0 for stored, 8 for deflated, etc. + + The OS/2 extended attribute structure (FEA2LIST) is compressed and + then stored in its entirety within this structure. There will only + ever be one block of data in the variable-length field. + + + -OS/2 Access Control List Extra Field: + ==================================== + + The following is the layout of the OS/2 ACL extra block. + (Last Revision 19960922) + + Local-header version: + + Value Size Description + ----- ---- ----------- + (ACL) 0x4c41 Short tag for this extra block type ("AL") + TSize Short total data size for this block + BSize Long uncompressed ACL data size + CType Short compression type + EACRC Long CRC value for uncompressed ACL data + (var.) variable compressed ACL data + + Central-header version: + + Value Size Description + ----- ---- ----------- + (ACL) 0x4c41 Short tag for this extra block type ("AL") + TSize Short total data size for this block (4) + BSize Long size of uncompressed local ACL data + + The value of CType is interpreted according to the "compression + method" section above; i.e., 0 for stored, 8 for deflated, etc. + + The uncompressed ACL data consist of a text header of the form + "ACL1:%hX,%hd\n", where the first field is the OS/2 ACCINFO acc_attr + member and the second is acc_count, followed by acc_count strings + of the form "%s,%hx\n", where the first field is acl_ugname (user + group name) and the second acl_access. This block type will be + extended for other operating systems as needed. + + + -Windows NT Security Descriptor Extra Field: + ========================================== + + The following is the layout of the NT Security Descriptor (another + type of ACL) extra block. (Last Revision 19960922) + + Local-header version: + + Value Size Description + ----- ---- ----------- + (SD) 0x4453 Short tag for this extra block type ("SD") + TSize Short total data size for this block + BSize Long uncompressed SD data size + Version Byte version of uncompressed SD data format + CType Short compression type + EACRC Long CRC value for uncompressed SD data + (var.) variable compressed SD data + + Central-header version: + + Value Size Description + ----- ---- ----------- + (SD) 0x4453 Short tag for this extra block type ("SD") + TSize Short total data size for this block (4) + BSize Long size of uncompressed local SD data + + The value of CType is interpreted according to the "compression + method" section above; i.e., 0 for stored, 8 for deflated, etc. + Version specifies how the compressed data are to be interpreted + and allows for future expansion of this extra field type. Currently + only version 0 is defined. + + For version 0, the compressed data are to be interpreted as a single + valid Windows NT SECURITY_DESCRIPTOR data structure, in self-relative + format. + + + -PKWARE Win95/WinNT Extra Field: + ============================== + + The following description covers PKWARE's "NTFS" attributes + "extra" block, introduced with the release of PKZIP 2.50 for + Windows. (Last Revision 20001118) + + (Note: At this time the Mtime, Atime and Ctime values may + be used on any WIN32 system.) + [Info-ZIP note: In the current implementations, this field has + a fixed total data size of 32 bytes and is only stored as local + extra field.] + + Value Size Description + ----- ---- ----------- + (NTFS) 0x000a Short Tag for this "extra" block type + TSize Short Total Data Size for this block + Reserved Long for future use + Tag1 Short NTFS attribute tag value #1 + Size1 Short Size of attribute #1, in bytes + (var.) SubSize1 Attribute #1 data + . + . + . + TagN Short NTFS attribute tag value #N + SizeN Short Size of attribute #N, in bytes + (var.) SubSize1 Attribute #N data + + For NTFS, values for Tag1 through TagN are as follows: + (currently only one set of attributes is defined for NTFS) + + Tag Size Description + ----- ---- ----------- + 0x0001 2 bytes Tag for attribute #1 + Size1 2 bytes Size of attribute #1, in bytes (24) + Mtime 8 bytes 64-bit NTFS file last modification time + Atime 8 bytes 64-bit NTFS file last access time + Ctime 8 bytes 64-bit NTFS file creation time + + The total length for this block is 28 bytes, resulting in a + fixed size value of 32 for the TSize field of the NTFS block. + + The NTFS filetimes are 64-bit unsigned integers, stored in Intel + (least significant byte first) byte order. They determine the + number of 1.0E-07 seconds (1/10th microseconds!) past WinNT "epoch", + which is "01-Jan-1601 00:00:00 UTC". + + + -PKWARE OpenVMS Extra Field: + ========================== + + The following is the layout of PKWARE's OpenVMS attributes "extra" + block. (Last Revision 12/17/91) + + Note: all fields stored in Intel low-byte/high-byte order. + + Value Size Description + ----- ---- ----------- + (VMS) 0x000c Short Tag for this "extra" block type + TSize Short Total Data Size for this block + CRC Long 32-bit CRC for remainder of the block + Tag1 Short OpenVMS attribute tag value #1 + Size1 Short Size of attribute #1, in bytes + (var.) Size1 Attribute #1 data + . + . + . + TagN Short OpenVMS attribute tage value #N + SizeN Short Size of attribute #N, in bytes + (var.) SizeN Attribute #N data + + Rules: + + 1. There will be one or more of attributes present, which + will each be preceded by the above TagX & SizeX values. + These values are identical to the ATR$C_XXXX and + ATR$S_XXXX constants which are defined in ATR.H under + OpenVMS C. Neither of these values will ever be zero. + + 2. No word alignment or padding is performed. + + 3. A well-behaved PKZIP/OpenVMS program should never produce + more than one sub-block with the same TagX value. Also, + there will never be more than one "extra" block of type + 0x000c in a particular directory record. + + + -Info-ZIP VMS Extra Field: + ======================== + + The following is the layout of Info-ZIP's VMS attributes extra + block for VAX or Alpha AXP. The local-header and central-header + versions are identical. (Last Revision 19960922) + + Value Size Description + ----- ---- ----------- + (VMS2) 0x4d49 Short tag for this extra block type ("JM") + TSize Short total data size for this block + ID Long block ID + Flags Short info bytes + BSize Short uncompressed block size + Reserved Long (reserved) + (var.) variable compressed VMS file-attributes block + + The block ID is one of the following unterminated strings: + + "VFAB" struct FAB + "VALL" struct XABALL + "VFHC" struct XABFHC + "VDAT" struct XABDAT + "VRDT" struct XABRDT + "VPRO" struct XABPRO + "VKEY" struct XABKEY + "VMSV" version (e.g., "V6.1"; truncated at hyphen) + "VNAM" reserved + + The lower three bits of Flags indicate the compression method. The + currently defined methods are: + + 0 stored (not compressed) + 1 simple "RLE" + 2 deflated + + The "RLE" method simply replaces zero-valued bytes with zero-valued + bits and non-zero-valued bytes with a "1" bit followed by the byte + value. + + The variable-length compressed data contains only the data corre- + sponding to the indicated structure or string. Typically multiple + VMS2 extra fields are present (each with a unique block type). + + + -Info-ZIP Macintosh Extra Field: + ============================== + + The following is the layout of the (old) Info-ZIP resource-fork extra + block for Macintosh. The local-header and central-header versions + are identical. (Last Revision 19960922) + + Value Size Description + ----- ---- ----------- + (Mac) 0x07c8 Short tag for this extra block type + TSize Short total data size for this block + "JLEE" beLong extra-field signature + FInfo 16 bytes Macintosh FInfo structure + CrDat beLong HParamBlockRec fileParam.ioFlCrDat + MdDat beLong HParamBlockRec fileParam.ioFlMdDat + Flags beLong info bits + DirID beLong HParamBlockRec fileParam.ioDirID + VolName 28 bytes volume name (optional) + + All fields but the first two are in native Macintosh format + (big-endian Motorola order, not little-endian Intel). The least + significant bit of Flags is 1 if the file is a data fork, 0 other- + wise. In addition, if this extra field is present, the filename + has an extra 'd' or 'r' appended to indicate data fork or resource + fork. The 28-byte VolName field may be omitted. + + + -ZipIt Macintosh Extra Field (long): + ================================== + + The following is the layout of the ZipIt extra block for Macintosh. + The local-header and central-header versions are identical. + (Last Revision 19970130) + + Value Size Description + ----- ---- ----------- + (Mac2) 0x2605 Short tag for this extra block type + TSize Short total data size for this block + "ZPIT" beLong extra-field signature + FnLen Byte length of FileName + FileName variable full Macintosh filename + FileType Byte[4] four-byte Mac file type string + Creator Byte[4] four-byte Mac creator string + + + -ZipIt Macintosh Extra Field (short): + =================================== + + The following is the layout of a shortened variant of the + ZipIt extra block for Macintosh (without "full name" entry). + This variant is used by ZipIt 1.3.5 and newer for entries that + do not need a "full Mac filename" record. + The local-header and central-header versions are identical. + (Last Revision 19980903) + + Value Size Description + ----- ---- ----------- + (Mac2b) 0x2705 Short tag for this extra block type + TSize Short total data size for this block (12) + "ZPIT" beLong extra-field signature + FileType Byte[4] four-byte Mac file type string + Creator Byte[4] four-byte Mac creator string + + + -Info-ZIP Macintosh Extra Field (new): + ==================================== + + The following is the layout of the (new) Info-ZIP extra + block for Macintosh, designed by Dirk Haase. + All values are in little-endian. + (Last Revision 19981005) + + Local-header version: + + Value Size Description + ----- ---- ----------- + (Mac3) 0x334d Short tag for this extra block type ("M3") + TSize Short total data size for this block + BSize Long uncompressed finder attribute data size + Flags Short info bits + fdType Byte[4] Type of the File (4-byte string) + fdCreator Byte[4] Creator of the File (4-byte string) + (CType) Short compression type + (CRC) Long CRC value for uncompressed MacOS data + Attribs variable finder attribute data (see below) + + + Central-header version: + + Value Size Description + ----- ---- ----------- + (Mac3) 0x334d Short tag for this extra block type ("M3") + TSize Short total data size for this block + BSize Long uncompressed finder attribute data size + Flags Short info bits + fdType Byte[4] Type of the File (4-byte string) + fdCreator Byte[4] Creator of the File (4-byte string) + + The third bit of Flags in both headers indicates whether + the LOCAL extra field is uncompressed (and therefore whether CType + and CRC are omitted): + + Bits of the Flags: + bit 0 if set, file is a data fork; otherwise unset + bit 1 if set, filename will be not changed + bit 2 if set, Attribs is uncompressed (no CType, CRC) + bit 3 if set, date and times are in 64 bit + if zero date and times are in 32 bit. + bit 4 if set, timezone offsets fields for the native + Mac times are omitted (UTC support deactivated) + bits 5-15 reserved; + + + Attributes: + + Attribs is a Mac-specific block of data in little-endian format with + the following structure (if compressed, uncompress it first): + + Value Size Description + ----- ---- ----------- + fdFlags Short Finder Flags + fdLocation.v Short Finder Icon Location + fdLocation.h Short Finder Icon Location + fdFldr Short Folder containing file + + FXInfo 16 bytes Macintosh FXInfo structure + FXInfo-Structure: + fdIconID Short + fdUnused[3] Short unused but reserved 6 bytes + fdScript Byte Script flag and number + fdXFlags Byte More flag bits + fdComment Short Comment ID + fdPutAway Long Home Dir ID + + FVersNum Byte file version number + may be not used by MacOS + ACUser Byte directory access rights + + FlCrDat ULong date and time of creation + FlMdDat ULong date and time of last modification + FlBkDat ULong date and time of last backup + These time numbers are original Mac FileTime values (local time!). + Currently, date-time width is 32-bit, but future version may + support be 64-bit times (see flags) + + CrGMTOffs Long(signed!) difference "local Creat. time - UTC" + MdGMTOffs Long(signed!) difference "local Modif. time - UTC" + BkGMTOffs Long(signed!) difference "local Backup time - UTC" + These "local time - UTC" differences (stored in seconds) may be + used to support timestamp adjustment after inter-timezone transfer. + These fields are optional; bit 4 of the flags word controls their + presence. + + Charset Short TextEncodingBase (Charset) + valid for the following two fields + + FullPath variable Path of the current file. + Zero terminated string (C-String) + Currently coded in the native Charset. + + Comment variable Finder Comment of the current file. + Zero terminated string (C-String) + Currently coded in the native Charset. + + + -SmartZIP Macintosh Extra Field: + ==================================== + + The following is the layout of the SmartZIP extra + block for Macintosh, designed by Marco Bambini. + + Local-header version: + + Value Size Description + ----- ---- ----------- + 0x4d63 Short tag for this extra block type ("cM") + TSize Short total data size for this block (64) + "dZip" beLong extra-field signature + fdType Byte[4] Type of the File (4-byte string) + fdCreator Byte[4] Creator of the File (4-byte string) + fdFlags beShort Finder Flags + fdLocation.v beShort Finder Icon Location + fdLocation.h beShort Finder Icon Location + fdFldr beShort Folder containing file + CrDat beLong HParamBlockRec fileParam.ioFlCrDat + MdDat beLong HParamBlockRec fileParam.ioFlMdDat + frScroll.v Byte vertical pos. of folder's scroll bar + fdScript Byte Script flag and number + frScroll.h Byte horizontal pos. of folder's scroll bar + fdXFlags Byte More flag bits + FileName Byte[32] full Macintosh filename (pascal string) + + All fields but the first two are in native Macintosh format + (big-endian Motorola order, not little-endian Intel). + The extra field size is fixed to 64 bytes. + The local-header and central-header versions are identical. + + + -Acorn SparkFS Extra Field: + ========================= + + The following is the layout of David Pilling's SparkFS extra block + for Acorn RISC OS. The local-header and central-header versions are + identical. (Last Revision 19960922) + + Value Size Description + ----- ---- ----------- + (Acorn) 0x4341 Short tag for this extra block type ("AC") + TSize Short total data size for this block (20) + "ARC0" Long extra-field signature + LoadAddr Long load address or file type + ExecAddr Long exec address + Attr Long file permissions + Zero Long reserved; always zero + + The following bits of Attr are associated with the given file + permissions: + + bit 0 user-writable ('W') + bit 1 user-readable ('R') + bit 2 reserved + bit 3 locked ('L') + bit 4 publicly writable ('w') + bit 5 publicly readable ('r') + bit 6 reserved + bit 7 reserved + + + -VM/CMS Extra Field: + ================== + + The following is the layout of the file-attributes extra block for + VM/CMS. The local-header and central-header versions are + identical. (Last Revision 19960922) + + Value Size Description + ----- ---- ----------- + (VM/CMS) 0x4704 Short tag for this extra block type + TSize Short total data size for this block + flData variable file attributes data + + flData is an uncompressed fldata_t struct. + + + -MVS Extra Field: + =============== + + The following is the layout of the file-attributes extra block for + MVS. The local-header and central-header versions are identical. + (Last Revision 19960922) + + Value Size Description + ----- ---- ----------- + (MVS) 0x470f Short tag for this extra block type + TSize Short total data size for this block + flData variable file attributes data + + flData is an uncompressed fldata_t struct. + + + -PKWARE Unix Extra Field: + ======================== + + The following is the layout of PKWARE's Unix "extra" block. + It was introduced with the release of PKZIP for Unix 2.50. + Note: all fields are stored in Intel low-byte/high-byte order. + (Last Revision 19980901) + + This field has a minimum data size of 12 bytes and is only stored + as local extra field. + + Value Size Description + ----- ---- ----------- + (Unix0) 0x000d Short Tag for this "extra" block type + TSize Short Total Data Size for this block + AcTime Long time of last access (UTC/GMT) + ModTime Long time of last modification (UTC/GMT) + UID Short Unix user ID + GID Short Unix group ID + (var) variable Variable length data field + + The variable length data field will contain file type + specific data. Currently the only values allowed are + the original "linked to" file names for hard or symbolic + links, and the major and minor device node numbers for + character and block device nodes. Since device nodes + cannot be either symbolic or hard links, only one set of + variable length data is stored. Link files will have the + name of the original file stored. This name is NOT NULL + terminated. Its size can be determined by checking TSize - + 12. Device entries will have eight bytes stored as two 4 + byte entries (in little-endian format). The first entry + will be the major device number, and the second the minor + device number. + + [Info-ZIP note: The fixed part of this field has the same layout as + Info-ZIP's abandoned "Unix1 timestamps & owner ID info" extra field; + only the two tag bytes are different.] + + + -PATCH Descriptor Extra Field: + ============================ + + The following is the layout of the Patch Descriptor "extra" + block. + + Note: all fields stored in Intel low-byte/high-byte order. + + Value Size Description + ----- ---- ----------- + (Patch) 0x000f Short Tag for this "extra" block type + TSize Short Size of the total "extra" block + Version Short Version of the descriptor + Flags Long Actions and reactions (see below) + OldSize Long Size of the file about to be patched + OldCRC Long 32-bit CRC of the file about to be patched + NewSize Long Size of the resulting file + NewCRC Long 32-bit CRC of the resulting file + + + Actions and reactions + + Bits Description + ---- ---------------- + 0 Use for autodetection + 1 Treat as selfpatch + 2-3 RESERVED + 4-5 Action (see below) + 6-7 RESERVED + 8-9 Reaction (see below) to absent file + 10-11 Reaction (see below) to newer file + 12-13 Reaction (see below) to unknown file + 14-15 RESERVED + 16-31 RESERVED + + Actions + + Action Value + ------ ----- + none 0 + add 1 + delete 2 + patch 3 + + Reactions + + Reaction Value + -------- ----- + ask 0 + skip 1 + ignore 2 + fail 3 + + + -PKCS#7 Store for X.509 Certificates: + =================================== + + This field is contains the information about each + certificate a file is signed with. This field should only + appear in the first central directory record, and will be + ignored in any other record. + + Note: all fields stored in Intel low-byte/high-byte order. + + Value Size Description + ----- ---- ----------- + (Store) 0x0014 2 bytes Tag for this "extra" block type + SSize 2 bytes Size of the store data + SData (variable) Data about the store + + SData + Value Size Description + ----- ---- ----------- + Version 2 bytes Version number, 0x0001 for now + StoreD (variable) Actual store data + + The StoreD member is suitable for passing as the pbData + member of a CRYPT_DATA_BLOB to the CertOpenStore() function + in Microsoft's CryptoAPI. The SSize member above will be + cbData + 6, where cbData is the cbData member of the same + CRYPT_DATA_BLOB. The encoding type to pass to + CertOpenStore() should be + PKCS_7_ANS_ENCODING | X509_ASN_ENCODING. + + + -X.509 Certificate ID and Signature for individual file: + ====================================================== + + This field contains the information about which certificate + in the PKCS#7 Store was used to sign the particular file. + It also contains the signature data. This field can appear + multiple times, but can only appear once per certificate. + + Note: all fields stored in Intel low-byte/high-byte order. + + Value Size Description + ----- ---- ----------- + (CID) 0x0015 2 bytes Tag for this "extra" block type + CSize 2 bytes Size of Method + Method (variable) + + Method + Value Size Description + ----- ---- ----------- + Version 2 bytes Version number, for now 0x0001 + AlgID 2 bytes Algorithm ID used for signing + IDSize 2 bytes Size of Certificate ID data + CertID (variable) Certificate ID data + SigSize 2 bytes Size of Signature data + Sig (variable) Signature data + + CertID + Value Size Description + ----- ---- ----------- + Size1 4 bytes Size of CertID, should be (IDSize - 4) + Size1 4 bytes A bug in version one causes this value + to appear twice. + IssSize 4 bytes Issuer data size + Issuer (variable) Issuer data + SerSize 4 bytes Serial Number size + Serial (variable) Serial Number data + + The Issuer and IssSize members are suitable for creating a + CRYPT_DATA_BLOB to be the Issuer member of a CERT_INFO + struct. The Serial and SerSize members would be the + SerialNumber member of the same CERT_INFO struct. This + struct would be used to find the certificate in the store + the file was signed with. Those structures are from the MS + CryptoAPI. + + Sig and SigSize are the actual signature data and size + generated by signing the file with the MS CryptoAPI using a + hash created with the given AlgID. + + + -X.509 Certificate ID and Signature for central directory: + ======================================================== + + This field contains the information about which certificate + in the PKCS#7 Store was used to sign the central directory. + It should only appear with the first central directory + record, along with the store. The data structure is the + same as the CID, except that SigSize will be 0, and there + will be no Sig member. + + This field is also kept after the last central directory + record, as the signature data (ID 0x05054b50, it looks like + a central directory record of a different type). This + second copy of the data is the Signature Data member of the + record, and will have a SigSize that is non-zero, and will + have Sig data. + + Note: all fields stored in Intel low-byte/high-byte order. + + Value Size Description + ----- ---- ----------- + (CDID) 0x0016 2 bytes Tag for this "extra" block type + CSize 2 bytes Size of Method + Method (variable) + + + -ZIP64 Extended Information Extra Field: + ====================================== + + The following is the layout of the ZIP64 extended + information "extra" block. If one of the size or + offset fields in the Local or Central directory + record is too small to hold the required data, + a ZIP64 extended information record is created. + The order of the fields in the ZIP64 extended + information record is fixed, but the fields will + only appear if the corresponding Local or Central + directory record field is set to 0xFFFF or 0xFFFFFFFF. + + Note: all fields stored in Intel low-byte/high-byte order. + + Value Size Description + ----- ---- ----------- + (ZIP64) 0x0001 2 bytes Tag for this "extra" block type + Size 2 bytes Size of this "extra" block + Original + Size 8 bytes Original uncompresseed file size + Compressed + Size 8 bytes Size of compressed data + Relative Header + Offset 8 bytes Offset of local header record + Disk Start + Number 4 bytes Number of the disk on which + this file starts + + This entry in the Local header must include BOTH original + and compressed file sizes. + + + -Extended Timestamp Extra Field: + ============================== + + The following is the layout of the extended-timestamp extra block. + (Last Revision 19970118) + + Local-header version: + + Value Size Description + ----- ---- ----------- + (time) 0x5455 Short tag for this extra block type ("UT") + TSize Short total data size for this block + Flags Byte info bits + (ModTime) Long time of last modification (UTC/GMT) + (AcTime) Long time of last access (UTC/GMT) + (CrTime) Long time of original creation (UTC/GMT) + + Central-header version: + + Value Size Description + ----- ---- ----------- + (time) 0x5455 Short tag for this extra block type ("UT") + TSize Short total data size for this block + Flags Byte info bits (refers to local header!) + (ModTime) Long time of last modification (UTC/GMT) + + The central-header extra field contains the modification time only, + or no timestamp at all. TSize is used to flag its presence or + absence. But note: + + If "Flags" indicates that Modtime is present in the local header + field, it MUST be present in the central header field, too! + This correspondence is required because the modification time + value may be used to support trans-timezone freshening and + updating operations with zip archives. + + The time values are in standard Unix signed-long format, indicating + the number of seconds since 1 January 1970 00:00:00. The times + are relative to Coordinated Universal Time (UTC), also sometimes + referred to as Greenwich Mean Time (GMT). To convert to local time, + the software must know the local timezone offset from UTC/GMT. + + The lower three bits of Flags in both headers indicate which time- + stamps are present in the LOCAL extra field: + + bit 0 if set, modification time is present + bit 1 if set, access time is present + bit 2 if set, creation time is present + bits 3-7 reserved for additional timestamps; not set + + Those times that are present will appear in the order indicated, but + any combination of times may be omitted. (Creation time may be + present without access time, for example.) TSize should equal + (1 + 4*(number of set bits in Flags)), as the block is currently + defined. Other timestamps may be added in the future. + + + -Info-ZIP Unix Extra Field (type 1): + ================================== + + The following is the layout of the old Info-ZIP extra block for + Unix. It has been replaced by the extended-timestamp extra block + (0x5455) and the Unix type 2 extra block (0x7855). + (Last Revision 19970118) + + Local-header version: + + Value Size Description + ----- ---- ----------- + (Unix1) 0x5855 Short tag for this extra block type ("UX") + TSize Short total data size for this block + AcTime Long time of last access (UTC/GMT) + ModTime Long time of last modification (UTC/GMT) + UID Short Unix user ID (optional) + GID Short Unix group ID (optional) + + Central-header version: + + Value Size Description + ----- ---- ----------- + (Unix1) 0x5855 Short tag for this extra block type ("UX") + TSize Short total data size for this block + AcTime Long time of last access (GMT/UTC) + ModTime Long time of last modification (GMT/UTC) + + The file access and modification times are in standard Unix signed- + long format, indicating the number of seconds since 1 January 1970 + 00:00:00. The times are relative to Coordinated Universal Time + (UTC), also sometimes referred to as Greenwich Mean Time (GMT). To + convert to local time, the software must know the local timezone + offset from UTC/GMT. The modification time may be used by non-Unix + systems to support inter-timezone freshening and updating of zip + archives. + + The local-header extra block may optionally contain UID and GID + info for the file. The local-header TSize value is the only + indication of this. Note that Unix UIDs and GIDs are usually + specific to a particular machine, and they generally require root + access to restore. + + This extra field type is obsolete, but it has been in use since + mid-1994. Therefore future archiving software should continue to + support it. Some guidelines: + + An archive member should either contain the old "Unix1" + extra field block or the new extra field types "time" and/or + "Unix2". + + If both the old "Unix1" block type and one or both of the new + block types "time" and "Unix2" are found, the "Unix1" block + should be considered invalid and ignored. + + Unarchiving software should recognize both old and new extra + field block types, but the info from new types overrides the + old "Unix1" field. + + Archiving software should recognize "Unix1" extra fields for + timestamp comparison but never create it for updated, freshened + or new archive members. When copying existing members to a new + archive, any "Unix1" extra field blocks should be converted to + the new "time" and/or "Unix2" types. + + + -Info-ZIP Unix Extra Field (type 2): + ================================== + + The following is the layout of the new Info-ZIP extra block for + Unix. (Last Revision 19960922) + + Local-header version: + + Value Size Description + ----- ---- ----------- + (Unix2) 0x7855 Short tag for this extra block type ("Ux") + TSize Short total data size for this block (4) + UID Short Unix user ID + GID Short Unix group ID + + Central-header version: + + Value Size Description + ----- ---- ----------- + (Unix2) 0x7855 Short tag for this extra block type ("Ux") + TSize Short total data size for this block (0) + + The data size of the central-header version is zero; it is used + solely as a flag that UID/GID info is present in the local-header + extra field. If additional fields are ever added to the local + version, the central version may be extended to indicate this. + + Note that Unix UIDs and GIDs are usually specific to a particular + machine, and they generally require root access to restore. + + + -ASi Unix Extra Field: + ==================== + + The following is the layout of the ASi extra block for Unix. The + local-header and central-header versions are identical. + (Last Revision 19960916) + + Value Size Description + ----- ---- ----------- + (Unix3) 0x756e Short tag for this extra block type ("nu") + TSize Short total data size for this block + CRC Long CRC-32 of the remaining data + Mode Short file permissions + SizDev Long symlink'd size OR major/minor dev num + UID Short user ID + GID Short group ID + (var.) variable symbolic link filename + + Mode is the standard Unix st_mode field from struct stat, containing + user/group/other permissions, setuid/setgid and symlink info, etc. + + If Mode indicates that this file is a symbolic link, SizDev is the + size of the file to which the link points. Otherwise, if the file + is a device, SizDev contains the standard Unix st_rdev field from + struct stat (includes the major and minor numbers of the device). + SizDev is undefined in other cases. + + If Mode indicates that the file is a symbolic link, the final field + will be the name of the file to which the link points. The file- + name length can be inferred from TSize. + + [Note that TSize may incorrectly refer to the data size not counting + the CRC; i.e., it may be four bytes too small.] + + + -BeOS Extra Field: + ================ + + The following is the layout of the file-attributes extra block for + BeOS. (Last Revision 19970531) + + Local-header version: + + Value Size Description + ----- ---- ----------- + (BeOS) 0x6542 Short tag for this extra block type ("Be") + TSize Short total data size for this block + BSize Long uncompressed file attribute data size + Flags Byte info bits + (CType) Short compression type + (CRC) Long CRC value for uncompressed file attribs + Attribs variable file attribute data + + Central-header version: + + Value Size Description + ----- ---- ----------- + (BeOS) 0x6542 Short tag for this extra block type ("Be") + TSize Short total data size for this block (5) + BSize Long size of uncompr. local EF block data + Flags Byte info bits + + The least significant bit of Flags in both headers indicates whether + the LOCAL extra field is uncompressed (and therefore whether CType + and CRC are omitted): + + bit 0 if set, Attribs is uncompressed (no CType, CRC) + bits 1-7 reserved; if set, assume error or unknown data + + Currently the only supported compression types are deflated (type 8) + and stored (type 0); the latter is not used by Info-ZIP's Zip but is + supported by UnZip. + + Attribs is a BeOS-specific block of data in big-endian format with + the following structure (if compressed, uncompress it first): + + Value Size Description + ----- ---- ----------- + Name variable attribute name (null-terminated string) + Type Long attribute type (32-bit unsigned integer) + Size Long Long data size for this sub-block (64 bits) + Data variable attribute data + + The attribute structure is repeated for every attribute. The Data + field may contain anything--text, flags, bitmaps, etc. + + + -SMS/QDOS Extra Field: + ==================== + + The following is the layout of the file-attributes extra block for + SMS/QDOS. The local-header and central-header versions are identical. + (Last Revision 19960929) + + Value Size Description + ----- ---- ----------- + (QDOS) 0xfb4a Short tag for this extra block type + TSize Short total data size for this block + LongID Long extra-field signature + (ExtraID) Long additional signature/flag bytes + QDirect 64 bytes qdirect structure + + LongID may be "QZHD" or "QDOS". In the latter case, ExtraID will + be present. Its first three bytes are "02\0"; the last byte is + currently undefined. + + QDirect contains the file's uncompressed directory info (qdirect + struct). Its elements are in native (big-endian) format: + + d_length beLong file length + d_access byte file access type + d_type byte file type + d_datalen beLong data length + d_reserved beLong unused + d_szname beShort size of filename + d_name 36 bytes filename + d_update beLong time of last update + d_refdate beLong file version number + d_backup beLong time of last backup (archive date) + + + -AOS/VS Extra Field: + ================== + + The following is the layout of the extra block for Data General + AOS/VS. The local-header and central-header versions are identical. + (Last Revision 19961125) + + Value Size Description + ----- ---- ----------- + (AOSVS) 0x5356 Short tag for this extra block type ("VS") + TSize Short total data size for this block + "FCI\0" Long extra-field signature + Version Byte version of AOS/VS extra block (10 = 1.0) + Fstat variable fstat packet + AclBuf variable raw ACL data ($MXACL bytes) + + Fstat contains the file's uncompressed fstat packet, which is one of + the following: + + normal fstat packet (P_FSTAT struct) + DIR/CPD fstat packet (P_FSTAT_DIR struct) + unit (device) fstat packet (P_FSTAT_UNIT struct) + IPC file fstat packet (P_FSTAT_IPC struct) + + AclBuf contains the raw ACL data; its length is $MXACL. + + + -Tandem NSK Extra Field: + ====================== + + The following is the layout of the file-attributes extra block for + Tandem NSK. The local-header and central-header versions are + identical. (Last Revision 19981221) + + Value Size Description + ----- ---- ----------- + (TA) 0x4154 Short tag for this extra block type ("TA") + TSize Short total data size for this block (20) + NSKattrs 20 Bytes NSK attributes + + + -THEOS Extra Field: + ================= + + The following is the layout of the file-attributes extra block for + Theos. The local-header and central-header versions are identical. + (Last Revision 19990206) + + Value Size Description + ----- ---- ----------- + (Theos) 0x6854 Short 'Th' signature + size Short size of extra block + flags Byte reserved for future use + filesize Long file size + fileorg Byte type of file (see below) + keylen Short key length for indexed and keyed files, + data segment size for 16 bits programs + reclen Short record length for indexed,keyed and direct, + text segment size for 16 bits programs + filegrow Byte growing factor for indexed,keyed and direct + protect Byte protections (see below) + reserved Short reserved for future use + + File types + ========== + + 0x80 library (keyed access list of files) + 0x40 directory + 0x10 stream file + 0x08 direct file + 0x04 keyed file + 0x02 indexed file + 0x0e reserved + 0x01 16 bits real mode program (obsolete) + 0x21 16 bits protected mode program + 0x41 32 bits protected mode program + + Protection codes + ================ + + User protection + --------------- + 0x01 non readable + 0x02 non writable + 0x04 non executable + 0x08 non erasable + + Other protection + ---------------- + 0x10 non readable + 0x20 non writable + 0x40 non executable Theos before 4.0 + 0x40 modified Theos 4.x + 0x80 not hidden + + + -THEOS old inofficial Extra Field: + ================================ + + The following is the layout of an inoffical former version of a + Theos file-attributes extra blocks. This layout was never published + and is no longer created. However, UnZip can optionally support it + when compiling with the option flag OLD_THEOS_EXTRA defined. + Both the local-header and central-header versions are identical. + (Last Revision 19990206) + + Value Size Description + ----- ---- ----------- + (THS0) 0x4854 Short 'TH' signature + size Short size of extra block + flags Short reserved for future use + filesize Long file size + reclen Short record length for indexed,keyed and direct, + text segment size for 16 bits programs + keylen Short key length for indexed and keyed files, + data segment size for 16 bits programs + filegrow Byte growing factor for indexed,keyed and direct + reserved 3 Bytes reserved for future use + + + -FWKCS MD5 Extra Field: + ===================== + + The FWKCS Contents_Signature System, used in automatically + identifying files independent of filename, optionally adds + and uses an extra field to support the rapid creation of + an enhanced contents_signature. + There is no local-header version; the following applies + only to the central header. (Last Revision 19961207) + + Central-header version: + + Value Size Description + ----- ---- ----------- + (MD5) 0x4b46 Short tag for this extra block type ("FK") + TSize Short total data size for this block (19) + "MD5" 3 bytes extra-field signature + MD5hash 16 bytes 128-bit MD5 hash of uncompressed data + (low byte first) + + When FWKCS revises a .ZIP file central directory to add + this extra field for a file, it also replaces the + central directory entry for that file's uncompressed + file length with a measured value. + + FWKCS provides an option to strip this extra field, if + present, from a .ZIP file central directory. In adding + this extra field, FWKCS preserves .ZIP file Authenticity + Verification; if stripping this extra field, FWKCS + preserves all versions of AV through PKZIP version 2.04g. + + FWKCS, and FWKCS Contents_Signature System, are + trademarks of Frederick W. Kantor. + + (1) R. Rivest, RFC1321.TXT, MIT Laboratory for Computer + Science and RSA Data Security, Inc., April 1992. + ll.76-77: "The MD5 algorithm is being placed in the + public domain for review and possible adoption as a + standard." + + + -Info-ZIP Unicode Path Extra Field: + ================================= + + Stores the UTF-8 version of the entry path as stored in the + local header and central directory header. + (Last Revision 20070912) + + Value Size Description + ----- ---- ----------- + (UPath) 0x7075 Short tag for this extra block type ("up") + TSize Short total data size for this block + Version 1 byte version of this extra field, currently 1 + NameCRC32 4 bytes File Name Field CRC32 Checksum + UnicodeName Variable UTF-8 version of the entry File Name + + Currently Version is set to the number 1. If there is a need + to change this field, the version will be incremented. Changes + may not be backward compatible so this extra field should not be + used if the version is not recognized. + + The NameCRC32 is the standard zip CRC32 checksum of the File Name + field in the header. This is used to verify that the header + File Name field has not changed since the Unicode Path extra field + was created. This can happen if a utility renames the entry but + does not update the UTF-8 path extra field. If the CRC check fails, + this UTF-8 Path Extra Field should be ignored and the File Name field + in the header used instead. + + The UnicodeName is the UTF-8 version of the contents of the File Name + field in the header. As UnicodeName is defined to be UTF-8, no UTF-8 + byte order mark (BOM) is used. The length of this field is determined + by subtracting the size of the previous fields from TSize. If both + the File Name and Comment fields are UTF-8, the new General Purpose + Bit Flag, bit 11 (Language encoding flag (EFS)), can be used to + indicate that both the header File Name and Comment fields are UTF-8 + and, in this case, the Unicode Path and Unicode Comment extra fields + are not needed and should not be created. Note that, for backward + compatibility, bit 11 should only be used if the native character set + of the paths and comments being zipped up are already in UTF-8. The + same method, either bit 11 or extra fields, should be used in both + the local and central directory headers. + + + -Info-ZIP Unicode Comment Extra Field: + ==================================== + + Stores the UTF-8 version of the entry comment as stored in the + central directory header. + (Last Revision 20070912) + + Value Size Description + ----- ---- ----------- + (UCom) 0x6375 Short tag for this extra block type ("uc") + TSize Short total data size for this block + Version 1 byte version of this extra field, currently 1 + ComCRC32 4 bytes Comment Field CRC32 Checksum + UnicodeCom Variable UTF-8 version of the entry comment + + Currently Version is set to the number 1. If there is a need + to change this field, the version will be incremented. Changes + may not be backward compatible so this extra field should not be + used if the version is not recognized. + + The ComCRC32 is the standard zip CRC32 checksum of the Comment + field in the central directory header. This is used to verify that + the comment field has not changed since the Unicode Comment extra field + was created. This can happen if a utility changes the Comment field + but does not update the UTF-8 Comment extra field. If the CRC check + fails, this Unicode Comment extra field should be ignored and the + Comment field in the header used. + + The UnicodeCom field is the UTF-8 version of the entry comment field + in the header. As UnicodeCom is defined to be UTF-8, no UTF-8 byte + order mark (BOM) is used. The length of this field is determined by + subtracting the size of the previous fields from TSize. If both the + File Name and Comment fields are UTF-8, the new General Purpose Bit + Flag, bit 11 (Language encoding flag (EFS)), can be used to indicate + both the header File Name and Comment fields are UTF-8 and, in this + case, the Unicode Path and Unicode Comment extra fields are not + needed and should not be created. Note that, for backward + compatibility, bit 11 should only be used if the native character set + of the paths and comments being zipped up are already in UTF-8. The + same method, either bit 11 or extra fields, should be used in both + the local and central directory headers. + + + -Info-ZIP New Unix Extra Field: + ==================================== + + Currently stores Unix UIDs/GIDs up to 32 bits. + (Last Revision 20080509) + + Value Size Description + ----- ---- ----------- + (UnixN) 0x7875 Short tag for this extra block type ("ux") + TSize Short total data size for this block + Version 1 byte version of this extra field, currently 1 + UIDSize 1 byte Size of UID field + UID Variable UID for this entry + GIDSize 1 byte Size of GID field + GID Variable GID for this entry + + Currently Version is set to the number 1. If there is a need + to change this field, the version will be incremented. Changes + may not be backward compatible so this extra field should not be + used if the version is not recognized. + + UIDSize is the size of the UID field in bytes. This size should + match the size of the UID field on the target OS. + + UID is the UID for this entry in standard little endian format. + + GIDSize is the size of the GID field in bytes. This size should + match the size of the GID field on the target OS. + + GID is the GID for this entry in standard little endian format. + + If both the old 16-bit Unix extra field (tag 0x7855, Info-ZIP Unix) + and this extra field are present, the values in this extra field + supercede the values in that extra field. diff --git a/proginfo/fileinfo.cms b/proginfo/fileinfo.cms new file mode 100644 index 0000000..9d21935 --- /dev/null +++ b/proginfo/fileinfo.cms @@ -0,0 +1,231 @@ +[Quoting from a C/370 manual, courtesy of Carl Forde.] + + C/370 supports three types of input and output: text streams, binary + streams, and record I/O. Text and binary streams are both ANSI + standards; record I/O is a C/370 extension. + +[...] + + Record I/O is a C/370 extension to the ANSI standard. For files + opened in record format, C/370 reads and writes one record at a + time. If you try to write more data to a record than the record + can hold, the data is truncated. For record I/O, C/370 only allows + the use of fread() and fwrite() to read and write to the files. Any + other functions (such as fprintf(), fscanf(), getc(), and putc()) + fail. For record-orientated files, records do not change size when + you update them. If the new data has fewer characters than the + original record, the new data fills the first n characters, where + n is the number of characters of the new data. The record will + remain the same size, and the old characters (those after) n are + left unchanged. A subsequent update begins at the next boundary. + For example, if you have the string "abcdefgh": + + abcdefgh + + and you overwrite it with the string "1234", the record will look + like this: + + 1234efgh + + C/370 record I/O is binary. That is, it does not interpret any of + the data in a record file and therefore does not recognize control + characters. + + + The record model consists of: + + * A record, which is the unit of data transmitted to and from a + program + * A block, which is the unit of data transmitted to and from a + device. Each block may contain one or more records. + + In the record model of I/O, records and blocks have the following + attributes: + + RECFM Specifies the format of the data or how the data is organized + on the physical device. + LRECL Specifies the length of logical records (as opposed to + physical ones). + + BLKSIZE Specifies the length of physical records (blocks on the + physical device). + + + Opening a File by Filename + + The filename that you specify on the call to fopen() or freopen() + must be in the following format: + + >> ----filename---- ----filetype-------------------- + | | | | + --.-- -- --filemode-- + | | + --.-- + where + + filename is a 1- to 8-character string of any of the characters, + A-Z, a-z, 0-9, and +, -, $, #, @, :, and _. You can separate it + from the filetype with one or more spaces, or with a period. + [Further note: filenames are fully case-sensitive, as in Unix.] + + filetype is a 1- to 8-character string of any of the characters, + A-Z, a-z, 0-9, and +, -, $, #, @, :, and _. You can separate it + from the filemode with one or more spaces, or with a period. The + separator between filetype and filemode must be the same as the + one between filename and filetype. + + filemode is a 1- to 2-character string. The first must be any of + the characters A-Z, a-z, or *. If you use the asis parameter on + the fopen() or freopen() call, the first character of the filemode + must be a capital letter or an asterisk. Otherwise, the function + call fails. The second character of filemode is optional; if you + specify it, it must be any of the digits 0-6. You cannot specify + the second character if you have specified * for the first one. + + If you do not use periods as separators, there is no limit to how + much whitespace you can have before and after the filename, the + filetype, and filemode. + + + Opening a File without a File Mode Specified + + If you omit the file mode or specify * for it, C/370 does one + of the following when you call fopen() or freopen(): + + * If you have specified a read mode, C/370 looks for the named file + on all the accessed readable disks, in order. If it does not find + the file, the fopen() or freopen() call fails. + * If you have specified any of the write modes, C/370 writes the file + on the first writable disk you have accessed. Specifying a write + mode on an fopen() or freopen() call that contains the filename of + an existing file destroys that file. If you do not have any + writable disks accessed, the call fails. + + + fopen() and freopen() parameters + + recfm + CMS supports only two RECFMs, V and F. [note that MVS supports + 27(!) different RECFMs.] If you do not specify the RECFM for a + file, C/370 determines whether is is in fixed or variable format. + + lrecl and blksize + For files in fixed format, CMS allows records to be read and + written in blocks. To have a fixed format CMS file treated as a + fixed blocked CMS file, you can open the file with recfm=fb and + specify the lrecl and blksize. If you do not specify a recfm on + the open, the blksize can be a multiple of the lrecl, and the + file is treated as if it were blocked. + + For files in variable format, the CMS LRECL is different from the + LRECL for the record model. In the record model, the LRECL is + equal to the data length plus 4 bytes (for the record descriptor + word), and the BLKSIZE is equal to the LRECL plus 4 bytes (for + the block descriptor word). In CMS, BDWs and RDWs do not exist, + but because CMS follows the record model, you must still account + for them. When you specify V, you must still allocate the record + descriptor word and block descriptor word. That is, if you want + a maximum of n bytes per record, you must specify a minimum LRECL + of n+4 and a minimum BLKSIZE of n+8. + + When you are appending to V files, you can enlarge the record size + dynamically, but only if you have not specified LRECL or BLKSIZE + on the fopen() or freopen() command that opened the file. + + type + If you specify this parameter, the only valid value for CMS disk + files is type =record. This opens a file for record I/O. + + asis + If you use this parameter, you can open files with mixed-case + filenames such as JaMeS dAtA or pErCy.FILE. If you specify this + parameter, the file mode that you specify must be a capital letter + (if it is not an asterisk); otherwise; the function call fails and + the value returned is NULL. + + + Reading from Record I/O Files + fread() is the only interface allowed for reading record I/O files. + Each time you call fread() for a record I/O file, fread() reads + one record from the system. If you call fread() with a request for + less than a complete record, the requested bytes are copied to your + buffer, and the file position is set to the start fo the next + record. If the request is for more bytes that are in the record, + one record is read and the position is set to the start of the next + record. C/370 does not strip any blank characters or interpret any + data. + + fread() returns the number of items read successfully, so if you + pass a size argument equal to 1 and a count argument equal to the + maximum expected length of the record, fread() returns the length, + in bytes, of the record read. If you pass a size argument equal + to the maximum expected length of the record, and a count argument + equal to 1, fread() returns either 0 or 1, indicating whether a + record of length size read. If a record is read successfully but + is less than size bytes long, fread() returns 0. + + + Writing to Record I/O Files + fwrite() is the only interface allowed for writing to a file + opened for record I/O. Only one record is written at a time. If + you attempt to write more new data than a full record can hold or + try to update a record with more data than it currently has, C/370 + truncates your output at the record boundary. When C/370 performs + a truncation, it sets errno and raises SIGIOERR, if SIGIOERR is not + set to SIG_IGN. + + When you are writing new records to a fixed-record I/O file, if you + try to write a short record, C/370 pads the record with nulls out + to LRECL. + + At the completion of an fwrite(), the file position is at the start + of the next record. For new data, the block is flushed out to the + system as soon as it is full. + + + fldata() Behavior + When you call the fldata() function for an open CMS minidisk file, + it returns a data structure that looks like this: + + struct __filedata { + unsigned int __recfmF : 1, /* fixed length records */ + __recfmV : 1, /* variable length records */ + __recfmU : 1, /* n/a */ + __recfmS : 1, /* n/a */ + __recfmBlk : 1, /* n/a */ + __recfmASA : 1, /* text mode and ASA */ + __recfmM : 1, /* n/a */ + __dsorgPO : 1, /* n/a */ + __dsorgPDSmem : 1, /* n/a */ + __dsorgPDSdir : 1, /* n/a */ + __dsorgPS : 1, /* sequential data set */ + __dsorgConcat : 1, /* n/a */ + __dsorgMem : 1, /* n/a */ + __dsorgHiper : 1, /* n/a */ + __dsorgTemp : 1, /* created with tmpfile() */ + __dsorgVSAM : 1, /* n/a */ + __reserve1 : 1, /* n/a */ + __openmode : 2, /* see below 1 */ + __modeflag : 4, /* see below 2 */ + __reserve2 : 9, /* n/a */ + + char __device; __DISK + unsigned long __blksize, /* see below 3 */ + __maxreclen; /* see below 4 */ + unsigned short __vsamtype; /* n/a */ + unsigned long __vsamkeylen; /* n/a */ + unsigned long __vsamRKP; /* n/a */ + char * __dsname; /* fname ftype fmode */ + unsigned int __reserve4; /* n/a */ + + /* note 1: values are: __TEXT, __BINARY, __RECORD + note 2: values are: __READ, __WRITE, __APPEND, __UPDATE + these values can be added together to determine + the return value; for example, a file opened with + a+ will have the value __READ + __APPEND. + note 3: total block size of the file, including ASA + characters as well as RDW information + note 4: maximum record length of the data only (includes + ASA characters but excludes RDW information). + */ + }; diff --git a/proginfo/infozip.who b/proginfo/infozip.who new file mode 100644 index 0000000..994851c --- /dev/null +++ b/proginfo/infozip.who @@ -0,0 +1,242 @@ +These members of the Info-ZIP group contributed to the development and +testing of portable Zip. They are responsible for whatever works in +Zip. Whatever doesn't work is solely the fault of the authors of Zip +(Mark Adler, Rich Wales, Jean-loup Gailly, Kai Uwe Rommel, Igor Mandrichenko, +Onno van der Linden, Christian Spieler, John Bush, Paul Kienitz, Sergio Monesi +and Karl Davis, but see the license for the latest list). If you have +contributed and your name has been forgotten, please send a reminder to us +using the contact information in the Readme file. The names are given here +in alphabetical order, because it's impossible to classify them by importance +of the contribution. Some have made a complete port to a new target, some +have provided a one line fix. All are to be thanked. + + +Mark Adler madler@tybalt.caltech.edu NeXT 2.x, Mac + alan@spri.levels.unisa.edu.au Linux +Jeffrey Altman jaltman@watsun.cc.columbia.edu fseek bug on NT +Glenn J. Andrews oper1%drcv06.decnet@drcvax.af.mil VAX VMS +James Van Artsdalen james@raid.dell.com bug report +Eric Backus ericb@lsid.hp.com bug report +Quentin Barnes qbarnes@urbana.css.mot.com unix/Makefile mode of + installed files +Elmar Bartel bartel@informatik.tu-muenchen.de +Mark E. Becker mbecker@cs.uml.edu bug report +Paul von Behren Paul_von_Behren@stortek.com OS/390 port +Jon Bell swy@wsdot.wa.gov Intergraph/CLIX +Myles Bennett - Initial UnZip 6.0 large + files beta +Michael Bernardi mike@childsoc.demon.co.uk RS6000 +Tom Betz marob!upaya!tbetz@phri.nyu.edu SCO Xenix 2.3.1 +James Birdsall jwbirdsa@picarefy.com AT&T 3B1 +George boer@fwi.uva.nl OS/2 +Michael Bolton bolton@vaxc.erim.org VAX/VMS +Wim Bonner 27313853@WSUVM1.CSC.WSU.EDU HP 9000/840a HPUX +Paul Borman prb@cray.com Cray-X/YMP,2 UNICOS 6-8 +Kurt Van den Branden kvd2@bipsy.se.bel.alcatel.be VAX VMS +Scott Briggs briggs@nashua.progress.com Windows NT +Leslie C. Brown lbrown@BRL.MIL Pyramid MIS-4 +Ralf Brown ralf@b.gp.cs.cmu.edu Pyramid MIS-4 +Rodney Brown rdb@cmutual.com.au SunOS 4.1.3 DGUX OSF/1 + HP-UX CRC optimization +Jeremy Daniel Buhler jbuhler@owlnet.rice.edu BC++ +John Bush john.bush@east.sun.com Amiga (SAS/C) +Pietro Caselli zaphod@petruz.sublink.org Minix 1.5.10 +Andrew A. Chernov ache@astral.msk.su FreeBSD +Jeff Coffler jeffcof@microsoft.com Windows NT +David Dachtera David.Dachtera@advocatehealth.com VMS + link_zip.com bug +Bill Davidsen davidsen@crdos1.crd.ge.com Xenix (on what?) +Karl Davis riscman@geko.com.au Acorn +Daniel Deimert daniel@pkmab.se zeus3.21 Zilog S8000 +David Denholm denholm@sotona.physics.southampton.ac.uk VMS +Harald Denker harry@hal.westfalen.de ATARI +Matthew J. D'Errico doc@magna.com Bull +L. Peter Deutsch ghost@aladdin.com Linux +Uwe Doering gemini@geminix.in-berlin.de 386 Unix +Jean-Michel Dubois jmdubois@ibcfrance.fr Theos support +James P. Dugal jpd@usl.edu Pyramid 90X OSx4.1 +"Evil Ed" esaffle@gmuvax2.gmu.edu Ultrix-32 V3.1 (Rev. 9) +Patrick Ellis pellis@aic.mdc.com VMS zip -h appearance +Thomas Esken esken@uni-muenster.de Acorn fix +Dwight Estep estep@dlo10.enet.dec.com MSDOS +David A. Feinleib t-davefe@microsoft.com Windows NT +Joshua Felsteiner joshua@phys1.technion.ac.il Linux +Greg Flint afc@klaatu.cc.purdue.edu ETA-10P* hybrid Sys V +Carl Forde cforde@bcsc02.gov.bc.ca VM/CMS +Jeff Foy jfoy@glia.biostr.washington.edu IRIX Sys V Rel 3.3.1 +Mike Freeman mikef@pacifier.com Vax VMS +Kevin M. Fritz kmfritz@apgea.army.mil Turbo C++ 1.0 + Pyramid +Jean-loup Gailly jloup@chorus.fr MS-DOS Microsoft C 5.1 +Scott D. Galloway sgallowa@letterkenn-emh1.army.mil Sperry 5000 SysV.3 +Rainer Gerling gerling@faupt101.physik.uni-erlangen.de HPUX, MSDOS +Henry Gessau henryg@kullmar.kullmar.se Windows NT +Ed Gordon - Zip 3.0, VB, Unicode, + large files, splits, DLLs +Ian E. Gorman ian@iosphere.net ported zip 2.2 to VM/CMS +Wayne R. Graves graves@csa2.lbl.gov Vax VMS +George Grimes grimes@netcom.com Apollo Domain SR10.4 +Hunter Goatley goathunter@MadGoat.com VMS (VAX & Alpha), + web and ftp sites +Arnt Gulbrandsen agulbra@pvv.unit.no Linux +David Gundlach david@rolf.stat.uga.edu Sun SS1+ SunOS 4.1 +Peter Gutmann pgut1@cs.aukuni.ac.nz bug report +Dirk Haase d_haase@sitec.de MacOS port +Mark Hanning-Lee markhl@iris-355.jpl.nasa.gov SGI +Walter Haidinger e9225662@student.tuwien.ac.at Amiga and general fixes +Charles Hannum mycroft@ai.mit.edu bug report +Greg Hartwig ghartwig@ix.netcom.com VM/CMS cleanup +Tanvir Hassan tanvir.hassan@autodesk.com NT +Bob Hardy hardy@lucid.com Power C on MSDOS +Zachary Heilig heilig@plains.nodak.edu Turbo C++ 3.0 +Chris Herborth chrish@pobox.com BeOS port +Jonathan Hudson jrhudson@bigfoot.com QDOS port +Mark William Jacobs mark@mensch.stanford.edu MSDOS +Aubrey Jaffer jaffer@martigny.ai.mit.edu Pixel +Peter Jones jones.peter@uqam.ca MIPS UMIPS 4.0 + +Onolimit fix for HP-UX +Kjetil W. J{\o}rgensen jorgens@lise.unit.no OSF/1, DJGPP v2 +Bruce Kahn bkahn@archive.webo.dg.com MS-DOS Microsoft C 5.1 +Jonathan I. Kamens jik@pit-manager.mit.edu ultrix on DECstation +Dave Kapalko d.kapalko@att.com bug report +Bob Kemp Robert.V.Kemp@att.com AT&T 3B2 SysV 3.2v2 +Vivek Khera khera@cs.duke.edu SunOS +Earl Kiech KIECH@utkvx.utk.edu VAX VMS V5.4-1A +Paul Kienitz Paul.Kienitz@shelter.sf.ca.us Amiga, Watcom C +David Kirschbaum kirsch@usasoc.soc.mil He got us all in this + mess in the first place +Thomas Klausner wiz@danbala.tuwien.ac.at cygwin32 and -k fix +D. Krumbholz krumbh00@marvin.informatik.uni-dortmund.de + Acorn filetype and + timestamp bug report + +Bo Kullmar bk@kullmar.se DNIX 5.3, SunOS 4.1 +Baden Kudrenecky baden@unixg.ubc.ca OS/2 +Giuseppe La Sala lasala@mail.esa.esrin.it VMS +Jean-Marc Lasgouttes jean-marc.lasgouttes@inria.fr Bug report +Harry Langenbacher harry@neuron6.Jpl.Nasa.Gov Sun SS1+ SunOS 4.1 +Michael D. Lawler mdlawler@gwmicro.com Mt.Xinu BSD 4.3 on VAX + Borland C++ 4.51 +Johnny Lee johnnyl@microsoft.com Microsoft C 7.0 +Michael Lemke michael@io.as.utexas.edu VMS +David Lemson lemson@ux1.cso.uiuc.edu Sequent Dynix 3.0.17 +Tai-Shan Lin tlin@snakeyes.eecs.wsu.edu OS/2 +Onno van der Linden onno@simplex.nl NetBSD, Borland C++, + MSC 7.0, DJGPP 2 + +Michel loehden%mv13.decnet@vax.hrz.uni-marburg.de VMS +Warner Losh imp@Solbourne.COM packing algorithm help +Dave Lovelace davel@grex.cyberspace.org DG AOS/VS +Erik Luijten erik@tntnhb3.tn.tudelft.nl problem report +John Lundin lundin@urvax.urich.edu VAX VMS +Igor Mandrichenko mandrichenko@m10.ihep.su VAX VMS +Cliff Manis root@csoftec.csf.com SCO 2.3.1 (386) +Fulvio Marino fulvio@iconet.ico.olivetti.it X/OS 2.3 & 2.4 +Bill Marsh bmarsh@cod.nosc.mil SGI Iris 4D35 +Michael Mauch mauch@gmx.de djgpp LFN attribute fix +Peter Mauzey ptm@mtdcr.mt.lucent.com AT&T 6300, 7300 +Rafal Z. Maszkowski rzm@mat.torun.edu.pl Convex +Robert McBroom (?) rm3@ornl.gov DECsystem 5810 +Tom McConnell tmcconne@sedona.intel.com NCR SVR4 +Frank P. McIngvale frankm@eng.auburn.edu Bug report +Conor McMenamin C.S.McMenamin@sussex.ac.uk MSDOS +Will Menninger Win32, MinGW +John Messenger jlm@proteon.com Bug report +Michael kuch@mailserv.zdv.uni-tuebingen.de SGI +Dan Mick dmick@pongo.west.sun.com Solaris +Alan Modra alan@spri.levels.unisa.edu.au Linux +Laszlo Molnar lmolnar@goliat.eik.bme.hu DJGPP v2 +Jim Mollmann jmq@nccibm1.bitnet OS/2 & MVS +Sergio Monesi pel0015@cdc8g5.cdc.polimi.it Acorn +J. Mukherjee jmukherj@ringer.cs.utsa.edu OS/2 +Anthony Naggs amn@ubik.demon.co.uk bug report +Matti Narkia matti.narkia@ntc.nokia.com VAX VMS +Rainer Nausedat Zip 3.0, large files +Robert E. Newman Jr. newmanr@ssl.msfc.nasa.gov bug report +Robert Nielsen NielsenRJ@ems.com 2.2 -V VMS bug report +Christian Michel cmichel@de.ibm.com 2.2 check_dup OS/2 bug + report +Thomas S. Opheys opheys@kirk.fmi.uni-passau.de OS/2 +Humberto Ortiz-Zuazaga zuazaga@ucunix.san.uc.edu Linux +James E. O'Dell jim@fpr.com MacOS +William O'Shaughnessy williamo@hpcupt1.cup.hp.com HPUX +Neil Parks neil.parks@pcohio.com MSDOS +Enrico Renato Palmerini palmer@vxscaq.cineca.it UNISYS 7000 Sys 5 r2.3 +Geoff Pennington Geoff.Pennington@sgcs.co.uk -q output bug +Keith Petersen w8sdz@simtel20.army.mil Pyramid UCB OSx4.4c +George Petrov VM/CMS, MVS +Alan Phillips postmaster@lancaster.ac.uk Dynix/ptx 1.3 +Bruno Pillard bp@chorus.fr SunOS 4.1 +Piet W. Plomp piet@icce.rug.nl MSC 7.0, SCO 3.2v4.0 +John Poltorak j.poltorak@bradford.ac.uk problem report +Kenneth Porter 72420.2436@compuserve.com OS/2 +Norbert Pueschel pueschel@imsdd.meb.uni-bonn.de Amiga time.lib +Yuval Rakavy yuval@cs.huji.ac.il MSDOS +David A Rasmussen dave@convex.csd.uwm.edu Convex C220 with 9.0 OS +Eric Raymond esr@snark.thyrsus.com Unix +Jim Read 74312.3103@compuserve.com OS/2 +Michael Regoli mr@cica.indiana.edu Ultrix 3.1 VAX 8650 + BSD 4.3 IBM RT/125 + BSD 4.3 MicroVAX 3500 + SunOS 4.0.3 Sun 4/330 +Jochen Roderburg roderburg@rrz.uni-koeln.de Digital Unix with + AFS/NFS converter +Rick Rodgers rodgers@maxwell.mmwb.ucsf.EDU Unix man page +Greg Roelofs roe2@midway.uchicago.edu SunOS 4.1.1,4.1.2 Sun 4 + Unicos 5.1--6.1.5 Cray + OS/2 1.3 MS C 6.0 + Ultrix 4.1,4.2 DEC 5810 + VMS 5.2, 5.4 VAX 8600 + Irix 3.3.2, SGI Iris 4D + UTS 1.2.4 Amdahl 5880 +Phil Ritzenthaler phil@cgrg.ohio-state.edu SYSV +Kai Uwe Rommel rommel@ars.de or rommel@leo.org OS/2 +Markus Ruppel m.ruppel@imperial.ac.uk OS/2 +Shimazaki Ryo eririn@ma.mailbank.ne.jp human68k +Jon Saxton jrs@panix.com Microsoft C 6.0 +Steve Salisbury stevesa@msn.com Microsoft C 8.0 +Timo Salmi ts@uwasa.fi bug report +Darren Salt ds@youmustbejoking.demon.co.uk RISC OS +NIIMI Satoshi a01309@cfi.waseda.ac.jp Human68K +Tom Schmidt tschmidt@micron.com SCO 286 +Martin Schulz martin.schulz@isltd.insignia.com Windows NT, Atari +Steven Schweda VMS, Unix, large files +Dan Seyb dseyb@halnet.com AIX +Mark Shadley shadcat@catcher.com unix fixes +Timur Shaporev tim@rd.relcom.msk.su MSDOS +W. T. Sidney sidney@picard.med.ge.com bug report +Dave Sisson daves@vtcosy.cns.vt.edu AIX 1.1.1 PS/2 & 3090 +Dave Smith smithdt@bp.com Tandem port +Fred Smith fredex@fcshome.stoneham.ma.us Coherent +Christian Spieler spieler@ikp.tu-darmstadt.de VMS, MSDOS, emx, djgpp, + WIN32, Linux +Ron Srodawa srodawa@vela.acs.oakland.edu SCO Xenix/386 2.3.3 +Adam Stanley astanley@winternet.com MSDOS +Bertil Stenstr|m stenis@heron.dafa.se HP-UX 7.0 HP9000/835 +Carl Streeter streeter@oshkoshw.bitnet OS/2 +Reuben Sumner rasumner@undergrad.math.uwaterloo.ca Suggestions +E-Yen Tan e-yen.tan@brasenose.oxford.ac.uk Borland C++ win32 +Yoshioka Tsuneo tsuneo-y@is.aist-nara.ac.jp Multibyte charset + support +Paul Telles paul@pubnet.com SCO Xenix +Julian Thompson jrt@oasis.icl.co.uk bug report +Christopher C. Tjon tjon@plains.nodak.edu bug report +Robert F Tobler rft@cs.stanford.edu bug report +Eric Tomio tomio@acri.fr bug report +Cosmin Truta cosmint@cs.ubbcluj.ro win32 gcc based + asm +Anthony R. Venson cevens@unix1.sncc.lsu.edu MSDOS/emx +Antoine Verheijen antoine@sysmail.ucs.ualberta.ca envargs fix +Arjan de Vet devet@info.win.tue.nl SunOS 4.1, MSC 5.1 +Santiago Vila Doncel sanvila@ba.unex.es MSDOS +Johan Vromans jv@mh.nl bug report +Rich Wales wales@cs.ucla.edu SunOS 4.0.3 Sun-3/50 +Scott Walton scottw@io.com BSD/386 +Frank J. Wancho wancho@wsmr-simtel20.army.mil TOPS-20 + oyvind@stavanger.sgp.slb.com Bug report. +Takahiro Watanabe wata@first.tsukuba.ac.jp fixes for INSTALL +Mike White mwhite@pumatech.com wizzip DLL +Ray Wickert wickert@dc-srv.pa-x.dec.com MSDOS/DJGPP +Winfried Winkler willi@wap0109.chem.tu-berlin.de AIX +Norman J. Wong as219@freenet.carleton.ca MSDOS +Martin Zinser m.zinser@gsi.de VMS 7.x + diff --git a/proginfo/ntsd.txt b/proginfo/ntsd.txt new file mode 100644 index 0000000..8ac31ba --- /dev/null +++ b/proginfo/ntsd.txt @@ -0,0 +1,111 @@ +Info-ZIP portable Zip/UnZip Windows NT security descriptor support +================================================================== +Scott Field (sfield@microsoft.com), 8 October 1996 + + +This version of Info-ZIP's Win32 code allows for processing of Windows +NT security descriptors if they were saved in the .zip file using the +appropriate Win32 Zip running under Windows NT. This also requires +that the file system that Zip/UnZip operates on supports persistent +Acl storage. When the operating system is not Windows NT and the +target file system does not support persistent Acl storage, no security +descriptor processing takes place. + +A Windows NT security descriptor consists of any combination of the +following components: + + an owner (Sid) + a primary group (Sid) + a discretionary ACL (Dacl) + a system ACL (Sacl) + qualifiers for the preceding items + +By default, Zip will save all aspects of the security descriptor except +for the Sacl. The Sacl contains information pertaining to auditing of +the file, and requires a security privilege be granted to the calling +user in addition to being enabled by the calling application. In order +to save the Sacl during Zip, the user must specify the -! switch on the +Zip commandline. The user must also be granted either the SeBackupPrivilege +"Backup files and directories" or the SeSystemSecurityPrivilege "Manage +auditing and security log". + +By default, UnZip will not restore any aspects of the security descriptor. +If the -X option is specified to UnZip, the Dacl is restored to the file. +The other items in the security descriptor on the new file will receive +default values. If the -XX option is specified to UnZip, as many aspects +of the security descriptor as possible will be restored. If the calling +user is granted the SeRestorePrivilege "Restore files and directories", +all aspects of the security descriptor will be restored. If the calling +user is only granted the SeSystemSecurityPrivilege "Manage auditing and +security log", only the Dacl and Sacl will be restored to the new file. + +Note that when operating on files that reside on remote volumes, the +privileges specified above must be granted to the calling user on that +remote machine. Currently, there is no way to directly test what privileges +are present on a remote machine, so Zip and UnZip make a remote privilege +determination based on an indirect method. + +UnZip considerations +-------------------- + +In order for file security to be processed correctly, any directory entries +that have a security descriptor will be processed at the end of the unzip +cycle. This allows for unzip to process files within the newly created +directory regardless of the security descriptor associated with the directory +entry. This also prevents security inheritance problems that can occur as +a result of creating a new directory and then creating files in that directory +that will inherit parent directory permissions; such inherited permissions may +prevent the security descriptor taken from the zip file from being applied +to the new file. + +If directories exist which match directory/extract paths in the .zip file, +file security is not updated on the target directory. It is assumed that if +the target directory already exists, then appropriate security has already +been applied to that directory. + +"unzip -t" will test the integrity of stored security descriptors when +present and the operating system is Windows NT. + +ZipInfo (unzip -Z) will display information on stored security descriptor +when "unzip -Zv" is specifed. + + +Potential uses +============== + +The obvious use for this new support is to better support backup and restore +operations in a Windows NT environment where NTFS file security is utilized. +This allows individuals and organizations to archive files in a portable +fashion and transport these files across the organization. + +Another potential use of this support is setup and installation. This +allows for distribution of Windows NT based applications that have preset +security on files and directories. For example, prior to creation of the +.zip file, the user can set file security via File Manager or Explorer on +the files to be contained in the .zip file. In many cases, it is appropriate +to only grant Everyone Read access to .exe and .dll files, while granting +Administrators Full control. Using this support in conjunction with the +unzipsfx.exe self-extractor stub can yield a useful and powerful way to +install software with preset security (note that -X or -XX should be +specified on the self-extractor commandline). + +When creating .zip files with security which are intended for transport +across systems, it is important to take into account the relevance of +access control entries and the associated Sid of each entry. For example, +if a .zip file is created on a Windows NT workstation, and file security +references local workstation user accounts (like an account named Fred), +this access entry will not be relevant if the .zip file is transported to +another machine. Where possible, take advantage of the built-in well-known +groups, like Administrators, Everyone, Network, Guests, etc. These groups +have the same meaning on any Windows NT machine. Note that the names of +these groups may differ depending on the language of the installed Windows +NT, but this isn't a problem since each name has well-known ID that, upon +restore, translates to the correct group name regardless of locale. + +When access control entries contain Sid entries that reference Domain +accounts, these entries will only be relevant on systems that recognize +the referenced domain. Generally speaking, the only side effects of +irrelevant access control entries is wasted space in the stored security +descriptor and loss of complete intended access control. Such irrelevant +access control entries will show up as "Account Unknown" when viewing file +security with File Manager or Explorer. diff --git a/proginfo/perform.dos b/proginfo/perform.dos new file mode 100644 index 0000000..98744ee --- /dev/null +++ b/proginfo/perform.dos @@ -0,0 +1,183 @@ +Date: Wed, 27 Mar 1996 01:31:50 CET +0100 +From: Christian Spieler (IKDA, THD, D-64289 Darmstadt) +Subject: More detailed comparison of MSDOS Info-ZIP programs' performance + +Hello all, + +In response to some additional questions and requests concerning +my previous message about DOS performance of 16/32-bit Info-ZIP programs, +I have produced a more detailed comparison: + +System: +Cx486DX-40, VL-bus, 8MB; IDE hard disk; +DOS 6.2, HIMEM, EMM386 NOEMS NOVCPI, SMARTDRV 3MB, write back. + +I have used the main directory of UnZip 5.20p as source, including the +objects and executable of an EMX compile for unzip.exe (to supply some +binary test files). + +Tested programs were (my current updated sources!) Zip 2.0w and UnZip 5.20p +- 16-bit MSC 5.1, compressed with LZEXE 0.91e +- 32-bit Watcom C 10.5, as supplied by Kai Uwe Rommel (PMODE 1.22) +- 32-bit EMX 0.9b +- 32-bit DJGPP v2 +- 32-bit DJGPP v1.12m4 + +The EMX and DJ1 (GO32) executables were bound with the full extender, to +create standalone executables. + +A) Tests of Zip + Command : "\zip.exe -q<#> tes.zip unz/*" (unz/*.* for Watcom!!) + where <#> was: 0, 1, 6, 9. + The test archive "tes.zip" was never deleted, this test + measured "time to update archive". + + The following table contains average execution seconds (averaged over + at least 3 runs, with the first run discarted to fill disk cache); + numbers in parenteses specify the standard deviation of the last + digits. + + cmpr level| 0 | 1 | 6 | 9 + =============================================================== + EMX win95 | 7.77 | 7.97 | 12.82 | 22.31 + --------------------------------------------------------------- + EMX | 7.15(40) | 8.00(6) | 12.52(25) | 20.93 + DJ2 | 13.50(32) | 14.20(7) | 19.05 | 28.48(9) + DJ1 | 13.56(30) | 14.48(3) | 18.70 | 27.43(13) + WAT | 6.94(22) | 8.93 | 15.73(34) | 30.25(6) + MSC | 5.99(82) | 9.40(4) | 13.59(9) | 20.77(4) + =============================================================== + + The "EMX win95" line was created for comparison, to check the performance + of emx 0.9 with the RSX extender in a DPMI environment. (This line was + produced by applying the "stubbed" EMX executable in a full screen DOS box.) + + +B) Tests of UnZip + Commands : \unzip.exe -qt tes.zip (testing performance) + \unzip.exe -qo tes.zip -dtm (extracting performance) + + The tes.zip archive created by maximum compression with the Zip test + was used as example archive. Contents (archive size was 347783 bytes): + 1028492 bytes uncompressed, 337235 bytes compressed, 67%, 85 files + + The extraction directory tm was not deleted between the individual runs, + thus this measurement checks the "overwrite all" time. + + | testing | extracting + =================================================================== + EMX | 1.98 | 6.43(8) + DJ2 | 2.09 | 11.85(39) + DJ1 | 2.09 | 7.46(9) + WAT | 2.42 | 7.10(27) + MSC | 4.94 | 9.57(31) + +Remarks: + +The executables compiled by me were generated with all "performance" +options enabled (ASM_CRC, and ASMV for Zip), and with full crypt support. +For DJ1 and DJ2, the GCC options were "-O2 -m486", for EMX "-O -m486". + +The Watcom UnZip was compiled with ASM_CRC code enabled as well, +but the Watcom Zip example was made without any optional assembler code! + + + +Discussion of the results: + +In overall performance, the EMX executables clearly win. +For UnZip, emx is by far the fastest program, and the Zip performance is +comparable to the 16-bit "reference". + +Whenever "real" work including I/O is requested, the DJGPP versions +lose badly because of poor I/O performance, this is the case especially +for the "newer" DJGPP v2 !!! +(I tried to tweak with the transfer buffer size, but without any success.) +An interesting result is that DJ v1 UnZip works remarkably better than +DJ v2 (in contrast to Zip, where both executables' performance is +approximately equal). + +The Watcom C programs show a clear performance deficit in the "computational +part" (Watcom C compiler produces code that is far from optimal), but +the extender (which is mostly responsible for the I/O throughput) seems +to be quite fast. + +The "natural" performance deficit of the 16-bit MSC code, which can be +clearly seen in the "testing task" comparison for UnZip, is (mostly, +for Zip more than) compensated by the better I/O throughput (due to the +"direct interface" between "C RTL" and "DOS services", without any mode +switching). + +But performance is only one aspect when choosing which compiler should +be used for official distribution: + +Sizes of the executables: + | Zip || UnZip + | standalone stub || standalone | stub +====================================================================== +EMX | 143,364 (1) | 94,212 || 159,748 (1) | 110,596 +DJ2 | 118,272 (2) | -- || 124,928 (2) | -- +DJ1 | 159,744 | 88,064 || 177,152 | 105,472 +WAT | 140,073 | -- || 116,231 | -- +MSC | 49,212 (3) | -- || 45,510 (3) | -- + +(1) does not run in "DPMI only" environment (Windows DOS box) +(2) requires externally supplied DPMI server +(3) compressed with LZexe 0.91 + +Caveats/Bugs/Problems of the different extenders: + +EMX: +- requires two different extenders to run in all DOS-compatible environments, + EMX for "raw/himem/vcpi" and RSX for "dpmi" (Windows). +- does not properly support time zones (no daylight savings time) + +DJv2: +- requires an external (freely available) DPMI extender when run on plain + DOS; this extender cannot (currently ??) be bound into the executable. + +DJv1: +- uses up large amount of "low" dos memory (below 1M) when spawning + another program, each instance of a DJv1 program requires its private + GO32 extender copy in low dos memory (may be problem for the zip + "-T" feature) + +Watcom/PMODE: +- extended memory is allocated statically (default: ALL available memory) + This means that a spawned program does not get any extended memory. + You can work around this problem by setting a hard limit on the amount + of extended memory available to the PMODE program, but this limit is + "hard" and restricts the allocatable memory for the program itself. + In detail: + The Watcom zip.exe as distributed did not allow the "zip -T" feature; + there was no extended memory left to spawn unzip. + I could work around this problem by applying PMSETUP to change the + amount of allocated extended memory to 2.0 MByte (I had 4MB free extended + memory on my test system). But, this limit cannot be enlarged at + runtime, when zip needs more memory to store "header info" while + zipping up a huge drive, and on a system with less free memory, this + method is not applicable, either. + +Summary: + +For Zip: +Use the 16-bit executable whenever possible (unless you need the +larger memory capabilities when zipping up a huge amount of files) + +As 32-bit executable, we may distribute Watcom C (after we have confirmed +that enabling ASMV and ASM_CRC give us some better computational +performance.) +The alternative for 32-bit remains DJGPP v1, which shows the least problems +(to my knowledge); v2 and EMX cannot be used because of their lack of +"universality". + +For UnZip: +Here, the Watcom C 32-bit executable is probably the best compromise, +but DJ v1 could be used as well. +And, after all, the 16-bit version does not lose badly when doing +"real" extraction! For the SFX stub, the 16-bit version remains first +choice because of its much smaller size! + +Best regards + +Christian Spieler diff --git a/proginfo/timezone.txt b/proginfo/timezone.txt new file mode 100644 index 0000000..7868093 --- /dev/null +++ b/proginfo/timezone.txt @@ -0,0 +1,85 @@ +Timezone strings: +----------------- +This is a description of valid timezone strings for ENV[ARC]:TZ: +"XPG3TZ - time zone information" +The form of the time zone information is based on the XPG3 specification of +the TZ environment variable. Spaces are allowed only in timezone +designations, where they are significant. The following description +closely follows the XPG3 specification, except for the paragraphs starting +**CLARIFICATION**. + +[[],[/