.; File: MK:[11,45]VD.CMD    Last Edit: 3-OCT-1986 10:16:34 
.;
.; VD.CMD -- mount or dismount virtual disks.
.;
.; This command file will permit a user to mount or dismount a VD by
.; specifying the two letter abbreviation for that disk.  That two letter
.; abbreviation will be used as the pseudodevice assignment for that
.; disk so that the user can subsequently address that disk with that
.; code.
.;
.; Any combination of disks can be mounted and dismounted in the same
.; command line.  Options exist to assign the local SY: to a disk, run
.; a setup command file, and list all defined virtual disks.
.;
.; A master table of virtual disks defines the names and attributes of
.; virtual disks on the system.  The attributes include "available" to
.; indicate disk in on system, "privledged" to indicate the disk is
.; accessible only to privledged users, and "public" to indicate the disk
.; is public mounted at system boot time.  Use of the master table 
.; permits us to have a generic command file driven by a table that can
.; be edited as desired by the system manager.
.;
.;
.;  History:
.;
.; 
.;	JMB  4-JAN-1985 
.;		JMB214 -- check for device spec.
.;
.;	JMB   9-JAN-1985 
.;		JMB219 -- add optional volume name param.
.;			- add undocumented debug switch.
.;
.;	JMB    5-JUN-1985 
.;		 JMB226 -- add table lookup for most params
.;			   add more error detection
.;
.;      PTH    7-Aug-85  
.;               Significant changes - added new pseudodevices,
.;               "?" help, "/DA" debug switch, multiple entry
.;               of pseudodevices, and dismount/dvd of pseudodevices.
.;
.;      PTH    29-Aug-85  Added "*" recognition to indicate SYD psuedodevice
.;
.;      PTH    9-Sep-85  Corrected bug where "@BH" was accepted as "BH"
.;               and not kicked out as unrecognized.  It was in the upper
.;               case conversion part.
.;
.;      PTH    26-Sep-85  Added "#" recognition to indicate that SYD
.;               should be done and chain to xxSETUP.CMD file for setup
.;               of development system assignments, flags, and libraries.
.;
.;      PTH    12-Dec-85  Added subroutine to return current VD info and
.;               availability, making it easier to add and subtract VDs
.;               from the command file.  Added DR as a disk.  Restricted
.;               disk access based on <priv> terminal status.  Centralized
.;               data base for ease of modification.  Search for GETSYM:
.;               for start of data base.
.;
.;      PTH    26-Feb-86.  Moved to MK:[11,45].  RX VD deleted, MK MPLUSKIT
.;               VD added.  References to LB: changed to DR:.
.;
.;      PTH    25-Jul-86.  Modified to use an external table containing
.;               VD information.  This permits easier maintenance for
.;               adding and subtracting VDs, and also makes possible a
.;               generic command file using a site specific data file.
.;               The table will be in LB:[1,5]VDTABLE.TXT.  All references
.;               back to LB: rather than DR:
.;
.;      PTH    1-Oct-86.  Removed deassigns of VS:.  We normally do not
.;               need them, since we use the disk abbreviations instead.
.;               However, at logout, DVD/ALL will use VS: assigments to
.;               DVD any disks that are still around.  So we will now
.;               Leave the VS: assignments as AVD sets them.
.;
.;
.; Syntax --
.;
.;  This command file can be invoked with parameters as follows:
.;
.;	P1 = pseudodevices list (ddnn: for mount, -ddnn: for dismount)
.;        
.;    the switch /DA can be appended to the pseudodevice list to obtain
.;      debug dumps before execution of commands.
.;
.;    the switch /LI can be used to get a list of all available virtual
.;      disk codes (two letter codes).  It can be appended to a devicelist
.;      or more commonly, just used alone.
.;
.;
.;
.; Action - setting up a VD
.;
.;	The equivalent of
.; >AVD filespec/VM
.; >ASN vm:=ddnn:/login
.; >ASN =vm:/login
.; >MOU ddnn:volumeid
.;
.; Action - taking down a VD
.;
.; >DMO ddnn:
.; >DVD ddnn:
.; >ASN =ddnn:/login
.;
.; If p1 parameter (pseudodevice) present -
.;
.; Lookup pseudodevices in table, get params from it, then as above.
.; Multiple pseudodevices can be strung together, separating with
.; commas, including dismount (ie -HZ) devices.  This allows us to
.; mount or dismount more than one device, or dismount 
.; and mount devices at the same time.  
.;
.enable substitution
.; 
.; if current user is non-privileged, we make the pseudodevice
.; assignment local, so he can get rid of it, else make it
.; login
	
	.sets lsw ""
	.ift <PRIVIL> .sets lsw "/login"

