!=====================================================================+ ! ASKOPER - Request an operator reply and place in a symbol | !=====================================================================+ ! Author : Harry Flowers ! ! ASKOPER is a program to ask an operator for a reply to a request. ! If no reply is needed, the DCL command "REQUEST" should be used ! instead. The DCL symbol "OPER_REPLY" is defined as the reply given ! by the operator. ASKOPER has the following qualifiers: ! ! General: ! /[NO]LOG - controls logging of information output as to the message ! and status; /LOG is now the default ! /GLOBAL - causes the symbol "OPER_REPLY" to be defined as a global ! symbol instead of a local symbol ! ! Operator classes: ! /CENTRAL /PRINTER /TAPES /DISKS /DEVICES ! /CARDS /NETWORK /CLUSTER /SECURITY /OPER1 ! /OPER2 /OPER3 /OPER4 /OPER5 /OPER6 ! /OPER7 /OPER8 /OPER9 /OPER10 /OPER11 ! /OPER12 ! ! ASKOPER is defined as a foreign command, as in: ! ! $ ASKOPER == "$dev:[dir]ASKOPER.EXE" ! !====================================================================== ! OPTION TYPE = EXPLICIT EXTERNAL LONG FUNCTION LIB$GET_FOREIGN, & SYS$CREMBX, & SYS$SNDOPR, & SYS$QIOW, & LIB$SET_SYMBOL ! DECLARE STRING COMMAND_LINE, PROMPT_STR, CMD, CRLF, & OPER_REPLY, LONG STAT, TBL_TYPE, & WORD OUT_LEN, MBX_CHAN, MB_IOSB(3%), X, Y, Z, & BYTE LOGGING ! EXTERNAL LONG CONSTANT IO$_READVBLK, & LIB$K_CLI_LOCAL_SYM, & LIB$K_CLI_GLOBAL_SYM ! %INCLUDE "$OPCDEF" %FROM %LIBRARY "SYS$LIBRARY:BASIC$STARLET" %INCLUDE "$OPCMSG" %FROM %LIBRARY "SYS$LIBRARY:BASIC$STARLET" ! ! Map the message buffer for the call to $SNDOPR. ! MAP(RQST_BUFFER) & BYTE RQ_TYPE, & BYTE RQ_TARGET(2%), & LONG RQ_ID, & STRING RQ_TEXT = 255% ! ! Map the message buffer again as a string to allow passing BY DESC. ! MAP(RQST_BUFFER) & STRING REQUEST = 263% ! MAP(RQST_BUFFER) & BYTE DUMMY, & LONG RQ_TARGETL ! ! Map the message buffer for the reply returned in the mailbox. ! MAP(REPLY_BUFFER) & BYTE RP_TYPE, & BYTE RP_RESERVED, & WORD RP_STATUS, & LONG RP_ID, & STRING RP_TEXT = 255% ! ! CRLF = CHR$(13%) + CHR$(10%) PROMPT_STR = "_Operator request: " LOGGING = 1% ! STAT = LIB$GET_FOREIGN(COMMAND_LINE,PROMPT_STR,OUT_LEN,) IF (STAT AND 1%) = 0% THEN CALL LIB$STOP(STAT BY VALUE) \ END IF ! IF OUT_LEN = 0% THEN PRINT "%ASKOPER-F-NOREQ, no request...aborting." CALL LIB$STOP(OUT_LEN BY VALUE) END IF RQ_TARGETL = 0 RQ_TEXT = EDIT$(COMMAND_LINE,4%+8%+16%+128%+256%) TBL_TYPE = LIB$K_CLI_LOCAL_SYM ! ! Start our primitive parse of the command line Y = POS(RQ_TEXT,"/",0%) ! First slash (/) X = POS(RQ_TEXT,'"',0%) ! Find quotes IF (X <> 0%) AND (X < Y) ! If quote before / THEN ! then Z = POS(RQ_TEXT,'"',X+1%) ! check for end quote IF Z > Y ! if it's after /, / is quoted THEN ! so we Y = POS(RQ_TEXT,"/",Z) ! check after the end quote END IF ! end if / is quoted END IF ! end if quote before / WHILE Y <> 0% ! While there are /'s Z = POS(RQ_TEXT,"/",Y+1%) ! Next / after Y X = POS(RQ_TEXT," ",Y+1%) ! Next space after Y IF (Z = 0%) THEN Z = X \ END IF ! If no /, end @ space IF (X <> 0%) AND (X < Z) THEN Z = X \ END IF ! Space before /, end@space Z = LEN(RQ_TEXT) + 1% IF Z = 0% ! No space or slash, end @ end+1 CMD = SEG$(RQ_TEXT,Y+1%,Z-1%) ! Extract command RQ_TEXT = LEFT$(RQ_TEXT,Y-1%) + RIGHT$(RQ_TEXT,Z) SELECT CMD CASE "CEN" TO "CENTRAL" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_CENTRL CASE "PRI" TO "PRINTER" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_PRINT CASE "TAP" TO "TAPES" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_TAPES CASE "DIS" TO "DISKS" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_DISKS CASE "DEV" TO "DEVICES" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_DEVICE CASE "CAR" TO "CARDS" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_CARDS CASE "NET" TO "NETWORK" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_NTWORK CASE "CLU" TO "CLUSTER" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_CLUSTER CASE "SEC" TO "SECURITY" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_SECURITY CASE "REPLY" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_REPLY CASE "SOF" TO "SOFTWARE" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_SOFTWARE CASE "LIC" TO "LICENSE" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_LICENSE CASE "OPER1" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_OPER1 CASE "OPER2" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_OPER2 CASE "OPER3" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_OPER3 CASE "OPER4" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_OPER4 CASE "OPER5" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_OPER5 CASE "OPER6" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_OPER6 CASE "OPER7" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_OPER7 CASE "OPER8" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_OPER8 CASE "OPER9" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_OPER9 CASE "OPER10" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_OPER10 CASE "OPER11" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_OPER11 CASE "OPER12" RQ_TARGETL = RQ_TARGETL OR OPC$M_NM_OPER12 CASE "GLO" TO "GLOBAL" TBL_TYPE = LIB$K_CLI_GLOBAL_SYM CASE "LOG" LOGGING = 1% CASE "NOLOG" LOGGING = 0% CASE ELSE PRINT "%ASKOPER-W-UNK, unknown qualifier: ";CMD END SELECT Y = POS(RQ_TEXT,"/",0%) ! Find remaining /'s X = POS(RQ_TEXT,'"',0%) ! Find quotes IF (X <> 0%) AND (X < Y) ! If quote before / THEN ! then Z = POS(RQ_TEXT,'"',X+1%) ! check for end quote IF Z > Y ! if it's after /, / is quoted THEN ! so we Y = POS(RQ_TEXT,"/",Z) ! check after the end quote END IF ! end if / is quoted END IF ! end if quote before / NEXT ! Y <> 0%; /'s to parse ! ! If no operator class specified, send to central operator IF RQ_TARGETL = 0 THEN RQ_TARGETL = OPC$M_NM_CENTRL \ END IF ! RQ_TYPE = OPC$_RQ_RQST RQ_TEXT = EDIT$(RQ_TEXT,4%+8%+16%+128%+256%) IF LEN(RQ_TEXT) = 0% THEN PRINT "%ASKOPER-F-NOREQ, no request...aborting." CALL LIB$STOP(0%) END IF ! ! Create temporary mailbox for the reply. ! STAT = SYS$CREMBX(,MBX_CHAN,,,,,) IF (STAT AND 1%)=0% THEN CALL LIB$STOP(STAT BY VALUE) \ END IF ! ! Call the SNDOPR service. ! DO_REQUEST: STAT = SYS$SNDOPR(REQUEST,MBX_CHAN BY VALUE) IF (STAT AND 1%)=0% THEN CALL LIB$STOP(STAT BY VALUE) \ END IF IF LOGGING THEN PRINT "%ASKOPER-I-REQ, request sent: ";RQ_TEXT END IF ! ! Issue a read request to the mailbox and wait for reply. ! STAT = SYS$QIOW(,MBX_CHAN BY VALUE,IO$_READVBLK BY VALUE, & MB_IOSB() BY REF,,,RP_TYPE BY REF,255% BY VALUE,,,,) IF (STAT AND 1%)=0% THEN CALL LIB$STOP(STAT BY VALUE) \ END IF IF (RP_STATUS AND 1%)=0% THEN CALL LIB$STOP(RP_STATUS BY VALUE) \ END IF IF RP_STATUS = OPC$_RQSTPEND THEN CALL LIB$SIGNAL(RP_STATUS BY VALUE) GOTO DO_REQUEST END IF IF LOGGING THEN CALL LIB$SIGNAL(RP_STATUS BY VALUE) PRINT "%ASKOPER-I-REPLY, operator reply: " + RP_TEXT END IF OPER_REPLY = LEFT(RP_TEXT,POS(RP_TEXT,CRLF,0%)-1%) OPER_REPLY = EDIT$(OPER_REPLY,4%+8%+16%+32%+128%+256%) ! ! Define the OPER_REPLY symbol. ! STAT = LIB$SET_SYMBOL("OPER_REPLY",OPER_REPLY,TBL_TYPE BY REF) IF (STAT AND 1%)=0% THEN CALL LIB$STOP(STAT BY VALUE) \ END IF END