RFC 976

UUCP mail interchange format standard

๐Ÿ“… published February 1986, from ietf

RFC 976: UUCP Mail Interchange Format Standard ๐Ÿ’Œ

Okay bestie, here's the header rundown ๐ŸŽ€. This is RFC 976, titled "UUCP Mail Interchange Format Standard." Mark R. Horton from Bell Laboratories wrote it, and it's dated February 1986. The header doesn't list a category, and it doesn't say what it obsoletes or updates, so there's nothing to report on either. ๐ŸŒธ

Status of This Memo โœจ

So why does this RFC exist? The ARPA-Internet community needed current info on what different projects were doing and how far along they were, so this RFC was issued for the community's benefit ๐Ÿซถ. Everything in it is accurate as of the publication date, but it can change, and later RFCs will show those changes ๐Ÿฆ‹.

This document defines the standard format for sending mail messages between machines in the UUCP Project ๐Ÿ’…. It does NOT cover how messages get stored on one machine, or the lower level transport mechanisms that move the data from one machine to the next. It's a standard for hosts in the UUCP zone to conform to. Distribution of this memo is unlimited ๐ŸŒˆ.

1. Introduction ๐Ÿงš

This document is meant to define the standard format for sending mail messages between machines in the UUCP Project ๐Ÿ“ฌ. Same as above, it doesn't cover storage on one machine or the lower level transport mechanisms. We assume remote execution of the rmail command (or something equivalent) as the basic UUCP network operation ๐Ÿ’œ.

Okay, the big philosophy: if we invented a brand new standard, we'd end up incompatible with systems that already exist ๐Ÿ’€. The world already has way too many incompatible standards, and that causes ambiguity. For example, a!b@c.d gets parsed as a!(b@c.d) in the old UUCP world, but as (a!b)@c.d in the Internet world ๐Ÿ™ˆ. (Neither standard lets you use parentheses, and adding them would make us compatible with neither. Parentheses would also cause real trouble with the shell and the UUCP transport mechanism.)

So instead, we're adopting the established, well-documented, and extensible standards the ARPA community already has ๐Ÿ‘‘. The UUCP zone is the subset of the community connected by UUCP that chooses to register with the UUCP project, and it's an administrative entity. The actual transport can be whatever the two hosts arrange, whether that's UUCP, SMTP, MMDF, or something else. We adopt RFC-920 (domains) and RFC-822 (mail format) as UUCP zone standards. All mail sent between systems SHOULD conform to those two standards. And if the ARPA community ever changes these standards, we plan to change ours too, so we stay compatible, as long as there's a reasonable amount of time to upgrade software โญ.

This document is an interpretation of RFC-822 and RFC-920 for the UUCP world ๐Ÿ”ฅ. It shows how the envelope should be encoded and how UUCP routing works in an environment full of mixed implementations.

2. Basics ๐Ÿ’–

Messages split into two parts: the envelope and the message ๐Ÿ’Œ. The envelope holds info the mail transport services need. The message holds info that's useful to the sender and receiver, and it's split into the header and the body. Sometimes an intermediate host adds to the message (like a Received line), but unless it's a gateway that has to translate formats, intermediate hosts aren't expected to change the message itself. In the UUCP world, the envelope is made of the "destination addresses" (usually the argument or arguments to the rmail command) and the "source path" (usually one or more lines at the start of the message beginning with either "From " or ">From ", which people call "From_ lines"). The RFC-822 header lines (including "From:" and "To:") are part of the message, and so is the body text ๐ŸŽ€.

UUCP uses short host names like "ucbvax" at and below the transport layer. We call these "6 letter names," because every UUCP implementation considers at least the first 6 letters significant. (Some consider the first 7 or first 14 significant, but we MUST use the lowest common denominator.) UUCP names can be longer than 6 characters, but all such names MUST be unique in their first 6 letters ๐Ÿ™Œ. RFC-920 domain names, like "ucbvax.Berkeley.EDU," are called "domain names," and the two kinds of names are different things ๐Ÿ“. Upper and lower case are usually treated as different in 6 letter names, but they're treated as equivalent in domain names. Names like "ucbvax.UUCP," which are a 6 letter name followed by ".UUCP," used to be domain-style references to a host with that 6 letter name. Those are being phased out in favor of organizational domain names like "ucbvax.Berkeley.EDU" ๐ŸŒท.

