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: calendar.c /main/1 1996/04/21 19:21:47 drk $ */
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 /*****************************************************************************
32 * Functions that manage the calendar data structures.
33 *****************************************************************************/
35 #include <EUSCompat.h>
53 /* linked list of calendar structure representing opened calendars */
54 Calendar *_DtCm_active_cal_list = NULL;
56 /******************************************************************************
57 * forward declaration of static functions used within the file
58 ******************************************************************************/
59 static CSA_return_code _get_owner_from_old_cal(Calendar *cal, char *buf);
60 static CSA_return_code _get_calendar_owner(Calendar *cal, uint num_names,
61 char **names, CSA_attribute *attr);
62 static CSA_return_code _get_calendar_name(Calendar *cal, CSA_attribute *attr);
63 static CSA_return_code _get_product_identifier(Calendar *cal,
65 static CSA_return_code _get_version_supported(Calendar *cal,
67 static CSA_return_code _get_server_version(Calendar *cal, CSA_attribute *attr);
68 static CSA_return_code _get_data_version(Calendar *cal, CSA_attribute *attr);
69 static CSA_return_code _get_access_list(Calendar *cal, uint num_names,
70 char ** names, CSA_attribute *attr);
71 static CSA_return_code _get_number_entries(Calendar *cal, uint num_names,
72 char ** names, CSA_attribute *attr);
74 /*****************************************************************************
75 * extern functions used in the library
76 *****************************************************************************/
79 * Allocate a calendar structure and initialize it with
80 * the location, and name of the calendar.
83 _DtCm_new_Calendar(const char *calendar)
90 if ((cal = (Calendar *)malloc(sizeof(Calendar))) == NULL)
93 memset((void *)cal, 0, sizeof(Calendar));
95 if ((cal->name = strdup(calendar)) == NULL) {
100 cal->location = strchr(cal->name, '@');
103 /* set up attribute array */
104 if ((cal->attrs = (cms_attribute *)calloc(1,
105 sizeof(cms_attribute) * (_DtCm_cal_name_tbl->size + 1))) == NULL) {
111 for (i = 1; i <= _DtCm_cal_name_tbl->size; i++) {
112 if ((cal->attrs[i].name.name =
113 strdup(_DtCm_cal_name_tbl->names[i])) == NULL) {
115 cal->num_attrs = i - 1;
116 _DtCm_free_Calendar(cal);
119 cal->attrs[i].name.num = i;
121 cal->num_attrs = _DtCm_cal_name_tbl->size;
123 if (_DtCm_active_cal_list == NULL) {
124 _DtCm_active_cal_list = cal;
129 cal->next = _DtCm_active_cal_list;
130 _DtCm_active_cal_list->prev = cal;
131 _DtCm_active_cal_list = cal;
134 cal->cal_tbl = _DtCm_cal_name_tbl;
135 cal->entry_tbl = _DtCm_entry_name_tbl;
137 cal->handle = (void *)cal;
143 * After freeing up memory pointed to by cal,
144 * put it in the free list.
147 _DtCm_free_Calendar(Calendar *cal)
149 _DtCmCallbackEntry *cb, *ptr;
151 /* remove from active list */
152 if (_DtCm_active_cal_list == cal)
153 _DtCm_active_cal_list = cal->next;
155 if (cal->prev != NULL)
156 cal->prev->next = cal->next;
158 if (cal->next != NULL)
159 cal->next->prev = cal->prev;
161 /* free up resources used by it */
162 if (cal->name) free(cal->name);
163 if (cal->ehead) _DtCm_free_libentries((_DtCm_libentry *)cal->ehead);
165 if (cal->cal_tbl != _DtCm_cal_name_tbl)
166 _DtCm_free_name_table(cal->cal_tbl);
168 if (cal->entry_tbl != _DtCm_entry_name_tbl)
169 _DtCm_free_name_table(cal->entry_tbl);
179 * no need to free attribute values now
180 * since the values are passed to client
182 * need to free attribute values if they
185 _DtCm_free_cms_attribute_values(cal->num_attrs, cal->attrs);
188 memset((void *)cal, '\0', sizeof(Calendar));
190 /* if no calendar is open, destroy rpc mapping */
191 if (_DtCm_active_cal_list == NULL)
192 _DtCm_destroy_agent();
196 * Given the calendar handle, return the internal calendar data structure.
199 _DtCm_get_Calendar(CSA_session_handle calhandle)
201 Calendar *cal = (Calendar *)calhandle;
203 if (cal == NULL || cal->handle != (void *)cal)
206 return ((Calendar *)calhandle);
210 * Add linked list of entry data structures to the calendar.
213 _DtCm_add_to_entry_list(Calendar *cal, caddr_t elist)
216 _DtCm_libentry *entries = (_DtCm_libentry *)elist;
221 if (cal->ehead == NULL)
224 ((_DtCm_libentry *)cal->etail)->next = entries;
225 entries->prev = (_DtCm_libentry *)cal->etail;
228 /* find tail of given entry list */
231 while (entries->next != NULL) {
233 entries->next->cal = cal;
234 entries = entries->next;
237 cal->etail = (caddr_t)entries;
240 _DtCm_count_entry_in_list(cal->ehead);
247 _DtCm_remove_from_entry_list(
252 _DtCm_libentry *ehead = (_DtCm_libentry *)head;
253 _DtCm_libentry *etail = (_DtCm_libentry *)tail;
255 if (ehead == NULL || tail == NULL)
258 if (ehead == (_DtCm_libentry *)cal->ehead)
259 cal->ehead = (caddr_t)etail->next;
261 if (etail == (_DtCm_libentry *)cal->etail)
262 cal->etail = (caddr_t)ehead->prev;
264 /* remove from list */
265 if (ehead->prev != NULL)
266 ehead->prev->next = etail->next;
268 if (etail->next != NULL)
269 etail->next->prev = ehead->prev;
271 etail->next = ehead->prev = NULL;
274 _DtCm_count_entry_in_list(cal->ehead);
279 _DtCm_reset_cal_attrs(Calendar *cal)
281 cal->got_attrs = B_FALSE;
285 * Assume good parameters. Caller should check before calling this.
287 extern CSA_return_code
288 _DtCm_list_old_cal_attr_names(
290 CSA_uint32 *num_names_r,
293 CSA_return_code stat;
294 char **names, buf[BUFSIZ];
297 if ((names = _DtCm_alloc_character_pointers(_DtCM_OLD_CAL_ATTR_SIZE))
299 return (CSA_E_INSUFFICIENT_MEMORY);
301 /* find out whether we know the owner of the calendar */
302 if ((stat = _get_owner_from_old_cal(cal, buf)) != CSA_SUCCESS) {
307 for (i = 1, j = 0; i <= _DtCM_DEFINED_CAL_ATTR_SIZE; i++) {
308 if (_CSA_cal_attr_info[i].fst_vers > 0 &&
309 _CSA_cal_attr_info[i].fst_vers <= cal->file_version) {
310 if (i == CSA_CAL_ATTR_CALENDAR_OWNER_I && *buf == '\0')
314 strdup(_CSA_calendar_attribute_names[i])) == NULL)
317 return (CSA_E_INSUFFICIENT_MEMORY);
326 return (CSA_SUCCESS);
329 extern CSA_return_code
330 _DtCm_get_all_cal_attrs(
332 CSA_uint32 *num_attrs,
333 CSA_attribute **attrs)
335 CSA_return_code stat;
337 CSA_attribute *attrs_r;
339 if (num_attrs == NULL || attrs == NULL)
340 return (CSA_E_INVALID_PARAMETER);
342 if (cal->rpc_version >= _DtCM_FIRST_EXTENSIBLE_SERVER_VERSION) {
343 if ((stat = _DtCm_rpc_get_cal_attrs(cal, 0, 0, NULL))
347 if ((attrs_r = _DtCm_alloc_attributes(cal->num_attrs)) == NULL)
348 return (CSA_E_INSUFFICIENT_MEMORY);
351 for (i = 1, j = 0; i <= cal->num_attrs; i++) {
352 if (cal->attrs[i].value != NULL) {
354 if ((stat = _DtCm_cms2csa_attribute(
355 cal->attrs[i], &attrs_r[j])) != CSA_SUCCESS)
367 return (CSA_SUCCESS);
369 return (_DtCm_get_cal_attrs_by_name(cal,
370 _DtCM_DEFINED_CAL_ATTR_SIZE + 1,
371 _CSA_calendar_attribute_names, num_attrs, attrs));
375 * If it's not found, the attribute value is set to NULL.
377 extern CSA_return_code
378 _DtCm_get_cal_attrs_by_name(
380 CSA_uint32 num_names,
381 CSA_attribute_reference *names,
382 CSA_uint32 *num_attrs,
383 CSA_attribute **attrs)
385 CSA_return_code stat = CSA_SUCCESS;
386 CSA_attribute *attrs_r;
389 if (num_attrs == 0 || attrs == NULL)
390 return (CSA_E_INVALID_PARAMETER);
393 if ((attrs_r = _DtCm_alloc_attributes(num_names)) == NULL)
394 return (CSA_E_INSUFFICIENT_MEMORY);
396 for (i = 0, j = 0; i < num_names; i++) {
397 if (names[i] == NULL)
400 index = _DtCm_get_index_from_table(cal->cal_tbl, names[i]);
403 case CSA_X_DT_CAL_ATTR_SERVER_VERSION_I:
405 stat = _get_server_version(cal, &attrs_r[j]);
408 case CSA_X_DT_CAL_ATTR_DATA_VERSION_I:
410 stat = _get_data_version(cal, &attrs_r[j]);
413 case CSA_CAL_ATTR_ACCESS_LIST_I:
415 stat = _get_access_list(cal, num_names, names,
419 case CSA_CAL_ATTR_NUMBER_ENTRIES_I:
421 stat = _get_number_entries(cal, num_names,
425 case CSA_CAL_ATTR_CALENDAR_NAME_I:
427 stat = _get_calendar_name(cal, &attrs_r[j]);
430 case CSA_CAL_ATTR_CALENDAR_OWNER_I:
432 stat = _get_calendar_owner(cal, num_names, names,
436 case CSA_CAL_ATTR_PRODUCT_IDENTIFIER_I:
438 stat = _get_product_identifier(cal, &attrs_r[j]);
441 case CSA_CAL_ATTR_VERSION_I:
443 stat = _get_version_supported(cal, &attrs_r[j]);
447 if (cal->rpc_version >=
448 _DtCM_FIRST_EXTENSIBLE_SERVER_VERSION)
450 if (cal->file_version <
451 _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
455 if (cal->got_attrs == B_FALSE &&
456 (stat = _DtCm_rpc_get_cal_attrs(cal, 0,
457 num_names, names)) == CSA_SUCCESS) {
458 /* there might by new attributes */
460 (index = _DtCm_get_index_from_table(
461 cal->cal_tbl, names[i])) == -1)
465 if (stat == CSA_SUCCESS &&
466 cal->attrs[index].value)
467 stat = _DtCm_cms2csa_attribute(
468 cal->attrs[index], &attrs_r[j]);
473 if (stat == CSA_SUCCESS) {
474 if (attrs_r[j].value != NULL)
491 return (CSA_SUCCESS);
495 * Debugging function - count the number of entries in the list and print it out
498 _DtCm_count_entry_in_list(caddr_t elist)
501 _DtCm_libentry *list;
503 for (i = 0, list = (_DtCm_libentry *)elist;
505 i++, list = list->next)
508 fprintf(stderr, "number of entries = %d\n", i);
511 /******************************************************************************
512 * static functions used within in the file
513 ******************************************************************************/
516 * owner should point to a buffer big enough to hold the owner name
517 * We test whether the calendar name is a user name, if so, the
518 * owner will be the same as the calendar name.
519 * Otherwise, we don't know the owner.
521 static CSA_return_code
522 _get_owner_from_old_cal(Calendar *cal, char *owner)
526 if ((calname = _DtCmGetPrefix(cal->name, '@')) == NULL)
527 return (CSA_E_INSUFFICIENT_MEMORY);
529 if (_DtCmIsUserName(calname) == B_TRUE)
530 strcpy(owner, calname);
535 return (CSA_SUCCESS);
538 static CSA_return_code
545 CSA_return_code stat;
546 CSA_attribute_value *val;
547 char *owner, buf[BUFSIZ];
549 if (cal->rpc_version >= _DtCM_FIRST_EXTENSIBLE_SERVER_VERSION) {
550 if (cal->got_attrs == B_FALSE) {
551 if ((stat = _DtCm_rpc_get_cal_attrs(cal, 0, num_names,
552 names)) != CSA_SUCCESS)
555 owner = cal->attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].value->\
558 if ((stat = _get_owner_from_old_cal(cal, buf)) != CSA_SUCCESS)
560 else if (*buf == '\0')
561 return (CSA_SUCCESS);
566 if (attr->name = strdup(CSA_CAL_ATTR_CALENDAR_OWNER)) {
567 if ((val = (CSA_attribute_value *)calloc(1,
568 sizeof(CSA_attribute_value))) == NULL) {
570 return (CSA_E_INSUFFICIENT_MEMORY);
573 val->type = CSA_VALUE_CALENDAR_USER;
575 if ((val->item.calendar_user_value = (CSA_calendar_user *)
576 calloc(1, sizeof(CSA_calendar_user))) == NULL) {
579 return (CSA_E_INSUFFICIENT_MEMORY);
582 if (val->item.calendar_user_value->user_name = strdup(owner)) {
584 return (CSA_SUCCESS);
586 free(val->item.calendar_user_value);
589 return (CSA_E_INSUFFICIENT_MEMORY);
592 return (CSA_E_INSUFFICIENT_MEMORY);
595 static CSA_return_code
596 _get_calendar_name(Calendar *cal, CSA_attribute *attr)
598 if (attr->name = strdup(CSA_CAL_ATTR_CALENDAR_NAME))
599 return (_DtCm_set_csa_string_attrval(cal->name, &attr->value,
602 return (CSA_E_INSUFFICIENT_MEMORY);
605 static CSA_return_code
606 _get_product_identifier(Calendar *cal, CSA_attribute *attr)
608 if (attr->name = strdup(CSA_CAL_ATTR_PRODUCT_IDENTIFIER))
609 return (_DtCm_set_csa_string_attrval(_DtCM_PRODUCT_IDENTIFIER,
610 &attr->value, CSA_VALUE_STRING));
612 return (CSA_E_INSUFFICIENT_MEMORY);
615 static CSA_return_code
616 _get_version_supported(Calendar *cal, CSA_attribute *attr)
618 if (attr->name = strdup(CSA_CAL_ATTR_VERSION))
619 return (_DtCm_set_csa_string_attrval(
620 _DtCM_SPEC_VERSION_SUPPORTED, &attr->value,
623 return (CSA_E_INSUFFICIENT_MEMORY);
626 static CSA_return_code
627 _get_server_version(Calendar *cal, CSA_attribute *attr)
629 if (attr->name = strdup(CSA_X_DT_CAL_ATTR_SERVER_VERSION))
630 return (_DtCm_set_csa_uint32_attrval(cal->rpc_version,
633 return (CSA_E_INSUFFICIENT_MEMORY);
636 static CSA_return_code
637 _get_data_version(Calendar *cal, CSA_attribute *attr)
639 if (attr->name = strdup(CSA_X_DT_CAL_ATTR_DATA_VERSION))
640 return (_DtCm_set_csa_uint32_attrval(cal->file_version,
643 return (CSA_E_INSUFFICIENT_MEMORY);
646 static CSA_return_code
653 CSA_return_code stat = CSA_SUCCESS;
655 if (cal->rpc_version < _DtCM_FIRST_EXTENSIBLE_SERVER_VERSION)
656 stat = _DtCm_rpc_get_cal_attrs(cal, CSA_CAL_ATTR_ACCESS_LIST_I,
658 else if (cal->got_attrs == B_FALSE)
659 stat = _DtCm_rpc_get_cal_attrs(cal, 0, num_names, names);
661 if (stat == CSA_SUCCESS)
662 stat = _DtCm_cms2csa_attribute(
663 cal->attrs[CSA_CAL_ATTR_ACCESS_LIST_I], attr);
668 static CSA_return_code
675 CSA_return_code stat = CSA_SUCCESS;
677 if (cal->rpc_version < _DtCM_FIRST_EXTENSIBLE_SERVER_VERSION)
678 stat = _DtCm_rpc_get_cal_attrs(cal,
679 CSA_CAL_ATTR_NUMBER_ENTRIES_I, 0, NULL);
680 else if (cal->got_attrs == B_FALSE)
681 stat = _DtCm_rpc_get_cal_attrs(cal, 0, num_names, names);
683 if (stat == CSA_SUCCESS)
684 stat = _DtCm_cms2csa_attribute(
685 cal->attrs[CSA_CAL_ATTR_NUMBER_ENTRIES_I], attr);