The Network Kit: The Mail Daemon

Declared in: <net/E-Mail.h>


Overview

Every Be machine has a mail daemon; this is a local process that's responsible for retrieving mail from and sending mail to a mail server. The mail server that the daemon talks to is a networking application that's either part of your Internet Service Provider's services, or that's running on a local "mail repository" machine. The functions described in this section tell you how to manage the mail daemon's connection with the mail server--how to tell the daemon which mail server to talk to, how to command the daemon to send and retrieve mail, how to automate mail retrieval, and so on.

All the functions that are described here (but one) are promoted to user-land through the E-mail preferences application (the one exception is the forward_mail() function). Indeed, the operations that these functions perform are rightly regarded as belonging to the user. The only reason that you would need to call the daemon functions--with the exceptions of forward_mail() and, possibly, check_for_mail()--is if you want to build your own E-mail preferences application. (forward_mail() and check_for_mail() could legitimately be worked into a mail-reading or -composing application.)

The architecture of the E-mail message itself isn't discussed here; for such information see Mail Messages .


The Mail Daemon and the Mail Server

The mail daemon can talk to two different mail servers:

The POP and the SMTP servers are identified by their hosts' names (in other words, the names of the machines on which the servers are running). The mail daemon can only talk to one POP and one SMTP server at a time, but can talk to the two of them simultaneously. Typically--nearly exclusively--the POP and SMTP servers reside on the same machine, and so are identified by the same name.

To set the identities of the POP and SMTP mail servers, you fill in the fields of a mail_account structure and pass the structure to the set_mail_account() function. As the name of the structure implies, mail_account encodes more than just the names of the servers' hosts. It also identifies a specific user's POP mail account; the complete definition of the structure is this:

   typedef struct
   {
       char pop_name[B_MAX_USER_NAME_LENGTH];
       char pop_password[B_MAX_USER_NAME_LENGTH];
       char pop_host[B_MAX_HOST_NAME_LENGTH];
       char smtp_host[B_MAX_HOST_NAME_LENGTH];
   } mail_account;

The POP user information that's stored in the mail_account structure (in other words, the pop_name and pop_password fields) is used only for the POP server; it has no significance for the SMTP server.


Sending and Retrieving Mail

Messages that are retrieved (from the mail server) by the mail daemon are stored in the database, from whence they are plucked and displayed by a mail-reading application (a "mail reader"; Be supplies a simple mail reader called BeMail). Similarly, messages that the user composes (in a mail composition application) and sends are placed in the database until the mail daemon comes along and passes them on to the mail server.

Sending and retrieving mail is the mail daemon's most important function. Both actions (server-to-database and database-to-server transmission) are performed through the check_for_mail() function. This is the mail daemon's fundamental "do something" function.


Other Mail Daemon Features

The other mail structures and functions define the other features that are provided by the mail daemon. These features are:

All of these features (less mail-forwarding) can also be set by the user through the E-mail preferences panel.


Functions


check_for_mail()

      long check_for_mail(long *incoming_count)

Sends and retrieves mail. More specifically, this functions asks the mail daemon to retrieve in-coming messages from the POP server and send out-going messages to the SMTP server. The number of POP messages that were retrieved is returned, by reference, in the argument. If you don't need to know the in-coming count, you can (and should) pass NULL as the incoming_count argument; the function is (potentially) much faster if you ignore the count in this manner.