2.1 Hybrid Addresses ๐Ÿฆ‹

There are (among others) two major kinds of mailing address syntax in the UUCP world. The a!b!c!user form ("bang paths") is what older UUCP software uses to explicitly route mail to the destination. The user@domain form ("domain") follows RFC-822 ๐ŸŒธ. Most of the time you can look at an address and tell which kind it is. A hybrid address, with a ! to the left of an @ like a!b@c, is the problem child ๐Ÿ˜ญ: it could be read as (a!b)@c.d or as a!(b@c.d). Both readings can be useful. The first interpretation is REQUIRED by RFC-822, and the second is a de-facto standard in UUCP software.

Because hybrid addresses cause so much confusion, we recommend that all transport layer software avoid them at all times ๐Ÿšซ. A pure bang syntax can disambiguate: the first case above gets written c.d!a!b, and the second gets written a!c.d!b. We recommend that all implementations use this "bang domain" syntax unless they're sure what's running on the next machine ๐Ÿ’…. In line with RFC-822 and the AT&T Message Transfer Architecture, we recommend that any host accepting hybrid addresses apply the (a!b)@c.d interpretation ๐Ÿ‘‘.

2.2 Transport ๐Ÿšš

SMTP isn't available to much of the UUCP domain, so we define the method for "remote execution" based transport mechanisms ๐Ÿ’ซ. The command to be "remotely executed" SHOULD read:

rmail user@domain ...

The message goes on the standard input of the command. The "user@domain" argument MUST conform to RFC-920 and RFC-822. You can pass more than one address argument, which saves transmission costs when several recipients get the same message ๐ŸŽ€.

There's also an alternative form that MAY be used:

rmail domain!user

