Steltor Calendar API (CAPI)

Version 2.0


Contents of this file

Overview
Implementation Considerations
Function Summary
Examples
Appendices
    CAPI Status Codes

CAPI Overview

CAPI is the Steltor Application Programmers' Interface. CAPI provides basic calendaring functionality through a collection of C function calls.

Implementation Considerations

Character Sets

This implementation of CAPI only supports UTF-8. Strings passed to CAPI_Logon and CAPI_GetHandle must be in UTF-8. All output data is in UTF-8. Input must be in UTF-8; this means that MIME entities which specify a character set must specify UTF-8 or US-ASCII (MIME defaults to US-ASCII if no character set is specified).

iCalendar Support

iCalendar information saved via CAPI can be retrieved later. However, not all iCalendar data is actively supported by this revision of CAPI.  In particular, VTODO, VFREEBUSY and VJOURNAL components are not supported.

iCalendar input

Some data is mapped to native data structures. Data for these properties will not always be completely preserved. The following are affected:

Other iCalendar data will be preserved and returned unchanged.

iCalendar output

When data created with native Steltor clients is output, the following is a list of available properties, and how they are obtained. Other properties stored with CAPI are also available.

Instances of an event are all returned in separate VEVENT objects.

Security Model

There are two parts to the security model: storing and fetching events. These are handled by different security paradigms.

The owner of an event can add or delete any property of that event. When an "ATTENDEE" property is created for a user which is also on the server, and a handle has been supplied for that user, the property is created with default values for its parameters. The owner of the event cannot modify the parameters of that property, only the user to whom it corresponds can do that.

When a user is updating their "ATTENDEE" property no error will be returned if there is an attempt to modify other event data, but the modifications will not occur.

It is possible for a user to refuse invitations from another user. In that case an "ATTENDEE" property will not be created for that user and it will be indicated that the invitation was refused. This may also occur when attempting to double book resources.

When fetching events the security model is based on the iCalendar classification of the event. Users grant other users different access levels to different classes of events. The three access levels are: no read access, read the start and end times of the event only, and read all details of the event. From the point of view of CAPI this results in some events for which only the "DTSTART", "DURATION" and "DTEND" properties will be released. All other events will be invisible or all of their properties will be released.

This CAPI implementation does not provide functionality extensions for modifying security records which govern this behaviour.

Alarms

Alarms are considered private to each user, so users cannot read or write alarms for each other. Since users cannot read each others alarms it is not possible for users to do fetches by alarm range on each other's calendars. Any user may set an alarm for an event which they are attending, so events can have many alarms for different attendees.

Alarms will be returned by a fetch by id on the current user's agenda, and in fetches by alarm range. The alarm always applies to the logged in user.

Event Recurrences

All event recurrences are expanded into separate recurrence dates. This affects events which are stored with "RRULE" properties. Once an event is stored any "RRULE" and "EXRULE" properties will be lost.

Format of returned iCal

When fetching events iCal data is returned with a separate "VEVENT" component for each instance of a recurring event. This may result in a lot of unnecessary data for events with many instances. This behaviour may change in the future.

User identification

CAPI identifies users by a userid, but allows additional information to be provided. Depending on the server configuration additional information may be required. The same string format is provided at logon and when obtaining a handle, however not all options will be available at both times.

Logging into the server as a resource is not supported.

There are three things that can be specified in this additional data. Firstly, users can be identified using the native field-value pair specification. Secondly, on logon, if several nodes are present and the default one is not the desired one, it is possible to specify the correct node. Thirdly, on logon, an initialization file other than the default may be used. This final option is unnecessary now, but is provided for future use.

All options are specified using field-value pairs. The entire string is a collection of such pairs. The userid is separated from the extended data by an ASCII '?' character. The character immediately following this one is the delimiter of each subsequent field value pair. The delimiter may be anything except a digit, a letter, NUL, '*' or '='. The rest of the string consists of field-value pairs separated by the chosen delimiter. The string is terminated by a delimiter followed by a NUL character. Field value pairs consist of a field name, followed by an '=', followed by the value. The value is a string which does not contain the delimiter character, the NUL character, and for user identification strings, the SOLIDUS character.

For example, the field name G denotes the given name, and S denotes the surname. The following is a sample legal string for identifying a user. In this case the '?' separating the userid from the extended string is included. Note that the string is NUL terminated.

      "?^S=Bunny^G=Bugs^"

Any field used for identifying a user may be terminated with a '*', which will match any string. This is not available for specifying nodes or initialization files. In this way it is possible to identify multiple users simultaneously. The following will also match the above user:

      "?^S=Bu*^G=Bugs^I=*^"

Resources have a different name structure; they are identified with the single field RS which indicates resource name.

The following (almost) ABNF [RFC2234] describes legal logon strings:

      logon-string = userid "?" ext-string %x00

             ; Nul-terminated logon string


      userid = *( ALPHA / DIGIT / "-")

             ; something like this


      ; ext-string is non-userid information.  It cannot
      ; contain any nul characters.

The description below diverges from ABNF in that values in double quotes are case-sensitive, ie. field names must be in uppercase. Also, the delimiter character must be the same in all cases in a single string.

      ext-string = DELIMITER fields 


      fields = logon-fields search-fields


      logon-fields = [node] [company domain] [ini-file schedule]

             ; These may only be used at logon.
             ; ini-file and schedule must always appear together


      node = "ND=" node-number DELIMITER

             ; Identifies the node on which the required user's agenda resides
             ; Value of "0" or absence indicates default or master node.
      company domain = "CD=" domain-name DELIMITER
             ; Identifies the domain on which the required user's agenda resides
             ; Use with Lexacom Enterprise Calendar Server only. Node and company 
             ; domain are mutually exclusive.
      node-number = 1*DIGIT

             ; Decimal representation of the node


      ini-file = "IN=" filename DELIMITER

             ; see notes below


      filename = *FILENAME-CHAR

             ; a valid filename on the local system


      schedule = "SC=" schedule-name DELIMITER

             ; see notes below


      schedule-name = *(ALPHA / DIGIT / SPACE)

             ; a schedule in the ini-file


      search-fields = [surname] [given-name] [initials] [generation] 
                      [org-unit1] [org-unit2] [org-unit3] [org-unit4] 
                      [organization] [country] [admin] [private]
                      [resource-name]

             ; These fields identify the user to the server


      surname = "S=" 1*VALUE-CHAR ["*"] DELIMITER

             ;  Specifies the user's surname


      given-name = "G=" 1*VALUE-CHAR ["*"] DELIMITER

             ;  Specifies the user's given-name


      initials = "I=" 1*VALUE-CHAR ["*"] DELIMITER

             ;  Specifies the user's initials


      generation = "X=" 1*VALUE-CHAR ["*"] DELIMITER

             ;  Specifies the user's generation


      org-unit1 = "OU1=" 1*VALUE-CHAR ["*"] DELIMITER

             ;  Specifies the user's first organizational unit


      org-unit2 = "OU2=" 1*VALUE-CHAR ["*"] DELIMITER

             ;  Specifies the user's second organizational unit


      org-unit3 = "OU3=" 1*VALUE-CHAR ["*"] DELIMITER

             ;  Specifies the user's third organizational unit


      org-unit4 = "OU4=" 1*VALUE-CHAR ["*"] DELIMITER

             ;  Specifies the user's fourth organizational unit


      organization = "O=" 1*VALUE-CHAR ["*"] DELIMITER

             ;  Specifies the user's organization


      country = "C=" 1*VALUE-CHAR ["*"] DELIMITER

             ;  Specifies the user's country


      admin = "A=" 1*VALUE-CHAR ["*"] DELIMITER

             ;  Specifies the user's administration domain


      private = "P=" 1*VALUE-CHAR ["*"] DELIMITER

             ;  Specifies the user's private domain


      resource-name = "RS=" 1*VALUE-CHAR ["*"] DELIMITER

             ;  Specifies the resource's name


      DELIMITER = %x01-29 / %x2B-2F / %x3A-3C / %x3E-40 / %5B-60 / %7B-7F

             ; Everything except NUL, "*", DIGIT, "=", ALPHA


      FILENAME-CHAR = %x2F / VALUE-CHAR

             ; VALUE-CHAR or "/"  (Unless this is the delimiter)


      VALUE-CHAR = %x01-29 / %x2B-2E / %x30-7F

             ; Everything except NUL, "*", "/"
             ; Also, must not include the chosen delimiter

Data Streams

The data stream that an application supplies to CAPI and receives from CAPI is MIME encapsulated iCalendar objects. A single request may fetch data from a list of calendars. A reply to such a request will consist of a separate iCalendar object for each calendar in the list. That is, a request for events from calendarA and calendarB results in an iCalendar stream of this form:

Content-type: text/calendar
Content-Transfer-Encoding: 7bit

BEGIN:VCALENDAR
... events from calendarA
END:VCALENDAR

Content-type: text/calendar
Content-Transfer-Encoding: 7bit

