440 lines
10 KiB
C
440 lines
10 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: updateattrs.c /main/1 1996/04/21 19:24:52 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 <stdlib.h>
|
|
#include <string.h>
|
|
#include "updateattrs.h"
|
|
#include "cmsdata.h"
|
|
#include "nametbl.h"
|
|
#include "attr.h"
|
|
|
|
|
|
/*****************************************************************************
|
|
* extern functions used in the library
|
|
*****************************************************************************/
|
|
|
|
/*
|
|
* need to copy original attributes and roll back if update fails
|
|
*/
|
|
extern CSA_return_code
|
|
_DtCmUpdateAttributes(
|
|
uint numsrc,
|
|
cms_attribute *srcattrs,
|
|
uint *numdst,
|
|
cms_attribute **dstattrs,
|
|
_DtCmNameTable **tbl,
|
|
boolean_t caltbl,
|
|
int **types,
|
|
boolean_t makecopy)
|
|
{
|
|
CSA_return_code stat = CSA_SUCCESS;
|
|
uint i, oldnum = 0;
|
|
cms_attribute *oldattrs;
|
|
int index;
|
|
|
|
/* copy original attributes for rollback if update fails */
|
|
if (makecopy && *numdst > 0 && (stat = _DtCm_copy_cms_attributes(
|
|
*numdst, *dstattrs, &oldnum, &oldattrs)) != CSA_SUCCESS)
|
|
return (stat);
|
|
|
|
for (i = 0; i < numsrc && stat == CSA_SUCCESS; i++) {
|
|
if (srcattrs[i].name.name == NULL)
|
|
continue;
|
|
|
|
if (srcattrs[i].name.num <= 0)
|
|
srcattrs[i].name.num = _DtCm_get_index_from_table(*tbl,
|
|
srcattrs[i].name.name);
|
|
|
|
index = srcattrs[i].name.num;
|
|
|
|
if (index < 0 || index > (*tbl)->size) {
|
|
if (index < 0)
|
|
srcattrs[i].name.num = 0;
|
|
|
|
if ((stat = _DtCmExtendNameTable(srcattrs[i].name.name,
|
|
index > 0 ? index : 0, srcattrs[i].value->type,
|
|
(caltbl == B_TRUE ? _DtCm_cal_name_tbl :
|
|
_DtCm_entry_name_tbl),
|
|
(caltbl == B_TRUE ? _DtCM_DEFINED_CAL_ATTR_SIZE :
|
|
_DtCM_DEFINED_ENTRY_ATTR_SIZE),
|
|
(caltbl == B_TRUE ? _CSA_calendar_attribute_names :
|
|
_CSA_entry_attribute_names), tbl, types))
|
|
== CSA_SUCCESS) {
|
|
|
|
if (index <= 0)
|
|
srcattrs[i].name.num = (*tbl)->size;
|
|
|
|
stat = _DtCmGrowAttrArray(numdst,
|
|
dstattrs, &srcattrs[i]);
|
|
}
|
|
} else {
|
|
if ((*tbl)->names[index] == NULL) {
|
|
/* fill in the missing hole */
|
|
if ((stat = _DtCm_add_name_to_table(*tbl,
|
|
index, srcattrs[i].name.name))
|
|
!= CSA_SUCCESS)
|
|
break;
|
|
|
|
if (types && srcattrs[i].value)
|
|
(*types)[index] =
|
|
srcattrs[i].value->type;
|
|
}
|
|
|
|
if (types && srcattrs[i].value &&
|
|
srcattrs[i].value->type != (*types)[index])
|
|
stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
|
|
else if (index > *numdst)
|
|
stat = _DtCmGrowAttrArray(numdst, dstattrs,
|
|
&srcattrs[i]);
|
|
else
|
|
stat = _DtCmUpdateAttribute(&srcattrs[i],
|
|
&(*dstattrs)[index]);
|
|
}
|
|
}
|
|
|
|
if (makecopy && oldnum > 0) {
|
|
if (stat != CSA_SUCCESS) {
|
|
_DtCm_free_cms_attributes(*numdst + 1, *dstattrs);
|
|
free(*dstattrs);
|
|
*numdst = oldnum;
|
|
*dstattrs = oldattrs;
|
|
} else {
|
|
_DtCm_free_cms_attributes(oldnum + 1, oldattrs);
|
|
free(oldattrs);
|
|
}
|
|
}
|
|
|
|
return (stat);
|
|
}
|
|
|
|
extern CSA_return_code
|
|
_DtCmUpdateAttribute(
|
|
cms_attribute *from,
|
|
cms_attribute *to)
|
|
{
|
|
CSA_return_code stat = CSA_SUCCESS;
|
|
|
|
if (to->name.name == NULL) {
|
|
to->name.num = from->name.num;
|
|
if ((to->name.name = strdup(from->name.name)) == NULL)
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
if (from->value && to->value && from->value->type != to->value->type)
|
|
return (CSA_E_INVALID_ATTRIBUTE_VALUE);
|
|
|
|
if (from->value) {
|
|
switch (from->value->type) {
|
|
case CSA_VALUE_BOOLEAN:
|
|
case CSA_VALUE_ENUMERATED:
|
|
case CSA_VALUE_FLAGS:
|
|
case CSA_VALUE_SINT32:
|
|
case CSA_VALUE_UINT32:
|
|
stat = _DtCmUpdateSint32AttrVal(from->value,
|
|
&to->value);
|
|
break;
|
|
|
|
case CSA_VALUE_STRING:
|
|
case CSA_VALUE_CALENDAR_USER:
|
|
case CSA_VALUE_DATE_TIME:
|
|
case CSA_VALUE_DATE_TIME_RANGE:
|
|
case CSA_VALUE_TIME_DURATION:
|
|
stat = _DtCmUpdateStringAttrVal(from->value,
|
|
&to->value);
|
|
break;
|
|
|
|
case CSA_VALUE_REMINDER:
|
|
stat = _DtCmUpdateReminderAttrVal(from->value,
|
|
&to->value);
|
|
break;
|
|
|
|
case CSA_VALUE_ACCESS_LIST:
|
|
stat = _DtCmUpdateAccessListAttrVal(from->value,
|
|
&to->value);
|
|
break;
|
|
|
|
case CSA_VALUE_DATE_TIME_LIST:
|
|
stat = _DtCmUpdateDateTimeListAttrVal(from->value,
|
|
&to->value);
|
|
break;
|
|
|
|
case CSA_VALUE_OPAQUE_DATA:
|
|
stat = _DtCmUpdateOpaqueDataAttrVal(from->value,
|
|
&to->value);
|
|
break;
|
|
|
|
default:
|
|
stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
|
|
}
|
|
} else {
|
|
_DtCm_free_cms_attribute_value(to->value);
|
|
to->value = NULL;
|
|
}
|
|
|
|
return (stat);
|
|
}
|
|
|
|
extern CSA_return_code
|
|
_DtCmUpdateAccessListAttrVal(
|
|
cms_attribute_value *newval,
|
|
cms_attribute_value **attrval)
|
|
{
|
|
cms_attribute_value *val;
|
|
cms_access_entry *newlist = NULL;
|
|
|
|
if (newval && newval->item.access_list_value &&
|
|
(newlist = _DtCm_copy_cms_access_list(
|
|
newval->item.access_list_value)) == NULL)
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
|
|
if (*attrval == NULL) {
|
|
if ((val = (cms_attribute_value *)malloc(
|
|
sizeof(cms_attribute_value))) == NULL) {
|
|
if (newlist)
|
|
_DtCm_free_cms_access_entry(newlist);
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
val->type = CSA_VALUE_ACCESS_LIST;
|
|
} else {
|
|
val = *attrval;
|
|
_DtCm_free_cms_access_entry(
|
|
(cms_access_entry *)val->item.access_list_value);
|
|
}
|
|
|
|
val->item.access_list_value = newlist;
|
|
|
|
*attrval = val;
|
|
|
|
return (CSA_SUCCESS);
|
|
}
|
|
|
|
extern CSA_return_code
|
|
_DtCmUpdateSint32AttrVal(
|
|
cms_attribute_value *newval,
|
|
cms_attribute_value **attrval)
|
|
{
|
|
cms_attribute_value *val;
|
|
|
|
if (newval) {
|
|
if (*attrval == NULL) {
|
|
if ((val = (cms_attribute_value *)malloc(
|
|
sizeof(cms_attribute_value))) == NULL) {
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
val->type = newval->type;
|
|
|
|
*attrval = val;
|
|
}
|
|
(*attrval)->item.sint32_value = newval->item.sint32_value;
|
|
|
|
} else if (*attrval) {
|
|
|
|
free(*attrval);
|
|
*attrval = NULL;
|
|
}
|
|
|
|
return (CSA_SUCCESS);
|
|
}
|
|
|
|
extern CSA_return_code
|
|
_DtCmUpdateStringAttrVal(
|
|
cms_attribute_value *newval,
|
|
cms_attribute_value **attrval)
|
|
{
|
|
cms_attribute_value *val;
|
|
char *newstring = NULL;
|
|
|
|
if (newval) {
|
|
if (newval->item.string_value &&
|
|
(newstring = strdup(newval->item.string_value)) == NULL)
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
|
|
if (*attrval == NULL) {
|
|
if ((val = (cms_attribute_value *)malloc(
|
|
sizeof(cms_attribute_value))) == NULL) {
|
|
if (newstring)
|
|
free(newstring);
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
val->type = newval->type;
|
|
} else {
|
|
val = *attrval;
|
|
if (val->item.string_value)
|
|
free(val->item.string_value);
|
|
}
|
|
|
|
val->item.string_value = newstring;
|
|
|
|
*attrval = val;
|
|
|
|
} else if (*attrval) {
|
|
|
|
free((*attrval)->item.string_value);
|
|
free(*attrval);
|
|
*attrval = NULL;
|
|
}
|
|
|
|
return (CSA_SUCCESS);
|
|
}
|
|
|
|
extern CSA_return_code
|
|
_DtCmUpdateReminderAttrVal(
|
|
cms_attribute_value *newval,
|
|
cms_attribute_value **attrval)
|
|
{
|
|
CSA_return_code stat;
|
|
cms_attribute_value *val;
|
|
CSA_reminder *rem = NULL;
|
|
|
|
if (newval && newval->item.reminder_value) {
|
|
if ((stat = _DtCm_copy_reminder(newval->item.reminder_value,
|
|
&rem)) != CSA_SUCCESS)
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
|
|
if (*attrval == NULL) {
|
|
if ((val = (cms_attribute_value *)malloc(
|
|
sizeof(cms_attribute_value))) == NULL) {
|
|
if (rem)
|
|
_DtCm_free_reminder(rem);
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
val->type = newval->type;
|
|
} else {
|
|
val = *attrval;
|
|
if (val->item.reminder_value)
|
|
_DtCm_free_reminder(val->item.reminder_value);
|
|
}
|
|
|
|
val->item.reminder_value = rem;
|
|
|
|
*attrval = val;
|
|
|
|
} else if (*attrval) {
|
|
|
|
_DtCm_free_reminder((*attrval)->item.reminder_value);
|
|
free(*attrval);
|
|
*attrval = NULL;
|
|
}
|
|
|
|
return (CSA_SUCCESS);
|
|
}
|
|
|
|
extern CSA_return_code
|
|
_DtCmUpdateDateTimeListAttrVal(
|
|
cms_attribute_value *newval,
|
|
cms_attribute_value **attrval)
|
|
{
|
|
cms_attribute_value *val;
|
|
CSA_date_time_list dtlist = NULL;
|
|
|
|
if (newval && newval->item.date_time_list_value) {
|
|
if ((dtlist = _DtCm_copy_date_time_list(
|
|
newval->item.date_time_list_value)) == NULL)
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
|
|
if (*attrval == NULL) {
|
|
if ((val = (cms_attribute_value *)malloc(
|
|
sizeof(cms_attribute_value))) == NULL) {
|
|
if (dtlist)
|
|
_DtCm_free_date_time_list(dtlist);
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
val->type = newval->type;
|
|
} else {
|
|
val = *attrval;
|
|
if (val->item.date_time_list_value)
|
|
_DtCm_free_date_time_list(
|
|
val->item.date_time_list_value);
|
|
}
|
|
|
|
val->item.date_time_list_value = dtlist;
|
|
|
|
*attrval = val;
|
|
|
|
} else if (*attrval) {
|
|
|
|
_DtCm_free_date_time_list((*attrval)->item.date_time_list_value);
|
|
free(*attrval);
|
|
*attrval = NULL;
|
|
}
|
|
|
|
return (CSA_SUCCESS);
|
|
}
|
|
|
|
extern CSA_return_code
|
|
_DtCmUpdateOpaqueDataAttrVal(
|
|
cms_attribute_value *newval,
|
|
cms_attribute_value **attrval)
|
|
{
|
|
CSA_return_code stat;
|
|
cms_attribute_value *val;
|
|
CSA_opaque_data *opq = NULL;
|
|
|
|
if (newval && newval->item.opaque_data_value) {
|
|
if ((stat = _DtCm_copy_opaque_data(
|
|
newval->item.opaque_data_value, &opq)) != CSA_SUCCESS)
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
|
|
if (*attrval == NULL) {
|
|
if ((val = (cms_attribute_value *)malloc(
|
|
sizeof(cms_attribute_value))) == NULL) {
|
|
if (opq) _DtCm_free_opaque_data(opq);
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
val->type = newval->type;
|
|
} else {
|
|
val = *attrval;
|
|
if (val->item.opaque_data_value)
|
|
_DtCm_free_opaque_data(
|
|
val->item.opaque_data_value);
|
|
}
|
|
|
|
val->item.opaque_data_value = opq;
|
|
|
|
*attrval = val;
|
|
|
|
} else if (*attrval) {
|
|
|
|
_DtCm_free_opaque_data((*attrval)->item.opaque_data_value);
|
|
free(*attrval);
|
|
*attrval = NULL;
|
|
}
|
|
|
|
return (CSA_SUCCESS);
|
|
}
|
|
|