summaryrefslogtreecommitdiff
path: root/tandem
diff options
context:
space:
mode:
Diffstat (limited to 'tandem')
-rw-r--r--tandem/HISTORY97
-rw-r--r--tandem/README95
-rw-r--r--tandem/commacs94
-rw-r--r--tandem/doit21
-rw-r--r--tandem/macros571
-rw-r--r--tandem/make130
-rw-r--r--tandem/tandem.c889
-rw-r--r--tandem/tandem.h236
-rw-r--r--tandem/tannsk.h19
-rw-r--r--tandem/tanzip.c723
-rw-r--r--tandem/tanzip.h43
-rw-r--r--tandem/zipup.h26
12 files changed, 2944 insertions, 0 deletions
diff --git a/tandem/HISTORY b/tandem/HISTORY
new file mode 100644
index 0000000..59d3429
--- /dev/null
+++ b/tandem/HISTORY
@@ -0,0 +1,97 @@
+Tandem Port History
+===================
+
+Hi, I'm Dave Smith and I work at BP Oil UK, looking after their European card
+processing system since 1992. We need to send lots of files via FTP to other
+BP machines (Novell, NT, Sun...). Sending large files was frowned upon, so the
+search for a zip product was on.
+
+We tried the GZIP product from Twinsoft Netherlands but it was complicated to
+use and it was not widely known by other arts of BP.
+
+What we really wanted was a PKZIP compatible product, as this is a widely known
+product. By chance when surfing the web I discovered the Info-ZIP web site.
+This claimed PKZIP 2.04g compatibility and had a number of ports, was free, and
+even had source code, but unfortunately no Tandem version :-(
+
+Thus in the autumn 1996 I bit the bullet and took on the job of porting the
+code to Tandem NSK (Guardian). This meant dusting off my circa 1985 'C'
+programming skills and firing up the Tandem 'C' compiler - not known for its
+ease of use, especially debugging 8-; This was all on D30 by the way.
+
+To start this off I had to choose an existing port to base te Tandem one on.
+Nearest (?) was the VM-CMS/MVS port by George Petrov. The main similarity
+being that these machines are record based, and have a similarish filing system
+to Guardian.
+
+First to be tackled was ZIP. By the end of 1996 I had a version which compiled
+and ran (giving the program banner) - which seemed like a major acheivement at
+the time.
+
+In December 1996 I forwarded a version of ZIP to Info-ZIP which wor
+ked only on Edit files, and had no concept of directories. Became ZIP 2.1
+
+By March 1997 I had improved ZIP so that it could cope with Unstructured files
+as well (Became ZIP 2.2). I also had ported a version of UNZIP which could
+create Unstructured files (not Edit) - UNZIP 5.20
+
+At the start of September 1997 I sent UNZIP with Edit file support to Info-ZIP
+(incorporated into 5.32)
+
+In March 1998 I submitted file I/O improvements (SBB) for ZIP (2.3a)
+
+In August 1998 I added Tandem DEFINE processing for ZIP (2.3e). This was a
+feature required by BP to allow them to store files with a different internal
+name than the physical file being zipped (without renaming it).
+Also added storing of proper UTC timestamps which allow for DST & timezone.
+
+Also in August I added the same file I/O improvements for UNZIP (5.33f)
+
+I then added the ability to update the unzipped files last modified and last
+open timestamps - this required help from TNSC to allow me access to the
+priviliged procedure call. Also can give the files back to the original user
+by use of the '-X' flag.
+
+At the end of 1998 I was given the go ahead to add the zipping of Enscribe
+files. This first version stores all Enscribe file attributes EXCEPT SQL, alt
+key and partition information.
+
+ZIP now uses its own Guardian I/O (rather than the 'C'library) for the reading
+of files to be zipped.
+
+Unstructured files use Large Transfer mode and READ (56K or 30K reads)
+Edit files use IOEdit routines
+Enscribe files use READ and SBB and add LF to the end of each record.
+
+UNZIP has the ability to update the filecode of files restored to ther original
+value (Unstructured only)
+
+
+To Do ZIP
+===========
+1. Change I/O to use NSK/Large Transfer mode in fwrite of ZIP file itself- this
+ will dramaticaly speed up updating an existing zipfile. When updating an
+ existing zipfile it copies it to a temporary file currently using only SBB.
+2. Add raw binary mode to allow storing of raw data in zip file - e.g. only to
+ be unzipped on Tandem ! This is simplest/fastest way to provide full
+ Enscribe support for Tandem platform - with no cross-platform support.
+3. Add SQL support !!
+
+To Do UNZIP
+===========
+1. Re-write the I/O routines to use NSK to recreate the original Enscribe file
+ structure.
+2. Use NSK Large Transfer mode I/O for reading/writing of ZIP file
+3. Add raw binary mode to allow restoration of Tandem file from previous raw
+ data ZIP (see above)
+4. Add SQL support !!
+
+
+
+Current Versions on Website
+===========================
+
+ZIP 2.3
+UNZIP 5.5
+
+As of February 17th 2002
diff --git a/tandem/README b/tandem/README
new file mode 100644
index 0000000..f877aeb
--- /dev/null
+++ b/tandem/README
@@ -0,0 +1,95 @@
+Tandem Port of Info ZIP (zip)
+=======================
+
+History:
+1. Tidy up COMMACS/MACROS/MAKE
+2. Changes for version 5.32d affected files:
+- TANDEMC (changes to stat() for UNZIP)
+- ZIPUPC (changes to use REVISIOH rather than REVISEH)
+- ZIPFILEC (don't add ".zip" to ZIP name)
+- FILEIOC (cosmetic missing "*/")
+3. Fix to allow zipping of files called ZIP (e.g. DAVES.ZIP)
+03/08/98 2.3e Process Tandem DEFINE names - use define name as internal name
+ Remove BITSO from build of ZIPLIB
+ New DOIT macro for extracting files from archive
+17/08/98 2.3e Set USE_EF_UT_TIME to allow for timezone changes
+18/08/98 2.3e Use define LICENSED to build object able to update timestamps
+30/11/98 2.3h Updated mapname/chmod/in2ex, include licensing in MAKE
+21/12/98 2.3i Add simple Enscribe file handling, consisting of:
+ - storing Enscribe files as LF delimited text files
+ - adding Tandem Extra Field, holding Enscribe file attributes
+ Create ZIP file with Tandem File Code 1001
+ Rationalised TANDEMH and TANDEMC wth UNZIP 5.40d
+12/01/99 2.3i Correct bug stopping setting of last open timestamp
+25/01/99 2.3k Add '-B' flag to zip Enscribe files with no record delimiters
+26/01/99 2.3k Make CRLF the default delimiter for Structured and Text files
+01/02/99 2.3k Use maximum size large transfer read (57344) as default, allow
+ smaller value as option
+01/02/99 2.3k Redefine -B flag for Edit/Enscribe files as in table below.
+ Default (-B or -B0 or no flag) is add CR/LF
+
+ -B<number> options at present are:
+ Bit 0 - Don't add delimiter (Edit/Enscribe)
+ Bit 1 - Use LF rather than CR/LF as delimiter (Edit/Enscribe)
+ Bit 2 - Space fill record to max record length (Enscribe)
+ Bit 3 - Trim trailing space (Edit/Enscribe)
+
+ Bit 8 - Force 30K (Expand) large read for Unstructured files
+
+06/02/99 2.3k Attempt to catch Large Transfer mode failure (err 21) when
+ attempting 56K reads, add substitute 30K reads (Expand files)
+24/03/99 2.3m Split TANDEMC into TANDEMC/TANZIPC/TANUNZC
+24/03/99 2.3m Added TANNSKH to allow for declarations which require
+ structures defined in ZIPH after call to TANDEMH
+11/05/99 2.3m Change zopen in TANZIPC to allow opening of files with
+ missing alt keys (err 4)
+ Assume not DST if can't resolve time (no DST table available)
+27/09/99 2.3o Fixed bug in -B0 option causing files to be stored rather than
+ deflated. Created TANZIPH
+29/04/02 2.4g Fixed contention on temporary file when multiple ZIPs run
+
+A few notes about the files on this subvol
+
+COMMACS - used by MAKE (compiler)
+DOIT - macro to extract required Tandem files from archive and rename
+MACROS - used by MAKE (bind)
+MAKE - recompile ZIP code, attempts to only recompile changed code
+README - this file
+ZIPLIB - library of ZIP compiled routines, used by ZIP/ZIPNOTE etc
+ZIPL - ZIP object (bound using LARGE memory model)
+ZIPNOTE - ZIPNOTE object (bound using LARGE memory model)
+
+*C - Source file
+*H - Header files
+*O - Individual object files (when compiled by MAKE)
+
+Install Notes:
+==============
+Stage 1 - get ZIP object onto Tandem
+- download Tandem Zip executables archive from Web
+- using PC unzip program (e.g. pkunzip/WinZip) extract ZIP
+- copy ZIP from PC to Tandem in Binary mode s(FTP/IXF)
+- alter file code to 100
+- optionally place in $SYSTEM.SYSTEM to allow easy access from command line
+
+Stage 2 - (optional) compile source code (requires UNZIP on Tandem)
+- download ZIP source archive fwom web - contains all supported platforms
+- copy archive onto Tandem as Binary
+- extract Tandem DOIT macro ( UNZIP -j <archive> tandem/DOIT )
+- update DOIT macro to point at archive file
+- restore relevant files by running DOIT
+- NOTE that revision.h must be restored as REVISIOH
+- replace references to $T with a collector on your system
+- replace references to SUPER.DAVES with whatever user id you use
+- to compile run MAKE (compiles, accelerates, licences)
+- NOTE: Always run the accelerated object on TNS/R systems, otherwise
+ it runs extremely slow.
+
+
+Additional Notes - LICENSE the object:
+======================================
+If you wish to be able to update the last modified time of the zip file
+(-o option) you need to add the line "#define LICENSED" to the TANDEMH file.
+If you set this option then you MUST FUP LICENSE the file as SUPER.SUPER.
+This is a Tandem restriction since we have to call a PRIV procedure to update
+the file label. For ZIP the define is setup (default) in tandem.h
diff --git a/tandem/commacs b/tandem/commacs
new file mode 100644
index 0000000..31e91a1
--- /dev/null
+++ b/tandem/commacs
@@ -0,0 +1,94 @@
+?section CC ROUTINE
+#FRAME
+[#PUSH file stem src obj htime file prev time stime otime
+ comp out options sup buf col locn group
+]
+
+[#IF [#ARGUMENT /VALUE file/ WORD /SPACE/ END]]
+[#IF [#EMPTYV file] |THEN|
+ #OUTPUT Syntax: CC <file> <collector> <comp-options>
+ #RESET FRAMES
+ #RETURN
+]
+
+[#IF NOT [#FILEINFO /EXISTENCE/ [file]]
+|THEN|
+ #OUTPUT [file] does not exist !
+ #RESET FRAMES
+ #RETURN
+]
+
+#PUSH #DEFAULTS vol subvol
+#SETMANY vol subvol src, [#FILEINFO /VOLUME, SUBVOL, FILE/ [file]]
+VOLUME [vol].[subvol]
+
+#SETV stem file
+#CHARDEL stem [#CHARCOUNT stem]
+#SET obj [stem]O
+#SETV stem src
+#CHARDEL stem [#CHARCOUNT stem]
+
+[#IF [#ARGUMENT /VALUE out/ DEVICE END]]
+[#IF [#EMPTYV out] |THEN| #SET out $T.#C]
+
+#SETMANY col group, [#FILEINFO /VOLUME, SUBVOL/ [out]]
+#SET locn [group].[stem]
+#SET sup [#LOOKUPPROCESS /ANCESTOR/ [col]]
+
+#SET options [#REST]
+
+== Find newest Header file
+#SET htime 0
+#SET file [#FILENAMES /MAXIMUM 1/ *H]
+[#LOOP |WHILE| NOT [#EMPTYV file]
+|DO|
+ #SET time [#FILEINFO /MODIFICATION/ [file]]
+ [#IF time > htime |THEN| #SETV htime time]
+
+ #SETV prev file
+ #SET file [#FILENAMES /MAXIMUM 1, PREVIOUS [prev]/ *H]
+]
+
+#SET stime [#FILEINFO /MODIFICATION/ [src]]
+#SET otime [#FILEINFO /MODIFICATION/ [obj]]
+
+#SET comp 0
+
+[#IF otime < htime
+|THEN|
+ #OUTPUT Header file(s) changed since object [obj] compiled
+ #SET comp -1
+]
+
+[#IF otime < stime
+|THEN|
+ #OUTPUT Source file [src] changed since object [obj] compiled
+ #SET comp -1
+]
+
+[#IF comp
+|THEN|
+ SPOOLCOM /OUTV buf/ OPEN [sup];JOB (OWNER, LOC [locn]),STATUS,DELETE !
+ #SET buf
+ #OUTPUT Compiling [src]... [options]
+ C /IN [src], OUT [out].[stem]/[obj];SYMBOLS,HIGHPIN [options]
+ [#CASE [tacl^completioncode]
+ | 0 |
+ #OUTPUT Compiled OK: [src]
+ SPOOLCOM /OUTV buf/ OPEN [sup];JOB (OWNER, LOC [locn]),STATUS,DELETE !
+ #SET _completion:completioncode 0
+ | 1 |
+ #OUTPUT [src]: Compile Warnings
+ SPOOLCOM /OUTV buf/ OPEN [sup];JOB (OWNER, LOC [locn]),STATUS
+ #OUTPUTV buf
+ |OTHERWISE|
+ #OUTPUT [src]: Compile FAILED !
+ SPOOLCOM /OUTV buf/ OPEN [sup];JOB (OWNER, LOC [locn]),STATUS
+ #OUTPUTV buf
+ ]
+|ELSE|
+ #OUTPUT Object file [obj] is up to date
+ #SET _completion:completioncode 0
+]
+
+#UNFRAME
diff --git a/tandem/doit b/tandem/doit
new file mode 100644
index 0000000..1388730
--- /dev/null
+++ b/tandem/doit
@@ -0,0 +1,21 @@
+?tacl macro
+#frame
+#push zipfile
+#SET zipfile [#FILEINFO /SUBVOL/ A]
+
+unzip -a [zipfile] *.c -x */*
+== Following not required
+RENAME apic apicz
+RENAME timezonc timezonz
+
+unzip -a [zipfile] *.h -x */*
+== Following not required
+RENAME apih apizh
+
+unzip -aj [zipfile] tandem/*.h
+
+unzip -aj [zipfile] tandem/*.c
+
+unzip -aj [zipfile] tandem/* -x tandem/*.*
+
+#unframe
diff --git a/tandem/macros b/tandem/macros
new file mode 100644
index 0000000..ab1505b
--- /dev/null
+++ b/tandem/macros
@@ -0,0 +1,571 @@
+?section ADD^LIST routine
+[#IF [#ARGUMENT /VALUE item/ WORD/SPACE/]]
+#APPEND bin ADD * FROM [item]
+#SET itime [#FILEINFO /MODIFICATION/ [item]]
+[#IF itime > ntime |THEN| #SETV ntime itime]
+
+?section BBZIPLIB MACRO
+#FRAME
+#push bin item ntime itime libtime
+#SET ntime 0
+
+#OUTPUT Building [lib]
+#APPEND bin CLEAR
+add^list CRC32O
+add^list CRYPTO
+add^list DEFLATEO
+add^list FILEIOO
+add^list GLOBALSO
+add^list TANDEMO
+add^list TANZIPO
+add^list TREESO
+add^list TTYIOO
+add^list UTILO
+add^list ZIPFILEO
+add^list ZIPUPO
+#APPEND bin INFO UNRESOLVED *
+#APPEND bin BUILD [lib] ! , LIST * OFF
+
+#SET libtime [#FILEINFO /MODIFICATION/ [lib]]
+[#IF libtime < ntime
+|THEN|
+ #OUTPUT [lib] needs re-building
+ BIND /NAME,INV BIN/
+ [#CASE [tacl^completioncode]
+ | 0 | #OUTPUT Bound [lib] OK
+ | 1 | #OUTPUT [lib]: BIND Failed with Warnings
+ | OTHERWISE | #OUTPUT [lib]: BIND Failed with ERRORS !
+ ]
+|ELSE|
+ #OUTPUT [lib] is up to date
+]
+
+#UNFRAME
+
+?section BBZIP MACRO
+#FRAME
+#push bin ziptime build
+#SET build 0
+#OUTPUT Building %1% with %2% memory model
+#APPEND bin CLEAR
+#APPEND bin ADD * FROM ZIPO
+#APPEND bin select search ($system.system.c%2%, [lib])
+#APPEND bin select runnable object on
+#APPEND bin select list * off
+#APPEND bin set heap 20 pages
+#APPEND bin set symbols on
+#APPEND bin set saveabend on
+#APPEND bin set inspect on
+#APPEND bin info unresolved *
+#APPEND bin BUILD %1% !
+
+#SET ziptime [#FILEINFO /MODIFICATION/ %1%]
+[#IF ziptime < [#FILEINFO /MODIFICATION/ ZIPO] |THEN|
+ #OUTPUT %1% is older than ZIPO
+ #SET build -1
+]
+[#IF ziptime < [#FILEINFO /MODIFICATION/ [lib]] |THEN|
+ #OUTPUT %1% is older than [lib]
+ #SET build -1
+]
+[#IF build
+|THEN|
+ #OUTPUT %1% is out of date, re-building
+ BIND /NAME,INV BIN/
+ [#CASE [tacl^completioncode]
+ | 0 | #OUTPUT Bound %1% OK
+ | 1 | #OUTPUT %1%: BIND Failed with Warnings
+ | OTHERWISE | #OUTPUT %1%: BIND Failed with ERRORS !
+ ]
+|ELSE|
+ #OUTPUT %1% is up to date, no re-build required
+]
+
+#UNFRAME
+
+?section BBANY MACRO
+#FRAME
+#push bin memory anytime build
+#SET build 0
+#SETMANY memory, %2% LARGE
+#OUTPUT Building %1% with [memory] memory model
+#APPEND bin CLEAR
+#APPEND bin ADD * FROM %1%O
+#APPEND bin select search ($system.system.c[memory],[lib])
+#APPEND bin select runnable object on
+#APPEND bin select list * off
+#APPEND bin set heap 20 pages
+#APPEND bin set symbols on
+#APPEND bin set saveabend on
+#APPEND bin set inspect on
+#APPEND bin info unresolved *
+#APPEND bin BUILD %1% !
+
+#SET anytime [#FILEINFO /MODIFICATION/ %1%]
+[#IF anytime < [#FILEINFO /MODIFICATION/ %1%O] |THEN|
+ #OUTPUT %1% is older than %1%O
+ #SET build -1
+]
+[#IF anytime < [#FILEINFO /MODIFICATION/ [lib]] |THEN|
+ #OUTPUT %1% is older than [lib]
+ #SET build -1
+]
+[#IF build
+|THEN|
+ #OUTPUT %1% is out of date, re-building
+ BIND /NAME,INV BIN/
+ [#CASE [tacl^completioncode]
+ | 0 | #OUTPUT Bound %1% OK
+ | 1 | #OUTPUT %1%: BIND Failed with Warnings
+ | OTHERWISE | #OUTPUT %1%: BIND Failed with ERRORS !
+ ]
+|ELSE|
+ #OUTPUT %1% is up to date, no re-build required
+]
+
+#UNFRAME
+
+
+?section BBUNZIPLIB MACRO
+#FRAME
+#push bin item ntime itime libtime
+#SET ntime 0
+
+#OUTPUT Building [lib]
+#APPEND bin CLEAR
+add^list CRC32O
+add^list CRYPTO
+add^list ENVARGSO
+add^list EXPLODEO
+add^list EXTRACTO
+add^list FILEIOO
+add^list GLOBALSO
+add^list INFLATEO
+add^list LISTO
+add^list MATCHO
+add^list PROCESSO
+add^list TANDEMO
+add^list TANUNZO
+add^list TTYIOO
+add^list UNSHRINO
+add^list ZIPINFOO
+#APPEND bin INFO UNRESOLVED *
+#APPEND bin BUILD [lib] ! , LIST * OFF
+
+#SET libtime [#FILEINFO /MODIFICATION/ [lib]]
+[#IF libtime < ntime
+|THEN|
+ #OUTPUT [lib] needs re-building
+ BIND /NAME,INV BIN/
+ [#CASE [tacl^completioncode]
+ | 0 | #OUTPUT Bound [lib] OK
+ | 1 | #OUTPUT [lib]: BIND Failed with Warnings
+ | OTHERWISE | #OUTPUT [lib]: BIND Failed with ERRORS !
+ ]
+|ELSE|
+ #OUTPUT [lib] is up to date
+]
+
+#UNFRAME
+
+?section BBUNZIP MACRO
+#FRAME
+#push bin ziptime build
+#SET build 0
+#OUTPUT Building %1% with %2% memory model
+#APPEND bin CLEAR
+#APPEND bin ADD * FROM UNZIPO
+#APPEND bin select search ($system.system.c%2%,[lib])
+#APPEND bin select runnable object on
+#APPEND bin select list * off
+#APPEND bin set heap 20 pages
+#APPEND bin set symbols on
+#APPEND bin set saveabend on
+#APPEND bin set inspect on
+#APPEND bin info unresolved *
+#APPEND bin BUILD %1% !
+
+#SET ziptime [#FILEINFO /MODIFICATION/ %1%]
+[#IF ziptime < [#FILEINFO /MODIFICATION/ UNZIPO] |THEN|
+ #OUTPUT %1% is older than UNZIPO
+ #SET build -1
+]
+[#IF ziptime < [#FILEINFO /MODIFICATION/ [lib]] |THEN|
+ #OUTPUT %1% is older than [lib]
+ #SET build -1
+]
+[#IF build
+|THEN|
+ #OUTPUT %1% is out of date, re-building
+ BIND /NAME,INV BIN/
+ [#CASE [tacl^completioncode]
+ | 0 | #OUTPUT Bound %1% OK
+ | 1 | #OUTPUT %1%: BIND Failed with Warnings
+ | OTHERWISE | #OUTPUT %1%: BIND Failed with ERRORS !
+ ]
+|ELSE|
+ #OUTPUT %1% is up to date, no re-build required
+]
+
+#UNFRAME
+
+?section BBSFXLIB MACRO
+#FRAME
+#push bin item ntime itime libtime
+#SET ntime 0
+
+#OUTPUT Building [lib]
+#APPEND bin CLEAR
+add^list CRC32O
+add^list EXTRACTX
+add^list FILEIOX
+add^list GLOBALSX
+add^list INFLATEX
+add^list MATCHX
+add^list PROCESSX
+add^list TANDEMX
+add^list TANUNZX
+add^list TTYIOX
+#APPEND bin INFO UNRESOLVED *
+#APPEND bin BUILD [lib] ! , LIST * OFF
+
+#SET libtime [#FILEINFO /MODIFICATION/ [lib]]
+[#IF libtime < ntime
+|THEN|
+ #OUTPUT [lib] needs re-building
+ BIND /NAME,INV BIN/
+ [#CASE [tacl^completioncode]
+ | 0 | #OUTPUT Bound [lib] OK
+ | 1 | #OUTPUT [lib]: BIND Failed with Warnings
+ | OTHERWISE | #OUTPUT [lib]: BIND Failed with ERRORS !
+ ]
+|ELSE|
+ #OUTPUT [lib] is up to date
+]
+
+#UNFRAME
+
+?section BBSFX MACRO
+#FRAME
+#push bin ziptime build
+#SET build 0
+#OUTPUT Building %1% with %2% memory model
+#APPEND bin CLEAR
+#APPEND bin ADD * FROM UNZIPX
+#APPEND bin select search ($system.system.c%2%,[lib])
+#APPEND bin select runnable object on
+#APPEND bin select list * off
+#APPEND bin set heap 20 pages
+#APPEND bin set symbols on
+#APPEND bin set saveabend on
+#APPEND bin set inspect on
+#APPEND bin info unresolved *
+#APPEND bin BUILD %1% !
+
+#SET ziptime [#FILEINFO /MODIFICATION/ %1%]
+[#IF ziptime < [#FILEINFO /MODIFICATION/ UNZIPX] |THEN|
+ #OUTPUT %1% is older than UNZIPX
+ #SET build -1
+]
+[#IF ziptime < [#FILEINFO /MODIFICATION/ [lib]] |THEN|
+ #OUTPUT %1% is older than [lib]
+ #SET build -1
+]
+[#IF build
+|THEN|
+ #OUTPUT %1% is out of date, re-building
+ BIND /NAME,INV BIN/
+ [#CASE [tacl^completioncode]
+ | 0 | #OUTPUT Bound %1% OK
+ | 1 | #OUTPUT %1%: BIND Failed with Warnings
+ | OTHERWISE | #OUTPUT %1%: BIND Failed with ERRORS !
+ ]
+|ELSE|
+ #OUTPUT %1% is up to date, no re-build required
+]
+
+#UNFRAME
+
+?section accel^file MACRO
+#FRAME
+#PUSH buf
+[#IF [#FILEINFO /MODIFICATION/ %1%]
+ > [#FILEINFO /MODIFICATION/ %2%]
+|THEN|
+ #OUTPUT %2% is older than %1%
+ #OUTPUT Accelerating %1% to %2%
+ AXCEL /OUTV buf/ %1%,%2%
+ #OUTPUTV buf
+ [#CASE [tacl^completioncode]
+ | 0 | #OUTPUT Accelerated %2% OK
+ | 1 | #OUTPUT %2%: AXCEL Failed with Warnings
+ | OTHERWISE | #OUTPUT %2%: AXCEL Failed with ERRORS !
+ ]
+|ELSE|
+ #OUTPUT %2% is up to date
+]
+
+#UNFRAME
+
+?section fup^license ROUTINE
+#FRAME
+#PUSH #DEFAULTS filename old^user current^user
+
+[#IF [#ARGUMENT /VALUE filename/ FILENAME]]
+
+#SET old^user [#USERNAME [#PROCESSINFO /PAID/]]
+#SETV current^user old^user
+[#LOOP |WHILE| current^user '<>' "SUPER.SUPER"
+ AND NOT [#INPUTEOF]
+|DO|
+ #OUTPUT Please log on as SUPER.SUPER (CTRL-Y aborts)
+ logon SUPER.SUPER
+ #SET current^user [#USERNAME [#PROCESSINFO /PAID/]]
+ #OUTPUT
+]
+
+[#IF current^user '=' "SUPER.SUPER" |THEN|
+ #OUTPUT Licensing [filename]
+ $SYSTEM.SYSTEM.FUP LICENSE [filename]
+]
+
+[#LOOP |WHILE| current^user '<>' old^user
+ AND NOT [#INPUTEOF]
+|DO|
+ #OUTPUT Please log on as [old^user] (CTRL-Y aborts)
+ logon [old^user]
+ #SET current^user [#USERNAME [#PROCESSINFO /PAID/]]
+ #OUTPUT
+]
+
+#UNFRAME
+
+
+?section CODE routine
+#FRAME
+#PUSH delta arg
+
+#SET /TYPE delta/ DELTA
+
+[#LOOP |WHILE| [#COMPUTE [#ARGUMENT /VALUE arg/ NUMBER END] = 1 ]
+|DO|
+ #APPEND DELTA [arg]I
+]
+
+#RESULT [#DELTA /COMMANDS DELTA/]
+
+#UNFRAME
+
+
+?section TACL^COMPLETIONCODE routine
+#RESULT [_completion:completioncode]
+
+?SECTION INCREMENT routine
+#FRAME
+#PUSH increment_variable increment_value
+
+[#IF [#ARGUMENT /VALUE increment_variable/ VARIABLE]]
+[#IF [#EMPTYV [increment_variable]]|THEN|#SET [increment_variable] 0]
+[#IF [#MORE]
+ |THEN|
+ [#IF [#ARGUMENT /VALUE increment_value/ NUMBER]]
+ |ELSE|
+ #SET increment_value 1
+]
+[#IF [#ARGUMENT END]]
+
+#SET [increment_variable] [#COMPUTE [increment_variable] + [increment_value]]
+
+#UNFRAME
+
+?section ERROR^IN^FUP^OUTPUT routine
+#FRAME
+#PUSH err output last line type
+
+#SETMANY err output, 0 0
+
+[#LOOP |WHILE| NOT [#EMPTYV fup^out]
+|DO|
+ #EXTRACTV fup^out line
+ [#SETMANY type, [#CHARGET line 1 TO 7] .]
+ [#CASE [type]
+ | ERROR | #SETMANY output err, -1 -1
+ | WARNING | #SET output -1
+ | OTHERWISE |
+ ]
+ [#IF output |THEN|
+ #OUTPUTV last
+ #OUTPUTV line
+ #SET output 0
+ #EXTRACTV fup^out line
+ ]
+ #SETV last line
+]
+
+#RESULT [err]
+
+#UNFRAME
+
+?section SECURE^FILE routine
+#FRAME
+
+[#DEF fup^out TEXT |BODY|]
+[#DEF fup^buf TEXT |BODY|]
+
+[#DEF fup^cmd MACRO |BODY|
+ FUP /OUTV fup^out/ %*%
+ #SETV fup^buf fup^out
+ [#IF [error^in^fup^output]
+ |THEN|
+ #OUTPUT Error detected in FUP output, ABORTING !!
+ #OUTPUT ..............................................................
+ #OUTPUTV fup^buf
+ #OUTPUT ..............................................................
+ #RAISE _BREAK
+ ]
+]
+
+[#DEF display^action MACRO |BODY|
+ [#IF NOT action |THEN|
+ #OUTPUT /HOLD/ Updating [file] ...
+ #SET action -1
+ #SET count 0
+ ]
+ #OUTPUT /COLUMN 3/ ... %*%
+]
+
+[#DEF display^noaction MACRO |BODY|
+ [#IF count
+ |THEN|
+ increment count
+ |ELSE|
+ #OUTPUT
+ #SET count 1
+ ]
+ [#IF count |THEN|
+ #OUTPUT /COLUMN [count]/ [code 27]A.
+ [#IF count > 75
+ |THEN|
+ #SET count 0
+ ]
+ ]
+]
+
+[#DEF process^file TEXT |BODY|
+ #SET action 0
+ #SETMANY cur^owner cur^security cur^license cur^progid, &
+ [#FILEINFO /OWNER, SECURITY, LICENSED, PROGID/ [file]]
+
+ #SET cur^owner [#USERNAME [cur^owner]]
+
+ [#IF NOT [#EMPTYV owner]
+ |THEN|
+ [#IF owner '<>' cur^owner
+ |THEN|
+ display^action giving to [owner] (was [cur^owner])
+ fup^cmd GIVE [file], [owner]
+ [#IF cur^progid
+ |THEN|
+ #OUTPUT /COLUMN 3/... WARNING! Loss of PROGID flag
+ #SET cur^progid 0
+ ]
+ ]
+ ]
+ [#IF NOT [#EMPTYV security]
+ |THEN|
+ [#IF security '<>' cur^security
+ |THEN|
+ display^action securing to [security] (was [cur^security])
+ fup^cmd SECURE [file], [security]
+ ]
+ ]
+ [#IF license |THEN|
+ [#IF NOT cur^license
+ |THEN|
+ display^action licensed
+ fup^cmd LICENSE [file]
+ ]
+ ]
+ [#IF progid |THEN|
+ [#IF NOT cur^progid
+ |THEN|
+ display^action PROGID flag set
+ fup^cmd SECURE [file],, PROGID
+ ]
+ ]
+ [#IF action
+ |THEN|
+ fup^cmd INFO [file]
+ |ELSE|
+ [#IF tflag
+ |THEN|
+ display^noaction
+ |ELSE|
+ #OUTPUT /HOLD/ Unchanged : [file]
+ [#IF cur^progid |THEN| #OUTPUT /COLUMN 39,HOLD/ P]
+ [#IF cur^license |THEN| #OUTPUT /COLUMN 40,HOLD/ L]
+ #OUTPUTV /COLUMN 43,HOLD/ cur^security
+ #OUTPUTV /COLUMN 50,HOLD/ cur^owner
+ #OUTPUT
+ ]
+ ]
+]
+
+#PUSH arg template file security owner progid license prev action count tflag
+#PUSH cur^security cur^owner cur^license cur^progid
+
+#SETMANY license progid, 0 0
+#SET count 0
+#SET tflag 0
+
+[#LOOP |WHILE| [#MORE]
+|DO|
+ [#CASE [#ARGUMENT /VALUE arg/ FILENAME
+ USER /USERNAME/
+ USER
+ SECURITY
+ KEYWORD /WORDLIST LICENSE/
+ KEYWORD /WORDLIST PROGID/
+ TEMPLATE
+ ]
+ | 1 | #SETV file arg
+ | 2 | #SETV owner arg
+ | 3 | #SET owner [#USERNAME [arg]]
+ | 4 | #SETV security arg
+ | 5 | #SET license -1
+ | 6 | #SET progid -1
+ | 7 | #SETV template arg
+ ]
+]
+[#IF [#ARGUMENT END]]
+
+
+[#IF [#EMPTYV template]
+|THEN|
+ #SETV template file
+|ELSE|
+ #SET tflag -1
+ #OUTPUT /HOLD/ Template : [template]
+ [#IF progid |THEN| #OUTPUT /COLUMN 39,HOLD/ P]
+ [#IF license |THEN| #OUTPUT /COLUMN 40,HOLD/ L]
+ [#IF NOT [#EMPTYV security] |THEN| #OUTPUTV /HOLD/ " "[security]""]
+ [#IF NOT [#EMPTYV owner] |THEN| #OUTPUTV /HOLD/ " [owner]"]
+ #OUTPUT
+]
+
+[#IF [#EMPTYV template]
+|THEN|
+ #OUTPUT ERROR! No filename specified
+ #RESET FRAMES
+ #RETURN
+|ELSE|
+ #SET file [#FILENAMES /MAXIMUM 1/ [template]]
+ [#LOOP |WHILE| NOT [#EMPTYV file]
+ |DO|
+ process^file
+ #SETV prev file
+ #SET file [#FILENAMES /MAXIMUM 1, PREVIOUS [prev]/ [template]]
+ ]
+]
+
+#UNFRAME
diff --git a/tandem/make b/tandem/make
new file mode 100644
index 0000000..84efb4d
--- /dev/null
+++ b/tandem/make
@@ -0,0 +1,130 @@
+?tacl routine
+#FRAME
+SINK [#LOAD /keep 1/ commacs]
+SINK [#LOAD /keep 1/ macros]
+
+[#PUSH file prev memory clib OK model zip lib accel unlicensed licensed
+ options fileset nocrypt crypt
+]
+#PUSH #DEFAULTS
+
+#SET OK -1
+
+[#IF [#ARGUMENT /VALUE memory/ KEYWORD /WORDLIST LARGE SMALL/ OTHERWISE ]]
+[#IF [#ARGUMENT /VALUE model/ KEYWORD /WORDLIST NOWIDE WIDE/ OTHERWISE ]]
+[#IF [#ARGUMENT /VALUE unlicensed/ KEYWORD /WORDLIST UNLICENSED/ OTHERWISE ]]
+[#IF [#ARGUMENT /VALUE nocrypt/ KEYWORD /WORDLIST NOCRYPT/ OTHERWISE ]]
+[#IF [#ARGUMENT /VALUE fileset/ TEMPLATE FILENAME OTHERWISE ]]
+
+[#IF [#EMPTYV memory] |THEN| #SET memory LARGE]
+[#IF [#EMPTYV model] |THEN| #SET model NOWIDE]
+
+[#IF model '=' "WIDE"
+ |THEN| #SETV clib model
+ |ELSE| #SETV clib memory
+]
+
+[#IF model '=' "WIDE"
+|THEN|
+ #SET zip ZIPW
+|ELSE|
+ #SET zip ZIPL
+]
+#SET lib [zip]B
+#SET accel ZIP
+#SET options [options], [model]
+
+[#IF unlicensed '=' "UNLICENSED"
+|THEN|
+ #SET zip [zip]U
+ #SET accel [accel]U
+ #SET lib [lib]U
+|ELSE|
+ #SET licensed LICENSED
+ #SET options [options], define [licensed]
+]
+
+[#IF nocrypt '=' "NOCRYPT"
+|THEN|
+|ELSE|
+ #SET crypt USE_CRYPT
+ #SET options [options], define [crypt]
+]
+
+[#IF [#EMPTYV fileset] |THEN| #SET fileset *C]
+
+#OUTPUT Files to compile: [fileset]
+#OUTPUT Pointer Model : [model]
+#OUTPUT Memory Model : [memory]
+#OUTPUT C Library : [clib]
+#OUTPUT Axcel Object : [accel]
+#OUTPUT Run Object : [zip]
+#OUTPUT Library Object : [lib]
+#OUTPUT Compile Options : [options]
+#OUTPUT
+
+#SET file [#FILENAMES /MAXIMUM 1/ [fileset]]
+[#loop |while| NOT [#EMPTYV file]
+|do|
+ #SETV prev file
+ CC [file] $T.#ZIP [options]
+ [#IF [tacl^completioncode] > 1 |THEN| #set OK 0 ]
+ #SET file [#FILENAMES /MAXIMUM 1, PREVIOUS [prev]/ [fileset]]
+]
+
+[#IF OK |THEN|
+ BBZIPLIB
+ [#IF [tacl^completioncode] > 0 |THEN| #SET OK 0]
+]
+
+#PUSH #PROCESSFILESECURITY
+VOLUME ,"NUNU"
+
+[#IF OK |THEN|
+ BBZIP [zip] [clib]
+ [#IF [tacl^completioncode] > 0 |THEN| #SET OK 0]
+]
+
+[#IF OK |THEN|
+ secure^file [accel] "UUUU" SUPER.DAVES
+ accel^file [zip] [accel]
+ [#IF [tacl^completioncode] > 0 |THEN| #SET OK 0]
+]
+
+[#IF OK
+ |THEN| #OUTPUT Successfully produced Accelerated Object [accel]
+ secure^file [accel] "UUUU" SUPER.DAVES
+ [#IF [#INTERACTIVE] |THEN|
+ [#IF licensed '=' "LICENSED" |THEN|
+ #OUTPUT [accel] will not run without being LICENSED
+ [#IF [#FILEINFO /LICENSED/ [accel]]
+ |THEN|
+ #OUTPUT [accel] already LICENSED
+ |ELSE|
+ [#IF [#MATCH Y* [#INPUT [accel] License [accel] ?]] |THEN|
+ fup^license [accel]
+ ]
+ ]
+ ]
+ ]
+ |ELSE| #OUTPUT Failed to produce Accelerated Object [accel]
+]
+
+#OUTPUT Finished
+
+#OUTPUT Setting up additonal utilities
+== ZIPNOTE
+CC ZIPNOTEC $T.#ZIP [options]
+#SET zip ZIPNOTE
+#SET accel ZIPNOTE
+[#IF OK |THEN|
+ BBANY [zip] [clib]
+ [#IF [tacl^completioncode] > 0 |THEN| #SET OK 0]
+]
+[#IF OK |THEN|
+ secure^file [accel] "UUUU" SUPER.DAVES
+ accel^file [zip] [accel]
+ [#IF [tacl^completioncode] > 0 |THEN| #SET OK 0]
+]
+
+#UNFRAME
diff --git a/tandem/tandem.c b/tandem/tandem.c
new file mode 100644
index 0000000..0aa1e06
--- /dev/null
+++ b/tandem/tandem.c
@@ -0,0 +1,889 @@
+/*
+ Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*
+ * routines common to TANDEM (ZIP and UNZIP)
+ */
+
+#include "zip.h" /* This sets up ZIP / UNZIP define */
+
+#include <tal.h>
+#include "$system.zsysdefs.zsysc" nolist
+#include <cextdecs> nolist
+#include "tannsk.h"
+
+static time_t gmt_to_time_t (long long *);
+
+int isatty (fnum)
+int fnum;
+{
+ return 1;
+}
+
+/********************/
+/* Function in2ex() */
+/********************/
+
+#ifdef UNZIP
+char *in2ex(__G__ n)
+ __GDEF
+#else
+char *in2ex(n)
+#endif
+ char *n; /* internal file name */
+/* Convert the zip file name to an external file name, returning the malloc'ed
+ string or NULL if not enough memory. */
+{
+ char *x; /* external file name buffer */
+ char *y; /* pointer to external buffer */
+ char *max; /* pointer to max end of next file part */
+ char *t; /* pointer to internal - start of substring */
+ char *p; /* pointer to internal - TANDEM delimiter */
+ char *e; /* pointer to internal - DOS extension delimiter */
+ char *z; /* pointer to internal - end of substring */
+ int len; /* length of substring to copy to external name */
+ int allow_dollar; /* $ symbol allowed as next character */
+
+ if ((x = malloc(strlen(n) + 4)) == NULL) /* + 4 for safety */
+ return NULL;
+
+ *x = '\0';
+
+ /* Junk pathname as requested */
+#ifdef UNZIP
+ if (uO.jflag && (t = strrchr(n, INTERNAL_DELIMITER)) != NULL)
+ ++t;
+ else
+ t = n;
+#endif /* UNZIP */
+#ifdef ZIP
+ if (!pathput)
+ t = last(n, INTERNAL_DELIMITER);
+ else
+ t = n;
+#endif /* ZIP */
+
+ allow_dollar = TRUE;
+
+ while (*t != '\0') { /* File part could be sys, vol, subvol or file */
+ if (*t == INTERNAL_DELIMITER) { /* System, Volume or Subvol Name */
+ t++;
+ if (*t == INTERNAL_DELIMITER) { /* System */
+ strcat(x, TANDEM_NODE_STR);
+ t++;
+ }
+ else {
+ strcat(x, TANDEM_DELIMITER_STR);
+ allow_dollar = FALSE;
+ }
+ }
+ /* Work out where end of current external string is */
+ y = x + strlen(x);
+
+ /* Work out substring to copy and externalise */
+ p = strchr(t, INTERNAL_DELIMITER);
+ e = strchr(t, DOS_EXTENSION);
+ if (p != NULL) {
+ if (e > p)
+ e = NULL;
+ }
+
+ z = e;
+ if (z == NULL)
+ z = p;
+ if (z == NULL)
+ z = t + strlen(t);
+
+ /* can't have Tandem name longer than 8 characters */
+ max = y + MAXFILEPARTLEN;
+
+ /* Allow $ symbol as first character in some cases */
+ if (*t == '$') {
+ if (allow_dollar)
+ *y++ = *t++;
+ else;
+ *t++;
+ }
+
+ /* Make sure first real character is alpha */
+ if (! isalpha(*t) )
+ *y++ = 'A';
+
+ /* Characters left to process */
+ len = z - t;
+
+ while ( len > 0 ) {
+ if ( isalnum(*t) ) {
+ *y++ = toupper(*t++);
+ if (y >= max)
+ break;
+ }
+ else
+ t++;
+ len--;
+ }
+ *y = '\0';
+ t = p;
+
+ if (p == NULL) {
+ /* Last part of filename, store pseudo extension if available */
+ if (e != NULL) {
+ strcat(x, TANDEM_EXTENSION_STR);
+ y = x + strlen(x);
+
+ /* no restriction on extension length as its virtual */
+ z = e + 1;
+ while ( *z != '\0' ) {
+ *y++ = toupper(*z++);
+ }
+ *y = '\0';
+ }
+ break;
+ }
+ }
+
+ return x;
+}
+
+void zexit(status)
+ int status;
+{
+ /* Exit(>0) creates saveabend files */
+ terminate_program (0,0,(short)status,,,);
+}
+
+/************************/
+/* Function zputc() */
+/************************/
+
+#ifdef putc
+# undef putc
+#endif
+
+int zputc(ch, fptr)
+ int ch;
+ FILE *fptr;
+{
+ int err;
+ err = putc(ch,fptr);
+ fflush(fptr);
+ return err;
+}
+#define putc zputc
+
+#ifdef LICENSED
+_tal _priv short FILE_CHANGELABEL_ (
+ short, /* IN */
+ short, /* IN */
+ const short _far * /* IN */
+ );
+
+_c _callable int changelabel OF((short, const short *, const short *));
+
+_c _callable int changelabel(fnum, modtime, actime)
+ short fnum;
+ const short *modtime;
+ const short *actime;
+{
+ int err;
+
+ err = FILE_CHANGELABEL_(fnum, 16, modtime);
+ if (!err)
+ err = FILE_CHANGELABEL_(fnum, 17, actime);
+ return err;
+}
+
+int islicensed(void)
+{
+ #define plist_items 1
+ #define plist_size 10
+
+ short myphandle[ZSYS_VAL_PHANDLE_WLEN];
+ short licensetag[plist_items] = {37};
+ short licensed[plist_size];
+ short maxlen = plist_size;
+ short items = plist_items;
+ short resultlen[1], err;
+
+ err = PROCESSHANDLE_NULLIT_(myphandle);
+
+ if (!err)
+ err = PROCESS_GETINFO_(myphandle);
+
+ if (!err)
+ err = PROCESS_GETINFOLIST_(/*cpu*/,
+ /*pin*/,
+ /*nodename*/,
+ /*nodenamelen*/,
+ myphandle,
+ licensetag,
+ items,
+ licensed,
+ maxlen,
+ resultlen
+ );
+
+ if (err != 0)
+ return 0;
+ else
+ return licensed[0];
+}
+#endif /* LICENSED */
+
+int utime(file, time)
+ const char *file;
+ const ztimbuf *time;
+{
+#ifdef LICENSED
+ int result, err;
+ union timestamp_ov {
+ long long fulltime;
+ short wordtime[4];
+ };
+ union timestamp_ov lasttime, opentime;
+ struct tm *modt, *opent;
+ short datetime[8], errormask[1];
+ short len, fnum, access, exclus, options;
+ char fname[FILENAME_MAX + 1];
+ short extension;
+ char ext[EXTENSION_MAX + 1];
+
+ if (islicensed() ) {
+ /* Attempt to update file label */
+ modt = gmtime( &time->modtime );
+
+ datetime[0] = modt->tm_year + 1900;
+ datetime[1] = modt->tm_mon + 1;
+ datetime[2] = modt->tm_mday;
+ datetime[3] = modt->tm_hour;
+ datetime[4] = modt->tm_min;
+ datetime[5] = modt->tm_sec;
+ datetime[6] = datetime[7] = 0;
+ errormask[0] = 0;
+ lasttime.fulltime = COMPUTETIMESTAMP (datetime, errormask);
+
+ opent = gmtime( &time->actime );
+
+ datetime[0] = opent->tm_year + 1900;
+ datetime[1] = opent->tm_mon + 1;
+ datetime[2] = opent->tm_mday;
+ datetime[3] = opent->tm_hour;
+ datetime[4] = opent->tm_min;
+ datetime[5] = opent->tm_sec;
+ datetime[6] = datetime[7] = 0;
+ errormask[0] = 0;
+ opentime.fulltime = COMPUTETIMESTAMP (datetime, errormask);
+
+ /* Remove any (pseudo) file extension */
+ extension = parsename (file,fname,ext);
+ len = strlen(fname);
+
+ access = NSK_WRONLY;
+ exclus = NSK_SHARED;
+ options = NSK_NOUPDATEOPENTIME;
+
+ extension = parsename (file,fname,ext);
+ len = strlen(fname);
+
+ err = FILE_OPEN_((char *)fname, len, &fnum, access, exclus,,,options,,,);
+ result = changelabel(fnum,lasttime.wordtime,opentime.wordtime);
+ err = FILE_CLOSE_(fnum);
+ return result;
+ }
+ return -1;
+#else /* !LICENSED */
+ return 0; /* "no error", to suppress annoying failure messages */
+#endif /* ?LICENSED */
+}
+
+/* TANDEM version of chmod() function */
+
+int chmod(file, unix_sec)
+ const char *file;
+ mode_t unix_sec;
+{
+ FILE *stream;
+ struct nsk_sec_type {
+ unsigned progid : 1;
+ unsigned clear : 1;
+ unsigned null : 2;
+ unsigned read : 3;
+ unsigned write : 3;
+ unsigned execute: 3;
+ unsigned purge : 3;
+ };
+ union nsk_sec_ov {
+ struct nsk_sec_type bit_ov;
+ short int_ov;
+ };
+ union nsk_sec_ov nsk_sec;
+ short fnum, err, nsk_sec_int;
+ short len, access, exclus, extension, options;
+ char fname[FILENAME_MAX + 1];
+ char ext[EXTENSION_MAX + 1];
+
+ nsk_sec.bit_ov.progid = 0;
+ nsk_sec.bit_ov.clear = 0;
+ nsk_sec.bit_ov.null = 0;
+
+ /* 4="N", 5="C", 6="U", 7="-" */
+
+ if (unix_sec & S_IROTH) nsk_sec.bit_ov.read = 4;
+ else if (unix_sec & S_IRGRP) nsk_sec.bit_ov.read = 5;
+ else if (unix_sec & S_IRUSR) nsk_sec.bit_ov.read = 6;
+ else nsk_sec.bit_ov.read = 7;
+
+ if (unix_sec & S_IWOTH) nsk_sec.bit_ov.write = 4;
+ else if (unix_sec & S_IWGRP) nsk_sec.bit_ov.write = 5;
+ else if (unix_sec & S_IWUSR) nsk_sec.bit_ov.write = 6;
+ else nsk_sec.bit_ov.write = 7;
+
+ if (unix_sec & S_IXOTH) nsk_sec.bit_ov.execute = 4;
+ else if (unix_sec & S_IXGRP) nsk_sec.bit_ov.execute = 5;
+ else if (unix_sec & S_IXUSR) nsk_sec.bit_ov.execute = 6;
+ else nsk_sec.bit_ov.execute = 7;
+
+ nsk_sec.bit_ov.purge = nsk_sec.bit_ov.write;
+
+ nsk_sec_int = nsk_sec.int_ov;
+
+ access = NSK_RDONLY;
+ exclus = NSK_SHARED;
+ options = NSK_NOUPDATEOPENTIME;
+
+ extension = parsename (file,fname,ext);
+ len = strlen(fname);
+
+ err = FILE_OPEN_((char *)fname, len, &fnum, access, exclus,,,options,,,);
+ err = (SETMODE(fnum, SET_FILE_SECURITY, nsk_sec_int) != CCE);
+ err = FILE_CLOSE_(fnum);
+
+ return (err != 0 ? -1 : 0);
+}
+
+/* TANDEM version of chown() function */
+
+int chown(file, uid, gid)
+ const char *file;
+ uid_t uid;
+ gid_t gid;
+{
+ FILE *stream;
+ struct nsk_own_type {
+ unsigned group : 8;
+ unsigned user : 8;
+ };
+ union nsk_own_ov {
+ struct nsk_own_type bit_ov;
+ short int_ov;
+ };
+ union nsk_own_ov nsk_own;
+ short fnum, err, nsk_own_int;
+ short len, access, exclus, extension, options;
+ char fname[FILENAME_MAX + 1];
+ char ext[EXTENSION_MAX + 1];
+
+ nsk_own.bit_ov.group = gid;
+ nsk_own.bit_ov.user = uid;
+
+ nsk_own_int = nsk_own.int_ov;
+
+ access = NSK_RDONLY;
+ exclus = NSK_SHARED;
+ options = NSK_NOUPDATEOPENTIME;
+
+ extension = parsename (file,fname,ext);
+ len = strlen(fname);
+
+ err = FILE_OPEN_((char *)fname, len, &fnum, access, exclus,,,options,,,);
+ err = (SETMODE(fnum, SET_FILE_OWNER, nsk_own_int) != CCE);
+ err = FILE_CLOSE_(fnum);
+ return (err != 0 ? -1 : 0);
+}
+
+/* TANDEM version of getch() - non-echo character reading */
+int zgetch(void)
+{
+ char ch;
+ short f, err, count, fnum, rlen;
+
+ rlen = 1;
+ f = (short)fileno(stdin);
+ fnum = fdtogfn (f);
+ #define ECHO_MODE 20
+ err = (SETMODE(fnum, ECHO_MODE, 0) != CCE);
+ err = (READX(fnum, &ch, rlen, (short *) &count) != CCE);
+ err = (SETMODE(fnum, ECHO_MODE, 1) != CCE);
+
+ if (err)
+ if (err != 1)
+ return EOF;
+ else
+ ch = 'q';
+ else
+ if (count == 0)
+ ch = '\r';
+
+ return (int)ch;
+}
+
+short parsename(srce, fname, ext)
+ const char *srce;
+ char *fname;
+ char *ext;
+{
+ /* As a way of supporting DOS extensions from Tandem we look for a space
+ separated extension string after the Guardian filename
+ e.g. ZIP ZIPFILE "$DATA4.TESTING.INVOICE TXT"
+ */
+
+ char *fstart;
+ char *fptr;
+ short extension = 0;
+
+ *fname = *ext = '\0'; /* set to null string */
+
+ fstart = (char *) srce;
+
+ if ((fptr = strrchr(fstart, TANDEM_EXTENSION)) != NULL) {
+ extension = 1;
+
+ fptr++;
+ strncat(ext, fptr, _min(EXTENSION_MAX, strlen(fptr)));
+
+ fptr = strchr(fstart, TANDEM_EXTENSION); /* End of filename */
+ strncat(fname, fstart, _min(FILENAME_MAX, (fptr - fstart)));
+ }
+ else {
+ /* just copy string */
+ strncat(fname, srce, _min(FILENAME_MAX, strlen(srce)));
+ }
+
+ return extension;
+}
+
+static time_t gmt_to_time_t (gmt)
+ long long *gmt;
+{
+ #define GMT_TO_LCT 0
+ #define GMT_TO_LST 1
+
+ struct tm temp_tm;
+ short date_time[8];
+ long julian_dayno;
+ long long lct, lst, itime;
+ short err[1], type;
+
+ type = GMT_TO_LCT;
+ lct = CONVERTTIMESTAMP(*gmt, type,, err);
+
+ if (!err[0]) {
+ type = GMT_TO_LST;
+ lst = CONVERTTIMESTAMP(*gmt, type,, err);
+ }
+
+ itime = (err[0] ? *gmt : lct);
+ /* If we have no DST in force then make sure we give it a value,
+ else mktime screws up if we set the isdst flag to -1 */
+ temp_tm.tm_isdst = (err[0] ? 0 : ((lct == lst) ? 0 : 1));
+
+ julian_dayno = INTERPRETTIMESTAMP(itime, date_time);
+
+ temp_tm.tm_sec = date_time[5];
+ temp_tm.tm_min = date_time[4];
+ temp_tm.tm_hour = date_time[3];
+ temp_tm.tm_mday = date_time[2];
+ temp_tm.tm_mon = date_time[1] - 1; /* C's so sad */
+ temp_tm.tm_year = date_time[0] - 1900; /* it's almost funny */
+
+ return (mktime(&temp_tm));
+}
+
+/* TANDEM version of stat() function */
+int stat(n, s)
+ const char *n;
+ struct stat *s;
+{
+ #define ilist_items 26
+ #define klist_items 4
+ #define slist_items 3
+ #define ulist_items 1
+ #define flist_size 100
+
+ short err, i, extension;
+ char fname[FILENAME_MAX + 1];
+ short fnamelen;
+ char ext[EXTENSION_MAX + 1];
+
+ /* #0 #1 #2 #3 #4 #5 #6 #7 #8 #9 */
+ short ilist[ilist_items]={56,144, 54,142, 58, 62, 60, 41, 42, 44,
+ 50, 51, 52, 61, 63, 66, 67, 70, 72, 73,
+ 74, 75, 76, 77, 78, 79 };
+ short ilen[ilist_items] ={ 4, 4, 4, 2, 1, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1 };
+ short ioff[ilist_items];
+
+ /* #0 #1 #2 #3 #4 #5 #6 #7 #8 #9 */
+ short klist[klist_items]={45, 46, 68, 69 };
+ short klen[klist_items] ={ 1, 1, 1, 1 };
+ short koff[klist_items];
+
+ /* #0 #1 #2 #3 #4 #5 #6 #7 #8 #9 */
+ short slist[slist_items]={43, 80, 90 };
+ short slen[slist_items] ={ 1, 1, 1 };
+ short soff[slist_items];
+
+ /* #0 #1 #2 #3 #4 #5 #6 #7 #8 #9 */
+ short ulist[ulist_items]={65 };
+ short ulen[ulist_items] ={ 1 };
+ short uoff[ulist_items];
+
+ short flist[flist_size];
+ short extra[2];
+ short *rlen=&extra[0];
+ short *err_item=&extra[1];
+ unsigned short *fowner;
+ unsigned short *fprogid;
+ char *fsec;
+
+ nsk_stat_ov *nsk_ov;
+ nsk_file_attrs *nsk_attr;
+
+ short end, count, kind, level, options, searchid;
+ short info[5];
+
+ /* Initialise stat structure */
+ s->st_dev = _S_GUARDIANOBJECT;
+ s->st_ino = 0;
+ s->st_nlink = 0;
+ s->st_rdev = 0;
+ s->st_uid = s->st_gid = 0;
+ s->st_size = 0;
+ s->st_atime = s->st_ctime = s->st_mtime = 0;
+ s->st_reserved[0] = 0;
+ s->st_reserved[1] = 0;
+ s->st_reserved[2] = 0;
+ nsk_ov = (nsk_stat_ov *)&s->st_reserved[0];
+ nsk_attr = (nsk_file_attrs *)&nsk_ov->ov.nsk_ef_region;
+
+ /* Check to see if name contains a (pseudo) file extension */
+ extension = parsename (n,fname,ext);
+
+ fnamelen = strlen(fname);
+
+ options = 3; /* Allow Subvols and Templates */
+ err = FILENAME_SCAN_( fname,
+ fnamelen,
+ &count,
+ &kind,
+ &level,
+ options
+ );
+
+ /* allow kind == 2 (DEFINE names) */
+ if (err != 0) return -1;
+
+ if (kind == 1 || (kind == 0 && level < 2)) {
+ /* Pattern, Subvol Name or One part Filename - lets see if it exists */
+ err = FILENAME_FINDSTART_ ( &searchid,
+ fname,
+ fnamelen,
+ ,
+ DISK_DEVICE
+ );
+
+ if (err != 0) {
+ end = FILENAME_FINDFINISH_ ( searchid );
+ return -1;
+ }
+
+ err = FILENAME_FINDNEXT_ ( searchid,
+ fname,
+ FILENAME_MAX,
+ &fnamelen,
+ info
+ );
+ end = FILENAME_FINDFINISH_ ( searchid );
+
+ if (err != 0)
+ return -1; /* Non existing template, subvol or file */
+
+ if (kind == 1 || info[2] == -1) {
+ s->st_mode = S_IFDIR; /* Its an existing template or directory */
+ return 0;
+ }
+
+ /* Must be a real file so drop to code below to get info on it */
+ }
+
+ err = FILE_GETINFOLISTBYNAME_( fname,
+ fnamelen,
+ ilist,
+ ilist_items,
+ flist,
+ flist_size,
+ rlen,
+ err_item
+ );
+ if (err != 0) return -1;
+
+ ioff[0] = 0;
+
+ /* Build up table of offets into result list */
+ for (i=1; i < ilist_items; i++)
+ ioff[i] = ioff[i-1] + ilen[i-1];
+
+ /* Set up main stat fields */
+
+ /* Setup timestamps */
+ s->st_atime = gmt_to_time_t ((long long *)&flist[ioff[0]]);
+ s->st_mtime = s->st_ctime = gmt_to_time_t ((long long *)&flist[ioff[1]]);
+ nsk_ov->ov.creation_time = gmt_to_time_t ((long long *)&flist[ioff[2]]);
+
+ s->st_size = *(off_t *)&flist[ioff[3]];
+
+ fowner = (unsigned short *)&flist[ioff[4]];
+ s->st_uid = *fowner & 0x00ff;
+ s->st_gid = *fowner >> 8;
+
+ /* Note that Purge security (fsec[3]) in NSK has no relevance to stat() */
+ fsec = (char *)&flist[ioff[5]];
+ fprogid = (unsigned short *)&flist[ioff[6]];
+
+ s->st_mode = S_IFREG | /* Regular File */
+ /* Parse Read Flag */
+ ((fsec[0] & 0x03) == 0x00 ? S_IROTH : 0) |
+ ((fsec[0] & 0x02) == 0x00 ? S_IRGRP : 0) |
+ ((fsec[0] & 0x03) != 0x03 ? S_IRUSR : 0) |
+ /* Parse Write Flag */
+ ((fsec[1] & 0x03) == 0x00 ? S_IWOTH : 0) |
+ ((fsec[1] & 0x02) == 0x00 ? S_IWGRP : 0) |
+ ((fsec[1] & 0x03) != 0x03 ? S_IWUSR : 0) |
+ /* Parse Execute Flag */
+ ((fsec[2] & 0x03) == 0x00 ? S_IXOTH : 0) |
+ ((fsec[2] & 0x02) == 0x00 ? S_IXGRP : 0) |
+ ((fsec[2] & 0x03) != 0x03 ? S_IXUSR : 0) |
+ /* Parse Progid */
+ (*fprogid == 1 ? (S_ISUID | S_ISGID) : 0) ;
+
+ /* Set up NSK additional stat fields */
+ nsk_attr->progid = (unsigned) flist[ioff[6]];
+ nsk_attr->filetype = (unsigned) flist[ioff[7]];
+ nsk_attr->filecode = (unsigned) flist[ioff[8]];
+ nsk_attr->block = (unsigned short) flist[ioff[9]];
+ nsk_attr->priext = (unsigned short) flist[ioff[10]];
+ nsk_attr->secext = (unsigned short) flist[ioff[11]];
+ nsk_attr->maxext = (unsigned short) flist[ioff[12]];
+ nsk_attr->flags.clearonpurge = (unsigned) flist[ioff[13]];
+ nsk_attr->licensed = (unsigned) flist[ioff[14]];
+ nsk_attr->flags.audited = (unsigned) flist[ioff[15]];
+ nsk_attr->flags.acompress = (unsigned) flist[ioff[16]];
+ nsk_attr->flags.refresheof = (unsigned) flist[ioff[17]];
+ nsk_attr->flags.buffered = (unsigned) (flist[ioff[18]] == 0 ? 1 : 0);
+ nsk_attr->flags.verified = (unsigned) flist[ioff[19]];
+ nsk_attr->flags.serial = (unsigned) flist[ioff[20]];
+ nsk_attr->flags.crashopen = (unsigned) flist[ioff[22]];
+ nsk_attr->flags.rollforward = (unsigned) flist[ioff[23]];
+ nsk_attr->flags.broken = (unsigned) flist[ioff[24]];
+ nsk_attr->flags.corrupt = (unsigned) flist[ioff[25]];
+ nsk_attr->fileopen = (unsigned) flist[ioff[21]];
+
+
+ if (nsk_attr->filetype == NSK_UNSTRUCTURED) {
+ /* extra info for Unstructured files */
+ err = FILE_GETINFOLISTBYNAME_( fname,
+ fnamelen,
+ ulist,
+ ulist_items,
+ flist,
+ flist_size,
+ rlen,
+ err_item
+ );
+ if (err != 0) return -1;
+
+ uoff[0] = 0;
+
+ /* Build up table of offets into result list */
+ for (i=1; i < ulist_items; i++)
+ uoff[i] = uoff[i-1] + ulen[i-1];
+ }
+ else {
+ /* extra info for Structured files */
+ err = FILE_GETINFOLISTBYNAME_( fname,
+ fnamelen,
+ slist,
+ slist_items,
+ flist,
+ flist_size,
+ rlen,
+ err_item
+ );
+ if (err != 0) return -1;
+
+ soff[0] = 0;
+
+ /* Build up table of offets into result list */
+ for (i=1; i < slist_items; i++)
+ soff[i] = soff[i-1] + slen[i-1];
+
+ nsk_attr->reclen = (unsigned) flist[soff[0]];
+ nsk_attr->flags.secpart = (unsigned) flist[soff[1]];
+ nsk_attr->flags.primpart = (unsigned)
+ ( (flist[soff[2]] > 0 && nsk_attr->flags.secpart == 0) ? 1 : 0 );
+
+ if (nsk_attr->filetype == NSK_KEYSEQUENCED) {
+ /* extra info for Key Sequenced files */
+ err = FILE_GETINFOLISTBYNAME_( fname,
+ fnamelen,
+ klist,
+ klist_items,
+ flist,
+ flist_size,
+ rlen,
+ err_item
+ );
+ if (err != 0) return -1;
+
+ koff[0] = 0;
+
+ /* Build up table of offets into result list */
+ for (i=1; i < klist_items; i++)
+ koff[i] = koff[i-1] + klen[i-1];
+
+ nsk_attr->keyoff = (unsigned) flist[koff[0]];
+ nsk_attr->keylen = (unsigned) flist[koff[1]];
+ nsk_attr->flags.dcompress = (unsigned) flist[koff[2]];
+ nsk_attr->flags.icompress = (unsigned) flist[koff[3]];
+ }
+ }
+
+ return 0;
+}
+
+#ifndef SFX
+/* TANDEM Directory processing */
+
+DIR *opendir(const char *dirname)
+{
+ short i, resolve;
+ char sname[FILENAME_MAX + 1];
+ short snamelen;
+ char fname[FILENAME_MAX + 1];
+ short fnamelen;
+ char *p;
+ short searchid, err, end;
+ struct dirent *entry;
+ DIR *dirp;
+ char ext[EXTENSION_MAX + 1];
+ short extension;
+
+ extension = parsename(dirname, sname, ext);
+ snamelen = strlen(sname);
+
+ /* First we work out how detailed the template is...
+ * e.g. If the template is DAVES*.* we want the search result
+ * in the same format
+ */
+
+ p = sname;
+ i = 0;
+ while ((p = strchr(p, TANDEM_DELIMITER)) != NULL){
+ i++;
+ p++;
+ };
+ resolve = 2 - i;
+
+ /* Attempt to start a filename template */
+ err = FILENAME_FINDSTART_ ( &searchid,
+ sname,
+ snamelen,
+ resolve,
+ DISK_DEVICE
+ );
+ if (err != 0) {
+ end = FILENAME_FINDFINISH_(searchid);
+ return NULL;
+ }
+
+ /* Create DIR structure */
+ if ((dirp = malloc(sizeof(DIR))) == NULL ) {
+ end = FILENAME_FINDFINISH_(searchid);
+ return NULL;
+ }
+ dirp->D_list = dirp->D_curpos = NULL;
+ strcpy(dirp->D_path, dirname);
+
+ while ((err = FILENAME_FINDNEXT_(searchid,
+ fname,
+ FILENAME_MAX,
+ &fnamelen
+ )
+ ) == 0 ){
+ /* Create space for entry */
+ if ((entry = malloc (sizeof(struct dirent))) == NULL) {
+ end = FILENAME_FINDFINISH_(searchid);
+ return NULL;
+ }
+
+ /* Link to last entry */
+ if (dirp->D_curpos == NULL)
+ dirp->D_list = dirp->D_curpos = entry; /* First name */
+ else {
+ dirp->D_curpos->d_next = entry; /* Link */
+ dirp->D_curpos = entry;
+ };
+ /* Add directory entry */
+ *dirp->D_curpos->d_name = '\0';
+ strncat(dirp->D_curpos->d_name,fname,fnamelen);
+ if (extension) {
+ strcat(dirp->D_curpos->d_name,TANDEM_EXTENSION_STR);
+ strcat(dirp->D_curpos->d_name,ext);
+ };
+ dirp->D_curpos->d_next = NULL;
+ };
+
+ end = FILENAME_FINDFINISH_(searchid);
+
+ if (err == 1) { /* Should return EOF at end of search */
+ dirp->D_curpos = dirp->D_list; /* Set current pos to start */
+ return dirp;
+ }
+ else
+ return NULL;
+}
+
+struct dirent *readdir(DIR *dirp)
+{
+ struct dirent *cur;
+
+ cur = dirp->D_curpos;
+ dirp->D_curpos = dirp->D_curpos->d_next;
+ return cur;
+}
+
+void rewinddir(DIR *dirp)
+{
+ dirp->D_curpos = dirp->D_list;
+}
+
+int closedir(DIR *dirp)
+{
+ struct dirent *node;
+
+ while (dirp->D_list != NULL) {
+ node = dirp->D_list;
+ dirp->D_list = dirp->D_list->d_next;
+ free( node );
+ }
+ free( dirp );
+ return 0;
+}
+
+#endif /* !SFX */
diff --git a/tandem/tandem.h b/tandem/tandem.h
new file mode 100644
index 0000000..7296d26
--- /dev/null
+++ b/tandem/tandem.h
@@ -0,0 +1,236 @@
+/*
+ Copyright (c) 1990-2006 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+#ifndef __tandem_h /* prevent multiple inclusions */
+#define __tandem_h
+
+#ifndef TANDEM
+# define TANDEM /* better than __TANDEM */
+#endif
+
+/* LICENSED define now supplied by compile time option (MAKE) */
+
+#define NO_UNISTD_H
+#define NO_RMDIR
+#define NO_MKTEMP
+
+/* TANDEM supplies proper UTC vs. local time conversion, so enable Info-ZIP's
+ UT e.f. support unless explicitly suppressed by a compilation option. */
+#if (!defined(USE_EF_UT_TIME) && !defined(NO_EF_UT_TIME))
+# define USE_EF_UT_TIME
+#endif
+#if (defined(NO_EF_UT_TIME) && defined(USE_EF_UT_TIME))
+# undef USE_EF_UT_TIME
+#endif
+
+/* Include file for TANDEM */
+
+#ifndef NULL
+# define NULL 0
+#endif
+
+#include <time.h> /* the usual non-BSD time functions */
+#include <stdio.h>
+#include <sysstat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <ctype.h>
+
+#define PASSWD_FROM_STDIN
+ /* Kludge until we know how to open a non-echo tty channel */
+
+#define NSK_UNSTRUCTURED 0
+#define NSK_RELATIVE 1
+#define NSK_ENTRYSEQUENCED 2
+#define NSK_KEYSEQUENCED 3
+#define NSK_OBJECTFILECODE 100
+#define NSK_EDITFILECODE 101
+#define NSK_ZIPFILECODE 1001
+#define TANDEM_BLOCKSIZE 4096
+#define MAX_NORMAL_READ 4096
+#define MAX_EDIT_READ 255
+#define MAX_LARGE_READ 57344
+#define MAX_LARGE_READ_EXPAND 30720
+
+#define MAXFILEPARTLEN 8
+#define MAXPATHLEN 128
+#define EXTENSION_MAX 3
+/* FILENAME_MAX is defined in stdio.h */
+
+#define EXIT zexit /* To stop creation of Abend files */
+#define RETURN zexit /* To stop creation of Abend files */
+#define putc zputc /* To allow us to auto flush */
+
+
+#define FOPR "rb"
+#define FOPM "r+"
+#define FOPW "wb"
+#define FOPWT "w"
+
+#define NAMELEN FILENAME_MAX+1+EXTENSION_MAX /* allow for space extension */
+
+struct dirent {
+ struct dirent *d_next;
+ char d_name[NAMELEN+1];
+};
+
+typedef struct _DIR {
+ struct dirent *D_list;
+ struct dirent *D_curpos;
+ char D_path[NAMELEN+1];
+} DIR;
+
+DIR * opendir(const char *dirname);
+struct dirent *readdir(DIR *dirp);
+void rewinddir(DIR *dirp);
+int closedir(DIR *dirp);
+char * readd(DIR *dirp);
+
+#define DISK_DEVICE 3
+
+/* SETMODE Literals */
+#define SET_FILE_SECURITY 1
+#define SET_FILE_OWNER 2
+#define SET_FILE_BUFFERED 90
+#define SET_FILE_MAXEXTENTS 92
+#define SET_FILE_BUFFERSIZE 93
+#define SET_LARGE_TRANSFERS 141
+
+/* FILE_OPEN_ Literals */
+#define NSK_RDWR 0
+#define NSK_RDONLY 1
+#define NSK_WRONLY 2
+#define NSK_APPEND 3
+#define NSK_SHARED 0
+#define NSK_EXCLUSIVE 1
+#define NSK_PROCESSEXCLUSIVE 2
+#define NSK_PROTECTED 3
+#define NSK_UNSTRUCTUREDACCESS 0x8000
+#define NSK_NOUPDATEOPENTIME 0x2000
+
+#define NSK_NO_DELIMITER 0x0001
+#define NSK_USE_FF_DELIMITER 0x0002
+#define NSK_SPACE_FILL 0x0004
+#define NSK_TRIM_TRAILING_SPACE 0x0008
+#define NSK_LARGE_READ_EXPAND 0x0100 /* use smaller value for Expand */
+
+#define DOS_EXTENSION '.'
+#define TANDEM_EXTENSION ' '
+#define TANDEM_DELIMITER '.'
+#define TANDEM_NODE '\\'
+#define INTERNAL_DELIMITER '/'
+#define INTERNAL_NODE '//'
+#define TANDEM_WILD_1 '*'
+#define TANDEM_WILD_2 '?'
+
+#define DOS_EXTENSION_STR "."
+#define TANDEM_EXTENSION_STR " "
+#define TANDEM_DELIMITER_STR "."
+#define TANDEM_NODE_STR "\\"
+#define INTERNAL_DELIMITER_STR "/"
+#define INTERNAL_NODE_STR "//"
+
+/* Use 'spare' area at end of stat structure to hold additional Tandem/NSK
+ file details. Initially used to hold Creation time, now also holds most
+ Enscribe details */
+
+struct nsk_stat_reserved
+{
+ int64_t spare[3];
+};
+
+#pragma FIELDALIGN SHARED8 nsk_owner
+struct nsk_owner
+{
+ unsigned group : 8;
+ unsigned user : 8;
+};
+
+#pragma FIELDALIGN SHARED8 nsk_file_flags
+struct nsk_file_flags
+{
+ unsigned buffered : 1;
+ unsigned audited : 1;
+ unsigned acompress : 1;
+ unsigned icompress : 1;
+ unsigned dcompress : 1;
+ unsigned oddunstr : 1;
+ unsigned verified : 1;
+ unsigned serial : 1;
+ unsigned refresheof : 1;
+ unsigned broken : 1;
+ unsigned corrupt : 1;
+ unsigned primpart : 1;
+ unsigned secpart : 1;
+ unsigned crashopen : 1;
+ unsigned rollforward : 1;
+ unsigned clearonpurge: 1;
+};
+
+#pragma FIELDALIGN SHARED8 nsk_file_attrs_def
+struct nsk_file_attrs_def
+{
+ unsigned short filecode; /* 16 */
+ unsigned short block; /* 16 */ /* Allow of block > 4096 one day ! */
+ struct nsk_file_flags flags; /* 16 */
+ struct nsk_owner owner; /* 16 */
+ unsigned short priext; /* 16 */
+ unsigned short secext; /* 16 */
+ unsigned maxext : 10;
+ unsigned read : 3;
+ unsigned write : 3;
+ unsigned execute : 3;
+ unsigned delete : 3;
+ unsigned licensed : 1;
+ unsigned progid : 1;
+ unsigned keylen : 8;
+ unsigned : 5;
+ unsigned keyoff : 11;
+ unsigned : 1;
+ unsigned filetype : 2;
+ unsigned fileopen : 1;
+ unsigned reclen : 12;
+};
+typedef struct nsk_file_attrs_def nsk_file_attrs;
+
+#pragma FIELDALIGN SHARED8 nsk_stat_overlay
+struct nsk_stat_overlay
+{
+ time_t creation_time; /* 32 bits */
+ nsk_file_attrs nsk_ef_region;
+ /* char nsk_ef_region[20]; *//* EF region */
+};
+
+typedef union
+{
+ struct nsk_stat_reserved reserved;
+ struct nsk_stat_overlay ov;
+} nsk_stat_ov;
+
+/* Prototype function declarations */
+
+void zexit (int);
+
+int zputc(
+ int,
+ FILE *
+);
+
+int zgetch (void);
+
+short parsename(
+ const char *,
+ char *,
+ char *
+);
+
+int islicensed (void);
+
+/* End of prototype function declarations */
+
+#endif /* !__tandem_h */
diff --git a/tandem/tannsk.h b/tandem/tannsk.h
new file mode 100644
index 0000000..34ad49c
--- /dev/null
+++ b/tandem/tannsk.h
@@ -0,0 +1,19 @@
+/*
+ Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*
+ * Header declaration(s) which are forced to go after earlier includes
+ */
+
+#ifndef __tannsk_h /* prevent multiple inclusions */
+#define __tannsk_h
+
+/* ztimbuf is declared in zip\tailor.h after include of tandem.h */
+int utime (const char *, const ztimbuf *);
+
+#endif /* !__tannsk_h */
diff --git a/tandem/tanzip.c b/tandem/tanzip.c
new file mode 100644
index 0000000..5985b33
--- /dev/null
+++ b/tandem/tanzip.c
@@ -0,0 +1,723 @@
+/*
+ Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+/*
+ * routines only used by TANDEM ZIP
+ */
+
+#include "zip.h"
+#include "crypt.h"
+#include <tal.h>
+#include "$system.zsysdefs.zsysc" nolist
+#include <cextdecs> nolist
+#include "tannsk.h"
+
+/******************************/
+/* Function version_local() */
+/******************************/
+
+void version_local()
+{
+ static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n";
+#if 0
+ char buf[40];
+#endif
+
+ printf(CompiledWith,
+
+#ifdef __GNUC__
+ "gcc ", __VERSION__,
+#else
+ "C ", "T9255D44 - (16OCT98)",
+#endif
+
+ "NonStop ", "(Tandem/NSK)",
+
+#ifdef __DATE__
+ " on ", __DATE__
+#else
+ "", ""
+#endif
+ );
+
+} /* end function version_local() */
+
+
+/************************/
+/* Function nskopen() */
+/************************/
+
+#ifdef fopen
+# undef fopen
+#endif
+
+FILE *nskopen(fname, opt)
+const char *fname;
+const char *opt;
+{
+ int fdesc;
+ short fnum, err, len;
+ int priext, secext;
+ short maxext, filecode, blocksize;
+
+ #define alist_items 1
+ #define vlist_bytes 2
+ short alist[alist_items]={42};
+ unsigned short vlist[alist_items];
+ short extra, *err_item=&extra;
+
+ char nsk_work[FILENAME_MAX + 1], *nsk_fname=&nsk_work[0];
+
+ /* See if we want to create a new file */
+ if ((strcmp(opt,FOPW) == 0) || (strcmp(opt,FOPWT) == 0)) {
+ blocksize = TANDEM_BLOCKSIZE;
+ priext = 100;
+ secext = 500;
+ maxext = 978;
+ filecode = NSK_ZIPFILECODE;
+
+ if ((fdesc = creat(fname,,priext,secext)) != -1){
+ fnum = fdtogfn ((short)fdesc);
+ err = (SETMODE (fnum, SET_FILE_BUFFERSIZE, blocksize) != CCE);
+ err = (SETMODE (fnum, SET_FILE_BUFFERED, 0, 0) != CCE);
+ err = (SETMODE (fnum, SET_FILE_BUFFERED, 0, 1) != CCE);
+ err = (SETMODE (fnum, SET_FILE_MAXEXTENTS, maxext) != CCE);
+ err = close(fdesc);
+
+ vlist[0] = filecode;
+
+ /* Note that FILE_ALTERLIST_ expects uppercase names */
+ /* Need to call strlen and upshift */
+ len = strlen(fname);
+ err = STRING_UPSHIFT_((char *)fname,
+ len,
+ nsk_fname,
+ len);
+
+ err = FILE_ALTERLIST_(nsk_fname,
+ len,
+ alist,
+ alist_items,
+ vlist,
+ vlist_bytes,
+ ,
+ err_item);
+ };
+ };
+
+ return fopen(fname,opt);
+}
+#define fopen nskopen
+
+
+ int Bflag = 0; /* Special formatting options for Tandem */
+ /* Bit 0 = Add delimiter (0 = Yes, 1 = No) */
+ /* Bit 1 = Delimiter Type (0 = CR/LF, 1 = LF) */
+ /* Bit 2 = Space Fill records (0 = No, 1 = Yes) */
+ /* Bit 3 = Trim trailing space(0 = No, 1 = Yes) */
+ /* Thus, default is to add CR/LF, no padding */
+ /* Bit 8 = Use 'safe' large read size (Expand) */
+ char nsk_delim[2] = {'\r', '\n'}; /* CR/LF */
+ int nsk_delim_len = 2;
+ int nsk_space_fill = 0; /* 0 = No, 1 = Yes */
+ int nsk_trim_space = 0; /* 0 = No, 1 = Yes */
+ unsigned short nsk_large_read = MAX_LARGE_READ;
+
+ /* Following holds details of file currently used by zopen & zread */
+ struct stat znsk_stat;
+ nsk_stat_ov *znsk_ov = (nsk_stat_ov *)&znsk_stat.st_reserved[0];
+ nsk_file_attrs *znsk_attr = (nsk_file_attrs *)
+ ( (char *)(&znsk_stat.st_reserved[0]) +
+ offsetof (struct nsk_stat_overlay, nsk_ef_region) );
+
+ /* Following items used by zread to avoid overwriting window */
+ char zreadbuf[MAX_LARGE_READ]; /* Buffer as large as biggest read */
+ char *zreadptr = (char *) zreadbuf; /* pointer to start of buffer */
+ char *zread_ovptr = NULL; /* pointer to left overs */
+ long zread_ovlen = 0; /* size of remaining left overs */
+
+ int zopen (filename, opt)
+ const char *filename;
+ int opt;
+ {
+ /* Currently ignore opt. Choose method of I/O based on NSK file type */
+ short err, len, fnum, access, exclus, bufferlen, options;
+ long recnum;
+ char fname[FILENAME_MAX + 1];
+ short extension;
+ char ext[EXTENSION_MAX + 1];
+
+ /* Remove any (pseudo) file extension */
+ extension = parsename (filename,fname,ext);
+ len = strlen(fname);
+
+ fnum = 0;
+ access = NSK_RDONLY;
+ exclus = NSK_SHARED;
+
+ err = stat(fname, &znsk_stat); /* Setup global struct, used by zread */
+
+ if (znsk_attr->filetype == NSK_UNSTRUCTURED)
+ if (znsk_attr->filecode == NSK_EDITFILECODE) {
+ /* Edit File */
+ fnum = -1; /* Ask OPENEDIT_ to open the file for us */
+ err = OPENEDIT_ ((char *)fname, len, &fnum, access, exclus);
+ if (!err) {
+ recnum = -1; /* Position to first line */
+ err = POSITIONEDIT (fnum, recnum);
+ }
+ }
+ else {
+ /* Unstructured File */
+ options = NSK_UNSTRUCTUREDACCESS;
+ err = FILE_OPEN_((char *)fname, len, &fnum, access, exclus,
+ ,,options,,,);
+ if (!err)
+ /* Ask for large transfer mode */
+ err = (SETMODE (fnum, SET_LARGE_TRANSFERS, 1) != CCE);
+ }
+ else {
+ /* Structured File */
+ bufferlen = 4096; /* request SBB */
+ err = FILE_OPEN_((char *)fname, len, &fnum, access, exclus,
+ ,,,, bufferlen ,);
+ if (err == 4)
+ err = 0; /* Allow saving of files that have missing altkeys */
+ }
+
+ return (err == 0 ? (int)fnum : -1);
+ }
+
+ unsigned zread (fnum, buf, len)
+ int fnum;
+ char *buf;
+ unsigned len;
+ {
+ short err, trail;
+ long total, movelen;
+ unsigned short countread;
+ unsigned readlen; /* typed to match incoming arg */
+ char *bufptr, *readptr;
+
+ total = err = 0;
+ bufptr = buf;
+
+ /* We use a separate buffer to read in data as it can be larger than
+ WSIZE, and hence would overwrite memory */
+
+ /* We always attempt to give the user the exact requested size
+ Hence we make use of an overfow buffer for previously truncated data */
+
+ /* see if we have some left over characters from last time */
+ if (zread_ovlen) {
+ movelen = _min(len,zread_ovlen);
+ memcpy(bufptr, zread_ovptr, movelen);
+ bufptr += movelen;
+ total += movelen;
+ zread_ovptr += movelen;
+ zread_ovlen -= movelen;
+ }
+
+ while (!err && (total < len)) {
+ readptr = zreadptr;
+
+ if (znsk_attr->filetype == NSK_UNSTRUCTURED)
+ if (znsk_attr->filecode == NSK_EDITFILECODE){
+ /* Edit File */
+ trail = 1;
+ readlen = MAX_EDIT_READ; /* guarantee it fits in buffer */
+
+ /* get line and preserve any trailing space characters */
+ err = READEDIT (fnum,, zreadptr, (short) readlen,
+ (short *) &countread,,, trail);
+ /* if countread is ever negative then we will skip a line */
+
+ if (!err) {
+ readptr = zreadptr + countread;
+ /* Note it is possible for Edit files to hold trailing space */
+ if (nsk_trim_space)
+ while (*(readptr-1) == ' ') {
+ readptr--;
+ countread--;
+ }
+
+ if (nsk_delim_len) {
+ memcpy(readptr, nsk_delim, nsk_delim_len);
+ readptr += nsk_delim_len;
+ countread += nsk_delim_len;
+ }
+ }
+ }
+ else {
+ /* Unstructured File */
+
+ /* Using large transfer mode so we have to use 2K multiples
+ Use largest size possible and put remains in overflow */
+
+ readlen = nsk_large_read; /* use largest read, overflow into buffer*/
+
+ err = (READX(fnum, zreadptr, readlen, (short *)&countread) != CCE);
+ if (err && (errno == EINVAL)) {
+ /* Read too big so scale back to smaller value */
+ readlen = nsk_large_read = MAX_LARGE_READ_EXPAND;
+ err = (READX(fnum, zreadptr, readlen, (short *)&countread) != CCE);
+ }
+ if (!err)
+ readptr = zreadptr + countread;
+ }
+ else {
+ /* Structured File */
+ readlen = znsk_attr->reclen;
+
+ err = (READX(fnum, zreadptr, readlen, (short *)&countread)!= CCE);
+
+ if (!err) {
+ readptr = zreadptr + countread;
+ if (nsk_space_fill)
+ while (countread < readlen) {
+ *readptr++ = ' ';
+ countread++;
+ }
+ else
+ if (nsk_trim_space)
+ while (*(readptr-1) == ' ') {
+ readptr--;
+ countread--;
+ }
+
+ if (nsk_delim_len) {
+ memcpy(readptr, nsk_delim, nsk_delim_len);
+ readptr += nsk_delim_len;
+ countread += nsk_delim_len;
+ }
+ }
+ }
+ if (!err) {
+ movelen = _min((len-total), countread);
+ memcpy(bufptr, zreadptr, movelen);
+ bufptr += movelen;
+ total += movelen;
+ if (movelen < countread) { /* still stuff in Read buffer */
+ zread_ovptr = zreadptr + movelen; /* pointer to whats left */
+ zread_ovlen = countread - movelen; /* how much is left */
+ }
+ }
+ }
+
+ return ((unsigned)total);
+ }
+
+ int zclose (fnum)
+ int fnum;
+ {
+ short err;
+
+ if ((znsk_attr->filetype == NSK_UNSTRUCTURED)
+ && (znsk_attr->filecode == NSK_EDITFILECODE))
+ err = CLOSEEDIT_(fnum);
+ else
+ err = FILE_CLOSE_(fnum);
+
+ return (err != 0);
+ }
+
+/* modified to work with get_option which returns
+ a string with the number value without leading option */
+void nskformatopt(p)
+char *p;
+{
+ /* set up formatting options for ZIP */
+
+ Bflag = 0; /* default option */
+
+ Bflag = strtoul(p, NULL, 10);
+
+ if (Bflag & NSK_SPACE_FILL)
+ nsk_space_fill = 1;
+ else
+ nsk_space_fill = 0;
+
+ if (Bflag & NSK_TRIM_TRAILING_SPACE)
+ nsk_trim_space = 1;
+ else
+ nsk_trim_space = 0;
+
+ if (Bflag & NSK_NO_DELIMITER)
+ nsk_delim_len = 0;
+ else {
+ if (Bflag & NSK_USE_FF_DELIMITER) {
+ nsk_delim[0] = '\n';
+ nsk_delim_len = 1;
+ }
+ else { /* CR/LF */
+ nsk_delim[0] = '\r';
+ nsk_delim[1] = '\n';
+ nsk_delim_len = 2;
+ }
+ }
+
+ if (Bflag & NSK_LARGE_READ_EXPAND)
+ nsk_large_read = MAX_LARGE_READ_EXPAND;
+ else
+ nsk_large_read = MAX_LARGE_READ;
+
+}
+
+
+ int deletedir(d)
+ char *d; /* directory to delete */
+ /* Delete the directory *d if it is empty, do nothing otherwise.
+ Return the result of rmdir(), delete(), or system().
+ For VMS, d must be in format [x.y]z.dir;1 (not [x.y.z]).
+ */
+ {
+ return rmdir(d);
+ }
+
+ local char *readd(d)
+ DIR *d; /* directory stream to read from */
+ /* Return a pointer to the next name in the directory stream d, or NULL if
+ no more entries or an error occurs. */
+ {
+ struct dirent *e;
+
+ e = readdir(d);
+ return e == NULL ? (char *) NULL : e->d_name;
+ }
+
+ int procname(n, caseflag)
+ char *n; /* name to process */
+ int caseflag; /* true to force case-sensitive match */
+ /* Process a name or sh expression to operate on (or exclude). Return
+ an error code in the ZE_ class. */
+ {
+ char *a; /* path and name for recursion */
+ DIR *d; /* directory stream from opendir() */
+ char *e; /* pointer to name from readd() */
+ int m; /* matched flag */
+ char *p; /* path for recursion */
+ struct stat s; /* result of stat() */
+ struct zlist far *z; /* steps through zfiles list */
+
+ if (strcmp(n, "-") == 0) /* if compressing stdin */
+ return newname(n, 0, caseflag);
+ else if (stat(n, &s))
+ {
+ /* Not a file or directory--search for shell expression in zip file */
+ p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */
+ m = 1;
+ for (z = zfiles; z != NULL; z = z->nxt) {
+ if (MATCH(p, z->zname, caseflag))
+ {
+ z->mark = pcount ? filter(z->zname, caseflag) : 1;
+ if (verbose)
+ fprintf(mesg, "zip diagnostic: %scluding %s\n",
+ z->mark ? "in" : "ex", z->name);
+ m = 0;
+ }
+ }
+ free((zvoid *)p);
+ return m ? ZE_MISS : ZE_OK;
+ }
+
+ /* Live name--use if file, recurse if directory */
+ if ((s.st_mode & S_IFDIR) == 0)
+ {
+ /* add or remove name of file */
+ if ((m = newname(n, 0, caseflag)) != ZE_OK)
+ return m;
+ } else {
+ if ((p = malloc(strlen(n)+4)) == NULL)
+ return ZE_MEM;
+
+ strcpy(p, n);
+
+ /* No concept of directories on Tandem - so do not store them ...*/
+ /* code removed from which attempted to save dir name if dirnames set */
+
+ /* Test for recurse being set removed, since Tandem has no dir concept*/
+ /* recurse into template */
+ if ((d = opendir(n)) != NULL)
+ {
+ while ((e = readd(d)) != NULL) {
+ if ((m = procname(e, caseflag)) != ZE_OK) /* recurse on name */
+ {
+ if (m == ZE_MISS)
+ zipwarn("name not matched: ", e);
+ else
+ ziperr(m, e);
+ }
+ }
+ closedir(d);
+ }
+ free((zvoid *)p);
+ } /* (s.st_mode & S_IFDIR) == 0) */
+ return ZE_OK;
+ }
+
+ char *ex2in(x, isdir, pdosflag)
+ char *x; /* external file name */
+ int isdir; /* input: x is a directory */
+ int *pdosflag; /* output: force MSDOS file attributes? */
+ /* Convert the external file name to a zip file name, returning the malloc'ed
+ string or NULL if not enough memory. */
+ {
+ char *n; /* internal file name (malloc'ed) */
+ char *t; /* shortened name */
+ int dosflag;
+ char *p; /* pointer to temp area */
+ char fname[FILENAME_MAX + 1]= ""; /* file name */
+ char ext[EXTENSION_MAX + 1] = ""; /* extension name */
+ short extension; /* does the filename contain an extension */
+
+ dosflag = dosify; /* default for non-DOS non-OS/2 */
+
+ /* Find starting point in name before doing malloc */
+ if (*x == '=')
+ t = x + 1; /* store DEFINE names without the '=' */
+ else
+ t = x;
+
+ /* Make changes, if any, to the copied name (leave original intact) */
+
+ if (!pathput)
+ t = last(t, TANDEM_DELIMITER);
+
+ /* Malloc space for internal name and copy it */
+ if ((n = malloc(strlen(t) + 4)) == NULL) /* + 4 for safety */
+ return NULL;
+
+ extension = parsename(t,fname,ext);
+ t = fname;
+
+ *n= '\0';
+
+ while (*t != '\0') { /* File part could be sys,vol,subvol or file */
+ if (*t == TANDEM_NODE) { /* System Name */
+ strcat(n, INTERNAL_NODE_STR);
+ t++;
+ }
+ else if (*t == TANDEM_DELIMITER) { /* Volume or Subvol */
+ strcat(n, INTERNAL_DELIMITER_STR);
+ t++;
+ };
+ p = strchr(t,TANDEM_DELIMITER);
+ if (p == NULL) break;
+ strncat(n,t,(p - t));
+ t = p;
+ }
+
+ strcat(n,t); /* mop up any left over characters */
+
+ if (extension) {
+ strcat(n,DOS_EXTENSION_STR);
+ strcat(n,ext);
+ };
+
+ if (isdir == 42) return n; /* avoid warning on unused variable */
+
+ if (dosify)
+ msname(n);
+
+ /* Returned malloc'ed name */
+ if (pdosflag)
+ *pdosflag = dosflag;
+
+ return n;
+ }
+
+ void stamp(f, d)
+ char *f; /* name of file to change */
+ ulg d; /* dos-style time to change it to */
+ /* Set last updated and accessed time of file f to the DOS time d. */
+ {
+ ztimbuf u; /* argument for utime() */
+
+ /* Convert DOS time to time_t format in u.actime and u.modtime */
+ u.actime = u.modtime = dos2unixtime(d);
+
+ utime(f, &u);
+ }
+
+ ulg filetime(f, a, n, t)
+ char *f; /* name of file to get info on */
+ ulg *a; /* return value: file attributes */
+ long *n; /* return value: file size */
+ iztimes *t; /* return value: access and modification time */
+ {
+ struct stat s;
+ nsk_stat_ov *nsk_ov;
+
+ if (strcmp(f, "-") == 0) { /* if compressing stdin */
+ if (n != NULL) {
+ *n = -1L;
+ }
+ }
+
+ if (stat(f, &s) != 0) return 0;
+
+ if (a!= NULL) {
+ *a = ((ulg)s.st_mode << 16) | !(s.st_mode & S_IWUSR);
+ if ((s.st_mode & S_IFMT) == S_IFDIR) {
+ *a |= MSDOS_DIR_ATTR;
+ }
+ }
+
+ if (n!= NULL)
+ *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L;
+
+ if (t != NULL) {
+ t->atime = s.st_atime;
+ t->mtime = s.st_mtime;
+ nsk_ov = (nsk_stat_ov *)&s.st_reserved[0];
+ t->ctime = nsk_ov->ov.creation_time;
+ }
+
+ return unix2dostime(&s.st_mtime);
+ }
+
+ int set_extra_field(z, z_utim)
+ struct zlist far *z;
+ iztimes *z_utim;
+ /* create extra field and change z->att if desired */
+ /* store full data in local header but just modification time stamp info
+ in central header */
+ {
+ struct stat s;
+ nsk_stat_ov *nsk_ov = (nsk_stat_ov *)&s.st_reserved[0];
+ nsk_file_attrs *nsk_attr = (nsk_file_attrs *)&nsk_ov->ov.nsk_ef_region;
+ char *ext, *cext;
+ int lsize, csize;
+#ifdef USE_EF_UT_TIME
+ char *UTptr, *Uxptr;
+#endif /* USE_EF_UT_TIME */
+
+ /* For the Tandem and UT local field including the UID/GID fields, we
+ have to stat the file again. */
+ if (LSSTAT(z->name, &s))
+ return ZE_OPEN;
+
+ z->ext = z->cext = 0;
+
+ #define EB_TANDEM_SIZE 20
+ #define EF_TANDEM_SIZE (EB_HEADSIZE + EB_TANDEM_SIZE)
+
+ /* allocate size of buffers to allow Tandem field */
+ lsize = EF_TANDEM_SIZE;
+ csize = EF_TANDEM_SIZE;
+
+#ifdef USE_EF_UT_TIME
+
+ #define EB_L_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(3))
+ #define EB_C_UT_SIZE (EB_HEADSIZE + EB_UT_LEN(1))
+ #define EB_L_UX2_SIZE (EB_HEADSIZE + EB_UX2_MINLEN)
+ #define EB_C_UX2_SIZE EB_HEADSIZE
+ #define EF_L_UNIX_SIZE (EB_L_UT_SIZE + EB_L_UX2_SIZE)
+ #define EF_C_UNIX_SIZE (EB_C_UT_SIZE + EB_C_UX2_SIZE)
+
+ /* resize to allow for UT fields */
+ lsize += EF_L_UNIX_SIZE;
+ csize += EF_C_UNIX_SIZE;
+
+#endif /* USE_EF_UT_TIME */
+
+ if ((z->extra = (char *)malloc(lsize)) == NULL)
+ return ZE_MEM;
+ ext = z->extra;
+
+ if ((z->cextra = (char *)malloc(csize)) == NULL)
+ return ZE_MEM;
+ cext = z->cextra;
+
+ /* Place Tandem field first so its on an even boundary */
+ *ext++ = *cext++ = 'T';
+ *ext++ = *cext++ = 'A';
+ *ext++ = *cext++ = (char)EB_TANDEM_SIZE; /*length of data part of e.f.*/
+ *ext++ = *cext++ = 0;
+
+ /* Copy Tandem specific file information */
+ memcpy(ext, (char *)nsk_attr, EB_TANDEM_SIZE);
+ ext += EB_TANDEM_SIZE;
+ z->ext += EF_TANDEM_SIZE;
+
+ /* Copy same data to central field */
+ memcpy(cext, (char *)nsk_attr, EB_TANDEM_SIZE);
+ cext += EB_TANDEM_SIZE;
+ z->cext += EF_TANDEM_SIZE;
+
+#ifdef USE_EF_UT_TIME
+ UTptr = ext;
+ *ext++ = 'U';
+ *ext++ = 'T';
+ *ext++ = (char)EB_UT_LEN(3); /* length of data part of local e.f. */
+ *ext++ = 0;
+ *ext++ = EB_UT_FL_MTIME | EB_UT_FL_ATIME | EB_UT_FL_CTIME;
+ *ext++ = (char)(s.st_mtime);
+ *ext++ = (char)(s.st_mtime >> 8);
+ *ext++ = (char)(s.st_mtime >> 16);
+ *ext++ = (char)(s.st_mtime >> 24);
+ *ext++ = (char)(s.st_atime);
+ *ext++ = (char)(s.st_atime >> 8);
+ *ext++ = (char)(s.st_atime >> 16);
+ *ext++ = (char)(s.st_atime >> 24);
+
+ *ext++ = (char)(nsk_ov->ov.creation_time);
+ *ext++ = (char)(nsk_ov->ov.creation_time >> 8);
+ *ext++ = (char)(nsk_ov->ov.creation_time >> 16);
+ *ext++ = (char)(nsk_ov->ov.creation_time >> 24);
+
+ Uxptr = ext;
+ *ext++ = 'U';
+ *ext++ = 'x';
+ *ext++ = (char)EB_UX2_MINLEN; /* length of data part of local e.f. */
+ *ext++ = 0;
+ *ext++ = (char)(s.st_uid);
+ *ext++ = (char)(s.st_uid >> 8);
+ *ext++ = (char)(s.st_gid);
+ *ext++ = (char)(s.st_gid >> 8);
+
+ z->ext += EF_L_UNIX_SIZE;
+
+ memcpy(cext, UTptr, EB_C_UT_SIZE);
+ cext[EB_LEN] = (char)EB_UT_LEN(1);
+ memcpy(cext+EB_C_UT_SIZE, Uxptr, EB_C_UX2_SIZE);
+ cext[EB_LEN+EB_C_UT_SIZE] = 0;
+
+ z->cext += EF_C_UNIX_SIZE;
+ cext += EF_C_UNIX_SIZE;
+
+#endif /* USE_EF_UT_TIME */
+
+ return ZE_OK;
+ }
+
+#if CRYPT
+ /* getpid() only available on OSS so make up dummy version using NSK PID */
+ unsigned zgetpid (void)
+ {
+ short myphandle[ZSYS_VAL_PHANDLE_WLEN];
+ short err;
+ unsigned retval;
+
+ err = PROCESSHANDLE_NULLIT_(myphandle);
+
+ if (!err)
+ err = PROCESS_GETINFO_(myphandle);
+
+ if (!err)
+ retval = (unsigned) myphandle[ZSYS_VAL_PHANDLE_WLEN - 3];
+ else
+#ifndef __INT32
+ retval = (unsigned) 31415;
+#else
+ retval = (unsigned) 3141592654L;
+#endif /* __INT32 */
+
+ return retval;
+ }
+#endif /* CRYPT */
diff --git a/tandem/tanzip.h b/tandem/tanzip.h
new file mode 100644
index 0000000..528337d
--- /dev/null
+++ b/tandem/tanzip.h
@@ -0,0 +1,43 @@
+/*
+ Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 2000-Apr-09 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, all these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
+*/
+#ifndef __tanzip_h /* prevent multiple inclusions */
+#define __tanzip_h
+
+# define fopen nskopen /* To allow us to set extent sizes */
+
+# define USE_CASE_MAP
+
+ FILE *nskopen(const char *, const char *);
+ int zopen (const char *, int);
+ int zclose (int);
+ unsigned zread (int, char *, unsigned);
+ void nskformatopt(char *);
+
+ #define getpid zgetpid
+ unsigned zgetpid (void);
+
+#define CBSZ 0x10000 /* Was used for both fcopy and file_read. */
+ /* Created separate define (SBSZ) for file_read */
+ /* fcopy param is type size_t (unsigned long) */
+ /* For Guardian we choose a multiple of 4K */
+
+#define ZBSZ 0x10000 /* This is used in call to setvbuf, 64K seems to work */
+ /* in all memory models. Again it is an unsigned long */
+ /* For Guardian we choose a multiple of 4K */
+
+#ifndef __INT32
+#define SBSZ 0x0e000 /* Maximum of size unsigned (int). Only used in STORE */
+ /* method. We can use up to 56K bytes thanks to large */
+ /* transfer mode. Note WSIZE is limited to 32K, which */
+ /* limits the DEFLATE read size to same value. */
+#else
+#define SBSZ 0x10000 /* WIDE model so we can use 64K */
+#endif /* __INT32 */
+
+#endif /* !__tanzip_h */
diff --git a/tandem/zipup.h b/tandem/zipup.h
new file mode 100644
index 0000000..19d92ad
--- /dev/null
+++ b/tandem/zipup.h
@@ -0,0 +1,26 @@
+/*
+ Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 1999-Oct-05 or later
+ (the contents of which are also included in zip.h) for terms of use.
+ If, for some reason, both of these files are missing, the Info-ZIP license
+ also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html
+*/
+#ifndef O_RDONLY
+# define O_RDONLY 0
+#endif
+#define fhow O_RDONLY
+#define fbad (-1)
+typedef int ftype;
+
+/* Now we create Guardian versions of zopen, zread, zclose instead
+ moved prototypes to tanzip.h as they are now coded in tanzip.c
+ #define zopen(n,p) open(n,p)
+ #define zread(f,b,n) read(f,b,n)
+ #define zclose(f) close(f)
+*/
+
+
+#define zerr(f) (k == (extent)(-1L))
+#define zstdin 0
+