BEGIN:VCALENDAR
... events from calendarB
END:VCALENDAR

The order of the iCalendar objects corresponds to the order of the calendars in the request list. If a request results in an empty solution set, the return stream will be an empty iCalendar object. If there is any sort of error with a calendar the iCalendar reply object corresponding to that calendar will be empty.

For example, in the example above if calendarB was deleted by someone else just prior to an attempt to fetch data, the resulting stream would have the following form:

Content-type: text/calendar
Content-Transfer-Encoding: 7bit

BEGIN:VCALENDAR
... events from calendarA
END:VCALENDAR

Content-type: text/calendar
Content-Transfer-Encoding: 7bit

BEGIN:VCALENDAR
END:VCALENDAR

On a successful fetch the "VCALENDAR" will contain many "VEVENT" components, each containing the requested properties, if available. iCalendar allows these different components to contain information about different instances of the same event. The returned data may use any of the following methods to give instance specific information:

Please note that the "DTSTART" property returned indicates the start time of the first instance identified in the "VEVENT" component in which it resides and not the start time of the first instance of the event in the Calendar Store. Furthermore the number of "VEVENT" components returned in the calendar has no relation to the number of instances of the event. Consequently, when fetching events, if the recurrence identifying properties are not requested, there will be no way to determine how many instances exist, and to which instances each returned property applies.

When storing, data supplied to CAPI must consist of a single "VCALENDAR" component inside a single MIME part. The calendar may contain many "VEVENTS", but these must all be information about a single event. For example, this is a valid input:

Content-type: text/calendar
Content-Transfer-Encoding: 7bit

BEGIN:VCALENDAR
BEGIN:VEVENT
event properties
END:VEVENT
BEGIN:VEVENT
event properties
END:VEVENT
END:VCALENDAR

Access Control

Access to data through CAPI is controlled by the calendar server. It is based on the requester and the data / operation being requested. CAPI provides an interface to request reading any combination of properties. Properties that the requesting user is not authorized to read will not be returned in the iCalendar data stream response and an appropriate access violation will be returned as the function call status. A subtle difference occurs when the requested property is available as far as access control, but does not exist in the components of the solution set. As an example, if the VEVENT.GEO property is requested, and it exists, but the requester does not have permission to read it, the resulting iCalendar data stream will not contain the VEVENT.GEO property in the data stream and an access violation will be returned. If the requester has permission to read the VEVENT.GEO property, but the components do not have a GEO property value, the data stream will not contain the VEVENT.GEO property but no error will be returned.

The key point is that a fetch operation will not fail due to property access restriction.  That is, if the requester has permission to read some but not all requested properties, the operation will complete and result in a solution set containing those properties to which the requester has access.

Users will typically only have access to modify some of the events which they can read. The security paradigm of the server will dictate which events can be modified. There may be multiple access levels for the modification of an event. If the user is the owner of the event they will typically have full privileges to modify the event, and if they are invited to the event they may have restricted privileges to modify information relating to their attendance, such as acceptance and alarms.

CAPI will silently ignore attempts to modify restricted properties in reduced access modes. This simplifies the implementation of modification in these cases.

Errors may occur for specific agendas when attempting to modify events or when creating events. These errors will be returned using a supplied array of status values, allowing the rest of the operation to proceed.

Limitations in this implementation

Servers without full support

This CAPI implementation can only provide a limited operation with servers that are identified as "pre-4.0".

Unsupported iCalendar properties

The following describes all properties that are recognized by pre-4.0 servers and the details of their use.


Function Summary

Session

Capabilities

Identify the capabilities of a Calendar
CAPI_GetCapabilities

Logoff Terminate a session with a calendar. 
CAPI_Logoff
Logon Establish a session with a calendar but do not authenticate
CAPI_Connect

Establish a session with a calendar and identify user. 
CAPI_Logon

Identities Assume the identity of another calendar user
CAPI_SetIdentity

Calendar Management  

 nothing at this time

iCalendar Component Management 

Fetch Get components that match the specified criteria: datetime range, uid or reminders set to go off in a datetime range. 
CAPI_FetchEventsByRange
CAPI_FetchEventByID
CAPI_FetchEventsByAlarmRange
Delete Delete calendar entries. 
CAPI_DeleteEvent
Store Create or update a set of component attributes. 
CAPI_StoreEvent
Identify a 
Calendar Store
Identify a user and get a handle to their calendar. 
CAPI_GetHandle
CAPI_DestroyHandles
Reminders Read a set of reminders. 
CAPI_FetchEventsByAlarmRange
Data Streaming Allows sending and receiving arbitrarily large data items in easily managed chunks 
CAPI_CreateCallbackStream
CAPI_CreateFileStream
CAPI_CreateMemoryStream
CAPI_DestroyStreams

Error handling

Functions dealing with error status Breaks down an error status into its constituent bit fields
CAPI_GetStatusLevels

Returns a text description for a given error code
CAPI_GetStatusString

Accessories

UID Retrieve the UIDs of components that have just been stored
CAPI_GetLastStoredUID
CAPI_GetLastStoredUIDs

Several examples are included to illustrate usage.

Data Types and Defines

CAPICallback
A typedef of a function prototype.  Callbacks used in a CAPIStream must have this prototype. 
CAPIFlag
A numeric value used to modify the behaviour of CAPI functions.
CAPIHandle
An opaque data type used as a handle that points to a calendar. 
CAPISession
An opaque data type, a handle to data containing information generated in response to a successful server login.  It identifies the logged in user to the server.
CAPIStream
An opaque data type, a handle to a stream through which MIME / iCalendar data is passed into and out of CAPI. 
CAPIStatus
A numeric value used to convey the results of an access to the calendar server.  Zero (0) is used to convey success.

Miscellaneous

Identifying an Instance

Depending on the operation, there are several ways to work with recurring Events. To work with the entire recurring series the UID is used by itself (no Recurrence-ID). To identify a particular instance in a recurring series, the UID identifies the series, and the Recurrence-ID identifies the specific instance. A special modifier can be associated with the Recurrence-ID to indicate a subset of instances. That is, the combination of UID, Recurrence-ID, and the modifier THISANDPRIOR identifies the subset consisting of the first instance and all instances up to and including the one specified by Recurrence-ID.  The combination of UID, Recurrence-ID and the modifier THISANDFUTURE identifies the subset consisting of the instance specified by Recurrence-ID and all subsequent instances.

Recurrence-ID is represented as a DateTime value.

#define CAPI_THISINSTANCE 0
#define CAPI_THISANDPRIOR 1
#define CAPI_THISANDFUTURE 2

Detailed Definitions

In the function prototypes below parameters are listed on separate lines and described with a comment. A convention is used in the comments: if the comment begins with "i:" the parameter is an input to the function, if it begins with "o:" the parameter is an output of the function and what the parameter points to may be modified.

Some functions require date values to be passed in as character strings. These values must be supplied in iCalendar date/time format as UTC values, no timezones.

Functions return a value of type CAPIStatus, defined as an unsigned long. The possible values of CAPIStatus are defined in a hierarchy, with more detailed status reports appearing deeper in the hierarchy. For each function the possible return values of CAPIStatus are listed, with the understanding that all values which derive from listed values may also be returned. For instance if the status code CAPI_STAT_SERVICE_FILE is listed, then CAPI_STAT_SERVICE_FILE_OPEN may also be returned.

Some of the functions return an array of status codes as well as the regular status, to identify situations that arose with regard to individual handles. Functions must initialize all cells of this array to CAPI_STAT_OK before performing other processing, to avoid returning misleading data. If a status code other than CAPI_STAT_OK is returned somewhere in the array, the status code returned by the function must not be CAPI_STAT_OK. Equivalently, if the function returns CAPI_STAT_OK then it can be assumed that no unusual situation occurred on any of the supplied handles. In general, if a problem was encountered with some of the handles the returned status will be non-fatal. Furthermore, if a fatal status is returned it cannot be assumed that any attempt was made to use the handles, so the information returned in the array will not have been set. (The initialization of the array should prevent some confusion.)

Some of the functions take arrays of property strings and arrays of handles as parameters. In the event that a NULL value is encountered in one of these lists it will be ignored and the status value returned will not indicate an error. This makes manipulations of these arrays easier for the API user. However, in the case of the handle array the status code returned in the array of CAPIStatus should reflect this fact. Duplicate entries should not appear in either list, if they do it is implementation dependent what occurs, and need not necessarily result in a fatal status.

CAPICallback

typedef int (*CAPICallback)(
    void* pData,                /* i: caller-defined data, the value  */
                                /*    supplied in CAPI_SetStreamCallbacks  */
    char* pBuf,                 /* io: buffer to read or write  */
    size_t iSize,               /* i: the number of characters in pBuf  */
    size_t* piTransferred);     /* o: the number of characters copied  */

Description

This is the prototype of a function that is passed to CAPI_SetStreamCallbacks.

Returns

Callbacks supplying iCalendar data streams (such as CAPI_StoreEvent) must return values as follows:

