Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

COPYTREE, part 01/01

3 views
Skip to first unread message

fair...@sldb2.slac.stanford.edu

unread,
Jul 27, 1995, 3:00:00 AM7/27/95
to
Submitted-by: Ken Fairfield <Fair...@SLAC.Stanford.EDU>
Posting-number: Volume 7, Issue 58
Archive-name: copytree/part01

The following command file in VMS_SHARE format, COPYTREE.COM, copies
an entire directory tree from a "source" root to a "destination"
root. Optionally, the source root can be on a remote DECnet node.
If the destination root directory does not exist, it will be created
(provided the user running the procedure has adequate privileges and
disk quota). The destination root need not be the same, or even
related to, the source root directory name.

Please read the comments at the top of the file for usage,
restrictions, and comments on the alternative of using COPY in some
cases.

-Ken
--
Kenneth H. Fairfield | Internet: Fair...@Slac.Stanford.Edu
SLAC, P.O.Box 4349, MS 46 | DECnet: 45537::FAIRFIELD (45537=SLACVX)
Stanford, CA 94309 | Voice: 415-926-2924 FAX: 415-926-3515
-------------------------------------------------------------------------
These opinions are mine, not SLAC's, Stanford's, nor the DOE's...

-------------------------------------------------------------------------------
$! ------------------ CUT HERE -----------------------
$ v='f$verify(f$trnlnm("SHARE_UNPACK_VERIFY"))'
$!
$! This archive created:
$! Name : COPYTREE
$! By : Ken Fairfield <Fair...@SLAC.Stanford.EDU>
$! Date : 15-JUL-1995 20:20:12.37
$! Using: VMS_SHARE 8.5-1, (C) 1993 Andy Harper, Kings College London UK
$!
$! Credit is due to these people for their original ideas:
$! James Gray, Michael Bednarek
$!
$! To unpack this archive:
$! Minimum of VMS 4.4 (VAX) / OpenVMS 1.0 (Alpha) is required.
$! Remove the headers of the first part, up to `cut here' line.
$! Execute file as a command procedure.
$!
$! The following file(s) will be created after unpacking:
$! 1. COPYTREE.COM
$!
$ set="set"
$ set symbol/scope=(nolocal,noglobal)
$ f="SYS$SCRATCH:."+f$getjpi("","PID")+";"
$ if f$trnlnm("SHARE_UNPACK") .nes. "" then $ -
f=f$parse("SHARE_UNPACK_TEMP",f)
$ e="write sys$error ""%UNPACK"", "
$ w="write sys$output ""%UNPACK"", "
$ if .not. f$trnlnm("SHARE_UNPACK_LOG") then $ w = "!"
$ if f$getsyi("CPU") .gt. 127 then $ goto start
$ ve=f$getsyi("version")
$ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto start
$ e "-E-OLDVER, Must run at least VMS 4.4"
$ v=f$verify(v)
$ exit 44
$unpack:subroutine!P1=file,P2=chksum,P3=attrib,P4=size,P5=fileno,P6=filetotal
$ if f$parse(P1) .nes. "" then $ goto dirok
$ dn=f$parse(P1,,,"DIRECTORY")
$ w "-I-CREDIR, Creating directory ''dn'"
$ create/dir 'dn'
$ if $status then $ goto dirok
$ e "-E-CREDIRFAIL, Unable to create ''dn' File skipped"
$ delete 'f'*
$ exit
$dirok:
$ x=f$search(P1)
$ if x .eqs. "" then $ goto file_absent
$ e "-W-HIGHVERS, Creating higher version of ", P1
$file_absent:
$ w "-I-UNPACK, Unpacking ", P5, " of ", P6, " - ", P1, " - ", P4, " Blocks"
$ n=P1
$ if P3 .nes. "" then $ n=f
$ if .not. f$verify() then $ define/user sys$output nl:
$ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT/NOJOURNAL 'f'/OUT='n'
PROCEDURE GetHex(s,p)LOCAL x1,x2;x1:=INDEX(t,SUBSTR(s,p,1))-1;x2:=INDEX(t,
SUBSTR(s,p+1,1))-1;RETURN 16*x1+x2;ENDPROCEDURE;PROCEDURE SkipPartsep LOCAL m;
LOOP m:=MARK(NONE);EXITIF m=END_OF(CURRENT_BUFFER);DELETE(m);EXITIF INDEX(
ERASE_LINE,"-+-+-+-+-+-+-+-+")=1;ENDLOOP;ENDPROCEDURE;
PROCEDURE ProcessLine LOCAL c,s,l,b,n,p;s := ERASE_LINE;EDIT(s,TRIM);c :=
SUBSTR(s,1,1);s := s-c;IF c = "X" THEN SPLIT_LINE; ENDIF;MOVE_HORIZONTAL(-1);
l := LENGTH(s);p := 1;LOOP EXITIF p > l;c := SUBSTR(s,p,1);p := p+1;
CASE c FROM ' ' TO '`' ['`']: COPY_TEXT(ASCII(GetHex(s,p))); p:=p+2;[INRANGE,
OUTRANGE]: COPY_TEXT(c);ENDCASE;ENDLOOP;ENDPROCEDURE;PROCEDURE Decode(b)
LOCAL m;POSITION(BEGINNING_OF(b));LOOP m:=MARK(NONE);EXITIF m=END_OF(b);DELETE(
m);IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+-")=1 THEN SkipPartSep;
ELSE ProcessLine;MOVE_HORIZONTAL(1);ENDIF;ENDLOOP;ENDPROCEDURE;SET(
FACILITY_NAME,"UNPACK");SET(SUCCESS,OFF);SET(INFORMATIONAL,OFF);t:=
"0123456789ABCDEF";f:=GET_INFO(COMMAND_LINE,"file_name");o:=CREATE_BUFFER(f,f);
Decode(o);WRITE_FILE(o,GET_INFO(COMMAND_LINE,"output_file"));QUIT;
$ if p3 .eqs. "" then $ goto dl
$ open/write fdl &f
$ write fdl "RECORD"
$ write fdl P3
$ close fdl
$ w "-I-CONVRFM, Converting record format to ", P3
$ convert/fdl='f' 'f'-1 'f'
$ fa=f$getdvi(f$parse(f),"ALLDEVNAM")
$ Pa=f$getdvi(f$parse(P1),"ALLDEVNAM")
$ if fa .eqs. Pa then $ rename &f 'f$parse(P1)'
$ if fa .nes. Pa then $ copy &f 'f$parse(P1)'
$dl: delete 'f'*
$ checksum 'P1'
$ if checksum$checksum .nes. P2 then $ -
e "-E-CHKSMFAIL, Checksum of ''P1' failed."
$ exit
$ endsubroutine
$start:
$!
$ create 'f'
X$!++
X$!`09`09C O P Y T R E E . C O M
X$!`09`09=======================
X$!
X$!`09Command procedure to copy a complete directory tree from one
X$!`09"root" to another, including between DECnet nodes.
X$!
X$!
X$! Input Parameters:
X$!
X$!`09P1 - Source root directory.`09This should include the full
X$!`09 directory specification, e.g. NODE::DEV:`5BDIRECTORY`5D, where
X$!`09 NODE:: is optional. The source root may include one or
X$!`09 more subdirectories. Files resident in the source root
X$!`09 directory are copied to the destination root directory.
X$!
X$!`09P2 - Destination root directory. Give a complete specification
X$!`09 similar to P1. However, a NODE:: specification is NOT
X$!`09 allowed: the destination root directory must be on the
X$!`09 local node.
X$!
X$!`09P3 - File protection string for creating P2 (optional). The
X$!`09 protection string must be specified in the standard
X$!`09 SYSTEM,OWNER,GROUP,WORLD order since a default D(elete)
X$!`09 protection may be added to SYSTEM and OWNER for the files
X$!`09 created.
X$!
X$!`09 When specifying P3, use an equals sign, rather than a
X$!`09 colon, to separate the access class from the access code.
X$!`09 For example, use "S=RWE,O=WR,G,W", not "S:RWE,O:WR,G,W".
X$!
X$!
X$! Notes:
X$!
X$!`09If a given (sub)directory already exists on the destination
X$!`09device, the user is prompted before continuing the COPY to that
X$!`09directory (and its subdirectories).`09This avoids _accidently_
X$!`09copying, say, the MAIL files from the source directory to the
X$!`09user's current MAIL subdirectory. As a result, the user will
X$!`09_frequently_ have to answer this question in the affirmative for
X$!`09the (top-level) destination directory since it is common for that
X$!`09directory to already exist, e.g., the user's login directory.
X$!
X$!`09File and directory protection masks are taken from the source
X$!`09directory and its subdirectories. The destination root directory
X$!`09protection mask (only) may be specified on the command line if it
X$!`09is to be different than the source directory protection. All
X$!`09files with file type .MAI are given the protection (RW,RW,,) which
X$!`09is the VMS default protection for MAIL files.
X$!
X$!`09In some restricted circumstances, a COPY command may serve in
X$!`09place of this procedure. In particular, if the source root
X$!`09directory exists on the destination device, _and_ the user has
X$!`09READ access to the `5B000000`5D directory on that device, then the
X$!`09following syntax will work:
X$!
X$!`09 $ COPY NODE::DEVICE:`5BDIR...`5D*.*;* DEV2:`5B*...`5D
X$!
X$!`09If the source directory includes a subdirectory specification,
X$!`09e.g., `5BDIR.SUBDIR.SUB2...`5D, then `5BDIR.SUBDIR.SUB2`5D _must_ exist o
Vn
X$!`09the destination device, DEV2:, for the COPY to succeed. Note that
X$!`09it is common practice on VMS systems to _deny_ access to `5B000000`5D
X$!`09for unprivileged users. Thanks to Rod Eldridge <r...@iastate.edu>,
X$!`09Jim Dunham <dun...@star.enet.dec.com>, and others for pointing out
X$!`09this alternative.
X$!
X$!
X$!
X$! Restrictions:
X$!
X$!`09In order to keep this procedure fairly simple, the following
X$!`09restriction must be observed:
X$!
X$!`09o Use of angle brackets, <>, in directory specifications is
X$!`09 NOT supported. Use only square brackets, `5B`5D, in both source
X$!`09 and destination directory specifications. This restriction
X$!`09 could be relaxed, but the present author isn't sufficiently
X$!`09 motivated...
X$!
X$!`09o The user must have READ access to the files on the remote
X$!`09 node if NODE:: is specified. This may present problems for
X$!`09 world-read-protected files, such as *.MAI. You _may_ supply
X$!`09 an access string in the node specification, for example,
X$!`09 NODE"accnt passwd"::, but this should be discouraged since
X$!`09 the password is sent in PLAIN TEXT over the network to the
X$!`09 remote node. It is far better to arrange for PROXY access
X$!`09 to the remote node by using AUTHORIZE (on the remote node)
X$!`09 to ADD/PROXY the user(s) in question.
X$!
X$!`09o ACL's present on the source files are not (necessarily) pro-
X$!`09 pogated to the destination files. ACL's on the destination
X$!`09 directory will be applied according to the rules used by
X$!`09 COPY.
X$!
X$!`09o The destination root directory must not contain a DECnet
X$!`09 node name even if the full tree of subdirectories exists
X$!`09 under the destination root. This procedure tries to create
X$!`09 each subdirectory (even when it already exists), and
X$!`09 CREATE/DIRECTORY does not allow a node name in the directory
X$!`09 specification. `5BThis restriction could be "lightened" by
X$!`09 testing for the existence of the subdirectory first, but it
X$!`09 would still require that the whole tree of subdirectories be
X$!`09 present under the destination root, and there seems little
X$!`09 to be gained by adding that limited capability.`5D
X$!
X$!
X$! Author/Date:`09K.H. Fairfield,`09`0929-APR-1991
X$!`09`09`09Stanford Linear Accelerator Center
X$!`09`09`09P.O. Box 4349, M/S 46
X$!`09`09`09Stanford, CA 94309-4349 `20
X$!`09`09`09<Fair...@SLAC.Stanford.EDU>
X$!
X$! Revisions:
X$!
X$!`09K.H. Fairfield, 07-DEC-1992
X$!`09Take file protection mask from the source directory and its
X$!`09subdirectories, while adding Delete access for Owner and System.
X$!
X$!`09K.H. Fairfield, 08-JUN-1994
X$!`09Expanded processing of the file protection string for SYSTEM and
X$!`09OWNER fields to avoid adding a "D" when no access was allowed, or
X$!`09when the "D" was already present in the directory protection (both
X$!`09conditions nonstandard, in my opinion, but...). Thanks`09to
X$!`09Sebastian Kloska for pointing out that neither of these cases had
X$!`09been handled correctly previously.
X$!--
X$
X$`09If p1 .Eqs. "" Then Inquire p1 "Input root"
X$`09If p2 .Eqs. "" Then Inquire p2 "Output root"
X$`09If p3 .Nes. ""
X$`09Then
X$`09 dirprot = "/Prot=(" + p3 + ")"
X$
X$`09 sysprot = F$Element(0, ",", p3)
X$`09 theprot = F$Element(1, "=", sysprot)
X$`09 If theprot .Nes. "="
X$`09 Then
X$`09 sysprot = "SYSTEM=" + theprot - "D" + "D"
X$`09 Else
X$`09 sysprot = "SYSTEM"
X$`09 Endif
X$
X$`09 ownprot = F$Element(1, ",", p3)
X$`09 theprot = F$Element(1, "=", ownprot)
X$`09 If theprot .Nes. "="
X$`09 Then
X$`09 ownprot = "OWNER=" + theprot - "D" + "D"
X$`09 Else
X$`09 ownprot = "OWNER"
X$`09 Endif
X$
X$`09 fprot = "/Prot=(" + sysprot + "," -
X`09`09`09 + ownprot + "," -
X`09`09`09 + F$Element(2, ",", p3) + "," -
X`09`09`09 + F$Element(3, ",", p3) + ")"
X$`09Else
X$`09 lastdir = ""
X$`09 n=0
X$ DIRLOOP:
X$`09 thisdir = F$Element (n, ".", p1)
X$`09 If (thisdir .Nes. ".")
X$`09 Then
X$`09 lastdir = "." + thisdir
X$`09 n=n+1
X$`09 Goto DIRLOOP
X$`09 Else
X$`09 If (lastdir .Nes. "")
X$`09 Then
X$`09`09 bclose = F$Extract (F$Length(p1)-1, 1, p1)
X$`09`09 thisdir = lastdir - "." - bclose
X$`09`09 parent = p1 - lastdir + bclose + thisdir + ".DIR;1"
X$`09`09 dirprot = "/Prot=(" + -
X`09`09 F$Edit (F$File_Attributes (parent, "PRO"), "COLLAPSE") -
X`09`09`09`09+ ")"
X$`09 Else
X$`09`09 dirprot = " "
X$`09 Endif
X$`09 Endif
X$`09 fprot = " "
X$`09Endif
X$
X$!
X$`09Set Noon
X$`09Create/Dire/Log'dirprot' 'p2'
X$`09crestat = $Status
X$`09If .Not.crestat
X$`09Then
X$`09Else
X$`09 If crestat .Eq. %X10911293
X$`09 Then
X$`09 Inquire yn "Do you wish to continue? (y/n)"
X$`09 If yn Then Goto OK
X$`09 Else
X$`09 Goto OK
X$`09 Endif
X$`09Endif
X$`09Exit 'crestat'
X$!
X$ OK:
X$`09Write Sys$output " Copying " + p1 + "*.*;* --> " + p2 + "*.*;*"
X$`09Copy 'p1'*.*;*/Exclude=(*.DIR;1,NETSERVER.LOG;*) 'p2'*.*;*'fprot'
X$`09Set On
X$!
X$! Re-establish correct (VMS default) protections on MAIL files.
X$!
X$`09If F$Search("''p2'*.mai;*") .Nes. "" Then -
X`09 Set Prot=(SYSTEM:RW, OWNER:RW, GROUP, WORLD) 'p2'*.MAI;*
X$!
X$ LOOP: next = F$Search(p1+"*.DIR;1")
X$`09If next .Eqs. "" Then Exit 1
X$!
X$`09newprot = F$Edit (F$File_Attributes (next, "PRO"), "COLLAPSE")
X$!
X$`09next = F$Parse(next,,,"NAME")
X$`09input_dir = p1 - "`5D" + "." + next + "`5D"
X$`09output_dir = p2 - "`5D" + "." + next + "`5D"
X$`09@'F$Environment("PROCEDURE") 'input_dir' 'output_dir' 'newprot'
X$`09Goto LOOP
$ call unpack COPYTREE.COM 1080254885 "" 17 1 1
$ v=f$verify(v)
$ exit

0 new messages