Google
 

Trailing-Edge - PDP-10 Archives - SRI_NIC_PERM_SRC_3_19910112 - utilities/mailbx.mac
There are no other files named mailbx.mac in the archive.
TITLE MAILBOX FINDER
SUBTTL A TYPICAL CRETINOUS BBN SPECIAL
SEARCH MONSYM

A=1
B=2
C=3
D=4
E=5
F=6
;10 - 13 RUN CODE
Z=16
P=17

;SPECIAL CHARS IN TEXT FILE
BRKCHR=="\"	;BREAK CHAR BETWEEN MAILBOX BLOCKS
UIDCHR=="#"	;USER ID NUMBER FIELD PRECURSOR

PDLL==10	;PDL LENGTH

;USER & SITE BUFFERS ARE DEFINED AS 140 & 150
;IN PAGE 0 OF MAILBOX FINDER
USER:	BLOCK 8	;USER NAME
SITE:	BLOCK 8	;SITE NAME
	BLOCK 40	;FOR TEXT FILE SCANNING BUFFER

;ENTRY VECTOR
ENTVEC:	JRST BEG	;SUBSYSTEM
	HALTF		;NO REENTRY
	JRST INFRK	;INFERIOR FORK
	JRST BUILD	;CREATE NEW HASH FILE

;A, USER AND SITE ARGS SHOULD BE SET UP AS IN SUBR COMMENTS
;HALTF WHEN FINISHED, WITH RESULTS AS IN SUBR COMMENTS
;SUPERIOR MAY CONTINUE IT TO LOOK FOR ANOTHER MATCH
INFRK:	MOVE P,[-PDLL,,PDL-1]	;START LOC AS INFERIOR FORK
	PUSHJ P,SUBR
INFRK1:	MOVEM A,INFFLG
	HALTF		;RETURN TO SUPERIOR FORK
	SKIPLE A,INFFLG
	PUSHJ P,NXTHSH	;TRY FOR ANOTHER MATCH
	JRST INFRK1

INFFLG:	0	;SAVED STATUS TO PREVENT ILLEGAL REPEAT

BEG:	RESET		;START LOC AS SUBSYSTEM
	MOVE P,[-PDLL,,PDL-1]
	MOVEI A,100	;PRIMARY INPUT
	SIBE		;TYPED AHEAD?
	 JRST BEG1	;YES, ABORT HEADER
	HRROI A,[ASCIZ \Mailbox finder (2/9/81) -- Type user@site<CR>
Type to match
---- --------
V  given site
A  all sites
\]
	PSOUT	;SINCE MACRO ASCIZ HAS 18-WORD MAX
	HRROI A,[ASCIZ \N  NIC ID
S  suppress hunting (match only as specified)
<CR> to begin matching
\]
	SKIPA
RUBOUT:	HRROI A,[ASCIZ \XXX
\]
	PSOUT
BEG1:	SETZM USER
	MOVE A,[USER,,USER+1]
	BLT A,SITE+7
	MOVE B,[440700,,USER]
BEG2:	PUSHJ P,BEGBIN	;READ IN A CHAR
	CAIN A,"@"
	JRST [	MOVE B,[440700,,SITE]
		JRST BEG2]
	CAIN A,12
	JRST BEG3
	CAIN A,177
	JRST RUBOUT
	CAME B,[010700,,SITE+7]
	IDPB A,B
	JRST BEG2

BEGBIN:	PBIN
	CAIN A,15
	PBIN
	CAIL A,141	;LOWER CASE A
	CAILE A,172	;LOWER CASE Z
	SKIPA		;DON'T CONVERT
	SUBI A,40	;CONVERT
	CAIN A,26	;CTRL V QUOTES LOWER CASE
	PBIN
	POPJ P,

BEG3:	MOVEI Z,
BEG4:	PUSHJ P,BEGBIN
	CAIN A,12
	JRST BEG5
	CAIN A,"V"
	IORI Z,1	;GIVEN SITE
	CAIN A,"A"
	IORI Z,5	;ALL SITES
	CAIN A,"N"
	IORI Z,400000	;NIC ID
	CAIN A,"S"
	TLO Z,-1	;SUPPRESS HUNTING TO OTHER SITE TYPES
	CAIN A,177	;RUBOUT
	JRST RUBOUT
	JRST BEG4

BEG5:	MOVE A,Z
	TRNN A,-1	;NO SKIP IF NO ARG OR ONLY S TYPED
	MOVEI A,5	;DEFAULT SEARCH TYPE
	TLO A,200000	;LOWER CASE ALREADY HANDLED
	PUSHJ P,SUBR
	SKIPA
BEG6:	PUSHJ P,NXTHSH
	JUMPLE A,TYPERR
	HRROI A,USER
	PSOUT
	MOVEI A,"@"
	PBOUT
	HRROI A,SITE
	PSOUT
	HRROI A,[ASCIZ/
/]
	PSOUT
	JRST BEG6

TYPERR:	JUMPE A,TYPDUN
	MOVNS A
	HRRO A,ERRTAB(A)
	ESOUT
	HRROI A,[ASCIZ/
/]
	PSOUT
TYPDUN:	HRRO A,ERRTAB	;PICK UP "DONE" STRING PNTR
	PSOUT
	HRROI A,[ASCIZ/
/]
	PSOUT
	HALTF
	JRST .-1

