Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6724 → Rev 6725

/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