  Using Callable MAIL API? (BASIC) 
 The Question is:
 
Do you have any examples of the use of the Mail Utility in a basic program.
The examples in the Utility Routines Manual are all in C.
 
Thanks
 
 
 The Answer is:
 
COPYRIGHT (c) 1988, 1993 by Digital Equipment Corporation.
ALL RIGHTS RESERVED. No distribution except as provided under contract.
 
Copyright (c) Digital Equipment Corporation 1990, 1991. All rights reserved
LAYERED PRODUCT:  VAX BASIC V3.4          OP/SYS: VMS V5.4
 
SOURCE:     Digital Customer Support Center
 
 
OVERVIEW:
 
This program shows how the callable MAIL routines can be used to send
a message to a user-specified address.  Although any text file can be
used, this program explicitly uses a file called MAIL_BODY.TXT.
MAIL_BODY.TXT can be created with an editor.  Slight modifications to
this program can make it possible to send any text file.
 
 
*** CAUTION ***
 
This sample program has been tested using VAX BASIC Version 3.4 on VMS
Version 5.4.  However, we cannot guarantee its effectiveness because
of the possibility of error in transmitting or implementing it.  It is
meant to be used as a template for writing your own program and it may
require modification for use on your system.
 
 
PROGRAM NOTES:
 
Please note that this program does not trap for an invalid address
name.  The user is expected to supply valid addresses at the TO: and
CC: prompts.
 
In the DCL interface to VMS mail it is possible for the user to
specify multiple addresses at the TO: and CC: prompts by separating
the addresses with commas.  Callable mail does not accept multiple
addresses in that format.  Callable mail accepts only ONE address
at a time.  If you wish for the user to enter addresses in the DCL
format, it is up to the program to parse out each address and feed
it to MAIL$SEND_ADD_ADDRESS individually.
 
Also, the Mail utility is smart enough to detect when the same
name is specified on the TO: and CC: lines.  If this is the case
only one message will be sent to that address.
 
Finally, please realize that, just because you specify a certain
TO: or CC: value in the call to MAIL$SEND_ADD_ATTRIBUTE, the
message will NOT necessarily be sent to those addresses.  This is
because MAIL$SEND_ADD_ATTRIBUTE only formats the header as it will
show up in the message text.  It has nothing to do with where the
message will go.  MAIL$SEND_ADD_ADDRESS dictates where the message
will go.
 
 
PROGRAM:
 
OPTION TYPE = EXPLICIT
 
EXTERNAL LONG FUNCTION mail$send_begin,         &amp;
                       mail$send_add_attribute, &amp;
                       mail$send_add_address,   &amp;
                       mail$send_add_bodypart,  &amp;
                       mail$send_message,       &amp;
                       mail$send_end
 
 
! Include the MAILDEF constants.
 
%INCLUDE "$maildef" %FROM %LIBRARY "sys$library:basic$starlet"
 
 
! Set up the item list.
 
RECORD item_list
    GROUP item (1% TO 5%)
        VARIANT
        CASE
            WORD buflen
            WORD itmcod
            LONG bufadr
            LONG retlen
        CASE
            LONG terminator
        END VARIANT
    END GROUP
END RECORD
 
DECLARE LONG      stat,      &amp;
                  context,   &amp;
        WORD      user_type, &amp;
        item_list mailitm1,  &amp;
        item_list mailitm2
 
MAP (title_buffer) STRING to_name   = 255%, from_name    = 255%, &amp;
                          cc_name   = 255%, subject_line = 255%, &amp;
                          text_line = 255%, text_file    = 255%
 
 
! Get the information for TO:, FROM:, CC:, and SUBJECT: lines.
! EDIT$ is used to capitalize some of the fields.
 
INPUT "What is the address the message should go to (TO:)"; to_name
to_name = EDIT$(to_name, 32%)
 
! Note:
! You must have SYSPRV privilege to change the From line on the message
 
INPUT "What should the 'FROM:' line say"; from_name
from_name = EDIT$(from_name, 32%)
 
INPUT "Carbon copy to (CC:)"; cc_name
cc_name = EDIT$(cc_name, 32%)
 
INPUT "What should the 'SUBJECT:' line contain"; subject_line
 
begin_send:
    !
    ! Initialize the SEND context.
    !
    stat = mail$send_begin (context, 0%, 0%)
    CALL lib$stop(stat BY VALUE) IF (stat AND 1%) = 0%
 
send_attributes:
    !
    ! Prepare the item list to supply TO:, FROM:, CC:, and SUBJECT:
    ! information and add all of these attributes in one call to
    ! MAIL$SEND_ADD_ATTRIBUTE.  Please realize that, just because
    ! we specify 'TO:' and 'CC:' addresses in this call to
    ! MAIL$SEND_ADD_ATTRIBUTE, it doesn't mean the message will
    ! actually be sent there.  MAIL$SEND_ADD_ATTRIBUTE merely
    ! formats the mail header.  **It does not specify the addresses
    ! the message will actually go to**.  Addresses are specified
    ! in the call to MAIL$SEND_ADD_ADDRESS.
    !
    mailitm2::item(1%)::buflen     = LEN(TRM$(to_name))
    mailitm2::item(1%)::itmcod     = mail$_send_to_line    ! TO:
    mailitm2::item(1%)::bufadr     = LOC(to_name)
 
    mailitm2::item(2%)::buflen     = LEN(TRM$(from_name))
    mailitm2::item(2%)::itmcod     = mail$_send_from_line  ! FROM:
    mailitm2::item(2%)::bufadr     = LOC(from_name)
 
    mailitm2::item(3%)::buflen     = LEN(TRM$(cc_name))
    mailitm2::item(3%)::itmcod     = mail$_send_cc_line    ! CC:
    mailitm2::item(3%)::bufadr     = LOC(cc_name)
 
    mailitm2::item(4%)::buflen     = LEN(TRM$(subject_line))
    mailitm2::item(4%)::itmcod     = mail$_send_subject    ! SUBJECT:
    mailitm2::item(4%)::bufadr     = LOC(subject_line)
 
    mailitm2::item(5%)::terminator = 0%
 
    stat = mail$send_add_attribute (context, mailitm2, 0%)
    CALL lib$stop(stat BY VALUE) IF (stat AND 1%) = 0%
 
