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 librararies 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)
93 fprintf(stderr, "cms_ping_5_svc called\n");
95 return((void *)&dummy); /* for RPC reply */
99 extern cms_list_calendars_res *
100 cms_list_calendars_5_svc(void *dummy, struct svc_req *svcrq)
102 static cms_list_calendars_res res;
105 fprintf(stderr, "cms_list_calendars_5_svc called\n");
107 if (res.num_names > 0) {
108 _free_char_array(res.num_names, res.names);
112 res.stat = _ListCalendarNames(&res.num_names, &res.names);
117 extern cms_open_res *
118 cms_open_calendar_5_svc(cms_open_args *args, struct svc_req *svcrq)
120 static cms_open_res res;
121 static char sversion[80];
126 fprintf(stderr, "cms_open_calendar_5_svc called\n");
128 if (res.num_attrs > 0) {
129 _DtCm_free_cms_attributes(res.num_attrs, res.attrs);
134 /* check parameter */
135 if (args->cal == NULL) {
136 res.stat = CSA_E_INVALID_PARAMETER;
140 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
141 &res.user_access, &cal)) == CSA_SUCCESS) {
143 res.svr_vers = TABLEVERS;
145 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
147 res.file_vers = cal->fversion;
150 /* old format data */
151 res.file_vers = _DtCM_FIRST_EXTENSIBLE_DATA_VERSION - 1;
154 /* return attribute names */
155 res.stat = _DtCmsGetAllCalAttrs(cal, &res.num_attrs,
156 &res.attrs, B_FALSE);
159 if (res.stat == CSA_SUCCESS) {
161 cal->rlist = _DtCmsDoOpenCalCallback(cal->rlist,
162 cal->calendar, user, args->pid);
169 extern CSA_return_code *
170 cms_create_calendar_5_svc(cms_create_args *args, struct svc_req *svcrq)
172 static CSA_return_code res;
177 fprintf(stderr, "cms_create_calendar_5_svc called\n");
179 /* check parameter */
180 if (args->cal == NULL) {
181 res = CSA_E_INVALID_PARAMETER;
185 /* need to check whether we know about the sender,
186 * if not, fail the request
188 if ((res = _DtCmsGetClientInfo(svcrq, &user)) != CSA_SUCCESS) {
192 if ((res = _DtCm_check_cal_cms_attributes(_DtCMS_VERSION4,
193 args->num_attrs, args->attrs, user, args->cal, B_TRUE, B_TRUE,
194 B_FALSE)) != CSA_SUCCESS)
197 if ((res = _DtCmsGetCalendarByName(args->cal, B_FALSE, &cal))
198 == CSA_SUCCESS && cal != NULL) {
200 res = CSA_E_CALENDAR_EXISTS;
204 /* create callog file for new calendar */
205 res = _DtCmsCreateCallog(user, args, &cal);
211 extern CSA_return_code *
212 cms_remove_calendar_5_svc(cms_remove_args *args, struct svc_req *svcrq)
214 static CSA_return_code res;
220 fprintf(stderr, "cms_remove_calendar_5_svc called\n");
222 if ((res = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
223 &access, &cal)) != CSA_SUCCESS)
226 if (!(access & CSA_OWNER_RIGHTS)) {
228 res = CSA_E_NO_AUTHORITY;
232 /* move callog.name file to calrm.name */
233 res = _DtCmsRemoveLog(cal->calendar, user);
235 if (res != CSA_SUCCESS)
239 cal->rlist = _DtCmsDoRemoveCalCallback(cal->rlist,
240 cal->calendar, user, args->pid);
242 /* free up internal structures */
243 _DtCmsFreeCalendar(cal);
249 extern CSA_return_code *
250 cms_register_5_svc(cms_register_args *args, struct svc_req *svcrq)
252 static CSA_return_code res;
255 _DtCmsRegistrationInfo *rinfo;
258 fprintf(stderr, "cms_register_5_svc called\n");
260 if (args->cal == NULL ||
261 args->update_type >= (CSA_CB_ENTRY_UPDATED << 1)) {
262 res = CSA_E_INVALID_PARAMETER;
266 if ((res = _DtCmsGetClientInfo(svcrq, &user)) != CSA_SUCCESS)
269 if ((res = _DtCmsGetCalendarByName(args->cal, B_TRUE, &cal))
273 if ((rinfo = _DtCmsGetRegistration(&(cal->rlist), user, args->prognum,
274 args->versnum, args->procnum, args->pid)) == NULL) {
275 /* this client has not registered */
277 if ((rinfo = _DtCmsMakeRegistrationInfo(user,
278 args->update_type, args->prognum, args->versnum,
279 args->procnum, args->pid)) == NULL) {
280 res = CSA_E_INSUFFICIENT_MEMORY;
284 /* put in the calendar's registration list */
285 rinfo->next = cal->rlist;
289 fprintf(stderr, "%s registered on %s, old types = %d\n",
290 user, args->cal, rinfo->types);
293 /* add new type to the registration */
294 rinfo->types = rinfo->types | args->update_type;
298 fprintf(stderr, "%s registered on %s, types = %d\n",
299 user, args->cal, rinfo->types);
306 extern CSA_return_code *
307 cms_unregister_5_svc(cms_register_args *args, struct svc_req *svcrq)
309 static CSA_return_code res;
312 _DtCmsRegistrationInfo *rinfo;
315 fprintf(stderr, "cms_unregister_5_svc called\n");
317 if (args->cal == NULL ||
318 args->update_type >= (CSA_CB_ENTRY_UPDATED << 1)) {
319 res = CSA_E_INVALID_PARAMETER;
323 if ((res = _DtCmsGetClientInfo(svcrq, &user)) != CSA_SUCCESS)
326 if ((res = _DtCmsGetCalendarByName(args->cal, B_FALSE, &cal))
330 if (cal == NULL || (rinfo = _DtCmsGetRegistration(&(cal->rlist), user,
331 args->prognum, args->versnum, args->procnum, args->pid)) == NULL) {
332 res = CSA_E_CALLBACK_NOT_REGISTERED;
336 /* update registration info */
338 fprintf(stderr, "%s registered on %s, old types = %d\n",
339 user, args->cal, rinfo->types);
342 /* registered bits are cleared, unregistered bits are ignored */
343 rinfo->types = (rinfo->types | args->update_type) ^ args->update_type;
346 fprintf(stderr, "%s unregistered types %d on %s, new types = %d\n",
347 user, args->update_type, args->cal, rinfo->types);
350 if (rinfo->types == 0) {
351 cal->rlist = _DtCmsRemoveRegistration(cal->rlist, rinfo);
358 extern cms_enumerate_calendar_attr_res *
359 cms_enumerate_calendar_attr_5_svc(buffer *args, struct svc_req *svcrq)
361 static cms_enumerate_calendar_attr_res res;
368 fprintf(stderr, "cms_enumerate_calendar_attr_5_svc called\n");
370 if (res.num_names > 0) {
371 _DtCmsFreeCmsAttrNames(res.num_names, res.names);
375 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, *args, &user,
376 &access, &cal)) != CSA_SUCCESS)
379 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
380 if (!_DTCMS_HAS_VIEW_CALENDAR_ATTR_ACCESS(access)) {
381 res.stat = CSA_E_NO_AUTHORITY;
385 res.stat = _DtCmsGetCalAttrNames(cal, &res.num_names,
388 res.stat = _DtCmsGetOldCalAttrNames(cal, &res.num_names,
395 extern cms_get_cal_attr_res *
396 cms_get_calendar_attr_5_svc(cms_get_cal_attr_args *args, struct svc_req *svcrq)
398 static cms_get_cal_attr_res res;
404 fprintf(stderr, "cms_get_calendar_attr_5_svc called\n");
406 if (res.num_attrs > 0) {
407 _DtCm_free_cms_attributes(res.num_attrs, res.attrs);
412 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
413 &access, &cal)) != CSA_SUCCESS)
416 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
417 !_DTCMS_HAS_VIEW_CALENDAR_ATTR_ACCESS(access)) {
418 res.stat = CSA_E_NO_AUTHORITY;
422 if (args->num_names > 0)
423 res.stat = _DtCmsGetCalAttrsByName(cal, args->num_names,
424 args->names, &res.num_attrs, &res.attrs);
426 res.stat = _DtCmsGetAllCalAttrs(cal, &res.num_attrs,
432 extern CSA_return_code *
433 cms_set_calendar_attr_5_svc(cms_set_cal_attr_args *args, struct svc_req *svcrq)
435 static CSA_return_code res;
441 fprintf(stderr, "cms_set_calendar_attr_5_svc called\n");
443 if ((res = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
444 &access, &cal)) != CSA_SUCCESS)
447 if ((cal->fversion < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
448 !(access & CSA_OWNER_RIGHTS)) ||
449 (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
450 !(access & (CSA_OWNER_RIGHTS | CSA_INSERT_CALENDAR_ATTRIBUTES |
451 CSA_CHANGE_CALENDAR_ATTRIBUTES)))) {
452 res = CSA_E_NO_AUTHORITY;
457 if (args->cal == NULL || args->num_attrs == 0) {
458 res = CSA_E_INVALID_PARAMETER;
462 /* check validity of attribute values */
463 if ((res = _DtCm_check_cal_cms_attributes(
464 (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ?
465 cal->fversion : _DtCM_FIRST_EXTENSIBLE_DATA_VERSION - 1),
466 args->num_attrs, args->attrs, NULL, NULL, B_TRUE, B_FALSE, B_TRUE))
470 if (cal->fversion >=_DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
471 if ((res = _DtCmsUpdateCalAttributesAndLog(cal, args->num_attrs,
472 args->attrs, access)) != CSA_SUCCESS)
478 Access_Entry_4 *v4list;
480 /* for old format file, the only settable calendar attribute
483 for (i = args->num_attrs - 1; i >= 0; i--) {
484 if (args->attrs[i].name.name)
488 if (args->attrs[i].value == NULL ||
489 args->attrs[i].value->item.access_list_value == NULL) {
490 res = _DtCmsSetV4AccessListAndLog(cal, NULL);
492 if ((res = _DtCmsCmsAccessToV4Access(
493 args->attrs[i].value->item.access_list_value,
494 &v4list)) == CSA_SUCCESS)
495 res = _DtCmsSetV4AccessListAndLog(cal, v4list);
498 if (res != CSA_SUCCESS)
503 cal->rlist = _DtCmsDoUpdateCalAttrsCallback(cal->rlist, cal->calendar,
504 user, args->num_attrs, args->attrs, args->pid);
512 extern cms_archive_res *
513 cms_archive_5_svc(cms_archive_args *args, struct svc_req *svcrq)
515 static cms_archive_res res;
518 fprintf(stderr, "cms_archive_5_svc called\n");
520 res.stat = CSA_E_NOT_SUPPORTED;
524 extern CSA_return_code *
525 cms_restore_5_svc(cms_restore_args *args, struct svc_req *svcrq)
527 static CSA_return_code res;
530 fprintf(stderr, "cms_restore_5_svc called\n");
532 res = CSA_E_NOT_SUPPORTED;
536 extern cms_reminder_res *
537 cms_lookup_reminder_5_svc(cms_reminder_args *args, struct svc_req *svcrq)
539 static cms_reminder_res res;
545 fprintf(stderr, "cms_lookup_reminder_5_svc called\n");
547 if (res.rems != NULL) {
548 _DtCmsFreeReminderRef(res.rems);
552 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
553 &access, &cal)) != CSA_SUCCESS)
556 if ((access & CSA_OWNER_RIGHTS) == 0) {
557 res.stat = CSA_E_NO_AUTHORITY;
561 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
562 res.stat = _DtCmsLookupReminder(cal->remq, args->tick,
563 args->num_names, args->names, &res.rems);
568 if ((res.stat = _DtCmsGetV4Reminders(cal, time(0), &v4rem,
569 &ids)) == CSA_SUCCESS) {
570 res.stat = _DtCmsV4ReminderToReminderRef(cal->calendar,
571 v4rem, ids, &res.rems);
572 _DtCm_free_reminder4(v4rem);
573 _DtCmsFreeEntryIds(ids);
580 extern cms_entries_res *
581 cms_lookup_entries_5_svc(cms_lookup_entries_args *args, struct svc_req *svcrq)
583 static cms_entries_res res;
587 time_t start1, start2, end1, end2;
590 boolean_t no_start_time_range, no_end_time_range;
592 cms_attribute *hattrs;
596 fprintf(stderr, "cms_lookup_entries_5_svc called\n");
599 _DtCm_free_cms_entries(res.entries);
603 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
604 &access, &cal)) != CSA_SUCCESS)
607 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
608 !_DTCMS_HAS_VIEW_ACCESS(access)) {
609 res.stat = CSA_E_NO_AUTHORITY;
614 if ((res.stat = _DtCm_check_operator(args->num_attrs, NULL,
615 args->attrs, args->ops)) != CSA_SUCCESS)
619 if ((res.stat = _DtCmHashCriteria(
620 cal->fversion < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ?
621 _DtCm_entry_name_tbl : cal->entry_tbl, args->num_attrs,
622 NULL, args->attrs, args->ops, &no_match, &no_start_time_range,
623 &no_end_time_range, &start1, &start2, &end1, &end2, &id,
624 &hnum, &hattrs, &hops)) == CSA_E_INVALID_ATTRIBUTE) {
626 /* attribute not defined in this calendar specified,
629 res.stat = CSA_SUCCESS;
632 } else if (res.stat != CSA_SUCCESS || no_match == B_TRUE)
636 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
638 res.stat = _DtCmsLookupEntriesById(cal, user, access,
639 no_start_time_range, no_end_time_range,
640 start1, start2, end1, end2, id, hnum,
641 hattrs, hops, &res.entries);
643 res.stat = _DtCmsLookupEntries(cal, user, access,
644 start1, start2, no_end_time_range,
645 end1, end2, hnum, hattrs, hops,
649 Appt_4 *appt = NULL;;
652 res.stat = _DtCmsLookupKeyrangeV4(cal, user, access,
653 no_start_time_range, no_end_time_range,
654 start1, start2, end1, end2, id,
655 _DtCm_match_one_appt, hnum, hattrs,
658 prange.key1 = start1;
659 prange.key2 = start2;
661 res.stat = _DtCmsLookupRangeV4(cal, user, access,
662 &prange, no_end_time_range, end1, end2,
663 _DtCm_match_one_appt, hnum,
664 hattrs, hops, &appt, NULL);
667 if (res.stat == CSA_SUCCESS && appt) {
668 res.stat = _DtCmsAppt4ToCmsentriesForClient(args->cal,
670 _DtCm_free_appt4(appt);
674 _DtCmFreeHashedArrays(hnum, hattrs, hops);
679 extern cms_entries_res *
680 cms_enumerate_sequence_5_svc(cms_enumerate_args *args, struct svc_req *svcrq)
682 static cms_entries_res res;
688 fprintf(stderr, "cms_enumerate_sequence_5_svc called\n");
691 _DtCm_free_cms_entries(res.entries);
695 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
696 &access, &cal)) != CSA_SUCCESS)
699 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
700 !_DTCMS_HAS_VIEW_ACCESS(access)) {
701 res.stat = CSA_E_NO_AUTHORITY;
706 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
707 res.stat = _DtCmsEnumerateSequenceById(cal, user, access,
708 B_FALSE, B_TRUE, args->start, args->end,
709 0, 0, args->id, 0, NULL, NULL, &res.entries);
713 res.stat = _DtCmsLookupKeyrangeV4(cal, user, access,
714 B_FALSE, B_TRUE, args->start, args->end,
715 0, 0, args->id, NULL, 0, NULL, NULL, &appt,
718 if (res.stat == CSA_SUCCESS && appt) {
719 res.stat = _DtCmsAppt4ToCmsentriesForClient(args->cal,
721 _DtCm_free_appt4(appt);
728 extern cms_get_entry_attr_res *
729 cms_get_entry_attr_5_svc(cms_get_entry_attr_args *args, struct svc_req *svcrq)
731 static cms_get_entry_attr_res res;
737 fprintf(stderr, "cms_get_entry_attr_5_svc called\n");
740 _DtCmsFreeEntryAttrResItem(res.entries);
744 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
745 &access, &cal)) != CSA_SUCCESS)
748 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
749 !_DTCMS_HAS_VIEW_ACCESS(access)) {
750 res.stat = CSA_E_NO_AUTHORITY;
755 if (args->num_keys == 0) {
756 res.stat = CSA_E_INVALID_PARAMETER;
760 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
761 res.stat = _DtCmsLookupEntriesByKey(cal, user, access,
762 args->num_keys, args->keys, args->num_names,
763 args->names, &res.entries);
765 res.stat = CSA_E_NOT_SUPPORTED;
771 extern cms_entry_res *
772 cms_insert_entry_5_svc(cms_insert_args *args, struct svc_req *svcrq)
774 static cms_entry_res res;
779 uint access, needaccess;
783 fprintf(stderr, "cms_insert_entry_5_svc called\n");
785 if (res.entry != NULL) {
786 res.entry->num_attrs--;
787 _DtCm_free_cms_entry(res.entry);
791 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
792 &access, &cal)) != CSA_SUCCESS)
795 if ((cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
796 !_DTCMS_HAS_INSERT_ACCESS(access)) ||
797 (cal->fversion < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
798 !_DTCMS_HAS_V4_WRITE_ACCESS(access))) {
799 res.stat = CSA_E_NO_AUTHORITY;
804 if (args->cal == NULL || args->num_attrs == 0) {
805 res.stat = CSA_E_INVALID_PARAMETER;
809 /* check validity of attribute values */
810 if ((res.stat = _DtCm_check_entry_cms_attributes(
811 (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ?
812 cal->fversion : _DtCM_FIRST_EXTENSIBLE_DATA_VERSION - 1),
813 args->num_attrs, args->attrs, CSA_CB_ENTRY_ADDED, B_TRUE))
817 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
818 if ((res.stat = _DtCmsMakeHashedEntry(cal, args->num_attrs,
819 args->attrs, &entry)) != CSA_SUCCESS)
822 if ((res.stat = _DtCmsCheckInitialAttributes(entry))
824 _DtCm_free_cms_entry(entry);
828 /* check access rights */
829 needaccess = _DtCmsClassToInsertAccess(entry);
830 if ((access & (CSA_OWNER_RIGHTS | needaccess)) == 0) {
831 _DtCm_free_cms_entry(entry);
832 res.stat = CSA_E_NO_AUTHORITY;
837 if ((res.stat = _DtCm_set_string_attrval(user,
838 &entry->attrs[CSA_ENTRY_ATTR_ORGANIZER_I].value,
839 CSA_VALUE_CALENDAR_USER)) != CSA_SUCCESS) {
840 _DtCm_free_cms_entry(entry);
844 /* insert entry and log it */
845 if ((res.stat = _DtCmsInsertEntryAndLog(cal, entry))
847 _DtCm_free_cms_entry(entry);
853 if ((appt = _DtCm_make_appt4(B_TRUE)) == NULL) {
854 res.stat = CSA_E_INSUFFICIENT_MEMORY;
858 if ((res.stat = _DtCmsAttrsToAppt4(args->num_attrs,
859 args->attrs, appt, B_TRUE)) != CSA_SUCCESS) {
860 _DtCm_free_appt4(appt);
864 if (appt->author) free(appt->author);
865 if ((appt->author = strdup(user)) == NULL) {
866 _DtCm_free_appt4(appt);
871 * calculate the correct start day,
873 _DtCms_adjust_appt_startdate(appt);
875 if ((res.stat = _DtCmsInsertApptAndLog(cal, appt))
877 _DtCm_free_appt4(appt);
881 key.id = appt->appt_id.key;
882 key.time = appt->appt_id.tick;
885 if (res.stat == CSA_SUCCESS)
886 cal->modified = B_TRUE;
891 cal->rlist = _DtCmsDoV1CbForV4Data(cal->rlist, user, args->pid,
894 cal->rlist = _DtCmsDoInsertEntryCallback(cal->rlist, cal->calendar,
895 user, key.id, args->pid);
898 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ||
899 (cal->fversion < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
900 (res.stat = _DtCmsAppt4ToCmsentriesForClient(cal->calendar, appt,
901 &entry)) == CSA_SUCCESS)) {
903 res.stat = _DtCmsGetCmsEntryForClient(entry, &res.entry, B_FALSE);
905 _DtCm_free_cms_entry(entry);
911 extern cms_entry_res *
912 cms_update_entry_5_svc(cms_update_args *args, struct svc_req *svcrq)
914 static cms_entry_res res;
919 uint access, needaccess;
923 fprintf(stderr, "cms_update_entry_5_svc called\n");
925 if (res.entry != NULL) {
926 res.entry->num_attrs--;
927 _DtCm_free_cms_entry(res.entry);
931 if ((res.stat = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
932 &access, &cal)) != CSA_SUCCESS)
935 if ((cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
936 !_DTCMS_HAS_CHANGE_ACCESS(access)) ||
937 (cal->fversion < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
938 !_DTCMS_HAS_V4_WRITE_ACCESS(access))) {
939 res.stat = CSA_E_NO_AUTHORITY;
944 if (args->cal == NULL || args->entry.id <= 0 || args->num_attrs == 0) {
945 res.stat = CSA_E_INVALID_PARAMETER;
949 if (args->scope < CSA_SCOPE_ALL || args->scope > CSA_SCOPE_FORWARD) {
950 res.stat = CSA_E_INVALID_ENUM;
954 /* check validity of attribute values */
955 if ((res.stat = _DtCm_check_entry_cms_attributes(
956 (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ?
957 cal->fversion : _DtCM_FIRST_EXTENSIBLE_DATA_VERSION - 1),
958 args->num_attrs, args->attrs, CSA_CB_ENTRY_UPDATED, B_TRUE))
962 /* get event from one-time event tree */
963 event = (caddr_t)rb_lookup(cal->tree, (caddr_t)&args->entry);
965 /* update entry and log it */
966 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
967 if (event != NULL || args->scope == CSA_SCOPE_ALL) {
968 res.stat = _DtCmsUpdateEntry(cal, user, access,
969 &args->entry, args->num_attrs,
970 args->attrs, NULL, &newentry);
972 res.stat = _DtCmsUpdateInstances(cal, user, access,
973 &args->entry, args->scope,
974 args->num_attrs, args->attrs, NULL,
980 if (event != NULL || args->scope == CSA_SCOPE_ALL)
983 opt = (args->scope == CSA_SCOPE_ONE) ?
984 do_one_4 : do_forward_4;
986 if (event == NULL && (event = hc_lookup(cal->list,
987 (caddr_t)&args->entry)) == NULL) {
989 res.stat = CSA_X_DT_E_ENTRY_NOT_FOUND;
991 } else if ((appt = _DtCm_copy_one_appt4((Appt_4 *)event))
994 res.stat = CSA_E_INSUFFICIENT_MEMORY;
997 /* get rid of exceptions */
998 _DtCm_free_excpt4(appt->exception);
999 appt->exception = NULL;
1001 if ((res.stat = _DtCmsAttrsToAppt4(args->num_attrs,
1002 args->attrs, appt, B_TRUE)) == CSA_SUCCESS) {
1004 if (opt == do_all_4)
1005 res.stat = _DtCmsChangeAll(cal, user,
1006 access, (Id_4 *)&args->entry,
1009 res.stat = _DtCmsChangeSome(cal, user,
1010 access, (Id_4 *)&args->entry,
1017 if (res.stat == CSA_SUCCESS)
1018 cal->modified = B_TRUE;
1023 cal->rlist = _DtCmsDoV1CbForV4Data(cal->rlist, user, args->pid,
1025 (appt ? (cms_key *)&appt->appt_id : &newentry->key));
1027 cal->rlist = _DtCmsDoUpdateEntryCallback(cal->rlist, cal->calendar,
1028 user, (appt ? appt->appt_id.key : newentry->key.id),
1029 args->entry.id, args->scope, args->entry.time,
1033 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ||
1034 (cal->fversion < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
1035 (res.stat = _DtCmsAppt4ToCmsentriesForClient(cal->calendar, appt,
1036 &newentry)) == CSA_SUCCESS)) {
1038 res.stat = _DtCmsGetCmsEntryForClient(newentry, &res.entry, B_FALSE);
1040 _DtCm_free_cms_entry(newentry);
1046 extern CSA_return_code *
1047 cms_delete_entry_5_svc(cms_delete_args *args, struct svc_req *svcrq)
1049 static CSA_return_code res;
1050 _DtCmsCalendar *cal;
1053 uint access, needaccess;
1056 fprintf(stderr, "cms_delete_entry_5_svc called\n");
1058 if ((res = _DtCmsV5LoadAndCheckAccess(svcrq, args->cal, &user,
1059 &access, &cal)) != CSA_SUCCESS)
1062 /* for v3 data, authority check is done in the routines doing the
1063 * deletion since we may need to check the organizer
1065 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
1066 !_DTCMS_HAS_CHANGE_ACCESS(access)) {
1067 res = CSA_E_NO_AUTHORITY;
1071 /* check argument */
1072 if (args->cal == NULL || args->entry.id <= 0) {
1073 res = CSA_E_INVALID_PARAMETER;
1077 if (args->scope < CSA_SCOPE_ALL || args->scope > CSA_SCOPE_FORWARD) {
1078 res = CSA_E_INVALID_ENUM;
1083 /* get event from one-time event tree */
1084 event = (caddr_t)rb_lookup(cal->tree, (caddr_t)&args->entry);
1086 /* delete entry and log it */
1087 if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
1088 if (event != NULL || args->scope == CSA_SCOPE_ALL) {
1089 res = _DtCmsDeleteEntryAndLog(cal, user, access,
1090 &args->entry, NULL);
1092 res = _DtCmsDeleteInstancesAndLog(cal, user, access,
1093 &args->entry, args->scope, NULL, NULL);
1096 if (event != NULL || args->scope == CSA_SCOPE_ALL) {
1097 res = _DtCmsDeleteApptAndLog(cal, user, access,
1098 (Id_4 *)&args->entry, NULL);
1100 res = _DtCmsDeleteApptInstancesAndLog(cal, user, access,
1101 (Id_4 *)&args->entry,
1102 ((args->scope == CSA_SCOPE_ONE) ? do_one_4 :
1103 do_forward_4), NULL, NULL);
1107 if (res == CSA_SUCCESS)
1108 cal->modified = B_TRUE;
1113 cal->rlist = _DtCmsDoV1CbForV4Data(cal->rlist, user, args->pid,
1114 &args->entry, NULL);
1116 cal->rlist = _DtCmsDoDeleteEntryCallback(cal->rlist, cal->calendar,
1117 user, args->entry.id, args->scope, args->entry.time,
1124 void initfunctable(program_handle ph)
1126 ph->program_num = TABLEPROG;
1127 ph->prog[TABLEVERS].vers = &tableprog_5_table[0];
1128 ph->prog[TABLEVERS].nproc = sizeof(tableprog_5_table)/sizeof(tableprog_5_table[0]);
1131 /*****************************************************************************
1132 * static functions used within the file
1133 *****************************************************************************/
1135 static CSA_return_code
1136 _DtCmsCreateCallog(char *user, cms_create_args *args, _DtCmsCalendar **newcal)
1138 CSA_return_code stat;
1139 _DtCmsCalendar *cal;
1145 cms_attribute_value val;
1146 cms_access_entry aentry;
1147 int nidx = 0, oidx = 0;
1151 * if calendar name is a user name, make sure that
1152 * it's the same as the sender.
1154 calname = _DtCmGetPrefix(args->cal, '@');
1155 username = _DtCmGetPrefix(user, '@');
1157 if (_DtCmIsUserName(calname) && strcmp(calname, username)) {
1160 return (CSA_E_NO_AUTHORITY);
1162 log = _DtCmsGetLogFN(calname);
1166 /* create internal calendar data structure */
1167 if ((cal = _DtCmsMakeCalendar(user, args->cal)) == NULL) {
1169 return (CSA_E_INSUFFICIENT_MEMORY);
1172 /* fill in information */
1173 _csa_tick_to_iso8601(time(0), datestr);
1175 if ((stat = _DtCm_set_string_attrval(datestr,
1176 &cal->attrs[CSA_CAL_ATTR_DATE_CREATED_I].value,
1177 CSA_VALUE_DATE_TIME)) != CSA_SUCCESS) {
1178 _DtCmsFreeCalendar(cal);
1183 /* initialize access list to be "WORLD", VIEW_PUBLIC */
1184 aentry.user = WORLD;
1185 aentry.rights = CSA_VIEW_PUBLIC_ENTRIES;
1187 val.item.access_list_value = &aentry;
1188 val.type = CSA_VALUE_ACCESS_LIST;
1190 if ((stat = _DtCmUpdateAccessListAttrVal(&val,
1191 &cal->attrs[CSA_CAL_ATTR_ACCESS_LIST_I].value)) != CSA_SUCCESS) {
1192 _DtCmsFreeCalendar(cal);
1197 /* set product identifier */
1198 if ((stat = _DtCm_set_string_attrval(_DtCM_PRODUCT_IDENTIFIER,
1199 &cal->attrs[CSA_CAL_ATTR_PRODUCT_IDENTIFIER_I].value,
1200 CSA_VALUE_STRING)) != CSA_SUCCESS) {
1201 _DtCmsFreeCalendar(cal);
1206 /* set CSA version */
1207 if ((stat = _DtCm_set_string_attrval(_DtCM_SPEC_VERSION_SUPPORTED,
1208 &cal->attrs[CSA_CAL_ATTR_VERSION_I].value, CSA_VALUE_STRING))
1210 _DtCmsFreeCalendar(cal);
1215 /* we dont use the values specified by client */
1216 for (i = 0; i < args->num_attrs; i++) {
1217 if (strcmp(args->attrs[i].name.name,
1218 CSA_CAL_ATTR_CALENDAR_NAME) == 0) {
1220 name = args->attrs[i].name.name;
1221 args->attrs[i].name.name = NULL;
1222 } else if (strcmp(args->attrs[i].name.name,
1223 CSA_CAL_ATTR_CALENDAR_OWNER) == 0) {
1225 owner = args->attrs[i].name.name;
1226 args->attrs[i].name.name = NULL;
1230 /* initialize calendar attribute with info provided by caller */
1231 if ((stat = _DtCmUpdateAttributes(args->num_attrs, args->attrs,
1232 &cal->num_attrs, &cal->attrs, &cal->cal_tbl, B_TRUE,
1233 NULL, B_FALSE)) != CSA_SUCCESS) {
1234 _DtCmsFreeCalendar(cal);
1239 if (nidx) args->attrs[nidx].name.name = name;
1240 if (oidx) args->attrs[oidx].name.name = owner;
1242 /* use passed in char set if client does not supply one */
1243 if (cal->attrs[CSA_CAL_ATTR_CHARACTER_SET_I].value == NULL &&
1244 args->char_set && *args->char_set != NULL) {
1245 if ((stat = _DtCm_set_string_attrval(args->char_set,
1246 &cal->attrs[CSA_CAL_ATTR_CHARACTER_SET_I].value,
1247 CSA_VALUE_STRING)) != CSA_SUCCESS) {
1248 _DtCmsFreeCalendar(cal);
1255 if ((stat = _DtCmsCreateLogV2(user, log)) != CSA_SUCCESS) {
1256 _DtCmsFreeCalendar(cal);
1262 if ((stat = _DtCmsAppendCalAttrsByFN(log, cal->num_attrs, cal->attrs))
1266 _DtCmsFreeCalendar(cal);
1271 _DtCmsPutInCalList(cal);
1278 #define _NAME_INCREMENT 10
1280 static CSA_return_code
1281 _ListCalendarNames(uint *num_names, char ***names)
1283 uint num = 0, count = 0;
1284 char **names_r = NULL;
1288 if ((dirp = opendir(".")) == NULL)
1289 return (CSA_E_FAILURE);
1292 if ((dp = (struct dirent *)malloc(sizeof(struct dirent) + FILENAME_MAX))
1295 return (CSA_E_INSUFFICIENT_MEMORY);
1298 while (dp = readdir_r(dirp, dp)) {
1300 while (dp = readdir(dirp)) {
1302 if (strncmp(dp->d_name, "callog.", strlen("callog.")) == 0) {
1304 count += _NAME_INCREMENT;
1305 if ((names_r = (char **)_grow_char_array(
1306 names_r, sizeof(char *) * count,
1307 sizeof(char *) * (count + _NAME_INCREMENT)))
1314 return (CSA_E_INSUFFICIENT_MEMORY);
1317 if ((names_r[num++] = strdup(dp->d_name)) == NULL) {
1318 _free_char_array(num, names_r);
1320 return (CSA_E_INSUFFICIENT_MEMORY);
1328 } else if (count > 0)
1331 return (CSA_SUCCESS);
1335 _grow_char_array(void *ptr, uint oldcount, uint newcount)
1339 if (nptr = realloc(ptr, newcount)) {
1340 memset((void *)((char *)nptr + oldcount), NULL,
1341 newcount - oldcount);
1348 _free_char_array(uint num_elem, char **ptr)
1355 for (i = 0; i < num_elem; i++) {
1366 * This routine assumes that the attributes are hashed already
1368 static CSA_return_code
1369 _DtCmsGetOldCalAttrNames(
1370 _DtCmsCalendar *cal,
1372 cms_attr_name **names_r)
1374 CSA_return_code stat = CSA_SUCCESS;
1375 cms_attr_name *names;
1378 if ((names = (cms_attr_name *)calloc(1,
1379 sizeof(cms_attr_name)*_DtCM_OLD_CAL_ATTR_SIZE)) == NULL)
1380 return (CSA_E_INSUFFICIENT_MEMORY);
1382 for (i = 1, j = 0; i <= _DtCM_DEFINED_CAL_ATTR_SIZE; i++) {
1383 if ((_CSA_cal_attr_info[i].fst_vers > 0 &&
1384 _CSA_cal_attr_info[i].fst_vers <= cal->fversion)
1385 || i == CSA_CAL_ATTR_CALENDAR_SIZE_I) {
1386 if ((names[j].name =
1387 strdup(_CSA_calendar_attribute_names[i])) == NULL)
1389 _DtCmsFreeCmsAttrNames(j, names);
1390 return (CSA_E_INSUFFICIENT_MEMORY);
1401 return (CSA_SUCCESS);