;************************************************************************** ; NETSPEC UTILITY ; ; ; ; 1.0 FUNCTION ; ; The NETSPEC utility creates logical names for the node ; field of a file specification used in DECnet file transfers ; (i.e SIVAX1"username password"::). This function is ; equivalent to the following DCL command: ; ; ASSIGN "node""username password""::" logical_name ; ; The logical name created is the last 4 characters of the node name. ; The advantages of using NETSPEC are: ; ; 1. Less input required. NETSPEC expects only the node name and ; password to be input. Switches (described below) can be used to make logical ; name assignments for all nodes with a single command. ; ; 2. Security. NETSPEC reads the password without echoing it. ; ; ; ; 2.0 FORMAT ; ; ; $ NETSPEC [node1 node2..] [/ALL/SAMEPASSWORD] ; $_Password at node: ; $_Verification: ; ; Switches: /ALL - Define logical names for all nodes ; /SAMEPASSWORD - Use same password at all nodes ; ;*************************************************************************** ;***************************************************************************** ; ; CONSTANT DECLARATIONS ; ;***************************************************************************** $TPADEF ; PARAMETER BLOCK OFFSETS FOR LIB$TPARSE $JPIDEF ; DEFINE $GETJPI ITEM CODES MAXNODES == 20 MAXCHARS == 20 COMLEN=160 ; LENGTH OF FOREIGN COMMAND LINE PASBUFMAX=80 ; LENGTH OF PASSWORD INPUT BUFFER VERBUFMAX=80 ; LENGTH OF VERIFICATION INPUT BUFFER OFFSET=16 ; OFFSET INTO LONG PASSWORD PROMPT FOR NODE ;*************************************************************************** ; ; DATA DECLARATIONS ; ;*************************************************************************** PARSE_ARGS: ; PARAMETER BLOCK FOR LIB$TPARSE .LONG TPA$K_COUNT0 ; LENGTH IN LONGWORDS OF BLOCK .LONG TPA$M_ABBREV ; ALLOW ABBREVIATION .BLKB TPA$K_LENGTH0-8 USERDESC:: .LONG 0 ; DESCRIPTOR FOR USERNAME .LONG 0 COMDESC: .WORD COMLEN,0 ; DESCRIPTOR FOR COMMAND LINE .LONG COMLINE COMLINE: .BLKB COMLEN ; COMMAND LINE BUFFER NODES: .ASCID /$_Nodes: / ; DESCRIPTOR FOR NODES PROMPT PARSERR: .ASCID /Syntax error or node not currently reachable./ ERRORMSG: .ASCID /Not enough input/ LOGMSG: .LONG LOGEND-LOGST .LONG LOGST LOGST: .ASCII /The new logical name is / LOGNAM: .BLKB 4 LOGEND: SHORTPROMPT: .ASCID <^O15><^O12>/$_Password: / ; PROMPT FOR PASSWORD AT ALL NODES LONGPROMPT: .ASCID <^O15><^O12>/$_Password at : / ; PROMPT FOR PASSWORD ; AT A SINGLE NODE VERPROMPT: .ASCID <^O15><^O12>/$_Verification: / ; VERIFICATION PROMPT NODENAMES:: .BLKB MAXNODES*MAXCHARS ; TABLE OF NODE NAMES ; BUILT BY FINDNODES PASSBUFFER: .BLKB PASBUFMAX ; PASSWORD INPUT BUFFER VERBUFFER: .BLKB VERBUFMAX ; VERIFICATION INPUT BUFFER PASDESC: .LONG 0 ; DESCRIPTOR FOR PASSWORD .LONG PASSBUFFER EQUIVNAME: .LONG 0 ; DESCRIPTOR FOR EQUIVALENCE NAME .LONG EQUIVBUFFER EQUIVBUFFER: .BLKB 63 ; EQUIV NAME BUFFER LOGNAME: .WORD 4,0 ; DESCRIPTOR FOR LOGICAL NAME .LONG 0 NODEMASK:: .LONG 0 ; ITEM LIST FOR $GETJPI ITEMS: .WORD 12 ; SIZE OF USERNAME BUFFER .WORD JPI$_USERNAME ; USERNAME ITEM CODE IUSERBUF: .LONG 0 ; ADDR OF USERNAME BUFFER .LONG USERSIZE ; ADDR TO RETURN USERNAME LENGTH .LONG 0 ; END OF LIST USERSIZE: .LONG 0 ; LOCAL TERMINAL DESCRIPTOR AND CHANNEL NUMBER STORAGE TT_DESC: .ASCID /SYS$INPUT/ ; LOGICAL NAME OF TERMINAL DEV_DESC: PHYS_NAME_LEN: .LONG 63 PHYS_NAME_ADR: .LONG PHYS_NAME PHYS_NAME: .BLKB 63 TT_CHAN: .BLKW 1 TTIOSB: .BLKL 2 ; IO STATUS BLOCK ;************************************************************************* ; ; READ MACRO - READ FROM INPUT CHANNEL WITH NO ECHO ; ; ; SIDE AFFECTS - USES R0,R1,R7,R11,RX ; ;********************************************************************** .MACRO READ_NOECHO BUFFER,BUFLEN,RX MOVZWL (RX),R11 ; LENGTH OF STRING MOVL 4(RX),R7 ; ADDR OF STRING $QIOW_S CHAN=TT_CHAN,- FUNC=#IO$_READPROMPT!IO$M_NOECHO,- IOSB=TTIOSB,- P1=BUFFER,- P2=#BUFLEN,- P5=R7,- P6=R11 .ENDM READ_NOECHO ;**************************************************************************** ; ; NETSPEC - MAIN PROGRAM ; ;**************************************************************************** .ENTRY NETSPEC,^M<> ; TRANSLATE LOGICAL NAME FOR SYS$INPUT AND ASSIGN A CHANNEL $TRNLOG_S- ; GET TERMINAL'S PHYSICAL DEVICE NAME LOGNAM=TT_DESC,- RSLLEN=PHYS_NAME_LEN,- RSLBUF=DEV_DESC CMPB PHYS_NAME,#^X1B ; DOES NAME START WITH ESCAPE? BNEQ 1$ ; NOPE SUBL #4,PHYS_NAME_LEN ; YUP, STRIP 1ST 4 CHARS ADDL #4,PHYS_NAME_ADR 1$: $ASSIGN_S - ; OPEN THE CHANNEL DEVNAM=DEV_DESC,- CHAN=TT_CHAN BLBS R0,5$ ; BRANCH IF ERROR RET ; CALL FINDNODES TO BUILD A TABLE OF ALL NODES CURRENTLY REACHABLE ; USED AS A KEYWORD TABLE BY PARSING ACTION ROUTINE 5$: CALLS #0,FINDNODES BLBS R0,10$ RET ; CALL LIB$GET_FOREIGN TO GET REST OF COMMAND LINE AFTER "NETSPEC" 10$: PUSHAW PARSE_ARGS+TPA$L_STRINGCNT ; GET BACK NUMBER OF CHARS PUSHL #0 PUSHAL COMDESC ; STRING DESC TO RECEIVE COMMAND CALLS #3,G^LIB$GET_FOREIGN BLBS R0,15$ RET ; IF WE DIDN'T FIND ANYTHING, GET IT OURSELVES 15$: MOVAL COMLINE,PARSE_ARGS+TPA$L_STRINGPTR TSTW PARSE_ARGS+TPA$L_STRINGCNT BNEQ 25$ MOVZWL NODES,R1 $QIOW_S CHAN=TT_CHAN,- FUNC=#IO$_READPROMPT,- IOSB=TTIOSB,- P1=COMLINE,- P2=#COMLEN,- P5=NODES+4,- P6=R1 BLBS R0,20$ RET 20$: MOVZWL TTIOSB+2,PARSE_ARGS+TPA$L_STRINGCNT BNEQ 23$ PUSHAL ERRORMSG CALLS #1,G^LIB$PUT_OUTPUT RET 23$: MOVZWL TTIOSB+2,COMDESC PUSHAL COMDESC PUSHAL PARSE_ARGS+TPA$L_STRINGCNT CALLS #2,G^STR$UPCASE ; CALL LIB$TPARSE TO PARSE COMMAND LINE 25$: PUSHAL PARSE_KEY PUSHAL PARSE_STATE PUSHAL PARSE_ARGS CALLS #3,G^LIB$TPARSE BLBS R0,30$ PUSHAL PARSERR CALLS #1,G^LIB$PUT_OUTPUT RET 30$: BBC #31,NODEMASK,100$ ; BRANCH IF WE MUST GET A DIFFERENT ; PASSWORD FOR EACH NODE ; "/SAMEPASSWORD" PROCESSING ; USE SAME PASSWORD FOR ALL SPECIFIED NODES CALLS #0,GETPASSWORD ; READ AND VERIFY PASSWORD BLBC R0,99$ ; EXIT IF ERROR ; DO THE ASSIGNMENT FOR ALL SPECIFIED NODES IN NODEMASK CLRL R9 ; R9 = CURRENT BIT IN NODE MASK 50$: BBC R9,NODEMASK,60$ ; KEEP GOING IF NODE NOT INDICATED IN BIT MASK CALLS #0,ASSIGN ; BUILD THE EQUIVALENCE STRING AND DO ASSIGNMENT BLBC R0,99$ ; EXIT IF ERROR 60$: INCL R9 CMPL #MAXNODES,R9 ; DONE? BNEQ 50$ ; BRANCH IF NOPE JMP 98$ ; GET A DIFFERENT PASSWORD AND DO ASSIGNMENT FOR EACH NODE SPECIFIED ; IN THE MASK 100$: CLRL R9 ; R9 = CURRENT BIT IN NODE MASK MOVAL NODENAMES+1,R8 ; R8 = ADDRRESS OF CURRENT NODE STRING 110$: BBC R9,NODEMASK,120$ ; SKIP THIS NODE IF BIT NOT SET ; BUILD THE PROMPT STRING MOVAL LONGPROMPT+8+OFFSET,R7 MOVC3 #6,(R8),(R7) CALLS #0,GETPASSWORD ; READ AND VERIFY PASSWORD BLBC R0,99$ CALLS #0,ASSIGN ; BUILD EQUIV. NAME AND MAKE ASSIGNMENT BLBC R0,99$ 120$: INCL R9 ADDL2 #MAXCHARS,R8 ; POINT TO NEXT NODE NAME CMPL #MAXNODES,R9 ; DONE? BNEQ 110$ ; BRANCH IF NO 98$: MOVL #1,R0 ; SUCCESSFUL COMPLETION 99$: RET ;***************************************************************************** ; ; GETPASSWORD - READ AND VERIFY PASSWORD ; ; INPUTS: NODEMASK = BIT MASK OF ALL NODES FOR WHICH ; ASSIGNMENTS MUST BE MADE ; OUTPUTS: ; PASDESC = PASSWORD DESCRIPTOR ; ;**************************************************************************** .ENTRY GETPASSWORD,^M<> 10$: MOVAL SHORTPROMPT,R10 BBS #31,NODEMASK,20$ ; IF SAME PASSWORD FOR ALL NODES ; USE SHORT PROMPT MOVAL LONGPROMPT,R10 ; ELSE PUT NODE IN THE PROMPT 20$: READ_NOECHO PASSBUFFER,PASBUFMAX,R10 ; READ PASSWORD BLBC R0,30$ MOVZWL TTIOSB+2,PASDESC ; SAVE LENGTH MOVAL VERPROMPT,R10 READ_NOECHO VERBUFFER,VERBUFMAX,R10 ; READ VERIFICATION BLBC R0,30$ MOVZWL TTIOSB+2,R0 CMPC5 PASDESC,PASSBUFFER,#^A/ /,R0,VERBUFFER ; COMPARE THEM BEQL 25$ ; MATCH, EXIT JMP 10$ 25$: MOVL #1,R0 ; SUCCESSFUL COMPLETION 30$: RET ;***************************************************************************** ; ; ASSIGN - BUILD EQUIVALENCE NAME AND ASSIGN A LOGICAL NAME ; ; INPUTS: R9 = NODE INDEX ; PASDESC = DESCRIPTOR FOR PASSWORD STRING ; ; OUTPUTS: A LOGICAL NAME WILL BE INSERTED INTO THE PROCESS ; LOGICAL NAME TABLE AS IF THE FOLLOWING DCL COMMAND ; HAD BEEN ENTERED: ; ; ASSIGN "node""username password""::" logname ; ;***************************************************************************** .ENTRY ASSIGN,^M<> MOVAL EQUIVBUFFER,R3 ; FIND NODE NAME MULL3 #MAXCHARS,R9,R6 ; GET INDEX INTO NODENAME TABLE ADDL2 #NODENAMES+1,R6 MOVC3 #6,(R6),(R3) ; MOVE NODE NAME TO EQUIV BUFFER CMPB #^A/M/,(R6) ; IS NODE = MORDOR? BEQL 5$ ; BRANCH IF YES INCL R6 ; SKIP PAST "SI" IN NODE NAME INCL R6 ; REMAINDER IS LOGICAL NAME 5$: MOVL R6,LOGNAME+4 ; MOVE ADDR OF LOG NAME TO DESCRIPTOR MOVL (R6),LOGNAM ; BUILD REMAINDER OF EQUIVALENCE NAME MOVB #^A/"/,(R3)+ ; INSERT " ; TEST TO SEE COMMAND CONTAINED USERNAME BITL #USER,NODEMASK BEQL 7$ MOVL USERDESC,R1 MOVL USERDESC+4,R2 6$: MOVC3 R1,(R2),(R3) BRB 10$ ; CALL $GETJPI SYSTEM SERVICE TO GET USERNAME OF CURRENT PROCESS 7$: MOVL R3,IUSERBUF $GETJPI_S ITMLST=ITEMS BLBC R0,99$ ADDL2 USERSIZE,R3 ; MOVE PAST USERNAME IN BUFFER 10$: MOVB #^A/ /,(R3)+ ; INSERT A SPACE MOVZWL PASDESC,R1 ; LENGTH OF STRING MOVL PASDESC+4,R2 ; ADDRESS OF STRING MOVC3 R1,(R2),(R3) ; MOVE PASSWORD TO EQUIVBUFFER MOVL #^A/":: /,(R3)+ ; INSERT ":: SUBL2 #EQUIVBUFFER,R3 ; COMPUTE LENGTH OF STRING MOVL R3,EQUIVNAME ; change mode to exec and create the logical name in supervisor mode ; so it doesn't go away when we do $CMEXEC_S CRELOG BLBC R0,99$ PUSHAL LOGMSG CALLS #1,G^LIB$PUT_OUTPUT 99$: ASNRET: RET CRELOG: .WORD 0 $CRELOG_S TBLFLG=#2,LOGNAM=LOGNAME,EQLNAM=EQUIVNAME,ACMODE=#2 RET .END NETSPEC