RFC 1056

PCMAIL: A distributed mail system for personal computers

๐Ÿ“… published June 1988, from ietf

PCMAIL: A Distributed Mail System for Personal Computers ๐Ÿ’–

Okay bestie, so this is RFC 1056 ๐ŸŽ€, PCMAIL: A Distributed Mail System for Personal Computers. It comes from the Network Working Group, it was written by M. Lambert over at MIT, and it's dated June 1988 ๐Ÿ“…. It obsoletes RFC-993 (so that one's been replaced โœจ), and the header doesn't list anything it updates.

Table of Contents ๐Ÿ—‚๏ธ

   1. Status of this Document                                      1
   2. Introduction                                                 2
   3. Repository architecture                                      4
        3.1. Management of user mail state                         5
        3.2. Repository-to-RFC-822 name translation                7
   4. Communication between repository and client: DMSP            8
        4.1. DMSP commands                                         8
        4.2. DMSP responses                                        8
        4.3. DMSP sessions                                        11
        4.4. General operations                                   11
        4.5. User operations                                      12
        4.6. Client operations                                    13
        4.7. Mailbox operations                                   14
        4.8. Address operations                                   15
        4.9. Subscription operations                              15
        4.10. Message operations                                  16
   5. Client Architecture                                         18
        5.1. Multiple clients                                     18
        5.2. Synchronization                                      18
        5.3. Batch operation versus interactive operation         20
        5.4. Message summaries                                    20
   6. Typical interactive-style client-repository interaction     21
   7. A current Pcmail implementation                             25
        7.1. IBM PC client code                                   25
        7.2. UNIX client code                                     26
        7.3. Repository code                                      26
   8. Conclusions                                                 26
   I. DMSP Protocol Specification                                 28
   II. Operations by name                                         37
   III. Responses by number                                       38

1. Status of this Memo ๐Ÿ“œ

Okay so this RFC is basically a chat about the Pcmail workstation-based distributed mail system ๐Ÿ–ฅ๏ธ. It's identical to the discussion in RFC-993, except this time a new, much simpler mail transport protocol gets described ๐Ÿ’…. That new transport protocol is the result of continued research into ease of protocol implementation and use issues ๐Ÿง . And distribution of this memo is unlimited โœจ.


2. Introduction ๐ŸŒˆ

Pcmail is a distributed mail system that gives mail service to an arbitrary number of users ๐Ÿ’Œ, and each user owns one or more workstations ๐Ÿ–ฅ๏ธ. The whole point is giving super flexible mail service to a wide variety of workstations ๐Ÿซถ. That ranges from small, resource-limited machines like IBM PCs ๐Ÿซ  all the way up to resource-rich machines (where "resources" are mainly processor speed and disk space) like Suns or Microvaxes ๐Ÿ‘‘. Pcmail tries to give limited service to the resource-limited workstations while still giving full service to the resource-rich ones ๐Ÿ’ช. It's meant to work well with machines that are only infrequently connected to a network, and also with machines that are permanently connected ๐ŸŒ. It's also designed to give diskless workstations full mail service ๐Ÿ™Œ.

The system has two halves ๐ŸŒ—. The first is a single entity called the "repository". The repository is a storage center for incoming mail ๐Ÿ“ฌ. Mail for a Pcmail user can arrive externally from the Internet or internally from other repository users ๐ŸŒ. The repository also keeps a stable copy of each user's mail state (from here on called the user's "global mail state") ๐Ÿ”’. So the repository is typically a computer with a large amount of disk storage ๐Ÿ’พ.

The second half of Pcmail is one or more "clients" ๐Ÿง‘โ€๐Ÿ’ป. Each Pcmail user may have an arbitrary number of clients, typically single-user workstations โœจ. The clients give the user a friendly way to access their global mail state over a network ๐ŸŽ€. To make the interaction between the repository and a user's clients more efficient, each client keeps a local copy of its user's global mail state, called the "local mail state" ๐Ÿ“‹. It's assumed that clients, possibly being small personal computers, may not always have access to a network, and therefore not to the global mail state in the repository ๐Ÿ“ด. This means the local and global mail states may not be identical all the time, so synchronization between them is necessary ๐Ÿ”„.

Clients talk to the repository via the Distributed Mail System Protocol (DMSP), and the specification for that protocol lives in appendix A ๐Ÿ“œ. So the repository is a DMSP server in addition to being a mail end-site and storage facility ๐Ÿงš. DMSP gives you a complete set of mail manipulation operations ("send a message", "delete a message", "print a message", etc.) ๐Ÿ’…. It also has special operations that allow easy synchronization between a user's global mail state and their clients' local mail states ๐Ÿซถ. Particular attention was paid to the way DMSP operations act on a user's mail state ๐Ÿ‘€. All DMSP operations are failure-atomic (that is, they are guaranteed either to succeed completely, or leave the user's mail state unchanged) ๐Ÿ›ก๏ธ. A client can be abruptly disconnected from the repository without leaving inconsistent or damaged mail states ๐Ÿ˜Œ.

Pcmail's design has been shaped by the characteristics of currently available workstations ๐Ÿ–ฅ๏ธ. Some workstations are fairly portable, and can be packed up and moved in the back seat of an automobile ๐Ÿš—. A few are truly portable (about the size of a briefcase) and battery-powered ๐Ÿ”‹. Some workstations have constant access to a high-speed local-area network, so Pcmail should allow for "on-line" mail delivery for those machines ๐Ÿš€. At the same time it should provide "batch" mail delivery for other workstations that are not always connected to a network ๐Ÿ“ฆ. Portable and semi-portable workstations tend to be resource-poor ๐Ÿฅบ. A typical IBM PC has a small amount of main memory (typically less than one megabyte) and little in the way of mass storage, like floppy-disk drives that can access perhaps 360 kilobytes of data ๐Ÿ’ฟ. Pcmail must be able to give machines like this adequate mail service without hampering its performance on more resource-rich workstations ๐Ÿ’ช. Finally, all workstations share some common characteristics that Pcmail should take advantage of ๐ŸŽฏ. For instance, workstations are fairly inexpensive compared to the time-shared systems most people use for mail service ๐Ÿ’ธ. That means people may own more than one workstation, like a Microvax in the office and an IBM PC at home ๐Ÿ .

Pcmail's design reflects the differing characteristics of the various workstations ๐Ÿงฉ. Since one person can own several workstations, Pcmail lets users have multiple access points to their mail state ๐Ÿฆ‹. Each Pcmail user can have several client workstations, and each can access the user's mail by communicating with the repository over a network ๐ŸŒธ. The clients all keep local copies of the user's global mail state, and they synchronize the local and global states using DMSP ๐Ÿ”.

It's also possible that some workstations will only infrequently be connected to a network, and so will only be able to communicate with the repository now and then ๐Ÿซ . The Pcmail design therefore allows two modes of communication between repository and client โœจ. "Interactive mode" is used when the client is always connected to the network โšก. Any changes to the client's local mail state are immediately made to the repository's global mail state too, and any incoming mail is immediately sent from repository to client ๐Ÿ“จ. "Batch mode" is used by clients that have infrequent access to the repository ๐Ÿ—ƒ๏ธ. Users manipulate the client's local mail state and the changes get queued locally ๐Ÿ“ฅ. When the client is next connected to the repository, the changes are executed and the client's local mail state is synchronized with the repository's global mail state โœ….

Finally, the Pcmail design minimizes the effect of using a resource-poor workstation as a client ๐Ÿงš. Mail messages are split into two parts: a "descriptor" and a "body" ๐Ÿ“. The descriptor is a capsule message summary whose length (typically about 100 bytes) is independent of the actual message length ๐Ÿ“. The body is the actual message text, including an RFC-822 standard message header ๐Ÿ“ง. While the client may not have enough storage to hold a complete set of messages, it can usually hold a complete set of descriptors, which gives the user at least a summary of their mail state ๐Ÿ‘€. For clients with extremely limited resources, Pcmail allows storing partial sets of descriptors ๐Ÿ™ˆ. Although this means the user doesn't have a complete local mail state, they can at least look at summaries of some messages ๐Ÿ’•. When a client can't immediately store message bodies, it can always pull them over from the repository as storage becomes available ๐Ÿ’–.

