Subject: Proposal for c-client API for IMSP

From: Chris Newman <[email-masked]>
Date: Fri, 10 Dec 1993 16:07:41 -0500 (EST)

Here is my current outline for a c-client API for
IMSP/options/address-books.  It's designed around the concept of a
"SUPPORTSTREAM" which is conceptually equivalent to an IMSP
connection.  It allows for multiple separate option and address book
drivers in an implementation along the lines of c-client's multiple
mailbox drivers -- thus allowing for both remote and local storage of
options and address books.  I've got the basic framework implemented
am and working on the IMSP drivers.

The option support is based on a the simple key string/value string
option functionality provided by IMSP.

The address book support is based on IMSP's relatively general address
book.  The model is that each address book is a set of keys (names)
and each key (name) has a set of field-data pairs.  This allows users
to put phone numbers, snail-mail addresses, etc. into their address
books.  Distribution-lists are just another address book entry with
multiple values in the email field.

I'd appreciate it if client implementors would let me know if this
should suffice for address book/option support.

		- Chris Newman

------------------------
*DRAFT*DRAFT*DRAFT*DRAFT*DRAFT*DRAFT*DRAFT*DRAFT*DRAFT*DRAFT*DRAFT*DRAFT*

			   IMSP client API
			   ---------------

			   by Chris Newman
			    draft 12/10/93

1.0 Status of this document
---------------------------
This is a draft of this document, and is subject to change.

1.1 Introduction
----------------
Interactive Mail Support Protocol (IMSP) provides support services for
a set of IMAP servers.  Some of these services such as options and
address books are disjoint from IMAP services.  Other services such
as the FIND and SUBSCRIBE services are designed to replace similar,
but more limited services in IMAP.  Because of the latter type of
service, it is desirable to have the IMSP client API well integrated
with the current c-client IMAP library, preferably in such a way that
a new combined c-client/IMSP library can be linked against an existing
c-client Mail User Agent (MUA) and automatically take advantage of
IMSP's expanded service.

When possible, this API will use c-client functionality.  For example,
IMSP error messages will be displayed using the mm_log callback, and
login credentials will be obtained via the mm_login callback.

2.0 Datatypes
-------------
1) A "support stream" structure.  It needs to specify address book
   drivers, option drivers, a list of open address books, a cached
   mailbox list and a list of c-client MAILSTREAMs.  A replacement for
   the c-client mail_open() will be needed which takes a support
   stream instead of a MAILSTREAM to recycle.  This type will be
   referred to as "SUPPORTSTREAM".

2) A key-value pair array which is useful for specifying a list of
   field-data pairs for an address book entry.  This structure is made
   up of two string pointers as follows:

   typedef struct keyvalue {
       char *key, *value;
   } keyvalue;

3) An "address book" access descriptor.  This type may refer to either
   a local file or an IMSP server and IMSP address book name pair.
   This will be referred to as type "abook".

4) An "address book driver" that contains calls to manage all the
   address book functions listed below.  This will be referred to as
   type "abookdriver".

5) An "options driver" that contains calls to manage all the option
   functions listed below.  This will be referred to as type
   "optiondriver".

3.0 IMSP/SUPPORTSTREAM connection control
-----------------------------------------
SUPPORTSTREAM *support_new(void)

This returns a pointer to a new support stream.

void support_done(SUPPORTSTREAM *s);

This closes the support stream and releases all memory or other
resources associated with it.  This will close any associated address
book pointers or and possibly MAILSTREAMS.

void support_add_adriver(SUPPORTSTREAM *s, abookdriver *d);

This adds the specified address book driver to the SUPPORTSTREAM.
Returns error status.

void support_add_odriver(SUPPORTSTREAM *s, optiondriver *d);

This adds the specified option driver to the SUPPORTSTREAM. Returns
error status.

int imsp_open(SUPPORTSTREAM *s, char *hostname);

This attempts to open an IMSP connection to the specified hostname.
If a connection is successfully opened, then the IMSP address book and
option drivers will automatically be added as the first SUPPORTSTREAM
drivers.  This will use c-client's mm_login() callback to get the
username and password as needed.  Returns error status.

4.0 MAILSTREAM support
----------------------
MAILSTREAM *mailbox_open(SUPPORTSTREAM *s, char *name, char *options);

This should be used instead of mail_open() in c-client.  It will open
the specified mailbox using the SUPPORTSTREAM/IMSP as appropriate.
This will also set the driver for the MAILSTREAM such that
find/create/rename/delete and other routines superceeded by IMSP are
handled properly.

void mailbox_close(MAILSTREAM *m);

This will close and "free" the MAILSTREAM m.  The library may keep m
open and recycle it on future mailbox_open() calls.

5.0 Options
-----------
void mm_option(SUPPORTSTREAM *s, char *option, char *value, int
	read_write_flag);

This is the callback used whenever a "* OPTION" from the server is
processed, or an option is read from a local option file.  The option
and value parameters will point to strings representing the option
name and its value respectively.  The read_write_flag will be non-zero
if the option may be modified by the client.

int option_get(SUPPORTSTREAM *s, char *pattern);

This will call mm_option for all the options matching the specified
pattern (using wildcards as in the IMSP specification).  Returns error
status.

int option_lock(SUPPORTSTREAM *s, char *option);

This will lock the specified option, and may call mm_option to update
its value.  Returns error status.

