submit -- submit mail for MMDF transport


/usr/mmdf/bin/submit [ -cdjlmnqrsStuvwWzf...*g...*h...*i...*x...*k...*L...*V...*U...*]


All mail is entered into the MMDF mail transport environment through the submit program. While it can be called directly from a user's terminal, access to submit is most conveniently performed through a program such as mail(C).

Basic modes

submit permits considerable flexibility with respect to batching multiple submissions, response and error handling, and address source specification.

Multiple submissions modes

  1. Terminate after one submission, such as is carried out by the mail command. Specified by passing any initialization information in the submit invocation line (that is, the exec(S) call).

  2. Permit multiple message submissions, as is done by the SMTP channel. The initialization information is given as the first input line, for each submission.
The format of this information is the same for both modes.

Response and error handling modes

  1. Accept input until error or end-of-message, but terminate on any error. This is called ``non-protocol mode''. This mode is mandatory when using Multiple submissions mode #1.

  2. Notify result for each segment and continue. This is called ``protocol mode''. During it, each address produces a status reply and the message text produces a reply. The domain of the term segment depends on the error. Simple addressing errors cause rejection only of the erroneous address. Other errors may cause rejection of the entire message, but permit submission of following messages.
Messages can now be submitted with a null return address in protocol mode Formerly, a null address for either the return address or a recipient address resulted in the silent termination of address-list processing. This caused a serious problem, because in verify-address mode the caller will expect a response to each address. If the caller passed a null address, it would result in a protocol lockup as the caller waited forever for a response while submit had moved on to expecting the message text. A null recipient address is not valid and should result in an explicit error, and a null return address is the standard indication that a return is not desired if the mail cannot be delivered. For example, execmail '' would hang. Address-list parsing is now terminated only by a !, as per the submit specification. For the sake of old programs that incorrectly used an empty address line to terminate the address list, a new submit option, e, causes submit to revert to the old behavior. Setting SUBMIT_EMPTY_ADDR_TERM=1 in the environment before executing submit is equivalent to passing the e option. The only known example of this is mush, when built to use submit directly. To make mush use this option without recompiling it, put this line in the global Mushrc file: To make mush use this option without recompiling it, put this line in the mush global .Mushrc. file:
   set sendmail='/usr/mmdf/bin/submit -mlnre'

Address modes

  1. Addresses extracted from components of the message text. Common when non-protocol mode is also in force for the Interaction and the Verification option.

  2. Explicit address list given ahead of message text. Common when the second modes apply for the other options (protocol mode).

  3. Both of the above (extracted and explicit addresses).


A message's initialization information is specified through a single string, passed either in the process-invocation argument list or in the first line of submit input. Hence, the string may be terminated either by a null or newline. Spaces and tabs in the line are ignored, unless part of a literal. Specification is only required for non-defaults.

  Option Value Literal
1. Relay source a. none (default)
  for the ``Via'' or b. source channel i...*
  ``Received'' field c. source host h...*
2. From/Sender a. reject on error (default)
  authentication b. trust, disclaim on error t
    c. no trust (disclaim) u
    d. add Sender: field S
3. ``Source-Info'' field a. not included (default)
    b. disclaim author u
    c. user text f...*
