2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: insert.c /main/5 1996/10/03 10:29:24 drk $ */
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.
31 #include <EUSCompat.h>
41 #if !defined(CSRG_BASED)
45 #include <sys/systeminfo.h>
49 #include "cmscalendar.h"
63 extern char *_DtCm_rule_buf; /* buffer to hold a rule for parser */
64 extern RepeatEvent *_DtCm_repeat_info; /* parsed recurrence info */
66 /******************************************************************************
67 * forward declaration of static functions used within the file
68 ******************************************************************************/
69 static boolean_t _IsOnetimeEntry(cms_entry *entry);
70 static CSA_return_code _RuleToRepeatInfo(cms_entry *entry, RepeatEvent *re);
71 static int _RuleToRepeatType(RepeatEvent *re);
72 static int _DailyRuleToRepeatType(RepeatEvent *re);
73 static int _WeeklyRuleToRepeatType(RepeatEvent *re);
74 static int _MonthlyRuleToRepeatType(RepeatEvent *re);
76 /*****************************************************************************
77 * extern functions used in the library
78 *****************************************************************************/
80 extern CSA_return_code
81 _DtCmsInsertEntry(_DtCmsCalendar *cal, cms_entry *entry)
85 List_node *lnode = NULL;
88 time_t key, tick, endtime;
92 RepeatEvent *re = NULL;
93 RepeatEventState *res;
94 extern void _DtCm_rule_parser();
98 if (cal == NULL || entry == NULL)
99 return (CSA_E_INVALID_PARAMETER);
101 /* assign key if this is a new appointment */
103 _DtCmsGenerateKey(cal, &(entry->key.id));
107 date = entry->attrs[CSA_ENTRY_ATTR_START_DATE_I].value->\
108 item.date_time_value;
109 _csa_iso8601_to_tick(date, &entry->key.time);
111 /* set reference id */
112 sprintf(buf, "%ld:%s@%s", entry->key.id, cal->calendar,
113 _DtCmGetHostAtDomain());
114 opq.size = strlen(buf);
115 opq.data = (unsigned char *)buf;
116 if ((stat = _DtCm_set_opaque_attrval(&opq,
117 &entry->attrs[CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I].value)) != CSA_SUCCESS) {
122 /* check recurrence rule */
123 if (_IsOnetimeEntry(entry) == B_FALSE) {
124 /* check recurrence rule */
125 aptr = &entry->attrs[CSA_ENTRY_ATTR_RECURRENCE_RULE_I];
126 _DtCm_rule_buf = aptr->value->item.string_value;
128 if ((re = _DtCm_repeat_info) == NULL)
129 return (CSA_E_INVALID_RULE);
131 /* get number of recurrences */
132 aptr = &entry->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I];
133 count = CountEvents(entry->key.time, re,
135 aptr->value->item.date_time_list_value : NULL));
138 /* turn into onetime entry */
139 _DtCmsConvertToOnetime(entry, re);
144 return (CSA_E_INVALID_RULE);
145 else if (count == RE_INFINITY)
146 count = CSA_X_DT_DT_REPEAT_FOREVER;
148 if ((stat = _DtCm_set_uint32_attrval(count,
149 &entry->attrs[CSA_ENTRY_ATTR_NUMBER_RECURRENCES_I].\
150 value)) != CSA_SUCCESS)
153 /* adjust start date */
154 tick = ClosestTick(entry->key.time, entry->key.time,
156 if (tick != entry->key.time &&
157 !_DtCmsInExceptionList(entry, tick)) {
160 _csa_tick_to_iso8601(tick, entry->attrs\
161 [CSA_ENTRY_ATTR_START_DATE_I].value->\
162 item.date_time_value);
165 _csa_iso8601_to_tick(entry->attrs\
166 [CSA_ENTRY_ATTR_END_DATE_I].value->\
167 item.date_time_value, &endtime);
168 endtime += (tick - entry->key.time);
169 _csa_tick_to_iso8601(endtime, entry->attrs\
170 [CSA_ENTRY_ATTR_END_DATE_I].value->\
171 item.date_time_value);
174 entry->key.time = tick;
179 if ((stat = _DtCmsCheckStartEndTime(entry)) != CSA_SUCCESS)
182 if ((stat = _RuleToRepeatInfo(entry, re)) != CSA_SUCCESS)
185 if ((stat = _DtCm_copy_cms_entry(entry, &newptr)) != CSA_SUCCESS)
188 /* Add the entry into the data structure */
190 rb_stat = rb_insert (cal->tree, (caddr_t)newptr,
191 (caddr_t)&(newptr->key));
193 rb_stat = hc_insert (REPT_LIST(cal), (caddr_t)newptr,
194 (caddr_t)&(newptr->key), re, &lnode);
197 if (rb_stat == rb_ok) {
198 /* Add the qualified reminder attrs to the reminder queue */
199 _DtCmsAddReminders4Entry(&cal->remq, newptr, lnode);
202 return (_DtCmsRbToCsaStat(rb_stat));
205 extern CSA_return_code
206 _DtCmsInsertEntryAndLog(_DtCmsCalendar *cal, cms_entry *entry)
208 CSA_return_code stat;
210 if ((stat = _DtCmsInsertEntry(cal, entry)) == CSA_SUCCESS) {
211 /* append entry to the log file */
212 if ((stat = _DtCmsV5TransactLog(cal, entry, _DtCmsLogAdd))
214 (void)_DtCmsDeleteEntry(cal, NULL, 0, &entry->key,
221 /*****************************************************************************
222 * static functions used within the file
223 *****************************************************************************/
226 _IsOnetimeEntry(cms_entry *entry)
230 if (entry->attrs[CSA_ENTRY_ATTR_RECURRENCE_RULE_I].value == NULL)
236 static CSA_return_code
237 _RuleToRepeatInfo(cms_entry *entry, RepeatEvent *re)
239 CSA_return_code stat;
245 return (_DtCm_set_sint32_attrval(CSA_X_DT_REPEAT_ONETIME,
246 &entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I].value));
248 if ((stat = _DtCm_set_sint32_attrval(_RuleToRepeatType(re),
249 &entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I].value))
253 type = entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I].value->\
256 if (re->re_duration != RE_NOTSET) {
257 if (re->re_duration == RE_INFINITY) {
259 } else if (type == CSA_X_DT_REPEAT_EVERY_NDAY ||
260 type == CSA_X_DT_REPEAT_EVERY_NWEEK ||
261 type == CSA_X_DT_REPEAT_EVERY_NMONTH) {
263 duration = re->re_duration * re->re_interval;
265 duration = re->re_duration;
267 if ((stat = _DtCm_set_uint32_attrval(duration,
268 &entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I].value))
273 if ((stat = _DtCm_set_uint32_attrval(re->re_interval,
274 &entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I].value))
278 if (_csa_tick_to_iso8601(re->re_end_date, buf) == 0) {
279 if ((stat = _DtCm_set_string_attrval(buf,
280 &entry->attrs[CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE_I].\
281 value, CSA_VALUE_DATE_TIME)) != CSA_SUCCESS)
285 return (CSA_SUCCESS);
289 _RuleToRepeatType(RepeatEvent *re)
291 switch (re->re_type) {
292 /* not supported in this release
296 return (_DailyRuleToRepeatType(re));
299 return (_WeeklyRuleToRepeatType(re));
301 case RT_MONTHLY_POSITION:
302 return (_MonthlyRuleToRepeatType(re));
305 return (_MonthlyRuleToRepeatType(re));
307 case RT_YEARLY_MONTH:
308 if ((re->re_data.re_yearly->yd_nitems == 1 ||
309 re->re_data.re_yearly->yd_nitems == 0) &&
310 re->re_interval == 1)
311 return (CSA_X_DT_REPEAT_YEARLY);
313 return (CSA_X_DT_REPEAT_OTHER_YEARLY);
316 return (CSA_X_DT_REPEAT_YEARLY);
319 return (CSA_X_DT_REPEAT_OTHER);
324 _DailyRuleToRepeatType(RepeatEvent *re)
326 if (re->re_interval == 1)
327 return (CSA_X_DT_REPEAT_DAILY);
329 return (CSA_X_DT_REPEAT_EVERY_NDAY);
332 #define _DtCms_MON_TO_FRI_MASK 0x3e
333 #define _DtCms_MON_WED_FRI_MASK 0x2a
334 #define _DtCms_TUE_THUR_MASK 0x14
337 _WeeklyRuleToRepeatType(RepeatEvent *re)
341 if (re->re_data.re_weekly->wd_ndaytime == 1 ||
342 re->re_data.re_weekly->wd_ndaytime == 0) {
343 if (re->re_interval == 1)
344 return (CSA_X_DT_REPEAT_WEEKLY);
345 else if (re->re_interval == 2)
346 return (CSA_X_DT_REPEAT_BIWEEKLY);
348 return (CSA_X_DT_REPEAT_EVERY_NWEEK);
349 } else if (re->re_interval > 1)
350 return (CSA_X_DT_REPEAT_OTHER_WEEKLY);
352 /* check for MWF, M-F, TuTh */
353 for (i = 0, mask = 0; i < re->re_data.re_weekly->wd_ndaytime; i++) {
354 temp = re->re_data.re_weekly->wd_daytime[i].dt_day;
355 temp = 0x1 << re->re_data.re_weekly->wd_daytime[i].dt_day;
356 mask |= (0x1 << re->re_data.re_weekly->wd_daytime[i].dt_day);
359 if (mask == _DtCms_MON_TO_FRI_MASK)
360 return (CSA_X_DT_REPEAT_MON_TO_FRI);
361 else if (mask == _DtCms_MON_WED_FRI_MASK)
362 return (CSA_X_DT_REPEAT_MONWEDFRI);
363 else if (mask == _DtCms_TUE_THUR_MASK)
364 return (CSA_X_DT_REPEAT_TUETHUR);
366 return (CSA_X_DT_REPEAT_WEEKDAYCOMBO);
370 _MonthlyRuleToRepeatType(RepeatEvent *re)
372 if (re->re_data.re_monthly->md_nitems == 1 ||
373 re->re_data.re_monthly->md_nitems == 0) {
374 if (re->re_interval == 1)
375 if (re->re_type == RT_MONTHLY_POSITION)
376 return (CSA_X_DT_REPEAT_MONTHLY_BY_WEEKDAY);
378 return (CSA_X_DT_REPEAT_MONTHLY_BY_DATE);
380 return (CSA_X_DT_REPEAT_EVERY_NMONTH);
382 return (CSA_X_DT_REPEAT_OTHER_MONTHLY);