Here, "domain" contains at least one period and no !'s. It's interpreted exactly the same as user@domain, and it's handy for transporting a message across old UUCP hosts without worrying that they'll change the address ๐Ÿงš. The "user" string can contain any characters except "@". That character is forbidden because nobody knows what an intermediate host might do to it ๐Ÿ™ˆ. (It's also RECOMMENDED that the "%" character be avoided, since some hosts treat "%" as a synonym for "@".) To route across hosts that don't understand domains, this works:

rmail a!b!c!domain!user

A "domain" can be told apart from a 6 letter UUCP site name because a domain always has at least one period. For single level domains with no periods, a period SHOULD be added to the end. For example, Mark.Horton@att becomes att.!Mark.Horton. A translator from ! to @ format SHOULD remove a trailing dot at the end of the domain, if there is one. We don't expect this to come up much, except in local networks that use addresses like user@host ๐ŸŒˆ.

A simple implementation can always generate domain!user syntax (instead of user@domain). It's safe to assume gateways are class 3, since class 3 is what gateways are โœจ. (Classes are explained in section 3.5.)

2.3 Batch SMTP ๐Ÿ“ฆ

Standard conforming implementations MAY optionally support a protocol called "Batch SMTP" ๐Ÿ’œ. SMTP (Simple Mail Transfer Protocol) is the ARPA community's standard mail transfer protocol (RFC-821) ๐ŸŒธ. It's also used on BITNET and Mailnet. SMTP was designed to be interactive, but you can batch up a series of commands and send them to a remote machine for batch execution. BITNET does this, and it's a good fit for UUCP ๐Ÿฆ‹. One advantage of BSMTP is that the UNIX shell never gets involved in interpreting the messages, so special characters like spaces and parentheses are fair game in electronic messages ๐Ÿ“. (Those characters are expected to be popular in X.400 addresses ๐Ÿ‘€.)

To support BSMTP on UNIX, a conforming host SHOULD arrange for mail to the user "b-smtp" to be interpreted as Batch SMTP commands. We use "b-smtp" instead of "bsmtp" because "bsmtp" might conflict with a login name ๐Ÿ™ˆ. Lots of mail systems treat a line with a single period as an "end of file" flag. SMTP uses the period as a REQUIRED end of file flag, and we also need to strip off headers. So we put an extra "#" at the start of each BSMTP line ๐Ÿ’…. On a sendmail system, an easy way to do this is to include this alias:

b-smtp: "|egrep '^#' | sed 's/^#//' | /usr/lib/sendmail -bs"

That feeds the commands to an SMTP interpreter. A better solution would check for errors and send an error message back to the sender ๐Ÿ’ก.

Here's an example BSMTP message from seismo.CSS.GOV to cbosgd.ATT.COM. This sample is the file shipped over the UUCP link as input to the command "rmail b-smtp" ๐Ÿ“ฎ. The RFC-822 message sits between the DATA line and the period line โœจ. The envelope info goes in the MAIL FROM and RCPT TO lines, and the name of the sending system is in the HELO line. The actual envelope info (above the # lines) gets ignored, so it doesn't need to be there at all ๐Ÿซถ.

From foo!bar Sun Jan 12 23:59:00 1986 remote from seismo Date:
Tue, 18 Feb 86 13:07:36 EST
From: mark@ucbvax.Berkeley.EDU
Message-Id: <8602181807.AA10228@mark@ucbvax.Berkeley.EDU> To:
b-smtp@cbosgd.ATT.COM

#HELO seismo.CSS.GOV
#MAIL FROM:<mark@ucbvax.Berkeley.EDU>
#RCPT TO:<mark@cbosgd.ATT.COM>
#DATA
#Date: Tue, 18 Feb 86 13:07:36 EST
#From: mark@ucbvax.Berkeley.EDU
#Message-Id: <8602181807.AA10228@mark@ucbvax.Berkeley.EDU> #To:
mark@cbosgd.ATT.COM
#
#This is a sample message.
#.
#QUIT

2.4. Envelope ๐Ÿ“ฎ

okay so the envelope is basically the "who sent this and how did it get here" info ๐Ÿ’Œ The command's standard input should begin with a single line that looks like this:

From domain!user date remote from system

Right after that line comes the RFC-822 format headers and body of the message, the whole vibe ๐ŸŽ€ You might also see extra From_ lines stacked above that line, one for each system the message passes through ๐Ÿงš The "system" fields can even get smooshed into one line with a bunch of !'s in the "user" string. And the ">" character may come before the "From" ๐Ÿ™ˆ Basically this is the envelope info, and it should follow the same conventions that old UUCP mail used. The big difference is when the system names get stacked. Before, you'd get a!b!c!mysys!me, but now it's a!b!c!mysys!domain!me ๐Ÿ’– The domain has to contain at least one period, and "mysys" is often the 6 letter UUCP name for the same system that "domain" names. If the "domain!" part is redundant, it may be left out of the envelope, whether that's in the source path or the destination address โœจ

The receiving system may discard the extra "From_" lines if it folds all that info into a single From_ line ๐Ÿงน It passes along path!domain!user as the "envelope" info, which holds the address of the sender, and it might keep the forwarding date and system in a brand new header line, like Received or Sent-By ๐Ÿฆ‹ Adding Received this way is discouraged, and I'm not gonna lie, the reason is kinda messy ๐Ÿ˜ญ The line looks like it was added by a different system than the one actually adding it, and that other system might have already included a Received line too! Sent-By is similar to Received, but the date doesn't have to be converted into RFC-822 format, and the line isn't claimed to have been added by the system named in it ๐Ÿ’…

If the receiving system passes the message along to another system, it adds a "From_" line to the front. That line gives the same user@domain address for the sender, plus its own name for the system ๐ŸŒธ If the receiving system stores the message in a local mailbox, it is recommended that one single "From_" line gets generated at the front of the message. It should keep the date in the same format, since certain mail reading programs are super sensitive to that format ๐Ÿ™ˆ And it should not use the "remote from system" syntax ๐ŸŽ€

Note: if an intermediate system adds text like "system!" to the front of a "user@domain" address, whether that's in the envelope or the body, that's a violation of this standard and of RFC-822. No cap, don't do it ๐Ÿ’€

2.5. Routing ๐Ÿ—บ๏ธ

To route mail properly, it's sometimes necessary to know what software a destination or intermediate machine is running, or what conventions it follows ๐Ÿง  We tried to keep this info to a minimum, but supporting subdomains might mean different methods are needed in different situations ๐ŸŒˆ So to predict how other hosts will behave, we sort hosts into three classes. Here they are, bestie ๐Ÿ‘‘

Class 1 is old-style UUCP ! routing only. We assume the host understands local user names:

rmail user

and bang paths:

rmail host1!host2!user

But we don't assume anything more about the host ๐Ÿ“ If we have no info about a host, we can treat it as class 1 with no problems, since we make no assumptions about how it'll handle hybrid addresses.

Class 2 is old-style UUCP ! routing plus 4.2BSD style domain parsing ๐Ÿ’œ We assume the capabilities of class 1, plus the ability to understand rmail user@domain, as long as the "domain" is one outside the UUCP zone that the host knows about. Class 2 hosts don't necessarily understand domain!user or have routers. Hosts in non-UUCP RFC-920 domains are considered class 2, even though they may not understand host!user ๐Ÿฆ‹

Class 3 is where all the class 1 and 2 features are present. On top of that, class 3 hosts must be able to route UUCP mail for hosts that aren't immediately adjacent, and they also understand the syntax rmail domain!user as described above โญ All gateways into UUCP must be class 3. Period ๐Ÿ’…

This document describes what class 3 hosts must be able to process. Classes 1 and 2 already exist and will keep existing for a long time ๐Ÿซถ They're basically viewed as "older systems" that may eventually be upgraded to class 3 status. Glow up era ๐ŸŒท

3. Algorithm ๐Ÿงฉ

The algorithm for delivering a message to an address "user@domain" over UUCP links can be summed up like this ๐Ÿ“ฌ

a. If the address is actually of the form @domain1:user@domain2, the "domain" used for the rest should be "domain1" instead of "domain2", and the bang form reads domain1!domain2!user. ๐Ÿ’–

b. Determine d: the most specific part of "domain" that's recognized locally. This part will be a suffix of "domain". You can do this by scanning through a table with entries that go from specific to general, and comparing the entries with "domain" to see if they sit at the tail of "domain". For example, with the address "mark@osgd.cb.att.com", if the local host recognizes "uucp" and "att.com", d would be "att.com". The final entry in the table will be the null string, matching any completely unrecognized domain. ๐Ÿ”

c. Look in the found table entry for g: the name of the "gateway", and for r: a UUCP !-style route to reach g. G is not necessarily directly connected to the local host, but it should be viewed as a gateway into the d domain. (The values of g and r for a given d may be different on different hosts, although g will often be the same.) ๐ŸŒ‰

d. Look at the beginning of r to find the "next hop" host n. N will always be directly connected to the local host. ๐ŸŽฏ

e. Determine, if possible, the class of g and n. ๐Ÿท๏ธ

f. Create an appropriate destination string s to be interpreted by n. (See below.) โœ๏ธ

g. Pass the message off to n with destination information s. ๐Ÿš€

In an environment with other types of networks that don't use UUCP ! parsing, the table will probably contain additional info, like which type of link to use ๐ŸŒ The path info may be replaced in other environments by info specific to the network.

The first entries in the table from part (b) are normally very specific, and they let well known routes get built directly instead of routing through the domain tree ๐Ÿ’Ž The domain tree should be reserved for cases where no better info is available, where traffic is very light, or where the default route is the best option available. If a better route is available, you can put that info in the table โœจ If a host has any significant amount of traffic going to a second host, it is normally expected that the two hosts will set up a direct UUCP link and make an entry in their tables to send mail directly, even if they're in separate domains ๐Ÿซถ Routing tables should be constructed to keep paths short and inexpensive for as much traffic as possible ๐Ÿƒโ€โ™€๏ธ

Here are some hints for building the destination string n (step f above) ๐ŸŽ€ The "envelope recipient" info (the argument(s) to rmail) may be in either domain ! form (host.com!user) or domain @ form (user@host.com), as long as the sending site is sure the next hop is class 3. If the next hop isn't class 3, or the sending site isn't sure, the ! form should be used, if possible, since it's hard to predict what the next hop would do with a hybrid address ๐Ÿ˜ญ

If the gateway is known to be class 3, domain ! form may be used. But if the sending site isn't sure, and the entire destination string was matched in the lookup (rather than some parent domain), the 6 letter ! form should be used: r!user, for example dumbhost!host!user ๐Ÿงƒ If the gateway appears to actually be a gateway for a subdomain, e.g. because a parent domain was matched (like the address user@host.gateway.com, where host.gateway.com wasn't found but gateway.com was), it can be assumed to be at class 3. This allows routes like dumbhost!domain!host.domain.com!user to be used with a reasonable degree of safety ๐Ÿ›ก๏ธ If a direct link exists to the destination host, the user@domain syntax or the domain!user syntax may be used.

