/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 */ |