/programs/fs/unzip60/os2/Contents |
---|
0,0 → 1,22 |
Contents of the "os2" subdirectory for UnZip 5.3 and later: |
Contents this file |
makefile.os2 makefile for almost every compiler available under OS/2 |
os2.c OS/2-specific support routines |
os2data.h OS/2-specific data declarations |
os2cfg.h OS/2-specific configuration, included in unzpriv.h |
os2acl.c OS/2-specific routines for access-control-list support |
os2acl.h OS/2-specific header file for access-control-list support |
rexxapi.c interface to integrate UnZip DLL in REXX API |
rexxapi.def OS/2 linker definition file for REXX API DLL |
rexxhelp.c help function for UnZip's REXX API DLL |
rexxtest.cmd REXX script for testing UnZip's REXX API DLL |
stub.def OS/2 linker definition file (generic UnZip DLL API) |
unzip.def OS/2 linker definition file |
zip2exe.cmd REXX script for creating self-extracting archives |
zipgrep.cmd really cool REXX script to search for strings in a zipfile |
zgrepapi.cmd new version of zipgrep.cmd; takes advantage of REXX API DLL |
There is no support for the ancient Zortech and GCC/2 (Michael Johnson/Colin |
Jensen) compilers. The free emx+gcc is supported, as are roughly half a dozen |
commercial compilers. |
/programs/fs/unzip60/os2/makefile.os2 |
---|
0,0 → 1,662 |
# Makefile for UnZip, UnZipSFX and fUnZip 03 January 2007 |
# |
# supported compilers: |
# - Microsoft C, version 6.00 or higher, for use under OS/2 1.x (16-bit) |
# - Watcom C/C++, version 9.0+, for use under OS/2 1.x or 2.x+ (16/32-bit) |
# - emx+gcc, version 0.9c or higher, for use under OS/2 2.x+ (32-bit) |
# - IBM C Set++, for use under OS/2 2.x+ (32-bit) |
# - Borland C++, for use under OS/2 2.x+ (32-bit) |
# - Metaware High C/C++, for use under OS/2 2.x+ (32-bit) |
# |
# supported cross-compilers: |
# - Microsoft C, version 6.0 or 7.0, for use under DOS (16-bit) |
# - Watcom C/C++, version 9.0+, for use under DOS/Win95/NT (16/32-bit) |
# - GNU gcc (emx), version 0.9c or higher, for use under DOS/Win95/NT (32-bit) |
# |
# supported assemblers: |
# - Microsoft MASM 6.00 with Microsoft 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 "{d,n}make -f os2/makefile.os2" (this makefile depends on its |
# name being "makefile.os2", and it must be in the os2 subdirectory). |
# In case you want to use Watcom wmake instead, you have to switch wmake into |
# the "MS nmake compatible" mode by specifying the "-ms" option. Additionally, |
# it is required to override the MAKE macro definition for the recursive |
# invokation of wmake. An example: |
# wmake -ms -f os2/makefile.os2 MAKE="wmake -ms" watcom |
# Notes on Microsoft C 6.00 compilation for OS/2: |
# |
# The resulting programs can be used under OS/2 protected mode only, not |
# under DOS. A larger stack has to be used for OS/2 because system calls |
# use more stack than under DOS; 8k is recommended by Microsoft. |
# Notes on IBM C Set++, Watcom C/C++, Borland C++ or emx+gcc compilation: |
# |
# The resulting programs can be used under protected mode of OS/2 2.x or |
# higher only, not under OS/2 1.x and not under DOS. |
# |
# The NFLAGS macro is used to work around an optimization bug in the IBM |
# C++ Set compiler; this is fixed by CSD #4, so NFLAGS="" can be used for |
# all targets below. |
# 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. See also msdos/README for important |
# notes about PMODE/W bugs. |
default: |
@echo "Enter `$(MAKE) -f os2/makefile.os2 target' from the main" |
@echo "UnZip directory, where target is one of:" |
@echo " msc mscdebug mscdos ibm ibmdyn ibmdebug ibmprof" |
@echo " ibmdll ibmdyndll ibmdebugdll ibmprofdll" |
@echo " metaware borland gcc gccdyn gccdebug gccdos gccwin32" |
@echo " watcom watcom16 watcomdos watcom16dos pmodew watcomwin32" |
# MS C 6.00 for OS/2, 16-bit (should figure out way to split unzip/funzip |
# compiles so former is always large model and latter always small model...) |
msc: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="cl -nologo -AL -Ocegit -Gs -I. $(FP)" \ |
CFLAGS="-G2 -Zp1 -W3 -DOS2 -DMSC -DASM_CRC $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
AS="ml -nologo -c -Zm -Cp" \ |
ASFLAGS="-D__LARGE__ -D__286" \ |
LDFLAGS="-F 2000 -Lp -Fe" \ |
LDFLAGS2="-link /noe" \ |
OUT="-Fo" \ |
OBJ=".obj" \ |
CRCA_O="crc_i86.obj" \ |
OBJF2="os2f.obj" \ |
DEF="os2\unzip.def" |
# MS C 6.00 for OS/2, debug version |
mscdebug: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="cl -nologo -AL -Zi -Od -I. $(FP)" \ |
CFLAGS="-G2 -Zp1 -W3 -DOS2 -DMSC -DASM_CRC $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
AS="ml -nologo -c -Zim -Cp" \ |
ASFLAGS="-D__LARGE__ -D__286" \ |
LDFLAGS="-F 2000 -Lp -Fe" \ |
LDFLAGS2="-link /noe" \ |
OUT="-Fo" \ |
OBJ=".obj" \ |
CRCA_O="crc_i86.obj" \ |
OBJF2="os2f.obj" \ |
DEF="os2\unzip.def" |
# cross-compilation for MS-DOS with MS C 6.00 (same comment as above...formerly; |
# now unzip is large model again, because of DEFLATE_64 support) |
mscdos: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="cl -nologo -AL -Oaict -Gs -I. $(FP)" \ |
CFLAGS="-Zp1 -W3 -DASM_CRC $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
AS="ml -nologo -c -Zm -Cp" \ |
ASFLAGS="-D__LARGE__" \ |
LDFLAGS="-F 0C00 -Lr -Fe" \ |
LDFLAGS2="-link /noe /exe" \ |
OUT="-Fo" \ |
OBJ=".obj" \ |
CRCA_O="crc_i86" \ |
OBJU2="msdos.obj" \ |
OBJX2="msdos_.obj" \ |
OBJF2="msdosf.obj" \ |
OSDEP_H="msdos/doscfg.h" |
# IBM C Set, statically linked runtime |
ibm: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="icc -Q -O -Gs -I." \ |
CFLAGS="-Sm -Sp1 -DOS2 $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
LDFLAGS="-B/ST:0x50000 -Fe" \ |
LDFLAGS2="" \ |
OUT="-Fo" \ |
OBJ=".obj" \ |
DEF="os2\unzip.def" |
# IBM C Set, dynamically linked runtime |
ibmdyn: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="icc -Q -O -Gs -Gd -I." \ |
CFLAGS="-Sm -Sp1 -DOS2 $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
LDFLAGS="-B/ST:0x50000 -Fe" \ |
LDFLAGS2="" \ |
OUT="-Fo" \ |
OBJ=".obj" \ |
DEF="os2\unzip.def" |
# IBM C Set, debug version |
ibmdebug: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="icc -Q -Ti -I." \ |
CFLAGS="-Sm -Sp1 -D__DEBUG_ALLOC__ -DOS2 $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
LDFLAGS="-B/ST:0x50000 -Fe" \ |
LDFLAGS2="" \ |
OUT="-Fo" \ |
OBJ=".obj" \ |
DEF="os2\unzip.def" |
# IBM C Set, profiling version for PROFIT |
ibmprof: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="icc -Q -O -Gs -Gh -Ti -I." \ |
CFLAGS="-Sm -Sp1 -DOS2 $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
LDFLAGS="-B/ST:0x50000 -Fe" \ |
LDFLAGS2="cppopa3.obj" \ |
OUT="-Fo" \ |
OBJ=".obj" \ |
DEF="os2\unzip.def" |
# IBM C Set, statically linked runtime |
ibmdll: |
$(MAKE) -f os2/makefile.os2 dll \ |
CC="icc -Q -O -Gs -I." \ |
CFLAGS="-Sm -Sp1 -DOS2 $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="-Gm -Ge- -DDLL -DOS2DLL -DAPI_DOC" \ |
LDFLAGS="-Fe" \ |
LDFLAGS2="" \ |
OUT="-Fo" \ |
OBJ=".obj" \ |
DLLDEF="os2\rexxapi.def" \ |
STUBDEF="os2\stub.def" \ |
DEF="os2\unzip.def" \ |
APILIB="REXX.lib" |
# IBM C Set, dynamically linked runtime |
ibmdyndll: |
$(MAKE) -f os2/makefile.os2 dll \ |
CC="icc -Q -O -Gs -Gd -I." \ |
CFLAGS="-Sm -Sp1 -DOS2 $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="-Gm -Ge- -DDLL -DOS2DLL -DAPI_DOC" \ |
LDFLAGS="-Fe" \ |
LDFLAGS2="" \ |
OUT="-Fo" \ |
OBJ=".obj" \ |
DLLDEF="os2\rexxapi.def" \ |
STUBDEF="os2\stub.def" \ |
DEF="os2\unzip.def" \ |
APILIB="REXX.lib" |
# IBM C Set, debug version |
ibmdebugdll: |
$(MAKE) -f os2/makefile.os2 dll \ |
CC="icc -Q -Ti -I." \ |
CFLAGS="-Sm -Sp1 -D__DEBUG_ALLOC__ -DOS2 $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="-Gm -Ge- -DDLL -DOS2DLL -DAPI_DOC" \ |
LDFLAGS="-Fe" \ |
LDFLAGS2="" \ |
OUT="-Fo" \ |
OBJ=".obj" \ |
DLLDEF="os2\rexxapi.def" \ |
STUBDEF="os2\stub.def" \ |
DEF="os2\unzip.def" \ |
APILIB="REXX.lib" |
# IBM C Set, profiling version for PROFIT |
ibmprofdll: |
$(MAKE) -f os2/makefile.os2 dll \ |
CC="icc -Q -O -Gs -Gh -Ti -I." \ |
CFLAGS="-Gm -Sm -Sp1 -DOS2 $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="-Gm -Ge- -DDLL -DOS2DLL -DAPI_DOC" \ |
LDFLAGS="-Fe" \ |
LDFLAGS2="profit.obj" \ |
OUT="-Fo" \ |
OBJ=".obj" \ |
DLLDEF="os2\rexxapi.def" \ |
STUBDEF="os2\stub.def" \ |
DEF="os2\unzip.def" \ |
APILIB="REXX.lib" |
# Watcom C/386 9.0 or higher |
watcom: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="wcl386 -bt=os2v2 -zq -Ox -s -I." \ |
CFLAGS="-Zp1 -DOS2 -DASM_CRC $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
AS="wasm -bt=os2v2 -zq -3 -mf" \ |
ASFLAGS="" \ |
LDFLAGS="-k0x50000 -x -l=os2v2 -Fe=" \ |
LDFLAGS2="" \ |
OUT="-Fo" \ |
OBJ=".obj" \ |
CRCA_O="crc_i386.obj" \ |
DEF="" \ |
DIRSEP="\\" \ |
AS_DIRSEP="\\" |
# Watcom C/286 9.0 or higher |
watcom16: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="wcl -bt=os2 -zq -ml -Ox -s -I." \ |
CFLAGS="-Zp1 -DOS2 $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
AS="wasm -bt=os2 -zq -2 -ml" \ |
ASFLAGS="" \ |
LDFLAGS="-k0x2000 -x -l=os2 -Fe=" \ |
LDFLAGS2="" \ |
OUT="-Fo" \ |
OBJ=".obj" \ |
CRCA_O="crc_i86.obj" \ |
OBJF2="os2f.obj" \ |
DIRSEP="\\" \ |
AS_DIRSEP="\\" |
# Watcom C/386 9.0 or higher, crosscompilation for DOS, DOS4GW extender |
watcomdos: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="wcl386 -bt=dos4g -zq -Ox -s -I." \ |
CFLAGS="-Zp1 -DMSDOS -DASM_CRC $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
AS="wasm -bt=dos4g -zq -3 -mf" \ |
ASFLAGS="" \ |
LDFLAGS="-k0x50000 -x -l=dos4g -Fe=" \ |
LDFLAGS2="" \ |
OUT="-Fo" \ |
OBJ=".obj" \ |
CRCA_O="crc_i386.obj" \ |
OBJU2="msdos.obj" \ |
OBJX2="msdos_.obj" \ |
OSDEP_H="msdos/doscfg.h" \ |
DIRSEP="\\" \ |
AS_DIRSEP="\\" |
# Watcom C/386 9.0 or higher, crosscompilation for DOS, PMODE/W extender |
pmodew: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="wcl386 -bt=dos4g -zq -Ox -s -I." \ |
CFLAGS="-Zp1 -DMSDOS -DASM_CRC $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
AS="wasm -bt=dos4g -zq -3 -mf" \ |
ASFLAGS="" \ |
LDFLAGS="-k0x50000 -x -l=pmodew -Fe=" \ |
LDFLAGS2="" \ |
OUT="-Fo" \ |
OBJ=".obj" \ |
CRCA_O="crc_i386.obj" \ |
OBJU2="msdos.obj" \ |
OBJX2="msdos_.obj" \ |
OSDEP_H="msdos/doscfg.h" \ |
DIRSEP="\\" \ |
AS_DIRSEP="\\" |
# Watcom C/286 9.0 or higher, crosscompilation for DOS |
watcom16dos: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="wcl -bt=dos -zq -ml -Ox -s -I." \ |
CFLAGS="-Zp1 -DMSDOS $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
AS="wasm -bt=dos -0 -ml" \ |
ASFLAGS="-D__LARGE__" \ |
LDFLAGS="-k0xC00 -x -l=dos -Fe=" \ |
LDFLAGS2="" \ |
OUT="-Fo" \ |
OBJ=".obj" \ |
OBJU2="msdos.obj" \ |
OBJX2="msdos_.obj" \ |
OBJF2="msdosf.obj" \ |
OSDEP_H="msdos/doscfg.h" \ |
DIRSEP="\\" \ |
AS_DIRSEP="\\" |
# Watcom C/386 9.0 or higher, crosscompilation for Win95/NT |
watcomwin32: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="wcl386 -bt=NT -zq -Ox -s -I." \ |
CFLAGS="-Zp1 -DWIN32 -DASM_CRC $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
AS="wasm -bt=NT -zq -3 -mf" \ |
ASFLAGS="" \ |
LDFLAGS="-k0x50000 -x -l=NT -Fe=" \ |
LDFLAGS2="" \ |
OUT="-Fo" \ |
OBJ=".obj" \ |
CRCA_O="crc_i386.obj" \ |
OBJU2="win32.obj nt.obj" \ |
OBJX2="win32_.obj nt_.obj" \ |
OBJF2="win32f.obj" \ |
DEF="" \ |
DIRSEP="\\" \ |
AS_DIRSEP="\\" |
# MetaWare High C/C++ 3.2 |
metaware: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="hc -O2 -I." \ |
CFLAGS="-D__32BIT__ -DOS2 $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
LDFLAGS="-o " \ |
LDFLAGS2="" \ |
OUT="-o ./" \ |
OBJ=".obj" \ |
DEF="-Hdef=os2\unzip.def" |
# Borland C++ |
borland: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="bcc -O -I. -Ios2" \ |
CFLAGS="-w- -D__cdecl -D__32BIT__ -DOS2 $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
LDFLAGS="-e" \ |
LDFLAGS2="" \ |
OUT="-o" \ |
OBJ=".obj" \ |
DEF="-sDos2\unzip.def" |
# emx, gcc, OMF format, statically linked C runtime |
gcc: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="gcc -Zomf -O -I." \ |
CFLAGS="-Wall -DOS2 -DASM_CRC $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
AS="gcc -Zomf" \ |
ASFLAGS="-Di386" \ |
LDFLAGS="-o ./" \ |
LDFLAGS2="-Zsmall-conv -Zstack 320 -Zsys -s" \ |
OUT="-o" \ |
OBJ=".obj" \ |
CRCA_O="crc_gcc.obj" \ |
DEF="os2/unzip.def" |
# emx, gcc, OMF format, dynamically linked C runtime |
gccdyn: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="gcc -Zomf -O -I." \ |
CFLAGS="-Wall -DOS2 -DASM_CRC $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
AS="gcc -Zomf" \ |
ASFLAGS="-Di386" \ |
LDFLAGS="-o ./" \ |
LDFLAGS2="-Zstack 320 -Zcrtdll -s" \ |
OUT="-o" \ |
OBJ=".obj" \ |
CRCA_O="crc_gcc.obj" \ |
DEF="os2/unzip.def" |
# emx, gcc, a.out format, with debug info for gdb |
gccdebug: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="gcc -g -I." \ |
CFLAGS="-Wall -DOS2 -DASM_CRC $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
AS="gcc -g" \ |
ASFLAGS="-Di386" \ |
LDFLAGS="-o ./" \ |
LDFLAGS2="-Zsmall-conv" \ |
OUT="-o" \ |
OBJ=".o" \ |
CRCA_O="crc_gcc.o" \ |
# emx, gcc, a.out format, cross-compilation for MS-DOS |
gccdos: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="gcc -O -I." \ |
CFLAGS="-Wall -DMSDOS -DASM_CRC $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
AS="gcc" \ |
ASFLAGS="-Di386" \ |
LDFLAGS="-o ./" \ |
LDFLAGS2="-Zsmall-conv -s" \ |
OUT="-o" \ |
OBJ=".o" \ |
CRCA_O="crc_gcc.o" \ |
OBJU2="msdos.o" \ |
OBJX2="msdos_.o" \ |
OSDEP_H="msdos/doscfg.h" |
# emx, gcc, RSXNT, cross-compilation for Win32, statically linked C runtime |
gccwin32: |
$(MAKE) -f os2/makefile.os2 all \ |
CC="gcc -Zwin32 -O2 -I." \ |
CFLAGS="-Wall -DWIN32 -DASM_CRC $(LOCAL_UNZIP)" \ |
NFLAGS="" \ |
DLLFLAG="" \ |
AS="gcc" \ |
ASFLAGS="-Di386" \ |
LDFLAGS="-Zsys -o ./" \ |
LDFLAGS2="-ladvapi32 -Zsmall-conv -s" \ |
OUT="-o" \ |
OBJ=".o" \ |
CRCA_O="crc_gcc.o" \ |
OBJU2="win32.o nt.o" \ |
OBJX2="win32_.o nt_.o" \ |
OBJF2="win32f.o" \ |
OSDEP_H="win32/w32cfg.h" |
# variables |
# LOCAL_UNZIP = -DREENTRANT |
# default settings for target dependent macros: |
DIRSEP = / |
AS_DIRSEP = / |
OSDEP_H = os2/os2data.h os2/os2cfg.h |
CRCA_O = |
OBJU = unzip$(OBJ) crc32$(OBJ) $(CRCA_O) crypt$(OBJ) envargs$(OBJ) \ |
explode$(OBJ) extract$(OBJ) fileio$(OBJ) globals$(OBJ) \ |
inflate$(OBJ) list$(OBJ) match$(OBJ) process$(OBJ) ttyio$(OBJ) \ |
ubz2err$(OBJ) unreduce$(OBJ) unshrink$(OBJ) zipinfo$(OBJ) |
OBJU2 = os2$(OBJ) os2acl$(OBJ) |
OBJX = unzipsf_$(OBJ) crc32_$(OBJ) $(CRCA_O) crypt_$(OBJ) \ |
extract_$(OBJ) fileio_$(OBJ) globals_$(OBJ) inflate_$(OBJ) \ |
match_$(OBJ) process_$(OBJ) ttyio_$(OBJ) ubz2err_$(OBJ) |
OBJX2 = os2_$(OBJ) os2acl_$(OBJ) |
OBJDLL= api$(OBJ) apihelp$(OBJ) rexxhelp$(OBJ) rexxapi$(OBJ) |
OBJF = funzip$(OBJ) crc32f$(OBJ) $(CRCA_O) cryptf$(OBJ) inflatef$(OBJ) \ |
globalsf$(OBJ) ttyiof$(OBJ) |
OBJF2 = |
UNZIP_H = unzip.h unzpriv.h globals.h $(OSDEP_H) |
# rules |
.SUFFIXES: .c .asm $(OBJ) |
.c$(OBJ): |
$(CC) -c $(CFLAGS) $(DLLFLAG) $< |
.asm$(OBJ): |
$(AS) $(ASFLAGS) $< $(ASEOL) |
# targets |
all: unzip.exe funzip.exe unzipsfx.exe |
dll: unzip32.dll unzip.stb funzip.exe unzipsfx.exe |
unzip.exe: $(OBJU) $(OBJU2) |
$(CC) $(LDFLAGS)$@ $(DEF) $(OBJU) $(OBJU2) $(LDFLAGS2) |
funzip.exe: $(OBJF) $(OBJF2) |
$(CC) $(LDFLAGS)$@ $(DEF) $(OBJF) $(OBJF2) $(LDFLAGS2) |
unzipsfx.exe: $(OBJX) $(OBJX2) |
$(CC) $(LDFLAGS)$@ $(DEF) $(OBJX) $(OBJX2) $(LDFLAGS2) |
unzip32.dll: $(DLLDEF) $(OBJU) $(OBJU2) $(OBJDLL) |
$(CC) $(DLLFLAG) $(LDFLAGS)$@ $(DLLDEF) $(OBJU) $(OBJDLL) $(OBJU2) $(APILIB) $(LDFLAGS2) |
unzip.stb: unzipstb$(OBJ) $(STUBDEF) |
$(CC) $(LDFLAGS)$@ $(STUBDEF) unzipstb$(OBJ) $(LDFLAGS2) |
copy unzip.stb unzip.exe |
# dependencies |
apihelp$(OBJ): apihelp.c $(UNZIP_H) unzvers.h |
crc32$(OBJ): crc32.c $(UNZIP_H) zip.h crc32.h |
envargs$(OBJ): envargs.c $(UNZIP_H) |
explode$(OBJ): explode.c $(UNZIP_H) |
extract$(OBJ): extract.c $(UNZIP_H) crc32.h crypt.h |
fileio$(OBJ): fileio.c $(UNZIP_H) crc32.h crypt.h ttyio.h ebcdic.h |
globals$(OBJ): globals.c $(UNZIP_H) |
inflate$(OBJ): inflate.c $(UNZIP_H) |
list$(OBJ): list.c $(UNZIP_H) |
match$(OBJ): match.c $(UNZIP_H) |
process$(OBJ): process.c $(UNZIP_H) crc32.h |
ttyio$(OBJ): ttyio.c $(UNZIP_H) zip.h crypt.h ttyio.h |
ubz2err$(OBJ): ubz2err.c $(UNZIP_H) |
unreduce$(OBJ): unreduce.c $(UNZIP_H) |
unshrink$(OBJ): unshrink.c $(UNZIP_H) |
unzip$(OBJ): unzip.c $(UNZIP_H) crypt.h unzvers.h consts.h |
api$(OBJ): api.c $(UNZIP_H) unzvers.h |
zipinfo$(OBJ): zipinfo.c $(UNZIP_H) |
unzipstb$(OBJ): unzipstb.c # DLL version |
$(CC) -c $(CFLAGS) unzipstb.c |
msdos$(OBJ): msdos/msdos.c $(UNZIP_H) unzvers.h # DOS only |
$(CC) -c $(CFLAGS) msdos$(DIRSEP)msdos.c |
msdos_$(OBJ): msdos/msdos.c $(UNZIP_H) # DOS unzipsfx |
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ msdos$(DIRSEP)msdos.c |
msdosf$(OBJ): msdos/msdos.c $(UNZIP_H) # DOS funzip |
$(CC) -c $(CFLAGS) -DFUNZII $(OUT)$@ msdos$(DIRSEP)msdos.c |
win32$(OBJ): win32/win32.c $(UNZIP_H) win32/nt.h unzvers.h # Win32 only |
$(CC) -c $(CFLAGS) win32$(DIRSEP)win32.c |
nt$(OBJ): win32/nt.c $(UNZIP_H) win32/nt.h # Win32 only |
$(CC) -c $(CFLAGS) win32$(DIRSEP)nt.c |
win32_$(OBJ): win32/win32.c $(UNZIP_H) win32/nt.h # Win32 unzipsfx |
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ win32$(DIRSEP)win32.c |
nt_$(OBJ): win32/nt.c $(UNZIP_H) win32/nt.h # Win32 unzipsfx |
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ win32$(DIRSEP)nt.c |
win32f$(OBJ): win32/win32.c $(UNZIP_H) win32/nt.h # Win32 funzip |
$(CC) -c $(CFLAGS) -DFUNZIP $(OUT)$@ win32$(DIRSEP)win32.c |
os2$(OBJ): os2/os2.c $(UNZIP_H) unzvers.h # OS/2 only |
$(CC) -c $(CFLAGS) $(DLLFLAG) os2$(DIRSEP)os2.c |
os2_$(OBJ): os2/os2.c $(UNZIP_H) # OS/2 unzipsfx |
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ os2$(DIRSEP)os2.c |
os2f$(OBJ): os2/os2.c $(UNZIP_H) # OS/2 funzip |
$(CC) -c $(CFLAGS) -DFUNZIP $(OUT)$@ os2$(DIRSEP)os2.c |
os2acl$(OBJ): os2/os2acl.c $(UNZIP_H) unzvers.h # OS/2 only |
$(CC) -c $(CFLAGS) $(DLLFLAG) os2$(DIRSEP)os2acl.c |
os2acl_$(OBJ): os2/os2acl.c $(UNZIP_H) unzvers.h # OS/2 unzipsfx |
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ os2$(DIRSEP)os2acl.c |
rexxhelp$(OBJ): os2/rexxhelp.c # OS/2 DLL only |
$(CC) -c $(CFLAGS) $(DLLFLAG) os2$(DIRSEP)rexxhelp.c |
rexxapi$(OBJ): os2/rexxapi.c # OS/2 DLL only |
$(CC) -c $(CFLAGS) $(DLLFLAG) os2$(DIRSEP)rexxapi.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 |
# NFLAGS are solely used as work-around for optimization bug in IBM C++ Set |
crypt$(OBJ): crypt.c $(UNZIP_H) zip.h crypt.h crc32.h ttyio.h |
$(CC) -c $(CFLAGS) $(DLLFLAG) $(NFLAGS) crypt.c |
# funzip compilation section |
funzip$(OBJ): funzip.c $(UNZIP_H) crc32.h crypt.h ttyio.h |
$(CC) -c $(CFLAGS) funzip.c |
crc32f$(OBJ): crc32.c $(UNZIP_H) zip.h crc32.h |
$(CC) -c $(CFLAGS) -DFUNZIP $(OUT)$@ crc32.c |
cryptf$(OBJ): crypt.c $(UNZIP_H) zip.h crypt.h crc32.h ttyio.h |
$(CC) -c $(CFLAGS) $(NFLAGS) -DFUNZIP $(OUT)$@ crypt.c |
globalsf$(OBJ): globals.c $(UNZIP_H) |
$(CC) -c $(CFLAGS) -DFUNZIP $(OUT)$@ globals.c |
inflatef$(OBJ): inflate.c inflate.h $(UNZIP_H) crypt.h |
$(CC) -c $(CFLAGS) -DFUNZIP $(OUT)$@ inflate.c |
ttyiof$(OBJ): ttyio.c $(UNZIP_H) zip.h crypt.h ttyio.h |
$(CC) -c $(CFLAGS) $(NFLAGS) -DFUNZIP $(OUT)$@ ttyio.c |
# unzipsfx compilation section |
crc32_$(OBJ): crc32.c $(UNZIP_H) zip.h crc32.h |
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ crc32.c |
crypt_$(OBJ): crypt.c $(UNZIP_H) zip.h crypt.h crc32.h ttyio.h |
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ crypt.c |
extract_$(OBJ): extract.c $(UNZIP_H) crypt.h |
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ extract.c |
fileio_$(OBJ): fileio.c $(UNZIP_H) crc32.h crypt.h ttyio.h ebcdic.h |
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ fileio.c |
globals_$(OBJ): globals.c $(UNZIP_H) |
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ globals.c |
inflate_$(OBJ): inflate.c inflate.h $(UNZIP_H) crypt.h |
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ inflate.c |
match_$(OBJ): match.c $(UNZIP_H) |
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ match.c |
process_$(OBJ): process.c $(UNZIP_H) crc32.h |
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ process.c |
ttyio_$(OBJ): ttyio.c $(UNZIP_H) zip.h crypt.h ttyio.h |
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ ttyio.c |
ubz2err_$(OBJ): ubz2err.c $(UNZIP_H) |
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ ubz2err.c |
unzipsf_$(OBJ): unzip.c $(UNZIP_H) crypt.h unzvers.h consts.h |
$(CC) -c $(CFLAGS) -DSFX $(OUT)$@ unzip.c |
/programs/fs/unzip60/os2/os2.c |
---|
0,0 → 1,2412 |
/* |
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, both of these files are missing, the Info-ZIP license |
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html |
*/ |
/*--------------------------------------------------------------------------- |
os2.c |
OS/2-specific routines for use with Info-ZIP's UnZip 5.1 and later. |
This file contains the OS/2 versions of the file name/attribute/time/etc |
code. Most or all of the routines which make direct use of OS/2 system |
calls (i.e., the non-lowercase routines) are Kai Uwe Rommel's. The read- |
dir() suite was written by Michael Rendell and ported to OS/2 by Kai Uwe; |
it is in the public domain. |
Contains: GetCountryInfo() |
SetFileSize() |
GetFileTime() |
SetFileTime() (TIMESTAMP only) |
stamp_file() (TIMESTAMP only) |
Utime2DosDateTime() |
SetPathAttrTimes() |
SetEAs() |
GetLoadPath() |
opendir() |
closedir() |
readdir() |
[ seekdir() ] not used |
[ telldir() ] not used |
free_dircontents() |
getdirent() |
IsFileSystemFAT() |
do_wild() |
mapattr() |
mapname() |
checkdir() |
isfloppy() |
IsFileNameValid() |
map2fat() |
SetLongNameEA() |
close_outfile() |
check_for_newer() |
dateformat() |
version() |
zcalloc() (16-bit, only) |
zcfree() (16-bit, only) |
InitNLS() |
IsUpperNLS() |
ToLowerNLS() |
StringLower() |
screensize() |
DebugMalloc() |
---------------------------------------------------------------------------*/ |
#define UNZIP_INTERNAL |
#include "unzip.h" |
/* fUnZip does not need anything from here except the zcalloc() & zcfree() |
* function pair (when Deflate64 support is enabled in 16-bit environment). |
*/ |
#ifndef FUNZIP |
#include "os2acl.h" |
extern ZCONST char Far TruncEAs[]; |
/* local prototypes */ |
#ifdef TIMESTAMP |
static int SetFileTime(ZCONST char *name, ulg stamp); |
#endif |
#if defined(USE_EF_UT_TIME) || defined(TIMESTAMP) |
static ulg Utime2DosDateTime OF((time_t uxtime)); |
#endif |
static int getOS2filetimes OF((__GPRO__ |
ulg *pM_dt, ulg *pA_dt, ulg *pC_dt)); |
static void SetPathAttrTimes OF((__GPRO__ int flags, int dir)); |
static int SetEAs OF((__GPRO__ const char *path, |
void *ef_block)); |
static int SetACL OF((__GPRO__ const char *path, |
void *ef_block)); |
static int EvalExtraFields OF((__GPRO__ const char *path, |
void *extra_field, unsigned ef_len)); |
static int isfloppy OF((int nDrive)); |
static int IsFileNameValid OF((const char *name)); |
static void map2fat OF((char *pathcomp, char **pEndFAT)); |
static int SetLongNameEA OF((char *name, char *longname)); |
static void InitNLS OF((void)); |
#ifdef ACORN_FTYPE_NFS |
/* Acorn bits for NFS filetyping */ |
typedef struct { |
uch ID[2]; |
uch size[2]; |
uch ID_2[4]; |
uch loadaddr[4]; |
uch execaddr[4]; |
uch attr[4]; |
} RO_extra_block; |
#endif /* ACORN_FTYPE_NFS */ |
/*****************************/ |
/* Strings used in os2.c */ |
/*****************************/ |
#ifndef SFX |
static ZCONST char Far CantAllocateWildcard[] = |
"warning: cannot allocate wildcard buffers\n"; |
#endif |
static ZCONST char Far WarnDirTraversSkip[] = |
"warning: skipped \"../\" path component(s) in %s\n"; |
static ZCONST char Far Creating[] = " creating: %-22s "; |
static ZCONST char Far ConversionFailed[] = |
"mapname: conversion of %s failed\n"; |
static ZCONST char Far Labelling[] = "labelling %c: %-22s\n"; |
static ZCONST char Far ErrSetVolLabel[] = |
"mapname: error setting volume label\n"; |
static ZCONST char Far PathTooLong[] = "checkdir error: path too long: %s\n"; |
static ZCONST char Far CantCreateDir[] = "checkdir error: cannot create %s\n\ |
unable to process %s.\n"; |
static ZCONST char Far DirIsntDirectory[] = |
"checkdir error: %s exists but is not directory\n\ |
unable to process %s.\n"; |
static ZCONST char Far PathTooLongTrunc[] = |
"checkdir warning: path too long; truncating\n %s\n\ |
-> %s\n"; |
#if (!defined(SFX) || defined(SFX_EXDIR)) |
static ZCONST char Far CantCreateExtractDir[] = |
"checkdir: cannot create extraction directory: %s\n"; |
#endif |
#ifndef __GNUC__ |
/* all supported non-gcc compilers provide MSC/DOS style mkdir() */ |
# if (_MSC_VER >= 600) || defined(__IBMC__) |
# include <direct.h> /* have special MSC/IBM C mkdir prototype */ |
# else /* own prototype because dir.h conflicts? */ |
int mkdir(const char *path); |
# endif |
# define MKDIR(path,mode) mkdir(path) |
#else |
/* EMX and hopefully all other gcc ports support POSIX style mkdir() */ |
# define MKDIR(path,mode) mkdir(path,mode) |
#endif |
#ifdef __32BIT__ |
USHORT DosDevIOCtl32(PVOID pData, USHORT cbData, PVOID pParms, USHORT cbParms, |
USHORT usFunction, USHORT usCategory, HFILE hDevice) |
{ |
ULONG ulParmLengthInOut = cbParms, ulDataLengthInOut = cbData; |
return (USHORT) DosDevIOCtl(hDevice, usCategory, usFunction, |
pParms, cbParms, &ulParmLengthInOut, |
pData, cbData, &ulDataLengthInOut); |
} |
# define DosDevIOCtl DosDevIOCtl32 |
#else |
# define DosDevIOCtl DosDevIOCtl2 |
#endif |
typedef struct |
{ |
ush nID; |
ush nSize; |
ulg lSize; |
} |
EFHEADER, *PEFHEADER; |
#ifdef __32BIT__ |
#define DosFindFirst(p1, p2, p3, p4, p5, p6) \ |
DosFindFirst(p1, p2, p3, p4, p5, p6, 1) |
#else |
typedef struct |
{ |
ULONG oNextEntryOffset; |
BYTE fEA; |
BYTE cbName; |
USHORT cbValue; |
CHAR szName[1]; |
} |
FEA2, *PFEA2; |
typedef struct |
{ |
ULONG cbList; |
FEA2 list[1]; |
} |
FEA2LIST, *PFEA2LIST; |
#define DosQueryCurrentDisk DosQCurDisk |
#define DosQueryFSAttach(p1, p2, p3, p4, p5) \ |
DosQFSAttach(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 |
#define DosSetPathInfo(p1, p2, p3, p4, p5) \ |
DosSetPathInfo(p1, p2, p3, p4, p5, 0) |
#define DosQueryPathInfo(p1, p2, p3, p4) \ |
DosQPathInfo(p1, p2, p3, p4, 0) |
#define DosQueryFileInfo DosQFileInfo |
#define DosMapCase DosCaseMap |
#define DosQueryCtryInfo DosGetCtryInfo |
#endif /* !__32BIT__ */ |
/* |
* @(#) dir.h 1.4 87/11/06 Public Domain. |
*/ |
#define A_RONLY 0x01 |
#define A_HIDDEN 0x02 |
#define A_SYSTEM 0x04 |
#define A_LABEL 0x08 |
#define A_DIR 0x10 |
#define A_ARCHIVE 0x20 |
const int attributes = A_DIR | A_HIDDEN | A_SYSTEM; |
extern DIR *opendir(__GPRO__ ZCONST char *); |
extern struct direct *readdir(__GPRO__ DIR *); |
extern void seekdir(DIR *, long); |
extern long telldir(DIR *); |
extern void closedir(DIR *); |
#define rewinddir(dirp) seekdir(dirp, 0L) |
int IsFileSystemFAT(__GPRO__ ZCONST char *dir); |
char *StringLower(char *szArg); |
/* |
* @(#)dir.c 1.4 87/11/06 Public Domain. |
*/ |
#ifndef S_IFMT |
# define S_IFMT 0xF000 |
#endif |
#ifndef SFX |
static char *getdirent(__GPRO__ ZCONST char *); |
static void free_dircontents(struct _dircontents *); |
#endif /* !SFX */ |
int GetCountryInfo(void) |
{ |
COUNTRYINFO ctryi; |
COUNTRYCODE ctryc; |
#ifdef __32BIT__ |
ULONG cbInfo; |
#else |
USHORT cbInfo; |
#endif |
ctryc.country = ctryc.codepage = 0; |
if ( DosQueryCtryInfo(sizeof(ctryi), &ctryc, &ctryi, &cbInfo) != NO_ERROR ) |
return 0; |
return ctryi.fsDateFmt; |
} |
int SetFileSize(FILE *file, ulg filesize) |
{ |
#ifdef __32BIT__ |
return DosSetFileSize(fileno(file), (size_t)filesize) ? -1 : 0; |
#else |
return 0; |
#endif |
} |
long GetFileTime(ZCONST char *name) |
{ |
#ifdef __32BIT__ |
FILESTATUS3 fs; |
#else |
FILESTATUS fs; |
#endif |
USHORT nDate, nTime; |
if ( DosQueryPathInfo((PSZ) name, 1, (PBYTE) &fs, sizeof(fs)) ) |
return -1; |
nDate = * (USHORT *) &fs.fdateLastWrite; |
nTime = * (USHORT *) &fs.ftimeLastWrite; |
return ((ULONG) nDate) << 16 | nTime; |
} |
#ifdef TIMESTAMP |
static int SetFileTime(ZCONST char *name, ulg stamp) /* swiped from Zip */ |
{ |
FILESTATUS fs; |
USHORT fd, ft; |
if (DosQueryPathInfo((PSZ) name, FIL_STANDARD, (PBYTE) &fs, sizeof(fs))) |
return -1; |
fd = (USHORT) (stamp >> 16); |
ft = (USHORT) stamp; |
fs.fdateLastWrite = fs.fdateCreation = * (FDATE *) &fd; |
fs.ftimeLastWrite = fs.ftimeCreation = * (FTIME *) &ft; |
if (DosSetPathInfo((PSZ) name, FIL_STANDARD, (PBYTE) &fs, sizeof(fs), 0)) |
return -1; |
return 0; |
} |
int stamp_file(ZCONST char *fname, time_t modtime) |
{ |
return SetFileTime(fname, Utime2DosDateTime(modtime)); |
} |
#endif /* TIMESTAMP */ |
/* The following DOS date/time structures are machine-dependent as they |
* assume "little-endian" byte order. For OS/2-specific code, which |
* is run on x86 CPUs (or emulators?), this assumption is valid; but |
* care should be taken when using this code as template for other ports. |
*/ |
typedef union { |
ULONG timevalue; /* combined value, useful for comparisons */ |
struct { |
FTIME ft; /* system file time record: |
* USHORT twosecs : 5 |
* USHORT minutes : 6; |
* USHORT hours : 5; */ |
FDATE fd; /* system file date record: |
* USHORT day : 5 |
* USHORT month : 4; |
* USHORT year : 7; */ |
} _fdt; |
} F_DATE_TIME, *PF_DATE_TIME; |
#if defined(USE_EF_UT_TIME) || defined(TIMESTAMP) |
static ulg Utime2DosDateTime(uxtime) |
time_t uxtime; |
{ |
F_DATE_TIME dosfiletime; |
struct tm *t; |
/* round up to even seconds */ |
/* round up (down if "up" overflows) to even seconds */ |
if (((ulg)uxtime) & 1) |
uxtime = (uxtime + 1 > uxtime) ? uxtime + 1 : uxtime - 1; |
t = localtime(&(uxtime)); |
if (t == (struct tm *)NULL) { |
/* time conversion error; use current time instead, hoping |
that localtime() does not reject it as well! */ |
time_t now = time(NULL); |
t = localtime(&now); |
} |
if (t->tm_year < 80) { |
dosfiletime._fdt.ft.twosecs = 0; |
dosfiletime._fdt.ft.minutes = 0; |
dosfiletime._fdt.ft.hours = 0; |
dosfiletime._fdt.fd.day = 1; |
dosfiletime._fdt.fd.month = 1; |
dosfiletime._fdt.fd.year = 0; |
} else { |
dosfiletime._fdt.ft.twosecs = t->tm_sec >> 1; |
dosfiletime._fdt.ft.minutes = t->tm_min; |
dosfiletime._fdt.ft.hours = t->tm_hour; |
dosfiletime._fdt.fd.day = t->tm_mday; |
dosfiletime._fdt.fd.month = t->tm_mon + 1; |
dosfiletime._fdt.fd.year = t->tm_year - 80; |
} |
return dosfiletime.timevalue; |
} /* end function Utime2DosDateTime() */ |
#endif /* USE_EF_UT_TIME || TIMESTAMP */ |
static int getOS2filetimes(__GPRO__ ulg *pM_dt, ulg *pA_dt, ulg *pC_dt) |
{ |
#ifdef USE_EF_UT_TIME |
unsigned eb_izux_flg; |
iztimes z_utime; |
#endif |
/* Copy and/or convert time and date variables, if necessary; */ |
/* return a flag indicating which time stamps are available. */ |
#ifdef USE_EF_UT_TIME |
if (G.extra_field && |
#ifdef IZ_CHECK_TZ |
G.tz_is_valid && |
#endif |
((eb_izux_flg = ef_scan_for_izux(G.extra_field, |
G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime, |
&z_utime, NULL)) & EB_UT_FL_MTIME)) |
{ |
TTrace((stderr, "getOS2filetimes: UT e.f. modif. time = %lu\n", |
z_utime.mtime)); |
*pM_dt = Utime2DosDateTime(z_utime.mtime); |
if (eb_izux_flg & EB_UT_FL_ATIME) { |
TTrace((stderr, "getOS2filetimes: UT e.f. access time = %lu\n", |
z_utime.atime)); |
*pA_dt = Utime2DosDateTime(z_utime.atime); |
} |
if (eb_izux_flg & EB_UT_FL_CTIME) { |
TTrace((stderr, "getOS2filetimes: UT e.f. creation time = %lu\n", |
z_utime.ctime)); |
*pC_dt = Utime2DosDateTime(z_utime.ctime); |
} else { |
/* no creation time value supplied, set it to modification time */ |
*pC_dt = *pM_dt; |
eb_izux_flg |= EB_UT_FL_CTIME; |
} |
return (int)eb_izux_flg; |
} |
#endif /* USE_EF_UT_TIME */ |
*pC_dt = *pM_dt = G.lrec.last_mod_dos_datetime; |
TTrace((stderr, "\ngetOS2filetimes: DOS dir modific./creation time = %lu\n", |
*pM_dt)); |
return (EB_UT_FL_MTIME | EB_UT_FL_CTIME); |
} |
static void SetPathAttrTimes(__GPRO__ int flags, int dir) |
{ |
HFILE hFile; |
#ifdef __32BIT__ |
ULONG nAction; |
#else |
USHORT nAction; |
#endif |
FILESTATUS fs; |
USHORT nLength; |
char szName[CCHMAXPATH]; |
ulg Mod_dt, Acc_dt, Cre_dt; |
int gotTimes; |
strcpy(szName, G.filename); |
nLength = strlen(szName); |
if (szName[nLength - 1] == '/') |
szName[nLength - 1] = 0; |
if (dir) |
{ |
if ( DosQueryPathInfo(szName, FIL_STANDARD, (PBYTE) &fs, sizeof(fs)) ) |
return; |
} |
else |
{ |
/* for regular files, open them and operate on the file handle, to |
work around certain network operating system bugs ... */ |
if ( DosOpen(szName, &hFile, &nAction, 0, 0, |
OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW, |
OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READWRITE, 0) ) |
return; |
if ( DosQueryFileInfo(hFile, FIL_STANDARD, (PBYTE) &fs, sizeof(fs)) ) |
return; |
} |
if (uO.D_flag <= (dir ? 1 : 0)) { |
/* set date/time stamps */ |
gotTimes = getOS2filetimes(__G__ &Mod_dt, &Acc_dt, &Cre_dt); |
if (gotTimes & EB_UT_FL_MTIME) { |
fs.fdateLastWrite = ((F_DATE_TIME *)&Mod_dt)->_fdt.fd; |
fs.ftimeLastWrite = ((F_DATE_TIME *)&Mod_dt)->_fdt.ft; |
} |
if (gotTimes & EB_UT_FL_ATIME) { |
fs.fdateLastAccess = ((F_DATE_TIME *)&Acc_dt)->_fdt.fd; |
fs.ftimeLastAccess = ((F_DATE_TIME *)&Acc_dt)->_fdt.ft; |
} |
if (gotTimes & EB_UT_FL_CTIME) { |
fs.fdateCreation = ((F_DATE_TIME *)&Cre_dt)->_fdt.fd; |
fs.ftimeCreation = ((F_DATE_TIME *)&Cre_dt)->_fdt.ft; |
} |
} |
if ( flags != -1 ) |
fs.attrFile = flags; /* hidden, system, archive, read-only */ |
if (dir) |
{ |
DosSetPathInfo(szName, FIL_STANDARD, (PBYTE) &fs, sizeof(fs), 0); |
} |
else |
{ |
DosSetFileInfo(hFile, FIL_STANDARD, (PBYTE) &fs, sizeof(fs)); |
DosClose(hFile); |
} |
} |
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; |
static int SetEAs(__GPRO__ const char *path, void *ef_block) |
{ /* returns almost-PK errors */ |
EFHEADER *pEAblock = (PEFHEADER) ef_block; |
#ifdef __32BIT__ |
EAOP2 eaop; |
PFEA2LIST pFEA2list; |
#else |
EAOP eaop; |
PFEALIST pFEAlist; |
PFEA pFEA; |
PFEA2LIST pFEA2list; |
PFEA2 pFEA2; |
ULONG nLength2; |
#endif |
USHORT nLength; |
char szName[CCHMAXPATH]; |
int error; |
if ( ef_block == NULL || pEAblock -> nID != EF_OS2 ) |
return PK_OK; /* not an OS/2 extra field: assume OK */ |
if ( pEAblock->nSize < 4 || (pEAblock->lSize > 0L && pEAblock->nSize <= 10) ) |
return IZ_EF_TRUNC; /* no compressed data! */ |
strcpy(szName, path); |
nLength = strlen(szName); |
if (szName[nLength - 1] == '/') |
szName[nLength - 1] = 0; |
if ( (pFEA2list = (PFEA2LIST) malloc((size_t) pEAblock -> lSize)) == NULL ) |
return PK_MEM4; |
if ( (error = memextract(__G__ (uch *)pFEA2list, pEAblock->lSize, |
(uch *)(pEAblock+1), (ulg)(pEAblock->nSize - 4))) != PK_OK ) |
{ |
free(pFEA2list); |
return error; |
} |
#ifdef __32BIT__ |
eaop.fpGEA2List = NULL; |
eaop.fpFEA2List = pFEA2list; |
#else |
pFEAlist = (PVOID) pFEA2list; |
pFEA2 = pFEA2list -> list; |
pFEA = pFEAlist -> list; |
do |
{ |
nLength2 = pFEA2 -> oNextEntryOffset; |
nLength = sizeof(FEA) + pFEA2 -> cbName + 1 + pFEA2 -> cbValue; |
memcpy(pFEA, (PCH) pFEA2 + sizeof(pFEA2 -> oNextEntryOffset), nLength); |
pFEA2 = (PFEA2) ((PCH) pFEA2 + nLength2); |
pFEA = (PFEA) ((PCH) pFEA + nLength); |
} |
while ( nLength2 != 0 ); |
pFEAlist -> cbList = (PCH) pFEA - (PCH) pFEAlist; |
eaop.fpGEAList = NULL; |
eaop.fpFEAList = pFEAlist; |
#endif |
eaop.oError = 0; |
DosSetPathInfo(szName, FIL_QUERYEASIZE, (PBYTE) &eaop, sizeof(eaop), 0); |
if (!uO.tflag && QCOND2) |
Info(slide, 0, ((char *)slide, " (%ld bytes EAs)", pFEA2list -> cbList)); |
free(pFEA2list); |
return PK_COOL; |
} |
static int SetACL(__GPRO__ const char *path, void *ef_block) |
{ /* returns almost-PK errors */ |
EFHEADER *pACLblock = (PEFHEADER) ef_block; |
char *szACL; |
int error; |
if ( ef_block == NULL || pACLblock -> nID != EF_ACL ) |
return PK_OK; /* not an OS/2 extra field: assume OK */ |
if (pACLblock->nSize < 4 || (pACLblock->lSize > 0L && pACLblock->nSize <= 10)) |
return IZ_EF_TRUNC; /* no compressed data! */ |
if ( (szACL = malloc((size_t) pACLblock -> lSize)) == NULL ) |
return PK_MEM4; |
if ( (error = memextract(__G__ (uch *)szACL, pACLblock->lSize, |
(uch *)(pACLblock+1), (ulg)(pACLblock->nSize - 4))) != PK_OK ) |
{ |
free(szACL); |
return error; |
} |
if (acl_set(NULL, path, szACL) == 0) |
if (!uO.tflag && QCOND2) |
Info(slide, 0, ((char *)slide, " (%ld bytes ACL)", strlen(szACL))); |
free(szACL); |
return PK_COOL; |
} |
#ifdef SFX |
char *GetLoadPath(__GPRO) |
{ |
#ifdef __32BIT__ /* generic for 32-bit API */ |
PTIB pptib; |
PPIB pppib; |
char *szPath; |
DosGetInfoBlocks(&pptib, &pppib); |
szPath = pppib -> pib_pchenv; |
#else /* 16-bit, note: requires large data model */ |
SEL selEnv; |
USHORT offCmd; |
char *szPath; |
DosGetEnv(&selEnv, &offCmd); |
szPath = MAKEP(selEnv, 0); |
#endif |
while (*szPath) /* find end of process environment */ |
szPath = strchr(szPath, 0) + 1; |
return szPath + 1; /* .exe file name follows environment */ |
} /* end function GetLoadPath() */ |
#else /* !SFX */ |
DIR *opendir(__GPRO__ const char *name) |
{ |
struct stat statb; |
DIR *dirp; |
char c; |
char *s; |
struct _dircontents *dp; |
char nbuf[MAXPATHLEN + 1]; |
int len; |
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; |
} |
/* GRR: Borland and Watcom C return non-zero on wildcards... < 0 ? */ |
if (stat(nbuf, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR) |
{ |
Trace((stderr, "opendir: stat(%s) returns negative or not directory\n", |
FnFilter1(nbuf))); |
return NULL; |
} |
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) */ |
Trace((stderr, "opendir: nbuf = [%s]\n", FnFilter1(nbuf))); |
dirp -> dd_loc = 0; |
dirp -> dd_contents = dirp -> dd_cp = NULL; |
if ((s = getdirent(__G__ 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 = G.os2.find.cbFile; |
dp -> _d_mode = G.os2.find.attrFile; |
dp -> _d_time = *(unsigned *) &(G.os2.find.ftimeLastWrite); |
dp -> _d_date = *(unsigned *) &(G.os2.find.fdateLastWrite); |
} |
while ((s = getdirent(__G__ NULL)) != NULL); |
dirp -> dd_cp = dirp -> dd_contents; |
return dirp; |
} |
void closedir(DIR * dirp) |
{ |
free_dircontents(dirp -> dd_contents); |
free(dirp); |
} |
struct direct *readdir(__GPRO__ DIR * dirp) |
{ |
/* moved to os2data.h so it can be global */ |
/* static struct direct dp; */ |
if (dirp -> dd_cp == NULL) |
return NULL; |
G.os2.dp.d_namlen = G.os2.dp.d_reclen = |
strlen(strcpy(G.os2.dp.d_name, dirp -> dd_cp -> _d_entry)); |
G.os2.dp.d_ino = 0; |
G.os2.dp.d_size = dirp -> dd_cp -> _d_size; |
G.os2.dp.d_mode = dirp -> dd_cp -> _d_mode; |
G.os2.dp.d_time = dirp -> dd_cp -> _d_time; |
G.os2.dp.d_date = dirp -> dd_cp -> _d_date; |
dirp -> dd_cp = dirp -> dd_cp -> _d_next; |
dirp -> dd_loc++; |
return &G.os2.dp; |
} |
#if 0 /* not used in unzip; retained for possibly future use */ |
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; |
} |
#endif /* 0 */ |
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(__GPRO__ ZCONST char *dir) |
{ |
int done; |
/* moved to os2data.h so it can be global */ |
/* static int lower; */ |
if (dir != NULL) |
{ /* get first entry */ |
G.os2.hdir = HDIR_SYSTEM; |
G.os2.count = 1; |
done = DosFindFirst((PSZ) dir, &G.os2.hdir, attributes, |
&G.os2.find, sizeof(G.os2.find), &G.os2.count); |
G.os2.lower = IsFileSystemFAT(__G__ dir); |
} |
else /* get next entry */ |
done = DosFindNext(G.os2.hdir, |
&G.os2.find, sizeof(G.os2.find), &G.os2.count); |
if (done == 0) |
{ |
if ( G.os2.lower ) |
StringLower(G.os2.find.achName); |
return G.os2.find.achName; |
} |
else |
{ |
DosFindClose(G.os2.hdir); |
return NULL; |
} |
} |
int IsFileSystemFAT(__GPRO__ ZCONST char *dir) /* FAT / HPFS detection */ |
{ |
/* moved to os2data.h so they can be global */ |
/* static USHORT nLastDrive=(USHORT)(-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 case sensitive */ |
if ( isalpha((uch)dir[0]) && (dir[1] == ':') ) |
nDrive = toupper(dir[0]) - '@'; |
else |
DosQueryCurrentDisk(&nDrive, &lMap); |
if ( nDrive == G.os2.nLastDrive ) |
return G.os2.nResult; |
bName[0] = (char) (nDrive + '@'); |
bName[1] = ':'; |
bName[2] = 0; |
G.os2.nLastDrive = nDrive; |
cbData = sizeof(bData); |
if ( !DosQueryFSAttach(bName, 0, FSAIL_QUERYNAME, (PVOID) pData, &cbData) ) |
G.os2.nResult = !strcmp((char *) (pData -> szFSDName) + pData -> cbName, |
"FAT"); |
else |
G.os2.nResult = FALSE; |
/* End of this ugly code */ |
return G.os2.nResult; |
} /* end function IsFileSystemFAT() */ |
/************************/ |
/* Function do_wild() */ |
/************************/ |
char *do_wild(__G__ wildspec) |
__GDEF |
ZCONST char *wildspec; /* only used first time on a given dir */ |
{ |
/* moved to os2data.h so they can be global */ |
#if 0 |
static DIR *wild_dir = NULL; |
static ZCONST char *wildname; |
static char *dirname, matchname[FILNAMSIZ]; |
static int notfirstcall=FALSE, have_dirname, dirnamelen; |
#endif |
char *fnamestart; |
struct direct *file; |
/* Even when we're just returning wildspec, we *always* do so in |
* matchname[]--calling routine is allowed to append four characters |
* to the returned string, and wildspec may be a pointer to argv[]. |
*/ |
if (!G.os2.notfirstcall) { /* first call: must initialize everything */ |
G.os2.notfirstcall = TRUE; |
if (!iswild(wildspec)) { |
strncpy(G.os2.matchname, wildspec, FILNAMSIZ); |
G.os2.matchname[FILNAMSIZ-1] = '\0'; |
G.os2.have_dirname = FALSE; |
G.os2.wild_dir = NULL; |
return G.os2.matchname; |
} |
/* break the wildspec into a directory part and a wildcard filename */ |
if ((G.os2.wildname = (ZCONST char *)strrchr(wildspec, '/')) == NULL && |
(G.os2.wildname = (ZCONST char *)strrchr(wildspec, ':')) == NULL) { |
G.os2.dirname = "."; |
G.os2.dirnamelen = 1; |
G.os2.have_dirname = FALSE; |
G.os2.wildname = wildspec; |
} else { |
++G.os2.wildname; /* point at character after '/' or ':' */ |
G.os2.dirnamelen = G.os2.wildname - wildspec; |
if ((G.os2.dirname = (char *)malloc(G.os2.dirnamelen+1)) == NULL) { |
Info(slide, 1, ((char *)slide, |
LoadFarString(CantAllocateWildcard))); |
strncpy(G.os2.matchname, wildspec, FILNAMSIZ); |
G.os2.matchname[FILNAMSIZ-1] = '\0'; |
return G.os2.matchname; /* but maybe filespec was not a wildcard */ |
} |
strncpy(G.os2.dirname, wildspec, G.os2.dirnamelen); |
G.os2.dirname[G.os2.dirnamelen] = '\0'; /* terminate for strcpy below */ |
G.os2.have_dirname = TRUE; |
} |
Trace((stderr, "do_wild: dirname = [%s]\n", |
FnFilter1(G.os2.dirname))); |
if ((G.os2.wild_dir = opendir(__G__ G.os2.dirname)) != NULL) { |
if (G.os2.have_dirname) { |
strcpy(G.os2.matchname, G.os2.dirname); |
fnamestart = G.os2.matchname + G.os2.dirnamelen; |
} else |
fnamestart = G.os2.matchname; |
while ((file = readdir(__G__ G.os2.wild_dir)) != NULL) { |
Trace((stderr, "do_wild: readdir returns %s\n", |
FnFilter1(file->d_name))); |
strcpy(fnamestart, file->d_name); |
if (strrchr(fnamestart, '.') == (char *)NULL) |
strcat(fnamestart, "."); |
if (match(fnamestart, G.os2.wildname, 1 WISEP) && |
/* 1 == ignore case */ |
/* skip "." and ".." directory entries */ |
strcmp(fnamestart, ".") && strcmp(fnamestart, "..")) { |
Trace((stderr, "do_wild: match() succeeds\n")); |
/* remove trailing dot */ |
fnamestart += strlen(fnamestart) - 1; |
if (*fnamestart == '.') |
*fnamestart = '\0'; |
return G.os2.matchname; |
} |
} |
/* if we get to here directory is exhausted, so close it */ |
closedir(G.os2.wild_dir); |
G.os2.wild_dir = NULL; |
} |
#ifdef DEBUG |
else { |
Trace((stderr, "do_wild: opendir(%s) returns NULL\n", |
FnFilter1(G.os2.dirname))); |
} |
#endif /* DEBUG */ |
/* return the raw wildspec in case that works (e.g., directory not |
* searchable, but filespec was not wild and file is readable) */ |
strncpy(G.os2.matchname, wildspec, FILNAMSIZ); |
G.os2.matchname[FILNAMSIZ-1] = '\0'; |
return G.os2.matchname; |
} |
/* last time through, might have failed opendir but returned raw wildspec */ |
if (G.os2.wild_dir == NULL) { |
G.os2.notfirstcall = FALSE; /* nothing left to try--reset */ |
if (G.os2.have_dirname) |
free(G.os2.dirname); |
return (char *)NULL; |
} |
/* If we've gotten this far, we've read and matched at least one entry |
* successfully (in a previous call), so dirname has been copied into |
* matchname already. |
*/ |
if (G.os2.have_dirname) { |
/* strcpy(G.os2.matchname, G.os2.dirname); */ |
fnamestart = G.os2.matchname + G.os2.dirnamelen; |
} else |
fnamestart = G.os2.matchname; |
while ((file = readdir(__G__ G.os2.wild_dir)) != NULL) { |
Trace((stderr, "do_wild: readdir returns %s\n", |
FnFilter1(file->d_name))); |
strcpy(fnamestart, file->d_name); |
if (strrchr(fnamestart, '.') == (char *)NULL) |
strcat(fnamestart, "."); |
if (match(fnamestart, G.os2.wildname, 1 WISEP)) { /* 1==ignore case */ |
Trace((stderr, "do_wild: match() succeeds\n")); |
/* remove trailing dot */ |
fnamestart += strlen(fnamestart) - 1; |
if (*fnamestart == '.') |
*fnamestart = '\0'; |
return G.os2.matchname; |
} |
} |
closedir(G.os2.wild_dir); /* have read at least one entry; nothing left */ |
G.os2.wild_dir = NULL; |
G.os2.notfirstcall = FALSE; /* reset for new wildspec */ |
if (G.os2.have_dirname) |
free(G.os2.dirname); |
return (char *)NULL; |
} /* end function do_wild() */ |
#endif /* !SFX */ |
/* scan extra fields for something we happen to know */ |
static int EvalExtraFields(__GPRO__ const char *path, |
void *extra_field, unsigned ef_len) |
{ |
char *ef_ptr = extra_field; |
PEFHEADER pEFblock; |
int rc = PK_OK; |
while (ef_len >= sizeof(EFHEADER)) |
{ |
pEFblock = (PEFHEADER) ef_ptr; |
if (pEFblock -> nSize > (ef_len - EB_HEADSIZE)) |
return PK_ERR; /* claimed EFblock length exceeds EF size! */ |
switch (pEFblock -> nID) |
{ |
case EF_OS2: |
rc = SetEAs(__G__ path, ef_ptr); |
break; |
case EF_ACL: |
rc = (uO.X_flag) ? SetACL(__G__ path, ef_ptr) : PK_OK; |
break; |
#if 0 |
case EF_IZUNIX: |
case EF_PKUNIX: |
/* handled elsewhere */ |
break; |
#endif |
default: |
TTrace((stderr,"EvalExtraFields: unknown extra field block, ID=%d\n", |
pEFblock -> nID)); |
break; |
} |
ef_ptr += (pEFblock -> nSize + EB_HEADSIZE); |
ef_len -= (pEFblock -> nSize + EB_HEADSIZE); |
if (rc != PK_OK) |
break; |
} |
return rc; |
} |
/************************/ |
/* Function mapattr() */ |
/************************/ |
int mapattr(__G) |
__GDEF |
{ |
/* set archive bit (file is not backed up): */ |
G.pInfo->file_attr = (unsigned)(G.crec.external_file_attributes | 32) & 0xff; |
return 0; |
} |
/************************/ |
/* Function mapname() */ |
/************************/ |
/* |
* There are presently two possibilities in OS/2: the output filesystem is |
* FAT, or it is HPFS. If the former, we need to map to FAT, obviously, but |
* we *also* must map to HPFS and store that version of the name in extended |
* attributes. Either way, we need to map to HPFS, so the main mapname |
* routine does that. In the case that the output file system is FAT, an |
* extra filename-mapping routine is called in checkdir(). While it should |
* be possible to determine the filesystem immediately upon entry to mapname(), |
* it is conceivable that the DOS APPEND utility could be added to OS/2 some- |
* day, allowing a FAT directory to be APPENDed to an HPFS drive/path. There- |
* fore we simply check the filesystem at each path component. |
* |
* Note that when alternative IFSes become available/popular, everything will |
* become immensely more complicated. For example, a Minix filesystem would |
* have limited filename lengths like FAT but no extended attributes in which |
* to store the longer versions of the names. A BSD Unix filesystem would |
* support paths of length 1024 bytes or more, but it is not clear that FAT |
* EAs would allow such long .LONGNAME fields or that OS/2 would properly |
* restore such fields when moving files from FAT to the new filesystem. |
* |
* GRR: some or all of the following chars should be checked in either |
* mapname (HPFS) or map2fat (FAT), depending: ,=^+'"[]<>|\t& |
*/ |
int mapname(__G__ renamed) |
__GDEF |
int renamed; |
/* |
* returns: |
* MPN_OK - no problem detected |
* MPN_INF_TRUNC - caution (truncated filename) |
* MPN_INF_SKIP - info "skip entry" (dir doesn't exist) |
* MPN_ERR_SKIP - error -> skip entry |
* MPN_ERR_TOOLONG - error -> path is too long |
* MPN_NOMEM - error (memory allocation failed) -> skip entry |
* [also MPN_VOL_LABEL, MPN_CREATED_DIR] |
*/ |
{ |
char pathcomp[FILNAMSIZ]; /* path-component buffer */ |
char *pp, *cp=(char *)NULL; /* character pointers */ |
char *lastsemi=(char *)NULL; /* pointer to last semi-colon in pathcomp */ |
#ifdef ACORN_FTYPE_NFS |
char *lastcomma=(char *)NULL; /* pointer to last comma in pathcomp */ |
RO_extra_block *ef_spark; /* pointer Acorn FTYPE ef block */ |
#endif |
int killed_ddot = FALSE; /* is set when skipping "../" pathcomp */ |
int error = MPN_OK; |
register unsigned workch; /* hold the character being tested */ |
/*--------------------------------------------------------------------------- |
Initialize various pointers and counters and stuff. |
---------------------------------------------------------------------------*/ |
/* can create path as long as not just freshening, or if user told us */ |
G.create_dirs = (!uO.fflag || renamed); |
G.os2.created_dir = FALSE; /* not yet */ |
G.os2.renamed_fullpath = FALSE; |
G.os2.fnlen = strlen(G.filename); |
/* GRR: for VMS, convert to internal format now or later? or never? */ |
if (renamed) { |
cp = G.filename - 1; /* point to beginning of renamed name... */ |
while (*++cp) |
if (*cp == '\\') /* convert backslashes to forward */ |
*cp = '/'; |
cp = G.filename; |
/* use temporary rootpath if user gave full pathname */ |
if (G.filename[0] == '/') { |
G.os2.renamed_fullpath = TRUE; |
pathcomp[0] = '/'; /* copy the '/' and terminate */ |
pathcomp[1] = '\0'; |
++cp; |
} else if (isalpha((uch)G.filename[0]) && G.filename[1] == ':') { |
G.os2.renamed_fullpath = TRUE; |
pp = pathcomp; |
*pp++ = *cp++; /* copy the "d:" (+ '/', possibly) */ |
*pp++ = *cp++; |
if (*cp == '/') |
*pp++ = *cp++; /* otherwise add "./"? */ |
*pp = '\0'; |
} |
} |
/* pathcomp is ignored unless renamed_fullpath is TRUE: */ |
if ((error = checkdir(__G__ pathcomp, INIT)) != 0) /* init path buffer */ |
return error; /* ...unless no mem or vol label on hard disk */ |
*pathcomp = '\0'; /* initialize translation buffer */ |
pp = pathcomp; /* point to translation buffer */ |
if (!renamed) { /* cp already set if renamed */ |
if (uO.jflag) /* junking directories */ |
/* GRR: watch out for VMS version... */ |
cp = (char *)strrchr(G.filename, '/'); |
if (cp == (char *)NULL) /* no '/' or not junking dirs */ |
cp = G.filename; /* point to internal zipfile-member pathname */ |
else |
++cp; /* point to start of last component of path */ |
} |
/*--------------------------------------------------------------------------- |
Begin main loop through characters in filename. |
---------------------------------------------------------------------------*/ |
while ((workch = (uch)*cp++) != 0) { |
switch (workch) { |
case '/': /* can assume -j flag not given */ |
*pp = '\0'; |
if (strcmp(pathcomp, ".") == 0) { |
/* don't bother appending "./" to the path */ |
*pathcomp = '\0'; |
} else if (!uO.ddotflag && strcmp(pathcomp, "..") == 0) { |
/* "../" dir traversal detected, skip over it */ |
*pathcomp = '\0'; |
killed_ddot = TRUE; /* set "show message" flag */ |
} |
/* when path component is not empty, append it now */ |
if (*pathcomp != '\0' && |
((error = checkdir(__G__ pathcomp, APPEND_DIR)) |
& MPN_MASK) > MPN_INF_TRUNC) |
return error; |
pp = pathcomp; /* reset conversion buffer for next piece */ |
lastsemi = (char *)NULL; /* leave direct. semi-colons alone */ |
break; |
case ':': /* drive never stored, so no colon allowed */ |
case '\\': /* "non-dos" FSs may allow '\\' as normal */ |
*pp++ = '_'; /* character in filenames */ |
break; /* -> map invalid chars to underscore */ |
case ';': /* start of VMS version? */ |
lastsemi = pp; /* remove VMS version later... */ |
*pp++ = ';'; /* but keep semicolon for now */ |
break; |
#ifdef ACORN_FTYPE_NFS |
case ',': /* NFS filetype extension */ |
lastcomma = pp; |
*pp++ = ','; /* keep for now; may need to remove */ |
break; /* later, if requested */ |
#endif |
case ' ': /* keep spaces unless specifically */ |
if (uO.sflag) /* requested to change to underscore */ |
*pp++ = '_'; |
else |
*pp++ = ' '; |
break; |
default: |
/* allow ASCII 255 and European characters in filenames: */ |
if (isprint(workch) || workch >= 127) |
*pp++ = (char)workch; |
} /* end switch */ |
} /* end while loop */ |
/* Show warning when stripping insecure "parent dir" path components */ |
if (killed_ddot && QCOND2) { |
Info(slide, 0, ((char *)slide, LoadFarString(WarnDirTraversSkip), |
FnFilter1(G.filename))); |
if (!(error & ~MPN_MASK)) |
error = (error & MPN_MASK) | PK_WARN; |
} |
/*--------------------------------------------------------------------------- |
Report if directory was created (and no file to create: filename ended |
in '/'), check name to be sure it exists, and combine path and name be- |
fore exiting. |
---------------------------------------------------------------------------*/ |
if (G.filename[G.os2.fnlen-1] == '/') { |
checkdir(__G__ G.filename, GETPATH); |
if (G.os2.created_dir) { |
if (QCOND2) |
Info(slide, 0, ((char *)slide, LoadFarString(Creating), |
FnFilter1(G.filename))); |
if (G.extra_field) { /* zipfile extra field has extended attribs */ |
int err = EvalExtraFields(__G__ G.filename, G.extra_field, |
G.lrec.extra_field_length); |
if (err == IZ_EF_TRUNC) { |
if (uO.qflag) |
Info(slide, 1, ((char *)slide, "%-22s ", |
FnFilter1(G.filename))); |
Info(slide, 1, ((char *)slide, LoadFarString(TruncEAs), |
makeword(G.extra_field+2)-10, "\n")); |
} else if (!uO.qflag) |
(*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0); |
} else if (!uO.qflag) |
(*G.message)((zvoid *)&G, (uch *)"\n", 1L, 0); |
/* set date/time stamps */ |
SetPathAttrTimes(__G__ G.pInfo->file_attr & ~A_ARCHIVE, 1); |
/* dir time already set */ |
return (error & ~MPN_MASK) | MPN_CREATED_DIR; |
} else if (G.extra_field && IS_OVERWRT_ALL) { |
/* overwrite EAs of existing directory since user requested it */ |
int err = EvalExtraFields(__G__ G.filename, G.extra_field, |
G.lrec.extra_field_length); |
if (err == IZ_EF_TRUNC) { |
Info(slide, 0x421, ((char *)slide, "%-22s ", |
FnFilter1(G.filename))); |
Info(slide, 0x401, ((char *)slide, LoadFarString(TruncEAs), |
makeword(G.extra_field+2)-10, "\n")); |
} |
/* set date/time stamps (dirs only have creation times) */ |
SetPathAttrTimes(__G__ G.pInfo->file_attr & ~A_ARCHIVE, 1); |
} |
/* dir existed already; don't look for data to extract */ |
return (error & ~MPN_MASK) | MPN_INF_SKIP; |
} |
*pp = '\0'; /* done with pathcomp: terminate it */ |
/* if not saving them, remove VMS version numbers (appended "###") */ |
if (!uO.V_flag && lastsemi) { |
pp = lastsemi + 1; /* semi-colon was kept: expect #s after */ |
while (isdigit((uch)(*pp))) |
++pp; |
if (*pp == '\0') /* only digits between ';' and end: nuke */ |
*lastsemi = '\0'; |
} |
#ifdef ACORN_FTYPE_NFS |
/* translate Acorn filetype information if asked to do so */ |
if (uO.acorn_nfs_ext && |
(ef_spark = (RO_extra_block *) |
getRISCOSexfield(G.extra_field, G.lrec.extra_field_length)) |
!= (RO_extra_block *)NULL) |
{ |
/* file *must* have a RISC OS extra field */ |
long ft = (long)makelong(ef_spark->loadaddr); |
/*32-bit*/ |
if (lastcomma) { |
pp = lastcomma + 1; |
while (isxdigit((uch)(*pp))) ++pp; |
if (pp == lastcomma+4 && *pp == '\0') *lastcomma='\0'; /* nuke */ |
} |
if ((ft & 1<<31)==0) ft=0x000FFD00; |
sprintf(pathcomp+strlen(pathcomp), ",%03x", (int)(ft>>8) & 0xFFF); |
} |
#endif /* ACORN_FTYPE_NFS */ |
if (*pathcomp == '\0') { |
Info(slide, 1, ((char *)slide, LoadFarString(ConversionFailed), |
FnFilter1(G.filename))); |
return (error & ~MPN_MASK) | MPN_ERR_SKIP; |
} |
checkdir(__G__ pathcomp, APPEND_NAME); /* returns 1 if truncated: care? */ |
checkdir(__G__ G.filename, GETPATH); |
Trace((stderr, "mapname returns with filename = [%s] (error = %d)\n\n", |
FnFilter1(G.filename), error)); |
if (G.pInfo->vollabel) { /* set the volume label now */ |
VOLUMELABEL FSInfoBuf; |
/* GRR: "VOLUMELABEL" defined for IBM C and emx, but haven't checked MSC... */ |
strcpy(FSInfoBuf.szVolLabel, G.filename); |
FSInfoBuf.cch = (BYTE)strlen(FSInfoBuf.szVolLabel); |
if (!uO.qflag) |
Info(slide, 0, ((char *)slide, LoadFarString(Labelling), |
(char)(G.os2.nLabelDrive + 'a' - 1), FnFilter1(G.filename))); |
if (DosSetFSInfo(G.os2.nLabelDrive, FSIL_VOLSER, (PBYTE)&FSInfoBuf, |
sizeof(VOLUMELABEL))) |
{ |
Info(slide, 1, ((char *)slide, LoadFarString(ErrSetVolLabel))); |
return (error & ~MPN_MASK) | MPN_ERR_SKIP; |
} |
/* success: skip the "extraction" quietly */ |
return (error & ~MPN_MASK) | MPN_INF_SKIP; |
} |
return error; |
} /* end function mapname() */ |
/***********************/ |
/* Function checkdir() */ |
/***********************/ |
int checkdir(__G__ pathcomp, flag) |
__GDEF |
char *pathcomp; |
int flag; |
/* |
* returns: |
* MPN_OK - no problem detected |
* MPN_INF_TRUNC - (on APPEND_NAME) truncated filename |
* MPN_INF_SKIP - path doesn't exist, not allowed to create |
* MPN_ERR_SKIP - path doesn't exist, tried to create and failed; or path |
* exists and is not a directory, but is supposed to be |
* MPN_ERR_TOOLONG - path is too long |
* MPN_NOMEM - can't allocate memory for filename buffers |
*/ |
{ |
/* moved to os2data.h so they can be global */ |
#if 0 |
static int rootlen = 0; /* length of rootpath */ |
static char *rootpath; /* user's "extract-to" directory */ |
static char *buildpathHPFS; /* full path (so far) to extracted file, */ |
static char *buildpathFAT; /* both HPFS/EA (main) and FAT versions */ |
static char *endHPFS; /* corresponding pointers to end of */ |
static char *endFAT; /* buildpath ('\0') */ |
#endif |
# define FN_MASK 7 |
# define FUNCTION (flag & FN_MASK) |
/*--------------------------------------------------------------------------- |
APPEND_DIR: append the path component to the path being built and check |
for its existence. If doesn't exist and we are creating directories, do |
so for this one; else signal success or error as appropriate. |
---------------------------------------------------------------------------*/ |
if (FUNCTION == APPEND_DIR) { |
char *p = pathcomp; |
int longdirEA, too_long=FALSE; |
Trace((stderr, "appending dir segment [%s]\n", FnFilter1(pathcomp))); |
while ((*G.os2.endHPFS = *p++) != '\0') /* copy to HPFS filename */ |
++G.os2.endHPFS; |
if (IsFileNameValid(G.os2.buildpathHPFS)) { |
longdirEA = FALSE; |
p = pathcomp; |
while ((*G.os2.endFAT = *p++) != '\0') /* copy to FAT filename, too */ |
++G.os2.endFAT; |
} else { |
longdirEA = TRUE; |
/* GRR: check error return? */ |
map2fat(pathcomp, &G.os2.endFAT); /* map, put in FAT fn, update endFAT */ |
} |
/* GRR: could do better check, see if overrunning buffer as we go: |
* check endHPFS-G.os2.buildpathHPFS after each append, set warning variable |
* if within 20 of FILNAMSIZ; then if var set, do careful check when |
* appending. Clear variable when begin new path. */ |
/* next check: need to append '/', at least one-char name, '\0' */ |
if ((G.os2.endHPFS-G.os2.buildpathHPFS) > FILNAMSIZ-3) |
too_long = TRUE; /* check if extracting dir? */ |
#ifdef MSC /* MSC 6.00 bug: stat(non-existent-dir) == 0 [exists!] */ |
if (GetFileTime(G.os2.buildpathFAT) == -1 || stat(G.os2.buildpathFAT, &G.statbuf)) |
#else |
if (stat(G.os2.buildpathFAT, &G.statbuf)) /* path doesn't exist */ |
#endif |
{ |
if (!G.create_dirs) { /* told not to create (freshening) */ |
free(G.os2.buildpathHPFS); |
free(G.os2.buildpathFAT); |
/* path doesn't exist: nothing to do */ |
return MPN_INF_SKIP; |
} |
if (too_long) { /* GRR: should allow FAT extraction w/o EAs */ |
Info(slide, 1, ((char *)slide, LoadFarString(PathTooLong), |
FnFilter1(G.os2.buildpathHPFS))); |
free(G.os2.buildpathHPFS); |
free(G.os2.buildpathFAT); |
/* no room for filenames: fatal */ |
return MPN_ERR_TOOLONG; |
} |
if (MKDIR(G.os2.buildpathFAT, 0777) == -1) { /* create the directory */ |
Info(slide, 1, ((char *)slide, LoadFarString(CantCreateDir), |
FnFilter2(G.os2.buildpathFAT), FnFilter1(G.filename))); |
free(G.os2.buildpathHPFS); |
free(G.os2.buildpathFAT); |
/* path didn't exist, tried to create, failed */ |
return MPN_ERR_SKIP; |
} |
G.os2.created_dir = TRUE; |
/* only set EA if creating directory */ |
/* GRR: need trailing '/' before function call? */ |
if (longdirEA) { |
#ifdef DEBUG |
int e = |
#endif |
SetLongNameEA(G.os2.buildpathFAT, pathcomp); |
Trace((stderr, "APPEND_DIR: SetLongNameEA() returns %d\n", e)); |
} |
} else if (!S_ISDIR(G.statbuf.st_mode)) { |
Info(slide, 1, ((char *)slide, LoadFarString(DirIsntDirectory), |
FnFilter2(G.os2.buildpathFAT), FnFilter1(G.filename))); |
free(G.os2.buildpathHPFS); |
free(G.os2.buildpathFAT); |
/* path existed but wasn't dir */ |
return MPN_ERR_SKIP; |
} |
if (too_long) { |
Info(slide, 1, ((char *)slide, LoadFarString(PathTooLong), |
FnFilter1(G.os2.buildpathHPFS))); |
free(G.os2.buildpathHPFS); |
free(G.os2.buildpathFAT); |
/* no room for filenames: fatal */ |
return MPN_ERR_TOOLONG; |
} |
*G.os2.endHPFS++ = '/'; |
*G.os2.endFAT++ = '/'; |
*G.os2.endHPFS = *G.os2.endFAT = '\0'; |
Trace((stderr, "buildpathHPFS now = [%s]\n", |
FnFilter1(G.os2.buildpathHPFS))); |
Trace((stderr, "buildpathFAT now = [%s]\n", |
FnFilter1(G.os2.buildpathFAT))); |
return MPN_OK; |
} /* end if (FUNCTION == APPEND_DIR) */ |
/*--------------------------------------------------------------------------- |
GETPATH: copy full FAT path to the string pointed at by pathcomp (want |
filename to reflect name used on disk, not EAs; if full path is HPFS, |
buildpathFAT and buildpathHPFS will be identical). Also free both paths. |
---------------------------------------------------------------------------*/ |
if (FUNCTION == GETPATH) { |
Trace((stderr, "getting and freeing FAT path [%s]\n", |
FnFilter1(G.os2.buildpathFAT))); |
Trace((stderr, "freeing HPFS path [%s]\n", |
FnFilter1(G.os2.buildpathHPFS))); |
strcpy(pathcomp, G.os2.buildpathFAT); |
free(G.os2.buildpathFAT); |
free(G.os2.buildpathHPFS); |
G.os2.buildpathHPFS = G.os2.buildpathFAT = G.os2.endHPFS = G.os2.endFAT = (char *)NULL; |
return MPN_OK; |
} |
/*--------------------------------------------------------------------------- |
APPEND_NAME: assume the path component is the filename; append it and |
return without checking for existence. |
---------------------------------------------------------------------------*/ |
if (FUNCTION == APPEND_NAME) { |
char *p = pathcomp; |
int error = MPN_OK; |
Trace((stderr, "appending filename [%s]\n", FnFilter1(pathcomp))); |
/* The buildpathHPFS buffer has been allocated large enough to |
* hold the complete combined name, so there is no need to check |
* for OS filename size limit overflow within the copy loop. |
*/ |
while ((*G.os2.endHPFS = *p++) != '\0') { /* copy to HPFS filename */ |
++G.os2.endHPFS; |
} |
/* Now, check for OS filename size overflow. When detected, the |
* mapped HPFS name is truncated and a warning message is shown. |
*/ |
if ((G.os2.endHPFS-G.os2.buildpathHPFS) >= FILNAMSIZ) { |
G.os2.buildpathHPFS[FILNAMSIZ-1] = '\0'; |
Info(slide, 1, ((char *)slide, LoadFarString(PathTooLongTrunc), |
FnFilter1(G.filename), FnFilter2(G.os2.buildpathHPFS))); |
error = MPN_INF_TRUNC; /* filename truncated */ |
} |
/* GRR: how can longnameEA ever be set before this point??? we don't want |
* to save the original name to EAs if user renamed it, do we? |
* |
* if (!G.os2.longnameEA && ((G.os2.longnameEA = !IsFileNameValid(name)) != 0)) |
*/ |
/* The buildpathFAT buffer has the same allocated size as the |
* buildpathHPFS buffer, so there is no need for an overflow check |
* within the following copy loop, either. |
*/ |
if (G.pInfo->vollabel || IsFileNameValid(G.os2.buildpathHPFS)) { |
G.os2.longnameEA = FALSE; |
/* copy to FAT filename, too */ |
p = pathcomp; |
while ((*G.os2.endFAT = *p++) != '\0') |
++G.os2.endFAT; |
} else { |
G.os2.longnameEA = TRUE; |
if ((G.os2.lastpathcomp = (char *)malloc(strlen(pathcomp)+1)) == |
(char *)NULL) |
{ |
Info(slide, 1, ((char *)slide, |
"checkdir warning: cannot save longname EA: out of memory\n")); |
G.os2.longnameEA = FALSE; |
/* can't set .LONGNAME extended attribute */ |
error = MPN_INF_TRUNC; |
} else /* used and freed in close_outfile() */ |
strcpy(G.os2.lastpathcomp, pathcomp); |
/* map, put in FAT fn, update endFAT */ |
map2fat(pathcomp, &G.os2.endFAT); |
} |
/* Check that the FAT path does not exceed the FILNAMSIZ limit, and |
* truncate when neccessary. |
* Note that truncation can only happen when the HPFS path (which is |
* never shorter than the FAT path) has been already truncated. |
* So, emission of the warning message and setting the error code |
* has already happened. |
*/ |
if ((G.os2.endFAT-G.os2.buildpathFAT) >= FILNAMSIZ) |
G.os2.buildpathFAT[FILNAMSIZ-1] = '\0'; |
Trace((stderr, "buildpathHPFS: %s\nbuildpathFAT: %s\n", |
FnFilter1(G.os2.buildpathHPFS), FnFilter2(G.os2.buildpathFAT))); |
return error; /* could check for existence, prompt for new name... */ |
} /* end if (FUNCTION == APPEND_NAME) */ |
/*--------------------------------------------------------------------------- |
INIT: allocate and initialize buffer space for the file currently being |
extracted. If file was renamed with an absolute path, don't prepend the |
extract-to path. |
---------------------------------------------------------------------------*/ |
if (FUNCTION == INIT) { |
Trace((stderr, "initializing buildpathHPFS and buildpathFAT to ")); |
#ifdef ACORN_FTYPE_NFS |
if ((G.os2.buildpathHPFS = (char *)malloc(G.os2.fnlen+G.os2.rootlen+ |
(uO.acorn_nfs_ext ? 5 : 1))) |
#else |
if ((G.os2.buildpathHPFS = (char *)malloc(G.os2.fnlen+G.os2.rootlen+1)) |
#endif |
== (char *)NULL) |
return MPN_NOMEM; |
#ifdef ACORN_FTYPE_NFS |
if ((G.os2.buildpathFAT = (char *)malloc(G.os2.fnlen+G.os2.rootlen+ |
(uO.acorn_nfs_ext ? 5 : 1))) |
#else |
if ((G.os2.buildpathFAT = (char *)malloc(G.os2.fnlen+G.os2.rootlen+1)) |
#endif |
== (char *)NULL) { |
free(G.os2.buildpathHPFS); |
return MPN_NOMEM; |
} |
if (G.pInfo->vollabel) { /* use root or renamed path, but don't store */ |
/* GRR: for network drives, do strchr() and return IZ_VOL_LABEL if not [1] */ |
if (G.os2.renamed_fullpath && pathcomp[1] == ':') |
*G.os2.buildpathHPFS = (char)ToLower(*pathcomp); |
else if (!G.os2.renamed_fullpath && G.os2.rootlen > 1 && G.os2.rootpath[1] == ':') |
*G.os2.buildpathHPFS = (char)ToLower(*G.os2.rootpath); |
else { |
ULONG lMap; |
DosQueryCurrentDisk(&G.os2.nLabelDrive, &lMap); |
*G.os2.buildpathHPFS = (char)(G.os2.nLabelDrive - 1 + 'a'); |
} |
G.os2.nLabelDrive = *G.os2.buildpathHPFS - 'a' + 1; /* save for mapname() */ |
if (uO.volflag == 0 || *G.os2.buildpathHPFS < 'a' || /* no labels/bogus? */ |
(uO.volflag == 1 && !isfloppy(G.os2.nLabelDrive))) { /* -$: no fixed */ |
free(G.os2.buildpathHPFS); |
free(G.os2.buildpathFAT); |
return MPN_VOL_LABEL; /* skipping with message */ |
} |
*G.os2.buildpathHPFS = '\0'; |
} else if (G.os2.renamed_fullpath) /* pathcomp = valid data */ |
strcpy(G.os2.buildpathHPFS, pathcomp); |
else if (G.os2.rootlen > 0) |
strcpy(G.os2.buildpathHPFS, G.os2.rootpath); |
else |
*G.os2.buildpathHPFS = '\0'; |
G.os2.endHPFS = G.os2.buildpathHPFS; |
G.os2.endFAT = G.os2.buildpathFAT; |
while ((*G.os2.endFAT = *G.os2.endHPFS) != '\0') { |
++G.os2.endFAT; |
++G.os2.endHPFS; |
} |
Trace((stderr, "[%s]\n", FnFilter1(G.os2.buildpathHPFS))); |
return MPN_OK; |
} |
/*--------------------------------------------------------------------------- |
ROOT: if appropriate, store the path in rootpath and create it if neces- |
sary; else assume it's a zipfile member and return. This path segment |
gets used in extracting all members from every zipfile specified on the |
command line. Note that under OS/2 and MS-DOS, if a candidate extract-to |
directory specification includes a drive letter (leading "x:"), it is |
treated just as if it had a trailing '/'--that is, one directory level |
will be created if the path doesn't exist, unless this is otherwise pro- |
hibited (e.g., freshening). |
---------------------------------------------------------------------------*/ |
#if (!defined(SFX) || defined(SFX_EXDIR)) |
if (FUNCTION == ROOT) { |
Trace((stderr, "initializing root path to [%s]\n", |
FnFilter1(pathcomp))); |
if (pathcomp == (char *)NULL) { |
G.os2.rootlen = 0; |
return MPN_OK; |
} |
if (G.os2.rootlen > 0) /* rootpath was already set, nothing to do */ |
return MPN_OK; |
if ((G.os2.rootlen = strlen(pathcomp)) > 0) { |
int had_trailing_pathsep=FALSE, has_drive=FALSE, add_dot=FALSE; |
char *tmproot; |
if ((tmproot = (char *)malloc(G.os2.rootlen+3)) == (char *)NULL) { |
G.os2.rootlen = 0; |
return MPN_NOMEM; |
} |
strcpy(tmproot, pathcomp); |
if (isalpha((uch)tmproot[0]) && tmproot[1] == ':') |
has_drive = TRUE; /* drive designator */ |
if (tmproot[G.os2.rootlen-1] == '/') { |
tmproot[--G.os2.rootlen] = '\0'; |
had_trailing_pathsep = TRUE; |
} |
if (has_drive && (G.os2.rootlen == 2)) { |
if (!had_trailing_pathsep) /* i.e., original wasn't "x:/" */ |
add_dot = TRUE; /* relative path: add '.' before '/' */ |
} else if (G.os2.rootlen > 0) { /* need not check "x:." and "x:/" */ |
#ifdef MSC /* MSC 6.00 bug: stat(non-existent-dir) == 0 [exists!] */ |
if (GetFileTime(tmproot) == -1 || |
SSTAT(tmproot, &G.statbuf) || !S_ISDIR(G.statbuf.st_mode)) |
#else |
if (SSTAT(tmproot, &G.statbuf) || !S_ISDIR(G.statbuf.st_mode)) |
#endif |
{ /* path does not exist */ |
if (!G.create_dirs /* || iswild(tmproot) */ |
) { |
free(tmproot); |
G.os2.rootlen = 0; |
return MPN_INF_SKIP; /* treat as stored file */ |
} |
/* create directory (could add loop here scanning tmproot |
* to create more than one level, but really necessary?) */ |
if (MKDIR(tmproot, 0777) == -1) { |
Info(slide, 1, ((char *)slide, |
LoadFarString(CantCreateExtractDir), |
FnFilter1(tmproot))); |
free(tmproot); |
G.os2.rootlen = 0; |
/* path didn't exist, tried to create, failed: */ |
/* file exists, or need 2+ directory levels */ |
return MPN_ERR_SKIP; |
} |
} |
} |
if (add_dot) /* had just "x:", make "x:." */ |
tmproot[G.os2.rootlen++] = '.'; |
tmproot[G.os2.rootlen++] = '/'; |
tmproot[G.os2.rootlen] = '\0'; |
if ((G.os2.rootpath = realloc(tmproot, G.os2.rootlen+1)) == NULL) { |
free(tmproot); |
G.os2.rootlen = 0; |
return MPN_NOMEM; |
} |
Trace((stderr, "rootpath now = [%s]\n", FnFilter1(G.os2.rootpath))); |
} |
return MPN_OK; |
} |
#endif /* !SFX || SFX_EXDIR */ |
/*--------------------------------------------------------------------------- |
END: free rootpath, immediately prior to program exit. |
---------------------------------------------------------------------------*/ |
if (FUNCTION == END) { |
Trace((stderr, "freeing rootpath\n")); |
if (G.os2.rootlen > 0) { |
free(G.os2.rootpath); |
G.os2.rootlen = 0; |
} |
return MPN_OK; |
} |
return MPN_INVALID; /* should never reach */ |
} /* end function checkdir() */ |
/***********************/ |
/* Function isfloppy() */ /* more precisely, is it removable? */ |
/***********************/ |
static int isfloppy(nDrive) |
int nDrive; /* 1 == A:, 2 == B:, etc. */ |
{ |
uch ParmList[1] = {0}; |
uch DataArea[1] = {0}; |
char Name[3]; |
HFILE handle; |
#ifdef __32BIT__ |
ULONG rc; |
ULONG action; |
#else |
USHORT rc; |
USHORT action; |
#endif |
Name[0] = (char) (nDrive + 'A' - 1); |
Name[1] = ':'; |
Name[2] = 0; |
rc = DosOpen(Name, &handle, &action, 0L, FILE_NORMAL, FILE_OPEN, |
OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR | |
OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE, 0L); |
if (rc == ERROR_NOT_READY) /* must be removable */ |
return TRUE; |
else if (rc) { /* other error: do default a/b heuristic instead */ |
Trace((stderr, "error in DosOpen(DASD): guessing...\n", rc)); |
return (nDrive == 1 || nDrive == 2)? TRUE : FALSE; |
} |
rc = DosDevIOCtl(DataArea, sizeof(DataArea), ParmList, sizeof(ParmList), |
DSK_BLOCKREMOVABLE, IOCTL_DISK, handle); |
DosClose(handle); |
if (rc) { /* again, just check for a/b */ |
Trace((stderr, "error in DosDevIOCtl category IOCTL_DISK, function " |
"DSK_BLOCKREMOVABLE\n (rc = 0x%04x): guessing...\n", rc)); |
return (nDrive == 1 || nDrive == 2)? TRUE : FALSE; |
} else { |
return DataArea[0] ? FALSE : TRUE; |
} |
} /* end function isfloppy() */ |
static int IsFileNameValid(const char *name) |
{ |
HFILE hf; |
#ifdef __32BIT__ |
ULONG uAction; |
#else |
USHORT uAction; |
#endif |
switch( DosOpen((PSZ) 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; |
} |
} |
/**********************/ |
/* Function map2fat() */ |
/**********************/ |
static void map2fat(pathcomp, pEndFAT) |
char *pathcomp, **pEndFAT; |
{ |
char *ppc = pathcomp; /* variable pointer to pathcomp */ |
char *pEnd = *pEndFAT; /* variable pointer to buildpathFAT */ |
char *pBegin = *pEndFAT; /* constant pointer to start of this comp. */ |
char *last_dot = (char *)NULL; /* last dot not converted to underscore */ |
int dotname = FALSE; /* flag: path component begins with dot */ |
/* ("." and ".." don't count) */ |
register unsigned workch; /* hold the character being tested */ |
/* Only need check those characters which are legal in HPFS but not |
* in FAT: to get here, must already have passed through mapname. |
* (GRR: oops, small bug--if char was quoted, no longer have any |
* knowledge of that.) Also must truncate path component to ensure |
* 8.3 compliance... |
*/ |
while ((workch = (uch)*ppc++) != 0) { |
switch (workch) { |
case '[': /* add '"' '+' ',' '=' ?? */ |
case ']': |
*pEnd++ = '_'; /* convert brackets to underscores */ |
break; |
case '.': |
if (pEnd == *pEndFAT) { /* nothing appended yet... */ |
if (*ppc == '\0') /* don't bother appending a */ |
break; /* "./" component to the path */ |
else if (*ppc == '.' && ppc[1] == '\0') { /* "../" */ |
*pEnd++ = '.'; /* add first dot, unchanged... */ |
++ppc; /* skip second dot, since it will */ |
} else { /* be "added" at end of if-block */ |
*pEnd++ = '_'; /* FAT doesn't allow null filename */ |
dotname = TRUE; /* bodies, so map .exrc -> _.exrc */ |
} /* (extra '_' now, "dot" below) */ |
} else if (dotname) { /* found a second dot, but still */ |
dotname = FALSE; /* have extra leading underscore: */ |
*pEnd = '\0'; /* remove it by shifting chars */ |
pEnd = *pEndFAT + 1; /* left one space (e.g., .p1.p2: */ |
while (pEnd[1]) { /* __p1 -> _p1_p2 -> _p1.p2 when */ |
*pEnd = pEnd[1]; /* finished) [opt.: since first */ |
++pEnd; /* two chars are same, can start */ |
} /* shifting at second position] */ |
} |
last_dot = pEnd; /* point at last dot so far... */ |
*pEnd++ = '_'; /* convert dot to underscore for now */ |
break; |
default: |
*pEnd++ = (char)workch; |
} /* end switch */ |
} /* end while loop */ |
*pEnd = '\0'; /* terminate buildpathFAT */ |
/* NOTE: keep in mind that pEnd points to the end of the path |
* component, and *pEndFAT still points to the *beginning* of it... |
* Also note that the algorithm does not try to get too fancy: |
* if there are no dots already, the name either gets truncated |
* at 8 characters or the last underscore is converted to a dot |
* (only if more characters are saved that way). In no case is |
* a dot inserted between existing characters. |
*/ |
if (last_dot == (char *)NULL) { /* no dots: check for underscores... */ |
char *plu = strrchr(pBegin, '_'); /* pointer to last underscore */ |
if (plu == (char *)NULL) { /* no dots, no underscores: truncate at 8 */ |
*pEndFAT += 8; /* chars (could insert '.' and keep 11...) */ |
if (*pEndFAT > pEnd) |
*pEndFAT = pEnd; /* oops...didn't have 8 chars to truncate */ |
else |
**pEndFAT = '\0'; |
} else if (MIN(plu - pBegin, 8) + MIN(pEnd - plu - 1, 3) > 8) { |
last_dot = plu; /* be lazy: drop through to next if-block */ |
} else if ((pEnd - *pEndFAT) > 8) { |
*pEndFAT += 8; /* more fits into just basename than if */ |
**pEndFAT = '\0'; /* convert last underscore to dot */ |
} else |
*pEndFAT = pEnd; /* whole thing fits into 8 chars or less */ |
} |
if (last_dot != (char *)NULL) { /* one dot (or two, in the case of */ |
*last_dot = '.'; /* "..") is OK: put it back in */ |
if ((last_dot - pBegin) > 8) { |
char *p, *q; |
int i; |
p = last_dot; |
q = last_dot = pBegin + 8; |
for (i = 0; (i < 4) && *p; ++i) /* too many chars in basename: */ |
*q++ = *p++; /* shift ".ext" left and */ |
*q = '\0'; /* truncate/terminate it */ |
*pEndFAT = q; |
} else if ((pEnd - last_dot) > 4) { /* too many chars in extension */ |
*pEndFAT = last_dot + 4; |
**pEndFAT = '\0'; |
} else |
*pEndFAT = pEnd; /* filename is fine; point at terminating zero */ |
if ((last_dot - pBegin) > 0 && last_dot[-1] == ' ') |
last_dot[-1] = '_'; /* NO blank in front of '.'! */ |
} |
} /* end function map2fat() */ |
static int SetLongNameEA(char *name, char *longname) |
{ |
EAOP eaop; |
FEALST fealst; |
eaop.fpFEAList = (PFEALIST) &fealst; |
eaop.fpGEAList = NULL; |
eaop.oError = 0; |
strcpy((char *) fealst.szName, ".LONGNAME"); |
strcpy((char *) fealst.szValue, longname); |
fealst.cbList = sizeof(fealst) - CCHMAXPATH + strlen((char *) fealst.szValue); |
fealst.cbName = (BYTE) strlen((char *) fealst.szName); |
fealst.cbValue = sizeof(USHORT) * 2 + strlen((char *) fealst.szValue); |
#ifdef __32BIT__ |
fealst.oNext = 0; |
#endif |
fealst.fEA = 0; |
fealst.eaType = 0xFFFD; |
fealst.eaSize = strlen((char *) fealst.szValue); |
return DosSetPathInfo(name, FIL_QUERYEASIZE, |
(PBYTE) &eaop, sizeof(eaop), 0); |
} |
/****************************/ |
/* Function close_outfile() */ |
/****************************/ |
/* GRR: need to return error level!! */ |
void close_outfile(__G) /* only for extracted files, not directories */ |
__GDEF |
{ |
fclose(G.outfile); |
/* set extra fields, both stored-in-zipfile and .LONGNAME flavors */ |
if (G.extra_field) { /* zipfile extra field may have extended attribs */ |
int err = EvalExtraFields(__G__ G.filename, G.extra_field, |
G.lrec.extra_field_length); |
if (err == IZ_EF_TRUNC) { |
if (uO.qflag) |
Info(slide, 1, ((char *)slide, "%-22s ", |
FnFilter1(G.filename))); |
Info(slide, 1, ((char *)slide, LoadFarString(TruncEAs), |
makeword(G.extra_field+2)-10, uO.qflag? "\n" : "")); |
} |
} |
if (G.os2.longnameEA) { |
#ifdef DEBUG |
int e = |
#endif |
SetLongNameEA(G.filename, G.os2.lastpathcomp); |
Trace((stderr, "close_outfile: SetLongNameEA() returns %d\n", e)); |
free(G.os2.lastpathcomp); |
} |
/* set date/time and permissions */ |
SetPathAttrTimes(__G__ G.pInfo->file_attr, 0); |
} /* end function close_outfile() */ |
/******************************/ |
/* Function check_for_newer() */ |
/******************************/ |
int check_for_newer(__G__ filename) /* return 1 if existing file newer or equal; */ |
__GDEF |
char *filename; /* 0 if older; -1 if doesn't exist yet */ |
{ |
ulg existing, archive; |
#ifdef USE_EF_UT_TIME |
iztimes z_utime; |
#endif |
if ((existing = (ulg)GetFileTime(filename)) == (ulg)-1) |
return DOES_NOT_EXIST; |
#ifdef USE_EF_UT_TIME |
if (G.extra_field && |
#ifdef IZ_CHECK_TZ |
G.tz_is_valid && |
#endif |
(ef_scan_for_izux(G.extra_field, G.lrec.extra_field_length, 0, |
G.lrec.last_mod_dos_datetime, &z_utime, NULL) |
& EB_UT_FL_MTIME)) |
{ |
TTrace((stderr, "check_for_newer: using Unix extra field mtime\n")); |
archive = Utime2DosDateTime(z_utime.mtime); |
} else { |
archive = G.lrec.last_mod_dos_datetime; |
} |
#else /* !USE_EF_UT_TIME */ |
archive = G.lrec.last_mod_dos_datetime; |
#endif /* ?USE_EF_UT_TIME */ |
return (existing >= archive); |
} /* end function check_for_newer() */ |
#ifndef SFX |
/*************************/ |
/* Function dateformat() */ |
/*************************/ |
int dateformat() |
{ |
/*----------------------------------------------------------------------------- |
For those operating systems which support it, this function returns a value |
which tells how national convention says that numeric dates are displayed. |
Return values are DF_YMD, DF_DMY and DF_MDY. |
-----------------------------------------------------------------------------*/ |
switch (GetCountryInfo()) { |
case 0: |
return DF_MDY; |
case 1: |
return DF_DMY; |
case 2: |
return DF_YMD; |
} |
return DF_MDY; /* default if error */ |
} /* end function dateformat() */ |
/************************/ |
/* Function version() */ |
/************************/ |
void version(__G) |
__GDEF |
{ |
int len; |
#if defined(__IBMC__) || defined(__WATCOMC__) || defined(_MSC_VER) |
char buf[80]; |
#endif |
len = sprintf((char *)slide, LoadFarString(CompiledWith), |
#if defined(__GNUC__) |
# ifdef __EMX__ /* __EMX__ is defined as "1" only (sigh) */ |
"emx+gcc ", __VERSION__, |
# else |
"gcc ", __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", /* from Kai Uwe: three less than DOS */ |
# else |
" 2.0", /* (__BORLANDC__ == 0x0500)? */ |
# endif |
# else |
"Turbo C", /* these are probably irrelevant */ |
# 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 /* ?compilers */ |
"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 |
" (32-bit)", |
#endif |
#ifdef __DATE__ |
" on ", __DATE__ |
#else |
"", "" |
#endif |
); |
(*G.message)((zvoid *)&G, slide, (ulg)len, 0); |
/* MSC can't handle huge macro expansions */ |
/* temporary debugging code for Borland compilers only */ |
/* __TCPLUSPLUS__, __BCPLUSPLUS__ not defined for v1.5 */ |
#if (defined(__TURBOC__) && defined(DEBUG)) |
Info(slide, 0, ((char *)slide, "\t(__TURBOC__ = 0x%04x = %d)\n", __TURBOC__, |
__TURBOC__)); |
#ifdef __BORLANDC__ |
Info(slide, 0, ((char *)slide, "\t(__BORLANDC__ = 0x%04x)\n",__BORLANDC__)); |
#else |
Info(slide, 0, ((char *)slide, "\tdebug(__BORLANDC__ not defined)\n")); |
#endif |
#endif /* __TURBOC__ && DEBUG */ |
} /* end function version() */ |
#endif /* !SFX */ |
#endif /* !FUNZIP */ |
#ifdef MY_ZCALLOC /* Special zcalloc function for MEMORY16 (MSDOS/OS2) */ |
#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 */ |
#ifndef FUNZIP |
/* This table can be static because it is pseudo-constant */ |
static unsigned char cUpperCase[256], cLowerCase[256]; |
static BOOL bInitialized=FALSE; |
/* Initialize the tables of upper- and lowercase characters, including |
handling of country-dependent characters. */ |
static void InitNLS(void) |
{ |
unsigned nCnt, nU; |
COUNTRYCODE cc; |
if (bInitialized == FALSE) { |
bInitialized = TRUE; |
for ( nCnt = 0; nCnt < 256; nCnt++ ) |
cUpperCase[nCnt] = cLowerCase[nCnt] = (unsigned char) nCnt; |
cc.country = cc.codepage = 0; |
DosMapCase(sizeof(cUpperCase), &cc, (PCHAR) cUpperCase); |
for ( nCnt = 0; nCnt < 256; nCnt++ ) { |
nU = cUpperCase[nCnt]; |
if (nU != nCnt && cLowerCase[nU] == (unsigned char) nU) |
cLowerCase[nU] = (unsigned char) nCnt; |
} |
for ( nCnt = 'A'; nCnt <= 'Z'; nCnt++ ) |
cLowerCase[nCnt] = (unsigned char) (nCnt - 'A' + 'a'); |
} |
} |
int IsUpperNLS(int nChr) |
{ |
return (cUpperCase[nChr] == (unsigned char) nChr); |
} |
int ToLowerNLS(int nChr) |
{ |
return cLowerCase[nChr]; |
} |
char *StringLower(char *szArg) |
{ |
unsigned char *szPtr; |
for ( szPtr = (unsigned char *) szArg; *szPtr; szPtr++ ) |
*szPtr = cLowerCase[*szPtr]; |
return szArg; |
} |
#ifdef MORE |
int screensize(int *tt_rows, int *tt_cols) |
{ |
#ifdef __EMX__ |
int dst[2]; |
_scrsize(dst); |
if (tt_rows != NULL) *tt_rows = dst[1]; |
if (tt_cols != NULL) *tt_cols = dst[0]; |
#else |
VIOMODEINFO vmi; |
vmi.cb = sizeof(vmi); |
VioGetMode(&vmi, 0); |
if (tt_rows != NULL) *tt_rows = vmi.row; |
if (tt_cols != NULL) *tt_cols = vmi.col; |
#endif |
return 0; |
} |
#endif /* MORE */ |
#if defined(__IBMC__) && defined(__DEBUG_ALLOC__) |
void DebugMalloc(void) |
{ |
_dump_allocated(0); /* print out debug malloc memory statistics */ |
} |
#endif |
#if defined(REENTRANT) && defined(USETHREADID) |
ulg GetThreadId(void) |
{ |
PTIB pptib; /* Address of a pointer to the |
Thread Information Block */ |
PPIB pppib; /* Address of a pointer to the |
Process Information Block */ |
DosGetInfoBlocks(&pptib, &pppib); |
return pptib->tib_ptib2->tib2_ultid; |
} |
#endif /* defined(REENTRANT) && defined(USETHREADID) */ |
void os2GlobalsCtor(__GPRO) |
{ |
G.os2.nLastDrive = (USHORT)(-1); |
#ifdef OS2DLL |
G.os2.rexx_mes = "0"; |
#endif |
InitNLS(); |
} |
#endif /* !FUNZIP */ |
/programs/fs/unzip60/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 <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((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 */ |
/programs/fs/unzip60/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 <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 */ |
/programs/fs/unzip60/os2/os2cfg.h |
---|
0,0 → 1,166 |
/* |
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 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 |
*/ |
/*--------------------------------------------------------------------------- |
OS/2 specific configuration section: |
---------------------------------------------------------------------------*/ |
#ifndef __os2cfg_h |
#define __os2cfg_h |
#ifdef MSDOS |
# include <dos.h> /* for REGS macro (TC) or _dos_setftime (MSC) */ |
# ifdef __TURBOC__ /* includes Power C */ |
# include <sys/timeb.h> /* for structure ftime */ |
# ifndef __BORLANDC__ /* there appears to be a bug (?) in Borland's */ |
# include <mem.h> /* MEM.H related to __STDC__ and far poin- */ |
# endif /* ters. (dpk) [mem.h included for memcpy] */ |
# endif |
#endif /* MSDOS */ |
#ifdef __IBMC__ |
# define S_IFMT 0xF000 |
# define timezone _timezone /* (underscore names work with */ |
# define tzset _tzset /* all versions of C Set) */ |
# define PIPE_ERROR (errno == EERRSET || errno == EOS2ERR) |
#endif /* __IBMC__ */ |
#ifdef __WATCOMC__ |
# ifdef __386__ |
# ifndef WATCOMC_386 |
# define WATCOMC_386 |
# endif |
# define __32BIT__ |
# undef far |
# define far |
# undef near |
# define near |
/* Get asm routines to link properly without using "__cdecl": */ |
# 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__ */ |
# ifndef USE_ZLIB |
# pragma aux crc32 "_*" parm caller [] value [ax dx] \ |
modify [ax cx dx bx] |
# pragma aux get_crc_table "_*" parm caller [] value [ax] \ |
modify [ax cx dx bx] |
# endif /* !USE_ZLIB */ |
# endif /* ?__386__ */ |
#endif /* __WATCOMC__ */ |
#ifdef __EMX__ |
# ifndef __32BIT__ |
# define __32BIT__ |
# endif |
# define far |
#endif |
#ifndef __32BIT__ |
# define __16BIT__ |
#endif |
#ifdef MSDOS |
# undef MSDOS |
#endif |
#if defined(M_I86CM) || defined(M_I86LM) |
# define MED_MEM |
#endif |
#if (defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__)) |
# define MED_MEM |
#endif |
#ifdef __16BIT__ |
# ifndef MED_MEM |
# define SMALL_MEM |
# endif |
#endif |
#ifdef __16BIT__ |
# if defined(MSC) || defined(__WATCOMC__) |
# include <malloc.h> |
# define nearmalloc _nmalloc |
# define nearfree _nfree |
# endif |
# if defined(__TURBOC__) && defined(DYNALLOC_CRCTAB) |
# if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__) |
# undef DYNALLOC_CRCTAB |
# endif |
# endif |
# ifndef nearmalloc |
# define nearmalloc malloc |
# define nearfree free |
# endif |
# ifdef USE_DEFLATE64 |
# if (defined(M_I86TM) || defined(M_I86SM) || defined(M_I86MM)) |
# error Deflate64(tm) requires compact or large memory model |
# endif |
# if (defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)) |
# error Deflate64(tm) requires compact or large memory model |
# endif |
/* the 64k history buffer for Deflate64 must be allocated specially */ |
# define MALLOC_WORK |
# define MY_ZCALLOC |
# endif |
#endif |
/* TIMESTAMP is now supported on OS/2, so enable it by default */ |
#if (!defined(NOTIMESTAMP) && !defined(TIMESTAMP)) |
# define TIMESTAMP |
#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 RESTORE_ACL |
# define RESTORE_ACL |
#endif |
#ifndef OS2_EAS |
# define OS2_EAS /* for -l and -v listings (list.c) */ |
#endif |
#ifdef isupper |
# undef isupper |
#endif |
#ifdef tolower |
# undef tolower |
#endif |
#define isupper(x) IsUpperNLS((unsigned char)(x)) |
#define tolower(x) ToLowerNLS((unsigned char)(x)) |
#ifndef NO_STRNICMP /* use UnZip's zstrnicmp(), because some compilers */ |
# define NO_STRNICMP /* don't provide a NLS-aware strnicmp() function */ |
#endif |
#define USETHREADID |
/* handlers for OEM <--> ANSI string conversions */ |
#ifndef _OS2_ISO_ANSI |
/* use home-brewed conversion functions; internal charset is OEM */ |
# ifdef CRTL_CP_IS_ISO |
# undef CRTL_CP_IS_ISO |
# endif |
# ifndef CRTL_CP_IS_OEM |
# define CRTL_CP_IS_OEM |
# endif |
#endif |
/* screen size detection */ |
#define SCREENWIDTH 80 |
#define SCREENSIZE(scrrows, scrcols) screensize(scrrows, scrcols) |
int screensize(int *tt_rows, int *tt_cols); |
/* on the OS/2 console screen, line-wraps are always enabled */ |
#define SCREENLWRAP 1 |
#endif /* !__os2cfg_h */ |
/programs/fs/unzip60/os2/os2data.h |
---|
0,0 → 1,149 |
/* |
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 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 |
*/ |
/*--------------------------------------------------------------------------- |
os2data.h |
OS/2-specific structures and data to be included in the global data struc- |
ture. |
---------------------------------------------------------------------------*/ |
#define MAXNAMLEN 256 |
#define MAXPATHLEN 256 |
#define MAXLEN 256 /* temporary buffer length */ |
#define IBUF_LEN 4096 /* input buffer length */ |
#define INCL_NOPM |
#define INCL_VIO |
#define INCL_DOSNLS |
#define INCL_DOSPROCESS |
#define INCL_DOSDEVICES |
#define INCL_DOSDEVIOCTL |
#define INCL_DOSERRORS |
#define INCL_DOSMISC |
#if (defined(OS2DLL) && !defined(DLL)) |
# undef OS2DLL |
#endif |
#ifdef OS2DLL |
# define INCL_REXXSAA |
# include <rexxsaa.h> |
#endif |
#include <os2.h> |
struct direct |
{ |
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; /* MS-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 these data without any extra cost. |
* If these data are needed, the 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; |
struct os2Global { |
#ifndef SFX |
HDIR hdir; |
#ifdef __32BIT__ |
ULONG count; |
FILEFINDBUF3 find; |
#else |
USHORT count; |
FILEFINDBUF find; |
#endif |
#endif /* !SFX */ |
int created_dir; /* used by mapname(), checkdir() */ |
int renamed_fullpath; /* ditto */ |
int fnlen; /* ditto */ |
#ifdef __32BIT__ |
ULONG nLabelDrive; /* ditto */ |
#else |
USHORT nLabelDrive; |
#endif |
int longnameEA; /* checkdir(), close_outfile() */ |
char *lastpathcomp; /* ditto */ |
struct direct dp; |
int lower; |
USHORT nLastDrive, nResult; |
DIR *wild_dir; |
ZCONST char *wildname; |
char *dirname, matchname[FILNAMSIZ]; |
int notfirstcall, have_dirname, dirnamelen; |
int rootlen; /* length of rootpath */ |
char *rootpath; /* user's "extract-to" directory */ |
char *buildpathHPFS; /* full path (so far) to extracted file, */ |
char *buildpathFAT; /* both HPFS/EA (main) and FAT versions */ |
char *endHPFS; /* corresponding pointers to end of */ |
char *endFAT; /* buildpath ('\0') */ |
#ifdef OS2DLL |
char buffer[IBUF_LEN]; |
char output_var[MAXLEN]; |
char getvar_buf[MAXLEN]; |
int getvar_len; |
int output_idx; |
int stem_len; |
int putchar_idx; |
int rexx_error; |
char *rexx_mes; |
SHVBLOCK request; |
#endif |
}; |
#define SYSTEM_SPECIFIC_GLOBALS struct os2Global os2; |
#define SYSTEM_SPECIFIC_CTOR os2GlobalsCtor |
#ifdef OS2DLL |
# ifdef API_DOC |
# define SYSTEM_API_BRIEF REXXBrief |
# define SYSTEM_API_DETAILS REXXDetails |
extern char *REXXBrief; |
extern APIDocStruct REXXDetails[]; |
# endif |
#endif |
/programs/fs/unzip60/os2/rexxapi.c |
---|
0,0 → 1,894 |
/* |
Copyright (c) 1990-2004 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 |
*/ |
/********************************************************************** |
* REXXAPI.C * |
* * |
* This program adds a ZIP engine directly to the REXX language. * |
* The functions are: * |
* UZDropFuncs -- Makes all functions in this package * |
* unknown to REXX. * |
* UZLoadFuncs -- Makes all functions in this package * |
* known to REXX so REXX programs may * |
* call them. * |
* UZFileTree -- Searches for files matching a given * |
* filespec, including files in * |
* subdirectories. * |
* UZUnZip -- Unzip command-line entry point. * |
* This is functionally equivalent to * |
* using Unzip as an external program. * |
* UZUnZipToVar -- Unzip one file to a variable * |
* UZUnZipToStem -- Unzip files to a variable array * |
* UZVer -- Returns the Unzip version number * |
* * |
**********************************************************************/ |
/* Include files */ |
#ifdef OS2DLL |
#define INCL_DOS |
#define INCL_DOSMEMMGR |
#include <string.h> |
#include <stdlib.h> |
#include <stdio.h> |
#include <stdarg.h> |
#define UNZIP_INTERNAL |
#include "../unzip.h" |
#include "../unzvers.h" |
/*********************************************************************/ |
/* Various definitions used by various functions. */ |
/*********************************************************************/ |
RexxFunctionHandler UZDropFuncs; |
RexxFunctionHandler UZLoadFuncs; |
RexxFunctionHandler UZFileTree; |
RexxFunctionHandler UZUnZip; |
RexxFunctionHandler UZUnZipToVar; |
RexxFunctionHandler UZUnZipToStem; |
RexxFunctionHandler UZVer; |
RexxFunctionHandler UZAPIVer; |
int SetOutputVar(__GPRO__ const char *name); |
int SetOutputVarStem(__GPRO__ const char *name); |
int SetOutputVarLength(__GPRO); |
int WriteToVariable(__GPRO__ const char *name, char *buffer, int len); |
int PrintToSubVariable(__GPRO__ int idx, const char *format,...); |
int PrintToVariable(__GPRO__ const char *name, const char *format,...); |
int _PrintToVariable(__GPRO__ const char *name, const char *format, va_list arg_ptr); |
int TextSetNext(__GPRO__ char *format, int len, int all); |
#define EZRXSTRING(r,p) {(r).strptr=(PCH)p;(r).strlength=(ULONG)strlen((r).strptr);} |
/*********************************************************************/ |
/* RxFncTable */ |
/* Array of names of the UNZIPAPI functions. */ |
/* This list is used for registration and deregistration. */ |
/*********************************************************************/ |
static PSZ RxFncTable[] = |
{ |
"UZDropFuncs", |
"UZLoadFuncs", |
"UZFileSearch", |
"UZFileTree", |
"UZUnZip", |
"UZUnZipToVar", |
"UZUnZipToStem", |
"UZVer", |
}; |
/*********************************************************************/ |
/* Numeric Error Return Strings */ |
/*********************************************************************/ |
#define NO_UTIL_ERROR "0" /* No error whatsoever */ |
#define ERROR_NOMEM "2" /* Insufficient memory */ |
/*********************************************************************/ |
/* Numeric Return calls */ |
/*********************************************************************/ |
#define INVALID_ROUTINE 40 /* Raise Rexx error */ |
#define VALID_ROUTINE 0 /* Successful completion */ |
/*********************************************************************/ |
/* Some useful macros */ |
/*********************************************************************/ |
#define BUILDRXSTRING(t, s) { \ |
strcpy((t)->strptr,(s));\ |
(t)->strlength = strlen((s)); \ |
} |
/*********************************************************************/ |
/**************** UNZIPAPI Supporting Functions ********************/ |
/**************** UNZIPAPI Supporting Functions ********************/ |
/**************** UNZIPAPI Supporting Functions ********************/ |
/*********************************************************************/ |
int RexxReturn(__GPRO__ int nodefault, RXSTRING *retstr) |
{ |
int ret = G.os2.rexx_error; |
if (G.filenotfound) |
G.os2.rexx_mes = "file not found"; |
if (*G.os2.rexx_mes != '0') { |
if (retstr->strlength > 255) { |
DosFreeMem(retstr->strptr); |
retstr->strptr = NULL; |
} |
} else if (nodefault) |
goto noBuild; |
BUILDRXSTRING(retstr, G.os2.rexx_mes); |
noBuild: |
DESTROYGLOBALS(); |
return ret; |
} |
/* Get a variable from REXX, return 0 if OK */ |
int GetVariable(__GPRO__ const char *name) |
{ |
G.os2.request.shvnext = NULL; |
EZRXSTRING(G.os2.request.shvname, name); |
G.os2.request.shvnamelen = G.os2.request.shvname.strlength; |
G.os2.request.shvvalue.strptr = G.os2.buffer; |
G.os2.request.shvvalue.strlength = IBUF_LEN; |
G.os2.request.shvvaluelen = IBUF_LEN; |
G.os2.request.shvcode = RXSHV_SYFET; |
G.os2.request.shvret = 0; |
switch (RexxVariablePool(&G.os2.request)) { |
case RXSHV_MEMFL: |
G.os2.rexx_mes = ERROR_NOMEM; |
break; |
case RXSHV_BADN: |
case RXSHV_NEWV: |
G.os2.request.shvvaluelen = 0; |
case RXSHV_OK: |
*(G.os2.buffer+G.os2.request.shvvaluelen) = 0; |
return G.os2.request.shvvaluelen; |
} |
return 0; |
} |
/* Get REXX compound variable */ |
/* Stem must exist in G.os2.getvar_buf w/ length in G.os2.getvar_len */ |
int GetVariableIndex(__GPRO__ int index) |
{ |
sprintf(G.os2.getvar_buf+G.os2.getvar_len,"%d",index); |
return GetVariable(__G__ G.os2.getvar_buf); |
} |
/* Transfer REXX array to standard C string array */ |
/* Returns number of elements */ |
/* User is responsible for calling KillStringArray */ |
int CompoundToStringArray(__GPRO__ char ***pointer, const char *name) |
{ |
int count; |
int total; |
char **trav; |
G.os2.getvar_len = strlen(name); |
memcpy(G.os2.getvar_buf,name,G.os2.getvar_len+1); |
if (*(G.os2.getvar_buf+G.os2.getvar_len-1) != '.') |
*(G.os2.getvar_buf+G.os2.getvar_len++) = '.', *(G.os2.getvar_buf+G.os2.getvar_len) = 0; |
if (GetVariableIndex(__G__ 0)) |
return 0; |
total = atoi(G.os2.buffer); |
*pointer = (char **)malloc((total+1)<<2); |
trav = *pointer; |
for (count = 1; count <= total; count++) { |
GetVariableIndex(__G__ count); |
trav[count-1] = (char *)malloc(strlen(G.os2.buffer)+1); |
strcpy(trav[count-1],G.os2.buffer); |
} |
trav[count-1] = NULL; |
return total; |
} |
/* Kill string array created by CompoundToStringArray */ |
void KillStringArray(char **pointer) |
{ |
char **trav=pointer; |
while (*trav != NULL) { |
free(*trav); |
trav++; |
} |
free(pointer); |
} |
/************************************************************************* |
* Function: UZDropFuncs * |
* * |
* Syntax: call UZDropFuncs * |
* * |
* Return: NO_UTIL_ERROR - Successful. * |
*************************************************************************/ |
ULONG UZDropFuncs(CHAR *name, ULONG numargs, RXSTRING args[], |
CHAR *queuename, RXSTRING *retstr) |
{ |
INT entries; /* Num of entries */ |
INT j; /* Counter */ |
if (numargs != 0) /* no arguments for this */ |
return INVALID_ROUTINE; /* raise an error */ |
retstr->strlength = 0; /* return a null string result*/ |
entries = sizeof(RxFncTable)/sizeof(PSZ); |
for (j = 0; j < entries; j++) |
RexxDeregisterFunction(RxFncTable[j]); |
return VALID_ROUTINE; /* no error on call */ |
} |
/************************************************************************* |
* Function: UZFileTree * |
* * |
* Syntax: call UZFileTree zipfile, stem[, include-filespec] * |
* [, exclude-filespec][, options] * |
* * |
* Params: zipfile - Name of zip file to search. * |
* stem - Name of stem var to store results in. * |
* include - Filespec to search for (may include * and ?). * |
* exclude - Filespec to exclude (may include * and ?). * |
* options - Either of the following: * |
* 'F' - Give file statistics. * |
* Length Date Time Name * |
* 'Z' - Give zip statistics, too. * |
* Length Method Size Ratio Date Time CRC-32 Name* |
* Default is to return only filenames * |
* * |
* Return: NO_UTIL_ERROR - Successful. * |
* ERROR_NOMEM - Out of memory. * |
*************************************************************************/ |
ULONG UZFileTree(CHAR *name, ULONG numargs, RXSTRING args[], |
CHAR *queuename, RXSTRING *retstr) |
{ |
/* validate arguments */ |
char *incname[2]; |
char *excname[2]; |
CONSTRUCTGLOBALS(); |
if (numargs < 2 || numargs > 5 || |
!RXVALIDSTRING(args[0]) || |
!RXVALIDSTRING(args[1]) || |
args[0].strlength > 255) { |
DESTROYGLOBALS(); |
return INVALID_ROUTINE; /* Invalid call to routine */ |
} |
/* initialize data area */ |
SetOutputVarStem(__G__ args[1].strptr); |
G.wildzipfn = args[0].strptr; |
G.process_all_files = TRUE; |
uO.lflag = 1; |
uO.zipinfo_mode = TRUE; |
uO.C_flag = 1; |
G.extract_flag = FALSE; |
uO.qflag = 2; |
if (numargs >= 3 && /* check third option */ |
!RXNULLSTRING(args[2]) && |
args[2].strlength > 0) { /* a zero length string isn't */ |
if (!(G.filespecs = CompoundToStringArray(__G__ &G.pfnames,args[2].strptr))) { |
G.pfnames = incname; |
incname[0] = args[2].strptr; |
incname[1] = NULL; |
G.filespecs = 1; |
} |
G.process_all_files = FALSE; |
} |
if (numargs >= 4 && /* check third option */ |
!RXNULLSTRING(args[3]) && |
args[3].strlength > 0) { /* a zero length string isn't */ |
if (!(G.xfilespecs = CompoundToStringArray(__G__ &G.pxnames,args[3].strptr))) { |
G.pxnames = excname; |
excname[0] = args[3].strptr; |
excname[1] = NULL; |
G.xfilespecs = 1; |
} |
G.process_all_files = FALSE; |
} |
if (numargs == 5 && /* check third option */ |
!RXNULLSTRING(args[4]) && |
args[4].strlength > 0) { /* a zero length string isn't */ |
int first = *args[4].strptr & 0x5f; |
if (first == 'Z') |
uO.vflag = 2, uO.lflag = 0, uO.zipinfo_mode = FALSE; |
else if (first == 'F') |
uO.vflag = 1, uO.lflag = 0, uO.zipinfo_mode = FALSE; |
} |
process_zipfiles(__G); |
SetOutputVarLength(__G); |
if (G.filespecs > 0 && G.pfnames != incname) |
KillStringArray(G.pfnames); |
if (G.xfilespecs > 0 && G.pxnames != excname) |
KillStringArray(G.pxnames); |
return RexxReturn(__G__ 0,retstr); /* no error on call */ |
} |
/************************************************************************* |
* Function: UZUnZipToVar * |
* * |
* Syntax: call UZUnZipToVar zipfile, filespec [, stem] * |
* * |
* Params: zipfile - Name of zip file to search. * |
* filespec - File to extract * |
* stem - If you specify a stem variable, the file will be * |
* extracted to the variable, one line per index * |
* In this case, 0 will be returned * |
* * |
* Return: Extracted file * |
* ERROR_NOMEM - Out of memory. * |
*************************************************************************/ |
ULONG UZUnZipToVar(CHAR *name, ULONG numargs, RXSTRING args[], |
CHAR *queuename, RXSTRING *retstr) |
{ |
CONSTRUCTGLOBALS(); |
UzpBuffer *ub = (UzpBuffer *)retstr; |
/* validate arguments */ |
if (numargs < 2 || numargs > 3 || |
!RXVALIDSTRING(args[0]) || |
!RXVALIDSTRING(args[1]) || |
args[0].strlength == 0 || |
args[1].strlength == 0) { |
DESTROYGLOBALS(); |
return INVALID_ROUTINE; /* Invalid call to routine */ |
} |
uO.C_flag = 1; |
G.redirect_data=1; |
if (numargs == 3) { |
if (!RXVALIDSTRING(args[2]) || |
RXNULLSTRING(args[1]) || |
args[2].strlength == 0) { |
DESTROYGLOBALS(); |
return INVALID_ROUTINE; /* Invalid call to routine */ |
} |
SetOutputVarStem(__G__ args[2].strptr); |
G.redirect_text = 0; |
G.redirect_data++; |
} |
unzipToMemory(__G__ args[0].strptr, args[1].strptr, |
G.redirect_data==1 ? ub : NULL); |
return RexxReturn(__G__ G.redirect_data==1,retstr); |
} |
/************************************************************************* |
* Function: UZUnZipToStem * |
* * |
* Syntax: call UZUnZipToStem zipfile, stem[, include-filespec] * |
* [, exclude-filespec][, mode] * |
* * |
* Params: zipfile - Name of zip file to search. * |
* stem - Name of stem var to store files in. * |
* include - Filespec to search for (may include * and ?). * |
* exclude - Filespec to exclude (may include * and ?). * |
* mode - Specifies 'F'lat or 'T'ree mode. Umm, this is * |
* hard to explain so I'll give an example, too. * |
* Assuming a file unzip.zip containing: * |
* unzip.c * |
* unshrink.c * |
* extract.c * |
* os2/makefile.os2 * |
* os2/os2.c * |
* os2/dll/dll.def * |
* os2/dll/unzipapi.c * |
* * |
* -- In flat mode, each file is stored in * |
* stem.fullname i.e. stem."os2/dll/unzipapi.c" * |
* A list of files is created in stem.<index> * |
* * |
* Flat mode returns: * |
* stem.0 = 7 * |
* stem.1 = unzip.c * |
* stem.2 = unshrink.c * |
* stem.3 = extract.c * |
* stem.4 = os2/makefile.os2 * |
* stem.5 = os2/os2.c * |
* stem.6 = os2/dll/dll.def * |
* stem.7 = os2/dll/unzipapi.c * |
* * |
* And the following contain the contents of the * |
* various programs: * |
* stem.unzip.c * |
* stem.unshrink.c * |
* stem.extract.c * |
* stem.os2/makefile.os2 * |
* stem.os2/os2.c * |
* stem.os2/dll/dll.def * |
* stem.os2/dll/unzipapi.c * |
* * |
* -- In tree mode, slashes are converted to periods* |
* in the pathname thus the above file would have* |
* been stored in stem.os2.dll.unzipapi.c * |
* The index would then be stored in stem.OS2. * |
* DLL.<index>. * |
* * |
* NOTE: All path names are converted to uppercase * |
* * |
* Tree mode returns: * |
* stem.0 = 4 * |
* stem.1 = unzip.c * |
* stem.2 = unshrink.c * |
* stem.3 = extract.c * |
* stem.4 = OS2/ * |
* * |
* stem.OS2.0 = 3 * |
* stem.OS2.1 = makefile.os2 * |
* stem.OS2.2 = os2.c * |
* stem.OS2.3 = DLL/ * |
* * |
* stem.OS2.DLL.0 = 2 * |
* stem.OS2.DLL.1 = def * |
* stem.OS2.DLL.2 = unzipapi.c * |
* * |
* And the following contain the contents of the * |
* various programs: * |
* stem.unzip.c * |
* stem.unshrink.c * |
* stem.extract.c * |
* stem.OS2.makefile.os2 * |
* stem.OS2.os2.c * |
* stem.OS2.DLL.dll.def * |
* stem.OS2.DLL.unzipapi.c * |
* * |
* * |
* Return: NO_UTIL_ERROR - Successful. * |
* ERROR_NOMEM - Out of memory. * |
*************************************************************************/ |
ULONG UZUnZipToStem(CHAR *name, ULONG numargs, RXSTRING args[], |
CHAR *queuename, RXSTRING *retstr) |
{ |
char *incname[2]; |
char *excname[2]; |
CONSTRUCTGLOBALS(); |
/* validate arguments */ |
if (numargs < 2 || numargs > 5 || |
!RXVALIDSTRING(args[0]) || |
!RXVALIDSTRING(args[1]) || |
args[0].strlength > 255) { |
DESTROYGLOBALS(); |
return INVALID_ROUTINE; /* Invalid call to routine */ |
} |
/* initialize data area */ |
G.wildzipfn = args[0].strptr; |
G.process_all_files = TRUE; |
uO.C_flag = 1; |
G.extract_flag = TRUE; |
SetOutputVarStem(__G__ args[1].strptr); |
G.redirect_data = 3; |
G.redirect_text = 0; |
if (numargs >= 3 && /* check third option */ |
!RXNULLSTRING(args[2]) && |
args[2].strlength > 0) { /* a zero length string isn't */ |
if (!(G.filespecs = CompoundToStringArray(__G__ &G.pfnames,args[2].strptr))) { |
G.pfnames = incname; |
incname[0] = args[2].strptr; |
incname[1] = NULL; |
G.filespecs = 1; |
} |
G.process_all_files = FALSE; |
} |
if (numargs >= 4 && /* check third option */ |
!RXNULLSTRING(args[3]) && |
args[3].strlength > 0) { /* a zero length string isn't */ |
if (!(G.xfilespecs = CompoundToStringArray(__G__ &G.pxnames,args[3].strptr))) { |
G.pxnames = excname; |
excname[0] = args[3].strptr; |
excname[1] = NULL; |
G.xfilespecs = 1; |
} |
G.process_all_files = FALSE; |
} |
if (numargs == 5 && /* check third option */ |
!RXNULLSTRING(args[4]) && |
(*args[4].strptr & 0x5f) == 'T') { |
G.redirect_data++; |
G.os2.request.shvnext = NULL; |
EZRXSTRING(G.os2.request.shvname, args[4].strptr); |
G.os2.request.shvnamelen = G.os2.request.shvname.strlength; |
G.os2.request.shvcode = RXSHV_SYDRO; |
G.os2.request.shvret = 0; |
RexxVariablePool(&G.os2.request); |
} |
uO.qflag = 2; |
process_zipfiles(__G); |
if (G.filespecs > 0 && G.pfnames != incname) |
KillStringArray(G.pfnames); |
if (G.xfilespecs > 0 && G.pxnames != excname) |
KillStringArray(G.pxnames); |
if (G.redirect_data == 3) |
SetOutputVarLength(__G); |
return RexxReturn(__G__ 0,retstr); /* no error on call */ |
} |
/************************************************************************* |
* Function: UZLoadFuncs * |
* * |
* Syntax: call UZLoadFuncs [option] * |
* * |
* Params: none * |
* * |
* Return: null string * |
*************************************************************************/ |
ULONG UZLoadFuncs(CHAR *name, ULONG numargs, RXSTRING args[], |
CHAR *queuename, RXSTRING *retstr) |
{ |
INT entries; /* Num of entries */ |
INT j; /* Counter */ |
retstr->strlength = 0; /* set return value */ |
/* check arguments */ |
if (numargs > 0) |
return INVALID_ROUTINE; |
entries = sizeof(RxFncTable)/sizeof(PSZ); |
for (j = 0; j < entries; j++) { |
RexxRegisterFunctionDll(RxFncTable[j], |
"UNZIP32", RxFncTable[j]); |
} |
return VALID_ROUTINE; |
} |
/************************************************************************* |
* Function: UZVer * |
* * |
* Syntax: call UZVer * |
* * |
* Return: Version of Unzip * |
*************************************************************************/ |
ULONG UZVer(CHAR *name, ULONG numargs, RXSTRING args[], |
CHAR *queuename, RXSTRING *retstr) |
{ |
if (numargs > 1) /* validate arg count */ |
return INVALID_ROUTINE; |
if (numargs == 0 || (*args[0].strptr & 0x5f) != 'L') |
/* strcpy( retstr->strptr, UZ_VERNUM ); "5.13a BETA" */ |
sprintf( retstr->strptr, "%d.%d%d%s", UZ_MAJORVER, UZ_MINORVER, |
UZ_PATCHLEVEL, UZ_BETALEVEL ); |
else |
/* strcpy( retstr->strptr, UZ_VERSION ); UZ_VERNUM" of 26 Sep 94" */ |
sprintf( retstr->strptr, "%d.%d%d%s of %s", UZ_MAJORVER, UZ_MINORVER, |
UZ_PATCHLEVEL, UZ_BETALEVEL, UZ_VERSION_DATE ); |
retstr->strlength = strlen(retstr->strptr); |
return VALID_ROUTINE; |
} |
/************************************************************************* |
* Function: UZUnZip * |
* * |
* Syntax: call UZUnZip * |
* * |
* Return: Unzip return code * |
*************************************************************************/ |
ULONG UZUnZip(CHAR *name, ULONG numargs, RXSTRING args[], |
CHAR *queuename, RXSTRING *retstr) |
{ |
char *argv[30]; |
char *scan; |
int argc=0; |
int idx; |
CONSTRUCTGLOBALS(); |
if (numargs < 1 || numargs > 2 || |
args[0].strlength > 255) { |
DESTROYGLOBALS(); |
return INVALID_ROUTINE; /* Invalid call to routine */ |
} |
/* initialize data area */ |
if (numargs == 2) |
SetOutputVarStem(__G__ args[1].strptr); |
scan = args[0].strptr; |
argv[argc++] = ""; /* D:\\SOURCECODE\\UNZIP51S\\UNZIP.COM"; */ |
while (*scan == ' ') |
scan++; |
argv[argc++] = scan; |
while ( (scan = strchr(scan,' ')) != NULL) { |
*scan++ = 0; |
while (*scan == ' ') |
scan++; |
argv[argc++] = scan; |
} |
if (*argv[argc-1] == 0) |
argc--; |
argv[argc] = 0; |
/* GRR: should resetMainFlags() be called in here somewhere? */ |
sprintf(retstr->strptr, "%d", unzip(__G__ argc, argv)); /* a.k.a. MAIN() */ |
if (numargs == 2) |
SetOutputVarLength(__G); |
retstr->strlength = strlen(retstr->strptr); |
return RexxReturn(__G__ 1,retstr); |
} |
int varmessage(__GPRO__ ZCONST uch *buf, ulg size) |
{ |
if (size > 0) |
memcpy(G.os2.buffer+G.os2.putchar_idx,buf,size); |
G.os2.putchar_idx = TextSetNext(__G__ G.os2.buffer, size+G.os2.putchar_idx,0); |
return 0; |
} |
int varputchar(__GPRO__ int c) |
{ |
G.os2.buffer[G.os2.putchar_idx++] = c; |
if (c == '\n') { |
G.os2.buffer[G.os2.putchar_idx] = 0; |
if (G.os2.output_var[0]) |
G.os2.putchar_idx = TextSetNext(__G__ G.os2.buffer, G.os2.putchar_idx,0); |
else { |
G.os2.buffer[--G.os2.putchar_idx] = 0; |
puts(G.os2.buffer); |
G.os2.putchar_idx = 0; |
} |
} |
return 1; |
} |
int SetOutputVarStem(__GPRO__ const char *name) |
{ |
int len=strlen(name); |
G.redirect_text=1; |
G.os2.output_idx = 0; |
strcpy(G.os2.output_var, name); |
if (len) { |
strupr(G.os2.output_var); /* uppercase the name */ |
if (*(G.os2.output_var+len-1) != '.') { |
*(G.os2.output_var+len) = '.'; |
len++; |
*(G.os2.output_var+len) = 0; |
} |
WriteToVariable(__G__ G.os2.output_var,"",0); |
} |
G.os2.stem_len = len; |
return G.os2.stem_len; |
} |
int SetOutputVar(__GPRO__ const char *name) |
{ |
int len=strlen(name); |
G.redirect_text=1; |
G.os2.output_idx = 0; |
strcpy(G.os2.output_var, name); |
strupr(G.os2.output_var); /* uppercase the name */ |
if (*(name+len-1) == '.') |
G.os2.stem_len = len; |
else |
G.os2.stem_len = 0; |
return G.os2.stem_len; |
} |
int SetOutputVarLength(__GPRO) |
{ |
if (G.os2.stem_len > 0) { |
if (G.os2.putchar_idx) |
TextSetNext(__G__ G.os2.buffer,G.os2.putchar_idx,1); |
return PrintToSubVariable(__G__ 0,"%d",G.os2.output_idx); |
} |
return 0; |
} |
int PrintToVariable(__GPRO__ const char *name, const char *format,...) |
{ |
va_list arg_ptr; |
int ret; |
va_start(arg_ptr, format); |
ret = _PrintToVariable(__G__ name, format, arg_ptr); |
va_end(arg_ptr); |
return ret; |
} |
int WriteToVariable(__GPRO__ const char *name, char *buffer, int len) |
{ |
G.os2.request.shvnext = NULL; |
EZRXSTRING(G.os2.request.shvname, name); |
G.os2.request.shvnamelen = G.os2.request.shvname.strlength; |
G.os2.request.shvvalue.strptr = buffer; |
G.os2.request.shvvalue.strlength = len; |
G.os2.request.shvvaluelen = len; |
G.os2.request.shvcode = RXSHV_SET; |
G.os2.request.shvret = 0; |
switch (RexxVariablePool(&G.os2.request)) { |
case RXSHV_BADN: |
G.os2.rexx_error = INVALID_ROUTINE; |
break; |
case RXSHV_MEMFL: |
G.os2.rexx_mes = ERROR_NOMEM; |
break; |
case RXSHV_OK: |
return 0; |
} |
return INVALID_ROUTINE; /* error on non-zero */ |
} |
int _PrintToVariable(__GPRO__ const char *name, const char *format, va_list arg_ptr) |
{ |
int ret = vsprintf(G.os2.buffer, format, arg_ptr); |
WriteToVariable(__G__ name, G.os2.buffer, strlen(G.os2.buffer)); |
return ret; |
} |
int PrintToSubVariable(__GPRO__ int idx, const char *format, ...) |
{ |
va_list arg_ptr; |
int ret; |
if (G.os2.stem_len == 0) |
return INVALID_ROUTINE; /* error on non-zero */ |
sprintf(G.os2.output_var+G.os2.stem_len,"%d",idx); |
va_start(arg_ptr, format); |
ret = _PrintToVariable(__G__ G.os2.output_var, format, arg_ptr); |
va_end(arg_ptr); |
return ret; |
} |
int WriteToNextVariable(__GPRO__ char *buffer, int len) |
{ |
if (G.os2.stem_len > 0) { |
G.os2.output_idx++; |
sprintf(G.os2.output_var+G.os2.stem_len,"%d",G.os2.output_idx); |
} |
return WriteToVariable(__G__ G.os2.output_var, buffer, len); |
} |
int TextSetNext(__GPRO__ char *buffer, int len, int all) |
{ |
char *scan = buffer, *next, *base=buffer; |
int remaining=len; |
int ret; |
while ((next = strchr(scan,'\n')) != NULL && remaining > 0) { |
if (next > scan && *(next-1) == 0xd) |
*(next-1) = 0; |
else |
*next = 0; |
if (WriteToNextVariable(__G__ scan,strlen(scan))) |
return 0; |
next++; |
remaining -= (next-scan); |
scan = next; |
} |
if (remaining > 0) |
if (all) { |
*(scan+remaining) = 0; |
WriteToNextVariable(__G__ scan,remaining); |
} else { |
memcpy(buffer,scan,remaining); |
return remaining; |
} |
return 0; |
} |
int finish_REXX_redirect(__GPRO) |
{ |
char *scan, *ptr; |
int idx=0, first=1, offset; |
if (!G.redirect_size) |
return 0; |
switch(G.redirect_data) { |
case 1: |
break; |
case 2: |
TextSetNext(__G__ G.redirect_buffer, G.redirect_size, 1); |
SetOutputVarLength(__G); |
DosFreeMem(G.redirect_buffer); |
G.redirect_buffer = NULL; |
G.redirect_size = 0; |
break; |
case 3: |
WriteToNextVariable(__G__ G.filename, strlen(G.filename)); |
strcpy(G.os2.output_var+G.os2.stem_len, G.filename); |
WriteToVariable(__G__ G.os2.output_var, G.redirect_buffer, G.redirect_size); |
DosFreeMem(G.redirect_buffer); |
G.redirect_buffer = NULL; |
G.redirect_size = 0; |
break; |
case 4: |
if ((scan = strrchr(G.filename,'/')) != NULL) { |
idx = *scan; |
*scan = 0; |
strupr(G.filename); |
*scan = idx; |
} |
scan = G.os2.output_var+G.os2.stem_len; |
strcpy(scan,G.filename); |
while ((scan = strchr(scan,'/')) != NULL) |
*scan = '.'; |
WriteToVariable(__G__ G.os2.output_var, G.redirect_buffer, G.redirect_size); |
DosFreeMem(G.redirect_buffer); |
G.redirect_buffer = NULL; |
G.redirect_size = 0; |
strcpy(G.os2.getvar_buf, G.os2.output_var); |
do { |
if ((scan = strrchr(G.filename,'/')) == NULL) |
offset = 0; |
else |
offset = scan-G.filename+1; |
if (first || !GetVariable(__G__ G.os2.output_var)) { |
ptr = G.os2.getvar_buf+offset+G.os2.stem_len; |
*ptr = '0'; |
*(ptr+1) = 0; |
if (!GetVariable(__G__ G.os2.getvar_buf)) |
idx = 1; |
else |
idx = atoi(G.os2.buffer)+1; |
PrintToVariable(__G__ G.os2.getvar_buf,"%d",idx); |
sprintf(ptr,"%d",idx); |
if (!first) { |
PrintToVariable(__G__ G.os2.output_var,"%d",idx); |
idx = strlen(G.filename); |
*(G.filename+idx) = '/'; |
*(G.filename+idx+1) = 0; |
} |
WriteToVariable(__G__ G.os2.getvar_buf,G.filename+offset,strlen(G.filename+offset)); |
first=0; |
} |
if (offset) { |
*(G.os2.output_var+G.os2.stem_len+offset-1) = 0; |
*scan = 0; |
} |
} while (offset); |
break; |
} |
return 0; |
} |
#endif /* OS2DLL */ |
/programs/fs/unzip60/os2/rexxapi.def |
---|
0,0 → 1,18 |
LIBRARY UNZIP32 INITINSTANCE LONGNAMES |
PROTMODE |
DESCRIPTION 'Info-ZIP UnZip API - Copyright Scott Maxwell 1994, Info-ZIP 1995-1997' |
DATA MULTIPLE NONSHARED |
EXPORTS |
UzpVersion @1 |
UzpUnzipToMemory @2 |
UzpFileTree @3 |
UzpMain @4 |
UzpAltMain @5 |
UzpVersion2 @6 |
UZDROPFUNCS = UZDropFuncs @2000 |
UZLOADFUNCS = UZLoadFuncs @2001 |
UZFILETREE = UZFileTree @2002 |
UZUNZIPTOVAR = UZUnZipToVar @2003 |
UZUNZIPTOSTEM = UZUnZipToStem @2004 |
UZVER = UZVer @2005 |
UZUNZIP = UZUnZip @2007 |
/programs/fs/unzip60/os2/rexxhelp.c |
---|
0,0 → 1,186 |
/* |
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 |
*/ |
/* rexxhelp.c */ |
#if defined(API_DOC) && defined(OS2DLL) |
#define UNZIP_INTERNAL |
#include "../unzip.h" |
#include "../unzvers.h" |
APIDocStruct REXXDetails[] = { |
{ "UZDROPFUNCS" , "UZDropFuncs" , |
"call UZDropFuncs", |
"Use this function to drop all the loaded UnZip functions.\n" |
"\t\tOnce this function is processed by a REXX program, the\n" |
"\t\tUnZip functions are not accessible in any OS/2 sessions.\n" }, |
{ "UZLOADFUNCS" , "UZLoadFuncs" , |
"call UZLoadFuncs", |
"Use this function to make all of the UnZip functions\n" |
" in this package available to all OS/2 sessions.\n\n" |
" Example: call RxFuncAdd 'UZLoadFuncs', 'UNZIPAPI', 'UZLoadFuncs'\n" |
" call UZLoadFuncs\n" }, |
{ "UZFILETREE" , "UZFileTree" , |
"rc = UZFileTree(zipfile, stem, [include], [exclude], [options])\n\n" |
" zipfile - Name of ZIP file to search\n" |
" stem - Name of the stem variable for results\n" |
" Note: stem.0 contains the number of files found.\n" |
" include - Optional stem variable specifying a list of files (including\n" |
" wildcards) to include. stem.0 must indicate number of items.\n" |
" exclude - Optional stem variable specifying a list of files (including\n" |
" wildcards) to exclude. stem.0 must indicate number of items.\n" |
" NOTE: If lists are not needed, filespec strings may be passed.\n" |
" options - One of the following:\n" |
" 'O' - Give file names only. This is the default.\n" |
" 'F' - Give file statistics in the form:\n" |
" Length Date Time Name\n" |
" 'Z' - Also give ZIP statistics in the form:\n" |
" Length Method Size Ratio Date Time CRC-32 Name", |
"Finds all files in the specified ZIP with the specified\n" |
" filespec and places their descriptions in a stem variable.\n\n" |
" rc: Return codes\n" |
" 0 Successful\n" |
" 2 Error. Not enough memory.\n\n" |
" Examples:\n" |
" /* Return a list of all .NDX files in pcboard.qwk */\n" |
" rc = UZFileTree('pcboard.qwk', 'stem.', '*.ndx')\n\n" |
" /* Return a list of all files except *.NDX and *.DAT */\n" |
" exc.0 = 2; exc.1 = '*.ndx'; exc.2 = '*.dat'\n" |
" rc = UZFileTree('pcboard.qwk', 'stem.',,'exc.')\n" }, |
{ "UZUNZIP" , "UZUnZip" , |
"rc = UZUnZip('parameters', [stem])\n\n" |
" parameters - The entire list of parameters you would use from\n" |
" the command-line\n" |
" stem - The name of an optional stem variable where any\n" |
" output should be redirected.\n" |
" NOTE: If a stem is not specified, all output will\n" |
" go to the console.", |
"Provide a direct entry point to the command line interface.\n\n" |
" rc: UnZip return code\n\n" |
" Examples: /* Test the archive 'unzip51s.zip' and return output in stem.*/\n" |
" rc = UZUnZip('-t unzip51s.zip','stem.')\n" |
" /* Extract the archive, display output on screen */\n" |
" call UZUnZip 'doom.zip'\n" |
" /* Extract all .NDX files from the archive */\n" |
" call UZUnZip 'pcboard.qwk *.ndx','stem.'\n" }, |
{ "UZUNZIPTOVAR" , "UZUnZipToVar" , |
"rc = UZUnZipToVar('zipfile', 'filename', [stem])\n\n" |
" zipfile - Name of ZIP file to search\n" |
" filename - Name of file to extract from zipfile\n" |
" stem - Optional stem variable to extract the file to.\n" |
" If you specify a stem variable, the file will be extracted\n" |
" to the variable, one line per index, stem.0 containing a\n" |
" line count. In this case, 0 will be returned in rc.\n" |
" If NO stem variable is specified, the entire file will be\n" |
" extracted to rc.", |
"Unzip one file to a variable.\n\n" |
" rc: If no stem variable is specified, rc contains the contents of\n" |
" the extracted file if successful or an error-code if not.\n" |
" If a stem variable IS specified, rc contains 0 if successful.\n"}, |
/* GRR: "include" and "exclude" used to be identified as stem variables |
* (Daniel H bug report) |
*/ |
{ "UZUNZIPTOSTEM", "UZUnZipToStem", |
"rc = UZUnZipToStem(zipfile, stem, [include], [exclude], [mode])\n" |
" zipfile - Name of ZIP file to search\n" |
" stem - Stem variable used to store the extracted files\n" |
" include - Optional string variable specifying a list of files (including\n" |
" wildcards) to include. stem.0 must indicate number of items.\n" |
" exclude - Optional string variable specifying a list of files (including\n" |
" wildcards) to exclude. stem.0 must indicate number of items.\n" |
" NOTE: If lists are not needed, filespec strings may be passed.\n" |
" mode - Optional mode parameter specifies either 'F'lat (the default)\n" |
" or 'T'ree mode.\n" |
" -- In flat mode, each file is stored in stem.fullname i.e.\n" |
" stem.os2/dll/unzipapi.c. A list of files is created in\n" |
" stem.<index>\n" |
" -- In tree mode, slashes are converted to periods in the\n" |
" pathname thus the above file would have been stored in\n" |
" stem.OS2.DLL.unzipapi.c and an index stored for each\n" |
" directory, i.e. stem.OS2.DLL.<index> = \"unzipapi.c\",\n" |
" stem.OS2.<index> = \"DLL/\", stem.<index> = \"OS2/\"", |
"Unzip files to a stem variable.\n\n" |
" Example: Assuming a file unzip.zip containing:\n" |
" unzip.c, unshrink.c, extract.c,\n" |
" os2/makefile.os2, os2/os2.c\n" |
" os2/dll/dll.def, os2/dll/unzipapi.c\n\n" |
" rc = UZUnZipToStem('unzip.zip', 'stem.')\n" |
" Returns: stem.0 = 7\n" |
" stem.1 = unzip.c\n" |
" stem.2 = unshrink.c\n" |
" stem.3 = extract.c\n" |
" stem.4 = os2/makefile.os2\n" |
" stem.5 = os2/os2.c\n" |
" stem.6 = os2/dll/dll.def\n" |
" stem.7 = os2/dll/unzipapi.c\n" |
" And the following contain the contents of the\n" |
" various files:\n" |
" stem.unzip.c\n" |
" stem.unshrink.c\n" |
" stem.extract.c\n" |
" stem.os2/makefile.os2\n" |
" stem.os2/os2.c\n" |
" stem.os2/dll/dll.def\n" |
" stem.os2/dll/unzipapi.c\n\n" |
" rc = UZUnZipToStem('unzip.zip', 'stem.',,,'TREE')\n" |
" Returns: stem.0 = 4\n" |
" stem.1 = unzip.c\n" |
" stem.2 = unshrink.c\n" |
" stem.3 = extract.c\n" |
" stem.4 = OS2/\n" |
" stem.OS2.0 = 3\n" |
" stem.OS2.1 = makefile.os2\n" |
" stem.OS2.2 = os2.c\n" |
" stem.OS2.3 = DLL/\n" |
" stem.OS2.DLL.0 = 2\n" |
" stem.OS2.DLL.1 = def\n" |
" stem.OS2.DLL.2 = unzipapi.c\n" |
"\n" |
" And the following contain the contents of the\n" |
" various programs:\n" |
" stem.unzip.c\n" |
" stem.unshrink.c\n" |
" stem.extract.c\n" |
" stem.OS2.makefile.os2\n" |
" stem.OS2.os2.c\n" |
" stem.OS2.DLL.dll.def\n" |
" stem.OS2.DLL.unzipapi.c\n" }, |
{ "UZVER" , "UZVer" , |
"rc = UZVer([option])\n\n" |
" rc String containing UnZip version info in the form 'x.xx'\n" |
" If option is 'L' then info is in the form 'x.xx of <date>", |
"Returns the version number of UnZip\n" }, |
{ "UZAPIVER" , "UZAPIVer" , |
"rc = UZAPIVer([option])\n\n" |
" rc String containing API version info in the form 'x.xx'\n" |
" If option is 'L' then info is in the form 'x.xx of <date>", |
"Returns the version number of the API\n" }, |
{ 0 } |
}; |
char *REXXBrief = "\ |
REXX functions:\n\ |
UZDropFuncs -- Makes all functions in this package unknown to REXX\n\ |
UZLoadFuncs -- Makes all functions in this package known to REXX\n\ |
UZFileTree -- Searches for files matching a given filespec\n\ |
UZUnZip -- UnZip command-line entry point\n\ |
UZUnZipToVar -- Unzip one file to a variable\n\ |
UZUnZipToStem -- Unzip files to a variable array\n\ |
UZVer -- Returns the UnZip version number\n\ |
UZAPIVer -- Returns the API version number\n"; |
#endif /* API_DOC && OS2DLL */ |
/programs/fs/unzip60/os2/rexxtest.cmd |
---|
0,0 → 1,54 |
/* Test REXX UnZip API */ |
call RxFuncAdd 'UZLoadFuncs', 'UNZIP32', 'UZLoadFuncs' |
call UZLoadFuncs |
parse arg all |
say; say 'Demonstrating UZUnZip' UZUnZip(all,'TEST.') |
do num=1 to test.0 |
say num':'test.num |
end |
/*** Demonstrate UZFileTree ***/ |
fname = 'g:\cqc\channel1\12-30.qwk' |
say; say 'Demonstrating UZFileTree by displaying all entries in', |
fname |
exc.0 = 2 |
exc.1 = '*.dat' |
exc.2 = '*.ndx' |
call UZFileTree fname, 'files','','exc' |
do num=1 to files.0 |
say num':'files.num |
end |
say; say 'Demonstrating UZUnZipToVar -' UZUnZipToVar(fname,'CONTROL.DAT') |
test. = 0 |
say; say 'Demonstrating UZUnZipToVar -' UZUnZipToVar(fname,'CONTROL.DAT','test.') |
SAY "Test =" test.0 |
do num=1 to test.0 |
say num':'test.num |
end |
test. = 0 |
say; say 'Demonstrating UZUnZipToStem -' UZUnZipToStem('\SourceCode\cqc\cqcmain.zip','test',"*.rch",,'T') |
call recout "test" |
say; say 'Demonstrating UZVer -' UZVer() |
call UZDropFuncs |
exit |
recout: PROCEDURE EXPOSE test. |
parse arg this |
say this "Contains" value(this'.0') "entries" |
do num=1 to value(this'.0') |
tval = value(this'.'num) |
say "Got" this'.'num':' tval |
if Right(tval,1) = '/' then |
call recout this'.'left(tval,length(tval)-1) |
else |
say "Contains:" value(this'.tval') |
end |
return |
/programs/fs/unzip60/os2/stub.def |
---|
0,0 → 1,6 |
DESCRIPTION 'The world-famous Info-ZIP unarchiving utilities' |
STACKSIZE 0x50000 |
IMPORTS |
UNZIP32.UzpVersion |
UNZIP32.UzpMain |
UNZIP32.UzpVersion2 |
/programs/fs/unzip60/os2/unzip.def |
---|
0,0 → 1,4 |
NAME WINDOWCOMPAT NEWFILES |
DESCRIPTION 'The world-famous Info-ZIP unarchiving utilities' |
; SEGMENTS |
; _MSGSEG32 CLASS 'CODE' |
/programs/fs/unzip60/os2/zgrepapi.cmd |
---|
0,0 → 1,98 |
/*--------------------------------------------------------------------------- |
zapigrep.cmd (ye olde REXX procedure for OS/2) |
Script to search members of a zipfile for a string and print the names of |
any such members (and, optionally, the matching text). |
This is the zipgrep.cmd program completely rewritten to take advantage |
of the REXX API. Among the improvements are: |
egrep no longer needed. All work done by API and this script. |
Added option switches. |
Be aware, however, that this script does not support regular expressions |
as zipgrep does. |
---------------------------------------------------------------------------*/ |
PARSE ARG args |
nocase = 0 |
word = 0 |
text = 0 |
DO WHILE Left(args,1) == '-' | Left(args,1) == '/' |
PARSE VAR args option args |
option = Translate(SubStr(option,2)) |
DO WHILE option \= '' |
oneopt = Left(option,1) |
option = SubStr(option,2) |
SELECT |
WHEN oneopt == 'W' THEN |
word = 1 |
WHEN oneopt == 'I' THEN |
nocase = 1 |
WHEN oneopt == 'T' THEN |
text = 1 |
OTHERWISE NOP |
END |
END |
END |
PARSE VAR args string zipfile members |
IF (string == '') THEN DO |
SAY 'usage: zipgrep [-i][-t][-w] search_string zipfile [members...]' |
SAY ' Displays the names of zipfile members containing a given string.' |
SAY ' By default it displays filenames only of members containing an' |
SAY ' exact match of the string. Options are:'"0a"x |
SAY ' -i Ignore case' |
SAY ' -t Display matching lines' |
SAY ' -w Match words only' |
EXIT 1 |
END |
string = Strip(string,'b','"') |
IF nocase THEN string = Translate(string) |
CALL RxFuncAdd 'UZLoadFuncs', 'UNZIP32', 'UZLoadFuncs' |
CALL UZLoadFuncs |
CALL UZUnZipToStem zipfile, 'file.', members |
DO i = 1 TO file.0 |
ptr = file.i |
file = file.ptr |
IF nocase THEN file = Translate(file) |
IF word THEN DO |
wp = WordPos(string,file) |
IF wp>0 THEN |
scan = WordIndex(file,wp) |
ELSE |
scan = 0 |
END |
ELSE |
scan = Pos(string,file) |
IF scan \= 0 THEN DO |
SAY file.i':' |
IF text THEN DO |
DO WHILE scan > 0 |
from = LastPos('0a'x,file,scan)+1 |
to = Pos('0a'x,file,scan) |
IF to = 0 THEN to = Length(file.ptr) |
oneline = Strip(SubStr(file.ptr,from,to-from),'T','0a'x) |
SAY Strip(oneline,'T','0d'x) |
IF word THEN DO |
wp = WordPos(string,file,wp+1) |
IF wp>0 THEN |
scan = WordIndex(file,wp) |
ELSE |
scan = 0 |
END |
ELSE |
scan = Pos(string,file,scan+1) |
END |
END |
END |
END |
EXIT 0 |
/programs/fs/unzip60/os2/zip2exe.cmd |
---|
0,0 → 1,62 |
/**** REXX ******** ZIP2EXE.CMD ************** 01/04/96 *********\ |
|** This exec will prepend the Info Zip unzipsfx.exe file to an **| |
|** existing ZIP file to create a self extracting zip. **| |
|** **| |
|** The exec requires 1 argument, the name of the zip file to be **| |
|** acted upon. **| |
|** **| |
|** Put this exec into the path that contains your Info Zip **| |
|** executables. **| |
|** **| |
\*********************************************************************/ |
rc = 0 |
/** Start Argument processing ** End Initialization **/ |
PARSE UPPER ARG zip_file |
IF zip_file = "" |
THEN |
DO |
SAY "You must specify the name of the file to be processed" |
SAY "Please try again" |
rc = 9 |
SIGNAL FINI |
END |
IF POS(".ZIP",zip_file) = 0 |
THEN |
DO |
sfx_file = zip_file||".EXE" |
zip_file = zip_file||".ZIP" |
END |
ELSE |
sfx_file = SUBSTR(zip_file,1,LASTPOS(".",zip_file))||"EXE" |
zip_file = STREAM(zip_file,"C","QUERY EXISTS") |
IF zip_file = "" |
THEN |
DO |
SAY "The file "||ARG(1)||" Does not exist" |
SAY "Processing terminated" |
rc = 9 |
SIGNAL FINI |
END |
/** Start unzipsfx location ** End Argument processing **/ |
PARSE UPPER SOURCE . . command_file |
unzipsfx = SUBSTR(command_file,1,LASTPOS("\",command_file))||, |
"UNZIPSFX.EXE" |
IF STREAM(unzipsfx,"C","QUERY EXISTS") = "" |
THEN |
DO |
SAY "We are unable to locate the UNZIPSFX.EXE source" |
SAY "Ensure that the ZIP2EXE command is in the directory", |
"which contains UNZIPSFX.EXE" |
rc = 9 |
SIGNAL FINI |
END |
/** Execute the command ** End Argument processing **/ |
ADDRESS CMD "@COPY /b "||unzipsfx||"+"||zip_file, |
sfx_file||" > NUL" |
IF rc = 0 |
THEN |
SAY sfx_file||" successfully created" |
ELSE |
SAY sfx_file||" creation failed" |
FINI: |
EXIT rc |
/programs/fs/unzip60/os2/zipgrep.cmd |
---|
0,0 → 1,56 |
/*--------------------------------------------------------------------------- |
zipgrep.cmd (ye olde REXX procedure for OS/2) |
Script to search members of a zipfile for a string or regular expression |
and print the names of any such members (and, optionally, the matching |
text). The search is case-insensitive by default. |
History: |
original Bourne shell version by Jean-loup Gailly |
modified by Greg Roelofs for Ultrix (no egrep -i) and zipinfo -1 |
OS/2 REXX script by Greg Roelofs |
Last modified: 19 Jul 93 |
---------------------------------------------------------------------------*/ |
PARSE ARG string zipfile members |
if (string == '') then do |
say 'usage: zipgrep search_string zipfile [members...]' |
say ' Displays the names of zipfile members containing a given string,' |
say ' in addition to the matching text. This procedure requires unzip' |
say ' and egrep in the current path, and it is quite slow....' |
exit 1 |
end |
/* doesn't seem to work... |
newq = RXQUEUE("Create",zipgrep_pipe) |
oldq = RXQUEUE("Set",newq) |
*/ |
/* flush the queue before starting */ |
do QUEUED() |
PULL junk |
end |
/* GRR: can also add "2>&1" before pipe in following external command */ |
'@unzip -Z1' zipfile members '| rxqueue' |
do while QUEUED() > 0 |
PARSE PULL file |
'@unzip -p' zipfile file '| egrep -is' string |
if rc == 0 then do |
SAY file':' |
/* can comment out following line if just want filenames */ |
'@unzip -p' zipfile file '| egrep -i' string |
end |
end |
/* |
call RXQUEUE "Delete",newq |
call RXQUEUE "Set",oldq |
*/ |
exit 0 |