cdesktopenv/cde/lib/csa/attr.c

2002 lines
49 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: attr.c /main/1 1996/04/21 19:21:41 drk $ */
/*
* (c) Copyright 1993, 1994 Hewlett-Packard Company
* (c) Copyright 1993, 1994 International Business Machines Corp.
* (c) Copyright 1993, 1994 Novell, Inc.
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
*/
#include <EUSCompat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include "attr.h"
#include "cmsdata.h"
#include "nametbl.h"
#include "free.h"
#include "misc.h"
#include "iso8601.h"
#include "lutil.h"
/*
* calendar attributes defined by the library
* Note: index zero is not used
*/
char *_CSA_calendar_attribute_names[] = {
NULL,
"-//XAPIA/CSA/CALATTR//NONSGML Access List//EN",
"-//XAPIA/CSA/CALATTR//NONSGML Calendar Name//EN",
"-//XAPIA/CSA/CALATTR//NONSGML Calendar Owner//EN",
"-//XAPIA/CSA/CALATTR//NONSGML Calendar Size//EN",
"-//XAPIA/CSA/CALATTR//NONSGML Character Set//EN",
"-//XAPIA/CSA/CALATTR//NONSGML Country//EN",
"-//XAPIA/CSA/CALATTR//NONSGML Date Created//EN",
"-//XAPIA/CSA/CALATTR//NONSGML Language//EN",
"-//XAPIA/CSA/CALATTR//NONSGML Number Entries//EN",
"-//XAPIA/CSA/CALATTR//NONSGML Product Identifier//EN",
"-//XAPIA/CSA/CALATTR//NONSGML Time Zone//EN",
"-//XAPIA/CSA/CALATTR//NONSGML Version//EN",
"-//XAPIA/CSA/CALATTR//NONSGML Work Schedule//EN",
"-//CDE_XAPIA_PRIVATE/CSA/CALATTR//NONSGML Server Version//EN",
"-//CDE_XAPIA_PRIVATE/CSA/CALATTR//NONSGML Data Version//EN",
"-//CDE_XAPIA_PRIVATE/CSA/CALATTR//NONSGML Calendar Delimiter//EN"
};
/*
* entry attributes defined by the library
* Note: index zero is not used
*/
char *_CSA_entry_attribute_names[] = {
NULL,
"-//XAPIA/CSA/ENTRYATTR//NONSGML Attendee List//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Audio Reminder//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Classification//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Date Completed//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Date Created//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Description//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Due Date//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML End Date//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Exception Dates//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Exception Rule//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Flashing Reminder//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Last Update//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Mail Reminder//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Number Recurrences//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Organizer//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Popup Reminder//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Priority//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Recurrence Rule//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Recurring Dates//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Reference Identifier//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Sequence Number//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Sponsor//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Start Date//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Status//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Subtype//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Summary//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Time Transparency//EN",
"-//XAPIA/CSA/ENTRYATTR//NONSGML Type//EN",
"-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Show Time//EN",
"-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Type//EN",
"-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Times//EN",
"-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Interval//EN",
"-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Occurrence Number//EN",
"-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Sequence End Date//EN",
"-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Entry Delimiter//EN"
};
/*
* Values for entry attribute CSA_ENTRY_ATTR_SUBTYPE
*/
char *_CSA_entry_subtype_values[] = {
"-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Appointment//EN",
"-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Class//EN",
"-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Holiday//EN",
"-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Meeting//EN",
"-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Miscellaneous//EN",
"-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Phone Call//EN",
"-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Sick Day//EN",
"-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Special Occasion//EN",
"-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Travel//EN",
"-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Vacation//EN",
};
/* list of calendar attributes and value type */
_DtCmAttrInfo _CSA_cal_attr_info[] =
{
/* first element is not used */
{ 0, -1, 0, _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
{ CSA_CAL_ATTR_ACCESS_LIST_I, CSA_VALUE_ACCESS_LIST, 1,
_DtCm_old_attr_unknown, B_FALSE, B_FALSE },
{ CSA_CAL_ATTR_CALENDAR_NAME_I, CSA_VALUE_STRING, 1,
_DtCm_old_attr_unknown, B_TRUE, B_TRUE },
{ CSA_CAL_ATTR_CALENDAR_OWNER_I, CSA_VALUE_CALENDAR_USER, 1,
_DtCm_old_attr_unknown, B_TRUE, B_TRUE },
{ CSA_CAL_ATTR_CALENDAR_SIZE_I, CSA_VALUE_UINT32, 4,
_DtCm_old_attr_unknown, B_TRUE, B_TRUE },
{ CSA_CAL_ATTR_CHARACTER_SET_I, CSA_VALUE_STRING, 4,
_DtCm_old_attr_unknown, B_TRUE, B_TRUE },
{ CSA_CAL_ATTR_COUNTRY_I, CSA_VALUE_STRING, 0,
_DtCm_old_attr_unknown, B_FALSE, B_FALSE },
{ CSA_CAL_ATTR_DATE_CREATED_I, CSA_VALUE_DATE_TIME, 4,
_DtCm_old_attr_unknown, B_TRUE, B_TRUE },
{ CSA_CAL_ATTR_LANGUAGE_I, CSA_VALUE_STRING, 0,
_DtCm_old_attr_unknown, B_FALSE, B_FALSE },
{ CSA_CAL_ATTR_NUMBER_ENTRIES_I, CSA_VALUE_UINT32, 1,
_DtCm_old_attr_unknown, B_TRUE, B_TRUE },
{ CSA_CAL_ATTR_PRODUCT_IDENTIFIER_I, CSA_VALUE_STRING, 1,
_DtCm_old_attr_unknown, B_TRUE, B_TRUE },
{ CSA_CAL_ATTR_TIME_ZONE_I, CSA_VALUE_STRING, 4,
_DtCm_old_attr_unknown, B_TRUE, B_TRUE },
{ CSA_CAL_ATTR_VERSION_I, CSA_VALUE_STRING, 1,
_DtCm_old_attr_unknown, B_TRUE, B_TRUE },
{ CSA_CAL_ATTR_WORK_SCHEDULE_I, CSA_VALUE_OPAQUE_DATA, 0,
_DtCm_old_attr_unknown, B_FALSE, B_FALSE },
{ CSA_X_DT_CAL_ATTR_SERVER_VERSION_I, CSA_VALUE_UINT32, 1,
_DtCm_old_attr_unknown, B_TRUE, B_TRUE },
{ CSA_X_DT_CAL_ATTR_DATA_VERSION_I, CSA_VALUE_UINT32, 1,
_DtCm_old_attr_unknown, B_TRUE, B_TRUE },
{ CSA_X_DT_CAL_ATTR_CAL_DELIMITER_I, CSA_VALUE_STRING, -1,
_DtCm_old_attr_unknown, B_TRUE, B_TRUE }
};
/* list of entry attributes and value type */
_DtCmAttrInfo _CSA_entry_attr_info[] =
{
/* first element is not used */
{ 0, -1, 0, _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
{ CSA_ENTRY_ATTR_ATTENDEE_LIST_I, CSA_VALUE_ATTENDEE_LIST,
0, _DtCm_old_attr_unknown, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_AUDIO_REMINDER_I, CSA_VALUE_REMINDER,
1, _DtCm_old_attr_beep_reminder, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_CLASSIFICATION_I, CSA_VALUE_UINT32,
2, _DtCm_old_attr_privacy, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_DATE_COMPLETED_I, CSA_VALUE_DATE_TIME,
4, _DtCm_old_attr_unknown, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_DATE_CREATED_I, CSA_VALUE_DATE_TIME,
4, _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
{ CSA_ENTRY_ATTR_DESCRIPTION_I, CSA_VALUE_STRING,
4, _DtCm_old_attr_unknown, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_DUE_DATE_I, CSA_VALUE_DATE_TIME,
4, _DtCm_old_attr_unknown, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_END_DATE_I, CSA_VALUE_DATE_TIME,
1, _DtCm_old_attr_duration, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_EXCEPTION_DATES_I, CSA_VALUE_DATE_TIME_LIST,
4, _DtCm_old_attr_unknown, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_EXCEPTION_RULE_I, CSA_VALUE_STRING,
0, _DtCm_old_attr_unknown, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_FLASHING_REMINDER_I, CSA_VALUE_REMINDER,
1, _DtCm_old_attr_flash_reminder, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_LAST_UPDATE_I, CSA_VALUE_DATE_TIME,
4, _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
{ CSA_ENTRY_ATTR_MAIL_REMINDER_I, CSA_VALUE_REMINDER,
1, _DtCm_old_attr_mail_reminder, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_NUMBER_RECURRENCES_I, CSA_VALUE_UINT32,
4, _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
{ CSA_ENTRY_ATTR_ORGANIZER_I, CSA_VALUE_CALENDAR_USER,
1, _DtCm_old_attr_author, B_TRUE, B_TRUE },
{ CSA_ENTRY_ATTR_POPUP_REMINDER_I, CSA_VALUE_REMINDER,
1, _DtCm_old_attr_popup_reminder, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_PRIORITY_I, CSA_VALUE_UINT32,
4, _DtCm_old_attr_unknown, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_RECURRENCE_RULE_I, CSA_VALUE_STRING,
4, _DtCm_old_attr_unknown, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_RECURRING_DATES_I, CSA_VALUE_DATE_TIME_LIST,
0, _DtCm_old_attr_unknown, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I, CSA_VALUE_OPAQUE_DATA,
1, _DtCm_old_attr_id, B_TRUE, B_TRUE },
{ CSA_ENTRY_ATTR_SEQUENCE_NUMBER_I, CSA_VALUE_UINT32,
0, _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
{ CSA_ENTRY_ATTR_SPONSOR_I, CSA_VALUE_CALENDAR_USER,
4, _DtCm_old_attr_unknown, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_START_DATE_I, CSA_VALUE_DATE_TIME,
1, _DtCm_old_attr_time, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_STATUS_I, CSA_VALUE_UINT32,
2, _DtCm_old_attr_status, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_SUBTYPE_I, CSA_VALUE_STRING,
1, _DtCm_old_attr_type2, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_SUMMARY_I, CSA_VALUE_STRING,
1, _DtCm_old_attr_what, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_TIME_TRANSPARENCY_I, CSA_VALUE_SINT32,
4, _DtCm_old_attr_unknown, B_FALSE, B_FALSE },
{ CSA_ENTRY_ATTR_TYPE_I, CSA_VALUE_UINT32,
1, _DtCm_old_attr_type, B_FALSE, B_FALSE },
{ CSA_X_DT_ENTRY_ATTR_SHOWTIME_I, CSA_VALUE_SINT32,
2, _DtCm_old_attr_showtime, B_FALSE, B_FALSE },
{ CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I, CSA_VALUE_SINT32,
1, _DtCm_old_attr_repeat_type, B_FALSE, B_TRUE },
{ CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I, CSA_VALUE_UINT32,
1, _DtCm_old_attr_repeat_times, B_FALSE, B_TRUE },
{ CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I, CSA_VALUE_UINT32,
3, _DtCm_old_attr_repeat_nth_interval, B_FALSE, B_TRUE },
{ CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I, CSA_VALUE_SINT32,
3, _DtCm_old_attr_repeat_nth_weeknum, B_FALSE, B_TRUE },
{ CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE_I, CSA_VALUE_DATE_TIME,
3, _DtCm_old_attr_end_date, B_FALSE, B_TRUE },
{ CSA_X_DT_ENTRY_ATTR_ENTRY_DELIMITER_I, CSA_VALUE_STRING,
-1, _DtCm_old_attr_unknown, B_TRUE, B_TRUE }
};
/*****************************************************************************
* forward declaration of static functions used within the file
*****************************************************************************/
static CSA_return_code check_predefined_attrs(
int fversion,
uint num_attrs,
cms_attribute *attrs,
boolean_t checkreadonly,
_DtCmNameTable *tbl,
uint num_defined,
_DtCmAttrInfo *our_attrs);
static CSA_return_code convert_cms_user_to_csa_user(char *from,
CSA_calendar_user **to);
static CSA_return_code hash_entry_attrs(uint num_attrs, CSA_attribute *csaattrs,
cms_attribute *cmsattrs, uint *hnum, cms_attribute **hattrs, uint *num);
static CSA_return_code hash_cal_attrs(uint num_attrs, CSA_attribute *csaattrs,
cms_attribute *cmsattrs, uint *hnum, cms_attribute **hattrs, uint *num);
static CSA_return_code _DtCm_check_hashed_entry_attributes(
int fvers,
uint num_attrs,
cms_attribute *attrs,
CSA_flags utype);
static CSA_return_code _DtCm_check_hashed_cal_attributes(
int fvers,
uint num_attrs,
cms_attribute *attrs,
char *owner,
char *cname,
boolean_t checkreadonly,
boolean_t firsttime,
boolean_t csatype);
static CSA_return_code _CheckNameAtHost(char *owner, char *value);
static CSA_return_code _CheckCalendarOwner(char *owner, int type, char *name);
static CSA_return_code _CheckCalendarName(char *owner, char *cname,
cms_attribute_value *val);
/*****************************************************************************
* extern functions used in the library
*****************************************************************************/
/*
* For each calendar attribute, if it is a predefined attribute,
* check that the data type is correct.
* If checkreadonly is B_TRUE, also check that it's not readonly.
*/
extern CSA_return_code
_DtCm_check_cal_csa_attributes(
int fvers,
uint num_attrs,
CSA_attribute *attrs,
char *cname,
boolean_t checkreadonly,
boolean_t firsttime,
boolean_t checkattrnum)
{
CSA_return_code stat;
uint hnum;
cms_attribute *hattrs;
uint realnum;
if ((stat = hash_cal_attrs(num_attrs, attrs, NULL, &hnum, &hattrs,
&realnum)) != CSA_SUCCESS)
return (stat);
if (checkattrnum == B_TRUE && realnum == 0) {
free(hattrs);
return (CSA_E_INVALID_PARAMETER);
}
stat = _DtCm_check_hashed_cal_attributes(fvers, hnum, hattrs,
NULL, cname, checkreadonly, firsttime, B_TRUE);
free(hattrs);
return (stat);
}
extern CSA_return_code
_DtCm_check_cal_cms_attributes(
int fvers,
uint num_attrs,
cms_attribute *attrs,
char *owner,
char *cname,
boolean_t checkreadonly,
boolean_t firsttime,
boolean_t checkattrnum)
{
CSA_return_code stat;
uint hnum;
cms_attribute *hattrs;
uint realnum;
if ((stat = hash_cal_attrs(num_attrs, NULL, attrs, &hnum, &hattrs,
&realnum)) != CSA_SUCCESS)
return (stat);
if (checkattrnum == B_TRUE && realnum == 0) {
free(hattrs);
return (CSA_E_INVALID_PARAMETER);
}
stat = _DtCm_check_hashed_cal_attributes(fvers, hnum, hattrs,
owner, cname, checkreadonly, firsttime, B_FALSE);
free(hattrs);
return (stat);
}
extern CSA_return_code
_DtCm_check_entry_attributes(
int fvers,
uint num_attrs,
CSA_attribute *attrs,
CSA_flags utype,
boolean_t checkattrnum)
{
CSA_return_code stat;
uint hnum;
cms_attribute *hattrs;
uint realnum;
if ((stat = hash_entry_attrs(num_attrs, attrs, NULL, &hnum, &hattrs,
&realnum)) != CSA_SUCCESS)
return (stat);
if (checkattrnum == B_TRUE && realnum == 0) {
free(hattrs);
return (CSA_E_INVALID_PARAMETER);
}
stat = _DtCm_check_hashed_entry_attributes(fvers, hnum, hattrs,
utype);
free(hattrs);
return (stat);
}
extern CSA_return_code
_DtCm_check_entry_cms_attributes(
int fvers,
uint num_attrs,
cms_attribute *attrs,
CSA_flags utype,
boolean_t checkattrnum)
{
CSA_return_code stat;
uint hnum;
cms_attribute *hattrs;
uint realnum;
if ((stat = hash_entry_attrs(num_attrs, NULL, attrs, &hnum, &hattrs,
&realnum)) != CSA_SUCCESS)
return (stat);
if (checkattrnum == B_TRUE && realnum == 0) {
free(hattrs);
return (CSA_E_INVALID_PARAMETER);
}
stat = _DtCm_check_hashed_entry_attributes(fvers, hnum, hattrs,
utype);
free(hattrs);
return (stat);
}
/*
* copy attributes
* attributes with a name but NULL value is allowed
* attributes with null names are ignored
* validity of attributes should be checked before calling this routine
*
* Note: the first entry is not used
*/
extern CSA_return_code
_DtCm_copy_cms_attributes(
uint srcsize,
cms_attribute *srcattrs,
uint *dstsize,
cms_attribute **dstattrs)
{
int i, j;
CSA_return_code stat = CSA_SUCCESS;
cms_attribute *attrs;
if (dstsize == NULL || dstattrs == NULL)
return (CSA_E_INVALID_PARAMETER);
*dstsize = 0;
*dstattrs = NULL;
if (srcsize == 0)
return (CSA_SUCCESS);
if ((attrs = calloc(1, sizeof(cms_attribute) * (srcsize + 1))) == NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
/* firstr element is not used */
for (i = 1, j = 1; i <= srcsize; i++) {
if (srcattrs[i].name.name != NULL) {
if ((stat = _DtCm_copy_cms_attribute(&attrs[j],
&srcattrs[i], B_TRUE)) != CSA_SUCCESS)
break;
else
j++;
}
}
if (stat != CSA_SUCCESS && j > 1) {
_DtCm_free_cms_attributes(j, attrs);
free(attrs);
} else {
*dstsize = j - 1;
*dstattrs = attrs;
}
return(stat);
}
/*
* Frees the name and value field of the array, but not
* array itself.
* note: element 0 is not used
*/
extern void
_DtCm_free_cms_attributes(uint size, cms_attribute *attrs)
{
int i;
for (i = 0; i < size; i++) {
if (attrs[i].name.name) {
free(attrs[i].name.name);
attrs[i].name.name = NULL;
if (attrs[i].value) {
_DtCm_free_cms_attribute_value(attrs[i].value);
attrs[i].value = NULL;
}
}
}
}
/*
* Frees the name and value field of the array, but not
* array itself.
*/
extern void
_DtCm_free_attributes(uint size, CSA_attribute * attrs)
{
int i;
for (i = 0; i < size; i++) {
if (attrs[i].name) {
free(attrs[i].name);
attrs[i].name = NULL;
if (attrs[i].value) {
_DtCm_free_attribute_value(attrs[i].value);
attrs[i].value = NULL;
}
}
}
}
/*
* Free the value part of the cms_attribute structure.
* note: element 0 is not used
*/
extern void
_DtCm_free_cms_attribute_values(uint size, cms_attribute *attrs)
{
int i;
for (i = 1; i <= size; i++) {
if (attrs[i].value) {
_DtCm_free_cms_attribute_value(attrs[i].value);
attrs[i].value = NULL;
}
}
}
/*
* Free the value part of the the attribute structure.
*/
extern void
_DtCm_free_attribute_values(uint size, CSA_attribute * attrs)
{
int i;
for (i = 0; i < size; i++) {
if (attrs[i].value) {
_DtCm_free_attribute_value(attrs[i].value);
attrs[i].value = NULL;
}
}
}
extern char *
_DtCm_old_reminder_name_to_name(char *oldname)
{
if (strcmp(oldname, _DtCM_OLD_ATTR_BEEP_REMINDER) == 0)
return (CSA_ENTRY_ATTR_AUDIO_REMINDER);
else if (strcmp(oldname, _DtCM_OLD_ATTR_FLASH_REMINDER) == 0)
return (CSA_ENTRY_ATTR_FLASHING_REMINDER);
else if (strcmp(oldname, _DtCM_OLD_ATTR_MAIL_REMINDER) == 0)
return (CSA_ENTRY_ATTR_MAIL_REMINDER);
else if (strcmp(oldname, _DtCM_OLD_ATTR_POPUP_REMINDER) == 0)
return (CSA_ENTRY_ATTR_POPUP_REMINDER);
else
return (oldname);
}
extern int
_DtCm_old_reminder_name_to_index(char *oldname)
{
char *name;
name = _DtCm_old_reminder_name_to_name(oldname);
return (_DtCm_get_index_from_table(_DtCm_entry_name_tbl, name));
}
/*
* Given an attribute name, return the corresponding
* attribute number that's supported by old backends (v4 and before).
*/
extern CSA_return_code
_DtCm_get_old_attr_by_name(char *name, _DtCm_old_attrs *attr)
{
int index;
index = _DtCm_get_index_from_table(_DtCm_entry_name_tbl, name);
if (index > 0 && index <= _DtCM_DEFINED_ENTRY_ATTR_SIZE) {
if (_CSA_entry_attr_info[index].oldattr
!= _DtCm_old_attr_unknown) {
*attr = _CSA_entry_attr_info[index].oldattr;
return (CSA_SUCCESS);
} else
return (CSA_E_UNSUPPORTED_ATTRIBUTE);
} else
return (CSA_E_INVALID_ATTRIBUTE);
}
/*
* Given an attribute index, return the corresponding
* attribute number that's supported by old backends (v4 and before).
*/
extern CSA_return_code
_DtCm_get_old_attr_by_index(int index, _DtCm_old_attrs *attr)
{
if (index <= _DtCM_DEFINED_ENTRY_ATTR_SIZE) {
if (_CSA_entry_attr_info[index].oldattr
!= _DtCm_old_attr_unknown) {
*attr = _CSA_entry_attr_info[index].oldattr;
return (CSA_SUCCESS);
} else
return (CSA_E_UNSUPPORTED_ATTRIBUTE);
} else
return (CSA_E_INVALID_ATTRIBUTE);
}
/*
* copy attribute
* the attribute structure should contain valid value
* a NULL attribute value is valid
*/
extern CSA_return_code
_DtCm_copy_cms_attribute(
cms_attribute *to,
cms_attribute *from,
boolean_t copyname)
{
CSA_return_code stat = CSA_SUCCESS;
char *name;
if (to == NULL)
return (CSA_E_INVALID_PARAMETER);
/* copy the attribute name */
if (copyname) {
if ((name = strdup(from->name.name)) == NULL)
return(CSA_E_INSUFFICIENT_MEMORY);
}
if ((stat = _DtCm_copy_cms_attr_val(from->value, &to->value))
== CSA_SUCCESS) {
if (copyname) {
to->name.name = name;
to->name.num = from->name.num;
}
} else if (copyname)
free (name);
return(stat);
}
extern CSA_return_code
_DtCm_copy_cms_attr_val(cms_attribute_value *from, cms_attribute_value **to)
{
CSA_return_code stat = CSA_SUCCESS;
cms_attribute_value *val;
if (to == NULL)
return (CSA_E_INVALID_PARAMETER);
/* copy the attribute value */
if (from == NULL)
val = NULL;
else {
if ((val = (cms_attribute_value *)calloc(1,
sizeof(cms_attribute_value))) == NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
switch (from->type) {
case CSA_VALUE_BOOLEAN:
case CSA_VALUE_ENUMERATED:
case CSA_VALUE_FLAGS:
case CSA_VALUE_UINT32:
case CSA_VALUE_SINT32:
val->item.uint32_value = from->item.uint32_value;
break;
case CSA_VALUE_STRING:
case CSA_VALUE_DATE_TIME:
case CSA_VALUE_DATE_TIME_RANGE:
case CSA_VALUE_TIME_DURATION:
case CSA_VALUE_CALENDAR_USER:
if (from->item.string_value)
val->item.string_value =
strdup(from->item.string_value);
else
val->item.string_value = calloc(1, 1);
if (val->item.string_value == NULL)
stat = CSA_E_INSUFFICIENT_MEMORY;
break;
case CSA_VALUE_REMINDER:
if (from->item.reminder_value == NULL)
stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
else
stat = _DtCm_copy_reminder(
from->item.reminder_value,
&val->item.reminder_value);
break;
case CSA_VALUE_ATTENDEE_LIST:
stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
break;
case CSA_VALUE_ACCESS_LIST:
if (from->item.access_list_value &&
(val->item.access_list_value =
_DtCm_copy_cms_access_list(
from->item.access_list_value)) == NULL) {
stat = CSA_E_INSUFFICIENT_MEMORY;
}
break;
case CSA_VALUE_DATE_TIME_LIST:
if (from->item.date_time_list_value &&
(val->item.date_time_list_value =
_DtCm_copy_date_time_list(
from->item.date_time_list_value)) == NULL) {
stat = CSA_E_INSUFFICIENT_MEMORY;
}
break;
case CSA_VALUE_OPAQUE_DATA:
if (from->item.opaque_data_value) {
stat = _DtCm_copy_opaque_data(
from->item.opaque_data_value,
&val->item.opaque_data_value);
}
break;
default:
stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
break;
}
if (stat != CSA_SUCCESS)
free(val);
else
val->type = from->type;
}
if (stat == CSA_SUCCESS) {
*to = val;
}
return(stat);
}
/*
* copy the attribute name, and convert the attribute value
*/
extern CSA_return_code
_DtCm_cms2csa_attribute(cms_attribute from, CSA_attribute *to)
{
CSA_return_code stat;
char *name;
CSA_attribute_value *val;
if ((name = strdup(from.name.name)) == NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
if ((stat = _DtCm_cms2csa_attrval(from.value, &val)) == CSA_SUCCESS) {
to->name = name;
to->value = val;
} else
free(name);
return (stat);
}
extern CSA_return_code
_DtCm_cms2csa_attrval(cms_attribute_value *from, CSA_attribute_value **to)
{
CSA_return_code stat = CSA_SUCCESS;
CSA_attribute_value *val;
if (to == NULL)
return (CSA_E_INVALID_PARAMETER);
/* copy the attribute value */
if (from == NULL)
val = NULL;
else {
if ((val = (CSA_attribute_value *)calloc(1,
sizeof(CSA_attribute_value))) == NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
switch (from->type) {
case CSA_VALUE_BOOLEAN:
case CSA_VALUE_ENUMERATED:
case CSA_VALUE_FLAGS:
case CSA_VALUE_UINT32:
case CSA_VALUE_SINT32:
val->item.uint32_value = from->item.uint32_value;
break;
case CSA_VALUE_STRING:
case CSA_VALUE_DATE_TIME:
case CSA_VALUE_DATE_TIME_RANGE:
case CSA_VALUE_TIME_DURATION:
if (from->item.string_value)
val->item.string_value =
strdup(from->item.string_value);
else
val->item.string_value = calloc(1, 1);
if (val->item.string_value == NULL)
stat = CSA_E_INSUFFICIENT_MEMORY;
break;
case CSA_VALUE_REMINDER:
if (from->item.reminder_value == NULL)
stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
else
stat = _DtCm_copy_reminder(
from->item.reminder_value,
&val->item.reminder_value);
break;
case CSA_VALUE_CALENDAR_USER:
if (from->item.calendar_user_value == NULL)
stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
else
stat = convert_cms_user_to_csa_user(
from->item.calendar_user_value,
&val->item.calendar_user_value);
break;
case CSA_VALUE_ACCESS_LIST:
stat = _DtCm_cms2csa_access_list(
from->item.access_list_value,
&val->item.access_list_value);
break;
case CSA_VALUE_ATTENDEE_LIST:
stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
break;
case CSA_VALUE_DATE_TIME_LIST:
if (from->item.date_time_list_value &&
(val->item.date_time_list_value =
_DtCm_copy_date_time_list(
from->item.date_time_list_value)) == NULL) {
stat = CSA_E_INSUFFICIENT_MEMORY;
}
break;
case CSA_VALUE_OPAQUE_DATA:
if (from->item.opaque_data_value) {
stat = _DtCm_copy_opaque_data(
from->item.opaque_data_value,
&val->item.opaque_data_value);
} else
val->item.opaque_data_value = NULL;
break;
default:
stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
break;
}
if (stat != CSA_SUCCESS)
free(val);
else
val->type = from->type;
}
if (stat == CSA_SUCCESS) {
*to = val;
}
return(stat);
}
extern void
_DtCm_free_cms_attribute_value(cms_attribute_value *val)
{
if (val == NULL)
return;
switch (val->type) {
case CSA_VALUE_STRING:
case CSA_VALUE_DATE_TIME:
case CSA_VALUE_DATE_TIME_RANGE:
case CSA_VALUE_TIME_DURATION:
case CSA_VALUE_CALENDAR_USER:
if (val->item.string_value)
free(val->item.string_value);
break;
case CSA_VALUE_REMINDER:
if (val->item.reminder_value)
_DtCm_free_reminder(val->item.reminder_value);
break;
case CSA_VALUE_ACCESS_LIST:
if (val->item.access_list_value)
_DtCm_free_cms_access_entry(val->item.access_list_value);
break;
case CSA_VALUE_DATE_TIME_LIST:
if (val->item.date_time_list_value)
_DtCm_free_date_time_list(
val->item.date_time_list_value);
break;
case CSA_VALUE_OPAQUE_DATA:
if (val->item.opaque_data_value) {
_DtCm_free_opaque_data(val->item.opaque_data_value);
}
break;
}
free(val);
}
extern void
_DtCm_free_attribute_value(CSA_attribute_value *val)
{
if (val == NULL)
return;
switch (val->type) {
case CSA_VALUE_STRING:
case CSA_VALUE_DATE_TIME:
case CSA_VALUE_DATE_TIME_RANGE:
case CSA_VALUE_TIME_DURATION:
if (val->item.string_value)
free(val->item.string_value);
break;
case CSA_VALUE_REMINDER:
if (val->item.reminder_value)
_DtCm_free_reminder(val->item.reminder_value);
break;
case CSA_VALUE_ACCESS_LIST:
if (val->item.access_list_value)
_DtCm_free_csa_access_list(val->item.access_list_value);
break;
case CSA_VALUE_CALENDAR_USER:
if (val->item.calendar_user_value) {
if (val->item.calendar_user_value->user_name)
free(val->item.calendar_user_value->user_name);
if (val->item.calendar_user_value->calendar_address)
free(val->item.calendar_user_value->user_name);
free(val->item.calendar_user_value);
}
break;
case CSA_VALUE_DATE_TIME_LIST:
if (val->item.date_time_list_value)
_DtCm_free_date_time_list(
val->item.date_time_list_value);
break;
case CSA_VALUE_OPAQUE_DATA:
if (val->item.opaque_data_value) {
_DtCm_free_opaque_data(val->item.opaque_data_value);
}
break;
}
free(val);
}
extern CSA_return_code
_DtCm_set_uint32_attrval(uint numval, cms_attribute_value **attrval)
{
cms_attribute_value *val;
if ((val = (cms_attribute_value *)malloc(sizeof(cms_attribute_value)))
== NULL) {
return (CSA_E_INSUFFICIENT_MEMORY);
}
val->type = CSA_VALUE_UINT32;
val->item.uint32_value = numval;
*attrval = val;
return (CSA_SUCCESS);
}
extern CSA_return_code
_DtCm_set_sint32_attrval(int numval, cms_attribute_value **attrval)
{
cms_attribute_value *val;
if ((val = (cms_attribute_value *)malloc(sizeof(cms_attribute_value)))
== NULL) {
return (CSA_E_INSUFFICIENT_MEMORY);
}
val->type = CSA_VALUE_SINT32;
val->item.sint32_value = numval;
*attrval = val;
return (CSA_SUCCESS);
}
extern CSA_return_code
_DtCm_set_string_attrval(
char *strval,
cms_attribute_value **attrval,
CSA_enum type)
{
cms_attribute_value *val;
if (type != CSA_VALUE_STRING && type != CSA_VALUE_DATE_TIME &&
type != CSA_VALUE_DATE_TIME_RANGE &&
type != CSA_VALUE_TIME_DURATION && type != CSA_VALUE_CALENDAR_USER)
return (CSA_E_INVALID_PARAMETER);
if ((val = (cms_attribute_value *)malloc(sizeof(cms_attribute_value)))
== NULL) {
return (CSA_E_INSUFFICIENT_MEMORY);
}
val->type = type;
if (strval == NULL) {
val->item.string_value = NULL;
} else if ((val->item.string_value = strdup(strval)) == NULL) {
free(val);
return (CSA_E_INSUFFICIENT_MEMORY);
}
*attrval = val;
return (CSA_SUCCESS);
}
extern CSA_return_code
_DtCm_set_user_attrval(
char *user,
cms_attribute_value **attrval)
{
cms_attribute_value *val;
if (user == NULL) {
*attrval = NULL;
return (CSA_SUCCESS);
}
if ((val = (cms_attribute_value *)malloc(sizeof(cms_attribute_value)))
== NULL) {
return (CSA_E_INSUFFICIENT_MEMORY);
}
val->type = CSA_VALUE_CALENDAR_USER;
if ((val->item.calendar_user_value = strdup(user)) == NULL) {
free(val);
return (CSA_E_INSUFFICIENT_MEMORY);
}
*attrval = val;
return (CSA_SUCCESS);
}
extern CSA_return_code
_DtCm_set_reminder_attrval(CSA_reminder *remval, cms_attribute_value **attrval)
{
cms_attribute_value *val;
CSA_return_code stat;
if (remval == NULL)
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
if ((val = (cms_attribute_value *)malloc(sizeof(cms_attribute_value)))
== NULL) {
return (CSA_E_INSUFFICIENT_MEMORY);
}
val->type = CSA_VALUE_REMINDER;
if ((stat = _DtCm_copy_reminder(remval, &val->item.reminder_value))
!= CSA_SUCCESS) {
free(val);
return (stat);
} else {
*attrval = val;
return (CSA_SUCCESS);
}
}
extern CSA_return_code
_DtCm_set_csa_access_attrval(
cms_access_entry *aval,
CSA_attribute_value **attrval)
{
CSA_attribute_value *val;
CSA_return_code stat = CSA_SUCCESS;
if ((val = (CSA_attribute_value *)malloc(sizeof(CSA_attribute_value)))
== NULL) {
return (CSA_E_INSUFFICIENT_MEMORY);
}
val->type = CSA_VALUE_ACCESS_LIST;
if (aval == NULL) {
val->item.access_list_value = NULL;
} else {
stat = _DtCm_cms2csa_access_list(aval,
&val->item.access_list_value);
}
if (stat == CSA_SUCCESS)
*attrval = val;
else
free(val);
return (stat);
}
extern CSA_return_code
_DtCm_set_opaque_attrval(CSA_opaque_data *data, cms_attribute_value **attrval)
{
CSA_return_code stat;
cms_attribute_value *val;
if (data == NULL)
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
if ((val = (cms_attribute_value *)malloc(sizeof(cms_attribute_value)))
== NULL) {
return (CSA_E_INSUFFICIENT_MEMORY);
}
val->type = CSA_VALUE_OPAQUE_DATA;
if ((stat = _DtCm_copy_opaque_data(data, &val->item.opaque_data_value))
!= CSA_SUCCESS) {
free(val);
return (stat);
} else {
*attrval = val;
return (CSA_SUCCESS);
}
}
extern CSA_return_code
_DtCm_set_csa_uint32_attrval(uint numval, CSA_attribute_value **attrval)
{
CSA_attribute_value *val;
if ((val = (CSA_attribute_value *)malloc(sizeof(CSA_attribute_value)))
== NULL) {
return (CSA_E_INSUFFICIENT_MEMORY);
}
val->type = CSA_VALUE_UINT32;
val->item.uint32_value = numval;
*attrval = val;
return (CSA_SUCCESS);
}
extern CSA_return_code
_DtCm_set_csa_string_attrval(
char *strval,
CSA_attribute_value **attrval,
CSA_enum type)
{
CSA_attribute_value *val;
if (type != CSA_VALUE_STRING && type != CSA_VALUE_DATE_TIME &&
type != CSA_VALUE_DATE_TIME_RANGE &&
type != CSA_VALUE_TIME_DURATION && type != CSA_VALUE_CALENDAR_USER)
return (CSA_E_INVALID_PARAMETER);
if ((val = (CSA_attribute_value *)malloc(sizeof(CSA_attribute_value)))
== NULL) {
return (CSA_E_INSUFFICIENT_MEMORY);
}
val->type = type;
if (strval == NULL) {
val->item.string_value = NULL;
} else if ((val->item.string_value = strdup(strval)) == NULL) {
free(val);
return (CSA_E_INSUFFICIENT_MEMORY);
}
*attrval = val;
return (CSA_SUCCESS);
}
extern void
_DtCm_free_csa_access_list(CSA_access_list alist)
{
CSA_access_list nptr;
while (alist != NULL) {
nptr = alist->next;
if (alist->user) {
if (alist->user->user_name) {
free(alist->user->user_name);
}
if (alist->user->calendar_address) {
free(alist->user->calendar_address);
}
free(alist->user);
}
free(alist);
alist = nptr;
}
}
extern void
_DtCm_free_date_time_list(CSA_date_time_list list)
{
CSA_date_time_entry *nptr;
while (list != NULL) {
nptr = list->next;
if (list->date_time) {
free(list->date_time);
}
free(list);
list = nptr;
}
}
extern void
_DtCm_free_cms_access_entry(cms_access_entry *list)
{
cms_access_entry *nptr;
while (list != NULL) {
nptr = list->next;
if (list->user) {
free(list->user);
}
free(list);
list = nptr;
}
}
extern cms_access_entry *
_DtCm_copy_cms_access_list(cms_access_entry *alist)
{
cms_access_entry *l, *head, *prev;
boolean_t cleanup = B_FALSE;
prev = head = NULL;
while (alist != NULL) {
if ((l = (cms_access_entry *)calloc(1, sizeof(cms_access_entry)))
== NULL) {
cleanup = B_TRUE;
break;
}
if ((l->user = strdup(alist->user)) == NULL) {
free(l);
cleanup = B_TRUE;
break;
}
l->rights = alist->rights;
l->next = NULL;
if (head == NULL)
head = l;
else
prev->next = l;
prev = l;
alist = alist->next;
}
if (cleanup == B_TRUE) {
_DtCm_free_cms_access_entry(head);
head = NULL;
}
return(head);
}
extern CSA_return_code
_DtCm_cms2csa_access_list(
cms_access_entry *cmslist,
CSA_access_rights **csalist)
{
CSA_return_code stat = CSA_SUCCESS;
CSA_access_rights *to, *head, *prev;
head = prev = NULL;
while (cmslist != NULL) {
if ((to = (CSA_access_rights *)calloc(1,
sizeof(CSA_access_rights))) == NULL) {
stat = CSA_E_INSUFFICIENT_MEMORY;
break;
}
if ((to->user = (CSA_calendar_user *)calloc(1,
sizeof(CSA_calendar_user))) == NULL) {
free(to);
stat = CSA_E_INSUFFICIENT_MEMORY;
break;
}
if ((to->user->user_name = strdup(cmslist->user)) == NULL) {
free(to->user);
free(to);
stat = CSA_E_INSUFFICIENT_MEMORY;
break;
}
to->rights = cmslist->rights;
to->next = NULL;
if (head == NULL)
head = to;
else
prev->next = to;
prev = to;
cmslist = cmslist->next;
}
if (stat != CSA_SUCCESS) {
_DtCm_free_csa_access_list(head);
head = NULL;
}
*csalist = head;
return (stat);
}
extern CSA_return_code
_DtCm_csa2cms_access_list(
CSA_access_rights *csalist,
cms_access_entry **cmslist)
{
CSA_return_code stat = CSA_SUCCESS;
cms_access_entry *to, *head, *prev;
head = prev = NULL;
while (csalist != NULL) {
if ((to = (cms_access_entry *)calloc(1,
sizeof(cms_access_entry))) == NULL) {
stat = CSA_E_INSUFFICIENT_MEMORY;
break;
}
if (csalist->user->user_name) {
if ((to->user = strdup(csalist->user->user_name))
== NULL) {
stat = CSA_E_INSUFFICIENT_MEMORY;
free(to);
break;
}
} else {
stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
free(to);
break;
}
to->rights = csalist->rights;
to->next = NULL;
if (head == NULL)
head = to;
else
prev->next = to;
prev = to;
csalist = csalist->next;
}
if (stat != CSA_SUCCESS) {
_DtCm_free_cms_access_entry(head);
head = NULL;
}
*cmslist = head;
return (stat);
}
extern CSA_date_time_list
_DtCm_copy_date_time_list(CSA_date_time_list dlist)
{
CSA_date_time_entry *l, *head, *prev;
boolean_t cleanup = B_FALSE;
prev = head = NULL;
while (dlist != NULL) {
if ((l = (CSA_date_time_entry *)calloc(1,
sizeof(CSA_date_time_entry))) == NULL) {
cleanup = B_TRUE;
break;
}
if ((l->date_time = strdup(dlist->date_time)) == NULL) {
free(l);
cleanup = B_TRUE;
break;
}
l->next = NULL;
if (head == NULL)
head = l;
else
prev->next = l;
prev = l;
dlist = dlist->next;
}
if (cleanup == B_TRUE) {
_DtCm_free_date_time_list(head);
head = NULL;
}
return(head);
}
extern CSA_return_code
_DtCm_copy_reminder(CSA_reminder *from, CSA_reminder **to)
{
CSA_reminder *newval;
if ((newval = (CSA_reminder *)calloc(1, sizeof(CSA_reminder))) == NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
if (from->lead_time) {
if ((newval->lead_time = strdup(from->lead_time)) == NULL) {
free(newval);
return (CSA_E_INSUFFICIENT_MEMORY);
}
} else {
free(newval);
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
}
if (from->snooze_time)
newval->snooze_time = strdup(from->snooze_time);
else
newval->snooze_time = calloc(1, 1);
if (newval->snooze_time == NULL) {
_DtCm_free_reminder(newval);
return (CSA_E_INSUFFICIENT_MEMORY);
}
newval->repeat_count = from->repeat_count;
if (from->reminder_data.size > 0) {
newval->reminder_data.size = from->reminder_data.size;
if ((newval->reminder_data.data = malloc(
newval->reminder_data.size)) == NULL) {
_DtCm_free_reminder(newval);
return (CSA_E_INSUFFICIENT_MEMORY);
}
memcpy(newval->reminder_data.data, from->reminder_data.data,
from->reminder_data.size);
}
*to = newval;
return (CSA_SUCCESS);
}
extern void
_DtCm_free_reminder(CSA_reminder *val)
{
if (val == NULL) return;
if (val->lead_time)
free(val->lead_time);
if (val->snooze_time)
free(val->snooze_time);
if (val->reminder_data.size > 0)
free(val->reminder_data.data);
free(val);
}
extern CSA_return_code
_DtCm_copy_opaque_data(CSA_opaque_data *from, CSA_opaque_data **to)
{
CSA_opaque_data *val;
if ((val = (CSA_opaque_data *)calloc(1, sizeof(CSA_opaque_data)))
== NULL) {
return (CSA_E_INSUFFICIENT_MEMORY);
}
if (from->size > 0) {
val->size = from->size;
if ((val->data = malloc(from->size)) == NULL) {
free(val);
return (CSA_E_INSUFFICIENT_MEMORY);
}
memcpy(val->data, from->data, from->size);
} else {
val->size = 0;
val->data = NULL;
}
*to = val;
return (CSA_SUCCESS);
}
extern void
_DtCm_free_opaque_data(CSA_opaque_data *val)
{
if (val == NULL) return;
if (val->data)
free(val->data);
free(val);
}
extern void
_DtCm_get_attribute_types(uint size, int *types)
{
int i;
for (i = 1; i <= size; i++) {
types[i] = _CSA_entry_attr_info[i].type;
}
}
/******************************************************************************
* static functions used within the file
******************************************************************************/
/*
* The passed in attributes are hashed.
* For each attribute, check
* 1. type is valid and supported
* 2. if it's a date time value type, check validity of date time.
* 3. if it's a reminder value type, check validity of lead time.
* 4. if it is a defined attribute, check that the data type is correct.
* 5. if it is a defined attribute and checkreadonly is set, check
* that it's not readonly.
*/
static CSA_return_code
check_predefined_attrs(
int fver,
uint num_attrs,
cms_attribute *attrs,
boolean_t checkreadonly,
_DtCmNameTable *tbl,
uint num_defined,
_DtCmAttrInfo *our_attrs)
{
int i, index, cl;
CSA_reminder *rptr;
time_t tick;
for (i = 0; i < num_attrs; i++) {
if (attrs[i].name.name == NULL)
continue;
if (tbl == NULL)
index = i;
else
index = _DtCm_get_index_from_table(tbl,
attrs[i].name.name);
if (index > 0 && index <= num_defined) {
/* check whether the attribute is supported
* in this version
*/
if (our_attrs[index].fst_vers == 0 ||
(fver < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
fver < our_attrs[index].fst_vers))
return (CSA_E_UNSUPPORTED_ATTRIBUTE);
else if (our_attrs[index].fst_vers == -1)
return (CSA_E_INVALID_ATTRIBUTE);
/* check whether the attribute is readonly */
if (checkreadonly &&
((fver < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
our_attrs[index].nex_ro) ||
(fver >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
our_attrs[index].ex_ro)))
return (CSA_E_READONLY);
/* check data type */
if (attrs[i].value &&
attrs[i].value->type != our_attrs[index].type)
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
if (index == CSA_ENTRY_ATTR_CLASSIFICATION_I) {
cl = attrs[i].value->item.uint32_value;
if (cl < CSA_CLASS_PUBLIC ||
cl > CSA_CLASS_CONFIDENTIAL)
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
}
if (index == CSA_ENTRY_ATTR_TYPE_I) {
cl = attrs[i].value->item.uint32_value;
if (cl < CSA_TYPE_EVENT ||
cl > CSA_X_DT_TYPE_OTHER)
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
}
} else if (fver < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
return (CSA_E_INVALID_ATTRIBUTE);
}
/* check validity of value type */
if (attrs[i].value) {
if (attrs[i].value->type < CSA_VALUE_BOOLEAN ||
attrs[i].value->type > CSA_VALUE_OPAQUE_DATA)
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
/* cast the sint32_value element to the desired
* type to be safe since the value part could
* actually be a pointer to a CSA_attribute_value
*/
switch (attrs[i].value->type) {
case CSA_VALUE_DATE_TIME:
if (attrs[i].value->item.sint32_value == 0
|| _csa_iso8601_to_tick(
(char *)attrs[i].value->item.sint32_value,
&tick))
return (CSA_E_INVALID_DATE_TIME);
break;
case CSA_VALUE_REMINDER:
rptr = (CSA_reminder *)
attrs[i].value->item.sint32_value;
if (rptr == NULL || rptr->lead_time == NULL ||
_csa_iso8601_to_duration(rptr->lead_time,
&tick))
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
break;
case CSA_VALUE_ATTENDEE_LIST:
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
}
}
}
return (CSA_SUCCESS);
}
static CSA_return_code
convert_cms_user_to_csa_user(char *from, CSA_calendar_user **to)
{
CSA_calendar_user *newval;
if ((newval = (CSA_calendar_user *)calloc(1,
sizeof(CSA_calendar_user))) == NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
if (from) {
if ((newval->user_name = strdup(from)) == NULL) {
free(newval);
return (CSA_E_INSUFFICIENT_MEMORY);
}
}
*to = newval;
return (CSA_SUCCESS);
}
static CSA_return_code
hash_entry_attrs(
uint num_attrs,
CSA_attribute *csaattrs,
cms_attribute *cmsattrs,
uint *hnum,
cms_attribute **hattrs,
uint *num)
{
int i, j, index, count = 0;
cms_attribute *nattrs;
char *name;
cms_attribute_value *val;
if ((nattrs = (cms_attribute *)calloc(1,
sizeof(cms_attribute)*(num_attrs+_DtCM_DEFINED_ENTRY_ATTR_SIZE+1)))
== NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
for (i = 0, j = _DtCM_DEFINED_ENTRY_ATTR_SIZE + 1; i < num_attrs; i++) {
name = (csaattrs ? csaattrs[i].name : cmsattrs[i].name.name);
if (name == NULL)
continue;
else {
count++;
val = (csaattrs ?
((cms_attribute_value *)csaattrs[i].value) :
cmsattrs[i].value);
}
index = _DtCm_get_index_from_table(_DtCm_entry_name_tbl, name);
if (index > 0) {
if (cmsattrs) cmsattrs[i].name.num = index;
nattrs[index].name.name = name;
nattrs[index].value = val;
} else {
nattrs[j].name.name = name;
nattrs[j++].value = val;
}
}
if (num) *num = count;
*hnum = j - 1;
*hattrs = nattrs;
return (CSA_SUCCESS);
}
static CSA_return_code
hash_cal_attrs(
uint num_attrs,
CSA_attribute *csaattrs,
cms_attribute *cmsattrs,
uint *hnum,
cms_attribute **hattrs,
uint *num)
{
int i, j, index, count = 0;
cms_attribute *nattrs;
char *name;
cms_attribute_value *val;
if ((nattrs = (cms_attribute *)calloc(1,
sizeof(cms_attribute)*(num_attrs+_DtCM_DEFINED_CAL_ATTR_SIZE+1)))
== NULL)
return (CSA_E_INSUFFICIENT_MEMORY);
for (i = 0, j = _DtCM_DEFINED_CAL_ATTR_SIZE + 1; i < num_attrs; i++) {
name = (csaattrs ? csaattrs[i].name : cmsattrs[i].name.name);
if (name == NULL)
continue;
else {
count++;
val = (csaattrs ?
((cms_attribute_value *)csaattrs[i].value) :
cmsattrs[i].value);
}
index = _DtCm_get_index_from_table(_DtCm_cal_name_tbl, name);
if (index > 0) {
if (cmsattrs) cmsattrs[i].name.num = index;
nattrs[index].name.name = name;
nattrs[index].value = val;
} else {
nattrs[j].name.name = name;
nattrs[j++].value = val;
}
}
if (num) *num = count;
*hnum = j - 1;
*hattrs = nattrs;
return (CSA_SUCCESS);
}
static CSA_return_code
_DtCm_check_hashed_cal_attributes(
int fvers,
uint num_attrs,
cms_attribute *attrs,
char *owner,
char *cname,
boolean_t checkreadonly,
boolean_t firsttime,
boolean_t csatype)
{
CSA_return_code stat;
CSA_attribute_value *csaval;
cms_attribute_value *cmsval;
char *nattr = NULL; /* calendar name */
char *oattr = NULL; /* calendar owner */
char *cattr = NULL; /* character set */
char *tattr = NULL; /* time zone */
if (firsttime) {
if (attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].name.name) {
if (attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].value == NULL
|| attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].value->\
item.calendar_user_value == NULL)
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
if (csatype) {
csaval = (CSA_attribute_value *)attrs[\
CSA_CAL_ATTR_CALENDAR_OWNER_I].value;
stat = _CheckCalendarOwner(owner, csaval->type,
(csaval && csaval->item.calendar_user_value?
csaval->item.calendar_user_value->user_name:
NULL));
} else {
cmsval = attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].\
value;
stat = _CheckCalendarOwner(owner, cmsval->type,
cmsval ?
cmsval->item.calendar_user_value:NULL);
}
if (stat != CSA_SUCCESS)
return (stat);
oattr = attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].name.name;
attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].name.name = NULL;
}
if (attrs[CSA_CAL_ATTR_CALENDAR_NAME_I].name.name) {
if (attrs[CSA_CAL_ATTR_CALENDAR_NAME_I].value == NULL ||
attrs[CSA_CAL_ATTR_CALENDAR_NAME_I].value->\
item.string_value == NULL) {
if (oattr)
attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].\
name.name = oattr;
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
}
if ((stat = _CheckCalendarName(owner, cname,
attrs[CSA_CAL_ATTR_CALENDAR_NAME_I].value))
!= CSA_SUCCESS) {
if (oattr)
attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].\
name.name = oattr;
return (stat);
}
nattr = attrs[CSA_CAL_ATTR_CALENDAR_NAME_I].name.name;
attrs[CSA_CAL_ATTR_CALENDAR_NAME_I].name.name = NULL;
}
if (attrs[CSA_CAL_ATTR_CHARACTER_SET_I].name.name) {
cattr = attrs[CSA_CAL_ATTR_CHARACTER_SET_I].name.name;
attrs[CSA_CAL_ATTR_CHARACTER_SET_I].name.name = NULL;
}
if (attrs[CSA_CAL_ATTR_TIME_ZONE_I].name.name) {
tattr = attrs[CSA_CAL_ATTR_TIME_ZONE_I].name.name;
attrs[CSA_CAL_ATTR_TIME_ZONE_I].name.name = NULL;
}
}
stat = check_predefined_attrs(fvers, num_attrs+1, attrs,
checkreadonly, NULL, _DtCM_DEFINED_CAL_ATTR_SIZE,
_CSA_cal_attr_info);
if (oattr)
attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].name.name = oattr;
if (nattr)
attrs[CSA_CAL_ATTR_CALENDAR_NAME_I].name.name = nattr;
if (cattr)
attrs[CSA_CAL_ATTR_CHARACTER_SET_I].name.name = oattr;
if (tattr)
attrs[CSA_CAL_ATTR_TIME_ZONE_I].name.name = nattr;
return (stat);
}
static CSA_return_code
_DtCm_check_hashed_entry_attributes(
int fvers,
uint num_attrs,
cms_attribute *attrs,
CSA_flags utype)
{
CSA_return_code stat;
if ((stat = check_predefined_attrs(fvers, num_attrs+1, attrs,
(utype == 0 ? B_FALSE : B_TRUE), NULL,
_DtCM_DEFINED_ENTRY_ATTR_SIZE, _CSA_entry_attr_info))
!= CSA_SUCCESS) {
return (stat);
}
if (utype == CSA_CB_ENTRY_ADDED) {
/* make sure the minimum set of attribute is specified */
if (attrs[CSA_ENTRY_ATTR_START_DATE_I].value == NULL ||
attrs[CSA_ENTRY_ATTR_TYPE_I].value == NULL)
return (CSA_E_INVALID_PARAMETER);
} else if (utype == CSA_CB_ENTRY_UPDATED) {
/* type can only be set at insertion time */
if (attrs[CSA_ENTRY_ATTR_TYPE_I].name.name)
return (CSA_E_READONLY);
}
return (CSA_SUCCESS);
}
static CSA_return_code
_CheckNameAtHost(char *owner, char *value)
{
char *ptr, *optr;
int res;
/* check name part first */
if (owner == NULL) {
/* get user name of user running the application */
if ((owner = _DtCmGetUserName()) == NULL)
return (CSA_E_FAILURE);
}
if (optr = strchr(owner, '@')) *optr = '\0';
if (ptr = strchr(value, '@')) *ptr = '\0';
res = strcmp(value, owner);
if (optr) *optr = '@';
if (ptr) *ptr = '@';
if (res != 0)
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
/* check host too if it's specified */
if (ptr == NULL)
return (CSA_SUCCESS);
ptr++;
if (strcmp(ptr, (optr ? ++optr : _DtCmGetLocalHost())) == 0)
return (CSA_SUCCESS);
else
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
}
/*
* check the data type and validity of calendar owner attribute
*/
static CSA_return_code
_CheckCalendarOwner(char *owner, int type, char *user)
{
if (type != CSA_VALUE_CALENDAR_USER || user == NULL)
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
/* make sure user is the same as the one running the application */
return (_CheckNameAtHost(owner, user));
}
/*
* check the data type and validity of calendar name attribute
*/
static CSA_return_code
_CheckCalendarName(char *owner, char *cname, cms_attribute_value *val)
{
CSA_return_code stat;
char *ptr, *optr;
char user[BUFSIZ];
boolean_t isuser;
if (val->type != CSA_VALUE_STRING)
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
/* check that the attribute value is the same as the given
* calendar name
*/
if ((stat = _CheckNameAtHost(cname, val->item.string_value))
!= CSA_SUCCESS)
return (stat);
/* now make sure if cal name is a user name, it's
* the same as that of the calling user
*/
if (ptr = strchr(val->item.string_value, '@')) *ptr = '\0';
isuser = _DtCmIsUserName(val->item.string_value);
if (ptr) *ptr = '@';
/* make sure it's the same as the user running the application */
if (isuser == B_TRUE) {
sprintf(user, "%s%s", val->item.string_value, (ptr ? ptr : ""));
return (_CheckNameAtHost(owner, user));
}
/* check the host part */
if (ptr == NULL)
return (CSA_SUCCESS);
else
ptr++;
if (owner && (optr = strchr(owner, '@')))
optr++;
else
optr = _DtCmGetLocalHost();
if (strcmp(ptr, optr) == 0)
return (CSA_SUCCESS);
else
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
}