.; see if parmeters were input, if not, the operator will get help
.; special parameters are "?" for help.  We also recognize /HE for help.
.; We do not, however, recognize HE for help, since HE could be a valid
.; virtual disk abbreviation.
.;
	.if p1 eq "" .goto help
	.if p1 eq "?" .goto help
	.if p1 eq "/HE" .goto help
	.goto proces
.help:
;
; This command file will allocate, mount, and assign a pseudodevice name to 
; the virtual disk of your choice.  It can also dismount, deallocate
; and deassign a pseudodevice of the virtual disk of your choice.
; You may mount and dismount at the same time if desired.
;
; During this process you may indicate a virtual disk for your SY:
; default disk.  Likewise, you may execute a setup command file on that disk
; if you are going to do application work on that disk.
;
; All available virtual disks are assigned a two character code for
; reference and as use for the psuedodevice name.  The list of these
; codes can be obtained using the "/LI" switch, either alone or 
; with a device list.  For example, typing "@VD /LI" will give
; you a list with no other action.
;
; Pseudodevice VM: is used and deassigned, remaining free for further
; uses.  For this reason, do not psuedodevice VM: in any of your work.
; 
; If a "-" minus sign precedes the two letter code, the disk associated
; with that code will be dismounted and deallocated.  Likewise, the
; psuedodevice name will be eliminated.
;
; If a "*" asterisk precedes a pseudodevice, the SYD command will be
; performed after allocation and mounting of the disk, to assign SY: 
; to that disk, making it your default system device.  If an asterisk 
; appears for more than one disk, the SY: will wind up assigned to 
; the last disk in the list for which it occurs.
;
; If a "#" pound sign precedes a pseudodevice, the action will be the
; same as the "*" asterisk, plus, we will chain to the xxSETUP.CMD
; command file on that disk.  If the SETUP command file is not found,
; it will be ignored and the command file action will be just like the
; "*" asterisk function.
;
; The following command syntax is used:
;      >@VD devlist
;
; Devlist is list of disk codes (xx to mount, -xx to dismount),
; separated by commas ( [-]xx,[-]xx,[-]xx...[/sw...] where xx is two 
; character disk code, and sw is a switch name.)  
; The switch /DA can be appended to the devlist parameter for debug messages.
; A "?" for devlist will give you help.  A "/LI" switch 
; appended to to devlist will give you a list of available virtual disks.
;
; example: 
;   >@vd hz,-tb,-cb,*gl,fb,sm
;
; Disks HZ, GL, SM are mounted, TB and CB as dismounted.
; SY: is assigned to GL:.
;
;
.; we exit with warning status of 2, since no commands were performed.
	.goto warnnd

.proces:

.; Make sure the VD table file is accessible

	.testfile lb:[1,5]vdtable.txt
	.if <filerr> eq 1 .goto tblok
; 
; UNABLE TO ACCESS VD TABLE.  SEE SYSTEM MANAGER.
;
	.goto warnnd
.;
.tblok:
.;
.; Command string is assembled in P1.  Process it.
.;
	.setf debug
	.setf dolist
	.test p1 "/"
	.if <strlen> eq 0 .goto strip		!branch if no switches
.; see if debug desired
	.test p1 "/DA"
	.if <strlen> ne 0 .sett debug
	.test p1 "/da"
	.if <strlen> ne 0 .sett debug
