diff --git a/build/misc.tcl b/build/misc.tcl index 70843df3..de56dd9c 100644 --- a/build/misc.tcl +++ b/build/misc.tcl @@ -851,6 +851,10 @@ expect ":PDUMP SYS2;TS XXFILE" expect ">>" respond " " ":kill\r" +# MSEND +respond "*" ":midas sysbin;_sysen2;msend\r" +expect ":KILL" + # TJ6 respond "*" ":midas sysbin;_tj6;tj6\r" expect ":KILL" diff --git a/doc/programs.md b/doc/programs.md index 9f137bbe..2c2aedc3 100644 --- a/doc/programs.md +++ b/doc/programs.md @@ -130,6 +130,7 @@ - MLDEV, MLSLV, Allows access to remote systems as devices (e.g. DB:). - MLIFE, Mike Speciner's Conway Life. - MODEMS, modems gragon. +- MSEND, send to many users. - MSPLIT, split a file into smaller parts. - MTBOOT, make bootable tapes. - MUDDLE, MDL interpreter. diff --git a/src/sysen2/msend.140 b/src/sysen2/msend.140 new file mode 100644 index 00000000..2c0a7cc9 --- /dev/null +++ b/src/sysen2/msend.140 @@ -0,0 +1,1267 @@ +TITLE MSEND +; Send to many users, among other things. In addition to the usual list +; of users, one may give special names NET, ALL, LOCAL, and _, +; specifying, respectively, network, all, and local users, and users who +; are connected but not logged in. If the first character of a name is +; =, the rest of it is taken to specify an xjname: sending will be to +; all users who own such jobs. If the first character is *, the rest of +; the spec is an xuname to send to. +; Sends to users on other ITSes will work, but none of the special hacks +; will (you can't map in the system over the net). +; Most of this is done by grovelling around in the user variables. In +; particular, once a user has been identified, if FOO HACTRN isn't +; around then the program finds the name of the top-level job in the +; tree (FOO SHELL would come to mind if shell handled cli's). Sending +; is via the CLI device; like ddt, the crock makes sure %picli is on in +; the target, and sleeps between sends to keep the disks from wedging. +; TTY input is handled by a (crockish) insrt file, which see. + + +O=0 +A=1 +B=2 +C=3 +D=4 +E=5 +F=6 +G=7 + +T=15 +U=16 +P=17 + + +TTYI==0 +TTYO==1 +USRI==2 +CLIO==3 +DSKI==4 + +; DECREMENT BYTE POINTER +DEFINE DBP AC + ADD AC,[70000,,] + TLNE AC,400000 + ADD AC,[347777,,-1] +TERMIN + +LOC 40 + 0 + JSR UUOH + JSR TSINT +LOC 100 + +; typeout uuos +.INSRT TAA;UUOS > +.INSRT TAA;INP > + +PDLLEN==150 +PDL: BLOCK PDLLEN +JCL: BLOCK 50 + BUFMAKE NAMBUF,500,HLPTO,[To: ] + BUFMAKE TXTBUF,1000,HLPTXT,[Text: +] +USRB==3 +USRBLN==USRB*10 +; BLOCK OF USRB WORDS FOR EACH SPEC: FIRST IS SIXBIT (OR -1 OR -2); SECOND +; IS -1 IF JNAME SPEC RATHER THAN USER SPEC; THIRD IS HOSTNAME IF SUPPLIED (6BIT). +USRSPC: BLOCK USRBLN +USRSAV: -USRBLN,,USRSPC +USRUNM==0 +USRJSP==1 +USRHST==2 +SNDBLN==90 +SNDBLK: BLOCK 60 +SNDUNM==0 +SNDJNM==1 +SNDHST==2 +SNDWON==3 +SYSNAM: 0 ; NAME OF SYSTEM WE'RE ON +GOTADR: 0 +JCLFLG: 0 ; SAVED POINTER TO UNUSED JCL +BEFRQ: 0 ; -1 IF HEADER SHOULD BE Š TTYOPT: 0 +JOBSPC: 0 ; -1 IF PARSING JOB SPEC RATHER THAN USER ADDRESSEE +UNMSPC: 0 ; SIMILAR FOR UNAME SPEC +CJNAME: 0 ; SET BY ADRCHK TO JNAME OF GUY WE FINALLY FOUND +MSGPT: 0 ; BYTE POINTER TO MESSAGE +MSGLEN: 0 ; LENGTH +HDRPT: 0 +HDRLEN: 0 ; PTR AND LENGTH FOR HEADER +ALLFLG: 0 ; SET IN ALLSND, CLEARED IN NLOGIS +XUNSAV: 0 ; USED BY XUNSND +NETTST: 0 ; USED BY NETSND AND RNDSND +SYSVER: 0 ; SYSTEM VERSION #, SET BY INIT +SNTONE: 0 ; SOMETHING HAS BEEN SENT, SO SLEEP +RETRY: 0 ; SET AFTER FIRST TRY SENDING OVER NET + +START: MOVE P,[-PDLLEN,,PDL-1] + .CALL [SETZ + SIXBIT /SSTATU/ + MOVEM A + MOVEM A + MOVEM A + MOVEM A + MOVEM A + MOVEM SYSNAM ; AI, DM, ETC. + SETZM A] ; ITS VERSION NUMBER + .LOSE %LSSYS + CAME A,SYSVER + PUSHJ P,INIT + PUSHJ P,TTYOPN + .SUSET [.RXJNAM,,A] + CAMN A,[SIXBIT /SSEND/] + SETOM BEFRQ + .SUSET [.ROPTIO,,A] + TLNE A,OPTCMD + PUSHJ P,JCLHAK + SKIPN GOTADR +ADRCON: PUSHJ P,GETADR ; GET ADDRESSEES + SKIPN GOTADR + .BREAK 16,124000 + MOVEI B,TXTBUF + SKIPN BUFVCT(B) + JRST TXTCON + MOVE A,LSTBRK + CAIE A,^C + JRST SNDCON +TXTCON: PUSHJ P,GETMSG ; GET MSG + MOVE A,LSTBRK + SETZM LSTBRK + CAIN A,^C ; TERMINATE WITH CTRL-C? + JRST ADRCON + MOVEI B,TXTBUF + SKIPN BUFVCT(B) + .BREAK 16,124000 +SNDCON: PUSHJ P,SNDMSG +QUIT: .BREAK 16,124000 + +JCLHAK: .BREAK 12,[..RJCL,,JCL] + MOVE A,[440700,,JCL] + SETOM GOTADR + MOVEI B,0 + PUSHJ P,PRSADR ; SEE IF ANY ADDRESSEES HERE + SETZM GOTADR + ILDB O,A ; DID THAT USE ALL THE JCL? + JUMPE O,[SETZM JCLFLG ; YES + POPJ P,] + DBP A + MOVEM A,JCLFLG ; NO, SAVE POINTER TO WHAT'S LEFT + POPJ P, + +; READ ADDRESSEES FROM TTY IF NONE SUPPLIED +GETADR: PUSH P,A + PUSH P,B + PUSH P,C + HRRZ A,USRSAV + CAIE A,USRSPC ; NO USERS YET? + PUSHJ P,USRUNP ; UNPARSE WHAT'S THERE + MOVEI B,NAMBUF + SETOM KEEPQT ; KEEP 'S WHEN READ + PUSHJ P,GETBUF ; READ A BUFFER FULL + JRST GETADO ; NULL + MOVE A,NAMBUF+BUFBEG ; GET BEGINNING OF BUFFER + SETOM GOTADR + MOVNI B,1 ; DON'T TERMINATE ON CR HERE + PUSHJ P,PRSADR + SETZM GOTADR +GETADO: POP P,C + POP P,B + POP P,A + POPJ P, + +; PARSE BUFFER FULL OF ADDRESSEES. TERMINATE ON , CTRL-C, OR BREAK +; (BREAK IF B IS 0). RETURN BPTR TO UNEATEN DATA IN A. +PRSADR: PUSH P,O + PUSH P,B + PUSH P,C + PUSH P,D + PUSH P,E + MOVE D,USRSAV +PRSSTR: SETZM JOBSPC + SETZM UNMSPC + ILDB O,A + CAIN O,"= ; JNAME SPEC? + JRST [SETOM JOBSPC + JRST PRSLOP] + CAIN O,"* + JRST [SETOM UNMSPC + JRST PRSLOP] + CAIN O,"_ + JRST [PUSHJ P,GETSYL + MOVNI B,1 + PUSH P,C + JRST PRSCON] + DBP A +PRSLOP: PUSHJ P,GETSYL ; TERMINATES ON @,SPACE,COMMA,ETC. + PUSH P,C + CAIE C,"@ + JRST PRSCON + PUSH P,B + PUSHJ P,GETSYL + MOVEM C,-1(P) ; SAVE REAL TERMINATOR + JUMPE B,[POP P,B + JRST PRSCON] + CAMN B,SYSNAM + JRST [POP P,B + JRST PRSCON] + SETZM JOBSPC + SETZM UNMSPC ; CAN'T DO THESE AT FOREIGN SITE + MOVE C,B + POP P,B + CAIA +PRSCON: MOVEI C,0 + PUSHJ P,PRSONE ; PUT IT IN TABLE + JRST PRSOUT + POP P,C + CAIN C,^C ; TERMINATE ON CTRL-C + JRST PRSOUT + JUMPE C,PRSOUT + SKIPN -3(P) + JRST [CAIE C,^M + CAIN C,40 + JRST PRSOUT + CAIE C,^I + CAIN C,^J + JRST PRSOUT + JRST .+1] + JRST PRSSTR + +; GET A SYLLABLE INTO B, TERMINATOR INTO C. BYTE POINTER IS IN A. +GETSYL: PUSH P,D + MOVEI B,0 + MOVE D,[440600,,B] +GETSLL: ILDB C,A ; GET A CHAR + PUSHJ P,NTERMQ + JRST GETSYD + CAIN C,^Q ; QUOTING + ILDB C,A + SUBI C,40 + CAIL C,100 + SUBI C,40 + IDPB C,D + TLNE D,770000 ; FULL WORD? + JRST GETSLL +GETSFL: ILDB C,A + PUSHJ P,NTERMQ ; FLUSH CRAP + CAIA + JRST GETSFL +GETSYD: POP P,D + POPJ P, + +; SKIP IF NOT TERMINATOR +NTERMQ: CAIE C,40 + CAIN C,", + JRST NTERMO + CAIE C,"@ + CAIN C,^M + JRST NTERMO + CAIE C,^I + CAIN C,^J + JRST NTERMO + CAIE C,^C + CAIN C,0 + JRST NTERMO + AOS (P) +NTERMO: POPJ P, + +PRSONE: JUMPE B,POPJ1 + JUMPN C,PRSFRN ; FOREIGN SITE + CAMN B,[-1] ; SPEC OF NOT LOGGED IN? + JRST PRSPUT + CAMN B,[SIXBIT /NET/] + JRST [MOVNI B,2 + JRST PRSPUT] ; NET USERS + CAMN B,[SIXBIT /LOCAL/] + JRST [MOVNI B,3 + JRST PRSPUT] + CAMN B,[SIXBIT /ALL/] + JRST [MOVNI B,4 + JRST PRSPUT] + CAMN B,[SIXBIT /RANDOM/] + JRST [MOVNI B,5 + JRST PRSPUT] + SKIPN UNMSPC + SKIPE JOBSPC + JRST PRSPUT ; JOB SPEC + PUSHJ P,ADRCHK ; SEE IF LEGITIMATE USER + JRST [PUSHJ P,ADRBAD + JRST POPJ1] ; BITCH AND GO ON +; CHECK TO SEE IF THIS IS ALREADY IN TABLE. +PRSPUT: MOVE E,USRSAV +PRSPUL: CAMN D,E + JRST PRSPU1 + CAMN B,USRUNM(E) + CAME C,USRHST(E) ; HOST SAME? + JRST PRSNOT ; NOT ALREADY THERE + JRST POPJ1 +PRSNOT: ADD E,[USRB,,USRB] + JUMPL E,PRSPUL +PRSPU1: JUMPGE D,[OASCR TTYO,[ASCIZ / +Addressee table full. Oh, well./] + POPJ P,] + SETZM USRJSP(D) + MOVEM B,USRUNM(D) + MOVEM C,USRHST(D) + SKIPE JOBSPC + SETOM USRJSP(D) ; THIS GUY IS A JOB SPEC + SKIPE UNMSPC + AOS USRJSP(D) + ADD D,[USRHST+1,,USRHST+1] +POPJ1: AOS (P) +CPOPJ: POPJ P, + +PRSFRN: PUSH P,B + PUSH P,C + MOVEI B,0 + PUSHJ P,ADRCHK + JRST PRSFRB + POP P,C + POP P,B + JRST PRSPUT +PRSFRB: MOVEI B,0 + PUSHJ P,ADRBAD + POP P,C + POP P,B + JRST POPJ1 + +PRSOUT: CAME D,USRSAV + AOS -5(P) + MOVEM D,USRSAV + POP P,E + POP P,D + POP P,C + POP P,B + POP P,O + POPJ P, + +; TAKE UNAME IN B, OR 0 IN B AND TWO ARGS. SKIP IF ON-LINE AND LISTENING +ADRCHK: PUSH P,A + PUSH P,C + JUMPE B,ADRSPC + MOVE C,[SIXBIT /HACTRN/] + MOVE A,[SIXBIT /USR/] + PUSHJ P,ADRRCH + JRST [PUSHJ P,ADHAIR + JRST ADROUT + JRST ADRWON] + JRST ADROUT ; AROUND, BUT NOT LISTENING +ADRWON: AOS -2(P) + MOVEM C,CJNAME +ADROUT: POP P,C + POP P,A + POPJ P, + +ADRSPC: MOVE A,-3(P) ; HOST + TDZ A,[000077,,777777] + IOR A,[SIXBIT / USR/] + MOVE C,[SIXBIT /HACTRN/] + MOVE B,-4(P) + PUSHJ P,ADRRCH + JRST ADROUT + JRST ADROUT + JRST ADRWON + +; TAKES DEVICE IN A, UNAME IN B, JNAME IN C. +; SKIPS TWICE IF WIN, ONCE IF ON BUT NOT LISTENING, NOT IF NOT ON. +ADRRCH: SETZM RETRY + PUSH P,D +ADRRC1: .CALL [SETZ + SIXBIT /OPEN/ + [.BII+10,,USRI] + A + B + C + SETZB D] + JRST [CAIN D,%ENADV ; CHECK IF DEVICE NOT AVAIL + SKIPE RETRY + JRST ADRRCL ; SIGH + MOVEI D,70. + .SLEEP D, + SETOM RETRY + JRST ADRRC1] + AOS -1(P) + CAME A,[SIXBIT /USR/] + JRST ADRRCW ; CAN'T DO USETS OVER NET + .USET USRI,[.RMASK,,A] + TRNE A,%PICLI ; LISTENING? +ADRRCW: AOS -1(P) + .CLOSE USRI, +ADRRCL: POP P,D + POPJ P, + + +; COME HERE IF NOT A HACTRN--FIND THE GUY ANYWAY. UNAME IN B +ADHAIR: MOVE T,NCT ; # TTYS + SUBI T,1 +ADHBL: SKIPG A,@TTYSTS ; TTY FREE? + JRST ADHLOP + TLNN A,%TSCNS ; A CONSOLE? + JRST ADHLOP + HRRZ U,A + CAME B,@UNAME + JRST ADHLOP + PUSHJ P,FJNAME + MOVE A,[SIXBIT /USR/] + MOVE C,CJNAME + PUSHJ P,ADRRCH + JRST ADHLOP + JRST ADHLOP + AOS (P) + POPJ P, +ADHLOP: SOJL T,CPOPJ + JRST ADHBL + +; COME HERE WITH U SET UP--FIND JNAME OF TOP-LEVEL JOB +FJNAME: PUSH P,U + PUSH P,A +FJNLOP: SKIPL A,@SUPPRO + JRST [HRRZ U,A + JRST FJNLOP] + MOVE A,@JNAME + MOVEM A,CJNAME + POP P,A + POP P,U + POPJ P, + +; TAKE NAME IN B, GRIPE APPROPRIATELY +ADRBAD: OCTLP TTYO,"A + OASC TTYO,[ASCIZ /User /] + JUMPE B,[OSIX TTYO,-2(P) + OASCI TTYO,"@ + OSIX TTYO,-1(P) + JRST ADRBAO] + OSIX TTYO,B +ADRBAO: OASCR TTYO,[ASCIZ / not available./] + POPJ P, + +; UNPARSE CONTENTS OF USRSPC, PUT IN NAMBUF +VSRUNP: PUSH P,G + MOVEI G,1 ; GET VERBOSE STUFF + JRST USRPUS +USRUNP: PUSH P,G + MOVEI G,0 +USRPUS: PUSH P,O + PUSH P,A + PUSH P,B + PUSH P,C + PUSH P,D + PUSH P,E + PUSH P,F + MOVEI B,NAMBUF + SKIPN G + PUSHJ P,CLINBF ; CLEAN IT OUT + MOVE A,[-USRBLN,,USRSPC] + MOVE C,BUFNCH(B) + MOVEI D,0 +UNPLOP: JUMPN G,VNPLOP ; VERBOSITY + SKIPE USRJSP(A) + JRST [MOVEI O,"= + SKIPL USRJSP(A) + MOVEI O,"* + IDPB O,C + MOVE E,USRUNM(A) + AOJA D,UNNAME] + MOVE O,USRUNM(A) + AOJE O,[MOVE E,[SIXBIT /_/] + JRST UNNAME] + AOJE O,[MOVE E,[SIXBIT /NET/] + JRST UNNAME] + AOJE O,[MOVE E,[SIXBIT /LOCAL/] + JRST UNNAME] + AOJE O,[MOVE E,[SIXBIT /ALL/] + JRST UNNAME] + AOJE O,[MOVE E,[SIXBIT /RANDOM/] + JRST UNNAME] + MOVE E,USRUNM(A) +UNNAME: MOVE F,[440600,,E] + PUSHJ P,UNNLOP + SKIPN E,USRHST(A) ; SOME SITE GIVEN? + JRST UNNOUT + MOVEI O,"@ + IDPB O,C + ADDI D,1 + MOVE F,[440600,,E] + PUSHJ P,UNNLOP ; STICK IT IN +UNNOUT: ADD A,[USRB,,USRB] + CAME A,USRSAV + JRST [MOVEI O,", + IDPB O,C + ADDI D,1 + SKIPN G + JRST UNPLOP + MOVEI O,40 ; PUT SPACE AFTER COMMA IN VERBOSE MODE + IDPB O,C + AOJA D,UNPLOP] + JUMPN G,USRUNO + MOVE A,[-USRBLN,,USRSPC] + MOVEM A,USRSAV +USRUNO: MOVEM C,BUFNCH(B) + ADDM D,BUFCCT(B) + ADDM D,BUFVCT(B) + POP P,F + POP P,E + POP P,D + POP P,C + POP P,B + POP P,A + POP P,O + POP P,G + POPJ P, + +; SIXBIT TO STRING +UNNLOP: TLNE F,17 + JRST UNNLO1 + ILDB O,F + CAIN O,77 ; QUOTE LEADING _ + JRST [MOVEI O,^Q + ADDI D,1 + IDPB O,C + JRST .+1] + DBP F +UNNLO1: ILDB O,F + JUMPE O,CPOPJ + ADDI O,40 + IDPB O,C + ADDI D,1 + TLNE F,770000 + JRST UNNLO1 + POPJ P, + +; MORE VERBOSE VERSION +VNPLOP: SKIPE USRJSP(A) + JRST VNPSTR + MOVE O,USRUNM(A) + AOJE O,[MOVEI E,[ASCIZ /Randoms/] + JRST VNNAME] + AOJE O,[MOVEI E,[ASCIZ /Net users/] + JRST VNNAME] + AOJE O,[MOVEI E,[ASCIZ /Local users/] + JRST VNNAME] + AOJE O,[MOVEI E,[ASCIZ /Everybody/] + JRST VNNAME] + AOJE O,[MOVEI E,[ASCIZ /Net randoms/] + JRST VNNAME] + MOVE E,USRUNM(A) + JRST UNNAME +; STUFF ASCIZ INTO BUFFER +VNNAME: HRLI E,440700 + PUSHJ P,VNNLOP + JRST UNNOUT + +VNNLOP: ILDB O,E + JUMPE O,CPOPJ + IDPB O,C + AOJA D,VNNLOP + +VNPSTR: MOVE F,[440601,,USRUNM] + PUSHJ P,UNNLOP ; NAME INTO BUFFER + MOVE E,[440700,,[ASCIZ / users/]] + SKIPL USRJSP(A) + MOVE E,[440700,,[ASCIZ /*/]] + PUSHJ P,VNNLOP + JRST UNNOUT + +; GET MESSAGE TEXT + +GETMSG: PUSH P,A + PUSH P,B + PUSH P,C + MOVEI B,TXTBUF +; SKIPN BUFCCT(B) ; EMPTY? +; PUSHJ P,BUINIT ; INITIALIZE W/ NAME, TIME, CR + SKIPE A,JCLFLG + JRST GMSJCL + SETZM KEEPQT ; DON'T KEEP QUOTES + PUSHJ P,GETBUF + JFCL +GETMSO: POP P,C + POP P,B +POPAJ: POP P,A + POPJ P, + +; TRANSFER JCL TO INPUT BUFFER, DO RIGHT THING WHEN DONE +GMSJCL: PUSH P,E + PUSH P,D + PUSH P,C + MOVEI C,0 + MOVE E,BUFFCH(B) +GMSJCM: ILDB D,A + CAIE D,^C + CAIN D," + JRST GMSJCE + IDPB D,E + CAIN D,^M + JRST [MOVEI D,^J + IDPB D,E + ADDI C,2 + JRST GMSJCE] + AOJA C,GMSJCM +GMSJCE: MOVEM E,BUFNCH(B) + MOVEM C,BUFVCT(B) + ADDM C,BUFCCT(B) + SETZM JCLFLG + CAIE D,^J + JRST GMSJOT +; COME HERE IF THIS ISN'T THE FULL MESSAGE +GMSJCC: SETZM KEEPQT + PUSHJ P,GETBUF ; ADD TO BUFFER + JFCL +GMSJOT: SETZM JCLFLG + POP P,C + POP P,D + POP P,E + POP P,C + POP P,B + POP P,A + POPJ P, + +; COME HERE TO SEND MESSAGE OUT ONCE COMPOSED. + +SNDMSG: PUSH P,A + PUSH P,B + PUSH P,C + PUSH P,D + PUSHJ P,HDRGEN ; BUILD HEADER IN NAMBUF + MOVEI D,NAMBUF + MOVE B,BUFCCT(D) + MOVEM B,HDRLEN + MOVE B,BUFBEG(D) + MOVEM B,HDRPT + MOVEI D,TXTBUF + MOVE B,BUFCCT(D) + MOVEM B,MSGLEN + MOVE B,BUFBEG(D) + MOVEM B,MSGPT + MOVE C,[-USRBLN,,USRSPC] + OASC TTYO,[ASCIZ / +Sending: /] +SNDLOP: MOVE B,(C) ; PICK UP A USER + CAMN B,[-5] + JRST RNDSND + CAMN B,[-4] + JRST ALLSND + CAMN B,[-3] + JRST LOCSND + CAMN B,[-2] + JRST NETSND + CAMN B,[-1] + JRST NLOGIS ; SEND TO NON-LOGGED IN TYPES + SKIPGE USRJSP(C) + JRST JOBSND ; SEND TO ALL OWNERS OF JOBS + SKIPE USRJSP(C) + JRST XUNSND + SKIPE USRHST(C) + JRST SNDFRN + PUSHJ P,ADRCHK + JRST [PUSHJ P,ADRBAD + JRST SNDNXT] +SNDDO: PUSHJ P,ADRSND +SNDNXT: ADD C,[USRB,,USRB] + CAME C,USRSAV + JRST SNDLOP +SNDOUT: POP P,D + POP P,C + POP P,B + POP P,A + POPJ P, + +SNDFRN: PUSH P,B + PUSH P,USRHST(C) + MOVEI B,0 + PUSHJ P,ADRCHK + JRST SNDFRB + SUB P,[1,,1] + POP P,B + JRST SNDDO +SNDFRB: MOVEI B,0 + PUSHJ P,ADRBAD + SUB P,[2,,2] + JRST SNDNXT + +; BUILD HEADER FOR MESSAGE + +HDRGEN: PUSH P,O + PUSH P,A + PUSH P,B + PUSH P,C + PUSH P,D + PUSH P,E + PUSH P,F + MOVEI B,NAMBUF + PUSHJ P,CLINBF + MOVEI A,177 + MOVE C,BUFBEG(B) + IDPB A,C + MOVEM C,BUFNCH(B) + AOS BUFCCT(B) + AOS BUFVCT(B) + SKIPE BEFRQ + JRST HDRGDN + PUSHJ P,BUINIT ; OLD BUFFER INITIALIZATION THING + HLRE A,USRSAV ; LENGTH OF REMAINING SPACE IN NAME BLOCK + ADDI A,USRBLN + CAIG A,USRHST+1 + JRST [SKIPE USRSPC+USRJSP + JRST .+1 + MOVE A,USRSPC+USRUNM + CAMG A,[-1] + CAMGE A,[-5] + JRST HDRGDN + JRST .+1] + MOVE E,[440700,,[ASCIZ /To: /]] + MOVE C,BUFNCH(B) + MOVEI D,0 + PUSHJ P,VNNLOP ; STUFF OUT STRING + MOVEM C,BUFNCH(B) + ADDM D,BUFVCT(B) + ADDM D,BUFCCT(B) + PUSHJ P,VSRUNP ; ADDRESSEE LIST +NONAM: MOVEI D,0 + MOVE C,BUFNCH(B) + MOVE E,[440700,,[ASCIZ / +/]] + PUSHJ P,VNNLOP + MOVEM C,BUFNCH(B) + ADDM D,BUFVCT(B) + ADDM D,BUFCCT(B) +HDRGDN: POP P,F + POP P,E + POP P,D + POP P,C + POP P,B + POP P,A + POP P,O + POPJ P, + +; SEND TO ALL LOCAL USERS +LOCSND: OCTLP TTYO,"A + OASC TTYO,[ASCIZ /Send to local users: /] + MOVE T,NCT + SUBI T,1 +LOCLOP: SKIPG U,@TTYSTS + JRST LOCENL + TLNN U,%TSCNS ; IN USE AS A CONSOLE? + JRST LOCENL + MOVE A,@TTYTYP + TRNE A,%TYSTY ; STY? + JRST LOCENL + HRRZS U + MOVE B,@UNAME + PUSHJ P,FJNAME + PUSHJ P,ADRSND +LOCENL: SOJGE T,LOCLOP + JRST SNDNXT + +; SENDING TO NET RANDOMS +RNDSND: OCTLP TTYO,"A + OASC TTYO,[ASCIZ /Send to net randoms: /] + MOVE A,[PUSHJ P,DIRQ] + MOVEM A,NETTST + JRST NETSN0 + +; SKIP IF CHOMPER IN U IS LOGGED IN TO DIRECTORY +DIRQ: .CALL [SETZ + SIXBIT /OPEN/ + [.BII,,DSKI] + [SIXBIT /DSK/] + [SIXBIT /.FILE./] + [SIXBIT /(DIR)/] + SETZ @XUNAME] + POPJ P, + .CLOSE DSKI, + AOS (P) + POPJ P, + +; HANDLE SENDING TO ALL NET USERS +NETSND: OCTLP TTYO,"A + OASC TTYO,[ASCIZ /Send to net users: /] + SETZM NETTST +NETSN0: MOVE T,NSTTYS ; # STYS + SUBI T,1 +NETSNB: MOVE A,@STYSTS + TLNN A,%SSUSE ; IN USE? + JRST NETSNL + PUSHJ P,NETQ ; OWNED BY SOMEBODY WITH NET SOCKETS? + JRST NETSNL + MOVE A,NFSTTY + ADD A,T + EXCH A,T + SKIPG B,@TTYSTS + JRST NETSN1 + HRRZ U,B + SKIPE NETTST ; IF NO TEST + XCT NETTST ; TEST SKIPS IF FAILED + CAIA + JRST NETSN1 + MOVE B,@UNAME ; PICK UP UNAME + PUSHJ P,FJNAME ; GET JNAME OF TOP-LEVEL JOB IN CJNAME + PUSHJ P,ADRSND +NETSN1: EXCH A,T +NETSNL: SOJGE T,NETSNB + OASCR TTYO,[0] + JRST SNDNXT + +; COME HERE TO SEE IF STY (STYSTS IN A) IS OWNED BY SOMEONE WITH NET SOCKETS +NETQ: HRRZS A + PUSH P,T + PUSH P,B + MOVE T,IMPSTL ; # SOCKETS + SUBI T,1 +NETQL: SKIPL B,@IMSOC1 + JRST NETQLE + HRRZS B + CAMN B,A + JRST [AOS -2(P) + JRST NETQO] +NETQLE: SOJGE T,NETQL +NETQO: POP P,B + POP P,T + POPJ P, + +; SEND TO ALL USERS +ALLSND: OCTLP TTYO,"A + OASC TTYO,[ASCIZ /Send to all users: /] + MOVE T,[CAIA] + MOVEM T,ALLFLG ; TEST TO PERFORM + JRST NLOG1 + +; SEND TO ALL USERS WITH GIVEN XUNAME +XUNSND: OCTLP TTYO,"A + OASC TTYO,[ASCIZ /Send to users named /] + OSIX TTYO,B + OASC TTYO,[ASCIZ /: /] + MOVE T,[PUSHJ P,XUNCHK] + MOVEM T,ALLFLG + MOVEM B,XUNSAV + JRST NLOG1 +XUNCHK: PUSH P,B + MOVE B,@XUNAME + CAMN B,XUNSAV + AOS -1(P) + POP P,B + POPJ P, + +; SEND TO EVERYONE NOT LOGGED IN +NLOGIS: OCTLP TTYO,"A + OASC TTYO,[ASCIZ /Send to non-logged users: /] + SETZM ALLFLG +NLOG1: MOVE T,NCT + SUBI T,1 +NLOGL: SKIPG U,@TTYSTS + JRST NLOGED + TLNN U,%TSCNS + JRST NLOGED + HRRZS U + SKIPE ALLFLG + JRST [XCT ALLFLG + JRST NLOGED + JRST NLOGWN] ; SEE IF WE WANT TO SEND TO THIS GUY + HLRO B,@UNAME + AOJN B,NLOGED ; LOGGED IN? +NLOGWN: MOVE B,@UNAME + PUSHJ P,FJNAME + PUSHJ P,ADRSND +NLOGED: SOJGE T,NLOGL + OASCR TTYO,[0] + JRST SNDNXT + +; SEND TO EVERYONE WITH JOB OF A PARTICULAR NAME (USES XJNAME) +JOBSND: OCTLP TTYO,"A + OASC TTYO,[ASCIZ /Send to owners of /] + OSIX TTYO,B + OASC TTYO,[ASCIZ /s: /] + PUSH P,A + MOVE U,@USRHI + MOVE A,B +JOBSNL: SUB U,L + CAMG U,L + JRST JOBSNO + CAME A,@XJNAME + JRST JOBSNL + SKIPN B,@UNAME + JRST JOBSNL + PUSHJ P,FJNAME + PUSHJ P,ADRSND + JRST JOBSNL +JOBSNO: POP P,A + OASCR TTYO,[0] + JRST SNDNXT + +; ACTUALLY DO THE SEND +ADRSND: PUSH P,A + PUSH P,C + PUSH P,D + PUSH P,E + OSIX TTYO,B + SKIPE E,USRHST(C) + JRST [OASCI TTYO,"@ + OSIX TTYO,E + JRST .+1] + MOVE A,[-SNDBLN,,SNDBLK] + MOVE C,CJNAME +ADRUNL: SKIPN SNDUNM(A) + JRST ADRUNQ + CAME E,SNDHST(A) ; HOST DIFFERENT? + JRST ADRULE + CAMN B,SNDUNM(A) ; UNAME DIFFERENT? + CAME C,SNDJNM(A) + JRST ADRULE + SKIPL SNDWON(A) + OASCI TTYO,"? + JRST ADRSNO +ADRULE: ADD A,[SNDWON+1,,SNDWON+1] + JUMPL A,ADRUNL +ADRUNQ: MOVEM B,SNDUNM(A) + MOVEM C,SNDJNM(A) + MOVEM E,SNDHST(A) + JUMPN E,[IOR E,[SIXBIT / USR/] + JRST .+2] + MOVE E,[SIXBIT /USR/] + .CALL [SETZ + SIXBIT /OPEN/ + [.BII+10,,USRI] + E + B + SETZ C] + JRST SNDLST + CAME E,[SIXBIT /USR/] + JRST SNDCWN ; CAN'T USET ON NET + .USET USRI,[.RCNSL,,D] + JUMPL D,SNDLST + .USET USRI,[.RMASK,,D] + TRNN D,%PICLI + JRST SNDLST +SNDCWN: .CLOSE USRI, + SKIPN SNTONE + JRST ADRSDO + SKIPN SNDWON-USRB(A) + JRST ADRSDO + MOVEI D,20. + .SLEEP D, +ADRSDO: SKIPE E,SNDHST(A) + JRST [IOR E,[SIXBIT / CLI/] + JRST .+2] + MOVE E,[SIXBIT /CLI/] + SETZM RETRY +ADRSD1: .CALL [SETZ + SIXBIT /OPEN/ + [.UAO,,CLIO] + E + B + C + SETZB D] ; HACK THE ERROR + JRST [CAIN D,%ENADV ; ON DEVICE NOT AVAILABLE, SLEEP A WHILE, RETRY + SKIPE RETRY + JRST SNDLST + MOVEI D,70. + .SLEEP D, + SETOM RETRY + JRST ADRSD1] + MOVE D,HDRPT + MOVE E,HDRLEN + .CALL ADRSIO + .LOSE %LSSYS + MOVE D,MSGPT + MOVE E,MSGLEN + .CALL ADRSIO + .LOSE %LSSYS + .CLOSE CLIO, + SETOM SNDWON(A) + SETOM SNTONE +ADRSNO: OASCI TTYO,40 + POP P,E + POP P,D + POP P,C + POP P,A + POPJ P, +ADRSIO: SETZ + SIXBIT /SIOT/ + MOVEI CLIO + D + SETZ E +SNDLST: .CLOSE USRI, + OASCI TTYO,"? + JRST ADRSNO + +; INITIALIZE BUFFER--SETS STUFF IN BUFFER POINTED TO BY B +BUINIT: PUSH P,A + PUSH P,C + PUSH P,D + PUSH P,E + PUSH P,F + MOVE E,BUFNCH(B) + MOVEI F,0 + MOVE C,[440700,,[ASCIZ /Message from /]] +BUINI0: ILDB D,C + JUMPE D,BUINI1 + IDPB D,E + AOJA F,BUINI0 +BUINI1: MOVE C,[440600,,A] + SKIPE BEFRQ + JRST BEFRST + .SUSET [.RXUNAME,,A] +BUNMLP: ILDB D,C + JUMPE D,BUMACH + ADDI D,40 + IDPB D,E + ADDI F,1 + TLNE C,770000 + JRST BUNMLP +BUMACH: MOVE A,SYSNAM + MOVEI D,"@ + IDPB D,E + MOVE C,[440600,,A] + PUSHJ P,TWONUM +BUDATE: MOVEI D,40 + IDPB D,E + .RTIME A, + MOVE C,[440600,,A] + PUSHJ P,TWONUM + MOVEI D,": + IDPB D,E + PUSHJ P,TWONUM + MOVEI D,": + IDPB D,E + PUSHJ P,TWONUM + MOVEI D,^M + IDPB D,E + MOVEI D,^J + IDPB D,E + ADDI F,14. +BUINO: MOVEM E,BUFNCH(B) ; BEGINNING OF BUFFER + ADDM F,BUFCCT(B) + ADDM E,BUFVLN(B) + POP P,F + POP P,E + POP P,D + POP P,C + POP P,A + POPJ P, + +BEFRST: MOVEI D,177 + IDPB D,E + ADDI F,1 + JRST BUINO + +TWONUM: ILDB D,C + ADDI D,40 + IDPB D,E + ILDB D,C + ADDI D,40 + IDPB D,E + POPJ P, + +; HELP +TOCNT: 0 +TOTXT: [ASCIZ / +Specify the users you want the message sent to; terminate with +or ctrl-C. Names may be separated by , <,>, , etc. If the +first character of a name is '*', it is an xuname specification: the +message will be sent to everyone whose xuname matches the rest of the +name. Thus '*GUEST' will go to GUEST, GUEST0, etc. If the first +character is '=', it is a job spec: '=ZORK' goes to everyone who has a +job with xjname 'ZORK'. foo@AI sends to a user logged in on AI. This +will not work with specifications like '*GUEST', nor will it work with +machines other than AI, ML, MC, and DM./] + [ASCIZ / +Special characters are: +^@: delete the entire buffer. +: terminate and return to the 'Text' field. +: redisplay the buffer. +^G: quit the program. +^L: clear the screen and redisplay the buffer. +: quote the next character. +: swap the last two characters. +: delete a line. +: delete the preceding word. +: delete a line. +: reads a file name from the tty, then reads that file in. +: terminate and send unless the 'Text' field is still empty. +º delete a character./] +HLPTO: PUSH P,A + LDB A,[000100,,TOCNT] + OASCR TTYO,@TOTXT(A) + AOS TOCNT + POP P,A + POPJ P, + +TXTTXT: ASCIZ / +Text of the message. +Special characters are: +^@: delete the entire buffer. +: terminate and return to the 'To' field. +: redisplay the buffer. +^G: quit the program. +^L: clear the screen and redisplay the buffer. +: quote the next character. +: swap the last two characters. +: delete a line. +: delete the preceding word. +: delete a line. +: read a file name from the tty, then read in the specified file. +: terminate and send. +º delete a character./ + +HLPTXT: OASCR TTYO,TXTTXT + POPJ P, + +TTYOPN: .CALL [SETZ + SIXBIT /OPEN/ + [.UII,,TTYI] + [SIXBIT /TTY/] + [SIXBIT /TTY/] + SETZ [SIXBIT /TTY/]] + .LOSE 1400 + .CALL [SETZ + SIXBIT /OPEN/ + [.UIO,,TTYO] + [SIXBIT /TTY/] + [SIXBIT /TTY/] + SETZ [SIXBIT /TTY/]] + .LOSE 1400 + .CALL [SETZ + 'CNSGET + [TTYO] + MOVEM ; vsize + MOVEM ; hsize + MOVEM ; tctyp + MOVEM ; ttycom + SETZM TTYOPT] + .LOSE 1000 + .CALL TTYSET ; SET UP TTY TO TAKE CONTROL CHARACTERS + .LOSE 1000 + .SUSET [.SMSK2,,[1_TTYI]] + MOVE A,TTYOPT ; SET UP RUBOUT HANDLERS + MOVE [PUSHJ P,RUBECH] + TLNE A,%TOERS + MOVE [PUSHJ P,RUBFLS] + MOVEM XCTRUB + SETZM TOERS + TLNE A,%TOERS + SETOM TOERS + SETZM TOFCI + TLNE A,%TOFCI ; TV KEYBOARD? + SETOM TOFCI + POPJ P, + +TTYSET: SETZ + SIXBIT /TTYSET/ + 1000,,TTYI + [020202,,020202] + SETZ [030202,,020202] + +; INITIALIZE +INIT: MOVEM A,SYSVER + MOVE A,USRVAR +USRLOP: MOVE B,(A) + .EVAL B, + .VALUE + ADDI B,400000 + HRLI B,U + MOVEM B,1(A) + ADD A,[2,,2] + JUMPL A,USRLOP + MOVE A,TTYVAR +TTYLOP: MOVE B,(A) + .EVAL B, + .VALUE + ADDI B,400000 + HRLI B,T + MOVEM B,1(A) + ADD A,[2,,2] + JUMPL A,TTYLOP + MOVE A,SYSCON +CONLOP: MOVE B,(A) + .EVAL B, + .VALUE + MOVEM B,1(A) + ADD A,[2,,2] + JUMPL A,CONLOP + MOVE A,SYSLOC +LCNLOP: MOVE B,(A) + .EVAL B, + .VALUE + ADDI B,400000 + MOVEM B,1(A) + ADD A,[2,,2] + JUMPL A,LCNLOP + MOVE A,[-200,,200] + MOVEI B,0 + .CALL [SETZ + SIXBIT /CORBLK/ + MOVEI %CBRED + MOVEI %JSELF + A + MOVEI %JSABS + SETZ B] + .LOSE %LSSYS + .VALUE [ASCIZ / :PDUMP SYS2;TS MSEND +P/] + POPJ P, + +; THINGS TO EVAL +USRBLK: + SQUOZE 0,UNAME +UNAME: 0 + SQUOZE 0,XUNAME +XUNAME: 0 + SQUOZE 0,JNAME +JNAME: 0 + SQUOZE 0,SUPPRO +SUPPRO: 0 + SQUOZE 0,XJNAME +XJNAME: 0 +USRVAR: USRBLK-.,,USRBLK +TTYBLK: + SQUOZE 0,TTYSTS +TTYSTS: 0 + SQUOZE 0,TTYTYP +TTYTYP: 0 + SQUOZE 0,STYSTS +STYSTS: 0 + SQUOZE 0,IMSOC1 +IMSOC1: 0 +TTYVAR: TTYBLK-.,,TTYBLK +CONBLK: + SQUOZE 0,L +L: 0 + SQUOZE 0,NCT +NCT: 0 + SQUOZE 0,NFSTTY +NFSTTY: 0 + SQUOZE 0,NSTTYS +NSTTYS: 0 + SQUOZE 0,IMPSTL +IMPSTL: 0 +SYSCON: CONBLK-.,,CONBLK +LOCBLK: + SQUOZE 0,USRHI +USRHI: 0 +SYSLOC: LOCBLK-.,,LOCBLK + +; INTERRUPTS +TSINT: 0 +TSINTR: 0 + EXCH A,TSINT + SKIPGE A + JRST TSINTH + JFFO A,.+1 + .LOSE 1(B) ; WILL NEVER HAPPEN, OF COURSE + JRST TSOUT +TSINTH: TRNN A,<1_TTYI> + JRST TSOUT + MOVEI A,TTYI + .ITYIC A, + JRST TSOUT + CAIE A,^G + JRST TSOUT + SKIPE RQUOTE + JRST TSOUT + .IOT TTYI,A + .BREAK 16,124000 +TSOUT: EXCH A,TSINT + .DISMIS TSINTR +CONSTA +VARIAB +FREBOT: .+2 +FRETOP: <<./2000>+1>*2000 +END START \ No newline at end of file