ERRTAB: [ASCIZ \*\]
	[ASCIZ \That's a group, not a person\]
	[ASCIZ \Site name too long\]
	[ASCIZ \Site unrecognized\]
	[ASCIZ \System error - no hash file\]
	[ASCIZ \System error - no text file\]

;FIND MAILBOX OF USER@SITE GIVEN AS ASCIZ ARGS IN USER AND SITE
;<A> SAYS WHAT TYPE(S) OF SITE MATCHES TO ACCEPT:
;400000 (BIT 18) = GIVEN USER NAME IS A NIC ID (= HASH 0 INTERNALLY)
;1 = MATCH TO GIVEN SITE NAME
;4 = MATCH TO OTHER SITES
;SETZ (BIT 0) = DO NOT HUNT TO OTHER SITE TYPES
;200000,,0 (BIT 1) = SUPPRESS CONVERSION TO UPPER CASE

;RETURNS +1 WITH USER & SITE ASCIZ VALUES OF MAILBOX
;IN USER & SITE BUFFERS IF SUCCESSFUL
;<A> SAYS STATUS OF MATCH
;1,,0 = TEXT ENTRY MATCHED IS IDENTICAL TO MAILBOX RETURNED
;+N = MATCHED, USING SITE TYPE N (AS ABOVE)
; 0 = NO (MORE) MATCHES
;-N = ERROR OF VARIETY N (SEE CODE FOLLOWING ALDONE)
;     FILE NAME OF A DISTRIBUTION LIST IS FLAGGED AS ERROR -1
;<B> = USER ID NUMBER, OR -1 IF NONE
;FILES ARE CLOSED WHEN DONE OR ERROR (OTHER THAN DISTRIBUTION LIST)

;THE TWO FILES USED ARE AN ASCII TEXT FILE, MAILBOX.TEXT;N AND A HASH
;CODE FILE, MAILBOX.HASH;N -- THE HIGHEST-NUMBERED HASH FILE
;IS USED, AND THE TEXT FILE WITH THE SAME VERSION NUMBER.
;TEXT FILE FORMAT IS DESCRIBED IN THE TEXT FILE.
;HASH FILE IS POINTERS INTO USER@SITE CHAR STRINGS IN TEXT FILE.
;HASH FORMAT IS <HASHED SITE>,,<CHAR COUNT POINTER> AT ADDRESS
;<HASHED USER> IN THE HASH FILE, OR NEXT FREE (= 0) WORD THEREIN.

SUBR:	MOVE Z,A	;GET SITE TYPE ARG IN Z
	TLNE A,200000	;CONVERT LOWER CASE TO UPPER?
	JRST CASEOK	;NO
	MOVE A,[440700,,USER]
DOCASE:	ILDB B,A	;PICK UP CHAR
	CAIL B,141	;LOWER CASE A
	CAILE B,172	;LOWER CASE Z
	SKIPA		;DON'T CONVERT
	SUBI B,40	;CONVERT
	DPB B,A		;REPLACE CHAR
	CAME A,[010700,,SITE+7]	;DONE?
	JRST DOCASE	;NO, LOOP
CASEOK:	MOVE A,[440700,,USER]	;SCAN USER ARG
	MOVE B,USER+7	;TEST LAST CHAR
	TRNE B,376	;IS IT NULL?
	JRST FILL	;NO, CLEAR ENTIRE ARG
	ILDB B,A	;YES, SO SCAN ARG
	JUMPN B,.-1	;FOR FIRST NULL
FILL:	SKIPA B,[0]	;PICK UP NULL
	IDPB B,A	;FILL REST OF ARG WITH NULLS
	CAME A,[010700,,USER+7]	;AT END OF ARG?
	JRST .-2	;NO, KEEP FILLING
	TDZ Z,[377777,,377772]	;IGNORE UNUSED BITS
	SETZM OLDFCN	;INITIALIZE TYPES ALREADY TRIED
	SETOM LASTB	;INITIALIZE NON-MULTIPLE-MATCH VARIABLE
	MOVE A,SITE	;IS SITE ARG NULL?
	TLNN A,774000	;TEST FIRST CHAR TO SEE
	JSR DEFSIT	;YES, USE DEFAULT SITE
	MOVE A,SITE+7	;TEST LAST CHAR
	TRNE A,376	;IS IT NULL?
	JRST S2LONG	;NO, SITE ARG TOO LONG
	PUSHJ P,RECSIT	;TRY TO RECOGNIZE SITE NAME
	 JRST RECLOS	;UNRECOGNIZED SITE NAME
	SKIPA
NOHOST:	SETZM GSITE	;MATCH NO SITES IF LOCAL SITE NOT A HOST
	PUSHJ P,HASHGS	;HASH THE SITE NAME
	MOVEM A,SITHSH	;SAVE FOR USE IN FILTERING MATCHES
	MOVSI A,100001	;OLD FILE, SHORT FORM, STRING
	HRROI B,[ASCIZ \<UNSUPPORTED>MAILBOX.HASH\]
	GTJFN
	 JRST NOHASH
	MOVEM A,HSHJFN	;SAVE JFN OF HASH TABLE FILE
	MOVE B,[44B5+1B19]	;36.-BIT BYTES, READ
	OPENF	;OPEN FILE OF HASHED USER NAMES
	 JRST NOHASH
	SIZEF		;GET FILE SIZE
	 JRST NOHASH
	MOVEM B,HSHSIZ	;FILE LENGTH INDICATES HASH MASK
	PUSHJ P,HASH	;HASH USER ARG
	MOVEM A,HASHP	;SAVE HASH PNTR
	HRROI A,TFNAME	;INPUT STRING POINTER
	HRRZ B,HSHJFN	;THE HASH FILE JFN
	MOVE C,[111000,,1]	;DEV, DIR, NAME,,PUNCTUATE
	JFNS		;JFN TO STRING CONVERSION
	MOVE C,[440700,,[ASCIZ \.TEXT\]]	;EXTENSION
	SKIPA		;HAVE TO ILDB FIRST
	IDPB D,A	;DEPOSIT CHAR OF EXTENSION
	ILDB D,C	;GET NEXT CHAR
	JUMPN D,.-2	;LOOP UNTIL NULL CHAR
	MOVE C,[10,,1]	;VERSION,,PUNCTUATE
	JFNS		;JFN TO STRING CONVERSION
	MOVSI A,100001	;OLD FILE, SHORT FORM
	HRROI B,TFNAME	;FILE NAME POINTER
	GTJFN
	 JRST NOTEXT
	MOVEM A,TXTJFN	;SAVE JFN OF TEXT FILE
	MOVE B,[7B5+1B19]	;7-BIT BYTES, READ
	OPENF
	 JRST NOTEXT
	MOVEI A,400000	;SELF FORK HANDLE
	MOVE B,[LEVTAB,,CHNTAB]	;PI TABLE PNTRS
	SIR		;SET UP TABLES
	EIR		;ENABLE PI SYSTEM
	MOVSI B,(1B10)	;EOF = CHANNEL 10
	AIC		;ACTIVATE CHANNEL
	MOVE A,[USER,,GUSER]	;TRANSFER ARG...
	BLT A,GUSER+7	;...INTO SAFE PLACE
	JRST GOTTYP	;SKIP GETTING NEXT THE FIRST TIME

NXTTYP:	JUMPL Z,ALDONE	;NO NEXT TYPE IF NO HUNTING
	IORB Z,OLDFCN	;COMBINE JUST TESTED WITH PREVIOUS
	TRZE Z,400000	;CLEAR & SKIP IF NIC ID NOT DONE
	TRCA Z,5	;DO ALL ELSE IF NIC ID DONE
	MOVE Z,TYPFCN(Z)	;PICK UP NEW SITE TYPE
	JUMPE Z,ALDONE	;ALL DONE (RETURN FROM SUBR)
GOTTYP:	MOVE A,HSHJFN	;SET UP TO FIND A HASH MATCH
	HRRZ B,HASHP	;THE HASH POINTER
EOFRET:	SFPTR		;GET HERE IF EOF (WRAP-AROUND)
	 JRST NOHASH
NXTHSH:	SETZM NICFLG	;RESET THIS FLAG
	MOVE A,HSHJFN	;LOOK AT NEXT HASH ENTRY
HSHBIN:	BIN		;TAG IS FOR PSI ROUTINE IF EOF
	JUMPE B,NXTTYP	;NO MORE HASH MATCHES WITH CURRENT SITE TYPE
	TLNN B,-1	;IS SITE NUMBER 0?
	JRST [	TRNN Z,400000	;YES, HASH IS A NIC ID
		JRST NXTHSH	;BUT WE DON'T ACCEPT THEM
		SETOM NICFLG	;REMEMBER THIS IS NIC ID
		JRST HASHOK]	;OH YES WE DO
	HLRZ C,B	;GET SITE NUMBER
	CAMN C,SITHSH	;IS SITE HASH SAME?
	JRST [	TRNN Z,1	;YES, ACCEPTING EXACT MATCH?
		JRST NXTHSH	;NO, GO TO NEXT HASH ENTRY
		JRST HASHOK]	;YES
	TRNN Z,4	;ACCEPTING OTHERS?
	JRST NXTHSH	;NO, GO TO NEXT HASH ENTRY
;SITE HASH MATCHES, CHECK TEXT FILE FOR FULL MATCH
HASHOK:	MOVE A,TXTJFN	;PREPARE TO SEEK A TEXT MATCH
	HRRZS B		;BYTE POINTER (CHAR COUNT) FROM HASH ENTRY
	MOVEM B,TXTPTR	;SAVE FOR LATER
	MOVEM B,STXPTR	;TWO COPIES NEEDED
	SFPTR
	 JRST NOTEXT
	SETZM USER	;CLEAR OUT USER AND SITE NAME BUFFER
	MOVE B,[USER,,USER+1]
	BLT B,USER+17
	HRROI B,USER	;INPUT BUFFER
	MOVNI C,100	;BYTE COUNT
	SIN
	MOVE A,[440700,,USER]	;SCANS ENTRY FROM TEXT FILE
	MOVE B,[440700,,GUSER]	;SCANS ARG
USRLUP:	ILDB C,A
	ILDB D,B
	CAMN C,D	;DO CHARS OF USER NAME MATCH?
	JRST USRLUP	;YES, CONTINUE
	JUMPN D,NXTHSH	;USER IS TOO SHORT
	CAIE C,"@"	;TERMINATION?
	JRST NXTHSH	;NO, USER DOESN'T MATCH
	SKIPE NICFLG	;TRYING TO MATCH A NIC ID?
	JRST GOTIT	;WE KNOW IT'S AN ACCEPTABLE NIC ID
	SETCM B,Z	;ARE WE ACCEPTING ALL NORMAL SITES?
	TRNN B,5	;OTHERS + GIVEN
	JRST GOTIT	;WE DON'T CARE WHAT SITE IT IS
	MOVE B,[440700,,GSITE]	;SCANS SITE ARG
SITLUP:	ILDB C,A
	ILDB D,B
	CAMN C,D	;DO CHARS OF SITE NAME MATCH?
	JRST SITLUP	;YES, CONTINUE
	JUMPN D,GOTIT2	;SITE IS TOO SHORT
	CAIE C,11	;TAB
	CAIN C,12	;OR LF
	JRST GOTIT1	;MEANS WE HAVE MATCH
	CAIE C,15	;CR
	CAIN C,37	;EOL
	JRST GOTIT1	;ALSO MEAN MATCH
	CAIE C,UIDCHR	;AS DOES USER ID CHAR
	CAIN C,BRKCHR	;OR MAILBOX BREAK CHAR
	JRST GOTIT1	;ALSO MEAN MATCH
GOTIT2:	TRNN Z,4	;ACCEPTING OTHER SITES?
	JRST NXTHSH	;NO
	JRST GOTIT	;YES

GOTIT1:	TRNN Z,1	;ACCEPTING GIVEN SITE?
	JRST NXTHSH	;NO
GOTIT:
;MATCH IS COMPLETE, NOW LOOK BACK IN TEXT FOR MAILBOX
	MOVE A,TXTJFN	;JFN OF TEXT FILE
SCNLUP:	MOVEI D,200	;HOW MANY CHARS TO TRY REGRESSING
	CAMLE D,TXTPTR	;BUT ARE THERE THAT MANY?
	MOVE D,TXTPTR	;NO, JUST TAKE WHAT THERE IS
	JUMPE D,NOTEXT	;INITIAL BREAK CHAR MISSING IN TEXT FILE
	MOVN B,D
	ADDB B,TXTPTR	;BACK UP TEXT FILE PNTR
	SFPTR
	 JRST NOTEXT
	HRROI B,SITE	;SITE IS EASY PLACE TO SHUFFLE INFO FROM
	MOVNI C,300	;CHAR COUNT
	SIN		;READ IN A BLOCK OF TEXT
	MOVE B,[440700,,SITE]	;PREPARE TO SCAN THE BLOCK
	MOVEI E,0	;REMEMBERS BYTE POINTER OF BREAK CHARS
	MOVE 13,[BRKSCH,,10]	;WHERE TO LOAD FOLLOWING CODE
	BLT 13,13	;RUN SEARCH LOOP IN ACS
	JRST 10		;START IT

BRKSCH:	ILDB C,B	;PICK UP CHAR
	CAIE C,BRKCHR	;IS IT BREAK CHAR?
	SOJG D,10	;NO, LOOP
	JRST GOTBRK	;YES, EXIT

GOTBRK:	JUMPE D,NOBRK	;GOT BREAK CHAR LOC, IF ANY
	MOVE E,B	;SAVE LOC
	SOJG D,10	;LOOK FOR A LATER ONE
NOBRK:	JUMPE E,SCNLUP	;HAVE TO GO FURTHER BACK
;NOW E HAS BYTE PNTR TO LAST BREAK BEFORE GOOD USER CHARS
	SKIPA	;E IS OK FIRST TIME THROUGH
SKIPIT:	IBP E	;GO TO NEXT CHAR
	MOVE B,E	;MAKE A WORKING COPY OF E
	ILDB C,B	;PEEK AT CHAR
	CAIE C,12	;LF
	CAIN C,15	;CR
	JRST SKIPIT	;SKIP OVER THESE CHARS
	CAIE C,11	;TAB
	CAIN C,37	;EOL
	JRST SKIPIT	;OVER THESE TOO
	CAIN C,";"	;IS THIS A COMMENT?
	JRST [	ILDB C,E	;YES, SCAN PAST IT
		CAIE C,12
		CAIN C,15
		JRST SKIPIT	;LF OR CR TERMINATED COMMENT
		CAIE C,11
		CAIN C,37
		JRST SKIPIT	;TAB OR EOL TERMINATED IT
		JRST .]	;STILL IN COMMENT, LOOP BACK TO JRST [ ]
;NOW COMPUTE CHAR POSITION OF MAILBOX IN TEXT FILE
	MOVS B,E	;SITE+N,,POS0700
	LSHC B,-22	;RIGHT JUSTIFY SITE+N
	SUBI B,SITE	;GET N = WORDS FROM START OF SITE BUFFER
	IMULI B,5	;5 ASCII CHARS PER WORD
	LSH C,-36	;RIGHT JUSTIFY BYTE POS
	SUBI C,44	;MINUS BITS USED
	IDIVI C,7	;MINUS CHARS USED
	SUB B,C		;CHAR COUNT FROM START OF SITE BUFFER
	ADD B,TXTPTR	;GETTING CHAR POSITION IN TEXT FILE
	CAMN B,LASTB	;SAME AS LAST TIME?
	JRST NXTHSH	;YES, THIS USER ALREADY MATCHED
	MOVEM B,LASTB	;SAVE FOR NEW MATCH TESTING
	SETZM USER
	MOVE B,[USER,,USER+1]
	BLT B,USER+7	;CLEAR ALL OF USER NAME BUFFER
	MOVE B,[440700,,USER]	;PREPARE TO LOOK FOR @
	SKIPA	;C INVALID FIRST TIME THROUGH
LOOK1:	IDPB C,B	;SALT USER NAME CHAR
	ILDB C,E	;PICK UP NEXT CHAR
	CAIE C,"@"	;END OF USER NAME?
	JRST LOOK1	;NO, LOOP
	MOVE D,[440700,,SITE]	;PREPARE TO LOOK FOR SITE NAME END
	SKIPA	;C INVALID FIRST TIME THROUGH
LOOK2:	IDPB C,D
	ILDB C,E
	CAIE C,12	;LF
	CAIN C,15	;CR
	JRST LOOK3	;THESE MEAN END OF SITE AND NO ID
	CAIE C,11	;TAB
	CAIN C,37	;EOL
	JRST LOOK3	;SO DO THESE
	CAIE C,UIDCHR	;IS IT TIME FOR ID NUMBER?
	JRST LOOK2	;NO, THIS CHAR IS MORE SITE INFO
	MOVE A,E	;PREPARE TO GET "USER ID NUMBER"
	MOVEI C,12	;RADIX
	NIN
LOOK3:	 SETOM B	;FAILURE DEFAULT NUMBER
	CAMN B,[-2]	;IS MAILBOX A GROUP NAME?
	JRST GROUP	;YES, FUDGE UP FILE NAME
	HRRZ A,Z	;MATCH TYPE USED
	MOVE C,STXPTR	;CHAR COUNT WHERE USER MATCHED
	CAMN C,LASTB	;CHAR COUNT WHERE MAILBOX STARTED
	TLO A,1		;SET FLAG SAYING ARG = MAILBOX
LOOK4:	MOVEI C,	;NULL CHAR
	IDPB C,D	;OVERWRITE OLD INFO
	CAMG D,[350700,,SITE+7]	;TRUE WHEN 1 BYTE PAST SITE BUFFER
	JRST .-2	;CLEAR OUT REST OF SITE BUFFER
;NOW WE ARE DONE, WITH USER NAME IN USER,
;SITE NAME IN SITE, USER ID NUMBER IN B, MATCH USED IN A
	POPJ P,

ALDONE:	MOVEI B,	;ALL DONE, NO MORE MATCHES
FINISH:	SETOM A		;ALL
	CLOSF
	 JFCL
	RLJFN
	 JFCL
	MOVE A,B	;PUT ERROR NUMBER IN A
	POPJ P,

GROUP:	MOVE D,[440700,,USER]	;PREPARE TO COPY GROUP'S FILE NAME
	LDB C,A		;PICK UP NIN TERMINATOR
	SKIPA
	ILDB C,A	;PICK UP NEXT CHAR
	CAIE C,";"	;SEMICOLON FLAGS START OF FILE NAME
	JRST .-2	;LOOP LOOKING FOR SEMICOLON
	SKIPA
GROUP1:	IDPB C,D	;COPY FILE NAME CHAR
	ILDB C,A	;PICK UP NEXT TEXT FILE CHAR
	CAIE C,11	;TAB
	CAIN C,12	;LF
	JRST GROUP2	;THESE SAY FILE NAME IS DONE
	CAIE C,15	;CR
	CAIN C,37	;EOL
	SKIPA		;SO DO THESE
	JRST GROUP1
GROUP2:	MOVNI A,1	;GROUP MATCH IS LIKE ERROR OF TYPE 1
	JRST LOOK4

S2LONG:	MOVNI B,2	;SITE NAME TOO LONG
	JRST FINISH

RECLOS:	MOVNI B,3	;DIDN'T RECOGNIZE SITE NAME ARG
	JRST FINISH

NOHASH:	MOVNI B,4	;TROUBLE OPENING, READING, ETC. HASH FILE
	JRST FINISH

NOTEXT:	MOVNI B,5	;TROUBLE OPENING, READING, ETC. TEXT FILE
	JRST FINISH

DEFSIT:	0	;SITE NOT SPECIFIED, SO USE LOCAL HOST NAME
	MOVE A,[SIXBIT \LHOSTN\]
	SYSGT		;GET LOCAL HOST NUMBER
	JUMPE B,NOHOST	;NOT RECOGNIZED BY TENEX
	MOVE B,A	;HOST NUMBER
	HRROI A,SITE	;BYTE PNTR FOR STRING
	CVHST		;CONVERT TO STRING
	 JRST NOHOST	;NO STRING FOUND
	HRRZS A		;GET LAST WORD WRITTEN
	CAIL A,SITE+8	;COMPARE TO TABLE END
	JRST S2LONG	;SITE STRING TOO LONG
	JRST @DEFSIT	;RETURN

;FOLLOWING TABLE IS INDEXED BY CURRENT SITE MATCH TYPE
;AND YIELDS NEXT SITE TYPE
;400000 = NIC ID (BUT IS NOT ON WHEN THIS TABLE IS INDEXED INTO)
;4 = OTHER SITES, 1 = SPECIFIED SITE ONLY

TYPFCN:	1
	4
	0
	0
	1
	400000
	0
	0

OLDFCN:	0	;ACCUMULATES SITE TYPES ALREADY USED

;RECSIT TRIES TO RECOGNIZE THE ASCIZ SITE NAME IN SITE
;RETURNS +1 IF FAILS, +2 IF WINS WITH PROPER SITE NAME
;(POSSIBLY CONVERTED FROM NICKNAME ARG) IN GSITE
;IF ARG IS (NIC ID) THEN RETURNS +2 BUT GSITE IS ZEROED

RECSIT:	SETZM GSITE	;CLEAR OUT SITE BUFFER
	MOVE A,[GSITE,,GSITE+1]
	BLT A,GSITE+7
	MOVE A,SITE
	MOVE B,SITE+1
	CAMN A,[ASCII \(NIC \]
	CAME B,[ASCII \ID)\]
	SKIPA
	JRST RECRTN	;ARG IS (NIC ID), SO JUST RETURN
	MOVEI A,.GTHSN		;TRANSLATE HOST NAME
	HRROI B,SITE		;SOURCE SITE
	GTHST%			;C/NUMBER, D/STATUS
	 POPJ P,		;FAILED
	HRROI A,GSITE		;YES, MATCH IS DONE
	MOVE B,C
	CVHST			;GET PROPER HOST NAME IN CASE NICKNAME ARG
	 POPJ P,		;FAILURE
	TRNN D,HS%NCK		;SINGLE SKIP IF NICKNAME
RECRTN:	 AOS (P)		;SITE NAME IS RECOGNIZED
	AOS (P)
RECRET:	POPJ P,

LEVTAB:	RETPC1
	RETPC2
	RETPC3

RETPC1:	0
RETPC2:	0
RETPC3:	0

CHNTAB:	BLOCK 12
	1,,EOFINT	;PI LEVEL,,SERVICE ROUTINE ADDR
	BLOCK 31

EOFINT:	HRRZ C,RETPC1	;EOF IS CHANNEL 10 INTERRUPT
	CAIE C,HSHBIN	;WERE WE EXECUTING THIS INSN?
	CAIN C,HSHBIN+1	;TRY +1 ALSO FOR TIMING SAFETY
	SKIPA		;YES WE WERE
	DEBRK		;NO, NOT READING HASH FILE
	MOVEI B,EOFRET	;NEW RETURN PC
	MOVEM B,RETPC1	;STORE IT FOR TENEX TO SEE
	MOVEI B,	;NEW HASH FILE POINTER
	DEBRK	;DISMISS TO EOFRET

;HASH USER NAME ARG, CALLED WITH PUSHJ P,HASH
HASH:	MOVSI A,-8	;SCANS ARG
	MOVEI B,	;B GETS GOODIES
	XOR B,USER(A)
	AOBJN A,.-1	;DO ALL WORDS
	TLC B,(B)	;HASH IS XOR OF ALL HALFWORDS
	HLRZ A,B	;DISCARD LEFT HALF
	IDIV A,HSHSIZ	;MODULO HASH TABLE SIZE
	MOVE A,B	;RESULT IN A
	POPJ P,		;RETURN

;HASH SITE NAME IN GSITE, CALLED WITH PUSHJ P,HASHGS
HASHGS:	SKIPN A,GSITE	;GSITE = 0 FOR (NIC ID)...
	POPJ P,		;...AND ITS HASH IS ZERO
	MOVSI A,-8	;SCANS ARG
	MOVEI B,	;B GETS GOODIES
	XOR B,GSITE(A)
	AOBJN A,.-1	;DO ALL WORDS
	TLC B,(B)	;HASH IS XOR OF ALL HALFWORDS
	HLRZ A,B	;DISCARD LEFT HALF
	SKIPN A
	AOS A		;ONLY (NIC ID) MAY HASH TO ZERO
	POPJ P,		;RETURN, HASH VALUE IN A

;BUILD IS RUN BY A PRIVILEGED USER, ACCPTS THE FILE NAME OF
;AN ASCII MAILBOX.TEXT FILE, AND CREATES A MAILBOX.HASH FILE WITH
;THE SAME VERSION NUMBER

BUILD:	RESET		;START LOC TO BUILD NEW HASH FILE
	MOVE P,[-PDLL,,PDL-1]
	HRROI A,[ASCIZ \Rebuild MAILBOX.HASH file
Type MAILBOX.TEXT file name:
\]
	PSOUT
	MOVEI A,ETAB	;LONG FORM
	SETZ B,
	GTJFN
BUILD1:	 JSR [	0		;STORED PC FOR DEBUGGING
		MOVEI A,.PRIOU
		HRLOI B,.FHSLF
		SETZ C,
		ERSTR
		 JFCL
		 JFCL
		HRROI A,[ASCIZ/
/]
		PSOUT
		JRST BUILD]	;AND START OVER
	MOVEM A,TXTJFN	;STORE JFN OF TEXT FILE
	MOVE B,[7B5+1B19]	;7-BIT BYTES, READ
	OPENF
	 JRST BUILD1	;START OVER ON ERROR
	HRROI A,HFNAME	;PNTR TO HASH FILE NAME STRING...
	HRRZ B,TXTJFN	;...WHICH IS ABOUT TO APPEAR
	MOVE C,[111000,,1]	;DEV, DIR, NAME
	JFNS		;GET STRING
	MOVEM A,EXTPTR	;SAVE PNTR FOR RENAMING .TEMP TO .HASH
	MOVE C,[440700,,[ASCIZ \.TEMP\]]	;EXTENSION
	SKIPA		;D INVALID FIRST TIME
	IDPB D,A	;SALT CHAR OF EXTENSION
	ILDB D,C	;PICK UP NEXT CHAR
	JUMPN D,.-2	;LOOP UNTIL NULL
	MOVE C,[10,,1]	;VERSION
	JFNS
;NOW HAVE FILE NAME FOR NEW HASH FILE
	MOVSI A,400001	;FOR OUTPUT, SHORT FORM
	HRROI B,HFNAME
	GTJFN
	 JSR OUTLOS	;UNABLE TO GET JFN FOR NEW HASH FILE
	MOVEM A,HSHJFN	;SAVE JFN OF HASH FILE
	HRLI A,12	;FDBSIZ DISPLACEMENT
	SETOM B		;CHANGE ALL BITS
	MOVEI C,	;NEW LENGTH = 0
	CHFDB
;MUST CHFDB BEFORE OPENF, OR ANY LARGER FILE LENGTH COPIED INTO
;JFN STORAGE WHEN FILE OPENED WILL BE RESTORED WHEN FILE CLOSED
	MOVE A,HSHJFN
	MOVE B,[44B5+1B19+1B20+1B26]
		;36.-BIT BYTES, READ, WRITE, WAIT
	OPENF
	 JSR OUTLOS
	SETOM A		;REMOVE PAGE
	HRLZ B,HSHJFN	;FROM HASH FILE
CLRLUP:	PMAP		;CLEAR FILE
	AOS B		;NEXT PAGE
	TRNN B,1000	;DONE ALL PAGES?
	JRST CLRLUP	;NO, LOOP
	MOVE A,TXTJFN
	MOVEI B,	;READ TEXT FILE FROM BEGINNING
	SFPTR
	 JSR @BUILD1
	MOVEI D,	;COUNTS NAME@SITE LINES
SCAN1:	BIN		;READ A CHAR
	JUMPE B,EOF1	;NULL CHAR = EOF
	CAIE B,12	;LF
	CAIN B,15	;CR
	JRST SCAN1	;IGNORE THESE AT THIS POINT
	CAIE B,11	;TAB
	CAIN B,37	;EOL
	JRST SCAN1	;IGNORE THESE TOO
	CAIN B,BRKCHR	;BREAK BETWEEN MAILBOX BLOCKS
	JRST SCAN1	;IGNORE THESE TOO
	CAIE B,";"	;DON'T COUNT COMMENT LINES
	AOS D		;COUNT THE VALID LINE
	PUSHJ P,SCAN2	;READ TO LF, CR, TAB OR EOL
	JRST SCAN1	;LOOP UNTIL EOF

SCAN2:	BIN		;READ CHARS THROUGH FIRST LF, CR, TAB OR EOL
	CAIE B,12	;LF
	CAIN B,15	;CR
	POPJ P,		;RETURN
	CAIE B,11	;TAB
	CAIN B,37	;EOL
	POPJ P,		;RETURN
	JRST SCAN2	;LOOP

EOF1:	MOVEI A,101	;PRIMARY OUTPUT (TTY)
	MOVE B,D	;COUNT OF VALID LINES
	MOVEI C,12	;RADIX
	NOUT
	 JFCL
	HRROI A,[ASCIZ \. text entries, hash table = \]
	PSOUT
	LSH B,1		;COMPUTE LENGTH OF HASH TABLE FILE
	MOVEI C,8	;RADIX
	MOVEI A,101	;OUTPUT TO TTY
	NOUT
	 JFCL
	HRROI A,[ASCIZ \ words
\]
	PSOUT
	MOVEM B,HSHSIZ	;SAVE HASH MASK
	MOVE A,HSHJFN	;SET UP ROUT ARGS
	SOS C,B		;LAST WORD IN FILE
	MOVEI B,	;INNOCUOUS ZERO
	ROUT		;SO SUBR WILL GET CORRECT FILE SIZE
	MOVE A,TXTJFN	;SET TEXT FILE PNTR...
	MOVEI B,	;...TO BEGINNING AGAIN
	SFPTR
	 JSR @BUILD1
	SKIPA		;JUMP INTO PROCESSING TEXT
SCAN4:	PUSHJ P,SCAN2	;READ TO LF, CR, TAB OR EOL
SCAN5:	MOVE A,TXTJFN	;A MAY HAVE HSHJFN, SO RESTORE
SCAN7:	BIN		;READ IN A TEXT FILE CHAR
	JUMPE B,EOF2	;NULL CHAR = EOF
	CAIN B,";"	;START OF COMMENT LINE?
	JRST SCAN4	;YES, IGNORE REST OF LINE
	CAIE B,12	;LF
	CAIN B,15	;CR
	JRST SCAN7	;IGNORE THESE CHARS
	CAIE B,11	;TAB
	CAIN B,37	;EOL
	JRST SCAN7	;IGNORE THESE ALSO
	CAIN B,BRKCHR	;BREAK BETWEEN MAILBOXES
	JRST SCAN7	;IGNORE THESE ALSO
	MOVE C,B	;SAVE THE CHAR
	RFPTR		;READ FILE POINTER
	 JSR @BUILD1
	MOVEM B,TXTPTR	;SAVE TEXT FILE PNTR WHERE WE FOUND CHAR
	SETZM USER	;CLEAR OUT USER AND SITE BUFFERS
	MOVE B,[USER,,USER+1]	;IN PREPARATION FOR
	BLT B,SITE+7	;PROCESSING USER@SITE LINE
	MOVE B,C	;RETRIEVE CHAR AS IF FROM BIN JSYS
	MOVE C,[440700,,USER]	;PREPARE TO INPUT USER NAME
RUSER:	IDPB B,C	;SALT GOOD CHAR OF USER NAME
	CAMN C,[010700,,USER+7]	;AT END OF USER BUFFER?
	JRST U2MOBY	;YES, ABORT
	BIN		;GET ANOTHER CHAR
	CAIE B,"@"	;END OF USER NAME?
	JRST RUSER	;NO, KEEP ACCUMULATING CHARS
	MOVE C,[440700,,SITE]	;YES, NOW READ IN SITE NAME
RSITE:	BIN		;READ IN CHAR
	CAIE B,12	;LF
	CAIN B,15	;CR
	JRST SALT2	;END OF SITE NAME
	CAIE B,11	;TAB
	CAIN B,37	;EOL
	JRST SALT2	;THESE ALSO MEAN SITE NAME END
	CAIN B, BRKCHR	;BREAK CHAR (THO WOULD BE WEIRD TO FIND IT HERE)
	JRST SALT2	;THESE ALSO MEAN SITE NAME END
	CAIN B,UIDCHR	;DESIGNATES USER ID NUMBER FIELD...
	JRST SALT1	;...SO DONE WITH SITE NAME
	IDPB B,C	;ANOTHER GOOD SITE NAME CHAR
	CAMN C,[010700,,SITE+7]	;SITE NAME BUFFER OVERFLOWN?
	JRST S2MOBY	;YES, ABORT
	JRST RSITE	;NO, KEEP ACCUMULATING SITE

SALT1:	PUSHJ P,SCAN2	;SKIP OVER USER ID NUMBER
SALT2:	PUSHJ P,RECSIT	;TRY TO RECOGNIZE SITE NAME
	 JRST SUNREC	;TOMB OF THE UNKNOWN SITE
	 JRST NICKNM	;NICKNAME
;ABOVE RECSIT CALL COULD BE SPED UP BY READING IN ALL HOST
;NAMES AT START OF BUILD ROUTINE
	PUSHJ P,HASHGS	;HASH THE SITE NAME
	HRRM A,SALT4	;SAVE SITE HASH
	PUSHJ P,HASH	;HASH CODE USER NAME
;NOW HAVE HASH ADDRESS IN A
	MOVE E,A	;SAVE HASH ADDR
	SKIPA A,HSHJFN	;LOAD HASH FILE JFN & SKIP AOS
SALT3:	AOS E,F		;TRY NEXT SLOT
	IDIV E,HSHSIZ	;LIMIT ADDRESS TO LEGAL VALUES
	MOVE C,F	;HASH BYTE ADDRESS IS REMAINDER
	RIN		;LOOK AT WHAT'S THERE
	JUMPN B,SALT3	;LOOP IF SLOT NOT FREE
	SOS B,TXTPTR	;TEXT FILE BYTE COUNT PNTR
SALT4:	HRLI B,.	;SITE HASH VALUE
	ROUT		;DO THE SALTING INTO HASH FILE
	JRST SCAN5	;LOOP FOR NEXT USER@SITE LINE

EOF2:	MOVE A,EXTPTR	;EXTENSION CHAR PNTR
	SKIPA C,[440700,,[ASCIZ \.HASH\]]	;NEW EXTENSION
	 IDPB D,A
	ILDB D,C
	JUMPN D,.-2	;REPLACE EXTENSION CHARS UNTIL NULL
	MOVSI A,1	;SHORT FORM
	HRROI B,HFNAME	;NEW HASH FILE NAME
	GTJFN
	 JSR OUTLOS	;UNABLE TO GET JFN TO RENAME NEW HASH FILE
	MOVE B,A	;SHUFFLE ARGS
	MOVE A,HSHJFN		;CLOSE JFN
	HRLI A,(CO%NRJ)		;BUT DON'T RELEASE IT
	CLOSF		;BECAUSE CAN'T RENAME OPEN FILES
	 JSR OUTLOS
	MOVE A,HSHJFN
	RNAMF		;RENAME .TEMP FILE TO BE .HASH
	 JSR OUTLOS
	SETOM A		;ALL
	CLOSF
	 JSR OUTLOS
	RLJFN
	 JSR OUTLOS
	HRROI A,[ASCIZ \OK \]
	PSOUT
	HALTF
	JRST .-1

SUNREC:	HRROI A,[ASCIZ \Unrecognized site\]
	JRST S2MOB1

NICKNM:	HRROI A,[ASCIZ \Site nicknames not allowed\]
	JRST S2MOB1

U2MOBY:	MOVEI A,	;NULL
	DPB A,C		;SO USER NAME IS NULL-TERMINATED
	HRROI A,[ASCIZ \User name too long: \]
	PSOUT
	HRROI A,USER
	JRST OUTL1

S2MOBY:	MOVEI A,	;NULL
	DPB A,C		;SO SITE NAME IS NULL-TERMINATED
	HRROI A,[ASCIZ \Site name too long\]
S2MOB1:	PSOUT
	HRROI A,[ASCIZ \, user \]
	PSOUT
	HRROI A,USER
	PSOUT
	HRROI A,[ASCIZ \, site: \]
	PSOUT
	HRROI A,SITE
	JRST OUTL1

OUTLOS:	0	;STORED PC FOR DEBUGGING
	MOVEI A,.PRIOU
	HRLOI B,.FHSLF
	ERSTR
	 JFCL
	 JFCL
	HRROI A,[ASCIZ/
/]
OUTL1:	PSOUT
	HALTF
	JRST .-1

;GTJFN TABLE FOR BUILD TO OPEN MAILBOX.TEXT FILE WITH
ETAB:	GJ%OLD!GJ%CFM
	100,,101	;INJFN,,OUTJFN
	0		;DEV
	0		;DIR
	-1,,[ASCIZ \MAILBOX\]	;NAME
	-1,,[ASCIZ \TEXT\]	;EXT
	0		;PROT
	0		;ACCT
	0		;JFN

EXTPTR:	0	;HASH FILE EXTENSION PNTR FOR RENAMING
NICFLG:	0	;-1 WHEN SUBR IS LOOKING AT A NIC ID IN TEXT FILE
LASTB:	0	;CHAR POS OF LAST MAILBOX RETURNED, TO AVOID REPEATS
SITHSH:	0	;HASH VALUE OF SITE WE ARE TRYING TO MATCH
HSHSIZ:	0	;SIZE OF HASH TABLE FILE (WORDS)
HASHP:	0	;SAVED PNTR INTO HASH FILE
TXTPTR:	0	;SAVED PNTR INTO TEXT FILE
STXPTR:	0	;COPY OF TXTPTR NOT CLOBBERED BY SCAN FOR MAILBOX
HSHJFN:	0	;JFN OF HASH FILE
TXTJFN:	0	;JFN OF TEXT FILE
HFNAME:		;COMPUTED HASH FILE NAME...
TFNAME:	BLOCK 20	;...OR TEXT FILE NAME
GUSER:	BLOCK 8	;GIVEN USER ARG TO SUBR, SAVED FROM VOLATILE USER BUFFER
GSITE:	BLOCK 8	;GIVEN SITE ARG
PAT:	BLOCK 20
PDL:	BLOCK PDLL

END <4,,ENTVEC>