Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_SRC_3_19910112
-
mm-dom/sndmsg.dif
There are no other files named sndmsg.dif in the archive.
; SNDMSG.MAC.1 & <MM>SNDMSG.MAC.1 20-Apr-88 1449 PAGE 1
LINE 1, PAGE 1
1) TITLE SNDMSG - Routines to send local and network TTY messages
1) SUBTTL David Eppstein/DE/KSL/MRC/WHP4
1)
1) SEARCH MONSYM,MACSYM,SNDDEF
1) EXTERN $WAKE
1) EXTERN $GTLCL,$RMREL
1) ASUPPRESS
1) SALL
1) IFNDEF OT%822,OT%822==:1
1) ^L
1) ; Definitions and Storage
1)
1) A=:1 ;Temporary AC's for JSYS use etc
1) B=:2
1) C=:3
1) D=:4
1)
LINE 1, PAGE 1
2) ;[SRI-NIC]SRC:<MM>SNDMSG.MAC.17, 13-Aug-85 13:01:00, Edit by IAN
2) ;[NIC001] Add header line to outgoing Internet message bodies
2)
2) TITLE SNDMSG - Routines to send local and network TTY messages
2) SUBTTL David Eppstein / Stanford University / 22 April 1983
2)
2) ;; Taken from SEND.MAC, written March 1981 by Kirk Lougheed
2) ;;
2) ;; Judy Anderson of HP and Ken Olum of FLAIR wrote the Chaos support.
2) ;; Frank Fujimoto and David Eppstein, both of Stanford, wrote
2) ;; the TCP/SMTP support. David Eppstein wrote the Pup Ethernet code.
2) ;; Mark Crispin rewrote the TCP/SMTP support to use the JFN interface.
2)
2) SEARCH MONSYM,MACSYM,SNDDEF
2) EXTERN $GTPRO,$GTHNS,$PUPNS,$CHSNS,$RMREL
2) ASUPPRESS
2) SALL
2) ^L
2) ; Definitions and Storage
2)
2) A=1 ;Temporary AC's for JSYS use etc
2) B=2
2) C=3
2) D=4
2)
; SNDMSG.MAC.1 & <MM>SNDMSG.MAC.1 20-Apr-88 1449 PAGE 2
LINE 12, PAGE 2
1) FP=:15 ;TRVAR frame pointer
1) CX=:16 ;Scratch for MACREL
1) P=:17 ;Main stack pointer
1)
1) BUFLEN==MAXCHR/5 ;Length of command buffers (for long msgs)
1) PDLEN==100 ;Length of pushdown stack
LINE 12, PAGE 2
2) FP=15 ;TRVAR frame pointer
2) CX=16 ;Scratch for MACREL
2) P=17 ;Main stack pointer
2)
2) BUFLEN==600 ;Length of command buffers (for long msgs)
2) PDLEN==100 ;Length of pushdown stack
LINE 11, PAGE 3
1) .PSECT CODE ;Rest of this file is pure code
LINE 11, PAGE 3
2)
2) .PSECT DATA ;Uninitialized unpaged data
2)
2) NBFLEN==100
2) NETBUF: BLOCK NBFLEN ;Used to build "filename" for ICP etc
2)
2) NETUSR: BLOCK 20 ;Foreign username
2) NETADR: BLOCK 20 ;Foreign site name
2) NETJFN: BLOCK 1 ;JFN for net
2)
2) .ENDPS
2)
2) .PSECT CODE ;Rest of this file is pure code
LINE 9, PAGE 4
1) ; +2/Success, A, B, and C changed
1) ;
LINE 9, PAGE 4
2) ; +2/Success, A/updated pointer, B/0, C/unchanged
2) ;
; SNDMSG.MAC.1 & <MM>SNDMSG.MAC.1 20-Apr-88 1449 PAGE 3
LINE 45, PAGE 4
1) TRVAR <MSPTR,QUEJFN> ;Make some pseudo-globals
1) SETZM QUEJFN ;So nobody thinks random crud is a JFN
1) MKPTR (A) ;Turn into a byte pointer
LINE 45, PAGE 4
2) TRVAR <MSPTR,MSEPTR> ;Place to save message pointer and end of it
2) MKPTR (A) ;Turn into a byte pointer
LINE 63, PAGE 4
1) CALL MQUEUE ;Failed, queue net sends
1) MOVE B,ADR ;Get address block back
1) RET ;And return failure
1) ENDIF.
1) ENDDO.
1) CALL MQUEUE ;Done, finish queueing net sends
1) MOVE A,MSPTR ;Get message text pointer again
1) MOVE B,ADR ;Get final value in ADR (should be 0)
LINE 62, PAGE 4
2) MOVE B,ADR ;Failed, get address block back
2) RET ;And return failure
2) ENDIF.
2) ENDDO.
2) SETO A, ;Get -1
2) ADJBP A,MSEPTR ;So we can point to null at end of message
2) MOVE B,ADR ;Get final value in ADR (should be 0)
LINE 2, PAGE 5
1) ; Finish queueing net sends
1)
1) MQUEUE: SAVEAC <A,B,C> ;Don't mung error code or whatever
1) SKIPN QUEJFN ;Are we queueing anything?
1) RET ;No, done already
1)
1) ;; Finish creating the queued mail file
1) HRROI A,BUFFER ;Get buffer back
1) FMSG <^L
1) Date: > ;Yes, start text
1) SETO B,
1) MOVX C,OT%DAY!OT%SPA!OT%TMZ!OT%SCL!OT%822 ; RFC 822 standard date/time
1) ODTIM%
1) FMSG <
1) From: >
1) CALL .DIRST ;Put in my username
1) FMSG <@>
1) PUSH P,A
1) CALL $GTLCL ;Local host name
1) IFNSK.
; SNDMSG.MAC.1 & <MM>SNDMSG.MAC.1 20-Apr-88 1449 PAGE 4
1) POP P,A
1) RETSTR <Couldn't get local host name>,TTXNET
1) ENDIF.
1) POP P,A
1) CALL $RMREL
1) MOVE A,QUEJFN
1) HRROI B,BUFFER ;Get buffer back
1) SETZ C, ;Until null
1) SOUT% ;Start making file
1) FMSG <
1)
1) >
1) MOVE B,MSPTR ;Get pointer to message text
1) SETZ C, ;Ending on null
1) SOUT% ;Send it off
1) CLOSF% ;Close the file
1) NOP
1) CALLRET $WAKE ;Wake up MMailr and return
1) ^L
1) ; SNDONE - Send one message
LINE 2, PAGE 5
2) ; SNDONE - Send one message
LINE 4, PAGE 8
1) JSRET: HRROI A,BUFFER+200 ;Use a likely buffer
1) HRLOI B,.FHSLF ;With ourself
LINE 4, PAGE 6
2) JSRET: HRROI A,NETBUF ;Use a likely buffer
2) HRLOI B,.FHSLF ;With ourself
LINE 10, PAGE 8
1) HRROI A,BUFFER+200 ;Now point to the string we made
1) MOVX C,TTXNET ;Random network error (not called from SNDLOC)
LINE 10, PAGE 6
2) HRROI A,NETBUF ;Now point to the string we made
2) MOVX C,TTXNET ;Random network error (not called from SNDLOC)
LINE 43, PAGE 9
1) MOVX A,.PRIOU ;To the terminal
1) MOVE B,ADR ;With current address
LINE 43, PAGE 7
2) MOVEI A,.PRIOU ;To the terminal
2) MOVE B,ADR ;With current address
; SNDMSG.MAC.1 & <MM>SNDMSG.MAC.1 20-Apr-88 1449 PAGE 5
LINE 5, PAGE 11
1) SNDNET: SKIPE A,QUEJFN ;Do we have a queued mail file yet?
1) JRST NETRCP ;Yes, just add recipient
1) HRROI A,BUFFER ;Into a free place
1) HRROI B,[ASCIZ/MAILQ:[--QUEUED-MAIL--].NEW-/]
1) SETZ C,
1) SOUT% ;Start making name
1) PUSH P,A ;Create frame to save string pointer
1) GTAD% ;Now output date/time
1) MOVE B,A
1) MOVE A,(P)
1) MOVEI C,^D8 ;Output in octal
1) NOUT%
1) RETSTR <Couldn't make name for queued mail file>,TTXNET
1) FMSG <-SNDMSG-J>
1) MOVEM A,(P) ;Update saved string pointer
1) GJINF% ;Get my job number
1) POP P,A ;Get string pointer back
1) MOVE B,C ;Get job number in B
1) MOVEI C,^D10 ;Output in octal
1) NOUT%
1) RETSTR <Couldn't make name for queued mail file>,TTXNET
1) FMSG <.-1;P770000> ;Next generation, set protection
1) MOVX A,GJ%SHT!GJ%FOU ;File for output
1) HRROI B,BUFFER ;With nice file name
1) GTJFN% ;Get handle on queue file
1) RETSTR <Couldn't get handle on queued mail file>,TTXNET
1) MOVX B,FLD(7,OF%BSZ)!OF%WR ;Writing
1) OPENF% ;Open it up
1) RETSTR <Couldn't open queued mail file>,TTXNET
1) MOVEM A,QUEJFN ;Save for later
1) HRROI A,BUFFER ;Into buffer space
1) FMSG <^L=DELIVERY-OPTIONS:SEND
1) ^L_> ;This is a send, from someone
1) CALL $GTLCL ;Get local host name
1) RETSTR <Couldn't get local host name>,TTXNET
1) FMSG <
1) > ;CRLF (still in buffer)
1) CALL .DIRST ;And our user name
1) FMSG <
1) > ;Another CRLF
1) MOVE A,QUEJFN ;Get file again
1) HRROI B,BUFFER ;Get buffer back
1) SETZ C, ;Until null
1) SOUT% ;Start making file
1)
1) ; Here with A/QUEJFN, add one recipient to the list in the file
1) NETRCP: MOVEI B,"L"-100 ;Control L
1) BOUT% ;To start another host/recip pair
; SNDMSG.MAC.1 & <MM>SNDMSG.MAC.1 20-Apr-88 1449 PAGE 6
1) HRROI A,BUFFER ;Get a place to buffer user name
1) HRROI B,1(ADR) ;With pointer from address block
1) CALL MOVSTR ;Copy string
1) MOVE A,QUEJFN ;Get JFN back again
1) HRROI B,1(B) ;With next string in block
1) SOUT% ;Send host name first
1) FMSG <
1) > ;Then a CRLF
1) HRROI B,BUFFER ;Then point to user name
1) SETZ C, ;To null
1) SOUT% ;Add user name
1) FMSG <
1) > ;Another CRLF to tie it off
1) RETSKP ;Done for now with the net send
1) ^L
LINE 5, PAGE 9
2) SNDNET: HRROI A,NETUSR ;Into net user string
2) HRROI B,1(ADR) ;With pointer from address block
2) CALL MOVSTR ;Copy string
2) HRROI A,NETADR ;Now into host name
2) HRROI B,1(B) ;With next string in block
2) CALL MOVSTR ;Copy string
2) HRROI A,NETADR ;Point to network site name
2) MOVEI C,NETLST ;Get list of protocols supported
2) CALL $GTPRO ;Look it up
2) RETSTR <Unrecognized host name>,TTXNET
2) HRRZ C,(C) ;Get dispatch routine for protocol
2) CALL (C) ;Go jump to it
2) TRNA ;Non-skip
2) AOS (P) ;Skip
2) SKIPN A,NETJFN ;If server made a JFN, be sure to clean it up
2) IFSKP.
2) TXO A,CO%NRJ ;Yes, close it
2) CLOSF%
2) NOP
2) HRRZ A,NETJFN ;Now flush it
2) RLJFN%
2) NOP
2) SETZM NETJFN ;No more JFN
2) ENDIF.
2) RET
2)
2) ; List of networks we know about. For each network we have a pointer
2) ; to a string for the name of the net and the address of a handler routine.
2) ; The called routine gets a host number in B, should return +2 for success.
2)
2) NETLST: [ASCIZ/TCP/],,DOINT ;TCP/IP Internet (SMTP)
2) [ASCIZ/Chaos/],,DOCHA ;MIT Chaosnet
2) [ASCIZ/Pup/],,DOETH ;Pup Ethernet (MiscService packet protocol)
2) 0
2) ^L
; SNDMSG.MAC.1 & <MM>SNDMSG.MAC.1 20-Apr-88 1449 PAGE 7
2) ; DOINT - Send a message over the Internet
2)
2) DOINT: PUSH P,B ;Save address
2) HRROI A,NETBUF ;a := ptr to net file name str
2) HRROI B,[ASCIZ/TCP:./] ;Build device and default local spec
2) CALL CPYSTR ;Copy string
2) POP P,B ;Destination host number
2) MOVX C,^D8 ;TCP: hosts are in octal
2) NOUT% ;Output to file string
2) RETSTR <Couldn't copy host address>,TTXNET
2) HRROI B,[ASCIZ/-25;CONNECTION:ACTIVE;PERSIST:30/] ;Port 25, quit
2) CALL CPYSTR ; after 30 seconds
2) MOVX A,GJ%SHT ;Short form, restricted
2) HRROI B,NETBUF ;Pointer to file string we made
2) GTJFN% ;Make a JFN on it
2) RETSTR <Couldn't get network connection>,TTXNET
2) MOVEM A,NETJFN ;Save the JFN
2) MOVX B,<<FLD ^D8,OF%BSZ>!<FLD .TCMWH,OF%MOD>!OF%RD!OF%WR>
2) OPENF% ;Open 8 read/write buffered, wait for conn.
2) RETSTR <Couldn't open network connection>,TTXNET
2) CALL INTMSG ;Get initial hello, send the message
2) IFSKP. <AOS (P)> ;On success, set up +2 return
2) PUSH P,A ;Save error string in case of error
2) MOVE A,NETJFN ;Get the JFN for our connection
2) HRROI B,[ASCIZ \QUIT
2) \] ;Say we want to go bye-bye
2) SETZ C, ;Stop on null
2) SOUTR%
2) ERJMP .+1
2) DO.
2) BIN% ;Read any following crud
2) ERJMP ENDLP.
2) LOOP. ;Continue until error
2) ENDDO.
2) POP P,A ;Get error string back
2) MOVEI C,TTXNET ;Get failure code in case we failed
2) RET ;Return success or failure
2) ^L
2) ; GETRSP - listen for responses from the foreign MAISER
2) ; returns +2, with MAISER code in A, text in BUFFER
2) ; if MAISER sends a code .GE. 400, returns +1
2)
2) GETRSP: MOVE A,NETJFN ;A/foreign socket
2) HRROI B,BUFFER ;Into scratch buffer
2) MOVX C,1000*5-1 ;With this many characters
2) CALL SMTNIN ;Read MAISER's response
2) IFSKP.
2) CAIGE B,400 ;Look at number returned
2) RETSKP ;Below 400, return success
2) HRROI A,BUFFER ;Else get error string
2) ENDIF.
; SNDMSG.MAC.1 & <MM>SNDMSG.MAC.1 20-Apr-88 1449 PAGE 8
2) RET ;Return failure
2) ^L
2) ; INTMSG - build the actual message and send it
2)
2) ; If this could possibly go into a user's mailbox we would have to follow
2) ; RFC822 and build message headers. But we use SEND instead of SOML so
2) ; this is merely a terminal message and needs no headers.
2)
2) INTMSG: CALL GETRSP ;Pick up 220 site ident
2) RET
2) HRROI A,BUFFER ;Get a pointer to our output buffer
2) HRROI B,[ASCIZ/HELO /] ;String for hello command
2) CALL CPYSTR ;Start our message
2) SETO B, ;Local host number
2) CALL $GTHNS ;Get host name
2) RETSTR <Couldn't get local Internet host name>,TTXNET
2) CALL INTGO ;Send off our hello to the other site
2) RET
2) CALL GETRSP ;Pick up reply (most likely 250)
2) RET
2) HRROI A,BUFFER ;Put everything in our buffer
2) HRROI B,[ASCIZ/SEND FROM:</]
2) CALL CPYSTR ;Initiate message
2) CALL .DIRST ;Add our user name
2) MOVEI B,"@" ;Append at-sign for return address
2) IDPB B,A ;Drop it into buffer
2) SETO B, ;Local host number
2) CALL $GTHNS ;Add our site name
2) RETSTR <Couldn't get local Internet host name>,TTXNET
2) MOVEI B,">" ;Close with a close broket
2) IDPB B,A ;Drop it in
2) CALL INTGO ;Send the SEND command
2) RET
2) CALL GETRSP ;Get server's response
2) RET
2) HRROI A,BUFFER ;Where to build message to send
2) HRROI B,[ASCIZ/RCPT TO:</] ;Set up recipient command
2) CALL CPYSTR ;Throw start of command into buffer
2) HRROI B,NETUSR ;Get recipient user name
2) CALL CPYSTR ;Add it in
2) MOVEI B,"@" ;Get an at-sign
2) IDPB B,A ;Add that too
2) HRROI B,NETADR ;Get site name of recipient address
2) CALL CPYSTR ;Add it in
2) MOVEI B,">" ;And an angle bracket
2) IDPB B,A ;Closes off the recipient name
2) CALL INTGO ;Send off the buffer
2) RET
2) CALL GETRSP ;Pick up reply (250 or 251)
2) RET
2) HRROI B,[ASCIZ\DATA
; SNDMSG.MAC.1 & <MM>SNDMSG.MAC.1 20-Apr-88 1449 PAGE 9
2) \] ;Point to start of DATA command
2) CALL INTSTR ;Go send it
2) RET
2) CALL GETRSP ;Pick up reply (most likely 354)
2) RET
2) ;;
2) ;; [NIC001] First line of data should be header line for REPLY
2) ;; programs to use...
2) ;;
2) HRROI A,BUFFER
2) CALL .DIRST ;Add our user name
2) MOVEI B,"@" ;Append at-sign for return address
2) IDPB B,A ;Drop it into buffer
2) SETO B, ;Local host number
2) CALL $GTHNS ;Add our site name
2) RETSTR <Couldn't get local Internet host name>,TTXNET
2) MOVEI B," "
2) IDPB B,A
2) IDPB B,A
2) SETO B, ;B/want present time
2) MOVX C,OT%NSC!OT%12H!OT%TMZ!OT%SCL ;C/format
2) ODTIM% ;Write the time
2) CALL INTGO ;Add CRLF and send it off
2) RET
2) ;;
2) ;; End [NIC001]
2) ;;
2) SETZ D, ;Clear line position
2) MOVE C,MSPTR ;Point to message
2) ILDB B,C ;Get the first character
2) DO.
2) CALL INTCHR ;Send char out, maybe processing prefix period
2) RETSTR <Couldn't send char to net>,TTXNET
2) ILDB B,C ;Get another
2) JUMPN B,TOP. ;Go back for the next char
2) ENDDO.
2) MOVEM C,MSEPTR ;Save pointer to end of message
2) SKIPE D ;If not at start of line, need extra crlf
2) SKIPA B,[POINT 7,[ASCIZ \
2) .
2) \]]
2) MOVE B,[POINT 7,[ASCIZ \.
2) \]] ;Will eventually end with a CRLF . CRLF
2) CALL INTSTR ;Append the trailer
2) RET
2) CALL GETRSP ;Pick up reply (most likely 250)
2) RET
2) RETSKP ;Success, return +2
2) ^L
2) ; Copy in one data character, being careful with CRLFs and dots
2)
; SNDMSG.MAC.1 & <MM>SNDMSG.MAC.1 20-Apr-88 1449 PAGE 10
2) INTCHR: MOVE A,NETJFN ;Get jfn for output
2) CAIE B,"." ;If we have a period
2) IFSKP.
2) IFE. D ;If at the start of a line
2) BOUT% ;Send an extra dot
2) ERJMP R
2) ENDIF.
2) SETO D, ;In the middle of a line
2) BOUT% ;Now send our first dot
2) ERJMP R
2) RETSKP
2) ENDIF.
2) CAIE B,.CHCRT ;Carriage return?
2) IFSKP.
2) MOVEM B,D ;Yes, set line position positive to remember
2) BOUT% ;And go send it
2) ERJMP R
2) RETSKP
2) ENDIF.
2) CAIN B,.CHLFD ;Line feed?
2) SKIPG D ;And previous carriage return?
2) CAIA ;No, go on
2) TDZA D,D ;Yes, we are now at the start of a line
2) SETO D, ;Else we are in the middle of a line
2) BOUT% ;In any case go send the char
2) ERJMP R
2) RETSKP
2) ^L
2) ; INTGO - add CRLF to string in buffer and send it off
2) ; INTSTR - send string pointed to in B
2) ; both return +2 normally, or +1 on error
2)
2) INTGO: MOVEI B,.CHCRT ;A carriage return
2) IDPB B,A ;Append it to our buffer
2) MOVEI B,.CHLFD ;A linefeed
2) IDPB B,A ;Add it, too
2) MOVEI B,.CHNUL ;A null
2) IDPB B,A ;Tie off string with it
2) HRROI B,BUFFER ;What to send
2) INTSTR: MOVE A,NETJFN ;Where to send
2) SETZ C, ;End on null
2) SOUTR%
2) RETSTR <Couldn't send string to network>,TTXNET,ERJMP
2) RETSKP
2) ^L
2) ; SMTNIN - input a number (like NIN%), break on non-digit
2) ; call with A/SMTP connection JFN, B/pointer to line buffer, C/char count
2) ; returns +1/failure, +2/success, number in B, C and D smashed
2)
2) SMTNIN: TRVAR <ATMPTR,RETNUM,BUFCTR,<LINPTR,2>>
2) DMOVEM B,LINPTR ;Save where to start
; SNDMSG.MAC.1 & <MM>SNDMSG.MAC.1 20-Apr-88 1449 PAGE 11
2) SETZM ATMPTR ;No continuation lines yet
2) SETZM RETNUM ;Nothing to return yet
2) DO.
2) SETZ C, ;Nothing this time through
2) DO.
2) BIN% ;Get the next character from our stream
2) RETSTR <Couldn't read SMTP server response>,TTXNET,ERJMP
2) CAIL B,"0" ;Is it in range
2) CAILE B,"7" ;to be a digit?
2) IFSKP.
2) IMULI C,10 ;Yes, shift result by octal radix
2) ADD C,B ;Add in digit
2) SUBI C,"0" ;Minus offset for ASCII characters
2) LOOP. ;Go back for the next one
2) ENDIF.
2) ENDDO.
2) SKIPG C ;If somehow out of range
2) RETSTR <SMTP input number was not positive>,TTXNET
2) EXCH C,RETNUM ;Exchange with value to return
2) IFG. C
2) CAME C,RETNUM ;If had a number already but is not the same
2) RETSTR <SMTP multi-line input had different codes>,TTXNET
2) ENDIF.
2) CAIE B,"-" ;If we got a dash
2) IFSKP.
2) CALL GETLFD ;Then read in some more
2) RET ;Propagate fail return
2) LOOP.
2) ENDIF.
2) ENDDO.
2) CAIE B," " ;If not a space
2) RETSTR <SMTP code terminator is neither a dash nor a space>,TTXNET
2) ; JRST GETLFD
2)
2) ; GETLFD - Read in rest of server response line
2)
2) GETLFD: SKIPE B,ATMPTR ;Get pointer
2) IFSKP.
2) DMOVE B,LINPTR ;If none, point to start of buffer
2) MKPTR (B) ;Make sure it is a byte pointer
2) ELSE.
2) MOVEI C,.CHCRT ;Else get a CR
2) DPB C,B ;Drop it in over the null we left
2) MOVEI C,.CHLFD ;And a linefeed
2) IDPB C,B
2) MOVEI C," " ;And finally a space
2) IDPB C,B ;Drop it in to make pretty
2) SOS C,BUFCTR ;Count off, get old buffer counter
2) SOS C,BUFCTR ;And again
2) ENDIF.
2) MOVEI D,.CHCRT ;Read to a carriage return
; SNDMSG.MAC.1 & <MM>SNDMSG.MAC.1 20-Apr-88 1449 PAGE 12
2) SIN% ;Do the read
2) ERJMP R ;Propagate fail return
2) MOVEM B,ATMPTR ;Save new atom buffer pointer
2) MOVEM C,BUFCTR ;And new buffer space counter
2) SETZ C, ;Get a null
2) DPB C,B ;Drop it in over carriage return
2) BIN% ;Now read in the linefeed
2) ERJMP R
2) MOVE B,RETNUM ;Get the number to return
2) RETSKP
2) ^L
2) ; DOCHA - Send a message via the CHAOSnet
2)
2) ; Chaosnet symbols abstracted from CHASYM
2) .CSRFS==3 ;RFC sent
2) .CSOPN==4 ;Connection is open
2) .MOPKR==27 ;Read packet
2) CHPKDT==4 ;???
2) $CPKNB==041400,,0 ;???
2)
2) DOCHA: PUSH P,B ;Save foreign host
2) HRROI A,NETBUF ;Set up pointer for building filename string
2) HRROI B,[ASCIZ/CHA:/]
2) CALL CPYSTR ;Start with correct device name
2) POP P,B ;Get host number back
2) MOVEI C,^D8 ;Octal
2) NOUT%
2) RETSTR <Couldn't copy host number>,TTXNET
2) HRROI B,[ASCIZ/.SEND_/]
2) CALL CPYSTR ;Put contact name into buffer too
2) HRROI B,NETUSR ;And net username
2) CALL CPYSTR
2) MOVX A,GJ%SHT!GJ%OLD ;Short form, old file
2) HRROI B,NETBUF ;Filename
2) GTJFN%
2) RETSTR <Can't get Chaosnet connection>,TTXNET
2) MOVEM A,NETJFN ;Save JFN for later
2) MOVX B,FLD(8,OF%BSZ)!OF%WR ; write mode, 8 bits
2) OPENF%
2) RETSTR <Can't open Chaosnet connection>,TTXNET
2) CALL CHAMSG ;Build the message to be sent
2) RET
2) MOVE A,NETJFN ;A/network jfn
2) MOVE B,[POINT 8,BUFFER] ;B/buffer where CHAMSG left the message
2) SETZB C,D ;Normal SOUT, flush randomness in C & D
2) SOUT%
2) RETSTR <Can't send Chaosnet message>,TTXNET,ERJMP
2) MOVE A,NETJFN
2) MOVEI B,.MOEOF ;Send an EOF to Chaosnet
2) MTOPR%
2) RETSTR <Can't send Chaosnet EOF>,TTXNET,ERJMP
; SNDMSG.MAC.1 & <MM>SNDMSG.MAC.1 20-Apr-88 1449 PAGE 13
2) MOVEI B,.MONOP ;Wait for everything to die down
2) MTOPR%
2) RETSTR <Can't send Chaosnet NOP>,TTXNET,ERJMP
2) CLOSF% ;Close the Chaosnet connection
2) IFNJE.
2) SETZM NETJFN ;Flush the JFN
2) RETSKP
2) ENDIF.
2) MOVE A,NETJFN ;A/network jfn
2) MOVEI B,.MOPKR ;Get Los/CLS packet
2) HRROI C,NETBUF ;Drop it into NETBUF
2) MTOPR%
2) RETSTR <Chaosnet connection failed>,TTXNET,ERJMP
2) MOVE A,[POINT 8,NETBUF+CHPKDT]
2) LDB B,[$CPKNB+NETBUF] ;Get length
2) ADJBP B,A ;To point to end of string
2) SETZ C, ;Get a null
2) DPB C,B ;And tie off message with it
2) MOVX C,TTXNET ;Have pointer to string, now set err code
2) RET
2) ^L
2) ; CHAMSG - build a message to be sent over the CHAOSnet into BUFFER
2)
2) CHAMSG: MOVE A,[POINT 8,BUFFER] ;Get a pointer to our output buffer
2) CALL .DIRST ;Add our user name
2) MOVEI B,"@" ;Get an atsign
2) IDPB B,A ;Drop it in
2) SETO B, ;With local host name
2) MOVEM A,D ;Saving string pointer
2) CALL $CHSNS ;Copy local host name to our buffer
2) RETSTR <Couldn't get local Chaos host name>,TTXNET
2) MOVE A,D ;Get pointer to host name back
2) CALL $RMREL ;Flush ugly relative domain
2) MOVE A,D ;Get pointer once more
2) DO.
2) ILDB B,A ;Skip over
2) JUMPN B,TOP. ;Until we get a null
2) ENDDO.
2)
2) ;; Added sender, now add time
2) MOVEI B,.CHSPC ;A space
2) DPB B,A ;Add it to the buffer
2) SETO B, ;B/want present time
2) MOVX C,OT%NSC!OT%12H!OT%TMZ!OT%SCL ;C/format
2) ODTIM% ;Write the time
2) MOVEI B,215 ;CHAOSnet EOL
2) IDPB B,A ;Drop that in
2)
2) ;; Finished header, now add text of message (converting EOLs)
2) MOVE B,MSPTR ;Get pointer to message text
2) DO.
; SNDMSG.MAC.1 & <MM>SNDMSG.MAC.1 20-Apr-88 1449 PAGE 14
2) ILDB C,B ;Get a byte from the user
2) CAIN C,15 ;Carriage return?
2) MOVEI C,215 ;Replace with chaos EOL character
2) CAIE C,12 ;If linefeed, ignore it.
2) IDPB C,A ;Put character in the buffer
2) JUMPN C,TOP. ;And continue until we have transferred a null
2) ENDDO.
2) MOVEM B,MSEPTR ;Save pointer to end of message
2) MOVEI C,215 ;Put another carriage return for pretty
2) DPB C,A ;Clobber the null we left there
2) SETZ C,
2) IDPB C,A ;And terminate string with a null
2) RETSKP
2) ^L
2) ; DOETH - Send a message via the Pup Ethernet
2)
2) ; Definitions for Pup-based Ethernet (stolen from PUPPAR)
2)
2) IFNDEF PUPI%,<
2) OPDEF PUPI% [JSYS 441] ;JSYS to send a packet over the Ether
2) OPDEF PUPO% [JSYS 442] ;JSYS to pick up a packet
2)
2) PU%CHK==1B1 ;Compute/check checksum
2) PU%MEI==1B3 ;Header is in 16-bit hardware mode
2) PU%TIM==1B4 ;(PUPI%) input timeout in ms in ac3
2)
2) .PUORW==16 ;Raw I/O mode for OPENF%
2) >;IFNDEF PUPI%
2)
2) PBCONT==5 ;Start of data in buffer
2)
2) MNPLEN==^D22 ;Minimum Pup length (bytes) incl header
2) MXPLEN==^D554 ;Maximum Pup length
2) MXPBLN==<MXPLEN+3>/4 ;Maximum packet buffer size (words)
2)
2) DEFSTR PUPLEN,BUFFER,17,16 ;Pup length
2) DEFSTR PUPTYP,BUFFER,35,8 ;Pup type
2)
2) DOETH: PUSH P,B ;Save net number
2) HRROI A,NETBUF ;Get pointer to name string area
2) HRROI B,[ASCIZ/PUP:!J./]
2) CALL CPYSTR ;Copy string
2) HLRZ B,(P) ;Get net num back
2) MOVEI C,^D8 ;Octal
2) NOUT% ;Add the number
2) RETSTR <Couldn't copy net number>,TTXNET
2) CALL NUMSGN ;Add a number sign
2) POP P,B ;Get host number back
2) HRRZS B ;Just the host number
2) NOUT% ;Add the number (8 still in C)
2) RETSTR <Couldn't copy host number>,TTXNET
; SNDMSG.MAC.1 & <MM>SNDMSG.MAC.1 20-Apr-88 1449 PAGE 15
2) CALL NUMSGN ;Another number sign
2) MOVEI B,"4" ;Well-known socket for misc-services
2) IDPB B,A ;Drop it in
2) SETZ B, ;Get a null
2) IDPB B,A ;Drop that in too
2) MOVX A,GJ%SHT!GJ%OLD ;Short-style gtjfn, old file
2) HRROI B,NETBUF ;From name we just built
2) GTJFN% ;Get the jfn
2) RETSTR <Couldn't get network connection>,TTXNET
2) MOVEM A,NETJFN ;Save JFN
2) MOVX B,FLD(^D8,OF%BSZ)!FLD(.PUORW,OF%MOD)!OF%RD!OF%WR
2) OPENF% ;Open in raw packet mode
2) RETSTR <Couldn't open network connection>,TTXNET
2) CALL BLDETH ;Build packet into buffer
2) HRRZ A,NETJFN ;Get JFN back
2) TXO A,PU%CHK!PU%MEI ;Compute checksum, MEIS headers
2) MOVE B,[MXPBLN,,BUFFER] ;Max length, from buffer
2) PUPO% ;Send it out
2) ERJMP JSRET ;Random lossage
2) HRRZ A,NETJFN ;Get JFN again
2) TXO A,PU%CHK!PU%MEI!PU%TIM ;Checksum, MEIS headers, timeout
2) MOVE B,[MXPBLN,,BUFFER] ;Max length, into buffer
2) MOVX C,^D<30*1000> ;Wait for up to 30 seconds
2) PUPI% ;Read it back in
2) IFNJE. ;Got one?
2) LOAD A,PUPTYP ;Get type
2) CAIN A,301 ;Success?
2) RETSKP
2) LOAD B,PUPLEN ;Get length of pup
2) SUBI B,MNPLEN ;Minus minimum number is length of error string
2) IFE. B ;If we have nothing
2) HRROI A,[ASCIZ/Unknown network error/] ;Make up a string
2) ELSE.
2) MOVE A,[POINT 8,PBCONT+BUFFER] ;Get pointer to error
2) ADJBP B,A ;Point to end of error message
2) SETZ C, ;Get a null
2) IDPB C,B ;Drop it in at end of string
2) ENDIF.
2) MOVX C,TTXNET ;And error code
2) RET ;Return with it
2) ENDIF.
2) RETSTR <Failed to receive remote reply>,TTXNET
2)
2) NUMSGN: MOVEI B,"" ;Quote with control-V
2) IDPB B,A ;Drop it in
2) MOVEI B,"#" ;Number sign
2) IDPB B,A ;Drop it in
2) RET
2) ^L
2) ; Build packet into buffer for PUPO%
2) ; returns +1/always, mungs registers A-D
; SNDMSG.MAC.1 & <MM>SNDMSG.MAC.1 20-Apr-88 1449 PAGE 16
2)
2) BLDETH: SETZM BUFFER ;Clear start of buffer
2) MOVE A,[BUFFER,,BUFFER+1]
2) BLT A,BUFFER+MXPBLN-1 ;Clear it out for the length of a packet
2) MOVEI A,300 ;Get packet type for ether send
2) STOR A,PUPTYP ;Save it
2) MOVE A,[POINT 8,PBCONT+BUFFER] ;Get dest ptr
2) CALL .DIRST ;Copy user name or string describing us
2) MOVEI B,":" ;Colon
2) IDPB B,A ;Drop it in
2) HRROI B,NETUSR ;Get net user name
2) CALL CPYSTR ;Add it in
2) MOVEI B,":" ;Another colon
2) IDPB B,A ;Drop it in
2) MOVE B,MSPTR ;Point to message
2) CALL CPYSTR ;Copy it in
2) MOVEM B,MSEPTR ;Save pointer
2) MOVEI D,@A ;Compute address of last word
2) SUBI D,BUFFER-1 ;Compute # 36-bit words used
2) LSH D,2 ;Convert to bytes
2) LSH A,-^D33 ;Get bytes not used in last word
2) SUBI D,(A) ;Compute pup length
2) ADDI D,2 ;Include checksum
2) STOR D,PUPLEN ;Save length
2) RET
2) ^L