From: CSBVAX::MRGATE!@KL.SRI.Com,@wiscvm.wisc.edu:GA.JPH@ISUMVS@SMTP 2-SEP-1987 14:16 To: EVERHART Subj: VMS MAIL Foreign Protocol Guide Received: from wiscvm.wisc.edu by KL.SRI.COM with TCP; Wed 2 Sep 87 09:04:50-PDT Received: from ISUMVS.BITNET by wiscvm.wisc.edu ; Wed, 02 Sep 87 11:04:49 CDT Date: Wed, 2 Sep 87 11:04:39 CDT To: From: "John Hascall" Subject: VMS MAIL Foreign Protocol Guide Fellow netlanders: There as been considerable interest in the VMS MAIL foreign protocol interface recently. The following is a quick guide to this interface, based on what I have learned over the past few months. This information is mostly complete and correct as far as I know. If you cut on the dotted lines and print on a printer with 60 or 66 lines/page the page breaks will fall nicely. ------------------------------ cut here ---------------------------------------- VMS MAIL Foreign Protocol John P. Hascall Iowa State University Computation Center When VMS mail is given a "foreign protocol" address (either at the To: prompt or on the command line) of the form: protocol%"address" or mail is invoked with the command: MAIL/PROTOCOL=protocol_MAILSHR file-name.type;ver it uses LIB$FIND_IMAGE_SYMBOL to merge SYS$SHARE:protocol_MAILSHR.EXE into its address space. Mail then enters into a "conversation" with this image. The requirements the image must meet and the conversation are detailed below. IMAGE REQUIREMENTS: 1) Entry Point: MAIL$PROTOCOL 2) Installed: /SHARE/OPEN/HEADER/PRIV=(WORLD,NETMBX,OPER,SYSPRV) (the same privileges as MAIL) 3) Universal Symbols: MAIL$C_PROT_MAJOR == 1, MAIL$C_PROT_MINOR == 1 (see the linker manual for more on universal symbols) 4) Code: The usual rules for producing a sharable image. (see the linker manual) CONVERSATION Once VMS mail has determined that the suitable foreign protocol image exists, it calls the routine MAIL$PROTOCOL several times with varying arguments. There are two different conversations depending on how MAIL was invoked. If an address like protocol%"address" was specified then mail enters an "out-going" conversation. If MAIL was invoked with /PROTOCOL=protocol_MAILSHR file-name.type.ver then MAIL enters an "in-coming" conversation to deliver the message in the file. For either type of conversation MAIL calls MAIL$PROTOCOL several times. Each time MAIL$PROTOCOL is called the arguments are: 0(AP) - Number of arguments 4(AP) - Address of a Context variable (argument 1) 8(AP) - Function code (argument 2) . . arguments 3, 4, 5... depend on the function code . For an out-going conversation MAIL$PROTOCOL is called with the following function codes in this order (unless an error occurs or the user aborts the message (i.e., presses C), in which case LNK_C_OUT_DEACCESS is called immediately): LNK_C_OUT_CONNECT = 0 ; Outbound connect LNK_C_OUT_SENDER = 1 ; Sender Text (the From: line) LNK_C_OUT_CKUSER = 2 ; Recipient (this code will be repeated once for each recipient and then once more with a NULL recipient. LNK_C_OUT_TO = 3 ; Recipients Text (the To: line) LNK_C_OUT_SUBJ = 4 ; Subject Text (the Subject: line) LNK_C_OUT_FILE = 5 ; The body of the message. LNK_C_OUT_CKSEND = 6 ; Send the message. LNK_C_OUT_DEACCESS = 7 ; End conversation and for an incoming message: LNK_C_IN_CONNECT = 8 ; Inbound connect LNK_C_IN_SENDER = 9 ; return the sender text (From: line) LNK_C_IN_CKUSER = 10 ; return the next recipient (username) ; or a NULL byte to indicate no more ; (is called repeatedly) LNK_C_IN_TO = 11 ; return the recipient text (To: line) LNK_C_IN_SUBJ = 12 ; return the subject text (Subj: line) LNK_C_IN_FILE = 13 ; input the text of the file LNK_C_OUT_DEACCESS = 7 ; end conversation and some utility function codes (which may be called at any time they are necessary): LNK_C_IO_READ = 14 ; read a line (this function is never invoked as I can tell) LNK_C_IO_WRITE = 15 ; write a line (used to send us either an error code or error message) The first two arguments to MAIL$PROTOCOL are always the pointer to the context variable and the function code. The remaining arguments depend on the function code. They are as follows: OUT_CONNECT: 12(AP) ; address of a descriptor of a string which is the protocol name 16(AP) ; address of a descriptor of a string which is our node name 20(AP) ; MAIL$_LOGLINK [logical link] (immediate) 24(AP) ; RAT of mail file (immediate) 28(AP) ; RFM of mail file (immediate) 32(AP) ; MAIL$GL_FLAGS [global flags] (immediate) 36(AP) ; address of a descriptor of a string which is the attached file (whatever that means) OUT_SENDER: 12(AP) ; address of descriptor of senders node name 16(AP) ; address of descriptor of senders username OUT_CKUSER: 12(AP) ; address of descriptor of recipients node name 16(AP) ; address of descriptor of recipients username 20(AP) ; address of a routine to call if a recipient is bad OUT_TO: 12(AP) ; address of descriptor of local node name 16(AP) ; address of descriptor of To: line text OUT_SUBJ: 12(AP) ; address of descriptor of local node name 16(AP) ; address of descritpor of Subject: line text OUT_FILE: 12(AP) ; address of descriptor of local node name 16(AP) ; address of RAB of file to be mail, file is opened for BLOCK I/O and connected already 20(AP) ; address of a routine to call in case of an I/O error OUT_CKSEND: OUT_DEACCESS: IN_CONNECT: 12(AP) ; addr of descr of input translate table 16(AP) ; RAT (immediate) 20(AP) ; RFM (immediate) 24(AP) ; MAIL$GL_SYSFLAGS 28(AP) ; address of descriptor of protocol name 32(AP) ; server flags (???) IN_SENDER: 12(AP) ; addr of descr to return From: text to IN_CKUSER: 12(AP) ; addr of descr to return recip username IN_TO: 12(AP) ; addr of descr to return To: text to IN_SUBJ: 12(AP) ; addr of descr to return Subj: text to IN_FILE: 12(AP) ; ??? Unknown argument 16(AP) ; address of RAB 20(AP) ; addr to call in case of an I/O error IO_READ: 12(AP) ; addr of descr to return something IO_WRITE: 12(AP) ; addr of descr of an error code or an error message MAIL has sent us NOTES Since this is a sharable image, it may be being executed by more than one process at a time. When a connect function is received, use LIB$GET_VM to allocate enough memory for all the information you need for a mail message and store the address of this block in the provided context variable. On successive calls the context variable will point to the block for that message. You can delete this virtual memory upon receiving the OUT_DEACCESS function. I have the framework of an interface to this protocol which is available. This program is based on one written by Gerard K. Newman of the San Diego Supercomputer Center to whom I am grateful for making my investigation of this topic much shorter and easier by giving me a copy of his interface (wish I'd had it when I started, as I did a great deal of "re-inventing the wheel"). I hope to spare the the rest of you some of this re-inventing. If anyone has any additional information or corrections on this subject, I would be like to keep this information as complete and correct as possible. -------------------------- end of text ----------------------------------------- John Hascall (GA.JPH@ISUMVS.BITNET) or (GAJPH@ISUMVS.BITNET if the "." is a problem) Iowa State University Computation Center 104 Computer Science Ames, Iowa 50010 (515) 294-9889