      SUBROUTINE MAIN
      LOGICAL*1 ARG(40), BUF(512), FILE(40)
      INTEGER I, INT, N, JUNK
      INTEGER GETARG, EQUAL, OPEN, GETLIN, INDEX, GETWRD
      COMMON / CMAIL / NUSERS, REGIST, EDIT, TEMP1(40), TEMP2(40)
      INTEGER NUSERS
      INTEGER REGIST
      INTEGER EDIT
      LOGICAL*1 TEMP1
      LOGICAL*1 TEMP2
      LOGICAL*1 ALL(4)
      LOGICAL*1 FLAGS(4)
      DATA ALL(1)/97/,ALL(2)/108/,ALL(3)/108/,ALL(4)/0/
      DATA FLAGS(1)/43/,FLAGS(2)/45/,FLAGS(3)/63/,FLAGS(4)/0/
      CALL QUERY(50Husage:  mail [-lmlist] [-re] [all] [addressee] ...)
      CALL MALINT(ARG, FILE, BUF)
      I=1
23000 IF (.NOT.(GETARG(I, ARG, 40) .NE. -1))GOTO 23002
      CALL FOLD(ARG)
      IF (.NOT.(EQUAL(ARG, ALL) .EQ. 1))GOTO 23003
      CALL ADRFIL(FILE)
      INT = OPEN(FILE, 1)
      IF (.NOT.(INT .NE. -3))GOTO 23005
23007 IF (.NOT.(GETLIN(BUF, INT) .NE. -1))GOTO 23008
      N = 1
      JUNK = GETWRD(BUF, N, ARG)
      IF (.NOT.(JUNK .GT. 0))GOTO 23009
      CALL ADDUSR(ARG, BUF)
23009 CONTINUE
      GOTO 23007
23008 CONTINUE
      CALL CLOSE(INT)
23005 CONTINUE
      GOTO 23004
23003 CONTINUE
      IF (.NOT.(INDEX(FLAGS, ARG(1)) .GT. 0))GOTO 23011
      CALL MALCMD(ARG, FILE, BUF)
      GOTO 23012
23011 CONTINUE
      CALL ADDUSR(ARG, BUF)
23012 CONTINUE
23004 CONTINUE
23001 I=I+1
      GOTO 23000
23002 CONTINUE
      IF (.NOT.(NUSERS .NE. 0))GOTO 23013
      CALL SDMAIL(BUF, ARG, FILE)
23013 CONTINUE
      RETURN
      END
      SUBROUTINE ADDUSR(ARG, TEMP)
      LOGICAL*1 ARG(40), TEMP(40)
      INTEGER INT, INIT
      INTEGER CREATE, TBLOOK
      COMMON / CMAIL / NUSERS, REGIST, EDIT, TEMP1(40), TEMP2(40)
      INTEGER NUSERS
      INTEGER REGIST
      INTEGER EDIT
      LOGICAL*1 TEMP1
      LOGICAL*1 TEMP2
      LOGICAL*1 T1(4)
      LOGICAL*1 T2(4)
      DATA T1(1)/109/,T1(2)/116/,T1(3)/49/,T1(4)/0/
      DATA T2(1)/109/,T2(2)/116/,T2(3)/50/,T2(4)/0/
      DATA INIT /1/
      IF (.NOT.(INIT .EQ. 1))GOTO 23015
      CALL SCRATF(T1, TEMP1)
      CALL SCRATF(T2, TEMP2)
      INT = CREATE(TEMP1, 2)
      IF (.NOT.(INT .EQ. -3))GOTO 23017
      CALL MERROR(TEMP1)
23017 CONTINUE
      INIT = 0
23015 CONTINUE
      IF (.NOT.(ARG(1) .EQ. 0))GOTO 23019
      CALL CLOSE(INT)
      GOTO 23020
23019 CONTINUE
      IF (.NOT.(TBLOOK(ARG, TEMP) .EQ. 1))GOTO 23021
      NUSERS = NUSERS + 1
      CALL PUTLIN(ARG, INT)
      CALL PUTCH(10, INT)
      GOTO 23022
23021 CONTINUE
      CALL PUTLIN(19HInvalid user name: , 3)
      CALL REMARK(ARG)
