*Syntax10.Scn.Fnt ZStyleElemsAlloc HeaderSyntax24b.Scn.Fnt Syntax14.Scn.Fnt%Syntax14b.Scn.Fnt09 IStampElemsAlloc1 Jun 99Syntax12.Scn.Fnt Z`= Header1MarkElemsAlloc:Syntax16b.Scn.FntSyntax12b.Scn.Fnt ZText1WebElemsAllocLinkmailto:tanis@sport1.uibk.ac.at`= Header1ue  Header2  Text2  ou FirstIndent2Syntax10b.Scn.Fnt Syntax10i.Scn.Fntc  Text2I Z` Header3; Z Text3  Ze  Header2/T Z  Text27  Ze  Header2d Z  Text2 u u  Z` Header3; Z Text3 P\ParcElemsAllocАY Ze  Header2d Z  Text2 3 !e  Header2 + Z  Text2 Zu   S Z  Text2, Zu  Ze  Header2  Z  Text2a @  Ze  Header2  Z  Text2A    F   Ze  Header2  Z  Text2< ' Ze  Header2  Z  Text2y o  Ze  Header2  Z  Text2c  Z`= Header1Z ZText1 Ze  Header2{}$ Z  Text2pVersionElemsAllocBeg#Syntax10.Scn.FntPage1 Page2 Page3 Page1Page1 Page2Syntax10.Scn.Fnt p89Pb%PanelElemsNewNameCmdAddrBookGUI.InitPage2Par5Syntax10.Scn.Fnt*@ TextFieldElemsNewNameorganizationCmdPar @B@ StaticTextElemsNewNameCmdParAddress@B@ NameCmdParTitle@B@ NameCmdParOrganization*@ NametitleCmdPar *@ NameaddressCmdPar   ButtonElemsNewNamePage3CmdAddrBookGUI.Page3Par-> @ NamezipCmdPar U"@ NamecityCmdPar @B@ NameCmdParZip / City*@ NamestateCmdPar *@ NamecountryCmdPar *@ NameworkPhoneCmdPar *@ NamehomePhoneCmdPar *@ NamefaxCmdPar @B@ NameCmdParState@B@ NameCmdParCountry@B@ NameCmdParPhone@work@B@ NameCmdParPhone@home@B@ NameCmdParFax  NamePage1CmdAddrBookGUI.Page1Par<- y3a[[ [ [ [y [J[3[a [aJBPage3/Syntax10.Scn.Fnt p89Pb%PanelElemsNewNameCmdAddrBookGUI.InitPage3ParSyntax10.Scn.Fnt@B@ StaticTextElemsNewNameCmdParNotes  ButtonElemsNewNamePage2CmdAddrBookGUI.Page2Par<-A<7LTextAreaElemsNewNamenotesCmdParsSyntax10.Scn.Fntl3ParcElemsAllocА*ClockElemsNew,Notes can contain elements themselves ...   p89Pb%PanelElemsNewNameCmdAddrBookGUI.InitGUISyntax10.Scn.Fnt/@ TextFieldElemsNewNamecurName  @ ButtonElemsNewNameParCmdAddrBookGUI.ToAdrTo @ NameParCmdAddrBookGUI.ToGroupTo @ NameCmdAddrBook.AddGroupPar%groups.ValueAdd @ NameCmdAddrBookGUI.EditGroupParApplyIIRadioButtonElemsNewNameSortOrderCmdAddrBookGUI.SetOrderrealreal@B@ StaticTextElemsNewNamenick nameIINameSortOrderCmdAddrBookGUI.SetOrderrealnick @ NameCmdAddrBook.LoadLoad 0NameAddressesu Namereal name%ListElemsNewNameaddressesCmdAddrBookGUI.SetAdrSelStringAAAPar Z @ NameCmdAddrBook.DeleteGroupPar%groups.ValueDelete|`[NamegroupsCmdAddrBookGUI.SetGroupPar#Syntax10.Scn.Fnt* #Syntax10.Scn.Fnt* @ NameCmdAddrBookGUI.DeleteDelete @ NameCmdAddrBook.StoreStore @ NameCmdAddrBookGUI.EditParApply @ NameCmdAddrBookGUI.AddParAdd@B@ Namee-mail@B@ NameNickname@B@ NameName/@ NamecurNick @ NameCmdParGroups/@ NamecurEmail   NamePage2CmdAddrBookGUI.Page2Par-> / q<G] <]<Gz  4$yy <<< BB pVersionElemsAllocEndS  Ze  Header2{} Z  Text2H "  Z`= Header1Ą ZText1 Ze  Header2ք Z  Text2a  Ve  Header2  Text27 e  Header2f Z  Text2@ Courier10.Scn.Fnt+      /    w ! # 04 : (   Z` Header3M& Z Text3  .   1  Z` Header3; Text3I  *  4   8 8  G  Y l 1   Z` Header3; Z Text3   Z` Header3R Z Text30 -  Z` Header3R Z Text3 Z`= Header1Ą ZText1 Ze  Header2ք Z  Text2 Ze  Header2ք Z  Text2 Ze  Header2ք Z  Text2 Z` Header3R Z Text38 FoldElemsNew#Syntax10.Scn.Fnt]] Mailfile = {Header Message}. Header = F703 status4 . Message = textblocklen4 textblock . 8   Z` Header3R  Z Text3X  !r  0 Z` Header3R  Z Text3e  Header2ք  Text2` Header3R Text3h  M M` Header3R Text3h \` Header3R Text3` Header3R Text3СА   1 Jun 99 c Mail Tool A Mail Client for the Oberon System User's Guide & Implementation Robert Lichtenberger    1 Introduction Oberon Mail is an easy to use, yet powerful application to administer your electronic mails. You can receive and send mails, add signatures, add attachments as well as Oberon texts, etc. Oberon Mail was originally written by Christian Warlischek & Richard Mohr. The current version has almost completely been rewritten. The address book mechanism has been completely rewritten and is now equipped with a GUI. All questions, bug reports, suggestions etc. should be addressed to Robert Lichtenberger.  2 Using the Mail Client  2.1 Sending a mail Mails can be sent, by executing Mail.SendNew. You can specify recipients, subject, cc, bcc and attachments at the command line by passing them as Strings. Example: Executing 'Mail.SendNew "list@report.heaven.org" "Bug Report" "tanis@sport1.uibk.ac.at" "" "PostOffice.Mod"' will open a viewer with recipient 'list@report.heaven.org', cc 'tanis@sport1.uibk.ac.at', empty bcc (blind carbon copy, i.e. normal recipients don't see, you were getting this message), subject: 'Bug Report' and one attachment, the file 'PostOffice.Mod'. More than one recipient/attachment can be specified by space-seperated lists. After opening the message viewer with SendNew any kind of message can be entered, including Oberon text elements, different fonts, colors, etc. Pressing the Send button in the menubar of the viewer will try to send the message. Message sending is done in the background, so the viewer will disappear immediately. If for any reasons the sending fails completely (i.e. the message could not be delivered to even one of the recipients) the viewer containing the message will reappear. If the 'Send' key in Mail.Profile contains the value Delayed then no standard sending method is installed. Instead an external AddOn (e.g. MailQ) has to provide that functionality. Mails are sent as plain text, if they do not contain special characters or text elements and if they are completely written in the default font. Mails are sent as iso-8859-1, quoted-printable MIME messages, if they contain no text elements and if they are written completely in the default font. Otherwise, mails are sent as multipart/alternative MIME messages, offering a plain-text, an HTML-version and an Ascii-Coded version (application/x-oberon) of the message. You can also send a mail as quoted-printable US-Ascii only, regardless of its contents. To do so execute Mail.SendAscii instead of Mail.Send.  2.1.1 MailQ The Add-On module MailQ serves two purposes: It can archive outgoing mails and provides a way of delayed sending of outgoing mails. By adding MailQ to the list of Add-On modules in Mail.Profile every outgoing mail is stored as text under /Out or in the mailbox named out.mbx. You can specify which of these storage options should apply when using MailQ by using the key MailQStore in Mail.Profile. MailQStore can contain Text (stored as text in /Out), Box (stored in out.mbx) which is the default or Both for both methods. Note that you have to use option Text (or Both) to use delayed sending of messages. MailQ also remembers which files in the Out/ directory are new mails. By launching MailQ.Send [start end] all such mails are sent. MailQ.Send can be given two integer parameters start and end. It will then send all mails named /Out/Mailxxx.Text, where start <= xxx <= end. A useful configuration for Dial-Up IP (SLIP / PPP) users would therefore be to set the 'Send' key to delayed and add MailQ to the add-on list. When an IP connection is established, MailQ.Send will send all mails stored in the queue.  2.2 Create a new mailbox To create a new mailbox in your mailbox folder execute Mail.Open . The extension .mbx is appended to mailboxname, if needed. The files for your mailboxes are held in the directory given under the key in Mail.Profile.  2.3 Receiving mails Execute Mail.CheckNew to see if new Mail has arrived. The poller will be turned on, if specified so in Mail.Profile. To get new mail use Mail.FetchNew. Mail.FetchNew will call installed receivers (cf. AddOn key in Mail.Profile). If no receiver is specified Mail will default to the default action: Storing mails in the Mailbox specified by the key from the Mail.Profile. The entry in Mail.Profile specifies whether Mails are removed from the POP server after download or not. Be aware that turning the Poller on and specifying COPY as PollerAction is not a brilliant idea: New mails will be constantly copied to the . If you want to check mail for a pop account other than the one specified under the key in Mail.Profile you can execute Mail.SetUser . You will be prompted for a password. Attention! Your password is remembered in transient memory, i.e. it is not stored to disk. However using System.State one can get an array which contains your password in a very weakly encrypted form.  2.3.1 Filter Filter is a very simple e-Mail filter, that allows to automatically distribute incoming mail. Upon startup (or upon execution of Filter.UpdateProfile) it reads the content of Filter.Profile (located in your mDir) and builds a list of header fields, keyword and corresponding mailbox. If new messages arrive, the given header field is checked against all entries in the list and if a mail matches it is stored in the corresponding mailbox. The EBNF of Filter.Profile is: Profile = {HeaderField Keyword Mailbox}. HeaderField = string | name. Keyword = string | name. Mailbox = name. Keywords may contain wildcards. Example of Filter.Profile: Subject "[MyListPrefix]*" myList Subject "*bug*" oberonBugs From "badguy@foo.org" trash  2.4 Reading mails Open the mailbox with Mail.Open []. If you do not specify a mailbox, the default in-box is opened. A viewer is displayed, showing the contents of your mailbox. The column sizes of this viewer can be configured by the 'MailboxParc' key in Mail.Profile. You can read a message by selecting its number with the right mouse button and executing Mail.Show from the mailbox menu. Alternatively you can click on the message using the middle mouse button. Read messages appear black in your mailbox, whereas unread messages are red. For a quick look into small mails you can also interclick MM+MR. This will pop up a balloon showing the content of the mail. No processing of any kind (MIME, character sets, etc.) is performed when peeking at mails. MIME Attachments are indicated by popup elements. Clicking such a popup element with the middle mouse button causes the Mail tool to extract the attachment. If you want to change the filename interclick with the right mouse button. You can forward or reply to a mail by clicking the corresponding menu entry from the menu. The contents of the mail will be quoted, i.e. a ">" character will be put in front of each line. By clicking 'ReplyAll' in the menu entry you can send a reply to a message which is also sent to the carbon copy recipients of the original mail. The key 'HeaderLength' in Mail.Profile determines whether the mail's headers are displayed or not.  2.5 Copy / Move mails between mailboxes You can copy and move mails between mailboxes in four different ways. Two ways start by opening the source and destination mailbox using Mail.Open. The following two methods can then be used: * Place the caret in the destination mailbox, select the number of the mail you wish to copy or move in the source mailbox and select Mail.Copy or Mail.Move from the menu. * Drag the message you wish to copy or move by pressing the middle mouse button above the message and dragging it into the destination mailbox viewer. If you interclick the right mouse button, the message will be copied. If you do not interclick, the message is moved, i.e. it is marked for deletion in the source mailbox. You can also use one of the following ways: * Drag the message you wish to copy or move and drop it over the name of a mailbox. Again interclicking with right mouse button will copy the message. * Click a message with middle mouse button and hold the mouse button (without moving the mouse). A popup menu will appear, containing all your mailboxes. Selecting one of the entries in the popup will move the clicked message to the mailbox. There is no way of copying mails in this way.  2.6 Deleting mails You can delete mails by selecting a number of messages with the right mouse button and selecting Mail.Delete from the menu. This process can be undone analogously by using Mail.Undelete. Deleted mails are displayed blue. They are physically deleted when you store the Mailbox, using Mail.Store from the Menu. You can also delete/undelete mails by selecting them with the right mouse button and interclicking left or middle button respectively.  2.7 Sorting mails You can sort your mailbox by subject, sender or size by clicking Mail.SortBySubject, Mail.SortBySender, Mail.SortBySize, Mail.SortByDate or Mail.SortByStatus in the menu. You can also specify a sort order by using the commands Mail.SortAscending and Mail.SortDescending. The default sort order is specified in Mail.Profile under the key SortOrder. If SortOrder is missing it defaults to ascending.  2.8 Importing mailboxes Mails can be imported from mail files, by using the command Mail.ImportMailbox . describes a file which contains at least one mail in plain ASCII format. is the name of the Oberon mailbox. Please note that both parameters are required.  2.9 Searching in mailboxes You can search for textual patterns in your mailbox. If you want to search within the Mailbox viewer's content only, use Edit.Search from the menu. To search through all mails in you mailbox mark the pattern you want to search for and execute Mail.Search from the menu. This will popup a new mailbox viewer called Search which will contain a copy of the mails in which the pattern could be found. If you launch Mail.Search from a command line then all mailboxes are searched.  2.10 Storing mailboxes Your mailbox's state (i.e. the state of the messages contained therein) can be stored by launching Mail.Store from the menu. Mails marked for deletion will be permanently removed. Messages themselves are stored automatically upon reception. Mail.Store only stores the state (read / unread) of the mails contained in a box and reorganizes the mailbox by removing deleted Mails permanently. Closing a mailbox viewer does not affect the state of a mailbox. If you quit Oberon or unload the mail tool however, the changes will be lost.  3 Addressbook Your Addressbook is managed by the modules AddrBook and AddrBookGUI. You can use the command interface of AddrBook or use the AddrBook.Panel. The AddrBook command interface is documented in AddrBook.Mod, using balloon elements.  3.1 The graphical User Interface    The GUI is opened by executing the AddrBook from the Sendmail Menu or by executing Panel.Open AddrBook.Panel . The addresses are loaded automatically. However you have to explicitly store changes done to the address book using the Button Store. You can also load the latest version of your addresses using the button Load. The lower part of the GUI is concerned with addresses. You can add new addresses by filling out the Name, Nickname and e-mail fields and clicking Add. Name and Nickname have to be unique. You can also edit an existing address by clicking (MM) the address list in the upper right corner of the GUI. The address is then copied into the fields Name, Nickname and e-mail. You can do the changes and complete the operation by pressing the Apply Button. Deleting an address is done anologously, using the delete button. Groups can be added, edited and deleted the same way using the buttons and the combo box in the upper left corner. The check boxes in the address list can be used to add or remove an address to the currently selected group. If the selected group is *, then clicking the box has no effect. If a group is active, the entries in the address list are sorted so that group members appear first in the list. The sorting order can be further influenced using the radio buttons real name and nick name in the upper right corner of the panel. The two To buttons add a group or single address to the mail message the caret is currently in. The caret has to be positioned on one of the lines To:, Cc: or Bcc: in the mail message. If this is not the case a new message will be opened.  3.1 Importing address data You can import address data from Eudora and Netscape using the commands AddrBook.ImportNetscape and AddrBook.ImportEudora .  4 Utilities & Setup  4.1 Poller The poller browses your mail-server for new mails. You can turn the poller on / off by executing Mail.PollerOn or Mail.PollerOff. You will be prompted for a password when turning the poller on. The entry specifies what the poller should do: It can copy mails, move mails or just check for new mails. Be aware that copying all mails every other minute may fill up your harddisk. The entry specifies the time in seconds between two polls.  4.2 Signature To create a signature, you have to execute the command Mail.CreateSign of the Utils-Menu in the toolbar. This will open a signature editing viewer. Every time you open a new message viewer the signature will be added at the end of your message.  4.3 Profile The configuration file "Mail.Profile" has the following format: <--- Network configuration ---> POPServer="Pop-Server" SMTPServer="SMTP-Server" Domain="Domain" POPUser="Pop account name" <--- General Settings --------> Reversepath="user@host" Signature="filename" MakeWebLinks=[YES|NO] HeaderLength=[NONE|FULL|FOLDED] Poller=[ON|OFF] PollerAction=[CHECK|COPY|MOVE] PollerIntervall="seconds" Send=[IMMEDIATE|DELAYED] AddOn={"add-on module" " "} SortOrder=[ASC|DESC] MailboxParc="parc with tab stop positions" <--- MIME --------------------> MIMEDelimiter=any text or element used for delimiting mime parts <--- MailQ -------------------> MailQStore=[Box|Text|Both] <--- Directories -------------> inBox="InBox.mbx" mDir="$MailboxSubdir"  4.3.1 Network configuration Oberon Mail needs to know how it should get your new mail, and how it should send your outgoing messages. Your Internet Service Provider will be able to give you this information. There are a few questions: * What is the address of your POP3 server? (POPServer) * What is the address of your SMTP server? (SMTPServer) * What is your Domain? (Domain) * What is the login name of your pop-account? (POPUser)  4.3.2 General settings * What is the address of your reversepath (usually your email-address)? (Reversepath) * Which file should be your Signature? (Signature) * Which kind of Header Style do you want to use? (HeaderLength) - NONE: No header will be displayed - FULL: Full header will be displayed - FOLDED: Header will be displayed, but collapsed in fold elements. * Start up Poller automatically, if a password has been given? (e.g by Mail.CheckNew/Mail.SetUser) (Poller) * Should all occurences of http://... be enclosed by Web-LinkElems (MakeWebLinks) * Should mail be sent immediately or delayed by an external add-on module, like MailQ (Send) * Which modules should be loaded (to allow them to set Mail.receiver or Mail.sender) when starting mail? (AddOn) * Tab stop positions for display of mailboxes (MailboxParc)  4.3.3 MIME The entry MIMEDelimiter may contain one line of text, which is used as seperator for parts of MIME - messages. It is strongly recommended to use LineElems here.  4.3.4 Directories and Files * Into which file should incoming mail be put? (inBox) * Subdirectory to put all mailboxes into? (mDir)  4.3.4 Web Integration The mail tool can be integrated into the Web - Browser, implementing the mailto: protocol. This is done at module load time. To ensure Mail is loaded whenever the Web Browser is used, open Web.Profile and add the entry Mail to the key of the Profile.  5 Implementation   5.1 Overview The Mail - Tool consists of two major parts: * The Address-Book: This again can be divided into the backend (AddrBook.Mod) and GUI (AddrBookGUI.Mod) * The Mail-Tool itself: The mail tool consists of three Modules: * PostOffice: Backend handling communication with servers, mailboxes, parsing mails, etc. * Mail: Front-end containing all relevant commands. * MIME: Extensible implementation of the 'multipurpose internet mail exchange' standard.  5.2 Address-Book The Address-Book is implemented as linked lists. Notifiers (Notifier) may be installed which are called, whenever a change occurs in the Address-Book. Notifiers are passed an address notification (AdrNotify) or a group notification (GroupNotify) object, depending on the kind of event. The field 'op' of notification indicates the kind of operation just performed on the Address-Book. Enumeration mechanisms (EnumerateGroups, EnumerateAdrReal, EnumerateAdrNick, EnumerateAdrGroup) allow iteration over the data. These mechanisms are used to print various lists of addresses (ListNick, ListReal, ListGroup). Both import filters (Netscape, Eudora) use simple parsing techniques. The exact programming interface is documented by balloon elements.  5.3 Mail - Tool  5.3.1 Post-Office The module PostOffice handles mails and mailboxes and is responsible for communication with servers using TCP, SMTP and POP protocols. Mails are written into a mailbox-file which is parsed when the mailbox is loaded. Mailbox file format:  The messages themselves are not kept in memory, they are loaded from hard disk on demand. Only the offset of the message within the mailbox file as well as its size, header fields, current status (read/unread, deleted), etc. is kept in memory All loaded mailboxes are held by PostOffice in a linked list. To access a mailbox use the procedure GetBox(boxname, box). It will load the box if needed. Each mailbox has a circular list of mail objects, containing at least one object (sentinel). Each mail has a key, sender, subject and reply-address, size of the message, its status (read/unread, deleted), its offset in the mailbox-file, a description of its header (see below) and offset of the mail body within the text of the mail. A mailbox can be sorted by calling box.Sort, passing a procedure which compares two mails and returns one of the constants less, equal or greater. To get the complete text of a mail, use box.GetText(mail.key, T). To get a mail by number use box.GetMailByNr(nr, mail); Header objects are used to represent the complete header of a mail which may be used by extensions to the mail tool, such as MIME. Headers are linked lists and contain a name and a body in each node. The name contains the name of the header field without colon. (such as From) The body contains the content of the header field, from the first character after the colon which is neither 'space' nor 'tab' to the first carriage return. The procedure ParseMail can be used to parse a text and update a mail object's sender, subject, reply and header fields. This is not necessary when using GetMailByNr. The Procedure BuildHeader takes a Texts.Reader and creates a complete header object. Headers use strings of varying length to reduce memory consumption. Note that mail objects contain a redundancy: The fields sender, subject and reply are contained within header. They are doubled for convenience reasons. To extract a certain line from a header use head.GetHeaderField. To extract a parameter (as defined in RFC2045) from a header use head.GetParameter. To send a mail call SendInBackground. Parameter T specifies a text containing a complete message (including header fields). to, cc, and bcc specify the recipients of the message. doneProc contains a notification procedure that is called, when the sending process has ended. This procedure will be passed a boolean parameter, indicating the success of the operation, an error (or success) message to be displayed and optionally the viewer and buffer passed to SendInBackground to allow the mail client to restore the viewer in which the user wrote the message. The notification procedure must be prepared for any of the two parameters (viewer or buffer) to be NIL, since SendInBackground may also be called without viewer/buffer. To check for new mails use box.FetchNew. Importing a mailbox can be done by calling ImportMailbox. A complete documentation of the interface of PostOffice is given in form of BalloonElems.  5.3.2 Mail The module Mail is the front end of the mail application by providing a command interface described in 'Using the mail client'. Mail handles MailboxFrames, allowing to drag and drop messages (procedure TrackMR) as well as providing a special "text selection" behaviour, which allows to select complete lines only. MailboxFrames also react upon PostOffice.NotifyMsg adjusting the color of mails according to their state. Mail also registers the 'mailto:' protocol for the web browser. Two parsing procedures (ParseRecipients, ParseAttachments) are provided to allow retrieval of information from messages to send. Mail also provides a poller in form of an Oberon.Task which will periodically poll for new mail at the POP server, if turned on. Signature handling and import of mailboxes are provided by Mail. Mail allows e-mail filtering by installing up-call procedures in Mail.receiver. If no other receiver is installed mail installs a default action. Mail needs / handles a number of text files: * MailBox.Menu.Text: The menu displayed for mailbox viewers. * MailSend.Menu.Text: The menu displayed for viewers containing new messages (to send) * Mail.Menu.Text: The menu displayed for viewers containing received messages * SendNew.Text: The header for new messages. (Must contain To:, cc:, bcc:, Subject: and Attach.: as well as LineElem) * Signature-File: Depending on the entry in Mail.Profile A complete documentation of the interface of Mail is given in form of BalloonElems.  5.3.3 MIME MIME is an extensible implementation of the multipurpose internet mail exchange standard as defined in RFC2045 - RFC2049. MIME provides a generic content handler mechanism which allows to install content handlers for various content types. It also provides functionality for parsing MIME header lines and multipart MIME boundaries. For textual contents a charset mechanism allows extensible conversion to Oberon's charset. Finally a set of content handlers is implemented which satisfies today's common content types: * plain text (us-ascii and iso-8859-1 character sets) * HTML - mails, including mails with inline pictures by implementing a new web loader for cid: - URLs * mixed multipart mails * alternative multipart mails (e.g. used when a message is sent as plain text as well as HTML) * Images (all kinds of images that are supported by PElems) * attachments * Special handler for Oberon Ascii-encoded data. Mails are sent as MIME multipart alternative providing a plain text, a HTML and a ascii-encoded Oberon version. The latter allows users of the Mail-Tool to exchange full featured Oberon texts without any loss of information. To extend MIME for new media types one simply calls AddContentHandler and passes the type of media to handle as well as a handler. To extend MIME for new character sets one simply calls AddCharsetProc and passes a Charset object which describes the charset and contains a conversion procedure. A complete documentation of the interface of MIME is given in form of BalloonElems.  5.4 Implementing extensions The Oberon Mail Tool is implemented in an extensible way. You may add functionality by using the framework-like mechanisms of the tool.  5.4.1 MIME-Types You can add new MIME type handlers by calling MIME.AddContentHandler. Two parameters must be given: * contentType contains the name of the MIME type you want to handle (e.g. "text/x-foo") * handler contains the procedure which shall handle MIME documents of the given type.  5.4.2 MIME character sets You can add new MIME character set translation procedures by calling MIME.AddCharsetProc. The parameter cs is a procedure which receives a character and translates it into the oberon character set.  5.4.2 Sender By assigning Mail.sender to a procedure of type PostOffice.Sender you can add specific actions to be performed when mails are sent. Module MailQ uses Mail.sender to save outgoing Mails to the Out/ - directory. Warning! If the installed procedure does not actually send the mail it must call the old Mail.sender to assure the mail is sent. If a Mail.sender implements a protocol different from SMTP it may decide to not call the old Mail.sender.  5.4.4 Receiver By assigning Mail.receiver to a procedure of type PostOffice.Receiver you can add specific actions to be performed when new mail arrives. Module Filter uses Mail.receiver to distribute incoming mails to different mailboxes. Warning! If the installed procedure does not do anything special with the incoming mail it must call the old Mail.receiver so that the mail is at least stored in the default mailbox. If a Mail.receiver does not do so, mails may be lost. Robert Lichtenberger,