internal.txt
上传用户:ycwykj01
上传日期:2007-01-04
资源大小:1819k
文件大小:112k
- 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
- i new string pointer value
- 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 Structions" 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 the 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 inconsistant 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 apce.
- 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 yyyyn
- 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 no references 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.