23022 CONTINUE
23020 CONTINUE
      RETURN
      END
      SUBROUTINE BADARG(ARG)
      LOGICAL*1 ARG(100)
      CALL PUTLIN(27HIgnoring invalid argument: , 3)
      CALL REMARK(ARG)
      RETURN
      END
      SUBROUTINE CLEANF
      COMMON / CMAIL / NUSERS, REGIST, EDIT, TEMP1(40), TEMP2(40)
      INTEGER NUSERS
      INTEGER REGIST
      INTEGER EDIT
      LOGICAL*1 TEMP1
      LOGICAL*1 TEMP2
      CALL REMOVE(TEMP1)
      CALL REMOVE(TEMP2)
      CALL ENDST(0)
      END
      SUBROUTINE DOTOST(OUT, USER)
      INTEGER OUT, IN, I, J, N
      INTEGER OPEN, LENGTH, GETLIN
      LOGICAL*1 USER(40)
      COMMON / CMAIL / NUSERS, REGIST, EDIT, TEMP1(40), TEMP2(40)
      INTEGER NUSERS
      INTEGER REGIST
      INTEGER EDIT
      LOGICAL*1 TEMP1
      LOGICAL*1 TEMP2
      LOGICAL*1 TOS(9)
      LOGICAL*1 BLS(9)
      DATA TOS(1)/84/,TOS(2)/111/,TOS(3)/58/,TOS(4)/32/,TOS(5)/32/,TOS(6
     *)/32/,TOS(7)/32/,TOS(8)/32/,TOS(9)/0/
      DATA BLS(1)/32/,BLS(2)/32/,BLS(3)/32/,BLS(4)/32/,BLS(5)/32/,BLS(6)
     */32/,BLS(7)/32/,BLS(8)/32/,BLS(9)/0/
      IN = OPEN(TEMP1, 1)
      IF (.NOT.(IN .EQ. -3))GOTO 23023
      CALL MERROR(TEMP1)
23023 CONTINUE
      CALL PUTLIN(TOS, OUT)
      J = 9
      I=GETLIN(USER,IN)
23025 IF (.NOT.(I .NE. -1))GOTO 23027
      USER(I) = 0
      N = J + LENGTH(USER) + 1
      IF (.NOT.(N .GT. 72))GOTO 23028
      CALL PUTCH(44, OUT)
      CALL PUTCH(10, OUT)
      CALL PUTLIN(BLS, OUT)
      J = 9
23028 CONTINUE
      IF (.NOT.(J .GT. 9))GOTO 23030
      CALL PUTCH(44, OUT)
23030 CONTINUE
      CALL PUTCH(32, OUT)
      CALL PUTLIN(USER, OUT)
      J = J + LENGTH(USER) + 2
23026 I=GETLIN(USER,IN)
      GOTO 23025
23027 CONTINUE
      CALL PUTCH(10, OUT)
      CALL CLOSE(IN)
      RETURN
      END
      SUBROUTINE EDITIT(FILE, BUF)
      LOGICAL*1 FILE(40), BUF(100), PROC(40), PID(7)
      INTEGER I, SSPAWN, LOCCOM
      LOGICAL*1 SUFFIX(7)
      LOGICAL*1 ED(3)
      DATA SUFFIX(1)/46/,SUFFIX(2)/116/,SUFFIX(3)/115/,SUFFIX(4)/107/,SU
     *FFIX(5)/0/,SUFFIX(6)/10/,SUFFIX(7)/0/
      DATA ED(1)/101/,ED(2)/100/,ED(3)/0/
      CALL IMPATH(BUF)
      IF (.NOT.(LOCCOM(ED, BUF, SUFFIX, PROC) .NE. 60))GOTO 23032
      CALL ERROR(28HCannot locate ed image file.)
23032 CONTINUE
      I = 1
      CALL STCOPY(ED, 1, BUF, I)
      CALL CHCOPY(32, BUF, I)
      CALL SCOPY(FILE, 1, BUF, I)
      IF (.NOT.(SSPAWN(PROC, BUF, PID, 119) .EQ. -3))GOTO 23034
      CALL ERROR(21HError in spawning ed!)
