calendar.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  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: calendar.c /main/1 1996/04/21 19:21:47 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 calendar data structures.
  32. *****************************************************************************/
  33. #include <EUSCompat.h>
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <pwd.h>
  38. #include "calendar.h"
  39. #include "entry.h"
  40. #include "cmsdata.h"
  41. #include "agent_p.h"
  42. #include "rpccalls.h"
  43. #include "debug.h"
  44. #include "attr.h"
  45. #include "xtclient.h"
  46. #include "misc.h"
  47. #include "free.h"
  48. #include "nametbl.h"
  49. #include "lutil.h"
  50. /* linked list of calendar structure representing opened calendars */
  51. Calendar *_DtCm_active_cal_list = NULL;
  52. /******************************************************************************
  53. * forward declaration of static functions used within the file
  54. ******************************************************************************/
  55. static CSA_return_code _get_owner_from_old_cal(Calendar *cal, char *buf);
  56. static CSA_return_code _get_calendar_owner(Calendar *cal, uint num_names,
  57. char **names, CSA_attribute *attr);
  58. static CSA_return_code _get_calendar_name(Calendar *cal, CSA_attribute *attr);
  59. static CSA_return_code _get_product_identifier(Calendar *cal,
  60. CSA_attribute *attr);
  61. static CSA_return_code _get_version_supported(Calendar *cal,
  62. CSA_attribute *attr);
  63. static CSA_return_code _get_server_version(Calendar *cal, CSA_attribute *attr);
  64. static CSA_return_code _get_data_version(Calendar *cal, CSA_attribute *attr);
  65. static CSA_return_code _get_access_list(Calendar *cal, uint num_names,
  66. char ** names, CSA_attribute *attr);
  67. static CSA_return_code _get_number_entries(Calendar *cal, uint num_names,
  68. char ** names, CSA_attribute *attr);
  69. /*****************************************************************************
  70. * extern functions used in the library
  71. *****************************************************************************/
  72. /*
  73. * Allocate a calendar structure and initialize it with
  74. * the location, and name of the calendar.
  75. */
  76. extern Calendar *
  77. _DtCm_new_Calendar(const char *calendar)
  78. {
  79. Calendar *cal;
  80. int i;
  81. _DtCm_init_hash();
  82. if ((cal = (Calendar *)malloc(sizeof(Calendar))) == NULL)
  83. return(NULL);
  84. memset((void *)cal, 0, sizeof(Calendar));
  85. if ((cal->name = strdup(calendar)) == NULL) {
  86. free(cal);
  87. return(NULL);
  88. }
  89. cal->location = strchr(cal->name, '@');
  90. cal->location++;
  91. /* set up attribute array */
  92. if ((cal->attrs = (cms_attribute *)calloc(1,
  93. sizeof(cms_attribute) * (_DtCm_cal_name_tbl->size + 1))) == NULL) {
  94. free(cal->name);
  95. free(cal);
  96. return(NULL);
  97. }
  98. for (i = 1; i <= _DtCm_cal_name_tbl->size; i++) {
  99. if ((cal->attrs[i].name.name =
  100. strdup(_DtCm_cal_name_tbl->names[i])) == NULL) {
  101. /* clean up */
  102. cal->num_attrs = i - 1;
  103. _DtCm_free_Calendar(cal);
  104. return(NULL);
  105. } else
  106. cal->attrs[i].name.num = i;
  107. }
  108. cal->num_attrs = _DtCm_cal_name_tbl->size;
  109. if (_DtCm_active_cal_list == NULL) {
  110. _DtCm_active_cal_list = cal;
  111. cal->next = NULL;
  112. cal->prev = NULL;
  113. }
  114. else {
  115. cal->next = _DtCm_active_cal_list;
  116. _DtCm_active_cal_list->prev = cal;
  117. _DtCm_active_cal_list = cal;
  118. }
  119. cal->cal_tbl = _DtCm_cal_name_tbl;
  120. cal->entry_tbl = _DtCm_entry_name_tbl;
  121. cal->handle = (void *)cal;
  122. return(cal);
  123. }
  124. /*
  125. * After freeing up memory pointed to by cal,
  126. * put it in the free list.
  127. */
  128. extern void
  129. _DtCm_free_Calendar(Calendar *cal)
  130. {
  131. _DtCmCallbackEntry *cb, *ptr;
  132. /* remove from active list */
  133. if (_DtCm_active_cal_list == cal)
  134. _DtCm_active_cal_list = cal->next;
  135. if (cal->prev != NULL)
  136. cal->prev->next = cal->next;
  137. if (cal->next != NULL)
  138. 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);
  142. if (cal->cal_tbl != _DtCm_cal_name_tbl)
  143. _DtCm_free_name_table(cal->cal_tbl);
  144. if (cal->entry_tbl != _DtCm_entry_name_tbl)
  145. _DtCm_free_name_table(cal->entry_tbl);
  146. cb = cal->cb_list;
  147. while (cb) {
  148. ptr = cb->next;
  149. free(cb);
  150. cb = ptr;
  151. }
  152. /*
  153. * no need to free attribute values now
  154. * since the values are passed to client
  155. * directly.
  156. * need to free attribute values if they
  157. * are cached later
  158. */
  159. _DtCm_free_cms_attribute_values(cal->num_attrs, cal->attrs);
  160. free(cal->attrs);
  161. memset((void *)cal, '\0', sizeof(Calendar));
  162. /* if no calendar is open, destroy rpc mapping */
  163. if (_DtCm_active_cal_list == NULL)
  164. _DtCm_destroy_agent();
  165. }
  166. /*
  167. * Given the calendar handle, return the internal calendar data structure.
  168. */
  169. extern Calendar *
  170. _DtCm_get_Calendar(CSA_session_handle calhandle)
  171. {
  172. Calendar *cal = (Calendar *)calhandle;
  173. if (cal == NULL || cal->handle != (void *)cal)
  174. return (NULL);
  175. else
  176. return ((Calendar *)calhandle);
  177. }
  178. /*
  179. * Add linked list of entry data structures to the calendar.
  180. */
  181. extern uint
  182. _DtCm_add_to_entry_list(Calendar *cal, caddr_t elist)
  183. {
  184. int i;
  185. _DtCm_libentry *entries = (_DtCm_libentry *)elist;
  186. if (entries == NULL)
  187. return (0);
  188. if (cal->ehead == NULL)
  189. cal->ehead = elist;
  190. else {
  191. ((_DtCm_libentry *)cal->etail)->next = entries;
  192. entries->prev = (_DtCm_libentry *)cal->etail;
  193. }
  194. /* find tail of given entry list */
  195. i = 1;
  196. entries->cal = cal;
  197. while (entries->next != NULL) {
  198. i++;
  199. entries->next->cal = cal;
  200. entries = entries->next;
  201. }
  202. cal->etail = (caddr_t)entries;
  203. #ifdef CM_DEBUG
  204. _DtCm_count_entry_in_list(cal->ehead);
  205. #endif
  206. return (i);
  207. }
  208. extern void
  209. _DtCm_remove_from_entry_list(
  210. Calendar *cal,
  211. caddr_t head,
  212. caddr_t tail)
  213. {
  214. _DtCm_libentry *ehead = (_DtCm_libentry *)head;
  215. _DtCm_libentry *etail = (_DtCm_libentry *)tail;
  216. if (ehead == NULL || tail == NULL)
  217. return;
  218. if (ehead == (_DtCm_libentry *)cal->ehead)
  219. cal->ehead = (caddr_t)etail->next;
  220. if (etail == (_DtCm_libentry *)cal->etail)
  221. cal->etail = (caddr_t)ehead->prev;
  222. /* remove from list */
  223. if (ehead->prev != NULL)
  224. ehead->prev->next = etail->next;
  225. if (etail->next != NULL)
  226. etail->next->prev = ehead->prev;
  227. etail->next = ehead->prev = NULL;
  228. #ifdef CM_DEBUG
  229. _DtCm_count_entry_in_list(cal->ehead);
  230. #endif
  231. }
  232. extern void
  233. _DtCm_reset_cal_attrs(Calendar *cal)
  234. {
  235. cal->got_attrs = B_FALSE;
  236. }
  237. /*
  238. * Assume good parameters. Caller should check before calling this.
  239. */
  240. extern CSA_return_code
  241. _DtCm_list_old_cal_attr_names(
  242. Calendar *cal,
  243. CSA_uint32 *num_names_r,
  244. char **names_r[])
  245. {
  246. CSA_return_code stat;
  247. char **names, buf[BUFSIZ];
  248. int i, j;
  249. if ((names = _DtCm_alloc_character_pointers(_DtCM_OLD_CAL_ATTR_SIZE))
  250. == NULL)
  251. return (CSA_E_INSUFFICIENT_MEMORY);
  252. /* find out whether we know the owner of the calendar */
  253. if ((stat = _get_owner_from_old_cal(cal, buf)) != CSA_SUCCESS) {
  254. _DtCm_free(names);
  255. return (stat);
  256. }
  257. for (i = 1, j = 0; i <= _DtCM_DEFINED_CAL_ATTR_SIZE; i++) {
  258. if (_CSA_cal_attr_info[i].fst_vers > 0 &&
  259. _CSA_cal_attr_info[i].fst_vers <= cal->file_version) {
  260. if (i == CSA_CAL_ATTR_CALENDAR_OWNER_I && *buf == '\0')
  261. continue;
  262. if ((names[j] =
  263. strdup(_CSA_calendar_attribute_names[i])) == NULL)
  264. {
  265. _DtCm_free(names);
  266. return (CSA_E_INSUFFICIENT_MEMORY);
  267. } else
  268. j++;
  269. }
  270. }
  271. *names_r = names;
  272. *num_names_r = j;
  273. return (CSA_SUCCESS);
  274. }
  275. extern CSA_return_code
  276. _DtCm_get_all_cal_attrs(
  277. Calendar *cal,
  278. CSA_uint32 *num_attrs,
  279. CSA_attribute **attrs)
  280. {
  281. CSA_return_code stat;
  282. int i, j;
  283. CSA_attribute *attrs_r;
  284. if (num_attrs == NULL || attrs == NULL)
  285. return (CSA_E_INVALID_PARAMETER);
  286. if (cal->rpc_version >= _DtCM_FIRST_EXTENSIBLE_SERVER_VERSION) {
  287. if ((stat = _DtCm_rpc_get_cal_attrs(cal, 0, 0, NULL))
  288. != CSA_SUCCESS)
  289. return (stat);
  290. if ((attrs_r = _DtCm_alloc_attributes(cal->num_attrs)) == NULL)
  291. return (CSA_E_INSUFFICIENT_MEMORY);
  292. /* get attributes */
  293. for (i = 1, j = 0; i <= cal->num_attrs; i++) {
  294. if (cal->attrs[i].value != NULL) {
  295. if ((stat = _DtCm_cms2csa_attribute(
  296. cal->attrs[i], &attrs_r[j])) != CSA_SUCCESS)
  297. {
  298. _DtCm_free(attrs_r);
  299. return (stat);
  300. } else
  301. j++;
  302. }
  303. }
  304. *num_attrs = j;
  305. *attrs = attrs_r;
  306. return (CSA_SUCCESS);
  307. } else
  308. return (_DtCm_get_cal_attrs_by_name(cal,
  309. _DtCM_DEFINED_CAL_ATTR_SIZE + 1,
  310. _CSA_calendar_attribute_names, num_attrs, attrs));
  311. }
  312. /*
  313. * If it's not found, the attribute value is set to NULL.
  314. */
  315. extern CSA_return_code
  316. _DtCm_get_cal_attrs_by_name(
  317. Calendar *cal,
  318. CSA_uint32 num_names,
  319. CSA_attribute_reference *names,
  320. CSA_uint32 *num_attrs,
  321. CSA_attribute **attrs)
  322. {
  323. CSA_return_code stat = CSA_SUCCESS;
  324. CSA_attribute *attrs_r;
  325. int i, j, index;
  326. if (num_attrs == 0 || attrs == NULL)
  327. return (CSA_E_INVALID_PARAMETER);
  328. if ((attrs_r = _DtCm_alloc_attributes(num_names)) == NULL)
  329. return (CSA_E_INSUFFICIENT_MEMORY);
  330. for (i = 0, j = 0; i < num_names; i++) {
  331. if (names[i] == NULL)
  332. continue;
  333. index = _DtCm_get_index_from_table(cal->cal_tbl, names[i]);
  334. switch (index) {
  335. case CSA_X_DT_CAL_ATTR_SERVER_VERSION_I:
  336. stat = _get_server_version(cal, &attrs_r[j]);
  337. break;
  338. case CSA_X_DT_CAL_ATTR_DATA_VERSION_I:
  339. stat = _get_data_version(cal, &attrs_r[j]);
  340. break;
  341. case CSA_CAL_ATTR_ACCESS_LIST_I:
  342. stat = _get_access_list(cal, num_names, names,
  343. &attrs_r[j]);
  344. break;
  345. case CSA_CAL_ATTR_NUMBER_ENTRIES_I:
  346. stat = _get_number_entries(cal, num_names,
  347. names, &attrs_r[j]);
  348. break;
  349. case CSA_CAL_ATTR_CALENDAR_NAME_I:
  350. stat = _get_calendar_name(cal, &attrs_r[j]);
  351. break;
  352. case CSA_CAL_ATTR_CALENDAR_OWNER_I:
  353. stat = _get_calendar_owner(cal, num_names, names,
  354. &attrs_r[j]);
  355. break;
  356. case CSA_CAL_ATTR_PRODUCT_IDENTIFIER_I:
  357. stat = _get_product_identifier(cal, &attrs_r[j]);
  358. break;
  359. case CSA_CAL_ATTR_VERSION_I:
  360. stat = _get_version_supported(cal, &attrs_r[j]);
  361. break;
  362. default:
  363. if (cal->rpc_version >=
  364. _DtCM_FIRST_EXTENSIBLE_SERVER_VERSION)
  365. {
  366. if (cal->file_version <
  367. _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
  368. index == -1)
  369. break;
  370. if (cal->got_attrs == B_FALSE &&
  371. (stat = _DtCm_rpc_get_cal_attrs(cal, 0,
  372. num_names, names)) == CSA_SUCCESS) {
  373. /* there might by new attributes */
  374. if (index == -1 &&
  375. (index = _DtCm_get_index_from_table(
  376. cal->cal_tbl, names[i])) == -1)
  377. break;
  378. }
  379. if (stat == CSA_SUCCESS &&
  380. cal->attrs[index].value)
  381. stat = _DtCm_cms2csa_attribute(
  382. cal->attrs[index], &attrs_r[j]);
  383. }
  384. break;
  385. }
  386. if (stat == CSA_SUCCESS) {
  387. if (attrs_r[j].value != NULL)
  388. j++;
  389. } else {
  390. _DtCm_free(attrs_r);
  391. return (stat);
  392. }
  393. }
  394. *num_attrs = j;
  395. if (j > 0) {
  396. *attrs = attrs_r;
  397. } else {
  398. *attrs = NULL;
  399. _DtCm_free(attrs_r);
  400. }
  401. return (CSA_SUCCESS);
  402. }
  403. /*
  404. * Debugging function - count the number of entries in the list and print it out
  405. */
  406. extern void
  407. _DtCm_count_entry_in_list(caddr_t elist)
  408. {
  409. int i;
  410. _DtCm_libentry *list;
  411. for (i = 0, list = (_DtCm_libentry *)elist;
  412. list != NULL;
  413. i++, list = list->next)
  414. ;
  415. fprintf(stderr, "number of entries = %d\n", i);
  416. }
  417. /******************************************************************************
  418. * static functions used within in the file
  419. ******************************************************************************/
  420. /*
  421. * owner should point to a buffer big enough to hold the owner name
  422. * We test whether the calendar name is a user name, if so, the
  423. * owner will be the same as the calendar name.
  424. * Otherwise, we don't know the owner.
  425. */
  426. static CSA_return_code
  427. _get_owner_from_old_cal(Calendar *cal, char *owner)
  428. {
  429. char *calname;
  430. if ((calname = _DtCmGetPrefix(cal->name, '@')) == NULL)
  431. return (CSA_E_INSUFFICIENT_MEMORY);
  432. if (_DtCmIsUserName(calname) == B_TRUE)
  433. strcpy(owner, calname);
  434. else
  435. *owner = '\0';
  436. free(calname);
  437. return (CSA_SUCCESS);
  438. }
  439. static CSA_return_code
  440. _get_calendar_owner(
  441. Calendar *cal,
  442. uint num_names,
  443. char **names,
  444. CSA_attribute *attr)
  445. {
  446. CSA_return_code stat;
  447. CSA_attribute_value *val;
  448. char *owner, buf[BUFSIZ];
  449. if (cal->rpc_version >= _DtCM_FIRST_EXTENSIBLE_SERVER_VERSION) {
  450. if (cal->got_attrs == B_FALSE) {
  451. if ((stat = _DtCm_rpc_get_cal_attrs(cal, 0, num_names,
  452. names)) != CSA_SUCCESS)
  453. return (stat);
  454. }
  455. owner = cal->attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].value->\
  456. item.string_value;
  457. } else {
  458. if ((stat = _get_owner_from_old_cal(cal, buf)) != CSA_SUCCESS)
  459. return (stat);
  460. else if (*buf == '\0')
  461. return (CSA_SUCCESS);
  462. else
  463. owner = buf;
  464. }
  465. if (attr->name = strdup(CSA_CAL_ATTR_CALENDAR_OWNER)) {
  466. if ((val = (CSA_attribute_value *)calloc(1,
  467. sizeof(CSA_attribute_value))) == NULL) {
  468. free(attr->name);
  469. return (CSA_E_INSUFFICIENT_MEMORY);
  470. }
  471. val->type = CSA_VALUE_CALENDAR_USER;
  472. if ((val->item.calendar_user_value = (CSA_calendar_user *)
  473. calloc(1, sizeof(CSA_calendar_user))) == NULL) {
  474. free(val);
  475. free(attr->name);
  476. return (CSA_E_INSUFFICIENT_MEMORY);
  477. }
  478. if (val->item.calendar_user_value->user_name = strdup(owner)) {
  479. attr->value = val;
  480. return (CSA_SUCCESS);
  481. } else {
  482. free(val->item.calendar_user_value);
  483. free(val);
  484. free(attr->name);
  485. return (CSA_E_INSUFFICIENT_MEMORY);
  486. }
  487. } else
  488. return (CSA_E_INSUFFICIENT_MEMORY);
  489. }
  490. static CSA_return_code
  491. _get_calendar_name(Calendar *cal, CSA_attribute *attr)
  492. {
  493. if (attr->name = strdup(CSA_CAL_ATTR_CALENDAR_NAME))
  494. return (_DtCm_set_csa_string_attrval(cal->name, &attr->value,
  495. CSA_VALUE_STRING));
  496. else
  497. return (CSA_E_INSUFFICIENT_MEMORY);
  498. }
  499. static CSA_return_code
  500. _get_product_identifier(Calendar *cal, CSA_attribute *attr)
  501. {
  502. if (attr->name = strdup(CSA_CAL_ATTR_PRODUCT_IDENTIFIER))
  503. return (_DtCm_set_csa_string_attrval(_DtCM_PRODUCT_IDENTIFIER,
  504. &attr->value, CSA_VALUE_STRING));
  505. else
  506. return (CSA_E_INSUFFICIENT_MEMORY);
  507. }
  508. static CSA_return_code
  509. _get_version_supported(Calendar *cal, CSA_attribute *attr)
  510. {
  511. if (attr->name = strdup(CSA_CAL_ATTR_VERSION))
  512. return (_DtCm_set_csa_string_attrval(
  513. _DtCM_SPEC_VERSION_SUPPORTED, &attr->value,
  514. CSA_VALUE_STRING));
  515. else
  516. return (CSA_E_INSUFFICIENT_MEMORY);
  517. }
  518. static CSA_return_code
  519. _get_server_version(Calendar *cal, CSA_attribute *attr)
  520. {
  521. if (attr->name = strdup(CSA_X_DT_CAL_ATTR_SERVER_VERSION))
  522. return (_DtCm_set_csa_uint32_attrval(cal->rpc_version,
  523. &attr->value));
  524. else
  525. return (CSA_E_INSUFFICIENT_MEMORY);
  526. }
  527. static CSA_return_code
  528. _get_data_version(Calendar *cal, CSA_attribute *attr)
  529. {
  530. if (attr->name = strdup(CSA_X_DT_CAL_ATTR_DATA_VERSION))
  531. return (_DtCm_set_csa_uint32_attrval(cal->file_version,
  532. &attr->value));
  533. else
  534. return (CSA_E_INSUFFICIENT_MEMORY);
  535. }
  536. static CSA_return_code
  537. _get_access_list(
  538. Calendar *cal,
  539. uint num_names,
  540. char **names,
  541. CSA_attribute *attr)
  542. {
  543. CSA_return_code stat = CSA_SUCCESS;
  544. if (cal->rpc_version < _DtCM_FIRST_EXTENSIBLE_SERVER_VERSION)
  545. stat = _DtCm_rpc_get_cal_attrs(cal, CSA_CAL_ATTR_ACCESS_LIST_I,
  546. 0, NULL);
  547. else if (cal->got_attrs == B_FALSE)
  548. stat = _DtCm_rpc_get_cal_attrs(cal, 0, num_names, names);
  549. if (stat == CSA_SUCCESS)
  550. stat = _DtCm_cms2csa_attribute(
  551. cal->attrs[CSA_CAL_ATTR_ACCESS_LIST_I], attr);
  552. return (stat);
  553. }
  554. static CSA_return_code
  555. _get_number_entries(
  556. Calendar *cal,
  557. uint num_names,
  558. char **names,
  559. CSA_attribute *attr)
  560. {
  561. CSA_return_code stat = CSA_SUCCESS;
  562. if (cal->rpc_version < _DtCM_FIRST_EXTENSIBLE_SERVER_VERSION)
  563. stat = _DtCm_rpc_get_cal_attrs(cal,
  564. CSA_CAL_ATTR_NUMBER_ENTRIES_I, 0, NULL);
  565. else if (cal->got_attrs == B_FALSE)
  566. stat = _DtCm_rpc_get_cal_attrs(cal, 0, num_names, names);
  567. if (stat == CSA_SUCCESS)
  568. stat = _DtCm_cms2csa_attribute(
  569. cal->attrs[CSA_CAL_ATTR_NUMBER_ENTRIES_I], attr);
  570. return (stat);
  571. }