convert4-5.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  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: convert4-5.c /main/1 1996/04/21 19:22:49 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. * Routines to convert data types used in version 4 to version 5.
  32. */
  33. #include <EUSCompat.h>
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <stdlib.h>
  37. #include "csa.h"
  38. #include "attr.h"
  39. #include "cmsdata.h"
  40. #include "convert4-5.h"
  41. #include "free.h"
  42. #include "iso8601.h"
  43. #include "lutil.h"
  44. #define V4_ATTR_NUM 13
  45. /*
  46. * forward declaration of static functions
  47. */
  48. static unsigned int accesstype4_to_accessright(int access);
  49. static CSA_return_code eventtype4_to_attrs(Event_Type_4 tag, uint num_attrs,
  50. cms_attribute *attrs);
  51. static CSA_return_code _RepeatInfoToRule(Appt_4 *a4,
  52. cms_attribute_value **attrval);
  53. /*****************************************************************************
  54. * extern functions
  55. *****************************************************************************/
  56. extern CSA_return_code
  57. _DtCm_accessentry4_to_cmsaccesslist(
  58. Access_Entry_4 *a4,
  59. cms_access_entry **alist)
  60. {
  61. CSA_return_code stat = CSA_SUCCESS;
  62. cms_access_entry *to, *head, *prev;
  63. head = prev = NULL;
  64. while (a4 != NULL) {
  65. if ((to = (cms_access_entry *)calloc(1,
  66. sizeof(cms_access_entry))) == NULL) {
  67. stat = CSA_E_INSUFFICIENT_MEMORY;
  68. break;
  69. }
  70. if (a4->who && (to->user = strdup(a4->who)) == NULL) {
  71. free(to);
  72. stat = CSA_E_INSUFFICIENT_MEMORY;
  73. break;
  74. }
  75. to->rights = accesstype4_to_accessright(a4->access_type);
  76. to->next = NULL;
  77. if (head == NULL)
  78. head = to;
  79. else
  80. prev->next = to;
  81. prev = to;
  82. a4 = a4->next;
  83. }
  84. if (stat != CSA_SUCCESS) {
  85. _DtCm_free_cms_access_entry(head);
  86. head = NULL;
  87. }
  88. *alist = head;
  89. return (stat);
  90. }
  91. extern CSA_return_code
  92. _DtCm_appt4_to_attrs(
  93. char *calname,
  94. Appt_4 *a4,
  95. uint num_attrs,
  96. cms_attribute *attrs,
  97. boolean_t rerule)
  98. {
  99. CSA_return_code stat = CSA_SUCCESS;
  100. Attribute_4 *reminders = a4->attr;
  101. char buf[BUFSIZ];
  102. CSA_opaque_data opq;
  103. int index, ntimes;
  104. char *ptr1, *ptr2;
  105. if (a4 == NULL || num_attrs < _DtCM_DEFINED_ENTRY_ATTR_SIZE)
  106. return (CSA_E_INVALID_PARAMETER);
  107. /* exception info is not converted since it's not used
  108. * and we don't have an attribute for it yet
  109. */
  110. while (stat == CSA_SUCCESS && reminders != NULL) {
  111. if ((index =
  112. _DtCm_old_reminder_name_to_index(reminders->attr)) >= 0) {
  113. if ((stat = _DtCmAttr4ToReminderValue(reminders,
  114. &attrs[index].value)) != CSA_SUCCESS) {
  115. break;
  116. }
  117. }
  118. reminders = reminders->next;
  119. }
  120. /* only contains the id now, need to
  121. * add calendar name and location info
  122. */
  123. if (a4->appt_id.key > 0) {
  124. ptr1 = strchr(calname, '@');
  125. ptr2 = (ptr1 ? strchr(ptr1, '.') : NULL);
  126. if (ptr1) {
  127. snprintf(buf, sizeof buf, "%ld:%s%s%s", a4->appt_id.key, calname,
  128. (ptr2 == NULL ? "." : ""),
  129. (ptr2 == NULL ? _DtCmGetLocalDomain(ptr1+1) :
  130. ""));
  131. } else {
  132. snprintf(buf, sizeof buf, "%ld:%s@%s", a4->appt_id.key, calname,
  133. _DtCmGetHostAtDomain());
  134. }
  135. opq.size = strlen(buf);
  136. opq.data = (unsigned char *)buf;
  137. }
  138. if (a4->period.period != single_4 &&
  139. a4->ntimes == _DtCM_OLD_REPEAT_FOREVER)
  140. ntimes = CSA_X_DT_DT_REPEAT_FOREVER;
  141. else
  142. ntimes = a4->ntimes;
  143. /* convert tick to iso8601 */
  144. if (stat != CSA_SUCCESS || (a4->appt_id.key > 0 &&
  145. (stat = _DtCm_set_opaque_attrval(&opq,
  146. &attrs[CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I].value))))
  147. ;
  148. else if ((stat = _csa_tick_to_iso8601(a4->appt_id.tick, buf) ?
  149. CSA_E_INVALID_DATE_TIME : CSA_SUCCESS) ||
  150. (stat = _DtCm_set_string_attrval(buf,
  151. &attrs[CSA_ENTRY_ATTR_START_DATE_I].value,CSA_VALUE_DATE_TIME)))
  152. ;
  153. else if (stat = eventtype4_to_attrs(a4->tag->tag, num_attrs, attrs))
  154. ;
  155. else if (stat = _DtCm_set_sint32_attrval(a4->tag->showtime,
  156. &attrs[CSA_X_DT_ENTRY_ATTR_SHOWTIME_I].value))
  157. ;
  158. else if ((stat = _csa_tick_to_iso8601(a4->appt_id.tick + a4->duration,
  159. buf) ? CSA_E_INVALID_DATE_TIME : CSA_SUCCESS) ||
  160. (stat = _DtCm_set_string_attrval(buf,
  161. &attrs[CSA_ENTRY_ATTR_END_DATE_I].value, CSA_VALUE_DATE_TIME)))
  162. ;
  163. else if (stat = _DtCm_set_string_attrval(a4->what,
  164. &attrs[CSA_ENTRY_ATTR_SUMMARY_I].value, CSA_VALUE_STRING))
  165. ;
  166. else if (stat = _DtCm_set_user_attrval(a4->author,
  167. &attrs[CSA_ENTRY_ATTR_ORGANIZER_I].value))
  168. ;
  169. else if (stat = _DtCm_set_uint32_attrval(_DtCm_apptstatus4_to_status(
  170. a4->appt_status), &attrs[CSA_ENTRY_ATTR_STATUS_I].value))
  171. ;
  172. else if (stat = _DtCm_set_uint32_attrval(
  173. _DtCm_privacy4_to_classification(a4->privacy),
  174. &attrs[CSA_ENTRY_ATTR_CLASSIFICATION_I].value))
  175. ;
  176. else if (rerule && (stat = _RepeatInfoToRule(a4,
  177. &attrs[CSA_ENTRY_ATTR_RECURRENCE_RULE_I].value)))
  178. ;
  179. else if (!rerule &&
  180. ((stat = _DtCm_set_uint32_attrval(ntimes,
  181. &attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I].value)) ||
  182. (stat = _DtCm_set_sint32_attrval(_DtCm_interval4_to_rtype(
  183. a4->period.period),
  184. &attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I].value)) ||
  185. (a4->period.period == nthWeekday_4 &&
  186. (stat = _DtCm_set_sint32_attrval(a4->period.nth, &attrs\
  187. [CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I].value))) ||
  188. (a4->period.period >= everyNthDay_4 &&
  189. a4->period.period <= everyNthMonth_4 &&
  190. (stat = _DtCm_set_uint32_attrval(a4->period.nth, &attrs\
  191. [CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I].value))) ||
  192. (a4->period.enddate != 0 &&
  193. ((stat = _csa_tick_to_iso8601(a4->period.enddate, buf) ?
  194. CSA_E_INVALID_DATE_TIME : CSA_SUCCESS) ||
  195. (stat = _DtCm_set_string_attrval(buf, &attrs\
  196. [CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE_I].value,
  197. CSA_VALUE_DATE_TIME))))))
  198. ;
  199. else {
  200. return (CSA_SUCCESS);
  201. }
  202. /* something wrong, need cleanup */
  203. /* free up all attribute values set so far */
  204. return (stat);
  205. }
  206. extern int
  207. _DtCm_eventtype4_to_type(Event_Type_4 tag)
  208. {
  209. switch (tag) {
  210. case appointment_4:
  211. case holiday_4:
  212. return (CSA_TYPE_EVENT);
  213. case toDo_4:
  214. return (CSA_TYPE_TODO);
  215. case reminder_4:
  216. case otherTag_4:
  217. default:
  218. return (CSA_X_DT_TYPE_OTHER);
  219. }
  220. }
  221. extern char *
  222. _DtCm_eventtype4_to_subtype(Event_Type_4 tag)
  223. {
  224. switch (tag) {
  225. case appointment_4:
  226. return (CSA_SUBTYPE_APPOINTMENT);
  227. case holiday_4:
  228. return (CSA_SUBTYPE_HOLIDAY);
  229. case toDo_4:
  230. case reminder_4:
  231. case otherTag_4:
  232. default:
  233. return ("");
  234. }
  235. }
  236. extern CSA_sint32
  237. _DtCm_interval4_to_rtype(Interval_4 val)
  238. {
  239. switch (val) {
  240. case single_4:
  241. return (CSA_X_DT_REPEAT_ONETIME);
  242. case weekly_4:
  243. return (CSA_X_DT_REPEAT_WEEKLY);
  244. case daily_4:
  245. return (CSA_X_DT_REPEAT_DAILY);
  246. case biweekly_4:
  247. return (CSA_X_DT_REPEAT_BIWEEKLY);
  248. case monthly_4:
  249. return (CSA_X_DT_REPEAT_MONTHLY_BY_DATE);
  250. case yearly_4:
  251. return (CSA_X_DT_REPEAT_YEARLY);
  252. case nthWeekday_4:
  253. return (CSA_X_DT_REPEAT_MONTHLY_BY_WEEKDAY);
  254. case everyNthDay_4:
  255. return (CSA_X_DT_REPEAT_EVERY_NDAY);
  256. case everyNthWeek_4:
  257. return (CSA_X_DT_REPEAT_EVERY_NWEEK);
  258. case everyNthMonth_4:
  259. return (CSA_X_DT_REPEAT_EVERY_NMONTH);
  260. case monThruFri_4:
  261. return (CSA_X_DT_REPEAT_MON_TO_FRI);
  262. case monWedFri_4:
  263. return (CSA_X_DT_REPEAT_MONWEDFRI);
  264. case tueThur_4:
  265. return (CSA_X_DT_REPEAT_TUETHUR);
  266. case daysOfWeek_4:
  267. return (CSA_X_DT_REPEAT_WEEKDAYCOMBO);
  268. case otherPeriod_4:
  269. default:
  270. return (CSA_X_DT_REPEAT_OTHER);
  271. }
  272. }
  273. extern CSA_sint32
  274. _DtCm_apptstatus4_to_status(Appt_Status_4 stat)
  275. {
  276. switch (stat) {
  277. case active_4:
  278. return (CSA_X_DT_STATUS_ACTIVE);
  279. case completed_4:
  280. return (CSA_STATUS_COMPLETED);
  281. case pendingAdd_4:
  282. return (CSA_X_DT_STATUS_ADD_PENDING);
  283. case pendingDelete_4:
  284. return (CSA_X_DT_STATUS_DELETE_PENDING);
  285. case committed_4:
  286. return (CSA_X_DT_STATUS_COMMITTED);
  287. case cancelled_4:
  288. return (CSA_X_DT_STATUS_CANCELLED);
  289. default:
  290. return (CSA_X_DT_STATUS_ACTIVE);
  291. }
  292. }
  293. extern CSA_sint32
  294. _DtCm_privacy4_to_classification(Privacy_Level_4 p)
  295. {
  296. switch (p) {
  297. case public_4:
  298. return (CSA_CLASS_PUBLIC);
  299. case semiprivate_4:
  300. return (CSA_CLASS_CONFIDENTIAL);
  301. case private_4:
  302. return (CSA_CLASS_PRIVATE);
  303. default:
  304. return (CSA_CLASS_PUBLIC);
  305. }
  306. }
  307. /******************************************************************************
  308. * static functions used within the file
  309. ******************************************************************************/
  310. /*
  311. * Static functions used within the file.
  312. */
  313. /*
  314. * DtCM_PERMIT_ACCESS is added for backward compatibility
  315. */
  316. static unsigned int
  317. accesstype4_to_accessright(int access)
  318. {
  319. unsigned int newaccess = 0;
  320. if (access & access_read_4)
  321. newaccess |= CSA_X_DT_BROWSE_ACCESS;
  322. if (access & access_write_4)
  323. newaccess |= CSA_X_DT_INSERT_ACCESS;
  324. if (access & access_delete_4)
  325. newaccess |= CSA_X_DT_DELETE_ACCESS;
  326. return (newaccess);
  327. }
  328. extern CSA_return_code
  329. _DtCmAttr4ToReminderValue(
  330. Attribute_4 *remval,
  331. cms_attribute_value **attrval)
  332. {
  333. CSA_reminder rval;
  334. char timestr[BUFSIZ];
  335. /*
  336. * rval is just a place holder, values will be
  337. * copied in _DtCm_set_reminder_attrval
  338. */
  339. _csa_duration_to_iso8601(atoi(remval->value), timestr);
  340. rval.lead_time = timestr;
  341. if (remval->clientdata && *remval->clientdata != '\0') {
  342. rval.reminder_data.size = strlen(remval->clientdata);
  343. rval.reminder_data.data = (unsigned char *)remval->clientdata;
  344. } else {
  345. rval.reminder_data.size = 0;
  346. rval.reminder_data.data = NULL;
  347. }
  348. rval.snooze_time = NULL;
  349. rval.repeat_count = 0;
  350. return (_DtCm_set_reminder_attrval(&rval, attrval));
  351. }
  352. static CSA_return_code
  353. eventtype4_to_attrs(Event_Type_4 tag, uint num_attrs, cms_attribute *attrs)
  354. {
  355. CSA_return_code stat;
  356. switch (tag) {
  357. case appointment_4:
  358. if ((stat = _DtCm_set_uint32_attrval(CSA_TYPE_EVENT,
  359. &attrs[CSA_ENTRY_ATTR_TYPE_I].value)) != CSA_SUCCESS)
  360. return (stat);
  361. return (_DtCm_set_string_attrval(CSA_SUBTYPE_APPOINTMENT,
  362. &attrs[CSA_ENTRY_ATTR_SUBTYPE_I].value,
  363. CSA_VALUE_STRING));
  364. case toDo_4:
  365. return (_DtCm_set_uint32_attrval(CSA_TYPE_TODO,
  366. &attrs[CSA_ENTRY_ATTR_TYPE_I].value));
  367. case holiday_4:
  368. if ((stat = _DtCm_set_uint32_attrval(CSA_TYPE_EVENT,
  369. &attrs[CSA_ENTRY_ATTR_TYPE_I].value)) != CSA_SUCCESS)
  370. return (stat);
  371. return (_DtCm_set_string_attrval(CSA_SUBTYPE_HOLIDAY,
  372. &attrs[CSA_ENTRY_ATTR_SUBTYPE_I].value,
  373. CSA_VALUE_STRING));
  374. case reminder_4:
  375. case otherTag_4:
  376. default:
  377. return (_DtCm_set_uint32_attrval(CSA_X_DT_TYPE_OTHER,
  378. &attrs[CSA_ENTRY_ATTR_TYPE_I].value));
  379. }
  380. }
  381. static CSA_return_code
  382. _RepeatInfoToRule(Appt_4 *a4, cms_attribute_value **attrval)
  383. {
  384. char buf[BUFSIZ], datestr[25];
  385. uint duration;
  386. if (a4->period.period == single_4 || a4->period.period == otherPeriod_4) {
  387. *attrval = NULL;
  388. return (CSA_SUCCESS);
  389. }
  390. if (a4->ntimes == _DtCM_OLD_REPEAT_FOREVER) {
  391. duration = 0;
  392. } else if (a4->period.period >= everyNthDay_4 &&
  393. a4->period.period <= everyNthMonth_4) {
  394. duration = ((a4->ntimes % a4->period.nth) ? 1 : 0) +
  395. a4->ntimes/a4->period.nth;
  396. } else
  397. duration = a4->ntimes;
  398. switch (a4->period.period) {
  399. case daily_4:
  400. snprintf(buf, sizeof buf, "D1 #%d ", duration);
  401. break;
  402. case weekly_4:
  403. snprintf(buf, sizeof buf, "W1 #%d ", duration);
  404. break;
  405. case biweekly_4:
  406. snprintf(buf, sizeof buf, "W2 #%d ", duration);
  407. break;
  408. case monthly_4:
  409. snprintf(buf, sizeof buf, "MD1 #%d ", duration);
  410. break;
  411. case yearly_4:
  412. snprintf(buf, sizeof buf, "YM1 #%d ", duration);
  413. break;
  414. case nthWeekday_4:
  415. snprintf(buf, sizeof buf, "MP1 #%d ", duration);
  416. break;
  417. case everyNthDay_4:
  418. snprintf(buf, sizeof buf, "D%d #%d ", a4->period.nth, duration);
  419. break;
  420. case everyNthWeek_4:
  421. snprintf(buf, sizeof buf, "W%d #%d ", a4->period.nth, duration);
  422. break;
  423. case everyNthMonth_4:
  424. snprintf(buf, sizeof buf, "MD%d #%d ", a4->period.nth, duration);
  425. break;
  426. case monThruFri_4:
  427. snprintf(buf, sizeof buf, "W1 MO TU WE TH FR #%d ", duration);
  428. break;
  429. case monWedFri_4:
  430. snprintf(buf, sizeof buf, "W1 MO WE FR #%d ", duration);
  431. break;
  432. case tueThur_4:
  433. snprintf(buf, sizeof buf, "W1 TU TH #%d ", duration);
  434. break;
  435. case daysOfWeek_4:
  436. snprintf(buf, sizeof buf, "W1 #%d ", duration);
  437. /* XXX strcat is unsafe here */
  438. if (a4->period.nth & 0x1) strcat(buf, "SU ");
  439. if (a4->period.nth & 0x2) strcat(buf, "MO ");
  440. if (a4->period.nth & 0x4) strcat(buf, "TU ");
  441. if (a4->period.nth & 0x8) strcat(buf, "WE ");
  442. if (a4->period.nth & 0x10) strcat(buf, "TH ");
  443. if (a4->period.nth & 0x20) strcat(buf, "FR ");
  444. if (a4->period.nth & 0x40) strcat(buf, "SA ");
  445. break;
  446. }
  447. if (a4->period.enddate) {
  448. if (_csa_tick_to_iso8601(a4->period.enddate, datestr))
  449. return (CSA_E_INVALID_DATE_TIME);
  450. strcat(buf, datestr);
  451. }
  452. return (_DtCm_set_string_attrval(buf, attrval, CSA_VALUE_STRING));
  453. }