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: entry.c /main/1 1996/04/21 19:23:10 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.
32 * Functions that manage the entry data structures.
35 #include <EUSCompat.h>
43 #include "convert4-5.h"
44 #include "convert5-4.h"
51 #include "updateattrs.h"
53 /******************************************************************************
54 * forward declaration of static functions used within the file
55 ******************************************************************************/
56 static CSA_return_code _CmsentryToLibentry(_DtCmNameTable **tbl, cms_entry *e,
57 _DtCm_libentry **entry_r);
59 /*****************************************************************************
60 * extern functions used in the library
61 *****************************************************************************/
64 * Given the entry handle, return the internal entry data structure.
66 extern _DtCm_libentry *
67 _DtCm_get_libentry(CSA_entry_handle entryhandle)
69 _DtCm_libentry *entry = (_DtCm_libentry *)entryhandle;
71 if (entry == NULL || entry->handle != (void *)entry)
77 extern CSA_return_code
78 _DtCm_make_libentry(cms_entry *e, _DtCm_libentry **entry_r)
81 CSA_return_code stat = CSA_SUCCESS;
84 return (CSA_E_INVALID_PARAMETER);
86 if ((ptr = (_DtCm_libentry *)calloc(1, sizeof(_DtCm_libentry)))
88 return (CSA_E_INSUFFICIENT_MEMORY);
91 if ((ptr->e = _DtCm_make_cms_entry(_DtCm_entry_name_tbl))
93 stat = CSA_E_INSUFFICIENT_MEMORY;
95 stat = _DtCm_copy_cms_entry(e, &ptr->e);
97 if (stat == CSA_SUCCESS) {
98 ptr->handle = (void *)ptr;
107 * Get entry data from the server.
109 extern CSA_return_code
110 _DtCm_get_entry_detail(_DtCm_libentry *entry)
112 CSA_return_code stat = CSA_SUCCESS;
114 if (entry->filled == B_FALSE)
115 return (_DtCm_rpc_lookup_entry_by_id(entry->cal, entry));
121 * return attribute names of all attributes.
122 * ** how to deal with
123 * - predefined attributes with null values
124 * - custom attributes
126 extern CSA_return_code
127 _DtCm_get_entry_attr_names(
128 _DtCm_libentry *entry,
129 CSA_uint32 *num_names_r,
138 if ((names = _DtCm_alloc_character_pointers(entry->e->num_attrs))
140 return (CSA_E_INSUFFICIENT_MEMORY);
142 /* first element in attr array is not used */
143 for (i = 1, j = 0; i <= entry->e->num_attrs; i++) {
144 /* there should not be any NULL names in the attr array */
145 if (entry->e->attrs[i].value != NULL) {
146 if ((names[j] = strdup(entry->e->attrs[i].name.name))
149 return (CSA_E_INSUFFICIENT_MEMORY);
158 return (CSA_SUCCESS);
161 extern CSA_return_code
162 _DtCm_get_all_entry_attrs(
163 _DtCm_libentry *entry,
164 CSA_uint32 *num_attrs,
165 CSA_attribute **attrs)
168 CSA_return_code stat = CSA_SUCCESS;
169 CSA_attribute *attrs_r;
171 if (num_attrs == NULL || attrs == NULL)
172 return (CSA_E_INVALID_PARAMETER);
174 if ((attrs_r = _DtCm_alloc_attributes(entry->e->num_attrs)) == NULL)
175 return (CSA_E_INSUFFICIENT_MEMORY);
177 /* first element in attr array is not used */
178 for (i = 1, j = 0; i <= entry->e->num_attrs; i++) {
179 if (entry->e->attrs[i].value != NULL) {
181 if ((stat = _DtCm_cms2csa_attribute(entry->e->attrs[i],
182 &attrs_r[j])) != CSA_SUCCESS) {
193 return (CSA_SUCCESS);
197 * Search the attribute list for the given attribute names.
198 * If it's not found, the attribute value
201 extern CSA_return_code
202 _DtCm_get_entry_attrs_by_name(
203 _DtCm_libentry *entry,
204 CSA_uint32 num_names,
205 CSA_attribute_reference *names,
206 CSA_uint32 *num_attrs,
207 CSA_attribute **attrs)
210 CSA_return_code stat = CSA_SUCCESS;
211 CSA_attribute *attrs_r;
213 if (num_attrs == NULL || attrs == NULL)
214 return (CSA_E_INVALID_PARAMETER);
216 if ((attrs_r = _DtCm_alloc_attributes(num_names)) == NULL)
217 return (CSA_E_INSUFFICIENT_MEMORY);
220 for (i = 0, j = 0; i < num_names; i++) {
221 if (names[i] != NULL) {
222 index = _DtCm_get_index_from_table(
223 entry->cal->entry_tbl, names[i]);
225 if (index >= 0 && entry->e->attrs[index].value) {
226 if (attrs_r[j].name =
227 strdup(entry->e->attrs[index].name.name))
229 stat = _DtCm_cms2csa_attrval(
230 entry->e->attrs[index].value,
233 stat = CSA_E_INSUFFICIENT_MEMORY;
235 if (stat != CSA_SUCCESS) {
247 return (CSA_SUCCESS);
251 * convert the linked list of entry structures to
252 * an array of entry handles.
254 extern CSA_return_code
255 _DtCm_libentry_to_entryh(
256 _DtCm_libentry *elist,
258 CSA_entry_handle **entries_r)
260 CSA_entry_handle *eh;
264 if (elist == NULL || size == NULL || entries_r == NULL)
265 return (CSA_E_INVALID_PARAMETER);
267 for (i = 0, ptr = elist; ptr != NULL; ptr = ptr->next)
270 if ((eh = _DtCm_alloc_entry_handles(i)) == NULL)
271 return (CSA_E_INSUFFICIENT_MEMORY);
273 for (j = 0; j < i; j++, elist = elist->next)
274 eh[j] = (CSA_entry_handle)elist;
279 return (CSA_SUCCESS);
282 extern CSA_return_code
283 _DtCmCmsentriesToLibentries(
284 _DtCmNameTable **tbl,
286 _DtCm_libentry **libentries)
288 CSA_return_code stat = CSA_SUCCESS;
289 _DtCm_libentry *entry, *head, *prev;
291 if (libentries == NULL)
292 return(CSA_E_INVALID_PARAMETER);
295 while (entries != NULL) {
297 if ((stat = _CmsentryToLibentry(tbl, entries, &entry))
310 entries = entries->next;
313 if (stat != CSA_SUCCESS) {
314 _DtCm_free_libentries(head);
322 extern CSA_return_code
323 _DtCm_appt4_to_libentries(
326 _DtCm_libentry **libentries)
328 CSA_return_code stat = CSA_SUCCESS;
329 _DtCm_libentry *entry, *head, *prev;
331 if (libentries == NULL)
332 return(CSA_E_INVALID_PARAMETER);
335 while (appt4 != NULL) {
337 if ((stat = _DtCm_make_libentry(NULL, &entry)) != CSA_SUCCESS)
340 if ((stat = _DtCm_appt4_to_attrs(calname, appt4,
341 entry->e->num_attrs, entry->e->attrs, B_FALSE))
345 entry->e->key.time = appt4->appt_id.tick;
346 entry->e->key.id = appt4->appt_id.key;
347 entry->filled = B_TRUE;
361 if (stat != CSA_SUCCESS) {
362 _DtCm_free_libentries(head);
370 extern CSA_return_code
371 _DtCm_libentries_to_appt4(_DtCm_libentry *entries, Appt_4 **appt4)
373 CSA_return_code stat = CSA_SUCCESS;
374 Appt_4 *a4, *head, *prev;
377 return(CSA_E_INVALID_PARAMETER);
380 while (entries != NULL) {
382 if ((stat = _DtCm_cms_entry_to_appt4(entries->e, &a4)) != CSA_SUCCESS)
393 entries = entries->next;
396 if (stat != CSA_SUCCESS) {
397 _DtCm_free_appt4(head);
405 extern CSA_return_code
406 _DtCm_reminder4_to_csareminder(
408 CSA_uint32 *num_rems,
409 CSA_reminder_reference **rems)
411 CSA_return_code stat = CSA_SUCCESS;
412 _DtCm_libentry *entry;
413 CSA_reminder_reference *rem_r;
415 Reminder_4 *rptr = r4;
416 char isotime[BUFSIZ];
418 if (num_rems == NULL || rems == NULL)
419 return(CSA_E_INVALID_PARAMETER);
424 return (CSA_SUCCESS);
427 for (count = 0, rptr = r4; rptr != NULL; count++, rptr = rptr->next)
430 if ((rem_r = _DtCm_alloc_reminder_references(count)) == NULL) {
431 return (CSA_E_INSUFFICIENT_MEMORY);
435 while (r4 != NULL && r4->attr.attr != NULL) {
437 (void)_csa_tick_to_iso8601(r4->tick, isotime);
438 if ((rem_r[i].run_time = strdup(isotime)) == NULL) {
439 stat = CSA_E_INSUFFICIENT_MEMORY;
443 if ((rem_r[i].attribute_name = strdup(
444 _DtCm_old_reminder_name_to_name(r4->attr.attr))) == NULL) {
445 stat = CSA_E_INSUFFICIENT_MEMORY;
449 if ((stat = _DtCm_make_libentry(NULL, &entry)) == CSA_SUCCESS) {
450 entry->e->key.id = r4->appt_id.key;
451 entry->e->key.time = r4->appt_id.tick;
452 rem_r[i].entry = (CSA_entry_handle)entry;
460 if (stat == CSA_SUCCESS) {
470 extern CSA_return_code
471 _DtCm_cms2csa_reminder_ref(
472 cms_reminder_ref *cmsrems,
473 CSA_uint32 *num_rems,
474 CSA_reminder_reference **csarems)
476 CSA_return_code stat = CSA_SUCCESS;
477 _DtCm_libentry *entry;
478 CSA_reminder_reference *rem_r;
479 cms_reminder_ref *rptr;
481 char isotime[BUFSIZ];
484 if (num_rems == NULL || csarems == NULL)
485 return(CSA_E_INVALID_PARAMETER);
487 if (cmsrems == NULL) {
490 return (CSA_SUCCESS);
493 for (count = 0, rptr = cmsrems; rptr != NULL; rptr = rptr->next)
496 if ((rem_r = _DtCm_alloc_reminder_references(count)) == NULL) {
497 return (CSA_E_INSUFFICIENT_MEMORY);
501 while (cmsrems != NULL && stat == CSA_SUCCESS) {
503 (void)_csa_tick_to_iso8601(cmsrems->runtime, isotime);
504 if ((rem_r[i].run_time = strdup(isotime)) == NULL) {
505 stat = CSA_E_INSUFFICIENT_MEMORY;
509 if ((rem_r[i].attribute_name = strdup(cmsrems->reminder_name))
511 stat = CSA_E_INSUFFICIENT_MEMORY;
515 if ((stat = _DtCm_make_libentry(NULL, &entry)) == CSA_SUCCESS) {
516 opq.size = strlen(cmsrems->entryid);
517 opq.data = (unsigned char *)cmsrems->entryid;
519 /* put reference id in entry */
520 stat = _DtCm_set_opaque_attrval(&opq,
522 [CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I].value);
524 entry->e->key.id = cmsrems->key.id;
525 entry->e->key.time = cmsrems->key.time;
527 rem_r[i].entry = (CSA_entry_handle)entry;
531 cmsrems = cmsrems->next;
535 if (stat == CSA_SUCCESS) {
546 * This routine convert the entry to an entry structure with
547 * a header so that it can be freed with csa_free
548 * Memory occupied by the orginal entry will be destroyed.
550 extern _DtCm_libentry *
551 _DtCm_convert_entry_wheader(_DtCm_libentry *entry)
553 _DtCm_libentry *pentry;
555 if ((pentry = (_DtCm_libentry *)_DtCm_alloc_entry(
556 sizeof(_DtCm_libentry))) == NULL) {
557 _DtCm_free_libentries(entry);
561 pentry->handle = (void *)pentry;
562 pentry->filled = entry->filled;
563 pentry->e = entry->e;
571 * this is invoked from csa_free indirectly
575 _DtCm_free_entry_content(uint dummy, _DtCm_libentry *entry)
577 _DtCm_remove_from_entry_list(entry->cal, (caddr_t)entry, (caddr_t)entry);
578 if (entry->e) _DtCm_free_cms_entry(entry->e);
579 memset((void *)entry, 0, sizeof(_DtCm_libentry));
583 * free a linked list of entries
584 * It is first removed from the list and then freed.
587 _DtCm_free_libentries_from_list(_DtCm_libentry *head, _DtCm_libentry *tail)
589 if (head == NULL || tail == NULL)
592 _DtCm_remove_from_entry_list(head->cal, (caddr_t)head, (caddr_t)tail);
594 _DtCm_free_libentries(head);
598 * free a linked list of appointments
599 * All the memory pointed to by the entry are freed,
600 * except for the attribute array.
601 * The entry structures are returned to the free list.
604 _DtCm_free_libentries(_DtCm_libentry *entry)
606 _DtCm_libentry *nptr;
608 while (entry != NULL) {
611 if (entry->e) _DtCm_free_cms_entry(entry->e);
612 memset((void *)entry, 0, sizeof(_DtCm_libentry));
621 * Free the reminder linked list.
622 * The entry objects pointed to by the list are freed as well.
625 _DtCm_free_reminder_references(uint num_rems, CSA_reminder_reference *rems)
627 _DtCm_libentry *entry, *head, *cptr;
631 for (i = 0; i < num_rems; i++) {
633 entry = (_DtCm_libentry *)rems[i].entry;
634 if (entry && entry->handle == (void *)entry) {
637 } else if (cptr->next == entry) {
640 _DtCm_free_libentries_from_list(head, cptr);
645 if (rems[i].run_time)
646 free(rems[i].run_time);
648 if (rems[i].snooze_time)
649 free(rems[i].snooze_time);
651 if (rems[i].attribute_name)
652 free(rems[i].attribute_name);
656 _DtCm_free_libentries_from_list(head, cptr);
660 _DtCm_free_entry_handles(uint num_entries, CSA_entry_handle *entries)
663 _DtCm_libentry *entry, *head, *cptr;
665 DP(("api.c: _DtCm_free_entry_handles\n"));
668 for (i = 0, head = cptr = NULL; i < num_entries; i++) {
670 /* in case it is a bad appointment handle */
671 if ((entry = _DtCm_get_libentry(entries[i])) != NULL) {
673 * rather than freeing one appointment at a time,
674 * check to see if the appointments are linked to
675 * each other and free each consecutive chunk together
680 } else if (cptr->next == entry) {
683 _DtCm_free_libentries_from_list(head, cptr);
689 _DtCm_free_libentries_from_list(head, cptr);
692 /******************************************************************************
693 * static functions used within in the file
694 ******************************************************************************/
696 static CSA_return_code
698 _DtCmNameTable **tbl,
700 _DtCm_libentry **entry_r)
702 _DtCm_libentry *entry;
703 CSA_return_code stat;
705 if ((stat = _DtCm_make_libentry(NULL, &entry)) != CSA_SUCCESS)
708 if ((stat = _DtCmUpdateAttributes(e->num_attrs, e->attrs,
709 &entry->e->num_attrs, &entry->e->attrs, tbl, B_FALSE,
710 NULL, B_FALSE)) != CSA_SUCCESS) {
711 _DtCm_free_libentries(entry);
713 entry->e->key = e->key;
714 entry->filled = B_TRUE;