libcsa: Resolve 96 -Wunused-variable warnings.
[oweals/cde.git] / cde / lib / csa / entry.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
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)
10  * any later version.
11  *
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
16  * details.
17  *
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
22  */
23 /* $XConsortium: entry.c /main/1 1996/04/21 19:23:10 drk $ */
24 /*
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.
29  */
30
31 /*
32  * Functions that manage the entry data structures.
33  */
34
35 #include <EUSCompat.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include "appt4.h"
40 #include "attr.h"
41 #include "calendar.h"
42 #include "cmsdata.h"
43 #include "convert4-5.h"
44 #include "convert5-4.h"
45 #include "debug.h"
46 #include "entry.h"
47 #include "free.h"
48 #include "nametbl.h"
49 #include "rpccalls.h"
50 #include "iso8601.h"
51 #include "updateattrs.h"
52
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);
58
59 /*****************************************************************************
60  * extern functions used in the library
61  *****************************************************************************/
62
63 /*
64  * Given the entry handle, return the internal entry data structure.
65  */
66 extern _DtCm_libentry *
67 _DtCm_get_libentry(CSA_entry_handle entryhandle)
68 {
69         _DtCm_libentry *entry = (_DtCm_libentry *)entryhandle;
70
71         if (entry == NULL || entry->handle != (void *)entry)
72                 return (NULL);
73         else
74                 return(entry);
75 }
76
77 extern CSA_return_code
78 _DtCm_make_libentry(cms_entry *e, _DtCm_libentry **entry_r)
79 {
80         _DtCm_libentry  *ptr;
81         CSA_return_code stat = CSA_SUCCESS;
82
83         if (entry_r == NULL)
84                 return (CSA_E_INVALID_PARAMETER);
85
86         if ((ptr = (_DtCm_libentry *)calloc(1, sizeof(_DtCm_libentry)))
87             == NULL)
88                 return (CSA_E_INSUFFICIENT_MEMORY);
89
90         if (e == NULL) {
91                 if ((ptr->e = _DtCm_make_cms_entry(_DtCm_entry_name_tbl))
92                     == NULL)
93                         stat = CSA_E_INSUFFICIENT_MEMORY;
94         } else
95                 stat = _DtCm_copy_cms_entry(e, &ptr->e);
96
97         if (stat == CSA_SUCCESS) {
98                 ptr->handle = (void *)ptr;
99                 *entry_r = ptr;
100         } else
101                 free(ptr);
102
103         return (stat);
104 }
105
106 /*
107  * Get entry data from the server.
108  */
109 extern CSA_return_code
110 _DtCm_get_entry_detail(_DtCm_libentry *entry)
111 {
112         CSA_return_code stat = CSA_SUCCESS;
113
114         if (entry->filled == B_FALSE)
115                 return (_DtCm_rpc_lookup_entry_by_id(entry->cal, entry));
116         else
117                 return (stat);
118 }
119
120 /*
121  * return attribute names of all attributes.
122  * ** how to deal with
123  *      - predefined attributes with null values
124  *      - custom attributes
125  */
126 extern CSA_return_code
127 _DtCm_get_entry_attr_names(
128         _DtCm_libentry *entry,
129         CSA_uint32 *num_names_r,
130         char **names_r[])
131 {
132         char    **names;
133         int     i, j;
134
135         *names_r = NULL;
136         *num_names_r = 0;
137
138         if ((names = _DtCm_alloc_character_pointers(entry->e->num_attrs))
139             == NULL)
140                 return (CSA_E_INSUFFICIENT_MEMORY);
141
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))
147                             == NULL) {
148                                 _DtCm_free(names);
149                                 return (CSA_E_INSUFFICIENT_MEMORY);
150                         } else
151                                 j++;
152                 }
153         }
154
155         *names_r = names;
156         *num_names_r = j;
157
158         return (CSA_SUCCESS);
159 }
160
161 extern CSA_return_code
162 _DtCm_get_all_entry_attrs(
163         _DtCm_libentry *entry,
164         CSA_uint32 *num_attrs,
165         CSA_attribute **attrs)
166 {
167         int             i, j;
168         CSA_return_code stat = CSA_SUCCESS;
169         CSA_attribute   *attrs_r;
170
171         if (num_attrs == NULL || attrs == NULL)
172                 return (CSA_E_INVALID_PARAMETER);
173
174         if ((attrs_r = _DtCm_alloc_attributes(entry->e->num_attrs)) == NULL)
175                 return (CSA_E_INSUFFICIENT_MEMORY);
176
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) {
180
181                         if ((stat = _DtCm_cms2csa_attribute(entry->e->attrs[i],
182                             &attrs_r[j])) != CSA_SUCCESS) {
183                                 _DtCm_free(attrs_r);
184                                 return (stat);
185                         } else
186                                 j++;
187                 }
188         }
189
190         *num_attrs = j;
191         *attrs = attrs_r;
192
193         return (CSA_SUCCESS);
194 }
195
196 /*
197  * Search the attribute list for the given attribute names.
198  * If it's not found, the attribute value
199  * is set to NULL.
200  */
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)
208 {
209         int             i, j, index;
210         CSA_return_code stat = CSA_SUCCESS;
211         CSA_attribute   *attrs_r;
212
213         if (num_attrs == NULL || attrs == NULL)
214                 return (CSA_E_INVALID_PARAMETER);
215
216         if ((attrs_r = _DtCm_alloc_attributes(num_names)) == NULL)
217                 return (CSA_E_INSUFFICIENT_MEMORY);
218
219         /* get attributes */
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]);
224
225                         if (index >= 0 && entry->e->attrs[index].value) {
226                                 if (attrs_r[j].name =
227                                     strdup(entry->e->attrs[index].name.name))
228                                 {
229                                         stat = _DtCm_cms2csa_attrval(
230                                                 entry->e->attrs[index].value,
231                                                 &attrs_r[j].value);
232                                 } else
233                                         stat = CSA_E_INSUFFICIENT_MEMORY;
234
235                                 if (stat != CSA_SUCCESS) {
236                                         _DtCm_free(attrs_r);
237                                         return (stat);
238                                 } else
239                                         j++;
240                         }
241                 }
242         }
243
244         *num_attrs = j;
245         *attrs = attrs_r;
246
247         return (CSA_SUCCESS);
248 }
249
250 /*
251  * convert the linked list of entry structures to
252  * an array of entry handles.
253  */
254 extern CSA_return_code
255 _DtCm_libentry_to_entryh(
256         _DtCm_libentry *elist,
257         CSA_uint32 *size,
258         CSA_entry_handle **entries_r)
259 {
260         CSA_entry_handle        *eh;
261         _DtCm_libentry  *ptr;
262         int             i, j;
263
264         if (elist == NULL || size == NULL || entries_r == NULL)
265                 return (CSA_E_INVALID_PARAMETER);
266
267         for (i = 0, ptr = elist; ptr != NULL; ptr = ptr->next)
268                 i++;
269
270         if ((eh = _DtCm_alloc_entry_handles(i)) == NULL)
271                 return (CSA_E_INSUFFICIENT_MEMORY);
272
273         for (j = 0; j < i; j++, elist = elist->next)
274                 eh[j] = (CSA_entry_handle)elist;
275
276         *size = i;
277         *entries_r = eh;
278
279         return (CSA_SUCCESS);
280 }
281
282 extern CSA_return_code
283 _DtCmCmsentriesToLibentries(
284         _DtCmNameTable  **tbl,
285         cms_entry       *entries,
286         _DtCm_libentry  **libentries)
287 {
288         CSA_return_code stat = CSA_SUCCESS;
289         _DtCm_libentry  *entry, *head, *prev;
290
291         if (libentries == NULL)
292                 return(CSA_E_INVALID_PARAMETER);
293
294         prev = head = NULL;
295         while (entries != NULL) {
296
297                 if ((stat = _CmsentryToLibentry(tbl, entries, &entry))
298                     != CSA_SUCCESS)
299                         break;
300
301                 if (head == NULL)
302                         head = entry;
303                 else {
304                         prev->next = entry;
305                         entry->prev = prev;
306                 }
307
308                 prev = entry;
309
310                 entries = entries->next;
311         }
312
313         if (stat != CSA_SUCCESS) {
314                 _DtCm_free_libentries(head);
315                 head = NULL;
316         }
317
318         *libentries = head;
319         return(stat);
320 }
321
322 extern CSA_return_code
323 _DtCm_appt4_to_libentries(
324         char            *calname,
325         Appt_4          *appt4,
326         _DtCm_libentry  **libentries)
327 {
328         CSA_return_code stat = CSA_SUCCESS;
329         _DtCm_libentry  *entry, *head, *prev;
330
331         if (libentries == NULL)
332                 return(CSA_E_INVALID_PARAMETER);
333
334         prev = head = NULL;
335         while (appt4 != NULL) {
336
337                 if ((stat = _DtCm_make_libentry(NULL, &entry)) != CSA_SUCCESS)
338                         break;
339
340                 if ((stat = _DtCm_appt4_to_attrs(calname, appt4,
341                     entry->e->num_attrs, entry->e->attrs, B_FALSE))
342                     != CSA_SUCCESS)
343                         break;
344
345                 entry->e->key.time = appt4->appt_id.tick;
346                 entry->e->key.id = appt4->appt_id.key;
347                 entry->filled = B_TRUE;
348
349                 if (head == NULL)
350                         head = entry;
351                 else {
352                         prev->next = entry;
353                         entry->prev = prev;
354                 }
355
356                 prev = entry;
357
358                 appt4 = appt4->next;
359         }
360
361         if (stat != CSA_SUCCESS) {
362                 _DtCm_free_libentries(head);
363                 head = NULL;
364         }
365
366         *libentries = head;
367         return(stat);
368 }
369
370 extern CSA_return_code
371 _DtCm_libentries_to_appt4(_DtCm_libentry *entries, Appt_4 **appt4)
372 {
373         CSA_return_code stat = CSA_SUCCESS;
374         Appt_4          *a4, *head, *prev;
375
376         if (appt4 == NULL)
377                 return(CSA_E_INVALID_PARAMETER);
378
379         prev = head = NULL;
380         while (entries != NULL) {
381
382                 if ((stat = _DtCm_cms_entry_to_appt4(entries->e, &a4)) != CSA_SUCCESS)
383                         break;
384
385                 if (head == NULL)
386                         head = a4;
387                 else {
388                         prev->next = a4;
389                 }
390
391                 prev = a4;
392
393                 entries = entries->next;
394         }
395
396         if (stat != CSA_SUCCESS) {
397                 _DtCm_free_appt4(head);
398                 head = NULL;
399         }
400
401         *appt4 = head;
402         return(stat);
403 }
404
405 extern CSA_return_code
406 _DtCm_reminder4_to_csareminder(
407         Reminder_4 *r4,
408         CSA_uint32 *num_rems,
409         CSA_reminder_reference **rems)
410 {
411         CSA_return_code stat = CSA_SUCCESS;
412         _DtCm_libentry  *entry;
413         CSA_reminder_reference *rem_r;
414         int     i, count;
415         Reminder_4 *rptr = r4;
416         char    isotime[BUFSIZ];
417
418         if (num_rems == NULL || rems == NULL)
419                 return(CSA_E_INVALID_PARAMETER);
420
421         if (r4 == NULL) {
422                 *num_rems = 0;
423                 *rems = NULL;
424                 return (CSA_SUCCESS);
425         }
426
427         for (count = 0, rptr = r4; rptr != NULL; count++, rptr = rptr->next)
428                 ;
429
430         if ((rem_r = _DtCm_alloc_reminder_references(count)) == NULL) {
431                 return (CSA_E_INSUFFICIENT_MEMORY);
432         }
433
434         i = 0;
435         while (r4 != NULL && r4->attr.attr != NULL) {
436
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;
440                         break;
441                 }
442
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;
446                         break;
447                 }
448
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;
453                 } else
454                         break;
455
456                 r4 = r4->next;
457                 i++;
458         }
459
460         if (stat == CSA_SUCCESS) {
461                 *num_rems = i;
462                 *rems = rem_r;
463         } else {
464                 _DtCm_free(rem_r);
465         }
466
467         return(stat);
468 }
469
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)
475 {
476         CSA_return_code         stat = CSA_SUCCESS;
477         _DtCm_libentry          *entry;
478         CSA_reminder_reference  *rem_r;
479         cms_reminder_ref        *rptr;
480         int                     i, count;
481         char                    isotime[BUFSIZ];
482         CSA_opaque_data         opq;
483
484         if (num_rems == NULL || csarems == NULL)
485                 return(CSA_E_INVALID_PARAMETER);
486
487         if (cmsrems == NULL) {
488                 *num_rems = 0;
489                 *csarems = NULL;
490                 return (CSA_SUCCESS);
491         }
492
493         for (count = 0, rptr = cmsrems; rptr != NULL; rptr = rptr->next)
494                 count++;
495
496         if ((rem_r = _DtCm_alloc_reminder_references(count)) == NULL) {
497                 return (CSA_E_INSUFFICIENT_MEMORY);
498         }
499
500         i = 0;
501         while (cmsrems != NULL && stat == CSA_SUCCESS) {
502
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;
506                         break;
507                 }
508
509                 if ((rem_r[i].attribute_name = strdup(cmsrems->reminder_name))
510                     == NULL) {
511                         stat = CSA_E_INSUFFICIENT_MEMORY;
512                         break;
513                 }
514
515                 if ((stat = _DtCm_make_libentry(NULL, &entry)) == CSA_SUCCESS) {
516                         opq.size = strlen(cmsrems->entryid);
517                         opq.data = (unsigned char *)cmsrems->entryid;
518
519                         /* put reference id in entry */
520                         stat = _DtCm_set_opaque_attrval(&opq,
521                                 &entry->e->attrs\
522                                 [CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I].value);
523
524                         entry->e->key.id = cmsrems->key.id;
525                         entry->e->key.time = cmsrems->key.time;
526
527                         rem_r[i].entry = (CSA_entry_handle)entry;
528                 } else
529                         break;
530
531                 cmsrems = cmsrems->next;
532                 i++;
533         }
534
535         if (stat == CSA_SUCCESS) {
536                 *num_rems = i;
537                 *csarems = rem_r;
538         } else {
539                 _DtCm_free(rem_r);
540         }
541
542         return(stat);
543 }
544
545 /*
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.
549  */
550 extern _DtCm_libentry *
551 _DtCm_convert_entry_wheader(_DtCm_libentry *entry)
552 {
553         _DtCm_libentry *pentry;
554
555         if ((pentry = (_DtCm_libentry *)_DtCm_alloc_entry(
556             sizeof(_DtCm_libentry))) == NULL) {
557                 _DtCm_free_libentries(entry);
558                 return (NULL);
559         }
560
561         pentry->handle = (void *)pentry;
562         pentry->filled = entry->filled;
563         pentry->e = entry->e;
564
565         free(entry);
566
567         return(pentry);
568 }
569
570 /*
571  * this is invoked from csa_free indirectly
572  * to free one entry.
573  */
574 extern void
575 _DtCm_free_entry_content(uint dummy, _DtCm_libentry *entry)
576 {
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));
580 }
581
582 /*
583  * free a linked list of entries
584  * It is first removed from the list and then freed.
585  */
586 extern void
587 _DtCm_free_libentries_from_list(_DtCm_libentry *head, _DtCm_libentry *tail)
588 {
589         if (head == NULL || tail == NULL)
590                 return;
591
592         _DtCm_remove_from_entry_list(head->cal, (caddr_t)head, (caddr_t)tail);
593
594         _DtCm_free_libentries(head);
595 }
596
597 /*
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.
602  */
603 extern void
604 _DtCm_free_libentries(_DtCm_libentry *entry)
605 {
606         _DtCm_libentry *nptr;
607
608         while (entry != NULL) {
609                 nptr = entry->next;
610
611                 if (entry->e) _DtCm_free_cms_entry(entry->e);
612                 memset((void *)entry, 0, sizeof(_DtCm_libentry));
613
614                 free(entry);
615
616                 entry = nptr;
617         }
618 }
619
620 /*
621  * Free the reminder linked list.
622  * The entry objects pointed to by the list are freed as well.
623  */
624 extern void
625 _DtCm_free_reminder_references(uint num_rems, CSA_reminder_reference *rems)
626 {
627         _DtCm_libentry  *entry, *head, *cptr;
628         int i;
629
630         head = cptr = NULL;
631         for (i = 0; i < num_rems; i++) {
632
633                 entry = (_DtCm_libentry *)rems[i].entry;
634                 if (entry && entry->handle == (void *)entry) {
635                         if (head == NULL) {
636                                 head = cptr = entry;
637                         } else if (cptr->next == entry) {
638                                 cptr = cptr->next;
639                         } else {
640                                 _DtCm_free_libentries_from_list(head, cptr);
641                                 head = cptr = entry;
642                         }
643                 }
644
645                 if (rems[i].run_time)
646                         free(rems[i].run_time);
647
648                 if (rems[i].snooze_time)
649                         free(rems[i].snooze_time);
650
651                 if (rems[i].attribute_name)
652                         free(rems[i].attribute_name);
653
654         }
655
656         _DtCm_free_libentries_from_list(head, cptr);
657 }
658
659 extern void
660 _DtCm_free_entry_handles(uint num_entries, CSA_entry_handle *entries)
661 {
662         int i;
663         _DtCm_libentry *entry, *head, *cptr;
664
665         DP(("api.c: _DtCm_free_entry_handles\n"));
666
667         head = cptr = NULL;
668         for (i = 0, head = cptr = NULL; i < num_entries; i++) {
669
670                 /* in case it is a bad appointment handle */
671                 if ((entry = _DtCm_get_libentry(entries[i])) != NULL) {
672                         /*
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
676                          */
677
678                         if (head == NULL) {
679                                 head = cptr = entry;
680                         } else if (cptr->next == entry) {
681                                 cptr = cptr->next;
682                         } else {
683                                 _DtCm_free_libentries_from_list(head, cptr);
684                                 head = cptr = entry;
685                         }
686                 }
687         }
688
689         _DtCm_free_libentries_from_list(head, cptr);
690 }
691
692 /******************************************************************************
693  * static functions used within in the file
694  ******************************************************************************/
695
696 static CSA_return_code
697 _CmsentryToLibentry(
698         _DtCmNameTable  **tbl,
699         cms_entry       *e,
700         _DtCm_libentry  **entry_r)
701 {
702         _DtCm_libentry *entry;
703         CSA_return_code stat;
704
705         if ((stat = _DtCm_make_libentry(NULL, &entry)) != CSA_SUCCESS)
706                 return (stat); 
707
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);
712         } else {
713                 entry->e->key = e->key;
714                 entry->filled = B_TRUE;
715                 *entry_r = entry;
716         }
717
718         return (stat);
719 }
720
721