23034 CONTINUE
      RETURN
      END
      SUBROUTINE GSBJCT(BUF)
      LOGICAL*1 BUF(512)
      INTEGER N
      INTEGER ISATTY, PROMPT
      LOGICAL*1 SUBJCT(10)
      DATA SUBJCT(1)/83/,SUBJCT(2)/117/,SUBJCT(3)/98/,SUBJCT(4)/106/,SUB
     *JCT(5)/101/,SUBJCT(6)/99/,SUBJCT(7)/116/,SUBJCT(8)/58/,SUBJCT(9)/3
     *2/,SUBJCT(10)/0/
      IF (.NOT.(ISATTY(1) .EQ. 1))GOTO 23036
      N = PROMPT(SUBJCT, BUF, 1)
      IF (.NOT.(N .GE. 1))GOTO 23038
      BUF(N) = 0
      GOTO 23039
23038 CONTINUE
      BUF(1) = 0
23039 CONTINUE
      GOTO 23037
23036 CONTINUE
      BUF(1) = 0
23037 CONTINUE
      RETURN
      END
      SUBROUTINE MALCMD(IARG, OUT, BUF)
      LOGICAL*1 IARG(40), MLLIST(40), OUT(40), BUF(512)
      INTEGER I, INT, OPEN, GETLIN, GETWRD, INDEX
      COMMON / CMAIL / NUSERS, REGIST, EDIT, TEMP1(40), TEMP2(40)
      INTEGER NUSERS
      INTEGER REGIST
      INTEGER EDIT
      LOGICAL*1 TEMP1
      LOGICAL*1 TEMP2
      IF (.NOT.(IARG(1) .EQ. 45 .AND. IARG(2) .EQ. 108))GOTO 23040
      CALL SCOPY(IARG, 3, MLLIST, 1)
      INT = OPEN(MLLIST, 1)
      IF (.NOT.(INT .NE. -3))GOTO 23042
23044 IF (.NOT.(GETLIN(BUF, INT) .NE. -1))GOTO 23045
      I = INDEX(BUF, 35)
      IF (.NOT.(I .GT. 0))GOTO 23046
      BUF(I) = 0
23046 CONTINUE
      I = 1
23048 IF (.NOT.(GETWRD(BUF, I, OUT) .GT. 0))GOTO 23049
      CALL ADDUSR(OUT, IARG)
      GOTO 23048
23049 CONTINUE
      GOTO 23044
23045 CONTINUE
      CALL CLOSE(INT)
      GOTO 23043
23042 CONTINUE
      CALL PUTLIN(36HError in opening mailing list file: , 3)
      CALL REMARK(MLLIST)
23043 CONTINUE
      GOTO 23041
23040 CONTINUE
      IF (.NOT.(IARG(1) .EQ. 45))GOTO 23050
      IF (.NOT.(INDEX(IARG, 114) .GT. 0))GOTO 23052
      REGIST = 1
23052 CONTINUE
      IF (.NOT.(INDEX(IARG, 101) .GT. 0))GOTO 23054
      EDIT = 1
23054 CONTINUE
      GOTO 23051
23050 CONTINUE
      CALL BADARG(IARG)
23051 CONTINUE
23041 CONTINUE
      RETURN
      END
      SUBROUTINE MALINP(TEMP, FILE, BUF, EDIT)
      INTEGER EDIT, INT, OPEN, ISATTY, CREATE, GETLIN, INP, FSIZE, PROMP
     *T
      LOGICAL*1 FILE(40), BUF(512), CLOWER, TEMP(40)
      LOGICAL*1 MTS(4)
      DATA MTS(1)/109/,MTS(2)/116/,MTS(3)/115/,MTS(4)/0/
      INT = CREATE(TEMP, 2)
      IF (.NOT.(INT .EQ. -3))GOTO 23056
      CALL MERROR(TEMP)
