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: 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_return_code stat = CSA_SUCCESS;
261 CSA_entry_handle *eh;
265 if (elist == NULL || size == NULL || entries_r == NULL)
266 return (CSA_E_INVALID_PARAMETER);
268 for (i = 0, ptr = elist; ptr != NULL; ptr = ptr->next)
271 if ((eh = _DtCm_alloc_entry_handles(i)) == NULL)
272 return (CSA_E_INSUFFICIENT_MEMORY);
274 for (j = 0; j < i; j++, elist = elist->next)
275 eh[j] = (CSA_entry_handle)elist;
280 return (CSA_SUCCESS);
283 extern CSA_return_code
284 _DtCmCmsentriesToLibentries(
285 _DtCmNameTable **tbl,
287 _DtCm_libentry **libentries)
289 CSA_return_code stat = CSA_SUCCESS;
290 _DtCm_libentry *entry, *head, *prev;
292 if (libentries == NULL)
293 return(CSA_E_INVALID_PARAMETER);
296 while (entries != NULL) {
298 if ((stat = _CmsentryToLibentry(tbl, entries, &entry))
311 entries = entries->next;
314 if (stat != CSA_SUCCESS) {
315 _DtCm_free_libentries(head);
323 extern CSA_return_code
324 _DtCm_appt4_to_libentries(
327 _DtCm_libentry **libentries)
329 CSA_return_code stat = CSA_SUCCESS;
330 _DtCm_libentry *entry, *head, *prev;
332 if (libentries == NULL)
333 return(CSA_E_INVALID_PARAMETER);
336 while (appt4 != NULL) {
338 if ((stat = _DtCm_make_libentry(NULL, &entry)) != CSA_SUCCESS)
341 if ((stat = _DtCm_appt4_to_attrs(calname, appt4,
342 entry->e->num_attrs, entry->e->attrs, B_FALSE))
346 entry->e->key.time = appt4->appt_id.tick;
347 entry->e->key.id = appt4->appt_id.key;
348 entry->filled = B_TRUE;
362 if (stat != CSA_SUCCESS) {
363 _DtCm_free_libentries(head);
371 extern CSA_return_code
372 _DtCm_libentries_to_appt4(_DtCm_libentry *entries, Appt_4 **appt4)
374 CSA_return_code stat = CSA_SUCCESS;
375 Appt_4 *a4, *head, *prev;
378 return(CSA_E_INVALID_PARAMETER);
381 while (entries != NULL) {
383 if ((stat = _DtCm_cms_entry_to_appt4(entries->e, &a4)) != CSA_SUCCESS)
394 entries = entries->next;
397 if (stat != CSA_SUCCESS) {
398 _DtCm_free_appt4(head);
406 extern CSA_return_code
407 _DtCm_reminder4_to_csareminder(
409 CSA_uint32 *num_rems,
410 CSA_reminder_reference **rems)
412 CSA_return_code stat = CSA_SUCCESS;
413 _DtCm_libentry *entry;
414 CSA_reminder_reference *rem_r;
416 Reminder_4 *rptr = r4;
417 char isotime[BUFSIZ];
419 if (num_rems == NULL || rems == NULL)
420 return(CSA_E_INVALID_PARAMETER);
425 return (CSA_SUCCESS);
428 for (count = 0, rptr = r4; rptr != NULL; count++, rptr = rptr->next)
431 if ((rem_r = _DtCm_alloc_reminder_references(count)) == NULL) {
432 return (CSA_E_INSUFFICIENT_MEMORY);
436 while (r4 != NULL && r4->attr.attr != NULL) {
438 (void)_csa_tick_to_iso8601(r4->tick, isotime);
439 if ((rem_r[i].run_time = strdup(isotime)) == NULL) {
440 stat = CSA_E_INSUFFICIENT_MEMORY;
444 if ((rem_r[i].attribute_name = strdup(
445 _DtCm_old_reminder_name_to_name(r4->attr.attr))) == NULL) {
446 stat = CSA_E_INSUFFICIENT_MEMORY;
450 if ((stat = _DtCm_make_libentry(NULL, &entry)) == CSA_SUCCESS) {
451 entry->e->key.id = r4->appt_id.key;
452 entry->e->key.time = r4->appt_id.tick;
453 rem_r[i].entry = (CSA_entry_handle)entry;
461 if (stat == CSA_SUCCESS) {
471 extern CSA_return_code
472 _DtCm_cms2csa_reminder_ref(
473 cms_reminder_ref *cmsrems,
474 CSA_uint32 *num_rems,
475 CSA_reminder_reference **csarems)
477 CSA_return_code stat = CSA_SUCCESS;
478 _DtCm_libentry *entry;
479 CSA_reminder_reference *rem_r;
480 cms_reminder_ref *rptr;
482 char isotime[BUFSIZ];
486 if (num_rems == NULL || csarems == NULL)
487 return(CSA_E_INVALID_PARAMETER);
489 if (cmsrems == NULL) {
492 return (CSA_SUCCESS);
495 for (count = 0, rptr = cmsrems; rptr != NULL; rptr = rptr->next)
498 if ((rem_r = _DtCm_alloc_reminder_references(count)) == NULL) {
499 return (CSA_E_INSUFFICIENT_MEMORY);
503 while (cmsrems != NULL && stat == CSA_SUCCESS) {
505 (void)_csa_tick_to_iso8601(cmsrems->runtime, isotime);
506 if ((rem_r[i].run_time = strdup(isotime)) == NULL) {
507 stat = CSA_E_INSUFFICIENT_MEMORY;
511 if ((rem_r[i].attribute_name = strdup(cmsrems->reminder_name))
513 stat = CSA_E_INSUFFICIENT_MEMORY;
517 if ((stat = _DtCm_make_libentry(NULL, &entry)) == CSA_SUCCESS) {
518 opq.size = strlen(cmsrems->entryid);
519 opq.data = (unsigned char *)cmsrems->entryid;
521 /* put reference id in entry */
522 stat = _DtCm_set_opaque_attrval(&opq,
524 [CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I].value);
526 entry->e->key.id = cmsrems->key.id;
527 entry->e->key.time = cmsrems->key.time;
529 rem_r[i].entry = (CSA_entry_handle)entry;
533 cmsrems = cmsrems->next;
537 if (stat == CSA_SUCCESS) {
548 * This routine convert the entry to an entry structure with
549 * a header so that it can be freed with csa_free
550 * Memory occupied by the orginal entry will be destroyed.
552 extern _DtCm_libentry *
553 _DtCm_convert_entry_wheader(_DtCm_libentry *entry)
555 _DtCm_libentry *pentry;
557 if ((pentry = (_DtCm_libentry *)_DtCm_alloc_entry(
558 sizeof(_DtCm_libentry))) == NULL) {
559 _DtCm_free_libentries(entry);
563 pentry->handle = (void *)pentry;
564 pentry->filled = entry->filled;
565 pentry->e = entry->e;
573 * this is invoked from csa_free indirectly
577 _DtCm_free_entry_content(uint dummy, _DtCm_libentry *entry)
579 _DtCm_remove_from_entry_list(entry->cal, (caddr_t)entry, (caddr_t)entry);
580 if (entry->e) _DtCm_free_cms_entry(entry->e);
581 memset((void *)entry, NULL, sizeof(_DtCm_libentry));
585 * free a linked list of entries
586 * It is first removed from the list and then freed.
589 _DtCm_free_libentries_from_list(_DtCm_libentry *head, _DtCm_libentry *tail)
591 if (head == NULL || tail == NULL)
594 _DtCm_remove_from_entry_list(head->cal, (caddr_t)head, (caddr_t)tail);
596 _DtCm_free_libentries(head);
600 * free a linked list of appointments
601 * All the memory pointed to by the entry are freed,
602 * except for the attribute array.
603 * The entry structures are returned to the free list.
606 _DtCm_free_libentries(_DtCm_libentry *entry)
608 _DtCm_libentry *nptr;
610 while (entry != NULL) {
613 if (entry->e) _DtCm_free_cms_entry(entry->e);
614 memset((void *)entry, NULL, sizeof(_DtCm_libentry));
623 * Free the reminder linked list.
624 * The entry objects pointed to by the list are freed as well.
627 _DtCm_free_reminder_references(uint num_rems, CSA_reminder_reference *rems)
629 CSA_reminder_reference *nptr;
630 _DtCm_libentry *entry, *head, *cptr;
634 for (i = 0; i < num_rems; i++) {
636 entry = (_DtCm_libentry *)rems[i].entry;
637 if (entry && entry->handle == (void *)entry) {
640 } else if (cptr->next == entry) {
643 _DtCm_free_libentries_from_list(head, cptr);
648 if (rems[i].run_time)
649 free(rems[i].run_time);
651 if (rems[i].snooze_time)
652 free(rems[i].snooze_time);
654 if (rems[i].attribute_name)
655 free(rems[i].attribute_name);
659 _DtCm_free_libentries_from_list(head, cptr);
663 _DtCm_free_entry_handles(uint num_entries, CSA_entry_handle *entries)
666 _DtCm_libentry *entry, *head, *cptr;
668 DP(("api.c: _DtCm_free_entry_handles\n"));
671 for (i = 0, head = cptr = NULL; i < num_entries; i++) {
673 /* in case it is a bad appointment handle */
674 if ((entry = _DtCm_get_libentry(entries[i])) != NULL) {
676 * rather than freeing one appointment at a time,
677 * check to see if the appointments are linked to
678 * each other and free each consecutive chunk together
683 } else if (cptr->next == entry) {
686 _DtCm_free_libentries_from_list(head, cptr);
692 _DtCm_free_libentries_from_list(head, cptr);
695 /******************************************************************************
696 * static functions used within in the file
697 ******************************************************************************/
699 static CSA_return_code
701 _DtCmNameTable **tbl,
703 _DtCm_libentry **entry_r)
705 _DtCm_libentry *entry;
706 CSA_return_code stat;
708 if ((stat = _DtCm_make_libentry(NULL, &entry)) != CSA_SUCCESS)
711 if ((stat = _DtCmUpdateAttributes(e->num_attrs, e->attrs,
712 &entry->e->num_attrs, &entry->e->attrs, tbl, B_FALSE,
713 NULL, B_FALSE)) != CSA_SUCCESS) {
714 _DtCm_free_libentries(entry);
716 entry->e->key = e->key;
717 entry->filled = B_TRUE;