Sun Java System Calendar Server 6 2005Q4 Developer's Guide

Chapter 1 Calendar Server API (CSAPI) Overview

This chapter gives an overview of the Calendar Server API (CSAPI), which is a set of high performance programmatic interfaces that enables you to modify or enhance the feature set of Calendar Server . CSAPI allows you to create very fast runtime shared objects that outperform both system executables and scripts in any language, with respect to speed, memory footprint, and load. All of these factors contribute to scalability issues in high-end systems.

This chapter has the following sections:

CSAPI Architecture

The CSAPI is a group of shared-object runtime interfaces to Calendar Server functions. You can use plug-in CSAPI modules to manipulate server data for incoming requests and for responses. This architecture allows the server to act as a simple gateway to data that it knows nothing about. It also allows for dynamic logging and statistics tracking, external authentication schemes, user attribute manipulation, and a variety of other functions.

Figure 1–1 shows the relationship of CSAPI modules to other subsystems within Calendar Server. Depending on which functional group or groups a CSAPI module supports, it can interact with one or more areas of Calendar Server functionality, such as data formatting, authentication, and directory services.

A module is a shared object (.so file) on UNIX, or dynamic linked library (.dll file) on Windows. Each module that you provide must implement one or more of the CSAPI interfaces (or pure virtual base classes) defined in this document. For information about the CSAPI interfaces, see Chapter 2, CSAPI Reference.

Each client-side interface addresses a functional area of Calendar Server. The implementation contained in a module can either augment or override the native Calendar Server functionality in its area.

A set of server-side API's allows CSAPI modules to get the server’s version information, and use the server’s fast memory allocation mechanism.

You can use the default code for each of the CSAPI interfaces as a template to create your own plug-ins. The Calendar Server bundle contains all the default code, along with all supporting libraries and headers you need to implement your own plug-ins.

Figure 1–1 CSAPI Relationship to Other Subsystems

This graphic shows how the Calendar Server internal modules communicate
directly to CSAPI plug-in modules.

Thread Safe Requirement

CSAPI module plug-ins must be thread safe, as many thousands of threads can access a module at any time. For those plug-ins that cannot be thread-aware, use simple monitors at the function-call level in the plug-in itself. For more information on Netscape Portable Runtime (NSPR) threads, refer to the NSPR reference manual at For the URL, see the Dependencies section that follows.


CSAPI is a C and C++ interface for UNIX and Windows systems. It uses Netscape Portable Runtime (NSPR), a part of the Mozilla source code that is a platform independent API to operating system services, and XPCOM for Interface Dispatch.

For documentation on NSPR see the MozillaTM technical documentation site:

For documentation on XPCOM, see:

You must use NSPR for platform-independent C data types and runtime functions in implementations that need to run on different platforms. Calendar Server uses the XPCOM C++ API (QueryInterface) to discover the exact interfaces a specific module implements.


The following section describes how the system loads and uses the plug-ins you provide. Default plug-ins ship with the system. You can choose to augment or override any or all of them.

Loading CSAPI Modules

Calendar Server loads CSAPI modules from the cal/bin/plugins directory at startup and unloads them at server shutdown. All plug-in modules must reside in this directory and have filenames that are prefaced with cs_.

The server checks ics.conf for the modules to be dynamically loaded at server startup. If the value of the preference csapi.plugin.loadall is y, the server loads all shared objects in the cal/bin/plugins directory whose names begin with the prefix cs_. Otherwise, if the value is n, various parameters exist for the various plug-ins. For more information on the preferences in ics.conf, see the Sun Java System Calendar Server 6 2005Q4 Administration Guide.

To specify the loading of a specific plug-in, csapi.plugin.loadall must be set to n. In addition, two parameters must be used: csapi.plugin.plugin name, with a value of y, and csapi.plugin.plugin, with the value being the name of the plug-in.

For example, to load only the calendar-lookup plug-in, the parameters are:

csapi.plugin.loadall = "n"
csapi.plugin.calendarlookup = "y" = "calendarlookup"

Note that the plugin name part of the parameter must match on both parameters, but that it does not have to be the same as the value of the parameter. Thus, if you wanted to create a plug-in called cs_myown_plugin, you could call the parameters csapi.plugin.anyname, and The value of must be “cs_myown_plugin”.