.; see if VD list desired
	.test p1 "/LI"
	.if <strlen> ne 0 .sett dolist
	.test p1 "/li"
	.if <strlen> ne 0 .sett dolist
	.ift debug .goto strip			!branch if valid DA switch
	.ift dolist .goto list			!branch if valid LI switch
.;
.; switch was present, but not recognized.  Abort execution and tell 
.;   operator
;
; Unrecognized switch used in command line.  Type "@VD ?" for help with
;    command line syntax.
;
	.goto errnd
.;
.;
.list:
.; get a list of available VD names.  Read them from the VD table file.
.;
.lstgo:
	.openr lb:[1,5]vdtable.txt
	.ift <eof> .goto lstend
.lstnxt:
	.read buffer
	.ift <eof> .goto lstend
	.sets first buffer[1.:1.]
.; leading % means end of table data before eof
	.if first eq "%" .goto lstend
.; ignore lines beginning with semi-colon (comment)
	.if first eq ";" .goto lstnxt
.; break out disk information - note that we use fixed position for 
.;  information.
	.sets vdname buffer[2.:3.]
	.sets desc buffer[5.:24.]
	.sets file buffer[26.:55.]
	.parse file " " file dummy
	.sets volid buffer[57.:68.]
	.setf pubdev
	.sets bool buffer[70.:70.]
	.if bool eq "X" .sett pubdev
	.if bool eq "x" .sett pubdev
	.setf prvdev
	.sets bool buffer[72.:72.]
	.if bool eq "X" .sett prvdev
	.if bool eq "x" .sett prvdev
	.setf avldev
	.sets bool buffer[74.:74.]
	.if bool eq "X" .sett avldev
	.if bool eq "x" .sett avldev
.; non privledged users cannot access privledged disks
	.iff <privil> .ift prvdev .goto lstnxt
.;
.; LOADED will indicate that the disk container file is on the system
.; and available to the users.
.ift avldev ; (loaded)     'vdname' = 'desc'
.iff avldev ; (not loaded) 'vdname' = 'desc'
	.goto lstnxt
.lstend:
	.close
;
.; Process the parameters and execute them
.;
.strip:
	.parse p1 "/" p1hold junk		!strip off switches

.real:
.; execute the devices named in p1hold until there are none left

	.parse p1hold "," pseudo tmp
	.sets p1hold tmp
	.if pseudo eq "" .goto realnd

.realvr:
	.test pseudo ":"
	.if <strlen> = 0 .sets pseudo pseudo+":"
.;
.; see if we are to dismount the pseudodevice
	.test pseudo "-"
	.if <strlen> ne 0 .goto dmovd
.;
.; see if we are do assign sy to the pseudodevice
	.setf dosyd
	.test pseudo "*"
	.if <strlen> eq 0 .goto noasn
	.sett dosyd
	.parse pseudo "*" junk pseudo
.noasn:
	.setf doset
	.test pseudo "#"
	.if <strlen> eq 0 .goto noset
	.sett dosyd
	.sett doset
	.parse pseudo "#" junk pseudo
.noset:
.;
.; here, we just have a pseudodevice as input
.; if a known device, fill in file and volid,
.; else go get params from operator

	.parse pseudo ":" dnam junk	! strip colon
.; 
.; ensure that dnam is all upper case:

	.sets lower "abcdefghijklmnopqrstuvwxyz"
	.sets upper "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	.sets tmp ""
	.test dnam
	.setn maxcnt <strlen>
	.setn count 1.
.upper:
	.test lower dnam[count:count]
	.setn pos <strlen>
	.if pos eq 0 .goto u10
	.sets tmp tmp+upper[pos:pos]
	.goto u20
.u10:
	.sets tmp tmp+dnam[count:count]
.u20:
	.inc count
	.if count gt maxcnt .goto u30
	.goto upper
.u30:
.;
.; Get the symbols for the device specified.  This information is in
.; the VD table file.

.devgo:
	.sets vdname ""
	.openr lb:[1,5]vdtable.txt
	.ift <eof> .goto devend
.devnxt:
	.read buffer
	.ift <eof> .goto devend
	.sets first buffer[1.:1.]