display_message_body:
    PRINT
    PRINT
    PRINT "This program uses a data file called MAIL_BODY.TXT"
    PRINT "for the body of the mail message.  You can create a test"
    PRINT "file with this name using an editor.  The text of the file"
    PRINT "can also be entered interactively with a slight modification"
    PRINT "to this program."
    PRINT
 
    WHEN ERROR IN
        !
        ! Print out the body of the file for the user to see.
        ! After the end of file is reached, use MAIL$SEND_ADD_BODYPART
        ! to insert the text file as the body of the mail message.
        !
        OPEN "MAIL_BODY.TXT" FOR INPUT AS FILE #1
        PRINT "Here is the text of the file you are mailing:"
        PRINT
        WHILE 1%
            INPUT LINE #1, text_line
            PRINT TRM$(text_line)
        NEXT
    USE
        SELECT ERR
            CASE = 5          ! Trap for non-existent file
                PRINT "*** The data file with the mail message ***"
                PRINT "***         cannot be found.            ***"
                CONTINUE clean_context
            CASE = 11         ! Trap for end of file and send message.
                CLOSE #1
                CONTINUE add_bodypart
            CASE ELSE
                PRINT "Unexpected error :"; ERR
                CONTINUE clean_context
        END SELECT
    END WHEN
 
add_bodypart:
    !
    ! Prepare the item list for the message body.  Since we have an
    ! existing file with the message body, we can use MAIL$_SEND_FILENAME
    ! as the item code and make one call to MAIL$SEND_ADD_BODYPART.  If
    ! we were sending individual lines of the body, we would use
    ! MAIL$_SEND_RECORD as the item code and make repeated calls to
    ! MAIL$SEND_ADD_BODYPART.
    !
    text_file = "MAIL_BODY.TXT"
    mailitm1::item(1%)::buflen = LEN(TRM$(text_file))
    mailitm1::item(1%)::itmcod = mail$_send_filename
    mailitm1::item(1%)::bufadr = LOC(text_file)
 
    stat = mail$send_add_bodypart (context, mailitm1, 0%)
    CALL lib$stop(stat BY VALUE) IF (stat AND 1%) = 0%
 
prepare_address:
    !
    ! Specify the addresses given in the 'TO:' and 'CC:' lines.
    ! Remember, MAIL$SEND_ADD_ATTRIBUTE only formats the mail header
    ! lines.  MAIL$SEND_ADD_ADDRESS is the routine that actually
    ! dictates where the message will be sent.  Separate calls to
    ! MAIL$SEND_ADD_ADDRESS are used here to specify the TO: and CC:
    ! addresses.
    !
    ! Also note that only ONE address at a time can be specified.
    ! Merely specifying multiple addresses in one line separated
    ! by commas is not the proper approach.  If the user entered
    ! multiple addresses separated by commas on the TO: or CC:
    ! lines the program must parse each address singly and pass
    ! each individual address to MAIL$SEND_ADD_ADDRESS.  This
    ! program does not do so -- it expects the user to enter
    ! a single address at the TO: and CC: prompts.
    !
    ! Finally, it should be noted that Mail is smart enough to figure
    ! out if you specify the same address on the TO: and CC: lines
    ! and will only send one message to that address.
    !
    user_type = mail$_to
 
    mailitm1::item(1%)::itmcod     = mail$_send_username
    mailitm1::item(1%)::buflen     = LEN(TRM$(to_name))
    mailitm1::item(1%)::bufadr     = LOC(to_name)
 
    mailitm1::item(2%)::itmcod     = mail$_send_username_type
    mailitm1::item(2%)::buflen     = 2%
    mailitm1::item(2%)::bufadr     = LOC(user_type)
 
    mailitm1::item(3%)::terminator = 0%
 
    stat = mail$send_add_address (context, mailitm1, 0%)
    CALL lib$stop(stat BY VALUE) IF (stat AND 1%) = 0%
 
    user_type = mail$_cc
 
    mailitm1::item(1%)::itmcod     = mail$_send_username
    mailitm1::item(1%)::buflen     = LEN(TRM$(cc_name))
    mailitm1::item(1%)::bufadr     = LOC(cc_name)
 
    mailitm1::item(2%)::itmcod     = mail$_send_username_type
    mailitm1::item(2%)::buflen     = 2%
    mailitm1::item(2%)::bufadr     = LOC(user_type)
 
    mailitm1::item(3%)::terminator = 0%
 
    stat = mail$send_add_address (context, mailitm1, 0%)
    CALL lib$stop(stat BY VALUE) IF (stat AND 1%) = 0%
 
send_message:
    !
    ! Send the message.
    !
    stat = mail$send_message (context, 0%, 0%)
    CALL lib$stop(stat BY VALUE) IF (stat AND 1%) = 0%
 
    PRINT
    PRINT
    PRINT "...Message sent..."
    PRINT
    PRINT
 
clean_context:
    !
    ! Clean up the context.
    !
    stat = mail$send_end (context, 0%, 0%)
    CALL lib$stop(stat BY VALUE) IF (stat AND 1%) = 0%
    END
 