Calendar Server uses the NSPR function PR_LoadLibrary() to load the shared object at startup, the function PR_UnloadLibrary to unload the shared image at shutdown. Once a shared object is loaded into memory, Calendar Server uses the function PR_FindSymbol to find entry points to known API implementations.

Plug-in Interfaces

All CSAPI plug-ins support one and only one exported symbol, NSGetFactory, as required by the XPCOM specification. From this entry point, Calendar Server calls the XPCOM method QueryInterface to find an object implementing the csIPlugin interface. This allows the server to query the plug-in for version, description, and vendor information. While this interface is optional, you should implement it so the server can ensure version control.

Plug-in Version Numbers

Each default plug-in interface can have a different version number. Version numbers increment by a whole number when the API is updated by Sun Microsystems, Inc. All custom plug-ins must use the methods in the current version of the default plug-in API.

If you created a custom plug-in based on an earlier default plug-in version, you must update your custom plug-in to use the new version of all updated methods, and you must increment its version number to reflect the current version number of the default plug-in.

The system does not load plug-ins with version numbers earlier than the current default version number. Your plug-in must have a version number greater than the current default plug-in, but less than the next whole number. For example, if you are writing, or have created in the past, a custom plug-in for csIDatabaseLookup, which is currently at version 2.0, your plug-in version number must be greater than 2.0 and less than 3.0.

The following table lists the current version of each plug-in API.

Plug-in API 

Current Version of Default Plug-in 



















Client and Server Plug-in API's

The CSAPI API's fall into two categories: client and server commands.

The interfaces are described in detail in Chapter 2, CSAPI Reference

Client API's

The following table lists the CSAPI client API's, which can be implemented by one or more plug-ins.

Client API's 


API: csIAccessControl

Augments or overrides the default access control mechanism. 

API: csIAuthentication

Augments or overrides the login authentication mechanism. 

API: csICalendarLookup

Augments or overrides the default calendar lookup mechanism. 

API: csIDataTranslator

Augments or overrides the format translation of incoming and outgoing data. 

API: csIPlugin

Provides version control and descriptive information about the module. 

API: csIQualifiedCalidLookup

Retrieves a calendar ID for the specified qualified URL. 

API: csIUserAttributes

Augments or overrides the mechanism for storing and retrieving user attributes. 

Server API's

The following is a list of the server API's, which can be implemented with one or more plug-ins.

Server API's 


API: csICalendarServer

Provides general server information, including version number. 

API: csIMalloc

Allows access to server’s memory allocation mechanism. 

Required Initialization Routine

All interfaces have the following initialization method that you must implement:

Init (nsISupports * aServer);

The server invokes this method immediately after it registers the interface in a newly loaded module. In the module, you can bind the parameter that the server returns, aServer, and use it to refer to the server instance. Your custom plug-in can use the QueryInterface method to find the server interfaces.

The following example checks the version of Calendar Server. It demonstrates how to do the following:

CSAPI Interface Samples

The distribution includes sample code for three of the CSAPI interfaces in the csapi/samples directory. You can use these files as templates in building your own CSAPI modules.

The following sample modules are provided:

Table 1–1 CSAPI Interface Samples

CSAPI Module Sample  



This sample overrides the default login authentication mechanism, using local authentication to validate users. The sample works on SolarisTM and on Windows:

On Solaris, it uses the pam library to authenticate against the local /etc/passwd file or NIS.

On Windows, it uses the WIN32 API LogonUser, which authenticates against Microsoft clients. In order for this sample to work properly on Windows, the administrator must enable the privilege for users to log on using batch jobs. You can do this from within the UserManager Administrative Tool, under the Policies/User Rights section.


This sample overrides the default format translation of incoming and outgoing data. It shows how to convert icalendar data into Microsoft Outlook CSV format. CSV format is a simple line-oriented file, where each entry has its own line and properties are separated by commas.


This sample overrides the default mechanism for storing and retrieving user attributes. It shows how to use the Berkeley database to store local user preferences. This code works on all supported platforms. The database is a simple table-driven key-value pair. The key for storing user preferences is a string stored as $user.$pref. The key must be unique.