.; leading % means end of table data before eof
	.if first eq "%" .goto devend
.; ignore lines beginning with semi-colon (comment)
	.if first eq ";" .goto devnxt
.; break out disk information
	.sets nambuf buffer[2.:3.]
	.if nambuf ne dnam .goto devnxt
	.sets vdname buffer[2.:3.]
	.sets desc buffer[5.:24.]
	.sets file buffer[26.:55.]
	.parse file " " file dummy
	.sets volid buffer[57.:68.]
	.setf pubdev
	.sets bool buffer[70.:70.]
	.if bool eq "X" .sett pubdev
	.if bool eq "x" .sett pubdev
	.setf prvdev
	.sets bool buffer[72.:72.]
	.if bool eq "X" .sett prvdev
	.if bool eq "x" .sett prvdev
	.setf avldev
	.sets bool buffer[74.:74.]
	.if bool eq "X" .sett avldev
	.if bool eq "x" .sett avldev
.devend:
	.close

.;  If VDNAME comes back blank (null),
.;  then we know that its not an available or valid VD.
	.if vdname eq "" .goto badvd

.; non privledged users cannot access privledged disks
	.iff <privil> .ift prvdev .goto badvd

.; can only access available devices
	.iff avldev .goto outvd	
	.goto goodvd

.badvd:
;
; Virtual disk 'dnam' not valid or not accessible.  Type "@VD /LI" for 
;   list of accessible virtual disks, or "@VD ?" for help.  Name 'dnam' ignored.
;
	.goto rerr
.;
.outvd:
;
; Virtual disk 'dnam' not loaded on system.  See system manager to have
;    disk loaded from tape.  Type "@VD /LI" for list of loaded disks.
;
	.goto rerr
.;
.;
.goodvd:
.; now do the mount or dismount
.; dump current setup if debug mode is on
.;
	.iff debug .goto nobug
;
; debug dump -- ready to allocate and mount
;	file='file'
;	lsw='lsw'
;	p1hold='p1hold'
;	pseudo='pseudo'
;	volid='volid'
.ift pubdev ;	pubdev=T
.iff pubdev ;	pubdev=F
.ift prvdev ;	prvdev=T
.iff prvdev ;	prvdev=F
.ift avldev ;	avldev=T
.iff avldev ;	avldev=F
;	dnam='dnam'
	.ask go do it
	.iff go .goto real

.nobug:
.; AVD only in not public device, which is thus already AVDed and PUB mounted
	.iff pubdev .goto r103
	.goto r201

.;
.r103:
	AVD 'file'/VM
	.if <exstat> = 1 .goto r100
;
; Avd Error
;
	.goto rerr
.r100:
.; We use device VM: to tell which device to associate with the 
.;   disk abbreviation (2 letter code)
	ASN vm:='pseudo''lsw'
	.if <exstat> = 1 .goto r200
.r101:
;
;Assign Error!
; Beware hanging "VM" assignment!
;
	.goto rerr
.r200:
	ASN =vm:
	.if <exstat> <> 1 .goto r101
	MOU 'pseudo''volid'
	.if <exstat> <> 1 .goto r102
.r201:
	.ift dosyd SYD 'pseudo'
	.sets setid pseudo[1:2]
;
; Virtual disk 'dnam' ('desc') is now mounted and available.
.ift pubdev ;   This disk was already public, no futher action required.
.ift dosyd ;   You default disk (SY:) will be this disk 'dnam':
;
;
	.parse file "[]" dummy ufd dummy
	.iff doset .goto r202
	.testfile ['ufd']'setid'SETUP.CMD
	.if <filerr> eq 1 .goto r203
;
;  No Setup command file (['ufd']'setid'SETUP.CMD) found.  Ignored.
;
	.goto r202
.r203:
;   The setup command file will now be run.
	@['ufd']'setid'SETUP
.r202:
	.goto real

.r102:
;
; Mount Error!
; Beware - disk is assigned, pseudodevice is assigned, no mount.
;