CAPI_CALLBACK_DONE		done
CAPI_CALLBACK_CONTINUE		call back again
> 0				error numbers

Callbacks receiving iCalendar data streams (such as CAPI_FetchEventsByRange) must return values as follows

CAPI_CALLBACK_CONTINUE		call back again
> 0				error numbers

CAPI signals the end of the data stream with a call to the callback where iSize is 0.


CAPI_Capabilities

This function has been rendered obsolete in CAPI 2.0. Though it is still supported for backward compatibility, it is recommended that you use CAPI_GetCapabilities instead.


CAPI_Connect

CAPI_Status CAPI_Connect(
	const char *  in_host,
	CAPIFlag      in_lFlags,
	CAPISession * out_session)

Description

Establish a connection with a calendar service.  The session obtained in this manner can only be used with CAPI_GetCapabilities or CAPI_Logon.  The session cannot be used to perform any other calendar operations until a user has authenticated using CAPI_Logon.

The format of the host parameter is the same as in the CAPI_Logon function except that no extended parameter can be specified.

Example:

    "calserv.net:4093" is ok
    "calserv.net:4093?^AUTH=sasl^" is incorrect

Cleanup

Use CAPI_Logoff to destroy the session.

Returns

errors


CAPI_CreateCallbackStream

CAPIStatus CAPI_CreateCallbackStream (
    CAPISession s,               /* i: login session handle  */
    CAPIStream* pStream,         /* io: The stream to modify  */
    CAPICallback pfnSndCallback, /* i: Snd iCalendar data    */
    void* userDataSnd,           /* i: a user supplied value */
    CAPICallback pfnRcvCallback, /* i: Rcv iCalendar data  */
    void* userDataRcv,           /* i: a user supplied value */
    CAPIFlag lFlags );           /* i: bit flags (none at this time; set to 0)  */

Description

Assign the functions to supply and receive data for the supplied CAPIStream. When a store, fetch, other CAPI function is invoked, the CAPI function will talk directly to the stream in order to send or receive data. NULL values for a callback means that the operation is not allowed. The memory in which the stream is returned must be preinitialized to NULL.

Note

This function should be used instead of the old CAPI_SetStreamCallbacks function.

Cleanup

The stream created by calling this routine must be destroyed by calling CAPI_DestroyStreams.

Returns

CAPI_STAT_OK
CAPI_STAT_SERVICE
CAPI_STAT_API_FLAGS
CAPI_STAT_API_NULL
CAPI_STAT_API_BADPARAM
CAPI_STAT_API_CALLBACK
CAPI_STAT_API_SESSION
CAPI_STAT_LIBRARY


CAPI_CreateFileStream

CAPIStatus CAPI_CreateFileStream(
	CAPISession  in_session,
	CAPIStream * out_pStream,
	FILE * 	     in_file
	CAPIFlag     in_lFlags)

Description

Assign the given file pointer to a CAPI stream.  This is an alternative to using CAPI_CreateCallbackStream.  The caller is responsible for opening the file with the right permissions before calling this function. That is, a send stream used by a Store operation should have read permissions to the file while a receive stream used by a Fetch operation should have write permissions.

Cleanup

The stream created by calling this routine must be destroyed by calling CAPI_DestroyStreams.  Note that the destroy function will not close file pointer; this must be done by the user.

Returns

errors


CAPI_CreateMemoryStream

CAPIStatus CAPI_CreateMemoryStream(
	CAPISession  in_session,
	CAPIStream * out_pStream,
	const char * in_sendBuffer, 	/* send buffer */
	char **      in_recvBuffer, 	/* receive buffer */
	CAPIFlag     in_lFlags)

Description

Assign the send and receive memory buffers to a stream.  This is an alternative to using CAPI_CreateCallbackStream.  The send buffer should be a null-terminated string whose content will be passed to a Store function.  The receive buffer will be allocated and filled up by a Fetch function. NULL values for either parameter means that the stream will not support that type of operation.

Cleanup

The stream created by calling this routine must be destroyed by calling CAPI_DestroyStreams. This will take care of freeing the receive buffer as well.

Returns

errors


CAPI_DeleteEvent

CAPIStatus CAPI_DeleteEvent(
    CAPISession s,              /* i:  login session handle  */
    CAPIHandle* pH,             /* i:  list of CAPIHandles for delete  */
    int iHandleCount,           /* i:  number of valid handles in pH  */
    CAPIStatus* pS,             /* o: array of status for each handle */
    CAPIFlag lFlags,            /* i:  bit flags (none at this time; set to 0)  */
    char* psUID,                /* i:  UID of the event to delete  */
    char* dtRecurrenceID,       /* i:  recurrence-id, NULL means ignore  */
    int iModifier);             /* i:  one of CAPI_THISINSTANCE,  */
                                /*     CAPI_THISANDPRIOR, CAPI_THISANDFUTURE  */
                                /*     only valid if recurrence-id is non-NULL  */

Description

Delete the component(s) specified by the combination of psUID, dRecurrenceID, and iModifier from the supplied list of calendars. When this function returns, the buffer for CAPIStatus return values, pS, will contain the status associated with each handle relative to the delete operation. That is, pS[i] holds the status of the delete operation for the calendar addressed by pH[i]. pS must be large enough to hold iHandleCount CAPIStatus codes. Even if the event cannot be deleted from some handles it will be deleted from those which it can.

Flags

CAPI_NOTIFY_EMAIL
Sends e-mail notification of the event deletion.
CAPI_NOTIFY_SMS
Sends wireless notification of the event deletion by Short Message Service (SMS).

Returns

CAPI_STAT_OK
CAPI_STAT_DATA_DATE
CAPI_STAT_DATA_UID
CAPI_STAT_SERVICE
CAPI_STAT_API_FLAGS
CAPI_STAT_API_NULL
CAPI_STAT_API_BADPARAM
CAPI_STAT_API_HANDLE
CAPI_STAT_API_SESSION
CAPI_STAT_SECUR_WRITE
CAPI_STAT_LIBRARY


CAPI_DestroyHandles

 CAPIStatus CAPI_DestroyHandles(
    CAPISession s,              /* i: login session handle  */
    CAPIHandle* pH,             /* i: pointer to array of handles to destroy  */
    int iHandleCount,           /* i: number of valid handles in pH  */
    CAPIFlag lFlags);           /* i: bit flags (none at this time; set to 0)  */

Description

Destroy handles created by CAPI_GetHandle(). On a fatal error no handles will have been destroyed.

Returns

CAPI_STAT_OK
CAPI_STAT_SERVICE
CAPI_STAT_API_FLAGS
CAPI_STAT_API_NULL
CAPI_STAT_API_BADPARAM
CAPI_STAT_API_HANDLE
CAPI_STAT_LIBRARY


CAPI_DestroyStreams

CAPIStatus CAPI_DestroyStreams(
    CAPISession s,              /* i: login session handle  */
    CAPIStream* pS,             /* i: array of streams to destroy  */
    int iStreamCount,           /* i: number of valid streams in pS  */
    CAPIFlag lFlags);           /* i: bit flags (none at this time; set to 0)  */

Description

Destroy any streams created by CAPI_CreateCallbackStream, CAPI_CreateFileStream or CAPI_CreateMemoryStream. On a fatal error no streams will be destroyed.

Returns

CAPI_STAT_OK
CAPI_STAT_SERVICE
CAPI_STAT_API_FLAGS
CAPI_STAT_API_NULL
CAPI_STAT_API_BADPARAM
CAPI_STAT_API_STREAM
CAPI_STAT_LIBRARY


CAPI_FetchEventByID

CAPIStatus CAPI_FetchEventByID(
    CAPISession s,              /* i: login session handle  */
    CAPIHandle h,               /* i: calendar from which to fetch events  */
    CAPIFlag lFlags,            /* i: bit flags (none at this time; set to 0)  */
    char* psUID,                /* i: UID of the event to fetch  */
    char* dtRecurrenceID,       /* i: recurrence-id, NULL means ignore  */
    int iModifier,              /* i: one of CAPI_THISINSTANCE,  */
                                /*    CAPI_THISANDPRIOR, CAPI_THISANDFUTURE  */
                                /*    only valid if recurrence-id is non-NULL  */
    char** ppsPropList,         /* i: list of properties to return   */
    int iPropCount,             /* i: number of properties in the list  */
    CAPIStream stream);         /* i: stream to write solution set to  */

Description

Search the calendar for the event, event instance, or event subset as specified by psUID, dRecurrenceID, and iModifier. The solution set, returned through the supplied CAPIStream pointer, will be a MIME / ICAL data stream containing the VEVENTs.  The returned event properties are limited to those properties specified in the supplied property list subject to access control.  A NULL value for ppsPropList means return all properties. Normal VEVENTs as well as "day events" (VEVENTs with DTSTART values that contain the VALUE=DATE paramater) are returned by this call.

Returns

