1 /* $XConsortium: cmsfunc.c /main/4 1995/11/09 12:42:12 rswiston $ */
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.
16 #include <sys/resource.h>
24 #include "cmscalendar.h"
25 #include "updateattrs.h"
29 #include "rpcextras.h"
42 #include "convert4-5.h"
43 #include "convert5-4.h"
45 #include "cmsconvert.h"
49 /******************************************************************************
50 * forward declaration of static functions used within the file
51 ******************************************************************************/
53 static CSA_return_code _DtCmsCreateCallog(char *user, cms_create_args *args,
54 _DtCmsCalendar **cal);
55 static CSA_return_code _ListCalendarNames(uint *num_names, char ***names);
56 static void * _grow_char_array(void *ptr, uint oldcount, uint newcount);
57 static void _free_char_array(uint num_elem, char **ptr);
58 static CSA_return_code _DtCmsGetOldCalAttrNames(_DtCmsCalendar *cal,
59 uint *num_names_r, cms_attr_name **names_r);
61 /*****************************************************************************
62 * extern functions used in the library
63 *****************************************************************************/
66 cms_ping_5_svc(void *args, struct svc_req *svcrq)
71 fprintf(stderr, "cms_ping_5_svc called\n");
73 return((void *)&dummy); /* for RPC reply */
77 extern cms_list_calendars_res *
78 cms_list_calendars_5_svc(void *dummy, struct svc_req *svcrq)
80 static cms_list_calendars_res res;
83 fprintf(stderr, "cms_list_calendars_5_svc called\n");
85 if (res.num_names > 0) {
86 _free_char_array(res.num_names, res.names);
90 res.stat = _ListCalendarNames(&res.num_names, &res.names);
96 cms_open_calendar_5_svc(cms_open_args *args, struct svc_req *svcrq)
98 static cms_open_res res;
99 static char sversion[80];
104 fprintf(stderr, "cms_open_calendar_5_svc called\n");
106 if (res.num_attrs > 0) {
107 _DtCm_free_cms_attributes(res.num_attrs, res.attrs);
112 /* check parameter */
113 if (args->cal == NULL) {
114 res.stat = CSA_E_INVALID_PARAMETER;
118 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
119 &res.user_access, &cal)) == CSA_SUCCESS) {
121 res.svr_vers = TABLEVERS;
123 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
125 res.file_vers = cal->fversion;
128 /* old format data */
129 res.file_vers = _DtCM_FIRST_EXTENSIBLE_DATA_VERSION - 1;
132 /* return attribute names */
133 res.stat = _DtCmsGetAllCalAttrs(cal, &res.num_attrs,
134 &res.attrs, B_FALSE);
137 if (res.stat == CSA_SUCCESS) {
139 cal->rlist = _DtCmsDoOpenCalCallback(cal->rlist,
140 cal->calendar, user, args->pid);
147 extern CSA_return_code *
148 cms_create_calendar_5_svc(cms_create_args *args, struct svc_req *svcrq)
150 static CSA_return_code res;
155 fprintf(stderr, "cms_create_calendar_5_svc called\n");
157 /* check parameter */
158 if (args->cal == NULL) {
159 res = CSA_E_INVALID_PARAMETER;
163 /* need to check whether we know about the sender,
164 * if not, fail the request
166 if ((res = _DtCmsGetClientInfo(svcrq, &user)) != CSA_SUCCESS) {
170 if ((res = _DtCm_check_cal_cms_attributes(_DtCMS_VERSION4,
171 args->num_attrs, args->attrs, user, args->cal, B_TRUE, B_TRUE,
172 B_FALSE)) != CSA_SUCCESS)
175 if ((res = _DtCmsGetCalendarByName(args->cal, B_FALSE, &cal))
176 == CSA_SUCCESS && cal != NULL) {
178 res = CSA_E_CALENDAR_EXISTS;
182 /* create callog file for new calendar */
183 res = _DtCmsCreateCallog(user, args, &cal);
189 extern CSA_return_code *
190 cms_remove_calendar_5_svc(cms_remove_args *args, struct svc_req *svcrq)
192 static CSA_return_code res;
198 fprintf(stderr, "cms_remove_calendar_5_svc called\n");
200 if ((res = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
201 &access, &cal)) != CSA_SUCCESS)
204 if (!(access & CSA_OWNER_RIGHTS)) {
206 res = CSA_E_NO_AUTHORITY;
210 /* move callog.name file to calrm.name */
211 res = _DtCmsRemoveLog(cal->calendar, user);
213 if (res != CSA_SUCCESS)
217 cal->rlist = _DtCmsDoRemoveCalCallback(cal->rlist,
218 cal->calendar, user, args->pid);
220 /* free up internal structures */
221 _DtCmsFreeCalendar(cal);
227 extern CSA_return_code *
228 cms_register_5_svc(cms_register_args *args, struct svc_req *svcrq)
230 static CSA_return_code res;
233 _DtCmsRegistrationInfo *rinfo;
236 fprintf(stderr, "cms_register_5_svc called\n");
238 if (args->cal == NULL ||
239 args->update_type >= (CSA_CB_ENTRY_UPDATED << 1)) {
240 res = CSA_E_INVALID_PARAMETER;
244 if ((res = _DtCmsGetClientInfo(svcrq, &user)) != CSA_SUCCESS)
247 if ((res = _DtCmsGetCalendarByName(args->cal, B_TRUE, &cal))
251 if ((rinfo = _DtCmsGetRegistration(&(cal->rlist), user, args->prognum,
252 args->versnum, args->procnum, args->pid)) == NULL) {
253 /* this client has not registered */
255 if ((rinfo = _DtCmsMakeRegistrationInfo(user,
256 args->update_type, args->prognum, args->versnum,
257 args->procnum, args->pid)) == NULL) {
258 res = CSA_E_INSUFFICIENT_MEMORY;
262 /* put in the calendar's registration list */
263 rinfo->next = cal->rlist;
267 fprintf(stderr, "%s registered on %s, old types = %d\n",
268 user, args->cal, rinfo->types);
271 /* add new type to the registration */
272 rinfo->types = rinfo->types | args->update_type;
276 fprintf(stderr, "%s registered on %s, types = %d\n",
277 user, args->cal, rinfo->types);
284 extern CSA_return_code *
285 cms_unregister_5_svc(cms_register_args *args, struct svc_req *svcrq)
287 static CSA_return_code res;
290 _DtCmsRegistrationInfo *rinfo;
293 fprintf(stderr, "cms_unregister_5_svc called\n");
295 if (args->cal == NULL ||
296 args->update_type >= (CSA_CB_ENTRY_UPDATED << 1)) {
297 res = CSA_E_INVALID_PARAMETER;
301 if ((res = _DtCmsGetClientInfo(svcrq, &user)) != CSA_SUCCESS)
304 if ((res = _DtCmsGetCalendarByName(args->cal, B_FALSE, &cal))
308 if (cal == NULL || (rinfo = _DtCmsGetRegistration(&(cal->rlist), user,
309 args->prognum, args->versnum, args->procnum, args->pid)) == NULL) {
310 res = CSA_E_CALLBACK_NOT_REGISTERED;
314 /* update registration info */
316 fprintf(stderr, "%s registered on %s, old types = %d\n",
317 user, args->cal, rinfo->types);
320 /* registered bits are cleared, unregistered bits are ignored */
321 rinfo->types = (rinfo->types | args->update_type) ^ args->update_type;
324 fprintf(stderr, "%s unregistered types %d on %s, new types = %d\n",
325 user, args->update_type, args->cal, rinfo->types);
328 if (rinfo->types == 0) {
329 cal->rlist = _DtCmsRemoveRegistration(cal->rlist, rinfo);
336 extern cms_enumerate_calendar_attr_res *
337 cms_enumerate_calendar_attr_5_svc(buffer *args, struct svc_req *svcrq)
339 static cms_enumerate_calendar_attr_res res;
346 fprintf(stderr, "cms_enumerate_calendar_attr_5_svc called\n");
348 if (res.num_names > 0) {
349 _DtCmsFreeCmsAttrNames(res.num_names, res.names);
353 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, *args, &user,
354 &access, &cal)) != CSA_SUCCESS)
357 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
358 if (!_DTCMS_HAS_VIEW_CALENDAR_ATTR_ACCESS(access)) {
359 res.stat = CSA_E_NO_AUTHORITY;
363 res.stat = _DtCmsGetCalAttrNames(cal, &res.num_names,
366 res.stat = _DtCmsGetOldCalAttrNames(cal, &res.num_names,
373 extern cms_get_cal_attr_res *
374 cms_get_calendar_attr_5_svc(cms_get_cal_attr_args *args, struct svc_req *svcrq)
376 static cms_get_cal_attr_res res;
382 fprintf(stderr, "cms_get_calendar_attr_5_svc called\n");
384 if (res.num_attrs > 0) {
385 _DtCm_free_cms_attributes(res.num_attrs, res.attrs);
390 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
391 &access, &cal)) != CSA_SUCCESS)
394 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
395 !_DTCMS_HAS_VIEW_CALENDAR_ATTR_ACCESS(access)) {
396 res.stat = CSA_E_NO_AUTHORITY;
400 if (args->num_names > 0)
401 res.stat = _DtCmsGetCalAttrsByName(cal, args->num_names,
402 args->names, &res.num_attrs, &res.attrs);
404 res.stat = _DtCmsGetAllCalAttrs(cal, &res.num_attrs,
410 extern CSA_return_code *
411 cms_set_calendar_attr_5_svc(cms_set_cal_attr_args *args, struct svc_req *svcrq)
413 static CSA_return_code res;
419 fprintf(stderr, "cms_set_calendar_attr_5_svc called\n");
421 if ((res = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
422 &access, &cal)) != CSA_SUCCESS)
425 if ((cal->fversion < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
426 !(access & CSA_OWNER_RIGHTS)) ||
427 (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
428 !(access & (CSA_OWNER_RIGHTS | CSA_INSERT_CALENDAR_ATTRIBUTES |
429 CSA_CHANGE_CALENDAR_ATTRIBUTES)))) {
430 res = CSA_E_NO_AUTHORITY;
435 if (args->cal == NULL || args->num_attrs == 0) {
436 res = CSA_E_INVALID_PARAMETER;
440 /* check validity of attribute values */
441 if ((res = _DtCm_check_cal_cms_attributes(
442 (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ?
443 cal->fversion : _DtCM_FIRST_EXTENSIBLE_DATA_VERSION - 1),
444 args->num_attrs, args->attrs, NULL, NULL, B_TRUE, B_FALSE, B_TRUE))
448 if (cal->fversion >=_DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
449 if ((res = _DtCmsUpdateCalAttributesAndLog(cal, args->num_attrs,
450 args->attrs, access)) != CSA_SUCCESS)
456 Access_Entry_4 *v4list;
458 /* for old format file, the only settable calendar attribute
461 for (i = args->num_attrs - 1; i >= 0; i--) {
462 if (args->attrs[i].name.name)
466 if (args->attrs[i].value == NULL ||
467 args->attrs[i].value->item.access_list_value == NULL) {
468 res = _DtCmsSetV4AccessListAndLog(cal, NULL);
470 if ((res = _DtCmsCmsAccessToV4Access(
471 args->attrs[i].value->item.access_list_value,
472 &v4list)) == CSA_SUCCESS)
473 res = _DtCmsSetV4AccessListAndLog(cal, v4list);
476 if (res != CSA_SUCCESS)
481 cal->rlist = _DtCmsDoUpdateCalAttrsCallback(cal->rlist, cal->calendar,
482 user, args->num_attrs, args->attrs, args->pid);
490 extern cms_archive_res *
491 cms_archive_5_svc(cms_archive_args *args, struct svc_req *svcrq)
493 static cms_archive_res res;
496 fprintf(stderr, "cms_archive_5_svc called\n");
498 res.stat = CSA_E_NOT_SUPPORTED;
502 extern CSA_return_code *
503 cms_restore_5_svc(cms_restore_args *args, struct svc_req *svcrq)
505 static CSA_return_code res;
508 fprintf(stderr, "cms_restore_5_svc called\n");
510 res = CSA_E_NOT_SUPPORTED;
514 extern cms_reminder_res *
515 cms_lookup_reminder_5_svc(cms_reminder_args *args, struct svc_req *svcrq)
517 static cms_reminder_res res;
523 fprintf(stderr, "cms_lookup_reminder_5_svc called\n");
525 if (res.rems != NULL) {
526 _DtCmsFreeReminderRef(res.rems);
530 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
531 &access, &cal)) != CSA_SUCCESS)
534 if ((access & CSA_OWNER_RIGHTS) == 0) {
535 res.stat = CSA_E_NO_AUTHORITY;
539 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
540 res.stat = _DtCmsLookupReminder(cal->remq, args->tick,
541 args->num_names, args->names, &res.rems);
546 if ((res.stat = _DtCmsGetV4Reminders(cal, time(0), &v4rem,
547 &ids)) == CSA_SUCCESS) {
548 res.stat = _DtCmsV4ReminderToReminderRef(cal->calendar,
549 v4rem, ids, &res.rems);
550 _DtCm_free_reminder4(v4rem);
551 _DtCmsFreeEntryIds(ids);
558 extern cms_entries_res *
559 cms_lookup_entries_5_svc(cms_lookup_entries_args *args, struct svc_req *svcrq)
561 static cms_entries_res res;
565 time_t start1, start2, end1, end2;
568 boolean_t no_start_time_range, no_end_time_range;
570 cms_attribute *hattrs;
574 fprintf(stderr, "cms_lookup_entries_5_svc called\n");
577 _DtCm_free_cms_entries(res.entries);
581 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
582 &access, &cal)) != CSA_SUCCESS)
585 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
586 !_DTCMS_HAS_VIEW_ACCESS(access)) {
587 res.stat = CSA_E_NO_AUTHORITY;
592 if ((res.stat = _DtCm_check_operator(args->num_attrs, NULL,
593 args->attrs, args->ops)) != CSA_SUCCESS)
597 if ((res.stat = _DtCmHashCriteria(
598 cal->fversion < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ?
599 _DtCm_entry_name_tbl : cal->entry_tbl, args->num_attrs,
600 NULL, args->attrs, args->ops, &no_match, &no_start_time_range,
601 &no_end_time_range, &start1, &start2, &end1, &end2, &id,
602 &hnum, &hattrs, &hops)) == CSA_E_INVALID_ATTRIBUTE) {
604 /* attribute not defined in this calendar specified,
607 res.stat = CSA_SUCCESS;
610 } else if (res.stat != CSA_SUCCESS || no_match == B_TRUE)
614 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
616 res.stat = _DtCmsLookupEntriesById(cal, user, access,
617 no_start_time_range, no_end_time_range,
618 start1, start2, end1, end2, id, hnum,
619 hattrs, hops, &res.entries);
621 res.stat = _DtCmsLookupEntries(cal, user, access,
622 start1, start2, no_end_time_range,
623 end1, end2, hnum, hattrs, hops,
627 Appt_4 *appt = NULL;;
630 res.stat = _DtCmsLookupKeyrangeV4(cal, user, access,
631 no_start_time_range, no_end_time_range,
632 start1, start2, end1, end2, id,
633 _DtCm_match_one_appt, hnum, hattrs,
636 prange.key1 = start1;
637 prange.key2 = start2;
639 res.stat = _DtCmsLookupRangeV4(cal, user, access,
640 &prange, no_end_time_range, end1, end2,
641 _DtCm_match_one_appt, hnum,
642 hattrs, hops, &appt, NULL);
645 if (res.stat == CSA_SUCCESS && appt) {
646 res.stat = _DtCmsAppt4ToCmsentriesForClient(args->cal,
648 _DtCm_free_appt4(appt);
652 _DtCmFreeHashedArrays(hnum, hattrs, hops);
657 extern cms_entries_res *
658 cms_enumerate_sequence_5_svc(cms_enumerate_args *args, struct svc_req *svcrq)
660 static cms_entries_res res;
666 fprintf(stderr, "cms_enumerate_sequence_5_svc called\n");
669 _DtCm_free_cms_entries(res.entries);
673 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
674 &access, &cal)) != CSA_SUCCESS)
677 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
678 !_DTCMS_HAS_VIEW_ACCESS(access)) {
679 res.stat = CSA_E_NO_AUTHORITY;
684 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
685 res.stat = _DtCmsEnumerateSequenceById(cal, user, access,
686 B_FALSE, B_TRUE, args->start, args->end,
687 0, 0, args->id, 0, NULL, NULL, &res.entries);
691 res.stat = _DtCmsLookupKeyrangeV4(cal, user, access,
692 B_FALSE, B_TRUE, args->start, args->end,
693 0, 0, args->id, NULL, 0, NULL, NULL, &appt,
696 if (res.stat == CSA_SUCCESS && appt) {
697 res.stat = _DtCmsAppt4ToCmsentriesForClient(args->cal,
699 _DtCm_free_appt4(appt);
706 extern cms_get_entry_attr_res *
707 cms_get_entry_attr_5_svc(cms_get_entry_attr_args *args, struct svc_req *svcrq)
709 static cms_get_entry_attr_res res;
715 fprintf(stderr, "cms_get_entry_attr_5_svc called\n");
718 _DtCmsFreeEntryAttrResItem(res.entries);
722 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
723 &access, &cal)) != CSA_SUCCESS)
726 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
727 !_DTCMS_HAS_VIEW_ACCESS(access)) {
728 res.stat = CSA_E_NO_AUTHORITY;
733 if (args->num_keys == 0) {
734 res.stat = CSA_E_INVALID_PARAMETER;
738 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
739 res.stat = _DtCmsLookupEntriesByKey(cal, user, access,
740 args->num_keys, args->keys, args->num_names,
741 args->names, &res.entries);
743 res.stat = CSA_E_NOT_SUPPORTED;
749 extern cms_entry_res *
750 cms_insert_entry_5_svc(cms_insert_args *args, struct svc_req *svcrq)
752 static cms_entry_res res;
757 uint access, needaccess;
761 fprintf(stderr, "cms_insert_entry_5_svc called\n");
763 if (res.entry != NULL) {
764 res.entry->num_attrs--;
765 _DtCm_free_cms_entry(res.entry);
769 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
770 &access, &cal)) != CSA_SUCCESS)
773 if ((cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
774 !_DTCMS_HAS_INSERT_ACCESS(access)) ||
775 (cal->fversion < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
776 !_DTCMS_HAS_V4_WRITE_ACCESS(access))) {
777 res.stat = CSA_E_NO_AUTHORITY;
782 if (args->cal == NULL || args->num_attrs == 0) {
783 res.stat = CSA_E_INVALID_PARAMETER;
787 /* check validity of attribute values */
788 if ((res.stat = _DtCm_check_entry_cms_attributes(
789 (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ?
790 cal->fversion : _DtCM_FIRST_EXTENSIBLE_DATA_VERSION - 1),
791 args->num_attrs, args->attrs, CSA_CB_ENTRY_ADDED, B_TRUE))
795 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
796 if ((res.stat = _DtCmsMakeHashedEntry(cal, args->num_attrs,
797 args->attrs, &entry)) != CSA_SUCCESS)
800 if ((res.stat = _DtCmsCheckInitialAttributes(entry))
802 _DtCm_free_cms_entry(entry);
806 /* check access rights */
807 needaccess = _DtCmsClassToInsertAccess(entry);
808 if ((access & (CSA_OWNER_RIGHTS | needaccess)) == 0) {
809 _DtCm_free_cms_entry(entry);
810 res.stat = CSA_E_NO_AUTHORITY;
815 if ((res.stat = _DtCm_set_string_attrval(user,
816 &entry->attrs[CSA_ENTRY_ATTR_ORGANIZER_I].value,
817 CSA_VALUE_CALENDAR_USER)) != CSA_SUCCESS) {
818 _DtCm_free_cms_entry(entry);
822 /* insert entry and log it */
823 if ((res.stat = _DtCmsInsertEntryAndLog(cal, entry))
825 _DtCm_free_cms_entry(entry);
831 if ((appt = _DtCm_make_appt4(B_TRUE)) == NULL) {
832 res.stat = CSA_E_INSUFFICIENT_MEMORY;
836 if ((res.stat = _DtCmsAttrsToAppt4(args->num_attrs,
837 args->attrs, appt, B_TRUE)) != CSA_SUCCESS) {
838 _DtCm_free_appt4(appt);
842 if (appt->author) free(appt->author);
843 if ((appt->author = strdup(user)) == NULL) {
844 _DtCm_free_appt4(appt);
849 * calculate the correct start day,
851 _DtCms_adjust_appt_startdate(appt);
853 if ((res.stat = _DtCmsInsertApptAndLog(cal, appt))
855 _DtCm_free_appt4(appt);
859 key.id = appt->appt_id.key;
860 key.time = appt->appt_id.tick;
863 if (res.stat == CSA_SUCCESS)
864 cal->modified = B_TRUE;
869 cal->rlist = _DtCmsDoV1CbForV4Data(cal->rlist, user, args->pid,
872 cal->rlist = _DtCmsDoInsertEntryCallback(cal->rlist, cal->calendar,
873 user, key.id, args->pid);
876 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ||
877 (cal->fversion < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
878 (res.stat = _DtCmsAppt4ToCmsentriesForClient(cal->calendar, appt,
879 &entry)) == CSA_SUCCESS)) {
881 res.stat = _DtCmsGetCmsEntryForClient(entry, &res.entry, B_FALSE);
883 _DtCm_free_cms_entry(entry);
889 extern cms_entry_res *
890 cms_update_entry_5_svc(cms_update_args *args, struct svc_req *svcrq)
892 static cms_entry_res res;
897 uint access, needaccess;
901 fprintf(stderr, "cms_update_entry_5_svc called\n");
903 if (res.entry != NULL) {
904 res.entry->num_attrs--;
905 _DtCm_free_cms_entry(res.entry);
909 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
910 &access, &cal)) != CSA_SUCCESS)
913 if ((cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
914 !_DTCMS_HAS_CHANGE_ACCESS(access)) ||
915 (cal->fversion < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
916 !_DTCMS_HAS_V4_WRITE_ACCESS(access))) {
917 res.stat = CSA_E_NO_AUTHORITY;
922 if (args->cal == NULL || args->entry.id <= 0 || args->num_attrs == 0) {
923 res.stat = CSA_E_INVALID_PARAMETER;
927 if (args->scope < CSA_SCOPE_ALL || args->scope > CSA_SCOPE_FORWARD) {
928 res.stat = CSA_E_INVALID_ENUM;
932 /* check validity of attribute values */
933 if ((res.stat = _DtCm_check_entry_cms_attributes(
934 (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ?
935 cal->fversion : _DtCM_FIRST_EXTENSIBLE_DATA_VERSION - 1),
936 args->num_attrs, args->attrs, CSA_CB_ENTRY_UPDATED, B_TRUE))
940 /* get event from one-time event tree */
941 event = (caddr_t)rb_lookup(cal->tree, (caddr_t)&args->entry);
943 /* update entry and log it */
944 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
945 if (event != NULL || args->scope == CSA_SCOPE_ALL) {
946 res.stat = _DtCmsUpdateEntry(cal, user, access,
947 &args->entry, args->num_attrs,
948 args->attrs, NULL, &newentry);
950 res.stat = _DtCmsUpdateInstances(cal, user, access,
951 &args->entry, args->scope,
952 args->num_attrs, args->attrs, NULL,
958 if (event != NULL || args->scope == CSA_SCOPE_ALL)
961 opt = (args->scope == CSA_SCOPE_ONE) ?
962 do_one_4 : do_forward_4;
964 if (event == NULL && (event = hc_lookup(cal->list,
965 (caddr_t)&args->entry)) == NULL) {
967 res.stat = CSA_X_DT_E_ENTRY_NOT_FOUND;
969 } else if ((appt = _DtCm_copy_one_appt4((Appt_4 *)event))
972 res.stat = CSA_E_INSUFFICIENT_MEMORY;
975 /* get rid of exceptions */
976 _DtCm_free_excpt4(appt->exception);
977 appt->exception = NULL;
979 if ((res.stat = _DtCmsAttrsToAppt4(args->num_attrs,
980 args->attrs, appt, B_TRUE)) == CSA_SUCCESS) {
983 res.stat = _DtCmsChangeAll(cal, user,
984 access, (Id_4 *)&args->entry,
987 res.stat = _DtCmsChangeSome(cal, user,
988 access, (Id_4 *)&args->entry,
995 if (res.stat == CSA_SUCCESS)
996 cal->modified = B_TRUE;
1001 cal->rlist = _DtCmsDoV1CbForV4Data(cal->rlist, user, args->pid,
1003 (appt ? (cms_key *)&appt->appt_id : &newentry->key));
1005 cal->rlist = _DtCmsDoUpdateEntryCallback(cal->rlist, cal->calendar,
1006 user, (appt ? appt->appt_id.key : newentry->key.id),
1007 args->entry.id, args->scope, args->entry.time,
1011 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ||
1012 (cal->fversion < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
1013 (res.stat = _DtCmsAppt4ToCmsentriesForClient(cal->calendar, appt,
1014 &newentry)) == CSA_SUCCESS)) {
1016 res.stat = _DtCmsGetCmsEntryForClient(newentry, &res.entry, B_FALSE);
1018 _DtCm_free_cms_entry(newentry);
1024 extern CSA_return_code *
1025 cms_delete_entry_5_svc(cms_delete_args *args, struct svc_req *svcrq)
1027 static CSA_return_code res;
1028 _DtCmsCalendar *cal;
1031 uint access, needaccess;
1034 fprintf(stderr, "cms_delete_entry_5_svc called\n");
1036 if ((res = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
1037 &access, &cal)) != CSA_SUCCESS)
1040 /* for v3 data, authority check is done in the routines doing the
1041 * deletion since we may need to check the organizer
1043 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
1044 !_DTCMS_HAS_CHANGE_ACCESS(access)) {
1045 res = CSA_E_NO_AUTHORITY;
1049 /* check argument */
1050 if (args->cal == NULL || args->entry.id <= 0) {
1051 res = CSA_E_INVALID_PARAMETER;
1055 if (args->scope < CSA_SCOPE_ALL || args->scope > CSA_SCOPE_FORWARD) {
1056 res = CSA_E_INVALID_ENUM;
1061 /* get event from one-time event tree */
1062 event = (caddr_t)rb_lookup(cal->tree, (caddr_t)&args->entry);
1064 /* delete entry and log it */
1065 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
1066 if (event != NULL || args->scope == CSA_SCOPE_ALL) {
1067 res = _DtCmsDeleteEntryAndLog(cal, user, access,
1068 &args->entry, NULL);
1070 res = _DtCmsDeleteInstancesAndLog(cal, user, access,
1071 &args->entry, args->scope, NULL, NULL);
1074 if (event != NULL || args->scope == CSA_SCOPE_ALL) {
1075 res = _DtCmsDeleteApptAndLog(cal, user, access,
1076 (Id_4 *)&args->entry, NULL);
1078 res = _DtCmsDeleteApptInstancesAndLog(cal, user, access,
1079 (Id_4 *)&args->entry,
1080 ((args->scope == CSA_SCOPE_ONE) ? do_one_4 :
1081 do_forward_4), NULL, NULL);
1085 if (res == CSA_SUCCESS)
1086 cal->modified = B_TRUE;
1091 cal->rlist = _DtCmsDoV1CbForV4Data(cal->rlist, user, args->pid,
1092 &args->entry, NULL);
1094 cal->rlist = _DtCmsDoDeleteEntryCallback(cal->rlist, cal->calendar,
1095 user, args->entry.id, args->scope, args->entry.time,
1102 void initfunctable(program_handle ph)
1104 ph->program_num = TABLEPROG;
1105 ph->prog[TABLEVERS].vers = &tableprog_5_table[0];
1106 ph->prog[TABLEVERS].nproc = sizeof(tableprog_5_table)/sizeof(tableprog_5_table[0]);
1109 /*****************************************************************************
1110 * static functions used within the file
1111 *****************************************************************************/
1113 static CSA_return_code
1114 _DtCmsCreateCallog(char *user, cms_create_args *args, _DtCmsCalendar **newcal)
1116 CSA_return_code stat;
1117 _DtCmsCalendar *cal;
1123 cms_attribute_value val;
1124 cms_access_entry aentry;
1125 int nidx = 0, oidx = 0;
1129 * if calendar name is a user name, make sure that
1130 * it's the same as the sender.
1132 calname = _DtCmGetPrefix(args->cal, '@');
1133 username = _DtCmGetPrefix(user, '@');
1135 if (_DtCmIsUserName(calname) && strcmp(calname, username)) {
1138 return (CSA_E_NO_AUTHORITY);
1140 log = _DtCmsGetLogFN(calname);
1144 /* create internal calendar data structure */
1145 if ((cal = _DtCmsMakeCalendar(user, args->cal)) == NULL) {
1147 return (CSA_E_INSUFFICIENT_MEMORY);
1150 /* fill in information */
1151 _csa_tick_to_iso8601(time(0), datestr);
1153 if ((stat = _DtCm_set_string_attrval(datestr,
1154 &cal->attrs[CSA_CAL_ATTR_DATE_CREATED_I].value,
1155 CSA_VALUE_DATE_TIME)) != CSA_SUCCESS) {
1156 _DtCmsFreeCalendar(cal);
1161 /* initialize access list to be "WORLD", VIEW_PUBLIC */
1162 aentry.user = WORLD;
1163 aentry.rights = CSA_VIEW_PUBLIC_ENTRIES;
1165 val.item.access_list_value = &aentry;
1166 val.type = CSA_VALUE_ACCESS_LIST;
1168 if ((stat = _DtCmUpdateAccessListAttrVal(&val,
1169 &cal->attrs[CSA_CAL_ATTR_ACCESS_LIST_I].value)) != CSA_SUCCESS) {
1170 _DtCmsFreeCalendar(cal);
1175 /* set product identifier */
1176 if ((stat = _DtCm_set_string_attrval(_DtCM_PRODUCT_IDENTIFIER,
1177 &cal->attrs[CSA_CAL_ATTR_PRODUCT_IDENTIFIER_I].value,
1178 CSA_VALUE_STRING)) != CSA_SUCCESS) {
1179 _DtCmsFreeCalendar(cal);
1184 /* set CSA version */
1185 if ((stat = _DtCm_set_string_attrval(_DtCM_SPEC_VERSION_SUPPORTED,
1186 &cal->attrs[CSA_CAL_ATTR_VERSION_I].value, CSA_VALUE_STRING))
1188 _DtCmsFreeCalendar(cal);
1193 /* we dont use the values specified by client */
1194 for (i = 0; i < args->num_attrs; i++) {
1195 if (strcmp(args->attrs[i].name.name,
1196 CSA_CAL_ATTR_CALENDAR_NAME) == 0) {
1198 name = args->attrs[i].name.name;
1199 args->attrs[i].name.name = NULL;
1200 } else if (strcmp(args->attrs[i].name.name,
1201 CSA_CAL_ATTR_CALENDAR_OWNER) == 0) {
1203 owner = args->attrs[i].name.name;
1204 args->attrs[i].name.name = NULL;
1208 /* initialize calendar attribute with info provided by caller */
1209 if ((stat = _DtCmUpdateAttributes(args->num_attrs, args->attrs,
1210 &cal->num_attrs, &cal->attrs, &cal->cal_tbl, B_TRUE,
1211 NULL, B_FALSE)) != CSA_SUCCESS) {
1212 _DtCmsFreeCalendar(cal);
1217 if (nidx) args->attrs[nidx].name.name = name;
1218 if (oidx) args->attrs[oidx].name.name = owner;
1220 /* use passed in char set if client does not supply one */
1221 if (cal->attrs[CSA_CAL_ATTR_CHARACTER_SET_I].value == NULL &&
1222 args->char_set && *args->char_set != NULL) {
1223 if ((stat = _DtCm_set_string_attrval(args->char_set,
1224 &cal->attrs[CSA_CAL_ATTR_CHARACTER_SET_I].value,
1225 CSA_VALUE_STRING)) != CSA_SUCCESS) {
1226 _DtCmsFreeCalendar(cal);
1233 if ((stat = _DtCmsCreateLogV2(user, log)) != CSA_SUCCESS) {
1234 _DtCmsFreeCalendar(cal);
1240 if ((stat = _DtCmsAppendCalAttrsByFN(log, cal->num_attrs, cal->attrs))
1244 _DtCmsFreeCalendar(cal);
1249 _DtCmsPutInCalList(cal);
1256 #define _NAME_INCREMENT 10
1258 static CSA_return_code
1259 _ListCalendarNames(uint *num_names, char ***names)
1261 uint num = 0, count = 0;
1262 char **names_r = NULL;
1266 if ((dirp = opendir(".")) == NULL)
1267 return (CSA_E_FAILURE);
1270 if ((dp = (struct dirent *)malloc(sizeof(struct dirent) + FILENAME_MAX))
1273 return (CSA_E_INSUFFICIENT_MEMORY);
1276 while (dp = readdir_r(dirp, dp)) {
1278 while (dp = readdir(dirp)) {
1280 if (strncmp(dp->d_name, "callog.", strlen("callog.")) == 0) {
1282 count += _NAME_INCREMENT;
1283 if ((names_r = (char **)_grow_char_array(
1284 names_r, sizeof(char *) * count,
1285 sizeof(char *) * (count + _NAME_INCREMENT)))
1292 return (CSA_E_INSUFFICIENT_MEMORY);
1295 if ((names_r[num++] = strdup(dp->d_name)) == NULL) {
1296 _free_char_array(num, names_r);
1298 return (CSA_E_INSUFFICIENT_MEMORY);
1306 } else if (count > 0)
1309 return (CSA_SUCCESS);
1313 _grow_char_array(void *ptr, uint oldcount, uint newcount)
1317 if (nptr = realloc(ptr, newcount)) {
1318 memset((void *)((char *)nptr + oldcount), NULL,
1319 newcount - oldcount);
1326 _free_char_array(uint num_elem, char **ptr)
1333 for (i = 0; i < num_elem; i++) {
1344 * This routine assumes that the attributes are hashed already
1346 static CSA_return_code
1347 _DtCmsGetOldCalAttrNames(
1348 _DtCmsCalendar *cal,
1350 cms_attr_name **names_r)
1352 CSA_return_code stat = CSA_SUCCESS;
1353 cms_attr_name *names;
1356 if ((names = (cms_attr_name *)calloc(1,
1357 sizeof(cms_attr_name)*_DtCM_OLD_CAL_ATTR_SIZE)) == NULL)
1358 return (CSA_E_INSUFFICIENT_MEMORY);
1360 for (i = 1, j = 0; i <= _DtCM_DEFINED_CAL_ATTR_SIZE; i++) {
1361 if ((_CSA_cal_attr_info[i].fst_vers > 0 &&
1362 _CSA_cal_attr_info[i].fst_vers <= cal->fversion)
1363 || i == CSA_CAL_ATTR_CALENDAR_SIZE_I) {
1364 if ((names[j].name =
1365 strdup(_CSA_calendar_attribute_names[i])) == NULL)
1367 _DtCmsFreeCmsAttrNames(j, names);
1368 return (CSA_E_INSUFFICIENT_MEMORY);
1379 return (CSA_SUCCESS);