api.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341
  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: api.c /main/1 1996/04/21 19:21:31 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. * Implements the calendar manager API functions.
  32. */
  33. #include <EUSCompat.h>
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <pwd.h>
  38. #ifdef SunOS
  39. #include <stropts.h>
  40. #endif
  41. #include "csa.h"
  42. #include "agent_p.h"
  43. #include "entry.h"
  44. #include "rpccalls.h"
  45. #include "connection.h"
  46. #include "debug.h"
  47. #include "attr.h"
  48. #include "xtclient.h"
  49. #include "misc.h"
  50. #include "free.h"
  51. #include "iso8601.h"
  52. #include "match.h"
  53. /******************************************************************************
  54. * forward declaration of static functions used within the file
  55. ******************************************************************************/
  56. static CSA_return_code _handle_register_callback_ext(CSA_extension *ext);
  57. static CSA_return_code _handle_logon_ext(CSA_extension *ext,
  58. CSA_extension **pext);
  59. static CSA_return_code _handle_query_config_ext(CSA_extension *ext);
  60. static void _handle_com_support_ext(CSA_extension *ext);
  61. /******************************************************************************
  62. * Calendar Manager API
  63. ******************************************************************************/
  64. /*
  65. * List calendars supported by a server
  66. */
  67. extern CSA_return_code
  68. csa_list_calendars(
  69. CSA_service_reference calendar_service,
  70. CSA_uint32 *number_names,
  71. CSA_calendar_user **calendar_names,
  72. CSA_extension *list_calendars_extensions)
  73. {
  74. DP(("api.c: csa_list_calendars\n"));
  75. if (calendar_service == NULL || number_names == NULL ||
  76. calendar_names == NULL)
  77. return (CSA_E_INVALID_PARAMETER);
  78. /* no function extension is supported */
  79. if (list_calendars_extensions != NULL)
  80. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  81. return (_DtCm_rpc_list_calendars(calendar_service, number_names,
  82. calendar_names));
  83. }
  84. /*
  85. * Logon to a calendar.
  86. * Returns a calendar session handle.
  87. *
  88. * arguments not used by this implementation:
  89. * calendar_servce, password, character_set, caller_csa_version,
  90. * logon_extensions
  91. *
  92. * arguments ignored for now
  93. * character_set, caller_csa_version
  94. *
  95. * user - only the calendar_address field is used, other fields are ignored
  96. * - format is calendar_name@host
  97. */
  98. extern CSA_return_code
  99. csa_logon(
  100. CSA_service_reference calendar_service,
  101. CSA_calendar_user *user,
  102. CSA_string password,
  103. CSA_string character_set,
  104. CSA_string caller_csa_version,
  105. CSA_session_handle *session,
  106. CSA_extension *logon_extensions)
  107. {
  108. CSA_return_code stat;
  109. Calendar *cal;
  110. CSA_extension *pext = NULL;
  111. DP(("api.c: csa_logon\n"));
  112. /* check validity of arguments */
  113. if (user == NULL || user->calendar_address == NULL || session == NULL
  114. || strchr(user->calendar_address, '@') == NULL)
  115. return (CSA_E_INVALID_PARAMETER);
  116. /* create calendar object */
  117. if ((cal = _DtCm_new_Calendar(user->calendar_address)) == NULL) {
  118. return (CSA_E_INSUFFICIENT_MEMORY);
  119. }
  120. if (logon_extensions != NULL) {
  121. if ((stat = _handle_logon_ext(logon_extensions, &pext))
  122. != CSA_SUCCESS)
  123. return (stat);
  124. }
  125. /* open calendar */
  126. if ((stat = _DtCm_rpc_open_calendar(cal)) == CSA_SUCCESS) {
  127. if (pext) pext->item_data = cal->access;
  128. *session = (CSA_session_handle)cal;
  129. } else {
  130. _DtCm_free_Calendar(cal);
  131. }
  132. return (stat);
  133. }
  134. /*
  135. * Create a calendar.
  136. *
  137. * arguments not used by this implementation:
  138. * session - always ignored
  139. * add_calendar_extensions
  140. *
  141. * user - only the calendar_address field is used, other fields are ignored
  142. * - format is calendar_name@host
  143. */
  144. extern CSA_return_code
  145. csa_add_calendar(
  146. CSA_session_handle session,
  147. CSA_calendar_user *user,
  148. CSA_uint32 number_attributes,
  149. CSA_attribute *calendar_attributes,
  150. CSA_extension *add_calendar_extensions)
  151. {
  152. CSA_return_code stat;
  153. Calendar *cal;
  154. char *host;
  155. DP(("api.c: csa_add_calendar\n"));
  156. /* check validity of arguments */
  157. if (user == NULL || user->calendar_address == NULL ||
  158. (host = strchr(user->calendar_address, '@')) == NULL)
  159. return (CSA_E_INVALID_PARAMETER);
  160. /* check add_calendar_extensions and return appropriate return code */
  161. /* no function extension is supported */
  162. if (add_calendar_extensions != NULL)
  163. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  164. /* create calendar object */
  165. if ((cal = _DtCm_new_Calendar(user->calendar_address)) == NULL) {
  166. return (CSA_E_INSUFFICIENT_MEMORY);
  167. }
  168. host++;
  169. if ((stat = _DtCm_get_server_rpc_version(host, &cal->rpc_version))
  170. != CSA_SUCCESS)
  171. return (stat);
  172. /* check validity of attributes */
  173. if (number_attributes > 0 &&
  174. (stat = _DtCm_check_cal_csa_attributes(cal->rpc_version - 1,
  175. number_attributes, calendar_attributes, user->calendar_address,
  176. B_TRUE, B_TRUE, B_FALSE)) != CSA_SUCCESS) {
  177. return (stat);
  178. }
  179. /* create calendar */
  180. stat = _DtCm_rpc_create_calendar(cal, number_attributes,
  181. calendar_attributes);
  182. _DtCm_free_Calendar(cal);
  183. return (stat);
  184. }
  185. /*
  186. * Logoff a calendar.
  187. * The calendar handle becomes invalid
  188. *
  189. * argument not used by this implementation:
  190. * logoff_extensions
  191. */
  192. extern CSA_return_code
  193. csa_logoff(
  194. CSA_session_handle session,
  195. CSA_extension *logoff_extensions)
  196. {
  197. Calendar *cal;
  198. DP(("api.c: csa_logoff\n"));
  199. /* get calendar object */
  200. if ((cal = _DtCm_get_Calendar(session)) == NULL)
  201. return (CSA_E_INVALID_SESSION_HANDLE);
  202. /* check logoff_extensions and return appropriate return code */
  203. /* no function extension is supported */
  204. if (logoff_extensions != NULL)
  205. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  206. /* unregister with server */
  207. if (cal->all_reasons)
  208. (void) _DtCm_rpc_unregister_client(cal, cal->all_reasons);
  209. /* clean up */
  210. _DtCm_free_Calendar(cal);
  211. return (CSA_SUCCESS);
  212. }
  213. /*
  214. * delete calendar
  215. */
  216. extern CSA_return_code
  217. csa_delete_calendar(
  218. CSA_session_handle session,
  219. CSA_extension *delete_calendar_extensions)
  220. {
  221. Calendar *cal;
  222. DP(("api.c: csa_delete_calendar\n"));
  223. /* get calendar object */
  224. if ((cal = _DtCm_get_Calendar(session)) == NULL)
  225. return (CSA_E_INVALID_SESSION_HANDLE);
  226. /* check extensions and return appropriate return code */
  227. /* no function extension is supported */
  228. if (delete_calendar_extensions != NULL)
  229. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  230. if (cal->rpc_version < 5)
  231. return (CSA_E_NOT_SUPPORTED);
  232. return (_DtCm_rpc_delete_calendar(cal));
  233. }
  234. extern CSA_return_code
  235. csa_list_calendar_attributes(
  236. CSA_session_handle session,
  237. CSA_uint32 *number_names,
  238. CSA_attribute_reference **calendar_attributes_names,
  239. CSA_extension *list_calendar_attributes_extensions)
  240. {
  241. Calendar *cal;
  242. DP(("api.c: csa_list_calendar_attributes\n"));
  243. if (number_names == NULL || calendar_attributes_names == NULL)
  244. return (CSA_E_INVALID_PARAMETER);
  245. /* no function extension is supported */
  246. if (list_calendar_attributes_extensions != NULL)
  247. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  248. /* get calendar object */
  249. if ((cal = _DtCm_get_Calendar(session)) == NULL)
  250. return (CSA_E_INVALID_SESSION_HANDLE);
  251. if (cal->rpc_version < _DtCM_FIRST_EXTENSIBLE_SERVER_VERSION) {
  252. return (_DtCm_list_old_cal_attr_names(cal, number_names,
  253. calendar_attributes_names));
  254. } else
  255. return (_DtCm_rpc_list_calendar_attributes(cal, number_names,
  256. calendar_attributes_names));
  257. }
  258. extern CSA_return_code
  259. csa_save(
  260. CSA_session_handle session,
  261. CSA_string archive_name,
  262. CSA_uint32 number_attributes,
  263. CSA_attribute *attributes,
  264. CSA_enum *operators,
  265. CSA_boolean delete_entry,
  266. CSA_extension *save_extensions)
  267. {
  268. DP(("api.c: csa_save\n"));
  269. return (CSA_E_NOT_SUPPORTED);
  270. }
  271. extern CSA_return_code
  272. csa_restore(
  273. CSA_session_handle session,
  274. CSA_string archive_name,
  275. CSA_uint32 number_attributes,
  276. CSA_attribute *attributes,
  277. CSA_enum *operators,
  278. CSA_extension *restore_extensions)
  279. {
  280. DP(("api.c: csa_restore\n"));
  281. return (CSA_E_NOT_SUPPORTED);
  282. }
  283. /*
  284. * If list_operators is NULL, the operator is default to be CSA_MATCH_EQUAL_TO
  285. * for all attributes.
  286. * *** might want to check operator for conflicts that won't result in no match
  287. */
  288. extern CSA_return_code
  289. csa_list_entries(
  290. CSA_session_handle session,
  291. CSA_uint32 number_attributes,
  292. CSA_attribute *entry_attributes,
  293. CSA_enum *list_operators,
  294. CSA_uint32 *number_entries,
  295. CSA_entry_handle **entries,
  296. CSA_extension *list_entries_extensions)
  297. {
  298. CSA_return_code stat;
  299. Calendar *cal;
  300. _DtCm_libentry *elist;
  301. DP(("api.c: csa_list_entries\n"));
  302. if (entries == NULL || number_entries == NULL)
  303. return (CSA_E_INVALID_PARAMETER);
  304. else {
  305. *entries = NULL;
  306. *number_entries = 0;
  307. }
  308. /* check list_entries_extensions
  309. * and return appropriate return code
  310. * no function extension is supported
  311. */
  312. if (list_entries_extensions != NULL)
  313. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  314. /* get calendar object */
  315. if ((cal = _DtCm_get_Calendar(session)) == NULL)
  316. return (CSA_E_INVALID_SESSION_HANDLE);
  317. if (list_operators && (stat = _DtCm_check_operator(number_attributes,
  318. entry_attributes, NULL, list_operators)) != CSA_SUCCESS) {
  319. return (stat);
  320. }
  321. /* check data type */
  322. if ((stat = _DtCm_check_entry_attributes(cal->file_version,
  323. number_attributes, entry_attributes, 0, B_FALSE)) != CSA_SUCCESS) {
  324. /*
  325. * if attribute not supported by old backends
  326. * are specified, just fail the match,
  327. * i.e. return NULL and CSA_SUCCESS
  328. */
  329. if (stat == CSA_E_UNSUPPORTED_ATTRIBUTE)
  330. stat = CSA_SUCCESS;
  331. return (stat);
  332. }
  333. /* lookup entries */
  334. if ((stat = _DtCm_rpc_lookup_entries(cal, number_attributes,
  335. entry_attributes, list_operators, &elist)) == CSA_SUCCESS) {
  336. if (elist) {
  337. *number_entries = _DtCm_add_to_entry_list(cal, (caddr_t)elist);
  338. stat = _DtCm_libentry_to_entryh(elist, number_entries,
  339. entries);
  340. }
  341. }
  342. return (stat);
  343. }
  344. extern CSA_return_code
  345. csa_list_entry_attributes(
  346. CSA_session_handle session,
  347. CSA_entry_handle entryh,
  348. CSA_uint32 *number_names,
  349. CSA_attribute_reference **entry_attribute_names,
  350. CSA_extension *list_entry_attributes_extensions)
  351. {
  352. CSA_return_code stat;
  353. _DtCm_libentry *entry;
  354. DP(("api.c: csa_list_entry_attributes\n"));
  355. if (number_names == NULL || entry_attribute_names == NULL)
  356. return (CSA_E_INVALID_PARAMETER);
  357. /* check list_entry_attributes_extensions
  358. * and return appropriate return code
  359. * no function extension is supported
  360. */
  361. if (list_entry_attributes_extensions != NULL)
  362. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  363. /* get appointment */
  364. if ((entry = _DtCm_get_libentry(entryh)) == NULL)
  365. return (CSA_E_INVALID_ENTRY_HANDLE);
  366. if ((stat = _DtCm_get_entry_detail(entry)) != CSA_SUCCESS)
  367. return (stat);
  368. return (_DtCm_get_entry_attr_names(entry, number_names,
  369. entry_attribute_names));
  370. }
  371. extern CSA_return_code
  372. csa_read_entry_attributes(
  373. CSA_session_handle session,
  374. CSA_entry_handle entryh,
  375. CSA_uint32 number_names,
  376. CSA_attribute_reference *attribute_names,
  377. CSA_uint32 *number_attributes,
  378. CSA_attribute **entry_attributes,
  379. CSA_extension *read_entry_attributes_extensions)
  380. {
  381. CSA_return_code stat;
  382. _DtCm_libentry *entry;
  383. DP(("api.c: csa_read_entry_attributes\n"));
  384. if (number_attributes == 0 || entry_attributes == NULL)
  385. return (CSA_E_INVALID_PARAMETER);
  386. /* check read_entry_attributes_extensions
  387. * and return appropriate return code
  388. * no function extension is supported
  389. */
  390. if (read_entry_attributes_extensions != NULL)
  391. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  392. /* get entry object */
  393. if ((entry = _DtCm_get_libentry(entryh)) == NULL)
  394. return (CSA_E_INVALID_ENTRY_HANDLE);
  395. if ((stat = _DtCm_get_entry_detail(entry)) != CSA_SUCCESS)
  396. return (stat);
  397. if (number_names > 0) {
  398. return (_DtCm_get_entry_attrs_by_name(entry, number_names,
  399. attribute_names, number_attributes, entry_attributes));
  400. } else {
  401. return (_DtCm_get_all_entry_attrs(entry, number_attributes,
  402. entry_attributes));
  403. }
  404. }
  405. extern CSA_return_code
  406. csa_free(CSA_buffer memory)
  407. {
  408. DP(("api.c: csa_free\n"));
  409. return (_DtCm_free(memory));
  410. }
  411. extern CSA_return_code
  412. csa_look_up(
  413. CSA_session_handle session,
  414. CSA_calendar_user *users,
  415. CSA_flags look_up_flags,
  416. CSA_uint32 *number_users,
  417. CSA_calendar_user **user_list,
  418. CSA_extension *look_up_extensions)
  419. {
  420. DP(("api.c: csa_look_up\n"));
  421. return (CSA_E_NOT_SUPPORTED);
  422. }
  423. extern CSA_return_code
  424. csa_query_configuration(
  425. CSA_session_handle session,
  426. CSA_enum item,
  427. CSA_buffer *reference,
  428. CSA_extension *query_configuration_extensions)
  429. {
  430. CSA_return_code stat = CSA_SUCCESS;
  431. Calendar *cal;
  432. DP(("api.c: csa_query_configuration\n"));
  433. /* get calendar object */
  434. if ((cal = _DtCm_get_Calendar(session)) == NULL)
  435. return (CSA_E_INVALID_SESSION_HANDLE);
  436. if (item < CSA_CONFIG_CHARACTER_SET || item > CSA_CONFIG_VER_SPEC)
  437. return (CSA_E_INVALID_ENUM);
  438. if (reference == NULL)
  439. return (CSA_E_INVALID_PARAMETER);
  440. if (query_configuration_extensions) {
  441. if ((stat = _handle_query_config_ext(
  442. query_configuration_extensions)) != CSA_SUCCESS)
  443. return (stat);
  444. }
  445. switch (item) {
  446. case CSA_CONFIG_DEFAULT_SERVICE:
  447. case CSA_CONFIG_DEFAULT_USER:
  448. *reference = NULL;
  449. break;
  450. case CSA_CONFIG_REQ_PASSWORD:
  451. *reference = (CSA_buffer)CSA_REQUIRED_NO;
  452. break;
  453. case CSA_CONFIG_REQ_SERVICE:
  454. case CSA_CONFIG_REQ_USER:
  455. *reference = (CSA_buffer)CSA_REQUIRED_YES;
  456. break;
  457. case CSA_CONFIG_UI_AVAIL:
  458. *reference = (CSA_buffer)CSA_FALSE;
  459. break;
  460. case CSA_CONFIG_VER_SPEC:
  461. *reference = (CSA_buffer)strdup(_DtCM_SPEC_VERSION_SUPPORTED);
  462. break;
  463. case CSA_CONFIG_CHARACTER_SET:
  464. case CSA_CONFIG_LINE_TERM:
  465. case CSA_CONFIG_VER_IMPLEM:
  466. stat = CSA_E_UNSUPPORTED_ENUM;
  467. }
  468. return (stat);
  469. }
  470. extern CSA_return_code
  471. csa_read_calendar_attributes(
  472. CSA_session_handle session,
  473. CSA_uint32 number_names,
  474. CSA_attribute_reference *attribute_names,
  475. CSA_uint32 *number_attributes,
  476. CSA_attribute **calendar_attributes,
  477. CSA_extension *read_calendar_attributes_extensions)
  478. {
  479. Calendar *cal;
  480. DP(("api.c: csa_read_calendar_attributes\n"));
  481. if (number_attributes == 0 || calendar_attributes == NULL)
  482. return (CSA_E_INVALID_PARAMETER);
  483. /* check read_calendar_attributes_extensions
  484. * and return appropriate return code
  485. * no function extension is supported
  486. */
  487. if (read_calendar_attributes_extensions != NULL)
  488. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  489. /* get calendar object */
  490. if ((cal = _DtCm_get_Calendar(session)) == NULL)
  491. return (CSA_E_INVALID_SESSION_HANDLE);
  492. _DtCm_reset_cal_attrs(cal);
  493. if (number_names > 0) {
  494. return (_DtCm_get_cal_attrs_by_name(cal, number_names,
  495. attribute_names, number_attributes,
  496. calendar_attributes));
  497. } else {
  498. return (_DtCm_get_all_cal_attrs(cal, number_attributes,
  499. calendar_attributes));
  500. }
  501. }
  502. extern CSA_return_code
  503. csa_register_callback(
  504. CSA_session_handle session,
  505. CSA_flags reason,
  506. CSA_callback callback,
  507. CSA_buffer client_data,
  508. CSA_extension *register_callback_extensions)
  509. {
  510. CSA_return_code stat = CSA_SUCCESS;
  511. _DtCmCallbackEntry *cb_entry;
  512. Calendar *cal;
  513. boolean_t async = B_FALSE;
  514. /* get calendar object */
  515. if ((cal = _DtCm_get_Calendar(session)) == NULL)
  516. return (CSA_E_INVALID_SESSION_HANDLE);
  517. /* make sure some valid flags are set
  518. * and only entry added, deleted or updated is specified for
  519. * servers support up to version 4 rpc protocol
  520. */
  521. if (reason == 0 || reason >= (CSA_CB_ENTRY_UPDATED << 1) ||
  522. (cal->rpc_version < _DtCM_FIRST_EXTENSIBLE_SERVER_VERSION &&
  523. (reason & ~(CSA_CB_ENTRY_ADDED|CSA_CB_ENTRY_DELETED|
  524. CSA_CB_ENTRY_UPDATED))))
  525. return (CSA_E_INVALID_FLAG);
  526. /* must specify a callback function otherwise
  527. * there is no point to make this call
  528. */
  529. if (callback == NULL)
  530. return (CSA_E_INVALID_PARAMETER);
  531. /* need to initialize agent before doing XtAppAddInput */
  532. _DtCm_init_agent();
  533. if (register_callback_extensions != NULL) {
  534. if ((stat = _handle_register_callback_ext(
  535. register_callback_extensions)) != CSA_SUCCESS)
  536. return (stat);
  537. else
  538. async = B_TRUE;
  539. }
  540. /*
  541. * register interest only if we have a new flag
  542. * NOTE: It's OK to register more than once, even if it's
  543. * the same calendar, same reason. The customer is always right.
  544. */
  545. if (((cal->all_reasons | reason) ^ cal->all_reasons) &&
  546. (stat = _DtCm_rpc_register_client(cal, reason)) != CSA_SUCCESS)
  547. return stat;
  548. if ((cb_entry = (_DtCmCallbackEntry*)malloc(sizeof(_DtCmCallbackEntry)))
  549. == NULL)
  550. return (CSA_E_INSUFFICIENT_MEMORY);
  551. /* update info in calendar structure */
  552. cal->all_reasons |= reason;
  553. /* don't just do cal->async_process = async, since cal->async_process
  554. * might have been set to B_TRUE before.
  555. */
  556. if (async == B_TRUE)
  557. cal->async_process = B_TRUE;
  558. if (cal->async_process == B_TRUE)
  559. cal->do_reasons = cal->all_reasons;
  560. /* fill in the callback record */
  561. cb_entry->reason = reason;
  562. cb_entry->handler = callback;
  563. cb_entry->client_data = client_data;
  564. /* insert it at head of list */
  565. cb_entry->next = cal->cb_list;
  566. cb_entry->prev = (_DtCmCallbackEntry*) NULL;
  567. if (cal->cb_list != (_DtCmCallbackEntry*) NULL)
  568. cal->cb_list->prev = cb_entry;
  569. cal->cb_list = cb_entry;
  570. return CSA_SUCCESS;
  571. }
  572. /*
  573. * csa_unregister_callback
  574. *
  575. * removes a previsouly registered callback from the callback list
  576. * of the specified calendar.
  577. */
  578. extern CSA_return_code
  579. csa_unregister_callback(
  580. CSA_session_handle session,
  581. CSA_flags reason,
  582. CSA_callback handler,
  583. CSA_buffer client_data,
  584. CSA_extension *unregister_callback_extensions)
  585. {
  586. Calendar *cal;
  587. boolean_t match_one = B_FALSE;
  588. boolean_t match_all = B_FALSE;
  589. boolean_t matched;
  590. CSA_flags all = 0, unreg;
  591. _DtCmCallbackEntry *cb, *ncb;
  592. /* get calendar object */
  593. if ((cal = _DtCm_get_Calendar(session)) == NULL)
  594. return (CSA_E_INVALID_SESSION_HANDLE);
  595. if (reason == 0 || reason >= (CSA_CB_ENTRY_UPDATED << 1))
  596. return (CSA_E_INVALID_FLAG);
  597. /* check unregister_callback_extensions
  598. * and return appropriate return code
  599. * no function extension is supported
  600. */
  601. if (unregister_callback_extensions != NULL)
  602. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  603. if (handler == NULL && client_data == NULL)
  604. match_all = B_TRUE;
  605. else if (handler == NULL) /* but client data is not NULL */
  606. return (CSA_E_INVALID_PARAMETER);
  607. /*
  608. * Removal policy: If both handler and client data are NULL,
  609. * match all callbacks for the specified reason.
  610. * Otherwise, all of reason, handler and client data must
  611. * match.
  612. */
  613. cb = cal->cb_list;
  614. while (cb) {
  615. matched = B_TRUE;
  616. ncb = cb->next;
  617. if (!(reason & cb->reason) ||
  618. (match_all == B_FALSE && (handler != cb->handler ||
  619. client_data != cb->client_data))) {
  620. all = all | cb->reason;
  621. cb = cb->next;
  622. continue;
  623. }
  624. match_one = B_TRUE;
  625. if (cb->reason = (cb->reason | reason) ^ reason) {
  626. all = all | cb->reason;
  627. } else {
  628. /* remove entry */
  629. if (cb->prev != NULL)
  630. cb->prev->next = cb->next;
  631. if (cb->next != NULL)
  632. cb->next->prev = cb->prev;
  633. if (cb == cal->cb_list)
  634. cal->cb_list = cb->next;
  635. free(cb);
  636. }
  637. cb = ncb;
  638. }
  639. unreg = all ^ cal->all_reasons;
  640. cal->all_reasons = all;
  641. if (unreg)
  642. (void) _DtCm_rpc_unregister_client(cal, unreg);
  643. if (match_one == B_TRUE)
  644. return (CSA_SUCCESS);
  645. else
  646. return (CSA_E_CALLBACK_NOT_REGISTERED);
  647. }
  648. CSA_return_code
  649. csa_call_callbacks(
  650. CSA_session_handle session,
  651. CSA_flags reason,
  652. CSA_extension *call_callbacks_extensions)
  653. {
  654. Calendar *cal;
  655. DP(("api.c: csa_call_callbacks\n"));
  656. /* get calendar object */
  657. if ((cal = _DtCm_get_Calendar(session)) == NULL)
  658. return (CSA_E_INVALID_SESSION_HANDLE);
  659. /* no function extension is supported */
  660. if (call_callbacks_extensions != NULL)
  661. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  662. /* set up information in calendar structure */
  663. if (cal->async_process == B_FALSE)
  664. cal->do_reasons = reason;
  665. /* trigger callback mechanism */
  666. _DtCm_process_updates();
  667. if (cal->async_process == B_FALSE)
  668. cal->do_reasons = 0;
  669. return (CSA_SUCCESS);
  670. }
  671. extern CSA_return_code
  672. csa_update_calendar_attributes(
  673. CSA_session_handle session,
  674. CSA_uint32 num_attrs,
  675. CSA_attribute *attrs,
  676. CSA_extension *update_calendar_attributes_extensions)
  677. {
  678. CSA_return_code stat = CSA_SUCCESS;
  679. Calendar *cal;
  680. DP(("api.c: csa_update_calendar_attributes\n"));
  681. /* get calendar object */
  682. if ((cal = _DtCm_get_Calendar(session)) == NULL)
  683. return (CSA_E_INVALID_SESSION_HANDLE);
  684. if (num_attrs == 0 || attrs == NULL)
  685. return (CSA_E_INVALID_PARAMETER);
  686. /*
  687. * check update_calendar_attributes_extensions
  688. * return appropriate return code
  689. * no function extension is supported
  690. */
  691. if (update_calendar_attributes_extensions != NULL)
  692. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  693. /* check authority */
  694. if ((cal->file_version >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
  695. !(cal->access & (CSA_OWNER_RIGHTS | CSA_INSERT_CALENDAR_ATTRIBUTES |
  696. CSA_CHANGE_CALENDAR_ATTRIBUTES))) ||
  697. (cal->file_version < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION &&
  698. !(cal->access & CSA_OWNER_RIGHTS)))
  699. return (CSA_E_NO_AUTHORITY);
  700. /* check data type */
  701. if ((stat = _DtCm_check_cal_csa_attributes(cal->file_version,
  702. num_attrs, attrs, cal->name, B_TRUE, B_FALSE, B_TRUE))
  703. != CSA_SUCCESS) {
  704. return (stat);
  705. }
  706. /* set attributes */
  707. stat = _DtCm_rpc_set_cal_attrs(cal, num_attrs, attrs);
  708. return (stat);
  709. }
  710. extern CSA_return_code
  711. csa_add_entry(
  712. CSA_session_handle session,
  713. CSA_uint32 num_attrs,
  714. CSA_attribute *attrs,
  715. CSA_entry_handle *entry_r,
  716. CSA_extension *add_entry_extensions)
  717. {
  718. CSA_return_code stat;
  719. Calendar *cal;
  720. _DtCm_libentry *entry;
  721. DP(("api.c: csa_add_entry\n"));
  722. if (num_attrs == 0 || attrs == NULL)
  723. return (CSA_E_INVALID_PARAMETER);
  724. /* get calendar object */
  725. if ((cal = _DtCm_get_Calendar(session)) == NULL)
  726. return (CSA_E_INVALID_SESSION_HANDLE);
  727. /* check data type, readonly attributes, etc */
  728. if ((stat = _DtCm_check_entry_attributes(cal->file_version,
  729. num_attrs, attrs, CSA_CB_ENTRY_ADDED, B_TRUE)) != CSA_SUCCESS) {
  730. return (stat);
  731. }
  732. /* no function extension is supported */
  733. if (add_entry_extensions != NULL)
  734. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  735. /* insert in calendar */
  736. if ((stat = _DtCm_rpc_insert_entry(cal, num_attrs, attrs, &entry))
  737. == CSA_SUCCESS) {
  738. if (entry_r != NULL) {
  739. if ((entry = _DtCm_convert_entry_wheader(entry))==NULL)
  740. stat = CSA_E_INSUFFICIENT_MEMORY;
  741. else {
  742. _DtCm_add_to_entry_list(cal, (caddr_t)entry);
  743. *entry_r = (CSA_entry_handle)entry;
  744. }
  745. } else
  746. _DtCm_free_libentries(entry);
  747. }
  748. return (stat);
  749. }
  750. /*
  751. * The session argument is ignored in this implementation.
  752. */
  753. extern CSA_return_code
  754. csa_delete_entry(
  755. CSA_session_handle session,
  756. CSA_entry_handle entryh,
  757. CSA_enum delete_scope,
  758. CSA_extension *delete_entry_extensions)
  759. {
  760. CSA_return_code stat;
  761. _DtCm_libentry *entry;
  762. DP(("api.c: csa_delete_entry\n"));
  763. /* get entry object */
  764. if ((entry = _DtCm_get_libentry(entryh)) == NULL)
  765. return (CSA_E_INVALID_ENTRY_HANDLE);
  766. if (delete_scope < CSA_SCOPE_ALL || delete_scope > CSA_SCOPE_FORWARD)
  767. return (CSA_E_INVALID_ENUM);
  768. /* check delete_entry_extensions and return appropriate return code */
  769. /* no function extension is supported */
  770. if (delete_entry_extensions != NULL)
  771. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  772. /* delete entry from calendar */
  773. stat = _DtCm_rpc_delete_entry(entry->cal, entry, delete_scope);
  774. return (stat);
  775. }
  776. extern CSA_return_code
  777. csa_free_time_search(
  778. CSA_session_handle session,
  779. CSA_date_time_range date_time_range,
  780. CSA_time_duration time_duration,
  781. CSA_uint32 number_users,
  782. CSA_calendar_user *users,
  783. CSA_free_time **free_time,
  784. CSA_extension *free_time_search_extensions)
  785. {
  786. DP(("api.c: csa_free_time_search\n"));
  787. return (CSA_E_NOT_SUPPORTED);
  788. }
  789. extern CSA_return_code
  790. csa_list_entry_sequence(
  791. CSA_session_handle session,
  792. CSA_entry_handle entryh,
  793. CSA_date_time_range time_range,
  794. CSA_uint32 *number_entries,
  795. CSA_entry_handle **entries,
  796. CSA_extension *list_entry_sequence_extensions)
  797. {
  798. CSA_return_code stat;
  799. _DtCm_libentry *entry, *elist;
  800. cms_attribute *rtype;
  801. cms_attribute *rtimes;
  802. /* needed temporaryly */
  803. time_t start = 0, end = 0;
  804. DP(("api.c: csa_list_entry_sequence\n"));
  805. /* get entry object */
  806. if ((entry = _DtCm_get_libentry(entryh)) == NULL)
  807. return (CSA_E_INVALID_ENTRY_HANDLE);
  808. if (number_entries == NULL || entries == NULL)
  809. return (CSA_E_INVALID_PARAMETER);
  810. else {
  811. *number_entries = 0;
  812. *entries = NULL;
  813. }
  814. /* check whether this entry repeats */
  815. /* fail it if it's not a repeating event */
  816. if (entry->cal->file_version < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
  817. rtype = &entry->e->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I];
  818. if (rtype->value == NULL ||
  819. rtype->value->item.sint32_value == CSA_X_DT_REPEAT_ONETIME)
  820. {
  821. return (CSA_E_INVALID_PARAMETER);
  822. }
  823. } else {
  824. rtype = &entry->e->attrs[CSA_ENTRY_ATTR_RECURRENCE_RULE_I];
  825. if (rtype->value == NULL ||
  826. rtype->value->item.string_value == NULL ||
  827. *(rtype->value->item.string_value) == '\0' ) {
  828. return (CSA_E_INVALID_PARAMETER);
  829. }
  830. }
  831. /* if this entry repeats indefinitely and time range is not
  832. * specified, fail it
  833. */
  834. if (time_range) {
  835. if (_csa_iso8601_to_range(time_range, &start, &end) != 0)
  836. return (CSA_E_INVALID_DATE_TIME);
  837. }
  838. if (entry->cal->file_version < _DtCM_FIRST_EXTENSIBLE_DATA_VERSION)
  839. rtimes = &entry->e->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I];
  840. else
  841. rtimes = &entry->e->attrs[CSA_ENTRY_ATTR_NUMBER_RECURRENCES_I];
  842. if (start == 0 && end == 0 &&
  843. (rtimes->value && rtimes->value->item.uint32_value
  844. == CSA_X_DT_DT_REPEAT_FOREVER))
  845. return (CSA_E_INVALID_PARAMETER);
  846. /* no function extension is supported */
  847. if (list_entry_sequence_extensions != NULL)
  848. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  849. /* lookup sequence */
  850. if ((stat = _DtCm_rpc_enumerate_sequence(entry->cal, entry, start, end,
  851. &elist)) == CSA_SUCCESS) {
  852. if (elist) {
  853. *number_entries = _DtCm_add_to_entry_list(entry->cal,
  854. (caddr_t)elist);
  855. stat = _DtCm_libentry_to_entryh(elist, number_entries,
  856. entries);
  857. }
  858. }
  859. return (stat);
  860. }
  861. /*
  862. * Due to the implementation of existing backends (versions 2-4)
  863. * which will unmanage any reminders that happens before the
  864. * the given tick, the user specified tick is ignore and
  865. * we will pass in the current time.
  866. */
  867. extern CSA_return_code
  868. csa_read_next_reminder(
  869. CSA_session_handle session,
  870. CSA_uint32 number_names,
  871. CSA_attribute_reference *reminder_names,
  872. CSA_date_time given_time,
  873. CSA_uint32 *number_reminders,
  874. CSA_reminder_reference **reminders,
  875. CSA_extension *read_next_reminder_extensions)
  876. {
  877. CSA_return_code stat;
  878. Calendar *cal;
  879. _DtCm_libentry *eptr, *prev = NULL, *head = NULL;
  880. int i;
  881. time_t timeval;
  882. DP(("api.c: csa_read_next_reminder\n"));
  883. /* get calendar object */
  884. if ((cal = _DtCm_get_Calendar(session)) == NULL)
  885. return (CSA_E_INVALID_SESSION_HANDLE);
  886. if (number_reminders == 0 || reminders == NULL)
  887. return (CSA_E_INVALID_PARAMETER);
  888. if (given_time == NULL || _csa_iso8601_to_tick(given_time, &timeval))
  889. return (CSA_E_INVALID_DATE_TIME);
  890. /*
  891. * check read_next_reminder_extensions and
  892. * return appropriate return code
  893. * no function extension is supported
  894. */
  895. if (read_next_reminder_extensions != NULL)
  896. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  897. /* lookup reminders */
  898. if ((stat = _DtCm_rpc_lookup_reminder(cal, timeval,
  899. number_names, reminder_names, number_reminders, reminders))
  900. == CSA_SUCCESS) {
  901. /*
  902. * link up all associated entries
  903. * and add to calendar structure
  904. */
  905. for (i = 0; i < *number_reminders; i++) {
  906. eptr = (_DtCm_libentry *)((*reminders)[i]).entry;
  907. /* link entry back to cal */
  908. eptr->cal = cal;
  909. /* link up entries in the same order as
  910. * the associated reminders
  911. */
  912. if (head == NULL)
  913. head = eptr;
  914. else {
  915. prev->next = eptr;
  916. eptr->prev = prev;
  917. }
  918. prev = eptr;
  919. }
  920. (void)_DtCm_add_to_entry_list(cal, (caddr_t)head);
  921. }
  922. return (stat);
  923. }
  924. /*
  925. * These arguments are ignored in this implementation:
  926. * session, update_propagation
  927. */
  928. extern CSA_return_code
  929. csa_update_entry_attributes(
  930. CSA_session_handle session,
  931. CSA_entry_handle entry,
  932. CSA_enum scope,
  933. CSA_boolean update_propagation,
  934. CSA_uint32 num_attrs,
  935. CSA_attribute *attrs,
  936. CSA_entry_handle *new_entry,
  937. CSA_extension *update_entry_attributes_extensions)
  938. {
  939. CSA_return_code stat;
  940. _DtCm_libentry *oentry, *nentry;
  941. DP(("api.c: csa_update_entry_attributes\n"));
  942. /* get entry object */
  943. if ((oentry = _DtCm_get_libentry(entry)) == NULL)
  944. return (CSA_E_INVALID_ENTRY_HANDLE);
  945. if (scope < CSA_SCOPE_ALL || scope > CSA_SCOPE_FORWARD)
  946. return (CSA_E_INVALID_ENUM);
  947. if (num_attrs == 0 || attrs == NULL)
  948. return (CSA_E_INVALID_PARAMETER);
  949. /*
  950. * check update_entry_attributes_extensions and
  951. * return appropriate return code
  952. * no function extension is supported
  953. */
  954. if (update_entry_attributes_extensions != NULL)
  955. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  956. /* check data type, readonly attributes, etc */
  957. if ((stat = _DtCm_check_entry_attributes(oentry->cal->file_version,
  958. num_attrs, attrs, CSA_CB_ENTRY_UPDATED, B_TRUE)) != CSA_SUCCESS) {
  959. return (stat);
  960. }
  961. /* change entry in calendar */
  962. if ((stat = _DtCm_rpc_update_entry(oentry->cal, oentry, num_attrs,
  963. attrs, scope, &nentry)) == CSA_SUCCESS) {
  964. if (new_entry) {
  965. if ((nentry = _DtCm_convert_entry_wheader(nentry))
  966. == NULL)
  967. stat = CSA_E_INSUFFICIENT_MEMORY;
  968. else {
  969. _DtCm_add_to_entry_list(oentry->cal,
  970. (caddr_t)nentry);
  971. *new_entry = (CSA_entry_handle)nentry;
  972. }
  973. } else
  974. _DtCm_free_libentries(nentry);
  975. }
  976. return (stat);
  977. }
  978. /* ADD EVENT */
  979. extern CSA_return_code
  980. csa_add_event(
  981. CSA_service_reference calendar_service,
  982. CSA_string calendar_address,
  983. CSA_string logon_user,
  984. CSA_string logon_password,
  985. CSA_string attendee,
  986. CSA_enum attendee_priority,
  987. CSA_enum attendee_status,
  988. CSA_boolean attendee_rsvp_requested,
  989. CSA_date_time start_date,
  990. CSA_date_time end_date,
  991. CSA_string organizer,
  992. CSA_string sponsor,
  993. CSA_string summary,
  994. CSA_string description,
  995. CSA_string recurrence_rule,
  996. CSA_string exception_rule,
  997. CSA_string subtype,
  998. CSA_enum classification,
  999. CSA_string delimiters,
  1000. CSA_string add_event_extensions)
  1001. {
  1002. DP(("api.c: csa_add_event\n"));
  1003. return (CSA_E_NOT_SUPPORTED);
  1004. }
  1005. /* ADD TODO */
  1006. CSA_return_code
  1007. csa_add_todo(
  1008. CSA_service_reference calendar_service,
  1009. CSA_string calendar_address,
  1010. CSA_string logon_user,
  1011. CSA_string logon_password,
  1012. CSA_enum attendee_priority,
  1013. CSA_enum attendee_status,
  1014. CSA_boolean attendee_rsvp_requested,
  1015. CSA_date_time start_date,
  1016. CSA_date_time due_date,
  1017. CSA_uint32 priority,
  1018. CSA_string summary,
  1019. CSA_string description,
  1020. CSA_enum classification,
  1021. CSA_string delimiters,
  1022. CSA_string add_todo_extensions)
  1023. {
  1024. DP(("api.c: csa_add_todo\n"));
  1025. return (CSA_E_NOT_SUPPORTED);
  1026. }
  1027. /* ADD MEMO */
  1028. CSA_return_code
  1029. csa_add_memo(
  1030. CSA_service_reference calendar_service,
  1031. CSA_string calendar_address,
  1032. CSA_string logon_user,
  1033. CSA_string logon_password,
  1034. CSA_date_time start_date,
  1035. CSA_string summary,
  1036. CSA_string delimiters,
  1037. CSA_string add_memo_extensions)
  1038. {
  1039. DP(("api.c: csa_add_memo\n"));
  1040. return (CSA_E_NOT_SUPPORTED);
  1041. }
  1042. /******************************************************************************
  1043. * static functions used within in the file
  1044. ******************************************************************************/
  1045. static CSA_return_code
  1046. _handle_register_callback_ext(CSA_extension *ext)
  1047. {
  1048. int i;
  1049. for (i = 0; ; i++) {
  1050. if (ext[i].item_code == CSA_X_XT_APP_CONTEXT_EXT) {
  1051. _DtCm_register_xtcallback(
  1052. (XtAppContext)ext[i].item_data);
  1053. } else
  1054. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  1055. if (ext[i].extension_flags & CSA_EXT_LAST_ELEMENT)
  1056. break;
  1057. }
  1058. return (CSA_SUCCESS);
  1059. }
  1060. static CSA_return_code
  1061. _handle_logon_ext(CSA_extension *ext, CSA_extension **pext)
  1062. {
  1063. int i;
  1064. int get_access_index = -1;
  1065. int com_support_index = -1;
  1066. for (i = 0; ; i++) {
  1067. if (ext[i].item_code == CSA_X_DT_GET_USER_ACCESS_EXT)
  1068. get_access_index = i;
  1069. else if (ext[i].item_code == CSA_X_COM_SUPPORT_EXT)
  1070. com_support_index = i;
  1071. else
  1072. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  1073. if (ext[i].extension_flags & CSA_EXT_LAST_ELEMENT)
  1074. break;
  1075. }
  1076. if (get_access_index >= 0)
  1077. *pext = &ext[get_access_index];
  1078. if (com_support_index >= 0)
  1079. _handle_com_support_ext(&ext[com_support_index]);
  1080. return (CSA_SUCCESS);
  1081. }
  1082. static CSA_return_code
  1083. _handle_query_config_ext(CSA_extension *ext)
  1084. {
  1085. int i;
  1086. int com_support_index = -1;
  1087. for (i = 0; ; i++) {
  1088. if (ext[i].item_code == CSA_X_COM_SUPPORT_EXT) {
  1089. com_support_index = i;
  1090. } else
  1091. return (CSA_E_UNSUPPORTED_FUNCTION_EXT);
  1092. if (ext[i].extension_flags & CSA_EXT_LAST_ELEMENT)
  1093. break;
  1094. }
  1095. if (com_support_index >= 0)
  1096. _handle_com_support_ext(&ext[com_support_index]);
  1097. return (CSA_SUCCESS);
  1098. }
  1099. static void
  1100. _handle_com_support_ext(CSA_extension *ext)
  1101. {
  1102. int i;
  1103. CSA_X_COM_support *xcom;
  1104. for (i = 0, xcom = ext->item_reference; i < ext->item_data; i++) {
  1105. switch (xcom[i].item_code) {
  1106. case CSA_X_COM_SUPPORT_EXT:
  1107. case CSA_X_XT_APP_CONTEXT_EXT:
  1108. case CSA_XS_DT:
  1109. case CSA_X_DT_GET_USER_ACCESS_EXT:
  1110. xcom[i].flags = CSA_X_COM_SUPPORTED;
  1111. break;
  1112. case CSA_XS_COM:
  1113. case CSA_X_UI_ID_EXT:
  1114. default:
  1115. xcom[i].flags = CSA_X_COM_NOT_SUPPORTED;
  1116. break;
  1117. }
  1118. }
  1119. }