CAPI_STAT_OK
CAPI_STAT_DATA_DATE
CAPI_STAT_DATA_UID
CAPI_STAT_SERVICE
CAPI_STAT_API_FLAGS
CAPI_STAT_API_NULL
CAPI_STAT_API_BADPARAM
CAPI_STAT_API_CALLBACK
CAPI_STAT_API_HANDLE
CAPI_STAT_API_SESSION
CAPI_STAT_API_STREAM
CAPI_STAT_SECUR_READ
CAPI_STAT_LIBRARY


CAPI_FetchEventsByAlarmRange

CAPIStatus CAPI_FetchEventsByAlarmRange(
    CAPISession s,              /* i: login session handle  */
    CAPIHandle* pH,             /* i: list of CAPIHandles for Fetch  */
    int iHandleCount,           /* i: number of valid handles in pH  */
    CAPIStatus* pS,             /* o: array of status for each handle */
    CAPIFlag lFlags,            /* i: bit flags (none at this time; set to 0)  */
    char* dStart,               /* i: range start time eg "19980704T080000Z"  */
    char* dEnd,                 /* i: range end time eg "19980704T180000Z"  */
    char** ppsPropList,         /* i: list of properties to return  */
    int iPropCount,             /* i: number of properties in *ppsPropList  */
    CAPIStream stream);         /* i: stream to write solution set to  */

Description

Search the list of calendars for events having alarms that will go off between dStart and dEnd. The solution set is returned via the supplied CAPIStream pointer. The return stream will be a MIME / ICAL data stream of VEVENTs containing alarms that overlap the supplied date range.  The returned event properties are limited to those properties specified in the supplied property list subject to access control. A NULL value for ppsPropList means return all properties. Normal VEVENTs as well as "day events" (VEVENTs with DTSTART values that contain the VALUE=DATE paramater) are returned by this call.

Dates must be supplied in iCalendar date/time format, UTC based.

When this function returns, the buffer for CAPIStatus return values, pS, will contain the status associated with each handle relative to the fetch operation. That is, pS[i] holds the status of the fetch operation for the calendar addressed by pH[i]. pS must be large enough to hold iHandleCount CAPIStatus codes.

Returns

CAPI_STAT_OK
CAPI_STAT_DATA_DATE
CAPI_STAT_SERVICE
CAPI_STAT_API_FLAGS
CAPI_STAT_API_NULL
CAPI_STAT_API_BADPARAM
CAPI_STAT_API_CALLBACK
CAPI_STAT_API_HANDLE
CAPI_STAT_API_SESSION
CAPI_STAT_API_STREAM
CAPI_STAT_SECUR_READ
CAPI_STAT_LIBRARY


CAPI_FetchEventsByRange

CAPIStatus CAPI_FetchEventsByRange(
    CAPISession s,              /* i: login session handle  */
    CAPIHandle* pH,             /* i: list of CAPIHandles for fetch  */
    int iHandleCount,           /* i: number of valid handles in pp  */
    CAPIStatus* pS,             /* o: array of status for each handle */
    CAPIFlag lFlags,            /* i: bit flags (none at this time; set to 0)  */
    char* dStart,               /* i: range start time  */
    char* dEnd,                 /* i: range end time  */
    char** ppsPropList,         /* i: list of properties returned in events  */
    int iPropCount,             /* i: number of properties in the list  */
    CAPIStream stream);         /* i: stream to write solution set to  */

Description

Search the list of calendars for events that overlap dStart and dEnd.  The values for dStart and dEnd are iCalendar format strings specified as UTC times. For example: 19980803T173000Z . The solution set, returned through the supplied CAPIStream pointer, will be a MIME / ICAL data stream of VEVENTs that overlap the supplied date range.  Recurrences outside the range will not be returned.  The returned event properties are limited to those properties specified in the supplied property list subject to access control.  A NULL value for ppsPropList means return all properties. Normal VEVENTs as well as "day events" (VEVENTs with DTSTART values that contain the VALUE=DATE paramater) are returned by this call.

When this function returns, the buffer for CAPIStatus return values, pS, will contain the status associated with each handle relative to the fetch operation. That is, pS[i] holds the status of the fetch operation for the calendar addressed by pH[i]. pS must be large enough to hold iHandleCount CAPIStatus codes.

Returns

CAPI_STAT_OK
CAPI_STAT_DATA_DATE
CAPI_STAT_SERVICE
CAPI_STAT_API_FLAGS
CAPI_STAT_API_NULL
CAPI_STAT_API_BADPARAM
CAPI_STAT_API_CALLBACK
CAPI_STAT_API_HANDLE
CAPI_STAT_API_SESSION
CAPI_STAT_API_STREAM
CAPI_STAT_SECUR_READ
CAPI_STAT_LIBRARY


CAPI_GetCapabilities

CAPIStatus CAPI_GetCapabilities(
	CAPI_Session  in_session,
	CAPIFlag      in_lFlags,
	const char ** out_value)

Description

Returns information about the calendar session.

Flags

Name  Example
CAPI_CAPAB_AUTH returns "sasl,basic"
CAPI_CAPAB_COMP        returns "rle"
CAPI_CAPAB_ENCR         returns "des,basic"
CAPI_CAPAB_MAXDATE    returns "20371201"
CAPI_CAPAB_CAPI_VERSION  returns "2.0"
CAPI_CAPAB_VERSION  returns "2.4"
CAPI_CAPAB_SERVER_VERSION  returns "5.1"
CAPI_CAPAB_UNSUPPORTED_ICAL_PROP returns "GEO,COMMENT"
CAPI_CAPAB_UNSUPPORTED_ICAL_COMP returns "VJOURNAL"

Returns

errors


CAPI_GetHandle

CAPIStatus CAPI_GetHandle(
    CAPISession s,              /* i: login session handle  */
    char* u,                    /* i: user as defined in CAPI_Logon  */
    CAPIFlag lFlags,            /* i: bit flags (none at this time; set to 0)  */
    CAPIHandle* pH);            /* o: return new handle  */

Description

Get a handle to the calendar of the supplied user. The user string should be formatted as in CAPI_Logon. In particular, note that extra information is supplied through the user string and is delimited from the user by a question mark (?). Instead of a user string, a NULL pointer may also be passed. In that case, the function returns the handle of the logged on user. The memory in which the handle is returned must be preinitialized to NULL.

Cleanup

Handles created by this call must be destroyed by calling CAPI_DestroyHandles().

Returns

CAPI_STAT_OK
CAPI_STAT_DATA_USERID
CAPI_STAT_SERVICE
CAPI_STAT_API_FLAGS
CAPI_STAT_API_NULL
CAPI_STAT_API_HANDLE
CAPI_STAT_API_SESSION
CAPI_STAT_LIBRARY


CAPI_GetLastStoredUID

CAPIStatus CAPI_GetLastStoredUID (
    CAPISession Se            /* i: the session from which to get the UID */
                              /*    Must be a session returned by CAPI_Logon */
    char const ** pUID        /* o: to return pointer to UID string */
    CAPIFlag lFlags)          /* i: bit flags modifying behaviour */
                              /*    This must be 0 currently.*/

Description

This function returns the UID of the event which were stored by the last successful call to CAPI_StoreEvent, or no UID if the there was no call to CAPI_StoreEvent or the last call was not successful.

The UID is returned as a static read-only string.  The pointer to that string is only valid until the next call to CAPI_StoreEvent; hence, it may be desirable to copy it to another variable as soon as it is obtained.  This UID is appropriate for use in subsequent CAPI calls.

Cleanup

No clean up is required.

Returns

This function can return any of
CAPI_STAT_OK
CAPI_STAT_SERVICE
CAPI_STAT_API_FLAGS
CAPI_STAT_API_NULL
CAPI_STAT_API_BADPARAM
CAPI_STAT_LIBRARY


CAPI_GetLastStoredUIDs

CAPIStatus CAPI_GetLastStoredUID (
    CAPISession Se            /* i: the session from which to get the UID */
                              /*    Must be a session returned by CAPI_Logon */
    char const * const ** pUIDs /* o: to return pointer to UID string array */
    long * count              /* o: number of UIDs in the array */ 
    CAPIFlag lFlags)          /* i: bit flags modifying behaviour */
                              /*    This must be 0 currently.*/

Description

This functions is similar to CAPI_GetLastStoredUID except that it returns a pointer to an array of UIDs.  It should normally be called after a CAPI_StoreEvent in which multiple events were requested.  Both the array and the UIDs in it are read-only.  You should not modify or try to free() them.

Cleanup

No clean up is required.

Returns

Same as CAPI_GetLastStoredUID 


CAPI_GetStatusLevels

CAPI_FUNC (void) CAPI_GetStatusLevels(
    CAPIStatus s,                 /* i: status to be evaluated */
    int * level1,                 /* o: pointer for the level 1 result */
    int * level2,                 /* o: pointer for the level 2 result */
    int * level3,                 /* o: pointer for the level 3 result */
    int * level4,                 /* o: pointer for the level 4 result */
    int * level5);                /* o: pointer for the level 5 result */