The remainder of this document is broken up into sections discussing the following:

  • The repository architecture
  • DMSP, its operations, and motivation for its design
  • The client architecture
  • A typical DMSP session between the repository and a client
  • The current Pcmail implementation
  • Appendices describing the DMSP protocol in detail

3. Repository architecture ๐Ÿ 

A typical machine running repository code has a relatively powerful processor and a large amount of disk storage ๐Ÿ’ช. It also has to be a permanent network site, and there are two reasons for that ๐ŸŒ. First, clients communicate with the repository over a network and rely on the repository being available at any time ๐Ÿ“ถ. Second, people sending mail to repository users rely on the repository being available to receive mail at any time ๐Ÿ“ฌ.

The repository has several tasks ๐Ÿ“‹. First, and most importantly, it has to efficiently manage a potentially large number of users and their mail states ๐Ÿ‘‘. Mail has to be stored reliably, in a way that makes it easy for multiple clients to access the global mail state and synchronize their local mail states with the global state ๐Ÿซถ. Since a large category of electronic mail is represented by bulletin boards (bboards), the repository should efficiently manage bboard mail ๐Ÿ“Œ. It should use a minimum of storage to store bboard messages in a way that still lets any user subscribing to the bboard read the mail ๐Ÿง . Second, the repository has to be able to communicate efficiently with its clients. The protocol used between repository and client must be reliable, and it must provide operations that (1) allow typical mail manipulation, and (2) support Pcmail's distributed nature by allowing efficient synchronization between local and global mail states ๐Ÿ”ฅ. Third, the repository has to be able to process mail from sources outside the repository's own user community (a primary outside source is the Internet) ๐ŸŒ. Internet mail arrives with a NIC RFC-822 standard message header, and the recipient names in the message must be properly translated from the RFC-822 namespace into the repository's namespace ๐Ÿงš.

3.1. Management of user mail state ๐Ÿ’–