void option_unlock(SUPPORTSTREAM *s, char *option);

This will unlock the specified option.

int option_set(SUPPORTSTREAM *s, char *option, char *value);

This will set the value for the specified option.  This may also call
mm_option with the new value.  Returns error status.

5.1 Discussion of Options
-------------------------
The user interface is expected to call option_lock() on read-write
options before displaying them in a context where the user may modify
them.  If a lock fails on an option with "already locked" status the
user should be asked if they want to "break the lock" before a call to
option_set().  option_lock() is an advisory lock and will not be
enforced by the API.  Since options are per-user, an "already locked"
error indicates the user has another active client showing options in
a modifiable context.

6.0 Address books
-----------------
void mm_addressbook(SUPPORTSTREAM *s, char *abook_name);

This callback is passed the name of a valid address book.

void mm_address(abook ab, char *name, fielddata *fdata, int count);

This callback is passed the name of an entry in the specified address
book, and a list of field/data pairs.  The fdata & count arguments are
0 except in response to an explicit fetch command.  If fdata is
non-zero, mm_address is expected to make sure it is freed.

int abook_find(SUPPORTSTREAM *s, char *pattern);

This calls mm_addressbook for each address book on the specified
connection that matches the pattern and is readable by the current
user.  Returns error status.

abook *abook_open(SUPPORTSTREAM *s, char *abook_name);

This "opens" the specified address book, returning an abook structure
to access its contents.  For IMSP, this will not generate any protocol
requests.  If abook_name is NULL, the default address book (specified
by the IMSP login name of the current user for the IMSP driver) will
be used.  Returns NULL on failure.

void abook_close(abook *ab);

This "closes" the specified address book and releases any resources it
uses.

int abook_getlist(abook *ab);

This calls mm_address() for each address in the specified address
book.  Returns error status.

int abook_search(abook *ab, char *pattern, keyvalue *criteria,
	long number_of_criteria);

This calls mm_address() for each address in the specified address book
that matches the pattern and criteria.  The criteria is specified as
defined in the IMSP specification, and may be NULL if
number_of_criteria is 0.  Returns error status.

int abook_fetch(abook *ab, char *name);

This calls mm_address() for with the field data pairs for the
specified address book entry.  Returns error status.

int abook_lock(abook *ab, char *name);

This places an advisory lock on the specified address book entry.
Returns error status.

void abook_unlock(abook *ab, char *name);

This removes an advisory lock from the specified entry.

int abook_store(abook *ab, char *name, keyvalue *field_data,
	long number_of_field_data_pairs);

This stores the field_data in the specified address book entry.
number_of_field_data_pairs must be at least 1.  Returns error status.

int abook_delete(abook *ab, char *name);

This deletes the specified address book entry.  Returns error status.

char *abook_expand(abook *ab, char *name);

This will return a CRLF separated list of email addresses for the
specified address book entry.  It will return NULL on failure.  Note
that an address book entry need not have any email field.  Clients
must not use the email field returned by abook_fetch() -- they must
call this function.  This function may "open" other address books to
expand address references via the "members" field of the address book.

6.1 Address book access control
-------------------------------

void mm_abookacl(abook *ab, char *identifier, char *rights);

Callback used to specify access rights.  The "identifier" parameter
will be NULL if this is the result of a "MYACL".

int abook_getacl(abook *ab, int myrights);

If myrights is 1, this will call mm_abookacl with the rights for the
current user, otherwise it will call mm_abookacl for each entry in the
access control list.  Returns error status.

int abook_setacl(abook *ab, char *identifier, char *rights);

This sets the access control rights for "identifier" to "rights".  May
call mm_abookacl() with the actual rights set.  Returns error status.

6.2 Discussion of Address books
-------------------------------
A utility function to convert ACL rights strings to/from bit-vectors
will be provided.

The user interface is expected to call abook_lock() before displaying
the contents of an address book entry is a context where the user may
modify it.

---

From: Steve Hole <[email-masked]>
Date: Mon, 24 Jan 1994 13:09:37 -0700

On Fri, 21 Jan 1994 08:13:33 -0700 Chris Newman wrote:

> From: Chris Newman
> Date: Fri, 21 Jan 1994 08:13:33 -0700
> Subject: Re: Re:Proposal for c-client API for IMSP
> To: Adam Treister <[email-masked]>
> Cc: [email-masked]
> 

> > No argument these are the most important cases, but there are other
> > lists that mailstrom uses, that in theory should be shared across
> > clients.  eg: (Preferred-Fonts (Browser (Geneva 10 Bold))
> > (ReadWindow (Courier 12 Plain)) (Telemetry (Monaco 9 plain))).  Yes,
> > I can parse these lists myself, but the most effective way to get
> > these things to be cross client is to build it into c-client.
> 
> We definitely need to work out some system for registry of generic
> options and the prefixes used for client-specific options.

I'll buy that.   We are developing a hierarchical option model here
that will be used in the ECSMail version 3.0.   Some of these would
be useful in the generic sense I'm sure.   I would be happy to 
contribute this information as part of the startup.

Cheers.

--
Steve Hole  		        ECS Technical Manager
ISA Corporation			mail:  [email-masked]
Suite 835, 10040 - 104 St.      phone: (403) 420-8081
Edmonton, Alberta, Canada       fax:   (403) 420-8037
T5J 0Z2