Code Examples
To List and Print Calendars
Example 10-1 Listing and Printing Calendars Supported by Server
Example:
List and print out the calendars supported by a server.
Free memory returned by a CSA function.
list_calendar()
{
CSA_return_code stat;
CSA_uint32 i, number;
CSA_calendar_user *calendars;
char *host;
/*specify some machine in the network */
host = "somehost";
stat= csa_list_calendars(host, &number, &calendars, NULL);
for (i = 0; i< number; i++) {
/* the calendar_address field contains the address of the
* the calendar in the format "user@host" */
printf("%d: %s\n", i, calendars[i].calendar_address);
}
/* Example: free memory returned by a CSA function
* free the memory returned by csa_list_calendars above
*/
stat = csa_free(calendars);
}
To Add a Calendar
Example 10-2 Adding a Calendar Named "activity" to Host "host1"
#include <csa/csa.h>
CSA_access_rights *setup_access_list() {
CSA_access_rights *ptr1, *ptr2;
/* Allow any user to view public and confidential entries and
* user "user1" to view and insert public entries.
* The special user name "world" means any user.
*/
ptr2 = (CSA_access_rights *)calloc(1, sizeof(CSA_access_rights));
ptr2->user = (CSA_calendar_user *)calloc(1, sizeof(CSA_calendar_user));
ptr2->user->user_name = strdup("world");
ptr2->user->user_type = CSA_USER_TYPE_INDIVIDUAL;
ptr2->flags = CSA_VIEW_PUBLIC_ENTRIES | CSA_VIEW_CONFIDENTIAL_ENTRIES;
ptr1 = (CSA_access_rights *)calloc(1, sizeof(CSA_access_rights));
ptr1->user = (CSA_calendar_user *)calloc(1, sizeof(CSA_calendar_user));
ptr1->user->user_name = strdup("user1");
ptr1->user->user_type = CSA_USER_TYPE_INDIVIDUAL;
ptr1->flags = CSA_VIEW_PUBLIC_ENTRIES | CSA_INSERT_PUBLIC_ENTRIES;
ptr1->next = ptr2;
}
void destroy_access_list(CSA_access_rights *list)
{
CSA_access_rights *ptr;
while (list != NULL) {
ptr = list->next;
if (list->user) {
if (list->user->user_name)
free(list->user->user_name);
free(list->user);
} free(list);
list = ptr;
}
}
add_calendar()
{
CSA_return_code stat;
CSA_calendar_user caddr;
CSA_attribute attr;
CSA_attribute_value attr_val;
/* Specify the calendar to add */
caddr.user_name = NULL;
caddr.user_type = NULL;
caddr.calendar_address = "activity@host1";
caddr.calendar_user_extensions = NULL;
/* set up the access list */
attr_val.type = CSA_VALUE_ACCESS_LIST;
attr_val.item.access_list_value = setup_access_list();
attr.name = CSA_CAL_ATTR_ACCESS_LIST;
attr.value = &attr_val;
attr.attribute_extensions = NULL;
stat = csa_add_calendar(NULL, &caddr, 1, &attr, NULL);
destroy_access_list(attr_val.item.access_list_value);
}
To Log on to a Calendar
Example 10-3 Logging on to a Calendar
CSA_session_handle cal;
logon()
{
CSA_return_code stat;
CSA_calendar_user caddr
; CSA_flags access;
CSA_extension logon_exts[2];
CSA_X_COM_support check_support[2];
/* Specify the calendar to logon to */
caddr.user_name = NULL;
caddr.user_type = CSA_USER_TYPE_INDIVIDUAL;
caddr.calendar_address = "user@host";
caddr.calendar_user_extensions = NULL;
/* Specify the get user access extension (CSA_X_DT_GET_USER_ACCESS_EXT)
* to retrieve the user's access right with respect to the calendar.
*/
logon_exts[0].item_code = CSA_X_DT_GET_USER_ACCESS_EXT;
logon_exts[0].item_data = 0;
logon_exts[0].item_reference = NULL;
logon_exts[0].extension_flags = NULL;
/* Specify the CSA_X_COM_SUPPORT_EXT extension to check
* whether the CSA_X_XT_APP_CONTEXT_EXT extension and the
* CSA_X_UI_ID_EXT extension are supported.
*/
check_support[0].item_code = CSA_X_XT_APP_CONTEXT_EXT;
check_support[0].flags = NULL;
check_support[1].item_code = CSA_X_UI_ID_EXT;
check_support[1].flags = NULL;
logon_exts[1].item_code = CSA_X_COM_SUPPORT_EXT;
logon_exts[1].item_data = 2;
logon_exts[1].item_reference = (CSA_buffer)check_support;
logon_exts[0].extension_flags = CSA_EXT_LAST_ELEMENT;
stat = csa_logon(NULL, &caddr, NULL, NULL, NULL, &cal, logon_exts);
if (stat == CSA_SUCCESS) {
access = (CSA_flags)get_access_ext.item_data;
if (check_support[0].flag & CSA_X_COM_SUPPORTED)
printf("The CSA_X_XT_APP_CONTEXT_EXT extension is supported\n");
if (check_support[1].flag & CSA_X_COM_SUPPORTED)
printf("The CSA_X_UI_ID_EXT extension is supported\n");
}
}
To Terminate a Calendar Session
Example 10-4 Terminating a Calendar Session
logoff()
{
CSA_return_code stat;
/* When the session is no longer needed, it can be terminated by
* calling csa_logoff.
* Terminate the session returned by csa_logon in the previous
* example.
*/
stat = csa_logoff(cal, NULL);
}
To Delete a Calendar
Example 10-5 Deleting a Calendar
delete_calendar()
{
/* After a calendar session is established by calling csa_logon(),
* a calendar can be deleted using csa_delete_calendar().
*/
CSA_return_code stat;
stat = csa_delete_calendar(cal, NULL);
}
To Add a Calendar Entry
Example 10-6 Adding a Calendar Entry
#include <csa/csa.h>
CSA_return_code stat;
CSA_session_handle cal;
CSA_attribute attrs[9];
CSA_attribute_value attr_val[9];
CSA_reminder audio;
CSA_reminder mail;
CSA_entry_handle new_entry;
int i;
i = 0;
/* The start date attribute. This attribute has no default
* value and must be specified.
* A CSA_date_time value is a UTC based date and time value
* expressed in the ISO 8601 standard.
*/
attrs[i].name = CSA_ENTRY_ATTR_START_DATE;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_DATE_TIME;
attr_val[i].item.date_time_value = iso8601time(time(NULL));
i++;
/* The end date attribute.
* If not specified, the entry will not have the end date
* attribute.
*/
attrs[i].name = CSA_ENTRY_ATTR_END_DATE;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_DATE_TIME;
attr_val[i].item.date_time_value = iso8601time(time(NULL) + 3600);
i++;
/* The classification attribute.
* If not specified, the default value is CSA_CLASS_PUBLIC.
*/
attrs[i].name = CSA_ENTRY_ATTR_CLASSIFICATION;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_UINT32;
attr_val[i].item.sint32_value = CSA_CLASS_CONFIDENTIAL;
i++;
/* The type attribute. This attribute has no default value and
* must be specified.
*/
attrs[i].name = CSA_ENTRY_ATTR_TYPE;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_UINT32;
attr_val[i].item.sint32_value = CSA_TYPE_EVENT;
i++;
/* The sub-type attribute.
* If not specified, the default value is CSA_SUBTYPE_APPOINTMENT
*/
attrs[i].name = CSA_ENTRY_ATTR_SUBTYPE;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_STRING;
attr_val[i].item.string_value = CSA_SUBTYPE_APPOINTMENT;
i++;
/* The summary attribute */
attrs[i].name = CSA_ENTRY_ATTR_SUMMARY;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_STRING;
attr_val[i].item.string_value = argv6;
attrs[i].attribute_extensions = NULL;
i++;
/* The recurrence rule attribute.
* If not specified, the entry is a one time entry.
* The recurrence rule "D1 #3" specifies that the
* entry is to be repeated daily for 3 days.
*/
attrs[i].name = CSA_ENTRY_ATTR_RECURRENCE_RULE;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_STRING;
attr_val[i].item.string_value = argv7;
i++;
/* The audio reminder attribute.
* The lead time of a reminder is a CSA_time_duration value
* which is expressed in the ISO 8601 standard.
* For example, a lead time of 5 minutes is expressed as
* the string "+PT300S". A negative lead time of 5 minutes
* is expressed as "-PT300S".
*/
attrs[i].name = CSA_ENTRY_ATTR_AUDIO_REMINDER;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_REMINDER;
attr_val[i].item.reminder_value = &audio;
memset((void *)&audio, NULL, sizeof(audio));
audio.lead_time = "+PT300S"; i++;
/* The mail reminder attribute.
* The e-mail address is specified in the reminder_data field
* This reminder has a lead time of one day.
*/
attrs[i].name = CSA_ENTRY_ATTR_MAIL_REMINDER;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_REMINDER;
attr_val[i].item.reminder_value = &mail;
memset((void *)&mail, NULL, sizeof(mail));
mail.lead_time = "+PT86400S";
mail.reminder_data.data = "someuser@somehost";
mail.reminder_data.size = strlen(mail.reminder_data.data);
i++;
/* add an entry with the specified attribute values */
stat = csa_add_entry(cal, i, attrs, &newentry, NULL);
if (stat == CSA_SUCCESS)
csa_free((CSA_buffer)newentry);
To Look Up Entries in a Calendar
Example 10-7 Looking up Calendar Entries; Reading Attribute Values
#include <csa/csa.h>
CSA_return_code stat;
CSA_session_handle cal;
CSA_attribute attrs[4];
CSA_attribute_value attr_val[4];
CSA_enum ops[4];
CSA_uint32 i;
CSA_uint32 num_entries;
CSA_entry_handle *entries;
CSA_uint32 num_attributes;
CSA_attribute *entry_attrs;
/* find all entries with the following criteria:
* (all appointments in the month of August 1996 UTC time)
* start date equals to or after 00:00:00 Aug 1 1996 UTC time
* and start date before 00:00:00 Sep 1 1996 UTC time
* and type equals to CSA_TYPE_EVENT
* and sub-type equals CSA_SUBTYPE_APPOINTMENT
*/
i = 0;
/* start date equals to or after 00:00:00 Aug 1 1996 UTC time */
attrs[i].name = CSA_ENTRY_ATTR_START_DATE;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_DATE_TIME;
attr_val[i].item.date_time_value = "19960801T000000Z";
ops[i] = CSA_MATCH_GREATER_THAN_OR_EQUAL_TO;
i++;
/* start date before 00:00:00 Sep 1 1996 UTC time */
attrs[i].name = CSA_ENTRY_ATTR_START_DATE;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_DATE_TIME;
attr_val[i].item.date_time_value = "19960901T000000Z"
ops[i] = CSA_MATCH_LESS_THAN;
i++;
/* type equals to CSA_TYPE_EVENT */
attrs[i].name = CSA_ENTRY_ATTR_TYPE;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_UINT32;
attr_val[i].item.sint32_value = CSA_TYPE_EVENT;
ops[i] = CSA_MATCH_EQUAL_TO;
i++;
/* sub-type equals CSA_SUBTYPE_APPOINTMENT */
attrs[i].name = CSA_ENTRY_ATTR_SUBTYPE;
attrs[i].value = &attr_val[i];
attrs[i].attribute_extensions = NULL;
attr_val[i].type = CSA_VALUE_STRING;
attr_val[i].item.string_value = CSA_SUBTYPE_APPOINTMENT;
ops[i] = CSA_MATCH_EQUAL_TO;
i++;
/* do look up */
stat = csa_list_entries(csa, i, attrs, ops, &num_entries, &entries, NULL);
if (stat == CSA_SUCCESS) {
for (i = 0; i < num_entries; i++) {
/* get all attribute values of the entry;
* specifying 0 for number_names and NULL for attribute_names
* will cause all attribute values to be returned
*/
stat = csa_read_entry_attributes(cal, entries[i], 0, NULL,
&num_attributes, &entry_attrs,
NULL); if (stat == CSA_SUCCESS) {
/* use the returned attribute values,
* free the memory when done
*/
csa_free(entry_attrs);
} else {
/* handle error */
}
}
} else {
/* handle error */
}
Example: Change the end time of the returned appointments to be
one hour later.
CSA_attribute_reference name = CSA_ENTRY_ATTR_END_DATE;
char buffer[80];
time_t endtime;
CSA_entry_handle new_entry;
for (i = 0; i < num_entries; i++) {
/* get the end time of the appointment */
stat = csa_read_entry_attributes(cal, entries[i], 0, &name,
&num_attributes, &entry_attrs, NULL);
if (stat == CSA_SUCCESS) {
/* change the end time to be one hour later */
from_iso8601_time(entry_attrs[0].value->item.date_time_value, &endtime);
endtime += 60*60 /* number of second in an hour */
to_iso8601_time(endtime, buffer);
attrs[0].name = CSA_ENTRY_ATTR_END_DATE;
attrs[0].value = &attr_val[i];
attrs[0].attribute_extensions = NULL;
attr_val[0].type = CSA_VALUE_DATE_TIME;
attr_val[0].item.date_time_value = buffer;
stat = csa_update_entry_attributes(cal, entries[0], CSA_SCOPE_ALL,
CSA_FALSE, 1, attrs, &new_entry,
NULL);
if (stat == CSA_SUCCESS) {
csa_free(new_entry);
} else {
/* handle error */
}
csa_free(entry_attrs);
} else {
/* handle error */
}
}
To Update a Calendar Entry
Example 10-8 Changing End Time of Returned Appointments: One Hour Later
CSA_attribute_reference name = CSA_ENTRY_ATTR_END_DATE;
char buffer[80];
time_t endtime;
CSA_entry_handle new_entry;
for (i = 0; i < num_entries; i++) {
/* get the end time of the appointment */
stat = csa_read_entry_attributes(cal, entries[i], 0, &name,
&num_attributes, &entry_attrs, NULL);
if (stat == CSA_SUCCESS) {
/* change the end time to be one hour later */
from_iso8601_time(entry_attrs[0].value->item.date_time_value, &endtime);
endtime += 60*60 /* number of second in an hour */
to_iso8601_time(endtime, buffer);
attrs[0].name = CSA_ENTRY_ATTR_END_DATE;
attrs[0].value = &attr_val[i];
attrs[0].attribute_extensions = NULL;
attr_val[0].type = CSA_VALUE_DATE_TIME;
attr_val[0].item.date_time_value = buffer;
stat = csa_update_entry_attributes(cal, entries[0], CSA_SCOPE_ALL,
CSA_FALSE, 1, attrs, &new_entry,
NULL); if (stat == CSA_SUCCESS) {
csa_free(new_entry);
} else {
/* handle error */
}
csa_free(entry_attrs);
} else {
/* handle error */
}
}
To Register Callback and Keep Reminders
/* The example code shows the usage of csa_register_callback,
* csa_read_next_reminder, and csa_call_callbacks.
* The skeleton code registers a callback routine for
* events CSA_CB_ENTRY_ADDED, CSA_CB_ENTRY_DELETED, and
* CSA_CB_ENTRY_UPDATED; and another callback routine for the
* CSA_CB_CALENDAR_ATTRIBUTE_UPDATED event.
* It also shows how to set up a timer for reminder delivery.
* Two utilities routines for conversion between time representation
* in the ISO 8601 format and the tick representing time in seconds
* since 00:00:00 UTC 1/1/70 are also included.
*/
#include <csa/csa.h>
#include <time.h>
#include <unistd.h>
CSA_session_handle cal; /* a calendar session */
time_t run_time; /* the time the reminders is to be run */
CSA_uint32 num_rems; /* number of reminders returned */
CSA_reminder_reference *rems; /* an array of reminder information */
void
set_up_callback_handler()
{
CSA_return_code stat;
CSA_flags flags;
/* Xt based applications can use the CSA_X_XT_APP_CONTEXT_EXT
* extension to specify the Xt application context so that
* callback routines will be invoked asynchronously
*
* CSA_extension callback_ext;
* callback_ext.item_code = CSA_X_XT_APP_CONTEXT_EXT;
* callback_ext.item_data = (CSA_uint32)application_context;
* callback_ext.extension_flags = CSA_EXT_LAST_ELEMENT;
*
* Pass the callback_ext as the last parameter to
* csa_register_callback.
*/
flags = CSA_CB_ENTRY_ADDED|CSA_CB_ENTRY_DELETED|CSA_CB_ENTRY_UPDATED;
stat = csa_register_callback(cal, flags, entry_update_callback,
NULL, NULL);
if (stat != CSA_SUCCESS) {
/* error handling code */
}
stat = csa_register_callback(cal, CSA_CB_CALENDAR_ATTRIBUTE_UPDATED,
calendar_update_callback, NULL, NULL);
if (stat != CSA_SUCCESS) {
/* error handling code */
}
}
/* * This routine polls the library and causes the registered
* callback to be invoked if the interested event has occurred.
* If an application does not use the CSA_X_XT_APP_CONTEXT_EXT
* extension to set up asynchronously callback invocation,
* it needs to call csa_call_callbacks to force the invocation
* of callbacks.
*/
check_events(CSA_flags event)
{
csa_call_callbacks(cal, event, NULL);
}
/*
* This is the callback routine for events CSA_CB_ENTRY_ADDED,
* CSA_CB_ENTRY_ADDED, and CSA_CB_ENTRY_UPDATED.
*/
void
entry_update_callback(
CSA_session_handle cal,
CSA_flags flags,
CSA_buffer call_data,
CSA_buffer client_data,
CSA_extension *ext)
{
/* An entry is either added, deleted or updated.
* Possible things to do in this callback routine:
*
* 1. Update the calendar view, or
* 2. If this is your own calendar, update reminder information.
*
* The sample code in this routine updates reminder information
*/ reset_reminder();
}
/*
* This is the callback routine for the CSA_CB_CALENDAR_ATTRIBUTE_UPDATED
* event
*/
void
calendar_update_callback(
CSA_session_handle cal,
CSA_flags flags,
CSA_buffer call_data,
CSA_buffer client_data,
CSA_extension *ext)
{
/* update calendar attributes */
}
/*
* This routine updates reminder information:
* - get rid of existing information if any
* - call csa_read_next_reminder() to get the next
* reminder to deliver
* - check the run time and set timer
*/
void
reset_reminder() {
CSA_return_code stat;
time_t current_time;
char isotime[BUFSIZ];
CSA_uint32 number_reminders;
CSA_reminder_reference *reminders;
current_time = time(NULL);
/* get rid of existing information */
if (rems) {
/* this comparison is to make sure that we don't lose
* any reminders whose run time is between the last
* run time and the current time
*/
if (current_time > run_time)
current_time = run_time;
csa_free((CSA_buffer)rems);
}
to_iso8601_time(current_time, isotime);
stat = csa_read_next_reminder(cal, 0, NULL, isotime,
&number_reminders, &reminders, NULL);
if (stat == CSA_SUCCESS && num_rems > 0) {
num_rems = number_reminders;
rems = reminders;
/* Set timer to deliver the reminder.
* sigset() should be used to set up the signal
* disposition for the SIGALRM signal.
*/
from_iso8601_time(reminders[0].run_time, &run_time);
remain = run_time - time(NULL);
alarm((remain > 0) ? remain : 1);
/* Xt based application can set the timer using
* XtAppAddTimeOut
*/
}
}
/*
* This routine converts a time value in the iso8601 format to
* a tick (representing time in seconds since 00:00:00 UTC, 1/1/70).
* The tick is adjusted to the local time.
*/ int from_iso8601_time(char *buf, time_t *tick_out)
{
int year, month, day, hour, min, sec;
struct tm time_str;
sscanf(buf, "%4d%2d%2dT%2d%2d%2dZ",
&year, &month, &day, &hour, &min, &sec);
time_str.tm_year = year - 1900;
time_str.tm_mon = month - 1;
time_str.tm_mday = day;
time_str.tm_hour = hour;
time_str.tm_min = min;
time_str.tm_sec = sec;
time_str.tm_isdst = -1;
*tick_out = mktime(&time_str);
if (*tick_out != (long)-1) {
/* adjust for local time zone */
if (time_str.tm_isdst == 0)
*tick_out -= timezone;
else
*tick_out -= altzone;
return(0);
} else
return(-1);
}
/*
* This routine converts a tick (representing time in seconds
* since 00:00:00 UTC, 1/1/70) to the iso8601 format.
*/
int
to_iso8601_time(time_t tick, char *buf_out)
{
struct tm time_str;
if (gmtime_r(&tick, &time_str)) {
/* format string forces fixed width (zero-padded) fields */
sprintf(buf_out, "%04d%02d%02dT%02d%02d%02dZ",
time_str.tm_year + 1900,
time_str.tm_mon + 1,
time_str.tm_mday,
time_str.tm_hour,
time_str.tm_min,
time_str.tm_sec);
return (0);
} else {
return (-1);
}
}