libDtSearch: Coverity 86579
[oweals/cde.git] / cde / lib / csa / convert5-4.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: convert5-4.c /main/2 1996/10/07 15:57:11 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 <string.h>
34 #include <stdlib.h>
35 #include "convert4-5.h"
36 #include "convert5-4.h"
37 #include "attr.h"
38 #include "appt4.h"
39 #include "iso8601.h"
40
41 /*
42  * Routines to convert data types used in version 5 to version 4.
43  */
44
45 /*****************************************************************************
46  * extern functions
47  *****************************************************************************/
48
49 /*
50  * attributes are checked before calling this routine
51  * so all attributes should be supported in v4
52  */
53 extern CSA_return_code
54 _DtCm_cmsattrs_to_apptdata(uint size, cms_attribute *attrs, Appt_4 *appt)
55 {
56         CSA_return_code stat = CSA_SUCCESS;
57         char            *string, *ptr;
58         time_t          endtick;
59         cms_attribute   *aptr;
60         char            buf[BUFSIZ];
61
62         /*
63          * this routine is called to convert valid v2 to v4 attributes
64          * so no checking of CSA_E_INVALID_ATTRIBUTE and
65          * CSA_E_UNSUPPORTED_ATTRIBUTE is necessary
66          */
67
68         /* assuming all appt data is available */
69
70         /* start time */
71         if (_csa_iso8601_to_tick(
72             attrs[CSA_ENTRY_ATTR_START_DATE_I].value->item.date_time_value,
73             &appt->appt_id.tick))
74                 return (CSA_E_INVALID_DATE_TIME);
75
76         /* duration */
77         aptr = &attrs[CSA_ENTRY_ATTR_END_DATE_I];
78         if (aptr->value && aptr->value->item.date_time_value &&
79                 *(aptr->value->item.date_time_value))
80         {
81                 if (_csa_iso8601_to_tick(aptr->value->item.date_time_value,
82                     &endtick))
83                         return (CSA_E_INVALID_DATE_TIME);
84                 else
85                         appt->duration = endtick - appt->appt_id.tick;
86         }
87
88         /* id */
89         aptr = &attrs[CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I];
90         if (aptr->value && aptr->value->item.opaque_data_value &&
91                 aptr->value->item.opaque_data_value->size > 0)
92         {
93                 strncpy(buf, (char *)aptr->value->item.opaque_data_value->data,
94                         aptr->value->item.opaque_data_value->size);
95                 buf[aptr->value->item.opaque_data_value->size] = '\0';
96
97                 ptr = strchr(buf, ':');
98                 if (ptr != NULL)
99                         *ptr = '\0';
100
101                 appt->appt_id.key = atol(buf);
102
103         } else
104                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
105
106         /* _DtCm_old_attr_type */
107         if ((stat = _DtCm_attrs_to_eventtype4(
108             attrs[CSA_ENTRY_ATTR_TYPE_I].value,
109             attrs[CSA_ENTRY_ATTR_SUBTYPE_I].value, appt->tag)) != CSA_SUCCESS)
110                 return (stat);
111
112         /* _DtCm_old_attr_what */
113         aptr = &attrs[CSA_ENTRY_ATTR_SUMMARY_I];
114         if (aptr->value->item.string_value) {
115                 if ((string = strdup(aptr->value->item.string_value)) == NULL)
116                         return (CSA_E_INSUFFICIENT_MEMORY);
117                 else {
118                         if (appt->what)
119                                 free(appt->what);
120                         appt->what = string;
121                 }
122         }
123
124         /* _DtCm_old_attr_author */
125         aptr = &attrs[CSA_ENTRY_ATTR_ORGANIZER_I];
126         if (aptr->value && aptr->value->item.calendar_user_value) {
127                 if ((string = strdup(aptr->value->item.calendar_user_value))
128                     == NULL)
129                         return (CSA_E_INSUFFICIENT_MEMORY);
130                 else {
131                         if (appt->author)
132                                 free(appt->author);
133                         appt->author = string;
134                 }
135         }
136
137         /* _DtCm_old_attr_beep_reminder */
138         aptr = &attrs[CSA_ENTRY_ATTR_AUDIO_REMINDER_I];
139         if (aptr->value && aptr->value->item.reminder_value) {
140                 if ((stat = _DtCm_add_reminder(_DtCM_OLD_ATTR_BEEP_REMINDER,
141                     aptr->value->item.reminder_value, appt)) != CSA_SUCCESS)
142                         return (stat);
143         }
144
145         /* _DtCm_old_attr_flash_reminder */
146         aptr = &attrs[CSA_ENTRY_ATTR_FLASHING_REMINDER_I];
147         if (aptr->value && aptr->value->item.reminder_value) {
148                 if ((stat = _DtCm_add_reminder(_DtCM_OLD_ATTR_FLASH_REMINDER,
149                     aptr->value->item.reminder_value, appt)) != CSA_SUCCESS)
150                         return (stat);
151         }
152
153         /* _DtCm_old_attr_mail_reminder */
154         aptr = &attrs[CSA_ENTRY_ATTR_MAIL_REMINDER_I];
155         if (aptr->value && aptr->value->item.reminder_value) {
156                 if ((stat = _DtCm_add_reminder(_DtCM_OLD_ATTR_MAIL_REMINDER,
157                     aptr->value->item.reminder_value, appt)) != CSA_SUCCESS)
158                         return (stat);
159         }
160
161         /* _DtCm_old_attr_popup_reminder */
162         aptr = &attrs[CSA_ENTRY_ATTR_POPUP_REMINDER_I];
163         if (aptr->value && aptr->value->item.reminder_value) {
164                 if ((stat = _DtCm_add_reminder(_DtCM_OLD_ATTR_POPUP_REMINDER,
165                     aptr->value->item.reminder_value, appt)) != CSA_SUCCESS)
166                         return (stat);
167         }
168
169         /* _DtCm_old_attr_repeat_type */
170         if (_DtCm_rtype_to_interval4(
171             attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I].value->item.sint32_value,
172             &appt->period.period))
173                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
174
175         /* _DtCm_old_attr_repeat_times */
176         aptr = &attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I];
177         if (aptr->value)
178                 appt->ntimes = aptr->value->item.uint32_value;
179
180         if (appt->period.period != single_4 &&
181             appt->ntimes == CSA_X_DT_DT_REPEAT_FOREVER) {
182                 appt->ntimes = _DtCM_OLD_REPEAT_FOREVER;
183         }
184
185         /* _DtCm_old_attr_showtime */
186         aptr = &attrs[CSA_X_DT_ENTRY_ATTR_SHOWTIME_I];
187         if (aptr->value)
188                 appt->tag->showtime = aptr->value->item.sint32_value;
189
190         /* _DtCm_old_attr_status */
191         if (_DtCm_status_to_apptstatus4(
192             attrs[CSA_ENTRY_ATTR_STATUS_I].value->item.uint32_value,
193             &appt->appt_status))
194                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
195
196         /* _DtCm_old_attr_privacy */
197         if (_DtCm_classification_to_privacy4(
198             attrs[CSA_ENTRY_ATTR_CLASSIFICATION_I].value->item.uint32_value,
199             &appt->privacy))
200                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
201
202         /* _DtCm_old_attr_end_date */
203         aptr = &attrs[CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE_I];
204         if (aptr->value && aptr->value->item.date_time_value &&
205                 *(aptr->value->item.date_time_value))
206         {
207                 if (_csa_iso8601_to_tick(aptr->value->item.date_time_value,
208                     &appt->period.enddate))
209                         return (CSA_E_INVALID_DATE_TIME);
210         }
211
212         switch (appt->period.period) {
213         case nthWeekday_4:
214                 /* _DtCm_old_attr_repeat_nth_weeknum */
215                 aptr = &attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I];
216                 if (aptr->value)
217                         appt->period.nth = aptr->value->item.sint32_value;
218                 break;
219         case everyNthDay_4:
220         case everyNthWeek_4:
221         case everyNthMonth_4:
222                 /* _DtCm_old_attr_repeat_nth_interval */
223                 aptr = &attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I];
224                 if (aptr->value)
225                         appt->period.nth = aptr->value->item.uint32_value;
226                 break;
227         default:
228                 appt->period.nth = 0;
229         }
230
231         return (stat);
232 }
233
234 /*
235  * ** need to check whether value is valid
236  */
237 extern CSA_return_code
238 _DtCm_attrs_to_apptdata(uint size, CSA_attribute *attrs, Appt_4 *appt)
239 {
240         CSA_return_code stat = CSA_SUCCESS;
241         _DtCm_old_attrs oldattr;
242         char            *string;
243         int             interval = 0, week_num = 0, i;
244         boolean_t       set_interval = B_FALSE, set_weeknum = B_FALSE;
245         time_t          endtick = -1;
246         int             tindex = 0, stindex = 0;
247         CSA_attribute_value     otype;
248
249         for (i = 0; i < size && stat == CSA_SUCCESS; i++) {
250
251                 if (attrs[i].name == NULL)
252                         continue;
253
254                 if ((stat = _DtCm_get_old_attr_by_name(attrs[i].name, &oldattr))
255                     != CSA_SUCCESS)
256                         break;
257
258                 switch (oldattr) {
259                 case _DtCm_old_attr_id:
260                         stat = CSA_E_READONLY;
261                         break;
262
263                 case _DtCm_old_attr_time:
264                         if (attrs[i].value == NULL ||
265                             attrs[i].value->item.date_time_value == NULL ||
266                             _csa_iso8601_to_tick(
267                             attrs[i].value->item.date_time_value,
268                             &appt->appt_id.tick))
269                                 stat = CSA_E_INVALID_DATE_TIME;
270                         break;
271                 case _DtCm_old_attr_type:
272                         if (attrs[i].value == NULL)
273                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
274                         else
275                                 tindex = i;
276                         break;
277                 case _DtCm_old_attr_type2:
278                         stindex = i;
279                         break;
280                 case _DtCm_old_attr_duration:
281                         if (attrs[i].value == NULL)
282                                 appt->duration = 0;
283                         else if (attrs[i].value->item.date_time_value
284                             == NULL || _csa_iso8601_to_tick(
285                             attrs[i].value->item.date_time_value,
286                             &endtick))
287                                 stat = CSA_E_INVALID_DATE_TIME;
288                         break;
289                 case _DtCm_old_attr_what:
290                         if (attrs[i].value && attrs[i].value->item.string_value)
291                         {
292                                 if ((string = strdup(
293                                     attrs[i].value->item.string_value))
294                                     == NULL)
295                                         stat = CSA_E_INSUFFICIENT_MEMORY;
296                                 else {
297                                         if (appt->what)
298                                                 free(appt->what);
299                                         appt->what = string;
300                                 }
301                         }
302                         break;
303                 case _DtCm_old_attr_author:
304                         stat = CSA_E_READONLY;
305                         break;
306
307                 case _DtCm_old_attr_beep_reminder:
308                         if (attrs[i].value == NULL)
309                                 stat = _DtCm_remove_reminder(
310                                         _DtCM_OLD_ATTR_BEEP_REMINDER, appt);
311                         else if (attrs[i].value->item.reminder_value == NULL)
312                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
313                         else
314                                 stat = _DtCm_add_reminder(
315                                         _DtCM_OLD_ATTR_BEEP_REMINDER,
316                                         attrs[i].value->item.reminder_value,
317                                         appt);
318                         break;
319
320                 case _DtCm_old_attr_flash_reminder:
321                         if (attrs[i].value == NULL)
322                                 stat = _DtCm_remove_reminder(
323                                         _DtCM_OLD_ATTR_FLASH_REMINDER, appt);
324                         else if (attrs[i].value->item.reminder_value == NULL)
325                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
326                         else
327                                 stat = _DtCm_add_reminder(
328                                         _DtCM_OLD_ATTR_FLASH_REMINDER,
329                                         attrs[i].value->item.reminder_value,
330                                         appt);
331                         break;
332
333                 case _DtCm_old_attr_mail_reminder:
334                         if (attrs[i].value == NULL)
335                                 stat = _DtCm_remove_reminder(
336                                         _DtCM_OLD_ATTR_MAIL_REMINDER, appt);
337                         else if (attrs[i].value->item.reminder_value == NULL)
338                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
339                         else
340                                 stat = _DtCm_add_reminder(
341                                         _DtCM_OLD_ATTR_MAIL_REMINDER,
342                                         attrs[i].value->item.reminder_value,
343                                         appt);
344                         break;
345
346                 case _DtCm_old_attr_popup_reminder:
347                         if (attrs[i].value == NULL)
348                                 stat = _DtCm_remove_reminder(
349                                         _DtCM_OLD_ATTR_POPUP_REMINDER, appt);
350                         else if (attrs[i].value->item.reminder_value == NULL)
351                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
352                         else
353                                 stat = _DtCm_add_reminder(
354                                         _DtCM_OLD_ATTR_POPUP_REMINDER,
355                                         attrs[i].value->item.reminder_value,
356                                         appt);
357                         break;
358
359                 case _DtCm_old_attr_repeat_type:
360                         if (attrs[i].value == NULL)
361                                 appt->period.period = single_4;
362                         else if (_DtCm_rtype_to_interval4(
363                             attrs[i].value->item.sint32_value,
364                             &appt->period.period))
365                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
366                         break;
367                 case _DtCm_old_attr_repeat_times:
368                         if (attrs[i].value == NULL)
369                                 appt->ntimes = 1;
370                         else 
371                                 appt->ntimes =
372                                         attrs[i].value->item.uint32_value;
373                         break;
374                 case _DtCm_old_attr_showtime:
375                         if (attrs[i].value == NULL)
376                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
377                         else
378                                 appt->tag->showtime =
379                                         attrs[i].value->item.sint32_value;
380                         break;
381                 case _DtCm_old_attr_status:
382                         if (attrs[i].value == NULL)
383                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
384                         else if (_DtCm_status_to_apptstatus4(
385                             attrs[i].value->item.sint32_value,
386                             &appt->appt_status))
387                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
388                         break;
389                 case _DtCm_old_attr_privacy:
390                         if (attrs[i].value == NULL)
391                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
392                         else if (_DtCm_classification_to_privacy4(
393                             attrs[i].value->item.sint32_value,
394                             &appt->privacy))
395                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
396                         break;
397                 case _DtCm_old_attr_repeat_nth_interval:
398                         if (attrs[i].value != NULL) {
399                                 set_interval = B_TRUE;
400                                 interval = attrs[i].value->item.uint32_value;
401                         }
402                         break;
403                 case _DtCm_old_attr_repeat_nth_weeknum:
404                         if (attrs[i].value != NULL) {
405                                 set_weeknum = B_TRUE;
406                                 week_num = attrs[i].value->item.sint32_value;
407                         }
408                         break;
409                 case _DtCm_old_attr_end_date:
410                         if (attrs[i].value == NULL)
411                                 appt->period.enddate = 0;
412                         else if (attrs[i].value->item.date_time_value == NULL ||
413                             _csa_iso8601_to_tick(
414                             attrs[i].value->item.date_time_value,
415                             &appt->period.enddate))
416                                 stat = CSA_E_INVALID_DATE_TIME;
417                         break;
418                 default:
419                         stat = CSA_E_INVALID_PARAMETER;
420                 }
421         }
422
423         if (stat == CSA_SUCCESS) {
424
425                 if (tindex || stindex) {
426                         if (tindex == 0) {
427                                 otype.type = CSA_VALUE_SINT32;
428                                 switch (appt->tag->tag) {
429                                 case appointment_4:
430                                 case holiday_4:
431                                         otype.item.sint32_value =
432                                                 CSA_TYPE_EVENT;
433                                         break;
434                                 case toDo_4:
435                                         otype.item.sint32_value = CSA_TYPE_TODO;
436                                         break;
437                                 case reminder_4:
438                                 case otherTag_4:
439                                         otype.item.sint32_value =
440                                                 CSA_X_DT_TYPE_OTHER; 
441                                 }
442                         }
443
444                         stat = _DtCm_attrs_to_eventtype4(
445                                 (cms_attribute_value *)
446                                 (tindex ? attrs[tindex].value : &otype),
447                                 (cms_attribute_value *)
448                                 (stindex ? attrs[stindex].value : NULL),
449                                 appt->tag);
450                 }
451
452                 if (stat == CSA_SUCCESS) {
453                         if (endtick >= 0) {
454                                 appt->duration = endtick - appt->appt_id.tick;
455                                 /* make sure duration is positive */
456                                 if (appt->duration < 0)
457                                         stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
458                         }
459
460                         if (appt->period.period != single_4 &&
461                             appt->ntimes == CSA_X_DT_DT_REPEAT_FOREVER) {
462                                 appt->ntimes = _DtCM_OLD_REPEAT_FOREVER;
463                         }
464
465                         switch (appt->period.period) {
466                         case nthWeekday_4:
467                                 if (set_weeknum == B_TRUE)
468                                         appt->period.nth = week_num;
469                                 break;
470                         case everyNthDay_4:
471                         case everyNthWeek_4:
472                         case everyNthMonth_4:
473                                 if (set_interval == B_TRUE)
474                                         appt->period.nth = interval;
475                                 break;
476                         default:
477                                 appt->period.nth = 0;
478                         }
479                 }
480         }
481
482         return (stat);
483 }
484
485 extern CSA_return_code
486 _DtCm_cms_entry_to_appt4(cms_entry *entry, Appt_4 **appt4_r)
487 {
488         CSA_return_code stat;
489         Appt_4          *appt;
490
491         if (entry == NULL || appt4_r == NULL)
492                 return (CSA_E_INVALID_PARAMETER);
493
494         if ((appt = _DtCm_make_appt4(B_TRUE)) == NULL)
495                 return (CSA_E_INSUFFICIENT_MEMORY);
496
497         if ((stat = _DtCm_cmsattrs_to_apptdata(entry->num_attrs, entry->attrs,
498             appt)) != CSA_SUCCESS) {
499                 _DtCm_free_appt4(appt);
500                 return (stat);
501         } else {
502                 *appt4_r = appt;
503                 return (CSA_SUCCESS);
504         }
505 }
506
507 extern CSA_return_code
508 _DtCm_attrs_to_appt4(uint num_attrs, CSA_attribute *attrs, Appt_4 **appt4_r)
509 {
510         CSA_return_code stat;
511         Appt_4          *appt;
512
513         if (appt4_r == NULL)
514                 return (CSA_E_INVALID_PARAMETER);
515
516         if ((appt = _DtCm_make_appt4(B_TRUE)) == NULL)
517                 return (CSA_E_INSUFFICIENT_MEMORY);
518
519         if ((stat = _DtCm_attrs_to_apptdata(num_attrs, attrs, appt)) != CSA_SUCCESS) {
520                 _DtCm_free_appt4(appt);
521                 return (stat);
522         } else {
523                 *appt4_r = appt;
524                 return (CSA_SUCCESS);
525         }
526 }
527
528 extern CSA_return_code
529 _DtCm_scope_to_options4(CSA_enum scope, Options_4 *opt)
530 {
531         if (opt == NULL)
532                 return (CSA_E_INVALID_PARAMETER);
533
534         switch (scope) {
535         case CSA_SCOPE_ONE:
536                 *opt = do_one_4;
537                 break;
538         case CSA_SCOPE_ALL:
539                 *opt = do_all_4;
540                 break;
541         case CSA_SCOPE_FORWARD:
542                 *opt = do_forward_4;
543                 break;
544         default:
545                 return (CSA_E_INVALID_ENUM);
546         }
547
548         return (CSA_SUCCESS);
549 }
550
551 extern CSA_return_code
552 _DtCm_csaaccesslist_toaccessentry4(CSA_access_list alist, Access_Entry_4 **a4)
553 {
554         CSA_return_code stat = CSA_SUCCESS;
555         Access_Entry_4  *to, *prev, *head;
556
557         head = prev = NULL;
558         while (alist != NULL) {
559                 if ((to = (Access_Entry_4 *)calloc(1, sizeof(Access_Entry_4)))
560                     == NULL) {
561                         stat = CSA_E_INSUFFICIENT_MEMORY;
562                         break;
563                 }
564
565                 if ((to->access_type = _DtCmAccessRightToV4AccessType(
566                     alist->rights)) < 0) {
567                         stat = CSA_E_INVALID_FLAG;
568                         break;
569                 }
570
571                 if (alist->user == NULL || alist->user->user_name == NULL) {
572                         stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
573                         break;
574                 }
575
576                 if ((to->who = strdup(alist->user->user_name)) == NULL) {
577                         free(to);
578                         stat = CSA_E_INSUFFICIENT_MEMORY;
579                         break;
580                 }
581
582                 if (head == NULL)
583                         head = to;
584                 else
585                         prev->next = to;
586
587                 prev = to;
588
589                 alist = alist->next;
590         }
591
592         if (stat != CSA_SUCCESS) {
593                 _DtCm_free_access_list4(head);
594                 head = NULL;
595         }
596
597         *a4 = head;
598         return (stat);
599 }
600
601 extern int
602 _DtCm_rtype_to_interval4(int val, Interval_4 *period)
603 {
604         switch (val) {
605         case CSA_X_DT_REPEAT_ONETIME:
606                 *period = single_4;
607                 break;
608         case CSA_X_DT_REPEAT_WEEKLY:
609                 *period = weekly_4;
610                 break;
611         case CSA_X_DT_REPEAT_DAILY:
612                 *period = daily_4;
613                 break;
614         case CSA_X_DT_REPEAT_BIWEEKLY:
615                 *period = biweekly_4;
616                 break;
617         case CSA_X_DT_REPEAT_MONTHLY_BY_DATE:
618                 *period = monthly_4;
619                 break;
620         case CSA_X_DT_REPEAT_YEARLY:
621                 *period = yearly_4;
622                 break;
623         case CSA_X_DT_REPEAT_MONTHLY_BY_WEEKDAY:
624                 *period = nthWeekday_4;
625                 break;
626         case CSA_X_DT_REPEAT_EVERY_NDAY:
627                 *period = everyNthDay_4;
628                 break;
629         case CSA_X_DT_REPEAT_EVERY_NWEEK:
630                 *period = everyNthWeek_4;
631                 break;
632         case CSA_X_DT_REPEAT_EVERY_NMONTH:
633                 *period = everyNthMonth_4;
634                 break;
635         case CSA_X_DT_REPEAT_MON_TO_FRI:
636                 *period = monThruFri_4;
637                 break;
638         case CSA_X_DT_REPEAT_MONWEDFRI:
639                 *period = monWedFri_4;
640                 break;
641         case CSA_X_DT_REPEAT_TUETHUR:
642                 *period = tueThur_4;
643                 break;
644         case CSA_X_DT_REPEAT_WEEKDAYCOMBO:
645                 *period = daysOfWeek_4;
646                 break;
647         case CSA_X_DT_REPEAT_OTHER:
648                 *period = otherPeriod_4;
649                 break;
650         default:
651                 return (-1);
652         }
653         return (0);
654 }
655
656 extern int
657 _DtCm_status_to_apptstatus4(int val, Appt_Status_4 *astat)
658 {
659         switch (val) {
660         case CSA_X_DT_STATUS_ACTIVE:
661                 *astat = active_4;
662                 break;
663         case CSA_STATUS_COMPLETED:
664                 *astat = completed_4;
665                 break;
666         case CSA_X_DT_STATUS_CANCELLED:
667                 *astat = cancelled_4;
668                 break;
669         case CSA_X_DT_STATUS_COMMITTED:
670                 *astat = committed_4;
671                 break;
672         case CSA_X_DT_STATUS_ADD_PENDING:
673                 *astat = pendingAdd_4;
674                 break;
675         case CSA_X_DT_STATUS_DELETE_PENDING:
676                 *astat = pendingDelete_4;
677                 break;
678         default:
679                 return (-1);
680         }
681
682         return (0);
683 }
684
685 extern int
686 _DtCm_classification_to_privacy4(int val, Privacy_Level_4 *privacy)
687 {
688         switch (val) {
689         case CSA_CLASS_PUBLIC:
690                 *privacy = public_4;
691                 break;
692         case CSA_CLASS_CONFIDENTIAL:
693                 *privacy = semiprivate_4;
694                 break;
695         case CSA_CLASS_PRIVATE:
696                 *privacy = private_4;
697                 break;
698         default:
699                 return (-1);
700         }
701
702         return (0);
703 }
704
705 extern CSA_return_code
706 _DtCm_attrs_to_eventtype4(
707         cms_attribute_value     *type,
708         cms_attribute_value     *stype,
709         Tag_4                   *tag)
710 {
711         CSA_return_code stat = CSA_SUCCESS;
712
713         if (type) {
714                 switch (type->item.uint32_value) {
715                 case CSA_TYPE_EVENT:
716
717                         if (stype && stype->item.string_value) {
718                                 if (strcmp(stype->item.string_value,
719                                     CSA_SUBTYPE_APPOINTMENT) == 0)
720                                         tag->tag = appointment_4;
721                                 else if (strcmp(stype->item.string_value,
722                                     CSA_SUBTYPE_HOLIDAY) == 0)
723                                         tag->tag = holiday_4;
724                                 else
725                                         stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
726                         } else
727                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
728                         break;
729
730                 case CSA_TYPE_TODO:
731
732                         if (stype)
733                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
734                         else
735                                 tag->tag = toDo_4;
736                         break;
737
738                 case CSA_X_DT_TYPE_OTHER:
739
740                         if (stype)
741                                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
742                         else
743                                 tag->tag = otherTag_4;
744                         break;
745
746                 default:
747                         stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
748                 }
749         } else
750                 stat = CSA_E_INVALID_ATTRIBUTE_VALUE;
751
752         return (stat);
753 }
754
755 /*
756  * Get rid of the given reminder in the appt.
757  */
758 extern CSA_return_code
759 _DtCm_remove_reminder(char *rem, Appt_4 *appt)
760 {
761         Attribute_4     *attr, *prev;
762
763         for (attr = prev = appt->attr; attr != NULL; attr = attr->next) { 
764                 if (strcmp(attr->attr, rem) == 0) {
765                         if (prev == attr)
766                                 appt->attr = attr->next;
767                         else
768                                 prev->next = attr->next;
769
770                         attr->next = NULL;
771                         _DtCm_free_attr4(attr);
772                 } else
773                         prev = attr;
774         }
775
776         return (CSA_SUCCESS);
777 }
778
779 /*
780  * If the corresponding attribute exists already, replace it.
781  */
782 extern CSA_return_code
783 _DtCm_add_reminder(char *rem, CSA_reminder * val, Appt_4 *appt)
784 {
785         Attribute_4     *newattr, *attrs, *prev = NULL;
786         char            adv[80];
787         time_t          ltime = 0;
788
789 /*
790         if ((val->snooze_time && val->snooze_time[0] != NULL)
791             || val->repeat_count > 1)
792                 return (CSA_E_INVALID_ATTRIBUTE_VALUE);
793 */
794
795         if ((newattr = calloc(1, sizeof(Attribute_4))) == NULL)
796                 return (CSA_E_INSUFFICIENT_MEMORY);
797
798         if ((newattr->attr = strdup(rem)) == NULL) {
799                 free(newattr);
800                 return (CSA_E_INSUFFICIENT_MEMORY);
801         }
802
803         /* convert lead_time to advance value */
804         if (val->lead_time)
805                 _csa_iso8601_to_duration(val->lead_time, &ltime);
806         sprintf(adv, "%d", ltime);
807
808         if ((newattr->value = strdup(adv)) == NULL) {
809                 _DtCm_free_attr4(newattr);
810                 return (CSA_E_INSUFFICIENT_MEMORY);
811         }
812
813         if (val->reminder_data.size > 0) {
814                 if ((newattr->clientdata = malloc(val->reminder_data.size + 1))
815                     == NULL) {
816                         _DtCm_free_attr4(newattr);
817                         return (CSA_E_INSUFFICIENT_MEMORY);
818                 }
819                 memcpy(newattr->clientdata, val->reminder_data.data,
820                         val->reminder_data.size);
821                 newattr->clientdata[val->reminder_data.size] = '\0';
822
823         } else if ((newattr->clientdata = calloc(1,1)) == NULL) {
824                 _DtCm_free_attr4(newattr);
825                 return (CSA_E_INSUFFICIENT_MEMORY);
826         }
827
828         for (attrs = appt->attr; attrs != NULL; attrs = attrs->next) {
829                 if (strcmp(attrs->attr, rem) == 0) {
830
831                         newattr->next = attrs->next;
832                         if (prev == NULL)
833                                 appt->attr = newattr;
834                         else
835                                 prev->next = newattr;
836
837                         attrs->next = NULL;
838                         _DtCm_free_attr4(attrs);
839
840                         break;
841                 } else
842                         prev = attrs;
843         }
844
845         if (attrs == NULL) {
846                 newattr->next = appt->attr;
847                 appt->attr = newattr;
848         }
849
850         return (CSA_SUCCESS);
851 }
852
853 extern int
854 _DtCmAccessRightToV4AccessType(unsigned int access)
855 {
856         int     newaccess = access_none_4;
857
858         if (access < 0 ||
859             access & ~(CSA_X_DT_BROWSE_ACCESS | CSA_X_DT_INSERT_ACCESS |
860             CSA_X_DT_DELETE_ACCESS))
861                 return (-1);
862
863         if (access & CSA_X_DT_BROWSE_ACCESS)
864                 newaccess |= access_read_4;
865         if (access & CSA_X_DT_INSERT_ACCESS)
866                 newaccess |= access_write_4;
867         if (access & CSA_X_DT_DELETE_ACCESS)
868                 newaccess |= access_delete_4;
869
870         return (newaccess);
871 }
872