dtcm: make it build
[oweals/cde.git] / cde / lib / csa / attr.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 libraries 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: attr.c /main/1 1996/04/21 19:21:41 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 <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <sys/types.h>
36 #include <unistd.h>
37 #include "attr.h"
38 #include "cmsdata.h"
39 #include "nametbl.h"
40 #include "free.h"
41 #include "misc.h"
42 #include "iso8601.h"
43 #include "lutil.h"
44
45 /*
46  * calendar attributes defined by the library
47  * Note: index zero is not used
48  */
49 char *_CSA_calendar_attribute_names[] = {
50         NULL,
51         "-//XAPIA/CSA/CALATTR//NONSGML Access List//EN",
52         "-//XAPIA/CSA/CALATTR//NONSGML Calendar Name//EN",
53         "-//XAPIA/CSA/CALATTR//NONSGML Calendar Owner//EN",
54         "-//XAPIA/CSA/CALATTR//NONSGML Calendar Size//EN",
55         "-//XAPIA/CSA/CALATTR//NONSGML Character Set//EN",
56         "-//XAPIA/CSA/CALATTR//NONSGML Country//EN",
57         "-//XAPIA/CSA/CALATTR//NONSGML Date Created//EN",
58         "-//XAPIA/CSA/CALATTR//NONSGML Language//EN",
59         "-//XAPIA/CSA/CALATTR//NONSGML Number Entries//EN",
60         "-//XAPIA/CSA/CALATTR//NONSGML Product Identifier//EN",
61         "-//XAPIA/CSA/CALATTR//NONSGML Time Zone//EN",
62         "-//XAPIA/CSA/CALATTR//NONSGML Version//EN",
63         "-//XAPIA/CSA/CALATTR//NONSGML Work Schedule//EN",
64         "-//CDE_XAPIA_PRIVATE/CSA/CALATTR//NONSGML Server Version//EN",
65         "-//CDE_XAPIA_PRIVATE/CSA/CALATTR//NONSGML Data Version//EN",
66         "-//CDE_XAPIA_PRIVATE/CSA/CALATTR//NONSGML Calendar Delimiter//EN"
67 };
68
69 /*
70  * entry attributes defined by the library
71  * Note: index zero is not used
72  */
73 char *_CSA_entry_attribute_names[] = {
74         NULL,
75         "-//XAPIA/CSA/ENTRYATTR//NONSGML Attendee List//EN",
76         "-//XAPIA/CSA/ENTRYATTR//NONSGML Audio Reminder//EN",
77         "-//XAPIA/CSA/ENTRYATTR//NONSGML Classification//EN",
78         "-//XAPIA/CSA/ENTRYATTR//NONSGML Date Completed//EN",
79         "-//XAPIA/CSA/ENTRYATTR//NONSGML Date Created//EN",
80         "-//XAPIA/CSA/ENTRYATTR//NONSGML Description//EN",
81         "-//XAPIA/CSA/ENTRYATTR//NONSGML Due Date//EN",
82         "-//XAPIA/CSA/ENTRYATTR//NONSGML End Date//EN",
83         "-//XAPIA/CSA/ENTRYATTR//NONSGML Exception Dates//EN",
84         "-//XAPIA/CSA/ENTRYATTR//NONSGML Exception Rule//EN",
85         "-//XAPIA/CSA/ENTRYATTR//NONSGML Flashing Reminder//EN",
86         "-//XAPIA/CSA/ENTRYATTR//NONSGML Last Update//EN",
87         "-//XAPIA/CSA/ENTRYATTR//NONSGML Mail Reminder//EN",
88         "-//XAPIA/CSA/ENTRYATTR//NONSGML Number Recurrences//EN",
89         "-//XAPIA/CSA/ENTRYATTR//NONSGML Organizer//EN",
90         "-//XAPIA/CSA/ENTRYATTR//NONSGML Popup Reminder//EN",
91         "-//XAPIA/CSA/ENTRYATTR//NONSGML Priority//EN",
92         "-//XAPIA/CSA/ENTRYATTR//NONSGML Recurrence Rule//EN",
93         "-//XAPIA/CSA/ENTRYATTR//NONSGML Recurring Dates//EN",
94         "-//XAPIA/CSA/ENTRYATTR//NONSGML Reference Identifier//EN",
95         "-//XAPIA/CSA/ENTRYATTR//NONSGML Sequence Number//EN",
96         "-//XAPIA/CSA/ENTRYATTR//NONSGML Sponsor//EN",
97         "-//XAPIA/CSA/ENTRYATTR//NONSGML Start Date//EN",
98         "-//XAPIA/CSA/ENTRYATTR//NONSGML Status//EN",
99         "-//XAPIA/CSA/ENTRYATTR//NONSGML Subtype//EN",
100         "-//XAPIA/CSA/ENTRYATTR//NONSGML Summary//EN",
101         "-//XAPIA/CSA/ENTRYATTR//NONSGML Time Transparency//EN",
102         "-//XAPIA/CSA/ENTRYATTR//NONSGML Type//EN",
103         "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Show Time//EN",
104         "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Type//EN",
105         "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Times//EN",
106         "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Interval//EN",
107         "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Repeat Occurrence Number//EN",
108         "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Sequence End Date//EN",
109         "-//CDE_XAPIA_PRIVATE/CSA/ENTRYATTR//NONSGML Entry Delimiter//EN"
110 };
111
112 /*
113  * Values for entry attribute CSA_ENTRY_ATTR_SUBTYPE
114  */
115 char *_CSA_entry_subtype_values[] = {
116         "-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Appointment//EN",
117         "-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Class//EN",
118         "-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Holiday//EN",
119         "-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Meeting//EN",
120         "-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Miscellaneous//EN",
121         "-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Phone Call//EN",
122         "-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Sick Day//EN",
123         "-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Special Occasion//EN",
124         "-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Travel//EN",
125         "-//XAPIA/CSA/SUBTYPE//NONSGML Subtype Vacation//EN",
126 };
127
128 /* list of calendar attributes and value type */
129 _DtCmAttrInfo _CSA_cal_attr_info[] =
130 {
131         /* first element is not used */
132         { 0, -1, 0, _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
133         { CSA_CAL_ATTR_ACCESS_LIST_I, CSA_VALUE_ACCESS_LIST,    1,
134                 _DtCm_old_attr_unknown, B_FALSE, B_FALSE },
135         { CSA_CAL_ATTR_CALENDAR_NAME_I, CSA_VALUE_STRING,       1,
136                 _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
137         { CSA_CAL_ATTR_CALENDAR_OWNER_I, CSA_VALUE_CALENDAR_USER,       1,
138                 _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
139         { CSA_CAL_ATTR_CALENDAR_SIZE_I, CSA_VALUE_UINT32,       4,
140                 _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
141         { CSA_CAL_ATTR_CHARACTER_SET_I, CSA_VALUE_STRING,       4,
142                 _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
143         { CSA_CAL_ATTR_COUNTRY_I,       CSA_VALUE_STRING,       0,
144                 _DtCm_old_attr_unknown, B_FALSE, B_FALSE },
145         { CSA_CAL_ATTR_DATE_CREATED_I,  CSA_VALUE_DATE_TIME,    4,
146                 _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
147         { CSA_CAL_ATTR_LANGUAGE_I,      CSA_VALUE_STRING,       0,
148                 _DtCm_old_attr_unknown, B_FALSE, B_FALSE },
149         { CSA_CAL_ATTR_NUMBER_ENTRIES_I, CSA_VALUE_UINT32,      1,
150                 _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
151         { CSA_CAL_ATTR_PRODUCT_IDENTIFIER_I, CSA_VALUE_STRING,  1,
152                 _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
153         { CSA_CAL_ATTR_TIME_ZONE_I,     CSA_VALUE_STRING,       4,
154                 _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
155         { CSA_CAL_ATTR_VERSION_I,       CSA_VALUE_STRING,       1,
156                 _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
157         { CSA_CAL_ATTR_WORK_SCHEDULE_I, CSA_VALUE_OPAQUE_DATA,  0,
158                 _DtCm_old_attr_unknown, B_FALSE, B_FALSE },
159         { CSA_X_DT_CAL_ATTR_SERVER_VERSION_I, CSA_VALUE_UINT32, 1,
160                 _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
161         { CSA_X_DT_CAL_ATTR_DATA_VERSION_I, CSA_VALUE_UINT32,   1,
162                 _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
163         { CSA_X_DT_CAL_ATTR_CAL_DELIMITER_I, CSA_VALUE_STRING,  -1,
164                 _DtCm_old_attr_unknown, B_TRUE, B_TRUE }
165 };
166
167 /* list of entry attributes and value type */
168 _DtCmAttrInfo _CSA_entry_attr_info[] =
169 {
170         /* first element is not used */
171         { 0, -1, 0, _DtCm_old_attr_unknown, B_TRUE, B_TRUE },
172         { CSA_ENTRY_ATTR_ATTENDEE_LIST_I,       CSA_VALUE_ATTENDEE_LIST,
173           0,    _DtCm_old_attr_unknown,         B_FALSE, B_FALSE },
174         { CSA_ENTRY_ATTR_AUDIO_REMINDER_I,      CSA_VALUE_REMINDER,
175           1,    _DtCm_old_attr_beep_reminder,   B_FALSE, B_FALSE },
176         { CSA_ENTRY_ATTR_CLASSIFICATION_I,      CSA_VALUE_UINT32,
177           2,    _DtCm_old_attr_privacy,         B_FALSE, B_FALSE },
178         { CSA_ENTRY_ATTR_DATE_COMPLETED_I,      CSA_VALUE_DATE_TIME,
179           4,    _DtCm_old_attr_unknown,         B_FALSE, B_FALSE },
180         { CSA_ENTRY_ATTR_DATE_CREATED_I,        CSA_VALUE_DATE_TIME,
181           4,    _DtCm_old_attr_unknown,         B_TRUE, B_TRUE },
182         { CSA_ENTRY_ATTR_DESCRIPTION_I,         CSA_VALUE_STRING,
183           4,    _DtCm_old_attr_unknown,         B_FALSE, B_FALSE },
184         { CSA_ENTRY_ATTR_DUE_DATE_I,            CSA_VALUE_DATE_TIME,
185           4,    _DtCm_old_attr_unknown,         B_FALSE, B_FALSE },
186         { CSA_ENTRY_ATTR_END_DATE_I,            CSA_VALUE_DATE_TIME,
187           1,    _DtCm_old_attr_duration,        B_FALSE, B_FALSE },
188         { CSA_ENTRY_ATTR_EXCEPTION_DATES_I,     CSA_VALUE_DATE_TIME_LIST,
189           4,    _DtCm_old_attr_unknown,         B_FALSE, B_FALSE },
190         { CSA_ENTRY_ATTR_EXCEPTION_RULE_I,      CSA_VALUE_STRING,
191           0,    _DtCm_old_attr_unknown,         B_FALSE, B_FALSE },
192         { CSA_ENTRY_ATTR_FLASHING_REMINDER_I,   CSA_VALUE_REMINDER,
193           1,    _DtCm_old_attr_flash_reminder,  B_FALSE, B_FALSE },
194         { CSA_ENTRY_ATTR_LAST_UPDATE_I,         CSA_VALUE_DATE_TIME,
195           4,    _DtCm_old_attr_unknown,         B_TRUE, B_TRUE },
196         { CSA_ENTRY_ATTR_MAIL_REMINDER_I,       CSA_VALUE_REMINDER,
197           1,    _DtCm_old_attr_mail_reminder,   B_FALSE, B_FALSE },
198         { CSA_ENTRY_ATTR_NUMBER_RECURRENCES_I,  CSA_VALUE_UINT32,
199           4,    _DtCm_old_attr_unknown,         B_TRUE, B_TRUE },
200         { CSA_ENTRY_ATTR_ORGANIZER_I,           CSA_VALUE_CALENDAR_USER,
201           1,    _DtCm_old_attr_author,          B_TRUE, B_TRUE },
202         { CSA_ENTRY_ATTR_POPUP_REMINDER_I,      CSA_VALUE_REMINDER,
203           1,    _DtCm_old_attr_popup_reminder,  B_FALSE, B_FALSE },
204         { CSA_ENTRY_ATTR_PRIORITY_I,            CSA_VALUE_UINT32,
205           4,    _DtCm_old_attr_unknown,         B_FALSE, B_FALSE },
206         { CSA_ENTRY_ATTR_RECURRENCE_RULE_I,     CSA_VALUE_STRING,
207           4,    _DtCm_old_attr_unknown,         B_FALSE, B_FALSE },
208         { CSA_ENTRY_ATTR_RECURRING_DATES_I,     CSA_VALUE_DATE_TIME_LIST,
209           0,    _DtCm_old_attr_unknown,         B_FALSE, B_FALSE },
210         { CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I, CSA_VALUE_OPAQUE_DATA, 
211           1,    _DtCm_old_attr_id,              B_TRUE, B_TRUE },
212         { CSA_ENTRY_ATTR_SEQUENCE_NUMBER_I,     CSA_VALUE_UINT32,
213           0,    _DtCm_old_attr_unknown,         B_TRUE, B_TRUE },
214         { CSA_ENTRY_ATTR_SPONSOR_I,             CSA_VALUE_CALENDAR_USER,
215           4,    _DtCm_old_attr_unknown,         B_FALSE, B_FALSE },
216         { CSA_ENTRY_ATTR_START_DATE_I,          CSA_VALUE_DATE_TIME,
217           1,    _DtCm_old_attr_time,            B_FALSE, B_FALSE },
218         { CSA_ENTRY_ATTR_STATUS_I,              CSA_VALUE_UINT32,
219           2,    _DtCm_old_attr_status,          B_FALSE, B_FALSE },
220         { CSA_ENTRY_ATTR_SUBTYPE_I,             CSA_VALUE_STRING,
221           1,    _DtCm_old_attr_type2,           B_FALSE, B_FALSE },
222         { CSA_ENTRY_ATTR_SUMMARY_I,             CSA_VALUE_STRING,
223           1,    _DtCm_old_attr_what,            B_FALSE, B_FALSE },
224         { CSA_ENTRY_ATTR_TIME_TRANSPARENCY_I,   CSA_VALUE_SINT32,
225           4,    _DtCm_old_attr_unknown,         B_FALSE, B_FALSE },
226         { CSA_ENTRY_ATTR_TYPE_I,                CSA_VALUE_UINT32,
227           1,    _DtCm_old_attr_type,            B_FALSE, B_FALSE },
228         { CSA_X_DT_ENTRY_ATTR_SHOWTIME_I,       CSA_VALUE_SINT32,
229           2,    _DtCm_old_attr_showtime,        B_FALSE, B_FALSE },
230         { CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,    CSA_VALUE_SINT32,
231           1,    _DtCm_old_attr_repeat_type,     B_FALSE, B_TRUE },
232         { CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I,   CSA_VALUE_UINT32,
233           1,    _DtCm_old_attr_repeat_times,    B_FALSE, B_TRUE },
234         { CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I, CSA_VALUE_UINT32,
235           3,    _DtCm_old_attr_repeat_nth_interval, B_FALSE, B_TRUE },
236         { CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I, CSA_VALUE_SINT32,
237           3,    _DtCm_old_attr_repeat_nth_weeknum, B_FALSE, B_TRUE },
238         { CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE_I, CSA_VALUE_DATE_TIME,
239           3,    _DtCm_old_attr_end_date,        B_FALSE, B_TRUE },
240         { CSA_X_DT_ENTRY_ATTR_ENTRY_DELIMITER_I, CSA_VALUE_STRING,
241           -1,   _DtCm_old_attr_unknown,         B_TRUE, B_TRUE }
242 };
243
244 /*****************************************************************************
245  * forward declaration of static functions used within the file
246  *****************************************************************************/
247 static CSA_return_code check_predefined_attrs(
248         int                     fversion,
249         uint                    num_attrs,
250         cms_attribute           *attrs,
251         boolean_t               checkreadonly,
252         _DtCmNameTable          *tbl,
253         uint                    num_defined,
254         _DtCmAttrInfo           *our_attrs);
255
256 static CSA_return_code convert_cms_user_to_csa_user(char *from,
257         CSA_calendar_user **to);
258
259 static CSA_return_code hash_entry_attrs(uint num_attrs, CSA_attribute *csaattrs,
260         cms_attribute *cmsattrs, uint *hnum, cms_attribute **hattrs, uint *num);
261
262 static CSA_return_code hash_cal_attrs(uint num_attrs, CSA_attribute *csaattrs,
263         cms_attribute *cmsattrs, uint *hnum, cms_attribute **hattrs, uint *num);
264
265 static CSA_return_code _DtCm_check_hashed_entry_attributes(
266         int             fvers,
267         uint            num_attrs,
268         cms_attribute   *attrs,
269         CSA_flags       utype);
270
271 static CSA_return_code _DtCm_check_hashed_cal_attributes(
272         int             fvers,
273         uint            num_attrs,
274         cms_attribute   *attrs,
275         char            *owner,
276         char            *cname,
277         boolean_t       checkreadonly,
278         boolean_t       firsttime,
279         boolean_t       csatype);
280
281 static CSA_return_code _CheckNameAtHost(char *owner, char *value);
282
283 static CSA_return_code _CheckCalendarOwner(char *owner, int type, char *name);
284
285 static CSA_return_code _CheckCalendarName(char *owner, char *cname,
286                                         cms_attribute_value *val);
287
288 /*****************************************************************************
289  * extern functions used in the library
290  *****************************************************************************/
291
292 /*
293  * For each calendar attribute, if it is a predefined attribute,
294  * check that the data type is correct.
295  * If checkreadonly is B_TRUE, also check that it's not readonly.
296  */
297 extern CSA_return_code
298 _DtCm_check_cal_csa_attributes(
299         int             fvers,
300         uint            num_attrs,
301         CSA_attribute   *attrs,
302         char            *cname,
303         boolean_t       checkreadonly,
304         boolean_t       firsttime,
305         boolean_t       checkattrnum)
306 {
307         CSA_return_code stat;
308         uint            hnum;
309         cms_attribute   *hattrs;
310         uint            realnum;
311
312         if ((stat = hash_cal_attrs(num_attrs, attrs, NULL, &hnum, &hattrs,
313             &realnum)) != CSA_SUCCESS)
314                 return (stat);
315
316         if (checkattrnum == B_TRUE && realnum == 0) {
317                 free(hattrs);
318                 return (CSA_E_INVALID_PARAMETER);
319         }
320
321         stat = _DtCm_check_hashed_cal_attributes(fvers, hnum, hattrs,
322                 NULL, cname, checkreadonly, firsttime, B_TRUE);
323
324         free(hattrs);
325
326         return (stat);
327 }
328
329 extern CSA_return_code
330 _DtCm_check_cal_cms_attributes(
331         int             fvers,
332         uint            num_attrs,
333         cms_attribute   *attrs,
334         char            *owner,
335         char            *cname,
336         boolean_t       checkreadonly,
337         boolean_t       firsttime,
338         boolean_t       checkattrnum)
339 {
340         CSA_return_code stat;
341         uint            hnum;
342         cms_attribute   *hattrs;
343         uint            realnum;
344
345         if ((stat = hash_cal_attrs(num_attrs, NULL, attrs, &hnum, &hattrs,
346             &realnum)) != CSA_SUCCESS)
347                 return (stat);
348
349         if (checkattrnum == B_TRUE && realnum == 0) {
350                 free(hattrs);
351                 return (CSA_E_INVALID_PARAMETER);
352         }
353
354         stat = _DtCm_check_hashed_cal_attributes(fvers, hnum, hattrs,
355                 owner, cname, checkreadonly, firsttime, B_FALSE);
356
357         free(hattrs);
358
359         return (stat);
360 }
361
362 extern CSA_return_code
363 _DtCm_check_entry_attributes(
364         int             fvers,
365         uint            num_attrs,
366         CSA_attribute   *attrs,
367         CSA_flags       utype,
368         boolean_t       checkattrnum)
369 {
370         CSA_return_code stat;
371         uint            hnum;
372         cms_attribute   *hattrs;
373         uint            realnum;
374
375         if ((stat = hash_entry_attrs(num_attrs, attrs, NULL, &hnum, &hattrs,
376             &realnum)) != CSA_SUCCESS)
377                 return (stat);
378
379         if (checkattrnum == B_TRUE && realnum == 0) {
380                 free(hattrs);
381                 return (CSA_E_INVALID_PARAMETER);
382         }
383
384         stat = _DtCm_check_hashed_entry_attributes(fvers, hnum, hattrs,
385                 utype);
386
387         free(hattrs);
388
389         return (stat);
390 }
391
392 extern CSA_return_code
393 _DtCm_check_entry_cms_attributes(
394         int             fvers,
395         uint            num_attrs,
396         cms_attribute   *attrs,
397         CSA_flags       utype,
398         boolean_t       checkattrnum)
399 {
400         CSA_return_code stat;
401         uint            hnum;
402         cms_attribute   *hattrs;
403         uint            realnum;
404
405         if ((stat = hash_entry_attrs(num_attrs, NULL, attrs, &hnum, &hattrs,
406             &realnum)) != CSA_SUCCESS)
407                 return (stat);
408
409         if (checkattrnum == B_TRUE && realnum == 0) {
410                 free(hattrs);
411                 return (CSA_E_INVALID_PARAMETER);
412         }
413
414         stat = _DtCm_check_hashed_entry_attributes(fvers, hnum, hattrs,
415                 utype);
416
417         free(hattrs);
418
419         return (stat);
420 }
421
422 /*
423  * copy attributes
424  * attributes with a name but NULL value is allowed
425  * attributes with null names are ignored
426  * validity of attributes should be checked before calling this routine
427  *
428  * Note: the first entry is not used
429  */
430 extern CSA_return_code
431 _DtCm_copy_cms_attributes(
432         uint srcsize,
433         cms_attribute *srcattrs,
434         uint *dstsize,
435         cms_attribute **dstattrs)
436 {
437         int     i, j;
438         CSA_return_code stat = CSA_SUCCESS;
439         cms_attribute   *attrs;
440
441         if (dstsize == NULL || dstattrs == NULL)
442                 return (CSA_E_INVALID_PARAMETER);
443
444         *dstsize = 0;
445         *dstattrs = NULL;
446
447         if (srcsize == 0)
448                 return (CSA_SUCCESS);
449
450         if ((attrs = calloc(1, sizeof(cms_attribute) * (srcsize + 1))) == NULL)
451                 return (CSA_E_INSUFFICIENT_MEMORY);
452
453         /* firstr element is not used */
454         for (i = 1, j = 1; i <= srcsize; i++) {
455                 if (srcattrs[i].name.name != NULL) {
456                         if ((stat = _DtCm_copy_cms_attribute(&attrs[j],
457                             &srcattrs[i], B_TRUE)) != CSA_SUCCESS)
458                                 break;
459                         else
460                                 j++;
461                 }
462         }
463
464         if (stat != CSA_SUCCESS && j > 1) {
465                 _DtCm_free_cms_attributes(j, attrs);
466                 free(attrs);
467         } else {
468                 *dstsize = j - 1;
469                 *dstattrs = attrs;
470         }
471
472         return(stat);
473 }
474
475 /*
476  * Frees the name and value field of the array, but not
477  * array itself.
478  * note: element 0 is not used
479  */
480 extern void
481 _DtCm_free_cms_attributes(uint size, cms_attribute *attrs)
482 {
483         int i;
484
485         for (i = 0; i < size; i++) {
486                 if (attrs[i].name.name) {
487                         free(attrs[i].name.name);
488                         attrs[i].name.name = NULL;
489
490                         if (attrs[i].value) {
491                                 _DtCm_free_cms_attribute_value(attrs[i].value);
492                                 attrs[i].value = NULL;
493                         }
494                 }
495         }
496 }
497
498 /*
499  * Frees the name and value field of the array, but not
500  * array itself.
501  */
502 extern void
503 _DtCm_free_attributes(uint size, CSA_attribute * attrs)
504 {
505         int i;
506
507         for (i = 0; i < size; i++) {
508                 if (attrs[i].name) {
509                         free(attrs[i].name);
510                         attrs[i].name = NULL;
511
512                         if (attrs[i].value) {
513                                 _DtCm_free_attribute_value(attrs[i].value);
514                                 attrs[i].value = NULL;
515                         }
516                 }
517         }
518 }
519
520 /*
521  * Free the value part of the cms_attribute structure.
522  * note: element 0 is not used
523  */
524 extern void
525 _DtCm_free_cms_attribute_values(uint size, cms_attribute *attrs)
526 {
527         int     i;
528
529         for (i = 1; i <= size; i++) {
530                 if (attrs[i].value) {
531                         _DtCm_free_cms_attribute_value(attrs[i].value);
532                         attrs[i].value = NULL;
533                 }
534         }
535 }
536
537 /*
538  * Free the value part of the the attribute structure.
539  */
540 extern void
541 _DtCm_free_attribute_values(uint size, CSA_attribute * attrs)
542 {
543         int     i;
544
545         for (i = 0; i < size; i++) {
546                 if (attrs[i].value) {
547                         _DtCm_free_attribute_value(attrs[i].value);
548                         attrs[i].value = NULL;
549                 }
550         }
551 }
552
553 extern char *
554 _DtCm_old_reminder_name_to_name(char *oldname)
555 {
556         if (strcmp(oldname, _DtCM_OLD_ATTR_BEEP_REMINDER) == 0)
557                 return (CSA_ENTRY_ATTR_AUDIO_REMINDER);
558         else if (strcmp(oldname, _DtCM_OLD_ATTR_FLASH_REMINDER) == 0)
559                 return (CSA_ENTRY_ATTR_FLASHING_REMINDER);
560         else if (strcmp(oldname, _DtCM_OLD_ATTR_MAIL_REMINDER) == 0)
561                 return (CSA_ENTRY_ATTR_MAIL_REMINDER);
562         else if (strcmp(oldname, _DtCM_OLD_ATTR_POPUP_REMINDER) == 0)
563                 return (CSA_ENTRY_ATTR_POPUP_REMINDER);
564         else
565                 return (oldname);
566 }
567
568 extern int
569 _DtCm_old_reminder_name_to_index(char *oldname)
570 {
571         char    *name;
572
573         name = _DtCm_old_reminder_name_to_name(oldname);
574
575         return (_DtCm_get_index_from_table(_DtCm_entry_name_tbl, name));
576 }
577
578 /*
579  * Given an attribute name, return the corresponding
580  * attribute number that's supported by old backends (v4 and before).
581  */
582 extern CSA_return_code
583 _DtCm_get_old_attr_by_name(char *name, _DtCm_old_attrs *attr)
584 {
585         int     index;
586
587         index = _DtCm_get_index_from_table(_DtCm_entry_name_tbl, name);
588         if (index > 0 && index <= _DtCM_DEFINED_ENTRY_ATTR_SIZE) {
589
590                 if (_CSA_entry_attr_info[index].oldattr
591                     != _DtCm_old_attr_unknown) {
592                         *attr = _CSA_entry_attr_info[index].oldattr;
593                         return (CSA_SUCCESS);
594                 } else
595                         return (CSA_E_UNSUPPORTED_ATTRIBUTE);
596         } else
597                 return (CSA_E_INVALID_ATTRIBUTE);
598 }
599
600 /*
601  * Given an attribute index, return the corresponding
602  * attribute number that's supported by old backends (v4 and before).
603  */
604 extern CSA_return_code
605 _DtCm_get_old_attr_by_index(int index, _DtCm_old_attrs *attr)
606 {
607         if (index <= _DtCM_DEFINED_ENTRY_ATTR_SIZE) {
608                 if (_CSA_entry_attr_info[index].oldattr
609                     != _DtCm_old_attr_unknown) {
610                         *attr = _CSA_entry_attr_info[index].oldattr;
611                         return (CSA_SUCCESS);
612                 } else
613                         return (CSA_E_UNSUPPORTED_ATTRIBUTE);
614         } else
615                 return (CSA_E_INVALID_ATTRIBUTE);
616 }
617
618 /*
619  * copy attribute
620  * the attribute structure should contain valid value
621  * a NULL attribute value is valid
622  */
623 extern CSA_return_code
624 _DtCm_copy_cms_attribute(
625         cms_attribute *to,
626         cms_attribute *from,
627         boolean_t copyname)
628 {
629         CSA_return_code stat = CSA_SUCCESS;
630         char            *name;
631
632         if (to == NULL)
633                 return (CSA_E_INVALID_PARAMETER);
634
635         /* copy the attribute name */
636         if (copyname) {
637                 if ((name = strdup(from->name.name)) == NULL)
638                         return(CSA_E_INSUFFICIENT_MEMORY);
639         }
640
641         if ((stat = _DtCm_copy_cms_attr_val(from->value, &to->value))
642             == CSA_SUCCESS) {
643                 if (copyname) {
644                         to->name.name = name;
645                         to->name.num = from->name.num;
646                 }
647         } else if (copyname)
648                 free (name);
649
650         return(stat);
651 }
652
653 extern CSA_return_code
654 _DtCm_copy_cms_attr_val(cms_attribute_value *from, cms_attribute_value **to)
655 {
656         CSA_return_code stat = CSA_SUCCESS;
657         cms_attribute_value     *val;
658
659         if (to == NULL)
660                 return (CSA_E_INVALID_PARAMETER);
661
662         /* copy the attribute value */
663         if (from == NULL)
664                 val = NULL;
665         else {
666                 if ((val = (cms_attribute_value *)calloc(1,
667                     sizeof(cms_attribute_value))) == NULL)
668                         return (CSA_E_INSUFFICIENT_MEMORY);
669
670                 switch (from->type) {
671                 case CSA_VALUE_BOOLEAN:
672                 case CSA_VALUE_ENUMERATED:
673                 case CSA_VALUE_FLAGS:
674                 case CSA_VALUE_UINT32:
675                 case CSA_VALUE_SINT32:
676                         val->item.uint32_value = from->item.uint32_value;
677                         break;
678
679                 case CSA_VALUE_STRING:
680                 case CSA_VALUE_DATE_TIME:
681                 case CSA_VALUE_DATE_TIME_RANGE:
682                 case CSA_VALUE_TIME_DURATION:
683                 case CSA_VALUE_CALENDAR_USER:
684                         if (from->item.string_value)
685                                 val->item.string_value =
686                                         strdup(from->item.string_value);
687                         else
688                                 val->item.string_value = calloc(1, 1);
689                         if (val->item.string_value == NULL)
690                                 stat = CSA_E_INSUFFICIENT_MEMORY;
691                         break;
692
693                 case CSA_VALUE_REMINDER:
694                         if (from->item.reminder_value == NULL)
695                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
696                         else
697                                 stat = _DtCm_copy_reminder(
698                                         from->item.reminder_value,
699                                         &val->item.reminder_value);
700                         break;
701                 case CSA_VALUE_ATTENDEE_LIST:
702                         stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
703                         break;
704                 case CSA_VALUE_ACCESS_LIST:
705                         if (from->item.access_list_value &&
706                             (val->item.access_list_value =
707                             _DtCm_copy_cms_access_list(
708                             from->item.access_list_value)) == NULL) {
709
710                                 stat = CSA_E_INSUFFICIENT_MEMORY;
711                         }
712                         break;
713                 case CSA_VALUE_DATE_TIME_LIST:
714                         if (from->item.date_time_list_value &&
715                             (val->item.date_time_list_value =
716                             _DtCm_copy_date_time_list(
717                             from->item.date_time_list_value)) == NULL) {
718
719                                 stat = CSA_E_INSUFFICIENT_MEMORY;
720                         }
721                         break;
722                 case CSA_VALUE_OPAQUE_DATA:
723                         if (from->item.opaque_data_value) {
724                                 stat = _DtCm_copy_opaque_data(
725                                         from->item.opaque_data_value,
726                                         &val->item.opaque_data_value);
727                         }
728                         break;
729                 default:
730                         stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
731                         break;
732                 }
733
734                 if (stat != CSA_SUCCESS)
735                         free(val);
736                 else
737                         val->type = from->type;
738         }
739
740         if (stat == CSA_SUCCESS) {
741                 *to = val;
742         }
743
744         return(stat);
745 }
746
747 /*
748  * copy the attribute name, and convert the attribute value
749  */
750 extern CSA_return_code
751 _DtCm_cms2csa_attribute(cms_attribute from, CSA_attribute *to)
752 {
753         CSA_return_code         stat;
754         char                    *name;
755         CSA_attribute_value     *val;
756
757         if ((name = strdup(from.name.name)) == NULL)
758                 return (CSA_E_INSUFFICIENT_MEMORY);
759
760         if ((stat = _DtCm_cms2csa_attrval(from.value, &val)) == CSA_SUCCESS) {
761                 to->name = name;
762                 to->value = val;
763         } else
764                 free(name);
765
766         return (stat);
767 }
768
769 extern CSA_return_code
770 _DtCm_cms2csa_attrval(cms_attribute_value *from, CSA_attribute_value **to)
771 {
772         CSA_return_code stat = CSA_SUCCESS;
773         CSA_attribute_value     *val;
774
775         if (to == NULL)
776                 return (CSA_E_INVALID_PARAMETER);
777
778         /* copy the attribute value */
779         if (from == NULL)
780                 val = NULL;
781         else {
782                 if ((val = (CSA_attribute_value *)calloc(1,
783                     sizeof(CSA_attribute_value))) == NULL)
784                         return (CSA_E_INSUFFICIENT_MEMORY);
785
786                 switch (from->type) {
787                 case CSA_VALUE_BOOLEAN:
788                 case CSA_VALUE_ENUMERATED:
789                 case CSA_VALUE_FLAGS:
790                 case CSA_VALUE_UINT32:
791                 case CSA_VALUE_SINT32:
792                         val->item.uint32_value = from->item.uint32_value;
793                         break;
794
795                 case CSA_VALUE_STRING:
796                 case CSA_VALUE_DATE_TIME:
797                 case CSA_VALUE_DATE_TIME_RANGE:
798                 case CSA_VALUE_TIME_DURATION:
799                         if (from->item.string_value)
800                                 val->item.string_value =
801                                         strdup(from->item.string_value);
802                         else
803                                 val->item.string_value = calloc(1, 1);
804                         if (val->item.string_value == NULL)
805                                 stat = CSA_E_INSUFFICIENT_MEMORY;
806                         break;
807
808                 case CSA_VALUE_REMINDER:
809                         if (from->item.reminder_value == NULL)
810                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
811                         else
812                                 stat = _DtCm_copy_reminder(
813                                         from->item.reminder_value,
814                                         &val->item.reminder_value);
815                         break;
816                 case CSA_VALUE_CALENDAR_USER:
817                         if (from->item.calendar_user_value == NULL)
818                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
819                         else
820                                 stat = convert_cms_user_to_csa_user(
821                                         from->item.calendar_user_value,
822                                         &val->item.calendar_user_value);
823                         break;
824                 case CSA_VALUE_ACCESS_LIST:
825                         stat = _DtCm_cms2csa_access_list(
826                                 from->item.access_list_value,
827                                 &val->item.access_list_value);
828                         break;
829                 case CSA_VALUE_ATTENDEE_LIST:
830                         stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
831                         break;
832                 case CSA_VALUE_DATE_TIME_LIST:
833                         if (from->item.date_time_list_value &&
834                             (val->item.date_time_list_value =
835                             _DtCm_copy_date_time_list(
836                             from->item.date_time_list_value)) == NULL) {
837                                 stat = CSA_E_INSUFFICIENT_MEMORY;
838                         }
839                         break;
840                 case CSA_VALUE_OPAQUE_DATA:
841                         if (from->item.opaque_data_value) {
842                                 stat = _DtCm_copy_opaque_data(
843                                         from->item.opaque_data_value,
844                                         &val->item.opaque_data_value);
845                         } else
846                                 val->item.opaque_data_value = NULL;
847                         break;
848                 default:
849                         stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
850                         break;
851                 }
852
853                 if (stat != CSA_SUCCESS)
854                         free(val);
855                 else
856                         val->type = from->type;
857         }
858
859         if (stat == CSA_SUCCESS) {
860                 *to = val;
861         }
862
863         return(stat);
864 }
865
866 extern void
867 _DtCm_free_cms_attribute_value(cms_attribute_value *val)
868 {
869         if (val == NULL)
870                 return;
871
872         switch (val->type) {
873         case CSA_VALUE_STRING:
874         case CSA_VALUE_DATE_TIME:
875         case CSA_VALUE_DATE_TIME_RANGE:
876         case CSA_VALUE_TIME_DURATION:
877         case CSA_VALUE_CALENDAR_USER:
878                 if (val->item.string_value)
879                         free(val->item.string_value);
880                 break;
881
882         case CSA_VALUE_REMINDER:
883                 if (val->item.reminder_value)
884                         _DtCm_free_reminder(val->item.reminder_value);
885                 break;
886         case CSA_VALUE_ACCESS_LIST:
887                 if (val->item.access_list_value)
888                         _DtCm_free_cms_access_entry(val->item.access_list_value);
889                 break;
890         case CSA_VALUE_DATE_TIME_LIST:
891                 if (val->item.date_time_list_value)
892                         _DtCm_free_date_time_list(
893                                 val->item.date_time_list_value);
894                 break;
895         case CSA_VALUE_OPAQUE_DATA:
896                 if (val->item.opaque_data_value) {
897                         _DtCm_free_opaque_data(val->item.opaque_data_value);
898                 }
899                 break;
900         }
901         free(val);
902 }
903
904 extern void
905 _DtCm_free_attribute_value(CSA_attribute_value *val)
906 {
907         if (val == NULL)
908                 return;
909
910         switch (val->type) {
911         case CSA_VALUE_STRING:
912         case CSA_VALUE_DATE_TIME:
913         case CSA_VALUE_DATE_TIME_RANGE:
914         case CSA_VALUE_TIME_DURATION:
915                 if (val->item.string_value)
916                         free(val->item.string_value);
917                 break;
918
919         case CSA_VALUE_REMINDER:
920                 if (val->item.reminder_value)
921                         _DtCm_free_reminder(val->item.reminder_value);
922                 break;
923         case CSA_VALUE_ACCESS_LIST:
924                 if (val->item.access_list_value)
925                         _DtCm_free_csa_access_list(val->item.access_list_value);
926                 break;
927         case CSA_VALUE_CALENDAR_USER:
928                 if (val->item.calendar_user_value) {
929                         if (val->item.calendar_user_value->user_name)
930                                 free(val->item.calendar_user_value->user_name);
931                         if (val->item.calendar_user_value->calendar_address)
932                                 free(val->item.calendar_user_value->user_name);
933                         free(val->item.calendar_user_value);
934                 }
935                 break;
936         case CSA_VALUE_DATE_TIME_LIST:
937                 if (val->item.date_time_list_value)
938                         _DtCm_free_date_time_list(
939                                 val->item.date_time_list_value);
940                 break;
941         case CSA_VALUE_OPAQUE_DATA:
942                 if (val->item.opaque_data_value) {
943                         _DtCm_free_opaque_data(val->item.opaque_data_value);
944                 }
945                 break;
946         }
947         free(val);
948 }
949
950 extern CSA_return_code
951 _DtCm_set_uint32_attrval(uint numval, cms_attribute_value **attrval)
952 {
953         cms_attribute_value     *val;
954
955         if ((val = (cms_attribute_value *)malloc(sizeof(cms_attribute_value)))
956             == NULL) {
957                 return (CSA_E_INSUFFICIENT_MEMORY);
958         }
959
960         val->type = CSA_VALUE_UINT32;
961         val->item.uint32_value = numval;
962
963         *attrval = val;
964
965         return (CSA_SUCCESS);
966 }
967
968 extern CSA_return_code
969 _DtCm_set_sint32_attrval(int numval, cms_attribute_value **attrval)
970 {
971         cms_attribute_value     *val;
972
973         if ((val = (cms_attribute_value *)malloc(sizeof(cms_attribute_value)))
974             == NULL) {
975                 return (CSA_E_INSUFFICIENT_MEMORY);
976         }
977
978         val->type = CSA_VALUE_SINT32;
979         val->item.sint32_value = numval;
980
981         *attrval = val;
982
983         return (CSA_SUCCESS);
984 }
985
986 extern CSA_return_code
987 _DtCm_set_string_attrval(
988         char *strval,
989         cms_attribute_value **attrval,
990         CSA_enum type)
991 {
992         cms_attribute_value     *val;
993
994         if (type != CSA_VALUE_STRING && type != CSA_VALUE_DATE_TIME &&
995             type != CSA_VALUE_DATE_TIME_RANGE &&
996             type != CSA_VALUE_TIME_DURATION && type != CSA_VALUE_CALENDAR_USER)
997                 return (CSA_E_INVALID_PARAMETER);
998
999         if ((val = (cms_attribute_value *)malloc(sizeof(cms_attribute_value)))
1000             == NULL) {
1001                 return (CSA_E_INSUFFICIENT_MEMORY);
1002         }
1003
1004         val->type = type;
1005
1006         if (strval == NULL) {
1007                 val->item.string_value = NULL;
1008         } else if ((val->item.string_value = strdup(strval)) == NULL) {
1009                 free(val);
1010                 return (CSA_E_INSUFFICIENT_MEMORY);
1011         }
1012
1013         *attrval = val;
1014
1015         return (CSA_SUCCESS);
1016 }
1017
1018 extern CSA_return_code
1019 _DtCm_set_user_attrval(
1020         char *user,
1021         cms_attribute_value **attrval)
1022 {
1023         cms_attribute_value     *val;
1024
1025         if (user == NULL) {
1026                 *attrval = NULL;
1027                 return (CSA_SUCCESS);
1028         }
1029
1030         if ((val = (cms_attribute_value *)malloc(sizeof(cms_attribute_value)))
1031             == NULL) {
1032                 return (CSA_E_INSUFFICIENT_MEMORY);
1033         }
1034
1035         val->type = CSA_VALUE_CALENDAR_USER;
1036
1037         if ((val->item.calendar_user_value = strdup(user)) == NULL) {
1038                 free(val);
1039                 return (CSA_E_INSUFFICIENT_MEMORY);
1040         }
1041
1042         *attrval = val;
1043
1044         return (CSA_SUCCESS);
1045 }
1046
1047 extern CSA_return_code
1048 _DtCm_set_reminder_attrval(CSA_reminder *remval, cms_attribute_value **attrval)
1049 {
1050         cms_attribute_value *val;
1051         CSA_return_code stat;
1052
1053         if (remval == NULL)
1054                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
1055
1056         if ((val = (cms_attribute_value *)malloc(sizeof(cms_attribute_value)))
1057             == NULL) {
1058                 return (CSA_E_INSUFFICIENT_MEMORY);
1059         }
1060
1061         val->type = CSA_VALUE_REMINDER;
1062
1063         if ((stat = _DtCm_copy_reminder(remval, &val->item.reminder_value))
1064             != CSA_SUCCESS) {
1065                 free(val);
1066                 return (stat);
1067         } else {
1068
1069                 *attrval = val;
1070
1071                 return (CSA_SUCCESS);
1072         }
1073 }
1074
1075 extern CSA_return_code
1076 _DtCm_set_csa_access_attrval(
1077         cms_access_entry *aval,
1078         CSA_attribute_value **attrval)
1079 {
1080         CSA_attribute_value *val;
1081         CSA_return_code stat = CSA_SUCCESS;
1082
1083         if ((val = (CSA_attribute_value *)malloc(sizeof(CSA_attribute_value)))
1084             == NULL) {
1085                 return (CSA_E_INSUFFICIENT_MEMORY);
1086         }
1087
1088         val->type = CSA_VALUE_ACCESS_LIST;
1089
1090         if (aval == NULL) {
1091
1092                 val->item.access_list_value = NULL;
1093
1094         } else {
1095         
1096                 stat = _DtCm_cms2csa_access_list(aval,
1097                         &val->item.access_list_value);
1098
1099         }
1100
1101         if (stat == CSA_SUCCESS)
1102                 *attrval = val;
1103         else
1104                 free(val);
1105
1106         return (stat);
1107 }
1108
1109 extern CSA_return_code
1110 _DtCm_set_opaque_attrval(CSA_opaque_data *data, cms_attribute_value **attrval)
1111 {
1112         CSA_return_code stat;
1113         cms_attribute_value     *val;
1114
1115         if (data == NULL)
1116                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
1117
1118         if ((val = (cms_attribute_value *)malloc(sizeof(cms_attribute_value)))
1119             == NULL) {
1120                 return (CSA_E_INSUFFICIENT_MEMORY);
1121         }
1122
1123         val->type = CSA_VALUE_OPAQUE_DATA;
1124
1125         if ((stat = _DtCm_copy_opaque_data(data, &val->item.opaque_data_value))
1126             != CSA_SUCCESS) {
1127                 free(val);
1128                 return (stat);
1129         } else {
1130
1131                 *attrval = val;
1132                 return (CSA_SUCCESS);
1133         }
1134 }
1135
1136 extern CSA_return_code
1137 _DtCm_set_csa_uint32_attrval(uint numval, CSA_attribute_value **attrval)
1138 {
1139         CSA_attribute_value     *val;
1140
1141         if ((val = (CSA_attribute_value *)malloc(sizeof(CSA_attribute_value)))
1142             == NULL) {
1143                 return (CSA_E_INSUFFICIENT_MEMORY);
1144         }
1145
1146         val->type = CSA_VALUE_UINT32;
1147         val->item.uint32_value = numval;
1148
1149         *attrval = val;
1150
1151         return (CSA_SUCCESS);
1152 }
1153
1154 extern CSA_return_code
1155 _DtCm_set_csa_string_attrval(
1156         char *strval,
1157         CSA_attribute_value **attrval,
1158         CSA_enum type)
1159 {
1160         CSA_attribute_value     *val;
1161
1162         if (type != CSA_VALUE_STRING && type != CSA_VALUE_DATE_TIME &&
1163             type != CSA_VALUE_DATE_TIME_RANGE &&
1164             type != CSA_VALUE_TIME_DURATION && type != CSA_VALUE_CALENDAR_USER)
1165                 return (CSA_E_INVALID_PARAMETER);
1166
1167         if ((val = (CSA_attribute_value *)malloc(sizeof(CSA_attribute_value)))
1168             == NULL) {
1169                 return (CSA_E_INSUFFICIENT_MEMORY);
1170         }
1171
1172         val->type = type;
1173
1174         if (strval == NULL) {
1175                 val->item.string_value = NULL;
1176         } else if ((val->item.string_value = strdup(strval)) == NULL) {
1177                 free(val);
1178                 return (CSA_E_INSUFFICIENT_MEMORY);
1179         }
1180
1181         *attrval = val;
1182
1183         return (CSA_SUCCESS);
1184 }
1185
1186 extern void
1187 _DtCm_free_csa_access_list(CSA_access_list alist)
1188 {
1189         CSA_access_list nptr;
1190
1191         while (alist != NULL) {
1192                 nptr = alist->next;
1193
1194                 if (alist->user) {
1195                         if (alist->user->user_name) {
1196                                 free(alist->user->user_name);
1197                         }
1198                         if (alist->user->calendar_address) {
1199                                 free(alist->user->calendar_address);
1200                         }
1201                         free(alist->user);
1202                 }
1203
1204                 free(alist);
1205
1206                 alist = nptr;
1207         }
1208 }
1209
1210 extern void
1211 _DtCm_free_date_time_list(CSA_date_time_list list)
1212 {
1213         CSA_date_time_entry *nptr;
1214
1215         while (list != NULL) {
1216                 nptr = list->next;
1217
1218                 if (list->date_time) {
1219                         free(list->date_time);
1220                 }
1221
1222                 free(list);
1223
1224                 list = nptr;
1225         }
1226 }
1227
1228 extern void
1229 _DtCm_free_cms_access_entry(cms_access_entry *list)
1230 {
1231         cms_access_entry *nptr;
1232
1233         while (list != NULL) {
1234                 nptr = list->next;
1235
1236                 if (list->user) {
1237                         free(list->user);
1238                 }
1239
1240                 free(list);
1241
1242                 list = nptr;
1243         }
1244 }
1245
1246 extern cms_access_entry *
1247 _DtCm_copy_cms_access_list(cms_access_entry *alist)
1248 {
1249         cms_access_entry        *l, *head, *prev;
1250         boolean_t       cleanup = B_FALSE;
1251
1252         prev = head = NULL;
1253         while (alist != NULL) {
1254                 if ((l = (cms_access_entry *)calloc(1, sizeof(cms_access_entry)))
1255                     == NULL) {
1256                         cleanup = B_TRUE;
1257                         break;
1258                 }
1259
1260                 if ((l->user = strdup(alist->user)) == NULL) {
1261                         free(l);
1262                         cleanup = B_TRUE;
1263                         break;
1264                 }
1265
1266                 l->rights = alist->rights;
1267                 l->next = NULL;
1268
1269                 if (head == NULL)
1270                         head = l;
1271                 else
1272                         prev->next = l;
1273                 prev = l;
1274
1275                 alist = alist->next;
1276         }
1277
1278         if (cleanup == B_TRUE) {
1279                 _DtCm_free_cms_access_entry(head);
1280                 head = NULL;
1281         }
1282         return(head);
1283 }
1284
1285 extern CSA_return_code
1286 _DtCm_cms2csa_access_list(
1287         cms_access_entry *cmslist,
1288         CSA_access_rights **csalist)
1289 {
1290         CSA_return_code stat = CSA_SUCCESS;
1291         CSA_access_rights *to, *head, *prev;
1292
1293         head = prev = NULL;
1294         while (cmslist != NULL) {
1295                 if ((to = (CSA_access_rights *)calloc(1,
1296                     sizeof(CSA_access_rights))) == NULL) {
1297                         stat = CSA_E_INSUFFICIENT_MEMORY;
1298                         break;
1299                 }
1300
1301                 if ((to->user = (CSA_calendar_user *)calloc(1,
1302                     sizeof(CSA_calendar_user))) == NULL) {
1303                         free(to);
1304                         stat = CSA_E_INSUFFICIENT_MEMORY;
1305                         break;
1306                 }
1307
1308                 if ((to->user->user_name = strdup(cmslist->user)) == NULL) {
1309                         free(to->user);
1310                         free(to);
1311                         stat = CSA_E_INSUFFICIENT_MEMORY;
1312                         break;
1313                 }
1314
1315                 to->rights = cmslist->rights;
1316                 to->next = NULL;
1317
1318                 if (head == NULL)
1319                         head = to;
1320                 else
1321                         prev->next = to;
1322
1323                 prev = to;
1324
1325                 cmslist = cmslist->next;
1326         }
1327
1328         if (stat != CSA_SUCCESS) {
1329                 _DtCm_free_csa_access_list(head);
1330                 head = NULL;
1331         }
1332
1333         *csalist = head;
1334         return (stat);
1335 }
1336
1337 extern CSA_return_code
1338 _DtCm_csa2cms_access_list(
1339         CSA_access_rights *csalist,
1340         cms_access_entry **cmslist)
1341 {
1342         CSA_return_code stat = CSA_SUCCESS;
1343         cms_access_entry *to, *head, *prev;
1344
1345         head = prev = NULL;
1346         while (csalist != NULL) {
1347                 if ((to = (cms_access_entry *)calloc(1,
1348                     sizeof(cms_access_entry))) == NULL) {
1349                         stat = CSA_E_INSUFFICIENT_MEMORY;
1350                         break;
1351                 }
1352
1353                 if (csalist->user->user_name) {
1354                         if ((to->user = strdup(csalist->user->user_name))
1355                             == NULL) {
1356                                 stat = CSA_E_INSUFFICIENT_MEMORY;
1357                                 free(to);
1358                                 break;
1359                         }
1360                 } else {
1361                         stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
1362                         free(to);
1363                         break;
1364                 }
1365
1366                 to->rights = csalist->rights;
1367                 to->next = NULL;
1368
1369                 if (head == NULL)
1370                         head = to;
1371                 else
1372                         prev->next = to;
1373
1374                 prev = to;
1375
1376                 csalist = csalist->next;
1377         }
1378
1379         if (stat != CSA_SUCCESS) {
1380                 _DtCm_free_cms_access_entry(head);
1381                 head = NULL;
1382         }
1383
1384         *cmslist = head;
1385         return (stat);
1386 }
1387
1388 extern CSA_date_time_list
1389 _DtCm_copy_date_time_list(CSA_date_time_list dlist)
1390 {
1391         CSA_date_time_entry     *l, *head, *prev;
1392         boolean_t       cleanup = B_FALSE;
1393
1394         prev = head = NULL;
1395         while (dlist != NULL) {
1396                 if ((l = (CSA_date_time_entry *)calloc(1,
1397                     sizeof(CSA_date_time_entry))) == NULL) {
1398                         cleanup = B_TRUE;
1399                         break;
1400                 }
1401
1402                 if ((l->date_time = strdup(dlist->date_time)) == NULL) {
1403                         free(l);
1404                         cleanup = B_TRUE;
1405                         break;
1406                 }
1407
1408                 l->next = NULL;
1409
1410                 if (head == NULL)
1411                         head = l;
1412                 else
1413                         prev->next = l;
1414                 prev = l;
1415
1416                 dlist = dlist->next;
1417         }
1418
1419         if (cleanup == B_TRUE) {
1420                 _DtCm_free_date_time_list(head);
1421                 head = NULL;
1422         }
1423         return(head);
1424 }
1425
1426 extern CSA_return_code
1427 _DtCm_copy_reminder(CSA_reminder *from, CSA_reminder **to)
1428 {
1429         CSA_reminder *newval;
1430
1431         if ((newval = (CSA_reminder *)calloc(1, sizeof(CSA_reminder))) == NULL)
1432                 return (CSA_E_INSUFFICIENT_MEMORY);
1433
1434         if (from->lead_time) {
1435                 if ((newval->lead_time = strdup(from->lead_time)) == NULL) {
1436                         free(newval);
1437                         return (CSA_E_INSUFFICIENT_MEMORY);
1438                 }
1439         } else {
1440                 free(newval);
1441                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
1442         }
1443
1444         if (from->snooze_time)
1445                 newval->snooze_time = strdup(from->snooze_time);
1446         else
1447                 newval->snooze_time = calloc(1, 1);
1448
1449         if (newval->snooze_time == NULL) {
1450                 _DtCm_free_reminder(newval);
1451                 return (CSA_E_INSUFFICIENT_MEMORY);
1452         }
1453
1454         newval->repeat_count = from->repeat_count;
1455
1456         if (from->reminder_data.size > 0) {
1457                 newval->reminder_data.size = from->reminder_data.size;
1458                 if ((newval->reminder_data.data = malloc(
1459                     newval->reminder_data.size)) == NULL) {
1460                         _DtCm_free_reminder(newval);
1461                         return (CSA_E_INSUFFICIENT_MEMORY);
1462                 }
1463                 memcpy(newval->reminder_data.data, from->reminder_data.data,
1464                         from->reminder_data.size);
1465         }
1466
1467         *to = newval;
1468         return (CSA_SUCCESS);
1469 }
1470
1471 extern void
1472 _DtCm_free_reminder(CSA_reminder *val)
1473 {
1474         if (val == NULL) return;
1475
1476         if (val->lead_time)
1477                 free(val->lead_time);
1478
1479         if (val->snooze_time)
1480                 free(val->snooze_time);
1481
1482         if (val->reminder_data.size > 0)
1483                 free(val->reminder_data.data);
1484
1485         free(val);
1486 }
1487
1488 extern CSA_return_code
1489 _DtCm_copy_opaque_data(CSA_opaque_data *from, CSA_opaque_data **to)
1490 {
1491         CSA_opaque_data *val;
1492
1493         if ((val = (CSA_opaque_data *)calloc(1, sizeof(CSA_opaque_data)))
1494             == NULL) {
1495                 return (CSA_E_INSUFFICIENT_MEMORY);
1496         }
1497
1498         if (from->size > 0) {
1499                 val->size = from->size;
1500                 if ((val->data = malloc(from->size)) == NULL) {
1501                         free(val);
1502                         return (CSA_E_INSUFFICIENT_MEMORY);
1503                 }
1504                 memcpy(val->data, from->data, from->size);
1505         } else {
1506                 val->size = 0;
1507                 val->data = NULL;
1508         }
1509
1510         *to = val;
1511
1512         return (CSA_SUCCESS);
1513 }
1514
1515 extern void
1516 _DtCm_free_opaque_data(CSA_opaque_data *val)
1517 {
1518         if (val == NULL) return;
1519
1520         if (val->data)
1521                 free(val->data);
1522         free(val);
1523 }
1524
1525 extern void
1526 _DtCm_get_attribute_types(uint size, int *types)
1527 {
1528         int     i;
1529
1530         for (i = 1; i <= size; i++) {
1531                 types[i] = _CSA_entry_attr_info[i].type;
1532         }
1533 }
1534
1535 /******************************************************************************
1536  * static functions used within the file
1537  ******************************************************************************/
1538
1539 /*
1540  * The passed in attributes are hashed.
1541  * For each attribute, check
1542  * 1. type is valid and supported
1543  * 2. if it's a date time value type, check validity of date time.
1544  * 3. if it's a reminder value type, check validity of lead time.
1545  * 4. if it is a defined attribute, check that the data type is correct.
1546  * 5. if it is a defined attribute and checkreadonly is set, check
1547  *      that it's not readonly.
1548  */
1549 static CSA_return_code
1550 check_predefined_attrs(
1551         int                     fver,
1552         uint                    num_attrs,
1553         cms_attribute           *attrs,
1554         boolean_t               checkreadonly,
1555         _DtCmNameTable          *tbl,
1556         uint                    num_defined,
1557         _DtCmAttrInfo           *our_attrs)
1558 {
1559         int             i, index, cl;
1560         CSA_reminder    *rptr;
1561         time_t          tick;
1562
1563         for (i = 0; i < num_attrs; i++) {
1564
1565                 if (attrs[i].name.name == NULL)
1566                         continue;
1567
1568                 if (tbl == NULL)
1569                         index = i;
1570                 else
1571                         index = _DtCm_get_index_from_table(tbl,
1572                                         attrs[i].name.name); 
1573
1574                 if (index > 0 && index <= num_defined) {
1575
1576                         /* check whether the attribute is supported
1577                          * in this version
1578                          */
1579                         if (our_attrs[index].fst_vers == 0 ||
1580                             (fver < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
1581                             fver < our_attrs[index].fst_vers))
1582                                 return (CSA_E_UNSUPPORTED_ATTRIBUTE);
1583                         else if (our_attrs[index].fst_vers == -1)
1584                                 return (CSA_E_INVALID_ATTRIBUTE);
1585
1586                         /* check whether the attribute is readonly */
1587                         if (checkreadonly &&
1588                             ((fver < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
1589                             our_attrs[index].nex_ro) ||
1590                             (fver >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
1591                             our_attrs[index].ex_ro)))
1592                                 return (CSA_E_READONLY);
1593
1594                         /* check data type */
1595                         if (attrs[i].value &&
1596                             attrs[i].value->type != our_attrs[index].type)
1597                                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
1598
1599                         if (index == CSA_ENTRY_ATTR_CLASSIFICATION_I) {
1600                                 cl = attrs[i].value->item.uint32_value;
1601                                 if (cl < CSA_CLASS_PUBLIC ||
1602                                     cl > CSA_CLASS_CONFIDENTIAL)
1603                                         return (CSA_E_INVALID_ATTRIBUTE_VALUE);
1604                         }
1605
1606                         if (index == CSA_ENTRY_ATTR_TYPE_I) {
1607                                 cl = attrs[i].value->item.uint32_value;
1608                                 if (cl < CSA_TYPE_EVENT ||
1609                                     cl > CSA_X_DT_TYPE_OTHER)
1610                                         return (CSA_E_INVALID_ATTRIBUTE_VALUE);
1611                         }
1612
1613                 } else if (fver < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
1614                         return (CSA_E_INVALID_ATTRIBUTE);
1615                 }
1616
1617                 /* check validity of value type */
1618                 if (attrs[i].value) {
1619                         if (attrs[i].value->type < CSA_VALUE_BOOLEAN ||
1620                             attrs[i].value->type > CSA_VALUE_OPAQUE_DATA)
1621                                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
1622
1623                         /* cast the sint32_value element to the desired
1624                          * type to be safe since the value part could
1625                          * actually be a pointer to a CSA_attribute_value
1626                          */
1627                         switch (attrs[i].value->type) {
1628                         case CSA_VALUE_DATE_TIME:
1629                                 if (attrs[i].value->item.sint32_value == 0
1630                                     || _csa_iso8601_to_tick(
1631                                     (char *)attrs[i].value->item.sint32_value,
1632                                     &tick))
1633                                         return (CSA_E_INVALID_DATE_TIME);
1634                                 break;
1635                         case CSA_VALUE_REMINDER:
1636                                 rptr = (CSA_reminder *)
1637                                         attrs[i].value->item.sint32_value;
1638                                 if (rptr == NULL || rptr->lead_time == NULL ||
1639                                     _csa_iso8601_to_duration(rptr->lead_time,
1640                                                              &tick))
1641                                         return (CSA_E_INVALID_ATTRIBUTE_VALUE);
1642                                 break;
1643                         case CSA_VALUE_ATTENDEE_LIST:
1644                                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
1645                         }
1646                 }
1647         }
1648
1649         return (CSA_SUCCESS);
1650 }
1651
1652 static CSA_return_code
1653 convert_cms_user_to_csa_user(char *from, CSA_calendar_user **to)
1654 {
1655         CSA_calendar_user *newval;
1656
1657         if ((newval = (CSA_calendar_user *)calloc(1,
1658             sizeof(CSA_calendar_user))) == NULL)
1659                 return (CSA_E_INSUFFICIENT_MEMORY);
1660
1661         if (from) {
1662                 if ((newval->user_name = strdup(from)) == NULL) {
1663                         free(newval);
1664                         return (CSA_E_INSUFFICIENT_MEMORY);
1665                 }
1666         }
1667
1668         *to = newval;
1669         return (CSA_SUCCESS);
1670 }
1671
1672 static CSA_return_code
1673 hash_entry_attrs(
1674         uint            num_attrs,
1675         CSA_attribute   *csaattrs,
1676         cms_attribute   *cmsattrs,
1677         uint            *hnum,
1678         cms_attribute   **hattrs,
1679         uint            *num)
1680 {
1681         int                     i, j, index, count = 0;
1682         cms_attribute           *nattrs;
1683         char                    *name;
1684         cms_attribute_value     *val;
1685
1686         if ((nattrs = (cms_attribute *)calloc(1,
1687             sizeof(cms_attribute)*(num_attrs+_DtCM_DEFINED_ENTRY_ATTR_SIZE+1)))
1688             == NULL)
1689                 return (CSA_E_INSUFFICIENT_MEMORY);
1690
1691         for (i = 0, j = _DtCM_DEFINED_ENTRY_ATTR_SIZE + 1; i < num_attrs; i++) {
1692                 name = (csaattrs ? csaattrs[i].name : cmsattrs[i].name.name);
1693                 if (name == NULL)
1694                         continue;
1695                 else {
1696                         count++;
1697                         val = (csaattrs ?
1698                                 ((cms_attribute_value *)csaattrs[i].value) :
1699                                 cmsattrs[i].value);
1700                 }
1701
1702                 index = _DtCm_get_index_from_table(_DtCm_entry_name_tbl, name);
1703
1704                 if (index > 0) {
1705                         if (cmsattrs) cmsattrs[i].name.num = index;
1706
1707                         nattrs[index].name.name = name;
1708                         nattrs[index].value = val;
1709                 } else {
1710                         nattrs[j].name.name = name;
1711                         nattrs[j++].value = val;
1712                 }
1713         }
1714
1715         if (num) *num = count;
1716         *hnum = j - 1;
1717         *hattrs = nattrs;
1718         return (CSA_SUCCESS);
1719 }
1720
1721 static CSA_return_code
1722 hash_cal_attrs(
1723         uint            num_attrs,
1724         CSA_attribute   *csaattrs,
1725         cms_attribute   *cmsattrs,
1726         uint            *hnum,
1727         cms_attribute   **hattrs,
1728         uint            *num)
1729 {
1730         int                     i, j, index, count = 0;
1731         cms_attribute           *nattrs;
1732         char                    *name;
1733         cms_attribute_value     *val;
1734
1735         if ((nattrs = (cms_attribute *)calloc(1,
1736             sizeof(cms_attribute)*(num_attrs+_DtCM_DEFINED_CAL_ATTR_SIZE+1)))
1737             == NULL)
1738                 return (CSA_E_INSUFFICIENT_MEMORY);
1739
1740         for (i = 0, j = _DtCM_DEFINED_CAL_ATTR_SIZE + 1; i < num_attrs; i++) {
1741                 name = (csaattrs ? csaattrs[i].name : cmsattrs[i].name.name);
1742                 if (name == NULL)
1743                         continue;
1744                 else {
1745                         count++;
1746                         val = (csaattrs ?
1747                                 ((cms_attribute_value *)csaattrs[i].value) :
1748                                 cmsattrs[i].value);
1749                 }
1750
1751                 index = _DtCm_get_index_from_table(_DtCm_cal_name_tbl, name);
1752
1753                 if (index > 0) {
1754                         if (cmsattrs) cmsattrs[i].name.num = index;
1755
1756                         nattrs[index].name.name = name;
1757                         nattrs[index].value = val;
1758                 } else {
1759                         nattrs[j].name.name = name;
1760                         nattrs[j++].value = val;
1761                 }
1762         }
1763
1764         if (num) *num = count;
1765         *hnum = j - 1;
1766         *hattrs = nattrs;
1767         return (CSA_SUCCESS);
1768 }
1769
1770 static CSA_return_code
1771 _DtCm_check_hashed_cal_attributes(
1772         int             fvers,
1773         uint            num_attrs,
1774         cms_attribute   *attrs,
1775         char            *owner,
1776         char            *cname,
1777         boolean_t       checkreadonly,
1778         boolean_t       firsttime,
1779         boolean_t       csatype)
1780 {
1781         CSA_return_code stat;
1782         CSA_attribute_value     *csaval;
1783         cms_attribute_value     *cmsval;
1784         char                    *nattr = NULL; /* calendar name */
1785         char                    *oattr = NULL; /* calendar owner */
1786         char                    *cattr = NULL; /* character set */
1787         char                    *tattr = NULL; /* time zone */
1788
1789         if (firsttime) {
1790                 if (attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].name.name) {
1791                         if (attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].value == NULL
1792                             || attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].value->\
1793                             item.calendar_user_value == NULL)
1794                                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
1795
1796                         if (csatype) {
1797                                 csaval = (CSA_attribute_value *)attrs[\
1798                                         CSA_CAL_ATTR_CALENDAR_OWNER_I].value;
1799                                 stat = _CheckCalendarOwner(owner, csaval->type,
1800                                     (csaval && csaval->item.calendar_user_value?
1801                                     csaval->item.calendar_user_value->user_name:
1802                                     NULL));
1803                         } else {
1804                                 cmsval = attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].\
1805                                         value;
1806                                 stat = _CheckCalendarOwner(owner, cmsval->type,
1807                                         cmsval ?
1808                                         cmsval->item.calendar_user_value:NULL);
1809                         }
1810
1811                         if (stat != CSA_SUCCESS)
1812                                 return (stat);
1813
1814                         oattr = attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].name.name;
1815                         attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].name.name = NULL;
1816                 }
1817
1818                 if (attrs[CSA_CAL_ATTR_CALENDAR_NAME_I].name.name) {
1819                         if (attrs[CSA_CAL_ATTR_CALENDAR_NAME_I].value == NULL ||
1820                             attrs[CSA_CAL_ATTR_CALENDAR_NAME_I].value->\
1821                             item.string_value == NULL) {
1822                                 if (oattr)
1823                                         attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].\
1824                                                 name.name = oattr;
1825                                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
1826                         }
1827
1828                         if ((stat = _CheckCalendarName(owner, cname,
1829                             attrs[CSA_CAL_ATTR_CALENDAR_NAME_I].value))
1830                             != CSA_SUCCESS) {
1831                                 if (oattr)
1832                                         attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].\
1833                                                 name.name = oattr;
1834                                 return (stat);
1835                         }
1836
1837                         nattr = attrs[CSA_CAL_ATTR_CALENDAR_NAME_I].name.name;
1838                         attrs[CSA_CAL_ATTR_CALENDAR_NAME_I].name.name = NULL;
1839                 }
1840
1841                 if (attrs[CSA_CAL_ATTR_CHARACTER_SET_I].name.name) {
1842                         cattr = attrs[CSA_CAL_ATTR_CHARACTER_SET_I].name.name;
1843                         attrs[CSA_CAL_ATTR_CHARACTER_SET_I].name.name = NULL;
1844                 }
1845
1846                 if (attrs[CSA_CAL_ATTR_TIME_ZONE_I].name.name) {
1847                         tattr = attrs[CSA_CAL_ATTR_TIME_ZONE_I].name.name;
1848                         attrs[CSA_CAL_ATTR_TIME_ZONE_I].name.name = NULL;
1849                 }
1850         }
1851
1852         stat = check_predefined_attrs(fvers, num_attrs+1, attrs,
1853                 checkreadonly, NULL, _DtCM_DEFINED_CAL_ATTR_SIZE,
1854                 _CSA_cal_attr_info);
1855
1856         if (oattr)
1857                 attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].name.name = oattr;
1858
1859         if (nattr)
1860                 attrs[CSA_CAL_ATTR_CALENDAR_NAME_I].name.name = nattr;
1861
1862         if (cattr)
1863                 attrs[CSA_CAL_ATTR_CHARACTER_SET_I].name.name = oattr;
1864
1865         if (tattr)
1866                 attrs[CSA_CAL_ATTR_TIME_ZONE_I].name.name = nattr;
1867
1868         return (stat);
1869 }
1870
1871 static CSA_return_code
1872 _DtCm_check_hashed_entry_attributes(
1873         int             fvers,
1874         uint            num_attrs,
1875         cms_attribute   *attrs,
1876         CSA_flags       utype)
1877 {
1878         CSA_return_code stat;
1879
1880         if ((stat = check_predefined_attrs(fvers, num_attrs+1, attrs,
1881             (utype == 0 ? B_FALSE : B_TRUE), NULL,
1882             _DtCM_DEFINED_ENTRY_ATTR_SIZE, _CSA_entry_attr_info))
1883             != CSA_SUCCESS) {
1884
1885                 return (stat);
1886         }
1887
1888         if (utype == CSA_CB_ENTRY_ADDED) {
1889
1890                 /* make sure the minimum set of attribute is specified */
1891                 if (attrs[CSA_ENTRY_ATTR_START_DATE_I].value == NULL ||
1892                     attrs[CSA_ENTRY_ATTR_TYPE_I].value == NULL)
1893                         return (CSA_E_INVALID_PARAMETER);
1894
1895         } else if (utype == CSA_CB_ENTRY_UPDATED) {
1896
1897                 /* type can only be set at insertion time */
1898                 if (attrs[CSA_ENTRY_ATTR_TYPE_I].name.name)
1899                         return (CSA_E_READONLY);
1900         }
1901
1902         return (CSA_SUCCESS);
1903 }
1904
1905 static CSA_return_code
1906 _CheckNameAtHost(char *owner, char *value)
1907 {
1908         char            *ptr, *optr;
1909         int             res;
1910
1911         /* check name part first */
1912         if (owner == NULL) {
1913                 /* get user name of user running the application */
1914                 if ((owner = _DtCmGetUserName()) == NULL)
1915                         return (CSA_E_FAILURE);
1916         }
1917
1918         if (optr = strchr(owner, '@')) *optr = '\0';
1919         if (ptr = strchr(value, '@')) *ptr = '\0';
1920         res = strcmp(value, owner);
1921         if (optr) *optr = '@';
1922         if (ptr) *ptr = '@';
1923
1924         if (res != 0)
1925                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
1926
1927         /* check host too if it's specified */
1928         if (ptr == NULL)
1929                 return (CSA_SUCCESS);
1930
1931         ptr++;
1932         if (strcmp(ptr, (optr ? ++optr : _DtCmGetLocalHost())) == 0)
1933                 return (CSA_SUCCESS);
1934         else
1935                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
1936 }
1937
1938 /*
1939  * check the data type and validity of calendar owner attribute
1940  */
1941 static CSA_return_code
1942 _CheckCalendarOwner(char *owner, int type, char *user)
1943 {
1944         if (type != CSA_VALUE_CALENDAR_USER || user == NULL)
1945                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
1946
1947         /* make sure user is the same as the one running the application */
1948         return (_CheckNameAtHost(owner, user));
1949 }
1950
1951 /*
1952  * check the data type and validity of calendar name attribute
1953  */
1954 static CSA_return_code
1955 _CheckCalendarName(char *owner, char *cname, cms_attribute_value *val)
1956 {
1957         CSA_return_code stat;
1958         char            *ptr, *optr;
1959         char            user[BUFSIZ];
1960         boolean_t       isuser;
1961
1962         if (val->type != CSA_VALUE_STRING)
1963                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
1964
1965         /* check that the attribute value is the same as the given
1966          * calendar name
1967          */
1968         if ((stat = _CheckNameAtHost(cname, val->item.string_value))
1969             != CSA_SUCCESS)
1970                 return (stat);
1971
1972         /* now make sure if cal name is a user name, it's
1973          * the same as that of the calling user
1974          */
1975         if (ptr = strchr(val->item.string_value, '@')) *ptr = '\0';
1976         isuser = _DtCmIsUserName(val->item.string_value);
1977         if (ptr) *ptr = '@';
1978
1979         /* make sure it's the same as the user running the application */
1980         if (isuser == B_TRUE) {
1981                 sprintf(user, "%s%s", val->item.string_value, (ptr ? ptr : ""));
1982                 return (_CheckNameAtHost(owner, user));
1983         }
1984
1985         /* check the host part */
1986         if (ptr == NULL)
1987                 return (CSA_SUCCESS);
1988         else
1989                 ptr++;
1990
1991         if (owner && (optr = strchr(owner, '@')))
1992                 optr++;
1993         else
1994                 optr = _DtCmGetLocalHost();
1995
1996         if (strcmp(ptr, optr) == 0)
1997                 return (CSA_SUCCESS);
1998         else
1999                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
2000 }
2001