1222 lines
29 KiB
C
1222 lines
29 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these libraries and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
/* $XConsortium: cmscalendar.c /main/4 1995/11/09 12:40:39 rswiston $ */
|
|
/*
|
|
* (c) Copyright 1993, 1994 Hewlett-Packard Company
|
|
* (c) Copyright 1993, 1994 International Business Machines Corp.
|
|
* (c) Copyright 1993, 1994 Novell, Inc.
|
|
* (c) Copyright 1993, 1994 Sun Microsystems, Inc.
|
|
*/
|
|
|
|
#include <EUSCompat.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <signal.h>
|
|
#include <sys/stat.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <pwd.h>
|
|
#include <time.h>
|
|
#ifdef SunOS
|
|
#include <sys/systeminfo.h>
|
|
#endif
|
|
#include "cmscalendar.h"
|
|
#include "access.h"
|
|
#include "attr.h"
|
|
#include "cm.h"
|
|
#include "rtable4.h"
|
|
#include "tree.h"
|
|
#include "list.h"
|
|
#include "log.h"
|
|
#include "appt4.h" /* Internal appointment data structure */
|
|
#include "cmsdata.h"
|
|
#include "cmsentry.h"
|
|
#include "callback.h"
|
|
#include "garbage.h"
|
|
#include "repeat.h"
|
|
#include "v4ops.h"
|
|
#include "v5ops.h"
|
|
#include "insert.h"
|
|
#include "updateattrs.h"
|
|
#include "reminder.h"
|
|
#include "misc.h"
|
|
#include "convert4-5.h"
|
|
#include "lutil.h"
|
|
|
|
extern int debug;
|
|
extern char *pgname;
|
|
|
|
/******************************************************************************
|
|
* forward declaration of static functions used within the file
|
|
******************************************************************************/
|
|
|
|
static CSA_return_code get_file_owner(char *log, char **owner);
|
|
static char * get_calname(char *target);
|
|
static CSA_return_code init_cal_attrs(_DtCmsCalendar *cal);
|
|
static CSA_return_code _GetCalendarSize(_DtCmsCalendar *cal, int index,
|
|
cms_attribute *attr);
|
|
static CSA_return_code _GetNumberEntries(_DtCmsCalendar *cal, int index,
|
|
cms_attribute *attr);
|
|
static CSA_return_code _GetAccessList(_DtCmsCalendar *cal, int index,
|
|
cms_attribute *attr);
|
|
static CSA_return_code _GetCalendarName(_DtCmsCalendar *cal, int index,
|
|
cms_attribute *attr);
|
|
static CSA_return_code _GetCalendarOwner(_DtCmsCalendar *cal, int index,
|
|
cms_attribute *attr);
|
|
static CSA_return_code _GetServerVersion(_DtCmsCalendar *cal, int index,
|
|
cms_attribute *attr);
|
|
static CSA_return_code _GetDataVersion(_DtCmsCalendar *cal, int index,
|
|
cms_attribute *attr);
|
|
static CSA_return_code _GetProductId(_DtCmsCalendar *cal, int index,
|
|
cms_attribute *attr);
|
|
static CSA_return_code _GetSupportedVersion(_DtCmsCalendar *cal, int index,
|
|
cms_attribute *attr);
|
|
static CSA_return_code _CopyCalendarAttr(_DtCmsCalendar *cal, int index,
|
|
cms_attribute *attr);
|
|
|
|
/* global variable shared with parser.y */
|
|
_DtCmsCalendar *currentCalendar;
|
|
|
|
/* static variables used within the file */
|
|
static _DtCmsCalendar *calendar_list = NULL;
|
|
|
|
static _DtCmGetAttrFunc _GetAttrFuncPtrs[] =
|
|
{ NULL,
|
|
_GetAccessList,
|
|
_GetCalendarName,
|
|
_GetCalendarOwner,
|
|
_GetCalendarSize,
|
|
_CopyCalendarAttr,
|
|
_CopyCalendarAttr,
|
|
_CopyCalendarAttr,
|
|
_CopyCalendarAttr,
|
|
_GetNumberEntries,
|
|
_GetProductId,
|
|
_CopyCalendarAttr,
|
|
_GetSupportedVersion,
|
|
_CopyCalendarAttr,
|
|
_GetServerVersion,
|
|
_GetDataVersion
|
|
};
|
|
|
|
/*****************************************************************************
|
|
* extern functions
|
|
*****************************************************************************/
|
|
|
|
extern _DtCmsCalendar *
|
|
_DtCmsMakeCalendar(char *owner, char *name)
|
|
{
|
|
_DtCmsCalendar *cal;
|
|
|
|
if ((cal = (_DtCmsCalendar *)calloc(1, sizeof(_DtCmsCalendar)))
|
|
== NULL) {
|
|
return (NULL);
|
|
}
|
|
|
|
cal->fversion = _DtCMS_VERSION4;
|
|
|
|
if (init_cal_attrs(cal) != CSA_SUCCESS) {
|
|
free(cal);
|
|
return (NULL);
|
|
}
|
|
|
|
if (_DtCm_set_string_attrval(owner,
|
|
&cal->attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].value,
|
|
CSA_VALUE_CALENDAR_USER)) {
|
|
_DtCmsFreeCalendar(cal);
|
|
return (NULL);
|
|
}
|
|
if ((cal->owner = strdup(cal->attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].\
|
|
value->item.string_value)) == NULL) {
|
|
_DtCmsFreeCalendar(cal);
|
|
return (NULL);
|
|
}
|
|
|
|
if (_DtCm_set_string_attrval(name,
|
|
&cal->attrs[CSA_CAL_ATTR_CALENDAR_NAME_I].value, CSA_VALUE_STRING))
|
|
{
|
|
_DtCmsFreeCalendar(cal);
|
|
return (NULL);
|
|
}
|
|
if ((cal->calendar = get_calname(name)) == NULL) {
|
|
_DtCmsFreeCalendar(cal);
|
|
return (NULL);
|
|
}
|
|
|
|
if ((cal->types = (int *)calloc(1, sizeof(int) *
|
|
(_DtCm_entry_name_tbl->size + 1))) == NULL) {
|
|
_DtCmsFreeCalendar(cal);
|
|
return (NULL);
|
|
} else
|
|
_DtCm_get_attribute_types(_DtCm_entry_name_tbl->size,
|
|
cal->types);
|
|
|
|
if (!(cal->tree = rb_create(_DtCmsGetEntryKey, _DtCmsCompareEntry))) {
|
|
_DtCmsFreeCalendar(cal);
|
|
return (NULL);
|
|
}
|
|
|
|
if (!(cal->list = hc_create(_DtCmsGetEntryKey, _DtCmsCompareRptEntry)))
|
|
{
|
|
_DtCmsFreeCalendar(cal);
|
|
return (NULL);
|
|
}
|
|
|
|
cal->cal_tbl = _DtCm_cal_name_tbl;
|
|
cal->entry_tbl = _DtCm_entry_name_tbl;
|
|
cal->num_entry_attrs = _DtCm_entry_name_tbl->size;
|
|
cal->getattrfuncs = _GetAttrFuncPtrs;
|
|
|
|
return (cal);
|
|
}
|
|
|
|
extern void
|
|
_DtCmsPutInCalList(_DtCmsCalendar *cal)
|
|
{
|
|
/* link with other calendar structures */
|
|
cal->next = calendar_list;
|
|
calendar_list = cal;
|
|
}
|
|
|
|
extern void
|
|
_DtCmsFreeCalendar(_DtCmsCalendar *cal)
|
|
{
|
|
_DtCmsCalendar *clist, *prev;
|
|
|
|
if (cal == NULL) return;
|
|
|
|
for (clist = calendar_list, prev = NULL; clist != NULL;
|
|
clist = clist->next) {
|
|
|
|
if (clist == cal) {
|
|
if (prev == NULL)
|
|
calendar_list = clist->next;
|
|
else
|
|
prev->next = clist->next;
|
|
|
|
break;
|
|
} else
|
|
prev = clist;
|
|
}
|
|
|
|
if (cal->calendar)
|
|
free(cal->calendar);
|
|
|
|
if (cal->owner)
|
|
free(cal->owner);
|
|
|
|
if (cal->fversion == 1) {
|
|
_DtCm_free_access_list4(GET_R_ACCESS ((cal)));
|
|
_DtCm_free_access_list4(GET_W_ACCESS ((cal)));
|
|
_DtCm_free_access_list4(GET_D_ACCESS ((cal)));
|
|
_DtCm_free_access_list4(GET_X_ACCESS ((cal)));
|
|
_DtCm_free_access_list4(cal->alist);
|
|
} else {
|
|
if (cal->cal_tbl != _DtCm_cal_name_tbl)
|
|
_DtCm_free_name_table(cal->cal_tbl);
|
|
|
|
if (cal->entry_tbl != _DtCm_entry_name_tbl)
|
|
_DtCm_free_name_table(cal->entry_tbl);
|
|
|
|
if (cal->types) free(cal->types);
|
|
|
|
if (cal->num_attrs) {
|
|
_DtCm_free_cms_attributes(cal->num_attrs + 1,
|
|
cal->attrs);
|
|
free(cal->attrs);
|
|
}
|
|
}
|
|
|
|
if (cal->tree)
|
|
rb_destroy(cal->tree, NULL);
|
|
|
|
if (cal->list)
|
|
hc_destroy(cal->list, NULL);
|
|
|
|
free(cal);
|
|
}
|
|
|
|
/*
|
|
* Called when loading data from callog file.
|
|
* Types of data to be stored in the tree and list structures
|
|
* depends on the version of the callog file.
|
|
*/
|
|
extern CSA_return_code
|
|
_DtCmsSetFileVersion(_DtCmsCalendar *cal, int version)
|
|
{
|
|
cal->fversion = version;
|
|
|
|
if (version == 1) {
|
|
if (!(cal->tree = rb_create(_DtCmsGetApptKey,
|
|
_DtCmsCompareAppt))) {
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
if (!(cal->list = hc_create(_DtCmsGetApptKey,
|
|
_DtCmsCompareRptAppt))) {
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
} else {
|
|
if (!(cal->tree = rb_create(_DtCmsGetEntryKey,
|
|
_DtCmsCompareEntry))) {
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
if (!(cal->list = hc_create(_DtCmsGetEntryKey,
|
|
_DtCmsCompareRptEntry))) {
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
if (init_cal_attrs(cal) != CSA_SUCCESS)
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
|
|
if ((cal->types = (int *)calloc(1, sizeof(int) *
|
|
(_DtCm_entry_name_tbl->size + 1))) == NULL) {
|
|
_DtCmsFreeCalendar(cal);
|
|
return (0);
|
|
} else
|
|
_DtCm_get_attribute_types(_DtCm_entry_name_tbl->size,
|
|
cal->types);
|
|
|
|
}
|
|
|
|
cal->cal_tbl = _DtCm_cal_name_tbl;
|
|
cal->entry_tbl = _DtCm_entry_name_tbl;
|
|
|
|
return (CSA_SUCCESS);
|
|
}
|
|
|
|
/* return value:
|
|
* 0 - file loaded successfully
|
|
* FILEERROR - file does not exist
|
|
* CERROR - something goes wrong
|
|
*/
|
|
extern CSA_return_code
|
|
start_log(_DtCmsCalendar *cal, char *filename)
|
|
{
|
|
int fd;
|
|
FILE *f;
|
|
char firstline[80], *numptr;
|
|
int version;
|
|
struct stat info;
|
|
struct passwd *pw;
|
|
extern void setinput(FILE *);
|
|
extern int yyyparse();
|
|
extern int yyywrap(FILE *);
|
|
|
|
if (cal == NULL || filename == NULL)
|
|
return(CSA_E_FAILURE);
|
|
|
|
if ((f = fopen(filename, "r")) == NULL) {
|
|
if (errno == ENOENT)
|
|
return(CSA_E_CALENDAR_NOT_EXIST);
|
|
else
|
|
return(CSA_X_DT_E_BACKING_STORE_PROBLEM);
|
|
}
|
|
|
|
setinput(f);
|
|
currentCalendar = cal;
|
|
if (yyyparse() == -1) {
|
|
fprintf(stderr, "%s: unable to parse %s\n", pgname, filename);
|
|
yyywrap(f);
|
|
return(CSA_X_DT_E_BACKING_STORE_PROBLEM);
|
|
}
|
|
yyywrap(f);
|
|
|
|
return(CSA_SUCCESS);
|
|
}
|
|
|
|
/*
|
|
* Load calendar data into memory from callog file.
|
|
*/
|
|
extern CSA_return_code
|
|
_DtCmsLoadCalendar(char *target, _DtCmsCalendar **infoptr)
|
|
{
|
|
CSA_return_code stat;
|
|
char *calname;
|
|
char *log;
|
|
_DtCmsCalendar *cal = NULL;
|
|
|
|
if (target == NULL || infoptr == NULL)
|
|
return (CSA_E_FAILURE);
|
|
|
|
*infoptr = NULL;
|
|
|
|
if ((calname = get_calname(target)) == NULL)
|
|
return(CSA_E_INSUFFICIENT_MEMORY);
|
|
|
|
if ((log = _DtCmsGetLogFN(calname)) == NULL)
|
|
{
|
|
free(calname);
|
|
return(CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
if ((cal = (_DtCmsCalendar *)calloc(1, sizeof(_DtCmsCalendar)))
|
|
== NULL) {
|
|
stat = CSA_E_INSUFFICIENT_MEMORY;
|
|
goto ERROR;
|
|
}
|
|
|
|
if (!(cal->calendar = (char *)strdup(calname))) {
|
|
stat = CSA_E_INSUFFICIENT_MEMORY;
|
|
goto ERROR;
|
|
}
|
|
|
|
/* load data from file */
|
|
if ((stat = start_log(cal, log)) != CSA_SUCCESS) {
|
|
goto ERROR;
|
|
}
|
|
|
|
/*
|
|
* get file owner after the file is loaded since file
|
|
* ownership might be fixed in start_log()
|
|
*/
|
|
if (cal->fversion == _DtCMS_VERSION1) {
|
|
if ((stat = get_file_owner(calname, &cal->owner))
|
|
!= CSA_SUCCESS)
|
|
goto ERROR;
|
|
|
|
cal->alist = _DtCmsCalendarAccessList(cal);
|
|
} else {
|
|
if (cal->attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].value)
|
|
cal->owner = strdup(cal->\
|
|
attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I].\
|
|
value->item.calendar_user_value);
|
|
else {
|
|
stat = CSA_X_DT_E_BACKING_STORE_PROBLEM;
|
|
fprintf(stderr, "%s: %s\n", pgname,
|
|
"calendar owner attribute is missing from callog file");
|
|
goto ERROR;
|
|
}
|
|
|
|
if (cal->attrs[CSA_CAL_ATTR_PRODUCT_IDENTIFIER_I].value == NULL)
|
|
{
|
|
if ((stat = _DtCm_set_string_attrval(
|
|
_DtCM_PRODUCT_IDENTIFIER, &cal->\
|
|
attrs[CSA_CAL_ATTR_PRODUCT_IDENTIFIER_I].value,
|
|
CSA_VALUE_STRING)) != CSA_SUCCESS) {
|
|
goto ERROR;
|
|
}
|
|
}
|
|
|
|
if (cal->attrs[CSA_CAL_ATTR_VERSION_I].value == NULL) {
|
|
if ((stat = _DtCm_set_string_attrval(
|
|
_DtCM_SPEC_VERSION_SUPPORTED,
|
|
&cal->attrs[CSA_CAL_ATTR_VERSION_I].value,
|
|
CSA_VALUE_STRING)) != CSA_SUCCESS) {
|
|
goto ERROR;
|
|
}
|
|
}
|
|
|
|
cal->num_entry_attrs = cal->entry_tbl->size;
|
|
}
|
|
|
|
cal->getattrfuncs = _GetAttrFuncPtrs;
|
|
|
|
/* link with other calendar structures */
|
|
cal->next = calendar_list;
|
|
calendar_list = cal;
|
|
|
|
free(log);
|
|
free(calname);
|
|
|
|
*infoptr = cal;
|
|
return (CSA_SUCCESS);
|
|
ERROR:
|
|
free(calname);
|
|
free(log);
|
|
|
|
_DtCmsFreeCalendar(cal);
|
|
return (stat);
|
|
}
|
|
|
|
extern char *
|
|
_DtCmsGetCalendarOwner(char *target)
|
|
{
|
|
char *name;
|
|
_DtCmsCalendar *clist = calendar_list;
|
|
|
|
if ((name = get_calname(target)) == NULL)
|
|
return(NULL);
|
|
|
|
while (clist != NULL) {
|
|
if (strcmp(name, clist->calendar) == 0) {
|
|
free(name);
|
|
return(clist->owner);
|
|
}
|
|
clist = clist->next;
|
|
}
|
|
free(name);
|
|
return(NULL);
|
|
}
|
|
|
|
extern CSA_return_code
|
|
_DtCmsGetCalendarByName(char *target, boolean_t load, _DtCmsCalendar **cal)
|
|
{
|
|
char *name;
|
|
_DtCmsCalendar *clist = calendar_list;
|
|
|
|
if ((name = get_calname(target)) == NULL)
|
|
return (0);
|
|
|
|
while (clist != NULL) {
|
|
if (strcmp (name, clist->calendar) == 0) {
|
|
free (name);
|
|
*cal = clist;
|
|
return (CSA_SUCCESS);
|
|
}
|
|
clist = clist->next;
|
|
}
|
|
free (name);
|
|
|
|
if (load == B_TRUE)
|
|
return (_DtCmsLoadCalendar(target, cal));
|
|
else {
|
|
*cal = NULL;
|
|
return (CSA_SUCCESS);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* For parser only.
|
|
*/
|
|
extern CSA_return_code
|
|
_DtCmsInsertAppt_for_parser(_DtCmsCalendar *cal, Appt_4 *appt)
|
|
{
|
|
return (_DtCmsInsertAppt(cal, appt));
|
|
}
|
|
|
|
/*
|
|
* For parser only.
|
|
*/
|
|
extern CSA_return_code
|
|
_DtCmsInsertEntry4Parser(_DtCmsCalendar *cal, cms_entry *entry)
|
|
{
|
|
cms_entry *eptr;
|
|
CSA_return_code stat;
|
|
|
|
if ((stat = _DtCmsMakeHashedEntry(cal, entry->num_attrs,
|
|
entry->attrs, &eptr)) != CSA_SUCCESS)
|
|
return (stat);
|
|
|
|
eptr->key = entry->key;
|
|
|
|
stat = _DtCmsInsertEntry(cal, eptr);
|
|
|
|
_DtCm_free_cms_entry(eptr);
|
|
|
|
return(stat);
|
|
}
|
|
|
|
extern void
|
|
_DtCmsGenerateKey(_DtCmsCalendar *cal, long *key)
|
|
{
|
|
if (*key == 0) {
|
|
*key = ++(cal->lastkey);
|
|
} else if (*key > cal->lastkey)
|
|
cal->lastkey = *key;
|
|
}
|
|
|
|
extern CSA_return_code
|
|
_DtCmsEnumerateUp(_DtCmsCalendar *cal, _DtCmsEnumerateProc doit)
|
|
{
|
|
if (cal == NULL || doit == NULL)
|
|
return (CSA_E_INVALID_PARAMETER);
|
|
if (rb_enumerate_up (APPT_TREE(cal), doit) != rb_ok ||
|
|
hc_enumerate_up (REPT_LIST(cal), doit) != rb_ok)
|
|
return (CSA_E_FAILURE);
|
|
else
|
|
return (CSA_SUCCESS);
|
|
}
|
|
|
|
extern void
|
|
_DtCmsEnumerateDown(_DtCmsCalendar *cal, _DtCmsEnumerateProc doit)
|
|
{
|
|
if (cal == NULL || doit == NULL)
|
|
return;
|
|
rb_enumerate_down (APPT_TREE(cal), doit);
|
|
hc_enumerate_down (REPT_LIST(cal), doit);
|
|
}
|
|
|
|
/*
|
|
* For parser only.
|
|
*/
|
|
extern void
|
|
_DtCmsSetAccess4Parser(
|
|
_DtCmsCalendar *cal,
|
|
Access_Entry_4 *list,
|
|
int type)
|
|
{
|
|
if (type == access_read_4)
|
|
SET_R_ACCESS(cal, list);
|
|
else if (type == access_write_4)
|
|
SET_W_ACCESS(cal, list);
|
|
else if (type == access_delete_4)
|
|
SET_D_ACCESS(cal, list);
|
|
else if (type == access_exec_4)
|
|
SET_X_ACCESS(cal, list);
|
|
}
|
|
|
|
extern void
|
|
_DtCmsSetCalendarAttrs4Parser(
|
|
_DtCmsCalendar *cal,
|
|
int len,
|
|
cms_attribute *attrs)
|
|
{
|
|
cms_attribute_value *val;
|
|
|
|
/* we don't want to free the value part of the access list
|
|
* attribute even it may be an empty list
|
|
*/
|
|
val = cal->attrs[CSA_CAL_ATTR_ACCESS_LIST_I].value;
|
|
cal->attrs[CSA_CAL_ATTR_ACCESS_LIST_I].value = NULL;
|
|
_DtCm_free_cms_attribute_values(cal->num_attrs, cal->attrs);
|
|
cal->attrs[CSA_CAL_ATTR_ACCESS_LIST_I].value = val;
|
|
|
|
(void)_DtCmUpdateAttributes(len, attrs, &cal->num_attrs, &cal->attrs,
|
|
&cal->cal_tbl, B_TRUE, NULL, B_FALSE);
|
|
}
|
|
|
|
extern CSA_return_code
|
|
_DtCmsRbToCsaStat(Rb_Status rb_stat)
|
|
{
|
|
if (rb_stat == rb_ok) {
|
|
return CSA_SUCCESS;
|
|
}
|
|
return CSA_E_FAILURE;
|
|
}
|
|
|
|
extern void
|
|
garbage_collect(void)
|
|
{
|
|
unsigned remain;
|
|
_DtCmsCalendar *clist = calendar_list;
|
|
|
|
while (clist != NULL) {
|
|
|
|
/* deregister stale client */
|
|
clist->rlist = _DtCmsCheckRegistrationList(clist->rlist);
|
|
|
|
if (clist->remq)
|
|
_DtCmsUpdateReminders(clist->remq);
|
|
|
|
if (clist->modified == B_TRUE) {
|
|
if (debug)
|
|
fprintf(stderr, "rpc.csmd: %s%s\n",
|
|
"do garbage collection on ",
|
|
clist->calendar);
|
|
_DtCmsCollectOne(clist);
|
|
clist->modified = B_FALSE;
|
|
}
|
|
|
|
clist = clist->next;
|
|
}
|
|
|
|
if ((remain = (unsigned) alarm((unsigned) 0)) == 0)
|
|
alarm ((unsigned) (3600L * 24L));
|
|
else
|
|
alarm (remain);
|
|
}
|
|
|
|
extern void
|
|
debug_switch(void)
|
|
{
|
|
_DtCmsCalendar *clist = calendar_list;
|
|
Access_Entry_4 *l;
|
|
|
|
debug = !debug;
|
|
fprintf (stderr, "Debug Mode is %s\n", debug ? "ON" : "OFF");
|
|
|
|
if (debug) {
|
|
while (clist != NULL) {
|
|
_DtCmsPrintReminderListV4(clist->rm_queue);
|
|
|
|
if ((l = _DtCmsCalendarAccessList(clist)) != NULL) {
|
|
_DtCmsShowAccessList(l);
|
|
_DtCm_free_access_list4(l);
|
|
}
|
|
clist = clist->next;
|
|
}
|
|
}
|
|
}
|
|
|
|
extern CSA_return_code
|
|
_DtCmsGetCalAttrsByName(
|
|
_DtCmsCalendar *cal,
|
|
uint num_names,
|
|
cms_attr_name *names,
|
|
uint *num_attrs_r,
|
|
cms_attribute **attrs_r)
|
|
{
|
|
CSA_return_code stat = CSA_SUCCESS;
|
|
int i, j, index = 0;
|
|
cms_attribute *attrs;
|
|
|
|
if ((attrs = calloc(1, sizeof(cms_attribute)*num_names)) == NULL)
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
|
|
/* get attributes */
|
|
for (i = 0, j = 0; i < num_names; i++) {
|
|
if (names[i].name == NULL)
|
|
continue;
|
|
|
|
if (names[i].num <= 0)
|
|
index = names[i].num = _DtCm_get_index_from_table(
|
|
cal->cal_tbl, names[i].name);
|
|
|
|
if (index > 0) {
|
|
if (index <= _DtCM_DEFINED_CAL_ATTR_SIZE) {
|
|
if (_CSA_cal_attr_info[index].fst_vers
|
|
<= cal->fversion
|
|
|| index == CSA_CAL_ATTR_CALENDAR_SIZE_I) {
|
|
stat = cal->getattrfuncs[index](cal,
|
|
index, &attrs[j]);
|
|
}
|
|
} else if (cal->attrs && cal->attrs[index].value) {
|
|
stat = _DtCm_copy_cms_attribute(&attrs[j],
|
|
&cal->attrs[index], B_TRUE);
|
|
}
|
|
|
|
if (stat != CSA_SUCCESS) {
|
|
_DtCm_free_cms_attributes(j, attrs);
|
|
free(attrs);
|
|
return (stat);
|
|
} else if (attrs[j].name.name)
|
|
j++;
|
|
}
|
|
}
|
|
|
|
if (j > 0) {
|
|
*num_attrs_r = j;
|
|
*attrs_r = attrs;
|
|
} else {
|
|
*num_attrs_r = 0;
|
|
*attrs_r = NULL;
|
|
free(attrs);
|
|
}
|
|
|
|
return (CSA_SUCCESS);
|
|
}
|
|
|
|
extern CSA_return_code
|
|
_DtCmsGetAllCalAttrs(
|
|
_DtCmsCalendar *cal,
|
|
uint *num_attrs_r,
|
|
cms_attribute **attrs_r,
|
|
boolean_t returnall)
|
|
{
|
|
CSA_return_code stat = CSA_SUCCESS;
|
|
cms_attribute *attrs, *cattrs = cal->attrs;
|
|
int i, j, num_cal_attrs = cal->num_attrs;
|
|
|
|
num_cal_attrs = cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ?
|
|
cal->num_attrs : _DtCM_OLD_CAL_ATTR_SIZE;
|
|
|
|
if ((attrs = calloc(1, sizeof(cms_attribute)*num_cal_attrs)) == NULL)
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
|
|
if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
|
|
/* first element is not used */
|
|
for (i = 1, j = 0; i <= num_cal_attrs; i++) {
|
|
if (i <= _DtCM_DEFINED_CAL_ATTR_SIZE) {
|
|
if ((stat = cal->getattrfuncs[i](cal, i,
|
|
&attrs[j])) != CSA_SUCCESS) {
|
|
_DtCm_free_cms_attributes(j, attrs);
|
|
free(attrs);
|
|
return (stat);
|
|
} else if (attrs[j].name.name)
|
|
j++;
|
|
} else if (cattrs[i].value) {
|
|
if (returnall) {
|
|
stat = _DtCm_copy_cms_attribute(
|
|
&attrs[j], &cal->attrs[i],
|
|
B_TRUE);
|
|
} else {
|
|
/* just return the attribute name */
|
|
if (attrs[j].name.name = strdup(
|
|
cattrs[i].name.name)) {
|
|
attrs[j].name.num =
|
|
cattrs[i].name.num;
|
|
} else
|
|
stat =CSA_E_INSUFFICIENT_MEMORY;
|
|
}
|
|
|
|
if (stat == CSA_SUCCESS)
|
|
j++;
|
|
else {
|
|
_DtCm_free_cms_attributes(j, attrs);
|
|
free(attrs);
|
|
return (stat);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
for (i = 1, j = 0; i <= _DtCM_DEFINED_CAL_ATTR_SIZE; i++) {
|
|
if (_CSA_cal_attr_info[i].fst_vers <= cal->fversion ||
|
|
i == CSA_CAL_ATTR_CALENDAR_SIZE_I)
|
|
{
|
|
if ((stat = cal->getattrfuncs[i](cal, i,
|
|
&attrs[j])) != CSA_SUCCESS) {
|
|
_DtCm_free_cms_attributes(j, attrs);
|
|
free(attrs);
|
|
return (stat);
|
|
} else if (attrs[j].name.name)
|
|
j++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (j > 0) {
|
|
*num_attrs_r = j;
|
|
*attrs_r = attrs;
|
|
} else {
|
|
*num_attrs_r = 0;
|
|
*attrs_r = NULL;
|
|
free(attrs);
|
|
}
|
|
|
|
return (CSA_SUCCESS);
|
|
}
|
|
|
|
extern CSA_return_code
|
|
_DtCmsGetCalAttrNames(
|
|
_DtCmsCalendar *cal,
|
|
uint *num_names_r,
|
|
cms_attr_name **names_r)
|
|
{
|
|
CSA_return_code stat = CSA_SUCCESS;
|
|
cms_attribute *attrs = cal->attrs;
|
|
cms_attr_name *names;
|
|
uint i, j, num_attrs = cal->num_attrs;
|
|
|
|
if ((names = calloc(1, sizeof(cms_attr_name)*num_attrs)) == NULL)
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
|
|
/* first element is not used */
|
|
for (i = 1, j = 0; i <= num_attrs; i++) {
|
|
if (attrs[i].value || (i == CSA_CAL_ATTR_CALENDAR_SIZE_I ||
|
|
i == CSA_CAL_ATTR_NUMBER_ENTRIES_I ||
|
|
i == CSA_X_DT_CAL_ATTR_SERVER_VERSION_I ||
|
|
i == CSA_X_DT_CAL_ATTR_DATA_VERSION_I ||
|
|
i == CSA_CAL_ATTR_ACCESS_LIST_I))
|
|
{
|
|
if (names[j].name = strdup(attrs[i].name.name)) {
|
|
names[j].num = attrs[i].name.num;
|
|
j++;
|
|
} else {
|
|
_DtCmsFreeCmsAttrNames(j, names);
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (j > 0) {
|
|
*num_names_r = j;
|
|
*names_r = names;
|
|
} else {
|
|
*num_names_r = 0;
|
|
*names_r = NULL;
|
|
free(names);
|
|
}
|
|
|
|
return (CSA_SUCCESS);
|
|
}
|
|
|
|
extern void
|
|
_DtCmsFreeCmsAttrNames(uint num, cms_attr_name *names)
|
|
{
|
|
uint i;
|
|
|
|
for (i = 0; i < num; i++)
|
|
if (names[i].name) free(names[i].name);
|
|
|
|
free(names);
|
|
}
|
|
|
|
extern CSA_return_code
|
|
_DtCmsUpdateCalAttributesAndLog(
|
|
_DtCmsCalendar *cal,
|
|
uint numsrc,
|
|
cms_attribute *srcattrs,
|
|
uint access)
|
|
{
|
|
CSA_return_code stat = CSA_SUCCESS;
|
|
uint i, oldnum = 0;
|
|
cms_attribute *oldattrs = NULL;
|
|
char *log;
|
|
|
|
/* we didn't use _DtCmUpdateAttributes because we need
|
|
* to check access rights here
|
|
*/
|
|
|
|
/* copy original attributes for rollback if update fails */
|
|
if (cal->attrs && (stat = _DtCm_copy_cms_attributes(cal->num_attrs,
|
|
cal->attrs, &oldnum, &oldattrs)) != CSA_SUCCESS)
|
|
return (stat);
|
|
|
|
for (i = 0; i < numsrc && stat == CSA_SUCCESS; i++) {
|
|
if (srcattrs[i].name.name == NULL)
|
|
continue;
|
|
|
|
if (srcattrs[i].name.num <= 0)
|
|
srcattrs[i].name.num = _DtCm_get_index_from_table(
|
|
cal->cal_tbl,
|
|
srcattrs[i].name.name);
|
|
|
|
if (srcattrs[i].name.num < 0) {
|
|
if (!_DTCMS_HAS_INSERT_CALENDAR_ATTR_ACCESS(access))
|
|
stat = CSA_E_NO_AUTHORITY;
|
|
else {
|
|
if ((stat = _DtCmExtendNameTable(
|
|
srcattrs[i].name.name, 0, 0,
|
|
_DtCm_cal_name_tbl,
|
|
_DtCM_DEFINED_CAL_ATTR_SIZE,
|
|
_CSA_calendar_attribute_names,
|
|
&cal->cal_tbl, NULL)) == CSA_SUCCESS) {
|
|
srcattrs[i].name.num =
|
|
cal->cal_tbl->size;
|
|
stat = _DtCmGrowAttrArray(
|
|
&cal->num_attrs, &cal->attrs,
|
|
&srcattrs[i]);
|
|
}
|
|
}
|
|
|
|
} else if (!_DTCMS_HAS_CHANGE_CALENDAR_ATTR_ACCESS(access)) {
|
|
|
|
stat = CSA_E_NO_AUTHORITY;
|
|
} else {
|
|
cms_attribute_value val;
|
|
|
|
if (srcattrs[i].name.num == CSA_CAL_ATTR_ACCESS_LIST_I
|
|
&& srcattrs[i].value == NULL) {
|
|
val.type = CSA_VALUE_ACCESS_LIST;
|
|
val.item.access_list_value = NULL;
|
|
srcattrs[i].value = &val;
|
|
}
|
|
stat = _DtCmUpdateAttribute(&srcattrs[i],
|
|
&cal->attrs[srcattrs[i].name.num]);
|
|
}
|
|
}
|
|
|
|
if (stat == CSA_SUCCESS) {
|
|
log = _DtCmsGetLogFN(cal->calendar);
|
|
|
|
/* dump file */
|
|
stat = _DtCmsAppendCalAttrsByFN(log, cal->num_attrs,
|
|
cal->attrs);
|
|
free(log);
|
|
}
|
|
|
|
if (stat == CSA_SUCCESS) {
|
|
cal->modified = B_TRUE;
|
|
|
|
_DtCm_free_cms_attributes(oldnum + 1, oldattrs);
|
|
free(oldattrs);
|
|
} else {
|
|
_DtCm_free_cms_attributes(cal->num_attrs+1, cal->attrs);
|
|
free(cal->attrs);
|
|
cal->num_attrs = oldnum;
|
|
cal->attrs = oldattrs;
|
|
}
|
|
|
|
return (stat);
|
|
}
|
|
|
|
extern CSA_return_code
|
|
_DtCmsV5TransactLog(_DtCmsCalendar *cal, cms_entry *e, _DtCmsLogOps op)
|
|
{
|
|
CSA_return_code stat;
|
|
char *log;
|
|
|
|
if ((log = _DtCmsGetLogFN(cal->calendar)) == NULL)
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
|
|
if (cal->hashed == B_FALSE ||
|
|
cal->num_entry_attrs < cal->entry_tbl->size) {
|
|
if ((stat = _DtCmsAppendHTableByFN(log, cal->entry_tbl->size,
|
|
cal->entry_tbl->names, cal->types)) != CSA_SUCCESS) {
|
|
free(log);
|
|
return (stat);
|
|
} else {
|
|
cal->hashed = B_TRUE;
|
|
cal->num_entry_attrs = cal->entry_tbl->size;
|
|
}
|
|
}
|
|
stat = _DtCmsAppendEntryByFN(log, e, op);
|
|
free(log);
|
|
return(stat);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* static functions used within the file
|
|
*****************************************************************************/
|
|
|
|
/*
|
|
* return user name of file owner
|
|
* If the calendar name is the same as a user account name, the
|
|
* calendar name is return; otherwise, the owner name is derived from
|
|
* the owner of the calendar file
|
|
*/
|
|
static CSA_return_code
|
|
get_file_owner(char *calname, char **owner)
|
|
{
|
|
struct stat info;
|
|
struct passwd *pw;
|
|
char buf[BUFSIZ];
|
|
char *log;
|
|
int res;
|
|
|
|
if (calname == NULL || owner == NULL)
|
|
return (CSA_E_FAILURE);
|
|
|
|
*owner = NULL;
|
|
|
|
if (_DtCmIsUserName(calname) == B_TRUE) {
|
|
snprintf(buf, sizeof(buf), "%s", calname);
|
|
} else {
|
|
if ((log = _DtCmsGetLogFN(calname)) == NULL)
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
|
|
res = stat(log, &info);
|
|
free(log);
|
|
|
|
if (res == 0) {
|
|
|
|
if (pw = getpwuid(info.st_uid))
|
|
snprintf(buf, sizeof(buf), "%s", pw->pw_name);
|
|
else
|
|
return (CSA_E_FAILURE);
|
|
} else
|
|
return(CSA_X_DT_E_BACKING_STORE_PROBLEM);
|
|
}
|
|
|
|
if (((*owner) = (char *)strdup(buf)) == NULL)
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
else
|
|
return (CSA_SUCCESS);
|
|
}
|
|
|
|
static char *
|
|
get_calname(char *target)
|
|
{
|
|
char *ptr, *name;
|
|
|
|
if (target == NULL)
|
|
return (NULL);
|
|
|
|
ptr = strchr(target, '@');
|
|
if (ptr == NULL) {
|
|
return (strdup(target));
|
|
} else {
|
|
*ptr = '\0';
|
|
name = strdup(target);
|
|
*ptr = '@';
|
|
return (name);
|
|
}
|
|
}
|
|
|
|
static CSA_return_code
|
|
init_cal_attrs(_DtCmsCalendar *cal)
|
|
{
|
|
int i;
|
|
|
|
/* initialize the calendar with predefined attribute names */
|
|
if ((cal->attrs = (cms_attribute *)calloc(1,
|
|
sizeof(cms_attribute)*(_DtCm_cal_name_tbl->size + 1))) == NULL) {
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
for (i = 1; i <= _DtCm_cal_name_tbl->size; i++) {
|
|
if ((cal->attrs[i].name.name =
|
|
strdup(_DtCm_cal_name_tbl->names[i])) == NULL) {
|
|
_DtCm_free_cms_attributes(i, cal->attrs);
|
|
free(cal->attrs);
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
cal->attrs[i].name.num = i;
|
|
}
|
|
cal->num_attrs = _DtCm_cal_name_tbl->size;
|
|
|
|
return (CSA_SUCCESS);
|
|
}
|
|
|
|
static CSA_return_code
|
|
_CopyCalendarAttr(_DtCmsCalendar *cal, int index, cms_attribute *attr)
|
|
{
|
|
cms_attribute tmp;
|
|
cms_attribute_value tmpval;
|
|
|
|
if (cal->attrs && cal->attrs[index].value)
|
|
return (_DtCm_copy_cms_attribute(attr,
|
|
&cal->attrs[index], B_TRUE));
|
|
else
|
|
return (CSA_SUCCESS);
|
|
}
|
|
|
|
static CSA_return_code
|
|
_GetCalendarSize(_DtCmsCalendar *cal, int index, cms_attribute *attr)
|
|
{
|
|
CSA_return_code stat;
|
|
int size;
|
|
|
|
if ((stat = _DtCmsGetFileSize(cal->calendar, &size)) == CSA_SUCCESS) {
|
|
attr->name.num = CSA_CAL_ATTR_CALENDAR_SIZE_I;
|
|
if (attr->name.name = strdup(CSA_CAL_ATTR_CALENDAR_SIZE))
|
|
return (_DtCm_set_uint32_attrval((uint)size,
|
|
&attr->value));
|
|
else
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
return (stat);
|
|
}
|
|
|
|
static CSA_return_code
|
|
_GetNumberEntries(_DtCmsCalendar *cal, int index, cms_attribute *attr)
|
|
{
|
|
uint size;
|
|
|
|
size = rb_size(cal->tree) + hc_size(cal->list);
|
|
|
|
attr->name.num = CSA_CAL_ATTR_NUMBER_ENTRIES_I;
|
|
if (attr->name.name = strdup(CSA_CAL_ATTR_NUMBER_ENTRIES))
|
|
return (_DtCm_set_uint32_attrval(size, &attr->value));
|
|
else
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
static CSA_return_code
|
|
_GetAccessList(_DtCmsCalendar *cal, int index, cms_attribute *attr)
|
|
{
|
|
if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
|
|
return (_DtCm_copy_cms_attribute(attr,
|
|
&cal->attrs[CSA_CAL_ATTR_ACCESS_LIST_I], B_TRUE));
|
|
} else {
|
|
Access_Entry_4 *alist;
|
|
CSA_return_code stat;
|
|
cms_attribute tmpattr;
|
|
cms_attribute_value tmpval;
|
|
|
|
alist = _DtCmsCalendarAccessList(cal);
|
|
if ((stat = _DtCm_accessentry4_to_cmsaccesslist(alist,
|
|
&tmpval.item.access_list_value)) == CSA_SUCCESS) {
|
|
tmpattr.name.num = CSA_CAL_ATTR_ACCESS_LIST_I;
|
|
tmpattr.name.name = CSA_CAL_ATTR_ACCESS_LIST;
|
|
tmpattr.value = &tmpval;
|
|
tmpval.type = CSA_VALUE_ACCESS_LIST;
|
|
|
|
free(alist);
|
|
return (_DtCm_copy_cms_attribute(attr, &tmpattr,
|
|
B_TRUE));
|
|
} else {
|
|
free(alist);
|
|
return (stat);
|
|
}
|
|
}
|
|
}
|
|
|
|
static CSA_return_code
|
|
_GetCalendarName(_DtCmsCalendar *cal, int index, cms_attribute *attr)
|
|
{
|
|
if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
|
|
return (_DtCm_copy_cms_attribute(attr,
|
|
&cal->attrs[CSA_CAL_ATTR_CALENDAR_NAME_I], B_TRUE));
|
|
} else {
|
|
attr->name.num = CSA_CAL_ATTR_CALENDAR_NAME_I;
|
|
if (attr->name.name = strdup(CSA_CAL_ATTR_CALENDAR_NAME)) {
|
|
return (_DtCm_set_string_attrval(cal->calendar,
|
|
&attr->value, CSA_VALUE_STRING));
|
|
} else {
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
}
|
|
}
|
|
|
|
static CSA_return_code
|
|
_GetCalendarOwner(_DtCmsCalendar *cal, int index, cms_attribute *attr)
|
|
{
|
|
if (cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION) {
|
|
return (_DtCm_copy_cms_attribute(attr,
|
|
&cal->attrs[CSA_CAL_ATTR_CALENDAR_OWNER_I], B_TRUE));
|
|
} else {
|
|
attr->name.num = CSA_CAL_ATTR_CALENDAR_OWNER_I;
|
|
if (attr->name.name = strdup(CSA_CAL_ATTR_CALENDAR_OWNER)) {
|
|
return (_DtCm_set_user_attrval(cal->owner,
|
|
&attr->value));
|
|
} else {
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
}
|
|
}
|
|
|
|
static CSA_return_code
|
|
_GetServerVersion(_DtCmsCalendar *cal, int index, cms_attribute *attr)
|
|
{
|
|
attr->name.num = CSA_X_DT_CAL_ATTR_SERVER_VERSION_I;
|
|
if (attr->name.name = strdup(CSA_X_DT_CAL_ATTR_SERVER_VERSION))
|
|
return (_DtCm_set_uint32_attrval((uint)TABLEVERS, &attr->value));
|
|
else
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
static CSA_return_code
|
|
_GetDataVersion(_DtCmsCalendar *cal, int index, cms_attribute *attr)
|
|
{
|
|
uint version;
|
|
|
|
version = cal->fversion >= _DtCM_FIRST_EXTENSIBLE_DATA_VERSION ?
|
|
cal->fversion : _DtCM_FIRST_EXTENSIBLE_DATA_VERSION - 1;
|
|
|
|
attr->name.num = CSA_X_DT_CAL_ATTR_DATA_VERSION_I;
|
|
if (attr->name.name = strdup(CSA_X_DT_CAL_ATTR_DATA_VERSION))
|
|
return (_DtCm_set_uint32_attrval(version, &attr->value));
|
|
else
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
static CSA_return_code
|
|
_GetProductId(_DtCmsCalendar *cal, int index, cms_attribute *attr)
|
|
{
|
|
attr->name.num = CSA_CAL_ATTR_PRODUCT_IDENTIFIER_I;
|
|
if (attr->name.name = strdup(CSA_CAL_ATTR_PRODUCT_IDENTIFIER)) {
|
|
return (_DtCm_set_string_attrval(_DtCM_PRODUCT_IDENTIFIER,
|
|
&attr->value, CSA_VALUE_STRING));
|
|
} else {
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
}
|
|
|
|
static CSA_return_code
|
|
_GetSupportedVersion(_DtCmsCalendar *cal, int index, cms_attribute *attr)
|
|
{
|
|
attr->name.num = CSA_CAL_ATTR_VERSION_I;
|
|
if (attr->name.name = strdup(CSA_CAL_ATTR_VERSION)) {
|
|
return (_DtCm_set_string_attrval(_DtCM_SPEC_VERSION_SUPPORTED,
|
|
&attr->value, CSA_VALUE_STRING));
|
|
} else {
|
|
return (CSA_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
}
|
|
|