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); } |
#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); } |
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"); } } |
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); } |
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); } |
#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); |
#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 */ } } |
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 */ } } |
/* 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); } } |