Description

CAPI_GetStatusLevels is a new function to break down CAPI error status into its component bit fields.

Cleanup

No clean up is required.


CAPI_GetStatusString

CAPI_FUNC (void) CAPI_GetStatusString(
    CAPIStatus s,                 /* i: status to be eveluated */
    const char ** errString);     /* o: pointer for the result string */

Description

Returns a text description of a given CAPI error status code.

Cleanup

No clean up is required.


CAPI_HandleInfo

CAPIStatus CAPI_HandleInfo(
    CAPISession s,              /* i: login session handle  */
    CAPIHandle h,               /* i: handle from CAPI_GetHandle  */
    CAPIFlag lFlags,            /* i: bit flags (values in ctapi.h)  */
    char ** psInfo)             /* o: return handle info  */

Description

This function returns information about the agenda of the supplied handle. Three pieces of information can be returned, chosen by the value of lFlags. The information is returned as a pointer to a static read-only string.

CAPI_HANDLE_TYPE indicates the type of the handle, this can be "user" or "resource" and indicates what type of agenda this is. CAPI_HANDLE_NAME returns the name of the agenda owner, or resource, in the form of a sequence of field-value pairs, separated by "/". This string, when prepended with a '?' is of an appropriate format to be passed to CAPI_GetHandle. A description of the field names is given in the section on identifying users above. CAPI_HANDLE_MAILTO returns the email address of who the agenda belongs to. Since resources do not have email addresses an error is returned when this mode is used with a resource agenda.

Cleanup

Since the returned string is static read-only, nothing needs to be cleaned up.

Returns

CAPI_STAT_OK
CAPI_STAT_SERVICE
CAPI_STAT_API_FLAGS
CAPI_STAT_API_NULL
CAPI_STAT_API_HANDLE
CAPI_STAT_API_SESSION
CAPI_STAT_LIBRARY


CAPI_Logoff

CAPIStatus CAPI_Logoff(
    CAPISession * s,             /* io: session from login  */
    CAPIFlag lFlags);            /* i: bit flags */

Description

This function can be used in 2 ways:

  1. Terminate the supplied session.  This will end the connection to the calendar store and will also reset the session pointer to NULL upon return.
  2. Deauthenticate session but do not disconnect.  This will preserve the connection to the calendar store, but no calendar operation will be allowed until another user has authenticated using CAPI_Logon.

Flags

CAPI_MODE_NONE
Behaviour #1
CAPI_LOGOFF_STAY_CONNECTED
Behaviour #2

Cleanup

Since the "stay connected" mode does not destroy the session, a final call to CAPI_Logoff is needed to terminate the sesssion in this case.

Returns

CAPI_STAT_OK
CAPI_STAT_SERVICE
CAPI_STAT_API_FLAGS
CAPI_STAT_API_NULL
CAPI_STAT_API_SESSION
CAPI_STAT_LIBRARY


CAPI_Logon

CAPIStatus CAPI_Logon(
    const char* psUser,         /* i: Calendar (and "?extra" information )  */
    const char* psPassword,     /* i: password for sUser  */
    const char* psHost,         /* i: calendar server host (and :port)  */
    CAPIFlag lFlags,            /* i: bit flags (none at this time; set to 0)  */
    CAPISession* pSession);     /* io: the session  */

Description

Establish a session with the Calendar Store.  No session will be returned if an error occurs.

The session parameter can be used in 2 ways:

  1. Preinitialize the session to NULL.  In this case, the function will connect to the calendar service, authenticate as the given user and return a new session.
  2. Reuse an active session obtained from a previous call to CAPI_Connect (or CAPI_Logon, when you use CAPI_Logoff without disconnecting) and authenticate as a new user.  Since the connection to a calendar service has already been established, the hostname may be omitted.

ACE

With CorporateTime servers that support the ACE framework, CAPI_Logon will try to use the default ACE mechanisms set by the server.  For authentication mechanisms that don't require user credentials at each logon (e.g. SASL with Kerberos), an empty string may be passed for the user and password parameters.

The host parameter can also be used to specify ACE mechanisms other than the defaults.  The format of this parameter is decribed below:

	host-string = hostname "?" ext-param %x00

	; Nul-terminated string
	hostname = *( ALPHA / DIGIT / "." ) [":" port-number]
	
	; Identifies a calendar store 
	port-number = 1*DIGIT
	; Identifies the port on which the server is listening (optional).
	; In most cases this should be left out so as to use the default 
	; port number
	ext-param = DELIMITER fields
	; the extended string is used to specify ACE mechanisms
	fields = [authentication-mech] [compression-mech] [encryption-mech]
	authentication-mech = "AUTH=" ACE-mechanism DELIMITER
	compression-mech = "COMP=" ACE-mechanism DELIMITER
	encryption-mech = "ENCR=" ACE-mechanism DELIMITER
	; To find out which ACE-mechanisms the server support
	; use CAPI_Connect followed by CAPI_GetCapabilities
	DELIMITER = %x01-29 / %x2B-2F / %x3A-3C / %x3E-40 / %5B-60 / %7B-7F
	; Everything except NUL, "*", DIGIT, "=", ALPHA

Example:

        "calserv.domain.net?^AUTH=sasl^ENCR=des^COMP=rle^"
	; connect to "calserv.domain.net" and use SASL to authenticate,
	; DES for encryption and RLE for compression
	"?^AUTH=sasl^ENCR=des^COMP=rle^"
	; This is an example of reusing an already established connection
	; Here we only want to specify the ACE mechanisms, not the hostname.

Cleanup

The sessions created by calling this routine must be destroyed by calling CAPI_Logoff. Please note that CAPI_Logon creates a temporary file which is removed by CAPI_Logoff.

Returns

CAPI_STAT_OK
CAPI_STAT_DATA_USERID
CAPI_STAT_DATA_HOSTNAME
CAPI_STAT_SERVICE
CAPI_STAT_API_FLAGS
CAPI_STAT_API_NULL
CAPI_STAT_API_BADPARAM
CAPI_STAT_API_SESSION
CAPI_STAT_SECUR_LOGON
CAPI_STAT_LIBRARY


CAPI_SetIdentity

CAPIStatus CAPI_SetIdentity(
	const char * in_username,
	CAPIFlag     in_lFlags,
	CAPISession  io_session)

Description

Allow an authenticated user (CAPI_Logon) to work as another calendar user.  For this to work, proper designate rights must have been set in advance; otherwise, a security error will be returned.

The format of the username parameter is the same as in the CAPI_Logon function.  The authenticated user may revert to her original identity by using NULL as username.

Returns

errors


CAPI_SetStreamCallbacks

This function has been made obsolete in CAPI 2.0. Although it is still supported for backward compatibility, you should use CAPI_CreateCallbackStream instead.


CAPI_StoreEvent

CAPIStatus CAPI_StoreEvent(
    CAPISession s,              /* i: login session handle  */
    CAPIHandle* pH,             /* i: list of CAPIHandles for store  */
    int iHandleCount,           /* i: number of valid handles in pH  */
    CAPIStatus* pS,             /* o: array status for each handle */
    CAPIFlag lFlags,            /* i: bit flags, described in header  */
    CAPIStream stream );        /* i: stream for reading data to store */

Description

Store events in the supplied list of calendars.  If an event is already in the Calendar (as identified by its UID and Recurrence-ID) it will be updated. CAPI is not responsible for enforcing iCalendar security or data integrity as defined by the "ORGANIZER", "SEQUENCE" and "DTSTAMP" properties. It is the responsibility of the CAPI user to be familiar with this model and to enforce it. CAPI_StoreEvent is capable of overwriting these properties.

When this function returns, the buffer for CAPIStatus return values, pS, will contain the status associated with each handle relative to the store operation. That is, pS[i] holds the status of the store operation for the calendar addressed by pH[i]. pS must be large enough to hold iHandleCount CAPIStatus codes. A failure for one particular handle will not cause a failure for the entire operation.

CAPI_StoreEvent allows data to passed in several VEVENT components. Each VEVENT may or may not refer to the same event. These will be processed as if they had been supplied to many consecutive calls to CAPI_StoreEvent, one per call, in the order in which they appear in the "VCALENDAR". Despite the fact that behaviour is the same, it is preferable to make only one call to CAPI_StoreEvent, as this is likely to be more efficient than many calls.  A huge collection of VEVENTs will however require more memory to process.

CAPI_StoreEvent can create new instances, either of a new event or of an event which is already on the server. It can also be used to modify groups of instances, either all, one or a range of instances of an existing event. The appropriate behaviour is chosen through the specification of the properties "UID", "RECURRENCE-ID", "DTSTART", "RDATE", "RRULE", "EXDATE" and "EXRULE".

If "UID" does not match an event that already exists on the server then it is a request to create a new event on the server. In this case a "RECURRENCE-ID" property may not be specified, and a "DTSTART" property must be specified.

