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>
43 #include <sys/systeminfo.h>
47 #include "cmscalendar.h"
61 extern char *_DtCm_rule_buf; /* buffer to hold a rule for parser */
62 extern RepeatEvent *_DtCm_repeat_info; /* parsed recurrence info */
64 /******************************************************************************
65 * forward declaration of static functions used within the file
66 ******************************************************************************/
67 static boolean_t _IsOnetimeEntry(cms_entry *entry);
68 static CSA_return_code _RuleToRepeatInfo(cms_entry *entry, RepeatEvent *re);
69 static int _RuleToRepeatType(RepeatEvent *re);
70 static int _DailyRuleToRepeatType(RepeatEvent *re);
71 static int _WeeklyRuleToRepeatType(RepeatEvent *re);
72 static int _MonthlyRuleToRepeatType(RepeatEvent *re);
74 /*****************************************************************************
75 * extern functions used in the library
76 *****************************************************************************/
78 extern CSA_return_code
79 _DtCmsInsertEntry(_DtCmsCalendar *cal, cms_entry *entry)
83 List_node *lnode = NULL;
86 time_t key, tick, endtime;
90 RepeatEvent *re = NULL;
91 RepeatEventState *res;
92 extern void _DtCm_rule_parser();
96 if (cal == NULL || entry == NULL)
97 return (CSA_E_INVALID_PARAMETER);
99 /* assign key if this is a new appointment */
101 _DtCmsGenerateKey(cal, &(entry->key.id));
105 date = entry->attrs[CSA_ENTRY_ATTR_START_DATE_I].value->\
106 item.date_time_value;
107 _csa_iso8601_to_tick(date, &entry->key.time);
109 /* set reference id */
110 sprintf(buf, "%ld:%s@%s", entry->key.id, cal->calendar,
111 _DtCmGetHostAtDomain());
112 opq.size = strlen(buf);
113 opq.data = (unsigned char *)buf;
114 if ((stat = _DtCm_set_opaque_attrval(&opq,
115 &entry->attrs[CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I].value)) != CSA_SUCCESS) {
120 /* check recurrence rule */
121 if (_IsOnetimeEntry(entry) == B_FALSE) {
122 /* check recurrence rule */
123 aptr = &entry->attrs[CSA_ENTRY_ATTR_RECURRENCE_RULE_I];
124 _DtCm_rule_buf = aptr->value->item.string_value;
126 if ((re = _DtCm_repeat_info) == NULL)
127 return (CSA_E_INVALID_RULE);
129 /* get number of recurrences */
130 aptr = &entry->attrs[CSA_ENTRY_ATTR_EXCEPTION_DATES_I];
131 count = CountEvents(entry->key.time, re,
133 aptr->value->item.date_time_list_value : NULL));
136 /* turn into onetime entry */
137 _DtCmsConvertToOnetime(entry, re);
142 return (CSA_E_INVALID_RULE);
143 else if (count == RE_INFINITY)
144 count = CSA_X_DT_DT_REPEAT_FOREVER;
146 if ((stat = _DtCm_set_uint32_attrval(count,
147 &entry->attrs[CSA_ENTRY_ATTR_NUMBER_RECURRENCES_I].\
148 value)) != CSA_SUCCESS)
151 /* adjust start date */
152 tick = ClosestTick(entry->key.time, entry->key.time,
154 if (tick != entry->key.time &&
155 !_DtCmsInExceptionList(entry, tick)) {
158 _csa_tick_to_iso8601(tick, entry->attrs\
159 [CSA_ENTRY_ATTR_START_DATE_I].value->\
160 item.date_time_value);
163 _csa_iso8601_to_tick(entry->attrs\
164 [CSA_ENTRY_ATTR_END_DATE_I].value->\
165 item.date_time_value, &endtime);
166 endtime += (tick - entry->key.time);
167 _csa_tick_to_iso8601(endtime, entry->attrs\
168 [CSA_ENTRY_ATTR_END_DATE_I].value->\
169 item.date_time_value);
172 entry->key.time = tick;
177 if ((stat = _DtCmsCheckStartEndTime(entry)) != CSA_SUCCESS)
180 if ((stat = _RuleToRepeatInfo(entry, re)) != CSA_SUCCESS)
183 if ((stat = _DtCm_copy_cms_entry(entry, &newptr)) != CSA_SUCCESS)
186 /* Add the entry into the data structure */
188 rb_stat = rb_insert (cal->tree, (caddr_t)newptr,
189 (caddr_t)&(newptr->key));
191 rb_stat = hc_insert (REPT_LIST(cal), (caddr_t)newptr,
192 (caddr_t)&(newptr->key), re, &lnode);
195 if (rb_stat == rb_ok) {
196 /* Add the qualified reminder attrs to the reminder queue */
197 _DtCmsAddReminders4Entry(&cal->remq, newptr, lnode);
200 return (_DtCmsRbToCsaStat(rb_stat));
203 extern CSA_return_code
204 _DtCmsInsertEntryAndLog(_DtCmsCalendar *cal, cms_entry *entry)
206 CSA_return_code stat;
208 if ((stat = _DtCmsInsertEntry(cal, entry)) == CSA_SUCCESS) {
209 /* append entry to the log file */
210 if ((stat = _DtCmsV5TransactLog(cal, entry, _DtCmsLogAdd))
212 (void)_DtCmsDeleteEntry(cal, NULL, 0, &entry->key,
219 /*****************************************************************************
220 * static functions used within the file
221 *****************************************************************************/
224 _IsOnetimeEntry(cms_entry *entry)
228 if (entry->attrs[CSA_ENTRY_ATTR_RECURRENCE_RULE_I].value == NULL)
234 static CSA_return_code
235 _RuleToRepeatInfo(cms_entry *entry, RepeatEvent *re)
237 CSA_return_code stat;
243 return (_DtCm_set_sint32_attrval(CSA_X_DT_REPEAT_ONETIME,
244 &entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I].value));
246 if ((stat = _DtCm_set_sint32_attrval(_RuleToRepeatType(re),
247 &entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I].value))
251 type = entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I].value->\
254 if (re->re_duration != RE_NOTSET) {
255 if (re->re_duration == RE_INFINITY) {
257 } else if (type == CSA_X_DT_REPEAT_EVERY_NDAY ||
258 type == CSA_X_DT_REPEAT_EVERY_NWEEK ||
259 type == CSA_X_DT_REPEAT_EVERY_NMONTH) {
261 duration = re->re_duration * re->re_interval;
263 duration = re->re_duration;
265 if ((stat = _DtCm_set_uint32_attrval(duration,
266 &entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I].value))
271 if ((stat = _DtCm_set_uint32_attrval(re->re_interval,
272 &entry->attrs[CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I].value))
276 if (_csa_tick_to_iso8601(re->re_end_date, buf) == 0) {
277 if ((stat = _DtCm_set_string_attrval(buf,
278 &entry->attrs[CSA_X_DT_ENTRY_ATTR_SEQUENCE_END_DATE_I].\
279 value, CSA_VALUE_DATE_TIME)) != CSA_SUCCESS)
283 return (CSA_SUCCESS);
287 _RuleToRepeatType(RepeatEvent *re)
289 switch (re->re_type) {
290 /* not supported in this release
294 return (_DailyRuleToRepeatType(re));
297 return (_WeeklyRuleToRepeatType(re));
299 case RT_MONTHLY_POSITION:
300 return (_MonthlyRuleToRepeatType(re));
303 return (_MonthlyRuleToRepeatType(re));
305 case RT_YEARLY_MONTH:
306 if ((re->re_data.re_yearly->yd_nitems == 1 ||
307 re->re_data.re_yearly->yd_nitems == 0) &&
308 re->re_interval == 1)
309 return (CSA_X_DT_REPEAT_YEARLY);
311 return (CSA_X_DT_REPEAT_OTHER_YEARLY);
314 return (CSA_X_DT_REPEAT_YEARLY);
317 return (CSA_X_DT_REPEAT_OTHER);
322 _DailyRuleToRepeatType(RepeatEvent *re)
324 if (re->re_interval == 1)
325 return (CSA_X_DT_REPEAT_DAILY);
327 return (CSA_X_DT_REPEAT_EVERY_NDAY);
330 #define _DtCms_MON_TO_FRI_MASK 0x3e
331 #define _DtCms_MON_WED_FRI_MASK 0x2a
332 #define _DtCms_TUE_THUR_MASK 0x14
335 _WeeklyRuleToRepeatType(RepeatEvent *re)
339 if (re->re_data.re_weekly->wd_ndaytime == 1 ||
340 re->re_data.re_weekly->wd_ndaytime == 0) {
341 if (re->re_interval == 1)
342 return (CSA_X_DT_REPEAT_WEEKLY);
343 else if (re->re_interval == 2)
344 return (CSA_X_DT_REPEAT_BIWEEKLY);
346 return (CSA_X_DT_REPEAT_EVERY_NWEEK);
347 } else if (re->re_interval > 1)
348 return (CSA_X_DT_REPEAT_OTHER_WEEKLY);
350 /* check for MWF, M-F, TuTh */
351 for (i = 0, mask = 0; i < re->re_data.re_weekly->wd_ndaytime; i++) {
352 temp = re->re_data.re_weekly->wd_daytime[i].dt_day;
353 temp = 0x1 << re->re_data.re_weekly->wd_daytime[i].dt_day;
354 mask |= (0x1 << re->re_data.re_weekly->wd_daytime[i].dt_day);
357 if (mask == _DtCms_MON_TO_FRI_MASK)
358 return (CSA_X_DT_REPEAT_MON_TO_FRI);
359 else if (mask == _DtCms_MON_WED_FRI_MASK)
360 return (CSA_X_DT_REPEAT_MONWEDFRI);
361 else if (mask == _DtCms_TUE_THUR_MASK)
362 return (CSA_X_DT_REPEAT_TUETHUR);
364 return (CSA_X_DT_REPEAT_WEEKDAYCOMBO);
368 _MonthlyRuleToRepeatType(RepeatEvent *re)
370 if (re->re_data.re_monthly->md_nitems == 1 ||
371 re->re_data.re_monthly->md_nitems == 0) {
372 if (re->re_interval == 1)
373 if (re->re_type == RT_MONTHLY_POSITION)
374 return (CSA_X_DT_REPEAT_MONTHLY_BY_WEEKDAY);
376 return (CSA_X_DT_REPEAT_MONTHLY_BY_DATE);
378 return (CSA_X_DT_REPEAT_EVERY_NMONTH);
380 return (CSA_X_DT_REPEAT_OTHER_MONTHLY);