Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6724 → Rev 6725

/programs/fs/unzip60/tandem/Contents
0,0 → 1,27
Contents of the "tandem" subdirectory for UnZip 5.42 and later:
 
Contents this file
README
HISTORY
commacs generic support macros for compiling
doit macro to extract and rename required Tandem files from archive
macros Info-ZIP-specific macros for compiling
make Tandem NSK script to compile UnZip intelligently
makesfx Tandem NSK script to compile UnZipSFX
tandem.c Tandem NSK-specific Zip & UnZip support routines
tandem.h Tandem NSK-specific data declarations
tanunz.c Tandem NSK-specific UnZip support routines
tannsk.h Tandem NSK-specific declarations that need delayed including
 
To compile, run the rename.unix script on a Unix system (renames *.c files
to *c and *.h files to *h, and leaves all files necessary for Tandem port
in the Tandem subdirectory). Then transfer the renamed files to the Tandem
system (if by ftp, use ASCII mode so the line-endings are converted to CR/LF
format properly). Edit the `make' script and change all references to
$DATA9.DAVESZIP with whatever subvol you use, and change all references to
SUPER.DAVES with whatever user id you use. Then run it. Individual object
files will be named *o (that is, unzip.c -> unzipc -> unzipo), and an
intermediate UnZip library (unziplib) and final UnZip binary (unzipl or
unzipw, depending on large or wide model) will be created.
 
The filecode for unzipl should be 100 [OBJECT]...presumably this is automatic.
/programs/fs/unzip60/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
/programs/fs/unzip60/tandem/README
0,0 → 1,118
Tandem Port of Info ZIP (unzip)
=======================
 
Recent changes:
1. Support UNZIPing of EDIT (text) files by use of the "-a" parameter
2. Changes for version 2.2 affected files:
- TANDEMC (changes to stat() to pass file creation time)
- ZIPINFOC (exclude TANDEM from tzset() test)
3. Fix to default time/date field to UK format (dd/mm/yyyy)
03/08/98 5.33f Updates for TANDEMC/H to keep instep with ZIP (file buffering)
New DOIT macro for extracting files from archive
Fix in2ex to expand full vol/subvol depending on '-j' flag
17/08/98 5.33f Set USE_EF_UT_TIME to allow for timezone changes
18/08/98 5.33f Use define LICENSED to build object able to update timestamps
19/08/98 5.33f Add -X flag support (restore file owner id) via unzip.c/h
new chown function in tandem.c.
Modified close_outfile to make the chown the last step.
30/11/98 5.41a Updated mapname/chmod/in2ex, include licensing in MAKE
21/12/98 5.41a Add decoding of new Tandem extra field EF_TANDEM
Make '-a' default option. Add '-b' option to force creation
of 'C' filecode 180 type text files.
If available populate Tandem file code (e.g. Object files)
Rationalised TANDEMH and TANDEMC wth ZIP 2.3i
Fixed MORE (-M flag) processing by creating zgetch()
12/01/99 5.41a Correct bug stopping setting of last open timestamp
24/03/99 5.41b Split TANDEMC into TANDEMC/TANZIPC/TANUNZC
24/03/99 5.41b Added TANNSKH to allow for declarations which require
structures defined in ZIPH after call to TANDEMH
07/05/99 5.41c Assume not DST if can't resolve time (no DST table available)
01/06/99 5.41c Add steps to make Self Extracting files (SFX)
12/01/01 5.42g Fix problems with MAKE for WIDE objects, updated TANDEMC/H
in line with ZIP, updated DOIT to remove TIMEZONE.C
 
If we ever want to use TIMEZONE.C then we need to set the
define IZTZ_DEFINESTDGLOBALS, it then compiles OK. The object
would need to be added to the building of UNZIPLIB in make.
 
09/02/01 5.50a Added code to tandem.c to create files with appropriate
extent sizes, or actual values if file was originally NSK
15/02/01 Update tandem.c to force first character to 'A' for Tandem
filenames
12/04/01 5.50c Fix problem with duff EF lengths in ef_scan_for_tandem
12/04/01 Change definition of nsk_attrs to allow for Wide mode and
subsequent respecifications of procedures that use it
12/04/01 Fix bug in tanunz.c so that call to FILE_ALTERLIST_ has upper
case filename
12/04/01 Update tandem.c to only allow '$' in in2ex as appropriate
16/07/01 5.50g Fixed bug in tandem.c for incorrect use of slist_items rather
than vlist_items
18/07/01 Allow edit files to be created with original extents
25/07/02 5.51b Add "-r" remove file extensions command line option
07/08/02 5.51b Non-Tandem non-text files now set to code 0 (not 100)
21/10/02 5.51b Tandem Enscribe files containing text set to code 101
03/01/03 5.51b Fix bug in extract of Text files - caused by Deflate64 changes
which made various buffers 64k and mismatches with unsigned.
Added NO_DEFLATE64 to MAKE and made this the default for
non-WIDE mode. If DEFLATE64 is used and non-WIDE then it drops
down to MED_MEM model for OUTBUFSIZ logic.
 
A few notes about the files on this subvol
 
COMMACS - required by MAKE, *** held on ZIP subvol ***
DOIT - macro to extract required Tandem files from archive and rename
MACROS - required by MAKE, *** held on ZIP subvol ***
MAKE - recompile UNZIP code, attempts to only recompile changed code
MAKESFX - make SFX header file
README - this file
UNZIPLIB - library of ZIP compiled routines, used by ZIP/ZIPNOTE etc
UNZIPL - ZIP 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 UNZIP object onto Tandem
- download Tandem Unzip executables archive from Web
- using PC unzip program (e.g. pkunzip/WinZip) extract UNZIP
- copy UNZIP 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) retrieve source code (requires UNZIP on Tandem)
- download UNZIP source archive from 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
- 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 files you unzip
you need to add the line "#define LICENSED" to the TANDEMH file. If you set
this option 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 UNZIP the define is setup (default) in tandem.h
 
 
Additional Notes - Self Extracting
==================================
 
To create a Self Extracting (SFX) file you need to do the following
- run the MAKESFX file to create the SFX object files
- create a normal Zip file
- create an empty Unstructured file
- FUP COPY SFX into new file
- FUP COPY your Zip file to the end of this new file
- run ZIP -A <zipfile> to fix the internal pointers
- alter the filecode of <zipfile> to 100 (I'll do this in Zip -A soon)
 
For performance you should Axcel the finished file.
/programs/fs/unzip60/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
/programs/fs/unzip60/tandem/doit
0,0 → 1,20
?tacl macro
#frame
#push zipfile
#SET zipfile [#FILEINFO /SUBVOL/ A]
 
unzip -a [zipfile] *.c -x */*
== Following not required
RENAME apic apicz
RENAME apihelpc apihelpz
RENAME timezonc timezonz
 
unzip -a [zipfile] *.h -x */*
 
unzip -aj [zipfile] tandem/*.h
 
unzip -aj [zipfile] tandem/*.c
 
unzip -aj [zipfile] tandem/* -x tandem/*.*
 
#unframe
/programs/fs/unzip60/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
/programs/fs/unzip60/tandem/make
0,0 → 1,138
?tacl routine
#FRAME
SINK [#LOAD /keep 1/ commacs]
SINK [#LOAD /keep 1/ macros]
 
[#PUSH file prev memory clib OK model unzip lib accel unlicensed licensed
options fileset nocrypt crypt arg^value object^owner object^security
deflate64
]
#PUSH #DEFAULTS
 
#SET OK -1
 
== Customise the following values for your environment
#SET object^owner SUPER.DAVES
#SET object^security "UUUU"
 
[#LOOP |WHILE| [#MORE] |DO|
[#CASE [#ARGUMENT /VALUE arg^value/
KEYWORD /WORDLIST LARGE SMALL/
KEYWORD /WORDLIST NOWIDE WIDE/
KEYWORD /WORDLIST UNLICENSED/
KEYWORD /WORDLIST NOCRYPT/
KEYWORD /WORDLIST DEFLATE64 NODEFLATE64/
TEMPLATE FILENAME ]
|1| #SET memory [arg^value]
|2| #SET model [arg^value]
|3| #SET unlicensed [arg^value]
|4| #SET nocrypt [arg^value]
|5| #SET deflate64 [arg^value]
|6| #SET fileset [arg^value]
|OTHERWISE|
]
]
 
[#IF [#EMPTYV memory] |THEN| #SET memory LARGE]
[#IF [#EMPTYV model] |THEN| #SET model NOWIDE]
[#IF [#EMPTYV deflate64] |THEN| #SET deflate64 DEFLATE64]
 
[#IF model '=' "WIDE"
|THEN| #SETV clib model
|ELSE| #SETV clib memory
]
 
[#IF model '=' "WIDE"
|THEN|
#SET unzip UNZIPW
|ELSE|
#SET unzip UNZIPL
]
#SET lib [unzip]B
#SET accel UNZIP
#SET options [options], [model]
 
[#IF unlicensed '=' "UNLICENSED"
|THEN|
#SET unzip [unzip]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 deflate64 '=' "NODEFLATE64"
|THEN|
#SET options [options], define NO_DEFLATE64
]
 
[#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 : [unzip]
#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.#UNZIP [options]
[#IF [tacl^completioncode] > 1 |THEN| #set OK 0 ]
#SET file [#FILENAMES /MAXIMUM 1, PREVIOUS [prev]/ [fileset]]
]
 
[#IF OK |THEN|
BBUNZIPLIB
[#IF [tacl^completioncode] > 0 |THEN| #SET OK 0]
]
 
#PUSH #PROCESSFILESECURITY
VOLUME ,"NUNU"
 
[#IF OK |THEN|
BBUNZIP [unzip] [clib]
[#IF [tacl^completioncode] > 0 |THEN| #SET OK 0]
]
 
[#IF OK |THEN|
secure^file [accel] [object^security] [object^owner]
accel^file [unzip] [accel]
[#IF [tacl^completioncode] > 0 |THEN| #SET OK 0]
]
 
[#IF OK
|THEN| #OUTPUT Successfully produced Accelerated Object [accel]
secure^file [accel] [object^security] [object^owner]
[#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
 
#UNFRAME
/programs/fs/unzip60/tandem/makesfx
0,0 → 1,79
?tacl routine
#FRAME
load /keep 1/ commacs
 
#PUSH file prev memory OK model sfx lib accel unlicensed licensed options
#PUSH #DEFAULTS
 
load /keep 1/ macros
 
#SET OK -1
 
[#IF [#ARGUMENT /VALUE memory/ KEYWORD /WORDLIST LARGE WIDE/ OTHERWISE ]]
[#IF [#ARGUMENT /VALUE unlicensed/ KEYWORD /WORDLIST UNLICENSED/ OTHERWISE ]]
 
[#IF memory '=' "WIDE"
|THEN|
#SET model WIDE
#SET sfx SFX
|ELSE|
#SET memory LARGE
#SET model NOWIDE
#SET sfx SFX
]
#OUTPUT Creating SFX Module
#SET lib [sfx]B
#SET accel SFX
 
#SET options [options], [model], define SFX
 
[#IF unlicensed '=' "UNLICENSED"
|THEN|
#SET sfx [sfx]U
#SET accel [accel]U
#SET lib [lib]U
|ELSE|
#SET licensed LICENSED
#SET options [options], define [licensed]
]
 
#OUTPUT Memory Model : [memory]
#OUTPUT Axcel Module : [accel]
#OUTPUT Run Module : [sfx]
 
[#IF [#FILEINFO /MODIFICATION/ EXTRACTC] > [#FILEINFO /MODIFICATION/ EXTRACTX]
|THEN|
#OUTPUT Compiling EXTRACTC for SFX
C /IN EXTRACTC, OUT $T.#SFX.EXTRACT/EXTRACTX;SYMBOLS,HIGHPIN [options]
|ELSE|
#OUTPUT EXTRACT(SFX) is up to date
]
 
[#IF [#FILEINFO /MODIFICATION/ PROCESSC] > [#FILEINFO /MODIFICATION/ PROCESSX]
|THEN|
#OUTPUT Compiling PROCESSC for SFX
C /IN PROCESSC, OUT $T.#SFX.PROCESS/PROCESSX;SYMBOLS,HIGHPIN [options]
|ELSE|
#OUTPUT PROCESS(SFX) is up to date
]
 
[#IF [#FILEINFO /MODIFICATION/ TANUNZC] > [#FILEINFO /MODIFICATION/ TANUNZX]
|THEN|
#OUTPUT Compiling TANUNZC for SFX
C /IN TANUNZC , OUT $T.#SFX.TANUNZ /TANUNZX ;SYMBOLS,HIGHPIN [options]
|ELSE|
#OUTPUT TANUNZ(SFX) is up to date
]
 
[#IF [#FILEINFO /MODIFICATION/ UNZIPC] > [#FILEINFO /MODIFICATION/ UNZIPX]
|THEN|
#OUTPUT Compiling UNZIPC for SFX
C /IN UNZIPC , OUT $T.#SFX.UNZIP /UNZIPX ;SYMBOLS,HIGHPIN [options]
|ELSE|
#OUTPUT UNZIP(SFX) is up to date
]
 
BBSFXLIB
BBSFX [sfx] [memory]
 
#UNFRAME
/programs/fs/unzip60/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 */
/programs/fs/unzip60/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 */
/programs/fs/unzip60/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 */
/programs/fs/unzip60/tandem/tanunz.c
0,0 → 1,1047
/*
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
*/
/*---------------------------------------------------------------------------
 
tanunz.c
 
Tandem/NSK routines for use with Info-ZIP's UnZip 5.3 and later.
 
Contains: do_wild() <-- generic enough to put in fileio.c?
ef_scan_for_tandem()
open_outfile()
mapattr()
mapname()
checkdir()
mkdir()
close_outfile()
version()
 
---------------------------------------------------------------------------*/
 
 
#define UNZIP_INTERNAL
#include "unzip.h"
 
#include <tal.h>
#include "$system.zsysdefs.zsysc" nolist
#include <cextdecs> nolist
#include "tannsk.h"
 
 
char *in2ex OF((__GPRO__ char *));
 
static nsk_file_attrs *ef_scan_for_tandem (
uch *ef_buf,
unsigned ef_len
);
 
 
static int created_dir; /* used in mapname(), checkdir() */
static int renamed_fullpath; /* ditto */
 
 
/****************************/
/* Strings used in tanunz.c */
/****************************/
 
static ZCONST char Far CannotDeleteOldFile[] =
"error: cannot delete old %s\n";
static ZCONST char Far CannotCreateFile[] = "error: cannot create %s\n";
 
 
#ifndef SFX
/**********************/
/* Function do_wild() */ /* for porting: dir separator; match(ignore_case) */
/**********************/
 
char *do_wild(__G__ wildspec)
__GDEF
ZCONST char *wildspec; /* only used first time on a given dir */
{
static DIR *wild_dir = (DIR *)NULL;
static ZCONST char *wildname;
static char *dirname, matchname[FILNAMSIZ];
static int notfirstcall=FALSE, have_dirname, dirnamelen;
struct dirent *file;
static char *intname;
int isdir = 0;
int pdosflag = 0;
 
/* 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 (!notfirstcall) { /* first call: must initialize everything */
notfirstcall = TRUE;
 
if (!iswild(wildspec)) {
strncpy(matchname, wildspec, FILNAMSIZ);
matchname[FILNAMSIZ-1] = '\0';
have_dirname = FALSE;
wild_dir = NULL;
return matchname;
}
 
dirnamelen = strlen(wildspec);
 
if ((dirname = (char *)malloc(dirnamelen+1)) == (char *)NULL) {
Info(slide, 0x201, ((char *)slide,
"warning: cannot allocate wildcard buffers\n"));
strncpy(matchname, wildspec, FILNAMSIZ);
matchname[FILNAMSIZ-1] = '\0';
return matchname; /* but maybe filespec was not a wildcard */
}
strcpy(dirname, wildspec);
wildname = wildspec;
have_dirname = FALSE;
 
if ((wild_dir = opendir(dirname)) != (DIR *)NULL) {
while ((file = readdir(wild_dir)) != (struct dirent *)NULL) {
Trace((stderr, "do_wild: readdir returns %s\n",
FnFilter1(file->d_name)));
if (file->d_name[0] == '.' && wildname[0] != '.')
continue; /* Unix: '*' and '?' do not match leading dot */
if (match(file->d_name, wildname, 0 WISEP) && /* 0=case sens.*/
/* skip "." and ".." directory entries */
strcmp(file->d_name, ".") && strcmp(file->d_name, "..")) {
Trace((stderr, "do_wild: match() succeeds\n"));
if (have_dirname) {
strcpy(matchname, dirname);
strcpy(matchname+dirnamelen, file->d_name);
} else
strcpy(matchname, file->d_name);
return matchname;
}
}
/* if we get to here directory is exhausted, so close it */
closedir(wild_dir);
wild_dir = (DIR *)NULL;
}
 
/* return the raw wildspec in case that works (e.g., directory not
* searchable, but filespec was not wild and file is readable) */
strncpy(matchname, wildspec, FILNAMSIZ);
matchname[FILNAMSIZ-1] = '\0';
return matchname;
}
 
/* last time through, might have failed opendir but returned raw wildspec */
if (wild_dir == (DIR *)NULL) {
notfirstcall = FALSE; /* nothing left to try--reset for new wildspec */
if (have_dirname)
free(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.
*/
while ((file = readdir(wild_dir)) != (struct dirent *)NULL) {
Trace((stderr, "do_wild: readdir returns %s\n",
FnFilter1(file->d_name)));
if (file->d_name[0] == '.' && wildname[0] != '.')
continue; /* Unix: '*' and '?' do not match leading dot */
if (match(file->d_name, wildname, 0 WISEP)) { /* 0 == case sens. */
if (have_dirname) {
/* strcpy(matchname, dirname); */
strcpy(matchname+dirnamelen, file->d_name);
} else
strcpy(matchname, file->d_name);
return matchname;
}
}
 
closedir(wild_dir); /* have read at least one entry; nothing left */
wild_dir = (DIR *)NULL;
notfirstcall = FALSE; /* reset for new wildspec */
if (have_dirname)
free(dirname);
return (char *)NULL;
 
} /* end function do_wild() */
 
#endif /* !SFX */
 
 
 
/*********************************/
/* Function ef_scan_for_tandem() */
/*********************************/
 
static nsk_file_attrs *ef_scan_for_tandem(ef_buf, ef_len)
uch *ef_buf; /* buffer containing extra field */
unsigned ef_len; /* total length of extra field */
{
unsigned eb_id;
unsigned eb_len;
 
/*---------------------------------------------------------------------------
This function scans the extra field for EF_TANDEM
-------------------------------------------------------------------------*/
 
if (ef_buf == NULL)
return NULL;
 
while (ef_len >= EB_HEADSIZE) {
eb_id = makeword(EB_ID + ef_buf);
eb_len = makeword(EB_LEN + ef_buf);
 
if (eb_len > (ef_len - EB_HEADSIZE)) {
/* discovered some extra field inconsistency! */
TTrace((stderr,
"ef_scan_for_tandem: block length %u > rest ef_size %u\n", eb_len,
ef_len - EB_HEADSIZE));
break;
}
 
switch (eb_id) {
case EF_TANDEM:
return (nsk_file_attrs *)(char *)(ef_buf + EB_HEADSIZE);
break;
 
default:
break;
}
 
/* Skip this extra field block */
ef_buf += (eb_len + EB_HEADSIZE);
ef_len -= (eb_len + EB_HEADSIZE);
}
 
return NULL;
}
 
 
/***************************/
/* Function open_outfile() */
/***************************/
 
int open_outfile(__G) /* return 1 if fail */
__GDEF
{
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;
nsk_file_attrs *znsk_attr;
ulg eof, pages;
char nsk_work[FILENAME_MAX + 1], *nsk_fname=&nsk_work[0];
 
#ifdef DLL
if (G.redirect_data)
return (redirect_outfile(__G) == FALSE);
#endif
if (SSTAT(G.filename, &G.statbuf) == 0) {
Trace((stderr, "open_outfile: stat(%s) returns 0: file exists\n",
FnFilter1(G.filename)));
if (unlink(G.filename) != 0) {
Trace((stderr, "open_outfile: existing file %s is read-only\n",
FnFilter1(G.filename)));
chmod(G.filename, S_IRUSR | S_IWUSR);
Trace((stderr, "open_outfile: %s now writable\n",
FnFilter1(G.filename)));
if (unlink(G.filename) != 0) {
Info(slide, 0x401, ((char *)slide,
LoadFarString(CannotDeleteOldFile), FnFilter1(G.filename)));
return 1;
}
}
Trace((stderr, "open_outfile: %s now deleted\n",
FnFilter1(G.filename)));
}
 
/* Set up Tandem specific file information if present */
znsk_attr = ef_scan_for_tandem(G.extra_field, G.lrec.extra_field_length);
if (znsk_attr != NULL) {
/* Set extent sizes */
priext = znsk_attr->priext;
secext = znsk_attr->secext;
maxext = (int) znsk_attr->maxext;
/* If original file was Enscribe and text then recreate as Edit */
filecode = (znsk_attr->filetype != NSK_UNSTRUCTURED ?
(G.pInfo->textmode ? NSK_EDITFILECODE : NSK_UNSTRUCTURED) :
znsk_attr->filecode);
blocksize = znsk_attr->block;
} else {
/* Try to work out some decent sizes based on how big the file is */
eof = G.lrec.ucsize;
pages = (eof/2048) + 2;
if (pages <= 500) {
priext = pages; /* fits into one extent */
maxext = 16;
} else {
priext = 500; /* Try and fit into 500 page chunks */
maxext = pages/(priext - 50); /* Allow for Enscribe overhead */
if (maxext > 978) {
priext = eof >> 10; /* 512 equal extents */
maxext = 978; /* 2048 * 512 == 2^10 */
}
}
secext = priext;
filecode = (G.pInfo->textmode ? NSK_EDITFILECODE : NSK_UNSTRUCTURED);
blocksize = TANDEM_BLOCKSIZE;
}
 
if ((fdesc = creat(G.filename,,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(G.filename);
err = STRING_UPSHIFT_(G.filename,
len,
nsk_fname,
len);
 
err = FILE_ALTERLIST_(nsk_fname,
len,
alist,
alist_items,
vlist,
vlist_bytes,
,
err_item);
};
 
G.outfile = fopen(G.filename, (G.pInfo->textmode ? FOPWT : FOPW));
 
if (G.outfile == (FILE *)NULL) {
Info(slide, 1, ((char *)slide, LoadFarString(CannotCreateFile),
FnFilter1(G.filename)));
return 1;
}
 
#ifdef USE_FWRITE
#ifdef _IOFBF /* make output fully buffered (works just about like write()) */
setvbuf(G.outfile, (char *)slide, _IOFBF, WSIZE);
#else
setbuf(G.outfile, (char *)slide);
#endif
#endif /* USE_FWRITE */
return 0;
 
} /* end function open_outfile() */
 
 
 
/**********************/
/* Function mapattr() */
/**********************/
 
int mapattr(__G)
__GDEF
{
ulg tmp = G.crec.external_file_attributes;
 
switch (G.pInfo->hostnum) {
case AMIGA_:
tmp = (unsigned)(tmp>>17 & 7); /* Amiga RWE bits */
G.pInfo->file_attr = (unsigned)(tmp<<6 | tmp<<3 | tmp);
break;
case THEOS_:
tmp &= 0xF1FFFFFFL;
if ((tmp & 0xF0000000L) != 0x40000000L)
tmp &= 0x01FFFFFFL; /* not a dir, mask all ftype bits */
else
tmp &= 0x41FFFFFFL; /* leave directory bit as set */
/* fall through! */
case TANDEM_:
case UNIX_:
case VMS_:
case ACORN_:
case ATARI_:
case ATHEOS_:
case BEOS_:
case QDOS_:
G.pInfo->file_attr = (unsigned)(tmp >> 16);
if (G.pInfo->file_attr != 0 || !G.extra_field) {
return 0;
} else {
/* Some (non-Info-ZIP) implementations of Zip for Unix and
VMS (and probably others ??) leave 0 in the upper 16-bit
part of the external_file_attributes field. Instead, they
store file permission attributes in some extra field.
As a work-around, we search for the presence of one of
these extra fields and fall back to the MSDOS compatible
part of external_file_attributes if one of the known
e.f. types has been detected.
Later, we might implement extraction of the permission
bits from the VMS extra field. But for now, the work-around
should be sufficient to provide "readable" extracted files.
(For ASI Unix e.f., an experimental remap of the e.f.
mode value IS already provided!)
*/
ush ebID;
unsigned ebLen;
uch *ef = G.extra_field;
unsigned ef_len = G.crec.extra_field_length;
int r = FALSE;
 
while (!r && ef_len >= EB_HEADSIZE) {
ebID = makeword(ef);
ebLen = (unsigned)makeword(ef+EB_LEN);
if (ebLen > (ef_len - EB_HEADSIZE))
/* discoverd some e.f. inconsistency! */
break;
switch (ebID) {
case EF_ASIUNIX:
if (ebLen >= (EB_ASI_MODE+2)) {
G.pInfo->file_attr =
(unsigned)makeword(ef+(EB_HEADSIZE+EB_ASI_MODE));
/* force stop of loop: */
ef_len = (ebLen + EB_HEADSIZE);
break;
}
/* else: fall through! */
case EF_PKVMS:
/* "found nondecypherable e.f. with perm. attr" */
r = TRUE;
default:
break;
}
ef_len -= (ebLen + EB_HEADSIZE);
ef += (ebLen + EB_HEADSIZE);
}
if (!r)
return 0;
}
/* fall through! */
/* all remaining cases: expand MSDOS read-only bit into write perms */
case FS_FAT_:
/* PKWARE's PKZip for Unix marks entries as FS_FAT_, but stores the
* Unix attributes in the upper 16 bits of the external attributes
* field, just like Info-ZIP's Zip for Unix. We try to use that
* value, after a check for consistency with the MSDOS attribute
* bits (see below).
*/
G.pInfo->file_attr = (unsigned)(tmp >> 16);
/* fall through! */
case FS_HPFS_:
case FS_NTFS_:
case MAC_:
case TOPS20_:
default:
/* Ensure that DOS subdir bit is set when the entry's name ends
* in a '/'. Some third-party Zip programs fail to set the subdir
* bit for directory entries.
*/
if ((tmp & 0x10) == 0) {
extent fnlen = strlen(G.filename);
if (fnlen > 0 && G.filename[fnlen-1] == '/')
tmp |= 0x10;
}
/* read-only bit --> write perms; subdir bit --> dir exec bit */
tmp = !(tmp & 1) << 1 | (tmp & 0x10) >> 4;
if ((G.pInfo->file_attr & 0700) == (unsigned)(0400 | tmp<<6))
/* keep previous G.pInfo->file_attr setting, when its "owner"
* part appears to be consistent with DOS attribute flags!
*/
return 0;
G.pInfo->file_attr = (unsigned)(0444 | tmp<<6 | tmp<<3 | tmp);
break;
} /* end switch (host-OS-created-by) */
 
/* for originating systems without concept of "group," "other," "system" */
umask( (int)(tmp=umask(0)) ); /* apply mask to expanded r/w(/x) perms */
G.pInfo->file_attr &= ~tmp;
 
return 0;
 
} /* end function mapattr() */
 
 
 
 
 
/************************/
/* Function mapname() */
/************************/
 
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; /* character pointers */
char *lastsemi=(char *)NULL; /* pointer to last semi-colon in pathcomp */
int error = MPN_OK;
register unsigned workch; /* hold the character being tested */
 
 
/*---------------------------------------------------------------------------
Initialize various pointers and counters and stuff.
---------------------------------------------------------------------------*/
 
if (G.pInfo->vollabel)
return MPN_VOL_LABEL; /* can't set disk volume labels on Tandem */
 
/* can create path as long as not just freshening, or if user told us */
G.create_dirs = (!uO.fflag || renamed);
 
created_dir = FALSE; /* not yet */
 
/* user gave full pathname: don't prepend rootpath */
renamed_fullpath = (renamed && (*G.filename == '/'));
 
if (checkdir(__G__ (char *)NULL, INIT) == MPN_NOMEM)
return MPN_NOMEM; /* initialize path buffer, unless no memory */
 
/* TANDEM - call in2ex */
pp = in2ex(__G__ G.filename);
if (pp == (char *)NULL)
return MPN_NOMEM;
strcpy(G.filename, pp);
free(pp);
 
*pathcomp = '\0'; /* initialize translation buffer */
pp = pathcomp; /* point to translation buffer */
/* directories have already been junked in in2ex() */
cp = G.filename; /* point to internal zipfile-member pathname */
 
/*---------------------------------------------------------------------------
Begin main loop through characters in filename.
---------------------------------------------------------------------------*/
 
while ((workch = (uch)*cp++) != 0) {
 
switch (workch) { /* includes space char, let checkdir handle it */
case TANDEM_DELIMITER: /* can assume -j flag not given */
*pp = '\0';
if (((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 ';': /* VMS version (or DEC-20 attrib?) */
lastsemi = pp;
*pp++ = ';'; /* keep for now; remove VMS ";##" */
break; /* later, if requested */
 
default:
/* allow European characters in filenames: */
if (isprint(workch) || (128 <= workch && workch <= 254))
*pp++ = (char)workch;
} /* end switch */
 
} /* end while loop */
 
/*---------------------------------------------------------------------------
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[strlen(G.filename) - 1] == TANDEM_DELIMITER) {
checkdir(__G__ G.filename, GETPATH);
if (created_dir) {
if (QCOND2) {
Info(slide, 0, ((char *)slide, " creating: %s\n",
FnFilter1(G.filename)));
}
/* set dir time (note trailing '/') */
return (error & ~MPN_MASK) | MPN_CREATED_DIR;
}
/* 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;
while (isdigit((uch)(*pp)))
++pp;
if (*pp == '\0') /* only digits between ';' and end: nuke */
*lastsemi = '\0';
}
 
if (*pathcomp == '\0') {
Info(slide, 1, ((char *)slide, "mapname: conversion of %s failed\n",
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);
 
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
*/
/* By using in2ex() to pre-process the filename we do not need to worry
about the lengths of filename parts. We just need to cope with mapping the
pseudo file extensions properly of the actual filename (last part of name).
e.g. "tandem c" -> tandemc
"revsion.h" -> revisioh
*/
{
static int rootlen = 0; /* length of rootpath */
static char *rootpath; /* user's "extract-to" directory */
static char *buildpath; /* full path (so far) to extracted file */
static char *end; /* pointer to end of buildpath ('\0') */
 
# define FN_MASK 7
# define FUNCTION (flag & FN_MASK)
 
char fname[FILENAME_MAX + 1];
short fnamelen, extlen, trunclen, i;
char ext[EXTENSION_MAX + 1];
char *ptr;
 
 
/*---------------------------------------------------------------------------
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) {
int too_long = FALSE;
 
Trace((stderr, "appending dir segment [%s]\n", FnFilter1(pathcomp)));
while ((*end = *pathcomp++) != '\0')
++end;
 
if (stat(buildpath, &G.statbuf)) { /* path doesn't exist */
if (!G.create_dirs) { /* told not to create (freshening) */
free(buildpath);
return MPN_INF_SKIP; /* path doesn't exist: nothing to do */
}
if (mkdir(buildpath, 0777) == -1) { /* create the directory */
Info(slide, 1, ((char *)slide,
"checkdir error: cannot create %s\n\
unable to process %s.\n",
FnFilter2(buildpath), FnFilter1(G.filename)));
free(buildpath);
/* path didn't exist, tried to create, failed */
return MPN_ERR_SKIP;
}
created_dir = TRUE;
} else if (!S_ISDIR(G.statbuf.st_mode)) {
Info(slide, 1, ((char *)slide,
"checkdir error: %s exists but is not directory\n\
unable to process %s.\n",
FnFilter2(buildpath), FnFilter1(G.filename)));
free(buildpath);
/* path existed but wasn't dir */
return MPN_ERR_SKIP;
}
*end++ = TANDEM_DELIMITER;
*end = '\0';
Trace((stderr, "buildpath now = [%s]\n", FnFilter1(buildpath)));
return MPN_OK;
 
} /* end if (FUNCTION == APPEND_DIR) */
 
/*---------------------------------------------------------------------------
GETPATH: copy full path to the string pointed at by pathcomp, and free
buildpath.
---------------------------------------------------------------------------*/
 
if (FUNCTION == GETPATH) {
strcpy(pathcomp, buildpath);
Trace((stderr, "getting and freeing path [%s]\n",
FnFilter1(pathcomp)));
free(buildpath);
buildpath = end = (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) {
Trace((stderr, "appending filename [%s]\n", FnFilter1(pathcomp)));
 
if (!uO.rflag /* Do not add extension if asked */
&& parsename(pathcomp, fname, ext))
{
fnamelen = strlen(fname);
extlen = strlen(ext);
if (fnamelen+extlen > MAXFILEPARTLEN) {
/* Doesn't fit. Best approx is to use up to three characters
from extension and place these on the end of as much of the
start of the filename part as possible.
*/
if (extlen > EXTENSION_MAX)
extlen = EXTENSION_MAX;
trunclen = MAXFILEPARTLEN - extlen;
ptr = fname;
for (i=0; i < trunclen; i++)
*end++ = *ptr++;
ptr = ext;
for (i=0; i < extlen; i++)
*end++ = *ptr++;
*end = '\0'; /* mark end of string */
}
else {
/* Just join parts end to end */
ptr = fname;
while ((*end = *ptr++) != '\0')
++end;
ptr = ext;
while ((*end = *ptr++) != '\0')
++end;
}
}
else
while ((*end = *pathcomp++) != '\0')
++end;
 
Trace((stderr, "buildpath now = [%s]\n", FnFilter1(buildpath)));
/* could check for existence here, prompt for new name... */
return MPN_OK;
}
 
/*---------------------------------------------------------------------------
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.
---------------------------------------------------------------------------*/
 
/* GRR: for VMS and TOPS-20, add up to 13 to strlen */
 
if (FUNCTION == INIT) {
Trace((stderr, "initializing buildpath to "));
if ((buildpath = (char *)malloc(strlen(G.filename)+rootlen+1))
== (char *)NULL)
return MPN_NOMEM;
if ((rootlen > 0) && !renamed_fullpath) {
strcpy(buildpath, rootpath);
end = buildpath + rootlen;
} else {
*buildpath = '\0';
end = buildpath;
}
Trace((stderr, "[%s]\n", FnFilter1(buildpath)));
return MPN_OK;
}
 
/*---------------------------------------------------------------------------
ROOT: if appropriate, store the path in rootpath and create it if
necessary; 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.
---------------------------------------------------------------------------*/
 
#if (!defined(SFX) || defined(SFX_EXDIR))
if (FUNCTION == ROOT) {
Trace((stderr, "initializing root path to [%s]\n",
FnFilter1(pathcomp)));
if (pathcomp == (char *)NULL) {
rootlen = 0;
return MPN_OK;
}
if (rootlen > 0) /* rootpath was already set, nothing to do */
return MPN_OK;
if ((rootlen = strlen(pathcomp)) > 0) {
char *tmproot;
 
if ((tmproot = (char *)malloc(rootlen+2)) == (char *)NULL) {
rootlen = 0;
return MPN_NOMEM;
}
strcpy(tmproot, pathcomp);
if (tmproot[rootlen-1] == TANDEM_DELIMITER) {
tmproot[--rootlen] = '\0';
}
if (rootlen > 0 && (stat(tmproot, &G.statbuf) ||
!S_ISDIR(G.statbuf.st_mode)))
{ /* path does not exist */
if (!G.create_dirs /* || iswild(tmproot) */ ) {
free(tmproot);
rootlen = 0;
/* skip (or treat as stored file) */
return MPN_INF_SKIP;
}
/* create the directory (could add loop here scanning tmproot
* to create more than one level, but why really necessary?) */
if (mkdir(tmproot, 0777) == -1) {
Info(slide, 1, ((char *)slide,
"checkdir: cannot create extraction directory: %s\n",
FnFilter1(tmproot)));
free(tmproot);
rootlen = 0;
/* path didn't exist, tried to create, and failed: */
/* file exists, or 2+ subdir levels required */
return MPN_ERR_SKIP;
}
}
tmproot[rootlen++] = TANDEM_DELIMITER;
tmproot[rootlen] = '\0';
if ((rootpath = (char *)realloc(tmproot, rootlen+1)) == NULL) {
free(tmproot);
rootlen = 0;
return MPN_NOMEM;
}
Trace((stderr, "rootpath now = [%s]\n", FnFilter1(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 (rootlen > 0) {
free(rootpath);
rootlen = 0;
}
return MPN_OK;
}
 
return MPN_INVALID; /* should never reach */
 
} /* end function checkdir() */
 
 
 
/********************/
/* Function mkdir() */
/********************/
 
int mkdir(path, mode)
const char *path; /* both */
mode_t mode; /* ignored */
/*
* returns: 0 - successful
* -1 - failed (errno not set, however)
*/
{
return 0;
}
 
 
/****************************/
/* Function close_outfile() */
/****************************/
 
void close_outfile(__G) /* GRR: change to return PK-style warning level */
__GDEF
{
union {
iztimes t3; /* mtime, atime, ctime */
ztimbuf t2; /* modtime, actime */
} zt;
ulg z_uidgid[2];
unsigned eb_izux_flg;
nsk_file_attrs *znsk_attr;
short err;
unsigned short len;
 
#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];
 
fclose(G.outfile);
 
/* Set up Tandem specific file information if present */
znsk_attr = ef_scan_for_tandem(G.extra_field, G.lrec.extra_field_length);
 
/* Currently we do not create 'proper' Tandem files in unzip - we only */
/* create unstructured (180) or edit (101) files. This code allows */
/* some limited support for restoration of Tandem file attributes */
 
if (znsk_attr != NULL) {
/* Reset File Code */
if (!uO.bflag && !G.pInfo->textmode
&& znsk_attr->filetype == NSK_UNSTRUCTURED) {
/* leave type 101 files alone */
vlist[0] = znsk_attr->filecode;
 
/* Note that FILE_ALTERLIST_ expect uppercase names and that */
/* G.lrec.filename_length is the length of original zipped filename */
/* not any 'rename' name. Need to re call strlen and upshift */
len = strlen(G.filename);
err = STRING_UPSHIFT_(G.filename,
len,
nsk_fname,
len);
 
err = FILE_ALTERLIST_(nsk_fname,
len,
alist,
alist_items,
vlist,
vlist_bytes,
,
err_item);
}
}
 
 
/*---------------------------------------------------------------------------
Convert from MSDOS-format local time and date to Unix-format 32-bit GMT
time: adjust base year from 1980 to 1970, do usual conversions from
yy/mm/dd hh:mm:ss to elapsed seconds, and account for timezone and day-
light savings time differences. If we have a Unix extra field, however,
we're laughing: both mtime and atime are ours. On the other hand, we
then have to check for restoration of UID/GID.
---------------------------------------------------------------------------*/
 
eb_izux_flg = (G.extra_field ? ef_scan_for_izux(G.extra_field,
G.lrec.extra_field_length, 0, G.lrec.last_mod_dos_datetime,
#ifdef IZ_CHECK_TZ
(G.tz_is_valid ? &(zt.t3) : NULL),
#else
&(zt.t3),
#endif
z_uidgid) : 0);
if (eb_izux_flg & EB_UT_FL_MTIME) {
TTrace((stderr, "\nclose_outfile: Unix e.f. modif. time = %ld\n",
zt.t3.mtime));
} else {
zt.t3.mtime = dos_to_unix_time(G.lrec.last_mod_dos_datetime);
}
if (eb_izux_flg & EB_UT_FL_ATIME) {
TTrace((stderr, "close_outfile: Unix e.f. access time = %ld\n",
zt.t3.atime));
} else {
zt.t3.atime = zt.t3.mtime;
TTrace((stderr, "\nclose_outfile: modification/access times = %ld\n",
zt.t3.mtime));
}
 
/*---------------------------------------------------------------------------
Change the file's last modified time to that stored in the zipfile.
Not sure how (yet) or whether it's a good idea to set the last open time
---------------------------------------------------------------------------*/
 
/* skip restoring time stamps on user's request */
if (uO.D_flag <= 1) {
/* set the file's access and modification times */
if (utime(G.filename, &(zt.t2)))
if (uO.qflag)
Info(slide, 0x201, ((char *)slide,
"warning: cannot set times for %s\n",
FnFilter1(G.filename)));
else
Info(slide, 0x201, ((char *)slide,
" (warning) cannot set times"));
}
 
/*---------------------------------------------------------------------------
Change the file permissions from default ones to those stored in the
zipfile.
---------------------------------------------------------------------------*/
 
#ifndef NO_CHMOD
if (chmod(G.filename, 0xffff & G.pInfo->file_attr))
perror("chmod (file attributes) error");
#endif
 
/*---------------------------------------------------------------------------
if -X option was specified and we have UID/GID info, restore it
this must come after the file security and modtimes changes - since once
we have secured the file to somebody else we cannot access it again.
---------------------------------------------------------------------------*/
 
if (uO.X_flag && eb_izux_flg & EB_UX2_VALID) {
TTrace((stderr, "close_outfile: restoring Unix UID/GID info\n"));
if (chown(G.filename, (uid_t)z_uidgid[0], (gid_t)z_uidgid[1]))
{
if (uO.qflag)
Info(slide, 0x201, ((char *)slide,
"warning: cannot set UID %lu and/or GID %lu for %s\n",
z_uidgid[0], z_uidgid[1], FnFilter1(G.filename)));
else
Info(slide, 0x201, ((char *)slide,
" (warning) cannot set UID %lu and/or GID %lu",
z_uidgid[0], z_uidgid[1]));
}
}
 
} /* end function close_outfile() */
 
 
#ifndef SFX
 
/************************/
/* Function version() */
/************************/
 
void version(__G)
__GDEF
{
 
/* Pyramid, NeXT have problems with huge macro expansion, too: no Info() */
sprintf((char *)slide, LoadFarString(CompiledWith),
 
"C ",
"T9255D44 - (16OCT98)",
"NonStop ",
"(Tandem/NSK)",
 
#ifdef __DATE__
" on ", __DATE__
#else
"", ""
#endif
);
 
(*G.message)((zvoid *)&G, slide, (ulg)strlen((char *)slide), 0);
 
} /* end function version() */
 
#endif /* !SFX */