.enable bar .style headers 6,0,0 .ap.p 0 .title Queued Mail System -- Internals .subtitle Introduction .date .lm 0.rm 72 .c;Queued Mail System (QMS) .b2.c;Version 1.0 .b2.c;Internals .flag substitute .b2.c;$$DATE .noflag substitute .b2.c;Robert C_. McQueen .page .subtitle Table of Contents .require "qms_internals.rnt" .page .hl1 Introduction The mail system on the VAX/VMS systems is primitive. The user agent (MAIL program) does not allow you many of the options that are found in the MM-20 and MS-10/20 mail user agents and the transfer agent doesn't allow multiple network support very easily. This project will be the first step in producing a new electronic mail environment for the VAX/VMS systems. The initial step will be to provide a mail transport system that can can be built on to provide future functionality. .hl1 Revision History The following is the revision history for the mail system overview document. All changes from the previous version are noted by change bars. .ls "o" .le;Preliminary version. .els .hl1 Overview The programs that are in the Queued Mail System are part of three different basic categories. These are: symbionts, server processes and utilities. All of the programs contain many common modules. The modules include: .ls "o" .le;General operator/log file message processing. .le;General file I/O routines. .le;Common routines to read and create queue requests. .le;General routine to create a mail message. .els The symbionts are used to either route the mail messages or to deliver them, while the server processes create mail messages from network connections or the local users, and the utilities help maintain the mail system. All of the programs will translate a logical name to determine the type of interaction with the operators and log file. The translation of the logical names provide a bit mask for internal use within the Queued Mail System. The bitmask determines if informational, warning or error messages should be sent to the operator and/or log file. All checking of the flags is done within a single module called QMS__INFORMATION. .X ^^QMS__INFORMATION The flags determine if the information processing routines should call the log file routines in QMS__LOG .x ^^QMS__LOG and/or the send to operator routines found in QMS__OPERATOR. .X ^^QMS__OPERATOR .hl1 Symbionts All of the symbionts use a common routine to talk to the job controller. .x ^^JOBCTL .x Job controller This module is QMS__SYMBIONT.C which uses the system SMB$ routines to process .x ^^QMS__SYMBIONT.C .X Modules>^^QMS__SYMBIONT.C queue requests from the job controller. The symbionts are all single threaded and are not set up to be multi-threaded. The symbionts are synchronous and do not handle messages that may arrive while they are attempting to process mail. .hl2 Router process The router process will accept mail and determine how to deliver it. The mail .x ^^QMS__ROUTER.C .x Modules>^^QMS__ROUTER.C that is processed by the router will come from network server processes and local users/processes. The router will then look at the address and determine where the address is valid and queue it for the specific delivery symbiont. .HL3 Basic logic flow The basic flow of control in the router symbiont is: .ls .le;Initialize the various modules in the symbiont uses. .le;Read and process the initialization file. .le;Initialize the network interface. .le;Call the symbiont level routines to wait for something to do. .le;Shutdown the router when the symbiont level routines return. This includes shutting down the network interface and the other various modules that require a shutdown. .els When a request is provided by the job controller to the symbiont .x Job controller .x ^^JOBCTL The request is processed in the following manner: .ls .le;Request attribute file is read in to the various internal data structures. .le;It is determine if the request has expired (timed out). If it has error mail is created and sent back along the return path and the request is finished processing. .le;The routine to route the mail message to the various recipients is called. The basic flow of the routing routine is: .ls .le;Scan each recipient on the recipient list. .le;Determine if the recipient is a network address, local address, distribution list or an unknown/illegal address. .le;There is then a switch statement (case statement) to dispatch according to the type of address that is to be processed. For local addresses, the recipient is placed on the local address queue. Distribution lists are expanded with the expansion placed on the end of the recipient queue, so that they can be properly routed. A network address is check to see if the network node specified is local and if it is the node name is removed from the recipient address and the address will be scanned again. If the network address is not local the proper network information block is found for the address and the recipient is queued .x ^Network ^Information ^Block (nib) on the network information block. .els .le;The routine to submit the routed mail message is called. This routine will scan all of the network information blocks and create a queue request for a .x ^Network ^Information ^Block (nib) network if the recipient list in the network information block is not empty. The message file will be modified to "fix" the return address to have the proper network node name on it. For example, the local mail is queued with the from address as "FROM: CSTEWART", when the message is cloned the address will be modified to be "FROM: CSTEWART@SCTLND" where SCTLND is the node name for the local node on the specific network that the message is being sent out on. Local messages are queued without the address modification, but with the first line added to the message to be the RFC822 return path (Return-path: address). .x ^^RFC822 .le;The request is completed and control is returned to the symbiont interface. .els .hl3 Router Initialization file The router initialization file is read by the QMS_ROUTER symbiont as one part of its startup up procedure. The initialization file is pointed to by the system logical name QMS$INITIALIZATION_FILE. .x Logical ^Names>^^QMS$INITIALIZATION_FILE. The router will build various internal data structures based on the information that is found in this file. The file is read only once, so if it changes the symbiont must be restarted. The internal data structures that are built from this file are the network information blocks, normally referenced in the code as "nib". The initial .x ^Network ^Information ^Block (nib) data is stored into this from the NETWORK lines found in the initialization file. The format of the line is: .b .br;NETWORK : DECNET : QMS$ROUTE__DECNET : QMS$DECNET__MAIL : RFC822 .x ^^DEC\\net .x ^^QMS$ROUTE__DECNET .x Logical names>^^QMS$ROUTE__DECNET .x ^^QMS__ROUTER>^^DEC\\net support .x Queue>^^QMS$DECNET__MAIL .br;NETWORK : INTERNET : QMS$ROUTE__INTERNET : QMS$INTERNET__MAIL : RFC822 .x ^^INTERNET .x ^^QMS$ROUTE__INTERNET .x Logical names>^^QMS$ROUTE__INTERNET .x ^^QMS__ROUTER>^^INTERNET support .x Queue>^^QMS$INTERNET__MAIL The first item is the "NETWORK" keyword, the second item is the type of network that we are dealing with (eg. DECnet, or Internet). The next item is the name of the sharable segment that is mapped in to handle the support of routing to that network. This is normally a logical name that points to the real file to do the network processing. The fourth field is the name of the queue to place all entries for this network. In the example above all validated DECNet requests would be placed into the QMS$DECNET__MAIL queue. The last field specifies the message format. In the cases show the format would be conforming to RFC-822. .x ^^RFC822 In the released version the QMS$ROUTE__DECNET, QMS$ROUTE__INTERNET and QMS$ROUTE__BITNET are logical names that define the sharable segments that are to .x Logical names>^^QMS$ROUTE_DECNET .x Logical names>^^QMS$ROUTE_INTERNET .x Logical names>^^QMS$ROUTE_BITNET be used to route the mail. For example the QMS$ROUTE__INTERNET will point to the QMS$SYSTEM:RTR__NETWORK__INTERNET.EXE segment. .X ^^RTR__NETWORK__INTERNET Assuming that you wanted to add a new entry to the initialization file to support a new network protocol you would have to do the following: .ls .le;Build a sharable segment to support the network routing. .le;Define a queue to store the requests for that network. .le;Build a server symbiont to support the new output queue. .els If you were added support for BITNET, and you were defining the queue to be QMS$BITNET__MAIL with the routing sharable segment to be QMS$ROUTER__BITNET the new line the in the initialization file would be: .b .br;NETWORK : BITNET : QMS$ROUTE__BITNET : QMS$BITNET__MAIL : RFC822 .x ^^BITNET .x ^^QMS$ROUTE__BITNET .x ^^QMS__ROUTER>^^BITNET support .x Queue>^^QMS$BITNET__MAIL .HL3 Network Information blocks (nib) .x ^Network ^Information ^Block (nib) The network information block is used to define a network that can have mail routed to it. The nib block is created by the initialization file processing routines and is stored in a linked list using the standard list processing of QMS__LISTS. .X ^^QMS__LISTS.C The network information blocks contain the following information: .ls "o" .le;This network is open (up). .le;Network channel for talking to network ACP (if there is one). .le;Name of the network. .le;Number of different names for the local node in this network. .le;A vector of local node names. This is to provide support for cluster alias and local delivery of cluster mail. .le;A recipient list which is used by the router when determining how to deliver a request. .le;The message format legal for delivery. This would be for future use when it might be advisable to support a mail message format other that RFC822 and there is need for a mail message format translation (eg. RFC822 to X.400). .LE;Name of the queue to submit the routed message to. .le;Name of the sharable router image (eg. QMS$ROUTE__DECNET). .X QMS$ROUTE__DECNET .LE;Entry point address for the sharable router image. .els .hl3 Network Router segments The network router segments are sharable segments that have a single entry .x Network Router>Entry point point. QMS__ROUTER will do a LIB$FIND__IMAGE__SYMBOL to cause the sharable .x ^^QMS__ROUTER .x ^^LIB$FIND__IMAGE__SYMBOL segment to be added to the address space. The symbols that are looked for in the image are: .LS "o" .lE;RTR$NETWORK - Main entry point into the network router segment. .LE;NETWORK$C__PROT__MAJOR - Major version number of the network router segment protocol/interface. The current value of this symbol should be one (1). .le;NETWORK$C__PROT__MINOR - Minor version number of the network router segment protocol/interface. The current value of this symbol should be zero (0). .els The entry point is called with a variable number of arguments depending on the function that is to be executed. The currently defined functions are: .ls "o" .le;NET__INITIALIZE - Initialize the network router segment. The function value is zero. .le;NET__SHUTDOWN - Shutdown the network router segment. The function value is one. .le;NET__VALID - Determine if this is a valid network address. The value for this function is two (2). .le;NET__LOCAL - Determine if a network node is local. The value for this function is three (3). .els The first argument of any call is always the function that is to be executed and the second argument is always the address of the network information block associated with this segment. All arguments after the first two are function specific. It is suggest that one of the currently running network router segments be looked at to determine the exact arguments that are required for the other functions. .hl2 Local delivery symbiont The local delivery symbiont, QMS__LOCAL__DELIVERY, was written to allow more .X QMS__LOCAL__DELIVERY than one local delivery mechanism. Currently, only delivery via VAXmail is .x ^^VAX\\mail implemented in the symbionts. The symbiont will do local initialization, then call the general symbiont module, QMS__SYMBIONT to talk to the job controller. .x Job controller .X ^^QMS__SYMBIONT When a request is to be processed, the local delivery symbiont will read in the extended request attributes, scan each recipient in the recipient list and determine the proper method of delivering the mail to the specified recipient. The hooks are in place in this symbiont to implement alternative delivery mechanisms. There is a routine that is called for each recipient to determine which mechanism to use and then there are calls to the various specified delivery routines. To add a new delivery mechanism all that would be required is a method of separating the new method from VAXmail deliveries and the specific delivery routine. .hl3 VAXmail Delivery .x ^^VAX\\mail The method that is currently employed to deliver mail on the VAX is to create a subprocess with a MAIL/PROTOCOL command to deliver the file to the user. This is done for each different recipient that is on the recipient list. Multiple recipients were not done at one time, because if the third recipient failed out of five that might have been specified, the fourth and fifth recipients on the list would not receive the mail. The /PROTOCOL qualifier for mail specifies that a foreign mail interface is to be used in the delivery of the mail. .x ^^VAX\\mail>^Foreign mail interface The qualifier takes as an argument a logical name which is translated to be that of a sharable segment. The sharable segment is mapped via the LIB$FIND__IMAGE__SYMBOL library routine. .x ^^LIB$FIND__IMAGE__SYMBOL VAXmail will first attempt to find the entry point and then two symbols that represent the version number of the interface definition. This interface can and will change in future versions of VMS, so we do no really document it here. For those people that want to know more about the interface it is suggest that the VXM__MAIN.C, VXM__OUTGOING.C, VXM__INCOMING.C and VXM__CONVERT modules be .x ^^VXM__MAIN.C .X ^^VXM__OUTGOING.C .X ^^VXM__INCOMING.C .X ^^VXM__CONVERT.C inspected for more details on the interface. .hl2 DECnet delivery symbiont .x Networks>^^DEC\\net .x Mail protocols>^^MAIL-11 .x Protocols>^^SMTP .x Mail protocols>^^SMTP .hl2 Internet delivery symbiont The Internet delivery symbiont uses the SMTP (Simple Mail Transport Protocol) to .x Mail protocols>^^SMTP .x Networks>Internet .x Protocols>^^SMTP send mail above the TCP/IP protocols. The current Internet delivery symbiont .x Protocols>^^TCP/IP .x Protocols>^^SMTP uses the CMU-TEK-IP software to interface to the TCP/IP system. The Internet and DECnet mail delivery symbionts both use a common SMTP processing module. This module is currently written in BLISS and is SMTP.BLI. .X SMTP.BLI The Internet delivery symbiont acts much like the other symbionts. When it is invoked by the job controller it will do some internal initialization and then .x Job controller call the general QMS_SYMBIONT routines. .x ^^QMS_SYMBIONT.C These routines allow for the general processing of symbiont requests from the VAX/VMS job controller. .hl3 Basic flow of control The basic flow of control for the top level processing is: .ls .le;Do initialization, this includes translating the logical name for the control flags for the symbiont. .le;Call symbiont level processing routines. .le;When the symbiont level routines return, the do general clean up and close any log files. .le;Exit with the final status. .els The request processing level will do the following: .ls .le;Read the request that was given to us to process. .le;Find a group of users on a single node to send to. .le;Make the network connection to that node. .le;Call the SMTP level to send to that group of users on the single node. .le;Close the network connection. .le;Loop back to find the next group of users, until there are no more. .els It is assumed that there is various error checking at all of the steps in the process and that messages are delivered to the operator and/or the log file indicating the error that was encountered. .hl2 BITNET delivery symbiont The BITNET delivery symbiont is not yet written. .hl1 Servers The term "servers" is used very loosely. This is being used to include both the network servers and the foreign mail interface to VAXmail. .hl2 MAIL11 server .x Networks>^^DEC\\net .x Mail protocols>^^MAIL-11 .hl2 DECnet SMTP server The DECnet SMTP server is invoked by DECnet-VAX's NETACP to process an incoming network connection. This network connection is normally object 125 or it can be the task name MX-LISTENER. .x Networks>^^DEC\\net .x Mail protocols>^^SMTP .x Protocols>^^SMTP The SMTP servers share a common driver (or main) module. This allows the DECnet and the Internet SMTP servers to act in the same manner when dealing with SMTP mail messages. The server will: .ls .le;Do general initialization, including translation of the logical name for the control flags, open the log file (if needed) and inform the operator that it has started. .le;Open the passive network connection. .le;Call the SMTP routines to receive a network message. .le;Clean up after the SMTP routines have returned. This includes closing the log file and informing the operator that the server is shutting down. .els .hl2 Internet SMTP server .x Mail protocols>^^SMTP .x Networks>Internet The Internet SMTP server is invoked by the CMU-TEK-IP software's IPACP. .x Protocols>^^TCP/IP .x Protocols>^^SMTP The SMTP servers share a common driver (or main) module. This allows the DECnet and the Internet SMTP servers to act in the same manner when dealing with SMTP mail messages. The server will: .ls .le;Do general initialization, including translation of the logical name for the control flags, open the log file (if needed) and inform the operator that it has started. .le;Open the passive network connection. .le;Call the SMTP routines to receive a network message. .le;Clean up after the SMTP routines have returned. This includes closing the log file and informing the operator that the server is shutting down. .els .hl2 VAXmail foreign mail interface .x ^^VAX\\mail>^Foreign mail interface The foreign mail interface for the Queued Mail System is invoked at the user level by specifying an address which has the format Q%"address". The character(s) before the percent sign are concatenated with MAIL$PROTOCOL__ to .x Logical names>^^MAIL$PROTOCOL__Q form the logical name that represents the foreign mail sharable segment. For the Queued Mail System, the logical name that is used is MAIL$PROTOCOL__Q. For those people that want to know more about the interface it is suggest that the VXM__MAIN.C, VXM__OUTGOING.C, VXM__INCOMING.C and VXM__CONVERT.C modules be .x ^^VXM__MAIN.C .X ^^VXM__OUTGOING.C .X ^^VXM__INCOMING.C .X ^^VXM__CONVERT.C inspected for more details on the interface. .hl1 Utilities There is only one utility at this point in time with the Queued Mail System. This utility creates the indexed distribution list file, QMS__BUILD__DL.EXE. .HL2 QMS__BUILD__DL This program will take as input a text file and produce an indexed file that is used by various programs to either validate a local address or to route the mail into a distribution list. .x ^^QMS__BUILD__DL .hl1 Data file formats .hl2 Queue requests (REQUEST__ATTR.TXT) All queue requests have an extended attributes file. This file is called REQUEST__ATTR.TXT and is created in the QMS$QUEUE disk area. .x Logical Names>^^QMS$QUEUE The file has a predefined format which is: .ls .le;Version number (Currently version 1) .le;Absolute Date/time for the next warning message to be issued for undelivered mail. .le;Delta date/time for the following warning. .le;Absolute date/time for the request to expire, return the mail as undelivered. .le;Full file specification for the message file. .le;Format of the message file (currently only RFC822 is valid). .le;Return path .le;Recipients of the message (one per line until the end of the file). .els No other information is kept about a queue request. .HL2 Distribution list file .x ^^QMS__BUILD__DL .hl3 Text file (MAIL.LST) .x Distribution lists>^^MAIL.LST The distribution file that is used by the queued mail system is an indexed file. The indexed file allows for quick access to a specific distribution list. To create the indexed file the program QMS_BUILD_DL is used. This .X Distribution lists .x ^^QMS__BUILD__DL program will take as input a file named MAIL.LST. The MAIL.LST file will .x ^^MAIL.LST define the distribution lists that are to be used. The format of the distribution list file is: .b list__name = address [, address] .b Additionally, the "!" character is used for comments and lines may be continued by using a hyphen at the end of a line. A line could be: .b LOCAL-INFO-VAX = SY$RCM, ADMIN$ROSENBERG, SY$STEVENS, - .BR;#################SY$GOLDMAN@BEANIE.STEVENS-TECH.EDU .B If the user name that is being placed in the distribution list is for a local user it will be validated to make sure that the user name doesn't have mail disabled and is valid. .hl3 Indexed file The indexed file consists of one key, the name of the distribution list and three other fields. The other fields are the length of the translation, the translation and a spare field. The logical name that points to the translation file on the system is QMS$DISTR__LIST__FILE. .X Logical names>^^QMS$DISTR__LIST__FILE .ax Module internals This section describes the routines that are found in the various modules that comprise the Queued Mail System. What is provided here is for reference only and should not be taken as how the system currently works. This information is current as of version 1.0.001. .CHAPTER QMS__CLONE__MESSAGE .hl1 Clone__Initialize .br;No parameters. This function initializes any variables which are unique to the module and need to be kept static during the module, but need to be reinitialized for each running of the module. .hl1 Qms__Clone__Text Parameters: .ls 'o' .le;orig__rab .br;struct RAB, by reference .br;Original file's RAB .b .le;clone__rab .br;struct RAB, by reference .br;Clone file's RAB .els This function copies the text in the given file into a new file. It uses QMS_FILE to do all the nasty IO work. .hl1 Qms__Open__Clone Parameters: .ls 'o' .le;message__file .br;struct string, by reference .br;Dynamic string descriptor message file name .b .le;message__fab .br;struct FAB, by reference .br;Message file's FAB .b .le;message__rab .br;struct RAB, by reference .br;Message file's RAB .b .le;cloned__file .br;struct string, by reference .br;Dynamic string descriptor of cloned file name .b .le;cloned__fab .br;struct FAB, by reference .br;Cloned file's FAB .le;cloned__rab .br;struct RAB, by reference .br;Cloned file's RAB .le;cloned__opened .br;struct string, by reference .br;File name cloned file is opened under .els This function will open the message file for reading and the clone file for writing, using the routines from QMS_FILE .hl1 Qms__Close__Clone Parameters: .ls 'o' .le;message__fab .br;struct FAB, by reference .le;message__rab .br;struct RAB, by reference .le;clone__fab .br;struct FAB, by reference .le;clone__rab .br;struct RAB, by reference .els This function will close the two files created by the qms__clone routine. .hl1 Write__Line__To__Clone Parameters: .ls 'o' .le;file__record .br;struct string, by reference .br;Dynamic string pointer to the line to be output .le;clone__fab .br;struct FAB, by reference .br;Clone file's FAB .le;clone__rab .br;struct RAB, by reference .br;Clone file's RAB .le;message__fab .br;struct FAB, by reference .br;Message file's FAB .le;message__rab .br;struct RAB, by reference .br;Message file's FAB .els This routine writes a line to the clone file. If there is an error, both the original message file and the clone file are closed. In either case, the status is returned. .hl1 Clone__Copy__String Parameters: .ls 'o' .le;input__string .br;struct string, by reference .br;String to copy from .le;output__string .br;struct string, by reference .br;String to copy to .els This routine will copy one dynamic string to another one. .hl1 Clone__Check__Address__Field Parameters: .ls 'o' .le;field__name .le;struct string, by reference .els This routine determines if the field name it is given is one of those which contains an address. .hl1 Clone__Extract__Field__name Parameters: .ls 'o' .le;header .br;struct string, by reference .br;Dynamic string descriptor of header line .le;field__name .br;struct string, by reference .br;Dynamic string descriptor of field_name .els This routine will extract the field name from the header line. .hl1 Clone__Read__Header Parameters: .ls 'o' .le;file__rab .br;struct RAB, by reference .br;Pointer to RAB of file to read from .le;header__line .br;struct string, by refernce .br;Pointer to header line string .els This routine will read the header lines of the message file. If the header line is not one of those that require processing, the information will just be written into the destination file. The routine returns when a null line is found (i.e., a line containing only a CRLF), since this signals the end of the headers. .hl1 Clone__Translate__Header Parameters: .ls 'o' .le;message__rab .br;struct RAB, by reference .br;Message file's RAB block .le;clone__rab .br;struct RAB, by reference .br;Clone file's RAB block .le;local__node__name .br;struct string, by reference .br;Name of local network node .els This function reads in the header line, determines if it is one of the 'from' lines (e.g., FROM, RESENT-FROM, etc.). If so, it sends the header off to the clone_parse_mailbox routine, which determines if the address is properly formatted according to RFC-822 specifications and if there is a return domain name. If no return domain name is there, one is added. After the function deals with it, the header line is written to the clone file, either as it was read in (if it wasn't changed) or as it was changed in clone__parse__message. .hl1 Clone__Make__Filename Parameters: .ls 'o' .le;message__file .br;struct string, by reference .br;Original message file's name .le;cloned__file .br;struct string, by reference .br;Cloned file's name .le;destination__network .br;struct network__dispatch_fields, by value .br;Destination of clone file .els This function creates the file name for the clone file by appending the network name to the end of the message file's name. .hl1 Clone__File Parameters: .ls 'o' .le;message__file .br;struct string, by reference .le;cloned__file .br;struct string, by reference .le;cloned__file;destination__network .br;struct network_dispatch_fields, by value .els Main clone file function. It calls the other functions to modify the message headers as necessary and to copy the message text into the clone file. .hl1 Clone__Add__Local__Domain Parameters: .ls 'o' .le;header .br;struct string, by reference .br;Dynamic string pointer to entire header line .le;address .br;struct string, by reference .br;Dynamic string pointer to where to add the local domain name .le;local__node .br;struct string, by reference .br;Dynamic string pointer to local node name .els This function will add the local domain name to the return address. .hl1 Clone__Parse__Comment Parameters: .ls 'o' .le;mailbox .br;struct string, by reference .br;string pointer to header .els This function is called when a parenthesis, indicating the beginning of a comment, is found. It parses through the header until the end of the comment is found. It deals with embedded comments as well. .hl1 Clone__Skip__Lwsp Parameters: .ls 'o' .le;mailbox .br;struct string, by reference .els This function skips the linear-white-space in the header line. .hl1 Clone__Parse__Atom Parameters: .ls 'o' .le;mailbox .br;struct string, by reference .els This routine will parse an atom. It will continue down the string until the end of the atom is found, signaled by the end of the mailbox, an open angle-bracket, an at-sign, or by any of a group of special or control characters. .hl1 Clone__Parse__Domain Parameters: .ls 'o' .le;mailbox .br;struct string, by reference .els This routine will parse a domain of the standard RFC822 form: subdomain *('.'subdomain) where subdomain is of the form domain-ref / domain-lit where domain-ref is an atom and domain-lit is of the form '[' dtext/quoted-pair ']' where dtext is any character, including SPACE and HTAB, but excepting '[',']','\', and CR, and a quoted-pair is of the form: '\' CHAR .hl1 Clone__Parse__Domain__Literal Parameters: .ls 'o' .le;mailbox .br;struct string, by reference .br;Pointer to mailbox in header .els This function will parse an RFC822 domain literal. .hl1 Clone__Parse__Quoted__String Parameters: .ls 'o' .le;mailbox .br;struct string, by reference .els This routine will parse a quoted string, searching through until the terminating " is found. .hl1 Clone__Parse__Route__Address Parameters: .ls 'o' .le;mailbox .br;struct string, by reference .els This routine will parse the route-address of the mailbox. According to RFC822 syntax, a route-address is of the form: '<'[route]address-spec'>' where the route is defined as: ('@'domain)':' and address-spec is defined as: local-part'@'domain .hl1 Clone__Parse__Mailbox Parameters: .ls 'o' .le;header .br;struct string, by reference .br;Pointer to beginning of entire header .le;mailbox .br;struct string, by reference .br;Pointer to beginning of mailbox in header .le;local__node .br;struct string, by reference .br;Pointer to local__node name .els This routine will parse a mailbox, removing any leading lwsp and any comments within parentheses. It will determine if a domain name needs to be added to the local-part of the address spec. .chapter QMS__CREATE__REQUEST .hl1 Qc__Initialize .br;No parameters. This routine will initialize the queue request creation module. All variables and interfaces that require initialization will be handled by this routine. .hl1 build__request__file Parameters: .ls 'o' .le;warn__time .br;struct string, by reference .br;String pointer to the warning time .le;warn__delta .br;struct string, by reference .br;String pointer to the warning delta .le;expire__time .br;struct string, by reference .br;String pointer to the expiration time .le;message__file .br;struct string, by reference .br;File name of the message text .le;mail__protocol .br;struct string, by reference .br;String pointer to mail protocol .le;reverse__path .br;struct string, by reference .br;Path to the message sender .le;recipient__list .br;struct list__header, by reference .br;List of address to receive this message .le;resulting__file .br;struct string, by reference .br;Store resulting file spec here .els This function will create the extended request file. It will then write the information into the file and then return. .hl1 build__item__list Parameters: .ls 'o' .le;item__list__desc .br;struct string, by reference .br;Dynamic string for item list .le;queue__name .br;struct string, by reference .br;String descriptor for the queue name .le;file__name .br;struct string, by reference .br;String descriptor for the file .le;delay__ptr .br;double, by reference .br;Delay to process file in queue .els This routine will build the send to job controller item list that is required for the submission of the request to the queue. .hl1 add__item Parameters: .ls 'o' .le;item__list__desc .br;struct string, by reference .br;Dynamic string descriptor for item list .le;sjc__code .br;unsigned short, by reference .br;SJC code indicating contents of buffer .le;buffer__length .br;unsigned short, by value .br;Length of buffer to add to the item list .le;buffer__address .br;unsigned int, by value .br;Pointer to buffer to add to item list .le;return__length__address .br;unsigned int, by value .br;Address to receive length of info, returned by SYS$SNDJBC .els This function creates the item to be added to the item_list which will be sent to the job controller. The item includes the SJC code, a, pointer to a string and a return__length__address. After creating the item, it creates a dynamic descriptor to point to the item. .hl1 c__create__request Parameters: .ls 'o' .le;queue__name .br;struct string, by reference .br;Queue to enter the request into .le;message__file .br;struct string, by reference .br;File specification of the message file .le;reverse__path .br;struct string, by reference .br;User name to create the request for .le;warn__time .br;struct string, by reference .br;date/time for first warning .le;warn__delta .br;struct string, by reference .br;delta to be added to the warning time .le;expire__time .br;struct string, by reference .br;Date/time of expiration of request .le;mail__protocol .br;struct string, by reference .br;Protocol for mail to use .le;after__time .br;struct string, by reference .br;Time to wait before processing the request .br;unsigned long *after_time .le;recipient__list .br;struct list_header, by reference .br;List of recipients for the request .els This routine will create a queue request for the caller. This function will call the various other routines to write the information into the request file and then it will create the request. .J.LM10.RM65.SP1 .P .CHAPTER qms__decnet .hl1 net__initialize .br;No parameters. This function will initialize the DECnet network module. It will open the channel to the NET: device. .hl1 net__get__domain Parameters: .ls 'o' .le;domain .br;struct string, by reference .br;Address of the dynamic descriptor .els This routine will return the domain name for this network. .hl1 net__connect__object Parameters: .ls 'o' .le;remote__node .br;struct string .le;protocol__key .br;int, by reference .els This routine is called to establish a connection to the remote DECnet mailer. .hl1 net__connect__mm Parameters: .ls 'o' .le;remote__node__name .br;struct string, by reference .els This routine is called to establish a connection to the remote MM mailer. .hl1 net__connect__mx Parameters: .ls 'o' .le;remote__node__name .br;struct string, reference .els This routine is used to connect to the remote MX mailer. .hl1 net__connect__mail11 Parameters: .ls 'o' .le;remote__node__name .br;struct string, by reference .els This routine is used to connect to a remote MAIL11 mailer. .hl1 net__close__link .br;No parameters. This routine will close the current network connection. It will return the close status code to the caller. .hl1 net__accept__connection .br;No parameters. This routine is called to complete the logical link connection being established by the remote connection .hl1 net__receive__data Parameters: .ls 'o' .le;buffer__address .br;char, by reference .br;Address of the buffer pointer .le;max__length .br;int, by reference .br;Maximum length of the buffer .le;result__length .br;int, by reference .br;Address of the buffer length variable .els This routine is called to read data off the network. The routine will return the buffer read off the net, as well as the length of the string to the caller .hl1 net__send__character Parameters: .ls 'o' .le;character .br;char, by reference .br;Character to send over the network .els This routine is called to send a single character out across the network to the remote mailer. .hl1 net__send__data Parameters: .ls 'o' .le;data__address .br;char, by reference .br;Address of the string to send .le;data__length .br;int, by value .br;Length of the data to send .els This routine is called to send a string of data out across the network to the remote mailer. .hl1 net__check__connection .br;No parameters. NET CHECK CONNECTION .J.LM10.RM65.sp1 .P .chapter QMS__DECNET__DELIVR .hl1 main .br;No parameters. This is the main routine for the message routine. It will initialize the various modules and then call the symbiont driver module to do all of the real work. .hl1 process__request Parameters: .ls 'o' .le;stream .br;unsigned long, by value .br;Currently running stream .els This routine is the main routine to process a single request. It is called by the symbiont driver, when we are in the run state and have parsed all of the various parameters. .br;What this routine will do is: .ls .le;Read the request building an in memory data base. .le;Split the recipient list up into a list into separate lists for: .ls "o" .le;Local delivery. .le;Network delivery. .els .le;If more than one output queue is required, then clone the message test file. .le;Submit the new information into the various output queues. .le;Release the request. .els .hl1 send__out__mail Parameters: .ls 'o' .le;recipient__list .br;struct list_header, by reference .le;message__file .br;struct string, by reference .le;retry__list .br;struct list_header, by reference .els This routine will send out mail. .hl1 struct list__member *requeue__current__recipient(position) Parameters: .ls 'o' .le;position .br;struct list__member, by reference .els This routine is called to move the current element from the per-node recipient list to the requeue list. .hl1 cleanup__mail__processing Parameters: .ls 'o' .le;passed__status .br;int, by value .els This routine is called to reset all global variables at termination of message processing. It will return to the caller the status passed to it, thus preserving the current status. This routine should be called at the end of PROCESS__REQUEST. .J.LM10.RM65.sp1 .P .chapter common__routines .hl1 cmn__list__per__node Parameters: .ls 'o' .le;input__list .br;struct list__header, by reference .le;per__node__list .br;struct list__header, by reference .le;current__node .br;struct string, by reference .els This routine is called to extract from an input list all elements of mail that are destined for the same destination node. .J.LM10.RM65.sp1 .P .chapter qms__distr__list .hl1 translate__initialization .br;No parameters. This routine is to be called before any Distribution List translations are to be performed. This routine will initialize any required data blocks and global variables, as well as open up the data file. .hl1 translate__name Parameters: .ls 'o' .le;keyword .br;struct string, by reference .le;destination__address .br;struct string, by reference .els This routine is called to perform the initial translation of a specified distribution list. If a successful translation is performed then the translation is returned to the caller, else the routine returns a failure to the caller. Subsequent calls to TRANSLATE__NEXT__IN__SERIES must be made if this routine makes a successful translation .hl1 translate__next__in__series .br;Parameters: .ls 'o' .le;keyword .br;struct string, by reference .le;destination__address .br;struct string, by reference .els This routine is called to make subsequent translations of a given Distribution list. The routine sequentially reads down the data file to find the rest of the translations for the given KEYWORD This routine must be called in a loop, as it can return only one translation per call. When it fails to find another translation the routine will return false. .hl1 translate__validate__name Parameters: .ls 'o' .le;keyword .br;struct string, by reference .els This routine is called to validate whether the specified address is a distribution list. If it is then a successful return is given, otherwise a record-not-found is returned. .hl1 translate__shut__down .br;No parameters. This routine is called when all translations are complete. It will close down the data file, and perform any cleanup required. .hl1 open__translation__file .br;No parameters. This procedure is called to open up the translation file, it assumes that the FAB and RAB blocks have been initialized. The routine will modify the default values to those that are specific to our case, and then Open and Connect to the Data file. .hl1 get__translation Parameters: .ls 'o' .le;keyword .br;struct string, by reference .els his routine is called to retrieve a record out of the data file. If the access mode is SEQUENTIAL then the routine will verify that the retrieved keyword matches the specified keyword. .J.LM10.RM65.sp1 .P .chapter QMS__ERROR .hl1 error__message Parameters: .ls 'o' .le;error__string .br;struct string, by reference .els This routine will send a message to the operator and/or log it as specified by the system flags. .j.lm10.rm65.sp1 .P .chapter qms__extract__header__info .hl1 extract__header__info Parameters: .ls 'o' .le;file__name .br;struct string, by reference .le;subject__destination .br;struct string, by reference .le;to__list__destination .br;struct string, by reference .le;from__destination .br;struct string, by reference .els This routine is called to retrieve specific fields from the header lines of the mail text file. The routine will return the text of the requested header lines, by skipping over the keywords in the header line. If the caller passes a NULL as a destination, the routine will not attempt to retrieve that specified header line. .hl1 determine__header__type Parameters: .ls 'o' .le;input__buffer .br;struct string .le;return__type .br;unsigned long .els This routine is called to determine what type of header we have retrieved. The determination is done by seeing if the beginning of the string equals a specified header keyword. The header types of this routine can determine are SUBJECT, TO, and 0FROM. The routine will then return to the calling routine an information message that specifies the type of header it is. .hl1 extract__info Parameters: .ls 'o' .le;destination .br;struct string, by reference .le;source .br;struct string, by reference .le;header__length .br;int, by value .els This routine is called to take care of extracting the wanted text from the header buffer. The argument HEADER__LENGTH is a value that indicates the number of characters to skip so we get just the text and not the header keyword. .J.LM10.RM65.sp1 .P .chapter qms__file .hl1 file__create__file Parameters: .ls 'o' .le;file__name .br;struct string, by reference .br;File name to open .le;file__rab .br;struct RAB, by reference .br;Record attributes block .le;file__fab .br;struct FAB, by reference .br;File attributes block .le;resulting__file__name .br;struct string, by reference .br;Resulting file name string .els This routine will open a text file. The file name will be generated by the routine. .hl1 file__close Parameters: .ls 'o' .le;file__rab .br;struct RAB, by reference .br;Record attributes block .le;file__fab .br;struct FAB, by reference .br;File attributes block .els This routine will close the text file. It will mainly call RMS to close the file that we created. .hl1 file__write__line Parameters: .ls 'o' .br;line .br;struct string, by reference .br;Line of text to write to the file .le;file__fab .br;struct RAB, by reference .br;Record attributes block .els This function will write a line of text into the message file that we are creating. .hl1 file__open Parameters: .ls 'o' .le;file__name .br;struct string, by reference .br;File name we are going to read .le;file__fab .br;struct FAB, by reference .br;File attribute block .le;file__rab .br;struct RAB, by reference .br;File record attribute block .els This routine will open a file for reading. It is called with the file name, and RMS blocks that are needed to read the file. .HL1 file__read__record Parameters: .ls 'o' .le;returned__record .br;struct string, by reference .br;Return we are returning .els This routine will read a record from the file. It will modify the record to add any formatting characters (adding form feeds, etc). .J.LM10.RM65.sp1 .P .chapter qms__information .hl1 info__message Parameters: .ls 'o' .le;info__string .br;struct string, by reference .br;String to output .le;level .br;enum information__types, by value .br;Level to output this at .els This routine will send a message to the operator and/or log it as specified by the system flags. .hl1 info__fao Parameters: .ls 'o' .le;fao__descriptor .br;struct string, by reference .le;output__level .br;enum information__types, by value .le;va__dcl .els This routine will expand an FAO string and log it to the proper output depending on the error level. .hl1 info__err__status Parameters: .ls 'o' .le;fao__descriptor .br;struct string, by reference .br;Pointer to FAO descriptor .le;output__level .br;enum information__types, by value .br;Output level .le;error__status .br;unsigned int, by value .br;Error status .le;va__dcl .els This routine will build the message to output with an error status. It will accept an FAO string and do lots of niffty things. .J.LM10.RM65.sp1 .P .chapter qms__internet .hl1 net__initialize .br;No parameters. This function will initialize the Internet network module. It will open the channel to the IP0: device. .hl1 net__get__domain Parameters: .ls 'o' .le;domain .br;struct string, by reference .br;Address of the dynamic descriptor .els This routine will return the domain name for this network. .hl1 net__close__link .br;No parameters. This routine will close the current network connection. It will return the close status code to the caller. .hl1 net__accept__connection .br;No parameters. [@tbs@] .hl1 net__receive__data Parameters: .ls 'o' .le;buffer__address .br;char, by reference .br;Address of the buffer pointer .le;max__length .br;int, by reference .br;Maximum length of the buffer .le;result__length .br;int, by reference .br;Address of the buffer length variable .els [@tbs@] .hl1 net__send__character Parameters: .ls 'o' .le;character .br;char, by value .br;Character to send over the network .els [@tbs@] .hl1 net__send__data Parameters: .ls 'o' .le;data__address .br;char, by reference .br;Address of the string to send .le;data__length .br;int, by value .br;Length of the data to send .els [@tbs@] .J.LM10.RM65.sp1 .P .chapter QMS__LIBRARY .hl1 lib__translate__logical Parameters: .ls 'o' .le;result__string .br;struct string, by reference .br;Result of the translation .le;logical__string .br;struct string, by reference .br;Logical name to translate .els This function will translate a logical name. .hl1 lib__delta__to__abs__time Parameters: .ls 'o' .le;delta__time__string .br;struct string, by reference .br;String descriptor .le;absolute__time[2] .br;unsigned long, by reference .br;64 bit system time format .els This routine will convert a delta time to a 64 bit absolute time. This routine is used for creating queue requests. .J.LM10.RM65.sp1 .P .chapter qms__lists .hl1 list__insert Parameters: .ls 'o' .le;element .br;char, by reference .br;Element to insert into list .le;position .br;struct list__member, by reference .br;Where to insert it .le;list .br;struct list__header, by reference .br;Header of list to insert into .le;length .br;int, by value .br;Length of element to insert .els This function will insert an element at a given position in the list. If the position passed is NULL, then the new element will be inserted into the front of the list. Otherwise, the element will be inserted AFTER the position passed to the function. .hl1 Parameters: .ls 'o' .le;list__locate(element, list) .br;struct list__member, by reference .le;element .br;unsigned char, by reference .br;Item to be located in the list .le;list .br;struct list__header, by reference .br;List in which to search .els This function will return the position of an element in the list. If the element does not exist in the list, then a pointer to the last element of the list is returned. .hl1 list__delete Parameters: .ls 'o' .le;position .br;struct list__member, by reference .br;Position to delete .le;list .br;struct list__header, by reference .br;List from which to delete .le;length .br;int, by value .br;Size of the element data .els This function deletes an element from the given list from the given position. .hl1 Parameters: .ls 'o' .le;list__next(position, list) .br;struct list__member, by reference .le;position .br;struct list__member, by reference .br;Position to process .le;list .br;struct list__header, by reference .br;List to manipulate .els This function will return the position of the next element following the given element in the specified list. If the current element is the last of the list, it is returned. .hl1 Parameters: .ls 'o' .le;list__previous(position) .br;struct list__member, by reference .le;position .br;struct list__member, by reference .br;Position to process .le;list .br;struct list__header, by reference .br;List to search in .els This function will return the position of the previous element following the given element in the specified list. If the current element is the first in the list, a pointer to it is returned. .hl1 list__make__null Parameters: .ls 'o' .le;list .br;struct list__header, by reference .br;List to remove .els This function will cause the specified list to become empty and return the position of the end of the list. .HL1 list__first PARAMETERS: .ls 'o' .le;Implemented as a macro .br;struct list__member list__first(list) .br;struct list__header *list; List to search .els This function will return the position of the first element in at list. .HL1 list__end Parameters: .ls 'o' .le;Implemented as a macro .br;struct list__member list__end(list) .els This routine will return the position of the last element in the list. .hl1 list__move__entry Parameters: .ls 'o' .le;current__list .br;struct list__header, by reference .br;List owning the cell to move .le;position .br;struct list__member, by reference .br;Position of the cell to move .le;new__list .br;struct list__header, by reference .br;New list to insert cell onto .els This routine will move a list entry from one list to another list. .hl1 list__make__str__list__null Parameters: .ls 'o' .le;string__list .br;struct list__header, by reference .br;Dynamic string list .els This routine will delete a list of dynamic string descriptors .J.LM10.RM65.sp1 .P .chapter qms__local__delivery .hl1 main .br;No parameters. This is the main routine for the message routine. It will initialize the various modules and then call the symbiont driver module to do all of the real work. .hl1 process__request Parameters: .ls 'o' .le;stream .br;unsigned long, by value .br;Currently running stream .els This routine is the main routine to process a single request. It is called by the symbiont driver, when we are in the run state and have parsed all of the various parameters. .br;What this routine will do is: .ls .le;Read the request building an in memory data base. .le;Determine how to deliver each message to each user. .le;Call the proper delivery routine for each message. .els .HL2 how__to__deliver Parameters: .ls 'o' .le;how__to__deliver(recipient) .br;enum local__delivery__mechanisms, by value .le;recipient .br;struct string, by reference .br;Recipient of the message .els This routine will determine the delivery mechanism to use for the local delivery of mail. This routine is supplied with the understanding that future versions of the local delivery will use more than just VAXmail. .HL2 deliver__to Parameters: .ls 'o' .le;vai .br;enum local__delivery__mechanism, by value .br;How to deliver .le;recipient .br;struct string, by reference .br;Who to deliver to .le;message__file .br;struct string, by reference .br;File we are delivering .els This routine will call the various delivery mechanisms to deliver the local mail. The status of the delivery from the lower level will then be returned to the upper level .HL2 deliver__vaxmail Parameters: .ls 'o' .le;recipient .br;struct string, by reference .br;Who we are sending to .le;message__file .br;struct string, by reference .br;File we are sending to .els This routine will cause mail to be delivered to the VAXmail user agent. It will spawn VAXmail with the proper commands to cause to read the message with the foreign mail protocol interface. .J.LM10.RM65.sp1 .P .chapter qms__logger .hl1 log__initialize .br;No parameters. This routine will initialize the log file processing. .hl1 log__open Parameters: .ls 'o' .le;log__file__name .br;struct string, by reference .br;Log file to open .els This routine will open the log file. .hl1 log__close .br;No parameters. This routine will close the currently open log file. .hl1 log__message Parameters: .ls 'o' .le;line .br;struct string, by reference .br;Pointer to the line of text to write .els This function will write a line of text to the log file. It will return the status of the $PUT to the log file to the caller. .hl1 log__fao Parameters: .ls 'o' .le;fao__descriptor .br;struct string, by reference .le;va__dcl .els This routine will log an FAO string .hl1 log__header Parameters: .ls 'o' .le;log__file__name .br;struct string, by reference .br;Log file name .els This function will write a standard header into the log file for informational purposes. The header includes the file name, the date/time of the creation of the file, and random information. .J.LM10.RM65.sp1 .P .chapter qms__operator .hl1 oper__message Parameters: .ls 'o' .le;message__string .br;struct string, by reference .br;String to send to the operator .els This routine will send a string to the operator terminal. It will return the status of the SNDOPR system service. .J.LM10.RM65.sp1 .P .chapter QMS__PARSE__ADDRESS .hl1 parse__address__initialize .br;No parameters. Initialization routine for the address parsing module. This routine will translate various system logical names for the local node name and domain. .hl1 parse__path Parameters: .ls 'o' .le;address .br;struct string, by reference .br;Pointer to the string address .els This routine will parse a RFC-822 path specification. This includes the at-domain list and the mailbox. .hl1 parse__mailbox Parameters: .ls 'o' .le;address .br;struct string, by reference .br;Mailing address to parse .els This routine will parse a valid RFC-822 mailbox. .hl1 parse__mailbox__internal Parameters: .ls 'o' .le;mailbox .br;struct string, by reference .br;Pointer to the mailbox string .els This is the internal routine that will part a mailbox. .hl1 parse__local__part Parameters: .ls 'o' .le;mailbox .br;struct string, by reference .br;Pointer to the mailbox .els This routine will parse the local part of an address. .hl1 parse__domain Parameters: .ls 'o' .le;mailbox .br;struct string, by reference .br;Pointer to the mailbox .els This routine will parse the domain part of a mailbox .hl1 parse__at__domain__list Parameters: .ls 'o' .le;mailbox .br;struct string, by reference .br;Pointer to the mailbox .els This routine will parse a at domain list that can optionally precede the local part of the mailbox. .hl1 parse__element Parameters: .ls 'o' .le;mailbox .br;struct string, by reference .br;Mailbox to parse .els This routine will parse an element of a domain name. This can either be a word or the [nnn.nnn.nnn.nnn] form of the name. .hl1 parse__snum Parameters: .ls 'o' .le;mailbox .br;struct string, by reference .br;Mailbox to parse .els This function will parse a three digit number and return to the caller. .J.LM10.RM65.sp1 .P .chapter qms__read__request .hl1 qr__read__request Parameters: .ls 'o' .le;message__file .br;struct string, by reference .br;File containing message text .le;reverse__path .br;struct string, by reference .br;User name of requester .le;warn__time .br;struct string, by reference .br;Date/time next warning is due .le;warn__delta .br;struct string, by reference .br;Time between warnings .le;expire__time .br;struct string, by reference .br;Date/time of expiration of message .le;mail__protocol .br;struct string, by reference .br;Protocol for mail to use .le;req__version__str .br;struct string, by reference .br;Version of mail which wrote the request .le;recipient__list .br;struct list__header, by reference .br;List of recipients for the request .els This routine will read a request into memory. .hl1 retrieve__request__file Parameters: .ls 'o' .le;req__version__str .br;struct string, by reference .br;Version of mail which wrote the request .le;warn__time .br;struct string, by reference .br;Date/time to send a warning .le;warn__delta .br;struct string, by reference .br;Time between warnings .le;expire__time .br;struct string, by reference .br;Time at which to expire message .le;message__file .br;struct string, by reference .br;File containing message text .le;mail__protocol .br;struct string, by reference .br;Protocol for mail to use .le;reverse__path .br;struct string, by reference .br;User who originated request .els This function will retrieve all pertinent information except the recipient list and return the information to its caller. .hl1 build__recipient__list Parameters: .ls 'o' .le;recipient__list .br;struct list__header, by reference .br;Pointer to list header for recipient list .els This routine will read each remaining line in the request file as a recipient and build from these a list of recipients to receive the message file. .hl1 abort__retrieve__request .br;No parameters. This routine will close the request file and return the status which is passed to it. This is only here to make the code in 'retrieve__request__file' a bit more neat. .J.LM10.RM65.sp1 .P .chapter QMS__ROUTER .hl1 main .br;No parameters. This is the main routine for the message routine. It will initialize the various modules and then call the symbiont driver module to do all of the real work. .hl1 router__initialize .br;No parameters. This routine will initialize the various data bases for the message router. This routine will return after all of the data bases local and external modules are finished initialization. .hl1 rtr__init__flags .br;No parameters. This routine will initialize the module flags. .hl1 rtr__init__dispatch .br;No parameters. This routine will initialize the router network dispatch table. .hl1 router__shutdown .br;No parameters. This routine will handle the router shutdown. It will call the various module routines that are required to shutdown the router. .hl1 process__request Parameters: .ls 'o' .le;stream .br;unsigned long, by value .br;Currently running stream .els This routine is the main routine to process a single request. It is called by the symbiont driver, when we are in the run state and have parsed all of the various parameters. .br;What this routine will do is: 1. Read the request building an in memory data base. 2. Split the recipient list up into a list into separate lists for: - Local delivery. - Network delivery. 3. If more than one output queue is required, then clone the message test file. 4. Submit the new information into the various output queues. 5. Release the request. .hl1 process__item Parameters: .ls 'o' .le;stream .br;unsigned long, by value .br;Stream that is currently running .le;item__code .br;unsigned long, by value .br;Message item code .le;item__buffer .br;unsigned long, by reference .br;Pointer to the information .le;item__size .br;unsigned long, by value .br;Size of the information .els This routine will handle the processing of a specific message item that is not handled by the symbiont driver module. These are queue specific items. .hl1 process__abort Parameters: .ls 'o' .le;stream .br;unsigned long, by value .br;Currently running symbiont stream .els This function will abort the current request for the driver symbiont. This routine should be a no-op, since we don't have to do any of that yet in this symbiont. .hl1 build__internal__request Parameters: .ls 'o' .le;recipient__list .br;struct list__header, by reference .br;Recipient list .le;message__file .br;struct string, by reference .br;Message file specification .le;reverse__path .br;struct string, by reference .br;Reverse path for sending message back .els This routine will build the internal message request data structures. It will read the queue information and insure that all of the proper information is present. .hl1 route__message Parameters: .ls 'o' .le;recipient__list .br;struct list__header, by reference .br;List of recipients .le;message__file .br;struct string, by reference .br;Message file specification .le;reverse__path .br;struct string, by reference .br;Reverse path for sending message back .els This routine will break the recipient list up into the lists for the various networks that we support. This routine will call the router network routines to determine which network owns the request. Distribution lists will be expanded at this point. .hl1 submit__routed__message Parameters: .ls 'o' .le;message__file .br;struct string, by reference .br;Message file specification .le;reverse__path .br;struct string, by reference .br;Reverse path for sending message back .els This routine will submit the routed messages to the proper queue for processing. It will clone the message if there is more than one output queue to be used. .hl1 error__invalid__address Parameters: .ls 'o' .le;reverse__path .br;struct string, by reference .br;Path message came from .le;address__list .br;struct list_header, by reference .br;List of problem addresses .els This routine will send an error message to the user stating that the address that they are attempting to send to is an invalid address. .hl1 error__nomail Parameters: .ls 'o' .le;reverse__path .br;struct string, by reference .br;Path message came from .le;address__list .br;struct list__header, by reference .br;List of problem addresses .els This routine will return an error message to the sender of the message that the local address they are attempting to send to has disallowed mail delivery. .hl1 error__unknown__address Parameters: .ls 'o' .le;reverse__path .br;struct string, by reference .br;Path message came from .le;address__list .br;struct list__header, by reference .br;List of problem addresses .le;reverse__path .br;struct string, by reference .br;Path message came from .le;address__list .br;struct list_header, by reference .br;List of problem addresses .els This routine will create an error message for each unknown address in the list that is passed to this routine. .hl1 send__error__mail Parameters: .ls 'o' .le;subject__string .br;struct string, by reference .le;msg__line__1 .br;struct string, by reference .le;msg__line__2 .br;struct string, by reference .le;reverse__path .br;struct string, by reference .le;address__list .br;struct list__header, by reference .els This routine is the generic routine to send error mail back to the original sender of the mail. .J.LM10.RM65.sp1 .P .chapter qms__rtr__network .hl1 rtr__nw__initialize .br;No parameters. This routine will initialize the router network routines. This routine will call the network specific routines to initialized the specific interfaces .hl1 rtr__nw__shutdown .br;No parameters. This routine will shutdown the router network interface. It will call the various network routines to shutdown the networks. .hl1 enum network__types rtr__to__network Parameters: .ls 'o' .le;node__name .br;struct string, by reference .br;Node name to determine network type of .els This routine will determine which of the various networks to use. .hl1 network__node__local Parameters: .ls 'o' .le;node__name .br;struct string, by reference .br;String pointer to the node name .le;network .br;enum network__type, by value .br;Network type .els This routine will determine if the node name that is specified represents the local node name. .hl1 decnet__initialize .br;No parameters. This routine will initialize the DECnet interface. It will set the decnet__open flag to true if DECnet is present on this machine. .HL1 is__decnet Parameters: .ls 'o' .le;node__name .br;struct string, by reference .br;Node name to check if DECnet or not .els This routine will determine if the node name given is a DECnet node name. To do this it will use an undocumented ACP function that SHOW NET uses. .hl1 decnet__shutdown .br;No parameters. This routine will shutdown the DECnet processing. It assumes that the DECnet initialization routine has been called before this routine. .hl1 internet__initialize .br;No parameters. This routine will initialize the Internet (CMU version) interface. It will determine if there is a Internet interface on the basis of the existence of the IP0: device or not. .hl1 is__internet Parameters: .ls 'o' .le;node__name .br;struct string, by reference .br;Node name to check .els This routine will determine if a node name is an internet node or not. It will attempt to translate the node name to a node number to make the determination if the node is an Internet node or not. .hl1 internet__shutdown .br;No parameters. This routine will shut down the Internet interface. It will just deassign the channel to the IP0: device and clear the internet__open flag. .hl1 bitnet__initialize .br;No parameters. This routine will initialize the BITNET interface. .hl1 is__bitnet Parameters: .ls 'o' .le;node__name .br;struct string, by reference .br;Node name to check. .els This routine will determine if a node name is a BITNET node name. This routine will do nothing for now. .hl1 bitnet__shutdown .br;No parameters. This routine will shutdown the BITNET interface. This is a no-op currently. .J.LM10.RM65.sp1 .P .chapter QMS__SYMBIONT .hl1 symb__ast .br;No parameters. This routine is the symbiont ast routine that is specified in the initialization call. This routine will issue a SYS$WAKE and light the message received flag. .hl1 symbiont__initialize .br;No parameters. This routine is the general symbiont initialization routine. It will call the standard library routines. .hl1 symbiont__driver .br; No parameters. This routine is the main driver routine for the symbiont. .hl1 symb__read__message .br;No parameters. This routine will process the various message items in the message that was just received. .hl1 symb__initial .br;No parameters. This routine is called when the symbiont is in the initial state. The only valid message that the job controller send in this state is the start stream message. .hl1 symb__idle .br;No parameters. This routine will handle the symbiont when it is in the idle state. .hl1 symb__run .br;No parameters. This procedure is called when the symbiont is in the running state. It is the function of this routine to cause a request to be processed. .hl1 symb__paused .br;No parameters. This routine is called when the symbiont has paused the request for some reason. It will hibernate until it receives a message from the job controller telling it what to do. .hl1 symb__abort Parameters: .ls 'o' .le;reply__code .br;unsigned long, by value .els This routine will handle aborting a currently running request. It will cause all of the low level processing to finish. .hl1 symb__done .br;No parameters. This routine handles the clean up after a request is processed successfully. It will inform the job controller and then clean up any local data. .hl1 symb__clean__up .br;No parameters. General clean up after a request is processed. Any dynamic strings will be deallocated, etc. .hl1 initialize__per__job__data .br;No parameters. Initialize the per job (task) data. .hl1 symb__store__error__condition Parameters: .ls 'o' .le;error__condition .br;unsigned long, by value .els This routine will store an error condition into the error vector that is returned to the job controller when an error is encountered. This routine can be called internal to this module and external to the module by the processing routines .hl1 symb__fatal__error PARAMETERS: .ls 'o' .le;message .br;unsigned char, by reference .br;Error text to output .els This routine will handle the symbiont fatal errors. The fatal error will be sent to the operator and then the symbiont will exit without any further processing. .J.LM10.RM65.sp1 .P .chapter QMS__TEXT__MESSAGE .hl1 text__initialize .br;No parameters. This function will initialize the text message creation module. .hl1 text__finished, text__create__file .br;No parameters. This routine will clean up after creating a text file. It is called by either the submit routine or the abort routine. It will return all dynamic strings to memory. .hl1 text__file__close .br;No parameters. This routine will close the text file. It will mainly call RMS to close the file that we created. .hl1 text__abort .br;No parameters. This function will abort the creation of the current text message. It will cause the message for creation to be aborted, and then return the various dynamic strings that were allocated. .hl1 text__submit Parameters: .ls 'o' .le;queue .br;struct string, by reference .br;Queue to submit the request to .le;user__name .br;struct string, by reference .br;Name of the user we are submitting for .le;recipients .br;struct list__header, by reference .br;Recipient list .els This function will close the text file and submit it to the specified queue. .hl1 text__write__line Parameters: .ls 'o' .le;line .br;struct string, by reference .br;Line of text to write to the file .els This function will write a line of text into the message file that we are creating. .hl1 text__header__date .br;No parameters. This function will write the date header line into the output file. Since the date header line is a standard, this routine is provided to write the information into the output file. .hl1 text__header__item Parameters: .ls 'o' .le;header__item .br;struct string, by reference .br;Header item we are writing .le;header__info .br;struct string, by reference .br;Info to write after the item .els This function will write a text header item into the file. It will handling wrapping the text at 80 characters, and do any other formatting of the message header item that is required. .hl1 text__end__headers .br;No parameters. This routine will signal the start of the message text area. This routine must be called after writing the various header items into the message file. The delimiter between the headers and the text is a blank line. This routine will just call the write routine with a null string. .hl1 text__end__of__text, write__multiline__header(header__line, file__rab) Parameters: .ls 'o' .le;header__line .br;struct string, by reference .br;Address of header line descriptor .le;file__rab .br;struct RAB, by reference .br;Address of RAB to write to .els This routine will write the line of dashes to end the text part of message. .chapter QMS__VALIDATE .hl1 validate__address Parameters: .ls 'o' .le;search__address .br;struct string, by reference .els This routine is called to verify whether the specified address is valid for the node on which QMS is running. .subtitle Index .page .require "qms_internals.rnx"