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