Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / lib / csa / updateattrs.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: updateattrs.c /main/1 1996/04/21 19:24:52 drk $ */
24 /*
25  *  (c) Copyright 1993, 1994 Hewlett-Packard Company
26  *  (c) Copyright 1993, 1994 International Business Machines Corp.
27  *  (c) Copyright 1993, 1994 Novell, Inc.
28  *  (c) Copyright 1993, 1994 Sun Microsystems, Inc.
29  */
30
31 #include <EUSCompat.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include "updateattrs.h"
35 #include "cmsdata.h"
36 #include "nametbl.h"
37 #include "attr.h"
38
39
40 /*****************************************************************************
41  * extern functions used in the library
42  *****************************************************************************/
43
44 /*
45  * need to copy original attributes and roll back if update fails
46  */
47 extern CSA_return_code
48 _DtCmUpdateAttributes(
49         uint            numsrc,
50         cms_attribute   *srcattrs,
51         uint            *numdst,
52         cms_attribute   **dstattrs,
53         _DtCmNameTable  **tbl,
54         boolean_t       caltbl,
55         int             **types,
56         boolean_t       makecopy)
57 {
58         CSA_return_code         stat = CSA_SUCCESS;
59         uint                    i, oldnum = 0;
60         cms_attribute           *oldattrs;
61         int                     index;
62
63         /* copy original attributes for rollback if update fails */
64         if (makecopy && *numdst > 0 && (stat = _DtCm_copy_cms_attributes(
65             *numdst, *dstattrs, &oldnum, &oldattrs)) != CSA_SUCCESS)
66                 return (stat);
67
68         for (i = 0; i < numsrc && stat == CSA_SUCCESS; i++) {
69                 if (srcattrs[i].name.name == NULL)
70                         continue;
71
72                 if (srcattrs[i].name.num <= 0)
73                         srcattrs[i].name.num = _DtCm_get_index_from_table(*tbl,
74                                         srcattrs[i].name.name);
75
76                 index = srcattrs[i].name.num;
77
78                 if (index < 0 || index > (*tbl)->size) {
79                         if (index < 0)
80                                 srcattrs[i].name.num = 0;
81
82                         if ((stat = _DtCmExtendNameTable(srcattrs[i].name.name,
83                             index > 0 ? index : 0, srcattrs[i].value->type,
84                             (caltbl == B_TRUE ? _DtCm_cal_name_tbl :
85                             _DtCm_entry_name_tbl),
86                             (caltbl == B_TRUE ? _DtCM_DEFINED_CAL_ATTR_SIZE :
87                             _DtCM_DEFINED_ENTRY_ATTR_SIZE),
88                             (caltbl == B_TRUE ? _CSA_calendar_attribute_names :
89                             _CSA_entry_attribute_names), tbl, types))
90                             == CSA_SUCCESS) {
91
92                                 if (index <= 0)
93                                         srcattrs[i].name.num = (*tbl)->size;
94
95                                 stat = _DtCmGrowAttrArray(numdst,
96                                         dstattrs, &srcattrs[i]);
97                         }
98                 } else {
99                         if ((*tbl)->names[index] == NULL) {
100                                 /* fill in the missing hole */
101                                 if ((stat = _DtCm_add_name_to_table(*tbl,
102                                     index, srcattrs[i].name.name))
103                                     != CSA_SUCCESS)
104                                         break;
105
106                                 if (types && srcattrs[i].value)
107                                         (*types)[index] =
108                                                 srcattrs[i].value->type;
109                         }
110
111                         if (types && srcattrs[i].value &&
112                             srcattrs[i].value->type != (*types)[index])
113                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
114                         else if (index > *numdst)
115                                 stat = _DtCmGrowAttrArray(numdst, dstattrs,
116                                         &srcattrs[i]);
117                         else
118                                 stat = _DtCmUpdateAttribute(&srcattrs[i],
119                                         &(*dstattrs)[index]);
120                 }
121         }
122
123         if (makecopy && oldnum > 0) {
124                 if (stat != CSA_SUCCESS) {
125                         _DtCm_free_cms_attributes(*numdst + 1, *dstattrs);
126                         free(*dstattrs);
127                         *numdst = oldnum;
128                         *dstattrs = oldattrs;
129                 } else {
130                         _DtCm_free_cms_attributes(oldnum + 1, oldattrs);
131                         free(oldattrs);
132                 }
133         }
134
135         return (stat);
136 }
137
138 extern CSA_return_code
139 _DtCmUpdateAttribute(
140         cms_attribute   *from,
141         cms_attribute   *to)
142 {
143         CSA_return_code stat = CSA_SUCCESS;
144
145         if (to->name.name == NULL) {
146                 to->name.num = from->name.num;
147                 if ((to->name.name = strdup(from->name.name)) == NULL)
148                         return (CSA_E_INSUFFICIENT_MEMORY);
149         }
150
151         if (from->value && to->value && from->value->type != to->value->type)
152                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
153
154         if (from->value) {
155                 switch (from->value->type) {
156                 case CSA_VALUE_BOOLEAN:
157                 case CSA_VALUE_ENUMERATED:
158                 case CSA_VALUE_FLAGS:
159                 case CSA_VALUE_SINT32:
160                 case CSA_VALUE_UINT32:
161                         stat = _DtCmUpdateSint32AttrVal(from->value,
162                                 &to->value);
163                         break;
164
165                 case CSA_VALUE_STRING:
166                 case CSA_VALUE_CALENDAR_USER:
167                 case CSA_VALUE_DATE_TIME:
168                 case CSA_VALUE_DATE_TIME_RANGE:
169                 case CSA_VALUE_TIME_DURATION:
170                         stat = _DtCmUpdateStringAttrVal(from->value,
171                                 &to->value);
172                         break;
173
174                 case CSA_VALUE_REMINDER:
175                         stat = _DtCmUpdateReminderAttrVal(from->value,
176                                 &to->value);
177                         break;
178
179                 case CSA_VALUE_ACCESS_LIST:
180                         stat = _DtCmUpdateAccessListAttrVal(from->value,
181                                 &to->value);
182                         break;
183
184                 case CSA_VALUE_DATE_TIME_LIST:
185                         stat = _DtCmUpdateDateTimeListAttrVal(from->value,
186                                 &to->value);
187                         break;
188
189                 case CSA_VALUE_OPAQUE_DATA:
190                         stat = _DtCmUpdateOpaqueDataAttrVal(from->value,
191                                 &to->value);
192                         break;
193
194                 default:
195                         stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
196                 }
197         } else {
198                 _DtCm_free_cms_attribute_value(to->value);
199                 to->value = NULL;
200         }
201
202         return (stat);
203 }
204
205 extern CSA_return_code
206 _DtCmUpdateAccessListAttrVal(
207         cms_attribute_value *newval,
208         cms_attribute_value **attrval)
209 {
210         cms_attribute_value *val;
211         cms_access_entry *newlist = NULL;
212
213         if (newval && newval->item.access_list_value &&
214             (newlist = _DtCm_copy_cms_access_list(
215             newval->item.access_list_value)) == NULL)
216                 return (CSA_E_INSUFFICIENT_MEMORY);
217
218         if (*attrval == NULL) {
219                 if ((val = (cms_attribute_value *)malloc(
220                     sizeof(cms_attribute_value))) == NULL) {
221                         if (newlist)
222                                 _DtCm_free_cms_access_entry(newlist);
223                         return (CSA_E_INSUFFICIENT_MEMORY);
224                 }
225
226                 val->type = CSA_VALUE_ACCESS_LIST;
227         } else {
228                 val = *attrval;
229                 _DtCm_free_cms_access_entry(
230                         (cms_access_entry *)val->item.access_list_value);
231         }
232
233         val->item.access_list_value = newlist;
234
235         *attrval = val;
236
237         return (CSA_SUCCESS);
238 }
239
240 extern CSA_return_code
241 _DtCmUpdateSint32AttrVal(
242         cms_attribute_value *newval,
243         cms_attribute_value **attrval)
244 {
245         cms_attribute_value     *val;
246
247         if (newval) {
248                 if (*attrval == NULL) {
249                         if ((val = (cms_attribute_value *)malloc(
250                             sizeof(cms_attribute_value))) == NULL) {
251                                 return (CSA_E_INSUFFICIENT_MEMORY);
252                         }
253
254                         val->type = newval->type;
255
256                         *attrval = val;
257                 }
258                 (*attrval)->item.sint32_value = newval->item.sint32_value;
259
260         } else if (*attrval) {
261
262                 free(*attrval);
263                 *attrval = NULL;
264         }
265
266         return (CSA_SUCCESS);
267 }
268
269 extern CSA_return_code
270 _DtCmUpdateStringAttrVal(
271         cms_attribute_value *newval,
272         cms_attribute_value **attrval)
273 {
274         cms_attribute_value     *val;
275         char *newstring = NULL;
276
277         if (newval) {
278                 if (newval->item.string_value &&
279                     (newstring = strdup(newval->item.string_value)) == NULL)
280                         return (CSA_E_INSUFFICIENT_MEMORY);
281
282                 if (*attrval == NULL) {
283                         if ((val = (cms_attribute_value *)malloc(
284                             sizeof(cms_attribute_value))) == NULL) {
285                                 if (newstring)
286                                         free(newstring);
287                                 return (CSA_E_INSUFFICIENT_MEMORY);
288                         }
289
290                         val->type = newval->type;
291                 } else {
292                         val = *attrval;
293                         if (val->item.string_value)
294                                 free(val->item.string_value);
295                 }
296
297                 val->item.string_value = newstring;
298
299                 *attrval = val;
300
301         } else if (*attrval) {
302
303                 free((*attrval)->item.string_value);
304                 free(*attrval);
305                 *attrval = NULL;
306         }
307
308         return (CSA_SUCCESS);
309 }
310
311 extern CSA_return_code
312 _DtCmUpdateReminderAttrVal(
313         cms_attribute_value *newval,
314         cms_attribute_value **attrval)
315 {
316         CSA_return_code         stat;
317         cms_attribute_value     *val;
318         CSA_reminder            *rem = NULL;
319
320         if (newval && newval->item.reminder_value) {
321                 if ((stat = _DtCm_copy_reminder(newval->item.reminder_value,
322                     &rem)) != CSA_SUCCESS)
323                         return (CSA_E_INSUFFICIENT_MEMORY);
324
325                 if (*attrval == NULL) {
326                         if ((val = (cms_attribute_value *)malloc(
327                             sizeof(cms_attribute_value))) == NULL) {
328                                 if (rem)
329                                         _DtCm_free_reminder(rem);
330                                 return (CSA_E_INSUFFICIENT_MEMORY);
331                         }
332
333                         val->type = newval->type;
334                 } else {
335                         val = *attrval;
336                         if (val->item.reminder_value)
337                                 _DtCm_free_reminder(val->item.reminder_value);
338                 }
339
340                 val->item.reminder_value = rem;
341
342                 *attrval = val;
343
344         } else if (*attrval) {
345
346                 _DtCm_free_reminder((*attrval)->item.reminder_value);
347                 free(*attrval);
348                 *attrval = NULL;
349         }
350
351         return (CSA_SUCCESS);
352 }
353
354 extern CSA_return_code
355 _DtCmUpdateDateTimeListAttrVal(
356         cms_attribute_value *newval,
357         cms_attribute_value **attrval)
358 {
359         cms_attribute_value     *val;
360         CSA_date_time_list      dtlist = NULL;
361
362         if (newval && newval->item.date_time_list_value) {
363                 if ((dtlist = _DtCm_copy_date_time_list(
364                     newval->item.date_time_list_value)) == NULL)
365                         return (CSA_E_INSUFFICIENT_MEMORY);
366
367                 if (*attrval == NULL) {
368                         if ((val = (cms_attribute_value *)malloc(
369                             sizeof(cms_attribute_value))) == NULL) {
370                                 if (dtlist)
371                                         _DtCm_free_date_time_list(dtlist);
372                                 return (CSA_E_INSUFFICIENT_MEMORY);
373                         }
374
375                         val->type = newval->type;
376                 } else {
377                         val = *attrval;
378                         if (val->item.date_time_list_value)
379                                 _DtCm_free_date_time_list(
380                                         val->item.date_time_list_value);
381                 }
382
383                 val->item.date_time_list_value = dtlist;
384
385                 *attrval = val;
386
387         } else if (*attrval) {
388
389                 _DtCm_free_date_time_list((*attrval)->item.date_time_list_value);
390                 free(*attrval);
391                 *attrval = NULL;
392         }
393
394         return (CSA_SUCCESS);
395 }
396
397 extern CSA_return_code
398 _DtCmUpdateOpaqueDataAttrVal(
399         cms_attribute_value *newval,
400         cms_attribute_value **attrval)
401 {
402         CSA_return_code         stat;
403         cms_attribute_value     *val;
404         CSA_opaque_data         *opq = NULL;
405
406         if (newval && newval->item.opaque_data_value) {
407                 if ((stat = _DtCm_copy_opaque_data(
408                     newval->item.opaque_data_value, &opq)) != CSA_SUCCESS)
409                         return (CSA_E_INSUFFICIENT_MEMORY);
410
411                 if (*attrval == NULL) {
412                         if ((val = (cms_attribute_value *)malloc(
413                             sizeof(cms_attribute_value))) == NULL) {
414                                 if (opq) _DtCm_free_opaque_data(opq);
415                                 return (CSA_E_INSUFFICIENT_MEMORY);
416                         }
417
418                         val->type = newval->type;
419                 } else {
420                         val = *attrval;
421                         if (val->item.opaque_data_value)
422                                 _DtCm_free_opaque_data(
423                                         val->item.opaque_data_value);
424                 }
425
426                 val->item.opaque_data_value = opq;
427
428                 *attrval = val;
429
430         } else if (*attrval) {
431
432                 _DtCm_free_opaque_data((*attrval)->item.opaque_data_value);
433                 free(*attrval);
434                 *attrval = NULL;
435         }
436
437         return (CSA_SUCCESS);
438 }
439