If the "UID" property matches an event that already exists on the server, the "RECURRENCE-ID" property is not present, and at least one of "DTSTART", "RDATE", "RRULE", "EXDATE" and "EXRULE" is present then the request is to add new instances to the event. If any instances on the server are identified by these dates they will be overwritten.

If the "UID" property matches an event that already exists on the server, and none of "RECURRENCE-ID", "DTSTART", "RDATE", "RRULE", "EXDATE" or "EXRULE" are present, then this is a request to modify all of the instances of an event. In this case the "DTEND" property may not be present.

If the "UID" property matches an event that already exists on the server, and the "RECURRENCE-ID" property is present, and it has no "range" parameter, then this is a request to modify a single instance. None of the properties "RDATE", "RRULE", "EXDATE" and "EXRULE" can be specified in this case, but the "DTSTART" property can be used to modify the start time of the particular instance.

If the "UID" property matches an event that already exists on the server, and the "RECURRENCE-ID" property is present, and it has a "range" parameter, then this is a request to modify a range of instances. None of the properties "DTSTART", "RDATE", "RRULE", "EXDATE" and "EXRULE" can be specified in this case. Also, "DTEND" may not be specified, although "DURATION" may be.

The iCalendar "RRULE" property is a concise way of specifying many instances of an event, however not all CorporateTime Servers support this method of storing instances. To accomodate this restriction CAPI expands recurrence rules to specific dates, storing only these dates, and discarding the expanded recurrence rule. In the case of a recurrence rule that goes for ever, the list of created dates will be truncated.

E-mail and wireless notification of newly created and modified events can be sent using the CAPI_NOTIFY_EMAIL and CAPI_NOTIFY_SMS flags.

E-mail, wireless and audio reminders to be triggered in advance of an event are also supported. Specify them using VALARM objects in the following format:

    BEGIN:VALARM
    ACTION:<name>
    TRIGGER:-PT2H1M
    END:VALARM

<name> can take one of the following values: EMAIL for an e-mail reminder, X-STELTOR-SMS for a wireless reminder, or AUDIO for an audio reminder. TRIGGER specifies the time in advance of the event start time at which to set the reminder.

Flags

CAPI_NOTIFY_EMAIL
Sends e-mail notification of the event creation or modification.
CAPI_NOTIFY_SMS
Sends wireless notification of the event creation or modification by Short Message Service (SMS).

CAPI_StoreEvent also provides the following mutually exclusive bit flags which govern the interpretation of the rest of the specified properties.

#define CAPI_STORE_REPLACE 0x00
#define CAPI_STORE_UPDATE  0x01
#define CAPI_STORE_DELPROP 0x02

CAPI_STORE_REPLACE

This mode can be used when creating new instances or modifying existing ones. When creating new instances they are created with all the properties as specified in the data. When existing instances are being modified all their properties are replaced with the ones specified in the supplied data.

Example

Event as it currently appears in the calendar store, prior to calling CAPI_StoreEvent (applies to all examples):

BEGIN:VEVENT
ORGANIZER:Mailto:A@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;CN=BIG A:Mailto:A@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=B:Mailto:B@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=C:Mailto:C@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=Hal:Mailto:D@example.com
ATTENDEE;RSVP=FALSE;TYPE=ROOM:conf_Big@example.com
ATTENDEE;ROLE=NON-PARTICIPANT;RSVP=FALSE:Mailto:E@example.com
DTSTAMP:19980611T190000Z
DTSTART:19980701T200000Z
DTEND:19980701T2100000Z
SUMMARY:Conference
LOCATION:The Big Conference Room
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
STATUS:CONFIRMED
END:VEVENT

Call CAPI_StoreEvent with the following ICAL stream, which modifies a particular instance:

BEGIN:VCALENDAR
PRODID:-//ACME//NONSGML DesktopCalendar//EN
VERSION:2.0
BEGIN:VEVENT
ORGANIZER:Mailto:A@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;CN=BIG A:Mailto:A@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=B:Mailto:B@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=C:Mailto:C@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=Hal:Mailto:D@example.com
DTSTAMP:19980611T190000Z
RECURRENCE-ID:19980701T200000Z
DURATION:PT1H
SUMMARY:Conference
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:1
STATUS:CONFIRMED
END:VEVENT
END:VCALENDAR

Upon successful completion of the CAPI_StoreEvent call, the event stored on the server will have its properties replaced the net effect being:

CAPI_STORE_UPDATE

This mode can be used when creating new instances or modifying existing ones. When creating new instances they are created with all the properties as specified in the data. When existing instances are being modified, this mode only affects the specified properties. Any property that is updated must be completely updated. Effectively, all instances of any supplied property are completely deleted from the event on the calendar store and replaced with supplied properties.  Thus, even to update a single ATTENDEE property, all ATTENDEE properties must be supplied.

Example

Call CAPI_StoreEvent with the following ICAL stream:

BEGIN:VCALENDAR
PRODID:-//ACME//NONSGML DesktopCalendar//EN
VERSION:2.0
BEGIN:VEVENT
RECURRENCE-ID:19980701T200000Z
DTEND:19980701T2200000Z
DESCRIPTION:We need to discuss the project schedule. Please come prepared.
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:1
END:VEVENT
END:VCALENDAR

Call CAPI_StoreEvent with the following ICAL stream:

BEGIN:VCALENDAR
PRODID:-//ACME//NONSGML DesktopCalendar//EN
VERSION:2.0
BEGIN:VEVENT
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;CN=BIG A:Mailto:A@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=B:Mailto:B@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=C:Mailto:C@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=Hal:Mailto:D@example.com
ATTENDEE;RSVP=FALSE;TYPE=ROOM:conf_Big@example.com
ATTENDEE;ROLE=NON-PARTICIPANT;RSVP=FALSE:Mailto:E@example.com
RECURRENCE-ID:19980701T200000Z
DTEND:19980701T2200000Z
DESCRIPTION:We need to discuss the project schedule. Please come prepared.
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:1
END:VEVENT
END:VCALENDAR

When CAPI_StoreEvent is called with either one of the above ICAL streams, the end time of the event recurrence will be moved, a description will be added, and the sequence number will be bumped. The calendar store copy will be as follows:

BEGIN:VEVENT
ORGANIZER:Mailto:A@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;CN=BIG A:Mailto:A@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=B:Mailto:B@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=C:Mailto:C@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=Hal:Mailto:D@example.com
ATTENDEE;RSVP=FALSE;TYPE=ROOM:conf_Big@example.com
ATTENDEE;ROLE=NON-PARTICIPANT;RSVP=FALSE:Mailto:E@example.com
DTSTAMP:19980611T193000Z
DTSTART:19980701T200000Z
DTEND:19980701T2200000Z
SUMMARY:Conference
DESCRIPTION:We need to discuss the project schedule. Please come prepared.
LOCATION:The Big Conference Room
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:1
STATUS:CONFIRMED
END:VEVENT

CAPI_STORE_DELPROP

This mode can only be used when modifying existing instances of an event. The non-indexing properties are deleted from the event. Some properties may appear many times. To delete one of these an exact match is required on the property, and its value, but not necessarily its parameters. For properties like "DURATION", which do not have a text value, the string output by CAPI must be matched. To delete all appearances of a particular property the property name only is specified, with no value and no parameters.

Call CAPI_StoreEvent with the following ICAL stream:

BEGIN:VCALENDAR
PRODID:-//ACME//NONSGML DesktopCalendar//EN
VERSION:2.0
BEGIN:VEVENT
LOCATION:The Big Conference Room
SUMMARY:Bla Bla Bla
UID:calsrv.example.com-873970198738777@example.com
END:VEVENT
END:VCALENDAR

Upon successful completion of the CAPI_StoreEvent call, the LOCATION property will be deleted.  The SUMMARY property will not be touched because it does not match the current summary. The calendar store copy will be as follows:

BEGIN:VEVENT
ORGANIZER:Mailto:A@example.com
ATTENDEE;ROLE=CHAIR;PARTSTAT=ACCEPTED;CN=BIG A:Mailto:A@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=B:Mailto:B@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=C:Mailto:C@example.com
ATTENDEE;RSVP=TRUE;TYPE=INDIVIDUAL;CN=Hal:Mailto:D@example.com
ATTENDEE;RSVP=FALSE;TYPE=ROOM:conf_Big@example.com
ATTENDEE;ROLE=NON-PARTICIPANT;RSVP=FALSE:Mailto:E@example.com
DTSTAMP:19980611T190000Z
DTSTART:19980701T200000Z
DTEND:19980701T2100000Z
SUMMARY:Conference
UID:calsrv.example.com-873970198738777@example.com
SEQUENCE:0
STATUS:CONFIRMED
END:VEVENT

Returns

