.PSECT $MAIL .TITLE $MAIL - MAIN LINE CODE FOR MAIL .IDENT /781123/ ; ; THIS CODE HAS BEEN DEVELOPED BY THE COMPUTING ; GROUP OF THE ATMOSPHERIC SCIENCES DIVISION, ; ALBERTA RESEARCH. THIS WORK FUNDED BY THE ; ALBERTA WEATHER MODIFICATION BOARD. ; ; THERE IS EXPLICITLY NO COPYRIGHT ON THIS SOFTWARE, ; AND ITS DISTRIBUTION IS ENCOURAGED. NO RESPONSIBILITY ; NOR GUARANTEE IS MADE OR ASSUMED BY THE AUTHOR, OR ; BY ALBERTA RESEARCH. ; ; SUGGESTIONS OR CHANGES ARE INVITED, AND WILL BE ; DISTRIBUTED TO OTHER USERS OF THIS SOFTWARE THROUGH ; THE DECUS IAS/RSX SPECIAL INTEREST GROUP. ; ; ; VERSION: 781020 ; WRITTEN BY: W. KORENDYK ; DATE WRITTEN: 1-NOV-78 ; ; ; ; MODIFICATIONS: ; ; CODE NAME DATE ; ;+ ; ; *** - MAIN -- MAIL'S MAIN LINE CODE ; ; THIS IS THE MAIN-LINE CODE FOR MAIL...WITH ITS ; LITTLE SUPPORT SUBROUTINES. ; ;- ; ; A HANDY RULE-OF-THUMB: THROUGHOUT THE MAIN-LINE, ; R0 POINTS TO THE NEXT CHARACTER IN THE COMMAND LINE ; ESC=33 .DSABL GBL .MCALL ENTER,LEAVE .MCALL TINIT,TTYOUT .MCALL EXIT$S,GMCR$ .MCALL FCSMC$,IOERR$,FILIO$,FDOF$L,FCSBT$ FCSMC$ IOERR$ FILIO$ FDOF$L FCSBT$ .MCALL MAIGBL MAIGBL ; ; ASSORTED ERROR MESSAGES ; .NLIST BEX ERR1: .ASCII /PROPER COMMAND SYNTAX IS ->MAIL [FROM] [TO PERSON]/ LERR1 =.-ERR1 ; LETTER: .BYTE LLET .ASCII /LETTER>/ LLET =.-LETTER-1 ; RSVPMT: .BYTE LRSV .ASCII /DO YOU WANT A REPLY?/ LRSV =.-RSVPMT-1 .EVEN .LIST BEX ; RSVP: .WORD 0 ; R.S.V.P. FLAG ; ; THE GMCR BUFFER ; GMCR: GMCR$ GBUF =GMCR+2 $MAIL: TINIT TTYLUN,TTYEVF ;INITIALIZE TERMINAL OUTPUT FINIT$ ;AND FILE AREAS CLR ACFOUN ;ALL ACCOUNTS FOUND SO FAR ; DIR$ #GMCR,DIRERR ; GET THE COMMAND LINE MOV #GBUF+2,R0 ; AND POINT TO IT 10$: CALL $GNBLK ; GET NEXT NON-BLANK BCS 40$ ; REACHED EOL TST R1 ; ANY BLANKS ENCOUNTERED? BEQ 10$ ; IF EQ, THEN NO 20$: TSTB -(R0) ; POINT TO THE "GOT" CHARACTER CALL ISQUE ; IS FIRST CHARACTER A "?"? BCC 110$ ; IF CC, YES IT WAS CALL ISME ; IS IT A "ME"? BCC 110$ ; IF CC, YES IT WAS MOV R0,-(SP) ; SAVE THE CURRENT POSITION CALL ISTO ; IS IT A "TO "? BCS 25$ ; IF CS, MUST BE A FILE NAME CALL $GNBLK ; SEE IF THERE IS A NAME STRING MOV (SP)+,R0 ; GET BACK THE OLD POINTER BCS 90$ ; IF CS, THEN NO, SO ERROR BR 50$ ; IF CC, THEN THERE IS A NAME STRING 25$: MOV (SP)+,R0 ; GET BACK THE OLD POINTER MOV #INPFDB,R2 ; GET FDB ADDRESS OF INPUT FILE CALL CSPARS ; FILL IN THE DSDS OF INPUT FILE BCS 110$ ; IT DIDN'T WORK MOV R0,-(SP) ; (SAVE FROM FCS) OPEN$R R2,,,,,,IOERR ; TRY TO OPEN THE FILE CALL FDB2FN ; SAVE THAT FILE NAME BLOCK CLOSE$ ,IOERR ; AND CLOSE THE FILE MOV (SP)+,R0 ; (GET BACK THE POINTER) CALL SWITCH ; SEE IF THERE ARE ANY SWITCHES ; ; WE ASSUME THAT CSPARS ADVANCES THE POINTER OVER THE FILE NAME ; BR 55$ ; ; 40$: TSTB -(R0) ; POINT TO THE "GOT" CHARACTER 50$: MOV R0,-(SP) ; SAVE THIS FOR A SECOND MOV #INPFDB,R0 ; THE FDB ADDRESS, MOV #LETTER,R1 ; AND THE PROMPT CLR R2 ; NO STRINGS TO INCLUDE CALL TERM ; THAT TERM SHOULD USE CALL ASKRSV ; ASK IF HE WANTS A REPLY MOV (SP)+,R0 ; GET BACK THE STRING POINTER 55$: CALL $GNBLK ; LOCATE A NAME STRING BCS 60$ ; IF CS, THEN ONE WAS NOT FOUND TSTB -(R0) ; POINT TO THE "GOT" CHARACTER CALL ISTO ; IS IT A "TO "? BCS 90$ ; IF CS, THEN NO CALL $GNBLK ; POINT TO THE NAME STRING BCS 90$ ; IF CS, THEN NOT FOUND TSTB -(R0) ; POINT TO THE "GOT" CHARACTER CALL PRENS ; DISPATCH TO NAME STRING PROCESSOR BR 100$ ; AND THAT IS ALL 60$: CALL ASKWHO ; ASK WHO TO SEND TO BR 100$ ; AND THAT IS ALL 90$: TTYOUT #ERR1,#LERR1 ; SYNTAX MESSAGE 100$: TST ACFOUN ; WHERE ALL THE ACCOUNTS FOUND? BEQ 105$ ; IF EQ, THEN YES CALL NFACT ; NO FINDIE ACCOUNT BR 110$ ; DON'T DELETE THE FILE 105$: CMP #^RMAI,INPFNB+N.FTYP ; IS THIS A TEMPORARY FILE BNE 110$ ; IF NE, THEN NO CALL FN2FDB ; ELSE FILL IN THE FDB DELET$ #INPFDB ; AND DELETE THE FILE 110$: EXIT$S ;THAT IS ALL ; ; SWITCH - SEE IF ANY SWITCHES GIVEN WITH FILE NAME ; ; INPUT: R0 = CURRENT POSITION IN COMMAND STRING ; ; OUTPUT: R0 = NEXT POSITION IN COMMAND STRING ; SWITCH: ENTER R1,R2 ;SAVE WORK REGISTERS CLR RSVP ; ASSUME NO REPLY CMPB #'/,(R0) ; A SWITCH SPECIFIED? BNE 20$ ; NE, THEN NO 1$: CALL $GNBLK ; POINT TO NEXT CHARACTER BCS 10$ ; IF CS, THEN AT EOL TST R1 ; ANY BLANKS? BEQ 1$ ; IF EQ, THEN NO 10$: TSTB -(R0) ; BACK UP POINTER BR 21$ ; 20$: INC RSVP ; INDICATE TO REPLY 21$: LEAVE ;THAT IS ALL RETURN ; ; ; ; ASKRSV - ASK IF WANTS AN RSVP ; ; ASSUMES THAT AN RSVP IS WANTED UNLESS HE EXPLICITLY ; SAYS "NO". ; ASKRSV: ENTER R1 ;WORK REGISTER CLR RSVP ; ASSUME NO RSVP MOV #RSVPMT,R1 ; THE READ PROMPT CALL RDPMPT ; READ REPLY TST TTYSB ; HOW DID IT READ? BMI 5$ ; NOT GOOD CMPB #'N,LINBUF ; AN "N"? BEQ 10$ ; YES CMPB #156,LINBUF ; HOW 'BOUT LC BEQ 10$ ; 5$: INC RSVP ; WANTS A REPLY 10$: LEAVE ; RETURN ; ; ; PRENS - PRE-NAMESTRING PROCESSOR ; ; INPUT: R0 = CURRENT POSITION IN COMMAND STRING ; = START ADDRESS OF THE NAMESTRING ; PRENS: MOV R1,-(SP) ;A WORK REGISTER MOV R0,-(SP) ;SAVE THE POINTER CLR BRKCNT ;NO BRACKETS ENCOUNTERED 1$: CALL $GNBLK ;SPACE DOWN THE LINE BCS 2$ ;ALL THE WAY TO THE EOL CALL CNTBRK ;COUNT THE BRACKETS BR 1$ ;TRY ANOTHER 2$: SUB (SP),R0 ;DETERMINE THE LENGTH DEC R0 ;LESS THE TERMINATOR MOV (SP),R1 ;ADDRESS OF STRING MOVB R0,-(R1) ;INCLUDE STRING LENGTH CALL NAMSTR ;PROCESS NAME STRING MOV (SP)+,R0 ;RESTORE POINTER MOV (SP)+,R1 ;AND WORK REGISTER RETURN ; ; ; NFACT - DID NOT FIND AN ACCOUNT...SO TELL THE ; USER THAT THE LETTER HE ENTERED WILL BE SAVED. ; ; THIS ROUTINE ASSUMES THAT THE INPUT FILE ; NAME IS STILL AT INPFNB. ; NFACT: ENTER R0,R1 ; MOV #INPFDB,R0 ; GET FDB ADDRESS MOV #NFB,R1 ; WHERE TO PUT THE CALL FMTFNM ; FORMATED FILE NAME MOVB #'",(R1)+ ; CLOSE QUOTE MOVB #15,(R1)+ ; CARRIAGE RETURN SUB #NFA,R1 ; GET THE LENGTH TTYOUT #NFA,R1 ; AND OUTPUT IT LEAVE ; RETURN ; ACFOUN: .WORD 0 ; .NLIST BEX NFA: .ASCIZ /LETTER RETAINED IN "/ NFB: .BLKW 16. .EVEN .LIST BEX ; ; CNTBRK -- ROUTINE TO ACCOUNT FOR THE COMMAS OF ; A UIC AND DISTINGUISH FROM DELIMITING COMMAS. ; ; INPUT: R2 = CHARACTER THAT WAS "GOT" LAST ; R0 = POSITION OF NEXT CHARACTER ; ; OUTPUT: IF FOUND TO BE A DELIMITING COMMA, THE ; COMMA IN THE BUFFER IS REPLACED WITH A SPACE. ; CNTBRK: CMPB #'[,R2 ;A "["? BEQ 11$ ;YES CMPB #'],R2 ;HOW 'BOUT "]"? BEQ 12$ ;YES CMPB #',,R2 ;A COMMA? BNE 1$ ;NO TST BRKCNT ;PART OF A UIC? BNE 1$ ;YES MOVB #40,-1(R0) ;NO, MAKE IT A SPACE BR 1$ ;AND CONTINUE 11$: INC BRKCNT ;START OF A UIC BR 1$ ;CONTINUE 12$: DEC BRKCNT ;END OF A UIC 1$: RETURN ;DONE ; BRKCNT: .WORD 0 ;UIC BRACKET COUNT ; ; THE STRING COMPARISON ROUTINES: ISTO, ISME, ISQUE. ; ; ON EACH, THE INPUT IS: ; R0 = START OF STRING ; ; OUTPUTS: ; CARRY CLEAR IFF STRING IS FOUND ; IF CARRY SET, R0 UNCHANGED ; IF CARRY CLEAR, R0 POINTS TO: ; (ISTO) CHARACTER FOLLOWING "TO " ; (ISME) CHARACTER FOLLOWING "ME" ; (ISQUE) CHARCATER FOLLOWING "?" ; .ENABL LSB ISTO: MOV #4$,-(SP) ;FAKE A ROUTINE MOV R0,-(SP) ;SAVE POINTER CMPB #'T,(R0)+ ;A "T" BNE 2$ ;NO CMPB #'O,(R0)+ ; BNE 2$ ; CMPB #40,(R0)+ ;A SPACE BR 1$ ;CHECK OUT ELSEWHERE ; ISME: MOV #ME,-(SP) ;ROUTINE TO USE MOV R0,-(SP) ;SAVE POINTER CMPB #'M,(R0)+ ; BNE 2$ ; CMPB #'E,(R0)+ ; BNE 2$ ; CMPB #40,(R0) ; BEQ 3$ ; CMPB #CR,(R0) ; BEQ 3$ ; CMPB #ESC,(R0) ; BR 1$ ; ; ISQUE: MOV #QUE,-(SP) ; MOV R0,-(SP) ;SAVE THE POINTER CMPB #'?,(R0)+ ; 1$: BEQ 3$ ; 2$: MOV (SP)+,R0 ;RESTORE POINTER TST (SP)+ ;POP ROUTINE NAME SEC ; BR 4$ ; 3$: TST (SP)+ ;REMOVE OLD POINTER CALL @(SP)+ ;CALL THE APPROP ROUTINE CLC ;INDICATE SUCCESS 4$: RETURN ; .DSABL LSB ; ; ASKWHO - ROUTINE TO PROMPT FOR A NAME STRING AT THE ; TERMINAL AND PROCESS IT. ; ; WHOTO: .BYTE LWH ;START OF PROMPT STRING .ASCII /WHO TO?/ ; LWH =.-WHOTO-1 .EVEN ; ASKWHO: ENTER R0,R1,R2,R3 ;SAVE REGISTERS 1$: MOV #WHOTO,R1 ; POINT TO PROMPT STRING CALL RDPMPT ; AND READ CMPB #IS.SUC,TTYSB ; WAS THE READ OKAY BNE 10$ ; IF NE, THEN NO MOV TTYSB+2,R3 ; GET LENGTH OF READ STRING BEQ 1$ ; IF NOTHING THERE, TRY AGAIN MOV #GBUF,R0 ; LET'S USE THE GMCR BUFFER MOV #LINBUF,R1 ; WHERE THE NAME STRING IS MOVB R3,(R0)+ ; PUT IN THE SIZE CLR BRKCNT ; NO BRACKETS YET! 2$: MOVB (R1)+,R2 ; GET A CHARACTER MOVB R2,(R0)+ ; MOVE IT INTO NAME STRING CALL CNTBRK ; COUNT THE UIC BRACKETS, CHANGE COMMAS SOB R3,2$ ; MOVB (R1),(R0) ; INCLUDE THE TERMINATOR MOV #GBUF+1,R0 ; POINT TO THE STRING CALL ISME ; IS IT A "ME"? BCC 1$ ; IF CC, THEN YES CALL ISQUE ; HOW 'BOUT A "?"? BCC 1$ ; IF CC, THEN YES MOV #GBUF,R1 ; POINT TO COMPLETED NAMSTR BUFFER CALL NAMSTR ; PROCESS IT BR 1$ ; AND TRY FOR ANOTHER 10$: LEAVE ; RETURN ; .END $MAIL