Al is a contributing editor for DDJ and can be contacted at 411 Borel Ave., San Mateo, CA 94402.
There is a new API that will soon allow you to add electronic mail to your applications with less work and more portability. That's because last October, Lotus Development Corporation released the first draft of the Open Messaging Interface API Functional Specification. OMI defines a standard, platform-independent method for applications to exchange electronic mail. IBM and Apple collaborated with Lotus in the definition of the specification. Lotus is committing its own applications -- AmiPro, 1-2-3, and Freelance Graphics -- to the OMI API, and they hope the rest of the industry will accept and endorse it as well. At the time of this writing, the OMI API specification is still in draft form, but the final specification should be available by the time you're reading this article. Software mail drivers will soon follow to implement the API on the various platforms where applications run.
The appearance of a standard API for electronic mail is a significant event for applications developers. As you'll see later in this article, desktop applications need to communicate among users, and until now there has been no standard way to do that. OMI is reminiscent of the Lotus-Intel-Microsoft Expanded Memory Specification (EMS) and the Microsoft, Intel, AST Research, and Lotus eXtended Memory Specification (XMS) in that all three APIs define standard ways for applications developers to access common system resources, and the standards result from the cooperative efforts of multiple industry giants. Third-party developers provide the necessary device drivers that implement the APIs, and that will be true of OMI, too.
But OMI goes a step beyond EMS and XMS. It defines an API for the functions of a complete electronic mail software process rather than for a hardware architecture. For OMI to succeed, the vendors of operating systems and networks must support it with API software libraries. Significantly absent from the OMI specification designers is Microsoft. Perhaps without Microsoft, OMI will test how well a PC API standard will fare without the support of the number one software giant.
We usually think of electronic mail as a stand-alone application where users write messages to one another. The messages are like letters, and, in most mail applications, the messages consist of human-readable text, can include non-text files as attachments, can have several "carbon copy" recipients, and will wind up in the receiver's message databases to be recalled and reread. Such applications abound, but often users who need to communicate with one another cannot because they use incompatible systems. Furthermore, many non-mail applications need to exchange messages and files beyond the boundaries of one user's workstation or a LAN. These two circumstances create the need for a standard way for remote applications to exchange data.
What other kinds of applications require mail capabilities? We could dream up many vertical applications that need to exchange text and data files. Some of the best examples, however, are horizontal, and the first one that comes to mind is the spreadsheet. (No wonder Lotus is committed to this project.)
Suppose you are a user who has just completed a complex spreadsheet. It is time to disseminate the data to the other members of the project. What are your options without electronic mail? If you are on a network, you can copy the spreadsheet file to a public network directory and call everyone and tell them to get the file. If you are not on a network, your communications program can call the group members one-by-one and upload the file. Or you can copy and distribute diskettes. Of course, it's easier if you and your coworkers have compatible conventional mail systems. You note the spreadsheet's filename, exit the spreadsheet application, enter the mail application, and send the file to everyone. With luck, your electronic mail program resides in memory or runs in a multitasker's window or task swapper's partition, and you don't have to exit the spreadsheet program. But you still need to deal with three possibly different user interfaces: the spreadsheet program, the operating system to switch to the mail program, and the mail application itself.
Suppose, instead, that your spreadsheet application itself is "mail aware." A mail-aware program can send and receive electronic mail in a standard format through a standard delivery system without involving a separate electronic mail program. You simply tell the spreadsheet program to mail the file to the group. You do not need to exit to a separate mail application. You can even send a descriptive note along with the file so the receiver knows what you are sending. If most of the group is using the spreadsheet application when their mail arrives, they receive the descriptive note in a message window, and the new file pops into their spreadsheet screen. Mission accomplished. But suppose that George is not in the spreadsheet program; he is writing a report when the mail shows up. If George has a mail-aware word processor with a compatible mail delivery system, then the word processor notifies him that the mail is in, and he reads the descriptive note from within the word processor. Of course, a word processor can't do much with a spreadsheet file, but the word processor's mail system can deliver the note to George and store the spreadsheet file where it ought to go. George knows that the file has arrived, and the next time he runs his spreadsheet application, there the file is.
Until now, such integration was possible only when the two applications came from the same vendor, or when the two vendors collaborated on the interface (which rarely happens) or independently developed their programs to operate within a defined message delivery environment. There are such environments. For example, most Netware electronic mail applications use the Netware Message Handling Service (MHS) to send and receive mail between remote users. MHS is a message delivery system. If your application builds a message in a precise format and writes it into the appropriate subdirectory on the file server, then MHS will deliver the message. If you and your mail application are properly registered, MHS will collect messages addressed to you and deposit them into the right place on the file server. Your mail application must observe the arrival of the message, retrieve it, and interpret its contents. MHS runs in a Netware network and on stand-alone work stations and exchanges messages with other MHS systems. By itself, it will not exchange messages with other delivery systems. For that, you need a gateway.
A gateway converts and copies messages from the format and location of one system to those of another. If your mail application deposits a message to a user in another system supported by the gateway, your message delivery system gives the message to the gateway. The gateway knows the formats of the two delivery systems it connects. The gateway translates the message and sends it to the other system. When that system sends messages back, the gateway translates them into the format of the local system and delivers them. In such an environment, you develop your mail application to run with a chosen delivery system (MHS, for example) and hope that gateways exist to connect you to any other systems that your users might want to talk to.
A typical electronic mail application consists of four parts: the user interface, the address book, the message database, and the message delivery system. Without OMI, every application must manage the first three and tightly bind to the fourth. Many applications do their own message delivery for local users and depend on gateways and message delivery systems to exchange mail with remote users. That dependence requires the application to not only have their own local delivery strategies but to conform to the conventions of the message delivery system as well. The OMI API removes that dependence by providing a common interface between the application and the delivery of all messages, whether the senders and receivers are local, or whether the exchange involves a message delivery system.
The OMI API is a common programming interface to all but the user interface functions of electronic mail. It does not eliminate gateways because it does not prescribe file formats, storage locations, or transmission media and protocols, but it does eliminate the need for applications to be aware -- at the source code level -- of the conventions associated with a particular message system. And it makes an OMI-conforming application compatible with all OMI environments.
An application conforms to OMI by calling functions that establish sessions, send and receive messages, read and update user address books, and maintain a message database. The application supplies the user interface and has no concern for the formats and locations of the data files. The underlying OMI engine takes care of that, thus resolving the question of which message delivery system the application should support. If the industry embraces OMI as Lotus expects, all popular platforms will have OMI libraries for developers to use. In the worst case, if you wanted your OMI-conforming application to run with some obscure message delivery system that had no OMI library, you could develop the library yourself. The effort would be no more difficult than the conventional route of binding your application directly to the message delivery system. Once you finished the library, you'd have another product to sell -- a new OMI engine for the heretofore neglected platform.
So, how does OMI promote portability for your application? Suppose you write an OMI-conforming mail application that runs on PCs. If the NetWare network has an OMI engine, you can build a NetWare version of your program simply by linking your program modules with the NetWare OMI function library. If the 3-Com network has a similar OMI engine, you can as easily build a 3-Com version of your program. Now, if either NetWare or 3-Com has a gateway to the other, your Netware users and your 3-Com users can communicate. Furthermore, if the systems have gateways to online services such as CompuServe mail, the users can exchange messages on the service by using your application.
Your application can also talk to other conforming applications where either one has a gateway. And that goes for applications running in totally different host systems, too. DOS users can communicate with Macintosh users, and they both can communicate with mainframe users, and so on, as long as everyone has OMI-conforming applications with OMI engines installed and the necessary gateways. Additionally, your application can communicate with other applications on the same platform, provided that the application is mail aware and OMI-conforming.
Many OMI API implementations will be function libraries. Programs will include the library when they link. Others will be implemented as Dynamic Link Libraries. For example, a Windows OMI API will work through calls to an OMI DLL. Any OMI-conforming Windows application will execute properly no matter what underlying message delivery system is in place. You won't need to relink the application to a different OMI library, either. The user's Windows installation would load the correct copy of the OMI DLL, and your application would work the same no matter which one Windows loads.
There are about 50 OMI functions divided into these seven categories: the Standard Send function, Session Management functions, Message Creation and Submission functions, Message Store functions, Message Access and Attribute functions, Address Book functions, and Common Object functions. The OMI API specification describes functions, data types, constants, and error codes in a generic C-language context. It does not say whether the function definitions have such things as far or pascal specifiers, no doubt leaving such platform-dependent details to the implementer.
The Standard Send function is one of the most interesting parts of the OMI specification. It is a boon for applications developers and an albatross for library implementors. With it, any application can be mail aware with little more than an extra line of code. It works on the sending side of electronic mail and includes in one function call everything an application needs to send electronic mail.
To send a message, an application calls the Standard Send function. The parameters include a list of recipients, an attachment file specification, and text for the message and its subject. Here's where the magic comes in. If those parameters are NULL, the OMI library takes over by prompting the user for whatever is missing. This means that an implementation of OMI must include the ability to pop up windows with which the user can type message text, select recipients, and specify file specifications for attachments. This is a significant feature if you are an application developer and you want to add electronic mail to your application. To gain that e-mail check mark on the bullet lists of magazine reviews, you simply add an option that calls the Standard Send function with NULL parameters. Voila. E-Mail. Your application will be able to send user-composed mail messages with user-specified attachments to user-selected recipients. Although the user cannot receive any mail, your application qualifies nonetheless as being mail aware. That's why the Standard Send function is a boon to applications developers. Upon close inspection, however, one might conclude that the capability has no more power than a memory-resident mail program that pops up over the application. In my opinion, the OMI specification could do as well without the user-prompting requirement. Here's why.
If the Standard Send function is gravy to the application developer, it is a burden to OMI library developers. They have to write the user interface code for the selection list boxes, a text editor, and video window pop-ups over the application, code that many applications will never use. It is apparent that the OMI designers targeted environments such as Windows and the Macintosh where the GUI manages a common user interface. But library developers for text-mode environments such as DOS will have to handle the user interface without help from the operating system. Those processes will add to the size and complexity of the OMI library, and their looks and feels will seldom be the same as those of the applications that they support.
Do not assume, however, that the Standard Send function has no value. The strength of the Standard Send function is not in its ability to wedge an electronic mail function into just any application but in its support for nonmail applications to send data files with no other electronic mail requirements. Such an application would develop the file and text parameters for the Standard Send function based on the application's knowledge of the data. There are several options presented by the function. The application might omit the recipient parameters and let OMI prompt the user for that information, or it could use its own user interface along with the OMI Address Book functions to build a recipient list. A closed system might use embedded recipient data, and the Standard Send function would be the application's only interface to OMI.
The Standard Send function is the only part of OMI that requires a user interface. The OMI specification does not say what that interface should look like, only what it should do.
Although the OMI specification does not address the issue of partial implementations, a minimal OMI library implementation might be no more than a Standard Send function without the user interface. This implementation would support those applications that provide all the parameters. A second-level OMI library might eliminate the Standard Send function altogether and support those applications that use their own user interface and the balance of the OMI functions to manage everything else. Of course, a complete OMI library would include everything.
To log into OMI, an application opens a session. You tell the session where the message store database is, the user's name and password, and what character set to use. Each session has a handle, which the mail program uses in subsequent calls to OMI. This handle allows a single copy of OMI to support multiple sessions in a multitasking environment, so theoretically you can have your mail-aware spreadsheet and word processor programs running at the same time.
The Session Management functions perform processes related to the user and the specific OMI session. One of the functions tells the mail program about the operating parameters of the particular OMI implementation. This allows a mail program to adapt itself to the local environment. The operating parameters include the maximum size of a message's text, the text format that is supported, character sets, and file attachment types. Other Session Management functions return the user's name, log the user into the OMI system, and validate the password. If your program uses only the Standard Send function, you do not need to open a session. The Standard Send function takes care of the session for you.
You use these functions to construct a mail message and deposit it into the OMI system to be delivered. You must have opened a session and interacted with your user to gather all the components of the mail message. A mail message consists of lists of recipients, including original, carbon copy, and blind carbon copy recipients, text and graphics, a file attachment, a subject, a delivery priority, whether or not the sender requires delivery notices or return receipts, whether or not the message is to be encrypted, if it should have a signature stamp, and whether or not the message will be saved in the sender's message archive. The Message Creation and Submission functions allow you to identify each of these components and options to OMI for each message. You submit a message as an original message, a reply to a message you received, or to forward a message to other recipients.
The message store is the message database that the OMI system maintains. The API specification does not dictate the formats or retrieval techniques that the data base will use. The message database, also called the "mailbox," contains the incoming mail in its inbox and messages that the user has filed in its archive.
The Message Store functions support the organization of messages into user-defined categories, also called "folders" in some systems. There are functions that move, copy, and delete messages among the categories, that enumerate the messages and categories in a mailbox, and that query the message store for unread messages.
These functions retrieve messages and their attributes from the message store. The application uses these functions to read incoming mail and to reread mail that the user previously filed in the archive.
An OMI application can use a message signature stamp, which is a binary copy of something that uniquely identifies the sender. The Message Access and Attribute functions support the signature with a verification function. OMI does not define the details of the signature, only the method used to request its verification.
Most electronic mail systems support at least two kinds of address books: the public address book that defines all the possible recipients for messages that the system originates, and a private address book for each user who originates messages. Many systems support distribution lists as well, where the originating user specifies the name of the list, and the system delivers a copy of the message to each of the users in the list. Systems that connect to outside mail applications will associate remote users with the necessary routing information so that the delivery system or gateway can properly deliver the message. Some systems include a default destination for unidentified users so that a remote delivery system can attempt the delivery.
OMI supports the interface with the message delivery system's addressing capability with functions that retrieve group and individual addressee information and add, change, and delete entries in address books. An application can support multiple books, and OMI will report the names of those books to the application.
The last category of functions in the ~ API supports common operations across the other categories. There are functions to close sessions, get object attributes, retrieve the names of objects, and locate entries in list objects.
Any programmer who has worked on electronic mail applications will appreciate the significance of the OMI announcement. For the first time, applications of all kinds will be able to exchange data across computer, operating system, and language boundaries without needing to integrate themselves into complex, multiple-delivery architectures. Applications that run on several platforms will have one less platform dependency to manage. Programmers will learn only one API in order to build mail-aware applications in many environments. And our software industry will have taken one more step forward in the advance of standard solutions to common problems.
Copyright © 1992, Dr. Dobb's Journal