23056 CONTINUE
      CALL GSBJCT(BUF)
      CALL PSTMRK(INT, BUF)
      INP = 1
      IF (.NOT.(ISATTY(1) .EQ. 1))GOTO 23058
      IF (.NOT.(EDIT .EQ. 1))GOTO 23060
      CALL SCRATF(MTS, FILE)
      CALL REMARK(43HYou are now entering ed to create your mail)
      CALL REMARK(36HPlease wait for ed to respond with 0)
      CALL EDITIT(FILE, BUF)
      INP = OPEN(FILE, 1)
      IF (.NOT.(INP .EQ. -3 .OR. FSIZE(FILE) .EQ. 0))GOTO 23062
      CALL CLOSE(INP)
      CALL REMOVE(FILE)
      CALL CLOSE(INT)
      CALL CLEANF
23062 CONTINUE
      GOTO 23061
23060 CONTINUE
      CALL PUTLIN(29HInput message: (q to quit or , 3)
      CALL PUTLIN(2H^Z, 3)
      CALL REMARK(9H to send))
23061 CONTINUE
23058 CONTINUE
23064 IF (.NOT.(GETLIN(BUF, INP) .NE. -1))GOTO 23065
      IF (.NOT.(CLOWER(BUF(1)) .EQ. 113 .AND. BUF(2) .EQ. 10 .AND. EDIT 
     *.EQ. 0))GOTO 23066
      CALL CLOSE(INT)
      CALL CLEANF
      GOTO 23067
23066 CONTINUE
      CALL PUTLIN(BUF, INT)
23067 CONTINUE
      GOTO 23064
23065 CONTINUE
      CALL CLOSE(INT)
      IF (.NOT.(INP .NE. 1))GOTO 23068
      CALL CLOSE(INP)
      CALL REMOVE(FILE)
23068 CONTINUE
      RETURN
      END
      SUBROUTINE MALINT(ARG, FILE, BUF)
      LOGICAL*1 ARG(40), FILE(40), BUF(512)
      INTEGER INT, I, JUNK
      INTEGER OPEN, GETLIN, GETWRD
      COMMON / CMAIL / NUSERS, REGIST, EDIT, TEMP1(40), TEMP2(40)
      INTEGER NUSERS
      INTEGER REGIST
      INTEGER EDIT
      LOGICAL*1 TEMP1
      LOGICAL*1 TEMP2
      INTEGER MEM(2000)
      LOGICAL*1 CMEM(4000)
      EQUIVALENCE (CMEM(1),MEM(1))
      COMMON/CDSMEM/MEM
      NUSERS = 0
      REGIST = 0
      EDIT = 0
      CALL ADRFIL(FILE)
      CALL TBINIT(2000)
      INT = OPEN(FILE, 1)
      IF (.NOT.(INT .NE. -3))GOTO 23070
23072 IF (.NOT.(GETLIN(BUF, INT) .NE. -1))GOTO 23073
      I = 1
      JUNK = GETWRD(BUF, I, ARG)
      JUNK = GETWRD(BUF, I, FILE)
      CALL TBINST(ARG, FILE)
      GOTO 23072
23073 CONTINUE
      CALL CLOSE(INT)
      GOTO 23071
23070 CONTINUE
      CALL ERROR(29HCannot open local users file.)
