1 /* $XConsortium: insert.c /main/5 1996/10/03 10:29:24 drk $ */
3 * (c) Copyright 1993, 1994 Hewlett-Packard Company
4 * (c) Copyright 1993, 1994 International Business Machines Corp.
5 * (c) Copyright 1993, 1994 Novell, Inc.
6 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
21 #include <sys/systeminfo.h>
25 #include "cmscalendar.h"
39 extern char *_DtCm_rule_buf; /* buffer to hold a rule for parser */
40 extern RepeatEvent *_DtCm_repeat_info; /* parsed recurrence info */
42 /******************************************************************************
43 * forward declaration of static functions used within the file
44 ******************************************************************************/
45 static boolean_t _IsOnetimeEntry(cms_entry *entry);
46 static CSA_return_code _RuleToRepeatInfo(cms_entry *entry, RepeatEvent *re);
47 static int _RuleToRepeatType(RepeatEvent *re);
48 static int _DailyRuleToRepeatType(RepeatEvent *re);
49 static int _WeeklyRuleToRepeatType(RepeatEvent *re);
50 static int _MonthlyRuleToRepeatType(RepeatEvent *re);
52 /*****************************************************************************
53 * extern functions used in the library
54 *****************************************************************************/
56 extern CSA_return_code
57 _DtCmsInsertEntry(_DtCmsCalendar *cal, cms_entry *entry)
61 List_node *lnode = NULL;
64 time_t key, tick, endtime;
68 RepeatEvent *re = NULL;
69 RepeatEventState *res;
70 extern void _DtCm_rule_parser();
74 if (cal == NULL || entry == NULL)
75 return (CSA_E_INVALID_PARAMETER);
77 /* assign key if this is a new appointment */
79 _DtCmsGenerateKey(cal, &(entry->key.id));
83 date = entry->attrs[CSA_ENTRY_ATTR_START_DATE_I].value->\
85 _csa_iso8601_to_tick(date, &entry->key.time);
87 /* set reference id */
88 sprintf(buf, "%ld:%s@%s", entry->key.id, cal->calendar,
89 _DtCmGetHostAtDomain());
90 opq.size = strlen(buf);
91 opq.data = (unsigned char *)buf;
92 if ((stat = _DtCm_set_opaque_attrval(&opq,
93 &entry->attrs[CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I].value)) != CSA_SUCCESS) {
98 /* check recurrence rule */
99 if (_IsOnetimeEntry(entry) == B_FALSE) {
100 /* check recurrence rule */
101 aptr = &entry->attrs[CSA_ENTRY_ATTR_RECURRENCE_RULE_I];
102 _DtCm_rule_buf = aptr->value->item.string_value;
104 if ((re = _DtCm_repeat_info) == NULL)
105 return (CSA_E_INVALID_RULE);
107 /* get number of recurrences */
108 aptr = &entry->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I];
109 count = CountEvents(entry->key.time, re,
111 aptr->value->item.date_time_list_value : NULL));
114 /* turn into onetime entry */
115 _DtCmsConvertToOnetime(entry, re);
120 return (CSA_E_INVALID_RULE);
121 else if (count == RE_INFINITY)
122 count = CSA_X_DT_DT_REPEAT_FOREVER;
124 if ((stat = _DtCm_set_uint32_attrval(count,
125 &entry->attrs[CSA_ENTRY_ATTR_NUMBER_RECURRENCES_I].\
126 value)) != CSA_SUCCESS)
129 /* adjust start date */
130 tick = ClosestTick(entry->key.time, entry->key.time,
132 if (tick != entry->key.time &&
133 !_DtCmsInExceptionList(entry, tick)) {
136 _csa_tick_to_iso8601(tick, entry->attrs\
137 [CSA_ENTRY_ATTR_START_DATE_I].value->\
138 item.date_time_value);
141 _csa_iso8601_to_tick(entry->attrs\
142 [CSA_ENTRY_ATTR_END_DATE_I].value->\
143 item.date_time_value, &endtime);
144 endtime += (tick - entry->key.time);
145 _csa_tick_to_iso8601(endtime, entry->attrs\
146 [CSA_ENTRY_ATTR_END_DATE_I].value->\
147 item.date_time_value);
150 entry->key.time = tick;
155 if ((stat = _DtCmsCheckStartEndTime(entry)) != CSA_SUCCESS)
158 if ((stat = _RuleToRepeatInfo(entry, re)) != CSA_SUCCESS)
161 if ((stat = _DtCm_copy_cms_entry(entry, &newptr)) != CSA_SUCCESS)
164 /* Add the entry into the data structure */
166 rb_stat = rb_insert (cal->tree, (caddr_t)newptr,
167 (caddr_t)&(newptr->key));
169 rb_stat = hc_insert (REPT_LIST(cal), (caddr_t)newptr,
170 (caddr_t)&(newptr->key), re, &lnode);
173 if (rb_stat == rb_ok) {
174 /* Add the qualified reminder attrs to the reminder queue */
175 _DtCmsAddReminders4Entry(&cal->remq, newptr, lnode);
178 return (_DtCmsRbToCsaStat(rb_stat));
181 extern CSA_return_code
182 _DtCmsInsertEntryAndLog(_DtCmsCalendar *cal, cms_entry *entry)
184 CSA_return_code stat;
186 if ((stat = _DtCmsInsertEntry(cal, entry)) == CSA_SUCCESS) {
187 /* append entry to the log file */
188 if ((stat = _DtCmsV5TransactLog(cal, entry, _DtCmsLogAdd))
190 (void)_DtCmsDeleteEntry(cal, NULL, 0, &entry->key,
197 /*****************************************************************************
198 * static functions used within the file
199 *****************************************************************************/
202 _IsOnetimeEntry(cms_entry *entry)
206 if (entry->attrs[CSA_ENTRY_ATTR_RECURRENCE_RULE_I].value == NULL)
212 static CSA_return_code
213 _RuleToRepeatInfo(cms_entry *entry, RepeatEvent *re)
215 CSA_return_code stat;
221 return (_DtCm_set_sint32_attrval(CSA_X_DT_REPEAT_ONETIME,
222 &entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I].value));
224 if ((stat = _DtCm_set_sint32_attrval(_RuleToRepeatType(re),
225 &entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I].value))
229 type = entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I].value->\
232 if (re->re_duration != RE_NOTSET) {
233 if (re->re_duration == RE_INFINITY) {
235 } else if (type == CSA_X_DT_REPEAT_EVERY_NDAY ||
236 type == CSA_X_DT_REPEAT_EVERY_NWEEK ||
237 type == CSA_X_DT_REPEAT_EVERY_NMONTH) {
239 duration = re->re_duration * re->re_interval;
241 duration = re->re_duration;
243 if ((stat = _DtCm_set_uint32_attrval(duration,
244 &entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I].value))
249 if ((stat = _DtCm_set_uint32_attrval(re->re_interval,
250 &entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I].value))
254 if (_csa_tick_to_iso8601(re->re_end_date, buf) == 0) {
255 if ((stat = _DtCm_set_string_attrval(buf,
256 &entry->attrs[CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE_I].\
257 value, CSA_VALUE_DATE_TIME)) != CSA_SUCCESS)
261 return (CSA_SUCCESS);
265 _RuleToRepeatType(RepeatEvent *re)
267 switch (re->re_type) {
268 /* not supported in this release
272 return (_DailyRuleToRepeatType(re));
275 return (_WeeklyRuleToRepeatType(re));
277 case RT_MONTHLY_POSITION:
278 return (_MonthlyRuleToRepeatType(re));
281 return (_MonthlyRuleToRepeatType(re));
283 case RT_YEARLY_MONTH:
284 if ((re->re_data.re_yearly->yd_nitems == 1 ||
285 re->re_data.re_yearly->yd_nitems == 0) &&
286 re->re_interval == 1)
287 return (CSA_X_DT_REPEAT_YEARLY);
289 return (CSA_X_DT_REPEAT_OTHER_YEARLY);
292 return (CSA_X_DT_REPEAT_YEARLY);
295 return (CSA_X_DT_REPEAT_OTHER);
300 _DailyRuleToRepeatType(RepeatEvent *re)
302 if (re->re_interval == 1)
303 return (CSA_X_DT_REPEAT_DAILY);
305 return (CSA_X_DT_REPEAT_EVERY_NDAY);
308 #define _DtCms_MON_TO_FRI_MASK 0x3e
309 #define _DtCms_MON_WED_FRI_MASK 0x2a
310 #define _DtCms_TUE_THUR_MASK 0x14
313 _WeeklyRuleToRepeatType(RepeatEvent *re)
317 if (re->re_data.re_weekly->wd_ndaytime == 1 ||
318 re->re_data.re_weekly->wd_ndaytime == 0) {
319 if (re->re_interval == 1)
320 return (CSA_X_DT_REPEAT_WEEKLY);
321 else if (re->re_interval == 2)
322 return (CSA_X_DT_REPEAT_BIWEEKLY);
324 return (CSA_X_DT_REPEAT_EVERY_NWEEK);
325 } else if (re->re_interval > 1)
326 return (CSA_X_DT_REPEAT_OTHER_WEEKLY);
328 /* check for MWF, M-F, TuTh */
329 for (i = 0, mask = 0; i < re->re_data.re_weekly->wd_ndaytime; i++) {
330 temp = re->re_data.re_weekly->wd_daytime[i].dt_day;
331 temp = 0x1 << re->re_data.re_weekly->wd_daytime[i].dt_day;
332 mask |= (0x1 << re->re_data.re_weekly->wd_daytime[i].dt_day);
335 if (mask == _DtCms_MON_TO_FRI_MASK)
336 return (CSA_X_DT_REPEAT_MON_TO_FRI);
337 else if (mask == _DtCms_MON_WED_FRI_MASK)
338 return (CSA_X_DT_REPEAT_MONWEDFRI);
339 else if (mask == _DtCms_TUE_THUR_MASK)
340 return (CSA_X_DT_REPEAT_TUETHUR);
342 return (CSA_X_DT_REPEAT_WEEKDAYCOMBO);
346 _MonthlyRuleToRepeatType(RepeatEvent *re)
348 if (re->re_data.re_monthly->md_nitems == 1 ||
349 re->re_data.re_monthly->md_nitems == 0) {
350 if (re->re_interval == 1)
351 if (re->re_type == RT_MONTHLY_POSITION)
352 return (CSA_X_DT_REPEAT_MONTHLY_BY_WEEKDAY);
354 return (CSA_X_DT_REPEAT_MONTHLY_BY_DATE);
356 return (CSA_X_DT_REPEAT_EVERY_NMONTH);
358 return (CSA_X_DT_REPEAT_OTHER_MONTHLY);