2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $XConsortium: cmsfunc.c /main/4 1995/11/09 12:42:12 rswiston $ */
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.
31 #include <EUSCompat.h>
38 #include <sys/resource.h>
46 #include "cmscalendar.h"
47 #include "updateattrs.h"
51 #include "rpcextras.h"
64 #include "convert4-5.h"
65 #include "convert5-4.h"
67 #include "cmsconvert.h"
71 /******************************************************************************
72 * forward declaration of static functions used within the file
73 ******************************************************************************/
75 static CSA_return_code _DtCmsCreateCallog(char *user, cms_create_args *args,
76 _DtCmsCalendar **cal);
77 static CSA_return_code _ListCalendarNames(uint *num_names, char ***names);
78 static void * _grow_char_array(void *ptr, uint oldcount, uint newcount);
79 static void _free_char_array(uint num_elem, char **ptr);
80 static CSA_return_code _DtCmsGetOldCalAttrNames(_DtCmsCalendar *cal,
81 uint *num_names_r, cms_attr_name **names_r);
83 /*****************************************************************************
84 * extern functions used in the library
85 *****************************************************************************/
88 cms_ping_5_svc(void *args, struct svc_req *svcrq)
91 fprintf(stderr, "cms_ping_5_svc called\n");
93 return(NULL); /* for RPC reply */
97 extern cms_list_calendars_res *
98 cms_list_calendars_5_svc(void *dummy, struct svc_req *svcrq)
100 static cms_list_calendars_res res;
103 fprintf(stderr, "cms_list_calendars_5_svc called\n");
105 if (res.num_names > 0) {
106 _free_char_array(res.num_names, res.names);
110 res.stat = _ListCalendarNames(&res.num_names, &res.names);
115 extern cms_open_res *
116 cms_open_calendar_5_svc(cms_open_args *args, struct svc_req *svcrq)
118 static cms_open_res res;
119 static char sversion[80];
124 fprintf(stderr, "cms_open_calendar_5_svc called\n");
126 if (res.num_attrs > 0) {
127 _DtCm_free_cms_attributes(res.num_attrs, res.attrs);
132 /* check parameter */
133 if (args->cal == NULL) {
134 res.stat = CSA_E_INVALID_PARAMETER;
138 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
139 &res.user_access, &cal)) == CSA_SUCCESS) {
141 res.svr_vers = TABLEVERS;
143 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
145 res.file_vers = cal->fversion;
148 /* old format data */
149 res.file_vers = _DtCM_FIRST_EXTENSIBLE_DATA_VERSION - 1;
152 /* return attribute names */
153 res.stat = _DtCmsGetAllCalAttrs(cal, &res.num_attrs,
154 &res.attrs, B_FALSE);
157 if (res.stat == CSA_SUCCESS) {
159 cal->rlist = _DtCmsDoOpenCalCallback(cal->rlist,
160 cal->calendar, user, args->pid);
167 extern CSA_return_code *
168 cms_create_calendar_5_svc(cms_create_args *args, struct svc_req *svcrq)
170 static CSA_return_code res;
175 fprintf(stderr, "cms_create_calendar_5_svc called\n");
177 /* check parameter */
178 if (args->cal == NULL) {
179 res = CSA_E_INVALID_PARAMETER;
183 /* need to check whether we know about the sender,
184 * if not, fail the request
186 if ((res = _DtCmsGetClientInfo(svcrq, &user)) != CSA_SUCCESS) {
190 if ((res = _DtCm_check_cal_cms_attributes(_DtCMS_VERSION4,
191 args->num_attrs, args->attrs, user, args->cal, B_TRUE, B_TRUE,
192 B_FALSE)) != CSA_SUCCESS)
195 if ((res = _DtCmsGetCalendarByName(args->cal, B_FALSE, &cal))
196 == CSA_SUCCESS && cal != NULL) {
198 res = CSA_E_CALENDAR_EXISTS;
202 /* create callog file for new calendar */
203 res = _DtCmsCreateCallog(user, args, &cal);
209 extern CSA_return_code *
210 cms_remove_calendar_5_svc(cms_remove_args *args, struct svc_req *svcrq)
212 static CSA_return_code res;
218 fprintf(stderr, "cms_remove_calendar_5_svc called\n");
220 if ((res = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
221 &access, &cal)) != CSA_SUCCESS)
224 if (!(access & CSA_OWNER_RIGHTS)) {
226 res = CSA_E_NO_AUTHORITY;
230 /* move callog.name file to calrm.name */
231 res = _DtCmsRemoveLog(cal->calendar, user);
233 if (res != CSA_SUCCESS)
237 cal->rlist = _DtCmsDoRemoveCalCallback(cal->rlist,
238 cal->calendar, user, args->pid);
240 /* free up internal structures */
241 _DtCmsFreeCalendar(cal);
247 extern CSA_return_code *
248 cms_register_5_svc(cms_register_args *args, struct svc_req *svcrq)
250 static CSA_return_code res;
253 _DtCmsRegistrationInfo *rinfo;
256 fprintf(stderr, "cms_register_5_svc called\n");
258 if (args->cal == NULL ||
259 args->update_type >= (CSA_CB_ENTRY_UPDATED << 1)) {
260 res = CSA_E_INVALID_PARAMETER;
264 if ((res = _DtCmsGetClientInfo(svcrq, &user)) != CSA_SUCCESS)
267 if ((res = _DtCmsGetCalendarByName(args->cal, B_TRUE, &cal))
271 if ((rinfo = _DtCmsGetRegistration(&(cal->rlist), user, args->prognum,
272 args->versnum, args->procnum, args->pid)) == NULL) {
273 /* this client has not registered */
275 if ((rinfo = _DtCmsMakeRegistrationInfo(user,
276 args->update_type, args->prognum, args->versnum,
277 args->procnum, args->pid)) == NULL) {
278 res = CSA_E_INSUFFICIENT_MEMORY;
282 /* put in the calendar's registration list */
283 rinfo->next = cal->rlist;
287 fprintf(stderr, "%s registered on %s, old types = %d\n",
288 user, args->cal, rinfo->types);
291 /* add new type to the registration */
292 rinfo->types = rinfo->types | args->update_type;
296 fprintf(stderr, "%s registered on %s, types = %d\n",
297 user, args->cal, rinfo->types);
304 extern CSA_return_code *
305 cms_unregister_5_svc(cms_register_args *args, struct svc_req *svcrq)
307 static CSA_return_code res;
310 _DtCmsRegistrationInfo *rinfo;
313 fprintf(stderr, "cms_unregister_5_svc called\n");
315 if (args->cal == NULL ||
316 args->update_type >= (CSA_CB_ENTRY_UPDATED << 1)) {
317 res = CSA_E_INVALID_PARAMETER;
321 if ((res = _DtCmsGetClientInfo(svcrq, &user)) != CSA_SUCCESS)
324 if ((res = _DtCmsGetCalendarByName(args->cal, B_FALSE, &cal))
328 if (cal == NULL || (rinfo = _DtCmsGetRegistration(&(cal->rlist), user,
329 args->prognum, args->versnum, args->procnum, args->pid)) == NULL) {
330 res = CSA_E_CALLBACK_NOT_REGISTERED;
334 /* update registration info */
336 fprintf(stderr, "%s registered on %s, old types = %d\n",
337 user, args->cal, rinfo->types);
340 /* registered bits are cleared, unregistered bits are ignored */
341 rinfo->types = (rinfo->types | args->update_type) ^ args->update_type;
344 fprintf(stderr, "%s unregistered types %d on %s, new types = %d\n",
345 user, args->update_type, args->cal, rinfo->types);
348 if (rinfo->types == 0) {
349 cal->rlist = _DtCmsRemoveRegistration(cal->rlist, rinfo);
356 extern cms_enumerate_calendar_attr_res *
357 cms_enumerate_calendar_attr_5_svc(buffer *args, struct svc_req *svcrq)
359 static cms_enumerate_calendar_attr_res res;
366 fprintf(stderr, "cms_enumerate_calendar_attr_5_svc called\n");
368 if (res.num_names > 0) {
369 _DtCmsFreeCmsAttrNames(res.num_names, res.names);
373 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, *args, &user,
374 &access, &cal)) != CSA_SUCCESS)
377 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
378 if (!_DTCMS_HAS_VIEW_CALENDAR_ATTR_ACCESS(access)) {
379 res.stat = CSA_E_NO_AUTHORITY;
383 res.stat = _DtCmsGetCalAttrNames(cal, &res.num_names,
386 res.stat = _DtCmsGetOldCalAttrNames(cal, &res.num_names,
393 extern cms_get_cal_attr_res *
394 cms_get_calendar_attr_5_svc(cms_get_cal_attr_args *args, struct svc_req *svcrq)
396 static cms_get_cal_attr_res res;
402 fprintf(stderr, "cms_get_calendar_attr_5_svc called\n");
404 if (res.num_attrs > 0) {
405 _DtCm_free_cms_attributes(res.num_attrs, res.attrs);
410 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
411 &access, &cal)) != CSA_SUCCESS)
414 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
415 !_DTCMS_HAS_VIEW_CALENDAR_ATTR_ACCESS(access)) {
416 res.stat = CSA_E_NO_AUTHORITY;
420 if (args->num_names > 0)
421 res.stat = _DtCmsGetCalAttrsByName(cal, args->num_names,
422 args->names, &res.num_attrs, &res.attrs);
424 res.stat = _DtCmsGetAllCalAttrs(cal, &res.num_attrs,
430 extern CSA_return_code *
431 cms_set_calendar_attr_5_svc(cms_set_cal_attr_args *args, struct svc_req *svcrq)
433 static CSA_return_code res;
439 fprintf(stderr, "cms_set_calendar_attr_5_svc called\n");
441 if ((res = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
442 &access, &cal)) != CSA_SUCCESS)
445 if ((cal->fversion < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
446 !(access & CSA_OWNER_RIGHTS)) ||
447 (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
448 !(access & (CSA_OWNER_RIGHTS | CSA_INSERT_CALENDAR_ATTRIBUTES |
449 CSA_CHANGE_CALENDAR_ATTRIBUTES)))) {
450 res = CSA_E_NO_AUTHORITY;
455 if (args->cal == NULL || args->num_attrs == 0) {
456 res = CSA_E_INVALID_PARAMETER;
460 /* check validity of attribute values */
461 if ((res = _DtCm_check_cal_cms_attributes(
462 (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ?
463 cal->fversion : _DtCM_FIRST_EXTENSIBLE_DATA_VERSION - 1),
464 args->num_attrs, args->attrs, NULL, NULL, B_TRUE, B_FALSE, B_TRUE))
468 if (cal->fversion >=_DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
469 if ((res = _DtCmsUpdateCalAttributesAndLog(cal, args->num_attrs,
470 args->attrs, access)) != CSA_SUCCESS)
476 Access_Entry_4 *v4list = NULL;
478 /* for old format file, the only settable calendar attribute
481 for (i = args->num_attrs - 1; i >= 0; i--) {
482 if (args->attrs[i].name.name)
486 if (args->attrs[i].value == NULL ||
487 args->attrs[i].value->item.access_list_value == NULL) {
488 res = _DtCmsSetV4AccessListAndLog(cal, NULL);
490 if ((res = _DtCmsCmsAccessToV4Access(
491 args->attrs[i].value->item.access_list_value,
492 &v4list)) == CSA_SUCCESS)
494 res = _DtCmsSetV4AccessListAndLog(cal, v4list);
499 if (res != CSA_SUCCESS)
504 cal->rlist = _DtCmsDoUpdateCalAttrsCallback(cal->rlist, cal->calendar,
505 user, args->num_attrs, args->attrs, args->pid);
513 extern cms_archive_res *
514 cms_archive_5_svc(cms_archive_args *args, struct svc_req *svcrq)
516 static cms_archive_res res;
519 fprintf(stderr, "cms_archive_5_svc called\n");
521 res.stat = CSA_E_NOT_SUPPORTED;
525 extern CSA_return_code *
526 cms_restore_5_svc(cms_restore_args *args, struct svc_req *svcrq)
528 static CSA_return_code res;
531 fprintf(stderr, "cms_restore_5_svc called\n");
533 res = CSA_E_NOT_SUPPORTED;
537 extern cms_reminder_res *
538 cms_lookup_reminder_5_svc(cms_reminder_args *args, struct svc_req *svcrq)
540 static cms_reminder_res res;
546 fprintf(stderr, "cms_lookup_reminder_5_svc called\n");
548 if (res.rems != NULL) {
549 _DtCmsFreeReminderRef(res.rems);
553 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
554 &access, &cal)) != CSA_SUCCESS)
557 if ((access & CSA_OWNER_RIGHTS) == 0) {
558 res.stat = CSA_E_NO_AUTHORITY;
562 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
563 res.stat = _DtCmsLookupReminder(cal->remq, args->tick,
564 args->num_names, args->names, &res.rems);
569 if ((res.stat = _DtCmsGetV4Reminders(cal, time(0), &v4rem,
570 &ids)) == CSA_SUCCESS) {
571 res.stat = _DtCmsV4ReminderToReminderRef(cal->calendar,
572 v4rem, ids, &res.rems);
573 _DtCm_free_reminder4(v4rem);
574 _DtCmsFreeEntryIds(ids);
581 extern cms_entries_res *
582 cms_lookup_entries_5_svc(cms_lookup_entries_args *args, struct svc_req *svcrq)
584 static cms_entries_res res;
588 time_t start1, start2, end1, end2;
591 boolean_t no_start_time_range, no_end_time_range;
593 cms_attribute *hattrs;
597 fprintf(stderr, "cms_lookup_entries_5_svc called\n");
600 _DtCm_free_cms_entries(res.entries);
604 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
605 &access, &cal)) != CSA_SUCCESS)
608 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
609 !_DTCMS_HAS_VIEW_ACCESS(access)) {
610 res.stat = CSA_E_NO_AUTHORITY;
615 if ((res.stat = _DtCm_check_operator(args->num_attrs, NULL,
616 args->attrs, args->ops)) != CSA_SUCCESS)
620 if ((res.stat = _DtCmHashCriteria(
621 cal->fversion < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ?
622 _DtCm_entry_name_tbl : cal->entry_tbl, args->num_attrs,
623 NULL, args->attrs, args->ops, &no_match, &no_start_time_range,
624 &no_end_time_range, &start1, &start2, &end1, &end2, &id,
625 &hnum, &hattrs, &hops)) == CSA_E_INVALID_ATTRIBUTE) {
627 /* attribute not defined in this calendar specified,
630 res.stat = CSA_SUCCESS;
633 } else if (res.stat != CSA_SUCCESS || no_match == B_TRUE)
637 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
639 res.stat = _DtCmsLookupEntriesById(cal, user, access,
640 no_start_time_range, no_end_time_range,
641 start1, start2, end1, end2, id, hnum,
642 hattrs, hops, &res.entries);
644 res.stat = _DtCmsLookupEntries(cal, user, access,
645 start1, start2, no_end_time_range,
646 end1, end2, hnum, hattrs, hops,
650 Appt_4 *appt = NULL;;
653 res.stat = _DtCmsLookupKeyrangeV4(cal, user, access,
654 no_start_time_range, no_end_time_range,
655 start1, start2, end1, end2, id,
656 _DtCm_match_one_appt, hnum, hattrs,
659 prange.key1 = start1;
660 prange.key2 = start2;
662 res.stat = _DtCmsLookupRangeV4(cal, user, access,
663 &prange, no_end_time_range, end1, end2,
664 _DtCm_match_one_appt, hnum,
665 hattrs, hops, &appt, NULL);
668 if (res.stat == CSA_SUCCESS && appt) {
669 res.stat = _DtCmsAppt4ToCmsentriesForClient(args->cal,
671 _DtCm_free_appt4(appt);
675 _DtCmFreeHashedArrays(hnum, hattrs, hops);
680 extern cms_entries_res *
681 cms_enumerate_sequence_5_svc(cms_enumerate_args *args, struct svc_req *svcrq)
683 static cms_entries_res res;
689 fprintf(stderr, "cms_enumerate_sequence_5_svc called\n");
692 _DtCm_free_cms_entries(res.entries);
696 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
697 &access, &cal)) != CSA_SUCCESS)
700 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
701 !_DTCMS_HAS_VIEW_ACCESS(access)) {
702 res.stat = CSA_E_NO_AUTHORITY;
707 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
708 res.stat = _DtCmsEnumerateSequenceById(cal, user, access,
709 B_FALSE, B_TRUE, args->start, args->end,
710 0, 0, args->id, 0, NULL, NULL, &res.entries);
714 res.stat = _DtCmsLookupKeyrangeV4(cal, user, access,
715 B_FALSE, B_TRUE, args->start, args->end,
716 0, 0, args->id, NULL, 0, NULL, NULL, &appt,
719 if (res.stat == CSA_SUCCESS && appt) {
720 res.stat = _DtCmsAppt4ToCmsentriesForClient(args->cal,
722 _DtCm_free_appt4(appt);
729 extern cms_get_entry_attr_res *
730 cms_get_entry_attr_5_svc(cms_get_entry_attr_args *args, struct svc_req *svcrq)
732 static cms_get_entry_attr_res res;
738 fprintf(stderr, "cms_get_entry_attr_5_svc called\n");
741 _DtCmsFreeEntryAttrResItem(res.entries);
745 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
746 &access, &cal)) != CSA_SUCCESS)
749 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
750 !_DTCMS_HAS_VIEW_ACCESS(access)) {
751 res.stat = CSA_E_NO_AUTHORITY;
756 if (args->num_keys == 0) {
757 res.stat = CSA_E_INVALID_PARAMETER;
761 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
762 res.stat = _DtCmsLookupEntriesByKey(cal, user, access,
763 args->num_keys, args->keys, args->num_names,
764 args->names, &res.entries);
766 res.stat = CSA_E_NOT_SUPPORTED;
772 extern cms_entry_res *
773 cms_insert_entry_5_svc(cms_insert_args *args, struct svc_req *svcrq)
775 static cms_entry_res res;
780 uint access, needaccess;
784 fprintf(stderr, "cms_insert_entry_5_svc called\n");
786 if (res.entry != NULL) {
787 res.entry->num_attrs--;
788 _DtCm_free_cms_entry(res.entry);
792 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
793 &access, &cal)) != CSA_SUCCESS)
796 if ((cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
797 !_DTCMS_HAS_INSERT_ACCESS(access)) ||
798 (cal->fversion < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
799 !_DTCMS_HAS_V4_WRITE_ACCESS(access))) {
800 res.stat = CSA_E_NO_AUTHORITY;
805 if (args->cal == NULL || args->num_attrs == 0) {
806 res.stat = CSA_E_INVALID_PARAMETER;
810 /* check validity of attribute values */
811 if ((res.stat = _DtCm_check_entry_cms_attributes(
812 (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ?
813 cal->fversion : _DtCM_FIRST_EXTENSIBLE_DATA_VERSION - 1),
814 args->num_attrs, args->attrs, CSA_CB_ENTRY_ADDED, B_TRUE))
818 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
819 if ((res.stat = _DtCmsMakeHashedEntry(cal, args->num_attrs,
820 args->attrs, &entry)) != CSA_SUCCESS)
823 if ((res.stat = _DtCmsCheckInitialAttributes(entry))
825 _DtCm_free_cms_entry(entry);
829 /* check access rights */
830 needaccess = _DtCmsClassToInsertAccess(entry);
831 if ((access & (CSA_OWNER_RIGHTS | needaccess)) == 0) {
832 _DtCm_free_cms_entry(entry);
833 res.stat = CSA_E_NO_AUTHORITY;
838 if ((res.stat = _DtCm_set_string_attrval(user,
839 &entry->attrs[CSA_ENTRY_ATTR_ORGANIZER_I].value,
840 CSA_VALUE_CALENDAR_USER)) != CSA_SUCCESS) {
841 _DtCm_free_cms_entry(entry);
845 /* insert entry and log it */
846 if ((res.stat = _DtCmsInsertEntryAndLog(cal, entry))
848 _DtCm_free_cms_entry(entry);
854 if ((appt = _DtCm_make_appt4(B_TRUE)) == NULL) {
855 res.stat = CSA_E_INSUFFICIENT_MEMORY;
859 if ((res.stat = _DtCmsAttrsToAppt4(args->num_attrs,
860 args->attrs, appt, B_TRUE)) != CSA_SUCCESS) {
861 _DtCm_free_appt4(appt);
865 if (appt->author) free(appt->author);
866 if ((appt->author = strdup(user)) == NULL) {
867 _DtCm_free_appt4(appt);
872 * calculate the correct start day,
874 _DtCms_adjust_appt_startdate(appt);
876 if ((res.stat = _DtCmsInsertApptAndLog(cal, appt))
878 _DtCm_free_appt4(appt);
882 key.id = appt->appt_id.key;
883 key.time = appt->appt_id.tick;
886 if (res.stat == CSA_SUCCESS)
887 cal->modified = B_TRUE;
892 cal->rlist = _DtCmsDoV1CbForV4Data(cal->rlist, user, args->pid,
895 cal->rlist = _DtCmsDoInsertEntryCallback(cal->rlist, cal->calendar,
896 user, key.id, args->pid);
899 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ||
900 (cal->fversion < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
901 (res.stat = _DtCmsAppt4ToCmsentriesForClient(cal->calendar, appt,
902 &entry)) == CSA_SUCCESS)) {
904 res.stat = _DtCmsGetCmsEntryForClient(entry, &res.entry, B_FALSE);
906 _DtCm_free_cms_entry(entry);
912 extern cms_entry_res *
913 cms_update_entry_5_svc(cms_update_args *args, struct svc_req *svcrq)
915 static cms_entry_res res;
920 uint access, needaccess;
924 fprintf(stderr, "cms_update_entry_5_svc called\n");
926 if (res.entry != NULL) {
927 res.entry->num_attrs--;
928 _DtCm_free_cms_entry(res.entry);
932 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
933 &access, &cal)) != CSA_SUCCESS)
936 if ((cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
937 !_DTCMS_HAS_CHANGE_ACCESS(access)) ||
938 (cal->fversion < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
939 !_DTCMS_HAS_V4_WRITE_ACCESS(access))) {
940 res.stat = CSA_E_NO_AUTHORITY;
945 if (args->cal == NULL || args->entry.id <= 0 || args->num_attrs == 0) {
946 res.stat = CSA_E_INVALID_PARAMETER;
950 if (args->scope < CSA_SCOPE_ALL || args->scope > CSA_SCOPE_FORWARD) {
951 res.stat = CSA_E_INVALID_ENUM;
955 /* check validity of attribute values */
956 if ((res.stat = _DtCm_check_entry_cms_attributes(
957 (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ?
958 cal->fversion : _DtCM_FIRST_EXTENSIBLE_DATA_VERSION - 1),
959 args->num_attrs, args->attrs, CSA_CB_ENTRY_UPDATED, B_TRUE))
963 /* get event from one-time event tree */
964 event = (caddr_t)rb_lookup(cal->tree, (caddr_t)&args->entry);
966 /* update entry and log it */
967 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
968 if (event != NULL || args->scope == CSA_SCOPE_ALL) {
969 res.stat = _DtCmsUpdateEntry(cal, user, access,
970 &args->entry, args->num_attrs,
971 args->attrs, NULL, &newentry);
973 res.stat = _DtCmsUpdateInstances(cal, user, access,
974 &args->entry, args->scope,
975 args->num_attrs, args->attrs, NULL,
981 if (event != NULL || args->scope == CSA_SCOPE_ALL)
984 opt = (args->scope == CSA_SCOPE_ONE) ?
985 do_one_4 : do_forward_4;
987 if (event == NULL && (event = hc_lookup(cal->list,
988 (caddr_t)&args->entry)) == NULL) {
990 res.stat = CSA_X_DT_E_ENTRY_NOT_FOUND;
992 } else if ((appt = _DtCm_copy_one_appt4((Appt_4 *)event))
995 res.stat = CSA_E_INSUFFICIENT_MEMORY;
998 /* get rid of exceptions */
999 _DtCm_free_excpt4(appt->exception);
1000 appt->exception = NULL;
1002 if ((res.stat = _DtCmsAttrsToAppt4(args->num_attrs,
1003 args->attrs, appt, B_TRUE)) == CSA_SUCCESS) {
1005 if (opt == do_all_4)
1006 res.stat = _DtCmsChangeAll(cal, user,
1007 access, (Id_4 *)&args->entry,
1010 res.stat = _DtCmsChangeSome(cal, user,
1011 access, (Id_4 *)&args->entry,
1018 if (res.stat == CSA_SUCCESS)
1019 cal->modified = B_TRUE;
1026 cal->rlist = _DtCmsDoV1CbForV4Data(cal->rlist, user, args->pid,
1028 (appt ? (cms_key *)&appt->appt_id : &newentry->key));
1030 cal->rlist = _DtCmsDoUpdateEntryCallback(cal->rlist, cal->calendar,
1031 user, (appt ? appt->appt_id.key : newentry->key.id),
1032 args->entry.id, args->scope, args->entry.time,
1038 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ||
1039 (cal->fversion < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
1040 (res.stat = _DtCmsAppt4ToCmsentriesForClient(cal->calendar, appt,
1041 &newentry)) == CSA_SUCCESS)) {
1043 res.stat = _DtCmsGetCmsEntryForClient(newentry, &res.entry, B_FALSE);
1045 _DtCm_free_cms_entry(newentry);
1051 extern CSA_return_code *
1052 cms_delete_entry_5_svc(cms_delete_args *args, struct svc_req *svcrq)
1054 static CSA_return_code res;
1055 _DtCmsCalendar *cal;
1058 uint access, needaccess;
1061 fprintf(stderr, "cms_delete_entry_5_svc called\n");
1063 if ((res = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
1064 &access, &cal)) != CSA_SUCCESS)
1067 /* for v3 data, authority check is done in the routines doing the
1068 * deletion since we may need to check the organizer
1070 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
1071 !_DTCMS_HAS_CHANGE_ACCESS(access)) {
1072 res = CSA_E_NO_AUTHORITY;
1076 /* check argument */
1077 if (args->cal == NULL || args->entry.id <= 0) {
1078 res = CSA_E_INVALID_PARAMETER;
1082 if (args->scope < CSA_SCOPE_ALL || args->scope > CSA_SCOPE_FORWARD) {
1083 res = CSA_E_INVALID_ENUM;
1088 /* get event from one-time event tree */
1089 event = (caddr_t)rb_lookup(cal->tree, (caddr_t)&args->entry);
1091 /* delete entry and log it */
1092 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
1093 if (event != NULL || args->scope == CSA_SCOPE_ALL) {
1094 res = _DtCmsDeleteEntryAndLog(cal, user, access,
1095 &args->entry, NULL);
1097 res = _DtCmsDeleteInstancesAndLog(cal, user, access,
1098 &args->entry, args->scope, NULL, NULL);
1101 if (event != NULL || args->scope == CSA_SCOPE_ALL) {
1102 res = _DtCmsDeleteApptAndLog(cal, user, access,
1103 (Id_4 *)&args->entry, NULL);
1105 res = _DtCmsDeleteApptInstancesAndLog(cal, user, access,
1106 (Id_4 *)&args->entry,
1107 ((args->scope == CSA_SCOPE_ONE) ? do_one_4 :
1108 do_forward_4), NULL, NULL);
1112 if (res == CSA_SUCCESS)
1113 cal->modified = B_TRUE;
1118 cal->rlist = _DtCmsDoV1CbForV4Data(cal->rlist, user, args->pid,
1119 &args->entry, NULL);
1121 cal->rlist = _DtCmsDoDeleteEntryCallback(cal->rlist, cal->calendar,
1122 user, args->entry.id, args->scope, args->entry.time,
1129 void initfunctable(program_handle ph)
1131 ph->program_num = TABLEPROG;
1132 ph->prog[TABLEVERS].vers = &tableprog_5_table[0];
1133 ph->prog[TABLEVERS].nproc = sizeof(tableprog_5_table)/sizeof(tableprog_5_table[0]);
1136 /*****************************************************************************
1137 * static functions used within the file
1138 *****************************************************************************/
1140 static CSA_return_code
1141 _DtCmsCreateCallog(char *user, cms_create_args *args, _DtCmsCalendar **newcal)
1143 CSA_return_code stat;
1144 _DtCmsCalendar *cal;
1150 cms_attribute_value val;
1151 cms_access_entry aentry;
1152 int nidx = 0, oidx = 0;
1156 * if calendar name is a user name, make sure that
1157 * it's the same as the sender.
1159 calname = _DtCmGetPrefix(args->cal, '@');
1160 username = _DtCmGetPrefix(user, '@');
1162 if (_DtCmIsUserName(calname) && strcmp(calname, username)) {
1165 return (CSA_E_NO_AUTHORITY);
1167 log = _DtCmsGetLogFN(calname);
1171 /* create internal calendar data structure */
1172 if ((cal = _DtCmsMakeCalendar(user, args->cal)) == NULL) {
1174 return (CSA_E_INSUFFICIENT_MEMORY);
1177 /* fill in information */
1178 _csa_tick_to_iso8601(time(0), datestr);
1180 if ((stat = _DtCm_set_string_attrval(datestr,
1181 &cal->attrs[CSA_CAL_ATTR_DATE_CREATED_I].value,
1182 CSA_VALUE_DATE_TIME)) != CSA_SUCCESS) {
1183 _DtCmsFreeCalendar(cal);
1188 /* initialize access list to be "WORLD", VIEW_PUBLIC */
1189 aentry.user = WORLD;
1190 aentry.rights = CSA_VIEW_PUBLIC_ENTRIES;
1192 val.item.access_list_value = &aentry;
1193 val.type = CSA_VALUE_ACCESS_LIST;
1195 if ((stat = _DtCmUpdateAccessListAttrVal(&val,
1196 &cal->attrs[CSA_CAL_ATTR_ACCESS_LIST_I].value)) != CSA_SUCCESS) {
1197 _DtCmsFreeCalendar(cal);
1202 /* set product identifier */
1203 if ((stat = _DtCm_set_string_attrval(_DtCM_PRODUCT_IDENTIFIER,
1204 &cal->attrs[CSA_CAL_ATTR_PRODUCT_IDENTIFIER_I].value,
1205 CSA_VALUE_STRING)) != CSA_SUCCESS) {
1206 _DtCmsFreeCalendar(cal);
1211 /* set CSA version */
1212 if ((stat = _DtCm_set_string_attrval(_DtCM_SPEC_VERSION_SUPPORTED,
1213 &cal->attrs[CSA_CAL_ATTR_VERSION_I].value, CSA_VALUE_STRING))
1215 _DtCmsFreeCalendar(cal);
1220 /* we don't use the values specified by client */
1221 for (i = 0; i < args->num_attrs; i++) {
1222 if (strcmp(args->attrs[i].name.name,
1223 CSA_CAL_ATTR_CALENDAR_NAME) == 0) {
1225 name = args->attrs[i].name.name;
1226 args->attrs[i].name.name = NULL;
1227 } else if (strcmp(args->attrs[i].name.name,
1228 CSA_CAL_ATTR_CALENDAR_OWNER) == 0) {
1230 owner = args->attrs[i].name.name;
1231 args->attrs[i].name.name = NULL;
1235 /* initialize calendar attribute with info provided by caller */
1236 if ((stat = _DtCmUpdateAttributes(args->num_attrs, args->attrs,
1237 &cal->num_attrs, &cal->attrs, &cal->cal_tbl, B_TRUE,
1238 NULL, B_FALSE)) != CSA_SUCCESS) {
1239 _DtCmsFreeCalendar(cal);
1244 if (nidx) args->attrs[nidx].name.name = name;
1245 if (oidx) args->attrs[oidx].name.name = owner;
1247 /* use passed in char set if client does not supply one */
1248 if (cal->attrs[CSA_CAL_ATTR_CHARACTER_SET_I].value == NULL &&
1249 args->char_set && *args->char_set != '\0') {
1250 if ((stat = _DtCm_set_string_attrval(args->char_set,
1251 &cal->attrs[CSA_CAL_ATTR_CHARACTER_SET_I].value,
1252 CSA_VALUE_STRING)) != CSA_SUCCESS) {
1253 _DtCmsFreeCalendar(cal);
1260 if ((stat = _DtCmsCreateLogV2(user, log)) != CSA_SUCCESS) {
1261 _DtCmsFreeCalendar(cal);
1267 if ((stat = _DtCmsAppendCalAttrsByFN(log, cal->num_attrs, cal->attrs))
1271 _DtCmsFreeCalendar(cal);
1276 _DtCmsPutInCalList(cal);
1283 #define _NAME_INCREMENT 10
1285 static CSA_return_code
1286 _ListCalendarNames(uint *num_names, char ***names)
1288 uint num = 0, count = 0;
1289 char **names_r = NULL;
1293 if ((dirp = opendir(".")) == NULL)
1294 return (CSA_E_FAILURE);
1297 if ((dp = (struct dirent *)malloc(sizeof(struct dirent) + FILENAME_MAX))
1300 return (CSA_E_INSUFFICIENT_MEMORY);
1303 while (dp = readdir_r(dirp, dp)) {
1305 while (dp = readdir(dirp)) {
1307 if (strncmp(dp->d_name, "callog.", strlen("callog.")) == 0) {
1309 count += _NAME_INCREMENT;
1310 if ((names_r = (char **)_grow_char_array(
1311 names_r, sizeof(char *) * count,
1312 sizeof(char *) * (count + _NAME_INCREMENT)))
1319 return (CSA_E_INSUFFICIENT_MEMORY);
1322 if ((names_r[num++] = strdup(dp->d_name)) == NULL) {
1323 _free_char_array(num, names_r);
1325 return (CSA_E_INSUFFICIENT_MEMORY);
1335 } else if (count > 0)
1338 return (CSA_SUCCESS);
1342 _grow_char_array(void *ptr, uint oldcount, uint newcount)
1346 if (nptr = realloc(ptr, newcount)) {
1347 memset((void *)((char *)nptr + oldcount), 0,
1348 newcount - oldcount);
1355 _free_char_array(uint num_elem, char **ptr)
1362 for (i = 0; i < num_elem; i++) {
1373 * This routine assumes that the attributes are hashed already
1375 static CSA_return_code
1376 _DtCmsGetOldCalAttrNames(
1377 _DtCmsCalendar *cal,
1379 cms_attr_name **names_r)
1381 CSA_return_code stat = CSA_SUCCESS;
1382 cms_attr_name *names;
1385 if ((names = (cms_attr_name *)calloc(1,
1386 sizeof(cms_attr_name)*_DtCM_OLD_CAL_ATTR_SIZE)) == NULL)
1387 return (CSA_E_INSUFFICIENT_MEMORY);
1389 for (i = 1, j = 0; i <= _DtCM_DEFINED_CAL_ATTR_SIZE; i++) {
1390 if ((_CSA_cal_attr_info[i].fst_vers > 0 &&
1391 _CSA_cal_attr_info[i].fst_vers <= cal->fversion)
1392 || i == CSA_CAL_ATTR_CALENDAR_SIZE_I) {
1393 if ((names[j].name =
1394 strdup(_CSA_calendar_attribute_names[i])) == NULL)
1396 _DtCmsFreeCmsAttrNames(j, names);
1397 return (CSA_E_INSUFFICIENT_MEMORY);
1408 return (CSA_SUCCESS);