If the mail world is unruffled, the function returns B_NO_ERROR ; otherwise, it returns one of the following:

  • B_MAIL_NO_DEMON. The mail demon isn't running.

  • B_MAIL_UNKNOWN_HOST. The named POP or SMTP mail server can't be found.

  • B_MAIL_ACCESS_ERROR. The connection to the POP or SMTP mail server failed.

  • B_MAIL_UNKNOWN_USER. The POP server doesn't recognize the user name.

  • B_MAIL_WRONG_PASSWORD. The POP server doesn't recognize the password.
  • In the cases where a name or password is unrecognized (B_MAIL_UNKNOWN_HOST , ...UNKNOWN_USER, and ...WRONG_PASSWORD ), the (mis)information is taken from the mail_account structure that was passed to the daemon in the most recent set_mail_account() call. Note that the validity of the mail_account information isn't checked when you set the structure --it's only checked when you actually attempt to use the information (as, for example, here).


    forward_mail()

          long forward_mail(BRecord *msg, 
             char *recipients,
             bool reset_sender = TRUE,
             bool queue = TRUE)

    Forwards the mail message represented by msg to the list of users given by recipients. msg is a BRecord object that encapsulates a single in-coming mail message. The user account names listed in recipients must be separated from each other by whitespace and/or commas; the entire list must be NULL-terminated. Both of these entities (the BRecord-as-mail-message, and the recipients list) are further explained in Mail Messages .

    If reset_sender is TRUE, the sender of the forwarded message is reset to be the current recipient; otherwise the sender is left as is. For example, if Anton sends a message to Bertrand and Bertrand forwards the message to Camille with reset_sender set to TRUE, the message that Camille receives will appear to have been sent by Bertrand; if set to FALSE , it will appear to have been sent by Anton.

    The queue argument determines whether the messages is sent now ( TRUE) or queued for later transmission (FALSE). If you send the message now, all other out-going and in- coming mail messages are transmitted as a matter of course (sending now is like calling check_for_mail()). If the message is queued, it waits for the daemon to perform its automatic check, or for the next explicit check_for_mail() call.


    set_mail_account(), get_mail_account()

          long set_mail_account(mail_account *account, bool save = TRUE)
          long get_mail_account(mail_account *account)

    set_mail_account() function lets you set the identities of the POP and SMTP mail servers that you want the mail daemon to use, and lets you set the (user-specific) POP account that the daemon should monitor (when it looks for in-coming mail). All this information is set by filling in the fields of the mail_account structure which you pass as the first argument to the function. The structure is defined as

       typedef struct
       {
           char pop_name[B_MAX_USER_NAME_LENGTH];
           char pop_password[B_MAX_USER_NAME_LENGTH];
           char pop_host[B_MAX_HOST_NAME_LENGTH];
           char smtp_host[B_MAX_HOST_NAME_LENGTH];
       } mail_account;

    The save argument sets the persistence of the mail account:

    You can set the default mail account even if the mail daemon isn't running. Currently, the set_mail_account() function always returns B_NO_ERROR .

    get_mail_account() returns, by reference in its argument, a copy of the mail account information that the daemon is currently set to use. If the daemon isn't running, this function returns the default mail account. In this case, the function returns B_MAIL_NO_DAEMON, otherwise it returns B_NO_ERROR.

    Note that the validity of the mail_account that you pass to set_mail_account() or that's copied into the get_mail_account() argument isn't checked by these functions. The mail account is only checked when you actually attempt to use the information; in other words, when you attempt to send or retrieve mail.


    set_mail_notification(), get_mail_notification()

          long set_mail_notification(mail_notification *notification, bool save = TRUE)
          long get_mail_notification(mail_notification *notification)

    set_mail_notification() establishes how you would like to be notified when new mail arrives. There are two notification signals: the mail alert panel and the system beep. You encode your preference by setting the fields of the argument mail_notification structure:

       typedef struct
       {
            bool alert;
            bool beep;
       } mail_notification;

    The save argument, if TRUE, registers the notification setting as the default--in other words, the daemon will remember it when you shutdown the computer. This function always returns B_NO_ERROR.

    get_mail_notification() returns, by reference, a copy of the mail_notification structure that's currently being used by the mail daemon. If the daemon isn't running, the function hands you the default notification setting, and returns (directly) B_MAIL_NO_DAEMON ; otherwise it returns B_NO_ERROR.


    set_mail_reader(), get_mail_reader()

          long set_mail_reader(ulong reader_sig, bool save = TRUE)
          long get_mail_reader(ulong *reader_sig)

    set_mail_reader() tells the system which application to launch (or find) to display newly- arrived mail. The application is identified by its signature. The save argument, if TRUE, registers the reader signature as the default--in other words, the daemon will remember it when you shutdown the computer. This function always returns B_NO_ERROR ; note that the function doesn't check to make sure that the argument identifies an actual application.

    get_mail_reader() returns, by reference, the signature of the application that the mail daemon is currently using (or will next use) to display mail. If the daemon isn't running, the function hands you the default reader, and returns (directly) B_MAIL_NO_DAEMON ; otherwise it returns B_NO_ERROR.

    In the absence of any other provision, the mail daemon uses the Be mail reader, BeMail (signature 'MAIL').


    set_mail_schedule(), get_mail_schedule()

          long set_mail_schedule(mail_schedule *schedule, bool save = TRUE)
          long get_mail_schedule(mail_schedule *schedule)

    set_mail_schedule() lets you tell the mail daemon during what days and hours it should automatically check for new mail, and how often it should check. You encode this information by filling in the fields of the argument mail_schedule structure:

       typedef struct
       {
          long  days;
          long  interval;
          long  start_time;
          long  end_time;
       } mail_schedule;






    The Be Book, HTML Edition, for Developer Release 8 of the Be Operating System.

    Copyright © 1996 Be, Inc. All rights reserved.

    Be, the Be logo, BeBox, BeOS, BeWare, and GeekPort are trademarks of Be, Inc.

    Last modified September 6, 1996.