diff options
Diffstat (limited to 'os2')
-rw-r--r-- | os2/makefile.os2 | 560 | ||||
-rw-r--r-- | os2/match32.asm | 175 | ||||
-rw-r--r-- | os2/os2.c | 481 | ||||
-rw-r--r-- | os2/os2acl.c | 385 | ||||
-rw-r--r-- | os2/os2acl.h | 34 | ||||
-rw-r--r-- | os2/os2zip.c | 1213 | ||||
-rw-r--r-- | os2/os2zip.h | 84 | ||||
-rw-r--r-- | os2/osdep.h | 173 | ||||
-rw-r--r-- | os2/zip.def | 3 | ||||
-rw-r--r-- | os2/zipup.h | 16 |
10 files changed, 3124 insertions, 0 deletions
diff --git a/os2/makefile.os2 b/os2/makefile.os2 new file mode 100644 index 0000000..8e5e7cf --- /dev/null +++ b/os2/makefile.os2 @@ -0,0 +1,560 @@ +# 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" \ + CRC32="crc_i86" \ + 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" \ + CRC32="crc_i86" \ + 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" \ + CRC32="crc_i86" \ + 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 -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 -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 -DNO_ASM" \ + AS="wasm -bt=dos4g -3p" \ + ASFLAGS="" \ + LDFLAGS="-k0x50000 -x -l=dos4g -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="\\" + +# 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 -bt=dos4g -3p" \ + ASFLAGS="" \ + LDFLAGS="-k0x50000 -x -l=pmodew -Fe=" \ + LDFLAGS2="" \ + OUT="-Fo" \ + OBJ=".obj" \ + CRC32="crc_i386" \ + 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 -bt=dos -2p -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" \ + CRC32="crc_gcc" \ + 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" \ + CRC32="crc_gcc" \ + 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" \ + CRC32="crc32" \ + 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" \ + CRC32="crc_gcc" \ + 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" \ + CRC32="crc_gcc" \ + 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" \ + CRC32="crc_gcc" \ + 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" \ + CRC32="crc_gcc" \ + 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 +CRC32 = crc32 + + +OBJZ = zip$(OBJ) zipfile$(OBJ) zipup$(OBJ) fileio$(OBJ) util$(OBJ) \ + $(CRC32)$(OBJ) crctab$(OBJ) 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) crctab$(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 crypt.h ttyio.h +zipfile$(OBJ): zipfile.c $(ZIP_H) +zipup$(OBJ): zipup.c $(ZIP_H) revision.h crypt.h $(ZIPUP_H) +fileio$(OBJ): fileio.c $(ZIP_H) +util$(OBJ): util.c $(ZIP_H) +globals$(OBJ): globals.c $(ZIP_H) +deflate$(OBJ): deflate.c $(ZIP_H) +trees$(OBJ): trees.c $(ZIP_H) +crc32$(OBJ): crc32.c $(ZIP_H) +crctab$(OBJ): crctab.c $(ZIP_H) +crypt$(OBJ): crypt.c $(ZIP_H) crypt.h ttyio.h +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 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) + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ zipfile.c + +fileio_$(OBJ): fileio.c $(ZIP_H) + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ fileio.c + +util_$(OBJ): util.c $(ZIP_H) os2/os2zip.h + $(CC) -c -I. $(CCFLAGS) -DUTIL $(OUT)$@ util.c + +crypt_$(OBJ): crypt.c $(ZIP_H) crypt.h ttyio.h + $(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..ef9a541 --- /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 2004-May-22 or later +; (the contents of which are also included in zip.h) for terms of use. +; If, for some reason, both of these files are missing, the Info-ZIP license +; also may be found at: ftp://ftp.info-zip.org/pub/infozip/licen; Copyright (c) 1990-1999 Info-ZIP. All rights reserved. +;=========================================================================== +; +; 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=<whatever>. + +; 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..355eea8 --- /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 2004-May-22 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +#include "zip.h" + +#ifndef UTIL /* the companion #endif is a bit of ways down ... */ + +#include <time.h> +#if defined(__IBMC__) || defined(MSC) +#include <direct.h> +#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..7c5b1fd --- /dev/null +++ b/os2/os2acl.c @@ -0,0 +1,385 @@ +/* + 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 +*/ +/* os2acl.c - access to OS/2 (LAN Server) ACLs + * + * Author: Kai Uwe Rommel <rommel@ars.de> + * 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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <malloc.h> + +#define INCL_NOPM +#define INCL_DOS +#define INCL_DOSERRORS +#include <os2.h> + +#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(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..dd34b2d --- /dev/null +++ b/os2/os2acl.h @@ -0,0 +1,34 @@ +/* + Copyright (c) 1990-2005 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2004-May-22 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* os2acl.h + * + * Author: Kai Uwe Rommel <rommel@ars.de> + * 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 <stdlib.h> +#include <time.h> +#include <ctype.h> +#ifndef __BORLANDC__ +#include <malloc.h> +#endif + +#define INCL_NOPM +#define INCL_DOSNLS +#define INCL_DOSERRORS +#include <os2.h> + +#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 <alloc.h> +# if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__) +# if defined(DYNAMIC_CRC_TABLE) && defined(DYNALLOC_CRCTAB) + error: No dynamic CRC table allocation with Borland C far data models. +# endif /* DYNAMIC_CRC_TABLE */ +# endif /* Turbo/Borland C far data memory models */ +# define nearmalloc malloc +# define nearfree free +# define DYN_ALLOC +# else /* !__TURBOC__ */ +# include <malloc.h> +# define nearmalloc _nmalloc +# define nearfree _nfree +# define farmalloc _fmalloc +# define farfree _ffree +# endif /* ?__TURBOC__ */ +# define MY_ZCALLOC 1 +#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 <sys/types.h> +#include <sys/stat.h> +#include <io.h> + +#ifdef ZCRYPT_INTERNAL +# ifndef __GO32__ +# include <process.h> /* 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 |