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