CAPI_STAT_OK
CAPI_STAT_DATA_ICAL
CAPI_STAT_DATA_MIME
CAPI_STAT_DATA_ENCODING
CAPI_STAT_SERVICE
CAPI_STAT_API_FLAGS
CAPI_STAT_API_NULL
CAPI_STAT_API_BADPARAM
CAPI_STAT_API_CALLBACK
CAPI_STAT_API_HANDLE
CAPI_STAT_API_SESSION
CAPI_STAT_API_STREAM
CAPI_STAT_SECUR_WRITE
CAPI_STAT_LIBRARY


CAPI_WebLogon

CAPIStatus CAPI_WebLogon(
    const char* pCookie,         /* i: Calendar userinfo cookie */
    CAPIFlag lFlags,             /* i: bit flags (none at this time; set to 0)  */
    CAPISession* pSession);      /* o: the session  */

Note

Due to differences in cookie implementations, this function is not designed to work for all Steltor web clients. This function may be removed from future versions of CAPI.

Description

Establish a session with the Calendar Server using cookie information created by the web client.  This is an alternative to CAPI_Logon which can be used only if you have the web client running.  If an error occurs no session will be returned.  The memory used to return the session must be preinitialized to NULL.  The function will scan the pCookie parameter for the HTTP cookie it needs to logon.

Cleanup

The sessions created by calling this routine must be destroyed by calling CAPI_Logoff

Returns

CAPI_STAT_OK
CAPI_STAT_DATA_COOKIE
CAPI_STAT_SERVICE
CAPI_STAT_API_FLAGS
CAPI_STAT_API_NULL
CAPI_STAT_API_BADPARAM
CAPI_STAT_API_SESSION
CAPI_STAT_SECUR_LOGON
CAPI_STAT_LIBRARY


Examples

The following examples illustrate the use of callbacks when fetching and storing events. The details of logging on and obtaining handles are omitted. Both examples use these definitions:

typedef struct 
{ 
    char *p; 
    size_t iSize; 
} CAPI_CTX; 
CAPIStatus status; 
CAPISession session; 
  

Store an event from a string

Add a fixed event to the calendar store.

void main() 
{ 
    char pBuf[1024]; 
    CAPI_CTX myCtx; 
    CAPIStream stream; 
    CAPIHandle * hlist; 
    int hcount; 
    CAPIStatus * slist; 
    ... 
    strcpy(pBuf, 
           "Content-type: text/calendar\n" 
           "Content-encoding: 7bit\n" 
           "\n" 
           "BEGIN:VCALENDAR\n" 
           "METHOD:PUBLISH\n" 
           "PRODID:-//ACME//NONSGML DesktopCalendar//EN\n" 
           "VERSION:2.0\n" 
           "BEGIN:VEVENT\n" 
           "ORGANIZER:mailto:a@example.com\n" 
           "DTSTART:19970701T200000Z\n" 
           "DTSTAMP:19970611T190000Z\n" 
           "SUMMARY:ST. PAUL SAINTS -VS- DULUTH-SUPERIOR DUKES\n" 
           "UID:0981234-1234234-23@example.com\n" 
           "END:VEVENT\n" 
           "END:VCALENDAR\n"); 
    myCtx.p = pBuf; 
    myCtx.iSize = strlen(pBuf); 
    status = CAPI_CreateCallbackString(session,&stream,supplyData,&myCtx,NULL,NULL,0); 
    status = CAPI_StoreEvent(session,hlist,hcount,slist,CAPI_STORE_REPLACE,stream); 
    ... 
} 
int supplyData(void* pData, char* pBuf, int iSize, int* piTransferred) 
{ 
    CAPI_CTX* pCtx = (CAPI_CTX*)pData; 
    *piTransferred = (pCtx->iSize > iSize) ? iSize : pCtx->iSize; 
    memcpy(pBuf,pCtx->p,*piTransferred); 
    pCtx->iSize -= *piTransferred; 
    pCtx->p += *piTransferred; 
    return pCtx->iSize > 0 ? CAPI_CALLBACK_CONTINUE : CAPI_CALLBACK_DONE; 
} 
  

Read Events into a String

Read the the DTSTART, DTEND, SUMMARY, UID, RECURRENCE-ID values for events that occur on March 13, 1998 in GMT.

void main() 
{ 
    CAPI_CTX myCtx; 
    CAPIStream stream; 
    char sBuf[20000]; 
    CAPIHandle * hlist; 
    int hcount; 
    CAPIStatus * slist; 
    static char sPropTable[]  = 
    { 
        "DTSTART", 
        "DTEND", 
        "SUMMARY", 
        "UID", 
        "RECURRENCE-ID" 
    }; 
    myCtx.p = sBuf; 
    myCtx.iSize = sizeof(sBuf); 
    status = CAPI_CreateCallbackStream(session,&stream,NULL,NULL,receiveData,&myCtx,0); 
    status = CAPI_FetchEventsByRange(session,hlist,hcount,slist,0, 
                                     "19980313T000000Z","19980313T235959Z", 
                                     sPropTable, 5, stream ); 
    printf("%s\n",myCtx.p); 
    ... 
} 
int receiveData(void* pData, char* pBuf, int iSize, int* piTransferred) 
{ 
    CAPI_CTX* pCtx = (CAPI_CTX*)pData; 
    *piTransferred = (pCtx->iSize > iSize) ? iSize : pCtx->iSize; 
    memcpy(pCtx->p,pBuf,*piTransferred); 
    pCtx->iSize -= *piTransferred; 
    pCtx->p += *piTransferred; 
    return pCtx->iSize > 0 ? CAPI_CALLBACK_CONTINUE : 1; 
                             /* returns 0 on success, 1 on overflow */ 
} 

CAPI Status Codes

CAPIStatus returns information about what happened on an API call. Often but not always this will be as a result of an error in the attempt to perform the call. CAPIStatus is defined as a long and uses 32 bits, split into five bit fields. The leftmost bit field contains information about what sort of status is being reported, such as whether an unrecoverable error occured, while the subsequent bit fields indicate what condition is being reported. The bit fields are in a hierarchy, where each level describes the status in more detail than the previous one. The status can be reported to different levels of the hierarchy depending upon how much detail is available, although greater detail is always to be preferred. The special value of zero in the CAPIStatus indicates that everything is ok, and nothing special needs to be reported.

Bits are counted from left to right with the left-most bit numbered 0. A bit with a value of 1 is called set, while a bit with a value of 0 is called unset. Bit fields are also numbered from left to right, with the leftmost bit field numbered 1. Bit field 1 is information about the status, while bit fields 2 through 5 specify the status itself. Bit field 2 is at the top of the hirearchy, specifying the most general information about the status, with greater detail specified in order by fields 3, 4 and 5. A status which has all of the bits in one of bit fields 2 through 5 unset is only partially specified. If a field has all its bits unset then any fields to the right of it must also have all their bits unset. For instance, if bit field 3 is unset, then bit fields 4 and 5 must also be unset.

The following provides descriptions of each bit field along with their possible values.

Possible values for CAPIStatus are listed below. The level of detail of the values is indicated by their indentation in the table. These values are for bit fields 2 through 5 only, and may be combined with any flags in field 1. The values themselves are in the header file.

CAPIStatus Values

