imapext-2007

diff docs/internal.txt @ 0:ada5e610ab86

imap-2007e
author yuuji@gentei.org
date Mon, 14 Sep 2009 15:17:45 +0900
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/docs/internal.txt	Mon Sep 14 15:17:45 2009 +0900
     1.3 @@ -0,0 +1,2988 @@
     1.4 +/* ========================================================================
     1.5 + * Copyright 1988-2006 University of Washington
     1.6 + *
     1.7 + * Licensed under the Apache License, Version 2.0 (the "License");
     1.8 + * you may not use this file except in compliance with the License.
     1.9 + * You may obtain a copy of the License at
    1.10 + *
    1.11 + *     http://www.apache.org/licenses/LICENSE-2.0
    1.12 + *
    1.13 + * 
    1.14 + * ========================================================================
    1.15 + */
    1.16 +
    1.17 +	  Documentation of c-client Functions and Interfaces
    1.18 +
    1.19 +REVISED: 19 August 1996
    1.20 +
    1.21 +				  Credits
    1.22 +
    1.23 +     The original version of this document was written by Mark Crispin at
    1.24 +the University of Washington, and described the version of c-client that
    1.25 +supported the IMAP2 (RFC 1176) and IMAP2bis (unpublished) protocols.
    1.26 +
    1.27 +     This version is a substantial rewrite of that document, and was
    1.28 +written by Mark Crispin with funding from Sun Microsystems, Incorporated.
    1.29 +Sun's generous support of this work is gratefully acknowledged.
    1.30 +
    1.31 +
    1.32 +				 Road Map
    1.33 +
    1.34 +     This document is organized into the following sections.  Except as
    1.35 +noted, an implementor of an application that uses c-client needs to be
    1.36 +familiar with all of these sections.  Someone who plans to write a new
    1.37 +mailbox driver for c-client (or otherwise modify it) needs to be familiar
    1.38 +with all sections, no exception.
    1.39 +
    1.40 +History
    1.41 +	History of how c-client came about.
    1.42 +
    1.43 +Overview
    1.44 +	Read this before designing an application that uses c-client.
    1.45 +
    1.46 +c-client Structures
    1.47 +	Documentation of several important c-client structs which are
    1.48 +	used in, and returned by, c-client calls.
    1.49 +
    1.50 +String Structures
    1.51 +	Documentation of the concept of a "string structure", which
    1.52 +	provides random access to strings without requiring that the
    1.53 +	string be in memory.
    1.54 +
    1.55 +c-client Support Functions
    1.56 +	Documentation of support functions for c-client; these deal
    1.57 +	with c-client functionality.
    1.58 +
    1.59 +	Only mail_parameters() is of interest to most application
    1.60 +	developers.  Advanced application developers, particularly
    1.61 +	for limited memory systems, may also need to know about the
    1.62 +	readfn_t, mailgets_t, mailcache_t, and tcptimeout_t function
    1.63 +	pointer types, and possibly also the mail_valid_net_parse()
    1.64 +	function.
    1.65 +
    1.66 +Mailbox Access Functions
    1.67 +	Documentation of functions which deal with mailboxes;
    1.68 +	listing, subscribing, creating, deleting, renaming, status
    1.69 +	inquiries, opening, and closing mailboxes.
    1.70 +
    1.71 +Handle Functions
    1.72 +	Documentation of mail stream handles, which provide protection
    1.73 +	for an advanced application which may have multiple pointers to
    1.74 +	a single mail stream.  If a stream has a handle on it, closing
    1.75 +	the stream does not release its memory, so pointers to it in
    1.76 +	the application remain valid.  Freeing the last handle will free
    1.77 +	the entire stream.
    1.78 +
    1.79 +	This is only of interest for advanced application developers.
    1.80 +
    1.81 +Message Data Fetching Functions
    1.82 +	Documentation on message data fetching in an open mailbox,
    1.83 +	including parsed representations of RFC-822 and MIME headers
    1.84 +	and message text.  Also how to fetch message attributes (flags,
    1.85 +	internal date, sizes).
    1.86 +
    1.87 +Message Status Manipulation Functions
    1.88 +	Documentation on altering message flags in an open mailbox.
    1.89 +
    1.90 +Mailbox Searching
    1.91 +	Documentation on searching an open mailbox for messages which
    1.92 +	match certain criteria (e.g. "messages sent July 4 from Jones
    1.93 +	with text `Paris'").
    1.94 +
    1.95 +Miscellaneous Mailbox and Message Functions
    1.96 +	Documentation on other operations that would be used by an
    1.97 +	application but that don't fit into any of the above categories.
    1.98 +
    1.99 +Date/Time Handling Functions
   1.100 +	Documentation on functions that deal with date/time strings.
   1.101 +
   1.102 +	This is only of interest for advanced application developers
   1.103 +	and for implementors of new c-client drivers.
   1.104 +
   1.105 +Utility Functions
   1.106 +	Documentation on internal utility functions.
   1.107 +
   1.108 +	This is primarily of interest for implementors of new c-client
   1.109 +	drivers, but advanced application developers may also use some
   1.110 +	of these functions.
   1.111 +
   1.112 +Data Structure Instantiation/Destruction functions
   1.113 +	Documentation on creating and destroy c-client structures.
   1.114 +
   1.115 +	This is primarily of interest for implementors of new c-client
   1.116 +	drivers.  However, application developers will need some of
   1.117 +	these functions to create and destroy structures which are used
   1.118 +	as arguments to various application functions.
   1.119 +
   1.120 +Authentication Functions
   1.121 +	Documentation on support for network protocol authentication
   1.122 +	functions.
   1.123 +
   1.124 +	This is only of interest for implementors of new c-client
   1.125 +	drivers which deal with authentication mechanisms.
   1.126 +
   1.127 +Network Access Functions
   1.128 +	Documentation on creating and destroy c-client structures.
   1.129 +
   1.130 +	This is primarily of interest for implementors of new c-client
   1.131 +	drivers which deal with a network.  However, advanced
   1.132 +	application developers may need to use this information if they
   1.133 +	wish to insert their own layer into a network session.
   1.134 +
   1.135 +Subscription Management Functions
   1.136 +	Documentation on managing the local (client-based) subscription
   1.137 +	database file.
   1.138 +
   1.139 +	This is primarily of interest to advanced application developers.
   1.140 +
   1.141 +Miscellaneous Utility Functions
   1.142 +	Documentation on various useful utility functions, such as "make
   1.143 +	a copy of this string."
   1.144 +
   1.145 +SMTP Functions
   1.146 +	Documentation on posting email messages via SMTP protocol.
   1.147 +
   1.148 +NNTP Functions
   1.149 +	Documentation on posting netnews messages via NNTP protocol.
   1.150 +
   1.151 +RFC 822 Support Functions
   1.152 +	Documentation on public RFC-822/MIME functions.
   1.153 +
   1.154 +	This is primarily of interest for implementors of new c-client
   1.155 +	drivers and advanced application developers.
   1.156 +
   1.157 +Operating System-Dependent Public Interface
   1.158 +	Documentation on OS-dependent functions.  With the exception of
   1.159 +	fs_get(), fs_give(), and fs_resize(), which should be called
   1.160 +	instead of malloc(), free(), and realloc(), these functions are
   1.161 +	primarily of interest for implementors of new c-client drivers.
   1.162 +
   1.163 +Main Program Callbacks
   1.164 +	Documentation of functions which the main program must provide
   1.165 +	as callbacks from c-client.
   1.166 +
   1.167 +Driver Interface
   1.168 +	Documentation of the driver dispatch vector and the functions
   1.169 +	which a driver must supply.
   1.170 +
   1.171 +	This is primarily of interest for implementors of new c-client
   1.172 +	drivers.
   1.173 +
   1.174 +Driver Support Functions
   1.175 +	Documentation of support functions which are called by drivers.
   1.176 +
   1.177 +	This is primarily of interest for implementors of new c-client
   1.178 +	drivers.
   1.179 +				  History
   1.180 +
   1.181 +     The c-client API was originally written by Mark Crispin at Stanford
   1.182 +University as a set of routines to support IMAP and SMTP from a main
   1.183 +program which would handle the user interface.  In its original form, it
   1.184 +was written as the low-level routines that were to be used as part of a
   1.185 +Macintosh client.
   1.186 +
   1.187 +     The first IMAP client, MM-D (for "MM on Xerox D machines" -- MM was a
   1.188 +popular DEC-20 mail program) was written in Interlisp for Xerox Lisp
   1.189 +machines.  At that time, there was no name for the embryonic Mac client,
   1.190 +but since it was the first one to be written in C instead of Lisp, it was
   1.191 +given a development name of "C client".  This name became "c-client"
   1.192 +because that is the name of the subdirectory on UNIX where the source files
   1.193 +were stored.
   1.194 +
   1.195 +     To exercise the routines, a minimal main program which uses c-client,
   1.196 +mtest, was written.  mtest has subsequently been extended so that it runs
   1.197 +on every platform that c-client is ported.
   1.198 +
   1.199 +     The real Mac client, was eventually written by Frank Gilmurrary and
   1.200 +Bill Yeager at Stanford using the autumn 1988 version of c-client and named
   1.201 +"MacMS".  In the winter of 1988-89, Mark Crispin, who had changed jobs to
   1.202 +the University of Washington, developed MS as an MM-like text-based program
   1.203 +for UNIX and MailManager as a GUI-based program for NeXT machines.
   1.204 +
   1.205 +     The realization sunk in that this API needed its own name.  As early
   1.206 +as spring 1989, there were at least four programs (mtest, MS, MailManager,
   1.207 +and MacMS) that used it.  The name c-client thus became permanent.
   1.208 +
   1.209 +     In its history, c-client has undergone two major redesigns, both by
   1.210 +Mark Crispin who is now on the staff at the University of Washington.
   1.211 +
   1.212 +     The first major redesign added the following:
   1.213 +	1) ANSI C calling conventions throughout to assist in function
   1.214 +	   argument type checking.
   1.215 +	2) Vectoring mail access calls through "driver" methods; thus
   1.216 +	   providing transparent access to multiple types of mail
   1.217 +	   stores with the same call.
   1.218 +	3) MIME support.
   1.219 +
   1.220 +     The second major redesign was part of the IMAP4 project.  Many
   1.221 +c-client functions were extended with additional arguments and options.
   1.222 +The driver interface was also made simpler, with more work done by
   1.223 +driver-independent code.
   1.224 +
   1.225 +			       Overview
   1.226 +
   1.227 +     The most important file for the author of an application using the
   1.228 +c-client is mail.h.  mail.h defines several important structures of
   1.229 +data which are passed between the main program and the c-client.
   1.230 +Although some functions (e.g. mail_fetchtext_body()) return the data
   1.231 +fetched, for certain other data items (e.g. flags) you need to get the
   1.232 +data as a structure reference.  mail.h also defines a large number of
   1.233 +useful constants and structures.
   1.234 +
   1.235 +     When a function in mail.h exists to reference data, it MUST be
   1.236 +used instead of referencing the structures directly.  This is because
   1.237 +in some cases the data is not actually fetched until a reference (via
   1.238 +the function call) is made.  For example, although the MESSAGECACHE
   1.239 +element for a message can be obtained by indexing the proper cache
   1.240 +element in the stream, there is no guarantee that the item in fact
   1.241 +exists unless mail_fetchstructure_full() is called for that message.
   1.242 +Less costly functions. also exist to create and load a MESSAGECACHE
   1.243 +element.
   1.244 +
   1.245 +     The main program will probably also need to include smtp.h,
   1.246 +misc.h, and osdep.h, but this usage should be solely to receive
   1.247 +function prototypes.  Any other definitions in those files should be
   1.248 +considered private to that module.
   1.249 +
   1.250 +     Two important predefined symbols are NIL and T.  NIL is any sort
   1.251 +of "false"; T is any sort of "true".  NIL is also used to null-specify
   1.252 +certain optional arguments.
   1.253 +
   1.254 +			* * * IMPORTANT * * *
   1.255 +
   1.256 +     Any multi-threaded application should test stream->lock prior to
   1.257 +calling any c-client stream functions.  Any attempt to call a
   1.258 +mail_xxx() function while one is already in progress on the same
   1.259 +stream will cause the application to fail in unpredictable ways.
   1.260 +
   1.261 +     Note that this check is insufficient in a preemptive-scheduling
   1.262 +multi-tasking application due to the possibility of a timing race.
   1.263 +Such applications must be written so that only one process accesses
   1.264 +the stream, or to have a higher level lock.
   1.265 +
   1.266 +     Since MAIL operations will not finish until they are completed, a
   1.267 +single-tasking application does not have to worry about this problem,
   1.268 +except in the callback invoked from MAIL (e.g. mm_exists(), etc.) in which
   1.269 +case the stream is *always* locked.
   1.270 +
   1.271 +			  c-client Structures
   1.272 +
   1.273 +     c-client has a large number of structures which are used for
   1.274 +multiple functions.  The most important of these are described here.
   1.275 +
   1.276 +     The MAILSTREAM structure is used to reference open mailboxes.
   1.277 +Applications may reference the following:
   1.278 +
   1.279 +char *mailbox;			mailbox name
   1.280 +unsigned short use;		stream use count, this is incremented
   1.281 +unsigned short sequence;	stream sequence, this is incremented
   1.282 +				 each time a stream is reused (i.e.
   1.283 +				 mail_open() is called to open a
   1.284 +				 different mailbox on this stream)
   1.285 +unsigned int rdonly : 1;	stream is open read-only
   1.286 +unsigned int anonymous : 1;	stream is open with anonymous access
   1.287 +unsigned int halfopen : 1;	stream is half-open; it can be
   1.288 +				 reopened or used for functions that
   1.289 +				 don't need a open mailbox such as
   1.290 +				 mail_create() but no message data
   1.291 +				 can be fetched
   1.292 +unsigned int perm_seen : 1;	Seen flag can be set permanently
   1.293 +unsigned int perm_deleted : 1;	Deleted flag can be set permanently
   1.294 +unsigned int perm_flagged : 1;	Flagged flag can be set permanently
   1.295 +unsigned int perm_answered :1;	Answered flag can be set permanently
   1.296 +unsigned int perm_draft : 1;	Draft flag can be set permanently
   1.297 +unsigned int kwd_create : 1;	new user flags can be created by
   1.298 +				 referencing then in mail_setflag() or
   1.299 +				 mail_clearflag().  Note: this can
   1.300 +				 change during a session (e.g. if
   1.301 +				 there is a limit on the number of
   1.302 +				 keywords), so check after creating a
   1.303 +				 new flag to see if any more can be
   1.304 +				 created before letting the user try
   1.305 +				 to do so
   1.306 +unsigned long perm_user_flags;	corresponding user flags can be set
   1.307 +				 permanently.  This is a bit mask
   1.308 +				 which matches the entries in
   1.309 +				 stream->user_flags[]
   1.310 +unsigned long gensym;		generated unique value.  Always
   1.311 +				 referenced with stream->gensys++
   1.312 +unsigned long nmsgs;		number of messages in current mailbox
   1.313 +unsigned long recent;		number of recent messages in current
   1.314 +				 mailbox
   1.315 +unsigned long uid_validity;	UID validity value; this is used to
   1.316 +				 verify that recorded UIDs match the
   1.317 +				 UIDs that the stream has.  If the
   1.318 +				 mailbox does not have matching UIDs
   1.319 +				 (e.g. the UIDs were lost or not
   1.320 +				 recorded) then the UID validity value
   1.321 +				 will be different
   1.322 +unsigned long uid_last;		highest currently assigned UID in the
   1.323 +				 current mailbox; a new UID will be
   1.324 +				 assigned with ++stream->uid_last
   1.325 +char *user_flags[NUSERFLAGS];	pointers to user flag names in bit
   1.326 +				 order from stream->perm_user_flags or
   1.327 +				 elt->user_flags
   1.328 +
   1.329 +     The following MAILSTREAM values are only used internally:
   1.330 +
   1.331 +DRIVER *dtb;			dispatch table for this driver
   1.332 +void *local;			pointer to driver local data
   1.333 +unsigned int lock : 1;		stream lock flag (an operation is in
   1.334 +				 progress; used as a bug trap to
   1.335 +				 detect recursion back to c-client
   1.336 +				 from callback routines).
   1.337 +unsigned int debug : 1;		debugging information should be logged
   1.338 +				 via mm_dlog().
   1.339 +unsigned int silent : 1;	don't do main program callbacks on
   1.340 +				 this stream (used when a stream is
   1.341 +				 opened internally)
   1.342 +unsigned int scache : 1;	short caching; don't cache information
   1.343 +				 in memory
   1.344 +
   1.345 +     The following MAILSTREAM values are only used by the cache
   1.346 +manager routine (see the documentation about mailcache_t above):
   1.347 +
   1.348 +unsigned long cachesize;	size of c-client message cache
   1.349 +union {
   1.350 +  void **c;			to get at the cache in general
   1.351 +  MESSAGECACHE **s;		message cache array
   1.352 +  LONGCACHE **l;		long cache array
   1.353 +} cache;
   1.354 +
   1.355 +     The following MAILSTREAM values are for the convenience of
   1.356 +drivers that use short caching and want to be able to garbage collect
   1.357 +any values that they returned:
   1.358 +
   1.359 +unsigned long msgno;		message number of `current' message
   1.360 +ENVELOPE *env;			pointer to `current' message envelope
   1.361 +BODY *body;			pointer to `current' message body
   1.362 +char *text;			pointer to `current' text
   1.363 +
   1.364 +
   1.365 +     The MESSAGECACHE structure (commonly called an "elt" as a
   1.366 +nickname for "cache ELemenT") contains information about messages.
   1.367 +Applications may use the following:
   1.368 +
   1.369 +unsigned long msgno;		message number.  If the elt is locked
   1.370 +				 (by elt->lockcount++), then the elt
   1.371 +				 pointer can be stored (e.g. with the
   1.372 +				 data for a window which draws this
   1.373 +				 message) and elt->msgno will change
   1.374 +				 automatically whenever expunges are
   1.375 +				 done so the window will always view
   1.376 +				 the correct message.  If elt->msgno
   1.377 +				 becomes 0, then the message has been
   1.378 +				 expunged, but the elt won't be freed
   1.379 +				 until the elt lock count is
   1.380 +				 decremented (by mail_free_elt()).
   1.381 +unsigned long uid;		message unique ID
   1.382 +unsigned int hours: 5;		internal date hours (0-23)
   1.383 +unsigned int minutes: 6;	internal date minutes (0-59)
   1.384 +unsigned int seconds: 6;	internal date seconds (0-59)
   1.385 +unsigned int zoccident : 1;	non-zero if internal date time zone is
   1.386 +				 west of UTC
   1.387 +unsigned int zhours : 4;	internal date time zone hours from UTC
   1.388 +				 (0-12)
   1.389 +unsigned int zminutes: 6;	internal date time zone minutes (0-59)
   1.390 +unsigned int seen : 1;		message Seen flag
   1.391 +unsigned int deleted : 1;	message Deleted flag
   1.392 +unsigned int flagged : 1; 	message Flagged flag
   1.393 +unsigned int answered : 1;	message Answered glag
   1.394 +unsigned int draft : 1;		message Draft flag
   1.395 +unsigned int valid : 1;		flags are valid in this elt; an elt
   1.396 +				 that was newly created but never
   1.397 +				 loaded with flags won't have this set.
   1.398 +unsigned int recent : 1;	message recent flag
   1.399 +unsigned int searched : 1;	message matches search criteria in
   1.400 +				 most recent mail_search_full() call
   1.401 +unsigned int spare : 1;		reserved for application use
   1.402 +unsigned int spare2 : 1;	reserved for application use
   1.403 +unsigned int spare3 : 1;	reserved for application use
   1.404 +unsigned int lockcount : 8;	non-zero if multiple references to
   1.405 +				 this elt.  Refer to the msgno member
   1.406 +				 for more information.
   1.407 +unsigned int day : 5;		internal date day of month (1-31)
   1.408 +unsigned int month : 4;		internal date month of year (1-12)
   1.409 +unsigned int year : 7;		internal date year since BASEYEAR
   1.410 +				 (currently 1970; was 1969 in older
   1.411 +				 versions so use BASEYEAR instead of
   1.412 +				 having the base year wired in)
   1.413 +unsigned long user_flags;	message user flags; this is a bit mask
   1.414 +				 which matches the entries in
   1.415 +				 stream->user_flags[]
   1.416 +unsigned long rfc822_size;	size of message in octets
   1.417 +
   1.418 +     The following MESSAGECACHE values are only used internally by
   1.419 +drivers:
   1.420 +
   1.421 +unsigned int sequence : 1;	message is in sequence from either
   1.422 +				 mail_sequence() or mail_uid_sequence()
   1.423 +unsigned long data1;		first data item
   1.424 +unsigned long data2;		second data item
   1.425 +unsigned long data3;		third data item
   1.426 +unsigned long data4;		fourth data item
   1.427 +
   1.428 +
   1.429 +     The ADDRESS structure is a parsed form of a linked list of RFC 822
   1.430 +addresses.  It contains the following information:
   1.431 +
   1.432 +char *personal;			personal name phrase
   1.433 +char *adl;			at-domain-list (also called "source
   1.434 +				 route")
   1.435 +char *mailbox;			mailbox name
   1.436 +char *host;			domain name of mailbox's host
   1.437 +char *error;			error in address from smtp_mail(); if
   1.438 +				 an error is returned from smtp_mail()
   1.439 +				 for one of the recipient addresses
   1.440 +				 the SMTP server's error text for that
   1.441 +				 recipient can be found here.  If it
   1.442 +				 is null then there was no error (or
   1.443 +				 an error was found with a prior
   1.444 +				 recipient
   1.445 +ADDRESS *next;			pointer to next address in list
   1.446 +
   1.447 +
   1.448 +     The ENVELOPE structure is a parsed form of the RFC 822 header.
   1.449 +Its member names correspond to the RFC 822 field names.  It contains
   1.450 +the following information:
   1.451 +
   1.452 +char *remail;			remail header if any
   1.453 +ADDRESS *return_path;		error return address
   1.454 +char *date;			message composition date string
   1.455 +ADDRESS *from;			from address list
   1.456 +ADDRESS *sender;		sender address list
   1.457 +ADDRESS *reply_to;		reply address list
   1.458 +char *subject;			message subject string
   1.459 +ADDRESS *to;			primary recipient list
   1.460 +ADDRESS *cc;			secondary recipient list
   1.461 +ADDRESS *bcc;			blind secondary recipient list
   1.462 +char *in_reply_to;		replied message ID
   1.463 +char *message_id;		message ID
   1.464 +char *newsgroups;		USENET newsgroups
   1.465 +char *followup_to;		USENET reply newsgroups
   1.466 +char *references;		USENET references
   1.467 +
   1.468 +
   1.469 +     The BODY structure is a parsed form of a linked list of the MIME
   1.470 +structure of a message.  It contains the following information.
   1.471 +
   1.472 +unsigned short type;		body primary type code.  This is an
   1.473 +				 index into the body_types vector of
   1.474 +				 body type names.  The following body
   1.475 +				 types are pre-defined:
   1.476 +	TYPETEXT		unformatted text
   1.477 +	TYPEMULTIPART		multiple part
   1.478 +	TYPEMESSAGE		encapsulated message
   1.479 +	TYPEAPPLICATION		application data
   1.480 +	TYPEAUDIO		audio
   1.481 +	TYPEIMAGE		static image (GIF, JPEG, etc.)
   1.482 +	TYPEVIDEO		video
   1.483 +	TYPEOTHER		unknown
   1.484 +				Additional types up to TYPEMAX are
   1.485 +				 dynamically defined if they are
   1.486 +				 encountered by c-client.
   1.487 +unsigned short encoding;	body transfer encoding.  This is an
   1.488 +				 index into the body_encodings vector
   1.489 +				 of body encoding names.  The
   1.490 +				 following body encodings are
   1.491 +				 pre-defined:
   1.492 +	ENC7BIT			7 bit SMTP semantic data
   1.493 +	ENC8BIT			8 bit SMTP semantic data
   1.494 +	ENCBINARY		8 bit binary data
   1.495 +	ENCBASE64		base-64 encoded data
   1.496 +	ENCQUOTEDPRINTABLE	human-readable 8-as-7 bit data
   1.497 +	ENCOTHER		unknown
   1.498 +				Additional encodings up to ENCMAX are
   1.499 +				 dynamically defined if they are
   1.500 +				 encountered by c-client.
   1.501 +char *subtype;			body subtype string
   1.502 +PARAMETER *parameter;		parameter list
   1.503 +char *id;			body content identifier
   1.504 +char *description;		body content description
   1.505 +unsigned char *contents.text;	when composing a message that is NOT
   1.506 +				 of TYPEMULTIPART, non-binary text of
   1.507 +				 the content is stored here.  Note that
   1.508 +				 this happens even when the text is
   1.509 +				 of TYPEMESSAGE.  Text of encoding
   1.510 +				 ENC8BIT may be converted to
   1.511 +				 ENCQUOTEDPRINTABLE when it is sent.
   1.512 +				 This should not be referenced for any
   1.513 +				 other reason; in particular, this is
   1.514 +				 NOT the way for an application to
   1.515 +				 access content data (use
   1.516 +				 mail_fetchbody_full() instead).
   1.517 +BINARY *contents.binary;	when composing a message that is NOT
   1.518 +				 of TYPEMULTIPART, binary content (of
   1.519 +				 encoding ENCBINARY) is stored here.
   1.520 +				 It will be converted to ENCBASE64 when
   1.521 +				 it is sent.
   1.522 +				 This should not be referenced for any
   1.523 +				 other reason; in particular, this is
   1.524 +				 NOT the way for an application to
   1.525 +				 access content data (use
   1.526 +				 mail_fetchbody_full() instead).
   1.527 +PART *contents.part;		for body parts of TYPEMULTIPART, this
   1.528 +				 contains the list of body parts in
   1.529 +				 this multipart
   1.530 +MESSAGE contents.msg;		for body parts of TYPEMESSAGE with
   1.531 +				 subtype "RFC822", this contains the
   1.532 +				 encapsulated message
   1.533 +unsigned long size.lines;	size in lines
   1.534 +unsigned long size.bytes;	size in octets.  This MUST be set when
   1.535 +				composing a message if the encoding is
   1.536 +				ENC8BIT or ENCBINARY.
   1.537 +char *md5;			body content MD5 checksum
   1.538 +
   1.539 +     The following BODY information is used only by c-client
   1.540 +internally.  The use of this data is driver-specific and it can not be
   1.541 +relied-upon by applications.
   1.542 +
   1.543 +unsigned char *contents.text;	drivers can store a pointer to the
   1.544 +				 body contents as text here.		
   1.545 +unsigned long size.ibytes;	internal size of the body content (prior
   1.546 +				 to newline conversion, etc.) in octets
   1.547 +
   1.548 +
   1.549 +     The MESSAGE structure is a parsed form of a MESSAGE/RFC822 MIME
   1.550 +body part.  It contains the following information:
   1.551 +
   1.552 +ENVELOPE *env;			encapsulated message RFC 822 header
   1.553 +BODY *body;			encapsulated message MIME structure
   1.554 +
   1.555 +     The following MESSAGE information is used only by c-client
   1.556 +internally.  The use of this data is driver-specific and it can not be
   1.557 +relied-upon by applications.
   1.558 +
   1.559 +char *hdr;			encapsulated message header
   1.560 +unsigned long hdrsize;		message header size
   1.561 +char *text;			message in RFC 822 form
   1.562 +unsigned long offset;		offset of text from header
   1.563 +
   1.564 +
   1.565 +     The PARAMETER structure is a parsed form of a linked list of
   1.566 +attribute/value pairs.  It contains the following information:
   1.567 +
   1.568 +char *attribute;		attribute name
   1.569 +char *value;			value
   1.570 +PARAMETER *next;		next parameter in list
   1.571 +
   1.572 +
   1.573 +     The PART structure is a parsed form of a linked list of MIME body
   1.574 +parts.  It contains the following information:
   1.575 +
   1.576 +BODY body;			body information for this part
   1.577 +PART *next;			next body part
   1.578 +
   1.579 +     The following PART information is used only by c-client
   1.580 +internally.  The use of this data is driver-specific and it can not be
   1.581 +relied-upon by applications.
   1.582 +
   1.583 +unsigned long offset;		offset from body origin
   1.584 +
   1.585 +
   1.586 +    The NETMBX structure is a parsed form of a network mailbox name:
   1.587 +
   1.588 +char host[NETMAXHOST];		remote host name
   1.589 +char user[NETMAXUSER];		remote user name if specified
   1.590 +char mailbox[NETMAXMBX];	remote mailbox name
   1.591 +char service[NETMAXSRV];	remote service name (IMAP4, NNTP, etc.)
   1.592 +unsigned long port;		TCP/IP port number if specified
   1.593 +unsigned int anoflag : 1;	anonymous access requested
   1.594 +unsigned int dbgflag : 1;	protocol debugging telemetry, via
   1.595 +				 mm_dlog(), requested
   1.596 +
   1.597 +
   1.598 +     The STRINGLIST structure is a list of strings (which may have
   1.599 +embedded NULs) and their lengths:
   1.600 +
   1.601 +char *text;			string text
   1.602 +unsigned long size;		string length
   1.603 +STRINGLIST *next;		next string in list
   1.604 +
   1.605 +			  String Structures
   1.606 +
   1.607 +     A string structure is analogous to a char*, and is used in some
   1.608 +functions as an input argument.  It represents a string of data in a
   1.609 +way that does not necessarily require the entire string to be in
   1.610 +memory at once.  This is essential for small machines with
   1.611 +highly-restricted memory limits (e.g. DOS).
   1.612 +
   1.613 +		       String Structure Access
   1.614 +
   1.615 +     To use a string structure, the caller needs to know a string
   1.616 +driver and needs to know the driver-dependent data used by that string
   1.617 +structure.  A simple string driver is mail_string, a string driver
   1.618 +that takes an in-memory char* string as the driver-dependent data.
   1.619 +The DOS port uses string drivers that take a struct holding a file
   1.620 +descriptor and a file offset.  Often the user of a string driver is
   1.621 +the same module that defined it, so usually the programmer knows about
   1.622 +its conventions.
   1.623 +
   1.624 +     The following calls are used to access a string structure:
   1.625 +
   1.626 +void INIT (STRING *s,STRINGDRIVER *d,void *data,unsigned long size);
   1.627 +	s	pointer to the string structure to be initialized
   1.628 +	d	pointer to the string driver
   1.629 +	data	pointer to driver-dependent data, from which the
   1.630 +		 driver can determine string data
   1.631 +	size	size of the string
   1.632 + This call initializes the string stucture.
   1.633 +
   1.634 +
   1.635 +unsigned long SIZE (STRING *s);
   1.636 +	s	pointer to the string structure
   1.637 + This call returns the number of characters remaining in the string
   1.638 +after the current string character pointer.
   1.639 +
   1.640 +
   1.641 +char CHR (STRING *s);
   1.642 +	s	pointer to the string structure
   1.643 + This call returns the character at the current string character
   1.644 +pointer.
   1.645 +
   1.646 +
   1.647 +char SNX (STRING *s);
   1.648 +	s	pointer to the string structure
   1.649 + This call returns the character at the current string character
   1.650 +pointer, and increments the string character pointer.
   1.651 +
   1.652 +
   1.653 +unsigned long GETPOS (STRING *s);
   1.654 +	s	pointer to the string structure
   1.655 + This returns the value of the current string character pointer.
   1.656 +
   1.657 +
   1.658 +void SETPOS (STRING *s,unsigned long i);
   1.659 +	s	pointer to the string structure
   1.660 +	i	new string pointer value
   1.661 + This method sets the string character pointer to the given value.
   1.662 +
   1.663 +
   1.664 +		      String Structure Internals
   1.665 +
   1.666 +     A string structure holds the following data:
   1.667 +
   1.668 +void *data;		used by the string driver as it likes
   1.669 +unsigned long data1;	used by the string driver as it likes
   1.670 +unsigned long size;	static, holds the total length of the string
   1.671 +			 from the INIT call
   1.672 +char *chunk;		current chunk of in-memory data; this is used
   1.673 +			 for buffering to avoid unnecessary calls to
   1.674 +			 the string driver's next method.
   1.675 +unsigned long chunksize; size of an in-memory data chunk
   1.676 +unsigned long offset;	position of first character of the chunk in
   1.677 +			 the overall string
   1.678 +char *curpos;		current position; this is what CHR() will
   1.679 +			 access
   1.680 +unsigned long cursize;	number of characters remaining in the current
   1.681 +			 string
   1.682 +STRINGDRIVER *dtb;	the string driver for this string structure
   1.683 +
   1.684 +
   1.685 +     A string structure is manipulated by a string driver, which has
   1.686 +the following access methods:
   1.687 +
   1.688 +void (*init) (STRING *s,void *data,unsigned long size);
   1.689 +	s	pointer to the string structure to be initialized
   1.690 +	data	pointer to driver-dependent data, from which the
   1.691 +		 driver can determine string data
   1.692 +	size	size of the string
   1.693 + This method initializes the string stucture.  It can use the data,
   1.694 +data1, and chunksize values as it likes.  The remaining values must be
   1.695 +set up as follows:
   1.696 +	size		static, copied from the size argument
   1.697 +	chunk		pointer to a buffer loaded with initial data
   1.698 +	chunksize	size of the buffer
   1.699 +	offset		0
   1.700 +	curpos		copied from chunk
   1.701 +	cursize		copied from chunksize
   1.702 +	dtb		STRINGDRIVER identity pointer
   1.703 +
   1.704 +
   1.705 +char (*next) (STRING *s);
   1.706 +	s	pointer to the string structure
   1.707 + This method returns the character at the current string character
   1.708 +pointer, and increments the string character pointer.  This method
   1.709 +is likely to call the setpos method if the desired character is not in
   1.710 +the current chunk.
   1.711 +
   1.712 +
   1.713 +void (*setpos) (STRING *s,unsigned long i);
   1.714 +	s	pointer to the string structure
   1.715 +	i	new string pointer value
   1.716 + This method sets the string character pointer to the given value.  If
   1.717 +the pointer is not in the current chunk, then a new chunk is loaded
   1.718 +and the associated values (chunk, offset, curpos, cursize) are
   1.719 +adjusted accordingly.
   1.720 +
   1.721 +		      c-client Support Functions
   1.722 +
   1.723 +
   1.724 +void mail_string_init (STRING *s,void *data,unsigned long size);
   1.725 +char mail_string_next (STRING *s);
   1.726 +void mail_string_setpos (STRING *s,unsigned long i);
   1.727 +
   1.728 +     These three functions are the init, next, and setpos string
   1.729 +structure access methods for the build-in mail_string string driver.
   1.730 +mail_string is a basic string driver for a char* string.  See the
   1.731 +documentation below on "String Structures" for more information.
   1.732 +
   1.733 +
   1.734 +void mail_link (DRIVER *driver);
   1.735 +	driver	pointer to the driver to be added
   1.736 +
   1.737 +     This function adds the specified driver to the list of mailbox
   1.738 +drivers.  Initially there are no drivers lunk, so all programs which
   1.739 +intend to use c-client need to have at least one call to this function.
   1.740 +
   1.741 +     A function which uses IMAP4 would have a statement such as:
   1.742 +	mail_link (&imapdriver);	/* link in IMAP driver */
   1.743 +early in the program's initialization.  Normally, this is done by the
   1.744 +statement
   1.745 +	#include "linkage.c"
   1.746 +which will include the "system standard driver linkage" defined when
   1.747 +c-client was built.  By using linkage.c instead of explicit mail_link()
   1.748 +calls, you are guaranteed that you will have a consistant linkage among
   1.749 +all software built on this system.
   1.750 +
   1.751 +
   1.752 +void auth_link (AUTHENTICATOR *auth);
   1.753 +	auth	pointer to the authenticator to be added
   1.754 +
   1.755 +     This function adds the specified authenticator to the list of
   1.756 +authenticators.  Initially there are no authenticators lunk.  Normally,
   1.757 +this is done by linkage.c so you don't need to call this routine
   1.758 +explicitly.
   1.759 +
   1.760 +
   1.761 +void *mail_parameters (MAILSTREAM *stream,long function,void *value);
   1.762 +	stream	stream to poll or NIL
   1.763 +	function function code
   1.764 +	value	new value for function codes that change a parameter
   1.765 +
   1.766 +     This function fetches or changes the settings of various c-client
   1.767 +operational parameters depending upon the function.  If the stream is
   1.768 +specified, only the action for the underlying driver for that stream is
   1.769 +taken; however, the scope of the operational parameters is global so
   1.770 +there is generally no reason for the stream argument ever to be
   1.771 +non-NIL.
   1.772 +
   1.773 +     The function codes ENABLE_DRIVER and DISABLE_DRIVER take a driver
   1.774 +pointer as a value.  These functions enable and disable mailbox
   1.775 +processing by that driver.  By default, all drivers are enabled.
   1.776 +
   1.777 +     The remaining function codes are in a pair named GET_xxx to
   1.778 +fetch an operational parameter and SET_xxx to set the parameter:
   1.779 +
   1.780 + GET_DRIVERS / SET_DRIVERS
   1.781 +	 The list of currently lunk drivers.
   1.782 +
   1.783 + GET_GETS / SET_GETS
   1.784 +	 If non-NIL, points to a function for reading message text.
   1.785 +	Defaults to NIL.
   1.786 +	 This function is called with three arguments; a function
   1.787 +	pointer to a "reading function", a stream for the reading
   1.788 +	function, and a size in octets.  The reading function is
   1.789 +	in turn called with the stream, a size in octets, and a
   1.790 +	pointer to a readin buffer.
   1.791 +	 This function returns with a char* string, which will be
   1.792 +	returned by the mail_fetchheader(), mail_fetchtext(), or
   1.793 +	mail_fetchbody() function which triggered the message text
   1.794 +	reading.
   1.795 +	 The purpose is to permit reading of large strings, without
   1.796 +	requiring an in-memory buffer for the entire string.  The idea
   1.797 +	is that this function can store the data in some form other
   1.798 +	than a char* (e.g. a temporary file) and the main program will
   1.799 +	recognize that it should get the text from there instead of
   1.800 +	from the results from mail_fetch....().
   1.801 +	 This is only supported on DOS and Win16; on other platforms it
   1.802 +	is inconsistent whether or not it works.
   1.803 +
   1.804 + GET_CACHE / SET_CACHE
   1.805 +	 Points to the c-client cache manager function.  Defaults to
   1.806 +	mm_cache().
   1.807 +
   1.808 + GET_SMTPVERBOSE / SET_SMTPVERBOSE
   1.809 +	 If non-NIL, points to a function that accepts a char* string.
   1.810 +	This function is called any time the SMTP routines receive a
   1.811 +	response code less than 100.  The argument is the text of the
   1.812 +	response code
   1.813 +
   1.814 + GET_RFC822OUTPUT / SET_RFC822OUTPUT
   1.815 +	 If non-NIL, points to an alternate rfc822_output() function.
   1.816 +	rfc822_output() will call this function and return instead of
   1.817 +	doing its normal action.  See the description of
   1.818 +	rfc822_output() for more information.	
   1.819 +
   1.820 + GET_USERNAME / SET_USERNAME
   1.821 +	 The logged-in user name.
   1.822 +
   1.823 + GET_HOMEDIR / SET_HOMEDIR
   1.824 +	 The home directory path name.
   1.825 +
   1.826 + GET_LOCALHOST / SET_LOCALHOST
   1.827 +	 The local host name.
   1.828 +
   1.829 + GET_SYSINBOX / SET_SYSINBOX
   1.830 +	 The "system INBOX" (where mail is delivered) path name.
   1.831 +
   1.832 + GET_OPENTIMEOUT / SET_OPENTIMEOUT
   1.833 +	 TCP/IP open timeout in seconds.  Defaults to 0 (system
   1.834 +	default timeout, usually 75 seconds on Unix).
   1.835 +	
   1.836 + GET_READTIMEOUT / SET_READTIMEOUT
   1.837 +	 TCP/IP read timeout in seconds.  Defaults to 0 (no timeout).
   1.838 +
   1.839 + GET_WRITETIMEOUT / SET_WRITETIMEOUT
   1.840 +	 TCP/IP write timeout in seconds.  Defaults to 0 (no timeout).
   1.841 +
   1.842 + GET_CLOSETIMEOUT / SET_CLOSETIMEOUT
   1.843 +	 TCP/IP close timeout in seconds.  Defaults to 0 (no timeout).
   1.844 +
   1.845 + GET_TIMEOUT / SET_TIMEOUT
   1.846 +	 If non-NIL, points to the function called when a TCP/IP
   1.847 +	timeout occurs.  This function is called with the number of
   1.848 +	seconds since the start of the TCP operation.  If it returns
   1.849 +	non-zero, the TCP/IP operation is continued; if it returns
   1.850 +	non-zero, the TCP/IP connection is aborted.
   1.851 +
   1.852 + GET_RSHTIMEOUT / SET_RSHTIMEOUT
   1.853 +	 rsh connection timeout in seconds.  Defaults to 15 seconds.
   1.854 +
   1.855 + GET_MAXLOGINTRIALS / SET_MAXLOGINTRIALS
   1.856 +	 The maximum number of login attempts permitted in an IMAP or
   1.857 +	POP connection.  Defaults to 3.
   1.858 +
   1.859 + GET_LOOKAHEAD / SET_LOOKAHEAD
   1.860 +	 The number of subsequent envelopes prefetched in IMAP when an
   1.861 +	envelope is fetched.  Defaults to 20.
   1.862 +
   1.863 + GET_IMAPPORT / SET_IMAPPORT
   1.864 +	 The IMAP port number.  Defaults to 143.
   1.865 +
   1.866 + GET_PREFETCH / SET_PREFETCH
   1.867 +	 The number of envelopes prefetched in IMAP from the results
   1.868 +	of a SEARCH.  Defaults to 20.
   1.869 +
   1.870 + GET_CLOSEONERROR / SET_CLOSEONERROR
   1.871 +	 If non-NIL, close an opening IMAP connection if the SELECT
   1.872 +	command fails instead of returning a half-open stream.
   1.873 +	Defaults to NIL.
   1.874 +
   1.875 + GET_POP3PORT / SET_POP3PORT
   1.876 +	 The POP3 port number.  Defaults to 110.
   1.877 +
   1.878 + GET_UIDLOOKAHEAD / SET_UIDLOOKAHEAD
   1.879 +	 The number of UIDs premapped when a message number is
   1.880 +	translated to a UID.  Defaults to 1000.
   1.881 +
   1.882 + GET_MBXPROTECTION / SET_MBXPROTECTION
   1.883 +	 Default file protection for newly created mailboxes.
   1.884 +	Defaults to 0600.
   1.885 +
   1.886 + GET_DIRPROTECTION / SET_DIRPROTECTION
   1.887 +	 Default file protection for newly created directories.
   1.888 +	Defaults to 0700.
   1.889 +
   1.890 + GET_LOCKPROTECTION / SET_LOCKPROTECTION
   1.891 +	 Default file protection for locks.  Defaults to 0666.
   1.892 +	WARNING: don't blithely change this.  If other processes
   1.893 +	can't get access to a lock then they will have trouble in
   1.894 +	locking properly.
   1.895 +
   1.896 + GET_FROMWIDGET / SET_FROMWIDGET
   1.897 +	 If non-NIL, APPEND in the Unix mbox format will insert a
   1.898 +	">" character in front of all lines which begin with the
   1.899 +	string "From ".  If NIL, it will only do so if the entire
   1.900 +	line looks like a message delimiter (that is, the date is
   1.901 +	also in correct format).  Defaults to T.
   1.902 +
   1.903 + GET_NEWSACTIVE / SET_NEWSACTIVE
   1.904 +	 Netnews active file path name.
   1.905 +
   1.906 + GET_NEWSSPOOL / SET_NEWSSPOOL
   1.907 +	 Netnews spool directory path name.
   1.908 +
   1.909 + GET_NEWSRC / SET_NEWSRC
   1.910 +	 Netnews newsgroup reading status file (.newsrc) path name.
   1.911 +
   1.912 + GET_EXTENSION / SET_EXTENSION
   1.913 +	 If non-NIL, points to a string holding the extension for all
   1.914 +	mailbox files.  This is only supported on DOS and Win16.
   1.915 +
   1.916 + GET_DISABLEFCNTLLOCK / SET_DISABLEFCNTLLOCK
   1.917 +	 If non-NIL, disables fcntl() locking on SVR4.  This is done
   1.918 +	if fcntl() tends to hang for no good reason.  Now that the
   1.919 +	fcntl() code checks for NFS files and no-ops the locking,
   1.920 +	this problem usually doesn't happen much any more.  Defaults
   1.921 +	to NIL.
   1.922 +
   1.923 + GET_LOCKEACCESERROR / SET_LOCKEACCESERROR
   1.924 +	 If non-NIL, give a warning if an attempt to create a .lock
   1.925 +	file gets an EACCES ("Permission denied") error.  This usually
   1.926 +	means that somebody protected the system inbox directory (e.g.
   1.927 +	/var/mail) instead of making it public-write with the sticky
   1.928 +	bit.  Defaults to non-NIL, since this is usually bad news.
   1.929 +
   1.930 + GET_LISTMAXLEVEL / SET_LISTMAXLEVEL
   1.931 +	 The maximum depth of recusion that LIST will go on a *
   1.932 +	wildcard.  Defaults to 20.
   1.933 +
   1.934 + GET_ANONYMOUSHOME / SET_ANONYMOUSHOME
   1.935 +	 The anonymous use home directory name.
   1.936 +
   1.937 +
   1.938 +typedef long (*readfn_t) (void *stream,unsigned long size,char *buffer);
   1.939 +	stream	a designator suitable
   1.940 +	size	a number of octets to read
   1.941 +	buffer	a buffer of at least size octets for readin
   1.942 +
   1.943 +     This function reads the given number of octets into the buffer,
   1.944 +using the given stream.  What sort of object the stream is depends upon
   1.945 +the function and its caller, so you must make sure that the readfn is
   1.946 +suitable for the caller's purpose.  Common uses include support of the
   1.947 +mailgets function (see below) and of reading from local files on systems
   1.948 +with limited address space.
   1.949 +
   1.950 +
   1.951 +typedef char *(*mailgets_t) (readfn_t f,void *stream,unsigned long size);
   1.952 +	f	the readfn to use
   1.953 +	stream	stream argument for the readfn
   1.954 +	size	total number of octets to read
   1.955 +
   1.956 +     This is the argument to the SET_GETS mail_parameter() call.  This
   1.957 +function must read size octets from the stream, using the readfn f.  It
   1.958 +may call f multiple times to accomplish this; this will read the data in
   1.959 +a serial fashion.  So, for example, if size is a megabyte and there is
   1.960 +only 4K of available buffer space, it can call f 256 times to satisfy
   1.961 +the request.  There is no way to back up in the reading, so any
   1.962 +processing or saving of the data must be done when it is read.
   1.963 +
   1.964 +     The function mm_gets() in mail.c is a sample mailgets function; it
   1.965 +reads the first MAXMESSAGESIZE of data into memory and discards the
   1.966 +rest.
   1.967 +
   1.968 +
   1.969 +typedef void *(*mailcache_t) (MAILSTREAM *stream,unsigned long msgno,long op);
   1.970 +	stream	stream to cache manage
   1.971 +	msgno	message to cache manage in the stream
   1.972 +	op	cache management operation
   1.973 +
   1.974 +     This function manages the c-client cache.  Normally, a program will
   1.975 +use the default c-client cache manager routine mm_cache().  However, a
   1.976 +main program may want to supply its own cache manager, e.g. it may want
   1.977 +to store the data on a disk file instead of in memory on DOS and Win16
   1.978 +where memory is tight.
   1.979 +
   1.980 +     If you write your own cache manager, you need to examine the
   1.981 +default mm_cache() manager closely, as well as paying close attention to
   1.982 +what goes into an elt (a MESSAGECACHE element).  It is highly likely
   1.983 +that if you roll elts out to disk, you will want to set stream->scache
   1.984 +and *NOT* use long elts (because long elts have ENVELOPE and BODY
   1.985 +pointers that you would have to know how to write to disk and read back).
   1.986 +
   1.987 +     The cache management functions are one of the following:
   1.988 +
   1.989 + CH_INIT	 Initialize the entire cache for the stream.  This is
   1.990 +		called only when creating a new stream or when freeing
   1.991 +		it.  The msgno argument is ignored.
   1.992 +
   1.993 + CH_SIZE	 Make sure that the cache is at least large enough to
   1.994 +		support msgno.  This is a request to grow the cache if
   1.995 +		necessary, not shrink it.
   1.996 +
   1.997 + CH_MAKELELT	 Return a long elt for msgno, creating it if necessary.
   1.998 +		This is the underlying support function for mail_lelt().
   1.999 +
  1.1000 + CH_LELT	 Return the long elt for msgno, or NIL if it does not
  1.1001 +		already exist.
  1.1002 +
  1.1003 + CH_MAKEELT	 Return an elt for msgno, creating it if necessary.
  1.1004 +		This is the underlying support function for mail_elt().
  1.1005 +
  1.1006 + CH_ELT		 Return the elt for msgno, or NIL if it does not already
  1.1007 +		exist.
  1.1008 +
  1.1009 + CH_FREE	 Free the [l]elt for msgno.
  1.1010 +
  1.1011 + CH_EXPUNGE	 Free the [l]elt for msgno, and reclaim its position.
  1.1012 +		All subsequent elts are renumbered with their elt->msgno
  1.1013 +		decremented by 1.  [Hence msgno+1 becomes msgno, etc.]
  1.1014 +		This supports message expunging from the cache.
  1.1015 +
  1.1016 +
  1.1017 +typedef long (*tcptimeout_t) (long time);
  1.1018 +	time	total time spent since TCP operation started
  1.1019 +
  1.1020 +     This function is called when a TCP operation times out.  It is set
  1.1021 +by the SET_TIMEOUT mail_parameter().  The function can return non-zero
  1.1022 +to continue the TCP operation (e.g. after outputting a "do you still
  1.1023 +want to wait" prompt) or zero if it wants the TCP operation to abort and
  1.1024 +close.  If the TCP operation aborts, it will likely cause the upper
  1.1025 +level IMAP, SMTP, etc. stream to abort and close as well.
  1.1026 +
  1.1027 +
  1.1028 +DRIVER *mail_valid (MAILSTREAM *stream,char *mailbox,char *purpose);
  1.1029 +	stream	if non-NIL, stream to use for validation
  1.1030 +	mailbox	mailbox name to validate
  1.1031 +	purpose	filled in as xxx in "Can't xxx" in error messages
  1.1032 +
  1.1033 +     This function validates the given mailbox name.  It successful, it
  1.1034 +returns the driver that can open that name if successful, otherwise it
  1.1035 +returns NIL.  If stream is non-NIL, the mailbox name must be valid for
  1.1036 +the type of mailbox associated with that stream (e.g. an NNTP name can
  1.1037 +not be used with an IMAP stream).  If purpose is non-NIL, an error
  1.1038 +message is passed via mm_log() when an error occurs.
  1.1039 +
  1.1040 +
  1.1041 +DRIVER *mail_valid_net (char *name,DRIVER *drv,char *host,char *mailbox);
  1.1042 +	name	mailbox name to validate
  1.1043 +	drv	driver name to validate against
  1.1044 +	host	buffer to return host name if non-NIL
  1.1045 +	mailbox	buffer to return remote mailbox name if non-NIL
  1.1046 +
  1.1047 +     This function is an alternative to mail_valid_net_parse().  It
  1.1048 +validates the given mailbox name as a network name and makes sure that
  1.1049 +its service name is the same as the driver in drv.  If successful, it
  1.1050 +returns drv, and copies the host and mailbox strings as needed.
  1.1051 +Otherwise it returns NIL.
  1.1052 +
  1.1053 +
  1.1054 +long mail_valid_net_parse (char *name,NETMBX *mb);
  1.1055 +	name	mailbox name to parse
  1.1056 +	mb	pointer to NETMBX structure to return
  1.1057 +
  1.1058 +     This function parses a network mailbox name.  If the name is a
  1.1059 +network mailbox name, it returns non-NIL, with the NETMBX structure
  1.1060 +loaded with the results form the parse.
  1.1061 +
  1.1062 +		       Mailbox Access Functions
  1.1063 +
  1.1064 +void mail_list (MAILSTREAM *stream,char *ref,char *pat);
  1.1065 +void mail_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents);
  1.1066 +	stream	if non-NIL, stream to use
  1.1067 +	ref	mailbox reference string
  1.1068 +	pat	mailbox pattern string
  1.1069 +	contents contents to search
  1.1070 +
  1.1071 +     This function returns a list of mailboxes via the mm_list()
  1.1072 +callback.  The reference is applied to the pattern in an implementation
  1.1073 +dependent fashion, and the resulting string is used to search for
  1.1074 +matching mailbox names.  "*" is a wildcard which matches zero or more
  1.1075 +characters; "%" is a variant which does not descend a hierarchy level.
  1.1076 +Read the IMAP specification for more information.
  1.1077 +
  1.1078 +     mail_scan() is a variant which takes a string to search for in the
  1.1079 +text of the mailbox.  The string is a free-text string, without regard
  1.1080 +for message boundaries, and thus the choice of strings must be made
  1.1081 +with care.
  1.1082 +
  1.1083 +
  1.1084 +void mail_lsub (MAILSTREAM *stream,char *ref,char *pat);
  1.1085 +	stream	if non-NIL, stream to use
  1.1086 +	ref	mailbox reference string
  1.1087 +	pat	mailbox pattern string
  1.1088 +
  1.1089 +     This function returns a list of subscribed mailboxes via the
  1.1090 +mm_lsub() callback.  The reference is applied to the pattern in an
  1.1091 +implementation dependent fashion, and the resulting string is used to
  1.1092 +search for matching mailbox names in the subscription list.  "*" is a
  1.1093 +wildcard which matches zero or more characters; "%" is a variant which
  1.1094 +does not descend a hierarchy level.  Read the IMAP specification for
  1.1095 +more information.
  1.1096 +
  1.1097 +
  1.1098 +long mail_subscribe (MAILSTREAM *stream,char *mailbox);
  1.1099 +	stream	if non-NIL, stream to use
  1.1100 +	mailbox	mailbox name
  1.1101 +
  1.1102 +     This function adds the given name to the subscription list.  It
  1.1103 +returns T if successful, NIL if unsuccessful.  If unsuccessful, an
  1.1104 +error message is returned via the mm_log() callback.
  1.1105 +
  1.1106 +
  1.1107 +long mail_unsubscribe (MAILSTREAM *stream,char *mailbox);
  1.1108 +	stream	if non-NIL, stream to use
  1.1109 +	mailbox	mailbox name
  1.1110 +
  1.1111 +     This function removes the given name from the subscription list.
  1.1112 +It returns T if successful, NIL if unsuccessful.  If unsuccessful, an
  1.1113 +error message is returned via the mm_log() callback.
  1.1114 +
  1.1115 +
  1.1116 +long mail_create (MAILSTREAM *stream,char *mailbox);
  1.1117 +	stream	if non-NIL, stream to use
  1.1118 +	mailbox	mailbox name
  1.1119 +
  1.1120 +     This function creates a mailbox with the given name.  It returns T
  1.1121 +if successful, NIL if unsuccessful.  If unsuccessful, an error message
  1.1122 +is returned via the mm_log() callback.
  1.1123 +
  1.1124 +     It is an error to create INBOX or a mailbox name which already
  1.1125 +exists.
  1.1126 +
  1.1127 +
  1.1128 +long mail_delete (MAILSTREAM *stream,char *mailbox);
  1.1129 +	stream	if non-NIL, stream to use
  1.1130 +	mailbox	mailbox name
  1.1131 +
  1.1132 +     This function deletes the named mailbox.  It returns T if
  1.1133 +successful, NIL if unsuccessful.  If unsuccessful, an error message is
  1.1134 +returned via the mm_log() callback.
  1.1135 +
  1.1136 +     It is an error to delete INBOX or a mailbox name which does not
  1.1137 +already exist.
  1.1138 +
  1.1139 +
  1.1140 +long mail_rename (MAILSTREAM *stream,char *old,char *newname);
  1.1141 +	stream	if non-NIL, stream to use
  1.1142 +	old	existing mailbox name
  1.1143 +	newname	new (not yet existing) mailbox name
  1.1144 +
  1.1145 +     This function renames the old mailbox to the new mailbox name.
  1.1146 +It returns T if successful, NIL if unsuccessful.  If unsuccessful, an
  1.1147 +error message is returned via the mm_log() callback.
  1.1148 +
  1.1149 +     It is an error to reanme a mailbox that does not exist, or rename
  1.1150 +a mailbox to a name that already exists.  It is permitted to rename
  1.1151 +INBOX; a new empty INBOX is created in its place.
  1.1152 +
  1.1153 +
  1.1154 +long mail_status (MAILSTREAM *stream,char *mbx,long flags);
  1.1155 +	stream	if non-NIL, stream to use
  1.1156 +	mbx	mailbox name
  1.1157 +	flags	option flags
  1.1158 +
  1.1159 +     This function returns the status of the given mailbox name via the
  1.1160 +mm_status() callback.  It returns T if successful, NIL if unsuccessful.
  1.1161 +If unsuccessful, an error message is returned via the mm_log()
  1.1162 +callback.
  1.1163 +
  1.1164 +     The options are a bit mask with one or more of the following,
  1.1165 +indicating the data which should be returned.
  1.1166 +	SA_MESSAGES	number of messages in the mailbox
  1.1167 +	SA_RECENT	number of recent messages in the mailbox
  1.1168 +	SA_UNSEEN	number of unseen messages in the mailbox
  1.1169 +	SA_UIDNEXT	next UID value to be assigned
  1.1170 +	SA_UIDVALIDITY	UID validity value
  1.1171 +
  1.1172 +     Note that, depending upon implementation, some of these values may
  1.1173 +be more costly to get than others.  For example, calculating the
  1.1174 +number of unseen messages may require opening the mailbox and scanning
  1.1175 +all of the message flags.  A mail_status() call should thus be used
  1.1176 +with option flags specifying only the data that is actually needed.
  1.1177 +
  1.1178 +
  1.1179 +MAILSTREAM *mail_open (MAILSTREAM *oldstream,char *name,long options);
  1.1180 +	oldstream if non-NIL, stream to recycle
  1.1181 +	name	mailbox name to open
  1.1182 +	options	option flags.
  1.1183 +
  1.1184 +     This function opens the mailbox and if successful returns a stream
  1.1185 +suitable for use by the other MAIL functions.
  1.1186 +
  1.1187 +     If oldstream is non-NIL, an attempt is made to reuse oldstream as
  1.1188 +the stream for this mailbox; this is useful when you want to open
  1.1189 +another mailbox to the same IMAP or NNTP server without having to open
  1.1190 +a new connection.  Doing this will close the previously open mailbox.
  1.1191 +
  1.1192 +     The options are a bit mask with one or more of the following:
  1.1193 +	OP_DEBUG	Log IMAP protocol telemetry through mm_debug()
  1.1194 +	OP_READONLY	Open mailbox read-only.
  1.1195 +	OP_ANONYMOUS	Don't use or update a .newsrc file for news.
  1.1196 +	OP_SHORTCACHE	Don't cache envelopes or body structures
  1.1197 +	OP_SILENT	Don't pass mailbox events (internal use only)
  1.1198 +	OP_PROTOTYPE	Return the "prototype stream" for the driver
  1.1199 +			 associated with this mailbox instead of
  1.1200 +			 opening the stream
  1.1201 +	OP_HALFOPEN	For IMAP and NNTP names, open a connection
  1.1202 +			 to the server but don't open a mailbox.
  1.1203 +	OP_EXPUNGE	Silently expunge the oldstream before recycling
  1.1204 +
  1.1205 + NIL is returned if this function fails for any reason.
  1.1206 +
  1.1207 +
  1.1208 +MAILSTREAM *mail_close (MAILSTREAM *stream);
  1.1209 +MAILSTREAM *mail_close_full (MAILSTREAM *stream,long options);
  1.1210 +	stream	stream to close
  1.1211 +	options	option flags
  1.1212 +     This function closes the MAIL stream and frees all resources
  1.1213 +associated with it that it may have created (subject to any handles
  1.1214 +existing).
  1.1215 +
  1.1216 +     The options for mail_close_full() are a bit mask with one or more
  1.1217 +of the following:
  1.1218 +	CL_EXPUNGE	Silently expunge before closing
  1.1219 +
  1.1220 +     This function always returns NIL, so it can be used as:
  1.1221 +	stream = mail_close (stream);
  1.1222 +
  1.1223 +			   Handle Functions
  1.1224 +
  1.1225 +     Handles are used when an entity that wishes to access the stream
  1.1226 +may survive the stream without knowing that it outlived it.  For
  1.1227 +example, an object reading a message may have a handle to a stream,
  1.1228 +but the message selection object that spawned it (and which owns the
  1.1229 +stream) may have gone away.  A stream can be closed or recycled while
  1.1230 +handles are pointing at it, but it is not completely freed until all
  1.1231 +handles are gone.  A stream may have an arbitrary number of handles.
  1.1232 +
  1.1233 +
  1.1234 +MAILHANDLE *mail_makehandle (MAILSTREAM *stream);
  1.1235 +	stream	stream to make handle to
  1.1236 +
  1.1237 +     This function creates and returns a handle to the stream.
  1.1238 +
  1.1239 +
  1.1240 +void mail_free_handle (MAILHANDLE **handle);
  1.1241 +	handle	pointer to handle to release
  1.1242 +
  1.1243 +     This function frees the handle and notifies the stream that it has
  1.1244 +one fewer handle.  If this is the last handle on the stream and the
  1.1245 +stream has been closed, then the stream is freed.
  1.1246 +
  1.1247 +
  1.1248 +MAILSTREAM *mail_stream (MAILHANDLE *handle);
  1.1249 +	handle	handle to look up
  1.1250 +
  1.1251 +     This function returns the stream associated with the handle if and
  1.1252 +only if the stream still represents the same MAIL connection associated
  1.1253 +with the handle.  Otherwise, NIL is returned (meaning that there is no
  1.1254 +active stream associated with this handle).
  1.1255 +
  1.1256 +		    Message Data Fetching Functions
  1.1257 +
  1.1258 +[Note!!  There is an important difference between a "sequence" and a
  1.1259 + "msgno".  A sequence is a string representing one or more messages in
  1.1260 + IMAP4-style sequence format ("n", "n:m", or combination of these
  1.1261 + delimited by commas), whereas a msgno is an int representing a single
  1.1262 + message.] 
  1.1263 +
  1.1264 +void mail_fetchfast (MAILSTREAM *stream,char *sequence);
  1.1265 +void mail_fetchfast_full (MAILSTREAM *stream,char *sequence,long flags);
  1.1266 +	stream	stream to fetch on
  1.1267 +	sequence IMAP-format set of message sequence numbers
  1.1268 +	flags	option flags
  1.1269 +
  1.1270 +     This function causes a cache load of all the "fast" information
  1.1271 +(internal date, RFC 822 size, and flags) for the given sequence.  Since
  1.1272 +all this information is also fetched by mail_fetchstructure(), this
  1.1273 +function is generally not used unless the OP_SHORTCACHE option in the
  1.1274 +mail_open() call is used.
  1.1275 +
  1.1276 +     The options for mail_fetchfast_full() are a bit mask with one or
  1.1277 +more of the following:
  1.1278 +	FT_UID		The sequence argument contains UIDs instead of
  1.1279 +			 sequence numbers
  1.1280 +
  1.1281 +
  1.1282 +void mail_fetchflags (MAILSTREAM *stream,char *sequence);
  1.1283 +void mail_fetchflags_full (MAILSTREAM *stream,char *sequence,long flags);
  1.1284 +
  1.1285 +     This function causes a fetch of the flags for the given sequence.
  1.1286 +This main reason for using this function is to update the flags in the
  1.1287 +local cache in case some other process changed the flags (multiple
  1.1288 +simultaneous write access is allowed to the flags) as part of a "check
  1.1289 +entire mailbox" (as opposed to "check for new messages") operation.
  1.1290 +
  1.1291 + The options for mail_fetchflags_full() are a bit mask with one or more
  1.1292 +of the following:
  1.1293 +	FT_UID		The sequence argument contains UIDs instead of
  1.1294 +			 sequence numbers
  1.1295 +
  1.1296 +
  1.1297 +ENVELOPE *mail_fetchenvelope (MAILSTREAM *stream,unsigned long msgno);
  1.1298 +ENVELOPE *mail_fetchstructure (MAILSTREAM *stream,unsigned long msgno,
  1.1299 +			       BODY **body);
  1.1300 +ENVELOPE *mail_fetchstructure_full (MAILSTREAM *stream,unsigned long msgno,
  1.1301 +				    BODY **body,long flags);
  1.1302 +	stream	stream to fetch on
  1.1303 +	msgno	message sequence number
  1.1304 +	body	pointer to where to return BODY structure if non-NIL
  1.1305 +	flags	option flags
  1.1306 +     This function causes a fetch of all the structured information
  1.1307 +(envelope, internal date, RFC 822 size, flags, and body structure) for
  1.1308 +the given msgno and, in the case of IMAP, up to MAPLOOKAHEAD (a
  1.1309 +parameter in IMAP2.H) subsequent messages which are not yet in the
  1.1310 +cache.  No fetch is done if the envelope for the given msgno is already
  1.1311 +in the cache.  The ENVELOPE and the BODY for this msgno is returned.
  1.1312 +It is possible for the BODY to be NIL, in which case no information is
  1.1313 +available about the structure of the message body.
  1.1314 +
  1.1315 +     The options for mail_fetchstructure_full() are a bit mask with one
  1.1316 +or more of the following:
  1.1317 +	FT_UID		The msgno argument is a UID 
  1.1318 +
  1.1319 +     This is the primary function for fetching non-text information
  1.1320 +about messages, and should be called before any attempt to reference
  1.1321 +cache information about this message via mail_elt().
  1.1322 +
  1.1323 +
  1.1324 +char *mail_fetchheader (MAILSTREAM *stream,unsigned long msgno);
  1.1325 +char *mail_fetchheader_full (MAILSTREAM *stream,unsigned long msgno,
  1.1326 +			     STRINGLIST *lines,unsigned long *len,long flags);
  1.1327 +	stream	stream to fetch on
  1.1328 +	msgno	message sequence number
  1.1329 +	lines	list of header lines to fetch
  1.1330 +	len	returned length in octets
  1.1331 +	flags	option flags
  1.1332 +
  1.1333 +     This function causes a fetch of the complete, unfiltered RFC 822
  1.1334 +format header of the specified message as a text string and returns
  1.1335 +that text string.
  1.1336 +
  1.1337 +     If the lines argument is non-NIL, it contains a list of header
  1.1338 +field names to use in subsetting the header text.  Only those lines
  1.1339 +which have that header field name are returned, unless FT_NOT is set in
  1.1340 +which case only those lines which do not have that header field name
  1.1341 +are returned.
  1.1342 +
  1.1343 +     If the len argument is non-NIL, it holds a pointer in which the
  1.1344 +length of the string in octets is returned.  This is useful in cases
  1.1345 +where there may be an embedded null in the string.
  1.1346 +
  1.1347 +     This function always returns a valid string pointer; if no header
  1.1348 +exists or if it can not be fetched (e.g. by a deceased IMAP stream) an
  1.1349 +empty string is returned.
  1.1350 +
  1.1351 +     The options for mail_fetchheader_full() are a bit mask with one or
  1.1352 +more of the following:
  1.1353 +	FT_UID		The msgno argument is a UID 
  1.1354 +	FT_NOT		The returned header lines are those that are
  1.1355 +			 not in the lines argument
  1.1356 +	FT_INTERNAL	The return string is in "internal" format,
  1.1357 +			 without any attempt to canonicalize to CRLF
  1.1358 +			  newlines
  1.1359 +	FT_PREFETCHTEXT	The RFC822.TEXT should be pre-fetched at the
  1.1360 +			 same time.  This avoids an extra RTT on an
  1.1361 +			 IMAP connection if a full message text is
  1.1362 +			 desired (e.g. in a "save to local file"
  1.1363 +			 operation)
  1.1364 +		 
  1.1365 +
  1.1366 +char *mail_fetchtext (MAILSTREAM *stream,unsigned long msgno);
  1.1367 +char *mail_fetchtext_full (MAILSTREAM *stream,unsigned long msgno,
  1.1368 +			   unsigned long *len,long flags);
  1.1369 +	stream	stream to fetch on
  1.1370 +	msgno	message sequence number
  1.1371 +	len	returned length in octets
  1.1372 +	flags	option flags
  1.1373 +
  1.1374 +     This function causes a fetch of the non-header text of the
  1.1375 +specified message as a text string and returns that text string.  No
  1.1376 +attempt is made to segregate individual body parts.
  1.1377 +
  1.1378 +     If the len argument is non-NIL, it holds a pointer in which the
  1.1379 +length of the string in octets is returned.  This is useful in cases
  1.1380 +where there may be an embedded null in the string.
  1.1381 +
  1.1382 +     This function always returns a valid string pointer; if no header
  1.1383 +exists or if it can not be fetched (e.g. by a deceased IMAP stream) an
  1.1384 +empty string is returned.
  1.1385 +
  1.1386 +      The options for mail_fetchtext_full() are a bit mask with one or
  1.1387 +more of the following:
  1.1388 +	FT_UID		The msgno argument is a UID 
  1.1389 +	FT_PEEK		Do not set the \Seen flag if it not already set
  1.1390 +	FT_INTERNAL	The return string is in "internal" format,
  1.1391 +			 without any attempt to canonicalize to CRLF
  1.1392 +			  newlines
  1.1393 +
  1.1394 +
  1.1395 +char *mail_fetchbody (MAILSTREAM *stream,unsigned long msgno,char *sec,
  1.1396 +		      unsigned long *len);
  1.1397 +char *mail_fetchbody_full (MAILSTREAM *stream,unsigned long msgno,char *sec,
  1.1398 +			   unsigned long *len,long flags);
  1.1399 +	stream	stream to fetch on
  1.1400 +	msgno	message sequence number
  1.1401 +	sec	section specifier
  1.1402 +	len	returned length in octets
  1.1403 +	flags	option flags
  1.1404 +
  1.1405 +      This function causes a fetch of the particular section of the
  1.1406 +body of the specified message as a text string and returns that text
  1.1407 +string.  The section specification is a string of integers delimited by
  1.1408 +period which index into a body part list as per the IMAP4
  1.1409 +specification.  Body parts are not decoded by this function; see
  1.1410 +rfc822_base64() and rfc822_quotedprintable().
  1.1411 +
  1.1412 +     If the len argument is non-NIL, it holds a pointer in which the
  1.1413 +length of the string in octets is returned.  This is useful in cases
  1.1414 +where there may be an embedded null in the string.
  1.1415 +
  1.1416 +      This function may return NIL on error.
  1.1417 +
  1.1418 +      The options for mail_fetchbody_full() are a bit mask with one or
  1.1419 +more of the following:
  1.1420 +	FT_UID		The msgno argument is a UID 
  1.1421 +	FT_PEEK		Do not set the \Seen flag if it not already set
  1.1422 +	FT_INTERNAL	The return string is in "internal" format,
  1.1423 +			 without any attempt to canonicalize to CRLF
  1.1424 +			  newlines
  1.1425 +
  1.1426 +
  1.1427 +unsigned long mail_uid (MAILSTREAM *stream,unsigned long msgno);
  1.1428 +	stream	stream to fetch on
  1.1429 +	msgno	message sequence number
  1.1430 +
  1.1431 +      This function returns the UID for the given message sequence
  1.1432 +number.
  1.1433 +
  1.1434 +
  1.1435 +void mail_fetchfrom (char *s,MAILSTREAM *stream,unsigned long msgno,
  1.1436 +		     long length);
  1.1437 +	s	destination string
  1.1438 +	stream	stream to fetch on
  1.1439 +	msgno	message sequence number
  1.1440 +	length	maximum field length
  1.1441 +
  1.1442 +     This function writes a "from" string of the specified length for
  1.1443 +the specified message, suitable for display to the user in a menu line,
  1.1444 +into the string pointed to by s.
  1.1445 +
  1.1446 +      If the personal name of the first address in the envelope's from
  1.1447 +item is non-NIL, it is used; otherwise a string is created by appending
  1.1448 +the mailbox of the first address, an "@", and the host of the first
  1.1449 +address.  The string is trimmed or padded with trailing spaces as
  1.1450 +necessary to make its length match the length argument.
  1.1451 +
  1.1452 +
  1.1453 +void mail_fetchsubject (char *s,MAILSTREAM *stream,unsigned long msgno,
  1.1454 +			long length);
  1.1455 +	s	destination string
  1.1456 +	stream	stream to fetch on
  1.1457 +	msgno	message sequence number
  1.1458 +	length	maximum field length
  1.1459 +
  1.1460 +      This function returns a "subject" string of the specified length
  1.1461 +for the specified message, suitable for display to the user in a menu
  1.1462 +line.
  1.1463 +
  1.1464 +       The envelope's subject item is copied and trimmed as necessary
  1.1465 +to make its length be no more what the caller requested.  Unlike
  1.1466 +mail_fetchfrom(), this function can return a string of shorter length
  1.1467 +than what the caller requested.
  1.1468 +
  1.1469 +
  1.1470 +LONGCACHE *mail_lelt (MAILSTREAM *stream,unsigned long msgno);
  1.1471 +MESSAGECACHE *mail_elt (MAILSTREAM *stream,unsigned long msgno);
  1.1472 +	stream	stream to access
  1.1473 +	msgno	message sequence number
  1.1474 +
  1.1475 +     This function returns the cache entry for the specified message.
  1.1476 +Although it will create a cache entry if it does not already exist,
  1.1477 +that functionality is for internal use only.  This function should
  1.1478 +never be called without having first called mail_fetchfast() or
  1.1479 +mail_fetchstructure() on the message first.
  1.1480 +
  1.1481 +     A cache entry holds the internal date/time, flags, and RFC 822
  1.1482 +size of a message.  It holds other data as well, but that is for
  1.1483 +internal use only.
  1.1484 +
  1.1485 +     mail_lelt() is a variant that returns a `long' cache entry, which
  1.1486 +consists of an cache entry (as a structure, not a pointer), an envelope
  1.1487 +pointer, and a body pointer.  This is used in conjunction with the elt
  1.1488 +lock count functionality, to allow an application to associate the
  1.1489 +cached envelope and body of a message with an open window even if the
  1.1490 +message is subsequently expunged or if the stream is closed.
  1.1491 +
  1.1492 +     Unless your application wants to look at cached envelopes and
  1.1493 +bodies even after the message is expunged or the stream is closed, it
  1.1494 +should not use mail_lelt().  Instead, it should use a returned elt from
  1.1495 +mail_elt() and use the elt->msgsno as the argument to
  1.1496 +mail_fetchstructure().
  1.1497 +
  1.1498 +	BEWARE: the behavior of mail_lelt() is undefined if the
  1.1499 +	stream is open with OP_SHORTCACHE.  mail_lelt() is extremely
  1.1500 +	special purpose, and should only be used in sophisticated
  1.1501 +	special purpose applications after discussing its use with
  1.1502 +	the c-client author.  If you think you need this function,
  1.1503 +	you are probably mistaken.  In almost all cases, you should
  1.1504 +	use mail_elt() and mail_fetchstructure() instead.
  1.1505 +
  1.1506 +		 Message Status Manipulation Functions
  1.1507 +
  1.1508 +void mail_setflag (MAILSTREAM *stream,char *sequence,char *flag);
  1.1509 +void mail_setflag_full (MAILSTREAM *stream,char *sequence,char *flag,
  1.1510 +			long flags);
  1.1511 +	stream	stream to use
  1.1512 +	sequence IMAP-format set of message sequence numbers
  1.1513 +	flag	IMAP-format flag string
  1.1514 +	flags	option flags
  1.1515 +
  1.1516 +    This function causes a store to add the specified flag to the flags
  1.1517 +set for the messages in the specified sequence.  If there is any
  1.1518 +problem in setting flags, a message will be passed to the application
  1.1519 +via the mm_log() facility.
  1.1520 +
  1.1521 +     The options for mail_setflag_full() are a bit mask with one or
  1.1522 +more of the following:
  1.1523 +	ST_UID		The sequence argument contains UIDs instead of
  1.1524 +			 sequence numbers
  1.1525 +	ST_SILENT	Do not update the local cache with the new
  1.1526 +			 value of the flags.  This is useful to save
  1.1527 +			 network bandwidth, at the cost of invalidating
  1.1528 +			 the cache.
  1.1529 +
  1.1530 +
  1.1531 +void mail_clearflag (MAILSTREAM *stream,char *sequence,char *flag);
  1.1532 +void mail_clearflag_full (MAILSTREAM *stream,char *sequence,char *flag,
  1.1533 +			  long flags);
  1.1534 +	stream	stream to use
  1.1535 +	sequence IMAP-format set of message sequence numbers
  1.1536 +	flag	IMAP-format flag string
  1.1537 +	flags	option flags
  1.1538 +
  1.1539 +     This function causes a store to delete the specified flag from the
  1.1540 +flags set for the messages in the specified sequence.  If there is any
  1.1541 +problem in clearing flags, a message will be passed to the application
  1.1542 +via the mm_log() facility.
  1.1543 +
  1.1544 +     The options for mail_setflag_full() are a bit mask with one or
  1.1545 +more of the following:
  1.1546 +	ST_UID		The sequence argument contains UIDs instead of
  1.1547 +			 sequence numbers
  1.1548 +	ST_SILENT	Do not update the local cache with the new
  1.1549 +			 value of the flags.  This is useful to save
  1.1550 +			 network bandwidth, at the cost of invalidating
  1.1551 +			 the cache.
  1.1552 +
  1.1553 +			   Mailbox Searching
  1.1554 +
  1.1555 +void mail_search (MAILSTREAM *stream,char *criteria);
  1.1556 +void mail_search_full (MAILSTREAM *stream,char *charset,SEARCHPGM *pgm,
  1.1557 +		       long flags);
  1.1558 +	stream	stream to search
  1.1559 +	charset	MIME character set to use when searching strings
  1.1560 +	pgm	search program
  1.1561 +	flags	option flags
  1.1562 +
  1.1563 +     This function causes a mailbox search, using the given MIME
  1.1564 +charset (NIL means the default, US-ASCII) and the given search program.
  1.1565 +A search program is a structure that holds the following data:
  1.1566 +
  1.1567 +SEARCHSET *msgno;	a set of message sequence numbers
  1.1568 +SEARCHSET *uid;		a set of unique identifiers
  1.1569 +SEARCHOR *or;		OR result of two search programs
  1.1570 +SEARCHPGMLIST *not;	AND result of list of NOT'ed search programs
  1.1571 +SEARCHHEADER *header;	message headers
  1.1572 +STRINGLIST *bcc;	string(s) appear in bcc list
  1.1573 +STRINGLIST *body;	string(s) appear in message body text
  1.1574 +STRINGLIST *cc;		string(s) appear in cc list
  1.1575 +STRINGLIST *from;	string(s) appear in from
  1.1576 +STRINGLIST *keyword;	user flag string(s) set
  1.1577 +STRINGLIST *unkeyword;	user flag strings() not set
  1.1578 +STRINGLIST *subject;	string(s) appear in subject
  1.1579 +STRINGLIST *text;	string(s) appear in message header or body
  1.1580 +STRINGLIST *to;		string(s) appear in to list
  1.1581 +unsigned long larger;	larger than this many octets
  1.1582 +unsigned long smaller;	smaller than this many octes
  1.1583 +	The following dates are in form:
  1.1584 +		((year - BASEYEAR) << 9) + (month << 5) + day
  1.1585 +unsigned short sentbefore;
  1.1586 +			sent before this date
  1.1587 +unsigned short senton;	sent on this date
  1.1588 +unsigned short sentsince;
  1.1589 +			sent since this date
  1.1590 +unsigned short before;	received before this date
  1.1591 +unsigned short on;	received on this date
  1.1592 +unsigned short since;	received since this date
  1.1593 +unsigned int answered : 1;
  1.1594 +			message answered
  1.1595 +unsigned int unanswered : 1;
  1.1596 +			message not answered
  1.1597 +unsigned int deleted : 1;
  1.1598 +			message deleted
  1.1599 +unsigned int undeleted : 1;
  1.1600 +			message not deleted
  1.1601 +unsigned int draft : 1;	message is a draft
  1.1602 +unsigned int undraft : 1;
  1.1603 +			message is not a draft
  1.1604 +unsigned int flagged : 1;
  1.1605 +			message flagged as urgent
  1.1606 +unsigned int unflagged : 1;
  1.1607 +			message not flagged as urgent
  1.1608 +unsigned int recent : 1;
  1.1609 +			message recent since last parse of mailbox
  1.1610 +unsigned int old : 1;	message not recent since last parse of mailbox
  1.1611 +unsigned int seen : 1;	message read
  1.1612 +unsigned int unseen : 1;
  1.1613 +			message not read
  1.1614 +
  1.1615 +     The following auxillary structures are used by search programs:
  1.1616 +	SEARCHHEADER:	header line searching
  1.1617 +char *line;		header line field name
  1.1618 +char *text;		text header line
  1.1619 +SEARCHHEADER *next;	next SEARCHHEADER in list (AND'ed)
  1.1620 +
  1.1621 +	SEARCHSET:	message number set
  1.1622 +unsigned long first;	first number in set
  1.1623 +unsigned long last;	if non-zero, last number in set
  1.1624 +SEARCHSET *next;	next SEARCHSET in list (AND'ed)
  1.1625 +
  1.1626 +	SEARCHOR:	two search programs, OR'ed together
  1.1627 +SEARCHPGM *first;	first program
  1.1628 +SEARCHPGM *second;	second program
  1.1629 +SEARCHOR *next;		next SEARCHOR in list
  1.1630 +
  1.1631 +	SEARCHPGMLIST:	list of search programs
  1.1632 +SEARCHPGM *pgm;		search program (AND'd with others in list)
  1.1633 +SEARCHPGMLIST *next;	next SEARCHPGM in list
  1.1634 +
  1.1635 +     mail_search(), the older interface, accepts a search criteria
  1.1636 +argument as a character string in IMAP2 (RFC-1176) format.  Do not try
  1.1637 +to use any IMAP4 search criteria with this interface.
  1.1638 +
  1.1639 +     The application's mm_searched() function is called for each
  1.1640 +message that matches the search criteria.  In addition, after the
  1.1641 +search is completed, the "fast" information (see mail_fetchfast_full()
  1.1642 +and envelopes of the searched messages are fetched (this is called
  1.1643 +pre-fetching).
  1.1644 +
  1.1645 +     If there is any problem in searching, a message will be passed to
  1.1646 +the application via the mm_log() facility.
  1.1647 +
  1.1648 +     The flags for mail_search_full() are a bit mask with one or more
  1.1649 +of the following:
  1.1650 +	SE_UID		Return UIDs instead of sequence numbers
  1.1651 +	SE_FREE		Return the search program to free storage after
  1.1652 +			 finishing
  1.1653 +	SE_NOPREFETCH	Don't prefetch searched messages.
  1.1654 +
  1.1655 +
  1.1656 +unsigned long *mail_sort (MAILSTREAM *stream,char *charset,SEARCHPGM *spg,
  1.1657 +			  SORTPGM *pgm,long flags);
  1.1658 +	stream	stream to sort
  1.1659 +	charset	MIME character set to use when sorting strings
  1.1660 +	spg	search program
  1.1661 +	pgm	sort program
  1.1662 +	flags	option flags
  1.1663 +
  1.1664 +
  1.1665 +     This function is a variant of mail_search_full().  It accepts an
  1.1666 +additional argument, a sort program, which specifies one or more sort
  1.1667 +rules to be applied to the result.  If the searching and sorting are
  1.1668 +successful, it returns a 0-terminated vector of message sequence
  1.1669 +numbers (or UIDs if SE_UID is set).  This vector is created out of
  1.1670 +free storage, and must be freed with fs_give() when finished with it.
  1.1671 +
  1.1672 +     A sort program is a structure that holds the following data:
  1.1673 +unsigned int reverse : 1;
  1.1674 +			reverse sorting of this key
  1.1675 +short function;		sort rule, one of the following:
  1.1676 +		SORTDATE	message Date
  1.1677 +		SORTARRIVAL	arrival date
  1.1678 +		SORTFROM	mailbox in first From address
  1.1679 +		SORTSUBJECT	message Subject
  1.1680 +		SORTTO		mailbox in first To address 
  1.1681 +		SORTCC		mailbox in first cc address 
  1.1682 +		SORTSIZE	size of message in octets
  1.1683 +SORTPGM *next;		next sort program to be applied if two or more
  1.1684 +			 messages collate identically with this rule
  1.1685 +
  1.1686 +     The flags for mail_search_full() are a bit mask with one or more
  1.1687 +of the following:
  1.1688 +	SE_UID		Return UIDs instead of sequence numbers
  1.1689 +	SE_FREE		Return the search program to free storage after
  1.1690 +			 finishing
  1.1691 +	SE_NOPREFETCH	Don't prefetch searched messages.
  1.1692 +	SO_FREE		Return the sort program to free storage after
  1.1693 +			 finishing
  1.1694 +
  1.1695 +	      Miscellaneous Mailbox and Message Functions
  1.1696 +
  1.1697 +long mail_ping (MAILSTREAM *stream);
  1.1698 +	stream	string to ping
  1.1699 +
  1.1700 +     The function pings the stream to see if it is still active.  It may
  1.1701 +discover new mail; this is the preferred method for a periodic "new mail
  1.1702 +check" as well as a "keep alive" for servers which have an inactivity
  1.1703 +timeout.  It returns T if the stream is still alive, NIL otherwise.
  1.1704 +
  1.1705 +     If new mail is found, the application's mm_exists() function is
  1.1706 +called with the newly-determined number of messages in the mailbox.
  1.1707 +
  1.1708 +
  1.1709 +void mail_check (MAILSTREAM *stream);
  1.1710 +	stream	stream to checkpoint
  1.1711 +
  1.1712 +      This function causes a mailstore-defined checkpoint of the
  1.1713 +mailbox.  This may include such things as a writeback to disk, a check
  1.1714 +for flag changes in a shared mailbox, etc.  It is not a "check for new
  1.1715 +mail"; mail_ping() performs this function (as potentially does any other
  1.1716 +function).  The status of the check is passed to the application via the
  1.1717 +mm_log() facility.
  1.1718 +
  1.1719 +
  1.1720 +void mail_expunge (MAILSTREAM *stream);
  1.1721 +	stream	string to expunge
  1.1722 +
  1.1723 +     This function causes an expunge (permanent removal of messages
  1.1724 +which are marked as deleted) of the mailbox.  The application's
  1.1725 +mm_expunged() function is called for each message that has been
  1.1726 +expunged.  The application's mm_exists() function is called at the start
  1.1727 +and end of the expunge to ensure synchronization.  The status of the
  1.1728 +expunge is passed to the application via the mm_log() facility.
  1.1729 +
  1.1730 +      Note that the decrementing of msgno's for subsequent messages
  1.1731 +happens immediately; for example, if three consequtive messages starting
  1.1732 +at msgno 5 are expunged, mm_expunged() will be called with a msgno of 5
  1.1733 +three times.
  1.1734 +
  1.1735 +
  1.1736 +long mail_copy (MAILSTREAM *stream,char *sequence,char *mailbox);
  1.1737 +long mail_move (MAILSTREAM *stream,char *sequence,char *mailbox);
  1.1738 +long mail_copy_full (MAILSTREAM *stream,char *sequence,char *mailbox,
  1.1739 +		     long options);
  1.1740 +	stream	stream to copy
  1.1741 +	sequence IMAP-format set of message numbers
  1.1742 +	mailbox	destination mailbox name
  1.1743 +	options	option flags
  1.1744 +
  1.1745 +     This function causes the messages in the specified sequence to be
  1.1746 +copied to the specified mailbox.  T is returned if the copy is
  1.1747 +successful.  mail_move() is equivalent to setting CP_MOVE in the options.
  1.1748 +
  1.1749 +     If there is any problem in copying, a message will be passed to
  1.1750 +the application via the mm_log() facility and the function returns NIL.
  1.1751 +No copying is actually done in this case.
  1.1752 +
  1.1753 +      Note that the mailbox must be on the same host as the stream and
  1.1754 +is a mailbox of the type of the source mailbox only.
  1.1755 +
  1.1756 +     The flags for mail_search_full() are a bit mask with one or more
  1.1757 +of the following:
  1.1758 +	CP_UID		The sequence argument contains UIDs instead of
  1.1759 +			 sequence numbers
  1.1760 +	CP_MOVE		Delete the messages from the current mailbox
  1.1761 +			 after copying to the destination.
  1.1762 +
  1.1763 +
  1.1764 +long mail_append (MAILSTREAM *stream,char *mailbox,STRING *message);
  1.1765 +long mail_append_full (MAILSTREAM *stream,char *mailbox,char *flags,char *date,
  1.1766 +		       STRING *message);
  1.1767 +	stream	stream to use if non-NIL (in the IMAP case)
  1.1768 +	mailbox	destination mailbox name
  1.1769 +	flags	flags to set on message if non-NIL
  1.1770 +	date	internal date (received date) to set on message if non-NIL
  1.1771 +	message	string structure of message to write
  1.1772 +
  1.1773 +     This function writes the message in the string structure to the
  1.1774 +destination mailbox, along with the flags and date if specified.  This
  1.1775 +is useful in those cases where you can't use mail_copy(), e.g. when
  1.1776 +copying from one server to another; you can always fetch the message
  1.1777 +and then mail_append() it to the destination.  It may also be useful
  1.1778 +for maintaining an outbox of your outgoing mail.
  1.1779 +
  1.1780 +
  1.1781 +void mail_gc (MAILSTREAM *stream,long gcflags);
  1.1782 +	stream	stream to GC if non-NIL (else GC's all streams)
  1.1783 +	flags	option flags
  1.1784 +
  1.1785 +      This function garbage collects (purges) the cache of entries of
  1.1786 +a specific type.  Some drivers do not allow purging of particular
  1.1787 +cache types, and an attempt to do so is ignored.
  1.1788 +
  1.1789 +      The flags for mail_gc() are a bit mask with one or more of the
  1.1790 +following:
  1.1791 +	GC_ELT		message cache elements
  1.1792 +	GC_ENV		ENVELOPEs and BODYs
  1.1793 +	GC_TEXTS	cached texts
  1.1794 +
  1.1795 +		     Date/Time Handling Functions
  1.1796 +
  1.1797 +
  1.1798 +char *mail_date (char *string,MESSAGECACHE *elt);
  1.1799 +	string	destination string
  1.1800 +	elt	message cache element containing date
  1.1801 +
  1.1802 +      This function accepts a message cache element that contains date
  1.1803 +information, and writes an IMAP-4 date string, that is, one in form:
  1.1804 +	dd-mmm-yyyy hh:mm:ss +zzzz
  1.1805 +based upon the data in the elt.  The destination string must be large
  1.1806 +enough to hold this string.
  1.1807 +
  1.1808 +
  1.1809 +char *mail_cdate (char *string,MESSAGECACHE *elt);
  1.1810 +	string	destination string
  1.1811 +	elt	message cache element containing date
  1.1812 +
  1.1813 +      This function accepts a message cache element that contains date
  1.1814 +information, and writes a ctime() format date string, that is, one in
  1.1815 +form:
  1.1816 +	www mmm dd hh:mm:ss yyyy\n
  1.1817 +based upon the data in the elt.  The destination string must be large
  1.1818 +enough to hold this string.
  1.1819 +
  1.1820 +
  1.1821 +long mail_parse_date (MESSAGECACHE *elt,char *string);
  1.1822 +	elt	message cache element to store parsed date
  1.1823 +	string	source date string
  1.1824 +
  1.1825 +      This function parses the date/time stored in the given string,
  1.1826 +in format:
  1.1827 +	[www,] date [[hh:mm[:ss][-zzz| +zzzz]
  1.1828 +where the date can be any of:
  1.1829 +	mm/dd/yy, mm/dd/yyyy, dd-mmm-yy, dd-mmm-yyyy, dd mmm yy, dd mmm yyyy
  1.1830 +and stores the result of the parse in the elt.  If the parse is
  1.1831 +successful, T is returned, else NIL.
  1.1832 +
  1.1833 +
  1.1834 +unsigned long mail_longdate (MESSAGECACHE *elt);
  1.1835 +	elt	message cache element containing date.
  1.1836 +
  1.1837 +      This function accepts a message cache element that contains date
  1.1838 +information, and returns the number of days since the base time of the
  1.1839 +imap-4 toolkit.  At present, this is the same as the Unix time() value
  1.1840 +for that date/time, and hence can be used for functions such as utime().
  1.1841 +
  1.1842 +			  Utility Functions
  1.1843 +
  1.1844 +void mail_debug (MAILSTREAM *stream);
  1.1845 +	stream	stream to debug
  1.1846 +
  1.1847 +      This function enables telemetry logging for this stream.  All
  1.1848 +telemetry is passed to the application via the mm_dlog() facility.
  1.1849 +
  1.1850 +
  1.1851 +void mail_nodebug (MAILSTREAM *stream);
  1.1852 +	stream	stream to disable debugging
  1.1853 +
  1.1854 +     This function disables telemetry logging for this stream.
  1.1855 +
  1.1856 +
  1.1857 +long mail_sequence (MAILSTREAM *stream,char *sequence);
  1.1858 +	stream	stream to set the sequence bits
  1.1859 +	sequence IMAP-format message set string
  1.1860 +
  1.1861 +     This function parses the given sequence string for message
  1.1862 +numbers, sets the sequence bit in the stream's message cache element
  1.1863 +of all messages in the sequence (and turns it off in all other message
  1.1864 +cache elements).  If the parse is successful, T is returned, else NIL.
  1.1865 +
  1.1866 +
  1.1867 +long mail_uid_sequence (MAILSTREAM *stream,char *sequence);
  1.1868 +	stream	stream to set the sequence bits
  1.1869 +	sequence IMAP-format message set string
  1.1870 +
  1.1871 +     This function parses the given sequence string for unique
  1.1872 +identifiers, sets the sequence bit in the stream's message cache
  1.1873 +element of all messages in the sequence (and turns it off in all other
  1.1874 +message cache elements).  If the parse is successful, T is returned,
  1.1875 +else NIL.
  1.1876 +
  1.1877 +
  1.1878 +long mail_parse_flags (MAILSTREAM *stream,char *flag,unsigned long *uf);
  1.1879 +	stream	stream (used to get user flags)
  1.1880 +	flag	IMAP-format flag string to parse
  1.1881 +	uf	returned location of user flags
  1.1882 +
  1.1883 +     The function parses the given flag string, and returns the system
  1.1884 +flags as its return value and the user flags in the location pointed
  1.1885 +to by the uf argument.  If there is an error in parse, a log message
  1.1886 +is issued via mm_log() and this function returns NIL.
  1.1887 +
  1.1888 +
  1.1889 +unsigned long mail_filter (char *text,unsigned long len,STRINGLIST *lines,
  1.1890 +			   long flags);
  1.1891 +	text	RFC 822 text to filter
  1.1892 +	len	length in octets in the text argument
  1.1893 +	lines	string list of header file names to filter
  1.1894 +	flags	option flags
  1.1895 +
  1.1896 +     This function supports the header lines filtering function of
  1.1897 +mail_fetchheader_full().  The lines argument contains a list of header
  1.1898 +field names to use in subsetting the header text.  Only those lines
  1.1899 +which have that header field name are returned, unless FT_NOT is set
  1.1900 +in which case only those lines which do not have that header field
  1.1901 +name are returned.
  1.1902 +
  1.1903 +     The options for mail_filter() are a bit mask with one or more of
  1.1904 +the following:
  1.1905 +	FT_NOT		The returned header lines are those that are
  1.1906 +			 not in the lines argument
  1.1907 +
  1.1908 +
  1.1909 +long mail_search_msg (MAILSTREAM *stream,unsigned long msgno,char *charset,
  1.1910 +		      SEARCHPGM *pgm);
  1.1911 +	stream	stream to search
  1.1912 +	msgno	message number of message to inspect
  1.1913 +	charset	character set of search strings
  1.1914 +	pgm	search program to test
  1.1915 +
  1.1916 +     This function implements mail_search_full() locally in cases when
  1.1917 +it is not done by a server (e.g. local mail files, NNTP/POP).  It
  1.1918 +inspects the given message on that stream to see if it matches the
  1.1919 +criteria or not.  If it matches, T is returned, else NIL.
  1.1920 +
  1.1921 +
  1.1922 +SEARCHPGM *mail_criteria (char *criteria);
  1.1923 +	criteria IMAP2-format search criteria string
  1.1924 +
  1.1925 +     This function accepts an IMAP2-format search criteria string and
  1.1926 +parses it.  If the parse is successful, it returns a search program
  1.1927 +suitable for use in mail_search_full().
  1.1928 +	WARNING: This function does not accept IMAP4 search criteria.
  1.1929 +	The source string must be writeable (this restriction was also
  1.1930 +	in the old IMAP2 c-client).
  1.1931 +
  1.1932 +	   Data Structure Instantiation/Destruction functions
  1.1933 +
  1.1934 +     These functions are used to obtain structures from free storage and
  1.1935 +to release them.
  1.1936 +
  1.1937 +ENVELOPE *mail_newenvelope (void);
  1.1938 +ADDRESS *mail_newaddr (void);
  1.1939 +BODY *mail_newbody (void);
  1.1940 +BODY *mail_initbody (BODY *body);
  1.1941 +PARAMETER *mail_newbody_parameter (void);
  1.1942 +PART *mail_newbody_part (void);
  1.1943 +STRINGLIST *mail_newstringlist (void);
  1.1944 +SEARCHPGM *mail_newsearchpgm (void);
  1.1945 +SEARCHHEADER *mail_newsearchheader (char *line);
  1.1946 +SEARCHSET *mail_newsearchset (void);
  1.1947 +SEARCHOR *mail_newsearchor (void);
  1.1948 +SEARCHPGMLIST *mail_newsearchpgmlist (void);
  1.1949 +SORTPGM *mail_newsortpgm (void);
  1.1950 +
  1.1951 +     These functions, all named mail_new...(), create a new structure of
  1.1952 +the given type and initialize all of its elements to zero or empty.
  1.1953 +
  1.1954 +void mail_free_body (BODY **body);
  1.1955 +void mail_free_body_parameter (PARAMETER **parameter);
  1.1956 +void mail_free_body_part (PART **part);
  1.1957 +void mail_free_cache (MAILSTREAM *stream);
  1.1958 +void mail_free_elt (MESSAGECACHE **elt);
  1.1959 +void mail_free_lelt (LONGCACHE **lelt);
  1.1960 +void mail_free_envelope (ENVELOPE **env);
  1.1961 +void mail_free_address (ADDRESS **address);
  1.1962 +void mail_free_stringlist (STRINGLIST **string);
  1.1963 +void mail_free_searchpgm (SEARCHPGM **pgm);
  1.1964 +void mail_free_searchheader (SEARCHHEADER **hdr);
  1.1965 +void mail_free_searchset (SEARCHSET **set);
  1.1966 +void mail_free_searchor (SEARCHOR **orl);
  1.1967 +void mail_free_searchpgmlist (SEARCHPGMLIST **pgl);
  1.1968 +void mail_free_sortpgm (SORTPGM **pgm);
  1.1969 +
  1.1970 +     These functions, all named mail_free_...(), take a pointer to a
  1.1971 +structure pointer, free all contained strings and structures within the
  1.1972 +structure, and finally free the structure itself and set its pointer to
  1.1973 +NIL.  For example, mail_free_envelope() frees all the ADDRESS structures
  1.1974 +contained in the envelope.
  1.1975 +
  1.1976 +     Normally, mail_free_elt() and mail_free_lelt() are used only if the
  1.1977 +main program has a private pointer to cache elements.  If so, it is
  1.1978 +expected to increment the cache element's lockcount when it makes a
  1.1979 +private pointer, and to call this function when it is finished with it.
  1.1980 +
  1.1981 +		       Authentication Functions
  1.1982 +
  1.1983 +char *mail_auth (char *mechanism,authresponse_t resp,int argc,char *argv[]);
  1.1984 +	mechanism authentication mechanism name
  1.1985 +	resp	callback function for providing responses
  1.1986 +	argc	main() function argc value
  1.1987 +	argv	main() function argv value
  1.1988 +
  1.1989 +     This server function searches the list of authenticators that was
  1.1990 +established by auth_link() for an authenticator with the given name.  If
  1.1991 +an authenticator is found, authentication is initialized.  The function
  1.1992 +pointed to by resp is called as the authenticator requires responses.
  1.1993 +
  1.1994 +
  1.1995 +AUTHENTICATOR *mail_lookup_auth (unsigned int i);
  1.1996 +	i	position in authenticator list
  1.1997 +
  1.1998 +     This function returns the nth authenticator in the list, where n is
  1.1999 +the value of it.
  1.2000 +
  1.2001 +
  1.2002 +unsigned int mail_lookup_auth_name (char *mechanism);
  1.2003 +	mechanism authentication mechanism name
  1.2004 +
  1.2005 +     This function searches the list of authenticators for an
  1.2006 +authenticator with the given name, and returns its position in the
  1.2007 +authenticator list.
  1.2008 +
  1.2009 +
  1.2010 +     The functions below are provided by c-client client drivers or by
  1.2011 +servers to support the protocol-dependent parts of authentication.
  1.2012 +
  1.2013 +typedef void *(*authchallenge_t) (void *stream,unsigned long *len);
  1.2014 +	stream	stream to read challenge
  1.2015 +	len	pointer to returned length in octets
  1.2016 +
  1.2017 +     This driver function is called by an authenticator to read a
  1.2018 +challenge from the given protocol stream in a protocol-dependent way.
  1.2019 +It returns that challenge in binary and its length in octets to the
  1.2020 +authenticator.
  1.2021 +
  1.2022 +
  1.2023 +typedef long (*authrespond_t) (void *stream,char *s,unsigned long size);
  1.2024 +	stream	stream to send response
  1.2025 +	s	response string
  1.2026 +	size	length of response string in octets
  1.2027 +
  1.2028 +     This driver function is called by an authenticator to send a
  1.2029 +challenge response to the given stream in a protocol-dependent way.
  1.2030 +It returns T if successful, NIL if failure.
  1.2031 +
  1.2032 +
  1.2033 +typedef char *(*authresponse_t) (void *challenge,unsigned long clen,
  1.2034 +				 unsigned long *rlen);
  1.2035 +	challenge challenge string
  1.2036 +	clen	length of challenge string in octets
  1.2037 +	rlen	pointer to returned length of response string
  1.2038 +
  1.2039 +     This server function is called with a challenge string of clen
  1.2040 +octets.  It sends, according to whatever protocol (IMAP, POP, etc.) it
  1.2041 +uses, and returns the received response and response length in octets.
  1.2042 +
  1.2043 +
  1.2044 +typedef long (*authclient_t) (authchallenge_t challenger,
  1.2045 +			      authrespond_t responder,NETMBX *mb,void *s,
  1.2046 +			      unsigned long trial);
  1.2047 +	challenger pointer to protocol-dependent challenge reader function
  1.2048 +	responder pointer to protocol-dependent response sender function
  1.2049 +	mb	NETMBX struct of the mailbox desired to open
  1.2050 +	s	stream for protocol-dependent routines to use
  1.2051 +	trial	number of authentication attempts remaining
  1.2052 +
  1.2053 +     This client authenticator function negotiates reading challenges
  1.2054 +and sending responses for a particular authenticator (Kerberos, etc.)
  1.2055 +over the protocol, and returns T if authenticated or NIL if failed.
  1.2056 +
  1.2057 +
  1.2058 +typedef char *(*authserver_t) (authresponse_t responder,int argc,char *argv[]);
  1.2059 +	responder pointer to protocol-dependent responder function
  1.2060 +	argc	main() function argc value
  1.2061 +	argv	main() function argv value
  1.2062 +
  1.2063 +    This server authenticator function negotiates sending challenges and
  1.2064 +reading responses for a particular authenticator (Kerberos, etc.), and
  1.2065 +returns either the authenticated user name or NIL if authentication
  1.2066 +failed.
  1.2067 +
  1.2068 +		       Network Access Functions
  1.2069 +
  1.2070 +     These functions provide a layer of indirection between the TCP
  1.2071 +routines and upper level routines.  This makes it possible to insert
  1.2072 +additional code (e.g. privacy or checksum handling).
  1.2073 +
  1.2074 +NETSTREAM *net_open (char *host,char *service,unsigned long port);
  1.2075 +	host	host name
  1.2076 +	service	contact service name
  1.2077 +	port	contact port number
  1.2078 +
  1.2079 +     This function opens a TCP connection to the given host and service
  1.2080 +or port.
  1.2081 +
  1.2082 +
  1.2083 +NETSTREAM *net_aopen (NETMBX *mb,char *service,char *usrbuf);
  1.2084 +	NETMBX	parsed mailbox specification
  1.2085 +	service	stream to open (at present, only /etc/rimapd is used)
  1.2086 +	usrbuf	buffer to return login user name
  1.2087 +
  1.2088 +     This function attempts to open a preauthenticated connection to the
  1.2089 +given mailbox and service.  It will return the login user name of the
  1.2090 +preauthenticated connection, as well as an open network stream, if
  1.2091 +successful.
  1.2092 +
  1.2093 +
  1.2094 +char *net_getline (NETSTREAM *stream);
  1.2095 +	stream	network stream to read
  1.2096 +
  1.2097 +     This routine reads a text line from the stream.  It calls
  1.2098 +stream->dtb->getline, which normally points to tcp_getline() but can be
  1.2099 +set to some other function.
  1.2100 +
  1.2101 +
  1.2102 +long net_getbuffer (void *stream,unsigned long size,char *buffer);
  1.2103 +	stream	network stream to read
  1.2104 +	size	length of data in octets
  1.2105 +	buffer	buffer of at least size octets
  1.2106 +
  1.2107 +     This routine reads data from the stream.  It calls
  1.2108 +stream->dtb->getbuffer, which normally points to tcp_getbuffer() but can
  1.2109 +be set to some other function.
  1.2110 +
  1.2111 +
  1.2112 +long net_soutr (NETSTREAM *stream,char *string);
  1.2113 +	stream	network stream to write
  1.2114 +	string	null-terminated string to output
  1.2115 +
  1.2116 +     This routine writes a null-terminated string to the stream.  It
  1.2117 +calls stream->dtb->soutr, which normally points to tcp_soutr() but can
  1.2118 +be set to some other function.
  1.2119 +
  1.2120 +
  1.2121 +long net_sout (NETSTREAM *stream,char *string,unsigned long size);
  1.2122 +	stream	network stream to write
  1.2123 +	string	string to output
  1.2124 +	size	length of string in octets
  1.2125 +
  1.2126 +     This routine writes a string of length size to the stream.  It
  1.2127 +calls stream->dtb->sout, which normally points to tcp_sout() but can be
  1.2128 +set to some other function.
  1.2129 +
  1.2130 +
  1.2131 +void net_close (NETSTREAM *stream);
  1.2132 +	stream	stream to close
  1.2133 +
  1.2134 +     This routine closes the stream.  It calls stream->dtb->close, which
  1.2135 +normally points to tcp_close() but can point to some other function.
  1.2136 +
  1.2137 +
  1.2138 +char *net_host (NETSTREAM *stream);
  1.2139 +	stream	stream to inspect
  1.2140 +
  1.2141 +     This routine returns the remote host name of the stream.  It calls
  1.2142 +stream->dtb->host, which normally points to tcp_host() but can point
  1.2143 +to some other function.
  1.2144 +
  1.2145 +
  1.2146 +unsigned long net_port (NETSTREAM *stream);
  1.2147 +	stream	stream to inspect
  1.2148 +
  1.2149 +     This routine returns the remote port number of the stream.  It calls
  1.2150 +stream->dtb->port, which normally points to tcp_port() but can point
  1.2151 +to some other function.
  1.2152 +
  1.2153 +
  1.2154 +char *net_localhost (NETSTREAM *stream);
  1.2155 +	stream	stream to inspect
  1.2156 +
  1.2157 +     This routine returns the local host name of the stream.  It calls
  1.2158 +stream->dtb->localhost, which normally points to tcp_localhost() but can
  1.2159 +point to some other function.
  1.2160 +
  1.2161 +		  Subscription Management Functions
  1.2162 +
  1.2163 +long sm_subscribe (char *mailbox);
  1.2164 +	mailbox	mailbox name to subscribe
  1.2165 +
  1.2166 +     This function adds the given mailbox name to the local subscription
  1.2167 +list, and returns T if successful, NIL if failure.
  1.2168 +
  1.2169 +
  1.2170 +long sm_unsubscribe (char *mailbox);
  1.2171 +	mailbox	mailbox name to unsubscribe
  1.2172 +
  1.2173 +     This function removes the given mailbox name from the local
  1.2174 +subscription list, and returns T if successful, NIL if failure.
  1.2175 +
  1.2176 +char *sm_read (void **sdb);
  1.2177 +	sdb	data to use in subsequent calls, or NIL if first call
  1.2178 +
  1.2179 +     This function returns the local subscription list as null
  1.2180 +terminated strings.  Each call returns the next element in the list.
  1.2181 +The first call should be with sdb pointing to a NIL pointer; this will
  1.2182 +be filled in for subsequent calls.  At the last call, NIL will be
  1.2183 +returned.
  1.2184 +
  1.2185 +		    Miscellaneous Utility Functions
  1.2186 +
  1.2187 +char *ucase (char *string);
  1.2188 +	string	string to convert
  1.2189 +
  1.2190 +     This function converts each lowercase character of the specified
  1.2191 +string to uppercase and returns the string.
  1.2192 +
  1.2193 +
  1.2194 +char *lcase (char *string);
  1.2195 +	string	string to convert
  1.2196 +
  1.2197 +     This function converts each uppercase character of the specified
  1.2198 +string to lowercase and returns the string.
  1.2199 +
  1.2200 +
  1.2201 +char *cpystr (char *string);
  1.2202 +	string	string to copy
  1.2203 +
  1.2204 + This function makes a copy of the string from free storage and returns
  1.2205 +the copy.
  1.2206 +
  1.2207 +
  1.2208 +long find_rightmost_bit (long *valptr);
  1.2209 +	valptr	pointer to value to search
  1.2210 +
  1.2211 +      This function returns -1 if the 32-bit value pointed to by valptr
  1.2212 +is non-zero, otherwise it returns the bit number (0 = LSB, 31 = MSB) of
  1.2213 +the right-most bit in that value.  This is used to convert from the bits
  1.2214 +in the cache's userflags item to an index into the stream's userFlags
  1.2215 +array of flag texts.
  1.2216 +
  1.2217 +
  1.2218 +long min (long i,long j);
  1.2219 +	i	first argument
  1.2220 +	j	second argument
  1.2221 +
  1.2222 +      This function returns the minimum of the two integers.
  1.2223 +
  1.2224 +long max (long i,long j);
  1.2225 +	i	first argument
  1.2226 +	j	second argument
  1.2227 +
  1.2228 +     This function returns the maximum of the two integers.
  1.2229 +
  1.2230 +long search (char *s,long c,char *pat,long patc);
  1.2231 +	s	string to search
  1.2232 +	c	size of string
  1.2233 +	pat	pattern to search in string
  1.2234 +	patc	size of pattern
  1.2235 +
  1.2236 +      This function does a fast case-independent search for the given
  1.2237 +pattern in pat (length patc) in base string s, and returns T if the
  1.2238 +pattern is found in the string.
  1.2239 +
  1.2240 +
  1.2241 +long pmatch (char *s,char *pat,delim);
  1.2242 +long pmatch_full (char *s,char *pat,delim);
  1.2243 +	s	string to match
  1.2244 +	pat	wildcard (* and %) to match in pattern
  1.2245 +	delim	hierarchy delimiter
  1.2246 +
  1.2247 +      This function returns T if the given wildcard pattern matches the
  1.2248 +string in s with hierarchy delimiter delim.  Otherwise NIL is returned.
  1.2249 +
  1.2250 +
  1.2251 +long dmatch (char *s,char *pat,char delim);
  1.2252 +	s	string to match
  1.2253 +	pat	wildcard (* and %) to match in pattern
  1.2254 +	delim	hierarchy delimiter
  1.2255 +
  1.2256 +     This function returns T if the given wildcard pattern matches the
  1.2257 +directory.  If not, then none of the elements in the directory are
  1.2258 +considered for recursive checking with pmatch_full().
  1.2259 +
  1.2260 +			     SMTP Functions
  1.2261 +
  1.2262 +SMTPSTREAM *smtp_open (char **hostlist,long debug);
  1.2263 +	hostlist vector of SMTP server host names to try
  1.2264 +	debug	non-zero if want protocol telemetry debugging
  1.2265 +
  1.2266 +      This function opens an SMTP connection to a one of the hosts in the
  1.2267 +host list and if successful returns a stream suitable for use by the
  1.2268 +other SMTP functions.  The hosts are tried in order until a connection is
  1.2269 +successfully opened.  If debug is non-NIL, protocol telemetry is logged
  1.2270 +via mm_dlog().  NIL is returned if this function fails to open a
  1.2271 +connection to any of the hosts in the list.
  1.2272 +
  1.2273 +void smtp_close (SMTPSTREAM *stream);
  1.2274 +	stream	stream to close
  1.2275 +
  1.2276 +     This function closes the SMTP stream and frees all resources
  1.2277 +associated with it that it may have created.
  1.2278 +
  1.2279 +long smtp_mail (SMTPSTREAM *stream,char *type,ENVELOPE *msg,BODY *body);
  1.2280 +	stream	stream to transmit mail
  1.2281 +	type	mail type (MAIL, SEND, SAML, SOML)
  1.2282 +	msg	message envelope
  1.2283 +	body	message body
  1.2284 +
  1.2285 +      This function negotiates an SMTP transaction of the specified type
  1.2286 +(one of "MAIL", "SEND", "SAML", or "SOML") to deliver the specified
  1.2287 +message.  This function returns T if success or NIL if there is any
  1.2288 +failure.  The text reason for the failure is in stream->reply item; if
  1.2289 +it is associated with a recipient it is also in that address'
  1.2290 +address->error item.
  1.2291 +
  1.2292 +
  1.2293 +void smtp_debug (SMTPSTREAM *stream);
  1.2294 +	stream	stream to enable debugging telemetry
  1.2295 +
  1.2296 +      This function enables SMTP protocol telemetry logging for this
  1.2297 +stream.  All SMTP protocol operations are passed to the application via
  1.2298 +the mm_dlog() facility.
  1.2299 +
  1.2300 +
  1.2301 +void smtp_nodebug (SMTPSTREAM *stream);
  1.2302 +	stream	stream to disable debugging telemetry
  1.2303 +
  1.2304 +      This function disables SMTP protocol telemetry logging for this
  1.2305 +stream.
  1.2306 +
  1.2307 +
  1.2308 +typedef void (*smtpverbose_t) (char *buffer);
  1.2309 +	buffer	pointer to verbose reply buffer
  1.2310 +
  1.2311 +     This is the argument to the SET_SMTPVERBOSE mail_parmameter() call.
  1.2312 +If this function pointer is non-NIL, then if a verbose SMTP response
  1.2313 +(with SMTP code less than 100) is received, this function is called with
  1.2314 +that response text as its argument.
  1.2315 +
  1.2316 +			     NNTP Functions
  1.2317 +
  1.2318 +NNTPSTREAM *nntp_open (char **hostlist,long debug);
  1.2319 +	hostlist vector of NNTP server host names to try
  1.2320 +	debug	non-zero if want protocol telemetry debugging
  1.2321 +
  1.2322 +      This function opens an NNTP connection to a one of the hosts in the
  1.2323 +host list and if successful returns a stream suitable for use by the
  1.2324 +other MTP functions.  The hosts are tried in order until a connection is
  1.2325 +successfully opened.  If debug is non-NIL, protocol telemetry is logged
  1.2326 +via mm_dlog().  NIL is returned if this function fails to open a
  1.2327 +connection to any of the hosts in the list.
  1.2328 +
  1.2329 +
  1.2330 +void nntp_close (NNTPSTREAM *stream);
  1.2331 +	stream	stream to close
  1.2332 +
  1.2333 +     This function closes the NNTP stream and frees all resources
  1.2334 +associated with it that it may have created.
  1.2335 +
  1.2336 +
  1.2337 +long nntp_mail (NNTPSTREAM *stream,ENVELOPE *msg,BODY *body);
  1.2338 +	stream	stream to transmit mail
  1.2339 +	msg	message envelope
  1.2340 +	body	message body
  1.2341 +
  1.2342 +      This function negotiates an NNTP posting transaction to deliver
  1.2343 +the specified news message.  This function returns T if success or NIL
  1.2344 +if there is any failure.  The text reason for the failure is in
  1.2345 +stream->reply item; if it is associated with a recipient it is also in
  1.2346 +that address' address->error item.
  1.2347 +
  1.2348 +		      RFC 822 Support Functions
  1.2349 +
  1.2350 +     Although rfc822.c contains several additional functions besides
  1.2351 +these, only the functions documented here should be used by
  1.2352 +applications.  The other functions are for internal use only.
  1.2353 +
  1.2354 +
  1.2355 +void rfc822_header (char *header,ENVELOPE *env,BODY *body);
  1.2356 +	header	buffer to write RFC 822 header
  1.2357 +	env	message ENVELOPE (used to obtain RFC 822 information)
  1.2358 +	body	message BODY (used to obtain MIME information)
  1.2359 +
  1.2360 +     This function writes an RFC 822 format header into header based
  1.2361 +on the information in the envelope and body.  The header buffer must
  1.2362 +be large enough to contain the full text of the resulting header.
  1.2363 +
  1.2364 +
  1.2365 +void rfc822_write_address (char *dest,ADDRESS *adr);
  1.2366 +	dest	buffer to write address list
  1.2367 +	adr	RFC 822 ADDRESS list
  1.2368 +
  1.2369 +     This function writes an RFC 822 format address list into dest
  1.2370 +based on the information in adr.  The dest buffer must be large enough
  1.2371 +to contain the full text of the resulting address list.
  1.2372 +
  1.2373 +void rfc822_parse_msg (ENVELOPE **en,BODY **bdy,char *s,unsigned long i,
  1.2374 +		       STRING *b,char *host,char *tmp);
  1.2375 +	en	destination pointer where message ENVELOPE will be stored
  1.2376 +	bdy	destination pointer where message BODY will be stored
  1.2377 +	s	RFC 822 header to parse (character string)
  1.2378 +	i	length of RFC 822 header
  1.2379 +	b	stringstruct of message body
  1.2380 +	host	default host name if an address lacks an @host.
  1.2381 +	temp	scratch buffer, must be long enough to hold unwound
  1.2382 +		 header lines (a buffer that is i octets long is OK)
  1.2383 +
  1.2384 +     This function parses the RFC 822 header pointed to by s with body
  1.2385 +pointed to by string structure b into the specified destination
  1.2386 +envelope and body pointers, using host as the default host name and
  1.2387 +tmp as a scratch buffer.  New ENVELOPE and BODY structures are
  1.2388 +created; when finished with them the application must free them with
  1.2389 +mail_free_envelope() and mail_free_body().  Any parsing errors are
  1.2390 +noted via the mm_log() mechanism using log type PARSE.
  1.2391 +
  1.2392 +
  1.2393 +void rfc822_parse_adrlist (ADDRESS **lst,char *string,char *host);
  1.2394 +	lst	destination pointer where ADDRESS will be stored
  1.2395 +	string	string of addresses to parse
  1.2396 +	host	default host name if an address lacks an @host.
  1.2397 +
  1.2398 +     This function parses the address list in the given string into an
  1.2399 +address list in lst.  Any addresses missing a host name are have the
  1.2400 +host name defaulted from the host argument.  If the destination list
  1.2401 +is non-empty it appends the new addresses to the list.  Any parsing
  1.2402 +errors are noted via the mm_log() mechanism using log type PARSE.
  1.2403 +
  1.2404 +long rfc822_output (char *t,ENVELOPE *env,BODY *body,soutr_t f,void *s,
  1.2405 +		    long ok8bit);
  1.2406 +	t	scratch buffer, large enough to hold message header
  1.2407 +	env	message ENVELOPE
  1.2408 +	body	message BODY
  1.2409 +	f	I/O function to write to
  1.2410 +	s	stream for I/O function f
  1.2411 +	ok8bit	non-zero if OK to output 8-bit data
  1.2412 +
  1.2413 +     This function writes the message described with the given
  1.2414 +envelope and body.  Any body part contents of type ENCBINARY is
  1.2415 +converted to ENCBASE64 before sending.  If ok8bit is NIL, any message
  1.2416 +data of type ENC8BIT is converted to ENCQUOTEDPRINTABLE before
  1.2417 +sending; if ok8bit is non-NIL then ENC8BIT data is sent as-is.  T is
  1.2418 +returned if the function succeeds, else NIL is returned.
  1.2419 +
  1.2420 +     The function f is typically net_soutr(), but it can be any
  1.2421 +function which matches
  1.2422 +  typedef long (*soutr_t) (void *stream,char *string);
  1.2423 +where stream holds sufficient information to enable the output routine
  1.2424 +to know where to output to, and the string is a null-terminated string
  1.2425 +to output.  This function returns either T or NIL, and that value is
  1.2426 +passed up to rfc822_output() for its return.
  1.2427 +
  1.2428 +
  1.2429 +void *rfc822_base64 (char *src,unsigned long srcl,unsigned long *len);
  1.2430 +	src	source string
  1.2431 +	srcl	size of source string in octets
  1.2432 +	len	pointer to where destination string length in octets
  1.2433 +		 will be returned
  1.2434 +
  1.2435 +     This function decodes a BASE64 body part given a source string
  1.2436 +and its length.  The decoded body part as a sequence of binary octets
  1.2437 +is returned, and its length is returned in len.
  1.2438 +
  1.2439 +
  1.2440 +char *rfc822_qprint (char *src,unsigned long srcl,unsigned long *len);
  1.2441 +	src	source string
  1.2442 +	srcl	size of source string in octets
  1.2443 +	len	pointer to where destination string length in octets
  1.2444 +		 will be returned
  1.2445 +
  1.2446 +     This function decodes a QUOTED-PRINTABLE body part given a source
  1.2447 +string and its length.  The decoded body part as an 8-bit character
  1.2448 +string is returned, and its length is returned in len.
  1.2449 +
  1.2450 +	     Operating System-Dependent Public Interface
  1.2451 +
  1.2452 +     These functions are in OS-dependent code, and are rewritten each
  1.2453 +time c-client is ported to a new operating system.
  1.2454 +
  1.2455 +
  1.2456 +void rfc822_date (char *date);
  1.2457 +	date	buffer to write the date, must be large enough
  1.2458 +
  1.2459 +     This function is called to get the current date and time in an
  1.2460 +RFC 822 format string into the given buffer.
  1.2461 +
  1.2462 +
  1.2463 +void *fs_get (size_t size);
  1.2464 +	size	number of octets requested
  1.2465 +
  1.2466 +      This function allocates and returns a block of free storage of
  1.2467 +the specified size.  Unlike malloc(), there is no failure return; this
  1.2468 +function must return with the requested storage.
  1.2469 +
  1.2470 +
  1.2471 +void fs_resize (void **block,size_t size);
  1.2472 +	block	pointer to pointer to block to be resized
  1.2473 +	size	new size in octets
  1.2474 +
  1.2475 +     This function resizes the free storage block, updating the
  1.2476 +pointer if necessary.  Unlike realloc(), there is no failure return;
  1.2477 +this function must return with the requested storage.
  1.2478 +
  1.2479 +
  1.2480 +void fs_give (void **block);
  1.2481 +	block	pointer to pointer to block to free
  1.2482 +
  1.2483 +      This function releases a block of free storage allocated by
  1.2484 +fs_get().  It also erases the block pointer, so it isn't necessary to
  1.2485 +do this in the application.
  1.2486 +
  1.2487 +
  1.2488 +void fatal (char *string);
  1.2489 +	string	message string
  1.2490 +
  1.2491 +      This function is called when an "impossible" error is detected
  1.2492 +and the client wishes to crash.  The string should contain a reason.
  1.2493 +
  1.2494 +
  1.2495 +char *strcrlfcpy (char **dst,long *dstl,char *src,long srcl);
  1.2496 +	dst	pointer to destination string pointer
  1.2497 +	dstl	pointer to destination string size
  1.2498 +	src	source strin
  1.2499 +	srcl	source string size
  1.2500 +
  1.2501 +      This function is called to copy into a destination string dst of
  1.2502 +size dstl (resized if necessary), a CRLF newline form string from
  1.2503 +local format string src of size srcl.
  1.2504 +
  1.2505 +
  1.2506 +TCPSTREAM *tcp_open (char *host,long port);
  1.2507 +TCPSTREAM *tcp_aopen (char *host,char *service);
  1.2508 +char *tcp_getline (TCPSTREAM *stream);
  1.2509 +long tcp_getbuffer (TCPSTREAM *stream,long size,char *buffer);
  1.2510 +long tcp_soutr (TCPSTREAM *stream,char *string);
  1.2511 +void tcp_close (TCPSTREAM *stream);
  1.2512 +char *tcp_host (TCPSTREAM *stream);
  1.2513 +unsigned long tcp_port (TCPSTREAM *stream);
  1.2514 +char *tcp_localhost (TCPSTREAM *stream);
  1.2515 +
  1.2516 +     These functions are TCP-specific versions of the more general
  1.2517 +net_xxx() functions.  These should not be called directly by
  1.2518 +applications.
  1.2519 +
  1.2520 +
  1.2521 +char *tcp_clienthost (char *dst);
  1.2522 +	dst	destination string buffer
  1.2523 +
  1.2524 +     This function should be called only by a server called by inetd
  1.2525 +or similar mechanism which maps standard input to a network socket.
  1.2526 +It returns the host name of the other end (e.g. the client of a
  1.2527 +server) using the given string buffer, or NIL if it can't get this
  1.2528 +information.
  1.2529 +
  1.2530 +			Main Program Callbacks
  1.2531 +
  1.2532 +     All applications which use the c-client must have the following
  1.2533 +callbacks to handle events from c-client.  Note that in any callback
  1.2534 +which involves a mail stream, the stream is locked and you can not
  1.2535 +recursively call c-client from the callback.  This may also be true in
  1.2536 +callbacks which do not have a stream; in general, the rule is "do not
  1.2537 +call c-client, especially any mail_xxx() function, from a c-client
  1.2538 +callback".
  1.2539 +
  1.2540 +
  1.2541 +void mm_flags (MAILSTREAM *stream,unsigned long number);
  1.2542 +	stream	stream where event happened
  1.2543 +	number	message number
  1.2544 +
  1.2545 +     This function is called when c-client manipulates the flags for
  1.2546 +the given message number.  This alerts the application that it may
  1.2547 +need to inspect that message's flags to see if there are any
  1.2548 +interesting changes.
  1.2549 +
  1.2550 +
  1.2551 +void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status);
  1.2552 +	stream	stream where event happened
  1.2553 +	mailbox	mailbox name for this status
  1.2554 +	status	MAILSTATUS structure with message status
  1.2555 +
  1.2556 +     This function is called when c-client reports status of a mailbox
  1.2557 +(generally as the result of a mail_status() function call).  The
  1.2558 +returned MAILSTATUS structure has the following members:
  1.2559 +
  1.2560 +long flags;			validity flags.  These are the same as
  1.2561 +				 the SA_xxx option flags in the
  1.2562 +				 mail_status() call, and they indicate
  1.2563 +				 which of the other members of the
  1.2564 +				 MAILSTATUS structure have usable data
  1.2565 +				 (i.e. if SA_MESSAGES is not set, do
  1.2566 +				 not believe status->messages!!).
  1.2567 +unsigned long messages;		number of messages if SA_MESSAGES
  1.2568 +unsigned long recent;		number of recent messages if SA_RECENT
  1.2569 +unsigned long unseen;		number of unseen messages if SA_UNSEEN
  1.2570 +unsigned long uidnext;		next UID to be assigned if SA_UIDNEXT
  1.2571 +unsigned long uidvalidity;	UID validity value if SA_UIDVALIDITY
  1.2572 +
  1.2573 +
  1.2574 +void mm_searched (MAILSTREAM *stream,unsigned long number);
  1.2575 +	stream	stream where event happened
  1.2576 +	number	message number
  1.2577 +
  1.2578 +     This function is called to notify the main program that this
  1.2579 +message number matches a search (generally as the result of a
  1.2580 +mail_search_full() function call).
  1.2581 +
  1.2582 +
  1.2583 +void mm_exists (MAILSTREAM *stream,unsigned long number);
  1.2584 +	stream	stream where event happened
  1.2585 +	number	message number
  1.2586 +
  1.2587 +     This function is called to notify the main program that there are
  1.2588 +this many messages in the mailbox.  It is also used to notify the main
  1.2589 +program of new mail, by announcing a higher number than the main
  1.2590 +program was previously aware.
  1.2591 +
  1.2592 +
  1.2593 +void mm_expunged (MAILSTREAM *stream,unsigned long number);
  1.2594 +	stream	stream where event happened
  1.2595 +	number	message number
  1.2596 +
  1.2597 +     This function is called to notify the main program that this
  1.2598 +message number has been expunged from the mail file and that all
  1.2599 +subsequent messages are now referenced by a message number one less
  1.2600 +than before.  This implicitly decrements the number of messages in the
  1.2601 +mailbox.
  1.2602 +
  1.2603 +
  1.2604 +void mm_list (MAILSTREAM *stream,char delim,char *name,long attrib);
  1.2605 +	stream	stream where event happened
  1.2606 +	delim	hierarchy delimiter
  1.2607 +	name	mailbox name
  1.2608 +	attrib	mailbox attributes
  1.2609 +
  1.2610 +     This function is called to notify the main program that this
  1.2611 +mailbox name matches a mailbox listing request (generally as the
  1.2612 +result of a mail_list() function call).  The hierarchy delimiter is a
  1.2613 +character that separates out levels of hierarchy in mailbox names.
  1.2614 +The attributes are a bit mask with one of the following:
  1.2615 +	LATT_NOINFERIORS
  1.2616 +			it is not possible for there to be any
  1.2617 +			 hierarchy inferiors to this name (that is,
  1.2618 +			 this name followed by the hierarchy delimiter
  1.2619 +			 and additional name characters).
  1.2620 +	LATT_NOSELECT	this is not a mailbox name, just a hierarchy
  1.2621 +			 level, and it may not be opened by mail_open()
  1.2622 +	LATT_MARKED	this mailbox may have recent messages
  1.2623 +	LATT_UNMARKED	this mailbox does not have any recent messages
  1.2624 +
  1.2625 +
  1.2626 +void mm_lsub (MAILSTREAM *stream,char delim,char *name,long attrib);
  1.2627 +	stream	stream where event happened
  1.2628 +	delim	hierarchy delimiter
  1.2629 +	name	mailbox name
  1.2630 +	attrib	mailbox attributes
  1.2631 +
  1.2632 +
  1.2633 +     This function is called to notify the main program that this
  1.2634 +mailbox name matches a subscribed mailbox listing request (generally
  1.2635 +as the result of a mail_lsub() function call).  The hierarchy
  1.2636 +delimiter is a character that separates out levels of hierarchy in
  1.2637 +mailbox names.  The attributes are a bit mask with one of the
  1.2638 +following:
  1.2639 +	LATT_NOINFERIORS
  1.2640 +			it is not possible for there to be any
  1.2641 +			 hierarchy inferiors to this name (that is,
  1.2642 +			 this name followed by the hierarchy delimiter
  1.2643 +			 and additional name characters).
  1.2644 +	LATT_NOSELECT	this is not a mailbox name, just a hierarchy
  1.2645 +			 level, and it may not be opened by mail_open()
  1.2646 +	LATT_MARKED	this mailbox may have recent messages
  1.2647 +	LATT_UNMARKED	this mailbox does not have any recent messages
  1.2648 +
  1.2649 +
  1.2650 +void mm_notify (MAILSTREAM *stream,char *string,long errflg);
  1.2651 +	stream	stream where event happened
  1.2652 +	string	message string
  1.2653 +	errflg	message error level
  1.2654 +
  1.2655 +     This function is called to deliver a stream-oriented message
  1.2656 +event.  This is the mechanism by which any IMAP response codes for any
  1.2657 +application (e.g. TRYCREATE) are delivered to the application.
  1.2658 +No newline is included in the string, so this function has to output
  1.2659 +its own.
  1.2660 +
  1.2661 +     The message error level is one of the following:
  1.2662 +
  1.2663 +	NIL	normal operation.  The text is `babble' that may be
  1.2664 +		interesting to the user, e.g. the greeting message
  1.2665 +		from a server.
  1.2666 +
  1.2667 +	WARN	A warning event.  This event should be displayed to
  1.2668 +		the user.  Examples: a mailbox rewrite failed because
  1.2669 +		of disk full, but the previous mailbox contents were
  1.2670 +		recovered.
  1.2671 +
  1.2672 +	ERROR	An error event.  This event should be displayed to
  1.2673 +		the user, or at least logged someplace.  This type of
  1.2674 +		error shouldn't happen, and so should be called to the
  1.2675 +		attention of support staff.  Whatever happened has
  1.2676 +		probably disrupted the user's work.  Examples: an
  1.2677 +		untagged BAD from an IMAP server.
  1.2678 +
  1.2679 +
  1.2680 +void mm_log (char *string,long errflg);
  1.2681 +	string	message string
  1.2682 +	errflg	message error level
  1.2683 +
  1.2684 +      This function is called to deliver a log message.  No newline is
  1.2685 +included in the string, so this function has to output its own.  In
  1.2686 +general, it is intended that these messages are logged someplace, and
  1.2687 +possibly shown to the user.
  1.2688 +
  1.2689 +     The message error level is one of the following:
  1.2690 +
  1.2691 +	NIL	normal operation.  The text is `babble' that may be
  1.2692 +		interesting to the user, e.g. "Expunged 3 messages".
  1.2693 +
  1.2694 +	PARSE	An RFC 822 parsing error.  Since bogus headers are
  1.2695 +		all-too-common in the real world, these can often be
  1.2696 +		ignored on the "garbage in, garbage out" princple.
  1.2697 +		However, since surprising results can be yielded when
  1.2698 +		trying to parse garbage, this message should be logged
  1.2699 +		somewhere so it can be figured out what happened.
  1.2700 +
  1.2701 +	WARN	A warning event.  This event should be displayed to
  1.2702 +		the user.  It occurs when an error condition has
  1.2703 +		happened, but c-client knows what to do to recover.
  1.2704 +		Examples: "Can't open read-write, so opening
  1.2705 +		read-only", "Empty mailbox", "Login failed, try
  1.2706 +		again", "Waiting for mailbox to become unlocked",
  1.2707 +		"IMAP protocol error".  Although a user should be
  1.2708 +		told about a warning, it's generally not necessary
  1.2709 +		to interrupt the flow of her work (e.g. it's alright
  1.2710 +		to display the warning in a scrolling window, but
  1.2711 +		not necessary to require the user to do anything).
  1.2712 +
  1.2713 +	ERROR	An error event.  This event should be displayed to
  1.2714 +		the user, or at least logged someplace.  This is a
  1.2715 +		serious error condition occured that aborted the
  1.2716 +		requested operation and possibly also aborted the mail
  1.2717 +		stream.  This ranges from normal error conditions such
  1.2718 +		as "Can't open mailbox", "too many login failures, go
  1.2719 +		away" to bizarre conditions such as "Apparent new mail
  1.2720 +		appeared in the mailbox that doesn't look like mail,
  1.2721 +		program aborting".  Errors must be called to the
  1.2722 +		user's attention, and probably should require some
  1.2723 +		sort of acknowledgement (e.g. answering a modal panel)
  1.2724 +		before the application proceeds.
  1.2725 +
  1.2726 +
  1.2727 +void mm_dlog (char *string);
  1.2728 +	string message string
  1.2729 +
  1.2730 +      This function is called to deliver a debugging telemetry
  1.2731 +message.  No newline is included in the string, so this function has
  1.2732 +to output its own.  This is called only when debugging is enabled.
  1.2733 +
  1.2734 +
  1.2735 +void mm_login (NETMBX *mb,char *user,char *pwd,long trial);
  1.2736 +	mb	parsed mailbox specification
  1.2737 +	user	pointer to where to return user name
  1.2738 +	pwd	pointer to where to return password
  1.2739 +	trial	number of prior login attempts
  1.2740 +
  1.2741 +      This function is called to get a user name and password for the
  1.2742 +given network mailbox.  It stores the user name and password in the
  1.2743 +strings pointed to by the appropriate arguments.  The trial argument
  1.2744 +is the number of attempts to perform the login and is initially zero
  1.2745 +(e.g. for a default username and password login functionality).  It is
  1.2746 +incremented for each subsequent trial until the maximum number of
  1.2747 +trials are made.
  1.2748 +
  1.2749 +
  1.2750 +void mm_critical (MAILSTREAM *stream);
  1.2751 +	stream	stream where event happened
  1.2752 +
  1.2753 +      This function is called to alert the application that c-client
  1.2754 +is about to run some critical code on that stream that may result in a
  1.2755 +clobbered mail file if it is interrupted.  It may be desirable to
  1.2756 +disable CTRL/C, etc. during this time.
  1.2757 +
  1.2758 +
  1.2759 +void mm_nocritical (MAILSTREAM *stream);
  1.2760 +	stream	stream where event happened
  1.2761 +
  1.2762 +      This function is called to alert the application that c-client
  1.2763 +is no longer running critical code on that stream that may result in a
  1.2764 +clobbered mail file if it is interrupted.
  1.2765 +
  1.2766 +
  1.2767 +long mm_diskerror (MAILSTREAM *stream,long errcode,long serious);
  1.2768 +	stream	stream where event happened
  1.2769 +	errcode	OS error code for disk error
  1.2770 +	serious	non-zero if c-client can not undo the operation (and
  1.2771 +		 thus must retry to avoid mail file damage)
  1.2772 +
  1.2773 +      This function is called to alert the application that the
  1.2774 +c-client has encountered an unrecoverable write error when trying to
  1.2775 +update the mail file.  errcode contains the system error code.  If
  1.2776 +serious is non-zero, then it is probable that the disk copy of the
  1.2777 +mailbox has been damaged.
  1.2778 +
  1.2779 +     The return value from this function is the abort flag; if serious
  1.2780 +is zero and the abort flag is non-zero, the operation is aborted.  If
  1.2781 +the abort flag is zero or if serious was non-zero, a return from this
  1.2782 +function will retry the failing operation.
  1.2783 +
  1.2784 +
  1.2785 +void mm_fatal (char *string);
  1.2786 +	string	message string
  1.2787 +
  1.2788 +      This function is called from the fatal() routine in the
  1.2789 +operating system code to notify the main program that it is about to
  1.2790 +crash.  The string contains a reason.  At the very minimum, the main
  1.2791 +program should do something like
  1.2792 + mm_log (string,ERROR);
  1.2793 +and then return.  No newline is included in the string, so this
  1.2794 +function has to output its own.
  1.2795 +
  1.2796 +			     Driver interface
  1.2797 +
  1.2798 +     When writing a new driver for the c-client, you must provide a
  1.2799 +DRIVER stucture giving a dispatch vector between MAIL and the driver.
  1.2800 +The DRIVER dispatch vector is described in mail.h.
  1.2801 +
  1.2802 +char *name;
  1.2803 +     Name by which the driver is known to c-client.
  1.2804 +
  1.2805 +unsigned long flags;
  1.2806 +     Attribute flags for this driver:
  1.2807 +	DR_DISABLE	This driver is currently disabled.
  1.2808 +	DR_LOCAL	This driver deals with local mailboxes; if
  1.2809 +			 this is off it deals with mailboxes over a
  1.2810 +			 network.
  1.2811 +	DR_MAIL		This driver supports e-mail messages.
  1.2812 +	DR_NEWS		This driver supports netnews messages
  1.2813 +	DR_READONLY	This driver only allows read-only access;
  1.2814 +			 mail_setflag(), mail_expunge(), etc. are
  1.2815 +			 no-ops.
  1.2816 +	DR_NOFAST	This driver does not implement mail_fetchfast()
  1.2817 +			 in a fast way (e.g. it may have to fetch the
  1.2818 +			 entire message text over a network to
  1.2819 +			 calculate sizes).
  1.2820 +	DR_NAMESPACE	This driver accepts and uses namespace format
  1.2821 +			 names.
  1.2822 +	DR_LOWMEM	This driver is designed for systems with very
  1.2823 +			 limited amounts of memory (e.g. DOS) and
  1.2824 +			 support routines called by this driver should
  1.2825 +			 try not to use much memory.
  1.2826 +
  1.2827 +DRIVER *next;
  1.2828 +     Pointer to the next driver which this application supports (or NIL if
  1.2829 +this is the last driver).  Drivers are lunk together via the mail_link()
  1.2830 +function.
  1.2831 +
  1.2832 +DRIVER *driver_valid (char *mailbox);
  1.2833 +     This function returns a pointer to the driver's DRIVER dispatch
  1.2834 +vector iff this driver accepts the given name as a valid mailbox for this
  1.2835 +driver.  Otherwise, it returns the value of the next driver's
  1.2836 +driver_valid() or NIL if there is no next driver.  In other words, calling
  1.2837 +driver_valid() for the first driver will return the driver dispatch vector
  1.2838 +for the driver which supports this type of mailbox.
  1.2839 +
  1.2840 +void *driver_parameters (long function,void *value);
  1.2841 +     This function implements mail_parameters() for this driver.
  1.2842 +
  1.2843 +void driver_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents);
  1.2844 +     This function implements mail_scan() for this driver.
  1.2845 +
  1.2846 +void driver_list (MAILSTREAM *stream,char *ref,char *pat);
  1.2847 +     This function implements mail_list() for this driver.
  1.2848 +
  1.2849 +void driver_lsub (MAILSTREAM *stream,char *ref,char *pat);
  1.2850 +     This function implements mail_lsub() for this driver.
  1.2851 +
  1.2852 +long driver_subscribe (MAILSTREAM *stream,char *mailbox);
  1.2853 +     This function implements mail_subscribe() for this driver.
  1.2854 +
  1.2855 +long driver_unsubscribe (MAILSTREAM *stream,char *mailbox);
  1.2856 +     This function implements mail_unsubscribe() for this driver.
  1.2857 +
  1.2858 +long driver_create (MAILSTREAM *stream,char *mailbox);
  1.2859 +     This function implements mail_create() for this driver.
  1.2860 +
  1.2861 +long driver_delete (MAILSTREAM *stream,char *mailbox);
  1.2862 +     This function implements mail_delete() for this driver.
  1.2863 +
  1.2864 +long driver_rename (MAILSTREAM *stream,char *old,char *new);
  1.2865 +     This function implements mail_rename() for this driver.
  1.2866 +
  1.2867 +long driver_status (MAILSTREAM *stream,char *mailbox,long flags);
  1.2868 +     This function implements mail_status() for this driver.
  1.2869 +
  1.2870 +MAILSTREAM *driver_open (MAILSTREAM *stream);
  1.2871 +     This function opens the mailbox identified by the given stream.  It
  1.2872 +may use the data on the stream and create additional data on stream->local
  1.2873 +as necessary.  It should return the given stream unless it failed to open
  1.2874 +the mailbox, in which case it should return NIL.
  1.2875 +
  1.2876 +void driver_close (MAILSTREAM *stream,long options);
  1.2877 +     This function implements mail_close() for this driver.
  1.2878 +
  1.2879 +void driver_fetchfast (MAILSTREAM *stream,char *sequence,long flags);
  1.2880 +     This function implements mail_fetchfast() for this driver.
  1.2881 +
  1.2882 +void driver_fetchflags (MAILSTREAM *stream,char *sequence,long flags);
  1.2883 +     This function implements mail_fetchflags() for this driver.
  1.2884 +
  1.2885 +ENVELOPE *driver_fetchstructure (MAILSTREAM *stream,unsigned long msgno,
  1.2886 +				 BODY **body,long flags);
  1.2887 +     This function implements mail_fetchstructure() for this driver.
  1.2888 +
  1.2889 +char *driver_fetchheader (MAILSTREAM *stream,unsigned long msgno,
  1.2890 +			  STRINGLIST *lines,unsigned long *len,long flags);
  1.2891 +     This function implements mail_fetchheader() for this driver.
  1.2892 +
  1.2893 +char *driver_fetchtext (MAILSTREAM *stream,unsigned long msgno,
  1.2894 +			unsigned long *len,long flags);
  1.2895 +     This function implements mail_fetchtext() for this driver.
  1.2896 +
  1.2897 +char *driver_fetchbody (MAILSTREAM *stream,unsigned long msgno,char *section,
  1.2898 +			unsigned long *len,long flags);
  1.2899 +     This function implements mail_fetchbody() for this driver.
  1.2900 +
  1.2901 +void driver_setflag (MAILSTREAM *stream,char *sequence,char *flag,long flags);
  1.2902 +     This function implements mail_setflag() for this driver.
  1.2903 +
  1.2904 +void driver_clearflag (MAILSTREAM *stream,char *sequence,char *flag,
  1.2905 +		       long flags);
  1.2906 +     This function implements mail_clearflag() for this driver.
  1.2907 +
  1.2908 +void driver_search (MAILSTREAM *stream,char *charset,SEARCHPGM *pgm,
  1.2909 +		    long flags);
  1.2910 +     This function implements mail_search() for this driver.
  1.2911 +
  1.2912 +unsigned long *driver_sort (MAILSTREAM *stream,char *charset,SEARCHPGM *spg,
  1.2913 +			    SORTPGM *pgm,long flags);
  1.2914 +     This function implements mail_sort() for this driver.
  1.2915 +
  1.2916 +void *driver_thread (MAILSTREAM *stream,char *seq,long function,long flag);
  1.2917 +     This dispatch is reserved for a future threading capability.
  1.2918 +
  1.2919 +long driver_ping (MAILSTREAM *stream);
  1.2920 +      This function implements mail_ping() for this driver.
  1.2921 +
  1.2922 +void driver_check (MAILSTREAM *stream);
  1.2923 +      This function implements mail_check() for this driver.
  1.2924 +
  1.2925 +void driver_expunge (MAILSTREAM *stream);
  1.2926 +      This function implements mail_expunge() for this driver.
  1.2927 +
  1.2928 +long driver_copy (MAILSTREAM *stream,char *sequence,char *mailbox,
  1.2929 +		  long options);
  1.2930 +      This function implements mail_copy() for this driver.
  1.2931 +
  1.2932 +long driver_append (MAILSTREAM *stream,char *mailbox,char *flags,char *date,
  1.2933 +		    STRING *message);
  1.2934 +      This function implements mail_append() for this driver.
  1.2935 +
  1.2936 +void driver_gc (MAILSTREAM *stream,long gcflags);
  1.2937 +      This function implements mail_gc() for this driver.
  1.2938 +
  1.2939 +			 Driver Support Functions
  1.2940 +
  1.2941 +void mail_searched (MAILSTREAM *stream,unsigned long msgno);
  1.2942 +	stream	stream where event happened
  1.2943 +	msgno	message number
  1.2944 +
  1.2945 +     This function is called by the driver to notify c-client that this
  1.2946 +message number matches a search.  It invokes the main program's
  1.2947 +mm_searched() function.
  1.2948 +
  1.2949 +void mail_exists (MAILSTREAM *stream,unsigned long nmsgs);
  1.2950 +	stream	stream where event happened
  1.2951 +	nmsgs	number of messages
  1.2952 +
  1.2953 +     This function is called by the driver to notify c-client that this
  1.2954 +message number exists (i.e. there are this many messages in the mailbox).
  1.2955 +It invokes the main program's mm_exists() function.
  1.2956 +
  1.2957 +void mail_recent (MAILSTREAM *stream,unsigned long recent);
  1.2958 +	stream	stream where event happened
  1.2959 +	recent	number of messages
  1.2960 +
  1.2961 +      This function is called by the driver to notify c-client that this
  1.2962 +many messages are "recent" (i.e. arrived in the mailbox since the previous
  1.2963 +time the mailbox was opened).
  1.2964 +
  1.2965 +void mail_expunged (MAILSTREAM *stream,unsigned long msgno);
  1.2966 +	stream	stream where event happened
  1.2967 +	msgno	number of messages
  1.2968 +
  1.2969 +      This function is called by the driver to notify MAIL that this
  1.2970 +message number has been expunged from the mail file and that all subsequent
  1.2971 +messages are now referenced by a message number one less than before.  It
  1.2972 +invokes the main program's mm_expunged() function.
  1.2973 +
  1.2974 +void mail_lock (MAILSTREAM *stream);
  1.2975 +	stream	stream where event happened
  1.2976 +      This function sets the stream lock.  It is an error to set the stream
  1.2977 +lock if the stream is already locked.
  1.2978 +
  1.2979 +      This is mainly used to catch errors due to a callback function
  1.2980 +(e.g. mm_exists) inadvertantly recursing back to the MAIL routines and
  1.2981 +establishing an infinite recursion.  Normally, drivers will set the lock
  1.2982 +prior to calling one of the callback functions above or, more likely, in
  1.2983 +the beginning of the driver's non-reentrant "do operation" section.  In the
  1.2984 +IMAP4 driver, the stream lock is set when entering imap_send() and cleared
  1.2985 +on exit.
  1.2986 +
  1.2987 +void mail_unlock (MAILSTREAM *stream);
  1.2988 +	stream	stream where event happened
  1.2989 +
  1.2990 +     This function releases the stream lock.  It is an error to release the
  1.2991 +stream lock if the stream is not locked.

UW-IMAP'd extensions by yuuji