	! Program: ASKOPER
	! Author : Harry Flowers
	! Description: Makes an operator request and waits for a reply.
	!	The reply is then stored in a symbol.  It is intended
	!	for operator interaction with batch jobs.
	!
	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 = 120%
	!
	! Map the message buffer again as a string to allow passing BY DESC.
	!
	MAP(RQST_BUFFER)			&
		STRING REQUEST = 128%
	!
	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