Status Description
CAPI_STAT_OK Operation completed successfully. Value 0.
CAPI_STAT_DATA Data class status
      CAPI_STAT_DATA_ICAL Information about iCal Data received
            CAPI_STAT_DATA_ICAL_NONE The provided data was not iCal data.
            CAPI_STAT_DATA_ICAL_LINEOVERFLOW One of the iCal data lines was too long, breaching the iCalendar spec.
            CAPI_STAT_DATA_ICAL_FOLDING There was a problem in the line folding
            CAPI_STAT_DATA_ICAL_IMPLEMENT A problem with this particular iCal implementation
            CAPI_STAT_DATA_ICAL_OVERFLOW There was an overflow when parsing the iCal data. This is caused by an internal limitation of the iCal library, and not not by a breach of the spec.
            CAPI_STAT_DATA_ICAL_COMPMISSING An expected or required component was missing
            CAPI_STAT_DATA_ICAL_COMPEXTRA An extra component was encountered. Either multiple specifications of a component which should only appear once, or a component which should not appear.
            CAPI_STAT_DATA_ICAL_COMPNAME There was a problem with a component name.
            CAPI_STAT_DATA_ICAL_COMPVALUE There was a problem with what a component contained.
            CAPI_STAT_DATA_ICAL_PROPMISSING An expected or required property was missing
            CAPI_STAT_DATA_ICAL_PROPEXTRA An extra property was encountered. Either multiple specifications of a property which should only appear once, or a property which should not appear.
            CAPI_STAT_DATA_ICAL_PROPVALUE There was a problem with a property value
            CAPI_STAT_DATA_ICAL_PROPNAME There was a problem with a property name.
            CAPI_STAT_DATA_ICAL_PARAMMISSING An expected or required parameter was missing
            CAPI_STAT_DATA_ICAL_PARAMEXTRA An extra parameter was encountered. Either multiple specifications of a parameter which should only appear once, or a parameter which should not appear.
            CAPI_STAT_DATA_ICAL_PARAMVALUE There was a problem with a parameter value
            CAPI_STAT_DATA_ICAL_PARAMNAME There was a problem with a parameter name.
            CAPI_STAT_DATA_ICAL_RECURMODE There was a problem with the recurrence specification. The rules laid out in the description of CAPI_StoreEvent were breached.
      CAPI_STAT_DATA_MIME Information about MIME Data received
            CAPI_STAT_DATA_MIME_NONE No MIME data was found
            CAPI_STAT_DATA_MIME_NOICAL No MIME parts were found whose headers indicated that they contain iCalendar data.
            CAPI_STAT_DATA_MIME_LENGTH One of the header lines was too long
            CAPI_STAT_DATA_MIME_HEADER A header could not be parsed
            CAPI_STAT_DATA_MIME_COMMENT A comment could not be parsed
            CAPI_STAT_DATA_MIME_ENCODING The encoding specified in the MIME object is not supported
            CAPI_STAT_DATA_MIME_IMPLEMENT A restriction specific to this MIME implementation was breached
            CAPI_STAT_DATA_MIME_IMPLEMENT_NESTING The MIME object was nested too deeply.
            CAPI_STAT_DATA_MIME_OVERFLOW There was an overflow when reading a MIME body part
            CAPI_STAT_DATA_MIME_FOLDING There was an error in the line folding
            CAPI_STAT_DATA_MIME_CHARSET There is no support for the specified charset.
      CAPI_STAT_DATA_DATE Information about Date data received
            CAPI_STAT_DATA_DATE_RANGE The date range is incorrect
            CAPI_STAT_DATA_DATE_FORMAT The format of the date data is incorrect
            CAPI_STAT_DATA_DATE_OUTOFRANGE A specified date is out of the range supported by this implementation
      CAPI_STAT_DATA_USERID Information about UserId string received
            CAPI_STAT_DATA_USERID_FORMAT The format of the UserId string was wrong
            CAPI_STAT_DATA_USERID_ID There was a problem with the Id part of the UserId string
            CAPI_STAT_DATA_USERID_EXT There was a problem with the Extended part of the UserId string
            CAPI_STAT_DATA_USERID_EXT_INIFILE There was a problem with the inifile
            CAPI_STAT_DATA_USERID_EXT_FORMAT The format of the extended string was bad.
            CAPI_STAT_DATA_USERID_EXT_NONE No users were identified by the string.
            CAPI_STAT_DATA_USERID_EXT_MANY Multiple users were identified by the string.
            CAPI_STAT_DATA_USERID_EXT_NODE The specified node could not be found
      CAPI_STAT_DATA_HOSTNAME Information about the hostname
            CAPI_STAT_DATA_HOSTNAME_FORMAT The format of the hostname string was wrong
            CAPI_STAT_DATA_HOSTNAME_HOST The hostname string could not be resolved to a host
            CAPI_STAT_DATA_HOSTNAME_SERVER No server could be found on the specified host and port
      CAPI_STAT_DATA_UID Information about the UID passed
            CAPI_STAT_DATA_UID_FORMAT The format of the UID string was wrong
            CAPI_STAT_DATA_UID_NOTFOUND An event with the supplied UID could not be found
            CAPI_STAT_DATA_UID_RECURRENCE The specified recurrence could not be found
      CAPI_STAT_DATA_ENCODING Information about the encoding of supplied data
      CAPI_STAT_DATA_COOKIE Information about the supplied cookie
CAPI_STAT_SERVICE Service class status
      CAPI_STAT_SERVICE_MEM There was a problem with system memory services
            CAPI_STAT_SERVICE_MEM_ALLOC Could not allocate memory
      CAPI_STAT_SERVICE_FILE There was a problem with system file services
            CAPI_STAT_SERVICE_FILE_OPEN There was a problem opening a file
            CAPI_STAT_SERVICE_FILE_CLOSE There was a problem closing a file
            CAPI_STAT_SERVICE_FILE_READ There was a problem reading from a file
            CAPI_STAT_SERVICE_FILE_WRITE There was a problem writing to a file
            CAPI_STAT_SERVICE_FILE_TEMP There was a problem allocating a temporary file
            CAPI_STAT_SERVICE_FILE_DELETE There was a problem deleting a file
      CAPI_STAT_SERVICE_NET There was a problem with network services
            CAPI_STAT_SERVICE_NET_TIMEOUT Timeout while waiting for network services
      CAPI_STAT_SERVICE_THREAD There was a problem with system thread services
      CAPI_STAT_SERVICE_LIBRARY There was a problem with the standard library services
      CAPI_STAT_SERVICE_TIME There was a problem with the standard time services
            CAPI_STAT_SERVICE_TIME_GMTIME GMTime could not be obtained
      CAPI_STAT_SERVICE_ACE A problem caused by one of the ACE plugins
            CAPI_STAT_SERVICE_ACE_SUPPORT Requested ACE option not supported
            CAPI_STAT_SERVICE_ACE_LOAD Required ACE plugin could not be loaded
CAPI_STAT_API API class status
      CAPI_STAT_API_FLAGS Bad flags were passed.
      CAPI_STAT_API_NULL A null pointer was passed.
      CAPI_STAT_API_BADPARAM A bad parameter was passed
      CAPI_STAT_API_CALLBACK There was a problem with the callback.
            CAPI_STAT_API_CALLBACK_ERROR The callback returned an error, which is returned in bit field 5
      CAPI_STAT_API_HANDLE There was a problem with a handle .
            CAPI_STAT_API_HANDLE_NULL The passed handle was null
            CAPI_STAT_API_HANDLE_BAD The passed handle was corrupt
            CAPI_STAT_API_HANDLE_NOTNULL The passed handle was not null
      CAPI_STAT_API_SESSION There was a problem with a session.
            CAPI_STAT_API_SESSION_NULL The passed session was null
            CAPI_STAT_API_SESSION_BAD The passed session was corrupt
            CAPI_STAT_API_SESSION_NOTNULL The passed session was not null
      CAPI_STAT_API_STREAM There was a problem with a stream.
            CAPI_STAT_API_STREAM_NULL The passed stream was null
            CAPI_STAT_API_STREAM_BAD The passed stream was corrupt
            CAPI_STAT_API_STREAM_NOTNULL The passed stream was not null
CAPI_STAT_SECUR Security class status
      CAPI_STAT_SECUR_LOGON There was a security error on logon
            CAPI_STAT_SECUR_LOGON_AUTH Logon authentication failed.
            CAPI_STAT_SECUR_LOGON_LOCKED The specified account is locked.
            CAPI_STAT_SECUR_LOGON_LOCKED_SYSOP Logon is locked for Sysops
            CAPI_STAT_SECUR_LOGON_LOCKED_RESOURCE Logon is locked for resources
      CAPI_STAT_SECUR_READ There was a security error on read
            CAPI_STAT_SECUR_READ_PROPS There was a security error reading properties
            CAPI_STAT_SECUR_READ_ALARM There was a security error reading alarm data.
      CAPI_STAT_SECUR_WRITE There was a security error on write
            CAPI_STAT_SECUR_WRITE_AGENDA There was a security error writing to an agenda
            CAPI_STAT_SECUR_WRITE_EVENT There was a security error writing to an event
      CAPI_STAT_SECUR_SERVER There was a security error in the server
            CAPI_STAT_SECUR_SERVER_LICENSE There was a licensing error on the server
CAPI_STAT_LIBRARY Library class status
      CAPI_STAT_LIBRARY_INTERNAL An internal error occured in the library
            CAPI_STAT_LIBRARY_INTERNAL_EXPIRY The function has expired in this library
            CAPI_STAT_LIBRARY_INTERNAL_PROTOCOL The library abused a protocol
            CAPI_STAT_LIBRARY_INTERNAL_DATA There was a corruption of data in the library
            CAPI_STAT_LIBRARY_INTERNAL_FUNCTION The library miscalled a function
            CAPI_STAT_LIBRARY_INTERNAL_COSMICRAY Something completely unexpected happened internally.
            CAPI_STAT_LIBRARY_INTERNAL_OVERFLOW Some internal maximum was exceeded
      CAPI_STAT_LIBRARY_IMPLEMENTATION The feature is not fully implemented
      CAPI_STAT_LIBRARY_SERVER A limitation of or occurence on the server.
            CAPI_STAT_LIBRARY_SERVER_SUPPORT The server does not provide support.
            CAPI_STAT_LIBRARY_SERVER_SUPPORT_UID There is no support for storing uids
            CAPI_STAT_LIBRARY_SERVER_SUPPORT_STANDARDS There is no support for CAPI on this server.
            CAPI_STAT_LIBRARY_SERVER_SUPPORT_CHARSET There is no support for the required character set.
            CAPI_STAT_LIBRARY_SERVER_USERDATA There is some problem with user data on the server.
            CAPI_STAT_LIBRARY_SERVER_BUSY The server cannot service the request right now because it is busy.

Copyright 2001 Steltor Inc. All rights reserved.
This page was last modified 19-03-2001