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