diff options
author | Eduardo Chappa <echappa@gmx.com> | 2013-02-03 00:59:38 -0700 |
---|---|---|
committer | Eduardo Chappa <echappa@gmx.com> | 2013-02-03 00:59:38 -0700 |
commit | 094ca96844842928810f14844413109fc6cdd890 (patch) | |
tree | e60efbb980f38ba9308ccb4fb2b77b87bbc115f3 /imap/docs/internal.txt | |
download | alpine-094ca96844842928810f14844413109fc6cdd890.tar.xz |
Initial Alpine Version
Diffstat (limited to 'imap/docs/internal.txt')
-rw-r--r-- | imap/docs/internal.txt | 2988 |
1 files changed, 2988 insertions, 0 deletions
diff --git a/imap/docs/internal.txt b/imap/docs/internal.txt new file mode 100644 index 00000000..203688e8 --- /dev/null +++ b/imap/docs/internal.txt @@ -0,0 +1,2988 @@ +/* ======================================================================== + * Copyright 1988-2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * + * ======================================================================== + */ + + Documentation of c-client Functions and Interfaces + +REVISED: 19 August 1996 + + Credits + + The original version of this document was written by Mark Crispin at +the University of Washington, and described the version of c-client that +supported the IMAP2 (RFC 1176) and IMAP2bis (unpublished) protocols. + + This version is a substantial rewrite of that document, and was +written by Mark Crispin with funding from Sun Microsystems, Incorporated. +Sun's generous support of this work is gratefully acknowledged. + + + Road Map + + This document is organized into the following sections. Except as +noted, an implementor of an application that uses c-client needs to be +familiar with all of these sections. Someone who plans to write a new +mailbox driver for c-client (or otherwise modify it) needs to be familiar +with all sections, no exception. + +History + History of how c-client came about. + +Overview + Read this before designing an application that uses c-client. + +c-client Structures + Documentation of several important c-client structs which are + used in, and returned by, c-client calls. + +String Structures + Documentation of the concept of a "string structure", which + provides random access to strings without requiring that the + string be in memory. + +c-client Support Functions + Documentation of support functions for c-client; these deal + with c-client functionality. + + Only mail_parameters() is of interest to most application + developers. Advanced application developers, particularly + for limited memory systems, may also need to know about the + readfn_t, mailgets_t, mailcache_t, and tcptimeout_t function + pointer types, and possibly also the mail_valid_net_parse() + function. + +Mailbox Access Functions + Documentation of functions which deal with mailboxes; + listing, subscribing, creating, deleting, renaming, status + inquiries, opening, and closing mailboxes. + +Handle Functions + Documentation of mail stream handles, which provide protection + for an advanced application which may have multiple pointers to + a single mail stream. If a stream has a handle on it, closing + the stream does not release its memory, so pointers to it in + the application remain valid. Freeing the last handle will free + the entire stream. + + This is only of interest for advanced application developers. + +Message Data Fetching Functions + Documentation on message data fetching in an open mailbox, + including parsed representations of RFC-822 and MIME headers + and message text. Also how to fetch message attributes (flags, + internal date, sizes). + +Message Status Manipulation Functions + Documentation on altering message flags in an open mailbox. + +Mailbox Searching + Documentation on searching an open mailbox for messages which + match certain criteria (e.g. "messages sent July 4 from Jones + with text `Paris'"). + +Miscellaneous Mailbox and Message Functions + Documentation on other operations that would be used by an + application but that don't fit into any of the above categories. + +Date/Time Handling Functions + Documentation on functions that deal with date/time strings. + + This is only of interest for advanced application developers + and for implementors of new c-client drivers. + +Utility Functions + Documentation on internal utility functions. + + This is primarily of interest for implementors of new c-client + drivers, but advanced application developers may also use some + of these functions. + +Data Structure Instantiation/Destruction functions + Documentation on creating and destroy c-client structures. + + This is primarily of interest for implementors of new c-client + drivers. However, application developers will need some of + these functions to create and destroy structures which are used + as arguments to various application functions. + +Authentication Functions + Documentation on support for network protocol authentication + functions. + + This is only of interest for implementors of new c-client + drivers which deal with authentication mechanisms. + +Network Access Functions + Documentation on creating and destroy c-client structures. + + This is primarily of interest for implementors of new c-client + drivers which deal with a network. However, advanced + application developers may need to use this information if they + wish to insert their own layer into a network session. + +Subscription Management Functions + Documentation on managing the local (client-based) subscription + database file. + + This is primarily of interest to advanced application developers. + +Miscellaneous Utility Functions + Documentation on various useful utility functions, such as "make + a copy of this string." + +SMTP Functions + Documentation on posting email messages via SMTP protocol. + +NNTP Functions + Documentation on posting netnews messages via NNTP protocol. + +RFC 822 Support Functions + Documentation on public RFC-822/MIME functions. + + This is primarily of interest for implementors of new c-client + drivers and advanced application developers. + +Operating System-Dependent Public Interface + Documentation on OS-dependent functions. With the exception of + fs_get(), fs_give(), and fs_resize(), which should be called + instead of malloc(), free(), and realloc(), these functions are + primarily of interest for implementors of new c-client drivers. + +Main Program Callbacks + Documentation of functions which the main program must provide + as callbacks from c-client. + +Driver Interface + Documentation of the driver dispatch vector and the functions + which a driver must supply. + + This is primarily of interest for implementors of new c-client + drivers. + +Driver Support Functions + Documentation of support functions which are called by drivers. + + This is primarily of interest for implementors of new c-client + drivers. + History + + The c-client API was originally written by Mark Crispin at Stanford +University as a set of routines to support IMAP and SMTP from a main +program which would handle the user interface. In its original form, it +was written as the low-level routines that were to be used as part of a +Macintosh client. + + The first IMAP client, MM-D (for "MM on Xerox D machines" -- MM was a +popular DEC-20 mail program) was written in Interlisp for Xerox Lisp +machines. At that time, there was no name for the embryonic Mac client, +but since it was the first one to be written in C instead of Lisp, it was +given a development name of "C client". This name became "c-client" +because that is the name of the subdirectory on UNIX where the source files +were stored. + + To exercise the routines, a minimal main program which uses c-client, +mtest, was written. mtest has subsequently been extended so that it runs +on every platform that c-client is ported. + + The real Mac client, was eventually written by Frank Gilmurrary and +Bill Yeager at Stanford using the autumn 1988 version of c-client and named +"MacMS". In the winter of 1988-89, Mark Crispin, who had changed jobs to +the University of Washington, developed MS as an MM-like text-based program +for UNIX and MailManager as a GUI-based program for NeXT machines. + + The realization sunk in that this API needed its own name. As early +as spring 1989, there were at least four programs (mtest, MS, MailManager, +and MacMS) that used it. The name c-client thus became permanent. + + In its history, c-client has undergone two major redesigns, both by +Mark Crispin who is now on the staff at the University of Washington. + + The first major redesign added the following: + 1) ANSI C calling conventions throughout to assist in function + argument type checking. + 2) Vectoring mail access calls through "driver" methods; thus + providing transparent access to multiple types of mail + stores with the same call. + 3) MIME support. + + The second major redesign was part of the IMAP4 project. Many +c-client functions were extended with additional arguments and options. +The driver interface was also made simpler, with more work done by +driver-independent code. + + Overview + + The most important file for the author of an application using the +c-client is mail.h. mail.h defines several important structures of +data which are passed between the main program and the c-client. +Although some functions (e.g. mail_fetchtext_body()) return the data +fetched, for certain other data items (e.g. flags) you need to get the +data as a structure reference. mail.h also defines a large number of +useful constants and structures. + + When a function in mail.h exists to reference data, it MUST be +used instead of referencing the structures directly. This is because +in some cases the data is not actually fetched until a reference (via +the function call) is made. For example, although the MESSAGECACHE +element for a message can be obtained by indexing the proper cache +element in the stream, there is no guarantee that the item in fact +exists unless mail_fetchstructure_full() is called for that message. +Less costly functions. also exist to create and load a MESSAGECACHE +element. + + The main program will probably also need to include smtp.h, +misc.h, and osdep.h, but this usage should be solely to receive +function prototypes. Any other definitions in those files should be +considered private to that module. + + Two important predefined symbols are NIL and T. NIL is any sort +of "false"; T is any sort of "true". NIL is also used to null-specify +certain optional arguments. + + * * * IMPORTANT * * * + + Any multi-threaded application should test stream->lock prior to +calling any c-client stream functions. Any attempt to call a +mail_xxx() function while one is already in progress on the same +stream will cause the application to fail in unpredictable ways. + + Note that this check is insufficient in a preemptive-scheduling +multi-tasking application due to the possibility of a timing race. +Such applications must be written so that only one process accesses +the stream, or to have a higher level lock. + + Since MAIL operations will not finish until they are completed, a +single-tasking application does not have to worry about this problem, +except in the callback invoked from MAIL (e.g. mm_exists(), etc.) in which +case the stream is *always* locked. + + c-client Structures + + c-client has a large number of structures which are used for +multiple functions. The most important of these are described here. + + The MAILSTREAM structure is used to reference open mailboxes. +Applications may reference the following: + +char *mailbox; mailbox name +unsigned short use; stream use count, this is incremented +unsigned short sequence; stream sequence, this is incremented + each time a stream is reused (i.e. + mail_open() is called to open a + different mailbox on this stream) +unsigned int rdonly : 1; stream is open read-only +unsigned int anonymous : 1; stream is open with anonymous access +unsigned int halfopen : 1; stream is half-open; it can be + reopened or used for functions that + don't need a open mailbox such as + mail_create() but no message data + can be fetched +unsigned int perm_seen : 1; Seen flag can be set permanently +unsigned int perm_deleted : 1; Deleted flag can be set permanently +unsigned int perm_flagged : 1; Flagged flag can be set permanently +unsigned int perm_answered :1; Answered flag can be set permanently +unsigned int perm_draft : 1; Draft flag can be set permanently +unsigned int kwd_create : 1; new user flags can be created by + referencing then in mail_setflag() or + mail_clearflag(). Note: this can + change during a session (e.g. if + there is a limit on the number of + keywords), so check after creating a + new flag to see if any more can be + created before letting the user try + to do so +unsigned long perm_user_flags; corresponding user flags can be set + permanently. This is a bit mask + which matches the entries in + stream->user_flags[] +unsigned long gensym; generated unique value. Always + referenced with stream->gensys++ +unsigned long nmsgs; number of messages in current mailbox +unsigned long recent; number of recent messages in current + mailbox +unsigned long uid_validity; UID validity value; this is used to + verify that recorded UIDs match the + UIDs that the stream has. If the + mailbox does not have matching UIDs + (e.g. the UIDs were lost or not + recorded) then the UID validity value + will be different +unsigned long uid_last; highest currently assigned UID in the + current mailbox; a new UID will be + assigned with ++stream->uid_last +char *user_flags[NUSERFLAGS]; pointers to user flag names in bit + order from stream->perm_user_flags or + elt->user_flags + + The following MAILSTREAM values are only used internally: + +DRIVER *dtb; dispatch table for this driver +void *local; pointer to driver local data +unsigned int lock : 1; stream lock flag (an operation is in + progress; used as a bug trap to + detect recursion back to c-client + from callback routines). +unsigned int debug : 1; debugging information should be logged + via mm_dlog(). +unsigned int silent : 1; don't do main program callbacks on + this stream (used when a stream is + opened internally) +unsigned int scache : 1; short caching; don't cache information + in memory + + The following MAILSTREAM values are only used by the cache +manager routine (see the documentation about mailcache_t above): + +unsigned long cachesize; size of c-client message cache +union { + void **c; to get at the cache in general + MESSAGECACHE **s; message cache array + LONGCACHE **l; long cache array +} cache; + + The following MAILSTREAM values are for the convenience of +drivers that use short caching and want to be able to garbage collect +any values that they returned: + +unsigned long msgno; message number of `current' message +ENVELOPE *env; pointer to `current' message envelope +BODY *body; pointer to `current' message body +char *text; pointer to `current' text + + + The MESSAGECACHE structure (commonly called an "elt" as a +nickname for "cache ELemenT") contains information about messages. +Applications may use the following: + +unsigned long msgno; message number. If the elt is locked + (by elt->lockcount++), then the elt + pointer can be stored (e.g. with the + data for a window which draws this + message) and elt->msgno will change + automatically whenever expunges are + done so the window will always view + the correct message. If elt->msgno + becomes 0, then the message has been + expunged, but the elt won't be freed + until the elt lock count is + decremented (by mail_free_elt()). +unsigned long uid; message unique ID +unsigned int hours: 5; internal date hours (0-23) +unsigned int minutes: 6; internal date minutes (0-59) +unsigned int seconds: 6; internal date seconds (0-59) +unsigned int zoccident : 1; non-zero if internal date time zone is + west of UTC +unsigned int zhours : 4; internal date time zone hours from UTC + (0-12) +unsigned int zminutes: 6; internal date time zone minutes (0-59) +unsigned int seen : 1; message Seen flag +unsigned int deleted : 1; message Deleted flag +unsigned int flagged : 1; message Flagged flag +unsigned int answered : 1; message Answered glag +unsigned int draft : 1; message Draft flag +unsigned int valid : 1; flags are valid in this elt; an elt + that was newly created but never + loaded with flags won't have this set. +unsigned int recent : 1; message recent flag +unsigned int searched : 1; message matches search criteria in + most recent mail_search_full() call +unsigned int spare : 1; reserved for application use +unsigned int spare2 : 1; reserved for application use +unsigned int spare3 : 1; reserved for application use +unsigned int lockcount : 8; non-zero if multiple references to + this elt. Refer to the msgno member + for more information. +unsigned int day : 5; internal date day of month (1-31) +unsigned int month : 4; internal date month of year (1-12) +unsigned int year : 7; internal date year since BASEYEAR + (currently 1970; was 1969 in older + versions so use BASEYEAR instead of + having the base year wired in) +unsigned long user_flags; message user flags; this is a bit mask + which matches the entries in + stream->user_flags[] +unsigned long rfc822_size; size of message in octets + + The following MESSAGECACHE values are only used internally by +drivers: + +unsigned int sequence : 1; message is in sequence from either + mail_sequence() or mail_uid_sequence() +unsigned long data1; first data item +unsigned long data2; second data item +unsigned long data3; third data item +unsigned long data4; fourth data item + + + The ADDRESS structure is a parsed form of a linked list of RFC 822 +addresses. It contains the following information: + +char *personal; personal name phrase +char *adl; at-domain-list (also called "source + route") +char *mailbox; mailbox name +char *host; domain name of mailbox's host +char *error; error in address from smtp_mail(); if + an error is returned from smtp_mail() + for one of the recipient addresses + the SMTP server's error text for that + recipient can be found here. If it + is null then there was no error (or + an error was found with a prior + recipient +ADDRESS *next; pointer to next address in list + + + The ENVELOPE structure is a parsed form of the RFC 822 header. +Its member names correspond to the RFC 822 field names. It contains +the following information: + +char *remail; remail header if any +ADDRESS *return_path; error return address +char *date; message composition date string +ADDRESS *from; from address list +ADDRESS *sender; sender address list +ADDRESS *reply_to; reply address list +char *subject; message subject string +ADDRESS *to; primary recipient list +ADDRESS *cc; secondary recipient list +ADDRESS *bcc; blind secondary recipient list +char *in_reply_to; replied message ID +char *message_id; message ID +char *newsgroups; USENET newsgroups +char *followup_to; USENET reply newsgroups +char *references; USENET references + + + The BODY structure is a parsed form of a linked list of the MIME +structure of a message. It contains the following information. + +unsigned short type; body primary type code. This is an + index into the body_types vector of + body type names. The following body + types are pre-defined: + TYPETEXT unformatted text + TYPEMULTIPART multiple part + TYPEMESSAGE encapsulated message + TYPEAPPLICATION application data + TYPEAUDIO audio + TYPEIMAGE static image (GIF, JPEG, etc.) + TYPEVIDEO video + TYPEOTHER unknown + Additional types up to TYPEMAX are + dynamically defined if they are + encountered by c-client. +unsigned short encoding; body transfer encoding. This is an + index into the body_encodings vector + of body encoding names. The + following body encodings are + pre-defined: + ENC7BIT 7 bit SMTP semantic data + ENC8BIT 8 bit SMTP semantic data + ENCBINARY 8 bit binary data + ENCBASE64 base-64 encoded data + ENCQUOTEDPRINTABLE human-readable 8-as-7 bit data + ENCOTHER unknown + Additional encodings up to ENCMAX are + dynamically defined if they are + encountered by c-client. +char *subtype; body subtype string +PARAMETER *parameter; parameter list +char *id; body content identifier +char *description; body content description +unsigned char *contents.text; when composing a message that is NOT + of TYPEMULTIPART, non-binary text of + the content is stored here. Note that + this happens even when the text is + of TYPEMESSAGE. Text of encoding + ENC8BIT may be converted to + ENCQUOTEDPRINTABLE when it is sent. + This should not be referenced for any + other reason; in particular, this is + NOT the way for an application to + access content data (use + mail_fetchbody_full() instead). +BINARY *contents.binary; when composing a message that is NOT + of TYPEMULTIPART, binary content (of + encoding ENCBINARY) is stored here. + It will be converted to ENCBASE64 when + it is sent. + This should not be referenced for any + other reason; in particular, this is + NOT the way for an application to + access content data (use + mail_fetchbody_full() instead). +PART *contents.part; for body parts of TYPEMULTIPART, this + contains the list of body parts in + this multipart +MESSAGE contents.msg; for body parts of TYPEMESSAGE with + subtype "RFC822", this contains the + encapsulated message +unsigned long size.lines; size in lines +unsigned long size.bytes; size in octets. This MUST be set when + composing a message if the encoding is + ENC8BIT or ENCBINARY. +char *md5; body content MD5 checksum + + The following BODY information is used only by c-client +internally. The use of this data is driver-specific and it can not be +relied-upon by applications. + +unsigned char *contents.text; drivers can store a pointer to the + body contents as text here. +unsigned long size.ibytes; internal size of the body content (prior + to newline conversion, etc.) in octets + + + The MESSAGE structure is a parsed form of a MESSAGE/RFC822 MIME +body part. It contains the following information: + +ENVELOPE *env; encapsulated message RFC 822 header +BODY *body; encapsulated message MIME structure + + The following MESSAGE information is used only by c-client +internally. The use of this data is driver-specific and it can not be +relied-upon by applications. + +char *hdr; encapsulated message header +unsigned long hdrsize; message header size +char *text; message in RFC 822 form +unsigned long offset; offset of text from header + + + The PARAMETER structure is a parsed form of a linked list of +attribute/value pairs. It contains the following information: + +char *attribute; attribute name +char *value; value +PARAMETER *next; next parameter in list + + + The PART structure is a parsed form of a linked list of MIME body +parts. It contains the following information: + +BODY body; body information for this part +PART *next; next body part + + The following PART information is used only by c-client +internally. The use of this data is driver-specific and it can not be +relied-upon by applications. + +unsigned long offset; offset from body origin + + + The NETMBX structure is a parsed form of a network mailbox name: + +char host[NETMAXHOST]; remote host name +char user[NETMAXUSER]; remote user name if specified +char mailbox[NETMAXMBX]; remote mailbox name +char service[NETMAXSRV]; remote service name (IMAP4, NNTP, etc.) +unsigned long port; TCP/IP port number if specified +unsigned int anoflag : 1; anonymous access requested +unsigned int dbgflag : 1; protocol debugging telemetry, via + mm_dlog(), requested + + + The STRINGLIST structure is a list of strings (which may have +embedded NULs) and their lengths: + +char *text; string text +unsigned long size; string length +STRINGLIST *next; next string in list + + String Structures + + A string structure is analogous to a char*, and is used in some +functions as an input argument. It represents a string of data in a +way that does not necessarily require the entire string to be in +memory at once. This is essential for small machines with +highly-restricted memory limits (e.g. DOS). + + String Structure Access + + To use a string structure, the caller needs to know a string +driver and needs to know the driver-dependent data used by that string +structure. A simple string driver is mail_string, a string driver +that takes an in-memory char* string as the driver-dependent data. +The DOS port uses string drivers that take a struct holding a file +descriptor and a file offset. Often the user of a string driver is +the same module that defined it, so usually the programmer knows about +its conventions. + + The following calls are used to access a string structure: + +void INIT (STRING *s,STRINGDRIVER *d,void *data,unsigned long size); + s pointer to the string structure to be initialized + d pointer to the string driver + data pointer to driver-dependent data, from which the + driver can determine string data + size size of the string + This call initializes the string stucture. + + +unsigned long SIZE (STRING *s); + s pointer to the string structure + This call returns the number of characters remaining in the string +after the current string character pointer. + + +char CHR (STRING *s); + s pointer to the string structure + This call returns the character at the current string character +pointer. + + +char SNX (STRING *s); + s pointer to the string structure + This call returns the character at the current string character +pointer, and increments the string character pointer. + + +unsigned long GETPOS (STRING *s); + s pointer to the string structure + This returns the value of the current string character pointer. + + +void SETPOS (STRING *s,unsigned long i); + s pointer to the string structure + i new string pointer value + This method sets the string character pointer to the given value. + + + String Structure Internals + + A string structure holds the following data: + +void *data; used by the string driver as it likes +unsigned long data1; used by the string driver as it likes +unsigned long size; static, holds the total length of the string + from the INIT call +char *chunk; current chunk of in-memory data; this is used + for buffering to avoid unnecessary calls to + the string driver's next method. +unsigned long chunksize; size of an in-memory data chunk +unsigned long offset; position of first character of the chunk in + the overall string +char *curpos; current position; this is what CHR() will + access +unsigned long cursize; number of characters remaining in the current + string +STRINGDRIVER *dtb; the string driver for this string structure + + + A string structure is manipulated by a string driver, which has +the following access methods: + +void (*init) (STRING *s,void *data,unsigned long size); + s pointer to the string structure to be initialized + data pointer to driver-dependent data, from which the + driver can determine string data + size size of the string + This method initializes the string stucture. It can use the data, +data1, and chunksize values as it likes. The remaining values must be +set up as follows: + size static, copied from the size argument + chunk pointer to a buffer loaded with initial data + chunksize size of the buffer + offset 0 + curpos copied from chunk + cursize copied from chunksize + dtb STRINGDRIVER identity pointer + + +char (*next) (STRING *s); + s pointer to the string structure + This method returns the character at the current string character +pointer, and increments the string character pointer. This method +is likely to call the setpos method if the desired character is not in +the current chunk. + + +void (*setpos) (STRING *s,unsigned long i); + s pointer to the string structure + i new string pointer value + This method sets the string character pointer to the given value. If +the pointer is not in the current chunk, then a new chunk is loaded +and the associated values (chunk, offset, curpos, cursize) are +adjusted accordingly. + + c-client Support Functions + + +void mail_string_init (STRING *s,void *data,unsigned long size); +char mail_string_next (STRING *s); +void mail_string_setpos (STRING *s,unsigned long i); + + These three functions are the init, next, and setpos string +structure access methods for the build-in mail_string string driver. +mail_string is a basic string driver for a char* string. See the +documentation below on "String Structures" for more information. + + +void mail_link (DRIVER *driver); + driver pointer to the driver to be added + + This function adds the specified driver to the list of mailbox +drivers. Initially there are no drivers lunk, so all programs which +intend to use c-client need to have at least one call to this function. + + A function which uses IMAP4 would have a statement such as: + mail_link (&imapdriver); /* link in IMAP driver */ +early in the program's initialization. Normally, this is done by the +statement + #include "linkage.c" +which will include the "system standard driver linkage" defined when +c-client was built. By using linkage.c instead of explicit mail_link() +calls, you are guaranteed that you will have a consistant linkage among +all software built on this system. + + +void auth_link (AUTHENTICATOR *auth); + auth pointer to the authenticator to be added + + This function adds the specified authenticator to the list of +authenticators. Initially there are no authenticators lunk. Normally, +this is done by linkage.c so you don't need to call this routine +explicitly. + + +void *mail_parameters (MAILSTREAM *stream,long function,void *value); + stream stream to poll or NIL + function function code + value new value for function codes that change a parameter + + This function fetches or changes the settings of various c-client +operational parameters depending upon the function. If the stream is +specified, only the action for the underlying driver for that stream is +taken; however, the scope of the operational parameters is global so +there is generally no reason for the stream argument ever to be +non-NIL. + + The function codes ENABLE_DRIVER and DISABLE_DRIVER take a driver +pointer as a value. These functions enable and disable mailbox +processing by that driver. By default, all drivers are enabled. + + The remaining function codes are in a pair named GET_xxx to +fetch an operational parameter and SET_xxx to set the parameter: + + GET_DRIVERS / SET_DRIVERS + The list of currently lunk drivers. + + GET_GETS / SET_GETS + If non-NIL, points to a function for reading message text. + Defaults to NIL. + This function is called with three arguments; a function + pointer to a "reading function", a stream for the reading + function, and a size in octets. The reading function is + in turn called with the stream, a size in octets, and a + pointer to a readin buffer. + This function returns with a char* string, which will be + returned by the mail_fetchheader(), mail_fetchtext(), or + mail_fetchbody() function which triggered the message text + reading. + The purpose is to permit reading of large strings, without + requiring an in-memory buffer for the entire string. The idea + is that this function can store the data in some form other + than a char* (e.g. a temporary file) and the main program will + recognize that it should get the text from there instead of + from the results from mail_fetch....(). + This is only supported on DOS and Win16; on other platforms it + is inconsistent whether or not it works. + + GET_CACHE / SET_CACHE + Points to the c-client cache manager function. Defaults to + mm_cache(). + + GET_SMTPVERBOSE / SET_SMTPVERBOSE + If non-NIL, points to a function that accepts a char* string. + This function is called any time the SMTP routines receive a + response code less than 100. The argument is the text of the + response code + + GET_RFC822OUTPUT / SET_RFC822OUTPUT + If non-NIL, points to an alternate rfc822_output() function. + rfc822_output() will call this function and return instead of + doing its normal action. See the description of + rfc822_output() for more information. + + GET_USERNAME / SET_USERNAME + The logged-in user name. + + GET_HOMEDIR / SET_HOMEDIR + The home directory path name. + + GET_LOCALHOST / SET_LOCALHOST + The local host name. + + GET_SYSINBOX / SET_SYSINBOX + The "system INBOX" (where mail is delivered) path name. + + GET_OPENTIMEOUT / SET_OPENTIMEOUT + TCP/IP open timeout in seconds. Defaults to 0 (system + default timeout, usually 75 seconds on Unix). + + GET_READTIMEOUT / SET_READTIMEOUT + TCP/IP read timeout in seconds. Defaults to 0 (no timeout). + + GET_WRITETIMEOUT / SET_WRITETIMEOUT + TCP/IP write timeout in seconds. Defaults to 0 (no timeout). + + GET_CLOSETIMEOUT / SET_CLOSETIMEOUT + TCP/IP close timeout in seconds. Defaults to 0 (no timeout). + + GET_TIMEOUT / SET_TIMEOUT + If non-NIL, points to the function called when a TCP/IP + timeout occurs. This function is called with the number of + seconds since the start of the TCP operation. If it returns + non-zero, the TCP/IP operation is continued; if it returns + non-zero, the TCP/IP connection is aborted. + + GET_RSHTIMEOUT / SET_RSHTIMEOUT + rsh connection timeout in seconds. Defaults to 15 seconds. + + GET_MAXLOGINTRIALS / SET_MAXLOGINTRIALS + The maximum number of login attempts permitted in an IMAP or + POP connection. Defaults to 3. + + GET_LOOKAHEAD / SET_LOOKAHEAD + The number of subsequent envelopes prefetched in IMAP when an + envelope is fetched. Defaults to 20. + + GET_IMAPPORT / SET_IMAPPORT + The IMAP port number. Defaults to 143. + + GET_PREFETCH / SET_PREFETCH + The number of envelopes prefetched in IMAP from the results + of a SEARCH. Defaults to 20. + + GET_CLOSEONERROR / SET_CLOSEONERROR + If non-NIL, close an opening IMAP connection if the SELECT + command fails instead of returning a half-open stream. + Defaults to NIL. + + GET_POP3PORT / SET_POP3PORT + The POP3 port number. Defaults to 110. + + GET_UIDLOOKAHEAD / SET_UIDLOOKAHEAD + The number of UIDs premapped when a message number is + translated to a UID. Defaults to 1000. + + GET_MBXPROTECTION / SET_MBXPROTECTION + Default file protection for newly created mailboxes. + Defaults to 0600. + + GET_DIRPROTECTION / SET_DIRPROTECTION + Default file protection for newly created directories. + Defaults to 0700. + + GET_LOCKPROTECTION / SET_LOCKPROTECTION + Default file protection for locks. Defaults to 0666. + WARNING: don't blithely change this. If other processes + can't get access to a lock then they will have trouble in + locking properly. + + GET_FROMWIDGET / SET_FROMWIDGET + If non-NIL, APPEND in the Unix mbox format will insert a + ">" character in front of all lines which begin with the + string "From ". If NIL, it will only do so if the entire + line looks like a message delimiter (that is, the date is + also in correct format). Defaults to T. + + GET_NEWSACTIVE / SET_NEWSACTIVE + Netnews active file path name. + + GET_NEWSSPOOL / SET_NEWSSPOOL + Netnews spool directory path name. + + GET_NEWSRC / SET_NEWSRC + Netnews newsgroup reading status file (.newsrc) path name. + + GET_EXTENSION / SET_EXTENSION + If non-NIL, points to a string holding the extension for all + mailbox files. This is only supported on DOS and Win16. + + GET_DISABLEFCNTLLOCK / SET_DISABLEFCNTLLOCK + If non-NIL, disables fcntl() locking on SVR4. This is done + if fcntl() tends to hang for no good reason. Now that the + fcntl() code checks for NFS files and no-ops the locking, + this problem usually doesn't happen much any more. Defaults + to NIL. + + GET_LOCKEACCESERROR / SET_LOCKEACCESERROR + If non-NIL, give a warning if an attempt to create a .lock + file gets an EACCES ("Permission denied") error. This usually + means that somebody protected the system inbox directory (e.g. + /var/mail) instead of making it public-write with the sticky + bit. Defaults to non-NIL, since this is usually bad news. + + GET_LISTMAXLEVEL / SET_LISTMAXLEVEL + The maximum depth of recusion that LIST will go on a * + wildcard. Defaults to 20. + + GET_ANONYMOUSHOME / SET_ANONYMOUSHOME + The anonymous use home directory name. + + +typedef long (*readfn_t) (void *stream,unsigned long size,char *buffer); + stream a designator suitable + size a number of octets to read + buffer a buffer of at least size octets for readin + + This function reads the given number of octets into the buffer, +using the given stream. What sort of object the stream is depends upon +the function and its caller, so you must make sure that the readfn is +suitable for the caller's purpose. Common uses include support of the +mailgets function (see below) and of reading from local files on systems +with limited address space. + + +typedef char *(*mailgets_t) (readfn_t f,void *stream,unsigned long size); + f the readfn to use + stream stream argument for the readfn + size total number of octets to read + + This is the argument to the SET_GETS mail_parameter() call. This +function must read size octets from the stream, using the readfn f. It +may call f multiple times to accomplish this; this will read the data in +a serial fashion. So, for example, if size is a megabyte and there is +only 4K of available buffer space, it can call f 256 times to satisfy +the request. There is no way to back up in the reading, so any +processing or saving of the data must be done when it is read. + + The function mm_gets() in mail.c is a sample mailgets function; it +reads the first MAXMESSAGESIZE of data into memory and discards the +rest. + + +typedef void *(*mailcache_t) (MAILSTREAM *stream,unsigned long msgno,long op); + stream stream to cache manage + msgno message to cache manage in the stream + op cache management operation + + This function manages the c-client cache. Normally, a program will +use the default c-client cache manager routine mm_cache(). However, a +main program may want to supply its own cache manager, e.g. it may want +to store the data on a disk file instead of in memory on DOS and Win16 +where memory is tight. + + If you write your own cache manager, you need to examine the +default mm_cache() manager closely, as well as paying close attention to +what goes into an elt (a MESSAGECACHE element). It is highly likely +that if you roll elts out to disk, you will want to set stream->scache +and *NOT* use long elts (because long elts have ENVELOPE and BODY +pointers that you would have to know how to write to disk and read back). + + The cache management functions are one of the following: + + CH_INIT Initialize the entire cache for the stream. This is + called only when creating a new stream or when freeing + it. The msgno argument is ignored. + + CH_SIZE Make sure that the cache is at least large enough to + support msgno. This is a request to grow the cache if + necessary, not shrink it. + + CH_MAKELELT Return a long elt for msgno, creating it if necessary. + This is the underlying support function for mail_lelt(). + + CH_LELT Return the long elt for msgno, or NIL if it does not + already exist. + + CH_MAKEELT Return an elt for msgno, creating it if necessary. + This is the underlying support function for mail_elt(). + + CH_ELT Return the elt for msgno, or NIL if it does not already + exist. + + CH_FREE Free the [l]elt for msgno. + + CH_EXPUNGE Free the [l]elt for msgno, and reclaim its position. + All subsequent elts are renumbered with their elt->msgno + decremented by 1. [Hence msgno+1 becomes msgno, etc.] + This supports message expunging from the cache. + + +typedef long (*tcptimeout_t) (long time); + time total time spent since TCP operation started + + This function is called when a TCP operation times out. It is set +by the SET_TIMEOUT mail_parameter(). The function can return non-zero +to continue the TCP operation (e.g. after outputting a "do you still +want to wait" prompt) or zero if it wants the TCP operation to abort and +close. If the TCP operation aborts, it will likely cause the upper +level IMAP, SMTP, etc. stream to abort and close as well. + + +DRIVER *mail_valid (MAILSTREAM *stream,char *mailbox,char *purpose); + stream if non-NIL, stream to use for validation + mailbox mailbox name to validate + purpose filled in as xxx in "Can't xxx" in error messages + + This function validates the given mailbox name. It successful, it +returns the driver that can open that name if successful, otherwise it +returns NIL. If stream is non-NIL, the mailbox name must be valid for +the type of mailbox associated with that stream (e.g. an NNTP name can +not be used with an IMAP stream). If purpose is non-NIL, an error +message is passed via mm_log() when an error occurs. + + +DRIVER *mail_valid_net (char *name,DRIVER *drv,char *host,char *mailbox); + name mailbox name to validate + drv driver name to validate against + host buffer to return host name if non-NIL + mailbox buffer to return remote mailbox name if non-NIL + + This function is an alternative to mail_valid_net_parse(). It +validates the given mailbox name as a network name and makes sure that +its service name is the same as the driver in drv. If successful, it +returns drv, and copies the host and mailbox strings as needed. +Otherwise it returns NIL. + + +long mail_valid_net_parse (char *name,NETMBX *mb); + name mailbox name to parse + mb pointer to NETMBX structure to return + + This function parses a network mailbox name. If the name is a +network mailbox name, it returns non-NIL, with the NETMBX structure +loaded with the results form the parse. + + Mailbox Access Functions + +void mail_list (MAILSTREAM *stream,char *ref,char *pat); +void mail_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents); + stream if non-NIL, stream to use + ref mailbox reference string + pat mailbox pattern string + contents contents to search + + This function returns a list of mailboxes via the mm_list() +callback. The reference is applied to the pattern in an implementation +dependent fashion, and the resulting string is used to search for +matching mailbox names. "*" is a wildcard which matches zero or more +characters; "%" is a variant which does not descend a hierarchy level. +Read the IMAP specification for more information. + + mail_scan() is a variant which takes a string to search for in the +text of the mailbox. The string is a free-text string, without regard +for message boundaries, and thus the choice of strings must be made +with care. + + +void mail_lsub (MAILSTREAM *stream,char *ref,char *pat); + stream if non-NIL, stream to use + ref mailbox reference string + pat mailbox pattern string + + This function returns a list of subscribed mailboxes via the +mm_lsub() callback. The reference is applied to the pattern in an +implementation dependent fashion, and the resulting string is used to +search for matching mailbox names in the subscription list. "*" is a +wildcard which matches zero or more characters; "%" is a variant which +does not descend a hierarchy level. Read the IMAP specification for +more information. + + +long mail_subscribe (MAILSTREAM *stream,char *mailbox); + stream if non-NIL, stream to use + mailbox mailbox name + + This function adds the given name to the subscription list. It +returns T if successful, NIL if unsuccessful. If unsuccessful, an +error message is returned via the mm_log() callback. + + +long mail_unsubscribe (MAILSTREAM *stream,char *mailbox); + stream if non-NIL, stream to use + mailbox mailbox name + + This function removes the given name from the subscription list. +It returns T if successful, NIL if unsuccessful. If unsuccessful, an +error message is returned via the mm_log() callback. + + +long mail_create (MAILSTREAM *stream,char *mailbox); + stream if non-NIL, stream to use + mailbox mailbox name + + This function creates a mailbox with the given name. It returns T +if successful, NIL if unsuccessful. If unsuccessful, an error message +is returned via the mm_log() callback. + + It is an error to create INBOX or a mailbox name which already +exists. + + +long mail_delete (MAILSTREAM *stream,char *mailbox); + stream if non-NIL, stream to use + mailbox mailbox name + + This function deletes the named mailbox. It returns T if +successful, NIL if unsuccessful. If unsuccessful, an error message is +returned via the mm_log() callback. + + It is an error to delete INBOX or a mailbox name which does not +already exist. + + +long mail_rename (MAILSTREAM *stream,char *old,char *newname); + stream if non-NIL, stream to use + old existing mailbox name + newname new (not yet existing) mailbox name + + This function renames the old mailbox to the new mailbox name. +It returns T if successful, NIL if unsuccessful. If unsuccessful, an +error message is returned via the mm_log() callback. + + It is an error to reanme a mailbox that does not exist, or rename +a mailbox to a name that already exists. It is permitted to rename +INBOX; a new empty INBOX is created in its place. + + +long mail_status (MAILSTREAM *stream,char *mbx,long flags); + stream if non-NIL, stream to use + mbx mailbox name + flags option flags + + This function returns the status of the given mailbox name via the +mm_status() callback. It returns T if successful, NIL if unsuccessful. +If unsuccessful, an error message is returned via the mm_log() +callback. + + The options are a bit mask with one or more of the following, +indicating the data which should be returned. + SA_MESSAGES number of messages in the mailbox + SA_RECENT number of recent messages in the mailbox + SA_UNSEEN number of unseen messages in the mailbox + SA_UIDNEXT next UID value to be assigned + SA_UIDVALIDITY UID validity value + + Note that, depending upon implementation, some of these values may +be more costly to get than others. For example, calculating the +number of unseen messages may require opening the mailbox and scanning +all of the message flags. A mail_status() call should thus be used +with option flags specifying only the data that is actually needed. + + +MAILSTREAM *mail_open (MAILSTREAM *oldstream,char *name,long options); + oldstream if non-NIL, stream to recycle + name mailbox name to open + options option flags. + + This function opens the mailbox and if successful returns a stream +suitable for use by the other MAIL functions. + + If oldstream is non-NIL, an attempt is made to reuse oldstream as +the stream for this mailbox; this is useful when you want to open +another mailbox to the same IMAP or NNTP server without having to open +a new connection. Doing this will close the previously open mailbox. + + The options are a bit mask with one or more of the following: + OP_DEBUG Log IMAP protocol telemetry through mm_debug() + OP_READONLY Open mailbox read-only. + OP_ANONYMOUS Don't use or update a .newsrc file for news. + OP_SHORTCACHE Don't cache envelopes or body structures + OP_SILENT Don't pass mailbox events (internal use only) + OP_PROTOTYPE Return the "prototype stream" for the driver + associated with this mailbox instead of + opening the stream + OP_HALFOPEN For IMAP and NNTP names, open a connection + to the server but don't open a mailbox. + OP_EXPUNGE Silently expunge the oldstream before recycling + + NIL is returned if this function fails for any reason. + + +MAILSTREAM *mail_close (MAILSTREAM *stream); +MAILSTREAM *mail_close_full (MAILSTREAM *stream,long options); + stream stream to close + options option flags + This function closes the MAIL stream and frees all resources +associated with it that it may have created (subject to any handles +existing). + + The options for mail_close_full() are a bit mask with one or more +of the following: + CL_EXPUNGE Silently expunge before closing + + This function always returns NIL, so it can be used as: + stream = mail_close (stream); + + Handle Functions + + Handles are used when an entity that wishes to access the stream +may survive the stream without knowing that it outlived it. For +example, an object reading a message may have a handle to a stream, +but the message selection object that spawned it (and which owns the +stream) may have gone away. A stream can be closed or recycled while +handles are pointing at it, but it is not completely freed until all +handles are gone. A stream may have an arbitrary number of handles. + + +MAILHANDLE *mail_makehandle (MAILSTREAM *stream); + stream stream to make handle to + + This function creates and returns a handle to the stream. + + +void mail_free_handle (MAILHANDLE **handle); + handle pointer to handle to release + + This function frees the handle and notifies the stream that it has +one fewer handle. If this is the last handle on the stream and the +stream has been closed, then the stream is freed. + + +MAILSTREAM *mail_stream (MAILHANDLE *handle); + handle handle to look up + + This function returns the stream associated with the handle if and +only if the stream still represents the same MAIL connection associated +with the handle. Otherwise, NIL is returned (meaning that there is no +active stream associated with this handle). + + Message Data Fetching Functions + +[Note!! There is an important difference between a "sequence" and a + "msgno". A sequence is a string representing one or more messages in + IMAP4-style sequence format ("n", "n:m", or combination of these + delimited by commas), whereas a msgno is an int representing a single + message.] + +void mail_fetchfast (MAILSTREAM *stream,char *sequence); +void mail_fetchfast_full (MAILSTREAM *stream,char *sequence,long flags); + stream stream to fetch on + sequence IMAP-format set of message sequence numbers + flags option flags + + This function causes a cache load of all the "fast" information +(internal date, RFC 822 size, and flags) for the given sequence. Since +all this information is also fetched by mail_fetchstructure(), this +function is generally not used unless the OP_SHORTCACHE option in the +mail_open() call is used. + + The options for mail_fetchfast_full() are a bit mask with one or +more of the following: + FT_UID The sequence argument contains UIDs instead of + sequence numbers + + +void mail_fetchflags (MAILSTREAM *stream,char *sequence); +void mail_fetchflags_full (MAILSTREAM *stream,char *sequence,long flags); + + This function causes a fetch of the flags for the given sequence. +This main reason for using this function is to update the flags in the +local cache in case some other process changed the flags (multiple +simultaneous write access is allowed to the flags) as part of a "check +entire mailbox" (as opposed to "check for new messages") operation. + + The options for mail_fetchflags_full() are a bit mask with one or more +of the following: + FT_UID The sequence argument contains UIDs instead of + sequence numbers + + +ENVELOPE *mail_fetchenvelope (MAILSTREAM *stream,unsigned long msgno); +ENVELOPE *mail_fetchstructure (MAILSTREAM *stream,unsigned long msgno, + BODY **body); +ENVELOPE *mail_fetchstructure_full (MAILSTREAM *stream,unsigned long msgno, + BODY **body,long flags); + stream stream to fetch on + msgno message sequence number + body pointer to where to return BODY structure if non-NIL + flags option flags + This function causes a fetch of all the structured information +(envelope, internal date, RFC 822 size, flags, and body structure) for +the given msgno and, in the case of IMAP, up to MAPLOOKAHEAD (a +parameter in IMAP2.H) subsequent messages which are not yet in the +cache. No fetch is done if the envelope for the given msgno is already +in the cache. The ENVELOPE and the BODY for this msgno is returned. +It is possible for the BODY to be NIL, in which case no information is +available about the structure of the message body. + + The options for mail_fetchstructure_full() are a bit mask with one +or more of the following: + FT_UID The msgno argument is a UID + + This is the primary function for fetching non-text information +about messages, and should be called before any attempt to reference +cache information about this message via mail_elt(). + + +char *mail_fetchheader (MAILSTREAM *stream,unsigned long msgno); +char *mail_fetchheader_full (MAILSTREAM *stream,unsigned long msgno, + STRINGLIST *lines,unsigned long *len,long flags); + stream stream to fetch on + msgno message sequence number + lines list of header lines to fetch + len returned length in octets + flags option flags + + This function causes a fetch of the complete, unfiltered RFC 822 +format header of the specified message as a text string and returns +that text string. + + If the lines argument is non-NIL, it contains a list of header +field names to use in subsetting the header text. Only those lines +which have that header field name are returned, unless FT_NOT is set in +which case only those lines which do not have that header field name +are returned. + + If the len argument is non-NIL, it holds a pointer in which the +length of the string in octets is returned. This is useful in cases +where there may be an embedded null in the string. + + This function always returns a valid string pointer; if no header +exists or if it can not be fetched (e.g. by a deceased IMAP stream) an +empty string is returned. + + The options for mail_fetchheader_full() are a bit mask with one or +more of the following: + FT_UID The msgno argument is a UID + FT_NOT The returned header lines are those that are + not in the lines argument + FT_INTERNAL The return string is in "internal" format, + without any attempt to canonicalize to CRLF + newlines + FT_PREFETCHTEXT The RFC822.TEXT should be pre-fetched at the + same time. This avoids an extra RTT on an + IMAP connection if a full message text is + desired (e.g. in a "save to local file" + operation) + + +char *mail_fetchtext (MAILSTREAM *stream,unsigned long msgno); +char *mail_fetchtext_full (MAILSTREAM *stream,unsigned long msgno, + unsigned long *len,long flags); + stream stream to fetch on + msgno message sequence number + len returned length in octets + flags option flags + + This function causes a fetch of the non-header text of the +specified message as a text string and returns that text string. No +attempt is made to segregate individual body parts. + + If the len argument is non-NIL, it holds a pointer in which the +length of the string in octets is returned. This is useful in cases +where there may be an embedded null in the string. + + This function always returns a valid string pointer; if no header +exists or if it can not be fetched (e.g. by a deceased IMAP stream) an +empty string is returned. + + The options for mail_fetchtext_full() are a bit mask with one or +more of the following: + FT_UID The msgno argument is a UID + FT_PEEK Do not set the \Seen flag if it not already set + FT_INTERNAL The return string is in "internal" format, + without any attempt to canonicalize to CRLF + newlines + + +char *mail_fetchbody (MAILSTREAM *stream,unsigned long msgno,char *sec, + unsigned long *len); +char *mail_fetchbody_full (MAILSTREAM *stream,unsigned long msgno,char *sec, + unsigned long *len,long flags); + stream stream to fetch on + msgno message sequence number + sec section specifier + len returned length in octets + flags option flags + + This function causes a fetch of the particular section of the +body of the specified message as a text string and returns that text +string. The section specification is a string of integers delimited by +period which index into a body part list as per the IMAP4 +specification. Body parts are not decoded by this function; see +rfc822_base64() and rfc822_quotedprintable(). + + If the len argument is non-NIL, it holds a pointer in which the +length of the string in octets is returned. This is useful in cases +where there may be an embedded null in the string. + + This function may return NIL on error. + + The options for mail_fetchbody_full() are a bit mask with one or +more of the following: + FT_UID The msgno argument is a UID + FT_PEEK Do not set the \Seen flag if it not already set + FT_INTERNAL The return string is in "internal" format, + without any attempt to canonicalize to CRLF + newlines + + +unsigned long mail_uid (MAILSTREAM *stream,unsigned long msgno); + stream stream to fetch on + msgno message sequence number + + This function returns the UID for the given message sequence +number. + + +void mail_fetchfrom (char *s,MAILSTREAM *stream,unsigned long msgno, + long length); + s destination string + stream stream to fetch on + msgno message sequence number + length maximum field length + + This function writes a "from" string of the specified length for +the specified message, suitable for display to the user in a menu line, +into the string pointed to by s. + + If the personal name of the first address in the envelope's from +item is non-NIL, it is used; otherwise a string is created by appending +the mailbox of the first address, an "@", and the host of the first +address. The string is trimmed or padded with trailing spaces as +necessary to make its length match the length argument. + + +void mail_fetchsubject (char *s,MAILSTREAM *stream,unsigned long msgno, + long length); + s destination string + stream stream to fetch on + msgno message sequence number + length maximum field length + + This function returns a "subject" string of the specified length +for the specified message, suitable for display to the user in a menu +line. + + The envelope's subject item is copied and trimmed as necessary +to make its length be no more what the caller requested. Unlike +mail_fetchfrom(), this function can return a string of shorter length +than what the caller requested. + + +LONGCACHE *mail_lelt (MAILSTREAM *stream,unsigned long msgno); +MESSAGECACHE *mail_elt (MAILSTREAM *stream,unsigned long msgno); + stream stream to access + msgno message sequence number + + This function returns the cache entry for the specified message. +Although it will create a cache entry if it does not already exist, +that functionality is for internal use only. This function should +never be called without having first called mail_fetchfast() or +mail_fetchstructure() on the message first. + + A cache entry holds the internal date/time, flags, and RFC 822 +size of a message. It holds other data as well, but that is for +internal use only. + + mail_lelt() is a variant that returns a `long' cache entry, which +consists of an cache entry (as a structure, not a pointer), an envelope +pointer, and a body pointer. This is used in conjunction with the elt +lock count functionality, to allow an application to associate the +cached envelope and body of a message with an open window even if the +message is subsequently expunged or if the stream is closed. + + Unless your application wants to look at cached envelopes and +bodies even after the message is expunged or the stream is closed, it +should not use mail_lelt(). Instead, it should use a returned elt from +mail_elt() and use the elt->msgsno as the argument to +mail_fetchstructure(). + + BEWARE: the behavior of mail_lelt() is undefined if the + stream is open with OP_SHORTCACHE. mail_lelt() is extremely + special purpose, and should only be used in sophisticated + special purpose applications after discussing its use with + the c-client author. If you think you need this function, + you are probably mistaken. In almost all cases, you should + use mail_elt() and mail_fetchstructure() instead. + + Message Status Manipulation Functions + +void mail_setflag (MAILSTREAM *stream,char *sequence,char *flag); +void mail_setflag_full (MAILSTREAM *stream,char *sequence,char *flag, + long flags); + stream stream to use + sequence IMAP-format set of message sequence numbers + flag IMAP-format flag string + flags option flags + + This function causes a store to add the specified flag to the flags +set for the messages in the specified sequence. If there is any +problem in setting flags, a message will be passed to the application +via the mm_log() facility. + + The options for mail_setflag_full() are a bit mask with one or +more of the following: + ST_UID The sequence argument contains UIDs instead of + sequence numbers + ST_SILENT Do not update the local cache with the new + value of the flags. This is useful to save + network bandwidth, at the cost of invalidating + the cache. + + +void mail_clearflag (MAILSTREAM *stream,char *sequence,char *flag); +void mail_clearflag_full (MAILSTREAM *stream,char *sequence,char *flag, + long flags); + stream stream to use + sequence IMAP-format set of message sequence numbers + flag IMAP-format flag string + flags option flags + + This function causes a store to delete the specified flag from the +flags set for the messages in the specified sequence. If there is any +problem in clearing flags, a message will be passed to the application +via the mm_log() facility. + + The options for mail_setflag_full() are a bit mask with one or +more of the following: + ST_UID The sequence argument contains UIDs instead of + sequence numbers + ST_SILENT Do not update the local cache with the new + value of the flags. This is useful to save + network bandwidth, at the cost of invalidating + the cache. + + Mailbox Searching + +void mail_search (MAILSTREAM *stream,char *criteria); +void mail_search_full (MAILSTREAM *stream,char *charset,SEARCHPGM *pgm, + long flags); + stream stream to search + charset MIME character set to use when searching strings + pgm search program + flags option flags + + This function causes a mailbox search, using the given MIME +charset (NIL means the default, US-ASCII) and the given search program. +A search program is a structure that holds the following data: + +SEARCHSET *msgno; a set of message sequence numbers +SEARCHSET *uid; a set of unique identifiers +SEARCHOR *or; OR result of two search programs +SEARCHPGMLIST *not; AND result of list of NOT'ed search programs +SEARCHHEADER *header; message headers +STRINGLIST *bcc; string(s) appear in bcc list +STRINGLIST *body; string(s) appear in message body text +STRINGLIST *cc; string(s) appear in cc list +STRINGLIST *from; string(s) appear in from +STRINGLIST *keyword; user flag string(s) set +STRINGLIST *unkeyword; user flag strings() not set +STRINGLIST *subject; string(s) appear in subject +STRINGLIST *text; string(s) appear in message header or body +STRINGLIST *to; string(s) appear in to list +unsigned long larger; larger than this many octets +unsigned long smaller; smaller than this many octes + The following dates are in form: + ((year - BASEYEAR) << 9) + (month << 5) + day +unsigned short sentbefore; + sent before this date +unsigned short senton; sent on this date +unsigned short sentsince; + sent since this date +unsigned short before; received before this date +unsigned short on; received on this date +unsigned short since; received since this date +unsigned int answered : 1; + message answered +unsigned int unanswered : 1; + message not answered +unsigned int deleted : 1; + message deleted +unsigned int undeleted : 1; + message not deleted +unsigned int draft : 1; message is a draft +unsigned int undraft : 1; + message is not a draft +unsigned int flagged : 1; + message flagged as urgent +unsigned int unflagged : 1; + message not flagged as urgent +unsigned int recent : 1; + message recent since last parse of mailbox +unsigned int old : 1; message not recent since last parse of mailbox +unsigned int seen : 1; message read +unsigned int unseen : 1; + message not read + + The following auxillary structures are used by search programs: + SEARCHHEADER: header line searching +char *line; header line field name +char *text; text header line +SEARCHHEADER *next; next SEARCHHEADER in list (AND'ed) + + SEARCHSET: message number set +unsigned long first; first number in set +unsigned long last; if non-zero, last number in set +SEARCHSET *next; next SEARCHSET in list (AND'ed) + + SEARCHOR: two search programs, OR'ed together +SEARCHPGM *first; first program +SEARCHPGM *second; second program +SEARCHOR *next; next SEARCHOR in list + + SEARCHPGMLIST: list of search programs +SEARCHPGM *pgm; search program (AND'd with others in list) +SEARCHPGMLIST *next; next SEARCHPGM in list + + mail_search(), the older interface, accepts a search criteria +argument as a character string in IMAP2 (RFC-1176) format. Do not try +to use any IMAP4 search criteria with this interface. + + The application's mm_searched() function is called for each +message that matches the search criteria. In addition, after the +search is completed, the "fast" information (see mail_fetchfast_full() +and envelopes of the searched messages are fetched (this is called +pre-fetching). + + If there is any problem in searching, a message will be passed to +the application via the mm_log() facility. + + The flags for mail_search_full() are a bit mask with one or more +of the following: + SE_UID Return UIDs instead of sequence numbers + SE_FREE Return the search program to free storage after + finishing + SE_NOPREFETCH Don't prefetch searched messages. + + +unsigned long *mail_sort (MAILSTREAM *stream,char *charset,SEARCHPGM *spg, + SORTPGM *pgm,long flags); + stream stream to sort + charset MIME character set to use when sorting strings + spg search program + pgm sort program + flags option flags + + + This function is a variant of mail_search_full(). It accepts an +additional argument, a sort program, which specifies one or more sort +rules to be applied to the result. If the searching and sorting are +successful, it returns a 0-terminated vector of message sequence +numbers (or UIDs if SE_UID is set). This vector is created out of +free storage, and must be freed with fs_give() when finished with it. + + A sort program is a structure that holds the following data: +unsigned int reverse : 1; + reverse sorting of this key +short function; sort rule, one of the following: + SORTDATE message Date + SORTARRIVAL arrival date + SORTFROM mailbox in first From address + SORTSUBJECT message Subject + SORTTO mailbox in first To address + SORTCC mailbox in first cc address + SORTSIZE size of message in octets +SORTPGM *next; next sort program to be applied if two or more + messages collate identically with this rule + + The flags for mail_search_full() are a bit mask with one or more +of the following: + SE_UID Return UIDs instead of sequence numbers + SE_FREE Return the search program to free storage after + finishing + SE_NOPREFETCH Don't prefetch searched messages. + SO_FREE Return the sort program to free storage after + finishing + + Miscellaneous Mailbox and Message Functions + +long mail_ping (MAILSTREAM *stream); + stream string to ping + + The function pings the stream to see if it is still active. It may +discover new mail; this is the preferred method for a periodic "new mail +check" as well as a "keep alive" for servers which have an inactivity +timeout. It returns T if the stream is still alive, NIL otherwise. + + If new mail is found, the application's mm_exists() function is +called with the newly-determined number of messages in the mailbox. + + +void mail_check (MAILSTREAM *stream); + stream stream to checkpoint + + This function causes a mailstore-defined checkpoint of the +mailbox. This may include such things as a writeback to disk, a check +for flag changes in a shared mailbox, etc. It is not a "check for new +mail"; mail_ping() performs this function (as potentially does any other +function). The status of the check is passed to the application via the +mm_log() facility. + + +void mail_expunge (MAILSTREAM *stream); + stream string to expunge + + This function causes an expunge (permanent removal of messages +which are marked as deleted) of the mailbox. The application's +mm_expunged() function is called for each message that has been +expunged. The application's mm_exists() function is called at the start +and end of the expunge to ensure synchronization. The status of the +expunge is passed to the application via the mm_log() facility. + + Note that the decrementing of msgno's for subsequent messages +happens immediately; for example, if three consequtive messages starting +at msgno 5 are expunged, mm_expunged() will be called with a msgno of 5 +three times. + + +long mail_copy (MAILSTREAM *stream,char *sequence,char *mailbox); +long mail_move (MAILSTREAM *stream,char *sequence,char *mailbox); +long mail_copy_full (MAILSTREAM *stream,char *sequence,char *mailbox, + long options); + stream stream to copy + sequence IMAP-format set of message numbers + mailbox destination mailbox name + options option flags + + This function causes the messages in the specified sequence to be +copied to the specified mailbox. T is returned if the copy is +successful. mail_move() is equivalent to setting CP_MOVE in the options. + + If there is any problem in copying, a message will be passed to +the application via the mm_log() facility and the function returns NIL. +No copying is actually done in this case. + + Note that the mailbox must be on the same host as the stream and +is a mailbox of the type of the source mailbox only. + + The flags for mail_search_full() are a bit mask with one or more +of the following: + CP_UID The sequence argument contains UIDs instead of + sequence numbers + CP_MOVE Delete the messages from the current mailbox + after copying to the destination. + + +long mail_append (MAILSTREAM *stream,char *mailbox,STRING *message); +long mail_append_full (MAILSTREAM *stream,char *mailbox,char *flags,char *date, + STRING *message); + stream stream to use if non-NIL (in the IMAP case) + mailbox destination mailbox name + flags flags to set on message if non-NIL + date internal date (received date) to set on message if non-NIL + message string structure of message to write + + This function writes the message in the string structure to the +destination mailbox, along with the flags and date if specified. This +is useful in those cases where you can't use mail_copy(), e.g. when +copying from one server to another; you can always fetch the message +and then mail_append() it to the destination. It may also be useful +for maintaining an outbox of your outgoing mail. + + +void mail_gc (MAILSTREAM *stream,long gcflags); + stream stream to GC if non-NIL (else GC's all streams) + flags option flags + + This function garbage collects (purges) the cache of entries of +a specific type. Some drivers do not allow purging of particular +cache types, and an attempt to do so is ignored. + + The flags for mail_gc() are a bit mask with one or more of the +following: + GC_ELT message cache elements + GC_ENV ENVELOPEs and BODYs + GC_TEXTS cached texts + + Date/Time Handling Functions + + +char *mail_date (char *string,MESSAGECACHE *elt); + string destination string + elt message cache element containing date + + This function accepts a message cache element that contains date +information, and writes an IMAP-4 date string, that is, one in form: + dd-mmm-yyyy hh:mm:ss +zzzz +based upon the data in the elt. The destination string must be large +enough to hold this string. + + +char *mail_cdate (char *string,MESSAGECACHE *elt); + string destination string + elt message cache element containing date + + This function accepts a message cache element that contains date +information, and writes a ctime() format date string, that is, one in +form: + www mmm dd hh:mm:ss yyyy\n +based upon the data in the elt. The destination string must be large +enough to hold this string. + + +long mail_parse_date (MESSAGECACHE *elt,char *string); + elt message cache element to store parsed date + string source date string + + This function parses the date/time stored in the given string, +in format: + [www,] date [[hh:mm[:ss][-zzz| +zzzz] +where the date can be any of: + mm/dd/yy, mm/dd/yyyy, dd-mmm-yy, dd-mmm-yyyy, dd mmm yy, dd mmm yyyy +and stores the result of the parse in the elt. If the parse is +successful, T is returned, else NIL. + + +unsigned long mail_longdate (MESSAGECACHE *elt); + elt message cache element containing date. + + This function accepts a message cache element that contains date +information, and returns the number of days since the base time of the +imap-4 toolkit. At present, this is the same as the Unix time() value +for that date/time, and hence can be used for functions such as utime(). + + Utility Functions + +void mail_debug (MAILSTREAM *stream); + stream stream to debug + + This function enables telemetry logging for this stream. All +telemetry is passed to the application via the mm_dlog() facility. + + +void mail_nodebug (MAILSTREAM *stream); + stream stream to disable debugging + + This function disables telemetry logging for this stream. + + +long mail_sequence (MAILSTREAM *stream,char *sequence); + stream stream to set the sequence bits + sequence IMAP-format message set string + + This function parses the given sequence string for message +numbers, sets the sequence bit in the stream's message cache element +of all messages in the sequence (and turns it off in all other message +cache elements). If the parse is successful, T is returned, else NIL. + + +long mail_uid_sequence (MAILSTREAM *stream,char *sequence); + stream stream to set the sequence bits + sequence IMAP-format message set string + + This function parses the given sequence string for unique +identifiers, sets the sequence bit in the stream's message cache +element of all messages in the sequence (and turns it off in all other +message cache elements). If the parse is successful, T is returned, +else NIL. + + +long mail_parse_flags (MAILSTREAM *stream,char *flag,unsigned long *uf); + stream stream (used to get user flags) + flag IMAP-format flag string to parse + uf returned location of user flags + + The function parses the given flag string, and returns the system +flags as its return value and the user flags in the location pointed +to by the uf argument. If there is an error in parse, a log message +is issued via mm_log() and this function returns NIL. + + +unsigned long mail_filter (char *text,unsigned long len,STRINGLIST *lines, + long flags); + text RFC 822 text to filter + len length in octets in the text argument + lines string list of header file names to filter + flags option flags + + This function supports the header lines filtering function of +mail_fetchheader_full(). The lines argument contains a list of header +field names to use in subsetting the header text. Only those lines +which have that header field name are returned, unless FT_NOT is set +in which case only those lines which do not have that header field +name are returned. + + The options for mail_filter() are a bit mask with one or more of +the following: + FT_NOT The returned header lines are those that are + not in the lines argument + + +long mail_search_msg (MAILSTREAM *stream,unsigned long msgno,char *charset, + SEARCHPGM *pgm); + stream stream to search + msgno message number of message to inspect + charset character set of search strings + pgm search program to test + + This function implements mail_search_full() locally in cases when +it is not done by a server (e.g. local mail files, NNTP/POP). It +inspects the given message on that stream to see if it matches the +criteria or not. If it matches, T is returned, else NIL. + + +SEARCHPGM *mail_criteria (char *criteria); + criteria IMAP2-format search criteria string + + This function accepts an IMAP2-format search criteria string and +parses it. If the parse is successful, it returns a search program +suitable for use in mail_search_full(). + WARNING: This function does not accept IMAP4 search criteria. + The source string must be writeable (this restriction was also + in the old IMAP2 c-client). + + Data Structure Instantiation/Destruction functions + + These functions are used to obtain structures from free storage and +to release them. + +ENVELOPE *mail_newenvelope (void); +ADDRESS *mail_newaddr (void); +BODY *mail_newbody (void); +BODY *mail_initbody (BODY *body); +PARAMETER *mail_newbody_parameter (void); +PART *mail_newbody_part (void); +STRINGLIST *mail_newstringlist (void); +SEARCHPGM *mail_newsearchpgm (void); +SEARCHHEADER *mail_newsearchheader (char *line); +SEARCHSET *mail_newsearchset (void); +SEARCHOR *mail_newsearchor (void); +SEARCHPGMLIST *mail_newsearchpgmlist (void); +SORTPGM *mail_newsortpgm (void); + + These functions, all named mail_new...(), create a new structure of +the given type and initialize all of its elements to zero or empty. + +void mail_free_body (BODY **body); +void mail_free_body_parameter (PARAMETER **parameter); +void mail_free_body_part (PART **part); +void mail_free_cache (MAILSTREAM *stream); +void mail_free_elt (MESSAGECACHE **elt); +void mail_free_lelt (LONGCACHE **lelt); +void mail_free_envelope (ENVELOPE **env); +void mail_free_address (ADDRESS **address); +void mail_free_stringlist (STRINGLIST **string); +void mail_free_searchpgm (SEARCHPGM **pgm); +void mail_free_searchheader (SEARCHHEADER **hdr); +void mail_free_searchset (SEARCHSET **set); +void mail_free_searchor (SEARCHOR **orl); +void mail_free_searchpgmlist (SEARCHPGMLIST **pgl); +void mail_free_sortpgm (SORTPGM **pgm); + + These functions, all named mail_free_...(), take a pointer to a +structure pointer, free all contained strings and structures within the +structure, and finally free the structure itself and set its pointer to +NIL. For example, mail_free_envelope() frees all the ADDRESS structures +contained in the envelope. + + Normally, mail_free_elt() and mail_free_lelt() are used only if the +main program has a private pointer to cache elements. If so, it is +expected to increment the cache element's lockcount when it makes a +private pointer, and to call this function when it is finished with it. + + Authentication Functions + +char *mail_auth (char *mechanism,authresponse_t resp,int argc,char *argv[]); + mechanism authentication mechanism name + resp callback function for providing responses + argc main() function argc value + argv main() function argv value + + This server function searches the list of authenticators that was +established by auth_link() for an authenticator with the given name. If +an authenticator is found, authentication is initialized. The function +pointed to by resp is called as the authenticator requires responses. + + +AUTHENTICATOR *mail_lookup_auth (unsigned int i); + i position in authenticator list + + This function returns the nth authenticator in the list, where n is +the value of it. + + +unsigned int mail_lookup_auth_name (char *mechanism); + mechanism authentication mechanism name + + This function searches the list of authenticators for an +authenticator with the given name, and returns its position in the +authenticator list. + + + The functions below are provided by c-client client drivers or by +servers to support the protocol-dependent parts of authentication. + +typedef void *(*authchallenge_t) (void *stream,unsigned long *len); + stream stream to read challenge + len pointer to returned length in octets + + This driver function is called by an authenticator to read a +challenge from the given protocol stream in a protocol-dependent way. +It returns that challenge in binary and its length in octets to the +authenticator. + + +typedef long (*authrespond_t) (void *stream,char *s,unsigned long size); + stream stream to send response + s response string + size length of response string in octets + + This driver function is called by an authenticator to send a +challenge response to the given stream in a protocol-dependent way. +It returns T if successful, NIL if failure. + + +typedef char *(*authresponse_t) (void *challenge,unsigned long clen, + unsigned long *rlen); + challenge challenge string + clen length of challenge string in octets + rlen pointer to returned length of response string + + This server function is called with a challenge string of clen +octets. It sends, according to whatever protocol (IMAP, POP, etc.) it +uses, and returns the received response and response length in octets. + + +typedef long (*authclient_t) (authchallenge_t challenger, + authrespond_t responder,NETMBX *mb,void *s, + unsigned long trial); + challenger pointer to protocol-dependent challenge reader function + responder pointer to protocol-dependent response sender function + mb NETMBX struct of the mailbox desired to open + s stream for protocol-dependent routines to use + trial number of authentication attempts remaining + + This client authenticator function negotiates reading challenges +and sending responses for a particular authenticator (Kerberos, etc.) +over the protocol, and returns T if authenticated or NIL if failed. + + +typedef char *(*authserver_t) (authresponse_t responder,int argc,char *argv[]); + responder pointer to protocol-dependent responder function + argc main() function argc value + argv main() function argv value + + This server authenticator function negotiates sending challenges and +reading responses for a particular authenticator (Kerberos, etc.), and +returns either the authenticated user name or NIL if authentication +failed. + + Network Access Functions + + These functions provide a layer of indirection between the TCP +routines and upper level routines. This makes it possible to insert +additional code (e.g. privacy or checksum handling). + +NETSTREAM *net_open (char *host,char *service,unsigned long port); + host host name + service contact service name + port contact port number + + This function opens a TCP connection to the given host and service +or port. + + +NETSTREAM *net_aopen (NETMBX *mb,char *service,char *usrbuf); + NETMBX parsed mailbox specification + service stream to open (at present, only /etc/rimapd is used) + usrbuf buffer to return login user name + + This function attempts to open a preauthenticated connection to the +given mailbox and service. It will return the login user name of the +preauthenticated connection, as well as an open network stream, if +successful. + + +char *net_getline (NETSTREAM *stream); + stream network stream to read + + This routine reads a text line from the stream. It calls +stream->dtb->getline, which normally points to tcp_getline() but can be +set to some other function. + + +long net_getbuffer (void *stream,unsigned long size,char *buffer); + stream network stream to read + size length of data in octets + buffer buffer of at least size octets + + This routine reads data from the stream. It calls +stream->dtb->getbuffer, which normally points to tcp_getbuffer() but can +be set to some other function. + + +long net_soutr (NETSTREAM *stream,char *string); + stream network stream to write + string null-terminated string to output + + This routine writes a null-terminated string to the stream. It +calls stream->dtb->soutr, which normally points to tcp_soutr() but can +be set to some other function. + + +long net_sout (NETSTREAM *stream,char *string,unsigned long size); + stream network stream to write + string string to output + size length of string in octets + + This routine writes a string of length size to the stream. It +calls stream->dtb->sout, which normally points to tcp_sout() but can be +set to some other function. + + +void net_close (NETSTREAM *stream); + stream stream to close + + This routine closes the stream. It calls stream->dtb->close, which +normally points to tcp_close() but can point to some other function. + + +char *net_host (NETSTREAM *stream); + stream stream to inspect + + This routine returns the remote host name of the stream. It calls +stream->dtb->host, which normally points to tcp_host() but can point +to some other function. + + +unsigned long net_port (NETSTREAM *stream); + stream stream to inspect + + This routine returns the remote port number of the stream. It calls +stream->dtb->port, which normally points to tcp_port() but can point +to some other function. + + +char *net_localhost (NETSTREAM *stream); + stream stream to inspect + + This routine returns the local host name of the stream. It calls +stream->dtb->localhost, which normally points to tcp_localhost() but can +point to some other function. + + Subscription Management Functions + +long sm_subscribe (char *mailbox); + mailbox mailbox name to subscribe + + This function adds the given mailbox name to the local subscription +list, and returns T if successful, NIL if failure. + + +long sm_unsubscribe (char *mailbox); + mailbox mailbox name to unsubscribe + + This function removes the given mailbox name from the local +subscription list, and returns T if successful, NIL if failure. + +char *sm_read (void **sdb); + sdb data to use in subsequent calls, or NIL if first call + + This function returns the local subscription list as null +terminated strings. Each call returns the next element in the list. +The first call should be with sdb pointing to a NIL pointer; this will +be filled in for subsequent calls. At the last call, NIL will be +returned. + + Miscellaneous Utility Functions + +char *ucase (char *string); + string string to convert + + This function converts each lowercase character of the specified +string to uppercase and returns the string. + + +char *lcase (char *string); + string string to convert + + This function converts each uppercase character of the specified +string to lowercase and returns the string. + + +char *cpystr (char *string); + string string to copy + + This function makes a copy of the string from free storage and returns +the copy. + + +long find_rightmost_bit (long *valptr); + valptr pointer to value to search + + This function returns -1 if the 32-bit value pointed to by valptr +is non-zero, otherwise it returns the bit number (0 = LSB, 31 = MSB) of +the right-most bit in that value. This is used to convert from the bits +in the cache's userflags item to an index into the stream's userFlags +array of flag texts. + + +long min (long i,long j); + i first argument + j second argument + + This function returns the minimum of the two integers. + +long max (long i,long j); + i first argument + j second argument + + This function returns the maximum of the two integers. + +long search (char *s,long c,char *pat,long patc); + s string to search + c size of string + pat pattern to search in string + patc size of pattern + + This function does a fast case-independent search for the given +pattern in pat (length patc) in base string s, and returns T if the +pattern is found in the string. + + +long pmatch (char *s,char *pat,delim); +long pmatch_full (char *s,char *pat,delim); + s string to match + pat wildcard (* and %) to match in pattern + delim hierarchy delimiter + + This function returns T if the given wildcard pattern matches the +string in s with hierarchy delimiter delim. Otherwise NIL is returned. + + +long dmatch (char *s,char *pat,char delim); + s string to match + pat wildcard (* and %) to match in pattern + delim hierarchy delimiter + + This function returns T if the given wildcard pattern matches the +directory. If not, then none of the elements in the directory are +considered for recursive checking with pmatch_full(). + + SMTP Functions + +SMTPSTREAM *smtp_open (char **hostlist,long debug); + hostlist vector of SMTP server host names to try + debug non-zero if want protocol telemetry debugging + + This function opens an SMTP connection to a one of the hosts in the +host list and if successful returns a stream suitable for use by the +other SMTP functions. The hosts are tried in order until a connection is +successfully opened. If debug is non-NIL, protocol telemetry is logged +via mm_dlog(). NIL is returned if this function fails to open a +connection to any of the hosts in the list. + +void smtp_close (SMTPSTREAM *stream); + stream stream to close + + This function closes the SMTP stream and frees all resources +associated with it that it may have created. + +long smtp_mail (SMTPSTREAM *stream,char *type,ENVELOPE *msg,BODY *body); + stream stream to transmit mail + type mail type (MAIL, SEND, SAML, SOML) + msg message envelope + body message body + + This function negotiates an SMTP transaction of the specified type +(one of "MAIL", "SEND", "SAML", or "SOML") to deliver the specified +message. This function returns T if success or NIL if there is any +failure. The text reason for the failure is in stream->reply item; if +it is associated with a recipient it is also in that address' +address->error item. + + +void smtp_debug (SMTPSTREAM *stream); + stream stream to enable debugging telemetry + + This function enables SMTP protocol telemetry logging for this +stream. All SMTP protocol operations are passed to the application via +the mm_dlog() facility. + + +void smtp_nodebug (SMTPSTREAM *stream); + stream stream to disable debugging telemetry + + This function disables SMTP protocol telemetry logging for this +stream. + + +typedef void (*smtpverbose_t) (char *buffer); + buffer pointer to verbose reply buffer + + This is the argument to the SET_SMTPVERBOSE mail_parmameter() call. +If this function pointer is non-NIL, then if a verbose SMTP response +(with SMTP code less than 100) is received, this function is called with +that response text as its argument. + + NNTP Functions + +NNTPSTREAM *nntp_open (char **hostlist,long debug); + hostlist vector of NNTP server host names to try + debug non-zero if want protocol telemetry debugging + + This function opens an NNTP connection to a one of the hosts in the +host list and if successful returns a stream suitable for use by the +other MTP functions. The hosts are tried in order until a connection is +successfully opened. If debug is non-NIL, protocol telemetry is logged +via mm_dlog(). NIL is returned if this function fails to open a +connection to any of the hosts in the list. + + +void nntp_close (NNTPSTREAM *stream); + stream stream to close + + This function closes the NNTP stream and frees all resources +associated with it that it may have created. + + +long nntp_mail (NNTPSTREAM *stream,ENVELOPE *msg,BODY *body); + stream stream to transmit mail + msg message envelope + body message body + + This function negotiates an NNTP posting transaction to deliver +the specified news message. This function returns T if success or NIL +if there is any failure. The text reason for the failure is in +stream->reply item; if it is associated with a recipient it is also in +that address' address->error item. + + RFC 822 Support Functions + + Although rfc822.c contains several additional functions besides +these, only the functions documented here should be used by +applications. The other functions are for internal use only. + + +void rfc822_header (char *header,ENVELOPE *env,BODY *body); + header buffer to write RFC 822 header + env message ENVELOPE (used to obtain RFC 822 information) + body message BODY (used to obtain MIME information) + + This function writes an RFC 822 format header into header based +on the information in the envelope and body. The header buffer must +be large enough to contain the full text of the resulting header. + + +void rfc822_write_address (char *dest,ADDRESS *adr); + dest buffer to write address list + adr RFC 822 ADDRESS list + + This function writes an RFC 822 format address list into dest +based on the information in adr. The dest buffer must be large enough +to contain the full text of the resulting address list. + +void rfc822_parse_msg (ENVELOPE **en,BODY **bdy,char *s,unsigned long i, + STRING *b,char *host,char *tmp); + en destination pointer where message ENVELOPE will be stored + bdy destination pointer where message BODY will be stored + s RFC 822 header to parse (character string) + i length of RFC 822 header + b stringstruct of message body + host default host name if an address lacks an @host. + temp scratch buffer, must be long enough to hold unwound + header lines (a buffer that is i octets long is OK) + + This function parses the RFC 822 header pointed to by s with body +pointed to by string structure b into the specified destination +envelope and body pointers, using host as the default host name and +tmp as a scratch buffer. New ENVELOPE and BODY structures are +created; when finished with them the application must free them with +mail_free_envelope() and mail_free_body(). Any parsing errors are +noted via the mm_log() mechanism using log type PARSE. + + +void rfc822_parse_adrlist (ADDRESS **lst,char *string,char *host); + lst destination pointer where ADDRESS will be stored + string string of addresses to parse + host default host name if an address lacks an @host. + + This function parses the address list in the given string into an +address list in lst. Any addresses missing a host name are have the +host name defaulted from the host argument. If the destination list +is non-empty it appends the new addresses to the list. Any parsing +errors are noted via the mm_log() mechanism using log type PARSE. + +long rfc822_output (char *t,ENVELOPE *env,BODY *body,soutr_t f,void *s, + long ok8bit); + t scratch buffer, large enough to hold message header + env message ENVELOPE + body message BODY + f I/O function to write to + s stream for I/O function f + ok8bit non-zero if OK to output 8-bit data + + This function writes the message described with the given +envelope and body. Any body part contents of type ENCBINARY is +converted to ENCBASE64 before sending. If ok8bit is NIL, any message +data of type ENC8BIT is converted to ENCQUOTEDPRINTABLE before +sending; if ok8bit is non-NIL then ENC8BIT data is sent as-is. T is +returned if the function succeeds, else NIL is returned. + + The function f is typically net_soutr(), but it can be any +function which matches + typedef long (*soutr_t) (void *stream,char *string); +where stream holds sufficient information to enable the output routine +to know where to output to, and the string is a null-terminated string +to output. This function returns either T or NIL, and that value is +passed up to rfc822_output() for its return. + + +void *rfc822_base64 (char *src,unsigned long srcl,unsigned long *len); + src source string + srcl size of source string in octets + len pointer to where destination string length in octets + will be returned + + This function decodes a BASE64 body part given a source string +and its length. The decoded body part as a sequence of binary octets +is returned, and its length is returned in len. + + +char *rfc822_qprint (char *src,unsigned long srcl,unsigned long *len); + src source string + srcl size of source string in octets + len pointer to where destination string length in octets + will be returned + + This function decodes a QUOTED-PRINTABLE body part given a source +string and its length. The decoded body part as an 8-bit character +string is returned, and its length is returned in len. + + Operating System-Dependent Public Interface + + These functions are in OS-dependent code, and are rewritten each +time c-client is ported to a new operating system. + + +void rfc822_date (char *date); + date buffer to write the date, must be large enough + + This function is called to get the current date and time in an +RFC 822 format string into the given buffer. + + +void *fs_get (size_t size); + size number of octets requested + + This function allocates and returns a block of free storage of +the specified size. Unlike malloc(), there is no failure return; this +function must return with the requested storage. + + +void fs_resize (void **block,size_t size); + block pointer to pointer to block to be resized + size new size in octets + + This function resizes the free storage block, updating the +pointer if necessary. Unlike realloc(), there is no failure return; +this function must return with the requested storage. + + +void fs_give (void **block); + block pointer to pointer to block to free + + This function releases a block of free storage allocated by +fs_get(). It also erases the block pointer, so it isn't necessary to +do this in the application. + + +void fatal (char *string); + string message string + + This function is called when an "impossible" error is detected +and the client wishes to crash. The string should contain a reason. + + +char *strcrlfcpy (char **dst,long *dstl,char *src,long srcl); + dst pointer to destination string pointer + dstl pointer to destination string size + src source strin + srcl source string size + + This function is called to copy into a destination string dst of +size dstl (resized if necessary), a CRLF newline form string from +local format string src of size srcl. + + +TCPSTREAM *tcp_open (char *host,long port); +TCPSTREAM *tcp_aopen (char *host,char *service); +char *tcp_getline (TCPSTREAM *stream); +long tcp_getbuffer (TCPSTREAM *stream,long size,char *buffer); +long tcp_soutr (TCPSTREAM *stream,char *string); +void tcp_close (TCPSTREAM *stream); +char *tcp_host (TCPSTREAM *stream); +unsigned long tcp_port (TCPSTREAM *stream); +char *tcp_localhost (TCPSTREAM *stream); + + These functions are TCP-specific versions of the more general +net_xxx() functions. These should not be called directly by +applications. + + +char *tcp_clienthost (char *dst); + dst destination string buffer + + This function should be called only by a server called by inetd +or similar mechanism which maps standard input to a network socket. +It returns the host name of the other end (e.g. the client of a +server) using the given string buffer, or NIL if it can't get this +information. + + Main Program Callbacks + + All applications which use the c-client must have the following +callbacks to handle events from c-client. Note that in any callback +which involves a mail stream, the stream is locked and you can not +recursively call c-client from the callback. This may also be true in +callbacks which do not have a stream; in general, the rule is "do not +call c-client, especially any mail_xxx() function, from a c-client +callback". + + +void mm_flags (MAILSTREAM *stream,unsigned long number); + stream stream where event happened + number message number + + This function is called when c-client manipulates the flags for +the given message number. This alerts the application that it may +need to inspect that message's flags to see if there are any +interesting changes. + + +void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status); + stream stream where event happened + mailbox mailbox name for this status + status MAILSTATUS structure with message status + + This function is called when c-client reports status of a mailbox +(generally as the result of a mail_status() function call). The +returned MAILSTATUS structure has the following members: + +long flags; validity flags. These are the same as + the SA_xxx option flags in the + mail_status() call, and they indicate + which of the other members of the + MAILSTATUS structure have usable data + (i.e. if SA_MESSAGES is not set, do + not believe status->messages!!). +unsigned long messages; number of messages if SA_MESSAGES +unsigned long recent; number of recent messages if SA_RECENT +unsigned long unseen; number of unseen messages if SA_UNSEEN +unsigned long uidnext; next UID to be assigned if SA_UIDNEXT +unsigned long uidvalidity; UID validity value if SA_UIDVALIDITY + + +void mm_searched (MAILSTREAM *stream,unsigned long number); + stream stream where event happened + number message number + + This function is called to notify the main program that this +message number matches a search (generally as the result of a +mail_search_full() function call). + + +void mm_exists (MAILSTREAM *stream,unsigned long number); + stream stream where event happened + number message number + + This function is called to notify the main program that there are +this many messages in the mailbox. It is also used to notify the main +program of new mail, by announcing a higher number than the main +program was previously aware. + + +void mm_expunged (MAILSTREAM *stream,unsigned long number); + stream stream where event happened + number message number + + This function is called to notify the main program that this +message number has been expunged from the mail file and that all +subsequent messages are now referenced by a message number one less +than before. This implicitly decrements the number of messages in the +mailbox. + + +void mm_list (MAILSTREAM *stream,char delim,char *name,long attrib); + stream stream where event happened + delim hierarchy delimiter + name mailbox name + attrib mailbox attributes + + This function is called to notify the main program that this +mailbox name matches a mailbox listing request (generally as the +result of a mail_list() function call). The hierarchy delimiter is a +character that separates out levels of hierarchy in mailbox names. +The attributes are a bit mask with one of the following: + LATT_NOINFERIORS + it is not possible for there to be any + hierarchy inferiors to this name (that is, + this name followed by the hierarchy delimiter + and additional name characters). + LATT_NOSELECT this is not a mailbox name, just a hierarchy + level, and it may not be opened by mail_open() + LATT_MARKED this mailbox may have recent messages + LATT_UNMARKED this mailbox does not have any recent messages + + +void mm_lsub (MAILSTREAM *stream,char delim,char *name,long attrib); + stream stream where event happened + delim hierarchy delimiter + name mailbox name + attrib mailbox attributes + + + This function is called to notify the main program that this +mailbox name matches a subscribed mailbox listing request (generally +as the result of a mail_lsub() function call). The hierarchy +delimiter is a character that separates out levels of hierarchy in +mailbox names. The attributes are a bit mask with one of the +following: + LATT_NOINFERIORS + it is not possible for there to be any + hierarchy inferiors to this name (that is, + this name followed by the hierarchy delimiter + and additional name characters). + LATT_NOSELECT this is not a mailbox name, just a hierarchy + level, and it may not be opened by mail_open() + LATT_MARKED this mailbox may have recent messages + LATT_UNMARKED this mailbox does not have any recent messages + + +void mm_notify (MAILSTREAM *stream,char *string,long errflg); + stream stream where event happened + string message string + errflg message error level + + This function is called to deliver a stream-oriented message +event. This is the mechanism by which any IMAP response codes for any +application (e.g. TRYCREATE) are delivered to the application. +No newline is included in the string, so this function has to output +its own. + + The message error level is one of the following: + + NIL normal operation. The text is `babble' that may be + interesting to the user, e.g. the greeting message + from a server. + + WARN A warning event. This event should be displayed to + the user. Examples: a mailbox rewrite failed because + of disk full, but the previous mailbox contents were + recovered. + + ERROR An error event. This event should be displayed to + the user, or at least logged someplace. This type of + error shouldn't happen, and so should be called to the + attention of support staff. Whatever happened has + probably disrupted the user's work. Examples: an + untagged BAD from an IMAP server. + + +void mm_log (char *string,long errflg); + string message string + errflg message error level + + This function is called to deliver a log message. No newline is +included in the string, so this function has to output its own. In +general, it is intended that these messages are logged someplace, and +possibly shown to the user. + + The message error level is one of the following: + + NIL normal operation. The text is `babble' that may be + interesting to the user, e.g. "Expunged 3 messages". + + PARSE An RFC 822 parsing error. Since bogus headers are + all-too-common in the real world, these can often be + ignored on the "garbage in, garbage out" princple. + However, since surprising results can be yielded when + trying to parse garbage, this message should be logged + somewhere so it can be figured out what happened. + + WARN A warning event. This event should be displayed to + the user. It occurs when an error condition has + happened, but c-client knows what to do to recover. + Examples: "Can't open read-write, so opening + read-only", "Empty mailbox", "Login failed, try + again", "Waiting for mailbox to become unlocked", + "IMAP protocol error". Although a user should be + told about a warning, it's generally not necessary + to interrupt the flow of her work (e.g. it's alright + to display the warning in a scrolling window, but + not necessary to require the user to do anything). + + ERROR An error event. This event should be displayed to + the user, or at least logged someplace. This is a + serious error condition occured that aborted the + requested operation and possibly also aborted the mail + stream. This ranges from normal error conditions such + as "Can't open mailbox", "too many login failures, go + away" to bizarre conditions such as "Apparent new mail + appeared in the mailbox that doesn't look like mail, + program aborting". Errors must be called to the + user's attention, and probably should require some + sort of acknowledgement (e.g. answering a modal panel) + before the application proceeds. + + +void mm_dlog (char *string); + string message string + + This function is called to deliver a debugging telemetry +message. No newline is included in the string, so this function has +to output its own. This is called only when debugging is enabled. + + +void mm_login (NETMBX *mb,char *user,char *pwd,long trial); + mb parsed mailbox specification + user pointer to where to return user name + pwd pointer to where to return password + trial number of prior login attempts + + This function is called to get a user name and password for the +given network mailbox. It stores the user name and password in the +strings pointed to by the appropriate arguments. The trial argument +is the number of attempts to perform the login and is initially zero +(e.g. for a default username and password login functionality). It is +incremented for each subsequent trial until the maximum number of +trials are made. + + +void mm_critical (MAILSTREAM *stream); + stream stream where event happened + + This function is called to alert the application that c-client +is about to run some critical code on that stream that may result in a +clobbered mail file if it is interrupted. It may be desirable to +disable CTRL/C, etc. during this time. + + +void mm_nocritical (MAILSTREAM *stream); + stream stream where event happened + + This function is called to alert the application that c-client +is no longer running critical code on that stream that may result in a +clobbered mail file if it is interrupted. + + +long mm_diskerror (MAILSTREAM *stream,long errcode,long serious); + stream stream where event happened + errcode OS error code for disk error + serious non-zero if c-client can not undo the operation (and + thus must retry to avoid mail file damage) + + This function is called to alert the application that the +c-client has encountered an unrecoverable write error when trying to +update the mail file. errcode contains the system error code. If +serious is non-zero, then it is probable that the disk copy of the +mailbox has been damaged. + + The return value from this function is the abort flag; if serious +is zero and the abort flag is non-zero, the operation is aborted. If +the abort flag is zero or if serious was non-zero, a return from this +function will retry the failing operation. + + +void mm_fatal (char *string); + string message string + + This function is called from the fatal() routine in the +operating system code to notify the main program that it is about to +crash. The string contains a reason. At the very minimum, the main +program should do something like + mm_log (string,ERROR); +and then return. No newline is included in the string, so this +function has to output its own. + + Driver interface + + When writing a new driver for the c-client, you must provide a +DRIVER stucture giving a dispatch vector between MAIL and the driver. +The DRIVER dispatch vector is described in mail.h. + +char *name; + Name by which the driver is known to c-client. + +unsigned long flags; + Attribute flags for this driver: + DR_DISABLE This driver is currently disabled. + DR_LOCAL This driver deals with local mailboxes; if + this is off it deals with mailboxes over a + network. + DR_MAIL This driver supports e-mail messages. + DR_NEWS This driver supports netnews messages + DR_READONLY This driver only allows read-only access; + mail_setflag(), mail_expunge(), etc. are + no-ops. + DR_NOFAST This driver does not implement mail_fetchfast() + in a fast way (e.g. it may have to fetch the + entire message text over a network to + calculate sizes). + DR_NAMESPACE This driver accepts and uses namespace format + names. + DR_LOWMEM This driver is designed for systems with very + limited amounts of memory (e.g. DOS) and + support routines called by this driver should + try not to use much memory. + +DRIVER *next; + Pointer to the next driver which this application supports (or NIL if +this is the last driver). Drivers are lunk together via the mail_link() +function. + +DRIVER *driver_valid (char *mailbox); + This function returns a pointer to the driver's DRIVER dispatch +vector iff this driver accepts the given name as a valid mailbox for this +driver. Otherwise, it returns the value of the next driver's +driver_valid() or NIL if there is no next driver. In other words, calling +driver_valid() for the first driver will return the driver dispatch vector +for the driver which supports this type of mailbox. + +void *driver_parameters (long function,void *value); + This function implements mail_parameters() for this driver. + +void driver_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents); + This function implements mail_scan() for this driver. + +void driver_list (MAILSTREAM *stream,char *ref,char *pat); + This function implements mail_list() for this driver. + +void driver_lsub (MAILSTREAM *stream,char *ref,char *pat); + This function implements mail_lsub() for this driver. + +long driver_subscribe (MAILSTREAM *stream,char *mailbox); + This function implements mail_subscribe() for this driver. + +long driver_unsubscribe (MAILSTREAM *stream,char *mailbox); + This function implements mail_unsubscribe() for this driver. + +long driver_create (MAILSTREAM *stream,char *mailbox); + This function implements mail_create() for this driver. + +long driver_delete (MAILSTREAM *stream,char *mailbox); + This function implements mail_delete() for this driver. + +long driver_rename (MAILSTREAM *stream,char *old,char *new); + This function implements mail_rename() for this driver. + +long driver_status (MAILSTREAM *stream,char *mailbox,long flags); + This function implements mail_status() for this driver. + +MAILSTREAM *driver_open (MAILSTREAM *stream); + This function opens the mailbox identified by the given stream. It +may use the data on the stream and create additional data on stream->local +as necessary. It should return the given stream unless it failed to open +the mailbox, in which case it should return NIL. + +void driver_close (MAILSTREAM *stream,long options); + This function implements mail_close() for this driver. + +void driver_fetchfast (MAILSTREAM *stream,char *sequence,long flags); + This function implements mail_fetchfast() for this driver. + +void driver_fetchflags (MAILSTREAM *stream,char *sequence,long flags); + This function implements mail_fetchflags() for this driver. + +ENVELOPE *driver_fetchstructure (MAILSTREAM *stream,unsigned long msgno, + BODY **body,long flags); + This function implements mail_fetchstructure() for this driver. + +char *driver_fetchheader (MAILSTREAM *stream,unsigned long msgno, + STRINGLIST *lines,unsigned long *len,long flags); + This function implements mail_fetchheader() for this driver. + +char *driver_fetchtext (MAILSTREAM *stream,unsigned long msgno, + unsigned long *len,long flags); + This function implements mail_fetchtext() for this driver. + +char *driver_fetchbody (MAILSTREAM *stream,unsigned long msgno,char *section, + unsigned long *len,long flags); + This function implements mail_fetchbody() for this driver. + +void driver_setflag (MAILSTREAM *stream,char *sequence,char *flag,long flags); + This function implements mail_setflag() for this driver. + +void driver_clearflag (MAILSTREAM *stream,char *sequence,char *flag, + long flags); + This function implements mail_clearflag() for this driver. + +void driver_search (MAILSTREAM *stream,char *charset,SEARCHPGM *pgm, + long flags); + This function implements mail_search() for this driver. + +unsigned long *driver_sort (MAILSTREAM *stream,char *charset,SEARCHPGM *spg, + SORTPGM *pgm,long flags); + This function implements mail_sort() for this driver. + +void *driver_thread (MAILSTREAM *stream,char *seq,long function,long flag); + This dispatch is reserved for a future threading capability. + +long driver_ping (MAILSTREAM *stream); + This function implements mail_ping() for this driver. + +void driver_check (MAILSTREAM *stream); + This function implements mail_check() for this driver. + +void driver_expunge (MAILSTREAM *stream); + This function implements mail_expunge() for this driver. + +long driver_copy (MAILSTREAM *stream,char *sequence,char *mailbox, + long options); + This function implements mail_copy() for this driver. + +long driver_append (MAILSTREAM *stream,char *mailbox,char *flags,char *date, + STRING *message); + This function implements mail_append() for this driver. + +void driver_gc (MAILSTREAM *stream,long gcflags); + This function implements mail_gc() for this driver. + + Driver Support Functions + +void mail_searched (MAILSTREAM *stream,unsigned long msgno); + stream stream where event happened + msgno message number + + This function is called by the driver to notify c-client that this +message number matches a search. It invokes the main program's +mm_searched() function. + +void mail_exists (MAILSTREAM *stream,unsigned long nmsgs); + stream stream where event happened + nmsgs number of messages + + This function is called by the driver to notify c-client that this +message number exists (i.e. there are this many messages in the mailbox). +It invokes the main program's mm_exists() function. + +void mail_recent (MAILSTREAM *stream,unsigned long recent); + stream stream where event happened + recent number of messages + + This function is called by the driver to notify c-client that this +many messages are "recent" (i.e. arrived in the mailbox since the previous +time the mailbox was opened). + +void mail_expunged (MAILSTREAM *stream,unsigned long msgno); + stream stream where event happened + msgno number of messages + + This function is called by the driver to notify MAIL that this +message number has been expunged from the mail file and that all subsequent +messages are now referenced by a message number one less than before. It +invokes the main program's mm_expunged() function. + +void mail_lock (MAILSTREAM *stream); + stream stream where event happened + This function sets the stream lock. It is an error to set the stream +lock if the stream is already locked. + + This is mainly used to catch errors due to a callback function +(e.g. mm_exists) inadvertantly recursing back to the MAIL routines and +establishing an infinite recursion. Normally, drivers will set the lock +prior to calling one of the callback functions above or, more likely, in +the beginning of the driver's non-reentrant "do operation" section. In the +IMAP4 driver, the stream lock is set when entering imap_send() and cleared +on exit. + +void mail_unlock (MAILSTREAM *stream); + stream stream where event happened + + This function releases the stream lock. It is an error to release the +stream lock if the stream is not locked. |