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