TITLE WAKEUP - Wakeup MMailr module for TOPS-20 mailsystem
	SUBTTL Mark Crispin 25 March 1985

; Copyright (c) 1985 Mark Crispin.  All Rights Reserved.

	SEARCH MACSYM,MONSYM	; system definitions
	SALL			; suppress macro expansions
	.DIRECTIVE FLBLST	; sane listings for ASCIZ

A=1				; JSYS, temp AC's
B=2
C=3
D=4

IFNDEF IPCBLN,IPCBLN==20	; length of IPCF buffer

	.PSECT DATA

MYPID:	0			; my IPCF PID

	.ENDPS
	.PSECT CODE

; Send a wakeup call to MMailr
;	CALL $WAKE
; Returns +1: Always

$WAKE::	SAVEAC <A,B,C>
	STKVAR <<IPCBLK,.IPCFP+1>,<IPCBUF,IPCBLN>>
	DO.
	  SKIPE B,MYPID		; have a PID already?
	   TDZA A,A		; yes, use it
	    MOVX A,IP%CPD	; no, create a PID
	  MOVEM A,.IPCFL+IPCBLK
	  MOVEM B,.IPCFS+IPCBLK	; PID to use if one there
	  SETZM .IPCFR+IPCBLK	; send to INFO
	  MOVSI A,.IPCI2+3	; length of INFO msg
	  HRRI A,IPCBUF		; where INFO msg is
	  MOVEM A,.IPCFP+IPCBLK
	  MOVX A,.IPCIW		; return PID associated with name
	  MOVEM A,.IPCI0+IPCBUF
	  SETZM .IPCI1+IPCBUF	; duplicate copy not needed
	  DMOVE A,[ASCII/[SYSTEM]MM/] ; 1st part of PID to look up
	  DMOVEM A,.IPCI2+IPCBUF
	  MOVE A,[ASCII/AILR/]	; 2nd part of PID to look up
	  MOVEM A,.IPCI2+2+IPCBUF
	  MOVX A,.IPCFP+1	; length of block
	  MOVEI B,IPCBLK	; get MMailr's PID
	  MSEND%
	  IFJER.
	    SKIPE MYPID		; had a PID?
	     CAIE A,IPCFX9	; yes, "Sender's PID invalid"?
	      RET		; no PID or some other error, go away
	    SETZM MYPID		; no PID any more
	    LOOP.		; try again, creating a PID this time
	  ENDIF.
	ENDDO.
	MOVE A,.IPCFS+IPCBLK	; get the PID I made
	MOVEM A,MYPID		; remember it for next time
	DO.
	  SETZM .IPCFL+IPCBLK	; no flags
	  SETZM .IPCFS+IPCBLK	; any sender
	  MOVE A,MYPID		; I'm the receiver
	  MOVEM A,.IPCFR+IPCBLK
	  MOVSI A,IPCBLN	; place to put the reply
	  HRRI A,IPCBUF
	  MOVEM A,.IPCFP+IPCBLK
	  MOVX A,.IPCFP+1	; length of block
	  MOVEI B,IPCBLK	; get reply from INFO
	  MRECV%
	   ERJMP R		; failure irrelevant here
	  LOAD A,IP%CFC,.IPCFL+IPCBLK ; see who sent message
	  CAIE A,.IPCCC		; from <SYSTEM>IPCF?
	   CAIN A,.IPCCF	; no, from <SYSTEM>INFO?
	   IFSKP.
	     LOOP.		; no, get another message
	   ENDIF.
	ENDDO.
	JN <IP%CFE,IP%CFM>,.IPCFL+IPCBLK,R ; give up if undeliverable
	SETZM .IPCFL+IPCBLK	; no flags
	MOVE A,MYPID		; I'm the sender
	MOVEM A,.IPCFS+IPCBLK
	MOVE A,.IPCI1+IPCBUF	; MMailr is the recipient
	MOVEM A,.IPCFR+IPCBLK
	MOVSI A,1		; one word from IPCBUF
	HRRI A,IPCBUF
	MOVEM A,.IPCFP+IPCBLK
	MOVX A,'PICKUP'		; magic word to wake up MMailr
	MOVEM A,IPCBUF
	MOVX C,^D20
	DO.
	  MOVX A,.IPCFP+1	; length
	  MOVEI B,IPCBLK	; send wakeup to MMailr
	  MSEND%
	  IFJER.
	    MOVX A,^D1000	; failed, wait a bit
	    DISMS%
	    SOJG C,TOP.		; try a few times
	    RET			; failed, give up
	  ENDIF.
	ENDDO.
	MOVX A,.MUQRY		; query function for MUTIL%
	MOVEM A,IPCBUF
	MOVE A,MYPID		; query packets for our PID
	MOVEM A,1+IPCBUF
	MOVX C,^D20		; number of retries
	DO.
	  MOVX A,.IPCFP+2	; number of words to return
	  MOVEI B,IPCBUF	; argument block in IPCBUF
	  MUTIL%
	  IFJER.
	    MOVX A,^D1000	; wait a bit
	    DISMS%
	    SOJG C,TOP.		; retry a few times
	    RET
	  ENDIF.
	ENDDO.
	DO.
	  SETZM .IPCFL+IPCBLK	; no flags
	  SETZM .IPCFS+IPCBLK	; sender is filled in by monitor
	  MOVE A,MYPID		; I'm the receiver
	  MOVEM A,.IPCFR+IPCBLK
	  MOVSI A,IPCBLN	; where MMailr reply will go
	  HRRI A,IPCBUF
	  MOVEM A,.IPCFP+IPCBLK
	  MOVX A,.IPCFP+1	; size of block
	  MOVEI B,IPCBLK	; get reply from MMailr
	  MRECV%
	   ERJMP .+1		; error uninteresting here
	  IFQN. IP%CFC,.IPCFP+IPCBLK ; get sender code
	    CAIE B,.IPCCF	; from <SYSTEM>INFO
	     CAIN B,.IPCCP	; or private <SYSTEM>INFO?
	      LOOP.		; yes, try for another message
	  ENDIF.
	ENDDO.
	RET

	END