.rerr:
	.asks act enter [C]ontinue to next, e[X]it, [R]epeat same dev
	.sets tmp act[1:1]
	.if tmp = "C" .goto real
	.if tmp = "c" .goto real
	.if tmp = "x" .goto errnd
	.if tmp = "X" .goto errnd
	.if tmp = "R" .goto realvr
	.if tmp = "r" .goto realvr
	.goto rerr


.dmovd:
	.parse pseudo "-" junk dnam 	! strip minus
	.parse dnam ":" dnam junk	! strip colon

.; get symbols for device DNAM, VDNAME comes back blank (null) if
.;   DNAM not valid or not available virtual disk
	.sets vdname ""

.zapgo:
	.sets vdname ""
	.openr lb:[1,5]vdtable.txt
	.ift <eof> .goto zapend
.zapnxt:
	.read buffer
	.ift <eof> .goto zapend
	.sets first buffer[1.:1.]

.; leading % means end of table data before eof
	.if first eq "%" .goto zapend

.; ignore lines beginning with semi-colon (comment)
	.if first eq ";" .goto zapnxt

.; break out disk information
	.sets nambuf buffer[2.:3.]
	.if nambuf ne dnam .goto zapnxt
	.sets vdname buffer[2.:3.]
	.setf pubdev
	.sets bool buffer[70.:70.]
	.if bool eq "X" .sett pubdev
	.if bool eq "x" .sett pubdev
	.setf prvdev
	.sets bool buffer[72.:72.]
	.if bool eq "X" .sett prvdev
	.if bool eq "x" .sett prvdev
	.setf avldev
	.sets bool buffer[74.:74.]
	.if bool eq "X" .sett avldev
	.if bool eq "x" .sett avldev
	.iff avldev .sets vdname ""
.zapend:
	.close

	.if vdname ne "" .goto d104
.;
.; invalid device or not available, slap hands...
;
; Virtual disk 'dnam' invalid or not available.  Type "@VD /LI" for list
;    of available disks, or "@VD ?" for help.
;
	.goto derr
.;
.d104:
.;
.; dump current setup if debug mode is on
.;
	.iff debug .goto nodbg
;
; debug dump -- ready to dismount and deallocate
;	lsw='lsw'
;	p1hold='p1hold'
;	pseudo='pseudo'
;	volid='volid'
.ift pubdev ;	pubdev=T
.iff pubdev ;	pubdev=F
.ift prvdev ;	prvdev=T
.iff prvdev ;	prvdev=F
.ift avldev ;	avldev=T
.iff avldev ;	avldev=F
;	dnam='dnam'
	.ask go do it
	.iff go .goto real

.nodbg:
;
;
	.iff pubdev .goto d103
;
; Virtual disk 'dnam' is public mounted, so no deallocate needed
;
	.goto d105
.d103:
	dmo 'dnam':
	.if <exstat> eq 1 .goto d100
.; dismounted prior to this, dismounted by another, or public mounted.
.; in any case, its okay.
.d100:
	dvd 'dnam':
	.if <exstat> eq 1 .goto d101
.; not able to dvd, someone else has disk allocated also, we need to
.; get rid of the pseudodevice assignment, but we have no way of knowing
.; which VSx it is.
;
;Deallocation warning - probably someone else is also on the disk
;
.d101:
	asn ='dnam':'lsw'
	.if <exstat> eq 1 .goto d102
;
;Assign Error!
;
	.goto derr
.d102:
;
; Virtual disk 'dnam' dismounted.  Reassign default device (SY:) if needed.
;
.d105:
	.goto real
.derr:
	.asks act enter [C]ontinue to next, e[X]it, [R]epeat same dev
	.sets tmp act[1:1]
	.if tmp = "C" .goto real
	.if tmp = "c" .goto real
	.if tmp = "x" .goto errnd
	.if tmp = "X" .goto errnd
	.if tmp = "R" .goto realvr
	.if tmp = "r" .goto realvr
	.goto derr


.realnd: 
	.exit 1
.;
.warnnd:
	.exit 2
.;
.errnd:
	.exit 4


