entry.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  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 libraries 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. * Functions that manage the entry data structures.
  32. */
  33. #include <EUSCompat.h>
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include "appt4.h"
  38. #include "attr.h"
  39. #include "calendar.h"
  40. #include "cmsdata.h"
  41. #include "convert4-5.h"
  42. #include "convert5-4.h"
  43. #include "debug.h"
  44. #include "entry.h"
  45. #include "free.h"
  46. #include "nametbl.h"
  47. #include "rpccalls.h"
  48. #include "iso8601.h"
  49. #include "updateattrs.h"
  50. /******************************************************************************
  51. * forward declaration of static functions used within the file
  52. ******************************************************************************/
  53. static CSA_return_code _CmsentryToLibentry(_DtCmNameTable **tbl, cms_entry *e,
  54. _DtCm_libentry **entry_r);
  55. /*****************************************************************************
  56. * extern functions used in the library
  57. *****************************************************************************/
  58. /*
  59. * Given the entry handle, return the internal entry data structure.
  60. */
  61. extern _DtCm_libentry *
  62. _DtCm_get_libentry(CSA_entry_handle entryhandle)
  63. {
  64. _DtCm_libentry *entry = (_DtCm_libentry *)entryhandle;
  65. if (entry == NULL || entry->handle != (void *)entry)
  66. return (NULL);
  67. else
  68. return(entry);
  69. }
  70. extern CSA_return_code
  71. _DtCm_make_libentry(cms_entry *e, _DtCm_libentry **entry_r)
  72. {
  73. _DtCm_libentry *ptr;
  74. CSA_return_code stat = CSA_SUCCESS;
  75. if (entry_r == NULL)
  76. return (CSA_E_INVALID_PARAMETER);
  77. if ((ptr = (_DtCm_libentry *)calloc(1, sizeof(_DtCm_libentry)))
  78. == NULL)
  79. return (CSA_E_INSUFFICIENT_MEMORY);
  80. if (e == NULL) {
  81. if ((ptr->e = _DtCm_make_cms_entry(_DtCm_entry_name_tbl))
  82. == NULL)
  83. stat = CSA_E_INSUFFICIENT_MEMORY;
  84. } else
  85. stat = _DtCm_copy_cms_entry(e, &ptr->e);
  86. if (stat == CSA_SUCCESS) {
  87. ptr->handle = (void *)ptr;
  88. *entry_r = ptr;
  89. } else
  90. free(ptr);
  91. return (stat);
  92. }
  93. /*
  94. * Get entry data from the server.
  95. */
  96. extern CSA_return_code
  97. _DtCm_get_entry_detail(_DtCm_libentry *entry)
  98. {
  99. CSA_return_code stat = CSA_SUCCESS;
  100. if (entry->filled == B_FALSE)
  101. return (_DtCm_rpc_lookup_entry_by_id(entry->cal, entry));
  102. else
  103. return (stat);
  104. }
  105. /*
  106. * return attribute names of all attributes.
  107. * ** how to deal with
  108. * - predefined attributes with null values
  109. * - custom attributes
  110. */
  111. extern CSA_return_code
  112. _DtCm_get_entry_attr_names(
  113. _DtCm_libentry *entry,
  114. CSA_uint32 *num_names_r,
  115. char **names_r[])
  116. {
  117. char **names;
  118. int i, j;
  119. *names_r = NULL;
  120. *num_names_r = 0;
  121. if ((names = _DtCm_alloc_character_pointers(entry->e->num_attrs))
  122. == NULL)
  123. return (CSA_E_INSUFFICIENT_MEMORY);
  124. /* first element in attr array is not used */
  125. for (i = 1, j = 0; i <= entry->e->num_attrs; i++) {
  126. /* there should not be any NULL names in the attr array */
  127. if (entry->e->attrs[i].value != NULL) {
  128. if ((names[j] = strdup(entry->e->attrs[i].name.name))
  129. == NULL) {
  130. _DtCm_free(names);
  131. return (CSA_E_INSUFFICIENT_MEMORY);
  132. } else
  133. j++;
  134. }
  135. }
  136. *names_r = names;
  137. *num_names_r = j;
  138. return (CSA_SUCCESS);
  139. }
  140. extern CSA_return_code
  141. _DtCm_get_all_entry_attrs(
  142. _DtCm_libentry *entry,
  143. CSA_uint32 *num_attrs,
  144. CSA_attribute **attrs)
  145. {
  146. int i, j;
  147. CSA_return_code stat = CSA_SUCCESS;
  148. CSA_attribute *attrs_r;
  149. if (num_attrs == NULL || attrs == NULL)
  150. return (CSA_E_INVALID_PARAMETER);
  151. if ((attrs_r = _DtCm_alloc_attributes(entry->e->num_attrs)) == NULL)
  152. return (CSA_E_INSUFFICIENT_MEMORY);
  153. /* first element in attr array is not used */
  154. for (i = 1, j = 0; i <= entry->e->num_attrs; i++) {
  155. if (entry->e->attrs[i].value != NULL) {
  156. if ((stat = _DtCm_cms2csa_attribute(entry->e->attrs[i],
  157. &attrs_r[j])) != CSA_SUCCESS) {
  158. _DtCm_free(attrs_r);
  159. return (stat);
  160. } else
  161. j++;
  162. }
  163. }
  164. *num_attrs = j;
  165. *attrs = attrs_r;
  166. return (CSA_SUCCESS);
  167. }
  168. /*
  169. * Search the attribute list for the given attribute names.
  170. * If it's not found, the attribute value
  171. * is set to NULL.
  172. */
  173. extern CSA_return_code
  174. _DtCm_get_entry_attrs_by_name(
  175. _DtCm_libentry *entry,
  176. CSA_uint32 num_names,
  177. CSA_attribute_reference *names,
  178. CSA_uint32 *num_attrs,
  179. CSA_attribute **attrs)
  180. {
  181. int i, j, index;
  182. CSA_return_code stat = CSA_SUCCESS;
  183. CSA_attribute *attrs_r;
  184. if (num_attrs == NULL || attrs == NULL)
  185. return (CSA_E_INVALID_PARAMETER);
  186. if ((attrs_r = _DtCm_alloc_attributes(num_names)) == NULL)
  187. return (CSA_E_INSUFFICIENT_MEMORY);
  188. /* get attributes */
  189. for (i = 0, j = 0; i < num_names; i++) {
  190. if (names[i] != NULL) {
  191. index = _DtCm_get_index_from_table(
  192. entry->cal->entry_tbl, names[i]);
  193. if (index >= 0 && entry->e->attrs[index].value) {
  194. if (attrs_r[j].name =
  195. strdup(entry->e->attrs[index].name.name))
  196. {
  197. stat = _DtCm_cms2csa_attrval(
  198. entry->e->attrs[index].value,
  199. &attrs_r[j].value);
  200. } else
  201. stat = CSA_E_INSUFFICIENT_MEMORY;
  202. if (stat != CSA_SUCCESS) {
  203. _DtCm_free(attrs_r);
  204. return (stat);
  205. } else
  206. j++;
  207. }
  208. }
  209. }
  210. *num_attrs = j;
  211. *attrs = attrs_r;
  212. return (CSA_SUCCESS);
  213. }
  214. /*
  215. * convert the linked list of entry structures to
  216. * an array of entry handles.
  217. */
  218. extern CSA_return_code
  219. _DtCm_libentry_to_entryh(
  220. _DtCm_libentry *elist,
  221. CSA_uint32 *size,
  222. CSA_entry_handle **entries_r)
  223. {
  224. CSA_entry_handle *eh;
  225. _DtCm_libentry *ptr;
  226. int i, j;
  227. if (elist == NULL || size == NULL || entries_r == NULL)
  228. return (CSA_E_INVALID_PARAMETER);
  229. for (i = 0, ptr = elist; ptr != NULL; ptr = ptr->next)
  230. i++;
  231. if ((eh = _DtCm_alloc_entry_handles(i)) == NULL)
  232. return (CSA_E_INSUFFICIENT_MEMORY);
  233. for (j = 0; j < i; j++, elist = elist->next)
  234. eh[j] = (CSA_entry_handle)elist;
  235. *size = i;
  236. *entries_r = eh;
  237. return (CSA_SUCCESS);
  238. }
  239. extern CSA_return_code
  240. _DtCmCmsentriesToLibentries(
  241. _DtCmNameTable **tbl,
  242. cms_entry *entries,
  243. _DtCm_libentry **libentries)
  244. {
  245. CSA_return_code stat = CSA_SUCCESS;
  246. _DtCm_libentry *entry, *head, *prev;
  247. if (libentries == NULL)
  248. return(CSA_E_INVALID_PARAMETER);
  249. prev = head = NULL;
  250. while (entries != NULL) {
  251. if ((stat = _CmsentryToLibentry(tbl, entries, &entry))
  252. != CSA_SUCCESS)
  253. break;
  254. if (head == NULL)
  255. head = entry;
  256. else {
  257. prev->next = entry;
  258. entry->prev = prev;
  259. }
  260. prev = entry;
  261. entries = entries->next;
  262. }
  263. if (stat != CSA_SUCCESS) {
  264. _DtCm_free_libentries(head);
  265. head = NULL;
  266. }
  267. *libentries = head;
  268. return(stat);
  269. }
  270. extern CSA_return_code
  271. _DtCm_appt4_to_libentries(
  272. char *calname,
  273. Appt_4 *appt4,
  274. _DtCm_libentry **libentries)
  275. {
  276. CSA_return_code stat = CSA_SUCCESS;
  277. _DtCm_libentry *entry, *head, *prev;
  278. if (libentries == NULL)
  279. return(CSA_E_INVALID_PARAMETER);
  280. prev = head = NULL;
  281. while (appt4 != NULL) {
  282. if ((stat = _DtCm_make_libentry(NULL, &entry)) != CSA_SUCCESS)
  283. break;
  284. if ((stat = _DtCm_appt4_to_attrs(calname, appt4,
  285. entry->e->num_attrs, entry->e->attrs, B_FALSE))
  286. != CSA_SUCCESS)
  287. break;
  288. entry->e->key.time = appt4->appt_id.tick;
  289. entry->e->key.id = appt4->appt_id.key;
  290. entry->filled = B_TRUE;
  291. if (head == NULL)
  292. head = entry;
  293. else {
  294. prev->next = entry;
  295. entry->prev = prev;
  296. }
  297. prev = entry;
  298. appt4 = appt4->next;
  299. }
  300. if (stat != CSA_SUCCESS) {
  301. _DtCm_free_libentries(head);
  302. head = NULL;
  303. }
  304. *libentries = head;
  305. return(stat);
  306. }
  307. extern CSA_return_code
  308. _DtCm_libentries_to_appt4(_DtCm_libentry *entries, Appt_4 **appt4)
  309. {
  310. CSA_return_code stat = CSA_SUCCESS;
  311. Appt_4 *a4, *head, *prev;
  312. if (appt4 == NULL)
  313. return(CSA_E_INVALID_PARAMETER);
  314. prev = head = NULL;
  315. while (entries != NULL) {
  316. if ((stat = _DtCm_cms_entry_to_appt4(entries->e, &a4)) != CSA_SUCCESS)
  317. break;
  318. if (head == NULL)
  319. head = a4;
  320. else {
  321. prev->next = a4;
  322. }
  323. prev = a4;
  324. entries = entries->next;
  325. }
  326. if (stat != CSA_SUCCESS) {
  327. _DtCm_free_appt4(head);
  328. head = NULL;
  329. }
  330. *appt4 = head;
  331. return(stat);
  332. }
  333. extern CSA_return_code
  334. _DtCm_reminder4_to_csareminder(
  335. Reminder_4 *r4,
  336. CSA_uint32 *num_rems,
  337. CSA_reminder_reference **rems)
  338. {
  339. CSA_return_code stat = CSA_SUCCESS;
  340. _DtCm_libentry *entry;
  341. CSA_reminder_reference *rem_r;
  342. int i, count;
  343. Reminder_4 *rptr = r4;
  344. char isotime[BUFSIZ];
  345. if (num_rems == NULL || rems == NULL)
  346. return(CSA_E_INVALID_PARAMETER);
  347. if (r4 == NULL) {
  348. *num_rems = 0;
  349. *rems = NULL;
  350. return (CSA_SUCCESS);
  351. }
  352. for (count = 0, rptr = r4; rptr != NULL; count++, rptr = rptr->next)
  353. ;
  354. if ((rem_r = _DtCm_alloc_reminder_references(count)) == NULL) {
  355. return (CSA_E_INSUFFICIENT_MEMORY);
  356. }
  357. i = 0;
  358. while (r4 != NULL && r4->attr.attr != NULL) {
  359. (void)_csa_tick_to_iso8601(r4->tick, isotime);
  360. if ((rem_r[i].run_time = strdup(isotime)) == NULL) {
  361. stat = CSA_E_INSUFFICIENT_MEMORY;
  362. break;
  363. }
  364. if ((rem_r[i].attribute_name = strdup(
  365. _DtCm_old_reminder_name_to_name(r4->attr.attr))) == NULL) {
  366. stat = CSA_E_INSUFFICIENT_MEMORY;
  367. break;
  368. }
  369. if ((stat = _DtCm_make_libentry(NULL, &entry)) == CSA_SUCCESS) {
  370. entry->e->key.id = r4->appt_id.key;
  371. entry->e->key.time = r4->appt_id.tick;
  372. rem_r[i].entry = (CSA_entry_handle)entry;
  373. } else
  374. break;
  375. r4 = r4->next;
  376. i++;
  377. }
  378. if (stat == CSA_SUCCESS) {
  379. *num_rems = i;
  380. *rems = rem_r;
  381. } else {
  382. _DtCm_free(rem_r);
  383. }
  384. return(stat);
  385. }
  386. extern CSA_return_code
  387. _DtCm_cms2csa_reminder_ref(
  388. cms_reminder_ref *cmsrems,
  389. CSA_uint32 *num_rems,
  390. CSA_reminder_reference **csarems)
  391. {
  392. CSA_return_code stat = CSA_SUCCESS;
  393. _DtCm_libentry *entry;
  394. CSA_reminder_reference *rem_r;
  395. cms_reminder_ref *rptr;
  396. int i, count;
  397. char isotime[BUFSIZ];
  398. CSA_opaque_data opq;
  399. if (num_rems == NULL || csarems == NULL)
  400. return(CSA_E_INVALID_PARAMETER);
  401. if (cmsrems == NULL) {
  402. *num_rems = 0;
  403. *csarems = NULL;
  404. return (CSA_SUCCESS);
  405. }
  406. for (count = 0, rptr = cmsrems; rptr != NULL; rptr = rptr->next)
  407. count++;
  408. if ((rem_r = _DtCm_alloc_reminder_references(count)) == NULL) {
  409. return (CSA_E_INSUFFICIENT_MEMORY);
  410. }
  411. i = 0;
  412. while (cmsrems != NULL && stat == CSA_SUCCESS) {
  413. (void)_csa_tick_to_iso8601(cmsrems->runtime, isotime);
  414. if ((rem_r[i].run_time = strdup(isotime)) == NULL) {
  415. stat = CSA_E_INSUFFICIENT_MEMORY;
  416. break;
  417. }
  418. if ((rem_r[i].attribute_name = strdup(cmsrems->reminder_name))
  419. == NULL) {
  420. stat = CSA_E_INSUFFICIENT_MEMORY;
  421. break;
  422. }
  423. if ((stat = _DtCm_make_libentry(NULL, &entry)) == CSA_SUCCESS) {
  424. opq.size = strlen(cmsrems->entryid);
  425. opq.data = (unsigned char *)cmsrems->entryid;
  426. /* put reference id in entry */
  427. stat = _DtCm_set_opaque_attrval(&opq,
  428. &entry->e->attrs\
  429. [CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I].value);
  430. entry->e->key.id = cmsrems->key.id;
  431. entry->e->key.time = cmsrems->key.time;
  432. rem_r[i].entry = (CSA_entry_handle)entry;
  433. } else
  434. break;
  435. cmsrems = cmsrems->next;
  436. i++;
  437. }
  438. if (stat == CSA_SUCCESS) {
  439. *num_rems = i;
  440. *csarems = rem_r;
  441. } else {
  442. _DtCm_free(rem_r);
  443. }
  444. return(stat);
  445. }
  446. /*
  447. * This routine convert the entry to an entry structure with
  448. * a header so that it can be freed with csa_free
  449. * Memory occupied by the orginal entry will be destroyed.
  450. */
  451. extern _DtCm_libentry *
  452. _DtCm_convert_entry_wheader(_DtCm_libentry *entry)
  453. {
  454. _DtCm_libentry *pentry;
  455. if ((pentry = (_DtCm_libentry *)_DtCm_alloc_entry(
  456. sizeof(_DtCm_libentry))) == NULL) {
  457. _DtCm_free_libentries(entry);
  458. return (NULL);
  459. }
  460. pentry->handle = (void *)pentry;
  461. pentry->filled = entry->filled;
  462. pentry->e = entry->e;
  463. free(entry);
  464. return(pentry);
  465. }
  466. /*
  467. * this is invoked from csa_free indirectly
  468. * to free one entry.
  469. */
  470. extern void
  471. _DtCm_free_entry_content(uint dummy, _DtCm_libentry *entry)
  472. {
  473. _DtCm_remove_from_entry_list(entry->cal, (caddr_t)entry, (caddr_t)entry);
  474. if (entry->e) _DtCm_free_cms_entry(entry->e);
  475. memset((void *)entry, 0, sizeof(_DtCm_libentry));
  476. }
  477. /*
  478. * free a linked list of entries
  479. * It is first removed from the list and then freed.
  480. */
  481. extern void
  482. _DtCm_free_libentries_from_list(_DtCm_libentry *head, _DtCm_libentry *tail)
  483. {
  484. if (head == NULL || tail == NULL)
  485. return;
  486. _DtCm_remove_from_entry_list(head->cal, (caddr_t)head, (caddr_t)tail);
  487. _DtCm_free_libentries(head);
  488. }
  489. /*
  490. * free a linked list of appointments
  491. * All the memory pointed to by the entry are freed,
  492. * except for the attribute array.
  493. * The entry structures are returned to the free list.
  494. */
  495. extern void
  496. _DtCm_free_libentries(_DtCm_libentry *entry)
  497. {
  498. _DtCm_libentry *nptr;
  499. while (entry != NULL) {
  500. nptr = entry->next;
  501. if (entry->e) _DtCm_free_cms_entry(entry->e);
  502. memset((void *)entry, 0, sizeof(_DtCm_libentry));
  503. free(entry);
  504. entry = nptr;
  505. }
  506. }
  507. /*
  508. * Free the reminder linked list.
  509. * The entry objects pointed to by the list are freed as well.
  510. */
  511. extern void
  512. _DtCm_free_reminder_references(uint num_rems, CSA_reminder_reference *rems)
  513. {
  514. _DtCm_libentry *entry, *head, *cptr;
  515. int i;
  516. head = cptr = NULL;
  517. for (i = 0; i < num_rems; i++) {
  518. entry = (_DtCm_libentry *)rems[i].entry;
  519. if (entry && entry->handle == (void *)entry) {
  520. if (head == NULL) {
  521. head = cptr = entry;
  522. } else if (cptr->next == entry) {
  523. cptr = cptr->next;
  524. } else {
  525. _DtCm_free_libentries_from_list(head, cptr);
  526. head = cptr = entry;
  527. }
  528. }
  529. if (rems[i].run_time)
  530. free(rems[i].run_time);
  531. if (rems[i].snooze_time)
  532. free(rems[i].snooze_time);
  533. if (rems[i].attribute_name)
  534. free(rems[i].attribute_name);
  535. }
  536. _DtCm_free_libentries_from_list(head, cptr);
  537. }
  538. extern void
  539. _DtCm_free_entry_handles(uint num_entries, CSA_entry_handle *entries)
  540. {
  541. int i;
  542. _DtCm_libentry *entry, *head, *cptr;
  543. DP(("api.c: _DtCm_free_entry_handles\n"));
  544. head = cptr = NULL;
  545. for (i = 0, head = cptr = NULL; i < num_entries; i++) {
  546. /* in case it is a bad appointment handle */
  547. if ((entry = _DtCm_get_libentry(entries[i])) != NULL) {
  548. /*
  549. * rather than freeing one appointment at a time,
  550. * check to see if the appointments are linked to
  551. * each other and free each consecutive chunk together
  552. */
  553. if (head == NULL) {
  554. head = cptr = entry;
  555. } else if (cptr->next == entry) {
  556. cptr = cptr->next;
  557. } else {
  558. _DtCm_free_libentries_from_list(head, cptr);
  559. head = cptr = entry;
  560. }
  561. }
  562. }
  563. _DtCm_free_libentries_from_list(head, cptr);
  564. }
  565. /******************************************************************************
  566. * static functions used within in the file
  567. ******************************************************************************/
  568. static CSA_return_code
  569. _CmsentryToLibentry(
  570. _DtCmNameTable **tbl,
  571. cms_entry *e,
  572. _DtCm_libentry **entry_r)
  573. {
  574. _DtCm_libentry *entry;
  575. CSA_return_code stat;
  576. if ((stat = _DtCm_make_libentry(NULL, &entry)) != CSA_SUCCESS)
  577. return (stat);
  578. if ((stat = _DtCmUpdateAttributes(e->num_attrs, e->attrs,
  579. &entry->e->num_attrs, &entry->e->attrs, tbl, B_FALSE,
  580. NULL, B_FALSE)) != CSA_SUCCESS) {
  581. _DtCm_free_libentries(entry);
  582. } else {
  583. entry->e->key = e->key;
  584. entry->filled = B_TRUE;
  585. *entry_r = entry;
  586. }
  587. return (stat);
  588. }