4. Address list source a. explicit list (default)
    b. extract from components x...*
    c. both (extract and g...*
5. Address verification a. abort on invalid (default)
    b. report on each address v
6. Delivery destination a. mailbox m (default)
7. Delivery attempt a. leave for daemon (default)
  (combinable) b. deliver local now l
    c. deliver netmail now n
8. Observation of a. none (default)
  immediate b. user will watch w
9. Return address a. send to submitter r
    b. send to ``Sender:'' s
    c. do not return q
    d. as specified (next line)
10. Returned mail a. entire original (default)
  contents b. citation only c
11. Warnings a. send warnings (default)
    b. do not send warnings z
12. Delay channel a. enable delay channel (default)
  usage b. don't use delay d
13. Delay channel a. not delay channel (default)
  indicator b. delay channel j
14. Nameserver a. short timeouts (default)
  timeouts b. as specified k...*
15. Submission a. not shown (default)
  tracing b. watch submission W
16. Logging file a. as per msglog (default)
    b. as specified L...*
17. Logging level a. as per msglog (default)
    b. as specified V...*
18. User id a. invoker's uid (default)
    b. as specified U...*

 |    | Option                | Value                       | Literal     |
 |1.  | Relay source          | a.|none                     | (default)   |
 |    | for the ``Via'' or    | b.|source channel           | i...*       |
 |    | ``Received'' field    | c.|source host              | h...*       |
 |2.  | From/Sender           | a.|reject on error          | (default)   |
 |    | authentication        | b.|trust, disclaim on error | t           |
 |    |                       | c.|no trust (disclaim)      | u           |
 |    |                       | d.|add Sender: field        | S           |
 |3.  | ``Source-Info'' field | a.|not included             | (default)   |
 |    |                       | b.|disclaim author          | u           |
 |    |                       | c.|user text                | f...*       |
 |4.  | Address list source   | a.|explicit list            | (default)   |
 |    |                       | b.|extract from components  | x...*       |
 |    |                       | c.|both (extract and        | g...*       |
 |    |                       |   |explicit)                |             |
 |5.  | Address verification  | a.|abort on invalid         | (default)   |
 |    |                       | b.|report on each address   | v           |
 |6.  | Delivery destination  | a.|mailbox                  | m (default) |
 |7.  | Delivery attempt      | a.|leave for daemon         | (default)   |
 |    | (combinable)          | b.|deliver local now        | l           |
 |    |                       | c.|deliver netmail now      | n           |
 |8.  | Observation of        | a.|none                     | (default)   |
 |    | immediate             | b.|user will watch          | w           |
 |    | attempts              |   |                         |             |
 |9.  | Return address        | a.|send to submitter        | r           |
 |    |                       | b.|send to ``Sender:''      | s           |
 |    |                       | c.|do not return            | q           |
 |    |                       | d.|as specified             | (next line) |
 |10. | Returned mail         | a.|entire original          | (default)   |
 |    | contents              | b.|citation only            | c           |
 |11. | Warnings              | a.|send warnings            | (default)   |
 |    |                       | b.|do not send warnings     | z           |
 |12. | Delay channel         | a.|enable delay channel     | (default)   |
 |    | usage                 | b.|don't use delay          | d           |
 |13. | Delay channel         | a.|not delay channel        | (default)   |
 |    | indicator             | b.|delay channel            | j           |
 |14. | Nameserver            | a.|short timeouts           | (default)   |
 |    | timeouts              | b.|as specified             | k...*       |
 |15. | Submission            | a.|not shown                | (default)   |
 |    | tracing               | b.|watch submission         | W           |
 |16. | Logging file          | a.|as per msglog            | (default)   |
 |    |                       | b.|as specified             | L...*       |
 |17. | Logging level         | a.|as per msglog            | (default)   |
 |    |                       | b.|as specified             | V...*       |
 |18. | User id               | a.|invoker's uid            | (default)   |
 |    |                       | b.|as specified             | U...*       |
Literals shown as characters, followed by an ellipsis, followed by an asterisk (for example x...*), represent a string. The first character specifies the nature of the setting. The value for the setting is placed between that character and the asterisk. The value may be any string not containing an asterisk, null, or newline. The values for settings x and g are comma-separated lists of strings. These strings may not contain asterisks, nulls, newlines, or commas.

Specific comments on each option:

  1. Relaying
    This is used when the calling program is interfacing with another distribution system, effecting relaying. The literal after the i specifies the channel the message is coming from. The h may be used, in conjunction with i, to specify the source host. The literal is the name of the host.

  2. From/Sender authentication
    Normally, a message that does not correctly identify its sender is rejected. Anyone may send mail with any author specified, but they must use either the u or t setting to bypass authentication. However, these settings may cause MMDF to include, in the Source-Info: component, a statement noting the absence of authentication. The u setting always adds this statement; the t setting only adds it if the user is not authorized (not root or mmdf) and the message header does not not correctly identify the sender. The relay channels are run under the mmdf uid in order to gain authorization such that the Source-Info: components is not added.

    The determination of whether a message correctly identifies its sender is based on the most authoritative From or Sender field. For the purpose of this test, a plain Sender is taken to be more authoritative than a plain From. If a Resent-, Remailed-, or Redistributed- version of either a From or Sender field is given, it is taken to be more authoritative than the plain version of either. All such "Re" headers are taken to be equally authoritative, and the last one seen in the header (the one furthest down in the header) is taken to be most authoritative. To determine whether a message correctly identifies its sender, the local-address part of the most authoritative sender is looked up in the password file to map it to a uid, and that uid is compared to the invoking user's uid. If the uids match and the hostname part of the address is a name for the local system, the message correctly identifies its sender.

    The S setting tells MMDF to use a Sender: field instead of a Source-Info: field, and also causes conflicting Sender: fields in the submitted header to be elided. This allows submission programs to send mail with a 'From:' field that does not match the identity of the invoking user without having to be privileged and without having a Source-Info: field added.

  3. Source-Info field
    In addition to the action explained above, Source-Info: can directly receive text, from the user, through the f setting. The value string is replicated on a separate line in the field.

  4. Address list source
    An explicit list has one address per line. When x or g are specified, they list the names of message components, such as To: and CC:, which are to be searched for addresses.

  5. Address verification
    Normally, any illegal address will cause the entire message to be rejected. In v (verify) mode, the acceptability of each message is reported and encountering an illegal address does not abort submission.

  6. Delivery destination
    Mail may be delivered only to a recipient's mailbox (file).

  7. Delivery attempt
    An immediate attempt causes a special deliver process to be forked and it will attempt to process the indicated mail immediately. (The n setting does not allow more granularity, for historical reasons.) Otherwise, the system's background daemon will get to it eventually. The daemon also handles mail that initially could not be delivered/relayed. A channel's descriptor structure (in chan.c or the runtime tailor file) specifies a channel as being Active, Passive, or Background. Only the first is processed by any request for immediate delivery. The second indicates a Post Office Box-style channel. The third limits the channel to processing by the background deliver daemon, which may be necessary for restricting access to special channels, such as dial-out telephones.

  8. Observation
    If an immediate attempt is requested, the user may elect to watch its progress. deliver and its children will report assorted aspects of their activity. If a quiet attempt is requested, submit returns as soon as submission is completed. That is, a quiet attempt is performed detached.

  9. Return address
    If the invoker of submit is not to receive return mail (for example, notification of delivery failure) then the next input line (the first, if settings are specified in the exec(S) call), contains an address that should receive the notification. It is not validated. If either the r or the s switch is given, submit will not read a line for the return address. If no return mail should be sent, the return address line should be empty (should consist of a newline only). If the q switch is given, a return address is read from the next line of input and the message is not passed to the remote system. The purpose is to determine who sent the message while viewing the MMDF queue. The S switch indicates to use a Sender: field instead of a Source-Info: field, and also causes conflicting Sender: fields in the submitted header to be elided. This allows submission programs to send mail with a From: field that does not match their identity without having to be privileged.

  10. Returned mail contents
    Normally, a copy of the entire message is sent with a delivery-failure notice. Using the c switch causes a citation, comprising the message header and first three non-blank lines of the body, to be sent. If more than listsize addresses are specified, for a message, citation-only is automatically set. listsize defaults to 12 and can be specified using the MLISTSIZE parameter (see mmdftailor(F)). In addition, no warning message is sent for addresses which take a long time to process (a site dependent value); the final failure notice is always sent if there are addresses that are never fully processed.

  11. Warnings
    Normally MMDF will send a non-delivery warning if a message has been undelivered after a small period (typically 12 to 72 hours, depending on the site). Deliver attempts continue until a timeout period is reached. This is typically after 3 to 10 days, depending on the site.

  12. Delay channel usage
    The delay channel is used to process mail submissions that could not be queued because necessary nameserver information was unavailable and therefore an authoritative decision on the validity of the address was not possible. If the d option is specified, use of the delay channel is prohibited. If the nameserver fails, an error is returned, rather than a conditional OK.

  13. Delay channel indicator
    This option is intended only to be used by the delay channel itself to indicate to submit that the invoking process is the delay channel. This option implies the d option above.

  14. Nameserver timeouts
    By default, MMDF uses a short timeout algorithm. This is suitable for user interface programs which do not want to wait a long time for dead nameservers. The k option allows a different timeout to be set. The value given is the number of seconds to wait for the nameserver lookup to complete.

  15. Submission tracing
    The W option causes submit to print a detailed description of its activities on file descriptor 2. It will indicate, for each addressee, the channel and addresses queued. This can generate a great deal of output if a mailing list is encountered, so it should be used with caution.

  16. Logging file
    The L option allows the specification of an alternate logging file at runtime. The string following the L should be the name of the logfile to be used. It can be terminated by a ``*'' or the end of the arguments. This option is only available to the root or mmdf users.

  17. Logging level
    The V option allows the setting of the logging level at runtime. The string following the V should be one of the valid MMDF logging level strings such as FTR or BST. It can be terminated by a ``*'' or the end of the arguments. This option is only available to the root or mmdf users.

  18. User id
    The U option allows the specification of a uid other than that of the invoking process. This option is used for access control. When U is used, submit will call setuid(S) to change the real uid to the specified id, so this option is only available to root.

Input stream

The following augmented BNF characterizes submit's input (file descriptor zero) format:

*(init-seq '\n' msg-info null) [null]

*{ switches listed above }

[ret-addr] '\n'
[addr-seq '!' '\n']
{ RFC 822 format message }

{ RFC 822 format (return) address }

*{ RFC 822 address }

Address format

Addresses are expected to conform to the ARPANET mail standard known as RFC 822, available from the Network Information Center at SRI International. submit (and MMDF in general) also continues to support RFC 733 style mail for compatibility with earlier mail systems.

In addition to those in RFC 822, the following address delimiters are recognized within the local part of addresses (in order of precedence):

@ % ! .

The ``!'' delimiter is interpreted as ``host!user'' while the others are interpreted as ``user?host''. For example, the address ``a.b!user%c@localhost'' would be queued for ``a.b!user@c''. The address ``a.b!user@localhost'' would be queued for ``user@a.b''. The address ``user.a@localhost'' would be queued for ``user@a''. Note that recognition of the ``.'' delimiter is a site-selectable option.

Also, addresses may be indirectly referenced, through a file specification of the form:

``<filename'' or ``:include:filename''

where the angle-bracket must be the first non-blank character of the specification (to distinguish it from the ``<...>'' usage, above).

Addresses in the file may be separated by commas or newlines.

Example interactions

Phases involve Invocation (Invoke), data sent into submit via its file descriptor zero (To), data returned from submit via its file descriptor one (From), iteration back to the specified phase (Loop), and process exit value (Exit).

  1. Simple, single-message command:

    a. Invoke:
    Parameters, ``-mlrxto,cc*'', indicate that the message is to be sent to recipients' mailboxes, local mail should be sent immediately, return mail goes to the submitter, and addresses are to be extracted from the To: and cc: components.

    b. To:
    The entire message.

    c. From:
    Error messages.

    d. Exit:
    Process return value, in wait(&val), indicating submission status.

  2. Standard, multi-message protocol:

    a. Invoke:
    No parameters.

    b. To:
    Initialization information line. A typical user program might have ``mlrv'', indicating the message is to be sent to mailboxes, local mail sent immediately, return mail goes to the sender, and each address verification is to be reported. A relay program might have ``mlntviVGR.BRL.MIL*,'' with ``mlv'' as above and the other settings indicating that mail for non-local channels is to be sent immediately, the author information is to be trusted, and the ``Received:'' component should cite the mail as being relayed via Internet host VGR.BRL.MIL.

    c. To:
    One address, terminated by a newline ('\n').

    d. From:
    Status character, from mmdf.h, plus human-oriented text plus newline.

    e. Loop:
    Back to (c). Terminate with address line having only an exclamation mark (!), with newline.

    f. To:
    Message text, in Internet RFC 822 format. Multi-line, terminated by null ('\0').

    g. From:
    Status character, text, newline.

    h. Loop:
    Back to (b). Terminate with initialization line having only a null, without newline.


When MMDF is used in conjunction with the DARPA domain nameserver system, configure a ``delay'' channel to allow queuing of addresses that fail verification temporarily due to nameserver failures (unavailability). Two other special channels that can be configured are the ``badusers'' and ``badhosts'' channels. Mail to unknown users or unknown hosts will be queued to these channels if they are configured. The bad channels have no special code associated with them. The channel configuration should reference whatever table and program is necessary to reach a smarter host that can deliver or forward the mail. The channel should have the ``host='' parameter set to this host name. The channel names given above are reserved.

badusers channel

The badusers channel has two confstr parameters, keepdomain and defdomain. Setting keepdomain=1 tells the channel to not strip the original domain from a recipient address. Setting defdomain=some.domain will set an explicit default domain; this should be set to whatever domain name the host that mail is being forwarded expects to see. If only defdomain is given, all messages transferred through the badusers channel will get the given domain. If both are given, recipient addresses that include a domain will keep it, while those that do not include a domain will get the default domain.

Exit values

The following, excerpted from MMDF source, lists the exit values.
/*                      Reply Codes for MMDF

* Based on: "Revised FTP Reply Codes", by Jon Postel & Nancy Neigus Arpanet * RFC 640 / NIC 30843, in the "Arpanet Protocol Handbook", E. Feinler * and J. Postel (eds.), NIC 7104, Network Information Center, SRI * International: Menlo Park, CA. (NTIS AD-A0038901) * * Actual values are different, but scheme is same. Codes must fit into * 8-bits (to pass on exit() calls); fields are packed 2-3-3 and interpreted * as octal numbers. * * Basic format: * * 0yz: positive completion; entire action done * 1yz: positive intermediate; only part done * 2yz: Transient negative completion; may work later * 3yz: Permanent negative completion; you lose forever * * x0z: syntax * x1z: general; doesn't fit any other category * x2z: connections; truly transfer-related * x3z: user/authentication/account * x4x: mail * x5z: file system * * 3-bit z field is unique to the reply. In the following, * the RP_xVAL defines are available for masking to obtain a field. */ /*************** FIELD DEFINITIONS & BASIC VALUES ***************** */

/* Field 1: Basic degree of success (2-bits) */

/* * Octal constant values are used for this field to avoid problems with sign * extension of char constant values with high bit set. */

#define RP_BTYP 0200 /* good vs. bad; on => bad */

#define RP_BVAL 0300 /* basic degree of success */

#define RP_BOK 0000 /* went fine; all done */ #define RP_BPOK 0100 /* only the first part got done */ #define RP_BTNO 0200 /* temporary failure; try later */ #define RP_BNO 0300 /* not now, nor never; you lose */

/* Field 2: Basic domain of discourse (3-bits) */

#define RP_CVAL ' 70') /* basic category (domain of reply) */

#define RP_CSYN ' 00' /* purely a matter of form */ #define RP_CGEN ' 10' /* couldn't find anywhere else for it */ #define RP_CCON ' 20' /* data-transfer-related issue */ #define RP_CUSR ' 30' /* pertaining to the user */ #define RP_CMAI ' 40' /* specific to mail semantics */ #define RP_CFIL ' 50' /* file system */ #define RP_CLIO ' 60' /* local i/o system */

/* Field 3: Specific value for this reply (3-bits) */

#define RP_SVAL ' 07' /* specific value of reply */ /********************* SPECIFIC SUCCESS VALUES ******************** */

/* Complete Success */

#define RP_DONE (RP_BOK | RP_CGEN | ' 00') /* done (e.g., w/transaction) */ #define RP_OK (RP_BOK | RP_CGEN | ' 01') /* general-purpose OK */

#define RP_MOK (RP_BOK | RP_CMAI | ' 00') /* message is accepted (w/text */ #define RP_DOK (RP_BOK | RP_CGEN | ' 03') /* accepted for the delayed submission channel */

/* Partial Success */

#define RP_MAST (RP_BPOK| RP_CGEN | ' 00') /* you are the requestor */ #define RP_SLAV (RP_BPOK| RP_CGEN | ' 01') /* you are the requestee */ #define RP_AOK (RP_BPOK| RP_CMAI | ' 00') /* message address is accepted */ #define RP_HOK (RP_BPOK| RP_CMAI | ' 01') /* host processing completed */ /********************* SPECIFIC FALURE VALUES ********************* */

/* Partial Failure */

#define RP_AGN (RP_BTNO | RP_CGEN | ' 00') /* not now; maybe later */ #define RP_TIME (RP_BTNO | RP_CGEN | ' 01') /* timeout */ #define RP_NOOP (RP_BTNO | RP_CGEN | ' 02') /* no-op; nothing done, this time */ #define RP_EOF (RP_BTNO | RP_CGEN | ' 03') /* encountered an end of file */

#define RP_NET (RP_BTNO | RP_CCON | ' 00') /* channel went bad */ #define RP_BHST (RP_BTNO | RP_CCON | ' 01') /* foreign host screwed up */ #define RP_DHST (RP_BTNO | RP_CCON | ' 02') /* host went away */ #define RP_NIO (RP_BTNO | RP_CCON | ' 04') /* general net i/o problem */ #define RP_NS (RP_BTNO | RP_CCON | ' 05') /* temporary nameserver failure */

#define RP_FIO (RP_BTNO | RP_CFIL | ' 00') /* error reading/writing file */ #define RP_FCRT (RP_BTNO | RP_CFIL | ' 01') /* unable to create file */ #define RP_FOPN (RP_BTNO | RP_CFIL | ' 02') /* unable to open file */ #define RP_LIO (RP_BTNO | RP_CLIO | ' 00') /* general local i/o problem */ #define RP_LOCK (RP_BTNO | RP_CLIO | ' 01') /* resource currently locked */

/* Complete Failure */

#define RP_MECH (RP_BNO | RP_CGEN | ' 00') /* bad mechanism/path; try alternate? */ #define RP_NO (RP_BNO | RP_CGEN | ' 01') /* general-purpose NO */

#define RP_PROT (RP_BNO | RP_CCON | ' 00') /* general prototocol error */

#define RP_RPLY (RP_BNO | RP_CCON | ' 01') /* bad reply code (PERMANENT ERROR) */

#define RP_NDEL (RP_BNO | RP_CMAI | ' 00') /* couldn't deliver */

#define RP_HUH (RP_BNO | RP_CSYN | ' 00') /* couldn't parse the request */ #define RP_NCMD (RP_BNO | RP_CSYN | ' 01') /* no such command defined */ #define RP_PARM (RP_BNO | RP_CSYN | ' 02') /* bad parameter */ #define RP_UCMD (RP_BNO | RP_CSYN | ' 03') /* command not implemented */ #define RP_USER (RP_BNO | RP_CUSR | ' 00') /* unknown user */ #define RP_NAUTH ((RP_BNO | RP_CUSR | ' 01')) /* bad authorisation */ /* SEK this will be used for user checks*/ #define RP_TOOBIG (RP_BNO | RP_CUSR | ' 02') /* User exceeded storage allocation */ #define RP_NONESUCH (RP_BNO | RP_CUSR | ' 03') /* We deny the existence of this mailbox */


struct rp_construct /* for constant reply conditions */ { ret_t rp_cval; char rp_cline[50]; };

#define RP_LINEBUF_MAX 4096

struct rp_bufstruct /* for reading reply strings */ { ret_t rp_val; char rp_line[RP_LINEBUF_MAX]; };

typedef struct rp_bufstruct RP_Buf;

#define rp_conlen(bufnam) (strlen (bufnam.rp_cline) + sizeof (bufnam.rp_cval))


#define rp_gval(val) ((ret_t) (val)) /* get the entire return value */

/* The next three give the field's bits, within the whole value */

#define rp_gbval(val) (rp_gval (val) & RP_BVAL) /* get the basic part of return value */ #define rp_gcval(val) (rp_gval (val) & RP_CVAL) /* get the domain part of value */ #define rp_gsval(val) (rp_gval (val) & RP_SVAL) /* get the specific part of value */

/* The next three give the numeric value withing the field */

#define rp_gbbit(val) ((rp_gval (val) >> 6) & 03) /* get the basic part right-shifted */ #define rp_gcbit(val) ((rp_gval (val) >> 3 ) & 07) /* get the domain part right-shifted */ #define rp_gsbit(val) (rp_gval (val) & 07) /* get the specific part right-shifted */

/* The following works with SIGNED or UNSIGNED chars! */ #define rp_isgood(val) (! rp_isbad(val)) /* is return value positive? */ #define rp_isbad(val) (rp_gval(val) & 0200) /* is return value negative? */


Numerous. Generally under the MMDF login directory.

See also

deliver(ADM), mail(C), mailx(C), mmdf(ADM), mmdftailor(F)

Standards conformance

MMDF is not part of any currently supported standard; it was developed at the University of Delaware and is used with permission.
© 2004 The SCO Group, Inc. All rights reserved.