All hosts conforming to this standard are class 3, and all subdomain gateways must be class 3 hosts ๐Ÿ’œ

4. Example ๐ŸŽฌ

Okay storytime! Suppose host A.D.COM sends mail to host C.D.COM. Let's say the 6 letter names for these hosts are aname and dname, and the intermediate host to route through is named bname ๐Ÿฆ‹

The user on A types:

mail user@c.d.com

The user interface creates a file such as:

Date:  9 Jan 1985   8:39 EST
From: myname@A.D.COM (My Name)
Subject: sample message
To: user@c.d.com

This is a sample message

and passes it to the transport mechanism with a command such as:

sendmail user@c.d.com < file

The transport mechanism looks up a route to c.d.com. It doesn't find c.d.com in its database, so it looks up d.com and finds that the path is bname!dname!%s, and that c.d.com is a class 3 host ๐Ÿ‘€ Plugging in c.d.com!user, it gets the path bname!dname!c.d.com!user. (If it had found c.d.com with path bname!cname!%s, it would have left the domain out of the resulting path: bname!cname!user, since it's not sure whether the destination host is class 1, 2, or 3.) ๐Ÿง 

It prepends a From_ line and passes it to uux:

uux - bname!rmail dname!c.d.com!user < file2

where file2 contains:

From A.D.COM!user Wed Jan  9 12:43:35 1985 remote from aname Date:
9 Jan 1985   8:39 EST
From: myname@A.D.COM (My Name)
Subject: sample message
To: user@c.d.com