23071 CONTINUE
      RETURN
      END
      SUBROUTINE MERROR(BUF)
      LOGICAL*1 BUF(100)
      CALL PUTLIN(33HCannot open mail temporary file: , 3)
      CALL REMARK(BUF)
      CALL CLEANF
      RETURN
      END
      SUBROUTINE PSTMRK(INT, SUBJCT)
      LOGICAL*1 IDATE(10), ITIME(10), USER(40), CUPPER
      LOGICAL*1 HDRPAT(4), SUBJCT(100)
      INTEGER INT, NOW(7)
      LOGICAL*1 DATES(10)
      LOGICAL*1 DASHST(4)
      LOGICAL*1 TIMZON(4)
      LOGICAL*1 FROMS(10)
      LOGICAL*1 SUBJS(10)
      DATA DATES(1)/68/,DATES(2)/97/,DATES(3)/116/,DATES(4)/101/,DATES(5
     *)/58/,DATES(6)/32/,DATES(7)/32/,DATES(8)/32/,DATES(9)/32/,DATES(10
     *)/0/
      DATA DASHST(1)/32/,DASHST(2)/45/,DASHST(3)/32/,DASHST(4)/0/
      DATA TIMZON(1)/80/,TIMZON(2)/83/,TIMZON(3)/84/,TIMZON(4)/0/
      DATA FROMS(1)/70/,FROMS(2)/114/,FROMS(3)/111/,FROMS(4)/109/,FROMS(
     *5)/58/,FROMS(6)/32/,FROMS(7)/32/,FROMS(8)/32/,FROMS(9)/32/,FROMS(1
     *0)/0/
      DATA SUBJS(1)/83/,SUBJS(2)/117/,SUBJS(3)/98/,SUBJS(4)/106/,SUBJS(5
     *)/101/,SUBJS(6)/99/,SUBJS(7)/116/,SUBJS(8)/58/,SUBJS(9)/32/,SUBJS(
     *10)/0/
      DATA HDRPAT/1, 1, 10, 0/
      CALL MAILID(USER)
      USER(1) = CUPPER(USER(1))
      CALL GETNOW(NOW)
      CALL FMTDAT(IDATE, ITIME, NOW, 1)
      CALL PUTLIN(HDRPAT, INT)
      CALL PUTLIN(DATES, INT)
      CALL PUTLIN(IDATE, INT)
      CALL PUTCH(32, INT)
      CALL PUTLIN(ITIME, INT)
      CALL PUTLIN(DASHST, INT)
      CALL PUTLIN(TIMZON, INT)
      CALL PUTCH(10, INT)
      CALL PUTLIN(FROMS, INT)
      CALL PUTLIN(USER, INT)
      CALL PUTCH(10, INT)
      CALL PUTLIN(SUBJS, INT)
      CALL PUTLIN(SUBJCT, INT)
      CALL PUTCH(10, INT)
      CALL DOTOST(INT, USER)
      CALL PUTCH(10, INT)
      RETURN
      END
      SUBROUTINE SDMAIL(BUF, FILE, USER)
      LOGICAL*1 BUF(512), FILE(40), USER(40)
      INTEGER INP, INT, N, JUNK, OUT
      INTEGER OPEN, GETLIN, TBLOOK, CREATE
      INTEGER*4 TOPFIL
      COMMON / CMAIL / NUSERS, REGIST, EDIT, TEMP1(40), TEMP2(40)
      INTEGER NUSERS
      INTEGER REGIST
      INTEGER EDIT
      LOGICAL*1 TEMP1
      LOGICAL*1 TEMP2
      LOGICAL*1 MYMAIL(7)
      DATA MYMAIL(1)/109/,MYMAIL(2)/121/,MYMAIL(3)/109/,MYMAIL(4)/97/,MY
     *MAIL(5)/105/,MYMAIL(6)/108/,MYMAIL(7)/0/
      CALL ADDUSR(0)
      CALL MALINP(TEMP2, FILE, BUF, EDIT)
      INP = OPEN(TEMP2, 1)
      IF (.NOT.(INP .EQ. -3))GOTO 23074
      CALL MERROR(TEMP2)
23074 CONTINUE
      CALL MARKL(INP, TOPFIL)
      INT = OPEN(TEMP1, 1)
      IF (.NOT.(INT .EQ. -3))GOTO 23076
      CALL CLOSE(INP)
      CALL MERROR(TEMP1)
23076 CONTINUE
      N=GETLIN(BUF,INT)
23078 IF (.NOT.(N .NE. -1))GOTO 23080
      BUF(N) = 0
      JUNK = TBLOOK(BUF, FILE)
      CALL CONCAT(FILE, MYMAIL, FILE)
      CALL SEEK(TOPFIL, INP)
      OUT = CREATE(FILE, 4)
      IF (.NOT.(OUT .EQ. -3))GOTO 23081
      CALL PUTLIN(20HCannot send mail to , 3)
      CALL REMARK(BUF)
      GOTO 23082
23081 CONTINUE
      CALL FCOPY(INP, OUT)
      CALL CLOSE(OUT)
      IF (.NOT.(REGIST .EQ. 1))GOTO 23083
      CALL PUTLIN(15HMail posted to , 3)
      CALL REMARK(BUF)
23083 CONTINUE
23082 CONTINUE
23079 N=GETLIN(BUF,INT)
      GOTO 23078
23080 CONTINUE
      CALL CLOSE(INT)
      CALL CLOSE(INP)
      CALL CLEANF
      RETURN
      END
