Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dtcm / server / cmsconvert.c
1 /* $XConsortium: cmsconvert.c /main/5 1996/10/03 10:38:06 drk $ */
2 /*
3  *  (c) Copyright 1993, 1994 Hewlett-Packard Company
4  *  (c) Copyright 1993, 1994 International Business Machines Corp.
5  *  (c) Copyright 1993, 1994 Novell, Inc.
6  *  (c) Copyright 1993, 1994 Sun Microsystems, Inc.
7  */
8
9 #include <EUSCompat.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include "cmsconvert.h"
14 #include "convert5-4.h"
15 #include "convert4-5.h"
16 #include "attr.h"
17 #include "appt4.h"
18 #include "iso8601.h"
19 #include "lutil.h"
20 #include "cmsdata.h"
21
22 /*
23  * Routines to convert data types used in version 5 to version 4.
24  */
25
26 /*
27  * forward declaration of functions used in the file
28  */
29 static Abb_Appt_4 * _MakeAbbrAppt();
30
31 static CSA_return_code _AttrsToAbbrAppt(uint size, cms_attribute *attrs,
32                                         Abb_Appt_4 *appt);
33
34 static uint _ConvertV5Access(uint v5rights, boolean_t strictmode);
35
36 static uint _ConvertV4Access(uint v4rights);
37
38 static char * _ConvertReminderName(char *rname);
39
40 static CSA_return_code _Appt4ToCmsentryAttrs(char *calname, Appt_4 *a4,
41                                 uint *num_attrs, cms_attribute **attrs_r);
42 /*****************************************************************************
43  * extern functions
44  *****************************************************************************/
45
46 extern CSA_return_code
47 _DtCmsCmsentriesToAppt4ForClient(cms_entry *entries, Appt_4 **appt)
48 {
49         CSA_return_code stat;
50         Appt_4  *newappt, *prev, *head;
51
52         if (appt == NULL)
53                 return (CSA_E_INVALID_PARAMETER);
54
55         head = prev = NULL;
56         while (entries != NULL) {
57                 if ((newappt = _DtCm_make_appt4(B_TRUE)) == NULL)
58                         break;
59
60                 if ((stat = _DtCmsAttrsToAppt4(entries->num_attrs + 1,
61                     entries->attrs, newappt, B_FALSE)) != CSA_SUCCESS) {
62                         _DtCm_free_appt4(newappt);
63                         break;
64                 } else
65                         newappt->appt_id.key = entries->key.id;
66
67                 if (head == NULL)
68                         head = newappt;
69                 else
70                         prev->next = newappt;
71
72                 prev = newappt;
73                 entries = entries->next;
74         }
75
76         if (stat != CSA_SUCCESS) {
77                 _DtCm_free_appt4(head);
78                 head = NULL;
79         }
80
81         *appt = head;
82         return (stat);
83 }
84
85 extern CSA_return_code
86 _DtCmsCmsentriesToAbbrAppt4ForClient(cms_entry *entries, Abb_Appt_4 **abbr)
87 {
88         CSA_return_code stat;
89         Abb_Appt_4      *newabbr, *prev, *head;
90
91         if (abbr == NULL)
92                 return (CSA_E_INVALID_PARAMETER);
93
94         head = prev = NULL;
95         while (entries != NULL) {
96                 if ((newabbr = _MakeAbbrAppt()) == NULL)
97                         break;
98
99                 if ((stat = _AttrsToAbbrAppt(entries->num_attrs, entries->attrs,
100                     newabbr)) != CSA_SUCCESS) {
101                         _DtCm_free_abbrev_appt4(newabbr);
102                         break;
103                 } else
104                         newabbr->appt_id.key = entries->key.id;
105
106                 if (head == NULL)
107                         head = newabbr;
108                 else
109                         prev->next = newabbr;
110
111                 prev = newabbr;
112                 entries = entries->next;
113         }
114
115         if (stat != CSA_SUCCESS) {
116                 _DtCm_free_abbrev_appt4(head);
117                 head = NULL;
118         }
119
120         *abbr = head;
121         return (stat);
122 }
123
124 extern Access_Entry_4 *
125 _DtCmsConvertV5AccessList(cms_access_entry *cmslist, boolean_t strictmode)
126 {
127         Access_Entry_4  *l, *head, *prev;
128         boolean_t       cleanup = B_FALSE;
129
130         prev = head = NULL;
131         while (cmslist != NULL) {
132                 if ((l = (Access_Entry_4 *)calloc(1, sizeof(Access_Entry_4)))
133                     == NULL) {
134                         cleanup = B_TRUE;
135                         break;
136                 }
137
138                 if ((l->who = strdup(cmslist->user)) == NULL) {
139                         free(l);
140                         cleanup = B_TRUE;
141                         break;
142                 }
143                 l->access_type = _ConvertV5Access(cmslist->rights, strictmode);
144
145                 if (head == NULL)
146                         head = l;
147                 else
148                         prev->next = l;
149                 prev = l;
150
151                 cmslist = cmslist->next;
152         }
153
154         if (cleanup == B_TRUE) {
155                 _DtCm_free_access_list4(head);
156                 head = NULL;
157         }
158         return (head);
159 }
160
161 extern cms_access_entry *
162 _DtCmsConvertV4AccessList(Access_Entry_4 *alist)
163 {
164         cms_access_entry        *l, *head, *prev;
165         boolean_t               cleanup = B_FALSE;
166
167         prev = head = NULL;
168         while (alist != NULL) {
169                 if ((l = (cms_access_entry *)calloc(1,
170                     sizeof(cms_access_entry))) == NULL) {
171                         cleanup = B_TRUE;
172                         break;
173                 }
174
175                 if ((l->user = strdup(alist->who)) == NULL) {
176                         free(l);
177                         cleanup = B_TRUE;
178                         break;
179                 }
180                 l->rights = _ConvertV4Access(alist->access_type);
181
182                 if (head == NULL)
183                         head = l;
184                 else
185                         prev->next = l;
186                 prev = l;
187
188                 alist = alist->next;
189         }
190
191         if (cleanup == B_TRUE) {
192                 _DtCm_free_cms_access_entry(head);
193                 head = NULL;
194         }
195         return (head);
196 }
197
198 extern CSA_return_code
199 _DtCmsReminderRefToReminder(
200         cms_reminder_ref        *rems,
201         Reminder_4              **r4)
202 {
203         CSA_return_code stat = CSA_SUCCESS;
204         Reminder_4      *head, *prev, *rptr;
205         char            buf[30];
206
207         prev = head = NULL;
208         while (rems != NULL) {
209
210                 if ((rptr = (Reminder_4 *)calloc(1, sizeof(Reminder_4)))
211                     == NULL) {
212                         stat = CSA_E_INSUFFICIENT_MEMORY;
213                         break;
214                 }
215
216                 rptr->appt_id.tick = rems->key.time;
217                 rptr->appt_id.key = rems->key.id;
218                 rptr->tick = rems->runtime;
219
220                 if ((rptr->attr.attr=_ConvertReminderName(rems->reminder_name))
221                     == NULL) {
222                         free(rptr);
223                         stat = CSA_E_INSUFFICIENT_MEMORY;
224                         break;
225                 }
226
227                 if ((rptr->attr.value = calloc(1,1)) == NULL) {
228                         free(rptr->attr.attr);
229                         free(rptr);
230                         stat = CSA_E_INSUFFICIENT_MEMORY;
231                         break;
232                 }
233
234                 if ((rptr->attr.clientdata = calloc(1,1)) == NULL) {
235                         free(rptr->attr.value);
236                         free(rptr->attr.attr);
237                         free(rptr);
238                         stat = CSA_E_INSUFFICIENT_MEMORY;
239                         break;
240                 }
241
242                 if (head == NULL)
243                         head = rptr;
244                 else
245                         prev->next = rptr;
246                 prev = rptr;
247
248                 rems = rems->next;
249         }
250
251         if (stat != CSA_SUCCESS) {
252                 _DtCm_free_reminder4(head);
253                 head = NULL;
254         }
255
256         *r4 = head;
257
258         return(stat);
259 }
260
261 extern CSA_return_code
262 _DtCmsV4ReminderToReminderRef(
263         char                    *calname,
264         Reminder_4              *r4,
265         _DtCmsEntryId           *ids,
266         cms_reminder_ref        **rems)
267 {
268         CSA_return_code         stat = CSA_SUCCESS;
269         cms_reminder_ref        *head, *prev, *rptr;
270         char                    buf[BUFSIZ];
271
272         prev = head = NULL;
273         while (r4 != NULL) {
274
275                 if ((rptr = (cms_reminder_ref *)calloc(1,
276                     sizeof(cms_reminder_ref))) == NULL) {
277                         stat = CSA_E_INSUFFICIENT_MEMORY;
278                         break;
279                 }
280
281                 rptr->key.time = r4->appt_id.tick;
282                 rptr->key.id = r4->appt_id.key;
283                 rptr->runtime = r4->tick;
284
285                 if ((rptr->reminder_name = strdup(
286                     _DtCm_old_reminder_name_to_name(r4->attr.attr)))
287                     == NULL) {
288                         free(rptr);
289                         stat = CSA_E_INSUFFICIENT_MEMORY;
290                         break;
291                 }
292
293                 sprintf(buf, "%ld:%s@%s", ids->id, calname,
294                         _DtCmGetHostAtDomain());
295
296                 if ((rptr->entryid = strdup(buf)) == NULL) {
297                         free(rptr->reminder_name);
298                         free(rptr);
299                         stat = CSA_E_INSUFFICIENT_MEMORY;
300                         break;
301                 }
302
303                 if (head == NULL)
304                         head = rptr;
305                 else
306                         prev->next = rptr;
307                 prev = rptr;
308
309                 r4 = r4->next;
310                 ids = ids->next;
311         }
312
313         if (stat != CSA_SUCCESS) {
314                 _DtCmsFreeReminderRef(head);
315                 head = NULL;
316         }
317
318         *rems = head;
319
320         return(stat);
321 }
322
323 extern CSA_return_code
324 _DtCmsCmsAccessToV4Access(cms_access_entry *alist, Access_Entry_4 **a4)
325 {
326         CSA_return_code stat = CSA_SUCCESS;
327         Access_Entry_4  *to, *prev, *head;
328
329         head = prev = NULL;
330         while (alist != NULL) {
331                 if ((to = (Access_Entry_4 *)calloc(1, sizeof(Access_Entry_4)))
332                     == NULL) {
333                         stat = CSA_E_INSUFFICIENT_MEMORY;
334                         break;
335                 }
336
337                 if ((to->access_type = _DtCmAccessRightToV4AccessType(
338                     alist->rights)) < 0) {
339                         stat = CSA_E_INVALID_FLAG;
340                         break;
341                 }
342
343                 if (alist->user == NULL) {
344                         stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
345                         break;
346                 }
347
348                 if ((to->who = strdup(alist->user)) == NULL) {
349                         free(to);
350                         stat = CSA_E_INSUFFICIENT_MEMORY;
351                         break;
352                 }
353
354                 if (head == NULL)
355                         head = to;
356                 else
357                         prev->next = to;
358
359                 prev = to;
360
361                 alist = alist->next;
362         }
363
364         if (stat != CSA_SUCCESS) {
365                 _DtCm_free_access_list4(head);
366                 head = NULL;
367         }
368
369         *a4 = head;
370         return (stat);
371 }
372
373 extern CSA_return_code
374 _DtCmsAppt4ToCmsentriesForClient(
375         char            *calname,
376         Appt_4          *appt,
377         cms_entry       **e_r)
378 {
379         CSA_return_code stat = CSA_SUCCESS;
380         cms_entry       *entry, *head, *prev;
381
382         if (e_r == NULL)
383                 return(CSA_E_INVALID_PARAMETER);
384
385         prev = head = NULL;
386         while (appt != NULL) {
387
388                 if ((entry = (cms_entry *)calloc(1, sizeof(cms_entry))) == NULL)
389                         break;
390
391                 if ((stat = _Appt4ToCmsentryAttrs(calname, appt,
392                     &entry->num_attrs, &entry->attrs)) == CSA_SUCCESS) {
393                         entry->key.time = appt->appt_id.tick;
394                         entry->key.id = appt->appt_id.key;
395                 } else {
396                         free(entry);
397                         break;
398                 }
399
400                 if (head == NULL)
401                         head = entry;
402                 else
403                         prev->next = entry;
404
405                 prev = entry;
406
407                 appt = appt->next;
408         }
409
410         if (stat != CSA_SUCCESS) {
411                 _DtCm_free_cms_entries(head);
412                 head = NULL;
413         }
414
415         *e_r = head;
416         return(stat);
417 }
418
419 extern CSA_return_code
420 _DtCmsAppt4ToCmsentry(
421         char            *calname,
422         Appt_4          *a4,
423         cms_entry       **entry_r,
424         boolean_t       rerule)
425 {
426         CSA_return_code stat;
427         cms_entry       *entry;
428
429         if (a4 == NULL)
430                 return(CSA_E_INVALID_PARAMETER);
431
432         if ((entry = _DtCm_make_cms_entry(_DtCm_entry_name_tbl)) == NULL)
433                 return (CSA_E_INSUFFICIENT_MEMORY);
434
435         entry->key.time = a4->appt_id.tick;
436         entry->key.id = a4->appt_id.key;
437
438         if ((stat = _DtCm_appt4_to_attrs(calname, a4, entry->num_attrs,
439             entry->attrs, rerule)) != CSA_SUCCESS) {
440                 _DtCm_free_cms_entry(entry);
441                 return (stat);
442         }
443
444         *entry_r = entry;
445         return (CSA_SUCCESS);
446 }
447
448 /*
449  * This routine is used either to convert attrs from clients for insert
450  * or update; or to convert appts for sending to clients
451  * Note: the reference id is not converted
452  */
453 extern CSA_return_code
454 _DtCmsAttrsToAppt4(
455         uint            size,
456         cms_attribute   *attrs,
457         Appt_4          *appt,
458         boolean_t       check)
459 {
460         CSA_return_code stat = CSA_SUCCESS;
461         char            *string;
462         time_t          endtick;
463         int             i, enddateindex = -1, interval = -1, wknum;
464         int             typeindex = -1, stypeindex = -1;
465         boolean_t       set_wknum = B_FALSE;
466
467         /*
468          * this routine is called to convert valid v2 to v4 attributes
469          * so no checking of CSA_E_INVALID_ATTRIBUTE and
470          * CSA_E_UNSUPPORTED_ATTRIBUTE is necessary
471          */
472
473         for (i = 0; i < size && stat == CSA_SUCCESS; i++) {
474                 switch (attrs[i].name.num) {
475                 case CSA_ENTRY_ATTR_START_DATE_I:
476                         if (check == B_TRUE && attrs[i].value == NULL)
477                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
478                         else if (_csa_iso8601_to_tick(attrs[i].value->\
479                             item.date_time_value, &appt->appt_id.tick))
480                                 stat = CSA_E_INVALID_DATE_TIME;
481                         break;
482
483                 case CSA_ENTRY_ATTR_END_DATE_I: 
484                         enddateindex = i;
485                         break;
486
487                 case CSA_ENTRY_ATTR_TYPE_I:
488                         typeindex = i;
489                         break;
490
491                 case CSA_ENTRY_ATTR_SUBTYPE_I:
492                         stypeindex = i;
493                         break;
494
495                 case CSA_ENTRY_ATTR_SUMMARY_I:
496
497                         if (attrs[i].value->item.string_value) {
498                                 if ((string = strdup(attrs[i].value->item.\
499                                     string_value)) == NULL)
500                                         stat = CSA_E_INSUFFICIENT_MEMORY;
501                                 else {
502                                         if (appt->what)
503                                                 free(appt->what);
504                                         appt->what = string;
505                                 }
506                         }
507                         break;
508
509                 case CSA_ENTRY_ATTR_ORGANIZER_I:
510                         free(appt->author);
511                         if ((appt->author = strdup(attrs[i].value->\
512                             item.calendar_user_value)) == NULL)
513                                 stat = CSA_E_INSUFFICIENT_MEMORY;
514                         break;
515
516                 case CSA_ENTRY_ATTR_AUDIO_REMINDER_I:
517
518                         if (attrs[i].value == NULL)
519                                 stat = _DtCm_remove_reminder(
520                                         _DtCM_OLD_ATTR_BEEP_REMINDER, appt);
521                         else if (attrs[i].value->item.reminder_value == NULL)
522                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
523                         else
524                                 stat = _DtCm_add_reminder(
525                                         _DtCM_OLD_ATTR_BEEP_REMINDER,
526                                         attrs[i].value->item.reminder_value,
527                                         appt);
528                         break;
529
530                 case CSA_ENTRY_ATTR_FLASHING_REMINDER_I:
531
532                         if (attrs[i].value == NULL)
533                                 stat = _DtCm_remove_reminder(
534                                         _DtCM_OLD_ATTR_FLASH_REMINDER, appt);
535                         else if (attrs[i].value->item.reminder_value == NULL)
536                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
537                         else
538                                 stat = _DtCm_add_reminder(
539                                         _DtCM_OLD_ATTR_FLASH_REMINDER,
540                                         attrs[i].value->item.reminder_value,
541                                         appt);
542                         break;
543
544                 case CSA_ENTRY_ATTR_MAIL_REMINDER_I:
545
546                         if (attrs[i].value == NULL)
547                                 stat = _DtCm_remove_reminder(
548                                         _DtCM_OLD_ATTR_MAIL_REMINDER, appt);
549                         else if (attrs[i].value->item.reminder_value == NULL)
550                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
551                         else
552                                 stat = _DtCm_add_reminder(
553                                         _DtCM_OLD_ATTR_MAIL_REMINDER,
554                                         attrs[i].value->item.reminder_value,
555                                         appt);
556                         break;
557
558                 case CSA_ENTRY_ATTR_POPUP_REMINDER_I:
559
560                         if (attrs[i].value == NULL)
561                                 stat = _DtCm_remove_reminder(
562                                         _DtCM_OLD_ATTR_POPUP_REMINDER, appt);
563                         else if (attrs[i].value->item.reminder_value == NULL)
564                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
565                         else
566                                 stat = _DtCm_add_reminder(
567                                         _DtCM_OLD_ATTR_POPUP_REMINDER,
568                                         attrs[i].value->item.reminder_value,
569                                         appt);
570                         break;
571
572                 case CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I:
573
574                         if (_DtCm_rtype_to_interval4(
575                             attrs[i].value->item.sint32_value,
576                             &appt->period.period)) {
577                                 if (check == B_TRUE)
578                                         stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
579                                 else
580                                         appt->period.period = otherPeriod_4;
581                         }
582                         break;
583
584                 case CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I:
585
586                         if (attrs[i].value) {
587                                 appt->ntimes =
588                                         attrs[i].value->item.uint32_value;
589                                 if (appt->ntimes == CSA_X_DT_DT_REPEAT_FOREVER)
590                                         appt->ntimes = _DtCM_OLD_REPEAT_FOREVER;
591                         }
592                         break;
593
594                 case CSA_X_DT_ENTRY_ATTR_SHOWTIME_I:
595
596                         if (attrs[i].value)
597                                 appt->tag->showtime =
598                                         attrs[i].value->item.sint32_value;
599                         break;
600
601                 case CSA_ENTRY_ATTR_STATUS_I:
602
603                         if (_DtCm_status_to_apptstatus4(
604                             attrs[i].value->item.uint32_value,
605                             &appt->appt_status)) {
606                                 if (check == B_TRUE)
607                                         stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
608                                 else
609                                         appt->appt_status = active_4;
610                         }
611                         break;
612
613                 case CSA_ENTRY_ATTR_CLASSIFICATION_I:
614
615                         if (_DtCm_classification_to_privacy4(
616                             attrs[i].value->item.uint32_value, &appt->privacy))
617                         {
618                                 if (check == B_TRUE)
619                                         stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
620                                 else
621                                         appt->privacy = public_4;
622                         }
623                         break;
624
625                 case CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE_I:
626
627                         if (attrs[i].value &&
628                             attrs[i].value->item.date_time_value &&
629                             *(attrs[i].value->item.date_time_value))
630                         {
631                                 if (_csa_iso8601_to_tick(
632                                     attrs[i].value->item.date_time_value,
633                                     &appt->period.enddate))
634                                         stat = CSA_E_INVALID_DATE_TIME;
635                         }
636                         break;
637
638                 case CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I:
639                         if (attrs[i].value)
640                                 interval = attrs[i].value->item.uint32_value;
641                         break;
642
643                 case CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I:
644                         if (attrs[i].value) {
645                                 set_wknum = B_TRUE;
646                                 wknum = attrs[i].value->item.sint32_value;
647                         }
648                         break;
649                 }
650         }
651
652         if (stat == CSA_SUCCESS && enddateindex >= 0) {
653                 if (attrs[enddateindex].value == NULL ||
654                     attrs[enddateindex].value->item.date_time_value == NULL) {
655                         appt->duration = 0;
656                 } else if (_csa_iso8601_to_tick(attrs[enddateindex].value->\
657                     item.date_time_value, &endtick)) {
658                         stat = CSA_E_INVALID_DATE_TIME;
659                 } else {
660                         appt->duration = endtick - appt->appt_id.tick;
661                 }
662         }
663
664         if (stat == CSA_SUCCESS && (typeindex >= 0 || typeindex >= 0)) {
665                 if (typeindex >= 0) {
666                         if (stat = _DtCm_attrs_to_eventtype4(
667                             attrs[typeindex].value,
668                             (stypeindex >= 0 ? attrs[stypeindex].value : NULL),
669                             appt->tag)) {
670                                 if (check == B_FALSE) {
671                                         /* this is the case where we are
672                                          * converting appt for clients
673                                          */
674                                         appt->tag->tag = otherTag_4;
675                                         stat = CSA_SUCCESS;
676                                 }
677                         }
678                 } else if (stypeindex >= 0) {
679                         if (attrs[stypeindex].value &&
680                             attrs[stypeindex].value->item.string_value)
681                         {
682                                 if (strcmp(attrs[stypeindex].value->item.\
683                                     string_value, CSA_SUBTYPE_APPOINTMENT) == 0)
684                                         appt->tag->tag = appointment_4;
685                                 else if (strcmp(attrs[stypeindex].value->item.\
686                                     string_value, CSA_SUBTYPE_HOLIDAY) == 0)
687                                         appt->tag->tag = holiday_4;
688                                 else
689                                         stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
690                         } else
691                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
692                 }
693         }
694
695         if (stat == CSA_SUCCESS) {
696                 switch (appt->period.period) {
697                 case nthWeekday_4:
698                         if (set_wknum == B_TRUE)
699                                 appt->period.nth = wknum;
700                         break;
701                 case everyNthDay_4:
702                 case everyNthWeek_4:
703                 case everyNthMonth_4:
704                         if (interval >= 0)
705                                 appt->period.nth = interval;
706                         break;
707                 default:
708                         appt->period.nth = 0;
709                 }
710
711                 if (appt->period.period == single_4)
712                         appt->ntimes = 0;
713         }
714         return (stat);
715 }
716
717
718 /******************************************************************************
719  * static functions used within the file
720  ******************************************************************************/
721
722 /*
723  * attributes are hashed
724  * we are converting v4 events to v3 appts, so attributes are
725  * assumed to be good and all mandatory ones are present
726  */
727 static CSA_return_code
728 _AttrsToAbbrAppt(uint size, cms_attribute *attrs, Abb_Appt_4 *appt)
729 {
730         CSA_return_code stat = CSA_SUCCESS;
731         char            *ptr;
732         time_t          endtick;
733         int             i, typeindex, stypeindex = -1, enddateindex = -1;
734         char            buf[BUFSIZ];
735
736         for (i = 0; i < size && stat == CSA_SUCCESS; i++) {
737                 switch (attrs[i].name.num) {
738                 case CSA_ENTRY_ATTR_START_DATE_I:
739                         _csa_iso8601_to_tick(attrs[i].value->\
740                             item.date_time_value, &appt->appt_id.tick);
741                         break;
742
743                 case CSA_ENTRY_ATTR_END_DATE_I:
744                         enddateindex = i;
745                         break;
746
747                 case CSA_ENTRY_ATTR_TYPE_I:
748                         typeindex = i;
749                         break;
750
751                 case CSA_ENTRY_ATTR_SUBTYPE_I:
752                         stypeindex = i;
753                         break;
754
755                 case CSA_X_DT_ENTRY_ATTR_SHOWTIME_I:
756                         appt->tag->showtime = attrs[i].value->item.sint32_value;
757                         break;
758
759                 case CSA_ENTRY_ATTR_SUMMARY_I:
760                         if (attrs[i].value && attrs[i].value->item.string_value)
761                         {
762                                 free(appt->what);
763                                 if ((appt->what = strdup(attrs[i].value->\
764                                     item.string_value)) == NULL)
765                                         stat = CSA_E_INSUFFICIENT_MEMORY;
766                         }
767                         break;
768
769                 case CSA_ENTRY_ATTR_STATUS_I:
770                         if (_DtCm_status_to_apptstatus4(attrs[i].value->item.\
771                             uint32_value, &appt->appt_status))
772                                 appt->appt_status = active_4;
773                         break;
774
775                 case CSA_ENTRY_ATTR_CLASSIFICATION_I:
776                         if (_DtCm_classification_to_privacy4(attrs[i].value->\
777                             item.uint32_value, &appt->privacy))
778                                 appt->privacy = public_4;
779                         break;
780
781                 case CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I:
782                         if (_DtCm_rtype_to_interval4(attrs[i].value->\
783                             item.sint32_value, &appt->period.period))
784                                 appt->period.period = otherPeriod_4;
785                         break;
786
787                 case CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I:
788                         appt->period.nth = attrs[i].value->item.sint32_value;
789                         break;
790
791                 case CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I:
792                         appt->period.nth = attrs[i].value->item.uint32_value;
793                         break;
794
795                 case CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE_I:
796                         _csa_iso8601_to_tick(attrs[i].value->item.\
797                                 date_time_value, &appt->period.enddate);
798                         break;
799                 }
800         }
801
802         if (stat != CSA_SUCCESS)
803                 return (stat);
804
805         if (enddateindex >= 0) {
806                 _csa_iso8601_to_tick(attrs[enddateindex].value->item.\
807                         date_time_value, &endtick);
808                 appt->duration = endtick - appt->appt_id.tick;
809         } else
810                 appt->duration = 0;
811
812         if (_DtCm_attrs_to_eventtype4(attrs[typeindex].value,
813             (stypeindex >= 0 ? attrs[stypeindex].value : NULL), appt->tag))
814                 appt->tag->tag = otherTag_4;
815
816         return (CSA_SUCCESS);
817 }
818
819 static Abb_Appt_4 *
820 _MakeAbbrAppt()
821 {
822         Abb_Appt_4 *a;
823
824         if ((a = (Abb_Appt_4 *)calloc(1, sizeof(Abb_Appt_4))) == NULL)
825                 return NULL;
826
827         if ((a->tag = (Tag_4 *)calloc(1, sizeof(Tag_4))) == NULL) {
828                 free(a);
829                 return NULL;
830         }
831
832         a->tag->tag = appointment_4;
833         a->tag->showtime =  B_TRUE;
834
835         return(a);
836 }
837
838 static uint
839 _ConvertV5Access(uint v5rights, boolean_t strictmode)
840 {
841         uint    access = 0;
842
843         if (v5rights & CSA_OWNER_RIGHTS)
844                 return (access_read_4 | access_write_4 | access_delete_4);
845
846         if (v5rights & (CSA_VIEW_PUBLIC_ENTRIES|CSA_VIEW_CONFIDENTIAL_ENTRIES|
847             CSA_VIEW_PRIVATE_ENTRIES))
848                 access = access_read_4;
849
850         if ((strictmode == B_TRUE &&
851             (v5rights & CSA_INSERT_PUBLIC_ENTRIES) &&
852             (v5rights & CSA_INSERT_PRIVATE_ENTRIES) &&
853             (v5rights & CSA_INSERT_CONFIDENTIAL_ENTRIES)) ||
854             (strictmode == B_FALSE &&
855             (v5rights & (CSA_INSERT_PUBLIC_ENTRIES |
856             CSA_INSERT_PRIVATE_ENTRIES | CSA_INSERT_CONFIDENTIAL_ENTRIES))))
857                 access |= access_write_4;
858
859         if ((strictmode == B_TRUE &&
860             (v5rights & CSA_CHANGE_PUBLIC_ENTRIES) &&
861             (v5rights & CSA_CHANGE_PRIVATE_ENTRIES) &&
862             (v5rights & CSA_CHANGE_CONFIDENTIAL_ENTRIES)) ||
863             (strictmode == B_FALSE &&
864             (v5rights & (CSA_CHANGE_PUBLIC_ENTRIES |
865             CSA_CHANGE_PRIVATE_ENTRIES | CSA_CHANGE_CONFIDENTIAL_ENTRIES))))
866                 access |= access_delete_4;
867
868         return (access);
869 }
870
871 static uint
872 _ConvertV4Access(uint v4rights)
873 {
874         uint    access = 0;
875
876         if (v4rights & access_read_4)
877                 access = CSA_VIEW_PUBLIC_ENTRIES;
878
879         if (v4rights & access_write_4)
880                 access |= CSA_INSERT_PUBLIC_ENTRIES;
881
882         if (v4rights & (access_write_4 | access_delete_4))
883                 access |= CSA_CHANGE_PUBLIC_ENTRIES;
884
885         return (access);
886 }
887
888 static char *
889 _ConvertReminderName(char *rname)
890 {
891         if (!strcmp(rname, CSA_ENTRY_ATTR_AUDIO_REMINDER))
892                 return (strdup(_DtCM_OLD_ATTR_BEEP_REMINDER));
893         else if (!strcmp(rname, CSA_ENTRY_ATTR_FLASHING_REMINDER))
894                 return (strdup(_DtCM_OLD_ATTR_FLASH_REMINDER));
895         else if (!strcmp(rname, CSA_ENTRY_ATTR_MAIL_REMINDER))
896                 return (strdup(_DtCM_OLD_ATTR_MAIL_REMINDER));
897         else if (!strcmp(rname, CSA_ENTRY_ATTR_POPUP_REMINDER))
898                 return (strdup(_DtCM_OLD_ATTR_POPUP_REMINDER));
899         else
900                 return (strdup(rname));
901 }
902
903 static CSA_return_code
904 _Appt4ToCmsentryAttrs(
905         char            *calname,
906         Appt_4          *a4,
907         uint            *num_attrs,
908         cms_attribute   **attrs_r)
909 {
910         CSA_return_code         stat = CSA_SUCCESS;
911         cms_attribute           *attrs;
912         cms_attribute           tmpattr;
913         cms_attribute_value     tmpval;
914         Attribute_4             *reminders = a4->attr;
915         char                    buf[BUFSIZ];
916         CSA_opaque_data         opq;
917         int                     index, ntimes, count = 0;
918         char                    *ptr1, *ptr2;
919
920         if (num_attrs == NULL || attrs_r == NULL)
921                 return (CSA_E_INVALID_PARAMETER);
922
923         if ((attrs = (cms_attribute *)calloc(1,
924             sizeof(cms_attribute) * (_DtCM_OLD_ENTRY_ATTR_SIZE+ 1))) == NULL)
925                 return (CSA_E_INSUFFICIENT_MEMORY);
926
927         if (a4->period.period != single_4 &&
928             a4->ntimes == _DtCM_OLD_REPEAT_FOREVER)
929                 ntimes = CSA_X_DT_DT_REPEAT_FOREVER;
930         else
931                 ntimes = a4->ntimes;
932
933         tmpattr.value = &tmpval;
934
935         /* reference id */
936         tmpattr.name.name = CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER;
937         tmpattr.name.num = CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I;
938         tmpval.type = CSA_VALUE_OPAQUE_DATA;
939         tmpval.item.opaque_data_value = &opq;
940         ptr1 = strchr(calname, '@');
941         ptr2 = (ptr1 ? strchr(ptr1, '.') : NULL);
942         if (ptr1) {
943                 sprintf(buf, "%ld:%s%s%s", a4->appt_id.key, calname,
944                         (ptr2 == NULL ? "." : ""),
945                         (ptr2 == NULL ? _DtCmGetLocalDomain(ptr1+1) : ""));
946         } else {
947                 sprintf(buf, "%ld:%s@%s", a4->appt_id.key, calname,
948                         _DtCmGetHostAtDomain());
949         }
950         opq.size = strlen(buf);
951         opq.data = (unsigned char *)buf;
952
953         if ((stat = _DtCm_copy_cms_attribute(&attrs[count++], &tmpattr, B_TRUE))
954             != CSA_SUCCESS) {
955                 free(attrs);
956                 return (stat);
957         }
958
959         /* start date */
960         tmpattr.name.name = CSA_ENTRY_ATTR_START_DATE;
961         tmpattr.name.num = CSA_ENTRY_ATTR_START_DATE_I;
962         tmpval.type = CSA_VALUE_DATE_TIME;
963         tmpval.item.date_time_value = buf;
964         if ((stat = _csa_tick_to_iso8601(a4->appt_id.tick, buf) ?
965             CSA_E_INVALID_DATE_TIME : CSA_SUCCESS) ||
966             (stat = _DtCm_copy_cms_attribute(&attrs[count++], &tmpattr, B_TRUE))
967             != CSA_SUCCESS) {
968                 goto error;
969         }
970
971         /* type */
972         tmpattr.name.name = CSA_ENTRY_ATTR_TYPE;
973         tmpattr.name.num = CSA_ENTRY_ATTR_TYPE_I;
974         tmpval.type = CSA_VALUE_UINT32;
975         tmpval.item.uint32_value = _DtCm_eventtype4_to_type(a4->tag->tag);
976         if ((stat = _DtCm_copy_cms_attribute(&attrs[count++], &tmpattr, B_TRUE))
977             != CSA_SUCCESS) {
978                 goto error;
979         }
980
981         /* subtype */
982         tmpattr.name.name = CSA_ENTRY_ATTR_SUBTYPE;
983         tmpattr.name.num = CSA_ENTRY_ATTR_SUBTYPE_I;
984         tmpval.type = CSA_VALUE_STRING;
985         tmpval.item.string_value = _DtCm_eventtype4_to_subtype(a4->tag->tag);
986         if ((stat = _DtCm_copy_cms_attribute(&attrs[count++], &tmpattr, B_TRUE))
987             != CSA_SUCCESS) {
988                 goto error;
989         }
990
991         /* showtime */
992         tmpattr.name.name = CSA_X_DT_ENTRY_ATTR_SHOWTIME;
993         tmpattr.name.num = CSA_X_DT_ENTRY_ATTR_SHOWTIME_I;
994         tmpval.type = CSA_VALUE_SINT32;
995         tmpval.item.sint32_value = a4->tag->showtime;
996         if ((stat = _DtCm_copy_cms_attribute(&attrs[count++], &tmpattr, B_TRUE))
997             != CSA_SUCCESS) {
998                 goto error;
999         }
1000
1001         /* end date */
1002         tmpattr.name.name = CSA_ENTRY_ATTR_END_DATE;
1003         tmpattr.name.num = CSA_ENTRY_ATTR_END_DATE_I;
1004         tmpval.type = CSA_VALUE_DATE_TIME;
1005         tmpval.item.date_time_value = buf;
1006         if ((stat = _csa_tick_to_iso8601(a4->appt_id.tick + a4->duration,
1007             buf) ? CSA_E_INVALID_DATE_TIME : CSA_SUCCESS) != CSA_SUCCESS ||
1008             (stat = _DtCm_copy_cms_attribute(&attrs[count++], &tmpattr, B_TRUE))
1009             != CSA_SUCCESS) {
1010                 goto error;
1011         }
1012
1013         /* summary */
1014         tmpattr.name.name = CSA_ENTRY_ATTR_SUMMARY;
1015         tmpattr.name.num = CSA_ENTRY_ATTR_SUMMARY_I;
1016         tmpval.type = CSA_VALUE_STRING;
1017         tmpval.item.string_value = a4->what;
1018         if ((stat = _DtCm_copy_cms_attribute(&attrs[count++], &tmpattr, B_TRUE))
1019             != CSA_SUCCESS) {
1020                 goto error;
1021         }
1022
1023         /* organizer */
1024         tmpattr.name.name = CSA_ENTRY_ATTR_ORGANIZER;
1025         tmpattr.name.num = CSA_ENTRY_ATTR_ORGANIZER_I;
1026         tmpval.type = CSA_VALUE_CALENDAR_USER;
1027         tmpval.item.calendar_user_value = a4->author;
1028         if ((stat = _DtCm_copy_cms_attribute(&attrs[count++], &tmpattr, B_TRUE))
1029             != CSA_SUCCESS) {
1030                 goto error;
1031         }
1032
1033         /* status */
1034         tmpattr.name.name = CSA_ENTRY_ATTR_STATUS;
1035         tmpattr.name.num = CSA_ENTRY_ATTR_STATUS_I;
1036         tmpval.type = CSA_VALUE_UINT32;
1037         tmpval.item.uint32_value = _DtCm_apptstatus4_to_status(a4->appt_status);
1038         if ((stat = _DtCm_copy_cms_attribute(&attrs[count++], &tmpattr, B_TRUE))
1039             != CSA_SUCCESS) {
1040                 goto error;
1041         }
1042
1043         /* classification */
1044         tmpattr.name.name = CSA_ENTRY_ATTR_CLASSIFICATION;
1045         tmpattr.name.num = CSA_ENTRY_ATTR_CLASSIFICATION_I;
1046         tmpval.type = CSA_VALUE_UINT32;
1047         tmpval.item.uint32_value = _DtCm_privacy4_to_classification(a4->privacy);
1048         if ((stat = _DtCm_copy_cms_attribute(&attrs[count++], &tmpattr, B_TRUE))
1049             != CSA_SUCCESS) {
1050                 goto error;
1051         }
1052
1053         /* repeat type */
1054         tmpattr.name.name = CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE;
1055         tmpattr.name.num = CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I;
1056         tmpval.type = CSA_VALUE_SINT32;
1057         tmpval.item.sint32_value = _DtCm_interval4_to_rtype(a4->period.period);
1058         if ((stat = _DtCm_copy_cms_attribute(&attrs[count++], &tmpattr, B_TRUE))
1059             != CSA_SUCCESS) {
1060                 goto error;
1061         }
1062
1063         /* repeat times */
1064         if (a4->period.period != single_4) {
1065                 tmpattr.name.name = CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES;
1066                 tmpattr.name.num = CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I;
1067                 tmpval.type = CSA_VALUE_UINT32;
1068                 tmpval.item.uint32_value = ntimes;
1069                 if ((stat = _DtCm_copy_cms_attribute(&attrs[count++], &tmpattr,
1070                     B_TRUE)) != CSA_SUCCESS) {
1071                         goto error;
1072                 }
1073         }
1074
1075         /* occurrence number */
1076         if (a4->period.period == nthWeekday_4) {
1077                 tmpattr.name.name = CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM;
1078                 tmpattr.name.num = CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I;
1079                 tmpval.type = CSA_VALUE_SINT32;
1080                 tmpval.item.sint32_value = a4->period.nth;
1081                 if ((stat = _DtCm_copy_cms_attribute(&attrs[count++], &tmpattr,
1082                     B_TRUE)) != CSA_SUCCESS) {
1083                         goto error;
1084                 }
1085         }
1086
1087         /* repeat interval */
1088         if (a4->period.period >= everyNthDay_4 &&
1089             a4->period.period <= everyNthMonth_4) {
1090                 tmpattr.name.name = CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL;
1091                 tmpattr.name.num = CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I;
1092                 tmpval.type = CSA_VALUE_UINT32;
1093                 tmpval.item.uint32_value = a4->period.nth;
1094                 if ((stat = _DtCm_copy_cms_attribute(&attrs[count++], &tmpattr,
1095                     B_TRUE)) != CSA_SUCCESS) {
1096                         goto error;
1097                 }
1098         }
1099
1100         if (a4->period.enddate != 0) {
1101                 tmpattr.name.name = CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE;
1102                 tmpattr.name.num = CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE_I;
1103                 tmpval.type = CSA_VALUE_DATE_TIME;
1104                 tmpval.item.date_time_value = buf;
1105                 if ((stat = _csa_tick_to_iso8601(a4->period.enddate, buf) ?
1106                     CSA_E_INVALID_DATE_TIME : CSA_SUCCESS) != CSA_SUCCESS ||
1107                     (stat = _DtCm_copy_cms_attribute(&attrs[count++], &tmpattr,
1108                     B_TRUE)) != CSA_SUCCESS) {
1109                         goto error;
1110                 }
1111         }
1112
1113         while (reminders != NULL) {
1114                 if ((attrs[count].name.num = _DtCm_old_reminder_name_to_index(
1115                     reminders->attr)) >= 0) {
1116                         if ((attrs[count].name.name =
1117                             strdup(_DtCm_old_reminder_name_to_name(
1118                             reminders->attr))) == NULL) {
1119                                 count++;
1120                                 goto error;
1121                         }
1122                         if ((stat = _DtCmAttr4ToReminderValue(reminders,
1123                             &attrs[count++].value)) != CSA_SUCCESS) {
1124                                 count++;
1125                                 goto error;
1126                         }
1127
1128                 }
1129                 reminders = reminders->next;
1130         }
1131
1132         *num_attrs = count;
1133         *attrs_r = attrs;
1134         return (CSA_SUCCESS);
1135
1136 error:
1137         _DtCm_free_cms_attributes(count--, attrs);
1138         free(attrs);
1139         return (stat);
1140 }
1141