This is a sample message

(Note the blank line at the end of the message. At least one blank line is required. ๐Ÿซถ)

This results in the command:

rmail dname!c.d.com!user

running on B. B prepends its own from line and passes the mail along:

uux - dname!rmail c.d.com!user < file3

where file3 contains:

From nuucp Wed Jan  9 12:43:35 1985 remote from bname >From
A.D.COM!user Wed Jan  9 11:21:48 1985 remote from aname Date:  9
Jan 1985   8:39 EST
From: myname@A.D.COM (My Name)
Subject: sample message
To: user@c.d.com

This is a sample message

The command:

rmail c.d.com!user

is run on C, which stacks the From_ lines into:

From bname!aname!A.D.COM!user Wed Jan  9 12:43:35 1985 Date:  9
Jan 1985   8:39 EST
From: myname@A.D.COM (My Name)
Subject: sample message
To: user@c.d.com

This is a sample message

and stores the message locally, probably in this same format. ๐ŸŽ‰โœจ

5. Summary โœจ

okay bestie, here's the whole vibe check in one place ๐Ÿ’… hosts that follow this standard should accept ALL of these forms:

rmail localuser               (no !%@ in user)
rmail hosta!hostb!user        (no !%@ in user)
rmail user@domain             (only . in domain)
rmail domain!user             (at least 1 . in domain)
rmail domain.!user            (in case domain has no dots)

The envelope part (the From_ lines) should conform to existing conventions, using ! routing ๐Ÿฆ‹ The heading part (the Word: lines, like Date:, From:, To:, and Subject:) must conform to RFC-822. All header addresses must be in the @ form. The originating site should make sure the addresses conform to RFC-822, because nobody requires forwarding sites or gateways to transform addresses into legal RFC-822 format ๐Ÿ™ˆ Those forwarding sites and gateways should NOT, however, turn a legal RFC-822 address like user@domain into an illegal one like gateway!user@domain, even if they're forwarding to a class 1 UUCP host. not me doing a whole plot twist on a perfectly good address ๐Ÿ’€


6. References โœจ

[1] Postel, J., "Simple Mail Transfer Protocol", RFC-821, USC/Information Sciences Institute, August, 1982.

[2] Crocker, D., "Standard for the Format of ARPA Internet Text Messages", RFC-822, Department of Electrical Engineering, University of Delaware, August, 1982.

[3] Postel, J., and J. K. Reynolds, "Domain Requirements", RFC-920, USC/Information Sciences Institute, October, 1984. ๐ŸŒˆ

๐Ÿ“ฆ where this page comes from