1 !MAIL System main driver for sending/receiving MAIL messages ! 2 ! !*************************************************************************** ! COPYRIGHT(C) 1978 by Larry Koolkin, University of Texas Medical Branch, ! Galveston, Texas, 77550. All rights reserved; no portion of this ! software may be reproduced, stored in any retreival system, or be copied ! without prior written permission of the author. !*************************************************************************** ! 5 EXTEND ! 10 DIM D$(2%),RECS$(100%),VALIDATE$(100%,2%),LLIST%(10%),KLIST%(10%) 15 JUNK$=SYS(CHR$(6%)+CHR$(-7%)) !Enable CTRL/C trapping ! 17 JUNK$=SYS(CHR$(6%)+CHR$(9%)+CHR$(0%)) \ KBNO%=(ASCII(MID(JUNK$,2%,1%)))/2 \ JOBNO%=(ASCII(MID(JUNK$,1%,1%)))/2 ! Save the KB number and JOB number for later use ! 18 JOBNO$=NUM1$(JOBNO%) \ JOBNO$="0"+JOBNO$ IF LEN(JOBNO$)<2% \ JOBNO$=RIGHT(JOBNO$,LEN(JOBNO$)-1%) IF LEN(JOBNO$)>2% \ STX$=CHR$(2%) ! Make a 2 digit job # string for temp. filname opens, ! STX is 1st character of a msg header record ! 20 ON ERROR GOTO 30000 30 VERSION$="UTMB Psychiatry MAIL System, Version 1.0" !Title/Version header line ! 35 PRINT \ PRINT TAB(12%);VERSION$ \ PRINT TAB(18%);DATE$(0%);" at ";TIME$(0%) \ PRINT 190 GOSUB 10000 ! Check if there is any new MAIL, print appropriate message is so ! 200 PRINT "#"; \ INPUT LINE CMD$ \ CMD$=FNCVT$(CMD$,1%+4%+8%+16%+32%+64%+128%) ! Input a command as CMD$, discard garbage characters 205 ! 210 IF LEN(CMD$)=0% OR LEFT(CMD$,1%)="H" THEN GOSUB 11000 \ GOTO 200 ! If or HELP, then print messages and get another command ! 220 CODE%=0% \ CODE%=1% IF LEFT(CMD$,1%)="S" \ CODE%=2% IF LEFT(CMD$,1%)="L" \ CODE%=3% IF LEFT(CMD$,1%)="M" \ CODE%=4% IF LEFT(CMD$,1%)="K" \ CODE%=5% IF LEFT(CMD$,1%)="E" ! Assign command codes to SEND,LIST,MOVE,KILL,EXIT ! 230 IF CODE%=0% THEN PRINT "* Illegal Command *" \ PRINT \ GOTO 200 ! Trap unrecognized command types, print error, return ! 300 ON CODE% GOSUB 1000,2000,3000,4000,5000 ! Transfer control to appropriate GOSUB for this command ! 310 PRINT \ GOTO 200 ! After completion of last command GOSUB, go back for another command ! 500 ! !************************************************************************** !************************************************************************** !************************************************************************** ! 1000 ! !<><><><>< S E N D ><><><><> ! 1010 VALID%=INSTR(1%,CMD$,":V") \ GOSUB 12000 IF VALID%<>0% ! Print VALID MAIL System users list if requested ! 1020 RECNUM%=0% \ PRINT "TO"; \ INPUT LINE TOLIST$ \ TOLIST$=FNCVT$(TOLIST$,-1%) ! Request the list of receivers, discard garbage characters ! and convert brackets to parentheses ! 1022 IF TOLIST$="?" THEN GOSUB 12000 \ GOTO 1020 ! If only '?' is entered, print VALID user list ! 1025 IF LEN(TOLIST$)=0% THEN PRINT "* Invalid Receiver List *" \ PRINT \ GOTO 1020 1027 TOFILE%=INSTR(1%,TOLIST$,";") \ GOTO 1030 IF TOFILE%=0% \ TOFILE$=RIGHT(TOLIST$,TOFILE%+1%) \ TOLIST$=LEFT(TOLIST$,TOFILE%-1%) ! If there is a file spec. in the TO list, strip it off as TOFILE$, ! and delete it from the TO list before proceeding ! 1030 RECNUM%=0% !Receiver count 1035 RECPNT%=INSTR(1%,TOLIST$,"(") \ GOTO 1100 IF RECPNT%=0% ! Process acct numbers in the list first, if they exist ! 1040 RECNUM%=RECNUM%+1% \ RECPNT1%=INSTR(RECPNT%+1%,TOLIST$,")") \ IF RECPNT1%=0% THEN PRINT "* Missing Parentheses *" \ PRINT \ GOTO 1020 1045 RECS$(RECNUM%)=MID(TOLIST$,RECPNT%+1%,RECPNT1%-RECPNT%-1%) \ TOLIST$=LEFT(TOLIST$,RECPNT%-2%)+RIGHT(TOLIST$,RECPNT1%+1%) \ GOTO 1035 ! Increment the number of requested receivers ! Save this receiver acct # (w/comma; w/o paren.) in RECS$() ! Delete this receiver from the list, leaving comma afterwards ! 1100 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 1110 TOLIST$=RIGHT(TOLIST$,2%) IF LEFT(TOLIST$,1%)="," \ GOTO 1200 IF LEN(TOLIST$)=0% ! Strip of initial comma from remaining list if it is now there, ! if no names left, then continue ! 1120 RECPNT%=INSTR(1%,TOLIST$,",") \ IF RECPNT%=0% THEN 1200 ! Begin comma search to break up the names remaining ! 1130 RECNUM%=RECNUM%+1% \ RECS$(RECNUM%)=LEFT(TOLIST$,RECPNT%-1%) \ TOLIST$=RIGHT(TOLIST$,RECPNT%+1%) \ GOTO 1120 ! Save this receiver name, delete it from the TO list, go back for more ! 1200 IF LEN(TOLIST$)<>0% THEN RECNUM%=RECNUM%+1% \ RECS$(RECNUM%)=TOLIST$ ! Check to see if one final name remains after all commas are gone ! 1300 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 1310 IF (RECNUM%=1% AND RECS$(RECNUM%)="ALL") THEN GOSUB 13000 ELSE GOSUB 13500 ! If 'ALL' requested, read entire MAIL.LST Valid listings; ! otherwise, go through that file to verify entries from receiver list ! 1315 GOTO 1900 IF BADLIST%=-1% !Request another command if no valid entries in TO? list ! 1320 OPEN "MAIL"+JOBNO$+".TMP" FOR OUTPUT AS FILE 9%,MODE 2% ! Create a temp file to accumulate the message text in ! 1330 JUNK%=PEEK(PEEK(PEEK(520%)+8%)+24%) \ SPROJ$=NUM1$(SWAP%(JUNK%) AND 255%) \ SPROG$=NUM1$(JUNK% AND 255%) \ SPROJ$="0"+SPROJ$ UNTIL LEN(SPROJ$)=4% \ SPROG$="0"+SPROG$ UNTIL LEN(SPROG$)=4% ! Look up the PPN of this user to put in Msg header ! 1340 FOR RECPNT1%=1% TO VALIDATE% \ IF SPROJ$=VALIDATE$(RECPNT1%,0%) AND SPROG$=VALIDATE$(RECPNT1%,1%) THEN 1360 1350 NEXT RECPNT1% \ SNAME$=STRING$(15%,32%) \ GOTO 1370 1360 SNAME$=VALIDATE$(RECPNT1%,2%) ! Look up MAIL system name for the sender; ! if he is not part of the MAIL system, load blanks for the name ! 1370 PRINT \ PRINT "HEADER:"; \ INPUT LINE HEADER$ 1380 HEADER$=FNCVT$(HEADER$,1%+4%) \ IF LEN(HEADER$)=0% OR LEN(HEADER$)>72% THEN PRINT "* Invalid header *" \ GOTO 1370 ! Input the header, must be from 1 to 72 characters long ! 1390 IF LEN(HEADER$)<72% THEN HEADER$=HEADER$+" " UNTIL LEN(HEADER$)=72% ! Pad header to length of 72 exactly ! 1400 HEADER$=STX$+" "+SPROJ$+SPROG$+SNAME$+ FNCVT$(DATE$(0%),-1%)+FNCVT$(LEFT(TIME$(0%),2%),-1%) +FNCVT$(RIGHT(TIME$(0%),4%),-1%)+HEADER$ ! Build entire header record for the msg ! 1410 PRINT #9%,FNCVT$(HEADER$,1%+4%) \ GOTO 1430 IF TOFILE%=0% ! Write the header to the text temp file, see if indirect msg file ! has been requested ! 1420 OPEN TOFILE$ FOR INPUT AS FILE 8% ! If so, open it 1423 PRINT TAB(6%);"Text being transferred from ";TOFILE$;"..." \ PRINT ! 1425 INPUT LINE #8%,JUNK$ 1427 JUNK$=FNCVT$(JUNK$,1%+4%) \ GOTO 1425 IF LEFT(JUNK$,1%)=STX$ \ PRINT #9%,JUNK$ \ GOTO 1425 ! Do no transfer the first line of the indirect text file ! if it is an old msg header record. ! 1428 CLOSE 8% ! and transfer the text from it to the temp file ! 1430 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 1440 PRINT \ PRINT "Enter message text; end with CTRL/Z..." \ PRINT 1450 INPUT LINE JUNK$ ! Now input msg text from the terminal 1460 JUNK$=FNCVT$(JUNK$,1%+4%) \ JUNK$=RIGHT(JUNK$,2%) IF LEFT(JUNK$,1%)=STX$ \ PRINT #9%,JUNK$ \ GOTO 1450 ! Loop back for more text until CTRL/Z is typed ! 1470 PRINT \ CLOSE 9% \ PRINT "SEND MSG NOW [Yes]"; \ INPUT LINE SNDNOW$ \ SNDNOW$=FNCVT$(SNDNOW$,-1%) \ SNDNOW%=INSTR(1%,SNDNOW$,";") \ IF SNDNOW%=0% THEN 1480 ELSE SNDFILE$=RIGHT(SNDNOW$,SNDNOW%+1%) ! Ask if the msg text is to be sent now and for a filename in ! which to save the compiled msg text (including header) optionally ! 1480 IF LEFT(SNDNOW$,1%)="Y" OR LEN(SNDNOW$)=0% THEN GOSUB 14000 ! Send the message to requested receivers if YES ! 1490 CLOSE 9% \ IF SNDNOW%=0% THEN KILL "MAIL"+JOBNO$+".TMP" ELSE NAME "MAIL"+JOBNO$+".TMP" AS SNDFILE$ ! If no msg save file is requested, kill the temp file after the send; ! otherwise, rename the temp file to the specified save filename ! 1500 IF [LEFT(SNDNOW$,1%)="Y" OR LEN(SNDNOW$)=0%] AND (CANTSEND%<><><>< L I S T ><><><><> ! 2010 LSPACE%=INSTR(1%,CMD$," ") \ LCOMMA%=INSTR(1%,CMD$,",") \ LDASH%=INSTR(1%,CMD$,"-") ! Search command string for space (arg.s follow), comma (list), ! or dash (incl. list) ! 2020 IF (LSPACE%=0% AND (LCOMMA%<>0% OR LDASH%<>0%)) OR (LCOMMA%<>0% AND LDASH%<>0%) THEN PRINT "* Invalid LIST format *" \ PRINT \ GOTO 2900 ! Must have a space for arg.s, cannot mix comma/dash lists for now ! 2030 OPEN "MAIL.TXT" FOR INPUT AS FILE 9%,MODE 4096% ! Open the msg file in read only mode ! 2032 INPUT LINE #9%,JUNK$ \ MSGNO%=VAL(LEFT(JUNK$,5%)) \ MSGHI%=VAL(MID(JUNK$,6%,5%)) ! Save # msgs and highest msg # from the header ! 2040 GOTO 2045 IF LSPACE%=0% \ GOTO 2400 IF LDASH%<>0% \ GOTO 2200 ! If no space, print headers only ! if a dash, print inclusive list ! otherwise assume a normal list (single item or commas) ! 2045 ! all msg headers only ! 2047 LCOUNT%=0% !# of text lines/msg 2050 INPUT LINE #9%,JUNK$ \ JUNK$=FNCVT$(JUNK$,1%+4%) 2060 IF LEFT(JUNK$,1%)<>STX$ THEN LCOUNT%=LCOUNT%+1% \ GOTO 2050 ! If not a msg hdr, just count msg text lines ! 2070 PRINT "[";LCOUNT%;" line(s) of text ]" IF LCOUNT%<>0% \ PRINT \ HJUNK$=FNHEAD$(0%,JUNK$) \ GOTO 2047 ! Print the msg hdr and # of text lines for previous one ! 2075 PRINT "[";LCOUNT%;" line(s) of text ]" IF LCOUNT%<>0% \ GOTO 2900 ! Print # of text lines for last msg, then return ! 2080 ! 2195 ! normal lists ! 2200 LARGS$=RIGHT(CMD$,LSPACE%+1%)+"," \ IF INSTR(1%,LARGS$,",,")<>0% THEN PRINT "* Illegal arguement in LIST  *" \ GOTO 2900 ! Strip off the msg # list; add a comma to the end; ! check for consec. commas with no arguement in between ! 2205 LCOUNT%=0% \ MAT LLIST%=ZER ! Initialize the # of items counter, and msg # array at zero ! 2210 LCOMMA%=INSTR(1%,LARGS$,",") \ IF LCOMMA%<>0% THEN LCOUNT%=LCOUNT%+1% \ LLIST%(LCOUNT%)=VAL(LEFT(LARGS$,LCOMMA%-1%)) \ LARGS$=RIGHT(LARGS$,LCOMMA%+1%) \ GOTO 2210 ! Break up the list into array LLIST%(); LCOUNT%=# items 2215 ! 2220 INPUT LINE #9%,JUNK$ \ JUNK$=FNCVT$(JUNK$,1%+4%) 2230 IF LEFT(JUNK$,1%)<>STX$ THEN 2220 ! Read records until a msg header is fount ! 2240 FOR JUNK%=1% TO LCOUNT% \ IF VAL(MID(JUNK$,2%,5%))=LLIST%(JUNK%) THEN 2260 2250 NEXT JUNK% \ GOTO 2220 ! Is this header for a msg # we want ? ! 2260 PRINT \ PRINT STRING$(80%,43%) \ PRINT \ HJUNK$=FNHEAD$(0%,JUNK$) \ PRINT \ ! Print the header line first ! 2270 INPUT LINE #9%,JUNK$ \ JUNK$=FNCVT$(JUNK$,1%+4%) 2280 IF LEFT(JUNK$,1%)=STX$ THEN PRINT \ PRINT STRING$(80%,43%) \ PRINT \ GOTO 2240 ! If its part of this msg print it, otherwise return 2290 PRINT JUNK$ \ GOTO 2270 2295 ! 2395 ! inclusive lists ! 2400 LARGS$=RIGHT(CMD$,LSPACE%+1%) \ LDASH%=INSTR(1%,LARGS$,"-") \ LFR%=VAL(LEFT(LARGS$,LDASH%-1%)) \ LTO%=VAL(RIGHT(LARGS$,LDASH%+1%)) \ IF (LFR% > LTO%) OR (LTO% > MSGHI%) THEN PRINT "* Invalid inclusive LIST specification *" \ PRINT \ GOTO 2900 ! Determine msg # to start/end listing and make sure the ! 'from'<'to' and 'to'STX$ \ MSGNO%=VAL(MID(JUNK$,2%,5%)) \ GOTO 2410 IF MSGNO%LTO% ! Search MAIL.TXT for 1st msg no => the 'from' specification ! until msg no. > 'to' specification 2425 PRINT \ PRINT STRING$(80%,43%) \ PRINT 2430 HJUNK$=FNHEAD$(0%,JUNK$) \ PRINT ! Print the msg header first... ! 2440 INPUT LINE #9%,JUNK$ \ JUNK$=FNCVT$(JUNK$,1%+4%) 2450 IF LEFT(JUNK$,1%)=STX$ THEN PRINT \ PRINT STRING$(80%,43%) \ PRINT \ GOTO 2420 ! If this line is hdr for next msg, go back; otherwise print it ! 2460 PRINT JUNK$ \ GOTO 2440 2470 ! 2900 CLOSE 9% \ RETURN 3000 !<><><><>< M O V E ><><><><> ! 3005 MFILE%=INSTR(1%,CMD$,";") \ GOTO 3010 IF MFILE%=0% \ MFILE$=RIGHT(CMD$,MFILE%+1%) \ CMD$=LEFT(CMD$,MFILE%-1%) ! Save a specified MOVE filename, strip it off the cmd string ! 3010 LSPACE%=INSTR(1%,CMD$," ") \ LCOMMA%=INSTR(1%,CMD$,",") \ LDASH%=INSTR(1%,CMD$,"-") \ IF (LSPACE%=0% AND (LCOMMA%<>0% OR LDASH%<>0%)) OR (LCOMMA%<>0% AND LDASH%<>0%) THEN PRINT "* Invalid MOVE format *" \ PRINT \ GOTO 3900 ! Verify MOVE arguement list, if it appears along with command ! 3020 GOTO 3080 IF LDASH%<>0% \ GOTO 3040 IF LSPACE%<>0% \ PRINT "MSG. NO.(S) TO MOVE"; \ INPUT LINE CMD$ \ CMD$=FNCVT$(CMD$,-1%) \ CMD$=" "+CMD$ \ GOTO 3005 ! Request the arguement list if not given along with the command ! 3030 ! process normal lists ! 3040 LARGS$=RIGHT(CMD$,LSPACE%+1%)+"," \ IF INSTR(1%,CMD$,",,")<>0% THEN PRINT "* Illegal arguement in MOVE *" \ GOTO 3900 ! Strip off the msg # list, check for consec. commas w/o arguements ! 3050 LCOUNT%=0% \ MAT KLIST%=ZER ! Initialize the # of items to MOVE and their msg #'s array ! 3060 LCOMMA%=INSTR(1%,LARGS$,",") \ IF LCOMMA%<>0% THEN LCOUNT%=LCOUNT%+1% \ KLIST%(LCOUNT%)=VAL(LEFT(LARGS$,LCOMMA%-1%)) \ LARGS$=RIGHT(LARGS$,LCOMMA%+1%) \ GOTO 3060 ! Break up the list into array KLIST%(), LCOUNT%=# of msgs to MOVE ! 3070 GOTO 3100 !Process the MOVE command ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! 3080 ! process inclusive lists ! 3090 LARGS$=RIGHT(CMD$,LSPACE%+1%) \ LDASH%=INSTR(1%,LARGS$,"-") \ KFR%=VAL(LEFT(LARGS$,LDASH%-1%)) \ KTO%=VAL(RIGHT(LARGS$,LDASH%+1%)) \ IF (KFR% > KTO%) THEN PRINT "* Invalid inclusive MOVE specification *" \ PRINT \ GOTO 3900 ! Determine msg # to start/end MOVE, and make sure the 'from' ! value is < = the 'to' value ! 3100 ! process the MOVE list ! 3110 KCOUNT%=0% ! Initialize the # of items actually MOVEed ! 3120 OPEN "MAIL.TXT" FOR INPUT AS FILE 9%,MODE 4096% \ TEMP$=CVT$$(TIME$(0%),-1%) \ TEMP$=LEFT(TEMP$,2%)+RIGHT(TEMP$,4%)+JOBNO$+".MSG" \ OPEN MFILE$ AS FILE 8%,MODE 2% IF MFILE%<>0% \ OPEN TEMP$ FOR OUTPUT AS FILE 8%,MODE 2% IF MFILE%=0% \ INPUT LINE #9%,JUNK$ ! Open MAIL.TXT and either the specified or default msg MOVE file, ! read the MAIL.TXT header ! 3130 INPUT LINE #9%,JUNK$ \ JUNK$=FNCVT$(JUNK$,1%+4%) ! Read a line from MAIL.TXT ! 3140 GOTO 3130 IF LEFT(JUNK$,1%)<>STX$ \ MSGNO%=VAL(MID(JUNK$,2%,5%)) ! Find a msg header ! 3150 GOTO 3180 IF LDASH%<>0% \ FOR JUNK%=1% TO LCOUNT% \ IF MSGNO%=KLIST%(JUNK%) THEN 3165 3160 NEXT JUNK% \ GOTO 3130 ! Skip over this msg if it is not to be MOVEd ! 3165 PRINT #8% \ HJUNK$=FNHEAD$(8%,JUNK$) \ PRINT #8% \ KCOUNT%=KCOUNT%+1% ! Print the header into msg MOVE file, incr. count of MOVEd msgs ! 3170 INPUT LINE #9%,JUNK$ \ JUNK$=FNCVT$(JUNK$,1%+4%) \ GOTO 3140 IF LEFT(JUNK$,1%)=STX$ \ PRINT #8%,JUNK$ \ GOTO 3170 ! Transfer the rest of this msg until next msg header is found ! 3180 GOTO 3130 IF (MSGNO%KTO%) \ PRINT #8% \ HJUNK$=FNHEAD$(8%,JUNK$) \ PRINT #8% \ KCOUNT%=KCOUNT%+1% ! If this msg # is within the inclusive range for this MOVE, ! transfer its header to the MOVE msg file, and incr. count ! 3190 INPUT LINE #9%,JUNK$ \ JUNK$=FNCVT$(JUNK$,1%+4%) \ GOTO 3140 IF LEFT(JUNK$,1%)=STX$ \ PRINT #8%,JUNK$ \ GOTO 3190 ! Transfer the rest of this msg for incl. list until next msg header ! 3200 ! 3210 CLOSE 8%,9% 3220 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 3250 PRINT KCOUNT%;" messages MOVEd into file "; \ PRINT MFILE$ IF MFILE%<>0% \ PRINT TEMP$ IF MFILE%=0% \ PRINT 3900 RETURN ! 4000 ! !<><><><>< K I L L ><><><><> ! 4010 LSPACE%=INSTR(1%,CMD$," ") \ LCOMMA%=INSTR(1%,CMD$,",") \ LDASH%=INSTR(1%,CMD$,"-") \ IF (LSPACE%=0% AND (LCOMMA%<>0% OR LDASH%<>0%)) OR (LCOMMA%<>0% AND LDASH%<>0%) THEN PRINT "* Invalid KILL format *" \ PRINT \ GOTO 4900 ! Verify KILL arguement list, if it appears along with command ! 4020 GOTO 4200 IF LDASH%<>0% \ GOTO 4030 IF LSPACE%<>0% \ PRINT "MSG. NO.(S) TO KILL"; \ INPUT LINE CMD$ \ CMD$=FNCVT$(CMD$,-1%) \ CMD$=" "+CMD$ \ GOTO 4010 ! Request the arguement list if not given along with the command ! 4025 ! process normal lists ! 4030 LARGS$=RIGHT(CMD$,LSPACE%+1%)+"," \ IF INSTR(1%,CMD$,",,")<>0% THEN PRINT "* Illegal arguement in KILL *" \ GOTO 4900 ! Strip off the msg # list, check for consec. commas w/o arguements ! 4040 LCOUNT%=0% \ MAT KLIST%=ZER ! Initialize the # of items to KILL and their msg #'s array ! 4050 LCOMMA%=INSTR(1%,LARGS$,",") \ IF LCOMMA%<>0% THEN LCOUNT%=LCOUNT%+1% \ KLIST%(LCOUNT%)=VAL(LEFT(LARGS$,LCOMMA%-1%)) \ LARGS$=RIGHT(LARGS$,LCOMMA%+1%) \ GOTO 4050 ! Break up the list into array KLIST%(), LCOUNT%=# of msgs to KILL ! 4060 GOTO 4500 !Process the KILL command ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! 4200 ! process inclusive lists ! 4210 LARGS$=RIGHT(CMD$,LSPACE%+1%) \ LDASH%=INSTR(1%,LARGS$,"-") \ KFR%=VAL(LEFT(LARGS$,LDASH%-1%)) \ KTO%=VAL(RIGHT(LARGS$,LDASH%+1%)) \ IF (KFR% > KTO%) THEN PRINT "* Invalid inclusive KILL specification *" \ PRINT \ GOTO 4900 ! Determine msg # to start/end KILL, and make sure the 'from' ! value is < = the 'to' value ! 4500 ! process the KILL list ! 4505 KCOUNT%=0% ! Initialize the # of items actually KILLed ! 4510 OPEN "MAIL.TXT" FOR INPUT AS FILE 9%,MODE 4096% \ OPEN "MAIL"+JOBNO$+".TMP" FOR OUTPUT AS FILE 8%,MODE 2% \ INPUT LINE #9%,JUNK$ \ JUNK$=FNCVT$(JUNK$,1%+4%) \ PRINT #8%,JUNK$ ! Open the two files, and transfer the header; updated later ! 4520 INPUT LINE #9%,JUNK$ \ JUNK$=FNCVT$(JUNK$,1%+4%) ! Read a line from MAIL.TXT ! 4530 GOTO 4520 IF LEFT(JUNK$,1%)<>STX$ \ MSGNO%=VAL(MID(JUNK$,2%,5%)) ! Find a msg header ! 4540 GOTO 4560 IF LDASH%<>0% \ FOR JUNK%=1% TO LCOUNT% \ IF MSGNO%=KLIST%(JUNK%) THEN 4600 4550 NEXT JUNK% \ PRINT #8%,JUNK$ \ MSGHI%=MSGNO% ! If not KILLed, transfer this text to temp file ! and save the highest msg number transferred 4555 INPUT LINE #9%,JUNK$ \ JUNK$=FNCVT$(JUNK$,1%+4%) \ GOTO 4530 IF LEFT(JUNK$,1%)=STX$ \ PRINT #8%,JUNK$ \ GOTO 4555 ! Transfer the rest of this msg until next msg header is found ! 4560 GOTO 4600 IF (MSGNO%>=KFR% AND MSGNO%<=KTO%) \ PRINT #8%,JUNK$ \ MSGHI%=MSGNO% ! Is this msg # within the inclusive range for this KILL ? ! if not, transfer to temp file and keep highest msg # 4570 INPUT LINE #9%,JUNK$ \ JUNK$=FNCVT$(JUNK$,1%+4%) \ GOTO 4530 IF LEFT(JUNK$,1%)=STX$ \ PRINT #8%,JUNK$ \ GOTO 4570 ! Transfer the rest of this msg for incl. list until next msg header ! 4600 KCOUNT%=KCOUNT%+1% \ GOTO 4520 ! Increment count of un-transferred (KILLed) msgs for header ! 4700 CLOSE 8%,9% 4710 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 4720 KILL "MAIL.TXT" \ NAME "MAIL"+JOBNO$+".TMP" AS "MAIL.TXT" \ OPEN "MAIL.TXT" FOR INPUT AS FILE 9%,RECORDSIZE 10% \ FIELD #9%,5% AS N0$,5% AS N1$ \ GET #9%,RECORD 1% ! Close the files, kill MAIL.TXT, rename the temp file to MAIL.TXT, ! re-open MAIL.TXT for header update ! 4730 MSGNO$=NUM1$(VAL(N0$)-KCOUNT%) \ MSGNO$="0"+MSGNO$ UNTIL LEN(MSGNO$)=5% \ MSGHI$=NUM1$(MSGHI%) \ MSGHI$="0"+MSGHI$ UNTIL LEN(MSGHI$)=5% \ LSET N0$=MSGNO$ \ LSET N1$=MSGHI$ \ PUT #9%,RECORD 1% \ CLOSE 9% ! # of msgs = old # msgs - # killed (KCOUNT%) ! highest msg # is kept track of in MSGHI% during transfers ! update the header, close the file ! 4800 PRINT KCOUNT%;" messages KILLed..." \ PRINT 4900 RETURN ! 5000 ! !<><><><>< E X I T ><><><><> ! 5100 CLOSE JUNK% FOR JUNK%=1% TO 12% \ GOTO 32767 ! ****** end for now ****** ! 5900 RETURN ! 10000 ! !<><><><>< CHECK FOR NEW MAIL IN 'MAIL.TXT' ><><><><> ! 10030 OPEN "MAIL.TXT" FOR INPUT AS FILE 11%,RECORDSIZE 49% ! Try to open the MAIL.TXT file if it exists on the account ! 10040 FIELD #11%, 10% AS N0$, 13% AS N1$, 13% AS N2$, 13% AS N3$ \ GET #11%,RECORD 1% ! Read MAIL.TXT header record ! 10050 D$(0%)=N1$+""\ D$(1%)=N2$+""\ D$(2%)=N3$+"" \ D1%=FND%(D$(0%),D$(1%),D%) ! D$(0%) = d/t of latest msg ! D$(1%) = d/t of last MAIL check by user ! D$(2%) = d/t of last LOGIN ! 10060 M0$=FNCVT$(DATE$(0%),-1%)+FNCVT$(TIME$(0%),-1%) \ M0$=LEFT(M0$,11%)+RIGHT(M0$,13%) \ LSET N2$=M0$ \ PUT #11%,RECORD 1% \ CLOSE 11% !Update the d/t of this MAIL check in MAIL.TXT header, then close it ! 10070 GOTO 10900 IF D1%<=0% !Skip to RETURN if no new MAIL 10080 PRINT \ PRINT TAB(6%);"<>< You have received new MAIL during the past "; \ PRINT "year(s)"; IF D1%=1% \ PRINT "month(s)"; IF D1%=2% \ PRINT "few days"; IF D1%=3% \ PRINT "few hours"; IF D1%=4% \ PRINT "few minutes"; IF D1%=5% \ PRINT " ><>" \ PRINT \ PRINT ! Print the appropriate informational message if new MAIL present ! 10900 CLOSE 11% \ RETURN ! 11000 ! !<><><><>< PRINT 'HELP' MESSAGES ><><><><> ! 11005 PRINT \ PRINT STRING$(75%,43%) \ PRINT 11010 PRINT " For information and instructions on the UTMB Department" \ PRINT "of Psychiatry and Behavioural Sciences 'MAIL' system, " \ PRINT "please QUE out or request a copy of 'MAILUS.DOC'. 11020 PRINT \ PRINT "This document is the 'MAIL System User's Guide', and it" \ PRINT "contains all relevant instruction for sending and reading" \ PRINT "messages." 11030 PRINT \ PRINT " If you are a new user, please contact Larry Koolkin at" \ PRINT "765-3219 in order to become a part of the 'MAIL' system" \ PRINT "valid users list. Thank you." 11040 PRINT \ PRINT STRING$(75%,43%) \ PRINT 11900 RETURN ! 12000 ! !<><><><>< PRINT VALID USER LIST ><><><><> ! 12010 OPEN "MAIL:MAIL.LST" FOR INPUT AS FILE 10%,MODE 4096% ! Open the VALID user list file in 'read regardless' mode ! 12011 PRINT \ PRINT "number account MAIL name" \ PRINT "------ ------- ---------" \ PRINT 12012 VNUMB%=0% \ VALID1$="### --> (\ \,\ \) \ \" \ VALID2$="description: \ \" ! Set up print using fields ! 12020 INPUT LINE #10%,VALID$ \ VALID$=FNCVT$(VALID$,5%) ! Read an entry from the VALID list ! 12030 VPROJ$=LEFT(VALID$,4%) \ VPROG$=MID(VALID$,5%,4%) \ VNAME$=MID(VALID$,9%,15%) \ VDESC$=RIGHT(VALID$,37%) ! Entry: project #, programmer #, MAIL name, descriptor string ! 12040 IF LEFT(VPROJ$,1%)="0" THEN VPROJ$=RIGHT(VPROJ$,2%) \ GOTO 12040 12050 IF LEFT(VPROG$,1%)="0" THEN VPROG$=RIGHT(VPROG$,2%) \ GOTO 12050 !Strip of leading zeros from account number ! 12055 VPROJ$="0" IF LEN(VPROJ$)=0% \ VPROG$="0" IF LEN(VPROG$)=0% ! Special case of prog. or proj. number = 0 ! 12060 VNUMB%=VNUMB%+1% \ PRINT USING VALID1$,VNUMB%,VPROJ$,VPROG$,VNAME$ \ PRINT USING VALID2$,VDESC$ \ PRINT ! Actually print the entry ! 12070 GOTO 12020 ! Go back for next entry 12500 CLOSE 10% \ RETURN ! 13000 ! !<><><><>< LOAD ENTIRE LIST RECEIVER TO SEND TO ('ALL' OPTION ) ><><><><> ! 13010 GOSUB 13450 !Read entire valid MAIL user list 13015 RECNUM%,BADLIST%=0% ! Number of receivers, number of those found to be invalid ! 13020 RECNUM%=VALIDATE% \ FOR JUNK%=1% TO RECNUM% \ RECS$(JUNK%)=NUM1$(VAL(VALIDATE$(JUNK%,0%))) + "," + NUM1$(VAL(VALIDATE$(JUNK%,1%))) \ NEXT JUNK% ! Build the PPN strings for the entire MAIL list ! 13030 RETURN ! 13450 ! ! <><><><>< READ MAIL.LST ENTRIES INTO ARRAY VALIDATE$(,) ><><><><> ! 13455 OPEN "MAIL:MAIL.LST" FOR INPUT AS FILE 11%,MODE 4096% !Open the file in read only mode ! 13460 VALIDATE%=0% 13465 INPUT LINE #11%,VALID$ \ VALID$=FNCVT$(VALID$,1%+4%) ! Read an entry ! 13470 VALIDATE%=VALIDATE%+1% \ VALIDATE$(VALIDATE%,0%)=LEFT(VALID$,4%) \ VALIDATE$(VALIDATE%,1%)=MID(VALID$,5%,4%) \ VALIDATE$(VALIDATE%,2%)=MID(VALID$,9%,15%) \ GOTO 13465 ! Load array VALIDATE$(,) from MAIL.LST to verify user requested lists ! 0=proj #, 1=prog #, 2=MAIL system name ! VALIDATE% contains the total number of valid entries in the system ! 13475 CLOSE 11% \ RETURN ! 13500 ! !<><><><>< VALIDATE A REQUESTOR'S RECEIVER LIST TO SEND TO ><><><><> ! 13510 BADLIST%=0% \ GOSUB 13450 ! Initialize # of bad entries in requested list, load MAIL valid list ! 13550 FOR RECPNT%=1% TO RECNUM% !User entered receivers 13560 FOR RECPNT1%=1% TO VALIDATE% !MAIL.LST Valid list 13570 RECPNT2%=INSTR(1%,RECS$(RECPNT%),",") \ GOTO 13572 IF RECPNT2%=0% \ GOTO 13574 IF RECPNT2%<>0% ! If 0, then name comparison; if <> 0 then PPN comparison ! 13572 IF RECS$(RECPNT%)<>FNCVT$(VALIDATE$(RECPNT1%,2%),-1%) THEN 13580 ELSE RECS$(RECPNT%)=NUM1$(VAL(VALIDATE$(RECPNT1%,0%)))+","+NUM1$(VAL(VALIDATE$(RECPNT1%,1%))) \ GOTO 13585 13574 IF (VAL(VALIDATE$(RECPNT1%,0%))= VAL(LEFT(RECS$(RECPNT%),RECPNT2%-1%)) AND VAL(VALIDATE$(RECPNT1%,1%))= VAL(RIGHT(RECS$(RECPNT%),RECPNT2%+1%))) THEN 13585 13580 NEXT RECPNT1% 13583 PRINT "* Name/account ";RECS$(RECPNT%);" is not part of MAIL * \ RECS$(RECPNT%)="" ! If a specified receiver is invalid, print msg and eliminate the name ! 13584 BADLIST%=BADLIST% + 1% !Count of number of invalid receivers requested 13585 NEXT RECPNT% 13588 IF BADLIST%=RECNUM% THEN PRINT "* No valid receivers in list *" \ PRINT \ BADLIST%=-1% ! If entire list is bad, request another command upon return ! 13590 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 13900 RETURN ! 14000 ! !<><><><>< SEND MSG TEXT TO LIST OF VALIDATED RECEIVERS ><><><><> ! 14005 CANTSEND%=0% !# req. recvrs unable to receive now 14010 FOR RECPNT%=1% TO RECNUM% !Loop through receiver PPN's 14020 IF LEN(RECS$(RECPNT%))=0% THEN CANTSEND%=CANTSEND%+1% \ GOTO 14250 ! If this is an invalidated entry, incr. the can't send to count ! and skip to next requested receiver ! 14030 OPEN "["+RECS$(RECPNT%)+"]MAIL.TXT" FOR INPUT AS FILE 9%,RECORDSIZE 49% \ FIELD #9%,5% AS N0$,5% AS N1$,13% AS N2$,13% AS N3$,13% AS N4$ \ GET #9%,RECORD 1% ! Try to open the receiver's MAIL.TXT file for the msg send ! 14032 MSGNO%=VAL(N0$) \ MSGNO$=FNCVT$(NUM1$(MSGNO%+1%),-1%) \ MSGNO$="0"+MSGNO$ UNTIL LEN(MSGNO$)=5% ! Increment current # msgs for this file by one ! 14034 MSGHI%=VAL(N1$) \ MSGHI$=FNCVT$(NUM1$(MSGHI%+1%),-1%) \ MSGHI$="0"+MSGHI$ UNTIL LEN(MSGHI$)=5% ! Increment current highest msg number for this file by one ! 14035 DLATEST$=FNCVT$(DATE$(0%),-1%)+ FNCVT$(LEFT(TIME$(0%),2%),-1%)+ FNCVT$(RIGHT(TIME$(0%),4%),-1%) ! Build d/t string of this msg send for MAIL.TXT header ! 14036 LSET N0$=MSGNO$ \ LSET N1$=MSGHI$ \ LSET N2$=DLATEST$ \ PUT #9%,RECORD 1% \ CLOSE 9% ! Rewrite the updated header record in user's MAIL.TXT file ! 14038 OPEN "["+RECS$(RECPNT%)+"]MAIL.TXT" FOR INPUT AS FILE 9%,MODE 2% ! Re-open the user's MAIL.TXT file for actual msg transfer ! 14040 OPEN "MAIL"+JOBNO$+".TMP" FOR INPUT AS FILE 8%,MODE 4096% ! Open the temp file containing the text to transfer ! 14050 INPUT LINE #8%,JUNK$ \ JUNK$=FNCVT$(JUNK$,1%+4%) \ JUNK$=STX$+MSGHI$+RIGHT(JUNK$,7%) \ PRINT #9%,JUNK$ ! Transfer the msg header first, inserting incremental msg # ! 14060 INPUT LINE #8%,JUNK$ 14070 JUNK$=FNCVT$(JUNK$,1%+4%) \ PRINT #9%,JUNK$ \ GOTO 14060 ! Loop through reading from temp and writing to MAIL.TXT ! 14080 CLOSE 8%,9% 14250 NEXT RECPNT% ! 14500 RETURN ! 20000 ! ! FUNCTION TO COMPARE DATE/TIME STRINGS; RETURN CODES ARE: ! ! negative if first is earlier; positive is second is earlier, ! zero if equal; ! ! numeric value of code indicates at what level the difference occurred: ! 1=yr, 2=mo, 3=day, 4=hr, 5=min ! 20010 !The expected d/t format for D1$/D2$ is dd-MMM-yyhhmm, length of 13 ! 20020 ! 20030 DEF FND%(D1$,D2$,D%) !DATE1, DATE2, RETURN CODE 20040 DIM D0$(12%) 20050 D%=0% \ D1$=FNCVT$(D1$,-1%) \ D2$=FNCVT$(D2$,-1%) ! Initialize return code at 0, FNCVT$ the d/t's 20060 D0$(1%)="JAN" \ D0$(2%)="FEB" \ D0$(3%)="MAR" \ D0$(4%)="APR" \ D0$(5%)="MAY" \ D0$(6%)="JUN" \ D0$(7%)="JUL" \ D0$(8%)="AUG" \ D0$(9%)="SEP" \ D0$(10%)="OCT" \ D0$(11%)="NOV" \ D0$(12%)="DEC" ! Month name list array 20070 ! 20080 Y1$=MID(D1$,8%,2%) \ Y2$=MID(D2$,8%,2%) \ M1$=MID(D1$,4%,3%) \ M2$=MID(D2$,4%,3%) \ H1$=MID(D1$,10%,2%)\ H2$=MID(D2$,10%,2%)\ X1$=RIGHT(D1$,12%) \ X2$=RIGHT(D2$,12%) \ E1$=LEFT(D1$,2%) \ E2$=LEFT(D2$,2%) !E=day; M=month; Y=year; H=hour; X=minute ! 20090 GOTO 20180 IF LEFT(D1$,9%)=LEFT(D2$,9%) ! If dates are same, skip to time check 20100 D%=-1% IF VAL(Y1$) < VAL(Y2$) \ D%=1% IF VAL(Y1$) > VAL(Y2$) \ GOTO 20200 IF D%<>0% !Discriminate on the year first, if possible 20110 ! 20120 FOR D3%=1% TO 12% \ GOTO 20140 IF M1$=D0$(D3%) 20130 NEXT D3% 20140 FOR D2%=1% TO 12% \ GOTO 20160 IF M2$=D0$(D2%) 20150 NEXT D2% !Determine the month numbers (1-12) for the two dates ! 20160 D%=-2% IF D3% < D2% \ D%=2% IF D3% > D2% \ GOTO 20200 IF D%<>0% !Discriminate on the month number next, if possible 20170 D%=-3% IF VAL(E1$) < VAL(E2$) \ D%=3% IF VAL(E1$) > VAL(E2$) \ GOTO 20200 IF D%<>0% !Discriminate on the day next, if possible 20180 D%=-4% IF VAL(H1$) < VAL(H2$) \ D%=4% IF VAL(H1$) > VAL(H2$) \ GOTO 20200 IF D%<>0% !Discriminate on the hour next, if possible 20190 D%=-5% IF VAL(X1$) < VAL(X2$) \ D%=5% IF VAL(X1$) > VAL(X2$) !Discriminate on minutes last, if d/t are same, return code stays 0 ! 20200 FND%=D% \ FNEND 20210 ! 21000 ! ! FUNCTION TO PRINT MESSAGE HEADER RECORDS ! 21010 DEF FNHEAD$(HJUNK%,HJUNK$) 21015 VALID3$="Msg no: ##### From: (#### , ####) / \ \ Sent: \ \ at \\:\\" 21020 PRINT #HJUNK% USING VALID3$,VAL(MID(HJUNK$,2%,5%)), VAL(MID(HJUNK$,7%,4%)), VAL(MID(HJUNK$,11%,4%)), MID(HJUNK$,15%,15%), MID(HJUNK$,30%,9%), MID(HJUNK$,39%,2%), MID(HJUNK$,41%,2%) \ PRINT #HJUNK% RIGHT(HJUNK$,43%) 21030 FNHEAD$=HJUNK$ \ FNEND 21040 ! 21500 ! ! <><><><>< FUNCTION TO DO FNCVT$ ON STRINGS ><><><><> ! 21510 DEF FNCVT$(HJUNK$,HJUNK%) 21520 FNCVT$=CVT$$(HJUNK$,HJUNK%) 21530 FNEND ! 30000 ! !<><><><>< ERROR HANDLING HERE ><><><><> ! 30005 IF ERR=28% THEN RESUME 5 ! Restart the entire program on a CTRL/C ! (can be used amidst session to see if new MAIL has arrived ! during the 'last few minutes'.) ! 30010 IF ERR=11% AND ERL=200 THEN CMD$="EXIT" \ RESUME 220 ! If CTRL/Z entered as a command, fake an EXIT and return ! 30020 IF ERL=200 THEN PRINT "* Illegal Command *" \ PRINT \ RESUME 200 !Trap misc. command entry errors and request another command ! 30030 IF ERR=5% AND ERL=10030 THEN OPEN "MAIL.TXT" FOR OUTPUT AS FILE 11% \ JUNK$=CVT$$(DATE$(0%),-1%)+CVT$$(TIME$(0%),-1%) \ JUNK$=LEFT(JUNK$,11%)+RIGHT(JUNK$,13%) \ PRINT #11%,STRING$(10%,48%)+JUNK$+JUNK$+JUNK$ \ CLOSE 11% \ PRINT \ PRINT "Initializing MAIL.TXT..." \ PRINT \ RESUME 10000 ! If there is no MAIL.TXT file on THIS acct., create one, initialize ! it, and continue ! 30040 IF ERL=12020% THEN RESUME 12500 ! Trap for end of reading the VALID users list file; MAIL.LST ! 30050 IF ERR=10% AND (ERL=10030 OR ERL=10060) THEN PRINT "* Your MAIL.TXT file is currently in use - try later *" \ RESUME 32767 ! If your MAIL.TXT is already opened, you cannot update the header ! until it is free, so exit from the progam for now ! 30060 IF ERR=11% AND ERL=13465 THEN RESUME 13475 ! Trap for while read valid MAIL user list from MAIL.LST ! 30075 IF ERL=13574% THEN RESUME 13583 ! Trap for illegal PPNs, i.e. alphabetics imbedded ! 30077 IF ERL=1020 OR ERL=1370 THEN RESUME 1900 ! Trap for errors while entering 'TO' or 'HEADER' in SEND ! 30080 IF ERL=1420% THEN PRINT "* Unable to open file "+TOFILE$+" *" \ RESUME 1428 ! Trap for inability to find/open specified indirect msg file ! 30090 IF ERL=1425% THEN RESUME 1428 ! Trap for when reading an indirect msg file ! 30100 IF ERR=11% AND ERL=1450 THEN RESUME 1470 ! Trap for end of msg text entry from the terminal ! 30105 IF ERR=5% AND ERL=14030 THEN OPEN "["+RECS$(RECPNT%)+"]MAIL.TXT" FOR OUTPUT AS FILE 11% \ JUNK$=CVT$$(DATE$(0%),-1%)+CVT$$(TIME$(0%),-1%) \ JUNK$=LEFT(JUNK$,11%)+RIGHT(JUNK$,13%) \ PRINT #11%,STRING$(10%,48%)+JUNK$+JUNK$+JUNK$ \ CLOSE 11% \ RESUME 14030 ! If there is no MAIL.TXT file on a valid rec.s acct. when msg is ! being sent; re-create and initialize is on the rec.s acct. ! 30110 IF ERL=14030 OR ERL=14036 OR ERL=14038 THEN PRINT "* Cannot send this msg to "+RECS$(RECPNT%)+" *" \ CANTSEND%=CANTSEND%+1% \ CLOSE 9% \ RESUME 14250 ! Trap for inability to open a valid receiver's MAIL.TXT file ! when trying to update it's header or actually send the msg text ! 30120 IF ERL=14060% THEN RESUME 14080 ! Trap for while reading text temp file for the msg send ! 30125 IF ERR=11% AND ERL=2050 THEN RESUME 2075 ! Print # of text lines in last msg for hdr print on this return ! 30130 IF ERR=11% AND (ERL>=2080% AND ERL<=2440%) THEN RESUME 2900 ! Trap for while reading MAIL.TXT during a LIST command ! 30140 IF ERR=55% AND ERL=2210 THEN PRINT "* More than 10 msg. #'s in LIST *" \ PRINT \ RESUME 2900 ! Only 10 msg allowed in individual LIST format ! 30145 IF (ERR=52% OR ERR=51%) AND (ERL=2210% OR ERL=2400%) THEN PRINT "* Invalid msg # in LIST *" \ PRINT \ RESUME 2900 ! Trap for non-numeric msg numbers in a LIST ! 30150 IF ERR=55% AND ERL=4050 THEN PRINT "* More than 10 msg. #'s in KILL *" \ PRINT \ RESUME 4900 ! Only 10 msg numbers allowed in individual KILL format ! 30155 IF (ERR=52% OR ERR=51%) AND (ERL=4050% OR ERL=4210%) THEN PRINT "* Invalid msg # in KILL *" \ PRINT \ RESUME 4900 ! Trap for non-numeric msg numbers in a KILL ! 30170 IF ERR=11% AND (ERL=4520% OR ERL=4555% OR ERL=4570%) THEN RESUME 4700 ! Trap for when transferring msgs to temp file during KILL ! 30180 IF ERR=55% AND ERL=3060 THEN PRINT "* More than 10 msg. #'s in MOVE *" \ PRINT \ RESUME 3900 ! Only 10 msg numbers allowed in indiv. list MOVE format ! 30190 IF (ERR=52 OR ERR=51%) AND (ERL=3060 OR ERL=3090) THEN PRINT "* Invalid msg # in MOVE *" \ PRINT \ RESUME 3900 ! Trap for non-numeric msg numbers in MOVE ! 30200 IF ERR=11% AND (ERL=3130 OR ERL=3170 OR ERL=3190) THEN RESUME 3210 ! Trap for when transferring msgs to temp file during MOVE ! 30999 ON ERROR GOTO 0 \ STOP ! Misc/unexpected errors ! 31000 !****** PUT IN CTRL/C HANDLING HERE ******* ! 32767 CLOSE JUNK% FOR JUNK%=1% TO 12% \ JUNK$=SYS(CHR$(9%)) \ END ! Exit and clear program !