1 /* $XConsortium: calendar.c /main/1 1996/04/21 19:21:47 drk $ */
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.
9 /*****************************************************************************
10 * Functions that manage the calendar data structures.
11 *****************************************************************************/
13 #include <EUSCompat.h>
31 /* linked list of calendar structure representing opened calendars */
32 Calendar *_DtCm_active_cal_list = NULL;
34 /******************************************************************************
35 * forward declaration of static functions used within the file
36 ******************************************************************************/
37 static CSA_return_code _get_owner_from_old_cal(Calendar *cal, char *buf);
38 static CSA_return_code _get_calendar_owner(Calendar *cal, uint num_names,
39 char **names, CSA_attribute *attr);
40 static CSA_return_code _get_calendar_name(Calendar *cal, CSA_attribute *attr);
41 static CSA_return_code _get_product_identifier(Calendar *cal,
43 static CSA_return_code _get_version_supported(Calendar *cal,
45 static CSA_return_code _get_server_version(Calendar *cal, CSA_attribute *attr);
46 static CSA_return_code _get_data_version(Calendar *cal, CSA_attribute *attr);
47 static CSA_return_code _get_access_list(Calendar *cal, uint num_names,
48 char ** names, CSA_attribute *attr);
49 static CSA_return_code _get_number_entries(Calendar *cal, uint num_names,
50 char ** names, CSA_attribute *attr);
52 /*****************************************************************************
53 * extern functions used in the library
54 *****************************************************************************/
57 * Allocate a calendar structure and initialize it with
58 * the location, and name of the calendar.
61 _DtCm_new_Calendar(const char *calendar)
68 if ((cal = (Calendar *)malloc(sizeof(Calendar))) == NULL)
71 memset((void *)cal, NULL, sizeof(Calendar));
73 if ((cal->name = strdup(calendar)) == NULL) {
78 cal->location = strchr(cal->name, '@');
81 /* set up attribute array */
82 if ((cal->attrs = (cms_attribute *)calloc(1,
83 sizeof(cms_attribute) * (_DtCm_cal_name_tbl->size + 1))) == NULL) {
89 for (i = 1; i <= _DtCm_cal_name_tbl->size; i++) {
90 if ((cal->attrs[i].name.name =
91 strdup(_DtCm_cal_name_tbl->names[i])) == NULL) {
93 cal->num_attrs = i - 1;
94 _DtCm_free_Calendar(cal);
97 cal->attrs[i].name.num = i;
99 cal->num_attrs = _DtCm_cal_name_tbl->size;
101 if (_DtCm_active_cal_list == NULL) {
102 _DtCm_active_cal_list = cal;
107 cal->next = _DtCm_active_cal_list;
108 _DtCm_active_cal_list->prev = cal;
109 _DtCm_active_cal_list = cal;
112 cal->cal_tbl = _DtCm_cal_name_tbl;
113 cal->entry_tbl = _DtCm_entry_name_tbl;
115 cal->handle = (void *)cal;
121 * After freeing up memory pointed to by cal,
122 * put it in the free list.
125 _DtCm_free_Calendar(Calendar *cal)
127 _DtCmCallbackEntry *cb, *ptr;
129 /* remove from active list */
130 if (_DtCm_active_cal_list == cal)
131 _DtCm_active_cal_list = cal->next;
133 if (cal->prev != NULL)
134 cal->prev->next = cal->next;
136 if (cal->next != NULL)
137 cal->next->prev = cal->prev;
139 /* free up resources used by it */
140 if (cal->name) free(cal->name);
141 if (cal->ehead) _DtCm_free_libentries((_DtCm_libentry *)cal->ehead);
143 if (cal->cal_tbl != _DtCm_cal_name_tbl)
144 _DtCm_free_name_table(cal->cal_tbl);
146 if (cal->entry_tbl != _DtCm_entry_name_tbl)
147 _DtCm_free_name_table(cal->entry_tbl);
157 * no need to free attribute values now
158 * since the values are passed to client
160 * need to free attribute values if they
163 _DtCm_free_cms_attribute_values(cal->num_attrs, cal->attrs);
166 memset((void *)cal, '\0', sizeof(Calendar));
168 /* if no calendar is open, destroy rpc mapping */
169 if (_DtCm_active_cal_list == NULL)
170 _DtCm_destroy_agent();
174 * Given the calendar handle, return the internal calendar data structure.
177 _DtCm_get_Calendar(CSA_session_handle calhandle)
179 Calendar *cal = (Calendar *)calhandle;
181 if (cal == NULL || cal->handle != (void *)cal)
184 return ((Calendar *)calhandle);
188 * Add linked list of entry data structures to the calendar.
191 _DtCm_add_to_entry_list(Calendar *cal, caddr_t elist)
194 _DtCm_libentry *entries = (_DtCm_libentry *)elist;
199 if (cal->ehead == NULL)
202 ((_DtCm_libentry *)cal->etail)->next = entries;
203 entries->prev = (_DtCm_libentry *)cal->etail;
206 /* find tail of given entry list */
209 while (entries->next != NULL) {
211 entries->next->cal = cal;
212 entries = entries->next;
215 cal->etail = (caddr_t)entries;
218 _DtCm_count_entry_in_list(cal->ehead);
225 _DtCm_remove_from_entry_list(
230 _DtCm_libentry *ehead = (_DtCm_libentry *)head;
231 _DtCm_libentry *etail = (_DtCm_libentry *)tail;
233 if (ehead == NULL || tail == NULL)
236 if (ehead == (_DtCm_libentry *)cal->ehead)
237 cal->ehead = (caddr_t)etail->next;
239 if (etail == (_DtCm_libentry *)cal->etail)
240 cal->etail = (caddr_t)ehead->prev;
242 /* remove from list */
243 if (ehead->prev != NULL)
244 ehead->prev->next = etail->next;
246 if (etail->next != NULL)
247 etail->next->prev = ehead->prev;
249 etail->next = ehead->prev = NULL;
252 _DtCm_count_entry_in_list(cal->ehead);
257 _DtCm_reset_cal_attrs(Calendar *cal)
259 cal->got_attrs = B_FALSE;
263 * Assume good parameters. Caller should check before calling this.
265 extern CSA_return_code
266 _DtCm_list_old_cal_attr_names(
268 CSA_uint32 *num_names_r,
271 CSA_return_code stat;
272 char **names, buf[BUFSIZ];
275 if ((names = _DtCm_alloc_character_pointers(_DtCM_OLD_CAL_ATTR_SIZE))
277 return (CSA_E_INSUFFICIENT_MEMORY);
279 /* find out whether we know the owner of the calendar */
280 if ((stat = _get_owner_from_old_cal(cal, buf)) != CSA_SUCCESS)
283 for (i = 1, j = 0; i <= _DtCM_DEFINED_CAL_ATTR_SIZE; i++) {
284 if (_CSA_cal_attr_info[i].fst_vers > 0 &&
285 _CSA_cal_attr_info[i].fst_vers <= cal->file_version) {
286 if (i == CSA_CAL_ATTR_CALENDAR_OWNER_I && *buf == NULL)
290 strdup(_CSA_calendar_attribute_names[i])) == NULL)
293 return (CSA_E_INSUFFICIENT_MEMORY);
302 return (CSA_SUCCESS);
305 extern CSA_return_code
306 _DtCm_get_all_cal_attrs(
308 CSA_uint32 *num_attrs,
309 CSA_attribute **attrs)
311 CSA_return_code stat;
313 CSA_attribute *attrs_r;
315 if (num_attrs == NULL || attrs == NULL)
316 return (CSA_E_INVALID_PARAMETER);
318 if (cal->rpc_version >= _DtCM_FIRST_EXTENSIBLE_SERVER_VERSION) {
319 if ((stat = _DtCm_rpc_get_cal_attrs(cal, 0, 0, NULL))
323 if ((attrs_r = _DtCm_alloc_attributes(cal->num_attrs)) == NULL)
324 return (CSA_E_INSUFFICIENT_MEMORY);
327 for (i = 1, j = 0; i <= cal->num_attrs; i++) {
328 if (cal->attrs[i].value != NULL) {
330 if ((stat = _DtCm_cms2csa_attribute(
331 cal->attrs[i], &attrs_r[j])) != CSA_SUCCESS)
343 return (CSA_SUCCESS);
345 return (_DtCm_get_cal_attrs_by_name(cal,
346 _DtCM_DEFINED_CAL_ATTR_SIZE + 1,
347 _CSA_calendar_attribute_names, num_attrs, attrs));
351 * If it's not found, the attribute value is set to NULL.
353 extern CSA_return_code
354 _DtCm_get_cal_attrs_by_name(
356 CSA_uint32 num_names,
357 CSA_attribute_reference *names,
358 CSA_uint32 *num_attrs,
359 CSA_attribute **attrs)
361 CSA_return_code stat = CSA_SUCCESS;
362 CSA_attribute *attrs_r;
365 if (num_attrs == 0 || attrs == NULL)
366 return (CSA_E_INVALID_PARAMETER);
369 if ((attrs_r = _DtCm_alloc_attributes(num_names)) == NULL)
370 return (CSA_E_INSUFFICIENT_MEMORY);
372 for (i = 0, j = 0; i < num_names; i++) {
373 if (names[i] == NULL)
376 index = _DtCm_get_index_from_table(cal->cal_tbl, names[i]);
379 case CSA_X_DT_CAL_ATTR_SERVER_VERSION_I:
381 stat = _get_server_version(cal, &attrs_r[j]);
384 case CSA_X_DT_CAL_ATTR_DATA_VERSION_I:
386 stat = _get_data_version(cal, &attrs_r[j]);
389 case CSA_CAL_ATTR_ACCESS_LIST_I:
391 stat = _get_access_list(cal, num_names, names,
395 case CSA_CAL_ATTR_NUMBER_ENTRIES_I:
397 stat = _get_number_entries(cal, num_names,
401 case CSA_CAL_ATTR_CALENDAR_NAME_I:
403 stat = _get_calendar_name(cal, &attrs_r[j]);
406 case CSA_CAL_ATTR_CALENDAR_OWNER_I:
408 stat = _get_calendar_owner(cal, num_names, names,
412 case CSA_CAL_ATTR_PRODUCT_IDENTIFIER_I:
414 stat = _get_product_identifier(cal, &attrs_r[j]);
417 case CSA_CAL_ATTR_VERSION_I:
419 stat = _get_version_supported(cal, &attrs_r[j]);
423 if (cal->rpc_version >=
424 _DtCM_FIRST_EXTENSIBLE_SERVER_VERSION)
426 if (cal->file_version <
427 _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
431 if (cal->got_attrs == B_FALSE &&
432 (stat = _DtCm_rpc_get_cal_attrs(cal, 0,
433 num_names, names)) == CSA_SUCCESS) {
434 /* there might by new attributes */
436 (index = _DtCm_get_index_from_table(
437 cal->cal_tbl, names[i])) == -1)
441 if (stat == CSA_SUCCESS &&
442 cal->attrs[index].value)
443 stat = _DtCm_cms2csa_attribute(
444 cal->attrs[index], &attrs_r[j]);
449 if (stat == CSA_SUCCESS) {
450 if (attrs_r[j].value != NULL)
467 return (CSA_SUCCESS);
471 * Debugging function - count the number of entries in the list and print it out
474 _DtCm_count_entry_in_list(caddr_t elist)
477 _DtCm_libentry *list;
479 for (i = 0, list = (_DtCm_libentry *)elist;
481 i++, list = list->next)
484 fprintf(stderr, "number of entries = %d\n", i);
487 /******************************************************************************
488 * static functions used within in the file
489 ******************************************************************************/
492 * owner should point to a buffer big enough to hold the owner name
493 * We test whether the calendar name is a user name, if so, the
494 * owner will be the same as the calendar name.
495 * Otherwise, we don't know the owner.
497 static CSA_return_code
498 _get_owner_from_old_cal(Calendar *cal, char *owner)
502 if ((calname = _DtCmGetPrefix(cal->name, '@')) == NULL)
503 return (CSA_E_INSUFFICIENT_MEMORY);
505 if (_DtCmIsUserName(calname) == B_TRUE)
506 strcpy(owner, calname);
511 return (CSA_SUCCESS);
514 static CSA_return_code
521 CSA_return_code stat;
522 CSA_attribute_value *val;
523 char *owner, buf[BUFSIZ];
525 if (cal->rpc_version >= _DtCM_FIRST_EXTENSIBLE_SERVER_VERSION) {
526 if (cal->got_attrs == B_FALSE) {
527 if ((stat = _DtCm_rpc_get_cal_attrs(cal, 0, num_names,
528 names)) != CSA_SUCCESS)
531 owner = cal->attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].value->\
534 if ((stat = _get_owner_from_old_cal(cal, buf)) != CSA_SUCCESS)
536 else if (*buf == NULL)
537 return (CSA_SUCCESS);
542 if (attr->name = strdup(CSA_CAL_ATTR_CALENDAR_OWNER)) {
543 if ((val = (CSA_attribute_value *)calloc(1,
544 sizeof(CSA_attribute_value))) == NULL) {
546 return (CSA_E_INSUFFICIENT_MEMORY);
549 val->type = CSA_VALUE_CALENDAR_USER;
551 if ((val->item.calendar_user_value = (CSA_calendar_user *)
552 calloc(1, sizeof(CSA_calendar_user))) == NULL) {
555 return (CSA_E_INSUFFICIENT_MEMORY);
558 if (val->item.calendar_user_value->user_name = strdup(owner)) {
560 return (CSA_SUCCESS);
562 free(val->item.calendar_user_value);
565 return (CSA_E_INSUFFICIENT_MEMORY);
568 return (CSA_E_INSUFFICIENT_MEMORY);
571 static CSA_return_code
572 _get_calendar_name(Calendar *cal, CSA_attribute *attr)
574 if (attr->name = strdup(CSA_CAL_ATTR_CALENDAR_NAME))
575 return (_DtCm_set_csa_string_attrval(cal->name, &attr->value,
578 return (CSA_E_INSUFFICIENT_MEMORY);
581 static CSA_return_code
582 _get_product_identifier(Calendar *cal, CSA_attribute *attr)
584 if (attr->name = strdup(CSA_CAL_ATTR_PRODUCT_IDENTIFIER))
585 return (_DtCm_set_csa_string_attrval(_DtCM_PRODUCT_IDENTIFIER,
586 &attr->value, CSA_VALUE_STRING));
588 return (CSA_E_INSUFFICIENT_MEMORY);
591 static CSA_return_code
592 _get_version_supported(Calendar *cal, CSA_attribute *attr)
596 if (attr->name = strdup(CSA_CAL_ATTR_VERSION))
597 return (_DtCm_set_csa_string_attrval(
598 _DtCM_SPEC_VERSION_SUPPORTED, &attr->value,
601 return (CSA_E_INSUFFICIENT_MEMORY);
604 static CSA_return_code
605 _get_server_version(Calendar *cal, CSA_attribute *attr)
607 if (attr->name = strdup(CSA_X_DT_CAL_ATTR_SERVER_VERSION))
608 return (_DtCm_set_csa_uint32_attrval(cal->rpc_version,
611 return (CSA_E_INSUFFICIENT_MEMORY);
614 static CSA_return_code
615 _get_data_version(Calendar *cal, CSA_attribute *attr)
617 if (attr->name = strdup(CSA_X_DT_CAL_ATTR_DATA_VERSION))
618 return (_DtCm_set_csa_uint32_attrval(cal->file_version,
621 return (CSA_E_INSUFFICIENT_MEMORY);
624 static CSA_return_code
631 CSA_return_code stat = CSA_SUCCESS;
633 if (cal->rpc_version < _DtCM_FIRST_EXTENSIBLE_SERVER_VERSION)
634 stat = _DtCm_rpc_get_cal_attrs(cal, CSA_CAL_ATTR_ACCESS_LIST_I,
636 else if (cal->got_attrs == B_FALSE)
637 stat = _DtCm_rpc_get_cal_attrs(cal, 0, num_names, names);
639 if (stat == CSA_SUCCESS)
640 stat = _DtCm_cms2csa_attribute(
641 cal->attrs[CSA_CAL_ATTR_ACCESS_LIST_I], attr);
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,
657 CSA_CAL_ATTR_NUMBER_ENTRIES_I, 0, NULL);
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_NUMBER_ENTRIES_I], attr);