ClientSideProgramming
From OpenChange wiki
Contents |
client side programming with libmapi
overview
libmapi is the openchange library containing a client side implementation of the Exchange protocols, including nspi and emsmdb. That's, libmapi allows your messaging clients to talk with an exchange 2000 server. This page describes the use of libmapi as a standalone software component.
prerequisites
libmapi requires the following components to be installed:
- samba, http://www.samba.org
- openchange, http://www.openchange.org
Eventhough libmapi aims to be as independent from the Samba configuration files as possible, the smb.conf configuration file needs to be installed on your system. This is because Samba dcerpc subsystem still uses attributes found in the file. Removal os this dependency is scheduled for the next release of Samba.
compiling with libmapi
In order for developpers to see how to use libmapi, a small mail client application has been implemented. It can be found in the standalone/ directory of the openchange source tree. We will refer to this code (oc_fetchmail.c, oc_sendmail.c) all along this guide. The simple Makefile contains all the information you need to compile and link against libmapi. Since libmapi is packaged, it uses pkg-config to use the correct directory.
export PKG_CONFIG_PATH=/usr/local/samba/lib/pkgconfig/
pkg-config --cflags libmapi
pkg-config --libs libmapi
including header files
#define __USE_GNU 1
#include <libmapi/libmapi.h>
#include <param.h>
libmapi (de)initialization
Before doing anything, a global libmapi initialization is required.
status = MAPIInitialize(profdb);
status = MapiLogonEx(&global_mapi_ctx->session, profname);
In order to see how to create a profile, refer to doc/howto.txt in the openchange source tree root directory.
At the end of your code, you should uninitialize the mapi library.
MAPIUninitialize();
With the above steps done, you should be able to use the libmapi exported functions without any problems. For a complete documentation about the programming interface, please refer to the openchange manual pages.
libmapi programming interface
- mapi objects
The EMSMDB exchange protocol roughly works by instantiating objects on the server and accessing them by the way of handles. libmapi has kept this idea of manipulating objects, and implements most of the functions described in the Microsoft MAPI documentation.
- accessing objects
An object that is persistent can be addressed by the way of its id (mapi_id_t, which is a typedef of uint64_t); For instance, folders and messages are persistent and can be opened given their ids. Once an object has been instantiated by the server, the client can access it by using a handle(mapi_handle_t). From inside the libmapi handles are mostly hidden since objects are represented by the mapi_object_t type, that hides the underlying implementation. Functions for manipulating mapi objects includes:
- mapi_object_init
- mapi_object_release
- mapi_object_debug
mapi_object_init and mapi_object_release should always be called prior(after) using an object. Do not assume the callee will do it work for you.
Once a mapi object has been initialized, it can be opened(or created) on a concrete type using one of the following functions:
- OpenMessage
- GetContentsTable
- GetHierarchyTable
- GetAttachementTable
- CreateFolder
- ...
Having an object of the right type, you can perform actions on it by using the related functions. To see which functions are available for a given type, please refer to the Openchange manual pages. Implementation resides inside the libmapi/ SVN directory, where the filenames mostly match object types.
The following code snippet shows how to open the message default store and retrieve the inbox folder id:
mapi_object_t obj_store;
mapi_id_t id_inbox;
enum MAPISTATUS status;
mapi_object_init(&obj_store);
status = OpenMsgStore(&obj_store);
if (status != MAPI_E_SUCCESS)
return -1;
status = GetReceiveFolder(&obj_store, &id_inbox);
if (status != MAPI_E_SUCCESS)
return -1;
mapi_object_release(&obj_store);
examples
- If you are looking for standalone applications using libmapi, refer to oc_fetchmail.c and oc_sendmail.c. They contain the necessary code to fetch and send mails and their attachments. For a more complete application, you may have a look at the openchange plugin for Evolution, available on the Openchange SVN.
- The torture/ openchange directory contains several tests that extensively use the libmapi exported functions in order to test them.
