IDENTIFICATION DIVISION. PROGRAM-ID. SENDMAIL. ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. INTERACTIVE-COBOL. OBJECT-COMPUTER. INTERACTIVE-COBOL. SPECIAL-NAMES. "@AUDIT" IS AUDIT-LOG. * Sample program using the IC_SEND_MAIL builtin * added in 3.50 of ICOBOL * * * Make sure the the environment parament ICSMTPSERVER is set * to find the SMTP server. (ICSMTPPORT is optional) * * RHJ 3.50 New. * 3.57 Updated for username/password support * 3.65 Updated with Help, etc. * 4.10 Updated to allow use of file for To:'s, * Support for a csv file, * progress reporting for To file * Errors are reported to audit-log (icrun -a) * 4.41 v6 Allow interactive support for To-file * v7 Allow for an argument column when using a csv file * Allow for an array of TOs that can be pasted in * Some pre checking before passing to emailer * 4.42 v8 Enhanced send-mail with more attachments * * INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT FILE-DSINPUT ASSIGN TO DISK, FILE-INPUT-NAME; ORGANIZATION IS LINE SEQUENTIAL; RECORD DELIMITER IS DATA-SENSITIVE, DELIMITER INTO DELIMIT; ACCESS MODE IS SEQUENTIAL; FILE STATUS IS FILE-STATUS. DATA DIVISION. FILE SECTION. * File used to input a list of To's FD FILE-DSINPUT RECORD IS VARYING IN SIZE FROM 1 TO 2048 CHARACTERS DEPENDING ON DSINPUT-SIZE. 01 FILE-DSINPUT-RECORD. 02 FILE-DSINPUT-DATA PIC X(2048). WORKING-STORAGE SECTION. 77 FILE-INPUT-NAME PIC X(128). 77 FILE-STATUS PIC X(2). 77 DELIMIT PIC X(2). 77 DSINPUT-SIZE PIC 9(4). 77 FILE-ERROR PIC 9 VALUE 0. 77 EOF-FLAG PIC 9 VALUE 0. 77 SAVE-TO-LIST PIC X(80). 77 FILE-LIST PIC 9. 77 LOOP-FOR-TO PIC 9 VALUE 0. 77 CSV-FILE PIC 9 VALUE 0. 77 CSV-FILE-DELIMITER PIC X VALUE ",". 77 CSV-FILE-TO-COLUMN PIC 99 VALUE 0. 77 CSV-FILE-ARG-COLUMN PIC 99 VALUE 0. 77 FIND-ARG PIC 9999. 77 CSV-ARG PIC X(70) VALUE SPACES. 77 CSV-ARG-LEN PIC 9(4). 77 CSV-ARG-DISPLAY PIC X(5) VALUE "Arg: ". 77 CSV-LOOP PIC 99. 77 CSV-HAD-ERROR PIC 9 VALUE 0. 77 CSV-POSITION PIC 9(4). 77 CSV-VALUE PIC X(80). 01 TAB-VALUE-DEC PIC 99 COMP VALUE 9. 01 TAB-VALUE-CHAR REDEFINES TAB-VALUE-DEC PIC X. 01 SAW-SEND-ERROR PIC 9 VALUE 0. 77 ICSMTPSERVER-ENV PIC X(20) VALUE "ICSMTPSERVER". 77 ICSMTPSERVER-ENTRY PIC X(70) VALUE SPACES. 01 HOLD-TOTAL-BODY. 04 HOLD-BODY-PART OCCURS 12 TIMES PIC X(80). 01 MAIL-STUFF. 02 FROM-ADDR PIC X(80). 02 TO-LIST PIC X(80). 02 CC-LIST PIC X(80). 02 BCC-LIST PIC X(80). 02 SUBJECT PIC X(80). 02 TOTAL-BODY. 04 BODY-PART OCCURS 12 TIMES PIC X(80). 02 MIME-TYPE1 PIC X(20). 02 ATT-FILE1 PIC X(80). 02 USER-PASS-ENTRY PIC X(70). 02 MIME-TYPE2 PIC X(20). 02 ATT-FILE2 PIC X(80). 02 MIME-TYPE3 PIC X(20). 02 ATT-FILE3 PIC X(80). 02 MIME-TYPE4 PIC X(20). 02 ATT-FILE4 PIC X(80). 02 MIME-TYPE5 PIC X(20). 02 ATT-FILE5 PIC X(80). 02 MIME-TYPE6 PIC X(20). 02 ATT-FILE6 PIC X(80). 02 MIME-TYPE7 PIC X(20). 02 ATT-FILE7 PIC X(80). 02 MIME-TYPE8 PIC X(20). 02 ATT-FILE8 PIC X(80). 02 MIME-TYPE9 PIC X(20). 02 ATT-FILE9 PIC X(80). 02 MIME-TYPE10 PIC X(20). 02 ATT-FILE10 PIC X(80). 01 ATT-NUMBER PIC 99. 01 START-LOC PIC 9(5). 01 BODY-LEN PIC 9(5). 01 BODY-TEXT-SIZE PIC 9(5) VALUE 4000. 01 BODY-TEXT PIC X(4000). 01 WORK-BODY-TEXT PIC X(4000). 01 BODY-TEXT-START PIC 9(5). 01 BODY-TEXT-LEN PIC 9(5). 01 EXCEPTION-STATUS PIC 9(5). 01 EXCEPT-MSG PIC X(60). 01 ESC-CODE PIC 99. 01 LAST-ESC-CODE PIC 99. 01 ANY-KEY PIC X. 77 COUNT-LINES PIC 9(5). 77 COUNT-MESSAGES PIC 9(5). 77 COUNT-MESSAGES-IN-ERROR PIC 9(5). * Default values for a 24 by 80 screen 77 ICCOLS-SETN PIC 9(3) VALUE 80. 77 ICCOLS-SETN-20 PIC 9(3) VALUE 60. 77 ICLINES-SETN PIC 9(3) VALUE 24. 77 ICLINES-SETN-1 PIC 9(3) VALUE 23. 77 ICLINES-SETN-2 PIC 9(3) VALUE 22. 77 ICLINES-SETN-3 PIC 9(3) VALUE 21. 77 ICLINES-SETN-DIV2 PIC 9(3) VALUE 12. 01 STRING-ARRAY. 02 STRING-VAL OCCURS 120 TIMES PIC X(80). 01 FULL-STRING PIC X(5000) VALUE SPACES. 01 LEN PIC 9(4). 01 CNT PIC 9(4). 01 CNT-I PIC 9(4). 01 I PIC 9(4). 01 J PIC 9(4). 01 K PIC 9(4). 01 LAST-BYTE PIC 9(4). 01 ESC-KEY PIC 99. 01 TO-ENTRY PIC 9 VALUE 1. 01 TO-ENTRY-TYPES-SETTING PIC X(40) VALUE "entry TO: file TO: .csv TO: array TO: ". 01 TO-ENTRYS REDEFINES TO-ENTRY-TYPES-SETTING. 02 TO-ENTRY-TYPES OCCURS 4 TIMES PIC X(10). 01 RUNTIME-VERSION. 02 RUNTIME-MAJOR PIC 9. 02 FILLER PIC X. 02 RUNTIME-MINOR PIC 99. 02 RUNTIME-BETA PIC X(12). SCREEN SECTION. 01 BLANK-SCREEN. 02 BLANK SCREEN. 01 HELP-SCREEN-BLANKS. 02 LINE 6 BLANK LINE. 02 LINE 7 BLANK LINE. 02 LINE 8 BLANK LINE. 02 LINE 9 BLANK LINE. 02 LINE 10 BLANK LINE. 02 LINE 11 BLANK LINE. 02 LINE 12 BLANK LINE. 02 LINE 13 BLANK LINE. 02 LINE 14 BLANK LINE. 02 LINE 15 BLANK LINE. 02 LINE 16 BLANK LINE. 02 LINE 17 BLANK LINE. 02 LINE 18 BLANK LINE. 02 LINE 19 BLANK LINE. 02 LINE 20 BLANK LINE. 02 LINE 21 BLANK LINE. 02 LINE 22 BLANK LINE. 02 LINE 24 BLANK LINE. 01 HELP-SCREEN. 02 LINE 6 COL 10 BRIGHT UNDERLINE "Help Selection:". 02 LINE 8 COL 1 "To:, Fr:, Subject:, and SMTP entries are required". 02 LINE 9 COL 1 "cc:, bc:, mine:, file: entries can be blank". 02 LINE 10 COL 1 " To:, cc:, bc:, can be a list of addresses separated by comma". 02 LINE 11 COL 1 " To can also be a text file with a list of email addresses,". 02 LINE 12 COL 1 " a .csv file with a list of email addresses in a particular column, or". 02 LINE 13 COL 1 " an array (upto 120) of items". 02 LINE 14 COL 1 "mime: entry must be blank unless a file: is to be passed". 02 LINE 15 COL 1 " then it must be a valid type: Text, Video, ...". 02 LINE 16 COL 1 "user,pass: entry is required if the SMTP server requires Authorization". 02 LINE 17 COL 1 " then it must match that required by the server, password is case sensitive". 02 LINE 18 COL 1 " To debug, use the -ai switches to icrun". 02 LINE 19 COL 1 "When using a file, each line will be sent as a separate email". 02 LINE 20 COL 1 "When using an array, each array element will be sent as a separate email". 02 LINE 21 COL 1 "When using a .csv file, an argument-column can be specifed as $arg in the body". 02 LINE 22 COL 1 " the $arg will be replaced by the data from the argument-column". 02 LINE 24 COL 1 "Hit any key to clear Help". 02 AUTO PIC X TO ANY-KEY. 01 MAIN-SCREEN. 02 LINE 1 BLANK LINE. 02 COL 10 BRIGHT " Sample Mail Sender v8". 02 SMTP-ENTRY. 04 COL 40 "SMTP: ". 04 PIC X(30) USING ICSMTPSERVER-ENTRY. 02 MAIN-ENTRY. 03 MAIN-ENTRY-TO. 04 LINE 2 COL 1 PIC X(10) FROM TO-ENTRY-TYPES (TO-ENTRY). 04 PIC X(70) USING TO-LIST. 03 FILLER. 04 LINE 3 COL 1 "Fr: ". 04 PIC X(75) USING FROM-ADDR. 04 LINE 4 COL 1 "cc: ". 04 PIC X(75) USING CC-LIST. 04 LINE 5 COL 1 "bc: ". 04 PIC X(75) USING BCC-LIST. 04 LINE 6 COL 1 "Subject: ". 04 PIC X(40) USING SUBJECT. 04 LINE 7 COL 1 "attachments: ". 04 PIC Z9 FROM ATT-NUMBER. 04 USER-ENTRY. 05 LINE 8 COL 1 "user/pass:". 05 PIC X(70) USING USER-PASS-ENTRY. 04 LINE 9 COL 1 "body: (use \\ in body for extra lines)". 04 LINE 10 COL 1 PIC X(80) USING BODY-PART (1). 04 LINE 11 COL 1 PIC X(80) USING BODY-PART (2). 04 LINE 12 COL 1 PIC X(80) USING BODY-PART (3). 04 LINE 13 COL 1 PIC X(80) USING BODY-PART (4). 04 LINE 14 COL 1 PIC X(80) USING BODY-PART (5). 04 LINE 15 COL 1 PIC X(80) USING BODY-PART (6). 04 LINE 16 COL 1 PIC X(80) USING BODY-PART (7). 04 LINE 17 COL 1 PIC X(80) USING BODY-PART (8). 04 LINE 18 COL 1 PIC X(80) USING BODY-PART (9). 04 LINE 19 COL 1 PIC X(80) USING BODY-PART (10). 04 LINE 20 COL 1 PIC X(80) USING BODY-PART (11). * UNDERLINE here shows the end of the message body 04 LINE 21 COL 1 UNDERLINE PIC X(80) USING BODY-PART (12). 02 LINE 22 BLANK LINE. 02 LINE 23 COL 1 "To:/Fr:/Subj: are required.". 02 LINE 23 COL 30 BOLD "toggle To: F1-entry, F2-file, F3-csv, F4-array". 02 LINE 24 COL 1 BLANK LINE BOLD "F5-send (sF5-interactive), F6-SMTP, F7-help, F8-att, ESC-cycle, ESC/ESC-exit". 01 MAIN-SCREEN-LOOP. 02 LINE 1 COL 10 BRIGHT " Sample Mail Sender v8". 02 SMTP-ENTRY-LOOP. 04 COL 40 "SMTP: ". 04 PIC X(30) USING ICSMTPSERVER-ENTRY. 02 MAIN-ENTRY-LOOP. 03 FILLER. 04 LINE 2 COL 1 PIC X(10) FROM TO-ENTRY-TYPES (TO-ENTRY). 04 PIC X(70) USING TO-LIST. 04 LINE 3 COL 1 "Fr: ". 04 PIC X(75) FROM FROM-ADDR. 04 LINE 4 COL 1 "cc: ". 04 PIC X(75) FROM CC-LIST. 04 LINE 5 COL 1 "bc: ". 04 PIC X(75) FROM BCC-LIST. 04 LINE 6 COL 1 "Subject: ". 04 PIC X(40) FROM SUBJECT. 04 LINE 7 COL 1 "attachments: ". 04 PIC Z9 FROM ATT-NUMBER. 04 USER-ENTRY. 05 LINE 8 COL 1 "user/pass:". 05 PIC X(70) FROM USER-PASS-ENTRY. 04 LINE 9 COL 1 "body: (use \\ in body for extra lines)". 04 LINE 10 COL 1 PIC X(80) USING BODY-PART (1). 04 LINE 11 COL 1 PIC X(80) USING BODY-PART (2). 04 LINE 12 COL 1 PIC X(80) USING BODY-PART (3). 04 LINE 13 COL 1 PIC X(80) USING BODY-PART (4). 04 LINE 14 COL 1 PIC X(80) USING BODY-PART (5). 04 LINE 15 COL 1 PIC X(80) USING BODY-PART (6). 04 LINE 16 COL 1 PIC X(80) USING BODY-PART (7). 04 LINE 17 COL 1 PIC X(80) USING BODY-PART (8). 04 LINE 18 COL 1 PIC X(80) USING BODY-PART (9). 04 LINE 19 COL 1 PIC X(80) USING BODY-PART (10). 04 LINE 20 COL 1 PIC X(80) USING BODY-PART (11). * UNDERLINE here shows the end of the message body 04 LINE 21 COL 1 UNDERLINE PIC X(80) USING BODY-PART (12). 02 LINE 22 BLANK LINE COL 1 PIC X(5) FROM CSV-ARG-DISPLAY. 02 BOLD PIC X(70) FROM CSV-ARG. 02 LINE 23 BLANK LINE COL 1 " Only the Body can be changed". 02 LINE 24 COL 1 BLANK LINE BOLD "F1-send (In loop mode), F2-skip, ESC-exit". 01 CSV-SETUP-NO-TAB. 02 CSV-SETUP-DISPLAY-NO-TAB. 04 LINE 22 BLANK LINE "CSV processing of To-file, To column is: ". 04 PIC Z9 USING CSV-FILE-TO-COLUMN. 04 " delimiter: ". 04 PIC X USING CSV-FILE-DELIMITER. 04 " argument col: ". 04 PIC Z9 USING CSV-FILE-ARG-COLUMN. 02 LINE 23 BLANK LINE. 02 LINE 24 BLANK LINE BOLD "F3-set delimiter to TAB". 01 CSV-SETUP-TAB. 02 CSV-SETUP-DISPLAY-TAB. 04 LINE 22 BLANK LINE "CSV processing of To-file, To column is: ". 04 PIC Z9 USING CSV-FILE-TO-COLUMN. 04 " delimiter: ". 04 BOLD "". * 04 LINE 23 BLANK LINE " extra argument column is: ". 04 " argument col: ". 04 PIC Z9 USING CSV-FILE-ARG-COLUMN. 02 LINE 23 BLANK LINE. 02 LINE 24 BLANK LINE BOLD "F3-unset TAB delimiter". 01 MAIN-SCREEN-FILES. 05 LINE 3 BLANK LINE. 05 LINE 4 BLANK LINE. 05 LINE 5 BLANK LINE. 05 COL 5 "Attachments". 05 LINE 6 COL 1 "mime-type: ". 05 COL 20 "filename:". 05 LINE 7 COL 1 PIC X(15) USING MIME-TYPE1. 05 COL 20 PIC X(60) USING ATT-FILE1. 05 LINE 8 COL 1 PIC X(15) USING MIME-TYPE2. 05 COL 20 PIC X(60) USING ATT-FILE2. 05 LINE 9 COL 1 PIC X(15) USING MIME-TYPE3. 05 COL 20 PIC X(60) USING ATT-FILE3. 05 LINE 10 COL 1 PIC X(15) USING MIME-TYPE4. 05 COL 20 PIC X(60) USING ATT-FILE4. 05 LINE 11 COL 1 PIC X(15) USING MIME-TYPE5. 05 COL 20 PIC X(60) USING ATT-FILE5. 05 LINE 12 COL 1 PIC X(15) USING MIME-TYPE6. 05 COL 20 PIC X(60) USING ATT-FILE6. 05 LINE 13 COL 1 PIC X(15) USING MIME-TYPE7. 05 COL 20 PIC X(60) USING ATT-FILE7. 05 LINE 14 COL 1 PIC X(15) USING MIME-TYPE8. 05 COL 20 PIC X(60) USING ATT-FILE8. 05 LINE 15 COL 1 PIC X(15) USING MIME-TYPE9. 05 COL 20 PIC X(60) USING ATT-FILE9. 05 LINE 16 COL 1 PIC X(15) USING MIME-TYPE10. 05 COL 20 PIC X(60) USING ATT-FILE10. 05 LINE 20 COL 1 "mime-types: text, video, application/pdf, ". 05 LINE 22 "ESC return to the main screen". 05 LINE 23 BLANK LINE. 01 BL-22. 02 LINE 22 BLANK LINE. 01 BL-23. 02 LINE 23 BLANK LINE. 01 POSITION-SCREEN. 02 LINE 22 COL 1 BLANK LINE. 01 ERROR-MESSAGE-COUNT. 02 LINE 25 COL 1 "Line: ". 02 PIC ZZ9 FROM COUNT-LINES. 02 " Error: ". 02 PIC ZZZZ9 FROM EXCEPTION-STATUS. 02 COL PLUS 1 PIC X(55) USING EXCEPT-MSG. 01 ERROR-MESSAGE. 02 LINE 25 COL 1 BLANK LINE "Error: ". 02 PIC ZZZZ9 FROM EXCEPTION-STATUS. 02 COL PLUS 1 PIC X(60) USING EXCEPT-MSG. 01 GOOD-MESSAGE. 02 LINE 25 COL 1 BLANK LINE "Success: ". 02 PIC ZZZZ9 FROM EXCEPTION-STATUS. 02 COL PLUS 1 PIC X(60) USING EXCEPT-MSG. 01 GOOD-MESSAGES. 02 LINE 25 COL 1 "Processed ". 02 PIC ZZZZ9 FROM COUNT-LINES. 02 " lines with ". 02 PIC ZZZZ9 FROM COUNT-MESSAGES. 02 " messages and ". 02 PIC ZZZZ9 FROM COUNT-MESSAGES-IN-ERROR. 02 " with an error.". 01 ERROR-MESSAGE-BLANK. 02 LINE 25 BLANK LINE. 01 TO-MAIN-SCREEN. 02 LINE 1 COL 1 BRIGHT "Input/Paste TO: array(max 120)". 02 COL 32 BRIGHT "F1-process, F2-clear array, ESC-return". 02 LINE PLUS 1 COL 1. 02 OCCURS 120 TIMES PIC X(80) USING STRING-VAL. 01 DATA-SCREEN. 02 LINE 4 COL 1 "Non-blank Entries: ". 02 BRIGHT PIC ZZ9 FROM CNT. 02 " total length: ". 02 BRIGHT PIC ZZZ9 FROM LEN. 02 LINE 5 COL 1 ERASE EOS. PROCEDURE DIVISION. DECLARATIVES. FILE-DSINPUT-ERROR SECTION. USE AFTER ERROR PROCEDURE ON FILE-DSINPUT. FILE-DSINPUT-ERROR-PROCESS. ACCEPT EXCEPTION-STATUS FROM EXCEPTION. CALL "IC_MSG_TEXT" USING EXCEPTION-STATUS, EXCEPT-MSG IF FILE-STATUS = "91" AND EXCEPTION-STATUS = 40 NEXT SENTENCE ELSE DISPLAY ERROR-MESSAGE. MOVE 1 TO FILE-ERROR. END DECLARATIVES. MAIN SECTION. START-UP. DISPLAY "Starting SendMailv8" UPON AUDIT-LOG. CALL "IC_VERSION" USING RUNTIME-VERSION. * Initialize input MOVE SPACES TO MAIL-STUFF, STRING-ARRAY. * MOVE "text" to MIME-TYPE. * Clear screen DISPLAY BLANK-SCREEN. CALL "IC_GET_ENV" USING ICSMTPSERVER-ENV, ICSMTPSERVER-ENTRY ON EXCEPTION * Could show warning DISPLAY " SendMail Error: SMTP server not set" UPON AUDIT-LOG END-CALL. MAIL-IT. * main Mail Loop * If previous message was sent successfully could do the following ** IF SAW-SEND-ERROR = 0 * Could do the following to clear the mail area of everything but the From ** MOVE SPACES TO MAIL-STUFF (81:). * OR * Could do the following to clear the mail area of everything ** MOVE SPACES TO MAIL-STUFF. * DISPLAY BLANK-SCREEN. DISPLAY MAIN-SCREEN. IF TO-ENTRY = 3 IF CSV-FILE-DELIMITER = TAB-VALUE-CHAR DISPLAY CSV-SETUP-DISPLAY-TAB ELSE DISPLAY CSV-SETUP-DISPLAY-NO-TAB END-IF END-IF. ACCEPT MAIN-ENTRY. * Clear message line from previous loop DISPLAY ERROR-MESSAGE-BLANK. ACCEPT ESC-CODE FROM ESCAPE. IF ESC-CODE = 1 * ESC IF LAST-ESC-CODE = 1 GO TO END-IT-EXIT END-IF END-IF. MOVE ESC-CODE TO LAST-ESC-CODE. IF ESC-CODE = 2 * F1, simple TO entry MOVE 1 TO TO-ENTRY GO TO MAIL-IT. IF ESC-CODE = 3 * F2 file-list of TOs MOVE 2 TO TO-ENTRY Go TO MAIL-IT. IF ESC-CODE = 4 * F3 Set up .csv file for TOs MOVE 3 TO TO-ENTRY IF TO-ENTRY = 3 DISPLAY MAIN-ENTRY-TO PERFORM WITH TEST AFTER UNTIL ESC-CODE = 1 OR ESC-CODE = 0 MOVE 0 TO ESC-CODE IF CSV-FILE-DELIMITER = TAB-VALUE-CHAR DISPLAY CSV-SETUP-TAB ACCEPT CSV-SETUP-TAB ON ESCAPE ACCEPT ESC-CODE FROM ESCAPE IF ESC-CODE = 4 MOVE "," TO CSV-FILE-DELIMITER END-IF END-ACCEPT ELSE DISPLAY CSV-SETUP-NO-TAB ACCEPT CSV-SETUP-NO-TAB ON ESCAPE ACCEPT ESC-CODE FROM ESCAPE IF ESC-CODE = 4 MOVE TAB-VALUE-CHAR TO CSV-FILE-DELIMITER END-IF END-ACCEPT END-IF IF ESC-CODE = 1 MOVE 0 TO CSV-FILE END-IF END-PERFORM DISPLAY BL-22 END-IF MOVE 0 TO ESC-CODE GO TO MAIL-IT END-IF. IF ESC-CODE = 5 * F4 , array of values for TOs MOVE 4 TO TO-ENTRY PERFORM PROCESS-TOS-MSG THRU PROCESS-TOS-MSG-END MOVE FULL-STRING TO TO-LIST GO TO MAIL-IT. IF ESC-CODE = 6 OR ESC-CODE = 14 * F5/sF5 send mail PERFORM PRE-CHECK IF EXCEPTION-STATUS = 0 PERFORM PROCESS-TO-MSG THRU PROCESS-TO-MSG-END END-IF GO TO MAIL-IT. IF ESC-CODE = 7 * F6 Change SMTP ACCEPT SMTP-ENTRY ACCEPT ESC-CODE FROM ESCAPE IF ESC-CODE = 1 GO TO END-IT-EXIT END-IF CALL "IC_SET_ENV" USING ICSMTPSERVER-ENV, ICSMTPSERVER-ENTRY ON EXCEPTION ACCEPT EXCEPTION-STATUS FROM EXCEPTION CALL "IC_MSG_TEXT" USING EXCEPTION-STATUS, EXCEPT-MSG DISPLAY ERROR-MESSAGE MOVE SPACES TO ICSMTPSERVER-ENTRY END-CALL GO TO MAIL-IT END-IF. IF ESC-CODE = 8 * F7 Help DISPLAY HELP-SCREEN-BLANKS; DISPLAY HELP-SCREEN; ACCEPT HELP-SCREEN; DISPLAY HELP-SCREEN-BLANKS; GO TO MAIL-IT. IF ESC-CODE = 9 * F8 Attachments DISPLAY HELP-SCREEN-BLANKS; DISPLAY MAIN-SCREEN-FILES ACCEPT MAIN-SCREEN-FILES MOVE 0 TO ATT-NUMBER. IF MIME-TYPE1 NOT = SPACES ADD 1 To ATT-NUMBER END-IF IF MIME-TYPE2 NOT = SPACES ADD 1 To ATT-NUMBER END-IF IF MIME-TYPE3 NOT = SPACES ADD 1 To ATT-NUMBER END-IF IF MIME-TYPE4 NOT = SPACES ADD 1 To ATT-NUMBER END-IF IF MIME-TYPE5 NOT = SPACES ADD 1 To ATT-NUMBER END-IF IF MIME-TYPE6 NOT = SPACES ADD 1 To ATT-NUMBER END-IF IF MIME-TYPE7 NOT = SPACES ADD 1 To ATT-NUMBER END-IF IF MIME-TYPE8 NOT = SPACES ADD 1 To ATT-NUMBER END-IF IF MIME-TYPE9 NOT = SPACES ADD 1 To ATT-NUMBER END-IF IF MIME-TYPE10 NOT = SPACES ADD 1 To ATT-NUMBER END-IF DISPLAY HELP-SCREEN-BLANKS; GO TO MAIL-IT. GO TO MAIL-IT. PROCESS-TO-MSG. * F5/sF5 Process sending a message * any setup MOVE SPACES TO CSV-ARG. IF TO-ENTRY = 2 OR TO-ENTRY = 3 * Using a file for To:s MOVE 1 TO FILE-LIST MOVE TO-LIST to SAVE-TO-LIST MOVE TO-LIST TO FILE-INPUT-NAME * Read file to get a list of to's MOVE 0 TO FILE-ERROR OPEN INPUT FILE-DSINPUT IF FILE-ERROR = 1 GO TO PROCESS-TO-MSG-END END-IF IF ESC-CODE = 14 * sF5 (Interactive mode) * Loop mode * Save base body MOVE TOTAL-BODY TO HOLD-TOTAL-BODY MOVE 1 TO LOOP-FOR-TO ELSE MOVE 0 TO LOOP-FOR-TO END-IF MOVE 0 TO EOF-FLAG MOVE 0 TO COUNT-LINES, COUNT-MESSAGES, COUNT-MESSAGES-IN-ERROR; PERFORM UNTIL EOF-FLAG NOT = 0 MOVE SPACES TO FILE-DSINPUT-DATA READ FILE-DSINPUT; AT END MOVE 1 TO EOF-FLAG; NOT AT END ADD 1 TO COUNT-LINES * DELIMIT holds the terminator(s), DSINPUT-SIZE holds # of bytes read MOVE FILE-DSINPUT-DATA TO TO-LIST * Handle a csv file IF TO-ENTRY = 3 MOVE 0 TO CSV-LOOP, CSV-HAD-ERROR MOVE 1 TO CSV-POSITION PERFORM UNTIL CSV-HAD-ERROR = 1 OR CSV-LOOP >= CSV-FILE-TO-COLUMN CALL "IC_DECODE_CSV" USING FILE-DSINPUT-DATA, CSV-POSITION, CSV-FILE-DELIMITER, CSV-VALUE ON EXCEPTION MOVE 1 TO CSV-HAD-ERROR END-CALL ADD 1 TO CSV-LOOP END-PERFORM IF CSV-HAD-ERROR = 0 MOVE CSV-VALUE TO TO-LIST END-IF * Now check for an arg IF CSV-FILE-ARG-COLUMN > 0 MOVE "Arg: " TO CSV-ARG-DISPLAY MOVE 0 TO CSV-LOOP, CSV-HAD-ERROR MOVE 1 TO CSV-POSITION PERFORM UNTIL CSV-HAD-ERROR = 1 OR CSV-LOOP >= CSV-FILE-ARG-COLUMN CALL "IC_DECODE_CSV" USING FILE-DSINPUT-DATA, CSV-POSITION, CSV-FILE-DELIMITER, CSV-VALUE ON EXCEPTION MOVE 1 TO CSV-HAD-ERROR END-CALL ADD 1 TO CSV-LOOP END-PERFORM IF CSV-HAD-ERROR = 0 MOVE CSV-VALUE TO CSV-ARG END-IF ELSE * no argument MOVE SPACES TO CSV-ARG-DISPLAY END-IF END-IF IF LOOP-FOR-TO = 1 * reset body MOVE HOLD-TOTAL-BODY TO TOTAL-BODY DISPLAY MAIN-SCREEN-LOOP ACCEPT MAIN-ENTRY-LOOP ACCEPT ESC-CODE FROM ESCAPE END-IF If ESC-CODE = 1 MOVE 1 TO EOF-FLAG ELSE IF ESC-CODE NOT = 3 * F2 is skip case, anything else send ADD 1 TO COUNT-MESSAGES PERFORM DO-SEND-SETUP PERFORM DO-SEND END-IF END-IF END-READ END-PERFORM CLOSE FILE-DSINPUT MOVE SAVE-TO-LIST TO TO-LIST DISPLAY GOOD-MESSAGES DISPLAY "Processed ", COUNT-LINES, " lines with ", COUNT-MESSAGES, " sent and ", COUNT-MESSAGES-IN-ERROR, " in error." UPON AUDIT-LOG ELSE IF TO-ENTRY = 4 * array list for TOs IF CNT > 0 IF ESC-CODE = 14 * Loop mode * Save base body MOVE TOTAL-BODY TO HOLD-TOTAL-BODY MOVE 2 TO LOOP-FOR-TO ELSE MOVE 0 TO LOOP-FOR-TO END-IF MOVE 1 TO CNT-I MOVE 0 to EOF-FLAG MOVE 0 TO COUNT-LINES, COUNT-MESSAGES, COUNT-MESSAGES-IN-ERROR; PERFORM UNTIL CNT-I > CNT OR EOF-FLAG = 1 MOVE STRING-VAL (CNT-I) TO TO-LIST IF LOOP-FOR-TO = 2 * reset body MOVE HOLD-TOTAL-BODY TO TOTAL-BODY DISPLAY MAIN-SCREEN-LOOP ACCEPT MAIN-ENTRY-LOOP ACCEPT ESC-CODE FROM ESCAPE END-IF IF ESC-CODE = 1 MOVE 1 TO EOF-FLAG ELSE IF ESC-CODE NOT = 3 * F2 is skip case, anything else send ADD 1 TO COUNT-MESSAGES PERFORM DO-SEND-SETUP PERFORM DO-SEND END-IF END-IF ADD 1 TO CNT-I, COUNT-LINES END-PERFORM MOVE SAVE-TO-LIST TO TO-LIST DISPLAY GOOD-MESSAGES DISPLAY "Processed ", COUNT-LINES, " entries with ", COUNT-MESSAGES, " sent and ", COUNT-MESSAGES-IN-ERROR, " in error." UPON AUDIT-LOG END-IF ELSE * simple message MOVE 0 TO FILE-LIST MOVE 0 TO COUNT-MESSAGES, COUNT-MESSAGES-IN-ERROR; PERFORM DO-SEND-SETUP PERFORM DO-SEND DISPLAY GOOD-MESSAGE END-IF. PROCESS-TO-MSG-END. EXIT. PROCESS-TOS-MSG. * F4 Get an array of TOs MOVE 0 TO CNT. DISPLAY BLANK-SCREEN. LOOP. DISPLAY TO-MAIN-SCREEN. ACCEPT TO-MAIN-SCREEN. ACCEPT ESC-KEY FROM ESCAPE. IF ESC-KEY = 1 * ESC GO TO PROCESS-TOS-MSG-END. IF ESC-KEY = 3 * F2 Clear MOVE SPACES TO STRING-ARRAY MOVE SPACES TO FULL-STRING DISPLAY BLANK-SCREEN GO TO LOOP. MOVE 1 TO I, LEN. MOVE 0 TO CNT. MOVE SPACES TO FULL-STRING. PERFORM LOOP2 120 TIMES. DISPLAY DATA-SCREEN. CALL "IC_TRIM" USING FULL-STRING, J, K. IF J = 0 OR K = 0 DISPLAY " empty string" ELSE * Protect reference modification having a zero DISPLAY FULL-STRING (J:K) END-IF. GO TO LOOP. PROCESS-TOS-MSG-END. EXIT. XXXX. MOVE ESC-KEY TO ESC-CODE. * F3 Use array for To:s * Now look for a file of to:'s IF CNT > 0 IF ESC-CODE = 10 * Loop mode * Save base body MOVE TOTAL-BODY TO HOLD-TOTAL-BODY MOVE 2 TO LOOP-FOR-TO ELSE MOVE 0 TO LOOP-FOR-TO END-IF MOVE 1 TO CNT-I MOVE 0 TO COUNT-LINES, COUNT-MESSAGES, COUNT-MESSAGES-IN-ERROR; PERFORM UNTIL CNT-I > CNT OR EOF-FLAG = 1 MOVE STRING-VAL (CNT-I) TO TO-LIST IF LOOP-FOR-TO = 2 * reset body MOVE HOLD-TOTAL-BODY TO TOTAL-BODY DISPLAY MAIN-SCREEN-LOOP ACCEPT MAIN-ENTRY-LOOP ACCEPT ESC-CODE FROM ESCAPE END-IF If ESC-CODE = 1 MOVE 1 TO EOF-FLAG ELSE IF ESC-CODE NOT = 3 * F2 is skip case, anything else send ADD 1 TO COUNT-MESSAGES PERFORM DO-SEND-SETUP PERFORM DO-SEND END-IF END-IF ADD 1 TO CNT-I END-PERFORM MOVE SAVE-TO-LIST TO TO-LIST DISPLAY GOOD-MESSAGES DISPLAY "Processed ", COUNT-LINES, " lines with ", COUNT-MESSAGES, " sent and ", COUNT-MESSAGES-IN-ERROR, " in error." UPON AUDIT-LOG ELSE MOVE 0 TO FILE-LIST MOVE 0 TO COUNT-MESSAGES, COUNT-MESSAGES-IN-ERROR; PERFORM DO-SEND-SETUP PERFORM DO-SEND DISPLAY GOOD-MESSAGE END-IF. LOOP2. IF STRING-VAL (I) = LOW-VALUES MOVE SPACES TO STRING-VAL (I). CALL "IC_TRIM" USING STRING-VAL(I), J, K. IF K > 0 * only do for non-blank entries ADD J TO K GIVING LAST-BYTE SUBTRACT 1 FROM LAST-BYTE IF FUNCTION ORD (STRING-VAL(I) (LAST-BYTE:1)) > 128 * remove any extranenous character from the end (sometimes an octal 240 MOVE SPACE TO STRING-VAL(I) (LAST-BYTE:1) SUBTRACT 1 FROM K END-IF * LEN is the next-byte in full-string to add characters MOVE STRING-VAL(I)(J:K) TO FULL-STRING (LEN:) ADD K TO LEN MOVE ";" TO FULL-STRING (LEN:1) ADD 1 TO LEN * CNT is the number of non-blank entries ADD 1 TO CNT END-IF. ADD 1 TO I. END-IT-EXIT. EXIT PROGRAM. END-IT-STOP. STOP RUN. PRE-CHECK. * Initial error checks * EXECPTION-STATUS will be non-zero if an error MOVE 0 TO EXCEPTION-STATUS. IF ICSMTPSERVER-ENTRY = SPACES MOVE 2084 TO EXCEPTION-STATUS ELSE IF FROM-ADDR = SPACES MOVE 2082 TO EXCEPTION-STATUS ELSE IF TO-LIST = SPACES MOVE 2081 TO EXCEPTION-STATUS ELSE IF SUBJECT = SPACES MOVE 2083 TO EXCEPTION-STATUS. IF EXCEPTION-STATUS NOT = 0 CALL "IC_MSG_TEXT" USING EXCEPTION-STATUS, EXCEPT-MSG DISPLAY ERROR-MESSAGE. DO-SEND-SETUP. MOVE SPACES TO BODY-TEXT. MOVE 1 TO BODY-TEXT-START; MOVE 0 TO BODY-TEXT-LEN. CALL "IC_TRIM" USING TOTAL-BODY, START-LOC, BODY-LEN. ADD START-LOC TO BODY-LEN. ADD 79 TO BODY-LEN. DIVIDE 80 INTO BODY-LEN. MOVE 1 TO I. PERFORM BODY-LEN TIMES CALL "IC_TRIM" USING BODY-PART (I), START-LOC, BODY-LEN IF BODY-LEN > 0 IF BODY-LEN NOT = 1 IF BODY-PART (I) (START-LOC + BODY-LEN - 2:2) = "\\" SUBTRACT 2 FROM BODY-LEN END-IF END-IF MOVE BODY-PART (I) (1:BODY-LEN) TO BODY-TEXT (BODY-TEXT-START:) ADD BODY-LEN TO BODY-TEXT-START END-IF MOVE X"0d0a" TO BODY-TEXT (BODY-TEXT-START:2) ADD 2 TO BODY-TEXT-START, BODY-TEXT-LEN ADD 1 TO I END-PERFORM. INSPECT BODY-TEXT REPLACING ALL "\\" BY X"0d0a". * Add extra lines requested. MOVE BODY-TEXT TO WORK-BODY-TEXT If CSV-FILE-ARG-COLUMN > 0 * look for $arg MOVE 0 TO FIND-ARG INSPECT BODY-TEXT TALLYING FIND-ARG FOR CHARACTERS BEFORE INITIAL "$arg" ADD 1 TO FIND-ARG IF FIND-ARG < BODY-TEXT-SIZE * found $arg CALL "IC_TRIM" USING CSV-ARG, J, K IF K > 0 * have an argument If K < 4 MOVE 4 TO K ELSE IF K > 4 * must make room, and must use temporay body-text since you have overlapping operand (undefined behavior) MOVE WORK-BODY-TEXT (FIND-ARG + 4:) TO BODY-TEXT (FIND-ARG + K:) END-IF END-IF MOVE CSV-ARG (1:K) TO BODY-TEXT (FIND-ARG:K) ELSE * no arg, just clear the token MOVE BODY-TEXT (FIND-ARG + 4:) TO BODY-TEXT (FIND-ARG:) END-IF END-IF END-IF. DO-SEND. * Preprocess TO-LIST, CC-LIST, BCC-LIST converting ; to , as most emailers * will not handle a semi-colon separator INSPECT TO-LIST REPLACING ALL ";" BY ",". INSPECT CC-LIST REPLACING ALL ";" BY ",". INSPECT BCC-LIST REPLACING ALL ";" BY ",". * Could make a check to ensure that each email address has an at-sign * or that TO-LIST is not empty ** Use the following if running runtime before 4.42 IF RUNTIME-MAJOR < 4 OR (RUNTIME-MAJOR = 4 AND RUNTIME-MINOR < 42) CALL "IC_SEND_MAIL" USING TO-LIST, FROM-ADDR, CC-LIST, BCC-LIST, SUBJECT, BODY-TEXT, MIME-TYPE1, ATT-FILE1, USER-PASS-ENTRY ON EXCEPTION ACCEPT EXCEPTION-STATUS FROM EXCEPTION CALL "IC_MSG_TEXT" USING EXCEPTION-STATUS, EXCEPT-MSG IF FILE-LIST = 0 DISPLAY ERROR-MESSAGE DISPLAY " SendMail Error: using To: ", TO-LIST UPON AUDIT-LOG ELSE DISPLAY " SendMail Error: on line ", COUNT-MESSAGES, " using To: ", TO-LIST UPON AUDIT-LOG END-IF ADD 1 TO COUNT-MESSAGES-IN-ERROR MOVE 1 TO SAW-SEND-ERROR NOT ON EXCEPTION ACCEPT EXCEPTION-STATUS FROM EXCEPTION CALL "IC_MSG_TEXT" USING EXCEPTION-STATUS, EXCEPT-MSG IF FILE-LIST = 0 DISPLAY GOOD-MESSAGE ELSE DISPLAY " SendMail to: ", TO-LIST UPON AUDIT-LOG END-IF MOVE 0 TO SAW-SEND-ERROR END-CALL ELSE ** Use this code if running 4.42 or above CALL "IC_SEND_MAIL" USING TO-LIST, FROM-ADDR, CC-LIST, BCC-LIST, SUBJECT, BODY-TEXT, MIME-TYPE1, ATT-FILE1, USER-PASS-ENTRY, MIME-TYPE2, ATT-FILE2, MIME-TYPE3, ATT-FILE3, MIME-TYPE4, ATT-FILE4, MIME-TYPE5, ATT-FILE5, MIME-TYPE6, ATT-FILE6, MIME-TYPE7, ATT-FILE7, MIME-TYPE8, ATT-FILE8, MIME-TYPE9, ATT-FILE9, MIME-TYPE10, ATT-FILE10 * 27 args, can add 2 or 4 more, limit is 31 ** ON EXCEPTION ACCEPT EXCEPTION-STATUS FROM EXCEPTION CALL "IC_MSG_TEXT" USING EXCEPTION-STATUS, EXCEPT-MSG IF FILE-LIST = 0 DISPLAY ERROR-MESSAGE DISPLAY " SendMail Error: using To: ", TO-LIST UPON AUDIT-LOG ELSE DISPLAY " SendMail Error: on line ", COUNT-MESSAGES, " using To: ", TO-LIST UPON AUDIT-LOG END-IF ADD 1 TO COUNT-MESSAGES-IN-ERROR MOVE 1 TO SAW-SEND-ERROR NOT ON EXCEPTION ACCEPT EXCEPTION-STATUS FROM EXCEPTION CALL "IC_MSG_TEXT" USING EXCEPTION-STATUS, EXCEPT-MSG IF FILE-LIST = 0 DISPLAY GOOD-MESSAGE ELSE DISPLAY " SendMail to: ", TO-LIST UPON AUDIT-LOG END-IF MOVE 0 TO SAW-SEND-ERROR END-CALL END-IF. * Progress bar IF FILE-LIST NOT = 0 IF FUNCTION MOD (COUNT-MESSAGES, 80) = 1 DISPLAY POSITION-SCREEN END-IF IF FUNCTION MOD (COUNT-MESSAGES, 5) = 0 DISPLAY "+" WITH NO ADVANCING ELSE DISPLAY "." WITH NO ADVANCING END-IF END-IF.