Okay so Pcmail splits the whole world into a community of users ๐ŸŒธ. Every user gets a user object, and it has a unique name, a password (the user's clients use it to authenticate themselves to the repository before they touch a global mail state ๐Ÿ”), a list of "client objects" for the clients that belong to that user, a list of "subscription objects", and a list of "mailbox objects" ๐Ÿ“ฌ.

A client object has a unique name and a status ๐Ÿฆ‹. A user gets one client object for every client they own, and a client can't communicate with the repository unless it has a matching client object in a user's client list. So client objects are basically the repository's VIP list of valid clients ๐Ÿ‘‘. They also help the repository keep local and global mail state in sync. The repository attaches an "update list" to every client, listing the message state changes that have happened since that client last synced ๐Ÿ”„.

A client's status is either "active" or "inactive" ๐Ÿ’…. The repository counts a client as inactive if it hasn't connected within a set time period (one week, in the current repository implementation). When a previously-inactive client finally connects, the repository tells it that it's been gone for a while and should "reset" itself ๐Ÿงน. Resetting puts every message in every mailbox onto the client's update list, so the client gets a fresh global mail state the next time it synchronizes (more on that below ๐Ÿ‘€). The reasoning is that enough global state changes happen in a week that an ordinary local state-global state synchronization would take the client too much time ๐Ÿ˜ญ.

Messages live in mailboxes ๐Ÿ“ฆ. Users can have any number of mailboxes, and they both store and categorize messages. A mailbox object names the mailbox and describes what's inside. Each mailbox has a unique name, and its contents are described by three numbers: the total number of messages, the total number of unseen messages (messages that have never been seen by the user through any client), and the mailbox's next available message unique identifier (UID). That summary lives in the mailbox object so clients can peek at a mailbox without reading every message in it ๐Ÿซฃ.

Some mailboxes are special because other users are allowed to read the messages in them ๐ŸŒˆ. These are called "bulletin board mailboxes" or "bboard mailboxes", and the repository uses them to store bboard mail. Bboard mailboxes differ from ordinary ones in these ways:

  • Their names are unique across the entire repository. For instance, only one bboard mailbox named sf-lovers may exist in the entire repository community. That doesn't stop other users from having an ordinary mailbox named sf-lovers.
  • Subscribers are granted read-only access to the messages in the bboard mailbox. The bboard mailbox's owner (typically the system manager) has read/update/delete access to the mailbox.

Bboard subscribers keep track of the messages they've looked at with a subscription object ๐Ÿ”–. It holds the name of the bboard, its owner (the user who owns the bboard mailbox where all the messages are stored), and the UID of the first message the subscriber hasn't seen yet.

Users gain read-only access to a bboard by creating a subscription to it, and they lose that access when they delete the subscription ๐Ÿšช. A list of all bboard mailboxes available for subscription can be sent to the user on demand ๐Ÿ“‹.

Each mailbox can hold any number of message objects ๐Ÿ’Œ. Each message is split into two parts: a "descriptor", which summarizes useful information about the message, and a "body", which is the message text itself, including its NIC RFC-822 message header ๐Ÿงฉ. Every message is assigned a monotonically increasing UID based on its mailbox's next available UID. Each mailbox has its own set of UIDs, and those, together with the mailbox name and user name, uniquely identify the message within the repository ๐Ÿ†”.

A descriptor holds the following info: the message UID, the message size in bytes and lines, four "useful" message header fields (the date:, to:, from:, and subject: fields), and sixteen flags ๐Ÿšฉ. These flags are numbered 0 through 15. Eight of them have well-known definitions and are reserved for the repository's use. The eight repository-defined flags mark:

  • (#0) whether the message has been deleted
  • (#1) whether it has been seen
  • (#2) whether it has been forwarded to the user
  • (#3) whether it has been forwarded by the user
  • (#4) whether it has been filed (written to a text file outside the repository)
  • (#5) whether it has been printed (locally or remotely)
  • (#6) whether it has been replied to
  • (#7) whether it has been copied to another mailbox

The remaining eight flags are available for user use ๐ŸŒŸ. Descriptors are the efficient shortcut here: clients can grab message info without wasting time pulling the entire message down from the repository โšก.

3.2. Repository-to-RFC-822 name translation ๐Ÿ”

"Address objects" are how the repository translates the RFC-822-style mail addresses in Internet messages into repository names ๐ŸŒ. The repository has its own namespace for identifying messages. Any message is uniquely identified by the triple (user-name, mailbox-name, message-UID), and any mailbox is uniquely identified by the pair (user-name, mailbox-name). To translate between RFC-822-style addresses and repository names, the repository keeps a list of address objects. Each address object is an association between an RFC-822-style address and a (user-name, mailbox-name) pair. When mail arrives from the Internet, the repository can use that address object list to translate the recipients into (user-name, mailbox-name) pairs and route the message correctly ๐Ÿ“ฎ.


4. Communication between repository and client: DMSP โœจ

The Distributed Mail System Protocol (DMSP) defines and manipulates the objects mentioned in the previous section ๐Ÿค. It was designed to work with Pcmail's single repository/multiple-client model of the world. Besides providing typical mail manipulation functions, DMSP also makes it easy to synchronize global and local mail states ๐Ÿ’œ.

DMSP has been completely re-specified in this version of Pcmail ๐ŸŽ€. It used to be implemented on top of the USP remote-procedure-call protocol. But USP is not fully unofficially specified (let alone officially specified) anywhere, so implementing USP was hard for sites wanting to run Pcmail on different systems. So the team decided to completely redesign DMSP. It's now a very simple request/response protocol, similar to SMTP or NNTP, that runs directly on a reliable bidirectional byte-stream such as TCP ๐Ÿงƒ. The TCP contact port for DMSP has been designated 158. Requests and responses consist of ASCII characters. On octet-based transmission streams, each character is transmitted right-justified in an octet with the high-order bit cleared to zero ๐Ÿ”ข.

4.1. DMSP commands ๐Ÿ’…

DMSP operations consist of an operation name, followed by zero or more tab or space characters, followed by zero or more arguments. Each argument is separated from the operation name and other arguments by one or more space or tab characters ๐Ÿงต. All operation requests, as well as all responses, must be terminated with a carriage-return plus line-feed (CR-LF) pair ๐Ÿ. All operation names and arguments must be taken from the set of alphanumeric characters plus the characters dash (-), underscore (_), and period (.) ๐Ÿ”ค.

DMSP operation names are case-insensitive, so they can come in any combo of upper and lower case ๐Ÿ™ƒ. DMSP arguments are case-insensitive but case-preserving. So a mailbox named MarkL can be referred to with an operation argument of markl, but it will always be stored, and sent back in repository responses, as MarkL. Furthermore, any attempt to create a new mailbox MaRkL will not be permitted ๐Ÿšซ.

Each operation argument may contain no more than 64 characters ๐Ÿ“. No single request or response line may contain more than 512 characters, including all white space and the terminating CR-LF ๐Ÿซถ.

4.2. DMSP responses ๐Ÿ’–

Every DMSP operation gets a response ๐Ÿ’…. That response can be followed by a list of zero or more lines of CR-LF-terminated text, and the list ends with a single period (".") plus a CR-LF. Every response starts with a three-digit reply code, and whatever text comes after the code can be in any format. The code alone tells you whether the operation worked, whether it flopped, or whether more text is coming after the response line. Anything after the code is just for info, so it doesn't have to follow any particular format ๐ŸŒธ.

The first digit tells you if the operation succeeded or failed, and if it succeeded, whether more text should be presented to the repository. These definitions are NNTP-style:

1XX             Informative message


2XX             Operation completed successfully


3XX             Operation completed successfully, present
                remainder of text and terminate with a single
                period plus CR-LF pair.


4XX             Operation was performed and failed for some
                reason.


5XX             Operation could not be performed because of a
                protocol syntax error of some sort.

The second digit tells you what type of object the response is about ๐Ÿงš:

X0X             Miscellaneous


X1X             User operation


X2X             Client operation


X3X             Mailbox operation
X4X             Subscription operation


X5X             Message operation


X6X             Address operation

In an error response, the final digit can describe the type of error that happened. Otherwise, it's just a unique number. Numbers 0 through 3 only mean something in 4XX (error) responses. In every other response, the numbers 0-9 just tell apart responses about the same type of object in different situations ๐ŸŽ€.

4X0             Operation failed because object exists


4X1             Operation failed because object does not exist


4X2             Operation failed because of an internal error


4X3             Operation failed because of an argument syntax
                error

Each operation generates one of a set of responses, all detailed in the protocol specification appendix ๐Ÿ“š.

List termination is decided by one well-known character sequence (CR-LF, period, CR-LF) and nothing else ๐Ÿฆ‹. Application data could accidentally contain that exact sequence, so the transmitting protocol module has to change the application data so it has no termination sequences in it. The receiving module then has to undo that change before handing the data to the application on the other end. ngl that's a clever little trick ๐Ÿ™ˆ.

Here's how the transmitting module changes the data: if a line of application data begins with a period, that period gets duplicated. Since the termination sequence is a single period, accidental termination is now prevented โœจ.

The receiving protocol checks all incoming data lines for a leading period. A single period is a list terminator. A period followed by other text gets removed before the data goes to the receiving application ๐Ÿ’œ.


4.3. DMSP sessions ๐ŸŒธ

Okay, here's how a DMSP session goes. A client starts by opening a connection to the repository's machine. Then it authenticates both itself and its user to the repository with a "login" operation. If the authentication works, the user can do an arbitrary number of DMSP operations, and then the session ends with a "logout" operation. At that point, the repository closes the connection ๐Ÿซถ.

Because DMSP can manipulate a pair of mail states (local and global) at once, it is extremely important that all DMSP operations are failure-atomic ๐Ÿ˜ญ. Failure of any DMSP operation has to leave both states in a consistent, known state. For this reason, a DMSP operation counts as failed unless the operation initiator receives an explicit acknowledgement. That acknowledgement is a response code, possibly followed by information, as described above ๐Ÿ’….

Next up is a general discussion of all the DMSP operations. They're grouped by type: general operations, user operations, client operations, mailbox operations, address operations, subscription operations, and message operations. The detailed operation specs live at the end of this document ๐ŸŒˆ.


4.4. General operations ๐ŸŽ€

The first group does general stuff that doesn't belong to any one kind of object. DMSP has three general operations, and they provide the following services ๐Ÿ‘‘.

To stop protocol version skew between clients and the repository, DMSP gives you a "send-version" operation. The client supplies its DMSP version number as an argument. The operation succeeds if that version number matches the repository's DMSP version number, and it fails if they don't match. Version numbers are natural numbers like "100", "101", or "200". The "send-version" operation should be the first thing a client sends to the repository, since no other operation may work correctly if the client and repository are on different versions of DMSP ๐Ÿ”ฅ.

Users can send mail to other users with the "send-message" operation. The message must have an Internet-style header, as defined by NIC RFC-822. The repository takes the message and distributes it to the mailboxes listed in the message header's destination fields. If one or more of those mailboxes lives outside the repository's user community, the repository is responsible for handing the message to a local SMTP server. The repository generates the message envelope from the message contents, since some clients may find envelope-generation stuff like address verification and syntax checking pretty difficult ๐Ÿงš.

A success acknowledgement only gets sent from the repository if (1) the entire message was successfully transmitted from client to repository, and (2) the message header was properly formatted. Once the repository has successfully received the message from the client, any later errors in queueing or delivery must be reported to the user via return mail ๐Ÿ’Œ.

The last general operation is "help". The repository responds to "help" by printing an acknowledgement followed by a list of supported commands, ending with a period plus CR-LF. The info is meant for display and can be in any format, as long as each line of text the repository returns is CR-LF-terminated โœจ.


4.5. User operations ๐ŸŒˆ

The next bunch of operations manipulates user objects. The big ones are "login" and "logout" ๐Ÿ’–. A client must perform a login operation before it can access a user's mail state.

A DMSP login operation takes five arguments:

  1. the user's name
  2. the user's password
  3. the name of the client performing the login
  4. a flag set to 1 if the repository should create a client object for the client if one does not exist (0 else)
  5. a flag set to 1 if the client wishes to operate in "batch mode" and 0 if the client wishes to operate in "interactive" mode

That last flag lets the repository tune its internal parameters for whichever mode you're using ๐Ÿ“.

The repository can make one of three responses ๐Ÿฆ‹. First, a success response, which means authentication worked. Second, one of several failure responses, which means authentication failed. Third, a special response saying authentication worked, but the client hasn't been used in over a week. That last one is a hint that the client should consider erasing its local mail state and pulling down a complete copy of the repository's mail state. The reasoning is that so many mail state changes have happened in a week that a normal synchronization would be inefficient ๐Ÿ™ˆ.

When a client finishes a session, it performs a logout operation. That lets the repository do any necessary cleanup before it closes the network connection ๐ŸŒธ.

A user can change his password with the "set-password" operation ๐Ÿ”. It works pretty much like the UNIX change-password operation. It takes two arguments: the user's current password and a desired new password. If the current password given matches the user's current password, the user's password gets changed to the new one.

Heads up: passwords are sent in clear text, because encryption can be really hard to do on some resource-poor clients. The original document is clear that this is not an acceptable long-term solution, and it welcomes alternatives ๐Ÿ˜ญ.

4.6. Client operations ๐Ÿฆ‹

DMSP has four operations for manipulating client objects ๐Ÿ’œ.

The first is "list-clients". It tells the repository to send the user's client list to the requesting client. The list is a series of lines, one per client. Each line has the client's name, then whitespace, then a status string. The status is either "inactive" or "active". As with all text responses, the list ends with a period plus CR-LF ๐Ÿ“‹.

The "create-client" operation lets a user add a client object to his list of client objects ๐Ÿ’…. Logging in already does this via the "create-this- client?" flag, but the create-client operation is handy for making a bunch of new client objects while you're already logged in through an existing client. The create-client operation takes one argument: the name of the client to create.

The "delete-client" operation removes an existing client object from a user's client list. The client being removed can't be in use by anyone at that time. Delete-client also takes one argument: the name of the client to delete ๐Ÿ—‘๏ธ.

The last client operation is "reset-client" ๐Ÿ”„. It makes the repository place all of the messages in all mailboxes onto the named client's update list. The next time that client synchronizes with the repository, it ends up receiving a list of all descriptors when it asks for a list of changed message descriptors for a particular mailbox. This is useful for two reasons. First, a client's local mail state can easily get lost or damaged, especially if it's stored on a floppy disk ๐Ÿ’พ. Second, if the repository has marked a client as inactive, reset-client gives you a fast way to resynchronize, assuming there are so many differences between the local and global mail states that a normal synchronization would take way too long โญ.

4.7. Mailbox operations ๐Ÿ“ฌโœจ

okay bestie, DMSP has seven operations that manipulate mailbox objects ๐Ÿ’…

First up is list-mailboxes. The repository sends the requesting client info on each mailbox, one line per mailbox, and ends the list with a period plus CR-LF ๐ŸŽ€. Each line has, in this order and separated by whitespace: the mailbox name, the "next available UID", the total message count, and the unseen message count. This is super useful for syncing local and global mail state, because the client can compare the user's global mailbox list against its own local one ๐Ÿ”„. It also gives a quick summary of what's in each mailbox without actually sending the contents ๐Ÿงš

create-mailbox tells the repository to make a brand new mailbox and attach it to the user's list of mailboxes ๐ŸŒธ It takes one argument: the name of the mailbox to create.

delete-mailbox removes a mailbox from the user's list ๐Ÿ’€ All the messages inside get deleted too and permanently removed from the system, so it's gone for good. Any address objects that bind the mailbox name to RFC-822-style mailbox addresses are removed as well. The argument is the name of the mailbox to delete.

create-bboard-mailbox lets a user create a bboard mailbox ๐ŸŒˆ The name you pass in must be unique across the entire repository user community. Once it exists, other users can subscribe to it, using subscription objects to keep track of which messages they've read on which bboard mailboxes ๐Ÿ‘‘

delete-bboard-mailbox lets a bboard's owner delete their bboard mailbox ๐Ÿฅ€ Subscribers who try to read from it after it's been deleted get told that the bboard no longer exists ๐Ÿ˜ญ The argument is, again, the name of the bboard mailbox to delete.

reset-mailbox makes the repository put all the messages in a named mailbox onto the current client's update list ๐Ÿ” The next time the client asks for a list of changed message descriptors for this mailbox, it gets a list of all message descriptors in the mailbox. It's basically a more specific version of reset-client, which lets the client pull over a complete copy of the user's global mail state. Its main use is for mailboxes whose contents got accidentally destroyed locally ๐Ÿ™ˆ

Finally, DMSP has the expunge-mailbox operation ๐Ÿฆ‹ Any message can be deleted and "undeleted" whenever, since that just changes the value of a flag attached to the message. Deletions only become permanent when you run expunge-mailbox. It makes the repository look through a named mailbox and remove from the system any messages marked "deleted". The argument is the name of the mailbox to expunge.


4.8. Address operations ๐Ÿ’Œ

DMSP gives you three operations for manipulating address objects ๐Ÿก

First, list-address returns a list of address objects associated with a particular mailbox. Each address goes on its own line ending with CR-LF, and the whole list ends with a period plus CR-LF ๐Ÿ“‹

create-address adds a new address object that associates a (user-name, mailbox-name) pair with a given RFC-822-style mailbox address ๐ŸŽ€ It takes two arguments: the mailbox name and the address name.

Last but not least, delete-address destroys the address object that binds the given RFC-822-style mail address to the given (user-name, mailbox-name) pair ๐Ÿ—‘๏ธ The arguments are the address to delete and the mailbox it belongs to.


4.9. Subscription operations ๐Ÿ””

DMSP provides five subscription operations, and they're giving main character energy ๐Ÿ‘‘

The first one, list-subscriptions, gives the user a list of the bboards they're currently subscribed to. You get one line per subscription, and each entry contains the following info, in order:

  • The bulletin board's name
  • The UID of the first message the subscriber has not yet seen
  • The number of messages the subscriber has not yet seen
  • The highest message UID in the bulletin board

list-available-subscriptions gives the user a list of every bboard they can subscribe to ๐Ÿงพ It's bboard names, one per line, ending with a period plus CR-LF.

create-subscription adds a subscription to the user's list of subscriptions ๐Ÿ’– It takes one argument: the name of the bboard to subscribe to.

delete-subscription removes a subscription from the list and takes the name of the subscription to remove as its argument ๐Ÿ™… Note that this does not delete the associated bboard mailbox (obviously only the bboard's owner can do that). It just removes the user from the list of the bboard's subscribers.

Finally, DMSP lets the user tell the repository which messages in a bboard they've seen โœ… Every subscription object contains the UID of the first message the user has not yet seen. The reset-subscription operation updates that number, making sure the user sees a given bboard message only once. Its arguments are the name of the subscription and the new UID value.


4.10. Message operations ๐Ÿ’œ

The most commonly manipulated Pcmail objects are messages, so DMSP has special message operations for efficient synchronization, plus a set of operations for standard message-manipulation functions โœจ

First, fetch-descriptors. A user can request a series of descriptors with this operation ๐Ÿง The series is identified by a pair of message UIDs, which are the lower and upper bounds of the list. UIDs are defined to be monotonically increasing numbers, so a pair of UIDs is enough to completely identify the series of descriptors. If the lower bound UID doesn't exist, the repository starts the series with the first message whose UID is greater than the lower bound. Similarly, if the upper bound doesn't exist, the repository ends the series with the last message whose UID is less than the upper bound. If certain UIDs within the series no longer exist, the repository obviously doesn't send them. The repository returns the descriptors in a list with the following format:

If a descriptor has been expunged, the repository transmits two consecutive lines of info. The first line has the word expunged, and the next line has the message UID ๐Ÿ’€ expunged notifications only get transmitted in response to a fetch-changed-descriptors command. They're a heads-up to the client that someone else has expunged the mailbox, so the client should remove its local copy of that expunged message.

If a descriptor has not been expunged, it's presented as six consecutive lines of info ๐Ÿ“ The first line is the word descriptor. The second line has the message UID, the flag states (see examples following), the message length in bytes, and the message length in lines. After that come four lines containing, in order, the message from: field, to: field, date: field, and subject: field. The entire list of descriptors is terminated by a period plus CR-LF. Individual descriptors aren't specially terminated, because the first line of each list entry (expunged or descriptor) determines the exact length of that entry, which is either two lines or six lines.

Next, fetch-changed-descriptors, which is intended for use during state synchronization ๐Ÿ”„ Whenever a descriptor changes state (one of its flags is cleared, for example), the repository notes which clients haven't yet recorded the change locally. fetch-changed-descriptors has the repository send the client a maximum of the first N descriptors that have changed since the client's last synchronization, where N is a number the client sends. The list begins with the descriptor with the lowest UID. Heads-up: the list of descriptors is only guaranteed to be monotonically increasing for a single call to fetch-changed-descriptors, because messages with lower UIDs may be changed by other clients in between calls. This operation takes two arguments: the name of the mailbox to search, and the maximum number of descriptors for the repository to return.

Once the changed descriptors have been looked at, the user will want to tell the repository that the current client has recorded the change locally โœ… The reset-descriptors command causes the repository to mark a given series of descriptors as "recorded by current client". The series is identified by a low UID and a high UID. UIDs within the series that no longer exist are ignored. The arguments are the mailbox name, the low UID in range, and the high UID in range.

Whole messages are transmitted from the repository to the user with the fetch-message operation ๐Ÿ“ฉ Splitting up fetch-descriptors and fetch-message is a lifesaver for clients with small amounts of disk storage. They can grab a small message summary (via fetch-descriptors or fetch-changed-descriptors) without having to pull over the entire message ๐Ÿ’พ The arguments are the mailbox name, followed by the message UID.

Sometimes a message is too large for some clients to store locally ๐Ÿ˜… That's okay, because users can still look at the message contents via the print-message operation ๐Ÿ–จ๏ธ This operation has the repository send a copy of the message to a named printer. The printer name only needs to have meaning to the particular repository implementation, and DMSP transmits the name only as a means of identification. The arguments are the mailbox name, followed by the message UID, followed by the printer identification.

Copying a message into another mailbox is handled by copy-message ๐Ÿ‘ฏ A descriptor list of length one, containing a descriptor for the copied message, is returned if the copy operation succeeds. This descriptor is required because the copied message acquires a UID that's different from the original message's UID. The client can't be expected to know which UID was assigned to the copy, which is why the repository sends a descriptor containing that UID. The arguments to copy-message are the source mailbox name, the target mailbox name, and the source message UID.

Each message has sixteen flags associated with it, as described earlier ๐Ÿšฉ These flags can be set and cleared using the set-message-flag operation. The first eight flags have special meaning to the repository, as described above, and the remaining eight are for user use. set-message-flag takes four arguments: the mailbox name, the message UID, the flag number (0 through 15), and the desired flag state (0 or 1).


5. Client Architecture ๐Ÿ’ปโœจ

Clients can be any number of different workstations, so Pcmail's architecture has to take into account the whole range of workstation characteristics ๐Ÿ–ฅ๏ธ First, most workstations are way more affordable than the big computers currently used for mail service, so it's totally possible a user has more than one ๐Ÿค‘ Second, some workstations are portable, and they aren't expected to stay constantly tied into a network ๐ŸŽ’ Finally, many of the smaller workstations are resource-poor, so they aren't expected to be able to store a significant amount of state information locally ๐Ÿฅบ The following subsections describe the particular parts of Pcmail's client architecture that address these different characteristics ๐ŸŒˆ

5.1. Multiple clients ๐Ÿ’ป

okay so bestie, Pcmail users can own more than one workstation ๐Ÿฅน like one client at home, one at the office, and maybe even a third portable one ๐ŸŽ’. that's literally the reason Pcmail uses the multiple client model ๐Ÿ’…. each client keeps its own separate copy of the user's mail state, which is why Pcmail is so distributed ๐ŸŒˆ. having separate clients means you can reach your mail state from a bunch of different places. and Pcmail doesn't limit how many clients a user can talk to the repository from at the same time ๐Ÿ™Œ. instead, the repository implementation decides whether it lets several clients have concurrent access to a user's mail state ๐Ÿงš. main character energy fr.

5.2. Synchronization ๐Ÿ”„

some workstations are small and super portable, so the odds of them always being hooked up to a network are pretty low ๐Ÿฅบ. that's another reason each client keeps a local copy of the user's mail state ๐Ÿ’œ. the user can mess around with the local mail state even when they're not connected to the network (or the repository) ๐ŸŽ€. but now we have a synchronization problem between the local and global mail states ๐Ÿ˜ญ. the repository is always in a position to receive global mail state updates, whether that's incoming mail or changes from other clients ๐Ÿ“ฌ. a client that isn't always connected can't get those global changes right away โณ. and on top of that, the client's user can make their own changes to the local mail state โœ๏ธ.

Pcmail's architecture allows fast synchronization between the client's local mail states and the repository's global mail state โšก. each client is identified in the repository by a client object attached to the user ๐Ÿชช, and that object is the basis for syncing local and global mail states ๐Ÿซถ. some of the less common state changes are adding and deleting user mailboxes and adding and deleting address objects ๐Ÿ“. those changes get synced through DMSP list operations ๐Ÿ“‹, which let clients compare their local mailbox and address object lists with the repository's global version and make any appropriate changes ๐Ÿ’…. most of the possible changes to a user's mail state are changed descriptors ๐Ÿฆ‹. since most users have a ton of messages and message states change pretty often, message synchronization needs special attention ๐Ÿ‘€.

An existing descriptor can change in three ways ๐Ÿงฉ. first, one of its sixteen flag values can change (this covers stuff like the user reading an unseen message, deleting a message, printing a message, etc). second, a descriptor can be created, either by a new message being delivered or by a message getting copied from one mailbox to another ๐Ÿ“ฆ. and finally, a descriptor can be destroyed via an "expunge-mailbox" operation ๐Ÿ’€.

In all of those cases, the repository and every client that hasn't already noticed the change need to sync up ๐Ÿ”. to keep track of which clients have noticed a global mail state change and updated their local states, each mailbox has a list of active clients attached to it ๐Ÿ“. each client also has a (potentially empty) "update list" of messages that changed since that client last synced ๐ŸŒธ.

When a client connects to the repository, it runs a DMSP "fetch-changed-descriptors" operation ๐Ÿ”Œ. this makes the repository send back a list of all the descriptors on that client's update list ๐Ÿ“œ. once the client has the changed descriptors, it can do one of two things ๐Ÿค”: if the descriptor is marked "expunged", the client can remove the matching message from the local mailbox ๐Ÿ—‘๏ธ. if the descriptor is not expunged, the client can store the descriptor, which updates the local mail state โœ…. after a changed descriptor has been recorded, the client uses the DMSP "reset-descriptors" operation to remove descriptors from its update list ๐Ÿงน. those descriptors won't be sent to the client again unless (1) it's explicitly requested through a "fetch-descriptors" operation, or (2) they change again ๐Ÿ”‚.

that's how a client can run through its user's mailboxes, get all the changes, bring them into the local mail state, and mark them as recorded ๐Ÿ slay.

5.3. Batch operation versus interactive operation ๐ŸŽฌ

because some workstations are portable, they might not always be connected to a network (and able to talk to the repository) ๐Ÿš‚. since each client keeps a local mail state, Pcmail users can work on that local state while they're offline from the repository ๐Ÿ“ด. this is called "batch" operation, since the client records all the changes and applies them to the repository's global state as a batch the next time it connects ๐Ÿ“ฆ. interactive operation is when a client is always connected to the repository ๐Ÿ“ถ. in interactive mode, changes made to the local mail state also get made to the global state right away through DMSP operations โšก.

in batch mode, the client and repository talk like this ๐Ÿ—ฃ๏ธ: the client connects to the repository and sends over all the changes the user made to the local mail state ๐Ÿ’Œ. the repository changes its global mail state to match โœจ. once all the changes are processed, the client begins synchronization, which brings newly-arrived mail, plus mail state changes from other clients, into the local state ๐ŸŽ.

in interactive mode, local changes are immediately propagated to the repository, so the first part of batch-type operation gets skipped ๐Ÿ™…โ€โ™€๏ธ. the synchronization process changes too. one synchronization is still needed when the client first opens a connection to the repository, but after that, syncs can happen either at the user's request or automatically every so often by the client ๐Ÿ”โœจ.

5.4. Message summaries ๐Ÿ“

smaller workstations might have very little disk storage ๐Ÿ’พ. clients on those machines may never have enough room for a complete local copy of a user's global mail state ๐Ÿ˜ต. so Pcmail's client architecture has to let users get a clear picture of their mail state without having all their messages present ๐Ÿ‘€.

descriptors give you message info without taking up big chunks of storage ๐Ÿฐ. each descriptor contains a summary of information about a message ๐Ÿงพ. that info includes the message UID, its length in bytes and lines, its status (contained in the eight system-defined and eight user-defined flags), and portions of its RFC-822 header (the "from:", "to:", "date:" and "subject:" fields) ๐Ÿ’Œ. all of this can be encoded in a small (around 100 bytes) data structure whose length doesn't depend on the size of the message it describes ๐ŸŒท iconic.

most clients should be able to store a complete list of message descriptors with little problem ๐Ÿ™Œ. that lets a user see their whole mail state without having every message locally ๐Ÿซง. if a client has extremely limited disk storage, it can also grab a subset of the descriptors from the repository ๐Ÿงšโ€โ™€๏ธ. short messages can live on the client along with the descriptors, and long messages can either be printed via the DMSP print-message operation or specially pulled over via the fetch-message operation ๐Ÿ“„๐Ÿ’–.

6. Typical interactive-style client-repository interaction โœจ

okay bestie, this section walks through a totally normal session between the repository and a client mail reader ๐Ÿ’… The client is one of three belonging to user "Fred". Its name is "office-client", and since Fred has used it within the last week, it's marked as "active" ๐ŸŒธ Fred has two mailboxes. "fred" is where all of his current mail lives, and "archive" holds the messages of lasting importance ๐Ÿ“ We're going to run through a simple synchronization operation. Usually the sync happens as part of a "get new mail" operation, so it's giving very real-life vibes ๐Ÿซถ

First, Fred's mail reader connects to the repository and gets this banner:

200 Pcmail repository version 3.0.0 ready

To access his global mail state, the mail reader must authenticate Fred to the repository. That happens through the DMSP login operation ๐Ÿ”

login fred fred-password office-client 0 0

This tells the repository that Fred is logging in via "office-client", and that "office-client" is identified by an existing client object in Fred's mail state. The first argument is Fred's repository user name. The second is his password. The third is the name of the client talking to the repository. The fourth tells the repository not to create "office-client" even if it can't find its client object. The final argument tells the repository that Fred's client is not operating in batch mode but rather in interactive mode โœจ

Fred's authentication checks out, so the repository logs him in:

200 command OK

Now that Fred is logged in, the mail reader does an initial synchronization. It starts by asking for an up-to-date list of mailboxes:

list-mailboxes

The repository replies with:

230 mailbox list follows:
fred 2313 10 1
archive 101 100 0
.

So this tells the mail reader there are two mailboxes, "fred" and "archive" ๐Ÿ“ฌ "Fred" has 10 messages, one of which is unseen, and the next incoming message will get a UID of 2313. "Archive" has 100 messages, none unseen, and the next message sent there will get UID 101. There are no new mailboxes in the list (if there were, the mail reader would create them. On the other hand, if some mailboxes in the mail reader's local list were not in the repository's list, the program would assume them deleted by another client and delete them locally as well). Lowkey iconic how it just handles all of that for you ๐Ÿฆ‹

To synchronize, the mail reader only needs to look at each mailbox's contents to see if (1) any new mail has arrived, or (2) Fred changed any messages on one of his other two clients after "office-client"'s last connection to the repository ๐Ÿ‘€

The mail reader asks for any changed descriptors with the "fetch-changed-descriptors" operation. It requests at most ten, since storage is very limited on Fred's workstation ๐Ÿฅบ

fetch-changed-descriptors fred 10

The repository responds with:

250 descriptor list follows:
expunged
2101
expunged
2104
descriptor
2107 1100011100000010 1400 30
foo@bar.edu (Foo Jones)
fred@PTT.LCS.MIT.EDU
Wed, 9 Dec 87 10:43:52 EST
A typical subject line
descriptor
2312 0000000000000000 12232 320
joe@athena.mit.edu
fred@PTT.LCS.MIT.EDU
Thu, 17 Dec 87 18:24:09 PST
Another typical subject line
.

Here's the format. If a descriptor changed because it was expunged, it comes through as two lines: the word "expunged" on one line, then the message UID on the next. If one of its flags changed state, or it's a new message, it comes through as six lines: the word "descriptor" on one line, then a line with the message UID, flags, and length in bytes and lines. After that come the to, from, date, and subject fields, each on its own line. The flags are sent as one string of ones and zeroes, a one if the flag is on and a zero if it's off. All 16 flags are always sent. Flag zero's state is the first character in the flag string, and flag fifteen's is the last character in the flag string ๐Ÿงš

Okay, the first two descriptors are expunged, probably because Fred emptied his mailbox on another client. The mail reader removes messages 2101 and 2104 from its local copy of mailbox "fred". The next descriptor is a message Fred marked for deletion on another client yesterday, so the mail reader marks its local version as deleted ๐Ÿ—‘๏ธ The last one is brand new, so the mail reader adds it to its local list. Since all changes to mailbox "fred" have now been recorded locally, the update list can be reset:

reset-descriptors fred 1 2312

The repository responds with:

200 command OK

That means it has removed every message in mailbox "fred" with UIDs between 1 and 2312 inclusive (in this case just two messages) from "office-client"'s update list. "Fred" is now synchronized! โœจ The mail reader turns to Fred's "archive" mailbox and asks for the first ten changed descriptors:

fetch-changed-descriptors archive 10

The repository responds with:

250 descriptor list follows:
.

A zero-length list means no descriptors have changed in "archive" since its last synchronization, so no new synchronization needs to happen ๐Ÿ’–

Fred's mail reader is now ready to pull over the new message. The message is 320 lines long, and there might not be enough storage on "office-client" to hold it. The mail reader tries anyway ๐Ÿ˜ฌ

fetch-message fred 2312

The repository starts sending the message:

251 message follows:
UID: 2312
From: joe@bar.mit.edu
To: fred@PTT.LCS.MIT.EDU
Date: Thu, 17 Dec 87 18:24:09 PST
Subject: Another typical subject line

Fred,

...

Halfway through, Fred's workstation runs out of disk space ๐Ÿ’€ Because all DMSP operations are defined to be failure-atomic, the part of the message that already arrived is destroyed locally and the operation fails. The mail reader tells Fred the message can't be pulled over because there isn't enough disk space. The synchronization process is now finished, and Fred can start reading his mail. The new message that was too big to fit on "office-client" gets marked "off line". Fred can use the mail reader to either remote-print it, or delete and expunge other messages until he has enough room to store it ๐Ÿ–จ๏ธ

Since Fred is running in interactive mode, any changes he makes to messages get transmitted straight into DMSP operations and sent to the repository. Depending on the mail reader implementation, Fred will either have to run a "synchronize" command every so often, or the client will sync for him automatically from time to time.

7. A current Pcmail implementation ๐ŸŒˆ

okay so this section briefly describes a current Pcmail system that looks after a small community of users ๐Ÿซถ The Pcmail repository runs under UNIX on a DEC Microvax-II connected to the Internet. The clients run on IBM PCs, XTs, and ATs, plus Sun workstations, Microvaxes, and VAX-750s. Quite the mix, honestly ๐Ÿ’…

7.1. IBM PC client code

The IBM machines only do batch mode, and that's totally a vibe check ๐Ÿฅฒ Users make local state changes in a mail reader. The changes get queued until the user runs a network client program. That program connects to the repository, performs the queued changes, and synchronizes local and global mail states. Then the network client program disconnects from the repository ๐Ÿ”Œ

The IBM PC client code has gone through several revisions since the first Pcmail RFC was published. What used to be a fairly primitive and clunky system has grown into something that makes excellent use of the PC's limited resources and gives users a pretty powerful, easy-to-use mail reader. Glow-up era for real โœจ

Users access and modify their local mail state through a mail reader written in the Epsilon text editor's EEL extension language. They get a bunch of commands for working with individual messages and mailboxes, plus commands for composing outgoing mail ๐Ÿ“

Synchronization and the processing of queued changes is handled by a separate program that the user runs whenever they want. It takes any actions queued while using the mail reader and converts them into DMSP operations. All queued changes are made before any synchronization happens. The program can be invoked straight from the mail reader, so there's no need to exit and restart ๐Ÿƒโ€โ™€๏ธ

Limiting IBM PC clients to batch mode was a choice made because of development environment limitations. The mail reader can't work with the network code inside it because of the network program architecture. The only solution was a two-part client: one part reads the mail, and the other part talks to the repository. It's a little cumbersome, but honestly the two-program setup works quite well ๐ŸŽ€

7.2. UNIX client code

Client code for the Suns, Microvaxes, and VAX-750s runs on 4.2/4.3BSD UNIX. It's fully interactive, with a powerful mail reader inside Richard Stallman's GNU-EMACS editor ๐Ÿคฉ UNIX workstations have a good amount of main memory and disk storage, so no effort went into shrinking local mail state by keeping message descriptors instead of message text. Big brain energy, no notes ๐Ÿง 

The local mail state is made up of a number of BABYL-format mailboxes. The interface looks a lot like the RMAIL mail reader that's already in GNU-EMACS ๐Ÿ“ง

The mail reader talks to the repository through network code implemented in EMACS-LISP. Changes to the local mail state are made on the repository right away. The repository is fast, but there's a small, noticeable delay when operations go over the network โณ

There's no provision for automatic synchronization when new mail arrives or old mail gets changed by another client. Instead, users have to get new mail explicitly. A simple "notification" program runs in the background and wakes up every minute to check for new mail. When mail shows up, the user runs a command to get it, which also synchronizes the mailbox at the same time ๐Ÿ””

7.3. Repository code

The repository is implemented in C on 4.2/4.3BSD UNIX. Right now it runs on DEC VAX-750s and Microvaxes, though other repositories will soon be running on IBM RT machines and Sun workstations ๐Ÿš€ The repository code is designed to let several clients belonging to one user "concurrently" modify that user's state, which is giving multitasking queen ๐Ÿ‘‘ A locking scheme keeps one client from modifying mail state while another client is modifying the same state ๐Ÿ”’

8. Conclusions โœจ

okay so Pcmail is currently used by a small community of people at the MIT Laboratory for Computer Science ๐ŸŽ€. The repository design is honestly giving ๐Ÿ’… because it's an efficient way to store and maintain mail state for several users. Its performance is quite good when up to ten users are connected ๐ŸŒธ. Whether it stays efficient when there are ten or a hundred times that many users is still a mystery ๐Ÿ‘€. Given enough disk storage, it should be able to, since communication between different users' clients and the repository is likely to be very asynchronous ๐Ÿฆ‹. It's also likely to happen in short bursts, with long "quiet intervals" in between while everyone is busy doing other things ๐Ÿ’œ.

Another research group at LCS is currently working on a replicated, scalable version of the repository ๐ŸŒˆ. It's designed to support a very large community of users with high availability ๐Ÿ‘‘. This repository also uses DMSP, and it has successfully communicated with clients that use the current repository implementation โœจ. So DMSP seems to be usable over several flavors of repository design ๐Ÿงš.

The IBM PC clients are very limited in resources ๐Ÿฅบ. The mail reader/editor combo is still quite powerful, though, which makes local mail state manipulation fairly easy ๐Ÿ’…. Obviously, a big performance glow-up would be a fully interactive client ๐Ÿ”ฅ. For now, batch-style synchronization is relatively time consuming because the PCs are slow ๐Ÿ˜ญ. The "batch-mode" the PCs use tends to be good for PCs that spend a large percentage of their time unplugged and away from a network ๐Ÿ“. It's somewhat inconvenient for PCs that are always connected to a network, though, and they could make good use of "interactive-mode" state manipulation ๐Ÿ™ˆ.

The UNIX-based clients are more powerful and easier to use than their PC counterparts ๐Ÿ’–. Synchronization is much faster, and there is far more functionality in the mail reader. Having an interface that runs within GNU-EMACS helps a lot with that ๐Ÿซถ. Most of the people using the Pcmail system use the UNIX-based client code ๐Ÿ‘‘.

I. DMSP Protocol Specification ๐Ÿ’–

Okay bestie, this appendix is basically the ultimate cheat sheet ๐Ÿ“. It lists the DMSP operations grouped by object type, along with their syntax and the responses they can send back. Some responses can be followed by zero or more lines of text, ending with a single period plus a CR-LF pair ๐Ÿซถ. Only the success responses and the common error responses are listed here, so the complete list of possible responses comes after this appendix โœจ. Anything in angle brackets, like <mailbox-name>, is a metalinguistic variable, which is just fancy talk for a placeholder standing in for a general request or response form ๐Ÿ’…. Operations that take arguments get a sample invocation right after their syntax and response ๐ŸŽ€.

General operations ๐ŸŒธ

HELP
100 Repository version xxx.  Following are supported:
HELP
SEND-VERSION
SEND-MESSAGE
LOGIN
LOGOUT
...
FETCH-MESSAGE
COPY-MESSAGE
.
SEND-VERSION <version-number>
200 Command OK
500 version skew!
i.e. SEND-VERSION 230
SEND-MESSAGE
350 enter message; end with "."
To: markl
From: markl
Subject: a test message

this is a test message
.

The repository answers back with:

200 Command OK
403 message syntax error

User operations ๐Ÿงš

LOGIN <user> <password> <client> <create-p> <batch-p>
200 Command OK
221 Client out of date by > 1 week
404 Bad password
405 Client <client-name> is locked
411 No user named <user-name>
421 Client <client-name> not found
i.e. LOGIN markl foo random-client-name 1 0
LOGOUT
200 Command OK
SET-PASSWORD <old-password> <new-password>
200 Command OK
404 Incorrect old password
i.e. SET-PASSWORD foo bar

Client operations ๐Ÿ’œ

LIST-CLIENTS
220 Client list <name> <status> follows:
client-1 active
client-2 inactive
client-3 active
...
client-foobar active
.

Each line of the list has a client name, then whitespace, then the word "active" or the word "inactive". That tells you whether or not the client has connected to the repository within the last week โญ.

CREATE-CLIENT <client-name>
200 Command OK
403 <client-name> is an illegal name
420 Client <client-name> exists
i.e. CREATE-CLIENT new-client
DELETE-CLIENT <client-name>
200 Command OK
421 Client <client-name> not found
405 Client <client-name> is locked
i.e. DELETE-CLIENT old-client
RESET-CLIENT <client-name>
200 Command OK
421 Client <client-name> not found
405 Client <client-name> is locked
i.e. RESET-CLIENT any-old-client

Mailbox operations ๐Ÿ“ฌ

LIST-MAILBOXES
230 Mbox list <name> <high-UID> <#msgs> <#new> follows:
mailbox-1 2338 8 1
mailbox-2 59 44 0
...
mailbox-foobar 19 9 0
.

Each line of the list has a mailbox name, then the mailbox's next available unique identifier, then the number of messages in the mailbox, and finally the number of unseen messages. Unseen messages are the ones whose descriptors have flag #1 ("message has been seen") set to zero ๐Ÿ‘€.

CREATE-MAILBOX <mailbox-name>
200 Command OK
403 <mailbox-name> is an illegal name
430 <mailbox-name> already exists
440 <mailbox-name> exists as a bboard subscription
i.e. CREATE-MAILBOX current-events
DELETE-MAILBOX <mailbox-name>
200 Command OK
431 mailbox <mailbox-name> not found
440 <mailbox-name> is a bboard; use delete-bboard-mailbox
i.e. DELETE-MAILBOX income-tax-information
CREATE-BBOARD-MAILBOX <mailbox-name>
200 Command OK
430 a mailbox named <mailbox-name> already exists.
430 a bboard mailbox named <mailbox-name> already exists.
403 <mailbox-name> is an illegal name
i.e. CREATE-BBOARD-MAILBOX sf-lovers
DELETE-BBOARD-MAILBOX <mailbox-name>
200 Command OK
404 not owner of <mailbox-name>
431 no bboard mailbox named <mailbox-name>
i.e. DELETE-BBOARD-MAILBOX rec.autos
RESET-MAILBOX <mailbox-name>
200 Command OK
431 mailbox <mailbox-name> not found
i.e. RESET-MAILBOX british-cars
EXPUNGE-MAILBOX <mailbox-name>
200 Command OK
431 mailbox <mailbox-name> not found
EXPUNGE-MAILBOX british-cars

Address operations ๐Ÿฆ‹

LIST-ADDRESSES <mailbox-name>
260 Address list for <mailbox-name> follows:
address-1
address-2
...
address-6
.

Or, instead:

431 mailbox <mailbox-name> not found
i.e. LIST-ADDRESSES archive

Each line of the list consists solely of one address ๐ŸŒˆ.

CREATE-ADDRESS <mailbox-name> <address-name>
200 Command OK
403 <mailbox-name> is an illegal name
431 mailbox <mailbox-name> not found
460 <address-name> already exists
i.e. CREATE-ADDRESS markl markl-bug-pcmail
DELETE-ADDRESS <mailbox-name> <address-name>
200 Command OK
431 mailbox <mailbox-name> not found
461 address <address-name> not found
i.e. DELETE-ADDRESS markl markl-info-cobol

Subscription operations ๐Ÿ”ฅ

LIST-SUBSCRIPTIONS
240 subscription list follows:
bboard-1 2573 33 2606
bboard-2 541 4 545
...
bboard-6 1530 43 1573
.

Each line of the list has a bulletin-board name, then the UID of the first message the user has not yet looked at, then the number of messages in that bulletin board the user has not yet looked at, and finally the bulletin board's next available unique message identifier ๐Ÿ“.

CREATE-SUBSCRIPTION <bboard-name>
200 Command OK
403 <bboard-name> is an illegal name
430 A mailbox named <bboard-name> already exists
431 Bboard mailbox <bboard-name> not found
440 Already subscribing to <bboard-name>
i.e. CREATE-SUBSCRIPTION sf-lovers
DELETE-SUBSCRIPTION <bboard-name>
200 Command OK
441 Subscription <bboard-name> not found
i.e. DELETE-SUBSCRIPTION rec.music
RESET-SUBSCRIPTION <bboard-name> <new-UID>
200 Command OK
441 Subscription <bboard-name> not found
i.e. RESET-SUBSCRIPTION rec.music.gdead 1210
LIST-AVAILABLE-SUBSCRIPTIONS
241 All available bboards follow:
mod.politics
sfl
tcp-ip
forum
...
comp.emacs
.

Each line of the list consists solely of one bulletin-board name ๐Ÿซง.

Message operations ๐Ÿ’Œ

FETCH-CHANGED-DESCRIPTORS <mailbox-name> <max-to-send>
250 Descriptor list follows:
expunged
2333
expunged
2334
descriptor
2337 0001000001110000 481 14
croaker@ptt.lcs.mit.edu
fred@anymachine.mit.edu
Tue, 19 Jan 88 11:10:03 EST
a typical subject line
descriptor
2339 0000000000000000 1457 40
bob@lcs.mit.edu
csr-people@ptt.lcs.mit.edu
Mon, 18 Jan 88 13:08:17 +0000
another typical subject line
expunged
2340
.

Or, instead:

431 mailbox <mailbox-name> not found
i.e. FETCH-CHANGED-DESCRIPTORS markl 100

Each element of the descriptor list is either two or six lines long ๐Ÿ“. An expunged descriptor takes two lines: the word "expunged" on one line, then the message unique identifier on the next. A descriptor that still exists takes six lines. The first is the word "descriptor". The second holds the message unique identifier, then the flag states (sixteen characters, each either one or zero depending on the associated flag value), then the message length in characters, then the message length in lines. The next four lines hold the message's "from:", "to:", "date:", and "subject:" fields, in that order. Flag zero's state is the first character in the flag string, and flag fifteen's state is the last character in the flag string ๐ŸŽ€.

FETCH-DESCRIPTORS <mailbox-name> <low-uid> <high-uid>
250 Descriptor list follows:
descriptor
2337 0001000001110000 481 14
croaker@ptt.lcs.mit.edu
fred@anymachine.mit.edu
Tue, 19 Jan 88 11:10:03 EST
a typical subject line
descriptor
2339 0000000000000000 1457 40
bob@lcs.mit.edu
csr-people@ptt.lcs.mit.edu
Mon, 18 Jan 88 13:08:17 +0000
another typical subject line
.

Or, instead:

431 mailbox <mailbox-name> not found
i.e. FETCH-DESCRIPTORS british-cars 12 31
COPY-MESSAGE <src-mailbox> <target-mailbox> <source-UID>
250 Descriptor list follows:
descriptor
2339 0000000000000000 1457 40
bob@lcs.mit.edu
csr-people@ptt.lcs.mit.edu
Mon, 18 Jan 88 13:08:17 +0000
another typical subject line
.

Or, instead:

400 cannot copy message onto itself
431 target mailbox <target-mailbox> not found
431 source mailbox <source-mailbox> not found
451 message <source-UID> not found
i.e. COPY-MESSAGE markl british-cars 2338
RESET-DESCRIPTORS <mailbox-name> <low-UID> <high-UID>
200 Command OK
431 mailbox <mailbox-name> not found
i.e. RESET-DESCRIPTORS markl 1 10000
PRINT-MESSAGE <mailbox-name> <UID> <printer-ID>
200 Command OK
401 printer <printer-name> not found
431 mailbox <mailbox-name> not found
451 message <UID> not found
i.e. PRINT-MESSAGE markl 2433 pravda
SET-MESSAGE-FLAG <mailbox-name> <UID> <flagnum> <state>
200 Command OK
431 mailbox <mailbox-name> not found
451 message <UID> not found
500 flag number <flag-number> out of range
i.e. SET-MESSAGE-FLAG british-cars 23 0 1
FETCH-MESSAGE <mailbox-name> <UID>
251 message follows:
From: markl@ptt.lcs.mit.edu
To: markl@ptt.lcs.mit.edu
Date: Sun, 17 Jan 88 11:11:11 EST
Subject: anything

this is a sample of some
message text
.

Or, instead:

431 Mailbox <mailbox-name> not found
451 message <UID> not found
i.e. FETCH-MESSAGE current-events 495

II. Operations by name โœจ

Here's the whole squad, alphabetically ๐Ÿ’…:

  • copy-message
  • create-address
  • create-bboard-mailbox
  • create-client
  • create-mailbox
  • create-subscription
  • delete-address
  • delete-bboard-mailbox
  • delete-client
  • delete-mailbox
  • delete-subscription
  • expunge-mailbox
  • fetch-changed-descriptors
  • fetch-descriptors
  • fetch-message
  • help
  • list-addresses
  • list-available-subscriptions
  • list-clients
  • list-mailboxes
  • list-subscriptions
  • login
  • logout
  • print-message
  • reset-client
  • reset-descriptors
  • reset-mailbox
  • reset-subscription
  • send-message
  • send-version
  • set-message-flag
  • set-password

III. Responses by number ๐Ÿ’…

okay bestie, this is the cheat sheet for every reply the repository can send back, lined up by number ๐Ÿซถ Each one is a 3-digit code followed by its message, and the codes are sorted by what they're giving you: success, success-ish, the "wait, who are you?" errors, and the "something broke" errors ๐Ÿ˜ญ

   100 Pcmail repository version XXX; following are supported
   200 Command OK
   220 Client list <name> <status> follows:
   221 Client out of date by > 1 week
   230 Mailbox list <name> <high UID> <#msgs> <#new> follows:
   240 Subscription list follows:
   250 Descriptor list follows:
   251 Message follows:
   260 Address list follows:
   350 enter message; end with "."
   400 cannot copy message onto itself
   410 already logged in
   420 client <name> already exists
   430 mailbox <name> already exists
   430 bboard mailbox <name> already exists
   440 subscription <name> already exists
   460 address <name> already exists
   411 no user named <name>
   421 client <name> not found
   431 mailbox <name> not found
   441 subscription <name> not found
   451 message <UID> not found
   461 address <name> not found
   402 internal error message
   403 syntax error in outbound message
   404 bad password or permission denied
   405 mail state is temporarily in use by another client
   406 please log in
   500 operation syntax error or illegal argument
heads up ๐Ÿ‘€ the list isn't in perfect numerical order (411 shows up after 460, for example), and 430 appears twice, once for a regular mailbox and once for a bboard mailbox. read it exactly as written, bestie, don't skip ahead ๐Ÿ™ˆ
๐Ÿ“ฆ where this page comes from