10 ! ----- MAIL.FUN ----- ! ! ----- FUNCTION TO SEND A MAIL MESSAGE ----- ! ! ----- Last Change 05/01/89 by Brian Lomasky ----- ! ! ----- Teradyne, Inc., 179 Lincoln Street, Boston, MA 02111 ----- ! ----- (617) 482-2706, x3259 ----- ! ! ----- Neither Brian Lomasky nor Teradyne, Inc. implicitly or ----- ! ----- explicitly implies this program is usable in any way. ----- ! ----- This program is released to the public domain in an ----- ! ----- "AS-IS" condition. ----- ! ! ----- Restrictions: ----- ! ----- 1) Requires VAX BASIC V2.4 or later. ----- ! FUNCTION WORD MAIL(STRING NODE, FROM_NAME, TO_LIST(), TO_SHOW, & SUBJECT, TEXT(), WORD BASIC_ERROR, STRING ERROR_TEXT) ! oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ! ----- PASSED PARAMETERS: ----- ! ! Variable: Meaning: Example: ! --------- -------------------------- -------- ! ! NODE NODE TO SEND TO (IGNORED OSCAR:: ! IF MAIL_CHANNEL (12) IS ! ALREADY OPENED BY THE MAIN ! PROGRAM OR BY A PREVIOUS CALL ! TO THIS SUBROUTINE) ! ! FROM_NAME "FROM" USERNAME LOMASKY ! ! TO_LIST() LIST OF "TO" USERNAMES (1 MARTZ ! USERNAME PER ARRAY ELEMENT, WARSEN ! LIST IS TERMINATED BY AN "" ! EMPTY ARRAY ELEMENT, FIRST ! ARRAY ELEMENT USED IS 1) ! ++++++++++++++++++++++++++++ ! >>> WARNING: THESE MUST <<< ! >>> BE UNIQUE NAMES; NO <<< ! >>> DUPLICATE NAMES ARE <<< ! >>> ALLOWED <<< ! ++++++++++++++++++++++++++++ ! ! TO_SHOW WHAT TO SHOW IN "TO:" FIELD "MRP,WOODY" ! ! SUBJECT SUBJECT OF MAIL "Pay Raises" ! ! TEXT() TEXT OF THE MESSAGE (1 LINE "We need" ! PER ARRAY ELEMENT, TEXT IS "a lot more" ! TERMINATED BY AN ARRAY ELEMENT "Money." ! CONTAINING CHR$(255), FIRST CHR$(255%) ! ARRAY ELEMENT USED IS 1) ! oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ! oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ! ----- FUNCTION RETURNS: ----- ! ! MAIL Error Status Code: Meaning: ! 0 SUCCESS ! 1 ERROR DURING FILE OPEN ! 2 ERROR WITH "FROM_NAME" ! 3 ERROR WITH "TO_LIST" ! 4 ERROR WITH "TO_SHOW" ! 5 ERROR WITH "SUBJECT" ! 6 ERROR WITH "TEXT" ! 7 ERROR RECEIVING STATUS ! 8 NO TO_LIST WAS PASSED ! 9 UNEXPECTED ERROR ! 10 DUPLICATE TO_LIST() ERR ! ! BASIC_ERROR BASIC ERR VALUE (0 IF N/A) ! ! ERROR_TEXT ERROR TEXT FROM MAIL SERVER (NULL IF N/A) ! ! oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo ! ====================================================================== ! ----- NOTE: ONCE THIS FUNCTION OPENS THE MAIL SERVER I/O ----- ! ----- CHANNEL ON MAIL_CHANNEL, IT STAYS OPEN TO SAVE THE ----- ! ----- TIME REQUIRED TO OPEN IT AGAIN WITH THE NEXT CALL ----- ! ----- TO THIS FUNCTION. TO USE A DIFFERENT NODE NAME, ----- ! ----- YOU MUST EXPLICITLY CLOSE THE MAIL_CHANNEL BEFORE ----- ! ----- CALLING THIS FUNCTION WITH THE NEW NODE NAME. ----- ! ====================================================================== OPTION TYPE = EXPLICIT %LET %DEBUG = 0% ! 1 IF DEBUG ON, 0 IF DEBUG OFF ON ERROR GOTO MAIL_ERROR ! TRAP ANY ERRORS DECLARE LONG CONSTANT TRUE = (1% = 1%) DECLARE LONG CONSTANT FALSE = NOT TRUE DECLARE WORD CONSTANT UPPERCASE = 32% ! FOR EDIT$ FUNCTION DECLARE WORD ARRAY_COUNTER ! ARRAY INDEX COUNTER DECLARE WORD LOOP ! TRUE TO EXECUTE LOOP DECLARE WORD MAIL_CHANNEL ! MAIL SERVER I/O CHANNEL MAIL_CHANNEL = 12% ! ASSIGN MAIL SERVER I/O CHANNEL DECLARE STRING MESSAGE_RECEIVED ! MESSAGE RECEIVED FROM SERVER DECLARE STRING NODE_NAME ! NODENAME LESS ANY COLONS DECLARE WORD RECEIVERS ! COUNT OF RECEIVERS DECLARE WORD TEMP ! TEMPORARY WORD DECLARE WORD TEMP2 ! TEMPORARY WORD ! ----- LOCAL FUNCTION TO GET A MESSAGE VIA THE SERVER I/O CHANNEL ---- DEF WORD GET_MSG ON ERROR GOTO GET_MSG_ERROR GET_MSG = TRUE ! ASSUME ERROR STATUS GET #MAIL_CHANNEL TEMP = RECOUNT MOVE FROM #MAIL_CHANNEL, MESSAGE_RECEIVED = TEMP GET_MSG = FALSE ! RETURN SUCCESS STATUS EXIT DEF GET_MSG_ERROR: RESUME GET_MSG_EXIT GET_MSG_EXIT: BASIC_ERROR = ERR ! RETURN BASIC ERROR CODE END DEF ! ----- LOCAL FUNCTION TO SEND A MESSAGE VIA THE SERVER I/O CHANNEL ---- DEF WORD PUT_MSG(STRING MESSAGE_TO_SEND) ON ERROR GOTO PUT_MSG_ERROR PUT_MSG = TRUE ! ASSUME ERROR STATUS TEMP = LEN(MESSAGE_TO_SEND) MOVE TO #MAIL_CHANNEL, MESSAGE_TO_SEND = TEMP PUT #MAIL_CHANNEL, COUNT TEMP PUT_MSG = FALSE ! RETURN SUCCESS STATUS EXIT DEF PUT_MSG_ERROR: RESUME PUT_MSG_EXIT PUT_MSG_EXIT: BASIC_ERROR = ERR ! RETURN BASIC ERROR CODE END DEF ! ----- LOCAL FUNCTION TO CHECK TO SEE IF THE MESSAGE JUST SENT ----- ! ----- WAS RECEIVED OK ----- DEF WORD CHECK_STATUS CHECK_STATUS = TRUE ! ASSUME ERROR STATUS ! ----- GET NEXT MESSAGE FROM RECEIVER ----- %IF %DEBUG = 1% %THEN PRINT "CHECK_STATUS: Get next message from receiver..." %END %IF EXIT DEF IF GET_MSG ! EXIT IF TRANSMISSION ERROR ! ----- SEE IF SUCCESS ----- IF (ASCII(MESSAGE_RECEIVED) AND 1%) = 1% THEN %IF %DEBUG = 1% %THEN PRINT "CHECK_STATUS: Success!!!" %END %IF CHECK_STATUS = FALSE ! RETURN SUCCESS STATUS EXIT DEF END IF ! ----- AN ERROR OCCURRED; READ ERROR TEXT ----- ERROR_TEXT = "" LOOP = TRUE ! SO LOOP WILL EXECUTE ONCE WHILE LOOP %IF %DEBUG = 1% %THEN PRINT "CHECK_STATUS: Read Error Text..." %END %IF EXIT DEF IF GET_MSG ! EXIT IF TRANSMISSION ERROR ! ----- SEE IF TEXT WAS READ ----- IF LEN(MESSAGE_RECEIVED) <> 1% THEN %IF %DEBUG = 1% %THEN PRINT "CHECK_STATUS: Append"; & " Error Text..." %END %IF ! ----- APPEND MESSAGE TEXT TO ERROR STRING ---- ERROR_TEXT = ERROR_TEXT + & MESSAGE_RECEIVED + CHR$(13%) ELSE IF ASCII(MESSAGE_RECEIVED) = 0% THEN ! ----- DONE WHEN A ZERO BYTE IS ----- ! ----- RECEIVED ----- LOOP = FALSE ELSE %IF %DEBUG = 1% %THEN PRINT "CHECK_STATUS:"; & " ASCII Byte="; & ASCII(MESSAGE_RECEIVED) %END %IF END IF END IF NEXT %IF %DEBUG = 1% %THEN PRINT "CHECK_STATUS: Exit Error Text Loop..." %END %IF LOOP = TRUE ! FIX FOR CALLING LOOP END DEF ! >>>>>>>>>>>>>>>>>>>> START OF MAIN FUNCTION <<<<<<<<<<<<<<<<<<<< BASIC_ERROR = 0% ! ASSUME NO BASIC ERROR CODE ERROR_TEXT = "" ! ASSUME NO SERVER ERROR TEXT ! ----- COUNT NUMBER OF ENTRIES (AND UPPERCASE) IN TO_LIST ARRAY ----- ARRAY_COUNTER = 1% WHILE TO_LIST(ARRAY_COUNTER) <> "" TO_LIST(ARRAY_COUNTER) = EDIT$(TO_LIST(ARRAY_COUNTER),UPPERCASE) ARRAY_COUNTER = ARRAY_COUNTER + 1% NEXT ARRAY_COUNTER = ARRAY_COUNTER - 1% IF ARRAY_COUNTER = 0% THEN MAIL = 8% ! RETURN NO TO_LIST ERROR EXIT FUNCTION END IF ! ----- COMPARE THEM AND EXIT IF ANY DUPLICATE NAMES ENCOUNTERED ----- TEMP = 0% MAIL = 10% ! ASSUME DUPLICATE TO_LIST ERROR WHILE TEMP < ARRAY_COUNTER TEMP = TEMP + 1% TEMP2 = TEMP WHILE TEMP2 < ARRAY_COUNTER TEMP2 = TEMP2 + 1% EXIT FUNCTION IF TO_LIST(TEMP) = TO_LIST(TEMP2) NEXT NEXT MAIL = 9% ! ASSUME UNEXPECTED ERROR ! ----- OPEN CHANNEL TO MAIL SERVER ----- %IF %DEBUG = 1% %THEN PRINT "Seeing if I/O channel is already opened..." %END %IF IF BUFSIZ(MAIL_CHANNEL) = 0% THEN ! IF NOT EXTERNALLY OPENED: TEMP = POS(NODE + ":", ":", 1%) ! LOCATE FIRST COLON IN NODE NODE_NAME = LEFT(NODE, TEMP - 1%) ! EXTRACT NODE LESS COLONS MAIL = 1% ! ASSUME ERROR DURING FILE OPEN %IF %DEBUG = 1% %THEN PRINT "Opening channel to mail server..." %END %IF ERROR_TEXT = "**" + NODE_NAME + '::"27="' + "**" OPEN NODE_NAME + '::"27="' AS FILE #MAIL_CHANNEL MAIL = 9% ! ASSUME UNEXPECTED ERROR END IF ERROR_TEXT = "" ! ASSUME NO SERVER ERROR TEXT LOOP = TRUE ! SO LOOP WILL EXECUTE WHILE LOOP ! START LOOP LOOP = FALSE ! ASSUME LOOP WILL EXIT MAIL = 2% ! ASSUME ERROR WITH "FROM_NAME" %IF %DEBUG = 1% %THEN PRINT "Sending the FROM: information..." %END %IF ITERATE IF PUT_MSG(FROM_NAME) ! SEND THE "FROM" INFORMATION RECEIVERS = 0% ! INIT COUNT OF RECEIVERS ARRAY_COUNTER = 1% ! INIT PASSED ARRAY INDEX ! ----- SEND EACH MESSAGE WHICH STATES WHO SHOULD RECEIVE ----- ! ----- THE TEXT ON THE OTHER SIDE ----- MAIL = 3% ! ASSUME ERROR WITH "TO_LIST" LOOP = TRUE ! SO LOOP MIGHT EXECUTE ONCE WHILE TO_LIST(ARRAY_COUNTER) <> "" AND BASIC_ERROR = 0% AND LOOP %IF %DEBUG = 1% %THEN PRINT "Sending TO_LIST("; & NUM1$(ARRAY_COUNTER); ")..." %END %IF ITERATE IF PUT_MSG(TO_LIST(ARRAY_COUNTER)) %IF %DEBUG = 1% %THEN PRINT "Checking Status..." %END %IF ITERATE IF CHECK_STATUS ! ----- COUNT A SUCCESSFUL RECEIVER ----- RECEIVERS = RECEIVERS + 1% ARRAY_COUNTER = ARRAY_COUNTER + 1% NEXT LOOP = FALSE ! SO LOOP WILL LATER EXIT ! ----- TERMINATE THE LIST OF RECEIVERS WITH A ONE-BYTE ----- ! ----- NULL RECORD ----- %IF %DEBUG = 1% %THEN PRINT "Sending Null Terminator..." %END %IF ITERATE IF PUT_MSG(CHR$(0%)) ! PUT THE NULL RECORD MAIL = 9% ! ASSUME UNEXPECTED ERROR ITERATE IF RECEIVERS = 0% ! END PROGRAM IF NO RECEIVERS ! ----- SEND THE TEXT THAT SHOWS UP IN THE "TO:" FIELD OF ----- ! ----- MAIL ----- MAIL = 4% ! ASSUME ERROR WITH "TO_SHOW" %IF %DEBUG = 1% %THEN PRINT "Sending TO: information..." %END %IF ITERATE IF PUT_MSG(TO_SHOW) ! PUT THE TEXT ! ----- SEND THE SUBJECT ----- MAIL = 5% ! ASSUME ERROR WITH "SUBJECT" %IF %DEBUG = 1% %THEN PRINT "Sending the Subject..." %END %IF ITERATE IF PUT_MSG(SUBJECT) ! PUT THE TEXT ! ----- SEND THE TEXT OF THE MESSAGE ----- MAIL = 6% ! ASSUME ERROR WITH "TEXT" ARRAY_COUNTER = 1% ! INIT TEXT ARRAY COUNTER WHILE TEXT(ARRAY_COUNTER) <> CHR$(255) AND BASIC_ERROR = 0% %IF %DEBUG = 1% %THEN PRINT "Sending TEXT("; & NUM1$(ARRAY_COUNTER); ")..." %END %IF ITERATE IF PUT_MSG(TEXT(ARRAY_COUNTER)) ARRAY_COUNTER = ARRAY_COUNTER + 1% NEXT ! ----- TERMINATE THE TEXT LIST WITH A ONE-BYTE NULL RECORD ---- %IF %DEBUG = 1% %THEN PRINT "Sending Null Terminator..." %END %IF ITERATE IF PUT_MSG(CHR$(0%)) ! PUT THE NULL RECORD ! ----- LOOP THROUGH AND RECEIVE THE STATUS CODE FOR ALL ----- ! ----- USERS THE MAIL WAS SENT TO ----- MAIL = 7% ! ASSUME STATUS CODE ERROR ARRAY_COUNTER = 0% ! INIT COUNTER LOOP = TRUE ! SO LOOP MIGHT EXECUTE ONCE WHILE ARRAY_COUNTER < RECEIVERS AND BASIC_ERROR = 0% AND LOOP ARRAY_COUNTER = ARRAY_COUNTER + 1% %IF %DEBUG = 1% %THEN PRINT "Checking Status for receiver #"; & NUM1$(ARRAY_COUNTER); "..." %END %IF ITERATE IF CHECK_STATUS NEXT LOOP = FALSE ! SO LOOP WILL EXIT NEXT MAIL = 0% ! RETURN SUCCESS STATUS %IF %DEBUG = 1% %THEN PRINT "----- Exiting MAIL Function -----" %END %IF EXIT FUNCTION MAIL_ERROR: RESUME MAIL_ERROR_EXIT ! ALL ERRORS ARE FATAL MAIL_ERROR_EXIT: BASIC_ERROR = ERR ! RETURN BASIC ERROR CODE %IF %DEBUG = 1% %THEN PRINT "Error "; NUM1$(BASIC_ERROR); " occurred..." PRINT "----- Exiting MAIL Function -----" %END %IF END FUNCTION